@cloudflare/sandbox 0.0.8 → 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.
Files changed (56) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/Dockerfile +73 -9
  3. package/container_src/handler/exec.ts +337 -0
  4. package/container_src/handler/file.ts +844 -0
  5. package/container_src/handler/git.ts +182 -0
  6. package/container_src/handler/ports.ts +314 -0
  7. package/container_src/handler/process.ts +640 -0
  8. package/container_src/index.ts +102 -2647
  9. package/container_src/types.ts +103 -0
  10. package/dist/chunk-6THNBO4S.js +46 -0
  11. package/dist/chunk-6THNBO4S.js.map +1 -0
  12. package/dist/chunk-6UAWTJ5S.js +85 -0
  13. package/dist/chunk-6UAWTJ5S.js.map +1 -0
  14. package/dist/chunk-G4XT4SP7.js +638 -0
  15. package/dist/chunk-G4XT4SP7.js.map +1 -0
  16. package/dist/chunk-ISFOIYQC.js +585 -0
  17. package/dist/chunk-ISFOIYQC.js.map +1 -0
  18. package/dist/chunk-NNGBXDMY.js +89 -0
  19. package/dist/chunk-NNGBXDMY.js.map +1 -0
  20. package/dist/client-Da-mLX4p.d.ts +210 -0
  21. package/dist/client.d.ts +2 -1
  22. package/dist/client.js +3 -37
  23. package/dist/index.d.ts +5 -200
  24. package/dist/index.js +17 -106
  25. package/dist/index.js.map +1 -1
  26. package/dist/request-handler.d.ts +16 -0
  27. package/dist/request-handler.js +12 -0
  28. package/dist/request-handler.js.map +1 -0
  29. package/dist/sandbox.d.ts +3 -0
  30. package/dist/sandbox.js +12 -0
  31. package/dist/sandbox.js.map +1 -0
  32. package/dist/security.d.ts +30 -0
  33. package/dist/security.js +13 -0
  34. package/dist/security.js.map +1 -0
  35. package/dist/sse-parser.d.ts +28 -0
  36. package/dist/sse-parser.js +11 -0
  37. package/dist/sse-parser.js.map +1 -0
  38. package/dist/types.d.ts +284 -0
  39. package/dist/types.js +19 -0
  40. package/dist/types.js.map +1 -0
  41. package/package.json +2 -7
  42. package/src/client.ts +320 -1242
  43. package/src/index.ts +20 -136
  44. package/src/request-handler.ts +144 -0
  45. package/src/sandbox.ts +645 -0
  46. package/src/security.ts +113 -0
  47. package/src/sse-parser.ts +147 -0
  48. package/src/types.ts +386 -0
  49. package/README.md +0 -65
  50. package/dist/chunk-7WZJ3TRE.js +0 -1364
  51. package/dist/chunk-7WZJ3TRE.js.map +0 -1
  52. package/tests/client.example.ts +0 -308
  53. package/tests/connection-test.ts +0 -81
  54. package/tests/simple-test.ts +0 -81
  55. package/tests/test1.ts +0 -281
  56. package/tests/test2.ts +0 -929
package/dist/index.js CHANGED
@@ -1,111 +1,22 @@
1
1
  import {
2
- HttpClient
3
- } from "./chunk-7WZJ3TRE.js";
4
-
5
- // src/index.ts
6
- import { Container, getContainer } from "@cloudflare/containers";
7
- function getSandbox(ns, id) {
8
- return getContainer(ns, id);
9
- }
10
- var Sandbox = class extends Container {
11
- defaultPort = 3e3;
12
- // The default port for the container to listen on
13
- sleepAfter = "3m";
14
- // Sleep the sandbox if no requests are made in this timeframe
15
- client;
16
- constructor(ctx, env) {
17
- super(ctx, env);
18
- this.client = new HttpClient({
19
- onCommandComplete: (success, exitCode, stdout, stderr, command, args) => {
20
- console.log(
21
- `[Container] Command completed: ${command}, Success: ${success}, Exit code: ${exitCode}`
22
- );
23
- },
24
- onCommandStart: (command, args) => {
25
- console.log(
26
- `[Container] Command started: ${command} ${args.join(" ")}`
27
- );
28
- },
29
- onError: (error, command, args) => {
30
- console.error(`[Container] Command error: ${error}`);
31
- },
32
- onOutput: (stream, data, command) => {
33
- console.log(`[Container] [${stream}] ${data}`);
34
- },
35
- port: this.defaultPort,
36
- stub: this
37
- });
38
- }
39
- envVars = {
40
- MESSAGE: "I was passed in via the Sandbox class!"
41
- };
42
- onStart() {
43
- console.log("Sandbox successfully started");
44
- }
45
- onStop() {
46
- console.log("Sandbox successfully shut down");
47
- if (this.client) {
48
- this.client.clearSession();
49
- }
50
- }
51
- onError(error) {
52
- console.log("Sandbox error:", error);
53
- }
54
- async exec(command, args, options) {
55
- if (options?.stream) {
56
- return this.client.executeStream(command, args);
57
- }
58
- return this.client.execute(command, args);
59
- }
60
- async gitCheckout(repoUrl, options) {
61
- if (options?.stream) {
62
- return this.client.gitCheckoutStream(
63
- repoUrl,
64
- options.branch,
65
- options.targetDir
66
- );
67
- }
68
- return this.client.gitCheckout(repoUrl, options.branch, options.targetDir);
69
- }
70
- async mkdir(path, options = {}) {
71
- if (options?.stream) {
72
- return this.client.mkdirStream(path, options.recursive);
73
- }
74
- return this.client.mkdir(path, options.recursive);
75
- }
76
- async writeFile(path, content, options = {}) {
77
- if (options?.stream) {
78
- return this.client.writeFileStream(path, content, options.encoding);
79
- }
80
- return this.client.writeFile(path, content, options.encoding);
81
- }
82
- async deleteFile(path, options = {}) {
83
- if (options?.stream) {
84
- return this.client.deleteFileStream(path);
85
- }
86
- return this.client.deleteFile(path);
87
- }
88
- async renameFile(oldPath, newPath, options = {}) {
89
- if (options?.stream) {
90
- return this.client.renameFileStream(oldPath, newPath);
91
- }
92
- return this.client.renameFile(oldPath, newPath);
93
- }
94
- async moveFile(sourcePath, destinationPath, options = {}) {
95
- if (options?.stream) {
96
- return this.client.moveFileStream(sourcePath, destinationPath);
97
- }
98
- return this.client.moveFile(sourcePath, destinationPath);
99
- }
100
- async readFile(path, options = {}) {
101
- if (options?.stream) {
102
- return this.client.readFileStream(path, options.encoding);
103
- }
104
- return this.client.readFile(path, options.encoding);
105
- }
106
- };
2
+ Sandbox,
3
+ getSandbox,
4
+ proxyToSandbox
5
+ } from "./chunk-ISFOIYQC.js";
6
+ import "./chunk-G4XT4SP7.js";
7
+ import "./chunk-6UAWTJ5S.js";
8
+ import {
9
+ asyncIterableToSSEStream,
10
+ parseSSEStream,
11
+ responseToAsyncIterable
12
+ } from "./chunk-NNGBXDMY.js";
13
+ import "./chunk-6THNBO4S.js";
107
14
  export {
108
15
  Sandbox,
109
- getSandbox
16
+ asyncIterableToSSEStream,
17
+ getSandbox,
18
+ parseSSEStream,
19
+ proxyToSandbox,
20
+ responseToAsyncIterable
110
21
  };
111
22
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Container, getContainer } from \"@cloudflare/containers\";\nimport { HttpClient } from \"./client\";\n\nexport function getSandbox(ns: DurableObjectNamespace<Sandbox>, id: string) {\n return getContainer(ns, id);\n}\n\nexport class Sandbox<Env = unknown> extends Container<Env> {\n defaultPort = 3000; // The default port for the container to listen on\n sleepAfter = \"3m\"; // Sleep the sandbox if no requests are made in this timeframe\n client: HttpClient;\n\n constructor(ctx: DurableObjectState, env: Env) {\n super(ctx, env);\n this.client = new HttpClient({\n onCommandComplete: (success, exitCode, stdout, stderr, command, args) => {\n console.log(\n `[Container] Command completed: ${command}, Success: ${success}, Exit code: ${exitCode}`\n );\n },\n onCommandStart: (command, args) => {\n console.log(\n `[Container] Command started: ${command} ${args.join(\" \")}`\n );\n },\n onError: (error, command, args) => {\n console.error(`[Container] Command error: ${error}`);\n },\n onOutput: (stream, data, command) => {\n console.log(`[Container] [${stream}] ${data}`);\n },\n port: this.defaultPort,\n stub: this,\n });\n }\n\n envVars = {\n MESSAGE: \"I was passed in via the Sandbox class!\",\n };\n\n override onStart() {\n console.log(\"Sandbox successfully started\");\n }\n\n override onStop() {\n console.log(\"Sandbox successfully shut down\");\n if (this.client) {\n this.client.clearSession();\n }\n }\n\n override onError(error: unknown) {\n console.log(\"Sandbox error:\", error);\n }\n\n async exec(command: string, args: string[], options?: { stream?: boolean }) {\n if (options?.stream) {\n return this.client.executeStream(command, args);\n }\n return this.client.execute(command, args);\n }\n\n async gitCheckout(\n repoUrl: string,\n options: { branch?: string; targetDir?: string; stream?: boolean }\n ) {\n if (options?.stream) {\n return this.client.gitCheckoutStream(\n repoUrl,\n options.branch,\n options.targetDir\n );\n }\n return this.client.gitCheckout(repoUrl, options.branch, options.targetDir);\n }\n\n async mkdir(\n path: string,\n options: { recursive?: boolean; stream?: boolean } = {}\n ) {\n if (options?.stream) {\n return this.client.mkdirStream(path, options.recursive);\n }\n return this.client.mkdir(path, options.recursive);\n }\n\n async writeFile(\n path: string,\n content: string,\n options: { encoding?: string; stream?: boolean } = {}\n ) {\n if (options?.stream) {\n return this.client.writeFileStream(path, content, options.encoding);\n }\n return this.client.writeFile(path, content, options.encoding);\n }\n\n async deleteFile(path: string, options: { stream?: boolean } = {}) {\n if (options?.stream) {\n return this.client.deleteFileStream(path);\n }\n return this.client.deleteFile(path);\n }\n\n async renameFile(\n oldPath: string,\n newPath: string,\n options: { stream?: boolean } = {}\n ) {\n if (options?.stream) {\n return this.client.renameFileStream(oldPath, newPath);\n }\n return this.client.renameFile(oldPath, newPath);\n }\n\n async moveFile(\n sourcePath: string,\n destinationPath: string,\n options: { stream?: boolean } = {}\n ) {\n if (options?.stream) {\n return this.client.moveFileStream(sourcePath, destinationPath);\n }\n return this.client.moveFile(sourcePath, destinationPath);\n }\n\n async readFile(\n path: string,\n options: { encoding?: string; stream?: boolean } = {}\n ) {\n if (options?.stream) {\n return this.client.readFileStream(path, options.encoding);\n }\n return this.client.readFile(path, options.encoding);\n }\n}\n"],"mappings":";;;;;AAAA,SAAS,WAAW,oBAAoB;AAGjC,SAAS,WAAW,IAAqC,IAAY;AAC1E,SAAO,aAAa,IAAI,EAAE;AAC5B;AAEO,IAAM,UAAN,cAAqC,UAAe;AAAA,EACzD,cAAc;AAAA;AAAA,EACd,aAAa;AAAA;AAAA,EACb;AAAA,EAEA,YAAY,KAAyB,KAAU;AAC7C,UAAM,KAAK,GAAG;AACd,SAAK,SAAS,IAAI,WAAW;AAAA,MAC3B,mBAAmB,CAAC,SAAS,UAAU,QAAQ,QAAQ,SAAS,SAAS;AACvE,gBAAQ;AAAA,UACN,kCAAkC,OAAO,cAAc,OAAO,gBAAgB,QAAQ;AAAA,QACxF;AAAA,MACF;AAAA,MACA,gBAAgB,CAAC,SAAS,SAAS;AACjC,gBAAQ;AAAA,UACN,gCAAgC,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,QAC3D;AAAA,MACF;AAAA,MACA,SAAS,CAAC,OAAO,SAAS,SAAS;AACjC,gBAAQ,MAAM,8BAA8B,KAAK,EAAE;AAAA,MACrD;AAAA,MACA,UAAU,CAAC,QAAQ,MAAM,YAAY;AACnC,gBAAQ,IAAI,gBAAgB,MAAM,KAAK,IAAI,EAAE;AAAA,MAC/C;AAAA,MACA,MAAM,KAAK;AAAA,MACX,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EAEA,UAAU;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EAES,UAAU;AACjB,YAAQ,IAAI,8BAA8B;AAAA,EAC5C;AAAA,EAES,SAAS;AAChB,YAAQ,IAAI,gCAAgC;AAC5C,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,aAAa;AAAA,IAC3B;AAAA,EACF;AAAA,EAES,QAAQ,OAAgB;AAC/B,YAAQ,IAAI,kBAAkB,KAAK;AAAA,EACrC;AAAA,EAEA,MAAM,KAAK,SAAiB,MAAgB,SAAgC;AAC1E,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,OAAO,cAAc,SAAS,IAAI;AAAA,IAChD;AACA,WAAO,KAAK,OAAO,QAAQ,SAAS,IAAI;AAAA,EAC1C;AAAA,EAEA,MAAM,YACJ,SACA,SACA;AACA,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,OAAO;AAAA,QACjB;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACF;AACA,WAAO,KAAK,OAAO,YAAY,SAAS,QAAQ,QAAQ,QAAQ,SAAS;AAAA,EAC3E;AAAA,EAEA,MAAM,MACJ,MACA,UAAqD,CAAC,GACtD;AACA,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,OAAO,YAAY,MAAM,QAAQ,SAAS;AAAA,IACxD;AACA,WAAO,KAAK,OAAO,MAAM,MAAM,QAAQ,SAAS;AAAA,EAClD;AAAA,EAEA,MAAM,UACJ,MACA,SACA,UAAmD,CAAC,GACpD;AACA,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,OAAO,gBAAgB,MAAM,SAAS,QAAQ,QAAQ;AAAA,IACpE;AACA,WAAO,KAAK,OAAO,UAAU,MAAM,SAAS,QAAQ,QAAQ;AAAA,EAC9D;AAAA,EAEA,MAAM,WAAW,MAAc,UAAgC,CAAC,GAAG;AACjE,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,OAAO,iBAAiB,IAAI;AAAA,IAC1C;AACA,WAAO,KAAK,OAAO,WAAW,IAAI;AAAA,EACpC;AAAA,EAEA,MAAM,WACJ,SACA,SACA,UAAgC,CAAC,GACjC;AACA,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,OAAO,iBAAiB,SAAS,OAAO;AAAA,IACtD;AACA,WAAO,KAAK,OAAO,WAAW,SAAS,OAAO;AAAA,EAChD;AAAA,EAEA,MAAM,SACJ,YACA,iBACA,UAAgC,CAAC,GACjC;AACA,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,OAAO,eAAe,YAAY,eAAe;AAAA,IAC/D;AACA,WAAO,KAAK,OAAO,SAAS,YAAY,eAAe;AAAA,EACzD;AAAA,EAEA,MAAM,SACJ,MACA,UAAmD,CAAC,GACpD;AACA,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,OAAO,eAAe,MAAM,QAAQ,QAAQ;AAAA,IAC1D;AACA,WAAO,KAAK,OAAO,SAAS,MAAM,QAAQ,QAAQ;AAAA,EACpD;AACF;","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,16 @@
1
+ import { S as Sandbox } from './client-Da-mLX4p.js';
2
+ import '@cloudflare/containers';
3
+ import './types.js';
4
+
5
+ interface SandboxEnv {
6
+ Sandbox: DurableObjectNamespace<Sandbox>;
7
+ }
8
+ interface RouteInfo {
9
+ port: number;
10
+ sandboxId: string;
11
+ path: string;
12
+ }
13
+ declare function proxyToSandbox<E extends SandboxEnv>(request: Request, env: E): Promise<Response | null>;
14
+ declare function isLocalhostPattern(hostname: string): boolean;
15
+
16
+ export { type RouteInfo, type SandboxEnv, isLocalhostPattern, proxyToSandbox };
@@ -0,0 +1,12 @@
1
+ import {
2
+ isLocalhostPattern,
3
+ proxyToSandbox
4
+ } from "./chunk-ISFOIYQC.js";
5
+ import "./chunk-G4XT4SP7.js";
6
+ import "./chunk-6UAWTJ5S.js";
7
+ import "./chunk-6THNBO4S.js";
8
+ export {
9
+ isLocalhostPattern,
10
+ proxyToSandbox
11
+ };
12
+ //# sourceMappingURL=request-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,3 @@
1
+ export { S as Sandbox, g as getSandbox } from './client-Da-mLX4p.js';
2
+ import '@cloudflare/containers';
3
+ import './types.js';
@@ -0,0 +1,12 @@
1
+ import {
2
+ Sandbox,
3
+ getSandbox
4
+ } from "./chunk-ISFOIYQC.js";
5
+ import "./chunk-G4XT4SP7.js";
6
+ import "./chunk-6UAWTJ5S.js";
7
+ import "./chunk-6THNBO4S.js";
8
+ export {
9
+ Sandbox,
10
+ getSandbox
11
+ };
12
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Security utilities for URL construction and input validation
3
+ *
4
+ * This module contains critical security functions to prevent:
5
+ * - URL injection attacks
6
+ * - SSRF (Server-Side Request Forgery) attacks
7
+ * - DNS rebinding attacks
8
+ * - Host header injection
9
+ * - Open redirect vulnerabilities
10
+ */
11
+ declare class SecurityError extends Error {
12
+ readonly code?: string | undefined;
13
+ constructor(message: string, code?: string | undefined);
14
+ }
15
+ /**
16
+ * Validates port numbers for sandbox services
17
+ * Only allows non-system ports to prevent conflicts and security issues
18
+ */
19
+ declare function validatePort(port: number): boolean;
20
+ /**
21
+ * Sanitizes and validates sandbox IDs for DNS compliance and security
22
+ * Only enforces critical requirements - allows maximum developer flexibility
23
+ */
24
+ declare function sanitizeSandboxId(id: string): string;
25
+ /**
26
+ * Logs security events for monitoring
27
+ */
28
+ declare function logSecurityEvent(event: string, details: Record<string, any>, severity?: 'low' | 'medium' | 'high' | 'critical'): void;
29
+
30
+ export { SecurityError, logSecurityEvent, sanitizeSandboxId, validatePort };
@@ -0,0 +1,13 @@
1
+ import {
2
+ SecurityError,
3
+ logSecurityEvent,
4
+ sanitizeSandboxId,
5
+ validatePort
6
+ } from "./chunk-6UAWTJ5S.js";
7
+ export {
8
+ SecurityError,
9
+ logSecurityEvent,
10
+ sanitizeSandboxId,
11
+ validatePort
12
+ };
13
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Server-Sent Events (SSE) parser for streaming responses
3
+ * Converts ReadableStream<Uint8Array> to typed AsyncIterable<T>
4
+ */
5
+ /**
6
+ * Parse a ReadableStream of SSE events into typed AsyncIterable
7
+ * @param stream - The ReadableStream from fetch response
8
+ * @param signal - Optional AbortSignal for cancellation
9
+ */
10
+ declare function parseSSEStream<T>(stream: ReadableStream<Uint8Array>, signal?: AbortSignal): AsyncIterable<T>;
11
+ /**
12
+ * Helper to convert a Response with SSE stream directly to AsyncIterable
13
+ * @param response - Response object with SSE stream
14
+ * @param signal - Optional AbortSignal for cancellation
15
+ */
16
+ declare function responseToAsyncIterable<T>(response: Response, signal?: AbortSignal): AsyncIterable<T>;
17
+ /**
18
+ * Create an SSE-formatted ReadableStream from an AsyncIterable
19
+ * (Useful for Worker endpoints that need to forward AsyncIterable as SSE)
20
+ * @param events - AsyncIterable of events
21
+ * @param options - Stream options
22
+ */
23
+ declare function asyncIterableToSSEStream<T>(events: AsyncIterable<T>, options?: {
24
+ signal?: AbortSignal;
25
+ serialize?: (event: T) => string;
26
+ }): ReadableStream<Uint8Array>;
27
+
28
+ export { asyncIterableToSSEStream, parseSSEStream, responseToAsyncIterable };
@@ -0,0 +1,11 @@
1
+ import {
2
+ asyncIterableToSSEStream,
3
+ parseSSEStream,
4
+ responseToAsyncIterable
5
+ } from "./chunk-NNGBXDMY.js";
6
+ export {
7
+ asyncIterableToSSEStream,
8
+ parseSSEStream,
9
+ responseToAsyncIterable
10
+ };
11
+ //# sourceMappingURL=sse-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,284 @@
1
+ interface BaseExecOptions {
2
+ /**
3
+ * Session ID for grouping related commands
4
+ */
5
+ sessionId?: string;
6
+ /**
7
+ * Maximum execution time in milliseconds
8
+ */
9
+ timeout?: number;
10
+ /**
11
+ * Environment variables for the command
12
+ */
13
+ env?: Record<string, string>;
14
+ /**
15
+ * Working directory for command execution
16
+ */
17
+ cwd?: string;
18
+ /**
19
+ * Text encoding for output (default: 'utf8')
20
+ */
21
+ encoding?: string;
22
+ }
23
+ interface ExecOptions extends BaseExecOptions {
24
+ /**
25
+ * Enable real-time output streaming via callbacks
26
+ */
27
+ stream?: boolean;
28
+ /**
29
+ * Callback for real-time output data
30
+ */
31
+ onOutput?: (stream: 'stdout' | 'stderr', data: string) => void;
32
+ /**
33
+ * Callback when command completes (only when stream: true)
34
+ */
35
+ onComplete?: (result: ExecResult) => void;
36
+ /**
37
+ * Callback for execution errors
38
+ */
39
+ onError?: (error: Error) => void;
40
+ /**
41
+ * AbortSignal for cancelling execution
42
+ */
43
+ signal?: AbortSignal;
44
+ }
45
+ interface ExecResult {
46
+ /**
47
+ * Whether the command succeeded (exitCode === 0)
48
+ */
49
+ success: boolean;
50
+ /**
51
+ * Process exit code
52
+ */
53
+ exitCode: number;
54
+ /**
55
+ * Standard output content
56
+ */
57
+ stdout: string;
58
+ /**
59
+ * Standard error content
60
+ */
61
+ stderr: string;
62
+ /**
63
+ * Command that was executed
64
+ */
65
+ command: string;
66
+ /**
67
+ * Execution duration in milliseconds
68
+ */
69
+ duration: number;
70
+ /**
71
+ * ISO timestamp when command started
72
+ */
73
+ timestamp: string;
74
+ /**
75
+ * Session ID if provided
76
+ */
77
+ sessionId?: string;
78
+ }
79
+ interface ProcessOptions extends BaseExecOptions {
80
+ /**
81
+ * Custom process ID for later reference
82
+ * If not provided, a UUID will be generated
83
+ */
84
+ processId?: string;
85
+ /**
86
+ * Automatically cleanup process record after exit (default: true)
87
+ */
88
+ autoCleanup?: boolean;
89
+ /**
90
+ * Callback when process exits
91
+ */
92
+ onExit?: (code: number | null) => void;
93
+ /**
94
+ * Callback for real-time output (background processes)
95
+ */
96
+ onOutput?: (stream: 'stdout' | 'stderr', data: string) => void;
97
+ /**
98
+ * Callback when process starts successfully
99
+ */
100
+ onStart?: (process: Process) => void;
101
+ /**
102
+ * Callback for process errors
103
+ */
104
+ onError?: (error: Error) => void;
105
+ }
106
+ type ProcessStatus = 'starting' | 'running' | 'completed' | 'failed' | 'killed' | 'error';
107
+ interface Process {
108
+ /**
109
+ * Unique process identifier
110
+ */
111
+ readonly id: string;
112
+ /**
113
+ * System process ID (if available and running)
114
+ */
115
+ readonly pid?: number;
116
+ /**
117
+ * Command that was executed
118
+ */
119
+ readonly command: string;
120
+ /**
121
+ * Current process status
122
+ */
123
+ readonly status: ProcessStatus;
124
+ /**
125
+ * When the process was started
126
+ */
127
+ readonly startTime: Date;
128
+ /**
129
+ * When the process ended (if completed)
130
+ */
131
+ readonly endTime?: Date;
132
+ /**
133
+ * Process exit code (if completed)
134
+ */
135
+ readonly exitCode?: number;
136
+ /**
137
+ * Session ID if provided
138
+ */
139
+ readonly sessionId?: string;
140
+ /**
141
+ * Kill the process
142
+ */
143
+ kill(signal?: string): Promise<void>;
144
+ /**
145
+ * Get current process status (refreshed)
146
+ */
147
+ getStatus(): Promise<ProcessStatus>;
148
+ /**
149
+ * Get accumulated logs
150
+ */
151
+ getLogs(): Promise<{
152
+ stdout: string;
153
+ stderr: string;
154
+ }>;
155
+ }
156
+ interface ExecEvent {
157
+ type: 'start' | 'stdout' | 'stderr' | 'complete' | 'error';
158
+ timestamp: string;
159
+ data?: string;
160
+ command?: string;
161
+ exitCode?: number;
162
+ result?: ExecResult;
163
+ error?: string;
164
+ sessionId?: string;
165
+ }
166
+ interface LogEvent {
167
+ type: 'stdout' | 'stderr' | 'exit' | 'error';
168
+ timestamp: string;
169
+ data: string;
170
+ processId: string;
171
+ sessionId?: string;
172
+ exitCode?: number;
173
+ }
174
+ interface StreamOptions extends BaseExecOptions {
175
+ /**
176
+ * Buffer size for streaming output
177
+ */
178
+ bufferSize?: number;
179
+ /**
180
+ * AbortSignal for cancelling stream
181
+ */
182
+ signal?: AbortSignal;
183
+ }
184
+ declare class SandboxError extends Error {
185
+ code?: string | undefined;
186
+ constructor(message: string, code?: string | undefined);
187
+ }
188
+ declare class ProcessNotFoundError extends SandboxError {
189
+ constructor(processId: string);
190
+ }
191
+ declare class ProcessAlreadyExistsError extends SandboxError {
192
+ constructor(processId: string);
193
+ }
194
+ declare class ExecutionTimeoutError extends SandboxError {
195
+ constructor(timeout: number);
196
+ }
197
+ interface ProcessRecord {
198
+ id: string;
199
+ pid?: number;
200
+ command: string;
201
+ status: ProcessStatus;
202
+ startTime: Date;
203
+ endTime?: Date;
204
+ exitCode?: number;
205
+ sessionId?: string;
206
+ childProcess?: any;
207
+ stdout: string;
208
+ stderr: string;
209
+ outputListeners: Set<(stream: 'stdout' | 'stderr', data: string) => void>;
210
+ statusListeners: Set<(status: ProcessStatus) => void>;
211
+ }
212
+ interface StartProcessRequest {
213
+ command: string;
214
+ options?: {
215
+ processId?: string;
216
+ sessionId?: string;
217
+ timeout?: number;
218
+ env?: Record<string, string>;
219
+ cwd?: string;
220
+ encoding?: string;
221
+ autoCleanup?: boolean;
222
+ };
223
+ }
224
+ interface StartProcessResponse {
225
+ process: {
226
+ id: string;
227
+ pid?: number;
228
+ command: string;
229
+ status: ProcessStatus;
230
+ startTime: string;
231
+ sessionId?: string;
232
+ };
233
+ }
234
+ interface ListProcessesResponse {
235
+ processes: Array<{
236
+ id: string;
237
+ pid?: number;
238
+ command: string;
239
+ status: ProcessStatus;
240
+ startTime: string;
241
+ endTime?: string;
242
+ exitCode?: number;
243
+ sessionId?: string;
244
+ }>;
245
+ }
246
+ interface GetProcessResponse {
247
+ process: {
248
+ id: string;
249
+ pid?: number;
250
+ command: string;
251
+ status: ProcessStatus;
252
+ startTime: string;
253
+ endTime?: string;
254
+ exitCode?: number;
255
+ sessionId?: string;
256
+ } | null;
257
+ }
258
+ interface GetProcessLogsResponse {
259
+ stdout: string;
260
+ stderr: string;
261
+ processId: string;
262
+ }
263
+ interface ISandbox {
264
+ exec(command: string, options?: ExecOptions): Promise<ExecResult>;
265
+ startProcess(command: string, options?: ProcessOptions): Promise<Process>;
266
+ listProcesses(): Promise<Process[]>;
267
+ getProcess(id: string): Promise<Process | null>;
268
+ killProcess(id: string, signal?: string): Promise<void>;
269
+ killAllProcesses(): Promise<number>;
270
+ execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;
271
+ streamProcessLogs(processId: string, options?: {
272
+ signal?: AbortSignal;
273
+ }): Promise<ReadableStream<Uint8Array>>;
274
+ cleanupCompletedProcesses(): Promise<number>;
275
+ getProcessLogs(id: string): Promise<{
276
+ stdout: string;
277
+ stderr: string;
278
+ }>;
279
+ }
280
+ declare function isExecResult(value: any): value is ExecResult;
281
+ declare function isProcess(value: any): value is Process;
282
+ declare function isProcessStatus(value: string): value is ProcessStatus;
283
+
284
+ export { type BaseExecOptions, type ExecEvent, type ExecOptions, type ExecResult, ExecutionTimeoutError, type GetProcessLogsResponse, type GetProcessResponse, type ISandbox, type ListProcessesResponse, type LogEvent, type Process, ProcessAlreadyExistsError, ProcessNotFoundError, type ProcessOptions, type ProcessRecord, type ProcessStatus, SandboxError, type StartProcessRequest, type StartProcessResponse, type StreamOptions, isExecResult, isProcess, isProcessStatus };
package/dist/types.js ADDED
@@ -0,0 +1,19 @@
1
+ import {
2
+ ExecutionTimeoutError,
3
+ ProcessAlreadyExistsError,
4
+ ProcessNotFoundError,
5
+ SandboxError,
6
+ isExecResult,
7
+ isProcess,
8
+ isProcessStatus
9
+ } from "./chunk-6THNBO4S.js";
10
+ export {
11
+ ExecutionTimeoutError,
12
+ ProcessAlreadyExistsError,
13
+ ProcessNotFoundError,
14
+ SandboxError,
15
+ isExecResult,
16
+ isProcess,
17
+ isProcessStatus
18
+ };
19
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@cloudflare/sandbox",
3
- "version": "0.0.8",
3
+ "version": "0.1.0",
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.19"
10
+ "@cloudflare/containers": "^0.0.24"
11
11
  },
12
12
  "tags": [
13
13
  "sandbox",
@@ -26,11 +26,6 @@
26
26
  "types": "./dist/index.d.ts",
27
27
  "import": "./dist/index.js",
28
28
  "require": "./dist/index.js"
29
- },
30
- "./client": {
31
- "types": "./dist/client.d.ts",
32
- "import": "./dist/client.js",
33
- "require": "./dist/client.js"
34
29
  }
35
30
  },
36
31
  "keywords": [],