@otterdeploy/docker 0.2.0 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@otterdeploy/docker",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Modern TypeScript Docker Engine SDK with Result-based error handling",
5
5
  "keywords": [
6
6
  "container",
@@ -43,6 +43,7 @@
43
43
  },
44
44
  "scripts": {
45
45
  "build": "tsdown",
46
+ "changeset": "changeset",
46
47
  "prepublishOnly": "bun run build",
47
48
  "test": "vitest",
48
49
  "test:watch": "vitest watch",
@@ -59,6 +60,7 @@
59
60
  "ssh2": "^1.17.0"
60
61
  },
61
62
  "devDependencies": {
63
+ "@changesets/cli": "^2.30.0",
62
64
  "@types/bun": "latest",
63
65
  "oxfmt": "^0.35.0",
64
66
  "oxlint": "^1.50.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/errors.ts","../src/transport/helpers.ts","../src/transport/unix-transport.ts","../src/transport/tcp-transport.ts","../src/transport/ssh-transport.ts","../src/transport/npipe-transport.ts","../src/transport/index.ts","../src/client/dial.ts","../src/client/system.ts","../src/transport/http-duplex.ts","../src/client/exec.ts","../src/client/container.ts","../src/session/index.ts","../src/client/image.ts","../src/client/volume.ts","../src/client/network.ts","../src/client/service.ts","../src/client/task.ts","../src/client/node.ts","../src/client/secret.ts","../src/client/config.ts","../src/client/plugin.ts","../src/client/index.ts","../src/transport/stream-utils.ts"],"sourcesContent":["import { TaggedError } from \"better-result\";\n\n// ---------------------------------------------------------------------------\n// API Errors (carry readonly statusCode)\n// ---------------------------------------------------------------------------\n\nexport class DockerBadRequestError extends TaggedError(\"DockerBadRequestError\")<{\n message: string;\n}>() {\n readonly statusCode = 400 as const;\n}\n\nexport class DockerUnauthorizedError extends TaggedError(\"DockerUnauthorizedError\")<{\n message: string;\n}>() {\n readonly statusCode = 401 as const;\n}\n\nexport class DockerForbiddenError extends TaggedError(\"DockerForbiddenError\")<{\n message: string;\n}>() {\n readonly statusCode = 403 as const;\n}\n\nexport class DockerNotFoundError extends TaggedError(\"DockerNotFoundError\")<{\n message: string;\n}>() {\n readonly statusCode = 404 as const;\n}\n\nexport class DockerConflictError extends TaggedError(\"DockerConflictError\")<{\n message: string;\n}>() {\n readonly statusCode = 409 as const;\n}\n\nexport class DockerServerError extends TaggedError(\"DockerServerError\")<{\n message: string;\n}>() {\n readonly statusCode = 500 as const;\n}\n\nexport class DockerServiceUnavailableError extends TaggedError(\"DockerServiceUnavailableError\")<{\n message: string;\n}>() {\n readonly statusCode = 503 as const;\n}\n\n// ---------------------------------------------------------------------------\n// Transport Errors\n// ---------------------------------------------------------------------------\n\nexport class DockerNetworkError extends TaggedError(\"DockerNetworkError\")<{\n message: string;\n cause: unknown;\n}>() {}\n\nexport class DockerTimeoutError extends TaggedError(\"DockerTimeoutError\")<{\n message: string;\n timeoutMs: number;\n}>() {}\n\nexport class DockerAbortError extends TaggedError(\"DockerAbortError\")<{\n message: string;\n}>() {}\n\nexport class DockerDecodeError extends TaggedError(\"DockerDecodeError\")<{\n message: string;\n cause: unknown;\n body: string;\n}>() {}\n\n// ---------------------------------------------------------------------------\n// Catch-all Error\n// ---------------------------------------------------------------------------\n\nexport class DockerUnknownError extends TaggedError(\"DockerUnknownError\")<{\n message: string;\n statusCode: number;\n}>() {}\n\n// ---------------------------------------------------------------------------\n// Type Unions\n// ---------------------------------------------------------------------------\n\nexport type DockerApiError =\n | DockerBadRequestError\n | DockerUnauthorizedError\n | DockerForbiddenError\n | DockerNotFoundError\n | DockerConflictError\n | DockerServerError\n | DockerServiceUnavailableError;\n\nexport type DockerTransportError =\n | DockerNetworkError\n | DockerTimeoutError\n | DockerAbortError\n | DockerDecodeError;\n\nexport type DockerError = DockerApiError | DockerTransportError | DockerUnknownError;\n\n// ---------------------------------------------------------------------------\n// Factory function\n// ---------------------------------------------------------------------------\n\n/**\n * Maps an HTTP status code to the appropriate Docker error class.\n * Unknown status codes produce a DockerUnknownError.\n */\nexport function statusCodeToError(\n statusCode: number,\n message: string,\n): DockerApiError | DockerUnknownError {\n switch (statusCode) {\n case 400:\n return new DockerBadRequestError({ message });\n case 401:\n return new DockerUnauthorizedError({ message });\n case 403:\n return new DockerForbiddenError({ message });\n case 404:\n return new DockerNotFoundError({ message });\n case 409:\n return new DockerConflictError({ message });\n case 500:\n return new DockerServerError({ message });\n case 503:\n return new DockerServiceUnavailableError({ message });\n default:\n return new DockerUnknownError({ message, statusCode });\n }\n}\n","/**\n * Shared helper functions used across all transport implementations.\n */\n\n/**\n * Builds the request path, appending query parameters if present.\n */\nexport function buildPath(path: string, query?: Record<string, unknown>): string {\n if (!query || Object.keys(query).length === 0) {\n return path;\n }\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) {\n params.append(key, String(value));\n }\n }\n return `${path}?${params.toString()}`;\n}\n\n/**\n * Collects all chunks from a readable stream into a single string.\n */\nexport function collectBody(stream: NodeJS.ReadableStream): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n stream.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n stream.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n stream.on(\"error\", reject);\n });\n}\n\n/**\n * Extracts error message from Docker API error response body.\n * Docker typically returns `{ message: \"...\" }`.\n */\nexport function extractErrorMessage(body: string): string {\n try {\n const parsed = JSON.parse(body);\n if (typeof parsed === \"object\" && parsed !== null && typeof parsed.message === \"string\") {\n return parsed.message;\n }\n } catch {\n // If we can't parse, use the raw body\n }\n return body || \"Unknown error\";\n}\n","import * as http from \"node:http\";\nimport type * as net from \"node:net\";\nimport { Result } from \"better-result\";\nimport {\n DockerNetworkError,\n DockerTimeoutError,\n DockerAbortError,\n statusCodeToError,\n type DockerError,\n} from \"../errors.ts\";\nimport type { Transport, DialOptions, DialResponse } from \"./types.ts\";\nimport { buildPath, collectBody, extractErrorMessage } from \"./helpers.ts\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype RequestFn = typeof http.request;\n\nexport type UnixTransportOptions = {\n socketPath?: string;\n /** @internal For testing only. Override the http.request function. */\n _requestFn?: RequestFn;\n};\n\n// ---------------------------------------------------------------------------\n// UnixTransport\n// ---------------------------------------------------------------------------\n\nexport class UnixTransport implements Transport {\n private readonly socketPath: string;\n private readonly requestFn: RequestFn;\n\n constructor(options: UnixTransportOptions) {\n this.socketPath =\n options.socketPath ??\n process.env.DOCKER_HOST?.replace(\"unix://\", \"\") ??\n \"/var/run/docker.sock\";\n this.requestFn = options._requestFn ?? http.request;\n }\n\n async dial(options: DialOptions): Promise<Result<DialResponse, DockerError>> {\n return Result.tryPromise({\n try: () => this.performRequest(options, false) as Promise<DialResponse>,\n catch: (cause) => this.convertError(cause),\n });\n }\n\n async dialStream(options: DialOptions): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return Result.tryPromise({\n try: () => this.performRequest(options, true) as Promise<NodeJS.ReadableStream>,\n catch: (cause) => this.convertError(cause),\n });\n }\n\n async dialHijack(options: DialOptions): Promise<Result<net.Socket, DockerError>> {\n return Result.tryPromise({\n try: () => this.performHijack(options),\n catch: (cause) => this.convertError(cause),\n });\n }\n\n destroy(): void {\n // No-op: no persistent connections to clean up\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n private performHijack(options: DialOptions): Promise<net.Socket> {\n return new Promise((resolve, reject) => {\n const requestPath = buildPath(options.path, options.query);\n\n const headers: Record<string, string> = {\n Connection: \"Upgrade\",\n Upgrade: \"tcp\",\n ...options.headers,\n };\n\n if (options.authconfig) {\n headers[\"X-Registry-Auth\"] = Buffer.from(JSON.stringify(options.authconfig)).toString(\n \"base64\",\n );\n }\n\n const body = options.body;\n let bodyStr: string | undefined;\n if (body !== undefined && typeof body !== \"string\" && !Buffer.isBuffer(body)) {\n bodyStr = JSON.stringify(body);\n if (!headers[\"Content-Type\"] && !headers[\"content-type\"]) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n headers[\"Content-Length\"] = Buffer.byteLength(bodyStr).toString();\n }\n\n const req = this.requestFn(\n {\n socketPath: this.socketPath,\n path: requestPath,\n method: options.method,\n headers,\n },\n (res) => {\n // If the server didn't upgrade, treat it as an error\n reject(\n new DockerNetworkError({\n message: `Expected upgrade response, got status ${res.statusCode}`,\n cause: undefined,\n }),\n );\n },\n );\n\n req.on(\"upgrade\", (_res, socket, _head) => {\n resolve(socket as net.Socket);\n });\n\n req.on(\"error\", (err) => {\n reject(\n new DockerNetworkError({\n message: `Connection error: ${err.message}`,\n cause: err,\n }),\n );\n });\n\n if (bodyStr !== undefined) {\n req.write(bodyStr);\n }\n req.end();\n });\n }\n\n private performRequest(\n options: DialOptions,\n isStream: boolean,\n ): Promise<DialResponse | NodeJS.ReadableStream> {\n return new Promise((resolve, reject) => {\n const requestPath = buildPath(options.path, options.query);\n\n const headers: Record<string, string> = {\n ...options.headers,\n };\n\n // Inject registry auth headers\n if (options.authconfig) {\n headers[\"X-Registry-Auth\"] = Buffer.from(JSON.stringify(options.authconfig)).toString(\n \"base64\",\n );\n }\n if (options.registryconfig) {\n headers[\"X-Registry-Config\"] = Buffer.from(JSON.stringify(options.registryconfig)).toString(\n \"base64\",\n );\n }\n\n // Determine body type and set headers accordingly\n const body = options.body;\n const isStreamBody =\n body !== null &&\n body !== undefined &&\n typeof body === \"object\" &&\n typeof (body as NodeJS.ReadableStream).pipe === \"function\";\n const isBufferBody = Buffer.isBuffer(body);\n const isStringBody = typeof body === \"string\";\n\n let bodyStr: string | undefined;\n if (body !== undefined && !isStreamBody && !isBufferBody && !isStringBody) {\n bodyStr = JSON.stringify(body);\n if (!headers[\"Content-Type\"] && !headers[\"content-type\"]) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n headers[\"Content-Length\"] = Buffer.byteLength(bodyStr).toString();\n } else if (isBufferBody) {\n headers[\"Content-Length\"] = (body as Buffer).length.toString();\n } else if (isStringBody) {\n headers[\"Content-Length\"] = Buffer.byteLength(body as string).toString();\n } else if (isStreamBody) {\n headers[\"Transfer-Encoding\"] = \"chunked\";\n }\n\n const req = this.requestFn(\n {\n socketPath: this.socketPath,\n path: requestPath,\n method: options.method,\n headers,\n },\n (res) => {\n const statusCode = res.statusCode ?? 0;\n const responseHeaders = (res.headers ?? {}) as Record<string, string>;\n\n // Check if this is a success status\n const isSuccess = options.statusCodes[statusCode] === true;\n\n if (isStream && isSuccess) {\n // For stream requests on success, return the raw stream\n resolve(res as unknown as NodeJS.ReadableStream);\n return;\n }\n\n // Collect body for both success and error cases\n collectBody(res as unknown as NodeJS.ReadableStream)\n .then((bodyText) => {\n if (isSuccess) {\n // 204 No Content or empty body\n if (statusCode === 204 || bodyText.length === 0) {\n resolve({\n statusCode,\n headers: responseHeaders,\n body: null,\n });\n return;\n }\n\n // Try to parse as JSON, fall back to raw text\n try {\n const parsed = JSON.parse(bodyText);\n resolve({\n statusCode,\n headers: responseHeaders,\n body: parsed,\n });\n } catch {\n // Not JSON — return raw text (e.g. _ping returns \"OK\")\n resolve({\n statusCode,\n headers: responseHeaders,\n body: bodyText,\n });\n }\n } else {\n // Error status: extract message and create appropriate error\n const message = extractErrorMessage(bodyText);\n reject(statusCodeToError(statusCode, message));\n }\n })\n .catch((collectErr) => {\n reject(\n new DockerNetworkError({\n message: `Failed to read response body: ${String(collectErr)}`,\n cause: collectErr,\n }),\n );\n });\n },\n );\n\n // Handle connection errors\n req.on(\"error\", (err) => {\n reject(\n new DockerNetworkError({\n message: `Connection error: ${err.message}`,\n cause: err,\n }),\n );\n });\n\n // Handle timeout\n if (options.timeout !== undefined) {\n req.setTimeout(options.timeout, () => {\n req.destroy();\n reject(\n new DockerTimeoutError({\n message: `Request timed out after ${options.timeout}ms`,\n timeoutMs: options.timeout!,\n }),\n );\n });\n }\n\n // Handle abort signal\n if (options.signal) {\n if (options.signal.aborted) {\n req.destroy();\n reject(\n new DockerAbortError({\n message: \"Request aborted\",\n }),\n );\n return;\n }\n options.signal.addEventListener(\n \"abort\",\n () => {\n req.destroy();\n reject(\n new DockerAbortError({\n message: \"Request aborted\",\n }),\n );\n },\n { once: true },\n );\n }\n\n // Send body based on type\n if (isStreamBody) {\n (body as NodeJS.ReadableStream).pipe(req);\n } else if (isBufferBody) {\n req.write(body as Buffer);\n req.end();\n } else if (isStringBody) {\n req.write(body as string);\n req.end();\n } else if (bodyStr !== undefined) {\n req.write(bodyStr);\n req.end();\n } else {\n req.end();\n }\n });\n }\n\n /**\n * Converts errors thrown from the inner promise back into DockerError types.\n * Errors that are already tagged DockerErrors pass through; unknown errors\n * become DockerNetworkError.\n */\n private convertError(cause: unknown): DockerError {\n // If the error is already one of our tagged errors, return it directly\n if (cause !== null && typeof cause === \"object\" && \"_tag\" in cause) {\n return cause as DockerError;\n }\n\n // Unknown error: wrap in DockerNetworkError\n return new DockerNetworkError({\n message: `Unexpected error: ${cause instanceof Error ? cause.message : String(cause)}`,\n cause,\n });\n }\n}\n","import * as http from \"node:http\";\nimport * as https from \"node:https\";\nimport type * as net from \"node:net\";\nimport { Result } from \"better-result\";\nimport {\n DockerNetworkError,\n DockerTimeoutError,\n DockerAbortError,\n statusCodeToError,\n type DockerError,\n} from \"../errors.ts\";\nimport type { Transport, DialOptions, DialResponse, TlsConfig } from \"./types.ts\";\nimport { buildPath, collectBody, extractErrorMessage } from \"./helpers.ts\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype RequestFn = typeof http.request;\n\nexport type TcpTransportOptions = {\n host: string;\n port?: number;\n tls?: TlsConfig;\n /** @internal For testing only. Override the request function. */\n _requestFn?: RequestFn;\n};\n\n// ---------------------------------------------------------------------------\n// TcpTransport\n// ---------------------------------------------------------------------------\n\nexport class TcpTransport implements Transport {\n private readonly host: string;\n private readonly port: number;\n private readonly agent?: https.Agent;\n private readonly useHttps: boolean;\n private readonly requestFn: RequestFn;\n\n constructor(options: TcpTransportOptions) {\n this.useHttps = !!options.tls;\n this.host = options.host;\n this.port = options.port ?? (this.useHttps ? 2376 : 2375);\n\n if (options.tls) {\n this.agent = new https.Agent({\n ca: options.tls.ca,\n cert: options.tls.cert,\n key: options.tls.key,\n rejectUnauthorized: options.tls.rejectUnauthorized ?? true,\n });\n }\n\n this.requestFn = options._requestFn ?? (this.useHttps ? https.request : http.request);\n }\n\n async dial(options: DialOptions): Promise<Result<DialResponse, DockerError>> {\n return Result.tryPromise({\n try: () => this.performRequest(options, false) as Promise<DialResponse>,\n catch: (cause) => this.convertError(cause),\n });\n }\n\n async dialStream(options: DialOptions): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return Result.tryPromise({\n try: () => this.performRequest(options, true) as Promise<NodeJS.ReadableStream>,\n catch: (cause) => this.convertError(cause),\n });\n }\n\n async dialHijack(options: DialOptions): Promise<Result<net.Socket, DockerError>> {\n return Result.tryPromise({\n try: () => this.performHijack(options),\n catch: (cause) => this.convertError(cause),\n });\n }\n\n destroy(): void {\n if (this.agent) {\n this.agent.destroy();\n }\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n private performHijack(options: DialOptions): Promise<net.Socket> {\n return new Promise((resolve, reject) => {\n const requestPath = buildPath(options.path, options.query);\n\n const headers: Record<string, string> = {\n Connection: \"Upgrade\",\n Upgrade: \"tcp\",\n ...options.headers,\n };\n\n if (options.authconfig) {\n headers[\"X-Registry-Auth\"] = Buffer.from(JSON.stringify(options.authconfig)).toString(\n \"base64\",\n );\n }\n\n const body = options.body;\n let bodyStr: string | undefined;\n if (body !== undefined && typeof body !== \"string\" && !Buffer.isBuffer(body)) {\n bodyStr = JSON.stringify(body);\n if (!headers[\"Content-Type\"] && !headers[\"content-type\"]) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n headers[\"Content-Length\"] = Buffer.byteLength(bodyStr).toString();\n }\n\n const requestOpts: http.RequestOptions = {\n hostname: this.host,\n port: this.port,\n path: requestPath,\n method: options.method,\n headers,\n };\n\n if (this.agent) {\n requestOpts.agent = this.agent;\n }\n\n const req = this.requestFn(requestOpts, (res) => {\n reject(\n new DockerNetworkError({\n message: `Expected upgrade response, got status ${res.statusCode}`,\n cause: undefined,\n }),\n );\n });\n\n req.on(\"upgrade\", (_res, socket, _head) => {\n resolve(socket as net.Socket);\n });\n\n req.on(\"error\", (err) => {\n reject(\n new DockerNetworkError({\n message: `Connection error: ${err.message}`,\n cause: err,\n }),\n );\n });\n\n if (bodyStr !== undefined) {\n req.write(bodyStr);\n }\n req.end();\n });\n }\n\n private performRequest(\n options: DialOptions,\n isStream: boolean,\n ): Promise<DialResponse | NodeJS.ReadableStream> {\n return new Promise((resolve, reject) => {\n const requestPath = buildPath(options.path, options.query);\n\n const headers: Record<string, string> = {\n ...options.headers,\n };\n\n // Inject registry auth headers\n if (options.authconfig) {\n headers[\"X-Registry-Auth\"] = Buffer.from(JSON.stringify(options.authconfig)).toString(\n \"base64\",\n );\n }\n if (options.registryconfig) {\n headers[\"X-Registry-Config\"] = Buffer.from(JSON.stringify(options.registryconfig)).toString(\n \"base64\",\n );\n }\n\n // Determine body type and set headers accordingly\n const body = options.body;\n const isStreamBody =\n body !== null &&\n body !== undefined &&\n typeof body === \"object\" &&\n typeof (body as NodeJS.ReadableStream).pipe === \"function\";\n const isBufferBody = Buffer.isBuffer(body);\n const isStringBody = typeof body === \"string\";\n\n let bodyStr: string | undefined;\n if (body !== undefined && !isStreamBody && !isBufferBody && !isStringBody) {\n bodyStr = JSON.stringify(body);\n if (!headers[\"Content-Type\"] && !headers[\"content-type\"]) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n headers[\"Content-Length\"] = Buffer.byteLength(bodyStr).toString();\n } else if (isBufferBody) {\n headers[\"Content-Length\"] = (body as Buffer).length.toString();\n } else if (isStringBody) {\n headers[\"Content-Length\"] = Buffer.byteLength(body as string).toString();\n } else if (isStreamBody) {\n headers[\"Transfer-Encoding\"] = \"chunked\";\n }\n\n const requestOpts: http.RequestOptions = {\n hostname: this.host,\n port: this.port,\n path: requestPath,\n method: options.method,\n headers,\n };\n\n if (this.agent) {\n requestOpts.agent = this.agent;\n }\n\n const req = this.requestFn(requestOpts, (res) => {\n const statusCode = res.statusCode ?? 0;\n const responseHeaders = (res.headers ?? {}) as Record<string, string>;\n\n // Check if this is a success status\n const isSuccess = options.statusCodes[statusCode] === true;\n\n if (isStream && isSuccess) {\n // For stream requests on success, return the raw stream\n resolve(res as unknown as NodeJS.ReadableStream);\n return;\n }\n\n // Collect body for both success and error cases\n collectBody(res as unknown as NodeJS.ReadableStream)\n .then((bodyText) => {\n if (isSuccess) {\n // 204 No Content or empty body\n if (statusCode === 204 || bodyText.length === 0) {\n resolve({\n statusCode,\n headers: responseHeaders,\n body: null,\n });\n return;\n }\n\n // Try to parse as JSON, fall back to raw text\n try {\n const parsed = JSON.parse(bodyText);\n resolve({\n statusCode,\n headers: responseHeaders,\n body: parsed,\n });\n } catch {\n // Not JSON — return raw text (e.g. _ping returns \"OK\")\n resolve({\n statusCode,\n headers: responseHeaders,\n body: bodyText,\n });\n }\n } else {\n // Error status: extract message and create appropriate error\n const message = extractErrorMessage(bodyText);\n reject(statusCodeToError(statusCode, message));\n }\n })\n .catch((collectErr) => {\n reject(\n new DockerNetworkError({\n message: `Failed to read response body: ${String(collectErr)}`,\n cause: collectErr,\n }),\n );\n });\n });\n\n // Handle connection errors\n req.on(\"error\", (err) => {\n reject(\n new DockerNetworkError({\n message: `Connection error: ${err.message}`,\n cause: err,\n }),\n );\n });\n\n // Handle timeout\n if (options.timeout !== undefined) {\n req.setTimeout(options.timeout, () => {\n req.destroy();\n reject(\n new DockerTimeoutError({\n message: `Request timed out after ${options.timeout}ms`,\n timeoutMs: options.timeout!,\n }),\n );\n });\n }\n\n // Handle abort signal\n if (options.signal) {\n if (options.signal.aborted) {\n req.destroy();\n reject(\n new DockerAbortError({\n message: \"Request aborted\",\n }),\n );\n return;\n }\n options.signal.addEventListener(\n \"abort\",\n () => {\n req.destroy();\n reject(\n new DockerAbortError({\n message: \"Request aborted\",\n }),\n );\n },\n { once: true },\n );\n }\n\n // Send body based on type\n if (isStreamBody) {\n (body as NodeJS.ReadableStream).pipe(req);\n } else if (isBufferBody) {\n req.write(body as Buffer);\n req.end();\n } else if (isStringBody) {\n req.write(body as string);\n req.end();\n } else if (bodyStr !== undefined) {\n req.write(bodyStr);\n req.end();\n } else {\n req.end();\n }\n });\n }\n\n /**\n * Converts errors thrown from the inner promise back into DockerError types.\n * Errors that are already tagged DockerErrors pass through; unknown errors\n * become DockerNetworkError.\n */\n private convertError(cause: unknown): DockerError {\n // If the error is already one of our tagged errors, return it directly\n if (cause !== null && typeof cause === \"object\" && \"_tag\" in cause) {\n return cause as DockerError;\n }\n\n // Unknown error: wrap in DockerNetworkError\n return new DockerNetworkError({\n message: `Unexpected error: ${cause instanceof Error ? cause.message : String(cause)}`,\n cause,\n });\n }\n}\n","import { Client } from \"ssh2\";\nimport { Readable } from \"node:stream\";\nimport type * as net from \"node:net\";\nimport { Result } from \"better-result\";\nimport {\n DockerNetworkError,\n statusCodeToError,\n type DockerError,\n} from \"../errors.ts\";\nimport type { Transport, DialOptions, DialResponse } from \"./types.ts\";\nimport { buildPath, extractErrorMessage } from \"./helpers.ts\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype ClientFactory = () => Client;\n\nexport type SshTransportOptions = {\n host: string;\n port?: number;\n username: string;\n privateKey?: string;\n passphrase?: string;\n /** @internal For testing only. Override the ssh2 Client factory. */\n _clientFactory?: ClientFactory;\n};\n\n/**\n * Builds a raw HTTP/1.1 request string to send over the dial-stdio stream.\n */\nfunction buildHttpRequest(options: DialOptions): { header: string; bodyStr?: string } {\n const requestPath = buildPath(options.path, options.query);\n\n const headers: Record<string, string> = {\n Host: \"docker\",\n ...options.headers,\n };\n\n // Inject registry auth headers\n if (options.authconfig) {\n headers[\"X-Registry-Auth\"] = Buffer.from(JSON.stringify(options.authconfig)).toString(\"base64\");\n }\n if (options.registryconfig) {\n headers[\"X-Registry-Config\"] = Buffer.from(JSON.stringify(options.registryconfig)).toString(\n \"base64\",\n );\n }\n\n const body = options.body;\n const isStreamBody =\n body !== null &&\n body !== undefined &&\n typeof body === \"object\" &&\n typeof (body as NodeJS.ReadableStream).pipe === \"function\";\n const isBufferBody = Buffer.isBuffer(body);\n const isStringBody = typeof body === \"string\";\n\n let bodyStr: string | undefined;\n if (body !== undefined && !isStreamBody && !isBufferBody && !isStringBody) {\n bodyStr = JSON.stringify(body);\n if (!headers[\"Content-Type\"] && !headers[\"content-type\"]) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n headers[\"Content-Length\"] = Buffer.byteLength(bodyStr).toString();\n } else if (isBufferBody) {\n bodyStr = (body as Buffer).toString();\n headers[\"Content-Length\"] = (body as Buffer).length.toString();\n } else if (isStringBody) {\n bodyStr = body as string;\n headers[\"Content-Length\"] = Buffer.byteLength(body as string).toString();\n } else if (isStreamBody) {\n headers[\"Transfer-Encoding\"] = \"chunked\";\n }\n\n let header = `${options.method} ${requestPath} HTTP/1.1\\r\\n`;\n for (const [key, value] of Object.entries(headers)) {\n header += `${key}: ${value}\\r\\n`;\n }\n header += \"\\r\\n\";\n\n return { header, bodyStr };\n}\n\n/**\n * Parses a raw HTTP response from the stream into status code, headers, and body.\n */\nfunction parseHttpResponse(raw: string): {\n statusCode: number;\n headers: Record<string, string>;\n body: string;\n} {\n const headerEndIdx = raw.indexOf(\"\\r\\n\\r\\n\");\n const headerSection = headerEndIdx >= 0 ? raw.slice(0, headerEndIdx) : raw;\n const body = headerEndIdx >= 0 ? raw.slice(headerEndIdx + 4) : \"\";\n\n const lines = headerSection.split(\"\\r\\n\");\n const statusLine = lines[0] ?? \"\";\n const statusMatch = statusLine.match(/^HTTP\\/\\d\\.\\d\\s+(\\d+)/);\n const statusCode = statusMatch?.[1] ? Number.parseInt(statusMatch[1], 10) : 0;\n\n const headers: Record<string, string> = {};\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i];\n if (!line) continue;\n const colonIdx = line.indexOf(\":\");\n if (colonIdx > 0) {\n const key = line.slice(0, colonIdx).trim().toLowerCase();\n const value = line.slice(colonIdx + 1).trim();\n headers[key] = value;\n }\n }\n\n return { statusCode, headers, body };\n}\n\n// ---------------------------------------------------------------------------\n// SshTransport\n// ---------------------------------------------------------------------------\n\nexport class SshTransport implements Transport {\n private readonly host: string;\n private readonly port: number;\n private readonly username: string;\n private readonly privateKey?: string;\n private readonly passphrase?: string;\n private readonly clientFactory: ClientFactory;\n\n constructor(opts: SshTransportOptions) {\n this.host = opts.host;\n this.port = opts.port ?? 22;\n this.username = opts.username;\n this.privateKey = opts.privateKey;\n this.passphrase = opts.passphrase;\n this.clientFactory = opts._clientFactory ?? (() => new Client());\n }\n\n async dial(options: DialOptions): Promise<Result<DialResponse, DockerError>> {\n return Result.tryPromise({\n try: () => this.performRequest(options, false) as Promise<DialResponse>,\n catch: (cause) => this.convertError(cause),\n });\n }\n\n async dialStream(options: DialOptions): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return Result.tryPromise({\n try: () => this.performRequest(options, true) as Promise<NodeJS.ReadableStream>,\n catch: (cause) => this.convertError(cause),\n });\n }\n\n async dialHijack(_options: DialOptions): Promise<Result<net.Socket, DockerError>> {\n return Result.err(\n new DockerNetworkError({\n message: \"dialHijack is not supported over SSH transport\",\n cause: undefined,\n }),\n );\n }\n\n destroy(): void {\n // No-op: connections are created per-request, not pooled\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n /**\n * Connects to the SSH host, runs `docker system dial-stdio`, writes an\n * HTTP request over the resulting bidirectional stream, and parses the\n * HTTP response.\n */\n private performRequest(\n options: DialOptions,\n isStream: boolean,\n ): Promise<DialResponse | NodeJS.ReadableStream> {\n return new Promise((resolve, reject) => {\n const client = this.clientFactory();\n\n client.on(\"ready\", () => {\n client.exec(\"docker system dial-stdio\", (err, stream) => {\n if (err) {\n client.end();\n reject(\n new DockerNetworkError({\n message: `SSH exec error: ${err.message}`,\n cause: err,\n }),\n );\n return;\n }\n\n // Write the HTTP request to the stream\n const { header, bodyStr: httpBody } = buildHttpRequest(options);\n stream.write(header);\n\n // Handle stream body by piping\n const body = options.body;\n const isStreamBody =\n body !== null &&\n body !== undefined &&\n typeof body === \"object\" &&\n typeof (body as NodeJS.ReadableStream).pipe === \"function\";\n\n if (isStreamBody) {\n (body as NodeJS.ReadableStream).pipe(stream, { end: false });\n } else if (httpBody !== undefined) {\n stream.write(httpBody);\n }\n\n // Collect the HTTP response\n const chunks: Buffer[] = [];\n\n stream.on(\"data\", (chunk: Buffer) => {\n chunks.push(chunk);\n });\n\n stream.on(\"end\", () => {\n client.end();\n\n const raw = Buffer.concat(chunks).toString(\"utf-8\");\n const { statusCode, headers, body } = parseHttpResponse(raw);\n\n const isSuccess = options.statusCodes[statusCode] === true;\n\n if (isStream && isSuccess) {\n // For stream requests, wrap the remaining body in a Readable\n const bodyStream = new Readable({\n read() {\n this.push(body ? Buffer.from(body) : null);\n this.push(null);\n },\n });\n resolve(bodyStream);\n return;\n }\n\n if (isSuccess) {\n // 204 No Content or empty body\n if (statusCode === 204 || body.length === 0) {\n resolve({\n statusCode,\n headers,\n body: null,\n });\n return;\n }\n\n // Try to parse as JSON, fall back to raw text\n try {\n const parsed = JSON.parse(body);\n resolve({\n statusCode,\n headers,\n body: parsed,\n });\n } catch {\n // Not JSON — return raw text (e.g. _ping returns \"OK\")\n resolve({\n statusCode,\n headers,\n body,\n });\n }\n } else {\n // Error status: extract message and create appropriate error\n const message = extractErrorMessage(body);\n reject(statusCodeToError(statusCode, message));\n }\n });\n\n stream.on(\"error\", (streamErr: Error) => {\n client.end();\n reject(\n new DockerNetworkError({\n message: `Stream error: ${streamErr.message}`,\n cause: streamErr,\n }),\n );\n });\n });\n });\n\n client.on(\"error\", (connErr: Error) => {\n reject(\n new DockerNetworkError({\n message: `SSH connection error: ${connErr.message}`,\n cause: connErr,\n }),\n );\n });\n\n client.connect({\n host: this.host,\n port: this.port,\n username: this.username,\n privateKey: this.privateKey,\n passphrase: this.passphrase,\n });\n });\n }\n\n /**\n * Converts errors thrown from the inner promise back into DockerError types.\n * Errors that are already tagged DockerErrors pass through; unknown errors\n * become DockerNetworkError.\n */\n private convertError(cause: unknown): DockerError {\n // If the error is already one of our tagged errors, return it directly\n if (cause !== null && typeof cause === \"object\" && \"_tag\" in cause) {\n return cause as DockerError;\n }\n\n // Unknown error: wrap in DockerNetworkError\n return new DockerNetworkError({\n message: `Unexpected error: ${cause instanceof Error ? cause.message : String(cause)}`,\n cause,\n });\n }\n}\n","import * as http from \"node:http\";\nimport type * as net from \"node:net\";\nimport { Result } from \"better-result\";\nimport {\n DockerNetworkError,\n DockerTimeoutError,\n DockerAbortError,\n statusCodeToError,\n type DockerError,\n} from \"../errors.ts\";\nimport type { Transport, DialOptions, DialResponse } from \"./types.ts\";\nimport { buildPath, collectBody, extractErrorMessage } from \"./helpers.ts\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype RequestFn = typeof http.request;\n\nconst DEFAULT_PIPE_PATH = \"\\\\\\\\.\\\\pipe\\\\docker_engine\";\n\nexport type NamedPipeTransportOptions = {\n path?: string;\n /** @internal For testing only. Override the http.request function. */\n _requestFn?: RequestFn;\n};\n\n// ---------------------------------------------------------------------------\n// NamedPipeTransport — Windows named pipe transport for Docker\n// ---------------------------------------------------------------------------\n\nexport class NamedPipeTransport implements Transport {\n private readonly pipePath: string;\n private readonly requestFn: RequestFn;\n\n constructor(options: NamedPipeTransportOptions) {\n this.pipePath = options.path ?? DEFAULT_PIPE_PATH;\n this.requestFn = options._requestFn ?? http.request;\n }\n\n async dial(options: DialOptions): Promise<Result<DialResponse, DockerError>> {\n return Result.tryPromise({\n try: () => this.performRequest(options, false) as Promise<DialResponse>,\n catch: (cause) => this.convertError(cause),\n });\n }\n\n async dialStream(options: DialOptions): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return Result.tryPromise({\n try: () => this.performRequest(options, true) as Promise<NodeJS.ReadableStream>,\n catch: (cause) => this.convertError(cause),\n });\n }\n\n async dialHijack(options: DialOptions): Promise<Result<net.Socket, DockerError>> {\n return Result.tryPromise({\n try: () => this.performHijack(options),\n catch: (cause) => this.convertError(cause),\n });\n }\n\n destroy(): void {\n // No-op: no persistent connections to clean up\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n private performHijack(options: DialOptions): Promise<net.Socket> {\n return new Promise((resolve, reject) => {\n const requestPath = buildPath(options.path, options.query);\n\n const headers: Record<string, string> = {\n Connection: \"Upgrade\",\n Upgrade: \"tcp\",\n ...options.headers,\n };\n\n if (options.authconfig) {\n headers[\"X-Registry-Auth\"] = Buffer.from(JSON.stringify(options.authconfig)).toString(\n \"base64\",\n );\n }\n\n const body = options.body;\n let bodyStr: string | undefined;\n if (body !== undefined && typeof body !== \"string\" && !Buffer.isBuffer(body)) {\n bodyStr = JSON.stringify(body);\n if (!headers[\"Content-Type\"] && !headers[\"content-type\"]) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n headers[\"Content-Length\"] = Buffer.byteLength(bodyStr).toString();\n }\n\n const req = this.requestFn(\n {\n socketPath: this.pipePath,\n path: requestPath,\n method: options.method,\n headers,\n },\n (res) => {\n reject(\n new DockerNetworkError({\n message: `Expected upgrade response, got status ${res.statusCode}`,\n cause: undefined,\n }),\n );\n },\n );\n\n req.on(\"upgrade\", (_res, socket, _head) => {\n resolve(socket as net.Socket);\n });\n\n req.on(\"error\", (err) => {\n reject(\n new DockerNetworkError({\n message: `Connection error: ${err.message}`,\n cause: err,\n }),\n );\n });\n\n if (bodyStr !== undefined) {\n req.write(bodyStr);\n }\n req.end();\n });\n }\n\n private performRequest(\n options: DialOptions,\n isStream: boolean,\n ): Promise<DialResponse | NodeJS.ReadableStream> {\n return new Promise((resolve, reject) => {\n const requestPath = buildPath(options.path, options.query);\n\n const headers: Record<string, string> = {\n ...options.headers,\n };\n\n // Inject registry auth headers\n if (options.authconfig) {\n headers[\"X-Registry-Auth\"] = Buffer.from(JSON.stringify(options.authconfig)).toString(\n \"base64\",\n );\n }\n if (options.registryconfig) {\n headers[\"X-Registry-Config\"] = Buffer.from(JSON.stringify(options.registryconfig)).toString(\n \"base64\",\n );\n }\n\n // Determine body type and set headers accordingly\n const body = options.body;\n const isStreamBody =\n body !== null &&\n body !== undefined &&\n typeof body === \"object\" &&\n typeof (body as NodeJS.ReadableStream).pipe === \"function\";\n const isBufferBody = Buffer.isBuffer(body);\n const isStringBody = typeof body === \"string\";\n\n let bodyStr: string | undefined;\n if (body !== undefined && !isStreamBody && !isBufferBody && !isStringBody) {\n bodyStr = JSON.stringify(body);\n if (!headers[\"Content-Type\"] && !headers[\"content-type\"]) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n headers[\"Content-Length\"] = Buffer.byteLength(bodyStr).toString();\n } else if (isBufferBody) {\n headers[\"Content-Length\"] = (body as Buffer).length.toString();\n } else if (isStringBody) {\n headers[\"Content-Length\"] = Buffer.byteLength(body as string).toString();\n } else if (isStreamBody) {\n headers[\"Transfer-Encoding\"] = \"chunked\";\n }\n\n const req = this.requestFn(\n {\n socketPath: this.pipePath,\n path: requestPath,\n method: options.method,\n headers,\n },\n (res) => {\n const statusCode = res.statusCode ?? 0;\n const responseHeaders = (res.headers ?? {}) as Record<string, string>;\n\n const isSuccess = options.statusCodes[statusCode] === true;\n\n if (isStream && isSuccess) {\n resolve(res as unknown as NodeJS.ReadableStream);\n return;\n }\n\n collectBody(res as unknown as NodeJS.ReadableStream)\n .then((bodyText) => {\n if (isSuccess) {\n if (statusCode === 204 || bodyText.length === 0) {\n resolve({ statusCode, headers: responseHeaders, body: null });\n return;\n }\n try {\n const parsed = JSON.parse(bodyText);\n resolve({ statusCode, headers: responseHeaders, body: parsed });\n } catch {\n resolve({ statusCode, headers: responseHeaders, body: bodyText });\n }\n } else {\n const message = extractErrorMessage(bodyText);\n reject(statusCodeToError(statusCode, message));\n }\n })\n .catch((collectErr) => {\n reject(\n new DockerNetworkError({\n message: `Failed to read response body: ${String(collectErr)}`,\n cause: collectErr,\n }),\n );\n });\n },\n );\n\n req.on(\"error\", (err) => {\n reject(\n new DockerNetworkError({\n message: `Connection error: ${err.message}`,\n cause: err,\n }),\n );\n });\n\n if (options.timeout !== undefined) {\n req.setTimeout(options.timeout, () => {\n req.destroy();\n reject(\n new DockerTimeoutError({\n message: `Request timed out after ${options.timeout}ms`,\n timeoutMs: options.timeout!,\n }),\n );\n });\n }\n\n if (options.signal) {\n if (options.signal.aborted) {\n req.destroy();\n reject(new DockerAbortError({ message: \"Request aborted\" }));\n return;\n }\n options.signal.addEventListener(\n \"abort\",\n () => {\n req.destroy();\n reject(new DockerAbortError({ message: \"Request aborted\" }));\n },\n { once: true },\n );\n }\n\n // Send body based on type\n if (isStreamBody) {\n (body as NodeJS.ReadableStream).pipe(req);\n } else if (isBufferBody) {\n req.write(body as Buffer);\n req.end();\n } else if (isStringBody) {\n req.write(body as string);\n req.end();\n } else if (bodyStr !== undefined) {\n req.write(bodyStr);\n req.end();\n } else {\n req.end();\n }\n });\n }\n\n private convertError(cause: unknown): DockerError {\n if (cause !== null && typeof cause === \"object\" && \"_tag\" in cause) {\n return cause as DockerError;\n }\n return new DockerNetworkError({\n message: `Unexpected error: ${cause instanceof Error ? cause.message : String(cause)}`,\n cause,\n });\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { UnixTransport } from \"./unix-transport.ts\";\nimport { TcpTransport } from \"./tcp-transport.ts\";\nimport { SshTransport } from \"./ssh-transport.ts\";\nimport { NamedPipeTransport } from \"./npipe-transport.ts\";\nimport type { Transport, TransportConfig } from \"./types.ts\";\n\nexport function createTransport(config: TransportConfig): Transport {\n switch (config.type) {\n case \"unix\":\n return new UnixTransport({ socketPath: config.socketPath });\n case \"tcp\":\n return new TcpTransport({ host: config.host, port: config.port, tls: config.tls });\n case \"ssh\":\n return new SshTransport({\n host: config.host,\n port: config.port,\n username: config.username,\n privateKey: config.privateKey,\n });\n case \"npipe\":\n return new NamedPipeTransport({ path: config.path });\n }\n}\n\n/**\n * Create a transport by auto-detecting configuration from environment variables.\n *\n * Environment variables:\n * - DOCKER_HOST: Docker daemon socket (unix://, tcp://, ssh://, npipe://)\n * - DOCKER_TLS_VERIFY: Set to \"1\" to enable TLS verification\n * - DOCKER_CERT_PATH: Directory containing ca.pem, cert.pem, key.pem\n * - DOCKER_CLIENT_TIMEOUT: Default timeout in seconds\n */\nexport function createTransportFromEnv(): Transport {\n const dockerHost = process.env.DOCKER_HOST;\n const tlsVerify = process.env.DOCKER_TLS_VERIFY === \"1\";\n const certPath = process.env.DOCKER_CERT_PATH;\n\n if (!dockerHost) {\n // Default: Unix socket\n return new UnixTransport({});\n }\n\n // Parse the DOCKER_HOST URL\n if (dockerHost.startsWith(\"unix://\")) {\n return new UnixTransport({ socketPath: dockerHost.replace(\"unix://\", \"\") });\n }\n\n if (dockerHost.startsWith(\"npipe://\")) {\n return new NamedPipeTransport({ path: dockerHost.replace(\"npipe://\", \"\") });\n }\n\n if (dockerHost.startsWith(\"ssh://\")) {\n const url = new URL(dockerHost);\n return new SshTransport({\n host: url.hostname,\n port: url.port ? Number.parseInt(url.port, 10) : 22,\n username: url.username || \"root\",\n });\n }\n\n if (dockerHost.startsWith(\"tcp://\")) {\n const url = new URL(dockerHost);\n const host = url.hostname;\n const port = url.port ? Number.parseInt(url.port, 10) : undefined;\n\n let tls: { ca?: string; cert?: string; key?: string; rejectUnauthorized?: boolean } | undefined;\n\n if (tlsVerify || certPath) {\n tls = { rejectUnauthorized: tlsVerify };\n if (certPath) {\n const caPath = path.join(certPath, \"ca.pem\");\n const certFilePath = path.join(certPath, \"cert.pem\");\n const keyPath = path.join(certPath, \"key.pem\");\n if (fs.existsSync(caPath)) tls.ca = fs.readFileSync(caPath, \"utf-8\");\n if (fs.existsSync(certFilePath)) tls.cert = fs.readFileSync(certFilePath, \"utf-8\");\n if (fs.existsSync(keyPath)) tls.key = fs.readFileSync(keyPath, \"utf-8\");\n }\n }\n\n return new TcpTransport({ host, port, tls });\n }\n\n // Fallback: treat as Unix socket path\n return new UnixTransport({ socketPath: dockerHost });\n}\n\nexport { UnixTransport } from \"./unix-transport.ts\";\nexport { TcpTransport } from \"./tcp-transport.ts\";\nexport { SshTransport } from \"./ssh-transport.ts\";\nexport { NamedPipeTransport } from \"./npipe-transport.ts\";\n\nexport type {\n Transport,\n TransportConfig,\n DialOptions,\n DialResponse,\n StatusCodeMap,\n HttpMethod,\n TlsConfig,\n} from \"./types.ts\";\n","import type { Transport, DialOptions } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport type { Result } from \"better-result\";\n\nexport async function typedDial<T>(\n transport: Transport,\n options: DialOptions,\n): Promise<Result<T, DockerError>> {\n const result = await transport.dial(options);\n return result.map((res) => res.body as T);\n}\n\nexport async function voidDial(\n transport: Transport,\n options: DialOptions,\n): Promise<Result<void, DockerError>> {\n const result = await transport.dial(options);\n return result.map(() => undefined);\n}\n","import type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport type {\n DockerInfo,\n DockerVersion,\n SystemDf,\n AuthConfig,\n AuthResponse,\n SwarmInitOptions,\n SwarmJoinOptions,\n SwarmLeaveOptions,\n SwarmUpdateOptions,\n EventsOptions,\n BuilderPruneOptions,\n BuilderPruneResponse,\n} from \"./types.ts\";\nimport { typedDial, voidDial } from \"./dial.ts\";\n\nexport class SystemOperations {\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n ) {}\n\n async ping(): Promise<Result<string, DockerError>> {\n return typedDial<string>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/_ping`,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async info(): Promise<Result<DockerInfo, DockerError>> {\n return typedDial<DockerInfo>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/info`,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async version(): Promise<Result<DockerVersion, DockerError>> {\n return typedDial<DockerVersion>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/version`,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async df(): Promise<Result<SystemDf, DockerError>> {\n return typedDial<SystemDf>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/system/df`,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n // ---------------------------------------------------------------------------\n // Swarm operations\n // ---------------------------------------------------------------------------\n\n async swarmInit(options: SwarmInitOptions): Promise<Result<string, DockerError>> {\n return typedDial<string>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/swarm/init`,\n body: options,\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 500: \"server error\",\n 503: \"node is already part of a swarm\",\n },\n });\n }\n\n async swarmJoin(options: SwarmJoinOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/swarm/join`,\n body: options,\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 500: \"server error\",\n 503: \"node is already part of a swarm\",\n },\n });\n }\n\n async swarmLeave(options?: SwarmLeaveOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/swarm/leave`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\", 503: \"node is not part of a swarm\" },\n });\n }\n\n async swarmUpdate(options: SwarmUpdateOptions): Promise<Result<void, DockerError>> {\n const { version, rotateWorkerToken, rotateManagerToken, rotateManagerUnlockKey, ...body } =\n options;\n const query: Record<string, unknown> = { version };\n if (rotateWorkerToken !== undefined) query.rotateWorkerToken = rotateWorkerToken;\n if (rotateManagerToken !== undefined) query.rotateManagerToken = rotateManagerToken;\n if (rotateManagerUnlockKey !== undefined) query.rotateManagerUnlockKey = rotateManagerUnlockKey;\n\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/swarm/update`,\n query,\n body,\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async swarmInspect(): Promise<Result<unknown, DockerError>> {\n return typedDial<unknown>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/swarm`,\n statusCodes: { 200: true, 500: \"server error\", 503: \"node is not part of a swarm\" },\n });\n }\n\n // ---------------------------------------------------------------------------\n // Events & Auth\n // ---------------------------------------------------------------------------\n\n async events(options?: EventsOptions): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"GET\",\n path: `/${this.apiVersion}/events`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async auth(options: AuthConfig): Promise<Result<AuthResponse, DockerError>> {\n return typedDial<AuthResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/auth`,\n body: options,\n statusCodes: { 200: true, 204: true, 500: \"server error\" },\n });\n }\n\n // ---------------------------------------------------------------------------\n // Builder\n // ---------------------------------------------------------------------------\n\n async pruneBuilder(\n options?: BuilderPruneOptions,\n ): Promise<Result<BuilderPruneResponse, DockerError>> {\n return typedDial<BuilderPruneResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/build/prune`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n}\n","import { Duplex } from \"node:stream\";\nimport type * as net from \"node:net\";\n\n/**\n * HttpDuplex wraps a raw net.Socket (obtained from HTTP hijack/upgrade)\n * into a Node.js Duplex stream for bidirectional I/O.\n *\n * Used for interactive attach/exec operations where stdin needs to be\n * written to the connection while stdout/stderr is read from it.\n */\nexport class HttpDuplex extends Duplex {\n private readonly socket: net.Socket;\n\n constructor(socket: net.Socket) {\n super();\n this.socket = socket;\n\n socket.on(\"data\", (chunk: Buffer) => {\n if (!this.push(chunk)) {\n socket.pause();\n }\n });\n\n socket.on(\"end\", () => {\n this.push(null);\n });\n\n socket.on(\"error\", (err: Error) => {\n this.destroy(err);\n });\n\n socket.on(\"close\", () => {\n this.push(null);\n });\n }\n\n override _read(_size: number): void {\n this.socket.resume();\n }\n\n override _write(chunk: Buffer | string, _encoding: BufferEncoding, callback: (error?: Error | null) => void): void {\n this.socket.write(chunk, callback);\n }\n\n override _final(callback: (error?: Error | null) => void): void {\n this.socket.end(callback);\n }\n\n override _destroy(error: Error | null, callback: (error?: Error | null) => void): void {\n this.socket.destroy(error ?? undefined);\n callback(error);\n }\n}\n","import type { Duplex } from \"node:stream\";\nimport type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport { HttpDuplex } from \"../transport/http-duplex.ts\";\nimport type { ExecStartOptions, ExecInspect } from \"./types.ts\";\nimport { typedDial, voidDial } from \"./dial.ts\";\n\nexport type ExecStartWithStdinOptions = ExecStartOptions & {\n stdin?: boolean;\n};\n\nexport class Exec {\n readonly id: string;\n\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n id: string,\n ) {\n this.id = id;\n }\n\n async start(\n options?: ExecStartWithStdinOptions,\n ): Promise<Result<NodeJS.ReadableStream | Duplex, DockerError>> {\n const { stdin, ...startOpts } = options ?? {};\n if (stdin) {\n const result = await this.transport.dialHijack({\n method: \"POST\",\n path: `/${this.apiVersion}/exec/${this.id}/start`,\n body: startOpts,\n hijack: true,\n openStdin: true,\n statusCodes: {\n 200: true,\n 101: true,\n 404: \"no such exec instance\",\n 409: \"container is paused\",\n 500: \"server error\",\n },\n });\n return result.map((socket) => new HttpDuplex(socket) as Duplex);\n }\n return this.transport.dialStream({\n method: \"POST\",\n path: `/${this.apiVersion}/exec/${this.id}/start`,\n body: Object.keys(startOpts).length > 0 ? startOpts : undefined,\n statusCodes: {\n 200: true,\n 404: \"no such exec instance\",\n 409: \"container is paused\",\n 500: \"server error\",\n },\n });\n }\n\n async resize(options: { h: number; w: number }): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/exec/${this.id}/resize`,\n query: options,\n statusCodes: { 200: true, 404: \"no such exec instance\", 500: \"server error\" },\n });\n }\n\n async inspect(): Promise<Result<ExecInspect, DockerError>> {\n return typedDial<ExecInspect>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/exec/${this.id}/json`,\n statusCodes: { 200: true, 404: \"no such exec instance\", 500: \"server error\" },\n });\n }\n}\n","import type { Duplex } from \"node:stream\";\nimport type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport { HttpDuplex } from \"../transport/http-duplex.ts\";\nimport type {\n ContainerSummary,\n ContainerInspect,\n CreateContainerOptions,\n CreateContainerResponse,\n WaitResponse,\n PruneResponse,\n ContainerTopResponse,\n ContainerChange,\n ContainerUpdateResponse,\n LogsOptions,\n ExecCreateOptions,\n IdResponse,\n Filters,\n CheckpointCreateOptions,\n ArchiveInfo,\n} from \"./types.ts\";\nimport { Exec } from \"./exec.ts\";\nimport { typedDial, voidDial } from \"./dial.ts\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport type ContainerListOptions = {\n all?: boolean;\n limit?: number;\n size?: boolean;\n filters?: Filters;\n};\n\nexport type ContainerStopOptions = {\n t?: number;\n};\n\nexport type ContainerRestartOptions = {\n t?: number;\n};\n\nexport type ContainerKillOptions = {\n signal?: string;\n};\n\nexport type ContainerRemoveOptions = {\n v?: boolean;\n force?: boolean;\n link?: boolean;\n};\n\nexport type ContainerWaitOptions = {\n condition?: \"not-running\" | \"next-exit\" | \"removed\";\n};\n\nexport type ContainerResizeOptions = {\n h: number;\n w: number;\n};\n\nexport type ContainerAttachOptions = {\n detachKeys?: string;\n logs?: boolean;\n stream?: boolean;\n stdin?: boolean;\n stdout?: boolean;\n stderr?: boolean;\n};\n\nexport type ContainerStatsOptions = {\n stream?: boolean;\n \"one-shot\"?: boolean;\n};\n\nexport type ContainerArchiveOptions = {\n path: string;\n};\n\nexport type ContainerPruneOptions = {\n filters?: Filters;\n};\n\nexport type ContainerCommitOptions = {\n repo?: string;\n tag?: string;\n comment?: string;\n author?: string;\n pause?: boolean;\n changes?: string;\n [key: string]: unknown;\n};\n\nexport type ContainerUpdateOptions = {\n Memory?: number;\n MemorySwap?: number;\n MemoryReservation?: number;\n NanoCpus?: number;\n CpuShares?: number;\n CpuPeriod?: number;\n CpuQuota?: number;\n CpusetCpus?: string;\n CpusetMems?: string;\n BlkioWeight?: number;\n RestartPolicy?: { Name?: string; MaximumRetryCount?: number };\n PidsLimit?: number;\n [key: string]: unknown;\n};\n\n// ---------------------------------------------------------------------------\n// Container entity\n// ---------------------------------------------------------------------------\n\nexport class Container {\n readonly id: string;\n\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n id: string,\n ) {\n this.id = id;\n }\n\n async inspect(): Promise<Result<ContainerInspect, DockerError>> {\n return typedDial<ContainerInspect>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/containers/${this.id}/json`,\n statusCodes: { 200: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async start(): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/start`,\n statusCodes: { 204: true, 304: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async stop(options?: ContainerStopOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/stop`,\n query: options,\n statusCodes: { 204: true, 304: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async restart(options?: ContainerRestartOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/restart`,\n query: options,\n statusCodes: { 204: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async kill(options?: ContainerKillOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/kill`,\n query: options,\n statusCodes: {\n 204: true,\n 404: \"no such container\",\n 409: \"container is not running\",\n 500: \"server error\",\n },\n });\n }\n\n async pause(): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/pause`,\n statusCodes: { 204: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async unpause(): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/unpause`,\n statusCodes: { 204: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async remove(options?: ContainerRemoveOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"DELETE\",\n path: `/${this.apiVersion}/containers/${this.id}`,\n query: options,\n statusCodes: {\n 204: true,\n 400: \"bad parameter\",\n 404: \"no such container\",\n 409: \"conflict\",\n 500: \"server error\",\n },\n });\n }\n\n async rename(name: string): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/rename`,\n query: { name },\n statusCodes: {\n 204: true,\n 404: \"no such container\",\n 409: \"name already in use\",\n 500: \"server error\",\n },\n });\n }\n\n async update(\n options: ContainerUpdateOptions,\n ): Promise<Result<ContainerUpdateResponse, DockerError>> {\n return typedDial<ContainerUpdateResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/update`,\n body: options,\n statusCodes: { 200: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async top(psArgs?: string): Promise<Result<ContainerTopResponse, DockerError>> {\n return typedDial<ContainerTopResponse>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/containers/${this.id}/top`,\n query: psArgs ? { ps_args: psArgs } : undefined,\n statusCodes: { 200: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async changes(): Promise<Result<ContainerChange[], DockerError>> {\n return typedDial<ContainerChange[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/containers/${this.id}/changes`,\n statusCodes: { 200: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async logs(options?: LogsOptions): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"GET\",\n path: `/${this.apiVersion}/containers/${this.id}/logs`,\n query: options,\n statusCodes: { 200: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async stats(\n options?: ContainerStatsOptions,\n ): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"GET\",\n path: `/${this.apiVersion}/containers/${this.id}/stats`,\n query: options,\n statusCodes: { 200: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async wait(options?: ContainerWaitOptions): Promise<Result<WaitResponse, DockerError>> {\n return typedDial<WaitResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/wait`,\n query: options,\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 404: \"no such container\",\n 500: \"server error\",\n },\n });\n }\n\n async resize(options: ContainerResizeOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/resize`,\n query: options,\n statusCodes: { 200: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async attach(\n options?: ContainerAttachOptions,\n ): Promise<Result<NodeJS.ReadableStream | Duplex, DockerError>> {\n if (options?.stdin) {\n // Use hijack for bidirectional I/O\n const result = await this.transport.dialHijack({\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/attach`,\n query: options,\n hijack: true,\n openStdin: true,\n statusCodes: { 200: true, 101: true, 404: \"no such container\", 500: \"server error\" },\n });\n return result.map((socket) => new HttpDuplex(socket) as Duplex);\n }\n return this.transport.dialStream({\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/attach`,\n query: options,\n statusCodes: { 200: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async exec(options: ExecCreateOptions): Promise<Result<Exec, DockerError>> {\n const result = await typedDial<{ Id: string }>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/exec`,\n body: options,\n statusCodes: {\n 201: true,\n 404: \"no such container\",\n 409: \"container is paused\",\n 500: \"server error\",\n },\n });\n return result.map((body) => new Exec(this.transport, this.apiVersion, body.Id));\n }\n\n async export(): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"GET\",\n path: `/${this.apiVersion}/containers/${this.id}/export`,\n statusCodes: { 200: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async getArchive(\n options: ContainerArchiveOptions,\n ): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"GET\",\n path: `/${this.apiVersion}/containers/${this.id}/archive`,\n query: { path: options.path },\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 404: \"no such container\",\n 500: \"server error\",\n },\n });\n }\n\n async putArchive(\n options: ContainerArchiveOptions,\n stream: NodeJS.ReadableStream,\n ): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"PUT\",\n path: `/${this.apiVersion}/containers/${this.id}/archive`,\n query: { path: options.path },\n body: stream,\n headers: { \"content-type\": \"application/x-tar\" },\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 403: \"permission denied\",\n 404: \"no such container\",\n 500: \"server error\",\n },\n });\n }\n\n // ---------------------------------------------------------------------------\n // Checkpoints\n // ---------------------------------------------------------------------------\n\n async listCheckpoints(): Promise<Result<unknown[], DockerError>> {\n return typedDial<unknown[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/containers/${this.id}/checkpoints`,\n statusCodes: { 200: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async createCheckpoint(\n options: CheckpointCreateOptions,\n ): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/${this.id}/checkpoints`,\n body: options,\n statusCodes: { 201: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async deleteCheckpoint(name: string): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"DELETE\",\n path: `/${this.apiVersion}/containers/${this.id}/checkpoints/${name}`,\n statusCodes: { 204: true, 404: \"no such checkpoint\", 500: \"server error\" },\n });\n }\n\n // ---------------------------------------------------------------------------\n // Archive info (HEAD)\n // ---------------------------------------------------------------------------\n\n async infoArchive(\n options: ContainerArchiveOptions,\n ): Promise<Result<ArchiveInfo, DockerError>> {\n const result = await this.transport.dial({\n method: \"HEAD\",\n path: `/${this.apiVersion}/containers/${this.id}/archive`,\n query: { path: options.path },\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 404: \"no such container\",\n 500: \"server error\",\n },\n });\n return result.map((res) => {\n const statHeader = res.headers[\"x-docker-container-path-stat\"];\n if (statHeader) {\n return JSON.parse(Buffer.from(statHeader, \"base64\").toString(\"utf-8\")) as ArchiveInfo;\n }\n return {} as ArchiveInfo;\n });\n }\n\n // ---------------------------------------------------------------------------\n // Commit\n // ---------------------------------------------------------------------------\n\n async commit(options?: ContainerCommitOptions): Promise<Result<IdResponse, DockerError>> {\n const query: Record<string, unknown> = { container: this.id };\n if (options) {\n const { repo, tag, comment, author, pause, changes, ...rest } = options;\n if (repo !== undefined) query.repo = repo;\n if (tag !== undefined) query.tag = tag;\n if (comment !== undefined) query.comment = comment;\n if (author !== undefined) query.author = author;\n if (pause !== undefined) query.pause = pause;\n if (changes !== undefined) query.changes = changes;\n Object.assign(query, rest);\n }\n return typedDial<IdResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/commit`,\n query,\n statusCodes: { 201: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// ContainerOperations namespace\n// ---------------------------------------------------------------------------\n\nexport class ContainerOperations {\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n ) {}\n\n async list(options?: ContainerListOptions): Promise<Result<ContainerSummary[], DockerError>> {\n return typedDial<ContainerSummary[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/containers/json`,\n query: options,\n statusCodes: { 200: true, 400: \"bad parameter\", 500: \"server error\" },\n });\n }\n\n async create(options: CreateContainerOptions): Promise<Result<Container, DockerError>> {\n const { name, platform, ...body } = options;\n const query: Record<string, unknown> = {};\n if (name !== undefined) query.name = name;\n if (platform !== undefined) query.platform = platform;\n\n const result = await typedDial<CreateContainerResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/create`,\n query: Object.keys(query).length > 0 ? query : undefined,\n body,\n statusCodes: {\n 201: true,\n 400: \"bad parameter\",\n 404: \"no such image\",\n 409: \"conflict\",\n 500: \"server error\",\n },\n });\n return result.map((resp) => new Container(this.transport, this.apiVersion, resp.Id));\n }\n\n async inspect(id: string): Promise<Result<ContainerInspect, DockerError>> {\n return typedDial<ContainerInspect>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/containers/${id}/json`,\n statusCodes: { 200: true, 404: \"no such container\", 500: \"server error\" },\n });\n }\n\n async prune(options?: ContainerPruneOptions): Promise<Result<PruneResponse, DockerError>> {\n return typedDial<PruneResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/containers/prune`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n getContainer(id: string): Container {\n return new Container(this.transport, this.apiVersion, id);\n }\n}\n","import * as path from \"node:path\";\nimport * as grpc from \"@grpc/grpc-js\";\nimport * as protoLoader from \"@grpc/proto-loader\";\nimport { randomUUID } from \"node:crypto\";\nimport { Result } from \"better-result\";\nimport { DockerNetworkError, type DockerError } from \"../errors.ts\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { AuthConfig } from \"../client/types.ts\";\n\nexport type SessionResult = {\n sessionId: string;\n close: () => void;\n};\n\n/**\n * Establishes a BuildKit gRPC session over a hijacked HTTP connection.\n *\n * This is used for BuildKit v2 builds to provide registry credentials\n * to the builder during image builds.\n */\nexport async function withSession(\n transport: Transport,\n apiVersion: string,\n auth?: AuthConfig,\n): Promise<Result<SessionResult, DockerError>> {\n const sessionId = randomUUID();\n\n const socketResult = await transport.dialHijack({\n method: \"POST\",\n path: `/${apiVersion}/session`,\n hijack: true,\n headers: {\n Upgrade: \"h2c\",\n \"X-Docker-Expose-Session-Uuid\": sessionId,\n \"X-Docker-Expose-Session-Name\": \"docker-sdk\",\n },\n statusCodes: {\n 200: true,\n 101: true,\n 500: \"server error\",\n },\n });\n\n if (socketResult.isErr()) {\n return socketResult as unknown as Result<SessionResult, DockerError>;\n }\n\n const socket = socketResult.value;\n\n try {\n const server = new grpc.Server();\n const creds = grpc.ServerCredentials.createInsecure();\n const injector = (server as any).createConnectionInjector(creds);\n injector.injectConnection(socket);\n\n const protoPath = path.resolve(import.meta.dirname!, \"auth.proto\");\n const pkg = protoLoader.loadSync(protoPath);\n const service = grpc.loadPackageDefinition(pkg);\n\n const authService = (service.moby as any)?.filesync?.v1?.Auth?.service;\n if (authService) {\n server.addService(authService, {\n Credentials(\n { request: _request }: { request: { Host: string } },\n callback: (err: Error | null, response: { Username?: string; Secret?: string }) => void,\n ) {\n if (auth) {\n callback(null, {\n Username: auth.username ?? \"\",\n Secret: auth.password ?? \"\",\n });\n } else {\n callback(null, {});\n }\n },\n FetchToken(\n _call: unknown,\n callback: (err: Error | null, response: Record<string, unknown>) => void,\n ) {\n callback(null, {});\n },\n GetTokenAuthority(\n _call: unknown,\n callback: (err: Error | null, response: Record<string, unknown>) => void,\n ) {\n callback(null, {});\n },\n VerifyTokenAuthority(\n _call: unknown,\n callback: (err: Error | null, response: Record<string, unknown>) => void,\n ) {\n callback(null, {});\n },\n });\n }\n\n const close = () => {\n server.forceShutdown();\n socket.end();\n };\n\n return Result.ok({ sessionId, close });\n } catch (err) {\n socket.end();\n return Result.err(\n new DockerNetworkError({\n message: `Failed to create gRPC session: ${err instanceof Error ? err.message : String(err)}`,\n cause: err,\n }),\n );\n }\n}\n","import type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport { withSession } from \"../session/index.ts\";\nimport type {\n ImageSummary,\n ImageInspect,\n ImageHistory,\n SearchResult,\n PruneResponse,\n BuildOptions,\n CreateImageOptions,\n ImageDeleteResponseItem,\n ImageImportOptions,\n Filters,\n AuthConfig,\n} from \"./types.ts\";\nimport { typedDial, voidDial } from \"./dial.ts\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport type ImageListOptions = {\n all?: boolean;\n filters?: Filters;\n digests?: boolean;\n};\n\nexport type ImageSearchOptions = {\n term: string;\n limit?: number;\n filters?: Filters;\n};\n\nexport type ImagePruneOptions = {\n filters?: Filters;\n};\n\nexport type ImageTagOptions = {\n repo: string;\n tag?: string;\n};\n\nexport type ImageRemoveOptions = {\n force?: boolean;\n noprune?: boolean;\n};\n\nexport type ImagePushOptions = {\n tag?: string;\n};\n\n// ---------------------------------------------------------------------------\n// Image entity\n// ---------------------------------------------------------------------------\n\nexport class Image {\n readonly name: string;\n\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n name: string,\n ) {\n this.name = name;\n }\n\n async inspect(): Promise<Result<ImageInspect, DockerError>> {\n return typedDial<ImageInspect>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/images/${this.name}/json`,\n statusCodes: { 200: true, 404: \"no such image\", 500: \"server error\" },\n });\n }\n\n async history(): Promise<Result<ImageHistory[], DockerError>> {\n return typedDial<ImageHistory[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/images/${this.name}/history`,\n statusCodes: { 200: true, 404: \"no such image\", 500: \"server error\" },\n });\n }\n\n async push(options?: ImagePushOptions): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"POST\",\n path: `/${this.apiVersion}/images/${this.name}/push`,\n query: options,\n statusCodes: { 200: true, 404: \"no such image\", 500: \"server error\" },\n });\n }\n\n async tag(options: ImageTagOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/images/${this.name}/tag`,\n query: options,\n statusCodes: {\n 201: true,\n 400: \"bad parameter\",\n 404: \"no such image\",\n 409: \"conflict\",\n 500: \"server error\",\n },\n });\n }\n\n async remove(\n options?: ImageRemoveOptions,\n ): Promise<Result<ImageDeleteResponseItem[], DockerError>> {\n return typedDial<ImageDeleteResponseItem[]>(this.transport, {\n method: \"DELETE\",\n path: `/${this.apiVersion}/images/${this.name}`,\n query: options,\n statusCodes: { 200: true, 404: \"no such image\", 409: \"conflict\", 500: \"server error\" },\n });\n }\n\n async get(): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"GET\",\n path: `/${this.apiVersion}/images/${this.name}/get`,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async distribution(): Promise<Result<Record<string, unknown>, DockerError>> {\n return typedDial<Record<string, unknown>>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/distribution/${this.name}/json`,\n statusCodes: { 200: true, 401: \"authentication required\", 500: \"server error\" },\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// ImageOperations namespace\n// ---------------------------------------------------------------------------\n\nexport class ImageOperations {\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n ) {}\n\n async list(options?: ImageListOptions): Promise<Result<ImageSummary[], DockerError>> {\n return typedDial<ImageSummary[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/images/json`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async create(options: CreateImageOptions): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"POST\",\n path: `/${this.apiVersion}/images/create`,\n query: options,\n statusCodes: { 200: true, 404: \"no such image\", 500: \"server error\" },\n });\n }\n\n async build(\n context: NodeJS.ReadableStream | Buffer,\n options?: BuildOptions & { authconfig?: AuthConfig; registryconfig?: Record<string, AuthConfig> },\n ): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n const { authconfig, registryconfig, ...queryOpts } = options ?? {};\n\n // For BuildKit v2 builds, establish a gRPC session first\n if (queryOpts.version === \"2\") {\n const sessionResult = await withSession(this.transport, this.apiVersion, authconfig);\n if (sessionResult.isErr()) {\n return sessionResult as unknown as Result<NodeJS.ReadableStream, DockerError>;\n }\n\n const { sessionId, close } = sessionResult.value;\n (queryOpts as Record<string, unknown>).session = sessionId;\n\n const buildResult = await this.transport.dialStream({\n method: \"POST\",\n path: `/${this.apiVersion}/build`,\n query: Object.keys(queryOpts).length > 0 ? queryOpts : undefined,\n body: context,\n headers: { \"Content-Type\": \"application/x-tar\" },\n registryconfig: registryconfig as Record<string, unknown> | undefined,\n statusCodes: { 200: true, 400: \"bad parameter\", 500: \"server error\" },\n });\n\n if (buildResult.isErr()) {\n close();\n return buildResult;\n }\n\n // Close session when the build stream ends\n const stream = buildResult.value;\n stream.on(\"end\", close);\n stream.on(\"error\", close);\n return buildResult;\n }\n\n return this.transport.dialStream({\n method: \"POST\",\n path: `/${this.apiVersion}/build`,\n query: Object.keys(queryOpts).length > 0 ? queryOpts : undefined,\n body: context,\n headers: { \"Content-Type\": \"application/x-tar\" },\n authconfig: authconfig as Record<string, unknown> | undefined,\n registryconfig: registryconfig as Record<string, unknown> | undefined,\n statusCodes: { 200: true, 400: \"bad parameter\", 500: \"server error\" },\n });\n }\n\n async load(stream: NodeJS.ReadableStream): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"POST\",\n path: `/${this.apiVersion}/images/load`,\n body: stream,\n headers: { \"Content-Type\": \"application/x-tar\" },\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async import(\n stream: NodeJS.ReadableStream,\n options?: ImageImportOptions,\n ): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"POST\",\n path: `/${this.apiVersion}/images/create`,\n query: { fromSrc: \"-\", ...options },\n body: stream,\n headers: { \"Content-Type\": \"application/x-tar\" },\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async search(options: ImageSearchOptions): Promise<Result<SearchResult[], DockerError>> {\n return typedDial<SearchResult[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/images/search`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async prune(options?: ImagePruneOptions): Promise<Result<PruneResponse, DockerError>> {\n return typedDial<PruneResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/images/prune`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n getImage(name: string): Image {\n return new Image(this.transport, this.apiVersion, name);\n }\n}\n","import type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport type {\n Volume,\n VolumeListResponse,\n CreateVolumeOptions,\n PruneResponse,\n Filters,\n} from \"./types.ts\";\nimport { typedDial, voidDial } from \"./dial.ts\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport type VolumeListOptions = {\n filters?: Filters;\n};\n\nexport type VolumePruneOptions = {\n filters?: Filters;\n};\n\nexport type VolumeRemoveOptions = {\n force?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Volume entity\n// ---------------------------------------------------------------------------\n\nexport class VolumeEntity {\n readonly name: string;\n\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n name: string,\n ) {\n this.name = name;\n }\n\n async inspect(): Promise<Result<Volume, DockerError>> {\n return typedDial<Volume>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/volumes/${this.name}`,\n statusCodes: { 200: true, 404: \"no such volume\", 500: \"server error\" },\n });\n }\n\n async remove(options?: VolumeRemoveOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"DELETE\",\n path: `/${this.apiVersion}/volumes/${this.name}`,\n query: options,\n statusCodes: { 204: true, 404: \"no such volume\", 409: \"volume in use\", 500: \"server error\" },\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// VolumeOperations namespace\n// ---------------------------------------------------------------------------\n\nexport class VolumeOperations {\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n ) {}\n\n async list(options?: VolumeListOptions): Promise<Result<VolumeListResponse, DockerError>> {\n return typedDial<VolumeListResponse>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/volumes`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async create(options: CreateVolumeOptions): Promise<Result<Volume, DockerError>> {\n return typedDial<Volume>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/volumes/create`,\n body: options,\n statusCodes: { 201: true, 500: \"server error\" },\n });\n }\n\n async inspect(name: string): Promise<Result<Volume, DockerError>> {\n return typedDial<Volume>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/volumes/${name}`,\n statusCodes: { 200: true, 404: \"no such volume\", 500: \"server error\" },\n });\n }\n\n async prune(options?: VolumePruneOptions): Promise<Result<PruneResponse, DockerError>> {\n return typedDial<PruneResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/volumes/prune`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n getVolume(name: string): VolumeEntity {\n return new VolumeEntity(this.transport, this.apiVersion, name);\n }\n}\n","import type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport type {\n Network,\n NetworkCreateOptions,\n NetworkCreateResponse,\n NetworkConnectOptions,\n NetworkDisconnectOptions,\n PruneResponse,\n Filters,\n} from \"./types.ts\";\nimport { typedDial, voidDial } from \"./dial.ts\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport type NetworkListOptions = {\n filters?: Filters;\n};\n\nexport type NetworkPruneOptions = {\n filters?: Filters;\n};\n\n// ---------------------------------------------------------------------------\n// Network entity\n// ---------------------------------------------------------------------------\n\nexport class NetworkEntity {\n readonly id: string;\n\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n id: string,\n ) {\n this.id = id;\n }\n\n async inspect(): Promise<Result<Network, DockerError>> {\n return typedDial<Network>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/networks/${this.id}`,\n statusCodes: { 200: true, 404: \"network not found\", 500: \"server error\" },\n });\n }\n\n async remove(): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"DELETE\",\n path: `/${this.apiVersion}/networks/${this.id}`,\n statusCodes: {\n 204: true,\n 403: \"operation forbidden\",\n 404: \"no such network\",\n 500: \"server error\",\n },\n });\n }\n\n async connect(options: NetworkConnectOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/networks/${this.id}/connect`,\n body: options,\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 403: \"operation forbidden\",\n 404: \"network or container not found\",\n 500: \"server error\",\n },\n });\n }\n\n async disconnect(options: NetworkDisconnectOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/networks/${this.id}/disconnect`,\n body: options,\n statusCodes: {\n 200: true,\n 403: \"operation forbidden\",\n 404: \"network or container not found\",\n 500: \"server error\",\n },\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// NetworkOperations namespace\n// ---------------------------------------------------------------------------\n\nexport class NetworkOperations {\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n ) {}\n\n async list(options?: NetworkListOptions): Promise<Result<Network[], DockerError>> {\n return typedDial<Network[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/networks`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async create(options: NetworkCreateOptions): Promise<Result<NetworkCreateResponse, DockerError>> {\n return typedDial<NetworkCreateResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/networks/create`,\n body: options,\n statusCodes: {\n 201: true,\n 400: \"bad parameter\",\n 403: \"operation forbidden\",\n 404: \"plugin not found\",\n 500: \"server error\",\n },\n });\n }\n\n async inspect(id: string): Promise<Result<Network, DockerError>> {\n return typedDial<Network>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/networks/${id}`,\n statusCodes: { 200: true, 404: \"network not found\", 500: \"server error\" },\n });\n }\n\n async prune(options?: NetworkPruneOptions): Promise<Result<PruneResponse, DockerError>> {\n return typedDial<PruneResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/networks/prune`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n getNetwork(id: string): NetworkEntity {\n return new NetworkEntity(this.transport, this.apiVersion, id);\n }\n}\n","import type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport type {\n Service,\n ServiceCreateOptions,\n ServiceCreateResponse,\n ServiceUpdateOptions,\n LogsOptions,\n Filters,\n} from \"./types.ts\";\nimport { typedDial, voidDial } from \"./dial.ts\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport type ServiceListOptions = {\n filters?: Filters;\n status?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Service entity\n// ---------------------------------------------------------------------------\n\nexport class ServiceEntity {\n readonly id: string;\n\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n id: string,\n ) {\n this.id = id;\n }\n\n async inspect(): Promise<Result<Service, DockerError>> {\n return typedDial<Service>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/services/${this.id}`,\n statusCodes: {\n 200: true,\n 404: \"no such service\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async update(options: ServiceUpdateOptions): Promise<Result<void, DockerError>> {\n const { version, registryAuthFrom, rollback, ...body } = options;\n const query: Record<string, unknown> = { version };\n if (registryAuthFrom !== undefined) query.registryAuthFrom = registryAuthFrom;\n if (rollback !== undefined) query.rollback = rollback;\n\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/services/${this.id}/update`,\n query,\n body,\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 404: \"no such service\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async remove(): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"DELETE\",\n path: `/${this.apiVersion}/services/${this.id}`,\n statusCodes: {\n 200: true,\n 404: \"no such service\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async logs(options?: LogsOptions): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"GET\",\n path: `/${this.apiVersion}/services/${this.id}/logs`,\n query: options,\n statusCodes: {\n 200: true,\n 404: \"no such service\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// ServiceOperations namespace\n// ---------------------------------------------------------------------------\n\nexport class ServiceOperations {\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n ) {}\n\n async list(options?: ServiceListOptions): Promise<Result<Service[], DockerError>> {\n return typedDial<Service[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/services`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\", 503: \"node is not part of a swarm\" },\n });\n }\n\n async create(options: ServiceCreateOptions): Promise<Result<ServiceCreateResponse, DockerError>> {\n const { ...body } = options;\n return typedDial<ServiceCreateResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/services/create`,\n body,\n statusCodes: {\n 201: true,\n 400: \"bad parameter\",\n 403: \"forbidden\",\n 409: \"name conflicts\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async inspect(id: string): Promise<Result<Service, DockerError>> {\n return typedDial<Service>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/services/${id}`,\n statusCodes: {\n 200: true,\n 404: \"no such service\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n getService(id: string): ServiceEntity {\n return new ServiceEntity(this.transport, this.apiVersion, id);\n }\n}\n","import type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport type { Task, LogsOptions, Filters } from \"./types.ts\";\nimport { typedDial } from \"./dial.ts\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport type TaskListOptions = {\n filters?: Filters;\n};\n\n// ---------------------------------------------------------------------------\n// Task entity\n// ---------------------------------------------------------------------------\n\nexport class TaskEntity {\n readonly id: string;\n\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n id: string,\n ) {\n this.id = id;\n }\n\n async inspect(): Promise<Result<Task, DockerError>> {\n return typedDial<Task>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/tasks/${this.id}`,\n statusCodes: {\n 200: true,\n 404: \"no such task\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async logs(options?: LogsOptions): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"GET\",\n path: `/${this.apiVersion}/tasks/${this.id}/logs`,\n query: options,\n statusCodes: {\n 200: true,\n 404: \"no such task\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// TaskOperations namespace\n// ---------------------------------------------------------------------------\n\nexport class TaskOperations {\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n ) {}\n\n async list(options?: TaskListOptions): Promise<Result<Task[], DockerError>> {\n return typedDial<Task[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/tasks`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\", 503: \"node is not part of a swarm\" },\n });\n }\n\n async inspect(id: string): Promise<Result<Task, DockerError>> {\n return typedDial<Task>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/tasks/${id}`,\n statusCodes: {\n 200: true,\n 404: \"no such task\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n getTask(id: string): TaskEntity {\n return new TaskEntity(this.transport, this.apiVersion, id);\n }\n}\n","import type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport type { Node, NodeSpec, Filters } from \"./types.ts\";\nimport { typedDial, voidDial } from \"./dial.ts\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport type NodeListOptions = {\n filters?: Filters;\n};\n\nexport type NodeUpdateOptions = {\n version: number;\n Name?: string;\n Labels?: Record<string, string>;\n Role?: NodeSpec[\"Role\"];\n Availability?: NodeSpec[\"Availability\"];\n};\n\nexport type NodeRemoveOptions = {\n force?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Node entity\n// ---------------------------------------------------------------------------\n\nexport class NodeEntity {\n readonly id: string;\n\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n id: string,\n ) {\n this.id = id;\n }\n\n async inspect(): Promise<Result<Node, DockerError>> {\n return typedDial<Node>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/nodes/${this.id}`,\n statusCodes: {\n 200: true,\n 404: \"no such node\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async update(options: NodeUpdateOptions): Promise<Result<void, DockerError>> {\n const { version, ...body } = options;\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/nodes/${this.id}/update`,\n query: { version },\n body,\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 404: \"no such node\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async remove(options?: NodeRemoveOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"DELETE\",\n path: `/${this.apiVersion}/nodes/${this.id}`,\n query: options,\n statusCodes: {\n 200: true,\n 404: \"no such node\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// NodeOperations namespace\n// ---------------------------------------------------------------------------\n\nexport class NodeOperations {\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n ) {}\n\n async list(options?: NodeListOptions): Promise<Result<Node[], DockerError>> {\n return typedDial<Node[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/nodes`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\", 503: \"node is not part of a swarm\" },\n });\n }\n\n async inspect(id: string): Promise<Result<Node, DockerError>> {\n return typedDial<Node>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/nodes/${id}`,\n statusCodes: {\n 200: true,\n 404: \"no such node\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n getNode(id: string): NodeEntity {\n return new NodeEntity(this.transport, this.apiVersion, id);\n }\n}\n","import type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport type { Secret, SecretCreateOptions, IdResponse, Filters } from \"./types.ts\";\nimport { typedDial, voidDial } from \"./dial.ts\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport type SecretListOptions = {\n filters?: Filters;\n};\n\nexport type SecretUpdateOptions = {\n version: number;\n Name?: string;\n Labels?: Record<string, string>;\n Data?: string;\n Driver?: { Name: string; Options?: Record<string, string> };\n Templating?: { Name: string; Options?: Record<string, string> };\n};\n\n// ---------------------------------------------------------------------------\n// Secret entity\n// ---------------------------------------------------------------------------\n\nexport class SecretEntity {\n readonly id: string;\n\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n id: string,\n ) {\n this.id = id;\n }\n\n async inspect(): Promise<Result<Secret, DockerError>> {\n return typedDial<Secret>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/secrets/${this.id}`,\n statusCodes: {\n 200: true,\n 404: \"no such secret\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async update(options: SecretUpdateOptions): Promise<Result<void, DockerError>> {\n const { version, ...body } = options;\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/secrets/${this.id}/update`,\n query: { version },\n body,\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 404: \"no such secret\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async remove(): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"DELETE\",\n path: `/${this.apiVersion}/secrets/${this.id}`,\n statusCodes: {\n 204: true,\n 404: \"no such secret\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// SecretOperations namespace\n// ---------------------------------------------------------------------------\n\nexport class SecretOperations {\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n ) {}\n\n async list(options?: SecretListOptions): Promise<Result<Secret[], DockerError>> {\n return typedDial<Secret[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/secrets`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\", 503: \"node is not part of a swarm\" },\n });\n }\n\n async create(options: SecretCreateOptions): Promise<Result<IdResponse, DockerError>> {\n return typedDial<IdResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/secrets/create`,\n body: options,\n statusCodes: {\n 201: true,\n 409: \"name conflicts\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async inspect(id: string): Promise<Result<Secret, DockerError>> {\n return typedDial<Secret>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/secrets/${id}`,\n statusCodes: {\n 200: true,\n 404: \"no such secret\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n getSecret(id: string): SecretEntity {\n return new SecretEntity(this.transport, this.apiVersion, id);\n }\n}\n","import type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport type { Config, ConfigCreateOptions, IdResponse, Filters } from \"./types.ts\";\nimport { typedDial, voidDial } from \"./dial.ts\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport type ConfigListOptions = {\n filters?: Filters;\n};\n\nexport type ConfigUpdateOptions = {\n version: number;\n Name?: string;\n Labels?: Record<string, string>;\n Data?: string;\n Templating?: { Name: string; Options?: Record<string, string> };\n};\n\n// ---------------------------------------------------------------------------\n// Config entity\n// ---------------------------------------------------------------------------\n\nexport class ConfigEntity {\n readonly id: string;\n\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n id: string,\n ) {\n this.id = id;\n }\n\n async inspect(): Promise<Result<Config, DockerError>> {\n return typedDial<Config>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/configs/${this.id}`,\n statusCodes: {\n 200: true,\n 404: \"no such config\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async update(options: ConfigUpdateOptions): Promise<Result<void, DockerError>> {\n const { version, ...body } = options;\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/configs/${this.id}/update`,\n query: { version },\n body,\n statusCodes: {\n 200: true,\n 400: \"bad parameter\",\n 404: \"no such config\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async remove(): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"DELETE\",\n path: `/${this.apiVersion}/configs/${this.id}`,\n statusCodes: {\n 204: true,\n 404: \"no such config\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// ConfigOperations namespace\n// ---------------------------------------------------------------------------\n\nexport class ConfigOperations {\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n ) {}\n\n async list(options?: ConfigListOptions): Promise<Result<Config[], DockerError>> {\n return typedDial<Config[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/configs`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\", 503: \"node is not part of a swarm\" },\n });\n }\n\n async create(options: ConfigCreateOptions): Promise<Result<IdResponse, DockerError>> {\n return typedDial<IdResponse>(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/configs/create`,\n body: options,\n statusCodes: {\n 201: true,\n 409: \"name conflicts\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n async inspect(id: string): Promise<Result<Config, DockerError>> {\n return typedDial<Config>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/configs/${id}`,\n statusCodes: {\n 200: true,\n 404: \"no such config\",\n 500: \"server error\",\n 503: \"node is not part of a swarm\",\n },\n });\n }\n\n getConfig(id: string): ConfigEntity {\n return new ConfigEntity(this.transport, this.apiVersion, id);\n }\n}\n","import type { Result } from \"better-result\";\nimport type { Transport } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport type { Plugin, PluginPrivilege, Filters } from \"./types.ts\";\nimport { typedDial, voidDial } from \"./dial.ts\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport type PluginListOptions = {\n filters?: Filters;\n};\n\nexport type PluginPrivilegesOptions = {\n remote: string;\n};\n\nexport type PluginInstallOptions = {\n remote: string;\n name?: string;\n};\n\nexport type PluginCreateOptions = {\n name: string;\n};\n\nexport type PluginRemoveOptions = {\n force?: boolean;\n};\n\nexport type PluginEnableOptions = {\n timeout?: number;\n};\n\nexport type PluginDisableOptions = {\n Force?: boolean;\n};\n\nexport type PluginConfigureOptions = {\n env: string[];\n};\n\nexport type PluginUpgradeOptions = {\n remote: string;\n};\n\n// ---------------------------------------------------------------------------\n// Plugin entity\n// ---------------------------------------------------------------------------\n\nexport class PluginEntity {\n readonly name: string;\n\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n name: string,\n ) {\n this.name = name;\n }\n\n async inspect(): Promise<Result<Plugin, DockerError>> {\n return typedDial<Plugin>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/plugins/${this.name}/json`,\n statusCodes: { 200: true, 404: \"plugin is not found\", 500: \"server error\" },\n });\n }\n\n async remove(options?: PluginRemoveOptions): Promise<Result<Plugin, DockerError>> {\n return typedDial<Plugin>(this.transport, {\n method: \"DELETE\",\n path: `/${this.apiVersion}/plugins/${this.name}`,\n query: options,\n statusCodes: { 200: true, 404: \"plugin is not found\", 500: \"server error\" },\n });\n }\n\n async enable(options?: PluginEnableOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/plugins/${this.name}/enable`,\n query: options,\n statusCodes: { 200: true, 404: \"plugin is not installed\", 500: \"server error\" },\n });\n }\n\n async disable(options?: PluginDisableOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/plugins/${this.name}/disable`,\n body: options,\n statusCodes: { 200: true, 404: \"plugin is not installed\", 500: \"server error\" },\n });\n }\n\n async push(): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/plugins/${this.name}/push`,\n statusCodes: { 200: true, 404: \"plugin is not found\", 500: \"server error\" },\n });\n }\n\n async configure(options: PluginConfigureOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/plugins/${this.name}/set`,\n body: options.env,\n statusCodes: { 204: true, 404: \"plugin is not found\", 500: \"server error\" },\n });\n }\n\n async upgrade(\n options: PluginUpgradeOptions,\n ): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n return this.transport.dialStream({\n method: \"POST\",\n path: `/${this.apiVersion}/plugins/${this.name}/upgrade`,\n query: { remote: options.remote },\n statusCodes: { 200: true, 404: \"plugin is not found\", 500: \"server error\" },\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// PluginOperations namespace\n// ---------------------------------------------------------------------------\n\nexport class PluginOperations {\n constructor(\n private readonly transport: Transport,\n private readonly apiVersion: string,\n ) {}\n\n async list(options?: PluginListOptions): Promise<Result<Plugin[], DockerError>> {\n return typedDial<Plugin[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/plugins`,\n query: options,\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async privileges(\n options: PluginPrivilegesOptions,\n ): Promise<Result<PluginPrivilege[], DockerError>> {\n return typedDial<PluginPrivilege[]>(this.transport, {\n method: \"GET\",\n path: `/${this.apiVersion}/plugins/privileges`,\n query: { remote: options.remote },\n statusCodes: { 200: true, 500: \"server error\" },\n });\n }\n\n async install(\n options: PluginInstallOptions,\n ): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n const query: Record<string, unknown> = { remote: options.remote };\n if (options.name !== undefined) {\n query.name = options.name;\n }\n return this.transport.dialStream({\n method: \"POST\",\n path: `/${this.apiVersion}/plugins/pull`,\n query,\n statusCodes: { 204: true, 500: \"server error\" },\n });\n }\n\n async create(options: PluginCreateOptions): Promise<Result<void, DockerError>> {\n return voidDial(this.transport, {\n method: \"POST\",\n path: `/${this.apiVersion}/plugins/create`,\n query: { name: options.name },\n statusCodes: { 204: true, 500: \"server error\" },\n });\n }\n\n getPlugin(name: string): PluginEntity {\n return new PluginEntity(this.transport, this.apiVersion, name);\n }\n}\n","import type { Result } from \"better-result\";\nimport { createTransport, createTransportFromEnv } from \"../transport/index.ts\";\nimport type { Transport, TransportConfig } from \"../transport/types.ts\";\nimport type { DockerError } from \"../errors.ts\";\nimport type {\n AuthConfig,\n WaitResponse,\n CreateContainerOptions,\n} from \"./types.ts\";\nimport { SystemOperations } from \"./system.ts\";\nimport { Container, ContainerOperations } from \"./container.ts\";\nimport { ImageOperations } from \"./image.ts\";\nimport { VolumeOperations } from \"./volume.ts\";\nimport { NetworkOperations } from \"./network.ts\";\nimport { ServiceOperations } from \"./service.ts\";\nimport { TaskOperations } from \"./task.ts\";\nimport { NodeOperations } from \"./node.ts\";\nimport { SecretOperations } from \"./secret.ts\";\nimport { ConfigOperations } from \"./config.ts\";\nimport { PluginOperations } from \"./plugin.ts\";\n\nexport type DockerConfig = {\n transport: TransportConfig;\n apiVersion: string;\n timeoutMs?: number;\n};\n\nexport type PullOptions = {\n authconfig?: AuthConfig;\n platform?: string;\n};\n\nexport type RunOptions = Omit<CreateContainerOptions, \"Image\" | \"Cmd\"> & {\n autoRemove?: boolean;\n};\n\nexport type RunResult = {\n output: WaitResponse;\n container: Container;\n};\n\nexport class Docker {\n readonly system: SystemOperations;\n readonly containers: ContainerOperations;\n readonly images: ImageOperations;\n readonly volumes: VolumeOperations;\n readonly networks: NetworkOperations;\n readonly services: ServiceOperations;\n readonly tasks: TaskOperations;\n readonly nodes: NodeOperations;\n readonly secrets: SecretOperations;\n readonly configs: ConfigOperations;\n readonly plugins: PluginOperations;\n private readonly transport: Transport;\n private readonly apiVersion: string;\n\n constructor(config: DockerConfig) {\n this.transport = createTransport(config.transport);\n this.apiVersion = config.apiVersion;\n const v = config.apiVersion;\n this.system = new SystemOperations(this.transport, v);\n this.containers = new ContainerOperations(this.transport, v);\n this.images = new ImageOperations(this.transport, v);\n this.volumes = new VolumeOperations(this.transport, v);\n this.networks = new NetworkOperations(this.transport, v);\n this.services = new ServiceOperations(this.transport, v);\n this.tasks = new TaskOperations(this.transport, v);\n this.nodes = new NodeOperations(this.transport, v);\n this.secrets = new SecretOperations(this.transport, v);\n this.configs = new ConfigOperations(this.transport, v);\n this.plugins = new PluginOperations(this.transport, v);\n }\n\n /** Create Docker client with pre-existing transport (for testing). */\n static fromTransport(transport: Transport, opts: { apiVersion: string }): Docker {\n const instance = Object.create(Docker.prototype) as Docker;\n const v = opts.apiVersion;\n (instance as any).transport = transport;\n (instance as any).apiVersion = v;\n (instance as any).system = new SystemOperations(transport, v);\n (instance as any).containers = new ContainerOperations(transport, v);\n (instance as any).images = new ImageOperations(transport, v);\n (instance as any).volumes = new VolumeOperations(transport, v);\n (instance as any).networks = new NetworkOperations(transport, v);\n (instance as any).services = new ServiceOperations(transport, v);\n (instance as any).tasks = new TaskOperations(transport, v);\n (instance as any).nodes = new NodeOperations(transport, v);\n (instance as any).secrets = new SecretOperations(transport, v);\n (instance as any).configs = new ConfigOperations(transport, v);\n (instance as any).plugins = new PluginOperations(transport, v);\n return instance;\n }\n\n /**\n * Create Docker client from environment variables.\n * Reads DOCKER_HOST, DOCKER_TLS_VERIFY, DOCKER_CERT_PATH, DOCKER_CLIENT_TIMEOUT.\n */\n static fromEnv(opts?: { apiVersion?: string }): Docker {\n const transport = createTransportFromEnv();\n const apiVersion = opts?.apiVersion ?? \"v1.47\";\n const instance = Object.create(Docker.prototype) as Docker;\n (instance as any).transport = transport;\n (instance as any).apiVersion = apiVersion;\n (instance as any).system = new SystemOperations(transport, apiVersion);\n (instance as any).containers = new ContainerOperations(transport, apiVersion);\n (instance as any).images = new ImageOperations(transport, apiVersion);\n (instance as any).volumes = new VolumeOperations(transport, apiVersion);\n (instance as any).networks = new NetworkOperations(transport, apiVersion);\n (instance as any).services = new ServiceOperations(transport, apiVersion);\n (instance as any).tasks = new TaskOperations(transport, apiVersion);\n (instance as any).nodes = new NodeOperations(transport, apiVersion);\n (instance as any).secrets = new SecretOperations(transport, apiVersion);\n (instance as any).configs = new ConfigOperations(transport, apiVersion);\n (instance as any).plugins = new PluginOperations(transport, apiVersion);\n return instance;\n }\n\n /**\n * Pull an image from a registry.\n * Returns a progress stream of newline-delimited JSON.\n */\n async pull(\n repoTag: string,\n options?: PullOptions,\n ): Promise<Result<NodeJS.ReadableStream, DockerError>> {\n const parts = repoTag.split(\":\");\n const tag = parts.length > 1 ? parts.pop()! : \"latest\";\n const repository = parts.join(\":\");\n\n return this.transport.dialStream({\n method: \"POST\",\n path: `/${this.apiVersion}/images/create`,\n query: { fromImage: repository, tag },\n authconfig: options?.authconfig as Record<string, unknown> | undefined,\n statusCodes: { 200: true, 404: \"no such image\", 500: \"server error\" },\n });\n }\n\n /**\n * Create and run a container, waiting for it to exit.\n * Returns the wait result and the container instance.\n */\n async run(\n image: string,\n cmd: string[],\n options?: RunOptions,\n ): Promise<Result<RunResult, DockerError>> {\n const { autoRemove, ...createOpts } = options ?? {};\n\n // 1. Create container\n const createResult = await this.containers.create({\n ...createOpts,\n Image: image,\n Cmd: cmd,\n AttachStdout: true,\n AttachStderr: true,\n });\n if (createResult.isErr()) return createResult as unknown as Result<RunResult, DockerError>;\n const container = createResult.value;\n\n // 2. Attach to container (stdout + stderr)\n const attachResult = await container.attach({\n stream: true,\n stdout: true,\n stderr: true,\n });\n if (attachResult.isErr()) return attachResult as unknown as Result<RunResult, DockerError>;\n\n // 3. Start container\n const startResult = await container.start();\n if (startResult.isErr()) return startResult as unknown as Result<RunResult, DockerError>;\n\n // 4. Wait for container to exit\n const waitResult = await container.wait();\n if (waitResult.isErr()) return waitResult as unknown as Result<RunResult, DockerError>;\n\n // 5. Auto-remove if requested\n if (autoRemove) {\n await container.remove({ force: true });\n }\n\n return waitResult.map((output: WaitResponse) => ({ output, container }));\n }\n\n destroy(): void {\n this.transport.destroy();\n }\n}\n","import { EventEmitter } from \"node:events\";\nimport { PassThrough } from \"node:stream\";\n\n// ---------------------------------------------------------------------------\n// DockerStream — EventEmitter wrapper around a Node.js ReadableStream\n// ---------------------------------------------------------------------------\n\nexport class DockerStream extends EventEmitter {\n readonly isTty: boolean;\n private readonly source: NodeJS.ReadableStream;\n\n constructor(source: NodeJS.ReadableStream, isTty: boolean) {\n super();\n this.source = source;\n this.isTty = isTty;\n\n // Relay events from the underlying source\n source.on(\"data\", (chunk: Buffer) => this.emit(\"data\", chunk));\n source.on(\"end\", () => this.emit(\"end\"));\n source.on(\"error\", (err: Error) => this.emit(\"error\", err));\n }\n\n /**\n * Destroys the underlying source stream.\n */\n destroy(): void {\n if (\"destroy\" in this.source && typeof this.source.destroy === \"function\") {\n (this.source as NodeJS.ReadableStream & { destroy(): void }).destroy();\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// demuxStream — separates Docker multiplexed stream into stdout/stderr\n// ---------------------------------------------------------------------------\n\nconst HEADER_SIZE = 8;\n\n/**\n * Separates a Docker multiplexed stream into stdout and stderr PassThrough\n * streams based on the Docker stream multiplexing protocol.\n *\n * Docker multiplexed format: 8-byte header per frame\n * - Byte 0: stream type (0=stdin, 1=stdout, 2=stderr)\n * - Bytes 1-3: padding (0)\n * - Bytes 4-7: payload size (big-endian uint32)\n * - Followed by `size` bytes of payload\n */\nexport function demuxStream(source: NodeJS.ReadableStream): {\n stdout: PassThrough;\n stderr: PassThrough;\n} {\n const stdout = new PassThrough();\n const stderr = new PassThrough();\n\n let buffer = Buffer.alloc(0);\n\n function processBuffer(): void {\n // Keep processing as long as we have at least a full header\n while (buffer.length >= HEADER_SIZE) {\n const streamType = buffer.readUInt8(0);\n const payloadSize = buffer.readUInt32BE(4);\n\n // Check if the full frame (header + payload) is available\n if (buffer.length < HEADER_SIZE + payloadSize) {\n break; // Wait for more data\n }\n\n const payload = buffer.subarray(HEADER_SIZE, HEADER_SIZE + payloadSize);\n\n // Route payload to appropriate stream\n switch (streamType) {\n case 1:\n stdout.write(payload);\n break;\n case 2:\n stderr.write(payload);\n break;\n // type 0 (stdin) and others are ignored\n }\n\n // Advance past this frame\n buffer = buffer.subarray(HEADER_SIZE + payloadSize);\n }\n }\n\n source.on(\"data\", (chunk: Buffer) => {\n buffer = Buffer.concat([buffer, chunk]);\n processBuffer();\n });\n\n source.on(\"end\", () => {\n stdout.end();\n stderr.end();\n });\n\n source.on(\"error\", (err: Error) => {\n stdout.destroy(err);\n stderr.destroy(err);\n });\n\n return { stdout, stderr };\n}\n\n// ---------------------------------------------------------------------------\n// followProgress — parses newline-delimited JSON progress streams\n// ---------------------------------------------------------------------------\n\n/**\n * Follows a newline-delimited JSON progress stream (e.g., from pull/push/build).\n * Accumulates all events and calls onFinished when the stream ends.\n * Optionally calls onProgress for each event as it arrives.\n */\nexport function followProgress(\n stream: NodeJS.ReadableStream,\n onFinished: (err: Error | null, output: unknown[]) => void,\n onProgress?: (event: unknown) => void,\n): void {\n const output: unknown[] = [];\n let buffer = \"\";\n\n stream.on(\"data\", (chunk: Buffer | string) => {\n buffer += typeof chunk === \"string\" ? chunk : chunk.toString(\"utf-8\");\n\n const lines = buffer.split(\"\\n\");\n // Keep the last (potentially incomplete) line in the buffer\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.length === 0) continue;\n try {\n const obj = JSON.parse(trimmed);\n output.push(obj);\n if (onProgress) {\n onProgress(obj);\n }\n } catch {\n // Skip unparseable lines\n }\n }\n });\n\n stream.on(\"end\", () => {\n // Process any remaining data in the buffer\n if (buffer.trim().length > 0) {\n try {\n const obj = JSON.parse(buffer.trim());\n output.push(obj);\n if (onProgress) {\n onProgress(obj);\n }\n } catch {\n // Skip unparseable remainder\n }\n }\n onFinished(null, output);\n });\n\n stream.on(\"error\", (err: Error) => {\n onFinished(err, output);\n });\n}\n"],"mappings":"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"}