@stacks/api-test-toolkit 1.12.2

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/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # @stacks/api-test-toolkit
2
+
3
+ Test utilities for integration tests that need Docker-managed dependencies (for example Postgres).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -D @stacks/api-test-toolkit
9
+ ```
10
+
11
+ This package expects Docker to be available on the machine running tests.
12
+
13
+ ## Quick Start
14
+
15
+ Use the toolkit in your test global setup/teardown hooks.
16
+
17
+ ```ts
18
+ import type { DockerTestContainerConfig } from '@stacks/api-test-toolkit';
19
+ import { dockerTestDown, dockerTestUp } from '@stacks/api-test-toolkit';
20
+
21
+ const postgres: DockerTestContainerConfig = {
22
+ image: 'postgres:17',
23
+ name: 'my-api-test-postgres',
24
+ ports: [{ host: 5432, container: 5432 }],
25
+ env: ['POSTGRES_USER=postgres', 'POSTGRES_PASSWORD=postgres', 'POSTGRES_DB=postgres'],
26
+ };
27
+
28
+ export async function globalSetup() {
29
+ await dockerTestUp({ config: postgres });
30
+ }
31
+
32
+ export async function globalTeardown() {
33
+ await dockerTestDown({ config: postgres });
34
+ }
35
+ ```
36
+
37
+ ## API
38
+
39
+ ### `dockerTestUp({ config })`
40
+
41
+ Creates (or starts) the container and waits until it is reachable on TCP by default.
42
+
43
+ - Pulls image if missing
44
+ - Reuses an existing container with the same name
45
+ - Waits for readiness unless `waitForReady` is set to `false`
46
+
47
+ ### `dockerTestDown({ config })`
48
+
49
+ Stops and removes the container if it exists.
50
+
51
+ - No-op if the container is already absent
52
+
53
+ ### `dockerTestLogs({ config, argv })`
54
+
55
+ Streams or prints recent container logs.
56
+
57
+ - Follows logs by default
58
+ - Use `argv: ['--once']` to print once and exit
59
+ - `-f` / `--follow` force streaming mode
60
+
61
+ ## `DockerTestContainerConfig`
62
+
63
+ Required fields:
64
+
65
+ - `image`: Docker image name (example: `postgres:17`)
66
+ - `name`: Docker container name
67
+ - `ports`: host/container port mapping array
68
+
69
+ Common optional fields:
70
+
71
+ - `host`: bind address (default: `127.0.0.1`)
72
+ - `waitPort`: host-side port to probe for readiness
73
+ - `waitForReady`: disable readiness check when set to `false`
74
+ - `env`: environment variables (`KEY=value`)
75
+ - `entrypoint`, `command`
76
+ - `volumes`: mount strings in `host:container` format
77
+ - `extraHosts`: `hostname:ip` entries
78
+ - `healthcheck`: shell command passed as Docker `CMD-SHELL`
79
+ - `restartPolicy`: `no | always | on-failure | unless-stopped`
80
+ - `labels`
81
+ - `timeoutMs`: readiness timeout (default: `120000`)
82
+
83
+ ## Docker client environment
84
+
85
+ By default, Docker is accessed through:
86
+
87
+ - `DOCKER_SOCKET_PATH` (defaults to `/var/run/docker.sock`)
88
+
89
+ If `DOCKER_HOST` is set, it is used instead.
90
+
91
+ ## Notes
92
+
93
+ - Prefer `import type` for TypeScript-only symbols:
94
+ - `import type { DockerTestContainerConfig } from '@stacks/api-test-toolkit'`
95
+ - Container names should be unique per test suite to avoid clashes.
96
+
97
+ ## License
98
+
99
+ Apache 2.0
@@ -0,0 +1,46 @@
1
+ export interface DockerTestPortMapping {
2
+ host: number;
3
+ container: number;
4
+ }
5
+ export interface DockerTestContainerConfig {
6
+ /** Docker image (e.g. "postgres:17") */
7
+ image: string;
8
+ /** Container name */
9
+ name: string;
10
+ /** Host to bind to (default: "127.0.0.1") */
11
+ host?: string;
12
+ /** Port mappings (host → container) */
13
+ ports: DockerTestPortMapping[];
14
+ /** Port to wait on before declaring the container ready (default: first port's host side) */
15
+ waitPort?: number;
16
+ /** Set to false to skip the port-readiness check (e.g. for one-shot sidecars) */
17
+ waitForReady?: boolean;
18
+ /** Environment variables */
19
+ env?: string[];
20
+ /** Override the image entrypoint */
21
+ entrypoint?: string[];
22
+ /** Override the image command */
23
+ command?: string[];
24
+ /** Bind-mount volumes ("host:container") */
25
+ volumes?: string[];
26
+ /** Extra /etc/hosts entries ("hostname:ip") */
27
+ extraHosts?: string[];
28
+ /** Docker healthcheck command (passed after CMD-SHELL) */
29
+ healthcheck?: string;
30
+ /** Restart policy (default: no) */
31
+ restartPolicy?: 'no' | 'always' | 'on-failure' | 'unless-stopped';
32
+ /** Labels to attach to the container */
33
+ labels?: Record<string, string>;
34
+ /** Startup timeout in ms (default: 120_000) */
35
+ timeoutMs?: number;
36
+ }
37
+ export declare function dockerTestUp(args: {
38
+ config: DockerTestContainerConfig;
39
+ }): Promise<void>;
40
+ export declare function dockerTestDown(args: {
41
+ config: DockerTestContainerConfig;
42
+ }): Promise<void>;
43
+ export declare function dockerTestLogs(args: {
44
+ config: DockerTestContainerConfig;
45
+ argv: string[];
46
+ }): Promise<void>;
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dockerTestUp = dockerTestUp;
4
+ exports.dockerTestDown = dockerTestDown;
5
+ exports.dockerTestLogs = dockerTestLogs;
6
+ /* eslint-disable @typescript-eslint/no-unsafe-return */
7
+ const node_assert_1 = require("node:assert");
8
+ const net = require("node:net");
9
+ const Docker = require("dockerode");
10
+ const DEFAULTS = {
11
+ host: '127.0.0.1',
12
+ timeoutMs: 120_000,
13
+ };
14
+ function createDockerClient() {
15
+ if (process.env.DOCKER_HOST) {
16
+ const dockerHost = new URL(process.env.DOCKER_HOST);
17
+ return new Docker({
18
+ host: dockerHost.hostname,
19
+ port: Number(dockerHost.port),
20
+ protocol: dockerHost.protocol.replace(':', ''),
21
+ });
22
+ }
23
+ return new Docker({ socketPath: process.env.DOCKER_SOCKET_PATH ?? '/var/run/docker.sock' });
24
+ }
25
+ function sleep(ms) {
26
+ return new Promise(resolve => setTimeout(resolve, ms));
27
+ }
28
+ function streamToPromise(stream) {
29
+ return new Promise((resolve, reject) => {
30
+ stream.on('end', () => resolve());
31
+ stream.on('error', reject);
32
+ });
33
+ }
34
+ async function pullImageIfMissing(docker, image) {
35
+ const images = (await docker.listImages());
36
+ const hasImage = images.some(img => img.RepoTags?.includes(image));
37
+ if (hasImage)
38
+ return;
39
+ process.stdout.write(`[testenv] pulling image ${image}\n`);
40
+ const stream = await docker.pull(image);
41
+ await new Promise((resolve, reject) => {
42
+ docker.modem.followProgress(stream, err => {
43
+ if (err) {
44
+ reject(err instanceof Error ? err : new Error(String(err)));
45
+ return;
46
+ }
47
+ resolve();
48
+ });
49
+ });
50
+ }
51
+ async function getContainer(docker, name) {
52
+ const containers = await docker.listContainers({
53
+ all: true,
54
+ filters: { name: [name] },
55
+ });
56
+ // Docker's name filter does substring matching, so we need an exact match.
57
+ // Container names are stored with a leading slash (e.g. "/my-container").
58
+ const exact = containers.find(c => c.Names.some(n => n === `/${name}` || n === name));
59
+ if (!exact)
60
+ return undefined;
61
+ node_assert_1.strict.ok(exact.Id);
62
+ return docker.getContainer(exact.Id);
63
+ }
64
+ async function ensureContainerRunning(docker, config) {
65
+ const host = config.host ?? DEFAULTS.host;
66
+ const { name, image, ports, env, entrypoint, command, volumes, extraHosts, healthcheck, restartPolicy, labels, } = config;
67
+ const existing = await getContainer(docker, name);
68
+ if (existing) {
69
+ const inspect = await existing.inspect();
70
+ if (!inspect.State.Running) {
71
+ process.stdout.write(`[testenv] starting existing container ${name}\n`);
72
+ await existing.start();
73
+ }
74
+ else {
75
+ process.stdout.write(`[testenv] container ${name} already running\n`);
76
+ }
77
+ return existing;
78
+ }
79
+ const exposedPorts = {};
80
+ const portBindings = {};
81
+ for (const { host: hostPort, container: containerPort } of ports) {
82
+ const key = `${containerPort}/tcp`;
83
+ exposedPorts[key] = {};
84
+ portBindings[key] = [{ HostPort: String(hostPort), HostIp: host }];
85
+ }
86
+ const binds = volumes?.map(v => {
87
+ // Resolve relative paths from the project root
88
+ if (!v.startsWith('/')) {
89
+ const [hostPath, ...rest] = v.split(':');
90
+ const resolved = `${process.cwd()}/${hostPath}`;
91
+ return [resolved, ...rest].join(':');
92
+ }
93
+ return v;
94
+ });
95
+ process.stdout.write(`[testenv] creating container ${name}\n`);
96
+ const container = await docker.createContainer({
97
+ name,
98
+ Image: image,
99
+ Env: env,
100
+ ...(entrypoint && { Entrypoint: entrypoint }),
101
+ ...(command && { Cmd: command }),
102
+ ExposedPorts: exposedPorts,
103
+ HostConfig: {
104
+ PortBindings: portBindings,
105
+ AutoRemove: false,
106
+ ...(binds && { Binds: binds }),
107
+ ...(extraHosts && { ExtraHosts: extraHosts }),
108
+ RestartPolicy: { Name: restartPolicy ?? 'no' },
109
+ },
110
+ Labels: labels,
111
+ ...(healthcheck && {
112
+ Healthcheck: {
113
+ Test: ['CMD-SHELL', healthcheck],
114
+ Interval: 2_000_000_000,
115
+ Timeout: 2_000_000_000,
116
+ Retries: 30,
117
+ StartPeriod: 2_000_000_000,
118
+ },
119
+ }),
120
+ });
121
+ await container.start();
122
+ return container;
123
+ }
124
+ async function waitForPort(host, port, timeoutMs) {
125
+ const startedAt = Date.now();
126
+ while (Date.now() - startedAt < timeoutMs) {
127
+ const ok = await new Promise(resolve => {
128
+ const socket = net.createConnection(port, host);
129
+ socket.setTimeout(1_000);
130
+ socket.on('connect', () => {
131
+ socket.end();
132
+ resolve(true);
133
+ });
134
+ socket.on('timeout', () => {
135
+ socket.destroy();
136
+ resolve(false);
137
+ });
138
+ socket.on('error', () => resolve(false));
139
+ });
140
+ if (ok)
141
+ return;
142
+ await sleep(500);
143
+ }
144
+ throw new Error(`timed out waiting for ${host}:${port}`);
145
+ }
146
+ async function dockerTestUp(args) {
147
+ const { config } = args;
148
+ const host = config.host ?? DEFAULTS.host;
149
+ const timeoutMs = config.timeoutMs ?? DEFAULTS.timeoutMs;
150
+ const docker = createDockerClient();
151
+ await pullImageIfMissing(docker, config.image);
152
+ await ensureContainerRunning(docker, config);
153
+ if (config.waitForReady !== false && config.ports.length > 0) {
154
+ const port = config.waitPort ?? config.ports[0].host;
155
+ await waitForPort(host, port, timeoutMs);
156
+ process.stdout.write(`[testenv] ${config.name} ready on ${host}:${port}\n`);
157
+ }
158
+ else {
159
+ process.stdout.write(`[testenv] ${config.name} started (no readiness check)\n`);
160
+ }
161
+ }
162
+ async function dockerTestDown(args) {
163
+ const { config } = args;
164
+ const docker = createDockerClient();
165
+ const container = await getContainer(docker, config.name);
166
+ if (!container) {
167
+ process.stdout.write(`[testenv] container ${config.name} is already absent\n`);
168
+ return;
169
+ }
170
+ const inspect = await container.inspect();
171
+ if (inspect.State.Running) {
172
+ process.stdout.write(`[testenv] stopping ${config.name}\n`);
173
+ await container.stop({ t: 0 });
174
+ }
175
+ process.stdout.write(`[testenv] removing ${config.name}\n`);
176
+ await container.remove({ force: true, v: true });
177
+ }
178
+ async function dockerTestLogs(args) {
179
+ const { config, argv } = args;
180
+ const follow = argv.includes('-f') || argv.includes('--follow') || !argv.includes('--once');
181
+ const docker = createDockerClient();
182
+ const container = await getContainer(docker, config.name);
183
+ if (!container) {
184
+ throw new Error(`container ${config.name} not found`);
185
+ }
186
+ if (follow) {
187
+ const logStream = await container.logs({
188
+ stdout: true,
189
+ stderr: true,
190
+ follow: true,
191
+ timestamps: true,
192
+ tail: 200,
193
+ });
194
+ container.modem.demuxStream(logStream, process.stdout, process.stderr);
195
+ await streamToPromise(logStream);
196
+ return;
197
+ }
198
+ const output = await container.logs({
199
+ stdout: true,
200
+ stderr: true,
201
+ follow: false,
202
+ timestamps: true,
203
+ tail: 200,
204
+ });
205
+ process.stdout.write(output.toString('utf8'));
206
+ }
207
+ //# sourceMappingURL=docker-container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-container.js","sourceRoot":"","sources":["../src/docker-container.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { type DockerTestContainerConfig, type DockerTestPortMapping, dockerTestDown, dockerTestLogs, dockerTestUp, } from './docker-container';
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dockerTestUp = exports.dockerTestLogs = exports.dockerTestDown = void 0;
4
+ var docker_container_1 = require("./docker-container");
5
+ Object.defineProperty(exports, "dockerTestDown", { enumerable: true, get: function () { return docker_container_1.dockerTestDown; } });
6
+ Object.defineProperty(exports, "dockerTestLogs", { enumerable: true, get: function () { return docker_container_1.dockerTestLogs; } });
7
+ Object.defineProperty(exports, "dockerTestUp", { enumerable: true, get: function () { return docker_container_1.dockerTestUp; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uDAM4B;AAH1B,kHAAA,cAAc,OAAA;AACd,kHAAA,cAAc,OAAA;AACd,gHAAA,YAAY,OAAA"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@stacks/api-test-toolkit",
3
+ "version": "1.12.2",
4
+ "description": "Test utilities for @stacks/api-toolkit",
5
+ "main": "./dist/index.js",
6
+ "typings": "./dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "rimraf dist && tsc --project tsconfig.build.json",
9
+ "prepublishOnly": "npm run build"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/stx-labs/api-toolkit.git",
14
+ "directory": "packages/api-test-toolkit"
15
+ },
16
+ "keywords": [
17
+ "api",
18
+ "testing"
19
+ ],
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "author": "Stacks Labs",
24
+ "license": "Apache 2.0",
25
+ "bugs": {
26
+ "url": "https://github.com/stx-labs/api-toolkit/issues"
27
+ },
28
+ "homepage": "https://github.com/stx-labs/api-toolkit#readme",
29
+ "engines": {
30
+ "node": ">=22"
31
+ },
32
+ "peerDependencies": {
33
+ "@stacks/api-toolkit": "^1.12.2"
34
+ },
35
+ "devDependencies": {
36
+ "@types/dockerode": "^4.0.1",
37
+ "@types/node": "^24.12.2"
38
+ },
39
+ "dependencies": {
40
+ "dockerode": "^4.0.10"
41
+ }
42
+ }