@computesdk/vercel 1.7.25 → 1.7.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,28 +1,14 @@
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[];
22
11
  }
23
- /**
24
- * Create a Vercel provider instance using the factory pattern
25
- */
26
12
  declare const vercel: (config: VercelConfig) => _computesdk_provider.Provider<Sandbox, any, Snapshot>;
27
13
 
28
14
  export { type VercelConfig, vercel };
package/dist/index.d.ts CHANGED
@@ -1,28 +1,14 @@
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[];
22
11
  }
23
- /**
24
- * Create a Vercel provider instance using the factory pattern
25
- */
26
12
  declare const vercel: (config: VercelConfig) => _computesdk_provider.Provider<Sandbox, any, Snapshot>;
27
13
 
28
14
  export { type VercelConfig, vercel };
package/dist/index.js CHANGED
@@ -36,26 +36,16 @@ function resolveCredentials(config) {
36
36
  return { useOidc, token, teamId, projectId };
37
37
  }
38
38
  function validateCredentials(creds) {
39
- if (creds.useOidc) {
40
- return;
41
- }
39
+ if (creds.useOidc) return;
42
40
  if (!creds.token) {
43
41
  throw new Error(
44
42
  `Missing Vercel authentication. Either:
45
43
  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.`
44
+ 2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable.`
57
45
  );
58
46
  }
47
+ if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);
48
+ if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);
59
49
  }
60
50
  function getUtf8Sink() {
61
51
  const chunks = [];
@@ -71,18 +61,14 @@ var vercel = (0, import_provider.defineProvider)({
71
61
  name: "vercel",
72
62
  methods: {
73
63
  sandbox: {
74
- // Collection operations (map to compute.sandbox.*)
75
64
  create: async (config, options) => {
76
65
  const creds = resolveCredentials(config);
77
66
  validateCredentials(creds);
78
67
  const timeout = options?.timeout ?? config.timeout ?? 3e5;
79
68
  try {
80
- let sandbox;
81
69
  const {
82
- runtime: optRuntime,
83
70
  timeout: _timeout,
84
71
  envs: _envs,
85
- // Vercel SDK does not support envs at sandbox creation time
86
72
  name: _name,
87
73
  metadata: _metadata,
88
74
  templateId,
@@ -90,29 +76,20 @@ var vercel = (0, import_provider.defineProvider)({
90
76
  sandboxId: _sandboxId,
91
77
  namespace: _namespace,
92
78
  directory: _directory,
93
- ports: optPorts,
94
- source: optSource,
95
79
  ...providerOptions
96
80
  } = options || {};
97
- const params = {
98
- timeout,
99
- ...providerOptions
100
- // Spread provider-specific options (e.g., resources, networkPolicy, signal)
101
- };
81
+ const optRuntime = options?.runtime;
82
+ const optPorts = options?.ports;
83
+ const optSource = options?.source;
84
+ const params = { timeout, ...providerOptions };
102
85
  const ports = optPorts ?? config.ports;
103
- if (ports && ports.length > 0) {
104
- params.ports = ports;
105
- }
86
+ if (ports && ports.length > 0) params.ports = ports;
106
87
  if (optRuntime) {
107
- const vercelRuntime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
108
- params.runtime = vercelRuntime;
88
+ params.runtime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
109
89
  }
110
90
  const snapshotId = optSnapshotId || templateId || optSource?.type === "snapshot" && optSource?.snapshotId;
111
91
  if (snapshotId) {
112
- params.source = {
113
- type: "snapshot",
114
- snapshotId
115
- };
92
+ params.source = { type: "snapshot", snapshotId };
116
93
  } else if (optSource) {
117
94
  params.source = optSource;
118
95
  }
@@ -121,75 +98,40 @@ var vercel = (0, import_provider.defineProvider)({
121
98
  params.teamId = creds.teamId;
122
99
  params.projectId = creds.projectId;
123
100
  }
124
- sandbox = await import_sandbox.Sandbox.create(params);
125
- return {
126
- sandbox,
127
- sandboxId: sandbox.sandboxId
128
- };
101
+ const sandbox = await import_sandbox.Sandbox.create(params);
102
+ return { sandbox, sandboxId: sandbox.sandboxId };
129
103
  } catch (error) {
130
104
  if (error instanceof Error) {
131
105
  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
- );
106
+ throw new Error(`Vercel authentication failed. Please check your VERCEL_TOKEN environment variable.`);
135
107
  }
136
108
  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
- );
109
+ throw new Error(`Vercel team/project configuration failed. Check VERCEL_TEAM_ID and VERCEL_PROJECT_ID.`);
140
110
  }
141
111
  }
142
- throw new Error(
143
- `Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`
144
- );
112
+ throw new Error(`Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`);
145
113
  }
146
114
  },
147
115
  getById: async (config, sandboxId) => {
148
116
  const creds = resolveCredentials(config);
149
117
  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) {
118
+ 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 });
119
+ return { sandbox, sandboxId };
120
+ } catch {
166
121
  return null;
167
122
  }
168
123
  },
169
124
  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
- );
125
+ throw new Error(`Vercel provider does not support listing sandboxes.`);
173
126
  },
174
127
  destroy: async (config, sandboxId) => {
175
128
  const creds = resolveCredentials(config);
176
129
  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
- }
130
+ 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
131
  await sandbox.stop();
189
- } catch (error) {
132
+ } catch {
190
133
  }
191
134
  },
192
- // Instance operations (map to individual Sandbox methods)
193
135
  runCommand: async (sandbox, command, options) => {
194
136
  const startTime = Date.now();
195
137
  try {
@@ -208,35 +150,19 @@ var vercel = (0, import_provider.defineProvider)({
208
150
  stdout: stdout?.sink,
209
151
  stderr: stderr?.sink
210
152
  });
211
- return {
212
- stdout: stdout?.value() ?? "",
213
- stderr: stderr?.value() ?? "",
214
- exitCode: result.exitCode ?? 0,
215
- durationMs: Date.now() - startTime
216
- };
153
+ return { stdout: stdout?.value() ?? "", stderr: stderr?.value() ?? "", exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };
217
154
  } catch (error) {
218
- return {
219
- stdout: "",
220
- stderr: error instanceof Error ? error.message : String(error),
221
- exitCode: 127,
222
- durationMs: Date.now() - startTime
223
- };
155
+ return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
224
156
  }
225
157
  },
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
- },
158
+ getInfo: async (_sandbox) => ({
159
+ id: "vercel-unknown",
160
+ provider: "vercel",
161
+ status: "running",
162
+ createdAt: /* @__PURE__ */ new Date(),
163
+ timeout: 3e5,
164
+ metadata: { vercelSandboxId: "vercel-unknown" }
165
+ }),
240
166
  getUrl: async (sandbox, options) => {
241
167
  try {
242
168
  let url = sandbox.domain(options.port);
@@ -247,21 +173,15 @@ var vercel = (0, import_provider.defineProvider)({
247
173
  }
248
174
  return url;
249
175
  } 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
- );
176
+ throw new Error(`Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}.`);
253
177
  }
254
178
  },
255
179
  filesystem: {
256
180
  readFile: async (sandbox, path) => {
257
181
  const stream = await sandbox.readFile({ path });
258
- if (!stream) {
259
- throw new Error(`File not found: ${path}`);
260
- }
182
+ if (!stream) throw new Error(`File not found: ${path}`);
261
183
  const chunks = [];
262
- for await (const chunk of stream) {
263
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
264
- }
184
+ for await (const chunk of stream) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
265
185
  return Buffer.concat(chunks).toString("utf-8");
266
186
  },
267
187
  writeFile: async (sandbox, path, content) => {
@@ -271,82 +191,42 @@ var vercel = (0, import_provider.defineProvider)({
271
191
  await sandbox.mkDir(path);
272
192
  },
273
193
  readdir: async (_sandbox, _path) => {
274
- throw new Error("Vercel sandbox does not support readdir. Use runCommand to list directory contents.");
194
+ throw new Error("Vercel sandbox does not support readdir.");
275
195
  },
276
196
  exists: async (_sandbox, _path) => {
277
- throw new Error("Vercel sandbox does not support exists. Use runCommand to check file existence.");
197
+ throw new Error("Vercel sandbox does not support exists.");
278
198
  },
279
199
  remove: async (_sandbox, _path) => {
280
- throw new Error("Vercel sandbox does not support remove. Use runCommand to delete files.");
200
+ throw new Error("Vercel sandbox does not support remove.");
281
201
  }
282
202
  },
283
- // Provider-specific typed getInstance method
284
- getInstance: (sandbox) => {
285
- return sandbox;
286
- }
203
+ getInstance: (sandbox) => sandbox
287
204
  },
288
205
  snapshot: {
289
206
  create: async (config, sandboxId) => {
290
207
  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
- }
208
+ 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
209
  return await sandbox.snapshot();
303
210
  },
304
211
  list: async (_config) => {
305
- throw new Error(
306
- `Vercel provider does not support listing snapshots.`
307
- );
212
+ throw new Error(`Vercel provider does not support listing snapshots.`);
308
213
  },
309
214
  delete: async (config, snapshotId) => {
310
215
  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
- }
216
+ 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
217
  await snapshot.delete();
323
218
  }
324
219
  },
325
- // Vercel doesn't have a separate "template" concept - snapshots serve as templates
326
220
  template: {
327
221
  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
- );
222
+ throw new Error(`Vercel does not support creating templates directly. Use snapshot.create() instead.`);
331
223
  },
332
224
  list: async (_config) => {
333
- throw new Error(
334
- `Vercel provider does not support listing templates.`
335
- );
225
+ throw new Error(`Vercel provider does not support listing templates.`);
336
226
  },
337
227
  delete: async (config, templateId) => {
338
228
  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
- }
229
+ 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
230
  await snapshot.delete();
351
231
  }
352
232
  }
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}\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 ports = optPorts ?? config.ports;\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
@@ -12,26 +12,16 @@ function resolveCredentials(config) {
12
12
  return { useOidc, token, teamId, projectId };
13
13
  }
14
14
  function validateCredentials(creds) {
15
- if (creds.useOidc) {
16
- return;
17
- }
15
+ if (creds.useOidc) return;
18
16
  if (!creds.token) {
19
17
  throw new Error(
20
18
  `Missing Vercel authentication. Either:
21
19
  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.`
20
+ 2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable.`
33
21
  );
34
22
  }
23
+ if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);
24
+ if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);
35
25
  }
36
26
  function getUtf8Sink() {
37
27
  const chunks = [];
@@ -47,18 +37,14 @@ var vercel = defineProvider({
47
37
  name: "vercel",
48
38
  methods: {
49
39
  sandbox: {
50
- // Collection operations (map to compute.sandbox.*)
51
40
  create: async (config, options) => {
52
41
  const creds = resolveCredentials(config);
53
42
  validateCredentials(creds);
54
43
  const timeout = options?.timeout ?? config.timeout ?? 3e5;
55
44
  try {
56
- let sandbox;
57
45
  const {
58
- runtime: optRuntime,
59
46
  timeout: _timeout,
60
47
  envs: _envs,
61
- // Vercel SDK does not support envs at sandbox creation time
62
48
  name: _name,
63
49
  metadata: _metadata,
64
50
  templateId,
@@ -66,29 +52,20 @@ var vercel = defineProvider({
66
52
  sandboxId: _sandboxId,
67
53
  namespace: _namespace,
68
54
  directory: _directory,
69
- ports: optPorts,
70
- source: optSource,
71
55
  ...providerOptions
72
56
  } = options || {};
73
- const params = {
74
- timeout,
75
- ...providerOptions
76
- // Spread provider-specific options (e.g., resources, networkPolicy, signal)
77
- };
57
+ const optRuntime = options?.runtime;
58
+ const optPorts = options?.ports;
59
+ const optSource = options?.source;
60
+ const params = { timeout, ...providerOptions };
78
61
  const ports = optPorts ?? config.ports;
79
- if (ports && ports.length > 0) {
80
- params.ports = ports;
81
- }
62
+ if (ports && ports.length > 0) params.ports = ports;
82
63
  if (optRuntime) {
83
- const vercelRuntime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
84
- params.runtime = vercelRuntime;
64
+ params.runtime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
85
65
  }
86
66
  const snapshotId = optSnapshotId || templateId || optSource?.type === "snapshot" && optSource?.snapshotId;
87
67
  if (snapshotId) {
88
- params.source = {
89
- type: "snapshot",
90
- snapshotId
91
- };
68
+ params.source = { type: "snapshot", snapshotId };
92
69
  } else if (optSource) {
93
70
  params.source = optSource;
94
71
  }
@@ -97,75 +74,40 @@ var vercel = defineProvider({
97
74
  params.teamId = creds.teamId;
98
75
  params.projectId = creds.projectId;
99
76
  }
100
- sandbox = await VercelSandbox.create(params);
101
- return {
102
- sandbox,
103
- sandboxId: sandbox.sandboxId
104
- };
77
+ const sandbox = await VercelSandbox.create(params);
78
+ return { sandbox, sandboxId: sandbox.sandboxId };
105
79
  } catch (error) {
106
80
  if (error instanceof Error) {
107
81
  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
- );
82
+ throw new Error(`Vercel authentication failed. Please check your VERCEL_TOKEN environment variable.`);
111
83
  }
112
84
  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
- );
85
+ throw new Error(`Vercel team/project configuration failed. Check VERCEL_TEAM_ID and VERCEL_PROJECT_ID.`);
116
86
  }
117
87
  }
118
- throw new Error(
119
- `Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`
120
- );
88
+ throw new Error(`Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`);
121
89
  }
122
90
  },
123
91
  getById: async (config, sandboxId) => {
124
92
  const creds = resolveCredentials(config);
125
93
  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) {
94
+ const sandbox = creds.useOidc ? await VercelSandbox.get({ sandboxId }) : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
95
+ return { sandbox, sandboxId };
96
+ } catch {
142
97
  return null;
143
98
  }
144
99
  },
145
100
  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
- );
101
+ throw new Error(`Vercel provider does not support listing sandboxes.`);
149
102
  },
150
103
  destroy: async (config, sandboxId) => {
151
104
  const creds = resolveCredentials(config);
152
105
  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
- }
106
+ const sandbox = creds.useOidc ? await VercelSandbox.get({ sandboxId }) : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
164
107
  await sandbox.stop();
165
- } catch (error) {
108
+ } catch {
166
109
  }
167
110
  },
168
- // Instance operations (map to individual Sandbox methods)
169
111
  runCommand: async (sandbox, command, options) => {
170
112
  const startTime = Date.now();
171
113
  try {
@@ -184,35 +126,19 @@ var vercel = defineProvider({
184
126
  stdout: stdout?.sink,
185
127
  stderr: stderr?.sink
186
128
  });
187
- return {
188
- stdout: stdout?.value() ?? "",
189
- stderr: stderr?.value() ?? "",
190
- exitCode: result.exitCode ?? 0,
191
- durationMs: Date.now() - startTime
192
- };
129
+ return { stdout: stdout?.value() ?? "", stderr: stderr?.value() ?? "", exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };
193
130
  } catch (error) {
194
- return {
195
- stdout: "",
196
- stderr: error instanceof Error ? error.message : String(error),
197
- exitCode: 127,
198
- durationMs: Date.now() - startTime
199
- };
131
+ return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
200
132
  }
201
133
  },
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
- },
134
+ getInfo: async (_sandbox) => ({
135
+ id: "vercel-unknown",
136
+ provider: "vercel",
137
+ status: "running",
138
+ createdAt: /* @__PURE__ */ new Date(),
139
+ timeout: 3e5,
140
+ metadata: { vercelSandboxId: "vercel-unknown" }
141
+ }),
216
142
  getUrl: async (sandbox, options) => {
217
143
  try {
218
144
  let url = sandbox.domain(options.port);
@@ -223,21 +149,15 @@ var vercel = defineProvider({
223
149
  }
224
150
  return url;
225
151
  } 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
- );
152
+ throw new Error(`Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}.`);
229
153
  }
230
154
  },
231
155
  filesystem: {
232
156
  readFile: async (sandbox, path) => {
233
157
  const stream = await sandbox.readFile({ path });
234
- if (!stream) {
235
- throw new Error(`File not found: ${path}`);
236
- }
158
+ if (!stream) throw new Error(`File not found: ${path}`);
237
159
  const chunks = [];
238
- for await (const chunk of stream) {
239
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
240
- }
160
+ for await (const chunk of stream) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
241
161
  return Buffer.concat(chunks).toString("utf-8");
242
162
  },
243
163
  writeFile: async (sandbox, path, content) => {
@@ -247,82 +167,42 @@ var vercel = defineProvider({
247
167
  await sandbox.mkDir(path);
248
168
  },
249
169
  readdir: async (_sandbox, _path) => {
250
- throw new Error("Vercel sandbox does not support readdir. Use runCommand to list directory contents.");
170
+ throw new Error("Vercel sandbox does not support readdir.");
251
171
  },
252
172
  exists: async (_sandbox, _path) => {
253
- throw new Error("Vercel sandbox does not support exists. Use runCommand to check file existence.");
173
+ throw new Error("Vercel sandbox does not support exists.");
254
174
  },
255
175
  remove: async (_sandbox, _path) => {
256
- throw new Error("Vercel sandbox does not support remove. Use runCommand to delete files.");
176
+ throw new Error("Vercel sandbox does not support remove.");
257
177
  }
258
178
  },
259
- // Provider-specific typed getInstance method
260
- getInstance: (sandbox) => {
261
- return sandbox;
262
- }
179
+ getInstance: (sandbox) => sandbox
263
180
  },
264
181
  snapshot: {
265
182
  create: async (config, sandboxId) => {
266
183
  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
- }
184
+ const sandbox = creds.useOidc ? await VercelSandbox.get({ sandboxId }) : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
278
185
  return await sandbox.snapshot();
279
186
  },
280
187
  list: async (_config) => {
281
- throw new Error(
282
- `Vercel provider does not support listing snapshots.`
283
- );
188
+ throw new Error(`Vercel provider does not support listing snapshots.`);
284
189
  },
285
190
  delete: async (config, snapshotId) => {
286
191
  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
- }
192
+ const snapshot = creds.useOidc ? await VercelSnapshot.get({ snapshotId }) : await VercelSnapshot.get({ snapshotId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
298
193
  await snapshot.delete();
299
194
  }
300
195
  },
301
- // Vercel doesn't have a separate "template" concept - snapshots serve as templates
302
196
  template: {
303
197
  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
- );
198
+ throw new Error(`Vercel does not support creating templates directly. Use snapshot.create() instead.`);
307
199
  },
308
200
  list: async (_config) => {
309
- throw new Error(
310
- `Vercel provider does not support listing templates.`
311
- );
201
+ throw new Error(`Vercel provider does not support listing templates.`);
312
202
  },
313
203
  delete: async (config, templateId) => {
314
204
  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
- }
205
+ const snapshot = creds.useOidc ? await VercelSnapshot.get({ snapshotId: templateId }) : await VercelSnapshot.get({ snapshotId: templateId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
326
206
  await snapshot.delete();
327
207
  }
328
208
  }
@@ -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}\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 ports = optPorts ?? config.ports;\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":";AAIA,SAAS,WAAW,eAAe,YAAY,sBAAsB;AACrE,SAAS,gBAAgB,sBAAsB;AAC/C,SAAS,gBAAgB;AAqBzB,SAAS,mBAAmB,QAA2C;AACrE,QAAM,QAAQ,OAAO,SAAU,OAAO,YAAY,eAAe,QAAQ,KAAK,gBAAiB;AAC/F,QAAM,SAAS,OAAO,UAAW,OAAO,YAAY,eAAe,QAAQ,KAAK,kBAAmB;AACnG,QAAM,YAAY,OAAO,aAAc,OAAO,YAAY,eAAe,QAAQ,KAAK,qBAAsB;AAC5G,QAAM,uBAAuB,CAAC,EAAE,OAAO,SAAS,OAAO,UAAU,OAAO;AACxE,QAAM,YAAY,OAAO,YAAY,eAAe,QAAQ,KAAK;AACjE,QAAM,UAAU,CAAC,wBAAwB,CAAC,CAAC;AAC3C,SAAO,EAAE,SAAS,OAAO,QAAQ,UAAU;AAC7C;AAEA,SAAS,oBAAoB,OAAkC;AAC7D,MAAI,MAAM,QAAS;AACnB,MAAI,CAAC,MAAM,OAAO;AAChB,UAAM,IAAI;AAAA,MACR;AAAA;AAAA;AAAA,IAGF;AAAA,EACF;AACA,MAAI,CAAC,MAAM,OAAQ,OAAM,IAAI,MAAM,2EAA2E;AAC9G,MAAI,CAAC,MAAM,UAAW,OAAM,IAAI,MAAM,oFAAoF;AAC5H;AAEA,SAAS,cAAc;AACrB,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAO,IAAI,SAAS;AAAA,IACxB,MAAM,OAAO,MAAM,IAAI;AACrB,aAAO,KAAK,OAAO,SAAS,KAAK,IAAI,MAAM,SAAS,MAAM,IAAI,OAAO,KAAK,CAAC;AAC3E,SAAG;AAAA,IACL;AAAA,EACF,CAAC;AACD,SAAO,EAAE,MAAM,OAAO,MAAM,OAAO,KAAK,EAAE,EAAE;AAC9C;AAEO,IAAM,SAAS,eAAiE;AAAA,EACrF,MAAM;AAAA,EACN,SAAS;AAAA,IACP,SAAS;AAAA,MACP,QAAQ,OAAO,QAAsB,YAAmC;AACtE,cAAM,QAAQ,mBAAmB,MAAM;AACvC,4BAAoB,KAAK;AACzB,cAAM,UAAU,SAAS,WAAW,OAAO,WAAW;AACtD,YAAI;AACF,gBAAM;AAAA,YACJ,SAAS;AAAA,YAAU,MAAM;AAAA,YAAO,MAAM;AAAA,YAAO,UAAU;AAAA,YACvD;AAAA,YAAY,YAAY;AAAA,YAAe,WAAW;AAAA,YAClD,WAAW;AAAA,YAAY,WAAW;AAAA,YAClC,GAAG;AAAA,UACL,IAAI,WAAW,CAAC;AAChB,gBAAM,aAAc,SAAiB;AACrC,gBAAM,WAAY,SAAiB;AACnC,gBAAM,YAAa,SAAiB;AAEpC,gBAAM,SAAc,EAAE,SAAS,GAAG,gBAAgB;AAClD,gBAAM,QAAQ,YAAY,OAAO;AACjC,cAAI,SAAS,MAAM,SAAS,EAAG,QAAO,QAAQ;AAE9C,cAAI,YAAY;AACd,mBAAO,UACL,eAAe,SAAS,WACxB,eAAe,WAAW,eAC1B;AAAA,UACJ;AAEA,gBAAM,aAAa,iBAAiB,cACjC,WAAW,SAAS,cAAc,WAAW;AAChD,cAAI,YAAY;AACd,mBAAO,SAAS,EAAE,MAAM,YAAY,WAAW;AAAA,UACjD,WAAW,WAAW;AACpB,mBAAO,SAAS;AAAA,UAClB;AAEA,cAAI,CAAC,MAAM,SAAS;AAClB,mBAAO,QAAQ,MAAM;AACrB,mBAAO,SAAS,MAAM;AACtB,mBAAO,YAAY,MAAM;AAAA,UAC3B;AAEA,gBAAM,UAAU,MAAM,cAAc,OAAO,MAAM;AACjD,iBAAO,EAAE,SAAS,WAAW,QAAQ,UAAU;AAAA,QACjD,SAAS,OAAO;AACd,cAAI,iBAAiB,OAAO;AAC1B,gBAAI,MAAM,QAAQ,SAAS,cAAc,KAAK,MAAM,QAAQ,SAAS,OAAO,GAAG;AAC7E,oBAAM,IAAI,MAAM,oFAAoF;AAAA,YACtG;AACA,gBAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,MAAM,QAAQ,SAAS,SAAS,GAAG;AACvE,oBAAM,IAAI,MAAM,uFAAuF;AAAA,YACzG;AAAA,UACF;AACA,gBAAM,IAAI,MAAM,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,QAC9G;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,QAAsB,cAAsB;AAC1D,cAAM,QAAQ,mBAAmB,MAAM;AACvC,YAAI;AACF,gBAAM,UAAU,MAAM,UAClB,MAAM,cAAc,IAAI,EAAE,UAAU,CAAC,IACrC,MAAM,cAAc,IAAI,EAAE,WAAW,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU,CAAC;AAC/G,iBAAO,EAAE,SAAS,UAAU;AAAA,QAC9B,QAAQ;AAAE,iBAAO;AAAA,QAAM;AAAA,MACzB;AAAA,MAEA,MAAM,OAAO,YAA0B;AACrC,cAAM,IAAI,MAAM,qDAAqD;AAAA,MACvE;AAAA,MAEA,SAAS,OAAO,QAAsB,cAAsB;AAC1D,cAAM,QAAQ,mBAAmB,MAAM;AACvC,YAAI;AACF,gBAAM,UAAU,MAAM,UAClB,MAAM,cAAc,IAAI,EAAE,UAAU,CAAC,IACrC,MAAM,cAAc,IAAI,EAAE,WAAW,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU,CAAC;AAC/G,gBAAM,QAAQ,KAAK;AAAA,QACrB,QAAQ;AAAA,QAA2C;AAAA,MACrD;AAAA,MAEA,YAAY,OAAO,SAAwB,SAAiB,YAAwD;AAClH,cAAM,YAAY,KAAK,IAAI;AAC3B,YAAI;AACF,cAAI,cAAc;AAClB,cAAI,SAAS,OAAO,OAAO,KAAK,QAAQ,GAAG,EAAE,SAAS,GAAG;AACvD,kBAAM,YAAY,OAAO,QAAQ,QAAQ,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,eAAe,CAAC,CAAC,GAAG,EAAE,KAAK,GAAG;AACrG,0BAAc,GAAG,SAAS,IAAI,WAAW;AAAA,UAC3C;AACA,gBAAM,SAAS,SAAS,aAAa,SAAY,YAAY;AAC7D,gBAAM,SAAS,SAAS,aAAa,SAAY,YAAY;AAC7D,gBAAM,SAAS,MAAM,QAAQ,WAAW;AAAA,YACtC,KAAK;AAAA,YAAM,MAAM,CAAC,MAAM,WAAW;AAAA,YACnC,KAAK,SAAS;AAAA,YAAK,UAAU,SAAS;AAAA,YACtC,QAAQ,QAAQ;AAAA,YAAM,QAAQ,QAAQ;AAAA,UACxC,CAAC;AACD,iBAAO,EAAE,QAAQ,QAAQ,MAAM,KAAK,IAAI,QAAQ,QAAQ,MAAM,KAAK,IAAI,UAAU,OAAO,YAAY,GAAG,YAAY,KAAK,IAAI,IAAI,UAAU;AAAA,QAC5I,SAAS,OAAO;AACd,iBAAO,EAAE,QAAQ,IAAI,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG,UAAU,KAAK,YAAY,KAAK,IAAI,IAAI,UAAU;AAAA,QACzI;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,cAAmD;AAAA,QACjE,IAAI;AAAA,QACJ,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,WAAW,oBAAI,KAAK;AAAA,QACpB,SAAS;AAAA,QACT,UAAU,EAAE,iBAAiB,iBAAiB;AAAA,MAChD;AAAA,MAEA,QAAQ,OAAO,SAAwB,YAAkE;AACvG,YAAI;AACF,cAAI,MAAM,QAAQ,OAAO,QAAQ,IAAI;AACrC,cAAI,QAAQ,UAAU;AACpB,kBAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,mBAAO,WAAW,QAAQ,WAAW;AACrC,kBAAM,OAAO,SAAS;AAAA,UACxB;AACA,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,IAAI,MAAM,wCAAwC,QAAQ,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,GAAG;AAAA,QACpI;AAAA,MACF;AAAA,MAEA,YAAY;AAAA,QACV,UAAU,OAAO,SAAwB,SAAkC;AACzE,gBAAM,SAAS,MAAM,QAAQ,SAAS,EAAE,KAAK,CAAC;AAC9C,cAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,mBAAmB,IAAI,EAAE;AACtD,gBAAM,SAAmB,CAAC;AAC1B,2BAAiB,SAAS,OAAQ,QAAO,KAAK,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK,CAAC;AACjG,iBAAO,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO;AAAA,QAC/C;AAAA,QACA,WAAW,OAAO,SAAwB,MAAc,YAAmC;AACzF,gBAAM,QAAQ,WAAW,CAAC,EAAE,MAAM,SAAS,OAAO,KAAK,OAAO,EAAE,CAAC,CAAC;AAAA,QACpE;AAAA,QACA,OAAO,OAAO,SAAwB,SAAgC;AAAE,gBAAM,QAAQ,MAAM,IAAI;AAAA,QAAG;AAAA,QACnG,SAAS,OAAO,UAAyB,UAAwC;AAC/E,gBAAM,IAAI,MAAM,0CAA0C;AAAA,QAC5D;AAAA,QACA,QAAQ,OAAO,UAAyB,UAAoC;AAC1E,gBAAM,IAAI,MAAM,yCAAyC;AAAA,QAC3D;AAAA,QACA,QAAQ,OAAO,UAAyB,UAAiC;AACvE,gBAAM,IAAI,MAAM,yCAAyC;AAAA,QAC3D;AAAA,MACF;AAAA,MAEA,aAAa,CAAC,YAA0C;AAAA,IAC1D;AAAA,IAEA,UAAU;AAAA,MACR,QAAQ,OAAO,QAAsB,cAAsB;AACzD,cAAM,QAAQ,mBAAmB,MAAM;AACvC,cAAM,UAAU,MAAM,UAClB,MAAM,cAAc,IAAI,EAAE,UAAU,CAAC,IACrC,MAAM,cAAc,IAAI,EAAE,WAAW,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU,CAAC;AAC/G,eAAO,MAAM,QAAQ,SAAS;AAAA,MAChC;AAAA,MACA,MAAM,OAAO,YAA0B;AAAE,cAAM,IAAI,MAAM,qDAAqD;AAAA,MAAG;AAAA,MACjH,QAAQ,OAAO,QAAsB,eAAuB;AAC1D,cAAM,QAAQ,mBAAmB,MAAM;AACvC,cAAM,WAAW,MAAM,UACnB,MAAM,eAAe,IAAI,EAAE,WAAW,CAAC,IACvC,MAAM,eAAe,IAAI,EAAE,YAAY,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU,CAAC;AACjH,cAAM,SAAS,OAAO;AAAA,MACxB;AAAA,IACF;AAAA,IAEA,UAAU;AAAA,MACR,QAAQ,OAAO,SAAuB,aAA+B;AACnE,cAAM,IAAI,MAAM,qFAAqF;AAAA,MACvG;AAAA,MACA,MAAM,OAAO,YAA0B;AAAE,cAAM,IAAI,MAAM,qDAAqD;AAAA,MAAG;AAAA,MACjH,QAAQ,OAAO,QAAsB,eAAuB;AAC1D,cAAM,QAAQ,mBAAmB,MAAM;AACvC,cAAM,WAAW,MAAM,UACnB,MAAM,eAAe,IAAI,EAAE,YAAY,WAAW,CAAC,IACnD,MAAM,eAAe,IAAI,EAAE,YAAY,YAAY,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU,CAAC;AAC7H,cAAM,SAAS,OAAO;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACF,CAAC;","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.26",
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": "4.0.0",
24
+ "@computesdk/provider": "2.0.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",