@ait-co/devtools 0.1.144 → 0.2.0
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.en.md +33 -217
- package/README.md +33 -246
- package/dist/in-app/auto.d.ts +1 -138
- package/dist/in-app/auto.js +28 -1102
- package/dist/in-app/auto.js.map +1 -1
- package/dist/in-app/index.d.ts +38 -547
- package/dist/in-app/index.d.ts.map +1 -1
- package/dist/in-app/index.js +62 -939
- package/dist/in-app/index.js.map +1 -1
- package/dist/mcp/cli.d.ts +1 -54
- package/dist/mcp/cli.js +33 -9720
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -88
- package/dist/mcp/server.js +36 -1076
- package/dist/mcp/server.js.map +1 -1
- package/dist/mock/index.d.ts +19 -20
- package/dist/mock/index.d.ts.map +1 -1
- package/dist/mock/index.js.map +1 -1
- package/dist/panel/index.js +1 -103
- package/dist/panel/index.js.map +1 -1
- package/dist/relay-url-store-CPZAn-T5.js +107 -0
- package/dist/relay-url-store-CPZAn-T5.js.map +1 -0
- package/dist/relay-url-store-DLjlvMSA.cjs +108 -0
- package/dist/relay-url-store-DLjlvMSA.cjs.map +1 -0
- package/dist/stubs/bin-devtools-mcp.js +58 -0
- package/dist/stubs/bin-devtools-mcp.js.map +1 -0
- package/dist/stubs/bin-devtools-test.d.ts +2 -0
- package/dist/stubs/bin-devtools-test.js +55 -0
- package/dist/stubs/bin-devtools-test.js.map +1 -0
- package/dist/test-runner/config.d.ts +1 -231
- package/dist/test-runner/config.js +41 -45
- package/dist/test-runner/config.js.map +1 -1
- package/dist/{tunnel-BGT9Curk.cjs → tunnel-BKZkOyQp.cjs} +1 -1
- package/dist/{tunnel-BGT9Curk.cjs.map → tunnel-BKZkOyQp.cjs.map} +1 -1
- package/dist/{tunnel-BOKmLzBO.js → tunnel-CqSCIrdU.js} +1 -1
- package/dist/{tunnel-BOKmLzBO.js.map → tunnel-CqSCIrdU.js.map} +1 -1
- package/dist/unplugin/index.cjs +9 -18
- package/dist/unplugin/index.cjs.map +1 -1
- package/dist/unplugin/index.d.cts +22 -3
- package/dist/unplugin/index.d.cts.map +1 -1
- package/dist/unplugin/index.d.ts +23 -4
- package/dist/unplugin/index.d.ts.map +1 -1
- package/dist/unplugin/index.js +10 -19
- package/dist/unplugin/index.js.map +1 -1
- package/package.json +10 -25
- package/dist/attach-orchestrator-0F0m_UqQ.js +0 -1845
- package/dist/attach-orchestrator-0F0m_UqQ.js.map +0 -1
- package/dist/attach-orchestrator-D65KxFy_.js +0 -1831
- package/dist/attach-orchestrator-D65KxFy_.js.map +0 -1
- package/dist/attach-orchestrator-DL3NQ9ca.js +0 -1846
- package/dist/attach-orchestrator-DL3NQ9ca.js.map +0 -1
- package/dist/bundle-C796JIwG.d.ts +0 -159
- package/dist/bundle-C796JIwG.d.ts.map +0 -1
- package/dist/capture-DsP525OZ.d.ts +0 -58
- package/dist/capture-DsP525OZ.d.ts.map +0 -1
- package/dist/cdp-connection-rP1WdnH5.d.ts +0 -287
- package/dist/cdp-connection-rP1WdnH5.d.ts.map +0 -1
- package/dist/cell-BaLvusOl.js +0 -68
- package/dist/cell-BaLvusOl.js.map +0 -1
- package/dist/cell-CBUS3-nT.js +0 -274
- package/dist/cell-CBUS3-nT.js.map +0 -1
- package/dist/cell-EBKKpAAT.js +0 -307
- package/dist/cell-EBKKpAAT.js.map +0 -1
- package/dist/chii-relay-B3ZhjGMi.js +0 -304
- package/dist/chii-relay-B3ZhjGMi.js.map +0 -1
- package/dist/chii-relay-CGMlePMd.cjs +0 -304
- package/dist/chii-relay-CGMlePMd.cjs.map +0 -1
- package/dist/debug-server-B3ABDrRI.js +0 -456
- package/dist/debug-server-B3ABDrRI.js.map +0 -1
- package/dist/debug-server-BWhwrVXa.js +0 -1158
- package/dist/debug-server-BWhwrVXa.js.map +0 -1
- package/dist/debug-server-CfQNxxGW.js +0 -600
- package/dist/debug-server-CfQNxxGW.js.map +0 -1
- package/dist/devtools-opener-3Drge_RJ.js +0 -75
- package/dist/devtools-opener-3Drge_RJ.js.map +0 -1
- package/dist/devtools-opener-CJpEsXXQ.js +0 -76
- package/dist/devtools-opener-CJpEsXXQ.js.map +0 -1
- package/dist/devtools-opener-CxtryS8c.js +0 -75
- package/dist/devtools-opener-CxtryS8c.js.map +0 -1
- package/dist/in-app/auto.d.ts.map +0 -1
- package/dist/mcp/cli.d.ts.map +0 -1
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/pool-DcaaOwUq.d.ts +0 -14761
- package/dist/pool-DcaaOwUq.d.ts.map +0 -1
- package/dist/qr-http-server-C_lqOrgc.js +0 -1644
- package/dist/qr-http-server-C_lqOrgc.js.map +0 -1
- package/dist/qr-http-server-CopuMbub.js +0 -1644
- package/dist/qr-http-server-CopuMbub.js.map +0 -1
- package/dist/qr-http-server-DrbIVDjO.js +0 -1645
- package/dist/qr-http-server-DrbIVDjO.js.map +0 -1
- package/dist/relay-factory-N9QobQxG.js +0 -206
- package/dist/relay-factory-N9QobQxG.js.map +0 -1
- package/dist/relay-secret-store-BR0YIkNv.cjs +0 -241
- package/dist/relay-secret-store-BR0YIkNv.cjs.map +0 -1
- package/dist/relay-secret-store-Bmyleu0A.js +0 -154
- package/dist/relay-secret-store-Bmyleu0A.js.map +0 -1
- package/dist/relay-secret-store-CQenfcSL.js +0 -154
- package/dist/relay-secret-store-CQenfcSL.js.map +0 -1
- package/dist/relay-secret-store-CYM8CBIF.js +0 -240
- package/dist/relay-secret-store-CYM8CBIF.js.map +0 -1
- package/dist/relay-secret-store-DKxs7zwq.js +0 -153
- package/dist/relay-secret-store-DKxs7zwq.js.map +0 -1
- package/dist/relay-secret-store-WJ8EGkIl.js +0 -153
- package/dist/relay-secret-store-WJ8EGkIl.js.map +0 -1
- package/dist/relay-url-store-BR2XodiO.js +0 -123
- package/dist/relay-url-store-BR2XodiO.js.map +0 -1
- package/dist/relay-url-store-C1as_m5G.cjs +0 -115
- package/dist/relay-url-store-C1as_m5G.cjs.map +0 -1
- package/dist/relay-url-store-CH63fVCm.js +0 -122
- package/dist/relay-url-store-CH63fVCm.js.map +0 -1
- package/dist/relay-url-store-CzFo_84F.js +0 -114
- package/dist/relay-url-store-CzFo_84F.js.map +0 -1
- package/dist/relay-url-store-DaY1QPes.js +0 -123
- package/dist/relay-url-store-DaY1QPes.js.map +0 -1
- package/dist/relay-url-store-xmUuTjXA.js +0 -122
- package/dist/relay-url-store-xmUuTjXA.js.map +0 -1
- package/dist/relay-worker-B5HKkGUY.js +0 -832
- package/dist/relay-worker-B5HKkGUY.js.map +0 -1
- package/dist/relay-worker-YdlpZQl9.d.ts +0 -214
- package/dist/relay-worker-YdlpZQl9.d.ts.map +0 -1
- package/dist/rolldown-runtime-DGkTqVfb.js +0 -15
- package/dist/rolldown-runtime-DUslC3ob.js +0 -14
- package/dist/runtime-kn9DxOeg.d.ts +0 -249
- package/dist/runtime-kn9DxOeg.d.ts.map +0 -1
- package/dist/test-runner/bin.js +0 -2584
- package/dist/test-runner/bin.js.map +0 -1
- package/dist/test-runner/bridge-stub.d.ts +0 -125
- package/dist/test-runner/bridge-stub.d.ts.map +0 -1
- package/dist/test-runner/bridge-stub.js +0 -92
- package/dist/test-runner/bridge-stub.js.map +0 -1
- package/dist/test-runner/bundle.d.ts +0 -2
- package/dist/test-runner/bundle.js +0 -439
- package/dist/test-runner/bundle.js.map +0 -1
- package/dist/test-runner/capture.d.ts +0 -2
- package/dist/test-runner/capture.js +0 -44
- package/dist/test-runner/capture.js.map +0 -1
- package/dist/test-runner/config.d.ts.map +0 -1
- package/dist/test-runner/method-pace.d.ts +0 -82
- package/dist/test-runner/method-pace.d.ts.map +0 -1
- package/dist/test-runner/method-pace.js +0 -120
- package/dist/test-runner/method-pace.js.map +0 -1
- package/dist/test-runner/pool.d.ts +0 -2
- package/dist/test-runner/pool.js +0 -136
- package/dist/test-runner/pool.js.map +0 -1
- package/dist/test-runner/relay-factory.d.ts +0 -11245
- package/dist/test-runner/relay-factory.d.ts.map +0 -1
- package/dist/test-runner/relay-factory.js +0 -206
- package/dist/test-runner/relay-factory.js.map +0 -1
- package/dist/test-runner/relay-worker.d.ts +0 -2
- package/dist/test-runner/relay-worker.js +0 -2
- package/dist/test-runner/report.d.ts +0 -163
- package/dist/test-runner/report.d.ts.map +0 -1
- package/dist/test-runner/report.js +0 -198
- package/dist/test-runner/report.js.map +0 -1
- package/dist/test-runner/rpc.d.ts +0 -56
- package/dist/test-runner/rpc.d.ts.map +0 -1
- package/dist/test-runner/rpc.js +0 -98
- package/dist/test-runner/rpc.js.map +0 -1
- package/dist/test-runner/runtime.d.ts +0 -2
- package/dist/test-runner/runtime.js +0 -659
- package/dist/test-runner/runtime.js.map +0 -1
- package/dist/test-runner/task-graph.d.ts +0 -38
- package/dist/test-runner/task-graph.d.ts.map +0 -1
- package/dist/test-runner/task-graph.js +0 -182
- package/dist/test-runner/task-graph.js.map +0 -1
- package/dist/throttle-DKKzX1qC.js +0 -59
- package/dist/throttle-DKKzX1qC.js.map +0 -1
- package/dist/totp-BqmCLSNA.js +0 -189
- package/dist/totp-BqmCLSNA.js.map +0 -1
- package/dist/totp-CMHR5lsW.cjs +0 -191
- package/dist/totp-CMHR5lsW.cjs.map +0 -1
- package/dist/totp-CZLLKfOC.js +0 -200
- package/dist/totp-CZLLKfOC.js.map +0 -1
- package/dist/totp-DAxys-r0.js +0 -199
- package/dist/totp-DAxys-r0.js.map +0 -1
- package/dist/totp-DfekTBk3.js +0 -211
- package/dist/totp-DfekTBk3.js.map +0 -1
- package/dist/totp-Dwft0Kz7.js +0 -3
- package/dist/totp-WY6l0ysP.js +0 -190
- package/dist/totp-WY6l0ysP.js.map +0 -1
- /package/dist/{test-runner/bin.d.ts → stubs/bin-devtools-mcp.d.ts} +0 -0
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
//#region src/test-runner/bridge-stub.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Bridge-stub interceptor for env3 blocking-UI SDK calls (devtools#740, DT-2).
|
|
4
|
-
*
|
|
5
|
-
* `--manual-blocking` (devtools#741) lets a human tap through native-UI SDK
|
|
6
|
-
* calls (fullscreen ads, permission dialogs, the save-file share sheet) so
|
|
7
|
-
* their real device behaviour can be captured. That capture (sdk-example
|
|
8
|
-
* run11, 2026-07-05, 2.x/iOS) is the ground truth this module replays: an
|
|
9
|
-
* opt-in interceptor that sits BETWEEN the test bundle and the real native
|
|
10
|
-
* bridge (`window.__sdk`, installed by `src/in-app/auto.ts`) and answers a
|
|
11
|
-
* fixed allowlist of blocking calls with fixture-shaped responses instead of
|
|
12
|
-
* forwarding them to native UI. This lets the SAME manual-tagged test files
|
|
13
|
-
* run unattended, so their assertions (denied-permission error shape,
|
|
14
|
-
* `NO_PERMISSION` envelope, etc.) become part of a CI-checkable contract
|
|
15
|
-
* instead of only ever running with a human present.
|
|
16
|
-
*
|
|
17
|
-
* HONESTY CONTRACT (devtools#740): a stubbed run is NOT env3 in the pure
|
|
18
|
-
* sense — it is a HYBRID cell (real device + real WebView + real bridge
|
|
19
|
-
* transport for every OTHER call, but a synthetic answer for the handful of
|
|
20
|
-
* calls in {@link STUB_REGISTRY}). Every artifact produced under this mode
|
|
21
|
-
* MUST be provenance-stamped (`cell.bridgeStub: true`, see `report.ts`) and
|
|
22
|
-
* MUST NOT be merged into the same file/mode as an unattended baseline run.
|
|
23
|
-
* A stubbed PASS proves "the SDK's rejection/resolution path behaves as
|
|
24
|
-
* fixture-shaped" — it does NOT prove the real native dialog/sheet still
|
|
25
|
-
* looks or behaves a given way on-device. Real behavior re-verification stays
|
|
26
|
-
* on `--manual-blocking` (DT-3) — this module never replaces it, only adds an
|
|
27
|
-
* unattended CHECK on top of what it captured.
|
|
28
|
-
*
|
|
29
|
-
* DRIFT AVOIDANCE: fixtures are frozen snapshots of a real capture. If the
|
|
30
|
-
* native SDK's error shape ever changes, only a fresh `--manual-blocking` run
|
|
31
|
-
* (DT-3) can tell you — this module has no way to detect drift on its own.
|
|
32
|
-
* Treat {@link STUB_REGISTRY} as "last known native truth", not as a
|
|
33
|
-
* specification devtools owns.
|
|
34
|
-
*
|
|
35
|
-
* Runs entirely on the PAGE side (browser-compatible, no Node APIs) — this
|
|
36
|
-
* file is bundled into the injected IIFE by `bundle.ts`'s `sdkRedirectPlugin`,
|
|
37
|
-
* mirroring how `runtime.ts` is bundled. It is imported ONLY from the
|
|
38
|
-
* test-runner (never from `sdk-example/src` — boilerplate cleanliness,
|
|
39
|
-
* umbrella §1.4: this is maintainer/runner infrastructure, not something a
|
|
40
|
-
* mini-app developer's shipped code should carry).
|
|
41
|
-
*
|
|
42
|
-
* SECRET-HANDLING: fixtures below are hand-derived summaries of the captured
|
|
43
|
-
* shapes (see per-entry doc comments citing the source scenario) — no device
|
|
44
|
-
* identifiers, tunnel hosts, relay URLs, or auth codes are embedded anywhere
|
|
45
|
-
* in this file.
|
|
46
|
-
*/
|
|
47
|
-
/**
|
|
48
|
-
* The exact shape a rejected native bridge call takes on iOS/2.x (and,
|
|
49
|
-
* empirically, unchanged across the manual captures this module replays).
|
|
50
|
-
* Mirrors the `errorKeys` observed in the ground-truth capture:
|
|
51
|
-
* `['name', 'code', 'userInfo', 'moduleName', '__isError']`.
|
|
52
|
-
*/
|
|
53
|
-
interface NativeBridgeErrorShape {
|
|
54
|
-
name: string;
|
|
55
|
-
code: string;
|
|
56
|
-
message: string;
|
|
57
|
-
userInfo: Record<string, unknown>;
|
|
58
|
-
moduleName: string;
|
|
59
|
-
__isError: true;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* One blocking-call stub entry. `kind` distinguishes the two native calling
|
|
63
|
-
* conventions observed in the mock/real SDK:
|
|
64
|
-
* - `'promise'` — the call returns a Promise the stub resolves/rejects
|
|
65
|
-
* (`openPermissionDialog`, `requestPermission`, `saveBase64Data`).
|
|
66
|
-
* - `'event'` — the call takes `{ onEvent, onError }` callbacks and returns
|
|
67
|
-
* a cleanup function (`showFullScreenAd`) — the native fullscreen-ad flow
|
|
68
|
-
* never resolves a Promise; it fires events instead.
|
|
69
|
-
*/
|
|
70
|
-
type StubEntry = {
|
|
71
|
-
kind: 'promise'; /** Pure factory so each call gets a fresh value/error (no shared mutable state). */
|
|
72
|
-
resolve: (args: unknown) => unknown;
|
|
73
|
-
} | {
|
|
74
|
-
kind: 'event';
|
|
75
|
-
/**
|
|
76
|
-
* Invoked synchronously with the same `args` the real call would
|
|
77
|
-
* receive; calls `args.onEvent`/`args.onError` per the fixture and
|
|
78
|
-
* returns a no-op cleanup function.
|
|
79
|
-
*/
|
|
80
|
-
run: (args: {
|
|
81
|
-
onEvent: (e: unknown) => void;
|
|
82
|
-
onError: (e: unknown) => void;
|
|
83
|
-
}) => () => void;
|
|
84
|
-
};
|
|
85
|
-
/**
|
|
86
|
-
* Fixture-shaped default responses for the blocking-UI APIs named in
|
|
87
|
-
* devtools#740 as the smallest viable surface: ads `show*`, permissions
|
|
88
|
-
* `openPermissionDialog`/`requestPermission`, storage `saveBase64Data`.
|
|
89
|
-
*
|
|
90
|
-
* Each entry cites the exact `.ait-capture` record (sdk-example run11,
|
|
91
|
-
* 2026-07-05, 2.x/iOS) it was derived from — see the PR body for the full
|
|
92
|
-
* source table. Only the REPRESENTATIVE shape is kept (one success + one
|
|
93
|
-
* native-error per API where the capture contains both); this is a fixed v1
|
|
94
|
-
* default set, not a scenario-selectable registry — see `resolveStubOutcome`
|
|
95
|
-
* for how a test can still opt into the error branch.
|
|
96
|
-
*/
|
|
97
|
-
declare const STUB_REGISTRY: Record<string, StubEntry>;
|
|
98
|
-
/** The allowlisted API names {@link STUB_REGISTRY} can intercept. */
|
|
99
|
-
type StubbableApiName = keyof typeof STUB_REGISTRY;
|
|
100
|
-
/**
|
|
101
|
-
* Wraps a `window.__sdk`-shaped bridge object so that calls to any name in
|
|
102
|
-
* {@link STUB_REGISTRY} are answered from the fixture instead of forwarded to
|
|
103
|
-
* `sdk`. Every other property (including non-stubbed functions) passes
|
|
104
|
-
* through UNCHANGED — this is a targeted intercept, not a blanket mock.
|
|
105
|
-
*
|
|
106
|
-
* Returns `sdk` itself, untouched, when `enabled` is false — the exact
|
|
107
|
-
* object identity is preserved so the zero-diff-when-off contract holds even
|
|
108
|
-
* under strict-equality checks in a caller.
|
|
109
|
-
*
|
|
110
|
-
* @param sdk - The real bridge namespace object (`window.__sdk`).
|
|
111
|
-
* @param enabled - Gate — mirrors the `--stub-blocking` CLI flag /
|
|
112
|
-
* `__AIT_STUB_BLOCKING__` page global. Defaults to `false`.
|
|
113
|
-
*/
|
|
114
|
-
declare function wrapSdkWithStub(sdk: Record<string, unknown>, enabled: boolean): Record<string, unknown>;
|
|
115
|
-
/**
|
|
116
|
-
* Reads the page-global stub-blocking gate. Mirrors the pattern
|
|
117
|
-
* `runtime.ts`/`cell.ts` use for `__AIT_CELL__`/`__AIT_PERMS__` — a plain
|
|
118
|
-
* `globalThis` property injected via `injectGlobals` (Node side, `cell.ts`)
|
|
119
|
-
* BEFORE the first test bundle runs. Absent/false = disabled (default),
|
|
120
|
-
* matching every other opt-in flag in this runner.
|
|
121
|
-
*/
|
|
122
|
-
declare function isStubBlockingEnabled(): boolean;
|
|
123
|
-
//#endregion
|
|
124
|
-
export { NativeBridgeErrorShape, STUB_REGISTRY, StubEntry, StubbableApiName, isStubBlockingEnabled, wrapSdkWithStub };
|
|
125
|
-
//# sourceMappingURL=bridge-stub.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-stub.d.ts","names":[],"sources":["../../src/test-runner/bridge-stub.ts"],"mappings":";;AAoDA;;;;;;;;;;;;;AAkCA;;;;;;;;;;;;;;;;AA4BA;;;;;AAgDA;;;;;AAgBA;;;;;;;;;;AAoCA;UAlKiB,sBAAA;EACf,IAAA;EACA,IAAA;EACA,OAAA;EACA,QAAA,EAAU,MAAA;EACV,UAAA;EACA,SAAA;AAAA;;;;;;;;;;KA4BU,SAAA;EAEN,IAAA;EAEA,OAAA,GAAU,IAAA;AAAA;EAGV,IAAA;;;;;;EAMA,GAAA,GAAM,IAAA;IAAQ,OAAA,GAAU,CAAA;IAAqB,OAAA,GAAU,CAAA;EAAA;AAAA;;;;;;;;;;;;;cAehD,aAAA,EAAe,MAAA,SAAe,SAAA;;KAgD/B,gBAAA,gBAAgC,aAAA;;;;;;;;;;;;;;;iBAgB5B,eAAA,CACd,GAAA,EAAK,MAAA,mBACL,OAAA,YACC,MAAA;;;;;;;;iBAiCa,qBAAA,CAAA"}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
//#region src/test-runner/bridge-stub.ts
|
|
2
|
-
/** Builds a {@link NativeBridgeErrorShape}-compatible `Error` instance. */
|
|
3
|
-
function makeNativeError(code, message, moduleName, userInfo = {}) {
|
|
4
|
-
const err = new Error(message);
|
|
5
|
-
err.name = "Error";
|
|
6
|
-
err.code = code;
|
|
7
|
-
err.userInfo = userInfo;
|
|
8
|
-
err.moduleName = moduleName;
|
|
9
|
-
err.__isError = true;
|
|
10
|
-
return err;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Fixture-shaped default responses for the blocking-UI APIs named in
|
|
14
|
-
* devtools#740 as the smallest viable surface: ads `show*`, permissions
|
|
15
|
-
* `openPermissionDialog`/`requestPermission`, storage `saveBase64Data`.
|
|
16
|
-
*
|
|
17
|
-
* Each entry cites the exact `.ait-capture` record (sdk-example run11,
|
|
18
|
-
* 2026-07-05, 2.x/iOS) it was derived from — see the PR body for the full
|
|
19
|
-
* source table. Only the REPRESENTATIVE shape is kept (one success + one
|
|
20
|
-
* native-error per API where the capture contains both); this is a fixed v1
|
|
21
|
-
* default set, not a scenario-selectable registry — see `resolveStubOutcome`
|
|
22
|
-
* for how a test can still opt into the error branch.
|
|
23
|
-
*/
|
|
24
|
-
const STUB_REGISTRY = {
|
|
25
|
-
openPermissionDialog: {
|
|
26
|
-
kind: "promise",
|
|
27
|
-
resolve: () => "allowed"
|
|
28
|
-
},
|
|
29
|
-
requestPermission: {
|
|
30
|
-
kind: "promise",
|
|
31
|
-
resolve: () => {
|
|
32
|
-
throw makeNativeError("NO_PERMISSION", "No permission", "RNPermissions");
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
saveBase64Data: {
|
|
36
|
-
kind: "promise",
|
|
37
|
-
resolve: () => void 0
|
|
38
|
-
},
|
|
39
|
-
showFullScreenAd: {
|
|
40
|
-
kind: "event",
|
|
41
|
-
run: (args) => {
|
|
42
|
-
const err = /* @__PURE__ */ new Error("광고가 로드 중이거나 준비되지 않았습니다");
|
|
43
|
-
err.code = "1006";
|
|
44
|
-
args.onError(err);
|
|
45
|
-
return () => {};
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* Wraps a `window.__sdk`-shaped bridge object so that calls to any name in
|
|
51
|
-
* {@link STUB_REGISTRY} are answered from the fixture instead of forwarded to
|
|
52
|
-
* `sdk`. Every other property (including non-stubbed functions) passes
|
|
53
|
-
* through UNCHANGED — this is a targeted intercept, not a blanket mock.
|
|
54
|
-
*
|
|
55
|
-
* Returns `sdk` itself, untouched, when `enabled` is false — the exact
|
|
56
|
-
* object identity is preserved so the zero-diff-when-off contract holds even
|
|
57
|
-
* under strict-equality checks in a caller.
|
|
58
|
-
*
|
|
59
|
-
* @param sdk - The real bridge namespace object (`window.__sdk`).
|
|
60
|
-
* @param enabled - Gate — mirrors the `--stub-blocking` CLI flag /
|
|
61
|
-
* `__AIT_STUB_BLOCKING__` page global. Defaults to `false`.
|
|
62
|
-
*/
|
|
63
|
-
function wrapSdkWithStub(sdk, enabled) {
|
|
64
|
-
if (!enabled) return sdk;
|
|
65
|
-
return new Proxy(sdk, { get(target, prop, receiver) {
|
|
66
|
-
if (typeof prop === "string" && Object.hasOwn(STUB_REGISTRY, prop)) return buildStubFunction(prop);
|
|
67
|
-
return Reflect.get(target, prop, receiver);
|
|
68
|
-
} });
|
|
69
|
-
}
|
|
70
|
-
/** Builds the callable replacement for a single stubbed API name. */
|
|
71
|
-
function buildStubFunction(name) {
|
|
72
|
-
const entry = STUB_REGISTRY[name];
|
|
73
|
-
if (entry.kind === "promise") return async (...args) => entry.resolve(args[0]);
|
|
74
|
-
return (...args) => {
|
|
75
|
-
const callArgs = args[0];
|
|
76
|
-
return entry.run(callArgs);
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Reads the page-global stub-blocking gate. Mirrors the pattern
|
|
81
|
-
* `runtime.ts`/`cell.ts` use for `__AIT_CELL__`/`__AIT_PERMS__` — a plain
|
|
82
|
-
* `globalThis` property injected via `injectGlobals` (Node side, `cell.ts`)
|
|
83
|
-
* BEFORE the first test bundle runs. Absent/false = disabled (default),
|
|
84
|
-
* matching every other opt-in flag in this runner.
|
|
85
|
-
*/
|
|
86
|
-
function isStubBlockingEnabled() {
|
|
87
|
-
return globalThis.__AIT_STUB_BLOCKING__ === true;
|
|
88
|
-
}
|
|
89
|
-
//#endregion
|
|
90
|
-
export { STUB_REGISTRY, isStubBlockingEnabled, wrapSdkWithStub };
|
|
91
|
-
|
|
92
|
-
//# sourceMappingURL=bridge-stub.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-stub.js","names":[],"sources":["../../src/test-runner/bridge-stub.ts"],"sourcesContent":["/**\n * Bridge-stub interceptor for env3 blocking-UI SDK calls (devtools#740, DT-2).\n *\n * `--manual-blocking` (devtools#741) lets a human tap through native-UI SDK\n * calls (fullscreen ads, permission dialogs, the save-file share sheet) so\n * their real device behaviour can be captured. That capture (sdk-example\n * run11, 2026-07-05, 2.x/iOS) is the ground truth this module replays: an\n * opt-in interceptor that sits BETWEEN the test bundle and the real native\n * bridge (`window.__sdk`, installed by `src/in-app/auto.ts`) and answers a\n * fixed allowlist of blocking calls with fixture-shaped responses instead of\n * forwarding them to native UI. This lets the SAME manual-tagged test files\n * run unattended, so their assertions (denied-permission error shape,\n * `NO_PERMISSION` envelope, etc.) become part of a CI-checkable contract\n * instead of only ever running with a human present.\n *\n * HONESTY CONTRACT (devtools#740): a stubbed run is NOT env3 in the pure\n * sense — it is a HYBRID cell (real device + real WebView + real bridge\n * transport for every OTHER call, but a synthetic answer for the handful of\n * calls in {@link STUB_REGISTRY}). Every artifact produced under this mode\n * MUST be provenance-stamped (`cell.bridgeStub: true`, see `report.ts`) and\n * MUST NOT be merged into the same file/mode as an unattended baseline run.\n * A stubbed PASS proves \"the SDK's rejection/resolution path behaves as\n * fixture-shaped\" — it does NOT prove the real native dialog/sheet still\n * looks or behaves a given way on-device. Real behavior re-verification stays\n * on `--manual-blocking` (DT-3) — this module never replaces it, only adds an\n * unattended CHECK on top of what it captured.\n *\n * DRIFT AVOIDANCE: fixtures are frozen snapshots of a real capture. If the\n * native SDK's error shape ever changes, only a fresh `--manual-blocking` run\n * (DT-3) can tell you — this module has no way to detect drift on its own.\n * Treat {@link STUB_REGISTRY} as \"last known native truth\", not as a\n * specification devtools owns.\n *\n * Runs entirely on the PAGE side (browser-compatible, no Node APIs) — this\n * file is bundled into the injected IIFE by `bundle.ts`'s `sdkRedirectPlugin`,\n * mirroring how `runtime.ts` is bundled. It is imported ONLY from the\n * test-runner (never from `sdk-example/src` — boilerplate cleanliness,\n * umbrella §1.4: this is maintainer/runner infrastructure, not something a\n * mini-app developer's shipped code should carry).\n *\n * SECRET-HANDLING: fixtures below are hand-derived summaries of the captured\n * shapes (see per-entry doc comments citing the source scenario) — no device\n * identifiers, tunnel hosts, relay URLs, or auth codes are embedded anywhere\n * in this file.\n */\n\n/**\n * The exact shape a rejected native bridge call takes on iOS/2.x (and,\n * empirically, unchanged across the manual captures this module replays).\n * Mirrors the `errorKeys` observed in the ground-truth capture:\n * `['name', 'code', 'userInfo', 'moduleName', '__isError']`.\n */\nexport interface NativeBridgeErrorShape {\n name: string;\n code: string;\n message: string;\n userInfo: Record<string, unknown>;\n moduleName: string;\n __isError: true;\n}\n\n/** Builds a {@link NativeBridgeErrorShape}-compatible `Error` instance. */\nfunction makeNativeError(\n code: string,\n message: string,\n moduleName: string,\n userInfo: Record<string, unknown> = {},\n): Error & NativeBridgeErrorShape {\n const err = new Error(message) as Error & NativeBridgeErrorShape;\n err.name = 'Error';\n err.code = code;\n err.userInfo = userInfo;\n err.moduleName = moduleName;\n err.__isError = true;\n return err;\n}\n\n/**\n * One blocking-call stub entry. `kind` distinguishes the two native calling\n * conventions observed in the mock/real SDK:\n * - `'promise'` — the call returns a Promise the stub resolves/rejects\n * (`openPermissionDialog`, `requestPermission`, `saveBase64Data`).\n * - `'event'` — the call takes `{ onEvent, onError }` callbacks and returns\n * a cleanup function (`showFullScreenAd`) — the native fullscreen-ad flow\n * never resolves a Promise; it fires events instead.\n */\nexport type StubEntry =\n | {\n kind: 'promise';\n /** Pure factory so each call gets a fresh value/error (no shared mutable state). */\n resolve: (args: unknown) => unknown;\n }\n | {\n kind: 'event';\n /**\n * Invoked synchronously with the same `args` the real call would\n * receive; calls `args.onEvent`/`args.onError` per the fixture and\n * returns a no-op cleanup function.\n */\n run: (args: { onEvent: (e: unknown) => void; onError: (e: unknown) => void }) => () => void;\n };\n\n/**\n * Fixture-shaped default responses for the blocking-UI APIs named in\n * devtools#740 as the smallest viable surface: ads `show*`, permissions\n * `openPermissionDialog`/`requestPermission`, storage `saveBase64Data`.\n *\n * Each entry cites the exact `.ait-capture` record (sdk-example run11,\n * 2026-07-05, 2.x/iOS) it was derived from — see the PR body for the full\n * source table. Only the REPRESENTATIVE shape is kept (one success + one\n * native-error per API where the capture contains both); this is a fixed v1\n * default set, not a scenario-selectable registry — see `resolveStubOutcome`\n * for how a test can still opt into the error branch.\n */\nexport const STUB_REGISTRY: Record<string, StubEntry> = {\n // Source: permissions.2.x.ios.json — scenario \"manual-native-dialog-camera\"\n // (outcome: resolved, value: 'allowed'). The capture's own resolved value\n // was a bare string, not an object — mirrored verbatim.\n openPermissionDialog: {\n kind: 'promise',\n resolve: () => 'allowed',\n },\n\n // Source: permissions.2.x.ios.json — scenario\n // \"manual-native-request-geolocation\" (outcome: rejected, isNativeShape:\n // true, errorCode: 'NO_PERMISSION', errorMessage: 'No permission'). This is\n // the exact envelope DT-2's issue body calls out (\"requestPermission→\n // 'denied' 스텁\") — the native denial path, not a synthetic message.\n requestPermission: {\n kind: 'promise',\n resolve: () => {\n throw makeNativeError('NO_PERMISSION', 'No permission', 'RNPermissions');\n },\n },\n\n // Source: storage.2.x.ios.json — scenario \"manual-happy-varied-mime-png\"\n // (outcome: resolved, returnType: 'undefined') — the real share-sheet call\n // resolves with no value on success.\n saveBase64Data: {\n kind: 'promise',\n resolve: () => undefined,\n },\n\n // Source: ads.2.x.ios.json — scenario \"manual-show\" (outcome: rejected,\n // errorCode: '1006', errorMessage: '광고가 로드 중이거나 준비되지 않았습니다').\n // showFullScreenAd never resolves/rejects a Promise on the real bridge — it\n // reports outcomes via onEvent/onError, so the representative capture\n // outcome is replayed as an onError call using the SAME error shape family\n // (isNativeShape: false in the capture — a plain Error, not the\n // name/code/userInfo/moduleName envelope).\n showFullScreenAd: {\n kind: 'event',\n run: (args) => {\n const err = new Error('광고가 로드 중이거나 준비되지 않았습니다') as Error & { code: string };\n err.code = '1006';\n args.onError(err);\n return () => {};\n },\n },\n};\n\n/** The allowlisted API names {@link STUB_REGISTRY} can intercept. */\nexport type StubbableApiName = keyof typeof STUB_REGISTRY;\n\n/**\n * Wraps a `window.__sdk`-shaped bridge object so that calls to any name in\n * {@link STUB_REGISTRY} are answered from the fixture instead of forwarded to\n * `sdk`. Every other property (including non-stubbed functions) passes\n * through UNCHANGED — this is a targeted intercept, not a blanket mock.\n *\n * Returns `sdk` itself, untouched, when `enabled` is false — the exact\n * object identity is preserved so the zero-diff-when-off contract holds even\n * under strict-equality checks in a caller.\n *\n * @param sdk - The real bridge namespace object (`window.__sdk`).\n * @param enabled - Gate — mirrors the `--stub-blocking` CLI flag /\n * `__AIT_STUB_BLOCKING__` page global. Defaults to `false`.\n */\nexport function wrapSdkWithStub(\n sdk: Record<string, unknown>,\n enabled: boolean,\n): Record<string, unknown> {\n if (!enabled) return sdk;\n\n return new Proxy(sdk, {\n get(target, prop, receiver) {\n if (typeof prop === 'string' && Object.hasOwn(STUB_REGISTRY, prop)) {\n return buildStubFunction(prop);\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n}\n\n/** Builds the callable replacement for a single stubbed API name. */\nfunction buildStubFunction(name: string): (...args: unknown[]) => unknown {\n const entry = STUB_REGISTRY[name];\n if (entry.kind === 'promise') {\n return async (...args: unknown[]) => entry.resolve(args[0]);\n }\n // 'event' kind: (args: { onEvent, onError, ... }) => cleanup\n return (...args: unknown[]) => {\n const callArgs = args[0] as { onEvent: (e: unknown) => void; onError: (e: unknown) => void };\n return entry.run(callArgs);\n };\n}\n\n/**\n * Reads the page-global stub-blocking gate. Mirrors the pattern\n * `runtime.ts`/`cell.ts` use for `__AIT_CELL__`/`__AIT_PERMS__` — a plain\n * `globalThis` property injected via `injectGlobals` (Node side, `cell.ts`)\n * BEFORE the first test bundle runs. Absent/false = disabled (default),\n * matching every other opt-in flag in this runner.\n */\nexport function isStubBlockingEnabled(): boolean {\n return (globalThis as { __AIT_STUB_BLOCKING__?: boolean }).__AIT_STUB_BLOCKING__ === true;\n}\n"],"mappings":";;AA8DA,SAAS,gBACP,MACA,SACA,YACA,WAAoC,EAAE,EACN;CAChC,MAAM,MAAM,IAAI,MAAM,QAAQ;AAC9B,KAAI,OAAO;AACX,KAAI,OAAO;AACX,KAAI,WAAW;AACf,KAAI,aAAa;AACjB,KAAI,YAAY;AAChB,QAAO;;;;;;;;;;;;;;AAwCT,MAAa,gBAA2C;CAItD,sBAAsB;EACpB,MAAM;EACN,eAAe;EAChB;CAOD,mBAAmB;EACjB,MAAM;EACN,eAAe;AACb,SAAM,gBAAgB,iBAAiB,iBAAiB,gBAAgB;;EAE3E;CAKD,gBAAgB;EACd,MAAM;EACN,eAAe,KAAA;EAChB;CASD,kBAAkB;EAChB,MAAM;EACN,MAAM,SAAS;GACb,MAAM,sBAAM,IAAI,MAAM,yBAAyB;AAC/C,OAAI,OAAO;AACX,QAAK,QAAQ,IAAI;AACjB,gBAAa;;EAEhB;CACF;;;;;;;;;;;;;;;AAmBD,SAAgB,gBACd,KACA,SACyB;AACzB,KAAI,CAAC,QAAS,QAAO;AAErB,QAAO,IAAI,MAAM,KAAK,EACpB,IAAI,QAAQ,MAAM,UAAU;AAC1B,MAAI,OAAO,SAAS,YAAY,OAAO,OAAO,eAAe,KAAK,CAChE,QAAO,kBAAkB,KAAK;AAEhC,SAAO,QAAQ,IAAI,QAAQ,MAAM,SAAS;IAE7C,CAAC;;;AAIJ,SAAS,kBAAkB,MAA+C;CACxE,MAAM,QAAQ,cAAc;AAC5B,KAAI,MAAM,SAAS,UACjB,QAAO,OAAO,GAAG,SAAoB,MAAM,QAAQ,KAAK,GAAG;AAG7D,SAAQ,GAAG,SAAoB;EAC7B,MAAM,WAAW,KAAK;AACtB,SAAO,MAAM,IAAI,SAAS;;;;;;;;;;AAW9B,SAAgB,wBAAiC;AAC/C,QAAQ,WAAmD,0BAA0B"}
|