@bojanrajkovic/containerfile-ts 0.0.1 → 1.0.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/README.md CHANGED
@@ -1,45 +1,157 @@
1
- # @bojanrajkovic/containerfile-ts
1
+ # containerfile-ts
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
3
+ [![CI](https://github.com/bojanrajkovic/containerfile-ts/actions/workflows/ci.yml/badge.svg)](https://github.com/bojanrajkovic/containerfile-ts/actions/workflows/ci.yml)
4
+ [![npm version](https://badge.fury.io/js/%40bojanrajkovic%2Fcontainerfile-ts.svg)](https://www.npmjs.com/package/@bojanrajkovic/containerfile-ts)
5
+
6
+ Type-safe Dockerfile/Containerfile generation with declarative TypeScript, inspired by [gha-ts](https://github.com/JLarky/gha-ts).
7
+
8
+ > **Note:** This is a vibe-coded library, built quickly with AI assistance as an experiment in declarative container definitions. It works, but take it in that spirit. PRs welcome if you find rough edges!
9
+
10
+ ## Installation
11
+
12
+ **Stable release (npm):**
13
+
14
+ ```bash
15
+ npm install @bojanrajkovic/containerfile-ts
16
+ # or
17
+ pnpm add @bojanrajkovic/containerfile-ts
18
+ # or
19
+ yarn add @bojanrajkovic/containerfile-ts
20
+ ```
21
+
22
+ **Alpha releases (GitHub Packages):**
23
+
24
+ To install pre-release versions from feature branches:
25
+
26
+ ```bash
27
+ # Configure npm to use GitHub Package Registry for @bojanrajkovic scope
28
+ echo "@bojanrajkovic:registry=https://npm.pkg.github.com" >> .npmrc
29
+
30
+ # Install specific alpha version
31
+ pnpm add @bojanrajkovic/containerfile-ts@1.0.0-branch-name.1
32
+ ```
33
+
34
+ **Note:** GitHub Package Registry requires authentication. See [GitHub Packages documentation](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry#authenticating-to-github-packages) for setup.
4
35
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
36
+ ## Usage
6
37
 
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
38
+ ### Simple Dockerfile
8
39
 
9
- ## Purpose
40
+ ```typescript
41
+ import { containerfile, from, workdir, copy, run, expose, cmd, render } from '@bojanrajkovic/containerfile-ts';
10
42
 
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@bojanrajkovic/containerfile-ts`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
43
+ const dockerfile = containerfile({
44
+ instructions: [
45
+ from('node:20-alpine'),
46
+ workdir('/app'),
47
+ copy('package*.json', '.'),
48
+ run('npm ci'),
49
+ copy('.', '.'),
50
+ expose(3000),
51
+ cmd(['node', 'dist/index.js']),
52
+ ],
53
+ });
15
54
 
16
- ## What is OIDC Trusted Publishing?
55
+ console.log(render(dockerfile));
56
+ ```
17
57
 
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
58
+ Output:
19
59
 
20
- ## Setup Instructions
60
+ ```dockerfile
61
+ FROM node:20-alpine
62
+ WORKDIR /app
63
+ COPY package*.json .
64
+ RUN npm ci
65
+ COPY . .
66
+ EXPOSE 3000
67
+ CMD ["node", "dist/index.js"]
68
+ ```
21
69
 
22
- To properly configure OIDC trusted publishing for this package:
70
+ ### Multi-Stage Build
23
71
 
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
72
+ ```typescript
73
+ import { containerfile, stage, from, workdir, copy, run, cmd, render } from '@bojanrajkovic/containerfile-ts';
28
74
 
29
- ## DO NOT USE THIS PACKAGE
75
+ const dockerfile = containerfile({
76
+ stages: [
77
+ stage('builder', [
78
+ from('node:20', { as: 'builder' }),
79
+ workdir('/app'),
80
+ copy('package*.json', '.'),
81
+ run('npm ci'),
82
+ copy('.', '.'),
83
+ run('npm run build'),
84
+ ]),
85
+ stage('runtime', [
86
+ from('node:20-alpine', { as: 'runtime' }),
87
+ workdir('/app'),
88
+ copy('/app/dist', './dist', { from: 'builder' }),
89
+ cmd(['node', 'dist/index.js']),
90
+ ]),
91
+ ],
92
+ });
30
93
 
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
94
+ console.log(render(dockerfile));
95
+ ```
36
96
 
37
- ## More Information
97
+ ## API Reference
38
98
 
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
99
+ ### Factory Functions
42
100
 
43
- ---
101
+ | Function | Description |
102
+ |----------|-------------|
103
+ | `from(image, options?)` | FROM instruction |
104
+ | `run(command)` | RUN instruction (string or exec form) |
105
+ | `copy(src, dest, options?)` | COPY instruction |
106
+ | `add(src, dest, options?)` | ADD instruction |
107
+ | `workdir(path)` | WORKDIR instruction |
108
+ | `env(key, value)` | ENV instruction |
109
+ | `expose(port, options?)` | EXPOSE instruction |
110
+ | `cmd(command)` | CMD instruction (exec form) |
111
+ | `entrypoint(command)` | ENTRYPOINT instruction (exec form) |
112
+ | `arg(name, options?)` | ARG instruction |
113
+ | `label(key, value)` | LABEL instruction |
114
+ | `stage(name, instructions)` | Named stage for multi-stage builds |
115
+ | `containerfile(def)` | Create containerfile definition |
44
116
 
45
- **Maintained for OIDC setup purposes only**
117
+ ### Rendering
118
+
119
+ | Function | Description |
120
+ |----------|-------------|
121
+ | `render(containerfile)` | Render to Dockerfile string |
122
+
123
+ ## Options
124
+
125
+ ### FromOptions
126
+
127
+ - `as?: string` - Stage name (AS clause)
128
+ - `platform?: string` - Target platform
129
+
130
+ ### CopyOptions
131
+
132
+ - `from?: string` - Source stage name
133
+ - `chown?: string` - Change ownership
134
+ - `chmod?: string` - Change permissions
135
+
136
+ ### AddOptions
137
+
138
+ - `chown?: string` - Change ownership
139
+ - `chmod?: string` - Change permissions
140
+
141
+ ### ExposeOptions
142
+
143
+ - `protocol?: 'tcp' | 'udp' | 'sctp'` - Port protocol (default: tcp)
144
+
145
+ ### ArgOptions
146
+
147
+ - `defaultValue?: string` - Default value for build arg
148
+
149
+ ## Changelog
150
+
151
+ See [CHANGELOG.md](./CHANGELOG.md) for release history and changes.
152
+
153
+ **Note:** The changelog is automatically generated from conventional commit messages.
154
+
155
+ ## License
156
+
157
+ MIT
@@ -0,0 +1,5 @@
1
+ export type { Instruction, FromInstruction, RunInstruction, CopyInstruction, AddInstruction, WorkdirInstruction, EnvInstruction, ExposeInstruction, CmdInstruction, EntrypointInstruction, ArgInstruction, LabelInstruction, Containerfile, Stage, FromOptions, CopyOptions, AddOptions, ExposeOptions, ArgOptions, } from './types.js';
2
+ export { from, run, copy, add, workdir, env, expose, cmd, entrypoint, arg, label, containerfile, } from './instructions.js';
3
+ export { stage } from './stage.js';
4
+ export { render } from './render.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,WAAW,EACX,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,KAAK,EACL,WAAW,EACX,WAAW,EACX,UAAU,EACV,aAAa,EACb,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,IAAI,EACJ,GAAG,EACH,IAAI,EACJ,GAAG,EACH,OAAO,EACP,GAAG,EACH,MAAM,EACN,GAAG,EACH,UAAU,EACV,GAAG,EACH,KAAK,EACL,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ // pattern: Functional Core
2
+ // Entry point for containerfile-ts library
3
+ export { from, run, copy, add, workdir, env, expose, cmd, entrypoint, arg, label, containerfile, } from './instructions.js';
4
+ export { stage } from './stage.js';
5
+ export { render } from './render.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,2CAA2C;AAwB3C,OAAO,EACL,IAAI,EACJ,GAAG,EACH,IAAI,EACJ,GAAG,EACH,OAAO,EACP,GAAG,EACH,MAAM,EACN,GAAG,EACH,UAAU,EACV,GAAG,EACH,KAAK,EACL,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,65 @@
1
+ import type { FromInstruction, RunInstruction, CopyInstruction, AddInstruction, WorkdirInstruction, EnvInstruction, ExposeInstruction, CmdInstruction, EntrypointInstruction, ArgInstruction, LabelInstruction, Containerfile, FromOptions, CopyOptions, AddOptions, ExposeOptions, ArgOptions } from './types.js';
2
+ /**
3
+ * Creates a FROM instruction
4
+ */
5
+ export declare function from(image: string, options?: FromOptions): FromInstruction;
6
+ /**
7
+ * Creates a RUN instruction
8
+ */
9
+ export declare function run(command: string | ReadonlyArray<string>): RunInstruction;
10
+ /**
11
+ * Creates a COPY instruction
12
+ *
13
+ * @param src - Source file path or array of source file paths
14
+ * @param dest - Destination path in the container
15
+ * @param options - Optional COPY options (from, chown, chmod)
16
+ */
17
+ export declare function copy(src: string | ReadonlyArray<string>, dest: string, options?: CopyOptions): CopyInstruction;
18
+ /**
19
+ * Creates an ADD instruction
20
+ *
21
+ * @param src - Source file path, URL, or array of source paths/URLs
22
+ * @param dest - Destination path in the container
23
+ * @param options - Optional ADD options (chown, chmod)
24
+ */
25
+ export declare function add(src: string | ReadonlyArray<string>, dest: string, options?: AddOptions): AddInstruction;
26
+ /**
27
+ * Creates a WORKDIR instruction
28
+ */
29
+ export declare function workdir(path: string): WorkdirInstruction;
30
+ /**
31
+ * Creates an ENV instruction
32
+ */
33
+ export declare function env(key: string, value: string): EnvInstruction;
34
+ /**
35
+ * Creates an EXPOSE instruction
36
+ *
37
+ * @param port - Port number or port range object with start and end
38
+ * @param options - Optional EXPOSE options (protocol: tcp, udp, or sctp)
39
+ */
40
+ export declare function expose(port: number | {
41
+ readonly start: number;
42
+ readonly end: number;
43
+ }, options?: ExposeOptions): ExposeInstruction;
44
+ /**
45
+ * Creates a CMD instruction
46
+ */
47
+ export declare function cmd(command: ReadonlyArray<string>): CmdInstruction;
48
+ /**
49
+ * Creates an ENTRYPOINT instruction
50
+ */
51
+ export declare function entrypoint(command: ReadonlyArray<string>): EntrypointInstruction;
52
+ /**
53
+ * Creates an ARG instruction
54
+ */
55
+ export declare function arg(name: string, options?: ArgOptions): ArgInstruction;
56
+ /**
57
+ * Creates a LABEL instruction
58
+ */
59
+ export declare function label(key: string, value: string): LabelInstruction;
60
+ /**
61
+ * Identity function for creating a Containerfile definition
62
+ * Provides type safety and IDE autocompletion
63
+ */
64
+ export declare function containerfile(def: Containerfile): Containerfile;
65
+ //# sourceMappingURL=instructions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../src/instructions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,WAAW,EACX,UAAU,EACV,aAAa,EACb,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,eAAe,CAO1E;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,cAAc,CAK3E;AAED;;;;;;GAMG;AACH,wBAAgB,IAAI,CAClB,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,EACnC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,WAAW,GACpB,eAAe,CASjB;AAED;;;;;;GAMG;AACH,wBAAgB,GAAG,CACjB,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,EACnC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,UAAU,GACnB,cAAc,CAQhB;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAKxD;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAM9D;AAcD;;;;;GAKG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAC/D,OAAO,CAAC,EAAE,aAAa,GACtB,iBAAiB,CAiBnB;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,cAAc,CAKlE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,qBAAqB,CAKhF;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,cAAc,CAMtE;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAMlE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,aAAa,CAE/D"}
@@ -0,0 +1,153 @@
1
+ // pattern: Functional Core
2
+ /**
3
+ * Creates a FROM instruction
4
+ */
5
+ export function from(image, options) {
6
+ return {
7
+ type: 'FROM',
8
+ image,
9
+ as: options?.as ?? null,
10
+ platform: options?.platform ?? null,
11
+ };
12
+ }
13
+ /**
14
+ * Creates a RUN instruction
15
+ */
16
+ export function run(command) {
17
+ return {
18
+ type: 'RUN',
19
+ command,
20
+ };
21
+ }
22
+ /**
23
+ * Creates a COPY instruction
24
+ *
25
+ * @param src - Source file path or array of source file paths
26
+ * @param dest - Destination path in the container
27
+ * @param options - Optional COPY options (from, chown, chmod)
28
+ */
29
+ export function copy(src, dest, options) {
30
+ return {
31
+ type: 'COPY',
32
+ src,
33
+ dest,
34
+ from: options?.from ?? null,
35
+ chown: options?.chown ?? null,
36
+ chmod: options?.chmod ?? null,
37
+ };
38
+ }
39
+ /**
40
+ * Creates an ADD instruction
41
+ *
42
+ * @param src - Source file path, URL, or array of source paths/URLs
43
+ * @param dest - Destination path in the container
44
+ * @param options - Optional ADD options (chown, chmod)
45
+ */
46
+ export function add(src, dest, options) {
47
+ return {
48
+ type: 'ADD',
49
+ src,
50
+ dest,
51
+ chown: options?.chown ?? null,
52
+ chmod: options?.chmod ?? null,
53
+ };
54
+ }
55
+ /**
56
+ * Creates a WORKDIR instruction
57
+ */
58
+ export function workdir(path) {
59
+ return {
60
+ type: 'WORKDIR',
61
+ path,
62
+ };
63
+ }
64
+ /**
65
+ * Creates an ENV instruction
66
+ */
67
+ export function env(key, value) {
68
+ return {
69
+ type: 'ENV',
70
+ key,
71
+ value,
72
+ };
73
+ }
74
+ /**
75
+ * Validates a port number is within the valid range (0-65535)
76
+ */
77
+ function validatePort(port, label) {
78
+ if (!Number.isInteger(port)) {
79
+ throw new Error(`invalid ${label}: ${port} (must be an integer)`);
80
+ }
81
+ if (port < 0 || port > 65535) {
82
+ throw new Error(`invalid ${label}: ${port} (must be 0-65535)`);
83
+ }
84
+ }
85
+ /**
86
+ * Creates an EXPOSE instruction
87
+ *
88
+ * @param port - Port number or port range object with start and end
89
+ * @param options - Optional EXPOSE options (protocol: tcp, udp, or sctp)
90
+ */
91
+ export function expose(port, options) {
92
+ if (typeof port === 'number') {
93
+ validatePort(port, 'port number');
94
+ }
95
+ else {
96
+ validatePort(port.start, 'port range start');
97
+ validatePort(port.end, 'port range end');
98
+ if (port.start > port.end) {
99
+ throw new Error(`invalid port range: start (${port.start}) must be <= end (${port.end})`);
100
+ }
101
+ }
102
+ return {
103
+ type: 'EXPOSE',
104
+ port,
105
+ protocol: options?.protocol ?? 'tcp',
106
+ };
107
+ }
108
+ /**
109
+ * Creates a CMD instruction
110
+ */
111
+ export function cmd(command) {
112
+ return {
113
+ type: 'CMD',
114
+ command,
115
+ };
116
+ }
117
+ /**
118
+ * Creates an ENTRYPOINT instruction
119
+ */
120
+ export function entrypoint(command) {
121
+ return {
122
+ type: 'ENTRYPOINT',
123
+ command,
124
+ };
125
+ }
126
+ /**
127
+ * Creates an ARG instruction
128
+ */
129
+ export function arg(name, options) {
130
+ return {
131
+ type: 'ARG',
132
+ name,
133
+ defaultValue: options?.defaultValue ?? null,
134
+ };
135
+ }
136
+ /**
137
+ * Creates a LABEL instruction
138
+ */
139
+ export function label(key, value) {
140
+ return {
141
+ type: 'LABEL',
142
+ key,
143
+ value,
144
+ };
145
+ }
146
+ /**
147
+ * Identity function for creating a Containerfile definition
148
+ * Provides type safety and IDE autocompletion
149
+ */
150
+ export function containerfile(def) {
151
+ return def;
152
+ }
153
+ //# sourceMappingURL=instructions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instructions.js","sourceRoot":"","sources":["../src/instructions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Instruction, Containerfile } from './types.js';
2
+ /**
3
+ * Renders a single instruction to its Dockerfile string representation
4
+ */
5
+ export declare function renderInstruction(instruction: Instruction): string;
6
+ /**
7
+ * Renders a Containerfile to its Dockerfile string representation
8
+ * Handles both single-stage and multi-stage builds
9
+ */
10
+ export declare function render(containerfile: Containerfile): string;
11
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EAad,MAAM,YAAY,CAAC;AAmHpB;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAGlE;AAoBD;;;GAGG;AACH,wBAAgB,MAAM,CAAC,aAAa,EAAE,aAAa,GAAG,MAAM,CAU3D"}
package/dist/render.js ADDED
@@ -0,0 +1,135 @@
1
+ // pattern: Functional Core
2
+ /**
3
+ * Formats an array as a JSON array with proper spacing after commas
4
+ */
5
+ function formatArray(arr) {
6
+ return '[' + arr.map(item => JSON.stringify(item)).join(', ') + ']';
7
+ }
8
+ function renderFrom(instruction) {
9
+ let line = 'FROM';
10
+ if (instruction.platform !== null) {
11
+ line += ` --platform=${instruction.platform}`;
12
+ }
13
+ line += ` ${instruction.image}`;
14
+ if (instruction.as !== null) {
15
+ line += ` AS ${instruction.as}`;
16
+ }
17
+ return line;
18
+ }
19
+ function renderRun(instruction) {
20
+ if (typeof instruction.command === 'string') {
21
+ return `RUN ${instruction.command}`;
22
+ }
23
+ return `RUN ${formatArray(instruction.command)}`;
24
+ }
25
+ function renderCopy(instruction) {
26
+ let line = 'COPY';
27
+ if (instruction.from !== null) {
28
+ line += ` --from=${instruction.from}`;
29
+ }
30
+ if (instruction.chown !== null) {
31
+ line += ` --chown=${instruction.chown}`;
32
+ }
33
+ if (instruction.chmod !== null) {
34
+ line += ` --chmod=${instruction.chmod}`;
35
+ }
36
+ const srcStr = typeof instruction.src === 'string'
37
+ ? instruction.src
38
+ : instruction.src.join(' ');
39
+ line += ` ${srcStr} ${instruction.dest}`;
40
+ return line;
41
+ }
42
+ function renderAdd(instruction) {
43
+ let line = 'ADD';
44
+ if (instruction.chown !== null) {
45
+ line += ` --chown=${instruction.chown}`;
46
+ }
47
+ if (instruction.chmod !== null) {
48
+ line += ` --chmod=${instruction.chmod}`;
49
+ }
50
+ const srcStr = typeof instruction.src === 'string'
51
+ ? instruction.src
52
+ : instruction.src.join(' ');
53
+ line += ` ${srcStr} ${instruction.dest}`;
54
+ return line;
55
+ }
56
+ function renderWorkdir(instruction) {
57
+ return `WORKDIR ${instruction.path}`;
58
+ }
59
+ function renderEnv(instruction) {
60
+ return `ENV ${instruction.key}=${instruction.value}`;
61
+ }
62
+ function renderExpose(instruction) {
63
+ const protocolSuffix = instruction.protocol === 'tcp' ? '' : `/${instruction.protocol}`;
64
+ const portStr = typeof instruction.port === 'number'
65
+ ? String(instruction.port)
66
+ : `${instruction.port.start}-${instruction.port.end}`;
67
+ return `EXPOSE ${portStr}${protocolSuffix}`;
68
+ }
69
+ function renderCmd(instruction) {
70
+ return `CMD ${formatArray(instruction.command)}`;
71
+ }
72
+ function renderEntrypoint(instruction) {
73
+ return `ENTRYPOINT ${formatArray(instruction.command)}`;
74
+ }
75
+ function renderArg(instruction) {
76
+ if (instruction.defaultValue !== null) {
77
+ return `ARG ${instruction.name}=${instruction.defaultValue}`;
78
+ }
79
+ return `ARG ${instruction.name}`;
80
+ }
81
+ function renderLabel(instruction) {
82
+ return `LABEL ${instruction.key}="${instruction.value}"`;
83
+ }
84
+ /**
85
+ * Renderer dispatch table - maps instruction type to render function
86
+ */
87
+ const renderers = {
88
+ FROM: renderFrom,
89
+ RUN: renderRun,
90
+ COPY: renderCopy,
91
+ ADD: renderAdd,
92
+ WORKDIR: renderWorkdir,
93
+ ENV: renderEnv,
94
+ EXPOSE: renderExpose,
95
+ CMD: renderCmd,
96
+ ENTRYPOINT: renderEntrypoint,
97
+ ARG: renderArg,
98
+ LABEL: renderLabel,
99
+ };
100
+ /**
101
+ * Renders a single instruction to its Dockerfile string representation
102
+ */
103
+ export function renderInstruction(instruction) {
104
+ const renderer = renderers[instruction.type];
105
+ return renderer(instruction);
106
+ }
107
+ /**
108
+ * Renders a Stage to its Dockerfile string representation
109
+ */
110
+ function renderStage(stageToRender) {
111
+ return stageToRender.instructions
112
+ .map(renderInstruction)
113
+ .join('\n');
114
+ }
115
+ /**
116
+ * Type guard for single-stage containerfile
117
+ */
118
+ function isSingleStage(containerfile) {
119
+ return 'instructions' in containerfile;
120
+ }
121
+ /**
122
+ * Renders a Containerfile to its Dockerfile string representation
123
+ * Handles both single-stage and multi-stage builds
124
+ */
125
+ export function render(containerfile) {
126
+ if (isSingleStage(containerfile)) {
127
+ return containerfile.instructions
128
+ .map(renderInstruction)
129
+ .join('\n');
130
+ }
131
+ return containerfile.stages
132
+ .map(renderStage)
133
+ .join('\n\n');
134
+ }
135
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Instruction, Stage } from './types.js';
2
+ /**
3
+ * Creates a named stage for multi-stage builds
4
+ */
5
+ export declare function stage(name: string, instructions: ReadonlyArray<Instruction>): Stage;
6
+ //# sourceMappingURL=stage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../src/stage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAErD;;GAEG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,KAAK,CAKnF"}
package/dist/stage.js ADDED
@@ -0,0 +1,11 @@
1
+ // pattern: Functional Core
2
+ /**
3
+ * Creates a named stage for multi-stage builds
4
+ */
5
+ export function stage(name, instructions) {
6
+ return {
7
+ name,
8
+ instructions,
9
+ };
10
+ }
11
+ //# sourceMappingURL=stage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage.js","sourceRoot":"","sources":["../src/stage.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAI3B;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,YAAwC;IAC1E,OAAO;QACL,IAAI;QACJ,YAAY;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * FROM instruction - specifies base image
3
+ */
4
+ export type FromInstruction = {
5
+ readonly type: 'FROM';
6
+ readonly image: string;
7
+ readonly as: string | null;
8
+ readonly platform: string | null;
9
+ };
10
+ /**
11
+ * RUN instruction - executes commands
12
+ */
13
+ export type RunInstruction = {
14
+ readonly type: 'RUN';
15
+ readonly command: string | ReadonlyArray<string>;
16
+ };
17
+ /**
18
+ * COPY instruction - copies files from build context or other stages
19
+ *
20
+ * @example
21
+ * Single source: `COPY file.txt /dest/`
22
+ * Multiple sources: `COPY file1.txt file2.txt /dest/`
23
+ *
24
+ * The `src` field supports both single file (string) and multiple files (ReadonlyArray<string>).
25
+ * When using an array, the final element in the container must be a directory for correct semantics.
26
+ */
27
+ export type CopyInstruction = {
28
+ readonly type: 'COPY';
29
+ readonly src: string | ReadonlyArray<string>;
30
+ readonly dest: string;
31
+ readonly from: string | null;
32
+ readonly chown: string | null;
33
+ readonly chmod: string | null;
34
+ };
35
+ /**
36
+ * ADD instruction - copies files with URL/archive support
37
+ *
38
+ * @example
39
+ * Single source: `ADD file.tar.gz /app/`
40
+ * Multiple sources: `ADD file1.txt file2.txt /app/`
41
+ * URL source: `ADD https://example.com/file.tar.gz /app/`
42
+ *
43
+ * The `src` field supports both single source (string) and multiple sources (ReadonlyArray<string>).
44
+ * Sources can be local files or URLs. When using an array, the final destination must be a directory.
45
+ */
46
+ export type AddInstruction = {
47
+ readonly type: 'ADD';
48
+ readonly src: string | ReadonlyArray<string>;
49
+ readonly dest: string;
50
+ readonly chown: string | null;
51
+ readonly chmod: string | null;
52
+ };
53
+ /**
54
+ * WORKDIR instruction - sets working directory
55
+ */
56
+ export type WorkdirInstruction = {
57
+ readonly type: 'WORKDIR';
58
+ readonly path: string;
59
+ };
60
+ /**
61
+ * ENV instruction - sets environment variables
62
+ */
63
+ export type EnvInstruction = {
64
+ readonly type: 'ENV';
65
+ readonly key: string;
66
+ readonly value: string;
67
+ };
68
+ /**
69
+ * EXPOSE instruction - documents exposed ports
70
+ *
71
+ * The `port` field supports both single ports and port ranges.
72
+ * Single port: `EXPOSE 8080/tcp`
73
+ * Port range: `EXPOSE 8080-8090/tcp`
74
+ *
75
+ * The `protocol` field supports TCP, UDP, and SCTP protocols.
76
+ * Examples:
77
+ * - TCP (default): `EXPOSE 8080/tcp`
78
+ * - UDP: `EXPOSE 5353/udp`
79
+ * - SCTP: `EXPOSE 132/sctp`
80
+ * - Port range with SCTP: `EXPOSE 8080-8090/sctp`
81
+ */
82
+ export type ExposeInstruction = {
83
+ readonly type: 'EXPOSE';
84
+ readonly port: number | {
85
+ readonly start: number;
86
+ readonly end: number;
87
+ };
88
+ readonly protocol: 'tcp' | 'udp' | 'sctp';
89
+ };
90
+ /**
91
+ * CMD instruction - default command
92
+ */
93
+ export type CmdInstruction = {
94
+ readonly type: 'CMD';
95
+ readonly command: ReadonlyArray<string>;
96
+ };
97
+ /**
98
+ * ENTRYPOINT instruction - container entrypoint
99
+ */
100
+ export type EntrypointInstruction = {
101
+ readonly type: 'ENTRYPOINT';
102
+ readonly command: ReadonlyArray<string>;
103
+ };
104
+ /**
105
+ * ARG instruction - build-time variable
106
+ */
107
+ export type ArgInstruction = {
108
+ readonly type: 'ARG';
109
+ readonly name: string;
110
+ readonly defaultValue: string | null;
111
+ };
112
+ /**
113
+ * LABEL instruction - metadata
114
+ */
115
+ export type LabelInstruction = {
116
+ readonly type: 'LABEL';
117
+ readonly key: string;
118
+ readonly value: string;
119
+ };
120
+ /**
121
+ * Discriminated union of all Dockerfile instructions
122
+ */
123
+ export type Instruction = FromInstruction | RunInstruction | CopyInstruction | AddInstruction | WorkdirInstruction | EnvInstruction | ExposeInstruction | CmdInstruction | EntrypointInstruction | ArgInstruction | LabelInstruction;
124
+ /**
125
+ * A named stage in a multi-stage build
126
+ */
127
+ export type Stage = {
128
+ readonly name: string;
129
+ readonly instructions: ReadonlyArray<Instruction>;
130
+ };
131
+ /**
132
+ * A Containerfile definition - either single-stage (instructions) or multi-stage (stages)
133
+ */
134
+ export type Containerfile = {
135
+ readonly instructions: ReadonlyArray<Instruction>;
136
+ } | {
137
+ readonly stages: ReadonlyArray<Stage>;
138
+ };
139
+ /**
140
+ * Options for the from() factory function
141
+ */
142
+ export type FromOptions = {
143
+ readonly as?: string;
144
+ readonly platform?: string;
145
+ };
146
+ /**
147
+ * Options for the copy() factory function
148
+ */
149
+ export type CopyOptions = {
150
+ readonly from?: string;
151
+ readonly chown?: string;
152
+ readonly chmod?: string;
153
+ };
154
+ /**
155
+ * Options for the add() factory function
156
+ */
157
+ export type AddOptions = {
158
+ readonly chown?: string;
159
+ readonly chmod?: string;
160
+ };
161
+ /**
162
+ * Options for the expose() factory function
163
+ */
164
+ export type ExposeOptions = {
165
+ readonly protocol?: 'tcp' | 'udp' | 'sctp';
166
+ };
167
+ /**
168
+ * Options for the arg() factory function
169
+ */
170
+ export type ArgOptions = {
171
+ readonly defaultValue?: string;
172
+ };
173
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ // pattern: Functional Core
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,2BAA2B"}
package/package.json CHANGED
@@ -1,10 +1,68 @@
1
1
  {
2
2
  "name": "@bojanrajkovic/containerfile-ts",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @bojanrajkovic/containerfile-ts",
3
+ "version": "1.0.0",
4
+ "description": "Type-safe Dockerfile/Containerfile generation with declarative TypeScript",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "typecheck": "tsc --noEmit",
20
+ "test": "vitest run",
21
+ "test:watch": "vitest",
22
+ "lint": "oxlint",
23
+ "lint:fix": "oxlint --fix",
24
+ "prepare": "husky"
25
+ },
26
+ "lint-staged": {
27
+ "*.ts": [
28
+ "oxlint --fix"
29
+ ]
30
+ },
5
31
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
32
+ "dockerfile",
33
+ "containerfile",
34
+ "docker",
35
+ "container",
36
+ "typescript",
37
+ "type-safe"
38
+ ],
39
+ "author": "Bojan Rajkovic",
40
+ "license": "MIT",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "https://github.com/bojanrajkovic/containerfile-ts.git"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "engines": {
49
+ "node": ">=20"
50
+ },
51
+ "devDependencies": {
52
+ "@commitlint/cli": "^20.1.0",
53
+ "@commitlint/config-conventional": "^20.1.0",
54
+ "@semantic-release/changelog": "^6.0.0",
55
+ "@semantic-release/commit-analyzer": "^11.0.0",
56
+ "@semantic-release/git": "^10.0.0",
57
+ "@semantic-release/github": "^9.0.0",
58
+ "@semantic-release/npm": "^11.0.0",
59
+ "@semantic-release/release-notes-generator": "^12.0.0",
60
+ "conventional-changelog-conventionalcommits": "^8.0.0",
61
+ "husky": "^9.1.0",
62
+ "lint-staged": "^15.2.0",
63
+ "oxlint": "^0.15.0",
64
+ "semantic-release": "^25.0.0",
65
+ "typescript": "^5.7.0",
66
+ "vitest": "^4.0.16"
67
+ }
10
68
  }