ppio-sandbox 2.0.0-a2 → 2.0.2-a1
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 +1 -1
- package/dist/{chunk-P33RTZCB.mjs → chunk-V2Q62RZL.mjs} +1133 -374
- package/dist/chunk-V2Q62RZL.mjs.map +1 -0
- package/dist/code-interpreter.d.mts +2 -2
- package/dist/code-interpreter.d.ts +2 -2
- package/dist/code-interpreter.js +1144 -382
- package/dist/code-interpreter.js.map +1 -1
- package/dist/code-interpreter.mjs +9 -3
- package/dist/code-interpreter.mjs.map +1 -1
- package/dist/desktop.d.mts +2 -2
- package/dist/desktop.d.ts +2 -2
- package/dist/desktop.js +1132 -370
- package/dist/desktop.js.map +1 -1
- package/dist/desktop.mjs +9 -3
- package/dist/desktop.mjs.map +1 -1
- package/dist/{index-Dvjw3Vq4.d.mts → index-COUoJrLZ.d.mts} +795 -750
- package/dist/{index-Dvjw3Vq4.d.ts → index-COUoJrLZ.d.ts} +795 -750
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1132 -370
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +9 -3
- package/package.json +1 -1
- package/dist/chunk-P33RTZCB.mjs.map +0 -1
|
@@ -60,7 +60,7 @@ import createClient from "openapi-fetch";
|
|
|
60
60
|
import platform2 from "platform";
|
|
61
61
|
|
|
62
62
|
// package.json
|
|
63
|
-
var version = "2.0.
|
|
63
|
+
var version = "2.0.2-a1";
|
|
64
64
|
|
|
65
65
|
// src/core/utils.ts
|
|
66
66
|
import platform from "platform";
|
|
@@ -268,6 +268,12 @@ var VolumeError = class extends Error {
|
|
|
268
268
|
this.name = "VolumeError";
|
|
269
269
|
}
|
|
270
270
|
};
|
|
271
|
+
var SecretError = class extends SandboxError {
|
|
272
|
+
constructor(message, stackTrace) {
|
|
273
|
+
super(message, stackTrace);
|
|
274
|
+
this.name = "SecretError";
|
|
275
|
+
}
|
|
276
|
+
};
|
|
271
277
|
|
|
272
278
|
// src/core/logs.ts
|
|
273
279
|
function formatLog(log) {
|
|
@@ -311,10 +317,10 @@ function createRpcLogger(logger) {
|
|
|
311
317
|
}
|
|
312
318
|
function createApiLogger(logger) {
|
|
313
319
|
return {
|
|
314
|
-
async onRequest({ request }) {
|
|
320
|
+
async onRequest({ request: request2 }) {
|
|
315
321
|
var _a3;
|
|
316
|
-
(_a3 = logger.info) == null ? void 0 : _a3.call(logger, `Request ${
|
|
317
|
-
return
|
|
322
|
+
(_a3 = logger.info) == null ? void 0 : _a3.call(logger, `Request ${request2.method} ${request2.url}`);
|
|
323
|
+
return request2;
|
|
318
324
|
},
|
|
319
325
|
async onResponse({ response }) {
|
|
320
326
|
var _a3, _b;
|
|
@@ -390,12 +396,27 @@ var REQUEST_TIMEOUT_MS = 6e4;
|
|
|
390
396
|
var DEFAULT_SANDBOX_TIMEOUT_MS = 3e5;
|
|
391
397
|
var KEEPALIVE_PING_INTERVAL_SEC = 50;
|
|
392
398
|
var KEEPALIVE_PING_HEADER = "Keepalive-Ping-Interval";
|
|
399
|
+
var LEGACY_DOMAINS = ["sandbox.ppio.cn", "cn-beijing-1.sandbox.ppio.com"];
|
|
400
|
+
function isLegacyDomain(domain) {
|
|
401
|
+
return domain ? LEGACY_DOMAINS.includes(domain) : true;
|
|
402
|
+
}
|
|
403
|
+
function raiseIfLegacy(config, feature, ErrorType = Error) {
|
|
404
|
+
if (config.isLegacyDomain) {
|
|
405
|
+
throw new ErrorType(`${feature} is not supported on legacy domains`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function validateDomain(domain) {
|
|
409
|
+
if (!domain) {
|
|
410
|
+
throw new Error("Domain cannot be empty");
|
|
411
|
+
}
|
|
412
|
+
}
|
|
393
413
|
var _ConnectionConfig = class _ConnectionConfig {
|
|
394
414
|
constructor(opts) {
|
|
395
415
|
var _a3;
|
|
396
416
|
this.apiKey = (opts == null ? void 0 : opts.apiKey) || _ConnectionConfig.apiKey;
|
|
397
417
|
this.debug = (opts == null ? void 0 : opts.debug) || _ConnectionConfig.debug;
|
|
398
418
|
this.domain = (opts == null ? void 0 : opts.domain) || _ConnectionConfig.domain;
|
|
419
|
+
this.isLegacyDomain = isLegacyDomain(this.domain);
|
|
399
420
|
this.accessToken = (opts == null ? void 0 : opts.accessToken) || _ConnectionConfig.accessToken;
|
|
400
421
|
this.requestTimeoutMs = (_a3 = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _a3 : REQUEST_TIMEOUT_MS;
|
|
401
422
|
this.logger = opts == null ? void 0 : opts.logger;
|
|
@@ -805,6 +826,9 @@ var Filesystem2 = class {
|
|
|
805
826
|
return new Uint8Array(res.data);
|
|
806
827
|
}
|
|
807
828
|
if (res.response.headers.get("content-length") === "0") {
|
|
829
|
+
if (format === "blob") {
|
|
830
|
+
return new Blob([]);
|
|
831
|
+
}
|
|
808
832
|
return "";
|
|
809
833
|
}
|
|
810
834
|
return res.data;
|
|
@@ -2317,64 +2341,7 @@ var Git = class {
|
|
|
2317
2341
|
}
|
|
2318
2342
|
};
|
|
2319
2343
|
|
|
2320
|
-
// src/core/volume/client.ts
|
|
2321
|
-
import createClient4 from "openapi-fetch";
|
|
2322
|
-
var FILE_TIMEOUT_MS = 36e5;
|
|
2323
|
-
var VolumeConnectionConfig = class _VolumeConnectionConfig {
|
|
2324
|
-
constructor(volume, opts) {
|
|
2325
|
-
var _a3, _b;
|
|
2326
|
-
this.domain = (opts == null ? void 0 : opts.domain) || volume.domain || _VolumeConnectionConfig.domain;
|
|
2327
|
-
this.debug = (_b = (_a3 = opts == null ? void 0 : opts.debug) != null ? _a3 : volume.debug) != null ? _b : _VolumeConnectionConfig.debug;
|
|
2328
|
-
this.apiUrl = (opts == null ? void 0 : opts.apiUrl) || _VolumeConnectionConfig.volumeApiUrl || (this.debug ? "http://localhost:8080" : `https://api.${this.domain}`);
|
|
2329
|
-
this.token = (opts == null ? void 0 : opts.token) || volume.token;
|
|
2330
|
-
this.headers = opts == null ? void 0 : opts.headers;
|
|
2331
|
-
this.logger = opts == null ? void 0 : opts.logger;
|
|
2332
|
-
this.requestTimeoutMs = opts == null ? void 0 : opts.requestTimeoutMs;
|
|
2333
|
-
}
|
|
2334
|
-
static get domain() {
|
|
2335
|
-
return getEnvVar("PPIO_DOMAIN") || "sandbox.ppio.cn";
|
|
2336
|
-
}
|
|
2337
|
-
static get debug() {
|
|
2338
|
-
return (getEnvVar("PPIO_DEBUG") || "false").toLowerCase() === "true";
|
|
2339
|
-
}
|
|
2340
|
-
static get volumeApiUrl() {
|
|
2341
|
-
return getEnvVar("PPIO_SANDBOX_VOLUME_API_URL");
|
|
2342
|
-
}
|
|
2343
|
-
getSignal(requestTimeoutMs) {
|
|
2344
|
-
const timeout = requestTimeoutMs != null ? requestTimeoutMs : this.requestTimeoutMs;
|
|
2345
|
-
return timeout ? AbortSignal.timeout(timeout) : void 0;
|
|
2346
|
-
}
|
|
2347
|
-
};
|
|
2348
|
-
var VolumeApiClient = class {
|
|
2349
|
-
constructor(config) {
|
|
2350
|
-
this.api = createClient4({
|
|
2351
|
-
baseUrl: config.apiUrl,
|
|
2352
|
-
headers: __spreadValues(__spreadValues(__spreadValues({}, defaultHeaders), config.token && { Authorization: `Bearer ${config.token}` }), config.headers)
|
|
2353
|
-
});
|
|
2354
|
-
if (config.logger) {
|
|
2355
|
-
this.api.use(createApiLogger(config.logger));
|
|
2356
|
-
}
|
|
2357
|
-
}
|
|
2358
|
-
};
|
|
2359
|
-
|
|
2360
|
-
// src/core/volume/types.ts
|
|
2361
|
-
var VolumeFileType = /* @__PURE__ */ ((VolumeFileType2) => {
|
|
2362
|
-
VolumeFileType2["UNKNOWN"] = "unknown";
|
|
2363
|
-
VolumeFileType2["FILE"] = "file";
|
|
2364
|
-
VolumeFileType2["DIRECTORY"] = "directory";
|
|
2365
|
-
VolumeFileType2["SYMLINK"] = "symlink";
|
|
2366
|
-
return VolumeFileType2;
|
|
2367
|
-
})(VolumeFileType || {});
|
|
2368
|
-
|
|
2369
2344
|
// src/core/volume/index.ts
|
|
2370
|
-
function convertVolumeEntryStat(entry) {
|
|
2371
|
-
return __spreadProps(__spreadValues({}, entry), {
|
|
2372
|
-
type: entry.type,
|
|
2373
|
-
atime: new Date(entry.atime),
|
|
2374
|
-
mtime: new Date(entry.mtime),
|
|
2375
|
-
ctime: new Date(entry.ctime)
|
|
2376
|
-
});
|
|
2377
|
-
}
|
|
2378
2345
|
var Volume = class _Volume {
|
|
2379
2346
|
/**
|
|
2380
2347
|
* Create a local Volume instance with no API call.
|
|
@@ -2386,6 +2353,9 @@ var Volume = class _Volume {
|
|
|
2386
2353
|
* @param debug whether to use debug mode.
|
|
2387
2354
|
*/
|
|
2388
2355
|
constructor(volumeId, name, token, domain, debug) {
|
|
2356
|
+
if (domain) {
|
|
2357
|
+
validateDomain(domain);
|
|
2358
|
+
}
|
|
2389
2359
|
this.volumeId = volumeId;
|
|
2390
2360
|
this.name = name;
|
|
2391
2361
|
this.token = token;
|
|
@@ -2397,15 +2367,20 @@ var Volume = class _Volume {
|
|
|
2397
2367
|
*
|
|
2398
2368
|
* @param name name of the volume.
|
|
2399
2369
|
* @param opts connection options.
|
|
2370
|
+
* @param [opts.quotaSizeGiB] capacity quota in GiB.
|
|
2371
|
+
* @param [opts.quotaInodes] inode quota.
|
|
2400
2372
|
*
|
|
2401
2373
|
* @returns new Volume instance.
|
|
2402
2374
|
*/
|
|
2403
2375
|
static async create(name, opts) {
|
|
2404
2376
|
const config = new ConnectionConfig(opts);
|
|
2377
|
+
raiseIfLegacy(config, "Volume.create", VolumeError);
|
|
2405
2378
|
const client = new ApiClient(config);
|
|
2406
2379
|
const res = await client.api.POST("/volumes", {
|
|
2407
2380
|
body: {
|
|
2408
|
-
name
|
|
2381
|
+
name,
|
|
2382
|
+
quotaSizeGiB: opts == null ? void 0 : opts.quotaSizeGiB,
|
|
2383
|
+
quotaInodes: opts == null ? void 0 : opts.quotaInodes
|
|
2409
2384
|
},
|
|
2410
2385
|
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2411
2386
|
});
|
|
@@ -2434,6 +2409,7 @@ var Volume = class _Volume {
|
|
|
2434
2409
|
*/
|
|
2435
2410
|
static async connect(volumeId, opts) {
|
|
2436
2411
|
const config = new ConnectionConfig(opts);
|
|
2412
|
+
raiseIfLegacy(config, "Volume.connect", VolumeError);
|
|
2437
2413
|
const { name, token } = await _Volume.getInfo(volumeId, opts);
|
|
2438
2414
|
return new _Volume(volumeId, name, token, config.domain, config.debug);
|
|
2439
2415
|
}
|
|
@@ -2446,7 +2422,9 @@ var Volume = class _Volume {
|
|
|
2446
2422
|
* @returns volume information.
|
|
2447
2423
|
*/
|
|
2448
2424
|
static async getInfo(volumeId, opts) {
|
|
2425
|
+
var _a3, _b, _c, _d;
|
|
2449
2426
|
const config = new ConnectionConfig(opts);
|
|
2427
|
+
raiseIfLegacy(config, "Volume.getInfo", VolumeError);
|
|
2450
2428
|
const client = new ApiClient(config);
|
|
2451
2429
|
const res = await client.api.GET("/volumes/{volumeID}", {
|
|
2452
2430
|
params: {
|
|
@@ -2463,10 +2441,15 @@ var Volume = class _Volume {
|
|
|
2463
2441
|
if (err) {
|
|
2464
2442
|
throw err;
|
|
2465
2443
|
}
|
|
2444
|
+
const data = res.data;
|
|
2466
2445
|
return {
|
|
2467
|
-
volumeId:
|
|
2468
|
-
name:
|
|
2469
|
-
token:
|
|
2446
|
+
volumeId: data.volumeID,
|
|
2447
|
+
name: data.name,
|
|
2448
|
+
token: data.token,
|
|
2449
|
+
quotaSizeGiB: (_a3 = data.quotaSizeGiB) != null ? _a3 : 0,
|
|
2450
|
+
quotaInodes: (_b = data.quotaInodes) != null ? _b : 0,
|
|
2451
|
+
usedSizeBytes: (_c = data.usedSizeBytes) != null ? _c : 0,
|
|
2452
|
+
usedInodes: (_d = data.usedInodes) != null ? _d : 0
|
|
2470
2453
|
};
|
|
2471
2454
|
}
|
|
2472
2455
|
/**
|
|
@@ -2479,6 +2462,7 @@ var Volume = class _Volume {
|
|
|
2479
2462
|
static async list(opts) {
|
|
2480
2463
|
var _a3;
|
|
2481
2464
|
const config = new ConnectionConfig(opts);
|
|
2465
|
+
raiseIfLegacy(config, "Volume.list", VolumeError);
|
|
2482
2466
|
const client = new ApiClient(config);
|
|
2483
2467
|
const res = await client.api.GET("/volumes", {
|
|
2484
2468
|
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
@@ -2487,10 +2471,61 @@ var Volume = class _Volume {
|
|
|
2487
2471
|
if (err) {
|
|
2488
2472
|
throw err;
|
|
2489
2473
|
}
|
|
2490
|
-
return ((_a3 = res.data) != null ? _a3 : []).map((vol) =>
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2474
|
+
return ((_a3 = res.data) != null ? _a3 : []).map((vol) => {
|
|
2475
|
+
var _a4, _b, _c, _d;
|
|
2476
|
+
return {
|
|
2477
|
+
volumeId: vol.volumeID,
|
|
2478
|
+
name: vol.name,
|
|
2479
|
+
quotaSizeGiB: (_a4 = vol.quotaSizeGiB) != null ? _a4 : 0,
|
|
2480
|
+
quotaInodes: (_b = vol.quotaInodes) != null ? _b : 0,
|
|
2481
|
+
usedSizeBytes: (_c = vol.usedSizeBytes) != null ? _c : 0,
|
|
2482
|
+
usedInodes: (_d = vol.usedInodes) != null ? _d : 0
|
|
2483
|
+
};
|
|
2484
|
+
});
|
|
2485
|
+
}
|
|
2486
|
+
/**
|
|
2487
|
+
* Update volume quota.
|
|
2488
|
+
*
|
|
2489
|
+
* @param volumeId volume ID.
|
|
2490
|
+
* @param params quota parameters.
|
|
2491
|
+
* @param opts connection options.
|
|
2492
|
+
*
|
|
2493
|
+
* @returns updated volume information.
|
|
2494
|
+
*/
|
|
2495
|
+
static async updateQuota(volumeId, params, opts) {
|
|
2496
|
+
var _a3, _b, _c, _d;
|
|
2497
|
+
const config = new ConnectionConfig(opts);
|
|
2498
|
+
raiseIfLegacy(config, "Volume.updateQuota", VolumeError);
|
|
2499
|
+
const res = await fetch(
|
|
2500
|
+
`${config.apiUrl}/volumes/${encodeURIComponent(volumeId)}`,
|
|
2501
|
+
{
|
|
2502
|
+
method: "PATCH",
|
|
2503
|
+
headers: __spreadValues(__spreadValues(__spreadProps(__spreadValues({}, config.headers), {
|
|
2504
|
+
"Content-Type": "application/json"
|
|
2505
|
+
}), config.apiKey ? { "X-API-KEY": config.apiKey } : {}), config.accessToken ? { Authorization: `Bearer ${config.accessToken}` } : {}),
|
|
2506
|
+
body: JSON.stringify({
|
|
2507
|
+
quotaSizeGiB: params.quotaSizeGiB,
|
|
2508
|
+
quotaInodes: params.quotaInodes
|
|
2509
|
+
}),
|
|
2510
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2511
|
+
}
|
|
2512
|
+
);
|
|
2513
|
+
if (res.status === 404) {
|
|
2514
|
+
throw new NotFoundError(`Volume ${volumeId} not found`);
|
|
2515
|
+
}
|
|
2516
|
+
if (!res.ok) {
|
|
2517
|
+
throw new VolumeError(`${res.status}: ${res.statusText}`);
|
|
2518
|
+
}
|
|
2519
|
+
const data = await res.json();
|
|
2520
|
+
return {
|
|
2521
|
+
volumeId: data.volumeID,
|
|
2522
|
+
name: data.name,
|
|
2523
|
+
token: data.token,
|
|
2524
|
+
quotaSizeGiB: (_a3 = data.quotaSizeGiB) != null ? _a3 : 0,
|
|
2525
|
+
quotaInodes: (_b = data.quotaInodes) != null ? _b : 0,
|
|
2526
|
+
usedSizeBytes: (_c = data.usedSizeBytes) != null ? _c : 0,
|
|
2527
|
+
usedInodes: (_d = data.usedInodes) != null ? _d : 0
|
|
2528
|
+
};
|
|
2494
2529
|
}
|
|
2495
2530
|
/**
|
|
2496
2531
|
* Destroy a volume.
|
|
@@ -2500,6 +2535,7 @@ var Volume = class _Volume {
|
|
|
2500
2535
|
*/
|
|
2501
2536
|
static async destroy(volumeId, opts) {
|
|
2502
2537
|
const config = new ConnectionConfig(opts);
|
|
2538
|
+
raiseIfLegacy(config, "Volume.destroy", VolumeError);
|
|
2503
2539
|
const client = new ApiClient(config);
|
|
2504
2540
|
const res = await client.api.DELETE("/volumes/{volumeID}", {
|
|
2505
2541
|
params: {
|
|
@@ -2518,296 +2554,196 @@ var Volume = class _Volume {
|
|
|
2518
2554
|
}
|
|
2519
2555
|
return true;
|
|
2520
2556
|
}
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
async list(path2, opts) {
|
|
2531
|
-
const config = new VolumeConnectionConfig(this, opts);
|
|
2532
|
-
const client = new VolumeApiClient(config);
|
|
2533
|
-
const res = await client.api.GET("/volumecontent/{volumeID}/dir", {
|
|
2534
|
-
params: {
|
|
2535
|
-
path: {
|
|
2536
|
-
volumeID: this.volumeId
|
|
2537
|
-
},
|
|
2538
|
-
query: {
|
|
2539
|
-
path: path2,
|
|
2540
|
-
depth: opts == null ? void 0 : opts.depth
|
|
2541
|
-
}
|
|
2542
|
-
},
|
|
2543
|
-
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2544
|
-
});
|
|
2545
|
-
if (res.response.status === 404) {
|
|
2546
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2547
|
-
}
|
|
2548
|
-
const err = handleApiError(res, VolumeError);
|
|
2549
|
-
if (err) {
|
|
2550
|
-
throw err;
|
|
2551
|
-
}
|
|
2552
|
-
const entries = Array.isArray(res.data) ? res.data : [];
|
|
2553
|
-
return entries.map(convertVolumeEntryStat);
|
|
2557
|
+
};
|
|
2558
|
+
|
|
2559
|
+
// src/core/secret/index.ts
|
|
2560
|
+
var SECRET_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
2561
|
+
var ENV_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
2562
|
+
var HOST_PATTERN = /^(\*\.)?[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;
|
|
2563
|
+
function validateSecretEnvs(secretEnvs, envs) {
|
|
2564
|
+
if (!secretEnvs) {
|
|
2565
|
+
return {};
|
|
2554
2566
|
}
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
const res = await client.api.POST("/volumecontent/{volumeID}/dir", {
|
|
2566
|
-
params: {
|
|
2567
|
-
path: {
|
|
2568
|
-
volumeID: this.volumeId
|
|
2569
|
-
},
|
|
2570
|
-
query: {
|
|
2571
|
-
path: path2,
|
|
2572
|
-
uid: opts == null ? void 0 : opts.uid,
|
|
2573
|
-
gid: opts == null ? void 0 : opts.gid,
|
|
2574
|
-
mode: opts == null ? void 0 : opts.mode,
|
|
2575
|
-
force: opts == null ? void 0 : opts.force
|
|
2576
|
-
}
|
|
2577
|
-
},
|
|
2578
|
-
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2579
|
-
});
|
|
2580
|
-
if (res.response.status === 404) {
|
|
2581
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2582
|
-
}
|
|
2583
|
-
const err = handleApiError(res, VolumeError);
|
|
2584
|
-
if (err) {
|
|
2585
|
-
throw err;
|
|
2567
|
+
if (typeof secretEnvs !== "object" || Array.isArray(secretEnvs)) {
|
|
2568
|
+
throw new InvalidArgumentError("secretEnvs must be a mapping");
|
|
2569
|
+
}
|
|
2570
|
+
const envNames = new Set(Object.keys(envs != null ? envs : {}));
|
|
2571
|
+
const validated = {};
|
|
2572
|
+
for (const [envName, secretName] of Object.entries(secretEnvs)) {
|
|
2573
|
+
if (!ENV_NAME_PATTERN.test(envName)) {
|
|
2574
|
+
throw new InvalidArgumentError(
|
|
2575
|
+
`secretEnvs key ${JSON.stringify(envName)} must be a valid sandbox environment variable name`
|
|
2576
|
+
);
|
|
2586
2577
|
}
|
|
2587
|
-
if (
|
|
2588
|
-
throw new
|
|
2578
|
+
if (envNames.has(envName)) {
|
|
2579
|
+
throw new InvalidArgumentError(
|
|
2580
|
+
`envs and secretEnvs both define ${JSON.stringify(envName)}`
|
|
2581
|
+
);
|
|
2589
2582
|
}
|
|
2590
|
-
|
|
2591
|
-
|
|
2583
|
+
validateSecretName(secretName);
|
|
2584
|
+
validated[envName] = secretName;
|
|
2585
|
+
}
|
|
2586
|
+
return validated;
|
|
2587
|
+
}
|
|
2588
|
+
var _Secret = class _Secret {
|
|
2589
|
+
static async create(params, opts) {
|
|
2590
|
+
validateSecretName(params.name);
|
|
2591
|
+
if (!params.value) {
|
|
2592
|
+
throw new InvalidArgumentError("value is required");
|
|
2593
|
+
}
|
|
2594
|
+
const body = {
|
|
2595
|
+
name: params.name,
|
|
2596
|
+
value: params.value,
|
|
2597
|
+
hosts: normalizeSecretHosts(params.hosts)
|
|
2598
|
+
};
|
|
2599
|
+
if (params.description !== void 0) {
|
|
2600
|
+
body.description = params.description;
|
|
2601
|
+
}
|
|
2602
|
+
return bindingFromJson(
|
|
2603
|
+
await request(
|
|
2604
|
+
"POST",
|
|
2605
|
+
_Secret.base,
|
|
2606
|
+
"Secret.create",
|
|
2607
|
+
opts,
|
|
2608
|
+
body
|
|
2609
|
+
)
|
|
2592
2610
|
);
|
|
2593
2611
|
}
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
}
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
},
|
|
2614
|
-
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2615
|
-
});
|
|
2616
|
-
if (res.response.status === 404) {
|
|
2617
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2618
|
-
}
|
|
2619
|
-
const err = handleApiError(res, VolumeError);
|
|
2620
|
-
if (err) {
|
|
2621
|
-
throw err;
|
|
2622
|
-
}
|
|
2623
|
-
if (!res.data) {
|
|
2624
|
-
throw new Error("Response data is missing");
|
|
2625
|
-
}
|
|
2626
|
-
return convertVolumeEntryStat(
|
|
2627
|
-
res.data
|
|
2612
|
+
static async list(opts) {
|
|
2613
|
+
var _a3;
|
|
2614
|
+
const data = await request(
|
|
2615
|
+
"GET",
|
|
2616
|
+
_Secret.base,
|
|
2617
|
+
"Secret.list",
|
|
2618
|
+
opts
|
|
2619
|
+
);
|
|
2620
|
+
return ((_a3 = data.secrets) != null ? _a3 : []).map(bindingFromJson);
|
|
2621
|
+
}
|
|
2622
|
+
static async get(name, opts) {
|
|
2623
|
+
validateSecretName(name);
|
|
2624
|
+
return bindingFromJson(
|
|
2625
|
+
await request(
|
|
2626
|
+
"GET",
|
|
2627
|
+
`${_Secret.base}/${encodeURIComponent(name)}`,
|
|
2628
|
+
"Secret.get",
|
|
2629
|
+
opts
|
|
2630
|
+
)
|
|
2628
2631
|
);
|
|
2629
2632
|
}
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
* `false` if it does not (404). Other errors are rethrown.
|
|
2635
|
-
*
|
|
2636
|
-
* @param path path to the file or directory.
|
|
2637
|
-
* @param opts connection options.
|
|
2638
|
-
*
|
|
2639
|
-
* @returns `true` if the path exists, `false` otherwise.
|
|
2640
|
-
*/
|
|
2641
|
-
async exists(path2, opts) {
|
|
2642
|
-
try {
|
|
2643
|
-
await this.getInfo(path2, opts);
|
|
2644
|
-
return true;
|
|
2645
|
-
} catch (err) {
|
|
2646
|
-
if (err instanceof NotFoundError) {
|
|
2647
|
-
return false;
|
|
2648
|
-
}
|
|
2649
|
-
throw err;
|
|
2633
|
+
static async update(params, opts) {
|
|
2634
|
+
validateSecretName(params.name);
|
|
2635
|
+
if (!params.value) {
|
|
2636
|
+
throw new InvalidArgumentError("value is required");
|
|
2650
2637
|
}
|
|
2638
|
+
const body = {
|
|
2639
|
+
value: params.value,
|
|
2640
|
+
hosts: normalizeSecretHosts(params.hosts)
|
|
2641
|
+
};
|
|
2642
|
+
if (params.description !== void 0) {
|
|
2643
|
+
body.description = params.description;
|
|
2644
|
+
}
|
|
2645
|
+
return bindingFromJson(
|
|
2646
|
+
await request(
|
|
2647
|
+
"PUT",
|
|
2648
|
+
`${_Secret.base}/${encodeURIComponent(params.name)}`,
|
|
2649
|
+
"Secret.update",
|
|
2650
|
+
opts,
|
|
2651
|
+
body
|
|
2652
|
+
)
|
|
2653
|
+
);
|
|
2651
2654
|
}
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
*/
|
|
2661
|
-
async updateMetadata(path2, metadata, opts) {
|
|
2662
|
-
const config = new VolumeConnectionConfig(this, opts);
|
|
2663
|
-
const client = new VolumeApiClient(config);
|
|
2664
|
-
const res = await client.api.PATCH("/volumecontent/{volumeID}/path", {
|
|
2665
|
-
params: {
|
|
2666
|
-
path: {
|
|
2667
|
-
volumeID: this.volumeId
|
|
2668
|
-
},
|
|
2669
|
-
query: {
|
|
2670
|
-
path: path2
|
|
2671
|
-
}
|
|
2672
|
-
},
|
|
2673
|
-
body: {
|
|
2674
|
-
uid: metadata.uid,
|
|
2675
|
-
gid: metadata.gid,
|
|
2676
|
-
mode: metadata.mode
|
|
2677
|
-
},
|
|
2678
|
-
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2679
|
-
});
|
|
2680
|
-
if (res.response.status === 404) {
|
|
2681
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2682
|
-
}
|
|
2683
|
-
const err = handleApiError(res, VolumeError);
|
|
2684
|
-
if (err) {
|
|
2685
|
-
throw err;
|
|
2686
|
-
}
|
|
2687
|
-
if (!res.data) {
|
|
2688
|
-
throw new Error("Response data is missing");
|
|
2689
|
-
}
|
|
2690
|
-
return convertVolumeEntryStat(
|
|
2691
|
-
res.data
|
|
2655
|
+
static async delete(name, opts) {
|
|
2656
|
+
var _a3;
|
|
2657
|
+
validateSecretName(name);
|
|
2658
|
+
const data = await request(
|
|
2659
|
+
"DELETE",
|
|
2660
|
+
`${_Secret.base}/${encodeURIComponent(name)}`,
|
|
2661
|
+
"Secret.delete",
|
|
2662
|
+
opts
|
|
2692
2663
|
);
|
|
2664
|
+
return String((_a3 = data.deleted) != null ? _a3 : "");
|
|
2693
2665
|
}
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
if (
|
|
2712
|
-
throw new
|
|
2666
|
+
};
|
|
2667
|
+
_Secret.base = "/secrets";
|
|
2668
|
+
var Secret = _Secret;
|
|
2669
|
+
function validateSecretName(name) {
|
|
2670
|
+
if (typeof name !== "string" || !SECRET_NAME_PATTERN.test(name)) {
|
|
2671
|
+
throw new InvalidArgumentError(
|
|
2672
|
+
`secret name ${JSON.stringify(name)} must be 1-128 characters and contain only letters, numbers, dots, underscores, and hyphens`
|
|
2673
|
+
);
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
function normalizeSecretHosts(hosts) {
|
|
2677
|
+
if (!hosts.length) {
|
|
2678
|
+
throw new InvalidArgumentError("hosts is required");
|
|
2679
|
+
}
|
|
2680
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2681
|
+
const normalizedHosts = [];
|
|
2682
|
+
for (const rawHost of hosts) {
|
|
2683
|
+
if (typeof rawHost !== "string") {
|
|
2684
|
+
throw new InvalidArgumentError("host must be a string");
|
|
2713
2685
|
}
|
|
2714
|
-
const
|
|
2715
|
-
if (
|
|
2716
|
-
throw
|
|
2686
|
+
const host = rawHost.trim().toLowerCase();
|
|
2687
|
+
if (!host) {
|
|
2688
|
+
throw new InvalidArgumentError("host cannot be empty");
|
|
2717
2689
|
}
|
|
2718
|
-
if (
|
|
2719
|
-
|
|
2690
|
+
if (host.includes("://") || /[/?#@:]/.test(host)) {
|
|
2691
|
+
throw new InvalidArgumentError(
|
|
2692
|
+
`host ${JSON.stringify(host)} must be a hostname only`
|
|
2693
|
+
);
|
|
2720
2694
|
}
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
}
|
|
2725
|
-
return typeof res.data === "string" ? res.data : "";
|
|
2695
|
+
const wildcard = host.startsWith("*.");
|
|
2696
|
+
const lookupHost = wildcard ? host.slice(2) : host;
|
|
2697
|
+
if (!lookupHost || lookupHost.includes("*")) {
|
|
2698
|
+
throw new InvalidArgumentError(`invalid host ${JSON.stringify(host)}`);
|
|
2726
2699
|
}
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
* Writing to a file that doesn't exist creates the file.
|
|
2733
|
-
*
|
|
2734
|
-
* Writing to a file that already exists overwrites the file.
|
|
2735
|
-
*
|
|
2736
|
-
* @param path path to the file.
|
|
2737
|
-
* @param data data to write to the file. Data can be a string, `ArrayBuffer`, `Blob`, or `ReadableStream`.
|
|
2738
|
-
* @param options file creation options.
|
|
2739
|
-
* @param opts connection options.
|
|
2740
|
-
*
|
|
2741
|
-
* @returns information about the written file
|
|
2742
|
-
*/
|
|
2743
|
-
async writeFile(path2, data, opts) {
|
|
2744
|
-
var _a3;
|
|
2745
|
-
const config = new VolumeConnectionConfig(this, opts);
|
|
2746
|
-
const client = new VolumeApiClient(config);
|
|
2747
|
-
const blob = await toBlob(data);
|
|
2748
|
-
const res = await client.api.PUT("/volumecontent/{volumeID}/file", {
|
|
2749
|
-
params: {
|
|
2750
|
-
path: {
|
|
2751
|
-
volumeID: this.volumeId
|
|
2752
|
-
},
|
|
2753
|
-
query: {
|
|
2754
|
-
path: path2,
|
|
2755
|
-
uid: opts == null ? void 0 : opts.uid,
|
|
2756
|
-
gid: opts == null ? void 0 : opts.gid,
|
|
2757
|
-
mode: opts == null ? void 0 : opts.mode,
|
|
2758
|
-
force: opts == null ? void 0 : opts.force
|
|
2759
|
-
}
|
|
2760
|
-
},
|
|
2761
|
-
bodySerializer: () => blob,
|
|
2762
|
-
body: {},
|
|
2763
|
-
headers: {
|
|
2764
|
-
"Content-Type": "application/octet-stream"
|
|
2765
|
-
},
|
|
2766
|
-
signal: config.getSignal((_a3 = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _a3 : FILE_TIMEOUT_MS)
|
|
2767
|
-
});
|
|
2768
|
-
if (res.response.status === 404) {
|
|
2769
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2770
|
-
}
|
|
2771
|
-
const err = handleApiError(res, VolumeError);
|
|
2772
|
-
if (err) {
|
|
2773
|
-
throw err;
|
|
2700
|
+
const normalized = wildcard ? `*.${lookupHost}` : lookupHost;
|
|
2701
|
+
if (!HOST_PATTERN.test(normalized)) {
|
|
2702
|
+
throw new InvalidArgumentError(
|
|
2703
|
+
`host ${JSON.stringify(host)} must be a hostname or wildcard hostname`
|
|
2704
|
+
);
|
|
2774
2705
|
}
|
|
2775
|
-
if (
|
|
2776
|
-
|
|
2706
|
+
if (seen.has(normalized)) {
|
|
2707
|
+
continue;
|
|
2777
2708
|
}
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
);
|
|
2709
|
+
seen.add(normalized);
|
|
2710
|
+
normalizedHosts.push(normalized);
|
|
2781
2711
|
}
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
}
|
|
2799
|
-
},
|
|
2800
|
-
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2801
|
-
});
|
|
2802
|
-
if (res.response.status === 404) {
|
|
2803
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2804
|
-
}
|
|
2805
|
-
const err = handleApiError(res, VolumeError);
|
|
2806
|
-
if (err) {
|
|
2807
|
-
throw err;
|
|
2808
|
-
}
|
|
2712
|
+
return normalizedHosts;
|
|
2713
|
+
}
|
|
2714
|
+
async function request(method, path2, feature, opts, body) {
|
|
2715
|
+
const config = new ConnectionConfig(opts);
|
|
2716
|
+
raiseIfLegacy(config, feature, SecretError);
|
|
2717
|
+
const headers = __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, config.headers), body ? { "Content-Type": "application/json" } : {}), config.apiKey ? { "X-API-KEY": config.apiKey } : {}), config.accessToken ? { Authorization: `Bearer ${config.accessToken}` } : {});
|
|
2718
|
+
const response = await fetch(`${config.apiUrl}${path2}`, {
|
|
2719
|
+
method,
|
|
2720
|
+
headers,
|
|
2721
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
2722
|
+
signal: config.getSignal()
|
|
2723
|
+
});
|
|
2724
|
+
const data = await parseJson(response);
|
|
2725
|
+
if (!response.ok) {
|
|
2726
|
+
const message = typeof (data == null ? void 0 : data.message) === "string" ? data.message : response.statusText;
|
|
2727
|
+
throw new SecretError(`${response.status}: ${message}`);
|
|
2809
2728
|
}
|
|
2810
|
-
|
|
2729
|
+
return data;
|
|
2730
|
+
}
|
|
2731
|
+
async function parseJson(response) {
|
|
2732
|
+
const text = await response.text();
|
|
2733
|
+
return text ? JSON.parse(text) : {};
|
|
2734
|
+
}
|
|
2735
|
+
function bindingFromJson(data) {
|
|
2736
|
+
var _a3, _b;
|
|
2737
|
+
return {
|
|
2738
|
+
name: data.name,
|
|
2739
|
+
hosts: (_a3 = data.hosts) != null ? _a3 : [],
|
|
2740
|
+
placeholder: data.placeholder,
|
|
2741
|
+
description: (_b = data.description) != null ? _b : null,
|
|
2742
|
+
hasSecret: data.hasSecret,
|
|
2743
|
+
status: data.status,
|
|
2744
|
+
updatedAt: data.updatedAt
|
|
2745
|
+
};
|
|
2746
|
+
}
|
|
2811
2747
|
|
|
2812
2748
|
// src/core/sandbox/index.ts
|
|
2813
2749
|
import { createConnectTransport } from "@connectrpc/connect-web";
|
|
@@ -2816,7 +2752,7 @@ import { createConnectTransport } from "@connectrpc/connect-web";
|
|
|
2816
2752
|
import {
|
|
2817
2753
|
Code as Code5,
|
|
2818
2754
|
ConnectError as ConnectError5,
|
|
2819
|
-
createClient as
|
|
2755
|
+
createClient as createClient5
|
|
2820
2756
|
} from "@connectrpc/connect";
|
|
2821
2757
|
import { compareVersions as compareVersions3 } from "compare-versions";
|
|
2822
2758
|
|
|
@@ -2836,7 +2772,7 @@ var Process = /* @__PURE__ */ serviceDesc2(file_process_process, 0);
|
|
|
2836
2772
|
import {
|
|
2837
2773
|
Code as Code4,
|
|
2838
2774
|
ConnectError as ConnectError4,
|
|
2839
|
-
createClient as
|
|
2775
|
+
createClient as createClient4
|
|
2840
2776
|
} from "@connectrpc/connect";
|
|
2841
2777
|
var Pty = class {
|
|
2842
2778
|
// 60 seconds
|
|
@@ -2844,7 +2780,7 @@ var Pty = class {
|
|
|
2844
2780
|
this.transport = transport;
|
|
2845
2781
|
this.connectionConfig = connectionConfig;
|
|
2846
2782
|
this.defaultPtyConnectionTimeout = 6e4;
|
|
2847
|
-
this.rpc =
|
|
2783
|
+
this.rpc = createClient4(Process, this.transport);
|
|
2848
2784
|
this.envdVersion = metadata.version;
|
|
2849
2785
|
}
|
|
2850
2786
|
/**
|
|
@@ -3056,7 +2992,7 @@ var Commands = class {
|
|
|
3056
2992
|
constructor(transport, connectionConfig, metadata) {
|
|
3057
2993
|
this.connectionConfig = connectionConfig;
|
|
3058
2994
|
this.defaultProcessConnectionTimeout = 6e4;
|
|
3059
|
-
this.rpc =
|
|
2995
|
+
this.rpc = createClient5(Process, transport);
|
|
3060
2996
|
this.envdVersion = metadata.version;
|
|
3061
2997
|
}
|
|
3062
2998
|
/**
|
|
@@ -3291,6 +3227,33 @@ var Commands = class {
|
|
|
3291
3227
|
|
|
3292
3228
|
// src/core/sandbox/sandboxApi.ts
|
|
3293
3229
|
import { compareVersions as compareVersions4 } from "compare-versions";
|
|
3230
|
+
async function createRawApiError(response) {
|
|
3231
|
+
var _a3;
|
|
3232
|
+
let message = response.statusText;
|
|
3233
|
+
try {
|
|
3234
|
+
const body = await response.json();
|
|
3235
|
+
message = (_a3 = body == null ? void 0 : body.message) != null ? _a3 : JSON.stringify(body);
|
|
3236
|
+
} catch (e) {
|
|
3237
|
+
try {
|
|
3238
|
+
message = await response.text();
|
|
3239
|
+
} catch (e2) {
|
|
3240
|
+
}
|
|
3241
|
+
}
|
|
3242
|
+
if (response.status === 401) {
|
|
3243
|
+
return new AuthenticationError(
|
|
3244
|
+
`Unauthorized, please check your credentials. - ${message}`
|
|
3245
|
+
);
|
|
3246
|
+
}
|
|
3247
|
+
if (response.status === 429) {
|
|
3248
|
+
return new RateLimitError(
|
|
3249
|
+
`Rate limit exceeded, please try again later - ${message}`
|
|
3250
|
+
);
|
|
3251
|
+
}
|
|
3252
|
+
return new SandboxError(`${response.status}: ${message}`);
|
|
3253
|
+
}
|
|
3254
|
+
function getRawApiHeaders(config, headers) {
|
|
3255
|
+
return __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, defaultHeaders), config.apiKey ? { "X-API-KEY": config.apiKey } : {}), config.accessToken ? { Authorization: `Bearer ${config.accessToken}` } : {}), config.headers), headers != null ? headers : {});
|
|
3256
|
+
}
|
|
3294
3257
|
function getLifecycle(opts) {
|
|
3295
3258
|
if (opts == null ? void 0 : opts.lifecycle) {
|
|
3296
3259
|
return opts.lifecycle;
|
|
@@ -3361,15 +3324,40 @@ var SandboxApi = class {
|
|
|
3361
3324
|
* @returns List of sandbox metrics containing CPU, memory and disk usage information.
|
|
3362
3325
|
*/
|
|
3363
3326
|
static async getMetrics(sandboxId, opts) {
|
|
3364
|
-
var _a3, _b;
|
|
3327
|
+
var _a3, _b, _c, _d;
|
|
3365
3328
|
const config = new ConnectionConfig(opts);
|
|
3366
3329
|
const client = new ApiClient(config);
|
|
3330
|
+
if (config.isLegacyDomain) {
|
|
3331
|
+
const res2 = await client.api.GET("/sandboxes/{sandboxID}/metrics", {
|
|
3332
|
+
params: {
|
|
3333
|
+
path: {
|
|
3334
|
+
sandboxID: sandboxId
|
|
3335
|
+
}
|
|
3336
|
+
},
|
|
3337
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3338
|
+
});
|
|
3339
|
+
const err2 = handleApiError(res2);
|
|
3340
|
+
if (err2) {
|
|
3341
|
+
throw err2;
|
|
3342
|
+
}
|
|
3343
|
+
return (_b = ((_a3 = res2.data) != null ? _a3 : []).map((metric) => ({
|
|
3344
|
+
timestamp: new Date(metric.timestamp),
|
|
3345
|
+
cpuUsedPct: metric.cpuUsedPct,
|
|
3346
|
+
cpuCount: metric.cpuCount,
|
|
3347
|
+
memUsed: metric.memUsedMiB * 1024 * 1024,
|
|
3348
|
+
memTotal: metric.memTotalMiB * 1024 * 1024,
|
|
3349
|
+
diskUsed: -1,
|
|
3350
|
+
diskTotal: -1
|
|
3351
|
+
}))) != null ? _b : [];
|
|
3352
|
+
}
|
|
3367
3353
|
const start = (opts == null ? void 0 : opts.start) ? Math.round(opts.start.getTime() / 1e3) : void 0;
|
|
3368
3354
|
const end = (opts == null ? void 0 : opts.end) ? Math.round(opts.end.getTime() / 1e3) : void 0;
|
|
3369
3355
|
const res = await client.api.GET("/sandboxes/{sandboxID}/metrics", {
|
|
3370
3356
|
params: {
|
|
3371
3357
|
path: {
|
|
3372
|
-
sandboxID: sandboxId
|
|
3358
|
+
sandboxID: sandboxId
|
|
3359
|
+
},
|
|
3360
|
+
query: {
|
|
3373
3361
|
start,
|
|
3374
3362
|
end
|
|
3375
3363
|
}
|
|
@@ -3380,7 +3368,7 @@ var SandboxApi = class {
|
|
|
3380
3368
|
if (err) {
|
|
3381
3369
|
throw err;
|
|
3382
3370
|
}
|
|
3383
|
-
return (
|
|
3371
|
+
return (_d = (_c = res.data) == null ? void 0 : _c.map((metric) => ({
|
|
3384
3372
|
timestamp: new Date(metric.timestamp),
|
|
3385
3373
|
cpuUsedPct: metric.cpuUsedPct,
|
|
3386
3374
|
cpuCount: metric.cpuCount,
|
|
@@ -3388,7 +3376,7 @@ var SandboxApi = class {
|
|
|
3388
3376
|
memTotal: metric.memTotal,
|
|
3389
3377
|
diskUsed: metric.diskUsed,
|
|
3390
3378
|
diskTotal: metric.diskTotal
|
|
3391
|
-
}))) != null ?
|
|
3379
|
+
}))) != null ? _d : [];
|
|
3392
3380
|
}
|
|
3393
3381
|
/**
|
|
3394
3382
|
* Set the timeout of the specified sandbox.
|
|
@@ -3417,17 +3405,238 @@ var SandboxApi = class {
|
|
|
3417
3405
|
},
|
|
3418
3406
|
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3419
3407
|
});
|
|
3420
|
-
if (((_a3 = res.error) == null ? void 0 : _a3.code) === 404) {
|
|
3408
|
+
if (((_a3 = res.error) == null ? void 0 : _a3.code) === 404) {
|
|
3409
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3410
|
+
}
|
|
3411
|
+
const err = handleApiError(res);
|
|
3412
|
+
if (err) {
|
|
3413
|
+
throw err;
|
|
3414
|
+
}
|
|
3415
|
+
}
|
|
3416
|
+
/**
|
|
3417
|
+
* @deprecated Only legacy domains support this method. Use {@link SandboxApi.createSnapshot} for modern domains.
|
|
3418
|
+
*/
|
|
3419
|
+
static async commit(sandboxId, opts) {
|
|
3420
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3421
|
+
const config = new ConnectionConfig(opts);
|
|
3422
|
+
if (!config.isLegacyDomain) {
|
|
3423
|
+
throw new SandboxError("Sandbox.commit is only supported for legacy domains");
|
|
3424
|
+
}
|
|
3425
|
+
const response = await fetch(
|
|
3426
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/commit`,
|
|
3427
|
+
{
|
|
3428
|
+
method: "POST",
|
|
3429
|
+
headers: getRawApiHeaders(config, {
|
|
3430
|
+
"Content-Type": "application/json"
|
|
3431
|
+
}),
|
|
3432
|
+
body: JSON.stringify((opts == null ? void 0 : opts.alias) ? { alias: opts.alias } : {}),
|
|
3433
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3434
|
+
}
|
|
3435
|
+
);
|
|
3436
|
+
if (response.status === 404) {
|
|
3437
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3438
|
+
}
|
|
3439
|
+
if (!response.ok) {
|
|
3440
|
+
throw await createRawApiError(response);
|
|
3441
|
+
}
|
|
3442
|
+
const data = await response.json();
|
|
3443
|
+
return {
|
|
3444
|
+
alias: (_d = (_c = (_a3 = data.aliases) == null ? void 0 : _a3[0]) != null ? _c : (_b = data.names) == null ? void 0 : _b[0]) != null ? _d : "",
|
|
3445
|
+
name: (_h = (_g = (_e = data.names) == null ? void 0 : _e[0]) != null ? _g : (_f = data.aliases) == null ? void 0 : _f[0]) != null ? _h : "",
|
|
3446
|
+
tags: [],
|
|
3447
|
+
templateId: data.templateID,
|
|
3448
|
+
buildId: data.buildID,
|
|
3449
|
+
aliases: (_i = data.aliases) != null ? _i : [],
|
|
3450
|
+
names: (_j = data.names) != null ? _j : [],
|
|
3451
|
+
templateType: "snapshot_template"
|
|
3452
|
+
};
|
|
3453
|
+
}
|
|
3454
|
+
static async hotplugMemory(sandboxId, requestedSizeMib, opts) {
|
|
3455
|
+
const config = new ConnectionConfig(opts);
|
|
3456
|
+
raiseIfLegacy(config, "Sandbox.hotplugMemory", SandboxError);
|
|
3457
|
+
const response = await fetch(
|
|
3458
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/hotplug-memory`,
|
|
3459
|
+
{
|
|
3460
|
+
method: "POST",
|
|
3461
|
+
headers: getRawApiHeaders(config, {
|
|
3462
|
+
"Content-Type": "application/json"
|
|
3463
|
+
}),
|
|
3464
|
+
body: JSON.stringify({
|
|
3465
|
+
requested_size_mib: requestedSizeMib
|
|
3466
|
+
}),
|
|
3467
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3468
|
+
}
|
|
3469
|
+
);
|
|
3470
|
+
if (response.status === 404) {
|
|
3471
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3472
|
+
}
|
|
3473
|
+
if (!response.ok) {
|
|
3474
|
+
throw await createRawApiError(response);
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
static async reset(sandboxId, opts) {
|
|
3478
|
+
var _a3;
|
|
3479
|
+
const config = new ConnectionConfig(opts);
|
|
3480
|
+
const response = await fetch(
|
|
3481
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/reset`,
|
|
3482
|
+
{
|
|
3483
|
+
method: "POST",
|
|
3484
|
+
headers: getRawApiHeaders(config, {
|
|
3485
|
+
"Content-Type": "application/json"
|
|
3486
|
+
}),
|
|
3487
|
+
body: JSON.stringify(__spreadValues({
|
|
3488
|
+
resume: (_a3 = opts == null ? void 0 : opts.resume) != null ? _a3 : true
|
|
3489
|
+
}, (opts == null ? void 0 : opts.timeoutMs) !== void 0 ? { timeout: timeoutToSeconds(opts.timeoutMs) } : {})),
|
|
3490
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3491
|
+
}
|
|
3492
|
+
);
|
|
3493
|
+
if (response.status === 404) {
|
|
3494
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3495
|
+
}
|
|
3496
|
+
if (response.status === 409) {
|
|
3497
|
+
return false;
|
|
3498
|
+
}
|
|
3499
|
+
if (!response.ok) {
|
|
3500
|
+
throw await createRawApiError(response);
|
|
3501
|
+
}
|
|
3502
|
+
return true;
|
|
3503
|
+
}
|
|
3504
|
+
static async mountVolume(sandboxId, name, path2, opts) {
|
|
3505
|
+
var _a3, _b;
|
|
3506
|
+
const config = new ConnectionConfig(opts);
|
|
3507
|
+
raiseIfLegacy(config, "Sandbox.mountVolume", SandboxError);
|
|
3508
|
+
const response = await fetch(
|
|
3509
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/volume-mounts`,
|
|
3510
|
+
{
|
|
3511
|
+
method: "POST",
|
|
3512
|
+
headers: getRawApiHeaders(config, {
|
|
3513
|
+
"Content-Type": "application/json"
|
|
3514
|
+
}),
|
|
3515
|
+
body: JSON.stringify({ name, path: path2 }),
|
|
3516
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3517
|
+
}
|
|
3518
|
+
);
|
|
3519
|
+
if (response.status === 404) {
|
|
3520
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3521
|
+
}
|
|
3522
|
+
if (!response.ok) {
|
|
3523
|
+
throw await createRawApiError(response);
|
|
3524
|
+
}
|
|
3525
|
+
const data = await response.json();
|
|
3526
|
+
return {
|
|
3527
|
+
sandboxId: data.sandboxID,
|
|
3528
|
+
templateId: data.templateID,
|
|
3529
|
+
name: data.name,
|
|
3530
|
+
metadata: (_a3 = data.metadata) != null ? _a3 : {},
|
|
3531
|
+
startedAt: new Date(data.startedAt),
|
|
3532
|
+
endAt: new Date(data.endAt),
|
|
3533
|
+
state: data.state,
|
|
3534
|
+
cpuCount: data.cpuCount,
|
|
3535
|
+
memoryMB: data.memoryMB,
|
|
3536
|
+
envdVersion: data.envdVersion,
|
|
3537
|
+
volumeMounts: (_b = data.volumeMounts) != null ? _b : []
|
|
3538
|
+
};
|
|
3539
|
+
}
|
|
3540
|
+
static async unmountVolume(sandboxId, path2, opts) {
|
|
3541
|
+
var _a3, _b;
|
|
3542
|
+
const config = new ConnectionConfig(opts);
|
|
3543
|
+
raiseIfLegacy(config, "Sandbox.unmountVolume", SandboxError);
|
|
3544
|
+
const url = new URL(
|
|
3545
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/volume-mounts`
|
|
3546
|
+
);
|
|
3547
|
+
url.searchParams.set("path", path2);
|
|
3548
|
+
if (opts == null ? void 0 : opts.force) {
|
|
3549
|
+
url.searchParams.set("force", "true");
|
|
3550
|
+
}
|
|
3551
|
+
const response = await fetch(url, {
|
|
3552
|
+
method: "DELETE",
|
|
3553
|
+
headers: getRawApiHeaders(config),
|
|
3554
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3555
|
+
});
|
|
3556
|
+
if (response.status === 404) {
|
|
3421
3557
|
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3422
3558
|
}
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
throw err;
|
|
3559
|
+
if (!response.ok) {
|
|
3560
|
+
throw await createRawApiError(response);
|
|
3426
3561
|
}
|
|
3562
|
+
const data = await response.json();
|
|
3563
|
+
return {
|
|
3564
|
+
sandboxId: data.sandboxID,
|
|
3565
|
+
templateId: data.templateID,
|
|
3566
|
+
name: data.name,
|
|
3567
|
+
metadata: (_a3 = data.metadata) != null ? _a3 : {},
|
|
3568
|
+
startedAt: new Date(data.startedAt),
|
|
3569
|
+
endAt: new Date(data.endAt),
|
|
3570
|
+
state: data.state,
|
|
3571
|
+
cpuCount: data.cpuCount,
|
|
3572
|
+
memoryMB: data.memoryMB,
|
|
3573
|
+
envdVersion: data.envdVersion,
|
|
3574
|
+
volumeMounts: (_b = data.volumeMounts) != null ? _b : []
|
|
3575
|
+
};
|
|
3427
3576
|
}
|
|
3428
|
-
static async
|
|
3577
|
+
static async setNetwork(sandboxId, opts) {
|
|
3578
|
+
const config = new ConnectionConfig(opts);
|
|
3579
|
+
raiseIfLegacy(config, "Sandbox.setNetwork", SandboxError);
|
|
3580
|
+
const response = await fetch(
|
|
3581
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/network`,
|
|
3582
|
+
{
|
|
3583
|
+
method: "PUT",
|
|
3584
|
+
headers: getRawApiHeaders(config, {
|
|
3585
|
+
"Content-Type": "application/json"
|
|
3586
|
+
}),
|
|
3587
|
+
body: JSON.stringify(__spreadValues(__spreadValues({}, (opts == null ? void 0 : opts.allowOut) ? { allowOut: opts.allowOut } : {}), (opts == null ? void 0 : opts.denyOut) ? { denyOut: opts.denyOut } : {})),
|
|
3588
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3589
|
+
}
|
|
3590
|
+
);
|
|
3591
|
+
if (response.status === 404) {
|
|
3592
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3593
|
+
}
|
|
3594
|
+
if (!response.ok) {
|
|
3595
|
+
throw await createRawApiError(response);
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
static async cloneSandboxes(sandboxId, opts) {
|
|
3429
3599
|
var _a3, _b, _c, _d;
|
|
3430
3600
|
const config = new ConnectionConfig(opts);
|
|
3601
|
+
const response = await fetch(
|
|
3602
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/clone`,
|
|
3603
|
+
{
|
|
3604
|
+
method: "POST",
|
|
3605
|
+
headers: getRawApiHeaders(config, {
|
|
3606
|
+
"Content-Type": "application/json"
|
|
3607
|
+
}),
|
|
3608
|
+
body: JSON.stringify(__spreadValues(__spreadValues({
|
|
3609
|
+
count: (_a3 = opts == null ? void 0 : opts.count) != null ? _a3 : 1,
|
|
3610
|
+
strict: (_b = opts == null ? void 0 : opts.strict) != null ? _b : false
|
|
3611
|
+
}, (opts == null ? void 0 : opts.nodeId) ? { nodeID: opts.nodeId } : {}), (opts == null ? void 0 : opts.timeoutMs) !== void 0 ? { timeout: timeoutToSeconds(opts.timeoutMs) } : {})),
|
|
3612
|
+
signal: config.getSignal((_c = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _c : 3e5)
|
|
3613
|
+
}
|
|
3614
|
+
);
|
|
3615
|
+
if (response.status === 404) {
|
|
3616
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3617
|
+
}
|
|
3618
|
+
if (!response.ok) {
|
|
3619
|
+
throw await createRawApiError(response);
|
|
3620
|
+
}
|
|
3621
|
+
const data = await response.json();
|
|
3622
|
+
return {
|
|
3623
|
+
sandboxes: ((_d = data.sandboxes) != null ? _d : []).map((sandbox) => {
|
|
3624
|
+
var _a4, _b2;
|
|
3625
|
+
const baseSandboxId = (_a4 = sandbox.sandboxID) != null ? _a4 : "";
|
|
3626
|
+
const sandboxId2 = sandbox.clientID ? `${baseSandboxId}-${sandbox.clientID}` : baseSandboxId;
|
|
3627
|
+
return {
|
|
3628
|
+
sandboxId: sandboxId2,
|
|
3629
|
+
envdVersion: (_b2 = sandbox.envdVersion) != null ? _b2 : "0.0.0",
|
|
3630
|
+
envdAccessToken: sandbox.envdAccessToken,
|
|
3631
|
+
trafficAccessToken: sandbox.trafficAccessToken
|
|
3632
|
+
};
|
|
3633
|
+
}),
|
|
3634
|
+
snapshotTemplateId: data.snapshotTemplateId
|
|
3635
|
+
};
|
|
3636
|
+
}
|
|
3637
|
+
static async getFullInfo(sandboxId, opts) {
|
|
3638
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3639
|
+
const config = new ConnectionConfig(opts);
|
|
3431
3640
|
const client = new ApiClient(config);
|
|
3432
3641
|
const res = await client.api.GET("/sandboxes/{sandboxID}", {
|
|
3433
3642
|
params: {
|
|
@@ -3447,12 +3656,29 @@ var SandboxApi = class {
|
|
|
3447
3656
|
if (!res.data) {
|
|
3448
3657
|
throw new Error("Sandbox not found");
|
|
3449
3658
|
}
|
|
3659
|
+
if (config.isLegacyDomain) {
|
|
3660
|
+
const data = res.data;
|
|
3661
|
+
return __spreadProps(__spreadValues({
|
|
3662
|
+
sandboxId: data.clientID != null ? `${data.sandboxID}-${data.clientID}` : data.sandboxID,
|
|
3663
|
+
templateId: data.templateID
|
|
3664
|
+
}, data.alias && { name: data.alias }), {
|
|
3665
|
+
metadata: (_b = data.metadata) != null ? _b : {},
|
|
3666
|
+
envdVersion: (_c = data.envdVersion) != null ? _c : "0.0.0",
|
|
3667
|
+
envdAccessToken: data.envdAccessToken,
|
|
3668
|
+
startedAt: new Date(data.startedAt),
|
|
3669
|
+
endAt: new Date(data.endAt),
|
|
3670
|
+
state: data.state,
|
|
3671
|
+
cpuCount: data.cpuCount,
|
|
3672
|
+
memoryMB: data.memoryMB,
|
|
3673
|
+
sandboxDomain: data.domain || void 0
|
|
3674
|
+
});
|
|
3675
|
+
}
|
|
3450
3676
|
return __spreadProps(__spreadValues({
|
|
3451
3677
|
sandboxId: res.data.sandboxID,
|
|
3452
3678
|
templateId: res.data.templateID
|
|
3453
3679
|
}, res.data.alias && { name: res.data.alias }), {
|
|
3454
|
-
metadata: (
|
|
3455
|
-
allowInternetAccess: (
|
|
3680
|
+
metadata: (_d = res.data.metadata) != null ? _d : {},
|
|
3681
|
+
allowInternetAccess: (_e = res.data.allowInternetAccess) != null ? _e : void 0,
|
|
3456
3682
|
envdVersion: res.data.envdVersion,
|
|
3457
3683
|
envdAccessToken: res.data.envdAccessToken,
|
|
3458
3684
|
startedAt: new Date(res.data.startedAt),
|
|
@@ -3471,7 +3697,7 @@ var SandboxApi = class {
|
|
|
3471
3697
|
autoResume: res.data.lifecycle.autoResume
|
|
3472
3698
|
} : void 0,
|
|
3473
3699
|
sandboxDomain: res.data.domain || void 0,
|
|
3474
|
-
volumeMounts: (
|
|
3700
|
+
volumeMounts: (_f = res.data.volumeMounts) != null ? _f : []
|
|
3475
3701
|
});
|
|
3476
3702
|
}
|
|
3477
3703
|
/**
|
|
@@ -3483,8 +3709,31 @@ var SandboxApi = class {
|
|
|
3483
3709
|
* @returns `true` if the sandbox got paused, `false` if the sandbox was already paused.
|
|
3484
3710
|
*/
|
|
3485
3711
|
static async pause(sandboxId, opts) {
|
|
3486
|
-
var _a3, _b;
|
|
3712
|
+
var _a3, _b, _c;
|
|
3487
3713
|
const config = new ConnectionConfig(opts);
|
|
3714
|
+
if (config.isLegacyDomain) {
|
|
3715
|
+
const response = await fetch(
|
|
3716
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/pause`,
|
|
3717
|
+
{
|
|
3718
|
+
method: "POST",
|
|
3719
|
+
headers: getRawApiHeaders(config, {
|
|
3720
|
+
"Content-Type": "application/json"
|
|
3721
|
+
}),
|
|
3722
|
+
body: JSON.stringify({ sync: (_a3 = opts == null ? void 0 : opts.sync) != null ? _a3 : false }),
|
|
3723
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3724
|
+
}
|
|
3725
|
+
);
|
|
3726
|
+
if (response.status === 404) {
|
|
3727
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3728
|
+
}
|
|
3729
|
+
if (response.status === 409) {
|
|
3730
|
+
return false;
|
|
3731
|
+
}
|
|
3732
|
+
if (!response.ok) {
|
|
3733
|
+
throw await createRawApiError(response);
|
|
3734
|
+
}
|
|
3735
|
+
return true;
|
|
3736
|
+
}
|
|
3488
3737
|
const client = new ApiClient(config);
|
|
3489
3738
|
const res = await client.api.POST("/sandboxes/{sandboxID}/pause", {
|
|
3490
3739
|
params: {
|
|
@@ -3494,10 +3743,10 @@ var SandboxApi = class {
|
|
|
3494
3743
|
},
|
|
3495
3744
|
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3496
3745
|
});
|
|
3497
|
-
if (((
|
|
3746
|
+
if (((_b = res.error) == null ? void 0 : _b.code) === 404) {
|
|
3498
3747
|
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3499
3748
|
}
|
|
3500
|
-
if (((
|
|
3749
|
+
if (((_c = res.error) == null ? void 0 : _c.code) === 409) {
|
|
3501
3750
|
return false;
|
|
3502
3751
|
}
|
|
3503
3752
|
const err = handleApiError(res);
|
|
@@ -3527,6 +3776,7 @@ var SandboxApi = class {
|
|
|
3527
3776
|
static async createSnapshot(sandboxId, opts) {
|
|
3528
3777
|
var _a3;
|
|
3529
3778
|
const config = new ConnectionConfig(opts);
|
|
3779
|
+
raiseIfLegacy(config, "Sandbox.createSnapshot", SandboxError);
|
|
3530
3780
|
const client = new ApiClient(config);
|
|
3531
3781
|
const res = await client.api.POST("/sandboxes/{sandboxID}/snapshots", {
|
|
3532
3782
|
params: {
|
|
@@ -3588,22 +3838,69 @@ var SandboxApi = class {
|
|
|
3588
3838
|
return true;
|
|
3589
3839
|
}
|
|
3590
3840
|
static async createSandbox(template, timeoutMs, opts) {
|
|
3591
|
-
var _a3, _b, _c;
|
|
3841
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3592
3842
|
const config = new ConnectionConfig(opts);
|
|
3593
|
-
const client = new ApiClient(config);
|
|
3594
3843
|
const lifecycle = getLifecycle(opts);
|
|
3595
3844
|
const autoPause = lifecycle.onTimeout === "pause";
|
|
3596
3845
|
const autoResumeEnabled = lifecycle.onTimeout === "pause" ? (_a3 = lifecycle.autoResume) != null ? _a3 : false : void 0;
|
|
3597
|
-
|
|
3846
|
+
if (config.isLegacyDomain) {
|
|
3847
|
+
if (opts == null ? void 0 : opts.mcp) {
|
|
3848
|
+
raiseIfLegacy(config, "Sandbox.create mcp", SandboxError);
|
|
3849
|
+
}
|
|
3850
|
+
if (opts == null ? void 0 : opts.network) {
|
|
3851
|
+
raiseIfLegacy(config, "Sandbox.create network", SandboxError);
|
|
3852
|
+
}
|
|
3853
|
+
if (opts == null ? void 0 : opts.volumeMounts) {
|
|
3854
|
+
raiseIfLegacy(config, "Sandbox.create volumeMounts", SandboxError);
|
|
3855
|
+
}
|
|
3856
|
+
if (opts == null ? void 0 : opts.secretEnvs) {
|
|
3857
|
+
raiseIfLegacy(config, "Sandbox.create secretEnvs", SandboxError);
|
|
3858
|
+
}
|
|
3859
|
+
const body2 = __spreadValues({
|
|
3860
|
+
templateID: template,
|
|
3861
|
+
timeout: timeoutToSeconds(timeoutMs),
|
|
3862
|
+
metadata: (_b = opts == null ? void 0 : opts.metadata) != null ? _b : {},
|
|
3863
|
+
envVars: (_c = opts == null ? void 0 : opts.envs) != null ? _c : {},
|
|
3864
|
+
secure: (_d = opts == null ? void 0 : opts.secure) != null ? _d : false,
|
|
3865
|
+
autoPause: autoPause != null ? autoPause : false
|
|
3866
|
+
}, (opts == null ? void 0 : opts.nodeId) ? { nodeID: opts.nodeId } : {});
|
|
3867
|
+
const response = await fetch(`${config.apiUrl}/sandboxes`, {
|
|
3868
|
+
method: "POST",
|
|
3869
|
+
headers: getRawApiHeaders(config, {
|
|
3870
|
+
"Content-Type": "application/json"
|
|
3871
|
+
}),
|
|
3872
|
+
body: JSON.stringify(body2),
|
|
3873
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3874
|
+
});
|
|
3875
|
+
if (!response.ok) {
|
|
3876
|
+
throw await createRawApiError(response);
|
|
3877
|
+
}
|
|
3878
|
+
const data = await response.json();
|
|
3879
|
+
if (compareVersions4(data.envdVersion, "0.1.0") < 0) {
|
|
3880
|
+
await this.kill(data.sandboxID, opts);
|
|
3881
|
+
throw new TemplateError(
|
|
3882
|
+
"You need to update the template to use the new SDK. You can do this by running `ppio-sandbox template build` in the directory with the template."
|
|
3883
|
+
);
|
|
3884
|
+
}
|
|
3885
|
+
return {
|
|
3886
|
+
sandboxId: data.clientID ? `${data.sandboxID}-${data.clientID}` : data.sandboxID,
|
|
3887
|
+
sandboxDomain: data.domain || void 0,
|
|
3888
|
+
envdVersion: data.envdVersion,
|
|
3889
|
+
envdAccessToken: data.envdAccessToken,
|
|
3890
|
+
trafficAccessToken: void 0
|
|
3891
|
+
};
|
|
3892
|
+
}
|
|
3893
|
+
const client = new ApiClient(config);
|
|
3894
|
+
const body = __spreadValues(__spreadValues(__spreadValues({
|
|
3598
3895
|
templateID: template,
|
|
3599
3896
|
metadata: opts == null ? void 0 : opts.metadata,
|
|
3600
3897
|
mcp: opts == null ? void 0 : opts.mcp,
|
|
3601
3898
|
envVars: opts == null ? void 0 : opts.envs,
|
|
3602
3899
|
timeout: timeoutToSeconds(timeoutMs),
|
|
3603
|
-
secure: (
|
|
3604
|
-
allow_internet_access: (
|
|
3900
|
+
secure: (_e = opts == null ? void 0 : opts.secure) != null ? _e : true,
|
|
3901
|
+
allow_internet_access: (_f = opts == null ? void 0 : opts.allowInternetAccess) != null ? _f : true,
|
|
3605
3902
|
network: opts == null ? void 0 : opts.network
|
|
3606
|
-
}, autoPause !== void 0 ? { autoPause } : {}), autoResumeEnabled !== void 0 ? { autoResume: { enabled: autoResumeEnabled } } : {});
|
|
3903
|
+
}, (opts == null ? void 0 : opts.nodeId) ? { nodeID: opts.nodeId } : {}), autoPause !== void 0 ? { autoPause } : {}), autoResumeEnabled !== void 0 ? { autoResume: { enabled: autoResumeEnabled } } : {});
|
|
3607
3904
|
if (opts == null ? void 0 : opts.volumeMounts) {
|
|
3608
3905
|
body.volumeMounts = Object.entries(opts.volumeMounts).map(
|
|
3609
3906
|
([mountPath, vol]) => ({
|
|
@@ -3612,6 +3909,14 @@ var SandboxApi = class {
|
|
|
3612
3909
|
})
|
|
3613
3910
|
);
|
|
3614
3911
|
}
|
|
3912
|
+
const validatedSecretEnvs = validateSecretEnvs(
|
|
3913
|
+
opts == null ? void 0 : opts.secretEnvs,
|
|
3914
|
+
opts == null ? void 0 : opts.envs
|
|
3915
|
+
);
|
|
3916
|
+
if (Object.keys(validatedSecretEnvs).length > 0) {
|
|
3917
|
+
;
|
|
3918
|
+
body.secrets = validatedSecretEnvs;
|
|
3919
|
+
}
|
|
3615
3920
|
const res = await client.api.POST("/sandboxes", {
|
|
3616
3921
|
body,
|
|
3617
3922
|
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
@@ -3638,6 +3943,33 @@ var SandboxApi = class {
|
|
|
3638
3943
|
var _a3, _b;
|
|
3639
3944
|
const timeoutMs = (_a3 = opts == null ? void 0 : opts.timeoutMs) != null ? _a3 : DEFAULT_SANDBOX_TIMEOUT_MS;
|
|
3640
3945
|
const config = new ConnectionConfig(opts);
|
|
3946
|
+
if (config.isLegacyDomain) {
|
|
3947
|
+
const response = await fetch(
|
|
3948
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/connect`,
|
|
3949
|
+
{
|
|
3950
|
+
method: "POST",
|
|
3951
|
+
headers: getRawApiHeaders(config, {
|
|
3952
|
+
"Content-Type": "application/json"
|
|
3953
|
+
}),
|
|
3954
|
+
body: JSON.stringify({ timeout: timeoutToSeconds(timeoutMs) }),
|
|
3955
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3956
|
+
}
|
|
3957
|
+
);
|
|
3958
|
+
if (response.status === 404) {
|
|
3959
|
+
throw new SandboxNotFoundError(`Paused sandbox ${sandboxId} not found`);
|
|
3960
|
+
}
|
|
3961
|
+
if (!response.ok) {
|
|
3962
|
+
throw await createRawApiError(response);
|
|
3963
|
+
}
|
|
3964
|
+
const data = await response.json();
|
|
3965
|
+
return {
|
|
3966
|
+
sandboxId: data.clientID ? `${data.sandboxID}-${data.clientID}` : data.sandboxID,
|
|
3967
|
+
sandboxDomain: data.domain || void 0,
|
|
3968
|
+
envdVersion: data.envdVersion || "0.0.0",
|
|
3969
|
+
envdAccessToken: data.envdAccessToken,
|
|
3970
|
+
trafficAccessToken: void 0
|
|
3971
|
+
};
|
|
3972
|
+
}
|
|
3641
3973
|
const client = new ApiClient(config);
|
|
3642
3974
|
const res = await client.api.POST("/sandboxes/{sandboxID}/connect", {
|
|
3643
3975
|
params: {
|
|
@@ -3665,6 +3997,69 @@ var SandboxApi = class {
|
|
|
3665
3997
|
trafficAccessToken: res.data.trafficAccessToken || void 0
|
|
3666
3998
|
};
|
|
3667
3999
|
}
|
|
4000
|
+
static async getQuota(opts) {
|
|
4001
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
|
|
4002
|
+
const config = new ConnectionConfig(opts);
|
|
4003
|
+
const url = new URL(`${config.apiUrl}/sandboxes/quota`);
|
|
4004
|
+
const response = await fetch(url, {
|
|
4005
|
+
method: "GET",
|
|
4006
|
+
headers: __spreadValues(__spreadValues(__spreadValues({}, config.headers), config.apiKey ? { "X-API-KEY": config.apiKey } : {}), config.accessToken ? { Authorization: `Bearer ${config.accessToken}` } : {}),
|
|
4007
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
4008
|
+
});
|
|
4009
|
+
if (!response.ok) {
|
|
4010
|
+
throw await createRawApiError(response);
|
|
4011
|
+
}
|
|
4012
|
+
const data = await response.json();
|
|
4013
|
+
return {
|
|
4014
|
+
limit: {
|
|
4015
|
+
concurrentInstances: (_b = (_a3 = data.limit) == null ? void 0 : _a3.concurrentInstances) != null ? _b : 0,
|
|
4016
|
+
concurrentVcpu: (_d = (_c = data.limit) == null ? void 0 : _c.concurrentVcpu) != null ? _d : 0,
|
|
4017
|
+
concurrentRamMb: (_f = (_e = data.limit) == null ? void 0 : _e.concurrentRamMb) != null ? _f : 0,
|
|
4018
|
+
maxLengthHours: (_h = (_g = data.limit) == null ? void 0 : _g.maxLengthHours) != null ? _h : 0,
|
|
4019
|
+
diskMb: (_j = (_i = data.limit) == null ? void 0 : _i.diskMb) != null ? _j : 0,
|
|
4020
|
+
maxVcpu: (_l = (_k = data.limit) == null ? void 0 : _k.maxVcpu) != null ? _l : 0,
|
|
4021
|
+
maxRamMb: (_n = (_m = data.limit) == null ? void 0 : _m.maxRamMb) != null ? _n : 0
|
|
4022
|
+
},
|
|
4023
|
+
usage: {
|
|
4024
|
+
concurrentInstances: (_p = (_o = data.usage) == null ? void 0 : _o.concurrentInstances) != null ? _p : 0,
|
|
4025
|
+
concurrentVcpu: (_r = (_q = data.usage) == null ? void 0 : _q.concurrentVcpu) != null ? _r : 0,
|
|
4026
|
+
concurrentRamMb: (_t = (_s = data.usage) == null ? void 0 : _s.concurrentRamMb) != null ? _t : 0
|
|
4027
|
+
}
|
|
4028
|
+
};
|
|
4029
|
+
}
|
|
4030
|
+
static async getEvents(opts) {
|
|
4031
|
+
var _a3, _b, _c;
|
|
4032
|
+
const config = new ConnectionConfig(opts);
|
|
4033
|
+
const url = new URL(`${config.apiUrl}/sandboxes/events`);
|
|
4034
|
+
if ((opts == null ? void 0 : opts.startTime) !== void 0)
|
|
4035
|
+
url.searchParams.set("startTime", String(opts.startTime));
|
|
4036
|
+
if ((opts == null ? void 0 : opts.endTime) !== void 0)
|
|
4037
|
+
url.searchParams.set("endTime", String(opts.endTime));
|
|
4038
|
+
if (opts == null ? void 0 : opts.sandboxID) url.searchParams.set("sandboxID", opts.sandboxID);
|
|
4039
|
+
if (opts == null ? void 0 : opts.templateID) url.searchParams.set("templateID", opts.templateID);
|
|
4040
|
+
if (opts == null ? void 0 : opts.events) url.searchParams.set("events", opts.events);
|
|
4041
|
+
if (opts == null ? void 0 : opts.state) url.searchParams.set("state", opts.state);
|
|
4042
|
+
if ((opts == null ? void 0 : opts.orderAsc) !== void 0)
|
|
4043
|
+
url.searchParams.set("orderAsc", String(opts.orderAsc));
|
|
4044
|
+
if ((opts == null ? void 0 : opts.offset) !== void 0)
|
|
4045
|
+
url.searchParams.set("offset", String(opts.offset));
|
|
4046
|
+
if ((opts == null ? void 0 : opts.limit) !== void 0)
|
|
4047
|
+
url.searchParams.set("limit", String(opts.limit));
|
|
4048
|
+
const response = await fetch(url, {
|
|
4049
|
+
method: "GET",
|
|
4050
|
+
headers: __spreadValues(__spreadValues(__spreadValues({}, config.headers), config.apiKey ? { "X-API-KEY": config.apiKey } : {}), config.accessToken ? { Authorization: `Bearer ${config.accessToken}` } : {}),
|
|
4051
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
4052
|
+
});
|
|
4053
|
+
if (!response.ok) {
|
|
4054
|
+
throw await createRawApiError(response);
|
|
4055
|
+
}
|
|
4056
|
+
const data = await response.json();
|
|
4057
|
+
return {
|
|
4058
|
+
items: (_a3 = data.items) != null ? _a3 : [],
|
|
4059
|
+
total: (_b = data.total) != null ? _b : 0,
|
|
4060
|
+
hasMore: (_c = data.hasMore) != null ? _c : false
|
|
4061
|
+
};
|
|
4062
|
+
}
|
|
3668
4063
|
};
|
|
3669
4064
|
var BasePaginator = class {
|
|
3670
4065
|
constructor(config, limit, nextToken) {
|
|
@@ -3697,7 +4092,7 @@ var SandboxPaginator = class extends BasePaginator {
|
|
|
3697
4092
|
this.query = opts == null ? void 0 : opts.query;
|
|
3698
4093
|
}
|
|
3699
4094
|
async nextItems() {
|
|
3700
|
-
var _a3, _b, _c;
|
|
4095
|
+
var _a3, _b, _c, _d, _e;
|
|
3701
4096
|
if (!this.hasNext) {
|
|
3702
4097
|
throw new Error("No more items to fetch");
|
|
3703
4098
|
}
|
|
@@ -3711,11 +4106,55 @@ var SandboxPaginator = class extends BasePaginator {
|
|
|
3711
4106
|
);
|
|
3712
4107
|
metadata = new URLSearchParams(encodedPairs).toString();
|
|
3713
4108
|
}
|
|
4109
|
+
if (this.config.isLegacyDomain) {
|
|
4110
|
+
const params = new URLSearchParams();
|
|
4111
|
+
if (metadata) {
|
|
4112
|
+
params.set("metadata", metadata);
|
|
4113
|
+
}
|
|
4114
|
+
if ((_c = (_b = this.query) == null ? void 0 : _b.state) == null ? void 0 : _c.length) {
|
|
4115
|
+
params.set("state", this.query.state.join(","));
|
|
4116
|
+
}
|
|
4117
|
+
if (this.limit) {
|
|
4118
|
+
params.set("limit", String(this.limit));
|
|
4119
|
+
}
|
|
4120
|
+
if (this.nextToken) {
|
|
4121
|
+
params.set("nextToken", this.nextToken);
|
|
4122
|
+
}
|
|
4123
|
+
const query = params.toString();
|
|
4124
|
+
const response = await fetch(
|
|
4125
|
+
`${this.config.apiUrl}/v2/sandboxes${query ? `?${query}` : ""}`,
|
|
4126
|
+
{
|
|
4127
|
+
headers: getRawApiHeaders(this.config),
|
|
4128
|
+
signal: this.config.getSignal()
|
|
4129
|
+
}
|
|
4130
|
+
);
|
|
4131
|
+
if (!response.ok) {
|
|
4132
|
+
throw await createRawApiError(response);
|
|
4133
|
+
}
|
|
4134
|
+
this.updatePagination(response);
|
|
4135
|
+
const data = await response.json();
|
|
4136
|
+
return (data != null ? data : []).map((sandbox) => {
|
|
4137
|
+
var _a4, _b2;
|
|
4138
|
+
return __spreadProps(__spreadValues({
|
|
4139
|
+
sandboxId: sandbox.clientID != null ? `${sandbox.sandboxID}-${sandbox.clientID}` : sandbox.sandboxID,
|
|
4140
|
+
templateId: sandbox.templateID
|
|
4141
|
+
}, sandbox.alias && { name: sandbox.alias }), {
|
|
4142
|
+
metadata: (_a4 = sandbox.metadata) != null ? _a4 : {},
|
|
4143
|
+
startedAt: new Date(sandbox.startedAt),
|
|
4144
|
+
endAt: new Date(sandbox.endAt),
|
|
4145
|
+
state: sandbox.state,
|
|
4146
|
+
cpuCount: sandbox.cpuCount,
|
|
4147
|
+
memoryMB: sandbox.memoryMB,
|
|
4148
|
+
envdVersion: sandbox.envdVersion,
|
|
4149
|
+
volumeMounts: (_b2 = sandbox.volumeMounts) != null ? _b2 : []
|
|
4150
|
+
});
|
|
4151
|
+
});
|
|
4152
|
+
}
|
|
3714
4153
|
const res = await this.client.api.GET("/v2/sandboxes", {
|
|
3715
4154
|
params: {
|
|
3716
4155
|
query: {
|
|
3717
4156
|
metadata,
|
|
3718
|
-
state: (
|
|
4157
|
+
state: (_d = this.query) == null ? void 0 : _d.state,
|
|
3719
4158
|
limit: this.limit,
|
|
3720
4159
|
nextToken: this.nextToken
|
|
3721
4160
|
}
|
|
@@ -3728,11 +4167,11 @@ var SandboxPaginator = class extends BasePaginator {
|
|
|
3728
4167
|
throw err;
|
|
3729
4168
|
}
|
|
3730
4169
|
this.updatePagination(res.response);
|
|
3731
|
-
return ((
|
|
4170
|
+
return ((_e = res.data) != null ? _e : []).map(
|
|
3732
4171
|
(sandbox) => {
|
|
3733
4172
|
var _a4, _b2;
|
|
3734
4173
|
return __spreadProps(__spreadValues({
|
|
3735
|
-
sandboxId: sandbox.sandboxID,
|
|
4174
|
+
sandboxId: this.config.isLegacyDomain && sandbox.clientID != null ? `${sandbox.sandboxID}-${sandbox.clientID}` : sandbox.sandboxID,
|
|
3736
4175
|
templateId: sandbox.templateID
|
|
3737
4176
|
}, sandbox.alias && { name: sandbox.alias }), {
|
|
3738
4177
|
metadata: (_a4 = sandbox.metadata) != null ? _a4 : {},
|
|
@@ -3751,6 +4190,7 @@ var SandboxPaginator = class extends BasePaginator {
|
|
|
3751
4190
|
var SnapshotPaginator = class extends BasePaginator {
|
|
3752
4191
|
constructor(opts) {
|
|
3753
4192
|
super(new ConnectionConfig(opts), opts == null ? void 0 : opts.limit, opts == null ? void 0 : opts.nextToken);
|
|
4193
|
+
raiseIfLegacy(this.config, "Sandbox.listSnapshots", SandboxError);
|
|
3754
4194
|
this.sandboxId = opts == null ? void 0 : opts.sandboxId;
|
|
3755
4195
|
}
|
|
3756
4196
|
async nextItems() {
|
|
@@ -3890,7 +4330,7 @@ var Sandbox = class extends SandboxApi {
|
|
|
3890
4330
|
sandboxOpts
|
|
3891
4331
|
);
|
|
3892
4332
|
const sandbox = new this(__spreadValues(__spreadValues({}, sandboxInfo), config));
|
|
3893
|
-
if (sandboxOpts == null ? void 0 : sandboxOpts.mcp) {
|
|
4333
|
+
if ((sandboxOpts == null ? void 0 : sandboxOpts.mcp) && !config.isLegacyDomain) {
|
|
3894
4334
|
sandbox.mcpToken = crypto.randomUUID();
|
|
3895
4335
|
const res = await sandbox.commands.run(
|
|
3896
4336
|
`mcp-gateway --config ${shellQuote(JSON.stringify(sandboxOpts.mcp))}`,
|
|
@@ -3907,6 +4347,101 @@ var Sandbox = class extends SandboxApi {
|
|
|
3907
4347
|
}
|
|
3908
4348
|
return sandbox;
|
|
3909
4349
|
}
|
|
4350
|
+
/**
|
|
4351
|
+
* Clone a sandbox to create one or more identical sandboxes.
|
|
4352
|
+
*
|
|
4353
|
+
* @param sandboxId source sandbox ID.
|
|
4354
|
+
* @param opts clone options.
|
|
4355
|
+
*
|
|
4356
|
+
* @returns cloned sandbox instances plus snapshot template ID.
|
|
4357
|
+
*/
|
|
4358
|
+
static async clone(sandboxId, opts) {
|
|
4359
|
+
const cloneResult = await SandboxApi.cloneSandboxes(sandboxId, opts);
|
|
4360
|
+
const config = new ConnectionConfig(opts);
|
|
4361
|
+
const sandboxes = cloneResult.sandboxes.map(
|
|
4362
|
+
(sandbox) => new this(__spreadValues({
|
|
4363
|
+
sandboxId: sandbox.sandboxId,
|
|
4364
|
+
envdVersion: sandbox.envdVersion,
|
|
4365
|
+
envdAccessToken: sandbox.envdAccessToken,
|
|
4366
|
+
trafficAccessToken: sandbox.trafficAccessToken
|
|
4367
|
+
}, config))
|
|
4368
|
+
);
|
|
4369
|
+
return {
|
|
4370
|
+
sandboxes,
|
|
4371
|
+
count: sandboxes.length,
|
|
4372
|
+
snapshotTemplateId: cloneResult.snapshotTemplateId
|
|
4373
|
+
};
|
|
4374
|
+
}
|
|
4375
|
+
/**
|
|
4376
|
+
* Dynamically adjust the hotplugged memory on a running sandbox.
|
|
4377
|
+
*
|
|
4378
|
+
* The value represents the new *total* plugged size in MiB, not a delta.
|
|
4379
|
+
* Use `0` to unplug all hotplugged memory.
|
|
4380
|
+
*/
|
|
4381
|
+
static async hotplugMemory(sandboxId, requestedSizeMib, opts) {
|
|
4382
|
+
return await SandboxApi.hotplugMemory(
|
|
4383
|
+
sandboxId,
|
|
4384
|
+
requestedSizeMib,
|
|
4385
|
+
opts
|
|
4386
|
+
);
|
|
4387
|
+
}
|
|
4388
|
+
/**
|
|
4389
|
+
* Mount a volume to a sandbox.
|
|
4390
|
+
*
|
|
4391
|
+
* @param sandboxId sandbox ID.
|
|
4392
|
+
* @param name volume name.
|
|
4393
|
+
* @param path mount path inside the sandbox.
|
|
4394
|
+
* @param opts connection options.
|
|
4395
|
+
*
|
|
4396
|
+
* @returns updated sandbox information.
|
|
4397
|
+
*/
|
|
4398
|
+
static async mountVolume(sandboxId, name, path2, opts) {
|
|
4399
|
+
return await SandboxApi.mountVolume(sandboxId, name, path2, opts);
|
|
4400
|
+
}
|
|
4401
|
+
/**
|
|
4402
|
+
* Unmount a volume from a sandbox.
|
|
4403
|
+
*
|
|
4404
|
+
* @param sandboxId sandbox ID.
|
|
4405
|
+
* @param path mount path to unmount.
|
|
4406
|
+
* @param opts connection options.
|
|
4407
|
+
* @param [opts.force] force unmount.
|
|
4408
|
+
*
|
|
4409
|
+
* @returns updated sandbox information.
|
|
4410
|
+
*/
|
|
4411
|
+
static async unmountVolume(sandboxId, path2, opts) {
|
|
4412
|
+
return await SandboxApi.unmountVolume(sandboxId, path2, opts);
|
|
4413
|
+
}
|
|
4414
|
+
/**
|
|
4415
|
+
* Commit a sandbox to create a snapshot template.
|
|
4416
|
+
*
|
|
4417
|
+
* @deprecated Use snapshot APIs instead. This method is only supported for modern domains.
|
|
4418
|
+
*
|
|
4419
|
+
* @param sandboxId source sandbox ID.
|
|
4420
|
+
* @param opts commit options.
|
|
4421
|
+
*
|
|
4422
|
+
* @returns created snapshot template.
|
|
4423
|
+
*/
|
|
4424
|
+
static async commit(sandboxId, opts) {
|
|
4425
|
+
return await SandboxApi.commit(sandboxId, opts);
|
|
4426
|
+
}
|
|
4427
|
+
/**
|
|
4428
|
+
* Reset sandbox memory and optionally resume the sandbox.
|
|
4429
|
+
*
|
|
4430
|
+
* @param sandboxId sandbox ID.
|
|
4431
|
+
* @param opts reset options.
|
|
4432
|
+
*
|
|
4433
|
+
* @returns `true` if reset succeeded, `false` if the sandbox is in a conflicting state.
|
|
4434
|
+
*/
|
|
4435
|
+
static async reset(sandboxId, opts) {
|
|
4436
|
+
return await SandboxApi.reset(sandboxId, opts);
|
|
4437
|
+
}
|
|
4438
|
+
/**
|
|
4439
|
+
* Update network egress rules for a running sandbox.
|
|
4440
|
+
* Omitting both `allowOut` and `denyOut` clears all egress rules.
|
|
4441
|
+
*/
|
|
4442
|
+
static async setNetwork(sandboxId, opts) {
|
|
4443
|
+
await SandboxApi.setNetwork(sandboxId, opts);
|
|
4444
|
+
}
|
|
3910
4445
|
static async betaCreate(templateOrOpts, opts) {
|
|
3911
4446
|
var _a3, _b, _c;
|
|
3912
4447
|
const { template, sandboxOpts } = typeof templateOrOpts === "string" ? {
|
|
@@ -3929,7 +4464,7 @@ var Sandbox = class extends SandboxApi {
|
|
|
3929
4464
|
sandboxOpts
|
|
3930
4465
|
);
|
|
3931
4466
|
const sandbox = new this(__spreadValues(__spreadValues({}, sandboxInfo), config));
|
|
3932
|
-
if (sandboxOpts == null ? void 0 : sandboxOpts.mcp) {
|
|
4467
|
+
if ((sandboxOpts == null ? void 0 : sandboxOpts.mcp) && !config.isLegacyDomain) {
|
|
3933
4468
|
sandbox.mcpToken = crypto.randomUUID();
|
|
3934
4469
|
const res = await sandbox.commands.run(
|
|
3935
4470
|
`mcp-gateway --config ${shellQuote(JSON.stringify(sandboxOpts.mcp))}`,
|
|
@@ -4071,6 +4606,68 @@ var Sandbox = class extends SandboxApi {
|
|
|
4071
4606
|
this.resolveApiOpts(opts)
|
|
4072
4607
|
);
|
|
4073
4608
|
}
|
|
4609
|
+
/**
|
|
4610
|
+
* Reset sandbox memory and optionally resume the sandbox.
|
|
4611
|
+
*
|
|
4612
|
+
* @param opts reset options.
|
|
4613
|
+
*
|
|
4614
|
+
* @returns `true` if reset succeeded, `false` if the sandbox is in a conflicting state.
|
|
4615
|
+
*/
|
|
4616
|
+
async reset(opts) {
|
|
4617
|
+
return await SandboxApi.reset(this.sandboxId, this.resolveApiOpts(opts));
|
|
4618
|
+
}
|
|
4619
|
+
/**
|
|
4620
|
+
* Update network egress rules for this running sandbox.
|
|
4621
|
+
* Omitting both `allowOut` and `denyOut` clears all egress rules.
|
|
4622
|
+
*/
|
|
4623
|
+
async setNetwork(opts) {
|
|
4624
|
+
await SandboxApi.setNetwork(this.sandboxId, this.resolveApiOpts(opts));
|
|
4625
|
+
}
|
|
4626
|
+
/**
|
|
4627
|
+
* Commit this sandbox to create a snapshot template.
|
|
4628
|
+
*
|
|
4629
|
+
* @deprecated Use snapshot APIs instead. This method is only supported for modern domains.
|
|
4630
|
+
*
|
|
4631
|
+
* @param opts commit options.
|
|
4632
|
+
*
|
|
4633
|
+
* @returns created snapshot template.
|
|
4634
|
+
*/
|
|
4635
|
+
async commit(opts) {
|
|
4636
|
+
return await SandboxApi.commit(this.sandboxId, this.resolveApiOpts(opts));
|
|
4637
|
+
}
|
|
4638
|
+
/**
|
|
4639
|
+
* Mount a volume to this sandbox.
|
|
4640
|
+
*
|
|
4641
|
+
* @param name volume name.
|
|
4642
|
+
* @param path mount path inside the sandbox.
|
|
4643
|
+
* @param opts connection options.
|
|
4644
|
+
*
|
|
4645
|
+
* @returns updated sandbox information.
|
|
4646
|
+
*/
|
|
4647
|
+
async mountVolume(name, path2, opts) {
|
|
4648
|
+
return await SandboxApi.mountVolume(
|
|
4649
|
+
this.sandboxId,
|
|
4650
|
+
name,
|
|
4651
|
+
path2,
|
|
4652
|
+
this.resolveApiOpts(opts)
|
|
4653
|
+
);
|
|
4654
|
+
}
|
|
4655
|
+
/**
|
|
4656
|
+
* Unmount a volume from this sandbox.
|
|
4657
|
+
*
|
|
4658
|
+
* @param path mount path to unmount.
|
|
4659
|
+
* @param opts connection options.
|
|
4660
|
+
* @param [opts.force] force unmount.
|
|
4661
|
+
*
|
|
4662
|
+
* @returns updated sandbox information.
|
|
4663
|
+
*/
|
|
4664
|
+
async unmountVolume(path2, opts) {
|
|
4665
|
+
return await SandboxApi.unmountVolume(
|
|
4666
|
+
this.sandboxId,
|
|
4667
|
+
path2,
|
|
4668
|
+
this.resolveApiOpts(opts)
|
|
4669
|
+
);
|
|
4670
|
+
}
|
|
4074
4671
|
/**
|
|
4075
4672
|
* Kill the sandbox.
|
|
4076
4673
|
*
|
|
@@ -4082,6 +4679,22 @@ var Sandbox = class extends SandboxApi {
|
|
|
4082
4679
|
}
|
|
4083
4680
|
await SandboxApi.kill(this.sandboxId, this.resolveApiOpts(opts));
|
|
4084
4681
|
}
|
|
4682
|
+
/**
|
|
4683
|
+
* Dynamically adjust the hotplugged memory on a running sandbox.
|
|
4684
|
+
*
|
|
4685
|
+
* The value represents the new *total* plugged size in MiB, not a delta.
|
|
4686
|
+
* Use `0` to unplug all hotplugged memory.
|
|
4687
|
+
*
|
|
4688
|
+
* @param requestedSizeMib new total plugged memory size in MiB.
|
|
4689
|
+
* @param opts connection options.
|
|
4690
|
+
*/
|
|
4691
|
+
async hotplugMemory(requestedSizeMib, opts) {
|
|
4692
|
+
await SandboxApi.hotplugMemory(
|
|
4693
|
+
this.sandboxId,
|
|
4694
|
+
requestedSizeMib,
|
|
4695
|
+
this.resolveApiOpts(opts)
|
|
4696
|
+
);
|
|
4697
|
+
}
|
|
4085
4698
|
/**
|
|
4086
4699
|
* Pause a sandbox by its ID.
|
|
4087
4700
|
*
|
|
@@ -4102,7 +4715,10 @@ var Sandbox = class extends SandboxApi {
|
|
|
4102
4715
|
* @deprecated Use {@link Sandbox.pause} instead.
|
|
4103
4716
|
*/
|
|
4104
4717
|
async betaPause(opts) {
|
|
4105
|
-
return await SandboxApi.betaPause(
|
|
4718
|
+
return await SandboxApi.betaPause(
|
|
4719
|
+
this.sandboxId,
|
|
4720
|
+
this.resolveApiOpts(opts)
|
|
4721
|
+
);
|
|
4106
4722
|
}
|
|
4107
4723
|
/**
|
|
4108
4724
|
* Create a snapshot of the sandbox's current state.
|
|
@@ -4154,6 +4770,7 @@ var Sandbox = class extends SandboxApi {
|
|
|
4154
4770
|
* @returns MCP URL for the sandbox.
|
|
4155
4771
|
*/
|
|
4156
4772
|
getMcpUrl() {
|
|
4773
|
+
raiseIfLegacy(this.connectionConfig, "Sandbox.getMcpUrl", SandboxError);
|
|
4157
4774
|
return `https://${this.getHost(this.mcpPort)}/mcp`;
|
|
4158
4775
|
}
|
|
4159
4776
|
/**
|
|
@@ -4162,6 +4779,7 @@ var Sandbox = class extends SandboxApi {
|
|
|
4162
4779
|
* @returns MCP token for the sandbox, or undefined if MCP is not enabled.
|
|
4163
4780
|
*/
|
|
4164
4781
|
async getMcpToken() {
|
|
4782
|
+
raiseIfLegacy(this.connectionConfig, "Sandbox.getMcpToken", SandboxError);
|
|
4165
4783
|
if (!this.mcpToken) {
|
|
4166
4784
|
this.mcpToken = await this.files.read("/etc/mcp-gateway/.token", {
|
|
4167
4785
|
user: "root"
|
|
@@ -5117,6 +5735,123 @@ function handleCmdEntrypointInstruction(instruction, templateBuilder) {
|
|
|
5117
5735
|
}
|
|
5118
5736
|
|
|
5119
5737
|
// src/core/template/index.ts
|
|
5738
|
+
var TemplateApi = class {
|
|
5739
|
+
static async listTemplates(options) {
|
|
5740
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h;
|
|
5741
|
+
const templateType = (_a3 = options == null ? void 0 : options.templateType) != null ? _a3 : "template_build";
|
|
5742
|
+
const page = (_b = options == null ? void 0 : options.page) != null ? _b : 1;
|
|
5743
|
+
const limit = (_c = options == null ? void 0 : options.limit) != null ? _c : 20;
|
|
5744
|
+
if (!["template_build", "snapshot_template"].includes(templateType)) {
|
|
5745
|
+
throw new Error(
|
|
5746
|
+
'templateType must be either "template_build" or "snapshot_template"'
|
|
5747
|
+
);
|
|
5748
|
+
}
|
|
5749
|
+
if (page < 1) {
|
|
5750
|
+
throw new Error("page must be >= 1");
|
|
5751
|
+
}
|
|
5752
|
+
if (limit < 1 || limit > 100) {
|
|
5753
|
+
throw new Error("limit must be between 1 and 100");
|
|
5754
|
+
}
|
|
5755
|
+
const config = new ConnectionConfig(options);
|
|
5756
|
+
const url = new URL(`${config.apiUrl}/v2/templates`);
|
|
5757
|
+
url.searchParams.set("template_type", templateType);
|
|
5758
|
+
url.searchParams.set("page", String(page));
|
|
5759
|
+
url.searchParams.set("limit", String(limit));
|
|
5760
|
+
const response = await fetch(url, {
|
|
5761
|
+
method: "GET",
|
|
5762
|
+
headers: __spreadValues(__spreadValues(__spreadValues({}, config.headers), config.apiKey ? { "X-API-KEY": config.apiKey } : {}), config.accessToken ? { Authorization: `Bearer ${config.accessToken}` } : {}),
|
|
5763
|
+
signal: config.getSignal(options == null ? void 0 : options.requestTimeoutMs)
|
|
5764
|
+
});
|
|
5765
|
+
if (!response.ok) {
|
|
5766
|
+
throw new Error(`${response.status}: ${await response.text()}`);
|
|
5767
|
+
}
|
|
5768
|
+
const data = await response.json();
|
|
5769
|
+
if (!data) {
|
|
5770
|
+
throw new Error("Template list response data is missing");
|
|
5771
|
+
}
|
|
5772
|
+
return {
|
|
5773
|
+
templates: ((_d = data.templates) != null ? _d : []).map(
|
|
5774
|
+
(template) => ({
|
|
5775
|
+
templateId: template.templateID,
|
|
5776
|
+
aliases: template.aliases,
|
|
5777
|
+
buildCount: template.buildCount,
|
|
5778
|
+
buildId: template.buildID,
|
|
5779
|
+
cpuCount: template.cpuCount,
|
|
5780
|
+
createdAt: new Date(template.createdAt),
|
|
5781
|
+
createdBy: template.createdBy,
|
|
5782
|
+
diskSizeMB: template.diskSizeMB,
|
|
5783
|
+
envdVersion: template.envdVersion,
|
|
5784
|
+
lastSpawnedAt: template.lastSpawnedAt ? new Date(template.lastSpawnedAt) : null,
|
|
5785
|
+
memoryMB: template.memoryMB,
|
|
5786
|
+
metadata: template.metadata,
|
|
5787
|
+
public: template.public,
|
|
5788
|
+
spawnCount: template.spawnCount,
|
|
5789
|
+
templateType: template.templateType,
|
|
5790
|
+
originSandboxID: template.originSandboxID,
|
|
5791
|
+
updatedAt: new Date(template.updatedAt)
|
|
5792
|
+
})
|
|
5793
|
+
),
|
|
5794
|
+
page: (_e = data.page) != null ? _e : page,
|
|
5795
|
+
limit: (_f = data.limit) != null ? _f : limit,
|
|
5796
|
+
total: (_g = data.total) != null ? _g : 0,
|
|
5797
|
+
totalPages: (_h = data.totalPages) != null ? _h : 0
|
|
5798
|
+
};
|
|
5799
|
+
}
|
|
5800
|
+
static async deleteTemplate(templateId, options) {
|
|
5801
|
+
var _a3;
|
|
5802
|
+
if (!templateId) {
|
|
5803
|
+
throw new Error("templateId cannot be empty");
|
|
5804
|
+
}
|
|
5805
|
+
const config = new ConnectionConfig(options);
|
|
5806
|
+
const client = new ApiClient(config);
|
|
5807
|
+
const res = await client.api.DELETE("/templates/{templateID}", {
|
|
5808
|
+
params: {
|
|
5809
|
+
path: {
|
|
5810
|
+
templateID: templateId
|
|
5811
|
+
}
|
|
5812
|
+
},
|
|
5813
|
+
signal: config.getSignal(options == null ? void 0 : options.requestTimeoutMs)
|
|
5814
|
+
});
|
|
5815
|
+
if (((_a3 = res.error) == null ? void 0 : _a3.code) === 404 || res.response.status === 404) {
|
|
5816
|
+
return false;
|
|
5817
|
+
}
|
|
5818
|
+
const err = handleApiError(res, BuildError);
|
|
5819
|
+
if (err) {
|
|
5820
|
+
throw err;
|
|
5821
|
+
}
|
|
5822
|
+
return true;
|
|
5823
|
+
}
|
|
5824
|
+
};
|
|
5825
|
+
var TemplatePaginator = class {
|
|
5826
|
+
constructor(options) {
|
|
5827
|
+
this.hasNextPage = true;
|
|
5828
|
+
var _a3;
|
|
5829
|
+
this.options = options;
|
|
5830
|
+
this.nextPageNumber = (_a3 = options == null ? void 0 : options.page) != null ? _a3 : 1;
|
|
5831
|
+
}
|
|
5832
|
+
get hasNext() {
|
|
5833
|
+
return this.hasNextPage;
|
|
5834
|
+
}
|
|
5835
|
+
get currentPage() {
|
|
5836
|
+
return this.nextPageNumber;
|
|
5837
|
+
}
|
|
5838
|
+
async nextPage() {
|
|
5839
|
+
if (!this.hasNextPage) {
|
|
5840
|
+
throw new Error("No more pages to fetch");
|
|
5841
|
+
}
|
|
5842
|
+
const response = await TemplateApi.listTemplates(__spreadProps(__spreadValues({}, this.options), {
|
|
5843
|
+
page: this.nextPageNumber
|
|
5844
|
+
}));
|
|
5845
|
+
this.hasNextPage = response.page < response.totalPages;
|
|
5846
|
+
this.nextPageNumber = response.page + 1;
|
|
5847
|
+
return response;
|
|
5848
|
+
}
|
|
5849
|
+
reset() {
|
|
5850
|
+
var _a3, _b;
|
|
5851
|
+
this.nextPageNumber = (_b = (_a3 = this.options) == null ? void 0 : _a3.page) != null ? _b : 1;
|
|
5852
|
+
this.hasNextPage = true;
|
|
5853
|
+
}
|
|
5854
|
+
};
|
|
5120
5855
|
var _a2;
|
|
5121
5856
|
var TemplateBase = class _TemplateBase {
|
|
5122
5857
|
constructor(options) {
|
|
@@ -5126,6 +5861,7 @@ var TemplateBase = class _TemplateBase {
|
|
|
5126
5861
|
this.registryConfig = void 0;
|
|
5127
5862
|
this.startCmd = void 0;
|
|
5128
5863
|
this.readyCmd = void 0;
|
|
5864
|
+
this.patchCmd = void 0;
|
|
5129
5865
|
// Force the whole template to be rebuilt
|
|
5130
5866
|
this.force = false;
|
|
5131
5867
|
// Force the next layer to be rebuilt
|
|
@@ -5141,6 +5877,9 @@ var TemplateBase = class _TemplateBase {
|
|
|
5141
5877
|
this.fileContextPath = (_a3 = options == null ? void 0 : options.fileContextPath) != null ? _a3 : this.fileContextPath;
|
|
5142
5878
|
this.fileIgnorePatterns = (_b = options == null ? void 0 : options.fileIgnorePatterns) != null ? _b : this.fileIgnorePatterns;
|
|
5143
5879
|
}
|
|
5880
|
+
static list(options) {
|
|
5881
|
+
return new TemplatePaginator(options);
|
|
5882
|
+
}
|
|
5144
5883
|
/**
|
|
5145
5884
|
* Convert a template to JSON representation.
|
|
5146
5885
|
*
|
|
@@ -5219,6 +5958,15 @@ var TemplateBase = class _TemplateBase {
|
|
|
5219
5958
|
logsOffset: options == null ? void 0 : options.logsOffset
|
|
5220
5959
|
});
|
|
5221
5960
|
}
|
|
5961
|
+
static async listTemplates(options) {
|
|
5962
|
+
return TemplateApi.listTemplates(options);
|
|
5963
|
+
}
|
|
5964
|
+
static async delete(templateId, options) {
|
|
5965
|
+
await TemplateApi.deleteTemplate(templateId, options);
|
|
5966
|
+
}
|
|
5967
|
+
static async deleteTemplate(templateId, options) {
|
|
5968
|
+
return TemplateApi.deleteTemplate(templateId, options);
|
|
5969
|
+
}
|
|
5222
5970
|
/**
|
|
5223
5971
|
* Check if a template with the given name exists.
|
|
5224
5972
|
*
|
|
@@ -5687,6 +6435,11 @@ var TemplateBase = class _TemplateBase {
|
|
|
5687
6435
|
this.collectStackTrace();
|
|
5688
6436
|
return this;
|
|
5689
6437
|
}
|
|
6438
|
+
setPatchCmd(cmd) {
|
|
6439
|
+
this.patchCmd = cmd;
|
|
6440
|
+
this.collectStackTrace();
|
|
6441
|
+
return this;
|
|
6442
|
+
}
|
|
5690
6443
|
setEnvs(envs) {
|
|
5691
6444
|
if (Object.keys(envs).length === 0) {
|
|
5692
6445
|
return this;
|
|
@@ -6012,6 +6765,7 @@ var TemplateBase = class _TemplateBase {
|
|
|
6012
6765
|
const templateData = {
|
|
6013
6766
|
startCmd: this.startCmd,
|
|
6014
6767
|
readyCmd: this.readyCmd,
|
|
6768
|
+
preBootScript: this.patchCmd,
|
|
6015
6769
|
steps,
|
|
6016
6770
|
force: this.force
|
|
6017
6771
|
};
|
|
@@ -6038,6 +6792,8 @@ Template.aliasExists = TemplateBase.aliasExists;
|
|
|
6038
6792
|
Template.assignTags = TemplateBase.assignTags;
|
|
6039
6793
|
Template.removeTags = TemplateBase.removeTags;
|
|
6040
6794
|
Template.getTags = TemplateBase.getTags;
|
|
6795
|
+
Template.list = TemplateBase.list;
|
|
6796
|
+
Template.delete = TemplateBase.delete;
|
|
6041
6797
|
Template.toJSON = TemplateBase.toJSON;
|
|
6042
6798
|
Template.toDockerfile = TemplateBase.toDockerfile;
|
|
6043
6799
|
|
|
@@ -6065,6 +6821,7 @@ export {
|
|
|
6065
6821
|
BuildError,
|
|
6066
6822
|
FileUploadError,
|
|
6067
6823
|
VolumeError,
|
|
6824
|
+
SecretError,
|
|
6068
6825
|
ApiClient,
|
|
6069
6826
|
ConnectionConfig,
|
|
6070
6827
|
getSignature,
|
|
@@ -6073,8 +6830,8 @@ export {
|
|
|
6073
6830
|
CommandExitError,
|
|
6074
6831
|
ALL_TRAFFIC,
|
|
6075
6832
|
Git,
|
|
6076
|
-
VolumeFileType,
|
|
6077
6833
|
Volume,
|
|
6834
|
+
Secret,
|
|
6078
6835
|
Sandbox,
|
|
6079
6836
|
LogEntry,
|
|
6080
6837
|
LogEntryStart,
|
|
@@ -6086,8 +6843,10 @@ export {
|
|
|
6086
6843
|
waitForProcess,
|
|
6087
6844
|
waitForFile,
|
|
6088
6845
|
waitForTimeout,
|
|
6846
|
+
TemplateApi,
|
|
6847
|
+
TemplatePaginator,
|
|
6089
6848
|
TemplateBase,
|
|
6090
6849
|
Template,
|
|
6091
6850
|
core_default
|
|
6092
6851
|
};
|
|
6093
|
-
//# sourceMappingURL=chunk-
|
|
6852
|
+
//# sourceMappingURL=chunk-V2Q62RZL.mjs.map
|