@computesdk/cloudflare 1.5.0 → 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 +52 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +52 -18
- 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
|
}
|
|
@@ -142,20 +156,35 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
142
156
|
sandbox: {
|
|
143
157
|
// ─── Collection operations ───────────────────────────────────────
|
|
144
158
|
create: async (config, options) => {
|
|
145
|
-
const
|
|
146
|
-
|
|
159
|
+
const {
|
|
160
|
+
runtime: _runtime,
|
|
161
|
+
timeout: optTimeout,
|
|
162
|
+
envs,
|
|
163
|
+
name: _name,
|
|
164
|
+
metadata: _metadata,
|
|
165
|
+
templateId: _templateId,
|
|
166
|
+
snapshotId: _snapshotId,
|
|
167
|
+
sandboxId: optSandboxId,
|
|
168
|
+
namespace: _namespace,
|
|
169
|
+
directory: _directory,
|
|
170
|
+
overlays: _overlays,
|
|
171
|
+
servers: _servers,
|
|
172
|
+
ports: _ports,
|
|
173
|
+
...rest
|
|
174
|
+
} = options || {};
|
|
175
|
+
const sandboxId = optSandboxId || createSandboxId();
|
|
176
|
+
const envVars = { ...config.envVars, ...envs };
|
|
177
|
+
const timeout = optTimeout ?? config.timeout;
|
|
178
|
+
const sleepAfter = timeout ? `${Math.ceil(timeout / 1e3)}s` : void 0;
|
|
147
179
|
if (isRemote(config)) {
|
|
148
|
-
await workerRequest(
|
|
149
|
-
{ sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: /* @__PURE__ */ new Map() },
|
|
150
|
-
"/v1/sandbox/create",
|
|
151
|
-
{ envVars: Object.keys(envVars).length > 0 ? envVars : void 0 }
|
|
152
|
-
);
|
|
153
180
|
return {
|
|
154
181
|
sandbox: {
|
|
155
182
|
sandboxId,
|
|
156
183
|
remote: true,
|
|
157
184
|
sandboxUrl: config.sandboxUrl,
|
|
158
185
|
sandboxSecret: config.sandboxSecret,
|
|
186
|
+
pendingEnvVars: Object.keys(envVars).length > 0 ? envVars : void 0,
|
|
187
|
+
remoteInitialized: false,
|
|
159
188
|
exposedPorts: /* @__PURE__ */ new Map()
|
|
160
189
|
},
|
|
161
190
|
sandboxId
|
|
@@ -167,7 +196,11 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
167
196
|
);
|
|
168
197
|
}
|
|
169
198
|
try {
|
|
170
|
-
const
|
|
199
|
+
const sandboxOpts = { ...config.sandboxOptions };
|
|
200
|
+
if (sleepAfter) {
|
|
201
|
+
sandboxOpts.sleepAfter = sleepAfter;
|
|
202
|
+
}
|
|
203
|
+
const sandbox = await getSandbox(config.sandboxBinding, sandboxId, sandboxOpts);
|
|
171
204
|
if (Object.keys(envVars).length > 0) {
|
|
172
205
|
await sandbox.setEnvVars(envVars);
|
|
173
206
|
}
|
|
@@ -202,6 +235,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
202
235
|
remote: true,
|
|
203
236
|
sandboxUrl: config.sandboxUrl,
|
|
204
237
|
sandboxSecret: config.sandboxSecret,
|
|
238
|
+
remoteInitialized: true,
|
|
205
239
|
exposedPorts: /* @__PURE__ */ new Map()
|
|
206
240
|
};
|
|
207
241
|
await workerRequest(cfSandbox, "/v1/sandbox/exec", { command: "true" });
|
|
@@ -248,7 +282,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
248
282
|
const detectedRuntime = runtime || detectRuntime(code);
|
|
249
283
|
const language = runtimeToLanguage(detectedRuntime);
|
|
250
284
|
if (cfSandbox.remote) {
|
|
251
|
-
const execution = await
|
|
285
|
+
const execution = await workerRequestWithInit(cfSandbox, "/v1/sandbox/runCode", { code, language });
|
|
252
286
|
return processExecution(execution, detectedRuntime);
|
|
253
287
|
}
|
|
254
288
|
try {
|
|
@@ -267,7 +301,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
267
301
|
if (options?.background) {
|
|
268
302
|
fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
269
303
|
}
|
|
270
|
-
const result = await
|
|
304
|
+
const result = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exec", {
|
|
271
305
|
command: fullCommand,
|
|
272
306
|
cwd: options?.cwd,
|
|
273
307
|
env: options?.env,
|
|
@@ -316,7 +350,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
316
350
|
getInfo: async (cfSandbox) => {
|
|
317
351
|
try {
|
|
318
352
|
if (cfSandbox.remote) {
|
|
319
|
-
await
|
|
353
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/info");
|
|
320
354
|
} else {
|
|
321
355
|
await cfSandbox.sandbox.exec("true");
|
|
322
356
|
}
|
|
@@ -355,7 +389,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
355
389
|
}
|
|
356
390
|
let preview;
|
|
357
391
|
if (cfSandbox.remote) {
|
|
358
|
-
preview = await
|
|
392
|
+
preview = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exposePort", { port, options: {} });
|
|
359
393
|
} else {
|
|
360
394
|
preview = await cfSandbox.sandbox.exposePort(port, {});
|
|
361
395
|
}
|
|
@@ -367,7 +401,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
367
401
|
filesystem: {
|
|
368
402
|
readFile: async (cfSandbox, path) => {
|
|
369
403
|
if (cfSandbox.remote) {
|
|
370
|
-
const file2 = await
|
|
404
|
+
const file2 = await workerRequestWithInit(cfSandbox, "/v1/sandbox/readFile", { path });
|
|
371
405
|
return file2.content || "";
|
|
372
406
|
}
|
|
373
407
|
const file = await cfSandbox.sandbox.readFile(path);
|
|
@@ -375,14 +409,14 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
375
409
|
},
|
|
376
410
|
writeFile: async (cfSandbox, path, content) => {
|
|
377
411
|
if (cfSandbox.remote) {
|
|
378
|
-
await
|
|
412
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/writeFile", { path, content });
|
|
379
413
|
return;
|
|
380
414
|
}
|
|
381
415
|
await cfSandbox.sandbox.writeFile(path, content);
|
|
382
416
|
},
|
|
383
417
|
mkdir: async (cfSandbox, path) => {
|
|
384
418
|
if (cfSandbox.remote) {
|
|
385
|
-
await
|
|
419
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/mkdir", { path });
|
|
386
420
|
return;
|
|
387
421
|
}
|
|
388
422
|
await cfSandbox.sandbox.mkdir(path, { recursive: true });
|
|
@@ -390,7 +424,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
390
424
|
readdir: async (cfSandbox, path) => {
|
|
391
425
|
let result;
|
|
392
426
|
if (cfSandbox.remote) {
|
|
393
|
-
result = await
|
|
427
|
+
result = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exec", {
|
|
394
428
|
command: `ls -la "${shellEscape(path)}"`,
|
|
395
429
|
cwd: "/"
|
|
396
430
|
});
|
|
@@ -404,7 +438,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
404
438
|
},
|
|
405
439
|
exists: async (cfSandbox, path) => {
|
|
406
440
|
if (cfSandbox.remote) {
|
|
407
|
-
const result2 = await
|
|
441
|
+
const result2 = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exists", { path });
|
|
408
442
|
return result2.exists;
|
|
409
443
|
}
|
|
410
444
|
const result = await cfSandbox.sandbox.exists(path);
|
|
@@ -412,7 +446,7 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
412
446
|
},
|
|
413
447
|
remove: async (cfSandbox, path) => {
|
|
414
448
|
if (cfSandbox.remote) {
|
|
415
|
-
await
|
|
449
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/deleteFile", { path });
|
|
416
450
|
return;
|
|
417
451
|
}
|
|
418
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 const sandboxId = options?.sandboxId || `cf-sandbox-${Date.now()}`;\n const envVars = { ...config.envVars, ...options?.envs };\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 { envVars: Object.keys(envVars).length > 0 ? envVars : undefined }\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
|
}
|
|
@@ -108,20 +122,35 @@ var cloudflare = defineProvider({
|
|
|
108
122
|
sandbox: {
|
|
109
123
|
// ─── Collection operations ───────────────────────────────────────
|
|
110
124
|
create: async (config, options) => {
|
|
111
|
-
const
|
|
112
|
-
|
|
125
|
+
const {
|
|
126
|
+
runtime: _runtime,
|
|
127
|
+
timeout: optTimeout,
|
|
128
|
+
envs,
|
|
129
|
+
name: _name,
|
|
130
|
+
metadata: _metadata,
|
|
131
|
+
templateId: _templateId,
|
|
132
|
+
snapshotId: _snapshotId,
|
|
133
|
+
sandboxId: optSandboxId,
|
|
134
|
+
namespace: _namespace,
|
|
135
|
+
directory: _directory,
|
|
136
|
+
overlays: _overlays,
|
|
137
|
+
servers: _servers,
|
|
138
|
+
ports: _ports,
|
|
139
|
+
...rest
|
|
140
|
+
} = options || {};
|
|
141
|
+
const sandboxId = optSandboxId || createSandboxId();
|
|
142
|
+
const envVars = { ...config.envVars, ...envs };
|
|
143
|
+
const timeout = optTimeout ?? config.timeout;
|
|
144
|
+
const sleepAfter = timeout ? `${Math.ceil(timeout / 1e3)}s` : void 0;
|
|
113
145
|
if (isRemote(config)) {
|
|
114
|
-
await workerRequest(
|
|
115
|
-
{ sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: /* @__PURE__ */ new Map() },
|
|
116
|
-
"/v1/sandbox/create",
|
|
117
|
-
{ envVars: Object.keys(envVars).length > 0 ? envVars : void 0 }
|
|
118
|
-
);
|
|
119
146
|
return {
|
|
120
147
|
sandbox: {
|
|
121
148
|
sandboxId,
|
|
122
149
|
remote: true,
|
|
123
150
|
sandboxUrl: config.sandboxUrl,
|
|
124
151
|
sandboxSecret: config.sandboxSecret,
|
|
152
|
+
pendingEnvVars: Object.keys(envVars).length > 0 ? envVars : void 0,
|
|
153
|
+
remoteInitialized: false,
|
|
125
154
|
exposedPorts: /* @__PURE__ */ new Map()
|
|
126
155
|
},
|
|
127
156
|
sandboxId
|
|
@@ -133,7 +162,11 @@ var cloudflare = defineProvider({
|
|
|
133
162
|
);
|
|
134
163
|
}
|
|
135
164
|
try {
|
|
136
|
-
const
|
|
165
|
+
const sandboxOpts = { ...config.sandboxOptions };
|
|
166
|
+
if (sleepAfter) {
|
|
167
|
+
sandboxOpts.sleepAfter = sleepAfter;
|
|
168
|
+
}
|
|
169
|
+
const sandbox = await getSandbox(config.sandboxBinding, sandboxId, sandboxOpts);
|
|
137
170
|
if (Object.keys(envVars).length > 0) {
|
|
138
171
|
await sandbox.setEnvVars(envVars);
|
|
139
172
|
}
|
|
@@ -168,6 +201,7 @@ var cloudflare = defineProvider({
|
|
|
168
201
|
remote: true,
|
|
169
202
|
sandboxUrl: config.sandboxUrl,
|
|
170
203
|
sandboxSecret: config.sandboxSecret,
|
|
204
|
+
remoteInitialized: true,
|
|
171
205
|
exposedPorts: /* @__PURE__ */ new Map()
|
|
172
206
|
};
|
|
173
207
|
await workerRequest(cfSandbox, "/v1/sandbox/exec", { command: "true" });
|
|
@@ -214,7 +248,7 @@ var cloudflare = defineProvider({
|
|
|
214
248
|
const detectedRuntime = runtime || detectRuntime(code);
|
|
215
249
|
const language = runtimeToLanguage(detectedRuntime);
|
|
216
250
|
if (cfSandbox.remote) {
|
|
217
|
-
const execution = await
|
|
251
|
+
const execution = await workerRequestWithInit(cfSandbox, "/v1/sandbox/runCode", { code, language });
|
|
218
252
|
return processExecution(execution, detectedRuntime);
|
|
219
253
|
}
|
|
220
254
|
try {
|
|
@@ -233,7 +267,7 @@ var cloudflare = defineProvider({
|
|
|
233
267
|
if (options?.background) {
|
|
234
268
|
fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
235
269
|
}
|
|
236
|
-
const result = await
|
|
270
|
+
const result = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exec", {
|
|
237
271
|
command: fullCommand,
|
|
238
272
|
cwd: options?.cwd,
|
|
239
273
|
env: options?.env,
|
|
@@ -282,7 +316,7 @@ var cloudflare = defineProvider({
|
|
|
282
316
|
getInfo: async (cfSandbox) => {
|
|
283
317
|
try {
|
|
284
318
|
if (cfSandbox.remote) {
|
|
285
|
-
await
|
|
319
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/info");
|
|
286
320
|
} else {
|
|
287
321
|
await cfSandbox.sandbox.exec("true");
|
|
288
322
|
}
|
|
@@ -321,7 +355,7 @@ var cloudflare = defineProvider({
|
|
|
321
355
|
}
|
|
322
356
|
let preview;
|
|
323
357
|
if (cfSandbox.remote) {
|
|
324
|
-
preview = await
|
|
358
|
+
preview = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exposePort", { port, options: {} });
|
|
325
359
|
} else {
|
|
326
360
|
preview = await cfSandbox.sandbox.exposePort(port, {});
|
|
327
361
|
}
|
|
@@ -333,7 +367,7 @@ var cloudflare = defineProvider({
|
|
|
333
367
|
filesystem: {
|
|
334
368
|
readFile: async (cfSandbox, path) => {
|
|
335
369
|
if (cfSandbox.remote) {
|
|
336
|
-
const file2 = await
|
|
370
|
+
const file2 = await workerRequestWithInit(cfSandbox, "/v1/sandbox/readFile", { path });
|
|
337
371
|
return file2.content || "";
|
|
338
372
|
}
|
|
339
373
|
const file = await cfSandbox.sandbox.readFile(path);
|
|
@@ -341,14 +375,14 @@ var cloudflare = defineProvider({
|
|
|
341
375
|
},
|
|
342
376
|
writeFile: async (cfSandbox, path, content) => {
|
|
343
377
|
if (cfSandbox.remote) {
|
|
344
|
-
await
|
|
378
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/writeFile", { path, content });
|
|
345
379
|
return;
|
|
346
380
|
}
|
|
347
381
|
await cfSandbox.sandbox.writeFile(path, content);
|
|
348
382
|
},
|
|
349
383
|
mkdir: async (cfSandbox, path) => {
|
|
350
384
|
if (cfSandbox.remote) {
|
|
351
|
-
await
|
|
385
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/mkdir", { path });
|
|
352
386
|
return;
|
|
353
387
|
}
|
|
354
388
|
await cfSandbox.sandbox.mkdir(path, { recursive: true });
|
|
@@ -356,7 +390,7 @@ var cloudflare = defineProvider({
|
|
|
356
390
|
readdir: async (cfSandbox, path) => {
|
|
357
391
|
let result;
|
|
358
392
|
if (cfSandbox.remote) {
|
|
359
|
-
result = await
|
|
393
|
+
result = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exec", {
|
|
360
394
|
command: `ls -la "${shellEscape(path)}"`,
|
|
361
395
|
cwd: "/"
|
|
362
396
|
});
|
|
@@ -370,7 +404,7 @@ var cloudflare = defineProvider({
|
|
|
370
404
|
},
|
|
371
405
|
exists: async (cfSandbox, path) => {
|
|
372
406
|
if (cfSandbox.remote) {
|
|
373
|
-
const result2 = await
|
|
407
|
+
const result2 = await workerRequestWithInit(cfSandbox, "/v1/sandbox/exists", { path });
|
|
374
408
|
return result2.exists;
|
|
375
409
|
}
|
|
376
410
|
const result = await cfSandbox.sandbox.exists(path);
|
|
@@ -378,7 +412,7 @@ var cloudflare = defineProvider({
|
|
|
378
412
|
},
|
|
379
413
|
remove: async (cfSandbox, path) => {
|
|
380
414
|
if (cfSandbox.remote) {
|
|
381
|
-
await
|
|
415
|
+
await workerRequestWithInit(cfSandbox, "/v1/sandbox/deleteFile", { path });
|
|
382
416
|
return;
|
|
383
417
|
}
|
|
384
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 const sandboxId = options?.sandboxId || `cf-sandbox-${Date.now()}`;\n const envVars = { ...config.envVars, ...options?.envs };\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 { envVars: Object.keys(envVars).length > 0 ? envVars : undefined }\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/provider": "1.0.
|
|
27
|
-
"computesdk": "2.
|
|
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