react-native 0.81.4 → 0.81.6

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 (35) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +1 -1
  2. package/Libraries/Renderer/implementations/ReactFabric-dev.js +38 -35
  3. package/Libraries/Renderer/implementations/ReactFabric-prod.js +51 -22
  4. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +54 -24
  5. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +36 -33
  6. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +5 -5
  7. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +5 -5
  8. package/Libraries/Renderer/shims/ReactNativeTypes.js +23 -11
  9. package/React/Base/RCTUtils.mm +5 -1
  10. package/React/Base/RCTVersion.m +1 -1
  11. package/React/CoreModules/RCTDeviceInfo.mm +3 -4
  12. package/React/Fabric/RCTSurfacePointerHandler.mm +1 -1
  13. package/React/Fabric/RCTSurfaceTouchHandler.mm +1 -1
  14. package/React/Views/RCTSwitchManager.m +24 -0
  15. package/ReactAndroid/gradle.properties +1 -1
  16. package/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java +25 -1
  17. package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +2 -2
  18. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
  19. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +0 -3
  20. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.kt +1 -1
  21. package/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.kt +2 -2
  22. package/ReactAndroid/src/main/jni/react/jni/TransformHelper.cpp +3 -1
  23. package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
  24. package/ReactCommon/react/renderer/components/view/BaseViewProps.cpp +0 -3
  25. package/ReactCommon/react/renderer/components/view/tests/ResolveTransformTest.cpp +377 -0
  26. package/package.json +10 -10
  27. package/scripts/codegen/generate-artifacts-executor/generateReactCodegenPodspec.js +7 -3
  28. package/scripts/codegen/generate-artifacts-executor/index.js +48 -22
  29. package/scripts/codegen/generate-artifacts-executor/utils.js +15 -3
  30. package/scripts/react_native_pods_utils/script_phases.sh +1 -3
  31. package/sdks/hermesc/osx-bin/hermes +0 -0
  32. package/sdks/hermesc/osx-bin/hermesc +0 -0
  33. package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
  34. package/third-party-podspecs/ReactNativeDependencies.podspec +1 -1
  35. package/types_generated/Libraries/Renderer/shims/ReactNativeTypes.d.ts +17 -10
@@ -0,0 +1,377 @@
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
+ #include <gtest/gtest.h>
9
+
10
+ #include <react/renderer/components/view/BaseViewProps.h>
11
+
12
+ namespace facebook::react {
13
+
14
+ namespace {
15
+
16
+ // For transforms involving rotations, use this helper to fix floating point
17
+ // accuracies
18
+ void expectTransformsEqual(const Transform& t1, const Transform& t2) {
19
+ for (int i = 0; i < 16; i++) {
20
+ EXPECT_NEAR(t1.matrix[i], t2.matrix[i], 0.0001);
21
+ }
22
+ }
23
+
24
+ } // namespace
25
+
26
+ class ResolveTransformTest : public ::testing::Test {
27
+ protected:
28
+ TransformOrigin createTransformOriginPoints(float x, float y, float z = 0) {
29
+ TransformOrigin origin;
30
+ origin.xy[0] = ValueUnit(x, UnitType::Point);
31
+ origin.xy[1] = ValueUnit(y, UnitType::Point);
32
+ origin.z = z;
33
+ return origin;
34
+ }
35
+
36
+ TransformOrigin createTransformOriginPercent(float x, float y, float z = 0) {
37
+ TransformOrigin origin;
38
+ origin.xy[0] = ValueUnit(x, UnitType::Percent);
39
+ origin.xy[1] = ValueUnit(y, UnitType::Percent);
40
+ origin.z = z;
41
+ return origin;
42
+ }
43
+ };
44
+
45
+ TEST_F(ResolveTransformTest, EmptyFrameNoTransformOrigin) {
46
+ Size frameSize{.width = 0, .height = 0};
47
+ Transform transform = Transform::Translate(10.0, 20.0, 0.0);
48
+ TransformOrigin transformOrigin; // Default (not set)
49
+
50
+ auto result =
51
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
52
+
53
+ // With empty frame size and no transform origin, should just apply the
54
+ // transform directly
55
+ EXPECT_EQ(result.matrix, transform.matrix);
56
+ }
57
+
58
+ TEST_F(ResolveTransformTest, EmptyFrameTransformOriginPoints) {
59
+ Size frameSize{.width = 0, .height = 0};
60
+ Transform transform = Transform::Translate(10.0, 20.0, 0.0);
61
+ TransformOrigin transformOrigin = createTransformOriginPoints(5, 8);
62
+
63
+ auto result =
64
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
65
+
66
+ // Should handle transform origin even with empty frame size
67
+ EXPECT_EQ(result.matrix, Transform::Translate(10.0, 20.0, 0.0).matrix);
68
+ }
69
+
70
+ TEST_F(ResolveTransformTest, EmptyFrameTransformOriginPercent) {
71
+ Size frameSize{.width = 0, .height = 0};
72
+ Transform transform = Transform::Translate(10.0, 20.0, 0.0);
73
+ TransformOrigin transformOrigin = createTransformOriginPercent(50, 50);
74
+
75
+ auto result =
76
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
77
+
78
+ // Transform origin does not affect translate transform
79
+ EXPECT_EQ(result.matrix, Transform::Translate(10.0, 20.0, 0.0).matrix);
80
+ }
81
+
82
+ TEST_F(ResolveTransformTest, NonEmptyFrameNoTransformOrigin) {
83
+ Size frameSize{.width = 100, .height = 200};
84
+ Transform transform = Transform::Translate(10.0, 20.0, 0.0);
85
+ TransformOrigin transformOrigin; // Default (not set)
86
+
87
+ auto result =
88
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
89
+
90
+ // Transform origin does not affect translate transform
91
+ EXPECT_EQ(result.matrix, Transform::Translate(10.0, 20.0, 0.0).matrix);
92
+ }
93
+
94
+ TEST_F(ResolveTransformTest, NonEmptyFrameTransformOriginPoints) {
95
+ Size frameSize{.width = 100, .height = 200};
96
+ Transform transform = Transform::Scale(2.0, 1.5, 0.);
97
+ TransformOrigin transformOrigin = createTransformOriginPoints(25, 50);
98
+
99
+ auto result =
100
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
101
+
102
+ auto expected = Transform::Translate(25.0, 25.0, 0.0) * transform;
103
+ EXPECT_EQ(result.matrix, expected.matrix);
104
+ }
105
+
106
+ TEST_F(ResolveTransformTest, NonEmptyFrameTransformOriginPercent) {
107
+ Size frameSize{.width = 100, .height = 200};
108
+ Transform transform = Transform::Scale(2.0, 1.5, 0.);
109
+ TransformOrigin transformOrigin =
110
+ createTransformOriginPercent(25, 75); // 25% width, 75% height
111
+
112
+ auto result =
113
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
114
+
115
+ // Should resolve percentages: 25% of 100 = 25, 75% of 200 = 150
116
+ auto expected = Transform::Translate(25.0, -25.0, 0.0) * transform;
117
+ EXPECT_EQ(result.matrix, expected.matrix);
118
+ }
119
+
120
+ TEST_F(ResolveTransformTest, IdentityTransformWithOrigin) {
121
+ Size frameSize{.width = 100, .height = 200};
122
+ Transform transform = Transform::Identity();
123
+ TransformOrigin transformOrigin = createTransformOriginPoints(25, 50);
124
+
125
+ auto result =
126
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
127
+
128
+ // Even with identity transform, transform origin should still apply
129
+ // translations but they should cancel out, resulting in identity
130
+ EXPECT_EQ(result.matrix, transform.matrix);
131
+ }
132
+
133
+ TEST_F(ResolveTransformTest, MultipleTransformOperations) {
134
+ Size frameSize{.width = 100, .height = 200};
135
+
136
+ Transform transform = Transform::Identity();
137
+ transform = transform * Transform::Translate(10.0, 20.0, 0.0);
138
+ transform = transform * Transform::Scale(2.0, 1.5, 0.0);
139
+
140
+ TransformOrigin transformOrigin = createTransformOriginPercent(50, 50);
141
+
142
+ auto result =
143
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
144
+
145
+ EXPECT_EQ(result.matrix, transform.matrix);
146
+ }
147
+
148
+ TEST_F(ResolveTransformTest, VariousTransformOriginPositions) {
149
+ Size frameSize{.width = 100, .height = 200};
150
+ Transform transform = Transform::Scale(2.0, 2.0, 0.);
151
+
152
+ // Test origin at top-left (0, 0)
153
+ TransformOrigin topLeft = createTransformOriginPoints(0, 0);
154
+ auto resultTopLeft =
155
+ BaseViewProps::resolveTransform(frameSize, transform, topLeft);
156
+ auto expected = Transform::Translate(50.0, 100.0, 0.0) * transform;
157
+ EXPECT_EQ(resultTopLeft.matrix, expected.matrix);
158
+
159
+ // Test origin at center (50%, 50%)
160
+ TransformOrigin center = createTransformOriginPercent(50, 50);
161
+ auto resultCenter =
162
+ BaseViewProps::resolveTransform(frameSize, transform, center);
163
+ EXPECT_EQ(resultCenter.matrix, transform.matrix);
164
+
165
+ // Test origin at bottom-right (100%, 100%)
166
+ TransformOrigin bottomRight = createTransformOriginPercent(100, 100);
167
+ auto resultBottomRight =
168
+ BaseViewProps::resolveTransform(frameSize, transform, bottomRight);
169
+ expected = Transform::Translate(-50.0, -100.0, 0.0) * transform;
170
+ EXPECT_EQ(resultBottomRight.matrix, expected.matrix);
171
+ }
172
+
173
+ // Test with z-component in transform origin
174
+ TEST_F(ResolveTransformTest, TransformOriginWithZComponent) {
175
+ Size frameSize{.width = 100, .height = 200};
176
+ Transform transform = Transform::Scale(1.5, 1.5, 0.);
177
+
178
+ TransformOrigin transformOrigin;
179
+ transformOrigin.xy[0] = ValueUnit(50, UnitType::Point);
180
+ transformOrigin.xy[1] = ValueUnit(100, UnitType::Point);
181
+ transformOrigin.z = 10.0f;
182
+
183
+ auto result =
184
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
185
+ auto expected = Transform::Translate(0.0, 0.0, 10.0) * transform;
186
+ EXPECT_EQ(result.matrix, expected.matrix);
187
+ }
188
+
189
+ TEST_F(ResolveTransformTest, ArbitraryTransformMatrix) {
190
+ Size frameSize{.width = 100, .height = 200};
191
+
192
+ Transform transform;
193
+ transform.operations.push_back({
194
+ .type = TransformOperationType::Arbitrary,
195
+ .x = ValueUnit(0, UnitType::Point),
196
+ .y = ValueUnit(0, UnitType::Point),
197
+ .z = ValueUnit(0, UnitType::Point),
198
+ });
199
+ // Set custom matrix
200
+ transform.matrix = {{2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 10, 20, 0, 1}};
201
+
202
+ TransformOrigin transformOrigin = createTransformOriginPoints(25, 50);
203
+
204
+ auto result =
205
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
206
+
207
+ auto expected = Transform::Translate(25.0, 50.0, 0.0) * transform;
208
+ EXPECT_EQ(result.matrix, expected.matrix);
209
+ }
210
+
211
+ // Test rotation with empty frame size and no transform origin
212
+ TEST_F(ResolveTransformTest, RotationEmptyFrameNoTransformOrigin) {
213
+ Size frameSize{.width = 0, .height = 0};
214
+ Transform transform = Transform::RotateZ(M_PI / 4.0); // 45 degrees
215
+ TransformOrigin transformOrigin; // Default (not set)
216
+
217
+ auto result =
218
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
219
+
220
+ // With empty frame size and no transform origin, should just apply the
221
+ // rotation directly
222
+ expectTransformsEqual(result, transform);
223
+ }
224
+
225
+ // Test rotation with empty frame size and transform origin in points
226
+ TEST_F(ResolveTransformTest, RotationEmptyFrameTransformOriginPoints) {
227
+ Size frameSize{.width = 0, .height = 0};
228
+ Transform transform = Transform::RotateZ(M_PI / 4.0); // 45 degrees
229
+ TransformOrigin transformOrigin = createTransformOriginPoints(10, 20);
230
+
231
+ auto result =
232
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
233
+
234
+ // With empty frame size, center is (0, 0), so origin offset is (10, 20)
235
+ auto expected = Transform::Translate(10.0, 20.0, 0.0) * transform *
236
+ Transform::Translate(-10.0, -20.0, 0.0);
237
+ expectTransformsEqual(result, expected);
238
+ }
239
+
240
+ // Test rotation with empty frame size and transform origin in percentages
241
+ TEST_F(ResolveTransformTest, RotationEmptyFrameTransformOriginPercent) {
242
+ Size frameSize{.width = 0, .height = 0};
243
+ Transform transform = Transform::RotateZ(M_PI / 6.0); // 30 degrees
244
+ TransformOrigin transformOrigin = createTransformOriginPercent(50, 50);
245
+
246
+ auto result =
247
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
248
+
249
+ // With 0 frame size, percentages resolve to 0, so no origin offset
250
+ expectTransformsEqual(result, transform);
251
+ }
252
+
253
+ // Test rotation with non-empty frame size and no transform origin
254
+ TEST_F(ResolveTransformTest, RotationNonEmptyFrameNoTransformOrigin) {
255
+ Size frameSize{.width = 100, .height = 200};
256
+ Transform transform = Transform::RotateZ(M_PI / 3.0); // 60 degrees
257
+ TransformOrigin transformOrigin; // Default (not set)
258
+
259
+ auto result =
260
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
261
+
262
+ // Without transform origin, rotation should happen around default center
263
+ expectTransformsEqual(result, transform);
264
+ }
265
+
266
+ // Test rotation with non-empty frame size and transform origin in points
267
+ TEST_F(ResolveTransformTest, RotationNonEmptyFrameTransformOriginPoints) {
268
+ Size frameSize{.width = 100, .height = 200};
269
+ Transform transform = Transform::RotateZ(M_PI / 4.0); // 45 degrees
270
+ TransformOrigin transformOrigin = createTransformOriginPoints(25, 50);
271
+
272
+ auto result =
273
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
274
+
275
+ // Center of 100x200 frame is (50, 100), origin at (25, 50) means offset of
276
+ // (-25, -50)
277
+ auto expected = Transform::Translate(-25.0, -50.0, 0.0) * transform *
278
+ Transform::Translate(25.0, 50.0, 0.0);
279
+ expectTransformsEqual(result, expected);
280
+ }
281
+
282
+ // Test rotation with non-empty frame size and transform origin in percentages
283
+ TEST_F(ResolveTransformTest, RotationNonEmptyFrameTransformOriginPercent) {
284
+ Size frameSize{.width = 100, .height = 200};
285
+ Transform transform = Transform::RotateZ(M_PI / 2.0); // 90 degrees
286
+ TransformOrigin transformOrigin =
287
+ createTransformOriginPercent(25, 75); // 25% width, 75% height
288
+
289
+ auto result =
290
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
291
+
292
+ // Should resolve percentages: 25% of 100 = 25, 75% of 200 = 150
293
+ // Center is (50, 100), so origin offset is (25-50, 150-100) = (-25, 50)
294
+ auto expected = Transform::Translate(-25.0, 50.0, 0.0) * transform *
295
+ Transform::Translate(25.0, -50.0, 0.0);
296
+ expectTransformsEqual(result, expected);
297
+ }
298
+
299
+ // Test rotation with mixed transform origin units
300
+ TEST_F(ResolveTransformTest, RotationMixedTransformOriginUnits) {
301
+ Size frameSize{.width = 100, .height = 200};
302
+ Transform transform = Transform::RotateZ(M_PI); // 180 degrees
303
+
304
+ TransformOrigin transformOrigin;
305
+ transformOrigin.xy[0] = ValueUnit(30, UnitType::Point); // 30 points
306
+ transformOrigin.xy[1] = ValueUnit(25, UnitType::Percent); // 25% of 200 = 50
307
+ transformOrigin.z = 0;
308
+
309
+ auto result =
310
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
311
+
312
+ // Center is (50, 100), origin is (30, 50), so offset is (-20, -50)
313
+ auto expected = Transform::Translate(-20.0, -50.0, 0.0) * transform *
314
+ Transform::Translate(20.0, 50.0, 0.0);
315
+ expectTransformsEqual(result, expected);
316
+ }
317
+
318
+ // Test multiple rotations (RotateX, RotateY, RotateZ)
319
+ TEST_F(ResolveTransformTest, MultipleRotationsWithTransformOrigin) {
320
+ Size frameSize{.width = 100, .height = 100};
321
+
322
+ Transform transform = Transform::Rotate(M_PI / 6.0, M_PI / 4.0, M_PI / 3.0);
323
+ TransformOrigin transformOrigin = createTransformOriginPercent(50, 50);
324
+
325
+ auto result =
326
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
327
+ expectTransformsEqual(result, transform);
328
+ }
329
+
330
+ // Test rotation with z-component in transform origin
331
+ TEST_F(ResolveTransformTest, RotationWithZTransformOrigin) {
332
+ Size frameSize{.width = 100, .height = 200};
333
+ Transform transform = Transform::RotateZ(M_PI / 4.0); // 45 degrees
334
+
335
+ TransformOrigin transformOrigin;
336
+ transformOrigin.xy[0] = ValueUnit(50, UnitType::Point);
337
+ transformOrigin.xy[1] = ValueUnit(100, UnitType::Point);
338
+ transformOrigin.z = 15.0f;
339
+
340
+ auto result =
341
+ BaseViewProps::resolveTransform(frameSize, transform, transformOrigin);
342
+
343
+ // Center is (50, 100), origin is (50, 100, 15), so offset is (0, 0, 15)
344
+ auto expected = Transform::Translate(0.0, 0.0, 15.0) * transform *
345
+ Transform::Translate(0.0, 0.0, -15.0);
346
+ expectTransformsEqual(result, expected);
347
+ }
348
+
349
+ // Test rotation at different origin positions (corners vs center)
350
+ TEST_F(ResolveTransformTest, RotationDifferentOriginPositions) {
351
+ Size frameSize{.width = 100, .height = 100};
352
+ Transform transform = Transform::RotateZ(M_PI / 2.0); // 90 degrees
353
+
354
+ // Test rotation around top-left corner (0, 0)
355
+ TransformOrigin topLeft = createTransformOriginPoints(0, 0);
356
+ auto resultTopLeft =
357
+ BaseViewProps::resolveTransform(frameSize, transform, topLeft);
358
+ auto expectedTopLeft = Transform::Translate(-50.0, -50.0, 0.0) * transform *
359
+ Transform::Translate(50.0, 50.0, 0.0);
360
+ expectTransformsEqual(resultTopLeft, expectedTopLeft);
361
+
362
+ // Test rotation around center (50%, 50%)
363
+ TransformOrigin center = createTransformOriginPercent(50, 50);
364
+ auto resultCenter =
365
+ BaseViewProps::resolveTransform(frameSize, transform, center);
366
+ expectTransformsEqual(resultCenter, transform);
367
+
368
+ // Test rotation around bottom-right corner (100%, 100%)
369
+ TransformOrigin bottomRight = createTransformOriginPercent(100, 100);
370
+ auto resultBottomRight =
371
+ BaseViewProps::resolveTransform(frameSize, transform, bottomRight);
372
+ auto expectedBottomRight = Transform::Translate(50.0, 50.0, 0.0) * transform *
373
+ Transform::Translate(-50.0, -50.0, 0.0);
374
+ expectTransformsEqual(resultBottomRight, expectedBottomRight);
375
+ }
376
+
377
+ } // namespace facebook::react
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native",
3
- "version": "0.81.4",
3
+ "version": "0.81.6",
4
4
  "description": "A framework for building native apps using React",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -152,8 +152,8 @@
152
152
  "featureflags": "node ./scripts/featureflags/index.js"
153
153
  },
154
154
  "peerDependencies": {
155
- "@types/react": "^19.1.0",
156
- "react": "^19.1.0"
155
+ "@types/react": "^19.1.4",
156
+ "react": "^19.1.4"
157
157
  },
158
158
  "peerDependenciesMeta": {
159
159
  "@types/react": {
@@ -162,13 +162,13 @@
162
162
  },
163
163
  "dependencies": {
164
164
  "@jest/create-cache-key-function": "^29.7.0",
165
- "@react-native/assets-registry": "0.81.4",
166
- "@react-native/codegen": "0.81.4",
167
- "@react-native/community-cli-plugin": "0.81.4",
168
- "@react-native/gradle-plugin": "0.81.4",
169
- "@react-native/js-polyfills": "0.81.4",
170
- "@react-native/normalize-colors": "0.81.4",
171
- "@react-native/virtualized-lists": "0.81.4",
165
+ "@react-native/assets-registry": "0.81.6",
166
+ "@react-native/codegen": "0.81.6",
167
+ "@react-native/community-cli-plugin": "0.81.6",
168
+ "@react-native/gradle-plugin": "0.81.6",
169
+ "@react-native/js-polyfills": "0.81.6",
170
+ "@react-native/normalize-colors": "0.81.6",
171
+ "@react-native/virtualized-lists": "0.81.6",
172
172
  "abort-controller": "^3.0.0",
173
173
  "anser": "^1.4.9",
174
174
  "ansi-regex": "^5.0.0",
@@ -71,14 +71,18 @@ function getInputFiles(appPath /*: string */, appPkgJson /*: $FlowFixMe */) {
71
71
  return `[${list}]`;
72
72
  }
73
73
 
74
- function codegenScripts(appPath /*: string */, outputPath /*: string */) {
75
- const relativeAppPath = path.relative(outputPath, appPath);
74
+ function codegenScripts(appPath /*: string */, baseOutputPath /*: string */) {
75
+ const relativeAppPath = path.relative(baseOutputPath, appPath);
76
+ const relativeReactNativeRootFolder = path.relative(
77
+ baseOutputPath,
78
+ REACT_NATIVE_PACKAGE_ROOT_FOLDER,
79
+ );
76
80
  return `<<-SCRIPT
77
81
  pushd "$PODS_ROOT/../" > /dev/null
78
82
  RCT_SCRIPT_POD_INSTALLATION_ROOT=$(pwd)
79
83
  popd >/dev/null
80
84
 
81
- export RCT_SCRIPT_RN_DIR="$RCT_SCRIPT_POD_INSTALLATION_ROOT/${path.relative(outputPath, REACT_NATIVE_PACKAGE_ROOT_FOLDER)}"
85
+ export RCT_SCRIPT_RN_DIR="$RCT_SCRIPT_POD_INSTALLATION_ROOT/${relativeReactNativeRootFolder}"
82
86
  export RCT_SCRIPT_APP_PATH="$RCT_SCRIPT_POD_INSTALLATION_ROOT/${relativeAppPath.length === 0 ? '.' : relativeAppPath}"
83
87
  export RCT_SCRIPT_OUTPUT_DIR="$RCT_SCRIPT_POD_INSTALLATION_ROOT"
84
88
  export RCT_SCRIPT_TYPE="withCodegenDiscovery"
@@ -61,7 +61,7 @@ const path = require('path');
61
61
  function execute(
62
62
  projectRoot /*: string */,
63
63
  targetPlatform /*: string */,
64
- baseOutputPath /*: string */,
64
+ optionalBaseOutputPath /*: ?string */,
65
65
  source /*: string */,
66
66
  runReactNativeCodegen /*: boolean */ = true,
67
67
  ) {
@@ -86,25 +86,35 @@ function execute(
86
86
  buildCodegenIfNeeded();
87
87
  }
88
88
 
89
- const reactNativeConfig = readReactNativeConfig(
90
- projectRoot,
91
- baseOutputPath,
92
- );
93
- const codegenEnabledLibraries = findCodegenEnabledLibraries(
94
- pkgJson,
95
- projectRoot,
96
- baseOutputPath,
97
- reactNativeConfig,
98
- );
99
-
100
- if (codegenEnabledLibraries.length === 0) {
101
- codegenLog('No codegen-enabled libraries found.', true);
102
- }
103
-
104
- let platforms =
89
+ const platforms =
105
90
  targetPlatform === 'all' ? supportedPlatforms : [targetPlatform];
106
91
 
92
+ // NOTE: We cache the external libraries search (which may not run) across platforms to not change previous behaviour
93
+ const externalLibrariesCache /*: { current?: ?Array<$FlowFixMe> } */ = {};
94
+
107
95
  for (const platform of platforms) {
96
+ // NOTE: This needs to be computed per-platform since `platform` can alter the path via a `package.json:codegenConfig.outputDir[platform]` override
97
+ const baseOutputPath = computeBaseOutputPath(
98
+ projectRoot,
99
+ optionalBaseOutputPath,
100
+ pkgJson,
101
+ platform,
102
+ );
103
+ const reactNativeConfig = readReactNativeConfig(
104
+ projectRoot,
105
+ baseOutputPath,
106
+ );
107
+ const codegenEnabledLibraries = findCodegenEnabledLibraries(
108
+ pkgJson,
109
+ projectRoot,
110
+ baseOutputPath,
111
+ reactNativeConfig,
112
+ externalLibrariesCache,
113
+ );
114
+ if (codegenEnabledLibraries.length === 0) {
115
+ codegenLog('No codegen-enabled libraries found.', true);
116
+ }
117
+
108
118
  const disabledLibraries = findDisabledLibrariesByPlatform(
109
119
  reactNativeConfig,
110
120
  platform,
@@ -182,22 +192,38 @@ function readOutputDirFromPkgJson(
182
192
  return null;
183
193
  }
184
194
 
185
- function computeOutputPath(
195
+ function computeBaseOutputPath(
186
196
  projectRoot /*: string */,
187
- baseOutputPath /*: string */,
197
+ optionalBaseOutputPath /*: ?string */,
188
198
  pkgJson /*: $FlowFixMe */,
189
199
  platform /*: string */,
190
200
  ) {
191
- if (baseOutputPath == null) {
201
+ if (
202
+ process.env.RCT_SCRIPT_OUTPUT_DIR != null &&
203
+ process.env.RCT_SCRIPT_OUTPUT_DIR.length > 0
204
+ ) {
205
+ return process.env.RCT_SCRIPT_OUTPUT_DIR;
206
+ }
207
+ let baseOutputPath /*: string */;
208
+ if (optionalBaseOutputPath == null) {
192
209
  const outputDirFromPkgJson = readOutputDirFromPkgJson(pkgJson, platform);
193
210
  if (outputDirFromPkgJson != null) {
194
- // $FlowFixMe[reassign-const]
195
211
  baseOutputPath = path.join(projectRoot, outputDirFromPkgJson);
196
212
  } else {
197
- // $FlowFixMe[reassign-const]
198
213
  baseOutputPath = projectRoot;
199
214
  }
215
+ } else {
216
+ baseOutputPath = optionalBaseOutputPath;
200
217
  }
218
+ return baseOutputPath;
219
+ }
220
+
221
+ function computeOutputPath(
222
+ projectRoot /*: string */,
223
+ baseOutputPath /*: string */,
224
+ pkgJson /*: $FlowFixMe */,
225
+ platform /*: string */,
226
+ ) /*: string */ {
201
227
  if (pkgJsonIncludesGeneratedCode(pkgJson)) {
202
228
  // Don't create nested directories for libraries to make importing generated headers easier.
203
229
  return baseOutputPath;
@@ -98,9 +98,11 @@ function cleanupEmptyFilesAndFolders(filepath /*: string */) {
98
98
  }
99
99
 
100
100
  function readGeneratedAutolinkingOutput(
101
+ projectRoot /*: string */,
101
102
  baseOutputPath /*: string */,
102
103
  ) /*: $FlowFixMe */ {
103
104
  // NOTE: Generated by scripts/cocoapods/autolinking.rb in list_native_modules (called by use_native_modules)
105
+ // The `baseOutputPath` is based on a CLI argument and optional
104
106
  const autolinkingGeneratedPath = path.resolve(
105
107
  baseOutputPath,
106
108
  'build/generated/autolinking/autolinking.json',
@@ -120,7 +122,10 @@ function readReactNativeConfig(
120
122
  projectRoot /*: string */,
121
123
  baseOutputPath /*: string */,
122
124
  ) /*: $FlowFixMe */ {
123
- const autolinkingOutput = readGeneratedAutolinkingOutput(baseOutputPath);
125
+ const autolinkingOutput = readGeneratedAutolinkingOutput(
126
+ projectRoot,
127
+ baseOutputPath,
128
+ );
124
129
  const rnConfigFilePath = path.resolve(projectRoot, 'react-native.config.js');
125
130
  if (autolinkingOutput) {
126
131
  return autolinkingOutput;
@@ -141,6 +146,7 @@ function findCodegenEnabledLibraries(
141
146
  projectRoot /*: string */,
142
147
  baseOutputPath /*: string */,
143
148
  reactNativeConfig /*: $FlowFixMe */,
149
+ externalLibrariesCache /*: { current?: ?Array<$FlowFixMe> } */ = {},
144
150
  ) /*: Array<$FlowFixMe> */ {
145
151
  const projectLibraries = findProjectRootLibraries(pkgJson, projectRoot);
146
152
  if (pkgJsonIncludesGeneratedCode(pkgJson)) {
@@ -149,8 +155,14 @@ function findCodegenEnabledLibraries(
149
155
  const libraries = [...projectLibraries];
150
156
  // If we ran autolinking, we shouldn't try to run our own "autolinking-like"
151
157
  // library discovery
152
- if (!readGeneratedAutolinkingOutput(baseOutputPath)) {
153
- libraries.push(...findExternalLibraries(pkgJson, projectRoot));
158
+ if (!readGeneratedAutolinkingOutput(projectRoot, baseOutputPath)) {
159
+ const externalLibraries =
160
+ externalLibrariesCache.current ??
161
+ (externalLibrariesCache.current = findExternalLibraries(
162
+ pkgJson,
163
+ projectRoot,
164
+ ));
165
+ libraries.push(...externalLibraries);
154
166
  }
155
167
  libraries.push(
156
168
  ...findLibrariesFromReactNativeConfig(projectRoot, reactNativeConfig),
@@ -96,7 +96,7 @@ generateCodegenArtifactsFromSchema () {
96
96
  generateArtifacts () {
97
97
  describe "Generating codegen artifacts"
98
98
  pushd "$RCT_SCRIPT_RN_DIR" >/dev/null || exit 1
99
- "$NODE_BINARY" "scripts/generate-codegen-artifacts.js" --path "$RCT_SCRIPT_APP_PATH" --outputPath "$TEMP_OUTPUT_DIR" --targetPlatform "ios"
99
+ "$NODE_BINARY" "scripts/generate-codegen-artifacts.js" --path "$RCT_SCRIPT_APP_PATH" --outputPath "$RCT_SCRIPT_OUTPUT_DIR" --targetPlatform "ios"
100
100
  popd >/dev/null || exit 1
101
101
  }
102
102
 
@@ -110,11 +110,9 @@ moveOutputs () {
110
110
  }
111
111
 
112
112
  withCodegenDiscovery () {
113
- setup_dirs
114
113
  find_node
115
114
  find_codegen
116
115
  generateArtifacts
117
- moveOutputs
118
116
  }
119
117
 
120
118
  noCodegenDiscovery () {
Binary file
Binary file
Binary file
@@ -62,7 +62,7 @@ Pod::Spec.new do |spec|
62
62
  exit 0
63
63
  fi
64
64
 
65
- cp -R "$HEADERS_PATH/" Headers
65
+ cp -R "$HEADERS_PATH/." Headers
66
66
  mkdir -p framework/packages/react-native
67
67
  cp -R "$XCFRAMEWORK_PATH/../." framework/packages/react-native/
68
68
  find "$XCFRAMEWORK_PATH/.." -type f -exec rm {} +