@computesdk/vercel 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,7 +10,22 @@ npm install @computesdk/vercel
10
10
 
11
11
  ## Prerequisites
12
12
 
13
- You need the following environment variables set:
13
+ Vercel provider supports two authentication methods:
14
+
15
+ ### Method 1: OIDC Token (Recommended)
16
+
17
+ The simplest way to authenticate. Vercel manages token expiration automatically.
18
+
19
+ **Development:**
20
+ ```bash
21
+ vercel env pull # Downloads VERCEL_OIDC_TOKEN to .env.local
22
+ ```
23
+
24
+ **Production:** Vercel automatically provides `VERCEL_OIDC_TOKEN` in your deployment environment.
25
+
26
+ ### Method 2: Access Token + Team/Project IDs
27
+
28
+ Alternative method using explicit credentials:
14
29
 
15
30
  - `VERCEL_TOKEN` - Your Vercel access token (get from [Vercel Account Tokens](https://vercel.com/account/tokens))
16
31
  - `VERCEL_TEAM_ID` - Your Vercel team ID
@@ -49,6 +64,23 @@ console.log(result.stdout); // "Hello from Python on Vercel!"
49
64
  await sandbox.doKill();
50
65
  ```
51
66
 
67
+ ### Sandbox Reconnection
68
+
69
+ ```typescript
70
+ import { vercel } from '@computesdk/vercel';
71
+
72
+ // Create a new sandbox
73
+ const sandbox1 = vercel();
74
+ const result1 = await sandbox1.doExecute('console.log("First execution");');
75
+ const sandboxId = sandbox1.sandboxId;
76
+
77
+ // Later, reconnect to the same sandbox
78
+ const sandbox2 = vercel({ sandboxId });
79
+ const result2 = await sandbox2.doExecute('console.log("Reconnected!");');
80
+
81
+ // Both executions run in the same Vercel sandbox environment
82
+ ```
83
+
52
84
  ### With ComputeSDK
53
85
 
54
86
  ```typescript
@@ -79,10 +111,13 @@ console.log(result.stdout);
79
111
  ### Options
80
112
 
81
113
  ```typescript
82
- interface SandboxConfig {
114
+ interface VercelConfig {
83
115
  runtime?: 'node' | 'python'; // Default: 'node'
84
116
  timeout?: number; // Default: 300000 (5 minutes)
85
- provider?: string; // Default: 'vercel'
117
+ sandboxId?: string; // Existing sandbox ID to reconnect to
118
+ token?: string; // Vercel API token (fallback to VERCEL_TOKEN)
119
+ teamId?: string; // Vercel team ID (fallback to VERCEL_TEAM_ID)
120
+ projectId?: string; // Vercel project ID (fallback to VERCEL_PROJECT_ID)
86
121
  }
87
122
  ```
88
123
 
@@ -179,6 +214,65 @@ Terminates the sandbox.
179
214
 
180
215
  **Returns:** `Promise<void>`
181
216
 
217
+ ### Filesystem Operations
218
+
219
+ The Vercel provider supports comprehensive filesystem operations through the `filesystem` property:
220
+
221
+ #### `sandbox.filesystem.readFile(path)`
222
+
223
+ Reads the contents of a file.
224
+
225
+ ```typescript
226
+ const content = await sandbox.filesystem.readFile('/vercel/sandbox/data.txt');
227
+ console.log(content);
228
+ ```
229
+
230
+ #### `sandbox.filesystem.writeFile(path, content)`
231
+
232
+ Writes content to a file, creating directories as needed.
233
+
234
+ ```typescript
235
+ await sandbox.filesystem.writeFile('/vercel/sandbox/output.txt', 'Hello World!');
236
+ ```
237
+
238
+ #### `sandbox.filesystem.mkdir(path)`
239
+
240
+ Creates a directory and any necessary parent directories.
241
+
242
+ ```typescript
243
+ await sandbox.filesystem.mkdir('/vercel/sandbox/project/data');
244
+ ```
245
+
246
+ #### `sandbox.filesystem.readdir(path)`
247
+
248
+ Lists the contents of a directory.
249
+
250
+ ```typescript
251
+ const entries = await sandbox.filesystem.readdir('/vercel/sandbox');
252
+ entries.forEach(entry => {
253
+ console.log(`${entry.name} (${entry.isDirectory ? 'directory' : 'file'}) - ${entry.size} bytes`);
254
+ });
255
+ ```
256
+
257
+ #### `sandbox.filesystem.exists(path)`
258
+
259
+ Checks if a file or directory exists.
260
+
261
+ ```typescript
262
+ const exists = await sandbox.filesystem.exists('/vercel/sandbox/config.json');
263
+ if (exists) {
264
+ console.log('Configuration file found!');
265
+ }
266
+ ```
267
+
268
+ #### `sandbox.filesystem.remove(path)`
269
+
270
+ Removes a file or directory.
271
+
272
+ ```typescript
273
+ await sandbox.filesystem.remove('/vercel/sandbox/temp.txt');
274
+ ```
275
+
182
276
  ## Examples
183
277
 
184
278
  ### Node.js Web Server Simulation
@@ -256,6 +350,137 @@ for product, revenue in sorted(product_sales.items(), key=lambda x: x[1], revers
256
350
  console.log(result.stdout);
257
351
  ```
258
352
 
353
+ ### Filesystem Operations Example
354
+
355
+ ```typescript
356
+ import { vercel } from '@computesdk/vercel';
357
+
358
+ const sandbox = vercel({ runtime: 'python' });
359
+
360
+ // Create a complete data processing pipeline using filesystem operations
361
+ try {
362
+ // 1. Set up project structure
363
+ await sandbox.filesystem.mkdir('/vercel/sandbox/project');
364
+ await sandbox.filesystem.mkdir('/vercel/sandbox/project/data');
365
+ await sandbox.filesystem.mkdir('/vercel/sandbox/project/output');
366
+
367
+ // 2. Create configuration file
368
+ const config = {
369
+ project_name: "Vercel Data Pipeline",
370
+ version: "1.0.0",
371
+ settings: {
372
+ input_format: "json",
373
+ output_format: "csv",
374
+ debug: true
375
+ }
376
+ };
377
+
378
+ await sandbox.filesystem.writeFile(
379
+ '/vercel/sandbox/project/config.json',
380
+ JSON.stringify(config, null, 2)
381
+ );
382
+
383
+ // 3. Create sample data
384
+ const sampleData = [
385
+ { id: 1, name: "Alice", department: "Engineering", salary: 95000 },
386
+ { id: 2, name: "Bob", department: "Marketing", salary: 75000 },
387
+ { id: 3, name: "Charlie", department: "Engineering", salary: 105000 },
388
+ { id: 4, name: "Diana", department: "Sales", salary: 85000 }
389
+ ];
390
+
391
+ await sandbox.filesystem.writeFile(
392
+ '/vercel/sandbox/project/data/employees.json',
393
+ JSON.stringify(sampleData, null, 2)
394
+ );
395
+
396
+ // 4. Create and execute data processing script
397
+ const processingScript = `
398
+ import json
399
+ import csv
400
+ import os
401
+ from collections import defaultdict
402
+
403
+ # Read configuration
404
+ with open('/vercel/sandbox/project/config.json', 'r') as f:
405
+ config = json.load(f)
406
+
407
+ print(f"Running {config['project_name']} v{config['version']}")
408
+
409
+ # Read employee data
410
+ with open('/vercel/sandbox/project/data/employees.json', 'r') as f:
411
+ employees = json.load(f)
412
+
413
+ # Process data - calculate department statistics
414
+ dept_stats = defaultdict(list)
415
+ for emp in employees:
416
+ dept_stats[emp['department']].append(emp['salary'])
417
+
418
+ # Calculate averages
419
+ results = []
420
+ for dept, salaries in dept_stats.items():
421
+ avg_salary = sum(salaries) / len(salaries)
422
+ results.append({
423
+ 'department': dept,
424
+ 'employee_count': len(salaries),
425
+ 'average_salary': round(avg_salary, 2),
426
+ 'total_salary': sum(salaries)
427
+ })
428
+
429
+ # Sort by average salary
430
+ results.sort(key=lambda x: x['average_salary'], reverse=True)
431
+
432
+ # Write results as JSON
433
+ with open('/vercel/sandbox/project/output/department_stats.json', 'w') as f:
434
+ json.dump(results, f, indent=2)
435
+
436
+ # Write results as CSV
437
+ with open('/vercel/sandbox/project/output/department_stats.csv', 'w', newline='') as f:
438
+ writer = csv.DictWriter(f, fieldnames=['department', 'employee_count', 'average_salary', 'total_salary'])
439
+ writer.writeheader()
440
+ writer.writerows(results)
441
+
442
+ print("Processing complete!")
443
+ print(f"Generated {len(results)} department statistics")
444
+
445
+ # Print summary
446
+ for result in results:
447
+ print(f"{result['department']}: {result['employee_count']} employees, avg salary ${result['average_salary']}")
448
+ `;
449
+
450
+ await sandbox.filesystem.writeFile('/vercel/sandbox/project/process.py', processingScript);
451
+
452
+ // 5. Execute the processing script
453
+ const result = await sandbox.doExecute('python /vercel/sandbox/project/process.py');
454
+ console.log('Execution Output:', result.stdout);
455
+
456
+ // 6. Read and display results
457
+ const jsonResults = await sandbox.filesystem.readFile('/vercel/sandbox/project/output/department_stats.json');
458
+ const csvResults = await sandbox.filesystem.readFile('/vercel/sandbox/project/output/department_stats.csv');
459
+
460
+ console.log('JSON Results:', jsonResults);
461
+ console.log('CSV Results:', csvResults);
462
+
463
+ // 7. List all generated files
464
+ const outputFiles = await sandbox.filesystem.readdir('/vercel/sandbox/project/output');
465
+ console.log('Generated files:');
466
+ outputFiles.forEach(file => {
467
+ console.log(` ${file.name} (${file.size} bytes)`);
468
+ });
469
+
470
+ // 8. Verify file existence
471
+ const configExists = await sandbox.filesystem.exists('/vercel/sandbox/project/config.json');
472
+ const resultsExist = await sandbox.filesystem.exists('/vercel/sandbox/project/output/department_stats.json');
473
+
474
+ console.log(`Configuration file exists: ${configExists}`);
475
+ console.log(`Results file exists: ${resultsExist}`);
476
+
477
+ } catch (error) {
478
+ console.error('Pipeline failed:', error.message);
479
+ } finally {
480
+ await sandbox.doKill();
481
+ }
482
+ ```
483
+
259
484
  ## Error Handling
260
485
 
261
486
  The provider includes comprehensive error handling:
package/dist/index.d.mts CHANGED
@@ -1,21 +1,24 @@
1
- import { ComputeSpecification, SandboxConfig, Runtime, ExecutionResult, SandboxInfo } from 'computesdk';
1
+ import * as computesdk from 'computesdk';
2
+ import { Runtime } from 'computesdk';
2
3
 
3
- declare class VercelProvider implements ComputeSpecification {
4
- readonly specificationVersion: "v1";
5
- readonly provider = "vercel";
6
- readonly sandboxId: string;
7
- private sandbox;
8
- private readonly token;
9
- private readonly teamId;
10
- private readonly projectId;
11
- private readonly runtime;
12
- private readonly timeout;
13
- constructor(config: SandboxConfig);
14
- private ensureSandbox;
15
- doExecute(code: string, runtime?: Runtime): Promise<ExecutionResult>;
16
- doKill(): Promise<void>;
17
- doGetInfo(): Promise<SandboxInfo>;
4
+ /**
5
+ * Vercel-specific configuration options
6
+ */
7
+ interface VercelConfig {
8
+ /** Vercel API token - if not provided, will fallback to VERCEL_TOKEN environment variable */
9
+ token?: string;
10
+ /** Vercel team ID - if not provided, will fallback to VERCEL_TEAM_ID environment variable */
11
+ teamId?: string;
12
+ /** Vercel project ID - if not provided, will fallback to VERCEL_PROJECT_ID environment variable */
13
+ projectId?: string;
14
+ /** Default runtime environment */
15
+ runtime?: Runtime;
16
+ /** Execution timeout in milliseconds */
17
+ timeout?: number;
18
18
  }
19
- declare function vercel(config?: Partial<SandboxConfig>): VercelProvider;
19
+ /**
20
+ * Create a Vercel provider instance using the factory pattern
21
+ */
22
+ declare const vercel: (config: VercelConfig) => computesdk.Provider;
20
23
 
21
- export { VercelProvider, vercel };
24
+ export { type VercelConfig, vercel };
package/dist/index.d.ts CHANGED
@@ -1,21 +1,24 @@
1
- import { ComputeSpecification, SandboxConfig, Runtime, ExecutionResult, SandboxInfo } from 'computesdk';
1
+ import * as computesdk from 'computesdk';
2
+ import { Runtime } from 'computesdk';
2
3
 
3
- declare class VercelProvider implements ComputeSpecification {
4
- readonly specificationVersion: "v1";
5
- readonly provider = "vercel";
6
- readonly sandboxId: string;
7
- private sandbox;
8
- private readonly token;
9
- private readonly teamId;
10
- private readonly projectId;
11
- private readonly runtime;
12
- private readonly timeout;
13
- constructor(config: SandboxConfig);
14
- private ensureSandbox;
15
- doExecute(code: string, runtime?: Runtime): Promise<ExecutionResult>;
16
- doKill(): Promise<void>;
17
- doGetInfo(): Promise<SandboxInfo>;
4
+ /**
5
+ * Vercel-specific configuration options
6
+ */
7
+ interface VercelConfig {
8
+ /** Vercel API token - if not provided, will fallback to VERCEL_TOKEN environment variable */
9
+ token?: string;
10
+ /** Vercel team ID - if not provided, will fallback to VERCEL_TEAM_ID environment variable */
11
+ teamId?: string;
12
+ /** Vercel project ID - if not provided, will fallback to VERCEL_PROJECT_ID environment variable */
13
+ projectId?: string;
14
+ /** Default runtime environment */
15
+ runtime?: Runtime;
16
+ /** Execution timeout in milliseconds */
17
+ timeout?: number;
18
18
  }
19
- declare function vercel(config?: Partial<SandboxConfig>): VercelProvider;
19
+ /**
20
+ * Create a Vercel provider instance using the factory pattern
21
+ */
22
+ declare const vercel: (config: VercelConfig) => computesdk.Provider;
20
23
 
21
- export { VercelProvider, vercel };
24
+ export { type VercelConfig, vercel };