@react-native/codegen 0.88.0-nightly-20260824-0c7f63a4e → 0.88.0-nightly-20260826-ea06a3191

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.
@@ -68,7 +68,7 @@ function getJavaValueForProp(prop, componentName) {
68
68
  return `value == null ? ${typeAnnotation.default} : ((Double) value).intValue()`;
69
69
  case 'DoubleTypeAnnotation':
70
70
  if (prop.optional) {
71
- return `value == null ? ${typeAnnotation.default}f : ((Double) value).doubleValue()`;
71
+ return `value == null ? ${typeAnnotation.default}d : ((Double) value).doubleValue()`;
72
72
  } else {
73
73
  return 'value == null ? Double.NaN : ((Double) value).doubleValue()';
74
74
  }
@@ -105,7 +105,9 @@ function getJavaValueForProp(
105
105
  return `value == null ? ${typeAnnotation.default} : ((Double) value).intValue()`;
106
106
  case 'DoubleTypeAnnotation':
107
107
  if (prop.optional) {
108
- return `value == null ? ${typeAnnotation.default}f : ((Double) value).doubleValue()`;
108
+ // The setter takes a `double`, so the default must be a double literal.
109
+ // A `f` suffix here would silently round the default to float precision.
110
+ return `value == null ? ${typeAnnotation.default}d : ((Double) value).doubleValue()`;
109
111
  } else {
110
112
  return 'value == null ? Double.NaN : ((Double) value).doubleValue()';
111
113
  }
@@ -16,7 +16,8 @@ const {
16
16
  createAliasResolver,
17
17
  getModules,
18
18
  isArrayRecursiveMember,
19
- isDirectRecursiveMember
19
+ isDirectRecursiveMember,
20
+ throwIfUnsupportedEventEmitterPayload
20
21
  } = require('./Utils');
21
22
  function serializeArg(moduleName, arg, index, resolveAlias, enumMap) {
22
23
  const {
@@ -410,6 +411,7 @@ function translateFunctionToCpp(hasteModuleName, prop, resolveAlias, enumMap, ar
410
411
  ${!isVoid ? !isNullable ? 'return ' : 'auto result = ' : ''}bridging::callFromJs<${returnType}>(rt, &T::${prop.name}, static_cast<${hasteModuleName}CxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule)${methodCallArgs});${!isVoid ? !isNullable ? '' : 'return result ? jsi::Value(std::move(*result)) : jsi::Value::null();' : 'return jsi::Value::undefined();'}\n }`;
411
412
  }
412
413
  function translateEventEmitterToCpp(moduleName, eventEmitter, resolveAlias, enumMap) {
414
+ throwIfUnsupportedEventEmitterPayload(eventEmitter.name, eventEmitter.typeAnnotation.typeAnnotation);
413
415
  const isVoidTypeAnnotation = eventEmitter.typeAnnotation.typeAnnotation.type === 'VoidTypeAnnotation';
414
416
  const templateName = `${toPascalCase(eventEmitter.name)}Type`;
415
417
  const jsiType = translatePrimitiveJSTypeToCpp(moduleName, null, eventEmitter.typeAnnotation.typeAnnotation, false, typeName => `Unsupported type for eventEmitter "${eventEmitter.name}" in ${moduleName}. Found: ${typeName}`, resolveAlias, enumMap);
@@ -40,6 +40,7 @@ const {
40
40
  getModules,
41
41
  isArrayRecursiveMember,
42
42
  isDirectRecursiveMember,
43
+ throwIfUnsupportedEventEmitterPayload,
43
44
  } = require('./Utils');
44
45
 
45
46
  type FilesOutput = Map<string, string>;
@@ -638,6 +639,11 @@ function translateEventEmitterToCpp(
638
639
  resolveAlias: AliasResolver,
639
640
  enumMap: NativeModuleEnumMap,
640
641
  ): EventEmitterCpp {
642
+ throwIfUnsupportedEventEmitterPayload(
643
+ eventEmitter.name,
644
+ eventEmitter.typeAnnotation.typeAnnotation,
645
+ );
646
+
641
647
  const isVoidTypeAnnotation =
642
648
  eventEmitter.typeAnnotation.typeAnnotation.type === 'VoidTypeAnnotation';
643
649
  const templateName = `${toPascalCase(eventEmitter.name)}Type`;
@@ -13,6 +13,7 @@ const {
13
13
  const {
14
14
  createAliasResolver,
15
15
  getModules,
16
+ throwIfUnsupportedEventEmitterPayload,
16
17
  throwIfUnsupportedPromiseArrayBuffer
17
18
  } = require('./Utils');
18
19
  function FileTemplate(config) {
@@ -81,6 +82,7 @@ function MethodTemplate(config) {
81
82
  }
82
83
  function translateEventEmitterTypeToJavaType(eventEmitter, imports) {
83
84
  const typeAnnotation = eventEmitter.typeAnnotation.typeAnnotation;
85
+ throwIfUnsupportedEventEmitterPayload(eventEmitter.name, typeAnnotation);
84
86
  switch (typeAnnotation.type) {
85
87
  case 'StringTypeAnnotation':
86
88
  return 'String';
@@ -119,11 +121,7 @@ function translateEventEmitterTypeToJavaType(eventEmitter, imports) {
119
121
  case 'ArrayTypeAnnotation':
120
122
  imports.add('com.facebook.react.bridge.ReadableArray');
121
123
  return 'ReadableArray';
122
- case 'DoubleTypeAnnotation':
123
- case 'FloatTypeAnnotation':
124
- case 'Int32TypeAnnotation':
125
124
  case 'VoidTypeAnnotation':
126
- case 'ArrayBufferTypeAnnotation':
127
125
  throw new Error(`Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`);
128
126
  default:
129
127
  typeAnnotation.type;
@@ -28,6 +28,7 @@ const {parseValidUnionType, toPascalCase} = require('../Utils');
28
28
  const {
29
29
  createAliasResolver,
30
30
  getModules,
31
+ throwIfUnsupportedEventEmitterPayload,
31
32
  throwIfUnsupportedPromiseArrayBuffer,
32
33
  } = require('./Utils');
33
34
 
@@ -141,6 +142,9 @@ function translateEventEmitterTypeToJavaType(
141
142
  imports: Set<string>,
142
143
  ): string {
143
144
  const typeAnnotation = eventEmitter.typeAnnotation.typeAnnotation;
145
+
146
+ throwIfUnsupportedEventEmitterPayload(eventEmitter.name, typeAnnotation);
147
+
144
148
  switch (typeAnnotation.type) {
145
149
  case 'StringTypeAnnotation':
146
150
  return 'String';
@@ -179,12 +183,8 @@ function translateEventEmitterTypeToJavaType(
179
183
  case 'ArrayTypeAnnotation':
180
184
  imports.add('com.facebook.react.bridge.ReadableArray');
181
185
  return 'ReadableArray';
182
- case 'DoubleTypeAnnotation':
183
- case 'FloatTypeAnnotation':
184
- case 'Int32TypeAnnotation':
185
186
  case 'VoidTypeAnnotation':
186
- case 'ArrayBufferTypeAnnotation':
187
- // TODO: Add support for these types
187
+ // Void emitters take no argument, so the caller never asks for a type.
188
188
  throw new Error(
189
189
  `Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`,
190
190
  );
@@ -2,8 +2,12 @@ const {
2
2
  parseValidUnionType,
3
3
  toPascalCase
4
4
  } = require('../../Utils');
5
+ const {
6
+ throwIfUnsupportedEventEmitterPayload
7
+ } = require('../Utils');
5
8
  function getEventEmitterTypeObjCType(eventEmitter) {
6
9
  const typeAnnotation = eventEmitter.typeAnnotation.typeAnnotation;
10
+ throwIfUnsupportedEventEmitterPayload(eventEmitter.name, typeAnnotation);
7
11
  switch (typeAnnotation.type) {
8
12
  case 'StringTypeAnnotation':
9
13
  return 'NSString *_Nonnull';
@@ -26,6 +30,9 @@ function getEventEmitterTypeObjCType(eventEmitter) {
26
30
  }
27
31
  case 'NumberTypeAnnotation':
28
32
  case 'NumberLiteralTypeAnnotation':
33
+ case 'DoubleTypeAnnotation':
34
+ case 'FloatTypeAnnotation':
35
+ case 'Int32TypeAnnotation':
29
36
  return 'NSNumber *_Nonnull';
30
37
  case 'BooleanTypeAnnotation':
31
38
  case 'BooleanLiteralTypeAnnotation':
@@ -36,9 +43,6 @@ function getEventEmitterTypeObjCType(eventEmitter) {
36
43
  return 'NSDictionary *';
37
44
  case 'ArrayTypeAnnotation':
38
45
  return 'NSArray<id<NSObject>> *';
39
- case 'DoubleTypeAnnotation':
40
- case 'FloatTypeAnnotation':
41
- case 'Int32TypeAnnotation':
42
46
  case 'VoidTypeAnnotation':
43
47
  throw new Error(`Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`);
44
48
  default:
@@ -11,12 +11,15 @@
11
11
  import type {NativeModuleEventEmitterShape} from '../../../CodegenSchema';
12
12
 
13
13
  const {parseValidUnionType, toPascalCase} = require('../../Utils');
14
+ const {throwIfUnsupportedEventEmitterPayload} = require('../Utils');
14
15
 
15
16
  function getEventEmitterTypeObjCType(
16
17
  eventEmitter: NativeModuleEventEmitterShape,
17
18
  ): string {
18
19
  const typeAnnotation = eventEmitter.typeAnnotation.typeAnnotation;
19
20
 
21
+ throwIfUnsupportedEventEmitterPayload(eventEmitter.name, typeAnnotation);
22
+
20
23
  switch (typeAnnotation.type) {
21
24
  case 'StringTypeAnnotation':
22
25
  return 'NSString *_Nonnull';
@@ -39,6 +42,9 @@ function getEventEmitterTypeObjCType(
39
42
  }
40
43
  case 'NumberTypeAnnotation':
41
44
  case 'NumberLiteralTypeAnnotation':
45
+ case 'DoubleTypeAnnotation':
46
+ case 'FloatTypeAnnotation':
47
+ case 'Int32TypeAnnotation':
42
48
  return 'NSNumber *_Nonnull';
43
49
  case 'BooleanTypeAnnotation':
44
50
  case 'BooleanLiteralTypeAnnotation':
@@ -49,11 +55,8 @@ function getEventEmitterTypeObjCType(
49
55
  return 'NSDictionary *';
50
56
  case 'ArrayTypeAnnotation':
51
57
  return 'NSArray<id<NSObject>> *';
52
- case 'DoubleTypeAnnotation':
53
- case 'FloatTypeAnnotation':
54
- case 'Int32TypeAnnotation':
55
58
  case 'VoidTypeAnnotation':
56
- // TODO: Add support for these types
59
+ // Void emitters take no argument, so both callers skip this function.
57
60
  throw new Error(
58
61
  `Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`,
59
62
  );
@@ -43,10 +43,16 @@ function throwIfUnsupportedPromiseArrayBuffer(methodName, nullableReturnTypeAnno
43
43
  throw new Error(`Unsupported return type for method "${methodName}": Promise<ArrayBuffer> is not ` + 'supported for Android (Java/Kotlin) or iOS (ObjC) TurboModules. Use a C++ ' + '(Cxx) TurboModule, return the ArrayBuffer from a synchronous method, or resolve ' + 'the Promise with a different type. ArrayBuffer is still supported as a method ' + 'argument and as a synchronous return value on all platforms.');
44
44
  }
45
45
  }
46
+ function throwIfUnsupportedEventEmitterPayload(eventEmitterName, typeAnnotation) {
47
+ if (typeAnnotation.type === 'ArrayBufferTypeAnnotation') {
48
+ throw new Error(`Unsupported eventType for ${eventEmitterName}. Found: ${typeAnnotation.type}. ` + 'ArrayBuffer is not supported as an EventEmitter payload on any platform. ' + 'Pass the ArrayBuffer through a method instead.');
49
+ }
50
+ }
46
51
  module.exports = {
47
52
  createAliasResolver,
48
53
  getModules,
49
54
  isDirectRecursiveMember,
50
55
  isArrayRecursiveMember,
56
+ throwIfUnsupportedEventEmitterPayload,
51
57
  throwIfUnsupportedPromiseArrayBuffer
52
58
  };
@@ -118,10 +118,29 @@ function throwIfUnsupportedPromiseArrayBuffer(
118
118
  }
119
119
  }
120
120
 
121
+ // ArrayBuffer is not emittable on any platform: Android emitters always carry a
122
+ // folly::dynamic payload, which cannot hold raw bytes, and neither the ObjC nor
123
+ // the C++ emitter contract can hand out a buffer that outlives the emit call.
124
+ // The parser rejects this too; the guard here also covers schemas built without
125
+ // going through the parser.
126
+ function throwIfUnsupportedEventEmitterPayload(
127
+ eventEmitterName: string,
128
+ typeAnnotation: NativeModuleTypeAnnotation,
129
+ ): void {
130
+ if (typeAnnotation.type === 'ArrayBufferTypeAnnotation') {
131
+ throw new Error(
132
+ `Unsupported eventType for ${eventEmitterName}. Found: ${typeAnnotation.type}. ` +
133
+ 'ArrayBuffer is not supported as an EventEmitter payload on any platform. ' +
134
+ 'Pass the ArrayBuffer through a method instead.',
135
+ );
136
+ }
137
+ }
138
+
121
139
  module.exports = {
122
140
  createAliasResolver,
123
141
  getModules,
124
142
  isDirectRecursiveMember,
125
143
  isArrayRecursiveMember,
144
+ throwIfUnsupportedEventEmitterPayload,
126
145
  throwIfUnsupportedPromiseArrayBuffer,
127
146
  };
@@ -12,6 +12,7 @@ const {
12
12
  UnsupportedArrayElementTypeAnnotationParserError,
13
13
  UnsupportedFunctionParamTypeAnnotationParserError,
14
14
  UnsupportedFunctionReturnTypeAnnotationParserError,
15
+ UnsupportedModuleEventEmitterPayloadTypeParserError,
15
16
  UnsupportedModuleEventEmitterPropertyParserError,
16
17
  UnsupportedModuleEventEmitterTypePropertyParserError,
17
18
  UnsupportedModulePropertyParserError,
@@ -72,6 +73,11 @@ function throwIfEventEmitterEventTypeIsUnsupported(nativeModuleName, propertyNam
72
73
  throw new UnsupportedModuleEventEmitterTypePropertyParserError(nativeModuleName, propertyName, propertyValueType, parser.language(), nullable);
73
74
  }
74
75
  }
76
+ function throwIfEventEmitterPayloadTypeIsUnsupported(nativeModuleName, propertyValue, propertyName, payloadTypeAnnotation) {
77
+ if (payloadTypeAnnotation.type === 'ArrayBufferTypeAnnotation') {
78
+ throw new UnsupportedModuleEventEmitterPayloadTypeParserError(nativeModuleName, propertyValue, propertyName, 'ArrayBuffer');
79
+ }
80
+ }
75
81
  function throwIfModuleTypeIsUnsupported(nativeModuleName, propertyValue, propertyName, propertyValueType, parser) {
76
82
  if (!parser.functionTypeAnnotation(propertyValueType)) {
77
83
  throw new UnsupportedModulePropertyParserError(nativeModuleName, propertyValue, propertyName, propertyValueType, parser.language());
@@ -179,6 +185,7 @@ module.exports = {
179
185
  throwIfUntypedModule,
180
186
  throwIfEventEmitterTypeIsUnsupported,
181
187
  throwIfEventEmitterEventTypeIsUnsupported,
188
+ throwIfEventEmitterPayloadTypeIsUnsupported,
182
189
  throwIfModuleTypeIsUnsupported,
183
190
  throwIfMoreThanOneModuleInterfaceParserError,
184
191
  throwIfUnsupportedFunctionParamTypeAnnotationParserError,
@@ -27,6 +27,7 @@ const {
27
27
  UnsupportedArrayElementTypeAnnotationParserError,
28
28
  UnsupportedFunctionParamTypeAnnotationParserError,
29
29
  UnsupportedFunctionReturnTypeAnnotationParserError,
30
+ UnsupportedModuleEventEmitterPayloadTypeParserError,
30
31
  UnsupportedModuleEventEmitterPropertyParserError,
31
32
  UnsupportedModuleEventEmitterTypePropertyParserError,
32
33
  UnsupportedModulePropertyParserError,
@@ -196,6 +197,25 @@ function throwIfEventEmitterEventTypeIsUnsupported(
196
197
  }
197
198
  }
198
199
 
200
+ // ArrayBuffer is not emittable on any platform: Android emitters always carry a
201
+ // folly::dynamic payload, which cannot hold raw bytes, and neither the ObjC nor
202
+ // the C++ emitter contract can hand out a buffer that outlives the emit call.
203
+ function throwIfEventEmitterPayloadTypeIsUnsupported(
204
+ nativeModuleName: string,
205
+ propertyValue: $FlowFixMe,
206
+ propertyName: string,
207
+ payloadTypeAnnotation: NativeModuleTypeAnnotation,
208
+ ) {
209
+ if (payloadTypeAnnotation.type === 'ArrayBufferTypeAnnotation') {
210
+ throw new UnsupportedModuleEventEmitterPayloadTypeParserError(
211
+ nativeModuleName,
212
+ propertyValue,
213
+ propertyName,
214
+ 'ArrayBuffer',
215
+ );
216
+ }
217
+ }
218
+
199
219
  function throwIfModuleTypeIsUnsupported(
200
220
  nativeModuleName: string,
201
221
  propertyValue: $FlowFixMe,
@@ -418,6 +438,7 @@ module.exports = {
418
438
  throwIfUntypedModule,
419
439
  throwIfEventEmitterTypeIsUnsupported,
420
440
  throwIfEventEmitterEventTypeIsUnsupported,
441
+ throwIfEventEmitterPayloadTypeIsUnsupported,
421
442
  throwIfModuleTypeIsUnsupported,
422
443
  throwIfMoreThanOneModuleInterfaceParserError,
423
444
  throwIfUnsupportedFunctionParamTypeAnnotationParserError,
@@ -43,6 +43,11 @@ class UnsupportedModuleEventEmitterPropertyParserError extends ParserError {
43
43
  super(nativeModuleName, propertyValue, message);
44
44
  }
45
45
  }
46
+ class UnsupportedModuleEventEmitterPayloadTypeParserError extends ParserError {
47
+ constructor(nativeModuleName, propertyValue, propertyName, payloadType) {
48
+ super(nativeModuleName, propertyValue, `EventEmitter '${propertyName}' cannot have payload type '${payloadType}'.`);
49
+ }
50
+ }
46
51
  class UnsupportedModulePropertyParserError extends ParserError {
47
52
  constructor(nativeModuleName, propertyValue, propertyName, invalidPropertyValueType, language) {
48
53
  super(nativeModuleName, propertyValue, `${language} interfaces extending TurboModule must only contain 'FunctionTypeAnnotation's or non nullable 'EventEmitter's. Property '${propertyName}' refers to a '${invalidPropertyValueType}'.`);
@@ -174,6 +179,7 @@ module.exports = {
174
179
  UnsupportedEnumDeclarationParserError,
175
180
  UnsupportedModuleEventEmitterTypePropertyParserError,
176
181
  UnsupportedModuleEventEmitterPropertyParserError,
182
+ UnsupportedModuleEventEmitterPayloadTypeParserError,
177
183
  UnsupportedModulePropertyParserError,
178
184
  UnsupportedObjectPropertyTypeAnnotationParserError,
179
185
  UnsupportedObjectPropertyWithIndexerTypeAnnotationParserError,
@@ -111,6 +111,21 @@ class UnsupportedModuleEventEmitterPropertyParserError extends ParserError {
111
111
  }
112
112
  }
113
113
 
114
+ class UnsupportedModuleEventEmitterPayloadTypeParserError extends ParserError {
115
+ constructor(
116
+ nativeModuleName: string,
117
+ propertyValue: $FlowFixMe,
118
+ propertyName: string,
119
+ payloadType: string,
120
+ ) {
121
+ super(
122
+ nativeModuleName,
123
+ propertyValue,
124
+ `EventEmitter '${propertyName}' cannot have payload type '${payloadType}'.`,
125
+ );
126
+ }
127
+ }
128
+
114
129
  class UnsupportedModulePropertyParserError extends ParserError {
115
130
  constructor(
116
131
  nativeModuleName: string,
@@ -456,6 +471,7 @@ module.exports = {
456
471
  UnsupportedEnumDeclarationParserError,
457
472
  UnsupportedModuleEventEmitterTypePropertyParserError,
458
473
  UnsupportedModuleEventEmitterPropertyParserError,
474
+ UnsupportedModuleEventEmitterPayloadTypeParserError,
459
475
  UnsupportedModulePropertyParserError,
460
476
  UnsupportedObjectPropertyTypeAnnotationParserError,
461
477
  UnsupportedObjectPropertyWithIndexerTypeAnnotationParserError,
@@ -3,6 +3,7 @@
3
3
  const {
4
4
  throwIfConfigNotfound,
5
5
  throwIfEventEmitterEventTypeIsUnsupported,
6
+ throwIfEventEmitterPayloadTypeIsUnsupported,
6
7
  throwIfEventEmitterTypeIsUnsupported,
7
8
  throwIfIncorrectModuleRegistryCallArgument,
8
9
  throwIfIncorrectModuleRegistryCallTypeParameterParserError,
@@ -203,6 +204,7 @@ function buildEventEmitterSchema(hasteModuleName, property, types, aliasMap, enu
203
204
  const eventTypeResolutionStatus = resolveTypeAnnotationFN(typeAnnotation.typeParameters.params[0], types, parser);
204
205
  throwIfEventEmitterEventTypeIsUnsupported(hasteModuleName, key.name, eventTypeResolutionStatus.typeAnnotation, parser, eventTypeResolutionStatus.nullable);
205
206
  const eventTypeAnnotation = translateTypeAnnotation(hasteModuleName, typeAnnotation.typeParameters.params[0], types, aliasMap, enumMap, tryParse, cxxOnly, parser);
207
+ throwIfEventEmitterPayloadTypeIsUnsupported(hasteModuleName, typeAnnotation.typeParameters.params[0], key.name, eventTypeAnnotation);
206
208
  return {
207
209
  name: eventemitterName,
208
210
  optional: Boolean(property.optional),
@@ -42,6 +42,7 @@ import type {
42
42
  const {
43
43
  throwIfConfigNotfound,
44
44
  throwIfEventEmitterEventTypeIsUnsupported,
45
+ throwIfEventEmitterPayloadTypeIsUnsupported,
45
46
  throwIfEventEmitterTypeIsUnsupported,
46
47
  throwIfIncorrectModuleRegistryCallArgument,
47
48
  throwIfIncorrectModuleRegistryCallTypeParameterParserError,
@@ -551,6 +552,13 @@ function buildEventEmitterSchema(
551
552
  parser,
552
553
  );
553
554
 
555
+ throwIfEventEmitterPayloadTypeIsUnsupported(
556
+ hasteModuleName,
557
+ typeAnnotation.typeParameters.params[0],
558
+ key.name,
559
+ eventTypeAnnotation,
560
+ );
561
+
554
562
  return {
555
563
  name: eventemitterName,
556
564
  optional: Boolean(property.optional),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native/codegen",
3
- "version": "0.88.0-nightly-20260824-0c7f63a4e",
3
+ "version": "0.88.0-nightly-20260826-ea06a3191",
4
4
  "description": "Code generation tools for React Native",
5
5
  "license": "MIT",
6
6
  "repository": {