@cloudflare/sandbox 0.2.3 → 0.3.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/CHANGELOG.md +69 -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 +204 -642
- 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 +74 -129
- package/container_src/isolation.ts +1039 -0
- package/container_src/jupyter-service.ts +8 -5
- package/container_src/shell-escape.ts +42 -0
- package/container_src/types.ts +35 -12
- package/dist/{chunk-VTKZL632.js → chunk-BEQUGUY4.js} +2 -2
- package/dist/{chunk-4KELYYKS.js → chunk-GTGWAEED.js} +239 -265
- package/dist/chunk-GTGWAEED.js.map +1 -0
- package/dist/{chunk-CUHYLCMT.js → chunk-SMUEY5JR.js} +111 -99
- package/dist/chunk-SMUEY5JR.js.map +1 -0
- package/dist/{client-bzEV222a.d.ts → client-Dny_ro_v.d.ts} +48 -84
- 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 +2 -2
- package/dist/jupyter-client.d.ts +2 -2
- package/dist/jupyter-client.js +2 -2
- package/dist/request-handler.d.ts +3 -3
- package/dist/request-handler.js +3 -5
- package/dist/sandbox.d.ts +2 -2
- package/dist/sandbox.js +3 -5
- package/dist/types.d.ts +127 -21
- package/dist/types.js +35 -9
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +175 -187
- package/src/index.ts +23 -13
- package/src/sandbox.ts +297 -332
- package/src/types.ts +125 -24
- package/dist/chunk-4KELYYKS.js.map +0 -1
- package/dist/chunk-CUHYLCMT.js.map +0 -1
- package/dist/chunk-S5FFBU4Y.js +0 -46
- package/dist/chunk-S5FFBU4Y.js.map +0 -1
- /package/dist/{chunk-VTKZL632.js.map → chunk-BEQUGUY4.js.map} +0 -0
|
@@ -141,13 +141,16 @@ export class JupyterService {
|
|
|
141
141
|
"[JupyterService] Pre-warming context pools for better performance"
|
|
142
142
|
);
|
|
143
143
|
|
|
144
|
-
//
|
|
144
|
+
// Only pre-warm Python contexts to avoid Bun WebSocket validation errors
|
|
145
|
+
// JavaScript contexts will be created on-demand
|
|
145
146
|
await this.jupyterServer.enablePoolWarming("python", 1);
|
|
146
147
|
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
// Commenting out JavaScript pre-warming due to kernel message validation errors
|
|
149
|
+
// The errors appear to be related to Bun's handling of WebSocket messages
|
|
150
|
+
// JavaScript contexts still work fine when created on-demand
|
|
151
|
+
//
|
|
152
|
+
// await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
153
|
+
// await this.jupyterServer.enablePoolWarming("javascript", 1);
|
|
151
154
|
} catch (error) {
|
|
152
155
|
console.error("[JupyterService] Error pre-warming context pools:", error);
|
|
153
156
|
console.error(
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure shell command utilities to prevent injection attacks
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Escapes a string for safe use in shell commands.
|
|
7
|
+
* This follows POSIX shell escaping rules to prevent command injection.
|
|
8
|
+
*
|
|
9
|
+
* @param str - The string to escape
|
|
10
|
+
* @returns The escaped string safe for shell use
|
|
11
|
+
*/
|
|
12
|
+
export function escapeShellArg(str: string): string {
|
|
13
|
+
// If string is empty, return empty quotes
|
|
14
|
+
if (str === '') {
|
|
15
|
+
return "''";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Check if string contains any characters that need escaping
|
|
19
|
+
// Safe characters: alphanumeric, dash, underscore, dot, slash
|
|
20
|
+
if (/^[a-zA-Z0-9._\-/]+$/.test(str)) {
|
|
21
|
+
return str;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// For strings with special characters, use single quotes and escape single quotes
|
|
25
|
+
// Single quotes preserve all characters literally except the single quote itself
|
|
26
|
+
// To include a single quote, we end the quoted string, add an escaped quote, and start a new quoted string
|
|
27
|
+
return `'${str.replace(/'/g, "'\\''")}'`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Escapes a file path for safe use in shell commands.
|
|
32
|
+
*
|
|
33
|
+
* @param path - The file path to escape
|
|
34
|
+
* @returns The escaped path safe for shell use
|
|
35
|
+
*/
|
|
36
|
+
export function escapeShellPath(path: string): string {
|
|
37
|
+
// Normalize path to prevent issues with multiple slashes
|
|
38
|
+
const normalizedPath = path.replace(/\/+/g, '/');
|
|
39
|
+
|
|
40
|
+
// Apply standard shell escaping
|
|
41
|
+
return escapeShellArg(normalizedPath);
|
|
42
|
+
}
|
package/container_src/types.ts
CHANGED
|
@@ -17,19 +17,20 @@ export interface ProcessRecord {
|
|
|
17
17
|
startTime: Date;
|
|
18
18
|
endTime?: Date;
|
|
19
19
|
exitCode?: number;
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
stdoutFile?: string; // Path to temp file containing stdout
|
|
21
|
+
stderrFile?: string; // Path to temp file containing stderr
|
|
22
22
|
stdout: string;
|
|
23
23
|
stderr: string;
|
|
24
24
|
outputListeners: Set<(stream: 'stdout' | 'stderr', data: string) => void>;
|
|
25
25
|
statusListeners: Set<(status: ProcessStatus) => void>;
|
|
26
|
+
monitoringInterval?: NodeJS.Timeout; // For polling temp files when streaming
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
export interface StartProcessRequest {
|
|
29
30
|
command: string;
|
|
31
|
+
sessionId: string;
|
|
30
32
|
options?: {
|
|
31
33
|
processId?: string;
|
|
32
|
-
sessionId?: string;
|
|
33
34
|
timeout?: number;
|
|
34
35
|
env?: Record<string, string>;
|
|
35
36
|
cwd?: string;
|
|
@@ -39,7 +40,6 @@ export interface StartProcessRequest {
|
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
export interface ExecuteOptions {
|
|
42
|
-
sessionId?: string | null;
|
|
43
43
|
background?: boolean;
|
|
44
44
|
cwd?: string | URL;
|
|
45
45
|
env?: Record<string, string>;
|
|
@@ -47,49 +47,59 @@ export interface ExecuteOptions {
|
|
|
47
47
|
|
|
48
48
|
export interface ExecuteRequest extends ExecuteOptions {
|
|
49
49
|
command: string;
|
|
50
|
+
sessionId: string;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
export interface GitCheckoutRequest {
|
|
53
54
|
repoUrl: string;
|
|
54
55
|
branch?: string;
|
|
55
56
|
targetDir?: string;
|
|
56
|
-
sessionId
|
|
57
|
+
sessionId: string;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
export interface MkdirRequest {
|
|
60
61
|
path: string;
|
|
61
62
|
recursive?: boolean;
|
|
62
|
-
sessionId
|
|
63
|
+
sessionId: string;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
export interface WriteFileRequest {
|
|
66
67
|
path: string;
|
|
67
68
|
content: string;
|
|
68
69
|
encoding?: string;
|
|
69
|
-
sessionId
|
|
70
|
+
sessionId: string;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
export interface ReadFileRequest {
|
|
73
74
|
path: string;
|
|
74
75
|
encoding?: string;
|
|
75
|
-
sessionId
|
|
76
|
+
sessionId: string;
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
export interface DeleteFileRequest {
|
|
79
80
|
path: string;
|
|
80
|
-
sessionId
|
|
81
|
+
sessionId: string;
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
export interface RenameFileRequest {
|
|
84
85
|
oldPath: string;
|
|
85
86
|
newPath: string;
|
|
86
|
-
sessionId
|
|
87
|
+
sessionId: string;
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
export interface MoveFileRequest {
|
|
90
91
|
sourcePath: string;
|
|
91
92
|
destinationPath: string;
|
|
92
|
-
sessionId
|
|
93
|
+
sessionId: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface ListFilesRequest {
|
|
97
|
+
path: string;
|
|
98
|
+
options?: {
|
|
99
|
+
recursive?: boolean;
|
|
100
|
+
includeHidden?: boolean;
|
|
101
|
+
};
|
|
102
|
+
sessionId: string;
|
|
93
103
|
}
|
|
94
104
|
|
|
95
105
|
export interface ExposePortRequest {
|
|
@@ -102,7 +112,20 @@ export interface UnexposePortRequest {
|
|
|
102
112
|
}
|
|
103
113
|
|
|
104
114
|
export interface SessionData {
|
|
105
|
-
|
|
115
|
+
id: string;
|
|
106
116
|
activeProcess: ChildProcess | null;
|
|
107
117
|
createdAt: Date;
|
|
108
118
|
}
|
|
119
|
+
|
|
120
|
+
// Session management API types
|
|
121
|
+
export interface CreateSessionRequest {
|
|
122
|
+
id: string;
|
|
123
|
+
env?: Record<string, string>;
|
|
124
|
+
cwd?: string;
|
|
125
|
+
isolation?: boolean;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface SessionExecRequest {
|
|
129
|
+
id: string;
|
|
130
|
+
command: string;
|
|
131
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
HttpClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SMUEY5JR.js";
|
|
4
4
|
import {
|
|
5
5
|
isRetryableError,
|
|
6
6
|
parseErrorResponse
|
|
@@ -234,4 +234,4 @@ var JupyterClient = class extends HttpClient {
|
|
|
234
234
|
export {
|
|
235
235
|
JupyterClient
|
|
236
236
|
};
|
|
237
|
-
//# sourceMappingURL=chunk-
|
|
237
|
+
//# sourceMappingURL=chunk-BEQUGUY4.js.map
|