1010- Simple API: ` createSandbox() ` → ` run() ` → ` dispose() ` .
1111- Expose variables and functions for untrusted code to access.
1212- Pretty good security:
13- * Code runs in a Web Worker on an opaque origin: no access to the host page's storage, cookies, or DOM.
14- * Network access is blocked by default using a strict [ Content-Security-Policy] ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP ) .
15- * Disables APIs like ` navigator ` to resist device fingerprinting.
13+ - Code runs in a Web Worker on an opaque origin: no access to the host page's storage, cookies, or DOM.
14+ - Network access is blocked by default using a strict [ Content-Security-Policy] ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP ) .
15+ - Disables APIs like ` navigator ` to resist device fingerprinting.
1616
1717## Quickstart
1818
@@ -25,19 +25,19 @@ npm install slopjail
2525Create a sandbox, run some code, and clean up:
2626
2727``` typescript
28- import { createSandbox } from ' slopjail'
28+ import { createSandbox } from " slopjail" ;
2929
3030const sandbox = await createSandbox ({
3131 globals: {
3232 twenty: 20 ,
3333 add : (a : number , b : number ) => a + b ,
3434 },
35- })
35+ });
3636
3737try {
38- await sandbox .run (' console.log(await add(twenty, 5))' ) // 25
38+ await sandbox .run (" console.log(await add(twenty, 5))" ); // 25
3939} finally {
40- sandbox .dispose ()
40+ sandbox .dispose ();
4141}
4242```
4343
@@ -65,18 +65,18 @@ const sandbox = await createSandbox({
6565 add : (a : number , b : number ) => a + b ,
6666 multiply : (a : number , b : number ) => a * b ,
6767 },
68- version: ' 1.0.0' ,
68+ version: " 1.0.0" ,
6969 },
70- })
70+ });
7171
7272try {
7373 await sandbox .run (`
7474 const sum = await math.add(2, 3)
7575 const product = await math.multiply(sum, 4)
7676 console.log(version, product) // "1.0.0" 20
77- ` )
77+ ` );
7878} finally {
79- sandbox .dispose ()
79+ sandbox .dispose ();
8080}
8181```
8282
8585` run() ` enforces a 3-second execution timeout by default. If the code doesn't finish in time, the returned promise rejects with an error. You can override it per call:
8686
8787``` typescript
88- await sandbox .run (code , { timeout: 10_000 }) // 10 seconds
88+ await sandbox .run (code , { timeout: 10_000 }); // 10 seconds
8989```
9090
9191### Content-Security-Policy
@@ -98,14 +98,14 @@ Use the `contentSecurityPolicy` option to relax specific CSP directives:
9898const sandbox = await createSandbox ({
9999 contentSecurityPolicy: {
100100 // Allow access to the GitHub API
101- connectSrc: [' https://api.github.com' ],
101+ connectSrc: [" https://api.github.com" ],
102102 },
103- })
103+ });
104104
105105await sandbox .run (`
106106 const res = await fetch('https://api.github.com/zen')
107107 console.log(await res.text())
108- ` )
108+ ` );
109109```
110110
111111You can allow ESM import statements by using ` scriptSrc ` :
@@ -114,14 +114,14 @@ You can allow ESM import statements by using `scriptSrc`:
114114const sandbox = await createSandbox ({
115115 contentSecurityPolicy: {
116116 // Allow importing ES modules from esm.sh
117- scriptSrc: [' https://esm.sh' ],
117+ scriptSrc: [" https://esm.sh" ],
118118 },
119- })
119+ });
120120
121121await sandbox .run (`
122122 import _ from 'https://esm.sh/underscore'
123123 console.log(_.uniq([1, 2, 1, 4, 1, 3])) // [1, 2, 4, 3]
124- ` )
124+ ` );
125125```
126126
127127### Naming sandboxes
@@ -131,26 +131,26 @@ Give a sandbox a name for easier debugging:
131131``` typescript
132132const sandbox = await createSandbox ({
133133 name: ` ai-code-tool-${Date .now ()} ` ,
134- })
134+ });
135135```
136136
137137### Automatic disposal
138138
139139` Sandbox ` implements [ ` Symbol.dispose ` ] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/using ) , so you can use ` using ` to automatically clean up when leaving scope:
140140
141141``` typescript
142- using sandbox = await createSandbox ()
143- await sandbox .run (code )
142+ using sandbox = await createSandbox ();
143+ await sandbox .run (code );
144144```
145145
146146Which is equivalent to:
147147
148148``` typescript
149- const sandbox = await createSandbox ()
149+ const sandbox = await createSandbox ();
150150try {
151- await sandbox .run (code )
151+ await sandbox .run (code );
152152} finally {
153- sandbox .dispose ()
153+ sandbox .dispose ();
154154}
155155```
156156
@@ -165,16 +165,16 @@ const sandbox = await createSandbox({
165165 globals: {
166166 console: {
167167 log : (... args : unknown []) => {
168- document .getElementById (' output' )! .textContent += args .join (' ' ) + ' \n '
168+ document .getElementById (" output" )! .textContent += args .join (" " ) + " \n " ;
169169 },
170170 },
171171 },
172- })
172+ });
173173
174174try {
175- await sandbox .run (' console.log("hello from the sandbox!")' )
175+ await sandbox .run (' console.log("hello from the sandbox!")' );
176176} finally {
177- sandbox .dispose ()
177+ sandbox .dispose ();
178178}
179179```
180180
@@ -185,16 +185,16 @@ You can either expose a global callback for sandboxed code to call, or use `eval
185185``` typescript
186186const sandbox = await createSandbox ({
187187 // Globals are copied into the sandbox, references are not shared
188- globals: { fruit: [' apple' , ' banana' ] },
189- })
188+ globals: { fruit: [" apple" , " banana" ] },
189+ });
190190
191191try {
192- await sandbox .run (' fruit.push("cherry")' )
192+ await sandbox .run (' fruit.push("cherry")' );
193193
194- const updatedFruit = await sandbox .evaluate (' fruit' )
194+ const updatedFruit = await sandbox .evaluate (" fruit" );
195195 console .log (updatedFruit ); // ['apple', 'banana', 'cherry']
196196} finally {
197- sandbox .dispose ()
197+ sandbox .dispose ();
198198}
199199```
200200
@@ -206,22 +206,22 @@ Create a new sandboxed execution environment.
206206
207207** Creation options:**
208208
209- | Option | Type | Description |
210- | ---| ---| ---|
211- | ` globals ` | ` Record<string, unknown> ` | Variables and functions to expose inside the sandbox. |
212- | ` contentSecurityPolicy ` | ` object ` | Additional CSP directives appended to the default policy. |
213- | ` name ` | ` string ` | Name for debugging. |
209+ | Option | Type | Description |
210+ | ----------------------- | ------------------------- | --------------------------------------------------------- |
211+ | ` globals ` | ` Record<string, unknown> ` | Variables and functions to expose inside the sandbox. |
212+ | ` contentSecurityPolicy ` | ` object ` | Additional CSP directives appended to the default policy. |
213+ | ` name ` | ` string ` | Name for debugging. |
214214
215215### ` Sandbox `
216216
217- | Method | Description |
218- | ---| ---|
219- | ` run(code: string, options?): Promise<void> ` | Execute JavaScript inside the sandbox. |
217+ | Method | Description |
218+ | ---------------------------------------------------- | -------------------------------------------------------------------------------- |
219+ | ` run(code: string, options?): Promise<void> ` | Execute JavaScript inside the sandbox. |
220220| ` evaluate(expr: string, options?): Promise<unknown> ` | Evaluate a single JavaScript expression inside the sandbox and return its value. |
221- | ` dispose(): void ` | Terminate the worker and clean up all resources. |
221+ | ` dispose(): void ` | Terminate the worker and clean up all resources. |
222222
223223** Execution options:**
224224
225- | Option | Type | Description |
226- | ---| ---| ---|
225+ | Option | Type | Description |
226+ | --------- | -------- | ----------------------------------------------------------------------------------------------- |
227227| ` timeout ` | ` number ` | Maximum time in milliseconds to wait before rejecting with a timeout error. Defaults to ` 3000 ` . |
0 commit comments