@crvouga/mockingbird-service-docker 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,14 +1,28 @@
1
1
  # Changelog — @crvouga/mockingbird-service-docker
2
2
 
3
- ## 1.2.0 (2026-10-09)
3
+ ## 1.4.0 (2026-10-15)
4
4
 
5
5
  ### Features
6
6
 
7
- - match Emulate provider coverage ([16b65ce](https://github.com/crvouga/mockingbird/commit/16b65ce791fa216f28ec1521df636f57771d9c5e))
7
+ - finish durable run lifecycle ([725ea1a](https://github.com/crvouga/mockingbird/commit/725ea1a966dac65434e98f06a9c33aca0d6f32d7))
8
+ - add management and portable archives ([0d2a6dd](https://github.com/crvouga/mockingbird/commit/0d2a6dd0f9fecb3a1ea7c1638f6639787395c2f4))
9
+
10
+ ### Fixes and improvements
8
11
 
9
- ### Dependencies
12
+ - correlate cross-namespace operations ([3457a4b](https://github.com/crvouga/mockingbird/commit/3457a4b7dbfd9ad9c8a10671a5744b7c8425d000))
13
+ - harden HTTP stream handling ([674307a](https://github.com/crvouga/mockingbird/commit/674307a869f57907567d462c4f506c3b0a237e13))
14
+
15
+ ## 1.3.0 (2026-10-12)
16
+
17
+ ### Features
10
18
 
11
- - `@crvouga/mockingbird-service-sqlite`
19
+ - unify the emulator control plane ([2068547](https://github.com/crvouga/mockingbird/commit/2068547bedde4e2e2331c1657c1a78120e84428b))
20
+
21
+ ## 1.2.0 (2026-10-08)
22
+
23
+ ### Features
24
+
25
+ - match Emulate provider coverage ([16b65ce](https://github.com/crvouga/mockingbird/commit/16b65ce791fa216f28ec1521df636f57771d9c5e))
12
26
 
13
27
  ## 1.1.0 (2026-10-08)
14
28
 
package/DISCOVERY.md CHANGED
@@ -34,6 +34,7 @@ repository; live parity is an additional oracle check, not a substitute for the
34
34
 
35
35
  - `GET /__admin/health`
36
36
  - `GET /__admin`
37
+ - `GET /__admin/controls`
37
38
  - `GET /__admin/state`
38
39
  - `GET /__admin/requests`
39
40
  - `GET /__admin/metrics`
@@ -44,6 +45,28 @@ For HTTP services, use `x-mockingbird-namespace` (or the documented credential/p
44
45
  parallel tests do not share state. Admin state, journal, metrics and fault-preset endpoints are
45
46
  designed for assertions and diagnosis by consuming test suites.
46
47
 
48
+ ## Admin controls
49
+
50
+ Every HTTP emulator takes the same controls, and each means the same thing at boot
51
+ (`createRuntime({ adminControls })`, `serve --admin-controls`), over `/__admin`, and in a request header:
52
+
53
+ | Control | Admin API | Request header | Interface |
54
+ | --- | --- | --- | --- |
55
+ | Isolate state by key | `GET /__admin/namespaces` | `x-mockingbird-namespace: <key>` | [Namespaces](https://mockingbird.chrisvouga.dev/docs/admin-controls/namespaces) |
56
+ | Reset to boot | `POST /__admin/reset` | `x-mockingbird-reset: true` | [Reset](https://mockingbird.chrisvouga.dev/docs/admin-controls/reset) |
57
+ | Snapshot and restore | `POST /__admin/snapshots`, `POST /__admin/snapshots/<id>/restore` | `x-mockingbird-snapshot: <name>`, `x-mockingbird-restore: <name>` | [Snapshot and restore](https://mockingbird.chrisvouga.dev/docs/admin-controls/snapshot-and-restore) |
58
+ | Move the clock | `POST /__admin/clock` | `x-mockingbird-time: <instant>`, `x-mockingbird-advance: <duration>` | [Clock](https://mockingbird.chrisvouga.dev/docs/admin-controls/clock) |
59
+ | Read or branch from old state | `GET /__admin/timeline` | `x-mockingbird-at: <checkpoint>`, `x-mockingbird-branch: <name>` | [Checkpoints and branches](https://mockingbird.chrisvouga.dev/docs/admin-controls/checkpoints-and-branches) |
60
+ | Inject a fault | `POST /__admin/faults` | `x-mockingbird-fault: <fault>` | [Faults](https://mockingbird.chrisvouga.dev/docs/admin-controls/faults) |
61
+ | Latency and timeouts | `PUT /__admin/latency` | `x-mockingbird-delay: <duration>`, `x-mockingbird-timeout: <duration>` | [Latency and timeouts](https://mockingbird.chrisvouga.dev/docs/admin-controls/latency-and-timeouts) |
62
+ | Replay from a seed | `PUT /__admin/controls` | `x-mockingbird-seed: <seed>` | [Seed and determinism](https://mockingbird.chrisvouga.dev/docs/admin-controls/seed-and-determinism) |
63
+ | See what happened | `GET /__admin/requests`, `GET /__admin/state` | | [Journal, metrics and state](https://mockingbird.chrisvouga.dev/docs/admin-controls/journal-and-state) |
64
+
65
+ `GET /__admin` lists every route and header with a one-line summary, and `GET /__admin/controls`
66
+ is the namespace's current control document. The same seed and the same requests give the same
67
+ bytes. Setting controls as an emulator starts is [Boot](https://mockingbird.chrisvouga.dev/docs/admin-controls/boot); every route and header is in
68
+ the [Reference](https://mockingbird.chrisvouga.dev/docs/admin-controls/reference). The full guide: <https://mockingbird.chrisvouga.dev/docs/admin-controls>.
69
+
47
70
  ## Report a mismatch or missing capability
48
71
 
49
72
  Follow the [agent reporting contract](https://github.com/crvouga/mockingbird/blob/main/docs/REPORTING_ISSUES.md). Include package version,
package/README.md CHANGED
@@ -18,11 +18,17 @@ bun add @crvouga/mockingbird-service-docker
18
18
  ## Usage
19
19
 
20
20
  ```ts
21
- import { createRuntime } from "@crvouga/mockingbird-service-docker"
21
+ import { DockerClient } from "@docker/node-sdk"
22
+ import { createServer } from "@crvouga/mockingbird-service-docker/server"
23
+
24
+ // Docker's Node SDK, as your application uses it (run with Node; its transport does not
25
+ // work under Bun). Only the Docker host changes.
26
+ const server = await createServer({ seed: 42 })
27
+ const docker = await DockerClient.fromDockerHost(`tcp://${server.host}:${server.port}`)
28
+ console.log(await docker.systemPing()) // 1.52
22
29
 
23
- const docker = createRuntime({ seed: 42 })
24
- const response = await docker.fetch(new Request("http://docker.mock/_ping"))
25
- console.log(await response.text()) // OK
30
+ await docker.close()
31
+ await server.close()
26
32
  ```
27
33
 
28
34
  Use `DockerAPI` for the provider-only Fetch surface, or `createRuntime` for health,
@@ -49,14 +55,15 @@ Run this with Node against the built package. The server uses an ephemeral
49
55
  loopback port and synthetic state; no Docker installation is needed.
50
56
 
51
57
  ```ts
58
+ import { DockerClient } from "@docker/node-sdk"
52
59
  import { createServer } from "@crvouga/mockingbird-service-docker/server"
53
60
 
54
61
  const server = await createServer({ seed: 42 })
62
+ const docker = await DockerClient.fromDockerHost(`tcp://${server.host}:${server.port}`)
55
63
  try {
56
- const response = await fetch(`${server.url}/v1.52/version`)
57
- if (!response.ok) throw new Error(`Docker mock returned ${response.status}`)
58
- console.log(await response.json())
64
+ console.log(await docker.systemVersion())
59
65
  } finally {
66
+ await docker.close()
60
67
  await server.close()
61
68
  }
62
69
  ```
@@ -71,10 +78,13 @@ adapter; use `createServer` for Docker's attach and Unix-socket transport.
71
78
  namespace. It never downloads an image or starts a process. For example:
72
79
 
73
80
  ```ts
74
- import { createRuntime } from "@crvouga/mockingbird-service-docker"
81
+ import { DockerClient } from "@docker/node-sdk"
82
+ import { createServer } from "@crvouga/mockingbird-service-docker/server"
75
83
 
76
- const docker = createRuntime({ seed: 42 })
77
- await docker.fetch(new Request("http://docker.mock/__admin/docker/seed", {
84
+ const server = await createServer({ seed: 42 })
85
+
86
+ // Test setup: seed synthetic observations.
87
+ await fetch(`${server.url}/__admin/docker/seed`, {
78
88
  method: "POST",
79
89
  headers: { "content-type": "application/json" },
80
90
  body: JSON.stringify({
@@ -85,7 +95,15 @@ await docker.fetch(new Request("http://docker.mock/__admin/docker/seed", {
85
95
  }],
86
96
  daemon: { rootless: true },
87
97
  }),
88
- }))
98
+ })
99
+
100
+ // The application sees them through Docker's SDK.
101
+ const docker = await DockerClient.fromDockerHost(`tcp://${server.host}:${server.port}`)
102
+ const [worker] = await docker.containerList({ all: true })
103
+ console.log(worker?.Names, worker?.State) // [ '/worker' ] running
104
+
105
+ await docker.close()
106
+ await server.close()
89
107
  ```
90
108
 
91
109
  Image IDs are immutable SHA-256 strings; container IDs are separate 64-character
@@ -5,7 +5,7 @@ import {
5
5
  createRuntime,
6
6
  isRunning,
7
7
  jsonRes
8
- } from "./chunk-5I542RFL.js";
8
+ } from "./chunk-PEU54Q4H.js";
9
9
 
10
10
  // src/attach.ts
11
11
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -615,6 +615,7 @@ var serveTarget = {
615
615
  defaultPort: DEFAULT_PORT,
616
616
  create: (_values, common) => createRuntime({
617
617
  ...common.adminKey !== void 0 ? { adminKey: common.adminKey } : {},
618
+ ...common.adminControls !== void 0 ? { adminControls: common.adminControls } : {},
618
619
  ...common.seed !== void 0 ? { seed: common.seed } : {},
619
620
  ...common.onLog ? { onLog: common.onLog } : {}
620
621
  }),
@@ -626,4 +627,4 @@ export {
626
627
  createServer2 as createServer,
627
628
  serveTarget
628
629
  };
629
- //# sourceMappingURL=chunk-TR75ZFCZ.js.map
630
+ //# sourceMappingURL=chunk-DG4KWFV5.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/attach.ts", "../src/streams.ts", "../src/transport.ts", "../src/server.ts"],
4
- "sourcesContent": ["import { AsyncLocalStorage } from \"node:async_hooks\"\nimport type { IncomingMessage } from \"node:http\"\nimport { STATUS_CODES } from \"node:http\"\nimport type { Duplex } from \"node:stream\"\nimport { annotateResponse, jsonRes } from \"@crvouga/mockingbird-service\"\nimport type { DockerAPI } from \"./index.js\"\nimport { booleanQuery } from \"./observations.js\"\nimport type { DockerRuntime } from \"./runtime.js\"\nimport { DockerInputError } from \"./state.js\"\nimport { type AttachSelection, type AttachStreamOptions, createAttachStreams } from \"./streams.js\"\n\nexport type AttachHandshakeOptions = {\n /** Deterministic mock writes; network packet boundaries remain OS-controlled. */\n chunkBytes?: number\n /** Synthetic already-framed output delivered with the final header fragment. */\n initialStreamBytes?: Uint8Array\n}\ntype Admission = { selection?: AttachSelection }\nconst header = Buffer.from(\n \"HTTP/1.1 101 UPGRADED\\r\\nContent-Type: application/vnd.docker.multiplexed-stream\\r\\nConnection: Upgrade\\r\\nUpgrade: tcp\\r\\n\\r\\n\",\n)\n\nexport const createAttachHandshake = (\n options: AttachHandshakeOptions = {},\n streamOptions: AttachStreamOptions = {},\n) => {\n const streams = createAttachStreams(streamOptions)\n const chunkBytes = options.chunkBytes ?? header.length\n if (!Number.isSafeInteger(chunkBytes) || chunkBytes < 1 || chunkBytes > 4096)\n throw new RangeError(\"attach chunkBytes must be 1..4096\")\n if ((options.initialStreamBytes?.byteLength ?? 0) > 1024 * 1024)\n throw new RangeError(\"initialStreamBytes exceeds 1 MiB\")\n const first = Buffer.from(options.initialStreamBytes ?? [])\n const admission = new AsyncLocalStorage<Admission>()\n const prepare = (api: DockerAPI, request: Request): Response => {\n const context = admission.getStore()\n if (!context) return jsonRes(501, { message: \"Mockingbird: attach requires Node HTTP upgrade\" })\n const url = new URL(request.url)\n if (\n !booleanQuery(url, \"stream\") ||\n booleanQuery(url, \"logs\") ||\n url.searchParams.has(\"detachKeys\") ||\n [...url.searchParams.keys()].some(\n (key) => ![\"stream\", \"logs\", \"stdin\", \"stdout\", \"stderr\"].includes(key),\n )\n )\n return jsonRes(501, { message: \"Mockingbird: attach mode is not implemented\" })\n const match = /^\\/containers\\/([^/]+)\\/attach$/.exec(url.pathname)\n if (!match?.[1]) return jsonRes(404, { message: \"page not found\" })\n let name: string\n try {\n name = decodeURIComponent(match[1])\n } catch {\n return jsonRes(400, { message: \"invalid container name encoding\" })\n }\n try {\n const c = api.state.find(name)\n if (c.status === \"paused\")\n throw new DockerInputError(\n 409,\n `container ${name} is paused, unpause the container before attach`,\n )\n if (c.status === \"restarting\")\n throw new DockerInputError(\n 409,\n `container ${name} is restarting, wait until the container is running`,\n )\n if (c.config?.Tty === true)\n return jsonRes(501, { message: \"Mockingbird: TTY attach is not implemented\" })\n context.selection = {\n api,\n generation: api.generation,\n containerId: c.id,\n namespace: request.headers.get(\"x-mockingbird-namespace\") ?? \"default\",\n branch: request.headers.get(\"x-mockingbird-branch\") ?? \"main\",\n stdin: booleanQuery(url, \"stdin\") && c.config?.OpenStdin === true,\n stdinOnce: c.config?.StdinOnce === true,\n stdout: booleanQuery(url, \"stdout\"),\n stderr: booleanQuery(url, \"stderr\"),\n }\n return annotateResponse(new Response(null), { wireStatus: 101, ids: { containerId: c.id } })\n } catch (error) {\n if (error instanceof DockerInputError)\n return new Response(`${error.message}\\r\\n`, {\n status: error.status,\n headers: { \"content-type\": \"application/vnd.docker.raw-stream\" },\n })\n throw error\n }\n }\n const write = (socket: Duplex, bytes: Uint8Array) =>\n new Promise<boolean>((resolve) => {\n const finish = (ok: boolean) => {\n socket.off(\"close\", closed)\n resolve(ok)\n }\n const closed = () => finish(false)\n socket.once(\"close\", closed)\n if (socket.destroyed) {\n finish(false)\n return\n }\n socket.write(bytes, (error) => finish(!error))\n })\n const upgrade = async (\n runtime: DockerRuntime,\n req: IncomingMessage,\n socket: Duplex,\n head: Buffer,\n ) => {\n socket.on(\"error\", () => socket.destroy())\n socket.pause()\n try {\n if (\n req.method !== \"POST\" ||\n req.headers.upgrade?.toLowerCase() !== \"tcp\" ||\n !req.headers.connection\n ?.toLowerCase()\n .split(/\\s*,\\s*/)\n .includes(\"upgrade\") ||\n Number(req.headers[\"content-length\"] ?? 0) !== 0 ||\n req.headers[\"transfer-encoding\"] !== undefined\n ) {\n await write(\n socket,\n Buffer.from(\n \"HTTP/1.1 501 Not Implemented\\r\\nConnection: close\\r\\nContent-Length: 0\\r\\n\\r\\n\",\n ),\n )\n socket.end()\n return\n }\n const target = new URL((req.url ?? \"/\").replace(/^\\/+/, \"/\"), \"http://docker.mock\")\n if (\n !/^(?:\\/__admin\\/ns\\/[^/]+)?(?:\\/v[0-9]+\\.[0-9]+)?\\/containers\\/[^/]+\\/attach$/.test(\n target.pathname,\n )\n ) {\n await write(\n socket,\n Buffer.from(\"HTTP/1.1 404 Not Found\\r\\nConnection: close\\r\\nContent-Length: 0\\r\\n\\r\\n\"),\n )\n socket.end()\n return\n }\n const headers = new Headers()\n for (let i = 0; i < req.rawHeaders.length; i += 2) {\n const name = req.rawHeaders[i],\n value = req.rawHeaders[i + 1]\n if (name && value !== undefined) headers.append(name, value)\n }\n const request = new Request(\n new URL((req.url ?? \"/\").replace(/^\\/+/, \"/\"), \"http://docker.mock\"),\n { method: \"POST\", headers },\n )\n const context: Admission = {}\n const response = await admission.run(context, () => runtime.fetch(request))\n if (socket.destroyed) return\n if (!context.selection || response.status !== 200) {\n const body = Buffer.from(await response.arrayBuffer())\n const type = response.headers.get(\"content-type\") ?? \"application/json\"\n await write(\n socket,\n Buffer.concat([\n Buffer.from(\n `HTTP/1.1 ${response.status} ${STATUS_CODES[response.status] ?? \"Error\"}\\r\\nContent-Type: ${type}\\r\\nConnection: close\\r\\nContent-Length: ${body.length}\\r\\n\\r\\n`,\n ),\n body,\n ]),\n )\n socket.end()\n return\n }\n const session = streams.connect(context.selection, socket, runtime)\n for (let offset = 0; offset < header.length; offset += chunkBytes) {\n const end = Math.min(offset + chunkBytes, header.length)\n const chunk = header.subarray(offset, end)\n if (!(await write(socket, end === header.length ? Buffer.concat([chunk, first]) : chunk)))\n return\n if (end < header.length) await new Promise<void>((resolve) => setImmediate(resolve))\n }\n session.start(head)\n } catch {\n socket.destroy()\n }\n }\n return { prepare, upgrade, attachments: streams.list }\n}\n", "import type { Duplex } from \"node:stream\"\nimport type { DockerAPI } from \"./index.js\"\nimport type { DockerRuntime } from \"./runtime.js\"\nimport { isRunning } from \"./state.js\"\n\nexport type AttachStreamOptions = {\n frameChunkBytes?: number\n maxQueuedBytes?: number\n maxStdinBytes?: number\n}\nexport type AttachSelection = {\n api: DockerAPI\n generation: number\n containerId: string\n namespace: string\n branch: string\n stdin: boolean\n stdout: boolean\n stderr: boolean\n stdinOnce: boolean\n}\n/** Node-owned live handle. Retaining one across restore never addresses a successor. */\nexport type DockerAttachment = {\n readonly id: number\n readonly containerId: string\n readonly namespace: string\n readonly branch: string\n readonly closed: boolean\n readonly stdinClosed: boolean\n readonly queuedBytes: number\n write(channel: \"stdout\" | \"stderr\", data: Uint8Array): Promise<void>\n takeStdin(): Uint8Array\n end(): Promise<void>\n cancel(): void\n}\nconst limit = (value: number, name: string) => {\n if (!Number.isSafeInteger(value) || value < 1 || value > 16 * 1024 * 1024)\n throw new RangeError(`${name} must be 1..16777216`)\n return value\n}\nexport const createAttachStreams = (options: AttachStreamOptions = {}) => {\n const chunkBytes = limit(options.frameChunkBytes ?? 64 * 1024, \"frameChunkBytes\")\n const maxQueued = limit(options.maxQueuedBytes ?? 1024 * 1024, \"maxQueuedBytes\")\n const maxStdin = limit(options.maxStdinBytes ?? 1024 * 1024, \"maxStdinBytes\")\n const sessions = new Set<DockerAttachment>()\n let sequence = 0\n const connect = (selection: AttachSelection, socket: Duplex, runtime: DockerRuntime) => {\n const { api, containerId, namespace, branch } = selection\n let closed = false,\n outputClosed = false,\n retired = false,\n inputEnded = false,\n queuedBytes = 0,\n inputSize = 0\n let input: Buffer[] = []\n let tail: Promise<void> = Promise.resolve()\n let releaseReady = (_ready: boolean) => {}\n const ready = new Promise<boolean>((resolve) => {\n releaseReady = resolve\n })\n const valid = () => !closed && api.generation === selection.generation\n const closeInput = () => {\n inputEnded = true\n if (!valid() || retired || !selection.stdin || !selection.stdinOnce) return\n const c = api.state.containers.get(containerId)\n if (c && !c.stdinClosed) {\n api.state.containers.update(containerId, { ...c, stdinClosed: true })\n runtime.checkpoint(namespace, branch)\n }\n }\n let detachInvalidation = () => {},\n detachExit = () => {}\n const release = () => {\n if (closed) return\n closed = true\n outputClosed = true\n releaseReady(false)\n sessions.delete(handle)\n detachInvalidation()\n detachExit()\n socket.off(\"data\", onData)\n socket.off(\"end\", onEnd)\n }\n const cancel = () => {\n closeInput()\n release()\n input = []\n inputSize = 0\n socket.destroy()\n }\n const send = (bytes: Uint8Array) =>\n new Promise<void>((resolve, reject) => {\n const close = () => {\n socket.off(\"close\", close)\n reject(new Error(\"Attachment closed\"))\n }\n if (!valid() || socket.destroyed) {\n close()\n return\n }\n socket.once(\"close\", close)\n socket.write(bytes, (error) => {\n socket.off(\"close\", close)\n if (error) reject(error)\n else resolve()\n })\n })\n const onData = (chunk: Buffer) => {\n if (!valid() || retired) return\n if (!selection.stdin || api.state.containers.get(containerId)?.stdinClosed) return\n if (inputSize + chunk.length > maxStdin) {\n cancel()\n return\n }\n input.push(Buffer.from(chunk))\n inputSize += chunk.length\n }\n const onEnd = () => {\n closeInput()\n if (selection.stdin && !selection.stdinOnce) void handle.end().catch(cancel)\n }\n const finish = async () => {\n await tail\n if (valid() && !socket.destroyed) socket.end()\n }\n const handle: DockerAttachment = {\n id: ++sequence,\n containerId,\n namespace,\n branch,\n get closed() {\n return closed\n },\n get stdinClosed() {\n return inputEnded || api.state.containers.get(containerId)?.stdinClosed === true\n },\n get queuedBytes() {\n return queuedBytes\n },\n async write(channel, data) {\n if (!valid() || outputClosed) throw new Error(\"Attachment closed\")\n if (channel !== \"stdout\" && channel !== \"stderr\")\n throw new TypeError(\"Unknown output channel\")\n if (!selection[channel]) return\n const size = data.byteLength + 8\n if (size + queuedBytes > maxQueued)\n throw new RangeError(\"Attachment output queue limit exceeded\")\n const frame = Buffer.allocUnsafe(size)\n frame[0] = channel === \"stdout\" ? 1 : 2\n frame.fill(0, 1, 4)\n frame.writeUInt32BE(data.byteLength, 4)\n frame.set(data, 8)\n queuedBytes += size\n const result = tail.then(async () => {\n if (!(await ready) || !valid()) throw new Error(\"Attachment closed\")\n for (let at = 0; at < frame.length; at += chunkBytes)\n await send(frame.subarray(at, at + chunkBytes))\n })\n tail = result.catch(() => {})\n try {\n await result\n } finally {\n queuedBytes -= size\n }\n },\n takeStdin() {\n const result = Buffer.concat(input, inputSize)\n input = []\n inputSize = 0\n return result\n },\n async end() {\n if (!valid() || outputClosed) return\n outputClosed = true\n closeInput()\n const c = api.state.containers.get(containerId)\n if (selection.stdinOnce && c && isRunning(c)) return\n await finish()\n },\n cancel,\n }\n socket.once(\"close\", () => {\n if (valid()) closeInput()\n release()\n })\n detachInvalidation = api.onInvalidate(cancel)\n detachExit = api.lifecycle.onExit((id) => {\n if (id === containerId) {\n retired = true\n input = []\n inputSize = 0\n inputEnded = true\n outputClosed = true\n void finish().catch(cancel)\n }\n })\n sessions.add(handle)\n if (!valid()) {\n cancel()\n }\n return {\n handle,\n start(head: Buffer) {\n if (!valid()) return\n socket.on(\"data\", onData)\n socket.once(\"end\", onEnd)\n if (head.length) onData(head)\n releaseReady(true)\n socket.resume()\n if (!selection.stdin && !selection.stdout && !selection.stderr)\n void handle.end().catch(cancel)\n },\n cancel,\n }\n }\n return { connect, list: () => [...sessions] }\n}\n", "import { lstat } from \"node:fs/promises\"\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\"\nimport type { Socket } from \"node:net\"\nimport { isAbsolute } from \"node:path\"\nimport type { DockerRuntime } from \"./runtime.js\"\n\nexport type TransportOptions = {\n port?: number\n host?: string\n socketPath?: string\n /** Maximum buffered request bytes. Default 1 MiB. */\n maxBodyBytes?: number\n /** Deadline for receiving a body, independent of long-running responses. */\n bodyTimeoutMs?: number\n /** Maximum simultaneous owned connections. Default 128. */\n maxConnections?: number\n}\nconst positive = (value: number, name: string) => {\n if (!Number.isSafeInteger(value) || value <= 0)\n throw new RangeError(`${name} must be a positive integer`)\n return value\n}\n\nexport const listenDocker = async (\n runtime: DockerRuntime,\n options: TransportOptions,\n upgrade?: (\n req: IncomingMessage,\n socket: import(\"node:stream\").Duplex,\n head: Buffer,\n ) => Promise<void>,\n) => {\n const maxBody = positive(options.maxBodyBytes ?? 1024 * 1024, \"maxBodyBytes\")\n const bodyTimeout = positive(options.bodyTimeoutMs ?? 30_000, \"bodyTimeoutMs\")\n const maxConnections = positive(options.maxConnections ?? 128, \"maxConnections\")\n const path = options.socketPath\n if (path !== undefined) {\n if (!isAbsolute(path) || path.includes(\"\\0\") || Buffer.byteLength(path) > 103)\n throw new Error(\"socketPath must be an absolute Unix path of at most 103 bytes\")\n if (options.port !== undefined || options.host !== undefined)\n throw new Error(\"socketPath cannot be combined with port or host\")\n const existing = await lstat(path).then(\n () => true,\n (error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") return false\n throw error\n },\n )\n if (existing) throw new Error(\"Refusing existing socketPath\")\n }\n const sockets = new Set<Socket>()\n const handle = async (req: IncomingMessage, res: ServerResponse) => {\n const abort = new AbortController()\n const onClose = () => {\n if (!res.writableFinished) abort.abort()\n }\n res.once(\"close\", onClose)\n const reject = (status: number) => {\n res.writeHead(status, { \"content-type\": \"application/json\", connection: \"close\" })\n res.end(JSON.stringify({ message: `Mockingbird transport rejected request (${status})` }))\n }\n try {\n if (Number(req.headers[\"content-length\"]) > maxBody) {\n reject(413)\n return\n }\n const body = await new Promise<Buffer | undefined>((resolve, rejectBody) => {\n const chunks: Buffer[] = []\n let size = 0\n const cleanup = () => {\n clearTimeout(timer)\n req.off(\"data\", data)\n req.off(\"end\", end)\n req.off(\"error\", error)\n abort.signal.removeEventListener(\"abort\", canceled)\n }\n const canceled = () => {\n cleanup()\n rejectBody(new Error(\"Request disconnected\"))\n }\n const error = (e: Error) => {\n cleanup()\n rejectBody(e)\n }\n const end = () => {\n cleanup()\n resolve(Buffer.concat(chunks, size))\n }\n const data = (chunk: Buffer) => {\n size += chunk.length\n if (size > maxBody) {\n cleanup()\n req.pause()\n reject(413)\n resolve(undefined)\n return\n }\n chunks.push(chunk)\n }\n const timer = setTimeout(() => {\n cleanup()\n req.pause()\n reject(408)\n resolve(undefined)\n }, bodyTimeout)\n req.on(\"data\", data)\n req.once(\"end\", end)\n req.once(\"error\", error)\n abort.signal.addEventListener(\"abort\", canceled, { once: true })\n if (abort.signal.aborted) canceled()\n })\n if (body === undefined || abort.signal.aborted) return\n const headers = new Headers()\n for (let i = 0; i < req.rawHeaders.length; i += 2) {\n const name = req.rawHeaders[i],\n value = req.rawHeaders[i + 1]\n if (name !== undefined && value !== undefined) headers.append(name, value)\n }\n const method = req.method ?? \"GET\"\n const request = new Request(\n new URL((req.url ?? \"/\").replace(/^\\/+/, \"/\"), \"http://docker.mock\"),\n {\n method,\n headers,\n signal: abort.signal,\n ...(method !== \"GET\" && method !== \"HEAD\" && body.length\n ? { body: new Uint8Array(body) }\n : {}),\n },\n )\n const response = await runtime.fetch(request)\n if (abort.signal.aborted) {\n await response.body?.cancel()\n return\n }\n const outgoing: Record<string, string | string[]> = Object.fromEntries(response.headers)\n const cookies = response.headers.getSetCookie()\n if (cookies.length) outgoing[\"set-cookie\"] = cookies\n res.writeHead(response.status, outgoing)\n if (!response.body) {\n res.end()\n return\n }\n res.flushHeaders()\n const reader = response.body.getReader()\n const cancel = () => {\n void reader.cancel().catch(() => {})\n }\n abort.signal.addEventListener(\"abort\", cancel, { once: true })\n try {\n while (!abort.signal.aborted) {\n const { done, value } = await reader.read()\n if (done) break\n if (!res.write(value))\n await new Promise<void>((resolve) => {\n const finish = () => {\n res.off(\"drain\", finish)\n res.off(\"close\", finish)\n resolve()\n }\n res.once(\"drain\", finish)\n res.once(\"close\", finish)\n if (res.destroyed) finish()\n })\n }\n if (!res.destroyed) res.end()\n } finally {\n abort.signal.removeEventListener(\"abort\", cancel)\n reader.releaseLock()\n }\n } catch (error) {\n if (\n (error as { code?: string })?.code === \"MOCKINGBIRD_DROP\" ||\n abort.signal.aborted ||\n res.headersSent\n )\n res.destroy()\n else reject(500)\n } finally {\n res.off(\"close\", onClose)\n }\n }\n const busy = new WeakSet<Socket>()\n const server = createServer(\n {\n maxHeaderSize: 16 * 1024,\n headersTimeout: 30_000,\n requestTimeout: 30_000,\n keepAliveTimeout: 5_000,\n },\n (req, res) => {\n // Sequential keep-alive is supported; pipelining cannot accumulate handlers.\n if (req.socket.destroyed || busy.has(req.socket)) {\n req.socket.destroy()\n return\n }\n busy.add(req.socket)\n const release = () => {\n busy.delete(req.socket)\n res.off(\"finish\", release)\n res.off(\"close\", release)\n }\n res.once(\"finish\", release)\n res.once(\"close\", release)\n void handle(req, res)\n },\n )\n if (upgrade)\n server.on(\"upgrade\", (req, socket, head) => {\n if (socket.destroyed || busy.has(socket as Socket) || !sockets.has(socket as Socket)) {\n socket.destroy()\n return\n }\n busy.add(socket as Socket)\n void upgrade(req, socket, head)\n })\n server.on(\"connection\", (socket) => {\n if (sockets.size >= maxConnections) {\n socket.destroy()\n return\n }\n sockets.add(socket)\n socket.once(\"close\", () => sockets.delete(socket))\n })\n server.once(\"close\", () => runtime.close())\n const host = options.host ?? \"127.0.0.1\"\n await new Promise<void>((resolve, reject) => {\n const error = (error: Error) => {\n server.off(\"listening\", ready)\n reject(error)\n }\n const ready = () => {\n server.off(\"error\", error)\n resolve()\n }\n server.once(\"error\", error)\n server.once(\"listening\", ready)\n if (path !== undefined) server.listen(path)\n else server.listen(options.port ?? 0, host)\n })\n const address = server.address()\n const port = typeof address === \"object\" && address !== null ? address.port : 0\n let closing: Promise<void> | undefined\n return {\n server,\n host,\n port,\n ...(path !== undefined ? { socketPath: path } : {}),\n url:\n path === undefined\n ? `http://${host.includes(\":\") ? `[${host}]` : host}:${port}`\n : \"http://docker.mock\",\n close: () =>\n (closing ??= new Promise<void>((resolve, reject) => {\n runtime.close()\n server.close((error) => {\n if (error && (error as NodeJS.ErrnoException).code !== \"ERR_SERVER_NOT_RUNNING\")\n reject(error)\n else resolve()\n })\n for (const socket of sockets) socket.destroy()\n })),\n }\n}\n", "/// <reference types=\"node\" />\nimport type { Listening, ServeTarget } from \"@crvouga/mockingbird-adapter-node\"\nimport { type AttachHandshakeOptions, createAttachHandshake } from \"./attach.js\"\nimport { createRuntime, type DockerRuntime, type DockerRuntimeOptions } from \"./runtime.js\"\nimport type { AttachStreamOptions, DockerAttachment } from \"./streams.js\"\n\nexport type { AttachStreamOptions, DockerAttachment } from \"./streams.js\"\n\nimport { listenDocker, type TransportOptions } from \"./transport.js\"\n\nexport const DEFAULT_PORT = 8826\nexport type DockerServerOptions = Omit<DockerRuntimeOptions, \"onAttach\"> &\n TransportOptions & {\n attachHandshake?: AttachHandshakeOptions\n attachStreams?: AttachStreamOptions\n }\nexport type DockerServer = Listening & {\n runtime: DockerRuntime\n socketPath?: string\n attachments(): DockerAttachment[]\n}\n\n/** Node-only bounded HTTP transport over TCP or a test-owned Unix socket. */\nexport const createServer = async (options: DockerServerOptions = {}): Promise<DockerServer> => {\n const {\n port,\n host,\n socketPath,\n maxBodyBytes,\n bodyTimeoutMs,\n maxConnections,\n attachHandshake,\n attachStreams,\n ...rest\n } = options\n const attach = createAttachHandshake(attachHandshake, attachStreams)\n const runtime = createRuntime({ ...rest, onAttach: attach.prepare })\n try {\n const listening = await listenDocker(\n runtime,\n {\n ...(port !== undefined ? { port } : {}),\n ...(host !== undefined ? { host } : {}),\n ...(socketPath !== undefined ? { socketPath } : {}),\n ...(maxBodyBytes !== undefined ? { maxBodyBytes } : {}),\n ...(bodyTimeoutMs !== undefined ? { bodyTimeoutMs } : {}),\n ...(maxConnections !== undefined ? { maxConnections } : {}),\n },\n (req, socket, head) => attach.upgrade(runtime, req, socket, head),\n )\n return { ...listening, runtime, attachments: attach.attachments }\n } catch (error) {\n runtime.close()\n throw error\n }\n}\n\nexport const serveTarget: ServeTarget = {\n name: \"docker\",\n defaultPort: DEFAULT_PORT,\n create: (_values, common) =>\n createRuntime({\n ...(common.adminKey !== undefined ? { adminKey: common.adminKey } : {}),\n ...(common.seed !== undefined ? { seed: common.seed } : {}),\n ...(common.onLog ? { onLog: common.onLog } : {}),\n }),\n banner: () => [\"Docker lifecycle: explicit simulated completion; no image execution or attach\"],\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { AsyncLocalStorage } from \"node:async_hooks\"\nimport type { IncomingMessage } from \"node:http\"\nimport { STATUS_CODES } from \"node:http\"\nimport type { Duplex } from \"node:stream\"\nimport { annotateResponse, jsonRes } from \"@crvouga/mockingbird-service\"\nimport type { DockerAPI } from \"./index.js\"\nimport { booleanQuery } from \"./observations.js\"\nimport type { DockerRuntime } from \"./runtime.js\"\nimport { DockerInputError } from \"./state.js\"\nimport { type AttachSelection, type AttachStreamOptions, createAttachStreams } from \"./streams.js\"\n\nexport type AttachHandshakeOptions = {\n /** Deterministic mock writes; network packet boundaries remain OS-controlled. */\n chunkBytes?: number\n /** Synthetic already-framed output delivered with the final header fragment. */\n initialStreamBytes?: Uint8Array\n}\ntype Admission = { selection?: AttachSelection }\nconst header = Buffer.from(\n \"HTTP/1.1 101 UPGRADED\\r\\nContent-Type: application/vnd.docker.multiplexed-stream\\r\\nConnection: Upgrade\\r\\nUpgrade: tcp\\r\\n\\r\\n\",\n)\n\nexport const createAttachHandshake = (\n options: AttachHandshakeOptions = {},\n streamOptions: AttachStreamOptions = {},\n) => {\n const streams = createAttachStreams(streamOptions)\n const chunkBytes = options.chunkBytes ?? header.length\n if (!Number.isSafeInteger(chunkBytes) || chunkBytes < 1 || chunkBytes > 4096)\n throw new RangeError(\"attach chunkBytes must be 1..4096\")\n if ((options.initialStreamBytes?.byteLength ?? 0) > 1024 * 1024)\n throw new RangeError(\"initialStreamBytes exceeds 1 MiB\")\n const first = Buffer.from(options.initialStreamBytes ?? [])\n const admission = new AsyncLocalStorage<Admission>()\n const prepare = (api: DockerAPI, request: Request): Response => {\n const context = admission.getStore()\n if (!context) return jsonRes(501, { message: \"Mockingbird: attach requires Node HTTP upgrade\" })\n const url = new URL(request.url)\n if (\n !booleanQuery(url, \"stream\") ||\n booleanQuery(url, \"logs\") ||\n url.searchParams.has(\"detachKeys\") ||\n [...url.searchParams.keys()].some(\n (key) => ![\"stream\", \"logs\", \"stdin\", \"stdout\", \"stderr\"].includes(key),\n )\n )\n return jsonRes(501, { message: \"Mockingbird: attach mode is not implemented\" })\n const match = /^\\/containers\\/([^/]+)\\/attach$/.exec(url.pathname)\n if (!match?.[1]) return jsonRes(404, { message: \"page not found\" })\n let name: string\n try {\n name = decodeURIComponent(match[1])\n } catch {\n return jsonRes(400, { message: \"invalid container name encoding\" })\n }\n try {\n const c = api.state.find(name)\n if (c.status === \"paused\")\n throw new DockerInputError(\n 409,\n `container ${name} is paused, unpause the container before attach`,\n )\n if (c.status === \"restarting\")\n throw new DockerInputError(\n 409,\n `container ${name} is restarting, wait until the container is running`,\n )\n if (c.config?.Tty === true)\n return jsonRes(501, { message: \"Mockingbird: TTY attach is not implemented\" })\n context.selection = {\n api,\n generation: api.generation,\n containerId: c.id,\n namespace: request.headers.get(\"x-mockingbird-namespace\") ?? \"default\",\n branch: request.headers.get(\"x-mockingbird-branch\") ?? \"main\",\n stdin: booleanQuery(url, \"stdin\") && c.config?.OpenStdin === true,\n stdinOnce: c.config?.StdinOnce === true,\n stdout: booleanQuery(url, \"stdout\"),\n stderr: booleanQuery(url, \"stderr\"),\n }\n return annotateResponse(new Response(null), { wireStatus: 101, ids: { containerId: c.id } })\n } catch (error) {\n if (error instanceof DockerInputError)\n return new Response(`${error.message}\\r\\n`, {\n status: error.status,\n headers: { \"content-type\": \"application/vnd.docker.raw-stream\" },\n })\n throw error\n }\n }\n const write = (socket: Duplex, bytes: Uint8Array) =>\n new Promise<boolean>((resolve) => {\n const finish = (ok: boolean) => {\n socket.off(\"close\", closed)\n resolve(ok)\n }\n const closed = () => finish(false)\n socket.once(\"close\", closed)\n if (socket.destroyed) {\n finish(false)\n return\n }\n socket.write(bytes, (error) => finish(!error))\n })\n const upgrade = async (\n runtime: DockerRuntime,\n req: IncomingMessage,\n socket: Duplex,\n head: Buffer,\n ) => {\n socket.on(\"error\", () => socket.destroy())\n socket.pause()\n try {\n if (\n req.method !== \"POST\" ||\n req.headers.upgrade?.toLowerCase() !== \"tcp\" ||\n !req.headers.connection\n ?.toLowerCase()\n .split(/\\s*,\\s*/)\n .includes(\"upgrade\") ||\n Number(req.headers[\"content-length\"] ?? 0) !== 0 ||\n req.headers[\"transfer-encoding\"] !== undefined\n ) {\n await write(\n socket,\n Buffer.from(\n \"HTTP/1.1 501 Not Implemented\\r\\nConnection: close\\r\\nContent-Length: 0\\r\\n\\r\\n\",\n ),\n )\n socket.end()\n return\n }\n const target = new URL((req.url ?? \"/\").replace(/^\\/+/, \"/\"), \"http://docker.mock\")\n if (\n !/^(?:\\/__admin\\/ns\\/[^/]+)?(?:\\/v[0-9]+\\.[0-9]+)?\\/containers\\/[^/]+\\/attach$/.test(\n target.pathname,\n )\n ) {\n await write(\n socket,\n Buffer.from(\"HTTP/1.1 404 Not Found\\r\\nConnection: close\\r\\nContent-Length: 0\\r\\n\\r\\n\"),\n )\n socket.end()\n return\n }\n const headers = new Headers()\n for (let i = 0; i < req.rawHeaders.length; i += 2) {\n const name = req.rawHeaders[i],\n value = req.rawHeaders[i + 1]\n if (name && value !== undefined) headers.append(name, value)\n }\n const request = new Request(\n new URL((req.url ?? \"/\").replace(/^\\/+/, \"/\"), \"http://docker.mock\"),\n { method: \"POST\", headers },\n )\n const context: Admission = {}\n const response = await admission.run(context, () => runtime.fetch(request))\n if (socket.destroyed) return\n if (!context.selection || response.status !== 200) {\n const body = Buffer.from(await response.arrayBuffer())\n const type = response.headers.get(\"content-type\") ?? \"application/json\"\n await write(\n socket,\n Buffer.concat([\n Buffer.from(\n `HTTP/1.1 ${response.status} ${STATUS_CODES[response.status] ?? \"Error\"}\\r\\nContent-Type: ${type}\\r\\nConnection: close\\r\\nContent-Length: ${body.length}\\r\\n\\r\\n`,\n ),\n body,\n ]),\n )\n socket.end()\n return\n }\n const session = streams.connect(context.selection, socket, runtime)\n for (let offset = 0; offset < header.length; offset += chunkBytes) {\n const end = Math.min(offset + chunkBytes, header.length)\n const chunk = header.subarray(offset, end)\n if (!(await write(socket, end === header.length ? Buffer.concat([chunk, first]) : chunk)))\n return\n if (end < header.length) await new Promise<void>((resolve) => setImmediate(resolve))\n }\n session.start(head)\n } catch {\n socket.destroy()\n }\n }\n return { prepare, upgrade, attachments: streams.list }\n}\n", "import type { Duplex } from \"node:stream\"\nimport type { DockerAPI } from \"./index.js\"\nimport type { DockerRuntime } from \"./runtime.js\"\nimport { isRunning } from \"./state.js\"\n\nexport type AttachStreamOptions = {\n frameChunkBytes?: number\n maxQueuedBytes?: number\n maxStdinBytes?: number\n}\nexport type AttachSelection = {\n api: DockerAPI\n generation: number\n containerId: string\n namespace: string\n branch: string\n stdin: boolean\n stdout: boolean\n stderr: boolean\n stdinOnce: boolean\n}\n/** Node-owned live handle. Retaining one across restore never addresses a successor. */\nexport type DockerAttachment = {\n readonly id: number\n readonly containerId: string\n readonly namespace: string\n readonly branch: string\n readonly closed: boolean\n readonly stdinClosed: boolean\n readonly queuedBytes: number\n write(channel: \"stdout\" | \"stderr\", data: Uint8Array): Promise<void>\n takeStdin(): Uint8Array\n end(): Promise<void>\n cancel(): void\n}\nconst limit = (value: number, name: string) => {\n if (!Number.isSafeInteger(value) || value < 1 || value > 16 * 1024 * 1024)\n throw new RangeError(`${name} must be 1..16777216`)\n return value\n}\nexport const createAttachStreams = (options: AttachStreamOptions = {}) => {\n const chunkBytes = limit(options.frameChunkBytes ?? 64 * 1024, \"frameChunkBytes\")\n const maxQueued = limit(options.maxQueuedBytes ?? 1024 * 1024, \"maxQueuedBytes\")\n const maxStdin = limit(options.maxStdinBytes ?? 1024 * 1024, \"maxStdinBytes\")\n const sessions = new Set<DockerAttachment>()\n let sequence = 0\n const connect = (selection: AttachSelection, socket: Duplex, runtime: DockerRuntime) => {\n const { api, containerId, namespace, branch } = selection\n let closed = false,\n outputClosed = false,\n retired = false,\n inputEnded = false,\n queuedBytes = 0,\n inputSize = 0\n let input: Buffer[] = []\n let tail: Promise<void> = Promise.resolve()\n let releaseReady = (_ready: boolean) => {}\n const ready = new Promise<boolean>((resolve) => {\n releaseReady = resolve\n })\n const valid = () => !closed && api.generation === selection.generation\n const closeInput = () => {\n inputEnded = true\n if (!valid() || retired || !selection.stdin || !selection.stdinOnce) return\n const c = api.state.containers.get(containerId)\n if (c && !c.stdinClosed) {\n api.state.containers.update(containerId, { ...c, stdinClosed: true })\n runtime.checkpoint(namespace, branch)\n }\n }\n let detachInvalidation = () => {},\n detachExit = () => {}\n const release = () => {\n if (closed) return\n closed = true\n outputClosed = true\n releaseReady(false)\n sessions.delete(handle)\n detachInvalidation()\n detachExit()\n socket.off(\"data\", onData)\n socket.off(\"end\", onEnd)\n }\n const cancel = () => {\n closeInput()\n release()\n input = []\n inputSize = 0\n socket.destroy()\n }\n const send = (bytes: Uint8Array) =>\n new Promise<void>((resolve, reject) => {\n const close = () => {\n socket.off(\"close\", close)\n reject(new Error(\"Attachment closed\"))\n }\n if (!valid() || socket.destroyed) {\n close()\n return\n }\n socket.once(\"close\", close)\n socket.write(bytes, (error) => {\n socket.off(\"close\", close)\n if (error) reject(error)\n else resolve()\n })\n })\n const onData = (chunk: Buffer) => {\n if (!valid() || retired) return\n if (!selection.stdin || api.state.containers.get(containerId)?.stdinClosed) return\n if (inputSize + chunk.length > maxStdin) {\n cancel()\n return\n }\n input.push(Buffer.from(chunk))\n inputSize += chunk.length\n }\n const onEnd = () => {\n closeInput()\n if (selection.stdin && !selection.stdinOnce) void handle.end().catch(cancel)\n }\n const finish = async () => {\n await tail\n if (valid() && !socket.destroyed) socket.end()\n }\n const handle: DockerAttachment = {\n id: ++sequence,\n containerId,\n namespace,\n branch,\n get closed() {\n return closed\n },\n get stdinClosed() {\n return inputEnded || api.state.containers.get(containerId)?.stdinClosed === true\n },\n get queuedBytes() {\n return queuedBytes\n },\n async write(channel, data) {\n if (!valid() || outputClosed) throw new Error(\"Attachment closed\")\n if (channel !== \"stdout\" && channel !== \"stderr\")\n throw new TypeError(\"Unknown output channel\")\n if (!selection[channel]) return\n const size = data.byteLength + 8\n if (size + queuedBytes > maxQueued)\n throw new RangeError(\"Attachment output queue limit exceeded\")\n const frame = Buffer.allocUnsafe(size)\n frame[0] = channel === \"stdout\" ? 1 : 2\n frame.fill(0, 1, 4)\n frame.writeUInt32BE(data.byteLength, 4)\n frame.set(data, 8)\n queuedBytes += size\n const result = tail.then(async () => {\n if (!(await ready) || !valid()) throw new Error(\"Attachment closed\")\n for (let at = 0; at < frame.length; at += chunkBytes)\n await send(frame.subarray(at, at + chunkBytes))\n })\n tail = result.catch(() => {})\n try {\n await result\n } finally {\n queuedBytes -= size\n }\n },\n takeStdin() {\n const result = Buffer.concat(input, inputSize)\n input = []\n inputSize = 0\n return result\n },\n async end() {\n if (!valid() || outputClosed) return\n outputClosed = true\n closeInput()\n const c = api.state.containers.get(containerId)\n if (selection.stdinOnce && c && isRunning(c)) return\n await finish()\n },\n cancel,\n }\n socket.once(\"close\", () => {\n if (valid()) closeInput()\n release()\n })\n detachInvalidation = api.onInvalidate(cancel)\n detachExit = api.lifecycle.onExit((id) => {\n if (id === containerId) {\n retired = true\n input = []\n inputSize = 0\n inputEnded = true\n outputClosed = true\n void finish().catch(cancel)\n }\n })\n sessions.add(handle)\n if (!valid()) {\n cancel()\n }\n return {\n handle,\n start(head: Buffer) {\n if (!valid()) return\n socket.on(\"data\", onData)\n socket.once(\"end\", onEnd)\n if (head.length) onData(head)\n releaseReady(true)\n socket.resume()\n if (!selection.stdin && !selection.stdout && !selection.stderr)\n void handle.end().catch(cancel)\n },\n cancel,\n }\n }\n return { connect, list: () => [...sessions] }\n}\n", "import { lstat } from \"node:fs/promises\"\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\"\nimport type { Socket } from \"node:net\"\nimport { isAbsolute } from \"node:path\"\nimport type { DockerRuntime } from \"./runtime.js\"\n\nexport type TransportOptions = {\n port?: number\n host?: string\n socketPath?: string\n /** Maximum buffered request bytes. Default 1 MiB. */\n maxBodyBytes?: number\n /** Deadline for receiving a body, independent of long-running responses. */\n bodyTimeoutMs?: number\n /** Maximum simultaneous owned connections. Default 128. */\n maxConnections?: number\n}\nconst positive = (value: number, name: string) => {\n if (!Number.isSafeInteger(value) || value <= 0)\n throw new RangeError(`${name} must be a positive integer`)\n return value\n}\n\nexport const listenDocker = async (\n runtime: DockerRuntime,\n options: TransportOptions,\n upgrade?: (\n req: IncomingMessage,\n socket: import(\"node:stream\").Duplex,\n head: Buffer,\n ) => Promise<void>,\n) => {\n const maxBody = positive(options.maxBodyBytes ?? 1024 * 1024, \"maxBodyBytes\")\n const bodyTimeout = positive(options.bodyTimeoutMs ?? 30_000, \"bodyTimeoutMs\")\n const maxConnections = positive(options.maxConnections ?? 128, \"maxConnections\")\n const path = options.socketPath\n if (path !== undefined) {\n if (!isAbsolute(path) || path.includes(\"\\0\") || Buffer.byteLength(path) > 103)\n throw new Error(\"socketPath must be an absolute Unix path of at most 103 bytes\")\n if (options.port !== undefined || options.host !== undefined)\n throw new Error(\"socketPath cannot be combined with port or host\")\n const existing = await lstat(path).then(\n () => true,\n (error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") return false\n throw error\n },\n )\n if (existing) throw new Error(\"Refusing existing socketPath\")\n }\n const sockets = new Set<Socket>()\n const handle = async (req: IncomingMessage, res: ServerResponse) => {\n const abort = new AbortController()\n const onClose = () => {\n if (!res.writableFinished) abort.abort()\n }\n res.once(\"close\", onClose)\n const reject = (status: number) => {\n res.writeHead(status, { \"content-type\": \"application/json\", connection: \"close\" })\n res.end(JSON.stringify({ message: `Mockingbird transport rejected request (${status})` }))\n }\n try {\n if (Number(req.headers[\"content-length\"]) > maxBody) {\n reject(413)\n return\n }\n const body = await new Promise<Buffer | undefined>((resolve, rejectBody) => {\n const chunks: Buffer[] = []\n let size = 0\n const cleanup = () => {\n clearTimeout(timer)\n req.off(\"data\", data)\n req.off(\"end\", end)\n req.off(\"error\", error)\n abort.signal.removeEventListener(\"abort\", canceled)\n }\n const canceled = () => {\n cleanup()\n rejectBody(new Error(\"Request disconnected\"))\n }\n const error = (e: Error) => {\n cleanup()\n rejectBody(e)\n }\n const end = () => {\n cleanup()\n resolve(Buffer.concat(chunks, size))\n }\n const data = (chunk: Buffer) => {\n size += chunk.length\n if (size > maxBody) {\n cleanup()\n req.pause()\n reject(413)\n resolve(undefined)\n return\n }\n chunks.push(chunk)\n }\n const timer = setTimeout(() => {\n cleanup()\n req.pause()\n reject(408)\n resolve(undefined)\n }, bodyTimeout)\n req.on(\"data\", data)\n req.once(\"end\", end)\n req.once(\"error\", error)\n abort.signal.addEventListener(\"abort\", canceled, { once: true })\n if (abort.signal.aborted) canceled()\n })\n if (body === undefined || abort.signal.aborted) return\n const headers = new Headers()\n for (let i = 0; i < req.rawHeaders.length; i += 2) {\n const name = req.rawHeaders[i],\n value = req.rawHeaders[i + 1]\n if (name !== undefined && value !== undefined) headers.append(name, value)\n }\n const method = req.method ?? \"GET\"\n const request = new Request(\n new URL((req.url ?? \"/\").replace(/^\\/+/, \"/\"), \"http://docker.mock\"),\n {\n method,\n headers,\n signal: abort.signal,\n ...(method !== \"GET\" && method !== \"HEAD\" && body.length\n ? { body: new Uint8Array(body) }\n : {}),\n },\n )\n const response = await runtime.fetch(request)\n if (abort.signal.aborted) {\n await response.body?.cancel()\n return\n }\n const outgoing: Record<string, string | string[]> = Object.fromEntries(response.headers)\n const cookies = response.headers.getSetCookie()\n if (cookies.length) outgoing[\"set-cookie\"] = cookies\n res.writeHead(response.status, outgoing)\n if (!response.body) {\n res.end()\n return\n }\n res.flushHeaders()\n const reader = response.body.getReader()\n const cancel = () => {\n void reader.cancel().catch(() => {})\n }\n abort.signal.addEventListener(\"abort\", cancel, { once: true })\n try {\n while (!abort.signal.aborted) {\n const { done, value } = await reader.read()\n if (done) break\n if (!res.write(value))\n await new Promise<void>((resolve) => {\n const finish = () => {\n res.off(\"drain\", finish)\n res.off(\"close\", finish)\n resolve()\n }\n res.once(\"drain\", finish)\n res.once(\"close\", finish)\n if (res.destroyed) finish()\n })\n }\n if (!res.destroyed) res.end()\n } finally {\n abort.signal.removeEventListener(\"abort\", cancel)\n reader.releaseLock()\n }\n } catch (error) {\n if (\n (error as { code?: string })?.code === \"MOCKINGBIRD_DROP\" ||\n abort.signal.aborted ||\n res.headersSent\n )\n res.destroy()\n else reject(500)\n } finally {\n res.off(\"close\", onClose)\n }\n }\n const busy = new WeakSet<Socket>()\n const server = createServer(\n {\n maxHeaderSize: 16 * 1024,\n headersTimeout: 30_000,\n requestTimeout: 30_000,\n keepAliveTimeout: 5_000,\n },\n (req, res) => {\n // Sequential keep-alive is supported; pipelining cannot accumulate handlers.\n if (req.socket.destroyed || busy.has(req.socket)) {\n req.socket.destroy()\n return\n }\n busy.add(req.socket)\n const release = () => {\n busy.delete(req.socket)\n res.off(\"finish\", release)\n res.off(\"close\", release)\n }\n res.once(\"finish\", release)\n res.once(\"close\", release)\n void handle(req, res)\n },\n )\n if (upgrade)\n server.on(\"upgrade\", (req, socket, head) => {\n if (socket.destroyed || busy.has(socket as Socket) || !sockets.has(socket as Socket)) {\n socket.destroy()\n return\n }\n busy.add(socket as Socket)\n void upgrade(req, socket, head)\n })\n server.on(\"connection\", (socket) => {\n if (sockets.size >= maxConnections) {\n socket.destroy()\n return\n }\n sockets.add(socket)\n socket.once(\"close\", () => sockets.delete(socket))\n })\n server.once(\"close\", () => runtime.close())\n const host = options.host ?? \"127.0.0.1\"\n await new Promise<void>((resolve, reject) => {\n const error = (error: Error) => {\n server.off(\"listening\", ready)\n reject(error)\n }\n const ready = () => {\n server.off(\"error\", error)\n resolve()\n }\n server.once(\"error\", error)\n server.once(\"listening\", ready)\n if (path !== undefined) server.listen(path)\n else server.listen(options.port ?? 0, host)\n })\n const address = server.address()\n const port = typeof address === \"object\" && address !== null ? address.port : 0\n let closing: Promise<void> | undefined\n return {\n server,\n host,\n port,\n ...(path !== undefined ? { socketPath: path } : {}),\n url:\n path === undefined\n ? `http://${host.includes(\":\") ? `[${host}]` : host}:${port}`\n : \"http://docker.mock\",\n close: () =>\n (closing ??= new Promise<void>((resolve, reject) => {\n runtime.close()\n server.close((error) => {\n if (error && (error as NodeJS.ErrnoException).code !== \"ERR_SERVER_NOT_RUNNING\")\n reject(error)\n else resolve()\n })\n for (const socket of sockets) socket.destroy()\n })),\n }\n}\n", "/// <reference types=\"node\" />\nimport type { Listening, ServeTarget } from \"@crvouga/mockingbird-adapter-node\"\nimport { type AttachHandshakeOptions, createAttachHandshake } from \"./attach.js\"\nimport { createRuntime, type DockerRuntime, type DockerRuntimeOptions } from \"./runtime.js\"\nimport type { AttachStreamOptions, DockerAttachment } from \"./streams.js\"\n\nexport type { AttachStreamOptions, DockerAttachment } from \"./streams.js\"\n\nimport { listenDocker, type TransportOptions } from \"./transport.js\"\n\nexport const DEFAULT_PORT = 8826\nexport type DockerServerOptions = Omit<DockerRuntimeOptions, \"onAttach\"> &\n TransportOptions & {\n attachHandshake?: AttachHandshakeOptions\n attachStreams?: AttachStreamOptions\n }\nexport type DockerServer = Listening & {\n runtime: DockerRuntime\n socketPath?: string\n attachments(): DockerAttachment[]\n}\n\n/** Node-only bounded HTTP transport over TCP or a test-owned Unix socket. */\nexport const createServer = async (options: DockerServerOptions = {}): Promise<DockerServer> => {\n const {\n port,\n host,\n socketPath,\n maxBodyBytes,\n bodyTimeoutMs,\n maxConnections,\n attachHandshake,\n attachStreams,\n ...rest\n } = options\n const attach = createAttachHandshake(attachHandshake, attachStreams)\n const runtime = createRuntime({ ...rest, onAttach: attach.prepare })\n try {\n const listening = await listenDocker(\n runtime,\n {\n ...(port !== undefined ? { port } : {}),\n ...(host !== undefined ? { host } : {}),\n ...(socketPath !== undefined ? { socketPath } : {}),\n ...(maxBodyBytes !== undefined ? { maxBodyBytes } : {}),\n ...(bodyTimeoutMs !== undefined ? { bodyTimeoutMs } : {}),\n ...(maxConnections !== undefined ? { maxConnections } : {}),\n },\n (req, socket, head) => attach.upgrade(runtime, req, socket, head),\n )\n return { ...listening, runtime, attachments: attach.attachments }\n } catch (error) {\n runtime.close()\n throw error\n }\n}\n\nexport const serveTarget: ServeTarget = {\n name: \"docker\",\n defaultPort: DEFAULT_PORT,\n create: (_values, common) =>\n createRuntime({\n ...(common.adminKey !== undefined ? { adminKey: common.adminKey } : {}),\n ...(common.adminControls !== undefined ? { adminControls: common.adminControls } : {}),\n ...(common.seed !== undefined ? { seed: common.seed } : {}),\n ...(common.onLog ? { onLog: common.onLog } : {}),\n }),\n banner: () => [\"Docker lifecycle: explicit simulated completion; no image execution or attach\"],\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["error", "createServer"]
7
7
  }