@ansight/react-native 1.3.0-preview.9 → 1.4.0-preview.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.
package/index.js CHANGED
@@ -1,7 +1,20 @@
1
1
  "use strict";
2
2
 
3
+ const { ensureReactInspectionHook } = require("./react-inspection-hook");
4
+ const { createReactCoordinateSpace } = require("./react-tree-geometry");
5
+ const { reactSemanticRole, reactSupportedActions } = require("./react-tree-semantics");
6
+
7
+ // Production React Native renderers only look for the DevTools hook once, when
8
+ // the renderer module initializes. Install a minimal root tracker while this
9
+ // package is loading so Fabric and Paper can report their roots before the app's
10
+ // first render. Development runtimes keep their full React DevTools hook.
11
+ if (typeof __DEV__ === "undefined" || !__DEV__) {
12
+ ensureReactInspectionHook(typeof global !== "undefined" ? global : undefined);
13
+ }
14
+
3
15
  const {
4
16
  AppState,
17
+ Dimensions,
5
18
  NativeEventEmitter,
6
19
  NativeModules,
7
20
  Platform,
@@ -10,6 +23,15 @@ const {
10
23
  findNodeHandle,
11
24
  processColor,
12
25
  } = require("react-native");
26
+ const { version: reactVersion } = require("react");
27
+ const {
28
+ createAutomaticSessionProperties,
29
+ mergeSessionProperties,
30
+ } = require("./session-properties");
31
+ const {
32
+ installNetworkCapture: installNetworkCaptureCore,
33
+ sanitizeNetworkRequest,
34
+ } = require("./network");
13
35
 
14
36
  const nativeModule = NativeModules.AnsightReactNative;
15
37
 
@@ -33,6 +55,9 @@ const hostConnectionStatusListeners = new Set();
33
55
  let lastHostConnectionStatusKey = null;
34
56
  const logListeners = new Set();
35
57
  let logEventSubscription = null;
58
+ let networkCaptureSubscription = null;
59
+ let networkCaptureRegistration = null;
60
+ let networkConnectionEventSubscription = null;
36
61
  const REACT_COMPONENT_TREE_TOOL_ID = "react.get_component_tree";
37
62
  const REACT_SHADOW_TREE_TOOL_ID = "react.get_shadow_tree";
38
63
 
@@ -44,7 +69,28 @@ function normalizePairingPayload(payload) {
44
69
  }
45
70
 
46
71
  function normalizeOptions(options = {}) {
47
- return { ...options };
72
+ const normalized = {
73
+ ...options,
74
+ customProperties: mergeSessionProperties(
75
+ automaticSessionProperties(),
76
+ options.customProperties
77
+ ),
78
+ };
79
+ delete normalized.networkCapture;
80
+ return normalized;
81
+ }
82
+
83
+ function automaticSessionProperties() {
84
+ return createAutomaticSessionProperties({
85
+ platform: Platform,
86
+ reactVersion,
87
+ runtimeGlobal: global,
88
+ developmentMode: typeof __DEV__ !== "undefined" && __DEV__,
89
+ });
90
+ }
91
+
92
+ function automaticSessionPropertyValue(group, key) {
93
+ return automaticSessionProperties()[group]?.[key];
48
94
  }
49
95
 
50
96
  function cloneOptions(options = {}) {
@@ -73,6 +119,17 @@ function cloneOptions(options = {}) {
73
119
  if (options.hostConnection) {
74
120
  clone.hostConnection = { ...options.hostConnection };
75
121
  }
122
+ if (options.networkCapture && typeof options.networkCapture === "object") {
123
+ clone.networkCapture = {
124
+ ...options.networkCapture,
125
+ additionalSensitiveHeaderNames: options.networkCapture.additionalSensitiveHeaderNames
126
+ ? [...options.networkCapture.additionalSensitiveHeaderNames]
127
+ : undefined,
128
+ additionalSensitiveQueryParameterNames: options.networkCapture.additionalSensitiveQueryParameterNames
129
+ ? [...options.networkCapture.additionalSensitiveQueryParameterNames]
130
+ : undefined,
131
+ };
132
+ }
76
133
  if (options.secureStorage) {
77
134
  clone.secureStorage = {
78
135
  ...options.secureStorage,
@@ -339,6 +396,52 @@ class AnsightOptionsBuilder {
339
396
  return this;
340
397
  }
341
398
 
399
+ withNetworkCapture(networkCapture = {}) {
400
+ this._options.networkCapture = { ...networkCapture };
401
+ return this;
402
+ }
403
+
404
+ withNetworkRequestBodies(maximumBodyBytes) {
405
+ if (!this._options.networkCapture || typeof this._options.networkCapture !== "object") return this;
406
+ const current = this._options.networkCapture;
407
+ this._options.networkCapture = {
408
+ ...current,
409
+ captureRequestBody: true,
410
+ ...(maximumBodyBytes == null ? {} : { maximumBodyBytes }),
411
+ };
412
+ return this;
413
+ }
414
+
415
+ withoutNetworkRequestBodies() {
416
+ if (!this._options.networkCapture || typeof this._options.networkCapture !== "object") return this;
417
+ const current = this._options.networkCapture;
418
+ this._options.networkCapture = { ...current, captureRequestBody: false };
419
+ return this;
420
+ }
421
+
422
+ withNetworkResponseBodies(maximumBodyBytes) {
423
+ if (!this._options.networkCapture || typeof this._options.networkCapture !== "object") return this;
424
+ const current = this._options.networkCapture;
425
+ this._options.networkCapture = {
426
+ ...current,
427
+ captureResponseBody: true,
428
+ ...(maximumBodyBytes == null ? {} : { maximumBodyBytes }),
429
+ };
430
+ return this;
431
+ }
432
+
433
+ withoutNetworkResponseBodies() {
434
+ if (!this._options.networkCapture || typeof this._options.networkCapture !== "object") return this;
435
+ const current = this._options.networkCapture;
436
+ this._options.networkCapture = { ...current, captureResponseBody: false };
437
+ return this;
438
+ }
439
+
440
+ withoutNetworkCapture() {
441
+ this._options.networkCapture = false;
442
+ return this;
443
+ }
444
+
342
445
  withToolGuard(toolGuard) {
343
446
  this._options.toolGuard = toolGuard;
344
447
  return this;
@@ -581,6 +684,7 @@ function addHostConnectionStatusListener(listener, options = {}) {
581
684
 
582
685
  async function notifyAfterHostConnectionChange(operation) {
583
686
  const result = await operation();
687
+ await refreshNetworkCaptureConnection();
584
688
  await emitHostConnectionStatusChangedIfNeeded();
585
689
  return result;
586
690
  }
@@ -811,7 +915,6 @@ function artifactDefinitionPayload(providerId, definition) {
811
915
  metadata: normalizedMetadata(definition.metadata),
812
916
  content: artifactContentDescriptor(definition),
813
917
  argumentsSchema: definition.argumentsSchema || { type: "object", additionalProperties: true },
814
- security: definition.security || { level: "moderate", implications: ["metadata_disclosure"] },
815
918
  };
816
919
  }
817
920
 
@@ -962,7 +1065,7 @@ function artifactToolDefinitions() {
962
1065
  name: "Query Artifacts",
963
1066
  description: "Queries app-provided artifact providers and currently requestable artifact definitions.",
964
1067
  category: "artifacts",
965
- scope: "read",
1068
+ policy: "read",
966
1069
  keywords: ["artifact", "artifacts", "query", "catalog", "provider", "export", "snapshot"],
967
1070
  argumentsSchema: {
968
1071
  type: "object",
@@ -974,18 +1077,13 @@ function artifactToolDefinitions() {
974
1077
  },
975
1078
  },
976
1079
  resultSchema: genericObject,
977
- security: {
978
- level: "moderate",
979
- summary: "Discovers app-provided artifact definitions and descriptive metadata.",
980
- implications: ["metadata_disclosure"],
981
- },
982
1080
  },
983
1081
  {
984
1082
  id: ARTIFACT_REQUEST_TOOL_ID,
985
1083
  name: "Request Artifact",
986
1084
  description: "Requests an app-provided artifact snapshot and streams it to the host.",
987
1085
  category: "artifacts",
988
- scope: "read",
1086
+ policy: "read",
989
1087
  keywords: ["artifact", "artifacts", "request", "export", "snapshot", "binary", "stream"],
990
1088
  argumentsSchema: {
991
1089
  type: "object",
@@ -999,11 +1097,6 @@ function artifactToolDefinitions() {
999
1097
  required: ["providerId", "artifactId"],
1000
1098
  },
1001
1099
  resultSchema: genericObject,
1002
- security: {
1003
- level: "high",
1004
- summary: "Requests and exports an app-provided artifact snapshot.",
1005
- implications: ["exports_app_data", "binary_transfer"],
1006
- },
1007
1100
  },
1008
1101
  ];
1009
1102
  }
@@ -1440,36 +1533,16 @@ function summarizeProps(props) {
1440
1533
  return summary;
1441
1534
  }
1442
1535
 
1443
- function reactSemanticRole(type, props, fiberTag) {
1444
- const declared = props && (props.accessibilityRole || props.role);
1445
- if (declared) return String(declared).toLowerCase();
1446
- if (fiberTag === 6 || /text/i.test(type)) return "text";
1447
- if (/button|pressable|touchable/i.test(type)) return "button";
1448
- if (/textinput/i.test(type)) return "textbox";
1449
- if (/switch/i.test(type)) return "switch";
1450
- if (/scrollview|flatlist|sectionlist/i.test(type)) return "scrollview";
1451
- return "view";
1452
- }
1453
-
1454
- function reactSupportedActions(type, props) {
1455
- const actions = [];
1456
- if (props && typeof props.onPress === "function") actions.push("tap");
1457
- if (props && (typeof props.onChangeText === "function" || /textinput/i.test(type))) {
1458
- actions.push("typeText", "focus");
1459
- }
1460
- if (/scrollview|flatlist|sectionlist/i.test(type) || (props && typeof props.onScroll === "function")) {
1461
- actions.push("scroll", "swipe");
1462
- }
1463
- return actions;
1464
- }
1465
-
1466
1536
  function applyReactTargetability(node, fiber, props, type) {
1467
1537
  const style = StyleSheet && typeof StyleSheet.flatten === "function"
1468
1538
  ? StyleSheet.flatten(props && props.style)
1469
1539
  : props && props.style;
1470
1540
  node.text = node.label || (node.visual && node.visual.text) || null;
1471
- node.role = reactSemanticRole(type, props, fiber.tag);
1472
1541
  node.supportedActions = reactSupportedActions(type, props);
1542
+ node.role = reactSemanticRole(type, props, fiber.tag);
1543
+ if (node.role === "view" && node.supportedActions.includes("tap")) {
1544
+ node.role = "button";
1545
+ }
1473
1546
  node.visible = !(style && style.display === "none") && !(props && props.accessibilityElementsHidden);
1474
1547
  node.enabled = !(props && (props.disabled === true || props.accessibilityState && props.accessibilityState.disabled === true));
1475
1548
  node.focusable = !!(props && props.focusable) || node.supportedActions.includes("focus");
@@ -1823,6 +1896,7 @@ async function captureReactVisualTree(rawOptions = {}) {
1823
1896
  source: "react",
1824
1897
  adapter: "react.fiber",
1825
1898
  treeKind: "component",
1899
+ coordinateSpace: createReactCoordinateSpace(Dimensions, context.nodesWithNativeTags),
1826
1900
  capturedAtUtc: new Date().toISOString(),
1827
1901
  hookAvailable: roots.hookAvailable,
1828
1902
  renderers: roots.renderers,
@@ -1883,6 +1957,7 @@ async function captureReactShadowTree(rawOptions = {}) {
1883
1957
  source: "react-native",
1884
1958
  adapter: "react-native.host-fiber",
1885
1959
  treeKind: "shadow",
1960
+ coordinateSpace: createReactCoordinateSpace(Dimensions, context.nodesWithNativeTags),
1886
1961
  capturedAtUtc: new Date().toISOString(),
1887
1962
  hookAvailable: roots.hookAvailable,
1888
1963
  renderers: roots.renderers,
@@ -1985,7 +2060,7 @@ function reactToolDefinitions(enableActions) {
1985
2060
  name: "Get React Component Tree",
1986
2061
  description: "Captures the live React Fiber component tree for the current React Native runtime.",
1987
2062
  category: "react",
1988
- scope: "read",
2063
+ policy: "read",
1989
2064
  keywords: ["react", "react-native", "fiber", "component", "component-tree"],
1990
2065
  argumentsSchema: {
1991
2066
  type: "object",
@@ -1998,18 +2073,13 @@ function reactToolDefinitions(enableActions) {
1998
2073
  },
1999
2074
  },
2000
2075
  resultSchema: { type: "object", additionalProperties: true },
2001
- security: {
2002
- level: "high",
2003
- summary: "Inspects the React component tree and optionally sanitized props/state.",
2004
- implications: ["inspects_runtime_state", "metadata_disclosure"],
2005
- },
2006
2076
  },
2007
2077
  {
2008
2078
  id: REACT_SHADOW_TREE_TOOL_ID,
2009
2079
  name: "Get React Shadow Tree",
2010
2080
  description: "Captures the committed React Native host tree with composite components flattened out.",
2011
2081
  category: "react",
2012
- scope: "read",
2082
+ policy: "read",
2013
2083
  keywords: ["react", "react-native", "host", "shadow", "shadow-tree", "layout"],
2014
2084
  argumentsSchema: {
2015
2085
  type: "object",
@@ -2021,18 +2091,13 @@ function reactToolDefinitions(enableActions) {
2021
2091
  },
2022
2092
  },
2023
2093
  resultSchema: { type: "object", additionalProperties: true },
2024
- security: {
2025
- level: "high",
2026
- summary: "Inspects the React Native host tree and optionally sanitized host props.",
2027
- implications: ["inspects_runtime_state", "metadata_disclosure"],
2028
- },
2029
2094
  },
2030
2095
  {
2031
2096
  id: "react.find_components",
2032
2097
  name: "Find React Components",
2033
2098
  description: "Searches the live React component tree by component type, text, testID, nativeID, or accessibility label.",
2034
2099
  category: "react",
2035
- scope: "read",
2100
+ policy: "read",
2036
2101
  keywords: ["react", "search", "component", "testid", "accessibility"],
2037
2102
  argumentsSchema: {
2038
2103
  type: "object",
@@ -2046,18 +2111,13 @@ function reactToolDefinitions(enableActions) {
2046
2111
  },
2047
2112
  },
2048
2113
  resultSchema: { type: "object", additionalProperties: true },
2049
- security: {
2050
- level: "high",
2051
- summary: "Searches React runtime metadata and may reveal UI text.",
2052
- implications: ["inspects_runtime_state", "metadata_disclosure"],
2053
- },
2054
2114
  },
2055
2115
  {
2056
2116
  id: "react.get_component",
2057
2117
  name: "Get React Component",
2058
2118
  description: "Returns a single React component node from the current React visual tree.",
2059
2119
  category: "react",
2060
- scope: "read",
2120
+ policy: "read",
2061
2121
  keywords: ["react", "component", "props", "fiber"],
2062
2122
  argumentsSchema: {
2063
2123
  type: "object",
@@ -2070,25 +2130,15 @@ function reactToolDefinitions(enableActions) {
2070
2130
  required: ["nodeId"],
2071
2131
  },
2072
2132
  resultSchema: { type: "object", additionalProperties: true },
2073
- security: {
2074
- level: "high",
2075
- summary: "Reads one React component node and optionally sanitized props/state.",
2076
- implications: ["inspects_runtime_state", "metadata_disclosure"],
2077
- },
2078
2133
  },
2079
2134
  {
2080
2135
  id: "react.get_navigation_state",
2081
2136
  name: "Get React Navigation State",
2082
2137
  description: "Returns the configured React Navigation ref state when installReactTools receives a navigationRef.",
2083
2138
  category: "react",
2084
- scope: "read",
2139
+ policy: "read",
2085
2140
  keywords: ["react", "navigation", "route", "screen"],
2086
2141
  resultSchema: { type: "object", additionalProperties: true },
2087
- security: {
2088
- level: "medium",
2089
- summary: "Reads navigation route metadata from a configured navigation ref.",
2090
- implications: ["inspects_runtime_state", "metadata_disclosure"],
2091
- },
2092
2142
  },
2093
2143
  ];
2094
2144
 
@@ -2098,7 +2148,7 @@ function reactToolDefinitions(enableActions) {
2098
2148
  name: "Invoke React Component Action",
2099
2149
  description: "Invokes an allow-listed function prop on a React component, such as onPress.",
2100
2150
  category: "react",
2101
- scope: "write",
2151
+ policy: "write",
2102
2152
  keywords: ["react", "component", "action", "onpress"],
2103
2153
  argumentsSchema: {
2104
2154
  type: "object",
@@ -2109,11 +2159,6 @@ function reactToolDefinitions(enableActions) {
2109
2159
  required: ["nodeId", "prop"],
2110
2160
  },
2111
2161
  resultSchema: { type: "object", additionalProperties: true },
2112
- security: {
2113
- level: "critical",
2114
- summary: "Invokes app code through a React prop function.",
2115
- implications: ["invokes_app_code", "mutates_runtime_state"],
2116
- },
2117
2162
  });
2118
2163
  }
2119
2164
 
@@ -2212,7 +2257,7 @@ function installReactTools(options = {}) {
2212
2257
  errorCode: "react_action_not_found",
2213
2258
  };
2214
2259
  }
2215
- await action();
2260
+ await action(args.value);
2216
2261
  return {
2217
2262
  success: true,
2218
2263
  message: `Invoked React component action '${prop}'.`,
@@ -2313,6 +2358,7 @@ function installErrorHandlers(options = {}) {
2313
2358
 
2314
2359
  async function initialize(options = {}) {
2315
2360
  const result = await nativeModule.initialize(normalizeOptions(options));
2361
+ await configureNetworkCapture(options.networkCapture);
2316
2362
  if (options.lifecycle !== false) {
2317
2363
  startAppStateTracking();
2318
2364
  }
@@ -2322,6 +2368,7 @@ async function initialize(options = {}) {
2322
2368
 
2323
2369
  async function initializeAndActivate(options = {}) {
2324
2370
  const result = await nativeModule.initializeAndActivate(normalizeOptions(options));
2371
+ await configureNetworkCapture(options.networkCapture);
2325
2372
  if (options.lifecycle !== false) {
2326
2373
  startAppStateTracking();
2327
2374
  }
@@ -2396,6 +2443,93 @@ function recordCrashCandidate(input = {}) {
2396
2443
  });
2397
2444
  }
2398
2445
 
2446
+ function recordNetworkRequest(input, sanitizationOptions = {}) {
2447
+ const sanitized = sanitizeNetworkRequest(input, sanitizationOptions, global);
2448
+ if (!sanitized) {
2449
+ return Promise.resolve({ success: false, message: "Network request capture was suppressed by the sanitizer." });
2450
+ }
2451
+ return nativeModule.recordNetworkRequest(sanitized);
2452
+ }
2453
+
2454
+ function installNetworkCapture(options = {}) {
2455
+ uninstallNetworkCapture();
2456
+ const registration = { options };
2457
+ networkCaptureRegistration = registration;
2458
+ ensureNetworkConnectionEventSubscription();
2459
+ void refreshNetworkCaptureConnection();
2460
+ return {
2461
+ remove() {
2462
+ if (networkCaptureRegistration === registration) {
2463
+ uninstallNetworkCapture();
2464
+ }
2465
+ },
2466
+ };
2467
+ }
2468
+
2469
+ function uninstallNetworkCapture() {
2470
+ networkCaptureRegistration = null;
2471
+ if (networkConnectionEventSubscription) {
2472
+ networkConnectionEventSubscription.remove();
2473
+ networkConnectionEventSubscription = null;
2474
+ }
2475
+ detachNetworkCapture();
2476
+ }
2477
+
2478
+ function detachNetworkCapture() {
2479
+ if (!networkCaptureSubscription) return;
2480
+ networkCaptureSubscription.remove();
2481
+ networkCaptureSubscription = null;
2482
+ }
2483
+
2484
+ async function refreshNetworkCaptureConnection() {
2485
+ const registration = networkCaptureRegistration;
2486
+ if (!registration) {
2487
+ detachNetworkCapture();
2488
+ return;
2489
+ }
2490
+ try {
2491
+ const status = await nativeModule.hostConnectionStatus();
2492
+ if (networkCaptureRegistration !== registration) return;
2493
+ applyNetworkConnectionStatus(status);
2494
+ } catch {
2495
+ if (networkCaptureRegistration === registration) detachNetworkCapture();
2496
+ }
2497
+ }
2498
+
2499
+ function ensureNetworkConnectionEventSubscription() {
2500
+ if (networkConnectionEventSubscription) return;
2501
+ const emitter = new NativeEventEmitter(nativeModule);
2502
+ networkConnectionEventSubscription = emitter.addListener(
2503
+ "AnsightHostConnectionStatus",
2504
+ applyNetworkConnectionStatus,
2505
+ );
2506
+ }
2507
+
2508
+ function applyNetworkConnectionStatus(status) {
2509
+ const registration = networkCaptureRegistration;
2510
+ if (!registration || !status || status.isConnected !== true) {
2511
+ detachNetworkCapture();
2512
+ return;
2513
+ }
2514
+ if (!networkCaptureSubscription) {
2515
+ networkCaptureSubscription = installNetworkCaptureCore({
2516
+ globalObject: global,
2517
+ options: registration.options,
2518
+ sourcePrefix: "react-native",
2519
+ capture: (request) => nativeModule.recordNetworkRequest(request),
2520
+ });
2521
+ }
2522
+ }
2523
+
2524
+ async function configureNetworkCapture(value) {
2525
+ uninstallNetworkCapture();
2526
+ if (!value) return;
2527
+ const registration = { options: typeof value === "object" ? value : {} };
2528
+ networkCaptureRegistration = registration;
2529
+ ensureNetworkConnectionEventSubscription();
2530
+ await refreshNetworkCaptureConnection();
2531
+ }
2532
+
2399
2533
  function screenViewed(name, details) {
2400
2534
  return nativeModule.screenViewed(name, details || {});
2401
2535
  }
@@ -2439,6 +2573,7 @@ const Ansight = {
2439
2573
  event: recordEvent,
2440
2574
  recordEvent,
2441
2575
  recordCrashCandidate,
2576
+ recordNetworkRequest,
2442
2577
  screenViewed,
2443
2578
  trackRoute,
2444
2579
  setAppLifecycleState: (state) => nativeModule.setAppLifecycleState(state),
@@ -2473,12 +2608,21 @@ const Ansight = {
2473
2608
  captureScreenFrame: (options = {}) => nativeModule.captureScreenFrame(options || {}),
2474
2609
  enableTouchCapture: () => nativeModule.enableTouchCapture(),
2475
2610
  disableTouchCapture: () => nativeModule.disableTouchCapture(),
2476
- updateSessionProperties: (properties) => nativeModule.updateSessionProperties(properties || {}),
2477
- clearSessionProperties: () => nativeModule.clearSessionProperties(),
2478
- updateCustomProperties: (properties) => nativeModule.updateSessionProperties(properties || {}),
2611
+ updateSessionProperties: (properties) => nativeModule.updateSessionProperties(
2612
+ mergeSessionProperties(automaticSessionProperties(), properties || {})
2613
+ ),
2614
+ clearSessionProperties: () => nativeModule.updateSessionProperties(automaticSessionProperties()),
2615
+ updateCustomProperties: (properties) => nativeModule.updateSessionProperties(
2616
+ mergeSessionProperties(automaticSessionProperties(), properties || {})
2617
+ ),
2479
2618
  registerCustomProperty: (group, key, value) => nativeModule.registerCustomProperty(group, key, value),
2480
- removeCustomProperty: (group, key) => nativeModule.removeCustomProperty(group, key),
2481
- clearCustomProperties: () => nativeModule.clearSessionProperties(),
2619
+ removeCustomProperty: (group, key) => {
2620
+ const automaticValue = automaticSessionPropertyValue(group, key);
2621
+ return automaticValue == null
2622
+ ? nativeModule.removeCustomProperty(group, key)
2623
+ : nativeModule.registerCustomProperty(group, key, automaticValue);
2624
+ },
2625
+ clearCustomProperties: () => nativeModule.updateSessionProperties(automaticSessionProperties()),
2482
2626
  registerTool,
2483
2627
  unregisterTool,
2484
2628
  registerArtifactProvider,
@@ -2500,6 +2644,9 @@ const Ansight = {
2500
2644
  installReactTools,
2501
2645
  uninstallReactTools,
2502
2646
  installErrorHandlers,
2647
+ installNetworkCapture,
2648
+ uninstallNetworkCapture,
2649
+ sanitizeNetworkRequest,
2503
2650
  createReactNavigationTracker,
2504
2651
  platform: Platform.OS,
2505
2652
  };
@@ -2518,3 +2665,7 @@ module.exports.registerArtifactProviders = registerArtifactProviders;
2518
2665
  module.exports.unregisterArtifactProvider = unregisterArtifactProvider;
2519
2666
  module.exports.listRegisteredArtifactProviders = listRegisteredArtifactProviders;
2520
2667
  module.exports.clearArtifactProviders = clearArtifactProviders;
2668
+ module.exports.recordNetworkRequest = recordNetworkRequest;
2669
+ module.exports.installNetworkCapture = installNetworkCapture;
2670
+ module.exports.uninstallNetworkCapture = uninstallNetworkCapture;
2671
+ module.exports.sanitizeNetworkRequest = sanitizeNetworkRequest;