@computesdk/cloudflare 1.5.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +25 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +25 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -142,13 +142,35 @@ var cloudflare = (0, import_provider.defineProvider)({
|
|
|
142
142
|
sandbox: {
|
|
143
143
|
// ─── Collection operations ───────────────────────────────────────
|
|
144
144
|
create: async (config, options) => {
|
|
145
|
-
const
|
|
146
|
-
|
|
145
|
+
const {
|
|
146
|
+
runtime: _runtime,
|
|
147
|
+
timeout: optTimeout,
|
|
148
|
+
envs,
|
|
149
|
+
name: _name,
|
|
150
|
+
metadata: _metadata,
|
|
151
|
+
templateId: _templateId,
|
|
152
|
+
snapshotId: _snapshotId,
|
|
153
|
+
sandboxId: optSandboxId,
|
|
154
|
+
namespace: _namespace,
|
|
155
|
+
directory: _directory,
|
|
156
|
+
overlays: _overlays,
|
|
157
|
+
servers: _servers,
|
|
158
|
+
ports: _ports,
|
|
159
|
+
...rest
|
|
160
|
+
} = options || {};
|
|
161
|
+
const sandboxId = optSandboxId || `cf-sandbox-${Date.now()}`;
|
|
162
|
+
const envVars = { ...config.envVars, ...envs };
|
|
163
|
+
const timeout = optTimeout ?? config.timeout;
|
|
147
164
|
if (isRemote(config)) {
|
|
148
165
|
await workerRequest(
|
|
149
166
|
{ sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: /* @__PURE__ */ new Map() },
|
|
150
167
|
"/v1/sandbox/create",
|
|
151
|
-
{
|
|
168
|
+
{
|
|
169
|
+
envVars: Object.keys(envVars).length > 0 ? envVars : void 0,
|
|
170
|
+
...timeout ? { timeout } : {},
|
|
171
|
+
...rest
|
|
172
|
+
// Pass through provider-specific options
|
|
173
|
+
}
|
|
152
174
|
);
|
|
153
175
|
return {
|
|
154
176
|
sandbox: {
|
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 // 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"]}
|
package/dist/index.mjs
CHANGED
|
@@ -108,13 +108,35 @@ var cloudflare = defineProvider({
|
|
|
108
108
|
sandbox: {
|
|
109
109
|
// ─── Collection operations ───────────────────────────────────────
|
|
110
110
|
create: async (config, options) => {
|
|
111
|
-
const
|
|
112
|
-
|
|
111
|
+
const {
|
|
112
|
+
runtime: _runtime,
|
|
113
|
+
timeout: optTimeout,
|
|
114
|
+
envs,
|
|
115
|
+
name: _name,
|
|
116
|
+
metadata: _metadata,
|
|
117
|
+
templateId: _templateId,
|
|
118
|
+
snapshotId: _snapshotId,
|
|
119
|
+
sandboxId: optSandboxId,
|
|
120
|
+
namespace: _namespace,
|
|
121
|
+
directory: _directory,
|
|
122
|
+
overlays: _overlays,
|
|
123
|
+
servers: _servers,
|
|
124
|
+
ports: _ports,
|
|
125
|
+
...rest
|
|
126
|
+
} = options || {};
|
|
127
|
+
const sandboxId = optSandboxId || `cf-sandbox-${Date.now()}`;
|
|
128
|
+
const envVars = { ...config.envVars, ...envs };
|
|
129
|
+
const timeout = optTimeout ?? config.timeout;
|
|
113
130
|
if (isRemote(config)) {
|
|
114
131
|
await workerRequest(
|
|
115
132
|
{ sandboxId, remote: true, sandboxUrl: config.sandboxUrl, sandboxSecret: config.sandboxSecret, exposedPorts: /* @__PURE__ */ new Map() },
|
|
116
133
|
"/v1/sandbox/create",
|
|
117
|
-
{
|
|
134
|
+
{
|
|
135
|
+
envVars: Object.keys(envVars).length > 0 ? envVars : void 0,
|
|
136
|
+
...timeout ? { timeout } : {},
|
|
137
|
+
...rest
|
|
138
|
+
// Pass through provider-specific options
|
|
139
|
+
}
|
|
118
140
|
);
|
|
119
141
|
return {
|
|
120
142
|
sandbox: {
|
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 // 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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@computesdk/cloudflare",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Cloudflare provider for ComputeSDK - edge code execution using Cloudflare Workers and Durable Objects",
|
|
5
5
|
"author": "Garrison",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@cloudflare/sandbox": "^0.7.0",
|
|
26
|
-
"
|
|
27
|
-
"computesdk": "
|
|
26
|
+
"computesdk": "2.5.1",
|
|
27
|
+
"@computesdk/provider": "1.0.31"
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
30
|
"computesdk",
|