computesdk 1.0.2 → 1.1.1

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
@@ -20,515 +20,976 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- AuthenticationError: () => AuthenticationError,
24
- BaseProvider: () => BaseProvider,
25
- ComputeError: () => ComputeError,
26
- ComputeSDK: () => ComputeSDK,
27
- ConfigurationError: () => ConfigurationError,
28
- DEFAULT_TIMEOUT: () => DEFAULT_TIMEOUT,
29
- ENV_KEYS: () => ENV_KEYS,
30
- ExecutionError: () => ExecutionError,
31
- ProviderError: () => ProviderError,
32
- ProviderUnavailableError: () => ProviderUnavailableError,
33
- TimeoutError: () => TimeoutError,
34
- autoSelectProvider: () => autoSelectProvider,
35
- createComputeRegistry: () => createComputeRegistry,
36
- default: () => index_default,
37
- detectAvailableProviders: () => detectAvailableProviders,
38
- executeSandbox: () => executeSandbox,
39
- getDefaultRuntime: () => getDefaultRuntime,
40
- isCloudflareWorkers: () => isCloudflareWorkers,
41
- normalizeContainerConfig: () => normalizeContainerConfig,
42
- normalizeSandboxConfig: () => normalizeSandboxConfig,
43
- retry: () => retry,
44
- validateProviderApiKey: () => validateProviderApiKey
23
+ SandboxManager: () => SandboxManager,
24
+ compute: () => compute,
25
+ createProvider: () => createProvider,
26
+ handleComputeRequest: () => handleComputeRequest
45
27
  });
46
28
  module.exports = __toCommonJS(index_exports);
47
29
 
48
- // src/errors.ts
49
- var ComputeError = class extends Error {
30
+ // src/sandbox.ts
31
+ var SandboxManager = class {
50
32
  /**
51
- * Create a new ComputeError
52
- *
53
- * @param message Error message
54
- * @param provider Provider identifier
55
- * @param sandboxId Optional sandbox identifier
33
+ * Create a sandbox from a provider
56
34
  */
57
- constructor(message, provider, sandboxId) {
58
- super(message);
59
- this.name = this.constructor.name;
60
- this.provider = provider;
61
- this.sandboxId = sandboxId;
62
- Object.setPrototypeOf(this, new.target.prototype);
35
+ async create(provider, options) {
36
+ return await provider.sandbox.create(options);
63
37
  }
64
- };
65
- var ExecutionError = class extends ComputeError {
66
38
  /**
67
- * Create a new ExecutionError
68
- *
69
- * @param message Error message
70
- * @param provider Provider identifier
71
- * @param exitCode Exit code from the execution
72
- * @param sandboxId Optional sandbox identifier
39
+ * Get an existing sandbox by ID from a provider
73
40
  */
74
- constructor(message, provider, exitCode, sandboxId) {
75
- super(message, provider, sandboxId);
76
- /** Error code */
77
- this.code = "EXECUTION_ERROR";
78
- /** Execution errors are generally not retryable */
79
- this.isRetryable = false;
80
- this.exitCode = exitCode;
41
+ async getById(provider, sandboxId) {
42
+ return await provider.sandbox.getById(sandboxId);
81
43
  }
82
- };
83
- var TimeoutError = class extends ComputeError {
84
44
  /**
85
- * Create a new TimeoutError
86
- *
87
- * @param message Error message
88
- * @param provider Provider identifier
89
- * @param timeoutMs Timeout duration in milliseconds
90
- * @param sandboxId Optional sandbox identifier
45
+ * List all active sandboxes from a provider
91
46
  */
92
- constructor(message, provider, timeoutMs, sandboxId) {
93
- super(message, provider, sandboxId);
94
- /** Error code */
95
- this.code = "TIMEOUT_ERROR";
96
- /** Timeout errors may be retryable with a longer timeout */
97
- this.isRetryable = true;
98
- this.timeoutMs = timeoutMs;
47
+ async list(provider) {
48
+ return await provider.sandbox.list();
99
49
  }
100
- };
101
- var ProviderError = class extends ComputeError {
102
50
  /**
103
- * Create a new ProviderError
104
- *
105
- * @param message Error message
106
- * @param provider Provider identifier
107
- * @param originalError Optional original error from the provider
108
- * @param sandboxId Optional sandbox identifier
51
+ * Destroy a sandbox via a provider
109
52
  */
110
- constructor(message, provider, originalError, sandboxId) {
111
- super(message, provider, sandboxId);
112
- /** Error code */
113
- this.code = "PROVIDER_ERROR";
114
- /** Provider errors may be retryable */
115
- this.isRetryable = true;
116
- this.originalError = originalError;
53
+ async destroy(provider, sandboxId) {
54
+ return await provider.sandbox.destroy(sandboxId);
117
55
  }
118
56
  };
119
- var ConfigurationError = class extends ComputeError {
57
+
58
+ // src/compute.ts
59
+ var ComputeManager = class {
60
+ constructor() {
61
+ this.sandboxManager = new SandboxManager();
62
+ this.config = null;
63
+ this.sandbox = {
64
+ /**
65
+ * Create a sandbox from a provider (or default provider if configured)
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * import { e2b } from '@computesdk/e2b'
70
+ * import { compute } from 'computesdk'
71
+ *
72
+ * // With explicit provider
73
+ * const sandbox = await compute.sandbox.create({
74
+ * provider: e2b({ apiKey: 'your-key' })
75
+ * })
76
+ *
77
+ * // With default provider (both forms work)
78
+ * compute.setConfig({ provider: e2b({ apiKey: 'your-key' }) })
79
+ * const sandbox1 = await compute.sandbox.create({})
80
+ * const sandbox2 = await compute.sandbox.create()
81
+ * ```
82
+ */
83
+ create: async (params) => {
84
+ const provider = params && "provider" in params && params.provider ? params.provider : this.getDefaultProvider();
85
+ const options = params?.options;
86
+ return await this.sandboxManager.create(provider, options);
87
+ },
88
+ /**
89
+ * Get an existing sandbox by ID from a provider (or default provider if configured)
90
+ */
91
+ getById: async (providerOrSandboxId, sandboxId) => {
92
+ if (typeof providerOrSandboxId === "string") {
93
+ const provider = this.getDefaultProvider();
94
+ return await this.sandboxManager.getById(provider, providerOrSandboxId);
95
+ } else {
96
+ if (!sandboxId) {
97
+ throw new Error("sandboxId is required when provider is specified");
98
+ }
99
+ return await this.sandboxManager.getById(providerOrSandboxId, sandboxId);
100
+ }
101
+ },
102
+ /**
103
+ * List all active sandboxes from a provider (or default provider if configured)
104
+ */
105
+ list: async (provider) => {
106
+ const actualProvider = provider || this.getDefaultProvider();
107
+ return await this.sandboxManager.list(actualProvider);
108
+ },
109
+ /**
110
+ * Destroy a sandbox via a provider (or default provider if configured)
111
+ */
112
+ destroy: async (providerOrSandboxId, sandboxId) => {
113
+ if (typeof providerOrSandboxId === "string") {
114
+ const provider = this.getDefaultProvider();
115
+ return await this.sandboxManager.destroy(provider, providerOrSandboxId);
116
+ } else {
117
+ if (!sandboxId) {
118
+ throw new Error("sandboxId is required when provider is specified");
119
+ }
120
+ return await this.sandboxManager.destroy(providerOrSandboxId, sandboxId);
121
+ }
122
+ }
123
+ };
124
+ }
120
125
  /**
121
- * Create a new ConfigurationError
122
- *
123
- * @param message Error message
124
- * @param provider Provider identifier
125
- * @param sandboxId Optional sandbox identifier
126
+ * Set default configuration
126
127
  */
127
- constructor(message, provider, sandboxId) {
128
- super(message, provider, sandboxId);
129
- /** Error code */
130
- this.code = "CONFIGURATION_ERROR";
131
- /** Configuration errors are not retryable without changes */
132
- this.isRetryable = false;
128
+ setConfig(config) {
129
+ this.config = config;
133
130
  }
134
- };
135
- var AuthenticationError = class extends ComputeError {
136
131
  /**
137
- * Create a new AuthenticationError
138
- *
139
- * @param message Error message
140
- * @param provider Provider identifier
141
- * @param sandboxId Optional sandbox identifier
132
+ * Get current configuration
142
133
  */
143
- constructor(message, provider, sandboxId) {
144
- super(message, provider, sandboxId);
145
- /** Error code */
146
- this.code = "AUTHENTICATION_ERROR";
147
- /** Authentication errors are not retryable without new credentials */
148
- this.isRetryable = false;
134
+ getConfig() {
135
+ return this.config;
149
136
  }
150
- };
151
- var ProviderUnavailableError = class extends ComputeError {
152
137
  /**
153
- * Create a new ProviderUnavailableError
154
- *
155
- * @param message Error message
156
- * @param provider Provider identifier
157
- * @param sandboxId Optional sandbox identifier
138
+ * Clear current configuration
158
139
  */
159
- constructor(message, provider, sandboxId) {
160
- super(message, provider, sandboxId);
161
- /** Error code */
162
- this.code = "PROVIDER_UNAVAILABLE";
163
- /** Provider unavailability may be temporary */
164
- this.isRetryable = true;
140
+ clearConfig() {
141
+ this.config = null;
142
+ }
143
+ /**
144
+ * Get the default provider, throwing if not configured
145
+ */
146
+ getDefaultProvider() {
147
+ if (!this.config?.provider) {
148
+ throw new Error(
149
+ "No default provider configured. Either call compute.setConfig({ provider }) or pass provider explicitly."
150
+ );
151
+ }
152
+ return this.config.provider;
153
+ }
154
+ // Future: compute.blob.*, compute.database.*, compute.git.* will be added here
155
+ // blob = new BlobManager();
156
+ // database = new DatabaseManager();
157
+ // git = new GitManager();
158
+ /**
159
+ * Get the sandbox manager (useful for testing)
160
+ */
161
+ getSandboxManager() {
162
+ return this.sandboxManager;
165
163
  }
166
164
  };
165
+ var compute = new ComputeManager();
167
166
 
168
- // src/config.ts
169
- var DEFAULT_TIMEOUT = 3e5;
170
- var ENV_KEYS = {
171
- E2B: "E2B_API_KEY",
172
- VERCEL: "VERCEL_TOKEN",
173
- CLOUDFLARE: "CLOUDFLARE_API_TOKEN",
174
- FLY: "FLY_API_TOKEN"
175
- };
176
- function isCloudflareWorkers() {
177
- return typeof DurableObject !== "undefined" && typeof WebSocketPair !== "undefined" && typeof caches !== "undefined";
167
+ // src/request-handler.ts
168
+ async function handleComputeRequest(params) {
169
+ const { request, provider } = params;
170
+ try {
171
+ const getSandbox = async (sandboxId) => {
172
+ if (sandboxId) {
173
+ const existingSandbox = await compute.sandbox.getById(provider, sandboxId);
174
+ if (!existingSandbox) {
175
+ throw new Error(`Sandbox with ID ${sandboxId} not found`);
176
+ }
177
+ return existingSandbox;
178
+ } else {
179
+ return await compute.sandbox.create({
180
+ provider,
181
+ options: request.options || { runtime: "python" }
182
+ });
183
+ }
184
+ };
185
+ switch (request.action) {
186
+ // Sandbox operations
187
+ case "compute.sandbox.create": {
188
+ const sandbox = await compute.sandbox.create({
189
+ provider,
190
+ options: request.options || { runtime: "python" }
191
+ });
192
+ return {
193
+ success: true,
194
+ sandboxId: sandbox.sandboxId,
195
+ provider: provider.name
196
+ };
197
+ }
198
+ case "compute.sandbox.destroy": {
199
+ if (!request.sandboxId) {
200
+ return {
201
+ success: false,
202
+ error: "Sandbox ID is required for destroy action",
203
+ sandboxId: "",
204
+ provider: provider.name
205
+ };
206
+ }
207
+ await compute.sandbox.destroy(provider, request.sandboxId);
208
+ return {
209
+ success: true,
210
+ sandboxId: request.sandboxId,
211
+ provider: provider.name
212
+ };
213
+ }
214
+ case "compute.sandbox.getInfo": {
215
+ if (!request.sandboxId) {
216
+ return {
217
+ success: false,
218
+ error: "Sandbox ID is required for getInfo action",
219
+ sandboxId: "",
220
+ provider: provider.name
221
+ };
222
+ }
223
+ const sandbox = await getSandbox(request.sandboxId);
224
+ const info = await sandbox.getInfo();
225
+ return {
226
+ success: true,
227
+ sandboxId: request.sandboxId,
228
+ provider: provider.name,
229
+ info: {
230
+ id: info.id,
231
+ provider: info.provider,
232
+ runtime: info.runtime,
233
+ status: info.status,
234
+ createdAt: info.createdAt.toISOString(),
235
+ timeout: info.timeout,
236
+ metadata: info.metadata
237
+ }
238
+ };
239
+ }
240
+ case "compute.sandbox.list": {
241
+ const sandboxes = await compute.sandbox.list(provider);
242
+ return {
243
+ success: true,
244
+ sandboxId: "",
245
+ provider: provider.name,
246
+ sandboxes: sandboxes.map((sandbox) => ({
247
+ sandboxId: sandbox.sandboxId,
248
+ provider: sandbox.provider
249
+ }))
250
+ };
251
+ }
252
+ // Code execution
253
+ case "compute.sandbox.runCode": {
254
+ if (!request.code) {
255
+ return {
256
+ success: false,
257
+ error: "Code is required for runCode action",
258
+ sandboxId: request.sandboxId || "",
259
+ provider: provider.name
260
+ };
261
+ }
262
+ const sandbox = await getSandbox(request.sandboxId);
263
+ const result = await sandbox.runCode(request.code, request.runtime);
264
+ return {
265
+ success: true,
266
+ sandboxId: sandbox.sandboxId,
267
+ provider: provider.name,
268
+ result: {
269
+ stdout: result.stdout,
270
+ stderr: result.stderr,
271
+ exitCode: result.exitCode,
272
+ executionTime: result.executionTime
273
+ }
274
+ };
275
+ }
276
+ case "compute.sandbox.runCommand": {
277
+ if (!request.command) {
278
+ return {
279
+ success: false,
280
+ error: "Command is required for runCommand action",
281
+ sandboxId: request.sandboxId || "",
282
+ provider: provider.name
283
+ };
284
+ }
285
+ const sandbox = await getSandbox(request.sandboxId);
286
+ const result = await sandbox.runCommand(request.command, request.args);
287
+ return {
288
+ success: true,
289
+ sandboxId: sandbox.sandboxId,
290
+ provider: provider.name,
291
+ result: {
292
+ stdout: result.stdout,
293
+ stderr: result.stderr,
294
+ exitCode: result.exitCode,
295
+ executionTime: result.executionTime
296
+ }
297
+ };
298
+ }
299
+ // Filesystem operations
300
+ case "compute.sandbox.filesystem.readFile": {
301
+ if (!request.sandboxId) {
302
+ return {
303
+ success: false,
304
+ error: "Sandbox ID is required for filesystem operations",
305
+ sandboxId: "",
306
+ provider: provider.name
307
+ };
308
+ }
309
+ if (!request.path) {
310
+ return {
311
+ success: false,
312
+ error: "File path is required for readFile action",
313
+ sandboxId: request.sandboxId,
314
+ provider: provider.name
315
+ };
316
+ }
317
+ const sandbox = await getSandbox(request.sandboxId);
318
+ const content = await sandbox.filesystem.readFile(request.path);
319
+ return {
320
+ success: true,
321
+ sandboxId: request.sandboxId,
322
+ provider: provider.name,
323
+ fileContent: content
324
+ };
325
+ }
326
+ case "compute.sandbox.filesystem.writeFile": {
327
+ if (!request.sandboxId) {
328
+ return {
329
+ success: false,
330
+ error: "Sandbox ID is required for filesystem operations",
331
+ sandboxId: "",
332
+ provider: provider.name
333
+ };
334
+ }
335
+ if (!request.path) {
336
+ return {
337
+ success: false,
338
+ error: "File path is required for writeFile action",
339
+ sandboxId: request.sandboxId,
340
+ provider: provider.name
341
+ };
342
+ }
343
+ if (request.content === void 0) {
344
+ return {
345
+ success: false,
346
+ error: "File content is required for writeFile action",
347
+ sandboxId: request.sandboxId,
348
+ provider: provider.name
349
+ };
350
+ }
351
+ const sandbox = await getSandbox(request.sandboxId);
352
+ await sandbox.filesystem.writeFile(request.path, request.content);
353
+ return {
354
+ success: true,
355
+ sandboxId: request.sandboxId,
356
+ provider: provider.name
357
+ };
358
+ }
359
+ case "compute.sandbox.filesystem.mkdir": {
360
+ if (!request.sandboxId) {
361
+ return {
362
+ success: false,
363
+ error: "Sandbox ID is required for filesystem operations",
364
+ sandboxId: "",
365
+ provider: provider.name
366
+ };
367
+ }
368
+ if (!request.path) {
369
+ return {
370
+ success: false,
371
+ error: "Directory path is required for mkdir action",
372
+ sandboxId: request.sandboxId,
373
+ provider: provider.name
374
+ };
375
+ }
376
+ const sandbox = await getSandbox(request.sandboxId);
377
+ await sandbox.filesystem.mkdir(request.path);
378
+ return {
379
+ success: true,
380
+ sandboxId: request.sandboxId,
381
+ provider: provider.name
382
+ };
383
+ }
384
+ case "compute.sandbox.filesystem.readdir": {
385
+ if (!request.sandboxId) {
386
+ return {
387
+ success: false,
388
+ error: "Sandbox ID is required for filesystem operations",
389
+ sandboxId: "",
390
+ provider: provider.name
391
+ };
392
+ }
393
+ if (!request.path) {
394
+ return {
395
+ success: false,
396
+ error: "Directory path is required for readdir action",
397
+ sandboxId: request.sandboxId,
398
+ provider: provider.name
399
+ };
400
+ }
401
+ const sandbox = await getSandbox(request.sandboxId);
402
+ const entries = await sandbox.filesystem.readdir(request.path);
403
+ return {
404
+ success: true,
405
+ sandboxId: request.sandboxId,
406
+ provider: provider.name,
407
+ files: entries.map((entry) => ({
408
+ name: entry.name,
409
+ path: entry.path,
410
+ isDirectory: entry.isDirectory,
411
+ size: entry.size,
412
+ lastModified: entry.lastModified.toISOString()
413
+ }))
414
+ };
415
+ }
416
+ case "compute.sandbox.filesystem.exists": {
417
+ if (!request.sandboxId) {
418
+ return {
419
+ success: false,
420
+ error: "Sandbox ID is required for filesystem operations",
421
+ sandboxId: "",
422
+ provider: provider.name
423
+ };
424
+ }
425
+ if (!request.path) {
426
+ return {
427
+ success: false,
428
+ error: "Path is required for exists action",
429
+ sandboxId: request.sandboxId,
430
+ provider: provider.name
431
+ };
432
+ }
433
+ const sandbox = await getSandbox(request.sandboxId);
434
+ const exists = await sandbox.filesystem.exists(request.path);
435
+ return {
436
+ success: true,
437
+ sandboxId: request.sandboxId,
438
+ provider: provider.name,
439
+ exists
440
+ };
441
+ }
442
+ case "compute.sandbox.filesystem.remove": {
443
+ if (!request.sandboxId) {
444
+ return {
445
+ success: false,
446
+ error: "Sandbox ID is required for filesystem operations",
447
+ sandboxId: "",
448
+ provider: provider.name
449
+ };
450
+ }
451
+ if (!request.path) {
452
+ return {
453
+ success: false,
454
+ error: "Path is required for remove action",
455
+ sandboxId: request.sandboxId,
456
+ provider: provider.name
457
+ };
458
+ }
459
+ const sandbox = await getSandbox(request.sandboxId);
460
+ await sandbox.filesystem.remove(request.path);
461
+ return {
462
+ success: true,
463
+ sandboxId: request.sandboxId,
464
+ provider: provider.name
465
+ };
466
+ }
467
+ // Terminal operations
468
+ case "compute.sandbox.terminal.create": {
469
+ if (!request.sandboxId) {
470
+ return {
471
+ success: false,
472
+ error: "Sandbox ID is required for terminal operations",
473
+ sandboxId: "",
474
+ provider: provider.name
475
+ };
476
+ }
477
+ const sandbox = await getSandbox(request.sandboxId);
478
+ const terminal = await sandbox.terminal.create(request.terminalOptions);
479
+ return {
480
+ success: true,
481
+ sandboxId: request.sandboxId,
482
+ provider: provider.name,
483
+ terminal: {
484
+ pid: terminal.pid,
485
+ command: terminal.command,
486
+ status: terminal.status,
487
+ cols: terminal.cols,
488
+ rows: terminal.rows
489
+ }
490
+ };
491
+ }
492
+ case "compute.sandbox.terminal.list": {
493
+ if (!request.sandboxId) {
494
+ return {
495
+ success: false,
496
+ error: "Sandbox ID is required for terminal operations",
497
+ sandboxId: "",
498
+ provider: provider.name
499
+ };
500
+ }
501
+ const sandbox = await getSandbox(request.sandboxId);
502
+ const terminals = await sandbox.terminal.list();
503
+ return {
504
+ success: true,
505
+ sandboxId: request.sandboxId,
506
+ provider: provider.name,
507
+ terminals: terminals.map((terminal) => ({
508
+ pid: terminal.pid,
509
+ command: terminal.command,
510
+ status: terminal.status,
511
+ cols: terminal.cols,
512
+ rows: terminal.rows
513
+ }))
514
+ };
515
+ }
516
+ case "compute.sandbox.terminal.getById": {
517
+ if (!request.sandboxId) {
518
+ return {
519
+ success: false,
520
+ error: "Sandbox ID is required for terminal operations",
521
+ sandboxId: "",
522
+ provider: provider.name
523
+ };
524
+ }
525
+ if (!request.terminalId) {
526
+ return {
527
+ success: false,
528
+ error: "Terminal ID is required for getById action",
529
+ sandboxId: request.sandboxId,
530
+ provider: provider.name
531
+ };
532
+ }
533
+ const sandbox = await getSandbox(request.sandboxId);
534
+ const terminal = await sandbox.terminal.getById(request.terminalId);
535
+ if (!terminal) {
536
+ return {
537
+ success: false,
538
+ error: `Terminal with ID ${request.terminalId} not found`,
539
+ sandboxId: request.sandboxId,
540
+ provider: provider.name
541
+ };
542
+ }
543
+ return {
544
+ success: true,
545
+ sandboxId: request.sandboxId,
546
+ provider: provider.name,
547
+ terminal: {
548
+ pid: terminal.pid,
549
+ command: terminal.command,
550
+ status: terminal.status,
551
+ cols: terminal.cols,
552
+ rows: terminal.rows
553
+ }
554
+ };
555
+ }
556
+ case "compute.sandbox.terminal.destroy": {
557
+ if (!request.sandboxId) {
558
+ return {
559
+ success: false,
560
+ error: "Sandbox ID is required for terminal operations",
561
+ sandboxId: "",
562
+ provider: provider.name
563
+ };
564
+ }
565
+ if (!request.terminalId) {
566
+ return {
567
+ success: false,
568
+ error: "Terminal ID is required for destroy action",
569
+ sandboxId: request.sandboxId,
570
+ provider: provider.name
571
+ };
572
+ }
573
+ const sandbox = await getSandbox(request.sandboxId);
574
+ await sandbox.terminal.destroy(request.terminalId);
575
+ return {
576
+ success: true,
577
+ sandboxId: request.sandboxId,
578
+ provider: provider.name
579
+ };
580
+ }
581
+ // Terminal I/O operations
582
+ case "compute.sandbox.terminal.write": {
583
+ if (!request.sandboxId) {
584
+ return {
585
+ success: false,
586
+ error: "Sandbox ID is required for terminal operations",
587
+ sandboxId: "",
588
+ provider: provider.name
589
+ };
590
+ }
591
+ if (!request.terminalId) {
592
+ return {
593
+ success: false,
594
+ error: "Terminal ID is required for write action",
595
+ sandboxId: request.sandboxId,
596
+ provider: provider.name
597
+ };
598
+ }
599
+ if (!request.data) {
600
+ return {
601
+ success: false,
602
+ error: "Data is required for write action",
603
+ sandboxId: request.sandboxId,
604
+ provider: provider.name
605
+ };
606
+ }
607
+ const sandbox = await getSandbox(request.sandboxId);
608
+ const terminal = await sandbox.terminal.getById(request.terminalId);
609
+ if (!terminal) {
610
+ return {
611
+ success: false,
612
+ error: `Terminal with ID ${request.terminalId} not found`,
613
+ sandboxId: request.sandboxId,
614
+ provider: provider.name
615
+ };
616
+ }
617
+ await terminal.write(request.data);
618
+ return {
619
+ success: true,
620
+ sandboxId: request.sandboxId,
621
+ provider: provider.name
622
+ };
623
+ }
624
+ case "compute.sandbox.terminal.resize": {
625
+ if (!request.sandboxId) {
626
+ return {
627
+ success: false,
628
+ error: "Sandbox ID is required for terminal operations",
629
+ sandboxId: "",
630
+ provider: provider.name
631
+ };
632
+ }
633
+ if (!request.terminalId) {
634
+ return {
635
+ success: false,
636
+ error: "Terminal ID is required for resize action",
637
+ sandboxId: request.sandboxId,
638
+ provider: provider.name
639
+ };
640
+ }
641
+ if (!request.cols || !request.rows) {
642
+ return {
643
+ success: false,
644
+ error: "Cols and rows are required for resize action",
645
+ sandboxId: request.sandboxId,
646
+ provider: provider.name
647
+ };
648
+ }
649
+ const sandbox = await getSandbox(request.sandboxId);
650
+ const terminal = await sandbox.terminal.getById(request.terminalId);
651
+ if (!terminal) {
652
+ return {
653
+ success: false,
654
+ error: `Terminal with ID ${request.terminalId} not found`,
655
+ sandboxId: request.sandboxId,
656
+ provider: provider.name
657
+ };
658
+ }
659
+ await terminal.resize(request.cols, request.rows);
660
+ return {
661
+ success: true,
662
+ sandboxId: request.sandboxId,
663
+ provider: provider.name
664
+ };
665
+ }
666
+ case "compute.sandbox.terminal.kill": {
667
+ if (!request.sandboxId) {
668
+ return {
669
+ success: false,
670
+ error: "Sandbox ID is required for terminal operations",
671
+ sandboxId: "",
672
+ provider: provider.name
673
+ };
674
+ }
675
+ if (!request.terminalId) {
676
+ return {
677
+ success: false,
678
+ error: "Terminal ID is required for kill action",
679
+ sandboxId: request.sandboxId,
680
+ provider: provider.name
681
+ };
682
+ }
683
+ const sandbox = await getSandbox(request.sandboxId);
684
+ const terminal = await sandbox.terminal.getById(request.terminalId);
685
+ if (!terminal) {
686
+ return {
687
+ success: false,
688
+ error: `Terminal with ID ${request.terminalId} not found`,
689
+ sandboxId: request.sandboxId,
690
+ provider: provider.name
691
+ };
692
+ }
693
+ await terminal.kill();
694
+ return {
695
+ success: true,
696
+ sandboxId: request.sandboxId,
697
+ provider: provider.name
698
+ };
699
+ }
700
+ default:
701
+ return {
702
+ success: false,
703
+ error: `Unknown action: ${request.action}`,
704
+ sandboxId: request.sandboxId || "",
705
+ provider: provider.name
706
+ };
707
+ }
708
+ } catch (error) {
709
+ return {
710
+ success: false,
711
+ error: error instanceof Error ? error.message : "Unknown error occurred",
712
+ sandboxId: request.sandboxId || "",
713
+ provider: provider.name
714
+ };
715
+ }
178
716
  }
179
- function detectAvailableProviders() {
180
- const available = [];
181
- if (process.env[ENV_KEYS.E2B]) {
182
- available.push("e2b");
717
+
718
+ // src/factory.ts
719
+ var UnsupportedFileSystem = class {
720
+ constructor(providerName) {
721
+ this.providerName = providerName;
183
722
  }
184
- if (process.env[ENV_KEYS.VERCEL]) {
185
- available.push("vercel");
723
+ async readFile(_path) {
724
+ throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
186
725
  }
187
- if (isCloudflareWorkers() || process.env[ENV_KEYS.CLOUDFLARE]) {
188
- available.push("cloudflare");
726
+ async writeFile(_path, _content) {
727
+ throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
189
728
  }
190
- if (process.env[ENV_KEYS.FLY]) {
191
- available.push("fly");
729
+ async mkdir(_path) {
730
+ throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
192
731
  }
193
- return available;
194
- }
195
- function autoSelectProvider() {
196
- const available = detectAvailableProviders();
197
- return available.length > 0 ? available[0] : void 0;
198
- }
199
- function normalizeContainerConfig(container) {
200
- if (!container) {
201
- return void 0;
732
+ async readdir(_path) {
733
+ throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
202
734
  }
203
- if (typeof container === "string") {
204
- return { image: container };
735
+ async exists(_path) {
736
+ throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
205
737
  }
206
- if (!container.image) {
207
- throw new ConfigurationError("Container configuration must include an image", "config");
738
+ async remove(_path) {
739
+ throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
208
740
  }
209
- return container;
210
- }
211
- function getDefaultRuntime(provider, runtime) {
212
- if (runtime) {
213
- return runtime;
214
- }
215
- switch (provider) {
216
- case "e2b":
217
- return "python";
218
- case "vercel":
219
- return "node";
220
- case "cloudflare":
221
- case "fly":
222
- throw new ConfigurationError(
223
- `Container-based provider '${provider}' requires explicit runtime or container configuration`,
224
- provider
225
- );
226
- default:
227
- return "node";
741
+ };
742
+ var UnsupportedTerminal = class {
743
+ constructor(providerName) {
744
+ this.providerName = providerName;
228
745
  }
229
- }
230
- function validateProviderApiKey(provider) {
231
- let envKey;
232
- switch (provider) {
233
- case "e2b":
234
- envKey = ENV_KEYS.E2B;
235
- break;
236
- case "vercel":
237
- envKey = ENV_KEYS.VERCEL;
238
- break;
239
- case "cloudflare":
240
- if (isCloudflareWorkers()) {
241
- return;
242
- }
243
- envKey = ENV_KEYS.CLOUDFLARE;
244
- break;
245
- case "fly":
246
- envKey = ENV_KEYS.FLY;
247
- break;
248
- case "auto":
249
- return;
250
- // Will be handled by auto-selection
251
- default:
252
- throw new ConfigurationError(`Unknown provider: ${provider}`, "config");
253
- }
254
- if (!process.env[envKey]) {
255
- const available = detectAvailableProviders();
256
- const suggestions = available.length > 0 ? `Available providers: ${available.join(", ")}` : `No provider API keys found. Set ${Object.values(ENV_KEYS).join(" or ")} environment variables.`;
257
- throw new ConfigurationError(
258
- `Missing API key for provider '${provider}'. ${suggestions}`,
259
- provider
260
- );
746
+ async create(_options) {
747
+ throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
261
748
  }
262
- }
263
- function normalizeSandboxConfig(config) {
264
- const normalized = {
265
- provider: config?.provider || "auto",
266
- timeout: config?.timeout || DEFAULT_TIMEOUT
267
- };
268
- if (normalized.provider === "auto") {
269
- const autoProvider = autoSelectProvider();
270
- if (!autoProvider) {
271
- throw new ConfigurationError(
272
- `No provider API keys found. Set one of the following environment variables: ${Object.values(ENV_KEYS).join(", ")}`,
273
- "config"
274
- );
275
- }
276
- normalized.provider = autoProvider;
277
- } else {
278
- validateProviderApiKey(normalized.provider);
749
+ async getById(_terminalId) {
750
+ throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
279
751
  }
280
- if (config?.runtime) {
281
- normalized.runtime = config.runtime;
282
- } else if (!config?.container) {
283
- normalized.runtime = getDefaultRuntime(normalized.provider);
752
+ async list() {
753
+ throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
284
754
  }
285
- if (config?.container) {
286
- normalized.container = normalizeContainerConfig(config.container);
755
+ async destroy(_terminalId) {
756
+ throw new Error(`Terminal operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
287
757
  }
288
- return normalized;
289
- }
290
-
291
- // src/utils.ts
292
- async function executeSandbox(params) {
293
- return await params.sandbox.execute(params.code, params.runtime);
294
- }
295
- async function retry(fn, maxRetries = 3, baseDelay = 1e3) {
296
- let lastError;
297
- for (let i = 0; i < maxRetries; i++) {
298
- try {
299
- return await fn();
300
- } catch (error) {
301
- lastError = error instanceof Error ? error : new Error(String(error));
302
- if (i === maxRetries - 1) {
303
- throw lastError;
758
+ };
759
+ var SupportedFileSystem = class {
760
+ constructor(sandbox, methods) {
761
+ this.sandbox = sandbox;
762
+ this.methods = methods;
763
+ }
764
+ async readFile(path) {
765
+ return this.methods.readFile(this.sandbox, path);
766
+ }
767
+ async writeFile(path, content) {
768
+ return this.methods.writeFile(this.sandbox, path, content);
769
+ }
770
+ async mkdir(path) {
771
+ return this.methods.mkdir(this.sandbox, path);
772
+ }
773
+ async readdir(path) {
774
+ return this.methods.readdir(this.sandbox, path);
775
+ }
776
+ async exists(path) {
777
+ return this.methods.exists(this.sandbox, path);
778
+ }
779
+ async remove(path) {
780
+ return this.methods.remove(this.sandbox, path);
781
+ }
782
+ };
783
+ var GeneratedTerminalSession = class {
784
+ constructor(terminal, sandbox, methods, terminalId, command, cols = 80, rows = 24) {
785
+ this.terminal = terminal;
786
+ this.sandbox = sandbox;
787
+ this.methods = methods;
788
+ this.pid = parseInt(terminalId);
789
+ this.command = command;
790
+ this.status = "running";
791
+ this.cols = cols;
792
+ this.rows = rows;
793
+ }
794
+ async write(data) {
795
+ return this.methods.write(this.sandbox, this.terminal, data);
796
+ }
797
+ async resize(cols, rows) {
798
+ return this.methods.resize(this.sandbox, this.terminal, cols, rows);
799
+ }
800
+ async kill() {
801
+ return this.methods.kill(this.sandbox, this.terminal);
802
+ }
803
+ };
804
+ var SupportedTerminal = class {
805
+ constructor(sandbox, methods) {
806
+ this.sandbox = sandbox;
807
+ this.methods = methods;
808
+ }
809
+ async create(options) {
810
+ let terminalSession;
811
+ const createOptions = {
812
+ ...options,
813
+ onData: (data) => {
814
+ if (terminalSession?.onData) {
815
+ terminalSession.onData(data);
816
+ }
817
+ },
818
+ onExit: (exitCode) => {
819
+ if (terminalSession?.onExit) {
820
+ terminalSession.onExit(exitCode);
821
+ }
304
822
  }
305
- const delay = baseDelay * Math.pow(2, i);
306
- await new Promise((resolve) => setTimeout(resolve, delay));
307
- }
823
+ };
824
+ const result = await this.methods.create(this.sandbox, createOptions);
825
+ terminalSession = new GeneratedTerminalSession(
826
+ result.terminal,
827
+ this.sandbox,
828
+ this.methods,
829
+ result.terminalId,
830
+ options?.command || "bash",
831
+ options?.cols || 80,
832
+ options?.rows || 24
833
+ );
834
+ terminalSession.onData = options?.onData;
835
+ terminalSession.onExit = options?.onExit;
836
+ return terminalSession;
308
837
  }
309
- throw lastError;
310
- }
311
-
312
- // src/registry.ts
313
- function createComputeRegistry(providers) {
314
- if (!providers || Object.keys(providers).length === 0) {
315
- throw new ConfigurationError("Provider registry requires at least one provider", "registry");
316
- }
317
- function sandbox(id) {
318
- const parts = id.split(":");
319
- if (parts.length < 1) {
320
- throw new ConfigurationError(`Invalid sandbox ID format: ${id}`, "registry");
321
- }
322
- const providerName = parts[0];
323
- const providerFactory = providers[providerName];
324
- if (!providerFactory) {
325
- const availableProviders = Object.keys(providers).join(", ");
326
- throw new ConfigurationError(
327
- `Provider '${providerName}' not found in registry. Available providers: ${availableProviders}`,
328
- "registry"
329
- );
838
+ async getById(terminalId) {
839
+ const result = await this.methods.getById(this.sandbox, terminalId);
840
+ if (!result) return null;
841
+ return new GeneratedTerminalSession(
842
+ result.terminal,
843
+ this.sandbox,
844
+ this.methods,
845
+ result.terminalId,
846
+ "bash",
847
+ // Default command for existing terminals
848
+ 80,
849
+ // Default cols
850
+ 24
851
+ // Default rows
852
+ );
853
+ }
854
+ async list() {
855
+ const results = await this.methods.list(this.sandbox);
856
+ return results.map((result) => new GeneratedTerminalSession(
857
+ result.terminal,
858
+ this.sandbox,
859
+ this.methods,
860
+ result.terminalId,
861
+ "bash",
862
+ // Default command
863
+ 80,
864
+ // Default cols
865
+ 24
866
+ // Default rows
867
+ ));
868
+ }
869
+ async destroy(terminalId) {
870
+ return this.methods.destroy(this.sandbox, terminalId);
871
+ }
872
+ };
873
+ var GeneratedSandbox = class {
874
+ constructor(sandbox, sandboxId, providerName, methods, config, destroyMethod) {
875
+ this.sandbox = sandbox;
876
+ this.methods = methods;
877
+ this.config = config;
878
+ this.destroyMethod = destroyMethod;
879
+ this.sandboxId = sandboxId;
880
+ this.provider = providerName;
881
+ if (methods.filesystem) {
882
+ this.filesystem = new SupportedFileSystem(sandbox, methods.filesystem);
883
+ } else {
884
+ this.filesystem = new UnsupportedFileSystem(providerName);
330
885
  }
331
- if (parts.length === 1) {
332
- return providerFactory();
333
- } else if (parts.length === 2) {
334
- const runtimeOrImage = parts[1];
335
- if (isRuntime(runtimeOrImage)) {
336
- return providerFactory({ runtime: runtimeOrImage });
337
- }
338
- return providerFactory({ container: { image: runtimeOrImage } });
886
+ if (methods.terminal) {
887
+ this.terminal = new SupportedTerminal(sandbox, methods.terminal);
339
888
  } else {
340
- const containerImage = parts.slice(1).join(":");
341
- return providerFactory({ container: { image: containerImage } });
889
+ this.terminal = new UnsupportedTerminal(providerName);
342
890
  }
343
891
  }
344
- return { sandbox };
345
- }
346
- function isRuntime(value) {
347
- return ["node", "python"].includes(value);
348
- }
349
-
350
- // src/providers/base.ts
351
- var import_uuid = require("uuid");
352
- var BaseProvider = class {
353
- /**
354
- * Create a new base provider
355
- *
356
- * @param provider Provider identifier
357
- * @param timeout Execution timeout in milliseconds
358
- */
359
- constructor(provider, timeout) {
360
- /** Specification version */
361
- this.specificationVersion = "v1";
362
- this.provider = provider;
363
- this.sandboxId = (0, import_uuid.v4)();
364
- this.timeout = timeout;
892
+ async runCode(code, runtime) {
893
+ return await this.methods.runCode(this.sandbox, code, runtime, this.config);
365
894
  }
366
- /**
367
- * Execute code in the sandbox
368
- *
369
- * @param code Code to execute
370
- * @param runtime Optional runtime to use
371
- * @returns Execution result
372
- */
373
- async execute(code, runtime) {
374
- const startTime = Date.now();
375
- try {
376
- const timeoutPromise = new Promise((_, reject) => {
377
- setTimeout(() => {
378
- reject(new TimeoutError(
379
- `Execution timed out after ${this.timeout}ms`,
380
- this.provider,
381
- this.timeout,
382
- this.sandboxId
383
- ));
384
- }, this.timeout);
385
- });
386
- const result = await Promise.race([
387
- this.doExecute(code, runtime),
388
- timeoutPromise
389
- ]);
390
- const executionTime = Date.now() - startTime;
391
- return {
392
- ...result,
393
- executionTime,
394
- sandboxId: this.sandboxId,
395
- provider: this.provider
396
- };
397
- } catch (error) {
398
- if (error instanceof Error && error.name.includes("Error") && "code" in error) {
399
- throw error;
400
- }
401
- throw new ProviderError(
402
- `Execution failed: ${error instanceof Error ? error.message : String(error)}`,
403
- this.provider,
404
- error instanceof Error ? error : void 0,
405
- this.sandboxId
406
- );
407
- }
895
+ async runCommand(command, args) {
896
+ return await this.methods.runCommand(this.sandbox, command, args);
897
+ }
898
+ async getInfo() {
899
+ return await this.methods.getInfo(this.sandbox);
408
900
  }
409
- /**
410
- * Kill the sandbox
411
- *
412
- * @returns Promise that resolves when the sandbox is killed
413
- */
414
901
  async kill() {
415
- try {
416
- await this.doKill();
417
- } catch (error) {
418
- throw new ProviderError(
419
- `Failed to kill sandbox: ${error instanceof Error ? error.message : String(error)}`,
420
- this.provider,
421
- error instanceof Error ? error : void 0,
422
- this.sandboxId
423
- );
424
- }
902
+ await this.destroy();
425
903
  }
426
- /**
427
- * Get information about the sandbox
428
- *
429
- * @returns Sandbox information
430
- */
431
- async getInfo() {
432
- try {
433
- return await this.doGetInfo();
434
- } catch (error) {
435
- throw new ProviderError(
436
- `Failed to get sandbox info: ${error instanceof Error ? error.message : String(error)}`,
437
- this.provider,
438
- error instanceof Error ? error : void 0,
439
- this.sandboxId
440
- );
441
- }
904
+ async destroy() {
905
+ await this.destroyMethod(this.config, this.sandboxId);
442
906
  }
443
907
  };
444
-
445
- // src/sdk.ts
446
- var ComputeSDK = class {
447
- /**
448
- * Create a new sandbox with the specified configuration
449
- *
450
- * @param config Optional sandbox configuration
451
- * @returns Configured sandbox instance
452
- */
453
- static createSandbox(config) {
454
- const normalizedConfig = normalizeSandboxConfig(config);
455
- const providerName = normalizedConfig.provider;
456
- try {
457
- const providerPackage = `@computesdk/${providerName}`;
458
- const provider = require(providerPackage);
459
- const factory = provider[providerName];
460
- if (!factory) {
461
- throw new ConfigurationError(
462
- `Provider package ${providerPackage} does not export a '${providerName}' function`,
463
- "sdk"
464
- );
465
- }
466
- if (providerName === "cloudflare") {
467
- throw new ConfigurationError(
468
- 'Cloudflare provider requires env parameter with Sandbox namespace. Use createSandbox({ provider: "cloudflare", env: yourEnv }) from within a Worker.',
469
- "sdk"
470
- );
471
- } else if (providerName === "fly") {
472
- if (!normalizedConfig.container) {
473
- throw new ConfigurationError(
474
- `${providerName} provider requires container configuration`,
475
- "sdk"
476
- );
477
- }
478
- return factory({ ...normalizedConfig, container: normalizedConfig.container });
479
- } else {
480
- return factory(normalizedConfig);
481
- }
482
- } catch (error) {
483
- if (error instanceof ConfigurationError) {
484
- throw error;
485
- }
486
- if (error.code === "MODULE_NOT_FOUND") {
487
- throw new ConfigurationError(
488
- `Provider '${providerName}' not installed. Run: npm install @computesdk/${providerName}`,
489
- "sdk"
908
+ var GeneratedSandboxManager = class {
909
+ constructor(config, providerName, methods) {
910
+ this.config = config;
911
+ this.providerName = providerName;
912
+ this.methods = methods;
913
+ this.activeSandboxes = /* @__PURE__ */ new Map();
914
+ }
915
+ async create(options) {
916
+ const result = await this.methods.create(this.config, options);
917
+ const sandbox = new GeneratedSandbox(
918
+ result.sandbox,
919
+ result.sandboxId,
920
+ this.providerName,
921
+ this.methods,
922
+ this.config,
923
+ this.methods.destroy
924
+ );
925
+ this.activeSandboxes.set(result.sandboxId, sandbox);
926
+ return sandbox;
927
+ }
928
+ async getById(sandboxId) {
929
+ const existing = this.activeSandboxes.get(sandboxId);
930
+ if (existing) {
931
+ return existing;
932
+ }
933
+ const result = await this.methods.getById(this.config, sandboxId);
934
+ if (!result) {
935
+ return null;
936
+ }
937
+ const sandbox = new GeneratedSandbox(
938
+ result.sandbox,
939
+ result.sandboxId,
940
+ this.providerName,
941
+ this.methods,
942
+ this.config,
943
+ this.methods.destroy
944
+ );
945
+ this.activeSandboxes.set(result.sandboxId, sandbox);
946
+ return sandbox;
947
+ }
948
+ async list() {
949
+ const results = await this.methods.list(this.config);
950
+ const sandboxes = [];
951
+ for (const result of results) {
952
+ let sandbox = this.activeSandboxes.get(result.sandboxId);
953
+ if (!sandbox) {
954
+ sandbox = new GeneratedSandbox(
955
+ result.sandbox,
956
+ result.sandboxId,
957
+ this.providerName,
958
+ this.methods,
959
+ this.config,
960
+ this.methods.destroy
490
961
  );
962
+ this.activeSandboxes.set(result.sandboxId, sandbox);
491
963
  }
492
- throw new ConfigurationError(
493
- `Failed to load provider '${providerName}': ${error.message}`,
494
- "sdk"
495
- );
964
+ sandboxes.push(sandbox);
496
965
  }
966
+ return sandboxes;
497
967
  }
498
- /**
499
- * Detect available providers based on environment variables
500
- *
501
- * @returns Array of available provider types
502
- */
503
- static detectProviders() {
504
- return detectAvailableProviders();
968
+ async destroy(sandboxId) {
969
+ await this.methods.destroy(this.config, sandboxId);
970
+ this.activeSandboxes.delete(sandboxId);
505
971
  }
506
972
  };
507
-
508
- // src/index.ts
509
- var index_default = ComputeSDK;
973
+ var GeneratedProvider = class {
974
+ constructor(config, providerConfig) {
975
+ this.name = providerConfig.name;
976
+ this.sandbox = new GeneratedSandboxManager(
977
+ config,
978
+ providerConfig.name,
979
+ providerConfig.methods.sandbox
980
+ );
981
+ }
982
+ };
983
+ function createProvider(providerConfig) {
984
+ return (config) => {
985
+ return new GeneratedProvider(config, providerConfig);
986
+ };
987
+ }
510
988
  // Annotate the CommonJS export names for ESM import in node:
511
989
  0 && (module.exports = {
512
- AuthenticationError,
513
- BaseProvider,
514
- ComputeError,
515
- ComputeSDK,
516
- ConfigurationError,
517
- DEFAULT_TIMEOUT,
518
- ENV_KEYS,
519
- ExecutionError,
520
- ProviderError,
521
- ProviderUnavailableError,
522
- TimeoutError,
523
- autoSelectProvider,
524
- createComputeRegistry,
525
- detectAvailableProviders,
526
- executeSandbox,
527
- getDefaultRuntime,
528
- isCloudflareWorkers,
529
- normalizeContainerConfig,
530
- normalizeSandboxConfig,
531
- retry,
532
- validateProviderApiKey
990
+ SandboxManager,
991
+ compute,
992
+ createProvider,
993
+ handleComputeRequest
533
994
  });
534
995
  //# sourceMappingURL=index.js.map