react-native 0.85.2 → 0.85.3

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 (108) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +1 -1
  2. package/Libraries/Utilities/HMRClient.js +28 -1
  3. package/React/Base/RCTVersion.m +1 -1
  4. package/React/CoreModules/RCTJscSafeUrl+Internal.h +23 -0
  5. package/React/CoreModules/RCTJscSafeUrl.mm +38 -0
  6. package/React/CoreModules/RCTRedBox+Internal.h +42 -0
  7. package/React/CoreModules/RCTRedBox.mm +30 -454
  8. package/React/CoreModules/RCTRedBox2AnsiParser+Internal.h +22 -0
  9. package/React/CoreModules/RCTRedBox2AnsiParser.mm +55 -0
  10. package/React/CoreModules/RCTRedBox2Controller+Internal.h +34 -0
  11. package/React/CoreModules/RCTRedBox2Controller.mm +764 -0
  12. package/React/CoreModules/RCTRedBox2ErrorParser+Internal.h +46 -0
  13. package/React/CoreModules/RCTRedBox2ErrorParser.mm +57 -0
  14. package/React/CoreModules/RCTRedBoxController+Internal.h +31 -0
  15. package/React/CoreModules/RCTRedBoxController.mm +447 -0
  16. package/React/CoreModules/RCTRedBoxHMRClient+Internal.h +26 -0
  17. package/React/CoreModules/RCTRedBoxHMRClient.mm +125 -0
  18. package/React/CoreModules/React-CoreModules.podspec +1 -0
  19. package/React/DevSupport/RCTFrameTimingsObserver.h +24 -0
  20. package/React/DevSupport/RCTFrameTimingsObserver.mm +298 -0
  21. package/React/FBReactNativeSpec/FBReactNativeSpecJSI.h +40 -0
  22. package/ReactAndroid/gradle.properties +1 -1
  23. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/InspectorFlags.kt +4 -0
  24. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingSequence.kt +1 -1
  25. package/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt +127 -26
  26. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +31 -1
  27. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +51 -1
  28. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +11 -1
  29. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +11 -1
  30. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +56 -1
  31. package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +11 -1
  32. package/ReactAndroid/src/main/java/com/facebook/react/internal/tracing/PerformanceTracer.kt +39 -0
  33. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
  34. package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +50 -10
  35. package/ReactAndroid/src/main/jni/CMakeLists.txt +7 -0
  36. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.cpp +22 -0
  37. package/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.h +2 -0
  38. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +71 -1
  39. package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +16 -1
  40. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.cpp +14 -0
  41. package/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h +18 -4
  42. package/ReactCommon/React-Fabric.podspec +6 -0
  43. package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
  44. package/ReactCommon/jsinspector-modern/HostAgent.cpp +36 -0
  45. package/ReactCommon/jsinspector-modern/HostTarget.cpp +7 -1
  46. package/ReactCommon/jsinspector-modern/HostTarget.h +25 -0
  47. package/ReactCommon/jsinspector-modern/HostTargetTracing.cpp +1 -1
  48. package/ReactCommon/jsinspector-modern/HostTargetTracing.h +4 -4
  49. package/ReactCommon/jsinspector-modern/InspectorFlags.cpp +12 -0
  50. package/ReactCommon/jsinspector-modern/InspectorFlags.h +12 -0
  51. package/ReactCommon/jsinspector-modern/NetworkIOAgent.cpp +1 -1
  52. package/ReactCommon/jsinspector-modern/RuntimeAgent.cpp +19 -0
  53. package/ReactCommon/jsinspector-modern/RuntimeAgent.h +7 -0
  54. package/ReactCommon/jsinspector-modern/RuntimeTarget.cpp +33 -0
  55. package/ReactCommon/jsinspector-modern/RuntimeTarget.h +6 -0
  56. package/ReactCommon/jsinspector-modern/tests/HostTargetTest.cpp +12 -0
  57. package/ReactCommon/jsinspector-modern/tests/InspectorMocks.h +3 -2
  58. package/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp +1 -0
  59. package/ReactCommon/jsinspector-modern/tests/NetworkReporterTest.cpp +1 -1
  60. package/ReactCommon/jsinspector-modern/tests/TracingTest.cpp +1 -1
  61. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.cpp +10 -0
  62. package/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h +3 -1
  63. package/ReactCommon/jsinspector-modern/tracing/CMakeLists.txt +1 -0
  64. package/ReactCommon/jsinspector-modern/tracing/FrameTimingSequence.h +7 -3
  65. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.cpp +52 -29
  66. package/ReactCommon/jsinspector-modern/tracing/HostTracingProfileSerializer.h +6 -6
  67. package/ReactCommon/jsinspector-modern/tracing/PerformanceTracerSection.h +113 -0
  68. package/ReactCommon/jsinspector-modern/tracing/React-jsinspectortracing.podspec +1 -0
  69. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.cpp +12 -5
  70. package/ReactCommon/jsinspector-modern/tracing/TraceEventGenerator.h +3 -1
  71. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.cpp +42 -0
  72. package/ReactCommon/jsinspector-modern/tracing/TraceEventSerializer.h +7 -0
  73. package/ReactCommon/react/debug/CMakeLists.txt +2 -1
  74. package/ReactCommon/react/debug/React-debug.podspec +7 -1
  75. package/ReactCommon/react/debug/redbox/AnsiParser.cpp +139 -0
  76. package/ReactCommon/react/debug/redbox/AnsiParser.h +35 -0
  77. package/ReactCommon/react/debug/redbox/JscSafeUrl.cpp +179 -0
  78. package/ReactCommon/react/debug/redbox/JscSafeUrl.h +27 -0
  79. package/ReactCommon/react/debug/redbox/RedBoxErrorParser.cpp +171 -0
  80. package/ReactCommon/react/debug/redbox/RedBoxErrorParser.h +40 -0
  81. package/ReactCommon/react/debug/redbox/tests/AnsiParserTest.cpp +97 -0
  82. package/ReactCommon/react/debug/redbox/tests/JscSafeUrlTest.cpp +173 -0
  83. package/ReactCommon/react/debug/redbox/tests/RedBoxErrorParserTest.cpp +107 -0
  84. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +21 -1
  85. package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +26 -1
  86. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +135 -45
  87. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +12 -2
  88. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +21 -1
  89. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +46 -1
  90. package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +6 -1
  91. package/ReactCommon/react/nativemodule/defaults/CMakeLists.txt +1 -0
  92. package/ReactCommon/react/nativemodule/defaults/DefaultTurboModules.cpp +7 -0
  93. package/ReactCommon/react/nativemodule/defaults/React-defaultsnativemodule.podspec +1 -0
  94. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +26 -1
  95. package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +11 -1
  96. package/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.h +4 -0
  97. package/ReactCommon/react/nativemodule/mutationobserver/React-mutationobservernativemodule.podspec +66 -0
  98. package/ReactCommon/react/performance/timeline/PerformanceObserver.cpp +18 -6
  99. package/ReactCommon/react/performance/timeline/PerformanceObserver.h +2 -0
  100. package/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +115 -0
  101. package/ReactCommon/{jsinspector-modern → react/utils}/Base64.h +2 -2
  102. package/package.json +11 -11
  103. package/scripts/cocoapods/utils.rb +1 -0
  104. package/scripts/react_native_pods.rb +1 -0
  105. package/scripts/replace-rncore-version.js +72 -15
  106. package/src/private/featureflags/ReactNativeFeatureFlags.js +26 -1
  107. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +6 -1
  108. package/src/private/setup/setUpDefaultReactNativeEnvironment.js +6 -0
@@ -0,0 +1,40 @@
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
+ #pragma once
9
+
10
+ #include <optional>
11
+ #include <string>
12
+
13
+ namespace facebook::react::unstable_redbox {
14
+
15
+ struct CodeFrame {
16
+ std::string content;
17
+ std::string fileName;
18
+ int row = 0;
19
+ int column = 0;
20
+ };
21
+
22
+ struct ParsedError {
23
+ std::string title;
24
+ std::string message;
25
+ std::optional<CodeFrame> codeFrame;
26
+ bool isCompileError = false;
27
+ bool isRetryable = true;
28
+ };
29
+
30
+ /**
31
+ * Parse a raw error message into structured components.
32
+ * C++ port of parseLogBoxException from parseLogBoxLog.js.
33
+ */
34
+ ParsedError parseErrorMessage(
35
+ const std::string &message,
36
+ const std::string &name = "",
37
+ const std::string &componentStack = "",
38
+ bool isFatal = true);
39
+
40
+ } // namespace facebook::react::unstable_redbox
@@ -0,0 +1,97 @@
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
+ #include <react/debug/redbox/AnsiParser.h>
10
+
11
+ using namespace facebook::react::unstable_redbox;
12
+
13
+ TEST(AnsiParserTest, ParsesPlainText) {
14
+ auto spans = parseAnsi("hello world");
15
+ ASSERT_EQ(spans.size(), 1);
16
+ EXPECT_EQ(spans[0].text, "hello world");
17
+ EXPECT_FALSE(spans[0].foregroundColor.has_value());
18
+ EXPECT_FALSE(spans[0].backgroundColor.has_value());
19
+ }
20
+
21
+ TEST(AnsiParserTest, ParsesRedForeground) {
22
+ auto spans = parseAnsi("\x1b[31mred text\x1b[0m normal");
23
+ ASSERT_EQ(spans.size(), 2);
24
+ EXPECT_EQ(spans[0].text, "red text");
25
+ ASSERT_TRUE(spans[0].foregroundColor.has_value());
26
+ EXPECT_EQ(spans[0].foregroundColor->r, 187);
27
+ EXPECT_EQ(spans[0].foregroundColor->g, 86);
28
+ EXPECT_EQ(spans[0].foregroundColor->b, 83);
29
+
30
+ EXPECT_EQ(spans[1].text, " normal");
31
+ EXPECT_FALSE(spans[1].foregroundColor.has_value());
32
+ }
33
+
34
+ TEST(AnsiParserTest, ParsesMultipleColors) {
35
+ auto spans = parseAnsi("\x1b[32mgreen\x1b[34mblue\x1b[0m");
36
+ ASSERT_EQ(spans.size(), 2);
37
+ EXPECT_EQ(spans[0].text, "green");
38
+ EXPECT_EQ(spans[0].foregroundColor->r, 144);
39
+ EXPECT_EQ(spans[1].text, "blue");
40
+ EXPECT_EQ(spans[1].foregroundColor->r, 125);
41
+ }
42
+
43
+ TEST(AnsiParserTest, ParsesBrightColors) {
44
+ auto spans = parseAnsi("\x1b[93myellow\x1b[0m");
45
+ ASSERT_EQ(spans.size(), 1);
46
+ EXPECT_EQ(spans[0].text, "yellow");
47
+ ASSERT_TRUE(spans[0].foregroundColor.has_value());
48
+ EXPECT_EQ(spans[0].foregroundColor->r, 234);
49
+ }
50
+
51
+ TEST(AnsiParserTest, ParsesBackgroundColor) {
52
+ auto spans = parseAnsi("\x1b[41mred bg\x1b[0m");
53
+ ASSERT_EQ(spans.size(), 1);
54
+ EXPECT_EQ(spans[0].text, "red bg");
55
+ EXPECT_FALSE(spans[0].foregroundColor.has_value());
56
+ ASSERT_TRUE(spans[0].backgroundColor.has_value());
57
+ EXPECT_EQ(spans[0].backgroundColor->r, 187);
58
+ EXPECT_EQ(spans[0].backgroundColor->g, 86);
59
+ EXPECT_EQ(spans[0].backgroundColor->b, 83);
60
+ }
61
+
62
+ TEST(AnsiParserTest, ResetClearsBackground) {
63
+ auto spans = parseAnsi("\x1b[31;42mcolored\x1b[49mfg only\x1b[0m");
64
+ ASSERT_EQ(spans.size(), 2);
65
+ ASSERT_TRUE(spans[0].foregroundColor.has_value());
66
+ ASSERT_TRUE(spans[0].backgroundColor.has_value());
67
+ ASSERT_TRUE(spans[1].foregroundColor.has_value());
68
+ EXPECT_FALSE(spans[1].backgroundColor.has_value());
69
+ }
70
+
71
+ TEST(AnsiParserTest, ResetShorthandClearsColors) {
72
+ auto spans = parseAnsi("\x1b[31mred\x1b[mplain");
73
+ ASSERT_EQ(spans.size(), 2);
74
+ EXPECT_EQ(spans[0].text, "red");
75
+ ASSERT_TRUE(spans[0].foregroundColor.has_value());
76
+ EXPECT_EQ(spans[1].text, "plain");
77
+ EXPECT_FALSE(spans[1].foregroundColor.has_value());
78
+ EXPECT_FALSE(spans[1].backgroundColor.has_value());
79
+ }
80
+
81
+ TEST(AnsiParserTest, StripsAnsi) {
82
+ auto result = stripAnsi("\x1b[31mred\x1b[0m and \x1b[32mgreen\x1b[0m");
83
+ EXPECT_EQ(result, "red and green");
84
+ }
85
+
86
+ TEST(AnsiParserTest, HandlesEmptyString) {
87
+ auto spans = parseAnsi("");
88
+ EXPECT_TRUE(spans.empty());
89
+ }
90
+
91
+ TEST(AnsiParserTest, HandlesSemicolonSeparatedCodes) {
92
+ auto spans = parseAnsi("\x1b[1;31mtext\x1b[0m");
93
+ ASSERT_EQ(spans.size(), 1);
94
+ EXPECT_EQ(spans[0].text, "text");
95
+ ASSERT_TRUE(spans[0].foregroundColor.has_value());
96
+ EXPECT_EQ(spans[0].foregroundColor->r, 187);
97
+ }
@@ -0,0 +1,173 @@
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
+ #include <react/debug/redbox/JscSafeUrl.h>
10
+
11
+ using namespace facebook::react::unstable_redbox;
12
+
13
+ // --- toNormalUrl ---
14
+
15
+ // Rewrites urls treating //& in paths as ?
16
+ TEST(JscSafeUrlTest, ToNormalUrl_RewritesMarkerInAbsolutePath) {
17
+ EXPECT_EQ(
18
+ toNormalUrl("/path1/path2//&foo=bar?bar=baz#frag?"),
19
+ "/path1/path2?foo=bar&bar=baz#frag?");
20
+ // Idempotent
21
+ EXPECT_EQ(
22
+ toNormalUrl("/path1/path2?foo=bar&bar=baz#frag?"),
23
+ "/path1/path2?foo=bar&bar=baz#frag?");
24
+ }
25
+
26
+ TEST(JscSafeUrlTest, ToNormalUrl_RewritesMarkerInRelativePathWithEncoding) {
27
+ EXPECT_EQ(
28
+ toNormalUrl("relative/path/with%3B%26/encoded//&foo=bar?bar=baz#frag?"),
29
+ "relative/path/with%3B%26/encoded?foo=bar&bar=baz#frag?");
30
+ EXPECT_EQ(
31
+ toNormalUrl("relative/path/with%3B%26/encoded?foo=bar&bar=baz#frag?"),
32
+ "relative/path/with%3B%26/encoded?foo=bar&bar=baz#frag?");
33
+ }
34
+
35
+ TEST(JscSafeUrlTest, ToNormalUrl_RewritesMarkerInFullUrl) {
36
+ EXPECT_EQ(
37
+ toNormalUrl(
38
+ "https://user:password@mydomain.com:8080/path1/path2//&foo=bar?bar=baz#frag?"),
39
+ "https://user:password@mydomain.com:8080/path1/path2?foo=bar&bar=baz#frag?");
40
+ EXPECT_EQ(
41
+ toNormalUrl(
42
+ "https://user:password@mydomain.com:8080/path1/path2?foo=bar&bar=baz#frag?"),
43
+ "https://user:password@mydomain.com:8080/path1/path2?foo=bar&bar=baz#frag?");
44
+ }
45
+
46
+ TEST(JscSafeUrlTest, ToNormalUrl_RewritesMarkerWithoutFragment) {
47
+ EXPECT_EQ(
48
+ toNormalUrl("http://127.0.0.1/path1/path2//&foo=bar&bar=baz"),
49
+ "http://127.0.0.1/path1/path2?foo=bar&bar=baz");
50
+ EXPECT_EQ(
51
+ toNormalUrl("http://127.0.0.1/path1/path2?foo=bar&bar=baz"),
52
+ "http://127.0.0.1/path1/path2?foo=bar&bar=baz");
53
+ }
54
+
55
+ // Returns other strings exactly as given
56
+ TEST(JscSafeUrlTest, ToNormalUrl_PassthroughForQueryWithMarkerAfter) {
57
+ auto url = "http://user:password/@mydomain.com/foo?bar=zoo?baz=quux//&";
58
+ EXPECT_EQ(toNormalUrl(url), url);
59
+ }
60
+
61
+ TEST(JscSafeUrlTest, ToNormalUrl_PassthroughForSimpleQuery) {
62
+ auto url = "/foo?bar=zoo?baz=quux";
63
+ EXPECT_EQ(toNormalUrl(url), url);
64
+ }
65
+
66
+ TEST(JscSafeUrlTest, ToNormalUrl_PassthroughForOpaqueUri) {
67
+ auto url = "proto:arbitrary_bad_url";
68
+ EXPECT_EQ(toNormalUrl(url), url);
69
+ }
70
+
71
+ TEST(JscSafeUrlTest, ToNormalUrl_PassthroughForStar) {
72
+ EXPECT_EQ(toNormalUrl("*"), "*");
73
+ }
74
+
75
+ TEST(JscSafeUrlTest, ToNormalUrl_PassthroughForRelativePath) {
76
+ auto url = "relative/path";
77
+ EXPECT_EQ(toNormalUrl(url), url);
78
+ }
79
+
80
+ // --- toJscSafeUrl ---
81
+
82
+ // Replaces the first ? with a JSC-friendly delimiter, url-encodes subsequent
83
+ // ?, and is idempotent
84
+ TEST(JscSafeUrlTest, ToJscSafeUrl_FullUrlWithEncodedQuestionMark) {
85
+ auto input =
86
+ "https://user:password@mydomain.com:8080/path1/path2?foo=bar&bar=question?#frag?";
87
+ auto output =
88
+ "https://user:password@mydomain.com:8080/path1/path2//&foo=bar&bar=question%3F#frag?";
89
+ EXPECT_EQ(toJscSafeUrl(input), output);
90
+ EXPECT_EQ(toJscSafeUrl(output), output);
91
+ }
92
+
93
+ TEST(JscSafeUrlTest, ToJscSafeUrl_SimpleUrl) {
94
+ auto input = "http://127.0.0.1/path1/path2?foo=bar";
95
+ auto output = "http://127.0.0.1/path1/path2//&foo=bar";
96
+ EXPECT_EQ(toJscSafeUrl(input), output);
97
+ EXPECT_EQ(toJscSafeUrl(output), output);
98
+ }
99
+
100
+ TEST(JscSafeUrlTest, ToJscSafeUrl_PassthroughForStar) {
101
+ EXPECT_EQ(toJscSafeUrl("*"), "*");
102
+ EXPECT_EQ(toJscSafeUrl("*"), "*");
103
+ }
104
+
105
+ TEST(JscSafeUrlTest, ToJscSafeUrl_PassthroughForAbsolutePath) {
106
+ EXPECT_EQ(toJscSafeUrl("/absolute/path"), "/absolute/path");
107
+ EXPECT_EQ(toJscSafeUrl("/absolute/path"), "/absolute/path");
108
+ }
109
+
110
+ TEST(JscSafeUrlTest, ToJscSafeUrl_PassthroughForRelativePath) {
111
+ EXPECT_EQ(toJscSafeUrl("relative/path"), "relative/path");
112
+ EXPECT_EQ(toJscSafeUrl("relative/path"), "relative/path");
113
+ }
114
+
115
+ TEST(JscSafeUrlTest, ToJscSafeUrl_EmptyQueryDropped) {
116
+ EXPECT_EQ(toJscSafeUrl("/?"), "/");
117
+ EXPECT_EQ(toJscSafeUrl("/"), "/");
118
+ }
119
+
120
+ TEST(JscSafeUrlTest, ToJscSafeUrl_PassthroughForUrlWithoutQuery) {
121
+ auto url = "http://127.0.0.1/path1/path";
122
+ EXPECT_EQ(toJscSafeUrl(url), url);
123
+ EXPECT_EQ(toJscSafeUrl(url), url);
124
+ }
125
+
126
+ TEST(JscSafeUrlTest, ToJscSafeUrl_AbsolutePathWithEncodedQuestionMark) {
127
+ auto input = "/path1/path2?foo=bar&bar=question?#frag?";
128
+ auto output = "/path1/path2//&foo=bar&bar=question%3F#frag?";
129
+ EXPECT_EQ(toJscSafeUrl(input), output);
130
+ EXPECT_EQ(toJscSafeUrl(output), output);
131
+ }
132
+
133
+ TEST(JscSafeUrlTest, ToJscSafeUrl_RelativePathWithEncodedQuestionMark) {
134
+ auto input = "relative/path?foo=bar&bar=question?#frag?";
135
+ auto output = "relative/path//&foo=bar&bar=question%3F#frag?";
136
+ EXPECT_EQ(toJscSafeUrl(input), output);
137
+ EXPECT_EQ(toJscSafeUrl(output), output);
138
+ }
139
+
140
+ TEST(JscSafeUrlTest, ToJscSafeUrl_AlreadySafeWithExtraQuery) {
141
+ auto input = "/path1/path2//&foo=bar&bar=question%3F?extra=query#frag?";
142
+ auto output = "/path1/path2//&foo=bar&bar=question%3F&extra=query#frag?";
143
+ EXPECT_EQ(toJscSafeUrl(input), output);
144
+ EXPECT_EQ(toJscSafeUrl(output), output);
145
+ }
146
+
147
+ // Throws on a URL with an empty path and a query string
148
+ TEST(JscSafeUrlTest, ToJscSafeUrl_ThrowsForEmptyPathWithQuery) {
149
+ EXPECT_THROW(toJscSafeUrl("http://127.0.0.1?foo=bar"), std::invalid_argument);
150
+ EXPECT_THROW(toJscSafeUrl("http://127.0.0.1?q#hash"), std::invalid_argument);
151
+ EXPECT_THROW(toJscSafeUrl("?foo=bar"), std::invalid_argument);
152
+ EXPECT_THROW(toJscSafeUrl("?foo=/bar#hash"), std::invalid_argument);
153
+ EXPECT_THROW(toJscSafeUrl("/?bar=baz/"), std::invalid_argument);
154
+ }
155
+
156
+ // --- isJscSafeUrl ---
157
+
158
+ TEST(JscSafeUrlTest, IsJscSafeUrl_TrueForSafeUrls) {
159
+ EXPECT_TRUE(isJscSafeUrl("http://example.com//&foo=bar//#frag=//"));
160
+ EXPECT_TRUE(isJscSafeUrl("http://example.com/with/path//&foo=bar//#frag=//"));
161
+ EXPECT_TRUE(isJscSafeUrl("//&foo=bar//#frag=//"));
162
+ EXPECT_TRUE(isJscSafeUrl("relative/path///&foo=bar//&#frag=//&"));
163
+ EXPECT_TRUE(isJscSafeUrl("/absolute/path//&foo=bar//&#frag=//&"));
164
+ }
165
+
166
+ TEST(JscSafeUrlTest, IsJscSafeUrl_FalseForNormalUrls) {
167
+ EXPECT_FALSE(isJscSafeUrl("http://example.com?foo=bar//&#frag=//"));
168
+ EXPECT_FALSE(
169
+ isJscSafeUrl("http://example.com/with/path/?foo=bar//&#frag=//"));
170
+ EXPECT_FALSE(isJscSafeUrl("?foo=bar//&#frag=//&"));
171
+ EXPECT_FALSE(isJscSafeUrl("relative/path/?foo=bar//#frag=//"));
172
+ EXPECT_FALSE(isJscSafeUrl("/absolute/path/?foo=bar//&#frag=//"));
173
+ }
@@ -0,0 +1,107 @@
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
+ #include <react/debug/redbox/RedBoxErrorParser.h>
10
+
11
+ using namespace facebook::react::unstable_redbox;
12
+
13
+ TEST(RedBoxErrorParserTest, ParsesBabelTransformError) {
14
+ auto result = parseErrorMessage(
15
+ "SyntaxError: /path/to/file.js: Unexpected token (10:5)\n\n"
16
+ "> 10 | const x = {\n"
17
+ " | ^");
18
+
19
+ EXPECT_EQ(result.title, "Syntax Error");
20
+ EXPECT_EQ(result.message, "Unexpected token");
21
+ ASSERT_TRUE(result.codeFrame.has_value());
22
+ EXPECT_EQ(result.codeFrame->fileName, "/path/to/file.js");
23
+ EXPECT_EQ(result.codeFrame->row, 10);
24
+ EXPECT_EQ(result.codeFrame->column, 5);
25
+ EXPECT_TRUE(result.isCompileError);
26
+ EXPECT_TRUE(result.isRetryable);
27
+ }
28
+
29
+ TEST(RedBoxErrorParserTest, ParsesMetroError) {
30
+ auto result = parseErrorMessage(
31
+ "InternalError Metro has encountered an error: "
32
+ "BundleError: Unable to resolve module (1:0)\n\n"
33
+ "code frame here");
34
+
35
+ EXPECT_EQ(result.title, "BundleError");
36
+ EXPECT_EQ(result.message, "Unable to resolve module");
37
+ ASSERT_TRUE(result.codeFrame.has_value());
38
+ EXPECT_EQ(result.codeFrame->row, 1);
39
+ EXPECT_TRUE(result.isCompileError);
40
+ }
41
+
42
+ TEST(RedBoxErrorParserTest, ParsesBundleLoadError_SyntaxError) {
43
+ auto result = parseErrorMessage(
44
+ "SyntaxError in /app/index.js: Unexpected token (3:10)\ncode frame");
45
+
46
+ EXPECT_EQ(result.title, "Syntax Error");
47
+ EXPECT_EQ(result.message, "Unexpected token");
48
+ ASSERT_TRUE(result.codeFrame.has_value());
49
+ EXPECT_EQ(result.codeFrame->fileName, "/app/index.js");
50
+ EXPECT_EQ(result.codeFrame->row, 3);
51
+ EXPECT_EQ(result.codeFrame->column, 10);
52
+ EXPECT_TRUE(result.isCompileError);
53
+ }
54
+
55
+ TEST(RedBoxErrorParserTest, ParsesBundleLoadError_UnableToResolve) {
56
+ auto result = parseErrorMessage(
57
+ "UnableToResolveError in /app/index.js: Cannot find module (1:0)");
58
+
59
+ EXPECT_EQ(result.title, "Module Not Found");
60
+ EXPECT_TRUE(result.isCompileError);
61
+ }
62
+
63
+ TEST(RedBoxErrorParserTest, ParsesGenericTransformError) {
64
+ auto result = parseErrorMessage("TransformError some error message");
65
+
66
+ EXPECT_EQ(result.title, "Syntax Error");
67
+ EXPECT_EQ(result.message, "TransformError some error message");
68
+ EXPECT_FALSE(result.codeFrame.has_value());
69
+ EXPECT_TRUE(result.isCompileError);
70
+ }
71
+
72
+ TEST(RedBoxErrorParserTest, DefaultsToUncaughtError) {
73
+ auto result = parseErrorMessage("TypeError: undefined is not a function");
74
+
75
+ EXPECT_EQ(result.title, "Uncaught Error");
76
+ EXPECT_EQ(result.message, "TypeError: undefined is not a function");
77
+ EXPECT_FALSE(result.codeFrame.has_value());
78
+ EXPECT_FALSE(result.isCompileError);
79
+ EXPECT_TRUE(result.isRetryable);
80
+ }
81
+
82
+ TEST(RedBoxErrorParserTest, UsesNameForTitle) {
83
+ auto result = parseErrorMessage("something broke", "CustomError");
84
+
85
+ EXPECT_EQ(result.title, "CustomError");
86
+ }
87
+
88
+ TEST(RedBoxErrorParserTest, UsesRenderErrorForComponentStack) {
89
+ auto result =
90
+ parseErrorMessage("something broke", "", "in MyComponent\nin App");
91
+
92
+ EXPECT_EQ(result.title, "Render Error");
93
+ }
94
+
95
+ TEST(RedBoxErrorParserTest, NonFatalDefaultsToError) {
96
+ auto result = parseErrorMessage("warning message", "", "", false);
97
+
98
+ EXPECT_EQ(result.title, "Error");
99
+ }
100
+
101
+ TEST(RedBoxErrorParserTest, HandlesEmptyMessage) {
102
+ auto result = parseErrorMessage("");
103
+
104
+ EXPECT_EQ(result.title, "Uncaught Error");
105
+ EXPECT_EQ(result.message, "");
106
+ EXPECT_FALSE(result.codeFrame.has_value());
107
+ }
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @generated SignedSource<<08a361f2ffac6a0496adac1d4c3e4726>>
7
+ * @generated SignedSource<<983f38f2d2fdc1cbef07f6a4b1891342>>
8
8
  */
9
9
 
10
10
  /**
@@ -190,6 +190,10 @@ bool ReactNativeFeatureFlags::enableModuleArgumentNSNullConversionIOS() {
190
190
  return getAccessor().enableModuleArgumentNSNullConversionIOS();
191
191
  }
192
192
 
193
+ bool ReactNativeFeatureFlags::enableMutationObserverByDefault() {
194
+ return getAccessor().enableMutationObserverByDefault();
195
+ }
196
+
193
197
  bool ReactNativeFeatureFlags::enableNativeCSSParsing() {
194
198
  return getAccessor().enableNativeCSSParsing();
195
199
  }
@@ -262,10 +266,18 @@ bool ReactNativeFeatureFlags::fuseboxEnabledRelease() {
262
266
  return getAccessor().fuseboxEnabledRelease();
263
267
  }
264
268
 
269
+ bool ReactNativeFeatureFlags::fuseboxFrameRecordingEnabled() {
270
+ return getAccessor().fuseboxFrameRecordingEnabled();
271
+ }
272
+
265
273
  bool ReactNativeFeatureFlags::fuseboxNetworkInspectionEnabled() {
266
274
  return getAccessor().fuseboxNetworkInspectionEnabled();
267
275
  }
268
276
 
277
+ bool ReactNativeFeatureFlags::fuseboxScreenshotCaptureEnabled() {
278
+ return getAccessor().fuseboxScreenshotCaptureEnabled();
279
+ }
280
+
269
281
  bool ReactNativeFeatureFlags::hideOffscreenVirtualViewsOnIOS() {
270
282
  return getAccessor().hideOffscreenVirtualViewsOnIOS();
271
283
  }
@@ -290,6 +302,14 @@ bool ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion() {
290
302
  return getAccessor().preventShadowTreeCommitExhaustion();
291
303
  }
292
304
 
305
+ bool ReactNativeFeatureFlags::redBoxV2Android() {
306
+ return getAccessor().redBoxV2Android();
307
+ }
308
+
309
+ bool ReactNativeFeatureFlags::redBoxV2IOS() {
310
+ return getAccessor().redBoxV2IOS();
311
+ }
312
+
293
313
  bool ReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover() {
294
314
  return getAccessor().shouldPressibilityUseW3CPointerEventsForHover();
295
315
  }
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @generated SignedSource<<0bbe4d41581432dfad7adbc2db133d00>>
7
+ * @generated SignedSource<<57b1294863f5899a0892cc8501773edf>>
8
8
  */
9
9
 
10
10
  /**
@@ -244,6 +244,11 @@ class ReactNativeFeatureFlags {
244
244
  */
245
245
  RN_EXPORT static bool enableModuleArgumentNSNullConversionIOS();
246
246
 
247
+ /**
248
+ * Enables the MutationObserver Web API in React Native.
249
+ */
250
+ RN_EXPORT static bool enableMutationObserverByDefault();
251
+
247
252
  /**
248
253
  * Parse CSS strings using the Fabric CSS parser instead of ViewConfig processing
249
254
  */
@@ -334,11 +339,21 @@ class ReactNativeFeatureFlags {
334
339
  */
335
340
  RN_EXPORT static bool fuseboxEnabledRelease();
336
341
 
342
+ /**
343
+ * Enable frame timings and screenshots support in the React Native DevTools CDP backend. This flag is global and should not be changed across React Host lifetimes.
344
+ */
345
+ RN_EXPORT static bool fuseboxFrameRecordingEnabled();
346
+
337
347
  /**
338
348
  * Enable network inspection support in the React Native DevTools CDP backend. Requires `enableBridgelessArchitecture`. This flag is global and should not be changed across React Host lifetimes.
339
349
  */
340
350
  RN_EXPORT static bool fuseboxNetworkInspectionEnabled();
341
351
 
352
+ /**
353
+ * Enable Page.captureScreenshot CDP method support in the React Native DevTools CDP backend. This flag is global and should not be changed across React Host lifetimes.
354
+ */
355
+ RN_EXPORT static bool fuseboxScreenshotCaptureEnabled();
356
+
342
357
  /**
343
358
  * Hides offscreen VirtualViews on iOS by setting hidden = YES to avoid extra cost of views
344
359
  */
@@ -369,6 +384,16 @@ class ReactNativeFeatureFlags {
369
384
  */
370
385
  RN_EXPORT static bool preventShadowTreeCommitExhaustion();
371
386
 
387
+ /**
388
+ * Use the redesigned RedBox error overlay on Android, styled to match the LogBox visual language.
389
+ */
390
+ RN_EXPORT static bool redBoxV2Android();
391
+
392
+ /**
393
+ * Use the redesigned RedBox error overlay on iOS, styled to match the LogBox visual language.
394
+ */
395
+ RN_EXPORT static bool redBoxV2IOS();
396
+
372
397
  /**
373
398
  * Function used to enable / disable Pressibility from using W3C Pointer Events for its hover callbacks
374
399
  */