From 4276a298b6163feaaccdd67490d46caec4a29e76 Mon Sep 17 00:00:00 2001 From: Casey Brooks Date: Sat, 21 Feb 2026 17:24:30 +0000 Subject: [PATCH 1/4] fix(docker-runner): migrate package to esm --- packages/docker-runner/package.json | 10 ++++++++- packages/docker-runner/src/contracts/api.ts | 2 +- packages/docker-runner/src/contracts/auth.ts | 2 +- packages/docker-runner/src/index.ts | 22 +++++++++---------- .../docker-runner/src/lib/container.handle.ts | 4 ++-- .../src/lib/container.service.ts | 14 ++++++------ .../src/lib/containerRegistry.port.ts | 2 +- .../src/lib/dockerClient.port.ts | 4 ++-- packages/docker-runner/src/service/app.ts | 6 ++--- packages/docker-runner/src/service/env.ts | 3 ++- packages/docker-runner/src/service/main.ts | 6 ++--- packages/docker-runner/tsconfig.json | 6 +++-- 12 files changed, 46 insertions(+), 35 deletions(-) diff --git a/packages/docker-runner/package.json b/packages/docker-runner/package.json index f2c1fdac3..2e3f5accb 100644 --- a/packages/docker-runner/package.json +++ b/packages/docker-runner/package.json @@ -2,7 +2,15 @@ "name": "@agyn/docker-runner", "version": "1.0.0", "private": true, - "main": "src/index.ts", + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, "scripts": { "dev": "tsx src/service/main.ts", "build": "tsc -p tsconfig.json", diff --git a/packages/docker-runner/src/contracts/api.ts b/packages/docker-runner/src/contracts/api.ts index 42eeef9e9..cb975ebcb 100644 --- a/packages/docker-runner/src/contracts/api.ts +++ b/packages/docker-runner/src/contracts/api.ts @@ -1,5 +1,5 @@ import type Docker from 'dockerode'; -import type { ContainerOpts, ExecOptions, ExecResult, Platform } from '../lib/types'; +import type { ContainerOpts, ExecOptions, ExecResult, Platform } from '../lib/types.js'; export type ErrorPayload = { error: { diff --git a/packages/docker-runner/src/contracts/auth.ts b/packages/docker-runner/src/contracts/auth.ts index 8dbebc5e0..e6d61518a 100644 --- a/packages/docker-runner/src/contracts/auth.ts +++ b/packages/docker-runner/src/contracts/auth.ts @@ -1,5 +1,5 @@ import crypto from 'node:crypto'; -import { canonicalJsonStringify } from './json'; +import { canonicalJsonStringify } from './json.js'; export type SignatureHeaders = { timestamp: string; diff --git a/packages/docker-runner/src/index.ts b/packages/docker-runner/src/index.ts index 44a37adc5..d4e53ec20 100644 --- a/packages/docker-runner/src/index.ts +++ b/packages/docker-runner/src/index.ts @@ -1,11 +1,11 @@ -export * from './lib/container.service'; -export * from './lib/container.handle'; -export * from './lib/container.mounts'; -export * from './lib/containerStream.util'; -export * from './lib/containerRegistry.port'; -export * from './lib/dockerClient.port'; -export * from './lib/execTimeout'; -export * from './lib/types'; -export * from './contracts/auth'; -export * from './contracts/json'; -export * from './contracts/api'; +export * from './lib/container.service.js'; +export * from './lib/container.handle.js'; +export * from './lib/container.mounts.js'; +export * from './lib/containerStream.util.js'; +export * from './lib/containerRegistry.port.js'; +export * from './lib/dockerClient.port.js'; +export * from './lib/execTimeout.js'; +export * from './lib/types.js'; +export * from './contracts/auth.js'; +export * from './contracts/json.js'; +export * from './contracts/api.js'; diff --git a/packages/docker-runner/src/lib/container.handle.ts b/packages/docker-runner/src/lib/container.handle.ts index b0964b2fa..be21f7b2e 100644 --- a/packages/docker-runner/src/lib/container.handle.ts +++ b/packages/docker-runner/src/lib/container.handle.ts @@ -1,5 +1,5 @@ -import type { DockerClientPort } from './dockerClient.port'; -import type { ExecOptions } from './types'; +import type { DockerClientPort } from './dockerClient.port.js'; +import type { ExecOptions } from './types.js'; /** * Lightweight entity wrapper representing a running (or created) container. diff --git a/packages/docker-runner/src/lib/container.service.ts b/packages/docker-runner/src/lib/container.service.ts index d2682419d..cd42b47a5 100644 --- a/packages/docker-runner/src/lib/container.service.ts +++ b/packages/docker-runner/src/lib/container.service.ts @@ -1,12 +1,12 @@ import { Injectable, Logger } from '@nestjs/common'; import Docker, { ContainerCreateOptions, Exec, type GetEventsOptions } from 'dockerode'; import { PassThrough, Writable } from 'node:stream'; -import { ContainerHandle } from './container.handle'; -import { mapInspectMounts } from './container.mounts'; -import { createUtf8Collector, demuxDockerMultiplex } from './containerStream.util'; -import { ExecIdleTimeoutError, ExecTimeoutError, isExecIdleTimeoutError, isExecTimeoutError } from './execTimeout'; -import type { ContainerRegistryPort } from './containerRegistry.port'; -import type { DockerClientPort } from './dockerClient.port'; +import { ContainerHandle } from './container.handle.js'; +import { mapInspectMounts } from './container.mounts.js'; +import { createUtf8Collector, demuxDockerMultiplex } from './containerStream.util.js'; +import { ExecIdleTimeoutError, ExecTimeoutError, isExecIdleTimeoutError, isExecTimeoutError } from './execTimeout.js'; +import type { ContainerRegistryPort } from './containerRegistry.port.js'; +import type { DockerClientPort } from './dockerClient.port.js'; import { ContainerOpts, ExecOptions, @@ -17,7 +17,7 @@ import { LogsStreamSession, Platform, PLATFORM_LABEL, -} from './types'; +} from './types.js'; const INTERACTIVE_EXEC_CLOSE_CAPTURE_LIMIT = 256 * 1024; // 256 KiB of characters (~512 KiB memory) diff --git a/packages/docker-runner/src/lib/containerRegistry.port.ts b/packages/docker-runner/src/lib/containerRegistry.port.ts index a0490a7f9..0250c6adf 100644 --- a/packages/docker-runner/src/lib/containerRegistry.port.ts +++ b/packages/docker-runner/src/lib/containerRegistry.port.ts @@ -1,4 +1,4 @@ -import type { ContainerMount } from './container.mounts'; +import type { ContainerMount } from './container.mounts.js'; export type RegisterContainerStartInput = { containerId: string; diff --git a/packages/docker-runner/src/lib/dockerClient.port.ts b/packages/docker-runner/src/lib/dockerClient.port.ts index 66fd1be98..29d64978e 100644 --- a/packages/docker-runner/src/lib/dockerClient.port.ts +++ b/packages/docker-runner/src/lib/dockerClient.port.ts @@ -1,4 +1,4 @@ -import type { ContainerHandle } from './container.handle'; +import type { ContainerHandle } from './container.handle.js'; import type { ContainerOpts, ExecOptions, @@ -8,7 +8,7 @@ import type { LogsStreamOptions, LogsStreamSession, Platform, -} from './types'; +} from './types.js'; export type DockerEventFilters = Record>; diff --git a/packages/docker-runner/src/service/app.ts b/packages/docker-runner/src/service/app.ts index 209bb5dbd..c7cf66d91 100644 --- a/packages/docker-runner/src/service/app.ts +++ b/packages/docker-runner/src/service/app.ts @@ -11,9 +11,9 @@ import { type ContainerOpts, type ExecOptions, } from '..'; -import { createDockerEventsParser } from './dockerEvents.parser'; -import type { RunnerConfig } from './config'; -import { closeWebsocket, getWebsocket, type SocketStream } from './websocket.util'; +import { createDockerEventsParser } from './dockerEvents.parser.js'; +import type { RunnerConfig } from './config.js'; +import { closeWebsocket, getWebsocket, type SocketStream } from './websocket.util.js'; const ensureImageSchema = z.object({ image: z.string().min(1), diff --git a/packages/docker-runner/src/service/env.ts b/packages/docker-runner/src/service/env.ts index 517100d3c..c624585af 100644 --- a/packages/docker-runner/src/service/env.ts +++ b/packages/docker-runner/src/service/env.ts @@ -1,12 +1,13 @@ import fs from 'node:fs'; import path from 'node:path'; +import { fileURLToPath } from 'node:url'; import { config } from 'dotenv'; const isProduction = () => process.env.NODE_ENV?.toLowerCase() === 'production'; function resolveCandidatePaths(): string[] { - const moduleDir = __dirname; + const moduleDir = path.dirname(fileURLToPath(import.meta.url)); const repoEnv = path.resolve(process.cwd(), '.env'); const packageEnv = path.resolve(moduleDir, '../../.env'); return [repoEnv, packageEnv]; diff --git a/packages/docker-runner/src/service/main.ts b/packages/docker-runner/src/service/main.ts index 61be2f7f2..53926b912 100644 --- a/packages/docker-runner/src/service/main.ts +++ b/packages/docker-runner/src/service/main.ts @@ -1,7 +1,7 @@ -import './env'; +import './env.js'; -import { loadRunnerConfig } from './config'; -import { createRunnerApp } from './app'; +import { loadRunnerConfig } from './config.js'; +import { createRunnerApp } from './app.js'; async function bootstrap(): Promise { try { diff --git a/packages/docker-runner/tsconfig.json b/packages/docker-runner/tsconfig.json index 672bbef46..523994211 100644 --- a/packages/docker-runner/tsconfig.json +++ b/packages/docker-runner/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "module": "CommonJS", - "moduleResolution": "Node", + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", "rootDir": "src", "outDir": "dist", + "declaration": true, "tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo", "composite": true, "types": ["node"] From 1e66f1428792d2805eab8fa9f9e056003c91a3a0 Mon Sep 17 00:00:00 2001 From: Casey Brooks Date: Sat, 21 Feb 2026 17:45:12 +0000 Subject: [PATCH 2/4] fix(docker-runner): build types during install --- packages/docker-runner/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/docker-runner/package.json b/packages/docker-runner/package.json index 2e3f5accb..97d195398 100644 --- a/packages/docker-runner/package.json +++ b/packages/docker-runner/package.json @@ -16,7 +16,8 @@ "build": "tsc -p tsconfig.json", "start": "node dist/service/main.js", "lint": "eslint .", - "test": "vitest run" + "test": "vitest run", + "prepare": "pnpm run build" }, "dependencies": { "@fastify/websocket": "^11.2.0", From 33269a4a5f7f879954bd6cc73a418c66dc62b5fa Mon Sep 17 00:00:00 2001 From: Casey Brooks Date: Sat, 21 Feb 2026 18:17:03 +0000 Subject: [PATCH 3/4] fix(docker-runner): align esm packaging --- packages/docker-runner/package.json | 12 ++-------- packages/docker-runner/src/contracts/api.ts | 2 +- packages/docker-runner/src/contracts/auth.ts | 2 +- packages/docker-runner/src/index.ts | 22 +++++++++---------- .../docker-runner/src/lib/container.handle.ts | 4 ++-- .../src/lib/container.service.ts | 14 ++++++------ .../src/lib/containerRegistry.port.ts | 2 +- .../src/lib/dockerClient.port.ts | 4 ++-- packages/docker-runner/src/service/app.ts | 6 ++--- packages/docker-runner/src/service/main.ts | 6 ++--- 10 files changed, 33 insertions(+), 41 deletions(-) diff --git a/packages/docker-runner/package.json b/packages/docker-runner/package.json index 97d195398..941443a00 100644 --- a/packages/docker-runner/package.json +++ b/packages/docker-runner/package.json @@ -3,21 +3,13 @@ "version": "1.0.0", "private": true, "type": "module", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } - }, + "main": "src/index.ts", "scripts": { "dev": "tsx src/service/main.ts", "build": "tsc -p tsconfig.json", "start": "node dist/service/main.js", "lint": "eslint .", - "test": "vitest run", - "prepare": "pnpm run build" + "test": "vitest run" }, "dependencies": { "@fastify/websocket": "^11.2.0", diff --git a/packages/docker-runner/src/contracts/api.ts b/packages/docker-runner/src/contracts/api.ts index cb975ebcb..42eeef9e9 100644 --- a/packages/docker-runner/src/contracts/api.ts +++ b/packages/docker-runner/src/contracts/api.ts @@ -1,5 +1,5 @@ import type Docker from 'dockerode'; -import type { ContainerOpts, ExecOptions, ExecResult, Platform } from '../lib/types.js'; +import type { ContainerOpts, ExecOptions, ExecResult, Platform } from '../lib/types'; export type ErrorPayload = { error: { diff --git a/packages/docker-runner/src/contracts/auth.ts b/packages/docker-runner/src/contracts/auth.ts index e6d61518a..8dbebc5e0 100644 --- a/packages/docker-runner/src/contracts/auth.ts +++ b/packages/docker-runner/src/contracts/auth.ts @@ -1,5 +1,5 @@ import crypto from 'node:crypto'; -import { canonicalJsonStringify } from './json.js'; +import { canonicalJsonStringify } from './json'; export type SignatureHeaders = { timestamp: string; diff --git a/packages/docker-runner/src/index.ts b/packages/docker-runner/src/index.ts index d4e53ec20..44a37adc5 100644 --- a/packages/docker-runner/src/index.ts +++ b/packages/docker-runner/src/index.ts @@ -1,11 +1,11 @@ -export * from './lib/container.service.js'; -export * from './lib/container.handle.js'; -export * from './lib/container.mounts.js'; -export * from './lib/containerStream.util.js'; -export * from './lib/containerRegistry.port.js'; -export * from './lib/dockerClient.port.js'; -export * from './lib/execTimeout.js'; -export * from './lib/types.js'; -export * from './contracts/auth.js'; -export * from './contracts/json.js'; -export * from './contracts/api.js'; +export * from './lib/container.service'; +export * from './lib/container.handle'; +export * from './lib/container.mounts'; +export * from './lib/containerStream.util'; +export * from './lib/containerRegistry.port'; +export * from './lib/dockerClient.port'; +export * from './lib/execTimeout'; +export * from './lib/types'; +export * from './contracts/auth'; +export * from './contracts/json'; +export * from './contracts/api'; diff --git a/packages/docker-runner/src/lib/container.handle.ts b/packages/docker-runner/src/lib/container.handle.ts index be21f7b2e..b0964b2fa 100644 --- a/packages/docker-runner/src/lib/container.handle.ts +++ b/packages/docker-runner/src/lib/container.handle.ts @@ -1,5 +1,5 @@ -import type { DockerClientPort } from './dockerClient.port.js'; -import type { ExecOptions } from './types.js'; +import type { DockerClientPort } from './dockerClient.port'; +import type { ExecOptions } from './types'; /** * Lightweight entity wrapper representing a running (or created) container. diff --git a/packages/docker-runner/src/lib/container.service.ts b/packages/docker-runner/src/lib/container.service.ts index cd42b47a5..d2682419d 100644 --- a/packages/docker-runner/src/lib/container.service.ts +++ b/packages/docker-runner/src/lib/container.service.ts @@ -1,12 +1,12 @@ import { Injectable, Logger } from '@nestjs/common'; import Docker, { ContainerCreateOptions, Exec, type GetEventsOptions } from 'dockerode'; import { PassThrough, Writable } from 'node:stream'; -import { ContainerHandle } from './container.handle.js'; -import { mapInspectMounts } from './container.mounts.js'; -import { createUtf8Collector, demuxDockerMultiplex } from './containerStream.util.js'; -import { ExecIdleTimeoutError, ExecTimeoutError, isExecIdleTimeoutError, isExecTimeoutError } from './execTimeout.js'; -import type { ContainerRegistryPort } from './containerRegistry.port.js'; -import type { DockerClientPort } from './dockerClient.port.js'; +import { ContainerHandle } from './container.handle'; +import { mapInspectMounts } from './container.mounts'; +import { createUtf8Collector, demuxDockerMultiplex } from './containerStream.util'; +import { ExecIdleTimeoutError, ExecTimeoutError, isExecIdleTimeoutError, isExecTimeoutError } from './execTimeout'; +import type { ContainerRegistryPort } from './containerRegistry.port'; +import type { DockerClientPort } from './dockerClient.port'; import { ContainerOpts, ExecOptions, @@ -17,7 +17,7 @@ import { LogsStreamSession, Platform, PLATFORM_LABEL, -} from './types.js'; +} from './types'; const INTERACTIVE_EXEC_CLOSE_CAPTURE_LIMIT = 256 * 1024; // 256 KiB of characters (~512 KiB memory) diff --git a/packages/docker-runner/src/lib/containerRegistry.port.ts b/packages/docker-runner/src/lib/containerRegistry.port.ts index 0250c6adf..a0490a7f9 100644 --- a/packages/docker-runner/src/lib/containerRegistry.port.ts +++ b/packages/docker-runner/src/lib/containerRegistry.port.ts @@ -1,4 +1,4 @@ -import type { ContainerMount } from './container.mounts.js'; +import type { ContainerMount } from './container.mounts'; export type RegisterContainerStartInput = { containerId: string; diff --git a/packages/docker-runner/src/lib/dockerClient.port.ts b/packages/docker-runner/src/lib/dockerClient.port.ts index 29d64978e..66fd1be98 100644 --- a/packages/docker-runner/src/lib/dockerClient.port.ts +++ b/packages/docker-runner/src/lib/dockerClient.port.ts @@ -1,4 +1,4 @@ -import type { ContainerHandle } from './container.handle.js'; +import type { ContainerHandle } from './container.handle'; import type { ContainerOpts, ExecOptions, @@ -8,7 +8,7 @@ import type { LogsStreamOptions, LogsStreamSession, Platform, -} from './types.js'; +} from './types'; export type DockerEventFilters = Record>; diff --git a/packages/docker-runner/src/service/app.ts b/packages/docker-runner/src/service/app.ts index c7cf66d91..209bb5dbd 100644 --- a/packages/docker-runner/src/service/app.ts +++ b/packages/docker-runner/src/service/app.ts @@ -11,9 +11,9 @@ import { type ContainerOpts, type ExecOptions, } from '..'; -import { createDockerEventsParser } from './dockerEvents.parser.js'; -import type { RunnerConfig } from './config.js'; -import { closeWebsocket, getWebsocket, type SocketStream } from './websocket.util.js'; +import { createDockerEventsParser } from './dockerEvents.parser'; +import type { RunnerConfig } from './config'; +import { closeWebsocket, getWebsocket, type SocketStream } from './websocket.util'; const ensureImageSchema = z.object({ image: z.string().min(1), diff --git a/packages/docker-runner/src/service/main.ts b/packages/docker-runner/src/service/main.ts index 53926b912..61be2f7f2 100644 --- a/packages/docker-runner/src/service/main.ts +++ b/packages/docker-runner/src/service/main.ts @@ -1,7 +1,7 @@ -import './env.js'; +import './env'; -import { loadRunnerConfig } from './config.js'; -import { createRunnerApp } from './app.js'; +import { loadRunnerConfig } from './config'; +import { createRunnerApp } from './app'; async function bootstrap(): Promise { try { From 32fb9edd1f22aeab178d81704f586080ef2508b1 Mon Sep 17 00:00:00 2001 From: Casey Brooks Date: Sat, 21 Feb 2026 19:44:37 +0000 Subject: [PATCH 4/4] fix(docker-runner): run runtime via tsx --- packages/docker-runner/Dockerfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/docker-runner/Dockerfile b/packages/docker-runner/Dockerfile index 7ea587c31..78ffd5b42 100644 --- a/packages/docker-runner/Dockerfile +++ b/packages/docker-runner/Dockerfile @@ -43,12 +43,17 @@ WORKDIR /opt/app/packages/docker-runner RUN apt-get update \ && apt-get install -y --no-install-recommends git openssl \ + && npm install --global tsx@^4.20.5 \ + && npm cache clean --force \ && rm -rf /var/lib/apt/lists/* COPY --from=build --chown=node:node /opt/app /opt/app +COPY --from=build --chown=node:node /workspace/packages/docker-runner/package.json /opt/app/packages/docker-runner/package.json +COPY --from=build --chown=node:node /workspace/packages/docker-runner/src /opt/app/packages/docker-runner/src +COPY --from=build --chown=node:node /workspace/packages/docker-runner/tsconfig.json /opt/app/packages/docker-runner/tsconfig.json USER node EXPOSE 7071 -CMD ["node", "dist/service/main.js"] +CMD ["tsx", "src/service/main.ts"]