@computesdk/e2b 1.6.7 → 1.7.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/README.md CHANGED
@@ -31,7 +31,7 @@ const compute = createCompute({
31
31
  });
32
32
 
33
33
  // Create sandbox
34
- const sandbox = await compute.sandbox.create({});
34
+ const sandbox = await compute.sandbox.create();
35
35
 
36
36
  // Execute Python code
37
37
  const result = await sandbox.runCode(`
@@ -258,7 +258,7 @@ export async function POST(request: Request) {
258
258
  ### Data Science Workflow
259
259
 
260
260
  ```typescript
261
- const sandbox = await compute.sandbox.create({});
261
+ const sandbox = await compute.sandbox.create();
262
262
 
263
263
  // Create project structure
264
264
  await sandbox.filesystem.mkdir('/analysis');
@@ -324,7 +324,7 @@ console.log('Chart created:', chartExists);
324
324
  ### Interactive Terminal Session
325
325
 
326
326
  ```typescript
327
- const sandbox = await compute.sandbox.create({});
327
+ const sandbox = await compute.sandbox.create();
328
328
 
329
329
  // Create interactive Python terminal
330
330
  const terminal = await sandbox.terminal.create({
package/dist/index.d.mts CHANGED
@@ -19,38 +19,4 @@ interface E2BConfig {
19
19
  */
20
20
  declare const e2b: (config: E2BConfig) => computesdk.Provider<Sandbox, any, any>;
21
21
 
22
- /**
23
- * Create a properly typed compute instance for E2B
24
- * This version provides full type safety for getInstance() calls
25
- *
26
- * @example
27
- * ```typescript
28
- * import { createE2BCompute } from '@computesdk/e2b'
29
- *
30
- * const compute = createE2BCompute({ apiKey: 'your-key' });
31
- * const sandbox = await compute.sandbox.create();
32
- * const instance = sandbox.getInstance(); // ✅ Properly typed as E2B Sandbox!
33
- * ```
34
- */
35
- declare function createE2BCompute(config: E2BConfig): {
36
- sandbox: {
37
- create(): Promise<{
38
- sandboxId: string;
39
- provider: string;
40
- runCode(code: string, runtime?: computesdk.Runtime): Promise<computesdk.ExecutionResult>;
41
- runCommand(command: string, args?: string[]): Promise<computesdk.ExecutionResult>;
42
- getInfo(): Promise<computesdk.SandboxInfo>;
43
- getUrl(options: {
44
- port: number;
45
- protocol?: string;
46
- }): Promise<string>;
47
- getProvider(): ReturnType<typeof e2b>;
48
- getInstance(): Sandbox;
49
- kill(): Promise<void>;
50
- destroy(): Promise<void>;
51
- filesystem: computesdk.SandboxFileSystem;
52
- }>;
53
- };
54
- };
55
-
56
- export { type E2BConfig, createE2BCompute, e2b };
22
+ export { type E2BConfig, e2b };
package/dist/index.d.ts CHANGED
@@ -19,38 +19,4 @@ interface E2BConfig {
19
19
  */
20
20
  declare const e2b: (config: E2BConfig) => computesdk.Provider<Sandbox, any, any>;
21
21
 
22
- /**
23
- * Create a properly typed compute instance for E2B
24
- * This version provides full type safety for getInstance() calls
25
- *
26
- * @example
27
- * ```typescript
28
- * import { createE2BCompute } from '@computesdk/e2b'
29
- *
30
- * const compute = createE2BCompute({ apiKey: 'your-key' });
31
- * const sandbox = await compute.sandbox.create();
32
- * const instance = sandbox.getInstance(); // ✅ Properly typed as E2B Sandbox!
33
- * ```
34
- */
35
- declare function createE2BCompute(config: E2BConfig): {
36
- sandbox: {
37
- create(): Promise<{
38
- sandboxId: string;
39
- provider: string;
40
- runCode(code: string, runtime?: computesdk.Runtime): Promise<computesdk.ExecutionResult>;
41
- runCommand(command: string, args?: string[]): Promise<computesdk.ExecutionResult>;
42
- getInfo(): Promise<computesdk.SandboxInfo>;
43
- getUrl(options: {
44
- port: number;
45
- protocol?: string;
46
- }): Promise<string>;
47
- getProvider(): ReturnType<typeof e2b>;
48
- getInstance(): Sandbox;
49
- kill(): Promise<void>;
50
- destroy(): Promise<void>;
51
- filesystem: computesdk.SandboxFileSystem;
52
- }>;
53
- };
54
- };
55
-
56
- export { type E2BConfig, createE2BCompute, e2b };
22
+ export { type E2BConfig, e2b };
package/dist/index.js CHANGED
@@ -20,7 +20,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- createE2BCompute: () => createE2BCompute,
24
23
  e2b: () => e2b
25
24
  });
26
25
  module.exports = __toCommonJS(index_exports);
@@ -28,6 +27,7 @@ var import_e2b = require("e2b");
28
27
  var import_computesdk = require("computesdk");
29
28
  var e2b = (0, import_computesdk.createProvider)({
30
29
  name: "e2b",
30
+ defaultMode: "direct",
31
31
  methods: {
32
32
  sandbox: {
33
33
  // Collection operations (map to compute.sandbox.*)
@@ -58,13 +58,15 @@ var e2b = (0, import_computesdk.createProvider)({
58
58
  sandbox = await import_e2b.Sandbox.create(options.templateId, {
59
59
  apiKey,
60
60
  timeoutMs: timeout,
61
- domain: options.domain
61
+ domain: options?.domain,
62
+ envs: options?.envs
62
63
  });
63
64
  } else {
64
65
  sandbox = await import_e2b.Sandbox.create({
65
66
  apiKey,
66
67
  timeoutMs: timeout,
67
- domain: options?.domain
68
+ domain: options?.domain,
69
+ envs: options?.envs
68
70
  });
69
71
  }
70
72
  sandboxId = sandbox.sandboxId || `e2b-${Date.now()}`;
@@ -132,47 +134,34 @@ var e2b = (0, import_computesdk.createProvider)({
132
134
  },
133
135
  // Instance operations (map to individual Sandbox methods)
134
136
  runCode: async (sandbox, code, runtime) => {
135
- const startTime = Date.now();
136
137
  try {
137
138
  const effectiveRuntime = runtime || // Strong Python indicators
138
139
  (code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") || code.includes("raise ") ? "python" : "node");
139
- let result;
140
140
  const encoded = Buffer.from(code).toString("base64");
141
- if (effectiveRuntime === "python") {
142
- result = await sandbox.commands.run(`echo "${encoded}" | base64 -d | python3`);
143
- } else {
144
- result = await sandbox.commands.run(`echo "${encoded}" | base64 -d | node`);
145
- }
141
+ const result = effectiveRuntime === "python" ? await sandbox.commands.run(`echo "${encoded}" | base64 -d | python3`) : await sandbox.commands.run(`echo "${encoded}" | base64 -d | node`);
146
142
  if (result.exitCode !== 0 && result.stderr) {
147
143
  if (result.stderr.includes("SyntaxError") || result.stderr.includes("invalid syntax") || result.stderr.includes("Unexpected token") || result.stderr.includes("Unexpected identifier")) {
148
144
  throw new Error(`Syntax error: ${result.stderr.trim()}`);
149
145
  }
150
146
  }
147
+ const output = result.stderr ? `${result.stdout}${result.stdout && result.stderr ? "\n" : ""}${result.stderr}` : result.stdout;
151
148
  return {
152
- stdout: result.stdout,
153
- stderr: result.stderr,
149
+ output,
154
150
  exitCode: result.exitCode,
155
- executionTime: Date.now() - startTime,
156
- sandboxId: sandbox.sandboxId || "e2b-unknown",
157
- provider: "e2b"
151
+ language: effectiveRuntime
158
152
  };
159
153
  } catch (error) {
160
154
  if (error instanceof Error && error.message === "exit status 1") {
161
155
  const actualStderr = error?.result?.stderr || "";
162
- const isSyntaxError = actualStderr.includes("SyntaxError");
163
- if (isSyntaxError) {
156
+ if (actualStderr.includes("SyntaxError")) {
164
157
  const syntaxErrorLine = actualStderr.split("\n").find((line) => line.includes("SyntaxError")) || "SyntaxError: Invalid syntax in code";
165
158
  throw new Error(`Syntax error: ${syntaxErrorLine}`);
166
- } else {
167
- return {
168
- stdout: "",
169
- stderr: actualStderr || "Error: Runtime error occurred during execution",
170
- exitCode: 1,
171
- executionTime: Date.now() - startTime,
172
- sandboxId: sandbox.sandboxId || "e2b-unknown",
173
- provider: "e2b"
174
- };
175
159
  }
160
+ return {
161
+ output: actualStderr || "Error: Runtime error occurred during execution",
162
+ exitCode: 1,
163
+ language: runtime || "node"
164
+ };
176
165
  }
177
166
  if (error instanceof Error && error.message.includes("Syntax error")) {
178
167
  throw error;
@@ -182,38 +171,38 @@ var e2b = (0, import_computesdk.createProvider)({
182
171
  );
183
172
  }
184
173
  },
185
- runCommand: async (sandbox, command, args = [], options) => {
174
+ runCommand: async (sandbox, command, args = []) => {
186
175
  const startTime = Date.now();
187
176
  try {
188
- const { command: finalCommand, args: finalArgs, isBackground } = (0, import_computesdk.createBackgroundCommand)(command, args, options);
189
- const quotedArgs = finalArgs.map((arg) => {
177
+ const quotedArgs = args.map((arg) => {
190
178
  if (arg.includes(" ") || arg.includes('"') || arg.includes("'") || arg.includes("$") || arg.includes("`")) {
191
179
  return `"${arg.replace(/"/g, '\\"')}"`;
192
180
  }
193
181
  return arg;
194
182
  });
195
- const fullCommand = quotedArgs.length > 0 ? `${finalCommand} ${quotedArgs.join(" ")}` : finalCommand;
183
+ const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(" ")}` : command;
196
184
  const execution = await sandbox.commands.run(fullCommand);
197
185
  return {
198
186
  stdout: execution.stdout,
199
187
  stderr: execution.stderr,
200
188
  exitCode: execution.exitCode,
201
- executionTime: Date.now() - startTime,
202
- sandboxId: sandbox.sandboxId || "e2b-unknown",
203
- provider: "e2b",
204
- isBackground,
205
- // For background commands, we can't get a real PID, but we can indicate it's running
206
- ...isBackground && { pid: -1 }
189
+ durationMs: Date.now() - startTime
207
190
  };
208
191
  } catch (error) {
192
+ const result = error?.result;
193
+ if (result) {
194
+ return {
195
+ stdout: result.stdout || "",
196
+ stderr: result.stderr || "",
197
+ exitCode: result.exitCode || 1,
198
+ durationMs: Date.now() - startTime
199
+ };
200
+ }
209
201
  return {
210
202
  stdout: "",
211
203
  stderr: error instanceof Error ? error.message : String(error),
212
204
  exitCode: 127,
213
- // Command not found exit code
214
- executionTime: Date.now() - startTime,
215
- sandboxId: sandbox.sandboxId || "e2b-unknown",
216
- provider: "e2b"
205
+ durationMs: Date.now() - startTime
217
206
  };
218
207
  }
219
208
  },
@@ -277,25 +266,8 @@ var e2b = (0, import_computesdk.createProvider)({
277
266
  }
278
267
  }
279
268
  });
280
- function createE2BCompute(config) {
281
- const provider = e2b(config);
282
- return {
283
- sandbox: {
284
- create: async () => {
285
- const sandbox = await provider.sandbox.create();
286
- return {
287
- ...sandbox,
288
- getInstance: () => {
289
- return sandbox.getInstance();
290
- }
291
- };
292
- }
293
- }
294
- };
295
- }
296
269
  // Annotate the CommonJS export names for ESM import in node:
297
270
  0 && (module.exports = {
298
- createE2BCompute,
299
271
  e2b
300
272
  });
301
273
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * E2B Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Sandbox as E2BSandbox } from 'e2b';\nimport { createProvider, createBackgroundCommand } from 'computesdk';\n\n\nimport type {\n ExecutionResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry,\n RunCommandOptions\n} from 'computesdk';\n\n/**\n * E2B-specific configuration options\n */\nexport interface E2BConfig {\n /** E2B API key - if not provided, will fallback to E2B_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n\n\n/**\n * Create an E2B provider instance using the factory pattern\n */\nexport const e2b = createProvider<E2BSandbox, E2BConfig>({\n name: 'e2b',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: E2BConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.E2B_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing E2B API key. Provide 'apiKey' in config or set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n\n // Validate API key format\n if (!apiKey.startsWith('e2b_')) {\n throw new Error(\n `Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.`\n );\n }\n\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: E2BSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing E2B session\n sandbox = await E2BSandbox.connect(options.sandboxId, {\n apiKey: apiKey,\n domain: options.domain,\n });\n sandboxId = options.sandboxId;\n } else {\n // Create new E2B session\n if (options?.templateId) {\n sandbox = await E2BSandbox.create(options.templateId, {\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options.domain,\n });\n } else {\n sandbox = await E2BSandbox.create({\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options?.domain,\n });\n }\n sandboxId = sandbox.sandboxId || `e2b-${Date.now()}`;\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `E2B authentication failed. Please check your E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `E2B quota exceeded. Please check your usage at https://e2b.dev/`\n );\n }\n }\n throw new Error(\n `Failed to create E2B sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: E2BConfig) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const paginator = E2BSandbox.list({\n apiKey: apiKey,\n });\n // Get first page of results using nextItems\n const items = await paginator.nextItems();\n return items.map((sandbox: any) => ({\n sandbox,\n sandboxId: sandbox.id\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n await sandbox.kill();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: E2BSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n 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 ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use runCommand for consistent execution across all providers\n let result;\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n\n if (effectiveRuntime === 'python') {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | python3`);\n } else {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | node`);\n }\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (result.exitCode !== 0 && result.stderr) {\n // Check for common syntax error patterns\n if (result.stderr.includes('SyntaxError') ||\n result.stderr.includes('invalid syntax') ||\n result.stderr.includes('Unexpected token') ||\n result.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${result.stderr.trim()}`);\n }\n }\n\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n } catch (error) {\n // Handle E2B's CommandExitError - check if it contains actual error details\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n const isSyntaxError = actualStderr.includes('SyntaxError');\n\n if (isSyntaxError) {\n // For syntax errors, throw\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n } else {\n // For runtime errors, return a result instead of throwing\n return {\n stdout: '',\n stderr: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n }\n\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: E2BSandbox, command: string, args: string[] = [], options?: RunCommandOptions): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Handle background command execution\n const { command: finalCommand, args: finalArgs, isBackground } = createBackgroundCommand(command, args, options);\n\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = finalArgs.map(arg => {\n // Quote arguments that contain spaces or special characters\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n // Escape any double quotes in the argument and wrap in double quotes\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${finalCommand} ${quotedArgs.join(' ')}` : finalCommand;\n\n // Execute command using E2B's bash execution via Python subprocess\n const execution = await sandbox.commands.run(fullCommand);\n\n return {\n stdout: execution.stdout,\n stderr: execution.stderr,\n exitCode: execution.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b',\n isBackground,\n // For background commands, we can't get a real PID, but we can indicate it's running\n ...(isBackground && { pid: -1 })\n };\n } catch (error) {\n // For command failures, return error info instead of throwing\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127, // Command not found exit code\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n },\n\n getInfo: async (sandbox: E2BSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b',\n runtime: 'python', // E2B default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n e2bSessionId: sandbox.sandboxId\n }\n };\n },\n\n getUrl: async (sandbox: E2BSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use E2B's built-in getHost method for accurate host information\n const host = sandbox.getHost(options.port);\n const protocol = options.protocol || 'https';\n return `${protocol}://${host}`;\n } catch (error) {\n throw new Error(\n `Failed to get E2B host for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - E2B has full filesystem support\n filesystem: {\n readFile: async (sandbox: E2BSandbox, path: string): Promise<string> => {\n return await sandbox.files.read(path);\n },\n\n writeFile: async (sandbox: E2BSandbox, path: string, content: string): Promise<void> => {\n await sandbox.files.write(path, content);\n },\n\n mkdir: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.makeDir(path);\n },\n\n readdir: async (sandbox: E2BSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.files.list(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n path: entry.path,\n isDirectory: Boolean(entry.isDir || entry.isDirectory),\n size: entry.size || 0,\n lastModified: new Date(entry.lastModified || Date.now())\n }));\n },\n\n exists: async (sandbox: E2BSandbox, path: string): Promise<boolean> => {\n return await sandbox.files.exists(path);\n },\n\n remove: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.remove(path);\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: E2BSandbox): E2BSandbox => {\n return sandbox;\n },\n\n }\n }\n});\n\n// Export E2B sandbox type for explicit typing\nexport type { Sandbox as E2BSandbox } from 'e2b';\n\n// Note: getInstance() typing is now handled by generic type parameters in the core SDK\n\n/**\n * Create a properly typed compute instance for E2B\n * This version provides full type safety for getInstance() calls\n * \n * @example\n * ```typescript\n * import { createE2BCompute } from '@computesdk/e2b'\n * \n * const compute = createE2BCompute({ apiKey: 'your-key' });\n * const sandbox = await compute.sandbox.create();\n * const instance = sandbox.getInstance(); // ✅ Properly typed as E2B Sandbox!\n * ```\n */\nexport function createE2BCompute(config: E2BConfig): {\n sandbox: {\n create(): Promise<{\n sandboxId: string;\n provider: string;\n runCode(code: string, runtime?: import('computesdk').Runtime): Promise<import('computesdk').ExecutionResult>;\n runCommand(command: string, args?: string[]): Promise<import('computesdk').ExecutionResult>;\n getInfo(): Promise<import('computesdk').SandboxInfo>;\n getUrl(options: { port: number; protocol?: string }): Promise<string>;\n getProvider(): ReturnType<typeof e2b>;\n getInstance(): E2BSandbox; // ✅ Properly typed!\n kill(): Promise<void>;\n destroy(): Promise<void>;\n filesystem: import('computesdk').SandboxFileSystem;\n }>;\n };\n} {\n const provider = e2b(config);\n \n return {\n sandbox: {\n create: async () => {\n const sandbox = await provider.sandbox.create();\n return {\n ...sandbox,\n getInstance: (): E2BSandbox => {\n return sandbox.getInstance() as E2BSandbox;\n }\n };\n }\n }\n };\n}\n"],"mappings":"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","names":["E2BSandbox"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * E2B Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Sandbox as E2BSandbox } from 'e2b';\nimport { createProvider } from 'computesdk';\n\n\nimport type {\n CodeResult,\n CommandResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry\n} from 'computesdk';\n\n/**\n * E2B-specific configuration options\n */\nexport interface E2BConfig {\n /** E2B API key - if not provided, will fallback to E2B_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n\n\n/**\n * Create an E2B provider instance using the factory pattern\n */\nexport const e2b = createProvider<E2BSandbox, E2BConfig>({\n name: 'e2b',\n defaultMode: 'direct',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: E2BConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.E2B_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing E2B API key. Provide 'apiKey' in config or set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n\n // Validate API key format\n if (!apiKey.startsWith('e2b_')) {\n throw new Error(\n `Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.`\n );\n }\n\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: E2BSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing E2B session\n sandbox = await E2BSandbox.connect(options.sandboxId, {\n apiKey: apiKey,\n domain: options.domain,\n });\n sandboxId = options.sandboxId;\n } else {\n // Create new E2B session\n if (options?.templateId) {\n sandbox = await E2BSandbox.create(options.templateId, {\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options?.domain,\n envs: options?.envs,\n });\n } else {\n sandbox = await E2BSandbox.create({\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options?.domain,\n envs: options?.envs,\n });\n }\n sandboxId = sandbox.sandboxId || `e2b-${Date.now()}`;\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `E2B authentication failed. Please check your E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `E2B quota exceeded. Please check your usage at https://e2b.dev/`\n );\n }\n }\n throw new Error(\n `Failed to create E2B sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: E2BConfig) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const paginator = E2BSandbox.list({\n apiKey: apiKey,\n });\n // Get first page of results using nextItems\n const items = await paginator.nextItems();\n return items.map((sandbox: any) => ({\n sandbox,\n sandboxId: sandbox.id\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n await sandbox.kill();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: E2BSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n try {\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n 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 ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n const result = effectiveRuntime === 'python'\n ? await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | python3`)\n : await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | node`);\n\n // Check for syntax errors and throw them\n if (result.exitCode !== 0 && result.stderr) {\n if (result.stderr.includes('SyntaxError') ||\n result.stderr.includes('invalid syntax') ||\n result.stderr.includes('Unexpected token') ||\n result.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${result.stderr.trim()}`);\n }\n }\n\n // Combine stdout and stderr for output\n const output = result.stderr\n ? `${result.stdout}${result.stdout && result.stderr ? '\\n' : ''}${result.stderr}`\n : result.stdout;\n\n return {\n output,\n exitCode: result.exitCode,\n language: effectiveRuntime\n };\n } catch (error) {\n // Handle E2B's CommandExitError\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n if (actualStderr.includes('SyntaxError')) {\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n }\n // For runtime errors, return a result instead of throwing\n return {\n output: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n language: runtime || 'node'\n };\n }\n\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: E2BSandbox, command: string, args: string[] = []): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = args.map((arg: string) => {\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(' ')}` : command;\n\n const execution = await sandbox.commands.run(fullCommand);\n\n return {\n stdout: execution.stdout,\n stderr: execution.stderr,\n exitCode: execution.exitCode,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n // E2B throws errors for non-zero exit codes\n // Extract the actual result from the error if available\n const result = (error as any)?.result;\n if (result) {\n return {\n stdout: result.stdout || '',\n stderr: result.stderr || '',\n exitCode: result.exitCode || 1,\n durationMs: Date.now() - startTime\n };\n }\n \n // Fallback for other errors (command not found, etc.)\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 (sandbox: E2BSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b',\n runtime: 'python', // E2B default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n e2bSessionId: sandbox.sandboxId\n }\n };\n },\n\n getUrl: async (sandbox: E2BSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use E2B's built-in getHost method for accurate host information\n const host = sandbox.getHost(options.port);\n const protocol = options.protocol || 'https';\n return `${protocol}://${host}`;\n } catch (error) {\n throw new Error(\n `Failed to get E2B host for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - E2B has full filesystem support\n filesystem: {\n readFile: async (sandbox: E2BSandbox, path: string): Promise<string> => {\n return await sandbox.files.read(path);\n },\n\n writeFile: async (sandbox: E2BSandbox, path: string, content: string): Promise<void> => {\n await sandbox.files.write(path, content);\n },\n\n mkdir: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.makeDir(path);\n },\n\n readdir: async (sandbox: E2BSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.files.list(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n path: entry.path,\n isDirectory: Boolean(entry.isDir || entry.isDirectory),\n size: entry.size || 0,\n lastModified: new Date(entry.lastModified || Date.now())\n }));\n },\n\n exists: async (sandbox: E2BSandbox, path: string): Promise<boolean> => {\n return await sandbox.files.exists(path);\n },\n\n remove: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.remove(path);\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: E2BSandbox): E2BSandbox => {\n return sandbox;\n },\n\n }\n }\n});\n\n// Export E2B sandbox type for explicit typing\nexport type { Sandbox as E2BSandbox } from 'e2b';\n"],"mappings":"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","names":["E2BSandbox"]}
package/dist/index.mjs CHANGED
@@ -1,8 +1,9 @@
1
1
  // src/index.ts
2
2
  import { Sandbox as E2BSandbox } from "e2b";
3
- import { createProvider, createBackgroundCommand } from "computesdk";
3
+ import { createProvider } from "computesdk";
4
4
  var e2b = createProvider({
5
5
  name: "e2b",
6
+ defaultMode: "direct",
6
7
  methods: {
7
8
  sandbox: {
8
9
  // Collection operations (map to compute.sandbox.*)
@@ -33,13 +34,15 @@ var e2b = createProvider({
33
34
  sandbox = await E2BSandbox.create(options.templateId, {
34
35
  apiKey,
35
36
  timeoutMs: timeout,
36
- domain: options.domain
37
+ domain: options?.domain,
38
+ envs: options?.envs
37
39
  });
38
40
  } else {
39
41
  sandbox = await E2BSandbox.create({
40
42
  apiKey,
41
43
  timeoutMs: timeout,
42
- domain: options?.domain
44
+ domain: options?.domain,
45
+ envs: options?.envs
43
46
  });
44
47
  }
45
48
  sandboxId = sandbox.sandboxId || `e2b-${Date.now()}`;
@@ -107,47 +110,34 @@ var e2b = createProvider({
107
110
  },
108
111
  // Instance operations (map to individual Sandbox methods)
109
112
  runCode: async (sandbox, code, runtime) => {
110
- const startTime = Date.now();
111
113
  try {
112
114
  const effectiveRuntime = runtime || // Strong Python indicators
113
115
  (code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") || code.includes("raise ") ? "python" : "node");
114
- let result;
115
116
  const encoded = Buffer.from(code).toString("base64");
116
- if (effectiveRuntime === "python") {
117
- result = await sandbox.commands.run(`echo "${encoded}" | base64 -d | python3`);
118
- } else {
119
- result = await sandbox.commands.run(`echo "${encoded}" | base64 -d | node`);
120
- }
117
+ const result = effectiveRuntime === "python" ? await sandbox.commands.run(`echo "${encoded}" | base64 -d | python3`) : await sandbox.commands.run(`echo "${encoded}" | base64 -d | node`);
121
118
  if (result.exitCode !== 0 && result.stderr) {
122
119
  if (result.stderr.includes("SyntaxError") || result.stderr.includes("invalid syntax") || result.stderr.includes("Unexpected token") || result.stderr.includes("Unexpected identifier")) {
123
120
  throw new Error(`Syntax error: ${result.stderr.trim()}`);
124
121
  }
125
122
  }
123
+ const output = result.stderr ? `${result.stdout}${result.stdout && result.stderr ? "\n" : ""}${result.stderr}` : result.stdout;
126
124
  return {
127
- stdout: result.stdout,
128
- stderr: result.stderr,
125
+ output,
129
126
  exitCode: result.exitCode,
130
- executionTime: Date.now() - startTime,
131
- sandboxId: sandbox.sandboxId || "e2b-unknown",
132
- provider: "e2b"
127
+ language: effectiveRuntime
133
128
  };
134
129
  } catch (error) {
135
130
  if (error instanceof Error && error.message === "exit status 1") {
136
131
  const actualStderr = error?.result?.stderr || "";
137
- const isSyntaxError = actualStderr.includes("SyntaxError");
138
- if (isSyntaxError) {
132
+ if (actualStderr.includes("SyntaxError")) {
139
133
  const syntaxErrorLine = actualStderr.split("\n").find((line) => line.includes("SyntaxError")) || "SyntaxError: Invalid syntax in code";
140
134
  throw new Error(`Syntax error: ${syntaxErrorLine}`);
141
- } else {
142
- return {
143
- stdout: "",
144
- stderr: actualStderr || "Error: Runtime error occurred during execution",
145
- exitCode: 1,
146
- executionTime: Date.now() - startTime,
147
- sandboxId: sandbox.sandboxId || "e2b-unknown",
148
- provider: "e2b"
149
- };
150
135
  }
136
+ return {
137
+ output: actualStderr || "Error: Runtime error occurred during execution",
138
+ exitCode: 1,
139
+ language: runtime || "node"
140
+ };
151
141
  }
152
142
  if (error instanceof Error && error.message.includes("Syntax error")) {
153
143
  throw error;
@@ -157,38 +147,38 @@ var e2b = createProvider({
157
147
  );
158
148
  }
159
149
  },
160
- runCommand: async (sandbox, command, args = [], options) => {
150
+ runCommand: async (sandbox, command, args = []) => {
161
151
  const startTime = Date.now();
162
152
  try {
163
- const { command: finalCommand, args: finalArgs, isBackground } = createBackgroundCommand(command, args, options);
164
- const quotedArgs = finalArgs.map((arg) => {
153
+ const quotedArgs = args.map((arg) => {
165
154
  if (arg.includes(" ") || arg.includes('"') || arg.includes("'") || arg.includes("$") || arg.includes("`")) {
166
155
  return `"${arg.replace(/"/g, '\\"')}"`;
167
156
  }
168
157
  return arg;
169
158
  });
170
- const fullCommand = quotedArgs.length > 0 ? `${finalCommand} ${quotedArgs.join(" ")}` : finalCommand;
159
+ const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(" ")}` : command;
171
160
  const execution = await sandbox.commands.run(fullCommand);
172
161
  return {
173
162
  stdout: execution.stdout,
174
163
  stderr: execution.stderr,
175
164
  exitCode: execution.exitCode,
176
- executionTime: Date.now() - startTime,
177
- sandboxId: sandbox.sandboxId || "e2b-unknown",
178
- provider: "e2b",
179
- isBackground,
180
- // For background commands, we can't get a real PID, but we can indicate it's running
181
- ...isBackground && { pid: -1 }
165
+ durationMs: Date.now() - startTime
182
166
  };
183
167
  } catch (error) {
168
+ const result = error?.result;
169
+ if (result) {
170
+ return {
171
+ stdout: result.stdout || "",
172
+ stderr: result.stderr || "",
173
+ exitCode: result.exitCode || 1,
174
+ durationMs: Date.now() - startTime
175
+ };
176
+ }
184
177
  return {
185
178
  stdout: "",
186
179
  stderr: error instanceof Error ? error.message : String(error),
187
180
  exitCode: 127,
188
- // Command not found exit code
189
- executionTime: Date.now() - startTime,
190
- sandboxId: sandbox.sandboxId || "e2b-unknown",
191
- provider: "e2b"
181
+ durationMs: Date.now() - startTime
192
182
  };
193
183
  }
194
184
  },
@@ -252,24 +242,7 @@ var e2b = createProvider({
252
242
  }
253
243
  }
254
244
  });
255
- function createE2BCompute(config) {
256
- const provider = e2b(config);
257
- return {
258
- sandbox: {
259
- create: async () => {
260
- const sandbox = await provider.sandbox.create();
261
- return {
262
- ...sandbox,
263
- getInstance: () => {
264
- return sandbox.getInstance();
265
- }
266
- };
267
- }
268
- }
269
- };
270
- }
271
245
  export {
272
- createE2BCompute,
273
246
  e2b
274
247
  };
275
248
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * E2B Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Sandbox as E2BSandbox } from 'e2b';\nimport { createProvider, createBackgroundCommand } from 'computesdk';\n\n\nimport type {\n ExecutionResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry,\n RunCommandOptions\n} from 'computesdk';\n\n/**\n * E2B-specific configuration options\n */\nexport interface E2BConfig {\n /** E2B API key - if not provided, will fallback to E2B_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n\n\n/**\n * Create an E2B provider instance using the factory pattern\n */\nexport const e2b = createProvider<E2BSandbox, E2BConfig>({\n name: 'e2b',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: E2BConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.E2B_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing E2B API key. Provide 'apiKey' in config or set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n\n // Validate API key format\n if (!apiKey.startsWith('e2b_')) {\n throw new Error(\n `Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.`\n );\n }\n\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: E2BSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing E2B session\n sandbox = await E2BSandbox.connect(options.sandboxId, {\n apiKey: apiKey,\n domain: options.domain,\n });\n sandboxId = options.sandboxId;\n } else {\n // Create new E2B session\n if (options?.templateId) {\n sandbox = await E2BSandbox.create(options.templateId, {\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options.domain,\n });\n } else {\n sandbox = await E2BSandbox.create({\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options?.domain,\n });\n }\n sandboxId = sandbox.sandboxId || `e2b-${Date.now()}`;\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `E2B authentication failed. Please check your E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `E2B quota exceeded. Please check your usage at https://e2b.dev/`\n );\n }\n }\n throw new Error(\n `Failed to create E2B sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: E2BConfig) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const paginator = E2BSandbox.list({\n apiKey: apiKey,\n });\n // Get first page of results using nextItems\n const items = await paginator.nextItems();\n return items.map((sandbox: any) => ({\n sandbox,\n sandboxId: sandbox.id\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n await sandbox.kill();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: E2BSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n 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 ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use runCommand for consistent execution across all providers\n let result;\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n\n if (effectiveRuntime === 'python') {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | python3`);\n } else {\n result = await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | node`);\n }\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (result.exitCode !== 0 && result.stderr) {\n // Check for common syntax error patterns\n if (result.stderr.includes('SyntaxError') ||\n result.stderr.includes('invalid syntax') ||\n result.stderr.includes('Unexpected token') ||\n result.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${result.stderr.trim()}`);\n }\n }\n\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n } catch (error) {\n // Handle E2B's CommandExitError - check if it contains actual error details\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n const isSyntaxError = actualStderr.includes('SyntaxError');\n\n if (isSyntaxError) {\n // For syntax errors, throw\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n } else {\n // For runtime errors, return a result instead of throwing\n return {\n stdout: '',\n stderr: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n }\n\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: E2BSandbox, command: string, args: string[] = [], options?: RunCommandOptions): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Handle background command execution\n const { command: finalCommand, args: finalArgs, isBackground } = createBackgroundCommand(command, args, options);\n\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = finalArgs.map(arg => {\n // Quote arguments that contain spaces or special characters\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n // Escape any double quotes in the argument and wrap in double quotes\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${finalCommand} ${quotedArgs.join(' ')}` : finalCommand;\n\n // Execute command using E2B's bash execution via Python subprocess\n const execution = await sandbox.commands.run(fullCommand);\n\n return {\n stdout: execution.stdout,\n stderr: execution.stderr,\n exitCode: execution.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b',\n isBackground,\n // For background commands, we can't get a real PID, but we can indicate it's running\n ...(isBackground && { pid: -1 })\n };\n } catch (error) {\n // For command failures, return error info instead of throwing\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127, // Command not found exit code\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b'\n };\n }\n },\n\n getInfo: async (sandbox: E2BSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b',\n runtime: 'python', // E2B default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n e2bSessionId: sandbox.sandboxId\n }\n };\n },\n\n getUrl: async (sandbox: E2BSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use E2B's built-in getHost method for accurate host information\n const host = sandbox.getHost(options.port);\n const protocol = options.protocol || 'https';\n return `${protocol}://${host}`;\n } catch (error) {\n throw new Error(\n `Failed to get E2B host for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - E2B has full filesystem support\n filesystem: {\n readFile: async (sandbox: E2BSandbox, path: string): Promise<string> => {\n return await sandbox.files.read(path);\n },\n\n writeFile: async (sandbox: E2BSandbox, path: string, content: string): Promise<void> => {\n await sandbox.files.write(path, content);\n },\n\n mkdir: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.makeDir(path);\n },\n\n readdir: async (sandbox: E2BSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.files.list(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n path: entry.path,\n isDirectory: Boolean(entry.isDir || entry.isDirectory),\n size: entry.size || 0,\n lastModified: new Date(entry.lastModified || Date.now())\n }));\n },\n\n exists: async (sandbox: E2BSandbox, path: string): Promise<boolean> => {\n return await sandbox.files.exists(path);\n },\n\n remove: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.remove(path);\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: E2BSandbox): E2BSandbox => {\n return sandbox;\n },\n\n }\n }\n});\n\n// Export E2B sandbox type for explicit typing\nexport type { Sandbox as E2BSandbox } from 'e2b';\n\n// Note: getInstance() typing is now handled by generic type parameters in the core SDK\n\n/**\n * Create a properly typed compute instance for E2B\n * This version provides full type safety for getInstance() calls\n * \n * @example\n * ```typescript\n * import { createE2BCompute } from '@computesdk/e2b'\n * \n * const compute = createE2BCompute({ apiKey: 'your-key' });\n * const sandbox = await compute.sandbox.create();\n * const instance = sandbox.getInstance(); // ✅ Properly typed as E2B Sandbox!\n * ```\n */\nexport function createE2BCompute(config: E2BConfig): {\n sandbox: {\n create(): Promise<{\n sandboxId: string;\n provider: string;\n runCode(code: string, runtime?: import('computesdk').Runtime): Promise<import('computesdk').ExecutionResult>;\n runCommand(command: string, args?: string[]): Promise<import('computesdk').ExecutionResult>;\n getInfo(): Promise<import('computesdk').SandboxInfo>;\n getUrl(options: { port: number; protocol?: string }): Promise<string>;\n getProvider(): ReturnType<typeof e2b>;\n getInstance(): E2BSandbox; // ✅ Properly typed!\n kill(): Promise<void>;\n destroy(): Promise<void>;\n filesystem: import('computesdk').SandboxFileSystem;\n }>;\n };\n} {\n const provider = e2b(config);\n \n return {\n sandbox: {\n create: async () => {\n const sandbox = await provider.sandbox.create();\n return {\n ...sandbox,\n getInstance: (): E2BSandbox => {\n return sandbox.getInstance() as E2BSandbox;\n }\n };\n }\n }\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * E2B Provider - Factory-based Implementation\n * \n * Full-featured provider with filesystem support using the factory pattern.\n * Reduces ~400 lines of boilerplate to ~100 lines of core logic.\n */\n\nimport { Sandbox as E2BSandbox } from 'e2b';\nimport { createProvider } from 'computesdk';\n\n\nimport type {\n CodeResult,\n CommandResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry\n} from 'computesdk';\n\n/**\n * E2B-specific configuration options\n */\nexport interface E2BConfig {\n /** E2B API key - if not provided, will fallback to E2B_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n\n\n/**\n * Create an E2B provider instance using the factory pattern\n */\nexport const e2b = createProvider<E2BSandbox, E2BConfig>({\n name: 'e2b',\n defaultMode: 'direct',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: E2BConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.E2B_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing E2B API key. Provide 'apiKey' in config or set E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n\n // Validate API key format\n if (!apiKey.startsWith('e2b_')) {\n throw new Error(\n `Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.`\n );\n }\n\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: E2BSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing E2B session\n sandbox = await E2BSandbox.connect(options.sandboxId, {\n apiKey: apiKey,\n domain: options.domain,\n });\n sandboxId = options.sandboxId;\n } else {\n // Create new E2B session\n if (options?.templateId) {\n sandbox = await E2BSandbox.create(options.templateId, {\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options?.domain,\n envs: options?.envs,\n });\n } else {\n sandbox = await E2BSandbox.create({\n apiKey: apiKey,\n timeoutMs: timeout,\n domain: options?.domain,\n envs: options?.envs,\n });\n }\n sandboxId = sandbox.sandboxId || `e2b-${Date.now()}`;\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `E2B authentication failed. Please check your E2B_API_KEY environment variable. Get your API key from https://e2b.dev/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `E2B quota exceeded. Please check your usage at https://e2b.dev/`\n );\n }\n }\n throw new Error(\n `Failed to create E2B sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: E2BConfig) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const paginator = E2BSandbox.list({\n apiKey: apiKey,\n });\n // Get first page of results using nextItems\n const items = await paginator.nextItems();\n return items.map((sandbox: any) => ({\n sandbox,\n sandboxId: sandbox.id\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: E2BConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.E2B_API_KEY!;\n\n try {\n const sandbox = await E2BSandbox.connect(sandboxId, {\n apiKey: apiKey,\n });\n await sandbox.kill();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: E2BSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n try {\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n 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 ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n const result = effectiveRuntime === 'python'\n ? await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | python3`)\n : await sandbox.commands.run(`echo \"${encoded}\" | base64 -d | node`);\n\n // Check for syntax errors and throw them\n if (result.exitCode !== 0 && result.stderr) {\n if (result.stderr.includes('SyntaxError') ||\n result.stderr.includes('invalid syntax') ||\n result.stderr.includes('Unexpected token') ||\n result.stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${result.stderr.trim()}`);\n }\n }\n\n // Combine stdout and stderr for output\n const output = result.stderr\n ? `${result.stdout}${result.stdout && result.stderr ? '\\n' : ''}${result.stderr}`\n : result.stdout;\n\n return {\n output,\n exitCode: result.exitCode,\n language: effectiveRuntime\n };\n } catch (error) {\n // Handle E2B's CommandExitError\n if (error instanceof Error && error.message === 'exit status 1') {\n const actualStderr = (error as any)?.result?.stderr || '';\n if (actualStderr.includes('SyntaxError')) {\n const syntaxErrorLine = actualStderr.split('\\n').find((line: string) => line.includes('SyntaxError')) || 'SyntaxError: Invalid syntax in code';\n throw new Error(`Syntax error: ${syntaxErrorLine}`);\n }\n // For runtime errors, return a result instead of throwing\n return {\n output: actualStderr || 'Error: Runtime error occurred during execution',\n exitCode: 1,\n language: runtime || 'node'\n };\n }\n\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `E2B execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: E2BSandbox, command: string, args: string[] = []): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = args.map((arg: string) => {\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(' ')}` : command;\n\n const execution = await sandbox.commands.run(fullCommand);\n\n return {\n stdout: execution.stdout,\n stderr: execution.stderr,\n exitCode: execution.exitCode,\n durationMs: Date.now() - startTime\n };\n } catch (error) {\n // E2B throws errors for non-zero exit codes\n // Extract the actual result from the error if available\n const result = (error as any)?.result;\n if (result) {\n return {\n stdout: result.stdout || '',\n stderr: result.stderr || '',\n exitCode: result.exitCode || 1,\n durationMs: Date.now() - startTime\n };\n }\n \n // Fallback for other errors (command not found, etc.)\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 (sandbox: E2BSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.sandboxId || 'e2b-unknown',\n provider: 'e2b',\n runtime: 'python', // E2B default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n e2bSessionId: sandbox.sandboxId\n }\n };\n },\n\n getUrl: async (sandbox: E2BSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use E2B's built-in getHost method for accurate host information\n const host = sandbox.getHost(options.port);\n const protocol = options.protocol || 'https';\n return `${protocol}://${host}`;\n } catch (error) {\n throw new Error(\n `Failed to get E2B host for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - E2B has full filesystem support\n filesystem: {\n readFile: async (sandbox: E2BSandbox, path: string): Promise<string> => {\n return await sandbox.files.read(path);\n },\n\n writeFile: async (sandbox: E2BSandbox, path: string, content: string): Promise<void> => {\n await sandbox.files.write(path, content);\n },\n\n mkdir: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.makeDir(path);\n },\n\n readdir: async (sandbox: E2BSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.files.list(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n path: entry.path,\n isDirectory: Boolean(entry.isDir || entry.isDirectory),\n size: entry.size || 0,\n lastModified: new Date(entry.lastModified || Date.now())\n }));\n },\n\n exists: async (sandbox: E2BSandbox, path: string): Promise<boolean> => {\n return await sandbox.files.exists(path);\n },\n\n remove: async (sandbox: E2BSandbox, path: string): Promise<void> => {\n await sandbox.files.remove(path);\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: E2BSandbox): E2BSandbox => {\n return sandbox;\n },\n\n }\n }\n});\n\n// Export E2B sandbox type for explicit typing\nexport type { Sandbox as E2BSandbox } from 'e2b';\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computesdk/e2b",
3
- "version": "1.6.7",
3
+ "version": "1.7.0",
4
4
  "description": "E2B provider for ComputeSDK",
5
5
  "author": "Garrison",
6
6
  "license": "MIT",
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "e2b": "^2.0.1",
22
- "computesdk": "1.8.7"
22
+ "computesdk": "1.9.0"
23
23
  },
24
24
  "keywords": [
25
25
  "e2b",