containless 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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +234 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config.d.ts +7 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +81 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/installer.d.ts +2 -0
  12. package/dist/installer.d.ts.map +1 -0
  13. package/dist/installer.js +237 -0
  14. package/dist/installer.js.map +1 -0
  15. package/dist/runner.d.ts +11 -0
  16. package/dist/runner.d.ts.map +1 -0
  17. package/dist/runner.js +88 -0
  18. package/dist/runner.js.map +1 -0
  19. package/dist/runtimes/go.d.ts +8 -0
  20. package/dist/runtimes/go.d.ts.map +1 -0
  21. package/dist/runtimes/go.js +44 -0
  22. package/dist/runtimes/go.js.map +1 -0
  23. package/dist/runtimes/index.d.ts +11 -0
  24. package/dist/runtimes/index.d.ts.map +1 -0
  25. package/dist/runtimes/index.js +55 -0
  26. package/dist/runtimes/index.js.map +1 -0
  27. package/dist/runtimes/java.d.ts +14 -0
  28. package/dist/runtimes/java.d.ts.map +1 -0
  29. package/dist/runtimes/java.js +49 -0
  30. package/dist/runtimes/java.js.map +1 -0
  31. package/dist/runtimes/node.d.ts +9 -0
  32. package/dist/runtimes/node.d.ts.map +1 -0
  33. package/dist/runtimes/node.js +45 -0
  34. package/dist/runtimes/node.js.map +1 -0
  35. package/dist/runtimes/python.d.ts +22 -0
  36. package/dist/runtimes/python.d.ts.map +1 -0
  37. package/dist/runtimes/python.js +115 -0
  38. package/dist/runtimes/python.js.map +1 -0
  39. package/dist/utils.d.ts +29 -0
  40. package/dist/utils.d.ts.map +1 -0
  41. package/dist/utils.js +170 -0
  42. package/dist/utils.js.map +1 -0
  43. package/package.json +67 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Anghelo Dearroz <anghelodechavezdearroz@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ <div align="center">
2
+
3
+ ![Containless Banner](.github/assets/banner.png)
4
+
5
+ # Containless
6
+
7
+ **Docker-like runtime isolation — without the container.**
8
+
9
+ Install and run Node.js, Python, Java, and Go locally inside your project folder, completely isolated from global installs.
10
+
11
+ [![npm version](https://img.shields.io/npm/v/containless.svg)](https://www.npmjs.com/package/containless)
12
+ [![license](https://img.shields.io/npm/l/containless.svg)](https://github.com/user/containless/blob/main/LICENSE)
13
+ [![node](https://img.shields.io/node/v/containless.svg)](https://nodejs.org)
14
+
15
+ </div>
16
+
17
+ ---
18
+
19
+ ## Why Containless?
20
+
21
+ Ever had a project that needs Node 18 while another needs Node 20? Or a Python project that conflicts with your system Python? **Containless** solves this by downloading runtimes directly into your project folder — no global installs, no version managers, no containers.
22
+
23
+ - 🎯 **Project-level isolation** — each project gets its own runtime
24
+ - 🚫 **Zero global pollution** — never touches your system PATH
25
+ - 📦 **Self-contained** — everything lives in `.containless/`
26
+ - ⚡ **Blazing fast** — cached downloads, no container overhead
27
+ - 🔒 **Reproducible** — lock runtime versions in `containless.json`
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ # Install globally
33
+ npm install -g containless
34
+
35
+ # Or use directly with npx
36
+ npx containless
37
+ ```
38
+
39
+ ## Quick Start
40
+
41
+ 1. Create a `containless.json` in your project root:
42
+
43
+ ```json
44
+ {
45
+ "runtime": {
46
+ "node": "18.17.0"
47
+ },
48
+ "start": "npm run dev"
49
+ }
50
+ ```
51
+
52
+ 2. Run your project:
53
+
54
+ ```bash
55
+ containless run
56
+ ```
57
+
58
+ That's it! Containless will download Node.js 18.17.0 into `.containless/runtimes/`, then run `npm run dev` using that local Node — completely ignoring any globally installed version.
59
+
60
+ ## Commands
61
+
62
+ ### `containless run`
63
+
64
+ Reads `containless.json`, ensures all defined runtimes are installed locally, then executes the `start` command.
65
+
66
+ ```bash
67
+ containless run
68
+ ```
69
+
70
+ ### `containless install <runtime@version>`
71
+
72
+ Download and install a specific runtime into `.containless/runtimes/`.
73
+
74
+ ```bash
75
+ containless install node@18.17.0
76
+ containless install python@3.11.0
77
+ containless install java@21
78
+ containless install go@1.21.0
79
+ ```
80
+
81
+ ### `containless clean`
82
+
83
+ Delete all locally installed runtimes.
84
+
85
+ ```bash
86
+ # Remove runtimes only
87
+ containless clean
88
+
89
+ # Remove everything (runtimes + cache)
90
+ containless clean --all
91
+ ```
92
+
93
+ ### `containless info`
94
+
95
+ Show a table of all locally installed runtimes with version and binary path.
96
+
97
+ ```bash
98
+ containless info
99
+ ```
100
+
101
+ Example output:
102
+ ```
103
+ ┌─────────┬─────────┬────────────────────────────────────────────────┬──────────┐
104
+ │ Runtime │ Version │ Binary Path │ Status │
105
+ ├─────────┼─────────┼────────────────────────────────────────────────┼──────────┤
106
+ │ node │ 18.17.0 │ .containless/runtimes/node-18.17.0/bin/node │ ✔ ready │
107
+ │ python │ 3.11.0 │ .containless/runtimes/python-3.11.0/bin/python│ ✔ ready │
108
+ └─────────┴─────────┴────────────────────────────────────────────────┴──────────┘
109
+ ```
110
+
111
+ ## Configuration
112
+
113
+ ### `containless.json`
114
+
115
+ | Field | Type | Description |
116
+ | --------- | ------------------------- | ---------------------------------------------- |
117
+ | `runtime` | `Record<string, string>` | Map of runtime names to version strings |
118
+ | `start` | `string` | Command to run when executing `containless run` |
119
+
120
+ #### Full example
121
+
122
+ ```json
123
+ {
124
+ "runtime": {
125
+ "node": "18.17.0",
126
+ "python": "3.11.0",
127
+ "java": "21",
128
+ "go": "1.21.0"
129
+ },
130
+ "start": "npm run dev"
131
+ }
132
+ ```
133
+
134
+ ## Supported Runtimes
135
+
136
+ | Runtime | Source | Platforms |
137
+ | ---------- | ------------------------------------- | ------------------------------------- |
138
+ | **Node.js**| [nodejs.org](https://nodejs.org) | linux-x64, darwin-x64, darwin-arm64, win32-x64 |
139
+ | **Python** | [python-build-standalone](https://github.com/indygreg/python-build-standalone) | linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64 |
140
+ | **Java** | [Adoptium](https://adoptium.net) | linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64 |
141
+ | **Go** | [go.dev](https://go.dev) | linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64 |
142
+
143
+ ## How It Works
144
+
145
+ 1. **Download** — Runtime archives are fetched from official sources
146
+ 2. **Cache** — Archives are stored in `.containless/cache/` to avoid re-downloading
147
+ 3. **Extract** — Runtimes are extracted to `.containless/runtimes/<name>-<version>/`
148
+ 4. **Inject** — When running commands, the local runtime's `bin/` directory is prepended to `PATH`
149
+ 5. **Isolate** — Your command runs with the local runtime, completely ignoring global installs
150
+
151
+ ```
152
+ your-project/
153
+ ├── containless.json
154
+ ├── .containless/
155
+ │ ├── cache/ ← downloaded archives
156
+ │ └── runtimes/
157
+ │ ├── node-18.17.0/ ← extracted Node.js
158
+ │ │ └── bin/node
159
+ │ └── python-3.11.0/ ← extracted Python
160
+ │ └── bin/python3
161
+ ├── src/
162
+ └── package.json
163
+ ```
164
+
165
+ ## .gitignore
166
+
167
+ Add `.containless/` to your `.gitignore` — runtime binaries should not be committed:
168
+
169
+ ```gitignore
170
+ .containless/
171
+ ```
172
+
173
+ Containless will warn you if this entry is missing.
174
+
175
+ ## Roadmap
176
+
177
+ Curious about what's next? Check out the [ROADMAP.md](./ROADMAP.md) for future planned features like broader runtime support, shell hooks, and intelligent lockfile parsing.
178
+
179
+ ## Contributing
180
+
181
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup, build instructions, and how to submit pull requests.
182
+
183
+ ## License
184
+
185
+ [MIT](./LICENSE) © Anghelo Dearroz
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,234 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const commander_1 = require("commander");
41
+ const chalk_1 = __importDefault(require("chalk"));
42
+ const fs = __importStar(require("fs-extra"));
43
+ const path = __importStar(require("path"));
44
+ const cli_table3_1 = __importDefault(require("cli-table3"));
45
+ const config_1 = require("./config");
46
+ const installer_1 = require("./installer");
47
+ const runner_1 = require("./runner");
48
+ const utils_1 = require("./utils");
49
+ const index_1 = require("./runtimes/index");
50
+ // ── ASCII Banner ────────────────────────────────────────────────────────────
51
+ const BANNER = chalk_1.default.bold.cyan(`
52
+ ██████╗ ██████╗ ███╗ ██╗████████╗ █████╗ ██╗███╗ ██╗██╗ ███████╗███████╗███████╗
53
+ ██╔════╝██╔═══██╗████╗ ██║╚══██╔══╝██╔══██╗██║████╗ ██║██║ ██╔════╝██╔════╝██╔════╝
54
+ ██║ ██║ ██║██╔██╗ ██║ ██║ ███████║██║██╔██╗ ██║██║ █████╗ ███████╗███████╗
55
+ ██║ ██║ ██║██║╚██╗██║ ██║ ██╔══██║██║██║╚██╗██║██║ ██╔══╝ ╚════██║╚════██║
56
+ ╚██████╗╚██████╔╝██║ ╚████║ ██║ ██║ ██║██║██║ ╚████║███████╗███████╗███████║███████║
57
+ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝╚══════╝╚══════╝
58
+ `);
59
+ // ── Program Setup ───────────────────────────────────────────────────────────
60
+ const program = new commander_1.Command();
61
+ program
62
+ .name('containless')
63
+ .description(chalk_1.default.dim('Docker-like runtime isolation — install and run runtimes locally, no containers needed.'))
64
+ .version('0.1.0')
65
+ .addHelpText('before', BANNER);
66
+ // ── Command: run ────────────────────────────────────────────────────────────
67
+ program
68
+ .command('run')
69
+ .description('Read containless.json, ensure runtimes are installed, and run the start command')
70
+ .option('-c, --config <path>', 'Path to containless.json', 'containless.json')
71
+ .action(async (opts) => {
72
+ try {
73
+ console.log(BANNER);
74
+ await (0, utils_1.checkGitignore)();
75
+ const config = await (0, config_1.readConfig)();
76
+ if (!config.start) {
77
+ (0, utils_1.logError)('No "start" command defined in containless.json');
78
+ process.exit(1);
79
+ }
80
+ // Install all runtimes defined in config
81
+ (0, utils_1.logInfo)(chalk_1.default.bold('Ensuring runtimes are installed...\n'));
82
+ for (const [name, version] of Object.entries(config.runtime)) {
83
+ if (!(0, utils_1.isSupportedRuntime)(name)) {
84
+ (0, utils_1.logWarn)(`Skipping unsupported runtime: ${name}`);
85
+ continue;
86
+ }
87
+ await (0, installer_1.installRuntime)(name, version);
88
+ }
89
+ console.log('');
90
+ (0, utils_1.logInfo)(chalk_1.default.bold('Starting application...\n'));
91
+ // Run the start command
92
+ const exitCode = await (0, runner_1.runCommand)({
93
+ command: config.start,
94
+ runtimes: config.runtime,
95
+ });
96
+ process.exit(exitCode);
97
+ }
98
+ catch (err) {
99
+ (0, utils_1.logError)(err.message);
100
+ process.exit(1);
101
+ }
102
+ });
103
+ // ── Command: install ────────────────────────────────────────────────────────
104
+ program
105
+ .command('install <runtime>')
106
+ .description('Download and install a runtime locally (e.g. node@18.17.0)')
107
+ .action(async (runtimeSpec) => {
108
+ try {
109
+ console.log(BANNER);
110
+ await (0, utils_1.checkGitignore)();
111
+ const { name, version } = (0, utils_1.parseRuntimeSpec)(runtimeSpec);
112
+ if (!(0, utils_1.isSupportedRuntime)(name)) {
113
+ (0, utils_1.logError)(`Unsupported runtime: "${name}". Supported: ${utils_1.SUPPORTED_RUNTIMES.join(', ')}`);
114
+ process.exit(1);
115
+ }
116
+ await (0, installer_1.installRuntime)(name, version);
117
+ }
118
+ catch (err) {
119
+ (0, utils_1.logError)(err.message);
120
+ process.exit(1);
121
+ }
122
+ });
123
+ // ── Command: clean ──────────────────────────────────────────────────────────
124
+ program
125
+ .command('clean')
126
+ .description('Delete all locally installed runtimes (.containless/runtimes/)')
127
+ .option('-a, --all', 'Delete the entire .containless/ directory (including cache)')
128
+ .action(async (opts) => {
129
+ try {
130
+ console.log(BANNER);
131
+ if (opts.all) {
132
+ const dir = (0, utils_1.containlessDir)();
133
+ if (await fs.pathExists(dir)) {
134
+ await fs.remove(dir);
135
+ (0, utils_1.logSuccess)(`Removed entire .containless/ directory`);
136
+ }
137
+ else {
138
+ (0, utils_1.logInfo)('Nothing to clean — .containless/ does not exist.');
139
+ }
140
+ }
141
+ else {
142
+ const dir = (0, utils_1.runtimesDir)();
143
+ if (await fs.pathExists(dir)) {
144
+ await fs.remove(dir);
145
+ (0, utils_1.logSuccess)(`Removed all installed runtimes from .containless/runtimes/`);
146
+ }
147
+ else {
148
+ (0, utils_1.logInfo)('Nothing to clean — no runtimes are installed.');
149
+ }
150
+ }
151
+ }
152
+ catch (err) {
153
+ (0, utils_1.logError)(err.message);
154
+ process.exit(1);
155
+ }
156
+ });
157
+ // ── Command: info ───────────────────────────────────────────────────────────
158
+ program
159
+ .command('info')
160
+ .description('Show what runtimes are currently installed locally')
161
+ .action(async () => {
162
+ try {
163
+ console.log(BANNER);
164
+ const rtDir = (0, utils_1.runtimesDir)();
165
+ if (!(await fs.pathExists(rtDir))) {
166
+ (0, utils_1.logInfo)('No runtimes installed. Use ' + chalk_1.default.bold('containless install <runtime@version>') + ' to get started.');
167
+ return;
168
+ }
169
+ const entries = await fs.readdir(rtDir, { withFileTypes: true });
170
+ const runtimes = entries.filter((e) => e.isDirectory());
171
+ if (runtimes.length === 0) {
172
+ (0, utils_1.logInfo)('No runtimes installed.');
173
+ return;
174
+ }
175
+ const table = new cli_table3_1.default({
176
+ head: [
177
+ chalk_1.default.cyan('Runtime'),
178
+ chalk_1.default.cyan('Version'),
179
+ chalk_1.default.cyan('Binary Path'),
180
+ chalk_1.default.cyan('Status'),
181
+ ],
182
+ style: {
183
+ head: [],
184
+ border: ['dim'],
185
+ },
186
+ chars: {
187
+ top: '─', 'top-mid': '┬', 'top-left': '┌', 'top-right': '┐',
188
+ bottom: '─', 'bottom-mid': '┴', 'bottom-left': '└', 'bottom-right': '┘',
189
+ left: '│', 'left-mid': '├',
190
+ mid: '─', 'mid-mid': '┼',
191
+ right: '│', 'right-mid': '┤',
192
+ middle: '│',
193
+ },
194
+ });
195
+ for (const entry of runtimes) {
196
+ const dirName = entry.name; // e.g. "node-18.17.0"
197
+ const dashIdx = dirName.indexOf('-');
198
+ if (dashIdx === -1)
199
+ continue;
200
+ const name = dirName.substring(0, dashIdx);
201
+ const version = dirName.substring(dashIdx + 1);
202
+ let binaryPath = '—';
203
+ let status = chalk_1.default.red('✖ binary not found');
204
+ if ((0, utils_1.isSupportedRuntime)(name)) {
205
+ const info = (0, index_1.getRuntimeInfo)(name, version);
206
+ const binDir = (0, utils_1.runtimeBinDir)(name, version);
207
+ const fullBinPath = path.join(binDir, info.binaryName);
208
+ binaryPath = path.relative(process.cwd(), fullBinPath);
209
+ if (await fs.pathExists(fullBinPath)) {
210
+ status = chalk_1.default.green('✔ ready');
211
+ }
212
+ }
213
+ else {
214
+ status = chalk_1.default.yellow('? unknown runtime');
215
+ }
216
+ table.push([
217
+ chalk_1.default.bold(name),
218
+ version,
219
+ chalk_1.default.dim(binaryPath),
220
+ status,
221
+ ]);
222
+ }
223
+ console.log(table.toString());
224
+ console.log('');
225
+ (0, utils_1.logInfo)(`Runtimes directory: ${chalk_1.default.dim(path.relative(process.cwd(), rtDir))}`);
226
+ }
227
+ catch (err) {
228
+ (0, utils_1.logError)(err.message);
229
+ process.exit(1);
230
+ }
231
+ });
232
+ // ── Parse & Run ─────────────────────────────────────────────────────────────
233
+ program.parse(process.argv);
234
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,yCAAoC;AACpC,kDAA0B;AAC1B,6CAA+B;AAC/B,2CAA6B;AAC7B,4DAA+B;AAC/B,qCAAsC;AACtC,2CAA6C;AAC7C,qCAAsC;AACtC,mCAaiB;AACjB,4CAAkD;AAElD,+EAA+E;AAE/E,MAAM,MAAM,GAAG,eAAK,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;CAO9B,CAAC,CAAC;AAEH,+EAA+E;AAE/E,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CACV,eAAK,CAAC,GAAG,CAAC,yFAAyF,CAAC,CACrG;KACA,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAEjC,+EAA+E;AAE/E,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,iFAAiF,CAAC;KAC9F,MAAM,CAAC,qBAAqB,EAAE,0BAA0B,EAAE,kBAAkB,CAAC;KAC7E,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,MAAM,IAAA,sBAAc,GAAE,CAAC;QAEvB,MAAM,MAAM,GAAG,MAAM,IAAA,mBAAU,GAAE,CAAC;QAElC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,IAAA,gBAAQ,EAAC,gDAAgD,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,yCAAyC;QACzC,IAAA,eAAO,EAAC,eAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC,CAAC;QAC5D,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7D,IAAI,CAAC,IAAA,0BAAkB,EAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,IAAA,eAAO,EAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;gBACjD,SAAS;YACX,CAAC;YACD,MAAM,IAAA,0BAAc,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,IAAA,eAAO,EAAC,eAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;QAEjD,wBAAwB;QACxB,MAAM,QAAQ,GAAG,MAAM,IAAA,mBAAU,EAAC;YAChC,OAAO,EAAE,MAAM,CAAC,KAAK;YACrB,QAAQ,EAAE,MAAM,CAAC,OAAO;SACzB,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAA,gBAAQ,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,+EAA+E;AAE/E,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,4DAA4D,CAAC;KACzE,MAAM,CAAC,KAAK,EAAE,WAAmB,EAAE,EAAE;IACpC,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpB,MAAM,IAAA,sBAAc,GAAE,CAAC;QAEvB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAA,wBAAgB,EAAC,WAAW,CAAC,CAAC;QAExD,IAAI,CAAC,IAAA,0BAAkB,EAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,IAAA,gBAAQ,EACN,yBAAyB,IAAI,iBAAiB,0BAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9E,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,IAAA,0BAAc,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAA,gBAAQ,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,+EAA+E;AAE/E,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,gEAAgE,CAAC;KAC7E,MAAM,CAAC,WAAW,EAAE,6DAA6D,CAAC;KAClF,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEpB,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,IAAA,sBAAc,GAAE,CAAC;YAC7B,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACrB,IAAA,kBAAU,EAAC,wCAAwC,CAAC,CAAC;YACvD,CAAC;iBAAM,CAAC;gBACN,IAAA,eAAO,EAAC,kDAAkD,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,IAAA,mBAAW,GAAE,CAAC;YAC1B,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACrB,IAAA,kBAAU,EAAC,4DAA4D,CAAC,CAAC;YAC3E,CAAC;iBAAM,CAAC;gBACN,IAAA,eAAO,EAAC,+CAA+C,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAA,gBAAQ,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,+EAA+E;AAE/E,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,oDAAoD,CAAC;KACjE,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEpB,MAAM,KAAK,GAAG,IAAA,mBAAW,GAAE,CAAC;QAE5B,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAClC,IAAA,eAAO,EAAC,6BAA6B,GAAG,eAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,GAAG,kBAAkB,CAAC,CAAC;YAClH,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAExD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,IAAA,eAAO,EAAC,wBAAwB,CAAC,CAAC;YAClC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,oBAAK,CAAC;YACtB,IAAI,EAAE;gBACJ,eAAK,CAAC,IAAI,CAAC,SAAS,CAAC;gBACrB,eAAK,CAAC,IAAI,CAAC,SAAS,CAAC;gBACrB,eAAK,CAAC,IAAI,CAAC,aAAa,CAAC;gBACzB,eAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;aACrB;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,EAAE;gBACR,MAAM,EAAE,CAAC,KAAK,CAAC;aAChB;YACD,KAAK,EAAE;gBACL,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG;gBAC3D,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG;gBACvE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG;gBAC1B,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG;gBACxB,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG;gBAC5B,MAAM,EAAE,GAAG;aACZ;SACF,CAAC,CAAC;QAEH,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,sBAAsB;YAClD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,OAAO,KAAK,CAAC,CAAC;gBAAE,SAAS;YAE7B,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;YAE/C,IAAI,UAAU,GAAG,GAAG,CAAC;YACrB,IAAI,MAAM,GAAG,eAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAE7C,IAAI,IAAA,0BAAkB,EAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,GAAG,IAAA,sBAAc,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAC3C,MAAM,MAAM,GAAG,IAAA,qBAAa,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;gBACvD,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;gBAEvD,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;oBACrC,MAAM,GAAG,eAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,eAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;YAC7C,CAAC;YAED,KAAK,CAAC,IAAI,CAAC;gBACT,eAAK,CAAC,IAAI,CAAC,IAAI,CAAC;gBAChB,OAAO;gBACP,eAAK,CAAC,GAAG,CAAC,UAAU,CAAC;gBACrB,MAAM;aACP,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,IAAA,eAAO,EAAC,uBAAuB,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAA,gBAAQ,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,+EAA+E;AAE/E,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface ContainlessConfig {
2
+ runtime: Record<string, string>;
3
+ start?: string;
4
+ }
5
+ export declare function configPath(cwd?: string): string;
6
+ export declare function readConfig(cwd?: string): Promise<ContainlessConfig>;
7
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAQD,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAsB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmCzE"}
package/dist/config.js ADDED
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.configPath = configPath;
37
+ exports.readConfig = readConfig;
38
+ const path = __importStar(require("path"));
39
+ const fs = __importStar(require("fs-extra"));
40
+ const utils_1 = require("./utils");
41
+ // ── Constants ───────────────────────────────────────────────────────────────
42
+ const CONFIG_FILENAME = 'containless.json';
43
+ // ── Read Config ─────────────────────────────────────────────────────────────
44
+ function configPath(cwd) {
45
+ return path.resolve(cwd || process.cwd(), CONFIG_FILENAME);
46
+ }
47
+ async function readConfig(cwd) {
48
+ const filePath = configPath(cwd);
49
+ if (!(await fs.pathExists(filePath))) {
50
+ (0, utils_1.logError)(`Config file not found: ${filePath}`);
51
+ (0, utils_1.logError)('Create a containless.json in your project root. Example:');
52
+ console.log(`
53
+ {
54
+ "runtime": {
55
+ "node": "18.17.0"
56
+ },
57
+ "start": "npm run dev"
58
+ }
59
+ `);
60
+ process.exit(1);
61
+ }
62
+ try {
63
+ const raw = await fs.readFile(filePath, 'utf-8');
64
+ const config = JSON.parse(raw);
65
+ if (!config.runtime || typeof config.runtime !== 'object') {
66
+ (0, utils_1.logError)('"runtime" field is missing or invalid in containless.json');
67
+ process.exit(1);
68
+ }
69
+ return config;
70
+ }
71
+ catch (err) {
72
+ if (err.name === 'SyntaxError') {
73
+ (0, utils_1.logError)(`containless.json is not valid JSON: ${err.message}`);
74
+ }
75
+ else {
76
+ (0, utils_1.logError)(`Failed to read containless.json: ${err.message}`);
77
+ }
78
+ process.exit(1);
79
+ }
80
+ }
81
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA,gCAEC;AAED,gCAmCC;AAxDD,2CAA6B;AAC7B,6CAA+B;AAC/B,mCAAmC;AASnC,+EAA+E;AAE/E,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAE3C,+EAA+E;AAE/E,SAAgB,UAAU,CAAC,GAAY;IACrC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;AAC7D,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,GAAY;IAC3C,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAEjC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QACrC,IAAA,gBAAQ,EAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;QAC/C,IAAA,gBAAQ,EAAC,0DAA0D,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC;;;;;;;CAOf,CAAC,CAAC;QACC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAC;QAEpD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC1D,IAAA,gBAAQ,EAAC,2DAA2D,CAAC,CAAC;YACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAI,GAAG,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAC/B,IAAA,gBAAQ,EAAC,uCAAuC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,IAAA,gBAAQ,EAAC,oCAAoC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function installRuntime(name: string, version: string, cwd?: string): Promise<void>;
2
+ //# sourceMappingURL=installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"AAoBA,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAwDf"}