@dimina-kit/devtools 0.4.0-dev.20260729062524 → 0.4.0-dev.20260801163345
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/dist/main/app/app.js +7 -0
- package/dist/main/app/bootstrap.d.ts +8 -5
- package/dist/main/app/bootstrap.js +15 -15
- package/dist/main/index.bundle.js +2207 -5152
- package/dist/main/ipc/app-lifecycle.d.ts +1 -31
- package/dist/main/ipc/app-lifecycle.js +1 -53
- package/dist/main/ipc/bridge-router.d.ts +19 -152
- package/dist/main/ipc/bridge-router.js +28 -2186
- package/dist/main/ipc/page-scroll.d.ts +1 -13
- package/dist/main/ipc/page-scroll.js +1 -16
- package/dist/main/ipc/session-listener-bag.d.ts +1 -40
- package/dist/main/ipc/session-listener-bag.js +1 -39
- package/dist/main/services/console-forward/index.d.ts +1 -60
- package/dist/main/services/console-forward/index.js +1 -225
- package/dist/main/services/console-forward/internal-log.d.ts +1 -10
- package/dist/main/services/console-forward/internal-log.js +1 -22
- package/dist/main/services/diagnostics/index.d.ts +1 -58
- package/dist/main/services/diagnostics/index.js +1 -60
- package/dist/main/services/dimina-resource-server.d.ts +1 -6
- package/dist/main/services/dimina-resource-server.js +1 -98
- package/dist/main/services/mcp/target-manager.js +5 -1
- package/dist/main/services/network-forward/index.d.ts +15 -3
- package/dist/main/services/network-forward/index.js +30 -4
- package/dist/main/services/network-forward/websocket.d.ts +36 -0
- package/dist/main/services/network-forward/websocket.js +120 -0
- package/dist/main/services/service-host-pool/pool.d.ts +1 -196
- package/dist/main/services/service-host-pool/pool.js +1 -363
- package/dist/main/services/simulator/custom-apis.d.ts +1 -42
- package/dist/main/services/simulator/custom-apis.js +1 -46
- package/dist/main/services/simulator/referer.d.ts +1 -9
- package/dist/main/services/simulator/referer.js +1 -19
- package/dist/main/services/simulator-storage/service-storage-ops.d.ts +1 -39
- package/dist/main/services/simulator-storage/service-storage-ops.js +1 -66
- package/dist/main/services/simulator-temp-files/disk.d.ts +1 -54
- package/dist/main/services/simulator-temp-files/disk.js +1 -237
- package/dist/main/services/simulator-temp-files/fs-channels.d.ts +1 -68
- package/dist/main/services/simulator-temp-files/fs-channels.js +1 -107
- package/dist/main/services/simulator-temp-files/index.d.ts +1 -32
- package/dist/main/services/simulator-temp-files/index.js +1 -181
- package/dist/main/services/simulator-temp-files/request-handler.d.ts +1 -29
- package/dist/main/services/simulator-temp-files/request-handler.js +1 -177
- package/dist/main/services/simulator-temp-files/resolver.d.ts +1 -21
- package/dist/main/services/simulator-temp-files/resolver.js +1 -21
- package/dist/main/services/simulator-temp-files/store.d.ts +1 -13
- package/dist/main/services/simulator-temp-files/store.js +1 -23
- package/dist/main/services/views/miniapp-partition.d.ts +1 -89
- package/dist/main/services/views/miniapp-partition.js +1 -158
- package/dist/main/services/views/simulator-session-policy.d.ts +1 -27
- package/dist/main/services/views/simulator-session-policy.js +1 -98
- package/dist/main/services/workbench-context.d.ts +4 -1
- package/dist/main/services/workbench-context.js +17 -0
- package/dist/main/utils/ipc-registry.d.ts +21 -3
- package/dist/main/utils/ipc-registry.js +26 -23
- package/dist/main/utils/paths.d.ts +14 -0
- package/dist/main/utils/paths.js +14 -0
- package/dist/main/windows/service-host-window/create.d.ts +1 -92
- package/dist/main/windows/service-host-window/create.js +1 -154
- package/dist/native-host/common/common.js +154 -58
- package/dist/native-host/container/pageFrame.css +1 -1
- package/dist/native-host/render/render.js +6611 -3312
- package/dist/native-host/service/service.js +2 -2
- package/dist/preload/index.d.ts +2 -0
- package/dist/preload/index.js +1 -0
- package/dist/preload/runtime/clipboard.d.ts +6 -0
- package/dist/preload/runtime/clipboard.js +12 -0
- package/dist/preload/runtime/native-host.d.ts +2 -0
- package/dist/preload/runtime/native-host.js +5 -10
- package/dist/preload/runtime/node-bindings.d.ts +18 -0
- package/dist/preload/runtime/node-bindings.js +44 -0
- package/dist/preload/windows/host-toolbar-runtime.cjs.map +2 -2
- package/dist/preload/windows/main.cjs +1195 -897
- package/dist/preload/windows/main.cjs.map +4 -4
- package/dist/preload/windows/simulator.cjs +149 -60
- package/dist/preload/windows/simulator.cjs.map +4 -4
- package/dist/preload/windows/simulator.js +149 -60
- package/dist/render-host/pageFrame.html +3 -3
- package/dist/shared/bridge-channels.d.ts +1 -419
- package/dist/shared/bridge-channels.js +1 -89
- package/dist/shared/dmb-resource-url.d.ts +2 -0
- package/dist/shared/dmb-resource-url.js +2 -0
- package/dist/shared/ipc-channels.d.ts +2 -32
- package/dist/shared/ipc-channels.js +2 -5
- package/dist/shared/node-bindings.d.ts +2 -0
- package/dist/shared/node-bindings.js +2 -0
- package/dist/shared/request-core.d.ts +1 -83
- package/dist/shared/request-core.js +1 -167
- package/dist/simulator/assets/device-shell-Cw7c-IkG.js +2 -0
- package/dist/simulator/assets/{device-shell-BHz1v3Yo.css → device-shell-DbC5ccs8.css} +1 -1
- package/dist/simulator/assets/{jsx-runtime-hBv-rHqQ.js → jsx-runtime-DkKmJyBb.js} +2 -2
- package/dist/simulator/assets/simulator-COIE6R49.js +10 -0
- package/dist/simulator/assets/simulator-mini-app-BLn7XV8e.js +2 -0
- package/dist/simulator/simulator.html +2 -2
- package/dist/simulator/temp-files.d.ts +29 -0
- package/dist/simulator/temp-files.js +79 -0
- package/dist/simulator/types.d.ts +43 -0
- package/dist/simulator/types.js +2 -0
- package/package.json +6 -5
- package/dist/shared/simulator-api-metadata.d.ts +0 -26
- package/dist/shared/simulator-api-metadata.js +0 -59
- package/dist/shared/vpath.d.ts +0 -42
- package/dist/shared/vpath.js +0 -105
- package/dist/simulator/assets/device-shell-CH_DMYaz.js +0 -2
- package/dist/simulator/assets/simulator-DXraYerh.js +0 -10
- package/dist/simulator/assets/simulator-mini-app-w1Bhwkld.js +0 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/preload/windows/main.ts", "
|
|
4
|
-
"sourcesContent": ["/**\n * Preload bridge for the main window, settings window, settings overlay\n * view, and popover overlay view. Exposes a minimal, typed `window.devtools`\n * surface so the renderer never has to call `window.require('electron')`.\n *\n * This file is bundled by esbuild to CJS at `dist/preload/windows/main.js`\n * (see package.json `build:preload`). It must remain a leaf module \u2014 do\n * NOT import other preload files via `.js` ESM specifiers; everything goes\n * through the Electron `contextBridge` / `ipcRenderer` runtime.\n *\n * Channel governance lives in the main process: `sender-policy.ts` plus the\n * per-handler zod schemas decide what's accepted. The preload layer is a\n * thin pass-through \u2014 a renderer inventing channel names will just hit a\n * main-side rejection, so duplicating an allowlist here added no real\n * defense for a devtool that loads user-trusted mini-programs.\n */\nimport { contextBridge, ipcRenderer, type IpcRendererEvent } from 'electron'\nimport { BRIDGE_CHANNELS as C, SIMULATOR_EVENTS as E } from '../../shared/bridge-channels.js'\nimport type {\n ApiCallPayload,\n ApiResponsePayload,\n} from '../../shared/bridge-channels.js'\nimport { runApiAsync } from '../runtime/main-api-runner.js'\nimport { simulatorApis } from '../../simulator/simulator-api.js'\n\nconst api = {\n ipc: {\n invoke: (channel: string, ...args: unknown[]) => ipcRenderer.invoke(channel, ...args),\n // Synchronous round-trip. Blocks the renderer until the main process sets\n // `event.returnValue` \u2014 used only for the editor's beforeunload flush, where\n // the write MUST land before the page is torn down (an async invoke can't).\n sendSync: (channel: string, ...args: unknown[]) => ipcRenderer.sendSync(channel, ...args),\n send: (channel: string, ...args: unknown[]) => {\n ipcRenderer.send(channel, ...args)\n },\n on: (\n channel: string,\n listener: (event: IpcRendererEvent, ...args: unknown[]) => void,\n ) => {\n ipcRenderer.on(channel, listener)\n return () => ipcRenderer.removeListener(channel, listener)\n },\n once: (\n channel: string,\n listener: (event: IpcRendererEvent, ...args: unknown[]) => void,\n ) => {\n ipcRenderer.once(channel, listener)\n },\n removeListener: (\n channel: string,\n listener: (...args: unknown[]) => void,\n ) => {\n ipcRenderer.removeListener(channel, listener)\n },\n },\n}\n\n// All host windows that load this preload run with `contextIsolation: true`\n// (main / settings / view-manager), so `contextBridge` is the path that\n// reaches the renderer's `window`. The simulator <webview> uses a separate\n// preload (`simulator.ts`).\ncontextBridge.exposeInMainWorld('devtools', api)\n\n// Native-host fallback: bridge-router forwards any invokeAPI name not\n// registered in `ctx.simulatorApis` to the simulator's webContents via\n// E.API_CALL. When the *main* window doubles as the simulator (the default\n// path for e2e callers that drive `dmb:spawn` without an explicit\n// simulatorWcId), the listener must live here in the main-window preload\n// because the renderer side has no DeviceShell mounted to install one.\nipcRenderer.on(E.API_CALL, (_event, payload: ApiCallPayload) => {\n void runApiAsync(\n simulatorApis as Record<string, (this: unknown, params?: unknown) => unknown | Promise<unknown>>,\n payload.name,\n payload.params,\n ).then((verdict) => {\n const ack: ApiResponsePayload = {\n appSessionId: payload.appSessionId,\n requestId: payload.requestId,\n ok: verdict.ok,\n result: verdict.result,\n errMsg: verdict.errMsg,\n }\n ipcRenderer.send(C.API_RESPONSE, ack)\n })\n})\n\n// Test-only hatch: e2e helpers emit synthetic IPC events on the renderer's\n// ipcRenderer instance to trigger handlers registered via `devtools.ipc.on`\n// without round-tripping through the main process. Gated on NODE_ENV so\n// production builds never expose it.\nif (process.env.NODE_ENV === 'test') {\n contextBridge.exposeInMainWorld('__testIpc', {\n emit: (channel: string, ...args: unknown[]) => {\n ;(ipcRenderer as unknown as { emit: (c: string, ...a: unknown[]) => void }).emit(channel, ...args)\n },\n })\n}\n\nexport type DevtoolsApi = typeof api\n", "import type { NativeDeviceInfo } from './ipc-channels.js'\n\nexport const BRIDGE_CHANNELS = {\n SPAWN: 'dmb:spawn',\n DISPOSE: 'dmb:dispose',\n PAGE_OPEN: 'dmb:page:open',\n PAGE_CLOSE: 'dmb:page:close',\n PAGE_LIFECYCLE: 'dmb:page:lifecycle',\n NAV_CALLBACK: 'dmb:nav:callback',\n SERVICE_INVOKE: 'dmb:service:invoke',\n SERVICE_PUBLISH: 'dmb:service:publish',\n RENDER_INVOKE: 'dmb:render:invoke',\n RENDER_PUBLISH: 'dmb:render:publish',\n TO_SERVICE: 'dmb:to-service',\n TO_RENDER: 'dmb:to-render',\n SIMULATOR_API: 'dmb:simulator-api',\n /** simulator \u2192 main: ack of an API_CALL request (carries success/fail args). */\n API_RESPONSE: 'dmb:api:response',\n /**\n * simulator webview preload \u2192 main (sendSync): \"is native-host mode on?\".\n * The guest preload can't read the launch `process.env`, so it asks main\n * (which can) at install time. Reply is `e.returnValue = boolean`.\n */\n NATIVE_HOST_ENABLED: 'dmb:native-host-enabled',\n /**\n * simulator (DeviceShell) \u2192 main: the visible top-of-stack page bridgeId.\n * Main has no z-order concept \u2014 the active page lives only in DeviceShell's\n * ShellState \u2014 so devtools panels / automation that must target \"the current\n * page's render webContents\" resolve it through this signal. Fire-and-forget.\n */\n ACTIVE_PAGE: 'dmb:active-page',\n /**\n * simulator (DeviceShell) \u2192 main: the FULL ordered page stack (bottom\u2192top)\n * whenever it changes. Main has no stack of its own (it only learns the\n * active bridgeId via ACTIVE_PAGE), so automation's `App.getPageStack` needs\n * this to report multi-page stacks. Fire-and-forget.\n */\n PAGE_STACK: 'dmb:page-stack',\n} as const\n\nexport const SIMULATOR_EVENTS = {\n DOM_READY: 'simulator:dom-ready',\n NAV_BAR: 'simulator:navigation-bar',\n NAV_ACTION: 'simulator:nav-action',\n TAB_ACTION: 'simulator:tab-action',\n /** main \u2192 simulator: invoke a wx.* API on the simulator-resident MiniApp. */\n API_CALL: 'simulator:api-call',\n /**\n * main \u2192 simulator: the renderer toolbar picked a different device. Carries a\n * NativeDeviceInfo; DeviceShell resizes the bezel + re-renders status bar /\n * notch. The race-free INITIAL device rides NativeHostConfig.device (read\n * synchronously at preload bridge-install); this event covers live changes.\n */\n DEVICE_CHANGE: 'simulator:device-change',\n /**\n * main \u2192 simulator: a watcher rebuild finished; boot a NEW app session for\n * the carried url ({@link RelaunchPayload}) IN PLACE, keeping the live\n * DeviceShell painted, and swap once the new session's root page reports\n * DOM_READY (ready-then-swap soft reload). Main sends this only when the\n * shell is live+ready; otherwise the renderer falls back to the hard\n * attachNativeSimulator rebuild.\n */\n RELAUNCH: 'simulator:relaunch',\n} as const\n\n/**\n * `simulator:relaunch` payload. `url` is a full simulator URL (same format as\n * the simulator page's own location / AttachNative), carrying the appId and\n * the page route the new session must boot at.\n */\nexport interface RelaunchPayload {\n url: string\n}\n\nexport const CHANNELS = BRIDGE_CHANNELS\n\n/**\n * Reply to a `NATIVE_HOST_ENABLED` sendSync. Main supplies the render-host\n * file:// URLs (computed with node:path/url, which the simulator webview's\n * preload lacks) so the preload can build the native-host bridge.\n */\nexport interface NativeHostConfig {\n enabled: boolean\n renderHostHtmlUrl: string\n renderPreloadUrl: string\n /**\n * The currently-selected device, if the renderer already pushed it before the\n * simulator WCV's preload installed (it does \u2014 SetDeviceInfo precedes\n * AttachNative). DeviceShell reads this as its initial device so it never\n * mounts with the wrong bezel size while waiting for the first DEVICE_CHANGE.\n * Absent only on the pre-spawn default path.\n */\n device?: NativeDeviceInfo\n}\n\nexport type BridgeChannel = typeof BRIDGE_CHANNELS[keyof typeof BRIDGE_CHANNELS]\n\nexport type BridgeTarget = 'service' | 'render' | 'container'\n\nexport type BridgeMessageType =\n | 'loadResource'\n | 'serviceResourceLoaded'\n | 'renderResourceLoaded'\n | 'resourceLoaded'\n | 'firstRender'\n | 'appShow'\n | 'appHide'\n | 'stackShow'\n | 'stackHide'\n | 'pageShow'\n | 'pageHide'\n | 'pageReady'\n | 'pageUnload'\n | 'pageScroll'\n | 'pageResize'\n | 'pageRouteDone'\n | 'mC'\n | 'mR'\n | 'mU'\n | 't'\n | 'u'\n | 'ub'\n | 'triggerCallback'\n | 'invokeAPI'\n | 'h5SdkAction'\n | 'componentError'\n | 'domReady'\n | 'print'\n | 'renderHostReady'\n | 'serviceHostError'\n | string\n\nexport interface MessageEnvelope<TBody extends Record<string, unknown> = Record<string, unknown>> {\n type: BridgeMessageType\n target: BridgeTarget\n body: TBody\n}\n\nexport interface HostEnvSnapshot {\n brand: string\n model: string\n platform: string\n system: string\n version: string\n SDKVersion: string\n pixelRatio: number\n screenWidth: number\n screenHeight: number\n windowWidth: number\n windowHeight: number\n statusBarHeight: number\n language: string\n theme: string\n [key: string]: unknown\n}\n\n/**\n * Map the renderer's logical device metrics onto the subset of a\n * HostEnvSnapshot the service-host window's `getSystemInfoSync` consumes.\n * `windowHeight` excludes the status bar (the page area); `windowWidth` has no\n * horizontal chrome. Zoom is intentionally absent \u2014 it is a display scale, not\n * a logical-size change.\n *\n * Single source of truth for the device\u2192host-env mapping, shared by the live\n * `SetDeviceInfo` IPC path (main/ipc/simulator.ts) and the per-spawn host-env\n * seeding (main/ipc/bridge-router.ts). Keeping them identical guarantees a\n * service-host RESPAWN after a device change reports the same dims the live\n * update pushed \u2014 otherwise a respawn would silently revert to the boot device.\n */\nexport function deviceInfoToHostEnv(d: NativeDeviceInfo): Partial<HostEnvSnapshot> {\n return {\n brand: d.brand,\n model: d.model,\n system: d.system,\n platform: d.platform,\n pixelRatio: d.pixelRatio,\n screenWidth: d.screenWidth,\n screenHeight: d.screenHeight,\n windowWidth: d.screenWidth,\n windowHeight: Math.max(0, d.screenHeight - d.statusBarHeight),\n statusBarHeight: d.statusBarHeight,\n }\n}\n\n/**\n * Subset of WeChat page `window` config plus tabBar list, parsed from\n * `app-config.json` (`{app:{window,tabBar,pages,entryPagePath}, modules:{[pagePath]:{...flat page.json fields,root?}}}`).\n * `modules[pagePath]` is FLAT \u2014 the compiler assigns the page's own `.json` file\n * content as-is (see `dimina/fe/packages/compiler/src/env.js` `collectionPageJson()`),\n * not wrapped under a `.window` key. Mirrors mergePageConfig in dimina-fe:\n * page-level keys override app-level.\n */\nexport interface PageWindowConfig {\n navigationBarTitleText?: string\n navigationBarBackgroundColor?: string\n navigationBarTextStyle?: 'black' | 'white'\n navigationStyle?: 'default' | 'custom'\n homeButton?: boolean\n backgroundColor?: string\n backgroundTextStyle?: 'dark' | 'light'\n enablePullDownRefresh?: boolean\n disableScroll?: boolean\n [key: string]: unknown\n}\n\nexport interface TabBarItem {\n pagePath: string\n text?: string\n iconPath?: string\n selectedIconPath?: string\n}\n\nexport interface TabBarConfig {\n color?: string\n selectedColor?: string\n backgroundColor?: string\n borderStyle?: 'black' | 'white'\n position?: 'bottom' | 'top'\n custom?: boolean\n list: TabBarItem[]\n}\n\nexport interface AppManifest {\n entryPagePath: string\n pages: string[]\n tabBar?: TabBarConfig\n /**\n * Provenance of this manifest: `'app-config'` when built from a real\n * compiled `app-config.json` (its `pages` list is authoritative, so mount\n * gates can validate membership against it); `'fallback'` when\n * app-config.json was unreachable and the manifest is a single-page stand-in\n * built from the spawn request. Mount gates only enforce against\n * `'app-config'` \u2014 a `'fallback'` manifest has no compiled truth to check\n * membership against, so it must let every page/nav target through.\n */\n source: 'app-config' | 'fallback'\n}\n\nexport interface SpawnRequest {\n simulatorWcId?: number\n appId: string\n bridgeId?: string\n pagePath?: string\n scene?: number\n query?: Record<string, unknown>\n apiNamespaces?: string[]\n hostEnvSnapshot?: Partial<HostEnvSnapshot>\n pkgRoot?: string\n root?: string\n /**\n * Base URL of the dev server that serves the compiled mini-app, i.e. the\n * SAME origin the simulator page was loaded from (`http://localhost:<port>/`).\n * The dev server statically serves `<appId>/<root>/\u2026` (app-config.json,\n * logic.js, page bundles, styles) \u2014 exactly what the default dimina-fe\n * `<webview>` fetches. The native-host render + service hosts source every\n * resource from here, so we don't need a second resource server or a local\n * compiled-output path. Trailing slash expected.\n */\n resourceBaseUrl?: string\n}\n\nexport interface SpawnResult {\n appSessionId: string\n bridgeId: string\n /** The pagePath originally requested (unchanged even when a fallback applied \u2014 see `resolvedPagePath`). */\n pagePath: string\n /**\n * The pagePath the root PageSession was ACTUALLY spawned with. Equal to\n * `pagePath` unless `pageFallbackApplied` is true, in which case the request\n * was absent from `manifest.pages` and this is `manifest.entryPagePath`\n * (or `manifest.pages[0]` when even that isn't a member). Callers that cache\n * \"the current page\" (e.g. `SimulatorMiniApp`) must reconcile against this,\n * not the original request.\n */\n resolvedPagePath: string\n /** Whether `resolvedPagePath` differs from the request because it was absent from the compiled manifest. Always false for a `'fallback'` manifest (nothing to validate against). */\n pageFallbackApplied: boolean\n serviceWcId: number\n resourceBaseUrl: string\n manifest: AppManifest\n rootWindowConfig: PageWindowConfig\n}\n\nexport interface PageOpenRequest {\n appSessionId: string\n pagePath: string\n query?: Record<string, unknown>\n bridgeId?: string\n}\n\nexport interface PageOpenResult {\n bridgeId: string\n pagePath: string\n windowConfig: PageWindowConfig\n isTab: boolean\n}\n\nexport interface PageClosePayload {\n bridgeId: string\n}\n\nexport interface DisposePayload {\n /** AppSession root bridgeId (legacy) or any page bridgeId. */\n bridgeId: string\n}\n\nexport type PageLifecycleEvent =\n | 'pageShow'\n | 'pageHide'\n | 'pageUnload'\n | 'stackShow'\n | 'stackHide'\n | 'appShow'\n | 'appHide'\n\nexport interface PageLifecyclePayload {\n appSessionId: string\n bridgeId: string\n event: PageLifecycleEvent\n}\n\n/**\n * Sent by simulator after a routing action (navigateTo etc.) completes so the\n * main process can call sendCallback() against the original service-issued\n * success/fail/complete ids.\n */\nexport interface NavCallbackPayload {\n appSessionId: string\n ok: boolean\n errMsg: string\n callbacks: { success?: unknown; fail?: unknown; complete?: unknown }\n}\n\nexport interface ServiceInvokePayload {\n bridgeId: string\n msg: MessageEnvelope\n}\n\nexport interface ServicePublishPayload {\n bridgeId: string\n targetBridgeId?: string\n msg: MessageEnvelope\n}\n\n/**\n * `dmb:active-page` \u2014 simulator (DeviceShell) \u2192 main. Records which page is the\n * visible top-of-stack so main-side services (WXML/element-inspect, automation)\n * can resolve \"the active page's render webContents\" by bridgeId.\n */\nexport interface ActivePagePayload {\n appSessionId: string\n bridgeId: string\n}\n\n/**\n * `dmb:page-stack` \u2014 simulator (DeviceShell) \u2192 main. The full ordered page\n * stack (bottom\u2192top) so `App.getPageStack` can report multi-page stacks.\n */\nexport interface PageStackEntry {\n pagePath: string\n query: Record<string, unknown>\n}\n\nexport interface PageStackPayload {\n appSessionId: string\n stack: PageStackEntry[]\n}\n\nexport interface RenderInvokePayload {\n bridgeId: string\n msg: MessageEnvelope\n}\n\nexport interface RenderPublishPayload {\n bridgeId: string\n msg: MessageEnvelope\n}\n\nexport interface ToServicePayload {\n msg: MessageEnvelope\n}\n\nexport interface ToRenderPayload {\n msg: MessageEnvelope\n}\n\nexport interface SimulatorApiInvokePayload {\n bridgeId: string\n name: string\n params: unknown\n}\n\n/**\n * `simulator:nav-action` \u2014 main \u2192 simulator window, carries router/tabBar\n * intentions. Simulator owns the visual stack state and decides whether to\n * push/pop webviews; it then calls back PAGE_LIFECYCLE + NAV_CALLBACK.\n */\nexport interface NavActionPayload {\n appSessionId: string\n bridgeId: string\n name: 'navigateTo' | 'navigateBack' | 'redirectTo' | 'reLaunch' | 'switchTab'\n params: Record<string, unknown>\n callbacks: { success?: unknown; fail?: unknown; complete?: unknown }\n}\n\n/**\n * `simulator:api-call` \u2014 main \u2192 simulator. Fallback path used when an\n * invokeAPI name is not registered in the main-process `ctx.simulatorApis`\n * registry: the simulator-resident MiniApp owns the wx.* handler (it can\n * read DOM, open file pickers, etc.), so we forward the call there and wait\n * for an `API_RESPONSE` ack.\n */\nexport interface ApiCallPayload {\n appSessionId: string\n bridgeId: string\n requestId: string\n name: string\n params: Record<string, unknown>\n callbacks: { success?: unknown; fail?: unknown; complete?: unknown }\n}\n\n/**\n * `dmb:api:response` \u2014 simulator \u2192 main. Ack for an `API_CALL`. Main looks\n * up `requestId` in its pending map and fires the original service-side\n * success/fail/complete callbacks accordingly.\n */\nexport interface ApiResponsePayload {\n appSessionId: string\n requestId: string\n ok: boolean\n /** Argument the simulator-side success/fail callback was invoked with. */\n result?: unknown\n errMsg?: string\n /**\n * Persistent-subscription marker (`keep: true` APIs, e.g.\n * `audioListen`). When set, this response is one of potentially many\n * fires of the same subscription: main re-fires the service-side success\n * callback but keeps the pendingApiCall alive (does not delete it or fire\n * `complete`) so subsequent fires of the same `requestId` are delivered.\n * Cleanup happens on page/app teardown instead.\n */\n keep?: boolean\n}\n\n/**\n * `simulator:tab-action` \u2014 main \u2192 simulator window, carries dynamic TabBar\n * API calls. Simulator updates TabBar React state and acknowledges via\n * NAV_CALLBACK so the service-side wx.* callback fires.\n */\nexport interface TabActionPayload {\n appSessionId: string\n bridgeId: string\n name:\n | 'setTabBarStyle'\n | 'setTabBarItem'\n | 'showTabBar'\n | 'hideTabBar'\n | 'setTabBarBadge'\n | 'removeTabBarBadge'\n | 'showTabBarRedDot'\n | 'hideTabBarRedDot'\n params: Record<string, unknown>\n callbacks: { success?: unknown; fail?: unknown; complete?: unknown }\n}\n", "/**\n * Native-host API_CALL handler installed inside the main-window preload.\n *\n * Goal: let the main devtools window double as a simulator when the\n * bridge-router forwards `simulator:api-call` to its webContents (the\n * default path in e2e tests, where `dmb:spawn` is invoked from mainWindow\n * directly with no explicit `simulatorWcId`).\n *\n * Unlike `simulator/main.tsx` (which boots a full DeviceShell + SimulatorMiniApp),\n * this runner is renderer-agnostic: it just owns a name\u2192handler table plus\n * a sentinel-based callback capture identical in shape to the simulator's\n * `runApiAsync`. The MiniAppContext stub it constructs is the smallest one\n * the built-in handlers expect (`appId`, `createCallbackFunction`, parent\n * with `el.querySelector` returning the simulated viewport rect).\n */\nimport type { MiniAppContext } from '../../simulator/types.js'\n\n// No `this` parameter: handlers are always invoked through `.call(ctx, \u2026)`\n// below with an explicit context object, so the declared type never needs to\n// constrain (or widen away) the caller's `this`.\ntype LooseApiHandler = (params?: unknown) => unknown | Promise<unknown>\n\nexport interface ApiRunVerdict {\n ok: boolean\n result?: unknown\n errMsg?: string\n}\n\ninterface ApiRunnerContext extends MiniAppContext {\n /** Dummy properties some upstream handlers introspect. */\n appId: string\n}\n\nfunction makeBaseContext(): ApiRunnerContext {\n // Minimal viewport rect: enough for handlers that read\n // `parent.el.querySelector('.dimina-native-webview__root').getBoundingClientRect()`\n // (see simulator-api.ts readWindowMetrics).\n const fakeRect = { width: 390, height: 844, x: 0, y: 0, top: 0, left: 0, right: 390, bottom: 844 }\n const fakeRoot = {\n getBoundingClientRect: () => fakeRect,\n } as unknown as Element\n return {\n appId: '',\n createCallbackFunction: () => undefined,\n parent: {\n el: {\n querySelector: () => fakeRoot,\n } as unknown as Element,\n getStatusBarRect: () => ({ height: 0 }),\n },\n }\n}\n\nexport function runApiAsync(\n handlers: Record<string, LooseApiHandler | undefined>,\n name: string,\n params: unknown,\n): Promise<ApiRunVerdict> {\n const handler = handlers[name]\n if (!handler) {\n return Promise.resolve({ ok: false, errMsg: `${name}:fail no handler` })\n }\n\n return new Promise<ApiRunVerdict>((resolve) => {\n let resolved = false\n const finish = (verdict: ApiRunVerdict): void => {\n if (resolved) return\n resolved = true\n resolve(verdict)\n }\n\n const SUCCESS = Symbol('main-cb-success')\n const FAIL = Symbol('main-cb-fail')\n const COMPLETE = Symbol('main-cb-complete')\n\n const base = makeBaseContext()\n const ctx: ApiRunnerContext = {\n ...base,\n createCallbackFunction(id: unknown) {\n if (id === undefined || id === null) return undefined\n return (...args: unknown[]) => {\n const arg = args[0]\n if (id === SUCCESS) {\n finish({ ok: true, result: arg })\n } else if (id === FAIL) {\n const errMsg =\n arg && typeof arg === 'object' && 'errMsg' in (arg as Record<string, unknown>)\n ? String((arg as { errMsg?: unknown }).errMsg)\n : `${name}:fail`\n finish({ ok: false, errMsg, result: arg })\n }\n }\n },\n }\n\n const userParams =\n params && typeof params === 'object' && !Array.isArray(params)\n ? { ...(params as Record<string, unknown>) }\n : {}\n const hadSuccess = userParams.success !== undefined && userParams.success !== null\n const hadFail = userParams.fail !== undefined && userParams.fail !== null\n const hadComplete = userParams.complete !== undefined && userParams.complete !== null\n\n userParams.success = SUCCESS\n userParams.fail = FAIL\n if (hadComplete) userParams.complete = COMPLETE\n\n try {\n const ret = (handler as LooseApiHandler).call(ctx, userParams)\n if (ret && typeof (ret as PromiseLike<unknown>).then === 'function') {\n Promise.resolve(ret as PromiseLike<unknown>).then(\n (r) => finish({ ok: true, result: r }),\n (err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err)\n finish({ ok: false, errMsg: `${name}:fail ${msg}` })\n },\n )\n return\n }\n if (!hadSuccess && !hadFail) {\n finish({ ok: true, result: ret })\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err)\n finish({ ok: false, errMsg: `${name}:fail ${msg}` })\n }\n })\n}\n", "import type { MiniAppContext } from './types'\n\n/**\n * Resolve the success / fail / complete callbacks of a wx.* API options\n * object in one step. Each runs through ctx.createCallbackFunction so it is\n * invoked with the proper this-binding; a missing option yields undefined.\n */\nexport function bindCallbacks(\n ctx: MiniAppContext,\n opts: { success?: unknown; fail?: unknown; complete?: unknown },\n) {\n return {\n onSuccess: ctx.createCallbackFunction(opts.success),\n onFail: ctx.createCallbackFunction(opts.fail),\n onComplete: ctx.createCallbackFunction(opts.complete),\n }\n}\n\n/**\n * Build a wx.* API stub for a capability the simulator cannot provide. The\n * returned function reports `${apiName}:fail not supported in simulator`\n * through the fail callback, then runs complete.\n */\nexport function notSupportedApi(\n apiName: string,\n): (this: MiniAppContext, opts?: { fail?: unknown; complete?: unknown }) => void {\n return function (this: MiniAppContext, opts: { fail?: unknown; complete?: unknown } = {}) {\n const { onFail, onComplete } = bindCallbacks(this, opts)\n onFail?.({ errMsg: `${apiName}:fail not supported in simulator` })\n onComplete?.()\n }\n}\n", "/**\n * DevTools API stubs for wx.xxx storage APIs (sync + async).\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi \u2192 MiniApp.invokeApi).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks } from './simulator-api-helpers'\n\n// \u2500\u2500\u2500 shared storage primitives \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Every sync/async pair below (set/get/remove/clear/info) shares the same\n// underlying localStorage layout: keys are namespaced per appId, values are\n// JSON-encoded objects / stringified primitives. These helpers are the\n// single authority for that layout so the sync and async variants cannot\n// drift apart.\n\nfunction storageKeyOf(appId: string, key: string): string {\n\treturn `${appId}_${key}`\n}\n\n/** Full (still-prefixed) localStorage keys belonging to `appId`. */\nfunction collectAppKeys(appId: string): string[] {\n\tconst prefix = `${appId}_`\n\tconst keys: string[] = []\n\tfor (let i = 0; i < localStorage.length; i++) {\n\t\tconst k = localStorage.key(i)\n\t\tif (k && k.startsWith(prefix)) keys.push(k)\n\t}\n\treturn keys\n}\n\nfunction writeEntry(appId: string, key: string, data: unknown): void {\n\tconst dataString = typeof data === 'object' ? JSON.stringify(data) : String(data)\n\tlocalStorage.setItem(storageKeyOf(appId, key), dataString)\n}\n\n/** Reads one entry, JSON-parsing when possible. `undefined` means the key was never set \u2014 distinct from a stored empty string. */\nfunction readEntry(appId: string, key: string): { data: unknown } | undefined {\n\tconst raw = localStorage.getItem(storageKeyOf(appId, key))\n\tif (raw === null) return undefined\n\ttry { return { data: JSON.parse(raw) as unknown } } catch { return { data: raw } }\n}\n\nfunction clearAppKeys(appId: string): void {\n\tcollectAppKeys(appId).forEach(k => localStorage.removeItem(k))\n}\n\nfunction storageInfoOf(appId: string): { keys: string[]; currentSize: number; limitSize: number } {\n\tconst prefix = `${appId}_`\n\tconst keys: string[] = []\n\tlet currentSize = 0\n\tfor (const fullKey of collectAppKeys(appId)) {\n\t\tkeys.push(fullKey.slice(prefix.length))\n\t\tconst item = localStorage.getItem(fullKey)\n\t\tcurrentSize += item ? item.length * 2 : 0\n\t}\n\treturn { keys, currentSize, limitSize: 10 * 1024 * 1024 }\n}\n\n// \u2500\u2500\u2500 Storage (sync) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function setStorageSync(this: MiniAppContext, { key, data }: { key: string; data: unknown }) {\n\twriteEntry(this.appId, key, data)\n}\n\nexport function getStorageSync(this: MiniAppContext, { key }: { key: string }) {\n\t// wx \u771F\u673A: a missing key returns {data: ''}, never undefined or a fail.\n\treturn readEntry(this.appId, key) ?? { data: '' }\n}\n\nexport function removeStorageSync(this: MiniAppContext, { key }: { key: string }) {\n\tlocalStorage.removeItem(storageKeyOf(this.appId, key))\n}\n\nexport function clearStorageSync(this: MiniAppContext) {\n\tclearAppKeys(this.appId)\n}\n\nexport function getStorageInfoSync(this: MiniAppContext) {\n\treturn storageInfoOf(this.appId)\n}\n\n// \u2500\u2500\u2500 Storage (async) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function setStorage(\n\tthis: MiniAppContext,\n\t{ key, data, success, fail, complete }: { key: string; data: unknown; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\ttry {\n\t\twriteEntry(this.appId, key, data)\n\t\tonSuccess?.({ errMsg: 'setStorage:ok' })\n\t} catch (e) {\n\t\tonFail?.({ errMsg: `setStorage:fail ${(e as Error).message}` })\n\t}\n\tonComplete?.()\n}\n\nexport function getStorage(\n\tthis: MiniAppContext,\n\t{ key, success, fail, complete }: { key: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\t// Unlike getStorageSync, the async variant fails (not {data: ''}) on a\n\t// missing key \u2014 this is the documented wx.getStorage contract.\n\tconst entry = readEntry(this.appId, key)\n\tif (!entry) {\n\t\tonFail?.({ errMsg: 'getStorage:fail data not found' })\n\t} else {\n\t\tonSuccess?.({ data: entry.data, errMsg: 'getStorage:ok' })\n\t}\n\tonComplete?.()\n}\n\nexport function removeStorage(\n\tthis: MiniAppContext,\n\t{ key, success, fail, complete }: { key: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\ttry {\n\t\tlocalStorage.removeItem(storageKeyOf(this.appId, key))\n\t\tonSuccess?.({ errMsg: 'removeStorage:ok' })\n\t} catch (e) {\n\t\tonFail?.({ errMsg: `removeStorage:fail ${(e as Error).message}` })\n\t}\n\tonComplete?.()\n}\n\nexport function clearStorage(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tclearAppKeys(this.appId)\n\tonSuccess?.({ errMsg: 'clearStorage:ok' })\n\tonComplete?.()\n}\n\nexport function getStorageInfo(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tconst info = storageInfoOf(this.appId)\n\tonSuccess?.({ ...info, errMsg: 'getStorageInfo:ok' })\n\tonComplete?.()\n}\n", "/**\n * DevTools API stubs for device-related wx.xxx APIs\n * (keyboard / phone / contact / vibrate / scan).\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi \u2192 MiniApp.invokeApi).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks, notSupportedApi } from './simulator-api-helpers'\n\n// \u2500\u2500\u2500 Device: Keyboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function hideKeyboard(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\t// In web, blur the active element to dismiss virtual keyboard\n\tif (document.activeElement && typeof (document.activeElement as HTMLElement).blur === 'function') {\n\t\t;(document.activeElement as HTMLElement).blur()\n\t}\n\tonSuccess?.({ errMsg: 'hideKeyboard:ok' })\n\tonComplete?.()\n}\n\nexport function adjustPosition(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tonSuccess?.({ errMsg: 'adjustPosition:ok' })\n\tonComplete?.()\n}\n\n// \u2500\u2500\u2500 Device: Phone \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function makePhoneCall(\n\tthis: MiniAppContext,\n\t{ phoneNumber, success, fail, complete }: { phoneNumber: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\n\ttry {\n\t\twindow.open(`tel:${phoneNumber}`)\n\t\tonSuccess?.({ errMsg: 'makePhoneCall:ok' })\n\t} catch (error) {\n\t\tonFail?.({ errMsg: `makePhoneCall:fail ${(error as Error).message}` })\n\t}\n\tonComplete?.()\n}\n\n// \u2500\u2500\u2500 Device: Contact (stub) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const chooseContact = notSupportedApi('chooseContact')\n\nexport const addPhoneContact = notSupportedApi('addPhoneContact')\n\n// \u2500\u2500\u2500 Device: Vibrate (stub) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function vibrateShort(this: MiniAppContext, { success, complete }: { type?: string; success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\t// Navigator.vibrate is available in some browsers\n\tif (navigator.vibrate) navigator.vibrate(15)\n\tonSuccess?.({ errMsg: 'vibrateShort:ok' })\n\tonComplete?.()\n}\n\nexport function vibrateLong(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tif (navigator.vibrate) navigator.vibrate(400)\n\tonSuccess?.({ errMsg: 'vibrateLong:ok' })\n\tonComplete?.()\n}\n\n// \u2500\u2500\u2500 Device: Scan (stub) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const scanCode = notSupportedApi('scanCode')\n\n// \u2500\u2500\u2500 Device: Clipboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getClipboardData(\n\tthis: MiniAppContext,\n\t{ success, fail, complete }: { success?: unknown; fail?: unknown; complete?: unknown } = {},\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\treturn navigator.clipboard.readText().then(\n\t\t(data) => {\n\t\t\tonSuccess?.({ data, errMsg: 'getClipboardData:ok' })\n\t\t\tonComplete?.()\n\t\t},\n\t\t(error: unknown) => {\n\t\t\tonFail?.({ errMsg: `getClipboardData:fail ${(error as Error)?.message ?? error}` })\n\t\t\tonComplete?.()\n\t\t},\n\t)\n}\n\nexport function setClipboardData(\n\tthis: MiniAppContext,\n\t{ data, success, fail, complete }: { data?: string; success?: unknown; fail?: unknown; complete?: unknown } = {},\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\t// Parity with the native ClipboardApi: `data` is required.\n\tif (typeof data !== 'string') {\n\t\tonFail?.({ errMsg: 'setClipboardData:fail data is required' })\n\t\tonComplete?.()\n\t\treturn Promise.resolve()\n\t}\n\treturn navigator.clipboard.writeText(data).then(\n\t\t() => {\n\t\t\tonSuccess?.({ errMsg: 'setClipboardData:ok' })\n\t\t\tonComplete?.()\n\t\t},\n\t\t(error: unknown) => {\n\t\t\tonFail?.({ errMsg: `setClipboardData:fail ${(error as Error)?.message ?? error}` })\n\t\t\tonComplete?.()\n\t\t},\n\t)\n}\n\n// \u2500\u2500\u2500 Device: Network type \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type NetworkType = 'wifi' | '2g' | '3g' | '4g' | '5g' | 'none' | 'unknown'\n\ninterface NetworkInfo {\n\tonLine: boolean\n\t/** NetworkInformation.type (e.g. 'wifi' / 'ethernet' / 'cellular'). */\n\ttype?: string\n\t/** NetworkInformation.effectiveType (e.g. '4g' / '3g' / '2g' / 'slow-2g'). */\n\teffectiveType?: string\n}\n\nfunction mapEffectiveType(effectiveType?: string): NetworkType {\n\tswitch (effectiveType) {\n\t\tcase '4g':\n\t\t\treturn '4g'\n\t\tcase '3g':\n\t\t\treturn '3g'\n\t\tcase '2g':\n\t\tcase 'slow-2g':\n\t\t\treturn '2g'\n\t\tdefault:\n\t\t\treturn 'unknown'\n\t}\n}\n\n/**\n * Best-effort map from the browser's NetworkInformation to the WeChat\n * `getNetworkType` vocabulary. The host machine is almost always on wifi or\n * ethernet, so an online connection with no finer signal reports 'wifi'.\n */\nexport function resolveNetworkType(info: NetworkInfo): NetworkType {\n\tif (!info.onLine) return 'none'\n\tif (info.type === 'wifi' || info.type === 'ethernet') return 'wifi'\n\tif (info.type === 'cellular') return mapEffectiveType(info.effectiveType)\n\tif (info.effectiveType) return mapEffectiveType(info.effectiveType)\n\treturn 'wifi'\n}\n\nexport function getNetworkType(\n\tthis: MiniAppContext,\n\t{ success, complete }: { success?: unknown; complete?: unknown } = {},\n) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tconst connection = (navigator as Navigator & {\n\t\tconnection?: { type?: string; effectiveType?: string }\n\t}).connection\n\tconst networkType = resolveNetworkType({\n\t\tonLine: navigator.onLine,\n\t\ttype: connection?.type,\n\t\teffectiveType: connection?.effectiveType,\n\t})\n\tonSuccess?.({ networkType, errMsg: 'getNetworkType:ok' })\n\tonComplete?.()\n}\n", "/**\n * Generic DOM-event \u2192 service-callback bridge.\n *\n * Container-side media APIs (audio, and in future recorder / video) need to\n * forward DOM media events on an `HTMLMediaElement` out to the mini-program\n * service layer. This helper centralises the \"bind a set of DOM events, build\n * a typed payload, invoke `fire`, return a disposer\" pattern so each media API\n * does not re-implement it.\n */\n\n/**\n * Builds the payload handed to `fire` for a given mini-program event name.\n * Receives the mini-program event name (already mapped from the DOM name) and\n * the DOM event, and returns the object delivered to the service callback.\n */\nexport type PayloadBuilder<P> = (event: string, domEvent: Event) => P\n\n/** Disposer returned by {@link bindDomEvents}; unbinds every listener. */\nexport type EventBridgeDisposer = () => void\n\n/**\n * Bind a batch of DOM events on `target`.\n *\n * @param target The EventTarget (e.g. an `HTMLAudioElement`) to listen on.\n * @param eventMap Map of DOM event name \u2192 mini-program event name.\n * @param fire The service callback; called once per DOM event with the\n * payload produced by `buildPayload`.\n * @param buildPayload Produces the typed payload for `fire`.\n * @returns A disposer that removes every listener registered by this call.\n */\nexport function bindDomEvents<P>(\n\ttarget: EventTarget,\n\teventMap: Record<string, string>,\n\tfire: (payload: P) => void,\n\tbuildPayload: PayloadBuilder<P>,\n): EventBridgeDisposer {\n\tconst registered: Array<[string, EventListener]> = []\n\n\tfor (const [domName, miniName] of Object.entries(eventMap)) {\n\t\tconst listener: EventListener = (domEvent) => {\n\t\t\tfire(buildPayload(miniName, domEvent))\n\t\t}\n\t\ttarget.addEventListener(domName, listener)\n\t\tregistered.push([domName, listener])\n\t}\n\n\treturn () => {\n\t\tfor (const [domName, listener] of registered) {\n\t\t\ttarget.removeEventListener(domName, listener)\n\t\t}\n\t\tregistered.length = 0\n\t}\n}\n", "/**\n * Devtools simulator temp-file registry.\n *\n * The simulator hands `chooseImage` / `chooseMedia` / `chooseVideo` /\n * `compressImage` etc. results back to mini-program code as paths. Historically\n * those paths were `blob:` URLs allocated via `URL.createObjectURL`, but the\n * blob: scheme is local-to-the-renderer and cannot be served back into the\n * webview's `persist:simulator` session through a `protocol.handle`. We switched\n * to a custom `difile://_tmp/{uuid}` scheme so the main process can\n * register a single `difile://` protocol handler and stream the bytes for any\n * path, regardless of which renderer originally produced it.\n *\n * To keep the renderer-side cache and the main-process byte store in sync,\n * `setTempFileSink` lets the preload bridge inject a sink that mirrors every\n * `write` / `revoke` / `revokeAll` over IPC. Tests inject a stub sink.\n */\n\nexport interface TempFileSink {\n\twrite(path: string, blob: Blob): void\n\trevoke(path: string): void\n\trevokeAll(): void\n}\n\nconst tempFiles = new Map<string, Blob>()\nlet activeSink: TempFileSink | null = null\n\nexport function setTempFileSink(sink: TempFileSink | null): void {\n\tactiveSink = sink\n}\n\nfunction cryptoRandomId(): string {\n\tconst c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n\tif (c && typeof c.randomUUID === 'function') return c.randomUUID()\n\treturn `${Date.now()}-${Math.random().toString(36).slice(2)}`\n}\n\nexport function createTempFilePath(blob: Blob): string {\n\tconst path = `difile://_tmp/${cryptoRandomId()}`\n\ttempFiles.set(path, blob)\n\tactiveSink?.write(path, blob)\n\treturn path\n}\n\nexport function registerTempFilePath(path: string, blob: Blob): void {\n\ttempFiles.set(path, blob)\n\tactiveSink?.write(path, blob)\n}\n\nexport function revokeTempFilePath(path: string): void {\n\ttempFiles.delete(path)\n\tactiveSink?.revoke(path)\n}\n\nexport function revokeAllTempFilePaths(): void {\n\ttempFiles.clear()\n\tactiveSink?.revokeAll()\n}\n\nexport async function resolveTempFilePath(path: string): Promise<Blob> {\n\tconst cached = tempFiles.get(path)\n\tif (cached) return cached\n\n\tconst response = await fetch(path)\n\tif (!response.ok) {\n\t\tthrow new Error(`\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6 ${path}`)\n\t}\n\tconst blob = await response.blob()\n\t// Cache the freshly fetched blob in-memory so subsequent reads are local.\n\t// We bypass `registerTempFilePath` deliberately: this is a renderer-only\n\t// cache fill, the main-process store already has the bytes (otherwise the\n\t// fetch would not have returned them), so triggering sink.write would\n\t// produce a redundant IPC.\n\ttempFiles.set(path, blob)\n\treturn blob\n}\n\nexport function getTempFileName(path: string, blob: Blob, fallback = 'file'): string {\n\tconst named = blob as Blob & { name?: unknown }\n\tif (typeof named.name === 'string' && named.name.trim()) {\n\t\treturn named.name\n\t}\n\n\ttry {\n\t\tconst url = new URL(path, window.location.href)\n\t\tconst segment = url.pathname.split('/').filter(Boolean).pop()\n\t\tif (segment) return decodeURIComponent(segment)\n\t} catch {\n\t\t// Fall through to the caller-provided fallback.\n\t}\n\n\treturn fallback\n}\n", "/**\n * DevTools API stubs for media-related wx.xxx APIs\n * (image / video / audio).\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi \u2192 MiniApp.invokeApi).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindDomEvents, type EventBridgeDisposer } from './event-bridge'\nimport { bindCallbacks } from './simulator-api-helpers'\nimport { createTempFilePath } from './temp-files'\n\n// \u2500\u2500\u2500 shared file-picker scaffolding \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// chooseImage / chooseVideo / chooseMedia all drive the browser file picker\n// through a hidden `<input type=file>`: create it, wire accept/multiple/\n// capture from the caller's options, listen for `change`, and report a\n// `${apiName}:fail cancel` when the user closes the dialog without picking\n// anything. `createFilePicker` is the single authority for that scaffold;\n// each API supplies only its accept string, multiplicity, and the\n// (possibly async) processing of the picked files.\n\ntype CancelCallbacks = Pick<ReturnType<typeof bindCallbacks>, 'onFail' | 'onComplete'>\n\ninterface FilePickerConfig {\n\taccept: string\n\tmultiple: boolean\n\t/** `capture` attribute value, or `undefined` to omit it (album source, or no single-camera source requested). */\n\tcapture?: 'user' | 'environment'\n}\n\n/** Resolves the `capture` attribute from `sourceType` + `camera`: only set when the caller asked for camera-only capture. */\nfunction captureAttrFor(sourceType: string[], camera: unknown): 'user' | 'environment' | undefined {\n\tif (sourceType.length !== 1 || sourceType[0] !== 'camera') return undefined\n\treturn camera === 'front' ? 'user' : 'environment'\n}\n\n/**\n * Drives a hidden `<input type=file>` through one pick cycle. Reports\n * `${apiName}:fail cancel` + `complete` when the selection is empty;\n * otherwise hands the raw (un-truncated) `FileList` to `onPick`, which owns\n * success/fail/complete and must call `removeInput` once it is done with the\n * picker element.\n */\nfunction createFilePicker(\n\tapiName: string,\n\tconfig: FilePickerConfig,\n\tcbs: CancelCallbacks,\n\tonPick: (files: File[], removeInput: () => void) => void | Promise<void>,\n): void {\n\tconst input = document.createElement('input')\n\tinput.type = 'file'\n\tinput.accept = config.accept\n\tinput.multiple = config.multiple\n\tif (config.capture) input.setAttribute('capture', config.capture)\n\tinput.style.display = 'none'\n\tdocument.body.appendChild(input)\n\n\tconst removeInput = () => input.remove()\n\n\tinput.addEventListener('change', () => {\n\t\tconst files = Array.from(input.files || [])\n\t\tif (files.length === 0) {\n\t\t\tcbs.onFail?.({ errMsg: `${apiName}:fail cancel` })\n\t\t\tcbs.onComplete?.()\n\t\t\tremoveInput()\n\t\t\treturn\n\t\t}\n\t\tvoid onPick(files, removeInput)\n\t})\n\n\tinput.click()\n}\n\n// \u2500\u2500\u2500 Media: Image \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function chooseImage(\n\tthis: MiniAppContext,\n\t{ count = 9, sourceType, camera, success, fail, complete }: {\n\t\tcount?: number\n\t\tsizeType?: unknown\n\t\tsourceType?: unknown\n\t\tcamera?: unknown\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onComplete } = cbs\n\tconst normalizedCount = normalizeChooseMediaCount(count)\n\tconst normalizedSourceType = normalizeStringArray(sourceType, ['album', 'camera'])\n\n\tcreateFilePicker(\n\t\t'chooseImage',\n\t\t{ accept: 'image/*', multiple: normalizedCount > 1, capture: captureAttrFor(normalizedSourceType, camera) },\n\t\tcbs,\n\t\t(rawFiles, removeInput) => {\n\t\t\tconst files = rawFiles.slice(0, normalizedCount)\n\t\t\tconst tempFilePaths = files.map(f => createTempFilePath(f))\n\t\t\tconst tempFiles = files.map((f, i) => ({ path: tempFilePaths[i], size: f.size }))\n\t\t\tonSuccess?.({ tempFilePaths, tempFiles, errMsg: 'chooseImage:ok' })\n\t\t\tonComplete?.()\n\t\t\tremoveInput()\n\t\t},\n\t)\n}\n\nexport function previewImage(\n\tthis: MiniAppContext,\n\t{ urls, current, success, complete }: { urls?: string[]; current?: string; success?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\n\tif (!urls || urls.length === 0) {\n\t\tonComplete?.()\n\t\treturn\n\t}\n\n\t// Simple overlay preview\n\tconst overlay = document.createElement('div')\n\toverlay.style.cssText =\n\t\t'position:fixed;inset:0;z-index:99999;background:rgba(0,0,0,.85);display:flex;align-items:center;justify-content:center;cursor:pointer;'\n\tconst img = document.createElement('img')\n\timg.src = current || urls[0] || ''\n\timg.style.cssText = 'max-width:90%;max-height:90%;object-fit:contain;'\n\toverlay.appendChild(img)\n\toverlay.addEventListener('click', () => overlay.remove())\n\tdocument.body.appendChild(overlay)\n\n\tonSuccess?.({ errMsg: 'previewImage:ok' })\n\tonComplete?.()\n}\n\nexport function compressImage(\n\tthis: MiniAppContext,\n\t{ src, quality = 80, success, fail, complete }: {\n\t\tsrc: string\n\t\tquality?: number\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\n\tconst img = new Image()\n\timg.crossOrigin = 'anonymous'\n\timg.onload = () => {\n\t\ttry {\n\t\t\tconst canvas = document.createElement('canvas')\n\t\t\tcanvas.width = img.naturalWidth\n\t\t\tcanvas.height = img.naturalHeight\n\t\t\tconst ctx = canvas.getContext('2d')!\n\t\t\tctx.drawImage(img, 0, 0)\n\t\t\tcanvas.toBlob(\n\t\t\t\t(blob) => {\n\t\t\t\t\tif (blob) {\n\t\t\t\t\t\tconst tempFilePath = createTempFilePath(blob)\n\t\t\t\t\t\tonSuccess?.({ tempFilePath, errMsg: 'compressImage:ok' })\n\t\t\t\t\t} else {\n\t\t\t\t\t\tonFail?.({ errMsg: 'compressImage:fail compression error' })\n\t\t\t\t\t}\n\t\t\t\t\tonComplete?.()\n\t\t\t\t},\n\t\t\t\t'image/jpeg',\n\t\t\t\tquality / 100,\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tonFail?.({ errMsg: `compressImage:fail ${(error as Error).message}` })\n\t\t\tonComplete?.()\n\t\t}\n\t}\n\timg.onerror = () => {\n\t\tonFail?.({ errMsg: 'compressImage:fail image load error' })\n\t\tonComplete?.()\n\t}\n\timg.src = src\n}\n\nexport function saveImageToPhotosAlbum(\n\tthis: MiniAppContext,\n\t{ filePath, success, fail, complete }: { filePath: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\n\ttry {\n\t\tconst a = document.createElement('a')\n\t\ta.href = filePath\n\t\ta.download = 'image'\n\t\ta.click()\n\t\tonSuccess?.({ errMsg: 'saveImageToPhotosAlbum:ok' })\n\t} catch (error) {\n\t\tonFail?.({ errMsg: `saveImageToPhotosAlbum:fail ${(error as Error).message}` })\n\t}\n\tonComplete?.()\n}\n\nexport function getImageInfo(\n\tthis: MiniAppContext,\n\t{ src, success, fail, complete }: { src: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\n\tconst img = new Image()\n\timg.crossOrigin = 'anonymous'\n\timg.onload = () => {\n\t\tonSuccess?.({\n\t\t\twidth: img.naturalWidth,\n\t\t\theight: img.naturalHeight,\n\t\t\tpath: src,\n\t\t\torientation: 'up',\n\t\t\ttype: 'unknown',\n\t\t\terrMsg: 'getImageInfo:ok',\n\t\t})\n\t\tonComplete?.()\n\t}\n\timg.onerror = () => {\n\t\tonFail?.({ errMsg: 'getImageInfo:fail image load error' })\n\t\tonComplete?.()\n\t}\n\timg.src = src\n}\n\n// \u2500\u2500\u2500 Media: Video \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype MediaFileType = 'image' | 'video'\ntype ChooseMediaCamera = 'back' | 'front'\n\nconst VIDEO_METADATA_TIMEOUT_MS = 5000\nconst VIDEO_THUMBNAIL_TIMEOUT_MS = 500\n\ninterface ChooseMediaTempFile {\n\ttempFilePath: string\n\tsize: number\n\tduration: number\n\theight: number\n\twidth: number\n\tthumbTempFilePath: string\n\tfileType: MediaFileType\n\toriginalFileObj: File\n}\n\nfunction normalizeStringArray(value: unknown, fallback: string[]): string[] {\n\treturn Array.isArray(value)\n\t\t? value.filter((item): item is string => typeof item === 'string')\n\t\t: fallback\n}\n\nfunction normalizeChooseMediaCount(value: unknown): number {\n\tconst n = Number(value)\n\tif (!Number.isFinite(n)) return 9\n\treturn Math.max(1, Math.min(20, Math.floor(n)))\n}\n\nfunction getChooseMediaAccept(mediaType: string[]): string {\n\tconst wantsMix = mediaType.includes('mix')\n\tconst wantsImage = wantsMix || mediaType.includes('image')\n\tconst wantsVideo = wantsMix || mediaType.includes('video')\n\tif (wantsImage && wantsVideo) return 'image/*,video/*'\n\treturn wantsVideo ? 'video/*' : 'image/*'\n}\n\nfunction getChooseMediaResultType(files: ChooseMediaTempFile[]): 'image' | 'video' | 'mix' {\n\tconst types = new Set(files.map(file => file.fileType))\n\tif (types.size > 1) return 'mix'\n\treturn files[0]?.fileType ?? 'image'\n}\n\nfunction readImageMetadata(src: string): Promise<{ width: number; height: number }> {\n\treturn new Promise((resolve) => {\n\t\tconst img = new Image()\n\t\timg.onload = () => resolve({ width: img.naturalWidth || 0, height: img.naturalHeight || 0 })\n\t\timg.onerror = () => resolve({ width: 0, height: 0 })\n\t\timg.src = src\n\t})\n}\n\nfunction readVideoMetadata(src: string): Promise<{ width: number; height: number; duration: number; thumbTempFilePath: string }> {\n\treturn new Promise((resolve) => {\n\t\tconst video = document.createElement('video')\n\t\tlet settled = false\n\t\tlet seekTimer: ReturnType<typeof setTimeout> | undefined\n\t\tconst finish = (metadata: { width: number; height: number; duration: number; thumbTempFilePath: string }) => {\n\t\t\tif (settled) return\n\t\t\tsettled = true\n\t\t\tclearTimeout(timer)\n\t\t\tif (seekTimer) clearTimeout(seekTimer)\n\t\t\t// Detach handlers so any late-firing DOM events (e.g. onseeked from a\n\t\t\t// previously queued currentTime change) cannot reach into the now-\n\t\t\t// resolved promise and allocate fresh blob: URLs.\n\t\t\tvideo.onloadedmetadata = null\n\t\t\tvideo.onseeked = null\n\t\t\tvideo.onerror = null\n\t\t\tvideo.removeAttribute('src')\n\t\t\tvideo.load()\n\t\t\tresolve(metadata)\n\t\t}\n\t\tconst drawThumbnail = (width: number, height: number): Promise<string> => {\n\t\t\treturn new Promise((resolveThumb) => {\n\t\t\t\tlet resolved = false\n\t\t\t\tconst done = (value: string) => {\n\t\t\t\t\tif (resolved) return\n\t\t\t\t\tresolved = true\n\t\t\t\t\tresolveThumb(value)\n\t\t\t\t}\n\t\t\t\tlet canvas: HTMLCanvasElement\n\t\t\t\ttry {\n\t\t\t\t\tcanvas = document.createElement('canvas')\n\t\t\t\t\tcanvas.width = width || 1\n\t\t\t\t\tcanvas.height = height || 1\n\t\t\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\t\t\tctx?.drawImage(video, 0, 0, canvas.width, canvas.height)\n\t\t\t\t} catch {\n\t\t\t\t\tdone('')\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst toDataUrlFallback = () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdone(canvas.toDataURL('image/jpeg', 0.8))\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tdone('')\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst fallbackTimer = setTimeout(toDataUrlFallback, VIDEO_THUMBNAIL_TIMEOUT_MS)\n\t\t\t\ttry {\n\t\t\t\t\tcanvas.toBlob(\n\t\t\t\t\t\t(blob) => {\n\t\t\t\t\t\t\tclearTimeout(fallbackTimer)\n\t\t\t\t\t\t\t// If the outer readVideoMetadata promise already settled\n\t\t\t\t\t\t\t// (e.g. the seekTimer fired before toBlob's async callback\n\t\t\t\t\t\t\t// arrived), we MUST NOT call createTempFilePath here \u2014 that\n\t\t\t\t\t\t\t// would allocate a fresh blob: URL and register it in the\n\t\t\t\t\t\t\t// temp-files Map with no one ever revoking it. Just drop\n\t\t\t\t\t\t\t// the blob on the floor; the resolved thumbTempFilePath\n\t\t\t\t\t\t\t// has already been chosen by the timeout path.\n\t\t\t\t\t\t\tif (settled || resolved) return\n\t\t\t\t\t\t\tif (blob) {\n\t\t\t\t\t\t\t\tdone(createTempFilePath(blob))\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttoDataUrlFallback()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t'image/jpeg',\n\t\t\t\t\t\t0.8,\n\t\t\t\t\t)\n\t\t\t\t} catch {\n\t\t\t\t\tclearTimeout(fallbackTimer)\n\t\t\t\t\ttoDataUrlFallback()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tconst timer = setTimeout(() => finish({ width: 0, height: 0, duration: 0, thumbTempFilePath: '' }), VIDEO_METADATA_TIMEOUT_MS)\n\n\t\tvideo.preload = 'metadata'\n\t\tvideo.muted = true\n\t\tvideo.onloadedmetadata = () => {\n\t\t\tconst width = video.videoWidth || 0\n\t\t\tconst height = video.videoHeight || 0\n\t\t\tconst duration = Number.isFinite(video.duration) ? video.duration : 0\n\t\t\tconst metadata = { width, height, duration, thumbTempFilePath: '' }\n\t\t\tif (!width || !height || duration <= 0) {\n\t\t\t\tfinish(metadata)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tvideo.onseeked = async () => {\n\t\t\t\tif (seekTimer) {\n\t\t\t\t\tclearTimeout(seekTimer)\n\t\t\t\t\tseekTimer = undefined\n\t\t\t\t}\n\t\t\t\tconst thumbTempFilePath = await drawThumbnail(width, height)\n\t\t\t\tfinish({ ...metadata, thumbTempFilePath })\n\t\t\t}\n\t\t\tseekTimer = setTimeout(() => finish(metadata), VIDEO_THUMBNAIL_TIMEOUT_MS)\n\t\t\ttry {\n\t\t\t\tvideo.currentTime = Math.min(0.1, Math.max(0, duration - 0.01))\n\t\t\t} catch {\n\t\t\t\tfinish(metadata)\n\t\t\t}\n\t\t}\n\t\tvideo.onerror = () => finish({ width: 0, height: 0, duration: 0, thumbTempFilePath: '' })\n\t\tvideo.src = src\n\t})\n}\n\nasync function buildChooseMediaTempFile(file: File): Promise<ChooseMediaTempFile> {\n\tconst tempFilePath = createTempFilePath(file)\n\tconst fileType: MediaFileType = file.type.startsWith('video') ? 'video' : 'image'\n\n\tif (fileType === 'video') {\n\t\tconst metadata = await readVideoMetadata(tempFilePath)\n\t\treturn {\n\t\t\ttempFilePath,\n\t\t\tsize: file.size,\n\t\t\tduration: metadata.duration,\n\t\t\theight: metadata.height,\n\t\t\twidth: metadata.width,\n\t\t\tthumbTempFilePath: metadata.thumbTempFilePath,\n\t\t\tfileType,\n\t\t\toriginalFileObj: file,\n\t\t}\n\t}\n\n\tconst metadata = await readImageMetadata(tempFilePath)\n\treturn {\n\t\ttempFilePath,\n\t\tsize: file.size,\n\t\tduration: 0,\n\t\theight: metadata.height,\n\t\twidth: metadata.width,\n\t\tthumbTempFilePath: '',\n\t\tfileType,\n\t\toriginalFileObj: file,\n\t}\n}\n\nexport function chooseMedia(\n\tthis: MiniAppContext,\n\t{ count = 9, mediaType = ['image', 'video'], sourceType = ['album', 'camera'], camera = 'back', success, fail, complete }: {\n\t\tcount?: number\n\t\tmediaType?: unknown\n\t\tsourceType?: unknown\n\t\tmaxDuration?: unknown\n\t\tsizeType?: unknown\n\t\tcamera?: ChooseMediaCamera\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onFail, onComplete } = cbs\n\tconst normalizedCount = normalizeChooseMediaCount(count)\n\tconst normalizedMediaType = normalizeStringArray(mediaType, ['image', 'video'])\n\tconst normalizedSourceType = normalizeStringArray(sourceType, ['album', 'camera'])\n\n\tcreateFilePicker(\n\t\t'chooseMedia',\n\t\t{\n\t\t\taccept: getChooseMediaAccept(normalizedMediaType),\n\t\t\tmultiple: normalizedCount > 1,\n\t\t\tcapture: captureAttrFor(normalizedSourceType, camera),\n\t\t},\n\t\tcbs,\n\t\tasync (rawFiles, removeInput) => {\n\t\t\tconst files = rawFiles.slice(0, normalizedCount)\n\t\t\ttry {\n\t\t\t\tconst tempFiles = await Promise.all(files.map(buildChooseMediaTempFile))\n\t\t\t\tonSuccess?.({\n\t\t\t\t\ttempFiles,\n\t\t\t\t\ttype: getChooseMediaResultType(tempFiles),\n\t\t\t\t\tfailedCount: 0,\n\t\t\t\t\terrMsg: 'chooseMedia:ok',\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tonFail?.({ errMsg: `chooseMedia:fail ${(error as Error).message}` })\n\t\t\t} finally {\n\t\t\t\tonComplete?.()\n\t\t\t\tremoveInput()\n\t\t\t}\n\t\t},\n\t)\n}\n\nexport function chooseVideo(\n\tthis: MiniAppContext,\n\t{ sourceType, camera, success, fail, complete }: {\n\t\tsourceType?: unknown\n\t\tcompressed?: unknown\n\t\tmaxDuration?: unknown\n\t\tcamera?: unknown\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onComplete } = cbs\n\tconst normalizedSourceType = normalizeStringArray(sourceType, ['album', 'camera'])\n\n\tcreateFilePicker(\n\t\t'chooseVideo',\n\t\t{ accept: 'video/*', multiple: false, capture: captureAttrFor(normalizedSourceType, camera) },\n\t\tcbs,\n\t\tasync (files, removeInput) => {\n\t\t\tconst file = files[0]!\n\t\t\tconst tempFilePath = createTempFilePath(file)\n\t\t\tconst metadata = await readVideoMetadata(tempFilePath)\n\t\t\tonSuccess?.({\n\t\t\t\ttempFilePath,\n\t\t\t\tduration: metadata.duration,\n\t\t\t\tsize: file.size,\n\t\t\t\twidth: metadata.width,\n\t\t\t\theight: metadata.height,\n\t\t\t\terrMsg: 'chooseVideo:ok',\n\t\t\t})\n\t\t\tonComplete?.()\n\t\t\tremoveInput()\n\t\t},\n\t)\n}\n\n// \u2500\u2500\u2500 Media: Audio (container-side handlers for service-apis/audio) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// service-apis/audio/index.js (injected into the service Worker by the dimina\n// container bundle) calls invokeAPI('audioCreate', { audioId }), etc. DOM media\n// events on the container's HTMLAudioElement are bridged back to the service\n// layer via the `audioListen` handler.\n\n/** Payload delivered to the service-side dispatcher on every audio event. */\ninterface AudioEventPayload {\n\tevent: string\n\tcurrentTime: number\n\tduration: number\n\tbuffered: number\n\tpaused: boolean\n}\n\n/** DOM media event name \u2192 mini-program audio event name. */\nconst AUDIO_EVENT_MAP: Record<string, string> = {\n\tplay: 'play',\n\tpause: 'pause',\n\tended: 'ended',\n\terror: 'error',\n\ttimeupdate: 'timeUpdate',\n\twaiting: 'waiting',\n\tseeking: 'seeking',\n\tseeked: 'seeked',\n\tcanplay: 'canplay',\n}\n\nconst _newAudioInstances = new Map<number, HTMLAudioElement>()\n/** Disposers that unbind the DOM event bridge for a given audio instance. */\nconst _audioEventDisposers = new Map<number, EventBridgeDisposer>()\n/** The service-side dispatcher callback for a given audio instance. */\nconst _audioFire = new Map<number, (payload: AudioEventPayload) => void>()\n\n/** Snapshot the current playback state of an audio element. */\nfunction audioSnapshot(audio: HTMLAudioElement, event: string): AudioEventPayload {\n\treturn {\n\t\tevent,\n\t\tcurrentTime: audio.currentTime || 0,\n\t\tduration: Number.isFinite(audio.duration) ? audio.duration : 0,\n\t\tbuffered: audio.buffered.length ? audio.buffered.end(audio.buffered.length - 1) : 0,\n\t\tpaused: audio.paused,\n\t}\n}\n\nexport function audioCreate(this: MiniAppContext, { audioId }: { audioId: number }) {\n\t_newAudioInstances.set(audioId, new Audio())\n}\n\n/**\n * Persistent event-bridge registration. The service-side InnerAudioContext\n * calls this once at construction with a `keep: true` callback; the container\n * resolves a `fire` callback and binds the DOM media events of the matching\n * audio element to it.\n *\n * The dimina service `invokeAPI` runs every callback through\n * `callback.store(success, keep, evtId)` and delivers the resulting callback\n * id under the `success` field of `params` \u2014 `evtId` itself is consumed by\n * `callback.store` and never reaches the container payload. So the handler\n * resolves `fire` from `success`, exactly like every other media API.\n */\nexport function audioListen(this: MiniAppContext, { audioId, success }: { audioId: number; success: unknown }) {\n\tconst audio = _newAudioInstances.get(audioId)\n\tconst fire = this.createCallbackFunction(success) as ((payload: AudioEventPayload) => void) | undefined\n\tif (!audio || !fire) return\n\n\t_audioFire.set(audioId, fire)\n\n\t// Rebind cleanly if audioListen is somehow called twice for one instance.\n\t_audioEventDisposers.get(audioId)?.()\n\tconst dispose = bindDomEvents<AudioEventPayload>(\n\t\taudio,\n\t\tAUDIO_EVENT_MAP,\n\t\tfire,\n\t\tevent => audioSnapshot(audio, event),\n\t)\n\t_audioEventDisposers.set(audioId, dispose)\n}\n\nexport function audioSetProp(\n\tthis: MiniAppContext,\n\t{ audioId, prop, value, startTime, loop, volume, playbackRate, autoplay }: {\n\t\taudioId: number\n\t\tprop: string\n\t\tvalue: unknown\n\t\tstartTime?: number\n\t\tloop?: boolean\n\t\tvolume?: number\n\t\tplaybackRate?: number\n\t\tautoplay?: boolean\n\t},\n) {\n\tconst audio = _newAudioInstances.get(audioId)\n\tif (!audio) return\n\tswitch (prop) {\n\t\tcase 'src':\n\t\t\taudio.src = value as string\n\t\t\tif (startTime != null) audio.currentTime = startTime\n\t\t\tif (loop != null) audio.loop = loop\n\t\t\tif (volume != null) audio.volume = Math.max(0, Math.min(1, volume))\n\t\t\tif (playbackRate != null) audio.playbackRate = playbackRate\n\t\t\tif (autoplay) audio.play().catch(() => {})\n\t\t\tbreak\n\t\tcase 'startTime': audio.currentTime = Number(value) || 0; break\n\t\tcase 'autoplay': audio.autoplay = !!value; break\n\t\tcase 'loop': audio.loop = !!value; break\n\t\tcase 'volume': audio.volume = Math.max(0, Math.min(1, Number(value) || 0)); break\n\t\tcase 'playbackRate': audio.playbackRate = Number(value) || 1; break\n\t}\n}\n\nexport function audioPlay(this: MiniAppContext, { audioId, src }: { audioId: number; src?: string }) {\n\tconst audio = _newAudioInstances.get(audioId)\n\tif (!audio) return\n\tif (src && audio.src !== src) audio.src = src\n\taudio.play().catch(() => {})\n}\n\nexport function audioPause(this: MiniAppContext, { audioId }: { audioId: number }) {\n\t_newAudioInstances.get(audioId)?.pause()\n}\n\nexport function audioStop(this: MiniAppContext, { audioId }: { audioId: number }) {\n\tconst audio = _newAudioInstances.get(audioId)\n\tif (!audio) return\n\taudio.pause()\n\taudio.currentTime = 0\n\t// `stop` has no DOM equivalent \u2014 synthesise it through the bridge.\n\t_audioFire.get(audioId)?.(audioSnapshot(audio, 'stop'))\n}\n\nexport function audioSeek(this: MiniAppContext, { audioId, position }: { audioId: number; position: number }) {\n\tconst audio = _newAudioInstances.get(audioId)\n\tif (!audio) return\n\taudio.currentTime = position\n}\n\nexport function audioDestroy(this: MiniAppContext, { audioId }: { audioId: number }) {\n\t_audioEventDisposers.get(audioId)?.()\n\t_audioEventDisposers.delete(audioId)\n\t_audioFire.delete(audioId)\n\n\tconst audio = _newAudioInstances.get(audioId)\n\tif (!audio) return\n\taudio.pause()\n\taudio.removeAttribute('src')\n\taudio.load()\n\t_newAudioInstances.delete(audioId)\n}\n", "/**\n * vpath resolver.\n *\n * Spec: `docs/file-system.md` \u2014 single resolver shared by every FSM\n * entry, the renderer-side temp store, and the main-process\n * protocol.handle / disk reader.\n *\n * resolveVPath(url): { kind, writable, realPath? } | null\n *\n * - `difile://_tmp/<id>` \u2192 kind=tmp, writable=false, no realPath\n * - `difile://_store/<id>` \u2192 kind=store, writable=false, realPath in base\n * - `difile://<rel>` \u2192 kind=usr, writable=true, realPath in base\n *\n * Security invariants (the resolver returns `null` instead of throwing):\n * - any non-`difile://` scheme is rejected outright;\n * - any `..` segment (raw or URL-encoded) is rejected before canonicalize;\n * - after `path.normalize` the resulting `realPath` MUST stay inside the\n * sandbox base; otherwise `null`;\n * - reserved prefixes `_tmp/` and `_store/` are case-sensitive \u2014 `_TMP/`,\n * `_Tmp/`, etc. fall through to the user-data namespace.\n */\n\n// Main-process (Node ESM) resolves these natively. Simulator (vite browser\n// bundle) externalizes node builtins as no-op stubs \u2014 that's safe here only\n// because the simulator never enters the `store`/`usr` branches below\n// (renderer-side FSM forwards disk-backed reads/writes to main via IPC).\nimport os from 'node:os'\nimport path from 'node:path'\n\nexport type VPathKind = 'tmp' | 'store' | 'usr'\n\nexport interface ResolvedVPath {\n\tkind: VPathKind\n\t/** `tmp` and `store` are runtime-owned and read-only; `usr` is writable. */\n\twritable: boolean\n\t/**\n\t * Canonical local path on disk for `store` / `usr` kinds (always within the\n\t * USER_DATA_PATH base directory after canonicalize). `tmp` kind has no\n\t * realPath \u2014 the bytes live in the renderer-side Blob Map.\n\t */\n\trealPath?: string\n}\n\nconst DIFILE_PREFIX = 'difile://'\n\n/**\n * USER_DATA_PATH sandbox base. Looked up dynamically on every call so test\n * doubles (e.g. monkey-patching `os.homedir`) and the `DIMINA_HOME` env\n * override apply per invocation. The env override exists for headless test\n * affordance and to keep the renderer/main store sharing one base.\n */\nexport function sandboxBase(): string {\n\tconst env = (typeof process !== 'undefined' && process.env && process.env.DIMINA_HOME) || ''\n\tif (env) {\n\t\treturn path.join(env, 'files')\n\t}\n\treturn path.join(os.homedir(), '.dimina', 'files')\n}\n\nexport function resolveVPath(url: unknown): ResolvedVPath | null {\n\tif (typeof url !== 'string') return null\n\tif (!url.startsWith(DIFILE_PREFIX)) return null\n\n\tconst raw = url.slice(DIFILE_PREFIX.length)\n\tif (raw.length === 0) return null\n\n\t// Decode URL-encoded sequences first so `%2e%2e` style escapes are caught\n\t// by the segment check below.\n\tlet decoded: string\n\ttry {\n\t\tdecoded = decodeURIComponent(raw)\n\t} catch {\n\t\treturn null\n\t}\n\n\t// Reject NUL bytes (raw or %00) \u2014 Node `fs.*` throws TypeError on a NUL\n\t// in the path, bypassing the API's `fail` callback and crashing the\n\t// renderer. Pull the rejection up to the validator.\n\tif (decoded.includes('\\0')) return null\n\n\t// Developer convention: `wx.env.USER_DATA_PATH = 'difile://'` so a write\n\t// like `${USER_DATA_PATH}/foo.txt` produces `difile:///foo.txt`. Strip\n\t// leading slashes so that path-joins cleanly under the sandbox base.\n\tdecoded = decoded.replace(/^[/\\\\]+/, '')\n\tif (decoded.length === 0) return null\n\n\t// Reject any '..' or '.' segment after decoding. We split on both '/' and\n\t// '\\\\' so Windows-style separators cannot smuggle a traversal segment past\n\t// the validator on POSIX hosts.\n\tconst segments = decoded.split(/[/\\\\]+/)\n\tif (segments.some(s => s === '..' || s === '.')) return null\n\n\t// Classify by reserved prefix (case-sensitive \u2014 `_TMP/` is a user file).\n\tlet kind: VPathKind\n\tlet writable: boolean\n\tif (decoded.startsWith('_tmp/')) {\n\t\tkind = 'tmp'\n\t\twritable = false\n\t} else if (decoded.startsWith('_store/')) {\n\t\tkind = 'store'\n\t\twritable = false\n\t} else {\n\t\tkind = 'usr'\n\t\twritable = true\n\t}\n\n\t// `tmp` lives in the renderer Blob Map \u2014 no realPath.\n\tif (kind === 'tmp') {\n\t\treturn { kind, writable }\n\t}\n\n\t// `store` / `usr`: anchor under the sandbox base and assert containment\n\t// after normalization. Defense in depth against any traversal that the\n\t// segment check above missed (e.g. backslash trickery on POSIX).\n\tconst base = sandboxBase()\n\tconst joined = path.join(base, decoded)\n\tconst normalized = path.normalize(joined)\n\tif (normalized !== base && !normalized.startsWith(base + path.sep)) return null\n\n\treturn { kind, writable, realPath: normalized }\n}\n", "/**\n * DevTools API stubs for filesystem wx.xxx APIs\n * (container-side handlers for service-apis/file).\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi \u2192 MiniApp.invokeApi).\n *\n * Contract (see `docs/file-system.md`):\n * - Every entry point routes its caller-supplied path through `resolveVPath`\n * (single resolver), which rejects non-`difile://` schemes, absolute\n * filesystem paths, and any `..` traversal.\n * - Write-class APIs (writeFile / appendFile / unlink / mkdir / rmdir /\n * truncate / rename(dest) / copyFile(dest)) refuse `difile://_tmp/*` and\n * `difile://_store/*` with `permission denied` \u2014 those namespaces are\n * runtime-owned and read-only, matching wx \u771F\u673A semantics.\n * - `fsSaveFile` returns a `difile://_store/{uuid}.{ext}` vpath, never a\n * real disk path.\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks, notSupportedApi } from './simulator-api-helpers'\nimport { resolveVPath, type ResolvedVPath } from '../shared/vpath.js'\nimport { resolveTempFilePath } from './temp-files'\n\n/**\n * Dispatch helper: pull a `_tmp/*` Blob out of the renderer Map and hand back\n * its bytes. Throws an ENOENT-shaped Error if the URL is unknown, so callers\n * can surface a `fail` with a real not-found message.\n */\nasync function _tmpBytes(url: string): Promise<Buffer> {\n\ttry {\n\t\tconst blob = await resolveTempFilePath(url)\n\t\treturn await blobToBuffer(blob)\n\t}\n\tcatch (err) {\n\t\tconst msg = err instanceof Error ? err.message : String(err)\n\t\tthrow new Error(`ENOENT: no such file (${url}): ${msg}`, { cause: err })\n\t}\n}\n\nfunction isArrayBuffer(value: unknown): value is ArrayBuffer {\n\treturn Object.prototype.toString.call(value) === '[object ArrayBuffer]'\n}\n\nasync function blobToBuffer(blob: Blob): Promise<Buffer> {\n\tconst readable = blob as Blob & { arrayBuffer?: () => Promise<ArrayBuffer> }\n\tif (typeof readable.arrayBuffer === 'function') {\n\t\tconst ab = await readable.arrayBuffer()\n\t\treturn Buffer.from(new Uint8Array(ab))\n\t}\n\n\tif (typeof FileReader !== 'function') {\n\t\tthrow new Error('Blob cannot be read as ArrayBuffer')\n\t}\n\n\treturn new Promise((resolve, reject) => {\n\t\tconst reader = new FileReader()\n\t\treader.onerror = () => reject(reader.error ?? new Error('Blob read failed'))\n\t\treader.onload = () => {\n\t\t\tconst result = reader.result\n\t\t\tif (!isArrayBuffer(result)) {\n\t\t\t\treject(new Error('Blob read did not return an ArrayBuffer'))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tresolve(Buffer.from(new Uint8Array(result)))\n\t\t}\n\t\treader.readAsArrayBuffer(blob)\n\t})\n}\n\n// In Electron renderer, Node.js built-ins are available via require.\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst _fs: typeof import('fs') = (typeof require !== 'undefined') ? require('fs') : null as unknown as typeof import('fs')\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst _path: typeof import('path') = (typeof require !== 'undefined') ? require('path') : null as unknown as typeof import('path')\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst _crypto: typeof import('crypto') = (typeof require !== 'undefined') ? require('crypto') : null as unknown as typeof import('crypto')\n\ntype FsCallbacks = ReturnType<typeof bindCallbacks>\ntype NodeStats = import('fs').Stats\ntype NodeErr = NodeJS.ErrnoException | Error | null\n\n// \u2500\u2500\u2500 shared fs-API scaffolding \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Every handler below shares the same skeleton: bail if Node `fs` isn't\n// available, resolve the caller path through the single vpath resolver\n// (bailing on invalid/unsafe paths), optionally reject read-only\n// namespaces for write-class APIs, then run a Node fs call and translate its\n// `(err, ...)` callback into the wx success/fail/complete triad. The helpers\n// below are the single authority for each of those steps so per-API bodies\n// only contain what differs between APIs (the real fs call and any extra\n// success payload fields).\n\n/** Bails with `${apiName}:fail not available in browser context` when the Node `fs` binding is absent (e.g. a browser-only build). */\nfunction guardFsAvailable(apiName: string, cbs: FsCallbacks): boolean {\n\tif (_fs) return false\n\tcbs.onFail?.({ errMsg: `${apiName}:fail not available in browser context` })\n\tcbs.onComplete?.()\n\treturn true\n}\n\n/** Resolves `p` via `resolveVPath`, or reports `${apiName}:fail invalid or unsafe path` and runs `complete`. */\nfunction resolveOrBail(p: unknown, apiName: string, cbs: FsCallbacks): ResolvedVPath | undefined {\n\tconst v = resolveVPath(p)\n\tif (v) return v\n\tcbs.onFail?.({ errMsg: `${apiName}:fail invalid or unsafe path` })\n\tcbs.onComplete?.()\n\treturn undefined\n}\n\n/**\n * Type-guards `v` as writable (narrows `realPath` to `string`), or reports\n * `${apiName}:fail permission denied` and runs `complete`. `_tmp` / `_store`\n * are runtime-owned and read-only, matching wx \u771F\u673A semantics.\n */\nfunction ensureWritable(v: ResolvedVPath, apiName: string, cbs: FsCallbacks): v is ResolvedVPath & { realPath: string } {\n\tif (v.writable && v.realPath) return true\n\tcbs.onFail?.({ errMsg: `${apiName}:fail permission denied` })\n\tcbs.onComplete?.()\n\treturn false\n}\n\n/** Fail handler for a `_tmpBytes(...).then(success, ...)` chain: reports `${apiName}:fail <message>` and runs `complete`. */\nfunction tmpFailHandler(apiName: string, cbs: FsCallbacks) {\n\treturn (err: Error) => {\n\t\tcbs.onFail?.({ errMsg: `${apiName}:fail ${err.message}` })\n\t\tcbs.onComplete?.()\n\t}\n}\n\n/**\n * Builds a Node-style `(err, ...args)` callback that translates into the wx\n * success/fail/complete triad: `err` truthy \u2192 fail with `${apiName}:fail\n * <message>`; otherwise success with `${apiName}:ok` plus whatever\n * `buildOk(...args)` contributes.\n */\nfunction nodeComplete<TArgs extends unknown[] = []>(\n\tapiName: string,\n\tcbs: FsCallbacks,\n\tbuildOk?: (...args: TArgs) => Record<string, unknown> | undefined,\n) {\n\treturn (err: NodeErr, ...args: TArgs) => {\n\t\tif (err) {\n\t\t\tcbs.onFail?.({ errMsg: `${apiName}:fail ${err.message}` })\n\t\t} else {\n\t\t\tcbs.onSuccess?.({ ...(buildOk ? buildOk(...args) : undefined), errMsg: `${apiName}:ok` })\n\t\t}\n\t\tcbs.onComplete?.()\n\t}\n}\n\n/**\n * `mkdir -p` the parent of `destReal`, then run `writeFn` (a `writeFile` /\n * `copyFile` call) through `nodeComplete`. Shared by every API that\n * materializes bytes onto disk under a possibly-not-yet-existing directory\n * (fsWriteFile, fsCopyFile's `_tmp` branch, fsSaveFile).\n */\nfunction mkdirpThenWrite(\n\tdestReal: string,\n\tapiName: string,\n\tcbs: FsCallbacks,\n\twriteFn: (done: (err: NodeErr) => void) => void,\n\tokExtra?: Record<string, unknown>,\n): void {\n\t_fs.mkdir(_path.dirname(destReal), { recursive: true }, (mkdirErr) => {\n\t\tif (mkdirErr) {\n\t\t\tcbs.onFail?.({ errMsg: `${apiName}:fail ${mkdirErr.message}` })\n\t\t\tcbs.onComplete?.()\n\t\t\treturn\n\t\t}\n\t\twriteFn(nodeComplete(apiName, cbs, () => okExtra))\n\t})\n}\n\nexport function fsAccess(\n\tthis: MiniAppContext,\n\t{ path, success, fail, complete }: { path: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsAccess', cbs)) return\n\tconst v = resolveOrBail(path, 'fsAccess', cbs)\n\tif (!v) return\n\tif (v.kind === 'tmp') {\n\t\t// _tmp existence check: renderer Map hit \u21D2 ok; miss \u21D2 ENOENT-shaped fail.\n\t\t_tmpBytes(path).then(\n\t\t\t() => { onSuccess?.({ errMsg: 'fsAccess:ok' }); onComplete?.() },\n\t\t\ttmpFailHandler('fsAccess', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!v.realPath) {\n\t\tonFail?.({ errMsg: 'fsAccess:fail invalid path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.access(v.realPath, _fs.constants.F_OK, nodeComplete('fsAccess', cbs))\n}\n\nexport function fsStat(\n\tthis: MiniAppContext,\n\t{ path, recursive = false, success, fail, complete }: {\n\t\tpath: string\n\t\trecursive?: boolean\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsStat', cbs)) return\n\tconst v = resolveOrBail(path, 'fsStat', cbs)\n\tif (!v) return\n\tif (v.kind === 'tmp') {\n\t\t// _tmp size is known from the Blob; mtime is 0 (no on-disk timestamp).\n\t\t_tmpBytes(path).then(\n\t\t\t(buf) => {\n\t\t\t\tonSuccess?.({\n\t\t\t\t\tstats: {\n\t\t\t\t\t\tsize: buf.length,\n\t\t\t\t\t\tmode: 0,\n\t\t\t\t\t\tlastAccessedTime: 0,\n\t\t\t\t\t\tlastModifiedTime: 0,\n\t\t\t\t\t\tisFile: true,\n\t\t\t\t\t\tisDirectory: false,\n\t\t\t\t\t},\n\t\t\t\t\terrMsg: 'fsStat:ok',\n\t\t\t\t})\n\t\t\t\tonComplete?.()\n\t\t\t},\n\t\t\ttmpFailHandler('fsStat', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!v.realPath) {\n\t\tonFail?.({ errMsg: 'fsStat:fail invalid path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\tconst resolved = v.realPath\n\tif (recursive) {\n\t\t// Build a map of path \u2192 stat info for the directory tree\n\t\tconst statsMap: Record<string, unknown> = {}\n\t\tconst walkDir = (dir: string, cb: (err: Error | null) => void) => {\n\t\t\t_fs.readdir(dir, { withFileTypes: true }, (err, entries) => {\n\t\t\t\tif (err) { cb(err); return }\n\t\t\t\tlet pending = entries.length\n\t\t\t\tif (pending === 0) { cb(null); return }\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tconst full = _path.join(dir, entry.name)\n\t\t\t\t\t_fs.stat(full, (statErr, s) => {\n\t\t\t\t\t\tif (!statErr) {\n\t\t\t\t\t\t\tstatsMap[full] = {\n\t\t\t\t\t\t\t\tsize: s.size,\n\t\t\t\t\t\t\t\tmode: s.mode,\n\t\t\t\t\t\t\t\tlastAccessedTime: s.atimeMs,\n\t\t\t\t\t\t\t\tlastModifiedTime: s.mtimeMs,\n\t\t\t\t\t\t\t\tisFile: s.isFile(),\n\t\t\t\t\t\t\t\tisDirectory: s.isDirectory(),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (entry.isDirectory()) {\n\t\t\t\t\t\t\twalkDir(full, () => { if (--pending === 0) cb(null) })\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (--pending === 0) cb(null)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\twalkDir(resolved, (err) => {\n\t\t\tif (err) {\n\t\t\t\tonFail?.({ errMsg: `fsStat:fail ${err.message}` })\n\t\t\t} else {\n\t\t\t\tonSuccess?.({ stats: statsMap, errMsg: 'fsStat:ok' })\n\t\t\t}\n\t\t\tonComplete?.()\n\t\t})\n\t} else {\n\t\t_fs.stat(resolved, nodeComplete('fsStat', cbs, (s: NodeStats) => ({\n\t\t\tstats: {\n\t\t\t\tsize: s.size,\n\t\t\t\tmode: s.mode,\n\t\t\t\tlastAccessedTime: s.atimeMs,\n\t\t\t\tlastModifiedTime: s.mtimeMs,\n\t\t\t\tisFile: s.isFile(),\n\t\t\t\tisDirectory: s.isDirectory(),\n\t\t\t},\n\t\t})))\n\t}\n}\n\nexport function fsReadFile(\n\tthis: MiniAppContext,\n\t{ filePath, encoding, success, fail, complete }: {\n\t\tfilePath: string\n\t\tencoding?: BufferEncoding\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsReadFile', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsReadFile', cbs)\n\tif (!v) return\n\tif (v.kind === 'tmp') {\n\t\t_tmpBytes(filePath).then(\n\t\t\t(buf) => {\n\t\t\t\tconst data: Buffer | string = encoding ? buf.toString(encoding) : buf\n\t\t\t\tonSuccess?.({ data, errMsg: 'fsReadFile:ok' })\n\t\t\t\tonComplete?.()\n\t\t\t},\n\t\t\ttmpFailHandler('fsReadFile', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!v.realPath) {\n\t\tonFail?.({ errMsg: 'fsReadFile:fail invalid path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.readFile(v.realPath, encoding || null, nodeComplete('fsReadFile', cbs, (data: Buffer | string) => ({ data })))\n}\n\nexport function fsWriteFile(\n\tthis: MiniAppContext,\n\t{ filePath, data, encoding = 'utf8', success, fail, complete }: {\n\t\tfilePath: string\n\t\tdata: string | Uint8Array\n\t\tencoding?: BufferEncoding\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsWriteFile', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsWriteFile', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsWriteFile', cbs)) return\n\tmkdirpThenWrite(v.realPath, 'fsWriteFile', cbs, done => _fs.writeFile(v.realPath, data as string, { encoding }, done))\n}\n\nexport function fsAppendFile(\n\tthis: MiniAppContext,\n\t{ filePath, data, encoding = 'utf8', success, fail, complete }: {\n\t\tfilePath: string\n\t\tdata: string | Uint8Array\n\t\tencoding?: BufferEncoding\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsAppendFile', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsAppendFile', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsAppendFile', cbs)) return\n\t_fs.appendFile(v.realPath, data as string, { encoding }, nodeComplete('fsAppendFile', cbs))\n}\n\nexport function fsCopyFile(\n\tthis: MiniAppContext,\n\t{ srcPath, destPath, success, fail, complete }: {\n\t\tsrcPath: string\n\t\tdestPath: string\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsCopyFile', cbs)) return\n\tconst vSrc = resolveOrBail(srcPath, 'fsCopyFile', cbs)\n\tif (!vSrc) return\n\tconst vDest = resolveOrBail(destPath, 'fsCopyFile', cbs)\n\tif (!vDest) return\n\tif (!ensureWritable(vDest, 'fsCopyFile', cbs)) return\n\tif (vSrc.kind === 'tmp') {\n\t\t// Materialize the renderer Blob into the user-data\n\t\t// area. The dest writable check above already rejected _tmp / _store\n\t\t// destinations \u2014 saveFile is the documented route for tmp\u2192store.\n\t\t_tmpBytes(srcPath).then(\n\t\t\tbuf => mkdirpThenWrite(vDest.realPath, 'fsCopyFile', cbs, done => _fs.writeFile(vDest.realPath, buf, done)),\n\t\t\ttmpFailHandler('fsCopyFile', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!vSrc.realPath) {\n\t\tonFail?.({ errMsg: 'fsCopyFile:fail invalid src path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.copyFile(vSrc.realPath, vDest.realPath, nodeComplete('fsCopyFile', cbs))\n}\n\nexport function fsRename(\n\tthis: MiniAppContext,\n\t{ oldPath, newPath, success, fail, complete }: {\n\t\toldPath: string\n\t\tnewPath: string\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsRename', cbs)) return\n\tconst vOld = resolveOrBail(oldPath, 'fsRename', cbs)\n\tif (!vOld) return\n\tconst vNew = resolveOrBail(newPath, 'fsRename', cbs)\n\tif (!vNew) return\n\t// Rename deletes the source \u2014 both sides must be writable. _tmp / _store\n\t// reject under either role.\n\tif (!ensureWritable(vOld, 'fsRename', cbs)) return\n\tif (!ensureWritable(vNew, 'fsRename', cbs)) return\n\t_fs.rename(vOld.realPath, vNew.realPath, nodeComplete('fsRename', cbs))\n}\n\nexport function fsUnlink(\n\tthis: MiniAppContext,\n\t{ filePath, success, fail, complete }: { filePath: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsUnlink', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsUnlink', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsUnlink', cbs)) return\n\t_fs.unlink(v.realPath, nodeComplete('fsUnlink', cbs))\n}\n\nexport function fsMkdir(\n\tthis: MiniAppContext,\n\t{ dirPath, recursive = false, success, fail, complete }: {\n\t\tdirPath: string\n\t\trecursive?: boolean\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsMkdir', cbs)) return\n\tconst v = resolveOrBail(dirPath, 'fsMkdir', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsMkdir', cbs)) return\n\t_fs.mkdir(v.realPath, { recursive }, nodeComplete('fsMkdir', cbs))\n}\n\nexport function fsRmdir(\n\tthis: MiniAppContext,\n\t{ dirPath, recursive = false, success, fail, complete }: {\n\t\tdirPath: string\n\t\trecursive?: boolean\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsRmdir', cbs)) return\n\tconst v = resolveOrBail(dirPath, 'fsRmdir', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsRmdir', cbs)) return\n\t// Node 14+: rm with recursive; older Node: rmdir with recursive flag\n\tconst rmFn = (_fs as typeof _fs & { rm?: typeof _fs.rmdir }).rm ?? _fs.rmdir\n\trmFn(v.realPath, { recursive } as Parameters<typeof _fs.rmdir>[1], nodeComplete('fsRmdir', cbs))\n}\n\nexport function fsReaddir(\n\tthis: MiniAppContext,\n\t{ dirPath, success, fail, complete }: { dirPath: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsReaddir', cbs)) return\n\tconst v = resolveOrBail(dirPath, 'fsReaddir', cbs)\n\tif (!v) return\n\t// _tmp and _store are flat (id-addressed) namespaces \u2014 readdir is meaningless.\n\tif (v.kind === 'tmp' || v.kind === 'store') {\n\t\tonFail?.({ errMsg: `fsReaddir:fail ${v.kind} is a flat namespace (no dir tree)` })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\tif (!v.realPath) {\n\t\tonFail?.({ errMsg: 'fsReaddir:fail invalid path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.readdir(v.realPath, nodeComplete('fsReaddir', cbs, (files: string[]) => ({ files })))\n}\n\nexport function fsGetFileInfo(\n\tthis: MiniAppContext,\n\t{ filePath, digestAlgorithm, success, fail, complete }: {\n\t\tfilePath: string\n\t\tdigestAlgorithm?: string\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsGetFileInfo', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsGetFileInfo', cbs)\n\tif (!v) return\n\tif (v.kind === 'tmp') {\n\t\t_tmpBytes(filePath).then(\n\t\t\t(buf) => {\n\t\t\t\tconst result: Record<string, unknown> = { size: buf.length, errMsg: 'fsGetFileInfo:ok' }\n\t\t\t\tif (digestAlgorithm) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst hash = _crypto.createHash(digestAlgorithm === 'md5' ? 'md5' : 'sha1')\n\t\t\t\t\t\thash.update(buf)\n\t\t\t\t\t\tresult.digest = hash.digest('hex')\n\t\t\t\t\t}\n\t\t\t\t\tcatch {\n\t\t\t\t\t\t// crypto unavailable \u2014 fall through without digest.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tonSuccess?.(result)\n\t\t\t\tonComplete?.()\n\t\t\t},\n\t\t\ttmpFailHandler('fsGetFileInfo', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!v.realPath) {\n\t\tonFail?.({ errMsg: 'fsGetFileInfo:fail invalid path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\tconst resolved = v.realPath\n\t_fs.stat(resolved, (err, s) => {\n\t\tif (err) {\n\t\t\tonFail?.({ errMsg: `fsGetFileInfo:fail ${err.message}` })\n\t\t\tonComplete?.()\n\t\t\treturn\n\t\t}\n\t\tconst result: Record<string, unknown> = { size: s.size, errMsg: 'fsGetFileInfo:ok' }\n\t\tif (digestAlgorithm) {\n\t\t\t// Compute digest if crypto is available\n\t\t\ttry {\n\t\t\t\tconst hash = _crypto.createHash(digestAlgorithm === 'md5' ? 'md5' : 'sha1')\n\t\t\t\tconst stream = _fs.createReadStream(resolved)\n\t\t\t\tstream.on('data', (chunk) => hash.update(chunk as Buffer))\n\t\t\t\tstream.on('end', () => {\n\t\t\t\t\tresult.digest = hash.digest('hex')\n\t\t\t\t\tonSuccess?.(result)\n\t\t\t\t\tonComplete?.()\n\t\t\t\t})\n\t\t\t\tstream.on('error', (hashErr) => {\n\t\t\t\t\tonFail?.({ errMsg: `fsGetFileInfo:fail ${hashErr.message}` })\n\t\t\t\t\tonComplete?.()\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t} catch {\n\t\t\t\t// crypto not available, skip digest\n\t\t\t}\n\t\t}\n\t\tonSuccess?.(result)\n\t\tonComplete?.()\n\t})\n}\n\n/**\n * Save a temp file into the read-only `_store/` namespace. Returns a vpath\n * (`difile://_store/{uuid}.{ext}`) rather than a real disk path so callers\n * cannot leak the host filesystem layout.\n *\n * Scope:\n * - source must be a `difile://`-anchored vpath (validator rejects abs paths);\n * - source from `_tmp/` materializes the renderer Blob into `_store/` via the\n * renderer-Blob \u2192 main-fs copy bridge;\n * - source from `_store/` or the user-data area is copied byte-for-byte to a\n * freshly minted `_store/{uuid}.{ext}` entry under the sandbox base.\n */\nexport function fsSaveFile(\n\tthis: MiniAppContext,\n\t{ tempFilePath, filePath: _filePath, success, fail, complete }: {\n\t\ttempFilePath: string\n\t\tfilePath?: string\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tvoid _filePath\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsSaveFile', cbs)) return\n\tconst src = resolveOrBail(tempFilePath, 'fsSaveFile', cbs)\n\tif (!src) return\n\tconst ext = _path.extname(tempFilePath) || ''\n\tconst id = _crypto.randomUUID() + ext\n\tconst savedFilePath = `difile://_store/${id}`\n\tconst destResolved = resolveVPath(savedFilePath)\n\tif (!destResolved || !destResolved.realPath) {\n\t\t// Defensive: a freshly minted vpath must always resolve.\n\t\tonFail?.({ errMsg: 'fsSaveFile:fail unable to allocate destination' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\tconst destReal = destResolved.realPath\n\n\tif (src.kind === 'tmp') {\n\t\t// Materialize the renderer Blob into _store on disk.\n\t\t_tmpBytes(tempFilePath).then(\n\t\t\tbytes => mkdirpThenWrite(destReal, 'fsSaveFile', cbs, done => _fs.writeFile(destReal, bytes, done), { savedFilePath }),\n\t\t\ttmpFailHandler('fsSaveFile', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!src.realPath) {\n\t\tonFail?.({ errMsg: 'fsSaveFile:fail invalid src path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\tmkdirpThenWrite(destReal, 'fsSaveFile', cbs, done => _fs.copyFile(src.realPath!, destReal, done), { savedFilePath })\n}\n\n/**\n * List files previously persisted by `fsSaveFile` \u2014 i.e. anything under the\n * `_store/` namespace. Returned `filePath` entries are vpaths so callers can\n * round-trip through `fsReadFile` / `fsRemoveSavedFile` without ever seeing\n * the host filesystem.\n */\nexport function fsGetSavedFileList(\n\tthis: MiniAppContext,\n\t{ success, fail, complete }: { success?: unknown; fail?: unknown; complete?: unknown } = {},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onComplete } = cbs\n\tif (guardFsAvailable('fsGetSavedFileList', cbs)) return\n\tconst storeVpath = resolveVPath('difile://_store/')\n\tconst storeDir = storeVpath?.realPath\n\tif (!storeDir) {\n\t\tonSuccess?.({ fileList: [], errMsg: 'fsGetSavedFileList:ok' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.readdir(storeDir, (err, files) => {\n\t\tif (err) {\n\t\t\t// Directory may not exist yet \u2014 return empty list\n\t\t\tonSuccess?.({ fileList: [], errMsg: 'fsGetSavedFileList:ok' })\n\t\t\tonComplete?.()\n\t\t\treturn\n\t\t}\n\t\tlet pending = files.length\n\t\tif (pending === 0) {\n\t\t\tonSuccess?.({ fileList: [], errMsg: 'fsGetSavedFileList:ok' })\n\t\t\tonComplete?.()\n\t\t\treturn\n\t\t}\n\t\tconst fileList: Array<{ filePath: string; size: number; createTime: number }> = []\n\t\tfor (const name of files) {\n\t\t\tconst full = _path.join(storeDir, name)\n\t\t\t_fs.stat(full, (statErr, s) => {\n\t\t\t\tif (!statErr) {\n\t\t\t\t\tfileList.push({\n\t\t\t\t\t\tfilePath: `difile://_store/${name}`,\n\t\t\t\t\t\tsize: s.size,\n\t\t\t\t\t\tcreateTime: s.birthtimeMs,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif (--pending === 0) {\n\t\t\t\t\tonSuccess?.({ fileList, errMsg: 'fsGetSavedFileList:ok' })\n\t\t\t\t\tonComplete?.()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nexport function fsRemoveSavedFile(\n\tthis: MiniAppContext,\n\t{ filePath, success, fail, complete }: { filePath: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsRemoveSavedFile', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsRemoveSavedFile', cbs)\n\tif (!v) return\n\t// removeSavedFile is the documented exception to the `_store/` read-only\n\t// rule. Only `_store/*` entries may be removed through this API.\n\tif (v.kind !== 'store' || !v.realPath) {\n\t\tonFail?.({ errMsg: 'fsRemoveSavedFile:fail only _store/ entries may be removed' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.unlink(v.realPath, nodeComplete('fsRemoveSavedFile', cbs))\n}\n\nexport function fsTruncate(\n\tthis: MiniAppContext,\n\t{ filePath, length = 0, success, fail, complete }: {\n\t\tfilePath: string\n\t\tlength?: number\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsTruncate', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsTruncate', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsTruncate', cbs)) return\n\t_fs.truncate(v.realPath, length, nodeComplete('fsTruncate', cbs))\n}\n\nexport const fsUnzip = notSupportedApi('fsUnzip')\n", "/**\n * DevTools API stubs for network-related wx.xxx APIs.\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi -> MiniApp.invokeApi).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks } from './simulator-api-helpers'\nimport { createTempFilePath, getTempFileName, resolveTempFilePath } from './temp-files'\n\nexport function downloadFile(\n\tthis: MiniAppContext,\n\t{ url, header = {}, filePath, success, fail, complete }: {\n\t\turl: string\n\t\theader?: Record<string, string>\n\t\tfilePath?: string\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\n\tfetch(url, { headers: header })\n\t\t.then(async (response) => {\n\t\t\tif (!response.ok) throw new Error(response.statusText)\n\t\t\tconst blob = await response.blob()\n\t\t\tconst tempFilePath = createTempFilePath(blob)\n\t\t\tonSuccess?.({\n\t\t\t\ttempFilePath,\n\t\t\t\tfilePath: filePath || tempFilePath,\n\t\t\t\tstatusCode: response.status,\n\t\t\t\terrMsg: 'downloadFile:ok',\n\t\t\t})\n\t\t})\n\t\t.catch((error: Error) => {\n\t\t\tonFail?.({ errMsg: `downloadFile:fail ${error.message}` })\n\t\t})\n\t\t.finally(() => {\n\t\t\tonComplete?.()\n\t\t})\n}\n\ntype UploadFileOptions = {\n\turl: string\n\tfilePath: string\n\tname: string\n\theader?: Record<string, string>\n\tformData?: Record<string, unknown>\n\ttimeout?: number\n\tuploadId?: string\n\tprogress?: unknown\n\theadersReceived?: unknown\n\tsuccess?: unknown\n\tfail?: unknown\n\tcomplete?: unknown\n}\n\nconst uploadRequests = new Map<string, XMLHttpRequest>()\nconst uploadPendingResolves = new Set<string>()\nconst uploadAbortedBeforeStart = new Set<string>()\nlet nextUploadId = 1\n\nfunction createUploadId(): string {\n\treturn `upload_${Date.now()}_${nextUploadId++}`\n}\n\nfunction parseResponseHeaders(raw: string): Record<string, string> {\n\tconst headers: Record<string, string> = {}\n\tfor (const line of raw.trim().split(/[\\r\\n]+/)) {\n\t\tif (!line) continue\n\t\tconst index = line.indexOf(':')\n\t\tif (index <= 0) continue\n\t\tconst key = line.slice(0, index).trim()\n\t\tconst value = line.slice(index + 1).trim()\n\t\tif (key) headers[key] = value\n\t}\n\treturn headers\n}\n\nfunction appendFormData(form: FormData, formData: Record<string, unknown>): void {\n\tfor (const [key, value] of Object.entries(formData)) {\n\t\tif (value == null) continue\n\t\tif (value instanceof Blob) {\n\t\t\tform.append(key, value)\n\t\t} else if (typeof value === 'object') {\n\t\t\t// JSON.stringify for plain objects/arrays; Map/Set/RegExp/TypedArray\n\t\t\t// fall through here too and become '{}' or similar \u2014 caller should\n\t\t\t// pre-stringify if they need a specific form.\n\t\t\tform.append(key, JSON.stringify(value))\n\t\t} else {\n\t\t\tform.append(key, String(value))\n\t\t}\n\t}\n}\n\nexport function uploadFile(\n\tthis: MiniAppContext,\n\t{\n\t\turl,\n\t\tfilePath,\n\t\tname,\n\t\theader = {},\n\t\tformData = {},\n\t\ttimeout,\n\t\tuploadId = createUploadId(),\n\t\tprogress,\n\t\theadersReceived,\n\t\tsuccess,\n\t\tfail,\n\t\tcomplete,\n\t}: UploadFileOptions,\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\tconst onProgress = this.createCallbackFunction(progress)\n\tconst onHeadersReceived = this.createCallbackFunction(headersReceived)\n\n\tconst cleanup = () => {\n\t\tuploadRequests.delete(uploadId)\n\t\tuploadPendingResolves.delete(uploadId)\n\t\tuploadAbortedBeforeStart.delete(uploadId)\n\t}\n\tconst finishFail = (message: string) => {\n\t\tcleanup()\n\t\tconst result = { errMsg: `uploadFile:fail ${message}` }\n\t\tonFail?.(result)\n\t\tonComplete?.(result)\n\t}\n\n\tuploadPendingResolves.add(uploadId)\n\tvoid resolveTempFilePath(filePath)\n\t\t.then((blob) => {\n\t\t\tuploadPendingResolves.delete(uploadId)\n\t\t\tif (uploadAbortedBeforeStart.has(uploadId)) {\n\t\t\t\tfinishFail('abort')\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst xhr = new XMLHttpRequest()\n\t\t\tlet settled = false\n\t\t\tlet deliveredHeaders = false\n\t\t\tuploadRequests.set(uploadId, xhr)\n\n\t\t\tconst finishSuccess = () => {\n\t\t\t\tif (settled) return\n\t\t\t\tsettled = true\n\t\t\t\tconst headers = parseResponseHeaders(xhr.getAllResponseHeaders())\n\t\t\t\tcleanup()\n\t\t\t\tconst result = {\n\t\t\t\t\tdata: typeof xhr.response === 'string' ? xhr.response : xhr.responseText,\n\t\t\t\t\tstatusCode: xhr.status,\n\t\t\t\t\theader: headers,\n\t\t\t\t\terrMsg: 'uploadFile:ok',\n\t\t\t\t}\n\t\t\t\tonSuccess?.(result)\n\t\t\t\tonComplete?.(result)\n\t\t\t}\n\t\t\tconst finishXhrFail = (message: string) => {\n\t\t\t\tif (settled) return\n\t\t\t\tsettled = true\n\t\t\t\tfinishFail(message)\n\t\t\t}\n\t\t\tconst emitHeaders = () => {\n\t\t\t\tif (deliveredHeaders) return\n\t\t\t\tdeliveredHeaders = true\n\t\t\t\tonHeadersReceived?.({ header: parseResponseHeaders(xhr.getAllResponseHeaders()) })\n\t\t\t}\n\n\t\t\txhr.open('POST', url, true)\n\t\t\tif (timeout === undefined) {\n\t\t\t\txhr.timeout = 60_000\n\t\t\t} else if (Number(timeout) > 0) {\n\t\t\t\txhr.timeout = Number(timeout)\n\t\t\t}\n\t\t\tfor (const [key, value] of Object.entries(header)) {\n\t\t\t\tif (/^(referer|content-type)$/i.test(key)) continue\n\t\t\t\txhr.setRequestHeader(key, String(value))\n\t\t\t}\n\t\t\txhr.upload.onprogress = (event) => {\n\t\t\t\tconst totalBytesExpectedToSend = event.lengthComputable ? event.total : blob.size\n\t\t\t\tconst progressValue = totalBytesExpectedToSend > 0\n\t\t\t\t\t? Math.round((event.loaded / totalBytesExpectedToSend) * 100)\n\t\t\t\t\t: 0\n\t\t\t\tonProgress?.({\n\t\t\t\t\tprogress: Math.max(0, Math.min(100, progressValue)),\n\t\t\t\t\ttotalBytesSent: event.loaded,\n\t\t\t\t\ttotalBytesExpectedToSend,\n\t\t\t\t})\n\t\t\t}\n\t\t\txhr.onreadystatechange = () => {\n\t\t\t\tif (xhr.readyState >= XMLHttpRequest.HEADERS_RECEIVED) emitHeaders()\n\t\t\t}\n\t\t\txhr.onload = () => {\n\t\t\t\temitHeaders()\n\t\t\t\tfinishSuccess()\n\t\t\t}\n\t\t\txhr.onerror = () => finishXhrFail('network error')\n\t\t\txhr.ontimeout = () => finishXhrFail('timeout')\n\t\t\txhr.onabort = () => finishXhrFail('abort')\n\n\t\t\tconst body = new FormData()\n\t\t\tappendFormData(body, formData)\n\t\t\tbody.append(name, blob, getTempFileName(filePath, blob, name || 'file'))\n\t\t\txhr.send(body)\n\t\t})\n\t\t.catch((error: Error) => {\n\t\t\tfinishFail(error.message)\n\t\t})\n}\n\nexport function uploadFileAbort(this: MiniAppContext, { uploadId }: { uploadId?: string } = {}) {\n\tif (!uploadId) return\n\tconst xhr = uploadRequests.get(uploadId)\n\tif (xhr) {\n\t\txhr.abort()\n\t\treturn\n\t}\n\tif (uploadPendingResolves.has(uploadId)) {\n\t\tuploadAbortedBeforeStart.add(uploadId)\n\t}\n}\n", "/**\n * In-renderer pub/sub store for the simulator's native UI overlays (toast,\n * loading, modal, action sheet).\n *\n * The wx.* UI handlers in `simulator-api-ui.ts` run inside the simulator\n * renderer (via runApiAsync) but cannot touch React state directly. They push\n * the desired overlay into this singleton; the `DeviceShell`-resident\n * `<UiOverlay>` subscribes and renders it inside the device frame (above the\n * page <webview>, clipped to the bezel \u2014 the same layering the status/nav bar\n * already use). User interaction (modal confirm/cancel, action-sheet tap) is\n * routed back to the handler through the `onResult` / `onSelect` callbacks the\n * handler attaches to the dialog state.\n */\n\nexport interface ToastState {\n title: string\n icon: 'success' | 'error' | 'loading' | 'none'\n image?: string\n /** ms before auto-dismiss; Infinity for showLoading (dismissed explicitly). */\n duration: number\n mask: boolean\n}\n\nexport interface ModalDialogState {\n kind: 'modal'\n title: string\n content: string\n showCancel: boolean\n cancelText: string\n cancelColor: string\n confirmText: string\n confirmColor: string\n editable: boolean\n placeholderText: string\n /** The renderer calls this when the user taps confirm/cancel. */\n onResult: (confirmed: boolean, content?: string) => void\n}\n\nexport interface ActionSheetDialogState {\n kind: 'actionSheet'\n itemList: string[]\n itemColor: string\n /** The renderer calls this with the tapped index, or -1 to cancel. */\n onSelect: (index: number) => void\n}\n\nexport type DialogState = ModalDialogState | ActionSheetDialogState\n\nexport interface UiOverlayState {\n toast: ToastState | null\n dialog: DialogState | null\n}\n\ntype Listener = (state: UiOverlayState) => void\n\nclass UiOverlayBus {\n private state: UiOverlayState = { toast: null, dialog: null }\n private readonly listeners = new Set<Listener>()\n\n getState(): UiOverlayState {\n return this.state\n }\n\n subscribe(listener: Listener): () => void {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n showToast(toast: ToastState): void {\n this.set({ ...this.state, toast })\n }\n\n hideToast(): void {\n this.set({ ...this.state, toast: null })\n }\n\n /**\n * Clear `toast` only if it is still the active one. The toast auto-dismiss\n * timer holds a reference to the toast it scheduled; a newer showToast may\n * have replaced it in the meantime, and a blind `hideToast()` from the stale\n * timer would wrongly clear the new toast.\n */\n dismissToast(toast: ToastState): void {\n if (this.state.toast === toast) this.hideToast()\n }\n\n showDialog(dialog: DialogState): void {\n this.set({ ...this.state, dialog })\n }\n\n hideDialog(): void {\n this.set({ ...this.state, dialog: null })\n }\n\n private set(next: UiOverlayState): void {\n this.state = next\n for (const listener of this.listeners) listener(next)\n }\n}\n\nexport const uiOverlayBus = new UiOverlayBus()\n", "/**\n * DevTools implementations for the WeChat-style interaction APIs that native\n * platforms (iOS / Android / Harmony) provide but the web container lacks:\n * showToast / hideToast / showLoading / hideLoading / showModal /\n * showActionSheet.\n *\n * Each handler is bound with `this` = MiniApp instance (via\n * AppManager.registerApi \u2192 MiniApp.invokeApi). The overlay is rendered by the\n * DeviceShell-resident `<UiOverlay>`; these handlers only push state into\n * `uiOverlayBus` and fire the success/fail/complete callbacks \u2014 immediately for\n * toast/loading, and on user interaction for modal/actionSheet (defaults and\n * verdict strings mirror the Android `InteractionApi`).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks } from './simulator-api-helpers'\nimport { uiOverlayBus } from './ui-overlay-bus'\n\ninterface ToastOpts {\n title?: string\n icon?: 'success' | 'error' | 'loading' | 'none'\n image?: string\n duration?: number\n mask?: boolean\n success?: unknown\n fail?: unknown\n complete?: unknown\n}\n\nexport function showToast(this: MiniAppContext, opts: ToastOpts = {}) {\n const { onSuccess, onComplete } = bindCallbacks(this, opts)\n uiOverlayBus.showToast({\n title: opts.title ?? '',\n icon: opts.icon ?? 'success',\n image: opts.image,\n duration: opts.duration ?? 1500,\n mask: opts.mask ?? false,\n })\n onSuccess?.({ errMsg: 'showToast:ok' })\n onComplete?.()\n}\n\nexport function hideToast(this: MiniAppContext, opts: { success?: unknown; complete?: unknown } = {}) {\n const { onSuccess, onComplete } = bindCallbacks(this, opts)\n uiOverlayBus.hideToast()\n onSuccess?.({ errMsg: 'hideToast:ok' })\n onComplete?.()\n}\n\nexport function showLoading(\n this: MiniAppContext,\n opts: { title?: string; mask?: boolean; success?: unknown; complete?: unknown } = {},\n) {\n const { onSuccess, onComplete } = bindCallbacks(this, opts)\n uiOverlayBus.showToast({\n title: opts.title ?? '',\n icon: 'loading',\n duration: Infinity,\n mask: opts.mask ?? false,\n })\n onSuccess?.({ errMsg: 'showLoading:ok' })\n onComplete?.()\n}\n\nexport function hideLoading(this: MiniAppContext, opts: { success?: unknown; complete?: unknown } = {}) {\n const { onSuccess, onComplete } = bindCallbacks(this, opts)\n uiOverlayBus.hideToast()\n onSuccess?.({ errMsg: 'hideLoading:ok' })\n onComplete?.()\n}\n\ninterface ModalOpts {\n title?: string\n content?: string\n showCancel?: boolean\n cancelText?: string\n cancelColor?: string\n confirmText?: string\n confirmColor?: string\n editable?: boolean\n placeholderText?: string\n success?: unknown\n fail?: unknown\n complete?: unknown\n}\n\nexport function showModal(this: MiniAppContext, opts: ModalOpts = {}) {\n const { onSuccess, onComplete } = bindCallbacks(this, opts)\n const editable = opts.editable ?? false\n // Guard against a double resolution (rapid double-tap / a re-render firing the\n // handler twice) settling the callbacks more than once.\n let settled = false\n uiOverlayBus.showDialog({\n kind: 'modal',\n title: opts.title ?? '',\n content: opts.content ?? '',\n showCancel: opts.showCancel ?? true,\n cancelText: opts.cancelText ?? '\u53D6\u6D88',\n cancelColor: opts.cancelColor ?? '#000000',\n confirmText: opts.confirmText ?? '\u786E\u5B9A',\n confirmColor: opts.confirmColor ?? '#576B95',\n editable,\n placeholderText: opts.placeholderText ?? '',\n onResult: (confirmed, content) => {\n if (settled) return\n settled = true\n uiOverlayBus.hideDialog()\n const result: Record<string, unknown> = {\n confirm: confirmed,\n cancel: !confirmed,\n errMsg: 'showModal:ok',\n }\n if (editable) result.content = content ?? ''\n onSuccess?.(result)\n onComplete?.()\n },\n })\n}\n\ninterface ActionSheetOpts {\n itemList?: string[]\n itemColor?: string\n success?: unknown\n fail?: unknown\n complete?: unknown\n}\n\nexport function showActionSheet(this: MiniAppContext, opts: ActionSheetOpts = {}) {\n const { onSuccess, onFail, onComplete } = bindCallbacks(this, opts)\n let settled = false\n uiOverlayBus.showDialog({\n kind: 'actionSheet',\n itemList: opts.itemList ?? [],\n itemColor: opts.itemColor ?? '#000000',\n onSelect: (index) => {\n if (settled) return\n settled = true\n uiOverlayBus.hideDialog()\n if (index === -1) {\n onFail?.({ errMsg: 'showActionSheet:fail cancel' })\n } else {\n onSuccess?.({ tapIndex: index, errMsg: 'showActionSheet:ok' })\n }\n onComplete?.()\n },\n })\n}\n", "/**\n * DevTools API stubs for wx.xxx APIs that exist on native platforms\n * (iOS / Android / Harmony) but are missing in the web container.\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi \u2192 MiniApp.invokeApi).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks } from './simulator-api-helpers'\nimport {\n\tsetStorageSync,\n\tgetStorageSync,\n\tremoveStorageSync,\n\tclearStorageSync,\n\tgetStorageInfoSync,\n\tsetStorage,\n\tgetStorage,\n\tremoveStorage,\n\tclearStorage,\n\tgetStorageInfo,\n} from './simulator-api-storage'\nimport {\n\thideKeyboard,\n\tadjustPosition,\n\tmakePhoneCall,\n\tchooseContact,\n\taddPhoneContact,\n\tvibrateShort,\n\tvibrateLong,\n\tscanCode,\n\tgetClipboardData,\n\tsetClipboardData,\n\tgetNetworkType,\n} from './simulator-api-device'\nimport {\n\tchooseImage,\n\tpreviewImage,\n\tcompressImage,\n\tsaveImageToPhotosAlbum,\n\tgetImageInfo,\n\tchooseMedia,\n\tchooseVideo,\n\taudioCreate,\n\taudioListen,\n\taudioSetProp,\n\taudioPlay,\n\taudioPause,\n\taudioStop,\n\taudioSeek,\n\taudioDestroy,\n} from './simulator-api-media'\nimport {\n\tfsAccess,\n\tfsStat,\n\tfsReadFile,\n\tfsWriteFile,\n\tfsAppendFile,\n\tfsCopyFile,\n\tfsRename,\n\tfsUnlink,\n\tfsMkdir,\n\tfsRmdir,\n\tfsReaddir,\n\tfsGetFileInfo,\n\tfsSaveFile,\n\tfsGetSavedFileList,\n\tfsRemoveSavedFile,\n\tfsTruncate,\n\tfsUnzip,\n} from './simulator-api-fs'\nimport {\n\tdownloadFile,\n\tuploadFile,\n\tuploadFileAbort,\n} from './simulator-api-network'\nexport {\n\tdownloadFile,\n\tuploadFile,\n\tuploadFileAbort,\n} from './simulator-api-network'\nimport {\n\tshowToast,\n\thideToast,\n\tshowLoading,\n\thideLoading,\n\tshowModal,\n\tshowActionSheet,\n} from './simulator-api-ui'\n\n// \u2500\u2500\u2500 Base \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function canIUse(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown }) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\t// In devtools all standard APIs are considered available.\n\tonSuccess?.(true)\n\tonComplete?.()\n\t// Also return synchronously for callers that use the return value.\n\treturn true\n}\n\nexport function getWindowInfo(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\n\tconst { wb, di, dev, pixelRatio, screenWidth, screenHeight, windowWidth, windowHeight } = readWindowMetrics(this)\n\tconst bar = this.parent?.getStatusBarRect?.() ?? { height: dev?.statusBarHeight ?? 0 }\n\tconst statusBarHeight = (di['statusBarHeight'] as number | undefined) ?? bar.height\n\n\tconst info = {\n\t\tpixelRatio, screenWidth, screenHeight, windowWidth, windowHeight,\n\t\tstatusBarHeight,\n\t\tsafeArea: {\n\t\t\twidth: wb.width,\n\t\t\theight: wb.height - statusBarHeight,\n\t\t\ttop: statusBarHeight,\n\t\t\tbottom: wb.height,\n\t\t\tleft: 0,\n\t\t\tright: wb.width,\n\t\t},\n\t}\n\tonSuccess?.(info)\n\tonComplete?.()\n\treturn info\n}\n\nexport function getSystemSetting(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\n\tconst info = {\n\t\tbluetoothEnabled: false,\n\t\tlocationEnabled: true,\n\t\twifiEnabled: true,\n\t\tdeviceOrientation: 'portrait',\n\t}\n\tonSuccess?.(info)\n\tonComplete?.()\n\treturn info\n}\n\n// \u2500\u2500\u2500 System Info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction readWindowMetrics(miniApp: MiniAppContext) {\n\t// Priority unchanged: __deviceInfo \u2192 host DOM rect. Only the last-resort\n\t// fallback follows the CURRENTLY emulated device (SimulatorMiniApp tracks\n\t// boot config device + live DEVICE_CHANGE) instead of a hardcoded 375x812.\n\tconst dev = miniApp.getDeviceMetrics?.()\n\tconst wb = miniApp.parent?.el?.querySelector('.dimina-native-webview__root')?.getBoundingClientRect()\n\t\t?? { width: dev?.screenWidth ?? 375, height: dev?.screenHeight ?? 812 }\n\tconst di = (window as Window & { __deviceInfo?: Record<string, unknown> }).__deviceInfo || {}\n\treturn {\n\t\twb,\n\t\tdi,\n\t\tdev,\n\t\tpixelRatio: (di['pixelRatio'] as number | undefined) || dev?.pixelRatio || window.devicePixelRatio || 2,\n\t\tscreenWidth: (di['screenWidth'] as number | undefined) || wb.width,\n\t\tscreenHeight: (di['screenHeight'] as number | undefined) || wb.height,\n\t\twindowWidth: wb.width,\n\t\twindowHeight: wb.height,\n\t}\n}\n\nfunction buildSystemInfo(miniApp: MiniAppContext) {\n\tconst { wb, di, dev, pixelRatio, screenWidth, screenHeight, windowWidth, windowHeight } = readWindowMetrics(miniApp)\n\tconst statusBarHeight = (di['statusBarHeight'] as number | undefined) ?? dev?.statusBarHeight ?? 0\n\t// Bottom inset sourced from safeAreaInsets.bottom (the single source \u2014 the\n\t// legacy flat `safeAreaBottom` field is decommissioned).\n\tconst bottomInset = (di['safeAreaInsets'] as { bottom?: number } | undefined)?.bottom\n\t\t?? dev?.safeAreaInsets?.bottom ?? 0\n\n\treturn {\n\t\tbrand: di['brand'] || 'devtools',\n\t\tmodel: di['model'] || 'devtools',\n\t\tpixelRatio, screenWidth, screenHeight, windowWidth, windowHeight,\n\t\tstatusBarHeight,\n\t\tlanguage: 'zh_CN',\n\t\tversion: '8.0.5',\n\t\tsystem: di['system'] || 'iOS 16.0',\n\t\tplatform: di['platform'] || 'ios',\n\t\tfontSizeSetting: 16,\n\t\tSDKVersion: '3.0.0',\n\t\tdeviceOrientation: 'portrait',\n\t\tsafeArea: {\n\t\t\twidth: wb.width,\n\t\t\theight: wb.height - statusBarHeight - bottomInset,\n\t\t\ttop: statusBarHeight,\n\t\t\tbottom: wb.height - bottomInset,\n\t\t\tleft: 0,\n\t\t\tright: wb.width,\n\t\t},\n\t}\n}\n\nexport function getSystemInfoAsync(this: MiniAppContext, opts: { success?: unknown; complete?: unknown }) {\n\tconst { success, complete } = opts\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tonSuccess?.(buildSystemInfo(this))\n\tonComplete?.()\n}\n\nexport function getSystemInfo(this: MiniAppContext, opts: { success?: unknown; complete?: unknown }) {\n\tgetSystemInfoAsync.call(this, opts)\n}\n\nexport function getSystemInfoSync(this: MiniAppContext) {\n\treturn buildSystemInfo(this)\n}\n\n// \u2500\u2500\u2500 Open API: Account Info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getAccountInfoSync(this: MiniAppContext) {\n\treturn {\n\t\tminiProgram: {\n\t\t\tappId: this.appId || '',\n\t\t\tenvVersion: 'develop',\n\t\t\tversion: '',\n\t\t},\n\t}\n}\n\n// \u2500\u2500\u2500 Collect all APIs into a map \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// `opts: never` (not the wider `unknown`) so every handler below \u2014 each typed\n// with its OWN specific opts shape (`getSystemInfoAsync`'s `{ success?, complete? }`,\n// `canIUse`'s `string`, \u2026) \u2014 remains assignable into this map: a function\n// parameter is checked contravariantly, and `never` is assignable into any\n// concrete opts type, whereas `unknown` (the caller-side \"any value\" type)\n// would reject every narrower handler signature here. Callers of this map\n// always cast to a caller-appropriate handler type before invoking (see\n// simulator-app.tsx / main-api-runner.ts) \u2014 this declaration only has to\n// typecheck the object literal itself.\nexport const simulatorApis: Record<string, (this: MiniAppContext, opts: never) => unknown> = {\n\t// Base\n\tcanIUse,\n\tgetSystemInfo,\n\tgetSystemInfoAsync,\n\tgetSystemInfoSync,\n\tgetWindowInfo,\n\tgetSystemSetting,\n\t// UI: interaction\n\tshowToast,\n\thideToast,\n\tshowLoading,\n\thideLoading,\n\tshowModal,\n\tshowActionSheet,\n\t// Network\n\tdownloadFile,\n\tuploadFile,\n\tuploadFileAbort,\n\t// Storage (sync)\n\tsetStorageSync,\n\tgetStorageSync,\n\tremoveStorageSync,\n\tclearStorageSync,\n\tgetStorageInfoSync,\n\t// Storage (async)\n\tsetStorage,\n\tgetStorage,\n\tremoveStorage,\n\tclearStorage,\n\tgetStorageInfo,\n\t// Open API\n\tgetAccountInfoSync,\n\t// Device\n\thideKeyboard,\n\tadjustPosition,\n\tmakePhoneCall,\n\tchooseContact,\n\taddPhoneContact,\n\tvibrateShort,\n\tvibrateLong,\n\tscanCode,\n\tgetClipboardData,\n\tsetClipboardData,\n\tgetNetworkType,\n\t// Media: Image\n\tchooseImage,\n\tpreviewImage,\n\tcompressImage,\n\tsaveImageToPhotosAlbum,\n\tgetImageInfo,\n\t// Media: Video\n\tchooseMedia,\n\tchooseVideo,\n\t// Media: Audio (service-apis/audio)\n\taudioCreate,\n\taudioListen,\n\taudioSetProp,\n\taudioPlay,\n\taudioPause,\n\taudioStop,\n\taudioSeek,\n\taudioDestroy,\n\t// Filesystem (service-apis/file)\n\tfsAccess,\n\tfsStat,\n\tfsReadFile,\n\tfsWriteFile,\n\tfsAppendFile,\n\tfsCopyFile,\n\tfsRename,\n\tfsUnlink,\n\tfsMkdir,\n\tfsRmdir,\n\tfsReaddir,\n\tfsGetFileInfo,\n\tfsSaveFile,\n\tfsGetSavedFileList,\n\tfsRemoveSavedFile,\n\tfsTruncate,\n\tfsUnzip,\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["
|
|
3
|
+
"sources": ["../../../src/preload/windows/main.ts", "../../../../dimina-electron-runtime/src/shared/bridge-channels.ts", "../../../src/preload/runtime/main-api-runner.ts", "../../../src/simulator/simulator-api-helpers.ts", "../../../src/simulator/simulator-api-storage.ts", "../../../src/simulator/simulator-api-device.ts", "../../../src/simulator/event-bridge.ts", "../../../../dimina-electron-runtime/src/shared/node-bindings.ts", "../../../../dimina-electron-runtime/src/shared/vpath.ts", "../../../src/simulator/temp-files.ts", "../../../src/simulator/simulator-api-fs.ts", "../../../src/simulator/simulator-api-media.ts", "../../../src/simulator/simulator-api-fsm.ts", "../../../../dimina-electron-runtime/src/shared/request-core.ts", "../../../src/simulator/simulator-api-network.ts", "../../../src/simulator/ui-overlay-bus.ts", "../../../src/simulator/simulator-api-ui.ts", "../../../src/simulator/simulator-api.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Preload bridge for the main window, settings window, settings overlay\n * view, and popover overlay view. Exposes a minimal, typed `window.devtools`\n * surface so the renderer never has to call `window.require('electron')`.\n *\n * This file is bundled by esbuild to CJS at `dist/preload/windows/main.js`\n * (see package.json `build:preload`). It must remain a leaf module \u2014 do\n * NOT import other preload files via `.js` ESM specifiers; everything goes\n * through the Electron `contextBridge` / `ipcRenderer` runtime.\n *\n * Channel governance lives in the main process: `sender-policy.ts` plus the\n * per-handler zod schemas decide what's accepted. The preload layer is a\n * thin pass-through \u2014 a renderer inventing channel names will just hit a\n * main-side rejection, so duplicating an allowlist here added no real\n * defense for a devtool that loads user-trusted mini-programs.\n */\nimport { contextBridge, ipcRenderer, type IpcRendererEvent } from 'electron'\nimport { BRIDGE_CHANNELS as C, SIMULATOR_EVENTS as E } from '../../shared/bridge-channels.js'\nimport type {\n ApiCallPayload,\n ApiResponsePayload,\n} from '../../shared/bridge-channels.js'\nimport { runApiAsync } from '../runtime/main-api-runner.js'\nimport { simulatorApis } from '../../simulator/simulator-api.js'\n\nconst api = {\n ipc: {\n invoke: (channel: string, ...args: unknown[]) => ipcRenderer.invoke(channel, ...args),\n // Synchronous round-trip. Blocks the renderer until the main process sets\n // `event.returnValue` \u2014 used only for the editor's beforeunload flush, where\n // the write MUST land before the page is torn down (an async invoke can't).\n sendSync: (channel: string, ...args: unknown[]) => ipcRenderer.sendSync(channel, ...args),\n send: (channel: string, ...args: unknown[]) => {\n ipcRenderer.send(channel, ...args)\n },\n on: (\n channel: string,\n listener: (event: IpcRendererEvent, ...args: unknown[]) => void,\n ) => {\n ipcRenderer.on(channel, listener)\n return () => ipcRenderer.removeListener(channel, listener)\n },\n once: (\n channel: string,\n listener: (event: IpcRendererEvent, ...args: unknown[]) => void,\n ) => {\n ipcRenderer.once(channel, listener)\n },\n removeListener: (\n channel: string,\n listener: (...args: unknown[]) => void,\n ) => {\n ipcRenderer.removeListener(channel, listener)\n },\n },\n}\n\n// All host windows that load this preload run with `contextIsolation: true`\n// (main / settings / view-manager), so `contextBridge` is the path that\n// reaches the renderer's `window`. The simulator <webview> uses a separate\n// preload (`simulator.ts`).\ncontextBridge.exposeInMainWorld('devtools', api)\n\n// Native-host fallback: bridge-router forwards any invokeAPI name not\n// registered in `ctx.simulatorApis` to the simulator's webContents via\n// E.API_CALL. When the *main* window doubles as the simulator (the default\n// path for e2e callers that drive `dmb:spawn` without an explicit\n// simulatorWcId), the listener must live here in the main-window preload\n// because the renderer side has no DeviceShell mounted to install one.\nipcRenderer.on(E.API_CALL, (_event, payload: ApiCallPayload) => {\n void runApiAsync(\n simulatorApis as Record<string, (this: unknown, params?: unknown) => unknown | Promise<unknown>>,\n payload.name,\n payload.params,\n ).then((verdict) => {\n const ack: ApiResponsePayload = {\n appSessionId: payload.appSessionId,\n requestId: payload.requestId,\n ok: verdict.ok,\n result: verdict.result,\n errMsg: verdict.errMsg,\n }\n ipcRenderer.send(C.API_RESPONSE, ack)\n })\n})\n\n// Test-only hatch: e2e helpers emit synthetic IPC events on the renderer's\n// ipcRenderer instance to trigger handlers registered via `devtools.ipc.on`\n// without round-tripping through the main process. Gated on NODE_ENV so\n// production builds never expose it.\nif (process.env.NODE_ENV === 'test') {\n contextBridge.exposeInMainWorld('__testIpc', {\n emit: (channel: string, ...args: unknown[]) => {\n ;(ipcRenderer as unknown as { emit: (c: string, ...a: unknown[]) => void }).emit(channel, ...args)\n },\n })\n}\n\nexport type DevtoolsApi = typeof api\n", "import type { NativeDeviceInfo } from './runtime-types.js'\n\nexport const BRIDGE_CHANNELS = {\n SPAWN: 'dmb:spawn',\n DISPOSE: 'dmb:dispose',\n PAGE_OPEN: 'dmb:page:open',\n PAGE_CLOSE: 'dmb:page:close',\n PAGE_LIFECYCLE: 'dmb:page:lifecycle',\n NAV_CALLBACK: 'dmb:nav:callback',\n SERVICE_INVOKE: 'dmb:service:invoke',\n SERVICE_PUBLISH: 'dmb:service:publish',\n RENDER_INVOKE: 'dmb:render:invoke',\n RENDER_PUBLISH: 'dmb:render:publish',\n TO_SERVICE: 'dmb:to-service',\n TO_RENDER: 'dmb:to-render',\n SIMULATOR_API: 'dmb:simulator-api',\n /** simulator \u2192 main: ack of an API_CALL request (carries success/fail args). */\n API_RESPONSE: 'dmb:api:response',\n /**\n * simulator webview preload \u2192 main (sendSync): \"is native-host mode on?\".\n * The guest preload can't read the launch `process.env`, so it asks main\n * (which can) at install time. Reply is `e.returnValue = boolean`.\n */\n NATIVE_HOST_ENABLED: 'dmb:native-host-enabled',\n /**\n * simulator (DeviceShell) \u2192 main: the visible top-of-stack page bridgeId.\n * Main has no z-order concept \u2014 the active page lives only in DeviceShell's\n * ShellState \u2014 so devtools panels / automation that must target \"the current\n * page's render webContents\" resolve it through this signal. Fire-and-forget.\n */\n ACTIVE_PAGE: 'dmb:active-page',\n /**\n * simulator (DeviceShell) \u2192 main: the FULL ordered page stack (bottom\u2192top)\n * whenever it changes. Main has no stack of its own (it only learns the\n * active bridgeId via ACTIVE_PAGE), so automation's `App.getPageStack` needs\n * this to report multi-page stacks. Fire-and-forget.\n */\n PAGE_STACK: 'dmb:page-stack',\n} as const\n\nexport const SIMULATOR_EVENTS = {\n DOM_READY: 'simulator:dom-ready',\n NAV_BAR: 'simulator:navigation-bar',\n NAV_ACTION: 'simulator:nav-action',\n TAB_ACTION: 'simulator:tab-action',\n /** main \u2192 simulator: invoke a wx.* API on the simulator-resident MiniApp. */\n API_CALL: 'simulator:api-call',\n /**\n * main \u2192 simulator: the renderer toolbar picked a different device. Carries a\n * NativeDeviceInfo; DeviceShell resizes the bezel + re-renders status bar /\n * notch. The race-free INITIAL device rides NativeHostConfig.device (read\n * synchronously at preload bridge-install); this event covers live changes.\n */\n DEVICE_CHANGE: 'simulator:device-change',\n /**\n * main \u2192 simulator: a watcher rebuild finished; boot a NEW app session for\n * the carried url ({@link RelaunchPayload}) IN PLACE, keeping the live\n * DeviceShell painted, and swap once the new session's root page reports\n * DOM_READY (ready-then-swap soft reload). Main sends this only when the\n * shell is live+ready; otherwise the renderer falls back to the hard\n * attachNativeSimulator rebuild.\n */\n RELAUNCH: 'simulator:relaunch',\n} as const\n\n/** Native simulator preload \u2194 owning Electron main-process custom API bridge. */\nexport const SimulatorCustomApiBridgeChannel = {\n Request: 'simulator:custom-apis:bridge-request',\n Response: 'simulator:custom-apis:bridge-response',\n} as const\n\n/**\n * `simulator:relaunch` payload. `url` is a full simulator URL (same format as\n * the simulator page's own location / AttachNative), carrying the appId and\n * the page route the new session must boot at.\n */\nexport interface RelaunchPayload {\n url: string\n}\n\nexport const CHANNELS = BRIDGE_CHANNELS\n\n/**\n * Reply to a `NATIVE_HOST_ENABLED` sendSync. Main supplies render-host asset\n * URLs (preload still needs a `file://` path for the guest preload script).\n * The pageFrame document itself is built per-bridge as `dmb-resource://\u2026`\n * via `buildRenderHostDocumentUrl` \u2014 `renderHostHtmlUrl` is only a legacy\n * placeholder kept for the config shape.\n */\nexport interface NativeHostConfig {\n enabled: boolean\n renderHostHtmlUrl: string\n renderPreloadUrl: string\n /**\n * The currently-selected device, if the renderer already pushed it before the\n * simulator WCV's preload installed (it does \u2014 SetDeviceInfo precedes\n * AttachNative). DeviceShell reads this as its initial device so it never\n * mounts with the wrong bezel size while waiting for the first DEVICE_CHANGE.\n * Absent only on the pre-spawn default path.\n */\n device?: NativeDeviceInfo\n}\n\nexport type BridgeChannel = typeof BRIDGE_CHANNELS[keyof typeof BRIDGE_CHANNELS]\n\nexport type BridgeTarget = 'service' | 'render' | 'container'\n\nexport type BridgeMessageType =\n | 'loadResource'\n | 'serviceResourceLoaded'\n | 'renderResourceLoaded'\n | 'resourceLoaded'\n | 'firstRender'\n | 'appShow'\n | 'appHide'\n | 'stackShow'\n | 'stackHide'\n | 'pageShow'\n | 'pageHide'\n | 'pageReady'\n | 'pageUnload'\n | 'pageScroll'\n | 'pageResize'\n | 'pageRouteDone'\n | 'mC'\n | 'mR'\n | 'mU'\n | 't'\n | 'u'\n | 'ub'\n | 'triggerCallback'\n | 'invokeAPI'\n | 'h5SdkAction'\n | 'componentError'\n | 'domReady'\n | 'print'\n | 'renderHostReady'\n | 'serviceHostError'\n | string\n\nexport interface MessageEnvelope<TBody extends Record<string, unknown> = Record<string, unknown>> {\n type: BridgeMessageType\n target: BridgeTarget\n body: TBody\n}\n\nexport interface HostEnvSnapshot {\n brand: string\n model: string\n platform: string\n system: string\n version: string\n SDKVersion: string\n pixelRatio: number\n screenWidth: number\n screenHeight: number\n windowWidth: number\n windowHeight: number\n statusBarHeight: number\n language: string\n theme: string\n [key: string]: unknown\n}\n\n/**\n * Map the renderer's logical device metrics onto the subset of a\n * HostEnvSnapshot the service-host window's `getSystemInfoSync` consumes.\n * `windowHeight` excludes the status bar (the page area); `windowWidth` has no\n * horizontal chrome. Zoom is intentionally absent \u2014 it is a display scale, not\n * a logical-size change.\n *\n * Single source of truth for the device\u2192host-env mapping, shared by the live\n * `SetDeviceInfo` IPC path (main/ipc/simulator.ts) and the per-spawn host-env\n * seeding (main/ipc/bridge-router.ts). Keeping them identical guarantees a\n * service-host RESPAWN after a device change reports the same dims the live\n * update pushed \u2014 otherwise a respawn would silently revert to the boot device.\n */\nexport function deviceInfoToHostEnv(d: NativeDeviceInfo): Partial<HostEnvSnapshot> {\n return {\n brand: d.brand,\n model: d.model,\n system: d.system,\n platform: d.platform,\n pixelRatio: d.pixelRatio,\n screenWidth: d.screenWidth,\n screenHeight: d.screenHeight,\n windowWidth: d.screenWidth,\n windowHeight: Math.max(0, d.screenHeight - d.statusBarHeight),\n statusBarHeight: d.statusBarHeight,\n }\n}\n\n/**\n * Subset of WeChat page `window` config plus tabBar list, parsed from\n * `app-config.json` (`{app:{window,tabBar,pages,entryPagePath}, modules:{[pagePath]:{...flat page.json fields,root?}}}`).\n * `modules[pagePath]` is FLAT \u2014 the compiler assigns the page's own `.json` file\n * content as-is (see `dimina/fe/packages/compiler/src/env.js` `collectionPageJson()`),\n * not wrapped under a `.window` key. Mirrors mergePageConfig in dimina-fe:\n * page-level keys override app-level.\n */\nexport interface PageWindowConfig {\n navigationBarTitleText?: string\n navigationBarBackgroundColor?: string\n navigationBarTextStyle?: 'black' | 'white'\n navigationStyle?: 'default' | 'custom'\n homeButton?: boolean\n backgroundColor?: string\n backgroundTextStyle?: 'dark' | 'light'\n enablePullDownRefresh?: boolean\n disableScroll?: boolean\n [key: string]: unknown\n}\n\nexport interface TabBarItem {\n pagePath: string\n text?: string\n iconPath?: string\n selectedIconPath?: string\n}\n\nexport interface TabBarConfig {\n color?: string\n selectedColor?: string\n backgroundColor?: string\n borderStyle?: 'black' | 'white'\n position?: 'bottom' | 'top'\n custom?: boolean\n list: TabBarItem[]\n}\n\nexport interface AppManifest {\n entryPagePath: string\n pages: string[]\n tabBar?: TabBarConfig\n /**\n * Provenance of this manifest: `'app-config'` when built from a real\n * compiled `app-config.json` (its `pages` list is authoritative, so mount\n * gates can validate membership against it); `'fallback'` when\n * app-config.json was unreachable and the manifest is a single-page stand-in\n * built from the spawn request. Mount gates only enforce against\n * `'app-config'` \u2014 a `'fallback'` manifest has no compiled truth to check\n * membership against, so it must let every page/nav target through.\n */\n source: 'app-config' | 'fallback'\n}\n\nexport interface SpawnRequest {\n simulatorWcId?: number\n appId: string\n bridgeId?: string\n pagePath?: string\n scene?: number\n query?: Record<string, unknown>\n apiNamespaces?: string[]\n hostEnvSnapshot?: Partial<HostEnvSnapshot>\n pkgRoot?: string\n root?: string\n /**\n * Base URL of the dev server that serves the compiled mini-app, i.e. the\n * SAME origin the simulator page was loaded from (`http://localhost:<port>/`).\n * The dev server statically serves `<appId>/<root>/\u2026` (app-config.json,\n * logic.js, page bundles, styles) \u2014 exactly what the default dimina-fe\n * `<webview>` fetches. The native-host render + service hosts source every\n * resource from here, so we don't need a second resource server or a local\n * compiled-output path. Trailing slash expected.\n */\n resourceBaseUrl?: string\n}\n\nexport interface SpawnResult {\n appSessionId: string\n bridgeId: string\n /** The pagePath originally requested (unchanged even when a fallback applied \u2014 see `resolvedPagePath`). */\n pagePath: string\n /**\n * The pagePath the root PageSession was ACTUALLY spawned with. Equal to\n * `pagePath` unless `pageFallbackApplied` is true, in which case the request\n * was absent from `manifest.pages` and this is `manifest.entryPagePath`\n * (or `manifest.pages[0]` when even that isn't a member). Callers that cache\n * \"the current page\" (e.g. `SimulatorMiniApp`) must reconcile against this,\n * not the original request.\n */\n resolvedPagePath: string\n /** Whether `resolvedPagePath` differs from the request because it was absent from the compiled manifest. Always false for a `'fallback'` manifest (nothing to validate against). */\n pageFallbackApplied: boolean\n serviceWcId: number\n resourceBaseUrl: string\n /** The page's resource root inside the mini-app package (e.g. `'main'`). Threaded to `createRenderHostUrl` so the render-host document URL can encode it \u2014 see `dmb-resource-url.ts`. */\n root: string\n manifest: AppManifest\n rootWindowConfig: PageWindowConfig\n}\n\nexport interface PageOpenRequest {\n appSessionId: string\n pagePath: string\n query?: Record<string, unknown>\n bridgeId?: string\n}\n\nexport interface PageOpenResult {\n bridgeId: string\n pagePath: string\n windowConfig: PageWindowConfig\n isTab: boolean\n}\n\nexport interface PageClosePayload {\n bridgeId: string\n}\n\nexport interface DisposePayload {\n /** AppSession root bridgeId (legacy) or any page bridgeId. */\n bridgeId: string\n}\n\nexport type PageLifecycleEvent =\n | 'pageShow'\n | 'pageHide'\n | 'pageUnload'\n | 'stackShow'\n | 'stackHide'\n | 'appShow'\n | 'appHide'\n\nexport interface PageLifecyclePayload {\n appSessionId: string\n bridgeId: string\n event: PageLifecycleEvent\n}\n\n/**\n * Sent by simulator after a routing action (navigateTo etc.) completes so the\n * main process can call sendCallback() against the original service-issued\n * success/fail/complete ids.\n */\nexport interface NavCallbackPayload {\n appSessionId: string\n ok: boolean\n errMsg: string\n callbacks: { success?: unknown; fail?: unknown; complete?: unknown }\n}\n\nexport interface ServiceInvokePayload {\n bridgeId: string\n msg: MessageEnvelope\n}\n\nexport interface ServicePublishPayload {\n bridgeId: string\n targetBridgeId?: string\n msg: MessageEnvelope\n}\n\n/**\n * `dmb:active-page` \u2014 simulator (DeviceShell) \u2192 main. Records which page is the\n * visible top-of-stack so main-side services (WXML/element-inspect, automation)\n * can resolve \"the active page's render webContents\" by bridgeId.\n */\nexport interface ActivePagePayload {\n appSessionId: string\n bridgeId: string\n}\n\n/**\n * `dmb:page-stack` \u2014 simulator (DeviceShell) \u2192 main. The full ordered page\n * stack (bottom\u2192top) so `App.getPageStack` can report multi-page stacks.\n */\nexport interface PageStackEntry {\n pagePath: string\n query: Record<string, unknown>\n}\n\nexport interface PageStackPayload {\n appSessionId: string\n stack: PageStackEntry[]\n}\n\nexport interface RenderInvokePayload {\n bridgeId: string\n msg: MessageEnvelope\n}\n\nexport interface RenderPublishPayload {\n bridgeId: string\n msg: MessageEnvelope\n}\n\nexport interface ToServicePayload {\n msg: MessageEnvelope\n}\n\nexport interface ToRenderPayload {\n msg: MessageEnvelope\n}\n\nexport interface SimulatorApiInvokePayload {\n bridgeId: string\n name: string\n params: unknown\n}\n\n/**\n * `simulator:nav-action` \u2014 main \u2192 simulator window, carries router/tabBar\n * intentions. Simulator owns the visual stack state and decides whether to\n * push/pop webviews; it then calls back PAGE_LIFECYCLE + NAV_CALLBACK.\n */\nexport interface NavActionPayload {\n appSessionId: string\n bridgeId: string\n name: 'navigateTo' | 'navigateBack' | 'redirectTo' | 'reLaunch' | 'switchTab'\n params: Record<string, unknown>\n callbacks: { success?: unknown; fail?: unknown; complete?: unknown }\n}\n\n/**\n * `simulator:api-call` \u2014 main \u2192 simulator. Fallback path used when an\n * invokeAPI name is not registered in the main-process `ctx.simulatorApis`\n * registry: the simulator-resident MiniApp owns the wx.* handler (it can\n * read DOM, open file pickers, etc.), so we forward the call there and wait\n * for an `API_RESPONSE` ack.\n */\nexport interface ApiCallPayload {\n appSessionId: string\n bridgeId: string\n requestId: string\n name: string\n params: Record<string, unknown>\n callbacks: { success?: unknown; fail?: unknown; complete?: unknown }\n}\n\n/**\n * `dmb:api:response` \u2014 simulator \u2192 main. Ack for an `API_CALL`. Main looks\n * up `requestId` in its pending map and fires the original service-side\n * success/fail/complete callbacks accordingly.\n */\nexport interface ApiResponsePayload {\n appSessionId: string\n requestId: string\n ok: boolean\n /** Argument the simulator-side success/fail callback was invoked with. */\n result?: unknown\n errMsg?: string\n /**\n * Persistent-subscription marker (`keep: true` APIs, e.g.\n * `audioListen`). When set, this response is one of potentially many\n * fires of the same subscription: main re-fires the service-side success\n * callback but keeps the pendingApiCall alive (does not delete it or fire\n * `complete`) so subsequent fires of the same `requestId` are delivered.\n * Cleanup happens on page/app teardown instead.\n */\n keep?: boolean\n /**\n * Handler-received acknowledgement. The simulator sends this as soon as it\n * has located a live handler for the forwarded call \u2014 before the handler\n * produces its verdict. Main disarms the no-handler watchdog but keeps the\n * pending call alive: a slow operation (large disk write, a modal waiting\n * on the user) must not be reported failed while the underlying work still\n * completes. No service-side callback fires for an ack.\n */\n ack?: boolean\n}\n\n/**\n * `simulator:tab-action` \u2014 main \u2192 simulator window, carries dynamic TabBar\n * API calls. Simulator updates TabBar React state and acknowledges via\n * NAV_CALLBACK so the service-side wx.* callback fires.\n */\nexport interface TabActionPayload {\n appSessionId: string\n bridgeId: string\n name:\n | 'setTabBarStyle'\n | 'setTabBarItem'\n | 'showTabBar'\n | 'hideTabBar'\n | 'setTabBarBadge'\n | 'removeTabBarBadge'\n | 'showTabBarRedDot'\n | 'hideTabBarRedDot'\n params: Record<string, unknown>\n callbacks: { success?: unknown; fail?: unknown; complete?: unknown }\n}\n", "/**\n * Native-host API_CALL handler installed inside the main-window preload.\n *\n * Goal: let the main devtools window double as a simulator when the\n * bridge-router forwards `simulator:api-call` to its webContents (the\n * default path in e2e tests, where `dmb:spawn` is invoked from mainWindow\n * directly with no explicit `simulatorWcId`).\n *\n * Unlike `simulator/main.tsx` (which boots a full DeviceShell + SimulatorMiniApp),\n * this runner is renderer-agnostic: it just owns a name\u2192handler table plus\n * a sentinel-based callback capture identical in shape to the simulator's\n * `runApiAsync`. The MiniAppContext stub it constructs is the smallest one\n * the built-in handlers expect (`appId`, `createCallbackFunction`, parent\n * with `el.querySelector` returning the simulated viewport rect).\n */\nimport type { MiniAppContext } from '../../simulator/types.js'\n\n// No `this` parameter: handlers are always invoked through `.call(ctx, \u2026)`\n// below with an explicit context object, so the declared type never needs to\n// constrain (or widen away) the caller's `this`.\ntype LooseApiHandler = (params?: unknown) => unknown | Promise<unknown>\n\nexport interface ApiRunVerdict {\n ok: boolean\n result?: unknown\n errMsg?: string\n}\n\ninterface ApiRunnerContext extends MiniAppContext {\n /** Dummy properties some upstream handlers introspect. */\n appId: string\n}\n\nfunction makeBaseContext(): ApiRunnerContext {\n // Minimal viewport rect: enough for handlers that read\n // `parent.el.querySelector('.dimina-native-webview__root').getBoundingClientRect()`\n // (see simulator-api.ts readWindowMetrics).\n const fakeRect = { width: 390, height: 844, x: 0, y: 0, top: 0, left: 0, right: 390, bottom: 844 }\n const fakeRoot = {\n getBoundingClientRect: () => fakeRect,\n } as unknown as Element\n return {\n appId: '',\n createCallbackFunction: () => undefined,\n parent: {\n el: {\n querySelector: () => fakeRoot,\n } as unknown as Element,\n getStatusBarRect: () => ({ height: 0 }),\n },\n }\n}\n\nexport function runApiAsync(\n handlers: Record<string, LooseApiHandler | undefined>,\n name: string,\n params: unknown,\n): Promise<ApiRunVerdict> {\n const handler = handlers[name]\n if (!handler) {\n return Promise.resolve({ ok: false, errMsg: `${name}:fail no handler` })\n }\n\n return new Promise<ApiRunVerdict>((resolve) => {\n let resolved = false\n const finish = (verdict: ApiRunVerdict): void => {\n if (resolved) return\n resolved = true\n resolve(verdict)\n }\n\n const SUCCESS = Symbol('main-cb-success')\n const FAIL = Symbol('main-cb-fail')\n const COMPLETE = Symbol('main-cb-complete')\n\n const base = makeBaseContext()\n const ctx: ApiRunnerContext = {\n ...base,\n createCallbackFunction(id: unknown) {\n if (id === undefined || id === null) return undefined\n return (...args: unknown[]) => {\n const arg = args[0]\n if (id === SUCCESS) {\n finish({ ok: true, result: arg })\n } else if (id === FAIL) {\n const errMsg =\n arg && typeof arg === 'object' && 'errMsg' in (arg as Record<string, unknown>)\n ? String((arg as { errMsg?: unknown }).errMsg)\n : `${name}:fail`\n finish({ ok: false, errMsg, result: arg })\n }\n }\n },\n }\n\n const userParams =\n params && typeof params === 'object' && !Array.isArray(params)\n ? { ...(params as Record<string, unknown>) }\n : {}\n const hadSuccess = userParams.success !== undefined && userParams.success !== null\n const hadFail = userParams.fail !== undefined && userParams.fail !== null\n const hadComplete = userParams.complete !== undefined && userParams.complete !== null\n\n userParams.success = SUCCESS\n userParams.fail = FAIL\n if (hadComplete) userParams.complete = COMPLETE\n\n try {\n const ret = (handler as LooseApiHandler).call(ctx, userParams)\n if (ret && typeof (ret as PromiseLike<unknown>).then === 'function') {\n Promise.resolve(ret as PromiseLike<unknown>).then(\n (r) => finish({ ok: true, result: r }),\n (err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err)\n finish({ ok: false, errMsg: `${name}:fail ${msg}` })\n },\n )\n return\n }\n if (!hadSuccess && !hadFail) {\n finish({ ok: true, result: ret })\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err)\n finish({ ok: false, errMsg: `${name}:fail ${msg}` })\n }\n })\n}\n", "import type { MiniAppContext } from './types'\n\n/**\n * Resolve the success / fail / complete callbacks of a wx.* API options\n * object in one step. Each runs through ctx.createCallbackFunction so it is\n * invoked with the proper this-binding; a missing option yields undefined.\n */\nexport function bindCallbacks(\n ctx: MiniAppContext,\n opts: { success?: unknown; fail?: unknown; complete?: unknown },\n) {\n return {\n onSuccess: ctx.createCallbackFunction(opts.success),\n onFail: ctx.createCallbackFunction(opts.fail),\n onComplete: ctx.createCallbackFunction(opts.complete),\n }\n}\n\n/**\n * Build a wx.* API stub for a capability the simulator cannot provide. The\n * returned function reports `${apiName}:fail not supported in simulator`\n * through the fail callback, then runs complete.\n */\nexport function notSupportedApi(\n apiName: string,\n): (this: MiniAppContext, opts?: { fail?: unknown; complete?: unknown }) => void {\n return function (this: MiniAppContext, opts: { fail?: unknown; complete?: unknown } = {}) {\n const { onFail, onComplete } = bindCallbacks(this, opts)\n onFail?.({ errMsg: `${apiName}:fail not supported in simulator` })\n onComplete?.()\n }\n}\n", "/**\n * DevTools API stubs for wx.xxx storage APIs (sync + async).\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi \u2192 MiniApp.invokeApi).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks } from './simulator-api-helpers'\n\n// \u2500\u2500\u2500 shared storage primitives \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Every sync/async pair below (set/get/remove/clear/info) shares the same\n// underlying localStorage layout: keys are namespaced per appId, values are\n// JSON-encoded objects / stringified primitives. These helpers are the\n// single authority for that layout so the sync and async variants cannot\n// drift apart.\n\nfunction storageKeyOf(appId: string, key: string): string {\n\treturn `${appId}_${key}`\n}\n\n/** Full (still-prefixed) localStorage keys belonging to `appId`. */\nfunction collectAppKeys(appId: string): string[] {\n\tconst prefix = `${appId}_`\n\tconst keys: string[] = []\n\tfor (let i = 0; i < localStorage.length; i++) {\n\t\tconst k = localStorage.key(i)\n\t\tif (k && k.startsWith(prefix)) keys.push(k)\n\t}\n\treturn keys\n}\n\nfunction writeEntry(appId: string, key: string, data: unknown): void {\n\tconst dataString = typeof data === 'object' ? JSON.stringify(data) : String(data)\n\tlocalStorage.setItem(storageKeyOf(appId, key), dataString)\n}\n\n/** Reads one entry, JSON-parsing when possible. `undefined` means the key was never set \u2014 distinct from a stored empty string. */\nfunction readEntry(appId: string, key: string): { data: unknown } | undefined {\n\tconst raw = localStorage.getItem(storageKeyOf(appId, key))\n\tif (raw === null) return undefined\n\ttry { return { data: JSON.parse(raw) as unknown } } catch { return { data: raw } }\n}\n\nfunction clearAppKeys(appId: string): void {\n\tcollectAppKeys(appId).forEach(k => localStorage.removeItem(k))\n}\n\nfunction storageInfoOf(appId: string): { keys: string[]; currentSize: number; limitSize: number } {\n\tconst prefix = `${appId}_`\n\tconst keys: string[] = []\n\tlet currentSize = 0\n\tfor (const fullKey of collectAppKeys(appId)) {\n\t\tkeys.push(fullKey.slice(prefix.length))\n\t\tconst item = localStorage.getItem(fullKey)\n\t\tcurrentSize += item ? item.length * 2 : 0\n\t}\n\treturn { keys, currentSize, limitSize: 10 * 1024 * 1024 }\n}\n\n// \u2500\u2500\u2500 Storage (sync) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function setStorageSync(this: MiniAppContext, { key, data }: { key: string; data: unknown }) {\n\twriteEntry(this.appId, key, data)\n}\n\nexport function getStorageSync(this: MiniAppContext, { key }: { key: string }) {\n\t// wx \u771F\u673A: a missing key returns {data: ''}, never undefined or a fail.\n\treturn readEntry(this.appId, key) ?? { data: '' }\n}\n\nexport function removeStorageSync(this: MiniAppContext, { key }: { key: string }) {\n\tlocalStorage.removeItem(storageKeyOf(this.appId, key))\n}\n\nexport function clearStorageSync(this: MiniAppContext) {\n\tclearAppKeys(this.appId)\n}\n\nexport function getStorageInfoSync(this: MiniAppContext) {\n\treturn storageInfoOf(this.appId)\n}\n\n// \u2500\u2500\u2500 Storage (async) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function setStorage(\n\tthis: MiniAppContext,\n\t{ key, data, success, fail, complete }: { key: string; data: unknown; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\ttry {\n\t\twriteEntry(this.appId, key, data)\n\t\tonSuccess?.({ errMsg: 'setStorage:ok' })\n\t} catch (e) {\n\t\tonFail?.({ errMsg: `setStorage:fail ${(e as Error).message}` })\n\t}\n\tonComplete?.()\n}\n\nexport function getStorage(\n\tthis: MiniAppContext,\n\t{ key, success, fail, complete }: { key: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\t// Unlike getStorageSync, the async variant fails (not {data: ''}) on a\n\t// missing key \u2014 this is the documented wx.getStorage contract.\n\tconst entry = readEntry(this.appId, key)\n\tif (!entry) {\n\t\tonFail?.({ errMsg: 'getStorage:fail data not found' })\n\t} else {\n\t\tonSuccess?.({ data: entry.data, errMsg: 'getStorage:ok' })\n\t}\n\tonComplete?.()\n}\n\nexport function removeStorage(\n\tthis: MiniAppContext,\n\t{ key, success, fail, complete }: { key: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\ttry {\n\t\tlocalStorage.removeItem(storageKeyOf(this.appId, key))\n\t\tonSuccess?.({ errMsg: 'removeStorage:ok' })\n\t} catch (e) {\n\t\tonFail?.({ errMsg: `removeStorage:fail ${(e as Error).message}` })\n\t}\n\tonComplete?.()\n}\n\nexport function clearStorage(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tclearAppKeys(this.appId)\n\tonSuccess?.({ errMsg: 'clearStorage:ok' })\n\tonComplete?.()\n}\n\nexport function getStorageInfo(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tconst info = storageInfoOf(this.appId)\n\tonSuccess?.({ ...info, errMsg: 'getStorageInfo:ok' })\n\tonComplete?.()\n}\n", "/**\n * DevTools API stubs for device-related wx.xxx APIs\n * (keyboard / phone / contact / vibrate / scan).\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi \u2192 MiniApp.invokeApi).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks, notSupportedApi } from './simulator-api-helpers'\n\n// \u2500\u2500\u2500 Device: Keyboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function hideKeyboard(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\t// In web, blur the active element to dismiss virtual keyboard\n\tif (document.activeElement && typeof (document.activeElement as HTMLElement).blur === 'function') {\n\t\t;(document.activeElement as HTMLElement).blur()\n\t}\n\tonSuccess?.({ errMsg: 'hideKeyboard:ok' })\n\tonComplete?.()\n}\n\nexport function adjustPosition(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tonSuccess?.({ errMsg: 'adjustPosition:ok' })\n\tonComplete?.()\n}\n\n// \u2500\u2500\u2500 Device: Phone \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function makePhoneCall(\n\tthis: MiniAppContext,\n\t{ phoneNumber, success, fail, complete }: { phoneNumber: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\n\ttry {\n\t\twindow.open(`tel:${phoneNumber}`)\n\t\tonSuccess?.({ errMsg: 'makePhoneCall:ok' })\n\t} catch (error) {\n\t\tonFail?.({ errMsg: `makePhoneCall:fail ${(error as Error).message}` })\n\t}\n\tonComplete?.()\n}\n\n// \u2500\u2500\u2500 Device: Contact (stub) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const chooseContact = notSupportedApi('chooseContact')\n\nexport const addPhoneContact = notSupportedApi('addPhoneContact')\n\n// \u2500\u2500\u2500 Device: Vibrate (stub) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function vibrateShort(this: MiniAppContext, { success, complete }: { type?: string; success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\t// Navigator.vibrate is available in some browsers\n\tif (navigator.vibrate) navigator.vibrate(15)\n\tonSuccess?.({ errMsg: 'vibrateShort:ok' })\n\tonComplete?.()\n}\n\nexport function vibrateLong(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tif (navigator.vibrate) navigator.vibrate(400)\n\tonSuccess?.({ errMsg: 'vibrateLong:ok' })\n\tonComplete?.()\n}\n\n// \u2500\u2500\u2500 Device: Scan (stub) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const scanCode = notSupportedApi('scanCode')\n\n// \u2500\u2500\u2500 Device: Clipboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface ClipboardBridge {\n\treadText(): string\n\twriteText(text: string): void\n}\n\nfunction getClipboardBridge(): ClipboardBridge | undefined {\n\treturn (window as unknown as Record<string, unknown>).__diminaClipboard as ClipboardBridge | undefined\n}\n\nexport function getClipboardData(\n\tthis: MiniAppContext,\n\t{ success, fail, complete }: { success?: unknown; fail?: unknown; complete?: unknown } = {},\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\tconst bridge = getClipboardBridge()\n\tif (!bridge) {\n\t\tonFail?.({ errMsg: 'getClipboardData:fail clipboard bridge unavailable' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\ttry {\n\t\tconst data = bridge.readText()\n\t\tonSuccess?.({ data, errMsg: 'getClipboardData:ok' })\n\t} catch (error: unknown) {\n\t\tonFail?.({ errMsg: `getClipboardData:fail ${(error as Error)?.message ?? error}` })\n\t}\n\tonComplete?.()\n}\n\nexport function setClipboardData(\n\tthis: MiniAppContext,\n\t{ data, success, fail, complete }: { data?: string; success?: unknown; fail?: unknown; complete?: unknown } = {},\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\tif (typeof data !== 'string') {\n\t\tonFail?.({ errMsg: 'setClipboardData:fail data is required' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\tconst bridge = getClipboardBridge()\n\tif (!bridge) {\n\t\tonFail?.({ errMsg: 'setClipboardData:fail clipboard bridge unavailable' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\ttry {\n\t\tbridge.writeText(data)\n\t\tonSuccess?.({ errMsg: 'setClipboardData:ok' })\n\t} catch (error: unknown) {\n\t\tonFail?.({ errMsg: `setClipboardData:fail ${(error as Error)?.message ?? error}` })\n\t}\n\tonComplete?.()\n}\n\n// \u2500\u2500\u2500 Device: Network type \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type NetworkType = 'wifi' | '2g' | '3g' | '4g' | '5g' | 'none' | 'unknown'\n\ninterface NetworkInfo {\n\tonLine: boolean\n\t/** NetworkInformation.type (e.g. 'wifi' / 'ethernet' / 'cellular'). */\n\ttype?: string\n\t/** NetworkInformation.effectiveType (e.g. '4g' / '3g' / '2g' / 'slow-2g'). */\n\teffectiveType?: string\n}\n\nfunction mapEffectiveType(effectiveType?: string): NetworkType {\n\tswitch (effectiveType) {\n\t\tcase '4g':\n\t\t\treturn '4g'\n\t\tcase '3g':\n\t\t\treturn '3g'\n\t\tcase '2g':\n\t\tcase 'slow-2g':\n\t\t\treturn '2g'\n\t\tdefault:\n\t\t\treturn 'unknown'\n\t}\n}\n\n/**\n * Best-effort map from the browser's NetworkInformation to the WeChat\n * `getNetworkType` vocabulary. The host machine is almost always on wifi or\n * ethernet, so an online connection with no finer signal reports 'wifi'.\n */\nexport function resolveNetworkType(info: NetworkInfo): NetworkType {\n\tif (!info.onLine) return 'none'\n\tif (info.type === 'wifi' || info.type === 'ethernet') return 'wifi'\n\tif (info.type === 'cellular') return mapEffectiveType(info.effectiveType)\n\tif (info.effectiveType) return mapEffectiveType(info.effectiveType)\n\treturn 'wifi'\n}\n\nexport function getNetworkType(\n\tthis: MiniAppContext,\n\t{ success, complete }: { success?: unknown; complete?: unknown } = {},\n) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tconst connection = (navigator as Navigator & {\n\t\tconnection?: { type?: string; effectiveType?: string }\n\t}).connection\n\tconst networkType = resolveNetworkType({\n\t\tonLine: navigator.onLine,\n\t\ttype: connection?.type,\n\t\teffectiveType: connection?.effectiveType,\n\t})\n\tonSuccess?.({ networkType, errMsg: 'getNetworkType:ok' })\n\tonComplete?.()\n}\n", "/**\n * Generic DOM-event \u2192 service-callback bridge.\n *\n * Container-side media APIs (audio, and in future recorder / video) need to\n * forward DOM media events on an `HTMLMediaElement` out to the mini-program\n * service layer. This helper centralises the \"bind a set of DOM events, build\n * a typed payload, invoke `fire`, return a disposer\" pattern so each media API\n * does not re-implement it.\n */\n\n/**\n * Builds the payload handed to `fire` for a given mini-program event name.\n * Receives the mini-program event name (already mapped from the DOM name) and\n * the DOM event, and returns the object delivered to the service callback.\n */\nexport type PayloadBuilder<P> = (event: string, domEvent: Event) => P\n\n/** Disposer returned by {@link bindDomEvents}; unbinds every listener. */\nexport type EventBridgeDisposer = () => void\n\n/**\n * Bind a batch of DOM events on `target`.\n *\n * @param target The EventTarget (e.g. an `HTMLAudioElement`) to listen on.\n * @param eventMap Map of DOM event name \u2192 mini-program event name.\n * @param fire The service callback; called once per DOM event with the\n * payload produced by `buildPayload`.\n * @param buildPayload Produces the typed payload for `fire`.\n * @returns A disposer that removes every listener registered by this call.\n */\nexport function bindDomEvents<P>(\n\ttarget: EventTarget,\n\teventMap: Record<string, string>,\n\tfire: (payload: P) => void,\n\tbuildPayload: PayloadBuilder<P>,\n): EventBridgeDisposer {\n\tconst registered: Array<[string, EventListener]> = []\n\n\tfor (const [domName, miniName] of Object.entries(eventMap)) {\n\t\tconst listener: EventListener = (domEvent) => {\n\t\t\tfire(buildPayload(miniName, domEvent))\n\t\t}\n\t\ttarget.addEventListener(domName, listener)\n\t\tregistered.push([domName, listener])\n\t}\n\n\treturn () => {\n\t\tfor (const [domName, listener] of registered) {\n\t\t\ttarget.removeEventListener(domName, listener)\n\t\t}\n\t\tregistered.length = 0\n\t}\n}\n", "/**\n * Bridge for real Node built-ins in browser-bundled renderer documents.\n *\n * The simulator document runs with nodeIntegration OFF and its vite bundle\n * stubs `node:*` imports with truthy-but-empty objects, while its preload\n * (sandbox:false + contextIsolation:false \u2014 one shared JS world with the\n * page) has full Node access. The preload publishes the real modules on this\n * global; browser-side consumers (the vpath resolver, the FileSystemManager\n * backends) read them from here.\n *\n * Consumers MUST validate that the member they need is a function \u2014 never\n * trust truthiness, the vite stubs are truthy objects.\n */\n\nexport const NODE_BINDINGS_GLOBAL = '__diminaNodeBindings'\n\nexport interface DiminaNodeBindings {\n\tfs?: typeof import('node:fs')\n\tpath?: typeof import('node:path')\n\tos?: typeof import('node:os')\n\tcrypto?: typeof import('node:crypto')\n\tbuffer?: typeof import('node:buffer')\n}\n\nexport function getNodeBindings(): DiminaNodeBindings {\n\tconst bag = (globalThis as Record<string, unknown>)[NODE_BINDINGS_GLOBAL]\n\treturn (bag && typeof bag === 'object' ? bag : {}) as DiminaNodeBindings\n}\n", "/**\n * Runtime vpath resolver.\n *\n * Spec: `docs/file-system.md` \u2014 single resolver shared by every FSM\n * entry, the renderer-side temp store, and the main-process\n * protocol.handle / disk reader.\n *\n * resolveVPath(url): { kind, writable, realPath? } | null\n *\n * - `difile://_tmp/<id>` \u2192 kind=tmp, writable=false, no realPath\n * - `difile://_store/<id>` \u2192 kind=store, writable=false, realPath in base\n * - `difile://<rel>` \u2192 kind=usr, writable=true, realPath in base\n *\n * Security invariants (the resolver returns `null` instead of throwing):\n * - any non-`difile://` scheme is rejected outright;\n * - any `..` segment (raw or URL-encoded) is rejected before canonicalize;\n * - after `path.normalize` the resulting `realPath` MUST stay inside the\n * sandbox base; otherwise `null`;\n * - reserved prefixes `_tmp/` and `_store/` are case-sensitive \u2014 `_TMP/`,\n * `_Tmp/`, etc. fall through to the user-data namespace.\n */\n\n// Main-process (Node ESM) resolves these natively. The simulator document's\n// vite bundle stubs them with truthy-but-empty objects, and its renderer DOES\n// enter the `store`/`usr` branches (the FileSystemManager backends run\n// there) \u2014 so probe a required function on the static import and fall back to\n// the preload-published node bindings (see ./node-bindings.ts).\nimport osStatic from 'node:os'\nimport pathStatic from 'node:path'\nimport { getNodeBindings } from './node-bindings.js'\n\nconst os: typeof import('os') =\n\ttypeof osStatic?.homedir === 'function' ? osStatic : (getNodeBindings().os ?? osStatic)\nconst path: typeof import('path') =\n\ttypeof pathStatic?.join === 'function' ? pathStatic : (getNodeBindings().path ?? pathStatic)\n\nexport type VPathKind = 'tmp' | 'store' | 'usr'\n\nexport interface ResolvedVPath {\n\tkind: VPathKind\n\t/** `tmp` and `store` are runtime-owned and read-only; `usr` is writable. */\n\twritable: boolean\n\t/**\n\t * Canonical local path on disk for `store` / `usr` kinds (always within the\n\t * USER_DATA_PATH base directory after canonicalize). `tmp` kind has no\n\t * realPath \u2014 the bytes live in the renderer-side Blob Map.\n\t */\n\trealPath?: string\n}\n\nconst DIFILE_PREFIX = 'difile://'\n\n/**\n * USER_DATA_PATH sandbox base. Looked up dynamically on every call so test\n * doubles (e.g. monkey-patching `os.homedir`) and the `DIMINA_HOME` env\n * override apply per invocation. The env override exists for headless test\n * affordance and to keep the renderer/main store sharing one base.\n */\nexport function sandboxBase(): string {\n\tconst env = (typeof process !== 'undefined' && process.env && process.env.DIMINA_HOME) || ''\n\tif (env) {\n\t\treturn path.join(env, 'files')\n\t}\n\treturn path.join(os.homedir(), '.dimina', 'files')\n}\n\nexport function resolveVPath(url: unknown): ResolvedVPath | null {\n\tif (typeof url !== 'string') return null\n\tif (!url.startsWith(DIFILE_PREFIX)) return null\n\n\tconst raw = url.slice(DIFILE_PREFIX.length)\n\tif (raw.length === 0) return null\n\n\t// Decode URL-encoded sequences first so `%2e%2e` style escapes are caught\n\t// by the segment check below.\n\tlet decoded: string\n\ttry {\n\t\tdecoded = decodeURIComponent(raw)\n\t} catch {\n\t\treturn null\n\t}\n\n\t// Reject NUL bytes (raw or %00) \u2014 Node `fs.*` throws TypeError on a NUL\n\t// in the path, bypassing the API's `fail` callback and crashing the\n\t// renderer. Pull the rejection up to the validator.\n\tif (decoded.includes('\\0')) return null\n\n\t// `wx.env.USER_DATA_PATH` is `'difile://usr'` (upstream `core/base`), but\n\t// hand-written paths also arrive as `difile:///foo.txt` (extra slashes\n\t// after the scheme). Strip leading slashes so both spellings path-join\n\t// cleanly under the sandbox base.\n\tdecoded = decoded.replace(/^[/\\\\]+/, '')\n\tif (decoded.length === 0) return null\n\n\t// Reject any '..' or '.' segment after decoding. We split on both '/' and\n\t// '\\\\' so Windows-style separators cannot smuggle a traversal segment past\n\t// the validator on POSIX hosts.\n\tconst segments = decoded.split(/[/\\\\]+/)\n\tif (segments.some(s => s === '..' || s === '.')) return null\n\n\t// Classify by reserved prefix (case-sensitive \u2014 `_TMP/` is a user file).\n\tlet kind: VPathKind\n\tlet writable: boolean\n\tif (decoded.startsWith('_tmp/')) {\n\t\tkind = 'tmp'\n\t\twritable = false\n\t} else if (decoded.startsWith('_store/')) {\n\t\tkind = 'store'\n\t\twritable = false\n\t} else {\n\t\tkind = 'usr'\n\t\twritable = true\n\t}\n\n\t// `tmp` lives in the renderer Blob Map \u2014 no realPath.\n\tif (kind === 'tmp') {\n\t\treturn { kind, writable }\n\t}\n\n\t// `store` / `usr`: anchor under the sandbox base and assert containment\n\t// after normalization. Defense in depth against any traversal that the\n\t// segment check above missed (e.g. backslash trickery on POSIX).\n\tconst base = sandboxBase()\n\tconst joined = path.join(base, decoded)\n\tconst normalized = path.normalize(joined)\n\tif (normalized !== base && !normalized.startsWith(base + path.sep)) return null\n\n\treturn { kind, writable, realPath: normalized }\n}\n", "/**\n * Devtools simulator temp-file registry.\n *\n * The simulator hands `chooseImage` / `chooseMedia` / `chooseVideo` /\n * `compressImage` etc. results back to mini-program code as paths. Historically\n * those paths were `blob:` URLs allocated via `URL.createObjectURL`, but the\n * blob: scheme is local-to-the-renderer and cannot be served back into the\n * webview's `persist:simulator` session through a `protocol.handle`. We switched\n * to a custom `difile://_tmp/{uuid}` scheme so the main process can\n * register a single `difile://` protocol handler and stream the bytes for any\n * path, regardless of which renderer originally produced it.\n *\n * To keep the renderer-side cache and the main-process byte store in sync,\n * `setTempFileSink` lets the preload bridge inject a sink that mirrors every\n * `write` / `revoke` / `revokeAll` over IPC. Tests inject a stub sink.\n */\n\nexport interface TempFileSink {\n\twrite(path: string, blob: Blob): void\n\trevoke(path: string): void\n\trevokeAll(): void\n}\n\nconst tempFiles = new Map<string, Blob>()\nlet activeSink: TempFileSink | null = null\n\nexport function setTempFileSink(sink: TempFileSink | null): void {\n\tactiveSink = sink\n}\n\nfunction cryptoRandomId(): string {\n\tconst c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n\tif (c && typeof c.randomUUID === 'function') return c.randomUUID()\n\treturn `${Date.now()}-${Math.random().toString(36).slice(2)}`\n}\n\nexport function createTempFilePath(blob: Blob): string {\n\tconst path = `difile://_tmp/${cryptoRandomId()}`\n\ttempFiles.set(path, blob)\n\tactiveSink?.write(path, blob)\n\treturn path\n}\n\nexport function registerTempFilePath(path: string, blob: Blob): void {\n\ttempFiles.set(path, blob)\n\tactiveSink?.write(path, blob)\n}\n\nexport function revokeTempFilePath(path: string): void {\n\ttempFiles.delete(path)\n\tactiveSink?.revoke(path)\n}\n\nexport function revokeAllTempFilePaths(): void {\n\ttempFiles.clear()\n\tactiveSink?.revokeAll()\n}\n\nexport async function resolveTempFilePath(path: string): Promise<Blob> {\n\tconst cached = tempFiles.get(path)\n\tif (cached) return cached\n\n\tconst response = await fetch(path)\n\tif (!response.ok) {\n\t\tthrow new Error(`\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6 ${path}`)\n\t}\n\tconst blob = await response.blob()\n\t// Cache the freshly fetched blob in-memory so subsequent reads are local.\n\t// We bypass `registerTempFilePath` deliberately: this is a renderer-only\n\t// cache fill, the main-process store already has the bytes (otherwise the\n\t// fetch would not have returned them), so triggering sink.write would\n\t// produce a redundant IPC.\n\ttempFiles.set(path, blob)\n\treturn blob\n}\n\nexport function getTempFileName(path: string, blob: Blob, fallback = 'file'): string {\n\tconst named = blob as Blob & { name?: unknown }\n\tif (typeof named.name === 'string' && named.name.trim()) {\n\t\treturn named.name\n\t}\n\n\ttry {\n\t\tconst url = new URL(path, window.location.href)\n\t\tconst segment = url.pathname.split('/').filter(Boolean).pop()\n\t\tif (segment) return decodeURIComponent(segment)\n\t} catch {\n\t\t// Fall through to the caller-provided fallback.\n\t}\n\n\treturn fallback\n}\n", "/**\n * DevTools API stubs for filesystem wx.xxx APIs\n * (container-side handlers for service-apis/file).\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi \u2192 MiniApp.invokeApi).\n *\n * Contract (see `docs/file-system.md`):\n * - Every entry point routes its caller-supplied path through `resolveVPath`\n * (single resolver), which rejects non-`difile://` schemes, absolute\n * filesystem paths, and any `..` traversal.\n * - Write-class APIs (writeFile / appendFile / unlink / mkdir / rmdir /\n * truncate / rename(dest) / copyFile(dest)) refuse `difile://_tmp/*` and\n * `difile://_store/*` with `permission denied` \u2014 those namespaces are\n * runtime-owned and read-only, matching wx \u771F\u673A semantics.\n * - `fsSaveFile` returns a `difile://_store/{uuid}.{ext}` vpath, never a\n * real disk path.\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks } from './simulator-api-helpers'\nimport { getNodeBindings } from '../shared/node-bindings.js'\nimport { resolveVPath, sandboxBase, type ResolvedVPath } from '../shared/vpath.js'\nimport { resolveTempFilePath } from './temp-files'\n\n/**\n * Dispatch helper: pull a `_tmp/*` Blob out of the renderer Map and hand back\n * its bytes. Throws an ENOENT-shaped Error if the URL is unknown, so callers\n * can surface a `fail` with a real not-found message.\n */\nasync function _tmpBytes(url: string): Promise<Buffer> {\n\ttry {\n\t\tconst blob = await resolveTempFilePath(url)\n\t\treturn await blobToBuffer(blob)\n\t}\n\tcatch (err) {\n\t\tconst msg = err instanceof Error ? err.message : String(err)\n\t\tthrow new Error(`ENOENT: no such file (${url}): ${msg}`, { cause: err })\n\t}\n}\n\nfunction isArrayBuffer(value: unknown): value is ArrayBuffer {\n\treturn Object.prototype.toString.call(value) === '[object ArrayBuffer]'\n}\n\n/**\n * `Buffer` for Blob materialization: the simulator document has no global\n * `Buffer` (nodeIntegration is off and the vite bundle does not polyfill\n * it), so take the constructor from the preload-published node bindings;\n * vitest/node contexts have the global.\n */\nconst BufferImpl: typeof Buffer | undefined =\n\tgetNodeBindings().buffer?.Buffer ?? (typeof Buffer !== 'undefined' ? Buffer : undefined)\n\nasync function blobToBuffer(blob: Blob): Promise<Buffer> {\n\tif (!BufferImpl) {\n\t\tthrow new Error('Buffer binding unavailable')\n\t}\n\tconst readable = blob as Blob & { arrayBuffer?: () => Promise<ArrayBuffer> }\n\tif (typeof readable.arrayBuffer === 'function') {\n\t\tconst ab = await readable.arrayBuffer()\n\t\treturn BufferImpl.from(new Uint8Array(ab))\n\t}\n\n\tif (typeof FileReader !== 'function') {\n\t\tthrow new Error('Blob cannot be read as ArrayBuffer')\n\t}\n\n\treturn new Promise((resolve, reject) => {\n\t\tconst reader = new FileReader()\n\t\treader.onerror = () => reject(reader.error ?? new Error('Blob read failed'))\n\t\treader.onload = () => {\n\t\t\tconst result = reader.result\n\t\t\tif (!isArrayBuffer(result)) {\n\t\t\t\treject(new Error('Blob read did not return an ArrayBuffer'))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tresolve(BufferImpl.from(new Uint8Array(result)))\n\t\t}\n\t\treader.readAsArrayBuffer(blob)\n\t})\n}\n\n/**\n * Real Node built-ins: the preload-published bindings in the simulator\n * document (nodeIntegration is off there and the vite bundle stubs `node:*`\n * imports), `require` under vitest/node. Each candidate is validated by\n * probing a required member function \u2014 the vite stubs are truthy objects, so\n * truthiness alone would wave a dead module through and the guard below\n * (`guardFsAvailable`) would then let calls crash mid-handler.\n */\nfunction resolveNodeModule<T>(fromBindings: T | undefined, name: string, probe: (mod: T) => boolean): T {\n\tif (fromBindings && probe(fromBindings)) return fromBindings\n\tif (typeof require !== 'undefined') {\n\t\t// eslint-disable-next-line @typescript-eslint/no-require-imports\n\t\tconst mod = require(name) as T\n\t\tif (mod && probe(mod)) return mod\n\t}\n\treturn null as unknown as T\n}\n\nconst _fs = resolveNodeModule(getNodeBindings().fs, 'fs', m => typeof m.readFile === 'function')\nconst _path = resolveNodeModule(getNodeBindings().path, 'path', m => typeof m.join === 'function')\nconst _crypto = resolveNodeModule(getNodeBindings().crypto, 'crypto', m => typeof m.createHash === 'function')\n\ntype FsCallbacks = ReturnType<typeof bindCallbacks>\ntype NodeStats = import('fs').Stats\ntype NodeErr = NodeJS.ErrnoException | Error | null\n\n// \u2500\u2500\u2500 shared fs-API scaffolding \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Every handler below shares the same skeleton: bail if Node `fs` isn't\n// available, resolve the caller path through the single vpath resolver\n// (bailing on invalid/unsafe paths), optionally reject read-only\n// namespaces for write-class APIs, then run a Node fs call and translate its\n// `(err, ...)` callback into the wx success/fail/complete triad. The helpers\n// below are the single authority for each of those steps so per-API bodies\n// only contain what differs between APIs (the real fs call and any extra\n// success payload fields).\n\n/** Bails with `${apiName}:fail not available in browser context` when the Node `fs` binding is absent (e.g. a browser-only build). */\nfunction guardFsAvailable(apiName: string, cbs: FsCallbacks): boolean {\n\tif (_fs) return false\n\tcbs.onFail?.({ errMsg: `${apiName}:fail not available in browser context` })\n\tcbs.onComplete?.()\n\treturn true\n}\n\n/**\n * True when any path component from the sandbox base down to `realPath` is a\n * symlink. `resolveVPath` validates the requested STRING (no `..`, stays\n * under the base after normalize) but never inspects the disk \u2014 a symlink\n * planted inside `usr/` would otherwise let Node's default follow-symlinks\n * behavior read or write through to a target outside the sandbox. `lstat`\n * (not `stat`/`exists`) sees the link itself, so dangling links \u2014 which\n * `fs.writeFile` would still follow to CREATE the outside target \u2014 are\n * caught too. The base itself may legitimately be a symlink (macOS tmpdir);\n * only components below it are checked.\n */\nfunction containsSymlink(realPath: string): boolean {\n\tconst rel = _path.relative(sandboxBase(), realPath)\n\tif (!rel || rel.startsWith('..')) return false\n\tlet cur = sandboxBase()\n\tfor (const seg of rel.split(_path.sep)) {\n\t\tcur = _path.join(cur, seg)\n\t\tlet entry: import('fs').Stats\n\t\ttry {\n\t\t\tentry = _fs.lstatSync(cur)\n\t\t} catch {\n\t\t\t// Nothing on disk from here down \u2014 nothing left to follow.\n\t\t\treturn false\n\t\t}\n\t\tif (entry.isSymbolicLink()) return true\n\t}\n\treturn false\n}\n\n/**\n * Resolves `p` via `resolveVPath` and asserts the resolved disk path does not\n * pass through a sandbox-internal symlink, or reports `${apiName}:fail\n * invalid or unsafe path` and runs `complete`.\n */\nfunction resolveOrBail(p: unknown, apiName: string, cbs: FsCallbacks): ResolvedVPath | undefined {\n\tconst v = resolveVPath(p)\n\tif (v && (!v.realPath || !_fs || !containsSymlink(v.realPath))) return v\n\tcbs.onFail?.({ errMsg: `${apiName}:fail invalid or unsafe path` })\n\tcbs.onComplete?.()\n\treturn undefined\n}\n\n/**\n * wx `Stats` payload: numeric mode bits, byte size, SECOND-unit epoch\n * timestamps \u2014 wx and the dimina native clients all report seconds, while\n * Node's `atimeMs`/`mtimeMs` are milliseconds.\n */\nfunction toWxStats(s: NodeStats): Record<string, unknown> {\n\treturn {\n\t\tsize: s.size,\n\t\tmode: s.mode,\n\t\tlastAccessedTime: Math.floor(s.atimeMs / 1000),\n\t\tlastModifiedTime: Math.floor(s.mtimeMs / 1000),\n\t\tisFile: s.isFile(),\n\t\tisDirectory: s.isDirectory(),\n\t}\n}\n\n/**\n * Type-guards `v` as writable (narrows `realPath` to `string`), or reports\n * `${apiName}:fail permission denied` and runs `complete`. `_tmp` / `_store`\n * are runtime-owned and read-only, matching wx \u771F\u673A semantics.\n */\nfunction ensureWritable(v: ResolvedVPath, apiName: string, cbs: FsCallbacks): v is ResolvedVPath & { realPath: string } {\n\tif (v.writable && v.realPath) return true\n\tcbs.onFail?.({ errMsg: `${apiName}:fail permission denied` })\n\tcbs.onComplete?.()\n\treturn false\n}\n\n/** Fail handler for a `_tmpBytes(...).then(success, ...)` chain: reports `${apiName}:fail <message>` and runs `complete`. */\nfunction tmpFailHandler(apiName: string, cbs: FsCallbacks) {\n\treturn (err: Error) => {\n\t\tcbs.onFail?.({ errMsg: `${apiName}:fail ${err.message}` })\n\t\tcbs.onComplete?.()\n\t}\n}\n\n/**\n * Builds a Node-style `(err, ...args)` callback that translates into the wx\n * success/fail/complete triad: `err` truthy \u2192 fail with `${apiName}:fail\n * <message>`; otherwise success with `${apiName}:ok` plus whatever\n * `buildOk(...args)` contributes.\n */\nfunction nodeComplete<TArgs extends unknown[] = []>(\n\tapiName: string,\n\tcbs: FsCallbacks,\n\tbuildOk?: (...args: TArgs) => Record<string, unknown> | undefined,\n) {\n\treturn (err: NodeErr, ...args: TArgs) => {\n\t\tif (err) {\n\t\t\tcbs.onFail?.({ errMsg: `${apiName}:fail ${err.message}` })\n\t\t} else {\n\t\t\tcbs.onSuccess?.({ ...(buildOk ? buildOk(...args) : undefined), errMsg: `${apiName}:ok` })\n\t\t}\n\t\tcbs.onComplete?.()\n\t}\n}\n\n/**\n * `mkdir -p` the parent of `destReal`, then run `writeFn` (a `writeFile` /\n * `copyFile` call) through `nodeComplete`. Shared by every API that\n * materializes bytes onto disk under a possibly-not-yet-existing directory\n * (fsWriteFile, fsCopyFile's `_tmp` branch, fsSaveFile).\n */\nfunction mkdirpThenWrite(\n\tdestReal: string,\n\tapiName: string,\n\tcbs: FsCallbacks,\n\twriteFn: (done: (err: NodeErr) => void) => void,\n\tokExtra?: Record<string, unknown>,\n): void {\n\t_fs.mkdir(_path.dirname(destReal), { recursive: true }, (mkdirErr) => {\n\t\tif (mkdirErr) {\n\t\t\tcbs.onFail?.({ errMsg: `${apiName}:fail ${mkdirErr.message}` })\n\t\t\tcbs.onComplete?.()\n\t\t\treturn\n\t\t}\n\t\t// fs.writeFile/copyFile validate their arguments synchronously (a\n\t\t// numeric `data`, an unknown `encoding`); this callback runs after the\n\t\t// wire handler's own try/catch has already returned, so an unguarded\n\t\t// throw here would leave the call with no verdict at all.\n\t\ttry {\n\t\t\twriteFn(nodeComplete(apiName, cbs, () => okExtra))\n\t\t} catch (err) {\n\t\t\tcbs.onFail?.({ errMsg: `${apiName}:fail ${err instanceof Error ? err.message : String(err)}` })\n\t\t\tcbs.onComplete?.()\n\t\t}\n\t})\n}\n\nexport function fsAccess(\n\tthis: MiniAppContext,\n\t{ path, success, fail, complete }: { path: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsAccess', cbs)) return\n\tconst v = resolveOrBail(path, 'fsAccess', cbs)\n\tif (!v) return\n\tif (v.kind === 'tmp') {\n\t\t// _tmp existence check: renderer Map hit \u21D2 ok; miss \u21D2 ENOENT-shaped fail.\n\t\t_tmpBytes(path).then(\n\t\t\t() => { onSuccess?.({ errMsg: 'fsAccess:ok' }); onComplete?.() },\n\t\t\ttmpFailHandler('fsAccess', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!v.realPath) {\n\t\tonFail?.({ errMsg: 'fsAccess:fail invalid path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.access(v.realPath, _fs.constants.F_OK, nodeComplete('fsAccess', cbs))\n}\n\nexport function fsStat(\n\tthis: MiniAppContext,\n\t{ path, recursive = false, success, fail, complete }: {\n\t\tpath: string\n\t\trecursive?: boolean\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsStat', cbs)) return\n\tconst v = resolveOrBail(path, 'fsStat', cbs)\n\tif (!v) return\n\tif (v.kind === 'tmp') {\n\t\t// _tmp size is known from the Blob; mtime is 0 (no on-disk timestamp).\n\t\t_tmpBytes(path).then(\n\t\t\t(buf) => {\n\t\t\t\tonSuccess?.({\n\t\t\t\t\tstats: {\n\t\t\t\t\t\tsize: buf.length,\n\t\t\t\t\t\tmode: 0,\n\t\t\t\t\t\tlastAccessedTime: 0,\n\t\t\t\t\t\tlastModifiedTime: 0,\n\t\t\t\t\t\tisFile: true,\n\t\t\t\t\t\tisDirectory: false,\n\t\t\t\t\t},\n\t\t\t\t\terrMsg: 'fsStat:ok',\n\t\t\t\t})\n\t\t\t\tonComplete?.()\n\t\t\t},\n\t\t\ttmpFailHandler('fsStat', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!v.realPath) {\n\t\tonFail?.({ errMsg: 'fsStat:fail invalid path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\tconst resolved = v.realPath\n\tif (recursive) {\n\t\t// Map of RELATIVE path \u2192 stats for the tree, keyed the way wx and the\n\t\t// dimina native clients key it: the queried directory itself as \".\"\n\t\t// plus `relative(root, entry)`-style descendants \u2014 never a host\n\t\t// absolute path (that would leak the sandbox location to mini-program\n\t\t// code). Any readdir/stat error fails the whole call: silently\n\t\t// dropping a failed entry would present an incomplete tree as ok.\n\t\tconst statsMap: Record<string, unknown> = {}\n\t\tlet settled = false\n\t\tconst failOnce = (err: Error) => {\n\t\t\tif (settled) return\n\t\t\tsettled = true\n\t\t\tonFail?.({ errMsg: `fsStat:fail ${err.message}` })\n\t\t\tonComplete?.()\n\t\t}\n\t\tconst okOnce = () => {\n\t\t\tif (settled) return\n\t\t\tsettled = true\n\t\t\tonSuccess?.({ stats: statsMap, errMsg: 'fsStat:ok' })\n\t\t\tonComplete?.()\n\t\t}\n\t\tconst relKey = (full: string): string => {\n\t\t\tconst rel = _path.relative(resolved, full)\n\t\t\treturn rel === '' ? '.' : rel.split(_path.sep).join('/')\n\t\t}\n\t\t// `lstat`, never `stat`: `resolveOrBail`'s symlink fence only inspects\n\t\t// the REQUESTED root path \u2014 a symlink discovered mid-walk would\n\t\t// otherwise be followed (leaking sandbox-external metadata into the\n\t\t// map) while its Dirent still reads as a non-directory (leaving a\n\t\t// truncated tree). A symlink anywhere in the walk fails the whole\n\t\t// call; the recursion decision uses the same lstat result.\n\t\tconst statInto = (full: string, cb: (err: Error | null, isDirectory?: boolean) => void) => {\n\t\t\t_fs.lstat(full, (err, s) => {\n\t\t\t\tif (err) { cb(err); return }\n\t\t\t\tif (s.isSymbolicLink()) {\n\t\t\t\t\tcb(new Error('invalid or unsafe path'))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tstatsMap[relKey(full)] = toWxStats(s)\n\t\t\t\tcb(null, s.isDirectory())\n\t\t\t})\n\t\t}\n\t\tconst walkDir = (dir: string, cb: (err: Error | null) => void) => {\n\t\t\t_fs.readdir(dir, { withFileTypes: true }, (err, entries) => {\n\t\t\t\tif (err) { cb(err); return }\n\t\t\t\tlet pending = entries.length\n\t\t\t\tif (pending === 0) { cb(null); return }\n\t\t\t\tlet erred = false\n\t\t\t\tconst done = (e: Error | null) => {\n\t\t\t\t\tif (erred) return\n\t\t\t\t\tif (e) { erred = true; cb(e); return }\n\t\t\t\t\tif (--pending === 0) cb(null)\n\t\t\t\t}\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tconst full = _path.join(dir, entry.name)\n\t\t\t\t\tstatInto(full, (statErr, isDirectory) => {\n\t\t\t\t\t\tif (statErr) { done(statErr); return }\n\t\t\t\t\t\tif (isDirectory) walkDir(full, done)\n\t\t\t\t\t\telse done(null)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tstatInto(resolved, (rootErr) => {\n\t\t\tif (rootErr) { failOnce(rootErr); return }\n\t\t\twalkDir(resolved, (err) => {\n\t\t\t\tif (err) failOnce(err)\n\t\t\t\telse okOnce()\n\t\t\t})\n\t\t})\n\t} else {\n\t\t_fs.stat(resolved, nodeComplete('fsStat', cbs, (s: NodeStats) => ({\n\t\t\tstats: toWxStats(s),\n\t\t})))\n\t}\n}\n\nexport function fsReadFile(\n\tthis: MiniAppContext,\n\t{ filePath, encoding, success, fail, complete }: {\n\t\tfilePath: string\n\t\tencoding?: BufferEncoding\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsReadFile', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsReadFile', cbs)\n\tif (!v) return\n\tif (v.kind === 'tmp') {\n\t\t_tmpBytes(filePath).then(\n\t\t\t(buf) => {\n\t\t\t\tconst data: Buffer | string = encoding ? buf.toString(encoding) : buf\n\t\t\t\tonSuccess?.({ data, errMsg: 'fsReadFile:ok' })\n\t\t\t\tonComplete?.()\n\t\t\t},\n\t\t\ttmpFailHandler('fsReadFile', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!v.realPath) {\n\t\tonFail?.({ errMsg: 'fsReadFile:fail invalid path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.readFile(v.realPath, encoding || null, nodeComplete('fsReadFile', cbs, (data: Buffer | string) => ({ data })))\n}\n\nexport function fsWriteFile(\n\tthis: MiniAppContext,\n\t{ filePath, data, encoding = 'utf8', success, fail, complete }: {\n\t\tfilePath: string\n\t\tdata: string | Uint8Array\n\t\tencoding?: BufferEncoding\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsWriteFile', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsWriteFile', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsWriteFile', cbs)) return\n\tmkdirpThenWrite(v.realPath, 'fsWriteFile', cbs, done => _fs.writeFile(v.realPath, data as string, { encoding }, done))\n}\n\nexport function fsAppendFile(\n\tthis: MiniAppContext,\n\t{ filePath, data, encoding = 'utf8', success, fail, complete }: {\n\t\tfilePath: string\n\t\tdata: string | Uint8Array\n\t\tencoding?: BufferEncoding\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsAppendFile', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsAppendFile', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsAppendFile', cbs)) return\n\t_fs.appendFile(v.realPath, data as string, { encoding }, nodeComplete('fsAppendFile', cbs))\n}\n\nexport function fsCopyFile(\n\tthis: MiniAppContext,\n\t{ srcPath, destPath, success, fail, complete }: {\n\t\tsrcPath: string\n\t\tdestPath: string\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsCopyFile', cbs)) return\n\tconst vSrc = resolveOrBail(srcPath, 'fsCopyFile', cbs)\n\tif (!vSrc) return\n\tconst vDest = resolveOrBail(destPath, 'fsCopyFile', cbs)\n\tif (!vDest) return\n\tif (!ensureWritable(vDest, 'fsCopyFile', cbs)) return\n\tif (vSrc.kind === 'tmp') {\n\t\t// Materialize the renderer Blob into the user-data\n\t\t// area. The dest writable check above already rejected _tmp / _store\n\t\t// destinations \u2014 saveFile is the documented route for tmp\u2192store.\n\t\t_tmpBytes(srcPath).then(\n\t\t\tbuf => mkdirpThenWrite(vDest.realPath, 'fsCopyFile', cbs, done => _fs.writeFile(vDest.realPath, buf, done)),\n\t\t\ttmpFailHandler('fsCopyFile', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!vSrc.realPath) {\n\t\tonFail?.({ errMsg: 'fsCopyFile:fail invalid src path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.copyFile(vSrc.realPath, vDest.realPath, nodeComplete('fsCopyFile', cbs))\n}\n\nexport function fsRename(\n\tthis: MiniAppContext,\n\t{ oldPath, newPath, success, fail, complete }: {\n\t\toldPath: string\n\t\tnewPath: string\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsRename', cbs)) return\n\tconst vOld = resolveOrBail(oldPath, 'fsRename', cbs)\n\tif (!vOld) return\n\tconst vNew = resolveOrBail(newPath, 'fsRename', cbs)\n\tif (!vNew) return\n\t// Rename deletes the source \u2014 both sides must be writable. _tmp / _store\n\t// reject under either role.\n\tif (!ensureWritable(vOld, 'fsRename', cbs)) return\n\tif (!ensureWritable(vNew, 'fsRename', cbs)) return\n\t_fs.rename(vOld.realPath, vNew.realPath, nodeComplete('fsRename', cbs))\n}\n\nexport function fsUnlink(\n\tthis: MiniAppContext,\n\t{ filePath, success, fail, complete }: { filePath: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsUnlink', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsUnlink', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsUnlink', cbs)) return\n\t_fs.unlink(v.realPath, nodeComplete('fsUnlink', cbs))\n}\n\nexport function fsMkdir(\n\tthis: MiniAppContext,\n\t{ dirPath, recursive = false, success, fail, complete }: {\n\t\tdirPath: string\n\t\trecursive?: boolean\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsMkdir', cbs)) return\n\tconst v = resolveOrBail(dirPath, 'fsMkdir', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsMkdir', cbs)) return\n\t_fs.mkdir(v.realPath, { recursive }, nodeComplete('fsMkdir', cbs))\n}\n\nexport function fsRmdir(\n\tthis: MiniAppContext,\n\t{ dirPath, recursive = false, success, fail, complete }: {\n\t\tdirPath: string\n\t\trecursive?: boolean\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsRmdir', cbs)) return\n\tconst v = resolveOrBail(dirPath, 'fsRmdir', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsRmdir', cbs)) return\n\t// The two cases need different Node primitives: `fs.rm` without\n\t// `recursive` refuses directories outright (ERR_FS_EISDIR) even when\n\t// empty, while wx's non-recursive rmdir removes an empty directory and\n\t// fails only on a non-empty one \u2014 exactly `fs.rmdir`'s contract.\n\tif (recursive) {\n\t\tconst rmFn = (_fs as typeof _fs & { rm?: typeof _fs.rmdir }).rm ?? _fs.rmdir\n\t\trmFn(v.realPath, { recursive: true } as Parameters<typeof _fs.rmdir>[1], nodeComplete('fsRmdir', cbs))\n\t} else {\n\t\t_fs.rmdir(v.realPath, nodeComplete('fsRmdir', cbs))\n\t}\n}\n\nexport function fsReaddir(\n\tthis: MiniAppContext,\n\t{ dirPath, success, fail, complete }: { dirPath: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsReaddir', cbs)) return\n\tconst v = resolveOrBail(dirPath, 'fsReaddir', cbs)\n\tif (!v) return\n\t// _tmp and _store are flat (id-addressed) namespaces \u2014 readdir is meaningless.\n\tif (v.kind === 'tmp' || v.kind === 'store') {\n\t\tonFail?.({ errMsg: `fsReaddir:fail ${v.kind} is a flat namespace (no dir tree)` })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\tif (!v.realPath) {\n\t\tonFail?.({ errMsg: 'fsReaddir:fail invalid path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.readdir(v.realPath, nodeComplete('fsReaddir', cbs, (files: string[]) => ({ files })))\n}\n\nexport function fsGetFileInfo(\n\tthis: MiniAppContext,\n\t{ filePath, digestAlgorithm, success, fail, complete }: {\n\t\tfilePath: string\n\t\tdigestAlgorithm?: string\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsGetFileInfo', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsGetFileInfo', cbs)\n\tif (!v) return\n\t// wx and every dimina native client default digestAlgorithm to md5 and\n\t// always include the digest \u2014 a missing digest is a fail, not a silently\n\t// smaller success payload.\n\tconst algorithm = digestAlgorithm === 'sha1' ? 'sha1' : 'md5'\n\tif (v.kind === 'tmp') {\n\t\t_tmpBytes(filePath).then(\n\t\t\t(buf) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst hash = _crypto.createHash(algorithm)\n\t\t\t\t\thash.update(buf)\n\t\t\t\t\tonSuccess?.({ size: buf.length, digest: hash.digest('hex'), errMsg: 'fsGetFileInfo:ok' })\n\t\t\t\t\tonComplete?.()\n\t\t\t\t} catch (hashErr) {\n\t\t\t\t\tonFail?.({ errMsg: `fsGetFileInfo:fail ${(hashErr as Error).message}` })\n\t\t\t\t\tonComplete?.()\n\t\t\t\t}\n\t\t\t},\n\t\t\ttmpFailHandler('fsGetFileInfo', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!v.realPath) {\n\t\tonFail?.({ errMsg: 'fsGetFileInfo:fail invalid path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\tconst resolved = v.realPath\n\t_fs.stat(resolved, (err, s) => {\n\t\tif (err) {\n\t\t\tonFail?.({ errMsg: `fsGetFileInfo:fail ${err.message}` })\n\t\t\tonComplete?.()\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tconst hash = _crypto.createHash(algorithm)\n\t\t\tconst stream = _fs.createReadStream(resolved)\n\t\t\tstream.on('data', (chunk) => hash.update(chunk as Buffer))\n\t\t\tstream.on('end', () => {\n\t\t\t\tonSuccess?.({ size: s.size, digest: hash.digest('hex'), errMsg: 'fsGetFileInfo:ok' })\n\t\t\t\tonComplete?.()\n\t\t\t})\n\t\t\tstream.on('error', (hashErr) => {\n\t\t\t\tonFail?.({ errMsg: `fsGetFileInfo:fail ${hashErr.message}` })\n\t\t\t\tonComplete?.()\n\t\t\t})\n\t\t} catch (hashErr) {\n\t\t\tonFail?.({ errMsg: `fsGetFileInfo:fail ${(hashErr as Error).message}` })\n\t\t\tonComplete?.()\n\t\t}\n\t})\n}\n\n/**\n * Save a temp file into the read-only `_store/` namespace. Returns a vpath\n * (`difile://_store/{uuid}.{ext}`) rather than a real disk path so callers\n * cannot leak the host filesystem layout.\n *\n * Scope:\n * - source must be a `difile://`-anchored vpath (validator rejects abs paths);\n * - source from `_tmp/` materializes the renderer Blob into `_store/` via the\n * renderer-Blob \u2192 main-fs copy bridge;\n * - source from `_store/` or the user-data area is copied byte-for-byte to a\n * freshly minted `_store/{uuid}.{ext}` entry under the sandbox base.\n */\n/**\n * Resolves the saveFile destination. wx contract: an explicit `filePath`\n * names the exact destination and is echoed back as `savedFilePath` \u2014 it\n * goes through the same validator + writable gate as every other\n * write-class destination, so runtime-owned `_tmp/` / `_store/` targets\n * fail with permission denied. Only when `filePath` is omitted is a fresh\n * `_store/{uuid}` vpath minted. Reports fail + complete and returns\n * undefined when the destination is invalid.\n */\nfunction resolveSaveFileDestination(\n\ttempFilePath: string,\n\tfilePath: string | undefined,\n\tcbs: FsCallbacks,\n): { savedFilePath: string; destReal: string } | undefined {\n\tif (typeof filePath === 'string' && filePath) {\n\t\tconst dest = resolveOrBail(filePath, 'fsSaveFile', cbs)\n\t\tif (!dest) return undefined\n\t\tif (!ensureWritable(dest, 'fsSaveFile', cbs)) return undefined\n\t\treturn { savedFilePath: filePath, destReal: dest.realPath }\n\t}\n\tconst ext = _path.extname(tempFilePath) || ''\n\tconst id = _crypto.randomUUID() + ext\n\tconst savedFilePath = `difile://_store/${id}`\n\tconst destResolved = resolveVPath(savedFilePath)\n\tif (!destResolved || !destResolved.realPath) {\n\t\t// Defensive: a freshly minted vpath must always resolve.\n\t\tcbs.onFail?.({ errMsg: 'fsSaveFile:fail unable to allocate destination' })\n\t\tcbs.onComplete?.()\n\t\treturn undefined\n\t}\n\tif (containsSymlink(destResolved.realPath)) {\n\t\tcbs.onFail?.({ errMsg: 'fsSaveFile:fail invalid or unsafe path' })\n\t\tcbs.onComplete?.()\n\t\treturn undefined\n\t}\n\treturn { savedFilePath, destReal: destResolved.realPath }\n}\n\nexport function fsSaveFile(\n\tthis: MiniAppContext,\n\t{ tempFilePath, filePath, success, fail, complete }: {\n\t\ttempFilePath: string\n\t\tfilePath?: string\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsSaveFile', cbs)) return\n\tconst src = resolveOrBail(tempFilePath, 'fsSaveFile', cbs)\n\tif (!src) return\n\n\tconst destination = resolveSaveFileDestination(tempFilePath, filePath, cbs)\n\tif (!destination) return\n\tconst { savedFilePath, destReal } = destination\n\n\tif (src.kind === 'tmp') {\n\t\t// Materialize the renderer Blob into _store on disk.\n\t\t_tmpBytes(tempFilePath).then(\n\t\t\tbytes => mkdirpThenWrite(destReal, 'fsSaveFile', cbs, done => _fs.writeFile(destReal, bytes, done), { savedFilePath }),\n\t\t\ttmpFailHandler('fsSaveFile', cbs),\n\t\t)\n\t\treturn\n\t}\n\tif (!src.realPath) {\n\t\tonFail?.({ errMsg: 'fsSaveFile:fail invalid src path' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\tif (src.realPath === destReal) {\n\t\t// Source and destination normalize to the same file: saving a file\n\t\t// onto itself is a defined no-op success, not whatever the host\n\t\t// Node's same-file copyFile happens to do. Still a no-op only for a\n\t\t// real file \u2014 resolveOrBail validates the path string, not the disk,\n\t\t// so a missing or directory source must fail here like any other save.\n\t\t_fs.stat(src.realPath, (statErr, st) => {\n\t\t\tif (statErr) {\n\t\t\t\tonFail?.({ errMsg: `fsSaveFile:fail ${statErr.message}` })\n\t\t\t\tonComplete?.()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!st.isFile()) {\n\t\t\t\tonFail?.({ errMsg: `fsSaveFile:fail illegal operation on a directory, copyfile '${tempFilePath}'` })\n\t\t\t\tonComplete?.()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcbs.onSuccess?.({ savedFilePath, errMsg: 'fsSaveFile:ok' })\n\t\t\tonComplete?.()\n\t\t})\n\t\treturn\n\t}\n\tmkdirpThenWrite(destReal, 'fsSaveFile', cbs, done => _fs.copyFile(src.realPath!, destReal, done), { savedFilePath })\n}\n\n/**\n * List files previously persisted by `fsSaveFile` \u2014 i.e. anything under the\n * `_store/` namespace. Returned `filePath` entries are vpaths so callers can\n * round-trip through `fsReadFile` / `fsRemoveSavedFile` without ever seeing\n * the host filesystem.\n */\nexport function fsGetSavedFileList(\n\tthis: MiniAppContext,\n\t{ success, fail, complete }: { success?: unknown; fail?: unknown; complete?: unknown } = {},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsGetSavedFileList', cbs)) return\n\tconst storeVpath = resolveVPath('difile://_store/')\n\tconst storeDir = storeVpath?.realPath\n\tif (!storeDir) {\n\t\tonSuccess?.({ fileList: [], errMsg: 'fsGetSavedFileList:ok' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.readdir(storeDir, (err, files) => {\n\t\tif (err) {\n\t\t\t// Only \"the store directory does not exist yet\" is a legitimate\n\t\t\t// empty list; any other readdir error (ENOTDIR, EACCES, EIO)\n\t\t\t// masked as an empty success would hide real breakage.\n\t\t\tif ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n\t\t\t\tonSuccess?.({ fileList: [], errMsg: 'fsGetSavedFileList:ok' })\n\t\t\t} else {\n\t\t\t\tonFail?.({ errMsg: `fsGetSavedFileList:fail ${err.message}` })\n\t\t\t}\n\t\t\tonComplete?.()\n\t\t\treturn\n\t\t}\n\t\tlet pending = files.length\n\t\tif (pending === 0) {\n\t\t\tonSuccess?.({ fileList: [], errMsg: 'fsGetSavedFileList:ok' })\n\t\t\tonComplete?.()\n\t\t\treturn\n\t\t}\n\t\tconst fileList: Array<{ filePath: string; size: number; createTime: number }> = []\n\t\tlet settled = false\n\t\tfor (const name of files) {\n\t\t\tconst full = _path.join(storeDir, name)\n\t\t\t_fs.stat(full, (statErr, s) => {\n\t\t\t\tif (settled) return\n\t\t\t\tif (statErr) {\n\t\t\t\t\t// A partial list would misrepresent the store's contents.\n\t\t\t\t\tsettled = true\n\t\t\t\t\tonFail?.({ errMsg: `fsGetSavedFileList:fail ${statErr.message}` })\n\t\t\t\t\tonComplete?.()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tfileList.push({\n\t\t\t\t\tfilePath: `difile://_store/${name}`,\n\t\t\t\t\tsize: s.size,\n\t\t\t\t\t// wx createTime is a seconds-unit epoch.\n\t\t\t\t\tcreateTime: Math.floor(s.birthtimeMs / 1000),\n\t\t\t\t})\n\t\t\t\tif (--pending === 0) {\n\t\t\t\t\tsettled = true\n\t\t\t\t\tonSuccess?.({ fileList, errMsg: 'fsGetSavedFileList:ok' })\n\t\t\t\t\tonComplete?.()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nexport function fsRemoveSavedFile(\n\tthis: MiniAppContext,\n\t{ filePath, success, fail, complete }: { filePath: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onFail, onComplete } = cbs\n\tif (guardFsAvailable('fsRemoveSavedFile', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsRemoveSavedFile', cbs)\n\tif (!v) return\n\t// removeSavedFile is the documented exception to the `_store/` read-only\n\t// rule. Only `_store/*` entries may be removed through this API.\n\tif (v.kind !== 'store' || !v.realPath) {\n\t\tonFail?.({ errMsg: 'fsRemoveSavedFile:fail only _store/ entries may be removed' })\n\t\tonComplete?.()\n\t\treturn\n\t}\n\t_fs.unlink(v.realPath, nodeComplete('fsRemoveSavedFile', cbs))\n}\n\nexport function fsTruncate(\n\tthis: MiniAppContext,\n\t{ filePath, length = 0, success, fail, complete }: {\n\t\tfilePath: string\n\t\tlength?: number\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tif (guardFsAvailable('fsTruncate', cbs)) return\n\tconst v = resolveOrBail(filePath, 'fsTruncate', cbs)\n\tif (!v) return\n\tif (!ensureWritable(v, 'fsTruncate', cbs)) return\n\t_fs.truncate(v.realPath, length, nodeComplete('fsTruncate', cbs))\n}\n\n/**\n * Synchronous \"vpath \u2192 bytes\" read for consumers that must resolve within one\n * task (saveImageToPhotosAlbum builds its download anchor synchronously so\n * its success/fail verdict precedes `complete`). Returns null when Node fs is\n * unavailable, the vpath does not resolve to a disk-backed file (`_tmp/*`\n * bytes live in the renderer Blob registry \u2014 resolve those through\n * `resolveTempFilePath` instead), the resolved path passes through a\n * sandbox-internal symlink, or the read itself fails.\n */\nexport function readVPathBytesSync(p: unknown): Buffer | null {\n\tif (!_fs) return null\n\tconst v = resolveVPath(p)\n\tif (!v?.realPath) return null\n\tif (containsSymlink(v.realPath)) return null\n\ttry {\n\t\treturn _fs.readFileSync(v.realPath)\n\t} catch {\n\t\treturn null\n\t}\n}\n", "/**\n * DevTools API stubs for media-related wx.xxx APIs\n * (image / video / audio).\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi \u2192 MiniApp.invokeApi).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindDomEvents, type EventBridgeDisposer } from './event-bridge'\nimport { bindCallbacks } from './simulator-api-helpers'\nimport { readVPathBytesSync } from './simulator-api-fs'\nimport { createTempFilePath, resolveTempFilePath } from './temp-files'\n\n// \u2500\u2500\u2500 shared file-picker scaffolding \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// chooseImage / chooseVideo / chooseMedia all drive the browser file picker\n// through a hidden `<input type=file>`: create it, wire accept/multiple/\n// capture from the caller's options, listen for `change`, and report a\n// `${apiName}:fail cancel` when the user closes the dialog without picking\n// anything. `createFilePicker` is the single authority for that scaffold;\n// each API supplies only its accept string, multiplicity, and the\n// (possibly async) processing of the picked files.\n\ntype CancelCallbacks = Pick<ReturnType<typeof bindCallbacks>, 'onFail' | 'onComplete'>\n\ninterface FilePickerConfig {\n\taccept: string\n\tmultiple: boolean\n\t/** `capture` attribute value, or `undefined` to omit it (album source, or no single-camera source requested). */\n\tcapture?: 'user' | 'environment'\n}\n\n/** Resolves the `capture` attribute from `sourceType` + `camera`: only set when the caller asked for camera-only capture. */\nfunction captureAttrFor(sourceType: string[], camera: unknown): 'user' | 'environment' | undefined {\n\tif (sourceType.length !== 1 || sourceType[0] !== 'camera') return undefined\n\treturn camera === 'front' ? 'user' : 'environment'\n}\n\n/**\n * Drives a hidden `<input type=file>` through one pick cycle. Reports\n * `${apiName}:fail cancel` + `complete` when the selection is empty;\n * otherwise hands the raw (un-truncated) `FileList` to `onPick`, which owns\n * success/fail/complete and must call `removeInput` once it is done with the\n * picker element.\n */\nfunction createFilePicker(\n\tapiName: string,\n\tconfig: FilePickerConfig,\n\tcbs: CancelCallbacks,\n\tonPick: (files: File[], removeInput: () => void) => void | Promise<void>,\n): void {\n\tconst input = document.createElement('input')\n\tinput.type = 'file'\n\tinput.accept = config.accept\n\tinput.multiple = config.multiple\n\tif (config.capture) input.setAttribute('capture', config.capture)\n\tinput.style.display = 'none'\n\tdocument.body.appendChild(input)\n\n\tconst removeInput = () => input.remove()\n\n\tinput.addEventListener('change', () => {\n\t\tconst files = Array.from(input.files || [])\n\t\tif (files.length === 0) {\n\t\t\tcbs.onFail?.({ errMsg: `${apiName}:fail cancel` })\n\t\t\tcbs.onComplete?.()\n\t\t\tremoveInput()\n\t\t\treturn\n\t\t}\n\t\tvoid onPick(files, removeInput)\n\t})\n\n\tinput.click()\n}\n\n// \u2500\u2500\u2500 Media: Image \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function chooseImage(\n\tthis: MiniAppContext,\n\t{ count = 9, sourceType, camera, success, fail, complete }: {\n\t\tcount?: number\n\t\tsizeType?: unknown\n\t\tsourceType?: unknown\n\t\tcamera?: unknown\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onComplete } = cbs\n\tconst normalizedCount = normalizeChooseMediaCount(count)\n\tconst normalizedSourceType = normalizeStringArray(sourceType, ['album', 'camera'])\n\n\tcreateFilePicker(\n\t\t'chooseImage',\n\t\t{ accept: 'image/*', multiple: normalizedCount > 1, capture: captureAttrFor(normalizedSourceType, camera) },\n\t\tcbs,\n\t\t(rawFiles, removeInput) => {\n\t\t\tconst files = rawFiles.slice(0, normalizedCount)\n\t\t\tconst tempFilePaths = files.map(f => createTempFilePath(f))\n\t\t\tconst tempFiles = files.map((f, i) => ({ path: tempFilePaths[i], size: f.size }))\n\t\t\tonSuccess?.({ tempFilePaths, tempFiles, errMsg: 'chooseImage:ok' })\n\t\t\tonComplete?.()\n\t\t\tremoveInput()\n\t\t},\n\t)\n}\n\nexport function previewImage(\n\tthis: MiniAppContext,\n\t{ urls, current, success, complete }: { urls?: string[]; current?: string; success?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\n\tif (!urls || urls.length === 0) {\n\t\tonComplete?.()\n\t\treturn\n\t}\n\n\t// Simple overlay preview\n\tconst overlay = document.createElement('div')\n\toverlay.style.cssText =\n\t\t'position:fixed;inset:0;z-index:99999;background:rgba(0,0,0,.85);display:flex;align-items:center;justify-content:center;cursor:pointer;'\n\tconst img = document.createElement('img')\n\timg.src = current || urls[0] || ''\n\timg.style.cssText = 'max-width:90%;max-height:90%;object-fit:contain;'\n\toverlay.appendChild(img)\n\toverlay.addEventListener('click', () => overlay.remove())\n\tdocument.body.appendChild(overlay)\n\n\tonSuccess?.({ errMsg: 'previewImage:ok' })\n\tonComplete?.()\n}\n\nexport function compressImage(\n\tthis: MiniAppContext,\n\t{ src, quality = 80, success, fail, complete }: {\n\t\tsrc: string\n\t\tquality?: number\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\n\tconst img = new Image()\n\timg.crossOrigin = 'anonymous'\n\timg.onload = () => {\n\t\ttry {\n\t\t\tconst canvas = document.createElement('canvas')\n\t\t\tcanvas.width = img.naturalWidth\n\t\t\tcanvas.height = img.naturalHeight\n\t\t\tconst ctx = canvas.getContext('2d')!\n\t\t\tctx.drawImage(img, 0, 0)\n\t\t\tcanvas.toBlob(\n\t\t\t\t(blob) => {\n\t\t\t\t\tif (blob) {\n\t\t\t\t\t\tconst tempFilePath = createTempFilePath(blob)\n\t\t\t\t\t\tonSuccess?.({ tempFilePath, errMsg: 'compressImage:ok' })\n\t\t\t\t\t} else {\n\t\t\t\t\t\tonFail?.({ errMsg: 'compressImage:fail compression error' })\n\t\t\t\t\t}\n\t\t\t\t\tonComplete?.()\n\t\t\t\t},\n\t\t\t\t'image/jpeg',\n\t\t\t\tquality / 100,\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tonFail?.({ errMsg: `compressImage:fail ${(error as Error).message}` })\n\t\t\tonComplete?.()\n\t\t}\n\t}\n\timg.onerror = () => {\n\t\tonFail?.({ errMsg: 'compressImage:fail image load error' })\n\t\tonComplete?.()\n\t}\n\timg.src = src\n}\n\nexport function saveImageToPhotosAlbum(\n\tthis: MiniAppContext,\n\t{ filePath, success, fail, complete }: { filePath: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\n\tconst triggerDownload = (href: string) => {\n\t\tconst a = document.createElement('a')\n\t\ta.href = href\n\t\ta.download = 'image'\n\t\ta.click()\n\t}\n\n\tif (typeof filePath === 'string' && filePath.startsWith('difile://_tmp/')) {\n\t\t// The simulator's temp-file scheme (chooseImage / chooseMedia /\n\t\t// compressImage mint these via createTempFilePath): the bytes live in\n\t\t// the renderer Blob registry, so resolution is async. The async branch\n\t\t// owns its whole verdict \u2014 success/fail strictly before complete.\n\t\tresolveTempFilePath(filePath)\n\t\t\t.then(\n\t\t\t\tblob =>\n\t\t\t\t\tnew Promise<string>((resolve, reject) => {\n\t\t\t\t\t\tconst reader = new FileReader()\n\t\t\t\t\t\treader.onerror = () => reject(reader.error ?? new Error('blob read failed'))\n\t\t\t\t\t\treader.onload = () => resolve(String(reader.result))\n\t\t\t\t\t\treader.readAsDataURL(blob)\n\t\t\t\t\t}),\n\t\t\t)\n\t\t\t.then(\n\t\t\t\t(href) => {\n\t\t\t\t\ttriggerDownload(href)\n\t\t\t\t\tonSuccess?.({ errMsg: 'saveImageToPhotosAlbum:ok' })\n\t\t\t\t\tonComplete?.()\n\t\t\t\t},\n\t\t\t\t(err: unknown) => {\n\t\t\t\t\tconst msg = err instanceof Error ? err.message : String(err)\n\t\t\t\t\tonFail?.({ errMsg: `saveImageToPhotosAlbum:fail ${msg}` })\n\t\t\t\t\tonComplete?.()\n\t\t\t\t},\n\t\t\t)\n\t\treturn\n\t}\n\n\ttry {\n\t\tif (typeof filePath === 'string' && filePath.startsWith('difile://')) {\n\t\t\tconst bytes = readVPathBytesSync(filePath)\n\t\t\tif (bytes) {\n\t\t\t\t// A data: href keeps the whole verdict synchronous (success before\n\t\t\t\t// complete) without needing URL.createObjectURL.\n\t\t\t\ttriggerDownload(`data:application/octet-stream;base64,${bytes.toString('base64')}`)\n\t\t\t\tonSuccess?.({ errMsg: 'saveImageToPhotosAlbum:ok' })\n\t\t\t} else {\n\t\t\t\tonFail?.({ errMsg: 'saveImageToPhotosAlbum:fail no such file' })\n\t\t\t}\n\t\t} else {\n\t\t\t// Real dimina clients (Android / iOS / Harmony) only accept a local\n\t\t\t// file path \u2014 a dataURL, remote http(s) URL, or blob: URL (which no\n\t\t\t// simulator code path ever mints as a filePath) fails on device, so\n\t\t\t// the simulator must not \"succeed\" on it either.\n\t\t\tonFail?.({ errMsg: 'saveImageToPhotosAlbum:fail invalid file path' })\n\t\t}\n\t} catch (error) {\n\t\tonFail?.({ errMsg: `saveImageToPhotosAlbum:fail ${(error as Error).message}` })\n\t}\n\tonComplete?.()\n}\n\nexport function getImageInfo(\n\tthis: MiniAppContext,\n\t{ src, success, fail, complete }: { src: string; success?: unknown; fail?: unknown; complete?: unknown },\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\n\tconst img = new Image()\n\timg.crossOrigin = 'anonymous'\n\timg.onload = () => {\n\t\tonSuccess?.({\n\t\t\twidth: img.naturalWidth,\n\t\t\theight: img.naturalHeight,\n\t\t\tpath: src,\n\t\t\torientation: 'up',\n\t\t\ttype: 'unknown',\n\t\t\terrMsg: 'getImageInfo:ok',\n\t\t})\n\t\tonComplete?.()\n\t}\n\timg.onerror = () => {\n\t\tonFail?.({ errMsg: 'getImageInfo:fail image load error' })\n\t\tonComplete?.()\n\t}\n\timg.src = src\n}\n\n// \u2500\u2500\u2500 Media: Video \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype MediaFileType = 'image' | 'video'\ntype ChooseMediaCamera = 'back' | 'front'\n\nconst VIDEO_METADATA_TIMEOUT_MS = 5000\nconst VIDEO_THUMBNAIL_TIMEOUT_MS = 500\n\ninterface ChooseMediaTempFile {\n\ttempFilePath: string\n\tsize: number\n\tduration: number\n\theight: number\n\twidth: number\n\tthumbTempFilePath: string\n\tfileType: MediaFileType\n\toriginalFileObj: File\n}\n\nfunction normalizeStringArray(value: unknown, fallback: string[]): string[] {\n\treturn Array.isArray(value)\n\t\t? value.filter((item): item is string => typeof item === 'string')\n\t\t: fallback\n}\n\nfunction normalizeChooseMediaCount(value: unknown): number {\n\tconst n = Number(value)\n\tif (!Number.isFinite(n)) return 9\n\treturn Math.max(1, Math.min(20, Math.floor(n)))\n}\n\nfunction getChooseMediaAccept(mediaType: string[]): string {\n\tconst wantsMix = mediaType.includes('mix')\n\tconst wantsImage = wantsMix || mediaType.includes('image')\n\tconst wantsVideo = wantsMix || mediaType.includes('video')\n\tif (wantsImage && wantsVideo) return 'image/*,video/*'\n\treturn wantsVideo ? 'video/*' : 'image/*'\n}\n\nfunction getChooseMediaResultType(files: ChooseMediaTempFile[]): 'image' | 'video' | 'mix' {\n\tconst types = new Set(files.map(file => file.fileType))\n\tif (types.size > 1) return 'mix'\n\treturn files[0]?.fileType ?? 'image'\n}\n\nfunction readImageMetadata(src: string): Promise<{ width: number; height: number }> {\n\treturn new Promise((resolve) => {\n\t\tconst img = new Image()\n\t\timg.onload = () => resolve({ width: img.naturalWidth || 0, height: img.naturalHeight || 0 })\n\t\timg.onerror = () => resolve({ width: 0, height: 0 })\n\t\timg.src = src\n\t})\n}\n\nfunction readVideoMetadata(src: string): Promise<{ width: number; height: number; duration: number; thumbTempFilePath: string }> {\n\treturn new Promise((resolve) => {\n\t\tconst video = document.createElement('video')\n\t\tlet settled = false\n\t\tlet seekTimer: ReturnType<typeof setTimeout> | undefined\n\t\tconst finish = (metadata: { width: number; height: number; duration: number; thumbTempFilePath: string }) => {\n\t\t\tif (settled) return\n\t\t\tsettled = true\n\t\t\tclearTimeout(timer)\n\t\t\tif (seekTimer) clearTimeout(seekTimer)\n\t\t\t// Detach handlers so any late-firing DOM events (e.g. onseeked from a\n\t\t\t// previously queued currentTime change) cannot reach into the now-\n\t\t\t// resolved promise and allocate fresh blob: URLs.\n\t\t\tvideo.onloadedmetadata = null\n\t\t\tvideo.onseeked = null\n\t\t\tvideo.onerror = null\n\t\t\tvideo.removeAttribute('src')\n\t\t\tvideo.load()\n\t\t\tresolve(metadata)\n\t\t}\n\t\tconst drawThumbnail = (width: number, height: number): Promise<string> => {\n\t\t\treturn new Promise((resolveThumb) => {\n\t\t\t\tlet resolved = false\n\t\t\t\tconst done = (value: string) => {\n\t\t\t\t\tif (resolved) return\n\t\t\t\t\tresolved = true\n\t\t\t\t\tresolveThumb(value)\n\t\t\t\t}\n\t\t\t\tlet canvas: HTMLCanvasElement\n\t\t\t\ttry {\n\t\t\t\t\tcanvas = document.createElement('canvas')\n\t\t\t\t\tcanvas.width = width || 1\n\t\t\t\t\tcanvas.height = height || 1\n\t\t\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\t\t\tctx?.drawImage(video, 0, 0, canvas.width, canvas.height)\n\t\t\t\t} catch {\n\t\t\t\t\tdone('')\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst toDataUrlFallback = () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdone(canvas.toDataURL('image/jpeg', 0.8))\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tdone('')\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst fallbackTimer = setTimeout(toDataUrlFallback, VIDEO_THUMBNAIL_TIMEOUT_MS)\n\t\t\t\ttry {\n\t\t\t\t\tcanvas.toBlob(\n\t\t\t\t\t\t(blob) => {\n\t\t\t\t\t\t\tclearTimeout(fallbackTimer)\n\t\t\t\t\t\t\t// If the outer readVideoMetadata promise already settled\n\t\t\t\t\t\t\t// (e.g. the seekTimer fired before toBlob's async callback\n\t\t\t\t\t\t\t// arrived), we MUST NOT call createTempFilePath here \u2014 that\n\t\t\t\t\t\t\t// would allocate a fresh blob: URL and register it in the\n\t\t\t\t\t\t\t// temp-files Map with no one ever revoking it. Just drop\n\t\t\t\t\t\t\t// the blob on the floor; the resolved thumbTempFilePath\n\t\t\t\t\t\t\t// has already been chosen by the timeout path.\n\t\t\t\t\t\t\tif (settled || resolved) return\n\t\t\t\t\t\t\tif (blob) {\n\t\t\t\t\t\t\t\tdone(createTempFilePath(blob))\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttoDataUrlFallback()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t'image/jpeg',\n\t\t\t\t\t\t0.8,\n\t\t\t\t\t)\n\t\t\t\t} catch {\n\t\t\t\t\tclearTimeout(fallbackTimer)\n\t\t\t\t\ttoDataUrlFallback()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tconst timer = setTimeout(() => finish({ width: 0, height: 0, duration: 0, thumbTempFilePath: '' }), VIDEO_METADATA_TIMEOUT_MS)\n\n\t\tvideo.preload = 'metadata'\n\t\tvideo.muted = true\n\t\tvideo.onloadedmetadata = () => {\n\t\t\tconst width = video.videoWidth || 0\n\t\t\tconst height = video.videoHeight || 0\n\t\t\tconst duration = Number.isFinite(video.duration) ? video.duration : 0\n\t\t\tconst metadata = { width, height, duration, thumbTempFilePath: '' }\n\t\t\tif (!width || !height || duration <= 0) {\n\t\t\t\tfinish(metadata)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tvideo.onseeked = async () => {\n\t\t\t\tif (seekTimer) {\n\t\t\t\t\tclearTimeout(seekTimer)\n\t\t\t\t\tseekTimer = undefined\n\t\t\t\t}\n\t\t\t\tconst thumbTempFilePath = await drawThumbnail(width, height)\n\t\t\t\tfinish({ ...metadata, thumbTempFilePath })\n\t\t\t}\n\t\t\tseekTimer = setTimeout(() => finish(metadata), VIDEO_THUMBNAIL_TIMEOUT_MS)\n\t\t\ttry {\n\t\t\t\tvideo.currentTime = Math.min(0.1, Math.max(0, duration - 0.01))\n\t\t\t} catch {\n\t\t\t\tfinish(metadata)\n\t\t\t}\n\t\t}\n\t\tvideo.onerror = () => finish({ width: 0, height: 0, duration: 0, thumbTempFilePath: '' })\n\t\tvideo.src = src\n\t})\n}\n\nasync function buildChooseMediaTempFile(file: File): Promise<ChooseMediaTempFile> {\n\tconst tempFilePath = createTempFilePath(file)\n\tconst fileType: MediaFileType = file.type.startsWith('video') ? 'video' : 'image'\n\n\tif (fileType === 'video') {\n\t\tconst metadata = await readVideoMetadata(tempFilePath)\n\t\treturn {\n\t\t\ttempFilePath,\n\t\t\tsize: file.size,\n\t\t\tduration: metadata.duration,\n\t\t\theight: metadata.height,\n\t\t\twidth: metadata.width,\n\t\t\tthumbTempFilePath: metadata.thumbTempFilePath,\n\t\t\tfileType,\n\t\t\toriginalFileObj: file,\n\t\t}\n\t}\n\n\tconst metadata = await readImageMetadata(tempFilePath)\n\treturn {\n\t\ttempFilePath,\n\t\tsize: file.size,\n\t\tduration: 0,\n\t\theight: metadata.height,\n\t\twidth: metadata.width,\n\t\tthumbTempFilePath: '',\n\t\tfileType,\n\t\toriginalFileObj: file,\n\t}\n}\n\nexport function chooseMedia(\n\tthis: MiniAppContext,\n\t{ count = 9, mediaType = ['image', 'video'], sourceType = ['album', 'camera'], camera = 'back', success, fail, complete }: {\n\t\tcount?: number\n\t\tmediaType?: unknown\n\t\tsourceType?: unknown\n\t\tmaxDuration?: unknown\n\t\tsizeType?: unknown\n\t\tcamera?: ChooseMediaCamera\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onFail, onComplete } = cbs\n\tconst normalizedCount = normalizeChooseMediaCount(count)\n\tconst normalizedMediaType = normalizeStringArray(mediaType, ['image', 'video'])\n\tconst normalizedSourceType = normalizeStringArray(sourceType, ['album', 'camera'])\n\n\tcreateFilePicker(\n\t\t'chooseMedia',\n\t\t{\n\t\t\taccept: getChooseMediaAccept(normalizedMediaType),\n\t\t\tmultiple: normalizedCount > 1,\n\t\t\tcapture: captureAttrFor(normalizedSourceType, camera),\n\t\t},\n\t\tcbs,\n\t\tasync (rawFiles, removeInput) => {\n\t\t\tconst files = rawFiles.slice(0, normalizedCount)\n\t\t\ttry {\n\t\t\t\tconst tempFiles = await Promise.all(files.map(buildChooseMediaTempFile))\n\t\t\t\tonSuccess?.({\n\t\t\t\t\ttempFiles,\n\t\t\t\t\ttype: getChooseMediaResultType(tempFiles),\n\t\t\t\t\tfailedCount: 0,\n\t\t\t\t\terrMsg: 'chooseMedia:ok',\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tonFail?.({ errMsg: `chooseMedia:fail ${(error as Error).message}` })\n\t\t\t} finally {\n\t\t\t\tonComplete?.()\n\t\t\t\tremoveInput()\n\t\t\t}\n\t\t},\n\t)\n}\n\nexport function chooseVideo(\n\tthis: MiniAppContext,\n\t{ sourceType, camera, success, fail, complete }: {\n\t\tsourceType?: unknown\n\t\tcompressed?: unknown\n\t\tmaxDuration?: unknown\n\t\tcamera?: unknown\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\tconst { onSuccess, onComplete } = cbs\n\tconst normalizedSourceType = normalizeStringArray(sourceType, ['album', 'camera'])\n\n\tcreateFilePicker(\n\t\t'chooseVideo',\n\t\t{ accept: 'video/*', multiple: false, capture: captureAttrFor(normalizedSourceType, camera) },\n\t\tcbs,\n\t\tasync (files, removeInput) => {\n\t\t\tconst file = files[0]!\n\t\t\tconst tempFilePath = createTempFilePath(file)\n\t\t\tconst metadata = await readVideoMetadata(tempFilePath)\n\t\t\tonSuccess?.({\n\t\t\t\ttempFilePath,\n\t\t\t\tduration: metadata.duration,\n\t\t\t\tsize: file.size,\n\t\t\t\twidth: metadata.width,\n\t\t\t\theight: metadata.height,\n\t\t\t\terrMsg: 'chooseVideo:ok',\n\t\t\t})\n\t\t\tonComplete?.()\n\t\t\tremoveInput()\n\t\t},\n\t)\n}\n\n// \u2500\u2500\u2500 Media: Audio (container-side handlers for service-apis/audio) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// service-apis/audio/index.js (injected into the service Worker by the dimina\n// container bundle) calls invokeAPI('audioCreate', { audioId }), etc. DOM media\n// events on the container's HTMLAudioElement are bridged back to the service\n// layer via the `audioListen` handler.\n\n/** Payload delivered to the service-side dispatcher on every audio event. */\ninterface AudioEventPayload {\n\tevent: string\n\tcurrentTime: number\n\tduration: number\n\tbuffered: number\n\tpaused: boolean\n}\n\n/** DOM media event name \u2192 mini-program audio event name. */\nconst AUDIO_EVENT_MAP: Record<string, string> = {\n\tplay: 'play',\n\tpause: 'pause',\n\tended: 'ended',\n\terror: 'error',\n\ttimeupdate: 'timeUpdate',\n\twaiting: 'waiting',\n\tseeking: 'seeking',\n\tseeked: 'seeked',\n\tcanplay: 'canplay',\n}\n\nconst _newAudioInstances = new Map<number, HTMLAudioElement>()\n/** Disposers that unbind the DOM event bridge for a given audio instance. */\nconst _audioEventDisposers = new Map<number, EventBridgeDisposer>()\n/** The service-side dispatcher callback for a given audio instance. */\nconst _audioFire = new Map<number, (payload: AudioEventPayload) => void>()\n\n/** Snapshot the current playback state of an audio element. */\nfunction audioSnapshot(audio: HTMLAudioElement, event: string): AudioEventPayload {\n\treturn {\n\t\tevent,\n\t\tcurrentTime: audio.currentTime || 0,\n\t\tduration: Number.isFinite(audio.duration) ? audio.duration : 0,\n\t\tbuffered: audio.buffered.length ? audio.buffered.end(audio.buffered.length - 1) : 0,\n\t\tpaused: audio.paused,\n\t}\n}\n\nexport function audioCreate(this: MiniAppContext, { audioId }: { audioId: number }) {\n\t_newAudioInstances.set(audioId, new Audio())\n}\n\n/**\n * Persistent event-bridge registration. The service-side InnerAudioContext\n * calls this once at construction with a `keep: true` callback; the container\n * resolves a `fire` callback and binds the DOM media events of the matching\n * audio element to it.\n *\n * The dimina service `invokeAPI` runs every callback through\n * `callback.store(success, keep, evtId)` and delivers the resulting callback\n * id under the `success` field of `params` \u2014 `evtId` itself is consumed by\n * `callback.store` and never reaches the container payload. So the handler\n * resolves `fire` from `success`, exactly like every other media API.\n */\nexport function audioListen(this: MiniAppContext, { audioId, success }: { audioId: number; success: unknown }) {\n\tconst audio = _newAudioInstances.get(audioId)\n\tconst fire = this.createCallbackFunction(success) as ((payload: AudioEventPayload) => void) | undefined\n\tif (!audio || !fire) return\n\n\t_audioFire.set(audioId, fire)\n\n\t// Rebind cleanly if audioListen is somehow called twice for one instance.\n\t_audioEventDisposers.get(audioId)?.()\n\tconst dispose = bindDomEvents<AudioEventPayload>(\n\t\taudio,\n\t\tAUDIO_EVENT_MAP,\n\t\tfire,\n\t\tevent => audioSnapshot(audio, event),\n\t)\n\t_audioEventDisposers.set(audioId, dispose)\n}\n\nexport function audioSetProp(\n\tthis: MiniAppContext,\n\t{ audioId, prop, value, startTime, loop, volume, playbackRate, autoplay }: {\n\t\taudioId: number\n\t\tprop: string\n\t\tvalue: unknown\n\t\tstartTime?: number\n\t\tloop?: boolean\n\t\tvolume?: number\n\t\tplaybackRate?: number\n\t\tautoplay?: boolean\n\t},\n) {\n\tconst audio = _newAudioInstances.get(audioId)\n\tif (!audio) return\n\tswitch (prop) {\n\t\tcase 'src':\n\t\t\taudio.src = value as string\n\t\t\tif (startTime != null) audio.currentTime = startTime\n\t\t\tif (loop != null) audio.loop = loop\n\t\t\tif (volume != null) audio.volume = Math.max(0, Math.min(1, volume))\n\t\t\tif (playbackRate != null) audio.playbackRate = playbackRate\n\t\t\tif (autoplay) audio.play().catch(() => {})\n\t\t\tbreak\n\t\tcase 'startTime': audio.currentTime = Number(value) || 0; break\n\t\tcase 'autoplay': audio.autoplay = !!value; break\n\t\tcase 'loop': audio.loop = !!value; break\n\t\tcase 'volume': audio.volume = Math.max(0, Math.min(1, Number(value) || 0)); break\n\t\tcase 'playbackRate': audio.playbackRate = Number(value) || 1; break\n\t}\n}\n\nexport function audioPlay(this: MiniAppContext, { audioId, src }: { audioId: number; src?: string }) {\n\tconst audio = _newAudioInstances.get(audioId)\n\tif (!audio) return\n\tif (src && audio.src !== src) audio.src = src\n\taudio.play().catch(() => {})\n}\n\nexport function audioPause(this: MiniAppContext, { audioId }: { audioId: number }) {\n\t_newAudioInstances.get(audioId)?.pause()\n}\n\nexport function audioStop(this: MiniAppContext, { audioId }: { audioId: number }) {\n\tconst audio = _newAudioInstances.get(audioId)\n\tif (!audio) return\n\taudio.pause()\n\taudio.currentTime = 0\n\t// `stop` has no DOM equivalent \u2014 synthesise it through the bridge.\n\t_audioFire.get(audioId)?.(audioSnapshot(audio, 'stop'))\n}\n\nexport function audioSeek(this: MiniAppContext, { audioId, position }: { audioId: number; position: number }) {\n\tconst audio = _newAudioInstances.get(audioId)\n\tif (!audio) return\n\taudio.currentTime = position\n}\n\nexport function audioDestroy(this: MiniAppContext, { audioId }: { audioId: number }) {\n\t_audioEventDisposers.get(audioId)?.()\n\t_audioEventDisposers.delete(audioId)\n\t_audioFire.delete(audioId)\n\n\tconst audio = _newAudioInstances.get(audioId)\n\tif (!audio) return\n\taudio.pause()\n\taudio.removeAttribute('src')\n\taudio.load()\n\t_newAudioInstances.delete(audioId)\n}\n", "/**\n * Container-side handlers for the `FileSystemManager.*` invokeAPI wire names.\n *\n * The service thread's FileSystemManager (upstream\n * `service/src/api/core/file/index.js`, overlaid by the devtools\n * `service-apis/file/index.js` shim at container build time) invokes the\n * container with dotted wire names \u2014 `FileSystemManager.writeFile`, \u2026 \u2014 and\n * speaks the upstream transport protocol:\n *\n * - write-class `data` arrives either as a plain string or as a\n * `{ __diminaFileDataType: 'base64', __diminaFileDataBase64 }` sentinel\n * (the service side's postMessage-safe ArrayBuffer encoding);\n * - binary `readFile` results travel back as `{ __diminaArrayBufferBase64 }`\n * for the service side to decode into an ArrayBuffer;\n * - errMsg uses the wx short name (`writeFile:ok`), matching what real\n * dimina clients (Android / iOS / Harmony FileSystemManager backends)\n * report to mini-program code.\n *\n * Each handler adapts that wire shape onto the `fs*` implementations in\n * `simulator-api-fs.ts`, which own path resolution (single vpath resolver)\n * and the actual Node fs work.\n */\n\nimport type { MiniAppContext } from './types'\nimport { getNodeBindings } from '../shared/node-bindings.js'\nimport { bindCallbacks } from './simulator-api-helpers'\nimport {\n\tfsAccess,\n\tfsStat,\n\tfsReadFile,\n\tfsWriteFile,\n\tfsAppendFile,\n\tfsCopyFile,\n\tfsRename,\n\tfsUnlink,\n\tfsMkdir,\n\tfsRmdir,\n\tfsReaddir,\n\tfsGetFileInfo,\n\tfsSaveFile,\n\tfsGetSavedFileList,\n\tfsRemoveSavedFile,\n\tfsTruncate,\n} from './simulator-api-fs'\n\n/** Sentinel keys of the service-side transport protocol (see upstream `service/src/api/core/file/index.js`). */\nconst ARRAY_BUFFER_BASE64_KEY = '__diminaArrayBufferBase64'\nconst FILE_DATA_TYPE_KEY = '__diminaFileDataType'\nconst FILE_DATA_BASE64_KEY = '__diminaFileDataBase64'\n\ntype WireParams = Record<string, unknown>\n\n/**\n * An `fs*` impl as seen from the untyped wire boundary. Each impl validates\n * its own fields (path resolution, data types), so the adapter hands the\n * whole params object through unchecked.\n */\ntype FsHandler = (this: MiniAppContext, opts: WireParams) => void\n\ninterface FsmAdapterSpec {\n\t/** wx short method name \u2014 also the errMsg prefix the service side expects. */\n\tshort: string\n\timpl: FsHandler\n\t/** Decode a base64 write-payload sentinel in `data` before the impl runs. */\n\tdecodeWriteData?: boolean\n\t/** Encode a binary success `data` into the ArrayBuffer base64 sentinel. */\n\tencodeReadResult?: boolean\n}\n\nconst FSM_ADAPTERS: FsmAdapterSpec[] = [\n\t{ short: 'access', impl: fsAccess as FsHandler },\n\t{ short: 'stat', impl: fsStat as FsHandler },\n\t{ short: 'readFile', impl: fsReadFile as FsHandler, encodeReadResult: true },\n\t{ short: 'writeFile', impl: fsWriteFile as FsHandler, decodeWriteData: true },\n\t{ short: 'appendFile', impl: fsAppendFile as FsHandler, decodeWriteData: true },\n\t{ short: 'copyFile', impl: fsCopyFile as FsHandler },\n\t{ short: 'rename', impl: fsRename as FsHandler },\n\t{ short: 'unlink', impl: fsUnlink as FsHandler },\n\t{ short: 'mkdir', impl: fsMkdir as FsHandler },\n\t{ short: 'rmdir', impl: fsRmdir as FsHandler },\n\t{ short: 'readdir', impl: fsReaddir as FsHandler },\n\t{ short: 'getFileInfo', impl: fsGetFileInfo as FsHandler },\n\t{ short: 'saveFile', impl: fsSaveFile as FsHandler },\n\t{ short: 'getSavedFileList', impl: fsGetSavedFileList as FsHandler },\n\t{ short: 'removeSavedFile', impl: fsRemoveSavedFile as FsHandler },\n\t{ short: 'truncate', impl: fsTruncate as FsHandler },\n]\n\n/** The `fs*` impls report `fsWriteFile:ok` \u2014 the legacy internal prefix for a given wx short name. */\nfunction legacyPrefix(short: string): string {\n\treturn `fs${short[0]!.toUpperCase()}${short.slice(1)}`\n}\n\n/** Rewrites a payload's `errMsg` from the internal `fs*` prefix to the wx short name. */\nfunction renameErrMsg(payload: unknown, legacy: string, short: string): unknown {\n\tif (!payload || typeof payload !== 'object') return payload\n\tconst rec = payload as WireParams\n\tif (typeof rec.errMsg === 'string' && rec.errMsg.startsWith(`${legacy}:`)) {\n\t\treturn { ...rec, errMsg: `${short}:${rec.errMsg.slice(legacy.length + 1)}` }\n\t}\n\treturn payload\n}\n\n/**\n * `Buffer` for the base64 codec: the simulator document has no global\n * `Buffer` (nodeIntegration is off), so take it from the preload-published\n * node bindings; vitest/node contexts have the global.\n */\nconst BufferImpl: typeof Buffer | undefined =\n\tgetNodeBindings().buffer?.Buffer ?? (typeof Buffer !== 'undefined' ? Buffer : undefined)\n\n/** Decodes the service side's base64 write-payload sentinel into bytes; passes any other value through. */\nfunction decodeFileData(data: unknown): unknown {\n\tif (!BufferImpl) return data\n\tif (!data || typeof data !== 'object') return data\n\tconst rec = data as WireParams\n\tif (rec[FILE_DATA_TYPE_KEY] !== 'base64' || typeof rec[FILE_DATA_BASE64_KEY] !== 'string') return data\n\treturn BufferImpl.from(rec[FILE_DATA_BASE64_KEY] as string, 'base64')\n}\n\n/**\n * Wraps a binary success `data` (Buffer/typed array) in the ArrayBuffer\n * base64 sentinel; strings pass through. `ArrayBuffer.isView` is a brand\n * check that holds across realms \u2014 an `instanceof Uint8Array` test would\n * miss Node `Buffer`s when this module is evaluated under a DOM realm.\n */\nfunction encodeReadResult(payload: unknown): unknown {\n\tif (!BufferImpl) return payload\n\tif (!payload || typeof payload !== 'object') return payload\n\tconst rec = payload as WireParams\n\tconst data = rec.data\n\tif (typeof data === 'string' || !ArrayBuffer.isView(data)) return payload\n\tconst bytes = BufferImpl.from(data.buffer, data.byteOffset, data.byteLength)\n\treturn { ...rec, data: { [ARRAY_BUFFER_BASE64_KEY]: bytes.toString('base64') } }\n}\n\nfunction makeFsmHandler(spec: FsmAdapterSpec): (this: MiniAppContext, params?: unknown) => void {\n\tconst legacy = legacyPrefix(spec.short)\n\treturn function (this: MiniAppContext, params?: unknown) {\n\t\tconst raw: WireParams =\n\t\t\tparams && typeof params === 'object' && !Array.isArray(params)\n\t\t\t\t? { ...(params as WireParams) }\n\t\t\t\t: {}\n\t\tconst { success, fail, complete, ...rest } = raw\n\t\t// Resolve the caller's callbacks through THIS context (on the production\n\t\t// bridge they are sentinel ids only runApiAsync's patched\n\t\t// createCallbackFunction understands).\n\t\tconst cbs = bindCallbacks(this, { success, fail, complete })\n\n\t\tconst opts: WireParams = rest\n\t\tif (spec.decodeWriteData && 'data' in opts) {\n\t\t\topts.data = decodeFileData(opts.data)\n\t\t}\n\t\t// Terminal guards: exactly one success/fail verdict and one complete per\n\t\t// call. A synchronous throw inside the impl (e.g. Node fs rejecting an\n\t\t// invalid `data` type) must surface as a short-name fail through the wx\n\t\t// callbacks \u2014 never propagate as an exception (the bridge would stamp it\n\t\t// with the dotted wire name) \u2014 and any late async callback the impl\n\t\t// still fires after that is dropped here.\n\t\tlet verdictFired = false\n\t\tlet completeFired = false\n\t\tconst fireSuccess = (out: unknown) => {\n\t\t\tif (verdictFired) return\n\t\t\tverdictFired = true\n\t\t\tcbs.onSuccess?.(out)\n\t\t}\n\t\tconst fireFail = (out: unknown) => {\n\t\t\tif (verdictFired) return\n\t\t\tverdictFired = true\n\t\t\tcbs.onFail?.(out)\n\t\t}\n\t\tconst fireComplete = () => {\n\t\t\tif (completeFired) return\n\t\t\tcompleteFired = true\n\t\t\tcbs.onComplete?.()\n\t\t}\n\t\topts.success = (res: unknown) => {\n\t\t\tlet out = renameErrMsg(res, legacy, spec.short)\n\t\t\tif (spec.encodeReadResult) out = encodeReadResult(out)\n\t\t\tfireSuccess(out)\n\t\t}\n\t\topts.fail = (res: unknown) => {\n\t\t\tfireFail(renameErrMsg(res, legacy, spec.short))\n\t\t}\n\t\topts.complete = fireComplete\n\n\t\t// The impl re-resolves its callbacks via ctx.createCallbackFunction, and\n\t\t// the production bridge's patched createCallbackFunction only understands\n\t\t// sentinel ids \u2014 hand the impl a derived context that passes the plain\n\t\t// interceptor functions above straight through.\n\t\tconst innerCtx = Object.create(this as object) as MiniAppContext\n\t\tinnerCtx.createCallbackFunction = (fn: unknown) =>\n\t\t\ttypeof fn === 'function' ? (fn as (...args: unknown[]) => void) : undefined\n\t\ttry {\n\t\t\tspec.impl.call(innerCtx, opts)\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err)\n\t\t\tfireFail({ errMsg: `${spec.short}:fail ${msg}` })\n\t\t\tfireComplete()\n\t\t}\n\t}\n}\n\nconst handlers: Record<string, (this: MiniAppContext, params?: unknown) => void> = {}\nfor (const spec of FSM_ADAPTERS) {\n\thandlers[`FileSystemManager.${spec.short}`] = makeFsmHandler(spec)\n}\n\n/** Registered 1:1 into `simulatorApis` \u2014 the keys are the invokeAPI wire names. */\nexport const fileSystemManagerApis = handlers\n", "/**\n * Runtime-owned authoritative implementation of wx.request network semantics, shared\n * by every request surface (simulator `directRequest`, preload api-compat\n * `wx.request` shim). Keeping the semantics in one module is what prevents the\n * surfaces from drifting apart on the core contract.\n *\n * The contract (official wx.request semantics):\n * - success vs fail is decided ONLY by whether a server response was\n * received. Any HTTP response \u2014 200, 401, 500 \u2014 resolves via `success`\n * with `{ data, statusCode, header, errMsg: 'request:ok' }`; callers\n * branch on `statusCode` (e.g. 401 \u2192 re-login).\n * - `fail` fires only for network-layer failures and always carries a\n * non-empty errMsg: 'request:fail timeout' (deadline hit),\n * 'request:fail abort' (caller aborted), 'request:fail <reason>' (DNS/\n * connection/protocol errors).\n * - `timeout` defaults to 60000ms (the wx default) when omitted or\n * non-positive \u2014 a request never hangs indefinitely.\n * - `dataType` (default 'json') controls body decoding: 'json' attempts\n * JSON.parse with raw-text fallback; anything else keeps raw text.\n * `responseType: 'arraybuffer'` (or the legacy `dataType: 'arraybuffer'`\n * spelling) yields an ArrayBuffer instead.\n * - Outgoing headers merge case-insensitively via `Headers` so a caller's\n * `content-type` in any casing wins exactly once; the `application/json`\n * default applies only when the caller supplied none. Plain-object merges\n * would keep both casings as distinct keys and comma-join them on the wire.\n * - GET/HEAD serialize object `data` into URL query params (no body);\n * other methods send string data verbatim, form-encode objects under\n * application/x-www-form-urlencoded, and JSON-encode otherwise.\n * - `complete` fires exactly once, after success or fail, with that same\n * result object.\n *\n * Not provided: `cookies` on the success result \u2014 fetch() cannot read\n * Set-Cookie response headers, so surfacing a fabricated list would lie.\n */\n\nexport interface RequestSuccessResult {\n data: unknown\n statusCode: number\n header: Record<string, string>\n errMsg: 'request:ok'\n}\n\nexport interface RequestFailResult {\n errMsg: string\n errno?: number\n}\n\nexport interface RequestHandle {\n abort(): void\n}\n\nexport interface RequestCoreOptions {\n url: string\n data?: unknown\n header?: Record<string, string>\n timeout?: number\n method?: string\n dataType?: string\n responseType?: string\n}\n\nexport interface RequestCoreCallbacks {\n success?: (res: RequestSuccessResult) => void\n fail?: (err: RequestFailResult) => void\n complete?: (res: RequestSuccessResult | RequestFailResult) => void\n}\n\n/**\n * The wx.request default timeout budget. Exported as the single source of\n * truth for every layer that reasons about a request's time budget \u2014 the\n * bridge-router watchdog (apiCallWatchdogMs in simulator-api-metadata.ts)\n * derives its window from this so the two cannot drift apart.\n */\nexport const DEFAULT_REQUEST_TIMEOUT_MS = 60_000\n\n/**\n * Largest delay setTimeout honours (2^31-1 ms). Anything above overflows the\n * signed-32-bit timer register and fires ~immediately (~1ms) instead of late \u2014\n * so an oversized caller timeout must be rejected, never passed through.\n */\nexport const MAX_TIMEOUT_MS = 2_147_483_647\n\n/**\n * Resolve a caller-supplied wx timeout into a usable budget: a finite positive\n * number within setTimeout's range is honoured; anything else (absent, 0,\n * negative, NaN, Infinity, overflowing) falls back to the wx default. Shared\n * by performRequest and the bridge-router watchdog (apiCallWatchdogMs) so the\n * two layers can never disagree on what a valid timeout is.\n */\nexport function resolveTimeoutBudgetMs(timeout: unknown): number {\n const t = Number(timeout)\n return Number.isFinite(t) && t > 0 && t <= MAX_TIMEOUT_MS ? t : DEFAULT_REQUEST_TIMEOUT_MS\n}\n\nfunction buildHeaders(header: Record<string, string> | undefined): Headers {\n const headers = new Headers()\n for (const [key, value] of Object.entries(header ?? {})) {\n if (value != null) headers.set(key, String(value))\n }\n if (!headers.has('content-type')) headers.set('content-type', 'application/json')\n return headers\n}\n\nfunction appendQueryParams(url: string, data: Record<string, unknown>): string {\n // Resolve against the current document when available so page-relative URLs\n // keep working in the render-window shim.\n const base = typeof location !== 'undefined' ? location.href : undefined\n const resolved = new URL(url, base)\n for (const [key, value] of Object.entries(data)) {\n resolved.searchParams.append(key, String(value))\n }\n return resolved.toString()\n}\n\nfunction encodeBody(data: unknown, contentType: string): BodyInit {\n if (typeof data === 'string') return data\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const form = new URLSearchParams()\n for (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n form.append(key, String(value))\n }\n return form.toString()\n }\n return JSON.stringify(data)\n}\n\nasync function decodeResponseData(\n response: Response,\n dataType: string,\n responseType: string,\n): Promise<unknown> {\n if (responseType === 'arraybuffer' || dataType === 'arraybuffer') {\n return response.arrayBuffer()\n }\n const text = await response.text()\n if (dataType !== 'json') return text\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n}\n\nexport function performRequest(\n opts: RequestCoreOptions,\n callbacks: RequestCoreCallbacks,\n): RequestHandle {\n const method = (opts.method || 'GET').toUpperCase()\n const canHaveBody = method !== 'GET' && method !== 'HEAD'\n const headers = buildHeaders(opts.header)\n\n let url = opts.url\n const init: RequestInit = { method, headers }\n\n if (!canHaveBody) {\n if (opts.data && typeof opts.data === 'object') {\n url = appendQueryParams(url, opts.data as Record<string, unknown>)\n }\n } else if (opts.data != null) {\n init.body = encodeBody(opts.data, headers.get('content-type') ?? '')\n }\n\n const controller = new AbortController()\n init.signal = controller.signal\n\n // First verdict wins: a timeout/abort settles the call even though the fetch\n // promise is still pending, and the fetch's own late resolution/AbortError\n // rejection must not fire a second callback round.\n let settled = false\n\n function settleSuccess(res: RequestSuccessResult): void {\n if (settled) return\n settled = true\n clearTimeout(timer)\n callbacks.success?.(res)\n callbacks.complete?.(res)\n }\n\n function settleFail(err: RequestFailResult): void {\n if (settled) return\n settled = true\n clearTimeout(timer)\n callbacks.fail?.(err)\n callbacks.complete?.(err)\n }\n\n const timeoutMs = resolveTimeoutBudgetMs(opts.timeout)\n const timer = setTimeout(() => {\n settleFail({ errMsg: 'request:fail timeout' })\n controller.abort()\n }, timeoutMs)\n\n const dataType = opts.dataType ?? 'json'\n const responseType = opts.responseType ?? 'text'\n\n fetch(url, init)\n .then(async (response) => {\n const header: Record<string, string> = {}\n response.headers.forEach((value, key) => {\n header[key] = value\n })\n const data = await decodeResponseData(response, dataType, responseType)\n settleSuccess({ data, statusCode: response.status, header, errMsg: 'request:ok' })\n })\n .catch((error: unknown) => {\n const reason = error instanceof Error ? error.message : String(error)\n settleFail({ errMsg: `request:fail ${reason || 'network error'}` })\n })\n\n return {\n abort() {\n settleFail({ errMsg: 'request:fail abort' })\n controller.abort()\n },\n }\n}\n", "/**\n * DevTools API stubs for network-related wx.xxx APIs.\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi -> MiniApp.invokeApi).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks } from './simulator-api-helpers'\nimport { resolveTimeoutBudgetMs } from '../shared/request-core'\nimport { createTempFilePath, getTempFileName, resolveTempFilePath } from './temp-files'\n\nexport function downloadFile(\n\tthis: MiniAppContext,\n\t{ url, header = {}, filePath, timeout, success, fail, complete }: {\n\t\turl: string\n\t\theader?: Record<string, string>\n\t\tfilePath?: string\n\t\ttimeout?: number\n\t\tsuccess?: unknown\n\t\tfail?: unknown\n\t\tcomplete?: unknown\n\t},\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\n\t// The handler owns its own deadline: the bridge's no-handler watchdog is\n\t// disarmed by the handler-received ack, so a stalled network must be\n\t// bounded here (wx budget semantics, same authority as `request`). First\n\t// verdict wins \u2014 a late fetch settlement after the timeout fired must not\n\t// resurrect success or double-fire complete.\n\tlet settled = false\n\tconst settleFail = (errMsg: string) => {\n\t\tif (settled) return\n\t\tsettled = true\n\t\tclearTimeout(timer)\n\t\tonFail?.({ errMsg })\n\t\tonComplete?.()\n\t}\n\tconst settleOk = (result: Record<string, unknown>) => {\n\t\tif (settled) return\n\t\tsettled = true\n\t\tclearTimeout(timer)\n\t\tonSuccess?.(result)\n\t\tonComplete?.()\n\t}\n\tconst controller = new AbortController()\n\tconst timer = setTimeout(() => {\n\t\tsettleFail('downloadFile:fail timeout')\n\t\tcontroller.abort()\n\t}, resolveTimeoutBudgetMs(timeout))\n\n\tfetch(url, { headers: header, signal: controller.signal })\n\t\t.then(async (response) => {\n\t\t\tif (!response.ok) {\n\t\t\t\t// statusText is frequently empty (HTTP/2 has none) \u2014 the status\n\t\t\t\t// code is the reliable part of the failure reason.\n\t\t\t\tsettleFail(\n\t\t\t\t\t`downloadFile:fail HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ''}`,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst blob = await response.blob()\n\t\t\tconst tempFilePath = createTempFilePath(blob)\n\t\t\tsettleOk({\n\t\t\t\ttempFilePath,\n\t\t\t\tfilePath: filePath || tempFilePath,\n\t\t\t\tstatusCode: response.status,\n\t\t\t\terrMsg: 'downloadFile:ok',\n\t\t\t})\n\t\t})\n\t\t.catch((error: Error) => {\n\t\t\tsettleFail(`downloadFile:fail ${error.message}`)\n\t\t})\n}\n\ntype UploadFileOptions = {\n\turl: string\n\tfilePath: string\n\tname: string\n\theader?: Record<string, string>\n\tformData?: Record<string, unknown>\n\ttimeout?: number\n\tuploadId?: string\n\tprogress?: unknown\n\theadersReceived?: unknown\n\tsuccess?: unknown\n\tfail?: unknown\n\tcomplete?: unknown\n}\n\nconst uploadRequests = new Map<string, XMLHttpRequest>()\nconst uploadPendingResolves = new Set<string>()\nconst uploadAbortedBeforeStart = new Set<string>()\nlet nextUploadId = 1\n\nfunction createUploadId(): string {\n\treturn `upload_${Date.now()}_${nextUploadId++}`\n}\n\nfunction parseResponseHeaders(raw: string): Record<string, string> {\n\tconst headers: Record<string, string> = {}\n\tfor (const line of raw.trim().split(/[\\r\\n]+/)) {\n\t\tif (!line) continue\n\t\tconst index = line.indexOf(':')\n\t\tif (index <= 0) continue\n\t\tconst key = line.slice(0, index).trim()\n\t\tconst value = line.slice(index + 1).trim()\n\t\tif (key) headers[key] = value\n\t}\n\treturn headers\n}\n\nfunction appendFormData(form: FormData, formData: Record<string, unknown>): void {\n\tfor (const [key, value] of Object.entries(formData)) {\n\t\tif (value == null) continue\n\t\tif (value instanceof Blob) {\n\t\t\tform.append(key, value)\n\t\t} else if (typeof value === 'object') {\n\t\t\t// JSON.stringify for plain objects/arrays; Map/Set/RegExp/TypedArray\n\t\t\t// fall through here too and become '{}' or similar \u2014 caller should\n\t\t\t// pre-stringify if they need a specific form.\n\t\t\tform.append(key, JSON.stringify(value))\n\t\t} else {\n\t\t\tform.append(key, String(value))\n\t\t}\n\t}\n}\n\nexport function uploadFile(\n\tthis: MiniAppContext,\n\t{\n\t\turl,\n\t\tfilePath,\n\t\tname,\n\t\theader = {},\n\t\tformData = {},\n\t\ttimeout,\n\t\tuploadId = createUploadId(),\n\t\tprogress,\n\t\theadersReceived,\n\t\tsuccess,\n\t\tfail,\n\t\tcomplete,\n\t}: UploadFileOptions,\n) {\n\tconst { onSuccess, onFail, onComplete } = bindCallbacks(this, { success, fail, complete })\n\tconst onProgress = this.createCallbackFunction(progress)\n\tconst onHeadersReceived = this.createCallbackFunction(headersReceived)\n\n\tconst cleanup = () => {\n\t\tuploadRequests.delete(uploadId)\n\t\tuploadPendingResolves.delete(uploadId)\n\t\tuploadAbortedBeforeStart.delete(uploadId)\n\t}\n\tconst finishFail = (message: string) => {\n\t\tcleanup()\n\t\tconst result = { errMsg: `uploadFile:fail ${message}` }\n\t\tonFail?.(result)\n\t\tonComplete?.(result)\n\t}\n\n\tuploadPendingResolves.add(uploadId)\n\tvoid resolveTempFilePath(filePath)\n\t\t.then((blob) => {\n\t\t\tuploadPendingResolves.delete(uploadId)\n\t\t\tif (uploadAbortedBeforeStart.has(uploadId)) {\n\t\t\t\tfinishFail('abort')\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst xhr = new XMLHttpRequest()\n\t\t\tlet settled = false\n\t\t\tlet deliveredHeaders = false\n\t\t\tuploadRequests.set(uploadId, xhr)\n\n\t\t\tconst finishSuccess = () => {\n\t\t\t\tif (settled) return\n\t\t\t\tsettled = true\n\t\t\t\tconst headers = parseResponseHeaders(xhr.getAllResponseHeaders())\n\t\t\t\tcleanup()\n\t\t\t\tconst result = {\n\t\t\t\t\tdata: typeof xhr.response === 'string' ? xhr.response : xhr.responseText,\n\t\t\t\t\tstatusCode: xhr.status,\n\t\t\t\t\theader: headers,\n\t\t\t\t\terrMsg: 'uploadFile:ok',\n\t\t\t\t}\n\t\t\t\tonSuccess?.(result)\n\t\t\t\tonComplete?.(result)\n\t\t\t}\n\t\t\tconst finishXhrFail = (message: string) => {\n\t\t\t\tif (settled) return\n\t\t\t\tsettled = true\n\t\t\t\tfinishFail(message)\n\t\t\t}\n\t\t\tconst emitHeaders = () => {\n\t\t\t\tif (deliveredHeaders) return\n\t\t\t\tdeliveredHeaders = true\n\t\t\t\tonHeadersReceived?.({ header: parseResponseHeaders(xhr.getAllResponseHeaders()) })\n\t\t\t}\n\n\t\t\txhr.open('POST', url, true)\n\t\t\tif (timeout === undefined) {\n\t\t\t\txhr.timeout = 60_000\n\t\t\t} else if (Number(timeout) > 0) {\n\t\t\t\txhr.timeout = Number(timeout)\n\t\t\t}\n\t\t\tfor (const [key, value] of Object.entries(header)) {\n\t\t\t\tif (/^(referer|content-type)$/i.test(key)) continue\n\t\t\t\txhr.setRequestHeader(key, String(value))\n\t\t\t}\n\t\t\txhr.upload.onprogress = (event) => {\n\t\t\t\tconst totalBytesExpectedToSend = event.lengthComputable ? event.total : blob.size\n\t\t\t\tconst progressValue = totalBytesExpectedToSend > 0\n\t\t\t\t\t? Math.round((event.loaded / totalBytesExpectedToSend) * 100)\n\t\t\t\t\t: 0\n\t\t\t\tonProgress?.({\n\t\t\t\t\tprogress: Math.max(0, Math.min(100, progressValue)),\n\t\t\t\t\ttotalBytesSent: event.loaded,\n\t\t\t\t\ttotalBytesExpectedToSend,\n\t\t\t\t})\n\t\t\t}\n\t\t\txhr.onreadystatechange = () => {\n\t\t\t\tif (xhr.readyState >= XMLHttpRequest.HEADERS_RECEIVED) emitHeaders()\n\t\t\t}\n\t\t\txhr.onload = () => {\n\t\t\t\temitHeaders()\n\t\t\t\tfinishSuccess()\n\t\t\t}\n\t\t\txhr.onerror = () => finishXhrFail('network error')\n\t\t\txhr.ontimeout = () => finishXhrFail('timeout')\n\t\t\txhr.onabort = () => finishXhrFail('abort')\n\n\t\t\tconst body = new FormData()\n\t\t\tappendFormData(body, formData)\n\t\t\tbody.append(name, blob, getTempFileName(filePath, blob, name || 'file'))\n\t\t\txhr.send(body)\n\t\t})\n\t\t.catch((error: Error) => {\n\t\t\tfinishFail(error.message)\n\t\t})\n}\n\nexport function uploadFileAbort(this: MiniAppContext, { uploadId }: { uploadId?: string } = {}) {\n\tif (!uploadId) return\n\tconst xhr = uploadRequests.get(uploadId)\n\tif (xhr) {\n\t\txhr.abort()\n\t\treturn\n\t}\n\tif (uploadPendingResolves.has(uploadId)) {\n\t\tuploadAbortedBeforeStart.add(uploadId)\n\t}\n}\n", "/**\n * In-renderer pub/sub store for the simulator's native UI overlays (toast,\n * loading, modal, action sheet).\n *\n * The wx.* UI handlers in `simulator-api-ui.ts` run inside the simulator\n * renderer (via runApiAsync) but cannot touch React state directly. They push\n * the desired overlay into this singleton; the `DeviceShell`-resident\n * `<UiOverlay>` subscribes and renders it inside the device frame (above the\n * page <webview>, clipped to the bezel \u2014 the same layering the status/nav bar\n * already use). User interaction (modal confirm/cancel, action-sheet tap) is\n * routed back to the handler through the `onResult` / `onSelect` callbacks the\n * handler attaches to the dialog state.\n */\n\nexport interface ToastState {\n title: string\n icon: 'success' | 'error' | 'loading' | 'none'\n image?: string\n /** ms before auto-dismiss; Infinity for showLoading (dismissed explicitly). */\n duration: number\n mask: boolean\n}\n\nexport interface ModalDialogState {\n kind: 'modal'\n title: string\n content: string\n showCancel: boolean\n cancelText: string\n cancelColor: string\n confirmText: string\n confirmColor: string\n editable: boolean\n placeholderText: string\n /** The renderer calls this when the user taps confirm/cancel. */\n onResult: (confirmed: boolean, content?: string) => void\n}\n\nexport interface ActionSheetDialogState {\n kind: 'actionSheet'\n itemList: string[]\n itemColor: string\n /** The renderer calls this with the tapped index, or -1 to cancel. */\n onSelect: (index: number) => void\n}\n\nexport type DialogState = ModalDialogState | ActionSheetDialogState\n\nexport interface UiOverlayState {\n toast: ToastState | null\n dialog: DialogState | null\n}\n\ntype Listener = (state: UiOverlayState) => void\n\nclass UiOverlayBus {\n private state: UiOverlayState = { toast: null, dialog: null }\n private readonly listeners = new Set<Listener>()\n\n getState(): UiOverlayState {\n return this.state\n }\n\n subscribe(listener: Listener): () => void {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n showToast(toast: ToastState): void {\n this.set({ ...this.state, toast })\n }\n\n hideToast(): void {\n this.set({ ...this.state, toast: null })\n }\n\n /**\n * Clear `toast` only if it is still the active one. The toast auto-dismiss\n * timer holds a reference to the toast it scheduled; a newer showToast may\n * have replaced it in the meantime, and a blind `hideToast()` from the stale\n * timer would wrongly clear the new toast.\n */\n dismissToast(toast: ToastState): void {\n if (this.state.toast === toast) this.hideToast()\n }\n\n showDialog(dialog: DialogState): void {\n this.set({ ...this.state, dialog })\n }\n\n hideDialog(): void {\n this.set({ ...this.state, dialog: null })\n }\n\n private set(next: UiOverlayState): void {\n this.state = next\n for (const listener of this.listeners) listener(next)\n }\n}\n\nexport const uiOverlayBus = new UiOverlayBus()\n", "/**\n * DevTools implementations for the WeChat-style interaction APIs that native\n * platforms (iOS / Android / Harmony) provide but the web container lacks:\n * showToast / hideToast / showLoading / hideLoading / showModal /\n * showActionSheet.\n *\n * Each handler is bound with `this` = MiniApp instance (via\n * AppManager.registerApi \u2192 MiniApp.invokeApi). The overlay is rendered by the\n * DeviceShell-resident `<UiOverlay>`; these handlers only push state into\n * `uiOverlayBus` and fire the success/fail/complete callbacks \u2014 immediately for\n * toast/loading, and on user interaction for modal/actionSheet (defaults and\n * verdict strings mirror the Android `InteractionApi`).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks } from './simulator-api-helpers'\nimport { uiOverlayBus } from './ui-overlay-bus'\n\ninterface ToastOpts {\n title?: string\n icon?: 'success' | 'error' | 'loading' | 'none'\n image?: string\n duration?: number\n mask?: boolean\n success?: unknown\n fail?: unknown\n complete?: unknown\n}\n\nexport function showToast(this: MiniAppContext, opts: ToastOpts = {}) {\n const { onSuccess, onComplete } = bindCallbacks(this, opts)\n uiOverlayBus.showToast({\n title: opts.title ?? '',\n icon: opts.icon ?? 'success',\n image: opts.image,\n duration: opts.duration ?? 1500,\n mask: opts.mask ?? false,\n })\n onSuccess?.({ errMsg: 'showToast:ok' })\n onComplete?.()\n}\n\nexport function hideToast(this: MiniAppContext, opts: { success?: unknown; complete?: unknown } = {}) {\n const { onSuccess, onComplete } = bindCallbacks(this, opts)\n uiOverlayBus.hideToast()\n onSuccess?.({ errMsg: 'hideToast:ok' })\n onComplete?.()\n}\n\nexport function showLoading(\n this: MiniAppContext,\n opts: { title?: string; mask?: boolean; success?: unknown; complete?: unknown } = {},\n) {\n const { onSuccess, onComplete } = bindCallbacks(this, opts)\n uiOverlayBus.showToast({\n title: opts.title ?? '',\n icon: 'loading',\n duration: Infinity,\n mask: opts.mask ?? false,\n })\n onSuccess?.({ errMsg: 'showLoading:ok' })\n onComplete?.()\n}\n\nexport function hideLoading(this: MiniAppContext, opts: { success?: unknown; complete?: unknown } = {}) {\n const { onSuccess, onComplete } = bindCallbacks(this, opts)\n uiOverlayBus.hideToast()\n onSuccess?.({ errMsg: 'hideLoading:ok' })\n onComplete?.()\n}\n\ninterface ModalOpts {\n title?: string\n content?: string\n showCancel?: boolean\n cancelText?: string\n cancelColor?: string\n confirmText?: string\n confirmColor?: string\n editable?: boolean\n placeholderText?: string\n success?: unknown\n fail?: unknown\n complete?: unknown\n}\n\nexport function showModal(this: MiniAppContext, opts: ModalOpts = {}) {\n const { onSuccess, onComplete } = bindCallbacks(this, opts)\n const editable = opts.editable ?? false\n // Guard against a double resolution (rapid double-tap / a re-render firing the\n // handler twice) settling the callbacks more than once.\n let settled = false\n uiOverlayBus.showDialog({\n kind: 'modal',\n title: opts.title ?? '',\n content: opts.content ?? '',\n showCancel: opts.showCancel ?? true,\n cancelText: opts.cancelText ?? '\u53D6\u6D88',\n cancelColor: opts.cancelColor ?? '#000000',\n confirmText: opts.confirmText ?? '\u786E\u5B9A',\n confirmColor: opts.confirmColor ?? '#576B95',\n editable,\n placeholderText: opts.placeholderText ?? '',\n onResult: (confirmed, content) => {\n if (settled) return\n settled = true\n uiOverlayBus.hideDialog()\n const result: Record<string, unknown> = {\n confirm: confirmed,\n cancel: !confirmed,\n errMsg: 'showModal:ok',\n }\n if (editable) result.content = content ?? ''\n onSuccess?.(result)\n onComplete?.()\n },\n })\n}\n\ninterface ActionSheetOpts {\n itemList?: string[]\n itemColor?: string\n success?: unknown\n fail?: unknown\n complete?: unknown\n}\n\nexport function showActionSheet(this: MiniAppContext, opts: ActionSheetOpts = {}) {\n const { onSuccess, onFail, onComplete } = bindCallbacks(this, opts)\n let settled = false\n uiOverlayBus.showDialog({\n kind: 'actionSheet',\n itemList: opts.itemList ?? [],\n itemColor: opts.itemColor ?? '#000000',\n onSelect: (index) => {\n if (settled) return\n settled = true\n uiOverlayBus.hideDialog()\n if (index === -1) {\n onFail?.({ errMsg: 'showActionSheet:fail cancel' })\n } else {\n onSuccess?.({ tapIndex: index, errMsg: 'showActionSheet:ok' })\n }\n onComplete?.()\n },\n })\n}\n", "/**\n * DevTools API stubs for wx.xxx APIs that exist on native platforms\n * (iOS / Android / Harmony) but are missing in the web container.\n *\n * Each exported function is bound with `this` = MiniApp instance\n * (via AppManager.registerApi \u2192 MiniApp.invokeApi).\n */\n\nimport type { MiniAppContext } from './types'\nimport { bindCallbacks } from './simulator-api-helpers'\nimport {\n\tsetStorageSync,\n\tgetStorageSync,\n\tremoveStorageSync,\n\tclearStorageSync,\n\tgetStorageInfoSync,\n\tsetStorage,\n\tgetStorage,\n\tremoveStorage,\n\tclearStorage,\n\tgetStorageInfo,\n} from './simulator-api-storage'\nimport {\n\thideKeyboard,\n\tadjustPosition,\n\tmakePhoneCall,\n\tchooseContact,\n\taddPhoneContact,\n\tvibrateShort,\n\tvibrateLong,\n\tscanCode,\n\tgetClipboardData,\n\tsetClipboardData,\n\tgetNetworkType,\n} from './simulator-api-device'\nimport {\n\tchooseImage,\n\tpreviewImage,\n\tcompressImage,\n\tsaveImageToPhotosAlbum,\n\tgetImageInfo,\n\tchooseMedia,\n\tchooseVideo,\n\taudioCreate,\n\taudioListen,\n\taudioSetProp,\n\taudioPlay,\n\taudioPause,\n\taudioStop,\n\taudioSeek,\n\taudioDestroy,\n} from './simulator-api-media'\nimport { fileSystemManagerApis } from './simulator-api-fsm'\nimport {\n\tdownloadFile,\n\tuploadFile,\n\tuploadFileAbort,\n} from './simulator-api-network'\nexport {\n\tdownloadFile,\n\tuploadFile,\n\tuploadFileAbort,\n} from './simulator-api-network'\nimport {\n\tshowToast,\n\thideToast,\n\tshowLoading,\n\thideLoading,\n\tshowModal,\n\tshowActionSheet,\n} from './simulator-api-ui'\n\n// \u2500\u2500\u2500 Base \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function canIUse(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown }) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\t// In devtools all standard APIs are considered available.\n\tonSuccess?.(true)\n\tonComplete?.()\n\t// Also return synchronously for callers that use the return value.\n\treturn true\n}\n\nexport function getWindowInfo(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\n\tconst { wb, di, dev, pixelRatio, screenWidth, screenHeight, windowWidth, windowHeight } = readWindowMetrics(this)\n\tconst bar = this.parent?.getStatusBarRect?.() ?? { height: dev?.statusBarHeight ?? 0 }\n\tconst statusBarHeight = (di['statusBarHeight'] as number | undefined) ?? bar.height\n\n\tconst info = {\n\t\tpixelRatio, screenWidth, screenHeight, windowWidth, windowHeight,\n\t\tstatusBarHeight,\n\t\tsafeArea: {\n\t\t\twidth: wb.width,\n\t\t\theight: wb.height - statusBarHeight,\n\t\t\ttop: statusBarHeight,\n\t\t\tbottom: wb.height,\n\t\t\tleft: 0,\n\t\t\tright: wb.width,\n\t\t},\n\t}\n\tonSuccess?.(info)\n\tonComplete?.()\n\treturn info\n}\n\nexport function getSystemSetting(this: MiniAppContext, { success, complete }: { success?: unknown; complete?: unknown } = {}) {\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\n\tconst info = {\n\t\tbluetoothEnabled: false,\n\t\tlocationEnabled: true,\n\t\twifiEnabled: true,\n\t\tdeviceOrientation: 'portrait',\n\t}\n\tonSuccess?.(info)\n\tonComplete?.()\n\treturn info\n}\n\n// \u2500\u2500\u2500 System Info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction readWindowMetrics(miniApp: MiniAppContext) {\n\t// Priority unchanged: __deviceInfo \u2192 host DOM rect. Only the last-resort\n\t// fallback follows the CURRENTLY emulated device (SimulatorMiniApp tracks\n\t// boot config device + live DEVICE_CHANGE) instead of a hardcoded 375x812.\n\tconst dev = miniApp.getDeviceMetrics?.()\n\tconst wb = miniApp.parent?.el?.querySelector('.dimina-native-webview__root')?.getBoundingClientRect()\n\t\t?? { width: dev?.screenWidth ?? 375, height: dev?.screenHeight ?? 812 }\n\tconst di = (window as Window & { __deviceInfo?: Record<string, unknown> }).__deviceInfo || {}\n\treturn {\n\t\twb,\n\t\tdi,\n\t\tdev,\n\t\tpixelRatio: (di['pixelRatio'] as number | undefined) || dev?.pixelRatio || window.devicePixelRatio || 2,\n\t\tscreenWidth: (di['screenWidth'] as number | undefined) || wb.width,\n\t\tscreenHeight: (di['screenHeight'] as number | undefined) || wb.height,\n\t\twindowWidth: wb.width,\n\t\twindowHeight: wb.height,\n\t}\n}\n\nfunction buildSystemInfo(miniApp: MiniAppContext) {\n\tconst { wb, di, dev, pixelRatio, screenWidth, screenHeight, windowWidth, windowHeight } = readWindowMetrics(miniApp)\n\tconst statusBarHeight = (di['statusBarHeight'] as number | undefined) ?? dev?.statusBarHeight ?? 0\n\t// Bottom inset sourced from safeAreaInsets.bottom (the single source \u2014 the\n\t// legacy flat `safeAreaBottom` field is decommissioned).\n\tconst bottomInset = (di['safeAreaInsets'] as { bottom?: number } | undefined)?.bottom\n\t\t?? dev?.safeAreaInsets?.bottom ?? 0\n\n\treturn {\n\t\tbrand: di['brand'] || 'devtools',\n\t\tmodel: di['model'] || 'devtools',\n\t\tpixelRatio, screenWidth, screenHeight, windowWidth, windowHeight,\n\t\tstatusBarHeight,\n\t\tlanguage: 'zh_CN',\n\t\tversion: '8.0.5',\n\t\tsystem: di['system'] || 'iOS 16.0',\n\t\tplatform: di['platform'] || 'ios',\n\t\tfontSizeSetting: 16,\n\t\tSDKVersion: '3.0.0',\n\t\tdeviceOrientation: 'portrait',\n\t\tsafeArea: {\n\t\t\twidth: wb.width,\n\t\t\theight: wb.height - statusBarHeight - bottomInset,\n\t\t\ttop: statusBarHeight,\n\t\t\tbottom: wb.height - bottomInset,\n\t\t\tleft: 0,\n\t\t\tright: wb.width,\n\t\t},\n\t}\n}\n\nexport function getSystemInfoAsync(this: MiniAppContext, opts: { success?: unknown; complete?: unknown }) {\n\tconst { success, complete } = opts\n\tconst { onSuccess, onComplete } = bindCallbacks(this, { success, complete })\n\tonSuccess?.(buildSystemInfo(this))\n\tonComplete?.()\n}\n\nexport function getSystemInfo(this: MiniAppContext, opts: { success?: unknown; complete?: unknown }) {\n\tgetSystemInfoAsync.call(this, opts)\n}\n\nexport function getSystemInfoSync(this: MiniAppContext) {\n\treturn buildSystemInfo(this)\n}\n\n// \u2500\u2500\u2500 Open API: Account Info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getAccountInfoSync(this: MiniAppContext) {\n\treturn {\n\t\tminiProgram: {\n\t\t\tappId: this.appId || '',\n\t\t\tenvVersion: 'develop',\n\t\t\tversion: '',\n\t\t},\n\t}\n}\n\n// \u2500\u2500\u2500 Collect all APIs into a map \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// `opts: never` (not the wider `unknown`) so every handler below \u2014 each typed\n// with its OWN specific opts shape (`getSystemInfoAsync`'s `{ success?, complete? }`,\n// `canIUse`'s `string`, \u2026) \u2014 remains assignable into this map: a function\n// parameter is checked contravariantly, and `never` is assignable into any\n// concrete opts type, whereas `unknown` (the caller-side \"any value\" type)\n// would reject every narrower handler signature here. Callers of this map\n// always cast to a caller-appropriate handler type before invoking (see\n// simulator-app.tsx / main-api-runner.ts) \u2014 this declaration only has to\n// typecheck the object literal itself.\nexport const simulatorApis: Record<string, (this: MiniAppContext, opts: never) => unknown> = {\n\t// Base\n\tcanIUse,\n\tgetSystemInfo,\n\tgetSystemInfoAsync,\n\tgetSystemInfoSync,\n\tgetWindowInfo,\n\tgetSystemSetting,\n\t// UI: interaction\n\tshowToast,\n\thideToast,\n\tshowLoading,\n\thideLoading,\n\tshowModal,\n\tshowActionSheet,\n\t// Network\n\tdownloadFile,\n\tuploadFile,\n\tuploadFileAbort,\n\t// Storage (sync)\n\tsetStorageSync,\n\tgetStorageSync,\n\tremoveStorageSync,\n\tclearStorageSync,\n\tgetStorageInfoSync,\n\t// Storage (async)\n\tsetStorage,\n\tgetStorage,\n\tremoveStorage,\n\tclearStorage,\n\tgetStorageInfo,\n\t// Open API\n\tgetAccountInfoSync,\n\t// Device\n\thideKeyboard,\n\tadjustPosition,\n\tmakePhoneCall,\n\tchooseContact,\n\taddPhoneContact,\n\tvibrateShort,\n\tvibrateLong,\n\tscanCode,\n\tgetClipboardData,\n\tsetClipboardData,\n\tgetNetworkType,\n\t// Media: Image\n\tchooseImage,\n\tpreviewImage,\n\tcompressImage,\n\tsaveImageToPhotosAlbum,\n\tgetImageInfo,\n\t// Media: Video\n\tchooseMedia,\n\tchooseVideo,\n\t// Media: Audio (service-apis/audio)\n\taudioCreate,\n\taudioListen,\n\taudioSetProp,\n\taudioPlay,\n\taudioPause,\n\taudioStop,\n\taudioSeek,\n\taudioDestroy,\n\t// Filesystem: the service thread invokes the dotted FileSystemManager.*\n\t// wire names (see simulator-api-fsm.ts).\n\t...fileSystemManagerApis,\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["handlers", "osStatic", "pathStatic", "path", "path", "path", "tempFiles", "metadata", "BufferImpl"]
|
|
7
7
|
}
|