@computesdk/vercel 1.7.25 → 1.7.27

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
@@ -37,39 +37,13 @@ Get your token from [Vercel Account Tokens](https://vercel.com/account/tokens)
37
37
 
38
38
  ## Quick Start
39
39
 
40
- ### Gateway Mode (Recommended)
41
-
42
- Use the gateway for zero-config auto-detection:
43
-
44
- ```typescript
45
- import { compute } from 'computesdk';
46
-
47
- // Auto-detects Vercel from VERCEL_OIDC_TOKEN or VERCEL_TOKEN environment variables
48
- const sandbox = await compute.sandbox.create();
49
-
50
- // Execute Node.js command
51
- const result = await sandbox.runCommand('node -e "console.log(\"Hello from Vercel!\")"');
52
- console.log(result.stdout); // "Hello from Vercel!"
53
-
54
- // Execute Python command
55
- const pythonResult = await sandbox.runCommand('python -c "print(\"Hello from Python!\")"');
56
- console.log(pythonResult.stdout); // "Hello from Python!"
57
-
58
- await sandbox.destroy();
59
- ```
60
-
61
- ### Direct Mode
62
-
63
- For direct SDK usage without the gateway:
64
-
65
40
  ```typescript
66
41
  import { vercel } from '@computesdk/vercel';
67
42
 
68
43
  const compute = vercel({
69
44
  token: process.env.VERCEL_TOKEN,
70
- teamId: process.env.VERCEL_TEAM_ID,
45
+ teamId: process.env.VERCEL_TEAM_ID,
71
46
  projectId: process.env.VERCEL_PROJECT_ID,
72
- runtime: 'python',
73
47
  timeout: 600000 // 10 minutes
74
48
  });
75
49
 
@@ -81,6 +55,8 @@ console.log(result.stdout);
81
55
  await sandbox.destroy();
82
56
  ```
83
57
 
58
+ OIDC tokens (`VERCEL_OIDC_TOKEN`) are auto-detected from the environment when no explicit credentials are provided in config.
59
+
84
60
  ## Configuration
85
61
 
86
62
  ### Environment Variables
@@ -105,19 +81,17 @@ interface VercelConfig {
105
81
  teamId?: string;
106
82
  /** Vercel project ID - if not provided, will use VERCEL_PROJECT_ID env var */
107
83
  projectId?: string;
108
- /** Default runtime environment */
109
- runtime?: 'node' | 'python';
110
84
  /** Execution timeout in milliseconds */
111
85
  timeout?: number;
86
+ /** Ports to expose */
87
+ ports?: number[];
112
88
  }
113
89
  ```
114
90
 
115
91
  ## Features
116
92
 
117
- - ✅ **Code Execution** - Node.js 22 and Python 3.13 runtime support
118
- - ✅ **Command Execution** - Run shell commands in sandbox
93
+ - ✅ **Command Execution** - Run shell commands in sandbox (Node.js 22, Python 3.13 available)
119
94
  - ✅ **Filesystem Operations** - Full file system access via shell commands
120
- - ✅ **Auto Runtime Detection** - Automatically detects Python vs Node.js
121
95
  - ✅ **Long-running Tasks** - Up to 45 minutes execution time
122
96
  - ✅ **Global Infrastructure** - Runs on Vercel's global network
123
97
  - ❌ **Interactive Terminals** - Not supported by Vercel Sandbox
@@ -125,40 +99,33 @@ interface VercelConfig {
125
99
 
126
100
  ## API Reference
127
101
 
128
- ### Code Execution
102
+ ### Command Execution
129
103
 
130
104
  ```typescript
131
- // Execute Node.js code
105
+ // Run Node.js code via heredoc
132
106
  const result = await sandbox.runCommand(`node - <<'JS'
133
107
  const data = { message: "Hello from Node.js" };
134
108
  console.log(JSON.stringify(data));
135
109
  JS`);
136
110
 
137
- // Execute Python code
111
+ // Run Python code via heredoc
138
112
  const result = await sandbox.runCommand(`python - <<'PY'
139
113
  import json
140
114
  data = {"message": "Hello from Python"}
141
115
  print(json.dumps(data))
142
116
  PY`);
143
117
 
144
- // Auto-detection (based on code patterns)
145
- const result = await sandbox.runCommand('python -c "print(\"Auto-detected as Python\")"');
146
- ```
147
-
148
- ### Command Execution
149
-
150
- ```typescript
151
118
  // List files
152
- const result = await sandbox.runCommand('ls', ['-la']);
119
+ const result = await sandbox.runCommand('ls -la');
153
120
 
154
121
  // Install packages (Node.js)
155
- const result = await sandbox.runCommand('npm', ['install', 'lodash']);
122
+ const result = await sandbox.runCommand('npm install lodash');
156
123
 
157
124
  // Install packages (Python)
158
- const result = await sandbox.runCommand('pip', ['install', 'requests']);
125
+ const result = await sandbox.runCommand('pip install requests');
159
126
 
160
127
  // Run scripts
161
- const result = await sandbox.runCommand('node', ['script.js']);
128
+ const result = await sandbox.runCommand('node script.js');
162
129
  ```
163
130
 
164
131
  ### Filesystem Operations
@@ -191,27 +158,15 @@ const info = await sandbox.getInfo();
191
158
  console.log(info.id, info.provider, info.status);
192
159
 
193
160
  // Get existing sandbox
194
- const existing = await compute.sandbox.getById(provider, 'sandbox-id');
161
+ const existing = await compute.sandbox.getById('sandbox-id');
195
162
 
196
163
  // Destroy sandbox
197
- await compute.sandbox.destroy(provider, 'sandbox-id');
164
+ await compute.sandbox.destroy('sandbox-id');
198
165
 
199
166
  // Note: Vercel doesn't support listing all sandboxes
200
167
  // Each sandbox is ephemeral and single-use
201
168
  ```
202
169
 
203
- ## Runtime Detection
204
-
205
- The provider automatically detects the runtime based on code patterns:
206
-
207
- **Python indicators:**
208
- - `print(` statements
209
- - `import` statements
210
- - `def` function definitions
211
- - Python-specific syntax (`f"`, `__`, etc.)
212
-
213
- **Default:** Node.js for all other cases
214
-
215
170
  ## Error Handling
216
171
 
217
172
  ```typescript
@@ -246,7 +201,7 @@ try {
246
201
  ```typescript
247
202
  import { vercel } from '@computesdk/vercel';
248
203
 
249
- const compute = vercel({ runtime: 'node' });
204
+ const compute = vercel({});
250
205
  const sandbox = await compute.sandbox.create();
251
206
 
252
207
  const result = await sandbox.runCommand(`node - <<'JS'
@@ -283,7 +238,7 @@ await sandbox.destroy();
283
238
  ```typescript
284
239
  import { vercel } from '@computesdk/vercel';
285
240
 
286
- const compute = vercel({ runtime: 'python' });
241
+ const compute = vercel({});
287
242
  const sandbox = await compute.sandbox.create();
288
243
 
289
244
  const result = await sandbox.runCommand(`python - <<'PY'
@@ -328,7 +283,7 @@ await sandbox.destroy();
328
283
  ```typescript
329
284
  import { vercel } from '@computesdk/vercel';
330
285
 
331
- const compute = vercel({ runtime: 'python' });
286
+ const compute = vercel({});
332
287
  const sandbox = await compute.sandbox.create();
333
288
 
334
289
  // Create project structure
@@ -442,11 +397,11 @@ await sandbox.destroy();
442
397
  ```typescript
443
398
  import { vercel } from '@computesdk/vercel';
444
399
 
445
- const compute = vercel({ runtime: 'node' });
400
+ const compute = vercel({});
446
401
  const sandbox = await compute.sandbox.create();
447
402
 
448
403
  // Install lodash
449
- const installResult = await sandbox.runCommand('npm', ['install', 'lodash']);
404
+ const installResult = await sandbox.runCommand('npm install lodash');
450
405
  console.log('Install result:', installResult.stdout);
451
406
 
452
407
  // Use lodash in code
package/dist/index.d.mts CHANGED
@@ -1,28 +1,15 @@
1
1
  import * as _computesdk_provider from '@computesdk/provider';
2
- import { Runtime } from '@computesdk/provider';
3
2
  import { Sandbox, Snapshot } from '@vercel/sandbox';
4
3
  export { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';
5
4
 
6
- /**
7
- * Vercel sandbox provider configuration
8
- */
9
5
  interface VercelConfig {
10
- /** Vercel API token */
11
6
  token?: string;
12
- /** Vercel team ID */
13
7
  teamId?: string;
14
- /** Vercel project ID */
15
8
  projectId?: string;
16
- /** Runtime environment for code execution */
17
- runtime?: Runtime;
18
- /** Execution timeout in milliseconds */
19
9
  timeout?: number;
20
- /** Ports to expose */
21
10
  ports?: number[];
11
+ daemonSsePort?: number | false;
22
12
  }
23
- /**
24
- * Create a Vercel provider instance using the factory pattern
25
- */
26
13
  declare const vercel: (config: VercelConfig) => _computesdk_provider.Provider<Sandbox, any, Snapshot>;
27
14
 
28
15
  export { type VercelConfig, vercel };
package/dist/index.d.ts CHANGED
@@ -1,28 +1,15 @@
1
1
  import * as _computesdk_provider from '@computesdk/provider';
2
- import { Runtime } from '@computesdk/provider';
3
2
  import { Sandbox, Snapshot } from '@vercel/sandbox';
4
3
  export { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';
5
4
 
6
- /**
7
- * Vercel sandbox provider configuration
8
- */
9
5
  interface VercelConfig {
10
- /** Vercel API token */
11
6
  token?: string;
12
- /** Vercel team ID */
13
7
  teamId?: string;
14
- /** Vercel project ID */
15
8
  projectId?: string;
16
- /** Runtime environment for code execution */
17
- runtime?: Runtime;
18
- /** Execution timeout in milliseconds */
19
9
  timeout?: number;
20
- /** Ports to expose */
21
10
  ports?: number[];
11
+ daemonSsePort?: number | false;
22
12
  }
23
- /**
24
- * Create a Vercel provider instance using the factory pattern
25
- */
26
13
  declare const vercel: (config: VercelConfig) => _computesdk_provider.Provider<Sandbox, any, Snapshot>;
27
14
 
28
15
  export { type VercelConfig, vercel };
package/dist/index.js CHANGED
@@ -26,6 +26,13 @@ module.exports = __toCommonJS(index_exports);
26
26
  var import_sandbox = require("@vercel/sandbox");
27
27
  var import_provider = require("@computesdk/provider");
28
28
  var import_node_stream = require("stream");
29
+ var DEFAULT_DAEMON_SSE_PORT = 38989;
30
+ function mergeExposedPorts(primary, fallback, daemonSsePort) {
31
+ const daemonPort = daemonSsePort === false ? void 0 : daemonSsePort ?? DEFAULT_DAEMON_SSE_PORT;
32
+ const merged = [...primary ?? fallback ?? []];
33
+ if (typeof daemonPort === "number") merged.push(daemonPort);
34
+ return Array.from(new Set(merged.filter((port) => Number.isInteger(port) && port > 0 && port <= 65535)));
35
+ }
29
36
  function resolveCredentials(config) {
30
37
  const token = config.token || typeof process !== "undefined" && process.env?.VERCEL_TOKEN || "";
31
38
  const teamId = config.teamId || typeof process !== "undefined" && process.env?.VERCEL_TEAM_ID || "";
@@ -36,26 +43,16 @@ function resolveCredentials(config) {
36
43
  return { useOidc, token, teamId, projectId };
37
44
  }
38
45
  function validateCredentials(creds) {
39
- if (creds.useOidc) {
40
- return;
41
- }
46
+ if (creds.useOidc) return;
42
47
  if (!creds.token) {
43
48
  throw new Error(
44
49
  `Missing Vercel authentication. Either:
45
50
  1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or
46
- 2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
47
- );
48
- }
49
- if (!creds.teamId) {
50
- throw new Error(
51
- `Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`
52
- );
53
- }
54
- if (!creds.projectId) {
55
- throw new Error(
56
- `Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`
51
+ 2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable.`
57
52
  );
58
53
  }
54
+ if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);
55
+ if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);
59
56
  }
60
57
  function getUtf8Sink() {
61
58
  const chunks = [];
@@ -71,18 +68,14 @@ var vercel = (0, import_provider.defineProvider)({
71
68
  name: "vercel",
72
69
  methods: {
73
70
  sandbox: {
74
- // Collection operations (map to compute.sandbox.*)
75
71
  create: async (config, options) => {
76
72
  const creds = resolveCredentials(config);
77
73
  validateCredentials(creds);
78
74
  const timeout = options?.timeout ?? config.timeout ?? 3e5;
79
75
  try {
80
- let sandbox;
81
76
  const {
82
- runtime: optRuntime,
83
77
  timeout: _timeout,
84
78
  envs: _envs,
85
- // Vercel SDK does not support envs at sandbox creation time
86
79
  name: _name,
87
80
  metadata: _metadata,
88
81
  templateId,
@@ -90,29 +83,21 @@ var vercel = (0, import_provider.defineProvider)({
90
83
  sandboxId: _sandboxId,
91
84
  namespace: _namespace,
92
85
  directory: _directory,
93
- ports: optPorts,
94
- source: optSource,
95
86
  ...providerOptions
96
87
  } = options || {};
97
- const params = {
98
- timeout,
99
- ...providerOptions
100
- // Spread provider-specific options (e.g., resources, networkPolicy, signal)
101
- };
102
- const ports = optPorts ?? config.ports;
103
- if (ports && ports.length > 0) {
104
- params.ports = ports;
105
- }
88
+ const optRuntime = options?.runtime;
89
+ const optPorts = options?.ports;
90
+ const optSource = options?.source;
91
+ const params = { timeout, ...providerOptions };
92
+ const optDaemonSsePort = options?.daemonSsePort;
93
+ const ports = mergeExposedPorts(optPorts, config.ports, optDaemonSsePort ?? config.daemonSsePort);
94
+ if (ports && ports.length > 0) params.ports = ports;
106
95
  if (optRuntime) {
107
- const vercelRuntime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
108
- params.runtime = vercelRuntime;
96
+ params.runtime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
109
97
  }
110
98
  const snapshotId = optSnapshotId || templateId || optSource?.type === "snapshot" && optSource?.snapshotId;
111
99
  if (snapshotId) {
112
- params.source = {
113
- type: "snapshot",
114
- snapshotId
115
- };
100
+ params.source = { type: "snapshot", snapshotId };
116
101
  } else if (optSource) {
117
102
  params.source = optSource;
118
103
  }
@@ -121,75 +106,40 @@ var vercel = (0, import_provider.defineProvider)({
121
106
  params.teamId = creds.teamId;
122
107
  params.projectId = creds.projectId;
123
108
  }
124
- sandbox = await import_sandbox.Sandbox.create(params);
125
- return {
126
- sandbox,
127
- sandboxId: sandbox.sandboxId
128
- };
109
+ const sandbox = await import_sandbox.Sandbox.create(params);
110
+ return { sandbox, sandboxId: sandbox.sandboxId };
129
111
  } catch (error) {
130
112
  if (error instanceof Error) {
131
113
  if (error.message.includes("unauthorized") || error.message.includes("token")) {
132
- throw new Error(
133
- `Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
134
- );
114
+ throw new Error(`Vercel authentication failed. Please check your VERCEL_TOKEN environment variable.`);
135
115
  }
136
116
  if (error.message.includes("team") || error.message.includes("project")) {
137
- throw new Error(
138
- `Vercel team/project configuration failed. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`
139
- );
117
+ throw new Error(`Vercel team/project configuration failed. Check VERCEL_TEAM_ID and VERCEL_PROJECT_ID.`);
140
118
  }
141
119
  }
142
- throw new Error(
143
- `Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`
144
- );
120
+ throw new Error(`Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`);
145
121
  }
146
122
  },
147
123
  getById: async (config, sandboxId) => {
148
124
  const creds = resolveCredentials(config);
149
125
  try {
150
- let sandbox;
151
- if (creds.useOidc) {
152
- sandbox = await import_sandbox.Sandbox.get({ sandboxId });
153
- } else {
154
- sandbox = await import_sandbox.Sandbox.get({
155
- sandboxId,
156
- token: creds.token,
157
- teamId: creds.teamId,
158
- projectId: creds.projectId
159
- });
160
- }
161
- return {
162
- sandbox,
163
- sandboxId
164
- };
165
- } catch (error) {
126
+ const sandbox = creds.useOidc ? await import_sandbox.Sandbox.get({ sandboxId }) : await import_sandbox.Sandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
127
+ return { sandbox, sandboxId };
128
+ } catch {
166
129
  return null;
167
130
  }
168
131
  },
169
132
  list: async (_config) => {
170
- throw new Error(
171
- `Vercel provider does not support listing sandboxes. Vercel sandboxes are ephemeral and designed for single-use execution.`
172
- );
133
+ throw new Error(`Vercel provider does not support listing sandboxes.`);
173
134
  },
174
135
  destroy: async (config, sandboxId) => {
175
136
  const creds = resolveCredentials(config);
176
137
  try {
177
- let sandbox;
178
- if (creds.useOidc) {
179
- sandbox = await import_sandbox.Sandbox.get({ sandboxId });
180
- } else {
181
- sandbox = await import_sandbox.Sandbox.get({
182
- sandboxId,
183
- token: creds.token,
184
- teamId: creds.teamId,
185
- projectId: creds.projectId
186
- });
187
- }
138
+ const sandbox = creds.useOidc ? await import_sandbox.Sandbox.get({ sandboxId }) : await import_sandbox.Sandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
188
139
  await sandbox.stop();
189
- } catch (error) {
140
+ } catch {
190
141
  }
191
142
  },
192
- // Instance operations (map to individual Sandbox methods)
193
143
  runCommand: async (sandbox, command, options) => {
194
144
  const startTime = Date.now();
195
145
  try {
@@ -208,35 +158,19 @@ var vercel = (0, import_provider.defineProvider)({
208
158
  stdout: stdout?.sink,
209
159
  stderr: stderr?.sink
210
160
  });
211
- return {
212
- stdout: stdout?.value() ?? "",
213
- stderr: stderr?.value() ?? "",
214
- exitCode: result.exitCode ?? 0,
215
- durationMs: Date.now() - startTime
216
- };
161
+ return { stdout: stdout?.value() ?? "", stderr: stderr?.value() ?? "", exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };
217
162
  } catch (error) {
218
- return {
219
- stdout: "",
220
- stderr: error instanceof Error ? error.message : String(error),
221
- exitCode: 127,
222
- durationMs: Date.now() - startTime
223
- };
163
+ return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
224
164
  }
225
165
  },
226
- getInfo: async (sandbox) => {
227
- return {
228
- id: "vercel-unknown",
229
- provider: "vercel",
230
- runtime: "node",
231
- // Vercel default
232
- status: "running",
233
- createdAt: /* @__PURE__ */ new Date(),
234
- timeout: 3e5,
235
- metadata: {
236
- vercelSandboxId: "vercel-unknown"
237
- }
238
- };
239
- },
166
+ getInfo: async (_sandbox) => ({
167
+ id: "vercel-unknown",
168
+ provider: "vercel",
169
+ status: "running",
170
+ createdAt: /* @__PURE__ */ new Date(),
171
+ timeout: 3e5,
172
+ metadata: { vercelSandboxId: "vercel-unknown" }
173
+ }),
240
174
  getUrl: async (sandbox, options) => {
241
175
  try {
242
176
  let url = sandbox.domain(options.port);
@@ -247,21 +181,15 @@ var vercel = (0, import_provider.defineProvider)({
247
181
  }
248
182
  return url;
249
183
  } catch (error) {
250
- throw new Error(
251
- `Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}. Ensure the port has an associated route.`
252
- );
184
+ throw new Error(`Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}.`);
253
185
  }
254
186
  },
255
187
  filesystem: {
256
188
  readFile: async (sandbox, path) => {
257
189
  const stream = await sandbox.readFile({ path });
258
- if (!stream) {
259
- throw new Error(`File not found: ${path}`);
260
- }
190
+ if (!stream) throw new Error(`File not found: ${path}`);
261
191
  const chunks = [];
262
- for await (const chunk of stream) {
263
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
264
- }
192
+ for await (const chunk of stream) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
265
193
  return Buffer.concat(chunks).toString("utf-8");
266
194
  },
267
195
  writeFile: async (sandbox, path, content) => {
@@ -271,82 +199,42 @@ var vercel = (0, import_provider.defineProvider)({
271
199
  await sandbox.mkDir(path);
272
200
  },
273
201
  readdir: async (_sandbox, _path) => {
274
- throw new Error("Vercel sandbox does not support readdir. Use runCommand to list directory contents.");
202
+ throw new Error("Vercel sandbox does not support readdir.");
275
203
  },
276
204
  exists: async (_sandbox, _path) => {
277
- throw new Error("Vercel sandbox does not support exists. Use runCommand to check file existence.");
205
+ throw new Error("Vercel sandbox does not support exists.");
278
206
  },
279
207
  remove: async (_sandbox, _path) => {
280
- throw new Error("Vercel sandbox does not support remove. Use runCommand to delete files.");
208
+ throw new Error("Vercel sandbox does not support remove.");
281
209
  }
282
210
  },
283
- // Provider-specific typed getInstance method
284
- getInstance: (sandbox) => {
285
- return sandbox;
286
- }
211
+ getInstance: (sandbox) => sandbox
287
212
  },
288
213
  snapshot: {
289
214
  create: async (config, sandboxId) => {
290
215
  const creds = resolveCredentials(config);
291
- let sandbox;
292
- if (creds.useOidc) {
293
- sandbox = await import_sandbox.Sandbox.get({ sandboxId });
294
- } else {
295
- sandbox = await import_sandbox.Sandbox.get({
296
- sandboxId,
297
- token: creds.token,
298
- teamId: creds.teamId,
299
- projectId: creds.projectId
300
- });
301
- }
216
+ const sandbox = creds.useOidc ? await import_sandbox.Sandbox.get({ sandboxId }) : await import_sandbox.Sandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
302
217
  return await sandbox.snapshot();
303
218
  },
304
219
  list: async (_config) => {
305
- throw new Error(
306
- `Vercel provider does not support listing snapshots.`
307
- );
220
+ throw new Error(`Vercel provider does not support listing snapshots.`);
308
221
  },
309
222
  delete: async (config, snapshotId) => {
310
223
  const creds = resolveCredentials(config);
311
- let snapshot;
312
- if (creds.useOidc) {
313
- snapshot = await import_sandbox.Snapshot.get({ snapshotId });
314
- } else {
315
- snapshot = await import_sandbox.Snapshot.get({
316
- snapshotId,
317
- token: creds.token,
318
- teamId: creds.teamId,
319
- projectId: creds.projectId
320
- });
321
- }
224
+ const snapshot = creds.useOidc ? await import_sandbox.Snapshot.get({ snapshotId }) : await import_sandbox.Snapshot.get({ snapshotId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
322
225
  await snapshot.delete();
323
226
  }
324
227
  },
325
- // Vercel doesn't have a separate "template" concept - snapshots serve as templates
326
228
  template: {
327
229
  create: async (_config, _options) => {
328
- throw new Error(
329
- `Vercel does not support creating templates directly. Use snapshot.create() to create a snapshot from a running sandbox.`
330
- );
230
+ throw new Error(`Vercel does not support creating templates directly. Use snapshot.create() instead.`);
331
231
  },
332
232
  list: async (_config) => {
333
- throw new Error(
334
- `Vercel provider does not support listing templates.`
335
- );
233
+ throw new Error(`Vercel provider does not support listing templates.`);
336
234
  },
337
235
  delete: async (config, templateId) => {
338
236
  const creds = resolveCredentials(config);
339
- let snapshot;
340
- if (creds.useOidc) {
341
- snapshot = await import_sandbox.Snapshot.get({ snapshotId: templateId });
342
- } else {
343
- snapshot = await import_sandbox.Snapshot.get({
344
- snapshotId: templateId,
345
- token: creds.token,
346
- teamId: creds.teamId,
347
- projectId: creds.projectId
348
- });
349
- }
237
+ const snapshot = creds.useOidc ? await import_sandbox.Snapshot.get({ snapshotId: templateId }) : await import_sandbox.Snapshot.get({ snapshotId: templateId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
350
238
  await snapshot.delete();
351
239
  }
352
240
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n * \n * Demonstrates the new defineProvider() factory pattern with ~50 lines\n * instead of the original ~350 lines of boilerplate.\n */\n\nimport { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\nimport { Writable } from 'node:stream';\n\nexport type { VercelSandbox, VercelSnapshot };\n\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Vercel sandbox provider configuration\n */\nexport interface VercelConfig {\n /** Vercel API token */\n token?: string;\n /** Vercel team ID */\n teamId?: string;\n /** Vercel project ID */\n projectId?: string;\n /** Runtime environment for code execution */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Ports to expose */\n ports?: number[];\n}\n\n/**\n * Resolved Vercel credentials with the authentication method to use\n */\ninterface ResolvedCredentials {\n /** Whether to use OIDC authentication (no explicit credentials needed) */\n useOidc: boolean;\n /** Token for traditional auth (only used if useOidc is false) */\n token: string;\n /** Team ID for traditional auth (only used if useOidc is false) */\n teamId: string;\n /** Project ID for traditional auth (only used if useOidc is false) */\n projectId: string;\n}\n\n/**\n * Resolve Vercel credentials with proper precedence:\n * 1. Config values (from setConfig) always win\n * 2. Environment variables are used as fallback\n * 3. OIDC is only used when no config credentials are provided\n */\nfunction resolveCredentials(config: VercelConfig): ResolvedCredentials {\n // Get values from config first, then fall back to environment\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 // Check if config explicitly provided credentials (config takes precedence)\n const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);\n \n // Only use OIDC if:\n // 1. No config credentials were provided, AND\n // 2. OIDC token is available in environment\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n const useOidc = !hasConfigCredentials && !!oidcToken;\n \n return { useOidc, token, teamId, projectId };\n}\n\n/**\n * Validate that we have sufficient credentials to authenticate\n */\nfunction validateCredentials(creds: ResolvedCredentials): void {\n if (creds.useOidc) {\n // OIDC auth - no additional validation needed\n return;\n }\n \n // Traditional auth - need all three\n if (!creds.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 (!creds.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 (!creds.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/**\n * Get a writable stream that collects UTF-8 string data and buffers it\n * in memory, returning the full concatenated string when done.\n */\nfunction getUtf8Sink() {\n const chunks: string[] = [];\n const sink = new Writable({\n write(chunk, _enc, cb) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk.toString(\"utf8\") :\n String(chunk));\n cb();\n },\n });\n return { sink, value: () => chunks.join(\"\") };\n}\n\n\n\n/**\n * Create a Vercel provider instance using the factory pattern\n */\nexport const vercel = defineProvider<VercelSandbox, VercelConfig, any, VercelSnapshot>({\n name: 'vercel',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: VercelConfig, options?: CreateSandboxOptions) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n\n // options.timeout takes precedence over config.timeout\n const timeout = options?.timeout ?? config.timeout ?? 300000;\n\n try {\n let sandbox: VercelSandbox;\n\n // Destructure known ComputeSDK fields, collect the rest for passthrough\n const {\n runtime: optRuntime,\n timeout: _timeout,\n envs: _envs, // Vercel SDK does not support envs at sandbox creation time\n name: _name,\n metadata: _metadata,\n templateId,\n snapshotId: optSnapshotId,\n sandboxId: _sandboxId,\n namespace: _namespace,\n directory: _directory,\n ports: optPorts,\n source: optSource,\n ...providerOptions\n } = options || {};\n\n // Construct base params, spreading provider-specific options\n const params: any = {\n timeout,\n ...providerOptions, // Spread provider-specific options (e.g., resources, networkPolicy, signal)\n };\n \n // Only add ports if explicitly configured (options.ports takes precedence)\n const ports = optPorts ?? config.ports;\n if (ports && ports.length > 0) {\n params.ports = ports;\n }\n\n // Pass runtime if specified (Vercel supports runtime selection).\n // Vercel only accepts specific versioned runtimes (node24, node22, python3.13),\n // so translate ComputeSDK's generic names to Vercel's expected format.\n if (optRuntime) {\n const vercelRuntime =\n optRuntime === 'node' ? 'node24' :\n optRuntime === 'python' ? 'python3.13' :\n optRuntime;\n params.runtime = vercelRuntime;\n }\n\n // Support both ComputeSDK format (snapshotId/templateId at top level) and \n // Vercel SDK format (source.snapshotId nested)\n const snapshotId = optSnapshotId || templateId ||\n (optSource?.type === 'snapshot' && optSource?.snapshotId);\n \n if (snapshotId) {\n params.source = {\n type: 'snapshot',\n snapshotId\n };\n } else if (optSource) {\n // Pass through source as-is (e.g., git or tarball sources)\n params.source = optSource;\n }\n\n // Add auth params if not using OIDC\n if (!creds.useOidc) {\n params.token = creds.token;\n params.teamId = creds.teamId;\n params.projectId = creds.projectId;\n }\n\n sandbox = await VercelSandbox.create(params);\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 // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n try {\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.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.`\n );\n },\n\n destroy: async (config: VercelConfig, sandboxId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n try {\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.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\n runCommand: async (sandbox: VercelSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Build command with options\n let fullCommand = command;\n \n // Handle environment variables\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]) => `${k}=\"${escapeShellArg(v)}\"`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n\n // If running in the background, don't capture stdout/stderr\n const stdout = options?.background ? undefined : getUtf8Sink();\n const stderr = options?.background ? undefined : getUtf8Sink();\n\n const result = await sandbox.runCommand({\n cmd: 'sh',\n args: ['-c', fullCommand],\n cwd: options?.cwd,\n detached: options?.background,\n stdout: stdout?.sink,\n stderr: stderr?.sink,\n });\n\n return {\n stdout: stdout?.value() ?? '',\n stderr: stderr?.value() ?? '',\n exitCode: result.exitCode ?? 0,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime,\n };\n }\n },\n\n getInfo: async (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 getUrl: async (sandbox: VercelSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Vercel's built-in domain method to get the real domain\n let url = sandbox.domain(options.port);\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}. Ensure the port has an associated route.`\n );\n }\n },\n\n filesystem: {\n readFile: async (sandbox: VercelSandbox, path: string): Promise<string> => {\n const stream = await sandbox.readFile({ path });\n if (!stream) {\n throw new Error(`File not found: ${path}`);\n }\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString('utf-8');\n },\n\n writeFile: async (sandbox: VercelSandbox, path: string, content: string): Promise<void> => {\n await sandbox.writeFiles([{ path, content: Buffer.from(content) }]);\n },\n\n mkdir: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n await sandbox.mkDir(path);\n },\n\n readdir: async (_sandbox: VercelSandbox, _path: string): Promise<FileEntry[]> => {\n throw new Error('Vercel sandbox does not support readdir. Use runCommand to list directory contents.');\n },\n\n exists: async (_sandbox: VercelSandbox, _path: string): Promise<boolean> => {\n throw new Error('Vercel sandbox does not support exists. Use runCommand to check file existence.');\n },\n\n remove: async (_sandbox: VercelSandbox, _path: string): Promise<void> => {\n throw new Error('Vercel sandbox does not support remove. Use runCommand to delete files.');\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: VercelSandbox): VercelSandbox => {\n return sandbox;\n },\n\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n return await sandbox.snapshot();\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing snapshots.`\n );\n },\n\n delete: async (config: VercelConfig, snapshotId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n let snapshot: VercelSnapshot;\n\n if (creds.useOidc) {\n // Use OIDC token method\n snapshot = await VercelSnapshot.get({ snapshotId });\n } else {\n // Use traditional method\n snapshot = await VercelSnapshot.get({\n snapshotId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n await snapshot.delete();\n }\n },\n\n // Vercel doesn't have a separate \"template\" concept - snapshots serve as templates\n template: {\n create: async (_config: VercelConfig, _options: { name: string }) => {\n throw new Error(\n `Vercel does not support creating templates directly. Use snapshot.create() to create a snapshot from a running sandbox.`\n );\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing templates.`\n );\n },\n\n delete: async (config: VercelConfig, templateId: string) => {\n // Reuse snapshot.delete since Vercel doesn't have separate templates\n const creds = resolveCredentials(config);\n\n let snapshot: VercelSnapshot;\n\n if (creds.useOidc) {\n snapshot = await VercelSnapshot.get({ snapshotId: templateId });\n } else {\n snapshot = await VercelSnapshot.get({\n snapshotId: templateId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n await snapshot.delete();\n }\n }\n }\n});\n"],"mappings":"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","names":["VercelSandbox","VercelSnapshot"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n */\n\nimport { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\nimport { Writable } from 'node:stream';\n\nexport type { VercelSandbox, VercelSnapshot };\n\nimport type { CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\nexport interface VercelConfig {\n token?: string;\n teamId?: string;\n projectId?: string;\n timeout?: number;\n ports?: number[];\n daemonSsePort?: number | false;\n}\n\nconst DEFAULT_DAEMON_SSE_PORT = 38989;\n\nfunction mergeExposedPorts(primary?: number[], fallback?: number[], daemonSsePort?: number | false): number[] {\n const daemonPort = daemonSsePort === false ? undefined : (daemonSsePort ?? DEFAULT_DAEMON_SSE_PORT);\n const merged = [...(primary ?? fallback ?? [])];\n if (typeof daemonPort === 'number') merged.push(daemonPort);\n return Array.from(new Set(merged.filter((port) => Number.isInteger(port) && port > 0 && port <= 65535)));\n}\n\ninterface ResolvedCredentials {\n useOidc: boolean;\n token: string;\n teamId: string;\n projectId: string;\n}\n\nfunction resolveCredentials(config: VercelConfig): ResolvedCredentials {\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 const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n const useOidc = !hasConfigCredentials && !!oidcToken;\n return { useOidc, token, teamId, projectId };\n}\n\nfunction validateCredentials(creds: ResolvedCredentials): void {\n if (creds.useOidc) return;\n if (!creds.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.`\n );\n }\n if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);\n if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);\n}\n\nfunction getUtf8Sink() {\n const chunks: string[] = [];\n const sink = new Writable({\n write(chunk, _enc, cb) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk.toString(\"utf8\") : String(chunk));\n cb();\n },\n });\n return { sink, value: () => chunks.join(\"\") };\n}\n\nexport const vercel = defineProvider<VercelSandbox, VercelConfig, any, VercelSnapshot>({\n name: 'vercel',\n methods: {\n sandbox: {\n create: async (config: VercelConfig, options?: CreateSandboxOptions) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const timeout = options?.timeout ?? config.timeout ?? 300000;\n try {\n const {\n timeout: _timeout, envs: _envs, name: _name, metadata: _metadata,\n templateId, snapshotId: optSnapshotId, sandboxId: _sandboxId,\n namespace: _namespace, directory: _directory,\n ...providerOptions\n } = options || {};\n const optRuntime = (options as any)?.runtime;\n const optPorts = (options as any)?.ports;\n const optSource = (options as any)?.source;\n\n const params: any = { timeout, ...providerOptions };\n const optDaemonSsePort = (options as any)?.daemonSsePort as number | false | undefined;\n const ports = mergeExposedPorts(optPorts, config.ports, optDaemonSsePort ?? config.daemonSsePort);\n if (ports && ports.length > 0) params.ports = ports;\n\n if (optRuntime) {\n params.runtime =\n optRuntime === 'node' ? 'node24' :\n optRuntime === 'python' ? 'python3.13' :\n optRuntime;\n }\n\n const snapshotId = optSnapshotId || templateId ||\n (optSource?.type === 'snapshot' && optSource?.snapshotId);\n if (snapshotId) {\n params.source = { type: 'snapshot', snapshotId };\n } else if (optSource) {\n params.source = optSource;\n }\n\n if (!creds.useOidc) {\n params.token = creds.token;\n params.teamId = creds.teamId;\n params.projectId = creds.projectId;\n }\n\n const sandbox = await VercelSandbox.create(params);\n return { sandbox, sandboxId: sandbox.sandboxId };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('token')) {\n throw new Error(`Vercel authentication failed. Please check your VERCEL_TOKEN environment variable.`);\n }\n if (error.message.includes('team') || error.message.includes('project')) {\n throw new Error(`Vercel team/project configuration failed. Check VERCEL_TEAM_ID and VERCEL_PROJECT_ID.`);\n }\n }\n throw new Error(`Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n getById: async (config: VercelConfig, sandboxId: string) => {\n const creds = resolveCredentials(config);\n try {\n const sandbox = creds.useOidc\n ? await VercelSandbox.get({ sandboxId })\n : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n return { sandbox, sandboxId };\n } catch { return null; }\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(`Vercel provider does not support listing sandboxes.`);\n },\n\n destroy: async (config: VercelConfig, sandboxId: string) => {\n const creds = resolveCredentials(config);\n try {\n const sandbox = creds.useOidc\n ? await VercelSandbox.get({ sandboxId })\n : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n await sandbox.stop();\n } catch { /* already destroyed or doesn't exist */ }\n },\n\n runCommand: async (sandbox: VercelSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n try {\n let fullCommand = command;\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}=\"${escapeShellArg(v)}\"`).join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n const stdout = options?.background ? undefined : getUtf8Sink();\n const stderr = options?.background ? undefined : getUtf8Sink();\n const result = await sandbox.runCommand({\n cmd: 'sh', args: ['-c', fullCommand],\n cwd: options?.cwd, detached: options?.background,\n stdout: stdout?.sink, stderr: stderr?.sink,\n });\n return { stdout: stdout?.value() ?? '', stderr: stderr?.value() ?? '', exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };\n } catch (error) {\n return { stdout: '', stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };\n }\n },\n\n getInfo: async (_sandbox: VercelSandbox): Promise<SandboxInfo> => ({\n id: 'vercel-unknown',\n provider: 'vercel',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: { vercelSandboxId: 'vercel-unknown' }\n }),\n\n getUrl: async (sandbox: VercelSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n let url = sandbox.domain(options.port);\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n return url;\n } catch (error) {\n throw new Error(`Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}.`);\n }\n },\n\n filesystem: {\n readFile: async (sandbox: VercelSandbox, path: string): Promise<string> => {\n const stream = await sandbox.readFile({ path });\n if (!stream) throw new Error(`File not found: ${path}`);\n const chunks: Buffer[] = [];\n for await (const chunk of stream) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n return Buffer.concat(chunks).toString('utf-8');\n },\n writeFile: async (sandbox: VercelSandbox, path: string, content: string): Promise<void> => {\n await sandbox.writeFiles([{ path, content: Buffer.from(content) }]);\n },\n mkdir: async (sandbox: VercelSandbox, path: string): Promise<void> => { await sandbox.mkDir(path); },\n readdir: async (_sandbox: VercelSandbox, _path: string): Promise<FileEntry[]> => {\n throw new Error('Vercel sandbox does not support readdir.');\n },\n exists: async (_sandbox: VercelSandbox, _path: string): Promise<boolean> => {\n throw new Error('Vercel sandbox does not support exists.');\n },\n remove: async (_sandbox: VercelSandbox, _path: string): Promise<void> => {\n throw new Error('Vercel sandbox does not support remove.');\n }\n },\n\n getInstance: (sandbox: VercelSandbox): VercelSandbox => sandbox,\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string) => {\n const creds = resolveCredentials(config);\n const sandbox = creds.useOidc\n ? await VercelSandbox.get({ sandboxId })\n : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n return await sandbox.snapshot();\n },\n list: async (_config: VercelConfig) => { throw new Error(`Vercel provider does not support listing snapshots.`); },\n delete: async (config: VercelConfig, snapshotId: string) => {\n const creds = resolveCredentials(config);\n const snapshot = creds.useOidc\n ? await VercelSnapshot.get({ snapshotId })\n : await VercelSnapshot.get({ snapshotId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n await snapshot.delete();\n }\n },\n\n template: {\n create: async (_config: VercelConfig, _options: { name: string }) => {\n throw new Error(`Vercel does not support creating templates directly. Use snapshot.create() instead.`);\n },\n list: async (_config: VercelConfig) => { throw new Error(`Vercel provider does not support listing templates.`); },\n delete: async (config: VercelConfig, templateId: string) => {\n const creds = resolveCredentials(config);\n const snapshot = creds.useOidc\n ? await VercelSnapshot.get({ snapshotId: templateId })\n : await VercelSnapshot.get({ snapshotId: templateId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n await snapshot.delete();\n }\n }\n }\n});\n"],"mappings":"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","names":["VercelSandbox","VercelSnapshot"]}
package/dist/index.mjs CHANGED
@@ -2,6 +2,13 @@
2
2
  import { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from "@vercel/sandbox";
3
3
  import { defineProvider, escapeShellArg } from "@computesdk/provider";
4
4
  import { Writable } from "stream";
5
+ var DEFAULT_DAEMON_SSE_PORT = 38989;
6
+ function mergeExposedPorts(primary, fallback, daemonSsePort) {
7
+ const daemonPort = daemonSsePort === false ? void 0 : daemonSsePort ?? DEFAULT_DAEMON_SSE_PORT;
8
+ const merged = [...primary ?? fallback ?? []];
9
+ if (typeof daemonPort === "number") merged.push(daemonPort);
10
+ return Array.from(new Set(merged.filter((port) => Number.isInteger(port) && port > 0 && port <= 65535)));
11
+ }
5
12
  function resolveCredentials(config) {
6
13
  const token = config.token || typeof process !== "undefined" && process.env?.VERCEL_TOKEN || "";
7
14
  const teamId = config.teamId || typeof process !== "undefined" && process.env?.VERCEL_TEAM_ID || "";
@@ -12,26 +19,16 @@ function resolveCredentials(config) {
12
19
  return { useOidc, token, teamId, projectId };
13
20
  }
14
21
  function validateCredentials(creds) {
15
- if (creds.useOidc) {
16
- return;
17
- }
22
+ if (creds.useOidc) return;
18
23
  if (!creds.token) {
19
24
  throw new Error(
20
25
  `Missing Vercel authentication. Either:
21
26
  1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or
22
- 2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
23
- );
24
- }
25
- if (!creds.teamId) {
26
- throw new Error(
27
- `Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`
28
- );
29
- }
30
- if (!creds.projectId) {
31
- throw new Error(
32
- `Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`
27
+ 2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable.`
33
28
  );
34
29
  }
30
+ if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);
31
+ if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);
35
32
  }
36
33
  function getUtf8Sink() {
37
34
  const chunks = [];
@@ -47,18 +44,14 @@ var vercel = defineProvider({
47
44
  name: "vercel",
48
45
  methods: {
49
46
  sandbox: {
50
- // Collection operations (map to compute.sandbox.*)
51
47
  create: async (config, options) => {
52
48
  const creds = resolveCredentials(config);
53
49
  validateCredentials(creds);
54
50
  const timeout = options?.timeout ?? config.timeout ?? 3e5;
55
51
  try {
56
- let sandbox;
57
52
  const {
58
- runtime: optRuntime,
59
53
  timeout: _timeout,
60
54
  envs: _envs,
61
- // Vercel SDK does not support envs at sandbox creation time
62
55
  name: _name,
63
56
  metadata: _metadata,
64
57
  templateId,
@@ -66,29 +59,21 @@ var vercel = defineProvider({
66
59
  sandboxId: _sandboxId,
67
60
  namespace: _namespace,
68
61
  directory: _directory,
69
- ports: optPorts,
70
- source: optSource,
71
62
  ...providerOptions
72
63
  } = options || {};
73
- const params = {
74
- timeout,
75
- ...providerOptions
76
- // Spread provider-specific options (e.g., resources, networkPolicy, signal)
77
- };
78
- const ports = optPorts ?? config.ports;
79
- if (ports && ports.length > 0) {
80
- params.ports = ports;
81
- }
64
+ const optRuntime = options?.runtime;
65
+ const optPorts = options?.ports;
66
+ const optSource = options?.source;
67
+ const params = { timeout, ...providerOptions };
68
+ const optDaemonSsePort = options?.daemonSsePort;
69
+ const ports = mergeExposedPorts(optPorts, config.ports, optDaemonSsePort ?? config.daemonSsePort);
70
+ if (ports && ports.length > 0) params.ports = ports;
82
71
  if (optRuntime) {
83
- const vercelRuntime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
84
- params.runtime = vercelRuntime;
72
+ params.runtime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
85
73
  }
86
74
  const snapshotId = optSnapshotId || templateId || optSource?.type === "snapshot" && optSource?.snapshotId;
87
75
  if (snapshotId) {
88
- params.source = {
89
- type: "snapshot",
90
- snapshotId
91
- };
76
+ params.source = { type: "snapshot", snapshotId };
92
77
  } else if (optSource) {
93
78
  params.source = optSource;
94
79
  }
@@ -97,75 +82,40 @@ var vercel = defineProvider({
97
82
  params.teamId = creds.teamId;
98
83
  params.projectId = creds.projectId;
99
84
  }
100
- sandbox = await VercelSandbox.create(params);
101
- return {
102
- sandbox,
103
- sandboxId: sandbox.sandboxId
104
- };
85
+ const sandbox = await VercelSandbox.create(params);
86
+ return { sandbox, sandboxId: sandbox.sandboxId };
105
87
  } catch (error) {
106
88
  if (error instanceof Error) {
107
89
  if (error.message.includes("unauthorized") || error.message.includes("token")) {
108
- throw new Error(
109
- `Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
110
- );
90
+ throw new Error(`Vercel authentication failed. Please check your VERCEL_TOKEN environment variable.`);
111
91
  }
112
92
  if (error.message.includes("team") || error.message.includes("project")) {
113
- throw new Error(
114
- `Vercel team/project configuration failed. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`
115
- );
93
+ throw new Error(`Vercel team/project configuration failed. Check VERCEL_TEAM_ID and VERCEL_PROJECT_ID.`);
116
94
  }
117
95
  }
118
- throw new Error(
119
- `Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`
120
- );
96
+ throw new Error(`Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`);
121
97
  }
122
98
  },
123
99
  getById: async (config, sandboxId) => {
124
100
  const creds = resolveCredentials(config);
125
101
  try {
126
- let sandbox;
127
- if (creds.useOidc) {
128
- sandbox = await VercelSandbox.get({ sandboxId });
129
- } else {
130
- sandbox = await VercelSandbox.get({
131
- sandboxId,
132
- token: creds.token,
133
- teamId: creds.teamId,
134
- projectId: creds.projectId
135
- });
136
- }
137
- return {
138
- sandbox,
139
- sandboxId
140
- };
141
- } catch (error) {
102
+ const sandbox = creds.useOidc ? await VercelSandbox.get({ sandboxId }) : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
103
+ return { sandbox, sandboxId };
104
+ } catch {
142
105
  return null;
143
106
  }
144
107
  },
145
108
  list: async (_config) => {
146
- throw new Error(
147
- `Vercel provider does not support listing sandboxes. Vercel sandboxes are ephemeral and designed for single-use execution.`
148
- );
109
+ throw new Error(`Vercel provider does not support listing sandboxes.`);
149
110
  },
150
111
  destroy: async (config, sandboxId) => {
151
112
  const creds = resolveCredentials(config);
152
113
  try {
153
- let sandbox;
154
- if (creds.useOidc) {
155
- sandbox = await VercelSandbox.get({ sandboxId });
156
- } else {
157
- sandbox = await VercelSandbox.get({
158
- sandboxId,
159
- token: creds.token,
160
- teamId: creds.teamId,
161
- projectId: creds.projectId
162
- });
163
- }
114
+ const sandbox = creds.useOidc ? await VercelSandbox.get({ sandboxId }) : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
164
115
  await sandbox.stop();
165
- } catch (error) {
116
+ } catch {
166
117
  }
167
118
  },
168
- // Instance operations (map to individual Sandbox methods)
169
119
  runCommand: async (sandbox, command, options) => {
170
120
  const startTime = Date.now();
171
121
  try {
@@ -184,35 +134,19 @@ var vercel = defineProvider({
184
134
  stdout: stdout?.sink,
185
135
  stderr: stderr?.sink
186
136
  });
187
- return {
188
- stdout: stdout?.value() ?? "",
189
- stderr: stderr?.value() ?? "",
190
- exitCode: result.exitCode ?? 0,
191
- durationMs: Date.now() - startTime
192
- };
137
+ return { stdout: stdout?.value() ?? "", stderr: stderr?.value() ?? "", exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };
193
138
  } catch (error) {
194
- return {
195
- stdout: "",
196
- stderr: error instanceof Error ? error.message : String(error),
197
- exitCode: 127,
198
- durationMs: Date.now() - startTime
199
- };
139
+ return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
200
140
  }
201
141
  },
202
- getInfo: async (sandbox) => {
203
- return {
204
- id: "vercel-unknown",
205
- provider: "vercel",
206
- runtime: "node",
207
- // Vercel default
208
- status: "running",
209
- createdAt: /* @__PURE__ */ new Date(),
210
- timeout: 3e5,
211
- metadata: {
212
- vercelSandboxId: "vercel-unknown"
213
- }
214
- };
215
- },
142
+ getInfo: async (_sandbox) => ({
143
+ id: "vercel-unknown",
144
+ provider: "vercel",
145
+ status: "running",
146
+ createdAt: /* @__PURE__ */ new Date(),
147
+ timeout: 3e5,
148
+ metadata: { vercelSandboxId: "vercel-unknown" }
149
+ }),
216
150
  getUrl: async (sandbox, options) => {
217
151
  try {
218
152
  let url = sandbox.domain(options.port);
@@ -223,21 +157,15 @@ var vercel = defineProvider({
223
157
  }
224
158
  return url;
225
159
  } catch (error) {
226
- throw new Error(
227
- `Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}. Ensure the port has an associated route.`
228
- );
160
+ throw new Error(`Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}.`);
229
161
  }
230
162
  },
231
163
  filesystem: {
232
164
  readFile: async (sandbox, path) => {
233
165
  const stream = await sandbox.readFile({ path });
234
- if (!stream) {
235
- throw new Error(`File not found: ${path}`);
236
- }
166
+ if (!stream) throw new Error(`File not found: ${path}`);
237
167
  const chunks = [];
238
- for await (const chunk of stream) {
239
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
240
- }
168
+ for await (const chunk of stream) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
241
169
  return Buffer.concat(chunks).toString("utf-8");
242
170
  },
243
171
  writeFile: async (sandbox, path, content) => {
@@ -247,82 +175,42 @@ var vercel = defineProvider({
247
175
  await sandbox.mkDir(path);
248
176
  },
249
177
  readdir: async (_sandbox, _path) => {
250
- throw new Error("Vercel sandbox does not support readdir. Use runCommand to list directory contents.");
178
+ throw new Error("Vercel sandbox does not support readdir.");
251
179
  },
252
180
  exists: async (_sandbox, _path) => {
253
- throw new Error("Vercel sandbox does not support exists. Use runCommand to check file existence.");
181
+ throw new Error("Vercel sandbox does not support exists.");
254
182
  },
255
183
  remove: async (_sandbox, _path) => {
256
- throw new Error("Vercel sandbox does not support remove. Use runCommand to delete files.");
184
+ throw new Error("Vercel sandbox does not support remove.");
257
185
  }
258
186
  },
259
- // Provider-specific typed getInstance method
260
- getInstance: (sandbox) => {
261
- return sandbox;
262
- }
187
+ getInstance: (sandbox) => sandbox
263
188
  },
264
189
  snapshot: {
265
190
  create: async (config, sandboxId) => {
266
191
  const creds = resolveCredentials(config);
267
- let sandbox;
268
- if (creds.useOidc) {
269
- sandbox = await VercelSandbox.get({ sandboxId });
270
- } else {
271
- sandbox = await VercelSandbox.get({
272
- sandboxId,
273
- token: creds.token,
274
- teamId: creds.teamId,
275
- projectId: creds.projectId
276
- });
277
- }
192
+ const sandbox = creds.useOidc ? await VercelSandbox.get({ sandboxId }) : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
278
193
  return await sandbox.snapshot();
279
194
  },
280
195
  list: async (_config) => {
281
- throw new Error(
282
- `Vercel provider does not support listing snapshots.`
283
- );
196
+ throw new Error(`Vercel provider does not support listing snapshots.`);
284
197
  },
285
198
  delete: async (config, snapshotId) => {
286
199
  const creds = resolveCredentials(config);
287
- let snapshot;
288
- if (creds.useOidc) {
289
- snapshot = await VercelSnapshot.get({ snapshotId });
290
- } else {
291
- snapshot = await VercelSnapshot.get({
292
- snapshotId,
293
- token: creds.token,
294
- teamId: creds.teamId,
295
- projectId: creds.projectId
296
- });
297
- }
200
+ const snapshot = creds.useOidc ? await VercelSnapshot.get({ snapshotId }) : await VercelSnapshot.get({ snapshotId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
298
201
  await snapshot.delete();
299
202
  }
300
203
  },
301
- // Vercel doesn't have a separate "template" concept - snapshots serve as templates
302
204
  template: {
303
205
  create: async (_config, _options) => {
304
- throw new Error(
305
- `Vercel does not support creating templates directly. Use snapshot.create() to create a snapshot from a running sandbox.`
306
- );
206
+ throw new Error(`Vercel does not support creating templates directly. Use snapshot.create() instead.`);
307
207
  },
308
208
  list: async (_config) => {
309
- throw new Error(
310
- `Vercel provider does not support listing templates.`
311
- );
209
+ throw new Error(`Vercel provider does not support listing templates.`);
312
210
  },
313
211
  delete: async (config, templateId) => {
314
212
  const creds = resolveCredentials(config);
315
- let snapshot;
316
- if (creds.useOidc) {
317
- snapshot = await VercelSnapshot.get({ snapshotId: templateId });
318
- } else {
319
- snapshot = await VercelSnapshot.get({
320
- snapshotId: templateId,
321
- token: creds.token,
322
- teamId: creds.teamId,
323
- projectId: creds.projectId
324
- });
325
- }
213
+ const snapshot = creds.useOidc ? await VercelSnapshot.get({ snapshotId: templateId }) : await VercelSnapshot.get({ snapshotId: templateId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
326
214
  await snapshot.delete();
327
215
  }
328
216
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n * \n * Demonstrates the new defineProvider() factory pattern with ~50 lines\n * instead of the original ~350 lines of boilerplate.\n */\n\nimport { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\nimport { Writable } from 'node:stream';\n\nexport type { VercelSandbox, VercelSnapshot };\n\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Vercel sandbox provider configuration\n */\nexport interface VercelConfig {\n /** Vercel API token */\n token?: string;\n /** Vercel team ID */\n teamId?: string;\n /** Vercel project ID */\n projectId?: string;\n /** Runtime environment for code execution */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Ports to expose */\n ports?: number[];\n}\n\n/**\n * Resolved Vercel credentials with the authentication method to use\n */\ninterface ResolvedCredentials {\n /** Whether to use OIDC authentication (no explicit credentials needed) */\n useOidc: boolean;\n /** Token for traditional auth (only used if useOidc is false) */\n token: string;\n /** Team ID for traditional auth (only used if useOidc is false) */\n teamId: string;\n /** Project ID for traditional auth (only used if useOidc is false) */\n projectId: string;\n}\n\n/**\n * Resolve Vercel credentials with proper precedence:\n * 1. Config values (from setConfig) always win\n * 2. Environment variables are used as fallback\n * 3. OIDC is only used when no config credentials are provided\n */\nfunction resolveCredentials(config: VercelConfig): ResolvedCredentials {\n // Get values from config first, then fall back to environment\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 // Check if config explicitly provided credentials (config takes precedence)\n const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);\n \n // Only use OIDC if:\n // 1. No config credentials were provided, AND\n // 2. OIDC token is available in environment\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n const useOidc = !hasConfigCredentials && !!oidcToken;\n \n return { useOidc, token, teamId, projectId };\n}\n\n/**\n * Validate that we have sufficient credentials to authenticate\n */\nfunction validateCredentials(creds: ResolvedCredentials): void {\n if (creds.useOidc) {\n // OIDC auth - no additional validation needed\n return;\n }\n \n // Traditional auth - need all three\n if (!creds.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 (!creds.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 (!creds.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/**\n * Get a writable stream that collects UTF-8 string data and buffers it\n * in memory, returning the full concatenated string when done.\n */\nfunction getUtf8Sink() {\n const chunks: string[] = [];\n const sink = new Writable({\n write(chunk, _enc, cb) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk.toString(\"utf8\") :\n String(chunk));\n cb();\n },\n });\n return { sink, value: () => chunks.join(\"\") };\n}\n\n\n\n/**\n * Create a Vercel provider instance using the factory pattern\n */\nexport const vercel = defineProvider<VercelSandbox, VercelConfig, any, VercelSnapshot>({\n name: 'vercel',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: VercelConfig, options?: CreateSandboxOptions) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n\n // options.timeout takes precedence over config.timeout\n const timeout = options?.timeout ?? config.timeout ?? 300000;\n\n try {\n let sandbox: VercelSandbox;\n\n // Destructure known ComputeSDK fields, collect the rest for passthrough\n const {\n runtime: optRuntime,\n timeout: _timeout,\n envs: _envs, // Vercel SDK does not support envs at sandbox creation time\n name: _name,\n metadata: _metadata,\n templateId,\n snapshotId: optSnapshotId,\n sandboxId: _sandboxId,\n namespace: _namespace,\n directory: _directory,\n ports: optPorts,\n source: optSource,\n ...providerOptions\n } = options || {};\n\n // Construct base params, spreading provider-specific options\n const params: any = {\n timeout,\n ...providerOptions, // Spread provider-specific options (e.g., resources, networkPolicy, signal)\n };\n \n // Only add ports if explicitly configured (options.ports takes precedence)\n const ports = optPorts ?? config.ports;\n if (ports && ports.length > 0) {\n params.ports = ports;\n }\n\n // Pass runtime if specified (Vercel supports runtime selection).\n // Vercel only accepts specific versioned runtimes (node24, node22, python3.13),\n // so translate ComputeSDK's generic names to Vercel's expected format.\n if (optRuntime) {\n const vercelRuntime =\n optRuntime === 'node' ? 'node24' :\n optRuntime === 'python' ? 'python3.13' :\n optRuntime;\n params.runtime = vercelRuntime;\n }\n\n // Support both ComputeSDK format (snapshotId/templateId at top level) and \n // Vercel SDK format (source.snapshotId nested)\n const snapshotId = optSnapshotId || templateId ||\n (optSource?.type === 'snapshot' && optSource?.snapshotId);\n \n if (snapshotId) {\n params.source = {\n type: 'snapshot',\n snapshotId\n };\n } else if (optSource) {\n // Pass through source as-is (e.g., git or tarball sources)\n params.source = optSource;\n }\n\n // Add auth params if not using OIDC\n if (!creds.useOidc) {\n params.token = creds.token;\n params.teamId = creds.teamId;\n params.projectId = creds.projectId;\n }\n\n sandbox = await VercelSandbox.create(params);\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 // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n try {\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.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.`\n );\n },\n\n destroy: async (config: VercelConfig, sandboxId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n try {\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.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\n runCommand: async (sandbox: VercelSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Build command with options\n let fullCommand = command;\n \n // Handle environment variables\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]) => `${k}=\"${escapeShellArg(v)}\"`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n\n // If running in the background, don't capture stdout/stderr\n const stdout = options?.background ? undefined : getUtf8Sink();\n const stderr = options?.background ? undefined : getUtf8Sink();\n\n const result = await sandbox.runCommand({\n cmd: 'sh',\n args: ['-c', fullCommand],\n cwd: options?.cwd,\n detached: options?.background,\n stdout: stdout?.sink,\n stderr: stderr?.sink,\n });\n\n return {\n stdout: stdout?.value() ?? '',\n stderr: stderr?.value() ?? '',\n exitCode: result.exitCode ?? 0,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime,\n };\n }\n },\n\n getInfo: async (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 getUrl: async (sandbox: VercelSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Vercel's built-in domain method to get the real domain\n let url = sandbox.domain(options.port);\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}. Ensure the port has an associated route.`\n );\n }\n },\n\n filesystem: {\n readFile: async (sandbox: VercelSandbox, path: string): Promise<string> => {\n const stream = await sandbox.readFile({ path });\n if (!stream) {\n throw new Error(`File not found: ${path}`);\n }\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString('utf-8');\n },\n\n writeFile: async (sandbox: VercelSandbox, path: string, content: string): Promise<void> => {\n await sandbox.writeFiles([{ path, content: Buffer.from(content) }]);\n },\n\n mkdir: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n await sandbox.mkDir(path);\n },\n\n readdir: async (_sandbox: VercelSandbox, _path: string): Promise<FileEntry[]> => {\n throw new Error('Vercel sandbox does not support readdir. Use runCommand to list directory contents.');\n },\n\n exists: async (_sandbox: VercelSandbox, _path: string): Promise<boolean> => {\n throw new Error('Vercel sandbox does not support exists. Use runCommand to check file existence.');\n },\n\n remove: async (_sandbox: VercelSandbox, _path: string): Promise<void> => {\n throw new Error('Vercel sandbox does not support remove. Use runCommand to delete files.');\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: VercelSandbox): VercelSandbox => {\n return sandbox;\n },\n\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n return await sandbox.snapshot();\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing snapshots.`\n );\n },\n\n delete: async (config: VercelConfig, snapshotId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n let snapshot: VercelSnapshot;\n\n if (creds.useOidc) {\n // Use OIDC token method\n snapshot = await VercelSnapshot.get({ snapshotId });\n } else {\n // Use traditional method\n snapshot = await VercelSnapshot.get({\n snapshotId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n await snapshot.delete();\n }\n },\n\n // Vercel doesn't have a separate \"template\" concept - snapshots serve as templates\n template: {\n create: async (_config: VercelConfig, _options: { name: string }) => {\n throw new Error(\n `Vercel does not support creating templates directly. Use snapshot.create() to create a snapshot from a running sandbox.`\n );\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing templates.`\n );\n },\n\n delete: async (config: VercelConfig, templateId: string) => {\n // Reuse snapshot.delete since Vercel doesn't have separate templates\n const creds = resolveCredentials(config);\n\n let snapshot: VercelSnapshot;\n\n if (creds.useOidc) {\n snapshot = await VercelSnapshot.get({ snapshotId: templateId });\n } else {\n snapshot = await VercelSnapshot.get({\n snapshotId: templateId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n await snapshot.delete();\n }\n }\n }\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n */\n\nimport { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\nimport { Writable } from 'node:stream';\n\nexport type { VercelSandbox, VercelSnapshot };\n\nimport type { CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\nexport interface VercelConfig {\n token?: string;\n teamId?: string;\n projectId?: string;\n timeout?: number;\n ports?: number[];\n daemonSsePort?: number | false;\n}\n\nconst DEFAULT_DAEMON_SSE_PORT = 38989;\n\nfunction mergeExposedPorts(primary?: number[], fallback?: number[], daemonSsePort?: number | false): number[] {\n const daemonPort = daemonSsePort === false ? undefined : (daemonSsePort ?? DEFAULT_DAEMON_SSE_PORT);\n const merged = [...(primary ?? fallback ?? [])];\n if (typeof daemonPort === 'number') merged.push(daemonPort);\n return Array.from(new Set(merged.filter((port) => Number.isInteger(port) && port > 0 && port <= 65535)));\n}\n\ninterface ResolvedCredentials {\n useOidc: boolean;\n token: string;\n teamId: string;\n projectId: string;\n}\n\nfunction resolveCredentials(config: VercelConfig): ResolvedCredentials {\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 const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n const useOidc = !hasConfigCredentials && !!oidcToken;\n return { useOidc, token, teamId, projectId };\n}\n\nfunction validateCredentials(creds: ResolvedCredentials): void {\n if (creds.useOidc) return;\n if (!creds.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.`\n );\n }\n if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);\n if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);\n}\n\nfunction getUtf8Sink() {\n const chunks: string[] = [];\n const sink = new Writable({\n write(chunk, _enc, cb) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk.toString(\"utf8\") : String(chunk));\n cb();\n },\n });\n return { sink, value: () => chunks.join(\"\") };\n}\n\nexport const vercel = defineProvider<VercelSandbox, VercelConfig, any, VercelSnapshot>({\n name: 'vercel',\n methods: {\n sandbox: {\n create: async (config: VercelConfig, options?: CreateSandboxOptions) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const timeout = options?.timeout ?? config.timeout ?? 300000;\n try {\n const {\n timeout: _timeout, envs: _envs, name: _name, metadata: _metadata,\n templateId, snapshotId: optSnapshotId, sandboxId: _sandboxId,\n namespace: _namespace, directory: _directory,\n ...providerOptions\n } = options || {};\n const optRuntime = (options as any)?.runtime;\n const optPorts = (options as any)?.ports;\n const optSource = (options as any)?.source;\n\n const params: any = { timeout, ...providerOptions };\n const optDaemonSsePort = (options as any)?.daemonSsePort as number | false | undefined;\n const ports = mergeExposedPorts(optPorts, config.ports, optDaemonSsePort ?? config.daemonSsePort);\n if (ports && ports.length > 0) params.ports = ports;\n\n if (optRuntime) {\n params.runtime =\n optRuntime === 'node' ? 'node24' :\n optRuntime === 'python' ? 'python3.13' :\n optRuntime;\n }\n\n const snapshotId = optSnapshotId || templateId ||\n (optSource?.type === 'snapshot' && optSource?.snapshotId);\n if (snapshotId) {\n params.source = { type: 'snapshot', snapshotId };\n } else if (optSource) {\n params.source = optSource;\n }\n\n if (!creds.useOidc) {\n params.token = creds.token;\n params.teamId = creds.teamId;\n params.projectId = creds.projectId;\n }\n\n const sandbox = await VercelSandbox.create(params);\n return { sandbox, sandboxId: sandbox.sandboxId };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('token')) {\n throw new Error(`Vercel authentication failed. Please check your VERCEL_TOKEN environment variable.`);\n }\n if (error.message.includes('team') || error.message.includes('project')) {\n throw new Error(`Vercel team/project configuration failed. Check VERCEL_TEAM_ID and VERCEL_PROJECT_ID.`);\n }\n }\n throw new Error(`Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n getById: async (config: VercelConfig, sandboxId: string) => {\n const creds = resolveCredentials(config);\n try {\n const sandbox = creds.useOidc\n ? await VercelSandbox.get({ sandboxId })\n : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n return { sandbox, sandboxId };\n } catch { return null; }\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(`Vercel provider does not support listing sandboxes.`);\n },\n\n destroy: async (config: VercelConfig, sandboxId: string) => {\n const creds = resolveCredentials(config);\n try {\n const sandbox = creds.useOidc\n ? await VercelSandbox.get({ sandboxId })\n : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n await sandbox.stop();\n } catch { /* already destroyed or doesn't exist */ }\n },\n\n runCommand: async (sandbox: VercelSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n try {\n let fullCommand = command;\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}=\"${escapeShellArg(v)}\"`).join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n const stdout = options?.background ? undefined : getUtf8Sink();\n const stderr = options?.background ? undefined : getUtf8Sink();\n const result = await sandbox.runCommand({\n cmd: 'sh', args: ['-c', fullCommand],\n cwd: options?.cwd, detached: options?.background,\n stdout: stdout?.sink, stderr: stderr?.sink,\n });\n return { stdout: stdout?.value() ?? '', stderr: stderr?.value() ?? '', exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };\n } catch (error) {\n return { stdout: '', stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };\n }\n },\n\n getInfo: async (_sandbox: VercelSandbox): Promise<SandboxInfo> => ({\n id: 'vercel-unknown',\n provider: 'vercel',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: { vercelSandboxId: 'vercel-unknown' }\n }),\n\n getUrl: async (sandbox: VercelSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n let url = sandbox.domain(options.port);\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n return url;\n } catch (error) {\n throw new Error(`Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}.`);\n }\n },\n\n filesystem: {\n readFile: async (sandbox: VercelSandbox, path: string): Promise<string> => {\n const stream = await sandbox.readFile({ path });\n if (!stream) throw new Error(`File not found: ${path}`);\n const chunks: Buffer[] = [];\n for await (const chunk of stream) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n return Buffer.concat(chunks).toString('utf-8');\n },\n writeFile: async (sandbox: VercelSandbox, path: string, content: string): Promise<void> => {\n await sandbox.writeFiles([{ path, content: Buffer.from(content) }]);\n },\n mkdir: async (sandbox: VercelSandbox, path: string): Promise<void> => { await sandbox.mkDir(path); },\n readdir: async (_sandbox: VercelSandbox, _path: string): Promise<FileEntry[]> => {\n throw new Error('Vercel sandbox does not support readdir.');\n },\n exists: async (_sandbox: VercelSandbox, _path: string): Promise<boolean> => {\n throw new Error('Vercel sandbox does not support exists.');\n },\n remove: async (_sandbox: VercelSandbox, _path: string): Promise<void> => {\n throw new Error('Vercel sandbox does not support remove.');\n }\n },\n\n getInstance: (sandbox: VercelSandbox): VercelSandbox => sandbox,\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string) => {\n const creds = resolveCredentials(config);\n const sandbox = creds.useOidc\n ? await VercelSandbox.get({ sandboxId })\n : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n return await sandbox.snapshot();\n },\n list: async (_config: VercelConfig) => { throw new Error(`Vercel provider does not support listing snapshots.`); },\n delete: async (config: VercelConfig, snapshotId: string) => {\n const creds = resolveCredentials(config);\n const snapshot = creds.useOidc\n ? await VercelSnapshot.get({ snapshotId })\n : await VercelSnapshot.get({ snapshotId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n await snapshot.delete();\n }\n },\n\n template: {\n create: async (_config: VercelConfig, _options: { name: string }) => {\n throw new Error(`Vercel does not support creating templates directly. Use snapshot.create() instead.`);\n },\n list: async (_config: VercelConfig) => { throw new Error(`Vercel provider does not support listing templates.`); },\n delete: async (config: VercelConfig, templateId: string) => {\n const creds = resolveCredentials(config);\n const snapshot = creds.useOidc\n ? await VercelSnapshot.get({ snapshotId: templateId })\n : await VercelSnapshot.get({ snapshotId: templateId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n await snapshot.delete();\n }\n }\n }\n});\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computesdk/vercel",
3
- "version": "1.7.25",
3
+ "version": "1.7.27",
4
4
  "description": "Vercel Sandbox provider for ComputeSDK - serverless code execution for Python and Node.js on Vercel's edge network",
5
5
  "author": "Garrison",
6
6
  "license": "MIT",
@@ -20,8 +20,8 @@
20
20
  "dependencies": {
21
21
  "@vercel/sandbox": "^1.9.3",
22
22
  "ms": "^2.1.3",
23
- "@computesdk/provider": "1.4.0",
24
- "computesdk": "3.0.0"
23
+ "@computesdk/provider": "2.1.0",
24
+ "computesdk": "4.1.0"
25
25
  },
26
26
  "keywords": [
27
27
  "computesdk",
@@ -53,7 +53,7 @@
53
53
  "tsup": "^8.0.0",
54
54
  "typescript": "^5.0.0",
55
55
  "vitest": "^1.0.0",
56
- "@computesdk/test-utils": "1.6.1"
56
+ "@computesdk/test-utils": "2.0.0"
57
57
  },
58
58
  "scripts": {
59
59
  "build": "tsup",