@docker-harpoon/core 0.1.0 → 0.1.3

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.
Files changed (38) hide show
  1. package/dist/__tests__/bindings.test.d.ts +10 -0
  2. package/dist/__tests__/bindings.test.d.ts.map +1 -0
  3. package/dist/__tests__/bindings.test.js +124 -0
  4. package/dist/__tests__/container.test.d.ts +12 -0
  5. package/dist/__tests__/container.test.d.ts.map +1 -0
  6. package/dist/__tests__/container.test.js +115 -0
  7. package/dist/__tests__/database.test.d.ts +10 -0
  8. package/dist/__tests__/database.test.d.ts.map +1 -0
  9. package/dist/__tests__/database.test.js +92 -0
  10. package/dist/__tests__/network.test.d.ts +10 -0
  11. package/dist/__tests__/network.test.d.ts.map +1 -0
  12. package/dist/__tests__/network.test.js +44 -0
  13. package/dist/api/index.d.ts +1 -1
  14. package/dist/api/index.d.ts.map +1 -1
  15. package/dist/api/promise.d.ts +8 -0
  16. package/dist/api/promise.d.ts.map +1 -1
  17. package/dist/api/promise.js +109 -4
  18. package/dist/build-strategies/types.d.ts.map +1 -1
  19. package/dist/config-patchers/types.d.ts.map +1 -1
  20. package/dist/dockerfile-transformers/types.d.ts.map +1 -1
  21. package/dist/errors.d.ts.map +1 -1
  22. package/dist/helpers/database.d.ts.map +1 -1
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -2
  26. package/dist/resources/container.d.ts +10 -0
  27. package/dist/resources/container.d.ts.map +1 -1
  28. package/dist/resources/container.js +222 -5
  29. package/dist/resources/image.d.ts +1 -1
  30. package/dist/resources/image.d.ts.map +1 -1
  31. package/dist/resources/index.d.ts +2 -0
  32. package/dist/resources/index.d.ts.map +1 -1
  33. package/dist/resources/index.js +2 -0
  34. package/dist/resources/network.d.ts.map +1 -1
  35. package/dist/resources/schemas.d.ts +120 -0
  36. package/dist/resources/schemas.d.ts.map +1 -0
  37. package/dist/resources/schemas.js +95 -0
  38. package/package.json +7 -4
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Bindings Integration Tests
3
+ *
4
+ * Dogfoods the binding system to verify:
5
+ * - createEnvBinding helper
6
+ * - Env var injection into containers
7
+ * - Binding composition
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=bindings.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindings.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/bindings.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Bindings Integration Tests
3
+ *
4
+ * Dogfoods the binding system to verify:
5
+ * - createEnvBinding helper
6
+ * - Env var injection into containers
7
+ * - Binding composition
8
+ */
9
+ import { describe, test, expect, afterEach, setDefaultTimeout } from 'bun:test';
10
+ import { Container, database, createEnvBinding, destroyAll } from '../index';
11
+ setDefaultTimeout(30_000);
12
+ const waitUntil = (fn, timeout = 5000) => {
13
+ return new Promise((resolve) => {
14
+ const interval = setInterval(() => {
15
+ if (fn()) {
16
+ clearInterval(interval);
17
+ resolve(true);
18
+ }
19
+ }, 100);
20
+ });
21
+ };
22
+ describe('Bindings', () => {
23
+ afterEach(async () => {
24
+ await destroyAll();
25
+ });
26
+ test('createEnvBinding creates a simple env binding', () => {
27
+ const binding = createEnvBinding('config', {
28
+ NODE_ENV: 'test',
29
+ LOG_LEVEL: 'debug',
30
+ });
31
+ expect(binding.type).toBe('config');
32
+ expect(binding.getEnv()).toEqual({
33
+ NODE_ENV: 'test',
34
+ LOG_LEVEL: 'debug',
35
+ });
36
+ });
37
+ test('container receives env vars from bindings', async () => {
38
+ const configBinding = createEnvBinding('config', {
39
+ APP_NAME: 'test-app',
40
+ APP_VERSION: '1.0.0',
41
+ });
42
+ const container = await Container('test-binding-env', {
43
+ image: 'alpine:latest',
44
+ cmd: ['sleep', '30'],
45
+ bindings: {
46
+ config: configBinding,
47
+ },
48
+ });
49
+ await waitUntil(() => !!container.getIp('test-binding-env'), 5000);
50
+ const result = await container.exec([
51
+ 'sh',
52
+ '-c',
53
+ 'echo "$APP_NAME:$APP_VERSION"',
54
+ ]);
55
+ expect(result.stdout.trim()).toBe('test-app:1.0.0');
56
+ await container.destroy();
57
+ });
58
+ test('multiple bindings merge env vars', async () => {
59
+ const binding1 = createEnvBinding('env1', {
60
+ VAR_A: 'a',
61
+ VAR_B: 'b',
62
+ });
63
+ const binding2 = createEnvBinding('env2', {
64
+ VAR_C: 'c',
65
+ VAR_D: 'd',
66
+ });
67
+ const container = await Container('test-multi-binding', {
68
+ image: 'alpine:latest',
69
+ cmd: ['sleep', '30'],
70
+ bindings: {
71
+ first: binding1,
72
+ second: binding2,
73
+ },
74
+ });
75
+ await waitUntil(() => !!container.getIp('test-multi-binding'), 5000);
76
+ const result = await container.exec([
77
+ 'sh',
78
+ '-c',
79
+ 'echo "$VAR_A$VAR_B$VAR_C$VAR_D"',
80
+ ]);
81
+ expect(result.stdout.trim()).toBe('abcd');
82
+ await container.destroy();
83
+ });
84
+ test('explicit env takes precedence over bindings', async () => {
85
+ const binding = createEnvBinding('config', {
86
+ MY_VAR: 'from-binding',
87
+ });
88
+ const container = await Container('test-env-precedence', {
89
+ image: 'alpine:latest',
90
+ cmd: ['sleep', '30'],
91
+ bindings: {
92
+ config: binding,
93
+ },
94
+ env: {
95
+ MY_VAR: 'from-explicit',
96
+ },
97
+ });
98
+ await waitUntil(() => !!container.getIp('test-env-precedence'), 5000);
99
+ const result = await container.exec(['sh', '-c', 'echo "$MY_VAR"']);
100
+ expect(result.stdout.trim()).toBe('from-explicit');
101
+ await container.destroy();
102
+ });
103
+ test('database can be used as binding resource', async () => {
104
+ const db = await database('test-db-binding', {
105
+ image: 'redis:7-alpine',
106
+ hostPort: 16390,
107
+ });
108
+ const dbBinding = createEnvBinding('database', {
109
+ REDIS_URL: db.connectionString,
110
+ });
111
+ const container = await Container('test-db-consumer', {
112
+ image: 'alpine:latest',
113
+ cmd: ['sleep', '30'],
114
+ bindings: {
115
+ db: dbBinding,
116
+ },
117
+ });
118
+ await waitUntil(() => !!container.getIp('test-db-consumer'), 5000);
119
+ const result = await container.exec(['sh', '-c', 'echo "$REDIS_URL"']);
120
+ expect(result.stdout.trim()).toBe('redis://localhost:16390');
121
+ await container.destroy();
122
+ await db.destroy();
123
+ });
124
+ });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Container Resource Integration Tests
3
+ *
4
+ * Dogfoods the Container resource to verify:
5
+ * - Creation with network binding
6
+ * - waitForLog functionality
7
+ * - exec command execution
8
+ * - stats retrieval
9
+ * - Lifecycle (stop, destroy)
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=container.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/container.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Container Resource Integration Tests
3
+ *
4
+ * Dogfoods the Container resource to verify:
5
+ * - Creation with network binding
6
+ * - waitForLog functionality
7
+ * - exec command execution
8
+ * - stats retrieval
9
+ * - Lifecycle (stop, destroy)
10
+ */
11
+ import { describe, test, expect, afterEach, setDefaultTimeout } from 'bun:test';
12
+ import { Network, Container, destroyAll } from '../index';
13
+ setDefaultTimeout(30_000);
14
+ describe('Container', () => {
15
+ afterEach(async () => {
16
+ await destroyAll();
17
+ });
18
+ test('creates a container with basic config', async () => {
19
+ const container = await Container('test-container-basic', {
20
+ image: 'alpine:latest',
21
+ cmd: ['sleep', '30'],
22
+ });
23
+ expect(container.id).toBeDefined();
24
+ expect(container.name).toBe('test-container-basic');
25
+ await container.destroy();
26
+ });
27
+ test('creates a container attached to a network', async () => {
28
+ const network = await Network('test-container-net');
29
+ const container = await Container('test-container-networked', {
30
+ image: 'alpine:latest',
31
+ cmd: ['sleep', '30'],
32
+ networks: [network],
33
+ });
34
+ expect(container.id).toBeDefined();
35
+ const ip = await container.getIp('test-container-net');
36
+ expect(ip).toBeDefined();
37
+ await container.destroy();
38
+ await network.destroy();
39
+ });
40
+ test('exec runs commands inside container', async () => {
41
+ const container = await Container('test-container-exec', {
42
+ image: 'alpine:latest',
43
+ cmd: ['sleep', '30'],
44
+ });
45
+ await new Promise((r) => setTimeout(r, 500));
46
+ const result = await container.exec(['echo', 'hello world']);
47
+ expect(result.exitCode).toBe(0);
48
+ expect(result.stdout.trim()).toBe('hello world');
49
+ expect(result.durationMs).toBeGreaterThan(0);
50
+ await container.destroy();
51
+ });
52
+ test('stats returns container resource statistics', async () => {
53
+ const container = await Container('test-container-stats', {
54
+ image: 'alpine:latest',
55
+ cmd: ['sleep', '30'],
56
+ });
57
+ await new Promise((r) => setTimeout(r, 500));
58
+ const stats = await container.stats();
59
+ expect(stats.cpu).toBeDefined();
60
+ expect(stats.cpu.cores).toBeGreaterThan(0);
61
+ expect(stats.memory).toBeDefined();
62
+ expect(stats.memory.limit).toBeGreaterThan(0);
63
+ expect(stats.network).toBeDefined();
64
+ expect(stats.containerId).toBe(container.id);
65
+ await container.destroy();
66
+ });
67
+ test('waitForLog detects log patterns', async () => {
68
+ const container = await Container('test-container-logs', {
69
+ image: 'alpine:latest',
70
+ cmd: ['sh', '-c', 'echo "Server started successfully" && sleep 30'],
71
+ });
72
+ await container.waitForLog('Server started', 5000);
73
+ expect(true).toBe(true);
74
+ await container.destroy();
75
+ });
76
+ test('stop gracefully shuts down container', async () => {
77
+ const container = await Container('test-container-stop', {
78
+ image: 'alpine:latest',
79
+ cmd: ['sh', '-c', 'trap "exit 0" TERM; while true; do sleep 1; done'],
80
+ });
81
+ await new Promise((r) => setTimeout(r, 500));
82
+ const metadata = await container.stop('SIGTERM', 10000);
83
+ expect(metadata.signal).toBe('SIGTERM');
84
+ expect(metadata.signalCount).toBeGreaterThan(0);
85
+ expect(metadata.timeTakenMs).toBeGreaterThan(0);
86
+ await container.destroy();
87
+ });
88
+ test('supports environment variables', async () => {
89
+ const container = await Container('test-container-env', {
90
+ image: 'alpine:latest',
91
+ cmd: ['sleep', '30'],
92
+ env: {
93
+ MY_VAR: 'hello',
94
+ ANOTHER_VAR: 'world',
95
+ },
96
+ });
97
+ await new Promise((r) => setTimeout(r, 500));
98
+ const result = await container.exec([
99
+ 'sh',
100
+ '-c',
101
+ 'echo $MY_VAR $ANOTHER_VAR',
102
+ ]);
103
+ expect(result.stdout.trim()).toBe('hello world');
104
+ await container.destroy();
105
+ });
106
+ test('supports port mappings', async () => {
107
+ const container = await Container('test-container-ports', {
108
+ image: 'alpine:latest',
109
+ cmd: ['sleep', '30'],
110
+ ports: [{ internal: 8080, external: 18080 }],
111
+ });
112
+ expect(container.id).toBeDefined();
113
+ await container.destroy();
114
+ });
115
+ });
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Database Helper Integration Tests
3
+ *
4
+ * Dogfoods the database helper to verify:
5
+ * - Connection string generation
6
+ * - Port mapping
7
+ * - Database-specific defaults
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=database.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/database.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Database Helper Integration Tests
3
+ *
4
+ * Dogfoods the database helper to verify:
5
+ * - Connection string generation
6
+ * - Port mapping
7
+ * - Database-specific defaults
8
+ */
9
+ import { describe, test, expect, afterEach, setDefaultTimeout } from 'bun:test';
10
+ import { Network, database, destroyAll } from '../index';
11
+ setDefaultTimeout(60_000);
12
+ describe('database', () => {
13
+ afterEach(async () => {
14
+ await destroyAll();
15
+ });
16
+ test('creates a postgres database with connection string', async () => {
17
+ const db = await database('test-postgres', {
18
+ image: 'postgres:16-alpine',
19
+ env: {
20
+ POSTGRES_PASSWORD: 'testpass',
21
+ POSTGRES_DB: 'testdb',
22
+ },
23
+ hostPort: 15432,
24
+ });
25
+ expect(db.id).toBeDefined();
26
+ expect(db.name).toBe('test-postgres');
27
+ expect(db.port).toBe(5432);
28
+ expect(db.hostPort).toBe(15432);
29
+ expect(db.connectionString).toBe('postgresql://postgres:testpass@localhost:15432/testdb');
30
+ await db.destroy();
31
+ });
32
+ test('creates a redis database with connection string', async () => {
33
+ const db = await database('test-redis', {
34
+ image: 'redis:7-alpine',
35
+ hostPort: 16379,
36
+ });
37
+ expect(db.port).toBe(6379);
38
+ expect(db.hostPort).toBe(16379);
39
+ expect(db.connectionString).toBe('redis://localhost:16379');
40
+ await db.destroy();
41
+ });
42
+ test('creates a redis database with password', async () => {
43
+ const db = await database('test-redis-auth', {
44
+ image: 'redis:7-alpine',
45
+ hostPort: 16380,
46
+ env: {
47
+ REDIS_PASSWORD: 'secret',
48
+ },
49
+ });
50
+ expect(db.connectionString).toBe('redis://:secret@localhost:16380');
51
+ await db.destroy();
52
+ });
53
+ test('creates a mysql database with connection string', async () => {
54
+ const db = await database('test-mysql', {
55
+ image: 'mysql:8',
56
+ env: {
57
+ MYSQL_ROOT_PASSWORD: 'rootpass',
58
+ MYSQL_DATABASE: 'mydb',
59
+ },
60
+ hostPort: 13306,
61
+ });
62
+ expect(db.port).toBe(3306);
63
+ expect(db.hostPort).toBe(13306);
64
+ expect(db.connectionString).toBe('mysql://root:rootpass@localhost:13306/mydb');
65
+ await db.destroy();
66
+ });
67
+ test('attaches database to network', async () => {
68
+ const network = await Network('test-db-net');
69
+ const db = await database('test-db-networked', {
70
+ image: 'redis:7-alpine',
71
+ networks: [network],
72
+ hostPort: 16381,
73
+ });
74
+ const ip = await db.getIp('test-db-net');
75
+ expect(ip).toBeDefined();
76
+ expect(ip).not.toBe('');
77
+ await db.destroy();
78
+ await network.destroy();
79
+ });
80
+ test('database inherits container methods', async () => {
81
+ const db = await database('test-db-methods', {
82
+ image: 'redis:7-alpine',
83
+ hostPort: 16382,
84
+ });
85
+ await db.waitForLog('Ready to accept connections', 10000);
86
+ const result = await db.exec(['redis-cli', 'PING']);
87
+ expect(result.stdout.trim()).toBe('PONG');
88
+ const stats = await db.stats();
89
+ expect(stats.cpu).toBeDefined();
90
+ await db.destroy();
91
+ });
92
+ });
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Network Resource Integration Tests
3
+ *
4
+ * Dogfoods the Network resource to verify:
5
+ * - Creation and destruction
6
+ * - Property access (id, name)
7
+ * - Duplicate network handling
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=network.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/network.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Network Resource Integration Tests
3
+ *
4
+ * Dogfoods the Network resource to verify:
5
+ * - Creation and destruction
6
+ * - Property access (id, name)
7
+ * - Duplicate network handling
8
+ */
9
+ import { describe, test, expect, afterEach, setDefaultTimeout } from 'bun:test';
10
+ import { Network, destroyAll } from '../index';
11
+ setDefaultTimeout(30_000);
12
+ describe('Network', () => {
13
+ afterEach(async () => {
14
+ await destroyAll();
15
+ });
16
+ test('creates a network and returns resource with id and name', async () => {
17
+ const network = await Network('test-network-basic');
18
+ expect(network.id).toBeDefined();
19
+ expect(network.id.length).toBeGreaterThan(0);
20
+ expect(network.name).toBe('test-network-basic');
21
+ await network.destroy();
22
+ });
23
+ test('allows custom driver configuration', async () => {
24
+ const network = await Network('test-network-custom', {
25
+ driver: 'bridge',
26
+ });
27
+ expect(network.name).toBe('test-network-custom');
28
+ expect(network.id).toBeDefined();
29
+ await network.destroy();
30
+ });
31
+ test('handles creating network with same name (replaces existing)', async () => {
32
+ const network1 = await Network('test-network-duplicate');
33
+ const id1 = network1.id;
34
+ const network2 = await Network('test-network-duplicate');
35
+ const id2 = network2.id;
36
+ expect(id2).not.toBe(id1);
37
+ await network2.destroy();
38
+ });
39
+ test('destroy is idempotent', async () => {
40
+ const network = await Network('test-network-idempotent');
41
+ await network.destroy();
42
+ expect(network.destroy()).resolves.toBeUndefined();
43
+ });
44
+ });
@@ -3,5 +3,5 @@
3
3
  *
4
4
  * Re-exports the Promise-based API for cleaner imports.
5
5
  */
6
- export { Network, Container, database, Image, setDocker, resetDocker, destroyAll, type NetworkConfig, type NetworkResource, type ContainerConfig, type ContainerResource, type PortMapping, type ShutdownMetadata, type DatabaseConfig, type DatabaseResource, type ImageConfig, type ImageResource, } from './promise';
6
+ export { Network, Container, database, Image, setDocker, resetDocker, destroyAll, type NetworkConfig, type NetworkResource, type ContainerConfig, type ContainerResource, type PortMapping, type ShutdownMetadata, type DatabaseConfig, type DatabaseResource, type ImageConfig, type ImageResource, type ContainerStats, type ExecOptions, type ExecResult, type LogOptions, type LogLine, } from './promise';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEL,OAAO,EACP,SAAS,EACT,QAAQ,EACR,KAAK,EAGL,SAAS,EACT,WAAW,EACX,UAAU,EAGV,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEL,OAAO,EACP,SAAS,EACT,QAAQ,EACR,KAAK,EAGL,SAAS,EACT,WAAW,EACX,UAAU,EAGV,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,aAAa,EAGlB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,OAAO,GACb,MAAM,WAAW,CAAC"}
@@ -7,6 +7,8 @@
7
7
  * Inspired by Alchemy.run and Pulumi's IAC patterns.
8
8
  */
9
9
  import Docker from 'dockerode';
10
+ import { type ContainerStats, type ExecOptions, type ExecResult, type LogOptions, type LogLine } from '../resources';
11
+ export type { ContainerStats, ExecOptions, ExecResult, LogOptions, LogLine, } from '../resources';
10
12
  import type { Binding } from '../bindings/types';
11
13
  export interface NetworkConfig {
12
14
  /** Network driver (default: 'bridge') */
@@ -49,6 +51,12 @@ export interface ContainerResource {
49
51
  stop(signal?: string, timeoutMs?: number): Promise<ShutdownMetadata>;
50
52
  /** Get container IP in a network */
51
53
  getIp(networkName: string): Promise<string>;
54
+ /** Get container resource statistics (CPU, memory, network) */
55
+ stats(): Promise<ContainerStats>;
56
+ /** Execute a command inside the container */
57
+ exec(cmd: string[], options?: Omit<ExecOptions, 'cmd'>): Promise<ExecResult>;
58
+ /** Stream container logs as an async iterable */
59
+ streamLogs(options?: LogOptions): Promise<AsyncIterable<LogLine>>;
52
60
  /** Remove this container */
53
61
  destroy(): Promise<void>;
54
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../../src/api/promise.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,MAAM,MAAM,WAAW,CAAC;AAkB/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,gCAAgC;IAChC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACrE,oCAAoC;IACpC,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,4BAA4B;IAC5B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,KAAK,CAAC,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD,0CAA0C;IAC1C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAwCD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC;AA4CD;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAC3B,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,aAAkB,GACzB,OAAO,CAAC,eAAe,CAAC,CA+B1B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,iBAAiB,CAAC,CAqD5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAwD3B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,KAAK,CACzB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,CAAC,CAWxB;AAED;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAShD"}
1
+ {"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../../src/api/promise.ts"],"names":[],"mappings":"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"}
@@ -7,8 +7,9 @@
7
7
  * Inspired by Alchemy.run and Pulumi's IAC patterns.
8
8
  */
9
9
  import { Effect, Scope, Exit } from 'effect';
10
- import { homedir } from 'os';
10
+ import { homedir, platform } from 'os';
11
11
  import { existsSync } from 'fs';
12
+ import { spawn } from 'child_process';
12
13
  import Docker from 'dockerode';
13
14
  // Import Effect-based resources (internal only)
14
15
  import { Network as EffectNetwork, Container as EffectContainer, Image as EffectImage, } from '../resources';
@@ -44,6 +45,92 @@ function getDocker() {
44
45
  }
45
46
  return dockerClient;
46
47
  }
48
+ // ============ Docker Auto-Start (Alchemy.run Style) ============
49
+ const DOCKER_STARTUP_TIMEOUT_MS = 60_000;
50
+ let dockerEnsured = false;
51
+ /**
52
+ * Start Docker Desktop on macOS/Windows if not running.
53
+ */
54
+ function startDockerDesktop() {
55
+ const os = platform();
56
+ if (os === 'darwin') {
57
+ console.log('[Harpoon] Starting Docker Desktop...');
58
+ const child = spawn('open', ['-a', 'Docker', '--background'], {
59
+ detached: true,
60
+ stdio: 'ignore',
61
+ });
62
+ child.unref();
63
+ }
64
+ else if (os === 'win32') {
65
+ console.log('[Harpoon] Starting Docker Desktop...');
66
+ const child = spawn('cmd', ['/c', 'start', '', 'Docker Desktop'], {
67
+ detached: true,
68
+ stdio: 'ignore',
69
+ });
70
+ child.unref();
71
+ }
72
+ // Linux: Docker daemon managed by systemd, no auto-start
73
+ }
74
+ /**
75
+ * Wait for Docker daemon to be ready with polling.
76
+ */
77
+ async function waitForDockerReady(socketPath, timeoutMs) {
78
+ const start = Date.now();
79
+ let lastError = null;
80
+ while (Date.now() - start < timeoutMs) {
81
+ try {
82
+ if (existsSync(socketPath)) {
83
+ const docker = new Docker({ socketPath });
84
+ await docker.ping();
85
+ console.log('[Harpoon] Docker is ready');
86
+ return;
87
+ }
88
+ }
89
+ catch (e) {
90
+ lastError = e;
91
+ }
92
+ await new Promise(r => setTimeout(r, 500));
93
+ }
94
+ throw new Error(`[Harpoon] Docker not ready after ${timeoutMs}ms: ${lastError?.message}`);
95
+ }
96
+ /**
97
+ * Ensure Docker is running, auto-starting if needed.
98
+ * This is the Alchemy.run-style declarative approach.
99
+ */
100
+ async function ensureDockerRunning() {
101
+ if (dockerEnsured)
102
+ return;
103
+ const socketPath = detectDockerSocket();
104
+ // Check if already running
105
+ if (existsSync(socketPath)) {
106
+ try {
107
+ const docker = new Docker({ socketPath });
108
+ await docker.ping();
109
+ dockerEnsured = true;
110
+ return; // Docker is ready
111
+ }
112
+ catch {
113
+ // Socket exists but daemon not responding, wait for it
114
+ console.log('[Harpoon] Docker socket exists but daemon not responding, waiting...');
115
+ }
116
+ }
117
+ else {
118
+ // Socket doesn't exist, start Docker
119
+ console.log('[Harpoon] Docker not running, attempting auto-start...');
120
+ startDockerDesktop();
121
+ }
122
+ // Wait for Docker to be ready
123
+ await waitForDockerReady(socketPath, DOCKER_STARTUP_TIMEOUT_MS);
124
+ dockerEnsured = true;
125
+ }
126
+ /**
127
+ * Get Docker client with auto-start support.
128
+ * Ensures Docker is running before returning client.
129
+ */
130
+ async function getDockerAsync() {
131
+ await ensureDockerRunning();
132
+ return getDocker();
133
+ }
47
134
  /**
48
135
  * Set a custom Docker client.
49
136
  * Useful for testing or custom configurations.
@@ -100,7 +187,7 @@ function registerCleanup() {
100
187
  */
101
188
  export async function Network(name, config = {}) {
102
189
  registerCleanup();
103
- const docker = getDocker();
190
+ const docker = await getDockerAsync();
104
191
  const scope = Effect.runSync(Scope.make());
105
192
  const effectConfig = {
106
193
  name,
@@ -139,7 +226,7 @@ export async function Network(name, config = {}) {
139
226
  */
140
227
  export async function Container(name, config) {
141
228
  registerCleanup();
142
- const docker = getDocker();
229
+ const docker = await getDockerAsync();
143
230
  const scope = Effect.runSync(Scope.make());
144
231
  // Convert NetworkResource to { name: string }
145
232
  const networks = config.networks?.map((n) => 'destroy' in n ? { name: n.name } : n);
@@ -169,6 +256,15 @@ export async function Container(name, config) {
169
256
  async getIp(networkName) {
170
257
  return Effect.runPromise(effectResource.getIp(networkName));
171
258
  },
259
+ async stats() {
260
+ return Effect.runPromise(effectResource.stats());
261
+ },
262
+ async exec(cmd, options) {
263
+ return Effect.runPromise(effectResource.exec({ cmd, ...options }));
264
+ },
265
+ async streamLogs(options) {
266
+ return Effect.runPromise(effectResource.streamLogs(options));
267
+ },
172
268
  async destroy() {
173
269
  await cleanup();
174
270
  resources.delete(resourceId);
@@ -199,7 +295,7 @@ export async function Container(name, config) {
199
295
  */
200
296
  export async function database(name, config) {
201
297
  registerCleanup();
202
- const docker = getDocker();
298
+ const docker = await getDockerAsync();
203
299
  const scope = Effect.runSync(Scope.make());
204
300
  // Convert NetworkResource to { name: string }
205
301
  const networks = config.networks?.map((n) => 'destroy' in n ? { name: n.name } : n);
@@ -232,6 +328,15 @@ export async function database(name, config) {
232
328
  async getIp(networkName) {
233
329
  return Effect.runPromise(effectResource.getIp(networkName));
234
330
  },
331
+ async stats() {
332
+ return Effect.runPromise(effectResource.stats());
333
+ },
334
+ async exec(cmd, options) {
335
+ return Effect.runPromise(effectResource.exec({ cmd, ...options }));
336
+ },
337
+ async streamLogs(options) {
338
+ return Effect.runPromise(effectResource.streamLogs(options));
339
+ },
235
340
  async destroy() {
236
341
  await cleanup();
237
342
  resources.delete(resourceId);
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/build-strategies/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAErB,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,sDAAsD;IACtD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B,6BAA6B;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEtD,uCAAuC;IACvC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAElC,mDAAmD;IACnD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAEjC,gCAAgC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,oCAAoC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC,gEAAgE;IAChE,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAElC,2CAA2C;IAC3C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAEpC,uDAAuD;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,EAAG,oBAAoB,CAAU;IAC9C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;gBAEvB,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAYjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,iCAAiC;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,CAChB,KAAK,EAAE,kBAAkB,KACtB,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;IAE1D,8BAA8B;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IAErD,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;CACxC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/build-strategies/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAErB,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,sDAAsD;IACtD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B,6BAA6B;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEtD,uCAAuC;IACvC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAElC,mDAAmD;IACnD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAEjC,gCAAgC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,oCAAoC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC,gEAAgE;IAChE,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAElC,2CAA2C;IAC3C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAEpC,uDAAuD;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,uBAAiC;IAC9C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAEnC,YAAY,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAW/D;CACF;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,iCAAiC;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,CAChB,KAAK,EAAE,kBAAkB,KACtB,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;IAE1D,8BAA8B;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IAErD,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;CACxC"}