@sandbox-engine/sdk 0.1.4 → 0.2.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/index.d.mts CHANGED
@@ -30,11 +30,31 @@ interface SandboxOptions {
30
30
  */
31
31
  dockerfile?: string;
32
32
  timeout?: number;
33
+ /** Environment variables injected into the container for the entire session. */
34
+ env?: Record<string, string>;
33
35
  }
34
36
  interface SandboxConnectOptions {
35
37
  serverUrl?: string;
36
38
  apiKey?: string;
37
39
  }
40
+ interface SandboxListOptions {
41
+ serverUrl?: string;
42
+ apiKey?: string;
43
+ }
44
+ interface SandboxSummary {
45
+ id: string;
46
+ status: string;
47
+ template: string;
48
+ createdAt: string;
49
+ timeout: number;
50
+ expiresAt: string | null;
51
+ agentUrl: string;
52
+ ports: Record<string, number>;
53
+ }
54
+ interface StreamLogsOptions {
55
+ onStdout?: (line: string) => void;
56
+ onStderr?: (line: string) => void;
57
+ }
38
58
  interface StartProcessOptions {
39
59
  command?: string;
40
60
  cmd?: string;
@@ -92,6 +112,23 @@ interface FileWriteManyResult {
92
112
  error?: string;
93
113
  }>;
94
114
  }
115
+ interface FileStat {
116
+ path: string;
117
+ size: number;
118
+ mtime: string;
119
+ isDirectory: boolean;
120
+ isFile: boolean;
121
+ }
122
+ interface FileWatchEvent {
123
+ type: 'change' | 'rename' | 'error';
124
+ eventType: 'create' | 'modify' | 'delete';
125
+ path: string;
126
+ data?: string;
127
+ }
128
+ interface FileWatchOptions {
129
+ recursive?: boolean;
130
+ onEvent: (event: FileWatchEvent) => void;
131
+ }
95
132
  interface PortMapping {
96
133
  containerPort: number;
97
134
  hostPort: number;
@@ -116,6 +153,12 @@ declare class Filesystem {
116
153
  writeMany(files: FileWriteEntry[]): Promise<FileWriteManyResult>;
117
154
  rename(oldPath: string, newPath: string): Promise<void>;
118
155
  delete(filePath: string): Promise<void>;
156
+ stat(filePath: string): Promise<FileStat>;
157
+ readBytes(filePath: string): Promise<Uint8Array>;
158
+ writeBytes(filePath: string, data: Uint8Array | Buffer): Promise<void>;
159
+ watch(dirPath: string, opts: FileWatchOptions): Promise<{
160
+ close: () => void;
161
+ }>;
119
162
  }
120
163
 
121
164
  declare class Process extends EventEmitter {
@@ -144,6 +187,9 @@ declare class BackgroundProcess {
144
187
  }>;
145
188
  waitForPort(port: number, opts?: WaitForPortOptions): Promise<void>;
146
189
  waitForLog(pattern: string | RegExp, opts?: WaitForLogOptions): Promise<string>;
190
+ streamLogs(opts?: StreamLogsOptions): {
191
+ close: () => void;
192
+ };
147
193
  }
148
194
  declare class ProcessManager {
149
195
  private readonly sandboxId;
@@ -181,6 +227,7 @@ declare class Sandbox {
181
227
  readonly processes: ProcessManager;
182
228
  private constructor();
183
229
  private static resolveClient;
230
+ static list(opts?: SandboxListOptions): Promise<SandboxSummary[]>;
184
231
  static create(opts?: SandboxOptions): Promise<Sandbox>;
185
232
  /**
186
233
  * Reconnect to an existing sandbox by ID.
@@ -205,4 +252,4 @@ declare class Sandbox {
205
252
  close(): Promise<void>;
206
253
  }
207
254
 
208
- export { BackgroundProcess, type BackgroundProcessInfo, type ExecOptions, type ExecResult, type FileEntry, type FileWriteEntry, type FileWriteManyResult, Filesystem, type PortMapping, Process, ProcessManager, type ProxyEnvResult, Sandbox, type SandboxConnectOptions, type SandboxOptions, type StartProcessOptions, Terminal, type WaitForLogOptions, type WaitForPortOptions, type WsMessage, type WsMessageType };
255
+ export { BackgroundProcess, type BackgroundProcessInfo, type ExecOptions, type ExecResult, type FileEntry, type FileStat, type FileWatchEvent, type FileWatchOptions, type FileWriteEntry, type FileWriteManyResult, Filesystem, type PortMapping, Process, ProcessManager, type ProxyEnvResult, Sandbox, type SandboxConnectOptions, type SandboxListOptions, type SandboxOptions, type SandboxSummary, type StartProcessOptions, type StreamLogsOptions, Terminal, type WaitForLogOptions, type WaitForPortOptions, type WsMessage, type WsMessageType };
package/dist/index.d.ts CHANGED
@@ -30,11 +30,31 @@ interface SandboxOptions {
30
30
  */
31
31
  dockerfile?: string;
32
32
  timeout?: number;
33
+ /** Environment variables injected into the container for the entire session. */
34
+ env?: Record<string, string>;
33
35
  }
34
36
  interface SandboxConnectOptions {
35
37
  serverUrl?: string;
36
38
  apiKey?: string;
37
39
  }
40
+ interface SandboxListOptions {
41
+ serverUrl?: string;
42
+ apiKey?: string;
43
+ }
44
+ interface SandboxSummary {
45
+ id: string;
46
+ status: string;
47
+ template: string;
48
+ createdAt: string;
49
+ timeout: number;
50
+ expiresAt: string | null;
51
+ agentUrl: string;
52
+ ports: Record<string, number>;
53
+ }
54
+ interface StreamLogsOptions {
55
+ onStdout?: (line: string) => void;
56
+ onStderr?: (line: string) => void;
57
+ }
38
58
  interface StartProcessOptions {
39
59
  command?: string;
40
60
  cmd?: string;
@@ -92,6 +112,23 @@ interface FileWriteManyResult {
92
112
  error?: string;
93
113
  }>;
94
114
  }
115
+ interface FileStat {
116
+ path: string;
117
+ size: number;
118
+ mtime: string;
119
+ isDirectory: boolean;
120
+ isFile: boolean;
121
+ }
122
+ interface FileWatchEvent {
123
+ type: 'change' | 'rename' | 'error';
124
+ eventType: 'create' | 'modify' | 'delete';
125
+ path: string;
126
+ data?: string;
127
+ }
128
+ interface FileWatchOptions {
129
+ recursive?: boolean;
130
+ onEvent: (event: FileWatchEvent) => void;
131
+ }
95
132
  interface PortMapping {
96
133
  containerPort: number;
97
134
  hostPort: number;
@@ -116,6 +153,12 @@ declare class Filesystem {
116
153
  writeMany(files: FileWriteEntry[]): Promise<FileWriteManyResult>;
117
154
  rename(oldPath: string, newPath: string): Promise<void>;
118
155
  delete(filePath: string): Promise<void>;
156
+ stat(filePath: string): Promise<FileStat>;
157
+ readBytes(filePath: string): Promise<Uint8Array>;
158
+ writeBytes(filePath: string, data: Uint8Array | Buffer): Promise<void>;
159
+ watch(dirPath: string, opts: FileWatchOptions): Promise<{
160
+ close: () => void;
161
+ }>;
119
162
  }
120
163
 
121
164
  declare class Process extends EventEmitter {
@@ -144,6 +187,9 @@ declare class BackgroundProcess {
144
187
  }>;
145
188
  waitForPort(port: number, opts?: WaitForPortOptions): Promise<void>;
146
189
  waitForLog(pattern: string | RegExp, opts?: WaitForLogOptions): Promise<string>;
190
+ streamLogs(opts?: StreamLogsOptions): {
191
+ close: () => void;
192
+ };
147
193
  }
148
194
  declare class ProcessManager {
149
195
  private readonly sandboxId;
@@ -181,6 +227,7 @@ declare class Sandbox {
181
227
  readonly processes: ProcessManager;
182
228
  private constructor();
183
229
  private static resolveClient;
230
+ static list(opts?: SandboxListOptions): Promise<SandboxSummary[]>;
184
231
  static create(opts?: SandboxOptions): Promise<Sandbox>;
185
232
  /**
186
233
  * Reconnect to an existing sandbox by ID.
@@ -205,4 +252,4 @@ declare class Sandbox {
205
252
  close(): Promise<void>;
206
253
  }
207
254
 
208
- export { BackgroundProcess, type BackgroundProcessInfo, type ExecOptions, type ExecResult, type FileEntry, type FileWriteEntry, type FileWriteManyResult, Filesystem, type PortMapping, Process, ProcessManager, type ProxyEnvResult, Sandbox, type SandboxConnectOptions, type SandboxOptions, type StartProcessOptions, Terminal, type WaitForLogOptions, type WaitForPortOptions, type WsMessage, type WsMessageType };
255
+ export { BackgroundProcess, type BackgroundProcessInfo, type ExecOptions, type ExecResult, type FileEntry, type FileStat, type FileWatchEvent, type FileWatchOptions, type FileWriteEntry, type FileWriteManyResult, Filesystem, type PortMapping, Process, ProcessManager, type ProxyEnvResult, Sandbox, type SandboxConnectOptions, type SandboxListOptions, type SandboxOptions, type SandboxSummary, type StartProcessOptions, type StreamLogsOptions, Terminal, type WaitForLogOptions, type WaitForPortOptions, type WsMessage, type WsMessageType };
package/dist/index.js CHANGED
@@ -149,6 +149,49 @@ var Filesystem = class {
149
149
  async delete(filePath) {
150
150
  await this.client.delete(`/api/sandboxes/${this.sandboxId}/files`, { path: filePath });
151
151
  }
152
+ async stat(filePath) {
153
+ return this.client.get(
154
+ `/api/sandboxes/${this.sandboxId}/files/stat`,
155
+ { path: filePath }
156
+ );
157
+ }
158
+ async readBytes(filePath) {
159
+ const res = await this.client.get(
160
+ `/api/sandboxes/${this.sandboxId}/files/bytes`,
161
+ { path: filePath }
162
+ );
163
+ return Uint8Array.from(Buffer.from(res.data, "base64"));
164
+ }
165
+ async writeBytes(filePath, data) {
166
+ await this.client.post(`/api/sandboxes/${this.sandboxId}/files/bytes`, {
167
+ path: filePath,
168
+ data: Buffer.from(data).toString("base64")
169
+ });
170
+ }
171
+ async watch(dirPath, opts) {
172
+ const ws = this.client.openWebSocket(`/api/sandboxes/${this.sandboxId}/files/watch`);
173
+ await new Promise((resolve, reject) => {
174
+ ws.once("open", () => {
175
+ ws.send(JSON.stringify({ path: dirPath, recursive: opts.recursive ?? false }));
176
+ resolve();
177
+ });
178
+ ws.once("error", reject);
179
+ });
180
+ ws.on("message", (raw) => {
181
+ try {
182
+ const event = JSON.parse(raw.toString());
183
+ opts.onEvent(event);
184
+ } catch {
185
+ }
186
+ });
187
+ return {
188
+ close: () => {
189
+ if (ws.readyState === ws.OPEN || ws.readyState === ws.CONNECTING) {
190
+ ws.close();
191
+ }
192
+ }
193
+ };
194
+ }
152
195
  };
153
196
 
154
197
  // src/process.ts
@@ -239,6 +282,29 @@ var BackgroundProcess = class {
239
282
  );
240
283
  return res.match;
241
284
  }
285
+ streamLogs(opts = {}) {
286
+ const ws = this.client.openWebSocket(
287
+ `/api/sandboxes/${this.sandboxId}/processes/logs/stream`
288
+ );
289
+ ws.on("open", () => {
290
+ ws.send(JSON.stringify({ processId: this.id }));
291
+ });
292
+ ws.on("message", (raw) => {
293
+ try {
294
+ const msg = JSON.parse(raw.toString());
295
+ if (msg.type === "stdout") opts.onStdout?.(msg.data ?? "");
296
+ else if (msg.type === "stderr") opts.onStderr?.(msg.data ?? "");
297
+ } catch {
298
+ }
299
+ });
300
+ return {
301
+ close: () => {
302
+ if (ws.readyState === ws.OPEN || ws.readyState === ws.CONNECTING) {
303
+ ws.close();
304
+ }
305
+ }
306
+ };
307
+ }
242
308
  };
243
309
  var ProcessManager = class {
244
310
  constructor(sandboxId, client) {
@@ -329,12 +395,17 @@ var Sandbox = class _Sandbox {
329
395
  const apiKey = opts.apiKey ?? process.env.SANDBOX_API_KEY ?? "dev-api-key";
330
396
  return new HttpClient(serverUrl, apiKey);
331
397
  }
398
+ static async list(opts = {}) {
399
+ const client = _Sandbox.resolveClient(opts);
400
+ return client.get("/api/sandboxes");
401
+ }
332
402
  static async create(opts = {}) {
333
403
  const client = _Sandbox.resolveClient(opts);
334
404
  const data = await client.post("/api/sandboxes", {
335
405
  template: opts.template,
336
406
  dockerfile: opts.dockerfile,
337
- timeout: opts.timeout
407
+ timeout: opts.timeout,
408
+ env: opts.env
338
409
  });
339
410
  return new _Sandbox(client, data.id);
340
411
  }
package/dist/index.mjs CHANGED
@@ -108,6 +108,49 @@ var Filesystem = class {
108
108
  async delete(filePath) {
109
109
  await this.client.delete(`/api/sandboxes/${this.sandboxId}/files`, { path: filePath });
110
110
  }
111
+ async stat(filePath) {
112
+ return this.client.get(
113
+ `/api/sandboxes/${this.sandboxId}/files/stat`,
114
+ { path: filePath }
115
+ );
116
+ }
117
+ async readBytes(filePath) {
118
+ const res = await this.client.get(
119
+ `/api/sandboxes/${this.sandboxId}/files/bytes`,
120
+ { path: filePath }
121
+ );
122
+ return Uint8Array.from(Buffer.from(res.data, "base64"));
123
+ }
124
+ async writeBytes(filePath, data) {
125
+ await this.client.post(`/api/sandboxes/${this.sandboxId}/files/bytes`, {
126
+ path: filePath,
127
+ data: Buffer.from(data).toString("base64")
128
+ });
129
+ }
130
+ async watch(dirPath, opts) {
131
+ const ws = this.client.openWebSocket(`/api/sandboxes/${this.sandboxId}/files/watch`);
132
+ await new Promise((resolve, reject) => {
133
+ ws.once("open", () => {
134
+ ws.send(JSON.stringify({ path: dirPath, recursive: opts.recursive ?? false }));
135
+ resolve();
136
+ });
137
+ ws.once("error", reject);
138
+ });
139
+ ws.on("message", (raw) => {
140
+ try {
141
+ const event = JSON.parse(raw.toString());
142
+ opts.onEvent(event);
143
+ } catch {
144
+ }
145
+ });
146
+ return {
147
+ close: () => {
148
+ if (ws.readyState === ws.OPEN || ws.readyState === ws.CONNECTING) {
149
+ ws.close();
150
+ }
151
+ }
152
+ };
153
+ }
111
154
  };
112
155
 
113
156
  // src/process.ts
@@ -198,6 +241,29 @@ var BackgroundProcess = class {
198
241
  );
199
242
  return res.match;
200
243
  }
244
+ streamLogs(opts = {}) {
245
+ const ws = this.client.openWebSocket(
246
+ `/api/sandboxes/${this.sandboxId}/processes/logs/stream`
247
+ );
248
+ ws.on("open", () => {
249
+ ws.send(JSON.stringify({ processId: this.id }));
250
+ });
251
+ ws.on("message", (raw) => {
252
+ try {
253
+ const msg = JSON.parse(raw.toString());
254
+ if (msg.type === "stdout") opts.onStdout?.(msg.data ?? "");
255
+ else if (msg.type === "stderr") opts.onStderr?.(msg.data ?? "");
256
+ } catch {
257
+ }
258
+ });
259
+ return {
260
+ close: () => {
261
+ if (ws.readyState === ws.OPEN || ws.readyState === ws.CONNECTING) {
262
+ ws.close();
263
+ }
264
+ }
265
+ };
266
+ }
201
267
  };
202
268
  var ProcessManager = class {
203
269
  constructor(sandboxId, client) {
@@ -288,12 +354,17 @@ var Sandbox = class _Sandbox {
288
354
  const apiKey = opts.apiKey ?? process.env.SANDBOX_API_KEY ?? "dev-api-key";
289
355
  return new HttpClient(serverUrl, apiKey);
290
356
  }
357
+ static async list(opts = {}) {
358
+ const client = _Sandbox.resolveClient(opts);
359
+ return client.get("/api/sandboxes");
360
+ }
291
361
  static async create(opts = {}) {
292
362
  const client = _Sandbox.resolveClient(opts);
293
363
  const data = await client.post("/api/sandboxes", {
294
364
  template: opts.template,
295
365
  dockerfile: opts.dockerfile,
296
- timeout: opts.timeout
366
+ timeout: opts.timeout,
367
+ env: opts.env
297
368
  });
298
369
  return new _Sandbox(client, data.id);
299
370
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sandbox-engine/sdk",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "SDK for creating and managing isolated sandbox environments",
5
5
  "keywords": ["sandbox", "docker", "code-execution", "isolated", "e2b"],
6
6
  "license": "MIT",