execbro 2.6.1 → 2.7.1
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/README.md +5 -2
- package/build/__tests__/helpers/mock-harness.d.ts +35 -0
- package/build/__tests__/helpers/mock-harness.d.ts.map +1 -0
- package/build/__tests__/helpers/mock-harness.js +83 -0
- package/build/__tests__/helpers/mock-harness.js.map +1 -0
- package/build/__tests__/unit/androidEmulatorAvds.test.js +2 -1
- package/build/__tests__/unit/androidEmulatorAvds.test.js.map +1 -1
- package/build/__tests__/unit/buildToken.test.js +20 -3
- package/build/__tests__/unit/buildToken.test.js.map +1 -1
- package/build/__tests__/unit/commandInjection.test.d.ts +2 -0
- package/build/__tests__/unit/commandInjection.test.d.ts.map +1 -0
- package/build/__tests__/unit/commandInjection.test.js +55 -0
- package/build/__tests__/unit/commandInjection.test.js.map +1 -0
- package/build/__tests__/unit/deviceResolver.test.js +2 -0
- package/build/__tests__/unit/deviceResolver.test.js.map +1 -1
- package/build/__tests__/unit/deviceResolverStaleRetry.test.js +1 -0
- package/build/__tests__/unit/deviceResolverStaleRetry.test.js.map +1 -1
- package/build/__tests__/unit/errorCategorization.test.js +14 -0
- package/build/__tests__/unit/errorCategorization.test.js.map +1 -1
- package/build/__tests__/unit/fingerprint.test.js +2 -2
- package/build/__tests__/unit/fingerprint.test.js.map +1 -1
- package/build/__tests__/unit/inputTarget.test.js +46 -0
- package/build/__tests__/unit/inputTarget.test.js.map +1 -1
- package/build/__tests__/unit/logSourceAndroid.test.js +5 -5
- package/build/__tests__/unit/logSourceAndroid.test.js.map +1 -1
- package/build/__tests__/unit/logSourceIos.test.js +10 -6
- package/build/__tests__/unit/logSourceIos.test.js.map +1 -1
- package/build/__tests__/unit/logStack.test.d.ts +2 -0
- package/build/__tests__/unit/logStack.test.d.ts.map +1 -0
- package/build/__tests__/unit/logStack.test.js +86 -0
- package/build/__tests__/unit/logStack.test.js.map +1 -0
- package/build/__tests__/unit/logSymbolication.test.d.ts +2 -0
- package/build/__tests__/unit/logSymbolication.test.d.ts.map +1 -0
- package/build/__tests__/unit/logSymbolication.test.js +215 -0
- package/build/__tests__/unit/logSymbolication.test.js.map +1 -0
- package/build/__tests__/unit/measureComponentResolution.test.d.ts +2 -0
- package/build/__tests__/unit/measureComponentResolution.test.d.ts.map +1 -0
- package/build/__tests__/unit/measureComponentResolution.test.js +111 -0
- package/build/__tests__/unit/measureComponentResolution.test.js.map +1 -0
- package/build/__tests__/unit/metroIdentity.test.d.ts +2 -0
- package/build/__tests__/unit/metroIdentity.test.d.ts.map +1 -0
- package/build/__tests__/unit/metroIdentity.test.js +41 -0
- package/build/__tests__/unit/metroIdentity.test.js.map +1 -0
- package/build/__tests__/unit/mockRulePush.test.d.ts +2 -0
- package/build/__tests__/unit/mockRulePush.test.d.ts.map +1 -0
- package/build/__tests__/unit/mockRulePush.test.js +65 -0
- package/build/__tests__/unit/mockRulePush.test.js.map +1 -0
- package/build/__tests__/unit/mockRules.test.d.ts +2 -0
- package/build/__tests__/unit/mockRules.test.d.ts.map +1 -0
- package/build/__tests__/unit/mockRules.test.js +111 -0
- package/build/__tests__/unit/mockRules.test.js.map +1 -0
- package/build/__tests__/unit/nativeLogs.test.js +8 -2
- package/build/__tests__/unit/nativeLogs.test.js.map +1 -1
- package/build/__tests__/unit/netInfoPatch.test.d.ts +2 -0
- package/build/__tests__/unit/netInfoPatch.test.d.ts.map +1 -0
- package/build/__tests__/unit/netInfoPatch.test.js +46 -0
- package/build/__tests__/unit/netInfoPatch.test.js.map +1 -0
- package/build/__tests__/unit/networkInterceptorXhr.test.d.ts +2 -0
- package/build/__tests__/unit/networkInterceptorXhr.test.d.ts.map +1 -0
- package/build/__tests__/unit/networkInterceptorXhr.test.js +440 -0
- package/build/__tests__/unit/networkInterceptorXhr.test.js.map +1 -0
- package/build/__tests__/unit/networkMock.test.d.ts +2 -0
- package/build/__tests__/unit/networkMock.test.d.ts.map +1 -0
- package/build/__tests__/unit/networkMock.test.js +183 -0
- package/build/__tests__/unit/networkMock.test.js.map +1 -0
- package/build/__tests__/unit/networkMockRender.test.d.ts +2 -0
- package/build/__tests__/unit/networkMockRender.test.d.ts.map +1 -0
- package/build/__tests__/unit/networkMockRender.test.js +131 -0
- package/build/__tests__/unit/networkMockRender.test.js.map +1 -0
- package/build/__tests__/unit/networkMockTamper.test.d.ts +2 -0
- package/build/__tests__/unit/networkMockTamper.test.d.ts.map +1 -0
- package/build/__tests__/unit/networkMockTamper.test.js +162 -0
- package/build/__tests__/unit/networkMockTamper.test.js.map +1 -0
- package/build/__tests__/unit/networkMockTool.test.d.ts +2 -0
- package/build/__tests__/unit/networkMockTool.test.d.ts.map +1 -0
- package/build/__tests__/unit/networkMockTool.test.js +69 -0
- package/build/__tests__/unit/networkMockTool.test.js.map +1 -0
- package/build/__tests__/unit/networkReplay.test.d.ts +2 -0
- package/build/__tests__/unit/networkReplay.test.d.ts.map +1 -0
- package/build/__tests__/unit/networkReplay.test.js +86 -0
- package/build/__tests__/unit/networkReplay.test.js.map +1 -0
- package/build/__tests__/unit/screenState.test.js +63 -2
- package/build/__tests__/unit/screenState.test.js.map +1 -1
- package/build/__tests__/unit/serialQueue.test.d.ts +2 -0
- package/build/__tests__/unit/serialQueue.test.d.ts.map +1 -0
- package/build/__tests__/unit/serialQueue.test.js +77 -0
- package/build/__tests__/unit/serialQueue.test.js.map +1 -0
- package/build/__tests__/unit/swipeDiagnosis.test.d.ts +2 -0
- package/build/__tests__/unit/swipeDiagnosis.test.d.ts.map +1 -0
- package/build/__tests__/unit/swipeDiagnosis.test.js +47 -0
- package/build/__tests__/unit/swipeDiagnosis.test.js.map +1 -0
- package/build/__tests__/unit/swipeDirection.test.js +30 -0
- package/build/__tests__/unit/swipeDirection.test.js.map +1 -1
- package/build/__tests__/unit/symbolicate.test.js +36 -0
- package/build/__tests__/unit/symbolicate.test.js.map +1 -1
- package/build/__tests__/unit/tap.test.js +0 -48
- package/build/__tests__/unit/tap.test.js.map +1 -1
- package/build/__tests__/unit/textEntry.test.js +53 -0
- package/build/__tests__/unit/textEntry.test.js.map +1 -1
- package/build/__tests__/unit/toolArgInjection.test.d.ts +2 -0
- package/build/__tests__/unit/toolArgInjection.test.d.ts.map +1 -0
- package/build/__tests__/unit/toolArgInjection.test.js +86 -0
- package/build/__tests__/unit/toolArgInjection.test.js.map +1 -0
- package/build/core/android.d.ts.map +1 -1
- package/build/core/android.js +54 -111
- package/build/core/android.js.map +1 -1
- package/build/core/androidForeground.d.ts +4 -0
- package/build/core/androidForeground.d.ts.map +1 -0
- package/build/core/androidForeground.js +34 -0
- package/build/core/androidForeground.js.map +1 -0
- package/build/core/androidSystemBars.d.ts +1 -1
- package/build/core/androidSystemBars.d.ts.map +1 -1
- package/build/core/androidSystemBars.js +5 -5
- package/build/core/androidSystemBars.js.map +1 -1
- package/build/core/appRequest.d.ts +1 -0
- package/build/core/appRequest.d.ts.map +1 -1
- package/build/core/appRequest.js +5 -2
- package/build/core/appRequest.js.map +1 -1
- package/build/core/buildInfo.d.ts +3 -0
- package/build/core/buildInfo.d.ts.map +1 -0
- package/build/core/buildInfo.js +6 -0
- package/build/core/buildInfo.js.map +1 -0
- package/build/core/componentSource.d.ts.map +1 -1
- package/build/core/componentSource.js +1 -1
- package/build/core/componentSource.js.map +1 -1
- package/build/core/connection.d.ts +6 -0
- package/build/core/connection.d.ts.map +1 -1
- package/build/core/connection.js +60 -5
- package/build/core/connection.js.map +1 -1
- package/build/core/deviceResolver.d.ts.map +1 -1
- package/build/core/deviceResolver.js +7 -1
- package/build/core/deviceResolver.js.map +1 -1
- package/build/core/exec.d.ts +5 -0
- package/build/core/exec.d.ts.map +1 -1
- package/build/core/exec.js +34 -1
- package/build/core/exec.js.map +1 -1
- package/build/core/fingerprint.d.ts.map +1 -1
- package/build/core/fingerprint.js +3 -3
- package/build/core/fingerprint.js.map +1 -1
- package/build/core/guides.d.ts.map +1 -1
- package/build/core/guides.js +21 -1
- package/build/core/guides.js.map +1 -1
- package/build/core/inputTarget.d.ts.map +1 -1
- package/build/core/inputTarget.js +42 -2
- package/build/core/inputTarget.js.map +1 -1
- package/build/core/ios.d.ts.map +1 -1
- package/build/core/ios.js +14 -17
- package/build/core/ios.js.map +1 -1
- package/build/core/jsLogEvents.d.ts.map +1 -1
- package/build/core/jsLogEvents.js +1 -0
- package/build/core/jsLogEvents.js.map +1 -1
- package/build/core/keyboardRaise.d.ts.map +1 -1
- package/build/core/keyboardRaise.js +3 -3
- package/build/core/keyboardRaise.js.map +1 -1
- package/build/core/logEventFormat.d.ts +2 -0
- package/build/core/logEventFormat.d.ts.map +1 -1
- package/build/core/logEventFormat.js +6 -1
- package/build/core/logEventFormat.js.map +1 -1
- package/build/core/logEvents.d.ts +2 -1
- package/build/core/logEvents.d.ts.map +1 -1
- package/build/core/logEvents.js.map +1 -1
- package/build/core/logSourceAndroid.d.ts +1 -1
- package/build/core/logSourceAndroid.d.ts.map +1 -1
- package/build/core/logSourceAndroid.js +9 -9
- package/build/core/logSourceAndroid.js.map +1 -1
- package/build/core/logSourceIos.d.ts +1 -1
- package/build/core/logSourceIos.d.ts.map +1 -1
- package/build/core/logSourceIos.js +9 -9
- package/build/core/logSourceIos.js.map +1 -1
- package/build/core/logStack.d.ts +6 -0
- package/build/core/logStack.d.ts.map +1 -0
- package/build/core/logStack.js +44 -0
- package/build/core/logStack.js.map +1 -0
- package/build/core/logSymbolication.d.ts +11 -0
- package/build/core/logSymbolication.d.ts.map +1 -0
- package/build/core/logSymbolication.js +91 -0
- package/build/core/logSymbolication.js.map +1 -0
- package/build/core/measureComponent.d.ts.map +1 -1
- package/build/core/measureComponent.js +45 -11
- package/build/core/measureComponent.js.map +1 -1
- package/build/core/metroIdentity.d.ts +8 -0
- package/build/core/metroIdentity.d.ts.map +1 -0
- package/build/core/metroIdentity.js +65 -0
- package/build/core/metroIdentity.js.map +1 -0
- package/build/core/mockRules.d.ts +30 -0
- package/build/core/mockRules.d.ts.map +1 -0
- package/build/core/mockRules.js +200 -0
- package/build/core/mockRules.js.map +1 -0
- package/build/core/nativeInputValue.js +6 -6
- package/build/core/nativeInputValue.js.map +1 -1
- package/build/core/nativeLogs.js +2 -2
- package/build/core/nativeLogs.js.map +1 -1
- package/build/core/netInfoPatch.d.ts +5 -0
- package/build/core/netInfoPatch.d.ts.map +1 -0
- package/build/core/netInfoPatch.js +88 -0
- package/build/core/netInfoPatch.js.map +1 -0
- package/build/core/network.d.ts.map +1 -1
- package/build/core/network.js +9 -0
- package/build/core/network.js.map +1 -1
- package/build/core/networkInterceptor.d.ts +6 -0
- package/build/core/networkInterceptor.d.ts.map +1 -1
- package/build/core/networkInterceptor.js +660 -13
- package/build/core/networkInterceptor.js.map +1 -1
- package/build/core/replay.d.ts +14 -0
- package/build/core/replay.d.ts.map +1 -0
- package/build/core/replay.js +14 -0
- package/build/core/replay.js.map +1 -0
- package/build/core/screenSpaceDevice.d.ts +5 -0
- package/build/core/screenSpaceDevice.d.ts.map +1 -1
- package/build/core/screenSpaceDevice.js +18 -0
- package/build/core/screenSpaceDevice.js.map +1 -1
- package/build/core/screenState.d.ts +8 -0
- package/build/core/screenState.d.ts.map +1 -1
- package/build/core/screenState.js +245 -32
- package/build/core/screenState.js.map +1 -1
- package/build/core/serialQueue.d.ts +6 -0
- package/build/core/serialQueue.d.ts.map +1 -0
- package/build/core/serialQueue.js +18 -0
- package/build/core/serialQueue.js.map +1 -0
- package/build/core/swipeDiagnosis.d.ts +17 -0
- package/build/core/swipeDiagnosis.d.ts.map +1 -0
- package/build/core/swipeDiagnosis.js +179 -0
- package/build/core/swipeDiagnosis.js.map +1 -0
- package/build/core/symbolicate.d.ts +2 -2
- package/build/core/symbolicate.d.ts.map +1 -1
- package/build/core/symbolicate.js +2 -2
- package/build/core/symbolicate.js.map +1 -1
- package/build/core/telemetry.d.ts.map +1 -1
- package/build/core/telemetry.js +5 -3
- package/build/core/telemetry.js.map +1 -1
- package/build/core/textEntry.d.ts +2 -0
- package/build/core/textEntry.d.ts.map +1 -1
- package/build/core/textEntry.js +30 -3
- package/build/core/textEntry.js.map +1 -1
- package/build/core/types.d.ts +11 -0
- package/build/core/types.d.ts.map +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +70 -9
- package/build/index.js.map +1 -1
- package/build/pro/tap.d.ts +6 -1
- package/build/pro/tap.d.ts.map +1 -1
- package/build/pro/tap.js +12 -3
- package/build/pro/tap.js.map +1 -1
- package/build/tools/componentTools.d.ts.map +1 -1
- package/build/tools/componentTools.js +12 -4
- package/build/tools/componentTools.js.map +1 -1
- package/build/tools/connectionTools.d.ts.map +1 -1
- package/build/tools/connectionTools.js +18 -0
- package/build/tools/connectionTools.js.map +1 -1
- package/build/tools/deviceTools.d.ts.map +1 -1
- package/build/tools/deviceTools.js +4 -1
- package/build/tools/deviceTools.js.map +1 -1
- package/build/tools/interactionTools.d.ts.map +1 -1
- package/build/tools/interactionTools.js +56 -14
- package/build/tools/interactionTools.js.map +1 -1
- package/build/tools/logTools.d.ts.map +1 -1
- package/build/tools/logTools.js +16 -3
- package/build/tools/logTools.js.map +1 -1
- package/build/tools/networkTools.d.ts.map +1 -1
- package/build/tools/networkTools.js +196 -4
- package/build/tools/networkTools.js.map +1 -1
- package/build/tools/requestTools.d.ts.map +1 -1
- package/build/tools/requestTools.js +93 -26
- package/build/tools/requestTools.js.map +1 -1
- package/package.json +3 -3
- package/tools.json +37 -1
- package/build/__tests__/helpers/fake-cdp-server.d.ts +0 -53
- package/build/__tests__/helpers/fake-cdp-server.d.ts.map +0 -1
- package/build/__tests__/helpers/fake-cdp-server.js +0 -116
- package/build/__tests__/helpers/fake-cdp-server.js.map +0 -1
- package/build/__tests__/helpers/tap-test-helpers.d.ts +0 -13
- package/build/__tests__/helpers/tap-test-helpers.d.ts.map +0 -1
- package/build/__tests__/helpers/tap-test-helpers.js +0 -103
- package/build/__tests__/helpers/tap-test-helpers.js.map +0 -1
- package/build/__tests__/integration/auto-reconnect.test.d.ts +0 -2
- package/build/__tests__/integration/auto-reconnect.test.d.ts.map +0 -1
- package/build/__tests__/integration/auto-reconnect.test.js +0 -108
- package/build/__tests__/integration/auto-reconnect.test.js.map +0 -1
- package/build/__tests__/integration/connection-health.test.d.ts +0 -2
- package/build/__tests__/integration/connection-health.test.d.ts.map +0 -1
- package/build/__tests__/integration/connection-health.test.js +0 -155
- package/build/__tests__/integration/connection-health.test.js.map +0 -1
- package/build/__tests__/integration/execute-in-app.test.d.ts +0 -2
- package/build/__tests__/integration/execute-in-app.test.d.ts.map +0 -1
- package/build/__tests__/integration/execute-in-app.test.js +0 -114
- package/build/__tests__/integration/execute-in-app.test.js.map +0 -1
- package/build/__tests__/integration/native-logs.test.d.ts +0 -2
- package/build/__tests__/integration/native-logs.test.d.ts.map +0 -1
- package/build/__tests__/integration/native-logs.test.js +0 -34
- package/build/__tests__/integration/native-logs.test.js.map +0 -1
- package/build/__tests__/integration/per-call-timeout.test.d.ts +0 -2
- package/build/__tests__/integration/per-call-timeout.test.d.ts.map +0 -1
- package/build/__tests__/integration/per-call-timeout.test.js +0 -99
- package/build/__tests__/integration/per-call-timeout.test.js.map +0 -1
- package/build/__tests__/integration/socket-close-midflight.test.d.ts +0 -2
- package/build/__tests__/integration/socket-close-midflight.test.d.ts.map +0 -1
- package/build/__tests__/integration/socket-close-midflight.test.js +0 -96
- package/build/__tests__/integration/socket-close-midflight.test.js.map +0 -1
- package/build/__tests__/integration/stale-target-probe.test.d.ts +0 -2
- package/build/__tests__/integration/stale-target-probe.test.d.ts.map +0 -1
- package/build/__tests__/integration/stale-target-probe.test.js +0 -70
- package/build/__tests__/integration/stale-target-probe.test.js.map +0 -1
- package/build/__tests__/integration/tap-strategies.test.d.ts +0 -2
- package/build/__tests__/integration/tap-strategies.test.d.ts.map +0 -1
- package/build/__tests__/integration/tap-strategies.test.js +0 -296
- package/build/__tests__/integration/tap-strategies.test.js.map +0 -1
- package/build/__tests__/integration/text-input.test.d.ts +0 -2
- package/build/__tests__/integration/text-input.test.d.ts.map +0 -1
- package/build/__tests__/integration/text-input.test.js +0 -142
- package/build/__tests__/integration/text-input.test.js.map +0 -1
- package/build/__tests__/integration/tools.test.d.ts +0 -2
- package/build/__tests__/integration/tools.test.d.ts.map +0 -1
- package/build/__tests__/integration/tools.test.js +0 -221
- package/build/__tests__/integration/tools.test.js.map +0 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const STACK_LEVELS = new Set(["warn", "error", "fatal"]);
|
|
2
|
+
export const MAX_STORED_FRAMES = 12;
|
|
3
|
+
export function captureStack(level, stackTrace) {
|
|
4
|
+
if (!STACK_LEVELS.has(level))
|
|
5
|
+
return undefined;
|
|
6
|
+
if (!stackTrace || typeof stackTrace !== "object")
|
|
7
|
+
return undefined;
|
|
8
|
+
const callFrames = stackTrace.callFrames;
|
|
9
|
+
if (!Array.isArray(callFrames) || callFrames.length === 0)
|
|
10
|
+
return undefined;
|
|
11
|
+
const out = [];
|
|
12
|
+
for (const raw of callFrames) {
|
|
13
|
+
if (out.length >= MAX_STORED_FRAMES)
|
|
14
|
+
break;
|
|
15
|
+
if (!raw || typeof raw !== "object")
|
|
16
|
+
continue;
|
|
17
|
+
const f = raw;
|
|
18
|
+
if (typeof f.lineNumber !== "number" || typeof f.columnNumber !== "number")
|
|
19
|
+
continue;
|
|
20
|
+
out.push({
|
|
21
|
+
functionName: typeof f.functionName === "string" ? f.functionName : undefined,
|
|
22
|
+
scriptId: typeof f.scriptId === "string" ? f.scriptId : undefined,
|
|
23
|
+
url: typeof f.url === "string" && f.url.length > 0 ? f.url : undefined,
|
|
24
|
+
lineNumber: f.lineNumber,
|
|
25
|
+
columnNumber: f.columnNumber,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return out.length > 0 ? out : undefined;
|
|
29
|
+
}
|
|
30
|
+
export function toStackFrames(frames) {
|
|
31
|
+
const out = [];
|
|
32
|
+
for (const f of frames) {
|
|
33
|
+
if (!f.url)
|
|
34
|
+
continue;
|
|
35
|
+
out.push({
|
|
36
|
+
file: f.url,
|
|
37
|
+
lineNumber: f.lineNumber + 1,
|
|
38
|
+
column: f.columnNumber + 1,
|
|
39
|
+
methodName: f.functionName && f.functionName.length > 0 ? f.functionName : null,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=logStack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logStack.js","sourceRoot":"","sources":["../../src/core/logStack.ts"],"names":[],"mappings":"AAoBA,MAAM,YAAY,GAAmC,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAOzF,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAOpC,MAAM,UAAU,YAAY,CACxB,KAAwB,EACxB,UAAmB;IAEnB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/C,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAEpE,MAAM,UAAU,GAAI,UAAuC,CAAC,UAAU,CAAC;IACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAE5E,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,MAAM,IAAI,iBAAiB;YAAE,MAAM;QAC3C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,SAAS;QAC9C,MAAM,CAAC,GAAG,GAA8B,CAAC;QACzC,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ;YAAE,SAAS;QACrF,GAAG,CAAC,IAAI,CAAC;YACL,YAAY,EAAE,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;YAC7E,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YACjE,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;YACtE,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,YAAY,EAAE,CAAC,CAAC,YAAY;SAC/B,CAAC,CAAC;IACP,CAAC;IAED,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5C,CAAC;AAiBD,MAAM,UAAU,aAAa,CAAC,MAAgC;IAC1D,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,CAAC,GAAG;YAAE,SAAS;QACrB,GAAG,CAAC,IAAI,CAAC;YACL,IAAI,EAAE,CAAC,CAAC,GAAG;YACX,UAAU,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC;YAC5B,MAAM,EAAE,CAAC,CAAC,YAAY,GAAG,CAAC;YAC1B,UAAU,EAAE,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI;SAClF,CAAC,CAAC;IACP,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { LogEvent } from "./logEvents.js";
|
|
2
|
+
import { type SymbolicatedFrame } from "./symbolicate.js";
|
|
3
|
+
export declare const READ_FRAME_BUDGET = 20;
|
|
4
|
+
export interface ResolvedStacks {
|
|
5
|
+
byEventId: Map<string, SymbolicatedFrame>;
|
|
6
|
+
overBudget: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function formatFrame(frame: SymbolicatedFrame): string;
|
|
9
|
+
export declare function resolveListStacks(events: readonly LogEvent[], budget?: number): Promise<ResolvedStacks>;
|
|
10
|
+
export declare function resolveFullStack(event: LogEvent): Promise<string[]>;
|
|
11
|
+
//# sourceMappingURL=logSymbolication.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logSymbolication.d.ts","sourceRoot":"","sources":["../../src/core/logSymbolication.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAIH,KAAK,iBAAiB,EACzB,MAAM,kBAAkB,CAAC;AAe1B,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAKpC,MAAM,WAAW,cAAc;IAE3B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAE1C,UAAU,EAAE,MAAM,CAAC;CACtB;AASD,wBAAgB,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAG5D;AAMD,wBAAsB,iBAAiB,CACnC,MAAM,EAAE,SAAS,QAAQ,EAAE,EAC3B,MAAM,SAAoB,GAC3B,OAAO,CAAC,cAAc,CAAC,CAyDzB;AAMD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAyBzE"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { toStackFrames } from "./logStack.js";
|
|
2
|
+
import { firstUserFrame, symbolicateFrames, } from "./symbolicate.js";
|
|
3
|
+
export const READ_FRAME_BUDGET = 20;
|
|
4
|
+
const LIST_LEVELS = new Set(["error", "fatal"]);
|
|
5
|
+
const EMPTY = { byEventId: new Map(), overBudget: 0 };
|
|
6
|
+
function frameKey(f) {
|
|
7
|
+
return `${f.file}|${f.lineNumber}|${f.column}`;
|
|
8
|
+
}
|
|
9
|
+
export function formatFrame(frame) {
|
|
10
|
+
const where = `${frame.file}:${frame.lineNumber}:${frame.column}`;
|
|
11
|
+
return frame.methodName ? `${where} in ${frame.methodName}` : where;
|
|
12
|
+
}
|
|
13
|
+
export async function resolveListStacks(events, budget = READ_FRAME_BUDGET) {
|
|
14
|
+
const candidates = events.filter((e) => e.source === "js" && LIST_LEVELS.has(e.level) && e.stackTrace?.length);
|
|
15
|
+
if (candidates.length === 0)
|
|
16
|
+
return EMPTY;
|
|
17
|
+
const uniqueFrames = [];
|
|
18
|
+
const indexByKey = new Map();
|
|
19
|
+
const perEvent = [];
|
|
20
|
+
let overBudget = 0;
|
|
21
|
+
for (const event of candidates) {
|
|
22
|
+
const frames = toStackFrames(event.stackTrace ?? []);
|
|
23
|
+
if (frames.length === 0)
|
|
24
|
+
continue;
|
|
25
|
+
const indexes = [];
|
|
26
|
+
let truncated = false;
|
|
27
|
+
for (const frame of frames) {
|
|
28
|
+
const key = frameKey(frame);
|
|
29
|
+
let idx = indexByKey.get(key);
|
|
30
|
+
if (idx === undefined) {
|
|
31
|
+
if (uniqueFrames.length >= budget) {
|
|
32
|
+
truncated = true;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
idx = uniqueFrames.length;
|
|
36
|
+
indexByKey.set(key, idx);
|
|
37
|
+
uniqueFrames.push(frame);
|
|
38
|
+
}
|
|
39
|
+
indexes.push(idx);
|
|
40
|
+
}
|
|
41
|
+
if (truncated && indexes.length === 0)
|
|
42
|
+
overBudget++;
|
|
43
|
+
if (indexes.length > 0)
|
|
44
|
+
perEvent.push({ id: event.id, indexes });
|
|
45
|
+
}
|
|
46
|
+
if (uniqueFrames.length === 0)
|
|
47
|
+
return { byEventId: new Map(), overBudget };
|
|
48
|
+
let resolved;
|
|
49
|
+
try {
|
|
50
|
+
resolved = await symbolicateFrames(uniqueFrames);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return { byEventId: new Map(), overBudget };
|
|
54
|
+
}
|
|
55
|
+
if (resolved === null)
|
|
56
|
+
return { byEventId: new Map(), overBudget };
|
|
57
|
+
const byEventId = new Map();
|
|
58
|
+
for (const { id, indexes } of perEvent) {
|
|
59
|
+
const slice = indexes.map((i) => resolved[i] ?? null);
|
|
60
|
+
const first = firstUserFrame(slice);
|
|
61
|
+
if (first)
|
|
62
|
+
byEventId.set(id, first);
|
|
63
|
+
}
|
|
64
|
+
return { byEventId, overBudget };
|
|
65
|
+
}
|
|
66
|
+
export async function resolveFullStack(event) {
|
|
67
|
+
const frames = toStackFrames(event.stackTrace ?? []);
|
|
68
|
+
if (frames.length === 0)
|
|
69
|
+
return [];
|
|
70
|
+
let resolved;
|
|
71
|
+
try {
|
|
72
|
+
resolved = await symbolicateFrames(frames);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
if (resolved === null)
|
|
78
|
+
return [];
|
|
79
|
+
const lines = [];
|
|
80
|
+
resolved.forEach((frame, i) => {
|
|
81
|
+
if (frame) {
|
|
82
|
+
lines.push(` ${frame.collapse ? "·" : "→"} ${formatFrame(frame)}`);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const raw = frames[i];
|
|
86
|
+
lines.push(` ? ${raw.methodName ?? "<anonymous>"} (unresolved)`);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return lines;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=logSymbolication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logSymbolication.js","sourceRoot":"","sources":["../../src/core/logSymbolication.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measureComponent.d.ts","sourceRoot":"","sources":["../../src/core/measureComponent.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACpB,UAAU,GACV,UAAU,GACV,oBAAoB,GACpB,SAAS,GACT,OAAO,CAAC;AAEd,MAAM,WAAW,aAAa;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,iBAAiB,GACvB,CAAC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,GAAG,aAAa,CAAC,GACxD;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF,wBAAgB,+BAA+B,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"measureComponent.d.ts","sourceRoot":"","sources":["../../src/core/measureComponent.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACpB,UAAU,GACV,UAAU,GACV,oBAAoB,GACpB,SAAS,GACT,OAAO,CAAC;AAEd,MAAM,WAAW,aAAa;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,iBAAiB,GACvB,CAAC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,GAAG,aAAa,CAAC,GACxD;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF,wBAAgB,+BAA+B,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CA8H5F"}
|
|
@@ -45,21 +45,50 @@ export function buildMeasureComponentExpression(componentName, index) {
|
|
|
45
45
|
const pub = sn.canonical.publicInstance;
|
|
46
46
|
return { instance: pub, nativeTag: pub.__nativeTag };
|
|
47
47
|
}
|
|
48
|
+
// Fabric shadow-node handle: no public instance on the fiber, but the UIManager can
|
|
49
|
+
// measure the node directly. Without this branch a plain RCTView is invisible to the
|
|
50
|
+
// search, so it walked past every one of them and picked whatever deep descendant
|
|
51
|
+
// happened to expose a public instance — on RN 0.83 that was an RNGestureHandlerButton
|
|
52
|
+
// inside the first tab, which made measure("ShopHeader") and measure("SubTabBar")
|
|
53
|
+
// return byte-identical frames and the same nativeTag. Same branch screenState and
|
|
54
|
+
// componentSource already carry; measure was the one that never got it.
|
|
55
|
+
const node = sn.node || (sn.canonical && sn.canonical.node);
|
|
56
|
+
if (node && globalThis.nativeFabricUIManager && typeof globalThis.nativeFabricUIManager.measureInWindow === "function") {
|
|
57
|
+
// The tag lives on the canonical record here, not on a public instance.
|
|
58
|
+
const canonicalTag = sn.canonical && typeof sn.canonical.nativeTag === "number"
|
|
59
|
+
? sn.canonical.nativeTag
|
|
60
|
+
: undefined;
|
|
61
|
+
return {
|
|
62
|
+
instance: {
|
|
63
|
+
measureInWindow: (cb) => {
|
|
64
|
+
try { globalThis.nativeFabricUIManager.measureInWindow(node, cb); } catch (e) {}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
nativeTag: canonicalTag
|
|
68
|
+
};
|
|
69
|
+
}
|
|
48
70
|
return null;
|
|
49
71
|
};
|
|
50
72
|
|
|
51
73
|
let target = getMeasurable(matched);
|
|
52
74
|
if (!target) {
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
75
|
+
// Breadth-first, so the SHALLOWEST measurable host wins.
|
|
76
|
+
//
|
|
77
|
+
// The previous descent was pre-order depth-first, which follows one spine to the leaf
|
|
78
|
+
// before trying the next branch. With a getMeasurable that can miss, that turns a near
|
|
79
|
+
// miss into a wildly wrong answer: the component's own container is skipped and some
|
|
80
|
+
// small leaf several levels down is measured and reported under the component's name.
|
|
81
|
+
// Breadth-first cannot do that — it exhausts a whole depth before descending.
|
|
82
|
+
const enqueueChain = (start, q) => { let n = start; while (n) { q.push(n); n = n.sibling; } };
|
|
83
|
+
const queue = [];
|
|
84
|
+
enqueueChain(matched.child, queue);
|
|
85
|
+
let guard = 0;
|
|
86
|
+
while (queue.length > 0 && !target && guard++ < 20000) {
|
|
87
|
+
const f = queue.shift();
|
|
88
|
+
const m = getMeasurable(f);
|
|
89
|
+
if (m) { target = m; break; }
|
|
90
|
+
enqueueChain(f.child, queue);
|
|
91
|
+
}
|
|
63
92
|
}
|
|
64
93
|
|
|
65
94
|
if (!target) {
|
|
@@ -68,9 +97,14 @@ export function buildMeasureComponentExpression(componentName, index) {
|
|
|
68
97
|
}
|
|
69
98
|
|
|
70
99
|
let done = false;
|
|
100
|
+
// Held so the loser can be cancelled. Without this the 1.5s timer stays armed in the
|
|
101
|
+
// app's runtime after every successful measure — harmless, but it is a timer per call
|
|
102
|
+
// that exists only to be ignored.
|
|
103
|
+
let timeoutId = null;
|
|
71
104
|
target.instance.measureInWindow((x, y, width, height) => {
|
|
72
105
|
if (done) return;
|
|
73
106
|
done = true;
|
|
107
|
+
if (timeoutId !== null) { try { clearTimeout(timeoutId); } catch (e) {} }
|
|
74
108
|
resolve({
|
|
75
109
|
outcome: "measured",
|
|
76
110
|
x: x,
|
|
@@ -81,7 +115,7 @@ export function buildMeasureComponentExpression(componentName, index) {
|
|
|
81
115
|
nativeTag: typeof target.nativeTag === "number" ? target.nativeTag : undefined,
|
|
82
116
|
});
|
|
83
117
|
});
|
|
84
|
-
setTimeout(() => {
|
|
118
|
+
timeoutId = setTimeout(() => {
|
|
85
119
|
if (done) return;
|
|
86
120
|
done = true;
|
|
87
121
|
resolve({ outcome: "timeout", error: "measureInWindow timed out (1500ms)" });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measureComponent.js","sourceRoot":"","sources":["../../src/core/measureComponent.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,+BAA+B,CAAC,aAAqB,EAAE,KAAa;IAChF,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAClF,OAAO;;;;;;;;;;;;0BAYe,WAAW;0BACX,SAAS
|
|
1
|
+
{"version":3,"file":"measureComponent.js","sourceRoot":"","sources":["../../src/core/measureComponent.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,+BAA+B,CAAC,aAAqB,EAAE,KAAa;IAChF,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAClF,OAAO;;;;;;;;;;;;0BAYe,WAAW;0BACX,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6GhC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function readListenerPid(port: number): Promise<string | null>;
|
|
2
|
+
export declare function metroProcessChanged(port: number): Promise<boolean>;
|
|
3
|
+
export declare function markBundlePossiblyStale(deviceName: string, reason: string): void;
|
|
4
|
+
export declare function clearBundleStale(deviceName?: string): void;
|
|
5
|
+
export declare function bundleStaleWarning(deviceName?: string): string | null;
|
|
6
|
+
export declare function staleBundleMessage(deviceName: string): string;
|
|
7
|
+
export declare function resetMetroIdentity(): void;
|
|
8
|
+
//# sourceMappingURL=metroIdentity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metroIdentity.d.ts","sourceRoot":"","sources":["../../src/core/metroIdentity.ts"],"names":[],"mappings":"AAiCA,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAY1E;AAQD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMxE;AAGD,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAGhF;AAMD,wBAAgB,gBAAgB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAc1D;AASD,wBAAgB,kBAAkB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYrE;AAGD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAO7D;AAGD,wBAAgB,kBAAkB,IAAI,IAAI,CAGzC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { execFileAsync } from "./exec.js";
|
|
2
|
+
const metroPidByPort = new Map();
|
|
3
|
+
const staleBundleDevices = new Map();
|
|
4
|
+
export async function readListenerPid(port) {
|
|
5
|
+
try {
|
|
6
|
+
const { stdout } = await execFileAsync("lsof", ["-nP", `-iTCP:${port}`, "-sTCP:LISTEN", "-t"], { timeout: 3000 });
|
|
7
|
+
const pid = stdout.split("\n").map((l) => l.trim()).filter(Boolean)[0];
|
|
8
|
+
return pid || null;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function metroProcessChanged(port) {
|
|
15
|
+
const pid = await readListenerPid(port);
|
|
16
|
+
if (!pid)
|
|
17
|
+
return false;
|
|
18
|
+
const previous = metroPidByPort.get(port);
|
|
19
|
+
metroPidByPort.set(port, pid);
|
|
20
|
+
return previous !== undefined && previous !== pid;
|
|
21
|
+
}
|
|
22
|
+
export function markBundlePossiblyStale(deviceName, reason) {
|
|
23
|
+
const key = (deviceName || "").trim();
|
|
24
|
+
if (key)
|
|
25
|
+
staleBundleDevices.set(key, reason);
|
|
26
|
+
}
|
|
27
|
+
export function clearBundleStale(deviceName) {
|
|
28
|
+
if (!deviceName) {
|
|
29
|
+
staleBundleDevices.clear();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const key = deviceName.trim();
|
|
33
|
+
staleBundleDevices.delete(key);
|
|
34
|
+
for (const known of [...staleBundleDevices.keys()]) {
|
|
35
|
+
if (known.toLowerCase().includes(key.toLowerCase()) || key.toLowerCase().includes(known.toLowerCase())) {
|
|
36
|
+
staleBundleDevices.delete(known);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function bundleStaleWarning(deviceName) {
|
|
41
|
+
if (staleBundleDevices.size === 0)
|
|
42
|
+
return null;
|
|
43
|
+
if (!deviceName) {
|
|
44
|
+
const [first] = staleBundleDevices.values();
|
|
45
|
+
return first ?? null;
|
|
46
|
+
}
|
|
47
|
+
const needle = deviceName.trim().toLowerCase();
|
|
48
|
+
for (const [known, reason] of staleBundleDevices.entries()) {
|
|
49
|
+
const k = known.toLowerCase();
|
|
50
|
+
if (k.includes(needle) || needle.includes(k))
|
|
51
|
+
return reason;
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
export function staleBundleMessage(deviceName) {
|
|
56
|
+
return (`⚠️ STALE BUNDLE RISK on "${deviceName}": Metro was restarted (different process) since this device last attached. ` +
|
|
57
|
+
`Fast Refresh history is discontinuous — any edit made while Metro was down was never sent to the app, and reconnecting ` +
|
|
58
|
+
`does not reconcile it. The app may still be running the OLD code, so behaviour that contradicts your edit is not evidence ` +
|
|
59
|
+
`the edit is wrong. Run reload_app to be certain, or get_refresh_status to see when the app last accepted an update.`);
|
|
60
|
+
}
|
|
61
|
+
export function resetMetroIdentity() {
|
|
62
|
+
metroPidByPort.clear();
|
|
63
|
+
staleBundleDevices.clear();
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=metroIdentity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metroIdentity.js","sourceRoot":"","sources":["../../src/core/metroIdentity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface MockRule {
|
|
2
|
+
id: string;
|
|
3
|
+
url: string;
|
|
4
|
+
method?: string;
|
|
5
|
+
mode: "replace" | "tamper";
|
|
6
|
+
times?: number;
|
|
7
|
+
delayMs?: number;
|
|
8
|
+
status?: number;
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
body?: string;
|
|
11
|
+
networkError?: string;
|
|
12
|
+
set?: Record<string, unknown>;
|
|
13
|
+
remove?: string[];
|
|
14
|
+
bodyReplace?: string;
|
|
15
|
+
source?: "mock" | "condition";
|
|
16
|
+
hits: number;
|
|
17
|
+
}
|
|
18
|
+
export type MockRuleInput = Omit<MockRule, "id" | "hits">;
|
|
19
|
+
export declare function __resetMockRules(): void;
|
|
20
|
+
export declare function validateUrlPattern(pattern: string): void;
|
|
21
|
+
export declare function addRule(device: string, input: MockRuleInput): MockRule;
|
|
22
|
+
export declare function removeRule(device: string, id: string): boolean;
|
|
23
|
+
export declare function clearRules(device?: string): number;
|
|
24
|
+
export declare function clearConditionRules(device: string): number;
|
|
25
|
+
export declare function listRules(device: string): MockRule[];
|
|
26
|
+
export declare function recordHit(device: string, id: string): void;
|
|
27
|
+
export declare function serializeRules(device: string): string;
|
|
28
|
+
export declare function formatRuleList(device: string): string;
|
|
29
|
+
export declare function activeMockBanner(device?: string): string;
|
|
30
|
+
//# sourceMappingURL=mockRules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockRules.d.ts","sourceRoot":"","sources":["../../src/core/mockRules.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,QAAQ;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IAOrB,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAE9B,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC;AAkB1D,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC;AAwFD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAmDxD;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,QAAQ,CAOtE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAO9D;AAED,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAYlD;AAMD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAO1D;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAEpD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAG1D;AAOD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrD;AASD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAerD;AAUD,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAgBxD"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { UserInputError } from "./errors.js";
|
|
2
|
+
const rulesByDevice = new Map();
|
|
3
|
+
let nextId = 1;
|
|
4
|
+
const MAX_PATTERN_LENGTH = 200;
|
|
5
|
+
const PROBE_INPUT_LENGTH = 22;
|
|
6
|
+
const PROBE_BUDGET_MS = 20;
|
|
7
|
+
export function __resetMockRules() {
|
|
8
|
+
rulesByDevice.clear();
|
|
9
|
+
nextId = 1;
|
|
10
|
+
}
|
|
11
|
+
function isRegexPattern(pattern) {
|
|
12
|
+
return (pattern.length > 1 &&
|
|
13
|
+
pattern.charAt(0) === "/" &&
|
|
14
|
+
pattern.charAt(pattern.length - 1) === "/");
|
|
15
|
+
}
|
|
16
|
+
function bodyCanRepeatOrBranch(body) {
|
|
17
|
+
let inClass = false;
|
|
18
|
+
for (let i = 0; i < body.length; i++) {
|
|
19
|
+
const c = body[i];
|
|
20
|
+
if (c === "\\") {
|
|
21
|
+
i++;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (inClass) {
|
|
25
|
+
if (c === "]")
|
|
26
|
+
inClass = false;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (c === "[") {
|
|
30
|
+
inClass = true;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (c === "*" || c === "+" || c === "|")
|
|
34
|
+
return true;
|
|
35
|
+
if (c === "{" && /^\{\d+,\}/.test(body.slice(i)))
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
function hasRiskyNesting(pattern) {
|
|
41
|
+
const openStack = [];
|
|
42
|
+
let inClass = false;
|
|
43
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
44
|
+
const c = pattern[i];
|
|
45
|
+
if (c === "\\") {
|
|
46
|
+
i++;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (inClass) {
|
|
50
|
+
if (c === "]")
|
|
51
|
+
inClass = false;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (c === "[") {
|
|
55
|
+
inClass = true;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (c === "(") {
|
|
59
|
+
openStack.push(i);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (c === ")") {
|
|
63
|
+
const open = openStack.pop();
|
|
64
|
+
if (open === undefined)
|
|
65
|
+
continue;
|
|
66
|
+
const rest = pattern.slice(i + 1);
|
|
67
|
+
const quantified = rest.charAt(0) === "*" ||
|
|
68
|
+
rest.charAt(0) === "+" ||
|
|
69
|
+
/^\{\d+,\}/.test(rest);
|
|
70
|
+
if (!quantified)
|
|
71
|
+
continue;
|
|
72
|
+
if (bodyCanRepeatOrBranch(pattern.slice(open + 1, i)))
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
export function validateUrlPattern(pattern) {
|
|
79
|
+
if (!isRegexPattern(pattern))
|
|
80
|
+
return;
|
|
81
|
+
const source = pattern.slice(1, -1);
|
|
82
|
+
if (source.length > MAX_PATTERN_LENGTH) {
|
|
83
|
+
throw new UserInputError(`Regex pattern is too long (${source.length} chars, max ${MAX_PATTERN_LENGTH}). ` +
|
|
84
|
+
`It runs inside the app's JS thread on every request. Use a shorter pattern, ` +
|
|
85
|
+
`or a plain substring (no surrounding slashes) for a literal match.`, "mock_pattern_too_long");
|
|
86
|
+
}
|
|
87
|
+
let re;
|
|
88
|
+
try {
|
|
89
|
+
re = new RegExp(source);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
throw new UserInputError(`Regex pattern "${pattern}" does not compile: ${err instanceof Error ? err.message : String(err)}. ` +
|
|
93
|
+
`Omit the surrounding slashes if you meant a literal substring.`, "mock_pattern_invalid");
|
|
94
|
+
}
|
|
95
|
+
if (hasRiskyNesting(source)) {
|
|
96
|
+
throw new UserInputError(`Regex pattern "${pattern}" has a nested quantifier (e.g. (a+)+, (.*)*, (a|aa)+) and can ` +
|
|
97
|
+
`backtrack catastrophically. It would run in the app's JS thread and freeze it. ` +
|
|
98
|
+
`Rewrite it without the nesting, or use a plain substring.`, "mock_pattern_backtracking");
|
|
99
|
+
}
|
|
100
|
+
const probe = "a".repeat(PROBE_INPUT_LENGTH) + "!";
|
|
101
|
+
const start = Date.now();
|
|
102
|
+
try {
|
|
103
|
+
re.test(probe);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const elapsed = Date.now() - start;
|
|
109
|
+
if (elapsed > PROBE_BUDGET_MS) {
|
|
110
|
+
throw new UserInputError(`Regex pattern "${pattern}" is too slow (${elapsed}ms on a ${probe.length}-character probe) — ` +
|
|
111
|
+
`it backtracks and would freeze the app's JS thread. Rewrite it or use a plain substring.`, "mock_pattern_slow");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export function addRule(device, input) {
|
|
115
|
+
validateUrlPattern(input.url);
|
|
116
|
+
const rule = { ...input, id: `m${nextId++}`, hits: 0 };
|
|
117
|
+
const list = rulesByDevice.get(device) ?? [];
|
|
118
|
+
list.push(rule);
|
|
119
|
+
rulesByDevice.set(device, list);
|
|
120
|
+
return rule;
|
|
121
|
+
}
|
|
122
|
+
export function removeRule(device, id) {
|
|
123
|
+
const list = rulesByDevice.get(device);
|
|
124
|
+
if (!list)
|
|
125
|
+
return false;
|
|
126
|
+
const i = list.findIndex((r) => r.id === id);
|
|
127
|
+
if (i === -1)
|
|
128
|
+
return false;
|
|
129
|
+
list.splice(i, 1);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
export function clearRules(device) {
|
|
133
|
+
if (device === undefined) {
|
|
134
|
+
let n = 0;
|
|
135
|
+
for (const list of rulesByDevice.values())
|
|
136
|
+
n += list.length;
|
|
137
|
+
rulesByDevice.clear();
|
|
138
|
+
return n;
|
|
139
|
+
}
|
|
140
|
+
const list = rulesByDevice.get(device);
|
|
141
|
+
if (!list)
|
|
142
|
+
return 0;
|
|
143
|
+
const n = list.length;
|
|
144
|
+
rulesByDevice.delete(device);
|
|
145
|
+
return n;
|
|
146
|
+
}
|
|
147
|
+
export function clearConditionRules(device) {
|
|
148
|
+
const list = rulesByDevice.get(device);
|
|
149
|
+
if (!list)
|
|
150
|
+
return 0;
|
|
151
|
+
const kept = list.filter((r) => r.source !== "condition");
|
|
152
|
+
const removed = list.length - kept.length;
|
|
153
|
+
rulesByDevice.set(device, kept);
|
|
154
|
+
return removed;
|
|
155
|
+
}
|
|
156
|
+
export function listRules(device) {
|
|
157
|
+
return rulesByDevice.get(device) ?? [];
|
|
158
|
+
}
|
|
159
|
+
export function recordHit(device, id) {
|
|
160
|
+
const rule = rulesByDevice.get(device)?.find((r) => r.id === id);
|
|
161
|
+
if (rule)
|
|
162
|
+
rule.hits++;
|
|
163
|
+
}
|
|
164
|
+
export function serializeRules(device) {
|
|
165
|
+
const wire = listRules(device).map(({ hits: _hits, source: _source, ...rest }) => rest);
|
|
166
|
+
return JSON.stringify(wire);
|
|
167
|
+
}
|
|
168
|
+
export function formatRuleList(device) {
|
|
169
|
+
const rules = listRules(device);
|
|
170
|
+
if (rules.length === 0)
|
|
171
|
+
return "No mock rules active.";
|
|
172
|
+
const lines = rules.map((r) => {
|
|
173
|
+
const status = r.status ? ` ${r.status}` : "";
|
|
174
|
+
const times = r.times ? ` (times:${r.times}${r.hits >= r.times ? ", spent" : ""})` : "";
|
|
175
|
+
const owner = r.source === "condition" ? " [owned by network_condition]" : "";
|
|
176
|
+
return `[${r.id}] ${r.method ?? "ANY"} ${r.url || "<any url>"} -> ${r.mode}${status}${times} hits=${r.hits}${owner}`;
|
|
177
|
+
});
|
|
178
|
+
return (lines.join("\n") +
|
|
179
|
+
"\n\nRules match in this order; a rule with hits=0 may be shadowed by one above it.");
|
|
180
|
+
}
|
|
181
|
+
export function activeMockBanner(device) {
|
|
182
|
+
if (device !== undefined) {
|
|
183
|
+
const n = listRules(device).length;
|
|
184
|
+
if (n === 0)
|
|
185
|
+
return "";
|
|
186
|
+
return `\n\n[${n} mock rule(s) active on ${device} — network_mock({action:"list"}) to inspect, {action:"clear"} to remove]`;
|
|
187
|
+
}
|
|
188
|
+
const parts = [];
|
|
189
|
+
let total = 0;
|
|
190
|
+
for (const [name, list] of rulesByDevice.entries()) {
|
|
191
|
+
if (list.length === 0)
|
|
192
|
+
continue;
|
|
193
|
+
total += list.length;
|
|
194
|
+
parts.push(`${list.length} on ${name}`);
|
|
195
|
+
}
|
|
196
|
+
if (total === 0)
|
|
197
|
+
return "";
|
|
198
|
+
return `\n\n[${total} mock rule(s) active (${parts.join(", ")}) — responses below may be altered. network_mock({action:"list"}) to inspect, {action:"clear"} to remove]`;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=mockRules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockRules.js","sourceRoot":"","sources":["../../src/core/mockRules.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execFileAsync } from "./exec.js";
|
|
2
2
|
function parseIosFields(json) {
|
|
3
3
|
const out = [];
|
|
4
4
|
let tree;
|
|
@@ -56,14 +56,14 @@ export const readNativeFields = async (platform, deviceId) => {
|
|
|
56
56
|
if (platform === "ios") {
|
|
57
57
|
if (!deviceId)
|
|
58
58
|
return { fields: [], error: "no simulator UDID" };
|
|
59
|
-
const { stdout } = await
|
|
59
|
+
const { stdout } = await execFileAsync("axe", ["describe-ui", "--udid", deviceId], { timeout: 20_000 });
|
|
60
60
|
return { fields: parseIosFields(stdout) };
|
|
61
61
|
}
|
|
62
|
-
const target = deviceId ?
|
|
62
|
+
const target = deviceId ? ["-s", deviceId] : [];
|
|
63
63
|
const path = "/sdcard/execbro-ui.xml";
|
|
64
|
-
await
|
|
65
|
-
const dump = await
|
|
66
|
-
const { stdout } = await
|
|
64
|
+
await execFileAsync("adb", [...target, "shell", `rm -f ${path}`], { timeout: 10_000 }).catch(() => undefined);
|
|
65
|
+
const dump = await execFileAsync("adb", [...target, "shell", `uiautomator dump ${path}`], { timeout: 20_000 });
|
|
66
|
+
const { stdout } = await execFileAsync("adb", [...target, "shell", `cat ${path}`], { timeout: 20_000 });
|
|
67
67
|
if (!stdout.includes("<node")) {
|
|
68
68
|
const why = `${dump.stdout} ${dump.stderr}`.trim().replace(/\s+/g, " ").slice(0, 160);
|
|
69
69
|
return { fields: [], error: `uiautomator dump produced no hierarchy${why ? `: ${why}` : ""}` };
|