@computesdk/vercel 1.7.5 → 1.7.8
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.js +61 -64
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +61 -64
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -25,35 +25,45 @@ __export(index_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(index_exports);
|
|
26
26
|
var import_sandbox = require("@vercel/sandbox");
|
|
27
27
|
var import_provider = require("@computesdk/provider");
|
|
28
|
+
function resolveCredentials(config) {
|
|
29
|
+
const token = config.token || typeof process !== "undefined" && process.env?.VERCEL_TOKEN || "";
|
|
30
|
+
const teamId = config.teamId || typeof process !== "undefined" && process.env?.VERCEL_TEAM_ID || "";
|
|
31
|
+
const projectId = config.projectId || typeof process !== "undefined" && process.env?.VERCEL_PROJECT_ID || "";
|
|
32
|
+
const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);
|
|
33
|
+
const oidcToken = typeof process !== "undefined" && process.env?.VERCEL_OIDC_TOKEN;
|
|
34
|
+
const useOidc = !hasConfigCredentials && !!oidcToken;
|
|
35
|
+
return { useOidc, token, teamId, projectId };
|
|
36
|
+
}
|
|
37
|
+
function validateCredentials(creds) {
|
|
38
|
+
if (creds.useOidc) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!creds.token) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Missing Vercel authentication. Either:
|
|
44
|
+
1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or
|
|
45
|
+
2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
if (!creds.teamId) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
if (!creds.projectId) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
28
59
|
var vercel = (0, import_provider.defineProvider)({
|
|
29
60
|
name: "vercel",
|
|
30
61
|
methods: {
|
|
31
62
|
sandbox: {
|
|
32
63
|
// Collection operations (map to compute.sandbox.*)
|
|
33
64
|
create: async (config, options) => {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
const teamId = config.teamId || typeof process !== "undefined" && process.env?.VERCEL_TEAM_ID || "";
|
|
37
|
-
const projectId = config.projectId || typeof process !== "undefined" && process.env?.VERCEL_PROJECT_ID || "";
|
|
38
|
-
if (!oidcToken && (!token || !teamId || !projectId)) {
|
|
39
|
-
if (!oidcToken && !token) {
|
|
40
|
-
throw new Error(
|
|
41
|
-
`Missing Vercel authentication. Either:
|
|
42
|
-
1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or
|
|
43
|
-
2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
if (!oidcToken && !teamId) {
|
|
47
|
-
throw new Error(
|
|
48
|
-
`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
if (!oidcToken && !projectId) {
|
|
52
|
-
throw new Error(
|
|
53
|
-
`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
65
|
+
const creds = resolveCredentials(config);
|
|
66
|
+
validateCredentials(creds);
|
|
57
67
|
const timeout = config.timeout || 3e5;
|
|
58
68
|
try {
|
|
59
69
|
let sandbox;
|
|
@@ -66,20 +76,19 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
66
76
|
ports: config.ports,
|
|
67
77
|
timeout
|
|
68
78
|
};
|
|
69
|
-
|
|
79
|
+
const snapshotId = options?.snapshotId || options?.source?.type === "snapshot" && options?.source?.snapshotId;
|
|
80
|
+
if (snapshotId) {
|
|
70
81
|
params.source = {
|
|
71
82
|
type: "snapshot",
|
|
72
|
-
snapshotId
|
|
83
|
+
snapshotId
|
|
73
84
|
};
|
|
74
85
|
}
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
params.
|
|
79
|
-
params.teamId = teamId;
|
|
80
|
-
params.projectId = projectId;
|
|
81
|
-
sandbox = await import_sandbox.Sandbox.create(params);
|
|
86
|
+
if (!creds.useOidc) {
|
|
87
|
+
params.token = creds.token;
|
|
88
|
+
params.teamId = creds.teamId;
|
|
89
|
+
params.projectId = creds.projectId;
|
|
82
90
|
}
|
|
91
|
+
sandbox = await import_sandbox.Sandbox.create(params);
|
|
83
92
|
}
|
|
84
93
|
return {
|
|
85
94
|
sandbox,
|
|
@@ -104,20 +113,17 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
104
113
|
}
|
|
105
114
|
},
|
|
106
115
|
getById: async (config, sandboxId) => {
|
|
107
|
-
const
|
|
116
|
+
const creds = resolveCredentials(config);
|
|
108
117
|
try {
|
|
109
118
|
let sandbox;
|
|
110
|
-
if (
|
|
119
|
+
if (creds.useOidc) {
|
|
111
120
|
sandbox = await import_sandbox.Sandbox.get({ sandboxId });
|
|
112
121
|
} else {
|
|
113
|
-
const token = config.token || process.env.VERCEL_TOKEN;
|
|
114
|
-
const teamId = config.teamId || process.env.VERCEL_TEAM_ID;
|
|
115
|
-
const projectId = config.projectId || process.env.VERCEL_PROJECT_ID;
|
|
116
122
|
sandbox = await import_sandbox.Sandbox.get({
|
|
117
123
|
sandboxId,
|
|
118
|
-
token,
|
|
119
|
-
teamId,
|
|
120
|
-
projectId
|
|
124
|
+
token: creds.token,
|
|
125
|
+
teamId: creds.teamId,
|
|
126
|
+
projectId: creds.projectId
|
|
121
127
|
});
|
|
122
128
|
}
|
|
123
129
|
return {
|
|
@@ -134,20 +140,17 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
134
140
|
);
|
|
135
141
|
},
|
|
136
142
|
destroy: async (config, sandboxId) => {
|
|
137
|
-
const
|
|
143
|
+
const creds = resolveCredentials(config);
|
|
138
144
|
try {
|
|
139
145
|
let sandbox;
|
|
140
|
-
if (
|
|
146
|
+
if (creds.useOidc) {
|
|
141
147
|
sandbox = await import_sandbox.Sandbox.get({ sandboxId });
|
|
142
148
|
} else {
|
|
143
|
-
const token = config.token || process.env.VERCEL_TOKEN;
|
|
144
|
-
const teamId = config.teamId || process.env.VERCEL_TEAM_ID;
|
|
145
|
-
const projectId = config.projectId || process.env.VERCEL_PROJECT_ID;
|
|
146
149
|
sandbox = await import_sandbox.Sandbox.get({
|
|
147
150
|
sandboxId,
|
|
148
|
-
token,
|
|
149
|
-
teamId,
|
|
150
|
-
projectId
|
|
151
|
+
token: creds.token,
|
|
152
|
+
teamId: creds.teamId,
|
|
153
|
+
projectId: creds.projectId
|
|
151
154
|
});
|
|
152
155
|
}
|
|
153
156
|
await sandbox.stop();
|
|
@@ -271,19 +274,16 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
271
274
|
},
|
|
272
275
|
snapshot: {
|
|
273
276
|
create: async (config, sandboxId) => {
|
|
274
|
-
const
|
|
277
|
+
const creds = resolveCredentials(config);
|
|
275
278
|
let sandbox;
|
|
276
|
-
if (
|
|
279
|
+
if (creds.useOidc) {
|
|
277
280
|
sandbox = await import_sandbox.Sandbox.get({ sandboxId });
|
|
278
281
|
} else {
|
|
279
|
-
const token = config.token || process.env.VERCEL_TOKEN;
|
|
280
|
-
const teamId = config.teamId || process.env.VERCEL_TEAM_ID;
|
|
281
|
-
const projectId = config.projectId || process.env.VERCEL_PROJECT_ID;
|
|
282
282
|
sandbox = await import_sandbox.Sandbox.get({
|
|
283
283
|
sandboxId,
|
|
284
|
-
token,
|
|
285
|
-
teamId,
|
|
286
|
-
projectId
|
|
284
|
+
token: creds.token,
|
|
285
|
+
teamId: creds.teamId,
|
|
286
|
+
projectId: creds.projectId
|
|
287
287
|
});
|
|
288
288
|
}
|
|
289
289
|
return await sandbox.snapshot();
|
|
@@ -294,19 +294,16 @@ var vercel = (0, import_provider.defineProvider)({
|
|
|
294
294
|
);
|
|
295
295
|
},
|
|
296
296
|
delete: async (config, snapshotId) => {
|
|
297
|
-
const
|
|
297
|
+
const creds = resolveCredentials(config);
|
|
298
298
|
let snapshot;
|
|
299
|
-
if (
|
|
299
|
+
if (creds.useOidc) {
|
|
300
300
|
snapshot = await import_sandbox.Snapshot.get({ snapshotId });
|
|
301
301
|
} else {
|
|
302
|
-
const token = config.token || process.env.VERCEL_TOKEN;
|
|
303
|
-
const teamId = config.teamId || process.env.VERCEL_TEAM_ID;
|
|
304
|
-
const projectId = config.projectId || process.env.VERCEL_PROJECT_ID;
|
|
305
302
|
snapshot = await import_sandbox.Snapshot.get({
|
|
306
303
|
snapshotId,
|
|
307
|
-
token,
|
|
308
|
-
teamId,
|
|
309
|
-
projectId
|
|
304
|
+
token: creds.token,
|
|
305
|
+
teamId: creds.teamId,
|
|
306
|
+
projectId: creds.projectId
|
|
310
307
|
});
|
|
311
308
|
}
|
|
312
309
|
await snapshot.delete();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n * \n * Demonstrates the new defineProvider() factory pattern with ~50 lines\n * instead of the original ~350 lines of boilerplate.\n */\n\nimport { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\n\nexport type { VercelSandbox, VercelSnapshot };\n\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Vercel sandbox provider configuration\n */\nexport interface VercelConfig {\n /** Vercel API token */\n token?: string;\n /** Vercel team ID */\n teamId?: string;\n /** Vercel project ID */\n projectId?: string;\n /** Runtime environment for code execution */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Ports to expose */\n ports?: number[];\n}\n\n\n\n\n/**\n * Create a Vercel provider instance using the factory pattern\n */\nexport const vercel = defineProvider<VercelSandbox, VercelConfig, any, VercelSnapshot>({\n name: 'vercel',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: VercelConfig, options?: CreateSandboxOptions) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n\n // Fall back to traditional method (token + teamId + projectId)\n const token = config.token || (typeof process !== 'undefined' && process.env?.VERCEL_TOKEN) || '';\n const teamId = config.teamId || (typeof process !== 'undefined' && process.env?.VERCEL_TEAM_ID) || '';\n const projectId = config.projectId || (typeof process !== 'undefined' && process.env?.VERCEL_PROJECT_ID) || '';\n\n // Validate authentication - either OIDC token OR traditional method\n if (!oidcToken && (!token || !teamId || !projectId)) {\n if (!oidcToken && !token) {\n throw new Error(\n `Missing Vercel authentication. Either:\\n` +\n `1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or\\n` +\n `2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n if (!oidcToken && !teamId) {\n throw new Error(\n `Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`\n );\n }\n if (!oidcToken && !projectId) {\n throw new Error(\n `Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`\n );\n }\n }\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: VercelSandbox;\n\n if (options?.sandboxId) {\n // Vercel doesn't support reconnecting to existing sandboxes\n // Each sandbox is ephemeral and must be created fresh\n throw new Error(\n `Vercel provider does not support reconnecting to existing sandboxes. Vercel sandboxes are ephemeral and must be created fresh each time.`\n );\n } else {\n // Construct base params\n const params: any = {\n ports: config.ports,\n timeout,\n };\n\n if (options?.snapshotId) {\n params.source = {\n type: 'snapshot',\n snapshotId: options.snapshotId\n };\n }\n\n // Create new Vercel sandbox\n if (oidcToken) {\n sandbox = await VercelSandbox.create(params);\n } else {\n // Add auth params\n params.token = token;\n params.teamId = teamId;\n params.projectId = projectId;\n sandbox = await VercelSandbox.create(params);\n }\n }\n\n return {\n sandbox,\n sandboxId: sandbox.sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('token')) {\n throw new Error(\n `Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n if (error.message.includes('team') || error.message.includes('project')) {\n throw new Error(\n `Vercel team/project configuration failed. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`\n );\n }\n }\n throw new Error(\n `Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: VercelConfig, sandboxId: string) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n\n try {\n let sandbox: VercelSandbox;\n\n if (oidcToken) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n const token = config.token || process.env.VERCEL_TOKEN!;\n const teamId = config.teamId || process.env.VERCEL_TEAM_ID!;\n const projectId = config.projectId || process.env.VERCEL_PROJECT_ID!;\n\n sandbox = await VercelSandbox.get({\n sandboxId,\n token,\n teamId,\n projectId,\n });\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing sandboxes. Vercel sandboxes are ephemeral and designed for single-use execution.`\n );\n },\n\n destroy: async (config: VercelConfig, sandboxId: string) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n\n try {\n let sandbox: VercelSandbox;\n\n if (oidcToken) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n const token = config.token || process.env.VERCEL_TOKEN!;\n const teamId = config.teamId || process.env.VERCEL_TEAM_ID!;\n const projectId = config.projectId || process.env.VERCEL_PROJECT_ID!;\n\n sandbox = await VercelSandbox.get({\n sandboxId,\n token,\n teamId,\n projectId,\n });\n }\n\n await sandbox.stop();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: VercelSandbox, code: string, runtime?: Runtime, config?: VercelConfig): Promise<CodeResult> => {\n const startTime = Date.now();\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || config?.runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n const commandString = effectiveRuntime === 'python'\n ? `echo \"${encoded}\" | base64 -d | python3`\n : `echo \"${encoded}\" | base64 -d | node`;\n\n const result = await sandbox.runCommand('sh', ['-c', commandString]);\n // Call stdout/stderr sequentially to avoid \"Multiple consumers for logs\" warning\n const stdout = await result.stdout();\n const stderr = await result.stderr();\n\n // Check for syntax errors and throw them\n if (result.exitCode !== 0 && stderr) {\n if (stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax') ||\n stderr.includes('Unexpected token') ||\n stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${stderr.trim()}`);\n }\n }\n\n return {\n output: stdout + stderr,\n exitCode: result.exitCode,\n language: effectiveRuntime,\n };\n },\n\n runCommand: async (sandbox: VercelSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Build command with options\n let fullCommand = command;\n \n // Handle environment variables\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]) => `${k}=\"${escapeShellArg(v)}\"`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n \n // Handle working directory\n if (options?.cwd) {\n fullCommand = `cd \"${escapeShellArg(options.cwd)}\" && ${fullCommand}`;\n }\n \n // Handle background execution\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const result = await sandbox.runCommand('sh', ['-c', fullCommand]);\n // Call stdout/stderr sequentially to avoid \"Multiple consumers for logs\" warning\n const stdout = await result.stdout();\n const stderr = await result.stderr();\n\n return {\n stdout,\n stderr,\n exitCode: result.exitCode,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime,\n };\n }\n },\n\n getInfo: async (sandbox: VercelSandbox): Promise<SandboxInfo> => {\n return {\n id: 'vercel-unknown',\n provider: 'vercel',\n runtime: 'node', // Vercel default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n vercelSandboxId: 'vercel-unknown'\n }\n };\n },\n\n getUrl: async (sandbox: VercelSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Vercel's built-in domain method to get the real domain\n let url = sandbox.domain(options.port);\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}. Ensure the port has an associated route.`\n );\n }\n },\n\n filesystem: {\n readFile: async (sandbox: VercelSandbox, path: string): Promise<string> => {\n const stream = await sandbox.readFile({ path });\n if (!stream) {\n throw new Error(`File not found: ${path}`);\n }\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString('utf-8');\n },\n\n writeFile: async (sandbox: VercelSandbox, path: string, content: string): Promise<void> => {\n await sandbox.writeFiles([{ path, content: Buffer.from(content) }]);\n },\n\n mkdir: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n await sandbox.mkDir(path);\n },\n\n readdir: async (_sandbox: VercelSandbox, _path: string): Promise<FileEntry[]> => {\n throw new Error('Vercel sandbox does not support readdir. Use runCommand to list directory contents.');\n },\n\n exists: async (_sandbox: VercelSandbox, _path: string): Promise<boolean> => {\n throw new Error('Vercel sandbox does not support exists. Use runCommand to check file existence.');\n },\n\n remove: async (_sandbox: VercelSandbox, _path: string): Promise<void> => {\n throw new Error('Vercel sandbox does not support remove. Use runCommand to delete files.');\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: VercelSandbox): VercelSandbox => {\n return sandbox;\n },\n\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n\n let sandbox: VercelSandbox;\n\n if (oidcToken) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n const token = config.token || process.env.VERCEL_TOKEN!;\n const teamId = config.teamId || process.env.VERCEL_TEAM_ID!;\n const projectId = config.projectId || process.env.VERCEL_PROJECT_ID!;\n\n sandbox = await VercelSandbox.get({\n sandboxId,\n token,\n teamId,\n projectId,\n });\n }\n\n return await sandbox.snapshot();\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing snapshots.`\n );\n },\n\n delete: async (config: VercelConfig, snapshotId: string) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n\n let snapshot: VercelSnapshot;\n\n if (oidcToken) {\n // Use OIDC token method\n snapshot = await VercelSnapshot.get({ snapshotId });\n } else {\n // Use traditional method\n const token = config.token || process.env.VERCEL_TOKEN!;\n const teamId = config.teamId || process.env.VERCEL_TEAM_ID!;\n const projectId = config.projectId || process.env.VERCEL_PROJECT_ID!;\n\n snapshot = await VercelSnapshot.get({\n snapshotId,\n token,\n teamId,\n projectId,\n });\n }\n\n await snapshot.delete();\n }\n }\n }\n});\n"],"mappings":"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","names":["VercelSandbox","VercelSnapshot"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n * \n * Demonstrates the new defineProvider() factory pattern with ~50 lines\n * instead of the original ~350 lines of boilerplate.\n */\n\nimport { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\n\nexport type { VercelSandbox, VercelSnapshot };\n\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Vercel sandbox provider configuration\n */\nexport interface VercelConfig {\n /** Vercel API token */\n token?: string;\n /** Vercel team ID */\n teamId?: string;\n /** Vercel project ID */\n projectId?: string;\n /** Runtime environment for code execution */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Ports to expose */\n ports?: number[];\n}\n\n/**\n * Resolved Vercel credentials with the authentication method to use\n */\ninterface ResolvedCredentials {\n /** Whether to use OIDC authentication (no explicit credentials needed) */\n useOidc: boolean;\n /** Token for traditional auth (only used if useOidc is false) */\n token: string;\n /** Team ID for traditional auth (only used if useOidc is false) */\n teamId: string;\n /** Project ID for traditional auth (only used if useOidc is false) */\n projectId: string;\n}\n\n/**\n * Resolve Vercel credentials with proper precedence:\n * 1. Config values (from setConfig) always win\n * 2. Environment variables are used as fallback\n * 3. OIDC is only used when no config credentials are provided\n */\nfunction resolveCredentials(config: VercelConfig): ResolvedCredentials {\n // Get values from config first, then fall back to environment\n const token = config.token || (typeof process !== 'undefined' && process.env?.VERCEL_TOKEN) || '';\n const teamId = config.teamId || (typeof process !== 'undefined' && process.env?.VERCEL_TEAM_ID) || '';\n const projectId = config.projectId || (typeof process !== 'undefined' && process.env?.VERCEL_PROJECT_ID) || '';\n \n // Check if config explicitly provided credentials (config takes precedence)\n const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);\n \n // Only use OIDC if:\n // 1. No config credentials were provided, AND\n // 2. OIDC token is available in environment\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n const useOidc = !hasConfigCredentials && !!oidcToken;\n \n return { useOidc, token, teamId, projectId };\n}\n\n/**\n * Validate that we have sufficient credentials to authenticate\n */\nfunction validateCredentials(creds: ResolvedCredentials): void {\n if (creds.useOidc) {\n // OIDC auth - no additional validation needed\n return;\n }\n \n // Traditional auth - need all three\n if (!creds.token) {\n throw new Error(\n `Missing Vercel authentication. Either:\\n` +\n `1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or\\n` +\n `2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n if (!creds.teamId) {\n throw new Error(\n `Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`\n );\n }\n if (!creds.projectId) {\n throw new Error(\n `Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`\n );\n }\n}\n\n\n\n\n/**\n * Create a Vercel provider instance using the factory pattern\n */\nexport const vercel = defineProvider<VercelSandbox, VercelConfig, any, VercelSnapshot>({\n name: 'vercel',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: VercelConfig, options?: CreateSandboxOptions) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: VercelSandbox;\n\n if (options?.sandboxId) {\n // Vercel doesn't support reconnecting to existing sandboxes\n // Each sandbox is ephemeral and must be created fresh\n throw new Error(\n `Vercel provider does not support reconnecting to existing sandboxes. Vercel sandboxes are ephemeral and must be created fresh each time.`\n );\n } else {\n // Construct base params\n const params: any = {\n ports: config.ports,\n timeout,\n };\n\n // Support both ComputeSDK format (snapshotId at top level) and \n // Vercel SDK format (source.snapshotId nested)\n const snapshotId = options?.snapshotId || \n (options?.source?.type === 'snapshot' && options?.source?.snapshotId);\n \n if (snapshotId) {\n params.source = {\n type: 'snapshot',\n snapshotId\n };\n }\n\n // Add auth params if not using OIDC\n if (!creds.useOidc) {\n params.token = creds.token;\n params.teamId = creds.teamId;\n params.projectId = creds.projectId;\n }\n\n sandbox = await VercelSandbox.create(params);\n }\n\n return {\n sandbox,\n sandboxId: sandbox.sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('token')) {\n throw new Error(\n `Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n if (error.message.includes('team') || error.message.includes('project')) {\n throw new Error(\n `Vercel team/project configuration failed. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`\n );\n }\n }\n throw new Error(\n `Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: VercelConfig, sandboxId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n try {\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing sandboxes. Vercel sandboxes are ephemeral and designed for single-use execution.`\n );\n },\n\n destroy: async (config: VercelConfig, sandboxId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n try {\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n await sandbox.stop();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: VercelSandbox, code: string, runtime?: Runtime, config?: VercelConfig): Promise<CodeResult> => {\n const startTime = Date.now();\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || config?.runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n const commandString = effectiveRuntime === 'python'\n ? `echo \"${encoded}\" | base64 -d | python3`\n : `echo \"${encoded}\" | base64 -d | node`;\n\n const result = await sandbox.runCommand('sh', ['-c', commandString]);\n // Call stdout/stderr sequentially to avoid \"Multiple consumers for logs\" warning\n const stdout = await result.stdout();\n const stderr = await result.stderr();\n\n // Check for syntax errors and throw them\n if (result.exitCode !== 0 && stderr) {\n if (stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax') ||\n stderr.includes('Unexpected token') ||\n stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${stderr.trim()}`);\n }\n }\n\n return {\n output: stdout + stderr,\n exitCode: result.exitCode,\n language: effectiveRuntime,\n };\n },\n\n runCommand: async (sandbox: VercelSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Build command with options\n let fullCommand = command;\n \n // Handle environment variables\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]) => `${k}=\"${escapeShellArg(v)}\"`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n \n // Handle working directory\n if (options?.cwd) {\n fullCommand = `cd \"${escapeShellArg(options.cwd)}\" && ${fullCommand}`;\n }\n \n // Handle background execution\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const result = await sandbox.runCommand('sh', ['-c', fullCommand]);\n // Call stdout/stderr sequentially to avoid \"Multiple consumers for logs\" warning\n const stdout = await result.stdout();\n const stderr = await result.stderr();\n\n return {\n stdout,\n stderr,\n exitCode: result.exitCode,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime,\n };\n }\n },\n\n getInfo: async (sandbox: VercelSandbox): Promise<SandboxInfo> => {\n return {\n id: 'vercel-unknown',\n provider: 'vercel',\n runtime: 'node', // Vercel default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n vercelSandboxId: 'vercel-unknown'\n }\n };\n },\n\n getUrl: async (sandbox: VercelSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Vercel's built-in domain method to get the real domain\n let url = sandbox.domain(options.port);\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}. Ensure the port has an associated route.`\n );\n }\n },\n\n filesystem: {\n readFile: async (sandbox: VercelSandbox, path: string): Promise<string> => {\n const stream = await sandbox.readFile({ path });\n if (!stream) {\n throw new Error(`File not found: ${path}`);\n }\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString('utf-8');\n },\n\n writeFile: async (sandbox: VercelSandbox, path: string, content: string): Promise<void> => {\n await sandbox.writeFiles([{ path, content: Buffer.from(content) }]);\n },\n\n mkdir: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n await sandbox.mkDir(path);\n },\n\n readdir: async (_sandbox: VercelSandbox, _path: string): Promise<FileEntry[]> => {\n throw new Error('Vercel sandbox does not support readdir. Use runCommand to list directory contents.');\n },\n\n exists: async (_sandbox: VercelSandbox, _path: string): Promise<boolean> => {\n throw new Error('Vercel sandbox does not support exists. Use runCommand to check file existence.');\n },\n\n remove: async (_sandbox: VercelSandbox, _path: string): Promise<void> => {\n throw new Error('Vercel sandbox does not support remove. Use runCommand to delete files.');\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: VercelSandbox): VercelSandbox => {\n return sandbox;\n },\n\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n return await sandbox.snapshot();\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing snapshots.`\n );\n },\n\n delete: async (config: VercelConfig, snapshotId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n let snapshot: VercelSnapshot;\n\n if (creds.useOidc) {\n // Use OIDC token method\n snapshot = await VercelSnapshot.get({ snapshotId });\n } else {\n // Use traditional method\n snapshot = await VercelSnapshot.get({\n snapshotId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n await snapshot.delete();\n }\n }\n }\n});\n"],"mappings":"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","names":["VercelSandbox","VercelSnapshot"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,35 +1,45 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from "@vercel/sandbox";
|
|
3
3
|
import { defineProvider, escapeShellArg } from "@computesdk/provider";
|
|
4
|
+
function resolveCredentials(config) {
|
|
5
|
+
const token = config.token || typeof process !== "undefined" && process.env?.VERCEL_TOKEN || "";
|
|
6
|
+
const teamId = config.teamId || typeof process !== "undefined" && process.env?.VERCEL_TEAM_ID || "";
|
|
7
|
+
const projectId = config.projectId || typeof process !== "undefined" && process.env?.VERCEL_PROJECT_ID || "";
|
|
8
|
+
const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);
|
|
9
|
+
const oidcToken = typeof process !== "undefined" && process.env?.VERCEL_OIDC_TOKEN;
|
|
10
|
+
const useOidc = !hasConfigCredentials && !!oidcToken;
|
|
11
|
+
return { useOidc, token, teamId, projectId };
|
|
12
|
+
}
|
|
13
|
+
function validateCredentials(creds) {
|
|
14
|
+
if (creds.useOidc) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (!creds.token) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`Missing Vercel authentication. Either:
|
|
20
|
+
1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or
|
|
21
|
+
2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
if (!creds.teamId) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
if (!creds.projectId) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
4
35
|
var vercel = defineProvider({
|
|
5
36
|
name: "vercel",
|
|
6
37
|
methods: {
|
|
7
38
|
sandbox: {
|
|
8
39
|
// Collection operations (map to compute.sandbox.*)
|
|
9
40
|
create: async (config, options) => {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const teamId = config.teamId || typeof process !== "undefined" && process.env?.VERCEL_TEAM_ID || "";
|
|
13
|
-
const projectId = config.projectId || typeof process !== "undefined" && process.env?.VERCEL_PROJECT_ID || "";
|
|
14
|
-
if (!oidcToken && (!token || !teamId || !projectId)) {
|
|
15
|
-
if (!oidcToken && !token) {
|
|
16
|
-
throw new Error(
|
|
17
|
-
`Missing Vercel authentication. Either:
|
|
18
|
-
1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or
|
|
19
|
-
2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
if (!oidcToken && !teamId) {
|
|
23
|
-
throw new Error(
|
|
24
|
-
`Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
if (!oidcToken && !projectId) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
`Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
41
|
+
const creds = resolveCredentials(config);
|
|
42
|
+
validateCredentials(creds);
|
|
33
43
|
const timeout = config.timeout || 3e5;
|
|
34
44
|
try {
|
|
35
45
|
let sandbox;
|
|
@@ -42,20 +52,19 @@ var vercel = defineProvider({
|
|
|
42
52
|
ports: config.ports,
|
|
43
53
|
timeout
|
|
44
54
|
};
|
|
45
|
-
|
|
55
|
+
const snapshotId = options?.snapshotId || options?.source?.type === "snapshot" && options?.source?.snapshotId;
|
|
56
|
+
if (snapshotId) {
|
|
46
57
|
params.source = {
|
|
47
58
|
type: "snapshot",
|
|
48
|
-
snapshotId
|
|
59
|
+
snapshotId
|
|
49
60
|
};
|
|
50
61
|
}
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
params.
|
|
55
|
-
params.teamId = teamId;
|
|
56
|
-
params.projectId = projectId;
|
|
57
|
-
sandbox = await VercelSandbox.create(params);
|
|
62
|
+
if (!creds.useOidc) {
|
|
63
|
+
params.token = creds.token;
|
|
64
|
+
params.teamId = creds.teamId;
|
|
65
|
+
params.projectId = creds.projectId;
|
|
58
66
|
}
|
|
67
|
+
sandbox = await VercelSandbox.create(params);
|
|
59
68
|
}
|
|
60
69
|
return {
|
|
61
70
|
sandbox,
|
|
@@ -80,20 +89,17 @@ var vercel = defineProvider({
|
|
|
80
89
|
}
|
|
81
90
|
},
|
|
82
91
|
getById: async (config, sandboxId) => {
|
|
83
|
-
const
|
|
92
|
+
const creds = resolveCredentials(config);
|
|
84
93
|
try {
|
|
85
94
|
let sandbox;
|
|
86
|
-
if (
|
|
95
|
+
if (creds.useOidc) {
|
|
87
96
|
sandbox = await VercelSandbox.get({ sandboxId });
|
|
88
97
|
} else {
|
|
89
|
-
const token = config.token || process.env.VERCEL_TOKEN;
|
|
90
|
-
const teamId = config.teamId || process.env.VERCEL_TEAM_ID;
|
|
91
|
-
const projectId = config.projectId || process.env.VERCEL_PROJECT_ID;
|
|
92
98
|
sandbox = await VercelSandbox.get({
|
|
93
99
|
sandboxId,
|
|
94
|
-
token,
|
|
95
|
-
teamId,
|
|
96
|
-
projectId
|
|
100
|
+
token: creds.token,
|
|
101
|
+
teamId: creds.teamId,
|
|
102
|
+
projectId: creds.projectId
|
|
97
103
|
});
|
|
98
104
|
}
|
|
99
105
|
return {
|
|
@@ -110,20 +116,17 @@ var vercel = defineProvider({
|
|
|
110
116
|
);
|
|
111
117
|
},
|
|
112
118
|
destroy: async (config, sandboxId) => {
|
|
113
|
-
const
|
|
119
|
+
const creds = resolveCredentials(config);
|
|
114
120
|
try {
|
|
115
121
|
let sandbox;
|
|
116
|
-
if (
|
|
122
|
+
if (creds.useOidc) {
|
|
117
123
|
sandbox = await VercelSandbox.get({ sandboxId });
|
|
118
124
|
} else {
|
|
119
|
-
const token = config.token || process.env.VERCEL_TOKEN;
|
|
120
|
-
const teamId = config.teamId || process.env.VERCEL_TEAM_ID;
|
|
121
|
-
const projectId = config.projectId || process.env.VERCEL_PROJECT_ID;
|
|
122
125
|
sandbox = await VercelSandbox.get({
|
|
123
126
|
sandboxId,
|
|
124
|
-
token,
|
|
125
|
-
teamId,
|
|
126
|
-
projectId
|
|
127
|
+
token: creds.token,
|
|
128
|
+
teamId: creds.teamId,
|
|
129
|
+
projectId: creds.projectId
|
|
127
130
|
});
|
|
128
131
|
}
|
|
129
132
|
await sandbox.stop();
|
|
@@ -247,19 +250,16 @@ var vercel = defineProvider({
|
|
|
247
250
|
},
|
|
248
251
|
snapshot: {
|
|
249
252
|
create: async (config, sandboxId) => {
|
|
250
|
-
const
|
|
253
|
+
const creds = resolveCredentials(config);
|
|
251
254
|
let sandbox;
|
|
252
|
-
if (
|
|
255
|
+
if (creds.useOidc) {
|
|
253
256
|
sandbox = await VercelSandbox.get({ sandboxId });
|
|
254
257
|
} else {
|
|
255
|
-
const token = config.token || process.env.VERCEL_TOKEN;
|
|
256
|
-
const teamId = config.teamId || process.env.VERCEL_TEAM_ID;
|
|
257
|
-
const projectId = config.projectId || process.env.VERCEL_PROJECT_ID;
|
|
258
258
|
sandbox = await VercelSandbox.get({
|
|
259
259
|
sandboxId,
|
|
260
|
-
token,
|
|
261
|
-
teamId,
|
|
262
|
-
projectId
|
|
260
|
+
token: creds.token,
|
|
261
|
+
teamId: creds.teamId,
|
|
262
|
+
projectId: creds.projectId
|
|
263
263
|
});
|
|
264
264
|
}
|
|
265
265
|
return await sandbox.snapshot();
|
|
@@ -270,19 +270,16 @@ var vercel = defineProvider({
|
|
|
270
270
|
);
|
|
271
271
|
},
|
|
272
272
|
delete: async (config, snapshotId) => {
|
|
273
|
-
const
|
|
273
|
+
const creds = resolveCredentials(config);
|
|
274
274
|
let snapshot;
|
|
275
|
-
if (
|
|
275
|
+
if (creds.useOidc) {
|
|
276
276
|
snapshot = await VercelSnapshot.get({ snapshotId });
|
|
277
277
|
} else {
|
|
278
|
-
const token = config.token || process.env.VERCEL_TOKEN;
|
|
279
|
-
const teamId = config.teamId || process.env.VERCEL_TEAM_ID;
|
|
280
|
-
const projectId = config.projectId || process.env.VERCEL_PROJECT_ID;
|
|
281
278
|
snapshot = await VercelSnapshot.get({
|
|
282
279
|
snapshotId,
|
|
283
|
-
token,
|
|
284
|
-
teamId,
|
|
285
|
-
projectId
|
|
280
|
+
token: creds.token,
|
|
281
|
+
teamId: creds.teamId,
|
|
282
|
+
projectId: creds.projectId
|
|
286
283
|
});
|
|
287
284
|
}
|
|
288
285
|
await snapshot.delete();
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n * \n * Demonstrates the new defineProvider() factory pattern with ~50 lines\n * instead of the original ~350 lines of boilerplate.\n */\n\nimport { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\n\nexport type { VercelSandbox, VercelSnapshot };\n\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Vercel sandbox provider configuration\n */\nexport interface VercelConfig {\n /** Vercel API token */\n token?: string;\n /** Vercel team ID */\n teamId?: string;\n /** Vercel project ID */\n projectId?: string;\n /** Runtime environment for code execution */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Ports to expose */\n ports?: number[];\n}\n\n\n\n\n/**\n * Create a Vercel provider instance using the factory pattern\n */\nexport const vercel = defineProvider<VercelSandbox, VercelConfig, any, VercelSnapshot>({\n name: 'vercel',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: VercelConfig, options?: CreateSandboxOptions) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n\n // Fall back to traditional method (token + teamId + projectId)\n const token = config.token || (typeof process !== 'undefined' && process.env?.VERCEL_TOKEN) || '';\n const teamId = config.teamId || (typeof process !== 'undefined' && process.env?.VERCEL_TEAM_ID) || '';\n const projectId = config.projectId || (typeof process !== 'undefined' && process.env?.VERCEL_PROJECT_ID) || '';\n\n // Validate authentication - either OIDC token OR traditional method\n if (!oidcToken && (!token || !teamId || !projectId)) {\n if (!oidcToken && !token) {\n throw new Error(\n `Missing Vercel authentication. Either:\\n` +\n `1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or\\n` +\n `2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n if (!oidcToken && !teamId) {\n throw new Error(\n `Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`\n );\n }\n if (!oidcToken && !projectId) {\n throw new Error(\n `Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`\n );\n }\n }\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: VercelSandbox;\n\n if (options?.sandboxId) {\n // Vercel doesn't support reconnecting to existing sandboxes\n // Each sandbox is ephemeral and must be created fresh\n throw new Error(\n `Vercel provider does not support reconnecting to existing sandboxes. Vercel sandboxes are ephemeral and must be created fresh each time.`\n );\n } else {\n // Construct base params\n const params: any = {\n ports: config.ports,\n timeout,\n };\n\n if (options?.snapshotId) {\n params.source = {\n type: 'snapshot',\n snapshotId: options.snapshotId\n };\n }\n\n // Create new Vercel sandbox\n if (oidcToken) {\n sandbox = await VercelSandbox.create(params);\n } else {\n // Add auth params\n params.token = token;\n params.teamId = teamId;\n params.projectId = projectId;\n sandbox = await VercelSandbox.create(params);\n }\n }\n\n return {\n sandbox,\n sandboxId: sandbox.sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('token')) {\n throw new Error(\n `Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n if (error.message.includes('team') || error.message.includes('project')) {\n throw new Error(\n `Vercel team/project configuration failed. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`\n );\n }\n }\n throw new Error(\n `Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: VercelConfig, sandboxId: string) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n\n try {\n let sandbox: VercelSandbox;\n\n if (oidcToken) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n const token = config.token || process.env.VERCEL_TOKEN!;\n const teamId = config.teamId || process.env.VERCEL_TEAM_ID!;\n const projectId = config.projectId || process.env.VERCEL_PROJECT_ID!;\n\n sandbox = await VercelSandbox.get({\n sandboxId,\n token,\n teamId,\n projectId,\n });\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing sandboxes. Vercel sandboxes are ephemeral and designed for single-use execution.`\n );\n },\n\n destroy: async (config: VercelConfig, sandboxId: string) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n\n try {\n let sandbox: VercelSandbox;\n\n if (oidcToken) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n const token = config.token || process.env.VERCEL_TOKEN!;\n const teamId = config.teamId || process.env.VERCEL_TEAM_ID!;\n const projectId = config.projectId || process.env.VERCEL_PROJECT_ID!;\n\n sandbox = await VercelSandbox.get({\n sandboxId,\n token,\n teamId,\n projectId,\n });\n }\n\n await sandbox.stop();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: VercelSandbox, code: string, runtime?: Runtime, config?: VercelConfig): Promise<CodeResult> => {\n const startTime = Date.now();\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || config?.runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n const commandString = effectiveRuntime === 'python'\n ? `echo \"${encoded}\" | base64 -d | python3`\n : `echo \"${encoded}\" | base64 -d | node`;\n\n const result = await sandbox.runCommand('sh', ['-c', commandString]);\n // Call stdout/stderr sequentially to avoid \"Multiple consumers for logs\" warning\n const stdout = await result.stdout();\n const stderr = await result.stderr();\n\n // Check for syntax errors and throw them\n if (result.exitCode !== 0 && stderr) {\n if (stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax') ||\n stderr.includes('Unexpected token') ||\n stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${stderr.trim()}`);\n }\n }\n\n return {\n output: stdout + stderr,\n exitCode: result.exitCode,\n language: effectiveRuntime,\n };\n },\n\n runCommand: async (sandbox: VercelSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Build command with options\n let fullCommand = command;\n \n // Handle environment variables\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]) => `${k}=\"${escapeShellArg(v)}\"`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n \n // Handle working directory\n if (options?.cwd) {\n fullCommand = `cd \"${escapeShellArg(options.cwd)}\" && ${fullCommand}`;\n }\n \n // Handle background execution\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const result = await sandbox.runCommand('sh', ['-c', fullCommand]);\n // Call stdout/stderr sequentially to avoid \"Multiple consumers for logs\" warning\n const stdout = await result.stdout();\n const stderr = await result.stderr();\n\n return {\n stdout,\n stderr,\n exitCode: result.exitCode,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime,\n };\n }\n },\n\n getInfo: async (sandbox: VercelSandbox): Promise<SandboxInfo> => {\n return {\n id: 'vercel-unknown',\n provider: 'vercel',\n runtime: 'node', // Vercel default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n vercelSandboxId: 'vercel-unknown'\n }\n };\n },\n\n getUrl: async (sandbox: VercelSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Vercel's built-in domain method to get the real domain\n let url = sandbox.domain(options.port);\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}. Ensure the port has an associated route.`\n );\n }\n },\n\n filesystem: {\n readFile: async (sandbox: VercelSandbox, path: string): Promise<string> => {\n const stream = await sandbox.readFile({ path });\n if (!stream) {\n throw new Error(`File not found: ${path}`);\n }\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString('utf-8');\n },\n\n writeFile: async (sandbox: VercelSandbox, path: string, content: string): Promise<void> => {\n await sandbox.writeFiles([{ path, content: Buffer.from(content) }]);\n },\n\n mkdir: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n await sandbox.mkDir(path);\n },\n\n readdir: async (_sandbox: VercelSandbox, _path: string): Promise<FileEntry[]> => {\n throw new Error('Vercel sandbox does not support readdir. Use runCommand to list directory contents.');\n },\n\n exists: async (_sandbox: VercelSandbox, _path: string): Promise<boolean> => {\n throw new Error('Vercel sandbox does not support exists. Use runCommand to check file existence.');\n },\n\n remove: async (_sandbox: VercelSandbox, _path: string): Promise<void> => {\n throw new Error('Vercel sandbox does not support remove. Use runCommand to delete files.');\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: VercelSandbox): VercelSandbox => {\n return sandbox;\n },\n\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n\n let sandbox: VercelSandbox;\n\n if (oidcToken) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n const token = config.token || process.env.VERCEL_TOKEN!;\n const teamId = config.teamId || process.env.VERCEL_TEAM_ID!;\n const projectId = config.projectId || process.env.VERCEL_PROJECT_ID!;\n\n sandbox = await VercelSandbox.get({\n sandboxId,\n token,\n teamId,\n projectId,\n });\n }\n\n return await sandbox.snapshot();\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing snapshots.`\n );\n },\n\n delete: async (config: VercelConfig, snapshotId: string) => {\n // Check for OIDC token first (recommended method)\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n\n let snapshot: VercelSnapshot;\n\n if (oidcToken) {\n // Use OIDC token method\n snapshot = await VercelSnapshot.get({ snapshotId });\n } else {\n // Use traditional method\n const token = config.token || process.env.VERCEL_TOKEN!;\n const teamId = config.teamId || process.env.VERCEL_TEAM_ID!;\n const projectId = config.projectId || process.env.VERCEL_PROJECT_ID!;\n\n snapshot = await VercelSnapshot.get({\n snapshotId,\n token,\n teamId,\n projectId,\n });\n }\n\n await snapshot.delete();\n }\n }\n }\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n * \n * Demonstrates the new defineProvider() factory pattern with ~50 lines\n * instead of the original ~350 lines of boilerplate.\n */\n\nimport { Sandbox as VercelSandbox, Snapshot as VercelSnapshot } from '@vercel/sandbox';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\n\nexport type { VercelSandbox, VercelSnapshot };\n\n\nimport type { Runtime, CodeResult, CommandResult, SandboxInfo, CreateSandboxOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\n/**\n * Vercel sandbox provider configuration\n */\nexport interface VercelConfig {\n /** Vercel API token */\n token?: string;\n /** Vercel team ID */\n teamId?: string;\n /** Vercel project ID */\n projectId?: string;\n /** Runtime environment for code execution */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Ports to expose */\n ports?: number[];\n}\n\n/**\n * Resolved Vercel credentials with the authentication method to use\n */\ninterface ResolvedCredentials {\n /** Whether to use OIDC authentication (no explicit credentials needed) */\n useOidc: boolean;\n /** Token for traditional auth (only used if useOidc is false) */\n token: string;\n /** Team ID for traditional auth (only used if useOidc is false) */\n teamId: string;\n /** Project ID for traditional auth (only used if useOidc is false) */\n projectId: string;\n}\n\n/**\n * Resolve Vercel credentials with proper precedence:\n * 1. Config values (from setConfig) always win\n * 2. Environment variables are used as fallback\n * 3. OIDC is only used when no config credentials are provided\n */\nfunction resolveCredentials(config: VercelConfig): ResolvedCredentials {\n // Get values from config first, then fall back to environment\n const token = config.token || (typeof process !== 'undefined' && process.env?.VERCEL_TOKEN) || '';\n const teamId = config.teamId || (typeof process !== 'undefined' && process.env?.VERCEL_TEAM_ID) || '';\n const projectId = config.projectId || (typeof process !== 'undefined' && process.env?.VERCEL_PROJECT_ID) || '';\n \n // Check if config explicitly provided credentials (config takes precedence)\n const hasConfigCredentials = !!(config.token || config.teamId || config.projectId);\n \n // Only use OIDC if:\n // 1. No config credentials were provided, AND\n // 2. OIDC token is available in environment\n const oidcToken = typeof process !== 'undefined' && process.env?.VERCEL_OIDC_TOKEN;\n const useOidc = !hasConfigCredentials && !!oidcToken;\n \n return { useOidc, token, teamId, projectId };\n}\n\n/**\n * Validate that we have sufficient credentials to authenticate\n */\nfunction validateCredentials(creds: ResolvedCredentials): void {\n if (creds.useOidc) {\n // OIDC auth - no additional validation needed\n return;\n }\n \n // Traditional auth - need all three\n if (!creds.token) {\n throw new Error(\n `Missing Vercel authentication. Either:\\n` +\n `1. Use OIDC token: Run 'vercel env pull' to get VERCEL_OIDC_TOKEN, or\\n` +\n `2. Use traditional method: Provide 'token' in config or set VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n if (!creds.teamId) {\n throw new Error(\n `Missing Vercel team ID. Provide 'teamId' in config or set VERCEL_TEAM_ID environment variable.`\n );\n }\n if (!creds.projectId) {\n throw new Error(\n `Missing Vercel project ID. Provide 'projectId' in config or set VERCEL_PROJECT_ID environment variable.`\n );\n }\n}\n\n\n\n\n/**\n * Create a Vercel provider instance using the factory pattern\n */\nexport const vercel = defineProvider<VercelSandbox, VercelConfig, any, VercelSnapshot>({\n name: 'vercel',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: VercelConfig, options?: CreateSandboxOptions) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n validateCredentials(creds);\n\n const timeout = config.timeout || 300000;\n\n try {\n let sandbox: VercelSandbox;\n\n if (options?.sandboxId) {\n // Vercel doesn't support reconnecting to existing sandboxes\n // Each sandbox is ephemeral and must be created fresh\n throw new Error(\n `Vercel provider does not support reconnecting to existing sandboxes. Vercel sandboxes are ephemeral and must be created fresh each time.`\n );\n } else {\n // Construct base params\n const params: any = {\n ports: config.ports,\n timeout,\n };\n\n // Support both ComputeSDK format (snapshotId at top level) and \n // Vercel SDK format (source.snapshotId nested)\n const snapshotId = options?.snapshotId || \n (options?.source?.type === 'snapshot' && options?.source?.snapshotId);\n \n if (snapshotId) {\n params.source = {\n type: 'snapshot',\n snapshotId\n };\n }\n\n // Add auth params if not using OIDC\n if (!creds.useOidc) {\n params.token = creds.token;\n params.teamId = creds.teamId;\n params.projectId = creds.projectId;\n }\n\n sandbox = await VercelSandbox.create(params);\n }\n\n return {\n sandbox,\n sandboxId: sandbox.sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('token')) {\n throw new Error(\n `Vercel authentication failed. Please check your VERCEL_TOKEN environment variable. Get your token from https://vercel.com/account/tokens`\n );\n }\n if (error.message.includes('team') || error.message.includes('project')) {\n throw new Error(\n `Vercel team/project configuration failed. Please check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID environment variables.`\n );\n }\n }\n throw new Error(\n `Failed to create Vercel sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: VercelConfig, sandboxId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n try {\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n return {\n sandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing sandboxes. Vercel sandboxes are ephemeral and designed for single-use execution.`\n );\n },\n\n destroy: async (config: VercelConfig, sandboxId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n try {\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n await sandbox.stop();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (sandbox: VercelSandbox, code: string, runtime?: Runtime, config?: VercelConfig): Promise<CodeResult> => {\n const startTime = Date.now();\n\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || config?.runtime || (\n // Strong Python indicators\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n\n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n const commandString = effectiveRuntime === 'python'\n ? `echo \"${encoded}\" | base64 -d | python3`\n : `echo \"${encoded}\" | base64 -d | node`;\n\n const result = await sandbox.runCommand('sh', ['-c', commandString]);\n // Call stdout/stderr sequentially to avoid \"Multiple consumers for logs\" warning\n const stdout = await result.stdout();\n const stderr = await result.stderr();\n\n // Check for syntax errors and throw them\n if (result.exitCode !== 0 && stderr) {\n if (stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax') ||\n stderr.includes('Unexpected token') ||\n stderr.includes('Unexpected identifier')) {\n throw new Error(`Syntax error: ${stderr.trim()}`);\n }\n }\n\n return {\n output: stdout + stderr,\n exitCode: result.exitCode,\n language: effectiveRuntime,\n };\n },\n\n runCommand: async (sandbox: VercelSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Build command with options\n let fullCommand = command;\n \n // Handle environment variables\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]) => `${k}=\"${escapeShellArg(v)}\"`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n \n // Handle working directory\n if (options?.cwd) {\n fullCommand = `cd \"${escapeShellArg(options.cwd)}\" && ${fullCommand}`;\n }\n \n // Handle background execution\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n const result = await sandbox.runCommand('sh', ['-c', fullCommand]);\n // Call stdout/stderr sequentially to avoid \"Multiple consumers for logs\" warning\n const stdout = await result.stdout();\n const stderr = await result.stderr();\n\n return {\n stdout,\n stderr,\n exitCode: result.exitCode,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime,\n };\n }\n },\n\n getInfo: async (sandbox: VercelSandbox): Promise<SandboxInfo> => {\n return {\n id: 'vercel-unknown',\n provider: 'vercel',\n runtime: 'node', // Vercel default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n vercelSandboxId: 'vercel-unknown'\n }\n };\n },\n\n getUrl: async (sandbox: VercelSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Vercel's built-in domain method to get the real domain\n let url = sandbox.domain(options.port);\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Vercel domain for port ${options.port}: ${error instanceof Error ? error.message : String(error)}. Ensure the port has an associated route.`\n );\n }\n },\n\n filesystem: {\n readFile: async (sandbox: VercelSandbox, path: string): Promise<string> => {\n const stream = await sandbox.readFile({ path });\n if (!stream) {\n throw new Error(`File not found: ${path}`);\n }\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString('utf-8');\n },\n\n writeFile: async (sandbox: VercelSandbox, path: string, content: string): Promise<void> => {\n await sandbox.writeFiles([{ path, content: Buffer.from(content) }]);\n },\n\n mkdir: async (sandbox: VercelSandbox, path: string): Promise<void> => {\n await sandbox.mkDir(path);\n },\n\n readdir: async (_sandbox: VercelSandbox, _path: string): Promise<FileEntry[]> => {\n throw new Error('Vercel sandbox does not support readdir. Use runCommand to list directory contents.');\n },\n\n exists: async (_sandbox: VercelSandbox, _path: string): Promise<boolean> => {\n throw new Error('Vercel sandbox does not support exists. Use runCommand to check file existence.');\n },\n\n remove: async (_sandbox: VercelSandbox, _path: string): Promise<void> => {\n throw new Error('Vercel sandbox does not support remove. Use runCommand to delete files.');\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: VercelSandbox): VercelSandbox => {\n return sandbox;\n },\n\n },\n\n snapshot: {\n create: async (config: VercelConfig, sandboxId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n let sandbox: VercelSandbox;\n\n if (creds.useOidc) {\n // Use OIDC token method\n sandbox = await VercelSandbox.get({ sandboxId });\n } else {\n // Use traditional method\n sandbox = await VercelSandbox.get({\n sandboxId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n return await sandbox.snapshot();\n },\n\n list: async (_config: VercelConfig) => {\n throw new Error(\n `Vercel provider does not support listing snapshots.`\n );\n },\n\n delete: async (config: VercelConfig, snapshotId: string) => {\n // Resolve credentials with proper precedence (config wins over env)\n const creds = resolveCredentials(config);\n\n let snapshot: VercelSnapshot;\n\n if (creds.useOidc) {\n // Use OIDC token method\n snapshot = await VercelSnapshot.get({ snapshotId });\n } else {\n // Use traditional method\n snapshot = await VercelSnapshot.get({\n snapshotId,\n token: creds.token,\n teamId: creds.teamId,\n projectId: creds.projectId,\n });\n }\n\n await snapshot.delete();\n }\n }\n }\n});\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.8",
|
|
4
4
|
"description": "Vercel Sandbox provider for ComputeSDK - serverless code execution for Python and Node.js on Vercel's edge network",
|
|
5
5
|
"author": "Garrison",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@vercel/sandbox": "^1.2.0",
|
|
22
22
|
"ms": "^2.1.3",
|
|
23
|
-
"computesdk": "1.
|
|
24
|
-
"
|
|
23
|
+
"@computesdk/provider": "1.0.22",
|
|
24
|
+
"computesdk": "2.0.2"
|
|
25
25
|
},
|
|
26
26
|
"keywords": [
|
|
27
27
|
"computesdk",
|