computesdk 1.8.8 → 1.9.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/README.md +98 -17
- package/dist/index.d.mts +313 -354
- package/dist/index.d.ts +313 -354
- package/dist/index.js +759 -457
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +750 -454
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -20,241 +20,786 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
CommandExitError: () => CommandExitError,
|
|
23
|
+
CommandExitError: () => import_client2.CommandExitError,
|
|
24
|
+
GATEWAY_URL: () => GATEWAY_URL,
|
|
25
|
+
PROVIDER_ENV_VARS: () => PROVIDER_ENV_VARS,
|
|
26
|
+
PROVIDER_PRIORITY: () => PROVIDER_PRIORITY,
|
|
27
|
+
Sandbox: () => import_client.Sandbox,
|
|
28
|
+
autoConfigureCompute: () => autoConfigureCompute,
|
|
29
|
+
calculateBackoff: () => calculateBackoff,
|
|
24
30
|
compute: () => compute,
|
|
25
|
-
createBackgroundCommand: () => createBackgroundCommand,
|
|
26
31
|
createCompute: () => createCompute,
|
|
27
32
|
createProvider: () => createProvider,
|
|
33
|
+
detectProvider: () => detectProvider,
|
|
34
|
+
gateway: () => gateway,
|
|
35
|
+
getProviderHeaders: () => getProviderHeaders,
|
|
28
36
|
handleComputeRequest: () => handleComputeRequest,
|
|
29
|
-
isCommandExitError: () => isCommandExitError
|
|
37
|
+
isCommandExitError: () => import_client2.isCommandExitError,
|
|
38
|
+
isGatewayModeEnabled: () => isGatewayModeEnabled
|
|
30
39
|
});
|
|
31
40
|
module.exports = __toCommonJS(index_exports);
|
|
32
41
|
|
|
33
42
|
// src/types/sandbox.ts
|
|
34
|
-
var
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
var import_client = require("@computesdk/client");
|
|
44
|
+
var import_client2 = require("@computesdk/client");
|
|
45
|
+
|
|
46
|
+
// src/constants.ts
|
|
47
|
+
var GATEWAY_URL = "https://gateway.computesdk.com";
|
|
48
|
+
var PROVIDER_PRIORITY = [
|
|
49
|
+
"e2b",
|
|
50
|
+
"railway",
|
|
51
|
+
"daytona",
|
|
52
|
+
"modal",
|
|
53
|
+
"runloop",
|
|
54
|
+
"vercel",
|
|
55
|
+
"cloudflare",
|
|
56
|
+
"codesandbox",
|
|
57
|
+
"blaxel"
|
|
58
|
+
];
|
|
59
|
+
var PROVIDER_ENV_VARS = {
|
|
60
|
+
e2b: ["E2B_API_KEY"],
|
|
61
|
+
railway: ["RAILWAY_API_KEY", "RAILWAY_PROJECT_ID", "RAILWAY_ENVIRONMENT_ID"],
|
|
62
|
+
daytona: ["DAYTONA_API_KEY"],
|
|
63
|
+
modal: ["MODAL_TOKEN_ID", "MODAL_TOKEN_SECRET"],
|
|
64
|
+
runloop: ["RUNLOOP_API_KEY"],
|
|
65
|
+
vercel: ["VERCEL_TOKEN", "VERCEL_TEAM_ID", "VERCEL_PROJECT_ID"],
|
|
66
|
+
cloudflare: ["CLOUDFLARE_API_TOKEN", "CLOUDFLARE_ACCOUNT_ID"],
|
|
67
|
+
codesandbox: ["CSB_API_KEY"],
|
|
68
|
+
blaxel: ["BL_API_KEY", "BL_WORKSPACE"]
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// src/providers/gateway.ts
|
|
72
|
+
var import_client3 = require("@computesdk/client");
|
|
73
|
+
|
|
74
|
+
// src/factory.ts
|
|
75
|
+
var import_cmd = require("@computesdk/cmd");
|
|
76
|
+
var UnsupportedFileSystem = class {
|
|
77
|
+
constructor(providerName) {
|
|
78
|
+
this.providerName = providerName;
|
|
79
|
+
}
|
|
80
|
+
async readFile(_path) {
|
|
81
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
82
|
+
}
|
|
83
|
+
async writeFile(_path, _content) {
|
|
84
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
85
|
+
}
|
|
86
|
+
async mkdir(_path) {
|
|
87
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
88
|
+
}
|
|
89
|
+
async readdir(_path) {
|
|
90
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
91
|
+
}
|
|
92
|
+
async exists(_path) {
|
|
93
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
94
|
+
}
|
|
95
|
+
async remove(_path) {
|
|
96
|
+
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
39
97
|
}
|
|
40
98
|
};
|
|
41
|
-
|
|
42
|
-
|
|
99
|
+
var SupportedFileSystem = class {
|
|
100
|
+
constructor(sandbox, methods, allMethods) {
|
|
101
|
+
this.sandbox = sandbox;
|
|
102
|
+
this.methods = methods;
|
|
103
|
+
this.allMethods = allMethods;
|
|
104
|
+
}
|
|
105
|
+
async readFile(path) {
|
|
106
|
+
return this.methods.readFile(this.sandbox, path, this.allMethods.runCommand);
|
|
107
|
+
}
|
|
108
|
+
async writeFile(path, content) {
|
|
109
|
+
return this.methods.writeFile(this.sandbox, path, content, this.allMethods.runCommand);
|
|
110
|
+
}
|
|
111
|
+
async mkdir(path) {
|
|
112
|
+
return this.methods.mkdir(this.sandbox, path, this.allMethods.runCommand);
|
|
113
|
+
}
|
|
114
|
+
async readdir(path) {
|
|
115
|
+
return this.methods.readdir(this.sandbox, path, this.allMethods.runCommand);
|
|
116
|
+
}
|
|
117
|
+
async exists(path) {
|
|
118
|
+
return this.methods.exists(this.sandbox, path, this.allMethods.runCommand);
|
|
119
|
+
}
|
|
120
|
+
async remove(path) {
|
|
121
|
+
return this.methods.remove(this.sandbox, path, this.allMethods.runCommand);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
var GeneratedSandbox = class {
|
|
125
|
+
constructor(sandbox, sandboxId, providerName, methods, config, destroyMethod, providerInstance) {
|
|
126
|
+
this.sandbox = sandbox;
|
|
127
|
+
this.methods = methods;
|
|
128
|
+
this.config = config;
|
|
129
|
+
this.destroyMethod = destroyMethod;
|
|
130
|
+
this.providerInstance = providerInstance;
|
|
131
|
+
this.sandboxId = sandboxId;
|
|
132
|
+
this.provider = providerName;
|
|
133
|
+
if (methods.filesystem) {
|
|
134
|
+
this.filesystem = new SupportedFileSystem(sandbox, methods.filesystem, methods);
|
|
135
|
+
} else {
|
|
136
|
+
this.filesystem = new UnsupportedFileSystem(providerName);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
getInstance() {
|
|
140
|
+
if (this.methods.getInstance) {
|
|
141
|
+
return this.methods.getInstance(this.sandbox);
|
|
142
|
+
}
|
|
143
|
+
return this.sandbox;
|
|
144
|
+
}
|
|
145
|
+
async runCode(code, runtime) {
|
|
146
|
+
return await this.methods.runCode(this.sandbox, code, runtime, this.config);
|
|
147
|
+
}
|
|
148
|
+
async runCommand(commandOrArray, argsOrOptions, maybeOptions) {
|
|
149
|
+
let command;
|
|
150
|
+
let args;
|
|
151
|
+
let options;
|
|
152
|
+
if (Array.isArray(commandOrArray)) {
|
|
153
|
+
[command, ...args] = commandOrArray;
|
|
154
|
+
options = argsOrOptions;
|
|
155
|
+
} else {
|
|
156
|
+
command = commandOrArray;
|
|
157
|
+
args = Array.isArray(argsOrOptions) ? argsOrOptions : [];
|
|
158
|
+
options = Array.isArray(argsOrOptions) ? maybeOptions : argsOrOptions;
|
|
159
|
+
}
|
|
160
|
+
const baseCommand = args.length > 0 ? [command, ...args] : [command];
|
|
161
|
+
if (options?.cwd || options?.background) {
|
|
162
|
+
const wrappedCommand = (0, import_cmd.cmd)(baseCommand, {
|
|
163
|
+
cwd: options.cwd,
|
|
164
|
+
background: options.background
|
|
165
|
+
});
|
|
166
|
+
const [wrappedCmd, ...wrappedArgs] = wrappedCommand;
|
|
167
|
+
return await this.methods.runCommand(this.sandbox, wrappedCmd, wrappedArgs, void 0);
|
|
168
|
+
}
|
|
169
|
+
return await this.methods.runCommand(this.sandbox, command, args, options);
|
|
170
|
+
}
|
|
171
|
+
async getInfo() {
|
|
172
|
+
return await this.methods.getInfo(this.sandbox);
|
|
173
|
+
}
|
|
174
|
+
async getUrl(options) {
|
|
175
|
+
return await this.methods.getUrl(this.sandbox, options);
|
|
176
|
+
}
|
|
177
|
+
getProvider() {
|
|
178
|
+
return this.providerInstance;
|
|
179
|
+
}
|
|
180
|
+
async kill() {
|
|
181
|
+
await this.destroy();
|
|
182
|
+
}
|
|
183
|
+
async destroy() {
|
|
184
|
+
await this.destroyMethod(this.config, this.sandboxId);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
function getEffectiveMode(config, defaultMode) {
|
|
188
|
+
if (config.mode) {
|
|
189
|
+
return config.mode;
|
|
190
|
+
}
|
|
191
|
+
return defaultMode;
|
|
43
192
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
193
|
+
var GeneratedSandboxManager = class {
|
|
194
|
+
constructor(config, providerName, methods, providerInstance, defaultMode) {
|
|
195
|
+
this.config = config;
|
|
196
|
+
this.providerName = providerName;
|
|
197
|
+
this.methods = methods;
|
|
198
|
+
this.providerInstance = providerInstance;
|
|
199
|
+
this.effectiveMode = getEffectiveMode(config, defaultMode);
|
|
200
|
+
}
|
|
201
|
+
async create(options) {
|
|
202
|
+
const optionsWithDefaults = { runtime: "node", ...options };
|
|
203
|
+
const result = await this.methods.create(this.config, optionsWithDefaults);
|
|
204
|
+
return new GeneratedSandbox(
|
|
205
|
+
result.sandbox,
|
|
206
|
+
result.sandboxId,
|
|
207
|
+
this.providerName,
|
|
208
|
+
this.methods,
|
|
209
|
+
this.config,
|
|
210
|
+
this.methods.destroy,
|
|
211
|
+
this.providerInstance
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
async getById(sandboxId) {
|
|
215
|
+
const result = await this.methods.getById(this.config, sandboxId);
|
|
216
|
+
if (!result) {
|
|
217
|
+
return null;
|
|
61
218
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
219
|
+
return new GeneratedSandbox(
|
|
220
|
+
result.sandbox,
|
|
221
|
+
result.sandboxId,
|
|
222
|
+
this.providerName,
|
|
223
|
+
this.methods,
|
|
224
|
+
this.config,
|
|
225
|
+
this.methods.destroy,
|
|
226
|
+
this.providerInstance
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
async list() {
|
|
230
|
+
const results = await this.methods.list(this.config);
|
|
231
|
+
return results.map((result) => new GeneratedSandbox(
|
|
232
|
+
result.sandbox,
|
|
233
|
+
result.sandboxId,
|
|
234
|
+
this.providerName,
|
|
235
|
+
this.methods,
|
|
236
|
+
this.config,
|
|
237
|
+
this.methods.destroy,
|
|
238
|
+
this.providerInstance
|
|
239
|
+
));
|
|
240
|
+
}
|
|
241
|
+
async destroy(sandboxId) {
|
|
242
|
+
await this.methods.destroy(this.config, sandboxId);
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
var GeneratedTemplateManager = class {
|
|
246
|
+
constructor(config, methods) {
|
|
247
|
+
this.config = config;
|
|
248
|
+
this.methods = methods;
|
|
249
|
+
}
|
|
250
|
+
async create(options) {
|
|
251
|
+
return await this.methods.create(this.config, options);
|
|
252
|
+
}
|
|
253
|
+
async list(options) {
|
|
254
|
+
return await this.methods.list(this.config, options);
|
|
255
|
+
}
|
|
256
|
+
async delete(templateId) {
|
|
257
|
+
return await this.methods.delete(this.config, templateId);
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
var GeneratedSnapshotManager = class {
|
|
261
|
+
constructor(config, methods) {
|
|
262
|
+
this.config = config;
|
|
263
|
+
this.methods = methods;
|
|
264
|
+
}
|
|
265
|
+
async create(sandboxId, options) {
|
|
266
|
+
return await this.methods.create(this.config, sandboxId, options);
|
|
267
|
+
}
|
|
268
|
+
async list(options) {
|
|
269
|
+
return await this.methods.list(this.config, options);
|
|
270
|
+
}
|
|
271
|
+
async delete(snapshotId) {
|
|
272
|
+
return await this.methods.delete(this.config, snapshotId);
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
var GeneratedProvider = class {
|
|
276
|
+
constructor(config, providerConfig) {
|
|
277
|
+
this.name = providerConfig.name;
|
|
278
|
+
this.sandbox = new GeneratedSandboxManager(
|
|
279
|
+
config,
|
|
280
|
+
providerConfig.name,
|
|
281
|
+
providerConfig.methods.sandbox,
|
|
282
|
+
this,
|
|
283
|
+
providerConfig.defaultMode ?? "gateway"
|
|
284
|
+
);
|
|
285
|
+
if (providerConfig.methods.template) {
|
|
286
|
+
this.template = new GeneratedTemplateManager(config, providerConfig.methods.template);
|
|
65
287
|
}
|
|
66
|
-
if (
|
|
67
|
-
|
|
288
|
+
if (providerConfig.methods.snapshot) {
|
|
289
|
+
this.snapshot = new GeneratedSnapshotManager(config, providerConfig.methods.snapshot);
|
|
68
290
|
}
|
|
69
|
-
|
|
70
|
-
|
|
291
|
+
}
|
|
292
|
+
getSupportedRuntimes() {
|
|
293
|
+
return ["node", "python"];
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
function createProvider(providerConfig) {
|
|
297
|
+
return (config) => {
|
|
298
|
+
return new GeneratedProvider(config, providerConfig);
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// src/compute-daemon/lifecycle.ts
|
|
303
|
+
async function waitForComputeReady(client, options = {}) {
|
|
304
|
+
const maxRetries = options.maxRetries ?? 30;
|
|
305
|
+
const initialDelayMs = options.initialDelayMs ?? 500;
|
|
306
|
+
const maxDelayMs = options.maxDelayMs ?? 5e3;
|
|
307
|
+
const backoffFactor = options.backoffFactor ?? 1.5;
|
|
308
|
+
let lastError = null;
|
|
309
|
+
let currentDelay = initialDelayMs;
|
|
310
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
311
|
+
try {
|
|
312
|
+
await client.health();
|
|
313
|
+
if (process.env.COMPUTESDK_DEBUG) {
|
|
314
|
+
console.log(`[Lifecycle] Sandbox ready after ${i + 1} attempt${i === 0 ? "" : "s"}`);
|
|
315
|
+
}
|
|
316
|
+
return;
|
|
317
|
+
} catch (error) {
|
|
318
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
319
|
+
if (i === maxRetries - 1) {
|
|
320
|
+
throw new Error(
|
|
321
|
+
`Sandbox failed to become ready after ${maxRetries} attempts.
|
|
322
|
+
Last error: ${lastError.message}
|
|
323
|
+
|
|
324
|
+
Possible causes:
|
|
325
|
+
1. Sandbox failed to start (check provider dashboard for errors)
|
|
326
|
+
2. Network connectivity issues between your app and the sandbox
|
|
327
|
+
3. Sandbox is taking longer than expected to initialize
|
|
328
|
+
4. Invalid sandbox URL or authentication credentials
|
|
329
|
+
|
|
330
|
+
Troubleshooting:
|
|
331
|
+
- Check sandbox logs in your provider dashboard
|
|
332
|
+
- Verify your network connection
|
|
333
|
+
- Try increasing maxRetries if initialization is slow
|
|
334
|
+
- Enable debug mode: export COMPUTESDK_DEBUG=1`
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
await new Promise((resolve) => setTimeout(resolve, currentDelay));
|
|
338
|
+
currentDelay = Math.min(currentDelay * backoffFactor, maxDelayMs);
|
|
71
339
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// src/utils.ts
|
|
344
|
+
function calculateBackoff(attempt, baseDelay = 1e3, jitterMax = 100) {
|
|
345
|
+
return baseDelay * Math.pow(2, attempt) + Math.random() * jitterMax;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// src/providers/gateway.ts
|
|
349
|
+
var import_client4 = require("@computesdk/client");
|
|
350
|
+
var DEFAULT_GATEWAY_URL = "https://gateway.computesdk.com";
|
|
351
|
+
var DEFAULT_REQUEST_TIMEOUT = 3e4;
|
|
352
|
+
var DEFAULT_MAX_RETRIES = 3;
|
|
353
|
+
var DEFAULT_RETRY_DELAY = 1e3;
|
|
354
|
+
var DEFAULT_RETRYABLE_STATUSES = [408, 429, 502, 503, 504];
|
|
355
|
+
var hasWarnedAboutMissingToken = false;
|
|
356
|
+
var GatewayError = class extends Error {
|
|
357
|
+
constructor(message, statusCode, provider, sandboxId, requestId) {
|
|
358
|
+
super(message);
|
|
359
|
+
this.statusCode = statusCode;
|
|
360
|
+
this.provider = provider;
|
|
361
|
+
this.sandboxId = sandboxId;
|
|
362
|
+
this.requestId = requestId;
|
|
363
|
+
this.name = "GatewayError";
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
async function gatewayFetch(url, config, options = {}) {
|
|
367
|
+
const timeout = config.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT;
|
|
368
|
+
const maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
369
|
+
const retryDelay = config.retryDelay ?? DEFAULT_RETRY_DELAY;
|
|
370
|
+
const retryableStatuses = config.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES;
|
|
371
|
+
let lastError = null;
|
|
372
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
373
|
+
const startTime = Date.now();
|
|
374
|
+
const controller = new AbortController();
|
|
375
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
376
|
+
try {
|
|
377
|
+
const response = await fetch(url, {
|
|
378
|
+
...options,
|
|
379
|
+
signal: controller.signal,
|
|
380
|
+
headers: {
|
|
381
|
+
"Content-Type": "application/json",
|
|
382
|
+
"X-ComputeSDK-API-Key": config.apiKey,
|
|
383
|
+
"X-Provider": config.provider,
|
|
384
|
+
...config.providerHeaders || {},
|
|
385
|
+
...options.headers
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
clearTimeout(timeoutId);
|
|
389
|
+
const duration = Date.now() - startTime;
|
|
390
|
+
if (process.env.COMPUTESDK_DEBUG) {
|
|
391
|
+
console.log(`[Gateway] ${options.method || "GET"} ${url} - ${response.status} (${duration}ms)`);
|
|
392
|
+
}
|
|
393
|
+
if (!response.ok) {
|
|
394
|
+
if (response.status === 404) {
|
|
395
|
+
return { success: false };
|
|
396
|
+
}
|
|
397
|
+
const errorText = await response.text().catch(() => response.statusText);
|
|
398
|
+
const requestId = response.headers.get("x-request-id");
|
|
399
|
+
const isRetryable = retryableStatuses.includes(response.status);
|
|
400
|
+
const shouldRetry = isRetryable && attempt < maxRetries;
|
|
401
|
+
if (shouldRetry) {
|
|
402
|
+
const delay = calculateBackoff(attempt, retryDelay);
|
|
403
|
+
if (process.env.COMPUTESDK_DEBUG) {
|
|
404
|
+
console.log(`[Gateway] Retry ${attempt + 1}/${maxRetries} after ${delay.toFixed(0)}ms (status: ${response.status})...`);
|
|
405
|
+
}
|
|
406
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
let errorMessage = `Gateway API error: ${errorText}`;
|
|
410
|
+
if (response.status === 401) {
|
|
411
|
+
errorMessage = `Invalid ComputeSDK API key.
|
|
412
|
+
|
|
413
|
+
Check your COMPUTESDK_API_KEY environment variable.
|
|
414
|
+
Get your key at: https://computesdk.com/dashboard`;
|
|
415
|
+
} else if (response.status === 403) {
|
|
416
|
+
errorMessage = `Access forbidden. Your API key may not have permission to use provider "${config.provider}".
|
|
417
|
+
|
|
418
|
+
Visit https://computesdk.com/dashboard to check your plan.`;
|
|
419
|
+
} else if (response.status === 429) {
|
|
420
|
+
errorMessage = `Rate limit exceeded. Please try again in a moment.
|
|
421
|
+
|
|
422
|
+
If this persists, visit https://computesdk.com/dashboard to upgrade your plan.`;
|
|
423
|
+
} else if (response.status >= 500) {
|
|
424
|
+
errorMessage = `Gateway server error (${response.status}). This is temporary - please try again.
|
|
425
|
+
|
|
426
|
+
If this persists, check status at https://status.computesdk.com`;
|
|
427
|
+
}
|
|
428
|
+
throw new GatewayError(
|
|
429
|
+
errorMessage,
|
|
430
|
+
response.status,
|
|
431
|
+
config.provider,
|
|
432
|
+
void 0,
|
|
433
|
+
requestId || void 0
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
return response.json();
|
|
437
|
+
} catch (error) {
|
|
438
|
+
clearTimeout(timeoutId);
|
|
439
|
+
if (error instanceof GatewayError) {
|
|
440
|
+
lastError = error;
|
|
441
|
+
throw error;
|
|
442
|
+
}
|
|
443
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
444
|
+
const timeoutError = new GatewayError(
|
|
445
|
+
`Request timed out after ${timeout}ms.
|
|
446
|
+
|
|
447
|
+
The gateway may be experiencing high load or network issues.
|
|
448
|
+
Check your connection and try again.`,
|
|
449
|
+
408,
|
|
450
|
+
config.provider
|
|
451
|
+
);
|
|
452
|
+
if (attempt < maxRetries) {
|
|
453
|
+
const delay = calculateBackoff(attempt, retryDelay);
|
|
454
|
+
if (process.env.COMPUTESDK_DEBUG) {
|
|
455
|
+
console.log(`[Gateway] Retry ${attempt + 1}/${maxRetries} after ${delay.toFixed(0)}ms (timeout)...`);
|
|
456
|
+
}
|
|
457
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
458
|
+
lastError = timeoutError;
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
throw timeoutError;
|
|
462
|
+
}
|
|
463
|
+
const networkError = new GatewayError(
|
|
464
|
+
`Failed to connect to gateway: ${error instanceof Error ? error.message : String(error)}
|
|
465
|
+
|
|
466
|
+
Check your internet connection and gateway URL.`,
|
|
467
|
+
0,
|
|
468
|
+
config.provider
|
|
469
|
+
);
|
|
470
|
+
if (attempt < maxRetries) {
|
|
471
|
+
const delay = calculateBackoff(attempt, retryDelay);
|
|
472
|
+
if (process.env.COMPUTESDK_DEBUG) {
|
|
473
|
+
console.log(`[Gateway] Retry ${attempt + 1}/${maxRetries} after ${delay.toFixed(0)}ms (network error)...`);
|
|
474
|
+
}
|
|
475
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
476
|
+
lastError = networkError;
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
throw networkError;
|
|
80
480
|
}
|
|
81
|
-
throw new Error(`Failed to authorize API key (network error): ${error instanceof Error ? error.message : String(error)}`);
|
|
82
481
|
}
|
|
482
|
+
throw lastError || new Error("Max retries exceeded");
|
|
83
483
|
}
|
|
484
|
+
var gateway = createProvider({
|
|
485
|
+
name: "gateway",
|
|
486
|
+
methods: {
|
|
487
|
+
sandbox: {
|
|
488
|
+
create: async (config, options) => {
|
|
489
|
+
const gatewayUrl = config.gatewayUrl || DEFAULT_GATEWAY_URL;
|
|
490
|
+
const result = await gatewayFetch(`${gatewayUrl}/sandbox`, config, {
|
|
491
|
+
method: "POST",
|
|
492
|
+
body: JSON.stringify(options || {})
|
|
493
|
+
});
|
|
494
|
+
if (!result.success || !result.data) {
|
|
495
|
+
throw new Error(`Gateway returned invalid response: ${JSON.stringify(result)}`);
|
|
496
|
+
}
|
|
497
|
+
const { sandboxId, url, token, provider, metadata } = result.data;
|
|
498
|
+
if (process.env.COMPUTESDK_DEBUG) {
|
|
499
|
+
console.log(`[Gateway] Sandbox created:`, {
|
|
500
|
+
sandboxId,
|
|
501
|
+
url,
|
|
502
|
+
hasToken: !!token,
|
|
503
|
+
tokenPrefix: token ? token.substring(0, 10) + "..." : "none",
|
|
504
|
+
provider
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
if (!token && !hasWarnedAboutMissingToken) {
|
|
508
|
+
hasWarnedAboutMissingToken = true;
|
|
509
|
+
console.warn(
|
|
510
|
+
`[Gateway] No token received from gateway for sandbox ${sandboxId}. Falling back to API key for authentication. This may indicate the gateway is running an outdated version. Check gateway deployment at ${config.gatewayUrl || DEFAULT_GATEWAY_URL}`
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
const sandbox = new import_client3.Sandbox({
|
|
514
|
+
sandboxUrl: url,
|
|
515
|
+
sandboxId,
|
|
516
|
+
provider,
|
|
517
|
+
token: token || config.apiKey,
|
|
518
|
+
// Use token from gateway, fallback to API key
|
|
519
|
+
metadata,
|
|
520
|
+
WebSocket: globalThis.WebSocket
|
|
521
|
+
});
|
|
522
|
+
await waitForComputeReady(sandbox);
|
|
523
|
+
return { sandbox, sandboxId };
|
|
524
|
+
},
|
|
525
|
+
getById: async (config, sandboxId) => {
|
|
526
|
+
const gatewayUrl = config.gatewayUrl || DEFAULT_GATEWAY_URL;
|
|
527
|
+
const result = await gatewayFetch(`${gatewayUrl}/sandbox/${sandboxId}`, config);
|
|
528
|
+
if (!result.success || !result.data) {
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
531
|
+
const { url, token, provider, metadata } = result.data;
|
|
532
|
+
if (!token && !hasWarnedAboutMissingToken) {
|
|
533
|
+
hasWarnedAboutMissingToken = true;
|
|
534
|
+
console.warn(
|
|
535
|
+
`[Gateway] No token received when reconnecting to sandbox ${sandboxId}. Falling back to API key for authentication. This may indicate the gateway is running an outdated version.`
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
const sandbox = new import_client3.Sandbox({
|
|
539
|
+
sandboxUrl: url,
|
|
540
|
+
sandboxId,
|
|
541
|
+
provider,
|
|
542
|
+
token: token || config.apiKey,
|
|
543
|
+
// Use token from gateway, fallback to API key
|
|
544
|
+
metadata,
|
|
545
|
+
WebSocket: globalThis.WebSocket
|
|
546
|
+
});
|
|
547
|
+
await waitForComputeReady(sandbox);
|
|
548
|
+
return { sandbox, sandboxId };
|
|
549
|
+
},
|
|
550
|
+
list: async () => {
|
|
551
|
+
throw new Error(
|
|
552
|
+
"Gateway provider does not support listing sandboxes. Use getById() with a known sandbox ID instead."
|
|
553
|
+
);
|
|
554
|
+
},
|
|
555
|
+
destroy: async (config, sandboxId) => {
|
|
556
|
+
const gatewayUrl = config.gatewayUrl || DEFAULT_GATEWAY_URL;
|
|
557
|
+
await gatewayFetch(`${gatewayUrl}/sandbox/${sandboxId}`, config, {
|
|
558
|
+
method: "DELETE"
|
|
559
|
+
});
|
|
560
|
+
},
|
|
561
|
+
// All operations delegate directly to ClientSandbox
|
|
562
|
+
runCode: async (sandbox, code, runtime) => sandbox.runCode(code, runtime),
|
|
563
|
+
runCommand: async (sandbox, command, args) => sandbox.runCommand(command, args),
|
|
564
|
+
getUrl: async (sandbox, options) => sandbox.getUrl(options),
|
|
565
|
+
getInfo: async (sandbox) => {
|
|
566
|
+
const info = await sandbox.getInfo();
|
|
567
|
+
return {
|
|
568
|
+
id: info.id,
|
|
569
|
+
provider: info.provider,
|
|
570
|
+
runtime: info.runtime,
|
|
571
|
+
status: info.status,
|
|
572
|
+
createdAt: info.createdAt,
|
|
573
|
+
timeout: info.timeout,
|
|
574
|
+
metadata: info.metadata || {}
|
|
575
|
+
};
|
|
576
|
+
},
|
|
577
|
+
// Filesystem delegates directly to ClientSandbox
|
|
578
|
+
filesystem: {
|
|
579
|
+
readFile: async (sandbox, path) => sandbox.filesystem.readFile(path),
|
|
580
|
+
writeFile: async (sandbox, path, content) => sandbox.filesystem.writeFile(path, content),
|
|
581
|
+
mkdir: async (sandbox, path) => sandbox.filesystem.mkdir(path),
|
|
582
|
+
readdir: async (sandbox, path) => sandbox.filesystem.readdir(path),
|
|
583
|
+
exists: async (sandbox, path) => sandbox.filesystem.exists(path),
|
|
584
|
+
remove: async (sandbox, path) => sandbox.filesystem.remove(path)
|
|
585
|
+
},
|
|
586
|
+
// getInstance returns the ClientSandbox directly
|
|
587
|
+
getInstance: (sandbox) => sandbox
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
});
|
|
84
591
|
|
|
85
|
-
// src/
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
592
|
+
// src/auto-detect.ts
|
|
593
|
+
function isGatewayModeEnabled() {
|
|
594
|
+
return !!(typeof process !== "undefined" && process.env?.COMPUTESDK_API_KEY);
|
|
595
|
+
}
|
|
596
|
+
function hasProviderEnv(provider) {
|
|
597
|
+
if (typeof process === "undefined") return false;
|
|
598
|
+
const requiredVars = PROVIDER_ENV_VARS[provider];
|
|
599
|
+
if (!requiredVars) return false;
|
|
600
|
+
return requiredVars.every((varName) => !!process.env?.[varName]);
|
|
89
601
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
602
|
+
function getProviderEnvStatus(provider) {
|
|
603
|
+
const requiredVars = PROVIDER_ENV_VARS[provider];
|
|
604
|
+
if (typeof process === "undefined" || !requiredVars) {
|
|
605
|
+
return { provider, present: [], missing: requiredVars ? [...requiredVars] : [], isComplete: false };
|
|
93
606
|
}
|
|
94
|
-
|
|
95
|
-
|
|
607
|
+
const present = requiredVars.filter((varName) => !!process.env?.[varName]);
|
|
608
|
+
const missing = requiredVars.filter((varName) => !process.env?.[varName]);
|
|
609
|
+
return {
|
|
610
|
+
provider,
|
|
611
|
+
present: [...present],
|
|
612
|
+
missing: [...missing],
|
|
613
|
+
isComplete: missing.length === 0
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
function detectProvider() {
|
|
617
|
+
if (typeof process === "undefined") return null;
|
|
618
|
+
const explicit = process.env.COMPUTESDK_PROVIDER?.toLowerCase();
|
|
619
|
+
if (explicit && hasProviderEnv(explicit)) {
|
|
620
|
+
return explicit;
|
|
621
|
+
}
|
|
622
|
+
if (explicit && !hasProviderEnv(explicit)) {
|
|
623
|
+
console.warn(
|
|
624
|
+
`\u26A0\uFE0F COMPUTESDK_PROVIDER is set to "${explicit}" but required credentials are missing.
|
|
625
|
+
Required: ${PROVIDER_ENV_VARS[explicit]?.join(", ") || "unknown"}
|
|
626
|
+
Falling back to auto-detection...`
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
for (const provider of PROVIDER_PRIORITY) {
|
|
630
|
+
if (hasProviderEnv(provider)) {
|
|
631
|
+
return provider;
|
|
632
|
+
}
|
|
96
633
|
}
|
|
97
634
|
return null;
|
|
98
635
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
636
|
+
function getProviderHeaders(provider) {
|
|
637
|
+
if (typeof process === "undefined") return {};
|
|
638
|
+
const headers = {};
|
|
639
|
+
switch (provider) {
|
|
640
|
+
case "e2b":
|
|
641
|
+
if (process.env.E2B_API_KEY) {
|
|
642
|
+
headers["X-E2B-API-Key"] = process.env.E2B_API_KEY;
|
|
643
|
+
}
|
|
644
|
+
break;
|
|
645
|
+
case "railway":
|
|
646
|
+
if (process.env.RAILWAY_API_KEY) {
|
|
647
|
+
headers["X-Railway-API-Key"] = process.env.RAILWAY_API_KEY;
|
|
648
|
+
}
|
|
649
|
+
if (process.env.RAILWAY_PROJECT_ID) {
|
|
650
|
+
headers["X-Railway-Project-ID"] = process.env.RAILWAY_PROJECT_ID;
|
|
651
|
+
}
|
|
652
|
+
if (process.env.RAILWAY_ENVIRONMENT_ID) {
|
|
653
|
+
headers["X-Railway-Environment-ID"] = process.env.RAILWAY_ENVIRONMENT_ID;
|
|
654
|
+
}
|
|
655
|
+
break;
|
|
656
|
+
case "daytona":
|
|
657
|
+
if (process.env.DAYTONA_API_KEY) {
|
|
658
|
+
headers["X-Daytona-API-Key"] = process.env.DAYTONA_API_KEY;
|
|
659
|
+
}
|
|
660
|
+
break;
|
|
661
|
+
case "modal":
|
|
662
|
+
if (process.env.MODAL_TOKEN_ID) {
|
|
663
|
+
headers["X-Modal-Token-ID"] = process.env.MODAL_TOKEN_ID;
|
|
664
|
+
}
|
|
665
|
+
if (process.env.MODAL_TOKEN_SECRET) {
|
|
666
|
+
headers["X-Modal-Token-Secret"] = process.env.MODAL_TOKEN_SECRET;
|
|
667
|
+
}
|
|
668
|
+
break;
|
|
669
|
+
case "runloop":
|
|
670
|
+
if (process.env.RUNLOOP_API_KEY) {
|
|
671
|
+
headers["X-Runloop-API-Key"] = process.env.RUNLOOP_API_KEY;
|
|
672
|
+
}
|
|
673
|
+
break;
|
|
674
|
+
case "vercel":
|
|
675
|
+
if (process.env.VERCEL_TOKEN) {
|
|
676
|
+
headers["X-Vercel-Token"] = process.env.VERCEL_TOKEN;
|
|
677
|
+
}
|
|
678
|
+
if (process.env.VERCEL_TEAM_ID) {
|
|
679
|
+
headers["X-Vercel-Team-ID"] = process.env.VERCEL_TEAM_ID;
|
|
680
|
+
}
|
|
681
|
+
if (process.env.VERCEL_PROJECT_ID) {
|
|
682
|
+
headers["X-Vercel-Project-ID"] = process.env.VERCEL_PROJECT_ID;
|
|
683
|
+
}
|
|
684
|
+
break;
|
|
685
|
+
case "cloudflare":
|
|
686
|
+
if (process.env.CLOUDFLARE_API_TOKEN) {
|
|
687
|
+
headers["X-Cloudflare-API-Token"] = process.env.CLOUDFLARE_API_TOKEN;
|
|
688
|
+
}
|
|
689
|
+
if (process.env.CLOUDFLARE_ACCOUNT_ID) {
|
|
690
|
+
headers["X-Cloudflare-Account-ID"] = process.env.CLOUDFLARE_ACCOUNT_ID;
|
|
691
|
+
}
|
|
692
|
+
break;
|
|
693
|
+
case "codesandbox":
|
|
694
|
+
if (process.env.CSB_API_KEY) {
|
|
695
|
+
headers["X-CodeSandbox-API-Key"] = process.env.CSB_API_KEY;
|
|
696
|
+
}
|
|
697
|
+
break;
|
|
698
|
+
case "blaxel":
|
|
699
|
+
if (process.env.BL_API_KEY) {
|
|
700
|
+
headers["X-Blaxel-API-Key"] = process.env.BL_API_KEY;
|
|
701
|
+
}
|
|
702
|
+
if (process.env.BL_WORKSPACE) {
|
|
703
|
+
headers["X-Blaxel-Workspace"] = process.env.BL_WORKSPACE;
|
|
704
|
+
}
|
|
705
|
+
break;
|
|
112
706
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
707
|
+
return headers;
|
|
708
|
+
}
|
|
709
|
+
function autoConfigureCompute() {
|
|
710
|
+
if (!isGatewayModeEnabled()) {
|
|
711
|
+
return null;
|
|
118
712
|
}
|
|
119
|
-
|
|
713
|
+
const provider = detectProvider();
|
|
714
|
+
if (!provider) {
|
|
715
|
+
const detectionResults = PROVIDER_PRIORITY.map((p) => getProviderEnvStatus(p));
|
|
716
|
+
const statusLines = detectionResults.map((result) => {
|
|
717
|
+
const status = result.isComplete ? "\u2705" : result.present.length > 0 ? "\u26A0\uFE0F " : "\u274C";
|
|
718
|
+
const ratio = `${result.present.length}/${result.present.length + result.missing.length}`;
|
|
719
|
+
let line = ` ${status} ${result.provider.padEnd(12)} ${ratio} credentials`;
|
|
720
|
+
if (result.present.length > 0 && result.missing.length > 0) {
|
|
721
|
+
line += ` (missing: ${result.missing.join(", ")})`;
|
|
722
|
+
}
|
|
723
|
+
return line;
|
|
724
|
+
});
|
|
120
725
|
throw new Error(
|
|
121
|
-
`
|
|
122
|
-
|
|
123
|
-
|
|
726
|
+
`COMPUTESDK_API_KEY is set but no provider detected.
|
|
727
|
+
|
|
728
|
+
Provider detection results:
|
|
729
|
+
` + statusLines.join("\n") + `
|
|
730
|
+
|
|
731
|
+
To fix this, set one of the following:
|
|
732
|
+
|
|
733
|
+
E2B: export E2B_API_KEY=xxx
|
|
734
|
+
Railway: export RAILWAY_API_KEY=xxx RAILWAY_PROJECT_ID=xxx RAILWAY_ENVIRONMENT_ID=xxx
|
|
735
|
+
Daytona: export DAYTONA_API_KEY=xxx
|
|
736
|
+
Modal: export MODAL_TOKEN_ID=xxx MODAL_TOKEN_SECRET=xxx
|
|
737
|
+
Runloop: export RUNLOOP_API_KEY=xxx
|
|
738
|
+
Vercel: export VERCEL_TOKEN=xxx VERCEL_TEAM_ID=xxx VERCEL_PROJECT_ID=xxx
|
|
739
|
+
Cloudflare: export CLOUDFLARE_API_TOKEN=xxx CLOUDFLARE_ACCOUNT_ID=xxx
|
|
740
|
+
CodeSandbox: export CSB_API_KEY=xxx
|
|
741
|
+
Blaxel: export BL_API_KEY=xxx BL_WORKSPACE=xxx
|
|
742
|
+
|
|
743
|
+
Or set COMPUTESDK_PROVIDER to specify explicitly:
|
|
744
|
+
export COMPUTESDK_PROVIDER=e2b
|
|
745
|
+
|
|
746
|
+
Docs: https://computesdk.com/docs/quickstart`
|
|
124
747
|
);
|
|
125
748
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
async function downloadInstallScript(sandbox) {
|
|
134
|
-
const downloadResult = await sandbox.runCommand("sh", ["-c", "curl -fsSL https://computesdk.com/install.sh -o /tmp/compute-install.sh 2>&1"]);
|
|
135
|
-
if (downloadResult.exitCode !== 0) {
|
|
136
|
-
const errorOutput = downloadResult.stderr || downloadResult.stdout || "unknown error";
|
|
749
|
+
const gatewayUrl = process.env.COMPUTESDK_GATEWAY_URL || GATEWAY_URL;
|
|
750
|
+
const computesdkApiKey = process.env.COMPUTESDK_API_KEY;
|
|
751
|
+
const providerHeaders = getProviderHeaders(provider);
|
|
752
|
+
try {
|
|
753
|
+
new URL(gatewayUrl);
|
|
754
|
+
} catch (error) {
|
|
137
755
|
throw new Error(
|
|
138
|
-
`
|
|
756
|
+
`Invalid gateway URL: "${gatewayUrl}"
|
|
757
|
+
|
|
758
|
+
The URL must be a valid HTTP/HTTPS URL.
|
|
759
|
+
Check your COMPUTESDK_GATEWAY_URL environment variable.`
|
|
139
760
|
);
|
|
140
761
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (installResult.exitCode !== 0) {
|
|
146
|
-
const errorOutput = installResult.stderr || installResult.stdout || "unknown error";
|
|
147
|
-
throw new Error(`Failed to install compute daemon: ${errorOutput}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
async function installComputeDaemon(sandbox, accessToken) {
|
|
151
|
-
if (await isComputeInstalled(sandbox)) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
await ensureDependencies(sandbox);
|
|
155
|
-
await downloadInstallScript(sandbox);
|
|
156
|
-
await runInstallScript(sandbox, accessToken);
|
|
157
|
-
if (!await isComputeInstalled(sandbox)) {
|
|
158
|
-
throw new Error("Compute binary not found at /usr/local/bin/compute after installation");
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// src/sandbox/wrapper.ts
|
|
163
|
-
var import_client = require("@computesdk/client");
|
|
164
|
-
|
|
165
|
-
// src/compute-daemon/lifecycle.ts
|
|
166
|
-
async function waitForComputeReady(client, maxRetries = 30, delayMs = 2e3) {
|
|
167
|
-
let lastError = null;
|
|
168
|
-
for (let i = 0; i < maxRetries; i++) {
|
|
169
|
-
try {
|
|
170
|
-
await client.health();
|
|
171
|
-
return;
|
|
172
|
-
} catch (error) {
|
|
173
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
174
|
-
if (i === maxRetries - 1) {
|
|
175
|
-
throw new Error(
|
|
176
|
-
`Compute daemon failed to start after ${maxRetries} attempts (${maxRetries * delayMs / 1e3}s).
|
|
177
|
-
Last error: ${lastError.message}
|
|
178
|
-
This could indicate:
|
|
179
|
-
1. The compute daemon failed to start in the sandbox
|
|
180
|
-
2. The sandbox_url is incorrect or unreachable
|
|
181
|
-
3. The sandbox is taking longer than expected to initialize`
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
185
|
-
}
|
|
762
|
+
if (process.env.COMPUTESDK_DEBUG) {
|
|
763
|
+
console.log(`\u2728 ComputeSDK: Auto-detected ${provider} provider`);
|
|
764
|
+
console.log(`\u{1F310} Gateway: ${gatewayUrl}`);
|
|
765
|
+
console.log(`\u{1F511} Provider headers:`, Object.keys(providerHeaders).join(", "));
|
|
186
766
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
sandboxUrl: authResponse.sandbox_url,
|
|
193
|
-
sandboxId: originalSandbox.sandboxId,
|
|
194
|
-
provider: originalSandbox.provider,
|
|
195
|
-
token: authResponse.access_token,
|
|
196
|
-
WebSocket: globalThis.WebSocket
|
|
197
|
-
});
|
|
198
|
-
await waitForComputeReady(client);
|
|
199
|
-
const wrappedSandbox = Object.assign(client, {
|
|
200
|
-
__originalSandbox: originalSandbox,
|
|
201
|
-
// Override getInstance to return the original provider's instance
|
|
202
|
-
getInstance: () => originalSandbox.getInstance(),
|
|
203
|
-
// Override getProvider to return the original provider
|
|
204
|
-
getProvider: () => originalSandbox.getProvider()
|
|
767
|
+
return gateway({
|
|
768
|
+
gatewayUrl,
|
|
769
|
+
apiKey: computesdkApiKey,
|
|
770
|
+
provider,
|
|
771
|
+
providerHeaders
|
|
205
772
|
});
|
|
206
|
-
return wrappedSandbox;
|
|
207
773
|
}
|
|
208
774
|
|
|
209
775
|
// src/compute.ts
|
|
210
776
|
var ComputeManager = class {
|
|
211
777
|
constructor() {
|
|
212
778
|
this.config = null;
|
|
213
|
-
this.
|
|
779
|
+
this.autoConfigured = false;
|
|
214
780
|
this.sandbox = {
|
|
215
781
|
/**
|
|
216
782
|
* Create a sandbox from a provider (or default provider if configured)
|
|
217
|
-
*
|
|
783
|
+
*
|
|
218
784
|
* @example
|
|
219
785
|
* ```typescript
|
|
220
786
|
* import { e2b } from '@computesdk/e2b'
|
|
221
787
|
* import { compute } from 'computesdk'
|
|
222
|
-
*
|
|
788
|
+
*
|
|
223
789
|
* // With explicit provider
|
|
224
790
|
* const sandbox = await compute.sandbox.create({
|
|
225
791
|
* provider: e2b({ apiKey: 'your-key' })
|
|
226
792
|
* })
|
|
227
|
-
*
|
|
228
|
-
* // With default provider
|
|
793
|
+
*
|
|
794
|
+
* // With default provider
|
|
229
795
|
* compute.setConfig({ defaultProvider: e2b({ apiKey: 'your-key' }) })
|
|
230
|
-
* const
|
|
231
|
-
* const sandbox2 = await compute.sandbox.create()
|
|
796
|
+
* const sandbox = await compute.sandbox.create()
|
|
232
797
|
* ```
|
|
233
798
|
*/
|
|
234
799
|
create: async (params) => {
|
|
235
800
|
const provider = params && "provider" in params && params.provider ? params.provider : this.getDefaultProvider();
|
|
236
801
|
const options = params?.options;
|
|
237
|
-
|
|
238
|
-
if (this.computeAuth.apiKey || this.computeAuth.accessToken) {
|
|
239
|
-
let authResponse = null;
|
|
240
|
-
let accessToken = this.computeAuth.accessToken;
|
|
241
|
-
if (this.computeAuth.apiKey && !accessToken) {
|
|
242
|
-
authResponse = await authorizeApiKey(this.computeAuth.apiKey);
|
|
243
|
-
accessToken = authResponse.access_token;
|
|
244
|
-
}
|
|
245
|
-
await installComputeDaemon(sandbox, accessToken);
|
|
246
|
-
if (authResponse) {
|
|
247
|
-
return await wrapWithComputeClient(sandbox, authResponse);
|
|
248
|
-
} else if (accessToken) {
|
|
249
|
-
const defaultAuthResponse = {
|
|
250
|
-
access_token: accessToken,
|
|
251
|
-
sandbox_url: "https://sandbox.computesdk.com",
|
|
252
|
-
preview_url: "https://preview.computesdk.com"
|
|
253
|
-
};
|
|
254
|
-
return await wrapWithComputeClient(sandbox, defaultAuthResponse);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return sandbox;
|
|
802
|
+
return await provider.sandbox.create(options);
|
|
258
803
|
},
|
|
259
804
|
/**
|
|
260
805
|
* Get an existing sandbox by ID from a provider (or default provider if configured)
|
|
@@ -304,16 +849,9 @@ var ComputeManager = class {
|
|
|
304
849
|
console.warn("Both defaultProvider and provider specified in setConfig. Using defaultProvider. The provider key is deprecated, please use defaultProvider instead.");
|
|
305
850
|
}
|
|
306
851
|
const actualProvider = config.defaultProvider || config.provider;
|
|
307
|
-
const accessToken = config.accessToken || config.jwt;
|
|
308
852
|
this.config = {
|
|
309
853
|
provider: actualProvider,
|
|
310
|
-
defaultProvider: actualProvider
|
|
311
|
-
apiKey: config.apiKey,
|
|
312
|
-
accessToken
|
|
313
|
-
};
|
|
314
|
-
this.computeAuth = {
|
|
315
|
-
apiKey: config.apiKey,
|
|
316
|
-
accessToken
|
|
854
|
+
defaultProvider: actualProvider
|
|
317
855
|
};
|
|
318
856
|
}
|
|
319
857
|
/**
|
|
@@ -328,39 +866,46 @@ var ComputeManager = class {
|
|
|
328
866
|
clearConfig() {
|
|
329
867
|
this.config = null;
|
|
330
868
|
}
|
|
869
|
+
/**
|
|
870
|
+
* Lazy auto-configure from environment if not explicitly configured
|
|
871
|
+
*/
|
|
872
|
+
ensureConfigured() {
|
|
873
|
+
if (this.config) return;
|
|
874
|
+
if (this.autoConfigured) return;
|
|
875
|
+
const provider = autoConfigureCompute();
|
|
876
|
+
this.autoConfigured = true;
|
|
877
|
+
if (provider) {
|
|
878
|
+
this.config = {
|
|
879
|
+
provider,
|
|
880
|
+
defaultProvider: provider
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
}
|
|
331
884
|
/**
|
|
332
885
|
* Get the default provider, throwing if not configured
|
|
333
886
|
*/
|
|
334
887
|
getDefaultProvider() {
|
|
888
|
+
this.ensureConfigured();
|
|
335
889
|
const provider = this.config?.defaultProvider || this.config?.provider;
|
|
336
890
|
if (!provider) {
|
|
337
891
|
throw new Error(
|
|
338
|
-
"No default provider configured.
|
|
892
|
+
"No default provider configured.\n\nOptions:\n1. Zero-config mode: Set COMPUTESDK_API_KEY and provider credentials (e.g., E2B_API_KEY)\n2. Explicit mode: Call compute.setConfig({ defaultProvider }) or pass provider to create()\n\nDocs: https://computesdk.com/docs/quickstart"
|
|
339
893
|
);
|
|
340
894
|
}
|
|
341
895
|
return provider;
|
|
342
896
|
}
|
|
343
|
-
// Future: compute.blob.*, compute.database.*, compute.git.* will be added here
|
|
344
|
-
// blob = new BlobManager();
|
|
345
|
-
// database = new DatabaseManager();
|
|
346
|
-
// git = new GitManager();
|
|
347
897
|
};
|
|
348
898
|
var compute = new ComputeManager();
|
|
349
899
|
function createCompute(config) {
|
|
350
900
|
const manager = new ComputeManager();
|
|
901
|
+
if (!config) {
|
|
902
|
+
return manager;
|
|
903
|
+
}
|
|
351
904
|
const actualProvider = config.defaultProvider || config.provider;
|
|
352
|
-
const accessToken = config.accessToken || config.jwt;
|
|
353
905
|
manager["config"] = {
|
|
354
906
|
provider: actualProvider,
|
|
355
|
-
defaultProvider: actualProvider
|
|
356
|
-
apiKey: config.apiKey,
|
|
357
|
-
accessToken
|
|
907
|
+
defaultProvider: actualProvider
|
|
358
908
|
};
|
|
359
|
-
manager["computeAuth"] = {
|
|
360
|
-
apiKey: config.apiKey,
|
|
361
|
-
accessToken
|
|
362
|
-
};
|
|
363
|
-
const isEnhanced = !!(config.apiKey || config.accessToken || config.jwt);
|
|
364
909
|
return {
|
|
365
910
|
setConfig: (cfg) => createCompute(cfg),
|
|
366
911
|
getConfig: () => manager.getConfig(),
|
|
@@ -368,24 +913,15 @@ function createCompute(config) {
|
|
|
368
913
|
sandbox: {
|
|
369
914
|
create: async (params) => {
|
|
370
915
|
const sandbox = await manager.sandbox.create(params);
|
|
371
|
-
if (isEnhanced) {
|
|
372
|
-
return sandbox;
|
|
373
|
-
}
|
|
374
916
|
return sandbox;
|
|
375
917
|
},
|
|
376
918
|
getById: async (sandboxId) => {
|
|
377
919
|
const sandbox = await manager.sandbox.getById(sandboxId);
|
|
378
920
|
if (!sandbox) return null;
|
|
379
|
-
if (isEnhanced) {
|
|
380
|
-
return sandbox;
|
|
381
|
-
}
|
|
382
921
|
return sandbox;
|
|
383
922
|
},
|
|
384
923
|
list: async () => {
|
|
385
924
|
const sandboxes = await manager.sandbox.list();
|
|
386
|
-
if (isEnhanced) {
|
|
387
|
-
return sandboxes;
|
|
388
|
-
}
|
|
389
925
|
return sandboxes;
|
|
390
926
|
},
|
|
391
927
|
destroy: async (sandboxId) => {
|
|
@@ -465,10 +1001,9 @@ async function executeAction(body, provider) {
|
|
|
465
1001
|
sandboxId,
|
|
466
1002
|
provider: provider.name,
|
|
467
1003
|
result: {
|
|
468
|
-
|
|
469
|
-
stderr: result.stderr,
|
|
1004
|
+
output: result.output,
|
|
470
1005
|
exitCode: result.exitCode,
|
|
471
|
-
|
|
1006
|
+
language: result.language
|
|
472
1007
|
}
|
|
473
1008
|
};
|
|
474
1009
|
}
|
|
@@ -483,9 +1018,7 @@ async function executeAction(body, provider) {
|
|
|
483
1018
|
stdout: result.stdout,
|
|
484
1019
|
stderr: result.stderr,
|
|
485
1020
|
exitCode: result.exitCode,
|
|
486
|
-
|
|
487
|
-
...result.isBackground && { isBackground: result.isBackground },
|
|
488
|
-
...result.pid && { pid: result.pid }
|
|
1021
|
+
durationMs: result.durationMs
|
|
489
1022
|
}
|
|
490
1023
|
};
|
|
491
1024
|
}
|
|
@@ -597,254 +1130,23 @@ async function handleComputeRequest(paramsOrRequestOrBody, provider) {
|
|
|
597
1130
|
}, { status: 500 });
|
|
598
1131
|
}
|
|
599
1132
|
}
|
|
600
|
-
|
|
601
|
-
// src/factory.ts
|
|
602
|
-
function createBackgroundCommand(command, args = [], options) {
|
|
603
|
-
if (!options?.background) {
|
|
604
|
-
return { command, args, isBackground: false };
|
|
605
|
-
}
|
|
606
|
-
const fullCommand = args.length > 0 ? `${command} ${args.join(" ")}` : command;
|
|
607
|
-
return {
|
|
608
|
-
command: "sh",
|
|
609
|
-
args: ["-c", `nohup ${fullCommand} > /dev/null 2>&1 &`],
|
|
610
|
-
isBackground: true
|
|
611
|
-
};
|
|
612
|
-
}
|
|
613
|
-
var UnsupportedFileSystem = class {
|
|
614
|
-
constructor(providerName) {
|
|
615
|
-
this.providerName = providerName;
|
|
616
|
-
}
|
|
617
|
-
async readFile(_path) {
|
|
618
|
-
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
619
|
-
}
|
|
620
|
-
async writeFile(_path, _content) {
|
|
621
|
-
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
622
|
-
}
|
|
623
|
-
async mkdir(_path) {
|
|
624
|
-
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
625
|
-
}
|
|
626
|
-
async readdir(_path) {
|
|
627
|
-
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
628
|
-
}
|
|
629
|
-
async exists(_path) {
|
|
630
|
-
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
631
|
-
}
|
|
632
|
-
async remove(_path) {
|
|
633
|
-
throw new Error(`Filesystem operations are not supported by ${this.providerName}'s sandbox environment. ${this.providerName} sandboxes are designed for code execution only.`);
|
|
634
|
-
}
|
|
635
|
-
};
|
|
636
|
-
var SupportedFileSystem = class {
|
|
637
|
-
constructor(sandbox, methods, allMethods) {
|
|
638
|
-
this.sandbox = sandbox;
|
|
639
|
-
this.methods = methods;
|
|
640
|
-
this.allMethods = allMethods;
|
|
641
|
-
}
|
|
642
|
-
async readFile(path) {
|
|
643
|
-
return this.methods.readFile(this.sandbox, path, this.allMethods.runCommand);
|
|
644
|
-
}
|
|
645
|
-
async writeFile(path, content) {
|
|
646
|
-
return this.methods.writeFile(this.sandbox, path, content, this.allMethods.runCommand);
|
|
647
|
-
}
|
|
648
|
-
async mkdir(path) {
|
|
649
|
-
return this.methods.mkdir(this.sandbox, path, this.allMethods.runCommand);
|
|
650
|
-
}
|
|
651
|
-
async readdir(path) {
|
|
652
|
-
return this.methods.readdir(this.sandbox, path, this.allMethods.runCommand);
|
|
653
|
-
}
|
|
654
|
-
async exists(path) {
|
|
655
|
-
return this.methods.exists(this.sandbox, path, this.allMethods.runCommand);
|
|
656
|
-
}
|
|
657
|
-
async remove(path) {
|
|
658
|
-
return this.methods.remove(this.sandbox, path, this.allMethods.runCommand);
|
|
659
|
-
}
|
|
660
|
-
};
|
|
661
|
-
var GeneratedSandbox = class {
|
|
662
|
-
constructor(sandbox, sandboxId, providerName, methods, config, destroyMethod, providerInstance) {
|
|
663
|
-
this.sandbox = sandbox;
|
|
664
|
-
this.methods = methods;
|
|
665
|
-
this.config = config;
|
|
666
|
-
this.destroyMethod = destroyMethod;
|
|
667
|
-
this.providerInstance = providerInstance;
|
|
668
|
-
this.sandboxId = sandboxId;
|
|
669
|
-
this.provider = providerName;
|
|
670
|
-
if (methods.filesystem) {
|
|
671
|
-
this.filesystem = new SupportedFileSystem(sandbox, methods.filesystem, methods);
|
|
672
|
-
} else {
|
|
673
|
-
this.filesystem = new UnsupportedFileSystem(providerName);
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
getInstance() {
|
|
677
|
-
if (this.methods.getInstance) {
|
|
678
|
-
return this.methods.getInstance(this.sandbox);
|
|
679
|
-
}
|
|
680
|
-
return this.sandbox;
|
|
681
|
-
}
|
|
682
|
-
async runCode(code, runtime) {
|
|
683
|
-
return await this.methods.runCode(this.sandbox, code, runtime, this.config);
|
|
684
|
-
}
|
|
685
|
-
async runCommand(command, args, options) {
|
|
686
|
-
if (options?.background) {
|
|
687
|
-
const fullCommand = args?.length ? `${command} ${args.join(" ")}` : command;
|
|
688
|
-
const bgCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
689
|
-
const result = await this.methods.runCommand(this.sandbox, "sh", ["-c", bgCommand], void 0);
|
|
690
|
-
return {
|
|
691
|
-
...result,
|
|
692
|
-
isBackground: true,
|
|
693
|
-
pid: -1
|
|
694
|
-
};
|
|
695
|
-
}
|
|
696
|
-
return await this.methods.runCommand(this.sandbox, command, args, options);
|
|
697
|
-
}
|
|
698
|
-
async getInfo() {
|
|
699
|
-
return await this.methods.getInfo(this.sandbox);
|
|
700
|
-
}
|
|
701
|
-
async getUrl(options) {
|
|
702
|
-
return await this.methods.getUrl(this.sandbox, options);
|
|
703
|
-
}
|
|
704
|
-
getProvider() {
|
|
705
|
-
return this.providerInstance;
|
|
706
|
-
}
|
|
707
|
-
async kill() {
|
|
708
|
-
await this.destroy();
|
|
709
|
-
}
|
|
710
|
-
async destroy() {
|
|
711
|
-
await this.destroyMethod(this.config, this.sandboxId);
|
|
712
|
-
}
|
|
713
|
-
};
|
|
714
|
-
var GeneratedSandboxManager = class {
|
|
715
|
-
constructor(config, providerName, methods, providerInstance) {
|
|
716
|
-
this.config = config;
|
|
717
|
-
this.providerName = providerName;
|
|
718
|
-
this.methods = methods;
|
|
719
|
-
this.providerInstance = providerInstance;
|
|
720
|
-
this.activeSandboxes = /* @__PURE__ */ new Map();
|
|
721
|
-
}
|
|
722
|
-
async create(options) {
|
|
723
|
-
const optionsWithDefaults = { runtime: "node", ...options };
|
|
724
|
-
const result = await this.methods.create(this.config, optionsWithDefaults);
|
|
725
|
-
const sandbox = new GeneratedSandbox(
|
|
726
|
-
result.sandbox,
|
|
727
|
-
result.sandboxId,
|
|
728
|
-
this.providerName,
|
|
729
|
-
this.methods,
|
|
730
|
-
this.config,
|
|
731
|
-
this.methods.destroy,
|
|
732
|
-
this.providerInstance
|
|
733
|
-
);
|
|
734
|
-
this.activeSandboxes.set(result.sandboxId, sandbox);
|
|
735
|
-
return sandbox;
|
|
736
|
-
}
|
|
737
|
-
async getById(sandboxId) {
|
|
738
|
-
const existing = this.activeSandboxes.get(sandboxId);
|
|
739
|
-
if (existing) {
|
|
740
|
-
return existing;
|
|
741
|
-
}
|
|
742
|
-
const result = await this.methods.getById(this.config, sandboxId);
|
|
743
|
-
if (!result) {
|
|
744
|
-
return null;
|
|
745
|
-
}
|
|
746
|
-
const sandbox = new GeneratedSandbox(
|
|
747
|
-
result.sandbox,
|
|
748
|
-
result.sandboxId,
|
|
749
|
-
this.providerName,
|
|
750
|
-
this.methods,
|
|
751
|
-
this.config,
|
|
752
|
-
this.methods.destroy,
|
|
753
|
-
this.providerInstance
|
|
754
|
-
);
|
|
755
|
-
this.activeSandboxes.set(result.sandboxId, sandbox);
|
|
756
|
-
return sandbox;
|
|
757
|
-
}
|
|
758
|
-
async list() {
|
|
759
|
-
const results = await this.methods.list(this.config);
|
|
760
|
-
const sandboxes = [];
|
|
761
|
-
for (const result of results) {
|
|
762
|
-
let sandbox = this.activeSandboxes.get(result.sandboxId);
|
|
763
|
-
if (!sandbox) {
|
|
764
|
-
sandbox = new GeneratedSandbox(
|
|
765
|
-
result.sandbox,
|
|
766
|
-
result.sandboxId,
|
|
767
|
-
this.providerName,
|
|
768
|
-
this.methods,
|
|
769
|
-
this.config,
|
|
770
|
-
this.methods.destroy,
|
|
771
|
-
this.providerInstance
|
|
772
|
-
);
|
|
773
|
-
this.activeSandboxes.set(result.sandboxId, sandbox);
|
|
774
|
-
}
|
|
775
|
-
sandboxes.push(sandbox);
|
|
776
|
-
}
|
|
777
|
-
return sandboxes;
|
|
778
|
-
}
|
|
779
|
-
async destroy(sandboxId) {
|
|
780
|
-
await this.methods.destroy(this.config, sandboxId);
|
|
781
|
-
this.activeSandboxes.delete(sandboxId);
|
|
782
|
-
}
|
|
783
|
-
};
|
|
784
|
-
var GeneratedTemplateManager = class {
|
|
785
|
-
constructor(config, methods) {
|
|
786
|
-
this.config = config;
|
|
787
|
-
this.methods = methods;
|
|
788
|
-
}
|
|
789
|
-
async create(options) {
|
|
790
|
-
return await this.methods.create(this.config, options);
|
|
791
|
-
}
|
|
792
|
-
async list(options) {
|
|
793
|
-
return await this.methods.list(this.config, options);
|
|
794
|
-
}
|
|
795
|
-
async delete(templateId) {
|
|
796
|
-
return await this.methods.delete(this.config, templateId);
|
|
797
|
-
}
|
|
798
|
-
};
|
|
799
|
-
var GeneratedSnapshotManager = class {
|
|
800
|
-
constructor(config, methods) {
|
|
801
|
-
this.config = config;
|
|
802
|
-
this.methods = methods;
|
|
803
|
-
}
|
|
804
|
-
async create(sandboxId, options) {
|
|
805
|
-
return await this.methods.create(this.config, sandboxId, options);
|
|
806
|
-
}
|
|
807
|
-
async list(options) {
|
|
808
|
-
return await this.methods.list(this.config, options);
|
|
809
|
-
}
|
|
810
|
-
async delete(snapshotId) {
|
|
811
|
-
return await this.methods.delete(this.config, snapshotId);
|
|
812
|
-
}
|
|
813
|
-
};
|
|
814
|
-
var GeneratedProvider = class {
|
|
815
|
-
// Phantom type for TypeScript inference
|
|
816
|
-
constructor(config, providerConfig) {
|
|
817
|
-
this.name = providerConfig.name;
|
|
818
|
-
this.sandbox = new GeneratedSandboxManager(
|
|
819
|
-
config,
|
|
820
|
-
providerConfig.name,
|
|
821
|
-
providerConfig.methods.sandbox,
|
|
822
|
-
this
|
|
823
|
-
);
|
|
824
|
-
if (providerConfig.methods.template) {
|
|
825
|
-
this.template = new GeneratedTemplateManager(config, providerConfig.methods.template);
|
|
826
|
-
}
|
|
827
|
-
if (providerConfig.methods.snapshot) {
|
|
828
|
-
this.snapshot = new GeneratedSnapshotManager(config, providerConfig.methods.snapshot);
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
getSupportedRuntimes() {
|
|
832
|
-
return ["node", "python"];
|
|
833
|
-
}
|
|
834
|
-
};
|
|
835
|
-
function createProvider(providerConfig) {
|
|
836
|
-
return (config) => {
|
|
837
|
-
return new GeneratedProvider(config, providerConfig);
|
|
838
|
-
};
|
|
839
|
-
}
|
|
840
1133
|
// Annotate the CommonJS export names for ESM import in node:
|
|
841
1134
|
0 && (module.exports = {
|
|
842
1135
|
CommandExitError,
|
|
1136
|
+
GATEWAY_URL,
|
|
1137
|
+
PROVIDER_ENV_VARS,
|
|
1138
|
+
PROVIDER_PRIORITY,
|
|
1139
|
+
Sandbox,
|
|
1140
|
+
autoConfigureCompute,
|
|
1141
|
+
calculateBackoff,
|
|
843
1142
|
compute,
|
|
844
|
-
createBackgroundCommand,
|
|
845
1143
|
createCompute,
|
|
846
1144
|
createProvider,
|
|
1145
|
+
detectProvider,
|
|
1146
|
+
gateway,
|
|
1147
|
+
getProviderHeaders,
|
|
847
1148
|
handleComputeRequest,
|
|
848
|
-
isCommandExitError
|
|
1149
|
+
isCommandExitError,
|
|
1150
|
+
isGatewayModeEnabled
|
|
849
1151
|
});
|
|
850
1152
|
//# sourceMappingURL=index.js.map
|