@react-native-windows/codegen 0.0.0-canary.25 → 0.0.0-canary.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -9
- package/lib-commonjs/Cli.js +36 -2
- package/lib-commonjs/Cli.js.map +1 -1
- package/lib-commonjs/generators/GenerateTypeScript.d.ts +11 -0
- package/lib-commonjs/generators/GenerateTypeScript.js +166 -0
- package/lib-commonjs/generators/GenerateTypeScript.js.map +1 -0
- package/package.json +1 -1
- package/src/Cli.ts +45 -2
- package/src/generators/GenerateTypeScript.ts +247 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,46 @@
|
|
|
1
1
|
# Change Log - @react-native-windows/codegen
|
|
2
2
|
|
|
3
|
-
This log was last generated on Wed, 09
|
|
3
|
+
This log was last generated on Wed, 09 Mar 2022 06:08:38 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
-
## 0.0.0-canary.
|
|
7
|
+
## 0.0.0-canary.28
|
|
8
8
|
|
|
9
|
-
Wed, 09
|
|
9
|
+
Wed, 09 Mar 2022 06:08:38 GMT
|
|
10
10
|
|
|
11
11
|
### Changes
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
- Bump @react-native-windows/fs to v1.0.2
|
|
15
|
-
- Bump @rnw-scripts/eslint-config to v1.1.11
|
|
16
|
-
- Bump @rnw-scripts/jest-unittest-config to v1.2.6
|
|
17
|
-
- Bump @rnw-scripts/just-task to v2.2.3
|
|
18
|
-
- Bump @rnw-scripts/ts-config to v2.0.2
|
|
13
|
+
- Fix turbo module codegen to generate correct import statement and registration (53799235+ZihanChen-MSFT@users.noreply.github.com)
|
|
19
14
|
|
|
15
|
+
## 0.0.0-canary.27
|
|
16
|
+
|
|
17
|
+
Fri, 04 Mar 2022 06:09:13 GMT
|
|
18
|
+
|
|
19
|
+
### Changes
|
|
20
|
+
|
|
21
|
+
- Generate fabric eventemitter.cpp (acoates@microsoft.com)
|
|
22
|
+
|
|
23
|
+
## 0.0.0-canary.26
|
|
24
|
+
|
|
25
|
+
Thu, 24 Feb 2022 06:07:47 GMT
|
|
26
|
+
|
|
27
|
+
### Changes
|
|
28
|
+
|
|
29
|
+
- Add TypeScript turbo module definition as new codegen traget (53799235+ZihanChen-MSFT@users.noreply.github.com)
|
|
30
|
+
|
|
31
|
+
## 0.0.0-canary.25
|
|
32
|
+
|
|
33
|
+
Wed, 09 Feb 2022 06:09:36 GMT
|
|
34
|
+
|
|
35
|
+
### Changes
|
|
36
|
+
|
|
37
|
+
- Bump minimum Node version to 14 (jthysell@microsoft.com)
|
|
38
|
+
- Bump @react-native-windows/fs to v1.0.2
|
|
39
|
+
- Bump @rnw-scripts/eslint-config to v1.1.11
|
|
40
|
+
- Bump @rnw-scripts/jest-unittest-config to v1.2.6
|
|
41
|
+
- Bump @rnw-scripts/just-task to v2.2.3
|
|
42
|
+
- Bump @rnw-scripts/ts-config to v2.0.2
|
|
43
|
+
|
|
20
44
|
## 0.0.0-canary.24
|
|
21
45
|
|
|
22
46
|
Tue, 08 Feb 2022 18:21:23 GMT
|
package/lib-commonjs/Cli.js
CHANGED
|
@@ -14,6 +14,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
14
14
|
const fs_1 = __importDefault(require("@react-native-windows/fs"));
|
|
15
15
|
const globby_1 = __importDefault(require("globby"));
|
|
16
16
|
const GenerateNM2_1 = require("./generators/GenerateNM2");
|
|
17
|
+
const GenerateTypeScript_1 = require("./generators/GenerateTypeScript");
|
|
17
18
|
// @ts-ignore
|
|
18
19
|
const flow_1 = require("react-native-tscodegen/lib/rncodegen/src/parsers/flow");
|
|
19
20
|
// @ts-ignore
|
|
@@ -27,6 +28,16 @@ const argv = yargs_1.default.options({
|
|
|
27
28
|
type: 'array',
|
|
28
29
|
describe: 'glob patterns for files which contains specs',
|
|
29
30
|
},
|
|
31
|
+
ts: {
|
|
32
|
+
type: 'boolean',
|
|
33
|
+
describe: 'generate turbo module definition files in TypeScript',
|
|
34
|
+
default: false,
|
|
35
|
+
},
|
|
36
|
+
outdir: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
describe: 'output directory',
|
|
39
|
+
default: 'codegen',
|
|
40
|
+
},
|
|
30
41
|
test: {
|
|
31
42
|
type: 'boolean',
|
|
32
43
|
describe: 'Verify that the generated output is unchanged',
|
|
@@ -128,7 +139,25 @@ function writeMapToFiles(map, outputDir) {
|
|
|
128
139
|
}
|
|
129
140
|
function parseFlowFile(filename) {
|
|
130
141
|
try {
|
|
131
|
-
|
|
142
|
+
const schema = (0, flow_1.parseFile)(filename);
|
|
143
|
+
// there will be at most one turbo module per file
|
|
144
|
+
const moduleName = Object.keys(schema.modules)[0];
|
|
145
|
+
if (moduleName) {
|
|
146
|
+
const spec = schema.modules[moduleName];
|
|
147
|
+
if (spec.type === 'NativeModule') {
|
|
148
|
+
const contents = fs_1.default.readFileSync(filename, 'utf8');
|
|
149
|
+
if (contents) {
|
|
150
|
+
// This is a temporary implementation until such information is added to the schema in facebook/react-native
|
|
151
|
+
if (contents.includes('TurboModuleRegistry.get<')) {
|
|
152
|
+
(0, GenerateTypeScript_1.setOptionalTurboModule)(spec, true);
|
|
153
|
+
}
|
|
154
|
+
else if (contents.includes('TurboModuleRegistry.getEnforcing<')) {
|
|
155
|
+
(0, GenerateTypeScript_1.setOptionalTurboModule)(spec, false);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return schema;
|
|
132
161
|
}
|
|
133
162
|
catch (e) {
|
|
134
163
|
if (e instanceof Error) {
|
|
@@ -161,7 +190,11 @@ function generate({ libraryName, schema, outputDirectory, moduleSpecName }, { /*
|
|
|
161
190
|
const generatorShadowNodeCPP = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateShadowNodeCPP').generate;
|
|
162
191
|
const generatorComponentDescriptorH = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateComponentDescriptorH').generate;
|
|
163
192
|
const generatorEventEmitterH = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterH').generate;
|
|
193
|
+
const generatorEventEmitterCPP = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterCpp').generate;
|
|
164
194
|
normalizeFileMap(generateNM2(libraryName, schema, moduleSpecName), outputDirectory, generatedFiles);
|
|
195
|
+
if (argv.ts) {
|
|
196
|
+
normalizeFileMap((0, GenerateTypeScript_1.generateTypeScript)(libraryName, schema, moduleSpecName), outputDirectory, generatedFiles);
|
|
197
|
+
}
|
|
165
198
|
if (Object.keys(schema.modules).some((moduleName) => schema.modules[moduleName].type === 'Component')) {
|
|
166
199
|
const componentGenerators = [
|
|
167
200
|
generatorPropsH,
|
|
@@ -170,6 +203,7 @@ function generate({ libraryName, schema, outputDirectory, moduleSpecName }, { /*
|
|
|
170
203
|
generatorShadowNodeCPP,
|
|
171
204
|
generatorComponentDescriptorH,
|
|
172
205
|
generatorEventEmitterH,
|
|
206
|
+
generatorEventEmitterCPP,
|
|
173
207
|
];
|
|
174
208
|
componentGenerators.forEach((generator) => {
|
|
175
209
|
const generated = generator(libraryName, schema, moduleSpecName);
|
|
@@ -194,6 +228,6 @@ else {
|
|
|
194
228
|
}
|
|
195
229
|
const libraryName = argv.libraryName;
|
|
196
230
|
const moduleSpecName = 'moduleSpecName';
|
|
197
|
-
const outputDirectory =
|
|
231
|
+
const outputDirectory = argv.outdir;
|
|
198
232
|
generate({ libraryName, schema, outputDirectory, moduleSpecName }, { generators: [], test: false });
|
|
199
233
|
//# sourceMappingURL=Cli.js.map
|
package/lib-commonjs/Cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Cli.js","sourceRoot":"","sources":["../src/Cli.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright (c) Microsoft Corporation.\n * Licensed under the MIT License.\n *\n * @format\n */\n\nimport yargs from 'yargs';\nimport path from 'path';\nimport fs from '@react-native-windows/fs';\nimport globby from 'globby';\nimport {createNM2Generator} from './generators/GenerateNM2';\n// @ts-ignore\nimport {parseFile} from 'react-native-tscodegen/lib/rncodegen/src/parsers/flow';\n// @ts-ignore\nimport schemaValidator from 'react-native-tscodegen/lib/rncodegen/src/schemaValidator';\n\nconst argv = yargs.options({\n file: {\n type: 'string',\n describe: 'file which contains spec',\n },\n files: {\n type: 'array',\n describe: 'glob patterns for files which contains specs',\n },\n test: {\n type: 'boolean',\n describe: 'Verify that the generated output is unchanged',\n },\n namespace: {\n type: 'string',\n describe: 'C++/C# Namespace to put generated native modules in',\n default: 'MyNamespace',\n },\n libraryName: {\n type: 'string',\n required: true,\n describe: 'Used for part of the path generated within the codegen dir',\n },\n}).argv;\n\nimport {SchemaType} from 'react-native-tscodegen';\n\ninterface Options {\n libraryName: string;\n schema: SchemaType;\n outputDirectory: string;\n moduleSpecName: string;\n}\n\ninterface Config {\n generators: any[] /*Generators[]*/;\n test?: boolean;\n}\n\n/*\nconst GENERATORS = {\n descriptors: [generateComponentDescriptorH.generate],\n events: [\n generateEventEmitterCpp.generate,\n generateEventEmitterH.generate,\n generateModuleHObjCpp.generate,\n generateModuleMm.generate,\n ],\n props: [\n generateComponentHObjCpp.generate,\n generatePropsCpp.generate,\n generatePropsH.generate,\n generatePropsJavaInterface.generate,\n generatePropsJavaDelegate.generate,\n ],\n modules: [generateModuleCpp.generate, generateModuleH.generate],\n tests: [generateTests.generate],\n 'shadow-nodes': [\n generateShadowNodeCpp.generate,\n generateShadowNodeH.generate,\n ],\n};\n*/\n\nfunction normalizeFileMap(\n map: Map<string, string>,\n outputDir: string,\n outMap: Map<string, string>,\n): void {\n for (const [fileName, contents] of map) {\n const location = path.join(outputDir, fileName);\n outMap.set(path.normalize(location), contents);\n }\n}\n\nfunction checkFilesForChanges(\n map: Map<string, string>,\n outputDir: string,\n): boolean {\n let hasChanges = false;\n\n const allExistingFiles = globby\n .sync(`${outputDir}/**`)\n .map((_) => path.normalize(_))\n .sort();\n const allGeneratedFiles = [...map.keys()]\n .map((_) => path.normalize(_))\n .sort();\n\n if (\n allExistingFiles.length !== allGeneratedFiles.length ||\n !allExistingFiles.every((val, index) => val === allGeneratedFiles[index])\n )\n return true;\n\n for (const [fileName, contents] of map) {\n if (!fs.existsSync(fileName)) {\n hasChanges = true;\n continue;\n }\n\n const currentContents = fs.readFileSync(fileName, 'utf8');\n if (currentContents !== contents) {\n console.error(`- ${fileName} has changed`);\n hasChanges = true;\n continue;\n }\n }\n\n return hasChanges;\n}\n\nfunction writeMapToFiles(map: Map<string, string>, outputDir: string) {\n let success = true;\n\n // This ensures that we delete any generated files from modules that have been deleted\n const allExistingFiles = globby.sync(`${outputDir}/**`);\n allExistingFiles.forEach((existingFile) => {\n if (!map.has(path.normalize(existingFile))) {\n fs.unlinkSync(existingFile);\n }\n });\n\n for (const [fileName, contents] of map) {\n try {\n fs.mkdirSync(path.dirname(fileName), {recursive: true});\n\n if (fs.existsSync(fileName)) {\n const currentContents = fs.readFileSync(fileName, 'utf8');\n // Don't update the files if there are no changes as this breaks incremental builds\n if (currentContents === contents) {\n continue;\n }\n }\n\n fs.writeFileSync(fileName, contents);\n } catch (error) {\n success = false;\n console.error(`Failed to write ${fileName} to ${fileName}`, error);\n }\n }\n\n return success;\n}\n\nfunction parseFlowFile(filename: string): SchemaType {\n try {\n return parseFile(filename);\n } catch (e) {\n if (e instanceof Error) {\n e.message = `(${filename}): ${e.message}`;\n }\n throw e;\n }\n}\n\nfunction combineSchemas(files: string[]): SchemaType {\n return files.reduce(\n (merged, filename) => {\n const contents = fs.readFileSync(filename, 'utf8');\n if (\n contents &&\n (/export\\s+default\\s+\\(?codegenNativeComponent</.test(contents) ||\n contents.includes('extends TurboModule'))\n ) {\n const schema = parseFlowFile(filename);\n merged.modules = {...merged.modules, ...schema.modules};\n }\n return merged;\n },\n {modules: {}},\n );\n}\n\nfunction generate(\n {libraryName, schema, outputDirectory, moduleSpecName}: Options,\n {/*generators,*/ test}: Config,\n): boolean {\n schemaValidator.validate(schema);\n\n const componentOutputdir = path.join(\n outputDirectory,\n 'react/components',\n libraryName,\n );\n\n const generatedFiles = new Map<string, string>();\n\n generatedFiles.set(\n path.join(outputDirectory, '.clang-format'),\n 'DisableFormat: true\\nSortIncludes: false',\n );\n\n const generateNM2 = createNM2Generator({namespace: argv.namespace});\n const generatorPropsH =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsH').generate;\n const generatorPropsCPP =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsCPP').generate;\n const generatorShadowNodeH =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateShadowNodeH').generate;\n const generatorShadowNodeCPP =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateShadowNodeCPP').generate;\n const generatorComponentDescriptorH =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateComponentDescriptorH').generate;\n const generatorEventEmitterH =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterH').generate;\n\n normalizeFileMap(\n generateNM2(libraryName, schema, moduleSpecName),\n outputDirectory,\n generatedFiles,\n );\n\n if (\n Object.keys(schema.modules).some(\n (moduleName) => schema.modules[moduleName].type === 'Component',\n )\n ) {\n const componentGenerators = [\n generatorPropsH,\n generatorPropsCPP,\n generatorShadowNodeH,\n generatorShadowNodeCPP,\n generatorComponentDescriptorH,\n generatorEventEmitterH,\n ];\n\n componentGenerators.forEach((generator) => {\n const generated: Map<string, string> = generator(\n libraryName,\n schema,\n moduleSpecName,\n );\n normalizeFileMap(generated, componentOutputdir, generatedFiles);\n });\n }\n\n if (test === true) {\n return checkFilesForChanges(generatedFiles, outputDirectory);\n }\n\n return writeMapToFiles(generatedFiles, outputDirectory);\n}\n\nif ((argv.file && argv.files) || (!argv.file && !argv.files)) {\n console.error('You must specify either --file or --files.');\n process.exit(1);\n}\n\nlet schema: SchemaType;\nif (argv.file) {\n schema = parseFlowFile(argv.file);\n} else {\n schema = combineSchemas(globby.sync(argv.files as string[]));\n}\n\nconst libraryName = argv.libraryName;\nconst moduleSpecName = 'moduleSpecName';\nconst outputDirectory = 'codegen';\ngenerate(\n {libraryName, schema, outputDirectory, moduleSpecName},\n {generators: [], test: false},\n);\n"]}
|
|
1
|
+
{"version":3,"file":"Cli.js","sourceRoot":"","sources":["../src/Cli.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright (c) Microsoft Corporation.\n * Licensed under the MIT License.\n *\n * @format\n */\n\nimport yargs from 'yargs';\nimport path from 'path';\nimport fs from '@react-native-windows/fs';\nimport globby from 'globby';\nimport {createNM2Generator} from './generators/GenerateNM2';\nimport {\n generateTypeScript,\n setOptionalTurboModule,\n} from './generators/GenerateTypeScript';\n// @ts-ignore\nimport {parseFile} from 'react-native-tscodegen/lib/rncodegen/src/parsers/flow';\n// @ts-ignore\nimport schemaValidator from 'react-native-tscodegen/lib/rncodegen/src/schemaValidator';\n\nconst argv = yargs.options({\n file: {\n type: 'string',\n describe: 'file which contains spec',\n },\n files: {\n type: 'array',\n describe: 'glob patterns for files which contains specs',\n },\n ts: {\n type: 'boolean',\n describe: 'generate turbo module definition files in TypeScript',\n default: false,\n },\n outdir: {\n type: 'string',\n describe: 'output directory',\n default: 'codegen',\n },\n test: {\n type: 'boolean',\n describe: 'Verify that the generated output is unchanged',\n },\n namespace: {\n type: 'string',\n describe: 'C++/C# Namespace to put generated native modules in',\n default: 'MyNamespace',\n },\n libraryName: {\n type: 'string',\n required: true,\n describe: 'Used for part of the path generated within the codegen dir',\n },\n}).argv;\n\nimport {SchemaType} from 'react-native-tscodegen';\n\ninterface Options {\n libraryName: string;\n schema: SchemaType;\n outputDirectory: string;\n moduleSpecName: string;\n}\n\ninterface Config {\n generators: any[] /*Generators[]*/;\n test?: boolean;\n}\n\n/*\nconst GENERATORS = {\n descriptors: [generateComponentDescriptorH.generate],\n events: [\n generateEventEmitterCpp.generate,\n generateEventEmitterH.generate,\n generateModuleHObjCpp.generate,\n generateModuleMm.generate,\n ],\n props: [\n generateComponentHObjCpp.generate,\n generatePropsCpp.generate,\n generatePropsH.generate,\n generatePropsJavaInterface.generate,\n generatePropsJavaDelegate.generate,\n ],\n modules: [generateModuleCpp.generate, generateModuleH.generate],\n tests: [generateTests.generate],\n 'shadow-nodes': [\n generateShadowNodeCpp.generate,\n generateShadowNodeH.generate,\n ],\n};\n*/\n\nfunction normalizeFileMap(\n map: Map<string, string>,\n outputDir: string,\n outMap: Map<string, string>,\n): void {\n for (const [fileName, contents] of map) {\n const location = path.join(outputDir, fileName);\n outMap.set(path.normalize(location), contents);\n }\n}\n\nfunction checkFilesForChanges(\n map: Map<string, string>,\n outputDir: string,\n): boolean {\n let hasChanges = false;\n\n const allExistingFiles = globby\n .sync(`${outputDir}/**`)\n .map((_) => path.normalize(_))\n .sort();\n const allGeneratedFiles = [...map.keys()]\n .map((_) => path.normalize(_))\n .sort();\n\n if (\n allExistingFiles.length !== allGeneratedFiles.length ||\n !allExistingFiles.every((val, index) => val === allGeneratedFiles[index])\n )\n return true;\n\n for (const [fileName, contents] of map) {\n if (!fs.existsSync(fileName)) {\n hasChanges = true;\n continue;\n }\n\n const currentContents = fs.readFileSync(fileName, 'utf8');\n if (currentContents !== contents) {\n console.error(`- ${fileName} has changed`);\n hasChanges = true;\n continue;\n }\n }\n\n return hasChanges;\n}\n\nfunction writeMapToFiles(map: Map<string, string>, outputDir: string) {\n let success = true;\n\n // This ensures that we delete any generated files from modules that have been deleted\n const allExistingFiles = globby.sync(`${outputDir}/**`);\n allExistingFiles.forEach((existingFile) => {\n if (!map.has(path.normalize(existingFile))) {\n fs.unlinkSync(existingFile);\n }\n });\n\n for (const [fileName, contents] of map) {\n try {\n fs.mkdirSync(path.dirname(fileName), {recursive: true});\n\n if (fs.existsSync(fileName)) {\n const currentContents = fs.readFileSync(fileName, 'utf8');\n // Don't update the files if there are no changes as this breaks incremental builds\n if (currentContents === contents) {\n continue;\n }\n }\n\n fs.writeFileSync(fileName, contents);\n } catch (error) {\n success = false;\n console.error(`Failed to write ${fileName} to ${fileName}`, error);\n }\n }\n\n return success;\n}\n\nfunction parseFlowFile(filename: string): SchemaType {\n try {\n const schema = parseFile(filename);\n // there will be at most one turbo module per file\n const moduleName = Object.keys(schema.modules)[0];\n if (moduleName) {\n const spec = schema.modules[moduleName];\n if (spec.type === 'NativeModule') {\n const contents = fs.readFileSync(filename, 'utf8');\n if (contents) {\n // This is a temporary implementation until such information is added to the schema in facebook/react-native\n if (contents.includes('TurboModuleRegistry.get<')) {\n setOptionalTurboModule(spec, true);\n } else if (contents.includes('TurboModuleRegistry.getEnforcing<')) {\n setOptionalTurboModule(spec, false);\n }\n }\n }\n }\n return schema;\n } catch (e) {\n if (e instanceof Error) {\n e.message = `(${filename}): ${e.message}`;\n }\n throw e;\n }\n}\n\nfunction combineSchemas(files: string[]): SchemaType {\n return files.reduce(\n (merged, filename) => {\n const contents = fs.readFileSync(filename, 'utf8');\n if (\n contents &&\n (/export\\s+default\\s+\\(?codegenNativeComponent</.test(contents) ||\n contents.includes('extends TurboModule'))\n ) {\n const schema = parseFlowFile(filename);\n merged.modules = {...merged.modules, ...schema.modules};\n }\n return merged;\n },\n {modules: {}},\n );\n}\n\nfunction generate(\n {libraryName, schema, outputDirectory, moduleSpecName}: Options,\n {/*generators,*/ test}: Config,\n): boolean {\n schemaValidator.validate(schema);\n\n const componentOutputdir = path.join(\n outputDirectory,\n 'react/components',\n libraryName,\n );\n\n const generatedFiles = new Map<string, string>();\n\n generatedFiles.set(\n path.join(outputDirectory, '.clang-format'),\n 'DisableFormat: true\\nSortIncludes: false',\n );\n\n const generateNM2 = createNM2Generator({namespace: argv.namespace});\n\n const generatorPropsH =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsH').generate;\n const generatorPropsCPP =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsCPP').generate;\n const generatorShadowNodeH =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateShadowNodeH').generate;\n const generatorShadowNodeCPP =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateShadowNodeCPP').generate;\n const generatorComponentDescriptorH =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateComponentDescriptorH').generate;\n const generatorEventEmitterH =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterH').generate;\n const generatorEventEmitterCPP =\n require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterCpp').generate;\n\n normalizeFileMap(\n generateNM2(libraryName, schema, moduleSpecName),\n outputDirectory,\n generatedFiles,\n );\n\n if (argv.ts) {\n normalizeFileMap(\n generateTypeScript(libraryName, schema, moduleSpecName),\n outputDirectory,\n generatedFiles,\n );\n }\n\n if (\n Object.keys(schema.modules).some(\n (moduleName) => schema.modules[moduleName].type === 'Component',\n )\n ) {\n const componentGenerators = [\n generatorPropsH,\n generatorPropsCPP,\n generatorShadowNodeH,\n generatorShadowNodeCPP,\n generatorComponentDescriptorH,\n generatorEventEmitterH,\n generatorEventEmitterCPP,\n ];\n\n componentGenerators.forEach((generator) => {\n const generated: Map<string, string> = generator(\n libraryName,\n schema,\n moduleSpecName,\n );\n normalizeFileMap(generated, componentOutputdir, generatedFiles);\n });\n }\n\n if (test === true) {\n return checkFilesForChanges(generatedFiles, outputDirectory);\n }\n\n return writeMapToFiles(generatedFiles, outputDirectory);\n}\n\nif ((argv.file && argv.files) || (!argv.file && !argv.files)) {\n console.error('You must specify either --file or --files.');\n process.exit(1);\n}\n\nlet schema: SchemaType;\nif (argv.file) {\n schema = parseFlowFile(argv.file);\n} else {\n schema = combineSchemas(globby.sync(argv.files as string[]));\n}\n\nconst libraryName = argv.libraryName;\nconst moduleSpecName = 'moduleSpecName';\nconst outputDirectory = argv.outdir;\ngenerate(\n {libraryName, schema, outputDirectory, moduleSpecName},\n {generators: [], test: false},\n);\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
* @format
|
|
5
|
+
*/
|
|
6
|
+
import { NativeModuleSchema, SchemaType } from 'react-native-tscodegen';
|
|
7
|
+
export declare function setOptionalTurboModule(schema: NativeModuleSchema, optional: boolean): void;
|
|
8
|
+
export declare function getOptionalTurboModule(schema: NativeModuleSchema): boolean;
|
|
9
|
+
declare type FilesOutput = Map<string, string>;
|
|
10
|
+
export declare function generateTypeScript(_libraryName: string, schema: SchemaType, _moduleSpecName: string): FilesOutput;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
* @format
|
|
5
|
+
*/
|
|
6
|
+
'use strict';
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.generateTypeScript = exports.getOptionalTurboModule = exports.setOptionalTurboModule = void 0;
|
|
9
|
+
function setOptionalTurboModule(schema, optional) {
|
|
10
|
+
const cs = schema;
|
|
11
|
+
cs.optionalTurboModule = optional;
|
|
12
|
+
}
|
|
13
|
+
exports.setOptionalTurboModule = setOptionalTurboModule;
|
|
14
|
+
function getOptionalTurboModule(schema) {
|
|
15
|
+
var _a;
|
|
16
|
+
return (_a = schema.optionalTurboModule) !== null && _a !== void 0 ? _a : false;
|
|
17
|
+
}
|
|
18
|
+
exports.getOptionalTurboModule = getOptionalTurboModule;
|
|
19
|
+
const moduleTemplate = `
|
|
20
|
+
/*
|
|
21
|
+
* This file is auto-generated from a NativeModule spec file in js.
|
|
22
|
+
*
|
|
23
|
+
* This is a TypeScript turbo module definition file.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import {TurboModule, TurboModuleRegistry} from 'react-native';
|
|
27
|
+
'use strict';
|
|
28
|
+
::_MODULE_ALIASED_STRUCTS_::
|
|
29
|
+
export interface Spec extends TurboModule {
|
|
30
|
+
::_MODULE_MEMBERS_::
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default TurboModuleRegistry.::_MODULE_GETTER_::<Spec>('::_MODULE_NAME_::');
|
|
34
|
+
`;
|
|
35
|
+
function optionalSign(obj) {
|
|
36
|
+
return obj.optional ? '?' : '';
|
|
37
|
+
}
|
|
38
|
+
function translateType(type) {
|
|
39
|
+
// avoid: Property 'type' does not exist on type 'never'
|
|
40
|
+
const returnType = type.type;
|
|
41
|
+
switch (type.type) {
|
|
42
|
+
case 'StringTypeAnnotation':
|
|
43
|
+
return 'string';
|
|
44
|
+
case 'NumberTypeAnnotation':
|
|
45
|
+
case 'FloatTypeAnnotation':
|
|
46
|
+
case 'DoubleTypeAnnotation':
|
|
47
|
+
case 'Int32TypeAnnotation':
|
|
48
|
+
return 'number';
|
|
49
|
+
case 'BooleanTypeAnnotation':
|
|
50
|
+
return 'boolean';
|
|
51
|
+
case 'ArrayTypeAnnotation':
|
|
52
|
+
if (type.elementType) {
|
|
53
|
+
return `${translateType(type.elementType)}[]`;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
return `Array`;
|
|
57
|
+
}
|
|
58
|
+
case 'GenericObjectTypeAnnotation':
|
|
59
|
+
return 'object';
|
|
60
|
+
case 'ObjectTypeAnnotation':
|
|
61
|
+
return `{${type.properties
|
|
62
|
+
.map((prop) => {
|
|
63
|
+
return `${prop.name}${optionalSign(prop)}: ${translateType(prop.typeAnnotation)}`;
|
|
64
|
+
})
|
|
65
|
+
.join(', ')}}`;
|
|
66
|
+
case 'ReservedTypeAnnotation': {
|
|
67
|
+
// avoid: Property 'name' does not exist on type 'never'
|
|
68
|
+
const name = type.name;
|
|
69
|
+
// (#6597)
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
71
|
+
if (name !== 'RootTag')
|
|
72
|
+
throw new Error(`Unknown reserved function: ${name} in translateReturnType`);
|
|
73
|
+
return 'number';
|
|
74
|
+
}
|
|
75
|
+
case 'TypeAliasTypeAnnotation':
|
|
76
|
+
return type.name;
|
|
77
|
+
case 'NullableTypeAnnotation':
|
|
78
|
+
return `(${translateType(type.typeAnnotation)} | null | undefined)`;
|
|
79
|
+
case 'VoidTypeAnnotation':
|
|
80
|
+
return `void`;
|
|
81
|
+
case 'PromiseTypeAnnotation':
|
|
82
|
+
return `Promise`;
|
|
83
|
+
case `FunctionTypeAnnotation`:
|
|
84
|
+
return `((${type.params
|
|
85
|
+
.map((param) => {
|
|
86
|
+
return `${param.name}${optionalSign(param)}: ${translateType(param.typeAnnotation)}`;
|
|
87
|
+
})
|
|
88
|
+
.join(', ')}) => ${translateType(type.returnTypeAnnotation)})`;
|
|
89
|
+
default:
|
|
90
|
+
throw new Error(`Unhandled type in translateReturnType: ${returnType}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function translateAlias(name, type) {
|
|
94
|
+
return `
|
|
95
|
+
export interface ${name} {
|
|
96
|
+
${type.properties
|
|
97
|
+
.map((prop) => {
|
|
98
|
+
return ` ${prop.name}${optionalSign(prop)}: ${translateType(prop.typeAnnotation)};`;
|
|
99
|
+
})
|
|
100
|
+
.join('\n')}
|
|
101
|
+
}
|
|
102
|
+
`;
|
|
103
|
+
}
|
|
104
|
+
function tryGetConstantType(nativeModule) {
|
|
105
|
+
const candidates = nativeModule.spec.properties.filter((prop) => prop.name === 'getConstants');
|
|
106
|
+
if (candidates.length === 0) {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
const getConstant = candidates[0];
|
|
110
|
+
const funcType = getConstant.typeAnnotation.type === 'NullableTypeAnnotation'
|
|
111
|
+
? getConstant.typeAnnotation.typeAnnotation
|
|
112
|
+
: getConstant.typeAnnotation;
|
|
113
|
+
if (funcType.params.length > 0 ||
|
|
114
|
+
funcType.returnTypeAnnotation.type !== 'ObjectTypeAnnotation') {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
const constantType = funcType.returnTypeAnnotation;
|
|
118
|
+
if (constantType.properties.length === 0) {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
return constantType;
|
|
122
|
+
}
|
|
123
|
+
function translateMethod(func) {
|
|
124
|
+
const funcType = func.typeAnnotation.type === 'NullableTypeAnnotation'
|
|
125
|
+
? func.typeAnnotation.typeAnnotation
|
|
126
|
+
: func.typeAnnotation;
|
|
127
|
+
return `
|
|
128
|
+
${func.name}(${funcType.params
|
|
129
|
+
.map((param) => {
|
|
130
|
+
return `${param.name}${optionalSign(param)}: ${translateType(param.typeAnnotation)}`;
|
|
131
|
+
})
|
|
132
|
+
.join(', ')})${optionalSign(func)}: ${translateType(funcType.returnTypeAnnotation)}${funcType.returnTypeAnnotation.type === 'ObjectTypeAnnotation' ? '' : ';'}`;
|
|
133
|
+
}
|
|
134
|
+
function generateTypeScript(_libraryName, schema, _moduleSpecName) {
|
|
135
|
+
const files = new Map();
|
|
136
|
+
for (const moduleName of Object.keys(schema.modules)) {
|
|
137
|
+
const nativeModule = schema.modules[moduleName];
|
|
138
|
+
// from 0.65 facebook's react-native-codegen
|
|
139
|
+
// the module name has the Native prefix comparing to 0.63
|
|
140
|
+
// when reading files we provided
|
|
141
|
+
const nativePrefix = 'Native';
|
|
142
|
+
const preferredModuleName = moduleName.startsWith(nativePrefix)
|
|
143
|
+
? moduleName.substr(nativePrefix.length)
|
|
144
|
+
: moduleName;
|
|
145
|
+
if (nativeModule.type === 'NativeModule') {
|
|
146
|
+
console.log(`Generating ${preferredModuleName}Spec.g.ts`);
|
|
147
|
+
const aliasCode = Object.keys(nativeModule.aliases)
|
|
148
|
+
.map((name) => translateAlias(name, nativeModule.aliases[name]))
|
|
149
|
+
.join('');
|
|
150
|
+
const constantType = tryGetConstantType(nativeModule);
|
|
151
|
+
const constantCode = constantType === undefined
|
|
152
|
+
? ''
|
|
153
|
+
: ` getConstants(): ${translateType(constantType)}`;
|
|
154
|
+
const methods = nativeModule.spec.properties.filter((prop) => prop.name !== 'getConstants');
|
|
155
|
+
const membersCode = methods.map(translateMethod).join('');
|
|
156
|
+
files.set(`${preferredModuleName}Spec.g.ts`, moduleTemplate
|
|
157
|
+
.replace(/::_MODULE_ALIASED_STRUCTS_::/g, aliasCode)
|
|
158
|
+
.replace(/::_MODULE_MEMBERS_::/g, constantCode + membersCode)
|
|
159
|
+
.replace(/::_MODULE_NAME_::/g, preferredModuleName)
|
|
160
|
+
.replace(/::_MODULE_GETTER_::/g, getOptionalTurboModule(nativeModule) ? 'get' : 'getEnforcing'));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return files;
|
|
164
|
+
}
|
|
165
|
+
exports.generateTypeScript = generateTypeScript;
|
|
166
|
+
//# sourceMappingURL=GenerateTypeScript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GenerateTypeScript.js","sourceRoot":"","sources":["../../src/generators/GenerateTypeScript.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright (c) Microsoft Corporation.\n * Licensed under the MIT License.\n * @format\n */\n\n'use strict';\n\nimport {\n NamedShape,\n NativeModuleBaseTypeAnnotation,\n NativeModuleFunctionTypeAnnotation,\n NativeModuleObjectTypeAnnotation,\n NativeModuleParamTypeAnnotation,\n NativeModuleReturnTypeAnnotation,\n NativeModuleSchema,\n Nullable,\n SchemaType,\n} from 'react-native-tscodegen';\n\ninterface CodegenNativeModuleSchema extends NativeModuleSchema {\n optionalTurboModule?: boolean;\n}\n\nexport function setOptionalTurboModule(\n schema: NativeModuleSchema,\n optional: boolean,\n): void {\n const cs = <CodegenNativeModuleSchema>schema;\n cs.optionalTurboModule = optional;\n}\n\nexport function getOptionalTurboModule(schema: NativeModuleSchema): boolean {\n return (<CodegenNativeModuleSchema>schema).optionalTurboModule ?? false;\n}\n\ntype ObjectProp = NamedShape<Nullable<NativeModuleBaseTypeAnnotation>>;\ntype FunctionParam = NamedShape<Nullable<NativeModuleParamTypeAnnotation>>;\ntype FunctionDecl = NamedShape<Nullable<NativeModuleFunctionTypeAnnotation>>;\ntype FilesOutput = Map<string, string>;\n\nconst moduleTemplate = `\n/*\n * This file is auto-generated from a NativeModule spec file in js.\n *\n * This is a TypeScript turbo module definition file.\n */\n\nimport {TurboModule, TurboModuleRegistry} from 'react-native';\n'use strict';\n::_MODULE_ALIASED_STRUCTS_::\nexport interface Spec extends TurboModule {\n::_MODULE_MEMBERS_::\n}\n\nexport default TurboModuleRegistry.::_MODULE_GETTER_::<Spec>('::_MODULE_NAME_::');\n`;\n\nfunction optionalSign<T>(obj: NamedShape<T>): string {\n return obj.optional ? '?' : '';\n}\n\nfunction translateType(\n type: Nullable<\n | NativeModuleBaseTypeAnnotation\n | NativeModuleParamTypeAnnotation\n | NativeModuleReturnTypeAnnotation\n >,\n): string {\n // avoid: Property 'type' does not exist on type 'never'\n const returnType = type.type;\n switch (type.type) {\n case 'StringTypeAnnotation':\n return 'string';\n case 'NumberTypeAnnotation':\n case 'FloatTypeAnnotation':\n case 'DoubleTypeAnnotation':\n case 'Int32TypeAnnotation':\n return 'number';\n case 'BooleanTypeAnnotation':\n return 'boolean';\n case 'ArrayTypeAnnotation':\n if (type.elementType) {\n return `${translateType(type.elementType)}[]`;\n } else {\n return `Array`;\n }\n case 'GenericObjectTypeAnnotation':\n return 'object';\n case 'ObjectTypeAnnotation':\n return `{${type.properties\n .map((prop: ObjectProp) => {\n return `${prop.name}${optionalSign(prop)}: ${translateType(\n prop.typeAnnotation,\n )}`;\n })\n .join(', ')}}`;\n case 'ReservedTypeAnnotation': {\n // avoid: Property 'name' does not exist on type 'never'\n const name = type.name;\n // (#6597)\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (name !== 'RootTag')\n throw new Error(\n `Unknown reserved function: ${name} in translateReturnType`,\n );\n return 'number';\n }\n case 'TypeAliasTypeAnnotation':\n return type.name;\n case 'NullableTypeAnnotation':\n return `(${translateType(type.typeAnnotation)} | null | undefined)`;\n case 'VoidTypeAnnotation':\n return `void`;\n case 'PromiseTypeAnnotation':\n return `Promise`;\n case `FunctionTypeAnnotation`:\n return `((${type.params\n .map((param: FunctionParam) => {\n return `${param.name}${optionalSign(param)}: ${translateType(\n param.typeAnnotation,\n )}`;\n })\n .join(', ')}) => ${translateType(type.returnTypeAnnotation)})`;\n default:\n throw new Error(`Unhandled type in translateReturnType: ${returnType}`);\n }\n}\n\nfunction translateAlias(\n name: string,\n type: NativeModuleObjectTypeAnnotation,\n): string {\n return `\nexport interface ${name} {\n${type.properties\n .map((prop: ObjectProp) => {\n return ` ${prop.name}${optionalSign(prop)}: ${translateType(\n prop.typeAnnotation,\n )};`;\n })\n .join('\\n')}\n}\n`;\n}\n\nfunction tryGetConstantType(\n nativeModule: NativeModuleSchema,\n): NativeModuleObjectTypeAnnotation | undefined {\n const candidates = nativeModule.spec.properties.filter(\n (prop) => prop.name === 'getConstants',\n );\n if (candidates.length === 0) {\n return undefined;\n }\n\n const getConstant = candidates[0];\n const funcType =\n getConstant.typeAnnotation.type === 'NullableTypeAnnotation'\n ? getConstant.typeAnnotation.typeAnnotation\n : getConstant.typeAnnotation;\n if (\n funcType.params.length > 0 ||\n funcType.returnTypeAnnotation.type !== 'ObjectTypeAnnotation'\n ) {\n return undefined;\n }\n\n const constantType = funcType.returnTypeAnnotation;\n if (constantType.properties.length === 0) {\n return undefined;\n }\n\n return constantType;\n}\n\nfunction translateMethod(func: FunctionDecl): string {\n const funcType =\n func.typeAnnotation.type === 'NullableTypeAnnotation'\n ? func.typeAnnotation.typeAnnotation\n : func.typeAnnotation;\n\n return `\n ${func.name}(${funcType.params\n .map((param: FunctionParam) => {\n return `${param.name}${optionalSign(param)}: ${translateType(\n param.typeAnnotation,\n )}`;\n })\n .join(', ')})${optionalSign(func)}: ${translateType(\n funcType.returnTypeAnnotation,\n )}${\n funcType.returnTypeAnnotation.type === 'ObjectTypeAnnotation' ? '' : ';'\n }`;\n}\n\nexport function generateTypeScript(\n _libraryName: string,\n schema: SchemaType,\n _moduleSpecName: string,\n): FilesOutput {\n const files = new Map<string, string>();\n\n for (const moduleName of Object.keys(schema.modules)) {\n const nativeModule = schema.modules[moduleName];\n // from 0.65 facebook's react-native-codegen\n // the module name has the Native prefix comparing to 0.63\n // when reading files we provided\n const nativePrefix = 'Native';\n const preferredModuleName = moduleName.startsWith(nativePrefix)\n ? moduleName.substr(nativePrefix.length)\n : moduleName;\n\n if (nativeModule.type === 'NativeModule') {\n console.log(`Generating ${preferredModuleName}Spec.g.ts`);\n\n const aliasCode = Object.keys(nativeModule.aliases)\n .map((name) => translateAlias(name, nativeModule.aliases[name]))\n .join('');\n\n const constantType = tryGetConstantType(nativeModule);\n const constantCode =\n constantType === undefined\n ? ''\n : ` getConstants(): ${translateType(constantType)}`;\n\n const methods = nativeModule.spec.properties.filter(\n (prop) => prop.name !== 'getConstants',\n );\n const membersCode = methods.map(translateMethod).join('');\n\n files.set(\n `${preferredModuleName}Spec.g.ts`,\n moduleTemplate\n .replace(/::_MODULE_ALIASED_STRUCTS_::/g, aliasCode)\n .replace(/::_MODULE_MEMBERS_::/g, constantCode + membersCode)\n .replace(/::_MODULE_NAME_::/g, preferredModuleName)\n .replace(\n /::_MODULE_GETTER_::/g,\n getOptionalTurboModule(nativeModule) ? 'get' : 'getEnforcing',\n ),\n );\n }\n }\n\n return files;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-windows/codegen",
|
|
3
|
-
"version": "0.0.0-canary.
|
|
3
|
+
"version": "0.0.0-canary.28",
|
|
4
4
|
"description": "Generators for react-native-codegen targeting react-native-windows",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": "https://github.com/microsoft/react-native-windows",
|
package/src/Cli.ts
CHANGED
|
@@ -10,6 +10,10 @@ import path from 'path';
|
|
|
10
10
|
import fs from '@react-native-windows/fs';
|
|
11
11
|
import globby from 'globby';
|
|
12
12
|
import {createNM2Generator} from './generators/GenerateNM2';
|
|
13
|
+
import {
|
|
14
|
+
generateTypeScript,
|
|
15
|
+
setOptionalTurboModule,
|
|
16
|
+
} from './generators/GenerateTypeScript';
|
|
13
17
|
// @ts-ignore
|
|
14
18
|
import {parseFile} from 'react-native-tscodegen/lib/rncodegen/src/parsers/flow';
|
|
15
19
|
// @ts-ignore
|
|
@@ -24,6 +28,16 @@ const argv = yargs.options({
|
|
|
24
28
|
type: 'array',
|
|
25
29
|
describe: 'glob patterns for files which contains specs',
|
|
26
30
|
},
|
|
31
|
+
ts: {
|
|
32
|
+
type: 'boolean',
|
|
33
|
+
describe: 'generate turbo module definition files in TypeScript',
|
|
34
|
+
default: false,
|
|
35
|
+
},
|
|
36
|
+
outdir: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
describe: 'output directory',
|
|
39
|
+
default: 'codegen',
|
|
40
|
+
},
|
|
27
41
|
test: {
|
|
28
42
|
type: 'boolean',
|
|
29
43
|
describe: 'Verify that the generated output is unchanged',
|
|
@@ -162,7 +176,24 @@ function writeMapToFiles(map: Map<string, string>, outputDir: string) {
|
|
|
162
176
|
|
|
163
177
|
function parseFlowFile(filename: string): SchemaType {
|
|
164
178
|
try {
|
|
165
|
-
|
|
179
|
+
const schema = parseFile(filename);
|
|
180
|
+
// there will be at most one turbo module per file
|
|
181
|
+
const moduleName = Object.keys(schema.modules)[0];
|
|
182
|
+
if (moduleName) {
|
|
183
|
+
const spec = schema.modules[moduleName];
|
|
184
|
+
if (spec.type === 'NativeModule') {
|
|
185
|
+
const contents = fs.readFileSync(filename, 'utf8');
|
|
186
|
+
if (contents) {
|
|
187
|
+
// This is a temporary implementation until such information is added to the schema in facebook/react-native
|
|
188
|
+
if (contents.includes('TurboModuleRegistry.get<')) {
|
|
189
|
+
setOptionalTurboModule(spec, true);
|
|
190
|
+
} else if (contents.includes('TurboModuleRegistry.getEnforcing<')) {
|
|
191
|
+
setOptionalTurboModule(spec, false);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return schema;
|
|
166
197
|
} catch (e) {
|
|
167
198
|
if (e instanceof Error) {
|
|
168
199
|
e.message = `(${filename}): ${e.message}`;
|
|
@@ -209,6 +240,7 @@ function generate(
|
|
|
209
240
|
);
|
|
210
241
|
|
|
211
242
|
const generateNM2 = createNM2Generator({namespace: argv.namespace});
|
|
243
|
+
|
|
212
244
|
const generatorPropsH =
|
|
213
245
|
require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsH').generate;
|
|
214
246
|
const generatorPropsCPP =
|
|
@@ -221,6 +253,8 @@ function generate(
|
|
|
221
253
|
require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateComponentDescriptorH').generate;
|
|
222
254
|
const generatorEventEmitterH =
|
|
223
255
|
require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterH').generate;
|
|
256
|
+
const generatorEventEmitterCPP =
|
|
257
|
+
require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterCpp').generate;
|
|
224
258
|
|
|
225
259
|
normalizeFileMap(
|
|
226
260
|
generateNM2(libraryName, schema, moduleSpecName),
|
|
@@ -228,6 +262,14 @@ function generate(
|
|
|
228
262
|
generatedFiles,
|
|
229
263
|
);
|
|
230
264
|
|
|
265
|
+
if (argv.ts) {
|
|
266
|
+
normalizeFileMap(
|
|
267
|
+
generateTypeScript(libraryName, schema, moduleSpecName),
|
|
268
|
+
outputDirectory,
|
|
269
|
+
generatedFiles,
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
|
|
231
273
|
if (
|
|
232
274
|
Object.keys(schema.modules).some(
|
|
233
275
|
(moduleName) => schema.modules[moduleName].type === 'Component',
|
|
@@ -240,6 +282,7 @@ function generate(
|
|
|
240
282
|
generatorShadowNodeCPP,
|
|
241
283
|
generatorComponentDescriptorH,
|
|
242
284
|
generatorEventEmitterH,
|
|
285
|
+
generatorEventEmitterCPP,
|
|
243
286
|
];
|
|
244
287
|
|
|
245
288
|
componentGenerators.forEach((generator) => {
|
|
@@ -273,7 +316,7 @@ if (argv.file) {
|
|
|
273
316
|
|
|
274
317
|
const libraryName = argv.libraryName;
|
|
275
318
|
const moduleSpecName = 'moduleSpecName';
|
|
276
|
-
const outputDirectory =
|
|
319
|
+
const outputDirectory = argv.outdir;
|
|
277
320
|
generate(
|
|
278
321
|
{libraryName, schema, outputDirectory, moduleSpecName},
|
|
279
322
|
{generators: [], test: false},
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
* @format
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
NamedShape,
|
|
11
|
+
NativeModuleBaseTypeAnnotation,
|
|
12
|
+
NativeModuleFunctionTypeAnnotation,
|
|
13
|
+
NativeModuleObjectTypeAnnotation,
|
|
14
|
+
NativeModuleParamTypeAnnotation,
|
|
15
|
+
NativeModuleReturnTypeAnnotation,
|
|
16
|
+
NativeModuleSchema,
|
|
17
|
+
Nullable,
|
|
18
|
+
SchemaType,
|
|
19
|
+
} from 'react-native-tscodegen';
|
|
20
|
+
|
|
21
|
+
interface CodegenNativeModuleSchema extends NativeModuleSchema {
|
|
22
|
+
optionalTurboModule?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function setOptionalTurboModule(
|
|
26
|
+
schema: NativeModuleSchema,
|
|
27
|
+
optional: boolean,
|
|
28
|
+
): void {
|
|
29
|
+
const cs = <CodegenNativeModuleSchema>schema;
|
|
30
|
+
cs.optionalTurboModule = optional;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getOptionalTurboModule(schema: NativeModuleSchema): boolean {
|
|
34
|
+
return (<CodegenNativeModuleSchema>schema).optionalTurboModule ?? false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type ObjectProp = NamedShape<Nullable<NativeModuleBaseTypeAnnotation>>;
|
|
38
|
+
type FunctionParam = NamedShape<Nullable<NativeModuleParamTypeAnnotation>>;
|
|
39
|
+
type FunctionDecl = NamedShape<Nullable<NativeModuleFunctionTypeAnnotation>>;
|
|
40
|
+
type FilesOutput = Map<string, string>;
|
|
41
|
+
|
|
42
|
+
const moduleTemplate = `
|
|
43
|
+
/*
|
|
44
|
+
* This file is auto-generated from a NativeModule spec file in js.
|
|
45
|
+
*
|
|
46
|
+
* This is a TypeScript turbo module definition file.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
import {TurboModule, TurboModuleRegistry} from 'react-native';
|
|
50
|
+
'use strict';
|
|
51
|
+
::_MODULE_ALIASED_STRUCTS_::
|
|
52
|
+
export interface Spec extends TurboModule {
|
|
53
|
+
::_MODULE_MEMBERS_::
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default TurboModuleRegistry.::_MODULE_GETTER_::<Spec>('::_MODULE_NAME_::');
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
function optionalSign<T>(obj: NamedShape<T>): string {
|
|
60
|
+
return obj.optional ? '?' : '';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function translateType(
|
|
64
|
+
type: Nullable<
|
|
65
|
+
| NativeModuleBaseTypeAnnotation
|
|
66
|
+
| NativeModuleParamTypeAnnotation
|
|
67
|
+
| NativeModuleReturnTypeAnnotation
|
|
68
|
+
>,
|
|
69
|
+
): string {
|
|
70
|
+
// avoid: Property 'type' does not exist on type 'never'
|
|
71
|
+
const returnType = type.type;
|
|
72
|
+
switch (type.type) {
|
|
73
|
+
case 'StringTypeAnnotation':
|
|
74
|
+
return 'string';
|
|
75
|
+
case 'NumberTypeAnnotation':
|
|
76
|
+
case 'FloatTypeAnnotation':
|
|
77
|
+
case 'DoubleTypeAnnotation':
|
|
78
|
+
case 'Int32TypeAnnotation':
|
|
79
|
+
return 'number';
|
|
80
|
+
case 'BooleanTypeAnnotation':
|
|
81
|
+
return 'boolean';
|
|
82
|
+
case 'ArrayTypeAnnotation':
|
|
83
|
+
if (type.elementType) {
|
|
84
|
+
return `${translateType(type.elementType)}[]`;
|
|
85
|
+
} else {
|
|
86
|
+
return `Array`;
|
|
87
|
+
}
|
|
88
|
+
case 'GenericObjectTypeAnnotation':
|
|
89
|
+
return 'object';
|
|
90
|
+
case 'ObjectTypeAnnotation':
|
|
91
|
+
return `{${type.properties
|
|
92
|
+
.map((prop: ObjectProp) => {
|
|
93
|
+
return `${prop.name}${optionalSign(prop)}: ${translateType(
|
|
94
|
+
prop.typeAnnotation,
|
|
95
|
+
)}`;
|
|
96
|
+
})
|
|
97
|
+
.join(', ')}}`;
|
|
98
|
+
case 'ReservedTypeAnnotation': {
|
|
99
|
+
// avoid: Property 'name' does not exist on type 'never'
|
|
100
|
+
const name = type.name;
|
|
101
|
+
// (#6597)
|
|
102
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
103
|
+
if (name !== 'RootTag')
|
|
104
|
+
throw new Error(
|
|
105
|
+
`Unknown reserved function: ${name} in translateReturnType`,
|
|
106
|
+
);
|
|
107
|
+
return 'number';
|
|
108
|
+
}
|
|
109
|
+
case 'TypeAliasTypeAnnotation':
|
|
110
|
+
return type.name;
|
|
111
|
+
case 'NullableTypeAnnotation':
|
|
112
|
+
return `(${translateType(type.typeAnnotation)} | null | undefined)`;
|
|
113
|
+
case 'VoidTypeAnnotation':
|
|
114
|
+
return `void`;
|
|
115
|
+
case 'PromiseTypeAnnotation':
|
|
116
|
+
return `Promise`;
|
|
117
|
+
case `FunctionTypeAnnotation`:
|
|
118
|
+
return `((${type.params
|
|
119
|
+
.map((param: FunctionParam) => {
|
|
120
|
+
return `${param.name}${optionalSign(param)}: ${translateType(
|
|
121
|
+
param.typeAnnotation,
|
|
122
|
+
)}`;
|
|
123
|
+
})
|
|
124
|
+
.join(', ')}) => ${translateType(type.returnTypeAnnotation)})`;
|
|
125
|
+
default:
|
|
126
|
+
throw new Error(`Unhandled type in translateReturnType: ${returnType}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function translateAlias(
|
|
131
|
+
name: string,
|
|
132
|
+
type: NativeModuleObjectTypeAnnotation,
|
|
133
|
+
): string {
|
|
134
|
+
return `
|
|
135
|
+
export interface ${name} {
|
|
136
|
+
${type.properties
|
|
137
|
+
.map((prop: ObjectProp) => {
|
|
138
|
+
return ` ${prop.name}${optionalSign(prop)}: ${translateType(
|
|
139
|
+
prop.typeAnnotation,
|
|
140
|
+
)};`;
|
|
141
|
+
})
|
|
142
|
+
.join('\n')}
|
|
143
|
+
}
|
|
144
|
+
`;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function tryGetConstantType(
|
|
148
|
+
nativeModule: NativeModuleSchema,
|
|
149
|
+
): NativeModuleObjectTypeAnnotation | undefined {
|
|
150
|
+
const candidates = nativeModule.spec.properties.filter(
|
|
151
|
+
(prop) => prop.name === 'getConstants',
|
|
152
|
+
);
|
|
153
|
+
if (candidates.length === 0) {
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const getConstant = candidates[0];
|
|
158
|
+
const funcType =
|
|
159
|
+
getConstant.typeAnnotation.type === 'NullableTypeAnnotation'
|
|
160
|
+
? getConstant.typeAnnotation.typeAnnotation
|
|
161
|
+
: getConstant.typeAnnotation;
|
|
162
|
+
if (
|
|
163
|
+
funcType.params.length > 0 ||
|
|
164
|
+
funcType.returnTypeAnnotation.type !== 'ObjectTypeAnnotation'
|
|
165
|
+
) {
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const constantType = funcType.returnTypeAnnotation;
|
|
170
|
+
if (constantType.properties.length === 0) {
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return constantType;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function translateMethod(func: FunctionDecl): string {
|
|
178
|
+
const funcType =
|
|
179
|
+
func.typeAnnotation.type === 'NullableTypeAnnotation'
|
|
180
|
+
? func.typeAnnotation.typeAnnotation
|
|
181
|
+
: func.typeAnnotation;
|
|
182
|
+
|
|
183
|
+
return `
|
|
184
|
+
${func.name}(${funcType.params
|
|
185
|
+
.map((param: FunctionParam) => {
|
|
186
|
+
return `${param.name}${optionalSign(param)}: ${translateType(
|
|
187
|
+
param.typeAnnotation,
|
|
188
|
+
)}`;
|
|
189
|
+
})
|
|
190
|
+
.join(', ')})${optionalSign(func)}: ${translateType(
|
|
191
|
+
funcType.returnTypeAnnotation,
|
|
192
|
+
)}${
|
|
193
|
+
funcType.returnTypeAnnotation.type === 'ObjectTypeAnnotation' ? '' : ';'
|
|
194
|
+
}`;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function generateTypeScript(
|
|
198
|
+
_libraryName: string,
|
|
199
|
+
schema: SchemaType,
|
|
200
|
+
_moduleSpecName: string,
|
|
201
|
+
): FilesOutput {
|
|
202
|
+
const files = new Map<string, string>();
|
|
203
|
+
|
|
204
|
+
for (const moduleName of Object.keys(schema.modules)) {
|
|
205
|
+
const nativeModule = schema.modules[moduleName];
|
|
206
|
+
// from 0.65 facebook's react-native-codegen
|
|
207
|
+
// the module name has the Native prefix comparing to 0.63
|
|
208
|
+
// when reading files we provided
|
|
209
|
+
const nativePrefix = 'Native';
|
|
210
|
+
const preferredModuleName = moduleName.startsWith(nativePrefix)
|
|
211
|
+
? moduleName.substr(nativePrefix.length)
|
|
212
|
+
: moduleName;
|
|
213
|
+
|
|
214
|
+
if (nativeModule.type === 'NativeModule') {
|
|
215
|
+
console.log(`Generating ${preferredModuleName}Spec.g.ts`);
|
|
216
|
+
|
|
217
|
+
const aliasCode = Object.keys(nativeModule.aliases)
|
|
218
|
+
.map((name) => translateAlias(name, nativeModule.aliases[name]))
|
|
219
|
+
.join('');
|
|
220
|
+
|
|
221
|
+
const constantType = tryGetConstantType(nativeModule);
|
|
222
|
+
const constantCode =
|
|
223
|
+
constantType === undefined
|
|
224
|
+
? ''
|
|
225
|
+
: ` getConstants(): ${translateType(constantType)}`;
|
|
226
|
+
|
|
227
|
+
const methods = nativeModule.spec.properties.filter(
|
|
228
|
+
(prop) => prop.name !== 'getConstants',
|
|
229
|
+
);
|
|
230
|
+
const membersCode = methods.map(translateMethod).join('');
|
|
231
|
+
|
|
232
|
+
files.set(
|
|
233
|
+
`${preferredModuleName}Spec.g.ts`,
|
|
234
|
+
moduleTemplate
|
|
235
|
+
.replace(/::_MODULE_ALIASED_STRUCTS_::/g, aliasCode)
|
|
236
|
+
.replace(/::_MODULE_MEMBERS_::/g, constantCode + membersCode)
|
|
237
|
+
.replace(/::_MODULE_NAME_::/g, preferredModuleName)
|
|
238
|
+
.replace(
|
|
239
|
+
/::_MODULE_GETTER_::/g,
|
|
240
|
+
getOptionalTurboModule(nativeModule) ? 'get' : 'getEnforcing',
|
|
241
|
+
),
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return files;
|
|
247
|
+
}
|