@computesdk/vercel 1.5.8 → 1.5.9

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 CHANGED
@@ -237,6 +237,34 @@ var vercel = (0, import_computesdk.createProvider)({
237
237
  );
238
238
  }
239
239
  },
240
+ filesystem: {
241
+ readFile: async (sandbox, path) => {
242
+ const stream = await sandbox.readFile({ path });
243
+ if (!stream) {
244
+ throw new Error(`File not found: ${path}`);
245
+ }
246
+ const chunks = [];
247
+ for await (const chunk of stream) {
248
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
249
+ }
250
+ return Buffer.concat(chunks).toString("utf-8");
251
+ },
252
+ writeFile: async (sandbox, path, content) => {
253
+ await sandbox.writeFiles([{ path, content: Buffer.from(content) }]);
254
+ },
255
+ mkdir: async (sandbox, path) => {
256
+ await sandbox.mkDir(path);
257
+ },
258
+ readdir: async (_sandbox, _path) => {
259
+ throw new Error("Vercel sandbox does not support readdir. Use runCommand to list directory contents.");
260
+ },
261
+ exists: async (_sandbox, _path) => {
262
+ throw new Error("Vercel sandbox does not support exists. Use runCommand to check file existence.");
263
+ },
264
+ remove: async (_sandbox, _path) => {
265
+ throw new Error("Vercel sandbox does not support remove. Use runCommand to delete files.");
266
+ }
267
+ },
240
268
  // Provider-specific typed getInstance method
241
269
  getInstance: (sandbox) => {
242
270
  return sandbox;
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 createProvider() factory pattern with ~50 lines\n * instead of the original ~350 lines of boilerplate.\n */\n\nimport { Sandbox as VercelSandbox } from '@vercel/sandbox';\nimport { createProvider } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions } from 'computesdk';\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 = createProvider<VercelSandbox, VercelConfig>({\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 // Create new Vercel sandbox\n if (oidcToken) {\n sandbox = await VercelSandbox.create(\n {\n ports: config.ports,\n timeout,\n }\n );\n } else {\n sandbox = await VercelSandbox.create({\n token,\n teamId,\n projectId,\n ports: config.ports,\n timeout,\n });\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<ExecutionResult> => {\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 stdout,\n stderr,\n exitCode: result.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\n };\n },\n\n runCommand: async (sandbox: VercelSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = args.map((arg: string) => {\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(' ')}` : command;\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 executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\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 // Provider-specific typed getInstance method\n getInstance: (sandbox: VercelSandbox): VercelSandbox => {\n return sandbox;\n },\n\n }\n }\n});\n"],"mappings":"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","names":["VercelSandbox"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n * \n * Demonstrates the new createProvider() factory pattern with ~50 lines\n * instead of the original ~350 lines of boilerplate.\n */\n\nimport { Sandbox as VercelSandbox } from '@vercel/sandbox';\nimport { createProvider } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions, FileEntry } from 'computesdk';\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 = createProvider<VercelSandbox, VercelConfig>({\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 // Create new Vercel sandbox\n if (oidcToken) {\n sandbox = await VercelSandbox.create(\n {\n ports: config.ports,\n timeout,\n }\n );\n } else {\n sandbox = await VercelSandbox.create({\n token,\n teamId,\n projectId,\n ports: config.ports,\n timeout,\n });\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<ExecutionResult> => {\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 stdout,\n stderr,\n exitCode: result.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\n };\n },\n\n runCommand: async (sandbox: VercelSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = args.map((arg: string) => {\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(' ')}` : command;\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 executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\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});\n"],"mappings":"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","names":["VercelSandbox"]}
package/dist/index.mjs CHANGED
@@ -213,6 +213,34 @@ var vercel = createProvider({
213
213
  );
214
214
  }
215
215
  },
216
+ filesystem: {
217
+ readFile: async (sandbox, path) => {
218
+ const stream = await sandbox.readFile({ path });
219
+ if (!stream) {
220
+ throw new Error(`File not found: ${path}`);
221
+ }
222
+ const chunks = [];
223
+ for await (const chunk of stream) {
224
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
225
+ }
226
+ return Buffer.concat(chunks).toString("utf-8");
227
+ },
228
+ writeFile: async (sandbox, path, content) => {
229
+ await sandbox.writeFiles([{ path, content: Buffer.from(content) }]);
230
+ },
231
+ mkdir: async (sandbox, path) => {
232
+ await sandbox.mkDir(path);
233
+ },
234
+ readdir: async (_sandbox, _path) => {
235
+ throw new Error("Vercel sandbox does not support readdir. Use runCommand to list directory contents.");
236
+ },
237
+ exists: async (_sandbox, _path) => {
238
+ throw new Error("Vercel sandbox does not support exists. Use runCommand to check file existence.");
239
+ },
240
+ remove: async (_sandbox, _path) => {
241
+ throw new Error("Vercel sandbox does not support remove. Use runCommand to delete files.");
242
+ }
243
+ },
216
244
  // Provider-specific typed getInstance method
217
245
  getInstance: (sandbox) => {
218
246
  return sandbox;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Vercel Provider - Factory-based Implementation\n * \n * Demonstrates the new createProvider() factory pattern with ~50 lines\n * instead of the original ~350 lines of boilerplate.\n */\n\nimport { Sandbox as VercelSandbox } from '@vercel/sandbox';\nimport { createProvider } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions } from 'computesdk';\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 = createProvider<VercelSandbox, VercelConfig>({\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 // Create new Vercel sandbox\n if (oidcToken) {\n sandbox = await VercelSandbox.create(\n {\n ports: config.ports,\n timeout,\n }\n );\n } else {\n sandbox = await VercelSandbox.create({\n token,\n teamId,\n projectId,\n ports: config.ports,\n timeout,\n });\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<ExecutionResult> => {\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 stdout,\n stderr,\n exitCode: result.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\n };\n },\n\n runCommand: async (sandbox: VercelSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = args.map((arg: string) => {\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(' ')}` : command;\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 executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\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 // Provider-specific typed getInstance method\n getInstance: (sandbox: VercelSandbox): VercelSandbox => {\n return sandbox;\n },\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 createProvider() factory pattern with ~50 lines\n * instead of the original ~350 lines of boilerplate.\n */\n\nimport { Sandbox as VercelSandbox } from '@vercel/sandbox';\nimport { createProvider } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions, FileEntry } from 'computesdk';\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 = createProvider<VercelSandbox, VercelConfig>({\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 // Create new Vercel sandbox\n if (oidcToken) {\n sandbox = await VercelSandbox.create(\n {\n ports: config.ports,\n timeout,\n }\n );\n } else {\n sandbox = await VercelSandbox.create({\n token,\n teamId,\n projectId,\n ports: config.ports,\n timeout,\n });\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<ExecutionResult> => {\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 stdout,\n stderr,\n exitCode: result.exitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\n };\n },\n\n runCommand: async (sandbox: VercelSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments, properly quoting each arg\n const quotedArgs = args.map((arg: string) => {\n if (arg.includes(' ') || arg.includes('\"') || arg.includes(\"'\") || arg.includes('$') || arg.includes('`')) {\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\n }\n return arg;\n });\n const fullCommand = quotedArgs.length > 0 ? `${command} ${quotedArgs.join(' ')}` : command;\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 executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.sandboxId,\n provider: 'vercel'\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});\n"],"mappings":";AAOA,SAAS,WAAW,qBAAqB;AACzC,SAAS,sBAAsB;AA2BxB,IAAM,SAAS,eAA4C;AAAA,EAChE,MAAM;AAAA,EACN,SAAS;AAAA,IACP,SAAS;AAAA;AAAA,MAEP,QAAQ,OAAO,QAAsB,YAAmC;AAEtE,cAAM,YAAY,OAAO,YAAY,eAAe,QAAQ,KAAK;AAGjE,cAAM,QAAQ,OAAO,SAAU,OAAO,YAAY,eAAe,QAAQ,KAAK,gBAAiB;AAC/F,cAAM,SAAS,OAAO,UAAW,OAAO,YAAY,eAAe,QAAQ,KAAK,kBAAmB;AACnG,cAAM,YAAY,OAAO,aAAc,OAAO,YAAY,eAAe,QAAQ,KAAK,qBAAsB;AAG5G,YAAI,CAAC,cAAc,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY;AACnD,cAAI,CAAC,aAAa,CAAC,OAAO;AACxB,kBAAM,IAAI;AAAA,cACR;AAAA;AAAA;AAAA,YAGF;AAAA,UACF;AACA,cAAI,CAAC,aAAa,CAAC,QAAQ;AACzB,kBAAM,IAAI;AAAA,cACR;AAAA,YACF;AAAA,UACF;AACA,cAAI,CAAC,aAAa,CAAC,WAAW;AAC5B,kBAAM,IAAI;AAAA,cACR;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,cAAM,UAAU,OAAO,WAAW;AAElC,YAAI;AACF,cAAI;AAEJ,cAAI,SAAS,WAAW;AAGtB,kBAAM,IAAI;AAAA,cACR;AAAA,YACF;AAAA,UACF,OAAO;AAEL,gBAAI,WAAW;AACb,wBAAU,MAAM,cAAc;AAAA,gBAC5B;AAAA,kBACE,OAAO,OAAO;AAAA,kBACd;AAAA,gBACF;AAAA,cACF;AAAA,YACF,OAAO;AACL,wBAAU,MAAM,cAAc,OAAO;AAAA,gBACnC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,OAAO,OAAO;AAAA,gBACd;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAEA,iBAAO;AAAA,YACL;AAAA,YACA,WAAW,QAAQ;AAAA,UACrB;AAAA,QACF,SAAS,OAAO;AACd,cAAI,iBAAiB,OAAO;AAC1B,gBAAI,MAAM,QAAQ,SAAS,cAAc,KAAK,MAAM,QAAQ,SAAS,OAAO,GAAG;AAC7E,oBAAM,IAAI;AAAA,gBACR;AAAA,cACF;AAAA,YACF;AACA,gBAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,MAAM,QAAQ,SAAS,SAAS,GAAG;AACvE,oBAAM,IAAI;AAAA,gBACR;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,gBAAM,IAAI;AAAA,YACR,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UAC5F;AAAA,QACF;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,QAAsB,cAAsB;AAE1D,cAAM,YAAY,OAAO,YAAY,eAAe,QAAQ,KAAK;AAEjE,YAAI;AACF,cAAI;AAEJ,cAAI,WAAW;AAEb,sBAAU,MAAM,cAAc,IAAI,EAAE,UAAU,CAAC;AAAA,UACjD,OAAO;AAEL,kBAAM,QAAQ,OAAO,SAAS,QAAQ,IAAI;AAC1C,kBAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAC5C,kBAAM,YAAY,OAAO,aAAa,QAAQ,IAAI;AAElD,sBAAU,MAAM,cAAc,IAAI;AAAA,cAChC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF,CAAC;AAAA,UACH;AAEA,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AAEd,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MAEA,MAAM,OAAO,YAA0B;AACrC,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,QAAsB,cAAsB;AAE1D,cAAM,YAAY,OAAO,YAAY,eAAe,QAAQ,KAAK;AAEjE,YAAI;AACF,cAAI;AAEJ,cAAI,WAAW;AAEb,sBAAU,MAAM,cAAc,IAAI,EAAE,UAAU,CAAC;AAAA,UACjD,OAAO;AAEL,kBAAM,QAAQ,OAAO,SAAS,QAAQ,IAAI;AAC1C,kBAAM,SAAS,OAAO,UAAU,QAAQ,IAAI;AAC5C,kBAAM,YAAY,OAAO,aAAa,QAAQ,IAAI;AAElD,sBAAU,MAAM,cAAc,IAAI;AAAA,cAChC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF,CAAC;AAAA,UACH;AAEA,gBAAM,QAAQ,KAAK;AAAA,QACrB,SAAS,OAAO;AAAA,QAGhB;AAAA,MACF;AAAA;AAAA,MAGA,SAAS,OAAO,SAAwB,MAAc,SAAmB,WAAoD;AAC3H,cAAM,YAAY,KAAK,IAAI;AAG3B,cAAM,mBAAmB,WAAW,QAAQ;AAAA,SAE1C,KAAK,SAAS,QAAQ,KACpB,KAAK,SAAS,SAAS,KACvB,KAAK,SAAS,MAAM,KACpB,KAAK,SAAS,MAAM,KACpB,KAAK,SAAS,OAAO,KACrB,KAAK,SAAS,IAAI,KAClB,KAAK,SAAS,IAAI,KAClB,KAAK,SAAS,IAAI,KAClB,KAAK,SAAS,QAAQ,IACpB,WAEA;AAIN,cAAM,UAAU,OAAO,KAAK,IAAI,EAAE,SAAS,QAAQ;AACnD,cAAM,gBAAgB,qBAAqB,WACvC,SAAS,OAAO,4BAChB,SAAS,OAAO;AAEpB,cAAM,SAAS,MAAM,QAAQ,WAAW,MAAM,CAAC,MAAM,aAAa,CAAC;AAEnE,cAAM,SAAS,MAAM,OAAO,OAAO;AACnC,cAAM,SAAS,MAAM,OAAO,OAAO;AAGnC,YAAI,OAAO,aAAa,KAAK,QAAQ;AACnC,cAAI,OAAO,SAAS,aAAa,KAC/B,OAAO,SAAS,gBAAgB,KAChC,OAAO,SAAS,kBAAkB,KAClC,OAAO,SAAS,uBAAuB,GAAG;AAC1C,kBAAM,IAAI,MAAM,iBAAiB,OAAO,KAAK,CAAC,EAAE;AAAA,UAClD;AAAA,QACF;AAEA,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,UAAU,OAAO;AAAA,UACjB,eAAe,KAAK,IAAI,IAAI;AAAA,UAC5B,WAAW,QAAQ;AAAA,UACnB,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,MAEA,YAAY,OAAO,SAAwB,SAAiB,OAAiB,CAAC,MAAgC;AAC5G,cAAM,YAAY,KAAK,IAAI;AAE3B,YAAI;AAEF,gBAAM,aAAa,KAAK,IAAI,CAAC,QAAgB;AAC3C,gBAAI,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,GAAG;AACzG,qBAAO,IAAI,IAAI,QAAQ,MAAM,KAAK,CAAC;AAAA,YACrC;AACA,mBAAO;AAAA,UACT,CAAC;AACD,gBAAM,cAAc,WAAW,SAAS,IAAI,GAAG,OAAO,IAAI,WAAW,KAAK,GAAG,CAAC,KAAK;AAEnF,gBAAM,SAAS,MAAM,QAAQ,WAAW,MAAM,CAAC,MAAM,WAAW,CAAC;AAEjE,gBAAM,SAAS,MAAM,OAAO,OAAO;AACnC,gBAAM,SAAS,MAAM,OAAO,OAAO;AAEnC,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,YACA,UAAU,OAAO;AAAA,YACjB,eAAe,KAAK,IAAI,IAAI;AAAA,YAC5B,WAAW,QAAQ;AAAA,YACnB,UAAU;AAAA,UACZ;AAAA,QACF,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,QAAQ;AAAA,YACR,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,YAC7D,UAAU;AAAA,YACV,eAAe,KAAK,IAAI,IAAI;AAAA,YAC5B,WAAW,QAAQ;AAAA,YACnB,UAAU;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,MAEA,SAAS,OAAO,YAAiD;AAC/D,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,UAAU;AAAA,UACV,SAAS;AAAA;AAAA,UACT,QAAQ;AAAA,UACR,WAAW,oBAAI,KAAK;AAAA,UACpB,SAAS;AAAA,UACT,UAAU;AAAA,YACR,iBAAiB;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAAA,MAEA,QAAQ,OAAO,SAAwB,YAAkE;AACvG,YAAI;AAEF,cAAI,MAAM,QAAQ,OAAO,QAAQ,IAAI;AAGrC,cAAI,QAAQ,UAAU;AACpB,kBAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,mBAAO,WAAW,QAAQ,WAAW;AACrC,kBAAM,OAAO,SAAS;AAAA,UACxB;AAEA,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,IAAI;AAAA,YACR,wCAAwC,QAAQ,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UACjH;AAAA,QACF;AAAA,MACF;AAAA,MAEA,YAAY;AAAA,QACV,UAAU,OAAO,SAAwB,SAAkC;AACzE,gBAAM,SAAS,MAAM,QAAQ,SAAS,EAAE,KAAK,CAAC;AAC9C,cAAI,CAAC,QAAQ;AACX,kBAAM,IAAI,MAAM,mBAAmB,IAAI,EAAE;AAAA,UAC3C;AACA,gBAAM,SAAmB,CAAC;AAC1B,2BAAiB,SAAS,QAAQ;AAChC,mBAAO,KAAK,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK,CAAC;AAAA,UACjE;AACA,iBAAO,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO;AAAA,QAC/C;AAAA,QAEA,WAAW,OAAO,SAAwB,MAAc,YAAmC;AACzF,gBAAM,QAAQ,WAAW,CAAC,EAAE,MAAM,SAAS,OAAO,KAAK,OAAO,EAAE,CAAC,CAAC;AAAA,QACpE;AAAA,QAEA,OAAO,OAAO,SAAwB,SAAgC;AACpE,gBAAM,QAAQ,MAAM,IAAI;AAAA,QAC1B;AAAA,QAEA,SAAS,OAAO,UAAyB,UAAwC;AAC/E,gBAAM,IAAI,MAAM,qFAAqF;AAAA,QACvG;AAAA,QAEA,QAAQ,OAAO,UAAyB,UAAoC;AAC1E,gBAAM,IAAI,MAAM,iFAAiF;AAAA,QACnG;AAAA,QAEA,QAAQ,OAAO,UAAyB,UAAiC;AACvE,gBAAM,IAAI,MAAM,yEAAyE;AAAA,QAC3F;AAAA,MACF;AAAA;AAAA,MAGA,aAAa,CAAC,YAA0C;AACtD,eAAO;AAAA,MACT;AAAA,IAEF;AAAA,EACF;AACF,CAAC;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computesdk/vercel",
3
- "version": "1.5.8",
3
+ "version": "1.5.9",
4
4
  "description": "Vercel Sandbox provider for ComputeSDK",
5
5
  "author": "Garrison",
6
6
  "license": "MIT",