@docker-harpoon/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.d.ts +7 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +10 -0
- package/dist/api/promise.d.ts +179 -0
- package/dist/api/promise.d.ts.map +1 -0
- package/dist/api/promise.js +282 -0
- package/dist/bindings/index.d.ts +8 -0
- package/dist/bindings/index.d.ts.map +1 -0
- package/dist/bindings/index.js +6 -0
- package/dist/bindings/types.d.ts +116 -0
- package/dist/bindings/types.d.ts.map +1 -0
- package/dist/bindings/types.js +46 -0
- package/dist/build-strategies/index.d.ts +30 -0
- package/dist/build-strategies/index.d.ts.map +1 -0
- package/dist/build-strategies/index.js +47 -0
- package/dist/build-strategies/standard.d.ts +16 -0
- package/dist/build-strategies/standard.d.ts.map +1 -0
- package/dist/build-strategies/standard.js +39 -0
- package/dist/build-strategies/types.d.ts +81 -0
- package/dist/build-strategies/types.d.ts.map +1 -0
- package/dist/build-strategies/types.js +25 -0
- package/dist/config-patchers/index.d.ts +33 -0
- package/dist/config-patchers/index.d.ts.map +1 -0
- package/dist/config-patchers/index.js +75 -0
- package/dist/config-patchers/types.d.ts +89 -0
- package/dist/config-patchers/types.d.ts.map +1 -0
- package/dist/config-patchers/types.js +25 -0
- package/dist/dockerfile-transformers/core.d.ts +59 -0
- package/dist/dockerfile-transformers/core.d.ts.map +1 -0
- package/dist/dockerfile-transformers/core.js +271 -0
- package/dist/dockerfile-transformers/index.d.ts +42 -0
- package/dist/dockerfile-transformers/index.d.ts.map +1 -0
- package/dist/dockerfile-transformers/index.js +67 -0
- package/dist/dockerfile-transformers/types.d.ts +116 -0
- package/dist/dockerfile-transformers/types.d.ts.map +1 -0
- package/dist/dockerfile-transformers/types.js +29 -0
- package/dist/errors.d.ts +75 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +119 -0
- package/dist/helpers/database.d.ts +54 -0
- package/dist/helpers/database.d.ts.map +1 -0
- package/dist/helpers/database.js +108 -0
- package/dist/helpers/index.d.ts +8 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +6 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/resources/container.d.ts +42 -0
- package/dist/resources/container.d.ts.map +1 -0
- package/dist/resources/container.js +256 -0
- package/dist/resources/image.d.ts +37 -0
- package/dist/resources/image.d.ts.map +1 -0
- package/dist/resources/image.js +113 -0
- package/dist/resources/index.d.ts +12 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +8 -0
- package/dist/resources/network.d.ts +21 -0
- package/dist/resources/network.d.ts.map +1 -0
- package/dist/resources/network.js +86 -0
- package/package.json +28 -0
package/dist/errors.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harpoon Core Error Classes
|
|
3
|
+
*
|
|
4
|
+
* Typed error classes for Docker resource operations.
|
|
5
|
+
* Provides clear error categorization.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Base error class for all Harpoon errors.
|
|
9
|
+
*/
|
|
10
|
+
export class HarpoonError extends Error {
|
|
11
|
+
/** Effect integration discriminant */
|
|
12
|
+
_tag = 'HarpoonError';
|
|
13
|
+
/** Resource identifier that caused the error */
|
|
14
|
+
resource;
|
|
15
|
+
/** Original error that caused this error */
|
|
16
|
+
cause;
|
|
17
|
+
constructor(message, resource, cause) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = 'HarpoonError';
|
|
20
|
+
this.resource = resource;
|
|
21
|
+
if (cause) {
|
|
22
|
+
this.cause = cause;
|
|
23
|
+
}
|
|
24
|
+
if (Error.captureStackTrace) {
|
|
25
|
+
Error.captureStackTrace(this, this.constructor);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Error during network operations.
|
|
31
|
+
*/
|
|
32
|
+
export class NetworkError extends HarpoonError {
|
|
33
|
+
_tag = 'NetworkError';
|
|
34
|
+
constructor(name, message, cause) {
|
|
35
|
+
super(message ?? `Network "${name}" operation failed`, name, cause);
|
|
36
|
+
this.name = 'NetworkError';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Error during image build operations.
|
|
41
|
+
*/
|
|
42
|
+
export class ImageError extends HarpoonError {
|
|
43
|
+
_tag = 'ImageError';
|
|
44
|
+
constructor(tag, message, cause) {
|
|
45
|
+
super(message ?? `Image "${tag}" build failed`, tag, cause);
|
|
46
|
+
this.name = 'ImageError';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Error during container operations.
|
|
51
|
+
*/
|
|
52
|
+
export class ContainerError extends HarpoonError {
|
|
53
|
+
_tag = 'ContainerError';
|
|
54
|
+
constructor(name, message, cause) {
|
|
55
|
+
super(message ?? `Container "${name}" operation failed`, name, cause);
|
|
56
|
+
this.name = 'ContainerError';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Error during scope operations.
|
|
61
|
+
*/
|
|
62
|
+
export class ScopeError extends HarpoonError {
|
|
63
|
+
_tag = 'ScopeError';
|
|
64
|
+
constructor(message, cause) {
|
|
65
|
+
super(message, 'scope', cause);
|
|
66
|
+
this.name = 'ScopeError';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Error during binding operations.
|
|
71
|
+
*/
|
|
72
|
+
export class BindingError extends HarpoonError {
|
|
73
|
+
_tag = 'BindingError';
|
|
74
|
+
bindingType;
|
|
75
|
+
constructor(bindingType, message, cause) {
|
|
76
|
+
super(message, bindingType, cause);
|
|
77
|
+
this.name = 'BindingError';
|
|
78
|
+
this.bindingType = bindingType;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// ============ Helper Functions ============
|
|
82
|
+
/**
|
|
83
|
+
* Convert an unknown error to an Error instance for use as cause.
|
|
84
|
+
* Preserves Error instances, wraps non-Errors in new Error.
|
|
85
|
+
*/
|
|
86
|
+
export function asCause(error) {
|
|
87
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Transform an unknown error into a typed HarpoonError.
|
|
91
|
+
*/
|
|
92
|
+
export function toHarpoonError(error, resource, ErrorClass = HarpoonError) {
|
|
93
|
+
// Already correct type - pass through
|
|
94
|
+
if (error instanceof ErrorClass) {
|
|
95
|
+
return error;
|
|
96
|
+
}
|
|
97
|
+
// Already a HarpoonError - pass through
|
|
98
|
+
if (error instanceof HarpoonError) {
|
|
99
|
+
return error;
|
|
100
|
+
}
|
|
101
|
+
// Effect TaggedError - extract message
|
|
102
|
+
if (error && typeof error === 'object' && '_tag' in error) {
|
|
103
|
+
const tagged = error;
|
|
104
|
+
return new ErrorClass(resource, tagged.message ?? `${tagged._tag} error`, error instanceof Error ? error : undefined);
|
|
105
|
+
}
|
|
106
|
+
// Standard Error
|
|
107
|
+
if (error instanceof Error) {
|
|
108
|
+
return new ErrorClass(resource, error.message, error);
|
|
109
|
+
}
|
|
110
|
+
// Unknown
|
|
111
|
+
return new ErrorClass(resource, String(error));
|
|
112
|
+
}
|
|
113
|
+
// ============ Type Predicates ============
|
|
114
|
+
export const isHarpoonError = (e) => e instanceof HarpoonError;
|
|
115
|
+
export const isNetworkError = (e) => e instanceof NetworkError;
|
|
116
|
+
export const isImageError = (e) => e instanceof ImageError;
|
|
117
|
+
export const isContainerError = (e) => e instanceof ContainerError;
|
|
118
|
+
export const isScopeError = (e) => e instanceof ScopeError;
|
|
119
|
+
export const isBindingError = (e) => e instanceof BindingError;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Helper
|
|
3
|
+
*
|
|
4
|
+
* Convenience function for creating database containers
|
|
5
|
+
* with sensible defaults.
|
|
6
|
+
*/
|
|
7
|
+
import { Effect, Scope } from 'effect';
|
|
8
|
+
import Docker from 'dockerode';
|
|
9
|
+
import { type ContainerResource } from '../resources/container';
|
|
10
|
+
import type { Binding } from '../bindings/types';
|
|
11
|
+
export interface DatabaseConfig {
|
|
12
|
+
/** Docker image (e.g., "postgres:15", "mysql:8", "redis:7") */
|
|
13
|
+
image: string;
|
|
14
|
+
/** Override default port for this database type */
|
|
15
|
+
port?: number;
|
|
16
|
+
/** Host port to expose (defaults to same as internal port) */
|
|
17
|
+
hostPort?: number;
|
|
18
|
+
/** Environment variables (e.g., { POSTGRES_PASSWORD: 'secret' }) */
|
|
19
|
+
env?: Record<string, string>;
|
|
20
|
+
/** Networks to connect to */
|
|
21
|
+
networks?: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
}>;
|
|
24
|
+
/** Bindings for this database */
|
|
25
|
+
bindings?: Record<string, Binding>;
|
|
26
|
+
}
|
|
27
|
+
export interface DatabaseResource extends ContainerResource {
|
|
28
|
+
/** Connection string for this database */
|
|
29
|
+
readonly connectionString: string;
|
|
30
|
+
/** Internal port the database is listening on */
|
|
31
|
+
readonly port: number;
|
|
32
|
+
/** Host port mapped to the database */
|
|
33
|
+
readonly hostPort: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create a database container with sensible defaults.
|
|
37
|
+
*
|
|
38
|
+
* Automatically infers database type from image name and sets:
|
|
39
|
+
* - Default port mappings
|
|
40
|
+
* - Connection string helper
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const db = await database("my-postgres", {
|
|
45
|
+
* image: "postgres:15",
|
|
46
|
+
* env: { POSTGRES_PASSWORD: "secret" },
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* console.log(db.connectionString);
|
|
50
|
+
* // postgresql://postgres:secret@localhost:5432/postgres
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare const database: (name: string, config: DatabaseConfig, docker: Docker) => Effect.Effect<DatabaseResource, Error, Scope.Scope>;
|
|
54
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/helpers/database.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAmC,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACjG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAYjD,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;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnC,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;AAyDD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,QAAQ,GACnB,MAAM,MAAM,EACZ,QAAQ,cAAc,EACtB,QAAQ,MAAM,KACb,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAiCjD,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Helper
|
|
3
|
+
*
|
|
4
|
+
* Convenience function for creating database containers
|
|
5
|
+
* with sensible defaults.
|
|
6
|
+
*/
|
|
7
|
+
import { Effect } from 'effect';
|
|
8
|
+
import { Container } from '../resources/container';
|
|
9
|
+
/** Known database images and their default ports */
|
|
10
|
+
const DATABASE_DEFAULTS = {
|
|
11
|
+
postgres: { port: 5432, user: 'postgres', passwordEnv: 'POSTGRES_PASSWORD' },
|
|
12
|
+
mysql: { port: 3306, user: 'root', passwordEnv: 'MYSQL_ROOT_PASSWORD' },
|
|
13
|
+
mariadb: { port: 3306, user: 'root', passwordEnv: 'MYSQL_ROOT_PASSWORD' },
|
|
14
|
+
mongo: { port: 27017 },
|
|
15
|
+
redis: { port: 6379 },
|
|
16
|
+
memcached: { port: 11211 },
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Infer database type from image name.
|
|
20
|
+
*/
|
|
21
|
+
function inferDatabaseType(image) {
|
|
22
|
+
const imageName = image.split(':')[0]?.toLowerCase() ?? '';
|
|
23
|
+
for (const dbType of Object.keys(DATABASE_DEFAULTS)) {
|
|
24
|
+
if (imageName.includes(dbType)) {
|
|
25
|
+
return dbType;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Build a connection string for the database.
|
|
32
|
+
*/
|
|
33
|
+
function buildConnectionString(dbType, host, port, env) {
|
|
34
|
+
switch (dbType) {
|
|
35
|
+
case 'postgres': {
|
|
36
|
+
const user = env['POSTGRES_USER'] ?? 'postgres';
|
|
37
|
+
const password = env['POSTGRES_PASSWORD'] ?? '';
|
|
38
|
+
const database = env['POSTGRES_DB'] ?? 'postgres';
|
|
39
|
+
return `postgresql://${user}:${password}@${host}:${port}/${database}`;
|
|
40
|
+
}
|
|
41
|
+
case 'mysql':
|
|
42
|
+
case 'mariadb': {
|
|
43
|
+
const user = env['MYSQL_USER'] ?? 'root';
|
|
44
|
+
const password = env['MYSQL_ROOT_PASSWORD'] ?? env['MYSQL_PASSWORD'] ?? '';
|
|
45
|
+
const database = env['MYSQL_DATABASE'] ?? '';
|
|
46
|
+
return `mysql://${user}:${password}@${host}:${port}/${database}`;
|
|
47
|
+
}
|
|
48
|
+
case 'mongo': {
|
|
49
|
+
const user = env['MONGO_INITDB_ROOT_USERNAME'] ?? '';
|
|
50
|
+
const password = env['MONGO_INITDB_ROOT_PASSWORD'] ?? '';
|
|
51
|
+
const auth = user && password ? `${user}:${password}@` : '';
|
|
52
|
+
return `mongodb://${auth}${host}:${port}`;
|
|
53
|
+
}
|
|
54
|
+
case 'redis': {
|
|
55
|
+
const password = env['REDIS_PASSWORD'] ?? '';
|
|
56
|
+
return password
|
|
57
|
+
? `redis://:${password}@${host}:${port}`
|
|
58
|
+
: `redis://${host}:${port}`;
|
|
59
|
+
}
|
|
60
|
+
default:
|
|
61
|
+
return `${host}:${port}`;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a database container with sensible defaults.
|
|
66
|
+
*
|
|
67
|
+
* Automatically infers database type from image name and sets:
|
|
68
|
+
* - Default port mappings
|
|
69
|
+
* - Connection string helper
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const db = await database("my-postgres", {
|
|
74
|
+
* image: "postgres:15",
|
|
75
|
+
* env: { POSTGRES_PASSWORD: "secret" },
|
|
76
|
+
* });
|
|
77
|
+
*
|
|
78
|
+
* console.log(db.connectionString);
|
|
79
|
+
* // postgresql://postgres:secret@localhost:5432/postgres
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export const database = (name, config, docker) => Effect.gen(function* () {
|
|
83
|
+
const dbType = inferDatabaseType(config.image);
|
|
84
|
+
const defaults = dbType ? DATABASE_DEFAULTS[dbType] : undefined;
|
|
85
|
+
const internalPort = config.port ?? defaults?.port ?? 5432;
|
|
86
|
+
const hostPort = config.hostPort ?? internalPort;
|
|
87
|
+
const env = config.env ?? {};
|
|
88
|
+
// Create container config
|
|
89
|
+
const containerConfig = {
|
|
90
|
+
image: config.image,
|
|
91
|
+
ports: [{ internal: internalPort, external: hostPort }],
|
|
92
|
+
env,
|
|
93
|
+
...(config.networks !== undefined && { networks: config.networks }),
|
|
94
|
+
...(config.bindings !== undefined && { bindings: config.bindings }),
|
|
95
|
+
};
|
|
96
|
+
// Create the container
|
|
97
|
+
const container = yield* Container(name, containerConfig, docker);
|
|
98
|
+
// Build connection string
|
|
99
|
+
const connectionString = buildConnectionString(dbType, 'localhost', hostPort, env);
|
|
100
|
+
// Return enhanced resource
|
|
101
|
+
const dbResource = {
|
|
102
|
+
...container,
|
|
103
|
+
connectionString,
|
|
104
|
+
port: internalPort,
|
|
105
|
+
hostPort,
|
|
106
|
+
};
|
|
107
|
+
return dbResource;
|
|
108
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @harpoon/core
|
|
3
|
+
*
|
|
4
|
+
* Infrastructure as Code for Docker testing environments.
|
|
5
|
+
*
|
|
6
|
+
* Simple Promise-based API:
|
|
7
|
+
*
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { Network, Container, database } from '@harpoon/core';
|
|
10
|
+
*
|
|
11
|
+
* const network = await Network("my-net");
|
|
12
|
+
* const db = await database("postgres", { image: "postgres:16" });
|
|
13
|
+
* const app = await Container("app", { image: "my-app" });
|
|
14
|
+
*
|
|
15
|
+
* await app.destroy();
|
|
16
|
+
* await db.destroy();
|
|
17
|
+
* await network.destroy();
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Resources:
|
|
21
|
+
* - Network: Docker network lifecycle management
|
|
22
|
+
* - Container: Docker container lifecycle with binding support
|
|
23
|
+
* - database: Database container helper with connection strings
|
|
24
|
+
* - Image: Docker image building with pluggable strategies
|
|
25
|
+
*
|
|
26
|
+
* Bindings:
|
|
27
|
+
* - Binding interface for env var injection and lifecycle hooks
|
|
28
|
+
* - BuildBinding interface for Dockerfile transformations
|
|
29
|
+
*/
|
|
30
|
+
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 './api';
|
|
31
|
+
export type { Binding, BuildBinding, BindingsEnv, FlatBindingsEnv, } from './bindings';
|
|
32
|
+
export { isBuildBinding, mergeBindingsEnv, createEnvBinding, } from './bindings';
|
|
33
|
+
export { HarpoonError, NetworkError, ImageError, ContainerError, ScopeError, BindingError, toHarpoonError, asCause, isHarpoonError, isNetworkError, isImageError, isContainerError, isScopeError, isBindingError, } from './errors';
|
|
34
|
+
export type { HarpoonApiError } from './errors';
|
|
35
|
+
export { buildStrategyRegistry, registerBuildStrategy, getBuildStrategy, listBuildStrategies, standardStrategy, BuildStrategyError, } from './build-strategies';
|
|
36
|
+
export type { BuildStrategy, BuildStrategyInput, BuildContext, BuildStrategyRegistry, } from './build-strategies';
|
|
37
|
+
export { configPatcherRegistry, registerConfigPatcher, getConfigPatcher, listConfigPatchers, createPatcherChain, ConfigPatchError, } from './config-patchers';
|
|
38
|
+
export type { ConfigPatcher, PatchContext, PatchResult, ConfigPatcherRegistry, PatcherChain, } from './config-patchers';
|
|
39
|
+
export { transformerRegistry, registerTransformer, getTransformer, listTransformers, getTransformersForType, createDefaultPipeline, createPipelineWithTransformers, parseDockerfile, parseDockerfileEffect, serializeDockerfile, createPipeline, transformDockerfile, replaceInstruction, splitInstruction, argsContain, getArg, TransformerError, } from './dockerfile-transformers';
|
|
40
|
+
export type { InstructionTransformer, DockerfileInstruction, TransformContext, TransformerRegistry, TransformPipeline, TransformResult, } from './dockerfile-transformers';
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,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,OAAO,CAAC;AAIf,YAAY,EACV,OAAO,EACP,YAAY,EACZ,WAAW,EACX,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAIpB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,UAAU,EACV,YAAY,EACZ,cAAc,EACd,OAAO,EACP,cAAc,EACd,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,cAAc,GACf,MAAM,UAAU,CAAC;AAElB,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAIhD,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,8BAA8B,EAC9B,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,WAAW,EACX,MAAM,EACN,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EACV,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,GAChB,MAAM,2BAA2B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @harpoon/core
|
|
3
|
+
*
|
|
4
|
+
* Infrastructure as Code for Docker testing environments.
|
|
5
|
+
*
|
|
6
|
+
* Simple Promise-based API:
|
|
7
|
+
*
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { Network, Container, database } from '@harpoon/core';
|
|
10
|
+
*
|
|
11
|
+
* const network = await Network("my-net");
|
|
12
|
+
* const db = await database("postgres", { image: "postgres:16" });
|
|
13
|
+
* const app = await Container("app", { image: "my-app" });
|
|
14
|
+
*
|
|
15
|
+
* await app.destroy();
|
|
16
|
+
* await db.destroy();
|
|
17
|
+
* await network.destroy();
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Resources:
|
|
21
|
+
* - Network: Docker network lifecycle management
|
|
22
|
+
* - Container: Docker container lifecycle with binding support
|
|
23
|
+
* - database: Database container helper with connection strings
|
|
24
|
+
* - Image: Docker image building with pluggable strategies
|
|
25
|
+
*
|
|
26
|
+
* Bindings:
|
|
27
|
+
* - Binding interface for env var injection and lifecycle hooks
|
|
28
|
+
* - BuildBinding interface for Dockerfile transformations
|
|
29
|
+
*/
|
|
30
|
+
// ============ Promise-based Public API ============
|
|
31
|
+
export {
|
|
32
|
+
// Resource constructors
|
|
33
|
+
Network, Container, database, Image,
|
|
34
|
+
// Docker client management
|
|
35
|
+
setDocker, resetDocker, destroyAll, } from './api';
|
|
36
|
+
export { isBuildBinding, mergeBindingsEnv, createEnvBinding, } from './bindings';
|
|
37
|
+
// ============ Errors ============
|
|
38
|
+
export { HarpoonError, NetworkError, ImageError, ContainerError, ScopeError, BindingError, toHarpoonError, asCause, isHarpoonError, isNetworkError, isImageError, isContainerError, isScopeError, isBindingError, } from './errors';
|
|
39
|
+
// ============ Build Strategies (Plugin System) ============
|
|
40
|
+
export { buildStrategyRegistry, registerBuildStrategy, getBuildStrategy, listBuildStrategies, standardStrategy, BuildStrategyError, } from './build-strategies';
|
|
41
|
+
// ============ Config Patchers (Plugin System) ============
|
|
42
|
+
export { configPatcherRegistry, registerConfigPatcher, getConfigPatcher, listConfigPatchers, createPatcherChain, ConfigPatchError, } from './config-patchers';
|
|
43
|
+
// ============ Dockerfile Transformers (Plugin System) ============
|
|
44
|
+
export { transformerRegistry, registerTransformer, getTransformer, listTransformers, getTransformersForType, createDefaultPipeline, createPipelineWithTransformers, parseDockerfile, parseDockerfileEffect, serializeDockerfile, createPipeline, transformDockerfile, replaceInstruction, splitInstruction, argsContain, getArg, TransformerError, } from './dockerfile-transformers';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Container Resource Module
|
|
3
|
+
*
|
|
4
|
+
* Manages Docker container lifecycle using Effect's acquireRelease pattern.
|
|
5
|
+
* Ensures containers are always cleaned up, even during interruption.
|
|
6
|
+
*
|
|
7
|
+
* Supports bindings for environment variable injection and lifecycle hooks.
|
|
8
|
+
*/
|
|
9
|
+
import { Effect, Scope } from 'effect';
|
|
10
|
+
import Docker from 'dockerode';
|
|
11
|
+
import type { Binding } from '../bindings/types';
|
|
12
|
+
export interface PortMapping {
|
|
13
|
+
internal: number;
|
|
14
|
+
external: number;
|
|
15
|
+
}
|
|
16
|
+
export interface ContainerConfig {
|
|
17
|
+
image: string;
|
|
18
|
+
networks?: Array<{
|
|
19
|
+
name: string;
|
|
20
|
+
}>;
|
|
21
|
+
ports?: PortMapping[];
|
|
22
|
+
env?: Record<string, string>;
|
|
23
|
+
cmd?: string[];
|
|
24
|
+
/** Bindings that provide env vars and lifecycle hooks */
|
|
25
|
+
bindings?: Record<string, Binding>;
|
|
26
|
+
}
|
|
27
|
+
export interface ShutdownMetadata {
|
|
28
|
+
signalCount: number;
|
|
29
|
+
graceful: boolean;
|
|
30
|
+
timeTakenMs: number;
|
|
31
|
+
signal: string;
|
|
32
|
+
timeoutMs: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ContainerResource {
|
|
35
|
+
readonly id: string;
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly waitForLog: (pattern: string | RegExp, timeoutMs?: number) => Effect.Effect<void, Error>;
|
|
38
|
+
readonly stopGracefully: (signal?: string, timeoutMs?: number) => Effect.Effect<ShutdownMetadata, Error>;
|
|
39
|
+
readonly getIp: (networkName: string) => Effect.Effect<string, Error>;
|
|
40
|
+
}
|
|
41
|
+
export declare const Container: (resourceId: string, config: ContainerConfig, docker: Docker) => Effect.Effect<ContainerResource, Error, Scope.Scope>;
|
|
42
|
+
//# sourceMappingURL=container.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/resources/container.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,EAAkB,MAAM,QAAQ,CAAC;AACvD,OAAO,MAAM,MAAM,WAAW,CAAC;AAE/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAGjD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnC,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,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,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,CACnB,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,SAAS,CAAC,EAAE,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,CACvB,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CACvE;AAgED,eAAO,MAAM,SAAS,GACpB,YAAY,MAAM,EAClB,QAAQ,eAAe,EACvB,QAAQ,MAAM,KACb,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAsSnD,CAAC"}
|