@computesdk/docker 1.2.57 → 1.2.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -167,7 +167,7 @@ function pickImageForRuntime(runtime, configured) {
167
167
  var docker = (0, import_provider.defineProvider)({
168
168
  name: PROVIDER,
169
169
  methods: {
170
- sandbox: {
170
+ instances: {
171
171
  create: async (config, options) => {
172
172
  const cfg = { ...defaultDockerConfig, ...config };
173
173
  const effectiveRuntime = options?.runtime ?? cfg.runtime ?? "python";
@@ -224,14 +224,14 @@ var docker = (0, import_provider.defineProvider)({
224
224
  image: inspect.Config?.Image ?? chosenImage.name,
225
225
  createdAt: new Date(inspect.Created || Date.now())
226
226
  };
227
- return { sandbox: handle, sandboxId: handle.containerId };
227
+ return { instance: handle, instanceId: handle.containerId };
228
228
  },
229
229
  getById: async (config, sandboxId) => {
230
230
  const docker2 = new import_dockerode.default((config || defaultDockerConfig).connection);
231
231
  try {
232
232
  const container = docker2.getContainer(sandboxId);
233
233
  const info = await container.inspect();
234
- return { sandbox: { docker: docker2, container, containerId: sandboxId, image: info.Config?.Image ?? "", createdAt: new Date(info.Created || Date.now()) }, sandboxId };
234
+ return { instance: { docker: docker2, container, containerId: sandboxId, image: info.Config?.Image ?? "", createdAt: new Date(info.Created || Date.now()) }, instanceId: sandboxId };
235
235
  } catch {
236
236
  return null;
237
237
  }
@@ -241,8 +241,8 @@ var docker = (0, import_provider.defineProvider)({
241
241
  try {
242
242
  const items = await docker2.listContainers({ all: true, filters: { label: [LABEL_KEY] } });
243
243
  return items.map((ci) => ({
244
- sandbox: { docker: docker2, container: docker2.getContainer(ci.Id), containerId: ci.Id, image: ci.Image, createdAt: new Date(ci.Created * 1e3) },
245
- sandboxId: ci.Id
244
+ instance: { docker: docker2, container: docker2.getContainer(ci.Id), containerId: ci.Id, image: ci.Image, createdAt: new Date(ci.Created * 1e3) },
245
+ instanceId: ci.Id
246
246
  }));
247
247
  } catch {
248
248
  return [];
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types/types.ts"],"sourcesContent":["import Docker from 'dockerode';\nimport { PassThrough } from 'stream';\nimport { defineProvider } from '@computesdk/provider';\nimport type {\n CommandResult,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n FileEntry,\n} from '@computesdk/provider';\n\nimport { defaultDockerConfig } from './types/types';\nimport type {\n DockerConfig,\n DockerSandboxHandle,\n DockerImage,\n PortBindings,\n} from './types/types';\n\nconst PROVIDER = 'docker' as const;\nconst LABEL_KEY = 'com.computesdk.sandbox';\nconst LABEL_RUNTIME = 'com.computesdk.runtime';\nconst KEEPALIVE_CMD = ['/bin/sh', '-c', 'while :; do sleep 3600; done'];\n\nfunction pick<T>(val: T | undefined, fallback: T): T {\n return typeof val === 'undefined' ? fallback : val;\n}\n\nasync function ensureImage(docker: Docker, image: DockerImage): Promise<void> {\n const policy = image.pullPolicy ?? 'ifNotPresent';\n if (policy === 'never') return;\n const images = await docker.listImages();\n const hasImage = images.some(img => (img.RepoTags || []).includes(image.name));\n if (policy === 'always' || (policy === 'ifNotPresent' && !hasImage)) {\n await new Promise<void>((resolve, reject) => {\n const cb = (err: any, stream?: NodeJS.ReadableStream) => {\n if (err) return reject(err);\n if (!stream) return reject(new Error('docker.pull returned no stream'));\n (docker as any).modem.followProgress(stream, (err2: any) => (err2 ? reject(err2) : resolve()));\n };\n if (image.auth) docker.pull(image.name, { authconfig: image.auth } as any, cb);\n else docker.pull(image.name, cb);\n });\n }\n}\n\nasync function waitUntilRunning(container: Docker.Container, timeoutMs = 4000) {\n const start = Date.now();\n try {\n const s = await container.inspect();\n if (s.State?.Running) return;\n } catch { /* ignore */ }\n while (Date.now() - start < timeoutMs) {\n const s = await container.inspect();\n if (s.State?.Running) return;\n await new Promise(r => setTimeout(r, 100));\n }\n throw new Error('Container did not reach Running state in time');\n}\n\nasync function runExec(\n handle: DockerSandboxHandle,\n shellCommand: string,\n attachTTY = false\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n await waitUntilRunning(handle.container);\n const exec = await handle.container.exec({\n Cmd: ['/bin/sh', '-c', shellCommand],\n AttachStdout: true,\n AttachStderr: true,\n Tty: attachTTY,\n });\n const stream = (await exec.start({ hijack: true, stdin: false })) as NodeJS.ReadableStream;\n let stdout = '';\n let stderr = '';\n await new Promise<void>((resolve, reject) => {\n if (attachTTY) {\n stream.on('data', (chunk: Buffer) => (stdout += chunk.toString('utf8')));\n stream.on('end', resolve);\n stream.on('error', reject);\n return;\n }\n const out = new PassThrough();\n const err = new PassThrough();\n out.on('data', (c: Buffer) => (stdout += c.toString('utf8')));\n err.on('data', (c: Buffer) => (stderr += c.toString('utf8')));\n (handle.docker as any).modem.demuxStream(stream as any, out as any, err as any);\n stream.on('end', resolve);\n stream.on('error', reject);\n });\n const inspect = await exec.inspect();\n return { stdout, stderr, exitCode: inspect.ExitCode ?? 0 };\n}\n\nfunction toHostBindings(ports?: PortBindings) {\n if (!ports) return undefined;\n const exposed: Record<string, {}> = {};\n const bindings: Record<string, Array<{ HostPort?: string; HostIp?: string }>> = {};\n for (const key of Object.keys(ports)) {\n exposed[key] = {};\n bindings[key] = (ports as any)[key].map((p: any) => ({ HostPort: p.hostPort ? String(p.hostPort) : undefined, HostIp: p.hostIP }));\n }\n return { ExposedPorts: exposed, PortBindings: bindings };\n}\n\nfunction dockerHostNameFromEnv(): string {\n const hostEnv = process.env.DOCKER_HOST;\n if (hostEnv?.startsWith('tcp://')) {\n try { return new URL(hostEnv).hostname || 'localhost'; } catch { /* noop */ }\n }\n return 'localhost';\n}\n\nfunction pickImageForRuntime(runtime: string, configured?: DockerImage): DockerImage {\n if (configured?.name) {\n if (runtime === 'python' && /python|conda|pypy/i.test(configured.name)) return configured;\n if (runtime === 'node' && /node/i.test(configured.name)) return configured;\n }\n return {\n name: runtime === 'python' ? 'python:3.11-slim' : 'node:20-alpine',\n pullPolicy: configured?.pullPolicy ?? 'ifNotPresent',\n auth: configured?.auth,\n };\n}\n\nexport const docker = defineProvider<DockerSandboxHandle, DockerConfig>({\n name: PROVIDER,\n methods: {\n sandbox: {\n create: async (config: DockerConfig, options?: CreateSandboxOptions) => {\n const cfg: DockerConfig = { ...defaultDockerConfig, ...config };\n const effectiveRuntime: string = ((options as any)?.runtime ?? cfg.runtime ?? 'python') as string;\n\n if (effectiveRuntime !== 'python' && effectiveRuntime !== 'node') {\n throw new Error(`Docker provider supports only 'python' or 'node'. Received: ${String(effectiveRuntime)}`);\n }\n\n const docker = new Docker(cfg.connection as any);\n const chosenImage = pickImageForRuntime(effectiveRuntime, cfg.image);\n await ensureImage(docker, chosenImage);\n\n const mergedEnv = { ...cfg.container?.env, ...options?.envs };\n const hb = toHostBindings(cfg.container?.ports);\n const createOptions = {\n Image: chosenImage.name,\n Tty: pick(cfg.container?.tty, false),\n OpenStdin: pick(cfg.container?.openStdin, false),\n Labels: {\n ...(options?.metadata ? Object.fromEntries(\n Object.entries(options.metadata).map(([k, v]) => [`com.computesdk.meta.${k}`, typeof v === 'string' ? v : JSON.stringify(v)])\n ) : {}),\n [LABEL_KEY]: 'true',\n [LABEL_RUNTIME]: effectiveRuntime,\n },\n WorkingDir: cfg.container?.workdir,\n Env: Object.keys(mergedEnv).length > 0\n ? Object.entries(mergedEnv).map(([k, v]) => `${k}=${v}`)\n : undefined,\n Cmd: KEEPALIVE_CMD,\n HostConfig: {\n AutoRemove: cfg.container?.autoRemove ?? false,\n Binds: cfg.container?.binds,\n NetworkMode: cfg.container?.networkMode,\n Privileged: cfg.container?.privileged,\n CapAdd: cfg.container?.capabilities?.add,\n CapDrop: cfg.container?.capabilities?.drop,\n LogConfig: cfg.container?.logDriver\n ? { Type: cfg.container.logDriver, Config: cfg.container.logOpts || {} }\n : undefined,\n Resources: cfg.container?.resources,\n DeviceRequests: cfg.container?.gpus ? [{\n Driver: 'nvidia',\n Count: cfg.container.gpus === 'all' ? -1 : typeof cfg.container.gpus === 'number' ? cfg.container.gpus : 1,\n DeviceIDs: typeof cfg.container.gpus === 'string' && cfg.container.gpus !== 'all' ? [String(cfg.container.gpus)] : undefined,\n Capabilities: [['gpu']],\n }] : undefined,\n ...(hb ? { PortBindings: hb.PortBindings } : {}),\n },\n ...(hb ? { ExposedPorts: hb.ExposedPorts } : {}),\n ...(cfg.createOptions || {}),\n } as import('dockerode').ContainerCreateOptions;\n\n const container = await docker.createContainer(createOptions);\n await container.start(cfg.startOptions || {});\n await waitUntilRunning(container);\n const inspect = await container.inspect();\n const handle: DockerSandboxHandle = {\n docker, container, containerId: inspect.Id,\n image: inspect.Config?.Image ?? chosenImage.name,\n createdAt: new Date(inspect.Created || Date.now()),\n };\n return { sandbox: handle, sandboxId: handle.containerId };\n },\n\n getById: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const container = docker.getContainer(sandboxId);\n const info = await container.inspect();\n return { sandbox: { docker, container, containerId: sandboxId, image: info.Config?.Image ?? '', createdAt: new Date(info.Created || Date.now()) } as DockerSandboxHandle, sandboxId };\n } catch { return null; }\n },\n\n list: async (config: DockerConfig) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const items = await docker.listContainers({ all: true, filters: { label: [LABEL_KEY] } as any });\n return items.map(ci => ({\n sandbox: { docker, container: docker.getContainer(ci.Id), containerId: ci.Id, image: ci.Image, createdAt: new Date((ci as any).Created * 1000) } as DockerSandboxHandle,\n sandboxId: ci.Id,\n }));\n } catch { return []; }\n },\n\n destroy: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const c = docker.getContainer(sandboxId);\n try { await c.stop({ t: 5 } as any); } catch { /* stopped */ }\n await c.remove({ force: true });\n } catch { /* ok if already gone */ }\n },\n\n runCommand: async (handle: DockerSandboxHandle, command: string, _options?: RunCommandOptions): Promise<CommandResult> => {\n const start = Date.now();\n const { stdout, stderr, exitCode } = await runExec(handle, command);\n return { stdout, stderr, exitCode, durationMs: Date.now() - start };\n },\n\n getInfo: async (handle: DockerSandboxHandle): Promise<SandboxInfo> => {\n const info = await handle.container.inspect();\n const state = info.State || {};\n return {\n id: handle.containerId,\n provider: PROVIDER,\n status: state.Running ? 'running' : 'stopped',\n createdAt: new Date(info.Created || handle.createdAt),\n timeout: 300000,\n metadata: {\n image: info.Config?.Image,\n name: info.Name,\n runtime: info.Config?.Labels?.[LABEL_RUNTIME],\n },\n };\n },\n\n getUrl: async (handle: DockerSandboxHandle, options: { port: number; protocol?: string }): Promise<string> => {\n const info = await handle.container.inspect();\n const protocol = options.protocol || 'http';\n const portKeyTcp = `${options.port}/tcp`;\n const ports = info.NetworkSettings?.Ports || {};\n const bindings = ports[portKeyTcp] || ports[`${options.port}/udp`] || [];\n let host = dockerHostNameFromEnv();\n let hostPort = String(options.port);\n if (Array.isArray(bindings) && bindings.length > 0) {\n hostPort = bindings[0].HostPort || hostPort;\n } else {\n const ip = info.NetworkSettings?.IPAddress || Object.values(info.NetworkSettings?.Networks || {})[0]?.IPAddress;\n if (ip) host = ip;\n }\n return `${protocol}://${host}:${hostPort}`;\n },\n\n filesystem: {\n readFile: async (handle: DockerSandboxHandle, path: string): Promise<string> => {\n const cmd = `if [ -f ${JSON.stringify(path)} ]; then base64 ${JSON.stringify(path)} | tr -d '\\\\n'; else exit 1; fi`;\n const { stdout, exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `File not found: ${path}`);\n return Buffer.from(stdout, 'base64').toString('utf8');\n },\n writeFile: async (handle: DockerSandboxHandle, path: string, content: string): Promise<void> => {\n const b64 = Buffer.from(content, 'utf8').toString('base64');\n const cmd = `mkdir -p $(dirname ${JSON.stringify(path)}) && echo \"${b64}\" | base64 -d > ${JSON.stringify(path)}`;\n const { exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `Failed to write: ${path}`);\n },\n mkdir: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `mkdir -p ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to mkdir: ${path}`);\n },\n readdir: async (handle: DockerSandboxHandle, path: string): Promise<FileEntry[]> => {\n const { stdout, exitCode, stderr } = await runExec(handle, `if [ -d ${JSON.stringify(path)} ]; then ls -la ${JSON.stringify(path)}; else exit 1; fi`);\n if (exitCode !== 0) throw new Error(stderr || `Not a directory: ${path}`);\n const lines = stdout.split('\\n').slice(1);\n const entries: FileEntry[] = [];\n for (const line of lines) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const name = parts.slice(8).join(' ');\n if (name === '.' || name === '..') continue;\n entries.push({ name, type: parts[0].startsWith('d') ? 'directory' as const : 'file' as const, size: Number(parts[4]) || 0, modified: new Date() });\n }\n return entries;\n },\n exists: async (handle: DockerSandboxHandle, path: string): Promise<boolean> => {\n const { exitCode } = await runExec(handle, `test -e ${JSON.stringify(path)}`);\n return exitCode === 0;\n },\n remove: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `rm -rf ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to remove: ${path}`);\n },\n },\n\n getInstance: (handle: DockerSandboxHandle): DockerSandboxHandle => handle,\n },\n },\n});\n","import type Docker from 'dockerode';\nimport type {\n DockerOptions,\n Container,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n Exec,\n ImageInfo,\n ImageBuildOptions,\n Network,\n} from 'dockerode';\n\nimport type {\n FileEntry,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n} from 'computesdk';\n\n/** When the provider should clean up containers it created */\nexport type CleanupPolicy = 'always' | 'onSuccess' | 'never';\n\n/** Image pull strategy */\nexport type PullPolicy = 'always' | 'ifNotPresent' | 'never';\n\n/** Connection to the Docker daemon (exactly what dockerode accepts) */\nexport type DockerConnection = DockerOptions;\n\n/** Auth when pulling private images (Engine API AuthConfig shape) */\nexport interface RegistryAuth {\n username?: string;\n password?: string;\n serveraddress?: string;\n identitytoken?: string;\n registrytoken?: string;\n}\n\n/** Default image & pull policy for sandboxes */\nexport interface DockerImage {\n name: string; // e.g. 'python:3.11-slim'\n pullPolicy?: PullPolicy; // default: 'ifNotPresent'\n auth?: RegistryAuth;\n}\n\n/** Convenience shape for port bindings */\nexport type PortBindings = Record<\n `${number}/${'tcp' | 'udp'}`,\n Array<{ hostPort?: number; hostIP?: string }>\n>;\n\n/** Subset of HostConfig resources & knobs that are commonly used */\nexport interface ResourceLimits {\n cpuShares?: number;\n cpuQuota?: number;\n cpuPeriod?: number;\n nanoCPUs?: number;\n memory?: number;\n memorySwap?: number;\n pidsLimit?: number;\n}\n\n/** Declarative container defaults that we'll translate into dockerode create options */\nexport interface ContainerDefaults {\n user?: string;\n workdir?: string;\n env?: Record<string, string>;\n binds?: string[];\n ports?: PortBindings;\n networkMode?: string;\n privileged?: boolean;\n capabilities?: { add?: string[]; drop?: string[] };\n gpus?: 'all' | number | string;\n resources?: ResourceLimits;\n logDriver?: string;\n logOpts?: Record<string, string>;\n autoRemove?: boolean;\n tty?: boolean;\n openStdin?: boolean;\n}\n\n/** Provider-level configuration for Docker */\nexport interface DockerConfig {\n connection?: DockerConnection;\n /** Default image runtime identifier, e.g. 'python' or 'node' */\n runtime?: string;\n timeout?: number;\n image: DockerImage;\n container?: ContainerDefaults;\n createOptions?: ContainerCreateOptions;\n startOptions?: ContainerStartOptions;\n cleanup?: CleanupPolicy;\n streamLogs?: boolean;\n}\n\n/** What we keep for each running sandbox */\nexport interface DockerSandboxHandle {\n docker: Docker;\n container: Container;\n containerId: string;\n image: string;\n createdAt: Date;\n}\n\n/** URL options for port-forwarded services */\nexport interface DockerUrlOptions {\n port: number;\n protocol?: 'http' | 'https';\n host?: string;\n}\n\n/** Optional FS helpers you might expose */\nexport interface DockerSandboxFileSystem {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n mkdir(path: string): Promise<void>;\n readdir(path: string): Promise<FileEntry[]>;\n exists(path: string): Promise<boolean>;\n remove(path: string): Promise<void>;\n}\n\n/** Sensible, safe defaults */\nexport const defaultDockerConfig: DockerConfig = {\n connection: {\n // Let dockerode fall back to DOCKER_HOST or /var/run/docker.sock\n timeout: 60_000,\n version: 'v1.43',\n },\n runtime: 'python',\n timeout: 300_000, // 5 minutes\n image: {\n name: 'python:3.11-slim',\n pullPolicy: 'ifNotPresent',\n },\n container: {\n workdir: '/workspace',\n env: {},\n autoRemove: false, // Keep container around for exec/FS/background\n tty: false, // Non-tty so we can demux stdout/stderr\n openStdin: false,\n resources: { memory: 512 * 1024 * 1024 },\n },\n cleanup: 'always',\n streamLogs: false,\n};\n\n/** Re-exports for convenience */\nexport type {\n Docker,\n Container,\n Exec,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n ImageInfo,\n ImageBuildOptions,\n Network,\n};\n"],"mappings":"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","names":["docker","Docker"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types/types.ts"],"sourcesContent":["import Docker from 'dockerode';\nimport { PassThrough } from 'stream';\nimport { defineProvider } from '@computesdk/provider';\nimport type {\n CommandResult,\n RunCommandOptions,\n CreateInstanceOptions,\n InstanceInfo,\n FileEntry,\n} from '@computesdk/provider';\n\nimport { defaultDockerConfig } from './types/types';\nimport type {\n DockerConfig,\n DockerSandboxHandle,\n DockerImage,\n PortBindings,\n} from './types/types';\n\nconst PROVIDER = 'docker' as const;\nconst LABEL_KEY = 'com.computesdk.sandbox';\nconst LABEL_RUNTIME = 'com.computesdk.runtime';\nconst KEEPALIVE_CMD = ['/bin/sh', '-c', 'while :; do sleep 3600; done'];\n\nfunction pick<T>(val: T | undefined, fallback: T): T {\n return typeof val === 'undefined' ? fallback : val;\n}\n\nasync function ensureImage(docker: Docker, image: DockerImage): Promise<void> {\n const policy = image.pullPolicy ?? 'ifNotPresent';\n if (policy === 'never') return;\n const images = await docker.listImages();\n const hasImage = images.some(img => (img.RepoTags || []).includes(image.name));\n if (policy === 'always' || (policy === 'ifNotPresent' && !hasImage)) {\n await new Promise<void>((resolve, reject) => {\n const cb = (err: any, stream?: NodeJS.ReadableStream) => {\n if (err) return reject(err);\n if (!stream) return reject(new Error('docker.pull returned no stream'));\n (docker as any).modem.followProgress(stream, (err2: any) => (err2 ? reject(err2) : resolve()));\n };\n if (image.auth) docker.pull(image.name, { authconfig: image.auth } as any, cb);\n else docker.pull(image.name, cb);\n });\n }\n}\n\nasync function waitUntilRunning(container: Docker.Container, timeoutMs = 4000) {\n const start = Date.now();\n try {\n const s = await container.inspect();\n if (s.State?.Running) return;\n } catch { /* ignore */ }\n while (Date.now() - start < timeoutMs) {\n const s = await container.inspect();\n if (s.State?.Running) return;\n await new Promise(r => setTimeout(r, 100));\n }\n throw new Error('Container did not reach Running state in time');\n}\n\nasync function runExec(\n handle: DockerSandboxHandle,\n shellCommand: string,\n attachTTY = false\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n await waitUntilRunning(handle.container);\n const exec = await handle.container.exec({\n Cmd: ['/bin/sh', '-c', shellCommand],\n AttachStdout: true,\n AttachStderr: true,\n Tty: attachTTY,\n });\n const stream = (await exec.start({ hijack: true, stdin: false })) as NodeJS.ReadableStream;\n let stdout = '';\n let stderr = '';\n await new Promise<void>((resolve, reject) => {\n if (attachTTY) {\n stream.on('data', (chunk: Buffer) => (stdout += chunk.toString('utf8')));\n stream.on('end', resolve);\n stream.on('error', reject);\n return;\n }\n const out = new PassThrough();\n const err = new PassThrough();\n out.on('data', (c: Buffer) => (stdout += c.toString('utf8')));\n err.on('data', (c: Buffer) => (stderr += c.toString('utf8')));\n (handle.docker as any).modem.demuxStream(stream as any, out as any, err as any);\n stream.on('end', resolve);\n stream.on('error', reject);\n });\n const inspect = await exec.inspect();\n return { stdout, stderr, exitCode: inspect.ExitCode ?? 0 };\n}\n\nfunction toHostBindings(ports?: PortBindings) {\n if (!ports) return undefined;\n const exposed: Record<string, {}> = {};\n const bindings: Record<string, Array<{ HostPort?: string; HostIp?: string }>> = {};\n for (const key of Object.keys(ports)) {\n exposed[key] = {};\n bindings[key] = (ports as any)[key].map((p: any) => ({ HostPort: p.hostPort ? String(p.hostPort) : undefined, HostIp: p.hostIP }));\n }\n return { ExposedPorts: exposed, PortBindings: bindings };\n}\n\nfunction dockerHostNameFromEnv(): string {\n const hostEnv = process.env.DOCKER_HOST;\n if (hostEnv?.startsWith('tcp://')) {\n try { return new URL(hostEnv).hostname || 'localhost'; } catch { /* noop */ }\n }\n return 'localhost';\n}\n\nfunction pickImageForRuntime(runtime: string, configured?: DockerImage): DockerImage {\n if (configured?.name) {\n if (runtime === 'python' && /python|conda|pypy/i.test(configured.name)) return configured;\n if (runtime === 'node' && /node/i.test(configured.name)) return configured;\n }\n return {\n name: runtime === 'python' ? 'python:3.11-slim' : 'node:20-alpine',\n pullPolicy: configured?.pullPolicy ?? 'ifNotPresent',\n auth: configured?.auth,\n };\n}\n\nexport const docker = defineProvider<DockerSandboxHandle, DockerConfig>({\n name: PROVIDER,\n methods: {\n instances: {\n create: async (config: DockerConfig, options?: CreateInstanceOptions) => {\n const cfg: DockerConfig = { ...defaultDockerConfig, ...config };\n const effectiveRuntime: string = ((options as any)?.runtime ?? cfg.runtime ?? 'python') as string;\n\n if (effectiveRuntime !== 'python' && effectiveRuntime !== 'node') {\n throw new Error(`Docker provider supports only 'python' or 'node'. Received: ${String(effectiveRuntime)}`);\n }\n\n const docker = new Docker(cfg.connection as any);\n const chosenImage = pickImageForRuntime(effectiveRuntime, cfg.image);\n await ensureImage(docker, chosenImage);\n\n const mergedEnv = { ...cfg.container?.env, ...options?.envs };\n const hb = toHostBindings(cfg.container?.ports);\n const createOptions = {\n Image: chosenImage.name,\n Tty: pick(cfg.container?.tty, false),\n OpenStdin: pick(cfg.container?.openStdin, false),\n Labels: {\n ...(options?.metadata ? Object.fromEntries(\n Object.entries(options.metadata).map(([k, v]) => [`com.computesdk.meta.${k}`, typeof v === 'string' ? v : JSON.stringify(v)])\n ) : {}),\n [LABEL_KEY]: 'true',\n [LABEL_RUNTIME]: effectiveRuntime,\n },\n WorkingDir: cfg.container?.workdir,\n Env: Object.keys(mergedEnv).length > 0\n ? Object.entries(mergedEnv).map(([k, v]) => `${k}=${v}`)\n : undefined,\n Cmd: KEEPALIVE_CMD,\n HostConfig: {\n AutoRemove: cfg.container?.autoRemove ?? false,\n Binds: cfg.container?.binds,\n NetworkMode: cfg.container?.networkMode,\n Privileged: cfg.container?.privileged,\n CapAdd: cfg.container?.capabilities?.add,\n CapDrop: cfg.container?.capabilities?.drop,\n LogConfig: cfg.container?.logDriver\n ? { Type: cfg.container.logDriver, Config: cfg.container.logOpts || {} }\n : undefined,\n Resources: cfg.container?.resources,\n DeviceRequests: cfg.container?.gpus ? [{\n Driver: 'nvidia',\n Count: cfg.container.gpus === 'all' ? -1 : typeof cfg.container.gpus === 'number' ? cfg.container.gpus : 1,\n DeviceIDs: typeof cfg.container.gpus === 'string' && cfg.container.gpus !== 'all' ? [String(cfg.container.gpus)] : undefined,\n Capabilities: [['gpu']],\n }] : undefined,\n ...(hb ? { PortBindings: hb.PortBindings } : {}),\n },\n ...(hb ? { ExposedPorts: hb.ExposedPorts } : {}),\n ...(cfg.createOptions || {}),\n } as import('dockerode').ContainerCreateOptions;\n\n const container = await docker.createContainer(createOptions);\n await container.start(cfg.startOptions || {});\n await waitUntilRunning(container);\n const inspect = await container.inspect();\n const handle: DockerSandboxHandle = {\n docker, container, containerId: inspect.Id,\n image: inspect.Config?.Image ?? chosenImage.name,\n createdAt: new Date(inspect.Created || Date.now()),\n };\n return { instance: handle, instanceId: handle.containerId };\n },\n\n getById: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const container = docker.getContainer(sandboxId);\n const info = await container.inspect();\n return { instance: { docker, container, containerId: sandboxId, image: info.Config?.Image ?? '', createdAt: new Date(info.Created || Date.now()) } as DockerSandboxHandle, instanceId: sandboxId };\n } catch { return null; }\n },\n\n list: async (config: DockerConfig) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const items = await docker.listContainers({ all: true, filters: { label: [LABEL_KEY] } as any });\n return items.map(ci => ({\n instance: { docker, container: docker.getContainer(ci.Id), containerId: ci.Id, image: ci.Image, createdAt: new Date((ci as any).Created * 1000) } as DockerSandboxHandle, instanceId: ci.Id,\n }));\n } catch { return []; }\n },\n\n destroy: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const c = docker.getContainer(sandboxId);\n try { await c.stop({ t: 5 } as any); } catch { /* stopped */ }\n await c.remove({ force: true });\n } catch { /* ok if already gone */ }\n },\n\n runCommand: async (handle: DockerSandboxHandle, command: string, _options?: RunCommandOptions): Promise<CommandResult> => {\n const start = Date.now();\n const { stdout, stderr, exitCode } = await runExec(handle, command);\n return { stdout, stderr, exitCode, durationMs: Date.now() - start };\n },\n\n getInfo: async (handle: DockerSandboxHandle): Promise<InstanceInfo> => {\n const info = await handle.container.inspect();\n const state = info.State || {};\n return {\n id: handle.containerId,\n provider: PROVIDER,\n status: state.Running ? 'running' : 'stopped',\n createdAt: new Date(info.Created || handle.createdAt),\n timeout: 300000,\n metadata: {\n image: info.Config?.Image,\n name: info.Name,\n runtime: info.Config?.Labels?.[LABEL_RUNTIME],\n },\n };\n },\n\n getUrl: async (handle: DockerSandboxHandle, options: { port: number; protocol?: string }): Promise<string> => {\n const info = await handle.container.inspect();\n const protocol = options.protocol || 'http';\n const portKeyTcp = `${options.port}/tcp`;\n const ports = info.NetworkSettings?.Ports || {};\n const bindings = ports[portKeyTcp] || ports[`${options.port}/udp`] || [];\n let host = dockerHostNameFromEnv();\n let hostPort = String(options.port);\n if (Array.isArray(bindings) && bindings.length > 0) {\n hostPort = bindings[0].HostPort || hostPort;\n } else {\n const ip = info.NetworkSettings?.IPAddress || Object.values(info.NetworkSettings?.Networks || {})[0]?.IPAddress;\n if (ip) host = ip;\n }\n return `${protocol}://${host}:${hostPort}`;\n },\n\n filesystem: {\n readFile: async (handle: DockerSandboxHandle, path: string): Promise<string> => {\n const cmd = `if [ -f ${JSON.stringify(path)} ]; then base64 ${JSON.stringify(path)} | tr -d '\\\\n'; else exit 1; fi`;\n const { stdout, exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `File not found: ${path}`);\n return Buffer.from(stdout, 'base64').toString('utf8');\n },\n writeFile: async (handle: DockerSandboxHandle, path: string, content: string): Promise<void> => {\n const b64 = Buffer.from(content, 'utf8').toString('base64');\n const cmd = `mkdir -p $(dirname ${JSON.stringify(path)}) && echo \"${b64}\" | base64 -d > ${JSON.stringify(path)}`;\n const { exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `Failed to write: ${path}`);\n },\n mkdir: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `mkdir -p ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to mkdir: ${path}`);\n },\n readdir: async (handle: DockerSandboxHandle, path: string): Promise<FileEntry[]> => {\n const { stdout, exitCode, stderr } = await runExec(handle, `if [ -d ${JSON.stringify(path)} ]; then ls -la ${JSON.stringify(path)}; else exit 1; fi`);\n if (exitCode !== 0) throw new Error(stderr || `Not a directory: ${path}`);\n const lines = stdout.split('\\n').slice(1);\n const entries: FileEntry[] = [];\n for (const line of lines) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const name = parts.slice(8).join(' ');\n if (name === '.' || name === '..') continue;\n entries.push({ name, type: parts[0].startsWith('d') ? 'directory' as const : 'file' as const, size: Number(parts[4]) || 0, modified: new Date() });\n }\n return entries;\n },\n exists: async (handle: DockerSandboxHandle, path: string): Promise<boolean> => {\n const { exitCode } = await runExec(handle, `test -e ${JSON.stringify(path)}`);\n return exitCode === 0;\n },\n remove: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `rm -rf ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to remove: ${path}`);\n },\n },\n\n getInstance: (handle: DockerSandboxHandle): DockerSandboxHandle => handle,\n },\n },\n});\n","import type Docker from 'dockerode';\nimport type {\n DockerOptions,\n Container,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n Exec,\n ImageInfo,\n ImageBuildOptions,\n Network,\n} from 'dockerode';\n\nimport type {\n FileEntry,\n RunCommandOptions,\n CreateInstanceOptions,\n InstanceInfo,\n} from 'computesdk';\n\n/** When the provider should clean up containers it created */\nexport type CleanupPolicy = 'always' | 'onSuccess' | 'never';\n\n/** Image pull strategy */\nexport type PullPolicy = 'always' | 'ifNotPresent' | 'never';\n\n/** Connection to the Docker daemon (exactly what dockerode accepts) */\nexport type DockerConnection = DockerOptions;\n\n/** Auth when pulling private images (Engine API AuthConfig shape) */\nexport interface RegistryAuth {\n username?: string;\n password?: string;\n serveraddress?: string;\n identitytoken?: string;\n registrytoken?: string;\n}\n\n/** Default image & pull policy for sandboxes */\nexport interface DockerImage {\n name: string; // e.g. 'python:3.11-slim'\n pullPolicy?: PullPolicy; // default: 'ifNotPresent'\n auth?: RegistryAuth;\n}\n\n/** Convenience shape for port bindings */\nexport type PortBindings = Record<\n `${number}/${'tcp' | 'udp'}`,\n Array<{ hostPort?: number; hostIP?: string }>\n>;\n\n/** Subset of HostConfig resources & knobs that are commonly used */\nexport interface ResourceLimits {\n cpuShares?: number;\n cpuQuota?: number;\n cpuPeriod?: number;\n nanoCPUs?: number;\n memory?: number;\n memorySwap?: number;\n pidsLimit?: number;\n}\n\n/** Declarative container defaults that we'll translate into dockerode create options */\nexport interface ContainerDefaults {\n user?: string;\n workdir?: string;\n env?: Record<string, string>;\n binds?: string[];\n ports?: PortBindings;\n networkMode?: string;\n privileged?: boolean;\n capabilities?: { add?: string[]; drop?: string[] };\n gpus?: 'all' | number | string;\n resources?: ResourceLimits;\n logDriver?: string;\n logOpts?: Record<string, string>;\n autoRemove?: boolean;\n tty?: boolean;\n openStdin?: boolean;\n}\n\n/** Provider-level configuration for Docker */\nexport interface DockerConfig {\n connection?: DockerConnection;\n /** Default image runtime identifier, e.g. 'python' or 'node' */\n runtime?: string;\n timeout?: number;\n image: DockerImage;\n container?: ContainerDefaults;\n createOptions?: ContainerCreateOptions;\n startOptions?: ContainerStartOptions;\n cleanup?: CleanupPolicy;\n streamLogs?: boolean;\n}\n\n/** What we keep for each running sandbox */\nexport interface DockerSandboxHandle {\n docker: Docker;\n container: Container;\n containerId: string;\n image: string;\n createdAt: Date;\n}\n\n/** URL options for port-forwarded services */\nexport interface DockerUrlOptions {\n port: number;\n protocol?: 'http' | 'https';\n host?: string;\n}\n\n/** Optional FS helpers you might expose */\nexport interface DockerSandboxFileSystem {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n mkdir(path: string): Promise<void>;\n readdir(path: string): Promise<FileEntry[]>;\n exists(path: string): Promise<boolean>;\n remove(path: string): Promise<void>;\n}\n\n/** Sensible, safe defaults */\nexport const defaultDockerConfig: DockerConfig = {\n connection: {\n // Let dockerode fall back to DOCKER_HOST or /var/run/docker.sock\n timeout: 60_000,\n version: 'v1.43',\n },\n runtime: 'python',\n timeout: 300_000, // 5 minutes\n image: {\n name: 'python:3.11-slim',\n pullPolicy: 'ifNotPresent',\n },\n container: {\n workdir: '/workspace',\n env: {},\n autoRemove: false, // Keep container around for exec/FS/background\n tty: false, // Non-tty so we can demux stdout/stderr\n openStdin: false,\n resources: { memory: 512 * 1024 * 1024 },\n },\n cleanup: 'always',\n streamLogs: false,\n};\n\n/** Re-exports for convenience */\nexport type {\n Docker,\n Container,\n Exec,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n ImageInfo,\n ImageBuildOptions,\n Network,\n};\n"],"mappings":"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","names":["docker","Docker"]}
package/dist/index.mjs CHANGED
@@ -133,7 +133,7 @@ function pickImageForRuntime(runtime, configured) {
133
133
  var docker = defineProvider({
134
134
  name: PROVIDER,
135
135
  methods: {
136
- sandbox: {
136
+ instances: {
137
137
  create: async (config, options) => {
138
138
  const cfg = { ...defaultDockerConfig, ...config };
139
139
  const effectiveRuntime = options?.runtime ?? cfg.runtime ?? "python";
@@ -190,14 +190,14 @@ var docker = defineProvider({
190
190
  image: inspect.Config?.Image ?? chosenImage.name,
191
191
  createdAt: new Date(inspect.Created || Date.now())
192
192
  };
193
- return { sandbox: handle, sandboxId: handle.containerId };
193
+ return { instance: handle, instanceId: handle.containerId };
194
194
  },
195
195
  getById: async (config, sandboxId) => {
196
196
  const docker2 = new Docker((config || defaultDockerConfig).connection);
197
197
  try {
198
198
  const container = docker2.getContainer(sandboxId);
199
199
  const info = await container.inspect();
200
- return { sandbox: { docker: docker2, container, containerId: sandboxId, image: info.Config?.Image ?? "", createdAt: new Date(info.Created || Date.now()) }, sandboxId };
200
+ return { instance: { docker: docker2, container, containerId: sandboxId, image: info.Config?.Image ?? "", createdAt: new Date(info.Created || Date.now()) }, instanceId: sandboxId };
201
201
  } catch {
202
202
  return null;
203
203
  }
@@ -207,8 +207,8 @@ var docker = defineProvider({
207
207
  try {
208
208
  const items = await docker2.listContainers({ all: true, filters: { label: [LABEL_KEY] } });
209
209
  return items.map((ci) => ({
210
- sandbox: { docker: docker2, container: docker2.getContainer(ci.Id), containerId: ci.Id, image: ci.Image, createdAt: new Date(ci.Created * 1e3) },
211
- sandboxId: ci.Id
210
+ instance: { docker: docker2, container: docker2.getContainer(ci.Id), containerId: ci.Id, image: ci.Image, createdAt: new Date(ci.Created * 1e3) },
211
+ instanceId: ci.Id
212
212
  }));
213
213
  } catch {
214
214
  return [];
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types/types.ts"],"sourcesContent":["import Docker from 'dockerode';\nimport { PassThrough } from 'stream';\nimport { defineProvider } from '@computesdk/provider';\nimport type {\n CommandResult,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n FileEntry,\n} from '@computesdk/provider';\n\nimport { defaultDockerConfig } from './types/types';\nimport type {\n DockerConfig,\n DockerSandboxHandle,\n DockerImage,\n PortBindings,\n} from './types/types';\n\nconst PROVIDER = 'docker' as const;\nconst LABEL_KEY = 'com.computesdk.sandbox';\nconst LABEL_RUNTIME = 'com.computesdk.runtime';\nconst KEEPALIVE_CMD = ['/bin/sh', '-c', 'while :; do sleep 3600; done'];\n\nfunction pick<T>(val: T | undefined, fallback: T): T {\n return typeof val === 'undefined' ? fallback : val;\n}\n\nasync function ensureImage(docker: Docker, image: DockerImage): Promise<void> {\n const policy = image.pullPolicy ?? 'ifNotPresent';\n if (policy === 'never') return;\n const images = await docker.listImages();\n const hasImage = images.some(img => (img.RepoTags || []).includes(image.name));\n if (policy === 'always' || (policy === 'ifNotPresent' && !hasImage)) {\n await new Promise<void>((resolve, reject) => {\n const cb = (err: any, stream?: NodeJS.ReadableStream) => {\n if (err) return reject(err);\n if (!stream) return reject(new Error('docker.pull returned no stream'));\n (docker as any).modem.followProgress(stream, (err2: any) => (err2 ? reject(err2) : resolve()));\n };\n if (image.auth) docker.pull(image.name, { authconfig: image.auth } as any, cb);\n else docker.pull(image.name, cb);\n });\n }\n}\n\nasync function waitUntilRunning(container: Docker.Container, timeoutMs = 4000) {\n const start = Date.now();\n try {\n const s = await container.inspect();\n if (s.State?.Running) return;\n } catch { /* ignore */ }\n while (Date.now() - start < timeoutMs) {\n const s = await container.inspect();\n if (s.State?.Running) return;\n await new Promise(r => setTimeout(r, 100));\n }\n throw new Error('Container did not reach Running state in time');\n}\n\nasync function runExec(\n handle: DockerSandboxHandle,\n shellCommand: string,\n attachTTY = false\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n await waitUntilRunning(handle.container);\n const exec = await handle.container.exec({\n Cmd: ['/bin/sh', '-c', shellCommand],\n AttachStdout: true,\n AttachStderr: true,\n Tty: attachTTY,\n });\n const stream = (await exec.start({ hijack: true, stdin: false })) as NodeJS.ReadableStream;\n let stdout = '';\n let stderr = '';\n await new Promise<void>((resolve, reject) => {\n if (attachTTY) {\n stream.on('data', (chunk: Buffer) => (stdout += chunk.toString('utf8')));\n stream.on('end', resolve);\n stream.on('error', reject);\n return;\n }\n const out = new PassThrough();\n const err = new PassThrough();\n out.on('data', (c: Buffer) => (stdout += c.toString('utf8')));\n err.on('data', (c: Buffer) => (stderr += c.toString('utf8')));\n (handle.docker as any).modem.demuxStream(stream as any, out as any, err as any);\n stream.on('end', resolve);\n stream.on('error', reject);\n });\n const inspect = await exec.inspect();\n return { stdout, stderr, exitCode: inspect.ExitCode ?? 0 };\n}\n\nfunction toHostBindings(ports?: PortBindings) {\n if (!ports) return undefined;\n const exposed: Record<string, {}> = {};\n const bindings: Record<string, Array<{ HostPort?: string; HostIp?: string }>> = {};\n for (const key of Object.keys(ports)) {\n exposed[key] = {};\n bindings[key] = (ports as any)[key].map((p: any) => ({ HostPort: p.hostPort ? String(p.hostPort) : undefined, HostIp: p.hostIP }));\n }\n return { ExposedPorts: exposed, PortBindings: bindings };\n}\n\nfunction dockerHostNameFromEnv(): string {\n const hostEnv = process.env.DOCKER_HOST;\n if (hostEnv?.startsWith('tcp://')) {\n try { return new URL(hostEnv).hostname || 'localhost'; } catch { /* noop */ }\n }\n return 'localhost';\n}\n\nfunction pickImageForRuntime(runtime: string, configured?: DockerImage): DockerImage {\n if (configured?.name) {\n if (runtime === 'python' && /python|conda|pypy/i.test(configured.name)) return configured;\n if (runtime === 'node' && /node/i.test(configured.name)) return configured;\n }\n return {\n name: runtime === 'python' ? 'python:3.11-slim' : 'node:20-alpine',\n pullPolicy: configured?.pullPolicy ?? 'ifNotPresent',\n auth: configured?.auth,\n };\n}\n\nexport const docker = defineProvider<DockerSandboxHandle, DockerConfig>({\n name: PROVIDER,\n methods: {\n sandbox: {\n create: async (config: DockerConfig, options?: CreateSandboxOptions) => {\n const cfg: DockerConfig = { ...defaultDockerConfig, ...config };\n const effectiveRuntime: string = ((options as any)?.runtime ?? cfg.runtime ?? 'python') as string;\n\n if (effectiveRuntime !== 'python' && effectiveRuntime !== 'node') {\n throw new Error(`Docker provider supports only 'python' or 'node'. Received: ${String(effectiveRuntime)}`);\n }\n\n const docker = new Docker(cfg.connection as any);\n const chosenImage = pickImageForRuntime(effectiveRuntime, cfg.image);\n await ensureImage(docker, chosenImage);\n\n const mergedEnv = { ...cfg.container?.env, ...options?.envs };\n const hb = toHostBindings(cfg.container?.ports);\n const createOptions = {\n Image: chosenImage.name,\n Tty: pick(cfg.container?.tty, false),\n OpenStdin: pick(cfg.container?.openStdin, false),\n Labels: {\n ...(options?.metadata ? Object.fromEntries(\n Object.entries(options.metadata).map(([k, v]) => [`com.computesdk.meta.${k}`, typeof v === 'string' ? v : JSON.stringify(v)])\n ) : {}),\n [LABEL_KEY]: 'true',\n [LABEL_RUNTIME]: effectiveRuntime,\n },\n WorkingDir: cfg.container?.workdir,\n Env: Object.keys(mergedEnv).length > 0\n ? Object.entries(mergedEnv).map(([k, v]) => `${k}=${v}`)\n : undefined,\n Cmd: KEEPALIVE_CMD,\n HostConfig: {\n AutoRemove: cfg.container?.autoRemove ?? false,\n Binds: cfg.container?.binds,\n NetworkMode: cfg.container?.networkMode,\n Privileged: cfg.container?.privileged,\n CapAdd: cfg.container?.capabilities?.add,\n CapDrop: cfg.container?.capabilities?.drop,\n LogConfig: cfg.container?.logDriver\n ? { Type: cfg.container.logDriver, Config: cfg.container.logOpts || {} }\n : undefined,\n Resources: cfg.container?.resources,\n DeviceRequests: cfg.container?.gpus ? [{\n Driver: 'nvidia',\n Count: cfg.container.gpus === 'all' ? -1 : typeof cfg.container.gpus === 'number' ? cfg.container.gpus : 1,\n DeviceIDs: typeof cfg.container.gpus === 'string' && cfg.container.gpus !== 'all' ? [String(cfg.container.gpus)] : undefined,\n Capabilities: [['gpu']],\n }] : undefined,\n ...(hb ? { PortBindings: hb.PortBindings } : {}),\n },\n ...(hb ? { ExposedPorts: hb.ExposedPorts } : {}),\n ...(cfg.createOptions || {}),\n } as import('dockerode').ContainerCreateOptions;\n\n const container = await docker.createContainer(createOptions);\n await container.start(cfg.startOptions || {});\n await waitUntilRunning(container);\n const inspect = await container.inspect();\n const handle: DockerSandboxHandle = {\n docker, container, containerId: inspect.Id,\n image: inspect.Config?.Image ?? chosenImage.name,\n createdAt: new Date(inspect.Created || Date.now()),\n };\n return { sandbox: handle, sandboxId: handle.containerId };\n },\n\n getById: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const container = docker.getContainer(sandboxId);\n const info = await container.inspect();\n return { sandbox: { docker, container, containerId: sandboxId, image: info.Config?.Image ?? '', createdAt: new Date(info.Created || Date.now()) } as DockerSandboxHandle, sandboxId };\n } catch { return null; }\n },\n\n list: async (config: DockerConfig) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const items = await docker.listContainers({ all: true, filters: { label: [LABEL_KEY] } as any });\n return items.map(ci => ({\n sandbox: { docker, container: docker.getContainer(ci.Id), containerId: ci.Id, image: ci.Image, createdAt: new Date((ci as any).Created * 1000) } as DockerSandboxHandle,\n sandboxId: ci.Id,\n }));\n } catch { return []; }\n },\n\n destroy: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const c = docker.getContainer(sandboxId);\n try { await c.stop({ t: 5 } as any); } catch { /* stopped */ }\n await c.remove({ force: true });\n } catch { /* ok if already gone */ }\n },\n\n runCommand: async (handle: DockerSandboxHandle, command: string, _options?: RunCommandOptions): Promise<CommandResult> => {\n const start = Date.now();\n const { stdout, stderr, exitCode } = await runExec(handle, command);\n return { stdout, stderr, exitCode, durationMs: Date.now() - start };\n },\n\n getInfo: async (handle: DockerSandboxHandle): Promise<SandboxInfo> => {\n const info = await handle.container.inspect();\n const state = info.State || {};\n return {\n id: handle.containerId,\n provider: PROVIDER,\n status: state.Running ? 'running' : 'stopped',\n createdAt: new Date(info.Created || handle.createdAt),\n timeout: 300000,\n metadata: {\n image: info.Config?.Image,\n name: info.Name,\n runtime: info.Config?.Labels?.[LABEL_RUNTIME],\n },\n };\n },\n\n getUrl: async (handle: DockerSandboxHandle, options: { port: number; protocol?: string }): Promise<string> => {\n const info = await handle.container.inspect();\n const protocol = options.protocol || 'http';\n const portKeyTcp = `${options.port}/tcp`;\n const ports = info.NetworkSettings?.Ports || {};\n const bindings = ports[portKeyTcp] || ports[`${options.port}/udp`] || [];\n let host = dockerHostNameFromEnv();\n let hostPort = String(options.port);\n if (Array.isArray(bindings) && bindings.length > 0) {\n hostPort = bindings[0].HostPort || hostPort;\n } else {\n const ip = info.NetworkSettings?.IPAddress || Object.values(info.NetworkSettings?.Networks || {})[0]?.IPAddress;\n if (ip) host = ip;\n }\n return `${protocol}://${host}:${hostPort}`;\n },\n\n filesystem: {\n readFile: async (handle: DockerSandboxHandle, path: string): Promise<string> => {\n const cmd = `if [ -f ${JSON.stringify(path)} ]; then base64 ${JSON.stringify(path)} | tr -d '\\\\n'; else exit 1; fi`;\n const { stdout, exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `File not found: ${path}`);\n return Buffer.from(stdout, 'base64').toString('utf8');\n },\n writeFile: async (handle: DockerSandboxHandle, path: string, content: string): Promise<void> => {\n const b64 = Buffer.from(content, 'utf8').toString('base64');\n const cmd = `mkdir -p $(dirname ${JSON.stringify(path)}) && echo \"${b64}\" | base64 -d > ${JSON.stringify(path)}`;\n const { exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `Failed to write: ${path}`);\n },\n mkdir: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `mkdir -p ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to mkdir: ${path}`);\n },\n readdir: async (handle: DockerSandboxHandle, path: string): Promise<FileEntry[]> => {\n const { stdout, exitCode, stderr } = await runExec(handle, `if [ -d ${JSON.stringify(path)} ]; then ls -la ${JSON.stringify(path)}; else exit 1; fi`);\n if (exitCode !== 0) throw new Error(stderr || `Not a directory: ${path}`);\n const lines = stdout.split('\\n').slice(1);\n const entries: FileEntry[] = [];\n for (const line of lines) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const name = parts.slice(8).join(' ');\n if (name === '.' || name === '..') continue;\n entries.push({ name, type: parts[0].startsWith('d') ? 'directory' as const : 'file' as const, size: Number(parts[4]) || 0, modified: new Date() });\n }\n return entries;\n },\n exists: async (handle: DockerSandboxHandle, path: string): Promise<boolean> => {\n const { exitCode } = await runExec(handle, `test -e ${JSON.stringify(path)}`);\n return exitCode === 0;\n },\n remove: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `rm -rf ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to remove: ${path}`);\n },\n },\n\n getInstance: (handle: DockerSandboxHandle): DockerSandboxHandle => handle,\n },\n },\n});\n","import type Docker from 'dockerode';\nimport type {\n DockerOptions,\n Container,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n Exec,\n ImageInfo,\n ImageBuildOptions,\n Network,\n} from 'dockerode';\n\nimport type {\n FileEntry,\n RunCommandOptions,\n CreateSandboxOptions,\n SandboxInfo,\n} from 'computesdk';\n\n/** When the provider should clean up containers it created */\nexport type CleanupPolicy = 'always' | 'onSuccess' | 'never';\n\n/** Image pull strategy */\nexport type PullPolicy = 'always' | 'ifNotPresent' | 'never';\n\n/** Connection to the Docker daemon (exactly what dockerode accepts) */\nexport type DockerConnection = DockerOptions;\n\n/** Auth when pulling private images (Engine API AuthConfig shape) */\nexport interface RegistryAuth {\n username?: string;\n password?: string;\n serveraddress?: string;\n identitytoken?: string;\n registrytoken?: string;\n}\n\n/** Default image & pull policy for sandboxes */\nexport interface DockerImage {\n name: string; // e.g. 'python:3.11-slim'\n pullPolicy?: PullPolicy; // default: 'ifNotPresent'\n auth?: RegistryAuth;\n}\n\n/** Convenience shape for port bindings */\nexport type PortBindings = Record<\n `${number}/${'tcp' | 'udp'}`,\n Array<{ hostPort?: number; hostIP?: string }>\n>;\n\n/** Subset of HostConfig resources & knobs that are commonly used */\nexport interface ResourceLimits {\n cpuShares?: number;\n cpuQuota?: number;\n cpuPeriod?: number;\n nanoCPUs?: number;\n memory?: number;\n memorySwap?: number;\n pidsLimit?: number;\n}\n\n/** Declarative container defaults that we'll translate into dockerode create options */\nexport interface ContainerDefaults {\n user?: string;\n workdir?: string;\n env?: Record<string, string>;\n binds?: string[];\n ports?: PortBindings;\n networkMode?: string;\n privileged?: boolean;\n capabilities?: { add?: string[]; drop?: string[] };\n gpus?: 'all' | number | string;\n resources?: ResourceLimits;\n logDriver?: string;\n logOpts?: Record<string, string>;\n autoRemove?: boolean;\n tty?: boolean;\n openStdin?: boolean;\n}\n\n/** Provider-level configuration for Docker */\nexport interface DockerConfig {\n connection?: DockerConnection;\n /** Default image runtime identifier, e.g. 'python' or 'node' */\n runtime?: string;\n timeout?: number;\n image: DockerImage;\n container?: ContainerDefaults;\n createOptions?: ContainerCreateOptions;\n startOptions?: ContainerStartOptions;\n cleanup?: CleanupPolicy;\n streamLogs?: boolean;\n}\n\n/** What we keep for each running sandbox */\nexport interface DockerSandboxHandle {\n docker: Docker;\n container: Container;\n containerId: string;\n image: string;\n createdAt: Date;\n}\n\n/** URL options for port-forwarded services */\nexport interface DockerUrlOptions {\n port: number;\n protocol?: 'http' | 'https';\n host?: string;\n}\n\n/** Optional FS helpers you might expose */\nexport interface DockerSandboxFileSystem {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n mkdir(path: string): Promise<void>;\n readdir(path: string): Promise<FileEntry[]>;\n exists(path: string): Promise<boolean>;\n remove(path: string): Promise<void>;\n}\n\n/** Sensible, safe defaults */\nexport const defaultDockerConfig: DockerConfig = {\n connection: {\n // Let dockerode fall back to DOCKER_HOST or /var/run/docker.sock\n timeout: 60_000,\n version: 'v1.43',\n },\n runtime: 'python',\n timeout: 300_000, // 5 minutes\n image: {\n name: 'python:3.11-slim',\n pullPolicy: 'ifNotPresent',\n },\n container: {\n workdir: '/workspace',\n env: {},\n autoRemove: false, // Keep container around for exec/FS/background\n tty: false, // Non-tty so we can demux stdout/stderr\n openStdin: false,\n resources: { memory: 512 * 1024 * 1024 },\n },\n cleanup: 'always',\n streamLogs: false,\n};\n\n/** Re-exports for convenience */\nexport type {\n Docker,\n Container,\n Exec,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n ImageInfo,\n ImageBuildOptions,\n Network,\n};\n"],"mappings":"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","names":["docker"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types/types.ts"],"sourcesContent":["import Docker from 'dockerode';\nimport { PassThrough } from 'stream';\nimport { defineProvider } from '@computesdk/provider';\nimport type {\n CommandResult,\n RunCommandOptions,\n CreateInstanceOptions,\n InstanceInfo,\n FileEntry,\n} from '@computesdk/provider';\n\nimport { defaultDockerConfig } from './types/types';\nimport type {\n DockerConfig,\n DockerSandboxHandle,\n DockerImage,\n PortBindings,\n} from './types/types';\n\nconst PROVIDER = 'docker' as const;\nconst LABEL_KEY = 'com.computesdk.sandbox';\nconst LABEL_RUNTIME = 'com.computesdk.runtime';\nconst KEEPALIVE_CMD = ['/bin/sh', '-c', 'while :; do sleep 3600; done'];\n\nfunction pick<T>(val: T | undefined, fallback: T): T {\n return typeof val === 'undefined' ? fallback : val;\n}\n\nasync function ensureImage(docker: Docker, image: DockerImage): Promise<void> {\n const policy = image.pullPolicy ?? 'ifNotPresent';\n if (policy === 'never') return;\n const images = await docker.listImages();\n const hasImage = images.some(img => (img.RepoTags || []).includes(image.name));\n if (policy === 'always' || (policy === 'ifNotPresent' && !hasImage)) {\n await new Promise<void>((resolve, reject) => {\n const cb = (err: any, stream?: NodeJS.ReadableStream) => {\n if (err) return reject(err);\n if (!stream) return reject(new Error('docker.pull returned no stream'));\n (docker as any).modem.followProgress(stream, (err2: any) => (err2 ? reject(err2) : resolve()));\n };\n if (image.auth) docker.pull(image.name, { authconfig: image.auth } as any, cb);\n else docker.pull(image.name, cb);\n });\n }\n}\n\nasync function waitUntilRunning(container: Docker.Container, timeoutMs = 4000) {\n const start = Date.now();\n try {\n const s = await container.inspect();\n if (s.State?.Running) return;\n } catch { /* ignore */ }\n while (Date.now() - start < timeoutMs) {\n const s = await container.inspect();\n if (s.State?.Running) return;\n await new Promise(r => setTimeout(r, 100));\n }\n throw new Error('Container did not reach Running state in time');\n}\n\nasync function runExec(\n handle: DockerSandboxHandle,\n shellCommand: string,\n attachTTY = false\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n await waitUntilRunning(handle.container);\n const exec = await handle.container.exec({\n Cmd: ['/bin/sh', '-c', shellCommand],\n AttachStdout: true,\n AttachStderr: true,\n Tty: attachTTY,\n });\n const stream = (await exec.start({ hijack: true, stdin: false })) as NodeJS.ReadableStream;\n let stdout = '';\n let stderr = '';\n await new Promise<void>((resolve, reject) => {\n if (attachTTY) {\n stream.on('data', (chunk: Buffer) => (stdout += chunk.toString('utf8')));\n stream.on('end', resolve);\n stream.on('error', reject);\n return;\n }\n const out = new PassThrough();\n const err = new PassThrough();\n out.on('data', (c: Buffer) => (stdout += c.toString('utf8')));\n err.on('data', (c: Buffer) => (stderr += c.toString('utf8')));\n (handle.docker as any).modem.demuxStream(stream as any, out as any, err as any);\n stream.on('end', resolve);\n stream.on('error', reject);\n });\n const inspect = await exec.inspect();\n return { stdout, stderr, exitCode: inspect.ExitCode ?? 0 };\n}\n\nfunction toHostBindings(ports?: PortBindings) {\n if (!ports) return undefined;\n const exposed: Record<string, {}> = {};\n const bindings: Record<string, Array<{ HostPort?: string; HostIp?: string }>> = {};\n for (const key of Object.keys(ports)) {\n exposed[key] = {};\n bindings[key] = (ports as any)[key].map((p: any) => ({ HostPort: p.hostPort ? String(p.hostPort) : undefined, HostIp: p.hostIP }));\n }\n return { ExposedPorts: exposed, PortBindings: bindings };\n}\n\nfunction dockerHostNameFromEnv(): string {\n const hostEnv = process.env.DOCKER_HOST;\n if (hostEnv?.startsWith('tcp://')) {\n try { return new URL(hostEnv).hostname || 'localhost'; } catch { /* noop */ }\n }\n return 'localhost';\n}\n\nfunction pickImageForRuntime(runtime: string, configured?: DockerImage): DockerImage {\n if (configured?.name) {\n if (runtime === 'python' && /python|conda|pypy/i.test(configured.name)) return configured;\n if (runtime === 'node' && /node/i.test(configured.name)) return configured;\n }\n return {\n name: runtime === 'python' ? 'python:3.11-slim' : 'node:20-alpine',\n pullPolicy: configured?.pullPolicy ?? 'ifNotPresent',\n auth: configured?.auth,\n };\n}\n\nexport const docker = defineProvider<DockerSandboxHandle, DockerConfig>({\n name: PROVIDER,\n methods: {\n instances: {\n create: async (config: DockerConfig, options?: CreateInstanceOptions) => {\n const cfg: DockerConfig = { ...defaultDockerConfig, ...config };\n const effectiveRuntime: string = ((options as any)?.runtime ?? cfg.runtime ?? 'python') as string;\n\n if (effectiveRuntime !== 'python' && effectiveRuntime !== 'node') {\n throw new Error(`Docker provider supports only 'python' or 'node'. Received: ${String(effectiveRuntime)}`);\n }\n\n const docker = new Docker(cfg.connection as any);\n const chosenImage = pickImageForRuntime(effectiveRuntime, cfg.image);\n await ensureImage(docker, chosenImage);\n\n const mergedEnv = { ...cfg.container?.env, ...options?.envs };\n const hb = toHostBindings(cfg.container?.ports);\n const createOptions = {\n Image: chosenImage.name,\n Tty: pick(cfg.container?.tty, false),\n OpenStdin: pick(cfg.container?.openStdin, false),\n Labels: {\n ...(options?.metadata ? Object.fromEntries(\n Object.entries(options.metadata).map(([k, v]) => [`com.computesdk.meta.${k}`, typeof v === 'string' ? v : JSON.stringify(v)])\n ) : {}),\n [LABEL_KEY]: 'true',\n [LABEL_RUNTIME]: effectiveRuntime,\n },\n WorkingDir: cfg.container?.workdir,\n Env: Object.keys(mergedEnv).length > 0\n ? Object.entries(mergedEnv).map(([k, v]) => `${k}=${v}`)\n : undefined,\n Cmd: KEEPALIVE_CMD,\n HostConfig: {\n AutoRemove: cfg.container?.autoRemove ?? false,\n Binds: cfg.container?.binds,\n NetworkMode: cfg.container?.networkMode,\n Privileged: cfg.container?.privileged,\n CapAdd: cfg.container?.capabilities?.add,\n CapDrop: cfg.container?.capabilities?.drop,\n LogConfig: cfg.container?.logDriver\n ? { Type: cfg.container.logDriver, Config: cfg.container.logOpts || {} }\n : undefined,\n Resources: cfg.container?.resources,\n DeviceRequests: cfg.container?.gpus ? [{\n Driver: 'nvidia',\n Count: cfg.container.gpus === 'all' ? -1 : typeof cfg.container.gpus === 'number' ? cfg.container.gpus : 1,\n DeviceIDs: typeof cfg.container.gpus === 'string' && cfg.container.gpus !== 'all' ? [String(cfg.container.gpus)] : undefined,\n Capabilities: [['gpu']],\n }] : undefined,\n ...(hb ? { PortBindings: hb.PortBindings } : {}),\n },\n ...(hb ? { ExposedPorts: hb.ExposedPorts } : {}),\n ...(cfg.createOptions || {}),\n } as import('dockerode').ContainerCreateOptions;\n\n const container = await docker.createContainer(createOptions);\n await container.start(cfg.startOptions || {});\n await waitUntilRunning(container);\n const inspect = await container.inspect();\n const handle: DockerSandboxHandle = {\n docker, container, containerId: inspect.Id,\n image: inspect.Config?.Image ?? chosenImage.name,\n createdAt: new Date(inspect.Created || Date.now()),\n };\n return { instance: handle, instanceId: handle.containerId };\n },\n\n getById: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const container = docker.getContainer(sandboxId);\n const info = await container.inspect();\n return { instance: { docker, container, containerId: sandboxId, image: info.Config?.Image ?? '', createdAt: new Date(info.Created || Date.now()) } as DockerSandboxHandle, instanceId: sandboxId };\n } catch { return null; }\n },\n\n list: async (config: DockerConfig) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const items = await docker.listContainers({ all: true, filters: { label: [LABEL_KEY] } as any });\n return items.map(ci => ({\n instance: { docker, container: docker.getContainer(ci.Id), containerId: ci.Id, image: ci.Image, createdAt: new Date((ci as any).Created * 1000) } as DockerSandboxHandle, instanceId: ci.Id,\n }));\n } catch { return []; }\n },\n\n destroy: async (config: DockerConfig, sandboxId: string) => {\n const docker = new Docker((config || defaultDockerConfig).connection as any);\n try {\n const c = docker.getContainer(sandboxId);\n try { await c.stop({ t: 5 } as any); } catch { /* stopped */ }\n await c.remove({ force: true });\n } catch { /* ok if already gone */ }\n },\n\n runCommand: async (handle: DockerSandboxHandle, command: string, _options?: RunCommandOptions): Promise<CommandResult> => {\n const start = Date.now();\n const { stdout, stderr, exitCode } = await runExec(handle, command);\n return { stdout, stderr, exitCode, durationMs: Date.now() - start };\n },\n\n getInfo: async (handle: DockerSandboxHandle): Promise<InstanceInfo> => {\n const info = await handle.container.inspect();\n const state = info.State || {};\n return {\n id: handle.containerId,\n provider: PROVIDER,\n status: state.Running ? 'running' : 'stopped',\n createdAt: new Date(info.Created || handle.createdAt),\n timeout: 300000,\n metadata: {\n image: info.Config?.Image,\n name: info.Name,\n runtime: info.Config?.Labels?.[LABEL_RUNTIME],\n },\n };\n },\n\n getUrl: async (handle: DockerSandboxHandle, options: { port: number; protocol?: string }): Promise<string> => {\n const info = await handle.container.inspect();\n const protocol = options.protocol || 'http';\n const portKeyTcp = `${options.port}/tcp`;\n const ports = info.NetworkSettings?.Ports || {};\n const bindings = ports[portKeyTcp] || ports[`${options.port}/udp`] || [];\n let host = dockerHostNameFromEnv();\n let hostPort = String(options.port);\n if (Array.isArray(bindings) && bindings.length > 0) {\n hostPort = bindings[0].HostPort || hostPort;\n } else {\n const ip = info.NetworkSettings?.IPAddress || Object.values(info.NetworkSettings?.Networks || {})[0]?.IPAddress;\n if (ip) host = ip;\n }\n return `${protocol}://${host}:${hostPort}`;\n },\n\n filesystem: {\n readFile: async (handle: DockerSandboxHandle, path: string): Promise<string> => {\n const cmd = `if [ -f ${JSON.stringify(path)} ]; then base64 ${JSON.stringify(path)} | tr -d '\\\\n'; else exit 1; fi`;\n const { stdout, exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `File not found: ${path}`);\n return Buffer.from(stdout, 'base64').toString('utf8');\n },\n writeFile: async (handle: DockerSandboxHandle, path: string, content: string): Promise<void> => {\n const b64 = Buffer.from(content, 'utf8').toString('base64');\n const cmd = `mkdir -p $(dirname ${JSON.stringify(path)}) && echo \"${b64}\" | base64 -d > ${JSON.stringify(path)}`;\n const { exitCode, stderr } = await runExec(handle, cmd);\n if (exitCode !== 0) throw new Error(stderr || `Failed to write: ${path}`);\n },\n mkdir: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `mkdir -p ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to mkdir: ${path}`);\n },\n readdir: async (handle: DockerSandboxHandle, path: string): Promise<FileEntry[]> => {\n const { stdout, exitCode, stderr } = await runExec(handle, `if [ -d ${JSON.stringify(path)} ]; then ls -la ${JSON.stringify(path)}; else exit 1; fi`);\n if (exitCode !== 0) throw new Error(stderr || `Not a directory: ${path}`);\n const lines = stdout.split('\\n').slice(1);\n const entries: FileEntry[] = [];\n for (const line of lines) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const name = parts.slice(8).join(' ');\n if (name === '.' || name === '..') continue;\n entries.push({ name, type: parts[0].startsWith('d') ? 'directory' as const : 'file' as const, size: Number(parts[4]) || 0, modified: new Date() });\n }\n return entries;\n },\n exists: async (handle: DockerSandboxHandle, path: string): Promise<boolean> => {\n const { exitCode } = await runExec(handle, `test -e ${JSON.stringify(path)}`);\n return exitCode === 0;\n },\n remove: async (handle: DockerSandboxHandle, path: string): Promise<void> => {\n const { exitCode, stderr } = await runExec(handle, `rm -rf ${JSON.stringify(path)}`);\n if (exitCode !== 0) throw new Error(stderr || `Failed to remove: ${path}`);\n },\n },\n\n getInstance: (handle: DockerSandboxHandle): DockerSandboxHandle => handle,\n },\n },\n});\n","import type Docker from 'dockerode';\nimport type {\n DockerOptions,\n Container,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n Exec,\n ImageInfo,\n ImageBuildOptions,\n Network,\n} from 'dockerode';\n\nimport type {\n FileEntry,\n RunCommandOptions,\n CreateInstanceOptions,\n InstanceInfo,\n} from 'computesdk';\n\n/** When the provider should clean up containers it created */\nexport type CleanupPolicy = 'always' | 'onSuccess' | 'never';\n\n/** Image pull strategy */\nexport type PullPolicy = 'always' | 'ifNotPresent' | 'never';\n\n/** Connection to the Docker daemon (exactly what dockerode accepts) */\nexport type DockerConnection = DockerOptions;\n\n/** Auth when pulling private images (Engine API AuthConfig shape) */\nexport interface RegistryAuth {\n username?: string;\n password?: string;\n serveraddress?: string;\n identitytoken?: string;\n registrytoken?: string;\n}\n\n/** Default image & pull policy for sandboxes */\nexport interface DockerImage {\n name: string; // e.g. 'python:3.11-slim'\n pullPolicy?: PullPolicy; // default: 'ifNotPresent'\n auth?: RegistryAuth;\n}\n\n/** Convenience shape for port bindings */\nexport type PortBindings = Record<\n `${number}/${'tcp' | 'udp'}`,\n Array<{ hostPort?: number; hostIP?: string }>\n>;\n\n/** Subset of HostConfig resources & knobs that are commonly used */\nexport interface ResourceLimits {\n cpuShares?: number;\n cpuQuota?: number;\n cpuPeriod?: number;\n nanoCPUs?: number;\n memory?: number;\n memorySwap?: number;\n pidsLimit?: number;\n}\n\n/** Declarative container defaults that we'll translate into dockerode create options */\nexport interface ContainerDefaults {\n user?: string;\n workdir?: string;\n env?: Record<string, string>;\n binds?: string[];\n ports?: PortBindings;\n networkMode?: string;\n privileged?: boolean;\n capabilities?: { add?: string[]; drop?: string[] };\n gpus?: 'all' | number | string;\n resources?: ResourceLimits;\n logDriver?: string;\n logOpts?: Record<string, string>;\n autoRemove?: boolean;\n tty?: boolean;\n openStdin?: boolean;\n}\n\n/** Provider-level configuration for Docker */\nexport interface DockerConfig {\n connection?: DockerConnection;\n /** Default image runtime identifier, e.g. 'python' or 'node' */\n runtime?: string;\n timeout?: number;\n image: DockerImage;\n container?: ContainerDefaults;\n createOptions?: ContainerCreateOptions;\n startOptions?: ContainerStartOptions;\n cleanup?: CleanupPolicy;\n streamLogs?: boolean;\n}\n\n/** What we keep for each running sandbox */\nexport interface DockerSandboxHandle {\n docker: Docker;\n container: Container;\n containerId: string;\n image: string;\n createdAt: Date;\n}\n\n/** URL options for port-forwarded services */\nexport interface DockerUrlOptions {\n port: number;\n protocol?: 'http' | 'https';\n host?: string;\n}\n\n/** Optional FS helpers you might expose */\nexport interface DockerSandboxFileSystem {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n mkdir(path: string): Promise<void>;\n readdir(path: string): Promise<FileEntry[]>;\n exists(path: string): Promise<boolean>;\n remove(path: string): Promise<void>;\n}\n\n/** Sensible, safe defaults */\nexport const defaultDockerConfig: DockerConfig = {\n connection: {\n // Let dockerode fall back to DOCKER_HOST or /var/run/docker.sock\n timeout: 60_000,\n version: 'v1.43',\n },\n runtime: 'python',\n timeout: 300_000, // 5 minutes\n image: {\n name: 'python:3.11-slim',\n pullPolicy: 'ifNotPresent',\n },\n container: {\n workdir: '/workspace',\n env: {},\n autoRemove: false, // Keep container around for exec/FS/background\n tty: false, // Non-tty so we can demux stdout/stderr\n openStdin: false,\n resources: { memory: 512 * 1024 * 1024 },\n },\n cleanup: 'always',\n streamLogs: false,\n};\n\n/** Re-exports for convenience */\nexport type {\n Docker,\n Container,\n Exec,\n ContainerCreateOptions,\n ContainerStartOptions,\n ContainerInspectInfo,\n ContainerInfo,\n ImageInfo,\n ImageBuildOptions,\n Network,\n};\n"],"mappings":";AAAA,OAAO,YAAY;AACnB,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;;;ACyHxB,IAAM,sBAAoC;AAAA,EAC/C,YAAY;AAAA;AAAA,IAEV,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAAA,EACA,SAAS;AAAA,EACT,SAAS;AAAA;AAAA,EACT,OAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,EACd;AAAA,EACA,WAAW;AAAA,IACT,SAAS;AAAA,IACT,KAAK,CAAC;AAAA,IACN,YAAY;AAAA;AAAA,IACZ,KAAK;AAAA;AAAA,IACL,WAAW;AAAA,IACX,WAAW,EAAE,QAAQ,MAAM,OAAO,KAAK;AAAA,EACzC;AAAA,EACA,SAAS;AAAA,EACT,YAAY;AACd;;;AD9HA,IAAM,WAAW;AACjB,IAAM,YAAY;AAClB,IAAM,gBAAgB;AACtB,IAAM,gBAAgB,CAAC,WAAW,MAAM,8BAA8B;AAEtE,SAAS,KAAQ,KAAoB,UAAgB;AACnD,SAAO,OAAO,QAAQ,cAAc,WAAW;AACjD;AAEA,eAAe,YAAYA,SAAgB,OAAmC;AAC5E,QAAM,SAAS,MAAM,cAAc;AACnC,MAAI,WAAW,QAAS;AACxB,QAAM,SAAS,MAAMA,QAAO,WAAW;AACvC,QAAM,WAAW,OAAO,KAAK,UAAQ,IAAI,YAAY,CAAC,GAAG,SAAS,MAAM,IAAI,CAAC;AAC7E,MAAI,WAAW,YAAa,WAAW,kBAAkB,CAAC,UAAW;AACnE,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,YAAM,KAAK,CAAC,KAAU,WAAmC;AACvD,YAAI,IAAK,QAAO,OAAO,GAAG;AAC1B,YAAI,CAAC,OAAQ,QAAO,OAAO,IAAI,MAAM,gCAAgC,CAAC;AACtE,QAACA,QAAe,MAAM,eAAe,QAAQ,CAAC,SAAe,OAAO,OAAO,IAAI,IAAI,QAAQ,CAAE;AAAA,MAC/F;AACA,UAAI,MAAM,KAAM,CAAAA,QAAO,KAAK,MAAM,MAAM,EAAE,YAAY,MAAM,KAAK,GAAU,EAAE;AAAA,UACxE,CAAAA,QAAO,KAAK,MAAM,MAAM,EAAE;AAAA,IACjC,CAAC;AAAA,EACH;AACF;AAEA,eAAe,iBAAiB,WAA6B,YAAY,KAAM;AAC7E,QAAM,QAAQ,KAAK,IAAI;AACvB,MAAI;AACF,UAAM,IAAI,MAAM,UAAU,QAAQ;AAClC,QAAI,EAAE,OAAO,QAAS;AAAA,EACxB,QAAQ;AAAA,EAAe;AACvB,SAAO,KAAK,IAAI,IAAI,QAAQ,WAAW;AACrC,UAAM,IAAI,MAAM,UAAU,QAAQ;AAClC,QAAI,EAAE,OAAO,QAAS;AACtB,UAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,GAAG,CAAC;AAAA,EAC3C;AACA,QAAM,IAAI,MAAM,+CAA+C;AACjE;AAEA,eAAe,QACb,QACA,cACA,YAAY,OACmD;AAC/D,QAAM,iBAAiB,OAAO,SAAS;AACvC,QAAM,OAAO,MAAM,OAAO,UAAU,KAAK;AAAA,IACvC,KAAK,CAAC,WAAW,MAAM,YAAY;AAAA,IACnC,cAAc;AAAA,IACd,cAAc;AAAA,IACd,KAAK;AAAA,EACP,CAAC;AACD,QAAM,SAAU,MAAM,KAAK,MAAM,EAAE,QAAQ,MAAM,OAAO,MAAM,CAAC;AAC/D,MAAI,SAAS;AACb,MAAI,SAAS;AACb,QAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,QAAI,WAAW;AACb,aAAO,GAAG,QAAQ,CAAC,UAAmB,UAAU,MAAM,SAAS,MAAM,CAAE;AACvE,aAAO,GAAG,OAAO,OAAO;AACxB,aAAO,GAAG,SAAS,MAAM;AACzB;AAAA,IACF;AACA,UAAM,MAAM,IAAI,YAAY;AAC5B,UAAM,MAAM,IAAI,YAAY;AAC5B,QAAI,GAAG,QAAQ,CAAC,MAAe,UAAU,EAAE,SAAS,MAAM,CAAE;AAC5D,QAAI,GAAG,QAAQ,CAAC,MAAe,UAAU,EAAE,SAAS,MAAM,CAAE;AAC5D,IAAC,OAAO,OAAe,MAAM,YAAY,QAAe,KAAY,GAAU;AAC9E,WAAO,GAAG,OAAO,OAAO;AACxB,WAAO,GAAG,SAAS,MAAM;AAAA,EAC3B,CAAC;AACD,QAAM,UAAU,MAAM,KAAK,QAAQ;AACnC,SAAO,EAAE,QAAQ,QAAQ,UAAU,QAAQ,YAAY,EAAE;AAC3D;AAEA,SAAS,eAAe,OAAsB;AAC5C,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,UAA8B,CAAC;AACrC,QAAM,WAA0E,CAAC;AACjF,aAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AACpC,YAAQ,GAAG,IAAI,CAAC;AAChB,aAAS,GAAG,IAAK,MAAc,GAAG,EAAE,IAAI,CAAC,OAAY,EAAE,UAAU,EAAE,WAAW,OAAO,EAAE,QAAQ,IAAI,QAAW,QAAQ,EAAE,OAAO,EAAE;AAAA,EACnI;AACA,SAAO,EAAE,cAAc,SAAS,cAAc,SAAS;AACzD;AAEA,SAAS,wBAAgC;AACvC,QAAM,UAAU,QAAQ,IAAI;AAC5B,MAAI,SAAS,WAAW,QAAQ,GAAG;AACjC,QAAI;AAAE,aAAO,IAAI,IAAI,OAAO,EAAE,YAAY;AAAA,IAAa,QAAQ;AAAA,IAAa;AAAA,EAC9E;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,SAAiB,YAAuC;AACnF,MAAI,YAAY,MAAM;AACpB,QAAI,YAAY,YAAY,qBAAqB,KAAK,WAAW,IAAI,EAAG,QAAO;AAC/E,QAAI,YAAY,UAAU,QAAQ,KAAK,WAAW,IAAI,EAAG,QAAO;AAAA,EAClE;AACA,SAAO;AAAA,IACL,MAAM,YAAY,WAAW,qBAAqB;AAAA,IAClD,YAAY,YAAY,cAAc;AAAA,IACtC,MAAM,YAAY;AAAA,EACpB;AACF;AAEO,IAAM,SAAS,eAAkD;AAAA,EACtE,MAAM;AAAA,EACN,SAAS;AAAA,IACP,WAAW;AAAA,MACT,QAAQ,OAAO,QAAsB,YAAoC;AACvE,cAAM,MAAoB,EAAE,GAAG,qBAAqB,GAAG,OAAO;AAC9D,cAAM,mBAA6B,SAAiB,WAAW,IAAI,WAAW;AAE9E,YAAI,qBAAqB,YAAY,qBAAqB,QAAQ;AAChE,gBAAM,IAAI,MAAM,+DAA+D,OAAO,gBAAgB,CAAC,EAAE;AAAA,QAC3G;AAEA,cAAMA,UAAS,IAAI,OAAO,IAAI,UAAiB;AAC/C,cAAM,cAAc,oBAAoB,kBAAkB,IAAI,KAAK;AACnE,cAAM,YAAYA,SAAQ,WAAW;AAErC,cAAM,YAAY,EAAE,GAAG,IAAI,WAAW,KAAK,GAAG,SAAS,KAAK;AAC5D,cAAM,KAAK,eAAe,IAAI,WAAW,KAAK;AAC9C,cAAM,gBAAgB;AAAA,UACpB,OAAO,YAAY;AAAA,UACnB,KAAK,KAAK,IAAI,WAAW,KAAK,KAAK;AAAA,UACnC,WAAW,KAAK,IAAI,WAAW,WAAW,KAAK;AAAA,UAC/C,QAAQ;AAAA,YACN,GAAI,SAAS,WAAW,OAAO;AAAA,cAC7B,OAAO,QAAQ,QAAQ,QAAQ,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,uBAAuB,CAAC,IAAI,OAAO,MAAM,WAAW,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC;AAAA,YAC9H,IAAI,CAAC;AAAA,YACL,CAAC,SAAS,GAAG;AAAA,YACb,CAAC,aAAa,GAAG;AAAA,UACnB;AAAA,UACA,YAAY,IAAI,WAAW;AAAA,UAC3B,KAAK,OAAO,KAAK,SAAS,EAAE,SAAS,IACjC,OAAO,QAAQ,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,IACrD;AAAA,UACJ,KAAK;AAAA,UACL,YAAY;AAAA,YACV,YAAY,IAAI,WAAW,cAAc;AAAA,YACzC,OAAO,IAAI,WAAW;AAAA,YACtB,aAAa,IAAI,WAAW;AAAA,YAC5B,YAAY,IAAI,WAAW;AAAA,YAC3B,QAAQ,IAAI,WAAW,cAAc;AAAA,YACrC,SAAS,IAAI,WAAW,cAAc;AAAA,YACtC,WAAW,IAAI,WAAW,YACtB,EAAE,MAAM,IAAI,UAAU,WAAW,QAAQ,IAAI,UAAU,WAAW,CAAC,EAAE,IACrE;AAAA,YACJ,WAAW,IAAI,WAAW;AAAA,YAC1B,gBAAgB,IAAI,WAAW,OAAO,CAAC;AAAA,cACrC,QAAQ;AAAA,cACR,OAAO,IAAI,UAAU,SAAS,QAAQ,KAAK,OAAO,IAAI,UAAU,SAAS,WAAW,IAAI,UAAU,OAAO;AAAA,cACzG,WAAW,OAAO,IAAI,UAAU,SAAS,YAAY,IAAI,UAAU,SAAS,QAAQ,CAAC,OAAO,IAAI,UAAU,IAAI,CAAC,IAAI;AAAA,cACnH,cAAc,CAAC,CAAC,KAAK,CAAC;AAAA,YACxB,CAAC,IAAI;AAAA,YACL,GAAI,KAAK,EAAE,cAAc,GAAG,aAAa,IAAI,CAAC;AAAA,UAChD;AAAA,UACA,GAAI,KAAK,EAAE,cAAc,GAAG,aAAa,IAAI,CAAC;AAAA,UAC9C,GAAI,IAAI,iBAAiB,CAAC;AAAA,QAC5B;AAEA,cAAM,YAAY,MAAMA,QAAO,gBAAgB,aAAa;AAC5D,cAAM,UAAU,MAAM,IAAI,gBAAgB,CAAC,CAAC;AAC5C,cAAM,iBAAiB,SAAS;AAChC,cAAM,UAAU,MAAM,UAAU,QAAQ;AACxC,cAAM,SAA8B;AAAA,UAClC,QAAAA;AAAA,UAAQ;AAAA,UAAW,aAAa,QAAQ;AAAA,UACxC,OAAO,QAAQ,QAAQ,SAAS,YAAY;AAAA,UAC5C,WAAW,IAAI,KAAK,QAAQ,WAAW,KAAK,IAAI,CAAC;AAAA,QACnD;AACA,eAAO,EAAE,UAAU,QAAQ,YAAY,OAAO,YAAY;AAAA,MAC5D;AAAA,MAEA,SAAS,OAAO,QAAsB,cAAsB;AAC1D,cAAMA,UAAS,IAAI,QAAQ,UAAU,qBAAqB,UAAiB;AAC3E,YAAI;AACF,gBAAM,YAAYA,QAAO,aAAa,SAAS;AAC/C,gBAAM,OAAO,MAAM,UAAU,QAAQ;AACrC,iBAAO,EAAE,UAAU,EAAE,QAAAA,SAAQ,WAAW,aAAa,WAAW,OAAO,KAAK,QAAQ,SAAS,IAAI,WAAW,IAAI,KAAK,KAAK,WAAW,KAAK,IAAI,CAAC,EAAE,GAA0B,YAAY,UAAU;AAAA,QACnM,QAAQ;AAAE,iBAAO;AAAA,QAAM;AAAA,MACzB;AAAA,MAEA,MAAM,OAAO,WAAyB;AACpC,cAAMA,UAAS,IAAI,QAAQ,UAAU,qBAAqB,UAAiB;AAC3E,YAAI;AACF,gBAAM,QAAQ,MAAMA,QAAO,eAAe,EAAE,KAAK,MAAM,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,EAAS,CAAC;AAC/F,iBAAO,MAAM,IAAI,SAAO;AAAA,YACtB,UAAU,EAAE,QAAAA,SAAQ,WAAWA,QAAO,aAAa,GAAG,EAAE,GAAG,aAAa,GAAG,IAAI,OAAO,GAAG,OAAO,WAAW,IAAI,KAAM,GAAW,UAAU,GAAI,EAAE;AAAA,YAA0B,YAAY,GAAG;AAAA,UAC3L,EAAE;AAAA,QACJ,QAAQ;AAAE,iBAAO,CAAC;AAAA,QAAG;AAAA,MACvB;AAAA,MAEA,SAAS,OAAO,QAAsB,cAAsB;AAC1D,cAAMA,UAAS,IAAI,QAAQ,UAAU,qBAAqB,UAAiB;AAC3E,YAAI;AACF,gBAAM,IAAIA,QAAO,aAAa,SAAS;AACvC,cAAI;AAAE,kBAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAQ;AAAA,UAAG,QAAQ;AAAA,UAAgB;AAC7D,gBAAM,EAAE,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,QAChC,QAAQ;AAAA,QAA2B;AAAA,MACrC;AAAA,MAEA,YAAY,OAAO,QAA6B,SAAiB,aAAyD;AACxH,cAAM,QAAQ,KAAK,IAAI;AACvB,cAAM,EAAE,QAAQ,QAAQ,SAAS,IAAI,MAAM,QAAQ,QAAQ,OAAO;AAClE,eAAO,EAAE,QAAQ,QAAQ,UAAU,YAAY,KAAK,IAAI,IAAI,MAAM;AAAA,MACpE;AAAA,MAEA,SAAS,OAAO,WAAuD;AACrE,cAAM,OAAO,MAAM,OAAO,UAAU,QAAQ;AAC5C,cAAM,QAAQ,KAAK,SAAS,CAAC;AAC7B,eAAO;AAAA,UACL,IAAI,OAAO;AAAA,UACX,UAAU;AAAA,UACV,QAAQ,MAAM,UAAU,YAAY;AAAA,UACpC,WAAW,IAAI,KAAK,KAAK,WAAW,OAAO,SAAS;AAAA,UACpD,SAAS;AAAA,UACT,UAAU;AAAA,YACR,OAAO,KAAK,QAAQ;AAAA,YACpB,MAAM,KAAK;AAAA,YACX,SAAS,KAAK,QAAQ,SAAS,aAAa;AAAA,UAC9C;AAAA,QACF;AAAA,MACF;AAAA,MAEA,QAAQ,OAAO,QAA6B,YAAkE;AAC5G,cAAM,OAAO,MAAM,OAAO,UAAU,QAAQ;AAC5C,cAAM,WAAW,QAAQ,YAAY;AACrC,cAAM,aAAa,GAAG,QAAQ,IAAI;AAClC,cAAM,QAAQ,KAAK,iBAAiB,SAAS,CAAC;AAC9C,cAAM,WAAW,MAAM,UAAU,KAAK,MAAM,GAAG,QAAQ,IAAI,MAAM,KAAK,CAAC;AACvE,YAAI,OAAO,sBAAsB;AACjC,YAAI,WAAW,OAAO,QAAQ,IAAI;AAClC,YAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,GAAG;AAClD,qBAAW,SAAS,CAAC,EAAE,YAAY;AAAA,QACrC,OAAO;AACL,gBAAM,KAAK,KAAK,iBAAiB,aAAa,OAAO,OAAO,KAAK,iBAAiB,YAAY,CAAC,CAAC,EAAE,CAAC,GAAG;AACtG,cAAI,GAAI,QAAO;AAAA,QACjB;AACA,eAAO,GAAG,QAAQ,MAAM,IAAI,IAAI,QAAQ;AAAA,MAC1C;AAAA,MAEA,YAAY;AAAA,QACV,UAAU,OAAO,QAA6B,SAAkC;AAC9E,gBAAM,MAAM,WAAW,KAAK,UAAU,IAAI,CAAC,mBAAmB,KAAK,UAAU,IAAI,CAAC;AAClF,gBAAM,EAAE,QAAQ,UAAU,OAAO,IAAI,MAAM,QAAQ,QAAQ,GAAG;AAC9D,cAAI,aAAa,EAAG,OAAM,IAAI,MAAM,UAAU,mBAAmB,IAAI,EAAE;AACvE,iBAAO,OAAO,KAAK,QAAQ,QAAQ,EAAE,SAAS,MAAM;AAAA,QACtD;AAAA,QACA,WAAW,OAAO,QAA6B,MAAc,YAAmC;AAC9F,gBAAM,MAAM,OAAO,KAAK,SAAS,MAAM,EAAE,SAAS,QAAQ;AAC1D,gBAAM,MAAM,sBAAsB,KAAK,UAAU,IAAI,CAAC,cAAc,GAAG,mBAAmB,KAAK,UAAU,IAAI,CAAC;AAC9G,gBAAM,EAAE,UAAU,OAAO,IAAI,MAAM,QAAQ,QAAQ,GAAG;AACtD,cAAI,aAAa,EAAG,OAAM,IAAI,MAAM,UAAU,oBAAoB,IAAI,EAAE;AAAA,QAC1E;AAAA,QACA,OAAO,OAAO,QAA6B,SAAgC;AACzE,gBAAM,EAAE,UAAU,OAAO,IAAI,MAAM,QAAQ,QAAQ,YAAY,KAAK,UAAU,IAAI,CAAC,EAAE;AACrF,cAAI,aAAa,EAAG,OAAM,IAAI,MAAM,UAAU,oBAAoB,IAAI,EAAE;AAAA,QAC1E;AAAA,QACA,SAAS,OAAO,QAA6B,SAAuC;AAClF,gBAAM,EAAE,QAAQ,UAAU,OAAO,IAAI,MAAM,QAAQ,QAAQ,WAAW,KAAK,UAAU,IAAI,CAAC,mBAAmB,KAAK,UAAU,IAAI,CAAC,mBAAmB;AACpJ,cAAI,aAAa,EAAG,OAAM,IAAI,MAAM,UAAU,oBAAoB,IAAI,EAAE;AACxE,gBAAM,QAAQ,OAAO,MAAM,IAAI,EAAE,MAAM,CAAC;AACxC,gBAAM,UAAuB,CAAC;AAC9B,qBAAW,QAAQ,OAAO;AACxB,kBAAM,QAAQ,KAAK,KAAK,EAAE,MAAM,KAAK;AACrC,gBAAI,MAAM,SAAS,EAAG;AACtB,kBAAM,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AACpC,gBAAI,SAAS,OAAO,SAAS,KAAM;AACnC,oBAAQ,KAAK,EAAE,MAAM,MAAM,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,cAAuB,QAAiB,MAAM,OAAO,MAAM,CAAC,CAAC,KAAK,GAAG,UAAU,oBAAI,KAAK,EAAE,CAAC;AAAA,UACnJ;AACA,iBAAO;AAAA,QACT;AAAA,QACA,QAAQ,OAAO,QAA6B,SAAmC;AAC7E,gBAAM,EAAE,SAAS,IAAI,MAAM,QAAQ,QAAQ,WAAW,KAAK,UAAU,IAAI,CAAC,EAAE;AAC5E,iBAAO,aAAa;AAAA,QACtB;AAAA,QACA,QAAQ,OAAO,QAA6B,SAAgC;AAC1E,gBAAM,EAAE,UAAU,OAAO,IAAI,MAAM,QAAQ,QAAQ,UAAU,KAAK,UAAU,IAAI,CAAC,EAAE;AACnF,cAAI,aAAa,EAAG,OAAM,IAAI,MAAM,UAAU,qBAAqB,IAAI,EAAE;AAAA,QAC3E;AAAA,MACF;AAAA,MAEA,aAAa,CAAC,WAAqD;AAAA,IACrE;AAAA,EACF;AACF,CAAC;","names":["docker"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computesdk/docker",
3
- "version": "1.2.57",
3
+ "version": "1.2.59",
4
4
  "description": "Docker provider for ComputeSDK - local containerized sandboxes for development and testing",
5
5
  "author": "IberAI",
6
6
  "license": "MIT",
@@ -19,8 +19,8 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "dockerode": "^4.0.8",
22
- "@computesdk/provider": "2.1.11",
23
- "computesdk": "4.1.10"
22
+ "@computesdk/provider": "2.1.13",
23
+ "computesdk": "4.1.11"
24
24
  },
25
25
  "keywords": [
26
26
  "computesdk",
@@ -53,7 +53,7 @@
53
53
  "tsup": "^8.0.0",
54
54
  "typescript": "^5.0.0",
55
55
  "vitest": "^1.0.0",
56
- "@computesdk/test-utils": "2.0.3"
56
+ "@computesdk/test-utils": "2.0.4"
57
57
  },
58
58
  "scripts": {
59
59
  "build": "tsup",