@react-native-windows/codegen 0.0.0-canary.13 → 0.0.0-canary.130

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.
Files changed (61) hide show
  1. package/CHANGELOG.md +1125 -16
  2. package/README.md +1 -1
  3. package/bin.js +0 -0
  4. package/lib-commonjs/Cli.d.ts +7 -0
  5. package/lib-commonjs/Cli.js +103 -0
  6. package/lib-commonjs/Cli.js.map +1 -0
  7. package/lib-commonjs/generators/AliasGen.d.ts +12 -0
  8. package/lib-commonjs/generators/AliasGen.js +115 -0
  9. package/lib-commonjs/generators/AliasGen.js.map +1 -0
  10. package/lib-commonjs/generators/AliasManaging.d.ts +15 -0
  11. package/lib-commonjs/generators/AliasManaging.js +49 -0
  12. package/lib-commonjs/generators/AliasManaging.js.map +1 -0
  13. package/lib-commonjs/generators/GenerateComponentWindows.d.ts +13 -0
  14. package/lib-commonjs/generators/GenerateComponentWindows.js +469 -0
  15. package/lib-commonjs/generators/GenerateComponentWindows.js.map +1 -0
  16. package/lib-commonjs/generators/GenerateNM2.d.ts +15 -0
  17. package/lib-commonjs/generators/GenerateNM2.js +145 -0
  18. package/lib-commonjs/generators/GenerateNM2.js.map +1 -0
  19. package/lib-commonjs/generators/GenerateTypeScript.d.ts +11 -0
  20. package/lib-commonjs/generators/GenerateTypeScript.js +166 -0
  21. package/lib-commonjs/generators/GenerateTypeScript.js.map +1 -0
  22. package/lib-commonjs/generators/ObjectTypes.d.ts +13 -0
  23. package/lib-commonjs/generators/ObjectTypes.js +81 -0
  24. package/lib-commonjs/generators/ObjectTypes.js.map +1 -0
  25. package/lib-commonjs/generators/ParamTypes.d.ts +13 -0
  26. package/lib-commonjs/generators/ParamTypes.js +183 -0
  27. package/lib-commonjs/generators/ParamTypes.js.map +1 -0
  28. package/lib-commonjs/generators/PropObjectTypes.d.ts +18 -0
  29. package/lib-commonjs/generators/PropObjectTypes.js +208 -0
  30. package/lib-commonjs/generators/PropObjectTypes.js.map +1 -0
  31. package/lib-commonjs/generators/ReturnTypes.d.ts +10 -0
  32. package/lib-commonjs/generators/ReturnTypes.js +29 -0
  33. package/lib-commonjs/generators/ReturnTypes.js.map +1 -0
  34. package/lib-commonjs/generators/ValidateConstants.d.ts +8 -0
  35. package/lib-commonjs/generators/ValidateConstants.js +38 -0
  36. package/lib-commonjs/generators/ValidateConstants.js.map +1 -0
  37. package/lib-commonjs/generators/ValidateMethods.d.ts +14 -0
  38. package/lib-commonjs/generators/ValidateMethods.js +112 -0
  39. package/lib-commonjs/generators/ValidateMethods.js.map +1 -0
  40. package/lib-commonjs/index.d.ts +39 -0
  41. package/lib-commonjs/index.js +227 -0
  42. package/lib-commonjs/index.js.map +1 -0
  43. package/package.json +39 -21
  44. package/src/Cli.ts +69 -232
  45. package/src/generators/AliasGen.ts +195 -0
  46. package/src/generators/AliasManaging.ts +75 -0
  47. package/src/generators/GenerateComponentWindows.ts +616 -0
  48. package/src/generators/GenerateNM2.ts +128 -131
  49. package/src/generators/GenerateTypeScript.ts +250 -0
  50. package/src/generators/ObjectTypes.ts +95 -37
  51. package/src/generators/ParamTypes.ts +309 -53
  52. package/src/generators/PropObjectTypes.ts +223 -0
  53. package/src/generators/ReturnTypes.ts +38 -40
  54. package/src/generators/ValidateConstants.ts +50 -0
  55. package/src/generators/ValidateMethods.ts +270 -0
  56. package/src/index.ts +415 -0
  57. package/.eslintrc.js +0 -4
  58. package/.vscode/launch.json +0 -23
  59. package/CHANGELOG.json +0 -726
  60. package/jest.config.js +0 -1
  61. package/tsconfig.json +0 -5
@@ -6,23 +6,18 @@
6
6
 
7
7
  'use strict';
8
8
 
9
- import {
10
- NativeModuleFunctionTypeAnnotation,
11
- NativeModulePropertyShape,
12
- SchemaType,
13
- } from 'react-native-tscodegen';
14
- import {
15
- getAliasCppName,
16
- setPreferredModuleName,
17
- translateObjectBody,
18
- } from './ObjectTypes';
19
- import {translateArgs, translateSpecArgs} from './ParamTypes';
20
- import {translateImplReturnType, translateSpecReturnType} from './ReturnTypes';
9
+ import type {SchemaType} from '@react-native/codegen/lib/CodegenSchema';
10
+ import {AliasMap, setPreferredModuleName} from './AliasManaging';
11
+ import {createAliasMap, generateAliases} from './AliasGen';
12
+ import {generateValidateConstants} from './ValidateConstants';
13
+ import {generateValidateMethods} from './ValidateMethods';
14
+ import type {CppStringTypes} from './ObjectTypes';
15
+
16
+ export type {CppStringTypes} from './ObjectTypes';
21
17
 
22
18
  type FilesOutput = Map<string, string>;
23
19
 
24
- const moduleTemplate = `
25
- /*
20
+ const headerTemplate = `/*
26
21
  * This file is auto-generated from a NativeModule spec file in js.
27
22
  *
28
23
  * This is a C++ Spec class that should be used with MakeTurboModuleProvider to register native modules
@@ -30,117 +25,71 @@ const moduleTemplate = `
30
25
  * by the TurboModule JS spec.
31
26
  */
32
27
  #pragma once
28
+ // clang-format off`;
33
29
 
34
- #include "NativeModules.h"
35
- #include <tuple>
36
-
37
- namespace ::_NAMESPACE_:: {
38
- ::_MODULE_ALIASED_STRUCTS_::
30
+ const specTemplate = `::_MODULE_CUSTOM_TYPES_REFLECTION_::
39
31
  struct ::_MODULE_NAME_::Spec : winrt::Microsoft::ReactNative::TurboModuleSpec {
40
- static constexpr auto methods = std::tuple{
41
- ::_MODULE_PROPERTIES_TUPLE_::
42
- };
32
+ ::_MODULE_MEMBERS_TUPLES_::
43
33
 
44
34
  template <class TModule>
45
35
  static constexpr void ValidateModule() noexcept {
46
- constexpr auto methodCheckResults = CheckMethods<TModule, ::_MODULE_NAME_::Spec>();
36
+ ::_MODULE_MEMBERS_CHECKS_::
47
37
 
48
- ::_MODULE_PROPERTIES_SPEC_ERRORS_::
49
- }
50
- };
38
+ ::_MODULE_MEMBERS_ERRORS_::
39
+ }`;
40
+
41
+ const typeOnlyTemplate = `
42
+ ${headerTemplate}
51
43
 
44
+ #include <string>
45
+ #include <optional>
46
+ #include <functional>
47
+ #include <vector>
48
+
49
+ namespace ::_NAMESPACE_:: {
50
+ ::_MODULE_CUSTOM_TYPES_::
52
51
  } // namespace ::_NAMESPACE_::
53
52
  `;
54
53
 
55
- function isMethodSync(funcType: NativeModuleFunctionTypeAnnotation) {
56
- return (
57
- funcType.returnTypeAnnotation.type !== 'VoidTypeAnnotation' &&
58
- funcType.returnTypeAnnotation.type !== 'PromiseTypeAnnotation'
59
- );
60
- }
54
+ const moduleOnlyTemplate = `
55
+ ${headerTemplate}
61
56
 
62
- function isMethodReturnPromise(funcType: NativeModuleFunctionTypeAnnotation) {
63
- return funcType.returnTypeAnnotation.type === 'PromiseTypeAnnotation';
64
- }
57
+ ::_TYPE_DEFINITION_INCLUDE_::
58
+ #include <NativeModules.h>
59
+ #include <tuple>
65
60
 
66
- function getPossibleMethodSignatures(
67
- prop: NativeModulePropertyShape,
68
- funcType: NativeModuleFunctionTypeAnnotation,
69
- ): string[] {
70
- const args = translateArgs(funcType.params);
71
- if (isMethodReturnPromise(funcType)) {
72
- // TODO: type of the promise could be provided in the future
73
- args.push('React::ReactPromise<React::JSValue> &&result');
74
- }
75
-
76
- // TODO: be much more exhastive on the possible method signatures that can be used..
77
- const sig = `REACT_${isMethodSync(funcType) ? 'SYNC_' : ''}METHOD(${
78
- prop.name
79
- }) ${translateImplReturnType(funcType.returnTypeAnnotation)} ${
80
- prop.name
81
- }(${args.join(', ')}) noexcept { /* implementation */ }}`;
82
-
83
- const staticsig = `REACT_${isMethodSync(funcType) ? 'SYNC_' : ''}METHOD(${
84
- prop.name
85
- }) static ${translateImplReturnType(funcType.returnTypeAnnotation)} ${
86
- prop.name
87
- }(${args.join(', ')}) noexcept { /* implementation */ }}`;
88
-
89
- return [sig, staticsig];
90
- }
61
+ namespace ::_NAMESPACE_:: {
62
+ ${specTemplate}
63
+ };
91
64
 
92
- function translatePossibleMethodSignatures(
93
- prop: NativeModulePropertyShape,
94
- funcType: NativeModuleFunctionTypeAnnotation,
95
- ): string {
96
- return getPossibleMethodSignatures(prop, funcType)
97
- .map(sig => `" ${sig}\\n"`)
98
- .join('\n ');
99
- }
65
+ } // namespace ::_NAMESPACE_::
66
+ `;
100
67
 
101
- function renderProperties(
102
- properties: ReadonlyArray<NativeModulePropertyShape>,
103
- tuple: boolean,
104
- ): string {
105
- // TODO: generate code for constants
106
- return properties
107
- .filter(prop => prop.name !== 'getConstants')
108
- .map((prop, index) => {
109
- // TODO: prop.optional === true
110
- // TODO: prop.typeAnnotation.type === 'NullableTypeAnnotation'
111
- const funcType =
112
- prop.typeAnnotation.type === 'NullableTypeAnnotation'
113
- ? prop.typeAnnotation.typeAnnotation
114
- : prop.typeAnnotation;
115
-
116
- const traversedArgs = translateSpecArgs(funcType.params);
117
-
118
- const translatedReturnParam = translateSpecReturnType(
119
- funcType.returnTypeAnnotation,
120
- );
121
-
122
- if (isMethodReturnPromise(funcType)) {
123
- // TODO: type of the promise could be provided in the future
124
- traversedArgs.push('Promise<React::JSValue>');
125
- }
68
+ const allInOneTemplate = `
69
+ ${headerTemplate}
126
70
 
127
- if (tuple) {
128
- return ` ${
129
- isMethodSync(funcType) ? 'Sync' : ''
130
- }Method<${translatedReturnParam}(${traversedArgs.join(
131
- ', ',
132
- )}) noexcept>{${index}, L"${prop.name}"},`;
133
- } else {
134
- return ` REACT_SHOW_METHOD_SPEC_ERRORS(
135
- ${index},
136
- "${prop.name}",
137
- ${translatePossibleMethodSignatures(prop, funcType)});`;
138
- }
139
- })
140
- .join('\n');
141
- }
71
+ #include <NativeModules.h>
72
+ #include <tuple>
142
73
 
143
- export function createNM2Generator({namespace}: {namespace: string}) {
74
+ namespace ::_NAMESPACE_:: {
75
+ ::_MODULE_CUSTOM_TYPES_::
76
+ ${specTemplate}
77
+ };
78
+
79
+ } // namespace ::_NAMESPACE_::
80
+ `;
81
+
82
+ export function createNM2Generator({
83
+ methodOnly,
84
+ namespace,
85
+ cppStringType,
86
+ separateDataTypes,
87
+ }: {
88
+ methodOnly: boolean;
89
+ namespace: string;
90
+ cppStringType: CppStringTypes;
91
+ separateDataTypes: boolean;
92
+ }) {
144
93
  return (
145
94
  _libraryName: string,
146
95
  schema: SchemaType,
@@ -161,33 +110,81 @@ export function createNM2Generator({namespace}: {namespace: string}) {
161
110
  if (nativeModule.type === 'NativeModule') {
162
111
  console.log(`Generating Native${preferredModuleName}Spec.g.h`);
163
112
 
164
- let traversedAliasedStructs = '';
165
- for (const aliasName of Object.keys(nativeModule.aliases)) {
166
- const aliasType = nativeModule.aliases[aliasName];
167
- traversedAliasedStructs = `${traversedAliasedStructs}
168
- REACT_STRUCT(${getAliasCppName(aliasName)})
169
- struct ${getAliasCppName(aliasName)} {
170
- ${translateObjectBody(aliasType, ' ')}
171
- };
172
- `;
113
+ // copy all explicit to a map
114
+ const aliases: AliasMap = createAliasMap(nativeModule.aliasMap);
115
+
116
+ // prepare methods
117
+ const methods = generateValidateMethods(nativeModule, aliases, {
118
+ cppStringType,
119
+ });
120
+ let tuples = `
121
+ static constexpr auto methods = std::tuple{
122
+ ${methods.traversedPropertyTuples}${
123
+ methods.traversedEventEmitterTuples ? '\n' : ''
124
+ }${methods.traversedEventEmitterTuples}
125
+ };`;
126
+ let checks = `
127
+ constexpr auto methodCheckResults = CheckMethods<TModule, ::_MODULE_NAME_::Spec>();`;
128
+ let errors =
129
+ methods.traversedProperties +
130
+ (methods.traversedEventEmitters ? '\n' : '') +
131
+ methods.traversedEventEmitters;
132
+
133
+ // prepare constants
134
+ const constants = generateValidateConstants(nativeModule, aliases);
135
+ if (constants !== undefined && !methodOnly) {
136
+ tuples = `
137
+ static constexpr auto constants = std::tuple{
138
+ ${constants[0]}
139
+ };${tuples}`;
140
+ checks = `
141
+ constexpr auto constantCheckResults = CheckConstants<TModule, ::_MODULE_NAME_::Spec>();${checks}`;
142
+ errors = `${constants[1]}
143
+
144
+ ${errors}`;
173
145
  }
174
146
 
175
- const properties = nativeModule.spec.properties;
176
- const traversedProperties = renderProperties(properties, false);
177
- const traversedPropertyTuples = renderProperties(properties, true);
147
+ // generate code for structs
148
+ const [customTypes, customReflection] = generateAliases(aliases, {
149
+ cppStringType,
150
+ });
178
151
 
179
- files.set(
180
- `Native${preferredModuleName}Spec.g.h`,
181
- moduleTemplate
182
- .replace(/::_MODULE_ALIASED_STRUCTS_::/g, traversedAliasedStructs)
183
- .replace(/::_MODULE_PROPERTIES_TUPLE_::/g, traversedPropertyTuples)
152
+ const customTypesExist = customTypes !== '';
153
+
154
+ const replaceContent = function (template: string): string {
155
+ return template
156
+ .replace(/::_MODULE_CUSTOM_TYPES_::/g, customTypes)
157
+ .replace(/::_MODULE_CUSTOM_TYPES_REFLECTION_::/g, customReflection)
158
+ .replace(/::_MODULE_MEMBERS_TUPLES_::/g, tuples.substring(1))
159
+ .replace(/::_MODULE_MEMBERS_CHECKS_::/g, checks.substring(1))
160
+ .replace(/::_MODULE_MEMBERS_ERRORS_::/g, errors)
161
+ .replace(/::_MODULE_NAME_::/g, preferredModuleName)
184
162
  .replace(
185
- /::_MODULE_PROPERTIES_SPEC_ERRORS_::/g,
186
- traversedProperties,
163
+ /::_TYPE_DEFINITION_INCLUDE_::/g,
164
+ customTypesExist
165
+ ? `// #include "Native${preferredModuleName}DataTypes.g.h" before this file to use the generated type definition`
166
+ : '',
187
167
  )
188
- .replace(/::_MODULE_NAME_::/g, preferredModuleName)
189
- .replace(/::_NAMESPACE_::/g, namespace),
190
- );
168
+ .replace(/::_NAMESPACE_::/g, namespace);
169
+ };
170
+
171
+ if (separateDataTypes) {
172
+ if (customTypesExist) {
173
+ files.set(
174
+ `Native${preferredModuleName}DataTypes.g.h`,
175
+ replaceContent(typeOnlyTemplate),
176
+ );
177
+ }
178
+ files.set(
179
+ `Native${preferredModuleName}Spec.g.h`,
180
+ replaceContent(moduleOnlyTemplate),
181
+ );
182
+ } else {
183
+ files.set(
184
+ `Native${preferredModuleName}Spec.g.h`,
185
+ replaceContent(allInOneTemplate),
186
+ );
187
+ }
191
188
  }
192
189
  }
193
190
 
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ * Licensed under the MIT License.
4
+ * @format
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ import type {
10
+ NamedShape,
11
+ NativeModuleBaseTypeAnnotation,
12
+ NativeModuleFunctionTypeAnnotation,
13
+ NativeModuleObjectTypeAnnotation,
14
+ NativeModuleParamTypeAnnotation,
15
+ NativeModuleReturnTypeAnnotation,
16
+ NativeModuleSchema,
17
+ UnsafeAnyTypeAnnotation,
18
+ Nullable,
19
+ SchemaType,
20
+ } from '@react-native/codegen/lib/CodegenSchema';
21
+
22
+ interface CodegenNativeModuleSchema extends NativeModuleSchema {
23
+ optionalTurboModule?: boolean;
24
+ }
25
+
26
+ export function setOptionalTurboModule(
27
+ schema: NativeModuleSchema,
28
+ optional: boolean,
29
+ ): void {
30
+ const cs = <CodegenNativeModuleSchema>schema;
31
+ cs.optionalTurboModule = optional;
32
+ }
33
+
34
+ export function getOptionalTurboModule(schema: NativeModuleSchema): boolean {
35
+ return (<CodegenNativeModuleSchema>schema).optionalTurboModule ?? false;
36
+ }
37
+
38
+ type ObjectProp = NamedShape<Nullable<NativeModuleBaseTypeAnnotation>>;
39
+ type FunctionParam = NamedShape<Nullable<NativeModuleParamTypeAnnotation>>;
40
+ type FunctionDecl = NamedShape<Nullable<NativeModuleFunctionTypeAnnotation>>;
41
+ type FilesOutput = Map<string, string>;
42
+
43
+ const moduleTemplate = `
44
+ /*
45
+ * This file is auto-generated from a NativeModule spec file in js.
46
+ *
47
+ * This is a TypeScript turbo module definition file.
48
+ */
49
+
50
+ import {TurboModule, TurboModuleRegistry} from 'react-native';
51
+ 'use strict';
52
+ ::_MODULE_ALIASED_STRUCTS_::
53
+ export interface Spec extends TurboModule {
54
+ ::_MODULE_MEMBERS_::
55
+ }
56
+
57
+ export default TurboModuleRegistry.::_MODULE_GETTER_::<Spec>('::_MODULE_NAME_::');
58
+ `;
59
+
60
+ function optionalSign<T>(obj: NamedShape<T>): string {
61
+ return obj.optional ? '?' : '';
62
+ }
63
+
64
+ function translateType(
65
+ type:
66
+ | Nullable<
67
+ | NativeModuleBaseTypeAnnotation
68
+ | NativeModuleParamTypeAnnotation
69
+ | NativeModuleReturnTypeAnnotation
70
+ >
71
+ | UnsafeAnyTypeAnnotation,
72
+ ): string {
73
+ // avoid: Property 'type' does not exist on type 'never'
74
+ const returnType = type.type;
75
+ switch (type.type) {
76
+ case 'StringTypeAnnotation':
77
+ return 'string';
78
+ case 'NumberTypeAnnotation':
79
+ case 'FloatTypeAnnotation':
80
+ case 'DoubleTypeAnnotation':
81
+ case 'Int32TypeAnnotation':
82
+ return 'number';
83
+ case 'BooleanTypeAnnotation':
84
+ return 'boolean';
85
+ case 'ArrayTypeAnnotation':
86
+ if (type.elementType.type !== 'AnyTypeAnnotation') {
87
+ return `${translateType(type.elementType)}[]`;
88
+ } else {
89
+ return `Array`;
90
+ }
91
+ case 'GenericObjectTypeAnnotation':
92
+ return 'object';
93
+ case 'ObjectTypeAnnotation':
94
+ return `{${type.properties
95
+ .map((prop: ObjectProp) => {
96
+ return `${prop.name}${optionalSign(prop)}: ${translateType(
97
+ prop.typeAnnotation,
98
+ )}`;
99
+ })
100
+ .join(', ')}}`;
101
+ case 'ReservedTypeAnnotation': {
102
+ // avoid: Property 'name' does not exist on type 'never'
103
+ const name = type.name;
104
+ // (#6597)
105
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
106
+ if (name !== 'RootTag')
107
+ throw new Error(
108
+ `Unknown reserved function: ${name} in translateReturnType`,
109
+ );
110
+ return 'number';
111
+ }
112
+ case 'TypeAliasTypeAnnotation':
113
+ return type.name;
114
+ case 'NullableTypeAnnotation':
115
+ return `(${translateType(type.typeAnnotation)} | null | undefined)`;
116
+ case 'VoidTypeAnnotation':
117
+ return `void`;
118
+ case 'PromiseTypeAnnotation':
119
+ return `Promise`;
120
+ case `FunctionTypeAnnotation`:
121
+ return `((${type.params
122
+ .map((param: FunctionParam) => {
123
+ return `${param.name}${optionalSign(param)}: ${translateType(
124
+ param.typeAnnotation,
125
+ )}`;
126
+ })
127
+ .join(', ')}) => ${translateType(type.returnTypeAnnotation)})`;
128
+ default:
129
+ throw new Error(`Unhandled type in translateReturnType: ${returnType}`);
130
+ }
131
+ }
132
+
133
+ function translateAlias(
134
+ name: string,
135
+ type: NativeModuleObjectTypeAnnotation,
136
+ ): string {
137
+ return `
138
+ export interface ${name} {
139
+ ${type.properties
140
+ .map((prop: ObjectProp) => {
141
+ return ` ${prop.name}${optionalSign(prop)}: ${translateType(
142
+ prop.typeAnnotation,
143
+ )};`;
144
+ })
145
+ .join('\n')}
146
+ }
147
+ `;
148
+ }
149
+
150
+ function tryGetConstantType(
151
+ nativeModule: NativeModuleSchema,
152
+ ): NativeModuleObjectTypeAnnotation | undefined {
153
+ const candidates = nativeModule.spec.methods.filter(
154
+ prop => prop.name === 'getConstants',
155
+ );
156
+ if (candidates.length === 0) {
157
+ return undefined;
158
+ }
159
+
160
+ const getConstant = candidates[0];
161
+ const funcType =
162
+ getConstant.typeAnnotation.type === 'NullableTypeAnnotation'
163
+ ? getConstant.typeAnnotation.typeAnnotation
164
+ : getConstant.typeAnnotation;
165
+ if (
166
+ funcType.params.length > 0 ||
167
+ funcType.returnTypeAnnotation.type !== 'ObjectTypeAnnotation'
168
+ ) {
169
+ return undefined;
170
+ }
171
+
172
+ const constantType = funcType.returnTypeAnnotation;
173
+ if (constantType.properties.length === 0) {
174
+ return undefined;
175
+ }
176
+
177
+ return constantType;
178
+ }
179
+
180
+ function translateMethod(func: FunctionDecl): string {
181
+ const funcType =
182
+ func.typeAnnotation.type === 'NullableTypeAnnotation'
183
+ ? func.typeAnnotation.typeAnnotation
184
+ : func.typeAnnotation;
185
+
186
+ return `
187
+ ${func.name}(${funcType.params
188
+ .map((param: FunctionParam) => {
189
+ return `${param.name}${optionalSign(param)}: ${translateType(
190
+ param.typeAnnotation,
191
+ )}`;
192
+ })
193
+ .join(', ')})${optionalSign(func)}: ${translateType(
194
+ funcType.returnTypeAnnotation,
195
+ )}${
196
+ funcType.returnTypeAnnotation.type === 'ObjectTypeAnnotation' ? '' : ';'
197
+ }`;
198
+ }
199
+
200
+ export function generateTypeScript(
201
+ _libraryName: string,
202
+ schema: SchemaType,
203
+ _moduleSpecName: string,
204
+ ): FilesOutput {
205
+ const files = new Map<string, string>();
206
+
207
+ for (const moduleName of Object.keys(schema.modules)) {
208
+ const nativeModule = schema.modules[moduleName];
209
+ // from 0.65 facebook's react-native-codegen
210
+ // the module name has the Native prefix comparing to 0.63
211
+ // when reading files we provided
212
+ const nativePrefix = 'Native';
213
+ const preferredModuleName = moduleName.startsWith(nativePrefix)
214
+ ? moduleName.substr(nativePrefix.length)
215
+ : moduleName;
216
+
217
+ if (nativeModule.type === 'NativeModule') {
218
+ console.log(`Generating ${preferredModuleName}Spec.g.ts`);
219
+
220
+ const aliasCode = Object.keys(nativeModule.aliasMap)
221
+ .map(name => translateAlias(name, nativeModule.aliasMap[name]))
222
+ .join('');
223
+
224
+ const constantType = tryGetConstantType(nativeModule);
225
+ const constantCode =
226
+ constantType === undefined
227
+ ? ''
228
+ : ` getConstants(): ${translateType(constantType)}`;
229
+
230
+ const methods = nativeModule.spec.methods.filter(
231
+ prop => prop.name !== 'getConstants',
232
+ );
233
+ const membersCode = methods.map(translateMethod).join('');
234
+
235
+ files.set(
236
+ `${preferredModuleName}Spec.g.ts`,
237
+ moduleTemplate
238
+ .replace(/::_MODULE_ALIASED_STRUCTS_::/g, aliasCode)
239
+ .replace(/::_MODULE_MEMBERS_::/g, constantCode + membersCode)
240
+ .replace(/::_MODULE_NAME_::/g, preferredModuleName)
241
+ .replace(
242
+ /::_MODULE_GETTER_::/g,
243
+ getOptionalTurboModule(nativeModule) ? 'get' : 'getEnforcing',
244
+ ),
245
+ );
246
+ }
247
+ }
248
+
249
+ return files;
250
+ }