@tensorlakeai/tensorlake 0.5.152 → 0.5.154
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/applications/index.cjs +3596 -3377
- package/dist/applications/index.cjs.map +1 -1
- package/dist/applications/index.d.cts +3 -3
- package/dist/applications/index.d.ts +3 -3
- package/dist/applications/index.js +3559 -3340
- package/dist/applications/index.js.map +1 -1
- package/dist/function-agent/main.cjs +1 -1
- package/dist/function-agent/main.js +1 -1
- package/dist/function-executor/main.cjs +2 -2
- package/dist/function-executor/main.js +2 -2
- package/dist/index.cjs +1502 -880
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +366 -21
- package/dist/index.d.ts +366 -21
- package/dist/index.js +1475 -871
- package/dist/index.js.map +1 -1
- package/dist/{remote-CC48cvYP.d.cts → remote-B3vn4tt1.d.cts} +1 -1
- package/dist/{remote-BbSrvgUn.d.ts → remote-DqBUuciu.d.ts} +1 -1
- package/dist/{sandbox-image-CAK_K7ND.d.cts → sandbox-image-BMiFlzAs.d.cts} +168 -13
- package/dist/{sandbox-image-CAK_K7ND.d.ts → sandbox-image-BMiFlzAs.d.ts} +168 -13
- package/dist/sandbox-image.cjs +437 -1300
- package/dist/sandbox-image.cjs.map +1 -1
- package/dist/sandbox-image.d.cts +1 -1
- package/dist/sandbox-image.d.ts +1 -1
- package/dist/sandbox-image.js +436 -1299
- package/dist/sandbox-image.js.map +1 -1
- package/package.json +7 -7
- package/runtime/function-executor/manifest.json +5 -5
- package/runtime/function-executor/package/dist/function-executor/main.js +2 -2
- package/runtime/function-executor/package/npm-shrinkwrap.json +2 -2
- package/runtime/function-executor/package/package.json +1 -1
- package/runtime/typescript-function-runner/manifest.json +5 -5
- package/runtime/typescript-function-runner/package/dist/function-agent/main.js +1 -1
- package/runtime/typescript-function-runner/package/npm-shrinkwrap.json +26 -26
- package/runtime/typescript-function-runner/package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -49,7 +49,7 @@ var init_defaults = __esm({
|
|
|
49
49
|
"src/defaults.ts"() {
|
|
50
50
|
"use strict";
|
|
51
51
|
init_cjs_shims();
|
|
52
|
-
SDK_VERSION = "0.5.
|
|
52
|
+
SDK_VERSION = "0.5.154";
|
|
53
53
|
API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
|
|
54
54
|
API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
|
|
55
55
|
NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
|
|
@@ -60,6 +60,20 @@ var init_defaults = __esm({
|
|
|
60
60
|
}
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
+
// src/enum.ts
|
|
64
|
+
function enumValue(values, value) {
|
|
65
|
+
return typeof value === "string" && Object.values(values).includes(value) ? value : values.UNKNOWN;
|
|
66
|
+
}
|
|
67
|
+
function withRaw(value, raw) {
|
|
68
|
+
return Object.defineProperty(value, "raw", { value: raw, enumerable: false, configurable: true });
|
|
69
|
+
}
|
|
70
|
+
var init_enum = __esm({
|
|
71
|
+
"src/enum.ts"() {
|
|
72
|
+
"use strict";
|
|
73
|
+
init_cjs_shims();
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
63
77
|
// src/errors.ts
|
|
64
78
|
function formatErrorDetails(errorDetails) {
|
|
65
79
|
if (errorDetails == null) return void 0;
|
|
@@ -498,7 +512,7 @@ var init_native_worker_client = __esm({
|
|
|
498
512
|
}
|
|
499
513
|
};
|
|
500
514
|
runtimeKey = /* @__PURE__ */ Symbol.for(
|
|
501
|
-
`tensorlake.native.worker.${false ? "source" : "0.5.
|
|
515
|
+
`tensorlake.native.worker.${false ? "source" : "0.5.154"}.v1`
|
|
502
516
|
);
|
|
503
517
|
runtimes = globalThis;
|
|
504
518
|
}
|
|
@@ -598,6 +612,9 @@ var init_models = __esm({
|
|
|
598
612
|
SnapshotStatus2["LOCAL_READY"] = "local_ready";
|
|
599
613
|
SnapshotStatus2["COMPLETED"] = "completed";
|
|
600
614
|
SnapshotStatus2["FAILED"] = "failed";
|
|
615
|
+
SnapshotStatus2["DELETING"] = "deleting";
|
|
616
|
+
SnapshotStatus2["REPLICATING"] = "replicating";
|
|
617
|
+
SnapshotStatus2["UNKNOWN"] = "unknown";
|
|
601
618
|
return SnapshotStatus2;
|
|
602
619
|
})(SnapshotStatus || {});
|
|
603
620
|
ProcessStatus = /* @__PURE__ */ ((ProcessStatus2) => {
|
|
@@ -3886,9 +3903,8 @@ var init_sandbox = __esm({
|
|
|
3886
3903
|
*
|
|
3887
3904
|
* Resource targets use create's cpus, memoryMb, and diskMb names. Resize
|
|
3888
3905
|
* waits by default; wait=false returns admission. Timeout does not cancel it.
|
|
3889
|
-
*
|
|
3890
|
-
*
|
|
3891
|
-
* Non-CAS sandboxes do not support live resize.
|
|
3906
|
+
* Which runtimes and dimensions support a live resize is decided by the
|
|
3907
|
+
* server, whose policy error is thrown unchanged.
|
|
3892
3908
|
* Wait, timeout, and pollInterval are ignored on non-resource updates.
|
|
3893
3909
|
* A no-op returns current resources with absent or earlier resize metadata.
|
|
3894
3910
|
*
|
|
@@ -4306,29 +4322,29 @@ var init_sandbox = __esm({
|
|
|
4306
4322
|
}
|
|
4307
4323
|
// --- File operations ---
|
|
4308
4324
|
/** Read a file from the sandbox and return its raw bytes. */
|
|
4309
|
-
async readFile(
|
|
4325
|
+
async readFile(path4) {
|
|
4310
4326
|
const proxy = await this.proxy.client();
|
|
4311
|
-
const { traceId, data } = await callNative(() => proxy.readFile(
|
|
4327
|
+
const { traceId, data } = await callNative(() => proxy.readFile(path4), {
|
|
4312
4328
|
sandboxId: this.sandboxId
|
|
4313
4329
|
});
|
|
4314
4330
|
return Object.assign(Uint8Array.from(data), { traceId });
|
|
4315
4331
|
}
|
|
4316
4332
|
/** Write raw bytes to a file in the sandbox, creating it if it does not exist. */
|
|
4317
|
-
async writeFile(
|
|
4333
|
+
async writeFile(path4, content) {
|
|
4318
4334
|
const proxy = await this.proxy.client();
|
|
4319
|
-
await callNative(() => proxy.writeFile(
|
|
4335
|
+
await callNative(() => proxy.writeFile(path4, Buffer.from(content)), {
|
|
4320
4336
|
sandboxId: this.sandboxId
|
|
4321
4337
|
});
|
|
4322
4338
|
}
|
|
4323
4339
|
/** Delete a file from the sandbox. */
|
|
4324
|
-
async deleteFile(
|
|
4340
|
+
async deleteFile(path4) {
|
|
4325
4341
|
const proxy = await this.proxy.client();
|
|
4326
|
-
await callNative(() => proxy.deleteFile(
|
|
4342
|
+
await callNative(() => proxy.deleteFile(path4), { sandboxId: this.sandboxId });
|
|
4327
4343
|
}
|
|
4328
4344
|
/** List the contents of a directory in the sandbox. */
|
|
4329
|
-
async listDirectory(
|
|
4345
|
+
async listDirectory(path4) {
|
|
4330
4346
|
const proxy = await this.proxy.client();
|
|
4331
|
-
const { traceId, json } = await callNative(() => proxy.listDirectory(
|
|
4347
|
+
const { traceId, json } = await callNative(() => proxy.listDirectory(path4), {
|
|
4332
4348
|
sandboxId: this.sandboxId
|
|
4333
4349
|
});
|
|
4334
4350
|
return Object.assign(fromSnakeKeys(JSON.parse(json)), {
|
|
@@ -4495,6 +4511,18 @@ __export(client_exports, {
|
|
|
4495
4511
|
DEFAULT_WAIT_POLL_INTERVAL_SEC: () => DEFAULT_WAIT_POLL_INTERVAL_SEC,
|
|
4496
4512
|
SandboxClient: () => SandboxClient
|
|
4497
4513
|
});
|
|
4514
|
+
function parseSnapshot(raw) {
|
|
4515
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
4516
|
+
throw new SandboxError("Invalid snapshot response: expected an object");
|
|
4517
|
+
}
|
|
4518
|
+
if (raw.status == null) {
|
|
4519
|
+
throw new SandboxError("Invalid snapshot response: missing status");
|
|
4520
|
+
}
|
|
4521
|
+
return withRaw({
|
|
4522
|
+
...fromSnakeKeys(raw, "snapshotId"),
|
|
4523
|
+
status: enumValue(SnapshotStatus, raw.status)
|
|
4524
|
+
}, raw);
|
|
4525
|
+
}
|
|
4498
4526
|
function requireReadOnlySnapshotPin(fileSystemId, mountPath, readOnly, snapshotId) {
|
|
4499
4527
|
if (snapshotId != null && readOnly !== true) {
|
|
4500
4528
|
throw new SandboxError(
|
|
@@ -4616,6 +4644,7 @@ var init_client = __esm({
|
|
|
4616
4644
|
"use strict";
|
|
4617
4645
|
init_cjs_shims();
|
|
4618
4646
|
init_defaults();
|
|
4647
|
+
init_enum();
|
|
4619
4648
|
init_errors();
|
|
4620
4649
|
init_native_worker_client();
|
|
4621
4650
|
init_native_sandbox();
|
|
@@ -4994,9 +5023,9 @@ var init_client = __esm({
|
|
|
4994
5023
|
});
|
|
4995
5024
|
}
|
|
4996
5025
|
/**
|
|
4997
|
-
* Update properties or resize a running sandbox.
|
|
4998
|
-
*
|
|
4999
|
-
*
|
|
5026
|
+
* Update properties or resize a running sandbox. Which runtimes and
|
|
5027
|
+
* dimensions support a live resize is decided by the server, whose policy
|
|
5028
|
+
* error is thrown unchanged.
|
|
5000
5029
|
* Resource names match create. Resize waits by default; wait=false returns
|
|
5001
5030
|
* admission. Timeout leaves the resize running and reports its generation.
|
|
5002
5031
|
* Wait, timeout, and pollInterval are ignored on non-resource updates.
|
|
@@ -5263,18 +5292,18 @@ var init_client = __esm({
|
|
|
5263
5292
|
* block automatically.
|
|
5264
5293
|
*/
|
|
5265
5294
|
async snapshot(sandboxId, options) {
|
|
5266
|
-
|
|
5295
|
+
const { json } = await callNative(
|
|
5267
5296
|
() => this.native.createSnapshot(sandboxId, options?.snapshotType ?? null),
|
|
5268
|
-
"snapshotId",
|
|
5269
5297
|
{ sandboxId, notFoundKind: "sandbox" }
|
|
5270
5298
|
);
|
|
5299
|
+
return parseSnapshot(JSON.parse(json));
|
|
5271
5300
|
}
|
|
5272
5301
|
/** Get current status and metadata for a snapshot by ID. */
|
|
5273
5302
|
async getSnapshot(snapshotId) {
|
|
5274
|
-
|
|
5275
|
-
() => this.native.getSnapshot(snapshotId)
|
|
5276
|
-
"snapshotId"
|
|
5303
|
+
const { traceId, json } = await callNative(
|
|
5304
|
+
() => this.native.getSnapshot(snapshotId)
|
|
5277
5305
|
);
|
|
5306
|
+
return Object.assign(parseSnapshot(JSON.parse(json)), { traceId });
|
|
5278
5307
|
}
|
|
5279
5308
|
/** List all snapshots in the namespace. */
|
|
5280
5309
|
async listSnapshots() {
|
|
@@ -5282,9 +5311,14 @@ var init_client = __esm({
|
|
|
5282
5311
|
() => this.native.listSnapshots()
|
|
5283
5312
|
);
|
|
5284
5313
|
const parsed = JSON.parse(json);
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5314
|
+
if (parsed !== null && (typeof parsed !== "object" || Array.isArray(parsed))) {
|
|
5315
|
+
throw new SandboxError("Invalid snapshot list response: expected an object");
|
|
5316
|
+
}
|
|
5317
|
+
const records = parsed?.snapshots ?? [];
|
|
5318
|
+
if (!Array.isArray(records)) {
|
|
5319
|
+
throw new SandboxError("Invalid snapshot list response: snapshots must be an array");
|
|
5320
|
+
}
|
|
5321
|
+
const snapshots = records.map((s) => parseSnapshot(s));
|
|
5288
5322
|
return Object.assign(snapshots, { traceId });
|
|
5289
5323
|
}
|
|
5290
5324
|
/** Delete a snapshot by ID. */
|
|
@@ -5315,6 +5349,11 @@ var init_client = __esm({
|
|
|
5315
5349
|
`Snapshot ${result.snapshotId} failed: ${info.error}`
|
|
5316
5350
|
);
|
|
5317
5351
|
}
|
|
5352
|
+
if (info.status === "deleting" /* DELETING */) {
|
|
5353
|
+
throw new SandboxError(
|
|
5354
|
+
`Snapshot ${result.snapshotId} is being deleted`
|
|
5355
|
+
);
|
|
5356
|
+
}
|
|
5318
5357
|
await sleep2(pollInterval * 1e3);
|
|
5319
5358
|
}
|
|
5320
5359
|
throw new SandboxError(
|
|
@@ -5572,694 +5611,115 @@ var init_client = __esm({
|
|
|
5572
5611
|
}
|
|
5573
5612
|
});
|
|
5574
5613
|
|
|
5575
|
-
// src/
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
if (!Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) {
|
|
5582
|
-
headers["Content-Type"] = "application/json";
|
|
5583
|
-
}
|
|
5584
|
-
}
|
|
5585
|
-
const request = {
|
|
5586
|
-
method,
|
|
5587
|
-
path: path3,
|
|
5588
|
-
headersJson: JSON.stringify(headers),
|
|
5589
|
-
statusOnlyCodes: [...options?.statusOnlyCodes ?? []]
|
|
5614
|
+
// src/image.ts
|
|
5615
|
+
function cloneOperation(op) {
|
|
5616
|
+
return {
|
|
5617
|
+
type: op.type,
|
|
5618
|
+
args: [...op.args],
|
|
5619
|
+
options: { ...op.options }
|
|
5590
5620
|
};
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
} else if (body !== void 0) {
|
|
5597
|
-
if (body instanceof Blob) request.body = Buffer.from(await body.arrayBuffer());
|
|
5598
|
-
else if (typeof body === "string") request.body = Buffer.from(body);
|
|
5599
|
-
else if (body instanceof ArrayBuffer) request.body = Buffer.from(new Uint8Array(body));
|
|
5600
|
-
else request.body = Buffer.from(body);
|
|
5621
|
+
}
|
|
5622
|
+
function renderOptions(options) {
|
|
5623
|
+
const entries = Object.entries(options);
|
|
5624
|
+
if (entries.length === 0) {
|
|
5625
|
+
return "";
|
|
5601
5626
|
}
|
|
5602
|
-
return
|
|
5627
|
+
return ` ${entries.map(([key, value]) => `--${key}=${value}`).join(" ")}`;
|
|
5628
|
+
}
|
|
5629
|
+
function renderBuildOp(op) {
|
|
5630
|
+
const options = renderOptions(op.options);
|
|
5631
|
+
if (op.type === ImageBuildOperationType.ENV) {
|
|
5632
|
+
return `ENV${options} ${op.args[0]}=${JSON.stringify(op.args[1])}`;
|
|
5633
|
+
}
|
|
5634
|
+
return `${op.type}${options} ${op.args.join(" ")}`;
|
|
5635
|
+
}
|
|
5636
|
+
function dockerfileContent(image) {
|
|
5637
|
+
const lines = image.baseImage == null ? [] : [`FROM ${image.baseImage}`];
|
|
5638
|
+
lines.push(...image.buildOperations.map((op) => renderBuildOp(op)));
|
|
5639
|
+
return lines.join("\n");
|
|
5603
5640
|
}
|
|
5604
|
-
var
|
|
5605
|
-
var
|
|
5606
|
-
"src/
|
|
5641
|
+
var import_node_crypto, DEFAULT_IMAGE_NAME, ImageBuildOperationType, Image;
|
|
5642
|
+
var init_image = __esm({
|
|
5643
|
+
"src/image.ts"() {
|
|
5607
5644
|
"use strict";
|
|
5608
5645
|
init_cjs_shims();
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5646
|
+
import_node_crypto = require("crypto");
|
|
5647
|
+
DEFAULT_IMAGE_NAME = "default";
|
|
5648
|
+
ImageBuildOperationType = {
|
|
5649
|
+
ADD: "ADD",
|
|
5650
|
+
COPY: "COPY",
|
|
5651
|
+
ENV: "ENV",
|
|
5652
|
+
RUN: "RUN",
|
|
5653
|
+
WORKDIR: "WORKDIR"
|
|
5654
|
+
};
|
|
5655
|
+
Image = class {
|
|
5656
|
+
_id;
|
|
5657
|
+
_name;
|
|
5658
|
+
_tag;
|
|
5659
|
+
_baseImage;
|
|
5660
|
+
_buildOperations;
|
|
5661
|
+
constructor(nameOrOptions = {}, tag = "latest", baseImage = null) {
|
|
5662
|
+
this._id = (0, import_node_crypto.randomUUID)();
|
|
5663
|
+
this._buildOperations = [];
|
|
5664
|
+
if (typeof nameOrOptions === "string") {
|
|
5665
|
+
this._name = nameOrOptions;
|
|
5666
|
+
this._tag = tag;
|
|
5667
|
+
this._baseImage = baseImage;
|
|
5668
|
+
return;
|
|
5619
5669
|
}
|
|
5670
|
+
this._name = nameOrOptions.name ?? DEFAULT_IMAGE_NAME;
|
|
5671
|
+
this._tag = nameOrOptions.tag ?? "latest";
|
|
5672
|
+
this._baseImage = nameOrOptions.baseImage ?? null;
|
|
5620
5673
|
}
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
client() {
|
|
5624
|
-
if (this.closed) throw new Error("Tensorlake native client is closed");
|
|
5625
|
-
if (this.native) return this.native;
|
|
5626
|
-
const ctor = loadNativeSandboxBinding().NativeCloudClient;
|
|
5627
|
-
if (!ctor) throw new Error("Native binding does not export NativeCloudClient; rebuild with 'npm run build:native'");
|
|
5628
|
-
return this.native = new ctor(JSON.stringify(this.options));
|
|
5674
|
+
get name() {
|
|
5675
|
+
return this._name;
|
|
5629
5676
|
}
|
|
5630
|
-
|
|
5631
|
-
this.
|
|
5632
|
-
releaseNativeHandle(this.native ?? null);
|
|
5633
|
-
this.native = void 0;
|
|
5634
|
-
}
|
|
5635
|
-
async requestResponse(method, path3, options) {
|
|
5636
|
-
const request = await serializeRequest(method, path3, options);
|
|
5637
|
-
const raw = await callNative(() => this.client().request(request));
|
|
5638
|
-
const response = new Response(
|
|
5639
|
-
[204, 205, 304].includes(raw.status) ? null : Uint8Array.from(raw.data).buffer,
|
|
5640
|
-
{ status: raw.status, headers: JSON.parse(raw.headersJson) }
|
|
5641
|
-
);
|
|
5642
|
-
return Object.assign(response, { traceId: raw.traceId });
|
|
5677
|
+
get tag() {
|
|
5678
|
+
return this._tag;
|
|
5643
5679
|
}
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
const text = await response.text();
|
|
5647
|
-
const value = text ? JSON.parse(text) : null;
|
|
5648
|
-
return Object.assign(value ?? {}, { traceId: response.traceId });
|
|
5680
|
+
get baseImage() {
|
|
5681
|
+
return this._baseImage;
|
|
5649
5682
|
}
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
const request = await serializeRequest(method, path3, { headers: { Accept: "text/event-stream" } });
|
|
5653
|
-
yield* nativeEventStream((emit) => this.client().stream(request, emit), void 0, signal);
|
|
5683
|
+
get buildOperations() {
|
|
5684
|
+
return this._buildOperations.map(cloneOperation);
|
|
5654
5685
|
}
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
function secretFromMetadata(metadata) {
|
|
5661
|
-
return {
|
|
5662
|
-
id: metadata.id,
|
|
5663
|
-
name: metadata.name,
|
|
5664
|
-
createdAt: new Date(metadata.created_at_ms)
|
|
5665
|
-
};
|
|
5666
|
-
}
|
|
5667
|
-
function applicationAllowsUnauthenticatedRequests(manifest) {
|
|
5668
|
-
return Array.isArray(manifest.allow) && manifest.allow.includes(UNAUTHENTICATED_REQUESTS);
|
|
5669
|
-
}
|
|
5670
|
-
function publicEndpointIdFromManifest(manifest) {
|
|
5671
|
-
for (const key of ["public_endpoint_id", "publicEndpointId"]) {
|
|
5672
|
-
const value = manifest[key];
|
|
5673
|
-
if (typeof value === "string" && value.length > 0) {
|
|
5674
|
-
return value;
|
|
5675
|
-
}
|
|
5676
|
-
}
|
|
5677
|
-
return void 0;
|
|
5678
|
-
}
|
|
5679
|
-
function generatePublicEndpointId() {
|
|
5680
|
-
return `endpoint_${(0, import_nanoid.nanoid)()}`;
|
|
5681
|
-
}
|
|
5682
|
-
function createApplicationBuildForm(request, imageContexts) {
|
|
5683
|
-
const contextsByPartName = /* @__PURE__ */ new Map();
|
|
5684
|
-
for (const context of imageContexts) {
|
|
5685
|
-
if (contextsByPartName.has(context.contextTarPartName)) {
|
|
5686
|
-
throw new Error(
|
|
5687
|
-
`duplicate image context part name '${context.contextTarPartName}'`
|
|
5688
|
-
);
|
|
5689
|
-
}
|
|
5690
|
-
contextsByPartName.set(context.contextTarPartName, context);
|
|
5691
|
-
}
|
|
5692
|
-
const form = new FormData();
|
|
5693
|
-
form.append(
|
|
5694
|
-
"app_version",
|
|
5695
|
-
new Blob([JSON.stringify(request)], { type: "application/json" }),
|
|
5696
|
-
"app_version"
|
|
5697
|
-
);
|
|
5698
|
-
for (const image of request.images) {
|
|
5699
|
-
const context = contextsByPartName.get(image.contextTarPartName);
|
|
5700
|
-
if (!context) {
|
|
5701
|
-
throw new Error(
|
|
5702
|
-
`missing image context for part '${image.contextTarPartName}'`
|
|
5703
|
-
);
|
|
5704
|
-
}
|
|
5705
|
-
form.append(
|
|
5706
|
-
image.contextTarPartName,
|
|
5707
|
-
new Blob([toBlobPart(context.contextTarGz)]),
|
|
5708
|
-
`${image.contextTarPartName}.tar.gz`
|
|
5709
|
-
);
|
|
5710
|
-
}
|
|
5711
|
-
for (const context of imageContexts) {
|
|
5712
|
-
if (!request.images.some((image) => image.contextTarPartName === context.contextTarPartName)) {
|
|
5713
|
-
throw new Error(
|
|
5714
|
-
`unexpected image context for part '${context.contextTarPartName}'`
|
|
5715
|
-
);
|
|
5716
|
-
}
|
|
5717
|
-
}
|
|
5718
|
-
return form;
|
|
5719
|
-
}
|
|
5720
|
-
function trimTrailingSlashes2(value) {
|
|
5721
|
-
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
5722
|
-
}
|
|
5723
|
-
function nextRequestPath(next) {
|
|
5724
|
-
const schemeIndex = next.indexOf("://");
|
|
5725
|
-
if (schemeIndex !== -1) {
|
|
5726
|
-
const afterScheme = next.slice(schemeIndex + 3);
|
|
5727
|
-
const slashIndex = afterScheme.indexOf("/");
|
|
5728
|
-
return slashIndex === -1 ? "/" : afterScheme.slice(slashIndex);
|
|
5729
|
-
}
|
|
5730
|
-
return next.startsWith("/") ? next : `/${next}`;
|
|
5731
|
-
}
|
|
5732
|
-
function toBlobPart(data) {
|
|
5733
|
-
if (typeof data === "string" || data instanceof Blob) {
|
|
5734
|
-
return data;
|
|
5735
|
-
}
|
|
5736
|
-
if (data instanceof Uint8Array) {
|
|
5737
|
-
return Uint8Array.from(data).buffer;
|
|
5738
|
-
}
|
|
5739
|
-
return data;
|
|
5740
|
-
}
|
|
5741
|
-
function toRequestBody(data) {
|
|
5742
|
-
return toBlobPart(data);
|
|
5743
|
-
}
|
|
5744
|
-
async function parseJsonResponse(response) {
|
|
5745
|
-
const text = await response.text();
|
|
5746
|
-
if (!text) {
|
|
5747
|
-
return void 0;
|
|
5748
|
-
}
|
|
5749
|
-
return JSON.parse(text);
|
|
5750
|
-
}
|
|
5751
|
-
var import_nanoid, CloudClient, UNAUTHENTICATED_REQUESTS;
|
|
5752
|
-
var init_cloud_client = __esm({
|
|
5753
|
-
"src/cloud-client.ts"() {
|
|
5754
|
-
"use strict";
|
|
5755
|
-
init_cjs_shims();
|
|
5756
|
-
import_nanoid = require("nanoid");
|
|
5757
|
-
init_defaults();
|
|
5758
|
-
init_native_cloud();
|
|
5759
|
-
init_models();
|
|
5760
|
-
CloudClient = class _CloudClient {
|
|
5761
|
-
transport;
|
|
5762
|
-
organizationId;
|
|
5763
|
-
projectId;
|
|
5764
|
-
namespace;
|
|
5765
|
-
constructor(options) {
|
|
5766
|
-
this.organizationId = options?.organizationId;
|
|
5767
|
-
this.projectId = options?.projectId;
|
|
5768
|
-
this.namespace = options?.namespace ?? NAMESPACE;
|
|
5769
|
-
this.transport = new NativeCloudTransport({
|
|
5770
|
-
baseUrl: options?.apiUrl ?? API_URL,
|
|
5771
|
-
apiKey: options?.apiKey ?? API_KEY,
|
|
5772
|
-
organizationId: this.organizationId,
|
|
5773
|
-
projectId: this.projectId,
|
|
5774
|
-
maxRetries: options?.maxRetries ?? MAX_RETRIES,
|
|
5775
|
-
retryBackoffMs: options?.retryBackoffMs ?? RETRY_BACKOFF_MS,
|
|
5776
|
-
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
5777
|
-
userAgent: `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
5686
|
+
add(src, dest, options = void 0) {
|
|
5687
|
+
return this._addOperation({
|
|
5688
|
+
type: ImageBuildOperationType.ADD,
|
|
5689
|
+
args: [src, dest],
|
|
5690
|
+
options: options == null ? {} : { ...options }
|
|
5778
5691
|
});
|
|
5779
5692
|
}
|
|
5780
|
-
|
|
5781
|
-
return
|
|
5693
|
+
copy(src, dest, options = void 0) {
|
|
5694
|
+
return this._addOperation({
|
|
5695
|
+
type: ImageBuildOperationType.COPY,
|
|
5696
|
+
args: [src, dest],
|
|
5697
|
+
options: options == null ? {} : { ...options }
|
|
5698
|
+
});
|
|
5782
5699
|
}
|
|
5783
|
-
|
|
5784
|
-
this.
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
let publicEndpointId = publicEndpointIdFromManifest(applicationManifest);
|
|
5789
|
-
if (applicationAllowsUnauthenticatedRequests(applicationManifest) && publicEndpointId === void 0) {
|
|
5790
|
-
const applicationName = applicationManifest.name;
|
|
5791
|
-
if (typeof applicationName === "string" && applicationName.length > 0) {
|
|
5792
|
-
publicEndpointId = await this.existingApplicationPublicEndpointId(applicationName);
|
|
5793
|
-
}
|
|
5794
|
-
publicEndpointId ??= generatePublicEndpointId();
|
|
5795
|
-
}
|
|
5796
|
-
if (publicEndpointId !== void 0) {
|
|
5797
|
-
applicationManifest.public_endpoint_id = publicEndpointId;
|
|
5798
|
-
delete applicationManifest.publicEndpointId;
|
|
5799
|
-
}
|
|
5800
|
-
const form = new FormData();
|
|
5801
|
-
form.append(
|
|
5802
|
-
"code",
|
|
5803
|
-
new Blob([toBlobPart(codeZip)], { type: "application/zip" }),
|
|
5804
|
-
"code.zip"
|
|
5805
|
-
);
|
|
5806
|
-
form.append("code_content_type", "application/zip");
|
|
5807
|
-
form.append("application", JSON.stringify(applicationManifest));
|
|
5808
|
-
form.append(
|
|
5809
|
-
"upgrade_requests_to_latest_code",
|
|
5810
|
-
String(upgradeRunningRequests)
|
|
5811
|
-
);
|
|
5812
|
-
await this.transport.requestResponse("POST", this.namespacePath("applications"), {
|
|
5813
|
-
body: form
|
|
5700
|
+
env(key, value) {
|
|
5701
|
+
return this._addOperation({
|
|
5702
|
+
type: ImageBuildOperationType.ENV,
|
|
5703
|
+
args: [key, value],
|
|
5704
|
+
options: {}
|
|
5814
5705
|
});
|
|
5815
5706
|
}
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5707
|
+
run(commands, options = void 0) {
|
|
5708
|
+
return this._addOperation({
|
|
5709
|
+
type: ImageBuildOperationType.RUN,
|
|
5710
|
+
args: Array.isArray(commands) ? [...commands] : [commands],
|
|
5711
|
+
options: options == null ? {} : { ...options }
|
|
5712
|
+
});
|
|
5821
5713
|
}
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5714
|
+
workdir(directory) {
|
|
5715
|
+
return this._addOperation({
|
|
5716
|
+
type: ImageBuildOperationType.WORKDIR,
|
|
5717
|
+
args: [directory],
|
|
5718
|
+
options: {}
|
|
5719
|
+
});
|
|
5827
5720
|
}
|
|
5828
5721
|
/**
|
|
5829
|
-
*
|
|
5830
|
-
*
|
|
5831
|
-
* Returns the template, or `null` when no image with that name exists.
|
|
5832
|
-
* API-key clients may omit organization/project IDs and use the
|
|
5833
|
-
* token-scoped Platform API route directly. Explicit scope remains
|
|
5834
|
-
* available for PAT callers.
|
|
5835
|
-
*/
|
|
5836
|
-
async findSandboxImageByName(imageName, options) {
|
|
5837
|
-
const base = this.platformProjectPath(
|
|
5838
|
-
"sandbox-templates",
|
|
5839
|
-
options?.organizationId,
|
|
5840
|
-
options?.projectId
|
|
5841
|
-
);
|
|
5842
|
-
const response = await this.transport.requestResponse(
|
|
5843
|
-
"GET",
|
|
5844
|
-
`${base}/by-name/${encodeURIComponent(imageName)}`,
|
|
5845
|
-
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
5846
|
-
);
|
|
5847
|
-
if (response.status === 404) {
|
|
5848
|
-
return null;
|
|
5849
|
-
}
|
|
5850
|
-
const raw = await parseJsonResponse(response);
|
|
5851
|
-
return fromSnakeKeys(raw);
|
|
5852
|
-
}
|
|
5853
|
-
/**
|
|
5854
|
-
* List all registered sandbox images (templates), following pagination to
|
|
5855
|
-
* the end. API-key clients may omit organization/project IDs and use the
|
|
5856
|
-
* token-scoped Platform API route directly.
|
|
5857
|
-
*/
|
|
5858
|
-
async listSandboxImages(options) {
|
|
5859
|
-
const base = this.platformProjectPath(
|
|
5860
|
-
"sandbox-templates",
|
|
5861
|
-
options?.organizationId,
|
|
5862
|
-
options?.projectId
|
|
5863
|
-
);
|
|
5864
|
-
let path3 = `${base}?pageSize=100`;
|
|
5865
|
-
const templates = [];
|
|
5866
|
-
while (path3 !== null) {
|
|
5867
|
-
const page = await this.transport.requestJson(
|
|
5868
|
-
"GET",
|
|
5869
|
-
path3
|
|
5870
|
-
);
|
|
5871
|
-
for (const item of page.items ?? []) {
|
|
5872
|
-
templates.push(fromSnakeKeys(item));
|
|
5873
|
-
}
|
|
5874
|
-
const next = page.pagination?.next;
|
|
5875
|
-
path3 = next ? nextRequestPath(next) : null;
|
|
5876
|
-
}
|
|
5877
|
-
return templates;
|
|
5878
|
-
}
|
|
5879
|
-
async applications() {
|
|
5880
|
-
const raw = await this.transport.requestJson(
|
|
5881
|
-
"GET",
|
|
5882
|
-
this.namespacePath("applications")
|
|
5883
|
-
);
|
|
5884
|
-
return (raw.applications ?? []).map(
|
|
5885
|
-
(application) => fromSnakeKeys(application)
|
|
5886
|
-
);
|
|
5887
|
-
}
|
|
5888
|
-
async applicationManifest(applicationName) {
|
|
5889
|
-
const raw = await this.transport.requestJson(
|
|
5890
|
-
"GET",
|
|
5891
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
5892
|
-
);
|
|
5893
|
-
return fromSnakeKeys(raw);
|
|
5894
|
-
}
|
|
5895
|
-
async runRequest(applicationName, inputs = []) {
|
|
5896
|
-
const path3 = this.namespacePath(
|
|
5897
|
-
`applications/${encodeURIComponent(applicationName)}`
|
|
5898
|
-
);
|
|
5899
|
-
const response = inputs.length === 0 ? await this.transport.requestResponse("POST", path3, {
|
|
5900
|
-
body: new Uint8Array(),
|
|
5901
|
-
headers: { Accept: "application/json" }
|
|
5902
|
-
}) : inputs.length === 1 && inputs[0].name === "0" ? await this.transport.requestResponse("POST", path3, {
|
|
5903
|
-
body: toRequestBody(inputs[0].data),
|
|
5904
|
-
headers: {
|
|
5905
|
-
Accept: "application/json",
|
|
5906
|
-
"Content-Type": inputs[0].contentType
|
|
5907
|
-
}
|
|
5908
|
-
}) : await this.runMultipartRequest(path3, inputs);
|
|
5909
|
-
const body = await parseJsonResponse(response);
|
|
5910
|
-
const requestId = body?.request_id;
|
|
5911
|
-
if (!requestId) {
|
|
5912
|
-
throw new Error("missing request_id in run request response body");
|
|
5913
|
-
}
|
|
5914
|
-
return requestId;
|
|
5915
|
-
}
|
|
5916
|
-
async waitOnRequestCompletion(applicationName, requestId) {
|
|
5917
|
-
const stream = this.transport.stream(
|
|
5918
|
-
"GET",
|
|
5919
|
-
this.namespacePath(
|
|
5920
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/progress`
|
|
5921
|
-
)
|
|
5922
|
-
);
|
|
5923
|
-
for await (const event of stream) {
|
|
5924
|
-
if (Object.prototype.hasOwnProperty.call(event, "RequestFinished")) {
|
|
5925
|
-
return;
|
|
5926
|
-
}
|
|
5927
|
-
}
|
|
5928
|
-
throw new Error("progress stream ended before request completion");
|
|
5929
|
-
}
|
|
5930
|
-
async requestMetadata(applicationName, requestId) {
|
|
5931
|
-
const raw = await this.transport.requestJson(
|
|
5932
|
-
"GET",
|
|
5933
|
-
this.namespacePath(
|
|
5934
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}`
|
|
5935
|
-
)
|
|
5936
|
-
);
|
|
5937
|
-
return fromSnakeKeys(raw);
|
|
5938
|
-
}
|
|
5939
|
-
async requestOutput(applicationName, requestId) {
|
|
5940
|
-
const response = await this.transport.requestResponse(
|
|
5941
|
-
"GET",
|
|
5942
|
-
this.namespacePath(
|
|
5943
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/output`
|
|
5944
|
-
)
|
|
5945
|
-
);
|
|
5946
|
-
const serializedValue = new Uint8Array(await response.arrayBuffer());
|
|
5947
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
5948
|
-
return {
|
|
5949
|
-
serializedValue,
|
|
5950
|
-
contentType
|
|
5951
|
-
};
|
|
5952
|
-
}
|
|
5953
|
-
async listSecrets(options) {
|
|
5954
|
-
const base = this.secretCollectionPath(
|
|
5955
|
-
options?.organizationId,
|
|
5956
|
-
options?.projectId
|
|
5957
|
-
);
|
|
5958
|
-
const raw = await this.transport.requestJson("GET", base);
|
|
5959
|
-
const pageSize = Math.max(0, options?.pageSize ?? 100);
|
|
5960
|
-
return Object.assign(
|
|
5961
|
-
{
|
|
5962
|
-
items: raw.slice(0, pageSize).map(secretFromMetadata),
|
|
5963
|
-
pagination: { total: raw.length }
|
|
5964
|
-
},
|
|
5965
|
-
{ traceId: raw.traceId }
|
|
5966
|
-
);
|
|
5967
|
-
}
|
|
5968
|
-
async getSecret(secretId, options) {
|
|
5969
|
-
const base = this.secretCollectionPath(
|
|
5970
|
-
options?.organizationId,
|
|
5971
|
-
options?.projectId
|
|
5972
|
-
);
|
|
5973
|
-
const raw = await this.transport.requestJson(
|
|
5974
|
-
"GET",
|
|
5975
|
-
`${base}/${encodeURIComponent(secretId)}`
|
|
5976
|
-
);
|
|
5977
|
-
return Object.assign(secretFromMetadata(raw), { traceId: raw.traceId });
|
|
5978
|
-
}
|
|
5979
|
-
async upsertSecrets(secrets, options) {
|
|
5980
|
-
const base = this.secretCollectionPath(
|
|
5981
|
-
options?.organizationId,
|
|
5982
|
-
options?.projectId
|
|
5983
|
-
);
|
|
5984
|
-
if (Array.isArray(secrets)) {
|
|
5985
|
-
const results = [];
|
|
5986
|
-
for (const secret of secrets) {
|
|
5987
|
-
results.push(await this.upsertSecret(base, secret));
|
|
5988
|
-
}
|
|
5989
|
-
return results;
|
|
5990
|
-
}
|
|
5991
|
-
return this.upsertSecret(base, secrets);
|
|
5992
|
-
}
|
|
5993
|
-
async deleteSecret(secretId, options) {
|
|
5994
|
-
const base = this.secretCollectionPath(
|
|
5995
|
-
options?.organizationId,
|
|
5996
|
-
options?.projectId
|
|
5997
|
-
);
|
|
5998
|
-
await this.transport.requestResponse(
|
|
5999
|
-
"DELETE",
|
|
6000
|
-
`${base}/${encodeURIComponent(secretId)}`
|
|
6001
|
-
);
|
|
6002
|
-
}
|
|
6003
|
-
async upsertSecret(base, secret) {
|
|
6004
|
-
let response = await this.transport.requestResponse("POST", base, {
|
|
6005
|
-
json: secret,
|
|
6006
|
-
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() },
|
|
6007
|
-
statusOnlyCodes: /* @__PURE__ */ new Set([409])
|
|
6008
|
-
});
|
|
6009
|
-
if (response.status === 409) {
|
|
6010
|
-
const prefix = base.slice(0, -"/secrets".length);
|
|
6011
|
-
const existing = await this.transport.requestJson(
|
|
6012
|
-
"GET",
|
|
6013
|
-
`${prefix}/secret-names/${encodeURIComponent(secret.name)}`
|
|
6014
|
-
);
|
|
6015
|
-
response = await this.transport.requestResponse(
|
|
6016
|
-
"POST",
|
|
6017
|
-
`${base}/${encodeURIComponent(existing.id)}/versions`,
|
|
6018
|
-
{
|
|
6019
|
-
json: { value: secret.value },
|
|
6020
|
-
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() }
|
|
6021
|
-
}
|
|
6022
|
-
);
|
|
6023
|
-
}
|
|
6024
|
-
const metadata = await parseJsonResponse(response);
|
|
6025
|
-
return Object.assign(secretFromMetadata(metadata), {
|
|
6026
|
-
traceId: response.traceId
|
|
6027
|
-
});
|
|
6028
|
-
}
|
|
6029
|
-
async startImageBuild(buildServicePath, request) {
|
|
6030
|
-
const form = new FormData();
|
|
6031
|
-
form.append("graph_name", request.applicationName);
|
|
6032
|
-
form.append("graph_version", request.applicationVersion);
|
|
6033
|
-
form.append("graph_function_name", request.functionName);
|
|
6034
|
-
form.append("image_name", request.imageName);
|
|
6035
|
-
form.append("image_id", request.imageId);
|
|
6036
|
-
form.append(
|
|
6037
|
-
"context",
|
|
6038
|
-
new Blob([toBlobPart(request.buildContext)]),
|
|
6039
|
-
"context.tar.gz"
|
|
6040
|
-
);
|
|
6041
|
-
const response = await this.transport.requestResponse(
|
|
6042
|
-
"PUT",
|
|
6043
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds`,
|
|
6044
|
-
{ body: form }
|
|
6045
|
-
);
|
|
6046
|
-
const raw = await parseJsonResponse(response);
|
|
6047
|
-
return fromSnakeKeys(raw);
|
|
6048
|
-
}
|
|
6049
|
-
async createApplicationBuild(buildServicePath, request, imageContexts) {
|
|
6050
|
-
const form = createApplicationBuildForm(request, imageContexts);
|
|
6051
|
-
const response = await this.transport.requestResponse(
|
|
6052
|
-
"POST",
|
|
6053
|
-
trimTrailingSlashes2(buildServicePath),
|
|
6054
|
-
{ body: form }
|
|
6055
|
-
);
|
|
6056
|
-
const raw = await parseJsonResponse(response);
|
|
6057
|
-
return fromSnakeKeys(raw);
|
|
6058
|
-
}
|
|
6059
|
-
async applicationBuildInfo(buildServicePath, applicationBuildId) {
|
|
6060
|
-
const raw = await this.transport.requestJson(
|
|
6061
|
-
"GET",
|
|
6062
|
-
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}`
|
|
6063
|
-
);
|
|
6064
|
-
return fromSnakeKeys(raw);
|
|
6065
|
-
}
|
|
6066
|
-
async cancelApplicationBuild(buildServicePath, applicationBuildId) {
|
|
6067
|
-
const raw = await this.transport.requestJson(
|
|
6068
|
-
"POST",
|
|
6069
|
-
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}/cancel`
|
|
6070
|
-
);
|
|
6071
|
-
return fromSnakeKeys(raw);
|
|
6072
|
-
}
|
|
6073
|
-
async buildInfo(buildServicePath, buildId) {
|
|
6074
|
-
const raw = await this.transport.requestJson(
|
|
6075
|
-
"GET",
|
|
6076
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}`
|
|
6077
|
-
);
|
|
6078
|
-
return fromSnakeKeys(raw);
|
|
6079
|
-
}
|
|
6080
|
-
async cancelBuild(buildServicePath, buildId) {
|
|
6081
|
-
await this.transport.requestResponse(
|
|
6082
|
-
"POST",
|
|
6083
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/cancel`
|
|
6084
|
-
);
|
|
6085
|
-
}
|
|
6086
|
-
async *streamBuildLogs(buildServicePath, buildId, signal) {
|
|
6087
|
-
const stream = this.transport.stream(
|
|
6088
|
-
"GET",
|
|
6089
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/logs`,
|
|
6090
|
-
signal
|
|
6091
|
-
);
|
|
6092
|
-
for await (const event of stream) {
|
|
6093
|
-
yield fromSnakeKeys(event);
|
|
6094
|
-
}
|
|
6095
|
-
}
|
|
6096
|
-
async runMultipartRequest(path3, inputs) {
|
|
6097
|
-
const form = new FormData();
|
|
6098
|
-
for (const input of inputs) {
|
|
6099
|
-
form.append(
|
|
6100
|
-
input.name,
|
|
6101
|
-
new Blob([toBlobPart(input.data)], { type: input.contentType }),
|
|
6102
|
-
input.name
|
|
6103
|
-
);
|
|
6104
|
-
}
|
|
6105
|
-
return this.transport.requestResponse("POST", path3, {
|
|
6106
|
-
body: form,
|
|
6107
|
-
headers: { Accept: "application/json" }
|
|
6108
|
-
});
|
|
6109
|
-
}
|
|
6110
|
-
namespacePath(subpath) {
|
|
6111
|
-
return `/v1/namespaces/${encodeURIComponent(this.namespace)}/${subpath.replace(/^\/+/, "")}`;
|
|
6112
|
-
}
|
|
6113
|
-
async existingApplicationPublicEndpointId(applicationName) {
|
|
6114
|
-
const response = await this.transport.requestResponse(
|
|
6115
|
-
"GET",
|
|
6116
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`),
|
|
6117
|
-
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
6118
|
-
);
|
|
6119
|
-
if (response.status === 404) {
|
|
6120
|
-
return void 0;
|
|
6121
|
-
}
|
|
6122
|
-
const application = await parseJsonResponse(response);
|
|
6123
|
-
return publicEndpointIdFromManifest(application);
|
|
6124
|
-
}
|
|
6125
|
-
platformProjectPath(resource, organizationId, projectId) {
|
|
6126
|
-
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
6127
|
-
const resolvedProjectId = projectId ?? this.projectId;
|
|
6128
|
-
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
6129
|
-
return `/platform/v1/${resource}`;
|
|
6130
|
-
}
|
|
6131
|
-
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
6132
|
-
throw new Error(
|
|
6133
|
-
"organizationId and projectId must be provided together"
|
|
6134
|
-
);
|
|
6135
|
-
}
|
|
6136
|
-
return `/platform/v1/organizations/${encodeURIComponent(resolvedOrganizationId)}/projects/${encodeURIComponent(resolvedProjectId)}/${resource}`;
|
|
6137
|
-
}
|
|
6138
|
-
secretCollectionPath(organizationId, projectId) {
|
|
6139
|
-
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
6140
|
-
const resolvedProjectId = projectId ?? this.projectId;
|
|
6141
|
-
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
6142
|
-
return this.namespacePath("secrets");
|
|
6143
|
-
}
|
|
6144
|
-
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
6145
|
-
throw new Error("organizationId and projectId must be provided together");
|
|
6146
|
-
}
|
|
6147
|
-
return this.namespacePath("secrets");
|
|
6148
|
-
}
|
|
6149
|
-
};
|
|
6150
|
-
UNAUTHENTICATED_REQUESTS = "unauthenticated_requests";
|
|
6151
|
-
}
|
|
6152
|
-
});
|
|
6153
|
-
|
|
6154
|
-
// src/image.ts
|
|
6155
|
-
function cloneOperation(op) {
|
|
6156
|
-
return {
|
|
6157
|
-
type: op.type,
|
|
6158
|
-
args: [...op.args],
|
|
6159
|
-
options: { ...op.options }
|
|
6160
|
-
};
|
|
6161
|
-
}
|
|
6162
|
-
function renderOptions(options) {
|
|
6163
|
-
const entries = Object.entries(options);
|
|
6164
|
-
if (entries.length === 0) {
|
|
6165
|
-
return "";
|
|
6166
|
-
}
|
|
6167
|
-
return ` ${entries.map(([key, value]) => `--${key}=${value}`).join(" ")}`;
|
|
6168
|
-
}
|
|
6169
|
-
function renderBuildOp(op) {
|
|
6170
|
-
const options = renderOptions(op.options);
|
|
6171
|
-
if (op.type === ImageBuildOperationType.ENV) {
|
|
6172
|
-
return `ENV${options} ${op.args[0]}=${JSON.stringify(op.args[1])}`;
|
|
6173
|
-
}
|
|
6174
|
-
return `${op.type}${options} ${op.args.join(" ")}`;
|
|
6175
|
-
}
|
|
6176
|
-
function dockerfileContent(image) {
|
|
6177
|
-
const lines = image.baseImage == null ? [] : [`FROM ${image.baseImage}`];
|
|
6178
|
-
lines.push(...image.buildOperations.map((op) => renderBuildOp(op)));
|
|
6179
|
-
return lines.join("\n");
|
|
6180
|
-
}
|
|
6181
|
-
var import_node_crypto, DEFAULT_IMAGE_NAME, ImageBuildOperationType, Image;
|
|
6182
|
-
var init_image = __esm({
|
|
6183
|
-
"src/image.ts"() {
|
|
6184
|
-
"use strict";
|
|
6185
|
-
init_cjs_shims();
|
|
6186
|
-
import_node_crypto = require("crypto");
|
|
6187
|
-
DEFAULT_IMAGE_NAME = "default";
|
|
6188
|
-
ImageBuildOperationType = {
|
|
6189
|
-
ADD: "ADD",
|
|
6190
|
-
COPY: "COPY",
|
|
6191
|
-
ENV: "ENV",
|
|
6192
|
-
RUN: "RUN",
|
|
6193
|
-
WORKDIR: "WORKDIR"
|
|
6194
|
-
};
|
|
6195
|
-
Image = class {
|
|
6196
|
-
_id;
|
|
6197
|
-
_name;
|
|
6198
|
-
_tag;
|
|
6199
|
-
_baseImage;
|
|
6200
|
-
_buildOperations;
|
|
6201
|
-
constructor(nameOrOptions = {}, tag = "latest", baseImage = null) {
|
|
6202
|
-
this._id = (0, import_node_crypto.randomUUID)();
|
|
6203
|
-
this._buildOperations = [];
|
|
6204
|
-
if (typeof nameOrOptions === "string") {
|
|
6205
|
-
this._name = nameOrOptions;
|
|
6206
|
-
this._tag = tag;
|
|
6207
|
-
this._baseImage = baseImage;
|
|
6208
|
-
return;
|
|
6209
|
-
}
|
|
6210
|
-
this._name = nameOrOptions.name ?? DEFAULT_IMAGE_NAME;
|
|
6211
|
-
this._tag = nameOrOptions.tag ?? "latest";
|
|
6212
|
-
this._baseImage = nameOrOptions.baseImage ?? null;
|
|
6213
|
-
}
|
|
6214
|
-
get name() {
|
|
6215
|
-
return this._name;
|
|
6216
|
-
}
|
|
6217
|
-
get tag() {
|
|
6218
|
-
return this._tag;
|
|
6219
|
-
}
|
|
6220
|
-
get baseImage() {
|
|
6221
|
-
return this._baseImage;
|
|
6222
|
-
}
|
|
6223
|
-
get buildOperations() {
|
|
6224
|
-
return this._buildOperations.map(cloneOperation);
|
|
6225
|
-
}
|
|
6226
|
-
add(src, dest, options = void 0) {
|
|
6227
|
-
return this._addOperation({
|
|
6228
|
-
type: ImageBuildOperationType.ADD,
|
|
6229
|
-
args: [src, dest],
|
|
6230
|
-
options: options == null ? {} : { ...options }
|
|
6231
|
-
});
|
|
6232
|
-
}
|
|
6233
|
-
copy(src, dest, options = void 0) {
|
|
6234
|
-
return this._addOperation({
|
|
6235
|
-
type: ImageBuildOperationType.COPY,
|
|
6236
|
-
args: [src, dest],
|
|
6237
|
-
options: options == null ? {} : { ...options }
|
|
6238
|
-
});
|
|
6239
|
-
}
|
|
6240
|
-
env(key, value) {
|
|
6241
|
-
return this._addOperation({
|
|
6242
|
-
type: ImageBuildOperationType.ENV,
|
|
6243
|
-
args: [key, value],
|
|
6244
|
-
options: {}
|
|
6245
|
-
});
|
|
6246
|
-
}
|
|
6247
|
-
run(commands, options = void 0) {
|
|
6248
|
-
return this._addOperation({
|
|
6249
|
-
type: ImageBuildOperationType.RUN,
|
|
6250
|
-
args: Array.isArray(commands) ? [...commands] : [commands],
|
|
6251
|
-
options: options == null ? {} : { ...options }
|
|
6252
|
-
});
|
|
6253
|
-
}
|
|
6254
|
-
workdir(directory) {
|
|
6255
|
-
return this._addOperation({
|
|
6256
|
-
type: ImageBuildOperationType.WORKDIR,
|
|
6257
|
-
args: [directory],
|
|
6258
|
-
options: {}
|
|
6259
|
-
});
|
|
6260
|
-
}
|
|
6261
|
-
/**
|
|
6262
|
-
* Build this image as a sandbox template and register it.
|
|
5722
|
+
* Build this image as a sandbox template and register it.
|
|
6263
5723
|
*
|
|
6264
5724
|
* Materializes the image in a build sandbox, snapshots the filesystem,
|
|
6265
5725
|
* and registers the snapshot as a named sandbox template.
|
|
@@ -6343,9 +5803,9 @@ var require_libc = __commonJS({
|
|
|
6343
5803
|
// src/native-binding.ts
|
|
6344
5804
|
function packageRoot() {
|
|
6345
5805
|
const parent = (0, import_node_url.fileURLToPath)(new URL("../", importMetaUrl));
|
|
6346
|
-
if (fs.existsSync(
|
|
5806
|
+
if (fs.existsSync(import_node_path.default.join(parent, "package.json"))) return parent;
|
|
6347
5807
|
const grandparent = (0, import_node_url.fileURLToPath)(new URL("../../", importMetaUrl));
|
|
6348
|
-
if (fs.existsSync(
|
|
5808
|
+
if (fs.existsSync(import_node_path.default.join(grandparent, "package.json"))) return grandparent;
|
|
6349
5809
|
return parent;
|
|
6350
5810
|
}
|
|
6351
5811
|
function linuxLibcFamily(options) {
|
|
@@ -6368,7 +5828,7 @@ function nativeTargetId(platform = process.platform, arch = process.arch, option
|
|
|
6368
5828
|
function nativeBindingPath(options = {}) {
|
|
6369
5829
|
const platform = options.platform ?? process.platform;
|
|
6370
5830
|
const arch = options.arch ?? process.arch;
|
|
6371
|
-
return
|
|
5831
|
+
return import_node_path.default.join(
|
|
6372
5832
|
options.packageRoot ?? packageRoot(),
|
|
6373
5833
|
"dist",
|
|
6374
5834
|
"native",
|
|
@@ -6401,7 +5861,7 @@ function loadNative() {
|
|
|
6401
5861
|
}
|
|
6402
5862
|
return require2(packageEntry);
|
|
6403
5863
|
}
|
|
6404
|
-
var import_libc, fs, import_node_module2,
|
|
5864
|
+
var import_libc, fs, import_node_module2, import_node_path, import_node_url, NATIVE_PACKAGES, cachedLinuxLibc;
|
|
6405
5865
|
var init_native_binding = __esm({
|
|
6406
5866
|
"src/native-binding.ts"() {
|
|
6407
5867
|
"use strict";
|
|
@@ -6409,7 +5869,7 @@ var init_native_binding = __esm({
|
|
|
6409
5869
|
import_libc = __toESM(require_libc(), 1);
|
|
6410
5870
|
fs = __toESM(require("fs"), 1);
|
|
6411
5871
|
import_node_module2 = require("module");
|
|
6412
|
-
|
|
5872
|
+
import_node_path = __toESM(require("path"), 1);
|
|
6413
5873
|
import_node_url = require("url");
|
|
6414
5874
|
NATIVE_PACKAGES = {
|
|
6415
5875
|
"darwin-arm64": "@tensorlakeai/native-darwin-arm64",
|
|
@@ -6422,16 +5882,562 @@ var init_native_binding = __esm({
|
|
|
6422
5882
|
}
|
|
6423
5883
|
});
|
|
6424
5884
|
|
|
5885
|
+
// src/image-builds.ts
|
|
5886
|
+
function isConfirmedCancellation(outcome) {
|
|
5887
|
+
return outcome === "cancelled" /* CANCELLED */ || outcome === "already_cancelled" /* ALREADY_CANCELLED */ || outcome === "already_failed" /* ALREADY_FAILED */;
|
|
5888
|
+
}
|
|
5889
|
+
function camelize(key) {
|
|
5890
|
+
return key.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
5891
|
+
}
|
|
5892
|
+
function toImageBuildError(error) {
|
|
5893
|
+
if (!(error instanceof Error)) return error;
|
|
5894
|
+
let payload;
|
|
5895
|
+
try {
|
|
5896
|
+
payload = JSON.parse(error.message);
|
|
5897
|
+
} catch {
|
|
5898
|
+
return error;
|
|
5899
|
+
}
|
|
5900
|
+
if (!payload || payload.category !== "image_build") return error;
|
|
5901
|
+
const details = {};
|
|
5902
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
5903
|
+
if (key === "category") continue;
|
|
5904
|
+
details[camelize(key)] = value;
|
|
5905
|
+
}
|
|
5906
|
+
details.code = enumValue(ImageBuildErrorCode, details.code || "internal" /* INTERNAL */);
|
|
5907
|
+
if ("activeKind" in details) details.activeKind = details.activeKind ? enumValue(ImageBuildKind, details.activeKind) : null;
|
|
5908
|
+
if ("activeStatus" in details) details.activeStatus = details.activeStatus ? enumValue(ImageBuildStatus, details.activeStatus) : null;
|
|
5909
|
+
if ("outcome" in details) details.outcome = details.outcome ? enumValue(ImageBuildCancellationOutcome, details.outcome) : null;
|
|
5910
|
+
if ("info" in details) details.info = buildInfoOrNull(details.info);
|
|
5911
|
+
const typed = details;
|
|
5912
|
+
const errors = {
|
|
5913
|
+
not_found: ImageBuildNotFoundError,
|
|
5914
|
+
image_build_in_progress: ImageBuildInProgressError,
|
|
5915
|
+
failed: ImageBuildFailedError,
|
|
5916
|
+
cancelled: ImageBuildCancelledError,
|
|
5917
|
+
timeout: ImageBuildTimeoutError,
|
|
5918
|
+
interrupted: ImageBuildInterruptedError
|
|
5919
|
+
};
|
|
5920
|
+
const ErrorClass = errors[typed.code] ?? ImageBuildError;
|
|
5921
|
+
return withRaw(new ErrorClass(typed), payload);
|
|
5922
|
+
}
|
|
5923
|
+
function camelizeRecord(value) {
|
|
5924
|
+
const out = {};
|
|
5925
|
+
for (const [key, inner] of Object.entries(value)) out[camelize(key)] = inner;
|
|
5926
|
+
return out;
|
|
5927
|
+
}
|
|
5928
|
+
function buildInfoOrNull(value) {
|
|
5929
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
5930
|
+
try {
|
|
5931
|
+
return parseBuildInfo(value);
|
|
5932
|
+
} catch (error) {
|
|
5933
|
+
if (error instanceof ImageBuildError) return null;
|
|
5934
|
+
throw error;
|
|
5935
|
+
}
|
|
5936
|
+
}
|
|
5937
|
+
function decodeResponse(value) {
|
|
5938
|
+
try {
|
|
5939
|
+
const raw = typeof value === "string" ? JSON.parse(value) : value;
|
|
5940
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) throw new TypeError("expected a response object");
|
|
5941
|
+
return raw;
|
|
5942
|
+
} catch (error) {
|
|
5943
|
+
throw withRaw(new ImageBuildError({ code: "service" /* SERVICE */, message: `Invalid image-build response: ${String(error)}` }), { response: value });
|
|
5944
|
+
}
|
|
5945
|
+
}
|
|
5946
|
+
function parseBuildInfo(value) {
|
|
5947
|
+
const raw = decodeResponse(value);
|
|
5948
|
+
if (raw.status == null) {
|
|
5949
|
+
throw withRaw(new ImageBuildError({ code: "service" /* SERVICE */, message: "Invalid image-build response: missing status" }), { response: value });
|
|
5950
|
+
}
|
|
5951
|
+
const attempt = raw.attempt_no ?? 0;
|
|
5952
|
+
const attemptNo = Number(attempt);
|
|
5953
|
+
if (typeof attempt !== "number" && typeof attempt !== "string" || typeof attempt === "string" && attempt.trim() === "" || !Number.isSafeInteger(attemptNo)) {
|
|
5954
|
+
throw withRaw(new ImageBuildError({ code: "service" /* SERVICE */, message: "Invalid image-build attempt_no" }), { response: value });
|
|
5955
|
+
}
|
|
5956
|
+
const camel = camelizeRecord(raw);
|
|
5957
|
+
const result = raw.result && typeof raw.result === "object" ? camelizeRecord(raw.result) : null;
|
|
5958
|
+
return withRaw({
|
|
5959
|
+
buildId: String(raw.build_id ?? ""),
|
|
5960
|
+
clientRequestId: camel.clientRequestId ?? null,
|
|
5961
|
+
kind: raw.kind ? enumValue(ImageBuildKind, raw.kind) : null,
|
|
5962
|
+
name: raw.name ?? null,
|
|
5963
|
+
status: enumValue(ImageBuildStatus, raw.status),
|
|
5964
|
+
phase: raw.phase ? enumValue(ImageBuildPhase, raw.phase) : null,
|
|
5965
|
+
attemptNo,
|
|
5966
|
+
builderSandboxId: camel.builderSandboxId ?? null,
|
|
5967
|
+
error: raw.error ?? null,
|
|
5968
|
+
result,
|
|
5969
|
+
operationDeadlineMs: camel.operationDeadlineMs ?? null,
|
|
5970
|
+
createdAtMs: camel.createdAtMs ?? null,
|
|
5971
|
+
updatedAtMs: camel.updatedAtMs ?? null
|
|
5972
|
+
}, raw);
|
|
5973
|
+
}
|
|
5974
|
+
function parseResult(json) {
|
|
5975
|
+
return camelizeRecord(decodeResponse(json));
|
|
5976
|
+
}
|
|
5977
|
+
function credentialsFromEnv() {
|
|
5978
|
+
const context = __imageBuildInternals.buildContextFromEnv();
|
|
5979
|
+
if (!context.apiKey) {
|
|
5980
|
+
if (context.personalAccessToken) {
|
|
5981
|
+
throw new ImageBuildError({
|
|
5982
|
+
code: "auth" /* AUTH */,
|
|
5983
|
+
message: "Sandbox image SDKs require TENSORLAKE_API_KEY. Personal access tokens are CLI-only."
|
|
5984
|
+
});
|
|
5985
|
+
}
|
|
5986
|
+
throw new ImageBuildError({ code: "auth" /* AUTH */, message: "Missing TENSORLAKE_API_KEY credentials." });
|
|
5987
|
+
}
|
|
5988
|
+
return { apiUrl: context.apiUrl, bearerToken: context.apiKey, namespace: context.namespace };
|
|
5989
|
+
}
|
|
5990
|
+
function clientOptions(credentials) {
|
|
5991
|
+
return {
|
|
5992
|
+
apiUrl: credentials.apiUrl,
|
|
5993
|
+
bearerToken: credentials.bearerToken,
|
|
5994
|
+
namespace: credentials.namespace,
|
|
5995
|
+
useScopeHeaders: false
|
|
5996
|
+
};
|
|
5997
|
+
}
|
|
5998
|
+
function rejectLegacyReference(buildId) {
|
|
5999
|
+
if (typeof buildId !== "string" || buildId.trim().length === 0) {
|
|
6000
|
+
throw new ImageBuildError({ code: "usage" /* USAGE */, message: "buildId must be a non-empty string" });
|
|
6001
|
+
}
|
|
6002
|
+
if (buildId.startsWith("sandbox_template_")) {
|
|
6003
|
+
throw new ImageBuildError({
|
|
6004
|
+
code: "usage" /* USAGE */,
|
|
6005
|
+
message: `'${buildId}' is a legacy sandbox template id; legacy images have no build operation to get, wait for or cancel`,
|
|
6006
|
+
buildId
|
|
6007
|
+
});
|
|
6008
|
+
}
|
|
6009
|
+
if (buildId.startsWith("image_")) {
|
|
6010
|
+
throw new ImageBuildError({
|
|
6011
|
+
code: "usage" /* USAGE */,
|
|
6012
|
+
message: `'${buildId}' is an image id, not a build id; look the image up with findSandboxImageByName or use the build id admission returned`,
|
|
6013
|
+
buildId
|
|
6014
|
+
});
|
|
6015
|
+
}
|
|
6016
|
+
}
|
|
6017
|
+
async function __runWithInterrupt(signal, run) {
|
|
6018
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6019
|
+
if (signal === void 0) {
|
|
6020
|
+
try {
|
|
6021
|
+
return await run(void 0);
|
|
6022
|
+
} catch (error) {
|
|
6023
|
+
throw toImageBuildError(error);
|
|
6024
|
+
}
|
|
6025
|
+
}
|
|
6026
|
+
const interruptId = binding.createImageBuildInterrupt();
|
|
6027
|
+
const onAbort = () => binding.triggerImageBuildInterrupt(interruptId);
|
|
6028
|
+
if (signal.aborted) onAbort();
|
|
6029
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
6030
|
+
try {
|
|
6031
|
+
return await run(interruptId);
|
|
6032
|
+
} catch (error) {
|
|
6033
|
+
throw toImageBuildError(error);
|
|
6034
|
+
} finally {
|
|
6035
|
+
signal.removeEventListener("abort", onAbort);
|
|
6036
|
+
binding.releaseImageBuildInterrupt(interruptId);
|
|
6037
|
+
}
|
|
6038
|
+
}
|
|
6039
|
+
function makeEmitter(options) {
|
|
6040
|
+
const emit = options.emit ?? (options.verbose ? __imageBuildInternals.stderrEmit : __imageBuildInternals.noopEmit);
|
|
6041
|
+
let emitError;
|
|
6042
|
+
const forward = (event) => {
|
|
6043
|
+
try {
|
|
6044
|
+
emit(__imageBuildInternals.eventToEmitDict(event));
|
|
6045
|
+
} catch (error) {
|
|
6046
|
+
emitError ??= error;
|
|
6047
|
+
}
|
|
6048
|
+
};
|
|
6049
|
+
return {
|
|
6050
|
+
forward,
|
|
6051
|
+
emit,
|
|
6052
|
+
rethrow() {
|
|
6053
|
+
if (emitError != null) throw emitError;
|
|
6054
|
+
}
|
|
6055
|
+
};
|
|
6056
|
+
}
|
|
6057
|
+
function decodeStarted(json, credentials) {
|
|
6058
|
+
const payload = decodeResponse(json);
|
|
6059
|
+
const build = payload.build;
|
|
6060
|
+
if (!build || typeof build !== "object" || Array.isArray(build) || typeof build.build_id !== "string" || !build.build_id.trim()) {
|
|
6061
|
+
throw withRaw(new ImageBuildError({
|
|
6062
|
+
code: "service" /* SERVICE */,
|
|
6063
|
+
message: "Invalid image-build admission: expected a build with a non-empty build_id"
|
|
6064
|
+
}), { response: payload });
|
|
6065
|
+
}
|
|
6066
|
+
return new ImageBuildHandle(parseBuildInfo(build), credentials, payload.client_request_id);
|
|
6067
|
+
}
|
|
6068
|
+
async function startImageBuild(source, options = {}, deps = {}) {
|
|
6069
|
+
const emitter = makeEmitter({ emit: deps.emit ?? options.emit, verbose: options.verbose });
|
|
6070
|
+
let dockerfilePath;
|
|
6071
|
+
let dockerfileText;
|
|
6072
|
+
let contextDir;
|
|
6073
|
+
let name;
|
|
6074
|
+
let tempContextDir;
|
|
6075
|
+
if (source instanceof Image) {
|
|
6076
|
+
if (!source.baseImage) throw new Error("Image must have a baseImage to build");
|
|
6077
|
+
if (options.contextDir != null) {
|
|
6078
|
+
contextDir = import_node_path2.default.resolve(options.contextDir);
|
|
6079
|
+
} else if (__imageBuildInternals.imageRequiresContext(source)) {
|
|
6080
|
+
throw new Error(
|
|
6081
|
+
"This image reads files from the host (via COPY/ADD or a RUN bind mount), so it needs a build context. Pass `contextDir` pointing at the directory that contains those sources; they resolve relative to it, like `docker build <contextDir>`."
|
|
6082
|
+
);
|
|
6083
|
+
} else {
|
|
6084
|
+
tempContextDir = (0, import_node_fs.mkdtempSync)(import_node_path2.default.join(import_node_os.default.tmpdir(), "tl-build-context-"));
|
|
6085
|
+
contextDir = tempContextDir;
|
|
6086
|
+
}
|
|
6087
|
+
dockerfilePath = import_node_path2.default.join(contextDir, "Dockerfile");
|
|
6088
|
+
let text = dockerfileContent(source);
|
|
6089
|
+
if (!text.endsWith("\n")) text += "\n";
|
|
6090
|
+
dockerfileText = text;
|
|
6091
|
+
name = options.registeredName ?? source.name;
|
|
6092
|
+
} else if (typeof source === "string") {
|
|
6093
|
+
const resolved = import_node_path2.default.resolve(source);
|
|
6094
|
+
if (!(0, import_node_fs.existsSync)(resolved)) throw new Error(`Dockerfile not found: ${source}`);
|
|
6095
|
+
dockerfilePath = resolved;
|
|
6096
|
+
name = options.registeredName ?? __imageBuildInternals.defaultRegisteredName(resolved);
|
|
6097
|
+
} else {
|
|
6098
|
+
throw new TypeError(`source must be an Image or a Dockerfile path, got ${typeof source}`);
|
|
6099
|
+
}
|
|
6100
|
+
try {
|
|
6101
|
+
const credentials = credentialsFromEnv();
|
|
6102
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6103
|
+
emitter.emit({ type: "status", message: `Building image '${name}'...` });
|
|
6104
|
+
const json = await __runWithInterrupt(
|
|
6105
|
+
options.signal,
|
|
6106
|
+
(interruptId) => binding.startImageBuild(
|
|
6107
|
+
{
|
|
6108
|
+
apiUrl: credentials.apiUrl,
|
|
6109
|
+
bearerToken: credentials.bearerToken,
|
|
6110
|
+
dockerfilePath,
|
|
6111
|
+
registeredName: name,
|
|
6112
|
+
diskMb: options.diskMb,
|
|
6113
|
+
cpus: options.cpus,
|
|
6114
|
+
memoryMb: options.memoryMb,
|
|
6115
|
+
isPublic: options.isPublic ?? false,
|
|
6116
|
+
namespace: credentials.namespace,
|
|
6117
|
+
useScopeHeaders: false,
|
|
6118
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6119
|
+
dockerfileText,
|
|
6120
|
+
contextDir,
|
|
6121
|
+
cas: true,
|
|
6122
|
+
buildArgs: options.buildArgs
|
|
6123
|
+
},
|
|
6124
|
+
emitter.forward,
|
|
6125
|
+
interruptId
|
|
6126
|
+
)
|
|
6127
|
+
);
|
|
6128
|
+
emitter.rethrow();
|
|
6129
|
+
return decodeStarted(json, credentials);
|
|
6130
|
+
} finally {
|
|
6131
|
+
if (tempContextDir != null) (0, import_node_fs.rmSync)(tempContextDir, { recursive: true, force: true });
|
|
6132
|
+
}
|
|
6133
|
+
}
|
|
6134
|
+
async function startImageImport(imageReference, options = {}, deps = {}) {
|
|
6135
|
+
if (typeof imageReference !== "string" || imageReference.trim().length === 0) {
|
|
6136
|
+
throw new Error("image reference to import must not be empty");
|
|
6137
|
+
}
|
|
6138
|
+
const reference = imageReference.trim();
|
|
6139
|
+
const name = options.registeredName ?? __imageBuildInternals.defaultRegisteredNameFromImage(reference);
|
|
6140
|
+
const emitter = makeEmitter({ emit: deps.emit ?? options.emit, verbose: options.verbose });
|
|
6141
|
+
const credentials = credentialsFromEnv();
|
|
6142
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6143
|
+
emitter.emit({ type: "status", message: `Importing image '${reference}' as '${name}'...` });
|
|
6144
|
+
const json = await __runWithInterrupt(
|
|
6145
|
+
options.signal,
|
|
6146
|
+
(interruptId) => binding.startImageImport(
|
|
6147
|
+
{
|
|
6148
|
+
apiUrl: credentials.apiUrl,
|
|
6149
|
+
bearerToken: credentials.bearerToken,
|
|
6150
|
+
imageReference: reference,
|
|
6151
|
+
registeredName: name,
|
|
6152
|
+
diskMb: options.diskMb,
|
|
6153
|
+
cpus: options.cpus,
|
|
6154
|
+
memoryMb: options.memoryMb,
|
|
6155
|
+
isPublic: options.isPublic ?? false,
|
|
6156
|
+
namespace: credentials.namespace,
|
|
6157
|
+
useScopeHeaders: false,
|
|
6158
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6159
|
+
cas: true
|
|
6160
|
+
},
|
|
6161
|
+
emitter.forward,
|
|
6162
|
+
interruptId
|
|
6163
|
+
)
|
|
6164
|
+
);
|
|
6165
|
+
emitter.rethrow();
|
|
6166
|
+
return decodeStarted(json, credentials);
|
|
6167
|
+
}
|
|
6168
|
+
async function getImageBuild(buildId) {
|
|
6169
|
+
rejectLegacyReference(buildId);
|
|
6170
|
+
const credentials = credentialsFromEnv();
|
|
6171
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6172
|
+
let json;
|
|
6173
|
+
try {
|
|
6174
|
+
json = await binding.getImageBuild(clientOptions(credentials), buildId);
|
|
6175
|
+
} catch (error) {
|
|
6176
|
+
throw toImageBuildError(error);
|
|
6177
|
+
}
|
|
6178
|
+
return new ImageBuildHandle(parseBuildInfo(json), credentials);
|
|
6179
|
+
}
|
|
6180
|
+
async function waitImageBuild(buildId, options = {}) {
|
|
6181
|
+
rejectLegacyReference(buildId);
|
|
6182
|
+
const credentials = credentialsFromEnv();
|
|
6183
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6184
|
+
const emitter = makeEmitter(options);
|
|
6185
|
+
const json = await __runWithInterrupt(
|
|
6186
|
+
options.signal,
|
|
6187
|
+
(interruptId) => binding.waitImageBuild(
|
|
6188
|
+
clientOptions(credentials),
|
|
6189
|
+
buildId,
|
|
6190
|
+
{ timeoutMs: options.timeoutMs, followLogs: options.followLogs ?? false },
|
|
6191
|
+
emitter.forward,
|
|
6192
|
+
interruptId
|
|
6193
|
+
)
|
|
6194
|
+
);
|
|
6195
|
+
emitter.rethrow();
|
|
6196
|
+
return parseResult(json);
|
|
6197
|
+
}
|
|
6198
|
+
async function cancelImageBuildWith(credentials, selector) {
|
|
6199
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6200
|
+
let json;
|
|
6201
|
+
try {
|
|
6202
|
+
json = await binding.cancelImageBuild(clientOptions(credentials), {
|
|
6203
|
+
buildId: selector.buildId,
|
|
6204
|
+
clientRequestId: selector.clientRequestId
|
|
6205
|
+
});
|
|
6206
|
+
} catch (error) {
|
|
6207
|
+
throw toImageBuildError(error);
|
|
6208
|
+
}
|
|
6209
|
+
const payload = decodeResponse(json);
|
|
6210
|
+
const outcome = enumValue(ImageBuildCancellationOutcome, payload.outcome);
|
|
6211
|
+
return withRaw({ outcome, build: buildInfoOrNull(payload.build), confirmed: isConfirmedCancellation(outcome) }, payload);
|
|
6212
|
+
}
|
|
6213
|
+
async function cancelImageBuild(selector) {
|
|
6214
|
+
const hasBuild = selector.buildId != null;
|
|
6215
|
+
const hasRequest = selector.clientRequestId != null;
|
|
6216
|
+
if (hasBuild === hasRequest) {
|
|
6217
|
+
throw new ImageBuildError({
|
|
6218
|
+
code: "usage" /* USAGE */,
|
|
6219
|
+
message: "pass exactly one of buildId or clientRequestId"
|
|
6220
|
+
});
|
|
6221
|
+
}
|
|
6222
|
+
if (selector.buildId != null) rejectLegacyReference(selector.buildId);
|
|
6223
|
+
return cancelImageBuildWith(credentialsFromEnv(), selector);
|
|
6224
|
+
}
|
|
6225
|
+
var import_node_path2, import_node_os, import_node_fs, ImageBuildStatus, ImageBuildPhase, ImageBuildKind, ImageBuildCancellationOutcome, ImageBuildErrorCode, ImageBuildError, ImageBuildNotFoundError, ImageBuildInProgressError, ImageBuildFailedError, ImageBuildCancelledError, ImageBuildTimeoutError, ImageBuildInterruptedError, ImageBuildHandle;
|
|
6226
|
+
var init_image_builds = __esm({
|
|
6227
|
+
"src/image-builds.ts"() {
|
|
6228
|
+
"use strict";
|
|
6229
|
+
init_cjs_shims();
|
|
6230
|
+
import_node_path2 = __toESM(require("path"), 1);
|
|
6231
|
+
init_enum();
|
|
6232
|
+
import_node_os = __toESM(require("os"), 1);
|
|
6233
|
+
import_node_fs = require("fs");
|
|
6234
|
+
init_image();
|
|
6235
|
+
init_sandbox_image();
|
|
6236
|
+
ImageBuildStatus = /* @__PURE__ */ ((ImageBuildStatus2) => {
|
|
6237
|
+
ImageBuildStatus2["PENDING"] = "pending";
|
|
6238
|
+
ImageBuildStatus2["RUNNING"] = "running";
|
|
6239
|
+
ImageBuildStatus2["SUCCEEDED"] = "succeeded";
|
|
6240
|
+
ImageBuildStatus2["FAILED"] = "failed";
|
|
6241
|
+
ImageBuildStatus2["CANCELLED"] = "cancelled";
|
|
6242
|
+
ImageBuildStatus2["UNKNOWN"] = "unknown";
|
|
6243
|
+
return ImageBuildStatus2;
|
|
6244
|
+
})(ImageBuildStatus || {});
|
|
6245
|
+
ImageBuildPhase = /* @__PURE__ */ ((ImageBuildPhase2) => {
|
|
6246
|
+
ImageBuildPhase2["AWAITING_CONTEXT"] = "awaiting_context";
|
|
6247
|
+
ImageBuildPhase2["STARTING_BUILDER"] = "starting_builder";
|
|
6248
|
+
ImageBuildPhase2["EXECUTING"] = "executing";
|
|
6249
|
+
ImageBuildPhase2["SNAPSHOTTING"] = "snapshotting";
|
|
6250
|
+
ImageBuildPhase2["PUBLISHING"] = "publishing";
|
|
6251
|
+
ImageBuildPhase2["FINISHED"] = "finished";
|
|
6252
|
+
ImageBuildPhase2["UNKNOWN"] = "unknown";
|
|
6253
|
+
return ImageBuildPhase2;
|
|
6254
|
+
})(ImageBuildPhase || {});
|
|
6255
|
+
ImageBuildKind = /* @__PURE__ */ ((ImageBuildKind2) => {
|
|
6256
|
+
ImageBuildKind2["DOCKERFILE"] = "dockerfile";
|
|
6257
|
+
ImageBuildKind2["IMPORT"] = "import";
|
|
6258
|
+
ImageBuildKind2["DIRECT"] = "direct";
|
|
6259
|
+
ImageBuildKind2["UNKNOWN"] = "unknown";
|
|
6260
|
+
return ImageBuildKind2;
|
|
6261
|
+
})(ImageBuildKind || {});
|
|
6262
|
+
ImageBuildCancellationOutcome = /* @__PURE__ */ ((ImageBuildCancellationOutcome2) => {
|
|
6263
|
+
ImageBuildCancellationOutcome2["CANCELLED"] = "cancelled";
|
|
6264
|
+
ImageBuildCancellationOutcome2["ALREADY_CANCELLED"] = "already_cancelled";
|
|
6265
|
+
ImageBuildCancellationOutcome2["ALREADY_COMPLETED"] = "already_completed";
|
|
6266
|
+
ImageBuildCancellationOutcome2["ALREADY_FAILED"] = "already_failed";
|
|
6267
|
+
ImageBuildCancellationOutcome2["NOT_ADMITTED"] = "not_admitted";
|
|
6268
|
+
ImageBuildCancellationOutcome2["UNCONFIRMED"] = "unconfirmed";
|
|
6269
|
+
ImageBuildCancellationOutcome2["UNKNOWN"] = "unknown";
|
|
6270
|
+
return ImageBuildCancellationOutcome2;
|
|
6271
|
+
})(ImageBuildCancellationOutcome || {});
|
|
6272
|
+
ImageBuildErrorCode = /* @__PURE__ */ ((ImageBuildErrorCode2) => {
|
|
6273
|
+
ImageBuildErrorCode2["USAGE"] = "usage";
|
|
6274
|
+
ImageBuildErrorCode2["AUTH"] = "auth";
|
|
6275
|
+
ImageBuildErrorCode2["NOT_FOUND"] = "not_found";
|
|
6276
|
+
ImageBuildErrorCode2["IMAGE_BUILD_IN_PROGRESS"] = "image_build_in_progress";
|
|
6277
|
+
ImageBuildErrorCode2["CLIENT_REQUEST_ID_MISMATCH"] = "client_request_id_mismatch";
|
|
6278
|
+
ImageBuildErrorCode2["FAILED"] = "failed";
|
|
6279
|
+
ImageBuildErrorCode2["CANCELLED"] = "cancelled";
|
|
6280
|
+
ImageBuildErrorCode2["TIMEOUT"] = "timeout";
|
|
6281
|
+
ImageBuildErrorCode2["INTERRUPTED"] = "interrupted";
|
|
6282
|
+
ImageBuildErrorCode2["SERVICE"] = "service";
|
|
6283
|
+
ImageBuildErrorCode2["INTERNAL"] = "internal";
|
|
6284
|
+
ImageBuildErrorCode2["UNKNOWN"] = "unknown";
|
|
6285
|
+
return ImageBuildErrorCode2;
|
|
6286
|
+
})(ImageBuildErrorCode || {});
|
|
6287
|
+
ImageBuildError = class extends Error {
|
|
6288
|
+
code;
|
|
6289
|
+
buildId;
|
|
6290
|
+
clientRequestId;
|
|
6291
|
+
details;
|
|
6292
|
+
constructor(details) {
|
|
6293
|
+
super(details.message);
|
|
6294
|
+
this.name = "ImageBuildError";
|
|
6295
|
+
this.code = details.code;
|
|
6296
|
+
this.details = { ...details };
|
|
6297
|
+
withRaw(this, {});
|
|
6298
|
+
if ("confirmed" in details) {
|
|
6299
|
+
this.details.confirmed = details.confirmed === true && isConfirmedCancellation(details.outcome);
|
|
6300
|
+
}
|
|
6301
|
+
if (details.buildId) this.buildId = details.buildId;
|
|
6302
|
+
if (details.clientRequestId) this.clientRequestId = details.clientRequestId;
|
|
6303
|
+
}
|
|
6304
|
+
};
|
|
6305
|
+
ImageBuildNotFoundError = class extends ImageBuildError {
|
|
6306
|
+
constructor(details) {
|
|
6307
|
+
super(details);
|
|
6308
|
+
this.name = "ImageBuildNotFoundError";
|
|
6309
|
+
}
|
|
6310
|
+
};
|
|
6311
|
+
ImageBuildInProgressError = class extends ImageBuildError {
|
|
6312
|
+
imageName;
|
|
6313
|
+
activeBuildId;
|
|
6314
|
+
activeKind;
|
|
6315
|
+
activeStatus;
|
|
6316
|
+
constructor(details) {
|
|
6317
|
+
super(details);
|
|
6318
|
+
this.name = "ImageBuildInProgressError";
|
|
6319
|
+
if (details.imageName) this.imageName = details.imageName;
|
|
6320
|
+
if (details.activeBuildId) this.activeBuildId = details.activeBuildId;
|
|
6321
|
+
if (details.activeKind) this.activeKind = details.activeKind;
|
|
6322
|
+
if (details.activeStatus) this.activeStatus = details.activeStatus;
|
|
6323
|
+
}
|
|
6324
|
+
};
|
|
6325
|
+
ImageBuildFailedError = class extends ImageBuildError {
|
|
6326
|
+
error;
|
|
6327
|
+
info;
|
|
6328
|
+
constructor(details) {
|
|
6329
|
+
super(details);
|
|
6330
|
+
this.name = "ImageBuildFailedError";
|
|
6331
|
+
this.error = details.error ?? "no error recorded";
|
|
6332
|
+
if (details.info) this.info = details.info;
|
|
6333
|
+
}
|
|
6334
|
+
};
|
|
6335
|
+
ImageBuildCancelledError = class extends ImageBuildError {
|
|
6336
|
+
info;
|
|
6337
|
+
constructor(details) {
|
|
6338
|
+
super(details);
|
|
6339
|
+
this.name = "ImageBuildCancelledError";
|
|
6340
|
+
if (details.info) this.info = details.info;
|
|
6341
|
+
}
|
|
6342
|
+
};
|
|
6343
|
+
ImageBuildTimeoutError = class extends ImageBuildError {
|
|
6344
|
+
constructor(details) {
|
|
6345
|
+
super(details);
|
|
6346
|
+
this.name = "ImageBuildTimeoutError";
|
|
6347
|
+
}
|
|
6348
|
+
};
|
|
6349
|
+
ImageBuildInterruptedError = class extends ImageBuildError {
|
|
6350
|
+
outcome;
|
|
6351
|
+
confirmed;
|
|
6352
|
+
result;
|
|
6353
|
+
constructor(details) {
|
|
6354
|
+
super(details);
|
|
6355
|
+
this.name = "ImageBuildInterruptedError";
|
|
6356
|
+
this.outcome = details.outcome ?? "unconfirmed" /* UNCONFIRMED */;
|
|
6357
|
+
this.confirmed = this.details.confirmed === true;
|
|
6358
|
+
if (details.result) this.result = details.result;
|
|
6359
|
+
}
|
|
6360
|
+
};
|
|
6361
|
+
ImageBuildHandle = class {
|
|
6362
|
+
buildId;
|
|
6363
|
+
/**
|
|
6364
|
+
* The admission's request id, when this handle started the build. Never
|
|
6365
|
+
* needed to cancel; a recovery aid for a lost admission answer.
|
|
6366
|
+
*/
|
|
6367
|
+
clientRequestId;
|
|
6368
|
+
#info;
|
|
6369
|
+
#credentials;
|
|
6370
|
+
/** @internal */
|
|
6371
|
+
constructor(info, credentials, clientRequestId) {
|
|
6372
|
+
this.buildId = info.buildId;
|
|
6373
|
+
this.clientRequestId = clientRequestId ?? info.clientRequestId ?? null;
|
|
6374
|
+
this.#info = info;
|
|
6375
|
+
this.#credentials = credentials;
|
|
6376
|
+
}
|
|
6377
|
+
/** The last observed state. */
|
|
6378
|
+
get info() {
|
|
6379
|
+
return this.#info;
|
|
6380
|
+
}
|
|
6381
|
+
/** Re-read the current state. */
|
|
6382
|
+
async refresh() {
|
|
6383
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6384
|
+
let json;
|
|
6385
|
+
try {
|
|
6386
|
+
json = await binding.getImageBuild(clientOptions(this.#credentials), this.buildId);
|
|
6387
|
+
} catch (error) {
|
|
6388
|
+
throw toImageBuildError(error);
|
|
6389
|
+
}
|
|
6390
|
+
this.#info = parseBuildInfo(json);
|
|
6391
|
+
return this.#info;
|
|
6392
|
+
}
|
|
6393
|
+
/**
|
|
6394
|
+
* Wait for publication and return this build's immutable result. See
|
|
6395
|
+
* {@link ImageBuildWaitOptions} for the timeout/abort distinction.
|
|
6396
|
+
*/
|
|
6397
|
+
async wait(options = {}) {
|
|
6398
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6399
|
+
const emitter = makeEmitter(options);
|
|
6400
|
+
const json = await __runWithInterrupt(
|
|
6401
|
+
options.signal,
|
|
6402
|
+
(interruptId) => binding.waitImageBuild(
|
|
6403
|
+
clientOptions(this.#credentials),
|
|
6404
|
+
this.buildId,
|
|
6405
|
+
{ timeoutMs: options.timeoutMs, followLogs: options.followLogs ?? false },
|
|
6406
|
+
emitter.forward,
|
|
6407
|
+
interruptId
|
|
6408
|
+
)
|
|
6409
|
+
);
|
|
6410
|
+
emitter.rethrow();
|
|
6411
|
+
const raw = decodeResponse(json);
|
|
6412
|
+
const result = camelizeRecord(raw);
|
|
6413
|
+
this.#info = withRaw(
|
|
6414
|
+
{ ...this.#info, status: "succeeded" /* SUCCEEDED */, result },
|
|
6415
|
+
{ ...this.#info.raw, status: "succeeded", result: raw }
|
|
6416
|
+
);
|
|
6417
|
+
return result;
|
|
6418
|
+
}
|
|
6419
|
+
/** Cancel this build by its id (the sufficient selector). */
|
|
6420
|
+
async cancel() {
|
|
6421
|
+
return cancelImageBuildWith(this.#credentials, { buildId: this.buildId });
|
|
6422
|
+
}
|
|
6423
|
+
};
|
|
6424
|
+
}
|
|
6425
|
+
});
|
|
6426
|
+
|
|
6425
6427
|
// src/sandbox-image.ts
|
|
6426
6428
|
var sandbox_image_exports = {};
|
|
6427
6429
|
__export(sandbox_image_exports, {
|
|
6430
|
+
__imageBuildInternals: () => __imageBuildInternals,
|
|
6428
6431
|
__setNativeBindingForTest: () => __setNativeBindingForTest,
|
|
6429
6432
|
buildContextFromEnv: () => buildContextFromEnv,
|
|
6430
6433
|
createSandboxImage: () => createSandboxImage,
|
|
6431
6434
|
deleteSandboxImage: () => deleteSandboxImage,
|
|
6435
|
+
deleteSandboxImageWithCredentials: () => deleteSandboxImageWithCredentials,
|
|
6432
6436
|
findSandboxImageByName: () => findSandboxImageByName,
|
|
6437
|
+
findSandboxImageByNameWithCredentials: () => findSandboxImageByNameWithCredentials,
|
|
6433
6438
|
importSandboxImage: () => importSandboxImage,
|
|
6434
6439
|
listSandboxImages: () => listSandboxImages,
|
|
6440
|
+
listSandboxImagesWithCredentials: () => listSandboxImagesWithCredentials,
|
|
6435
6441
|
runCreateSandboxImageCli: () => runCreateSandboxImageCli,
|
|
6436
6442
|
runImportSandboxImageCli: () => runImportSandboxImageCli
|
|
6437
6443
|
});
|
|
@@ -6505,6 +6511,15 @@ function eventToEmitDict(event) {
|
|
|
6505
6511
|
message: event.message
|
|
6506
6512
|
};
|
|
6507
6513
|
if (event.stream != null) out.stream = event.stream;
|
|
6514
|
+
if (event.buildId != null) out.build_id = event.buildId;
|
|
6515
|
+
if (event.clientRequestId !== void 0 && event.eventType !== "status") {
|
|
6516
|
+
out.client_request_id = event.clientRequestId;
|
|
6517
|
+
}
|
|
6518
|
+
if (event.status != null) out.status = event.status;
|
|
6519
|
+
if (event.phase !== void 0 && event.eventType.startsWith("build_")) out.phase = event.phase;
|
|
6520
|
+
if (event.attempt != null) out.attempt = event.attempt;
|
|
6521
|
+
if (event.outcome != null) out.outcome = event.outcome;
|
|
6522
|
+
if (event.confirmed != null) out.confirmed = event.confirmed;
|
|
6508
6523
|
return out;
|
|
6509
6524
|
}
|
|
6510
6525
|
function runOpMountsContext(op) {
|
|
@@ -6606,38 +6621,47 @@ async function createSandboxImage(source, options = {}, deps = {}) {
|
|
|
6606
6621
|
deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
|
|
6607
6622
|
);
|
|
6608
6623
|
}
|
|
6624
|
+
if (options.signal !== void 0 && !options.cas) {
|
|
6625
|
+
throw new Error(
|
|
6626
|
+
"signal is only supported for CAS image builds (cas: true); a legacy build has no Image Service build operation to cancel"
|
|
6627
|
+
);
|
|
6628
|
+
}
|
|
6609
6629
|
emit({ type: "status", message: `Building image '${effectiveName}'...` });
|
|
6610
6630
|
const binding = loadNativeBinding();
|
|
6611
6631
|
let emitError;
|
|
6612
|
-
const
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
6632
|
+
const nativeOptions = {
|
|
6633
|
+
apiUrl: context.apiUrl,
|
|
6634
|
+
bearerToken,
|
|
6635
|
+
dockerfilePath,
|
|
6636
|
+
registeredName: effectiveName,
|
|
6637
|
+
diskMb: options.diskMb,
|
|
6638
|
+
builderDiskMb: options.builderDiskMb,
|
|
6639
|
+
cpus: options.cpus,
|
|
6640
|
+
memoryMb: options.memoryMb,
|
|
6641
|
+
isPublic: options.isPublic ?? false,
|
|
6642
|
+
organizationId: usePat ? context.organizationId : void 0,
|
|
6643
|
+
projectId: usePat ? context.projectId : void 0,
|
|
6644
|
+
namespace: context.namespace,
|
|
6645
|
+
useScopeHeaders: usePat,
|
|
6646
|
+
userAgent: void 0,
|
|
6647
|
+
dockerCompat: options.dockerCompat ?? false,
|
|
6648
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6649
|
+
dockerfileText,
|
|
6650
|
+
contextDir: nativeContextDir,
|
|
6651
|
+
cas: options.cas ?? false,
|
|
6652
|
+
buildArgs: options.buildArgs
|
|
6653
|
+
};
|
|
6654
|
+
const forward = (event) => {
|
|
6655
|
+
try {
|
|
6656
|
+
emit(eventToEmitDict(event));
|
|
6657
|
+
} catch (error) {
|
|
6658
|
+
emitError ??= error;
|
|
6639
6659
|
}
|
|
6640
|
-
|
|
6660
|
+
};
|
|
6661
|
+
const resultJson = options.cas ? await __runWithInterrupt(
|
|
6662
|
+
options.signal,
|
|
6663
|
+
(interruptId) => binding.buildSandboxImage(nativeOptions, forward, interruptId)
|
|
6664
|
+
) : await binding.buildSandboxImage(nativeOptions, forward);
|
|
6641
6665
|
if (emitError != null) {
|
|
6642
6666
|
throw emitError;
|
|
6643
6667
|
}
|
|
@@ -6683,39 +6707,47 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
|
|
|
6683
6707
|
deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
|
|
6684
6708
|
);
|
|
6685
6709
|
}
|
|
6710
|
+
if (options.signal !== void 0 && !options.cas) {
|
|
6711
|
+
throw new Error(
|
|
6712
|
+
"signal is only supported for CAS image imports (cas: true); a legacy import has no Image Service build operation to cancel"
|
|
6713
|
+
);
|
|
6714
|
+
}
|
|
6686
6715
|
emit({
|
|
6687
6716
|
type: "status",
|
|
6688
6717
|
message: `Importing image '${reference}' as '${effectiveName}'...`
|
|
6689
6718
|
});
|
|
6690
6719
|
const binding = loadNativeBinding();
|
|
6691
6720
|
let emitError;
|
|
6692
|
-
const
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
}
|
|
6721
|
+
const nativeOptions = {
|
|
6722
|
+
apiUrl: context.apiUrl,
|
|
6723
|
+
bearerToken,
|
|
6724
|
+
imageReference: reference,
|
|
6725
|
+
registeredName: effectiveName,
|
|
6726
|
+
diskMb: options.diskMb,
|
|
6727
|
+
builderDiskMb: options.builderDiskMb,
|
|
6728
|
+
cpus: options.cpus,
|
|
6729
|
+
memoryMb: options.memoryMb,
|
|
6730
|
+
isPublic: options.isPublic ?? false,
|
|
6731
|
+
organizationId: usePat ? context.organizationId : void 0,
|
|
6732
|
+
projectId: usePat ? context.projectId : void 0,
|
|
6733
|
+
namespace: context.namespace,
|
|
6734
|
+
useScopeHeaders: usePat,
|
|
6735
|
+
userAgent: void 0,
|
|
6736
|
+
dockerCompat: options.dockerCompat ?? false,
|
|
6737
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6738
|
+
cas: options.cas ?? false
|
|
6739
|
+
};
|
|
6740
|
+
const forward = (event) => {
|
|
6741
|
+
try {
|
|
6742
|
+
emit(eventToEmitDict(event));
|
|
6743
|
+
} catch (error) {
|
|
6744
|
+
emitError ??= error;
|
|
6717
6745
|
}
|
|
6718
|
-
|
|
6746
|
+
};
|
|
6747
|
+
const resultJson = options.cas ? await __runWithInterrupt(
|
|
6748
|
+
options.signal,
|
|
6749
|
+
(interruptId) => binding.importSandboxImage(nativeOptions, forward, interruptId)
|
|
6750
|
+
) : await binding.importSandboxImage(nativeOptions, forward);
|
|
6719
6751
|
if (emitError != null) {
|
|
6720
6752
|
throw emitError;
|
|
6721
6753
|
}
|
|
@@ -6731,10 +6763,7 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
|
|
|
6731
6763
|
emit({ type: "done" });
|
|
6732
6764
|
return result;
|
|
6733
6765
|
}
|
|
6734
|
-
|
|
6735
|
-
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6736
|
-
throw new TypeError("imageName must be a non-empty string");
|
|
6737
|
-
}
|
|
6766
|
+
function catalogOptionsFromEnv() {
|
|
6738
6767
|
const context = buildContextFromEnv();
|
|
6739
6768
|
const bearerToken = context.apiKey;
|
|
6740
6769
|
if (!bearerToken) {
|
|
@@ -6745,66 +6774,76 @@ async function deleteSandboxImage(imageName) {
|
|
|
6745
6774
|
}
|
|
6746
6775
|
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6747
6776
|
}
|
|
6748
|
-
|
|
6749
|
-
apiUrl: context.apiUrl,
|
|
6750
|
-
apiKey: bearerToken,
|
|
6751
|
-
namespace: context.namespace
|
|
6752
|
-
});
|
|
6753
|
-
try {
|
|
6754
|
-
await client.deleteSandboxImage(imageName);
|
|
6755
|
-
} finally {
|
|
6756
|
-
client.close();
|
|
6757
|
-
}
|
|
6777
|
+
return { apiUrl: context.apiUrl, bearerToken, useScopeHeaders: false };
|
|
6758
6778
|
}
|
|
6759
|
-
|
|
6760
|
-
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6761
|
-
throw new TypeError("imageName must be a non-empty string");
|
|
6762
|
-
}
|
|
6779
|
+
function catalogOptionsFromCredentials(credentials) {
|
|
6763
6780
|
const context = buildContextFromEnv();
|
|
6764
|
-
const bearerToken = context.apiKey;
|
|
6781
|
+
const bearerToken = credentials.apiKey ?? context.apiKey;
|
|
6765
6782
|
if (!bearerToken) {
|
|
6766
|
-
if (context.personalAccessToken) {
|
|
6767
|
-
throw new Error(
|
|
6768
|
-
"Sandbox image SDKs require TENSORLAKE_API_KEY. Personal access tokens are CLI-only."
|
|
6769
|
-
);
|
|
6770
|
-
}
|
|
6771
6783
|
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6772
6784
|
}
|
|
6773
|
-
const
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
namespace: context.namespace
|
|
6777
|
-
});
|
|
6778
|
-
try {
|
|
6779
|
-
return await client.findSandboxImageByName(imageName);
|
|
6780
|
-
} finally {
|
|
6781
|
-
client.close();
|
|
6785
|
+
const { organizationId, projectId } = credentials;
|
|
6786
|
+
if (organizationId === void 0 !== (projectId === void 0)) {
|
|
6787
|
+
throw new TypeError("organizationId and projectId must be given together");
|
|
6782
6788
|
}
|
|
6789
|
+
return {
|
|
6790
|
+
apiUrl: credentials.apiUrl ?? context.apiUrl,
|
|
6791
|
+
bearerToken,
|
|
6792
|
+
organizationId,
|
|
6793
|
+
projectId,
|
|
6794
|
+
useScopeHeaders: organizationId !== void 0
|
|
6795
|
+
};
|
|
6783
6796
|
}
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
"Sandbox image SDKs require TENSORLAKE_API_KEY. Personal access tokens are CLI-only."
|
|
6791
|
-
);
|
|
6792
|
-
}
|
|
6793
|
-
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6797
|
+
function parseTemplate(json) {
|
|
6798
|
+
return JSON.parse(json);
|
|
6799
|
+
}
|
|
6800
|
+
async function deleteSandboxImage(imageName) {
|
|
6801
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6802
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6794
6803
|
}
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
+
await loadNativeBinding().deleteSandboxImage(catalogOptionsFromEnv(), imageName);
|
|
6805
|
+
}
|
|
6806
|
+
async function deleteSandboxImageWithCredentials(credentials, imageName) {
|
|
6807
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6808
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6809
|
+
}
|
|
6810
|
+
await loadNativeBinding().deleteSandboxImage(
|
|
6811
|
+
catalogOptionsFromCredentials(credentials),
|
|
6812
|
+
imageName
|
|
6813
|
+
);
|
|
6814
|
+
}
|
|
6815
|
+
async function findSandboxImageByName(imageName) {
|
|
6816
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6817
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6818
|
+
}
|
|
6819
|
+
const json = await loadNativeBinding().findSandboxImage(
|
|
6820
|
+
catalogOptionsFromEnv(),
|
|
6821
|
+
imageName
|
|
6822
|
+
);
|
|
6823
|
+
return json == null ? null : parseTemplate(json);
|
|
6824
|
+
}
|
|
6825
|
+
async function findSandboxImageByNameWithCredentials(credentials, imageName) {
|
|
6826
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6827
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6804
6828
|
}
|
|
6829
|
+
const json = await loadNativeBinding().findSandboxImage(
|
|
6830
|
+
catalogOptionsFromCredentials(credentials),
|
|
6831
|
+
imageName
|
|
6832
|
+
);
|
|
6833
|
+
return json == null ? null : parseTemplate(json);
|
|
6834
|
+
}
|
|
6835
|
+
async function listSandboxImages() {
|
|
6836
|
+
const json = await loadNativeBinding().listSandboxImages(catalogOptionsFromEnv());
|
|
6837
|
+
return JSON.parse(json);
|
|
6838
|
+
}
|
|
6839
|
+
async function listSandboxImagesWithCredentials(credentials) {
|
|
6840
|
+
const json = await loadNativeBinding().listSandboxImages(
|
|
6841
|
+
catalogOptionsFromCredentials(credentials)
|
|
6842
|
+
);
|
|
6843
|
+
return JSON.parse(json);
|
|
6805
6844
|
}
|
|
6806
6845
|
async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
|
|
6807
|
-
const parsed = (0,
|
|
6846
|
+
const parsed = (0, import_node_util.parseArgs)({
|
|
6808
6847
|
args: argv,
|
|
6809
6848
|
allowPositionals: true,
|
|
6810
6849
|
options: {
|
|
@@ -6858,7 +6897,7 @@ async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
|
|
|
6858
6897
|
);
|
|
6859
6898
|
}
|
|
6860
6899
|
async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
|
|
6861
|
-
const parsed = (0,
|
|
6900
|
+
const parsed = (0, import_node_util.parseArgs)({
|
|
6862
6901
|
args: argv,
|
|
6863
6902
|
allowPositionals: true,
|
|
6864
6903
|
options: {
|
|
@@ -6911,7 +6950,7 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
|
|
|
6911
6950
|
{ emit: ndjsonStdoutEmit, _allowPat: true }
|
|
6912
6951
|
);
|
|
6913
6952
|
}
|
|
6914
|
-
var import_node_path3, import_node_os2, import_node_fs2,
|
|
6953
|
+
var import_node_path3, import_node_os2, import_node_fs2, import_node_util, cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME2, __imageBuildInternals;
|
|
6915
6954
|
var init_sandbox_image = __esm({
|
|
6916
6955
|
"src/sandbox-image.ts"() {
|
|
6917
6956
|
"use strict";
|
|
@@ -6919,11 +6958,21 @@ var init_sandbox_image = __esm({
|
|
|
6919
6958
|
import_node_path3 = __toESM(require("path"), 1);
|
|
6920
6959
|
import_node_os2 = __toESM(require("os"), 1);
|
|
6921
6960
|
import_node_fs2 = require("fs");
|
|
6922
|
-
|
|
6923
|
-
init_cloud_client();
|
|
6961
|
+
import_node_util = require("util");
|
|
6924
6962
|
init_image();
|
|
6925
6963
|
init_native_binding();
|
|
6964
|
+
init_image_builds();
|
|
6926
6965
|
DEFAULT_IMAGE_NAME2 = "default";
|
|
6966
|
+
__imageBuildInternals = {
|
|
6967
|
+
loadNativeBinding: () => loadNativeBinding(),
|
|
6968
|
+
buildContextFromEnv: () => buildContextFromEnv(),
|
|
6969
|
+
stderrEmit: (event) => stderrEmit(event),
|
|
6970
|
+
noopEmit: (event) => noopEmit(event),
|
|
6971
|
+
eventToEmitDict: (event) => eventToEmitDict(event),
|
|
6972
|
+
imageRequiresContext: (image) => imageRequiresContext(image),
|
|
6973
|
+
defaultRegisteredName: (dockerfilePath) => defaultRegisteredName(dockerfilePath),
|
|
6974
|
+
defaultRegisteredNameFromImage: (reference) => defaultRegisteredNameFromImage(reference)
|
|
6975
|
+
};
|
|
6927
6976
|
}
|
|
6928
6977
|
});
|
|
6929
6978
|
|
|
@@ -6948,7 +6997,20 @@ __export(index_exports, {
|
|
|
6948
6997
|
Headers: () => Headers,
|
|
6949
6998
|
HttpBody: () => HttpBody,
|
|
6950
6999
|
Image: () => Image,
|
|
7000
|
+
ImageBuildCancellationOutcome: () => ImageBuildCancellationOutcome,
|
|
7001
|
+
ImageBuildCancelledError: () => ImageBuildCancelledError,
|
|
7002
|
+
ImageBuildError: () => ImageBuildError,
|
|
7003
|
+
ImageBuildErrorCode: () => ImageBuildErrorCode,
|
|
7004
|
+
ImageBuildFailedError: () => ImageBuildFailedError,
|
|
7005
|
+
ImageBuildHandle: () => ImageBuildHandle,
|
|
7006
|
+
ImageBuildInProgressError: () => ImageBuildInProgressError,
|
|
7007
|
+
ImageBuildInterruptedError: () => ImageBuildInterruptedError,
|
|
7008
|
+
ImageBuildKind: () => ImageBuildKind,
|
|
7009
|
+
ImageBuildNotFoundError: () => ImageBuildNotFoundError,
|
|
6951
7010
|
ImageBuildOperationType: () => ImageBuildOperationType,
|
|
7011
|
+
ImageBuildPhase: () => ImageBuildPhase,
|
|
7012
|
+
ImageBuildStatus: () => ImageBuildStatus,
|
|
7013
|
+
ImageBuildTimeoutError: () => ImageBuildTimeoutError,
|
|
6952
7014
|
MountError: () => MountError,
|
|
6953
7015
|
OutputMode: () => OutputMode,
|
|
6954
7016
|
PendingSandbox: () => PendingSandbox,
|
|
@@ -6981,12 +7043,14 @@ __export(index_exports, {
|
|
|
6981
7043
|
TERMINATION_REASON_CANCELLED: () => TERMINATION_REASON_CANCELLED,
|
|
6982
7044
|
TERMINATION_REASON_NO_CAPACITY: () => TERMINATION_REASON_NO_CAPACITY,
|
|
6983
7045
|
TcpTunnel: () => TcpTunnel,
|
|
7046
|
+
cancelImageBuild: () => cancelImageBuild,
|
|
6984
7047
|
createFileSystem: () => createFileSystem,
|
|
6985
7048
|
createSandboxImage: () => createSandboxImage,
|
|
6986
7049
|
deleteFileSystem: () => deleteFileSystem,
|
|
6987
7050
|
deleteSandboxImage: () => deleteSandboxImage,
|
|
6988
7051
|
dockerfileContent: () => dockerfileContent,
|
|
6989
7052
|
findSandboxImageByName: () => findSandboxImageByName,
|
|
7053
|
+
getImageBuild: () => getImageBuild,
|
|
6990
7054
|
importSandboxImage: () => importSandboxImage,
|
|
6991
7055
|
isSandboxPending: () => isSandboxPending,
|
|
6992
7056
|
listFileSystems: () => listFileSystems,
|
|
@@ -6998,7 +7062,10 @@ __export(index_exports, {
|
|
|
6998
7062
|
runLocal: () => runLocal,
|
|
6999
7063
|
runRemote: () => runRemote,
|
|
7000
7064
|
sandboxUrlFromIngressEndpoint: () => sandboxUrlFromIngressEndpoint,
|
|
7001
|
-
schema: () => schema
|
|
7065
|
+
schema: () => schema,
|
|
7066
|
+
startImageBuild: () => startImageBuild,
|
|
7067
|
+
startImageImport: () => startImageImport,
|
|
7068
|
+
waitImageBuild: () => waitImageBuild
|
|
7002
7069
|
});
|
|
7003
7070
|
module.exports = __toCommonJS(index_exports);
|
|
7004
7071
|
init_cjs_shims();
|
|
@@ -7008,11 +7075,546 @@ init_pending_sandbox();
|
|
|
7008
7075
|
init_sandbox();
|
|
7009
7076
|
init_desktop();
|
|
7010
7077
|
init_tunnel();
|
|
7011
|
-
|
|
7078
|
+
|
|
7079
|
+
// src/cloud-client.ts
|
|
7080
|
+
init_cjs_shims();
|
|
7081
|
+
var import_nanoid = require("nanoid");
|
|
7082
|
+
init_defaults();
|
|
7083
|
+
|
|
7084
|
+
// src/native-cloud.ts
|
|
7085
|
+
init_cjs_shims();
|
|
7086
|
+
init_native_sandbox();
|
|
7087
|
+
init_native_worker_client();
|
|
7088
|
+
var NativeCloudTransport = class {
|
|
7089
|
+
constructor(options) {
|
|
7090
|
+
this.options = options;
|
|
7091
|
+
if (!Number.isSafeInteger(options.maxRetries) || options.maxRetries < 0 || options.maxRetries > 4294967295) {
|
|
7092
|
+
throw new RangeError("maxRetries must be a non-negative 32-bit integer");
|
|
7093
|
+
}
|
|
7094
|
+
if (!Number.isFinite(options.retryBackoffMs) || options.retryBackoffMs < 0) {
|
|
7095
|
+
throw new RangeError("retryBackoffMs must be a non-negative finite number");
|
|
7096
|
+
}
|
|
7097
|
+
}
|
|
7098
|
+
native;
|
|
7099
|
+
closed = false;
|
|
7100
|
+
client() {
|
|
7101
|
+
if (this.closed) throw new Error("Tensorlake native client is closed");
|
|
7102
|
+
if (this.native) return this.native;
|
|
7103
|
+
const ctor = loadNativeSandboxBinding().NativeCloudClient;
|
|
7104
|
+
if (!ctor) throw new Error("Native binding does not export NativeCloudClient; rebuild with 'npm run build:native'");
|
|
7105
|
+
return this.native = new ctor(JSON.stringify(this.options));
|
|
7106
|
+
}
|
|
7107
|
+
close() {
|
|
7108
|
+
this.closed = true;
|
|
7109
|
+
releaseNativeHandle(this.native ?? null);
|
|
7110
|
+
this.native = void 0;
|
|
7111
|
+
}
|
|
7112
|
+
async requestResponse(method, path4, options) {
|
|
7113
|
+
const request = await serializeRequest(method, path4, options);
|
|
7114
|
+
const raw = await callNative(() => this.client().request(request));
|
|
7115
|
+
const response = new Response(
|
|
7116
|
+
[204, 205, 304].includes(raw.status) ? null : Uint8Array.from(raw.data).buffer,
|
|
7117
|
+
{ status: raw.status, headers: JSON.parse(raw.headersJson) }
|
|
7118
|
+
);
|
|
7119
|
+
return Object.assign(response, { traceId: raw.traceId });
|
|
7120
|
+
}
|
|
7121
|
+
async requestJson(method, path4) {
|
|
7122
|
+
const response = await this.requestResponse(method, path4);
|
|
7123
|
+
const text = await response.text();
|
|
7124
|
+
const value = text ? JSON.parse(text) : null;
|
|
7125
|
+
return Object.assign(value ?? {}, { traceId: response.traceId });
|
|
7126
|
+
}
|
|
7127
|
+
async *stream(method, path4, signal) {
|
|
7128
|
+
if (signal?.aborted) return;
|
|
7129
|
+
const request = await serializeRequest(method, path4, { headers: { Accept: "text/event-stream" } });
|
|
7130
|
+
yield* nativeEventStream((emit) => this.client().stream(request, emit), void 0, signal);
|
|
7131
|
+
}
|
|
7132
|
+
};
|
|
7133
|
+
async function serializeRequest(method, path4, options) {
|
|
7134
|
+
const headers = { ...options?.headers };
|
|
7135
|
+
let body = options?.body;
|
|
7136
|
+
if (options?.json !== void 0) {
|
|
7137
|
+
body = JSON.stringify(options.json);
|
|
7138
|
+
if (!Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) {
|
|
7139
|
+
headers["Content-Type"] = "application/json";
|
|
7140
|
+
}
|
|
7141
|
+
}
|
|
7142
|
+
const request = {
|
|
7143
|
+
method,
|
|
7144
|
+
path: path4,
|
|
7145
|
+
headersJson: JSON.stringify(headers),
|
|
7146
|
+
statusOnlyCodes: [...options?.statusOnlyCodes ?? []]
|
|
7147
|
+
};
|
|
7148
|
+
if (body instanceof FormData) {
|
|
7149
|
+
request.parts = [];
|
|
7150
|
+
for (const [name, value] of body.entries()) {
|
|
7151
|
+
request.parts.push(typeof value === "string" ? { name, data: Buffer.from(value) } : { name, data: Buffer.from(await value.arrayBuffer()), filename: value.name, contentType: value.type || "application/octet-stream" });
|
|
7152
|
+
}
|
|
7153
|
+
} else if (body !== void 0) {
|
|
7154
|
+
if (body instanceof Blob) request.body = Buffer.from(await body.arrayBuffer());
|
|
7155
|
+
else if (typeof body === "string") request.body = Buffer.from(body);
|
|
7156
|
+
else if (body instanceof ArrayBuffer) request.body = Buffer.from(new Uint8Array(body));
|
|
7157
|
+
else request.body = Buffer.from(body);
|
|
7158
|
+
}
|
|
7159
|
+
return request;
|
|
7160
|
+
}
|
|
7161
|
+
|
|
7162
|
+
// src/cloud-client.ts
|
|
7163
|
+
init_models();
|
|
7164
|
+
init_sandbox_image();
|
|
7165
|
+
var CloudClient = class _CloudClient {
|
|
7166
|
+
transport;
|
|
7167
|
+
apiUrl;
|
|
7168
|
+
apiKey;
|
|
7169
|
+
organizationId;
|
|
7170
|
+
projectId;
|
|
7171
|
+
namespace;
|
|
7172
|
+
constructor(options) {
|
|
7173
|
+
this.apiUrl = options?.apiUrl ?? API_URL;
|
|
7174
|
+
this.apiKey = options?.apiKey ?? API_KEY;
|
|
7175
|
+
this.organizationId = options?.organizationId;
|
|
7176
|
+
this.projectId = options?.projectId;
|
|
7177
|
+
this.namespace = options?.namespace ?? NAMESPACE;
|
|
7178
|
+
this.transport = new NativeCloudTransport({
|
|
7179
|
+
baseUrl: options?.apiUrl ?? API_URL,
|
|
7180
|
+
apiKey: options?.apiKey ?? API_KEY,
|
|
7181
|
+
organizationId: this.organizationId,
|
|
7182
|
+
projectId: this.projectId,
|
|
7183
|
+
maxRetries: options?.maxRetries ?? MAX_RETRIES,
|
|
7184
|
+
retryBackoffMs: options?.retryBackoffMs ?? RETRY_BACKOFF_MS,
|
|
7185
|
+
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
7186
|
+
userAgent: `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
7187
|
+
});
|
|
7188
|
+
}
|
|
7189
|
+
static forCloud(options) {
|
|
7190
|
+
return new _CloudClient(options);
|
|
7191
|
+
}
|
|
7192
|
+
close() {
|
|
7193
|
+
this.transport.close();
|
|
7194
|
+
}
|
|
7195
|
+
async upsertApplication(manifest, codeZip, upgradeRunningRequests = false) {
|
|
7196
|
+
const applicationManifest = { ...manifest };
|
|
7197
|
+
let publicEndpointId = publicEndpointIdFromManifest(applicationManifest);
|
|
7198
|
+
if (applicationAllowsUnauthenticatedRequests(applicationManifest) && publicEndpointId === void 0) {
|
|
7199
|
+
const applicationName = applicationManifest.name;
|
|
7200
|
+
if (typeof applicationName === "string" && applicationName.length > 0) {
|
|
7201
|
+
publicEndpointId = await this.existingApplicationPublicEndpointId(applicationName);
|
|
7202
|
+
}
|
|
7203
|
+
publicEndpointId ??= generatePublicEndpointId();
|
|
7204
|
+
}
|
|
7205
|
+
if (publicEndpointId !== void 0) {
|
|
7206
|
+
applicationManifest.public_endpoint_id = publicEndpointId;
|
|
7207
|
+
delete applicationManifest.publicEndpointId;
|
|
7208
|
+
}
|
|
7209
|
+
const form = new FormData();
|
|
7210
|
+
form.append(
|
|
7211
|
+
"code",
|
|
7212
|
+
new Blob([toBlobPart(codeZip)], { type: "application/zip" }),
|
|
7213
|
+
"code.zip"
|
|
7214
|
+
);
|
|
7215
|
+
form.append("code_content_type", "application/zip");
|
|
7216
|
+
form.append("application", JSON.stringify(applicationManifest));
|
|
7217
|
+
form.append(
|
|
7218
|
+
"upgrade_requests_to_latest_code",
|
|
7219
|
+
String(upgradeRunningRequests)
|
|
7220
|
+
);
|
|
7221
|
+
await this.transport.requestResponse("POST", this.namespacePath("applications"), {
|
|
7222
|
+
body: form
|
|
7223
|
+
});
|
|
7224
|
+
}
|
|
7225
|
+
async deleteApplication(applicationName) {
|
|
7226
|
+
await this.transport.requestResponse(
|
|
7227
|
+
"DELETE",
|
|
7228
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
7229
|
+
);
|
|
7230
|
+
}
|
|
7231
|
+
/**
|
|
7232
|
+
* Delete a registered sandbox image by name or id through the merged
|
|
7233
|
+
* catalog, with this client's credentials: an `image_` id or a name the
|
|
7234
|
+
* Image Service knows deletes a CAS image, a `sandbox_template_` id or a
|
|
7235
|
+
* name registered only in the platform registry deletes a legacy image.
|
|
7236
|
+
* Rejects when neither catalog knows the reference. The same semantics
|
|
7237
|
+
* and accepted differences as the module-level `deleteSandboxImage`.
|
|
7238
|
+
*/
|
|
7239
|
+
async deleteSandboxImage(imageName) {
|
|
7240
|
+
await deleteSandboxImageWithCredentials(this.catalogCredentials(), imageName);
|
|
7241
|
+
}
|
|
7242
|
+
/**
|
|
7243
|
+
* Look up a registered sandbox image by name or id through the merged
|
|
7244
|
+
* catalog, with this client's credentials. Returns the image in the
|
|
7245
|
+
* sandbox-template shape, or `null` when neither the Image Service nor the
|
|
7246
|
+
* platform registry knows the reference. An explicit organization/project
|
|
7247
|
+
* scope (the client's, or the call's override) addresses that project's
|
|
7248
|
+
* routes directly, as before; without one the key's own scope applies.
|
|
7249
|
+
*/
|
|
7250
|
+
async findSandboxImageByName(imageName, options) {
|
|
7251
|
+
return findSandboxImageByNameWithCredentials(
|
|
7252
|
+
this.catalogCredentials(options),
|
|
7253
|
+
imageName
|
|
7254
|
+
);
|
|
7255
|
+
}
|
|
7256
|
+
/**
|
|
7257
|
+
* List every registered sandbox image of the project (CAS and legacy, in
|
|
7258
|
+
* the sandbox-template shape, newest first) through the merged catalog,
|
|
7259
|
+
* with this client's credentials. An explicit organization/project scope
|
|
7260
|
+
* (the client's, or the call's override) addresses that project's routes
|
|
7261
|
+
* directly, as before; without one the key's own scope applies.
|
|
7262
|
+
*/
|
|
7263
|
+
async listSandboxImages(options) {
|
|
7264
|
+
return listSandboxImagesWithCredentials(this.catalogCredentials(options));
|
|
7265
|
+
}
|
|
7266
|
+
catalogCredentials(options) {
|
|
7267
|
+
return {
|
|
7268
|
+
apiUrl: this.apiUrl,
|
|
7269
|
+
apiKey: this.apiKey,
|
|
7270
|
+
organizationId: options?.organizationId ?? this.organizationId,
|
|
7271
|
+
projectId: options?.projectId ?? this.projectId
|
|
7272
|
+
};
|
|
7273
|
+
}
|
|
7274
|
+
async applications() {
|
|
7275
|
+
const raw = await this.transport.requestJson(
|
|
7276
|
+
"GET",
|
|
7277
|
+
this.namespacePath("applications")
|
|
7278
|
+
);
|
|
7279
|
+
return (raw.applications ?? []).map(
|
|
7280
|
+
(application) => fromSnakeKeys(application)
|
|
7281
|
+
);
|
|
7282
|
+
}
|
|
7283
|
+
async applicationManifest(applicationName) {
|
|
7284
|
+
const raw = await this.transport.requestJson(
|
|
7285
|
+
"GET",
|
|
7286
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
7287
|
+
);
|
|
7288
|
+
return fromSnakeKeys(raw);
|
|
7289
|
+
}
|
|
7290
|
+
async runRequest(applicationName, inputs = []) {
|
|
7291
|
+
const path4 = this.namespacePath(
|
|
7292
|
+
`applications/${encodeURIComponent(applicationName)}`
|
|
7293
|
+
);
|
|
7294
|
+
const response = inputs.length === 0 ? await this.transport.requestResponse("POST", path4, {
|
|
7295
|
+
body: new Uint8Array(),
|
|
7296
|
+
headers: { Accept: "application/json" }
|
|
7297
|
+
}) : inputs.length === 1 && inputs[0].name === "0" ? await this.transport.requestResponse("POST", path4, {
|
|
7298
|
+
body: toRequestBody(inputs[0].data),
|
|
7299
|
+
headers: {
|
|
7300
|
+
Accept: "application/json",
|
|
7301
|
+
"Content-Type": inputs[0].contentType
|
|
7302
|
+
}
|
|
7303
|
+
}) : await this.runMultipartRequest(path4, inputs);
|
|
7304
|
+
const body = await parseJsonResponse(response);
|
|
7305
|
+
const requestId = body?.request_id;
|
|
7306
|
+
if (!requestId) {
|
|
7307
|
+
throw new Error("missing request_id in run request response body");
|
|
7308
|
+
}
|
|
7309
|
+
return requestId;
|
|
7310
|
+
}
|
|
7311
|
+
async waitOnRequestCompletion(applicationName, requestId) {
|
|
7312
|
+
const stream = this.transport.stream(
|
|
7313
|
+
"GET",
|
|
7314
|
+
this.namespacePath(
|
|
7315
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/progress`
|
|
7316
|
+
)
|
|
7317
|
+
);
|
|
7318
|
+
for await (const event of stream) {
|
|
7319
|
+
if (Object.prototype.hasOwnProperty.call(event, "RequestFinished")) {
|
|
7320
|
+
return;
|
|
7321
|
+
}
|
|
7322
|
+
}
|
|
7323
|
+
throw new Error("progress stream ended before request completion");
|
|
7324
|
+
}
|
|
7325
|
+
async requestMetadata(applicationName, requestId) {
|
|
7326
|
+
const raw = await this.transport.requestJson(
|
|
7327
|
+
"GET",
|
|
7328
|
+
this.namespacePath(
|
|
7329
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}`
|
|
7330
|
+
)
|
|
7331
|
+
);
|
|
7332
|
+
return fromSnakeKeys(raw);
|
|
7333
|
+
}
|
|
7334
|
+
async requestOutput(applicationName, requestId) {
|
|
7335
|
+
const response = await this.transport.requestResponse(
|
|
7336
|
+
"GET",
|
|
7337
|
+
this.namespacePath(
|
|
7338
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/output`
|
|
7339
|
+
)
|
|
7340
|
+
);
|
|
7341
|
+
const serializedValue = new Uint8Array(await response.arrayBuffer());
|
|
7342
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
7343
|
+
return {
|
|
7344
|
+
serializedValue,
|
|
7345
|
+
contentType
|
|
7346
|
+
};
|
|
7347
|
+
}
|
|
7348
|
+
async listSecrets(options) {
|
|
7349
|
+
const base = this.secretCollectionPath(
|
|
7350
|
+
options?.organizationId,
|
|
7351
|
+
options?.projectId
|
|
7352
|
+
);
|
|
7353
|
+
const raw = await this.transport.requestJson("GET", base);
|
|
7354
|
+
const pageSize = Math.max(0, options?.pageSize ?? 100);
|
|
7355
|
+
return Object.assign(
|
|
7356
|
+
{
|
|
7357
|
+
items: raw.slice(0, pageSize).map(secretFromMetadata),
|
|
7358
|
+
pagination: { total: raw.length }
|
|
7359
|
+
},
|
|
7360
|
+
{ traceId: raw.traceId }
|
|
7361
|
+
);
|
|
7362
|
+
}
|
|
7363
|
+
async getSecret(secretId, options) {
|
|
7364
|
+
const base = this.secretCollectionPath(
|
|
7365
|
+
options?.organizationId,
|
|
7366
|
+
options?.projectId
|
|
7367
|
+
);
|
|
7368
|
+
const raw = await this.transport.requestJson(
|
|
7369
|
+
"GET",
|
|
7370
|
+
`${base}/${encodeURIComponent(secretId)}`
|
|
7371
|
+
);
|
|
7372
|
+
return Object.assign(secretFromMetadata(raw), { traceId: raw.traceId });
|
|
7373
|
+
}
|
|
7374
|
+
async upsertSecrets(secrets, options) {
|
|
7375
|
+
const base = this.secretCollectionPath(
|
|
7376
|
+
options?.organizationId,
|
|
7377
|
+
options?.projectId
|
|
7378
|
+
);
|
|
7379
|
+
if (Array.isArray(secrets)) {
|
|
7380
|
+
const results = [];
|
|
7381
|
+
for (const secret of secrets) {
|
|
7382
|
+
results.push(await this.upsertSecret(base, secret));
|
|
7383
|
+
}
|
|
7384
|
+
return results;
|
|
7385
|
+
}
|
|
7386
|
+
return this.upsertSecret(base, secrets);
|
|
7387
|
+
}
|
|
7388
|
+
async deleteSecret(secretId, options) {
|
|
7389
|
+
const base = this.secretCollectionPath(
|
|
7390
|
+
options?.organizationId,
|
|
7391
|
+
options?.projectId
|
|
7392
|
+
);
|
|
7393
|
+
await this.transport.requestResponse(
|
|
7394
|
+
"DELETE",
|
|
7395
|
+
`${base}/${encodeURIComponent(secretId)}`
|
|
7396
|
+
);
|
|
7397
|
+
}
|
|
7398
|
+
async upsertSecret(base, secret) {
|
|
7399
|
+
let response = await this.transport.requestResponse("POST", base, {
|
|
7400
|
+
json: secret,
|
|
7401
|
+
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() },
|
|
7402
|
+
statusOnlyCodes: /* @__PURE__ */ new Set([409])
|
|
7403
|
+
});
|
|
7404
|
+
if (response.status === 409) {
|
|
7405
|
+
const prefix = base.slice(0, -"/secrets".length);
|
|
7406
|
+
const existing = await this.transport.requestJson(
|
|
7407
|
+
"GET",
|
|
7408
|
+
`${prefix}/secret-names/${encodeURIComponent(secret.name)}`
|
|
7409
|
+
);
|
|
7410
|
+
response = await this.transport.requestResponse(
|
|
7411
|
+
"POST",
|
|
7412
|
+
`${base}/${encodeURIComponent(existing.id)}/versions`,
|
|
7413
|
+
{
|
|
7414
|
+
json: { value: secret.value },
|
|
7415
|
+
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() }
|
|
7416
|
+
}
|
|
7417
|
+
);
|
|
7418
|
+
}
|
|
7419
|
+
const metadata = await parseJsonResponse(response);
|
|
7420
|
+
return Object.assign(secretFromMetadata(metadata), {
|
|
7421
|
+
traceId: response.traceId
|
|
7422
|
+
});
|
|
7423
|
+
}
|
|
7424
|
+
async startImageBuild(buildServicePath, request) {
|
|
7425
|
+
const form = new FormData();
|
|
7426
|
+
form.append("graph_name", request.applicationName);
|
|
7427
|
+
form.append("graph_version", request.applicationVersion);
|
|
7428
|
+
form.append("graph_function_name", request.functionName);
|
|
7429
|
+
form.append("image_name", request.imageName);
|
|
7430
|
+
form.append("image_id", request.imageId);
|
|
7431
|
+
form.append(
|
|
7432
|
+
"context",
|
|
7433
|
+
new Blob([toBlobPart(request.buildContext)]),
|
|
7434
|
+
"context.tar.gz"
|
|
7435
|
+
);
|
|
7436
|
+
const response = await this.transport.requestResponse(
|
|
7437
|
+
"PUT",
|
|
7438
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds`,
|
|
7439
|
+
{ body: form }
|
|
7440
|
+
);
|
|
7441
|
+
const raw = await parseJsonResponse(response);
|
|
7442
|
+
return fromSnakeKeys(raw);
|
|
7443
|
+
}
|
|
7444
|
+
async createApplicationBuild(buildServicePath, request, imageContexts) {
|
|
7445
|
+
const form = createApplicationBuildForm(request, imageContexts);
|
|
7446
|
+
const response = await this.transport.requestResponse(
|
|
7447
|
+
"POST",
|
|
7448
|
+
trimTrailingSlashes2(buildServicePath),
|
|
7449
|
+
{ body: form }
|
|
7450
|
+
);
|
|
7451
|
+
const raw = await parseJsonResponse(response);
|
|
7452
|
+
return fromSnakeKeys(raw);
|
|
7453
|
+
}
|
|
7454
|
+
async applicationBuildInfo(buildServicePath, applicationBuildId) {
|
|
7455
|
+
const raw = await this.transport.requestJson(
|
|
7456
|
+
"GET",
|
|
7457
|
+
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}`
|
|
7458
|
+
);
|
|
7459
|
+
return fromSnakeKeys(raw);
|
|
7460
|
+
}
|
|
7461
|
+
async cancelApplicationBuild(buildServicePath, applicationBuildId) {
|
|
7462
|
+
const raw = await this.transport.requestJson(
|
|
7463
|
+
"POST",
|
|
7464
|
+
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}/cancel`
|
|
7465
|
+
);
|
|
7466
|
+
return fromSnakeKeys(raw);
|
|
7467
|
+
}
|
|
7468
|
+
async buildInfo(buildServicePath, buildId) {
|
|
7469
|
+
const raw = await this.transport.requestJson(
|
|
7470
|
+
"GET",
|
|
7471
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}`
|
|
7472
|
+
);
|
|
7473
|
+
return fromSnakeKeys(raw);
|
|
7474
|
+
}
|
|
7475
|
+
async cancelBuild(buildServicePath, buildId) {
|
|
7476
|
+
await this.transport.requestResponse(
|
|
7477
|
+
"POST",
|
|
7478
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/cancel`
|
|
7479
|
+
);
|
|
7480
|
+
}
|
|
7481
|
+
async *streamBuildLogs(buildServicePath, buildId, signal) {
|
|
7482
|
+
const stream = this.transport.stream(
|
|
7483
|
+
"GET",
|
|
7484
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/logs`,
|
|
7485
|
+
signal
|
|
7486
|
+
);
|
|
7487
|
+
for await (const event of stream) {
|
|
7488
|
+
yield fromSnakeKeys(event);
|
|
7489
|
+
}
|
|
7490
|
+
}
|
|
7491
|
+
async runMultipartRequest(path4, inputs) {
|
|
7492
|
+
const form = new FormData();
|
|
7493
|
+
for (const input of inputs) {
|
|
7494
|
+
form.append(
|
|
7495
|
+
input.name,
|
|
7496
|
+
new Blob([toBlobPart(input.data)], { type: input.contentType }),
|
|
7497
|
+
input.name
|
|
7498
|
+
);
|
|
7499
|
+
}
|
|
7500
|
+
return this.transport.requestResponse("POST", path4, {
|
|
7501
|
+
body: form,
|
|
7502
|
+
headers: { Accept: "application/json" }
|
|
7503
|
+
});
|
|
7504
|
+
}
|
|
7505
|
+
namespacePath(subpath) {
|
|
7506
|
+
return `/v1/namespaces/${encodeURIComponent(this.namespace)}/${subpath.replace(/^\/+/, "")}`;
|
|
7507
|
+
}
|
|
7508
|
+
async existingApplicationPublicEndpointId(applicationName) {
|
|
7509
|
+
const response = await this.transport.requestResponse(
|
|
7510
|
+
"GET",
|
|
7511
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`),
|
|
7512
|
+
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
7513
|
+
);
|
|
7514
|
+
if (response.status === 404) {
|
|
7515
|
+
return void 0;
|
|
7516
|
+
}
|
|
7517
|
+
const application = await parseJsonResponse(response);
|
|
7518
|
+
return publicEndpointIdFromManifest(application);
|
|
7519
|
+
}
|
|
7520
|
+
secretCollectionPath(organizationId, projectId) {
|
|
7521
|
+
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
7522
|
+
const resolvedProjectId = projectId ?? this.projectId;
|
|
7523
|
+
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
7524
|
+
return this.namespacePath("secrets");
|
|
7525
|
+
}
|
|
7526
|
+
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
7527
|
+
throw new Error("organizationId and projectId must be provided together");
|
|
7528
|
+
}
|
|
7529
|
+
return this.namespacePath("secrets");
|
|
7530
|
+
}
|
|
7531
|
+
};
|
|
7532
|
+
function secretFromMetadata(metadata) {
|
|
7533
|
+
return {
|
|
7534
|
+
id: metadata.id,
|
|
7535
|
+
name: metadata.name,
|
|
7536
|
+
createdAt: new Date(metadata.created_at_ms)
|
|
7537
|
+
};
|
|
7538
|
+
}
|
|
7539
|
+
var UNAUTHENTICATED_REQUESTS = "unauthenticated_requests";
|
|
7540
|
+
function applicationAllowsUnauthenticatedRequests(manifest) {
|
|
7541
|
+
return Array.isArray(manifest.allow) && manifest.allow.includes(UNAUTHENTICATED_REQUESTS);
|
|
7542
|
+
}
|
|
7543
|
+
function publicEndpointIdFromManifest(manifest) {
|
|
7544
|
+
for (const key of ["public_endpoint_id", "publicEndpointId"]) {
|
|
7545
|
+
const value = manifest[key];
|
|
7546
|
+
if (typeof value === "string" && value.length > 0) {
|
|
7547
|
+
return value;
|
|
7548
|
+
}
|
|
7549
|
+
}
|
|
7550
|
+
return void 0;
|
|
7551
|
+
}
|
|
7552
|
+
function generatePublicEndpointId() {
|
|
7553
|
+
return `endpoint_${(0, import_nanoid.nanoid)()}`;
|
|
7554
|
+
}
|
|
7555
|
+
function createApplicationBuildForm(request, imageContexts) {
|
|
7556
|
+
const contextsByPartName = /* @__PURE__ */ new Map();
|
|
7557
|
+
for (const context of imageContexts) {
|
|
7558
|
+
if (contextsByPartName.has(context.contextTarPartName)) {
|
|
7559
|
+
throw new Error(
|
|
7560
|
+
`duplicate image context part name '${context.contextTarPartName}'`
|
|
7561
|
+
);
|
|
7562
|
+
}
|
|
7563
|
+
contextsByPartName.set(context.contextTarPartName, context);
|
|
7564
|
+
}
|
|
7565
|
+
const form = new FormData();
|
|
7566
|
+
form.append(
|
|
7567
|
+
"app_version",
|
|
7568
|
+
new Blob([JSON.stringify(request)], { type: "application/json" }),
|
|
7569
|
+
"app_version"
|
|
7570
|
+
);
|
|
7571
|
+
for (const image of request.images) {
|
|
7572
|
+
const context = contextsByPartName.get(image.contextTarPartName);
|
|
7573
|
+
if (!context) {
|
|
7574
|
+
throw new Error(
|
|
7575
|
+
`missing image context for part '${image.contextTarPartName}'`
|
|
7576
|
+
);
|
|
7577
|
+
}
|
|
7578
|
+
form.append(
|
|
7579
|
+
image.contextTarPartName,
|
|
7580
|
+
new Blob([toBlobPart(context.contextTarGz)]),
|
|
7581
|
+
`${image.contextTarPartName}.tar.gz`
|
|
7582
|
+
);
|
|
7583
|
+
}
|
|
7584
|
+
for (const context of imageContexts) {
|
|
7585
|
+
if (!request.images.some((image) => image.contextTarPartName === context.contextTarPartName)) {
|
|
7586
|
+
throw new Error(
|
|
7587
|
+
`unexpected image context for part '${context.contextTarPartName}'`
|
|
7588
|
+
);
|
|
7589
|
+
}
|
|
7590
|
+
}
|
|
7591
|
+
return form;
|
|
7592
|
+
}
|
|
7593
|
+
function trimTrailingSlashes2(value) {
|
|
7594
|
+
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
7595
|
+
}
|
|
7596
|
+
function toBlobPart(data) {
|
|
7597
|
+
if (typeof data === "string" || data instanceof Blob) {
|
|
7598
|
+
return data;
|
|
7599
|
+
}
|
|
7600
|
+
if (data instanceof Uint8Array) {
|
|
7601
|
+
return Uint8Array.from(data).buffer;
|
|
7602
|
+
}
|
|
7603
|
+
return data;
|
|
7604
|
+
}
|
|
7605
|
+
function toRequestBody(data) {
|
|
7606
|
+
return toBlobPart(data);
|
|
7607
|
+
}
|
|
7608
|
+
async function parseJsonResponse(response) {
|
|
7609
|
+
const text = await response.text();
|
|
7610
|
+
if (!text) {
|
|
7611
|
+
return void 0;
|
|
7612
|
+
}
|
|
7613
|
+
return JSON.parse(text);
|
|
7614
|
+
}
|
|
7012
7615
|
|
|
7013
7616
|
// src/api-client.ts
|
|
7014
7617
|
init_cjs_shims();
|
|
7015
|
-
init_cloud_client();
|
|
7016
7618
|
|
|
7017
7619
|
// src/filesystem.ts
|
|
7018
7620
|
init_cjs_shims();
|
|
@@ -7021,21 +7623,21 @@ var import_node_crypto2 = require("crypto");
|
|
|
7021
7623
|
// src/mount-cli.ts
|
|
7022
7624
|
init_cjs_shims();
|
|
7023
7625
|
var import_node_child_process = require("child_process");
|
|
7024
|
-
var
|
|
7025
|
-
var
|
|
7026
|
-
var
|
|
7027
|
-
var
|
|
7626
|
+
var import_node_fs3 = require("fs");
|
|
7627
|
+
var import_node_os3 = require("os");
|
|
7628
|
+
var import_node_path4 = require("path");
|
|
7629
|
+
var import_node_util2 = require("util");
|
|
7028
7630
|
|
|
7029
7631
|
// src/filesystem-models.ts
|
|
7030
7632
|
init_cjs_shims();
|
|
7031
7633
|
var GIT_MODE_DIR = 16384;
|
|
7032
7634
|
var GIT_MODE_SYMLINK = 40960;
|
|
7033
|
-
function trimSlashes(
|
|
7635
|
+
function trimSlashes(path4) {
|
|
7034
7636
|
let start = 0;
|
|
7035
|
-
let end =
|
|
7036
|
-
while (start < end &&
|
|
7037
|
-
while (end > start &&
|
|
7038
|
-
return
|
|
7637
|
+
let end = path4.length;
|
|
7638
|
+
while (start < end && path4.charCodeAt(start) === 47) start += 1;
|
|
7639
|
+
while (end > start && path4.charCodeAt(end - 1) === 47) end -= 1;
|
|
7640
|
+
return path4.slice(start, end);
|
|
7039
7641
|
}
|
|
7040
7642
|
function fileEntryFromWire(entry, dirPath) {
|
|
7041
7643
|
const mode = entry.mode ?? 33188;
|
|
@@ -7053,9 +7655,9 @@ function fileEntryFromWire(entry, dirPath) {
|
|
|
7053
7655
|
}
|
|
7054
7656
|
function mountStatusFromRaw(raw, localPath) {
|
|
7055
7657
|
const mounted = "mounted" in raw ? Boolean(raw.mounted) : "active" in raw ? Boolean(raw.active) : true;
|
|
7056
|
-
const
|
|
7658
|
+
const path4 = String(raw.path || raw.mount_path || localPath || "");
|
|
7057
7659
|
const filesystem = raw.filesystem || raw.file_system || raw.repository || null;
|
|
7058
|
-
return { path:
|
|
7660
|
+
return { path: path4, filesystem, mounted, raw };
|
|
7059
7661
|
}
|
|
7060
7662
|
var FilesystemError = class extends Error {
|
|
7061
7663
|
constructor(message) {
|
|
@@ -7074,11 +7676,11 @@ var FilesystemNotFoundError = class extends FilesystemError {
|
|
|
7074
7676
|
var FileNotFoundInFilesystemError = class extends FilesystemError {
|
|
7075
7677
|
filesystem;
|
|
7076
7678
|
path;
|
|
7077
|
-
constructor(filesystem,
|
|
7078
|
-
super(`File not found in filesystem ${filesystem}: ${
|
|
7679
|
+
constructor(filesystem, path4) {
|
|
7680
|
+
super(`File not found in filesystem ${filesystem}: ${path4}`);
|
|
7079
7681
|
this.name = "FileNotFoundInFilesystemError";
|
|
7080
7682
|
this.filesystem = filesystem;
|
|
7081
|
-
this.path =
|
|
7683
|
+
this.path = path4;
|
|
7082
7684
|
}
|
|
7083
7685
|
};
|
|
7084
7686
|
var FilesystemAPIError = class extends FilesystemError {
|
|
@@ -7113,7 +7715,7 @@ var CliNotFoundError = class extends MountError {
|
|
|
7113
7715
|
};
|
|
7114
7716
|
|
|
7115
7717
|
// src/mount-cli.ts
|
|
7116
|
-
var execFileAsync = (0,
|
|
7718
|
+
var execFileAsync = (0, import_node_util2.promisify)(import_node_child_process.execFile);
|
|
7117
7719
|
var MountCli = class {
|
|
7118
7720
|
constructor(command, envOverrides) {
|
|
7119
7721
|
this.command = command;
|
|
@@ -7124,9 +7726,9 @@ var MountCli = class {
|
|
|
7124
7726
|
const candidates = [];
|
|
7125
7727
|
if (process.env.TENSORLAKE_CLI) candidates.push(process.env.TENSORLAKE_CLI);
|
|
7126
7728
|
candidates.push("tl");
|
|
7127
|
-
const installed = (0,
|
|
7729
|
+
const installed = (0, import_node_path4.join)((0, import_node_os3.homedir)(), ".tensorlake", "bin", "tl");
|
|
7128
7730
|
try {
|
|
7129
|
-
(0,
|
|
7731
|
+
(0, import_node_fs3.accessSync)(installed, import_node_fs3.constants.F_OK);
|
|
7130
7732
|
candidates.push(installed);
|
|
7131
7733
|
} catch {
|
|
7132
7734
|
}
|
|
@@ -7432,8 +8034,8 @@ var Filesystem = class {
|
|
|
7432
8034
|
}
|
|
7433
8035
|
// -- writes -------------------------------------------------------------------
|
|
7434
8036
|
/** Write one file. Returns the snapshot (version) the write produced. */
|
|
7435
|
-
async writeFile(
|
|
7436
|
-
return await this.writeFiles(/* @__PURE__ */ new Map([[
|
|
8037
|
+
async writeFile(path4, data, message) {
|
|
8038
|
+
return await this.writeFiles(/* @__PURE__ */ new Map([[path4, data]]), message);
|
|
7437
8039
|
}
|
|
7438
8040
|
/** Write several files (and/or delete paths) in one atomic snapshot. */
|
|
7439
8041
|
async writeFiles(files, message, deletes = []) {
|
|
@@ -7441,8 +8043,8 @@ var Filesystem = class {
|
|
|
7441
8043
|
if (entries.length === 0 && deletes.length === 0) {
|
|
7442
8044
|
throw new FilesystemError("nothing to write: no files or deletions given");
|
|
7443
8045
|
}
|
|
7444
|
-
const writes = entries.map(([
|
|
7445
|
-
path:
|
|
8046
|
+
const writes = entries.map(([path4, data]) => ({
|
|
8047
|
+
path: path4,
|
|
7446
8048
|
content: toBuffer(data)
|
|
7447
8049
|
}));
|
|
7448
8050
|
const resolvedMessage = message || `write ${writes.length} file(s) via SDK`;
|
|
@@ -7458,9 +8060,9 @@ var Filesystem = class {
|
|
|
7458
8060
|
* Stream one local file directly to object storage in bounded parts.
|
|
7459
8061
|
* This is the memory-bounded API for multi-GiB files.
|
|
7460
8062
|
*/
|
|
7461
|
-
async writeFileFromPath(
|
|
8063
|
+
async writeFileFromPath(path4, localPath, message) {
|
|
7462
8064
|
return await this.writeFilesFromPaths(
|
|
7463
|
-
/* @__PURE__ */ new Map([[
|
|
8065
|
+
/* @__PURE__ */ new Map([[path4, localPath]]),
|
|
7464
8066
|
message
|
|
7465
8067
|
);
|
|
7466
8068
|
}
|
|
@@ -7473,7 +8075,7 @@ var Filesystem = class {
|
|
|
7473
8075
|
if (entries.length === 0) {
|
|
7474
8076
|
throw new FilesystemError("nothing to write: no local files given");
|
|
7475
8077
|
}
|
|
7476
|
-
const writes = entries.map(([
|
|
8078
|
+
const writes = entries.map(([path4, localPath]) => ({ path: path4, localPath }));
|
|
7477
8079
|
const resolvedMessage = message || `write ${writes.length} local file(s) via SDK`;
|
|
7478
8080
|
const branch = await this.branch();
|
|
7479
8081
|
const traced = await callNative2(
|
|
@@ -7550,11 +8152,11 @@ var Filesystem = class {
|
|
|
7550
8152
|
};
|
|
7551
8153
|
}
|
|
7552
8154
|
/** Delete one file. Returns the durable version the deletion produced. */
|
|
7553
|
-
async deleteFile(
|
|
8155
|
+
async deleteFile(path4, message) {
|
|
7554
8156
|
return await this.writeFiles(
|
|
7555
8157
|
/* @__PURE__ */ new Map(),
|
|
7556
|
-
message || `delete ${
|
|
7557
|
-
[
|
|
8158
|
+
message || `delete ${path4} via SDK`,
|
|
8159
|
+
[path4]
|
|
7558
8160
|
);
|
|
7559
8161
|
}
|
|
7560
8162
|
/**
|
|
@@ -7605,15 +8207,15 @@ var Filesystem = class {
|
|
|
7605
8207
|
* Read a file's bytes at `version` (the current `main` head or a retained
|
|
7606
8208
|
* snapshot id; defaults to the filesystem's current head).
|
|
7607
8209
|
*/
|
|
7608
|
-
async readFile(
|
|
7609
|
-
return (await this.readFileWithMetadata(
|
|
8210
|
+
async readFile(path4, version) {
|
|
8211
|
+
return (await this.readFileWithMetadata(path4, { version })).data;
|
|
7610
8212
|
}
|
|
7611
8213
|
/**
|
|
7612
8214
|
* Read bytes and immutable metadata in one request. A range is executed by
|
|
7613
8215
|
* Artifact Storage, so callers never download the unrequested remainder.
|
|
7614
8216
|
*/
|
|
7615
|
-
async readFileWithMetadata(
|
|
7616
|
-
if (trimSlashes(
|
|
8217
|
+
async readFileWithMetadata(path4, options = {}) {
|
|
8218
|
+
if (trimSlashes(path4) === "") {
|
|
7617
8219
|
throw new FilesystemError("file path must not be empty");
|
|
7618
8220
|
}
|
|
7619
8221
|
const range = options.range;
|
|
@@ -7626,12 +8228,12 @@ var Filesystem = class {
|
|
|
7626
8228
|
const traced = await callNative2(
|
|
7627
8229
|
() => this.native.readFilesystemFile(
|
|
7628
8230
|
this.name,
|
|
7629
|
-
|
|
8231
|
+
path4,
|
|
7630
8232
|
resolvedVersion,
|
|
7631
8233
|
range?.offset,
|
|
7632
8234
|
range?.length
|
|
7633
8235
|
),
|
|
7634
|
-
new FileNotFoundInFilesystemError(this.name,
|
|
8236
|
+
new FileNotFoundInFilesystemError(this.name, path4)
|
|
7635
8237
|
);
|
|
7636
8238
|
const fullSize = traced.fullSize;
|
|
7637
8239
|
if (!traced.contentId || fullSize === void 0 || !Number.isSafeInteger(fullSize) || fullSize < 0 || traced.data.byteLength > fullSize) {
|
|
@@ -7646,9 +8248,9 @@ var Filesystem = class {
|
|
|
7646
8248
|
};
|
|
7647
8249
|
}
|
|
7648
8250
|
/** Read a file as UTF-8 text at `version`. Throws on non-UTF-8 content. */
|
|
7649
|
-
async readText(
|
|
8251
|
+
async readText(path4, version) {
|
|
7650
8252
|
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
|
7651
|
-
await this.readFile(
|
|
8253
|
+
await this.readFile(path4, version)
|
|
7652
8254
|
);
|
|
7653
8255
|
}
|
|
7654
8256
|
/** List one directory (non-recursive) at `version`. */
|
|
@@ -7711,11 +8313,11 @@ var FilesystemMount = class {
|
|
|
7711
8313
|
path;
|
|
7712
8314
|
readonly;
|
|
7713
8315
|
/** @internal — obtain instances via `FilesystemClient.mount()`. */
|
|
7714
|
-
constructor(client, cli, filesystem,
|
|
8316
|
+
constructor(client, cli, filesystem, path4, readonly) {
|
|
7715
8317
|
this.client = client;
|
|
7716
8318
|
this.cli = cli;
|
|
7717
8319
|
this.filesystem = filesystem;
|
|
7718
|
-
this.path =
|
|
8320
|
+
this.path = path4;
|
|
7719
8321
|
this.readonly = readonly;
|
|
7720
8322
|
}
|
|
7721
8323
|
/** Flush pending local changes into a durable snapshot. */
|
|
@@ -7733,6 +8335,7 @@ var FilesystemMount = class {
|
|
|
7733
8335
|
};
|
|
7734
8336
|
|
|
7735
8337
|
// src/api-client.ts
|
|
8338
|
+
init_sandbox_image();
|
|
7736
8339
|
init_errors();
|
|
7737
8340
|
var APIClient = class {
|
|
7738
8341
|
cloudClient;
|
|
@@ -7760,7 +8363,7 @@ var APIClient = class {
|
|
|
7760
8363
|
await this.cloudClient.deleteApplication(applicationName);
|
|
7761
8364
|
}
|
|
7762
8365
|
async deleteSandboxImage(imageName) {
|
|
7763
|
-
await this.
|
|
8366
|
+
await deleteSandboxImageWithCredentials(this.filesystemOptions, imageName);
|
|
7764
8367
|
}
|
|
7765
8368
|
async createFileSystem(name, description, options) {
|
|
7766
8369
|
const filesystem = await new FilesystemClient(this.filesystemOptions).create(
|
|
@@ -7830,7 +8433,7 @@ init_sandbox_image();
|
|
|
7830
8433
|
|
|
7831
8434
|
// src/repository-mount.ts
|
|
7832
8435
|
init_cjs_shims();
|
|
7833
|
-
var
|
|
8436
|
+
var import_node_path5 = require("path");
|
|
7834
8437
|
function requireNonEmpty(value, name) {
|
|
7835
8438
|
if (typeof value !== "string" || value.length === 0) {
|
|
7836
8439
|
throw new TypeError(`${name} must be a non-empty string`);
|
|
@@ -7847,28 +8450,28 @@ var GitCli = class extends MountCli {
|
|
|
7847
8450
|
if (options.readOnly && (options.publish || options.workspace !== void 0) || options.publish && options.workspace !== void 0) {
|
|
7848
8451
|
throw new TypeError("readOnly, publish, and workspace are mutually exclusive");
|
|
7849
8452
|
}
|
|
7850
|
-
const
|
|
8453
|
+
const path4 = (0, import_node_path5.resolve)(localPath);
|
|
7851
8454
|
const args = ["mount"];
|
|
7852
8455
|
if (options.readOnly) args.push("--ro");
|
|
7853
8456
|
if (options.publish) args.push("--publish");
|
|
7854
8457
|
if (options.workspace !== void 0) args.push(`--workspace=${options.workspace}`);
|
|
7855
|
-
args.push("--", target,
|
|
8458
|
+
args.push("--", target, path4);
|
|
7856
8459
|
await this.run(args);
|
|
7857
|
-
return new RepositoryMount(this, target,
|
|
8460
|
+
return new RepositoryMount(this, target, path4, options.readOnly ?? false);
|
|
7858
8461
|
}
|
|
7859
8462
|
async unmount(localPath, options = {}) {
|
|
7860
8463
|
requireNonEmpty(localPath, "localPath");
|
|
7861
8464
|
const args = ["unmount"];
|
|
7862
8465
|
if (options.deleteWorkspace) args.push("--delete");
|
|
7863
8466
|
if (options.discard) args.push("--discard");
|
|
7864
|
-
args.push("--", (0,
|
|
8467
|
+
args.push("--", (0, import_node_path5.resolve)(localPath));
|
|
7865
8468
|
await this.run(args);
|
|
7866
8469
|
}
|
|
7867
8470
|
async status(localPath) {
|
|
7868
8471
|
const args = ["status", "--json"];
|
|
7869
8472
|
if (localPath !== void 0) {
|
|
7870
8473
|
requireNonEmpty(localPath, "localPath");
|
|
7871
|
-
args.push("--", (0,
|
|
8474
|
+
args.push("--", (0, import_node_path5.resolve)(localPath));
|
|
7872
8475
|
}
|
|
7873
8476
|
const output = await this.run(args, 6e4);
|
|
7874
8477
|
let raw;
|
|
@@ -7883,7 +8486,7 @@ var GitCli = class extends MountCli {
|
|
|
7883
8486
|
}
|
|
7884
8487
|
const stringField = (key) => typeof raw[key] === "string" ? raw[key] : null;
|
|
7885
8488
|
return {
|
|
7886
|
-
path: stringField("mountpoint") ?? (localPath === void 0 ? "" : (0,
|
|
8489
|
+
path: stringField("mountpoint") ?? (localPath === void 0 ? "" : (0, import_node_path5.resolve)(localPath)),
|
|
7887
8490
|
repository: stringField("repository"),
|
|
7888
8491
|
reference: stringField("reference"),
|
|
7889
8492
|
workspaceId: stringField("workspace"),
|
|
@@ -7892,44 +8495,44 @@ var GitCli = class extends MountCli {
|
|
|
7892
8495
|
raw
|
|
7893
8496
|
};
|
|
7894
8497
|
}
|
|
7895
|
-
async snapshot(
|
|
8498
|
+
async snapshot(path4, message) {
|
|
7896
8499
|
const args = ["snapshot"];
|
|
7897
8500
|
if (message !== void 0) args.push(`--message=${message}`);
|
|
7898
|
-
args.push("--",
|
|
8501
|
+
args.push("--", path4);
|
|
7899
8502
|
await this.run(args);
|
|
7900
8503
|
}
|
|
7901
|
-
async sync(
|
|
7902
|
-
const args = ["sync", "--",
|
|
8504
|
+
async sync(path4, target) {
|
|
8505
|
+
const args = ["sync", "--", path4];
|
|
7903
8506
|
if (target !== void 0) {
|
|
7904
8507
|
requireNonEmpty(target, "target");
|
|
7905
8508
|
args.push(target);
|
|
7906
8509
|
}
|
|
7907
8510
|
await this.run(args);
|
|
7908
8511
|
}
|
|
7909
|
-
async rebase(
|
|
8512
|
+
async rebase(path4, target, failOnConflict) {
|
|
7910
8513
|
requireNonEmpty(target, "target");
|
|
7911
8514
|
const args = ["rebase"];
|
|
7912
8515
|
if (failOnConflict) args.push("--fail-on-conflict");
|
|
7913
|
-
args.push("--",
|
|
8516
|
+
args.push("--", path4, target);
|
|
7914
8517
|
await this.run(args);
|
|
7915
8518
|
}
|
|
7916
|
-
async promote(
|
|
8519
|
+
async promote(path4, branch, merge) {
|
|
7917
8520
|
requireNonEmpty(branch, "branch");
|
|
7918
8521
|
const args = ["promote"];
|
|
7919
8522
|
if (merge) args.push("--merge");
|
|
7920
|
-
args.push("--",
|
|
8523
|
+
args.push("--", path4, branch);
|
|
7921
8524
|
await this.run(args);
|
|
7922
8525
|
}
|
|
7923
|
-
async prefetch(
|
|
7924
|
-
await this.run(["prefetch", "--",
|
|
8526
|
+
async prefetch(path4) {
|
|
8527
|
+
await this.run(["prefetch", "--", path4]);
|
|
7925
8528
|
}
|
|
7926
8529
|
};
|
|
7927
8530
|
var RepositoryMount = class {
|
|
7928
8531
|
/** @internal Obtain instances via RepositoryClient.mount(). */
|
|
7929
|
-
constructor(cli, target,
|
|
8532
|
+
constructor(cli, target, path4, readOnly) {
|
|
7930
8533
|
this.cli = cli;
|
|
7931
8534
|
this.target = target;
|
|
7932
|
-
this.path =
|
|
8535
|
+
this.path = path4;
|
|
7933
8536
|
this.readOnly = readOnly;
|
|
7934
8537
|
}
|
|
7935
8538
|
/** Inspect workspace state, pending changes, and daemon diagnostics. */
|
|
@@ -8164,6 +8767,7 @@ function validateTimeoutMs2(timeoutMs) {
|
|
|
8164
8767
|
|
|
8165
8768
|
// src/index.ts
|
|
8166
8769
|
init_sandbox_image();
|
|
8770
|
+
init_image_builds();
|
|
8167
8771
|
|
|
8168
8772
|
// src/file-system.ts
|
|
8169
8773
|
init_cjs_shims();
|
|
@@ -9547,38 +10151,38 @@ init_cjs_shims();
|
|
|
9547
10151
|
var import_node_crypto4 = require("crypto");
|
|
9548
10152
|
var textEncoder = new TextEncoder();
|
|
9549
10153
|
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
9550
|
-
function assertJSONValue(value,
|
|
10154
|
+
function assertJSONValue(value, path4, seen) {
|
|
9551
10155
|
if (value === null || typeof value === "string" || typeof value === "boolean") return;
|
|
9552
10156
|
if (typeof value === "number") {
|
|
9553
|
-
if (!Number.isFinite(value)) throw new SerializationError(`${
|
|
10157
|
+
if (!Number.isFinite(value)) throw new SerializationError(`${path4} contains a non-finite number`);
|
|
9554
10158
|
return;
|
|
9555
10159
|
}
|
|
9556
10160
|
if (typeof value !== "object") {
|
|
9557
|
-
throw new SerializationError(`${
|
|
10161
|
+
throw new SerializationError(`${path4} contains unsupported ${typeof value}`);
|
|
9558
10162
|
}
|
|
9559
10163
|
if (isFile(value)) {
|
|
9560
|
-
throw new SerializationError(`${
|
|
10164
|
+
throw new SerializationError(`${path4} contains a nested File; File is only supported as a direct value`);
|
|
9561
10165
|
}
|
|
9562
10166
|
if (isHttpBody(value)) {
|
|
9563
10167
|
throw new SerializationError(
|
|
9564
|
-
`${
|
|
10168
|
+
`${path4} contains a nested HttpBody; HttpBody is only supported as a direct value`
|
|
9565
10169
|
);
|
|
9566
10170
|
}
|
|
9567
|
-
if (seen.has(value)) throw new SerializationError(`${
|
|
10171
|
+
if (seen.has(value)) throw new SerializationError(`${path4} contains a cycle`);
|
|
9568
10172
|
if (Object.getPrototypeOf(value) !== Object.prototype && !Array.isArray(value)) {
|
|
9569
|
-
throw new SerializationError(`${
|
|
10173
|
+
throw new SerializationError(`${path4} contains unsupported ${value.constructor?.name ?? "object"}`);
|
|
9570
10174
|
}
|
|
9571
10175
|
seen.add(value);
|
|
9572
10176
|
if (Array.isArray(value)) {
|
|
9573
10177
|
for (let index = 0; index < value.length; index += 1) {
|
|
9574
10178
|
if (!Object.prototype.hasOwnProperty.call(value, index)) {
|
|
9575
|
-
throw new SerializationError(`${
|
|
10179
|
+
throw new SerializationError(`${path4} contains a sparse array entry at index ${index}`);
|
|
9576
10180
|
}
|
|
9577
|
-
assertJSONValue(value[index], `${
|
|
10181
|
+
assertJSONValue(value[index], `${path4}[${index}]`, seen);
|
|
9578
10182
|
}
|
|
9579
10183
|
} else {
|
|
9580
10184
|
for (const [key, item] of Object.entries(value)) {
|
|
9581
|
-
assertJSONValue(item, `${
|
|
10185
|
+
assertJSONValue(item, `${path4}.${key}`, seen);
|
|
9582
10186
|
}
|
|
9583
10187
|
}
|
|
9584
10188
|
seen.delete(value);
|
|
@@ -10028,7 +10632,20 @@ init_models();
|
|
|
10028
10632
|
Headers,
|
|
10029
10633
|
HttpBody,
|
|
10030
10634
|
Image,
|
|
10635
|
+
ImageBuildCancellationOutcome,
|
|
10636
|
+
ImageBuildCancelledError,
|
|
10637
|
+
ImageBuildError,
|
|
10638
|
+
ImageBuildErrorCode,
|
|
10639
|
+
ImageBuildFailedError,
|
|
10640
|
+
ImageBuildHandle,
|
|
10641
|
+
ImageBuildInProgressError,
|
|
10642
|
+
ImageBuildInterruptedError,
|
|
10643
|
+
ImageBuildKind,
|
|
10644
|
+
ImageBuildNotFoundError,
|
|
10031
10645
|
ImageBuildOperationType,
|
|
10646
|
+
ImageBuildPhase,
|
|
10647
|
+
ImageBuildStatus,
|
|
10648
|
+
ImageBuildTimeoutError,
|
|
10032
10649
|
MountError,
|
|
10033
10650
|
OutputMode,
|
|
10034
10651
|
PendingSandbox,
|
|
@@ -10061,12 +10678,14 @@ init_models();
|
|
|
10061
10678
|
TERMINATION_REASON_CANCELLED,
|
|
10062
10679
|
TERMINATION_REASON_NO_CAPACITY,
|
|
10063
10680
|
TcpTunnel,
|
|
10681
|
+
cancelImageBuild,
|
|
10064
10682
|
createFileSystem,
|
|
10065
10683
|
createSandboxImage,
|
|
10066
10684
|
deleteFileSystem,
|
|
10067
10685
|
deleteSandboxImage,
|
|
10068
10686
|
dockerfileContent,
|
|
10069
10687
|
findSandboxImageByName,
|
|
10688
|
+
getImageBuild,
|
|
10070
10689
|
importSandboxImage,
|
|
10071
10690
|
isSandboxPending,
|
|
10072
10691
|
listFileSystems,
|
|
@@ -10078,6 +10697,9 @@ init_models();
|
|
|
10078
10697
|
runLocal,
|
|
10079
10698
|
runRemote,
|
|
10080
10699
|
sandboxUrlFromIngressEndpoint,
|
|
10081
|
-
schema
|
|
10700
|
+
schema,
|
|
10701
|
+
startImageBuild,
|
|
10702
|
+
startImageImport,
|
|
10703
|
+
waitImageBuild
|
|
10082
10704
|
});
|
|
10083
10705
|
//# sourceMappingURL=index.cjs.map
|