@computesdk/vercel 1.7.24 → 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/README.md +20 -20
- package/dist/index.d.mts +0 -14
- package/dist/index.d.ts +0 -14
- package/dist/index.js +69 -217
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +69 -217
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -47,12 +47,12 @@ import { compute } from 'computesdk';
|
|
|
47
47
|
// Auto-detects Vercel from VERCEL_OIDC_TOKEN or VERCEL_TOKEN environment variables
|
|
48
48
|
const sandbox = await compute.sandbox.create();
|
|
49
49
|
|
|
50
|
-
// Execute Node.js
|
|
51
|
-
const result = await sandbox.
|
|
50
|
+
// Execute Node.js command
|
|
51
|
+
const result = await sandbox.runCommand('node -e "console.log(\"Hello from Vercel!\")"');
|
|
52
52
|
console.log(result.stdout); // "Hello from Vercel!"
|
|
53
53
|
|
|
54
|
-
// Execute Python
|
|
55
|
-
const pythonResult = await sandbox.
|
|
54
|
+
// Execute Python command
|
|
55
|
+
const pythonResult = await sandbox.runCommand('python -c "print(\"Hello from Python!\")"');
|
|
56
56
|
console.log(pythonResult.stdout); // "Hello from Python!"
|
|
57
57
|
|
|
58
58
|
await sandbox.destroy();
|
|
@@ -75,7 +75,7 @@ const compute = vercel({
|
|
|
75
75
|
|
|
76
76
|
const sandbox = await compute.sandbox.create();
|
|
77
77
|
|
|
78
|
-
const result = await sandbox.
|
|
78
|
+
const result = await sandbox.runCommand('node -e "console.log(\"Hello from Vercel!\")"');
|
|
79
79
|
console.log(result.stdout);
|
|
80
80
|
|
|
81
81
|
await sandbox.destroy();
|
|
@@ -129,20 +129,20 @@ interface VercelConfig {
|
|
|
129
129
|
|
|
130
130
|
```typescript
|
|
131
131
|
// Execute Node.js code
|
|
132
|
-
const result = await sandbox.
|
|
132
|
+
const result = await sandbox.runCommand(`node - <<'JS'
|
|
133
133
|
const data = { message: "Hello from Node.js" };
|
|
134
134
|
console.log(JSON.stringify(data));
|
|
135
|
-
|
|
135
|
+
JS`);
|
|
136
136
|
|
|
137
137
|
// Execute Python code
|
|
138
|
-
const result = await sandbox.
|
|
138
|
+
const result = await sandbox.runCommand(`python - <<'PY'
|
|
139
139
|
import json
|
|
140
140
|
data = {"message": "Hello from Python"}
|
|
141
141
|
print(json.dumps(data))
|
|
142
|
-
|
|
142
|
+
PY`);
|
|
143
143
|
|
|
144
144
|
// Auto-detection (based on code patterns)
|
|
145
|
-
const result = await sandbox.
|
|
145
|
+
const result = await sandbox.runCommand('python -c "print(\"Auto-detected as Python\")"');
|
|
146
146
|
```
|
|
147
147
|
|
|
148
148
|
### Command Execution
|
|
@@ -225,7 +225,7 @@ try {
|
|
|
225
225
|
});
|
|
226
226
|
const sandbox = await compute.sandbox.create();
|
|
227
227
|
|
|
228
|
-
const result = await sandbox.
|
|
228
|
+
const result = await sandbox.runCommand('invalid code');
|
|
229
229
|
} catch (error) {
|
|
230
230
|
if (error.message.includes('Missing Vercel authentication')) {
|
|
231
231
|
console.error('Set VERCEL_OIDC_TOKEN or VERCEL_TOKEN environment variables');
|
|
@@ -249,7 +249,7 @@ import { vercel } from '@computesdk/vercel';
|
|
|
249
249
|
const compute = vercel({ runtime: 'node' });
|
|
250
250
|
const sandbox = await compute.sandbox.create();
|
|
251
251
|
|
|
252
|
-
const result = await sandbox.
|
|
252
|
+
const result = await sandbox.runCommand(`node - <<'JS'
|
|
253
253
|
const http = require('http');
|
|
254
254
|
const url = require('url');
|
|
255
255
|
|
|
@@ -272,7 +272,7 @@ const path = '/api/users';
|
|
|
272
272
|
const response = routes[path] ? routes[path]() : { error: 'Not found' };
|
|
273
273
|
|
|
274
274
|
console.log('Response:', JSON.stringify(response, null, 2));
|
|
275
|
-
`);
|
|
275
|
+
JS`);
|
|
276
276
|
|
|
277
277
|
console.log(result.stdout);
|
|
278
278
|
await sandbox.destroy();
|
|
@@ -286,7 +286,7 @@ import { vercel } from '@computesdk/vercel';
|
|
|
286
286
|
const compute = vercel({ runtime: 'python' });
|
|
287
287
|
const sandbox = await compute.sandbox.create();
|
|
288
288
|
|
|
289
|
-
const result = await sandbox.
|
|
289
|
+
const result = await sandbox.runCommand(`python - <<'PY'
|
|
290
290
|
import json
|
|
291
291
|
import statistics
|
|
292
292
|
from collections import Counter
|
|
@@ -317,7 +317,7 @@ print(f"Average Revenue per Product: ${avg_revenue:.2f}")
|
|
|
317
317
|
print("\\nRevenue by Product:")
|
|
318
318
|
for product, revenue in sorted(product_sales.items(), key=lambda x: x[1], reverse=True):
|
|
319
319
|
print(f" {product}: ${revenue}")
|
|
320
|
-
`);
|
|
320
|
+
PY`);
|
|
321
321
|
|
|
322
322
|
console.log(result.stdout);
|
|
323
323
|
await sandbox.destroy();
|
|
@@ -366,7 +366,7 @@ await sandbox.filesystem.writeFile(
|
|
|
366
366
|
);
|
|
367
367
|
|
|
368
368
|
// Process data
|
|
369
|
-
const result = await sandbox.
|
|
369
|
+
const result = await sandbox.runCommand(`python - <<'PY'
|
|
370
370
|
import json
|
|
371
371
|
import csv
|
|
372
372
|
from collections import defaultdict
|
|
@@ -416,7 +416,7 @@ print(f"Generated {len(results)} department statistics")
|
|
|
416
416
|
# Print summary
|
|
417
417
|
for result in results:
|
|
418
418
|
print(f"{result['department']}: {result['employee_count']} employees, avg salary ${result['average_salary']}")
|
|
419
|
-
`);
|
|
419
|
+
PY`);
|
|
420
420
|
|
|
421
421
|
console.log('Execution Output:', result.stdout);
|
|
422
422
|
|
|
@@ -450,7 +450,7 @@ const installResult = await sandbox.runCommand('npm', ['install', 'lodash']);
|
|
|
450
450
|
console.log('Install result:', installResult.stdout);
|
|
451
451
|
|
|
452
452
|
// Use lodash in code
|
|
453
|
-
const result = await sandbox.
|
|
453
|
+
const result = await sandbox.runCommand(`node - <<'JS'
|
|
454
454
|
const _ = require('lodash');
|
|
455
455
|
|
|
456
456
|
const data = [
|
|
@@ -470,7 +470,7 @@ console.log('Average age:', avgAge);
|
|
|
470
470
|
// Find oldest person
|
|
471
471
|
const oldest = _.maxBy(data, 'age');
|
|
472
472
|
console.log('Oldest person:', oldest.name);
|
|
473
|
-
`);
|
|
473
|
+
JS`);
|
|
474
474
|
|
|
475
475
|
console.log(result.stdout);
|
|
476
476
|
await sandbox.destroy();
|
|
@@ -502,4 +502,4 @@ await sandbox.destroy();
|
|
|
502
502
|
|
|
503
503
|
## License
|
|
504
504
|
|
|
505
|
-
MIT
|
|
505
|
+
MIT
|
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
|
|
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,152 +61,76 @@ 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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
...providerOptions
|
|
107
|
-
// Spread provider-specific options (e.g., resources, networkPolicy, signal)
|
|
108
|
-
};
|
|
109
|
-
const ports = optPorts ?? config.ports;
|
|
110
|
-
if (ports && ports.length > 0) {
|
|
111
|
-
params.ports = ports;
|
|
112
|
-
}
|
|
113
|
-
if (optRuntime) {
|
|
114
|
-
const vercelRuntime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
|
|
115
|
-
params.runtime = vercelRuntime;
|
|
116
|
-
}
|
|
117
|
-
const snapshotId = optSnapshotId || templateId || optSource?.type === "snapshot" && optSource?.snapshotId;
|
|
118
|
-
if (snapshotId) {
|
|
119
|
-
params.source = {
|
|
120
|
-
type: "snapshot",
|
|
121
|
-
snapshotId
|
|
122
|
-
};
|
|
123
|
-
} else if (optSource) {
|
|
124
|
-
params.source = optSource;
|
|
125
|
-
}
|
|
126
|
-
if (!creds.useOidc) {
|
|
127
|
-
params.token = creds.token;
|
|
128
|
-
params.teamId = creds.teamId;
|
|
129
|
-
params.projectId = creds.projectId;
|
|
130
|
-
}
|
|
131
|
-
sandbox = await import_sandbox.Sandbox.create(params);
|
|
69
|
+
const {
|
|
70
|
+
timeout: _timeout,
|
|
71
|
+
envs: _envs,
|
|
72
|
+
name: _name,
|
|
73
|
+
metadata: _metadata,
|
|
74
|
+
templateId,
|
|
75
|
+
snapshotId: optSnapshotId,
|
|
76
|
+
sandboxId: _sandboxId,
|
|
77
|
+
namespace: _namespace,
|
|
78
|
+
directory: _directory,
|
|
79
|
+
...providerOptions
|
|
80
|
+
} = options || {};
|
|
81
|
+
const optRuntime = options?.runtime;
|
|
82
|
+
const optPorts = options?.ports;
|
|
83
|
+
const optSource = options?.source;
|
|
84
|
+
const params = { timeout, ...providerOptions };
|
|
85
|
+
const ports = optPorts ?? config.ports;
|
|
86
|
+
if (ports && ports.length > 0) params.ports = ports;
|
|
87
|
+
if (optRuntime) {
|
|
88
|
+
params.runtime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
|
|
89
|
+
}
|
|
90
|
+
const snapshotId = optSnapshotId || templateId || optSource?.type === "snapshot" && optSource?.snapshotId;
|
|
91
|
+
if (snapshotId) {
|
|
92
|
+
params.source = { type: "snapshot", snapshotId };
|
|
93
|
+
} else if (optSource) {
|
|
94
|
+
params.source = optSource;
|
|
132
95
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
96
|
+
if (!creds.useOidc) {
|
|
97
|
+
params.token = creds.token;
|
|
98
|
+
params.teamId = creds.teamId;
|
|
99
|
+
params.projectId = creds.projectId;
|
|
100
|
+
}
|
|
101
|
+
const sandbox = await import_sandbox.Sandbox.create(params);
|
|
102
|
+
return { sandbox, sandboxId: sandbox.sandboxId };
|
|
137
103
|
} catch (error) {
|
|
138
104
|
if (error instanceof Error) {
|
|
139
105
|
if (error.message.includes("unauthorized") || error.message.includes("token")) {
|
|
140
|
-
throw new Error(
|
|
141
|
-
`Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
|
|
142
|
-
);
|
|
106
|
+
throw new Error(`Vercel authentication failed. Please check your VERCEL_TOKEN environment variable.`);
|
|
143
107
|
}
|
|
144
108
|
if (error.message.includes("team") || error.message.includes("project")) {
|
|
145
|
-
throw new Error(
|
|
146
|
-
`Vercel team/project configuration failed. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`
|
|
147
|
-
);
|
|
109
|
+
throw new Error(`Vercel team/project configuration failed. Check VERCEL_TEAM_ID and VERCEL_PROJECT_ID.`);
|
|
148
110
|
}
|
|
149
111
|
}
|
|
150
|
-
throw new Error(
|
|
151
|
-
`Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
152
|
-
);
|
|
112
|
+
throw new Error(`Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`);
|
|
153
113
|
}
|
|
154
114
|
},
|
|
155
115
|
getById: async (config, sandboxId) => {
|
|
156
116
|
const creds = resolveCredentials(config);
|
|
157
117
|
try {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
} else {
|
|
162
|
-
sandbox = await import_sandbox.Sandbox.get({
|
|
163
|
-
sandboxId,
|
|
164
|
-
token: creds.token,
|
|
165
|
-
teamId: creds.teamId,
|
|
166
|
-
projectId: creds.projectId
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
return {
|
|
170
|
-
sandbox,
|
|
171
|
-
sandboxId
|
|
172
|
-
};
|
|
173
|
-
} 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 {
|
|
174
121
|
return null;
|
|
175
122
|
}
|
|
176
123
|
},
|
|
177
124
|
list: async (_config) => {
|
|
178
|
-
throw new Error(
|
|
179
|
-
`Vercel provider does not support listing sandboxes. Vercel sandboxes are ephemeral and designed for single-use execution.`
|
|
180
|
-
);
|
|
125
|
+
throw new Error(`Vercel provider does not support listing sandboxes.`);
|
|
181
126
|
},
|
|
182
127
|
destroy: async (config, sandboxId) => {
|
|
183
128
|
const creds = resolveCredentials(config);
|
|
184
129
|
try {
|
|
185
|
-
|
|
186
|
-
if (creds.useOidc) {
|
|
187
|
-
sandbox = await import_sandbox.Sandbox.get({ sandboxId });
|
|
188
|
-
} else {
|
|
189
|
-
sandbox = await import_sandbox.Sandbox.get({
|
|
190
|
-
sandboxId,
|
|
191
|
-
token: creds.token,
|
|
192
|
-
teamId: creds.teamId,
|
|
193
|
-
projectId: creds.projectId
|
|
194
|
-
});
|
|
195
|
-
}
|
|
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 });
|
|
196
131
|
await sandbox.stop();
|
|
197
|
-
} catch
|
|
198
|
-
}
|
|
199
|
-
},
|
|
200
|
-
// Instance operations (map to individual Sandbox methods)
|
|
201
|
-
runCode: async (sandbox, code, runtime, config) => {
|
|
202
|
-
const startTime = Date.now();
|
|
203
|
-
const effectiveRuntime = runtime || config?.runtime || // Strong Python indicators
|
|
204
|
-
(code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") || code.includes("raise ") ? "python" : "node");
|
|
205
|
-
const encoded = Buffer.from(code).toString("base64");
|
|
206
|
-
const commandString = effectiveRuntime === "python" ? `echo "${encoded}" | base64 -d | python3` : `echo "${encoded}" | base64 -d | node`;
|
|
207
|
-
const result = await sandbox.runCommand("sh", ["-c", commandString]);
|
|
208
|
-
const stdout = await result.stdout();
|
|
209
|
-
const stderr = await result.stderr();
|
|
210
|
-
if (result.exitCode !== 0 && stderr) {
|
|
211
|
-
if (stderr.includes("SyntaxError") || stderr.includes("invalid syntax") || stderr.includes("Unexpected token") || stderr.includes("Unexpected identifier")) {
|
|
212
|
-
throw new Error(`Syntax error: ${stderr.trim()}`);
|
|
213
|
-
}
|
|
132
|
+
} catch {
|
|
214
133
|
}
|
|
215
|
-
return {
|
|
216
|
-
output: stdout + stderr,
|
|
217
|
-
exitCode: result.exitCode,
|
|
218
|
-
language: effectiveRuntime
|
|
219
|
-
};
|
|
220
134
|
},
|
|
221
135
|
runCommand: async (sandbox, command, options) => {
|
|
222
136
|
const startTime = Date.now();
|
|
@@ -236,35 +150,19 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
236
150
|
stdout: stdout?.sink,
|
|
237
151
|
stderr: stderr?.sink
|
|
238
152
|
});
|
|
239
|
-
return {
|
|
240
|
-
stdout: stdout?.value() ?? "",
|
|
241
|
-
stderr: stderr?.value() ?? "",
|
|
242
|
-
exitCode: result.exitCode ?? 0,
|
|
243
|
-
durationMs: Date.now() - startTime
|
|
244
|
-
};
|
|
153
|
+
return { stdout: stdout?.value() ?? "", stderr: stderr?.value() ?? "", exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };
|
|
245
154
|
} catch (error) {
|
|
246
|
-
return {
|
|
247
|
-
stdout: "",
|
|
248
|
-
stderr: error instanceof Error ? error.message : String(error),
|
|
249
|
-
exitCode: 127,
|
|
250
|
-
durationMs: Date.now() - startTime
|
|
251
|
-
};
|
|
155
|
+
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
|
|
252
156
|
}
|
|
253
157
|
},
|
|
254
|
-
getInfo: async (
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
timeout: 3e5,
|
|
263
|
-
metadata: {
|
|
264
|
-
vercelSandboxId: "vercel-unknown"
|
|
265
|
-
}
|
|
266
|
-
};
|
|
267
|
-
},
|
|
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
|
+
}),
|
|
268
166
|
getUrl: async (sandbox, options) => {
|
|
269
167
|
try {
|
|
270
168
|
let url = sandbox.domain(options.port);
|
|
@@ -275,21 +173,15 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
275
173
|
}
|
|
276
174
|
return url;
|
|
277
175
|
} catch (error) {
|
|
278
|
-
throw new Error(
|
|
279
|
-
`Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}. Ensure the port has an associated route.`
|
|
280
|
-
);
|
|
176
|
+
throw new Error(`Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}.`);
|
|
281
177
|
}
|
|
282
178
|
},
|
|
283
179
|
filesystem: {
|
|
284
180
|
readFile: async (sandbox, path) => {
|
|
285
181
|
const stream = await sandbox.readFile({ path });
|
|
286
|
-
if (!stream) {
|
|
287
|
-
throw new Error(`File not found: ${path}`);
|
|
288
|
-
}
|
|
182
|
+
if (!stream) throw new Error(`File not found: ${path}`);
|
|
289
183
|
const chunks = [];
|
|
290
|
-
for await (const chunk of stream)
|
|
291
|
-
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
292
|
-
}
|
|
184
|
+
for await (const chunk of stream) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
293
185
|
return Buffer.concat(chunks).toString("utf-8");
|
|
294
186
|
},
|
|
295
187
|
writeFile: async (sandbox, path, content) => {
|
|
@@ -299,82 +191,42 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
299
191
|
await sandbox.mkDir(path);
|
|
300
192
|
},
|
|
301
193
|
readdir: async (_sandbox, _path) => {
|
|
302
|
-
throw new Error("Vercel sandbox does not support readdir.
|
|
194
|
+
throw new Error("Vercel sandbox does not support readdir.");
|
|
303
195
|
},
|
|
304
196
|
exists: async (_sandbox, _path) => {
|
|
305
|
-
throw new Error("Vercel sandbox does not support exists.
|
|
197
|
+
throw new Error("Vercel sandbox does not support exists.");
|
|
306
198
|
},
|
|
307
199
|
remove: async (_sandbox, _path) => {
|
|
308
|
-
throw new Error("Vercel sandbox does not support remove.
|
|
200
|
+
throw new Error("Vercel sandbox does not support remove.");
|
|
309
201
|
}
|
|
310
202
|
},
|
|
311
|
-
|
|
312
|
-
getInstance: (sandbox) => {
|
|
313
|
-
return sandbox;
|
|
314
|
-
}
|
|
203
|
+
getInstance: (sandbox) => sandbox
|
|
315
204
|
},
|
|
316
205
|
snapshot: {
|
|
317
206
|
create: async (config, sandboxId) => {
|
|
318
207
|
const creds = resolveCredentials(config);
|
|
319
|
-
|
|
320
|
-
if (creds.useOidc) {
|
|
321
|
-
sandbox = await import_sandbox.Sandbox.get({ sandboxId });
|
|
322
|
-
} else {
|
|
323
|
-
sandbox = await import_sandbox.Sandbox.get({
|
|
324
|
-
sandboxId,
|
|
325
|
-
token: creds.token,
|
|
326
|
-
teamId: creds.teamId,
|
|
327
|
-
projectId: creds.projectId
|
|
328
|
-
});
|
|
329
|
-
}
|
|
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 });
|
|
330
209
|
return await sandbox.snapshot();
|
|
331
210
|
},
|
|
332
211
|
list: async (_config) => {
|
|
333
|
-
throw new Error(
|
|
334
|
-
`Vercel provider does not support listing snapshots.`
|
|
335
|
-
);
|
|
212
|
+
throw new Error(`Vercel provider does not support listing snapshots.`);
|
|
336
213
|
},
|
|
337
214
|
delete: async (config, snapshotId) => {
|
|
338
215
|
const creds = resolveCredentials(config);
|
|
339
|
-
|
|
340
|
-
if (creds.useOidc) {
|
|
341
|
-
snapshot = await import_sandbox.Snapshot.get({ snapshotId });
|
|
342
|
-
} else {
|
|
343
|
-
snapshot = await import_sandbox.Snapshot.get({
|
|
344
|
-
snapshotId,
|
|
345
|
-
token: creds.token,
|
|
346
|
-
teamId: creds.teamId,
|
|
347
|
-
projectId: creds.projectId
|
|
348
|
-
});
|
|
349
|
-
}
|
|
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 });
|
|
350
217
|
await snapshot.delete();
|
|
351
218
|
}
|
|
352
219
|
},
|
|
353
|
-
// Vercel doesn't have a separate "template" concept - snapshots serve as templates
|
|
354
220
|
template: {
|
|
355
221
|
create: async (_config, _options) => {
|
|
356
|
-
throw new Error(
|
|
357
|
-
`Vercel does not support creating templates directly. Use snapshot.create() to create a snapshot from a running sandbox.`
|
|
358
|
-
);
|
|
222
|
+
throw new Error(`Vercel does not support creating templates directly. Use snapshot.create() instead.`);
|
|
359
223
|
},
|
|
360
224
|
list: async (_config) => {
|
|
361
|
-
throw new Error(
|
|
362
|
-
`Vercel provider does not support listing templates.`
|
|
363
|
-
);
|
|
225
|
+
throw new Error(`Vercel provider does not support listing templates.`);
|
|
364
226
|
},
|
|
365
227
|
delete: async (config, templateId) => {
|
|
366
228
|
const creds = resolveCredentials(config);
|
|
367
|
-
|
|
368
|
-
if (creds.useOidc) {
|
|
369
|
-
snapshot = await import_sandbox.Snapshot.get({ snapshotId: templateId });
|
|
370
|
-
} else {
|
|
371
|
-
snapshot = await import_sandbox.Snapshot.get({
|
|
372
|
-
snapshotId: templateId,
|
|
373
|
-
token: creds.token,
|
|
374
|
-
teamId: creds.teamId,
|
|
375
|
-
projectId: creds.projectId
|
|
376
|
-
});
|
|
377
|
-
}
|
|
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 });
|
|
378
230
|
await snapshot.delete();
|
|
379
231
|
}
|
|
380
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 if (options?.sandboxId) {\n // Vercel doesn't support reconnecting to existing sandboxes\n // Each sandbox is ephemeral and must be created fresh\n throw new Error(\n `Vercel provider does not support reconnecting to existing sandboxes. Vercel sandboxes are ephemeral and must be created fresh each time.`\n );\n } else {\n // 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 overlays: _overlays,\n servers: _servers,\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\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 runCode: async (sandbox: VercelSandbox, code: string, runtime?: Runtime, config?: VercelConfig): Promise<CodeResult> => {\n const startTime = Date.now();\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || config?.runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n const commandString = effectiveRuntime === 'python'\n ? `echo \"${encoded}\" | base64 -d | python3`\n : `echo \"${encoded}\" | base64 -d | node`;\n\n const result = await sandbox.runCommand('sh', ['-c', commandString]);\n // Call stdout/stderr sequentially to avoid \"Multiple consumers for logs\" warning\n const stdout = await result.stdout();\n const stderr = await result.stderr();\n\n // Check for syntax errors and throw them\n if (result.exitCode !== 0 && stderr) {\n if (stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax') ||\n stderr.includes('Unexpected token') ||\n stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${stderr.trim()}`);\n }\n }\n\n return {\n output: stdout + stderr,\n exitCode: result.exitCode,\n language: effectiveRuntime,\n };\n },\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
|
|
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,152 +37,76 @@ 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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
...providerOptions
|
|
83
|
-
// Spread provider-specific options (e.g., resources, networkPolicy, signal)
|
|
84
|
-
};
|
|
85
|
-
const ports = optPorts ?? config.ports;
|
|
86
|
-
if (ports && ports.length > 0) {
|
|
87
|
-
params.ports = ports;
|
|
88
|
-
}
|
|
89
|
-
if (optRuntime) {
|
|
90
|
-
const vercelRuntime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
|
|
91
|
-
params.runtime = vercelRuntime;
|
|
92
|
-
}
|
|
93
|
-
const snapshotId = optSnapshotId || templateId || optSource?.type === "snapshot" && optSource?.snapshotId;
|
|
94
|
-
if (snapshotId) {
|
|
95
|
-
params.source = {
|
|
96
|
-
type: "snapshot",
|
|
97
|
-
snapshotId
|
|
98
|
-
};
|
|
99
|
-
} else if (optSource) {
|
|
100
|
-
params.source = optSource;
|
|
101
|
-
}
|
|
102
|
-
if (!creds.useOidc) {
|
|
103
|
-
params.token = creds.token;
|
|
104
|
-
params.teamId = creds.teamId;
|
|
105
|
-
params.projectId = creds.projectId;
|
|
106
|
-
}
|
|
107
|
-
sandbox = await VercelSandbox.create(params);
|
|
45
|
+
const {
|
|
46
|
+
timeout: _timeout,
|
|
47
|
+
envs: _envs,
|
|
48
|
+
name: _name,
|
|
49
|
+
metadata: _metadata,
|
|
50
|
+
templateId,
|
|
51
|
+
snapshotId: optSnapshotId,
|
|
52
|
+
sandboxId: _sandboxId,
|
|
53
|
+
namespace: _namespace,
|
|
54
|
+
directory: _directory,
|
|
55
|
+
...providerOptions
|
|
56
|
+
} = options || {};
|
|
57
|
+
const optRuntime = options?.runtime;
|
|
58
|
+
const optPorts = options?.ports;
|
|
59
|
+
const optSource = options?.source;
|
|
60
|
+
const params = { timeout, ...providerOptions };
|
|
61
|
+
const ports = optPorts ?? config.ports;
|
|
62
|
+
if (ports && ports.length > 0) params.ports = ports;
|
|
63
|
+
if (optRuntime) {
|
|
64
|
+
params.runtime = optRuntime === "node" ? "node24" : optRuntime === "python" ? "python3.13" : optRuntime;
|
|
65
|
+
}
|
|
66
|
+
const snapshotId = optSnapshotId || templateId || optSource?.type === "snapshot" && optSource?.snapshotId;
|
|
67
|
+
if (snapshotId) {
|
|
68
|
+
params.source = { type: "snapshot", snapshotId };
|
|
69
|
+
} else if (optSource) {
|
|
70
|
+
params.source = optSource;
|
|
108
71
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
72
|
+
if (!creds.useOidc) {
|
|
73
|
+
params.token = creds.token;
|
|
74
|
+
params.teamId = creds.teamId;
|
|
75
|
+
params.projectId = creds.projectId;
|
|
76
|
+
}
|
|
77
|
+
const sandbox = await VercelSandbox.create(params);
|
|
78
|
+
return { sandbox, sandboxId: sandbox.sandboxId };
|
|
113
79
|
} catch (error) {
|
|
114
80
|
if (error instanceof Error) {
|
|
115
81
|
if (error.message.includes("unauthorized") || error.message.includes("token")) {
|
|
116
|
-
throw new Error(
|
|
117
|
-
`Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
|
|
118
|
-
);
|
|
82
|
+
throw new Error(`Vercel authentication failed. Please check your VERCEL_TOKEN environment variable.`);
|
|
119
83
|
}
|
|
120
84
|
if (error.message.includes("team") || error.message.includes("project")) {
|
|
121
|
-
throw new Error(
|
|
122
|
-
`Vercel team/project configuration failed. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`
|
|
123
|
-
);
|
|
85
|
+
throw new Error(`Vercel team/project configuration failed. Check VERCEL_TEAM_ID and VERCEL_PROJECT_ID.`);
|
|
124
86
|
}
|
|
125
87
|
}
|
|
126
|
-
throw new Error(
|
|
127
|
-
`Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
128
|
-
);
|
|
88
|
+
throw new Error(`Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`);
|
|
129
89
|
}
|
|
130
90
|
},
|
|
131
91
|
getById: async (config, sandboxId) => {
|
|
132
92
|
const creds = resolveCredentials(config);
|
|
133
93
|
try {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
} else {
|
|
138
|
-
sandbox = await VercelSandbox.get({
|
|
139
|
-
sandboxId,
|
|
140
|
-
token: creds.token,
|
|
141
|
-
teamId: creds.teamId,
|
|
142
|
-
projectId: creds.projectId
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
return {
|
|
146
|
-
sandbox,
|
|
147
|
-
sandboxId
|
|
148
|
-
};
|
|
149
|
-
} 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 {
|
|
150
97
|
return null;
|
|
151
98
|
}
|
|
152
99
|
},
|
|
153
100
|
list: async (_config) => {
|
|
154
|
-
throw new Error(
|
|
155
|
-
`Vercel provider does not support listing sandboxes. Vercel sandboxes are ephemeral and designed for single-use execution.`
|
|
156
|
-
);
|
|
101
|
+
throw new Error(`Vercel provider does not support listing sandboxes.`);
|
|
157
102
|
},
|
|
158
103
|
destroy: async (config, sandboxId) => {
|
|
159
104
|
const creds = resolveCredentials(config);
|
|
160
105
|
try {
|
|
161
|
-
|
|
162
|
-
if (creds.useOidc) {
|
|
163
|
-
sandbox = await VercelSandbox.get({ sandboxId });
|
|
164
|
-
} else {
|
|
165
|
-
sandbox = await VercelSandbox.get({
|
|
166
|
-
sandboxId,
|
|
167
|
-
token: creds.token,
|
|
168
|
-
teamId: creds.teamId,
|
|
169
|
-
projectId: creds.projectId
|
|
170
|
-
});
|
|
171
|
-
}
|
|
106
|
+
const sandbox = creds.useOidc ? await VercelSandbox.get({ sandboxId }) : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
|
|
172
107
|
await sandbox.stop();
|
|
173
|
-
} catch
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
// Instance operations (map to individual Sandbox methods)
|
|
177
|
-
runCode: async (sandbox, code, runtime, config) => {
|
|
178
|
-
const startTime = Date.now();
|
|
179
|
-
const effectiveRuntime = runtime || config?.runtime || // Strong Python indicators
|
|
180
|
-
(code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") || code.includes("raise ") ? "python" : "node");
|
|
181
|
-
const encoded = Buffer.from(code).toString("base64");
|
|
182
|
-
const commandString = effectiveRuntime === "python" ? `echo "${encoded}" | base64 -d | python3` : `echo "${encoded}" | base64 -d | node`;
|
|
183
|
-
const result = await sandbox.runCommand("sh", ["-c", commandString]);
|
|
184
|
-
const stdout = await result.stdout();
|
|
185
|
-
const stderr = await result.stderr();
|
|
186
|
-
if (result.exitCode !== 0 && stderr) {
|
|
187
|
-
if (stderr.includes("SyntaxError") || stderr.includes("invalid syntax") || stderr.includes("Unexpected token") || stderr.includes("Unexpected identifier")) {
|
|
188
|
-
throw new Error(`Syntax error: ${stderr.trim()}`);
|
|
189
|
-
}
|
|
108
|
+
} catch {
|
|
190
109
|
}
|
|
191
|
-
return {
|
|
192
|
-
output: stdout + stderr,
|
|
193
|
-
exitCode: result.exitCode,
|
|
194
|
-
language: effectiveRuntime
|
|
195
|
-
};
|
|
196
110
|
},
|
|
197
111
|
runCommand: async (sandbox, command, options) => {
|
|
198
112
|
const startTime = Date.now();
|
|
@@ -212,35 +126,19 @@ var vercel = defineProvider({
|
|
|
212
126
|
stdout: stdout?.sink,
|
|
213
127
|
stderr: stderr?.sink
|
|
214
128
|
});
|
|
215
|
-
return {
|
|
216
|
-
stdout: stdout?.value() ?? "",
|
|
217
|
-
stderr: stderr?.value() ?? "",
|
|
218
|
-
exitCode: result.exitCode ?? 0,
|
|
219
|
-
durationMs: Date.now() - startTime
|
|
220
|
-
};
|
|
129
|
+
return { stdout: stdout?.value() ?? "", stderr: stderr?.value() ?? "", exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };
|
|
221
130
|
} catch (error) {
|
|
222
|
-
return {
|
|
223
|
-
stdout: "",
|
|
224
|
-
stderr: error instanceof Error ? error.message : String(error),
|
|
225
|
-
exitCode: 127,
|
|
226
|
-
durationMs: Date.now() - startTime
|
|
227
|
-
};
|
|
131
|
+
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
|
|
228
132
|
}
|
|
229
133
|
},
|
|
230
|
-
getInfo: async (
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
timeout: 3e5,
|
|
239
|
-
metadata: {
|
|
240
|
-
vercelSandboxId: "vercel-unknown"
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
},
|
|
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
|
+
}),
|
|
244
142
|
getUrl: async (sandbox, options) => {
|
|
245
143
|
try {
|
|
246
144
|
let url = sandbox.domain(options.port);
|
|
@@ -251,21 +149,15 @@ var vercel = defineProvider({
|
|
|
251
149
|
}
|
|
252
150
|
return url;
|
|
253
151
|
} catch (error) {
|
|
254
|
-
throw new Error(
|
|
255
|
-
`Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}. Ensure the port has an associated route.`
|
|
256
|
-
);
|
|
152
|
+
throw new Error(`Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}.`);
|
|
257
153
|
}
|
|
258
154
|
},
|
|
259
155
|
filesystem: {
|
|
260
156
|
readFile: async (sandbox, path) => {
|
|
261
157
|
const stream = await sandbox.readFile({ path });
|
|
262
|
-
if (!stream) {
|
|
263
|
-
throw new Error(`File not found: ${path}`);
|
|
264
|
-
}
|
|
158
|
+
if (!stream) throw new Error(`File not found: ${path}`);
|
|
265
159
|
const chunks = [];
|
|
266
|
-
for await (const chunk of stream)
|
|
267
|
-
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
268
|
-
}
|
|
160
|
+
for await (const chunk of stream) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
269
161
|
return Buffer.concat(chunks).toString("utf-8");
|
|
270
162
|
},
|
|
271
163
|
writeFile: async (sandbox, path, content) => {
|
|
@@ -275,82 +167,42 @@ var vercel = defineProvider({
|
|
|
275
167
|
await sandbox.mkDir(path);
|
|
276
168
|
},
|
|
277
169
|
readdir: async (_sandbox, _path) => {
|
|
278
|
-
throw new Error("Vercel sandbox does not support readdir.
|
|
170
|
+
throw new Error("Vercel sandbox does not support readdir.");
|
|
279
171
|
},
|
|
280
172
|
exists: async (_sandbox, _path) => {
|
|
281
|
-
throw new Error("Vercel sandbox does not support exists.
|
|
173
|
+
throw new Error("Vercel sandbox does not support exists.");
|
|
282
174
|
},
|
|
283
175
|
remove: async (_sandbox, _path) => {
|
|
284
|
-
throw new Error("Vercel sandbox does not support remove.
|
|
176
|
+
throw new Error("Vercel sandbox does not support remove.");
|
|
285
177
|
}
|
|
286
178
|
},
|
|
287
|
-
|
|
288
|
-
getInstance: (sandbox) => {
|
|
289
|
-
return sandbox;
|
|
290
|
-
}
|
|
179
|
+
getInstance: (sandbox) => sandbox
|
|
291
180
|
},
|
|
292
181
|
snapshot: {
|
|
293
182
|
create: async (config, sandboxId) => {
|
|
294
183
|
const creds = resolveCredentials(config);
|
|
295
|
-
|
|
296
|
-
if (creds.useOidc) {
|
|
297
|
-
sandbox = await VercelSandbox.get({ sandboxId });
|
|
298
|
-
} else {
|
|
299
|
-
sandbox = await VercelSandbox.get({
|
|
300
|
-
sandboxId,
|
|
301
|
-
token: creds.token,
|
|
302
|
-
teamId: creds.teamId,
|
|
303
|
-
projectId: creds.projectId
|
|
304
|
-
});
|
|
305
|
-
}
|
|
184
|
+
const sandbox = creds.useOidc ? await VercelSandbox.get({ sandboxId }) : await VercelSandbox.get({ sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
|
|
306
185
|
return await sandbox.snapshot();
|
|
307
186
|
},
|
|
308
187
|
list: async (_config) => {
|
|
309
|
-
throw new Error(
|
|
310
|
-
`Vercel provider does not support listing snapshots.`
|
|
311
|
-
);
|
|
188
|
+
throw new Error(`Vercel provider does not support listing snapshots.`);
|
|
312
189
|
},
|
|
313
190
|
delete: async (config, snapshotId) => {
|
|
314
191
|
const creds = resolveCredentials(config);
|
|
315
|
-
|
|
316
|
-
if (creds.useOidc) {
|
|
317
|
-
snapshot = await VercelSnapshot.get({ snapshotId });
|
|
318
|
-
} else {
|
|
319
|
-
snapshot = await VercelSnapshot.get({
|
|
320
|
-
snapshotId,
|
|
321
|
-
token: creds.token,
|
|
322
|
-
teamId: creds.teamId,
|
|
323
|
-
projectId: creds.projectId
|
|
324
|
-
});
|
|
325
|
-
}
|
|
192
|
+
const snapshot = creds.useOidc ? await VercelSnapshot.get({ snapshotId }) : await VercelSnapshot.get({ snapshotId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
|
|
326
193
|
await snapshot.delete();
|
|
327
194
|
}
|
|
328
195
|
},
|
|
329
|
-
// Vercel doesn't have a separate "template" concept - snapshots serve as templates
|
|
330
196
|
template: {
|
|
331
197
|
create: async (_config, _options) => {
|
|
332
|
-
throw new Error(
|
|
333
|
-
`Vercel does not support creating templates directly. Use snapshot.create() to create a snapshot from a running sandbox.`
|
|
334
|
-
);
|
|
198
|
+
throw new Error(`Vercel does not support creating templates directly. Use snapshot.create() instead.`);
|
|
335
199
|
},
|
|
336
200
|
list: async (_config) => {
|
|
337
|
-
throw new Error(
|
|
338
|
-
`Vercel provider does not support listing templates.`
|
|
339
|
-
);
|
|
201
|
+
throw new Error(`Vercel provider does not support listing templates.`);
|
|
340
202
|
},
|
|
341
203
|
delete: async (config, templateId) => {
|
|
342
204
|
const creds = resolveCredentials(config);
|
|
343
|
-
|
|
344
|
-
if (creds.useOidc) {
|
|
345
|
-
snapshot = await VercelSnapshot.get({ snapshotId: templateId });
|
|
346
|
-
} else {
|
|
347
|
-
snapshot = await VercelSnapshot.get({
|
|
348
|
-
snapshotId: templateId,
|
|
349
|
-
token: creds.token,
|
|
350
|
-
teamId: creds.teamId,
|
|
351
|
-
projectId: creds.projectId
|
|
352
|
-
});
|
|
353
|
-
}
|
|
205
|
+
const snapshot = creds.useOidc ? await VercelSnapshot.get({ snapshotId: templateId }) : await VercelSnapshot.get({ snapshotId: templateId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
|
|
354
206
|
await snapshot.delete();
|
|
355
207
|
}
|
|
356
208
|
}
|
package/dist/index.mjs.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 if (options?.sandboxId) {\n // Vercel doesn't support reconnecting to existing sandboxes\n // Each sandbox is ephemeral and must be created fresh\n throw new Error(\n `Vercel provider does not support reconnecting to existing sandboxes. Vercel sandboxes are ephemeral and must be created fresh each time.`\n );\n } else {\n // 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 overlays: _overlays,\n servers: _servers,\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\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 runCode: async (sandbox: VercelSandbox, code: string, runtime?: Runtime, config?: VercelConfig): Promise<CodeResult> => {\n const startTime = Date.now();\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || config?.runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n const commandString = effectiveRuntime === 'python'\n ? `echo \"${encoded}\" | base64 -d | python3`\n : `echo \"${encoded}\" | base64 -d | node`;\n\n const result = await sandbox.runCommand('sh', ['-c', commandString]);\n // Call stdout/stderr sequentially to avoid \"Multiple consumers for logs\" warning\n const stdout = await result.stdout();\n const stderr = await result.stderr();\n\n // Check for syntax errors and throw them\n if (result.exitCode !== 0 && stderr) {\n if (stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax') ||\n stderr.includes('Unexpected token') ||\n stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${stderr.trim()}`);\n }\n }\n\n return {\n output: stdout + stderr,\n exitCode: result.exitCode,\n language: effectiveRuntime,\n };\n },\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":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@computesdk/vercel",
|
|
3
|
-
"version": "1.7.
|
|
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
|
-
"
|
|
24
|
-
"computesdk": "2.
|
|
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": "
|
|
56
|
+
"@computesdk/test-utils": "2.0.0"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"build": "tsup",
|