@cloudflare/sandbox 0.2.4 → 0.3.1
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/CHANGELOG.md +75 -0
- package/Dockerfile +9 -11
- package/README.md +69 -7
- package/container_src/control-process.ts +784 -0
- package/container_src/handler/exec.ts +99 -254
- package/container_src/handler/file.ts +179 -837
- package/container_src/handler/git.ts +28 -80
- package/container_src/handler/process.ts +443 -515
- package/container_src/handler/session.ts +92 -0
- package/container_src/index.ts +68 -130
- package/container_src/isolation.ts +1038 -0
- package/container_src/shell-escape.ts +42 -0
- package/container_src/types.ts +27 -13
- package/dist/{chunk-HHUDRGPY.js → chunk-BEQUGUY4.js} +2 -2
- package/dist/{chunk-CKIGERRS.js → chunk-LFLJGISB.js} +240 -264
- package/dist/chunk-LFLJGISB.js.map +1 -0
- package/dist/{chunk-3CQ6THKA.js → chunk-SMUEY5JR.js} +85 -103
- package/dist/chunk-SMUEY5JR.js.map +1 -0
- package/dist/{client-Ce40ujDF.d.ts → client-Dny_ro_v.d.ts} +41 -25
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -9
- package/dist/interpreter.d.ts +1 -1
- package/dist/jupyter-client.d.ts +1 -1
- package/dist/jupyter-client.js +2 -2
- package/dist/request-handler.d.ts +1 -1
- package/dist/request-handler.js +3 -5
- package/dist/sandbox.d.ts +1 -1
- package/dist/sandbox.js +3 -5
- package/dist/types.d.ts +10 -21
- package/dist/types.js +35 -9
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/client.ts +120 -135
- package/src/index.ts +8 -0
- package/src/sandbox.ts +290 -331
- package/src/types.ts +15 -24
- package/dist/chunk-3CQ6THKA.js.map +0 -1
- package/dist/chunk-6EWSYSO7.js +0 -46
- package/dist/chunk-6EWSYSO7.js.map +0 -1
- package/dist/chunk-CKIGERRS.js.map +0 -1
- /package/dist/{chunk-HHUDRGPY.js.map → chunk-BEQUGUY4.js.map} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ISandbox, ExecOptions, ExecResult, ProcessOptions, Process, StreamOptions, GitCheckoutResponse, MkdirResponse, WriteFileResponse, DeleteFileResponse, RenameFileResponse, MoveFileResponse, ReadFileResponse, ListFilesResponse, BaseExecOptions, ExecuteResponse, StartProcessResponse, ListProcessesResponse, GetProcessResponse, GetProcessLogsResponse } from './types.js';
|
|
1
|
+
import { ISandbox, ExecOptions, ExecResult, ProcessOptions, Process, StreamOptions, GitCheckoutResponse, MkdirResponse, WriteFileResponse, DeleteFileResponse, RenameFileResponse, MoveFileResponse, ReadFileResponse, ListFilesResponse, ExecutionSession, BaseExecOptions, ExecuteResponse, StartProcessResponse, ListProcessesResponse, GetProcessResponse, GetProcessLogsResponse } from './types.js';
|
|
2
2
|
import { Container } from '@cloudflare/containers';
|
|
3
3
|
import { CreateContextOptions, CodeContext, OutputMessage, Result, ExecutionError, RunCodeOptions, ExecutionResult } from './interpreter-types.js';
|
|
4
4
|
|
|
@@ -35,6 +35,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
|
|
|
35
35
|
client: JupyterClient;
|
|
36
36
|
private sandboxName;
|
|
37
37
|
private codeInterpreter;
|
|
38
|
+
private defaultSession;
|
|
38
39
|
constructor(ctx: DurableObjectState, env: Env);
|
|
39
40
|
setSandboxName(name: string): Promise<void>;
|
|
40
41
|
setEnvVars(envVars: Record<string, string>): Promise<void>;
|
|
@@ -43,13 +44,12 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
|
|
|
43
44
|
onError(error: unknown): void;
|
|
44
45
|
fetch(request: Request): Promise<Response>;
|
|
45
46
|
private determinePort;
|
|
47
|
+
private ensureDefaultSession;
|
|
46
48
|
exec(command: string, options?: ExecOptions): Promise<ExecResult>;
|
|
47
|
-
private executeWithStreaming;
|
|
48
|
-
private mapExecuteResponseToExecResult;
|
|
49
49
|
startProcess(command: string, options?: ProcessOptions): Promise<Process>;
|
|
50
50
|
listProcesses(): Promise<Process[]>;
|
|
51
51
|
getProcess(id: string): Promise<Process | null>;
|
|
52
|
-
killProcess(id: string,
|
|
52
|
+
killProcess(id: string, signal?: string): Promise<void>;
|
|
53
53
|
killAllProcesses(): Promise<number>;
|
|
54
54
|
cleanupCompletedProcesses(): Promise<number>;
|
|
55
55
|
getProcessLogs(id: string): Promise<{
|
|
@@ -116,6 +116,16 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
|
|
|
116
116
|
* Delete a code context
|
|
117
117
|
*/
|
|
118
118
|
deleteCodeContext(contextId: string): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Create a new execution session with isolation
|
|
121
|
+
* Returns a session object with exec() method
|
|
122
|
+
*/
|
|
123
|
+
createSession(options: {
|
|
124
|
+
id?: string;
|
|
125
|
+
env?: Record<string, string>;
|
|
126
|
+
cwd?: string;
|
|
127
|
+
isolation?: boolean;
|
|
128
|
+
}): Promise<ExecutionSession>;
|
|
119
129
|
}
|
|
120
130
|
|
|
121
131
|
interface PreviewInfo {
|
|
@@ -156,52 +166,58 @@ interface HttpClientOptions {
|
|
|
156
166
|
declare class HttpClient {
|
|
157
167
|
private baseUrl;
|
|
158
168
|
private options;
|
|
159
|
-
private sessionId;
|
|
160
169
|
constructor(options?: HttpClientOptions);
|
|
161
170
|
protected doFetch(path: string, options?: RequestInit): Promise<Response>;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
171
|
+
createSession(options: {
|
|
172
|
+
id: string;
|
|
173
|
+
env?: Record<string, string>;
|
|
174
|
+
cwd?: string;
|
|
175
|
+
isolation?: boolean;
|
|
176
|
+
}): Promise<{
|
|
177
|
+
success: boolean;
|
|
178
|
+
id: string;
|
|
179
|
+
message: string;
|
|
180
|
+
}>;
|
|
181
|
+
exec(sessionId: string, command: string, options?: Pick<BaseExecOptions, "cwd" | "env">): Promise<ExecuteResponse>;
|
|
182
|
+
execStream(sessionId: string, command: string): Promise<ReadableStream<Uint8Array>>;
|
|
183
|
+
gitCheckout(repoUrl: string, sessionId: string, branch?: string, targetDir?: string): Promise<GitCheckoutResponse>;
|
|
184
|
+
mkdir(path: string, recursive: boolean | undefined, sessionId: string): Promise<MkdirResponse>;
|
|
185
|
+
writeFile(path: string, content: string, encoding: string | undefined, sessionId: string): Promise<WriteFileResponse>;
|
|
186
|
+
readFile(path: string, encoding: string | undefined, sessionId: string): Promise<ReadFileResponse>;
|
|
187
|
+
deleteFile(path: string, sessionId: string): Promise<DeleteFileResponse>;
|
|
188
|
+
renameFile(oldPath: string, newPath: string, sessionId: string): Promise<RenameFileResponse>;
|
|
189
|
+
moveFile(sourcePath: string, destinationPath: string, sessionId: string): Promise<MoveFileResponse>;
|
|
190
|
+
listFiles(path: string, sessionId: string, options?: {
|
|
172
191
|
recursive?: boolean;
|
|
173
192
|
includeHidden?: boolean;
|
|
174
|
-
}
|
|
193
|
+
}): Promise<ListFilesResponse>;
|
|
175
194
|
exposePort(port: number, name?: string): Promise<ExposePortResponse>;
|
|
176
195
|
unexposePort(port: number): Promise<UnexposePortResponse>;
|
|
177
196
|
getExposedPorts(): Promise<GetExposedPortsResponse>;
|
|
178
197
|
ping(): Promise<string>;
|
|
179
|
-
|
|
180
|
-
getSessionId(): string | null;
|
|
181
|
-
setSessionId(sessionId: string): void;
|
|
182
|
-
clearSession(): void;
|
|
183
|
-
startProcess(command: string, options?: {
|
|
198
|
+
startProcess(command: string, sessionId: string, options?: {
|
|
184
199
|
processId?: string;
|
|
185
|
-
sessionId?: string;
|
|
186
200
|
timeout?: number;
|
|
187
201
|
env?: Record<string, string>;
|
|
188
202
|
cwd?: string;
|
|
189
203
|
encoding?: string;
|
|
190
204
|
autoCleanup?: boolean;
|
|
191
205
|
}): Promise<StartProcessResponse>;
|
|
192
|
-
listProcesses(): Promise<ListProcessesResponse>;
|
|
206
|
+
listProcesses(sessionId?: string): Promise<ListProcessesResponse>;
|
|
193
207
|
getProcess(processId: string): Promise<GetProcessResponse>;
|
|
194
208
|
killProcess(processId: string): Promise<{
|
|
195
209
|
success: boolean;
|
|
196
210
|
message: string;
|
|
197
211
|
}>;
|
|
198
|
-
killAllProcesses(): Promise<{
|
|
212
|
+
killAllProcesses(sessionId?: string): Promise<{
|
|
199
213
|
success: boolean;
|
|
200
214
|
killedCount: number;
|
|
201
215
|
message: string;
|
|
202
216
|
}>;
|
|
203
217
|
getProcessLogs(processId: string): Promise<GetProcessLogsResponse>;
|
|
204
|
-
streamProcessLogs(processId: string
|
|
218
|
+
streamProcessLogs(processId: string, options?: {
|
|
219
|
+
signal?: AbortSignal;
|
|
220
|
+
}): Promise<ReadableStream<Uint8Array>>;
|
|
205
221
|
}
|
|
206
222
|
|
|
207
223
|
export { type ExecutionCallbacks as E, HttpClient as H, JupyterClient as J, Sandbox as S, getSandbox as g };
|
package/dist/client.d.ts
CHANGED
package/dist/client.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { CodeExecutionError, ContainerNotReadyError, ContextNotFoundError, JupyterNotReadyError, SandboxError, SandboxErrorResponse, SandboxNetworkError, ServiceUnavailableError, isJupyterNotReadyError, isRetryableError, isSandboxError, parseErrorResponse } from './errors.js';
|
|
2
2
|
export { ChartData, CodeContext, CreateContextOptions, Execution, ExecutionError, OutputMessage, Result, ResultImpl, RunCodeOptions } from './interpreter-types.js';
|
|
3
3
|
export { RouteInfo, SandboxEnv, proxyToSandbox } from './request-handler.js';
|
|
4
|
-
export { S as Sandbox, g as getSandbox } from './client-
|
|
4
|
+
export { S as Sandbox, g as getSandbox } from './client-Dny_ro_v.js';
|
|
5
5
|
export { asyncIterableToSSEStream, parseSSEStream, responseToAsyncIterable } from './sse-parser.js';
|
|
6
|
-
export { DeleteFileResponse, ExecEvent, ExecuteResponse, GitCheckoutResponse, ListFilesResponse, LogEvent, MkdirResponse, MoveFileResponse, ReadFileResponse, RenameFileResponse, WriteFileResponse } from './types.js';
|
|
6
|
+
export { DeleteFileResponse, ExecEvent, ExecOptions, ExecResult, ExecuteResponse, ExecutionSession, GitCheckoutResponse, ISandbox, ListFilesResponse, LogEvent, MkdirResponse, MoveFileResponse, Process, ProcessOptions, ProcessStatus, ReadFileResponse, RenameFileResponse, StreamOptions, WriteFileResponse } from './types.js';
|
|
7
7
|
import '@cloudflare/containers';
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Sandbox,
|
|
3
|
-
getSandbox,
|
|
4
|
-
proxyToSandbox
|
|
5
|
-
} from "./chunk-CKIGERRS.js";
|
|
6
|
-
import "./chunk-6UAWTJ5S.js";
|
|
7
1
|
import {
|
|
8
2
|
asyncIterableToSSEStream,
|
|
9
3
|
parseSSEStream,
|
|
10
4
|
responseToAsyncIterable
|
|
11
5
|
} from "./chunk-NNGBXDMY.js";
|
|
12
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
Sandbox,
|
|
8
|
+
getSandbox,
|
|
9
|
+
proxyToSandbox
|
|
10
|
+
} from "./chunk-LFLJGISB.js";
|
|
11
|
+
import "./chunk-6UAWTJ5S.js";
|
|
13
12
|
import "./chunk-FKBV7CZS.js";
|
|
14
13
|
import {
|
|
15
14
|
ResultImpl
|
|
16
15
|
} from "./chunk-EGC5IYXA.js";
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-BEQUGUY4.js";
|
|
17
|
+
import "./chunk-SMUEY5JR.js";
|
|
19
18
|
import {
|
|
20
19
|
CodeExecutionError,
|
|
21
20
|
ContainerNotReadyError,
|
package/dist/interpreter.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CreateContextOptions, CodeContext, RunCodeOptions, Execution } from './interpreter-types.js';
|
|
2
|
-
import { S as Sandbox } from './client-
|
|
2
|
+
import { S as Sandbox } from './client-Dny_ro_v.js';
|
|
3
3
|
import './types.js';
|
|
4
4
|
import '@cloudflare/containers';
|
|
5
5
|
|
package/dist/jupyter-client.d.ts
CHANGED
package/dist/jupyter-client.js
CHANGED
package/dist/request-handler.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isLocalhostPattern,
|
|
3
3
|
proxyToSandbox
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-LFLJGISB.js";
|
|
5
5
|
import "./chunk-6UAWTJ5S.js";
|
|
6
|
-
import "./chunk-NNGBXDMY.js";
|
|
7
|
-
import "./chunk-6EWSYSO7.js";
|
|
8
6
|
import "./chunk-FKBV7CZS.js";
|
|
9
7
|
import "./chunk-EGC5IYXA.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-BEQUGUY4.js";
|
|
9
|
+
import "./chunk-SMUEY5JR.js";
|
|
12
10
|
import "./chunk-LALY4SFU.js";
|
|
13
11
|
export {
|
|
14
12
|
isLocalhostPattern,
|
package/dist/sandbox.d.ts
CHANGED
package/dist/sandbox.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Sandbox,
|
|
3
3
|
getSandbox
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-LFLJGISB.js";
|
|
5
5
|
import "./chunk-6UAWTJ5S.js";
|
|
6
|
-
import "./chunk-NNGBXDMY.js";
|
|
7
|
-
import "./chunk-6EWSYSO7.js";
|
|
8
6
|
import "./chunk-FKBV7CZS.js";
|
|
9
7
|
import "./chunk-EGC5IYXA.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-BEQUGUY4.js";
|
|
9
|
+
import "./chunk-SMUEY5JR.js";
|
|
12
10
|
import "./chunk-LALY4SFU.js";
|
|
13
11
|
export {
|
|
14
12
|
Sandbox,
|
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { CreateContextOptions, CodeContext, RunCodeOptions, ExecutionResult } from './interpreter-types.js';
|
|
2
2
|
|
|
3
3
|
interface BaseExecOptions {
|
|
4
|
-
/**
|
|
5
|
-
* Session ID for grouping related commands
|
|
6
|
-
*/
|
|
7
|
-
sessionId?: string;
|
|
8
4
|
/**
|
|
9
5
|
* Maximum execution time in milliseconds
|
|
10
6
|
*/
|
|
@@ -73,10 +69,6 @@ interface ExecResult {
|
|
|
73
69
|
* ISO timestamp when command started
|
|
74
70
|
*/
|
|
75
71
|
timestamp: string;
|
|
76
|
-
/**
|
|
77
|
-
* Session ID if provided
|
|
78
|
-
*/
|
|
79
|
-
sessionId?: string;
|
|
80
72
|
}
|
|
81
73
|
interface ProcessOptions extends BaseExecOptions {
|
|
82
74
|
/**
|
|
@@ -135,10 +127,6 @@ interface Process {
|
|
|
135
127
|
* Process exit code (if completed)
|
|
136
128
|
*/
|
|
137
129
|
readonly exitCode?: number;
|
|
138
|
-
/**
|
|
139
|
-
* Session ID if provided
|
|
140
|
-
*/
|
|
141
|
-
readonly sessionId?: string;
|
|
142
130
|
/**
|
|
143
131
|
* Kill the process
|
|
144
132
|
*/
|
|
@@ -163,14 +151,12 @@ interface ExecEvent {
|
|
|
163
151
|
exitCode?: number;
|
|
164
152
|
result?: ExecResult;
|
|
165
153
|
error?: string;
|
|
166
|
-
sessionId?: string;
|
|
167
154
|
}
|
|
168
155
|
interface LogEvent {
|
|
169
156
|
type: 'stdout' | 'stderr' | 'exit' | 'error';
|
|
170
157
|
timestamp: string;
|
|
171
158
|
data: string;
|
|
172
159
|
processId: string;
|
|
173
|
-
sessionId?: string;
|
|
174
160
|
exitCode?: number;
|
|
175
161
|
}
|
|
176
162
|
interface StreamOptions extends BaseExecOptions {
|
|
@@ -204,8 +190,6 @@ interface ProcessRecord {
|
|
|
204
190
|
startTime: Date;
|
|
205
191
|
endTime?: Date;
|
|
206
192
|
exitCode?: number;
|
|
207
|
-
sessionId?: string;
|
|
208
|
-
childProcess?: any;
|
|
209
193
|
stdout: string;
|
|
210
194
|
stderr: string;
|
|
211
195
|
outputListeners: Set<(stream: 'stdout' | 'stderr', data: string) => void>;
|
|
@@ -215,7 +199,6 @@ interface StartProcessRequest {
|
|
|
215
199
|
command: string;
|
|
216
200
|
options?: {
|
|
217
201
|
processId?: string;
|
|
218
|
-
sessionId?: string;
|
|
219
202
|
timeout?: number;
|
|
220
203
|
env?: Record<string, string>;
|
|
221
204
|
cwd?: string;
|
|
@@ -230,7 +213,9 @@ interface StartProcessResponse {
|
|
|
230
213
|
command: string;
|
|
231
214
|
status: ProcessStatus;
|
|
232
215
|
startTime: string;
|
|
233
|
-
|
|
216
|
+
endTime?: string | null;
|
|
217
|
+
exitCode?: number | null;
|
|
218
|
+
sessionId: string;
|
|
234
219
|
};
|
|
235
220
|
}
|
|
236
221
|
interface ListProcessesResponse {
|
|
@@ -242,7 +227,6 @@ interface ListProcessesResponse {
|
|
|
242
227
|
startTime: string;
|
|
243
228
|
endTime?: string;
|
|
244
229
|
exitCode?: number;
|
|
245
|
-
sessionId?: string;
|
|
246
230
|
}>;
|
|
247
231
|
}
|
|
248
232
|
interface GetProcessResponse {
|
|
@@ -254,7 +238,6 @@ interface GetProcessResponse {
|
|
|
254
238
|
startTime: string;
|
|
255
239
|
endTime?: string;
|
|
256
240
|
exitCode?: number;
|
|
257
|
-
sessionId?: string;
|
|
258
241
|
} | null;
|
|
259
242
|
}
|
|
260
243
|
interface GetProcessLogsResponse {
|
|
@@ -322,6 +305,12 @@ interface ISandbox {
|
|
|
322
305
|
listCodeContexts(): Promise<CodeContext[]>;
|
|
323
306
|
deleteCodeContext(contextId: string): Promise<void>;
|
|
324
307
|
}
|
|
308
|
+
interface ExecutionSession extends Omit<ISandbox, 'createSession' | 'setSandboxName'> {
|
|
309
|
+
/**
|
|
310
|
+
* Session ID
|
|
311
|
+
*/
|
|
312
|
+
id: string;
|
|
313
|
+
}
|
|
325
314
|
interface ExecuteResponse {
|
|
326
315
|
success: boolean;
|
|
327
316
|
stdout: string;
|
|
@@ -406,4 +395,4 @@ declare function isExecResult(value: any): value is ExecResult;
|
|
|
406
395
|
declare function isProcess(value: any): value is Process;
|
|
407
396
|
declare function isProcessStatus(value: string): value is ProcessStatus;
|
|
408
397
|
|
|
409
|
-
export { type BaseExecOptions, type DeleteFileResponse, type ExecEvent, type ExecOptions, type ExecResult, type ExecuteResponse, ExecutionTimeoutError, type GetProcessLogsResponse, type GetProcessResponse, type GitCheckoutResponse, type ISandbox, type ListFilesResponse, type ListProcessesResponse, type LogEvent, type MkdirResponse, type MoveFileResponse, type Process, ProcessAlreadyExistsError, ProcessNotFoundError, type ProcessOptions, type ProcessRecord, type ProcessStatus, type ReadFileResponse, type RenameFileResponse, SandboxError, type StartProcessRequest, type StartProcessResponse, type StreamOptions, type WriteFileResponse, isExecResult, isProcess, isProcessStatus };
|
|
398
|
+
export { type BaseExecOptions, type DeleteFileResponse, type ExecEvent, type ExecOptions, type ExecResult, type ExecuteResponse, type ExecutionSession, ExecutionTimeoutError, type GetProcessLogsResponse, type GetProcessResponse, type GitCheckoutResponse, type ISandbox, type ListFilesResponse, type ListProcessesResponse, type LogEvent, type MkdirResponse, type MoveFileResponse, type Process, ProcessAlreadyExistsError, ProcessNotFoundError, type ProcessOptions, type ProcessRecord, type ProcessStatus, type ReadFileResponse, type RenameFileResponse, SandboxError, type StartProcessRequest, type StartProcessResponse, type StreamOptions, type WriteFileResponse, isExecResult, isProcess, isProcessStatus };
|
package/dist/types.js
CHANGED
|
@@ -1,12 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var SandboxError = class extends Error {
|
|
3
|
+
constructor(message, code) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.name = "SandboxError";
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
var ProcessNotFoundError = class extends SandboxError {
|
|
10
|
+
constructor(processId) {
|
|
11
|
+
super(`Process not found: ${processId}`, "PROCESS_NOT_FOUND");
|
|
12
|
+
this.name = "ProcessNotFoundError";
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var ProcessAlreadyExistsError = class extends SandboxError {
|
|
16
|
+
constructor(processId) {
|
|
17
|
+
super(`Process already exists: ${processId}`, "PROCESS_EXISTS");
|
|
18
|
+
this.name = "ProcessAlreadyExistsError";
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var ExecutionTimeoutError = class extends SandboxError {
|
|
22
|
+
constructor(timeout) {
|
|
23
|
+
super(`Execution timed out after ${timeout}ms`, "EXECUTION_TIMEOUT");
|
|
24
|
+
this.name = "ExecutionTimeoutError";
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
function isExecResult(value) {
|
|
28
|
+
return value && typeof value.success === "boolean" && typeof value.exitCode === "number" && typeof value.stdout === "string" && typeof value.stderr === "string";
|
|
29
|
+
}
|
|
30
|
+
function isProcess(value) {
|
|
31
|
+
return value && typeof value.id === "string" && typeof value.command === "string" && typeof value.status === "string";
|
|
32
|
+
}
|
|
33
|
+
function isProcessStatus(value) {
|
|
34
|
+
return ["starting", "running", "completed", "failed", "killed", "error"].includes(value);
|
|
35
|
+
}
|
|
10
36
|
export {
|
|
11
37
|
ExecutionTimeoutError,
|
|
12
38
|
ProcessAlreadyExistsError,
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["// Core Types\n\nexport interface BaseExecOptions {\n /**\n * Maximum execution time in milliseconds\n */\n timeout?: number;\n\n /**\n * Environment variables for the command\n */\n env?: Record<string, string>;\n\n /**\n * Working directory for command execution\n */\n cwd?: string;\n\n /**\n * Text encoding for output (default: 'utf8')\n */\n encoding?: string;\n}\n\nexport interface ExecOptions extends BaseExecOptions {\n /**\n * Enable real-time output streaming via callbacks\n */\n stream?: boolean;\n\n /**\n * Callback for real-time output data\n */\n onOutput?: (stream: 'stdout' | 'stderr', data: string) => void;\n\n /**\n * Callback when command completes (only when stream: true)\n */\n onComplete?: (result: ExecResult) => void;\n\n /**\n * Callback for execution errors\n */\n onError?: (error: Error) => void;\n\n /**\n * AbortSignal for cancelling execution\n */\n signal?: AbortSignal;\n}\n\nexport interface ExecResult {\n /**\n * Whether the command succeeded (exitCode === 0)\n */\n success: boolean;\n\n /**\n * Process exit code\n */\n exitCode: number;\n\n /**\n * Standard output content\n */\n stdout: string;\n\n /**\n * Standard error content\n */\n stderr: string;\n\n /**\n * Command that was executed\n */\n command: string;\n\n\n /**\n * Execution duration in milliseconds\n */\n duration: number;\n\n /**\n * ISO timestamp when command started\n */\n timestamp: string;\n}\n\n// Background Process Types\n\nexport interface ProcessOptions extends BaseExecOptions {\n /**\n * Custom process ID for later reference\n * If not provided, a UUID will be generated\n */\n processId?: string;\n\n /**\n * Automatically cleanup process record after exit (default: true)\n */\n autoCleanup?: boolean;\n\n /**\n * Callback when process exits\n */\n onExit?: (code: number | null) => void;\n\n /**\n * Callback for real-time output (background processes)\n */\n onOutput?: (stream: 'stdout' | 'stderr', data: string) => void;\n\n /**\n * Callback when process starts successfully\n */\n onStart?: (process: Process) => void;\n\n /**\n * Callback for process errors\n */\n onError?: (error: Error) => void;\n}\n\nexport type ProcessStatus =\n | 'starting' // Process is being initialized\n | 'running' // Process is actively running\n | 'completed' // Process exited successfully (code 0)\n | 'failed' // Process exited with non-zero code\n | 'killed' // Process was terminated by signal\n | 'error'; // Process failed to start or encountered error\n\nexport interface Process {\n /**\n * Unique process identifier\n */\n readonly id: string;\n\n /**\n * System process ID (if available and running)\n */\n readonly pid?: number;\n\n /**\n * Command that was executed\n */\n readonly command: string;\n\n\n /**\n * Current process status\n */\n readonly status: ProcessStatus;\n\n /**\n * When the process was started\n */\n readonly startTime: Date;\n\n /**\n * When the process ended (if completed)\n */\n readonly endTime?: Date;\n\n /**\n * Process exit code (if completed)\n */\n readonly exitCode?: number;\n\n /**\n * Kill the process\n */\n kill(signal?: string): Promise<void>;\n\n /**\n * Get current process status (refreshed)\n */\n getStatus(): Promise<ProcessStatus>;\n\n /**\n * Get accumulated logs\n */\n getLogs(): Promise<{ stdout: string; stderr: string }>;\n}\n\n// Streaming Types\n\nexport interface ExecEvent {\n type: 'start' | 'stdout' | 'stderr' | 'complete' | 'error';\n timestamp: string;\n data?: string;\n command?: string;\n exitCode?: number;\n result?: ExecResult;\n error?: string; // Changed to string for serialization\n}\n\nexport interface LogEvent {\n type: 'stdout' | 'stderr' | 'exit' | 'error';\n timestamp: string;\n data: string;\n processId: string;\n exitCode?: number; // For 'exit' events\n}\n\nexport interface StreamOptions extends BaseExecOptions {\n /**\n * Buffer size for streaming output\n */\n bufferSize?: number;\n\n /**\n * AbortSignal for cancelling stream\n */\n signal?: AbortSignal;\n}\n\n// Error Types\n\nexport class SandboxError extends Error {\n constructor(message: string, public code?: string) {\n super(message);\n this.name = 'SandboxError';\n }\n}\n\nexport class ProcessNotFoundError extends SandboxError {\n constructor(processId: string) {\n super(`Process not found: ${processId}`, 'PROCESS_NOT_FOUND');\n this.name = 'ProcessNotFoundError';\n }\n}\n\nexport class ProcessAlreadyExistsError extends SandboxError {\n constructor(processId: string) {\n super(`Process already exists: ${processId}`, 'PROCESS_EXISTS');\n this.name = 'ProcessAlreadyExistsError';\n }\n}\n\nexport class ExecutionTimeoutError extends SandboxError {\n constructor(timeout: number) {\n super(`Execution timed out after ${timeout}ms`, 'EXECUTION_TIMEOUT');\n this.name = 'ExecutionTimeoutError';\n }\n}\n\n// Internal Container Types\n\nexport interface ProcessRecord {\n id: string;\n pid?: number;\n command: string;\n status: ProcessStatus;\n startTime: Date;\n endTime?: Date;\n exitCode?: number;\n\n // Internal fields\n stdout: string; // Accumulated output (ephemeral)\n stderr: string; // Accumulated output (ephemeral)\n\n // Streaming\n outputListeners: Set<(stream: 'stdout' | 'stderr', data: string) => void>;\n statusListeners: Set<(status: ProcessStatus) => void>;\n}\n\n// Container Request/Response Types\n\nexport interface StartProcessRequest {\n command: string;\n options?: {\n processId?: string;\n timeout?: number;\n env?: Record<string, string>;\n cwd?: string;\n encoding?: string;\n autoCleanup?: boolean;\n };\n}\n\nexport interface StartProcessResponse {\n process: {\n id: string;\n pid?: number;\n command: string;\n status: ProcessStatus;\n startTime: string;\n endTime?: string | null;\n exitCode?: number | null;\n sessionId: string;\n };\n}\n\nexport interface ListProcessesResponse {\n processes: Array<{\n id: string;\n pid?: number;\n command: string;\n status: ProcessStatus;\n startTime: string;\n endTime?: string;\n exitCode?: number;\n }>;\n}\n\nexport interface GetProcessResponse {\n process: {\n id: string;\n pid?: number;\n command: string;\n status: ProcessStatus;\n startTime: string;\n endTime?: string;\n exitCode?: number;\n } | null;\n}\n\nexport interface GetProcessLogsResponse {\n stdout: string;\n stderr: string;\n processId: string;\n}\n\n// Import code interpreter types\nimport type {\n CodeContext,\n CreateContextOptions,\n ExecutionResult, \n RunCodeOptions\n} from './interpreter-types';\n\n// Main Sandbox Interface\n\nexport interface ISandbox {\n // Enhanced execution API\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n\n // Background process management\n startProcess(command: string, options?: ProcessOptions): Promise<Process>;\n listProcesses(): Promise<Process[]>;\n getProcess(id: string): Promise<Process | null>;\n killProcess(id: string, signal?: string): Promise<void>;\n killAllProcesses(): Promise<number>;\n\n // Advanced streaming - returns ReadableStream that can be converted to AsyncIterable\n execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;\n streamProcessLogs(processId: string, options?: { signal?: AbortSignal }): Promise<ReadableStream<Uint8Array>>;\n\n // Utility methods\n cleanupCompletedProcesses(): Promise<number>;\n getProcessLogs(id: string): Promise<{ stdout: string; stderr: string }>;\n\n // File operations\n gitCheckout(repoUrl: string, options: { branch?: string; targetDir?: string }): Promise<GitCheckoutResponse>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<MkdirResponse>;\n writeFile(path: string, content: string, options?: { encoding?: string }): Promise<WriteFileResponse>;\n deleteFile(path: string): Promise<DeleteFileResponse>;\n renameFile(oldPath: string, newPath: string): Promise<RenameFileResponse>;\n moveFile(sourcePath: string, destinationPath: string): Promise<MoveFileResponse>;\n readFile(path: string, options?: { encoding?: string }): Promise<ReadFileResponse>;\n listFiles(path: string, options?: { recursive?: boolean; includeHidden?: boolean }): Promise<ListFilesResponse>;\n\n // Port management\n exposePort(port: number, options: { name?: string; hostname: string }): Promise<{ url: string; port: number; name?: string }>;\n unexposePort(port: number): Promise<void>;\n getExposedPorts(hostname: string): Promise<Array<{ url: string; port: number; name?: string; exposedAt: string }>>;\n\n // Environment management\n setEnvVars(envVars: Record<string, string>): Promise<void>;\n setSandboxName(name: string): Promise<void>;\n\n // Code Interpreter API\n createCodeContext(options?: CreateContextOptions): Promise<CodeContext>;\n runCode(code: string, options?: RunCodeOptions): Promise<ExecutionResult>;\n runCodeStream(code: string, options?: RunCodeOptions): Promise<ReadableStream>;\n listCodeContexts(): Promise<CodeContext[]>;\n deleteCodeContext(contextId: string): Promise<void>;\n}\n\n// Execution session returned by createSession()\n// Sessions are full-featured sandbox objects with scoped execution context\n// Inherits all ISandbox methods except createSession (sessions can't create sub-sessions),\n// and setSandboxName (sessions inherit sandbox name).\nexport interface ExecutionSession extends Omit<ISandbox, 'createSession' | 'setSandboxName'> {\n /**\n * Session ID\n */\n id: string;\n}\n\n// API Response Types\n\nexport interface ExecuteResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n command: string;\n timestamp: string;\n}\n\nexport interface GitCheckoutResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n repoUrl: string;\n branch: string;\n targetDir: string;\n timestamp: string;\n}\n\nexport interface MkdirResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n path: string;\n recursive: boolean;\n timestamp: string;\n}\n\nexport interface WriteFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n timestamp: string;\n}\n\nexport interface ReadFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n content: string;\n timestamp: string;\n}\n\nexport interface DeleteFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n timestamp: string;\n}\n\nexport interface RenameFileResponse {\n success: boolean;\n exitCode: number;\n oldPath: string;\n newPath: string;\n timestamp: string;\n}\n\nexport interface MoveFileResponse {\n success: boolean;\n exitCode: number;\n sourcePath: string;\n destinationPath: string;\n timestamp: string;\n}\n\nexport interface ListFilesResponse {\n success: boolean;\n exitCode: number;\n path: string;\n files: Array<{\n name: string;\n absolutePath: string;\n relativePath: string;\n type: 'file' | 'directory' | 'symlink' | 'other';\n size: number;\n modifiedAt: string;\n mode: string;\n permissions: {\n readable: boolean;\n writable: boolean;\n executable: boolean;\n };\n }>;\n timestamp: string;\n}\n\n// Type Guards\n\nexport function isExecResult(value: any): value is ExecResult {\n return value &&\n typeof value.success === 'boolean' &&\n typeof value.exitCode === 'number' &&\n typeof value.stdout === 'string' &&\n typeof value.stderr === 'string';\n}\n\nexport function isProcess(value: any): value is Process {\n return value &&\n typeof value.id === 'string' &&\n typeof value.command === 'string' &&\n typeof value.status === 'string';\n}\n\nexport function isProcessStatus(value: string): value is ProcessStatus {\n return ['starting', 'running', 'completed', 'failed', 'killed', 'error'].includes(value);\n}"],"mappings":";AA2NO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YAAY,SAAwB,MAAe;AACjD,UAAM,OAAO;AADqB;AAElC,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,uBAAN,cAAmC,aAAa;AAAA,EACrD,YAAY,WAAmB;AAC7B,UAAM,sBAAsB,SAAS,IAAI,mBAAmB;AAC5D,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,4BAAN,cAAwC,aAAa;AAAA,EAC1D,YAAY,WAAmB;AAC7B,UAAM,2BAA2B,SAAS,IAAI,gBAAgB;AAC9D,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,wBAAN,cAAoC,aAAa;AAAA,EACtD,YAAY,SAAiB;AAC3B,UAAM,6BAA6B,OAAO,MAAM,mBAAmB;AACnE,SAAK,OAAO;AAAA,EACd;AACF;AA+OO,SAAS,aAAa,OAAiC;AAC5D,SAAO,SACL,OAAO,MAAM,YAAY,aACzB,OAAO,MAAM,aAAa,YAC1B,OAAO,MAAM,WAAW,YACxB,OAAO,MAAM,WAAW;AAC5B;AAEO,SAAS,UAAU,OAA8B;AACtD,SAAO,SACL,OAAO,MAAM,OAAO,YACpB,OAAO,MAAM,YAAY,YACzB,OAAO,MAAM,WAAW;AAC5B;AAEO,SAAS,gBAAgB,OAAuC;AACrE,SAAO,CAAC,YAAY,WAAW,aAAa,UAAU,UAAU,OAAO,EAAE,SAAS,KAAK;AACzF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudflare/sandbox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/cloudflare/sandbox-sdk"
|
|
7
7
|
},
|
|
8
8
|
"description": "A sandboxed environment for running commands",
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@cloudflare/containers": "^0.0.
|
|
10
|
+
"@cloudflare/containers": "^0.0.27"
|
|
11
11
|
},
|
|
12
12
|
"tags": [
|
|
13
13
|
"sandbox",
|