@react-native/codegen 0.88.0-nightly-20260806-65008fcdd → 0.88.0-nightly-20260807-5fb3ebce1

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.
@@ -12,7 +12,8 @@ const {
12
12
  } = require('../Utils');
13
13
  const {
14
14
  createAliasResolver,
15
- getModules
15
+ getModules,
16
+ throwIfUnsupportedPromiseArrayBuffer
16
17
  } = require('./Utils');
17
18
  function FileTemplate(config) {
18
19
  const {
@@ -118,6 +119,7 @@ function translateEventEmitterTypeToJavaType(eventEmitter, imports) {
118
119
  case 'FloatTypeAnnotation':
119
120
  case 'Int32TypeAnnotation':
120
121
  case 'VoidTypeAnnotation':
122
+ case 'ArrayBufferTypeAnnotation':
121
123
  throw new Error(`Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`);
122
124
  default:
123
125
  typeAnnotation.type;
@@ -203,7 +205,8 @@ function translateFunctionParamToJavaType(param, createErrorMessage, resolveAlia
203
205
  imports.add('com.facebook.react.bridge.Callback');
204
206
  return wrapOptional('Callback', isRequired);
205
207
  case 'ArrayBufferTypeAnnotation':
206
- throw new Error(`${createErrorMessage(realTypeAnnotation.type)} ArrayBuffer is only supported for C++ TurboModules.`);
208
+ imports.add('java.nio.ByteBuffer');
209
+ return wrapOptional('ByteBuffer', isRequired);
207
210
  default:
208
211
  realTypeAnnotation.type;
209
212
  throw new Error(createErrorMessage(realTypeAnnotation.type));
@@ -285,7 +288,8 @@ function translateFunctionReturnTypeToJavaType(nullableReturnTypeAnnotation, cre
285
288
  imports.add('com.facebook.react.bridge.WritableArray');
286
289
  return wrapOptional('WritableArray', isRequired);
287
290
  case 'ArrayBufferTypeAnnotation':
288
- throw new Error(`${createErrorMessage(realTypeAnnotation.type)} ArrayBuffer is only supported for C++ TurboModules.`);
291
+ imports.add('java.nio.ByteBuffer');
292
+ return wrapOptional('ByteBuffer', isRequired);
289
293
  default:
290
294
  realTypeAnnotation.type;
291
295
  throw new Error(createErrorMessage(realTypeAnnotation.type));
@@ -359,7 +363,7 @@ function getFalsyReturnStatementFromReturnType(nullableReturnTypeAnnotation, cre
359
363
  case 'ArrayTypeAnnotation':
360
364
  return 'return null;';
361
365
  case 'ArrayBufferTypeAnnotation':
362
- throw new Error(`${createErrorMessage(realTypeAnnotation.type)} ArrayBuffer is only supported for C++ TurboModules.`);
366
+ return 'return null;';
363
367
  default:
364
368
  realTypeAnnotation.type;
365
369
  throw new Error(createErrorMessage(realTypeAnnotation.type));
@@ -447,6 +451,7 @@ module.exports = {
447
451
  return buildGetConstantsMethod(method, imports, resolveAlias);
448
452
  }
449
453
  const [methodTypeAnnotation] = unwrapNullable(method.typeAnnotation);
454
+ throwIfUnsupportedPromiseArrayBuffer(method.name, methodTypeAnnotation.returnTypeAnnotation);
450
455
  const translatedReturnType = translateFunctionReturnTypeToJavaType(methodTypeAnnotation.returnTypeAnnotation, typeName => `Unsupported return type for method ${method.name}. Found: ${typeName}`, resolveAlias, imports);
451
456
  const returningPromise = methodTypeAnnotation.returnTypeAnnotation.type === 'PromiseTypeAnnotation';
452
457
  const isSyncMethod = methodTypeAnnotation.returnTypeAnnotation.type !== 'VoidTypeAnnotation' && !returningPromise;
@@ -25,7 +25,11 @@ import type {AliasResolver} from './Utils';
25
25
  const {unwrapNullable} = require('../../parsers/parsers-commons');
26
26
  const {wrapOptional} = require('../TypeUtils/Java');
27
27
  const {parseValidUnionType, toPascalCase} = require('../Utils');
28
- const {createAliasResolver, getModules} = require('./Utils');
28
+ const {
29
+ createAliasResolver,
30
+ getModules,
31
+ throwIfUnsupportedPromiseArrayBuffer,
32
+ } = require('./Utils');
29
33
 
30
34
  type FilesOutput = Map<string, string>;
31
35
 
@@ -170,6 +174,7 @@ function translateEventEmitterTypeToJavaType(
170
174
  case 'FloatTypeAnnotation':
171
175
  case 'Int32TypeAnnotation':
172
176
  case 'VoidTypeAnnotation':
177
+ case 'ArrayBufferTypeAnnotation':
173
178
  // TODO: Add support for these types
174
179
  throw new Error(
175
180
  `Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`,
@@ -268,9 +273,8 @@ function translateFunctionParamToJavaType(
268
273
  imports.add('com.facebook.react.bridge.Callback');
269
274
  return wrapOptional('Callback', isRequired);
270
275
  case 'ArrayBufferTypeAnnotation':
271
- throw new Error(
272
- `${createErrorMessage(realTypeAnnotation.type)} ArrayBuffer is only supported for C++ TurboModules.`,
273
- );
276
+ imports.add('java.nio.ByteBuffer');
277
+ return wrapOptional('ByteBuffer', isRequired);
274
278
  default:
275
279
  realTypeAnnotation.type as 'MixedTypeAnnotation';
276
280
  throw new Error(createErrorMessage(realTypeAnnotation.type));
@@ -366,9 +370,8 @@ function translateFunctionReturnTypeToJavaType(
366
370
  imports.add('com.facebook.react.bridge.WritableArray');
367
371
  return wrapOptional('WritableArray', isRequired);
368
372
  case 'ArrayBufferTypeAnnotation':
369
- throw new Error(
370
- `${createErrorMessage(realTypeAnnotation.type)} ArrayBuffer is only supported for C++ TurboModules.`,
371
- );
373
+ imports.add('java.nio.ByteBuffer');
374
+ return wrapOptional('ByteBuffer', isRequired);
372
375
  default:
373
376
  realTypeAnnotation.type as 'MixedTypeAnnotation';
374
377
  throw new Error(createErrorMessage(realTypeAnnotation.type));
@@ -452,9 +455,7 @@ function getFalsyReturnStatementFromReturnType(
452
455
  case 'ArrayTypeAnnotation':
453
456
  return 'return null;';
454
457
  case 'ArrayBufferTypeAnnotation':
455
- throw new Error(
456
- `${createErrorMessage(realTypeAnnotation.type)} ArrayBuffer is only supported for C++ TurboModules.`,
457
- );
458
+ return 'return null;';
458
459
  default:
459
460
  realTypeAnnotation.type as 'MixedTypeAnnotation';
460
461
  throw new Error(createErrorMessage(realTypeAnnotation.type));
@@ -589,6 +590,11 @@ module.exports = {
589
590
  method.typeAnnotation,
590
591
  );
591
592
 
593
+ throwIfUnsupportedPromiseArrayBuffer(
594
+ method.name,
595
+ methodTypeAnnotation.returnTypeAnnotation,
596
+ );
597
+
592
598
  // Handle return type
593
599
  const translatedReturnType = translateFunctionReturnTypeToJavaType(
594
600
  methodTypeAnnotation.returnTypeAnnotation,
@@ -8,7 +8,8 @@ const {
8
8
  } = require('../Utils');
9
9
  const {
10
10
  createAliasResolver,
11
- getModules
11
+ getModules,
12
+ throwIfUnsupportedPromiseArrayBuffer
12
13
  } = require('./Utils');
13
14
  const HostFunctionTemplate = ({
14
15
  hasteModuleName,
@@ -147,7 +148,7 @@ function translateReturnTypeToKind(nullableTypeAnnotation, resolveAlias) {
147
148
  case 'ArrayTypeAnnotation':
148
149
  return 'ArrayKind';
149
150
  case 'ArrayBufferTypeAnnotation':
150
- throw new Error('ArrayBuffer is only supported for C++ TurboModules.');
151
+ return 'ArrayBufferKind';
151
152
  default:
152
153
  realTypeAnnotation.type;
153
154
  throw new Error(`Unknown prop type for returning value, found: ${realTypeAnnotation.type}"`);
@@ -224,7 +225,7 @@ function translateParamTypeToJniType(param, resolveAlias) {
224
225
  case 'FunctionTypeAnnotation':
225
226
  return 'Lcom/facebook/react/bridge/Callback;';
226
227
  case 'ArrayBufferTypeAnnotation':
227
- throw new Error('ArrayBuffer is only supported for C++ TurboModules.');
228
+ return 'Ljava/nio/ByteBuffer;';
228
229
  default:
229
230
  realTypeAnnotation.type;
230
231
  throw new Error(`Unknown prop type for method arg, found: ${realTypeAnnotation.type}"`);
@@ -298,7 +299,7 @@ function translateReturnTypeToJniType(nullableTypeAnnotation, resolveAlias) {
298
299
  case 'ArrayTypeAnnotation':
299
300
  return 'Lcom/facebook/react/bridge/WritableArray;';
300
301
  case 'ArrayBufferTypeAnnotation':
301
- throw new Error('ArrayBuffer is only supported for C++ TurboModules.');
302
+ return 'Ljava/nio/ByteBuffer;';
302
303
  default:
303
304
  realTypeAnnotation.type;
304
305
  throw new Error(`Unknown prop type for method return type, found: ${realTypeAnnotation.type}"`);
@@ -336,6 +337,7 @@ function translateMethodForImplementation(hasteModuleName, property, resolveAlia
336
337
  const {
337
338
  returnTypeAnnotation
338
339
  } = propertyTypeAnnotation;
340
+ throwIfUnsupportedPromiseArrayBuffer(property.name, returnTypeAnnotation);
339
341
  if (property.name === 'getConstants' && returnTypeAnnotation.type === 'ObjectTypeAnnotation' && returnTypeAnnotation.properties.length === 0) {
340
342
  return '';
341
343
  }
@@ -24,7 +24,11 @@ import type {AliasResolver} from './Utils';
24
24
 
25
25
  const {unwrapNullable} = require('../../parsers/parsers-commons');
26
26
  const {parseValidUnionType} = require('../Utils');
27
- const {createAliasResolver, getModules} = require('./Utils');
27
+ const {
28
+ createAliasResolver,
29
+ getModules,
30
+ throwIfUnsupportedPromiseArrayBuffer,
31
+ } = require('./Utils');
28
32
 
29
33
  type FilesOutput = Map<string, string>;
30
34
 
@@ -35,7 +39,8 @@ type JSReturnType =
35
39
  | 'NumberKind'
36
40
  | 'PromiseKind'
37
41
  | 'ObjectKind'
38
- | 'ArrayKind';
42
+ | 'ArrayKind'
43
+ | 'ArrayBufferKind';
39
44
 
40
45
  const HostFunctionTemplate = ({
41
46
  hasteModuleName,
@@ -217,7 +222,7 @@ function translateReturnTypeToKind(
217
222
  case 'ArrayTypeAnnotation':
218
223
  return 'ArrayKind';
219
224
  case 'ArrayBufferTypeAnnotation':
220
- throw new Error('ArrayBuffer is only supported for C++ TurboModules.');
225
+ return 'ArrayBufferKind';
221
226
  default:
222
227
  realTypeAnnotation.type as 'MixedTypeAnnotation';
223
228
  throw new Error(
@@ -306,7 +311,7 @@ function translateParamTypeToJniType(
306
311
  case 'FunctionTypeAnnotation':
307
312
  return 'Lcom/facebook/react/bridge/Callback;';
308
313
  case 'ArrayBufferTypeAnnotation':
309
- throw new Error('ArrayBuffer is only supported for C++ TurboModules.');
314
+ return 'Ljava/nio/ByteBuffer;';
310
315
  default:
311
316
  realTypeAnnotation.type as 'MixedTypeAnnotation';
312
317
  throw new Error(
@@ -392,7 +397,7 @@ function translateReturnTypeToJniType(
392
397
  case 'ArrayTypeAnnotation':
393
398
  return 'Lcom/facebook/react/bridge/WritableArray;';
394
399
  case 'ArrayBufferTypeAnnotation':
395
- throw new Error('ArrayBuffer is only supported for C++ TurboModules.');
400
+ return 'Ljava/nio/ByteBuffer;';
396
401
  default:
397
402
  realTypeAnnotation.type as 'MixedTypeAnnotation';
398
403
  throw new Error(
@@ -448,6 +453,8 @@ function translateMethodForImplementation(
448
453
  unwrapNullable<NativeModuleFunctionTypeAnnotation>(property.typeAnnotation);
449
454
  const {returnTypeAnnotation} = propertyTypeAnnotation;
450
455
 
456
+ throwIfUnsupportedPromiseArrayBuffer(property.name, returnTypeAnnotation);
457
+
451
458
  if (
452
459
  property.name === 'getConstants' &&
453
460
  returnTypeAnnotation.type === 'ObjectTypeAnnotation' &&
@@ -11,6 +11,9 @@ const {
11
11
  capitalize,
12
12
  parseValidUnionType
13
13
  } = require('../../Utils');
14
+ const {
15
+ throwIfUnsupportedPromiseArrayBuffer
16
+ } = require('../Utils');
14
17
  const {
15
18
  getNamespacedStructName
16
19
  } = require('./Utils');
@@ -51,6 +54,7 @@ function serializeMethod(hasteModuleName, property, structCollector, resolveAlia
51
54
  });
52
55
  }
53
56
  });
57
+ throwIfUnsupportedPromiseArrayBuffer(methodName, propertyTypeAnnotation.returnTypeAnnotation);
54
58
  const [returnTypeAnnotation] = unwrapNullable(propertyTypeAnnotation.returnTypeAnnotation);
55
59
  if (returnTypeAnnotation.type === 'PromiseTypeAnnotation') {
56
60
  methodParams.push({
@@ -26,6 +26,7 @@ const {
26
26
  } = require('../../../parsers/parsers-commons');
27
27
  const {wrapOptional} = require('../../TypeUtils/Objective-C');
28
28
  const {capitalize, parseValidUnionType} = require('../../Utils');
29
+ const {throwIfUnsupportedPromiseArrayBuffer} = require('../Utils');
29
30
  const {getNamespacedStructName} = require('./Utils');
30
31
  const invariant = require('invariant');
31
32
 
@@ -103,6 +104,11 @@ function serializeMethod(
103
104
  }
104
105
  });
105
106
 
107
+ throwIfUnsupportedPromiseArrayBuffer(
108
+ methodName,
109
+ propertyTypeAnnotation.returnTypeAnnotation,
110
+ );
111
+
106
112
  // Unwrap returnTypeAnnotation, so we check if the return type is Promise
107
113
  // TODO(T76719514): Disallow nullable PromiseTypeAnnotations
108
114
  const [returnTypeAnnotation] = unwrapNullable(
@@ -30,9 +30,23 @@ function isArrayRecursiveMember(parentObjectAliasName, nullableTypeAnnotation) {
30
30
  const [typeAnnotation] = unwrapNullable(nullableTypeAnnotation);
31
31
  return parentObjectAliasName !== undefined && typeAnnotation.type === 'ArrayTypeAnnotation' && ((_typeAnnotation$eleme = typeAnnotation.elementType) === null || _typeAnnotation$eleme === void 0 ? void 0 : _typeAnnotation$eleme.name) === parentObjectAliasName;
32
32
  }
33
+ function throwIfUnsupportedPromiseArrayBuffer(methodName, nullableReturnTypeAnnotation) {
34
+ const [returnTypeAnnotation] = unwrapNullable(nullableReturnTypeAnnotation);
35
+ if (returnTypeAnnotation.type !== 'PromiseTypeAnnotation') {
36
+ return;
37
+ }
38
+ let elementType = returnTypeAnnotation.elementType;
39
+ if (elementType.type === 'NullableTypeAnnotation') {
40
+ elementType = elementType.typeAnnotation;
41
+ }
42
+ if (elementType.type === 'ArrayBufferTypeAnnotation') {
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
+ }
45
+ }
33
46
  module.exports = {
34
47
  createAliasResolver,
35
48
  getModules,
36
49
  isDirectRecursiveMember,
37
- isArrayRecursiveMember
50
+ isArrayRecursiveMember,
51
+ throwIfUnsupportedPromiseArrayBuffer
38
52
  };
@@ -13,6 +13,7 @@
13
13
  import type {
14
14
  NativeModuleAliasMap,
15
15
  NativeModuleObjectTypeAnnotation,
16
+ NativeModuleReturnTypeAnnotation,
16
17
  NativeModuleSchema,
17
18
  NativeModuleTypeAnnotation,
18
19
  Nullable,
@@ -77,9 +78,50 @@ function isArrayRecursiveMember(
77
78
  );
78
79
  }
79
80
 
81
+ // Platform-native (Java/Kotlin and ObjC) TurboModules copy ArrayBuffer
82
+ // arguments and return ArrayBuffers zero-copy from synchronous methods, but
83
+ // `Promise<ArrayBuffer>` is not part of their contract.
84
+ //
85
+ // On Android it cannot work: the resolve path serializes through
86
+ // folly::dynamic, which cannot carry raw bytes. On iOS the resolve path is a
87
+ // direct ObjC->jsi conversion that would in fact produce an ArrayBuffer for an
88
+ // NSMutableData, so the limitation there is not technical — the guard is
89
+ // applied to ObjC as well to keep one cross-platform contract, so a spec that
90
+ // compiles for iOS cannot fail to build for Android.
91
+ //
92
+ // Reject `Promise<ArrayBuffer>` at codegen time for both native platforms so
93
+ // the unsupported case surfaces as a build error rather than a runtime failure
94
+ // or a silent iOS/Android divergence.
95
+ function throwIfUnsupportedPromiseArrayBuffer(
96
+ methodName: string,
97
+ nullableReturnTypeAnnotation: Nullable<NativeModuleReturnTypeAnnotation>,
98
+ ): void {
99
+ const [returnTypeAnnotation] =
100
+ unwrapNullable<NativeModuleReturnTypeAnnotation>(
101
+ nullableReturnTypeAnnotation,
102
+ );
103
+ if (returnTypeAnnotation.type !== 'PromiseTypeAnnotation') {
104
+ return;
105
+ }
106
+ let elementType = returnTypeAnnotation.elementType;
107
+ if (elementType.type === 'NullableTypeAnnotation') {
108
+ elementType = elementType.typeAnnotation;
109
+ }
110
+ if (elementType.type === 'ArrayBufferTypeAnnotation') {
111
+ throw new Error(
112
+ `Unsupported return type for method "${methodName}": Promise<ArrayBuffer> is not ` +
113
+ 'supported for Android (Java/Kotlin) or iOS (ObjC) TurboModules. Use a C++ ' +
114
+ '(Cxx) TurboModule, return the ArrayBuffer from a synchronous method, or resolve ' +
115
+ 'the Promise with a different type. ArrayBuffer is still supported as a method ' +
116
+ 'argument and as a synchronous return value on all platforms.',
117
+ );
118
+ }
119
+ }
120
+
80
121
  module.exports = {
81
122
  createAliasResolver,
82
123
  getModules,
83
124
  isDirectRecursiveMember,
84
125
  isArrayRecursiveMember,
126
+ throwIfUnsupportedPromiseArrayBuffer,
85
127
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native/codegen",
3
- "version": "0.88.0-nightly-20260806-65008fcdd",
3
+ "version": "0.88.0-nightly-20260807-5fb3ebce1",
4
4
  "description": "Code generation tools for React Native",
5
5
  "license": "MIT",
6
6
  "repository": {