@computesdk/cloudflare 1.5.1 → 1.6.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/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +34 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +34 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/worker/Dockerfile +1 -1
- package/src/worker/index.ts +5 -3
- package/src/worker/package.json +1 -1
- package/src/worker/wrangler.jsonc +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -26,6 +26,8 @@ interface CloudflareSandbox {
|
|
|
26
26
|
remote: boolean;
|
|
27
27
|
sandboxUrl?: string;
|
|
28
28
|
sandboxSecret?: string;
|
|
29
|
+
pendingEnvVars?: Record<string, string>;
|
|
30
|
+
remoteInitialized?: boolean;
|
|
29
31
|
sandbox?: any;
|
|
30
32
|
}
|
|
31
33
|
declare const cloudflare: (config: CloudflareConfig) => _computesdk_provider.Provider<CloudflareSandbox, any, any>;
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ interface CloudflareSandbox {
|
|
|
26
26
|
remote: boolean;
|
|
27
27
|
sandboxUrl?: string;
|
|
28
28
|
sandboxSecret?: string;
|
|
29
|
+
pendingEnvVars?: Record<string, string>;
|
|
30
|
+
remoteInitialized?: boolean;
|
|
29
31
|
sandbox?: any;
|
|
30
32
|
}
|
|
31
33
|
declare const cloudflare: (config: CloudflareConfig) => _computesdk_provider.Provider<CloudflareSandbox, any, any>;
|
package/dist/index.js
CHANGED
|
@@ -68,6 +68,9 @@ function runtimeToLanguage(runtime) {
|
|
|
68
68
|
return "python";
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
+
function createSandboxId() {
|
|
72
|
+
return `cf-sandbox-${crypto.randomUUID()}`;
|
|
73
|
+
}
|
|
71
74
|
async function workerRequest(cfSandbox, path, body = {}) {
|
|
72
75
|
const res = await fetch(`${cfSandbox.sandboxUrl}${path}`, {
|
|
73
76
|
method: "POST",
|
|
@@ -89,6 +92,17 @@ async function workerRequest(cfSandbox, path, body = {}) {
|
|
|
89
92
|
}
|
|
90
93
|
return data;
|
|
91
94
|
}
|
|
95
|
+
async function workerRequestWithInit(cfSandbox, path, body = {}) {
|
|
96
|
+
if (!cfSandbox.remote || cfSandbox.remoteInitialized) {
|
|
97
|
+
return workerRequest(cfSandbox, path, body);
|
|
98
|
+
}
|
|
99
|
+
const initEnvVars = cfSandbox.pendingEnvVars;
|
|
100
|
+
const requestBody = initEnvVars && Object.keys(initEnvVars).length > 0 ? { ...body, initEnvVars } : body;
|
|
101
|
+
const data = await workerRequest(cfSandbox, path, requestBody);
|
|
102
|
+
cfSandbox.pendingEnvVars = void 0;
|
|
103
|
+
cfSandbox.remoteInitialized = true;
|
|
104
|
+
return data;
|
|
105
|
+
}
|
|
92
106
|
function shellEscape(s) {
|
|
93
107
|
return s.replace(/["$`\\!]/g, "\\$&");
|
|
94
108
|
}
|
|
@@ -158,26 +172,19 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
158
172
|
ports: _ports,
|
|
159
173
|
...rest
|
|
160
174
|
} = options || {};
|
|
161
|
-
const sandboxId = optSandboxId ||
|
|
175
|
+
const sandboxId = optSandboxId || createSandboxId();
|
|
162
176
|
const envVars = { ...config.envVars, ...envs };
|
|
163
177
|
const timeout = optTimeout ?? config.timeout;
|
|
178
|
+
const sleepAfter = timeout ? `${Math.ceil(timeout / 1e3)}s` : void 0;
|
|
164
179
|
if (isRemote(config)) {
|
|
165
|
-
await workerRequest(
|
|
166
|
-
{ sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: /* @__PURE__ */ new Map() },
|
|
167
|
-
"/v1/sandbox/create",
|
|
168
|
-
{
|
|
169
|
-
envVars: Object.keys(envVars).length > 0 ? envVars : void 0,
|
|
170
|
-
...timeout ? { timeout } : {},
|
|
171
|
-
...rest
|
|
172
|
-
// Pass through provider-specific options
|
|
173
|
-
}
|
|
174
|
-
);
|
|
175
180
|
return {
|
|
176
181
|
sandbox: {
|
|
177
182
|
sandboxId,
|
|
178
183
|
remote: true,
|
|
179
184
|
sandboxUrl: config.sandboxUrl,
|
|
180
185
|
sandboxSecret: config.sandboxSecret,
|
|
186
|
+
pendingEnvVars: Object.keys(envVars).length > 0 ? envVars : void 0,
|
|
187
|
+
remoteInitialized: false,
|
|
181
188
|
exposedPorts: /* @__PURE__ */ new Map()
|
|
182
189
|
},
|
|
183
190
|
sandboxId
|
|
@@ -189,7 +196,11 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
189
196
|
);
|
|
190
197
|
}
|
|
191
198
|
try {
|
|
192
|
-
const
|
|
199
|
+
const sandboxOpts = { ...config.sandboxOptions };
|
|
200
|
+
if (sleepAfter) {
|
|
201
|
+
sandboxOpts.sleepAfter = sleepAfter;
|
|
202
|
+
}
|
|
203
|
+
const sandbox = await getSandbox(config.sandboxBinding, sandboxId, sandboxOpts);
|
|
193
204
|
if (Object.keys(envVars).length > 0) {
|
|
194
205
|
await sandbox.setEnvVars(envVars);
|
|
195
206
|
}
|
|
@@ -224,6 +235,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
224
235
|
remote: true,
|
|
225
236
|
sandboxUrl: config.sandboxUrl,
|
|
226
237
|
sandboxSecret: config.sandboxSecret,
|
|
238
|
+
remoteInitialized: true,
|
|
227
239
|
exposedPorts: /* @__PURE__ */ new Map()
|
|
228
240
|
};
|
|
229
241
|
await workerRequest(cfSandbox, "/v1/sandbox/exec", { command: "true" });
|
|
@@ -270,7 +282,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
270
282
|
const detectedRuntime = runtime || detectRuntime(code);
|
|
271
283
|
const language = runtimeToLanguage(detectedRuntime);
|
|
272
284
|
if (cfSandbox.remote) {
|
|
273
|
-
const execution = await
|
|
285
|
+
const execution = await workerRequestWithInit(cfSandbox, "/v1/sandbox/runCode", { code, language });
|
|
274
286
|
return processExecution(execution, detectedRuntime);
|
|
275
287
|
}
|
|
276
288
|
try {
|
|
@@ -289,7 +301,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
289
301
|
if (options?.background) {
|
|
290
302
|
fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
291
303
|
}
|
|
292
|
-
const result = await
|
|
304
|
+
const result = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exec", {
|
|
293
305
|
command: fullCommand,
|
|
294
306
|
cwd: options?.cwd,
|
|
295
307
|
env: options?.env,
|
|
@@ -338,7 +350,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
338
350
|
getInfo: async (cfSandbox) => {
|
|
339
351
|
try {
|
|
340
352
|
if (cfSandbox.remote) {
|
|
341
|
-
await
|
|
353
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/info");
|
|
342
354
|
} else {
|
|
343
355
|
await cfSandbox.sandbox.exec("true");
|
|
344
356
|
}
|
|
@@ -377,7 +389,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
377
389
|
}
|
|
378
390
|
let preview;
|
|
379
391
|
if (cfSandbox.remote) {
|
|
380
|
-
preview = await
|
|
392
|
+
preview = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exposePort", { port, options: {} });
|
|
381
393
|
} else {
|
|
382
394
|
preview = await cfSandbox.sandbox.exposePort(port, {});
|
|
383
395
|
}
|
|
@@ -389,7 +401,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
389
401
|
filesystem: {
|
|
390
402
|
readFile: async (cfSandbox, path) => {
|
|
391
403
|
if (cfSandbox.remote) {
|
|
392
|
-
const file2 = await
|
|
404
|
+
const file2 = await workerRequestWithInit(cfSandbox, "/v1/sandbox/readFile", { path });
|
|
393
405
|
return file2.content || "";
|
|
394
406
|
}
|
|
395
407
|
const file = await cfSandbox.sandbox.readFile(path);
|
|
@@ -397,14 +409,14 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
397
409
|
},
|
|
398
410
|
writeFile: async (cfSandbox, path, content) => {
|
|
399
411
|
if (cfSandbox.remote) {
|
|
400
|
-
await
|
|
412
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/writeFile", { path, content });
|
|
401
413
|
return;
|
|
402
414
|
}
|
|
403
415
|
await cfSandbox.sandbox.writeFile(path, content);
|
|
404
416
|
},
|
|
405
417
|
mkdir: async (cfSandbox, path) => {
|
|
406
418
|
if (cfSandbox.remote) {
|
|
407
|
-
await
|
|
419
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/mkdir", { path });
|
|
408
420
|
return;
|
|
409
421
|
}
|
|
410
422
|
await cfSandbox.sandbox.mkdir(path, { recursive: true });
|
|
@@ -412,7 +424,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
412
424
|
readdir: async (cfSandbox, path) => {
|
|
413
425
|
let result;
|
|
414
426
|
if (cfSandbox.remote) {
|
|
415
|
-
result = await
|
|
427
|
+
result = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exec", {
|
|
416
428
|
command: `ls -la "${shellEscape(path)}"`,
|
|
417
429
|
cwd: "/"
|
|
418
430
|
});
|
|
@@ -426,7 +438,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
426
438
|
},
|
|
427
439
|
exists: async (cfSandbox, path) => {
|
|
428
440
|
if (cfSandbox.remote) {
|
|
429
|
-
const result2 = await
|
|
441
|
+
const result2 = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exists", { path });
|
|
430
442
|
return result2.exists;
|
|
431
443
|
}
|
|
432
444
|
const result = await cfSandbox.sandbox.exists(path);
|
|
@@ -434,7 +446,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
434
446
|
},
|
|
435
447
|
remove: async (cfSandbox, path) => {
|
|
436
448
|
if (cfSandbox.remote) {
|
|
437
|
-
await
|
|
449
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/deleteFile", { path });
|
|
438
450
|
return;
|
|
439
451
|
}
|
|
440
452
|
await cfSandbox.sandbox.deleteFile(path);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Cloudflare Provider - Factory-based Implementation (Dual-Mode)\n *\n * Supports two connection modes:\n *\n * 1. **Remote mode** — User deploys a gateway Worker to their Cloudflare account\n * via `npx @computesdk/cloudflare`, then connects from anywhere using\n * CLOUDFLARE_SANDBOX_URL + CLOUDFLARE_SANDBOX_SECRET.\n *\n * 2. **Direct mode** — User's code runs inside a Cloudflare Worker with the\n * Durable Object binding available. Uses the @cloudflare/sandbox SDK directly.\n *\n * The mode is selected automatically based on which config fields are provided.\n */\n\nimport { defineProvider } from '@computesdk/provider';\n\n/**\n * Lazy-load @cloudflare/sandbox to avoid importing it in Node.js environments.\n * The SDK only works inside the Cloudflare Workers runtime (its transitive dep\n * @cloudflare/containers uses extensionless ESM imports that break in Node).\n * Remote mode never needs this import.\n */\nlet _getSandboxFn: ((binding: any, id: string, options?: any) => any) | null = null;\nasync function getSandbox(binding: any, id: string, options?: any): Promise<any> {\n if (!_getSandboxFn) {\n const mod = await import('@cloudflare/sandbox');\n _getSandboxFn = mod.getSandbox as (binding: any, id: string, options?: any) => any;\n }\n return _getSandboxFn(binding, id, options);\n}\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n// ─── Config ──────────────────────────────────────────────────────────────────\n\nexport interface CloudflareConfig {\n // Remote mode (from anywhere — talks to deployed gateway Worker)\n /** URL of the deployed gateway Worker (e.g. https://computesdk-sandbox.user.workers.dev) */\n sandboxUrl?: string;\n /** Shared secret for authenticating with the gateway Worker */\n sandboxSecret?: string;\n\n // Direct mode (inside a Cloudflare Worker — uses DO binding)\n /** Cloudflare Sandbox Durable Object binding from Workers environment */\n sandboxBinding?: any;\n\n // Shared options\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Environment variables to pass to sandbox */\n envVars?: Record<string, string>;\n /** Options passed to getSandbox() for lifecycle control (direct mode only) */\n sandboxOptions?: {\n sleepAfter?: string | number;\n keepAlive?: boolean;\n };\n}\n\n// ─── Internal types ──────────────────────────────────────────────────────────\n\ninterface CloudflareSandbox {\n sandboxId: string;\n exposedPorts: Map<number, string>;\n // Remote mode fields\n remote: boolean;\n sandboxUrl?: string;\n sandboxSecret?: string;\n // Direct mode fields\n sandbox?: any; // The @cloudflare/sandbox instance\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction isRemote(config: CloudflareConfig): boolean {\n return !!(config.sandboxUrl && config.sandboxSecret);\n}\n\nfunction detectRuntime(code: string): Runtime {\n if (code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')) {\n return 'python';\n }\n if (code.includes('console.log') ||\n code.includes('process.') ||\n code.includes('require(') ||\n code.includes('module.exports') ||\n code.includes('__dirname') ||\n code.includes('__filename')) {\n return 'node';\n }\n return 'python';\n}\n\nfunction runtimeToLanguage(runtime: Runtime): 'python' | 'javascript' | 'typescript' {\n switch (runtime) {\n case 'python': return 'python';\n case 'node': return 'javascript';\n case 'bun': return 'javascript';\n case 'deno': return 'typescript';\n default: return 'python';\n }\n}\n\n/**\n * Make an authenticated request to the remote gateway Worker\n */\nasync function workerRequest(\n cfSandbox: CloudflareSandbox,\n path: string,\n body: Record<string, any> = {}\n): Promise<any> {\n const res = await fetch(`${cfSandbox.sandboxUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${cfSandbox.sandboxSecret}`,\n },\n body: JSON.stringify({ sandboxId: cfSandbox.sandboxId, ...body }),\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n const text = await res.text().catch(() => '(unreadable)');\n throw new Error(`Worker request failed: ${res.status} - ${text.slice(0, 200)}`);\n }\n\n if (!res.ok) {\n throw new Error(data.error || `Worker request failed: ${res.status}`);\n }\n\n return data;\n}\n\n/**\n * Escape a string for safe use inside double-quoted shell arguments.\n */\nfunction shellEscape(s: string): string {\n return s.replace(/[\"$`\\\\!]/g, '\\\\$&');\n}\n\n/**\n * Process code execution results into a CodeResult (shared by remote and direct modes)\n */\nfunction processExecution(execution: any, detectedRuntime: Runtime): CodeResult {\n const stdoutParts: string[] = [];\n const stderrParts: string[] = [];\n\n if (execution.logs) {\n if (execution.logs.stdout) stdoutParts.push(...execution.logs.stdout);\n if (execution.logs.stderr) stderrParts.push(...execution.logs.stderr);\n }\n if (execution.results && Array.isArray(execution.results)) {\n for (const res of execution.results) {\n if (res.text) stdoutParts.push(res.text);\n }\n }\n if (execution.error) {\n const errorMsg = execution.error.message || execution.error.name || 'Execution error';\n if (errorMsg.includes('SyntaxError') || errorMsg.includes('invalid syntax')) {\n throw new Error(`Syntax error: ${errorMsg}`);\n }\n stderrParts.push(errorMsg);\n }\n\n const stdout = stdoutParts.join('\\n');\n const stderr = stderrParts.join('\\n');\n\n return {\n output: stderr ? `${stdout}${stdout && stderr ? '\\n' : ''}${stderr}` : stdout,\n exitCode: execution.error ? 1 : 0,\n language: detectedRuntime\n };\n}\n\n/**\n * Parse ls -la output into FileEntry objects (used by both modes for readdir)\n */\nfunction parseLsOutput(stdout: string): FileEntry[] {\n const lines = stdout.split('\\n').filter((line: string) => line.trim() && !line.startsWith('total'));\n\n return lines.map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const permissions = parts[0] || '';\n const size = parseInt(parts[4]) || 0;\n const dateStr = (parts[5] || '') + ' ' + (parts[6] || '');\n const date = dateStr.trim() ? new Date(dateStr) : new Date();\n const name = parts.slice(8).join(' ') || parts[parts.length - 1] || 'unknown';\n\n return {\n name,\n type: permissions.startsWith('d') ? 'directory' as const : 'file' as const,\n size,\n modified: isNaN(date.getTime()) ? new Date() : date\n };\n });\n}\n\n// ─── Provider ────────────────────────────────────────────────────────────────\n\nexport const cloudflare = defineProvider<CloudflareSandbox, CloudflareConfig>({\n name: 'cloudflare',\n methods: {\n sandbox: {\n // ─── Collection operations ───────────────────────────────────────\n\n create: async (config: CloudflareConfig, options?: CreateSandboxOptions) => {\n // Destructure known ComputeSDK fields, collect the rest for passthrough\n const {\n runtime: _runtime,\n timeout: optTimeout,\n envs,\n name: _name,\n metadata: _metadata,\n templateId: _templateId,\n snapshotId: _snapshotId,\n sandboxId: optSandboxId,\n namespace: _namespace,\n directory: _directory,\n overlays: _overlays,\n servers: _servers,\n ports: _ports,\n ...rest\n } = options || {};\n\n const sandboxId = optSandboxId || `cf-sandbox-${Date.now()}`;\n const envVars = { ...config.envVars, ...envs };\n // options.timeout takes precedence over config.timeout\n const timeout = optTimeout ?? config.timeout;\n\n // Remote mode\n if (isRemote(config)) {\n await workerRequest(\n { sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: new Map() },\n '/v1/sandbox/create',\n {\n envVars: Object.keys(envVars).length > 0 ? envVars : undefined,\n ...(timeout ? { timeout } : {}),\n ...rest, // Pass through provider-specific options\n }\n );\n\n return {\n sandbox: {\n sandboxId,\n remote: true,\n sandboxUrl: config.sandboxUrl,\n sandboxSecret: config.sandboxSecret,\n exposedPorts: new Map(),\n },\n sandboxId\n };\n }\n\n // Direct mode\n if (!config.sandboxBinding) {\n throw new Error(\n 'Missing Cloudflare config. Either:\\n' +\n ' 1. Set CLOUDFLARE_SANDBOX_URL + CLOUDFLARE_SANDBOX_SECRET (remote mode)\\n' +\n ' 2. Provide sandboxBinding from your Workers environment (direct mode)\\n' +\n 'Run `npx @computesdk/cloudflare` to deploy a gateway Worker.'\n );\n }\n\n try {\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId, config.sandboxOptions);\n\n if (Object.keys(envVars).length > 0) {\n await sandbox.setEnvVars(envVars);\n }\n\n return {\n sandbox: {\n sandbox,\n sandboxId,\n remote: false,\n exposedPorts: new Map(),\n },\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('binding')) {\n throw new Error(\n 'Cloudflare Sandbox binding failed. Ensure your Durable Object binding is properly configured in wrangler.toml. ' +\n 'See https://developers.cloudflare.com/sandbox/get-started/ for setup instructions.'\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error('Cloudflare resource limits exceeded. Check your usage at https://dash.cloudflare.com/');\n }\n }\n throw new Error(`Failed to create Cloudflare sandbox: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n getById: async (config: CloudflareConfig, sandboxId: string) => {\n // Remote mode\n if (isRemote(config)) {\n try {\n const cfSandbox: CloudflareSandbox = {\n sandboxId,\n remote: true,\n sandboxUrl: config.sandboxUrl,\n sandboxSecret: config.sandboxSecret,\n exposedPorts: new Map(),\n };\n // Verify sandbox is alive\n await workerRequest(cfSandbox, '/v1/sandbox/exec', { command: 'true' });\n return { sandbox: cfSandbox, sandboxId };\n } catch {\n return null;\n }\n }\n\n // Direct mode\n if (!config.sandboxBinding) return null;\n\n try {\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId, config.sandboxOptions);\n await sandbox.exec('true');\n return {\n sandbox: { sandbox, sandboxId, remote: false, exposedPorts: new Map() },\n sandboxId\n };\n } catch {\n return null;\n }\n },\n\n list: async (_config: CloudflareConfig) => {\n throw new Error(\n 'Cloudflare provider does not support listing sandboxes. ' +\n 'Durable Objects do not have a native list API. ' +\n 'Use getById to reconnect to specific sandboxes by ID.'\n );\n },\n\n destroy: async (config: CloudflareConfig, sandboxId: string) => {\n try {\n if (isRemote(config)) {\n await workerRequest(\n { sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: new Map() },\n '/v1/sandbox/destroy'\n );\n return;\n }\n\n if (config.sandboxBinding) {\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId);\n await sandbox.destroy();\n }\n } catch {\n // Sandbox might already be destroyed\n }\n },\n\n // ─── Instance operations ─────────────────────────────────────────\n\n runCode: async (cfSandbox: CloudflareSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const detectedRuntime = runtime || detectRuntime(code);\n const language = runtimeToLanguage(detectedRuntime);\n\n // Remote mode\n if (cfSandbox.remote) {\n const execution = await workerRequest(cfSandbox, '/v1/sandbox/runCode', { code, language });\n return processExecution(execution, detectedRuntime);\n }\n\n // Direct mode\n try {\n const execution = await cfSandbox.sandbox.runCode(code, { language });\n return processExecution(execution, detectedRuntime);\n } catch (error) {\n if (error instanceof Error && error.message.includes('Syntax error')) throw error;\n throw new Error(`Cloudflare execution failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n runCommand: async (cfSandbox: CloudflareSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n // Remote mode\n if (cfSandbox.remote) {\n try {\n let fullCommand = command;\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const result = await workerRequest(cfSandbox, '/v1/sandbox/exec', {\n command: fullCommand,\n cwd: options?.cwd,\n env: options?.env,\n timeout: options?.timeout,\n });\n\n return {\n stdout: result.stdout || '',\n stderr: result.stderr || '',\n exitCode: result.exitCode,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n }\n\n // Direct mode\n try {\n let fullCommand = command;\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const execResult = await cfSandbox.sandbox.exec(fullCommand, {\n cwd: options?.cwd,\n env: options?.env,\n timeout: options?.timeout,\n });\n\n return {\n stdout: execResult.stdout || '',\n stderr: execResult.stderr || '',\n exitCode: execResult.exitCode,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n },\n\n getInfo: async (cfSandbox: CloudflareSandbox): Promise<SandboxInfo> => {\n try {\n if (cfSandbox.remote) {\n await workerRequest(cfSandbox, '/v1/sandbox/info');\n } else {\n await cfSandbox.sandbox.exec('true');\n }\n\n return {\n id: cfSandbox.sandboxId,\n provider: 'cloudflare',\n runtime: 'python',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cloudflareSandboxId: cfSandbox.sandboxId,\n mode: cfSandbox.remote ? 'remote' : 'direct',\n }\n };\n } catch (error) {\n return {\n id: cfSandbox.sandboxId,\n provider: 'cloudflare',\n runtime: 'python',\n status: 'error',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cloudflareSandboxId: cfSandbox.sandboxId,\n mode: cfSandbox.remote ? 'remote' : 'direct',\n error: error instanceof Error ? error.message : String(error)\n }\n };\n }\n },\n\n getUrl: async (cfSandbox: CloudflareSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const { port, protocol = 'https' } = options;\n\n if (cfSandbox.exposedPorts.has(port)) {\n return cfSandbox.exposedPorts.get(port)!;\n }\n\n let preview: any;\n if (cfSandbox.remote) {\n preview = await workerRequest(cfSandbox, '/v1/sandbox/exposePort', { port, options: {} });\n } else {\n preview = await cfSandbox.sandbox.exposePort(port, {});\n }\n\n const url = `${protocol}://${preview.url}`;\n cfSandbox.exposedPorts.set(port, url);\n return url;\n },\n\n // ─── Filesystem ────────────────────────────────────────────────\n\n filesystem: {\n readFile: async (cfSandbox: CloudflareSandbox, path: string): Promise<string> => {\n if (cfSandbox.remote) {\n const file = await workerRequest(cfSandbox, '/v1/sandbox/readFile', { path });\n return file.content || '';\n }\n const file = await cfSandbox.sandbox.readFile(path);\n return file.content || '';\n },\n\n writeFile: async (cfSandbox: CloudflareSandbox, path: string, content: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequest(cfSandbox, '/v1/sandbox/writeFile', { path, content });\n return;\n }\n await cfSandbox.sandbox.writeFile(path, content);\n },\n\n mkdir: async (cfSandbox: CloudflareSandbox, path: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequest(cfSandbox, '/v1/sandbox/mkdir', { path });\n return;\n }\n await cfSandbox.sandbox.mkdir(path, { recursive: true });\n },\n\n readdir: async (cfSandbox: CloudflareSandbox, path: string): Promise<FileEntry[]> => {\n // Both modes use ls -la since there's no native readdir\n let result: any;\n if (cfSandbox.remote) {\n result = await workerRequest(cfSandbox, '/v1/sandbox/exec', {\n command: `ls -la \"${shellEscape(path)}\"`,\n cwd: '/',\n });\n } else {\n result = await cfSandbox.sandbox.exec(`ls -la \"${shellEscape(path)}\"`, { cwd: '/' });\n }\n\n if (result.exitCode !== 0) {\n throw new Error(`Directory listing failed: ${result.stderr}`);\n }\n\n return parseLsOutput(result.stdout);\n },\n\n exists: async (cfSandbox: CloudflareSandbox, path: string): Promise<boolean> => {\n if (cfSandbox.remote) {\n const result = await workerRequest(cfSandbox, '/v1/sandbox/exists', { path });\n return result.exists;\n }\n const result = await cfSandbox.sandbox.exists(path);\n return result.exists;\n },\n\n remove: async (cfSandbox: CloudflareSandbox, path: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequest(cfSandbox, '/v1/sandbox/deleteFile', { path });\n return;\n }\n await cfSandbox.sandbox.deleteFile(path);\n }\n }\n }\n }\n});\n"],"mappings":"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","names":["file","result"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Cloudflare Provider - Factory-based Implementation (Dual-Mode)\n *\n * Supports two connection modes:\n *\n * 1. **Remote mode** — User deploys a gateway Worker to their Cloudflare account\n * via `npx @computesdk/cloudflare`, then connects from anywhere using\n * CLOUDFLARE_SANDBOX_URL + CLOUDFLARE_SANDBOX_SECRET.\n *\n * 2. **Direct mode** — User's code runs inside a Cloudflare Worker with the\n * Durable Object binding available. Uses the @cloudflare/sandbox SDK directly.\n *\n * The mode is selected automatically based on which config fields are provided.\n */\n\nimport { defineProvider } from '@computesdk/provider';\n\n/**\n * Lazy-load @cloudflare/sandbox to avoid importing it in Node.js environments.\n * The SDK only works inside the Cloudflare Workers runtime (its transitive dep\n * @cloudflare/containers uses extensionless ESM imports that break in Node).\n * Remote mode never needs this import.\n */\nlet _getSandboxFn: ((binding: any, id: string, options?: any) => any) | null = null;\nasync function getSandbox(binding: any, id: string, options?: any): Promise<any> {\n if (!_getSandboxFn) {\n const mod = await import('@cloudflare/sandbox');\n _getSandboxFn = mod.getSandbox as (binding: any, id: string, options?: any) => any;\n }\n return _getSandboxFn(binding, id, options);\n}\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n// ─── Config ──────────────────────────────────────────────────────────────────\n\nexport interface CloudflareConfig {\n // Remote mode (from anywhere — talks to deployed gateway Worker)\n /** URL of the deployed gateway Worker (e.g. https://computesdk-sandbox.user.workers.dev) */\n sandboxUrl?: string;\n /** Shared secret for authenticating with the gateway Worker */\n sandboxSecret?: string;\n\n // Direct mode (inside a Cloudflare Worker — uses DO binding)\n /** Cloudflare Sandbox Durable Object binding from Workers environment */\n sandboxBinding?: any;\n\n // Shared options\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Environment variables to pass to sandbox */\n envVars?: Record<string, string>;\n /** Options passed to getSandbox() for lifecycle control (direct mode only) */\n sandboxOptions?: {\n sleepAfter?: string | number;\n keepAlive?: boolean;\n };\n}\n\n// ─── Internal types ──────────────────────────────────────────────────────────\n\ninterface CloudflareSandbox {\n sandboxId: string;\n exposedPorts: Map<number, string>;\n // Remote mode fields\n remote: boolean;\n sandboxUrl?: string;\n sandboxSecret?: string;\n pendingEnvVars?: Record<string, string>;\n remoteInitialized?: boolean;\n // Direct mode fields\n sandbox?: any; // The @cloudflare/sandbox instance\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction isRemote(config: CloudflareConfig): boolean {\n return !!(config.sandboxUrl && config.sandboxSecret);\n}\n\nfunction detectRuntime(code: string): Runtime {\n if (code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')) {\n return 'python';\n }\n if (code.includes('console.log') ||\n code.includes('process.') ||\n code.includes('require(') ||\n code.includes('module.exports') ||\n code.includes('__dirname') ||\n code.includes('__filename')) {\n return 'node';\n }\n return 'python';\n}\n\nfunction runtimeToLanguage(runtime: Runtime): 'python' | 'javascript' | 'typescript' {\n switch (runtime) {\n case 'python': return 'python';\n case 'node': return 'javascript';\n case 'bun': return 'javascript';\n case 'deno': return 'typescript';\n default: return 'python';\n }\n}\n\nfunction createSandboxId(): string {\n return `cf-sandbox-${crypto.randomUUID()}`;\n}\n\n/**\n * Make an authenticated request to the remote gateway Worker\n */\nasync function workerRequest(\n cfSandbox: CloudflareSandbox,\n path: string,\n body: Record<string, any> = {}\n): Promise<any> {\n const res = await fetch(`${cfSandbox.sandboxUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${cfSandbox.sandboxSecret}`,\n },\n body: JSON.stringify({ sandboxId: cfSandbox.sandboxId, ...body }),\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n const text = await res.text().catch(() => '(unreadable)');\n throw new Error(`Worker request failed: ${res.status} - ${text.slice(0, 200)}`);\n }\n\n if (!res.ok) {\n throw new Error(data.error || `Worker request failed: ${res.status}`);\n }\n\n return data;\n}\n\nasync function workerRequestWithInit(\n cfSandbox: CloudflareSandbox,\n path: string,\n body: Record<string, any> = {}\n): Promise<any> {\n if (!cfSandbox.remote || cfSandbox.remoteInitialized) {\n return workerRequest(cfSandbox, path, body);\n }\n\n const initEnvVars = cfSandbox.pendingEnvVars;\n const requestBody = initEnvVars && Object.keys(initEnvVars).length > 0\n ? { ...body, initEnvVars }\n : body;\n\n const data = await workerRequest(cfSandbox, path, requestBody);\n cfSandbox.pendingEnvVars = undefined;\n cfSandbox.remoteInitialized = true;\n return data;\n}\n\n/**\n * Escape a string for safe use inside double-quoted shell arguments.\n */\nfunction shellEscape(s: string): string {\n return s.replace(/[\"$`\\\\!]/g, '\\\\$&');\n}\n\n/**\n * Process code execution results into a CodeResult (shared by remote and direct modes)\n */\nfunction processExecution(execution: any, detectedRuntime: Runtime): CodeResult {\n const stdoutParts: string[] = [];\n const stderrParts: string[] = [];\n\n if (execution.logs) {\n if (execution.logs.stdout) stdoutParts.push(...execution.logs.stdout);\n if (execution.logs.stderr) stderrParts.push(...execution.logs.stderr);\n }\n if (execution.results && Array.isArray(execution.results)) {\n for (const res of execution.results) {\n if (res.text) stdoutParts.push(res.text);\n }\n }\n if (execution.error) {\n const errorMsg = execution.error.message || execution.error.name || 'Execution error';\n if (errorMsg.includes('SyntaxError') || errorMsg.includes('invalid syntax')) {\n throw new Error(`Syntax error: ${errorMsg}`);\n }\n stderrParts.push(errorMsg);\n }\n\n const stdout = stdoutParts.join('\\n');\n const stderr = stderrParts.join('\\n');\n\n return {\n output: stderr ? `${stdout}${stdout && stderr ? '\\n' : ''}${stderr}` : stdout,\n exitCode: execution.error ? 1 : 0,\n language: detectedRuntime\n };\n}\n\n/**\n * Parse ls -la output into FileEntry objects (used by both modes for readdir)\n */\nfunction parseLsOutput(stdout: string): FileEntry[] {\n const lines = stdout.split('\\n').filter((line: string) => line.trim() && !line.startsWith('total'));\n\n return lines.map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const permissions = parts[0] || '';\n const size = parseInt(parts[4]) || 0;\n const dateStr = (parts[5] || '') + ' ' + (parts[6] || '');\n const date = dateStr.trim() ? new Date(dateStr) : new Date();\n const name = parts.slice(8).join(' ') || parts[parts.length - 1] || 'unknown';\n\n return {\n name,\n type: permissions.startsWith('d') ? 'directory' as const : 'file' as const,\n size,\n modified: isNaN(date.getTime()) ? new Date() : date\n };\n });\n}\n\n// ─── Provider ────────────────────────────────────────────────────────────────\n\nexport const cloudflare = defineProvider<CloudflareSandbox, CloudflareConfig>({\n name: 'cloudflare',\n methods: {\n sandbox: {\n // ─── Collection operations ───────────────────────────────────────\n\n create: async (config: CloudflareConfig, options?: CreateSandboxOptions) => {\n // Destructure known ComputeSDK fields, collect the rest for passthrough\n const {\n runtime: _runtime,\n timeout: optTimeout,\n envs,\n name: _name,\n metadata: _metadata,\n templateId: _templateId,\n snapshotId: _snapshotId,\n sandboxId: optSandboxId,\n namespace: _namespace,\n directory: _directory,\n overlays: _overlays,\n servers: _servers,\n ports: _ports,\n ...rest\n } = options || {};\n\n const sandboxId = optSandboxId || createSandboxId();\n const envVars = { ...config.envVars, ...envs };\n // options.timeout takes precedence over config.timeout\n const timeout = optTimeout ?? config.timeout;\n const sleepAfter = timeout ? `${Math.ceil(timeout / 1000)}s` : undefined;\n\n // Remote mode\n if (isRemote(config)) {\n return {\n sandbox: {\n sandboxId,\n remote: true,\n sandboxUrl: config.sandboxUrl,\n sandboxSecret: config.sandboxSecret,\n pendingEnvVars: Object.keys(envVars).length > 0 ? envVars : undefined,\n remoteInitialized: false,\n exposedPorts: new Map(),\n },\n sandboxId\n };\n }\n\n // Direct mode\n if (!config.sandboxBinding) {\n throw new Error(\n 'Missing Cloudflare config. Either:\\n' +\n ' 1. Set CLOUDFLARE_SANDBOX_URL + CLOUDFLARE_SANDBOX_SECRET (remote mode)\\n' +\n ' 2. Provide sandboxBinding from your Workers environment (direct mode)\\n' +\n 'Run `npx @computesdk/cloudflare` to deploy a gateway Worker.'\n );\n }\n\n try {\n const sandboxOpts = { ...config.sandboxOptions };\n if (sleepAfter) {\n sandboxOpts.sleepAfter = sleepAfter;\n }\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId, sandboxOpts);\n\n if (Object.keys(envVars).length > 0) {\n await sandbox.setEnvVars(envVars);\n }\n\n return {\n sandbox: {\n sandbox,\n sandboxId,\n remote: false,\n exposedPorts: new Map(),\n },\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('binding')) {\n throw new Error(\n 'Cloudflare Sandbox binding failed. Ensure your Durable Object binding is properly configured in wrangler.toml. ' +\n 'See https://developers.cloudflare.com/sandbox/get-started/ for setup instructions.'\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error('Cloudflare resource limits exceeded. Check your usage at https://dash.cloudflare.com/');\n }\n }\n throw new Error(`Failed to create Cloudflare sandbox: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n getById: async (config: CloudflareConfig, sandboxId: string) => {\n // Remote mode\n if (isRemote(config)) {\n try {\n const cfSandbox: CloudflareSandbox = {\n sandboxId,\n remote: true,\n sandboxUrl: config.sandboxUrl,\n sandboxSecret: config.sandboxSecret,\n remoteInitialized: true,\n exposedPorts: new Map(),\n };\n // Verify sandbox is alive\n await workerRequest(cfSandbox, '/v1/sandbox/exec', { command: 'true' });\n return { sandbox: cfSandbox, sandboxId };\n } catch {\n return null;\n }\n }\n\n // Direct mode\n if (!config.sandboxBinding) return null;\n\n try {\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId, config.sandboxOptions);\n await sandbox.exec('true');\n return {\n sandbox: { sandbox, sandboxId, remote: false, exposedPorts: new Map() },\n sandboxId\n };\n } catch {\n return null;\n }\n },\n\n list: async (_config: CloudflareConfig) => {\n throw new Error(\n 'Cloudflare provider does not support listing sandboxes. ' +\n 'Durable Objects do not have a native list API. ' +\n 'Use getById to reconnect to specific sandboxes by ID.'\n );\n },\n\n destroy: async (config: CloudflareConfig, sandboxId: string) => {\n try {\n if (isRemote(config)) {\n await workerRequest(\n { sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: new Map() },\n '/v1/sandbox/destroy'\n );\n return;\n }\n\n if (config.sandboxBinding) {\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId);\n await sandbox.destroy();\n }\n } catch {\n // Sandbox might already be destroyed\n }\n },\n\n // ─── Instance operations ─────────────────────────────────────────\n\n runCode: async (cfSandbox: CloudflareSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const detectedRuntime = runtime || detectRuntime(code);\n const language = runtimeToLanguage(detectedRuntime);\n\n // Remote mode\n if (cfSandbox.remote) {\n const execution = await workerRequestWithInit(cfSandbox, '/v1/sandbox/runCode', { code, language });\n return processExecution(execution, detectedRuntime);\n }\n\n // Direct mode\n try {\n const execution = await cfSandbox.sandbox.runCode(code, { language });\n return processExecution(execution, detectedRuntime);\n } catch (error) {\n if (error instanceof Error && error.message.includes('Syntax error')) throw error;\n throw new Error(`Cloudflare execution failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n runCommand: async (cfSandbox: CloudflareSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n // Remote mode\n if (cfSandbox.remote) {\n try {\n let fullCommand = command;\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const result = await workerRequestWithInit(cfSandbox, '/v1/sandbox/exec', {\n command: fullCommand,\n cwd: options?.cwd,\n env: options?.env,\n timeout: options?.timeout,\n });\n\n return {\n stdout: result.stdout || '',\n stderr: result.stderr || '',\n exitCode: result.exitCode,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n }\n\n // Direct mode\n try {\n let fullCommand = command;\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const execResult = await cfSandbox.sandbox.exec(fullCommand, {\n cwd: options?.cwd,\n env: options?.env,\n timeout: options?.timeout,\n });\n\n return {\n stdout: execResult.stdout || '',\n stderr: execResult.stderr || '',\n exitCode: execResult.exitCode,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n },\n\n getInfo: async (cfSandbox: CloudflareSandbox): Promise<SandboxInfo> => {\n try {\n if (cfSandbox.remote) {\n await workerRequestWithInit(cfSandbox, '/v1/sandbox/info');\n } else {\n await cfSandbox.sandbox.exec('true');\n }\n\n return {\n id: cfSandbox.sandboxId,\n provider: 'cloudflare',\n runtime: 'python',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cloudflareSandboxId: cfSandbox.sandboxId,\n mode: cfSandbox.remote ? 'remote' : 'direct',\n }\n };\n } catch (error) {\n return {\n id: cfSandbox.sandboxId,\n provider: 'cloudflare',\n runtime: 'python',\n status: 'error',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cloudflareSandboxId: cfSandbox.sandboxId,\n mode: cfSandbox.remote ? 'remote' : 'direct',\n error: error instanceof Error ? error.message : String(error)\n }\n };\n }\n },\n\n getUrl: async (cfSandbox: CloudflareSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const { port, protocol = 'https' } = options;\n\n if (cfSandbox.exposedPorts.has(port)) {\n return cfSandbox.exposedPorts.get(port)!;\n }\n\n let preview: any;\n if (cfSandbox.remote) {\n preview = await workerRequestWithInit(cfSandbox, '/v1/sandbox/exposePort', { port, options: {} });\n } else {\n preview = await cfSandbox.sandbox.exposePort(port, {});\n }\n\n const url = `${protocol}://${preview.url}`;\n cfSandbox.exposedPorts.set(port, url);\n return url;\n },\n\n // ─── Filesystem ────────────────────────────────────────────────\n\n filesystem: {\n readFile: async (cfSandbox: CloudflareSandbox, path: string): Promise<string> => {\n if (cfSandbox.remote) {\n const file = await workerRequestWithInit(cfSandbox, '/v1/sandbox/readFile', { path });\n return file.content || '';\n }\n const file = await cfSandbox.sandbox.readFile(path);\n return file.content || '';\n },\n\n writeFile: async (cfSandbox: CloudflareSandbox, path: string, content: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequestWithInit(cfSandbox, '/v1/sandbox/writeFile', { path, content });\n return;\n }\n await cfSandbox.sandbox.writeFile(path, content);\n },\n\n mkdir: async (cfSandbox: CloudflareSandbox, path: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequestWithInit(cfSandbox, '/v1/sandbox/mkdir', { path });\n return;\n }\n await cfSandbox.sandbox.mkdir(path, { recursive: true });\n },\n\n readdir: async (cfSandbox: CloudflareSandbox, path: string): Promise<FileEntry[]> => {\n // Both modes use ls -la since there's no native readdir\n let result: any;\n if (cfSandbox.remote) {\n result = await workerRequestWithInit(cfSandbox, '/v1/sandbox/exec', {\n command: `ls -la \"${shellEscape(path)}\"`,\n cwd: '/',\n });\n } else {\n result = await cfSandbox.sandbox.exec(`ls -la \"${shellEscape(path)}\"`, { cwd: '/' });\n }\n\n if (result.exitCode !== 0) {\n throw new Error(`Directory listing failed: ${result.stderr}`);\n }\n\n return parseLsOutput(result.stdout);\n },\n\n exists: async (cfSandbox: CloudflareSandbox, path: string): Promise<boolean> => {\n if (cfSandbox.remote) {\n const result = await workerRequestWithInit(cfSandbox, '/v1/sandbox/exists', { path });\n return result.exists;\n }\n const result = await cfSandbox.sandbox.exists(path);\n return result.exists;\n },\n\n remove: async (cfSandbox: CloudflareSandbox, path: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequestWithInit(cfSandbox, '/v1/sandbox/deleteFile', { path });\n return;\n }\n await cfSandbox.sandbox.deleteFile(path);\n }\n }\n }\n }\n});"],"mappings":"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","names":["file","result"]}
|
package/dist/index.mjs
CHANGED
|
@@ -34,6 +34,9 @@ function runtimeToLanguage(runtime) {
|
|
|
34
34
|
return "python";
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
function createSandboxId() {
|
|
38
|
+
return `cf-sandbox-${crypto.randomUUID()}`;
|
|
39
|
+
}
|
|
37
40
|
async function workerRequest(cfSandbox, path, body = {}) {
|
|
38
41
|
const res = await fetch(`${cfSandbox.sandboxUrl}${path}`, {
|
|
39
42
|
method: "POST",
|
|
@@ -55,6 +58,17 @@ async function workerRequest(cfSandbox, path, body = {}) {
|
|
|
55
58
|
}
|
|
56
59
|
return data;
|
|
57
60
|
}
|
|
61
|
+
async function workerRequestWithInit(cfSandbox, path, body = {}) {
|
|
62
|
+
if (!cfSandbox.remote || cfSandbox.remoteInitialized) {
|
|
63
|
+
return workerRequest(cfSandbox, path, body);
|
|
64
|
+
}
|
|
65
|
+
const initEnvVars = cfSandbox.pendingEnvVars;
|
|
66
|
+
const requestBody = initEnvVars && Object.keys(initEnvVars).length > 0 ? { ...body, initEnvVars } : body;
|
|
67
|
+
const data = await workerRequest(cfSandbox, path, requestBody);
|
|
68
|
+
cfSandbox.pendingEnvVars = void 0;
|
|
69
|
+
cfSandbox.remoteInitialized = true;
|
|
70
|
+
return data;
|
|
71
|
+
}
|
|
58
72
|
function shellEscape(s) {
|
|
59
73
|
return s.replace(/["$`\\!]/g, "\\$&");
|
|
60
74
|
}
|
|
@@ -124,26 +138,19 @@ var cloudflare = defineProvider({
|
|
|
124
138
|
ports: _ports,
|
|
125
139
|
...rest
|
|
126
140
|
} = options || {};
|
|
127
|
-
const sandboxId = optSandboxId ||
|
|
141
|
+
const sandboxId = optSandboxId || createSandboxId();
|
|
128
142
|
const envVars = { ...config.envVars, ...envs };
|
|
129
143
|
const timeout = optTimeout ?? config.timeout;
|
|
144
|
+
const sleepAfter = timeout ? `${Math.ceil(timeout / 1e3)}s` : void 0;
|
|
130
145
|
if (isRemote(config)) {
|
|
131
|
-
await workerRequest(
|
|
132
|
-
{ sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: /* @__PURE__ */ new Map() },
|
|
133
|
-
"/v1/sandbox/create",
|
|
134
|
-
{
|
|
135
|
-
envVars: Object.keys(envVars).length > 0 ? envVars : void 0,
|
|
136
|
-
...timeout ? { timeout } : {},
|
|
137
|
-
...rest
|
|
138
|
-
// Pass through provider-specific options
|
|
139
|
-
}
|
|
140
|
-
);
|
|
141
146
|
return {
|
|
142
147
|
sandbox: {
|
|
143
148
|
sandboxId,
|
|
144
149
|
remote: true,
|
|
145
150
|
sandboxUrl: config.sandboxUrl,
|
|
146
151
|
sandboxSecret: config.sandboxSecret,
|
|
152
|
+
pendingEnvVars: Object.keys(envVars).length > 0 ? envVars : void 0,
|
|
153
|
+
remoteInitialized: false,
|
|
147
154
|
exposedPorts: /* @__PURE__ */ new Map()
|
|
148
155
|
},
|
|
149
156
|
sandboxId
|
|
@@ -155,7 +162,11 @@ var cloudflare = defineProvider({
|
|
|
155
162
|
);
|
|
156
163
|
}
|
|
157
164
|
try {
|
|
158
|
-
const
|
|
165
|
+
const sandboxOpts = { ...config.sandboxOptions };
|
|
166
|
+
if (sleepAfter) {
|
|
167
|
+
sandboxOpts.sleepAfter = sleepAfter;
|
|
168
|
+
}
|
|
169
|
+
const sandbox = await getSandbox(config.sandboxBinding, sandboxId, sandboxOpts);
|
|
159
170
|
if (Object.keys(envVars).length > 0) {
|
|
160
171
|
await sandbox.setEnvVars(envVars);
|
|
161
172
|
}
|
|
@@ -190,6 +201,7 @@ var cloudflare = defineProvider({
|
|
|
190
201
|
remote: true,
|
|
191
202
|
sandboxUrl: config.sandboxUrl,
|
|
192
203
|
sandboxSecret: config.sandboxSecret,
|
|
204
|
+
remoteInitialized: true,
|
|
193
205
|
exposedPorts: /* @__PURE__ */ new Map()
|
|
194
206
|
};
|
|
195
207
|
await workerRequest(cfSandbox, "/v1/sandbox/exec", { command: "true" });
|
|
@@ -236,7 +248,7 @@ var cloudflare = defineProvider({
|
|
|
236
248
|
const detectedRuntime = runtime || detectRuntime(code);
|
|
237
249
|
const language = runtimeToLanguage(detectedRuntime);
|
|
238
250
|
if (cfSandbox.remote) {
|
|
239
|
-
const execution = await
|
|
251
|
+
const execution = await workerRequestWithInit(cfSandbox, "/v1/sandbox/runCode", { code, language });
|
|
240
252
|
return processExecution(execution, detectedRuntime);
|
|
241
253
|
}
|
|
242
254
|
try {
|
|
@@ -255,7 +267,7 @@ var cloudflare = defineProvider({
|
|
|
255
267
|
if (options?.background) {
|
|
256
268
|
fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
257
269
|
}
|
|
258
|
-
const result = await
|
|
270
|
+
const result = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exec", {
|
|
259
271
|
command: fullCommand,
|
|
260
272
|
cwd: options?.cwd,
|
|
261
273
|
env: options?.env,
|
|
@@ -304,7 +316,7 @@ var cloudflare = defineProvider({
|
|
|
304
316
|
getInfo: async (cfSandbox) => {
|
|
305
317
|
try {
|
|
306
318
|
if (cfSandbox.remote) {
|
|
307
|
-
await
|
|
319
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/info");
|
|
308
320
|
} else {
|
|
309
321
|
await cfSandbox.sandbox.exec("true");
|
|
310
322
|
}
|
|
@@ -343,7 +355,7 @@ var cloudflare = defineProvider({
|
|
|
343
355
|
}
|
|
344
356
|
let preview;
|
|
345
357
|
if (cfSandbox.remote) {
|
|
346
|
-
preview = await
|
|
358
|
+
preview = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exposePort", { port, options: {} });
|
|
347
359
|
} else {
|
|
348
360
|
preview = await cfSandbox.sandbox.exposePort(port, {});
|
|
349
361
|
}
|
|
@@ -355,7 +367,7 @@ var cloudflare = defineProvider({
|
|
|
355
367
|
filesystem: {
|
|
356
368
|
readFile: async (cfSandbox, path) => {
|
|
357
369
|
if (cfSandbox.remote) {
|
|
358
|
-
const file2 = await
|
|
370
|
+
const file2 = await workerRequestWithInit(cfSandbox, "/v1/sandbox/readFile", { path });
|
|
359
371
|
return file2.content || "";
|
|
360
372
|
}
|
|
361
373
|
const file = await cfSandbox.sandbox.readFile(path);
|
|
@@ -363,14 +375,14 @@ var cloudflare = defineProvider({
|
|
|
363
375
|
},
|
|
364
376
|
writeFile: async (cfSandbox, path, content) => {
|
|
365
377
|
if (cfSandbox.remote) {
|
|
366
|
-
await
|
|
378
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/writeFile", { path, content });
|
|
367
379
|
return;
|
|
368
380
|
}
|
|
369
381
|
await cfSandbox.sandbox.writeFile(path, content);
|
|
370
382
|
},
|
|
371
383
|
mkdir: async (cfSandbox, path) => {
|
|
372
384
|
if (cfSandbox.remote) {
|
|
373
|
-
await
|
|
385
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/mkdir", { path });
|
|
374
386
|
return;
|
|
375
387
|
}
|
|
376
388
|
await cfSandbox.sandbox.mkdir(path, { recursive: true });
|
|
@@ -378,7 +390,7 @@ var cloudflare = defineProvider({
|
|
|
378
390
|
readdir: async (cfSandbox, path) => {
|
|
379
391
|
let result;
|
|
380
392
|
if (cfSandbox.remote) {
|
|
381
|
-
result = await
|
|
393
|
+
result = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exec", {
|
|
382
394
|
command: `ls -la "${shellEscape(path)}"`,
|
|
383
395
|
cwd: "/"
|
|
384
396
|
});
|
|
@@ -392,7 +404,7 @@ var cloudflare = defineProvider({
|
|
|
392
404
|
},
|
|
393
405
|
exists: async (cfSandbox, path) => {
|
|
394
406
|
if (cfSandbox.remote) {
|
|
395
|
-
const result2 = await
|
|
407
|
+
const result2 = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exists", { path });
|
|
396
408
|
return result2.exists;
|
|
397
409
|
}
|
|
398
410
|
const result = await cfSandbox.sandbox.exists(path);
|
|
@@ -400,7 +412,7 @@ var cloudflare = defineProvider({
|
|
|
400
412
|
},
|
|
401
413
|
remove: async (cfSandbox, path) => {
|
|
402
414
|
if (cfSandbox.remote) {
|
|
403
|
-
await
|
|
415
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/deleteFile", { path });
|
|
404
416
|
return;
|
|
405
417
|
}
|
|
406
418
|
await cfSandbox.sandbox.deleteFile(path);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Cloudflare Provider - Factory-based Implementation (Dual-Mode)\n *\n * Supports two connection modes:\n *\n * 1. **Remote mode** — User deploys a gateway Worker to their Cloudflare account\n * via `npx @computesdk/cloudflare`, then connects from anywhere using\n * CLOUDFLARE_SANDBOX_URL + CLOUDFLARE_SANDBOX_SECRET.\n *\n * 2. **Direct mode** — User's code runs inside a Cloudflare Worker with the\n * Durable Object binding available. Uses the @cloudflare/sandbox SDK directly.\n *\n * The mode is selected automatically based on which config fields are provided.\n */\n\nimport { defineProvider } from '@computesdk/provider';\n\n/**\n * Lazy-load @cloudflare/sandbox to avoid importing it in Node.js environments.\n * The SDK only works inside the Cloudflare Workers runtime (its transitive dep\n * @cloudflare/containers uses extensionless ESM imports that break in Node).\n * Remote mode never needs this import.\n */\nlet _getSandboxFn: ((binding: any, id: string, options?: any) => any) | null = null;\nasync function getSandbox(binding: any, id: string, options?: any): Promise<any> {\n if (!_getSandboxFn) {\n const mod = await import('@cloudflare/sandbox');\n _getSandboxFn = mod.getSandbox as (binding: any, id: string, options?: any) => any;\n }\n return _getSandboxFn(binding, id, options);\n}\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n// ─── Config ──────────────────────────────────────────────────────────────────\n\nexport interface CloudflareConfig {\n // Remote mode (from anywhere — talks to deployed gateway Worker)\n /** URL of the deployed gateway Worker (e.g. https://computesdk-sandbox.user.workers.dev) */\n sandboxUrl?: string;\n /** Shared secret for authenticating with the gateway Worker */\n sandboxSecret?: string;\n\n // Direct mode (inside a Cloudflare Worker — uses DO binding)\n /** Cloudflare Sandbox Durable Object binding from Workers environment */\n sandboxBinding?: any;\n\n // Shared options\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Environment variables to pass to sandbox */\n envVars?: Record<string, string>;\n /** Options passed to getSandbox() for lifecycle control (direct mode only) */\n sandboxOptions?: {\n sleepAfter?: string | number;\n keepAlive?: boolean;\n };\n}\n\n// ─── Internal types ──────────────────────────────────────────────────────────\n\ninterface CloudflareSandbox {\n sandboxId: string;\n exposedPorts: Map<number, string>;\n // Remote mode fields\n remote: boolean;\n sandboxUrl?: string;\n sandboxSecret?: string;\n // Direct mode fields\n sandbox?: any; // The @cloudflare/sandbox instance\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction isRemote(config: CloudflareConfig): boolean {\n return !!(config.sandboxUrl && config.sandboxSecret);\n}\n\nfunction detectRuntime(code: string): Runtime {\n if (code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')) {\n return 'python';\n }\n if (code.includes('console.log') ||\n code.includes('process.') ||\n code.includes('require(') ||\n code.includes('module.exports') ||\n code.includes('__dirname') ||\n code.includes('__filename')) {\n return 'node';\n }\n return 'python';\n}\n\nfunction runtimeToLanguage(runtime: Runtime): 'python' | 'javascript' | 'typescript' {\n switch (runtime) {\n case 'python': return 'python';\n case 'node': return 'javascript';\n case 'bun': return 'javascript';\n case 'deno': return 'typescript';\n default: return 'python';\n }\n}\n\n/**\n * Make an authenticated request to the remote gateway Worker\n */\nasync function workerRequest(\n cfSandbox: CloudflareSandbox,\n path: string,\n body: Record<string, any> = {}\n): Promise<any> {\n const res = await fetch(`${cfSandbox.sandboxUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${cfSandbox.sandboxSecret}`,\n },\n body: JSON.stringify({ sandboxId: cfSandbox.sandboxId, ...body }),\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n const text = await res.text().catch(() => '(unreadable)');\n throw new Error(`Worker request failed: ${res.status} - ${text.slice(0, 200)}`);\n }\n\n if (!res.ok) {\n throw new Error(data.error || `Worker request failed: ${res.status}`);\n }\n\n return data;\n}\n\n/**\n * Escape a string for safe use inside double-quoted shell arguments.\n */\nfunction shellEscape(s: string): string {\n return s.replace(/[\"$`\\\\!]/g, '\\\\$&');\n}\n\n/**\n * Process code execution results into a CodeResult (shared by remote and direct modes)\n */\nfunction processExecution(execution: any, detectedRuntime: Runtime): CodeResult {\n const stdoutParts: string[] = [];\n const stderrParts: string[] = [];\n\n if (execution.logs) {\n if (execution.logs.stdout) stdoutParts.push(...execution.logs.stdout);\n if (execution.logs.stderr) stderrParts.push(...execution.logs.stderr);\n }\n if (execution.results && Array.isArray(execution.results)) {\n for (const res of execution.results) {\n if (res.text) stdoutParts.push(res.text);\n }\n }\n if (execution.error) {\n const errorMsg = execution.error.message || execution.error.name || 'Execution error';\n if (errorMsg.includes('SyntaxError') || errorMsg.includes('invalid syntax')) {\n throw new Error(`Syntax error: ${errorMsg}`);\n }\n stderrParts.push(errorMsg);\n }\n\n const stdout = stdoutParts.join('\\n');\n const stderr = stderrParts.join('\\n');\n\n return {\n output: stderr ? `${stdout}${stdout && stderr ? '\\n' : ''}${stderr}` : stdout,\n exitCode: execution.error ? 1 : 0,\n language: detectedRuntime\n };\n}\n\n/**\n * Parse ls -la output into FileEntry objects (used by both modes for readdir)\n */\nfunction parseLsOutput(stdout: string): FileEntry[] {\n const lines = stdout.split('\\n').filter((line: string) => line.trim() && !line.startsWith('total'));\n\n return lines.map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const permissions = parts[0] || '';\n const size = parseInt(parts[4]) || 0;\n const dateStr = (parts[5] || '') + ' ' + (parts[6] || '');\n const date = dateStr.trim() ? new Date(dateStr) : new Date();\n const name = parts.slice(8).join(' ') || parts[parts.length - 1] || 'unknown';\n\n return {\n name,\n type: permissions.startsWith('d') ? 'directory' as const : 'file' as const,\n size,\n modified: isNaN(date.getTime()) ? new Date() : date\n };\n });\n}\n\n// ─── Provider ────────────────────────────────────────────────────────────────\n\nexport const cloudflare = defineProvider<CloudflareSandbox, CloudflareConfig>({\n name: 'cloudflare',\n methods: {\n sandbox: {\n // ─── Collection operations ───────────────────────────────────────\n\n create: async (config: CloudflareConfig, options?: CreateSandboxOptions) => {\n // Destructure known ComputeSDK fields, collect the rest for passthrough\n const {\n runtime: _runtime,\n timeout: optTimeout,\n envs,\n name: _name,\n metadata: _metadata,\n templateId: _templateId,\n snapshotId: _snapshotId,\n sandboxId: optSandboxId,\n namespace: _namespace,\n directory: _directory,\n overlays: _overlays,\n servers: _servers,\n ports: _ports,\n ...rest\n } = options || {};\n\n const sandboxId = optSandboxId || `cf-sandbox-${Date.now()}`;\n const envVars = { ...config.envVars, ...envs };\n // options.timeout takes precedence over config.timeout\n const timeout = optTimeout ?? config.timeout;\n\n // Remote mode\n if (isRemote(config)) {\n await workerRequest(\n { sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: new Map() },\n '/v1/sandbox/create',\n {\n envVars: Object.keys(envVars).length > 0 ? envVars : undefined,\n ...(timeout ? { timeout } : {}),\n ...rest, // Pass through provider-specific options\n }\n );\n\n return {\n sandbox: {\n sandboxId,\n remote: true,\n sandboxUrl: config.sandboxUrl,\n sandboxSecret: config.sandboxSecret,\n exposedPorts: new Map(),\n },\n sandboxId\n };\n }\n\n // Direct mode\n if (!config.sandboxBinding) {\n throw new Error(\n 'Missing Cloudflare config. Either:\\n' +\n ' 1. Set CLOUDFLARE_SANDBOX_URL + CLOUDFLARE_SANDBOX_SECRET (remote mode)\\n' +\n ' 2. Provide sandboxBinding from your Workers environment (direct mode)\\n' +\n 'Run `npx @computesdk/cloudflare` to deploy a gateway Worker.'\n );\n }\n\n try {\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId, config.sandboxOptions);\n\n if (Object.keys(envVars).length > 0) {\n await sandbox.setEnvVars(envVars);\n }\n\n return {\n sandbox: {\n sandbox,\n sandboxId,\n remote: false,\n exposedPorts: new Map(),\n },\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('binding')) {\n throw new Error(\n 'Cloudflare Sandbox binding failed. Ensure your Durable Object binding is properly configured in wrangler.toml. ' +\n 'See https://developers.cloudflare.com/sandbox/get-started/ for setup instructions.'\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error('Cloudflare resource limits exceeded. Check your usage at https://dash.cloudflare.com/');\n }\n }\n throw new Error(`Failed to create Cloudflare sandbox: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n getById: async (config: CloudflareConfig, sandboxId: string) => {\n // Remote mode\n if (isRemote(config)) {\n try {\n const cfSandbox: CloudflareSandbox = {\n sandboxId,\n remote: true,\n sandboxUrl: config.sandboxUrl,\n sandboxSecret: config.sandboxSecret,\n exposedPorts: new Map(),\n };\n // Verify sandbox is alive\n await workerRequest(cfSandbox, '/v1/sandbox/exec', { command: 'true' });\n return { sandbox: cfSandbox, sandboxId };\n } catch {\n return null;\n }\n }\n\n // Direct mode\n if (!config.sandboxBinding) return null;\n\n try {\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId, config.sandboxOptions);\n await sandbox.exec('true');\n return {\n sandbox: { sandbox, sandboxId, remote: false, exposedPorts: new Map() },\n sandboxId\n };\n } catch {\n return null;\n }\n },\n\n list: async (_config: CloudflareConfig) => {\n throw new Error(\n 'Cloudflare provider does not support listing sandboxes. ' +\n 'Durable Objects do not have a native list API. ' +\n 'Use getById to reconnect to specific sandboxes by ID.'\n );\n },\n\n destroy: async (config: CloudflareConfig, sandboxId: string) => {\n try {\n if (isRemote(config)) {\n await workerRequest(\n { sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: new Map() },\n '/v1/sandbox/destroy'\n );\n return;\n }\n\n if (config.sandboxBinding) {\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId);\n await sandbox.destroy();\n }\n } catch {\n // Sandbox might already be destroyed\n }\n },\n\n // ─── Instance operations ─────────────────────────────────────────\n\n runCode: async (cfSandbox: CloudflareSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const detectedRuntime = runtime || detectRuntime(code);\n const language = runtimeToLanguage(detectedRuntime);\n\n // Remote mode\n if (cfSandbox.remote) {\n const execution = await workerRequest(cfSandbox, '/v1/sandbox/runCode', { code, language });\n return processExecution(execution, detectedRuntime);\n }\n\n // Direct mode\n try {\n const execution = await cfSandbox.sandbox.runCode(code, { language });\n return processExecution(execution, detectedRuntime);\n } catch (error) {\n if (error instanceof Error && error.message.includes('Syntax error')) throw error;\n throw new Error(`Cloudflare execution failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n runCommand: async (cfSandbox: CloudflareSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n // Remote mode\n if (cfSandbox.remote) {\n try {\n let fullCommand = command;\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const result = await workerRequest(cfSandbox, '/v1/sandbox/exec', {\n command: fullCommand,\n cwd: options?.cwd,\n env: options?.env,\n timeout: options?.timeout,\n });\n\n return {\n stdout: result.stdout || '',\n stderr: result.stderr || '',\n exitCode: result.exitCode,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n }\n\n // Direct mode\n try {\n let fullCommand = command;\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const execResult = await cfSandbox.sandbox.exec(fullCommand, {\n cwd: options?.cwd,\n env: options?.env,\n timeout: options?.timeout,\n });\n\n return {\n stdout: execResult.stdout || '',\n stderr: execResult.stderr || '',\n exitCode: execResult.exitCode,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n },\n\n getInfo: async (cfSandbox: CloudflareSandbox): Promise<SandboxInfo> => {\n try {\n if (cfSandbox.remote) {\n await workerRequest(cfSandbox, '/v1/sandbox/info');\n } else {\n await cfSandbox.sandbox.exec('true');\n }\n\n return {\n id: cfSandbox.sandboxId,\n provider: 'cloudflare',\n runtime: 'python',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cloudflareSandboxId: cfSandbox.sandboxId,\n mode: cfSandbox.remote ? 'remote' : 'direct',\n }\n };\n } catch (error) {\n return {\n id: cfSandbox.sandboxId,\n provider: 'cloudflare',\n runtime: 'python',\n status: 'error',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cloudflareSandboxId: cfSandbox.sandboxId,\n mode: cfSandbox.remote ? 'remote' : 'direct',\n error: error instanceof Error ? error.message : String(error)\n }\n };\n }\n },\n\n getUrl: async (cfSandbox: CloudflareSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const { port, protocol = 'https' } = options;\n\n if (cfSandbox.exposedPorts.has(port)) {\n return cfSandbox.exposedPorts.get(port)!;\n }\n\n let preview: any;\n if (cfSandbox.remote) {\n preview = await workerRequest(cfSandbox, '/v1/sandbox/exposePort', { port, options: {} });\n } else {\n preview = await cfSandbox.sandbox.exposePort(port, {});\n }\n\n const url = `${protocol}://${preview.url}`;\n cfSandbox.exposedPorts.set(port, url);\n return url;\n },\n\n // ─── Filesystem ────────────────────────────────────────────────\n\n filesystem: {\n readFile: async (cfSandbox: CloudflareSandbox, path: string): Promise<string> => {\n if (cfSandbox.remote) {\n const file = await workerRequest(cfSandbox, '/v1/sandbox/readFile', { path });\n return file.content || '';\n }\n const file = await cfSandbox.sandbox.readFile(path);\n return file.content || '';\n },\n\n writeFile: async (cfSandbox: CloudflareSandbox, path: string, content: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequest(cfSandbox, '/v1/sandbox/writeFile', { path, content });\n return;\n }\n await cfSandbox.sandbox.writeFile(path, content);\n },\n\n mkdir: async (cfSandbox: CloudflareSandbox, path: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequest(cfSandbox, '/v1/sandbox/mkdir', { path });\n return;\n }\n await cfSandbox.sandbox.mkdir(path, { recursive: true });\n },\n\n readdir: async (cfSandbox: CloudflareSandbox, path: string): Promise<FileEntry[]> => {\n // Both modes use ls -la since there's no native readdir\n let result: any;\n if (cfSandbox.remote) {\n result = await workerRequest(cfSandbox, '/v1/sandbox/exec', {\n command: `ls -la \"${shellEscape(path)}\"`,\n cwd: '/',\n });\n } else {\n result = await cfSandbox.sandbox.exec(`ls -la \"${shellEscape(path)}\"`, { cwd: '/' });\n }\n\n if (result.exitCode !== 0) {\n throw new Error(`Directory listing failed: ${result.stderr}`);\n }\n\n return parseLsOutput(result.stdout);\n },\n\n exists: async (cfSandbox: CloudflareSandbox, path: string): Promise<boolean> => {\n if (cfSandbox.remote) {\n const result = await workerRequest(cfSandbox, '/v1/sandbox/exists', { path });\n return result.exists;\n }\n const result = await cfSandbox.sandbox.exists(path);\n return result.exists;\n },\n\n remove: async (cfSandbox: CloudflareSandbox, path: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequest(cfSandbox, '/v1/sandbox/deleteFile', { path });\n return;\n }\n await cfSandbox.sandbox.deleteFile(path);\n }\n }\n }\n }\n});\n"],"mappings":"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","names":["file","result"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Cloudflare Provider - Factory-based Implementation (Dual-Mode)\n *\n * Supports two connection modes:\n *\n * 1. **Remote mode** — User deploys a gateway Worker to their Cloudflare account\n * via `npx @computesdk/cloudflare`, then connects from anywhere using\n * CLOUDFLARE_SANDBOX_URL + CLOUDFLARE_SANDBOX_SECRET.\n *\n * 2. **Direct mode** — User's code runs inside a Cloudflare Worker with the\n * Durable Object binding available. Uses the @cloudflare/sandbox SDK directly.\n *\n * The mode is selected automatically based on which config fields are provided.\n */\n\nimport { defineProvider } from '@computesdk/provider';\n\n/**\n * Lazy-load @cloudflare/sandbox to avoid importing it in Node.js environments.\n * The SDK only works inside the Cloudflare Workers runtime (its transitive dep\n * @cloudflare/containers uses extensionless ESM imports that break in Node).\n * Remote mode never needs this import.\n */\nlet _getSandboxFn: ((binding: any, id: string, options?: any) => any) | null = null;\nasync function getSandbox(binding: any, id: string, options?: any): Promise<any> {\n if (!_getSandboxFn) {\n const mod = await import('@cloudflare/sandbox');\n _getSandboxFn = mod.getSandbox as (binding: any, id: string, options?: any) => any;\n }\n return _getSandboxFn(binding, id, options);\n}\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n// ─── Config ──────────────────────────────────────────────────────────────────\n\nexport interface CloudflareConfig {\n // Remote mode (from anywhere — talks to deployed gateway Worker)\n /** URL of the deployed gateway Worker (e.g. https://computesdk-sandbox.user.workers.dev) */\n sandboxUrl?: string;\n /** Shared secret for authenticating with the gateway Worker */\n sandboxSecret?: string;\n\n // Direct mode (inside a Cloudflare Worker — uses DO binding)\n /** Cloudflare Sandbox Durable Object binding from Workers environment */\n sandboxBinding?: any;\n\n // Shared options\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Environment variables to pass to sandbox */\n envVars?: Record<string, string>;\n /** Options passed to getSandbox() for lifecycle control (direct mode only) */\n sandboxOptions?: {\n sleepAfter?: string | number;\n keepAlive?: boolean;\n };\n}\n\n// ─── Internal types ──────────────────────────────────────────────────────────\n\ninterface CloudflareSandbox {\n sandboxId: string;\n exposedPorts: Map<number, string>;\n // Remote mode fields\n remote: boolean;\n sandboxUrl?: string;\n sandboxSecret?: string;\n pendingEnvVars?: Record<string, string>;\n remoteInitialized?: boolean;\n // Direct mode fields\n sandbox?: any; // The @cloudflare/sandbox instance\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction isRemote(config: CloudflareConfig): boolean {\n return !!(config.sandboxUrl && config.sandboxSecret);\n}\n\nfunction detectRuntime(code: string): Runtime {\n if (code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')) {\n return 'python';\n }\n if (code.includes('console.log') ||\n code.includes('process.') ||\n code.includes('require(') ||\n code.includes('module.exports') ||\n code.includes('__dirname') ||\n code.includes('__filename')) {\n return 'node';\n }\n return 'python';\n}\n\nfunction runtimeToLanguage(runtime: Runtime): 'python' | 'javascript' | 'typescript' {\n switch (runtime) {\n case 'python': return 'python';\n case 'node': return 'javascript';\n case 'bun': return 'javascript';\n case 'deno': return 'typescript';\n default: return 'python';\n }\n}\n\nfunction createSandboxId(): string {\n return `cf-sandbox-${crypto.randomUUID()}`;\n}\n\n/**\n * Make an authenticated request to the remote gateway Worker\n */\nasync function workerRequest(\n cfSandbox: CloudflareSandbox,\n path: string,\n body: Record<string, any> = {}\n): Promise<any> {\n const res = await fetch(`${cfSandbox.sandboxUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${cfSandbox.sandboxSecret}`,\n },\n body: JSON.stringify({ sandboxId: cfSandbox.sandboxId, ...body }),\n });\n\n let data: any;\n try {\n data = await res.json();\n } catch {\n const text = await res.text().catch(() => '(unreadable)');\n throw new Error(`Worker request failed: ${res.status} - ${text.slice(0, 200)}`);\n }\n\n if (!res.ok) {\n throw new Error(data.error || `Worker request failed: ${res.status}`);\n }\n\n return data;\n}\n\nasync function workerRequestWithInit(\n cfSandbox: CloudflareSandbox,\n path: string,\n body: Record<string, any> = {}\n): Promise<any> {\n if (!cfSandbox.remote || cfSandbox.remoteInitialized) {\n return workerRequest(cfSandbox, path, body);\n }\n\n const initEnvVars = cfSandbox.pendingEnvVars;\n const requestBody = initEnvVars && Object.keys(initEnvVars).length > 0\n ? { ...body, initEnvVars }\n : body;\n\n const data = await workerRequest(cfSandbox, path, requestBody);\n cfSandbox.pendingEnvVars = undefined;\n cfSandbox.remoteInitialized = true;\n return data;\n}\n\n/**\n * Escape a string for safe use inside double-quoted shell arguments.\n */\nfunction shellEscape(s: string): string {\n return s.replace(/[\"$`\\\\!]/g, '\\\\$&');\n}\n\n/**\n * Process code execution results into a CodeResult (shared by remote and direct modes)\n */\nfunction processExecution(execution: any, detectedRuntime: Runtime): CodeResult {\n const stdoutParts: string[] = [];\n const stderrParts: string[] = [];\n\n if (execution.logs) {\n if (execution.logs.stdout) stdoutParts.push(...execution.logs.stdout);\n if (execution.logs.stderr) stderrParts.push(...execution.logs.stderr);\n }\n if (execution.results && Array.isArray(execution.results)) {\n for (const res of execution.results) {\n if (res.text) stdoutParts.push(res.text);\n }\n }\n if (execution.error) {\n const errorMsg = execution.error.message || execution.error.name || 'Execution error';\n if (errorMsg.includes('SyntaxError') || errorMsg.includes('invalid syntax')) {\n throw new Error(`Syntax error: ${errorMsg}`);\n }\n stderrParts.push(errorMsg);\n }\n\n const stdout = stdoutParts.join('\\n');\n const stderr = stderrParts.join('\\n');\n\n return {\n output: stderr ? `${stdout}${stdout && stderr ? '\\n' : ''}${stderr}` : stdout,\n exitCode: execution.error ? 1 : 0,\n language: detectedRuntime\n };\n}\n\n/**\n * Parse ls -la output into FileEntry objects (used by both modes for readdir)\n */\nfunction parseLsOutput(stdout: string): FileEntry[] {\n const lines = stdout.split('\\n').filter((line: string) => line.trim() && !line.startsWith('total'));\n\n return lines.map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const permissions = parts[0] || '';\n const size = parseInt(parts[4]) || 0;\n const dateStr = (parts[5] || '') + ' ' + (parts[6] || '');\n const date = dateStr.trim() ? new Date(dateStr) : new Date();\n const name = parts.slice(8).join(' ') || parts[parts.length - 1] || 'unknown';\n\n return {\n name,\n type: permissions.startsWith('d') ? 'directory' as const : 'file' as const,\n size,\n modified: isNaN(date.getTime()) ? new Date() : date\n };\n });\n}\n\n// ─── Provider ────────────────────────────────────────────────────────────────\n\nexport const cloudflare = defineProvider<CloudflareSandbox, CloudflareConfig>({\n name: 'cloudflare',\n methods: {\n sandbox: {\n // ─── Collection operations ───────────────────────────────────────\n\n create: async (config: CloudflareConfig, options?: CreateSandboxOptions) => {\n // Destructure known ComputeSDK fields, collect the rest for passthrough\n const {\n runtime: _runtime,\n timeout: optTimeout,\n envs,\n name: _name,\n metadata: _metadata,\n templateId: _templateId,\n snapshotId: _snapshotId,\n sandboxId: optSandboxId,\n namespace: _namespace,\n directory: _directory,\n overlays: _overlays,\n servers: _servers,\n ports: _ports,\n ...rest\n } = options || {};\n\n const sandboxId = optSandboxId || createSandboxId();\n const envVars = { ...config.envVars, ...envs };\n // options.timeout takes precedence over config.timeout\n const timeout = optTimeout ?? config.timeout;\n const sleepAfter = timeout ? `${Math.ceil(timeout / 1000)}s` : undefined;\n\n // Remote mode\n if (isRemote(config)) {\n return {\n sandbox: {\n sandboxId,\n remote: true,\n sandboxUrl: config.sandboxUrl,\n sandboxSecret: config.sandboxSecret,\n pendingEnvVars: Object.keys(envVars).length > 0 ? envVars : undefined,\n remoteInitialized: false,\n exposedPorts: new Map(),\n },\n sandboxId\n };\n }\n\n // Direct mode\n if (!config.sandboxBinding) {\n throw new Error(\n 'Missing Cloudflare config. Either:\\n' +\n ' 1. Set CLOUDFLARE_SANDBOX_URL + CLOUDFLARE_SANDBOX_SECRET (remote mode)\\n' +\n ' 2. Provide sandboxBinding from your Workers environment (direct mode)\\n' +\n 'Run `npx @computesdk/cloudflare` to deploy a gateway Worker.'\n );\n }\n\n try {\n const sandboxOpts = { ...config.sandboxOptions };\n if (sleepAfter) {\n sandboxOpts.sleepAfter = sleepAfter;\n }\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId, sandboxOpts);\n\n if (Object.keys(envVars).length > 0) {\n await sandbox.setEnvVars(envVars);\n }\n\n return {\n sandbox: {\n sandbox,\n sandboxId,\n remote: false,\n exposedPorts: new Map(),\n },\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('binding')) {\n throw new Error(\n 'Cloudflare Sandbox binding failed. Ensure your Durable Object binding is properly configured in wrangler.toml. ' +\n 'See https://developers.cloudflare.com/sandbox/get-started/ for setup instructions.'\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error('Cloudflare resource limits exceeded. Check your usage at https://dash.cloudflare.com/');\n }\n }\n throw new Error(`Failed to create Cloudflare sandbox: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n getById: async (config: CloudflareConfig, sandboxId: string) => {\n // Remote mode\n if (isRemote(config)) {\n try {\n const cfSandbox: CloudflareSandbox = {\n sandboxId,\n remote: true,\n sandboxUrl: config.sandboxUrl,\n sandboxSecret: config.sandboxSecret,\n remoteInitialized: true,\n exposedPorts: new Map(),\n };\n // Verify sandbox is alive\n await workerRequest(cfSandbox, '/v1/sandbox/exec', { command: 'true' });\n return { sandbox: cfSandbox, sandboxId };\n } catch {\n return null;\n }\n }\n\n // Direct mode\n if (!config.sandboxBinding) return null;\n\n try {\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId, config.sandboxOptions);\n await sandbox.exec('true');\n return {\n sandbox: { sandbox, sandboxId, remote: false, exposedPorts: new Map() },\n sandboxId\n };\n } catch {\n return null;\n }\n },\n\n list: async (_config: CloudflareConfig) => {\n throw new Error(\n 'Cloudflare provider does not support listing sandboxes. ' +\n 'Durable Objects do not have a native list API. ' +\n 'Use getById to reconnect to specific sandboxes by ID.'\n );\n },\n\n destroy: async (config: CloudflareConfig, sandboxId: string) => {\n try {\n if (isRemote(config)) {\n await workerRequest(\n { sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: new Map() },\n '/v1/sandbox/destroy'\n );\n return;\n }\n\n if (config.sandboxBinding) {\n const sandbox = await getSandbox(config.sandboxBinding, sandboxId);\n await sandbox.destroy();\n }\n } catch {\n // Sandbox might already be destroyed\n }\n },\n\n // ─── Instance operations ─────────────────────────────────────────\n\n runCode: async (cfSandbox: CloudflareSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const detectedRuntime = runtime || detectRuntime(code);\n const language = runtimeToLanguage(detectedRuntime);\n\n // Remote mode\n if (cfSandbox.remote) {\n const execution = await workerRequestWithInit(cfSandbox, '/v1/sandbox/runCode', { code, language });\n return processExecution(execution, detectedRuntime);\n }\n\n // Direct mode\n try {\n const execution = await cfSandbox.sandbox.runCode(code, { language });\n return processExecution(execution, detectedRuntime);\n } catch (error) {\n if (error instanceof Error && error.message.includes('Syntax error')) throw error;\n throw new Error(`Cloudflare execution failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n runCommand: async (cfSandbox: CloudflareSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n // Remote mode\n if (cfSandbox.remote) {\n try {\n let fullCommand = command;\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const result = await workerRequestWithInit(cfSandbox, '/v1/sandbox/exec', {\n command: fullCommand,\n cwd: options?.cwd,\n env: options?.env,\n timeout: options?.timeout,\n });\n\n return {\n stdout: result.stdout || '',\n stderr: result.stderr || '',\n exitCode: result.exitCode,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n }\n\n // Direct mode\n try {\n let fullCommand = command;\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const execResult = await cfSandbox.sandbox.exec(fullCommand, {\n cwd: options?.cwd,\n env: options?.env,\n timeout: options?.timeout,\n });\n\n return {\n stdout: execResult.stdout || '',\n stderr: execResult.stderr || '',\n exitCode: execResult.exitCode,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime\n };\n }\n },\n\n getInfo: async (cfSandbox: CloudflareSandbox): Promise<SandboxInfo> => {\n try {\n if (cfSandbox.remote) {\n await workerRequestWithInit(cfSandbox, '/v1/sandbox/info');\n } else {\n await cfSandbox.sandbox.exec('true');\n }\n\n return {\n id: cfSandbox.sandboxId,\n provider: 'cloudflare',\n runtime: 'python',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cloudflareSandboxId: cfSandbox.sandboxId,\n mode: cfSandbox.remote ? 'remote' : 'direct',\n }\n };\n } catch (error) {\n return {\n id: cfSandbox.sandboxId,\n provider: 'cloudflare',\n runtime: 'python',\n status: 'error',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n cloudflareSandboxId: cfSandbox.sandboxId,\n mode: cfSandbox.remote ? 'remote' : 'direct',\n error: error instanceof Error ? error.message : String(error)\n }\n };\n }\n },\n\n getUrl: async (cfSandbox: CloudflareSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const { port, protocol = 'https' } = options;\n\n if (cfSandbox.exposedPorts.has(port)) {\n return cfSandbox.exposedPorts.get(port)!;\n }\n\n let preview: any;\n if (cfSandbox.remote) {\n preview = await workerRequestWithInit(cfSandbox, '/v1/sandbox/exposePort', { port, options: {} });\n } else {\n preview = await cfSandbox.sandbox.exposePort(port, {});\n }\n\n const url = `${protocol}://${preview.url}`;\n cfSandbox.exposedPorts.set(port, url);\n return url;\n },\n\n // ─── Filesystem ────────────────────────────────────────────────\n\n filesystem: {\n readFile: async (cfSandbox: CloudflareSandbox, path: string): Promise<string> => {\n if (cfSandbox.remote) {\n const file = await workerRequestWithInit(cfSandbox, '/v1/sandbox/readFile', { path });\n return file.content || '';\n }\n const file = await cfSandbox.sandbox.readFile(path);\n return file.content || '';\n },\n\n writeFile: async (cfSandbox: CloudflareSandbox, path: string, content: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequestWithInit(cfSandbox, '/v1/sandbox/writeFile', { path, content });\n return;\n }\n await cfSandbox.sandbox.writeFile(path, content);\n },\n\n mkdir: async (cfSandbox: CloudflareSandbox, path: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequestWithInit(cfSandbox, '/v1/sandbox/mkdir', { path });\n return;\n }\n await cfSandbox.sandbox.mkdir(path, { recursive: true });\n },\n\n readdir: async (cfSandbox: CloudflareSandbox, path: string): Promise<FileEntry[]> => {\n // Both modes use ls -la since there's no native readdir\n let result: any;\n if (cfSandbox.remote) {\n result = await workerRequestWithInit(cfSandbox, '/v1/sandbox/exec', {\n command: `ls -la \"${shellEscape(path)}\"`,\n cwd: '/',\n });\n } else {\n result = await cfSandbox.sandbox.exec(`ls -la \"${shellEscape(path)}\"`, { cwd: '/' });\n }\n\n if (result.exitCode !== 0) {\n throw new Error(`Directory listing failed: ${result.stderr}`);\n }\n\n return parseLsOutput(result.stdout);\n },\n\n exists: async (cfSandbox: CloudflareSandbox, path: string): Promise<boolean> => {\n if (cfSandbox.remote) {\n const result = await workerRequestWithInit(cfSandbox, '/v1/sandbox/exists', { path });\n return result.exists;\n }\n const result = await cfSandbox.sandbox.exists(path);\n return result.exists;\n },\n\n remove: async (cfSandbox: CloudflareSandbox, path: string): Promise<void> => {\n if (cfSandbox.remote) {\n await workerRequestWithInit(cfSandbox, '/v1/sandbox/deleteFile', { path });\n return;\n }\n await cfSandbox.sandbox.deleteFile(path);\n }\n }\n }\n }\n});"],"mappings":"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","names":["file","result"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@computesdk/cloudflare",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Cloudflare provider for ComputeSDK - edge code execution using Cloudflare Workers and Durable Objects",
|
|
5
5
|
"author": "Garrison",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"src/worker"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@cloudflare/sandbox": "^0.7.
|
|
26
|
-
"computesdk": "
|
|
27
|
-
"
|
|
25
|
+
"@cloudflare/sandbox": "^0.7.18",
|
|
26
|
+
"@computesdk/provider": "1.0.31",
|
|
27
|
+
"computesdk": "2.5.1"
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
30
|
"computesdk",
|
package/src/worker/Dockerfile
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
FROM docker.io/cloudflare/sandbox:0.7.
|
|
1
|
+
FROM docker.io/cloudflare/sandbox:0.7.18
|
package/src/worker/index.ts
CHANGED
|
@@ -50,12 +50,14 @@ export default {
|
|
|
50
50
|
try {
|
|
51
51
|
const sandbox = getSandbox(env.Sandbox, sandboxId);
|
|
52
52
|
|
|
53
|
+
if (body.initEnvVars) {
|
|
54
|
+
await sandbox.setEnvVars(body.initEnvVars);
|
|
55
|
+
}
|
|
56
|
+
|
|
53
57
|
// --- Sandbox lifecycle ---
|
|
54
58
|
|
|
55
59
|
if (url.pathname === '/v1/sandbox/create') {
|
|
56
60
|
if (body.envVars) await sandbox.setEnvVars(body.envVars);
|
|
57
|
-
// Trigger lazy container start
|
|
58
|
-
await sandbox.exec('true');
|
|
59
61
|
return Response.json({ sandboxId, status: 'running' });
|
|
60
62
|
}
|
|
61
63
|
|
|
@@ -139,4 +141,4 @@ export default {
|
|
|
139
141
|
return Response.json({ error: message }, { status: 500 });
|
|
140
142
|
}
|
|
141
143
|
},
|
|
142
|
-
};
|
|
144
|
+
};
|
package/src/worker/package.json
CHANGED