react-native 0.76.7 → 0.76.8

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 (26) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +1 -1
  2. package/Libraries/Network/FormData.js +11 -3
  3. package/React/Base/RCTVersion.m +1 -1
  4. package/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +1 -7
  5. package/React/Fabric/Surface/RCTFabricSurface.mm +1 -0
  6. package/ReactAndroid/api/ReactAndroid.api +1 -1
  7. package/ReactAndroid/gradle.properties +1 -1
  8. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +3 -1
  9. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/HMRClient.java +4 -1
  10. package/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +13 -8
  11. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +1 -1
  12. package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
  13. package/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +24 -13
  14. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.h +24 -3
  15. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.mm +1 -43
  16. package/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm +4 -5
  17. package/cli.js +11 -2
  18. package/package.json +8 -8
  19. package/react-native.config.js +24 -23
  20. package/sdks/hermesc/linux64-bin/hermesc +0 -0
  21. package/sdks/hermesc/osx-bin/hermes +0 -0
  22. package/sdks/hermesc/osx-bin/hermesc +0 -0
  23. package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
  24. package/sdks/hermesc/win64-bin/msvcp140.dll +0 -0
  25. package/sdks/hermesc/win64-bin/vcruntime140.dll +0 -0
  26. package/sdks/hermesc/win64-bin/vcruntime140_1.dll +0 -0
@@ -16,7 +16,7 @@ const version: $ReadOnly<{
16
16
  }> = {
17
17
  major: 0,
18
18
  minor: 76,
19
- patch: 7,
19
+ patch: 8,
20
20
  prerelease: null,
21
21
  };
22
22
 
@@ -28,6 +28,15 @@ type FormDataPart =
28
28
  ...
29
29
  };
30
30
 
31
+ /**
32
+ * Encode a FormData filename compliant with RFC 2183
33
+ *
34
+ * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#directives
35
+ */
36
+ function encodeFilename(filename: string): string {
37
+ return encodeURIComponent(filename.replace(/\//g, '_'));
38
+ }
39
+
31
40
  /**
32
41
  * Polyfill for XMLHttpRequest2 FormData API, allowing multipart POST requests
33
42
  * with mixed data (string, native files) to be submitted via XMLHttpRequest.
@@ -82,9 +91,8 @@ class FormData {
82
91
  // content type (cf. web Blob interface.)
83
92
  if (typeof value === 'object' && !Array.isArray(value) && value) {
84
93
  if (typeof value.name === 'string') {
85
- headers['content-disposition'] += `; filename="${
86
- value.name
87
- }"; filename*=utf-8''${encodeURI(value.name)}`;
94
+ headers['content-disposition'] +=
95
+ `; filename="${encodeFilename(value.name)}"`;
88
96
  }
89
97
  if (typeof value.type === 'string') {
90
98
  headers['content-type'] = value.type;
@@ -23,7 +23,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
23
23
  __rnVersion = @{
24
24
  RCTVersionMajor: @(0),
25
25
  RCTVersionMinor: @(76),
26
- RCTVersionPatch: @(7),
26
+ RCTVersionPatch: @(8),
27
27
  RCTVersionPrerelease: [NSNull null],
28
28
  };
29
29
  });
@@ -99,11 +99,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
99
99
  NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
100
100
  [_backedTextInputView.defaultTextAttributes mutableCopy];
101
101
 
102
- #if !TARGET_OS_MACCATALYST
103
- RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
104
- eventEmitterWrapper.eventEmitter = _eventEmitter;
105
- defaultAttributes[RCTAttributedStringEventEmitterKey] = eventEmitterWrapper;
106
- #endif
102
+ defaultAttributes[RCTAttributedStringEventEmitterKey] = RCTWrapEventEmitter(_eventEmitter);
107
103
 
108
104
  _backedTextInputView.defaultTextAttributes = defaultAttributes;
109
105
  }
@@ -263,10 +259,8 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
263
259
  if (newTextInputProps.textAttributes != oldTextInputProps.textAttributes) {
264
260
  NSMutableDictionary<NSAttributedStringKey, id> *defaultAttributes =
265
261
  RCTNSTextAttributesFromTextAttributes(newTextInputProps.getEffectiveTextAttributes(RCTFontSizeMultiplier()));
266
- #if !TARGET_OS_MACCATALYST
267
262
  defaultAttributes[RCTAttributedStringEventEmitterKey] =
268
263
  _backedTextInputView.defaultTextAttributes[RCTAttributedStringEventEmitterKey];
269
- #endif
270
264
  _backedTextInputView.defaultTextAttributes = defaultAttributes;
271
265
  }
272
266
 
@@ -142,6 +142,7 @@ using namespace facebook::react;
142
142
 
143
143
  if (!_view) {
144
144
  _view = [[RCTSurfaceView alloc] initWithSurface:(RCTSurface *)self];
145
+ [self _updateLayoutContext];
145
146
  _touchHandler = [RCTSurfaceTouchHandler new];
146
147
  [_touchHandler attachToView:_view];
147
148
  }
@@ -2248,7 +2248,7 @@ public abstract interface class com/facebook/react/devsupport/HMRClient : com/fa
2248
2248
  public abstract fun disable ()V
2249
2249
  public abstract fun enable ()V
2250
2250
  public abstract fun registerBundle (Ljava/lang/String;)V
2251
- public abstract fun setup (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZ)V
2251
+ public abstract fun setup (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZLjava/lang/String;)V
2252
2252
  }
2253
2253
 
2254
2254
  public final class com/facebook/react/devsupport/InspectorFlags {
@@ -1,4 +1,4 @@
1
- VERSION_NAME=0.76.7
1
+ VERSION_NAME=0.76.8
2
2
  react.internal.publishingGroup=com.facebook.react
3
3
 
4
4
  android.useAndroidX=true
@@ -696,10 +696,12 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
696
696
  URL sourceUrl = new URL(getSourceUrl());
697
697
  String path = sourceUrl.getPath().substring(1); // strip initial slash in path
698
698
  String host = sourceUrl.getHost();
699
+ String scheme = sourceUrl.getProtocol();
699
700
  int port = sourceUrl.getPort() != -1 ? sourceUrl.getPort() : sourceUrl.getDefaultPort();
700
701
  mCurrentContext
701
702
  .getJSModule(HMRClient.class)
702
- .setup("android", path, host, port, mDevSettings.isHotModuleReplacementEnabled());
703
+ .setup(
704
+ "android", path, host, port, mDevSettings.isHotModuleReplacementEnabled(), scheme);
703
705
  } catch (MalformedURLException e) {
704
706
  showNewJavaError(e.getMessage(), e);
705
707
  }
@@ -26,8 +26,11 @@ public interface HMRClient extends JavaScriptModule {
26
26
  * @param host The host that the HMRClient should communicate with.
27
27
  * @param port The port that the HMRClient should communicate with on the host.
28
28
  * @param isEnabled Whether HMR is enabled initially.
29
+ * @param scheme The protocol that the HMRClient should communicate with on the host (defaults to
30
+ * http).
29
31
  */
30
- void setup(String platform, String bundleEntry, String host, int port, boolean isEnabled);
32
+ void setup(
33
+ String platform, String bundleEntry, String host, int port, boolean isEnabled, String scheme);
31
34
 
32
35
  /** Registers an additional JS bundle with HMRClient. */
33
36
  void registerBundle(String bundleUrl);
@@ -172,7 +172,7 @@ public class FabricUIManager
172
172
  private final CopyOnWriteArrayList<UIManagerListener> mListeners = new CopyOnWriteArrayList<>();
173
173
 
174
174
  private boolean mMountNotificationScheduled = false;
175
- private final List<Integer> mMountedSurfaceIds = new ArrayList<>();
175
+ private List<Integer> mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
176
176
 
177
177
  @ThreadConfined(UI)
178
178
  @NonNull
@@ -1257,12 +1257,15 @@ public class FabricUIManager
1257
1257
 
1258
1258
  // Collect surface IDs for all the mount items
1259
1259
  for (MountItem mountItem : mountItems) {
1260
- if (mountItem != null && !mMountedSurfaceIds.contains(mountItem.getSurfaceId())) {
1261
- mMountedSurfaceIds.add(mountItem.getSurfaceId());
1260
+ if (mountItem != null
1261
+ && !mSurfaceIdsWithPendingMountNotification.contains(mountItem.getSurfaceId())) {
1262
+ mSurfaceIdsWithPendingMountNotification.add(mountItem.getSurfaceId());
1262
1263
  }
1263
1264
  }
1264
1265
 
1265
- if (!mMountNotificationScheduled && !mMountedSurfaceIds.isEmpty()) {
1266
+ if (!mMountNotificationScheduled && !mSurfaceIdsWithPendingMountNotification.isEmpty()) {
1267
+ mMountNotificationScheduled = true;
1268
+
1266
1269
  // Notify mount when the effects are visible and prevent mount hooks to
1267
1270
  // delay paint.
1268
1271
  UiThreadUtil.getUiThreadHandler()
@@ -1272,17 +1275,19 @@ public class FabricUIManager
1272
1275
  public void run() {
1273
1276
  mMountNotificationScheduled = false;
1274
1277
 
1278
+ // Create a copy in case mount hooks trigger more mutations
1279
+ final List<Integer> surfaceIdsToReportMount =
1280
+ mSurfaceIdsWithPendingMountNotification;
1281
+ mSurfaceIdsWithPendingMountNotification = new ArrayList<>();
1282
+
1275
1283
  final @Nullable Binding binding = mBinding;
1276
1284
  if (binding == null || mDestroyed) {
1277
- mMountedSurfaceIds.clear();
1278
1285
  return;
1279
1286
  }
1280
1287
 
1281
- for (int surfaceId : mMountedSurfaceIds) {
1288
+ for (int surfaceId : surfaceIdsToReportMount) {
1282
1289
  binding.reportMount(surfaceId);
1283
1290
  }
1284
-
1285
- mMountedSurfaceIds.clear();
1286
1291
  }
1287
1292
  });
1288
1293
  }
@@ -17,6 +17,6 @@ public class ReactNativeVersion {
17
17
  public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
18
18
  "major", 0,
19
19
  "minor", 76,
20
- "patch", 7,
20
+ "patch", 8,
21
21
  "prerelease", null);
22
22
  }
@@ -17,7 +17,7 @@ namespace facebook::react {
17
17
  constexpr struct {
18
18
  int32_t Major = 0;
19
19
  int32_t Minor = 76;
20
- int32_t Patch = 7;
20
+ int32_t Patch = 8;
21
21
  std::string_view Prerelease = "";
22
22
  } ReactNativeVersion;
23
23
 
@@ -57,7 +57,7 @@ static jsi::Value convertNSNumberToJSINumber(jsi::Runtime &runtime, NSNumber *va
57
57
 
58
58
  static jsi::String convertNSStringToJSIString(jsi::Runtime &runtime, NSString *value)
59
59
  {
60
- return jsi::String::createFromUtf8(runtime, [value UTF8String] ?: "");
60
+ return jsi::String::createFromUtf8(runtime, [value UTF8String] ? [value UTF8String] : "");
61
61
  }
62
62
 
63
63
  static jsi::Object convertNSDictionaryToJSIObject(jsi::Runtime &runtime, NSDictionary *value)
@@ -195,7 +195,11 @@ static jsi::Value createJSRuntimeError(jsi::Runtime &runtime, const std::string
195
195
  /**
196
196
  * Creates JSError with current JS runtime and NSException stack trace.
197
197
  */
198
- static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSException *exception)
198
+ static jsi::JSError convertNSExceptionToJSError(
199
+ jsi::Runtime &runtime,
200
+ NSException *exception,
201
+ const std::string &moduleName,
202
+ const std::string &methodName)
199
203
  {
200
204
  std::string reason = [exception.reason UTF8String];
201
205
 
@@ -206,7 +210,8 @@ static jsi::JSError convertNSExceptionToJSError(jsi::Runtime &runtime, NSExcepti
206
210
  cause.setProperty(
207
211
  runtime, "stackReturnAddresses", convertNSArrayToJSIArray(runtime, exception.callStackReturnAddresses));
208
212
 
209
- jsi::Value error = createJSRuntimeError(runtime, "Exception in HostFunction: " + reason);
213
+ std::string message = moduleName + "." + methodName + " raised an exception: " + reason;
214
+ jsi::Value error = createJSRuntimeError(runtime, message);
210
215
  error.asObject(runtime).setProperty(runtime, "cause", std::move(cause));
211
216
  return {runtime, std::move(error)};
212
217
  }
@@ -338,28 +343,34 @@ id ObjCTurboModule::performMethodInvocation(
338
343
  }
339
344
 
340
345
  if (isSync) {
341
- TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
346
+ TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
342
347
  } else {
343
- TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
348
+ TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
344
349
  }
345
350
 
346
351
  @try {
347
352
  [inv invokeWithTarget:strongModule];
348
353
  } @catch (NSException *exception) {
349
- throw convertNSExceptionToJSError(runtime, exception);
354
+ if (isSync) {
355
+ // We can only convert NSException to JSError in sync method calls.
356
+ // See https://github.com/reactwg/react-native-new-architecture/discussions/276#discussioncomment-12567155
357
+ throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
358
+ } else {
359
+ @throw exception;
360
+ }
350
361
  } @finally {
351
362
  [retainedObjectsForInvocation removeAllObjects];
352
363
  }
353
364
 
354
365
  if (!isSync) {
355
- TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
366
+ TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
356
367
  return;
357
368
  }
358
369
 
359
370
  void *rawResult;
360
371
  [inv getReturnValue:&rawResult];
361
372
  result = (__bridge id)rawResult;
362
- TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
373
+ TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
363
374
  };
364
375
 
365
376
  if (isSync) {
@@ -401,23 +412,23 @@ void ObjCTurboModule::performVoidMethodInvocation(
401
412
  }
402
413
 
403
414
  if (shouldVoidMethodsExecuteSync_) {
404
- TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
415
+ TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
405
416
  } else {
406
- TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
417
+ TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, asyncCallCounter);
407
418
  }
408
419
 
409
420
  @try {
410
421
  [inv invokeWithTarget:strongModule];
411
422
  } @catch (NSException *exception) {
412
- throw convertNSExceptionToJSError(runtime, exception);
423
+ throw convertNSExceptionToJSError(runtime, exception, std::string{moduleName}, methodNameStr);
413
424
  } @finally {
414
425
  [retainedObjectsForInvocation removeAllObjects];
415
426
  }
416
427
 
417
428
  if (shouldVoidMethodsExecuteSync_) {
418
- TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
429
+ TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
419
430
  } else {
420
- TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
431
+ TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, asyncCallCounter);
421
432
  }
422
433
 
423
434
  return;
@@ -52,8 +52,29 @@ BOOL RCTIsAttributedStringEffectivelySame(
52
52
  NSDictionary<NSAttributedStringKey, id> *insensitiveAttributes,
53
53
  const facebook::react::TextAttributes &baseTextAttributes);
54
54
 
55
- @interface RCTWeakEventEmitterWrapper : NSObject
56
- @property (nonatomic, assign) facebook::react::SharedEventEmitter eventEmitter;
57
- @end
55
+ static inline NSData *RCTWrapEventEmitter(const facebook::react::SharedEventEmitter &eventEmitter)
56
+ {
57
+ auto eventEmitterPtr = new std::weak_ptr<const facebook::react::EventEmitter>(eventEmitter);
58
+ return [[NSData alloc] initWithBytesNoCopy:eventEmitterPtr
59
+ length:sizeof(eventEmitterPtr)
60
+ deallocator:^(void *ptrToDelete, NSUInteger) {
61
+ delete (std::weak_ptr<facebook::react::EventEmitter> *)ptrToDelete;
62
+ }];
63
+ }
64
+
65
+ static inline facebook::react::SharedEventEmitter RCTUnwrapEventEmitter(NSData *data)
66
+ {
67
+ if (data.length == 0) {
68
+ return nullptr;
69
+ }
70
+
71
+ auto weakPtr = dynamic_cast<std::weak_ptr<const facebook::react::EventEmitter> *>(
72
+ (std::weak_ptr<const facebook::react::EventEmitter> *)data.bytes);
73
+ if (weakPtr) {
74
+ return weakPtr->lock();
75
+ }
76
+
77
+ return nullptr;
78
+ }
58
79
 
59
80
  NS_ASSUME_NONNULL_END
@@ -16,45 +16,6 @@
16
16
 
17
17
  using namespace facebook::react;
18
18
 
19
- @implementation RCTWeakEventEmitterWrapper {
20
- std::weak_ptr<const EventEmitter> _weakEventEmitter;
21
- }
22
-
23
- - (void)setEventEmitter:(SharedEventEmitter)eventEmitter
24
- {
25
- _weakEventEmitter = eventEmitter;
26
- }
27
-
28
- - (SharedEventEmitter)eventEmitter
29
- {
30
- return _weakEventEmitter.lock();
31
- }
32
-
33
- - (void)dealloc
34
- {
35
- _weakEventEmitter.reset();
36
- }
37
-
38
- - (BOOL)isEqual:(id)object
39
- {
40
- // We consider the underlying EventEmitter as the identity
41
- if (![object isKindOfClass:[self class]]) {
42
- return NO;
43
- }
44
-
45
- auto thisEventEmitter = [self eventEmitter];
46
- auto otherEventEmitter = [((RCTWeakEventEmitterWrapper *)object) eventEmitter];
47
- return thisEventEmitter == otherEventEmitter;
48
- }
49
-
50
- - (NSUInteger)hash
51
- {
52
- // We consider the underlying EventEmitter as the identity
53
- return (NSUInteger)_weakEventEmitter.lock().get();
54
- }
55
-
56
- @end
57
-
58
19
  inline static UIFontWeight RCTUIFontWeightFromInteger(NSInteger fontWeight)
59
20
  {
60
21
  assert(fontWeight > 50);
@@ -405,10 +366,8 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
405
366
  {
406
367
  auto nsAttributedStringFragment = RCTNSAttributedStringFragmentFromFragment(fragment, placeholderImage);
407
368
 
408
- #if !TARGET_OS_MACCATALYST
409
369
  if (fragment.parentShadowView.componentHandle) {
410
- RCTWeakEventEmitterWrapper *eventEmitterWrapper = [RCTWeakEventEmitterWrapper new];
411
- eventEmitterWrapper.eventEmitter = fragment.parentShadowView.eventEmitter;
370
+ auto eventEmitterWrapper = RCTWrapEventEmitter(fragment.parentShadowView.eventEmitter);
412
371
 
413
372
  NSDictionary<NSAttributedStringKey, id> *additionalTextAttributes =
414
373
  @{RCTAttributedStringEventEmitterKey : eventEmitterWrapper};
@@ -416,7 +375,6 @@ static NSMutableAttributedString *RCTNSAttributedStringFragmentWithAttributesFro
416
375
  [nsAttributedStringFragment addAttributes:additionalTextAttributes
417
376
  range:NSMakeRange(0, nsAttributedStringFragment.length)];
418
377
  }
419
- #endif
420
378
 
421
379
  return nsAttributedStringFragment;
422
380
  }
@@ -280,11 +280,10 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
280
280
  // after (fraction == 1.0) the last character, then the attribute is valid.
281
281
  if (textStorage.length > 0 && (fraction > 0 || characterIndex > 0) &&
282
282
  (fraction < 1 || characterIndex < textStorage.length - 1)) {
283
- RCTWeakEventEmitterWrapper *eventEmitterWrapper =
284
- (RCTWeakEventEmitterWrapper *)[textStorage attribute:RCTAttributedStringEventEmitterKey
285
- atIndex:characterIndex
286
- effectiveRange:NULL];
287
- return eventEmitterWrapper.eventEmitter;
283
+ NSData *eventEmitterWrapper = (NSData *)[textStorage attribute:RCTAttributedStringEventEmitterKey
284
+ atIndex:characterIndex
285
+ effectiveRange:NULL];
286
+ return RCTUnwrapEventEmitter(eventEmitterWrapper);
288
287
  }
289
288
 
290
289
  return nil;
package/cli.js CHANGED
@@ -23,6 +23,15 @@ const deprecated = () => {
23
23
  );
24
24
  };
25
25
 
26
+ function findCommunityCli(startDir = process.cwd()) {
27
+ // With isolated node_modules (eg pnpm), we won't be able to find
28
+ // `@react-native-community/cli` starting from the `react-native` directory.
29
+ // Instead, we should use the project root, which we assume to be the cwd.
30
+ const options = {paths: [startDir]};
31
+ const rncli = require.resolve('@react-native-community/cli', options);
32
+ return require(rncli);
33
+ }
34
+
26
35
  function isMissingCliDependency(error) {
27
36
  return (
28
37
  error.code === 'MODULE_NOT_FOUND' &&
@@ -217,7 +226,7 @@ async function main() {
217
226
  }
218
227
 
219
228
  try {
220
- return require('@react-native-community/cli').run(name);
229
+ return findCommunityCli().run(name);
221
230
  } catch (e) {
222
231
  if (isMissingCliDependency(e)) {
223
232
  warnWithExplicitDependency();
@@ -231,7 +240,7 @@ if (require.main === module) {
231
240
  main();
232
241
  } else {
233
242
  try {
234
- cli = require('@react-native-community/cli');
243
+ cli = findCommunityCli();
235
244
  } catch (e) {
236
245
  // We silence @react-native-community/cli missing as it is no
237
246
  // longer a dependency
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native",
3
- "version": "0.76.7",
3
+ "version": "0.76.8",
4
4
  "description": "A framework for building native apps using React",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -109,13 +109,13 @@
109
109
  },
110
110
  "dependencies": {
111
111
  "@jest/create-cache-key-function": "^29.6.3",
112
- "@react-native/assets-registry": "0.76.7",
113
- "@react-native/codegen": "0.76.7",
114
- "@react-native/community-cli-plugin": "0.76.7",
115
- "@react-native/gradle-plugin": "0.76.7",
116
- "@react-native/js-polyfills": "0.76.7",
117
- "@react-native/normalize-colors": "0.76.7",
118
- "@react-native/virtualized-lists": "0.76.7",
112
+ "@react-native/assets-registry": "0.76.8",
113
+ "@react-native/codegen": "0.76.8",
114
+ "@react-native/community-cli-plugin": "0.76.8",
115
+ "@react-native/gradle-plugin": "0.76.8",
116
+ "@react-native/js-polyfills": "0.76.8",
117
+ "@react-native/normalize-colors": "0.76.8",
118
+ "@react-native/virtualized-lists": "0.76.8",
119
119
  "abort-controller": "^3.0.0",
120
120
  "anser": "^1.4.9",
121
121
  "ansi-regex": "^5.0.0",
@@ -20,9 +20,24 @@
20
20
 
21
21
  const verbose = process.env.DEBUG && process.env.DEBUG.includes('react-native');
22
22
 
23
+ function findCommunityPlatformPackage(spec, startDir = process.cwd()) {
24
+ // In monorepos, we cannot make any assumptions on where
25
+ // `@react-native-community/*` gets installed. The safest way to find it
26
+ // (barring adding an optional peer dependency) is to start from the project
27
+ // root.
28
+ //
29
+ // Note that we're assuming that the current working directory is the project
30
+ // root. This is also what `@react-native-community/cli` assumes (see
31
+ // https://github.com/react-native-community/cli/blob/14.x/packages/cli-tools/src/findProjectRoot.ts).
32
+ const main = require.resolve(spec, {paths: [startDir]});
33
+ return require(main);
34
+ }
35
+
23
36
  let android;
24
37
  try {
25
- android = require('@react-native-community/cli-platform-android');
38
+ android = findCommunityPlatformPackage(
39
+ '@react-native-community/cli-platform-android',
40
+ );
26
41
  } catch {
27
42
  if (verbose) {
28
43
  console.warn(
@@ -33,7 +48,9 @@ try {
33
48
 
34
49
  let ios;
35
50
  try {
36
- ios = require('@react-native-community/cli-platform-ios');
51
+ ios = findCommunityPlatformPackage(
52
+ '@react-native-community/cli-platform-ios',
53
+ );
37
54
  } catch {
38
55
  if (verbose) {
39
56
  console.warn(
@@ -44,27 +61,11 @@ try {
44
61
 
45
62
  const commands = [];
46
63
 
47
- try {
48
- const {
49
- bundleCommand,
50
- startCommand,
51
- } = require('@react-native/community-cli-plugin');
52
- commands.push(bundleCommand, startCommand);
53
- } catch (e) {
54
- const known =
55
- e.code === 'MODULE_NOT_FOUND' &&
56
- e.message.includes('@react-native-community/cli-server-api');
57
-
58
- if (!known) {
59
- throw e;
60
- }
61
-
62
- if (verbose) {
63
- console.warn(
64
- '@react-native-community/cli-server-api not found, the react-native.config.js may be unusable.',
65
- );
66
- }
67
- }
64
+ const {
65
+ bundleCommand,
66
+ startCommand,
67
+ } = require('@react-native/community-cli-plugin');
68
+ commands.push(bundleCommand, startCommand);
68
69
 
69
70
  const codegenCommand = {
70
71
  name: 'codegen',
Binary file
Binary file
Binary file
Binary file
Binary file