@boxlite-ai/boxlite 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/README.md +434 -0
- package/dist/browserbox.d.ts +145 -0
- package/dist/browserbox.d.ts.map +1 -0
- package/dist/browserbox.js +234 -0
- package/dist/browserbox.js.map +1 -0
- package/dist/codebox.d.ts +144 -0
- package/dist/codebox.d.ts.map +1 -0
- package/dist/codebox.js +202 -0
- package/dist/codebox.js.map +1 -0
- package/dist/computerbox.d.ts +271 -0
- package/dist/computerbox.d.ts.map +1 -0
- package/dist/computerbox.js +406 -0
- package/dist/computerbox.js.map +1 -0
- package/dist/constants.d.ts +24 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +32 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors.d.ts +82 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +114 -0
- package/dist/errors.js.map +1 -0
- package/dist/exec.d.ts +32 -0
- package/dist/exec.d.ts.map +1 -0
- package/dist/exec.js +3 -0
- package/dist/exec.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/interactivebox.d.ts +155 -0
- package/dist/interactivebox.d.ts.map +1 -0
- package/dist/interactivebox.js +299 -0
- package/dist/interactivebox.js.map +1 -0
- package/dist/native.d.ts +20 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +41 -0
- package/dist/native.js.map +1 -0
- package/dist/simplebox.d.ts +175 -0
- package/dist/simplebox.d.ts.map +1 -0
- package/dist/simplebox.js +232 -0
- package/dist/simplebox.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* InteractiveBox - Interactive terminal sessions with PTY support.
|
|
4
|
+
*
|
|
5
|
+
* Provides automatic PTY-based interactive sessions, similar to `docker exec -it`.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.InteractiveBox = void 0;
|
|
9
|
+
const native_1 = require("./native");
|
|
10
|
+
/**
|
|
11
|
+
* Interactive box with automatic PTY and terminal forwarding.
|
|
12
|
+
*
|
|
13
|
+
* When used as a context manager, automatically:
|
|
14
|
+
* 1. Auto-detects terminal size (like Docker)
|
|
15
|
+
* 2. Starts a shell with PTY
|
|
16
|
+
* 3. Sets local terminal to raw mode
|
|
17
|
+
* 4. Forwards stdin/stdout bidirectionally
|
|
18
|
+
* 5. Restores terminal mode on exit
|
|
19
|
+
*
|
|
20
|
+
* ## Example
|
|
21
|
+
*
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const box = new InteractiveBox({ image: 'alpine:latest' });
|
|
24
|
+
* try {
|
|
25
|
+
* await box.start();
|
|
26
|
+
* // You're now in an interactive shell!
|
|
27
|
+
* // Type commands, see output in real-time
|
|
28
|
+
* // Type "exit" to close
|
|
29
|
+
* await box.wait();
|
|
30
|
+
* } finally {
|
|
31
|
+
* await box.stop();
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* Or with async disposal (TypeScript 5.2+):
|
|
36
|
+
*
|
|
37
|
+
* ```typescript
|
|
38
|
+
* await using box = new InteractiveBox({ image: 'alpine:latest' });
|
|
39
|
+
* await box.start();
|
|
40
|
+
* await box.wait();
|
|
41
|
+
* // Automatically stopped when leaving scope
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
class InteractiveBox {
|
|
45
|
+
/**
|
|
46
|
+
* Create an interactive box.
|
|
47
|
+
*
|
|
48
|
+
* @param options - InteractiveBox configuration options
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const box = new InteractiveBox({
|
|
53
|
+
* image: 'alpine:latest',
|
|
54
|
+
* shell: '/bin/sh',
|
|
55
|
+
* tty: true,
|
|
56
|
+
* memoryMib: 512,
|
|
57
|
+
* cpus: 1
|
|
58
|
+
* });
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
constructor(options) {
|
|
62
|
+
this._ioTasks = [];
|
|
63
|
+
this._exited = false;
|
|
64
|
+
const JsBoxlite = (0, native_1.getJsBoxlite)();
|
|
65
|
+
// Use provided runtime or get global default
|
|
66
|
+
if (options.runtime) {
|
|
67
|
+
this._runtime = options.runtime;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
this._runtime = JsBoxlite.default();
|
|
71
|
+
}
|
|
72
|
+
// Create box directly (no SimpleBox wrapper)
|
|
73
|
+
const { shell = '/bin/sh', tty, env, ...boxOptions } = options;
|
|
74
|
+
this._box = this._runtime.create(boxOptions, options.name);
|
|
75
|
+
this._shell = shell;
|
|
76
|
+
this._env = env;
|
|
77
|
+
// Determine TTY mode: undefined = auto-detect, true = force, false = disable
|
|
78
|
+
if (tty === undefined) {
|
|
79
|
+
this._tty = process.stdin.isTTY ?? false;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
this._tty = tty;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get the box ID (ULID format).
|
|
87
|
+
*/
|
|
88
|
+
get id() {
|
|
89
|
+
return this._box.id;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Start the interactive shell session.
|
|
93
|
+
*
|
|
94
|
+
* This method:
|
|
95
|
+
* 1. Starts the shell with PTY
|
|
96
|
+
* 2. Sets terminal to raw mode (if tty=true)
|
|
97
|
+
* 3. Begins I/O forwarding
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* await box.start();
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
async start() {
|
|
105
|
+
// Convert env to array format if provided
|
|
106
|
+
const envArray = this._env
|
|
107
|
+
? Object.entries(this._env).map(([k, v]) => [k, v])
|
|
108
|
+
: undefined;
|
|
109
|
+
// Start shell with PTY
|
|
110
|
+
this._execution = await this._box.exec(this._shell, [], envArray, true);
|
|
111
|
+
// Get streams
|
|
112
|
+
try {
|
|
113
|
+
this._stdin = this._execution.stdin();
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
// stdin not available
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
this._stdout = this._execution.stdout();
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
// stdout not available
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
this._stderr = this._execution.stderr();
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
// stderr not available
|
|
129
|
+
}
|
|
130
|
+
// Only set raw mode and start forwarding if tty=true
|
|
131
|
+
if (this._tty && process.stdin.isTTY) {
|
|
132
|
+
// Set terminal to raw mode
|
|
133
|
+
process.stdin.setRawMode(true);
|
|
134
|
+
process.stdin.resume();
|
|
135
|
+
// Start bidirectional I/O forwarding
|
|
136
|
+
this._ioTasks.push(this._forwardStdin(), this._forwardOutput(), this._forwardStderr(), this._waitForExit());
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
// No I/O forwarding, just wait for execution
|
|
140
|
+
this._ioTasks.push(this._waitForExit());
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Wait for the shell to exit.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* await box.start();
|
|
149
|
+
* await box.wait(); // Blocks until shell exits
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
async wait() {
|
|
153
|
+
await Promise.all(this._ioTasks);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Stop the box and restore terminal settings.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* await box.stop();
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
async stop() {
|
|
164
|
+
// Restore terminal settings
|
|
165
|
+
if (this._tty && process.stdin.isTTY) {
|
|
166
|
+
try {
|
|
167
|
+
process.stdin.setRawMode(false);
|
|
168
|
+
process.stdin.pause();
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
// Ignore errors during cleanup
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Wait for I/O tasks to complete (with timeout)
|
|
175
|
+
try {
|
|
176
|
+
await Promise.race([
|
|
177
|
+
Promise.all(this._ioTasks),
|
|
178
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 3000))
|
|
179
|
+
]);
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
// Timeout or error - continue with shutdown
|
|
183
|
+
}
|
|
184
|
+
// Stop the box
|
|
185
|
+
await this._box.stop();
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Implement async disposable pattern (TypeScript 5.2+).
|
|
189
|
+
*
|
|
190
|
+
* Allows using `await using` syntax for automatic cleanup.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```typescript
|
|
194
|
+
* await using box = new InteractiveBox({ image: 'alpine' });
|
|
195
|
+
* await box.start();
|
|
196
|
+
* // Box automatically stopped when leaving scope
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
async [Symbol.asyncDispose]() {
|
|
200
|
+
await this.stop();
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Forward stdin to PTY (internal).
|
|
204
|
+
*/
|
|
205
|
+
async _forwardStdin() {
|
|
206
|
+
if (!this._stdin)
|
|
207
|
+
return;
|
|
208
|
+
try {
|
|
209
|
+
process.stdin.on('data', async (data) => {
|
|
210
|
+
if (!this._exited && this._stdin) {
|
|
211
|
+
try {
|
|
212
|
+
await this._stdin.write(data);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
// Ignore write errors (box may be shutting down)
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
// Wait for exit
|
|
220
|
+
await new Promise((resolve) => {
|
|
221
|
+
const checkExit = setInterval(() => {
|
|
222
|
+
if (this._exited) {
|
|
223
|
+
clearInterval(checkExit);
|
|
224
|
+
resolve();
|
|
225
|
+
}
|
|
226
|
+
}, 100);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
// Ignore errors during shutdown
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Forward PTY output to stdout (internal).
|
|
235
|
+
*/
|
|
236
|
+
async _forwardOutput() {
|
|
237
|
+
if (!this._stdout)
|
|
238
|
+
return;
|
|
239
|
+
try {
|
|
240
|
+
while (true) {
|
|
241
|
+
const chunk = await this._stdout.next();
|
|
242
|
+
if (chunk === null)
|
|
243
|
+
break;
|
|
244
|
+
// Write to stdout
|
|
245
|
+
if (typeof chunk === 'string') {
|
|
246
|
+
process.stdout.write(chunk);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
process.stdout.write(chunk);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch (err) {
|
|
254
|
+
// Stream ended or error
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Forward PTY stderr to stderr (internal).
|
|
259
|
+
*/
|
|
260
|
+
async _forwardStderr() {
|
|
261
|
+
if (!this._stderr)
|
|
262
|
+
return;
|
|
263
|
+
try {
|
|
264
|
+
while (true) {
|
|
265
|
+
const chunk = await this._stderr.next();
|
|
266
|
+
if (chunk === null)
|
|
267
|
+
break;
|
|
268
|
+
// Write to stderr
|
|
269
|
+
if (typeof chunk === 'string') {
|
|
270
|
+
process.stderr.write(chunk);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
process.stderr.write(chunk);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
catch (err) {
|
|
278
|
+
// Stream ended or error
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Wait for the shell to exit (internal).
|
|
283
|
+
*/
|
|
284
|
+
async _waitForExit() {
|
|
285
|
+
try {
|
|
286
|
+
if (this._execution) {
|
|
287
|
+
await this._execution.wait();
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
catch (err) {
|
|
291
|
+
// Ignore errors during shutdown
|
|
292
|
+
}
|
|
293
|
+
finally {
|
|
294
|
+
this._exited = true;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
exports.InteractiveBox = InteractiveBox;
|
|
299
|
+
//# sourceMappingURL=interactivebox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactivebox.js","sourceRoot":"","sources":["../lib/interactivebox.ts"],"names":[],"mappings":"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"}
|
package/dist/native.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native module loader for BoxLite Node.js SDK.
|
|
3
|
+
*
|
|
4
|
+
* This module centralizes native binding loading to avoid duplication
|
|
5
|
+
* across simplebox.ts, interactivebox.ts, and index.ts.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Load and return the native BoxLite module.
|
|
9
|
+
*
|
|
10
|
+
* Uses @node-rs/helper for platform-specific package selection.
|
|
11
|
+
* Caches the result for subsequent calls.
|
|
12
|
+
*
|
|
13
|
+
* @throws Error if the native extension is not found or fails to load
|
|
14
|
+
*/
|
|
15
|
+
export declare function getNativeModule(): any;
|
|
16
|
+
/**
|
|
17
|
+
* Get the JsBoxlite runtime class from the native module.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getJsBoxlite(): any;
|
|
20
|
+
//# sourceMappingURL=native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../lib/native.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH;;;;;;;GAOG;AACH,wBAAgB,eAAe,IAAI,GAAG,CAYrC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,GAAG,CAElC"}
|
package/dist/native.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Native module loader for BoxLite Node.js SDK.
|
|
4
|
+
*
|
|
5
|
+
* This module centralizes native binding loading to avoid duplication
|
|
6
|
+
* across simplebox.ts, interactivebox.ts, and index.ts.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.getNativeModule = getNativeModule;
|
|
10
|
+
exports.getJsBoxlite = getJsBoxlite;
|
|
11
|
+
const helper_1 = require("@node-rs/helper");
|
|
12
|
+
const path_1 = require("path");
|
|
13
|
+
// Cache the loaded native module
|
|
14
|
+
let _nativeModule = null;
|
|
15
|
+
/**
|
|
16
|
+
* Load and return the native BoxLite module.
|
|
17
|
+
*
|
|
18
|
+
* Uses @node-rs/helper for platform-specific package selection.
|
|
19
|
+
* Caches the result for subsequent calls.
|
|
20
|
+
*
|
|
21
|
+
* @throws Error if the native extension is not found or fails to load
|
|
22
|
+
*/
|
|
23
|
+
function getNativeModule() {
|
|
24
|
+
if (_nativeModule === null) {
|
|
25
|
+
try {
|
|
26
|
+
_nativeModule = (0, helper_1.loadBinding)((0, path_1.join)(__dirname, '..'), 'boxlite', '@boxlite/boxlite');
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
throw new Error(`BoxLite native extension not found: ${err}. ` +
|
|
30
|
+
`Please build the extension first with: npm run build`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return _nativeModule;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the JsBoxlite runtime class from the native module.
|
|
37
|
+
*/
|
|
38
|
+
function getJsBoxlite() {
|
|
39
|
+
return getNativeModule().JsBoxlite;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.js","sourceRoot":"","sources":["../lib/native.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAgBH,0CAYC;AAKD,oCAEC;AAjCD,4CAA8C;AAC9C,+BAA4B;AAE5B,iCAAiC;AACjC,IAAI,aAAa,GAAQ,IAAI,CAAC;AAE9B;;;;;;;GAOG;AACH,SAAgB,eAAe;IAC7B,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,aAAa,GAAG,IAAA,oBAAW,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC;QACpF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,uCAAuC,GAAG,IAAI;gBAC9C,sDAAsD,CACvD,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY;IAC1B,OAAO,eAAe,EAAE,CAAC,SAAS,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SimpleBox - Foundation for specialized container types.
|
|
3
|
+
*
|
|
4
|
+
* Provides common functionality for all specialized boxes (CodeBox, BrowserBox, etc.)
|
|
5
|
+
* This class encapsulates common patterns:
|
|
6
|
+
* 1. Automatic runtime lifecycle management
|
|
7
|
+
* 2. Command execution with output collection
|
|
8
|
+
* 3. Try/finally cleanup patterns
|
|
9
|
+
*/
|
|
10
|
+
import type { ExecResult } from './exec';
|
|
11
|
+
type Boxlite = any;
|
|
12
|
+
type Box = any;
|
|
13
|
+
/**
|
|
14
|
+
* Options for creating a SimpleBox.
|
|
15
|
+
*/
|
|
16
|
+
export interface SimpleBoxOptions {
|
|
17
|
+
/** Container image to use (e.g., 'python:slim', 'alpine:latest') */
|
|
18
|
+
image?: string;
|
|
19
|
+
/** Memory limit in MiB */
|
|
20
|
+
memoryMib?: number;
|
|
21
|
+
/** Number of CPU cores */
|
|
22
|
+
cpus?: number;
|
|
23
|
+
/** Optional runtime instance (uses global default if not provided) */
|
|
24
|
+
runtime?: Boxlite;
|
|
25
|
+
/** Optional name for the box (must be unique) */
|
|
26
|
+
name?: string;
|
|
27
|
+
/** Remove box when stopped (default: true) */
|
|
28
|
+
autoRemove?: boolean;
|
|
29
|
+
/** Run box in detached mode (survives parent process exit, default: false) */
|
|
30
|
+
detach?: boolean;
|
|
31
|
+
/** Working directory inside container */
|
|
32
|
+
workingDir?: string;
|
|
33
|
+
/** Environment variables */
|
|
34
|
+
env?: Record<string, string>;
|
|
35
|
+
/** Volume mounts */
|
|
36
|
+
volumes?: Array<{
|
|
37
|
+
hostPath: string;
|
|
38
|
+
guestPath: string;
|
|
39
|
+
readOnly?: boolean;
|
|
40
|
+
}>;
|
|
41
|
+
/** Port mappings */
|
|
42
|
+
ports?: Array<{
|
|
43
|
+
hostPort?: number;
|
|
44
|
+
guestPort: number;
|
|
45
|
+
protocol?: string;
|
|
46
|
+
}>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Base class for specialized container types.
|
|
50
|
+
*
|
|
51
|
+
* This class provides the foundation for all specialized boxes:
|
|
52
|
+
* - CodeBox: Python code execution sandbox
|
|
53
|
+
* - BrowserBox: Browser automation
|
|
54
|
+
* - ComputerBox: Desktop automation
|
|
55
|
+
* - InteractiveBox: PTY terminal sessions
|
|
56
|
+
*
|
|
57
|
+
* ## Usage
|
|
58
|
+
*
|
|
59
|
+
* SimpleBox can be used directly for simple command execution:
|
|
60
|
+
*
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const box = new SimpleBox({ image: 'alpine:latest' });
|
|
63
|
+
* try {
|
|
64
|
+
* const result = await box.exec('ls', '-la', '/');
|
|
65
|
+
* console.log(result.stdout);
|
|
66
|
+
* } finally {
|
|
67
|
+
* await box.stop();
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* Or extended for specialized use cases:
|
|
72
|
+
*
|
|
73
|
+
* ```typescript
|
|
74
|
+
* class MyBox extends SimpleBox {
|
|
75
|
+
* constructor() {
|
|
76
|
+
* super({ image: 'my-custom-image:latest' });
|
|
77
|
+
* }
|
|
78
|
+
*
|
|
79
|
+
* async myMethod() {
|
|
80
|
+
* const result = await this.exec('my-command');
|
|
81
|
+
* return result.stdout;
|
|
82
|
+
* }
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare class SimpleBox {
|
|
87
|
+
protected _runtime: Boxlite;
|
|
88
|
+
protected _box: Box;
|
|
89
|
+
protected _name?: string;
|
|
90
|
+
/**
|
|
91
|
+
* Create a new SimpleBox.
|
|
92
|
+
*
|
|
93
|
+
* @param options - Box configuration options
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* const box = new SimpleBox({
|
|
98
|
+
* image: 'python:slim',
|
|
99
|
+
* memoryMib: 512,
|
|
100
|
+
* cpus: 2,
|
|
101
|
+
* name: 'my-box'
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
constructor(options?: SimpleBoxOptions);
|
|
106
|
+
/**
|
|
107
|
+
* Get the box ID (ULID format).
|
|
108
|
+
*/
|
|
109
|
+
get id(): string;
|
|
110
|
+
/**
|
|
111
|
+
* Get the box name (if set).
|
|
112
|
+
*/
|
|
113
|
+
get name(): string | undefined;
|
|
114
|
+
/**
|
|
115
|
+
* Get box metadata.
|
|
116
|
+
*/
|
|
117
|
+
info(): any;
|
|
118
|
+
/**
|
|
119
|
+
* Execute a command in the box and collect the output.
|
|
120
|
+
*
|
|
121
|
+
* This is a convenience method that:
|
|
122
|
+
* 1. Starts the command
|
|
123
|
+
* 2. Collects all stdout and stderr
|
|
124
|
+
* 3. Waits for completion
|
|
125
|
+
* 4. Returns the result
|
|
126
|
+
*
|
|
127
|
+
* For streaming output, use the lower-level `this._box.exec()` directly.
|
|
128
|
+
*
|
|
129
|
+
* @param cmd - Command to execute (e.g., 'ls', 'python')
|
|
130
|
+
* @param args - Arguments to the command
|
|
131
|
+
* @param env - Environment variables (optional)
|
|
132
|
+
*
|
|
133
|
+
* @returns Promise resolving to ExecResult with exit code and output
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* // Simple execution
|
|
138
|
+
* const result = await box.exec('ls', '-la', '/');
|
|
139
|
+
* console.log(`Exit code: ${result.exitCode}`);
|
|
140
|
+
* console.log(`Output:\n${result.stdout}`);
|
|
141
|
+
*
|
|
142
|
+
* // With environment variables
|
|
143
|
+
* const result = await box.exec('env', [], { FOO: 'bar' });
|
|
144
|
+
* console.log(result.stdout);
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
exec(cmd: string, ...args: string[]): Promise<ExecResult>;
|
|
148
|
+
exec(cmd: string, args: string[], env: Record<string, string>): Promise<ExecResult>;
|
|
149
|
+
/**
|
|
150
|
+
* Stop the box.
|
|
151
|
+
*
|
|
152
|
+
* Sends a graceful shutdown signal to the VM. If `autoRemove` is true
|
|
153
|
+
* (default), the box files will be deleted after stopping.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* await box.stop();
|
|
158
|
+
* console.log('Box stopped');
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
stop(): Promise<void>;
|
|
162
|
+
/**
|
|
163
|
+
* Implement async disposable pattern (TypeScript 5.2+).
|
|
164
|
+
*
|
|
165
|
+
* Allows using `await using` syntax for automatic cleanup:
|
|
166
|
+
*
|
|
167
|
+
* ```typescript
|
|
168
|
+
* await using box = new SimpleBox({ image: 'alpine' });
|
|
169
|
+
* // Box automatically stopped when leaving scope
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
173
|
+
}
|
|
174
|
+
export {};
|
|
175
|
+
//# sourceMappingURL=simplebox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simplebox.d.ts","sourceRoot":"","sources":["../lib/simplebox.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAIzC,KAAK,OAAO,GAAG,GAAG,CAAC;AACnB,KAAK,GAAG,GAAG,GAAG,CAAC;AAIf;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,8CAA8C;IAC9C,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE7B,oBAAoB;IACpB,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC,CAAC;IAEH,oBAAoB;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;QACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBAAa,SAAS;IACpB,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC;IACpB,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;;;;;;;;;;OAcG;gBACS,OAAO,GAAE,gBAAqB;IA6B1C;;OAEG;IACH,IAAI,EAAE,IAAI,MAAM,CAEf;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;IAED;;OAEG;IACH,IAAI;IAIJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAqGzF;;;;;;;;;;;OAWG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B;;;;;;;;;OASG;IACG,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7C"}
|