@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,104 @@
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
+ const _require = require('../utils.js'),
14
+ getValueFromTypes = _require.getValueFromTypes;
15
+ function buildCommandSchema(property, types) {
16
+ const name = property.key.name;
17
+ const optional = property.optional;
18
+ const value = getValueFromTypes(property.value, types);
19
+ const firstParam = value.params[0].typeAnnotation;
20
+ if (
21
+ !(
22
+ firstParam.id != null &&
23
+ firstParam.id.type === 'QualifiedTypeIdentifier' &&
24
+ firstParam.id.qualification.name === 'React' &&
25
+ firstParam.id.id.name === 'ElementRef'
26
+ )
27
+ ) {
28
+ throw new Error(
29
+ `The first argument of method ${name} must be of type React.ElementRef<>`,
30
+ );
31
+ }
32
+ const params = value.params.slice(1).map(param => {
33
+ const paramName = param.name.name;
34
+ const paramValue = getValueFromTypes(param.typeAnnotation, types);
35
+ const type =
36
+ paramValue.type === 'GenericTypeAnnotation'
37
+ ? paramValue.id.name
38
+ : paramValue.type;
39
+ let returnType;
40
+ switch (type) {
41
+ case 'RootTag':
42
+ returnType = {
43
+ type: 'ReservedTypeAnnotation',
44
+ name: 'RootTag',
45
+ };
46
+ break;
47
+ case 'BooleanTypeAnnotation':
48
+ returnType = {
49
+ type: 'BooleanTypeAnnotation',
50
+ };
51
+ break;
52
+ case 'Int32':
53
+ returnType = {
54
+ type: 'Int32TypeAnnotation',
55
+ };
56
+ break;
57
+ case 'Double':
58
+ returnType = {
59
+ type: 'DoubleTypeAnnotation',
60
+ };
61
+ break;
62
+ case 'Float':
63
+ returnType = {
64
+ type: 'FloatTypeAnnotation',
65
+ };
66
+ break;
67
+ case 'StringTypeAnnotation':
68
+ returnType = {
69
+ type: 'StringTypeAnnotation',
70
+ };
71
+ break;
72
+ default:
73
+ type;
74
+ throw new Error(
75
+ `Unsupported param type for method "${name}", param "${paramName}". Found ${type}`,
76
+ );
77
+ }
78
+ return {
79
+ name: paramName,
80
+ optional: false,
81
+ typeAnnotation: returnType,
82
+ };
83
+ });
84
+ return {
85
+ name,
86
+ optional,
87
+ typeAnnotation: {
88
+ type: 'FunctionTypeAnnotation',
89
+ params,
90
+ returnTypeAnnotation: {
91
+ type: 'VoidTypeAnnotation',
92
+ },
93
+ },
94
+ };
95
+ }
96
+ function getCommands(commandTypeAST, types) {
97
+ return commandTypeAST
98
+ .filter(property => property.type === 'ObjectTypeProperty')
99
+ .map(property => buildCommandSchema(property, types))
100
+ .filter(Boolean);
101
+ }
102
+ module.exports = {
103
+ getCommands,
104
+ };
@@ -0,0 +1,123 @@
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
+
13
+ import type {
14
+ NamedShape,
15
+ CommandTypeAnnotation,
16
+ } from '../../../CodegenSchema.js';
17
+ import type {TypeDeclarationMap} from '../../utils';
18
+
19
+ const {getValueFromTypes} = require('../utils.js');
20
+
21
+ type EventTypeAST = Object;
22
+
23
+ function buildCommandSchema(property: EventTypeAST, types: TypeDeclarationMap) {
24
+ const name = property.key.name;
25
+ const optional = property.optional;
26
+ const value = getValueFromTypes(property.value, types);
27
+
28
+ const firstParam = value.params[0].typeAnnotation;
29
+
30
+ if (
31
+ !(
32
+ firstParam.id != null &&
33
+ firstParam.id.type === 'QualifiedTypeIdentifier' &&
34
+ firstParam.id.qualification.name === 'React' &&
35
+ firstParam.id.id.name === 'ElementRef'
36
+ )
37
+ ) {
38
+ throw new Error(
39
+ `The first argument of method ${name} must be of type React.ElementRef<>`,
40
+ );
41
+ }
42
+
43
+ const params = value.params.slice(1).map(param => {
44
+ const paramName = param.name.name;
45
+ const paramValue = getValueFromTypes(param.typeAnnotation, types);
46
+ const type =
47
+ paramValue.type === 'GenericTypeAnnotation'
48
+ ? paramValue.id.name
49
+ : paramValue.type;
50
+ let returnType;
51
+
52
+ switch (type) {
53
+ case 'RootTag':
54
+ returnType = {
55
+ type: 'ReservedTypeAnnotation',
56
+ name: 'RootTag',
57
+ };
58
+ break;
59
+ case 'BooleanTypeAnnotation':
60
+ returnType = {
61
+ type: 'BooleanTypeAnnotation',
62
+ };
63
+ break;
64
+ case 'Int32':
65
+ returnType = {
66
+ type: 'Int32TypeAnnotation',
67
+ };
68
+ break;
69
+ case 'Double':
70
+ returnType = {
71
+ type: 'DoubleTypeAnnotation',
72
+ };
73
+ break;
74
+ case 'Float':
75
+ returnType = {
76
+ type: 'FloatTypeAnnotation',
77
+ };
78
+ break;
79
+ case 'StringTypeAnnotation':
80
+ returnType = {
81
+ type: 'StringTypeAnnotation',
82
+ };
83
+ break;
84
+ default:
85
+ (type: empty);
86
+ throw new Error(
87
+ `Unsupported param type for method "${name}", param "${paramName}". Found ${type}`,
88
+ );
89
+ }
90
+
91
+ return {
92
+ name: paramName,
93
+ optional: false,
94
+ typeAnnotation: returnType,
95
+ };
96
+ });
97
+
98
+ return {
99
+ name,
100
+ optional,
101
+ typeAnnotation: {
102
+ type: 'FunctionTypeAnnotation',
103
+ params,
104
+ returnTypeAnnotation: {
105
+ type: 'VoidTypeAnnotation',
106
+ },
107
+ },
108
+ };
109
+ }
110
+
111
+ function getCommands(
112
+ commandTypeAST: $ReadOnlyArray<EventTypeAST>,
113
+ types: TypeDeclarationMap,
114
+ ): $ReadOnlyArray<NamedShape<CommandTypeAnnotation>> {
115
+ return commandTypeAST
116
+ .filter(property => property.type === 'ObjectTypeProperty')
117
+ .map(property => buildCommandSchema(property, types))
118
+ .filter(Boolean);
119
+ }
120
+
121
+ module.exports = {
122
+ getCommands,
123
+ };
@@ -0,0 +1,446 @@
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
+ const _require = require('../utils.js'),
14
+ getValueFromTypes = _require.getValueFromTypes;
15
+ function getProperties(typeName, types) {
16
+ const typeAlias = types[typeName];
17
+ try {
18
+ return typeAlias.right.typeParameters.params[0].properties;
19
+ } catch (e) {
20
+ throw new Error(
21
+ `Failed to find type definition for "${typeName}", please check that you have a valid codegen flow file`,
22
+ );
23
+ }
24
+ }
25
+ function getTypeAnnotationForArray(
26
+ name,
27
+ typeAnnotation,
28
+ defaultValue,
29
+ types,
30
+ buildSchema,
31
+ ) {
32
+ const extractedTypeAnnotation = getValueFromTypes(typeAnnotation, types);
33
+ if (extractedTypeAnnotation.type === 'NullableTypeAnnotation') {
34
+ throw new Error(
35
+ 'Nested optionals such as "$ReadOnlyArray<?boolean>" are not supported, please declare optionals at the top level of value definitions as in "?$ReadOnlyArray<boolean>"',
36
+ );
37
+ }
38
+ if (
39
+ extractedTypeAnnotation.type === 'GenericTypeAnnotation' &&
40
+ extractedTypeAnnotation.id.name === 'WithDefault'
41
+ ) {
42
+ throw new Error(
43
+ 'Nested defaults such as "$ReadOnlyArray<WithDefault<boolean, false>>" are not supported, please declare defaults at the top level of value definitions as in "WithDefault<$ReadOnlyArray<boolean>, false>"',
44
+ );
45
+ }
46
+ if (extractedTypeAnnotation.type === 'GenericTypeAnnotation') {
47
+ // Resolve the type alias if it's not defined inline
48
+ const objectType = getValueFromTypes(extractedTypeAnnotation, types);
49
+ if (objectType.id.name === '$ReadOnly') {
50
+ return {
51
+ type: 'ObjectTypeAnnotation',
52
+ properties: flattenProperties(
53
+ objectType.typeParameters.params[0].properties,
54
+ types,
55
+ )
56
+ .map(prop => buildSchema(prop, types))
57
+ .filter(Boolean),
58
+ };
59
+ }
60
+ if (objectType.id.name === '$ReadOnlyArray') {
61
+ // We need to go yet another level deeper to resolve
62
+ // types that may be defined in a type alias
63
+ const nestedObjectType = getValueFromTypes(
64
+ objectType.typeParameters.params[0],
65
+ types,
66
+ );
67
+ return {
68
+ type: 'ArrayTypeAnnotation',
69
+ elementType: {
70
+ type: 'ObjectTypeAnnotation',
71
+ properties: flattenProperties(
72
+ nestedObjectType.typeParameters.params[0].properties,
73
+ types,
74
+ )
75
+ .map(prop => buildSchema(prop, types))
76
+ .filter(Boolean),
77
+ },
78
+ };
79
+ }
80
+ }
81
+ const type =
82
+ extractedTypeAnnotation.type === 'GenericTypeAnnotation'
83
+ ? extractedTypeAnnotation.id.name
84
+ : extractedTypeAnnotation.type;
85
+ switch (type) {
86
+ case 'ImageSource':
87
+ return {
88
+ type: 'ReservedPropTypeAnnotation',
89
+ name: 'ImageSourcePrimitive',
90
+ };
91
+ case 'ImageRequest':
92
+ return {
93
+ type: 'ReservedPropTypeAnnotation',
94
+ name: 'ImageRequestPrimitive',
95
+ };
96
+ case 'ColorValue':
97
+ case 'ProcessedColorValue':
98
+ return {
99
+ type: 'ReservedPropTypeAnnotation',
100
+ name: 'ColorPrimitive',
101
+ };
102
+ case 'PointValue':
103
+ return {
104
+ type: 'ReservedPropTypeAnnotation',
105
+ name: 'PointPrimitive',
106
+ };
107
+ case 'EdgeInsetsValue':
108
+ return {
109
+ type: 'ReservedPropTypeAnnotation',
110
+ name: 'EdgeInsetsPrimitive',
111
+ };
112
+ case 'Stringish':
113
+ return {
114
+ type: 'StringTypeAnnotation',
115
+ };
116
+ case 'Int32':
117
+ return {
118
+ type: 'Int32TypeAnnotation',
119
+ };
120
+ case 'Double':
121
+ return {
122
+ type: 'DoubleTypeAnnotation',
123
+ };
124
+ case 'Float':
125
+ return {
126
+ type: 'FloatTypeAnnotation',
127
+ };
128
+ case 'BooleanTypeAnnotation':
129
+ return {
130
+ type: 'BooleanTypeAnnotation',
131
+ };
132
+ case 'StringTypeAnnotation':
133
+ return {
134
+ type: 'StringTypeAnnotation',
135
+ };
136
+ case 'UnionTypeAnnotation':
137
+ typeAnnotation.types.reduce((lastType, currType) => {
138
+ if (lastType && currType.type !== lastType.type) {
139
+ throw new Error(`Mixed types are not supported (see "${name}")`);
140
+ }
141
+ return currType;
142
+ });
143
+ if (defaultValue === null) {
144
+ throw new Error(`A default enum value is required for "${name}"`);
145
+ }
146
+ const unionType = typeAnnotation.types[0].type;
147
+ if (unionType === 'StringLiteralTypeAnnotation') {
148
+ return {
149
+ type: 'StringEnumTypeAnnotation',
150
+ default: defaultValue,
151
+ options: typeAnnotation.types.map(option => option.value),
152
+ };
153
+ } else if (unionType === 'NumberLiteralTypeAnnotation') {
154
+ throw new Error(
155
+ `Arrays of int enums are not supported (see: "${name}")`,
156
+ );
157
+ } else {
158
+ throw new Error(
159
+ `Unsupported union type for "${name}", received "${unionType}"`,
160
+ );
161
+ }
162
+ default:
163
+ type;
164
+ throw new Error(`Unknown property type for "${name}": ${type}`);
165
+ }
166
+ }
167
+ function flattenProperties(typeDefinition, types) {
168
+ return typeDefinition
169
+ .map(property => {
170
+ if (property.type === 'ObjectTypeProperty') {
171
+ return property;
172
+ } else if (property.type === 'ObjectTypeSpreadProperty') {
173
+ return flattenProperties(
174
+ getProperties(property.argument.id.name, types),
175
+ types,
176
+ );
177
+ }
178
+ })
179
+ .reduce((acc, item) => {
180
+ if (Array.isArray(item)) {
181
+ item.forEach(prop => {
182
+ verifyPropNotAlreadyDefined(acc, prop);
183
+ });
184
+ return acc.concat(item);
185
+ } else {
186
+ verifyPropNotAlreadyDefined(acc, item);
187
+ acc.push(item);
188
+ return acc;
189
+ }
190
+ }, [])
191
+ .filter(Boolean);
192
+ }
193
+ function verifyPropNotAlreadyDefined(props, needleProp) {
194
+ const propName = needleProp.key.name;
195
+ const foundProp = props.some(prop => prop.key.name === propName);
196
+ if (foundProp) {
197
+ throw new Error(`A prop was already defined with the name ${propName}`);
198
+ }
199
+ }
200
+ function getTypeAnnotation(
201
+ name,
202
+ annotation,
203
+ defaultValue,
204
+ withNullDefault,
205
+ types,
206
+ buildSchema,
207
+ ) {
208
+ const typeAnnotation = getValueFromTypes(annotation, types);
209
+ if (
210
+ typeAnnotation.type === 'GenericTypeAnnotation' &&
211
+ typeAnnotation.id.name === '$ReadOnlyArray'
212
+ ) {
213
+ return {
214
+ type: 'ArrayTypeAnnotation',
215
+ elementType: getTypeAnnotationForArray(
216
+ name,
217
+ typeAnnotation.typeParameters.params[0],
218
+ defaultValue,
219
+ types,
220
+ buildSchema,
221
+ ),
222
+ };
223
+ }
224
+ if (
225
+ typeAnnotation.type === 'GenericTypeAnnotation' &&
226
+ typeAnnotation.id.name === '$ReadOnly'
227
+ ) {
228
+ return {
229
+ type: 'ObjectTypeAnnotation',
230
+ properties: flattenProperties(
231
+ typeAnnotation.typeParameters.params[0].properties,
232
+ types,
233
+ )
234
+ .map(prop => buildSchema(prop, types))
235
+ .filter(Boolean),
236
+ };
237
+ }
238
+ const type =
239
+ typeAnnotation.type === 'GenericTypeAnnotation'
240
+ ? typeAnnotation.id.name
241
+ : typeAnnotation.type;
242
+ switch (type) {
243
+ case 'ImageSource':
244
+ return {
245
+ type: 'ReservedPropTypeAnnotation',
246
+ name: 'ImageSourcePrimitive',
247
+ };
248
+ case 'ImageRequest':
249
+ return {
250
+ type: 'ReservedPropTypeAnnotation',
251
+ name: 'ImageRequestPrimitive',
252
+ };
253
+ case 'ColorValue':
254
+ case 'ProcessedColorValue':
255
+ return {
256
+ type: 'ReservedPropTypeAnnotation',
257
+ name: 'ColorPrimitive',
258
+ };
259
+ case 'ColorArrayValue':
260
+ return {
261
+ type: 'ArrayTypeAnnotation',
262
+ elementType: {
263
+ type: 'ReservedPropTypeAnnotation',
264
+ name: 'ColorPrimitive',
265
+ },
266
+ };
267
+ case 'PointValue':
268
+ return {
269
+ type: 'ReservedPropTypeAnnotation',
270
+ name: 'PointPrimitive',
271
+ };
272
+ case 'EdgeInsetsValue':
273
+ return {
274
+ type: 'ReservedPropTypeAnnotation',
275
+ name: 'EdgeInsetsPrimitive',
276
+ };
277
+ case 'Int32':
278
+ return {
279
+ type: 'Int32TypeAnnotation',
280
+ default: defaultValue ? defaultValue : 0,
281
+ };
282
+ case 'Double':
283
+ return {
284
+ type: 'DoubleTypeAnnotation',
285
+ default: defaultValue ? defaultValue : 0,
286
+ };
287
+ case 'Float':
288
+ return {
289
+ type: 'FloatTypeAnnotation',
290
+ default: withNullDefault
291
+ ? defaultValue
292
+ : defaultValue
293
+ ? defaultValue
294
+ : 0,
295
+ };
296
+ case 'BooleanTypeAnnotation':
297
+ return {
298
+ type: 'BooleanTypeAnnotation',
299
+ default: withNullDefault
300
+ ? defaultValue
301
+ : defaultValue == null
302
+ ? false
303
+ : defaultValue,
304
+ };
305
+ case 'StringTypeAnnotation':
306
+ if (typeof defaultValue !== 'undefined') {
307
+ return {
308
+ type: 'StringTypeAnnotation',
309
+ default: defaultValue,
310
+ };
311
+ }
312
+ throw new Error(`A default string (or null) is required for "${name}"`);
313
+ case 'Stringish':
314
+ if (typeof defaultValue !== 'undefined') {
315
+ return {
316
+ type: 'StringTypeAnnotation',
317
+ default: defaultValue,
318
+ };
319
+ }
320
+ throw new Error(`A default string (or null) is required for "${name}"`);
321
+ case 'UnionTypeAnnotation':
322
+ typeAnnotation.types.reduce((lastType, currType) => {
323
+ if (lastType && currType.type !== lastType.type) {
324
+ throw new Error(`Mixed types are not supported (see "${name}").`);
325
+ }
326
+ return currType;
327
+ });
328
+ if (defaultValue === null) {
329
+ throw new Error(`A default enum value is required for "${name}"`);
330
+ }
331
+ const unionType = typeAnnotation.types[0].type;
332
+ if (unionType === 'StringLiteralTypeAnnotation') {
333
+ return {
334
+ type: 'StringEnumTypeAnnotation',
335
+ default: defaultValue,
336
+ options: typeAnnotation.types.map(option => option.value),
337
+ };
338
+ } else if (unionType === 'NumberLiteralTypeAnnotation') {
339
+ return {
340
+ type: 'Int32EnumTypeAnnotation',
341
+ default: defaultValue,
342
+ options: typeAnnotation.types.map(option => option.value),
343
+ };
344
+ } else {
345
+ throw new Error(
346
+ `Unsupported union type for "${name}", received "${unionType}"`,
347
+ );
348
+ }
349
+ case 'ObjectTypeAnnotation':
350
+ throw new Error(
351
+ `Cannot use "${type}" type annotation for "${name}": object types must be declared using $ReadOnly<>`,
352
+ );
353
+ case 'NumberTypeAnnotation':
354
+ throw new Error(
355
+ `Cannot use "${type}" type annotation for "${name}": must use a specific numeric type like Int32, Double, or Float`,
356
+ );
357
+ default:
358
+ type;
359
+ throw new Error(
360
+ `Unknown property type for "${name}": "${type}" in the State`,
361
+ );
362
+ }
363
+ }
364
+ function getSchemaInfo(property, types) {
365
+ const name = property.key.name;
366
+ const value = getValueFromTypes(property.value, types);
367
+ let typeAnnotation =
368
+ value.type === 'NullableTypeAnnotation' ? value.typeAnnotation : value;
369
+ const optional =
370
+ value.type === 'NullableTypeAnnotation' ||
371
+ property.optional ||
372
+ (value.type === 'GenericTypeAnnotation' &&
373
+ typeAnnotation.id.name === 'WithDefault');
374
+ if (
375
+ !property.optional &&
376
+ value.type === 'GenericTypeAnnotation' &&
377
+ typeAnnotation.id.name === 'WithDefault'
378
+ ) {
379
+ throw new Error(
380
+ `key ${name} must be optional if used with WithDefault<> annotation`,
381
+ );
382
+ }
383
+ if (
384
+ value.type === 'NullableTypeAnnotation' &&
385
+ typeAnnotation.type === 'GenericTypeAnnotation' &&
386
+ typeAnnotation.id.name === 'WithDefault'
387
+ ) {
388
+ throw new Error(
389
+ 'WithDefault<> is optional and does not need to be marked as optional. Please remove the ? annotation in front of it.',
390
+ );
391
+ }
392
+ let type = typeAnnotation.type;
393
+ if (
394
+ type === 'GenericTypeAnnotation' &&
395
+ (typeAnnotation.id.name === 'DirectEventHandler' ||
396
+ typeAnnotation.id.name === 'BubblingEventHandler')
397
+ ) {
398
+ return null;
399
+ }
400
+ if (
401
+ name === 'style' &&
402
+ type === 'GenericTypeAnnotation' &&
403
+ typeAnnotation.id.name === 'ViewStyleProp'
404
+ ) {
405
+ return null;
406
+ }
407
+ let defaultValue = null;
408
+ let withNullDefault = false;
409
+ if (
410
+ type === 'GenericTypeAnnotation' &&
411
+ typeAnnotation.id.name === 'WithDefault'
412
+ ) {
413
+ if (typeAnnotation.typeParameters.params.length === 1) {
414
+ throw new Error(
415
+ `WithDefault requires two parameters, did you forget to provide a default value for "${name}"?`,
416
+ );
417
+ }
418
+ defaultValue = typeAnnotation.typeParameters.params[1].value;
419
+ const defaultValueType = typeAnnotation.typeParameters.params[1].type;
420
+ typeAnnotation = typeAnnotation.typeParameters.params[0];
421
+ type =
422
+ typeAnnotation.type === 'GenericTypeAnnotation'
423
+ ? typeAnnotation.id.name
424
+ : typeAnnotation.type;
425
+ if (defaultValueType === 'NullLiteralTypeAnnotation') {
426
+ defaultValue = null;
427
+ withNullDefault = true;
428
+ }
429
+ }
430
+ return {
431
+ name,
432
+ optional,
433
+ typeAnnotation,
434
+ defaultValue,
435
+ withNullDefault,
436
+ };
437
+ }
438
+
439
+ // $FlowFixMe[unclear-type] there's no flowtype for ASTs
440
+
441
+ module.exports = {
442
+ getProperties,
443
+ getSchemaInfo,
444
+ getTypeAnnotation,
445
+ flattenProperties,
446
+ };