@cloudflare/sandbox 0.3.7 → 0.4.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.
Files changed (120) hide show
  1. package/.turbo/turbo-build.log +44 -0
  2. package/CHANGELOG.md +6 -14
  3. package/Dockerfile +82 -18
  4. package/README.md +89 -824
  5. package/dist/{chunk-JTKON2SH.js → chunk-BCJ7SF3Q.js} +9 -5
  6. package/dist/chunk-BCJ7SF3Q.js.map +1 -0
  7. package/dist/chunk-BFVUNTP4.js +104 -0
  8. package/dist/chunk-BFVUNTP4.js.map +1 -0
  9. package/dist/{chunk-NNGBXDMY.js → chunk-EKSWCBCA.js} +3 -6
  10. package/dist/chunk-EKSWCBCA.js.map +1 -0
  11. package/dist/chunk-HGF554LH.js +2236 -0
  12. package/dist/chunk-HGF554LH.js.map +1 -0
  13. package/dist/{chunk-6UAWTJ5S.js → chunk-Z532A7QC.js} +13 -20
  14. package/dist/{chunk-6UAWTJ5S.js.map → chunk-Z532A7QC.js.map} +1 -1
  15. package/dist/file-stream.d.ts +16 -38
  16. package/dist/file-stream.js +1 -2
  17. package/dist/index.d.ts +6 -5
  18. package/dist/index.js +35 -39
  19. package/dist/index.js.map +1 -1
  20. package/dist/interpreter.d.ts +3 -3
  21. package/dist/interpreter.js +2 -2
  22. package/dist/request-handler.d.ts +4 -3
  23. package/dist/request-handler.js +4 -7
  24. package/dist/sandbox-D9K2ypln.d.ts +583 -0
  25. package/dist/sandbox.d.ts +3 -3
  26. package/dist/sandbox.js +4 -7
  27. package/dist/security.d.ts +4 -3
  28. package/dist/security.js +3 -3
  29. package/dist/sse-parser.js +1 -1
  30. package/package.json +11 -5
  31. package/src/clients/base-client.ts +280 -0
  32. package/src/clients/command-client.ts +115 -0
  33. package/src/clients/file-client.ts +269 -0
  34. package/src/clients/git-client.ts +92 -0
  35. package/src/clients/index.ts +63 -0
  36. package/src/{interpreter-client.ts → clients/interpreter-client.ts} +148 -171
  37. package/src/clients/port-client.ts +105 -0
  38. package/src/clients/process-client.ts +177 -0
  39. package/src/clients/sandbox-client.ts +41 -0
  40. package/src/clients/types.ts +84 -0
  41. package/src/clients/utility-client.ts +94 -0
  42. package/src/errors/adapter.ts +180 -0
  43. package/src/errors/classes.ts +469 -0
  44. package/src/errors/index.ts +105 -0
  45. package/src/file-stream.ts +119 -117
  46. package/src/index.ts +81 -69
  47. package/src/interpreter.ts +17 -8
  48. package/src/request-handler.ts +69 -43
  49. package/src/sandbox.ts +694 -533
  50. package/src/security.ts +14 -23
  51. package/src/sse-parser.ts +4 -8
  52. package/startup.sh +3 -0
  53. package/tests/base-client.test.ts +328 -0
  54. package/tests/command-client.test.ts +407 -0
  55. package/tests/file-client.test.ts +643 -0
  56. package/tests/file-stream.test.ts +306 -0
  57. package/tests/git-client.test.ts +328 -0
  58. package/tests/port-client.test.ts +301 -0
  59. package/tests/process-client.test.ts +658 -0
  60. package/tests/sandbox.test.ts +465 -0
  61. package/tests/sse-parser.test.ts +290 -0
  62. package/tests/utility-client.test.ts +266 -0
  63. package/tests/wrangler.jsonc +35 -0
  64. package/tsconfig.json +9 -1
  65. package/vitest.config.ts +31 -0
  66. package/container_src/bun.lock +0 -76
  67. package/container_src/circuit-breaker.ts +0 -121
  68. package/container_src/control-process.ts +0 -784
  69. package/container_src/handler/exec.ts +0 -185
  70. package/container_src/handler/file.ts +0 -457
  71. package/container_src/handler/git.ts +0 -130
  72. package/container_src/handler/ports.ts +0 -314
  73. package/container_src/handler/process.ts +0 -568
  74. package/container_src/handler/session.ts +0 -92
  75. package/container_src/index.ts +0 -601
  76. package/container_src/interpreter-service.ts +0 -276
  77. package/container_src/isolation.ts +0 -1213
  78. package/container_src/mime-processor.ts +0 -255
  79. package/container_src/package.json +0 -18
  80. package/container_src/runtime/executors/javascript/node_executor.ts +0 -123
  81. package/container_src/runtime/executors/python/ipython_executor.py +0 -338
  82. package/container_src/runtime/executors/typescript/ts_executor.ts +0 -138
  83. package/container_src/runtime/process-pool.ts +0 -464
  84. package/container_src/shell-escape.ts +0 -42
  85. package/container_src/startup.sh +0 -11
  86. package/container_src/types.ts +0 -131
  87. package/dist/chunk-32UDXUPC.js +0 -671
  88. package/dist/chunk-32UDXUPC.js.map +0 -1
  89. package/dist/chunk-5DILEXGY.js +0 -85
  90. package/dist/chunk-5DILEXGY.js.map +0 -1
  91. package/dist/chunk-D3U63BZP.js +0 -240
  92. package/dist/chunk-D3U63BZP.js.map +0 -1
  93. package/dist/chunk-FXYPFGOZ.js +0 -129
  94. package/dist/chunk-FXYPFGOZ.js.map +0 -1
  95. package/dist/chunk-JTKON2SH.js.map +0 -1
  96. package/dist/chunk-NNGBXDMY.js.map +0 -1
  97. package/dist/chunk-SQLJNZ3K.js +0 -674
  98. package/dist/chunk-SQLJNZ3K.js.map +0 -1
  99. package/dist/chunk-W7TVRPBG.js +0 -108
  100. package/dist/chunk-W7TVRPBG.js.map +0 -1
  101. package/dist/client-B3RUab0s.d.ts +0 -225
  102. package/dist/client.d.ts +0 -4
  103. package/dist/client.js +0 -7
  104. package/dist/client.js.map +0 -1
  105. package/dist/errors.d.ts +0 -95
  106. package/dist/errors.js +0 -27
  107. package/dist/errors.js.map +0 -1
  108. package/dist/interpreter-client.d.ts +0 -4
  109. package/dist/interpreter-client.js +0 -9
  110. package/dist/interpreter-client.js.map +0 -1
  111. package/dist/interpreter-types.d.ts +0 -259
  112. package/dist/interpreter-types.js +0 -9
  113. package/dist/interpreter-types.js.map +0 -1
  114. package/dist/types.d.ts +0 -453
  115. package/dist/types.js +0 -45
  116. package/dist/types.js.map +0 -1
  117. package/src/client.ts +0 -1048
  118. package/src/errors.ts +0 -219
  119. package/src/interpreter-types.ts +0 -390
  120. package/src/types.ts +0 -571
package/src/types.ts DELETED
@@ -1,571 +0,0 @@
1
- // Core Types
2
-
3
- export interface BaseExecOptions {
4
- /**
5
- * Maximum execution time in milliseconds
6
- */
7
- timeout?: number;
8
-
9
- /**
10
- * Environment variables for the command
11
- */
12
- env?: Record<string, string>;
13
-
14
- /**
15
- * Working directory for command execution
16
- */
17
- cwd?: string;
18
-
19
- /**
20
- * Text encoding for output (default: 'utf8')
21
- */
22
- encoding?: string;
23
- }
24
-
25
- export interface ExecOptions extends BaseExecOptions {
26
- /**
27
- * Enable real-time output streaming via callbacks
28
- */
29
- stream?: boolean;
30
-
31
- /**
32
- * Callback for real-time output data
33
- */
34
- onOutput?: (stream: 'stdout' | 'stderr', data: string) => void;
35
-
36
- /**
37
- * Callback when command completes (only when stream: true)
38
- */
39
- onComplete?: (result: ExecResult) => void;
40
-
41
- /**
42
- * Callback for execution errors
43
- */
44
- onError?: (error: Error) => void;
45
-
46
- /**
47
- * AbortSignal for cancelling execution
48
- */
49
- signal?: AbortSignal;
50
- }
51
-
52
- export interface ExecResult {
53
- /**
54
- * Whether the command succeeded (exitCode === 0)
55
- */
56
- success: boolean;
57
-
58
- /**
59
- * Process exit code
60
- */
61
- exitCode: number;
62
-
63
- /**
64
- * Standard output content
65
- */
66
- stdout: string;
67
-
68
- /**
69
- * Standard error content
70
- */
71
- stderr: string;
72
-
73
- /**
74
- * Command that was executed
75
- */
76
- command: string;
77
-
78
-
79
- /**
80
- * Execution duration in milliseconds
81
- */
82
- duration: number;
83
-
84
- /**
85
- * ISO timestamp when command started
86
- */
87
- timestamp: string;
88
- }
89
-
90
- // Background Process Types
91
-
92
- export interface ProcessOptions extends BaseExecOptions {
93
- /**
94
- * Custom process ID for later reference
95
- * If not provided, a UUID will be generated
96
- */
97
- processId?: string;
98
-
99
- /**
100
- * Automatically cleanup process record after exit (default: true)
101
- */
102
- autoCleanup?: boolean;
103
-
104
- /**
105
- * Callback when process exits
106
- */
107
- onExit?: (code: number | null) => void;
108
-
109
- /**
110
- * Callback for real-time output (background processes)
111
- */
112
- onOutput?: (stream: 'stdout' | 'stderr', data: string) => void;
113
-
114
- /**
115
- * Callback when process starts successfully
116
- */
117
- onStart?: (process: Process) => void;
118
-
119
- /**
120
- * Callback for process errors
121
- */
122
- onError?: (error: Error) => void;
123
- }
124
-
125
- export type ProcessStatus =
126
- | 'starting' // Process is being initialized
127
- | 'running' // Process is actively running
128
- | 'completed' // Process exited successfully (code 0)
129
- | 'failed' // Process exited with non-zero code
130
- | 'killed' // Process was terminated by signal
131
- | 'error'; // Process failed to start or encountered error
132
-
133
- export interface Process {
134
- /**
135
- * Unique process identifier
136
- */
137
- readonly id: string;
138
-
139
- /**
140
- * System process ID (if available and running)
141
- */
142
- readonly pid?: number;
143
-
144
- /**
145
- * Command that was executed
146
- */
147
- readonly command: string;
148
-
149
-
150
- /**
151
- * Current process status
152
- */
153
- readonly status: ProcessStatus;
154
-
155
- /**
156
- * When the process was started
157
- */
158
- readonly startTime: Date;
159
-
160
- /**
161
- * When the process ended (if completed)
162
- */
163
- readonly endTime?: Date;
164
-
165
- /**
166
- * Process exit code (if completed)
167
- */
168
- readonly exitCode?: number;
169
-
170
- /**
171
- * Kill the process
172
- */
173
- kill(signal?: string): Promise<void>;
174
-
175
- /**
176
- * Get current process status (refreshed)
177
- */
178
- getStatus(): Promise<ProcessStatus>;
179
-
180
- /**
181
- * Get accumulated logs
182
- */
183
- getLogs(): Promise<{ stdout: string; stderr: string }>;
184
- }
185
-
186
- // Streaming Types
187
-
188
- export interface ExecEvent {
189
- type: 'start' | 'stdout' | 'stderr' | 'complete' | 'error';
190
- timestamp: string;
191
- data?: string;
192
- command?: string;
193
- exitCode?: number;
194
- result?: ExecResult;
195
- error?: string; // Changed to string for serialization
196
- }
197
-
198
- export interface LogEvent {
199
- type: 'stdout' | 'stderr' | 'exit' | 'error';
200
- timestamp: string;
201
- data: string;
202
- processId: string;
203
- exitCode?: number; // For 'exit' events
204
- }
205
-
206
- export interface StreamOptions extends BaseExecOptions {
207
- /**
208
- * Buffer size for streaming output
209
- */
210
- bufferSize?: number;
211
-
212
- /**
213
- * AbortSignal for cancelling stream
214
- */
215
- signal?: AbortSignal;
216
- }
217
-
218
- // File Streaming Types
219
-
220
- /**
221
- * SSE events for file streaming
222
- */
223
- export type FileStreamEvent =
224
- | {
225
- type: 'metadata';
226
- mimeType: string;
227
- size: number;
228
- isBinary: boolean;
229
- encoding: 'utf-8' | 'base64';
230
- }
231
- | {
232
- type: 'chunk';
233
- data: string; // base64 for binary, UTF-8 for text
234
- }
235
- | {
236
- type: 'complete';
237
- bytesRead: number;
238
- }
239
- | {
240
- type: 'error';
241
- error: string;
242
- };
243
-
244
- /**
245
- * File metadata from streaming
246
- */
247
- export interface FileMetadata {
248
- mimeType: string;
249
- size: number;
250
- isBinary: boolean;
251
- encoding: 'utf-8' | 'base64';
252
- }
253
-
254
- /**
255
- * File stream chunk - either string (text) or Uint8Array (binary, auto-decoded)
256
- */
257
- export type FileChunk = string | Uint8Array;
258
-
259
- /**
260
- * AsyncIterable of file chunks with metadata
261
- */
262
- export interface FileStream extends AsyncIterable<FileChunk> {
263
- metadata?: FileMetadata;
264
- }
265
-
266
- // Error Types
267
-
268
- export class SandboxError extends Error {
269
- constructor(message: string, public code?: string) {
270
- super(message);
271
- this.name = 'SandboxError';
272
- }
273
- }
274
-
275
- export class ProcessNotFoundError extends SandboxError {
276
- constructor(processId: string) {
277
- super(`Process not found: ${processId}`, 'PROCESS_NOT_FOUND');
278
- this.name = 'ProcessNotFoundError';
279
- }
280
- }
281
-
282
- export class ProcessAlreadyExistsError extends SandboxError {
283
- constructor(processId: string) {
284
- super(`Process already exists: ${processId}`, 'PROCESS_EXISTS');
285
- this.name = 'ProcessAlreadyExistsError';
286
- }
287
- }
288
-
289
- export class ExecutionTimeoutError extends SandboxError {
290
- constructor(timeout: number) {
291
- super(`Execution timed out after ${timeout}ms`, 'EXECUTION_TIMEOUT');
292
- this.name = 'ExecutionTimeoutError';
293
- }
294
- }
295
-
296
- // Internal Container Types
297
-
298
- export interface ProcessRecord {
299
- id: string;
300
- pid?: number;
301
- command: string;
302
- status: ProcessStatus;
303
- startTime: Date;
304
- endTime?: Date;
305
- exitCode?: number;
306
-
307
- // Internal fields
308
- stdout: string; // Accumulated output (ephemeral)
309
- stderr: string; // Accumulated output (ephemeral)
310
-
311
- // Streaming
312
- outputListeners: Set<(stream: 'stdout' | 'stderr', data: string) => void>;
313
- statusListeners: Set<(status: ProcessStatus) => void>;
314
- }
315
-
316
- // Container Request/Response Types
317
-
318
- export interface StartProcessRequest {
319
- command: string;
320
- options?: {
321
- processId?: string;
322
- timeout?: number;
323
- env?: Record<string, string>;
324
- cwd?: string;
325
- encoding?: string;
326
- autoCleanup?: boolean;
327
- };
328
- }
329
-
330
- export interface StartProcessResponse {
331
- process: {
332
- id: string;
333
- pid?: number;
334
- command: string;
335
- status: ProcessStatus;
336
- startTime: string;
337
- endTime?: string | null;
338
- exitCode?: number | null;
339
- sessionId: string;
340
- };
341
- }
342
-
343
- export interface ListProcessesResponse {
344
- processes: Array<{
345
- id: string;
346
- pid?: number;
347
- command: string;
348
- status: ProcessStatus;
349
- startTime: string;
350
- endTime?: string;
351
- exitCode?: number;
352
- }>;
353
- }
354
-
355
- export interface GetProcessResponse {
356
- process: {
357
- id: string;
358
- pid?: number;
359
- command: string;
360
- status: ProcessStatus;
361
- startTime: string;
362
- endTime?: string;
363
- exitCode?: number;
364
- } | null;
365
- }
366
-
367
- export interface GetProcessLogsResponse {
368
- stdout: string;
369
- stderr: string;
370
- processId: string;
371
- }
372
-
373
- // Import code interpreter types
374
- import type {
375
- CodeContext,
376
- CreateContextOptions,
377
- ExecutionResult,
378
- RunCodeOptions
379
- } from './interpreter-types';
380
-
381
- // Main Sandbox Interface
382
-
383
- export interface ISandbox {
384
- // Enhanced execution API
385
- exec(command: string, options?: ExecOptions): Promise<ExecResult>;
386
-
387
- // Background process management
388
- startProcess(command: string, options?: ProcessOptions): Promise<Process>;
389
- listProcesses(): Promise<Process[]>;
390
- getProcess(id: string): Promise<Process | null>;
391
- killProcess(id: string, signal?: string): Promise<void>;
392
- killAllProcesses(): Promise<number>;
393
-
394
- // Advanced streaming - returns ReadableStream that can be converted to AsyncIterable
395
- execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;
396
- streamProcessLogs(processId: string, options?: { signal?: AbortSignal }): Promise<ReadableStream<Uint8Array>>;
397
-
398
- // Utility methods
399
- cleanupCompletedProcesses(): Promise<number>;
400
- getProcessLogs(id: string): Promise<{ stdout: string; stderr: string }>;
401
-
402
- // File operations
403
- gitCheckout(repoUrl: string, options: { branch?: string; targetDir?: string }): Promise<GitCheckoutResponse>;
404
- mkdir(path: string, options?: { recursive?: boolean }): Promise<MkdirResponse>;
405
- writeFile(path: string, content: string, options?: { encoding?: string }): Promise<WriteFileResponse>;
406
- deleteFile(path: string): Promise<DeleteFileResponse>;
407
- renameFile(oldPath: string, newPath: string): Promise<RenameFileResponse>;
408
- moveFile(sourcePath: string, destinationPath: string): Promise<MoveFileResponse>;
409
- readFile(path: string, options?: { encoding?: string }): Promise<ReadFileResponse>;
410
- readFileStream(path: string): Promise<ReadableStream<Uint8Array>>;
411
- listFiles(path: string, options?: { recursive?: boolean; includeHidden?: boolean }): Promise<ListFilesResponse>;
412
-
413
- // Port management
414
- exposePort(port: number, options: { name?: string; hostname: string }): Promise<{ url: string; port: number; name?: string }>;
415
- unexposePort(port: number): Promise<void>;
416
- getExposedPorts(hostname: string): Promise<Array<{ url: string; port: number; name?: string; exposedAt: string }>>;
417
-
418
- // Environment management
419
- setEnvVars(envVars: Record<string, string>): Promise<void>;
420
- setSandboxName(name: string): Promise<void>;
421
-
422
- // Code Interpreter API
423
- createCodeContext(options?: CreateContextOptions): Promise<CodeContext>;
424
- runCode(code: string, options?: RunCodeOptions): Promise<ExecutionResult>;
425
- runCodeStream(code: string, options?: RunCodeOptions): Promise<ReadableStream>;
426
- listCodeContexts(): Promise<CodeContext[]>;
427
- deleteCodeContext(contextId: string): Promise<void>;
428
- }
429
-
430
- // Execution session returned by createSession()
431
- // Sessions are full-featured sandbox objects with scoped execution context
432
- // Inherits all ISandbox methods except createSession (sessions can't create sub-sessions),
433
- // and setSandboxName (sessions inherit sandbox name).
434
- export interface ExecutionSession extends Omit<ISandbox, 'createSession' | 'setSandboxName'> {
435
- /**
436
- * Session ID
437
- */
438
- id: string;
439
- }
440
-
441
- // API Response Types
442
-
443
- export interface ExecuteResponse {
444
- success: boolean;
445
- stdout: string;
446
- stderr: string;
447
- exitCode: number;
448
- command: string;
449
- timestamp: string;
450
- }
451
-
452
- export interface GitCheckoutResponse {
453
- success: boolean;
454
- stdout: string;
455
- stderr: string;
456
- exitCode: number;
457
- repoUrl: string;
458
- branch: string;
459
- targetDir: string;
460
- timestamp: string;
461
- }
462
-
463
- export interface MkdirResponse {
464
- success: boolean;
465
- stdout: string;
466
- stderr: string;
467
- exitCode: number;
468
- path: string;
469
- recursive: boolean;
470
- timestamp: string;
471
- }
472
-
473
- export interface WriteFileResponse {
474
- success: boolean;
475
- exitCode: number;
476
- path: string;
477
- timestamp: string;
478
- }
479
-
480
- export interface ReadFileResponse {
481
- success: boolean;
482
- exitCode: number;
483
- path: string;
484
- content: string;
485
- timestamp: string;
486
-
487
- /**
488
- * Encoding used for content (utf-8 for text, base64 for binary)
489
- */
490
- encoding?: 'utf-8' | 'base64';
491
-
492
- /**
493
- * Whether the file is detected as binary
494
- */
495
- isBinary?: boolean;
496
-
497
- /**
498
- * MIME type of the file (e.g., 'image/png', 'text/plain')
499
- */
500
- mimeType?: string;
501
-
502
- /**
503
- * File size in bytes
504
- */
505
- size?: number;
506
- }
507
-
508
- export interface DeleteFileResponse {
509
- success: boolean;
510
- exitCode: number;
511
- path: string;
512
- timestamp: string;
513
- }
514
-
515
- export interface RenameFileResponse {
516
- success: boolean;
517
- exitCode: number;
518
- oldPath: string;
519
- newPath: string;
520
- timestamp: string;
521
- }
522
-
523
- export interface MoveFileResponse {
524
- success: boolean;
525
- exitCode: number;
526
- sourcePath: string;
527
- destinationPath: string;
528
- timestamp: string;
529
- }
530
-
531
- export interface ListFilesResponse {
532
- success: boolean;
533
- exitCode: number;
534
- path: string;
535
- files: Array<{
536
- name: string;
537
- absolutePath: string;
538
- relativePath: string;
539
- type: 'file' | 'directory' | 'symlink' | 'other';
540
- size: number;
541
- modifiedAt: string;
542
- mode: string;
543
- permissions: {
544
- readable: boolean;
545
- writable: boolean;
546
- executable: boolean;
547
- };
548
- }>;
549
- timestamp: string;
550
- }
551
-
552
- // Type Guards
553
-
554
- export function isExecResult(value: any): value is ExecResult {
555
- return value &&
556
- typeof value.success === 'boolean' &&
557
- typeof value.exitCode === 'number' &&
558
- typeof value.stdout === 'string' &&
559
- typeof value.stderr === 'string';
560
- }
561
-
562
- export function isProcess(value: any): value is Process {
563
- return value &&
564
- typeof value.id === 'string' &&
565
- typeof value.command === 'string' &&
566
- typeof value.status === 'string';
567
- }
568
-
569
- export function isProcessStatus(value: string): value is ProcessStatus {
570
- return ['starting', 'running', 'completed', 'failed', 'killed', 'error'].includes(value);
571
- }