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