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
package/dist/code-interpreter.js
CHANGED
|
@@ -100,13 +100,16 @@ __export(code_interpreter_exports, {
|
|
|
100
100
|
Sandbox: () => Sandbox2,
|
|
101
101
|
SandboxError: () => SandboxError,
|
|
102
102
|
SandboxNotFoundError: () => SandboxNotFoundError,
|
|
103
|
+
Secret: () => Secret,
|
|
104
|
+
SecretError: () => SecretError,
|
|
103
105
|
Template: () => Template,
|
|
106
|
+
TemplateApi: () => TemplateApi,
|
|
104
107
|
TemplateBase: () => TemplateBase,
|
|
105
108
|
TemplateError: () => TemplateError,
|
|
109
|
+
TemplatePaginator: () => TemplatePaginator,
|
|
106
110
|
TimeoutError: () => TimeoutError,
|
|
107
111
|
Volume: () => Volume,
|
|
108
112
|
VolumeError: () => VolumeError,
|
|
109
|
-
VolumeFileType: () => VolumeFileType,
|
|
110
113
|
default: () => code_interpreter_default,
|
|
111
114
|
defaultBuildLogger: () => defaultBuildLogger,
|
|
112
115
|
getSignature: () => getSignature,
|
|
@@ -125,7 +128,7 @@ var import_openapi_fetch = __toESM(require("openapi-fetch"));
|
|
|
125
128
|
var import_platform2 = __toESM(require("platform"));
|
|
126
129
|
|
|
127
130
|
// package.json
|
|
128
|
-
var version = "2.0.
|
|
131
|
+
var version = "2.0.2-a1";
|
|
129
132
|
|
|
130
133
|
// src/core/utils.ts
|
|
131
134
|
var import_platform = __toESM(require("platform"));
|
|
@@ -333,6 +336,12 @@ var VolumeError = class extends Error {
|
|
|
333
336
|
this.name = "VolumeError";
|
|
334
337
|
}
|
|
335
338
|
};
|
|
339
|
+
var SecretError = class extends SandboxError {
|
|
340
|
+
constructor(message, stackTrace) {
|
|
341
|
+
super(message, stackTrace);
|
|
342
|
+
this.name = "SecretError";
|
|
343
|
+
}
|
|
344
|
+
};
|
|
336
345
|
|
|
337
346
|
// src/core/logs.ts
|
|
338
347
|
function formatLog(log) {
|
|
@@ -376,10 +385,10 @@ function createRpcLogger(logger) {
|
|
|
376
385
|
}
|
|
377
386
|
function createApiLogger(logger) {
|
|
378
387
|
return {
|
|
379
|
-
async onRequest({ request }) {
|
|
388
|
+
async onRequest({ request: request2 }) {
|
|
380
389
|
var _a3;
|
|
381
|
-
(_a3 = logger.info) == null ? void 0 : _a3.call(logger, `Request ${
|
|
382
|
-
return
|
|
390
|
+
(_a3 = logger.info) == null ? void 0 : _a3.call(logger, `Request ${request2.method} ${request2.url}`);
|
|
391
|
+
return request2;
|
|
383
392
|
},
|
|
384
393
|
async onResponse({ response }) {
|
|
385
394
|
var _a3, _b;
|
|
@@ -455,12 +464,27 @@ var REQUEST_TIMEOUT_MS = 6e4;
|
|
|
455
464
|
var DEFAULT_SANDBOX_TIMEOUT_MS = 3e5;
|
|
456
465
|
var KEEPALIVE_PING_INTERVAL_SEC = 50;
|
|
457
466
|
var KEEPALIVE_PING_HEADER = "Keepalive-Ping-Interval";
|
|
467
|
+
var LEGACY_DOMAINS = ["sandbox.ppio.cn", "cn-beijing-1.sandbox.ppio.com"];
|
|
468
|
+
function isLegacyDomain(domain) {
|
|
469
|
+
return domain ? LEGACY_DOMAINS.includes(domain) : true;
|
|
470
|
+
}
|
|
471
|
+
function raiseIfLegacy(config, feature, ErrorType = Error) {
|
|
472
|
+
if (config.isLegacyDomain) {
|
|
473
|
+
throw new ErrorType(`${feature} is not supported on legacy domains`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
function validateDomain(domain) {
|
|
477
|
+
if (!domain) {
|
|
478
|
+
throw new Error("Domain cannot be empty");
|
|
479
|
+
}
|
|
480
|
+
}
|
|
458
481
|
var _ConnectionConfig = class _ConnectionConfig {
|
|
459
482
|
constructor(opts) {
|
|
460
483
|
var _a3;
|
|
461
484
|
this.apiKey = (opts == null ? void 0 : opts.apiKey) || _ConnectionConfig.apiKey;
|
|
462
485
|
this.debug = (opts == null ? void 0 : opts.debug) || _ConnectionConfig.debug;
|
|
463
486
|
this.domain = (opts == null ? void 0 : opts.domain) || _ConnectionConfig.domain;
|
|
487
|
+
this.isLegacyDomain = isLegacyDomain(this.domain);
|
|
464
488
|
this.accessToken = (opts == null ? void 0 : opts.accessToken) || _ConnectionConfig.accessToken;
|
|
465
489
|
this.requestTimeoutMs = (_a3 = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _a3 : REQUEST_TIMEOUT_MS;
|
|
466
490
|
this.logger = opts == null ? void 0 : opts.logger;
|
|
@@ -861,6 +885,9 @@ var Filesystem2 = class {
|
|
|
861
885
|
return new Uint8Array(res.data);
|
|
862
886
|
}
|
|
863
887
|
if (res.response.headers.get("content-length") === "0") {
|
|
888
|
+
if (format === "blob") {
|
|
889
|
+
return new Blob([]);
|
|
890
|
+
}
|
|
864
891
|
return "";
|
|
865
892
|
}
|
|
866
893
|
return res.data;
|
|
@@ -2373,64 +2400,7 @@ var Git = class {
|
|
|
2373
2400
|
}
|
|
2374
2401
|
};
|
|
2375
2402
|
|
|
2376
|
-
// src/core/volume/client.ts
|
|
2377
|
-
var import_openapi_fetch3 = __toESM(require("openapi-fetch"));
|
|
2378
|
-
var FILE_TIMEOUT_MS = 36e5;
|
|
2379
|
-
var VolumeConnectionConfig = class _VolumeConnectionConfig {
|
|
2380
|
-
constructor(volume, opts) {
|
|
2381
|
-
var _a3, _b;
|
|
2382
|
-
this.domain = (opts == null ? void 0 : opts.domain) || volume.domain || _VolumeConnectionConfig.domain;
|
|
2383
|
-
this.debug = (_b = (_a3 = opts == null ? void 0 : opts.debug) != null ? _a3 : volume.debug) != null ? _b : _VolumeConnectionConfig.debug;
|
|
2384
|
-
this.apiUrl = (opts == null ? void 0 : opts.apiUrl) || _VolumeConnectionConfig.volumeApiUrl || (this.debug ? "http://localhost:8080" : `https://api.${this.domain}`);
|
|
2385
|
-
this.token = (opts == null ? void 0 : opts.token) || volume.token;
|
|
2386
|
-
this.headers = opts == null ? void 0 : opts.headers;
|
|
2387
|
-
this.logger = opts == null ? void 0 : opts.logger;
|
|
2388
|
-
this.requestTimeoutMs = opts == null ? void 0 : opts.requestTimeoutMs;
|
|
2389
|
-
}
|
|
2390
|
-
static get domain() {
|
|
2391
|
-
return getEnvVar("PPIO_DOMAIN") || "sandbox.ppio.cn";
|
|
2392
|
-
}
|
|
2393
|
-
static get debug() {
|
|
2394
|
-
return (getEnvVar("PPIO_DEBUG") || "false").toLowerCase() === "true";
|
|
2395
|
-
}
|
|
2396
|
-
static get volumeApiUrl() {
|
|
2397
|
-
return getEnvVar("PPIO_SANDBOX_VOLUME_API_URL");
|
|
2398
|
-
}
|
|
2399
|
-
getSignal(requestTimeoutMs) {
|
|
2400
|
-
const timeout = requestTimeoutMs != null ? requestTimeoutMs : this.requestTimeoutMs;
|
|
2401
|
-
return timeout ? AbortSignal.timeout(timeout) : void 0;
|
|
2402
|
-
}
|
|
2403
|
-
};
|
|
2404
|
-
var VolumeApiClient = class {
|
|
2405
|
-
constructor(config) {
|
|
2406
|
-
this.api = (0, import_openapi_fetch3.default)({
|
|
2407
|
-
baseUrl: config.apiUrl,
|
|
2408
|
-
headers: __spreadValues(__spreadValues(__spreadValues({}, defaultHeaders), config.token && { Authorization: `Bearer ${config.token}` }), config.headers)
|
|
2409
|
-
});
|
|
2410
|
-
if (config.logger) {
|
|
2411
|
-
this.api.use(createApiLogger(config.logger));
|
|
2412
|
-
}
|
|
2413
|
-
}
|
|
2414
|
-
};
|
|
2415
|
-
|
|
2416
|
-
// src/core/volume/types.ts
|
|
2417
|
-
var VolumeFileType = /* @__PURE__ */ ((VolumeFileType2) => {
|
|
2418
|
-
VolumeFileType2["UNKNOWN"] = "unknown";
|
|
2419
|
-
VolumeFileType2["FILE"] = "file";
|
|
2420
|
-
VolumeFileType2["DIRECTORY"] = "directory";
|
|
2421
|
-
VolumeFileType2["SYMLINK"] = "symlink";
|
|
2422
|
-
return VolumeFileType2;
|
|
2423
|
-
})(VolumeFileType || {});
|
|
2424
|
-
|
|
2425
2403
|
// src/core/volume/index.ts
|
|
2426
|
-
function convertVolumeEntryStat(entry) {
|
|
2427
|
-
return __spreadProps(__spreadValues({}, entry), {
|
|
2428
|
-
type: entry.type,
|
|
2429
|
-
atime: new Date(entry.atime),
|
|
2430
|
-
mtime: new Date(entry.mtime),
|
|
2431
|
-
ctime: new Date(entry.ctime)
|
|
2432
|
-
});
|
|
2433
|
-
}
|
|
2434
2404
|
var Volume = class _Volume {
|
|
2435
2405
|
/**
|
|
2436
2406
|
* Create a local Volume instance with no API call.
|
|
@@ -2442,6 +2412,9 @@ var Volume = class _Volume {
|
|
|
2442
2412
|
* @param debug whether to use debug mode.
|
|
2443
2413
|
*/
|
|
2444
2414
|
constructor(volumeId, name, token, domain, debug) {
|
|
2415
|
+
if (domain) {
|
|
2416
|
+
validateDomain(domain);
|
|
2417
|
+
}
|
|
2445
2418
|
this.volumeId = volumeId;
|
|
2446
2419
|
this.name = name;
|
|
2447
2420
|
this.token = token;
|
|
@@ -2453,15 +2426,20 @@ var Volume = class _Volume {
|
|
|
2453
2426
|
*
|
|
2454
2427
|
* @param name name of the volume.
|
|
2455
2428
|
* @param opts connection options.
|
|
2429
|
+
* @param [opts.quotaSizeGiB] capacity quota in GiB.
|
|
2430
|
+
* @param [opts.quotaInodes] inode quota.
|
|
2456
2431
|
*
|
|
2457
2432
|
* @returns new Volume instance.
|
|
2458
2433
|
*/
|
|
2459
2434
|
static async create(name, opts) {
|
|
2460
2435
|
const config = new ConnectionConfig(opts);
|
|
2436
|
+
raiseIfLegacy(config, "Volume.create", VolumeError);
|
|
2461
2437
|
const client = new ApiClient(config);
|
|
2462
2438
|
const res = await client.api.POST("/volumes", {
|
|
2463
2439
|
body: {
|
|
2464
|
-
name
|
|
2440
|
+
name,
|
|
2441
|
+
quotaSizeGiB: opts == null ? void 0 : opts.quotaSizeGiB,
|
|
2442
|
+
quotaInodes: opts == null ? void 0 : opts.quotaInodes
|
|
2465
2443
|
},
|
|
2466
2444
|
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2467
2445
|
});
|
|
@@ -2490,6 +2468,7 @@ var Volume = class _Volume {
|
|
|
2490
2468
|
*/
|
|
2491
2469
|
static async connect(volumeId, opts) {
|
|
2492
2470
|
const config = new ConnectionConfig(opts);
|
|
2471
|
+
raiseIfLegacy(config, "Volume.connect", VolumeError);
|
|
2493
2472
|
const { name, token } = await _Volume.getInfo(volumeId, opts);
|
|
2494
2473
|
return new _Volume(volumeId, name, token, config.domain, config.debug);
|
|
2495
2474
|
}
|
|
@@ -2502,7 +2481,9 @@ var Volume = class _Volume {
|
|
|
2502
2481
|
* @returns volume information.
|
|
2503
2482
|
*/
|
|
2504
2483
|
static async getInfo(volumeId, opts) {
|
|
2484
|
+
var _a3, _b, _c, _d;
|
|
2505
2485
|
const config = new ConnectionConfig(opts);
|
|
2486
|
+
raiseIfLegacy(config, "Volume.getInfo", VolumeError);
|
|
2506
2487
|
const client = new ApiClient(config);
|
|
2507
2488
|
const res = await client.api.GET("/volumes/{volumeID}", {
|
|
2508
2489
|
params: {
|
|
@@ -2519,10 +2500,15 @@ var Volume = class _Volume {
|
|
|
2519
2500
|
if (err) {
|
|
2520
2501
|
throw err;
|
|
2521
2502
|
}
|
|
2503
|
+
const data = res.data;
|
|
2522
2504
|
return {
|
|
2523
|
-
volumeId:
|
|
2524
|
-
name:
|
|
2525
|
-
token:
|
|
2505
|
+
volumeId: data.volumeID,
|
|
2506
|
+
name: data.name,
|
|
2507
|
+
token: data.token,
|
|
2508
|
+
quotaSizeGiB: (_a3 = data.quotaSizeGiB) != null ? _a3 : 0,
|
|
2509
|
+
quotaInodes: (_b = data.quotaInodes) != null ? _b : 0,
|
|
2510
|
+
usedSizeBytes: (_c = data.usedSizeBytes) != null ? _c : 0,
|
|
2511
|
+
usedInodes: (_d = data.usedInodes) != null ? _d : 0
|
|
2526
2512
|
};
|
|
2527
2513
|
}
|
|
2528
2514
|
/**
|
|
@@ -2535,6 +2521,7 @@ var Volume = class _Volume {
|
|
|
2535
2521
|
static async list(opts) {
|
|
2536
2522
|
var _a3;
|
|
2537
2523
|
const config = new ConnectionConfig(opts);
|
|
2524
|
+
raiseIfLegacy(config, "Volume.list", VolumeError);
|
|
2538
2525
|
const client = new ApiClient(config);
|
|
2539
2526
|
const res = await client.api.GET("/volumes", {
|
|
2540
2527
|
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
@@ -2543,10 +2530,61 @@ var Volume = class _Volume {
|
|
|
2543
2530
|
if (err) {
|
|
2544
2531
|
throw err;
|
|
2545
2532
|
}
|
|
2546
|
-
return ((_a3 = res.data) != null ? _a3 : []).map((vol) =>
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2533
|
+
return ((_a3 = res.data) != null ? _a3 : []).map((vol) => {
|
|
2534
|
+
var _a4, _b, _c, _d;
|
|
2535
|
+
return {
|
|
2536
|
+
volumeId: vol.volumeID,
|
|
2537
|
+
name: vol.name,
|
|
2538
|
+
quotaSizeGiB: (_a4 = vol.quotaSizeGiB) != null ? _a4 : 0,
|
|
2539
|
+
quotaInodes: (_b = vol.quotaInodes) != null ? _b : 0,
|
|
2540
|
+
usedSizeBytes: (_c = vol.usedSizeBytes) != null ? _c : 0,
|
|
2541
|
+
usedInodes: (_d = vol.usedInodes) != null ? _d : 0
|
|
2542
|
+
};
|
|
2543
|
+
});
|
|
2544
|
+
}
|
|
2545
|
+
/**
|
|
2546
|
+
* Update volume quota.
|
|
2547
|
+
*
|
|
2548
|
+
* @param volumeId volume ID.
|
|
2549
|
+
* @param params quota parameters.
|
|
2550
|
+
* @param opts connection options.
|
|
2551
|
+
*
|
|
2552
|
+
* @returns updated volume information.
|
|
2553
|
+
*/
|
|
2554
|
+
static async updateQuota(volumeId, params, opts) {
|
|
2555
|
+
var _a3, _b, _c, _d;
|
|
2556
|
+
const config = new ConnectionConfig(opts);
|
|
2557
|
+
raiseIfLegacy(config, "Volume.updateQuota", VolumeError);
|
|
2558
|
+
const res = await fetch(
|
|
2559
|
+
`${config.apiUrl}/volumes/${encodeURIComponent(volumeId)}`,
|
|
2560
|
+
{
|
|
2561
|
+
method: "PATCH",
|
|
2562
|
+
headers: __spreadValues(__spreadValues(__spreadProps(__spreadValues({}, config.headers), {
|
|
2563
|
+
"Content-Type": "application/json"
|
|
2564
|
+
}), config.apiKey ? { "X-API-KEY": config.apiKey } : {}), config.accessToken ? { Authorization: `Bearer ${config.accessToken}` } : {}),
|
|
2565
|
+
body: JSON.stringify({
|
|
2566
|
+
quotaSizeGiB: params.quotaSizeGiB,
|
|
2567
|
+
quotaInodes: params.quotaInodes
|
|
2568
|
+
}),
|
|
2569
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2570
|
+
}
|
|
2571
|
+
);
|
|
2572
|
+
if (res.status === 404) {
|
|
2573
|
+
throw new NotFoundError(`Volume ${volumeId} not found`);
|
|
2574
|
+
}
|
|
2575
|
+
if (!res.ok) {
|
|
2576
|
+
throw new VolumeError(`${res.status}: ${res.statusText}`);
|
|
2577
|
+
}
|
|
2578
|
+
const data = await res.json();
|
|
2579
|
+
return {
|
|
2580
|
+
volumeId: data.volumeID,
|
|
2581
|
+
name: data.name,
|
|
2582
|
+
token: data.token,
|
|
2583
|
+
quotaSizeGiB: (_a3 = data.quotaSizeGiB) != null ? _a3 : 0,
|
|
2584
|
+
quotaInodes: (_b = data.quotaInodes) != null ? _b : 0,
|
|
2585
|
+
usedSizeBytes: (_c = data.usedSizeBytes) != null ? _c : 0,
|
|
2586
|
+
usedInodes: (_d = data.usedInodes) != null ? _d : 0
|
|
2587
|
+
};
|
|
2550
2588
|
}
|
|
2551
2589
|
/**
|
|
2552
2590
|
* Destroy a volume.
|
|
@@ -2556,6 +2594,7 @@ var Volume = class _Volume {
|
|
|
2556
2594
|
*/
|
|
2557
2595
|
static async destroy(volumeId, opts) {
|
|
2558
2596
|
const config = new ConnectionConfig(opts);
|
|
2597
|
+
raiseIfLegacy(config, "Volume.destroy", VolumeError);
|
|
2559
2598
|
const client = new ApiClient(config);
|
|
2560
2599
|
const res = await client.api.DELETE("/volumes/{volumeID}", {
|
|
2561
2600
|
params: {
|
|
@@ -2574,296 +2613,196 @@ var Volume = class _Volume {
|
|
|
2574
2613
|
}
|
|
2575
2614
|
return true;
|
|
2576
2615
|
}
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
async list(path2, opts) {
|
|
2587
|
-
const config = new VolumeConnectionConfig(this, opts);
|
|
2588
|
-
const client = new VolumeApiClient(config);
|
|
2589
|
-
const res = await client.api.GET("/volumecontent/{volumeID}/dir", {
|
|
2590
|
-
params: {
|
|
2591
|
-
path: {
|
|
2592
|
-
volumeID: this.volumeId
|
|
2593
|
-
},
|
|
2594
|
-
query: {
|
|
2595
|
-
path: path2,
|
|
2596
|
-
depth: opts == null ? void 0 : opts.depth
|
|
2597
|
-
}
|
|
2598
|
-
},
|
|
2599
|
-
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2600
|
-
});
|
|
2601
|
-
if (res.response.status === 404) {
|
|
2602
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2603
|
-
}
|
|
2604
|
-
const err = handleApiError(res, VolumeError);
|
|
2605
|
-
if (err) {
|
|
2606
|
-
throw err;
|
|
2607
|
-
}
|
|
2608
|
-
const entries = Array.isArray(res.data) ? res.data : [];
|
|
2609
|
-
return entries.map(convertVolumeEntryStat);
|
|
2616
|
+
};
|
|
2617
|
+
|
|
2618
|
+
// src/core/secret/index.ts
|
|
2619
|
+
var SECRET_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
2620
|
+
var ENV_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
2621
|
+
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])?)*$/;
|
|
2622
|
+
function validateSecretEnvs(secretEnvs, envs) {
|
|
2623
|
+
if (!secretEnvs) {
|
|
2624
|
+
return {};
|
|
2610
2625
|
}
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
const res = await client.api.POST("/volumecontent/{volumeID}/dir", {
|
|
2622
|
-
params: {
|
|
2623
|
-
path: {
|
|
2624
|
-
volumeID: this.volumeId
|
|
2625
|
-
},
|
|
2626
|
-
query: {
|
|
2627
|
-
path: path2,
|
|
2628
|
-
uid: opts == null ? void 0 : opts.uid,
|
|
2629
|
-
gid: opts == null ? void 0 : opts.gid,
|
|
2630
|
-
mode: opts == null ? void 0 : opts.mode,
|
|
2631
|
-
force: opts == null ? void 0 : opts.force
|
|
2632
|
-
}
|
|
2633
|
-
},
|
|
2634
|
-
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2635
|
-
});
|
|
2636
|
-
if (res.response.status === 404) {
|
|
2637
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2638
|
-
}
|
|
2639
|
-
const err = handleApiError(res, VolumeError);
|
|
2640
|
-
if (err) {
|
|
2641
|
-
throw err;
|
|
2626
|
+
if (typeof secretEnvs !== "object" || Array.isArray(secretEnvs)) {
|
|
2627
|
+
throw new InvalidArgumentError("secretEnvs must be a mapping");
|
|
2628
|
+
}
|
|
2629
|
+
const envNames = new Set(Object.keys(envs != null ? envs : {}));
|
|
2630
|
+
const validated = {};
|
|
2631
|
+
for (const [envName, secretName] of Object.entries(secretEnvs)) {
|
|
2632
|
+
if (!ENV_NAME_PATTERN.test(envName)) {
|
|
2633
|
+
throw new InvalidArgumentError(
|
|
2634
|
+
`secretEnvs key ${JSON.stringify(envName)} must be a valid sandbox environment variable name`
|
|
2635
|
+
);
|
|
2642
2636
|
}
|
|
2643
|
-
if (
|
|
2644
|
-
throw new
|
|
2637
|
+
if (envNames.has(envName)) {
|
|
2638
|
+
throw new InvalidArgumentError(
|
|
2639
|
+
`envs and secretEnvs both define ${JSON.stringify(envName)}`
|
|
2640
|
+
);
|
|
2645
2641
|
}
|
|
2646
|
-
|
|
2647
|
-
|
|
2642
|
+
validateSecretName(secretName);
|
|
2643
|
+
validated[envName] = secretName;
|
|
2644
|
+
}
|
|
2645
|
+
return validated;
|
|
2646
|
+
}
|
|
2647
|
+
var _Secret = class _Secret {
|
|
2648
|
+
static async create(params, opts) {
|
|
2649
|
+
validateSecretName(params.name);
|
|
2650
|
+
if (!params.value) {
|
|
2651
|
+
throw new InvalidArgumentError("value is required");
|
|
2652
|
+
}
|
|
2653
|
+
const body = {
|
|
2654
|
+
name: params.name,
|
|
2655
|
+
value: params.value,
|
|
2656
|
+
hosts: normalizeSecretHosts(params.hosts)
|
|
2657
|
+
};
|
|
2658
|
+
if (params.description !== void 0) {
|
|
2659
|
+
body.description = params.description;
|
|
2660
|
+
}
|
|
2661
|
+
return bindingFromJson(
|
|
2662
|
+
await request(
|
|
2663
|
+
"POST",
|
|
2664
|
+
_Secret.base,
|
|
2665
|
+
"Secret.create",
|
|
2666
|
+
opts,
|
|
2667
|
+
body
|
|
2668
|
+
)
|
|
2648
2669
|
);
|
|
2649
2670
|
}
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
}
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
},
|
|
2670
|
-
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2671
|
-
});
|
|
2672
|
-
if (res.response.status === 404) {
|
|
2673
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2674
|
-
}
|
|
2675
|
-
const err = handleApiError(res, VolumeError);
|
|
2676
|
-
if (err) {
|
|
2677
|
-
throw err;
|
|
2678
|
-
}
|
|
2679
|
-
if (!res.data) {
|
|
2680
|
-
throw new Error("Response data is missing");
|
|
2681
|
-
}
|
|
2682
|
-
return convertVolumeEntryStat(
|
|
2683
|
-
res.data
|
|
2671
|
+
static async list(opts) {
|
|
2672
|
+
var _a3;
|
|
2673
|
+
const data = await request(
|
|
2674
|
+
"GET",
|
|
2675
|
+
_Secret.base,
|
|
2676
|
+
"Secret.list",
|
|
2677
|
+
opts
|
|
2678
|
+
);
|
|
2679
|
+
return ((_a3 = data.secrets) != null ? _a3 : []).map(bindingFromJson);
|
|
2680
|
+
}
|
|
2681
|
+
static async get(name, opts) {
|
|
2682
|
+
validateSecretName(name);
|
|
2683
|
+
return bindingFromJson(
|
|
2684
|
+
await request(
|
|
2685
|
+
"GET",
|
|
2686
|
+
`${_Secret.base}/${encodeURIComponent(name)}`,
|
|
2687
|
+
"Secret.get",
|
|
2688
|
+
opts
|
|
2689
|
+
)
|
|
2684
2690
|
);
|
|
2685
2691
|
}
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
* `false` if it does not (404). Other errors are rethrown.
|
|
2691
|
-
*
|
|
2692
|
-
* @param path path to the file or directory.
|
|
2693
|
-
* @param opts connection options.
|
|
2694
|
-
*
|
|
2695
|
-
* @returns `true` if the path exists, `false` otherwise.
|
|
2696
|
-
*/
|
|
2697
|
-
async exists(path2, opts) {
|
|
2698
|
-
try {
|
|
2699
|
-
await this.getInfo(path2, opts);
|
|
2700
|
-
return true;
|
|
2701
|
-
} catch (err) {
|
|
2702
|
-
if (err instanceof NotFoundError) {
|
|
2703
|
-
return false;
|
|
2704
|
-
}
|
|
2705
|
-
throw err;
|
|
2692
|
+
static async update(params, opts) {
|
|
2693
|
+
validateSecretName(params.name);
|
|
2694
|
+
if (!params.value) {
|
|
2695
|
+
throw new InvalidArgumentError("value is required");
|
|
2706
2696
|
}
|
|
2697
|
+
const body = {
|
|
2698
|
+
value: params.value,
|
|
2699
|
+
hosts: normalizeSecretHosts(params.hosts)
|
|
2700
|
+
};
|
|
2701
|
+
if (params.description !== void 0) {
|
|
2702
|
+
body.description = params.description;
|
|
2703
|
+
}
|
|
2704
|
+
return bindingFromJson(
|
|
2705
|
+
await request(
|
|
2706
|
+
"PUT",
|
|
2707
|
+
`${_Secret.base}/${encodeURIComponent(params.name)}`,
|
|
2708
|
+
"Secret.update",
|
|
2709
|
+
opts,
|
|
2710
|
+
body
|
|
2711
|
+
)
|
|
2712
|
+
);
|
|
2707
2713
|
}
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
*/
|
|
2717
|
-
async updateMetadata(path2, metadata, opts) {
|
|
2718
|
-
const config = new VolumeConnectionConfig(this, opts);
|
|
2719
|
-
const client = new VolumeApiClient(config);
|
|
2720
|
-
const res = await client.api.PATCH("/volumecontent/{volumeID}/path", {
|
|
2721
|
-
params: {
|
|
2722
|
-
path: {
|
|
2723
|
-
volumeID: this.volumeId
|
|
2724
|
-
},
|
|
2725
|
-
query: {
|
|
2726
|
-
path: path2
|
|
2727
|
-
}
|
|
2728
|
-
},
|
|
2729
|
-
body: {
|
|
2730
|
-
uid: metadata.uid,
|
|
2731
|
-
gid: metadata.gid,
|
|
2732
|
-
mode: metadata.mode
|
|
2733
|
-
},
|
|
2734
|
-
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2735
|
-
});
|
|
2736
|
-
if (res.response.status === 404) {
|
|
2737
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2738
|
-
}
|
|
2739
|
-
const err = handleApiError(res, VolumeError);
|
|
2740
|
-
if (err) {
|
|
2741
|
-
throw err;
|
|
2742
|
-
}
|
|
2743
|
-
if (!res.data) {
|
|
2744
|
-
throw new Error("Response data is missing");
|
|
2745
|
-
}
|
|
2746
|
-
return convertVolumeEntryStat(
|
|
2747
|
-
res.data
|
|
2714
|
+
static async delete(name, opts) {
|
|
2715
|
+
var _a3;
|
|
2716
|
+
validateSecretName(name);
|
|
2717
|
+
const data = await request(
|
|
2718
|
+
"DELETE",
|
|
2719
|
+
`${_Secret.base}/${encodeURIComponent(name)}`,
|
|
2720
|
+
"Secret.delete",
|
|
2721
|
+
opts
|
|
2748
2722
|
);
|
|
2723
|
+
return String((_a3 = data.deleted) != null ? _a3 : "");
|
|
2749
2724
|
}
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
if (
|
|
2768
|
-
throw new
|
|
2725
|
+
};
|
|
2726
|
+
_Secret.base = "/secrets";
|
|
2727
|
+
var Secret = _Secret;
|
|
2728
|
+
function validateSecretName(name) {
|
|
2729
|
+
if (typeof name !== "string" || !SECRET_NAME_PATTERN.test(name)) {
|
|
2730
|
+
throw new InvalidArgumentError(
|
|
2731
|
+
`secret name ${JSON.stringify(name)} must be 1-128 characters and contain only letters, numbers, dots, underscores, and hyphens`
|
|
2732
|
+
);
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
function normalizeSecretHosts(hosts) {
|
|
2736
|
+
if (!hosts.length) {
|
|
2737
|
+
throw new InvalidArgumentError("hosts is required");
|
|
2738
|
+
}
|
|
2739
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2740
|
+
const normalizedHosts = [];
|
|
2741
|
+
for (const rawHost of hosts) {
|
|
2742
|
+
if (typeof rawHost !== "string") {
|
|
2743
|
+
throw new InvalidArgumentError("host must be a string");
|
|
2769
2744
|
}
|
|
2770
|
-
const
|
|
2771
|
-
if (
|
|
2772
|
-
throw
|
|
2745
|
+
const host = rawHost.trim().toLowerCase();
|
|
2746
|
+
if (!host) {
|
|
2747
|
+
throw new InvalidArgumentError("host cannot be empty");
|
|
2773
2748
|
}
|
|
2774
|
-
if (
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
if (res.response.headers.get("content-length") === "0") {
|
|
2779
|
-
return "";
|
|
2780
|
-
}
|
|
2781
|
-
return typeof res.data === "string" ? res.data : "";
|
|
2749
|
+
if (host.includes("://") || /[/?#@:]/.test(host)) {
|
|
2750
|
+
throw new InvalidArgumentError(
|
|
2751
|
+
`host ${JSON.stringify(host)} must be a hostname only`
|
|
2752
|
+
);
|
|
2782
2753
|
}
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
*
|
|
2788
|
-
* Writing to a file that doesn't exist creates the file.
|
|
2789
|
-
*
|
|
2790
|
-
* Writing to a file that already exists overwrites the file.
|
|
2791
|
-
*
|
|
2792
|
-
* @param path path to the file.
|
|
2793
|
-
* @param data data to write to the file. Data can be a string, `ArrayBuffer`, `Blob`, or `ReadableStream`.
|
|
2794
|
-
* @param options file creation options.
|
|
2795
|
-
* @param opts connection options.
|
|
2796
|
-
*
|
|
2797
|
-
* @returns information about the written file
|
|
2798
|
-
*/
|
|
2799
|
-
async writeFile(path2, data, opts) {
|
|
2800
|
-
var _a3;
|
|
2801
|
-
const config = new VolumeConnectionConfig(this, opts);
|
|
2802
|
-
const client = new VolumeApiClient(config);
|
|
2803
|
-
const blob = await toBlob(data);
|
|
2804
|
-
const res = await client.api.PUT("/volumecontent/{volumeID}/file", {
|
|
2805
|
-
params: {
|
|
2806
|
-
path: {
|
|
2807
|
-
volumeID: this.volumeId
|
|
2808
|
-
},
|
|
2809
|
-
query: {
|
|
2810
|
-
path: path2,
|
|
2811
|
-
uid: opts == null ? void 0 : opts.uid,
|
|
2812
|
-
gid: opts == null ? void 0 : opts.gid,
|
|
2813
|
-
mode: opts == null ? void 0 : opts.mode,
|
|
2814
|
-
force: opts == null ? void 0 : opts.force
|
|
2815
|
-
}
|
|
2816
|
-
},
|
|
2817
|
-
bodySerializer: () => blob,
|
|
2818
|
-
body: {},
|
|
2819
|
-
headers: {
|
|
2820
|
-
"Content-Type": "application/octet-stream"
|
|
2821
|
-
},
|
|
2822
|
-
signal: config.getSignal((_a3 = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _a3 : FILE_TIMEOUT_MS)
|
|
2823
|
-
});
|
|
2824
|
-
if (res.response.status === 404) {
|
|
2825
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2754
|
+
const wildcard = host.startsWith("*.");
|
|
2755
|
+
const lookupHost = wildcard ? host.slice(2) : host;
|
|
2756
|
+
if (!lookupHost || lookupHost.includes("*")) {
|
|
2757
|
+
throw new InvalidArgumentError(`invalid host ${JSON.stringify(host)}`);
|
|
2826
2758
|
}
|
|
2827
|
-
const
|
|
2828
|
-
if (
|
|
2829
|
-
throw
|
|
2759
|
+
const normalized = wildcard ? `*.${lookupHost}` : lookupHost;
|
|
2760
|
+
if (!HOST_PATTERN.test(normalized)) {
|
|
2761
|
+
throw new InvalidArgumentError(
|
|
2762
|
+
`host ${JSON.stringify(host)} must be a hostname or wildcard hostname`
|
|
2763
|
+
);
|
|
2830
2764
|
}
|
|
2831
|
-
if (
|
|
2832
|
-
|
|
2765
|
+
if (seen.has(normalized)) {
|
|
2766
|
+
continue;
|
|
2833
2767
|
}
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
);
|
|
2768
|
+
seen.add(normalized);
|
|
2769
|
+
normalizedHosts.push(normalized);
|
|
2837
2770
|
}
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
}
|
|
2855
|
-
},
|
|
2856
|
-
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
2857
|
-
});
|
|
2858
|
-
if (res.response.status === 404) {
|
|
2859
|
-
throw new NotFoundError(`Path ${path2} not found`);
|
|
2860
|
-
}
|
|
2861
|
-
const err = handleApiError(res, VolumeError);
|
|
2862
|
-
if (err) {
|
|
2863
|
-
throw err;
|
|
2864
|
-
}
|
|
2771
|
+
return normalizedHosts;
|
|
2772
|
+
}
|
|
2773
|
+
async function request(method, path2, feature, opts, body) {
|
|
2774
|
+
const config = new ConnectionConfig(opts);
|
|
2775
|
+
raiseIfLegacy(config, feature, SecretError);
|
|
2776
|
+
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}` } : {});
|
|
2777
|
+
const response = await fetch(`${config.apiUrl}${path2}`, {
|
|
2778
|
+
method,
|
|
2779
|
+
headers,
|
|
2780
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
2781
|
+
signal: config.getSignal()
|
|
2782
|
+
});
|
|
2783
|
+
const data = await parseJson(response);
|
|
2784
|
+
if (!response.ok) {
|
|
2785
|
+
const message = typeof (data == null ? void 0 : data.message) === "string" ? data.message : response.statusText;
|
|
2786
|
+
throw new SecretError(`${response.status}: ${message}`);
|
|
2865
2787
|
}
|
|
2866
|
-
|
|
2788
|
+
return data;
|
|
2789
|
+
}
|
|
2790
|
+
async function parseJson(response) {
|
|
2791
|
+
const text = await response.text();
|
|
2792
|
+
return text ? JSON.parse(text) : {};
|
|
2793
|
+
}
|
|
2794
|
+
function bindingFromJson(data) {
|
|
2795
|
+
var _a3, _b;
|
|
2796
|
+
return {
|
|
2797
|
+
name: data.name,
|
|
2798
|
+
hosts: (_a3 = data.hosts) != null ? _a3 : [],
|
|
2799
|
+
placeholder: data.placeholder,
|
|
2800
|
+
description: (_b = data.description) != null ? _b : null,
|
|
2801
|
+
hasSecret: data.hasSecret,
|
|
2802
|
+
status: data.status,
|
|
2803
|
+
updatedAt: data.updatedAt
|
|
2804
|
+
};
|
|
2805
|
+
}
|
|
2867
2806
|
|
|
2868
2807
|
// src/core/sandbox/index.ts
|
|
2869
2808
|
var import_connect_web = require("@connectrpc/connect-web");
|
|
@@ -3334,6 +3273,33 @@ var Commands = class {
|
|
|
3334
3273
|
|
|
3335
3274
|
// src/core/sandbox/sandboxApi.ts
|
|
3336
3275
|
var import_compare_versions4 = require("compare-versions");
|
|
3276
|
+
async function createRawApiError(response) {
|
|
3277
|
+
var _a3;
|
|
3278
|
+
let message = response.statusText;
|
|
3279
|
+
try {
|
|
3280
|
+
const body = await response.json();
|
|
3281
|
+
message = (_a3 = body == null ? void 0 : body.message) != null ? _a3 : JSON.stringify(body);
|
|
3282
|
+
} catch (e) {
|
|
3283
|
+
try {
|
|
3284
|
+
message = await response.text();
|
|
3285
|
+
} catch (e2) {
|
|
3286
|
+
}
|
|
3287
|
+
}
|
|
3288
|
+
if (response.status === 401) {
|
|
3289
|
+
return new AuthenticationError(
|
|
3290
|
+
`Unauthorized, please check your credentials. - ${message}`
|
|
3291
|
+
);
|
|
3292
|
+
}
|
|
3293
|
+
if (response.status === 429) {
|
|
3294
|
+
return new RateLimitError(
|
|
3295
|
+
`Rate limit exceeded, please try again later - ${message}`
|
|
3296
|
+
);
|
|
3297
|
+
}
|
|
3298
|
+
return new SandboxError(`${response.status}: ${message}`);
|
|
3299
|
+
}
|
|
3300
|
+
function getRawApiHeaders(config, headers) {
|
|
3301
|
+
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 : {});
|
|
3302
|
+
}
|
|
3337
3303
|
function getLifecycle(opts) {
|
|
3338
3304
|
if (opts == null ? void 0 : opts.lifecycle) {
|
|
3339
3305
|
return opts.lifecycle;
|
|
@@ -3404,15 +3370,40 @@ var SandboxApi = class {
|
|
|
3404
3370
|
* @returns List of sandbox metrics containing CPU, memory and disk usage information.
|
|
3405
3371
|
*/
|
|
3406
3372
|
static async getMetrics(sandboxId, opts) {
|
|
3407
|
-
var _a3, _b;
|
|
3373
|
+
var _a3, _b, _c, _d;
|
|
3408
3374
|
const config = new ConnectionConfig(opts);
|
|
3409
3375
|
const client = new ApiClient(config);
|
|
3376
|
+
if (config.isLegacyDomain) {
|
|
3377
|
+
const res2 = await client.api.GET("/sandboxes/{sandboxID}/metrics", {
|
|
3378
|
+
params: {
|
|
3379
|
+
path: {
|
|
3380
|
+
sandboxID: sandboxId
|
|
3381
|
+
}
|
|
3382
|
+
},
|
|
3383
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3384
|
+
});
|
|
3385
|
+
const err2 = handleApiError(res2);
|
|
3386
|
+
if (err2) {
|
|
3387
|
+
throw err2;
|
|
3388
|
+
}
|
|
3389
|
+
return (_b = ((_a3 = res2.data) != null ? _a3 : []).map((metric) => ({
|
|
3390
|
+
timestamp: new Date(metric.timestamp),
|
|
3391
|
+
cpuUsedPct: metric.cpuUsedPct,
|
|
3392
|
+
cpuCount: metric.cpuCount,
|
|
3393
|
+
memUsed: metric.memUsedMiB * 1024 * 1024,
|
|
3394
|
+
memTotal: metric.memTotalMiB * 1024 * 1024,
|
|
3395
|
+
diskUsed: -1,
|
|
3396
|
+
diskTotal: -1
|
|
3397
|
+
}))) != null ? _b : [];
|
|
3398
|
+
}
|
|
3410
3399
|
const start = (opts == null ? void 0 : opts.start) ? Math.round(opts.start.getTime() / 1e3) : void 0;
|
|
3411
3400
|
const end = (opts == null ? void 0 : opts.end) ? Math.round(opts.end.getTime() / 1e3) : void 0;
|
|
3412
3401
|
const res = await client.api.GET("/sandboxes/{sandboxID}/metrics", {
|
|
3413
3402
|
params: {
|
|
3414
3403
|
path: {
|
|
3415
|
-
sandboxID: sandboxId
|
|
3404
|
+
sandboxID: sandboxId
|
|
3405
|
+
},
|
|
3406
|
+
query: {
|
|
3416
3407
|
start,
|
|
3417
3408
|
end
|
|
3418
3409
|
}
|
|
@@ -3423,7 +3414,7 @@ var SandboxApi = class {
|
|
|
3423
3414
|
if (err) {
|
|
3424
3415
|
throw err;
|
|
3425
3416
|
}
|
|
3426
|
-
return (
|
|
3417
|
+
return (_d = (_c = res.data) == null ? void 0 : _c.map((metric) => ({
|
|
3427
3418
|
timestamp: new Date(metric.timestamp),
|
|
3428
3419
|
cpuUsedPct: metric.cpuUsedPct,
|
|
3429
3420
|
cpuCount: metric.cpuCount,
|
|
@@ -3431,7 +3422,7 @@ var SandboxApi = class {
|
|
|
3431
3422
|
memTotal: metric.memTotal,
|
|
3432
3423
|
diskUsed: metric.diskUsed,
|
|
3433
3424
|
diskTotal: metric.diskTotal
|
|
3434
|
-
}))) != null ?
|
|
3425
|
+
}))) != null ? _d : [];
|
|
3435
3426
|
}
|
|
3436
3427
|
/**
|
|
3437
3428
|
* Set the timeout of the specified sandbox.
|
|
@@ -3448,28 +3439,249 @@ var SandboxApi = class {
|
|
|
3448
3439
|
static async setTimeout(sandboxId, timeoutMs, opts) {
|
|
3449
3440
|
var _a3;
|
|
3450
3441
|
const config = new ConnectionConfig(opts);
|
|
3451
|
-
const client = new ApiClient(config);
|
|
3452
|
-
const res = await client.api.POST("/sandboxes/{sandboxID}/timeout", {
|
|
3453
|
-
params: {
|
|
3454
|
-
path: {
|
|
3455
|
-
sandboxID: sandboxId
|
|
3456
|
-
}
|
|
3457
|
-
},
|
|
3458
|
-
body: {
|
|
3459
|
-
timeout: timeoutToSeconds(timeoutMs)
|
|
3460
|
-
},
|
|
3461
|
-
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3462
|
-
});
|
|
3463
|
-
if (((_a3 = res.error) == null ? void 0 : _a3.code) === 404) {
|
|
3442
|
+
const client = new ApiClient(config);
|
|
3443
|
+
const res = await client.api.POST("/sandboxes/{sandboxID}/timeout", {
|
|
3444
|
+
params: {
|
|
3445
|
+
path: {
|
|
3446
|
+
sandboxID: sandboxId
|
|
3447
|
+
}
|
|
3448
|
+
},
|
|
3449
|
+
body: {
|
|
3450
|
+
timeout: timeoutToSeconds(timeoutMs)
|
|
3451
|
+
},
|
|
3452
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3453
|
+
});
|
|
3454
|
+
if (((_a3 = res.error) == null ? void 0 : _a3.code) === 404) {
|
|
3455
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3456
|
+
}
|
|
3457
|
+
const err = handleApiError(res);
|
|
3458
|
+
if (err) {
|
|
3459
|
+
throw err;
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
/**
|
|
3463
|
+
* @deprecated Only legacy domains support this method. Use {@link SandboxApi.createSnapshot} for modern domains.
|
|
3464
|
+
*/
|
|
3465
|
+
static async commit(sandboxId, opts) {
|
|
3466
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3467
|
+
const config = new ConnectionConfig(opts);
|
|
3468
|
+
if (!config.isLegacyDomain) {
|
|
3469
|
+
throw new SandboxError("Sandbox.commit is only supported for legacy domains");
|
|
3470
|
+
}
|
|
3471
|
+
const response = await fetch(
|
|
3472
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/commit`,
|
|
3473
|
+
{
|
|
3474
|
+
method: "POST",
|
|
3475
|
+
headers: getRawApiHeaders(config, {
|
|
3476
|
+
"Content-Type": "application/json"
|
|
3477
|
+
}),
|
|
3478
|
+
body: JSON.stringify((opts == null ? void 0 : opts.alias) ? { alias: opts.alias } : {}),
|
|
3479
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3480
|
+
}
|
|
3481
|
+
);
|
|
3482
|
+
if (response.status === 404) {
|
|
3483
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3484
|
+
}
|
|
3485
|
+
if (!response.ok) {
|
|
3486
|
+
throw await createRawApiError(response);
|
|
3487
|
+
}
|
|
3488
|
+
const data = await response.json();
|
|
3489
|
+
return {
|
|
3490
|
+
alias: (_d = (_c = (_a3 = data.aliases) == null ? void 0 : _a3[0]) != null ? _c : (_b = data.names) == null ? void 0 : _b[0]) != null ? _d : "",
|
|
3491
|
+
name: (_h = (_g = (_e = data.names) == null ? void 0 : _e[0]) != null ? _g : (_f = data.aliases) == null ? void 0 : _f[0]) != null ? _h : "",
|
|
3492
|
+
tags: [],
|
|
3493
|
+
templateId: data.templateID,
|
|
3494
|
+
buildId: data.buildID,
|
|
3495
|
+
aliases: (_i = data.aliases) != null ? _i : [],
|
|
3496
|
+
names: (_j = data.names) != null ? _j : [],
|
|
3497
|
+
templateType: "snapshot_template"
|
|
3498
|
+
};
|
|
3499
|
+
}
|
|
3500
|
+
static async hotplugMemory(sandboxId, requestedSizeMib, opts) {
|
|
3501
|
+
const config = new ConnectionConfig(opts);
|
|
3502
|
+
raiseIfLegacy(config, "Sandbox.hotplugMemory", SandboxError);
|
|
3503
|
+
const response = await fetch(
|
|
3504
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/hotplug-memory`,
|
|
3505
|
+
{
|
|
3506
|
+
method: "POST",
|
|
3507
|
+
headers: getRawApiHeaders(config, {
|
|
3508
|
+
"Content-Type": "application/json"
|
|
3509
|
+
}),
|
|
3510
|
+
body: JSON.stringify({
|
|
3511
|
+
requested_size_mib: requestedSizeMib
|
|
3512
|
+
}),
|
|
3513
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3514
|
+
}
|
|
3515
|
+
);
|
|
3516
|
+
if (response.status === 404) {
|
|
3517
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3518
|
+
}
|
|
3519
|
+
if (!response.ok) {
|
|
3520
|
+
throw await createRawApiError(response);
|
|
3521
|
+
}
|
|
3522
|
+
}
|
|
3523
|
+
static async reset(sandboxId, opts) {
|
|
3524
|
+
var _a3;
|
|
3525
|
+
const config = new ConnectionConfig(opts);
|
|
3526
|
+
const response = await fetch(
|
|
3527
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/reset`,
|
|
3528
|
+
{
|
|
3529
|
+
method: "POST",
|
|
3530
|
+
headers: getRawApiHeaders(config, {
|
|
3531
|
+
"Content-Type": "application/json"
|
|
3532
|
+
}),
|
|
3533
|
+
body: JSON.stringify(__spreadValues({
|
|
3534
|
+
resume: (_a3 = opts == null ? void 0 : opts.resume) != null ? _a3 : true
|
|
3535
|
+
}, (opts == null ? void 0 : opts.timeoutMs) !== void 0 ? { timeout: timeoutToSeconds(opts.timeoutMs) } : {})),
|
|
3536
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3537
|
+
}
|
|
3538
|
+
);
|
|
3539
|
+
if (response.status === 404) {
|
|
3540
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3541
|
+
}
|
|
3542
|
+
if (response.status === 409) {
|
|
3543
|
+
return false;
|
|
3544
|
+
}
|
|
3545
|
+
if (!response.ok) {
|
|
3546
|
+
throw await createRawApiError(response);
|
|
3547
|
+
}
|
|
3548
|
+
return true;
|
|
3549
|
+
}
|
|
3550
|
+
static async mountVolume(sandboxId, name, path2, opts) {
|
|
3551
|
+
var _a3, _b;
|
|
3552
|
+
const config = new ConnectionConfig(opts);
|
|
3553
|
+
raiseIfLegacy(config, "Sandbox.mountVolume", SandboxError);
|
|
3554
|
+
const response = await fetch(
|
|
3555
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/volume-mounts`,
|
|
3556
|
+
{
|
|
3557
|
+
method: "POST",
|
|
3558
|
+
headers: getRawApiHeaders(config, {
|
|
3559
|
+
"Content-Type": "application/json"
|
|
3560
|
+
}),
|
|
3561
|
+
body: JSON.stringify({ name, path: path2 }),
|
|
3562
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3563
|
+
}
|
|
3564
|
+
);
|
|
3565
|
+
if (response.status === 404) {
|
|
3566
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3567
|
+
}
|
|
3568
|
+
if (!response.ok) {
|
|
3569
|
+
throw await createRawApiError(response);
|
|
3570
|
+
}
|
|
3571
|
+
const data = await response.json();
|
|
3572
|
+
return {
|
|
3573
|
+
sandboxId: data.sandboxID,
|
|
3574
|
+
templateId: data.templateID,
|
|
3575
|
+
name: data.name,
|
|
3576
|
+
metadata: (_a3 = data.metadata) != null ? _a3 : {},
|
|
3577
|
+
startedAt: new Date(data.startedAt),
|
|
3578
|
+
endAt: new Date(data.endAt),
|
|
3579
|
+
state: data.state,
|
|
3580
|
+
cpuCount: data.cpuCount,
|
|
3581
|
+
memoryMB: data.memoryMB,
|
|
3582
|
+
envdVersion: data.envdVersion,
|
|
3583
|
+
volumeMounts: (_b = data.volumeMounts) != null ? _b : []
|
|
3584
|
+
};
|
|
3585
|
+
}
|
|
3586
|
+
static async unmountVolume(sandboxId, path2, opts) {
|
|
3587
|
+
var _a3, _b;
|
|
3588
|
+
const config = new ConnectionConfig(opts);
|
|
3589
|
+
raiseIfLegacy(config, "Sandbox.unmountVolume", SandboxError);
|
|
3590
|
+
const url = new URL(
|
|
3591
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/volume-mounts`
|
|
3592
|
+
);
|
|
3593
|
+
url.searchParams.set("path", path2);
|
|
3594
|
+
if (opts == null ? void 0 : opts.force) {
|
|
3595
|
+
url.searchParams.set("force", "true");
|
|
3596
|
+
}
|
|
3597
|
+
const response = await fetch(url, {
|
|
3598
|
+
method: "DELETE",
|
|
3599
|
+
headers: getRawApiHeaders(config),
|
|
3600
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3601
|
+
});
|
|
3602
|
+
if (response.status === 404) {
|
|
3603
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3604
|
+
}
|
|
3605
|
+
if (!response.ok) {
|
|
3606
|
+
throw await createRawApiError(response);
|
|
3607
|
+
}
|
|
3608
|
+
const data = await response.json();
|
|
3609
|
+
return {
|
|
3610
|
+
sandboxId: data.sandboxID,
|
|
3611
|
+
templateId: data.templateID,
|
|
3612
|
+
name: data.name,
|
|
3613
|
+
metadata: (_a3 = data.metadata) != null ? _a3 : {},
|
|
3614
|
+
startedAt: new Date(data.startedAt),
|
|
3615
|
+
endAt: new Date(data.endAt),
|
|
3616
|
+
state: data.state,
|
|
3617
|
+
cpuCount: data.cpuCount,
|
|
3618
|
+
memoryMB: data.memoryMB,
|
|
3619
|
+
envdVersion: data.envdVersion,
|
|
3620
|
+
volumeMounts: (_b = data.volumeMounts) != null ? _b : []
|
|
3621
|
+
};
|
|
3622
|
+
}
|
|
3623
|
+
static async setNetwork(sandboxId, opts) {
|
|
3624
|
+
const config = new ConnectionConfig(opts);
|
|
3625
|
+
raiseIfLegacy(config, "Sandbox.setNetwork", SandboxError);
|
|
3626
|
+
const response = await fetch(
|
|
3627
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/network`,
|
|
3628
|
+
{
|
|
3629
|
+
method: "PUT",
|
|
3630
|
+
headers: getRawApiHeaders(config, {
|
|
3631
|
+
"Content-Type": "application/json"
|
|
3632
|
+
}),
|
|
3633
|
+
body: JSON.stringify(__spreadValues(__spreadValues({}, (opts == null ? void 0 : opts.allowOut) ? { allowOut: opts.allowOut } : {}), (opts == null ? void 0 : opts.denyOut) ? { denyOut: opts.denyOut } : {})),
|
|
3634
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3635
|
+
}
|
|
3636
|
+
);
|
|
3637
|
+
if (response.status === 404) {
|
|
3638
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3639
|
+
}
|
|
3640
|
+
if (!response.ok) {
|
|
3641
|
+
throw await createRawApiError(response);
|
|
3642
|
+
}
|
|
3643
|
+
}
|
|
3644
|
+
static async cloneSandboxes(sandboxId, opts) {
|
|
3645
|
+
var _a3, _b, _c, _d;
|
|
3646
|
+
const config = new ConnectionConfig(opts);
|
|
3647
|
+
const response = await fetch(
|
|
3648
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/clone`,
|
|
3649
|
+
{
|
|
3650
|
+
method: "POST",
|
|
3651
|
+
headers: getRawApiHeaders(config, {
|
|
3652
|
+
"Content-Type": "application/json"
|
|
3653
|
+
}),
|
|
3654
|
+
body: JSON.stringify(__spreadValues(__spreadValues({
|
|
3655
|
+
count: (_a3 = opts == null ? void 0 : opts.count) != null ? _a3 : 1,
|
|
3656
|
+
strict: (_b = opts == null ? void 0 : opts.strict) != null ? _b : false
|
|
3657
|
+
}, (opts == null ? void 0 : opts.nodeId) ? { nodeID: opts.nodeId } : {}), (opts == null ? void 0 : opts.timeoutMs) !== void 0 ? { timeout: timeoutToSeconds(opts.timeoutMs) } : {})),
|
|
3658
|
+
signal: config.getSignal((_c = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _c : 3e5)
|
|
3659
|
+
}
|
|
3660
|
+
);
|
|
3661
|
+
if (response.status === 404) {
|
|
3464
3662
|
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3465
3663
|
}
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
throw err;
|
|
3664
|
+
if (!response.ok) {
|
|
3665
|
+
throw await createRawApiError(response);
|
|
3469
3666
|
}
|
|
3667
|
+
const data = await response.json();
|
|
3668
|
+
return {
|
|
3669
|
+
sandboxes: ((_d = data.sandboxes) != null ? _d : []).map((sandbox) => {
|
|
3670
|
+
var _a4, _b2;
|
|
3671
|
+
const baseSandboxId = (_a4 = sandbox.sandboxID) != null ? _a4 : "";
|
|
3672
|
+
const sandboxId2 = sandbox.clientID ? `${baseSandboxId}-${sandbox.clientID}` : baseSandboxId;
|
|
3673
|
+
return {
|
|
3674
|
+
sandboxId: sandboxId2,
|
|
3675
|
+
envdVersion: (_b2 = sandbox.envdVersion) != null ? _b2 : "0.0.0",
|
|
3676
|
+
envdAccessToken: sandbox.envdAccessToken,
|
|
3677
|
+
trafficAccessToken: sandbox.trafficAccessToken
|
|
3678
|
+
};
|
|
3679
|
+
}),
|
|
3680
|
+
snapshotTemplateId: data.snapshotTemplateId
|
|
3681
|
+
};
|
|
3470
3682
|
}
|
|
3471
3683
|
static async getFullInfo(sandboxId, opts) {
|
|
3472
|
-
var _a3, _b, _c, _d;
|
|
3684
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3473
3685
|
const config = new ConnectionConfig(opts);
|
|
3474
3686
|
const client = new ApiClient(config);
|
|
3475
3687
|
const res = await client.api.GET("/sandboxes/{sandboxID}", {
|
|
@@ -3490,12 +3702,29 @@ var SandboxApi = class {
|
|
|
3490
3702
|
if (!res.data) {
|
|
3491
3703
|
throw new Error("Sandbox not found");
|
|
3492
3704
|
}
|
|
3705
|
+
if (config.isLegacyDomain) {
|
|
3706
|
+
const data = res.data;
|
|
3707
|
+
return __spreadProps(__spreadValues({
|
|
3708
|
+
sandboxId: data.clientID != null ? `${data.sandboxID}-${data.clientID}` : data.sandboxID,
|
|
3709
|
+
templateId: data.templateID
|
|
3710
|
+
}, data.alias && { name: data.alias }), {
|
|
3711
|
+
metadata: (_b = data.metadata) != null ? _b : {},
|
|
3712
|
+
envdVersion: (_c = data.envdVersion) != null ? _c : "0.0.0",
|
|
3713
|
+
envdAccessToken: data.envdAccessToken,
|
|
3714
|
+
startedAt: new Date(data.startedAt),
|
|
3715
|
+
endAt: new Date(data.endAt),
|
|
3716
|
+
state: data.state,
|
|
3717
|
+
cpuCount: data.cpuCount,
|
|
3718
|
+
memoryMB: data.memoryMB,
|
|
3719
|
+
sandboxDomain: data.domain || void 0
|
|
3720
|
+
});
|
|
3721
|
+
}
|
|
3493
3722
|
return __spreadProps(__spreadValues({
|
|
3494
3723
|
sandboxId: res.data.sandboxID,
|
|
3495
3724
|
templateId: res.data.templateID
|
|
3496
3725
|
}, res.data.alias && { name: res.data.alias }), {
|
|
3497
|
-
metadata: (
|
|
3498
|
-
allowInternetAccess: (
|
|
3726
|
+
metadata: (_d = res.data.metadata) != null ? _d : {},
|
|
3727
|
+
allowInternetAccess: (_e = res.data.allowInternetAccess) != null ? _e : void 0,
|
|
3499
3728
|
envdVersion: res.data.envdVersion,
|
|
3500
3729
|
envdAccessToken: res.data.envdAccessToken,
|
|
3501
3730
|
startedAt: new Date(res.data.startedAt),
|
|
@@ -3514,7 +3743,7 @@ var SandboxApi = class {
|
|
|
3514
3743
|
autoResume: res.data.lifecycle.autoResume
|
|
3515
3744
|
} : void 0,
|
|
3516
3745
|
sandboxDomain: res.data.domain || void 0,
|
|
3517
|
-
volumeMounts: (
|
|
3746
|
+
volumeMounts: (_f = res.data.volumeMounts) != null ? _f : []
|
|
3518
3747
|
});
|
|
3519
3748
|
}
|
|
3520
3749
|
/**
|
|
@@ -3526,8 +3755,31 @@ var SandboxApi = class {
|
|
|
3526
3755
|
* @returns `true` if the sandbox got paused, `false` if the sandbox was already paused.
|
|
3527
3756
|
*/
|
|
3528
3757
|
static async pause(sandboxId, opts) {
|
|
3529
|
-
var _a3, _b;
|
|
3758
|
+
var _a3, _b, _c;
|
|
3530
3759
|
const config = new ConnectionConfig(opts);
|
|
3760
|
+
if (config.isLegacyDomain) {
|
|
3761
|
+
const response = await fetch(
|
|
3762
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/pause`,
|
|
3763
|
+
{
|
|
3764
|
+
method: "POST",
|
|
3765
|
+
headers: getRawApiHeaders(config, {
|
|
3766
|
+
"Content-Type": "application/json"
|
|
3767
|
+
}),
|
|
3768
|
+
body: JSON.stringify({ sync: (_a3 = opts == null ? void 0 : opts.sync) != null ? _a3 : false }),
|
|
3769
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3770
|
+
}
|
|
3771
|
+
);
|
|
3772
|
+
if (response.status === 404) {
|
|
3773
|
+
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3774
|
+
}
|
|
3775
|
+
if (response.status === 409) {
|
|
3776
|
+
return false;
|
|
3777
|
+
}
|
|
3778
|
+
if (!response.ok) {
|
|
3779
|
+
throw await createRawApiError(response);
|
|
3780
|
+
}
|
|
3781
|
+
return true;
|
|
3782
|
+
}
|
|
3531
3783
|
const client = new ApiClient(config);
|
|
3532
3784
|
const res = await client.api.POST("/sandboxes/{sandboxID}/pause", {
|
|
3533
3785
|
params: {
|
|
@@ -3537,10 +3789,10 @@ var SandboxApi = class {
|
|
|
3537
3789
|
},
|
|
3538
3790
|
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3539
3791
|
});
|
|
3540
|
-
if (((
|
|
3792
|
+
if (((_b = res.error) == null ? void 0 : _b.code) === 404) {
|
|
3541
3793
|
throw new SandboxNotFoundError(`Sandbox ${sandboxId} not found`);
|
|
3542
3794
|
}
|
|
3543
|
-
if (((
|
|
3795
|
+
if (((_c = res.error) == null ? void 0 : _c.code) === 409) {
|
|
3544
3796
|
return false;
|
|
3545
3797
|
}
|
|
3546
3798
|
const err = handleApiError(res);
|
|
@@ -3570,6 +3822,7 @@ var SandboxApi = class {
|
|
|
3570
3822
|
static async createSnapshot(sandboxId, opts) {
|
|
3571
3823
|
var _a3;
|
|
3572
3824
|
const config = new ConnectionConfig(opts);
|
|
3825
|
+
raiseIfLegacy(config, "Sandbox.createSnapshot", SandboxError);
|
|
3573
3826
|
const client = new ApiClient(config);
|
|
3574
3827
|
const res = await client.api.POST("/sandboxes/{sandboxID}/snapshots", {
|
|
3575
3828
|
params: {
|
|
@@ -3631,22 +3884,69 @@ var SandboxApi = class {
|
|
|
3631
3884
|
return true;
|
|
3632
3885
|
}
|
|
3633
3886
|
static async createSandbox(template, timeoutMs, opts) {
|
|
3634
|
-
var _a3, _b, _c;
|
|
3887
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3635
3888
|
const config = new ConnectionConfig(opts);
|
|
3636
|
-
const client = new ApiClient(config);
|
|
3637
3889
|
const lifecycle = getLifecycle(opts);
|
|
3638
3890
|
const autoPause = lifecycle.onTimeout === "pause";
|
|
3639
3891
|
const autoResumeEnabled = lifecycle.onTimeout === "pause" ? (_a3 = lifecycle.autoResume) != null ? _a3 : false : void 0;
|
|
3640
|
-
|
|
3892
|
+
if (config.isLegacyDomain) {
|
|
3893
|
+
if (opts == null ? void 0 : opts.mcp) {
|
|
3894
|
+
raiseIfLegacy(config, "Sandbox.create mcp", SandboxError);
|
|
3895
|
+
}
|
|
3896
|
+
if (opts == null ? void 0 : opts.network) {
|
|
3897
|
+
raiseIfLegacy(config, "Sandbox.create network", SandboxError);
|
|
3898
|
+
}
|
|
3899
|
+
if (opts == null ? void 0 : opts.volumeMounts) {
|
|
3900
|
+
raiseIfLegacy(config, "Sandbox.create volumeMounts", SandboxError);
|
|
3901
|
+
}
|
|
3902
|
+
if (opts == null ? void 0 : opts.secretEnvs) {
|
|
3903
|
+
raiseIfLegacy(config, "Sandbox.create secretEnvs", SandboxError);
|
|
3904
|
+
}
|
|
3905
|
+
const body2 = __spreadValues({
|
|
3906
|
+
templateID: template,
|
|
3907
|
+
timeout: timeoutToSeconds(timeoutMs),
|
|
3908
|
+
metadata: (_b = opts == null ? void 0 : opts.metadata) != null ? _b : {},
|
|
3909
|
+
envVars: (_c = opts == null ? void 0 : opts.envs) != null ? _c : {},
|
|
3910
|
+
secure: (_d = opts == null ? void 0 : opts.secure) != null ? _d : false,
|
|
3911
|
+
autoPause: autoPause != null ? autoPause : false
|
|
3912
|
+
}, (opts == null ? void 0 : opts.nodeId) ? { nodeID: opts.nodeId } : {});
|
|
3913
|
+
const response = await fetch(`${config.apiUrl}/sandboxes`, {
|
|
3914
|
+
method: "POST",
|
|
3915
|
+
headers: getRawApiHeaders(config, {
|
|
3916
|
+
"Content-Type": "application/json"
|
|
3917
|
+
}),
|
|
3918
|
+
body: JSON.stringify(body2),
|
|
3919
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
3920
|
+
});
|
|
3921
|
+
if (!response.ok) {
|
|
3922
|
+
throw await createRawApiError(response);
|
|
3923
|
+
}
|
|
3924
|
+
const data = await response.json();
|
|
3925
|
+
if ((0, import_compare_versions4.compareVersions)(data.envdVersion, "0.1.0") < 0) {
|
|
3926
|
+
await this.kill(data.sandboxID, opts);
|
|
3927
|
+
throw new TemplateError(
|
|
3928
|
+
"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."
|
|
3929
|
+
);
|
|
3930
|
+
}
|
|
3931
|
+
return {
|
|
3932
|
+
sandboxId: data.clientID ? `${data.sandboxID}-${data.clientID}` : data.sandboxID,
|
|
3933
|
+
sandboxDomain: data.domain || void 0,
|
|
3934
|
+
envdVersion: data.envdVersion,
|
|
3935
|
+
envdAccessToken: data.envdAccessToken,
|
|
3936
|
+
trafficAccessToken: void 0
|
|
3937
|
+
};
|
|
3938
|
+
}
|
|
3939
|
+
const client = new ApiClient(config);
|
|
3940
|
+
const body = __spreadValues(__spreadValues(__spreadValues({
|
|
3641
3941
|
templateID: template,
|
|
3642
3942
|
metadata: opts == null ? void 0 : opts.metadata,
|
|
3643
3943
|
mcp: opts == null ? void 0 : opts.mcp,
|
|
3644
3944
|
envVars: opts == null ? void 0 : opts.envs,
|
|
3645
3945
|
timeout: timeoutToSeconds(timeoutMs),
|
|
3646
|
-
secure: (
|
|
3647
|
-
allow_internet_access: (
|
|
3946
|
+
secure: (_e = opts == null ? void 0 : opts.secure) != null ? _e : true,
|
|
3947
|
+
allow_internet_access: (_f = opts == null ? void 0 : opts.allowInternetAccess) != null ? _f : true,
|
|
3648
3948
|
network: opts == null ? void 0 : opts.network
|
|
3649
|
-
}, autoPause !== void 0 ? { autoPause } : {}), autoResumeEnabled !== void 0 ? { autoResume: { enabled: autoResumeEnabled } } : {});
|
|
3949
|
+
}, (opts == null ? void 0 : opts.nodeId) ? { nodeID: opts.nodeId } : {}), autoPause !== void 0 ? { autoPause } : {}), autoResumeEnabled !== void 0 ? { autoResume: { enabled: autoResumeEnabled } } : {});
|
|
3650
3950
|
if (opts == null ? void 0 : opts.volumeMounts) {
|
|
3651
3951
|
body.volumeMounts = Object.entries(opts.volumeMounts).map(
|
|
3652
3952
|
([mountPath, vol]) => ({
|
|
@@ -3655,6 +3955,14 @@ var SandboxApi = class {
|
|
|
3655
3955
|
})
|
|
3656
3956
|
);
|
|
3657
3957
|
}
|
|
3958
|
+
const validatedSecretEnvs = validateSecretEnvs(
|
|
3959
|
+
opts == null ? void 0 : opts.secretEnvs,
|
|
3960
|
+
opts == null ? void 0 : opts.envs
|
|
3961
|
+
);
|
|
3962
|
+
if (Object.keys(validatedSecretEnvs).length > 0) {
|
|
3963
|
+
;
|
|
3964
|
+
body.secrets = validatedSecretEnvs;
|
|
3965
|
+
}
|
|
3658
3966
|
const res = await client.api.POST("/sandboxes", {
|
|
3659
3967
|
body,
|
|
3660
3968
|
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
@@ -3681,6 +3989,33 @@ var SandboxApi = class {
|
|
|
3681
3989
|
var _a3, _b;
|
|
3682
3990
|
const timeoutMs = (_a3 = opts == null ? void 0 : opts.timeoutMs) != null ? _a3 : DEFAULT_SANDBOX_TIMEOUT_MS;
|
|
3683
3991
|
const config = new ConnectionConfig(opts);
|
|
3992
|
+
if (config.isLegacyDomain) {
|
|
3993
|
+
const response = await fetch(
|
|
3994
|
+
`${config.apiUrl}/sandboxes/${encodeURIComponent(sandboxId)}/connect`,
|
|
3995
|
+
{
|
|
3996
|
+
method: "POST",
|
|
3997
|
+
headers: getRawApiHeaders(config, {
|
|
3998
|
+
"Content-Type": "application/json"
|
|
3999
|
+
}),
|
|
4000
|
+
body: JSON.stringify({ timeout: timeoutToSeconds(timeoutMs) }),
|
|
4001
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
4002
|
+
}
|
|
4003
|
+
);
|
|
4004
|
+
if (response.status === 404) {
|
|
4005
|
+
throw new SandboxNotFoundError(`Paused sandbox ${sandboxId} not found`);
|
|
4006
|
+
}
|
|
4007
|
+
if (!response.ok) {
|
|
4008
|
+
throw await createRawApiError(response);
|
|
4009
|
+
}
|
|
4010
|
+
const data = await response.json();
|
|
4011
|
+
return {
|
|
4012
|
+
sandboxId: data.clientID ? `${data.sandboxID}-${data.clientID}` : data.sandboxID,
|
|
4013
|
+
sandboxDomain: data.domain || void 0,
|
|
4014
|
+
envdVersion: data.envdVersion || "0.0.0",
|
|
4015
|
+
envdAccessToken: data.envdAccessToken,
|
|
4016
|
+
trafficAccessToken: void 0
|
|
4017
|
+
};
|
|
4018
|
+
}
|
|
3684
4019
|
const client = new ApiClient(config);
|
|
3685
4020
|
const res = await client.api.POST("/sandboxes/{sandboxID}/connect", {
|
|
3686
4021
|
params: {
|
|
@@ -3708,6 +4043,69 @@ var SandboxApi = class {
|
|
|
3708
4043
|
trafficAccessToken: res.data.trafficAccessToken || void 0
|
|
3709
4044
|
};
|
|
3710
4045
|
}
|
|
4046
|
+
static async getQuota(opts) {
|
|
4047
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
|
|
4048
|
+
const config = new ConnectionConfig(opts);
|
|
4049
|
+
const url = new URL(`${config.apiUrl}/sandboxes/quota`);
|
|
4050
|
+
const response = await fetch(url, {
|
|
4051
|
+
method: "GET",
|
|
4052
|
+
headers: __spreadValues(__spreadValues(__spreadValues({}, config.headers), config.apiKey ? { "X-API-KEY": config.apiKey } : {}), config.accessToken ? { Authorization: `Bearer ${config.accessToken}` } : {}),
|
|
4053
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
4054
|
+
});
|
|
4055
|
+
if (!response.ok) {
|
|
4056
|
+
throw await createRawApiError(response);
|
|
4057
|
+
}
|
|
4058
|
+
const data = await response.json();
|
|
4059
|
+
return {
|
|
4060
|
+
limit: {
|
|
4061
|
+
concurrentInstances: (_b = (_a3 = data.limit) == null ? void 0 : _a3.concurrentInstances) != null ? _b : 0,
|
|
4062
|
+
concurrentVcpu: (_d = (_c = data.limit) == null ? void 0 : _c.concurrentVcpu) != null ? _d : 0,
|
|
4063
|
+
concurrentRamMb: (_f = (_e = data.limit) == null ? void 0 : _e.concurrentRamMb) != null ? _f : 0,
|
|
4064
|
+
maxLengthHours: (_h = (_g = data.limit) == null ? void 0 : _g.maxLengthHours) != null ? _h : 0,
|
|
4065
|
+
diskMb: (_j = (_i = data.limit) == null ? void 0 : _i.diskMb) != null ? _j : 0,
|
|
4066
|
+
maxVcpu: (_l = (_k = data.limit) == null ? void 0 : _k.maxVcpu) != null ? _l : 0,
|
|
4067
|
+
maxRamMb: (_n = (_m = data.limit) == null ? void 0 : _m.maxRamMb) != null ? _n : 0
|
|
4068
|
+
},
|
|
4069
|
+
usage: {
|
|
4070
|
+
concurrentInstances: (_p = (_o = data.usage) == null ? void 0 : _o.concurrentInstances) != null ? _p : 0,
|
|
4071
|
+
concurrentVcpu: (_r = (_q = data.usage) == null ? void 0 : _q.concurrentVcpu) != null ? _r : 0,
|
|
4072
|
+
concurrentRamMb: (_t = (_s = data.usage) == null ? void 0 : _s.concurrentRamMb) != null ? _t : 0
|
|
4073
|
+
}
|
|
4074
|
+
};
|
|
4075
|
+
}
|
|
4076
|
+
static async getEvents(opts) {
|
|
4077
|
+
var _a3, _b, _c;
|
|
4078
|
+
const config = new ConnectionConfig(opts);
|
|
4079
|
+
const url = new URL(`${config.apiUrl}/sandboxes/events`);
|
|
4080
|
+
if ((opts == null ? void 0 : opts.startTime) !== void 0)
|
|
4081
|
+
url.searchParams.set("startTime", String(opts.startTime));
|
|
4082
|
+
if ((opts == null ? void 0 : opts.endTime) !== void 0)
|
|
4083
|
+
url.searchParams.set("endTime", String(opts.endTime));
|
|
4084
|
+
if (opts == null ? void 0 : opts.sandboxID) url.searchParams.set("sandboxID", opts.sandboxID);
|
|
4085
|
+
if (opts == null ? void 0 : opts.templateID) url.searchParams.set("templateID", opts.templateID);
|
|
4086
|
+
if (opts == null ? void 0 : opts.events) url.searchParams.set("events", opts.events);
|
|
4087
|
+
if (opts == null ? void 0 : opts.state) url.searchParams.set("state", opts.state);
|
|
4088
|
+
if ((opts == null ? void 0 : opts.orderAsc) !== void 0)
|
|
4089
|
+
url.searchParams.set("orderAsc", String(opts.orderAsc));
|
|
4090
|
+
if ((opts == null ? void 0 : opts.offset) !== void 0)
|
|
4091
|
+
url.searchParams.set("offset", String(opts.offset));
|
|
4092
|
+
if ((opts == null ? void 0 : opts.limit) !== void 0)
|
|
4093
|
+
url.searchParams.set("limit", String(opts.limit));
|
|
4094
|
+
const response = await fetch(url, {
|
|
4095
|
+
method: "GET",
|
|
4096
|
+
headers: __spreadValues(__spreadValues(__spreadValues({}, config.headers), config.apiKey ? { "X-API-KEY": config.apiKey } : {}), config.accessToken ? { Authorization: `Bearer ${config.accessToken}` } : {}),
|
|
4097
|
+
signal: config.getSignal(opts == null ? void 0 : opts.requestTimeoutMs)
|
|
4098
|
+
});
|
|
4099
|
+
if (!response.ok) {
|
|
4100
|
+
throw await createRawApiError(response);
|
|
4101
|
+
}
|
|
4102
|
+
const data = await response.json();
|
|
4103
|
+
return {
|
|
4104
|
+
items: (_a3 = data.items) != null ? _a3 : [],
|
|
4105
|
+
total: (_b = data.total) != null ? _b : 0,
|
|
4106
|
+
hasMore: (_c = data.hasMore) != null ? _c : false
|
|
4107
|
+
};
|
|
4108
|
+
}
|
|
3711
4109
|
};
|
|
3712
4110
|
var BasePaginator = class {
|
|
3713
4111
|
constructor(config, limit, nextToken) {
|
|
@@ -3740,7 +4138,7 @@ var SandboxPaginator = class extends BasePaginator {
|
|
|
3740
4138
|
this.query = opts == null ? void 0 : opts.query;
|
|
3741
4139
|
}
|
|
3742
4140
|
async nextItems() {
|
|
3743
|
-
var _a3, _b, _c;
|
|
4141
|
+
var _a3, _b, _c, _d, _e;
|
|
3744
4142
|
if (!this.hasNext) {
|
|
3745
4143
|
throw new Error("No more items to fetch");
|
|
3746
4144
|
}
|
|
@@ -3754,11 +4152,55 @@ var SandboxPaginator = class extends BasePaginator {
|
|
|
3754
4152
|
);
|
|
3755
4153
|
metadata = new URLSearchParams(encodedPairs).toString();
|
|
3756
4154
|
}
|
|
4155
|
+
if (this.config.isLegacyDomain) {
|
|
4156
|
+
const params = new URLSearchParams();
|
|
4157
|
+
if (metadata) {
|
|
4158
|
+
params.set("metadata", metadata);
|
|
4159
|
+
}
|
|
4160
|
+
if ((_c = (_b = this.query) == null ? void 0 : _b.state) == null ? void 0 : _c.length) {
|
|
4161
|
+
params.set("state", this.query.state.join(","));
|
|
4162
|
+
}
|
|
4163
|
+
if (this.limit) {
|
|
4164
|
+
params.set("limit", String(this.limit));
|
|
4165
|
+
}
|
|
4166
|
+
if (this.nextToken) {
|
|
4167
|
+
params.set("nextToken", this.nextToken);
|
|
4168
|
+
}
|
|
4169
|
+
const query = params.toString();
|
|
4170
|
+
const response = await fetch(
|
|
4171
|
+
`${this.config.apiUrl}/v2/sandboxes${query ? `?${query}` : ""}`,
|
|
4172
|
+
{
|
|
4173
|
+
headers: getRawApiHeaders(this.config),
|
|
4174
|
+
signal: this.config.getSignal()
|
|
4175
|
+
}
|
|
4176
|
+
);
|
|
4177
|
+
if (!response.ok) {
|
|
4178
|
+
throw await createRawApiError(response);
|
|
4179
|
+
}
|
|
4180
|
+
this.updatePagination(response);
|
|
4181
|
+
const data = await response.json();
|
|
4182
|
+
return (data != null ? data : []).map((sandbox) => {
|
|
4183
|
+
var _a4, _b2;
|
|
4184
|
+
return __spreadProps(__spreadValues({
|
|
4185
|
+
sandboxId: sandbox.clientID != null ? `${sandbox.sandboxID}-${sandbox.clientID}` : sandbox.sandboxID,
|
|
4186
|
+
templateId: sandbox.templateID
|
|
4187
|
+
}, sandbox.alias && { name: sandbox.alias }), {
|
|
4188
|
+
metadata: (_a4 = sandbox.metadata) != null ? _a4 : {},
|
|
4189
|
+
startedAt: new Date(sandbox.startedAt),
|
|
4190
|
+
endAt: new Date(sandbox.endAt),
|
|
4191
|
+
state: sandbox.state,
|
|
4192
|
+
cpuCount: sandbox.cpuCount,
|
|
4193
|
+
memoryMB: sandbox.memoryMB,
|
|
4194
|
+
envdVersion: sandbox.envdVersion,
|
|
4195
|
+
volumeMounts: (_b2 = sandbox.volumeMounts) != null ? _b2 : []
|
|
4196
|
+
});
|
|
4197
|
+
});
|
|
4198
|
+
}
|
|
3757
4199
|
const res = await this.client.api.GET("/v2/sandboxes", {
|
|
3758
4200
|
params: {
|
|
3759
4201
|
query: {
|
|
3760
4202
|
metadata,
|
|
3761
|
-
state: (
|
|
4203
|
+
state: (_d = this.query) == null ? void 0 : _d.state,
|
|
3762
4204
|
limit: this.limit,
|
|
3763
4205
|
nextToken: this.nextToken
|
|
3764
4206
|
}
|
|
@@ -3771,11 +4213,11 @@ var SandboxPaginator = class extends BasePaginator {
|
|
|
3771
4213
|
throw err;
|
|
3772
4214
|
}
|
|
3773
4215
|
this.updatePagination(res.response);
|
|
3774
|
-
return ((
|
|
4216
|
+
return ((_e = res.data) != null ? _e : []).map(
|
|
3775
4217
|
(sandbox) => {
|
|
3776
4218
|
var _a4, _b2;
|
|
3777
4219
|
return __spreadProps(__spreadValues({
|
|
3778
|
-
sandboxId: sandbox.sandboxID,
|
|
4220
|
+
sandboxId: this.config.isLegacyDomain && sandbox.clientID != null ? `${sandbox.sandboxID}-${sandbox.clientID}` : sandbox.sandboxID,
|
|
3779
4221
|
templateId: sandbox.templateID
|
|
3780
4222
|
}, sandbox.alias && { name: sandbox.alias }), {
|
|
3781
4223
|
metadata: (_a4 = sandbox.metadata) != null ? _a4 : {},
|
|
@@ -3794,6 +4236,7 @@ var SandboxPaginator = class extends BasePaginator {
|
|
|
3794
4236
|
var SnapshotPaginator = class extends BasePaginator {
|
|
3795
4237
|
constructor(opts) {
|
|
3796
4238
|
super(new ConnectionConfig(opts), opts == null ? void 0 : opts.limit, opts == null ? void 0 : opts.nextToken);
|
|
4239
|
+
raiseIfLegacy(this.config, "Sandbox.listSnapshots", SandboxError);
|
|
3797
4240
|
this.sandboxId = opts == null ? void 0 : opts.sandboxId;
|
|
3798
4241
|
}
|
|
3799
4242
|
async nextItems() {
|
|
@@ -3933,7 +4376,7 @@ var Sandbox = class extends SandboxApi {
|
|
|
3933
4376
|
sandboxOpts
|
|
3934
4377
|
);
|
|
3935
4378
|
const sandbox = new this(__spreadValues(__spreadValues({}, sandboxInfo), config));
|
|
3936
|
-
if (sandboxOpts == null ? void 0 : sandboxOpts.mcp) {
|
|
4379
|
+
if ((sandboxOpts == null ? void 0 : sandboxOpts.mcp) && !config.isLegacyDomain) {
|
|
3937
4380
|
sandbox.mcpToken = crypto.randomUUID();
|
|
3938
4381
|
const res = await sandbox.commands.run(
|
|
3939
4382
|
`mcp-gateway --config ${shellQuote(JSON.stringify(sandboxOpts.mcp))}`,
|
|
@@ -3950,6 +4393,101 @@ var Sandbox = class extends SandboxApi {
|
|
|
3950
4393
|
}
|
|
3951
4394
|
return sandbox;
|
|
3952
4395
|
}
|
|
4396
|
+
/**
|
|
4397
|
+
* Clone a sandbox to create one or more identical sandboxes.
|
|
4398
|
+
*
|
|
4399
|
+
* @param sandboxId source sandbox ID.
|
|
4400
|
+
* @param opts clone options.
|
|
4401
|
+
*
|
|
4402
|
+
* @returns cloned sandbox instances plus snapshot template ID.
|
|
4403
|
+
*/
|
|
4404
|
+
static async clone(sandboxId, opts) {
|
|
4405
|
+
const cloneResult = await SandboxApi.cloneSandboxes(sandboxId, opts);
|
|
4406
|
+
const config = new ConnectionConfig(opts);
|
|
4407
|
+
const sandboxes = cloneResult.sandboxes.map(
|
|
4408
|
+
(sandbox) => new this(__spreadValues({
|
|
4409
|
+
sandboxId: sandbox.sandboxId,
|
|
4410
|
+
envdVersion: sandbox.envdVersion,
|
|
4411
|
+
envdAccessToken: sandbox.envdAccessToken,
|
|
4412
|
+
trafficAccessToken: sandbox.trafficAccessToken
|
|
4413
|
+
}, config))
|
|
4414
|
+
);
|
|
4415
|
+
return {
|
|
4416
|
+
sandboxes,
|
|
4417
|
+
count: sandboxes.length,
|
|
4418
|
+
snapshotTemplateId: cloneResult.snapshotTemplateId
|
|
4419
|
+
};
|
|
4420
|
+
}
|
|
4421
|
+
/**
|
|
4422
|
+
* Dynamically adjust the hotplugged memory on a running sandbox.
|
|
4423
|
+
*
|
|
4424
|
+
* The value represents the new *total* plugged size in MiB, not a delta.
|
|
4425
|
+
* Use `0` to unplug all hotplugged memory.
|
|
4426
|
+
*/
|
|
4427
|
+
static async hotplugMemory(sandboxId, requestedSizeMib, opts) {
|
|
4428
|
+
return await SandboxApi.hotplugMemory(
|
|
4429
|
+
sandboxId,
|
|
4430
|
+
requestedSizeMib,
|
|
4431
|
+
opts
|
|
4432
|
+
);
|
|
4433
|
+
}
|
|
4434
|
+
/**
|
|
4435
|
+
* Mount a volume to a sandbox.
|
|
4436
|
+
*
|
|
4437
|
+
* @param sandboxId sandbox ID.
|
|
4438
|
+
* @param name volume name.
|
|
4439
|
+
* @param path mount path inside the sandbox.
|
|
4440
|
+
* @param opts connection options.
|
|
4441
|
+
*
|
|
4442
|
+
* @returns updated sandbox information.
|
|
4443
|
+
*/
|
|
4444
|
+
static async mountVolume(sandboxId, name, path2, opts) {
|
|
4445
|
+
return await SandboxApi.mountVolume(sandboxId, name, path2, opts);
|
|
4446
|
+
}
|
|
4447
|
+
/**
|
|
4448
|
+
* Unmount a volume from a sandbox.
|
|
4449
|
+
*
|
|
4450
|
+
* @param sandboxId sandbox ID.
|
|
4451
|
+
* @param path mount path to unmount.
|
|
4452
|
+
* @param opts connection options.
|
|
4453
|
+
* @param [opts.force] force unmount.
|
|
4454
|
+
*
|
|
4455
|
+
* @returns updated sandbox information.
|
|
4456
|
+
*/
|
|
4457
|
+
static async unmountVolume(sandboxId, path2, opts) {
|
|
4458
|
+
return await SandboxApi.unmountVolume(sandboxId, path2, opts);
|
|
4459
|
+
}
|
|
4460
|
+
/**
|
|
4461
|
+
* Commit a sandbox to create a snapshot template.
|
|
4462
|
+
*
|
|
4463
|
+
* @deprecated Use snapshot APIs instead. This method is only supported for modern domains.
|
|
4464
|
+
*
|
|
4465
|
+
* @param sandboxId source sandbox ID.
|
|
4466
|
+
* @param opts commit options.
|
|
4467
|
+
*
|
|
4468
|
+
* @returns created snapshot template.
|
|
4469
|
+
*/
|
|
4470
|
+
static async commit(sandboxId, opts) {
|
|
4471
|
+
return await SandboxApi.commit(sandboxId, opts);
|
|
4472
|
+
}
|
|
4473
|
+
/**
|
|
4474
|
+
* Reset sandbox memory and optionally resume the sandbox.
|
|
4475
|
+
*
|
|
4476
|
+
* @param sandboxId sandbox ID.
|
|
4477
|
+
* @param opts reset options.
|
|
4478
|
+
*
|
|
4479
|
+
* @returns `true` if reset succeeded, `false` if the sandbox is in a conflicting state.
|
|
4480
|
+
*/
|
|
4481
|
+
static async reset(sandboxId, opts) {
|
|
4482
|
+
return await SandboxApi.reset(sandboxId, opts);
|
|
4483
|
+
}
|
|
4484
|
+
/**
|
|
4485
|
+
* Update network egress rules for a running sandbox.
|
|
4486
|
+
* Omitting both `allowOut` and `denyOut` clears all egress rules.
|
|
4487
|
+
*/
|
|
4488
|
+
static async setNetwork(sandboxId, opts) {
|
|
4489
|
+
await SandboxApi.setNetwork(sandboxId, opts);
|
|
4490
|
+
}
|
|
3953
4491
|
static async betaCreate(templateOrOpts, opts) {
|
|
3954
4492
|
var _a3, _b, _c;
|
|
3955
4493
|
const { template, sandboxOpts } = typeof templateOrOpts === "string" ? {
|
|
@@ -3972,7 +4510,7 @@ var Sandbox = class extends SandboxApi {
|
|
|
3972
4510
|
sandboxOpts
|
|
3973
4511
|
);
|
|
3974
4512
|
const sandbox = new this(__spreadValues(__spreadValues({}, sandboxInfo), config));
|
|
3975
|
-
if (sandboxOpts == null ? void 0 : sandboxOpts.mcp) {
|
|
4513
|
+
if ((sandboxOpts == null ? void 0 : sandboxOpts.mcp) && !config.isLegacyDomain) {
|
|
3976
4514
|
sandbox.mcpToken = crypto.randomUUID();
|
|
3977
4515
|
const res = await sandbox.commands.run(
|
|
3978
4516
|
`mcp-gateway --config ${shellQuote(JSON.stringify(sandboxOpts.mcp))}`,
|
|
@@ -4114,6 +4652,68 @@ var Sandbox = class extends SandboxApi {
|
|
|
4114
4652
|
this.resolveApiOpts(opts)
|
|
4115
4653
|
);
|
|
4116
4654
|
}
|
|
4655
|
+
/**
|
|
4656
|
+
* Reset sandbox memory and optionally resume the sandbox.
|
|
4657
|
+
*
|
|
4658
|
+
* @param opts reset options.
|
|
4659
|
+
*
|
|
4660
|
+
* @returns `true` if reset succeeded, `false` if the sandbox is in a conflicting state.
|
|
4661
|
+
*/
|
|
4662
|
+
async reset(opts) {
|
|
4663
|
+
return await SandboxApi.reset(this.sandboxId, this.resolveApiOpts(opts));
|
|
4664
|
+
}
|
|
4665
|
+
/**
|
|
4666
|
+
* Update network egress rules for this running sandbox.
|
|
4667
|
+
* Omitting both `allowOut` and `denyOut` clears all egress rules.
|
|
4668
|
+
*/
|
|
4669
|
+
async setNetwork(opts) {
|
|
4670
|
+
await SandboxApi.setNetwork(this.sandboxId, this.resolveApiOpts(opts));
|
|
4671
|
+
}
|
|
4672
|
+
/**
|
|
4673
|
+
* Commit this sandbox to create a snapshot template.
|
|
4674
|
+
*
|
|
4675
|
+
* @deprecated Use snapshot APIs instead. This method is only supported for modern domains.
|
|
4676
|
+
*
|
|
4677
|
+
* @param opts commit options.
|
|
4678
|
+
*
|
|
4679
|
+
* @returns created snapshot template.
|
|
4680
|
+
*/
|
|
4681
|
+
async commit(opts) {
|
|
4682
|
+
return await SandboxApi.commit(this.sandboxId, this.resolveApiOpts(opts));
|
|
4683
|
+
}
|
|
4684
|
+
/**
|
|
4685
|
+
* Mount a volume to this sandbox.
|
|
4686
|
+
*
|
|
4687
|
+
* @param name volume name.
|
|
4688
|
+
* @param path mount path inside the sandbox.
|
|
4689
|
+
* @param opts connection options.
|
|
4690
|
+
*
|
|
4691
|
+
* @returns updated sandbox information.
|
|
4692
|
+
*/
|
|
4693
|
+
async mountVolume(name, path2, opts) {
|
|
4694
|
+
return await SandboxApi.mountVolume(
|
|
4695
|
+
this.sandboxId,
|
|
4696
|
+
name,
|
|
4697
|
+
path2,
|
|
4698
|
+
this.resolveApiOpts(opts)
|
|
4699
|
+
);
|
|
4700
|
+
}
|
|
4701
|
+
/**
|
|
4702
|
+
* Unmount a volume from this sandbox.
|
|
4703
|
+
*
|
|
4704
|
+
* @param path mount path to unmount.
|
|
4705
|
+
* @param opts connection options.
|
|
4706
|
+
* @param [opts.force] force unmount.
|
|
4707
|
+
*
|
|
4708
|
+
* @returns updated sandbox information.
|
|
4709
|
+
*/
|
|
4710
|
+
async unmountVolume(path2, opts) {
|
|
4711
|
+
return await SandboxApi.unmountVolume(
|
|
4712
|
+
this.sandboxId,
|
|
4713
|
+
path2,
|
|
4714
|
+
this.resolveApiOpts(opts)
|
|
4715
|
+
);
|
|
4716
|
+
}
|
|
4117
4717
|
/**
|
|
4118
4718
|
* Kill the sandbox.
|
|
4119
4719
|
*
|
|
@@ -4125,6 +4725,22 @@ var Sandbox = class extends SandboxApi {
|
|
|
4125
4725
|
}
|
|
4126
4726
|
await SandboxApi.kill(this.sandboxId, this.resolveApiOpts(opts));
|
|
4127
4727
|
}
|
|
4728
|
+
/**
|
|
4729
|
+
* Dynamically adjust the hotplugged memory on a running sandbox.
|
|
4730
|
+
*
|
|
4731
|
+
* The value represents the new *total* plugged size in MiB, not a delta.
|
|
4732
|
+
* Use `0` to unplug all hotplugged memory.
|
|
4733
|
+
*
|
|
4734
|
+
* @param requestedSizeMib new total plugged memory size in MiB.
|
|
4735
|
+
* @param opts connection options.
|
|
4736
|
+
*/
|
|
4737
|
+
async hotplugMemory(requestedSizeMib, opts) {
|
|
4738
|
+
await SandboxApi.hotplugMemory(
|
|
4739
|
+
this.sandboxId,
|
|
4740
|
+
requestedSizeMib,
|
|
4741
|
+
this.resolveApiOpts(opts)
|
|
4742
|
+
);
|
|
4743
|
+
}
|
|
4128
4744
|
/**
|
|
4129
4745
|
* Pause a sandbox by its ID.
|
|
4130
4746
|
*
|
|
@@ -4145,7 +4761,10 @@ var Sandbox = class extends SandboxApi {
|
|
|
4145
4761
|
* @deprecated Use {@link Sandbox.pause} instead.
|
|
4146
4762
|
*/
|
|
4147
4763
|
async betaPause(opts) {
|
|
4148
|
-
return await SandboxApi.betaPause(
|
|
4764
|
+
return await SandboxApi.betaPause(
|
|
4765
|
+
this.sandboxId,
|
|
4766
|
+
this.resolveApiOpts(opts)
|
|
4767
|
+
);
|
|
4149
4768
|
}
|
|
4150
4769
|
/**
|
|
4151
4770
|
* Create a snapshot of the sandbox's current state.
|
|
@@ -4197,6 +4816,7 @@ var Sandbox = class extends SandboxApi {
|
|
|
4197
4816
|
* @returns MCP URL for the sandbox.
|
|
4198
4817
|
*/
|
|
4199
4818
|
getMcpUrl() {
|
|
4819
|
+
raiseIfLegacy(this.connectionConfig, "Sandbox.getMcpUrl", SandboxError);
|
|
4200
4820
|
return `https://${this.getHost(this.mcpPort)}/mcp`;
|
|
4201
4821
|
}
|
|
4202
4822
|
/**
|
|
@@ -4205,6 +4825,7 @@ var Sandbox = class extends SandboxApi {
|
|
|
4205
4825
|
* @returns MCP token for the sandbox, or undefined if MCP is not enabled.
|
|
4206
4826
|
*/
|
|
4207
4827
|
async getMcpToken() {
|
|
4828
|
+
raiseIfLegacy(this.connectionConfig, "Sandbox.getMcpToken", SandboxError);
|
|
4208
4829
|
if (!this.mcpToken) {
|
|
4209
4830
|
this.mcpToken = await this.files.read("/etc/mcp-gateway/.token", {
|
|
4210
4831
|
user: "root"
|
|
@@ -5158,6 +5779,123 @@ function handleCmdEntrypointInstruction(instruction, templateBuilder) {
|
|
|
5158
5779
|
}
|
|
5159
5780
|
|
|
5160
5781
|
// src/core/template/index.ts
|
|
5782
|
+
var TemplateApi = class {
|
|
5783
|
+
static async listTemplates(options) {
|
|
5784
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h;
|
|
5785
|
+
const templateType = (_a3 = options == null ? void 0 : options.templateType) != null ? _a3 : "template_build";
|
|
5786
|
+
const page = (_b = options == null ? void 0 : options.page) != null ? _b : 1;
|
|
5787
|
+
const limit = (_c = options == null ? void 0 : options.limit) != null ? _c : 20;
|
|
5788
|
+
if (!["template_build", "snapshot_template"].includes(templateType)) {
|
|
5789
|
+
throw new Error(
|
|
5790
|
+
'templateType must be either "template_build" or "snapshot_template"'
|
|
5791
|
+
);
|
|
5792
|
+
}
|
|
5793
|
+
if (page < 1) {
|
|
5794
|
+
throw new Error("page must be >= 1");
|
|
5795
|
+
}
|
|
5796
|
+
if (limit < 1 || limit > 100) {
|
|
5797
|
+
throw new Error("limit must be between 1 and 100");
|
|
5798
|
+
}
|
|
5799
|
+
const config = new ConnectionConfig(options);
|
|
5800
|
+
const url = new URL(`${config.apiUrl}/v2/templates`);
|
|
5801
|
+
url.searchParams.set("template_type", templateType);
|
|
5802
|
+
url.searchParams.set("page", String(page));
|
|
5803
|
+
url.searchParams.set("limit", String(limit));
|
|
5804
|
+
const response = await fetch(url, {
|
|
5805
|
+
method: "GET",
|
|
5806
|
+
headers: __spreadValues(__spreadValues(__spreadValues({}, config.headers), config.apiKey ? { "X-API-KEY": config.apiKey } : {}), config.accessToken ? { Authorization: `Bearer ${config.accessToken}` } : {}),
|
|
5807
|
+
signal: config.getSignal(options == null ? void 0 : options.requestTimeoutMs)
|
|
5808
|
+
});
|
|
5809
|
+
if (!response.ok) {
|
|
5810
|
+
throw new Error(`${response.status}: ${await response.text()}`);
|
|
5811
|
+
}
|
|
5812
|
+
const data = await response.json();
|
|
5813
|
+
if (!data) {
|
|
5814
|
+
throw new Error("Template list response data is missing");
|
|
5815
|
+
}
|
|
5816
|
+
return {
|
|
5817
|
+
templates: ((_d = data.templates) != null ? _d : []).map(
|
|
5818
|
+
(template) => ({
|
|
5819
|
+
templateId: template.templateID,
|
|
5820
|
+
aliases: template.aliases,
|
|
5821
|
+
buildCount: template.buildCount,
|
|
5822
|
+
buildId: template.buildID,
|
|
5823
|
+
cpuCount: template.cpuCount,
|
|
5824
|
+
createdAt: new Date(template.createdAt),
|
|
5825
|
+
createdBy: template.createdBy,
|
|
5826
|
+
diskSizeMB: template.diskSizeMB,
|
|
5827
|
+
envdVersion: template.envdVersion,
|
|
5828
|
+
lastSpawnedAt: template.lastSpawnedAt ? new Date(template.lastSpawnedAt) : null,
|
|
5829
|
+
memoryMB: template.memoryMB,
|
|
5830
|
+
metadata: template.metadata,
|
|
5831
|
+
public: template.public,
|
|
5832
|
+
spawnCount: template.spawnCount,
|
|
5833
|
+
templateType: template.templateType,
|
|
5834
|
+
originSandboxID: template.originSandboxID,
|
|
5835
|
+
updatedAt: new Date(template.updatedAt)
|
|
5836
|
+
})
|
|
5837
|
+
),
|
|
5838
|
+
page: (_e = data.page) != null ? _e : page,
|
|
5839
|
+
limit: (_f = data.limit) != null ? _f : limit,
|
|
5840
|
+
total: (_g = data.total) != null ? _g : 0,
|
|
5841
|
+
totalPages: (_h = data.totalPages) != null ? _h : 0
|
|
5842
|
+
};
|
|
5843
|
+
}
|
|
5844
|
+
static async deleteTemplate(templateId, options) {
|
|
5845
|
+
var _a3;
|
|
5846
|
+
if (!templateId) {
|
|
5847
|
+
throw new Error("templateId cannot be empty");
|
|
5848
|
+
}
|
|
5849
|
+
const config = new ConnectionConfig(options);
|
|
5850
|
+
const client = new ApiClient(config);
|
|
5851
|
+
const res = await client.api.DELETE("/templates/{templateID}", {
|
|
5852
|
+
params: {
|
|
5853
|
+
path: {
|
|
5854
|
+
templateID: templateId
|
|
5855
|
+
}
|
|
5856
|
+
},
|
|
5857
|
+
signal: config.getSignal(options == null ? void 0 : options.requestTimeoutMs)
|
|
5858
|
+
});
|
|
5859
|
+
if (((_a3 = res.error) == null ? void 0 : _a3.code) === 404 || res.response.status === 404) {
|
|
5860
|
+
return false;
|
|
5861
|
+
}
|
|
5862
|
+
const err = handleApiError(res, BuildError);
|
|
5863
|
+
if (err) {
|
|
5864
|
+
throw err;
|
|
5865
|
+
}
|
|
5866
|
+
return true;
|
|
5867
|
+
}
|
|
5868
|
+
};
|
|
5869
|
+
var TemplatePaginator = class {
|
|
5870
|
+
constructor(options) {
|
|
5871
|
+
this.hasNextPage = true;
|
|
5872
|
+
var _a3;
|
|
5873
|
+
this.options = options;
|
|
5874
|
+
this.nextPageNumber = (_a3 = options == null ? void 0 : options.page) != null ? _a3 : 1;
|
|
5875
|
+
}
|
|
5876
|
+
get hasNext() {
|
|
5877
|
+
return this.hasNextPage;
|
|
5878
|
+
}
|
|
5879
|
+
get currentPage() {
|
|
5880
|
+
return this.nextPageNumber;
|
|
5881
|
+
}
|
|
5882
|
+
async nextPage() {
|
|
5883
|
+
if (!this.hasNextPage) {
|
|
5884
|
+
throw new Error("No more pages to fetch");
|
|
5885
|
+
}
|
|
5886
|
+
const response = await TemplateApi.listTemplates(__spreadProps(__spreadValues({}, this.options), {
|
|
5887
|
+
page: this.nextPageNumber
|
|
5888
|
+
}));
|
|
5889
|
+
this.hasNextPage = response.page < response.totalPages;
|
|
5890
|
+
this.nextPageNumber = response.page + 1;
|
|
5891
|
+
return response;
|
|
5892
|
+
}
|
|
5893
|
+
reset() {
|
|
5894
|
+
var _a3, _b;
|
|
5895
|
+
this.nextPageNumber = (_b = (_a3 = this.options) == null ? void 0 : _a3.page) != null ? _b : 1;
|
|
5896
|
+
this.hasNextPage = true;
|
|
5897
|
+
}
|
|
5898
|
+
};
|
|
5161
5899
|
var _a2;
|
|
5162
5900
|
var TemplateBase = class _TemplateBase {
|
|
5163
5901
|
constructor(options) {
|
|
@@ -5167,6 +5905,7 @@ var TemplateBase = class _TemplateBase {
|
|
|
5167
5905
|
this.registryConfig = void 0;
|
|
5168
5906
|
this.startCmd = void 0;
|
|
5169
5907
|
this.readyCmd = void 0;
|
|
5908
|
+
this.patchCmd = void 0;
|
|
5170
5909
|
// Force the whole template to be rebuilt
|
|
5171
5910
|
this.force = false;
|
|
5172
5911
|
// Force the next layer to be rebuilt
|
|
@@ -5182,6 +5921,9 @@ var TemplateBase = class _TemplateBase {
|
|
|
5182
5921
|
this.fileContextPath = (_a3 = options == null ? void 0 : options.fileContextPath) != null ? _a3 : this.fileContextPath;
|
|
5183
5922
|
this.fileIgnorePatterns = (_b = options == null ? void 0 : options.fileIgnorePatterns) != null ? _b : this.fileIgnorePatterns;
|
|
5184
5923
|
}
|
|
5924
|
+
static list(options) {
|
|
5925
|
+
return new TemplatePaginator(options);
|
|
5926
|
+
}
|
|
5185
5927
|
/**
|
|
5186
5928
|
* Convert a template to JSON representation.
|
|
5187
5929
|
*
|
|
@@ -5260,6 +6002,15 @@ var TemplateBase = class _TemplateBase {
|
|
|
5260
6002
|
logsOffset: options == null ? void 0 : options.logsOffset
|
|
5261
6003
|
});
|
|
5262
6004
|
}
|
|
6005
|
+
static async listTemplates(options) {
|
|
6006
|
+
return TemplateApi.listTemplates(options);
|
|
6007
|
+
}
|
|
6008
|
+
static async delete(templateId, options) {
|
|
6009
|
+
await TemplateApi.deleteTemplate(templateId, options);
|
|
6010
|
+
}
|
|
6011
|
+
static async deleteTemplate(templateId, options) {
|
|
6012
|
+
return TemplateApi.deleteTemplate(templateId, options);
|
|
6013
|
+
}
|
|
5263
6014
|
/**
|
|
5264
6015
|
* Check if a template with the given name exists.
|
|
5265
6016
|
*
|
|
@@ -5728,6 +6479,11 @@ var TemplateBase = class _TemplateBase {
|
|
|
5728
6479
|
this.collectStackTrace();
|
|
5729
6480
|
return this;
|
|
5730
6481
|
}
|
|
6482
|
+
setPatchCmd(cmd) {
|
|
6483
|
+
this.patchCmd = cmd;
|
|
6484
|
+
this.collectStackTrace();
|
|
6485
|
+
return this;
|
|
6486
|
+
}
|
|
5731
6487
|
setEnvs(envs) {
|
|
5732
6488
|
if (Object.keys(envs).length === 0) {
|
|
5733
6489
|
return this;
|
|
@@ -6053,6 +6809,7 @@ var TemplateBase = class _TemplateBase {
|
|
|
6053
6809
|
const templateData = {
|
|
6054
6810
|
startCmd: this.startCmd,
|
|
6055
6811
|
readyCmd: this.readyCmd,
|
|
6812
|
+
preBootScript: this.patchCmd,
|
|
6056
6813
|
steps,
|
|
6057
6814
|
force: this.force
|
|
6058
6815
|
};
|
|
@@ -6079,6 +6836,8 @@ Template.aliasExists = TemplateBase.aliasExists;
|
|
|
6079
6836
|
Template.assignTags = TemplateBase.assignTags;
|
|
6080
6837
|
Template.removeTags = TemplateBase.removeTags;
|
|
6081
6838
|
Template.getTags = TemplateBase.getTags;
|
|
6839
|
+
Template.list = TemplateBase.list;
|
|
6840
|
+
Template.delete = TemplateBase.delete;
|
|
6082
6841
|
Template.toJSON = TemplateBase.toJSON;
|
|
6083
6842
|
Template.toDockerfile = TemplateBase.toDockerfile;
|
|
6084
6843
|
|
|
@@ -6561,13 +7320,16 @@ var code_interpreter_default = Sandbox2;
|
|
|
6561
7320
|
Sandbox,
|
|
6562
7321
|
SandboxError,
|
|
6563
7322
|
SandboxNotFoundError,
|
|
7323
|
+
Secret,
|
|
7324
|
+
SecretError,
|
|
6564
7325
|
Template,
|
|
7326
|
+
TemplateApi,
|
|
6565
7327
|
TemplateBase,
|
|
6566
7328
|
TemplateError,
|
|
7329
|
+
TemplatePaginator,
|
|
6567
7330
|
TimeoutError,
|
|
6568
7331
|
Volume,
|
|
6569
7332
|
VolumeError,
|
|
6570
|
-
VolumeFileType,
|
|
6571
7333
|
defaultBuildLogger,
|
|
6572
7334
|
getSignature,
|
|
6573
7335
|
waitForFile,
|