@computesdk/vercel 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 computesdk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,336 @@
1
+ # @computesdk/vercel
2
+
3
+ Vercel Sandbox provider for ComputeSDK - Execute Node.js and Python code in secure, isolated Vercel sandboxes.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @computesdk/vercel
9
+ ```
10
+
11
+ ## Prerequisites
12
+
13
+ You need the following environment variables set:
14
+
15
+ - `VERCEL_TOKEN` - Your Vercel access token (get from [Vercel Account Tokens](https://vercel.com/account/tokens))
16
+ - `VERCEL_TEAM_ID` - Your Vercel team ID
17
+ - `VERCEL_PROJECT_ID` - Your Vercel project ID
18
+
19
+ ## Quick Start
20
+
21
+ ### Basic Usage
22
+
23
+ ```typescript
24
+ import { vercel } from '@computesdk/vercel';
25
+
26
+ // Create sandbox with default Node.js runtime
27
+ const sandbox = vercel();
28
+
29
+ // Execute Node.js code
30
+ const result = await sandbox.doExecute('console.log("Hello from Vercel!");');
31
+ console.log(result.stdout); // "Hello from Vercel!"
32
+
33
+ // Clean up
34
+ await sandbox.doKill();
35
+ ```
36
+
37
+ ### Python Runtime
38
+
39
+ ```typescript
40
+ import { vercel } from '@computesdk/vercel';
41
+
42
+ // Create sandbox with Python runtime
43
+ const sandbox = vercel({ runtime: 'python' });
44
+
45
+ // Execute Python code
46
+ const result = await sandbox.doExecute('print("Hello from Python on Vercel!")');
47
+ console.log(result.stdout); // "Hello from Python on Vercel!"
48
+
49
+ await sandbox.doKill();
50
+ ```
51
+
52
+ ### With ComputeSDK
53
+
54
+ ```typescript
55
+ import { vercel } from '@computesdk/vercel';
56
+ import { executeSandbox } from 'computesdk';
57
+
58
+ // One-off execution
59
+ const result = await executeSandbox({
60
+ sandbox: vercel({ runtime: 'python' }),
61
+ code: `
62
+ import json
63
+ import datetime
64
+
65
+ data = {
66
+ "timestamp": datetime.datetime.now().isoformat(),
67
+ "message": "Hello from Vercel Sandbox"
68
+ }
69
+
70
+ print(json.dumps(data, indent=2))
71
+ `
72
+ });
73
+
74
+ console.log(result.stdout);
75
+ ```
76
+
77
+ ## Configuration
78
+
79
+ ### Options
80
+
81
+ ```typescript
82
+ interface SandboxConfig {
83
+ runtime?: 'node' | 'python'; // Default: 'node'
84
+ timeout?: number; // Default: 300000 (5 minutes)
85
+ provider?: string; // Default: 'vercel'
86
+ }
87
+ ```
88
+
89
+ ### Example with Custom Configuration
90
+
91
+ ```typescript
92
+ const sandbox = vercel({
93
+ runtime: 'python',
94
+ timeout: 600000, // 10 minutes
95
+ });
96
+ ```
97
+
98
+ ## Features
99
+
100
+ ### Supported Runtimes
101
+
102
+ - **Node.js 22** (`node`) - Default runtime
103
+ - **Python 3.13** (`python`) - Full Python environment
104
+
105
+ ### Capabilities
106
+
107
+ - ✅ **Isolated execution** - Each sandbox runs in its own secure environment
108
+ - ✅ **Long-running tasks** - Up to 45 minutes execution time
109
+ - ✅ **Standard libraries** - Node.js and Python standard libraries included
110
+ - ✅ **Error handling** - Comprehensive error reporting
111
+ - ✅ **Stream support** - Real-time stdout/stderr capture
112
+ - ✅ **Global deployment** - Runs on Vercel's global infrastructure
113
+
114
+ ### Limitations
115
+
116
+ - Maximum execution time: 45 minutes (configurable)
117
+ - Maximum 8 vCPUs per sandbox (default: 2 vCPUs)
118
+ - Memory allocation: 2048 MB per vCPU
119
+
120
+ ## API Reference
121
+
122
+ ### `vercel(config?)`
123
+
124
+ Creates a new Vercel sandbox provider.
125
+
126
+ **Parameters:**
127
+ - `config` (optional): Configuration object
128
+
129
+ **Returns:** `VercelProvider` instance
130
+
131
+ ### `sandbox.doExecute(code, runtime?)`
132
+
133
+ Executes code in the sandbox.
134
+
135
+ **Parameters:**
136
+ - `code`: String containing the code to execute
137
+ - `runtime` (optional): Runtime to use ('node' | 'python')
138
+
139
+ **Returns:** `Promise<ExecutionResult>`
140
+
141
+ ```typescript
142
+ interface ExecutionResult {
143
+ stdout: string;
144
+ stderr: string;
145
+ exitCode: number;
146
+ executionTime: number;
147
+ sandboxId: string;
148
+ provider: string;
149
+ }
150
+ ```
151
+
152
+ ### `sandbox.doGetInfo()`
153
+
154
+ Gets information about the sandbox.
155
+
156
+ **Returns:** `Promise<SandboxInfo>`
157
+
158
+ ```typescript
159
+ interface SandboxInfo {
160
+ id: string;
161
+ provider: string;
162
+ runtime: string;
163
+ status: 'running' | 'stopped';
164
+ createdAt: Date;
165
+ timeout: number;
166
+ metadata: {
167
+ vercelSandboxId: string;
168
+ teamId: string;
169
+ projectId: string;
170
+ vcpus: number;
171
+ region: string;
172
+ };
173
+ }
174
+ ```
175
+
176
+ ### `sandbox.doKill()`
177
+
178
+ Terminates the sandbox.
179
+
180
+ **Returns:** `Promise<void>`
181
+
182
+ ## Examples
183
+
184
+ ### Node.js Web Server Simulation
185
+
186
+ ```typescript
187
+ import { vercel } from '@computesdk/vercel';
188
+
189
+ const sandbox = vercel({ runtime: 'node' });
190
+
191
+ const result = await sandbox.doExecute(`
192
+ const http = require('http');
193
+ const url = require('url');
194
+
195
+ // Simulate API endpoints
196
+ const routes = {
197
+ '/api/users': () => ({
198
+ users: [
199
+ { id: 1, name: 'Alice', role: 'Developer' },
200
+ { id: 2, name: 'Bob', role: 'Designer' }
201
+ ]
202
+ }),
203
+ '/api/health': () => ({ status: 'healthy', timestamp: new Date().toISOString() })
204
+ };
205
+
206
+ // Process request
207
+ const path = '/api/users';
208
+ const response = routes[path] ? routes[path]() : { error: 'Not found' };
209
+
210
+ console.log('Response:', JSON.stringify(response, null, 2));
211
+ `);
212
+
213
+ console.log(result.stdout);
214
+ ```
215
+
216
+ ### Python Data Processing
217
+
218
+ ```typescript
219
+ import { vercel } from '@computesdk/vercel';
220
+
221
+ const sandbox = vercel({ runtime: 'python' });
222
+
223
+ const result = await sandbox.doExecute(`
224
+ import json
225
+ import statistics
226
+ from collections import Counter
227
+
228
+ # Sample data
229
+ sales_data = [
230
+ {"product": "laptop", "quantity": 5, "price": 999},
231
+ {"product": "mouse", "quantity": 20, "price": 25},
232
+ {"product": "keyboard", "quantity": 15, "price": 75},
233
+ {"product": "laptop", "quantity": 3, "price": 999},
234
+ {"product": "mouse", "quantity": 10, "price": 25}
235
+ ]
236
+
237
+ # Aggregate sales
238
+ product_sales = {}
239
+ for sale in sales_data:
240
+ product = sale["product"]
241
+ revenue = sale["quantity"] * sale["price"]
242
+ product_sales[product] = product_sales.get(product, 0) + revenue
243
+
244
+ # Calculate statistics
245
+ revenues = list(product_sales.values())
246
+ total_revenue = sum(revenues)
247
+ avg_revenue = statistics.mean(revenues)
248
+
249
+ print(f"Total Revenue: ${total_revenue}")
250
+ print(f"Average Revenue per Product: ${avg_revenue:.2f}")
251
+ print("\\nRevenue by Product:")
252
+ for product, revenue in sorted(product_sales.items(), key=lambda x: x[1], reverse=True):
253
+ print(f" {product}: ${revenue}")
254
+ `);
255
+
256
+ console.log(result.stdout);
257
+ ```
258
+
259
+ ## Error Handling
260
+
261
+ The provider includes comprehensive error handling:
262
+
263
+ ```typescript
264
+ import { vercel } from '@computesdk/vercel';
265
+
266
+ try {
267
+ const sandbox = vercel();
268
+ const result = await sandbox.doExecute('invalid syntax here');
269
+ } catch (error) {
270
+ if (error.message.includes('timeout')) {
271
+ console.error('Execution timed out');
272
+ } else if (error.message.includes('memory')) {
273
+ console.error('Memory limit exceeded');
274
+ } else if (error.message.includes('authentication')) {
275
+ console.error('Check your VERCEL_TOKEN');
276
+ } else {
277
+ console.error('Execution failed:', error.message);
278
+ }
279
+ }
280
+ ```
281
+
282
+ ## Authentication Setup
283
+
284
+ 1. **Get Vercel Token:**
285
+ - Go to [Vercel Account Tokens](https://vercel.com/account/tokens)
286
+ - Create a new token with appropriate permissions
287
+ - Set as `VERCEL_TOKEN` environment variable
288
+
289
+ 2. **Get Team and Project IDs:**
290
+ - Find your team ID in the Vercel dashboard URL
291
+ - Find your project ID in the project settings
292
+ - Set as `VERCEL_TEAM_ID` and `VERCEL_PROJECT_ID`
293
+
294
+ 3. **Environment Variables:**
295
+ ```bash
296
+ export VERCEL_TOKEN=your_vercel_token_here
297
+ export VERCEL_TEAM_ID=your_team_id_here
298
+ export VERCEL_PROJECT_ID=your_project_id_here
299
+ ```
300
+
301
+ ## Testing
302
+
303
+ Run the test suite:
304
+
305
+ ```bash
306
+ npm test
307
+ ```
308
+
309
+ Run tests with coverage:
310
+
311
+ ```bash
312
+ npm run test:coverage
313
+ ```
314
+
315
+ ## Development
316
+
317
+ Build the package:
318
+
319
+ ```bash
320
+ npm run build
321
+ ```
322
+
323
+ Run in development mode:
324
+
325
+ ```bash
326
+ npm run dev
327
+ ```
328
+
329
+ ## License
330
+
331
+ MIT - see LICENSE file for details.
332
+
333
+ ## Support
334
+
335
+ - [GitHub Issues](https://github.com/computesdk/computesdk/issues)
336
+ - [ComputeSDK Documentation](https://github.com/computesdk/computesdk)
@@ -0,0 +1,21 @@
1
+ import { ComputeSpecification, SandboxConfig, Runtime, ExecutionResult, SandboxInfo } from 'computesdk';
2
+
3
+ declare class VercelProvider implements ComputeSpecification {
4
+ readonly specificationVersion: "v1";
5
+ readonly provider = "vercel";
6
+ readonly sandboxId: string;
7
+ private sandbox;
8
+ private readonly token;
9
+ private readonly teamId;
10
+ private readonly projectId;
11
+ private readonly runtime;
12
+ private readonly timeout;
13
+ constructor(config: SandboxConfig);
14
+ private ensureSandbox;
15
+ doExecute(code: string, runtime?: Runtime): Promise<ExecutionResult>;
16
+ doKill(): Promise<void>;
17
+ doGetInfo(): Promise<SandboxInfo>;
18
+ }
19
+ declare function vercel(config?: Partial<SandboxConfig>): VercelProvider;
20
+
21
+ export { VercelProvider, vercel };
@@ -0,0 +1,21 @@
1
+ import { ComputeSpecification, SandboxConfig, Runtime, ExecutionResult, SandboxInfo } from 'computesdk';
2
+
3
+ declare class VercelProvider implements ComputeSpecification {
4
+ readonly specificationVersion: "v1";
5
+ readonly provider = "vercel";
6
+ readonly sandboxId: string;
7
+ private sandbox;
8
+ private readonly token;
9
+ private readonly teamId;
10
+ private readonly projectId;
11
+ private readonly runtime;
12
+ private readonly timeout;
13
+ constructor(config: SandboxConfig);
14
+ private ensureSandbox;
15
+ doExecute(code: string, runtime?: Runtime): Promise<ExecutionResult>;
16
+ doKill(): Promise<void>;
17
+ doGetInfo(): Promise<SandboxInfo>;
18
+ }
19
+ declare function vercel(config?: Partial<SandboxConfig>): VercelProvider;
20
+
21
+ export { VercelProvider, vercel };
package/dist/index.js ADDED
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
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
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ VercelProvider: () => VercelProvider,
34
+ vercel: () => vercel
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+ 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
+ );
88
+ }
89
+ if (error.message.includes("team") || error.message.includes("project")) {
90
+ throw new Error(
91
+ `Vercel team/project configuration error. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`
92
+ );
93
+ }
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
+ );
98
+ }
99
+ if (error.message.includes("quota") || error.message.includes("limit")) {
100
+ throw new Error(
101
+ `Vercel quota exceeded. Please check your usage in the Vercel dashboard.`
102
+ );
103
+ }
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();
144
+ }
145
+ });
146
+ const stderrPromise = new Promise((resolve) => {
147
+ if (result.stderr) {
148
+ result.stderr.on("data", (data) => {
149
+ stderr += data.toString();
150
+ });
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
+ );
183
+ }
184
+ }
185
+ throw new Error(
186
+ `Vercel execution failed: ${error instanceof Error ? error.message : String(error)}`
187
+ );
188
+ }
189
+ }
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
+ }
233
+ // Annotate the CommonJS export names for ESM import in node:
234
+ 0 && (module.exports = {
235
+ VercelProvider,
236
+ vercel
237
+ });
238
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,202 @@
1
+ // src/index.ts
2
+ import { Sandbox } from "@vercel/sandbox";
3
+ import ms from "ms";
4
+ var VercelProvider = class {
5
+ constructor(config) {
6
+ this.specificationVersion = "v1";
7
+ this.provider = "vercel";
8
+ this.sandbox = null;
9
+ this.sandboxId = `vercel-${Date.now()}-${Math.random().toString(36).substring(7)}`;
10
+ this.timeout = config.timeout || 3e5;
11
+ this.token = process.env.VERCEL_TOKEN || "";
12
+ this.teamId = process.env.VERCEL_TEAM_ID || "";
13
+ this.projectId = process.env.VERCEL_PROJECT_ID || "";
14
+ if (!this.token) {
15
+ throw new Error(
16
+ `Missing Vercel token. Set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
17
+ );
18
+ }
19
+ if (!this.teamId) {
20
+ throw new Error(
21
+ `Missing Vercel team ID. Set VERCEL_TEAM_ID environment variable.`
22
+ );
23
+ }
24
+ if (!this.projectId) {
25
+ throw new Error(
26
+ `Missing Vercel project ID. Set VERCEL_PROJECT_ID environment variable.`
27
+ );
28
+ }
29
+ if (config.runtime && !["node", "python"].includes(config.runtime)) {
30
+ throw new Error("Vercel provider only supports Node.js and Python runtimes");
31
+ }
32
+ this.runtime = config.runtime || "node";
33
+ }
34
+ async ensureSandbox() {
35
+ if (this.sandbox) {
36
+ return this.sandbox;
37
+ }
38
+ try {
39
+ const runtimeImage = this.runtime === "node" ? "node22" : "python3.13";
40
+ this.sandbox = await Sandbox.create({
41
+ runtime: runtimeImage,
42
+ timeout: ms(`${this.timeout}ms`),
43
+ resources: { vcpus: 2 }
44
+ // Default to 2 vCPUs
45
+ });
46
+ return this.sandbox;
47
+ } catch (error) {
48
+ if (error instanceof Error) {
49
+ if (error.message.includes("unauthorized") || error.message.includes("token")) {
50
+ throw new Error(
51
+ `Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
52
+ );
53
+ }
54
+ if (error.message.includes("team") || error.message.includes("project")) {
55
+ throw new Error(
56
+ `Vercel team/project configuration error. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`
57
+ );
58
+ }
59
+ if (error.message.includes("Memory limit exceeded")) {
60
+ throw new Error(
61
+ `Vercel execution failed due to memory limits. Consider optimizing your code or using smaller data sets.`
62
+ );
63
+ }
64
+ if (error.message.includes("quota") || error.message.includes("limit")) {
65
+ throw new Error(
66
+ `Vercel quota exceeded. Please check your usage in the Vercel dashboard.`
67
+ );
68
+ }
69
+ }
70
+ throw new Error(
71
+ `Failed to initialize Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`
72
+ );
73
+ }
74
+ }
75
+ async doExecute(code, runtime) {
76
+ if (runtime && !["node", "python"].includes(runtime)) {
77
+ throw new Error("Vercel provider only supports Node.js and Python runtimes");
78
+ }
79
+ const startTime = Date.now();
80
+ const actualRuntime = runtime || this.runtime;
81
+ try {
82
+ const sandbox = await this.ensureSandbox();
83
+ let command;
84
+ let args = [];
85
+ if (actualRuntime === "node") {
86
+ command = "node";
87
+ args = ["-e", code];
88
+ } else if (actualRuntime === "python") {
89
+ command = "python";
90
+ args = ["-c", code];
91
+ } else {
92
+ throw new Error(`Unsupported runtime: ${actualRuntime}`);
93
+ }
94
+ const result = await sandbox.runCommand({
95
+ cmd: command,
96
+ args
97
+ });
98
+ let stdout = "";
99
+ let stderr = "";
100
+ let exitCode = 0;
101
+ const stdoutPromise = new Promise((resolve) => {
102
+ if (result.stdout) {
103
+ result.stdout.on("data", (data) => {
104
+ stdout += data.toString();
105
+ });
106
+ result.stdout.on("end", resolve);
107
+ } else {
108
+ resolve();
109
+ }
110
+ });
111
+ const stderrPromise = new Promise((resolve) => {
112
+ if (result.stderr) {
113
+ result.stderr.on("data", (data) => {
114
+ stderr += data.toString();
115
+ });
116
+ result.stderr.on("end", resolve);
117
+ } else {
118
+ resolve();
119
+ }
120
+ });
121
+ const exitPromise = new Promise((resolve, reject) => {
122
+ result.on("exit", (code2) => {
123
+ exitCode = code2;
124
+ resolve(code2);
125
+ });
126
+ result.on("error", reject);
127
+ });
128
+ await Promise.all([stdoutPromise, stderrPromise, exitPromise]);
129
+ return {
130
+ stdout: stdout.trim(),
131
+ stderr: stderr.trim(),
132
+ exitCode,
133
+ executionTime: Date.now() - startTime,
134
+ sandboxId: this.sandboxId,
135
+ provider: this.provider
136
+ };
137
+ } catch (error) {
138
+ if (error instanceof Error) {
139
+ if (error.message.includes("timeout")) {
140
+ throw new Error(
141
+ `Vercel execution timeout (${this.timeout}ms). Consider increasing the timeout or optimizing your code.`
142
+ );
143
+ }
144
+ if (error.message.includes("memory") || error.message.includes("Memory")) {
145
+ throw new Error(
146
+ `Vercel execution failed due to memory limits. Consider optimizing your code or using smaller data sets.`
147
+ );
148
+ }
149
+ }
150
+ throw new Error(
151
+ `Vercel execution failed: ${error instanceof Error ? error.message : String(error)}`
152
+ );
153
+ }
154
+ }
155
+ async doKill() {
156
+ if (!this.sandbox) {
157
+ return;
158
+ }
159
+ try {
160
+ await this.sandbox.stop();
161
+ this.sandbox = null;
162
+ } catch (error) {
163
+ throw new Error(
164
+ `Failed to kill Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`
165
+ );
166
+ }
167
+ }
168
+ async doGetInfo() {
169
+ await this.ensureSandbox();
170
+ return {
171
+ id: this.sandboxId,
172
+ provider: this.provider,
173
+ runtime: this.runtime,
174
+ status: this.sandbox ? "running" : "stopped",
175
+ createdAt: /* @__PURE__ */ new Date(),
176
+ timeout: this.timeout,
177
+ metadata: {
178
+ vercelSandboxId: this.sandboxId,
179
+ teamId: this.teamId,
180
+ projectId: this.projectId,
181
+ vcpus: 2,
182
+ // Default vCPUs
183
+ region: "global"
184
+ // Vercel sandboxes can run globally
185
+ }
186
+ };
187
+ }
188
+ };
189
+ function vercel(config) {
190
+ const fullConfig = {
191
+ provider: "vercel",
192
+ runtime: "node",
193
+ timeout: 3e5,
194
+ ...config
195
+ };
196
+ return new VercelProvider(fullConfig);
197
+ }
198
+ export {
199
+ VercelProvider,
200
+ vercel
201
+ };
202
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +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":["code"]}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@computesdk/vercel",
3
+ "version": "1.0.0",
4
+ "description": "Vercel Sandbox provider for ComputeSDK",
5
+ "author": "Garrison",
6
+ "license": "MIT",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.mjs",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "dependencies": {
21
+ "@vercel/sandbox": "^0.0.13",
22
+ "ms": "^2.1.3"
23
+ },
24
+ "peerDependencies": {
25
+ "computesdk": "1.0.0"
26
+ },
27
+ "keywords": [
28
+ "vercel",
29
+ "sandbox",
30
+ "code-execution",
31
+ "nodejs",
32
+ "python",
33
+ "cloud",
34
+ "compute"
35
+ ],
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/computesdk/computesdk.git",
39
+ "directory": "packages/vercel"
40
+ },
41
+ "homepage": "https://github.com/computesdk/computesdk/tree/main/packages/vercel",
42
+ "bugs": {
43
+ "url": "https://github.com/computesdk/computesdk/issues"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^20.0.0",
47
+ "@types/ms": "^0.7.34",
48
+ "@vitest/coverage-v8": "^1.0.0",
49
+ "eslint": "^8.37.0",
50
+ "rimraf": "^5.0.0",
51
+ "tsup": "^8.0.0",
52
+ "typescript": "^5.0.0",
53
+ "vitest": "^1.0.0"
54
+ },
55
+ "scripts": {
56
+ "build": "tsup",
57
+ "dev": "tsup --watch",
58
+ "test": "vitest",
59
+ "typecheck": "tsc --noEmit",
60
+ "lint": "eslint ."
61
+ }
62
+ }