@react-native/codegen 0.72.1

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 (186) hide show
  1. package/README.md +21 -0
  2. package/lib/CodegenSchema.js +11 -0
  3. package/lib/CodegenSchema.js.flow +351 -0
  4. package/lib/SchemaValidator.js +54 -0
  5. package/lib/SchemaValidator.js.flow +67 -0
  6. package/lib/cli/combine/combine-js-to-schema-cli.js +50 -0
  7. package/lib/cli/combine/combine-js-to-schema-cli.js.flow +49 -0
  8. package/lib/cli/combine/combine-js-to-schema.js +110 -0
  9. package/lib/cli/combine/combine-js-to-schema.js.flow +48 -0
  10. package/lib/cli/combine/combine-utils.js +118 -0
  11. package/lib/cli/combine/combine-utils.js.flow +85 -0
  12. package/lib/cli/generators/generate-all.js +65 -0
  13. package/lib/cli/generators/generate-all.js.flow +66 -0
  14. package/lib/cli/parser/parser-cli.js +55 -0
  15. package/lib/cli/parser/parser-cli.js.flow +18 -0
  16. package/lib/cli/parser/parser.js +35 -0
  17. package/lib/cli/parser/parser.js.flow +37 -0
  18. package/lib/cli/parser/parser.sh +15 -0
  19. package/lib/generators/RNCodegen.js +207 -0
  20. package/lib/generators/RNCodegen.js.flow +284 -0
  21. package/lib/generators/Utils.js +31 -0
  22. package/lib/generators/Utils.js.flow +33 -0
  23. package/lib/generators/__test_fixtures__/fixtures.js +79 -0
  24. package/lib/generators/__test_fixtures__/fixtures.js.flow +82 -0
  25. package/lib/generators/components/ComponentsGeneratorUtils.js +217 -0
  26. package/lib/generators/components/ComponentsGeneratorUtils.js.flow +304 -0
  27. package/lib/generators/components/CppHelpers.js +188 -0
  28. package/lib/generators/components/CppHelpers.js.flow +228 -0
  29. package/lib/generators/components/GenerateComponentDescriptorH.js +75 -0
  30. package/lib/generators/components/GenerateComponentDescriptorH.js.flow +95 -0
  31. package/lib/generators/components/GenerateComponentHObjCpp.js +327 -0
  32. package/lib/generators/components/GenerateComponentHObjCpp.js.flow +418 -0
  33. package/lib/generators/components/GenerateEventEmitterCpp.js +199 -0
  34. package/lib/generators/components/GenerateEventEmitterCpp.js.flow +273 -0
  35. package/lib/generators/components/GenerateEventEmitterH.js +224 -0
  36. package/lib/generators/components/GenerateEventEmitterH.js.flow +315 -0
  37. package/lib/generators/components/GeneratePropsCpp.js +126 -0
  38. package/lib/generators/components/GeneratePropsCpp.js.flow +161 -0
  39. package/lib/generators/components/GeneratePropsH.js +606 -0
  40. package/lib/generators/components/GeneratePropsH.js.flow +778 -0
  41. package/lib/generators/components/GeneratePropsJavaDelegate.js +287 -0
  42. package/lib/generators/components/GeneratePropsJavaDelegate.js.flow +348 -0
  43. package/lib/generators/components/GeneratePropsJavaInterface.js +237 -0
  44. package/lib/generators/components/GeneratePropsJavaInterface.js.flow +288 -0
  45. package/lib/generators/components/GeneratePropsJavaPojo/PojoCollector.js +157 -0
  46. package/lib/generators/components/GeneratePropsJavaPojo/PojoCollector.js.flow +187 -0
  47. package/lib/generators/components/GeneratePropsJavaPojo/index.js +66 -0
  48. package/lib/generators/components/GeneratePropsJavaPojo/index.js.flow +80 -0
  49. package/lib/generators/components/GeneratePropsJavaPojo/serializePojo.js +273 -0
  50. package/lib/generators/components/GeneratePropsJavaPojo/serializePojo.js.flow +296 -0
  51. package/lib/generators/components/GenerateShadowNodeCpp.js +73 -0
  52. package/lib/generators/components/GenerateShadowNodeCpp.js.flow +95 -0
  53. package/lib/generators/components/GenerateShadowNodeH.js +91 -0
  54. package/lib/generators/components/GenerateShadowNodeH.js.flow +124 -0
  55. package/lib/generators/components/GenerateStateCpp.js +70 -0
  56. package/lib/generators/components/GenerateStateCpp.js.flow +92 -0
  57. package/lib/generators/components/GenerateStateH.js +93 -0
  58. package/lib/generators/components/GenerateStateH.js.flow +111 -0
  59. package/lib/generators/components/GenerateTests.js +165 -0
  60. package/lib/generators/components/GenerateTests.js.flow +219 -0
  61. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderH.js +91 -0
  62. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderH.js.flow +107 -0
  63. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderObjCpp.js +89 -0
  64. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderObjCpp.js.flow +105 -0
  65. package/lib/generators/components/GenerateViewConfigJs.js +410 -0
  66. package/lib/generators/components/GenerateViewConfigJs.js.flow +484 -0
  67. package/lib/generators/components/JavaHelpers.js +87 -0
  68. package/lib/generators/components/JavaHelpers.js.flow +119 -0
  69. package/lib/generators/components/__test_fixtures__/fixtures.js +1641 -0
  70. package/lib/generators/components/__test_fixtures__/fixtures.js.flow +1672 -0
  71. package/lib/generators/modules/GenerateModuleCpp.js +299 -0
  72. package/lib/generators/modules/GenerateModuleCpp.js.flow +278 -0
  73. package/lib/generators/modules/GenerateModuleH.js +373 -0
  74. package/lib/generators/modules/GenerateModuleH.js.flow +355 -0
  75. package/lib/generators/modules/GenerateModuleJavaSpec.js +571 -0
  76. package/lib/generators/modules/GenerateModuleJavaSpec.js.flow +553 -0
  77. package/lib/generators/modules/GenerateModuleJniCpp.js +505 -0
  78. package/lib/generators/modules/GenerateModuleJniCpp.js.flow +523 -0
  79. package/lib/generators/modules/GenerateModuleJniH.js +138 -0
  80. package/lib/generators/modules/GenerateModuleJniH.js.flow +148 -0
  81. package/lib/generators/modules/GenerateModuleObjCpp/StructCollector.js +262 -0
  82. package/lib/generators/modules/GenerateModuleObjCpp/StructCollector.js.flow +208 -0
  83. package/lib/generators/modules/GenerateModuleObjCpp/Utils.js +25 -0
  84. package/lib/generators/modules/GenerateModuleObjCpp/Utils.js.flow +32 -0
  85. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js +337 -0
  86. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js.flow +288 -0
  87. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js +330 -0
  88. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js.flow +279 -0
  89. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js +25 -0
  90. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js.flow +35 -0
  91. package/lib/generators/modules/GenerateModuleObjCpp/index.js +185 -0
  92. package/lib/generators/modules/GenerateModuleObjCpp/index.js.flow +219 -0
  93. package/lib/generators/modules/GenerateModuleObjCpp/serializeMethod.js +529 -0
  94. package/lib/generators/modules/GenerateModuleObjCpp/serializeMethod.js.flow +510 -0
  95. package/lib/generators/modules/GenerateModuleObjCpp/source/serializeModule.js +96 -0
  96. package/lib/generators/modules/GenerateModuleObjCpp/source/serializeModule.js.flow +121 -0
  97. package/lib/generators/modules/Utils.js +34 -0
  98. package/lib/generators/modules/Utils.js.flow +53 -0
  99. package/lib/generators/modules/__test_fixtures__/fixtures.js +1658 -0
  100. package/lib/generators/modules/__test_fixtures__/fixtures.js.flow +1669 -0
  101. package/lib/parsers/consistency/compareSnaps.js +84 -0
  102. package/lib/parsers/error-utils.js +284 -0
  103. package/lib/parsers/error-utils.js.flow +295 -0
  104. package/lib/parsers/errors.js +350 -0
  105. package/lib/parsers/errors.js.flow +439 -0
  106. package/lib/parsers/flow/components/__test_fixtures__/failures.js +583 -0
  107. package/lib/parsers/flow/components/__test_fixtures__/failures.js.flow +600 -0
  108. package/lib/parsers/flow/components/__test_fixtures__/fixtures.js +1001 -0
  109. package/lib/parsers/flow/components/__test_fixtures__/fixtures.js.flow +1016 -0
  110. package/lib/parsers/flow/components/commands.js +104 -0
  111. package/lib/parsers/flow/components/commands.js.flow +123 -0
  112. package/lib/parsers/flow/components/componentsUtils.js +446 -0
  113. package/lib/parsers/flow/components/componentsUtils.js.flow +496 -0
  114. package/lib/parsers/flow/components/events.js +233 -0
  115. package/lib/parsers/flow/components/events.js.flow +262 -0
  116. package/lib/parsers/flow/components/extends.js +52 -0
  117. package/lib/parsers/flow/components/extends.js.flow +66 -0
  118. package/lib/parsers/flow/components/index.js +267 -0
  119. package/lib/parsers/flow/components/index.js.flow +226 -0
  120. package/lib/parsers/flow/components/options.js +72 -0
  121. package/lib/parsers/flow/components/options.js.flow +87 -0
  122. package/lib/parsers/flow/components/props.js +47 -0
  123. package/lib/parsers/flow/components/props.js.flow +60 -0
  124. package/lib/parsers/flow/components/schema.js +106 -0
  125. package/lib/parsers/flow/components/schema.js.flow +62 -0
  126. package/lib/parsers/flow/index.js +80 -0
  127. package/lib/parsers/flow/index.js.flow +85 -0
  128. package/lib/parsers/flow/modules/__test_fixtures__/failures.js +215 -0
  129. package/lib/parsers/flow/modules/__test_fixtures__/failures.js.flow +223 -0
  130. package/lib/parsers/flow/modules/__test_fixtures__/fixtures.js +724 -0
  131. package/lib/parsers/flow/modules/__test_fixtures__/fixtures.js.flow +747 -0
  132. package/lib/parsers/flow/modules/index.js +528 -0
  133. package/lib/parsers/flow/modules/index.js.flow +420 -0
  134. package/lib/parsers/flow/parser.js +109 -0
  135. package/lib/parsers/flow/parser.js.flow +83 -0
  136. package/lib/parsers/flow/utils.js +108 -0
  137. package/lib/parsers/flow/utils.js.flow +123 -0
  138. package/lib/parsers/parser.js +11 -0
  139. package/lib/parsers/parser.js.flow +70 -0
  140. package/lib/parsers/parserMock.js +96 -0
  141. package/lib/parsers/parserMock.js.flow +68 -0
  142. package/lib/parsers/parsers-commons.js +448 -0
  143. package/lib/parsers/parsers-commons.js.flow +447 -0
  144. package/lib/parsers/parsers-primitives.js +387 -0
  145. package/lib/parsers/parsers-primitives.js.flow +383 -0
  146. package/lib/parsers/parsers-utils.js +18 -0
  147. package/lib/parsers/parsers-utils.js.flow +19 -0
  148. package/lib/parsers/schema/index.js +23 -0
  149. package/lib/parsers/schema/index.js.flow +26 -0
  150. package/lib/parsers/typescript/components/__test_fixtures__/failures.js +489 -0
  151. package/lib/parsers/typescript/components/__test_fixtures__/failures.js.flow +505 -0
  152. package/lib/parsers/typescript/components/__test_fixtures__/fixtures.js +1151 -0
  153. package/lib/parsers/typescript/components/__test_fixtures__/fixtures.js.flow +1168 -0
  154. package/lib/parsers/typescript/components/commands.js +132 -0
  155. package/lib/parsers/typescript/components/commands.js.flow +151 -0
  156. package/lib/parsers/typescript/components/componentsUtils.js +471 -0
  157. package/lib/parsers/typescript/components/componentsUtils.js.flow +521 -0
  158. package/lib/parsers/typescript/components/events.js +240 -0
  159. package/lib/parsers/typescript/components/events.js.flow +262 -0
  160. package/lib/parsers/typescript/components/extends.js +88 -0
  161. package/lib/parsers/typescript/components/extends.js.flow +103 -0
  162. package/lib/parsers/typescript/components/index.js +277 -0
  163. package/lib/parsers/typescript/components/index.js.flow +239 -0
  164. package/lib/parsers/typescript/components/options.js +72 -0
  165. package/lib/parsers/typescript/components/options.js.flow +87 -0
  166. package/lib/parsers/typescript/components/props.js +39 -0
  167. package/lib/parsers/typescript/components/props.js.flow +48 -0
  168. package/lib/parsers/typescript/components/schema.js +106 -0
  169. package/lib/parsers/typescript/components/schema.js.flow +62 -0
  170. package/lib/parsers/typescript/index.js +85 -0
  171. package/lib/parsers/typescript/index.js.flow +94 -0
  172. package/lib/parsers/typescript/modules/__test_fixtures__/failures.js +160 -0
  173. package/lib/parsers/typescript/modules/__test_fixtures__/failures.js.flow +167 -0
  174. package/lib/parsers/typescript/modules/__test_fixtures__/fixtures.js +701 -0
  175. package/lib/parsers/typescript/modules/__test_fixtures__/fixtures.js.flow +727 -0
  176. package/lib/parsers/typescript/modules/index.js +543 -0
  177. package/lib/parsers/typescript/modules/index.js.flow +435 -0
  178. package/lib/parsers/typescript/parseTopLevelType.js +203 -0
  179. package/lib/parsers/typescript/parseTopLevelType.js.flow +243 -0
  180. package/lib/parsers/typescript/parser.js +105 -0
  181. package/lib/parsers/typescript/parser.js.flow +87 -0
  182. package/lib/parsers/typescript/utils.js +101 -0
  183. package/lib/parsers/typescript/utils.js.flow +115 -0
  184. package/lib/parsers/utils.js +273 -0
  185. package/lib/parsers/utils.js.flow +266 -0
  186. package/package.json +45 -0
@@ -0,0 +1,484 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ * @format
9
+ */
10
+
11
+ 'use strict';
12
+ import type {
13
+ ComponentShape,
14
+ EventTypeShape,
15
+ PropTypeAnnotation,
16
+ } from '../../CodegenSchema';
17
+ import type {SchemaType} from '../../CodegenSchema';
18
+
19
+ const j = require('jscodeshift');
20
+
21
+ // File path -> contents
22
+ type FilesOutput = Map<string, string>;
23
+
24
+ const FileTemplate = ({
25
+ imports,
26
+ componentConfig,
27
+ }: {
28
+ imports: string,
29
+ componentConfig: string,
30
+ }) => `
31
+ /**
32
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
33
+ *
34
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
35
+ * once the code is regenerated.
36
+ *
37
+ * @flow
38
+ *
39
+ * ${'@'}generated by codegen project: GenerateViewConfigJs.js
40
+ */
41
+
42
+ 'use strict';
43
+
44
+ ${imports}
45
+
46
+ ${componentConfig}
47
+ `;
48
+
49
+ // We use this to add to a set. Need to make sure we aren't importing
50
+ // this multiple times.
51
+ const UIMANAGER_IMPORT = 'const {UIManager} = require("react-native")';
52
+
53
+ function getReactDiffProcessValue(typeAnnotation: PropTypeAnnotation) {
54
+ switch (typeAnnotation.type) {
55
+ case 'BooleanTypeAnnotation':
56
+ case 'StringTypeAnnotation':
57
+ case 'Int32TypeAnnotation':
58
+ case 'DoubleTypeAnnotation':
59
+ case 'FloatTypeAnnotation':
60
+ case 'ObjectTypeAnnotation':
61
+ case 'StringEnumTypeAnnotation':
62
+ case 'Int32EnumTypeAnnotation':
63
+ return j.literal(true);
64
+ case 'ReservedPropTypeAnnotation':
65
+ switch (typeAnnotation.name) {
66
+ case 'ColorPrimitive':
67
+ return j.template
68
+ .expression`{ process: require('react-native/Libraries/StyleSheet/processColor') }`;
69
+ case 'ImageSourcePrimitive':
70
+ return j.template
71
+ .expression`{ process: require('react-native/Libraries/Image/resolveAssetSource') }`;
72
+ case 'ImageRequestPrimitive':
73
+ throw new Error('ImageRequest should not be used in props');
74
+ case 'PointPrimitive':
75
+ return j.template
76
+ .expression`{ diff: require('react-native/Libraries/Utilities/differ/pointsDiffer') }`;
77
+ case 'EdgeInsetsPrimitive':
78
+ return j.template
79
+ .expression`{ diff: require('react-native/Libraries/Utilities/differ/insetsDiffer') }`;
80
+ default:
81
+ (typeAnnotation.name: empty);
82
+ throw new Error(
83
+ `Received unknown native typeAnnotation: "${typeAnnotation.name}"`,
84
+ );
85
+ }
86
+ case 'ArrayTypeAnnotation':
87
+ if (typeAnnotation.elementType.type === 'ReservedPropTypeAnnotation') {
88
+ switch (typeAnnotation.elementType.name) {
89
+ case 'ColorPrimitive':
90
+ return j.template
91
+ .expression`{ process: require('react-native/Libraries/StyleSheet/processColorArray') }`;
92
+ case 'ImageSourcePrimitive':
93
+ return j.literal(true);
94
+ case 'PointPrimitive':
95
+ return j.literal(true);
96
+ default:
97
+ throw new Error(
98
+ `Received unknown array native typeAnnotation: "${typeAnnotation.elementType.name}"`,
99
+ );
100
+ }
101
+ }
102
+ return j.literal(true);
103
+ default:
104
+ (typeAnnotation: empty);
105
+ throw new Error(
106
+ `Received unknown typeAnnotation: "${typeAnnotation.type}"`,
107
+ );
108
+ }
109
+ }
110
+
111
+ const ComponentTemplate = ({
112
+ componentName,
113
+ paperComponentName,
114
+ paperComponentNameDeprecated,
115
+ }: {
116
+ componentName: string,
117
+ paperComponentName: ?string,
118
+ paperComponentNameDeprecated: ?string,
119
+ }) => {
120
+ const nativeComponentName = paperComponentName ?? componentName;
121
+
122
+ return `
123
+ let nativeComponentName = '${nativeComponentName}';
124
+ ${
125
+ paperComponentNameDeprecated != null
126
+ ? DeprecatedComponentNameCheckTemplate({
127
+ componentName,
128
+ paperComponentNameDeprecated,
129
+ })
130
+ : ''
131
+ }
132
+
133
+ export const __INTERNAL_VIEW_CONFIG = VIEW_CONFIG;
134
+
135
+ export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL_VIEW_CONFIG);
136
+ `.trim();
137
+ };
138
+
139
+ // Check whether the native component exists in the app binary.
140
+ // Old getViewManagerConfig() checks for the existance of the native Paper view manager. Not available in Bridgeless.
141
+ // New hasViewManagerConfig() queries Fabric’s native component registry directly.
142
+ const DeprecatedComponentNameCheckTemplate = ({
143
+ componentName,
144
+ paperComponentNameDeprecated,
145
+ }: {
146
+ componentName: string,
147
+ paperComponentNameDeprecated: string,
148
+ }) =>
149
+ `
150
+ if (UIManager.hasViewManagerConfig('${componentName}')) {
151
+ nativeComponentName = '${componentName}';
152
+ } else if (UIManager.hasViewManagerConfig('${paperComponentNameDeprecated}')) {
153
+ nativeComponentName = '${paperComponentNameDeprecated}';
154
+ } else {
155
+ throw new Error('Failed to find native component for either "${componentName}" or "${paperComponentNameDeprecated}"');
156
+ }
157
+ `.trim();
158
+
159
+ // Replicates the behavior of RCTNormalizeInputEventName in RCTEventDispatcher.m
160
+ function normalizeInputEventName(name: string) {
161
+ if (name.startsWith('on')) {
162
+ return name.replace(/^on/, 'top');
163
+ } else if (!name.startsWith('top')) {
164
+ return `top${name[0].toUpperCase()}${name.slice(1)}`;
165
+ }
166
+
167
+ return name;
168
+ }
169
+
170
+ // Replicates the behavior of viewConfig in RCTComponentData.m
171
+ function getValidAttributesForEvents(
172
+ events: $ReadOnlyArray<EventTypeShape>,
173
+ imports: Set<string>,
174
+ ) {
175
+ imports.add(
176
+ "const {ConditionallyIgnoredEventHandlers} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');",
177
+ );
178
+
179
+ const validAttributes = j.objectExpression(
180
+ events.map(eventType => {
181
+ return j.property('init', j.identifier(eventType.name), j.literal(true));
182
+ }),
183
+ );
184
+
185
+ return j.callExpression(j.identifier('ConditionallyIgnoredEventHandlers'), [
186
+ validAttributes,
187
+ ]);
188
+ }
189
+
190
+ function generateBubblingEventInfo(
191
+ event: EventTypeShape,
192
+ nameOveride: void | string,
193
+ ) {
194
+ return j.property(
195
+ 'init',
196
+ j.identifier(nameOveride || normalizeInputEventName(event.name)),
197
+ j.objectExpression([
198
+ j.property(
199
+ 'init',
200
+ j.identifier('phasedRegistrationNames'),
201
+ j.objectExpression([
202
+ j.property(
203
+ 'init',
204
+ j.identifier('captured'),
205
+ j.literal(`${event.name}Capture`),
206
+ ),
207
+ j.property('init', j.identifier('bubbled'), j.literal(event.name)),
208
+ ]),
209
+ ),
210
+ ]),
211
+ );
212
+ }
213
+
214
+ function generateDirectEventInfo(
215
+ event: EventTypeShape,
216
+ nameOveride: void | string,
217
+ ) {
218
+ return j.property(
219
+ 'init',
220
+ j.identifier(nameOveride || normalizeInputEventName(event.name)),
221
+ j.objectExpression([
222
+ j.property(
223
+ 'init',
224
+ j.identifier('registrationName'),
225
+ j.literal(event.name),
226
+ ),
227
+ ]),
228
+ );
229
+ }
230
+
231
+ function buildViewConfig(
232
+ schema: SchemaType,
233
+ componentName: string,
234
+ component: ComponentShape,
235
+ imports: Set<string>,
236
+ ) {
237
+ const componentProps = component.props;
238
+ const componentEvents = component.events;
239
+
240
+ component.extendsProps.forEach(extendProps => {
241
+ switch (extendProps.type) {
242
+ case 'ReactNativeBuiltInType':
243
+ switch (extendProps.knownTypeName) {
244
+ case 'ReactNativeCoreViewProps':
245
+ imports.add(
246
+ "const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');",
247
+ );
248
+
249
+ return;
250
+ default:
251
+ (extendProps.knownTypeName: empty);
252
+ throw new Error('Invalid knownTypeName');
253
+ }
254
+ default:
255
+ (extendProps.type: empty);
256
+ throw new Error('Invalid extended type');
257
+ }
258
+ });
259
+
260
+ const validAttributes = j.objectExpression([
261
+ ...componentProps.map(schemaProp => {
262
+ return j.property(
263
+ 'init',
264
+ j.identifier(schemaProp.name),
265
+ getReactDiffProcessValue(schemaProp.typeAnnotation),
266
+ );
267
+ }),
268
+ ...(componentEvents.length > 0
269
+ ? [
270
+ j.spreadProperty(
271
+ getValidAttributesForEvents(componentEvents, imports),
272
+ ),
273
+ ]
274
+ : []),
275
+ ]);
276
+
277
+ const bubblingEventNames = component.events
278
+ .filter(event => event.bubblingType === 'bubble')
279
+ .reduce((bubblingEvents: Array<any>, event) => {
280
+ // We add in the deprecated paper name so that it is in the view config.
281
+ // This means either the old event name or the new event name can fire
282
+ // and be sent to the listener until the old top level name is removed.
283
+ if (event.paperTopLevelNameDeprecated) {
284
+ bubblingEvents.push(
285
+ generateBubblingEventInfo(event, event.paperTopLevelNameDeprecated),
286
+ );
287
+ } else {
288
+ bubblingEvents.push(generateBubblingEventInfo(event));
289
+ }
290
+ return bubblingEvents;
291
+ }, []);
292
+
293
+ const bubblingEvents =
294
+ bubblingEventNames.length > 0
295
+ ? j.property(
296
+ 'init',
297
+ j.identifier('bubblingEventTypes'),
298
+ j.objectExpression(bubblingEventNames),
299
+ )
300
+ : null;
301
+
302
+ const directEventNames = component.events
303
+ .filter(event => event.bubblingType === 'direct')
304
+ .reduce((directEvents: Array<any>, event) => {
305
+ // We add in the deprecated paper name so that it is in the view config.
306
+ // This means either the old event name or the new event name can fire
307
+ // and be sent to the listener until the old top level name is removed.
308
+ if (event.paperTopLevelNameDeprecated) {
309
+ directEvents.push(
310
+ generateDirectEventInfo(event, event.paperTopLevelNameDeprecated),
311
+ );
312
+ } else {
313
+ directEvents.push(generateDirectEventInfo(event));
314
+ }
315
+ return directEvents;
316
+ }, []);
317
+
318
+ const directEvents =
319
+ directEventNames.length > 0
320
+ ? j.property(
321
+ 'init',
322
+ j.identifier('directEventTypes'),
323
+ j.objectExpression(directEventNames),
324
+ )
325
+ : null;
326
+
327
+ const properties = [
328
+ j.property(
329
+ 'init',
330
+ j.identifier('uiViewClassName'),
331
+ j.literal(componentName),
332
+ ),
333
+ bubblingEvents,
334
+ directEvents,
335
+ j.property('init', j.identifier('validAttributes'), validAttributes),
336
+ ].filter(Boolean);
337
+
338
+ return j.objectExpression(properties);
339
+ }
340
+
341
+ function buildCommands(
342
+ schema: SchemaType,
343
+ componentName: string,
344
+ component: ComponentShape,
345
+ imports: Set<string>,
346
+ ) {
347
+ const commands = component.commands;
348
+
349
+ if (commands.length === 0) {
350
+ return null;
351
+ }
352
+
353
+ imports.add(
354
+ 'const {dispatchCommand} = require("react-native/Libraries/ReactNative/RendererProxy");',
355
+ );
356
+
357
+ const properties = commands.map(command => {
358
+ const commandName = command.name;
359
+ const params = command.typeAnnotation.params;
360
+
361
+ const commandNameLiteral = j.literal(commandName);
362
+ const commandNameIdentifier = j.identifier(commandName);
363
+ const arrayParams = j.arrayExpression(
364
+ params.map(param => {
365
+ return j.identifier(param.name);
366
+ }),
367
+ );
368
+
369
+ const expression = j.template
370
+ .expression`dispatchCommand(ref, ${commandNameLiteral}, ${arrayParams})`;
371
+
372
+ const functionParams = params.map(param => {
373
+ return j.identifier(param.name);
374
+ });
375
+
376
+ const property = j.property(
377
+ 'init',
378
+ commandNameIdentifier,
379
+ j.functionExpression(
380
+ null,
381
+ [j.identifier('ref'), ...functionParams],
382
+ j.blockStatement([j.expressionStatement(expression)]),
383
+ ),
384
+ );
385
+ property.method = true;
386
+
387
+ return property;
388
+ });
389
+
390
+ return j.exportNamedDeclaration(
391
+ j.variableDeclaration('const', [
392
+ j.variableDeclarator(
393
+ j.identifier('Commands'),
394
+ j.objectExpression(properties),
395
+ ),
396
+ ]),
397
+ );
398
+ }
399
+
400
+ module.exports = {
401
+ generate(libraryName: string, schema: SchemaType): FilesOutput {
402
+ try {
403
+ const fileName = `${libraryName}NativeViewConfig.js`;
404
+ const imports: Set<string> = new Set();
405
+
406
+ const moduleResults = Object.keys(schema.modules)
407
+ .map(moduleName => {
408
+ const module = schema.modules[moduleName];
409
+ if (module.type !== 'Component') {
410
+ return;
411
+ }
412
+
413
+ const {components} = module;
414
+
415
+ return Object.keys(components)
416
+ .map((componentName: string) => {
417
+ const component = components[componentName];
418
+
419
+ if (component.paperComponentNameDeprecated) {
420
+ imports.add(UIMANAGER_IMPORT);
421
+ }
422
+
423
+ const replacedTemplate = ComponentTemplate({
424
+ componentName,
425
+ paperComponentName: component.paperComponentName,
426
+ paperComponentNameDeprecated:
427
+ component.paperComponentNameDeprecated,
428
+ });
429
+
430
+ const replacedSourceRoot = j.withParser('flow')(replacedTemplate);
431
+
432
+ const paperComponentName =
433
+ component.paperComponentName ?? componentName;
434
+
435
+ replacedSourceRoot
436
+ .find(j.Identifier, {
437
+ name: 'VIEW_CONFIG',
438
+ })
439
+ .replaceWith(
440
+ buildViewConfig(
441
+ schema,
442
+ paperComponentName,
443
+ component,
444
+ imports,
445
+ ),
446
+ );
447
+
448
+ const commands = buildCommands(
449
+ schema,
450
+ paperComponentName,
451
+ component,
452
+ imports,
453
+ );
454
+ if (commands) {
455
+ replacedSourceRoot
456
+ .find(j.ExportDefaultDeclaration)
457
+ .insertAfter(j(commands).toSource());
458
+ }
459
+
460
+ const replacedSource: string = replacedSourceRoot.toSource({
461
+ quote: 'single',
462
+ trailingComma: true,
463
+ });
464
+
465
+ return replacedSource;
466
+ })
467
+ .join('\n\n');
468
+ })
469
+ .filter(Boolean)
470
+ .join('\n\n');
471
+
472
+ const replacedTemplate = FileTemplate({
473
+ componentConfig: moduleResults,
474
+ imports: Array.from(imports).sort().join('\n'),
475
+ });
476
+
477
+ return new Map([[fileName, replacedTemplate]]);
478
+ } catch (error) {
479
+ console.error(`\nError parsing schema for ${libraryName}\n`);
480
+ console.error(JSON.stringify(schema));
481
+ throw error;
482
+ }
483
+ },
484
+ };
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ *
8
+ * @format
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ function upperCaseFirst(inString) {
14
+ return inString[0].toUpperCase() + inString.slice(1);
15
+ }
16
+ function getInterfaceJavaClassName(componentName) {
17
+ return `${componentName.replace(/^RCT/, '')}ManagerInterface`;
18
+ }
19
+ function getDelegateJavaClassName(componentName) {
20
+ return `${componentName.replace(/^RCT/, '')}ManagerDelegate`;
21
+ }
22
+ function toSafeJavaString(input, shouldUpperCaseFirst) {
23
+ const parts = input.split('-');
24
+ if (shouldUpperCaseFirst === false) {
25
+ return parts.join('');
26
+ }
27
+ return parts.map(upperCaseFirst).join('');
28
+ }
29
+ function getImports(component, type) {
30
+ const imports = new Set();
31
+ component.extendsProps.forEach(extendProps => {
32
+ switch (extendProps.type) {
33
+ case 'ReactNativeBuiltInType':
34
+ switch (extendProps.knownTypeName) {
35
+ case 'ReactNativeCoreViewProps':
36
+ imports.add('import android.view.View;');
37
+ return;
38
+ default:
39
+ extendProps.knownTypeName;
40
+ throw new Error('Invalid knownTypeName');
41
+ }
42
+ default:
43
+ extendProps.type;
44
+ throw new Error('Invalid extended type');
45
+ }
46
+ });
47
+ function addImportsForNativeName(name) {
48
+ switch (name) {
49
+ case 'ColorPrimitive':
50
+ if (type === 'delegate') {
51
+ imports.add('import com.facebook.react.bridge.ColorPropConverter;');
52
+ }
53
+ return;
54
+ case 'ImageSourcePrimitive':
55
+ imports.add('import com.facebook.react.bridge.ReadableMap;');
56
+ return;
57
+ case 'PointPrimitive':
58
+ imports.add('import com.facebook.react.bridge.ReadableMap;');
59
+ return;
60
+ case 'EdgeInsetsPrimitive':
61
+ imports.add('import com.facebook.react.bridge.ReadableMap;');
62
+ return;
63
+ default:
64
+ name;
65
+ throw new Error(`Invalid ReservedPropTypeAnnotation name, got ${name}`);
66
+ }
67
+ }
68
+ component.props.forEach(prop => {
69
+ const typeAnnotation = prop.typeAnnotation;
70
+ if (typeAnnotation.type === 'ReservedPropTypeAnnotation') {
71
+ addImportsForNativeName(typeAnnotation.name);
72
+ }
73
+ if (typeAnnotation.type === 'ArrayTypeAnnotation') {
74
+ imports.add('import com.facebook.react.bridge.ReadableArray;');
75
+ }
76
+ if (typeAnnotation.type === 'ObjectTypeAnnotation') {
77
+ imports.add('import com.facebook.react.bridge.ReadableMap;');
78
+ }
79
+ });
80
+ return imports;
81
+ }
82
+ module.exports = {
83
+ getInterfaceJavaClassName,
84
+ getDelegateJavaClassName,
85
+ toSafeJavaString,
86
+ getImports,
87
+ };
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ * @format
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ import type {ComponentShape} from '../../CodegenSchema';
14
+
15
+ function upperCaseFirst(inString: string): string {
16
+ return inString[0].toUpperCase() + inString.slice(1);
17
+ }
18
+
19
+ function getInterfaceJavaClassName(componentName: string): string {
20
+ return `${componentName.replace(/^RCT/, '')}ManagerInterface`;
21
+ }
22
+
23
+ function getDelegateJavaClassName(componentName: string): string {
24
+ return `${componentName.replace(/^RCT/, '')}ManagerDelegate`;
25
+ }
26
+
27
+ function toSafeJavaString(
28
+ input: string,
29
+ shouldUpperCaseFirst?: boolean,
30
+ ): string {
31
+ const parts = input.split('-');
32
+
33
+ if (shouldUpperCaseFirst === false) {
34
+ return parts.join('');
35
+ }
36
+
37
+ return parts.map(upperCaseFirst).join('');
38
+ }
39
+
40
+ function getImports(
41
+ component: ComponentShape,
42
+ type: 'interface' | 'delegate',
43
+ ): Set<string> {
44
+ const imports: Set<string> = new Set();
45
+
46
+ component.extendsProps.forEach(extendProps => {
47
+ switch (extendProps.type) {
48
+ case 'ReactNativeBuiltInType':
49
+ switch (extendProps.knownTypeName) {
50
+ case 'ReactNativeCoreViewProps':
51
+ imports.add('import android.view.View;');
52
+ return;
53
+ default:
54
+ (extendProps.knownTypeName: empty);
55
+ throw new Error('Invalid knownTypeName');
56
+ }
57
+ default:
58
+ (extendProps.type: empty);
59
+ throw new Error('Invalid extended type');
60
+ }
61
+ });
62
+
63
+ function addImportsForNativeName(
64
+ name:
65
+ | 'ColorPrimitive'
66
+ | 'EdgeInsetsPrimitive'
67
+ | 'ImageSourcePrimitive'
68
+ | 'PointPrimitive'
69
+ | $TEMPORARY$string<'ColorPrimitive'>
70
+ | $TEMPORARY$string<'EdgeInsetsPrimitive'>
71
+ | $TEMPORARY$string<'ImageSourcePrimitive'>
72
+ | $TEMPORARY$string<'PointPrimitive'>,
73
+ ) {
74
+ switch (name) {
75
+ case 'ColorPrimitive':
76
+ if (type === 'delegate') {
77
+ imports.add('import com.facebook.react.bridge.ColorPropConverter;');
78
+ }
79
+ return;
80
+ case 'ImageSourcePrimitive':
81
+ imports.add('import com.facebook.react.bridge.ReadableMap;');
82
+ return;
83
+ case 'PointPrimitive':
84
+ imports.add('import com.facebook.react.bridge.ReadableMap;');
85
+ return;
86
+ case 'EdgeInsetsPrimitive':
87
+ imports.add('import com.facebook.react.bridge.ReadableMap;');
88
+ return;
89
+ default:
90
+ (name: empty);
91
+ throw new Error(`Invalid ReservedPropTypeAnnotation name, got ${name}`);
92
+ }
93
+ }
94
+
95
+ component.props.forEach(prop => {
96
+ const typeAnnotation = prop.typeAnnotation;
97
+
98
+ if (typeAnnotation.type === 'ReservedPropTypeAnnotation') {
99
+ addImportsForNativeName(typeAnnotation.name);
100
+ }
101
+
102
+ if (typeAnnotation.type === 'ArrayTypeAnnotation') {
103
+ imports.add('import com.facebook.react.bridge.ReadableArray;');
104
+ }
105
+
106
+ if (typeAnnotation.type === 'ObjectTypeAnnotation') {
107
+ imports.add('import com.facebook.react.bridge.ReadableMap;');
108
+ }
109
+ });
110
+
111
+ return imports;
112
+ }
113
+
114
+ module.exports = {
115
+ getInterfaceJavaClassName,
116
+ getDelegateJavaClassName,
117
+ toSafeJavaString,
118
+ getImports,
119
+ };