@computesdk/vercel 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,222 +15,331 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/index.ts
31
21
  var index_exports = {};
32
22
  __export(index_exports, {
33
- VercelProvider: () => VercelProvider,
34
23
  vercel: () => vercel
35
24
  });
36
25
  module.exports = __toCommonJS(index_exports);
37
26
  var import_sandbox = require("@vercel/sandbox");
38
- var import_ms = __toESM(require("ms"));
39
- var VercelProvider = class {
40
- constructor(config) {
41
- this.specificationVersion = "v1";
42
- this.provider = "vercel";
43
- this.sandbox = null;
44
- this.sandboxId = `vercel-${Date.now()}-${Math.random().toString(36).substring(7)}`;
45
- this.timeout = config.timeout || 3e5;
46
- this.token = process.env.VERCEL_TOKEN || "";
47
- this.teamId = process.env.VERCEL_TEAM_ID || "";
48
- this.projectId = process.env.VERCEL_PROJECT_ID || "";
49
- if (!this.token) {
50
- throw new Error(
51
- `Missing Vercel token. Set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
52
- );
53
- }
54
- if (!this.teamId) {
55
- throw new Error(
56
- `Missing Vercel team ID. Set VERCEL_TEAM_ID environment variable.`
57
- );
58
- }
59
- if (!this.projectId) {
60
- throw new Error(
61
- `Missing Vercel project ID. Set VERCEL_PROJECT_ID environment variable.`
62
- );
63
- }
64
- if (config.runtime && !["node", "python"].includes(config.runtime)) {
65
- throw new Error("Vercel provider only supports Node.js and Python runtimes");
66
- }
67
- this.runtime = config.runtime || "node";
68
- }
69
- async ensureSandbox() {
70
- if (this.sandbox) {
71
- return this.sandbox;
72
- }
73
- try {
74
- const runtimeImage = this.runtime === "node" ? "node22" : "python3.13";
75
- this.sandbox = await import_sandbox.Sandbox.create({
76
- runtime: runtimeImage,
77
- timeout: (0, import_ms.default)(`${this.timeout}ms`),
78
- resources: { vcpus: 2 }
79
- // Default to 2 vCPUs
80
- });
81
- return this.sandbox;
82
- } catch (error) {
83
- if (error instanceof Error) {
84
- if (error.message.includes("unauthorized") || error.message.includes("token")) {
85
- throw new Error(
86
- `Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
87
- );
27
+ var import_computesdk = require("computesdk");
28
+ var vercel = (0, import_computesdk.createProvider)({
29
+ name: "vercel",
30
+ methods: {
31
+ sandbox: {
32
+ // Collection operations (map to compute.sandbox.*)
33
+ create: async (config, options) => {
34
+ const oidcToken = typeof process !== "undefined" && process.env?.VERCEL_OIDC_TOKEN;
35
+ const token = config.token || typeof process !== "undefined" && process.env?.VERCEL_TOKEN || "";
36
+ const teamId = config.teamId || typeof process !== "undefined" && process.env?.VERCEL_TEAM_ID || "";
37
+ const projectId = config.projectId || typeof process !== "undefined" && process.env?.VERCEL_PROJECT_ID || "";
38
+ if (!oidcToken && (!token || !teamId || !projectId)) {
39
+ if (!oidcToken && !token) {
40
+ throw new Error(
41
+ `Missing Vercel authentication. Either:
42
+ 1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or
43
+ 2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
44
+ );
45
+ }
46
+ if (!oidcToken && !teamId) {
47
+ throw new Error(
48
+ `Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`
49
+ );
50
+ }
51
+ if (!oidcToken && !projectId) {
52
+ throw new Error(
53
+ `Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`
54
+ );
55
+ }
88
56
  }
89
- if (error.message.includes("team") || error.message.includes("project")) {
57
+ const runtime = options?.runtime || config.runtime || "node";
58
+ const timeout = config.timeout || 3e5;
59
+ try {
60
+ let sandbox;
61
+ if (options?.sandboxId) {
62
+ throw new Error(
63
+ `Vercel provider does not support reconnecting to existing sandboxes. Vercel sandboxes are ephemeral and must be created fresh each time.`
64
+ );
65
+ } else {
66
+ if (oidcToken) {
67
+ sandbox = await import_sandbox.Sandbox.create();
68
+ } else {
69
+ sandbox = await import_sandbox.Sandbox.create({
70
+ token,
71
+ teamId,
72
+ projectId
73
+ });
74
+ }
75
+ }
76
+ return {
77
+ sandbox,
78
+ sandboxId: sandbox.sandboxId
79
+ };
80
+ } catch (error) {
81
+ if (error instanceof Error) {
82
+ if (error.message.includes("unauthorized") || error.message.includes("token")) {
83
+ throw new Error(
84
+ `Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
85
+ );
86
+ }
87
+ if (error.message.includes("team") || error.message.includes("project")) {
88
+ throw new Error(
89
+ `Vercel team/project configuration failed. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`
90
+ );
91
+ }
92
+ }
90
93
  throw new Error(
91
- `Vercel team/project configuration error. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`
94
+ `Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`
92
95
  );
93
96
  }
94
- if (error.message.includes("Memory limit exceeded")) {
95
- throw new Error(
96
- `Vercel execution failed due to memory limits. Consider optimizing your code or using smaller data sets.`
97
- );
97
+ },
98
+ getById: async (config, sandboxId) => {
99
+ const oidcToken = typeof process !== "undefined" && process.env?.VERCEL_OIDC_TOKEN;
100
+ try {
101
+ let sandbox;
102
+ if (oidcToken) {
103
+ sandbox = await import_sandbox.Sandbox.get({ sandboxId });
104
+ } else {
105
+ const token = config.token || process.env.VERCEL_TOKEN;
106
+ const teamId = config.teamId || process.env.VERCEL_TEAM_ID;
107
+ const projectId = config.projectId || process.env.VERCEL_PROJECT_ID;
108
+ sandbox = await import_sandbox.Sandbox.get({
109
+ sandboxId,
110
+ token,
111
+ teamId,
112
+ projectId
113
+ });
114
+ }
115
+ return {
116
+ sandbox,
117
+ sandboxId
118
+ };
119
+ } catch (error) {
120
+ return null;
98
121
  }
99
- if (error.message.includes("quota") || error.message.includes("limit")) {
122
+ },
123
+ list: async (_config) => {
124
+ throw new Error(
125
+ `Vercel provider does not support listing sandboxes. Vercel sandboxes are ephemeral and designed for single-use execution. Consider using a provider with persistent sandbox management like E2B.`
126
+ );
127
+ },
128
+ destroy: async (config, sandboxId) => {
129
+ const oidcToken = typeof process !== "undefined" && process.env?.VERCEL_OIDC_TOKEN;
130
+ try {
131
+ let sandbox;
132
+ if (oidcToken) {
133
+ sandbox = await import_sandbox.Sandbox.get({ sandboxId });
134
+ } else {
135
+ const token = config.token || process.env.VERCEL_TOKEN;
136
+ const teamId = config.teamId || process.env.VERCEL_TEAM_ID;
137
+ const projectId = config.projectId || process.env.VERCEL_PROJECT_ID;
138
+ sandbox = await import_sandbox.Sandbox.get({
139
+ sandboxId,
140
+ token,
141
+ teamId,
142
+ projectId
143
+ });
144
+ }
145
+ await sandbox.stop();
146
+ } catch (error) {
147
+ }
148
+ },
149
+ // Instance operations (map to individual Sandbox methods)
150
+ runCode: async (sandbox, code, runtime, config) => {
151
+ const startTime = Date.now();
152
+ try {
153
+ const effectiveRuntime = runtime || config?.runtime || // Strong Python indicators
154
+ (code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") ? "python" : "node");
155
+ const encoded = Buffer.from(code).toString("base64");
156
+ let command;
157
+ if (effectiveRuntime === "python") {
158
+ command = await sandbox.runCommand("sh", ["-c", `echo "${encoded}" | base64 -d | python3`]);
159
+ } else {
160
+ command = await sandbox.runCommand("sh", ["-c", `echo "${encoded}" | base64 -d | node`]);
161
+ }
162
+ const finishedCommand = await command.wait();
163
+ let stdout = "";
164
+ let stderr = "";
165
+ for await (const log of finishedCommand.logs()) {
166
+ if (log.stream === "stdout") {
167
+ stdout += log.data;
168
+ } else if (log.stream === "stderr") {
169
+ stderr += log.data;
170
+ }
171
+ }
172
+ if (finishedCommand.exitCode !== 0 && stderr) {
173
+ if (stderr.includes("SyntaxError") || stderr.includes("invalid syntax") || stderr.includes("Unexpected token") || stderr.includes("Unexpected identifier")) {
174
+ throw new Error(`Syntax error: ${stderr.trim()}`);
175
+ }
176
+ }
177
+ return {
178
+ stdout,
179
+ stderr,
180
+ exitCode: finishedCommand.exitCode,
181
+ executionTime: Date.now() - startTime,
182
+ sandboxId: sandbox.sandboxId,
183
+ provider: "vercel"
184
+ };
185
+ } catch (error) {
186
+ if (error instanceof Error && error.message.includes("Syntax error")) {
187
+ throw error;
188
+ }
100
189
  throw new Error(
101
- `Vercel quota exceeded. Please check your usage in the Vercel dashboard.`
190
+ `Vercel execution failed: ${error instanceof Error ? error.message : String(error)}`
102
191
  );
103
192
  }
104
- }
105
- throw new Error(
106
- `Failed to initialize Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`
107
- );
108
- }
109
- }
110
- async doExecute(code, runtime) {
111
- if (runtime && !["node", "python"].includes(runtime)) {
112
- throw new Error("Vercel provider only supports Node.js and Python runtimes");
113
- }
114
- const startTime = Date.now();
115
- const actualRuntime = runtime || this.runtime;
116
- try {
117
- const sandbox = await this.ensureSandbox();
118
- let command;
119
- let args = [];
120
- if (actualRuntime === "node") {
121
- command = "node";
122
- args = ["-e", code];
123
- } else if (actualRuntime === "python") {
124
- command = "python";
125
- args = ["-c", code];
126
- } else {
127
- throw new Error(`Unsupported runtime: ${actualRuntime}`);
128
- }
129
- const result = await sandbox.runCommand({
130
- cmd: command,
131
- args
132
- });
133
- let stdout = "";
134
- let stderr = "";
135
- let exitCode = 0;
136
- const stdoutPromise = new Promise((resolve) => {
137
- if (result.stdout) {
138
- result.stdout.on("data", (data) => {
139
- stdout += data.toString();
140
- });
141
- result.stdout.on("end", resolve);
142
- } else {
143
- resolve();
193
+ },
194
+ runCommand: async (sandbox, command, args = []) => {
195
+ const startTime = Date.now();
196
+ try {
197
+ const cmd = await sandbox.runCommand(command, args);
198
+ const finishedCommand = await cmd.wait();
199
+ let stdout = "";
200
+ let stderr = "";
201
+ for await (const log of finishedCommand.logs()) {
202
+ if (log.stream === "stdout") {
203
+ stdout += log.data;
204
+ } else if (log.stream === "stderr") {
205
+ stderr += log.data;
206
+ }
207
+ }
208
+ return {
209
+ stdout,
210
+ stderr,
211
+ exitCode: finishedCommand.exitCode,
212
+ executionTime: Date.now() - startTime,
213
+ sandboxId: sandbox.sandboxId,
214
+ provider: "vercel"
215
+ };
216
+ } catch (error) {
217
+ return {
218
+ stdout: "",
219
+ stderr: error instanceof Error ? error.message : String(error),
220
+ exitCode: 127,
221
+ // Standard "command not found" exit code
222
+ executionTime: Date.now() - startTime,
223
+ sandboxId: sandbox.sandboxId,
224
+ provider: "vercel"
225
+ };
144
226
  }
145
- });
146
- const stderrPromise = new Promise((resolve) => {
147
- if (result.stderr) {
148
- result.stderr.on("data", (data) => {
149
- stderr += data.toString();
227
+ },
228
+ getInfo: async (sandbox) => {
229
+ return {
230
+ id: "vercel-unknown",
231
+ provider: "vercel",
232
+ runtime: "node",
233
+ // Vercel default
234
+ status: "running",
235
+ createdAt: /* @__PURE__ */ new Date(),
236
+ timeout: 3e5,
237
+ metadata: {
238
+ vercelSandboxId: "vercel-unknown"
239
+ }
240
+ };
241
+ },
242
+ // Optional filesystem methods - Vercel has shell-based filesystem support
243
+ filesystem: {
244
+ readFile: async (sandbox, path) => {
245
+ const cmd = await sandbox.runCommand("cat", [path]);
246
+ const finishedCommand = await cmd.wait();
247
+ if (finishedCommand.exitCode !== 0) {
248
+ let stderr = "";
249
+ for await (const log of finishedCommand.logs()) {
250
+ if (log.stream === "stderr") {
251
+ stderr += log.data;
252
+ }
253
+ }
254
+ throw new Error(`Failed to read file ${path}: ${stderr}`);
255
+ }
256
+ let content = "";
257
+ for await (const log of finishedCommand.logs()) {
258
+ if (log.stream === "stdout") {
259
+ content += log.data;
260
+ }
261
+ }
262
+ return content.replace(/\n$/, "");
263
+ },
264
+ writeFile: async (sandbox, path, content) => {
265
+ const cmd = await sandbox.runCommand("sh", ["-c", `echo ${JSON.stringify(content)} > ${JSON.stringify(path)}`]);
266
+ const finishedCommand = await cmd.wait();
267
+ if (finishedCommand.exitCode !== 0) {
268
+ let stderr = "";
269
+ for await (const log of finishedCommand.logs()) {
270
+ if (log.stream === "stderr") {
271
+ stderr += log.data;
272
+ }
273
+ }
274
+ throw new Error(`Failed to write file ${path}: ${stderr}`);
275
+ }
276
+ },
277
+ mkdir: async (sandbox, path) => {
278
+ const cmd = await sandbox.runCommand("mkdir", ["-p", path]);
279
+ const finishedCommand = await cmd.wait();
280
+ if (finishedCommand.exitCode !== 0) {
281
+ let stderr = "";
282
+ for await (const log of finishedCommand.logs()) {
283
+ if (log.stream === "stderr") {
284
+ stderr += log.data;
285
+ }
286
+ }
287
+ throw new Error(`Failed to create directory ${path}: ${stderr}`);
288
+ }
289
+ },
290
+ readdir: async (sandbox, path) => {
291
+ const cmd = await sandbox.runCommand("ls", ["-la", path]);
292
+ const finishedCommand = await cmd.wait();
293
+ let stdout = "";
294
+ let stderr = "";
295
+ for await (const log of finishedCommand.logs()) {
296
+ if (log.stream === "stdout") {
297
+ stdout += log.data;
298
+ } else if (log.stream === "stderr") {
299
+ stderr += log.data;
300
+ }
301
+ }
302
+ if (finishedCommand.exitCode !== 0) {
303
+ throw new Error(`Failed to list directory ${path}: ${stderr}`);
304
+ }
305
+ const lines = (stdout || "").split("\n").filter((line) => line.trim() && !line.startsWith("total"));
306
+ return lines.map((line) => {
307
+ const parts = line.trim().split(/\s+/);
308
+ const name = parts[parts.length - 1];
309
+ const isDirectory = line.startsWith("d");
310
+ return {
311
+ name,
312
+ path: `${path}/${name}`,
313
+ isDirectory,
314
+ size: parseInt(parts[4]) || 0,
315
+ lastModified: /* @__PURE__ */ new Date()
316
+ };
150
317
  });
151
- result.stderr.on("end", resolve);
152
- } else {
153
- resolve();
154
- }
155
- });
156
- const exitPromise = new Promise((resolve, reject) => {
157
- result.on("exit", (code2) => {
158
- exitCode = code2;
159
- resolve(code2);
160
- });
161
- result.on("error", reject);
162
- });
163
- await Promise.all([stdoutPromise, stderrPromise, exitPromise]);
164
- return {
165
- stdout: stdout.trim(),
166
- stderr: stderr.trim(),
167
- exitCode,
168
- executionTime: Date.now() - startTime,
169
- sandboxId: this.sandboxId,
170
- provider: this.provider
171
- };
172
- } catch (error) {
173
- if (error instanceof Error) {
174
- if (error.message.includes("timeout")) {
175
- throw new Error(
176
- `Vercel execution timeout (${this.timeout}ms). Consider increasing the timeout or optimizing your code.`
177
- );
178
- }
179
- if (error.message.includes("memory") || error.message.includes("Memory")) {
180
- throw new Error(
181
- `Vercel execution failed due to memory limits. Consider optimizing your code or using smaller data sets.`
182
- );
318
+ },
319
+ exists: async (sandbox, path) => {
320
+ const cmd = await sandbox.runCommand("test", ["-e", path]);
321
+ const finishedCommand = await cmd.wait();
322
+ return finishedCommand.exitCode === 0;
323
+ },
324
+ remove: async (sandbox, path) => {
325
+ const cmd = await sandbox.runCommand("rm", ["-rf", path]);
326
+ const finishedCommand = await cmd.wait();
327
+ if (finishedCommand.exitCode !== 0) {
328
+ let stderr = "";
329
+ for await (const log of finishedCommand.logs()) {
330
+ if (log.stream === "stderr") {
331
+ stderr += log.data;
332
+ }
333
+ }
334
+ throw new Error(`Failed to remove ${path}: ${stderr}`);
335
+ }
183
336
  }
184
337
  }
185
- throw new Error(
186
- `Vercel execution failed: ${error instanceof Error ? error.message : String(error)}`
187
- );
188
338
  }
189
339
  }
190
- async doKill() {
191
- if (!this.sandbox) {
192
- return;
193
- }
194
- try {
195
- await this.sandbox.stop();
196
- this.sandbox = null;
197
- } catch (error) {
198
- throw new Error(
199
- `Failed to kill Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`
200
- );
201
- }
202
- }
203
- async doGetInfo() {
204
- await this.ensureSandbox();
205
- return {
206
- id: this.sandboxId,
207
- provider: this.provider,
208
- runtime: this.runtime,
209
- status: this.sandbox ? "running" : "stopped",
210
- createdAt: /* @__PURE__ */ new Date(),
211
- timeout: this.timeout,
212
- metadata: {
213
- vercelSandboxId: this.sandboxId,
214
- teamId: this.teamId,
215
- projectId: this.projectId,
216
- vcpus: 2,
217
- // Default vCPUs
218
- region: "global"
219
- // Vercel sandboxes can run globally
220
- }
221
- };
222
- }
223
- };
224
- function vercel(config) {
225
- const fullConfig = {
226
- provider: "vercel",
227
- runtime: "node",
228
- timeout: 3e5,
229
- ...config
230
- };
231
- return new VercelProvider(fullConfig);
232
- }
340
+ });
233
341
  // Annotate the CommonJS export names for ESM import in node:
234
342
  0 && (module.exports = {
235
- VercelProvider,
236
343
  vercel
237
344
  });
238
345
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Sandbox } from '@vercel/sandbox';\nimport ms from 'ms';\nimport type {\n ComputeSpecification,\n ExecutionResult,\n Runtime,\n SandboxInfo,\n SandboxConfig\n} from 'computesdk';\n\nexport class VercelProvider implements ComputeSpecification {\n public readonly specificationVersion = 'v1' as const;\n public readonly provider = 'vercel';\n public readonly sandboxId: string;\n\n private sandbox: any = null;\n private readonly token: string;\n private readonly teamId: string;\n private readonly projectId: string;\n private readonly runtime: Runtime;\n private readonly timeout: number;\n\n constructor(config: SandboxConfig) {\n this.sandboxId = `vercel-${Date.now()}-${Math.random().toString(36).substring(7)}`;\n this.timeout = config.timeout || 300000;\n\n // Get authentication from environment\n this.token = process.env.VERCEL_TOKEN || '';\n this.teamId = process.env.VERCEL_TEAM_ID || '';\n this.projectId = process.env.VERCEL_PROJECT_ID || '';\n\n if (!this.token) {\n throw new Error(\n `Missing Vercel token. Set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n\n if (!this.teamId) {\n throw new Error(\n `Missing Vercel team ID. Set VERCEL_TEAM_ID environment variable.`\n );\n }\n\n if (!this.projectId) {\n throw new Error(\n `Missing Vercel project ID. Set VERCEL_PROJECT_ID environment variable.`\n );\n }\n\n // Validate runtime - Vercel supports Node.js and Python\n if (config.runtime && !['node', 'python'].includes(config.runtime)) {\n throw new Error('Vercel provider only supports Node.js and Python runtimes');\n }\n\n this.runtime = config.runtime || 'node';\n }\n\n private async ensureSandbox(): Promise<any> {\n if (this.sandbox) {\n return this.sandbox;\n }\n\n try {\n // Create Vercel Sandbox with appropriate runtime\n const runtimeImage = this.runtime === 'node' ? 'node22' : 'python3.13';\n\n this.sandbox = await Sandbox.create({\n runtime: runtimeImage,\n timeout: ms(`${this.timeout}ms`),\n resources: { vcpus: 2 }, // Default to 2 vCPUs\n });\n\n return this.sandbox;\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('token')) {\n throw new Error(\n `Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n if (error.message.includes('team') || error.message.includes('project')) {\n throw new Error(\n `Vercel team/project configuration error. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`\n );\n }\n if (error.message.includes('Memory limit exceeded')) {\n throw new Error(\n `Vercel execution failed due to memory limits. Consider optimizing your code or using smaller data sets.`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `Vercel quota exceeded. Please check your usage in the Vercel dashboard.`\n );\n }\n }\n throw new Error(\n `Failed to initialize Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async doExecute(code: string, runtime?: Runtime): Promise<ExecutionResult> {\n // Validate runtime\n if (runtime && !['node', 'python'].includes(runtime)) {\n throw new Error('Vercel provider only supports Node.js and Python runtimes');\n }\n\n const startTime = Date.now();\n const actualRuntime = runtime || this.runtime;\n\n try {\n const sandbox = await this.ensureSandbox();\n\n // Execute code based on runtime\n let command: string;\n let args: string[] = [];\n\n if (actualRuntime === 'node') {\n // For Node.js, use node -e to execute code directly\n command = 'node';\n args = ['-e', code];\n } else if (actualRuntime === 'python') {\n // For Python, use python -c to execute code directly\n command = 'python';\n args = ['-c', code];\n } else {\n throw new Error(`Unsupported runtime: ${actualRuntime}`);\n }\n\n // Execute the command in the sandbox\n const result = await sandbox.runCommand({\n cmd: command,\n args: args,\n });\n\n // Collect stdout and stderr streams\n let stdout = '';\n let stderr = '';\n let exitCode = 0;\n\n // Set up stream listeners\n const stdoutPromise = new Promise<void>((resolve) => {\n if (result.stdout) {\n result.stdout.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n result.stdout.on('end', resolve);\n } else {\n resolve();\n }\n });\n\n const stderrPromise = new Promise<void>((resolve) => {\n if (result.stderr) {\n result.stderr.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n result.stderr.on('end', resolve);\n } else {\n resolve();\n }\n });\n\n // Wait for the process to complete\n const exitPromise = new Promise<number>((resolve, reject) => {\n result.on('exit', (code: number) => {\n exitCode = code;\n resolve(code);\n });\n result.on('error', reject);\n });\n\n // Wait for all streams to complete\n await Promise.all([stdoutPromise, stderrPromise, exitPromise]);\n\n return {\n stdout: stdout.trim(),\n stderr: stderr.trim(),\n exitCode: exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: this.sandboxId,\n provider: this.provider\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('timeout')) {\n throw new Error(\n `Vercel execution timeout (${this.timeout}ms). Consider increasing the timeout or optimizing your code.`\n );\n }\n if (error.message.includes('memory') || error.message.includes('Memory')) {\n throw new Error(\n `Vercel execution failed due to memory limits. Consider optimizing your code or using smaller data sets.`\n );\n }\n }\n throw new Error(\n `Vercel execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async doKill(): Promise<void> {\n if (!this.sandbox) {\n return;\n }\n\n try {\n await this.sandbox.stop();\n this.sandbox = null;\n } catch (error) {\n throw new Error(\n `Failed to kill Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async doGetInfo(): Promise<SandboxInfo> {\n await this.ensureSandbox();\n\n return {\n id: this.sandboxId,\n provider: this.provider,\n runtime: this.runtime,\n status: this.sandbox ? 'running' : 'stopped',\n createdAt: new Date(),\n timeout: this.timeout,\n metadata: {\n vercelSandboxId: this.sandboxId,\n teamId: this.teamId,\n projectId: this.projectId,\n vcpus: 2, // Default vCPUs\n region: 'global' // Vercel sandboxes can run globally\n }\n };\n }\n}\n\nexport function vercel(config?: Partial<SandboxConfig>): VercelProvider {\n const fullConfig: SandboxConfig = {\n provider: 'vercel',\n runtime: 'node',\n timeout: 300000,\n ...config\n };\n\n return new VercelProvider(fullConfig);\n}\n"],"mappings":"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","names":["ms","code"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n * \n * Demonstrates the new createProvider() factory pattern with ~50 lines\n * instead of the original ~350 lines of boilerplate.\n */\n\nimport { Sandbox as VercelSandbox } from '@vercel/sandbox';\nimport { createProvider } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions, FileEntry } from 'computesdk';\n\n/**\n * Vercel-specific configuration options\n */\nexport interface VercelConfig {\n /** Vercel API token - if not provided, will fallback to VERCEL_TOKEN environment variable */\n token?: string;\n /** Vercel team ID - if not provided, will fallback to VERCEL_TEAM_ID environment variable */\n teamId?: string;\n /** Vercel project ID - if not provided, will fallback to VERCEL_PROJECT_ID environment variable */\n projectId?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n\n\n/**\n * Create a Vercel provider instance using the factory pattern\n */\nexport const vercel = createProvider<VercelSandbox, VercelConfig>({\n name: 'vercel',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: VercelConfig, options?: CreateSandboxOptions) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n \n // Fall back to traditional method (token + teamId + projectId)\n const token = config.token || (typeof process !== 'undefined' && process.env?.VERCEL_TOKEN) || '';\n const teamId = config.teamId || (typeof process !== 'undefined' && process.env?.VERCEL_TEAM_ID) || '';\n const projectId = config.projectId || (typeof process !== 'undefined' && process.env?.VERCEL_PROJECT_ID) || '';\n \n // Validate authentication - either OIDC token OR traditional method\n if (!oidcToken && (!token || !teamId || !projectId)) {\n if (!oidcToken && !token) {\n throw new Error(\n `Missing Vercel authentication. Either:\\n` +\n `1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or\\n` +\n `2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n if (!oidcToken && !teamId) {\n throw new Error(\n `Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`\n );\n }\n if (!oidcToken && !projectId) {\n throw new Error(\n `Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`\n );\n }\n }\n\n const runtime = options?.runtime || config.runtime || 'node';\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: VercelSandbox;\n\n if (options?.sandboxId) {\n // Vercel doesn't support reconnecting to existing sandboxes\n // Each sandbox is ephemeral and must be created fresh\n throw new Error(\n `Vercel provider does not support reconnecting to existing sandboxes. Vercel sandboxes are ephemeral and must be created fresh each time.`\n );\n } else {\n // Create new Vercel sandbox using the appropriate authentication method\n if (oidcToken) {\n // Use OIDC token method (simpler, recommended)\n sandbox = await VercelSandbox.create();\n } else {\n // Use traditional method (token + teamId + projectId)\n sandbox = await VercelSandbox.create({\n token,\n teamId,\n projectId,\n });\n }\n }\n\n return {\n sandbox,\n sandboxId: sandbox.sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('token')) {\n throw new Error(\n `Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n if (error.message.includes('team') || error.message.includes('project')) {\n throw new Error(\n `Vercel team/project configuration failed. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`\n );\n }\n }\n throw new Error(\n `Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: VercelConfig, sandboxId: string) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n \n try {\n let sandbox: VercelSandbox;\n \n if (oidcToken) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n const token = config.token || process.env.VERCEL_TOKEN!;\n const teamId = config.teamId || process.env.VERCEL_TEAM_ID!;\n const projectId = config.projectId || process.env.VERCEL_PROJECT_ID!;\n \n sandbox = await VercelSandbox.get({\n sandboxId,\n token,\n teamId,\n projectId,\n });\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: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing sandboxes. Vercel sandboxes are ephemeral and designed for single-use execution. Consider using a provider with persistent sandbox management like E2B.`\n );\n },\n\n destroy: async (config: VercelConfig, sandboxId: string) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n \n try {\n let sandbox: VercelSandbox;\n \n if (oidcToken) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n const token = config.token || process.env.VERCEL_TOKEN!;\n const teamId = config.teamId || process.env.VERCEL_TEAM_ID!;\n const projectId = config.projectId || process.env.VERCEL_PROJECT_ID!;\n \n sandbox = await VercelSandbox.get({\n sandboxId,\n token,\n teamId,\n projectId,\n });\n }\n \n await sandbox.stop();\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: VercelSandbox, code: string, runtime?: Runtime, config?: VercelConfig): Promise<ExecutionResult> => {\n const startTime = Date.now();\n \n try {\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || config?.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 ? '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 let command;\n \n if (effectiveRuntime === 'python') {\n // Execute Python code with base64 encoding\n command = await sandbox.runCommand('sh', ['-c', `echo \"${encoded}\" | base64 -d | python3`]);\n } else {\n // Execute Node.js code with base64 encoding\n command = await sandbox.runCommand('sh', ['-c', `echo \"${encoded}\" | base64 -d | node`]);\n }\n\n // Wait for command to complete and get exit code\n const finishedCommand = await command.wait();\n\n // Use single logs() iteration to avoid \"multiple consumers\" warning\n let stdout = '';\n let stderr = '';\n \n // Single iteration through logs to collect both stdout and stderr\n for await (const log of finishedCommand.logs()) {\n if (log.stream === 'stdout') {\n stdout += log.data;\n } else if (log.stream === 'stderr') {\n stderr += log.data;\n }\n }\n\n // Check for syntax errors and throw them (similar to E2B behavior)\n if (finishedCommand.exitCode !== 0 && stderr) {\n // Check for common syntax error patterns\n if (stderr.includes('SyntaxError') || \n stderr.includes('invalid syntax') ||\n stderr.includes('Unexpected token') ||\n stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${stderr.trim()}`);\n }\n }\n\n return {\n stdout,\n stderr,\n exitCode: finishedCommand.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\n };\n } catch (error) {\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Vercel execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: VercelSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n const cmd = await sandbox.runCommand(command, args);\n \n // Wait for command to complete and get exit code\n const finishedCommand = await cmd.wait();\n\n // Use logs() iterator to avoid \"multiple consumers\" warning\n let stdout = '';\n let stderr = '';\n \n for await (const log of finishedCommand.logs()) {\n if (log.stream === 'stdout') {\n stdout += log.data;\n } else if (log.stream === 'stderr') {\n stderr += log.data;\n }\n }\n\n return {\n stdout,\n stderr,\n exitCode: finishedCommand.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\n };\n } catch (error) {\n // For command execution, return error result instead of throwing\n // This handles cases like \"command not found\" where Vercel API returns 400\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127, // Standard \"command not found\" exit code\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\n };\n }\n },\n\n getInfo: async (sandbox: VercelSandbox): Promise<SandboxInfo> => {\n return {\n id: 'vercel-unknown',\n provider: 'vercel',\n runtime: 'node', // Vercel default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n vercelSandboxId: 'vercel-unknown'\n }\n };\n },\n\n // Optional filesystem methods - Vercel has shell-based filesystem support\n filesystem: {\n readFile: async (sandbox: VercelSandbox, path: string): Promise<string> => {\n const cmd = await sandbox.runCommand('cat', [path]);\n const finishedCommand = await cmd.wait();\n \n if (finishedCommand.exitCode !== 0) {\n let stderr = '';\n for await (const log of finishedCommand.logs()) {\n if (log.stream === 'stderr') {\n stderr += log.data;\n }\n }\n throw new Error(`Failed to read file ${path}: ${stderr}`);\n }\n \n let content = '';\n for await (const log of finishedCommand.logs()) {\n if (log.stream === 'stdout') {\n content += log.data;\n }\n }\n // Trim trailing newline that cat command adds\n return content.replace(/\\n$/, '');\n },\n\n writeFile: async (sandbox: VercelSandbox, path: string, content: string): Promise<void> => {\n const cmd = await sandbox.runCommand('sh', ['-c', `echo ${JSON.stringify(content)} > ${JSON.stringify(path)}`]);\n const finishedCommand = await cmd.wait();\n \n if (finishedCommand.exitCode !== 0) {\n let stderr = '';\n for await (const log of finishedCommand.logs()) {\n if (log.stream === 'stderr') {\n stderr += log.data;\n }\n }\n throw new Error(`Failed to write file ${path}: ${stderr}`);\n }\n },\n\n mkdir: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n const cmd = await sandbox.runCommand('mkdir', ['-p', path]);\n const finishedCommand = await cmd.wait();\n \n if (finishedCommand.exitCode !== 0) {\n let stderr = '';\n for await (const log of finishedCommand.logs()) {\n if (log.stream === 'stderr') {\n stderr += log.data;\n }\n }\n throw new Error(`Failed to create directory ${path}: ${stderr}`);\n }\n },\n\n readdir: async (sandbox: VercelSandbox, path: string): Promise<FileEntry[]> => {\n const cmd = await sandbox.runCommand('ls', ['-la', path]);\n const finishedCommand = await cmd.wait();\n \n let stdout = '';\n let stderr = '';\n \n // Single iteration through logs to collect both stdout and stderr\n for await (const log of finishedCommand.logs()) {\n if (log.stream === 'stdout') {\n stdout += log.data;\n } else if (log.stream === 'stderr') {\n stderr += log.data;\n }\n }\n \n if (finishedCommand.exitCode !== 0) {\n throw new Error(`Failed to list directory ${path}: ${stderr}`);\n }\n \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 name = parts[parts.length - 1];\n const isDirectory = line.startsWith('d');\n \n return {\n name,\n path: `${path}/${name}`,\n isDirectory,\n size: parseInt(parts[4]) || 0,\n lastModified: new Date()\n };\n });\n },\n\n exists: async (sandbox: VercelSandbox, path: string): Promise<boolean> => {\n const cmd = await sandbox.runCommand('test', ['-e', path]);\n const finishedCommand = await cmd.wait();\n return finishedCommand.exitCode === 0; // Exit code 0 means file exists\n },\n\n remove: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n const cmd = await sandbox.runCommand('rm', ['-rf', path]);\n const finishedCommand = await cmd.wait();\n \n if (finishedCommand.exitCode !== 0) {\n let stderr = '';\n for await (const log of finishedCommand.logs()) {\n if (log.stream === 'stderr') {\n stderr += log.data;\n }\n }\n throw new Error(`Failed to remove ${path}: ${stderr}`);\n }\n }\n }\n }\n }\n});"],"mappings":"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","names":["VercelSandbox"]}