@computesdk/vercel 1.7.53 → 1.7.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +127 -43
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +128 -44
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as _computesdk_provider from '@computesdk/provider';
|
|
2
1
|
import * as computesdk from 'computesdk';
|
|
2
|
+
import * as _computesdk_provider from '@computesdk/provider';
|
|
3
3
|
import { Sandbox } from '@vercel/sandbox';
|
|
4
4
|
export { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ interface VercelConfig {
|
|
|
11
11
|
ports?: number[];
|
|
12
12
|
daemonSsePort?: number | false;
|
|
13
13
|
}
|
|
14
|
-
declare const vercel: (config: VercelConfig) => _computesdk_provider.Provider<Sandbox, any, any, computesdk.Volume> & {
|
|
14
|
+
declare const vercel: (config: VercelConfig & _computesdk_provider.ProcessRuntimeOptions) => _computesdk_provider.Provider<Sandbox, any, any, computesdk.Volume> & {
|
|
15
15
|
readonly sizes: computesdk.InstanceSizeManager;
|
|
16
16
|
};
|
|
17
17
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as _computesdk_provider from '@computesdk/provider';
|
|
2
1
|
import * as computesdk from 'computesdk';
|
|
2
|
+
import * as _computesdk_provider from '@computesdk/provider';
|
|
3
3
|
import { Sandbox } from '@vercel/sandbox';
|
|
4
4
|
export { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ interface VercelConfig {
|
|
|
11
11
|
ports?: number[];
|
|
12
12
|
daemonSsePort?: number | false;
|
|
13
13
|
}
|
|
14
|
-
declare const vercel: (config: VercelConfig) => _computesdk_provider.Provider<Sandbox, any, any, computesdk.Volume> & {
|
|
14
|
+
declare const vercel: (config: VercelConfig & _computesdk_provider.ProcessRuntimeOptions) => _computesdk_provider.Provider<Sandbox, any, any, computesdk.Volume> & {
|
|
15
15
|
readonly sizes: computesdk.InstanceSizeManager;
|
|
16
16
|
};
|
|
17
17
|
|
package/dist/index.js
CHANGED
|
@@ -54,16 +54,62 @@ function validateCredentials(creds) {
|
|
|
54
54
|
if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);
|
|
55
55
|
if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);
|
|
56
56
|
}
|
|
57
|
-
function getUtf8Sink() {
|
|
57
|
+
function getUtf8Sink(onChunk) {
|
|
58
58
|
const chunks = [];
|
|
59
59
|
const sink = new import_node_stream.Writable({
|
|
60
|
+
decodeStrings: false,
|
|
60
61
|
write(chunk, _enc, cb) {
|
|
61
|
-
|
|
62
|
+
const text = Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
|
|
63
|
+
chunks.push(text);
|
|
64
|
+
if (text && onChunk) onChunk(text);
|
|
62
65
|
cb();
|
|
63
66
|
}
|
|
64
67
|
});
|
|
65
68
|
return { sink, value: () => chunks.join("") };
|
|
66
69
|
}
|
|
70
|
+
function credentialParams(creds) {
|
|
71
|
+
return creds.useOidc ? {} : { token: creds.token, teamId: creds.teamId, projectId: creds.projectId };
|
|
72
|
+
}
|
|
73
|
+
var handleCredentials = /* @__PURE__ */ new WeakMap();
|
|
74
|
+
function track(sandbox, creds) {
|
|
75
|
+
handleCredentials.set(sandbox, creds);
|
|
76
|
+
return sandbox;
|
|
77
|
+
}
|
|
78
|
+
var DEADLINE_WRAPPER = 'if command -v setsid >/dev/null 2>&1; then setsid sh -c "$1" & else sh -c "$1" & fi; pid=$!; (sleep "$0"; kill -KILL -"$pid" || kill -KILL "$pid") >/dev/null 2>&1 & w=$!; wait "$pid"; rc=$?; kill "$w" 2>/dev/null; exit $rc';
|
|
79
|
+
async function execCommand(sandbox, command, options) {
|
|
80
|
+
const startTime = Date.now();
|
|
81
|
+
try {
|
|
82
|
+
const env = options?.env && Object.keys(options.env).length > 0 ? options.env : void 0;
|
|
83
|
+
const stdout = options?.background ? void 0 : getUtf8Sink(options?.onStdout);
|
|
84
|
+
const stderr = options?.background ? void 0 : getUtf8Sink(options?.onStderr);
|
|
85
|
+
const deadline = options?.timeout && !options.background ? options.timeout : void 0;
|
|
86
|
+
const args = deadline ? ["-c", DEADLINE_WRAPPER, String(deadline / 1e3), command] : ["-c", command];
|
|
87
|
+
const controller = deadline ? new AbortController() : void 0;
|
|
88
|
+
const timer = deadline ? setTimeout(() => controller.abort(), deadline + 3e3) : void 0;
|
|
89
|
+
try {
|
|
90
|
+
const result = await sandbox.runCommand({
|
|
91
|
+
cmd: "sh",
|
|
92
|
+
args,
|
|
93
|
+
cwd: options?.cwd,
|
|
94
|
+
env,
|
|
95
|
+
detached: options?.background,
|
|
96
|
+
stdout: stdout?.sink,
|
|
97
|
+
stderr: stderr?.sink,
|
|
98
|
+
signal: controller?.signal
|
|
99
|
+
});
|
|
100
|
+
return { stdout: stdout?.value() ?? "", stderr: stderr?.value() ?? "", exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };
|
|
101
|
+
} catch (error) {
|
|
102
|
+
if (controller?.signal.aborted) {
|
|
103
|
+
return { stdout: stdout?.value() ?? "", stderr: `${stderr?.value() ?? ""}Command timed out after ${deadline}ms`, exitCode: 124, durationMs: Date.now() - startTime };
|
|
104
|
+
}
|
|
105
|
+
throw error;
|
|
106
|
+
} finally {
|
|
107
|
+
if (timer) clearTimeout(timer);
|
|
108
|
+
}
|
|
109
|
+
} catch (error) {
|
|
110
|
+
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
67
113
|
var vercel = (0, import_provider.defineProvider)({
|
|
68
114
|
name: "vercel",
|
|
69
115
|
methods: {
|
|
@@ -75,8 +121,8 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
75
121
|
try {
|
|
76
122
|
const {
|
|
77
123
|
timeout: _timeout,
|
|
78
|
-
envs
|
|
79
|
-
name
|
|
124
|
+
envs,
|
|
125
|
+
name,
|
|
80
126
|
metadata: _metadata,
|
|
81
127
|
templateId,
|
|
82
128
|
snapshotId: optSnapshotId,
|
|
@@ -92,6 +138,8 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
92
138
|
const optPorts = options?.ports;
|
|
93
139
|
const optSource = options?.source;
|
|
94
140
|
const params = { timeout, ...providerOptions };
|
|
141
|
+
if (envs && Object.keys(envs).length > 0) params.env = { ...envs, ...providerOptions.env };
|
|
142
|
+
if (name) params.name = name;
|
|
95
143
|
params.persistent = providerOptions.persistent ?? providerOptions.ephemeral === false;
|
|
96
144
|
const optDaemonSsePort = options?.daemonSsePort;
|
|
97
145
|
const ports = mergeExposedPorts(optPorts, config.ports, optDaemonSsePort ?? config.daemonSsePort);
|
|
@@ -116,7 +164,7 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
116
164
|
params.teamId = creds.teamId;
|
|
117
165
|
params.projectId = creds.projectId;
|
|
118
166
|
}
|
|
119
|
-
const sandbox = await import_sandbox.Sandbox.create(params);
|
|
167
|
+
const sandbox = track(await import_sandbox.Sandbox.create(params), creds);
|
|
120
168
|
return { instance: sandbox, instanceId: sandbox.name };
|
|
121
169
|
} catch (error) {
|
|
122
170
|
if (error instanceof Error) {
|
|
@@ -134,54 +182,78 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
134
182
|
const creds = resolveCredentials(config);
|
|
135
183
|
try {
|
|
136
184
|
const sandbox = creds.useOidc ? await import_sandbox.Sandbox.get({ name: sandboxId }) : await import_sandbox.Sandbox.get({ name: sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
|
|
137
|
-
return { instance: sandbox, instanceId: sandboxId };
|
|
185
|
+
return { instance: track(sandbox, creds), instanceId: sandboxId };
|
|
138
186
|
} catch {
|
|
139
187
|
return null;
|
|
140
188
|
}
|
|
141
189
|
},
|
|
142
|
-
list: async (
|
|
143
|
-
|
|
190
|
+
list: async (config) => {
|
|
191
|
+
const creds = resolveCredentials(config);
|
|
192
|
+
validateCredentials(creds);
|
|
193
|
+
const page = await import_sandbox.Sandbox.list({ ...credentialParams(creds), sortBy: "createdAt", sortOrder: "desc" });
|
|
194
|
+
const live = (page.sandboxes ?? []).filter((s) => s.status === "running" || s.status === "pending" || s.persistent && (s.status === "stopping" || s.status === "stopped" || s.status === "snapshotting"));
|
|
195
|
+
const sandboxes = await Promise.all(live.map((s) => import_sandbox.Sandbox.get({ name: s.name, ...credentialParams(creds) }).catch(() => null)));
|
|
196
|
+
return sandboxes.filter((s) => s !== null).map((sandbox) => ({ instance: track(sandbox, creds), instanceId: sandbox.name }));
|
|
144
197
|
},
|
|
198
|
+
// Deletes the named sandbox. Persistent sandboxes snapshot themselves on
|
|
199
|
+
// every stop; those automatic snapshots go too, snapshots taken with
|
|
200
|
+
// snapshot.create stay.
|
|
145
201
|
destroy: async (config, sandboxId) => {
|
|
146
202
|
const creds = resolveCredentials(config);
|
|
203
|
+
let sandbox;
|
|
147
204
|
try {
|
|
148
|
-
|
|
149
|
-
await sandbox.stop();
|
|
205
|
+
sandbox = await import_sandbox.Sandbox.get({ name: sandboxId, ...credentialParams(creds) });
|
|
150
206
|
} catch {
|
|
207
|
+
return;
|
|
151
208
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
209
|
+
await sandbox.stop().catch(() => {
|
|
210
|
+
});
|
|
211
|
+
const automatic = [];
|
|
212
|
+
if (sandbox.persistent) {
|
|
213
|
+
try {
|
|
214
|
+
for await (const snap of await sandbox.listSnapshots()) {
|
|
215
|
+
if (snap.creationMethod === "automatic" && snap.status === "created") automatic.push(snap.id);
|
|
216
|
+
}
|
|
217
|
+
} catch {
|
|
160
218
|
}
|
|
161
|
-
const stdout = options?.background ? void 0 : getUtf8Sink();
|
|
162
|
-
const stderr = options?.background ? void 0 : getUtf8Sink();
|
|
163
|
-
const result = await sandbox.runCommand({
|
|
164
|
-
cmd: "sh",
|
|
165
|
-
args: ["-c", fullCommand],
|
|
166
|
-
cwd: options?.cwd,
|
|
167
|
-
detached: options?.background,
|
|
168
|
-
stdout: stdout?.sink,
|
|
169
|
-
stderr: stderr?.sink,
|
|
170
|
-
timeoutMs: options?.timeout
|
|
171
|
-
});
|
|
172
|
-
return { stdout: stdout?.value() ?? "", stderr: stderr?.value() ?? "", exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };
|
|
173
|
-
} catch (error) {
|
|
174
|
-
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
|
|
175
219
|
}
|
|
220
|
+
await sandbox.delete().catch(() => {
|
|
221
|
+
});
|
|
222
|
+
await Promise.all(automatic.map(async (snapshotId) => {
|
|
223
|
+
try {
|
|
224
|
+
await (await import_sandbox.Snapshot.get({ snapshotId, ...credentialParams(creds) })).delete();
|
|
225
|
+
} catch {
|
|
226
|
+
}
|
|
227
|
+
}));
|
|
228
|
+
},
|
|
229
|
+
// Vercel's pause is a stop: a persistent sandbox snapshots its whole
|
|
230
|
+
// filesystem on stop and restores it in the next session. Processes do
|
|
231
|
+
// not survive, and a non-persistent sandbox would lose its files.
|
|
232
|
+
pause: async (sandbox) => {
|
|
233
|
+
if (!sandbox.persistent) {
|
|
234
|
+
throw new Error(`Vercel can only pause persistent sandboxes; create the sandbox with { persistent: true }.`);
|
|
235
|
+
}
|
|
236
|
+
await sandbox.stop();
|
|
237
|
+
},
|
|
238
|
+
resume: async (sandbox) => {
|
|
239
|
+
const creds = handleCredentials.get(sandbox) ?? resolveCredentials({});
|
|
240
|
+
const resumed = await import_sandbox.Sandbox.get({ name: sandbox.name, resume: true, ...credentialParams(creds) });
|
|
241
|
+
return track(resumed, creds);
|
|
242
|
+
},
|
|
243
|
+
pauseCapabilities: { memory: false, createOptions: { persistent: true } },
|
|
244
|
+
runCommand: (sandbox, command, options) => execCommand(sandbox, command, options),
|
|
245
|
+
streamCommand: (sandbox, command, options) => execCommand(sandbox, command, options),
|
|
246
|
+
getInfo: async (sandbox) => {
|
|
247
|
+
const status = sandbox.status;
|
|
248
|
+
return {
|
|
249
|
+
id: sandbox.name,
|
|
250
|
+
provider: "vercel",
|
|
251
|
+
status: status === "failed" || status === "aborted" ? "error" : status === "stopping" || status === "stopped" ? "stopped" : "running",
|
|
252
|
+
createdAt: sandbox.createdAt,
|
|
253
|
+
timeout: sandbox.timeout ?? 3e5,
|
|
254
|
+
metadata: { vercelSandboxName: sandbox.name, vercelStatus: status }
|
|
255
|
+
};
|
|
176
256
|
},
|
|
177
|
-
getInfo: async (_sandbox) => ({
|
|
178
|
-
id: "vercel-unknown",
|
|
179
|
-
provider: "vercel",
|
|
180
|
-
status: "running",
|
|
181
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
182
|
-
timeout: 3e5,
|
|
183
|
-
metadata: { vercelSandboxId: "vercel-unknown" }
|
|
184
|
-
}),
|
|
185
257
|
getUrl: async (sandbox, options) => {
|
|
186
258
|
try {
|
|
187
259
|
let url = sandbox.domain(options.port);
|
|
@@ -237,14 +309,26 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
237
309
|
metadata: { name: options?.name, sourceSessionId: snapshot.sourceSessionId }
|
|
238
310
|
};
|
|
239
311
|
},
|
|
240
|
-
list: async (
|
|
241
|
-
|
|
312
|
+
list: async (config) => {
|
|
313
|
+
const creds = resolveCredentials(config);
|
|
314
|
+
validateCredentials(creds);
|
|
315
|
+
const page = await import_sandbox.Snapshot.list(credentialParams(creds));
|
|
316
|
+
return (page.snapshots ?? []).filter((snap) => snap.status === "created").map((snap) => ({
|
|
317
|
+
id: snap.id,
|
|
318
|
+
provider: "vercel",
|
|
319
|
+
createdAt: new Date(snap.createdAt),
|
|
320
|
+
metadata: { sourceSessionId: snap.sourceSessionId, sizeBytes: snap.sizeBytes, region: snap.region }
|
|
321
|
+
}));
|
|
242
322
|
},
|
|
243
323
|
delete: async (config, snapshotId) => {
|
|
244
324
|
const creds = resolveCredentials(config);
|
|
245
325
|
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 });
|
|
246
326
|
await snapshot.delete();
|
|
247
|
-
}
|
|
327
|
+
},
|
|
328
|
+
// The whole rootfs (/tmp, $HOME, /etc, ...) is restored; processes are
|
|
329
|
+
// not. Snapshotting stops the source (it still exists and needs
|
|
330
|
+
// destroying); its next call starts a new session from the snapshot.
|
|
331
|
+
capabilities: { scope: "rootfs", memory: false, destroysSource: true, source: "stopped" }
|
|
248
332
|
},
|
|
249
333
|
template: {
|
|
250
334
|
create: async (_config, _options) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n */\n\nimport { Sandbox as VercelSandbox, Snapshot as VercelSnapshot, Drive as VercelDrive } from '@vercel/sandbox';\nimport { defineProvider, escapeShellArg, resolveVolumeRef, isUnifiedVolumeMounts, withVolumeSettle } from '@computesdk/provider';\nimport { Writable } from 'node:stream';\n\nexport type { VercelSandbox, VercelSnapshot };\n\nimport type { CommandResult, InstanceInfo, CreateInstanceOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\nexport interface VercelConfig {\n token?: string;\n teamId?: string;\n projectId?: string;\n timeout?: number;\n ports?: number[];\n daemonSsePort?: number | false;\n}\n\nconst DEFAULT_DAEMON_SSE_PORT = 38989;\n\nfunction mergeExposedPorts(primary?: number[], fallback?: number[], daemonSsePort?: number | false): number[] {\n const daemonPort = daemonSsePort === false ? undefined : (daemonSsePort ?? DEFAULT_DAEMON_SSE_PORT);\n const merged = [...(primary ?? fallback ?? [])];\n if (typeof daemonPort === 'number') merged.push(daemonPort);\n return Array.from(new Set(merged.filter((port) => Number.isInteger(port) && port > 0 && port <= 65535)));\n}\n\ninterface ResolvedCredentials {\n useOidc: boolean;\n token: string;\n teamId: string;\n projectId: string;\n}\n\nfunction resolveCredentials(config: VercelConfig): ResolvedCredentials {\n const token = config.token || (typeof process !== 'undefined' && process.env?.VERCEL_TOKEN) || '';\n const teamId = config.teamId || (typeof process !== 'undefined' && process.env?.VERCEL_TEAM_ID) || '';\n const projectId = config.projectId || (typeof process !== 'undefined' && process.env?.VERCEL_PROJECT_ID) || '';\n const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n const useOidc = !hasConfigCredentials && !!oidcToken;\n return { useOidc, token, teamId, projectId };\n}\n\nfunction validateCredentials(creds: ResolvedCredentials): void {\n if (creds.useOidc) return;\n if (!creds.token) {\n throw new Error(\n `Missing Vercel authentication. Either:\\n` +\n `1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or\\n` +\n `2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable.`\n );\n }\n if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);\n if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);\n}\n\nfunction getUtf8Sink() {\n const chunks: string[] = [];\n const sink = new Writable({\n write(chunk, _enc, cb) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk.toString(\"utf8\") : String(chunk));\n cb();\n },\n });\n return { sink, value: () => chunks.join(\"\") };\n}\n\nexport const vercel = defineProvider<VercelSandbox, VercelConfig>({\n name: 'vercel',\n methods: {\n instances: {\n create: async (config: VercelConfig, options?: CreateInstanceOptions) => {\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 volumes,\n ...providerOptions\n } = options || {};\n // `volumes` only counts as unified VolumeMount[] when every entry\n // carries `volume`; a provider-native volumes spec stays in\n // providerOptions and reaches the wire untouched.\n const unifiedVolumes = isUnifiedVolumeMounts(volumes) ? volumes : undefined;\n if (volumes !== undefined && !unifiedVolumes) (providerOptions as any).volumes = volumes;\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 // Vercel sandboxes are persistent by default, which auto-snapshots the\n // filesystem on every stop() and accrues Snapshot Storage. ComputeSDK\n // sandboxes default to non-persistent unless the caller opts in via\n // `persistent: true` or asks for the durable surface (`ephemeral: false`).\n params.persistent = providerOptions.persistent ?? (providerOptions.ephemeral === false);\n const optDaemonSsePort = (options as any)?.daemonSsePort as number | false | undefined;\n const ports = mergeExposedPorts(optPorts, config.ports, optDaemonSsePort ?? config.daemonSsePort);\n if (ports && ports.length > 0) params.ports = ports;\n\n if (optRuntime) {\n params.runtime =\n optRuntime === 'node' ? 'node24' :\n optRuntime === 'python' ? 'python3.13' :\n optRuntime;\n }\n\n const snapshotId = optSnapshotId || templateId ||\n (optSource?.type === 'snapshot' && optSource?.snapshotId);\n if (snapshotId) {\n params.source = { type: 'snapshot', snapshotId };\n } else if (optSource) {\n params.source = optSource;\n }\n\n // Unified mounts → vercel's {path: {drive, mode}} wire shape.\n if (unifiedVolumes) {\n params.mounts = Object.fromEntries((unifiedVolumes as any[]).map((m) => {\n const ref = resolveVolumeRef(m.volume);\n // The `drive` field serializes verbatim and the API resolves it\n // by NAME (a Drive object mounts as mount.name) — sending\n // driveId yields \"Drive not found\".\n return [m.mountPath, { drive: ref.name ?? ref.id, mode: m.readOnly ? 'snapshot' : 'read-write' }];\n }));\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 { instance: sandbox, instanceId: sandbox.name };\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({ name: sandboxId })\n : await VercelSandbox.get({ name: sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n return { instance: sandbox, instanceId: 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({ name: sandboxId })\n : await VercelSandbox.get({ name: 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 timeoutMs: options?.timeout,\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<InstanceInfo> => ({\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> => {\n await sandbox.fs.mkdir(path, { recursive: true });\n },\n readdir: async (sandbox: VercelSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.fs.readdir(path, { withFileTypes: true });\n return entries.map((entry) => ({\n name: entry.name,\n type: entry.isDirectory() ? 'directory' : 'file',\n }));\n },\n exists: async (sandbox: VercelSandbox, path: string): Promise<boolean> => {\n return sandbox.fs.exists(path);\n },\n remove: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n await sandbox.fs.rm(path, { recursive: true, force: true });\n }\n },\n\n getInstance: (sandbox: VercelSandbox): VercelSandbox => sandbox,\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string, options?: { name?: string }) => {\n const creds = resolveCredentials(config);\n const sandbox = creds.useOidc\n ? await VercelSandbox.get({ name: sandboxId })\n : await VercelSandbox.get({ name: sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n const snapshot = await sandbox.snapshot();\n // @vercel/sandbox's Snapshot class exposes `snapshotId`, not `id` —\n // map it to the ComputeSDK Snapshot shape ({ id }) consumers rely on.\n return {\n id: snapshot.snapshotId,\n provider: 'vercel',\n createdAt: snapshot.createdAt,\n metadata: { name: options?.name, sourceSessionId: snapshot.sourceSessionId },\n };\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 volume: {\n create: async (config: VercelConfig, options) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? { name: options.name }\n : { name: options.name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.getOrCreate(params as any);\n return { id: drive.driveId, name: drive.name, native: drive };\n },\n get: async (config: VercelConfig, name: string) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n try {\n const params = creds.useOidc\n ? { name }\n : { name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.get(params as any);\n return { id: drive.driveId, name: drive.name, native: drive };\n } catch { return null; }\n },\n list: async (config: VercelConfig) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? {}\n : { token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const page = await VercelDrive.list(params as any);\n const out: any[] = [];\n for await (const drive of page as any) {\n out.push({ id: drive.driveId, name: drive.name, native: drive });\n }\n return out;\n },\n delete: async (config: VercelConfig, name: string) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? { name }\n : { name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.get(params as any);\n await withVolumeSettle(() => drive.delete());\n },\n }\n }\n});\n"],"mappings":"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","names":["VercelSandbox","VercelSnapshot","VercelDrive"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n */\n\nimport { Sandbox as VercelSandbox, Snapshot as VercelSnapshot, Drive as VercelDrive } from '@vercel/sandbox';\nimport { defineProvider, resolveVolumeRef, isUnifiedVolumeMounts, withVolumeSettle } from '@computesdk/provider';\nimport { Writable } from 'node:stream';\n\nexport type { VercelSandbox, VercelSnapshot };\n\nimport type { CommandResult, InstanceInfo, CreateInstanceOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\nexport interface VercelConfig {\n token?: string;\n teamId?: string;\n projectId?: string;\n timeout?: number;\n ports?: number[];\n daemonSsePort?: number | false;\n}\n\nconst DEFAULT_DAEMON_SSE_PORT = 38989;\n\nfunction mergeExposedPorts(primary?: number[], fallback?: number[], daemonSsePort?: number | false): number[] {\n const daemonPort = daemonSsePort === false ? undefined : (daemonSsePort ?? DEFAULT_DAEMON_SSE_PORT);\n const merged = [...(primary ?? fallback ?? [])];\n if (typeof daemonPort === 'number') merged.push(daemonPort);\n return Array.from(new Set(merged.filter((port) => Number.isInteger(port) && port > 0 && port <= 65535)));\n}\n\ninterface ResolvedCredentials {\n useOidc: boolean;\n token: string;\n teamId: string;\n projectId: string;\n}\n\nfunction resolveCredentials(config: VercelConfig): ResolvedCredentials {\n const token = config.token || (typeof process !== 'undefined' && process.env?.VERCEL_TOKEN) || '';\n const teamId = config.teamId || (typeof process !== 'undefined' && process.env?.VERCEL_TEAM_ID) || '';\n const projectId = config.projectId || (typeof process !== 'undefined' && process.env?.VERCEL_PROJECT_ID) || '';\n const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n const useOidc = !hasConfigCredentials && !!oidcToken;\n return { useOidc, token, teamId, projectId };\n}\n\nfunction validateCredentials(creds: ResolvedCredentials): void {\n if (creds.useOidc) return;\n if (!creds.token) {\n throw new Error(\n `Missing Vercel authentication. Either:\\n` +\n `1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or\\n` +\n `2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable.`\n );\n }\n if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);\n if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);\n}\n\nfunction getUtf8Sink(onChunk?: (data: string) => void) {\n const chunks: string[] = [];\n const sink = new Writable({\n decodeStrings: false,\n write(chunk, _enc, cb) {\n const text = Buffer.isBuffer(chunk) ? chunk.toString(\"utf8\") : String(chunk);\n chunks.push(text);\n if (text && onChunk) onChunk(text);\n cb();\n },\n });\n return { sink, value: () => chunks.join(\"\") };\n}\n\nfunction credentialParams(creds: ResolvedCredentials) {\n return creds.useOidc ? {} : { token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n}\n\n// The credentials each handle was fetched with, so `resume` can fetch the\n// fresh session handle the same way.\nconst handleCredentials = new WeakMap<VercelSandbox, ResolvedCredentials>();\n\nfunction track(sandbox: VercelSandbox, creds: ResolvedCredentials): VercelSandbox {\n handleCredentials.set(sandbox, creds);\n return sandbox;\n}\n\n// `setsid` gives the command its own process group, so the watchdog can kill\n// the whole tree, not just the outer shell.\nconst DEADLINE_WRAPPER = 'if command -v setsid >/dev/null 2>&1; then setsid sh -c \"$1\" & else sh -c \"$1\" & fi; pid=$!; (sleep \"$0\"; kill -KILL -\"$pid\" || kill -KILL \"$pid\") >/dev/null 2>&1 & w=$!; wait \"$pid\"; rc=$?; kill \"$w\" 2>/dev/null; exit $rc';\n\n// Runs through the SDK's native env/cwd fields; stdout/stderr arrive on the\n// sinks while the command runs, so the same path serves streamCommand.\nasync function execCommand(sandbox: VercelSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> {\n const startTime = Date.now();\n try {\n const env = options?.env && Object.keys(options.env).length > 0 ? options.env : undefined;\n const stdout = options?.background ? undefined : getUtf8Sink(options?.onStdout);\n const stderr = options?.background ? undefined : getUtf8Sink(options?.onStderr);\n const deadline = options?.timeout && !options.background ? options.timeout : undefined;\n // A watchdog in the box kills the command's whole process group at the\n // deadline; the abort is a backstop so the caller still returns on time.\n const args = deadline ? ['-c', DEADLINE_WRAPPER, String(deadline / 1000), command] : ['-c', command];\n const controller = deadline ? new AbortController() : undefined;\n const timer = deadline ? setTimeout(() => controller!.abort(), deadline + 3000) : undefined;\n try {\n const result = await sandbox.runCommand({\n cmd: 'sh', args,\n cwd: options?.cwd, env, detached: options?.background,\n stdout: stdout?.sink, stderr: stderr?.sink,\n signal: controller?.signal,\n });\n return { stdout: stdout?.value() ?? '', stderr: stderr?.value() ?? '', exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };\n } catch (error) {\n if (controller?.signal.aborted) {\n return { stdout: stdout?.value() ?? '', stderr: `${stderr?.value() ?? ''}Command timed out after ${deadline}ms`, exitCode: 124, durationMs: Date.now() - startTime };\n }\n throw error;\n } finally {\n if (timer) clearTimeout(timer);\n }\n } catch (error) {\n return { stdout: '', stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };\n }\n}\n\nexport const vercel = defineProvider<VercelSandbox, VercelConfig>({\n name: 'vercel',\n methods: {\n instances: {\n create: async (config: VercelConfig, options?: CreateInstanceOptions) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const timeout = options?.timeout ?? config.timeout ?? 300000;\n try {\n const {\n timeout: _timeout, envs, name, metadata: _metadata,\n templateId, snapshotId: optSnapshotId, sandboxId: _sandboxId,\n namespace: _namespace, directory: _directory,\n volumes,\n ...providerOptions\n } = options || {};\n // `volumes` only counts as unified VolumeMount[] when every entry\n // carries `volume`; a provider-native volumes spec stays in\n // providerOptions and reaches the wire untouched.\n const unifiedVolumes = isUnifiedVolumeMounts(volumes) ? volumes : undefined;\n if (volumes !== undefined && !unifiedVolumes) (providerOptions as any).volumes = volumes;\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 if (envs && Object.keys(envs).length > 0) params.env = { ...envs, ...(providerOptions as any).env };\n if (name) params.name = name;\n // Vercel sandboxes are persistent by default, which auto-snapshots the\n // filesystem on every stop() and accrues Snapshot Storage. ComputeSDK\n // sandboxes default to non-persistent unless the caller opts in via\n // `persistent: true` or asks for the durable surface (`ephemeral: false`).\n params.persistent = providerOptions.persistent ?? (providerOptions.ephemeral === false);\n const optDaemonSsePort = (options as any)?.daemonSsePort as number | false | undefined;\n const ports = mergeExposedPorts(optPorts, config.ports, optDaemonSsePort ?? config.daemonSsePort);\n if (ports && ports.length > 0) params.ports = ports;\n\n if (optRuntime) {\n params.runtime =\n optRuntime === 'node' ? 'node24' :\n optRuntime === 'python' ? 'python3.13' :\n optRuntime;\n }\n\n const snapshotId = optSnapshotId || templateId ||\n (optSource?.type === 'snapshot' && optSource?.snapshotId);\n if (snapshotId) {\n params.source = { type: 'snapshot', snapshotId };\n } else if (optSource) {\n params.source = optSource;\n }\n\n // Unified mounts → vercel's {path: {drive, mode}} wire shape.\n if (unifiedVolumes) {\n params.mounts = Object.fromEntries((unifiedVolumes as any[]).map((m) => {\n const ref = resolveVolumeRef(m.volume);\n // The `drive` field serializes verbatim and the API resolves it\n // by NAME (a Drive object mounts as mount.name) — sending\n // driveId yields \"Drive not found\".\n return [m.mountPath, { drive: ref.name ?? ref.id, mode: m.readOnly ? 'snapshot' : 'read-write' }];\n }));\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 = track(await VercelSandbox.create(params), creds);\n return { instance: sandbox, instanceId: sandbox.name };\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({ name: sandboxId })\n : await VercelSandbox.get({ name: sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n return { instance: track(sandbox, creds), instanceId: sandboxId };\n } catch { return null; }\n },\n\n list: async (config: VercelConfig) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const page = await VercelSandbox.list({ ...credentialParams(creds), sortBy: 'createdAt', sortOrder: 'desc' } as any);\n // Paused (stopped) persistent sandboxes stay listed so callers can resume them.\n const live = (page.sandboxes ?? []).filter((s: any) => s.status === 'running' || s.status === 'pending'\n || (s.persistent && (s.status === 'stopping' || s.status === 'stopped' || s.status === 'snapshotting')));\n const sandboxes = await Promise.all(live.map((s: any) =>\n VercelSandbox.get({ name: s.name, ...credentialParams(creds) } as any).catch(() => null)));\n return sandboxes\n .filter((s): s is VercelSandbox => s !== null)\n .map((sandbox) => ({ instance: track(sandbox, creds), instanceId: sandbox.name }));\n },\n\n // Deletes the named sandbox. Persistent sandboxes snapshot themselves on\n // every stop; those automatic snapshots go too, snapshots taken with\n // snapshot.create stay.\n destroy: async (config: VercelConfig, sandboxId: string) => {\n const creds = resolveCredentials(config);\n let sandbox: VercelSandbox;\n try {\n sandbox = await VercelSandbox.get({ name: sandboxId, ...credentialParams(creds) } as any);\n } catch { return; /* already destroyed or doesn't exist */ }\n await sandbox.stop().catch(() => { /* already stopped */ });\n const automatic: string[] = [];\n if (sandbox.persistent) {\n try {\n for await (const snap of await sandbox.listSnapshots()) {\n if (snap.creationMethod === 'automatic' && snap.status === 'created') automatic.push(snap.id);\n }\n } catch { /* nothing to clean up */ }\n }\n await sandbox.delete().catch(() => { /* already deleted */ });\n await Promise.all(automatic.map(async (snapshotId) => {\n try {\n await (await VercelSnapshot.get({ snapshotId, ...credentialParams(creds) } as any)).delete();\n } catch { /* expired or already deleted */ }\n }));\n },\n\n // Vercel's pause is a stop: a persistent sandbox snapshots its whole\n // filesystem on stop and restores it in the next session. Processes do\n // not survive, and a non-persistent sandbox would lose its files.\n pause: async (sandbox: VercelSandbox) => {\n if (!sandbox.persistent) {\n throw new Error(`Vercel can only pause persistent sandboxes; create the sandbox with { persistent: true }.`);\n }\n await sandbox.stop();\n },\n\n resume: async (sandbox: VercelSandbox) => {\n const creds = handleCredentials.get(sandbox) ?? resolveCredentials({});\n const resumed = await VercelSandbox.get({ name: sandbox.name, resume: true, ...credentialParams(creds) } as any);\n return track(resumed, creds);\n },\n\n pauseCapabilities: { memory: false, createOptions: { persistent: true } },\n\n runCommand: (sandbox: VercelSandbox, command: string, options?: RunCommandOptions) => execCommand(sandbox, command, options),\n\n streamCommand: (sandbox: VercelSandbox, command: string, options: RunCommandOptions) => execCommand(sandbox, command, options),\n\n getInfo: async (sandbox: VercelSandbox): Promise<InstanceInfo> => {\n const status = sandbox.status;\n return {\n id: sandbox.name,\n provider: 'vercel',\n status: status === 'failed' || status === 'aborted' ? 'error'\n : status === 'stopping' || status === 'stopped' ? 'stopped'\n : 'running',\n createdAt: sandbox.createdAt,\n timeout: sandbox.timeout ?? 300000,\n metadata: { vercelSandboxName: sandbox.name, vercelStatus: status },\n };\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> => {\n await sandbox.fs.mkdir(path, { recursive: true });\n },\n readdir: async (sandbox: VercelSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.fs.readdir(path, { withFileTypes: true });\n return entries.map((entry) => ({\n name: entry.name,\n type: entry.isDirectory() ? 'directory' : 'file',\n }));\n },\n exists: async (sandbox: VercelSandbox, path: string): Promise<boolean> => {\n return sandbox.fs.exists(path);\n },\n remove: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n await sandbox.fs.rm(path, { recursive: true, force: true });\n }\n },\n\n getInstance: (sandbox: VercelSandbox): VercelSandbox => sandbox,\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string, options?: { name?: string }) => {\n const creds = resolveCredentials(config);\n const sandbox = creds.useOidc\n ? await VercelSandbox.get({ name: sandboxId })\n : await VercelSandbox.get({ name: sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n const snapshot = await sandbox.snapshot();\n // @vercel/sandbox's Snapshot class exposes `snapshotId`, not `id` —\n // map it to the ComputeSDK Snapshot shape ({ id }) consumers rely on.\n return {\n id: snapshot.snapshotId,\n provider: 'vercel',\n createdAt: snapshot.createdAt,\n metadata: { name: options?.name, sourceSessionId: snapshot.sourceSessionId },\n };\n },\n list: async (config: VercelConfig) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const page = await VercelSnapshot.list(credentialParams(creds) as any);\n return (page.snapshots ?? [])\n .filter((snap: any) => snap.status === 'created')\n .map((snap: any) => ({\n id: snap.id,\n provider: 'vercel',\n createdAt: new Date(snap.createdAt),\n metadata: { sourceSessionId: snap.sourceSessionId, sizeBytes: snap.sizeBytes, region: snap.region },\n }));\n },\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 // The whole rootfs (/tmp, $HOME, /etc, ...) is restored; processes are\n // not. Snapshotting stops the source (it still exists and needs\n // destroying); its next call starts a new session from the snapshot.\n capabilities: { scope: 'rootfs', memory: false, destroysSource: true, source: 'stopped' },\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 volume: {\n create: async (config: VercelConfig, options) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? { name: options.name }\n : { name: options.name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.getOrCreate(params as any);\n return { id: drive.driveId, name: drive.name, native: drive };\n },\n get: async (config: VercelConfig, name: string) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n try {\n const params = creds.useOidc\n ? { name }\n : { name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.get(params as any);\n return { id: drive.driveId, name: drive.name, native: drive };\n } catch { return null; }\n },\n list: async (config: VercelConfig) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? {}\n : { token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const page = await VercelDrive.list(params as any);\n const out: any[] = [];\n for await (const drive of page as any) {\n out.push({ id: drive.driveId, name: drive.name, native: drive });\n }\n return out;\n },\n delete: async (config: VercelConfig, name: string) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? { name }\n : { name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.get(params as any);\n await withVolumeSettle(() => drive.delete());\n },\n }\n }\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,qBAA2F;AAC3F,sBAA0F;AAC1F,yBAAyB;AAezB,IAAM,0BAA0B;AAEhC,SAAS,kBAAkB,SAAoB,UAAqB,eAA0C;AAC5G,QAAM,aAAa,kBAAkB,QAAQ,SAAa,iBAAiB;AAC3E,QAAM,SAAS,CAAC,GAAI,WAAW,YAAY,CAAC,CAAE;AAC9C,MAAI,OAAO,eAAe,SAAU,QAAO,KAAK,UAAU;AAC1D,SAAO,MAAM,KAAK,IAAI,IAAI,OAAO,OAAO,CAAC,SAAS,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,QAAQ,KAAK,CAAC,CAAC;AACzG;AASA,SAAS,mBAAmB,QAA2C;AACrE,QAAM,QAAQ,OAAO,SAAU,OAAO,YAAY,eAAe,QAAQ,KAAK,gBAAiB;AAC/F,QAAM,SAAS,OAAO,UAAW,OAAO,YAAY,eAAe,QAAQ,KAAK,kBAAmB;AACnG,QAAM,YAAY,OAAO,aAAc,OAAO,YAAY,eAAe,QAAQ,KAAK,qBAAsB;AAC5G,QAAM,uBAAuB,CAAC,EAAE,OAAO,SAAS,OAAO,UAAU,OAAO;AACxE,QAAM,YAAY,OAAO,YAAY,eAAe,QAAQ,KAAK;AACjE,QAAM,UAAU,CAAC,wBAAwB,CAAC,CAAC;AAC3C,SAAO,EAAE,SAAS,OAAO,QAAQ,UAAU;AAC7C;AAEA,SAAS,oBAAoB,OAAkC;AAC7D,MAAI,MAAM,QAAS;AACnB,MAAI,CAAC,MAAM,OAAO;AAChB,UAAM,IAAI;AAAA,MACR;AAAA;AAAA;AAAA,IAGF;AAAA,EACF;AACA,MAAI,CAAC,MAAM,OAAQ,OAAM,IAAI,MAAM,2EAA2E;AAC9G,MAAI,CAAC,MAAM,UAAW,OAAM,IAAI,MAAM,oFAAoF;AAC5H;AAEA,SAAS,YAAY,SAAkC;AACrD,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAO,IAAI,4BAAS;AAAA,IACxB,eAAe;AAAA,IACf,MAAM,OAAO,MAAM,IAAI;AACrB,YAAM,OAAO,OAAO,SAAS,KAAK,IAAI,MAAM,SAAS,MAAM,IAAI,OAAO,KAAK;AAC3E,aAAO,KAAK,IAAI;AAChB,UAAI,QAAQ,QAAS,SAAQ,IAAI;AACjC,SAAG;AAAA,IACL;AAAA,EACF,CAAC;AACD,SAAO,EAAE,MAAM,OAAO,MAAM,OAAO,KAAK,EAAE,EAAE;AAC9C;AAEA,SAAS,iBAAiB,OAA4B;AACpD,SAAO,MAAM,UAAU,CAAC,IAAI,EAAE,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU;AACrG;AAIA,IAAM,oBAAoB,oBAAI,QAA4C;AAE1E,SAAS,MAAM,SAAwB,OAA2C;AAChF,oBAAkB,IAAI,SAAS,KAAK;AACpC,SAAO;AACT;AAIA,IAAM,mBAAmB;AAIzB,eAAe,YAAY,SAAwB,SAAiB,SAAqD;AACvH,QAAM,YAAY,KAAK,IAAI;AAC3B,MAAI;AACF,UAAM,MAAM,SAAS,OAAO,OAAO,KAAK,QAAQ,GAAG,EAAE,SAAS,IAAI,QAAQ,MAAM;AAChF,UAAM,SAAS,SAAS,aAAa,SAAY,YAAY,SAAS,QAAQ;AAC9E,UAAM,SAAS,SAAS,aAAa,SAAY,YAAY,SAAS,QAAQ;AAC9E,UAAM,WAAW,SAAS,WAAW,CAAC,QAAQ,aAAa,QAAQ,UAAU;AAG7E,UAAM,OAAO,WAAW,CAAC,MAAM,kBAAkB,OAAO,WAAW,GAAI,GAAG,OAAO,IAAI,CAAC,MAAM,OAAO;AACnG,UAAM,aAAa,WAAW,IAAI,gBAAgB,IAAI;AACtD,UAAM,QAAQ,WAAW,WAAW,MAAM,WAAY,MAAM,GAAG,WAAW,GAAI,IAAI;AAClF,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,WAAW;AAAA,QACtC,KAAK;AAAA,QAAM;AAAA,QACX,KAAK,SAAS;AAAA,QAAK;AAAA,QAAK,UAAU,SAAS;AAAA,QAC3C,QAAQ,QAAQ;AAAA,QAAM,QAAQ,QAAQ;AAAA,QACtC,QAAQ,YAAY;AAAA,MACtB,CAAC;AACD,aAAO,EAAE,QAAQ,QAAQ,MAAM,KAAK,IAAI,QAAQ,QAAQ,MAAM,KAAK,IAAI,UAAU,OAAO,YAAY,GAAG,YAAY,KAAK,IAAI,IAAI,UAAU;AAAA,IAC5I,SAAS,OAAO;AACd,UAAI,YAAY,OAAO,SAAS;AAC9B,eAAO,EAAE,QAAQ,QAAQ,MAAM,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,KAAK,EAAE,2BAA2B,QAAQ,MAAM,UAAU,KAAK,YAAY,KAAK,IAAI,IAAI,UAAU;AAAA,MACrK;AACA,YAAM;AAAA,IACR,UAAE;AACA,UAAI,MAAO,cAAa,KAAK;AAAA,IAC/B;AAAA,EACF,SAAS,OAAO;AACd,WAAO,EAAE,QAAQ,IAAI,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG,UAAU,KAAK,YAAY,KAAK,IAAI,IAAI,UAAU;AAAA,EACzI;AACF;AAEO,IAAM,aAAS,gCAA4C;AAAA,EAChE,MAAM;AAAA,EACN,SAAS;AAAA,IACP,WAAW;AAAA,MACT,QAAQ,OAAO,QAAsB,YAAoC;AACvE,cAAM,QAAQ,mBAAmB,MAAM;AACvC,4BAAoB,KAAK;AACzB,cAAM,UAAU,SAAS,WAAW,OAAO,WAAW;AACtD,YAAI;AACF,gBAAM;AAAA,YACJ,SAAS;AAAA,YAAU;AAAA,YAAM;AAAA,YAAM,UAAU;AAAA,YACzC;AAAA,YAAY,YAAY;AAAA,YAAe,WAAW;AAAA,YAClD,WAAW;AAAA,YAAY,WAAW;AAAA,YAClC;AAAA,YACA,GAAG;AAAA,UACL,IAAI,WAAW,CAAC;AAIhB,gBAAM,qBAAiB,uCAAsB,OAAO,IAAI,UAAU;AAClE,cAAI,YAAY,UAAa,CAAC,eAAgB,CAAC,gBAAwB,UAAU;AACjF,gBAAM,aAAc,SAAiB;AACrC,gBAAM,WAAY,SAAiB;AACnC,gBAAM,YAAa,SAAiB;AAEpC,gBAAM,SAAc,EAAE,SAAS,GAAG,gBAAgB;AAClD,cAAI,QAAQ,OAAO,KAAK,IAAI,EAAE,SAAS,EAAG,QAAO,MAAM,EAAE,GAAG,MAAM,GAAI,gBAAwB,IAAI;AAClG,cAAI,KAAM,QAAO,OAAO;AAKxB,iBAAO,aAAa,gBAAgB,cAAe,gBAAgB,cAAc;AACjF,gBAAM,mBAAoB,SAAiB;AAC3C,gBAAM,QAAQ,kBAAkB,UAAU,OAAO,OAAO,oBAAoB,OAAO,aAAa;AAChG,cAAI,SAAS,MAAM,SAAS,EAAG,QAAO,QAAQ;AAE9C,cAAI,YAAY;AACd,mBAAO,UACL,eAAe,SAAS,WACxB,eAAe,WAAW,eAC1B;AAAA,UACJ;AAEA,gBAAM,aAAa,iBAAiB,cACjC,WAAW,SAAS,cAAc,WAAW;AAChD,cAAI,YAAY;AACd,mBAAO,SAAS,EAAE,MAAM,YAAY,WAAW;AAAA,UACjD,WAAW,WAAW;AACpB,mBAAO,SAAS;AAAA,UAClB;AAGA,cAAI,gBAAgB;AAClB,mBAAO,SAAS,OAAO,YAAa,eAAyB,IAAI,CAAC,MAAM;AACtE,oBAAM,UAAM,kCAAiB,EAAE,MAAM;AAIrC,qBAAO,CAAC,EAAE,WAAW,EAAE,OAAO,IAAI,QAAQ,IAAI,IAAI,MAAM,EAAE,WAAW,aAAa,aAAa,CAAC;AAAA,YAClG,CAAC,CAAC;AAAA,UACJ;AAEA,cAAI,CAAC,MAAM,SAAS;AAClB,mBAAO,QAAQ,MAAM;AACrB,mBAAO,SAAS,MAAM;AACtB,mBAAO,YAAY,MAAM;AAAA,UAC3B;AAEA,gBAAM,UAAU,MAAM,MAAM,eAAAA,QAAc,OAAO,MAAM,GAAG,KAAK;AAC/D,iBAAO,EAAE,UAAU,SAAS,YAAY,QAAQ,KAAK;AAAA,QACvD,SAAS,OAAO;AACd,cAAI,iBAAiB,OAAO;AAC1B,gBAAI,MAAM,QAAQ,SAAS,cAAc,KAAK,MAAM,QAAQ,SAAS,OAAO,GAAG;AAC7E,oBAAM,IAAI,MAAM,oFAAoF;AAAA,YACtG;AACA,gBAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,MAAM,QAAQ,SAAS,SAAS,GAAG;AACvE,oBAAM,IAAI,MAAM,uFAAuF;AAAA,YACzG;AAAA,UACF;AACA,gBAAM,IAAI,MAAM,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,QAC9G;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,QAAsB,cAAsB;AAC1D,cAAM,QAAQ,mBAAmB,MAAM;AACvC,YAAI;AACF,gBAAM,UAAU,MAAM,UAClB,MAAM,eAAAA,QAAc,IAAI,EAAE,MAAM,UAAU,CAAC,IAC3C,MAAM,eAAAA,QAAc,IAAI,EAAE,MAAM,WAAW,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU,CAAC;AACrH,iBAAO,EAAE,UAAU,MAAM,SAAS,KAAK,GAAG,YAAY,UAAU;AAAA,QAClE,QAAQ;AAAE,iBAAO;AAAA,QAAM;AAAA,MACzB;AAAA,MAEA,MAAM,OAAO,WAAyB;AACpC,cAAM,QAAQ,mBAAmB,MAAM;AACvC,4BAAoB,KAAK;AACzB,cAAM,OAAO,MAAM,eAAAA,QAAc,KAAK,EAAE,GAAG,iBAAiB,KAAK,GAAG,QAAQ,aAAa,WAAW,OAAO,CAAQ;AAEnH,cAAM,QAAQ,KAAK,aAAa,CAAC,GAAG,OAAO,CAAC,MAAW,EAAE,WAAW,aAAa,EAAE,WAAW,aACxF,EAAE,eAAe,EAAE,WAAW,cAAc,EAAE,WAAW,aAAa,EAAE,WAAW,eAAgB;AACzG,cAAM,YAAY,MAAM,QAAQ,IAAI,KAAK,IAAI,CAAC,MAC5C,eAAAA,QAAc,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,KAAK,EAAE,CAAQ,EAAE,MAAM,MAAM,IAAI,CAAC,CAAC;AAC3F,eAAO,UACJ,OAAO,CAAC,MAA0B,MAAM,IAAI,EAC5C,IAAI,CAAC,aAAa,EAAE,UAAU,MAAM,SAAS,KAAK,GAAG,YAAY,QAAQ,KAAK,EAAE;AAAA,MACrF;AAAA;AAAA;AAAA;AAAA,MAKA,SAAS,OAAO,QAAsB,cAAsB;AAC1D,cAAM,QAAQ,mBAAmB,MAAM;AACvC,YAAI;AACJ,YAAI;AACF,oBAAU,MAAM,eAAAA,QAAc,IAAI,EAAE,MAAM,WAAW,GAAG,iBAAiB,KAAK,EAAE,CAAQ;AAAA,QAC1F,QAAQ;AAAE;AAAA,QAAiD;AAC3D,cAAM,QAAQ,KAAK,EAAE,MAAM,MAAM;AAAA,QAAwB,CAAC;AAC1D,cAAM,YAAsB,CAAC;AAC7B,YAAI,QAAQ,YAAY;AACtB,cAAI;AACF,6BAAiB,QAAQ,MAAM,QAAQ,cAAc,GAAG;AACtD,kBAAI,KAAK,mBAAmB,eAAe,KAAK,WAAW,UAAW,WAAU,KAAK,KAAK,EAAE;AAAA,YAC9F;AAAA,UACF,QAAQ;AAAA,UAA4B;AAAA,QACtC;AACA,cAAM,QAAQ,OAAO,EAAE,MAAM,MAAM;AAAA,QAAwB,CAAC;AAC5D,cAAM,QAAQ,IAAI,UAAU,IAAI,OAAO,eAAe;AACpD,cAAI;AACF,mBAAO,MAAM,eAAAC,SAAe,IAAI,EAAE,YAAY,GAAG,iBAAiB,KAAK,EAAE,CAAQ,GAAG,OAAO;AAAA,UAC7F,QAAQ;AAAA,UAAmC;AAAA,QAC7C,CAAC,CAAC;AAAA,MACJ;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,OAAO,YAA2B;AACvC,YAAI,CAAC,QAAQ,YAAY;AACvB,gBAAM,IAAI,MAAM,2FAA2F;AAAA,QAC7G;AACA,cAAM,QAAQ,KAAK;AAAA,MACrB;AAAA,MAEA,QAAQ,OAAO,YAA2B;AACxC,cAAM,QAAQ,kBAAkB,IAAI,OAAO,KAAK,mBAAmB,CAAC,CAAC;AACrE,cAAM,UAAU,MAAM,eAAAD,QAAc,IAAI,EAAE,MAAM,QAAQ,MAAM,QAAQ,MAAM,GAAG,iBAAiB,KAAK,EAAE,CAAQ;AAC/G,eAAO,MAAM,SAAS,KAAK;AAAA,MAC7B;AAAA,MAEA,mBAAmB,EAAE,QAAQ,OAAO,eAAe,EAAE,YAAY,KAAK,EAAE;AAAA,MAExE,YAAY,CAAC,SAAwB,SAAiB,YAAgC,YAAY,SAAS,SAAS,OAAO;AAAA,MAE3H,eAAe,CAAC,SAAwB,SAAiB,YAA+B,YAAY,SAAS,SAAS,OAAO;AAAA,MAE7H,SAAS,OAAO,YAAkD;AAChE,cAAM,SAAS,QAAQ;AACvB,eAAO;AAAA,UACL,IAAI,QAAQ;AAAA,UACZ,UAAU;AAAA,UACV,QAAQ,WAAW,YAAY,WAAW,YAAY,UAClD,WAAW,cAAc,WAAW,YAAY,YAChD;AAAA,UACJ,WAAW,QAAQ;AAAA,UACnB,SAAS,QAAQ,WAAW;AAAA,UAC5B,UAAU,EAAE,mBAAmB,QAAQ,MAAM,cAAc,OAAO;AAAA,QACpE;AAAA,MACF;AAAA,MAEA,QAAQ,OAAO,SAAwB,YAAkE;AACvG,YAAI;AACF,cAAI,MAAM,QAAQ,OAAO,QAAQ,IAAI;AACrC,cAAI,QAAQ,UAAU;AACpB,kBAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,mBAAO,WAAW,QAAQ,WAAW;AACrC,kBAAM,OAAO,SAAS;AAAA,UACxB;AACA,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,IAAI,MAAM,wCAAwC,QAAQ,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,GAAG;AAAA,QACpI;AAAA,MACF;AAAA,MAEA,YAAY;AAAA,QACV,UAAU,OAAO,SAAwB,SAAkC;AACzE,gBAAM,SAAS,MAAM,QAAQ,SAAS,EAAE,KAAK,CAAC;AAC9C,cAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,mBAAmB,IAAI,EAAE;AACtD,gBAAM,SAAmB,CAAC;AAC1B,2BAAiB,SAAS,OAAQ,QAAO,KAAK,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK,CAAC;AACjG,iBAAO,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO;AAAA,QAC/C;AAAA,QACA,WAAW,OAAO,SAAwB,MAAc,YAAmC;AACzF,gBAAM,QAAQ,WAAW,CAAC,EAAE,MAAM,SAAS,OAAO,KAAK,OAAO,EAAE,CAAC,CAAC;AAAA,QACpE;AAAA,QACA,OAAO,OAAO,SAAwB,SAAgC;AACpE,gBAAM,QAAQ,GAAG,MAAM,MAAM,EAAE,WAAW,KAAK,CAAC;AAAA,QAClD;AAAA,QACA,SAAS,OAAO,SAAwB,SAAuC;AAC7E,gBAAM,UAAU,MAAM,QAAQ,GAAG,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AACtE,iBAAO,QAAQ,IAAI,CAAC,WAAW;AAAA,YAC7B,MAAM,MAAM;AAAA,YACZ,MAAM,MAAM,YAAY,IAAI,cAAc;AAAA,UAC5C,EAAE;AAAA,QACJ;AAAA,QACA,QAAQ,OAAO,SAAwB,SAAmC;AACxE,iBAAO,QAAQ,GAAG,OAAO,IAAI;AAAA,QAC/B;AAAA,QACA,QAAQ,OAAO,SAAwB,SAAgC;AACrE,gBAAM,QAAQ,GAAG,GAAG,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,QAC5D;AAAA,MACF;AAAA,MAEA,aAAa,CAAC,YAA0C;AAAA,IAC1D;AAAA,IAEA,UAAU;AAAA,MACR,QAAQ,OAAO,QAAsB,WAAmB,YAAgC;AACtF,cAAM,QAAQ,mBAAmB,MAAM;AACvC,cAAM,UAAU,MAAM,UAClB,MAAM,eAAAA,QAAc,IAAI,EAAE,MAAM,UAAU,CAAC,IAC3C,MAAM,eAAAA,QAAc,IAAI,EAAE,MAAM,WAAW,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU,CAAC;AACrH,cAAM,WAAW,MAAM,QAAQ,SAAS;AAGxC,eAAO;AAAA,UACL,IAAI,SAAS;AAAA,UACb,UAAU;AAAA,UACV,WAAW,SAAS;AAAA,UACpB,UAAU,EAAE,MAAM,SAAS,MAAM,iBAAiB,SAAS,gBAAgB;AAAA,QAC7E;AAAA,MACF;AAAA,MACA,MAAM,OAAO,WAAyB;AACpC,cAAM,QAAQ,mBAAmB,MAAM;AACvC,4BAAoB,KAAK;AACzB,cAAM,OAAO,MAAM,eAAAC,SAAe,KAAK,iBAAiB,KAAK,CAAQ;AACrE,gBAAQ,KAAK,aAAa,CAAC,GACxB,OAAO,CAAC,SAAc,KAAK,WAAW,SAAS,EAC/C,IAAI,CAAC,UAAe;AAAA,UACnB,IAAI,KAAK;AAAA,UACT,UAAU;AAAA,UACV,WAAW,IAAI,KAAK,KAAK,SAAS;AAAA,UAClC,UAAU,EAAE,iBAAiB,KAAK,iBAAiB,WAAW,KAAK,WAAW,QAAQ,KAAK,OAAO;AAAA,QACpG,EAAE;AAAA,MACN;AAAA,MACA,QAAQ,OAAO,QAAsB,eAAuB;AAC1D,cAAM,QAAQ,mBAAmB,MAAM;AACvC,cAAM,WAAW,MAAM,UACnB,MAAM,eAAAA,SAAe,IAAI,EAAE,WAAW,CAAC,IACvC,MAAM,eAAAA,SAAe,IAAI,EAAE,YAAY,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU,CAAC;AACjH,cAAM,SAAS,OAAO;AAAA,MACxB;AAAA;AAAA;AAAA;AAAA,MAIA,cAAc,EAAE,OAAO,UAAU,QAAQ,OAAO,gBAAgB,MAAM,QAAQ,UAAU;AAAA,IAC1F;AAAA,IAEA,UAAU;AAAA,MACR,QAAQ,OAAO,SAAuB,aAA+B;AACnE,cAAM,IAAI,MAAM,qFAAqF;AAAA,MACvG;AAAA,MACA,MAAM,OAAO,YAA0B;AAAE,cAAM,IAAI,MAAM,qDAAqD;AAAA,MAAG;AAAA,MACjH,QAAQ,OAAO,QAAsB,eAAuB;AAC1D,cAAM,QAAQ,mBAAmB,MAAM;AACvC,cAAM,WAAW,MAAM,UACnB,MAAM,eAAAA,SAAe,IAAI,EAAE,YAAY,WAAW,CAAC,IACnD,MAAM,eAAAA,SAAe,IAAI,EAAE,YAAY,YAAY,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU,CAAC;AAC7H,cAAM,SAAS,OAAO;AAAA,MACxB;AAAA,IACF;AAAA,IAEA,QAAQ;AAAA,MACN,QAAQ,OAAO,QAAsB,YAAY;AAC/C,cAAM,QAAQ,mBAAmB,MAAM;AACvC,4BAAoB,KAAK;AACzB,cAAM,SAAS,MAAM,UACjB,EAAE,MAAM,QAAQ,KAAK,IACrB,EAAE,MAAM,QAAQ,MAAM,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU;AAC/F,cAAM,QAAQ,MAAM,eAAAC,MAAY,YAAY,MAAa;AACzD,eAAO,EAAE,IAAI,MAAM,SAAS,MAAM,MAAM,MAAM,QAAQ,MAAM;AAAA,MAC9D;AAAA,MACA,KAAK,OAAO,QAAsB,SAAiB;AACjD,cAAM,QAAQ,mBAAmB,MAAM;AACvC,4BAAoB,KAAK;AACzB,YAAI;AACF,gBAAM,SAAS,MAAM,UACjB,EAAE,KAAK,IACP,EAAE,MAAM,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU;AACjF,gBAAM,QAAQ,MAAM,eAAAA,MAAY,IAAI,MAAa;AACjD,iBAAO,EAAE,IAAI,MAAM,SAAS,MAAM,MAAM,MAAM,QAAQ,MAAM;AAAA,QAC9D,QAAQ;AAAE,iBAAO;AAAA,QAAM;AAAA,MACzB;AAAA,MACA,MAAM,OAAO,WAAyB;AACpC,cAAM,QAAQ,mBAAmB,MAAM;AACvC,4BAAoB,KAAK;AACzB,cAAM,SAAS,MAAM,UACjB,CAAC,IACD,EAAE,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU;AAC3E,cAAM,OAAO,MAAM,eAAAA,MAAY,KAAK,MAAa;AACjD,cAAM,MAAa,CAAC;AACpB,yBAAiB,SAAS,MAAa;AACrC,cAAI,KAAK,EAAE,IAAI,MAAM,SAAS,MAAM,MAAM,MAAM,QAAQ,MAAM,CAAC;AAAA,QACjE;AACA,eAAO;AAAA,MACT;AAAA,MACA,QAAQ,OAAO,QAAsB,SAAiB;AACpD,cAAM,QAAQ,mBAAmB,MAAM;AACvC,4BAAoB,KAAK;AACzB,cAAM,SAAS,MAAM,UACjB,EAAE,KAAK,IACP,EAAE,MAAM,OAAO,MAAM,OAAO,QAAQ,MAAM,QAAQ,WAAW,MAAM,UAAU;AACjF,cAAM,QAAQ,MAAM,eAAAA,MAAY,IAAI,MAAa;AACjD,kBAAM,kCAAiB,MAAM,MAAM,OAAO,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AACF,CAAC;","names":["VercelSandbox","VercelSnapshot","VercelDrive"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { Sandbox as VercelSandbox, Snapshot as VercelSnapshot, Drive as VercelDrive } from "@vercel/sandbox";
|
|
3
|
-
import { defineProvider,
|
|
3
|
+
import { defineProvider, resolveVolumeRef, isUnifiedVolumeMounts, withVolumeSettle } from "@computesdk/provider";
|
|
4
4
|
import { Writable } from "stream";
|
|
5
5
|
var DEFAULT_DAEMON_SSE_PORT = 38989;
|
|
6
6
|
function mergeExposedPorts(primary, fallback, daemonSsePort) {
|
|
@@ -30,16 +30,62 @@ function validateCredentials(creds) {
|
|
|
30
30
|
if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);
|
|
31
31
|
if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);
|
|
32
32
|
}
|
|
33
|
-
function getUtf8Sink() {
|
|
33
|
+
function getUtf8Sink(onChunk) {
|
|
34
34
|
const chunks = [];
|
|
35
35
|
const sink = new Writable({
|
|
36
|
+
decodeStrings: false,
|
|
36
37
|
write(chunk, _enc, cb) {
|
|
37
|
-
|
|
38
|
+
const text = Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
|
|
39
|
+
chunks.push(text);
|
|
40
|
+
if (text && onChunk) onChunk(text);
|
|
38
41
|
cb();
|
|
39
42
|
}
|
|
40
43
|
});
|
|
41
44
|
return { sink, value: () => chunks.join("") };
|
|
42
45
|
}
|
|
46
|
+
function credentialParams(creds) {
|
|
47
|
+
return creds.useOidc ? {} : { token: creds.token, teamId: creds.teamId, projectId: creds.projectId };
|
|
48
|
+
}
|
|
49
|
+
var handleCredentials = /* @__PURE__ */ new WeakMap();
|
|
50
|
+
function track(sandbox, creds) {
|
|
51
|
+
handleCredentials.set(sandbox, creds);
|
|
52
|
+
return sandbox;
|
|
53
|
+
}
|
|
54
|
+
var DEADLINE_WRAPPER = 'if command -v setsid >/dev/null 2>&1; then setsid sh -c "$1" & else sh -c "$1" & fi; pid=$!; (sleep "$0"; kill -KILL -"$pid" || kill -KILL "$pid") >/dev/null 2>&1 & w=$!; wait "$pid"; rc=$?; kill "$w" 2>/dev/null; exit $rc';
|
|
55
|
+
async function execCommand(sandbox, command, options) {
|
|
56
|
+
const startTime = Date.now();
|
|
57
|
+
try {
|
|
58
|
+
const env = options?.env && Object.keys(options.env).length > 0 ? options.env : void 0;
|
|
59
|
+
const stdout = options?.background ? void 0 : getUtf8Sink(options?.onStdout);
|
|
60
|
+
const stderr = options?.background ? void 0 : getUtf8Sink(options?.onStderr);
|
|
61
|
+
const deadline = options?.timeout && !options.background ? options.timeout : void 0;
|
|
62
|
+
const args = deadline ? ["-c", DEADLINE_WRAPPER, String(deadline / 1e3), command] : ["-c", command];
|
|
63
|
+
const controller = deadline ? new AbortController() : void 0;
|
|
64
|
+
const timer = deadline ? setTimeout(() => controller.abort(), deadline + 3e3) : void 0;
|
|
65
|
+
try {
|
|
66
|
+
const result = await sandbox.runCommand({
|
|
67
|
+
cmd: "sh",
|
|
68
|
+
args,
|
|
69
|
+
cwd: options?.cwd,
|
|
70
|
+
env,
|
|
71
|
+
detached: options?.background,
|
|
72
|
+
stdout: stdout?.sink,
|
|
73
|
+
stderr: stderr?.sink,
|
|
74
|
+
signal: controller?.signal
|
|
75
|
+
});
|
|
76
|
+
return { stdout: stdout?.value() ?? "", stderr: stderr?.value() ?? "", exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };
|
|
77
|
+
} catch (error) {
|
|
78
|
+
if (controller?.signal.aborted) {
|
|
79
|
+
return { stdout: stdout?.value() ?? "", stderr: `${stderr?.value() ?? ""}Command timed out after ${deadline}ms`, exitCode: 124, durationMs: Date.now() - startTime };
|
|
80
|
+
}
|
|
81
|
+
throw error;
|
|
82
|
+
} finally {
|
|
83
|
+
if (timer) clearTimeout(timer);
|
|
84
|
+
}
|
|
85
|
+
} catch (error) {
|
|
86
|
+
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
43
89
|
var vercel = defineProvider({
|
|
44
90
|
name: "vercel",
|
|
45
91
|
methods: {
|
|
@@ -51,8 +97,8 @@ var vercel = defineProvider({
|
|
|
51
97
|
try {
|
|
52
98
|
const {
|
|
53
99
|
timeout: _timeout,
|
|
54
|
-
envs
|
|
55
|
-
name
|
|
100
|
+
envs,
|
|
101
|
+
name,
|
|
56
102
|
metadata: _metadata,
|
|
57
103
|
templateId,
|
|
58
104
|
snapshotId: optSnapshotId,
|
|
@@ -68,6 +114,8 @@ var vercel = defineProvider({
|
|
|
68
114
|
const optPorts = options?.ports;
|
|
69
115
|
const optSource = options?.source;
|
|
70
116
|
const params = { timeout, ...providerOptions };
|
|
117
|
+
if (envs && Object.keys(envs).length > 0) params.env = { ...envs, ...providerOptions.env };
|
|
118
|
+
if (name) params.name = name;
|
|
71
119
|
params.persistent = providerOptions.persistent ?? providerOptions.ephemeral === false;
|
|
72
120
|
const optDaemonSsePort = options?.daemonSsePort;
|
|
73
121
|
const ports = mergeExposedPorts(optPorts, config.ports, optDaemonSsePort ?? config.daemonSsePort);
|
|
@@ -92,7 +140,7 @@ var vercel = defineProvider({
|
|
|
92
140
|
params.teamId = creds.teamId;
|
|
93
141
|
params.projectId = creds.projectId;
|
|
94
142
|
}
|
|
95
|
-
const sandbox = await VercelSandbox.create(params);
|
|
143
|
+
const sandbox = track(await VercelSandbox.create(params), creds);
|
|
96
144
|
return { instance: sandbox, instanceId: sandbox.name };
|
|
97
145
|
} catch (error) {
|
|
98
146
|
if (error instanceof Error) {
|
|
@@ -110,54 +158,78 @@ var vercel = defineProvider({
|
|
|
110
158
|
const creds = resolveCredentials(config);
|
|
111
159
|
try {
|
|
112
160
|
const sandbox = creds.useOidc ? await VercelSandbox.get({ name: sandboxId }) : await VercelSandbox.get({ name: sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
|
|
113
|
-
return { instance: sandbox, instanceId: sandboxId };
|
|
161
|
+
return { instance: track(sandbox, creds), instanceId: sandboxId };
|
|
114
162
|
} catch {
|
|
115
163
|
return null;
|
|
116
164
|
}
|
|
117
165
|
},
|
|
118
|
-
list: async (
|
|
119
|
-
|
|
166
|
+
list: async (config) => {
|
|
167
|
+
const creds = resolveCredentials(config);
|
|
168
|
+
validateCredentials(creds);
|
|
169
|
+
const page = await VercelSandbox.list({ ...credentialParams(creds), sortBy: "createdAt", sortOrder: "desc" });
|
|
170
|
+
const live = (page.sandboxes ?? []).filter((s) => s.status === "running" || s.status === "pending" || s.persistent && (s.status === "stopping" || s.status === "stopped" || s.status === "snapshotting"));
|
|
171
|
+
const sandboxes = await Promise.all(live.map((s) => VercelSandbox.get({ name: s.name, ...credentialParams(creds) }).catch(() => null)));
|
|
172
|
+
return sandboxes.filter((s) => s !== null).map((sandbox) => ({ instance: track(sandbox, creds), instanceId: sandbox.name }));
|
|
120
173
|
},
|
|
174
|
+
// Deletes the named sandbox. Persistent sandboxes snapshot themselves on
|
|
175
|
+
// every stop; those automatic snapshots go too, snapshots taken with
|
|
176
|
+
// snapshot.create stay.
|
|
121
177
|
destroy: async (config, sandboxId) => {
|
|
122
178
|
const creds = resolveCredentials(config);
|
|
179
|
+
let sandbox;
|
|
123
180
|
try {
|
|
124
|
-
|
|
125
|
-
await sandbox.stop();
|
|
181
|
+
sandbox = await VercelSandbox.get({ name: sandboxId, ...credentialParams(creds) });
|
|
126
182
|
} catch {
|
|
183
|
+
return;
|
|
127
184
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
185
|
+
await sandbox.stop().catch(() => {
|
|
186
|
+
});
|
|
187
|
+
const automatic = [];
|
|
188
|
+
if (sandbox.persistent) {
|
|
189
|
+
try {
|
|
190
|
+
for await (const snap of await sandbox.listSnapshots()) {
|
|
191
|
+
if (snap.creationMethod === "automatic" && snap.status === "created") automatic.push(snap.id);
|
|
192
|
+
}
|
|
193
|
+
} catch {
|
|
136
194
|
}
|
|
137
|
-
const stdout = options?.background ? void 0 : getUtf8Sink();
|
|
138
|
-
const stderr = options?.background ? void 0 : getUtf8Sink();
|
|
139
|
-
const result = await sandbox.runCommand({
|
|
140
|
-
cmd: "sh",
|
|
141
|
-
args: ["-c", fullCommand],
|
|
142
|
-
cwd: options?.cwd,
|
|
143
|
-
detached: options?.background,
|
|
144
|
-
stdout: stdout?.sink,
|
|
145
|
-
stderr: stderr?.sink,
|
|
146
|
-
timeoutMs: options?.timeout
|
|
147
|
-
});
|
|
148
|
-
return { stdout: stdout?.value() ?? "", stderr: stderr?.value() ?? "", exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };
|
|
149
|
-
} catch (error) {
|
|
150
|
-
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
|
|
151
195
|
}
|
|
196
|
+
await sandbox.delete().catch(() => {
|
|
197
|
+
});
|
|
198
|
+
await Promise.all(automatic.map(async (snapshotId) => {
|
|
199
|
+
try {
|
|
200
|
+
await (await VercelSnapshot.get({ snapshotId, ...credentialParams(creds) })).delete();
|
|
201
|
+
} catch {
|
|
202
|
+
}
|
|
203
|
+
}));
|
|
204
|
+
},
|
|
205
|
+
// Vercel's pause is a stop: a persistent sandbox snapshots its whole
|
|
206
|
+
// filesystem on stop and restores it in the next session. Processes do
|
|
207
|
+
// not survive, and a non-persistent sandbox would lose its files.
|
|
208
|
+
pause: async (sandbox) => {
|
|
209
|
+
if (!sandbox.persistent) {
|
|
210
|
+
throw new Error(`Vercel can only pause persistent sandboxes; create the sandbox with { persistent: true }.`);
|
|
211
|
+
}
|
|
212
|
+
await sandbox.stop();
|
|
213
|
+
},
|
|
214
|
+
resume: async (sandbox) => {
|
|
215
|
+
const creds = handleCredentials.get(sandbox) ?? resolveCredentials({});
|
|
216
|
+
const resumed = await VercelSandbox.get({ name: sandbox.name, resume: true, ...credentialParams(creds) });
|
|
217
|
+
return track(resumed, creds);
|
|
218
|
+
},
|
|
219
|
+
pauseCapabilities: { memory: false, createOptions: { persistent: true } },
|
|
220
|
+
runCommand: (sandbox, command, options) => execCommand(sandbox, command, options),
|
|
221
|
+
streamCommand: (sandbox, command, options) => execCommand(sandbox, command, options),
|
|
222
|
+
getInfo: async (sandbox) => {
|
|
223
|
+
const status = sandbox.status;
|
|
224
|
+
return {
|
|
225
|
+
id: sandbox.name,
|
|
226
|
+
provider: "vercel",
|
|
227
|
+
status: status === "failed" || status === "aborted" ? "error" : status === "stopping" || status === "stopped" ? "stopped" : "running",
|
|
228
|
+
createdAt: sandbox.createdAt,
|
|
229
|
+
timeout: sandbox.timeout ?? 3e5,
|
|
230
|
+
metadata: { vercelSandboxName: sandbox.name, vercelStatus: status }
|
|
231
|
+
};
|
|
152
232
|
},
|
|
153
|
-
getInfo: async (_sandbox) => ({
|
|
154
|
-
id: "vercel-unknown",
|
|
155
|
-
provider: "vercel",
|
|
156
|
-
status: "running",
|
|
157
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
158
|
-
timeout: 3e5,
|
|
159
|
-
metadata: { vercelSandboxId: "vercel-unknown" }
|
|
160
|
-
}),
|
|
161
233
|
getUrl: async (sandbox, options) => {
|
|
162
234
|
try {
|
|
163
235
|
let url = sandbox.domain(options.port);
|
|
@@ -213,14 +285,26 @@ var vercel = defineProvider({
|
|
|
213
285
|
metadata: { name: options?.name, sourceSessionId: snapshot.sourceSessionId }
|
|
214
286
|
};
|
|
215
287
|
},
|
|
216
|
-
list: async (
|
|
217
|
-
|
|
288
|
+
list: async (config) => {
|
|
289
|
+
const creds = resolveCredentials(config);
|
|
290
|
+
validateCredentials(creds);
|
|
291
|
+
const page = await VercelSnapshot.list(credentialParams(creds));
|
|
292
|
+
return (page.snapshots ?? []).filter((snap) => snap.status === "created").map((snap) => ({
|
|
293
|
+
id: snap.id,
|
|
294
|
+
provider: "vercel",
|
|
295
|
+
createdAt: new Date(snap.createdAt),
|
|
296
|
+
metadata: { sourceSessionId: snap.sourceSessionId, sizeBytes: snap.sizeBytes, region: snap.region }
|
|
297
|
+
}));
|
|
218
298
|
},
|
|
219
299
|
delete: async (config, snapshotId) => {
|
|
220
300
|
const creds = resolveCredentials(config);
|
|
221
301
|
const snapshot = creds.useOidc ? await VercelSnapshot.get({ snapshotId }) : await VercelSnapshot.get({ snapshotId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });
|
|
222
302
|
await snapshot.delete();
|
|
223
|
-
}
|
|
303
|
+
},
|
|
304
|
+
// The whole rootfs (/tmp, $HOME, /etc, ...) is restored; processes are
|
|
305
|
+
// not. Snapshotting stops the source (it still exists and needs
|
|
306
|
+
// destroying); its next call starts a new session from the snapshot.
|
|
307
|
+
capabilities: { scope: "rootfs", memory: false, destroysSource: true, source: "stopped" }
|
|
224
308
|
},
|
|
225
309
|
template: {
|
|
226
310
|
create: async (_config, _options) => {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n */\n\nimport { Sandbox as VercelSandbox, Snapshot as VercelSnapshot, Drive as VercelDrive } from '@vercel/sandbox';\nimport { defineProvider, escapeShellArg, resolveVolumeRef, isUnifiedVolumeMounts, withVolumeSettle } from '@computesdk/provider';\nimport { Writable } from 'node:stream';\n\nexport type { VercelSandbox, VercelSnapshot };\n\nimport type { CommandResult, InstanceInfo, CreateInstanceOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\nexport interface VercelConfig {\n token?: string;\n teamId?: string;\n projectId?: string;\n timeout?: number;\n ports?: number[];\n daemonSsePort?: number | false;\n}\n\nconst DEFAULT_DAEMON_SSE_PORT = 38989;\n\nfunction mergeExposedPorts(primary?: number[], fallback?: number[], daemonSsePort?: number | false): number[] {\n const daemonPort = daemonSsePort === false ? undefined : (daemonSsePort ?? DEFAULT_DAEMON_SSE_PORT);\n const merged = [...(primary ?? fallback ?? [])];\n if (typeof daemonPort === 'number') merged.push(daemonPort);\n return Array.from(new Set(merged.filter((port) => Number.isInteger(port) && port > 0 && port <= 65535)));\n}\n\ninterface ResolvedCredentials {\n useOidc: boolean;\n token: string;\n teamId: string;\n projectId: string;\n}\n\nfunction resolveCredentials(config: VercelConfig): ResolvedCredentials {\n const token = config.token || (typeof process !== 'undefined' && process.env?.VERCEL_TOKEN) || '';\n const teamId = config.teamId || (typeof process !== 'undefined' && process.env?.VERCEL_TEAM_ID) || '';\n const projectId = config.projectId || (typeof process !== 'undefined' && process.env?.VERCEL_PROJECT_ID) || '';\n const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n const useOidc = !hasConfigCredentials && !!oidcToken;\n return { useOidc, token, teamId, projectId };\n}\n\nfunction validateCredentials(creds: ResolvedCredentials): void {\n if (creds.useOidc) return;\n if (!creds.token) {\n throw new Error(\n `Missing Vercel authentication. Either:\\n` +\n `1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or\\n` +\n `2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable.`\n );\n }\n if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);\n if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);\n}\n\nfunction getUtf8Sink() {\n const chunks: string[] = [];\n const sink = new Writable({\n write(chunk, _enc, cb) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk.toString(\"utf8\") : String(chunk));\n cb();\n },\n });\n return { sink, value: () => chunks.join(\"\") };\n}\n\nexport const vercel = defineProvider<VercelSandbox, VercelConfig>({\n name: 'vercel',\n methods: {\n instances: {\n create: async (config: VercelConfig, options?: CreateInstanceOptions) => {\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 volumes,\n ...providerOptions\n } = options || {};\n // `volumes` only counts as unified VolumeMount[] when every entry\n // carries `volume`; a provider-native volumes spec stays in\n // providerOptions and reaches the wire untouched.\n const unifiedVolumes = isUnifiedVolumeMounts(volumes) ? volumes : undefined;\n if (volumes !== undefined && !unifiedVolumes) (providerOptions as any).volumes = volumes;\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 // Vercel sandboxes are persistent by default, which auto-snapshots the\n // filesystem on every stop() and accrues Snapshot Storage. ComputeSDK\n // sandboxes default to non-persistent unless the caller opts in via\n // `persistent: true` or asks for the durable surface (`ephemeral: false`).\n params.persistent = providerOptions.persistent ?? (providerOptions.ephemeral === false);\n const optDaemonSsePort = (options as any)?.daemonSsePort as number | false | undefined;\n const ports = mergeExposedPorts(optPorts, config.ports, optDaemonSsePort ?? config.daemonSsePort);\n if (ports && ports.length > 0) params.ports = ports;\n\n if (optRuntime) {\n params.runtime =\n optRuntime === 'node' ? 'node24' :\n optRuntime === 'python' ? 'python3.13' :\n optRuntime;\n }\n\n const snapshotId = optSnapshotId || templateId ||\n (optSource?.type === 'snapshot' && optSource?.snapshotId);\n if (snapshotId) {\n params.source = { type: 'snapshot', snapshotId };\n } else if (optSource) {\n params.source = optSource;\n }\n\n // Unified mounts → vercel's {path: {drive, mode}} wire shape.\n if (unifiedVolumes) {\n params.mounts = Object.fromEntries((unifiedVolumes as any[]).map((m) => {\n const ref = resolveVolumeRef(m.volume);\n // The `drive` field serializes verbatim and the API resolves it\n // by NAME (a Drive object mounts as mount.name) — sending\n // driveId yields \"Drive not found\".\n return [m.mountPath, { drive: ref.name ?? ref.id, mode: m.readOnly ? 'snapshot' : 'read-write' }];\n }));\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 { instance: sandbox, instanceId: sandbox.name };\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({ name: sandboxId })\n : await VercelSandbox.get({ name: sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n return { instance: sandbox, instanceId: 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({ name: sandboxId })\n : await VercelSandbox.get({ name: 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 timeoutMs: options?.timeout,\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<InstanceInfo> => ({\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> => {\n await sandbox.fs.mkdir(path, { recursive: true });\n },\n readdir: async (sandbox: VercelSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.fs.readdir(path, { withFileTypes: true });\n return entries.map((entry) => ({\n name: entry.name,\n type: entry.isDirectory() ? 'directory' : 'file',\n }));\n },\n exists: async (sandbox: VercelSandbox, path: string): Promise<boolean> => {\n return sandbox.fs.exists(path);\n },\n remove: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n await sandbox.fs.rm(path, { recursive: true, force: true });\n }\n },\n\n getInstance: (sandbox: VercelSandbox): VercelSandbox => sandbox,\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string, options?: { name?: string }) => {\n const creds = resolveCredentials(config);\n const sandbox = creds.useOidc\n ? await VercelSandbox.get({ name: sandboxId })\n : await VercelSandbox.get({ name: sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n const snapshot = await sandbox.snapshot();\n // @vercel/sandbox's Snapshot class exposes `snapshotId`, not `id` —\n // map it to the ComputeSDK Snapshot shape ({ id }) consumers rely on.\n return {\n id: snapshot.snapshotId,\n provider: 'vercel',\n createdAt: snapshot.createdAt,\n metadata: { name: options?.name, sourceSessionId: snapshot.sourceSessionId },\n };\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 volume: {\n create: async (config: VercelConfig, options) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? { name: options.name }\n : { name: options.name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.getOrCreate(params as any);\n return { id: drive.driveId, name: drive.name, native: drive };\n },\n get: async (config: VercelConfig, name: string) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n try {\n const params = creds.useOidc\n ? { name }\n : { name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.get(params as any);\n return { id: drive.driveId, name: drive.name, native: drive };\n } catch { return null; }\n },\n list: async (config: VercelConfig) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? {}\n : { token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const page = await VercelDrive.list(params as any);\n const out: any[] = [];\n for await (const drive of page as any) {\n out.push({ id: drive.driveId, name: drive.name, native: drive });\n }\n return out;\n },\n delete: async (config: VercelConfig, name: string) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? { name }\n : { name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.get(params as any);\n await withVolumeSettle(() => drive.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, Drive as VercelDrive } from '@vercel/sandbox';\nimport { defineProvider, resolveVolumeRef, isUnifiedVolumeMounts, withVolumeSettle } from '@computesdk/provider';\nimport { Writable } from 'node:stream';\n\nexport type { VercelSandbox, VercelSnapshot };\n\nimport type { CommandResult, InstanceInfo, CreateInstanceOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\nexport interface VercelConfig {\n token?: string;\n teamId?: string;\n projectId?: string;\n timeout?: number;\n ports?: number[];\n daemonSsePort?: number | false;\n}\n\nconst DEFAULT_DAEMON_SSE_PORT = 38989;\n\nfunction mergeExposedPorts(primary?: number[], fallback?: number[], daemonSsePort?: number | false): number[] {\n const daemonPort = daemonSsePort === false ? undefined : (daemonSsePort ?? DEFAULT_DAEMON_SSE_PORT);\n const merged = [...(primary ?? fallback ?? [])];\n if (typeof daemonPort === 'number') merged.push(daemonPort);\n return Array.from(new Set(merged.filter((port) => Number.isInteger(port) && port > 0 && port <= 65535)));\n}\n\ninterface ResolvedCredentials {\n useOidc: boolean;\n token: string;\n teamId: string;\n projectId: string;\n}\n\nfunction resolveCredentials(config: VercelConfig): ResolvedCredentials {\n const token = config.token || (typeof process !== 'undefined' && process.env?.VERCEL_TOKEN) || '';\n const teamId = config.teamId || (typeof process !== 'undefined' && process.env?.VERCEL_TEAM_ID) || '';\n const projectId = config.projectId || (typeof process !== 'undefined' && process.env?.VERCEL_PROJECT_ID) || '';\n const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n const useOidc = !hasConfigCredentials && !!oidcToken;\n return { useOidc, token, teamId, projectId };\n}\n\nfunction validateCredentials(creds: ResolvedCredentials): void {\n if (creds.useOidc) return;\n if (!creds.token) {\n throw new Error(\n `Missing Vercel authentication. Either:\\n` +\n `1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or\\n` +\n `2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable.`\n );\n }\n if (!creds.teamId) throw new Error(`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID.`);\n if (!creds.projectId) throw new Error(`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID.`);\n}\n\nfunction getUtf8Sink(onChunk?: (data: string) => void) {\n const chunks: string[] = [];\n const sink = new Writable({\n decodeStrings: false,\n write(chunk, _enc, cb) {\n const text = Buffer.isBuffer(chunk) ? chunk.toString(\"utf8\") : String(chunk);\n chunks.push(text);\n if (text && onChunk) onChunk(text);\n cb();\n },\n });\n return { sink, value: () => chunks.join(\"\") };\n}\n\nfunction credentialParams(creds: ResolvedCredentials) {\n return creds.useOidc ? {} : { token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n}\n\n// The credentials each handle was fetched with, so `resume` can fetch the\n// fresh session handle the same way.\nconst handleCredentials = new WeakMap<VercelSandbox, ResolvedCredentials>();\n\nfunction track(sandbox: VercelSandbox, creds: ResolvedCredentials): VercelSandbox {\n handleCredentials.set(sandbox, creds);\n return sandbox;\n}\n\n// `setsid` gives the command its own process group, so the watchdog can kill\n// the whole tree, not just the outer shell.\nconst DEADLINE_WRAPPER = 'if command -v setsid >/dev/null 2>&1; then setsid sh -c \"$1\" & else sh -c \"$1\" & fi; pid=$!; (sleep \"$0\"; kill -KILL -\"$pid\" || kill -KILL \"$pid\") >/dev/null 2>&1 & w=$!; wait \"$pid\"; rc=$?; kill \"$w\" 2>/dev/null; exit $rc';\n\n// Runs through the SDK's native env/cwd fields; stdout/stderr arrive on the\n// sinks while the command runs, so the same path serves streamCommand.\nasync function execCommand(sandbox: VercelSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> {\n const startTime = Date.now();\n try {\n const env = options?.env && Object.keys(options.env).length > 0 ? options.env : undefined;\n const stdout = options?.background ? undefined : getUtf8Sink(options?.onStdout);\n const stderr = options?.background ? undefined : getUtf8Sink(options?.onStderr);\n const deadline = options?.timeout && !options.background ? options.timeout : undefined;\n // A watchdog in the box kills the command's whole process group at the\n // deadline; the abort is a backstop so the caller still returns on time.\n const args = deadline ? ['-c', DEADLINE_WRAPPER, String(deadline / 1000), command] : ['-c', command];\n const controller = deadline ? new AbortController() : undefined;\n const timer = deadline ? setTimeout(() => controller!.abort(), deadline + 3000) : undefined;\n try {\n const result = await sandbox.runCommand({\n cmd: 'sh', args,\n cwd: options?.cwd, env, detached: options?.background,\n stdout: stdout?.sink, stderr: stderr?.sink,\n signal: controller?.signal,\n });\n return { stdout: stdout?.value() ?? '', stderr: stderr?.value() ?? '', exitCode: result.exitCode ?? 0, durationMs: Date.now() - startTime };\n } catch (error) {\n if (controller?.signal.aborted) {\n return { stdout: stdout?.value() ?? '', stderr: `${stderr?.value() ?? ''}Command timed out after ${deadline}ms`, exitCode: 124, durationMs: Date.now() - startTime };\n }\n throw error;\n } finally {\n if (timer) clearTimeout(timer);\n }\n } catch (error) {\n return { stdout: '', stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };\n }\n}\n\nexport const vercel = defineProvider<VercelSandbox, VercelConfig>({\n name: 'vercel',\n methods: {\n instances: {\n create: async (config: VercelConfig, options?: CreateInstanceOptions) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const timeout = options?.timeout ?? config.timeout ?? 300000;\n try {\n const {\n timeout: _timeout, envs, name, metadata: _metadata,\n templateId, snapshotId: optSnapshotId, sandboxId: _sandboxId,\n namespace: _namespace, directory: _directory,\n volumes,\n ...providerOptions\n } = options || {};\n // `volumes` only counts as unified VolumeMount[] when every entry\n // carries `volume`; a provider-native volumes spec stays in\n // providerOptions and reaches the wire untouched.\n const unifiedVolumes = isUnifiedVolumeMounts(volumes) ? volumes : undefined;\n if (volumes !== undefined && !unifiedVolumes) (providerOptions as any).volumes = volumes;\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 if (envs && Object.keys(envs).length > 0) params.env = { ...envs, ...(providerOptions as any).env };\n if (name) params.name = name;\n // Vercel sandboxes are persistent by default, which auto-snapshots the\n // filesystem on every stop() and accrues Snapshot Storage. ComputeSDK\n // sandboxes default to non-persistent unless the caller opts in via\n // `persistent: true` or asks for the durable surface (`ephemeral: false`).\n params.persistent = providerOptions.persistent ?? (providerOptions.ephemeral === false);\n const optDaemonSsePort = (options as any)?.daemonSsePort as number | false | undefined;\n const ports = mergeExposedPorts(optPorts, config.ports, optDaemonSsePort ?? config.daemonSsePort);\n if (ports && ports.length > 0) params.ports = ports;\n\n if (optRuntime) {\n params.runtime =\n optRuntime === 'node' ? 'node24' :\n optRuntime === 'python' ? 'python3.13' :\n optRuntime;\n }\n\n const snapshotId = optSnapshotId || templateId ||\n (optSource?.type === 'snapshot' && optSource?.snapshotId);\n if (snapshotId) {\n params.source = { type: 'snapshot', snapshotId };\n } else if (optSource) {\n params.source = optSource;\n }\n\n // Unified mounts → vercel's {path: {drive, mode}} wire shape.\n if (unifiedVolumes) {\n params.mounts = Object.fromEntries((unifiedVolumes as any[]).map((m) => {\n const ref = resolveVolumeRef(m.volume);\n // The `drive` field serializes verbatim and the API resolves it\n // by NAME (a Drive object mounts as mount.name) — sending\n // driveId yields \"Drive not found\".\n return [m.mountPath, { drive: ref.name ?? ref.id, mode: m.readOnly ? 'snapshot' : 'read-write' }];\n }));\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 = track(await VercelSandbox.create(params), creds);\n return { instance: sandbox, instanceId: sandbox.name };\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({ name: sandboxId })\n : await VercelSandbox.get({ name: sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n return { instance: track(sandbox, creds), instanceId: sandboxId };\n } catch { return null; }\n },\n\n list: async (config: VercelConfig) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const page = await VercelSandbox.list({ ...credentialParams(creds), sortBy: 'createdAt', sortOrder: 'desc' } as any);\n // Paused (stopped) persistent sandboxes stay listed so callers can resume them.\n const live = (page.sandboxes ?? []).filter((s: any) => s.status === 'running' || s.status === 'pending'\n || (s.persistent && (s.status === 'stopping' || s.status === 'stopped' || s.status === 'snapshotting')));\n const sandboxes = await Promise.all(live.map((s: any) =>\n VercelSandbox.get({ name: s.name, ...credentialParams(creds) } as any).catch(() => null)));\n return sandboxes\n .filter((s): s is VercelSandbox => s !== null)\n .map((sandbox) => ({ instance: track(sandbox, creds), instanceId: sandbox.name }));\n },\n\n // Deletes the named sandbox. Persistent sandboxes snapshot themselves on\n // every stop; those automatic snapshots go too, snapshots taken with\n // snapshot.create stay.\n destroy: async (config: VercelConfig, sandboxId: string) => {\n const creds = resolveCredentials(config);\n let sandbox: VercelSandbox;\n try {\n sandbox = await VercelSandbox.get({ name: sandboxId, ...credentialParams(creds) } as any);\n } catch { return; /* already destroyed or doesn't exist */ }\n await sandbox.stop().catch(() => { /* already stopped */ });\n const automatic: string[] = [];\n if (sandbox.persistent) {\n try {\n for await (const snap of await sandbox.listSnapshots()) {\n if (snap.creationMethod === 'automatic' && snap.status === 'created') automatic.push(snap.id);\n }\n } catch { /* nothing to clean up */ }\n }\n await sandbox.delete().catch(() => { /* already deleted */ });\n await Promise.all(automatic.map(async (snapshotId) => {\n try {\n await (await VercelSnapshot.get({ snapshotId, ...credentialParams(creds) } as any)).delete();\n } catch { /* expired or already deleted */ }\n }));\n },\n\n // Vercel's pause is a stop: a persistent sandbox snapshots its whole\n // filesystem on stop and restores it in the next session. Processes do\n // not survive, and a non-persistent sandbox would lose its files.\n pause: async (sandbox: VercelSandbox) => {\n if (!sandbox.persistent) {\n throw new Error(`Vercel can only pause persistent sandboxes; create the sandbox with { persistent: true }.`);\n }\n await sandbox.stop();\n },\n\n resume: async (sandbox: VercelSandbox) => {\n const creds = handleCredentials.get(sandbox) ?? resolveCredentials({});\n const resumed = await VercelSandbox.get({ name: sandbox.name, resume: true, ...credentialParams(creds) } as any);\n return track(resumed, creds);\n },\n\n pauseCapabilities: { memory: false, createOptions: { persistent: true } },\n\n runCommand: (sandbox: VercelSandbox, command: string, options?: RunCommandOptions) => execCommand(sandbox, command, options),\n\n streamCommand: (sandbox: VercelSandbox, command: string, options: RunCommandOptions) => execCommand(sandbox, command, options),\n\n getInfo: async (sandbox: VercelSandbox): Promise<InstanceInfo> => {\n const status = sandbox.status;\n return {\n id: sandbox.name,\n provider: 'vercel',\n status: status === 'failed' || status === 'aborted' ? 'error'\n : status === 'stopping' || status === 'stopped' ? 'stopped'\n : 'running',\n createdAt: sandbox.createdAt,\n timeout: sandbox.timeout ?? 300000,\n metadata: { vercelSandboxName: sandbox.name, vercelStatus: status },\n };\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> => {\n await sandbox.fs.mkdir(path, { recursive: true });\n },\n readdir: async (sandbox: VercelSandbox, path: string): Promise<FileEntry[]> => {\n const entries = await sandbox.fs.readdir(path, { withFileTypes: true });\n return entries.map((entry) => ({\n name: entry.name,\n type: entry.isDirectory() ? 'directory' : 'file',\n }));\n },\n exists: async (sandbox: VercelSandbox, path: string): Promise<boolean> => {\n return sandbox.fs.exists(path);\n },\n remove: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n await sandbox.fs.rm(path, { recursive: true, force: true });\n }\n },\n\n getInstance: (sandbox: VercelSandbox): VercelSandbox => sandbox,\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string, options?: { name?: string }) => {\n const creds = resolveCredentials(config);\n const sandbox = creds.useOidc\n ? await VercelSandbox.get({ name: sandboxId })\n : await VercelSandbox.get({ name: sandboxId, token: creds.token, teamId: creds.teamId, projectId: creds.projectId });\n const snapshot = await sandbox.snapshot();\n // @vercel/sandbox's Snapshot class exposes `snapshotId`, not `id` —\n // map it to the ComputeSDK Snapshot shape ({ id }) consumers rely on.\n return {\n id: snapshot.snapshotId,\n provider: 'vercel',\n createdAt: snapshot.createdAt,\n metadata: { name: options?.name, sourceSessionId: snapshot.sourceSessionId },\n };\n },\n list: async (config: VercelConfig) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const page = await VercelSnapshot.list(credentialParams(creds) as any);\n return (page.snapshots ?? [])\n .filter((snap: any) => snap.status === 'created')\n .map((snap: any) => ({\n id: snap.id,\n provider: 'vercel',\n createdAt: new Date(snap.createdAt),\n metadata: { sourceSessionId: snap.sourceSessionId, sizeBytes: snap.sizeBytes, region: snap.region },\n }));\n },\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 // The whole rootfs (/tmp, $HOME, /etc, ...) is restored; processes are\n // not. Snapshotting stops the source (it still exists and needs\n // destroying); its next call starts a new session from the snapshot.\n capabilities: { scope: 'rootfs', memory: false, destroysSource: true, source: 'stopped' },\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 volume: {\n create: async (config: VercelConfig, options) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? { name: options.name }\n : { name: options.name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.getOrCreate(params as any);\n return { id: drive.driveId, name: drive.name, native: drive };\n },\n get: async (config: VercelConfig, name: string) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n try {\n const params = creds.useOidc\n ? { name }\n : { name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.get(params as any);\n return { id: drive.driveId, name: drive.name, native: drive };\n } catch { return null; }\n },\n list: async (config: VercelConfig) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? {}\n : { token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const page = await VercelDrive.list(params as any);\n const out: any[] = [];\n for await (const drive of page as any) {\n out.push({ id: drive.driveId, name: drive.name, native: drive });\n }\n return out;\n },\n delete: async (config: VercelConfig, name: string) => {\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n const params = creds.useOidc\n ? { name }\n : { name, token: creds.token, teamId: creds.teamId, projectId: creds.projectId };\n const drive = await VercelDrive.get(params as any);\n await withVolumeSettle(() => drive.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.54",
|
|
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": "^3.8.0",
|
|
22
22
|
"ms": "^2.1.3",
|
|
23
|
-
"
|
|
24
|
-
"computesdk": "
|
|
23
|
+
"computesdk": "4.1.16",
|
|
24
|
+
"@computesdk/provider": "2.1.22"
|
|
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": "2.0.
|
|
56
|
+
"@computesdk/test-utils": "2.0.6"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"build": "tsup",
|