@react-native/compatibility-check 0.84.0-nightly-20251204-5bb3a6d68 → 0.84.0-nightly-20251205-95cc1e767

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.
@@ -77,6 +77,11 @@ export type MembersComparisonResult = {
77
77
  missingMembers?: Array<NativeModuleEnumMember>;
78
78
  errorMembers?: Array<{ member: string; fault?: TypeComparisonError }>;
79
79
  };
80
+ export type UnionMembersComparisonResult = {
81
+ addedMembers?: Array<CompleteTypeAnnotation>;
82
+ missingMembers?: Array<CompleteTypeAnnotation>;
83
+ errorMembers?: Array<{ member: string; fault?: TypeComparisonError }>;
84
+ };
80
85
  export type NullableComparisonResult = {
81
86
  typeRefined: boolean;
82
87
  optionsReduced: boolean;
@@ -90,6 +95,7 @@ export type ComparisonResult =
90
95
  | { status: "nullableChange"; nullableLog: NullableComparisonResult }
91
96
  | { status: "properties"; propertyLog: PropertiesComparisonResult }
92
97
  | { status: "members"; memberLog: MembersComparisonResult }
98
+ | { status: "unionMembers"; memberLog: UnionMembersComparisonResult }
93
99
  | { status: "functionChange"; functionChangeLog: FunctionComparisonResult }
94
100
  | { status: "positionalTypeChange"; changeLog: PositionalComparisonResult }
95
101
  | { status: "error"; errorLog: TypeComparisonError };
@@ -99,6 +105,9 @@ export declare function isPropertyLogEmpty(
99
105
  export declare function isMemberLogEmpty(
100
106
  result: MembersComparisonResult,
101
107
  ): boolean;
108
+ export declare function isUnionMemberLogEmpty(
109
+ result: UnionMembersComparisonResult,
110
+ ): boolean;
102
111
  export declare function isFunctionLogEmpty(
103
112
  result: FunctionComparisonResult,
104
113
  ): boolean;
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.isFunctionLogEmpty = isFunctionLogEmpty;
7
7
  exports.isMemberLogEmpty = isMemberLogEmpty;
8
8
  exports.isPropertyLogEmpty = isPropertyLogEmpty;
9
+ exports.isUnionMemberLogEmpty = isUnionMemberLogEmpty;
9
10
  exports.makeError = makeError;
10
11
  exports.memberComparisonError = memberComparisonError;
11
12
  exports.positionalComparisonError = positionalComparisonError;
@@ -25,6 +26,9 @@ function isPropertyLogEmpty(result) {
25
26
  function isMemberLogEmpty(result) {
26
27
  return !(result.addedMembers || result.missingMembers || result.errorMembers);
27
28
  }
29
+ function isUnionMemberLogEmpty(result) {
30
+ return !(result.addedMembers || result.missingMembers || result.errorMembers);
31
+ }
28
32
  function isFunctionLogEmpty(result) {
29
33
  return !(result.returnType || result.parameterTypes);
30
34
  }
@@ -109,6 +109,14 @@ export type MembersComparisonResult = {
109
109
  fault?: TypeComparisonError,
110
110
  }>,
111
111
  };
112
+ export type UnionMembersComparisonResult = {
113
+ addedMembers?: Array<CompleteTypeAnnotation>,
114
+ missingMembers?: Array<CompleteTypeAnnotation>,
115
+ errorMembers?: Array<{
116
+ member: string,
117
+ fault?: TypeComparisonError,
118
+ }>,
119
+ };
112
120
  export type NullableComparisonResult = {
113
121
  /* Four possible cases of change:
114
122
  void goes to T? :: typeRefined !optionsReduced
@@ -130,6 +138,7 @@ export type ComparisonResult =
130
138
  | { status: "nullableChange", nullableLog: NullableComparisonResult }
131
139
  | { status: "properties", propertyLog: PropertiesComparisonResult }
132
140
  | { status: "members", memberLog: MembersComparisonResult }
141
+ | { status: "unionMembers", memberLog: UnionMembersComparisonResult }
133
142
  | { status: "functionChange", functionChangeLog: FunctionComparisonResult }
134
143
  | { status: "positionalTypeChange", changeLog: PositionalComparisonResult }
135
144
  | { status: "error", errorLog: TypeComparisonError };
@@ -142,6 +151,10 @@ declare export function isMemberLogEmpty(
142
151
  result: MembersComparisonResult,
143
152
  ): boolean;
144
153
 
154
+ declare export function isUnionMemberLogEmpty(
155
+ result: UnionMembersComparisonResult,
156
+ ): boolean;
157
+
145
158
  declare export function isFunctionLogEmpty(
146
159
  result: FunctionComparisonResult,
147
160
  ): boolean;
@@ -7,6 +7,7 @@ exports.formatDiffSet = formatDiffSet;
7
7
  exports.formatErrorMessage = formatErrorMessage;
8
8
  exports.formatErrorStore = formatErrorStore;
9
9
  exports.formatNativeSpecErrorStore = formatNativeSpecErrorStore;
10
+ var _Utils = require("@react-native/codegen/src/generators/Utils");
10
11
  function indentedLineStart(indent) {
11
12
  return "\n" + " ".repeat(indent);
12
13
  }
@@ -172,25 +173,61 @@ function formatTypeAnnotation(annotation) {
172
173
  annotation.value.includes(" ")
173
174
  ? `'${annotation.value}'`
174
175
  : annotation.value;
175
- case "StringLiteralUnionTypeAnnotation":
176
- return (
177
- "(" +
178
- annotation.types
179
- .map((stringLit) => formatTypeAnnotation(stringLit))
180
- .join(" | ") +
181
- ")"
182
- );
176
+ case "UnionTypeAnnotation":
177
+ const validUnionType = (0, _Utils.parseValidUnionType)(annotation);
178
+ switch (validUnionType) {
179
+ case "boolean":
180
+ if (
181
+ annotation.types.every(
182
+ ({ type }) => type === "BooleanLiteralTypeAnnotation",
183
+ )
184
+ ) {
185
+ return (
186
+ "(" +
187
+ annotation.types
188
+ .map((boolLit) => formatTypeAnnotation(boolLit))
189
+ .join(" | ") +
190
+ ")"
191
+ );
192
+ }
193
+ return `Union<boolean>`;
194
+ case "number":
195
+ if (
196
+ annotation.types.every(
197
+ ({ type }) => type === "NumberLiteralTypeAnnotation",
198
+ )
199
+ ) {
200
+ return (
201
+ "(" +
202
+ annotation.types
203
+ .map((numLit) => formatTypeAnnotation(numLit))
204
+ .join(" | ") +
205
+ ")"
206
+ );
207
+ }
208
+ return `Union<number>`;
209
+ case "object":
210
+ return `Union<Object>`;
211
+ case "string":
212
+ if (
213
+ annotation.types.every(
214
+ ({ type }) => type === "StringLiteralTypeAnnotation",
215
+ )
216
+ ) {
217
+ return (
218
+ "(" +
219
+ annotation.types
220
+ .map((stringLit) => formatTypeAnnotation(stringLit))
221
+ .join(" | ") +
222
+ ")"
223
+ );
224
+ }
225
+ return `Union<string>`;
226
+ default:
227
+ throw new Error(`Unsupported union member type`);
228
+ }
183
229
  case "StringTypeAnnotation":
184
230
  return "string";
185
- case "UnionTypeAnnotation": {
186
- const shortHandType =
187
- annotation.memberType === "StringTypeAnnotation"
188
- ? "string"
189
- : annotation.memberType === "ObjectTypeAnnotation"
190
- ? "Object"
191
- : "number";
192
- return `Union<${shortHandType}>`;
193
- }
194
231
  case "PromiseTypeAnnotation":
195
232
  return "Promise<" + formatTypeAnnotation(annotation.elementType) + ">";
196
233
  case "EventEmitterTypeAnnotation":
@@ -156,21 +156,15 @@ function compareTypeAnnotationForSorting(
156
156
  EQUALITY_MSG,
157
157
  );
158
158
  return typeA.value.localeCompare(typeB.value);
159
- case "StringLiteralUnionTypeAnnotation":
159
+ case "UnionTypeAnnotation":
160
160
  (0, _invariant.default)(
161
- typeB.type === "StringLiteralUnionTypeAnnotation",
161
+ typeB.type === "UnionTypeAnnotation",
162
162
  EQUALITY_MSG,
163
163
  );
164
164
  return compareAnnotationArraysForSorting(
165
165
  [originalPositionA, typeA.types],
166
166
  [originalPositionB, typeB.types],
167
167
  );
168
- case "UnionTypeAnnotation":
169
- (0, _invariant.default)(
170
- typeB.type === "UnionTypeAnnotation",
171
- EQUALITY_MSG,
172
- );
173
- return 0;
174
168
  case "VoidTypeAnnotation":
175
169
  return 0;
176
170
  case "ReservedTypeAnnotation":
@@ -279,8 +273,6 @@ function typeAnnotationArbitraryOrder(annotation) {
279
273
  return 15;
280
274
  case "BooleanLiteralTypeAnnotation":
281
275
  return 16;
282
- case "StringLiteralUnionTypeAnnotation":
283
- return 17;
284
276
  case "StringTypeAnnotation":
285
277
  return 18;
286
278
  case "StringLiteralTypeAnnotation":
@@ -11,6 +11,7 @@
11
11
  import type {
12
12
  ComparisonResult,
13
13
  MembersComparisonResult,
14
+ UnionMembersComparisonResult,
14
15
  } from "./ComparisonResult";
15
16
  import type {
16
17
  BooleanLiteralTypeAnnotation,
@@ -53,6 +54,10 @@ export declare function compareEnumDeclarationMemberArrays(
53
54
  newer: Array<NativeModuleEnumMember>,
54
55
  older: Array<NativeModuleEnumMember>,
55
56
  ): MembersComparisonResult;
57
+ export declare function compareUnionMemberArrays(
58
+ newer: Array<CompleteTypeAnnotation>,
59
+ older: Array<CompleteTypeAnnotation>,
60
+ ): UnionMembersComparisonResult;
56
61
  export declare function compareEnumDeclarationWithMembers(
57
62
  newerDeclaration: NativeModuleEnumDeclarationWithMembers,
58
63
  olderDeclaration: NativeModuleEnumDeclarationWithMembers,
@@ -16,6 +16,7 @@ exports.compareStringLiteralTypes = compareStringLiteralTypes;
16
16
  exports.compareStringLiteralUnionTypes = compareStringLiteralUnionTypes;
17
17
  exports.compareTypeAnnotation = compareTypeAnnotation;
18
18
  exports.compareTypes = compareTypes;
19
+ exports.compareUnionMemberArrays = compareUnionMemberArrays;
19
20
  exports.compareUnionTypes = compareUnionTypes;
20
21
  var _ComparisonResult = require("./ComparisonResult");
21
22
  var _SortTypeAnnotations = require("./SortTypeAnnotations.js");
@@ -190,12 +191,6 @@ function compareTypeAnnotation(
190
191
  EQUALITY_MSG,
191
192
  );
192
193
  return compareBooleanLiteralTypes(newerAnnotation, olderAnnotation);
193
- case "StringLiteralUnionTypeAnnotation":
194
- (0, _invariant.default)(
195
- olderAnnotation.type === "StringLiteralUnionTypeAnnotation",
196
- EQUALITY_MSG,
197
- );
198
- return compareStringLiteralUnionTypes(newerAnnotation, olderAnnotation);
199
194
  case "StringLiteralTypeAnnotation":
200
195
  (0, _invariant.default)(
201
196
  olderAnnotation.type === "StringLiteralTypeAnnotation",
@@ -260,6 +255,27 @@ function updatePropertyError(name, newType, oldType, result) {
260
255
  }
261
256
  };
262
257
  }
258
+ function updateUnionMemberError(name, newType, oldType, result) {
259
+ return (oldError) => {
260
+ const comparisonError = (0,
261
+ _ComparisonResult.typeAnnotationComparisonError)(
262
+ "has conflicting changes",
263
+ newType,
264
+ oldType,
265
+ oldError,
266
+ );
267
+ const memberLabel = getTypeAnnotationLabel(name);
268
+ const newFault = {
269
+ member: memberLabel,
270
+ fault: comparisonError,
271
+ };
272
+ if (result.errorMembers) {
273
+ result.errorMembers.push(newFault);
274
+ } else {
275
+ result.errorMembers = [newFault];
276
+ }
277
+ };
278
+ }
263
279
  function updateEnumMemberError(name, newType, oldType, result) {
264
280
  return (oldError) => {
265
281
  const comparisonError = (0,
@@ -280,6 +296,20 @@ function updateEnumMemberError(name, newType, oldType, result) {
280
296
  }
281
297
  };
282
298
  }
299
+ function getTypeAnnotationLabel(type) {
300
+ switch (type.type) {
301
+ case "StringLiteralTypeAnnotation":
302
+ return `"${type.value}"`;
303
+ case "NumberLiteralTypeAnnotation":
304
+ return String(type.value);
305
+ case "BooleanLiteralTypeAnnotation":
306
+ return String(type.value);
307
+ case "NullableTypeAnnotation":
308
+ return `?${getTypeAnnotationLabel(type.typeAnnotation)}`;
309
+ default:
310
+ return type.type;
311
+ }
312
+ }
283
313
  function updateNestedProperties(name, propertyChange, result) {
284
314
  if (result.nestedPropertyChanges) {
285
315
  result.nestedPropertyChanges.push([name, propertyChange]);
@@ -387,6 +417,7 @@ function comparePropertyArrays(newerOriginal, olderOriginal) {
387
417
  result,
388
418
  );
389
419
  case "members":
420
+ case "unionMembers":
390
421
  case "properties":
391
422
  case "functionChange":
392
423
  case "positionalTypeChange":
@@ -536,11 +567,11 @@ function compareEnumDeclarationMemberArrays(newer, older) {
536
567
  return {};
537
568
  } else if (newer.length === 0) {
538
569
  return {
539
- missingMembers: older,
570
+ missingMembers: [...older],
540
571
  };
541
572
  } else if (older.length === 0) {
542
573
  return {
543
- addedMembers: newer,
574
+ addedMembers: [...newer],
544
575
  };
545
576
  }
546
577
  const newerHead = newer.pop();
@@ -577,6 +608,7 @@ function compareEnumDeclarationMemberArrays(newer, older) {
577
608
  case "functionChange":
578
609
  case "positionalTypeChange":
579
610
  case "members":
611
+ case "unionMembers":
580
612
  break;
581
613
  default:
582
614
  throw new Error("Unsupported status " + comparedTypes.status);
@@ -602,6 +634,77 @@ function compareEnumDeclarationMemberArrays(newer, older) {
602
634
  }
603
635
  throw new Error("Internal error: should not reach here");
604
636
  }
637
+ function compareUnionMemberArrays(newer, older) {
638
+ if (newer.length === 0 && older.length === 0) {
639
+ return {};
640
+ } else if (newer.length === 0) {
641
+ return {
642
+ missingMembers: [...older],
643
+ };
644
+ } else if (older.length === 0) {
645
+ return {
646
+ addedMembers: [...newer],
647
+ };
648
+ }
649
+ const newerHead = newer.pop();
650
+ const olderHead = older.pop();
651
+ (0, _invariant.default)(
652
+ newerHead != null && olderHead != null,
653
+ "Array is empty",
654
+ );
655
+ const sortComparison = (0,
656
+ _SortTypeAnnotations.compareTypeAnnotationForSorting)(
657
+ [0, newerHead],
658
+ [0, olderHead],
659
+ );
660
+ if (sortComparison === 0) {
661
+ const headComparison = compareTypeAnnotation(newerHead, olderHead);
662
+ const restComparison = compareUnionMemberArrays(newer, older);
663
+ switch (headComparison.status) {
664
+ case "matching":
665
+ return restComparison;
666
+ case "error":
667
+ updateUnionMemberError(
668
+ newerHead,
669
+ newerHead,
670
+ olderHead,
671
+ restComparison,
672
+ )(headComparison.errorLog);
673
+ return restComparison;
674
+ case "skipped":
675
+ throw new Error(
676
+ "Internal error: returned 'skipped' for non-optional older type",
677
+ );
678
+ case "properties":
679
+ restComparison.missingMembers = restComparison.missingMembers || [];
680
+ restComparison.missingMembers.push(olderHead);
681
+ restComparison.addedMembers = restComparison.addedMembers || [];
682
+ restComparison.addedMembers.push(newerHead);
683
+ return restComparison;
684
+ case "nullableChange":
685
+ case "functionChange":
686
+ case "positionalTypeChange":
687
+ case "members":
688
+ case "unionMembers":
689
+ break;
690
+ default:
691
+ throw new Error("Unsupported status " + headComparison.status);
692
+ }
693
+ } else if (sortComparison > 0) {
694
+ older.push(olderHead);
695
+ const restComparison = compareUnionMemberArrays(newer, older);
696
+ restComparison.addedMembers = restComparison.addedMembers || [];
697
+ restComparison.addedMembers.push(newerHead);
698
+ return restComparison;
699
+ } else if (sortComparison < 0) {
700
+ newer.push(newerHead);
701
+ const restComparison = compareUnionMemberArrays(newer, older);
702
+ restComparison.missingMembers = restComparison.missingMembers || [];
703
+ restComparison.missingMembers.push(olderHead);
704
+ return restComparison;
705
+ }
706
+ throw new Error("Internal error: should not reach here");
707
+ }
605
708
  function compareEnumDeclarationWithMembers(newerDeclaration, olderDeclaration) {
606
709
  const sortedNewerTypes = Array.from(newerDeclaration.members).sort(
607
710
  compareEnumMember,
@@ -718,17 +821,53 @@ function compareNullableChange(newerAnnotation, olderAnnotation) {
718
821
  }
719
822
  }
720
823
  function compareUnionTypes(newerType, olderType) {
721
- if (newerType.memberType !== olderType.memberType) {
824
+ const sortedNewerTypes = (0, _SortTypeAnnotations.sortTypeAnnotations)(
825
+ newerType.types,
826
+ );
827
+ const sortedOlderTypes = (0, _SortTypeAnnotations.sortTypeAnnotations)(
828
+ olderType.types,
829
+ );
830
+ const result = compareUnionMemberArrays(
831
+ sortedNewerTypes.map(([_, type]) => type),
832
+ sortedOlderTypes.map(([_, type]) => type),
833
+ );
834
+ if ((0, _ComparisonResult.isUnionMemberLogEmpty)(result)) {
835
+ return {
836
+ status: "matching",
837
+ };
838
+ } else if (result.errorMembers) {
839
+ return (0, _ComparisonResult.makeError)(
840
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
841
+ "Union types do not match",
842
+ newerType,
843
+ olderType,
844
+ (0, _ComparisonResult.memberComparisonError)(
845
+ result.errorMembers.length > 1
846
+ ? "Union contained members with type mismatches"
847
+ : "Union contained a member with a type mismatch",
848
+ result.errorMembers,
849
+ ),
850
+ ),
851
+ );
852
+ } else if (
853
+ (result.addedMembers &&
854
+ result.addedMembers.length > 0 &&
855
+ result.addedMembers.length === newerType.types.length) ||
856
+ (result.missingMembers &&
857
+ result.missingMembers.length > 0 &&
858
+ result.missingMembers.length === olderType.types.length)
859
+ ) {
722
860
  return (0, _ComparisonResult.makeError)(
723
861
  (0, _ComparisonResult.typeAnnotationComparisonError)(
724
- "Union member type does not match",
862
+ "Union types do not match.",
725
863
  newerType,
726
864
  olderType,
727
865
  ),
728
866
  );
729
867
  }
730
868
  return {
731
- status: "matching",
869
+ status: "unionMembers",
870
+ memberLog: result,
732
871
  };
733
872
  }
734
873
  function comparePromiseTypes(newerType, olderType) {
@@ -884,6 +1023,7 @@ function compareFunctionTypes(newerType, olderType) {
884
1023
  if (
885
1024
  returnTypeResult.status === "properties" ||
886
1025
  returnTypeResult.status === "members" ||
1026
+ returnTypeResult.status === "unionMembers" ||
887
1027
  returnTypeResult.status === "functionChange" ||
888
1028
  returnTypeResult.status === "positionalTypeChange" ||
889
1029
  returnTypeResult.status === "nullableChange"
@@ -957,6 +1097,7 @@ function compareArrayOfTypes(fixedOrder, fixedLength, newerTypes, olderTypes) {
957
1097
  if (
958
1098
  result.status === "properties" ||
959
1099
  result.status === "members" ||
1100
+ result.status === "unionMembers" ||
960
1101
  result.status === "functionChange" ||
961
1102
  result.status === "positionalTypeChange" ||
962
1103
  result.status === "nullableChange"
@@ -11,6 +11,7 @@
11
11
  import type {
12
12
  ComparisonResult,
13
13
  MembersComparisonResult,
14
+ UnionMembersComparisonResult,
14
15
  } from "./ComparisonResult";
15
16
  import type {
16
17
  BooleanLiteralTypeAnnotation,
@@ -59,6 +60,11 @@ declare export function compareEnumDeclarationMemberArrays(
59
60
  older: Array<NativeModuleEnumMember>,
60
61
  ): MembersComparisonResult;
61
62
 
63
+ declare export function compareUnionMemberArrays(
64
+ newer: Array<CompleteTypeAnnotation>,
65
+ older: Array<CompleteTypeAnnotation>,
66
+ ): UnionMembersComparisonResult;
67
+
62
68
  declare export function compareEnumDeclarationWithMembers(
63
69
  newerDeclaration: NativeModuleEnumDeclarationWithMembers,
64
70
  olderDeclaration: NativeModuleEnumDeclarationWithMembers,
@@ -31,14 +31,15 @@ export declare type stricterPropertiesMessage =
31
31
  export declare const tooOptionalPropertiesMessage: "Property made optional, but native requires it";
32
32
  export declare type tooOptionalPropertiesMessage =
33
33
  typeof tooOptionalPropertiesMessage;
34
- export declare const removedUnionMessage: "Union removed items, but native may still provide them";
35
- export declare type removedUnionMessage = typeof removedUnionMessage;
36
- export declare const addedUnionMessage: "Union added items, but native will not expect/support them";
37
- export declare type addedUnionMessage = typeof addedUnionMessage;
38
34
  export declare const removedEnumMessage: "Enum removed items, but native may still provide them";
39
35
  export declare type removedEnumMessage = typeof removedEnumMessage;
40
36
  export declare const addedEnumMessage: "Enum added items, but native will not expect/support them";
41
37
  export declare type addedEnumMessage = typeof addedEnumMessage;
38
+ export declare const removedUnionMemberMessage: "Union removed items, but native may still provide them";
39
+ export declare type removedUnionMemberMessage =
40
+ typeof removedUnionMemberMessage;
41
+ export declare const addedUnionMemberMessage: "Union added items, but native will not expect/support them";
42
+ export declare type addedUnionMemberMessage = typeof addedUnionMemberMessage;
42
43
  export declare const removedIntersectionMessage: "Intersection removed items, but native may still require properties contained in them";
43
44
  export declare type removedIntersectionMessage =
44
45
  typeof removedIntersectionMessage;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true,
5
5
  });
6
- exports.addedUnionMessage =
6
+ exports.addedUnionMemberMessage =
7
7
  exports.addedPropertiesMessage =
8
8
  exports.addedIntersectionMessage =
9
9
  exports.addedEnumMessage =
@@ -14,7 +14,7 @@ exports.fromNativeVoidChangeMessage = void 0;
14
14
  exports.hasCodegenUpdatesTypes = hasCodegenUpdatesTypes;
15
15
  exports.hasUpdatesTypes = hasUpdatesTypes;
16
16
  exports.stricterPropertiesMessage =
17
- exports.removedUnionMessage =
17
+ exports.removedUnionMemberMessage =
18
18
  exports.removedPropertiesMessage =
19
19
  exports.removedIntersectionMessage =
20
20
  exports.removedEnumMessage =
@@ -78,7 +78,14 @@ function nestedPropertiesCheck(typeName, result, check, inverseCheck) {
78
78
  "Internal error: nested property change " + result.status,
79
79
  );
80
80
  case "properties":
81
- let finalResult = check(result.propertyLog, null, null, null, typeName);
81
+ let finalResult = check(
82
+ result.propertyLog,
83
+ null,
84
+ null,
85
+ null,
86
+ null,
87
+ typeName,
88
+ );
82
89
  if (result.propertyLog.nestedPropertyChanges) {
83
90
  finalResult = combine(
84
91
  finalResult,
@@ -105,7 +112,9 @@ function nestedPropertiesCheck(typeName, result, check, inverseCheck) {
105
112
  }
106
113
  return finalResult;
107
114
  case "members":
108
- return check(null, null, null, result.memberLog, typeName);
115
+ return check(null, null, null, result.memberLog, null, typeName);
116
+ case "unionMembers":
117
+ return check(null, null, null, null, result.memberLog, typeName);
109
118
  case "functionChange":
110
119
  let returnTypeResult = [];
111
120
  if (result.functionChangeLog.returnType) {
@@ -138,6 +147,7 @@ function nestedPropertiesCheck(typeName, result, check, inverseCheck) {
138
147
  changeLog,
139
148
  null,
140
149
  null,
150
+ null,
141
151
  typeName,
142
152
  );
143
153
  return combine(
@@ -155,6 +165,7 @@ function nestedPropertiesCheck(typeName, result, check, inverseCheck) {
155
165
  null,
156
166
  result.nullableLog,
157
167
  null,
168
+ null,
158
169
  typeName,
159
170
  );
160
171
  if (result.nullableLog.interiorLog) {
@@ -208,6 +219,7 @@ function checkForUnsafeRemovedProperties(
208
219
  _postionalChange,
209
220
  _nullableChange,
210
221
  _memberChange,
222
+ _unionMemberChange,
211
223
  typeName,
212
224
  ) {
213
225
  if (propertyChange && propertyChange.missingProperties) {
@@ -227,6 +239,7 @@ function checkForUnsafeAddedProperties(
227
239
  _positionalChange,
228
240
  _nullableChange,
229
241
  _memberChange,
242
+ _unionMemberChange,
230
243
  typeName,
231
244
  ) {
232
245
  if (propertyChange && propertyChange.addedProperties) {
@@ -246,6 +259,7 @@ function checkForUnSafeMadeStrictProperties(
246
259
  _positionalChange,
247
260
  _nullableChange,
248
261
  _memberChange,
262
+ _unionMemberChange,
249
263
  typeName,
250
264
  ) {
251
265
  if (
@@ -276,6 +290,7 @@ function checkForUnSafeMadeOptionalProperties(
276
290
  _positionalChange,
277
291
  _nullableChange,
278
292
  _memberChange,
293
+ _unionMemberChange,
279
294
  typeName,
280
295
  ) {
281
296
  if (
@@ -299,82 +314,105 @@ function checkForUnSafeMadeOptionalProperties(
299
314
  }
300
315
  return [];
301
316
  }
302
- const removedUnionMessage = (exports.removedUnionMessage =
303
- "Union removed items, but native may still provide them");
304
- function checkForUnsafeRemovedUnionItems(
317
+ const removedEnumMessage = (exports.removedEnumMessage =
318
+ "Enum removed items, but native may still provide them");
319
+ function checkForUnsafeRemovedEnumItems(
305
320
  _propertyChange,
306
- positionalChange,
321
+ _positionalChange,
307
322
  _nullableChange,
308
- _memberChange,
323
+ memberChange,
324
+ _unionMemberChange,
309
325
  typeName,
310
326
  ) {
311
- if (
312
- positionalChange &&
313
- (positionalChange.typeKind === "union" ||
314
- positionalChange.typeKind === "stringUnion") &&
315
- positionalChange.removedElements &&
316
- positionalChange.removedElements.length > 0
317
- ) {
327
+ if (memberChange?.missingMembers && memberChange?.missingMembers.length > 0) {
318
328
  return [
319
329
  {
320
330
  typeName,
321
- errorCode: "removedUnionCases",
322
- errorInformation: (0, _ComparisonResult.positionalComparisonError)(
323
- removedUnionMessage,
324
- positionalChange.removedElements,
331
+ errorCode: "removedEnumCases",
332
+ errorInformation: (0, _ComparisonResult.memberComparisonError)(
333
+ removedEnumMessage,
334
+ memberChange.missingMembers.map((member) => ({
335
+ member: member.name,
336
+ })),
325
337
  ),
326
338
  },
327
339
  ];
328
340
  }
329
341
  return [];
330
342
  }
331
- const addedUnionMessage = (exports.addedUnionMessage =
332
- "Union added items, but native will not expect/support them");
333
- function checkForUnsafeAddedUnionItems(
343
+ const addedEnumMessage = (exports.addedEnumMessage =
344
+ "Enum added items, but native will not expect/support them");
345
+ function checkForUnsafeAddedEnumItems(
334
346
  _propertyChange,
335
- positionalChange,
347
+ _positionalChange,
336
348
  _nullableChange,
337
- _memberChange,
349
+ memberChange,
350
+ _unionMemberChange,
338
351
  typeName,
339
352
  ) {
340
- if (
341
- positionalChange &&
342
- (positionalChange.typeKind === "union" ||
343
- positionalChange.typeKind === "stringUnion") &&
344
- positionalChange.addedElements &&
345
- positionalChange.addedElements.length > 0
346
- ) {
353
+ if (memberChange?.addedMembers && memberChange?.addedMembers.length > 0) {
347
354
  return [
348
355
  {
349
356
  typeName,
350
- errorCode: "addedUnionCases",
351
- errorInformation: (0, _ComparisonResult.positionalComparisonError)(
352
- addedUnionMessage,
353
- positionalChange.addedElements,
357
+ errorCode: "addedEnumCases",
358
+ errorInformation: (0, _ComparisonResult.memberComparisonError)(
359
+ addedEnumMessage,
360
+ memberChange.addedMembers.map((member) => ({
361
+ member: member.name,
362
+ })),
354
363
  ),
355
364
  },
356
365
  ];
357
366
  }
358
367
  return [];
359
368
  }
360
- const removedEnumMessage = (exports.removedEnumMessage =
361
- "Enum removed items, but native may still provide them");
362
- function checkForUnsafeRemovedEnumItems(
369
+ function getMemberLabel(member) {
370
+ if (
371
+ typeof member === "object" &&
372
+ member != null &&
373
+ "name" in member &&
374
+ "value" in member &&
375
+ typeof member.name === "string"
376
+ ) {
377
+ return member.name;
378
+ }
379
+ return getTypeAnnotationLabel(member);
380
+ }
381
+ function getTypeAnnotationLabel(type) {
382
+ if (type.type === "StringLiteralTypeAnnotation") {
383
+ return `"${type.value}"`;
384
+ } else if (type.type === "NumberLiteralTypeAnnotation") {
385
+ return String(type.value);
386
+ } else if (type.type === "BooleanLiteralTypeAnnotation") {
387
+ return String(type.value);
388
+ } else if (type.type === "NullableTypeAnnotation") {
389
+ return `?${getTypeAnnotationLabel(type.typeAnnotation)}`;
390
+ } else {
391
+ return type.type;
392
+ }
393
+ }
394
+ const removedUnionMemberMessage = (exports.removedUnionMemberMessage =
395
+ "Union removed items, but native may still provide them");
396
+ function checkForUnsafeRemovedUnionItems(
363
397
  _propertyChange,
364
398
  _positionalChange,
365
399
  _nullableChange,
366
400
  memberChange,
401
+ unionMemberChange,
367
402
  typeName,
368
403
  ) {
369
- if (memberChange?.missingMembers && memberChange?.missingMembers.length > 0) {
404
+ if (
405
+ unionMemberChange?.missingMembers &&
406
+ unionMemberChange?.missingMembers.length > 0
407
+ ) {
370
408
  return [
371
409
  {
372
410
  typeName,
373
- errorCode: "removedEnumCases",
411
+ errorCode: "removedUnionCases",
374
412
  errorInformation: (0, _ComparisonResult.memberComparisonError)(
375
- removedEnumMessage,
376
- memberChange.missingMembers.map((member) => ({
377
- member: member.name,
413
+ removedUnionMemberMessage,
414
+ unionMemberChange.missingMembers.map((member) => ({
415
+ member: getMemberLabel(member),
378
416
  })),
379
417
  ),
380
418
  },
@@ -382,24 +420,28 @@ function checkForUnsafeRemovedEnumItems(
382
420
  }
383
421
  return [];
384
422
  }
385
- const addedEnumMessage = (exports.addedEnumMessage =
386
- "Enum added items, but native will not expect/support them");
387
- function checkForUnsafeAddedEnumItems(
423
+ const addedUnionMemberMessage = (exports.addedUnionMemberMessage =
424
+ "Union added items, but native will not expect/support them");
425
+ function checkForUnsafeAddedUnionItems(
388
426
  _propertyChange,
389
427
  _positionalChange,
390
428
  _nullableChange,
391
429
  memberChange,
430
+ unionMemberChange,
392
431
  typeName,
393
432
  ) {
394
- if (memberChange?.addedMembers && memberChange?.addedMembers.length > 0) {
433
+ if (
434
+ unionMemberChange?.addedMembers &&
435
+ unionMemberChange?.addedMembers.length > 0
436
+ ) {
395
437
  return [
396
438
  {
397
439
  typeName,
398
- errorCode: "addedEnumCases",
440
+ errorCode: "addedUnionCases",
399
441
  errorInformation: (0, _ComparisonResult.memberComparisonError)(
400
- addedEnumMessage,
401
- memberChange.addedMembers.map((member) => ({
402
- member: member.name,
442
+ addedUnionMemberMessage,
443
+ unionMemberChange.addedMembers.map((member) => ({
444
+ member: getMemberLabel(member),
403
445
  })),
404
446
  ),
405
447
  },
@@ -414,6 +456,7 @@ function checkForUnsafeRemovedIntersectionItems(
414
456
  positionalChange,
415
457
  _nullableChange,
416
458
  _memberChange,
459
+ _unionMemberChange,
417
460
  typeName,
418
461
  ) {
419
462
  if (
@@ -442,6 +485,7 @@ function checkForUnsafeAddedIntersectionItems(
442
485
  positionalChange,
443
486
  _nullableChange,
444
487
  _memberChange,
488
+ _unionMemberChange,
445
489
  typeName,
446
490
  ) {
447
491
  if (
@@ -472,6 +516,7 @@ function checkForUnsafeNullableToNativeChange(
472
516
  _positionalChange,
473
517
  nullableChange,
474
518
  _memberChange,
519
+ _unionMemberChange,
475
520
  typeName,
476
521
  ) {
477
522
  if (
@@ -505,6 +550,7 @@ function checkForUnsafeNullableFromNativeChange(
505
550
  _positionalChange,
506
551
  nullableChange,
507
552
  _memberChange,
553
+ _unionMemberChange,
508
554
  typeName,
509
555
  ) {
510
556
  if (
@@ -535,6 +581,7 @@ function chainPropertiesChecks(checks) {
535
581
  positionalChange,
536
582
  nullableChange,
537
583
  memberChange,
584
+ unionMemberChange,
538
585
  typeName,
539
586
  ) =>
540
587
  checks.reduce(
@@ -545,6 +592,7 @@ function chainPropertiesChecks(checks) {
545
592
  positionalChange,
546
593
  nullableChange,
547
594
  memberChange,
595
+ unionMemberChange,
548
596
  typeName,
549
597
  ),
550
598
  ),
@@ -636,9 +684,52 @@ function assessComparisonResult(
636
684
  null,
637
685
  null,
638
686
  memberChange,
687
+ null,
639
688
  typeName,
640
689
  );
641
690
  const fromNativeErrorResult = checksForTypesFlowingFromNative(
691
+ null,
692
+ null,
693
+ null,
694
+ memberChange,
695
+ null,
696
+ typeName,
697
+ );
698
+ switch (oldDirection) {
699
+ case "toNative":
700
+ toNativeErrorResult.forEach((error) =>
701
+ incompatibleChanges.add(error),
702
+ );
703
+ break;
704
+ case "fromNative":
705
+ fromNativeErrorResult.forEach((error) =>
706
+ incompatibleChanges.add(error),
707
+ );
708
+ break;
709
+ case "both":
710
+ toNativeErrorResult.forEach((error) =>
711
+ incompatibleChanges.add(error),
712
+ );
713
+ fromNativeErrorResult.forEach((error) =>
714
+ incompatibleChanges.add(error),
715
+ );
716
+ break;
717
+ }
718
+ }
719
+ break;
720
+ case "unionMembers":
721
+ {
722
+ const memberChange = difference.memberLog;
723
+ const toNativeErrorResult = checksForTypesFlowingToNative(
724
+ null,
725
+ null,
726
+ null,
727
+ null,
728
+ memberChange,
729
+ typeName,
730
+ );
731
+ const fromNativeErrorResult = checksForTypesFlowingFromNative(
732
+ null,
642
733
  null,
643
734
  null,
644
735
  null,
@@ -776,6 +867,7 @@ function assessComparisonResult(
776
867
  changeLog,
777
868
  null,
778
869
  null,
870
+ null,
779
871
  typeName,
780
872
  );
781
873
  const toNativeResult = combine(
@@ -794,6 +886,7 @@ function assessComparisonResult(
794
886
  changeLog,
795
887
  null,
796
888
  null,
889
+ null,
797
890
  typeName,
798
891
  );
799
892
  const fromNativeResult = combine(
@@ -838,6 +931,7 @@ function assessComparisonResult(
838
931
  null,
839
932
  difference.nullableLog,
840
933
  null,
934
+ null,
841
935
  typeName,
842
936
  ).forEach((error) => incompatibleChanges.add(error));
843
937
  break;
@@ -847,6 +941,7 @@ function assessComparisonResult(
847
941
  null,
848
942
  difference.nullableLog,
849
943
  null,
944
+ null,
850
945
  typeName,
851
946
  ).forEach((error) => incompatibleChanges.add(error));
852
947
  break;
@@ -28,10 +28,10 @@ declare export const removedPropertiesMessage: "Object removed required properti
28
28
  declare export const addedPropertiesMessage: "Object added required properties, which native will not provide";
29
29
  declare export const stricterPropertiesMessage: "Property made strict, but native may not provide it";
30
30
  declare export const tooOptionalPropertiesMessage: "Property made optional, but native requires it";
31
- declare export const removedUnionMessage: "Union removed items, but native may still provide them";
32
- declare export const addedUnionMessage: "Union added items, but native will not expect/support them";
33
31
  declare export const removedEnumMessage: "Enum removed items, but native may still provide them";
34
32
  declare export const addedEnumMessage: "Enum added items, but native will not expect/support them";
33
+ declare export const removedUnionMemberMessage: "Union removed items, but native may still provide them";
34
+ declare export const addedUnionMemberMessage: "Union added items, but native will not expect/support them";
35
35
  declare export const removedIntersectionMessage: "Intersection removed items, but native may still require properties contained in them";
36
36
  declare export const addedIntersectionMessage: "Intersection added items, but native may not provide all required attributes";
37
37
  declare export const toNativeVoidChangeMessage: "Native may not be able to safely handle presence of type";
@@ -34,7 +34,7 @@ function convertPropToBasicTypes(inputType) {
34
34
  break;
35
35
  case "StringEnumTypeAnnotation":
36
36
  resultingType = {
37
- type: "StringLiteralUnionTypeAnnotation",
37
+ type: "UnionTypeAnnotation",
38
38
  types: inputType.options.map((option) => {
39
39
  return {
40
40
  type: "StringLiteralTypeAnnotation",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native/compatibility-check",
3
- "version": "0.84.0-nightly-20251204-5bb3a6d68",
3
+ "version": "0.84.0-nightly-20251205-95cc1e767",
4
4
  "description": "Check a React Native app's boundary between JS and Native for incompatibilities",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,7 +29,7 @@
29
29
  "dist"
30
30
  ],
31
31
  "dependencies": {
32
- "@react-native/codegen": "0.84.0-nightly-20251204-5bb3a6d68"
32
+ "@react-native/codegen": "0.84.0-nightly-20251205-95cc1e767"
33
33
  },
34
34
  "devDependencies": {
35
35
  "flow-remove-types": "^2.237.2",