docs: use `markdownDescription` extension in schema (#945)
`markdownDescription` is specific to Visual Studio Code (see https://github.com/Microsoft/vscode/issues/34498). Also extracted longer descriptions to separate files to make them easier to edit.
This commit is contained in:
Родитель
02c4f051df
Коммит
295d295745
|
@ -50,7 +50,8 @@ jobs:
|
|||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
npm run codegen
|
||||
npm run generate:code
|
||||
npm run generate:schema
|
||||
if [[ -n "$GITHUB_TOKEN" ]]; then
|
||||
git diff | npx suggestion-bot
|
||||
fi
|
||||
|
@ -88,12 +89,15 @@ jobs:
|
|||
# TODO: GITHUB_TOKEN is not set if a PR comes from a forked repo.
|
||||
# Ignore errors until we can create a GitHub PAT from a system
|
||||
# account.
|
||||
scripts/prettier-diff.js $(git ls-files '*.js' '*.yml' 'test/**/*.json') || true
|
||||
echo "::add-matcher::.github/eslint-stylish.json"
|
||||
npm run lint:js
|
||||
echo "::remove-matcher owner=eslint-stylish::"
|
||||
if [[ ${{ matrix.platform }} == macos ]]; then
|
||||
scripts/prettier-diff.js $(git ls-files '*.js' '*.yml' 'test/**/*.json') || true
|
||||
echo "::add-matcher::.github/eslint-stylish.json"
|
||||
npm run lint:js
|
||||
echo "::remove-matcher owner=eslint-stylish::"
|
||||
fi
|
||||
npx tsc
|
||||
npm run test:js -- --ci
|
||||
shell: bash
|
||||
- name: ktlint
|
||||
if: ${{ matrix.platform == 'macos' }}
|
||||
run: |
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// This file was generated by generate-manifest.js.
|
||||
// This file was generated by generate-manifest.mjs.
|
||||
// DO NOT MODIFY. ALL CHANGES WILL BE OVERWRITTEN.
|
||||
|
||||
package com.microsoft.reacttestapp.manifest
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// This file was generated by generate-manifest.js.
|
||||
// This file was generated by generate-manifest.mjs.
|
||||
// DO NOT MODIFY. ALL CHANGES WILL BE OVERWRITTEN.
|
||||
|
||||
struct Component: Decodable {
|
||||
|
|
|
@ -52,10 +52,11 @@
|
|||
},
|
||||
"scripts": {
|
||||
"clean": "git clean -dfqx --exclude=.yarn/cache",
|
||||
"codegen": "node scripts/generate-manifest.js",
|
||||
"format:c": "clang-format -i $(git ls-files '*.cpp' '*.h' '*.m' '*.mm')",
|
||||
"format:js": "prettier --write $(git ls-files '*.js' '*.yml' 'test/**/*.json')",
|
||||
"format:swift": "swiftformat --swiftversion 5.5 ios macos",
|
||||
"generate:code": "node scripts/generate-manifest.mjs",
|
||||
"generate:schema": "node scripts/generate-schema.mjs",
|
||||
"lint:commit": "git log --format='%s' origin/trunk..HEAD | tail -1 | commitlint",
|
||||
"lint:js": "eslint $(git ls-files '*.js') && tsc",
|
||||
"lint:kt": "ktlint --relative --verbose 'android/app/src/**/*.kt'",
|
||||
|
|
105
schema.json
105
schema.json
|
@ -18,14 +18,19 @@
|
|||
"presentationStyle": {
|
||||
"description": "The style in which to present your component.",
|
||||
"type": "string",
|
||||
"enum": ["default", "modal"]
|
||||
"enum": [
|
||||
"default",
|
||||
"modal"
|
||||
]
|
||||
},
|
||||
"slug": {
|
||||
"description": "URL slug that uniquely identifies this component. Used for deep linking.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["appKey"]
|
||||
"required": [
|
||||
"appKey"
|
||||
]
|
||||
},
|
||||
"manifest": {
|
||||
"type": "object",
|
||||
|
@ -37,20 +42,28 @@
|
|||
"type": "string"
|
||||
},
|
||||
"bundleRoot": {
|
||||
"description": "Specifies the root of the bundle file name. E.g., if the bundle file is `index.[platform].bundle`, `index` is the bundle root.\n\nDefaults to `index` and `main`.\n\nWhen set, the test app will look for the following files on startup:\n\n- `myRoot.[platform].jsbundle`\n- `myRoot.[platform].bundle`\n- `myRoot.native.jsbundle`\n- `myRoot.native.bundle`\n- `myRoot.jsbundle`\n- `myRoot.bundle`\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.0'>0.9.0</a>.",
|
||||
"description": "Specifies the root of the bundle file name. E.g., if the bundle file is\n`index.[platform].bundle`, `index` is the bundle root.",
|
||||
"markdownDescription": "Specifies the root of the bundle file name. E.g., if the bundle file is\n`index.[platform].bundle`, `index` is the bundle root.\n\nDefaults to `index` and `main`.\n\nWhen set, the test app will look for the following files on startup:\n\n- `myRoot.[platform].jsbundle`\n- `myRoot.[platform].bundle`\n- `myRoot.native.jsbundle`\n- `myRoot.native.bundle`\n- `myRoot.jsbundle`\n- `myRoot.bundle`\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.0'>0.9.0</a>.\n",
|
||||
"type": "string"
|
||||
},
|
||||
"singleApp": {
|
||||
"description": "In single-app mode, the component with the specified slug gets launched automatically, essentially behaving as a normal app.\n\nDefaults to multi-app mode.\n\nFor more details, see [its dedicated page](Single-app-Mode).\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/1.3.0'>1.3.0</a>.",
|
||||
"description": "In single-app mode, the component with the specified slug gets launched\nautomatically, essentially behaving as a normal app.",
|
||||
"markdownDescription": "In single-app mode, the component with the specified slug gets launched\nautomatically, essentially behaving as a normal app.\n\nDefaults to multi-app mode.\n\nFor more details, see [its dedicated page](Single-app-Mode).\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/1.3.0'>1.3.0</a>.\n",
|
||||
"type": "string"
|
||||
},
|
||||
"components": {
|
||||
"description": "All components that should be accessible from the home screen should be declared under this property. Each component must have `appKey` set, i.e. the name that you passed to `AppRegistry.registerComponent`.\n\n```javascript\nAppRegistry.registerComponent('Example', () => Example);\n```\n\nFor each entry, you can declare additional (optional) properties:\n\n```javascript\n{\n \"components\": [\n {\n // The app key passed to `AppRegistry.registerComponent()`\n \"appKey\": \"Example\",\n\n // [Optional] Name to be displayed on home screen\n \"displayName\": \"App\",\n\n // [Optional] Properties that should be passed to your component\n \"initialProperties\": {\n \"concurrentRoot\": false\n },\n\n // [Optional] The style in which to present your component.\n // Valid values are: \"modal\"\n \"presentationStyle\": \"\",\n\n // [Optional] URL slug that uniquely identifies this component.\n // Used for deep linking.\n \"slug\": \"\"\n }\n ]\n}\n```\n\nIf you're on React Native 0.69 and want to enable [Concurrent React](https://reactjs.org/blog/2022/03/29/react-v18.html#what-is-concurrent-react), set `\"concurrentRoot\": true` in `initialProperties`.\n\n<a name='android-adding-fragments' />\n\n#### [Android] Adding Fragments\n\nOn Android, you can add fragments to the home screen by using their fully qualified class names, e.g. `com.example.app.MyFragment`, as app key:\n\n```javascript\n\"components\": [\n {\n \"appKey\": \"com.example.app.MyFragment\",\n \"displayName\": \"App\"\n }\n]\n```\n\nIf you need to get the `ReactNativeHost` instance within `MyFragment`, you can request it as a service from the context:\n\n```java\n@Override\n@SuppressLint(\"WrongConstant\")\npublic void onAttach(@NonNull Context context) {\n super.onAttach(context);\n\n ReactNativeHost reactNativeHost = (ReactNativeHost)\n context.getSystemService(\"service:reactNativeHostService\");\n ReactInstanceManager reactInstanceManager =\n reactNativeHost.getReactInstanceManager();\n}\n```\n\n<a name='ios-macos-adding-view-controllers' />\n\n#### [iOS, macOS] Adding View Controllers\n\nOn iOS/macOS, you can have native view controllers on the home screen by using their Objective-C names as app key (Swift classes can declare Objective-C names with the <a href='https://docs.swift.org/swift-book/ReferenceManual/Attributes.html#objc'>`@objc`</a> attribute):\n\n```javascript\n\"components\": [\n {\n \"appKey\": \"RTAMyViewController\",\n \"displayName\": \"App\"\n }\n]\n```\n\nThe view controller must implement an initializer that accepts a `RCTBridge` instance:\n\n```objc\n- (nonnull instancetype)initWithBridge:(nonnull RCTBridge *)bridge;\n```",
|
||||
"description": "All components that should be accessible from the home screen should be declared\nunder this property. Each component must have `appKey` set, i.e. the name that\nyou passed to `AppRegistry.registerComponent`.",
|
||||
"markdownDescription": "All components that should be accessible from the home screen should be declared\nunder this property. Each component must have `appKey` set, i.e. the name that\nyou passed to `AppRegistry.registerComponent`.\n\n```javascript\nAppRegistry.registerComponent(\"Example\", () => Example);\n```\n\nFor each entry, you can declare additional (optional) properties:\n\n```javascript\n{\n \"components\": [\n {\n // The app key passed to `AppRegistry.registerComponent()`\n \"appKey\": \"Example\",\n\n // [Optional] Name to be displayed on home screen\n \"displayName\": \"App\",\n\n // [Optional] Properties that should be passed to your component\n \"initialProperties\": {\n \"concurrentRoot\": false\n },\n\n // [Optional] The style in which to present your component.\n // Valid values are: \"modal\"\n \"presentationStyle\": \"\",\n\n // [Optional] URL slug that uniquely identifies this component.\n // Used for deep linking.\n \"slug\": \"\"\n }\n ]\n}\n```\n\nIf you're on React Native 0.69 and want to enable\n[Concurrent React](https://reactjs.org/blog/2022/03/29/react-v18.html#what-is-concurrent-react),\nset `\"concurrentRoot\": true` in `initialProperties`.\n\n<a name='android-adding-fragments' />\n\n#### [Android] Adding Fragments\n\nOn Android, you can add fragments to the home screen by using their fully\nqualified class names, e.g. `com.example.app.MyFragment`, as app key:\n\n```javascript\n\"components\": [\n {\n \"appKey\": \"com.example.app.MyFragment\",\n \"displayName\": \"App\"\n }\n]\n```\n\nIf you need to get the `ReactNativeHost` instance within `MyFragment`, you can\nrequest it as a service from the context:\n\n```java\n@Override\n@SuppressLint(\"WrongConstant\")\npublic void onAttach(@NonNull Context context) {\n super.onAttach(context);\n\n ReactNativeHost reactNativeHost = (ReactNativeHost)\n context.getSystemService(\"service:reactNativeHostService\");\n ReactInstanceManager reactInstanceManager =\n reactNativeHost.getReactInstanceManager();\n}\n```\n\n<a name='ios-macos-adding-view-controllers' />\n\n#### [iOS, macOS] Adding View Controllers\n\nOn iOS/macOS, you can have native view controllers on the home screen by using\ntheir Objective-C names as app key (Swift classes can declare Objective-C names\nwith the\n<a href='https://docs.swift.org/swift-book/ReferenceManual/Attributes.html#objc'>`@objc`</a>\nattribute):\n\n```javascript\n\"components\": [\n {\n \"appKey\": \"RTAMyViewController\",\n \"displayName\": \"App\"\n }\n]\n```\n\nThe view controller must implement an initializer that accepts a `RCTBridge`\ninstance:\n\n```objc\n- (nonnull instancetype)initWithBridge:(nonnull RCTBridge *)bridge;\n```\n",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/component" }
|
||||
"items": {
|
||||
"$ref": "#/$defs/component"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["name", "displayName"]
|
||||
"required": [
|
||||
"name",
|
||||
"displayName"
|
||||
]
|
||||
},
|
||||
"signingConfig": {
|
||||
"type": "object",
|
||||
|
@ -72,19 +85,28 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["storeFile"],
|
||||
"required": [
|
||||
"storeFile"
|
||||
],
|
||||
"exclude-from-codegen": true
|
||||
}
|
||||
},
|
||||
"allOf": [{ "$ref": "#/$defs/manifest" }],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/manifest"
|
||||
}
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"resources": {
|
||||
"description": "Here you should declare all resources that should be bundled with the app. The property can be a list of paths to resources:\n\n```javascript\n\"resources\": [\n \"dist/assets\",\n \"dist/main.jsbundle\"\n]\n```\n\nOr you can declare platform specific resources using platform names as key:\n\n```javascript\n\"resources\": {\n \"android\": [\n \"dist/res\",\n \"dist/main.android.jsbundle\"\n ],\n \"ios\": [\n \"dist/assets\",\n \"dist/main.ios.jsbundle\"\n ],\n \"macos\": [\n \"dist/assets\",\n \"dist/main.macos.jsbundle\"\n ],\n \"windows\": [\n \"dist/assets\",\n \"dist/main.windows.bundle\"\n ]\n}\n```\n\nA path must be relative to the path of `app.json`, and can point to both a file or a directory.",
|
||||
"description": "Here you should declare all resources that should be bundled with the app. The\nproperty can be a list of paths to resources:",
|
||||
"markdownDescription": "Here you should declare all resources that should be bundled with the app. The\nproperty can be a list of paths to resources:\n\n```javascript\n\"resources\": [\n \"dist/assets\",\n \"dist/main.jsbundle\"\n]\n```\n\nOr you can declare platform specific resources using platform names as key:\n\n```javascript\n\"resources\": {\n \"android\": [\n \"dist/res\",\n \"dist/main.android.jsbundle\"\n ],\n \"ios\": [\n \"dist/assets\",\n \"dist/main.ios.jsbundle\"\n ],\n \"macos\": [\n \"dist/assets\",\n \"dist/main.macos.jsbundle\"\n ],\n \"windows\": [\n \"dist/assets\",\n \"dist/main.windows.bundle\"\n ]\n}\n```\n\nA path must be relative to the path of `app.json`, and can point to both a file\nor a directory.\n",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
{
|
||||
|
@ -92,22 +114,30 @@
|
|||
"properties": {
|
||||
"android": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"ios": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"macos": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"windows": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"uniqueItems": true
|
||||
}
|
||||
}
|
||||
|
@ -123,17 +153,26 @@
|
|||
"type": "string"
|
||||
},
|
||||
"signingConfigs": {
|
||||
"description": "Use this to set the <a href='https://developer.android.com/studio/publish/app-signing'>signing configurations</a> for the app.\n\nThe JSON schema follows the Gradle DSL very closely. Below is what one would add for the debug and release flavors:\n\n```javascript\n{\n \"android\": {\n \"signingConfigs\": {\n \"debug\": { // optional\n \"keyAlias\": \"androiddebugkey\", // defaults to \"androiddebugkey\"\n \"keyPassword\": \"android\", // defaults to \"android\n \"storeFile\": \"debug.keystore\", // required\n \"storePassword\": \"android\" // defaults to \"android\n },\n \"release\": { // optional\n \"keyAlias\": \"androiddebugkey\", // defaults to \"androiddebugkey\"\n \"keyPassword\": \"android\", // defaults to \"android\n \"storeFile\": \"release.keystore\", // required\n \"storePassword\": \"android\" // defaults to \"android\n }\n }\n }\n}\n```\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/0.11.0'>0.11.0</a>.",
|
||||
"description": "Use this to set the\n<a href='https://developer.android.com/studio/publish/app-signing'>signing\nconfigurations</a> for the app.",
|
||||
"markdownDescription": "Use this to set the\n<a href='https://developer.android.com/studio/publish/app-signing'>signing\nconfigurations</a> for the app.\n\nThe JSON schema follows the Gradle DSL very closely. Below is what one would add\nfor the debug and release flavors:\n\n```javascript\n{\n \"android\": {\n \"signingConfigs\": {\n \"debug\": { // optional\n \"keyAlias\": \"androiddebugkey\", // defaults to \"androiddebugkey\"\n \"keyPassword\": \"android\", // defaults to \"android\n \"storeFile\": \"debug.keystore\", // required\n \"storePassword\": \"android\" // defaults to \"android\n },\n \"release\": { // optional\n \"keyAlias\": \"androiddebugkey\", // defaults to \"androiddebugkey\"\n \"keyPassword\": \"android\", // defaults to \"android\n \"storeFile\": \"release.keystore\", // required\n \"storePassword\": \"android\" // defaults to \"android\n }\n }\n }\n}\n```\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.11.0'>0.11.0</a>.\n",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"debug": {
|
||||
"description": "Use this property for the debug signing config for the app. The value `storeFile` is required. Android defaults will be provided for other properties.",
|
||||
"allOf": [{ "$ref": "#/$defs/signingConfig" }],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/signingConfig"
|
||||
}
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"release": {
|
||||
"description": "Use this property for the release signing config for the app. The value `storeFile` is required. Android defaults will be provided for other properties.",
|
||||
"allOf": [{ "$ref": "#/$defs/signingConfig" }],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/signingConfig"
|
||||
}
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
|
@ -149,15 +188,18 @@
|
|||
"type": "string"
|
||||
},
|
||||
"codeSignEntitlements": {
|
||||
"description": "Specifies the path to a custom <a href='https://developer.apple.com/documentation/bundleresources/entitlements'>Entitlements</a> file. The path should be relative to `app.json`. This is the same as setting `CODE_SIGN_ENTITLEMENTS` in Xcode.\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.",
|
||||
"description": "Specifies the path to a custom\n<a href='https://developer.apple.com/documentation/bundleresources/entitlements'>Entitlements</a>\nfile. The path should be relative to `app.json`. This is the same as setting\n`CODE_SIGN_ENTITLEMENTS` in Xcode.",
|
||||
"markdownDescription": "Specifies the path to a custom\n<a href='https://developer.apple.com/documentation/bundleresources/entitlements'>Entitlements</a>\nfile. The path should be relative to `app.json`. This is the same as setting\n`CODE_SIGN_ENTITLEMENTS` in Xcode.\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.\n",
|
||||
"type": "string"
|
||||
},
|
||||
"codeSignIdentity": {
|
||||
"description": "Sets the <a href='https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW1'>code signing identity</a> to use when signing code. This is the same as setting `CODE_SIGN_IDENTITY` in Xcode.\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.",
|
||||
"description": "Sets the\n<a href='https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW1'>code\nsigning identity</a> to use when signing code. This is the same as setting\n`CODE_SIGN_IDENTITY` in Xcode.",
|
||||
"markdownDescription": "Sets the\n<a href='https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW1'>code\nsigning identity</a> to use when signing code. This is the same as setting\n`CODE_SIGN_IDENTITY` in Xcode.\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.\n",
|
||||
"type": "string"
|
||||
},
|
||||
"developmentTeam": {
|
||||
"description": "Sets the <a href='https://help.apple.com/xcode/mac/current/#/dev23aab79b4'>development team</a> that the app should be assigned to. This is the same as setting `DEVELOPMENT_TEAM` in Xcode.\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.",
|
||||
"description": "Sets the\n<a href='https://help.apple.com/xcode/mac/current/#/dev23aab79b4'>development\nteam</a> that the app should be assigned to. This is the same as setting\n`DEVELOPMENT_TEAM` in Xcode.",
|
||||
"markdownDescription": "Sets the\n<a href='https://help.apple.com/xcode/mac/current/#/dev23aab79b4'>development\nteam</a> that the app should be assigned to. This is the same as setting\n`DEVELOPMENT_TEAM` in Xcode.\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.\n",
|
||||
"type": "string"
|
||||
},
|
||||
"reactNativePath": {
|
||||
|
@ -175,15 +217,18 @@
|
|||
"type": "string"
|
||||
},
|
||||
"codeSignEntitlements": {
|
||||
"description": "Specifies the path to a custom <a href='https://developer.apple.com/documentation/bundleresources/entitlements'>Entitlements</a> file. The path should be relative to `app.json`. This is the same as setting `CODE_SIGN_ENTITLEMENTS` in Xcode.\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.",
|
||||
"description": "Specifies the path to a custom\n<a href='https://developer.apple.com/documentation/bundleresources/entitlements'>Entitlements</a>\nfile. The path should be relative to `app.json`. This is the same as setting\n`CODE_SIGN_ENTITLEMENTS` in Xcode.",
|
||||
"markdownDescription": "Specifies the path to a custom\n<a href='https://developer.apple.com/documentation/bundleresources/entitlements'>Entitlements</a>\nfile. The path should be relative to `app.json`. This is the same as setting\n`CODE_SIGN_ENTITLEMENTS` in Xcode.\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.\n",
|
||||
"type": "string"
|
||||
},
|
||||
"codeSignIdentity": {
|
||||
"description": "Sets the <a href='https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW1'>code signing identity</a> to use when signing code. This is the same as setting `CODE_SIGN_IDENTITY` in Xcode.\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.",
|
||||
"description": "Sets the\n<a href='https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW1'>code\nsigning identity</a> to use when signing code. This is the same as setting\n`CODE_SIGN_IDENTITY` in Xcode.",
|
||||
"markdownDescription": "Sets the\n<a href='https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW1'>code\nsigning identity</a> to use when signing code. This is the same as setting\n`CODE_SIGN_IDENTITY` in Xcode.\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.\n",
|
||||
"type": "string"
|
||||
},
|
||||
"developmentTeam": {
|
||||
"description": "Sets the <a href='https://help.apple.com/xcode/mac/current/#/dev23aab79b4'>development team</a> that the app should be assigned to. This is the same as setting `DEVELOPMENT_TEAM` in Xcode.\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.",
|
||||
"description": "Sets the\n<a href='https://help.apple.com/xcode/mac/current/#/dev23aab79b4'>development\nteam</a> that the app should be assigned to. This is the same as setting\n`DEVELOPMENT_TEAM` in Xcode.",
|
||||
"markdownDescription": "Sets the\n<a href='https://help.apple.com/xcode/mac/current/#/dev23aab79b4'>development\nteam</a> that the app should be assigned to. This is the same as setting\n`DEVELOPMENT_TEAM` in Xcode.\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.\n",
|
||||
"type": "string"
|
||||
},
|
||||
"reactNativePath": {
|
||||
|
@ -197,19 +242,23 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"appxManifest": {
|
||||
"description": "Sets the path to your <a href='https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/appx-package-manifest'>app package manifest</a>. If none is set, a default manifest will be provided. Changes to this property will not be automatically be picked up; you need to re-run `npx install-windows-test-app` to update the solution.\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/0.5.5'>0.5.5</a>.",
|
||||
"description": "Sets the path to your\n<a href='https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/appx-package-manifest'>app\npackage manifest</a>. If none is set, a default manifest will be provided.\nChanges to this property will not be automatically be picked up; you need to\nre-run `npx install-windows-test-app` to update the solution.",
|
||||
"markdownDescription": "Sets the path to your\n<a href='https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/appx-package-manifest'>app\npackage manifest</a>. If none is set, a default manifest will be provided.\nChanges to this property will not be automatically be picked up; you need to\nre-run `npx install-windows-test-app` to update the solution.\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.5.5'>0.5.5</a>.\n",
|
||||
"type": "string"
|
||||
},
|
||||
"certificateKeyFile": {
|
||||
"description": "The path to the certificate to use. If specified, it will also enable package signing. Changes to this property will not be automatically be picked up; you need to re-run `npx install-windows-test-app` to update the solution.\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/1.1.0'>1.1.0</a>.",
|
||||
"description": "The path to the certificate to use. If specified, it will also enable package\nsigning. Changes to this property will not be automatically be picked up; you\nneed to re-run `npx install-windows-test-app` to update the solution.",
|
||||
"markdownDescription": "The path to the certificate to use. If specified, it will also enable package\nsigning. Changes to this property will not be automatically be picked up; you\nneed to re-run `npx install-windows-test-app` to update the solution.\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/1.1.0'>1.1.0</a>.\n",
|
||||
"type": "string"
|
||||
},
|
||||
"certificatePassword": {
|
||||
"description": "The password for the private key in the certificate. Leave unset if no password. Changes to this property will not be automatically be picked up; you need to re-run `npx install-windows-test-app` to update the solution.\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/1.1.0'>1.1.0</a>.",
|
||||
"description": "The password for the private key in the certificate. Leave unset if no password.\nChanges to this property will not be automatically be picked up; you need to\nre-run `npx install-windows-test-app` to update the solution.",
|
||||
"markdownDescription": "The password for the private key in the certificate. Leave unset if no password.\nChanges to this property will not be automatically be picked up; you need to\nre-run `npx install-windows-test-app` to update the solution.\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/1.1.0'>1.1.0</a>.\n",
|
||||
"type": "string"
|
||||
},
|
||||
"certificateThumbprint": {
|
||||
"description": "This value must match the thumbprint in the signing certificate, or be unset. Changes to this property will not be automatically be picked up; you need to re-run `npx install-windows-test-app` to update the solution.\n\nIntroduced in <a href='//github.com/microsoft/react-native-test-app/releases/tag/1.1.0'>1.1.0</a>.",
|
||||
"description": "This value must match the thumbprint in the signing certificate, or be unset.\nChanges to this property will not be automatically be picked up; you need to\nre-run `npx install-windows-test-app` to update the solution.",
|
||||
"markdownDescription": "This value must match the thumbprint in the signing certificate, or be unset.\nChanges to this property will not be automatically be picked up; you need to\nre-run `npx install-windows-test-app` to update the solution.\n\nIntroduced in\n<a href='//github.com/microsoft/react-native-test-app/releases/tag/1.1.0'>1.1.0</a>.\n",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
Use this to set the
|
||||
<a href='https://developer.android.com/studio/publish/app-signing'>signing
|
||||
configurations</a> for the app.
|
||||
|
||||
The JSON schema follows the Gradle DSL very closely. Below is what one would add
|
||||
for the debug and release flavors:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"android": {
|
||||
"signingConfigs": {
|
||||
"debug": { // optional
|
||||
"keyAlias": "androiddebugkey", // defaults to "androiddebugkey"
|
||||
"keyPassword": "android", // defaults to "android
|
||||
"storeFile": "debug.keystore", // required
|
||||
"storePassword": "android" // defaults to "android
|
||||
},
|
||||
"release": { // optional
|
||||
"keyAlias": "androiddebugkey", // defaults to "androiddebugkey"
|
||||
"keyPassword": "android", // defaults to "android
|
||||
"storeFile": "release.keystore", // required
|
||||
"storePassword": "android" // defaults to "android
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Introduced in
|
||||
<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.11.0'>0.11.0</a>.
|
|
@ -0,0 +1,16 @@
|
|||
Specifies the root of the bundle file name. E.g., if the bundle file is
|
||||
`index.[platform].bundle`, `index` is the bundle root.
|
||||
|
||||
Defaults to `index` and `main`.
|
||||
|
||||
When set, the test app will look for the following files on startup:
|
||||
|
||||
- `myRoot.[platform].jsbundle`
|
||||
- `myRoot.[platform].bundle`
|
||||
- `myRoot.native.jsbundle`
|
||||
- `myRoot.native.bundle`
|
||||
- `myRoot.jsbundle`
|
||||
- `myRoot.bundle`
|
||||
|
||||
Introduced in
|
||||
<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.0'>0.9.0</a>.
|
|
@ -0,0 +1,98 @@
|
|||
All components that should be accessible from the home screen should be declared
|
||||
under this property. Each component must have `appKey` set, i.e. the name that
|
||||
you passed to `AppRegistry.registerComponent`.
|
||||
|
||||
```javascript
|
||||
AppRegistry.registerComponent("Example", () => Example);
|
||||
```
|
||||
|
||||
For each entry, you can declare additional (optional) properties:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
// The app key passed to `AppRegistry.registerComponent()`
|
||||
"appKey": "Example",
|
||||
|
||||
// [Optional] Name to be displayed on home screen
|
||||
"displayName": "App",
|
||||
|
||||
// [Optional] Properties that should be passed to your component
|
||||
"initialProperties": {
|
||||
"concurrentRoot": false
|
||||
},
|
||||
|
||||
// [Optional] The style in which to present your component.
|
||||
// Valid values are: "modal"
|
||||
"presentationStyle": "",
|
||||
|
||||
// [Optional] URL slug that uniquely identifies this component.
|
||||
// Used for deep linking.
|
||||
"slug": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
If you're on React Native 0.69 and want to enable
|
||||
[Concurrent React](https://reactjs.org/blog/2022/03/29/react-v18.html#what-is-concurrent-react),
|
||||
set `"concurrentRoot": true` in `initialProperties`.
|
||||
|
||||
<a name='android-adding-fragments' />
|
||||
|
||||
#### [Android] Adding Fragments
|
||||
|
||||
On Android, you can add fragments to the home screen by using their fully
|
||||
qualified class names, e.g. `com.example.app.MyFragment`, as app key:
|
||||
|
||||
```javascript
|
||||
"components": [
|
||||
{
|
||||
"appKey": "com.example.app.MyFragment",
|
||||
"displayName": "App"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
If you need to get the `ReactNativeHost` instance within `MyFragment`, you can
|
||||
request it as a service from the context:
|
||||
|
||||
```java
|
||||
@Override
|
||||
@SuppressLint("WrongConstant")
|
||||
public void onAttach(@NonNull Context context) {
|
||||
super.onAttach(context);
|
||||
|
||||
ReactNativeHost reactNativeHost = (ReactNativeHost)
|
||||
context.getSystemService("service:reactNativeHostService");
|
||||
ReactInstanceManager reactInstanceManager =
|
||||
reactNativeHost.getReactInstanceManager();
|
||||
}
|
||||
```
|
||||
|
||||
<a name='ios-macos-adding-view-controllers' />
|
||||
|
||||
#### [iOS, macOS] Adding View Controllers
|
||||
|
||||
On iOS/macOS, you can have native view controllers on the home screen by using
|
||||
their Objective-C names as app key (Swift classes can declare Objective-C names
|
||||
with the
|
||||
<a href='https://docs.swift.org/swift-book/ReferenceManual/Attributes.html#objc'>`@objc`</a>
|
||||
attribute):
|
||||
|
||||
```javascript
|
||||
"components": [
|
||||
{
|
||||
"appKey": "RTAMyViewController",
|
||||
"displayName": "App"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
The view controller must implement an initializer that accepts a `RCTBridge`
|
||||
instance:
|
||||
|
||||
```objc
|
||||
- (nonnull instancetype)initWithBridge:(nonnull RCTBridge *)bridge;
|
||||
```
|
|
@ -0,0 +1,7 @@
|
|||
Specifies the path to a custom
|
||||
<a href='https://developer.apple.com/documentation/bundleresources/entitlements'>Entitlements</a>
|
||||
file. The path should be relative to `app.json`. This is the same as setting
|
||||
`CODE_SIGN_ENTITLEMENTS` in Xcode.
|
||||
|
||||
Introduced in
|
||||
<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.
|
|
@ -0,0 +1,7 @@
|
|||
Sets the
|
||||
<a href='https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW1'>code
|
||||
signing identity</a> to use when signing code. This is the same as setting
|
||||
`CODE_SIGN_IDENTITY` in Xcode.
|
||||
|
||||
Introduced in
|
||||
<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.
|
|
@ -0,0 +1,7 @@
|
|||
Sets the
|
||||
<a href='https://help.apple.com/xcode/mac/current/#/dev23aab79b4'>development
|
||||
team</a> that the app should be assigned to. This is the same as setting
|
||||
`DEVELOPMENT_TEAM` in Xcode.
|
||||
|
||||
Introduced in
|
||||
<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.9.7'>0.9.7</a>.
|
|
@ -0,0 +1,35 @@
|
|||
Here you should declare all resources that should be bundled with the app. The
|
||||
property can be a list of paths to resources:
|
||||
|
||||
```javascript
|
||||
"resources": [
|
||||
"dist/assets",
|
||||
"dist/main.jsbundle"
|
||||
]
|
||||
```
|
||||
|
||||
Or you can declare platform specific resources using platform names as key:
|
||||
|
||||
```javascript
|
||||
"resources": {
|
||||
"android": [
|
||||
"dist/res",
|
||||
"dist/main.android.jsbundle"
|
||||
],
|
||||
"ios": [
|
||||
"dist/assets",
|
||||
"dist/main.ios.jsbundle"
|
||||
],
|
||||
"macos": [
|
||||
"dist/assets",
|
||||
"dist/main.macos.jsbundle"
|
||||
],
|
||||
"windows": [
|
||||
"dist/assets",
|
||||
"dist/main.windows.bundle"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
A path must be relative to the path of `app.json`, and can point to both a file
|
||||
or a directory.
|
|
@ -0,0 +1,9 @@
|
|||
In single-app mode, the component with the specified slug gets launched
|
||||
automatically, essentially behaving as a normal app.
|
||||
|
||||
Defaults to multi-app mode.
|
||||
|
||||
For more details, see [its dedicated page](Single-app-Mode).
|
||||
|
||||
Introduced in
|
||||
<a href='//github.com/microsoft/react-native-test-app/releases/tag/1.3.0'>1.3.0</a>.
|
|
@ -0,0 +1,8 @@
|
|||
Sets the path to your
|
||||
<a href='https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/appx-package-manifest'>app
|
||||
package manifest</a>. If none is set, a default manifest will be provided.
|
||||
Changes to this property will not be automatically be picked up; you need to
|
||||
re-run `npx install-windows-test-app` to update the solution.
|
||||
|
||||
Introduced in
|
||||
<a href='//github.com/microsoft/react-native-test-app/releases/tag/0.5.5'>0.5.5</a>.
|
|
@ -0,0 +1,6 @@
|
|||
The path to the certificate to use. If specified, it will also enable package
|
||||
signing. Changes to this property will not be automatically be picked up; you
|
||||
need to re-run `npx install-windows-test-app` to update the solution.
|
||||
|
||||
Introduced in
|
||||
<a href='//github.com/microsoft/react-native-test-app/releases/tag/1.1.0'>1.1.0</a>.
|
|
@ -0,0 +1,6 @@
|
|||
The password for the private key in the certificate. Leave unset if no password.
|
||||
Changes to this property will not be automatically be picked up; you need to
|
||||
re-run `npx install-windows-test-app` to update the solution.
|
||||
|
||||
Introduced in
|
||||
<a href='//github.com/microsoft/react-native-test-app/releases/tag/1.1.0'>1.1.0</a>.
|
|
@ -0,0 +1,6 @@
|
|||
This value must match the thumbprint in the signing certificate, or be unset.
|
||||
Changes to this property will not be automatically be picked up; you need to
|
||||
re-run `npx install-windows-test-app` to update the solution.
|
||||
|
||||
Introduced in
|
||||
<a href='//github.com/microsoft/react-native-test-app/releases/tag/1.1.0'>1.1.0</a>.
|
|
@ -1,83 +1,69 @@
|
|||
#!/usr/bin/env node
|
||||
// @ts-check
|
||||
|
||||
import { readFileSync } from "fs";
|
||||
import { generateSchema } from "./generate-schema.mjs";
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* description?: string;
|
||||
* type: "array";
|
||||
* items: { $ref: string; };
|
||||
* }} SchemaArrayProperty
|
||||
*
|
||||
* @typedef {{
|
||||
* description?: string;
|
||||
* type: "string";
|
||||
* enum?: string[];
|
||||
* }} SchemaStringProperty
|
||||
*
|
||||
* @typedef {{
|
||||
* description?: string;
|
||||
* allOf?: { $ref: string; }[];
|
||||
* type: "object";
|
||||
* properties: Record<string, SchemaArrayProperty | SchemaObjectProperty | SchemaStringProperty>;
|
||||
* }} SchemaObjectProperty
|
||||
* @typedef {import("./generate-schema.mjs").Schema} Schema
|
||||
* @typedef {import("./generate-schema.mjs").SchemaDefinition} SchemaDefinition
|
||||
*/
|
||||
const schema = (() => {
|
||||
const content = readFileSync("schema.json", { encoding: "utf-8" });
|
||||
return JSON.parse(content);
|
||||
})();
|
||||
|
||||
/**
|
||||
* Renders the specified JSON object schema.
|
||||
* @param {SchemaObjectProperty} definition
|
||||
* @param {string[]} lines
|
||||
* @param {string} scope
|
||||
*/
|
||||
function render(definition, lines, scope = "") {
|
||||
definition.allOf?.forEach(({ $ref }) => {
|
||||
render(schema.$defs[$ref.replace("#/$defs/", "")], lines, scope);
|
||||
});
|
||||
async function generateManifestDocs() {
|
||||
const schema = await generateSchema();
|
||||
|
||||
if (!definition.properties) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Renders the specified JSON object schema.
|
||||
* @param {Schema | SchemaDefinition} definition
|
||||
* @param {string[]} lines
|
||||
* @param {string} scope
|
||||
*/
|
||||
const render = (definition, lines, scope = "") => {
|
||||
definition.allOf?.forEach(({ $ref }) => {
|
||||
render(schema.$defs[$ref.replace("#/$defs/", "")], lines, scope);
|
||||
});
|
||||
|
||||
const breadcrumb = (() => {
|
||||
let count = 0;
|
||||
const length = scope.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
if (scope.charAt(i) === "/") {
|
||||
count++;
|
||||
if (!definition.properties) {
|
||||
return;
|
||||
}
|
||||
|
||||
const breadcrumb = (() => {
|
||||
let count = 0;
|
||||
const length = scope.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
if (scope.charAt(i) === "/") {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return ".".repeat(count);
|
||||
})();
|
||||
|
||||
for (const [key, def] of Object.entries(definition.properties)) {
|
||||
const { markdownDescription, type } = def;
|
||||
if (markdownDescription) {
|
||||
const anchor =
|
||||
breadcrumb.length < 2
|
||||
? `<a name="${scope
|
||||
.split("/")
|
||||
.slice(1, 3)
|
||||
.concat([key])
|
||||
.join(".")}" />`
|
||||
: "";
|
||||
lines.push("<tr>");
|
||||
lines.push(`<td valign='baseline'>${anchor}${breadcrumb}${key}</td>`);
|
||||
lines.push(`<td>\n\n${markdownDescription}\n</td>`);
|
||||
lines.push("</tr>");
|
||||
}
|
||||
if (type === "object") {
|
||||
render(def, lines, scope + `/${key}`);
|
||||
}
|
||||
}
|
||||
return ".".repeat(count);
|
||||
})();
|
||||
};
|
||||
|
||||
for (const [key, def] of Object.entries(definition.properties)) {
|
||||
const { description, type } = def;
|
||||
if (description) {
|
||||
const anchor =
|
||||
breadcrumb.length < 2
|
||||
? `<a name="${scope
|
||||
.split("/")
|
||||
.slice(1, 3)
|
||||
.concat([key])
|
||||
.join(".")}" />`
|
||||
: "";
|
||||
lines.push("<tr>");
|
||||
lines.push(`<td valign='baseline'>${anchor}${breadcrumb}${key}</td>`);
|
||||
lines.push(`<td>\n\n${description}\n\n</td>`);
|
||||
lines.push("</tr>");
|
||||
}
|
||||
if (type === "object") {
|
||||
render(def, lines, scope + `/${key}`);
|
||||
}
|
||||
}
|
||||
const lines = ["<table>"];
|
||||
render(schema, lines);
|
||||
lines.push("</table>");
|
||||
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
const lines = ["<table>"];
|
||||
render(schema, lines);
|
||||
lines.push("</table>");
|
||||
|
||||
console.log(lines.join("\n"));
|
||||
generateManifestDocs().then(console.log).catch(console.error);
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
// @ts-check
|
||||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { generateSchema } from "./generate-schema.mjs";
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
|
@ -19,23 +22,10 @@ const path = require("path");
|
|||
* structEnd: string;
|
||||
* }} Language
|
||||
*
|
||||
* @typedef {{
|
||||
* type: "array";
|
||||
* items: { "$ref": string; };
|
||||
* }} SchemaArrayProperty
|
||||
*
|
||||
* @typedef {{
|
||||
* type: "string";
|
||||
* enum?: string[];
|
||||
* }} SchemaStringProperty
|
||||
*
|
||||
* @typedef {{
|
||||
* type: "object";
|
||||
* properties: Record<string, SchemaArrayProperty | SchemaObjectProperty | SchemaStringProperty>;
|
||||
* required?: string[];
|
||||
* }} SchemaObjectProperty
|
||||
* @typedef {import("./generate-schema.mjs").Schema} Schema
|
||||
* @typedef {import("./generate-schema.mjs").SchemaDefinition} SchemaDefinition
|
||||
*/
|
||||
const schema = require("../schema.json");
|
||||
const thisScript = fileURLToPath(import.meta.url);
|
||||
|
||||
/**
|
||||
* Returns the struct name of the definition key or reference.
|
||||
|
@ -161,7 +151,7 @@ function getLanguage(output) {
|
|||
/**
|
||||
* Generates a data model from the specified schema definition.
|
||||
* @param {string} name
|
||||
* @param {SchemaObjectProperty} definition
|
||||
* @param {SchemaDefinition} definition
|
||||
* @param {Language} lang
|
||||
* @returns {string[]}
|
||||
*/
|
||||
|
@ -196,12 +186,13 @@ function generateType(name, definition, lang) {
|
|||
|
||||
/**
|
||||
* Generates manifest data models and writes them to specified path.
|
||||
* @param {Schema} schema
|
||||
* @param {string} output
|
||||
*/
|
||||
async function generate(output) {
|
||||
async function generate(schema, output) {
|
||||
const lang = getLanguage(output);
|
||||
const lines = [
|
||||
`// This file was generated by ${path.basename(__filename)}.`,
|
||||
`// This file was generated by ${path.basename(thisScript)}.`,
|
||||
"// DO NOT MODIFY. ALL CHANGES WILL BE OVERWRITTEN.",
|
||||
"",
|
||||
];
|
||||
|
@ -215,7 +206,7 @@ async function generate(output) {
|
|||
lines.push(
|
||||
...generateType(
|
||||
typename(key),
|
||||
/** @type {SchemaObjectProperty} */ (definition),
|
||||
/** @type {SchemaDefinition} */ (definition),
|
||||
lang
|
||||
),
|
||||
""
|
||||
|
@ -230,28 +221,34 @@ async function generate(output) {
|
|||
|
||||
const code = lines.join("\n");
|
||||
|
||||
const fs = require("fs/promises");
|
||||
const content = await fs.readFile(output, { encoding: "utf-8" });
|
||||
if (content !== code) {
|
||||
fs.writeFile(output, code);
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"android",
|
||||
"app",
|
||||
"src",
|
||||
"main",
|
||||
"java",
|
||||
"com",
|
||||
"microsoft",
|
||||
"reacttestapp",
|
||||
"manifest",
|
||||
"Manifest.kt"
|
||||
),
|
||||
path.join(__dirname, "..", "ios", "ReactTestApp", "Manifest.swift"),
|
||||
path.join(__dirname, "..", "windows", "ReactTestApp", "Manifest.h"),
|
||||
].forEach((output) => generate(output));
|
||||
async function main() {
|
||||
const schema = await generateSchema();
|
||||
const scriptsDir = path.dirname(thisScript);
|
||||
|
||||
[
|
||||
path.join(
|
||||
scriptsDir,
|
||||
"..",
|
||||
"android",
|
||||
"app",
|
||||
"src",
|
||||
"main",
|
||||
"java",
|
||||
"com",
|
||||
"microsoft",
|
||||
"reacttestapp",
|
||||
"manifest",
|
||||
"Manifest.kt"
|
||||
),
|
||||
path.join(scriptsDir, "..", "ios", "ReactTestApp", "Manifest.swift"),
|
||||
path.join(scriptsDir, "..", "windows", "ReactTestApp", "Manifest.h"),
|
||||
].forEach((output) => generate(schema, output));
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
|
@ -0,0 +1,321 @@
|
|||
#!/usr/bin/env node
|
||||
// @ts-check
|
||||
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as os from "node:os";
|
||||
import * as path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
/**
|
||||
* @typedef {Awaited<ReturnType<typeof generateSchema>>} Schema
|
||||
* @typedef {Schema["$defs"][keyof Schema["$defs"]]} SchemaDefinition
|
||||
*/
|
||||
|
||||
const thisScript = fileURLToPath(import.meta.url);
|
||||
const docsDir = path.join(path.dirname(thisScript), "docs");
|
||||
|
||||
/**
|
||||
* @param {string} content
|
||||
* @returns {string}
|
||||
*/
|
||||
function extractBrief(content) {
|
||||
const endBrief = content.indexOf("\n\n");
|
||||
return content.substring(0, endBrief);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async function readMarkdown(name) {
|
||||
const filename = path.join(docsDir, name + ".md");
|
||||
const md = await fs.readFile(filename, { encoding: "utf-8" });
|
||||
return trimCarriageReturn(md);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
const trimCarriageReturn =
|
||||
os.EOL === "\r\n" ? (str) => str.replace(/\r/g, "") : (str) => str;
|
||||
|
||||
export async function generateSchema() {
|
||||
const docs = {
|
||||
bundleRoot: null,
|
||||
components: null,
|
||||
resources: null,
|
||||
singleApp: null,
|
||||
"android.signingConfigs": null,
|
||||
"ios.codeSignEntitlements": null,
|
||||
"ios.codeSignIdentity": null,
|
||||
"ios.developmentTeam": null,
|
||||
"windows.appxManifest": null,
|
||||
"windows.certificateKeyFile": null,
|
||||
"windows.certificatePassword": null,
|
||||
"windows.certificateThumbprint": null,
|
||||
};
|
||||
for (const key of Object.keys(docs)) {
|
||||
docs[key] = readMarkdown(key);
|
||||
}
|
||||
|
||||
return {
|
||||
$defs: {
|
||||
component: {
|
||||
type: "object",
|
||||
properties: {
|
||||
appKey: {
|
||||
description:
|
||||
"The app key passed to `AppRegistry.registerComponent()`.",
|
||||
type: "string",
|
||||
},
|
||||
displayName: {
|
||||
description: "Name to be displayed on home screen.",
|
||||
type: "string",
|
||||
},
|
||||
initialProperties: {
|
||||
description: "Properties that should be passed to your component.",
|
||||
type: "object",
|
||||
},
|
||||
presentationStyle: {
|
||||
description: "The style in which to present your component.",
|
||||
type: "string",
|
||||
enum: ["default", "modal"],
|
||||
},
|
||||
slug: {
|
||||
description:
|
||||
"URL slug that uniquely identifies this component. Used for deep linking.",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
required: ["appKey"],
|
||||
},
|
||||
manifest: {
|
||||
type: "object",
|
||||
properties: {
|
||||
name: {
|
||||
type: "string",
|
||||
},
|
||||
displayName: {
|
||||
type: "string",
|
||||
},
|
||||
bundleRoot: {
|
||||
description: extractBrief(await docs.bundleRoot),
|
||||
markdownDescription: await docs.bundleRoot,
|
||||
type: "string",
|
||||
},
|
||||
singleApp: {
|
||||
description: extractBrief(await docs.singleApp),
|
||||
markdownDescription: await docs.singleApp,
|
||||
type: "string",
|
||||
},
|
||||
components: {
|
||||
description: extractBrief(await docs.components),
|
||||
markdownDescription: await docs.components,
|
||||
type: "array",
|
||||
items: { $ref: "#/$defs/component" },
|
||||
},
|
||||
},
|
||||
required: ["name", "displayName"],
|
||||
},
|
||||
signingConfig: {
|
||||
type: "object",
|
||||
properties: {
|
||||
keyAlias: {
|
||||
description:
|
||||
"Use this property to specify the alias of key to use in the store",
|
||||
type: "string",
|
||||
},
|
||||
keyPassword: {
|
||||
description:
|
||||
"Use this property to specify the password of key in the store",
|
||||
type: "string",
|
||||
},
|
||||
storeFile: {
|
||||
description:
|
||||
"Use this property to specify the relative file path to the key store file",
|
||||
type: "string",
|
||||
},
|
||||
storePassword: {
|
||||
description:
|
||||
"Use this property to specify the password of the key store",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
required: ["storeFile"],
|
||||
"exclude-from-codegen": true,
|
||||
},
|
||||
},
|
||||
allOf: [{ $ref: "#/$defs/manifest" }],
|
||||
type: "object",
|
||||
properties: {
|
||||
resources: {
|
||||
description: extractBrief(await docs.resources),
|
||||
markdownDescription: await docs.resources,
|
||||
oneOf: [
|
||||
{
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
uniqueItems: true,
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
android: {
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
uniqueItems: true,
|
||||
},
|
||||
ios: {
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
uniqueItems: true,
|
||||
},
|
||||
macos: {
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
uniqueItems: true,
|
||||
},
|
||||
windows: {
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
uniqueItems: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
android: {
|
||||
description: "Android specific properties go here.",
|
||||
type: "object",
|
||||
properties: {
|
||||
package: {
|
||||
description:
|
||||
"Use this property to set the <a href='https://developer.android.com/studio/build/application-id'>application ID</a> of the APK. The value is set to `applicationId` in `build.gradle`.",
|
||||
type: "string",
|
||||
},
|
||||
signingConfigs: {
|
||||
description: extractBrief(await docs["android.signingConfigs"]),
|
||||
markdownDescription: await docs["android.signingConfigs"],
|
||||
type: "object",
|
||||
properties: {
|
||||
debug: {
|
||||
description:
|
||||
"Use this property for the debug signing config for the app. The value `storeFile` is required. Android defaults will be provided for other properties.",
|
||||
allOf: [{ $ref: "#/$defs/signingConfig" }],
|
||||
type: "object",
|
||||
},
|
||||
release: {
|
||||
description:
|
||||
"Use this property for the release signing config for the app. The value `storeFile` is required. Android defaults will be provided for other properties.",
|
||||
allOf: [{ $ref: "#/$defs/signingConfig" }],
|
||||
type: "object",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ios: {
|
||||
description: "iOS specific properties go here.",
|
||||
type: "object",
|
||||
properties: {
|
||||
bundleIdentifier: {
|
||||
description:
|
||||
"Use this property to set the bundle identifier of the final app bundle. This is the same as setting `PRODUCT_BUNDLE_IDENTIFIER` in Xcode.",
|
||||
type: "string",
|
||||
},
|
||||
codeSignEntitlements: {
|
||||
description: extractBrief(await docs["ios.codeSignEntitlements"]),
|
||||
markdownDescription: await docs["ios.codeSignEntitlements"],
|
||||
type: "string",
|
||||
},
|
||||
codeSignIdentity: {
|
||||
description: extractBrief(await docs["ios.codeSignIdentity"]),
|
||||
markdownDescription: await docs["ios.codeSignIdentity"],
|
||||
type: "string",
|
||||
},
|
||||
developmentTeam: {
|
||||
description: extractBrief(await docs["ios.developmentTeam"]),
|
||||
markdownDescription: await docs["ios.developmentTeam"],
|
||||
type: "string",
|
||||
},
|
||||
reactNativePath: {
|
||||
description:
|
||||
'Sets a custom path to React Native. Useful for when `require("react-native")` does not return the desired path.',
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
macos: {
|
||||
description: "macOS specific properties go here.",
|
||||
type: "object",
|
||||
properties: {
|
||||
bundleIdentifier: {
|
||||
description:
|
||||
"Use this property to set the bundle identifier of the final app bundle. This is the same as setting `PRODUCT_BUNDLE_IDENTIFIER` in Xcode.",
|
||||
type: "string",
|
||||
},
|
||||
codeSignEntitlements: {
|
||||
description: extractBrief(await docs["ios.codeSignEntitlements"]),
|
||||
markdownDescription: await docs["ios.codeSignEntitlements"],
|
||||
type: "string",
|
||||
},
|
||||
codeSignIdentity: {
|
||||
description: extractBrief(await docs["ios.codeSignIdentity"]),
|
||||
markdownDescription: await docs["ios.codeSignIdentity"],
|
||||
type: "string",
|
||||
},
|
||||
developmentTeam: {
|
||||
description: extractBrief(await docs["ios.developmentTeam"]),
|
||||
markdownDescription: await docs["ios.developmentTeam"],
|
||||
type: "string",
|
||||
},
|
||||
reactNativePath: {
|
||||
description:
|
||||
'Sets a custom path to React Native for macOS. Useful for when `require("react-native-macos")` does not return the desired path.',
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
windows: {
|
||||
description: "Windows specific properties go here.",
|
||||
type: "object",
|
||||
properties: {
|
||||
appxManifest: {
|
||||
description: extractBrief(await docs["windows.appxManifest"]),
|
||||
markdownDescription: await docs["windows.appxManifest"],
|
||||
type: "string",
|
||||
},
|
||||
certificateKeyFile: {
|
||||
description: extractBrief(await docs["windows.certificateKeyFile"]),
|
||||
markdownDescription: await docs["windows.certificateKeyFile"],
|
||||
type: "string",
|
||||
},
|
||||
certificatePassword: {
|
||||
description: extractBrief(
|
||||
await docs["windows.certificatePassword"]
|
||||
),
|
||||
markdownDescription: await docs["windows.certificatePassword"],
|
||||
type: "string",
|
||||
},
|
||||
certificateThumbprint: {
|
||||
description: extractBrief(
|
||||
await docs["windows.certificateThumbprint"]
|
||||
),
|
||||
markdownDescription: await docs["windows.certificateThumbprint"],
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (process.argv[1] === thisScript) {
|
||||
generateSchema()
|
||||
.then((schema) => {
|
||||
return trimCarriageReturn(JSON.stringify(schema, undefined, 2)) + "\n";
|
||||
})
|
||||
.then((schema) => fs.writeFile("schema.json", schema))
|
||||
.catch(console.error);
|
||||
}
|
|
@ -39,6 +39,7 @@ function makeValidator() {
|
|||
cxt.fail(_`${data} %2 ${op} 0`);
|
||||
},
|
||||
});
|
||||
ajv.addKeyword({ keyword: "markdownDescription" });
|
||||
return ajv.compile(require(`${__dirname}/../schema.json`));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// This file was generated by generate-manifest.js.
|
||||
// This file was generated by generate-manifest.mjs.
|
||||
// DO NOT MODIFY. ALL CHANGES WILL BE OVERWRITTEN.
|
||||
|
||||
#ifndef REACTTESTAPP_MANIFEST_H_
|
||||
|
|
Загрузка…
Ссылка в новой задаче