@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.
Files changed (181) hide show
  1. package/README.en.md +33 -217
  2. package/README.md +33 -246
  3. package/dist/in-app/auto.d.ts +1 -138
  4. package/dist/in-app/auto.js +28 -1102
  5. package/dist/in-app/auto.js.map +1 -1
  6. package/dist/in-app/index.d.ts +38 -547
  7. package/dist/in-app/index.d.ts.map +1 -1
  8. package/dist/in-app/index.js +62 -939
  9. package/dist/in-app/index.js.map +1 -1
  10. package/dist/mcp/cli.d.ts +1 -54
  11. package/dist/mcp/cli.js +33 -9720
  12. package/dist/mcp/cli.js.map +1 -1
  13. package/dist/mcp/server.d.ts +1 -88
  14. package/dist/mcp/server.js +36 -1076
  15. package/dist/mcp/server.js.map +1 -1
  16. package/dist/mock/index.d.ts +19 -20
  17. package/dist/mock/index.d.ts.map +1 -1
  18. package/dist/mock/index.js.map +1 -1
  19. package/dist/panel/index.js +1 -103
  20. package/dist/panel/index.js.map +1 -1
  21. package/dist/relay-url-store-CPZAn-T5.js +107 -0
  22. package/dist/relay-url-store-CPZAn-T5.js.map +1 -0
  23. package/dist/relay-url-store-DLjlvMSA.cjs +108 -0
  24. package/dist/relay-url-store-DLjlvMSA.cjs.map +1 -0
  25. package/dist/stubs/bin-devtools-mcp.js +58 -0
  26. package/dist/stubs/bin-devtools-mcp.js.map +1 -0
  27. package/dist/stubs/bin-devtools-test.d.ts +2 -0
  28. package/dist/stubs/bin-devtools-test.js +55 -0
  29. package/dist/stubs/bin-devtools-test.js.map +1 -0
  30. package/dist/test-runner/config.d.ts +1 -231
  31. package/dist/test-runner/config.js +41 -45
  32. package/dist/test-runner/config.js.map +1 -1
  33. package/dist/{tunnel-BGT9Curk.cjs → tunnel-BKZkOyQp.cjs} +1 -1
  34. package/dist/{tunnel-BGT9Curk.cjs.map → tunnel-BKZkOyQp.cjs.map} +1 -1
  35. package/dist/{tunnel-BOKmLzBO.js → tunnel-CqSCIrdU.js} +1 -1
  36. package/dist/{tunnel-BOKmLzBO.js.map → tunnel-CqSCIrdU.js.map} +1 -1
  37. package/dist/unplugin/index.cjs +9 -18
  38. package/dist/unplugin/index.cjs.map +1 -1
  39. package/dist/unplugin/index.d.cts +22 -3
  40. package/dist/unplugin/index.d.cts.map +1 -1
  41. package/dist/unplugin/index.d.ts +23 -4
  42. package/dist/unplugin/index.d.ts.map +1 -1
  43. package/dist/unplugin/index.js +10 -19
  44. package/dist/unplugin/index.js.map +1 -1
  45. package/package.json +10 -25
  46. package/dist/attach-orchestrator-0F0m_UqQ.js +0 -1845
  47. package/dist/attach-orchestrator-0F0m_UqQ.js.map +0 -1
  48. package/dist/attach-orchestrator-D65KxFy_.js +0 -1831
  49. package/dist/attach-orchestrator-D65KxFy_.js.map +0 -1
  50. package/dist/attach-orchestrator-DL3NQ9ca.js +0 -1846
  51. package/dist/attach-orchestrator-DL3NQ9ca.js.map +0 -1
  52. package/dist/bundle-C796JIwG.d.ts +0 -159
  53. package/dist/bundle-C796JIwG.d.ts.map +0 -1
  54. package/dist/capture-DsP525OZ.d.ts +0 -58
  55. package/dist/capture-DsP525OZ.d.ts.map +0 -1
  56. package/dist/cdp-connection-rP1WdnH5.d.ts +0 -287
  57. package/dist/cdp-connection-rP1WdnH5.d.ts.map +0 -1
  58. package/dist/cell-BaLvusOl.js +0 -68
  59. package/dist/cell-BaLvusOl.js.map +0 -1
  60. package/dist/cell-CBUS3-nT.js +0 -274
  61. package/dist/cell-CBUS3-nT.js.map +0 -1
  62. package/dist/cell-EBKKpAAT.js +0 -307
  63. package/dist/cell-EBKKpAAT.js.map +0 -1
  64. package/dist/chii-relay-B3ZhjGMi.js +0 -304
  65. package/dist/chii-relay-B3ZhjGMi.js.map +0 -1
  66. package/dist/chii-relay-CGMlePMd.cjs +0 -304
  67. package/dist/chii-relay-CGMlePMd.cjs.map +0 -1
  68. package/dist/debug-server-B3ABDrRI.js +0 -456
  69. package/dist/debug-server-B3ABDrRI.js.map +0 -1
  70. package/dist/debug-server-BWhwrVXa.js +0 -1158
  71. package/dist/debug-server-BWhwrVXa.js.map +0 -1
  72. package/dist/debug-server-CfQNxxGW.js +0 -600
  73. package/dist/debug-server-CfQNxxGW.js.map +0 -1
  74. package/dist/devtools-opener-3Drge_RJ.js +0 -75
  75. package/dist/devtools-opener-3Drge_RJ.js.map +0 -1
  76. package/dist/devtools-opener-CJpEsXXQ.js +0 -76
  77. package/dist/devtools-opener-CJpEsXXQ.js.map +0 -1
  78. package/dist/devtools-opener-CxtryS8c.js +0 -75
  79. package/dist/devtools-opener-CxtryS8c.js.map +0 -1
  80. package/dist/in-app/auto.d.ts.map +0 -1
  81. package/dist/mcp/cli.d.ts.map +0 -1
  82. package/dist/mcp/server.d.ts.map +0 -1
  83. package/dist/pool-DcaaOwUq.d.ts +0 -14761
  84. package/dist/pool-DcaaOwUq.d.ts.map +0 -1
  85. package/dist/qr-http-server-C_lqOrgc.js +0 -1644
  86. package/dist/qr-http-server-C_lqOrgc.js.map +0 -1
  87. package/dist/qr-http-server-CopuMbub.js +0 -1644
  88. package/dist/qr-http-server-CopuMbub.js.map +0 -1
  89. package/dist/qr-http-server-DrbIVDjO.js +0 -1645
  90. package/dist/qr-http-server-DrbIVDjO.js.map +0 -1
  91. package/dist/relay-factory-N9QobQxG.js +0 -206
  92. package/dist/relay-factory-N9QobQxG.js.map +0 -1
  93. package/dist/relay-secret-store-BR0YIkNv.cjs +0 -241
  94. package/dist/relay-secret-store-BR0YIkNv.cjs.map +0 -1
  95. package/dist/relay-secret-store-Bmyleu0A.js +0 -154
  96. package/dist/relay-secret-store-Bmyleu0A.js.map +0 -1
  97. package/dist/relay-secret-store-CQenfcSL.js +0 -154
  98. package/dist/relay-secret-store-CQenfcSL.js.map +0 -1
  99. package/dist/relay-secret-store-CYM8CBIF.js +0 -240
  100. package/dist/relay-secret-store-CYM8CBIF.js.map +0 -1
  101. package/dist/relay-secret-store-DKxs7zwq.js +0 -153
  102. package/dist/relay-secret-store-DKxs7zwq.js.map +0 -1
  103. package/dist/relay-secret-store-WJ8EGkIl.js +0 -153
  104. package/dist/relay-secret-store-WJ8EGkIl.js.map +0 -1
  105. package/dist/relay-url-store-BR2XodiO.js +0 -123
  106. package/dist/relay-url-store-BR2XodiO.js.map +0 -1
  107. package/dist/relay-url-store-C1as_m5G.cjs +0 -115
  108. package/dist/relay-url-store-C1as_m5G.cjs.map +0 -1
  109. package/dist/relay-url-store-CH63fVCm.js +0 -122
  110. package/dist/relay-url-store-CH63fVCm.js.map +0 -1
  111. package/dist/relay-url-store-CzFo_84F.js +0 -114
  112. package/dist/relay-url-store-CzFo_84F.js.map +0 -1
  113. package/dist/relay-url-store-DaY1QPes.js +0 -123
  114. package/dist/relay-url-store-DaY1QPes.js.map +0 -1
  115. package/dist/relay-url-store-xmUuTjXA.js +0 -122
  116. package/dist/relay-url-store-xmUuTjXA.js.map +0 -1
  117. package/dist/relay-worker-B5HKkGUY.js +0 -832
  118. package/dist/relay-worker-B5HKkGUY.js.map +0 -1
  119. package/dist/relay-worker-YdlpZQl9.d.ts +0 -214
  120. package/dist/relay-worker-YdlpZQl9.d.ts.map +0 -1
  121. package/dist/rolldown-runtime-DGkTqVfb.js +0 -15
  122. package/dist/rolldown-runtime-DUslC3ob.js +0 -14
  123. package/dist/runtime-kn9DxOeg.d.ts +0 -249
  124. package/dist/runtime-kn9DxOeg.d.ts.map +0 -1
  125. package/dist/test-runner/bin.js +0 -2584
  126. package/dist/test-runner/bin.js.map +0 -1
  127. package/dist/test-runner/bridge-stub.d.ts +0 -125
  128. package/dist/test-runner/bridge-stub.d.ts.map +0 -1
  129. package/dist/test-runner/bridge-stub.js +0 -92
  130. package/dist/test-runner/bridge-stub.js.map +0 -1
  131. package/dist/test-runner/bundle.d.ts +0 -2
  132. package/dist/test-runner/bundle.js +0 -439
  133. package/dist/test-runner/bundle.js.map +0 -1
  134. package/dist/test-runner/capture.d.ts +0 -2
  135. package/dist/test-runner/capture.js +0 -44
  136. package/dist/test-runner/capture.js.map +0 -1
  137. package/dist/test-runner/config.d.ts.map +0 -1
  138. package/dist/test-runner/method-pace.d.ts +0 -82
  139. package/dist/test-runner/method-pace.d.ts.map +0 -1
  140. package/dist/test-runner/method-pace.js +0 -120
  141. package/dist/test-runner/method-pace.js.map +0 -1
  142. package/dist/test-runner/pool.d.ts +0 -2
  143. package/dist/test-runner/pool.js +0 -136
  144. package/dist/test-runner/pool.js.map +0 -1
  145. package/dist/test-runner/relay-factory.d.ts +0 -11245
  146. package/dist/test-runner/relay-factory.d.ts.map +0 -1
  147. package/dist/test-runner/relay-factory.js +0 -206
  148. package/dist/test-runner/relay-factory.js.map +0 -1
  149. package/dist/test-runner/relay-worker.d.ts +0 -2
  150. package/dist/test-runner/relay-worker.js +0 -2
  151. package/dist/test-runner/report.d.ts +0 -163
  152. package/dist/test-runner/report.d.ts.map +0 -1
  153. package/dist/test-runner/report.js +0 -198
  154. package/dist/test-runner/report.js.map +0 -1
  155. package/dist/test-runner/rpc.d.ts +0 -56
  156. package/dist/test-runner/rpc.d.ts.map +0 -1
  157. package/dist/test-runner/rpc.js +0 -98
  158. package/dist/test-runner/rpc.js.map +0 -1
  159. package/dist/test-runner/runtime.d.ts +0 -2
  160. package/dist/test-runner/runtime.js +0 -659
  161. package/dist/test-runner/runtime.js.map +0 -1
  162. package/dist/test-runner/task-graph.d.ts +0 -38
  163. package/dist/test-runner/task-graph.d.ts.map +0 -1
  164. package/dist/test-runner/task-graph.js +0 -182
  165. package/dist/test-runner/task-graph.js.map +0 -1
  166. package/dist/throttle-DKKzX1qC.js +0 -59
  167. package/dist/throttle-DKKzX1qC.js.map +0 -1
  168. package/dist/totp-BqmCLSNA.js +0 -189
  169. package/dist/totp-BqmCLSNA.js.map +0 -1
  170. package/dist/totp-CMHR5lsW.cjs +0 -191
  171. package/dist/totp-CMHR5lsW.cjs.map +0 -1
  172. package/dist/totp-CZLLKfOC.js +0 -200
  173. package/dist/totp-CZLLKfOC.js.map +0 -1
  174. package/dist/totp-DAxys-r0.js +0 -199
  175. package/dist/totp-DAxys-r0.js.map +0 -1
  176. package/dist/totp-DfekTBk3.js +0 -211
  177. package/dist/totp-DfekTBk3.js.map +0 -1
  178. package/dist/totp-Dwft0Kz7.js +0 -3
  179. package/dist/totp-WY6l0ysP.js +0 -190
  180. package/dist/totp-WY6l0ysP.js.map +0 -1
  181. /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"}
@@ -1,2 +0,0 @@
1
- import { i as bundleTestFile, n as BundleResult, r as buildSdkRedirectModuleContents, t as BundleOptions } from "../bundle-C796JIwG.js";
2
- export { BundleOptions, BundleResult, buildSdkRedirectModuleContents, bundleTestFile };