@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.js
CHANGED
|
@@ -46,7 +46,7 @@ var init_defaults = __esm({
|
|
|
46
46
|
"src/defaults.ts"() {
|
|
47
47
|
"use strict";
|
|
48
48
|
init_esm_shims();
|
|
49
|
-
SDK_VERSION = "0.5.
|
|
49
|
+
SDK_VERSION = "0.5.154";
|
|
50
50
|
API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
|
|
51
51
|
API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
|
|
52
52
|
NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
|
|
@@ -57,6 +57,20 @@ var init_defaults = __esm({
|
|
|
57
57
|
}
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
+
// src/enum.ts
|
|
61
|
+
function enumValue(values, value) {
|
|
62
|
+
return typeof value === "string" && Object.values(values).includes(value) ? value : values.UNKNOWN;
|
|
63
|
+
}
|
|
64
|
+
function withRaw(value, raw) {
|
|
65
|
+
return Object.defineProperty(value, "raw", { value: raw, enumerable: false, configurable: true });
|
|
66
|
+
}
|
|
67
|
+
var init_enum = __esm({
|
|
68
|
+
"src/enum.ts"() {
|
|
69
|
+
"use strict";
|
|
70
|
+
init_esm_shims();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
60
74
|
// src/errors.ts
|
|
61
75
|
function formatErrorDetails(errorDetails) {
|
|
62
76
|
if (errorDetails == null) return void 0;
|
|
@@ -495,7 +509,7 @@ var init_native_worker_client = __esm({
|
|
|
495
509
|
}
|
|
496
510
|
};
|
|
497
511
|
runtimeKey = /* @__PURE__ */ Symbol.for(
|
|
498
|
-
`tensorlake.native.worker.${false ? "source" : "0.5.
|
|
512
|
+
`tensorlake.native.worker.${false ? "source" : "0.5.154"}.v1`
|
|
499
513
|
);
|
|
500
514
|
runtimes = globalThis;
|
|
501
515
|
}
|
|
@@ -595,6 +609,9 @@ var init_models = __esm({
|
|
|
595
609
|
SnapshotStatus2["LOCAL_READY"] = "local_ready";
|
|
596
610
|
SnapshotStatus2["COMPLETED"] = "completed";
|
|
597
611
|
SnapshotStatus2["FAILED"] = "failed";
|
|
612
|
+
SnapshotStatus2["DELETING"] = "deleting";
|
|
613
|
+
SnapshotStatus2["REPLICATING"] = "replicating";
|
|
614
|
+
SnapshotStatus2["UNKNOWN"] = "unknown";
|
|
598
615
|
return SnapshotStatus2;
|
|
599
616
|
})(SnapshotStatus || {});
|
|
600
617
|
ProcessStatus = /* @__PURE__ */ ((ProcessStatus2) => {
|
|
@@ -3883,9 +3900,8 @@ var init_sandbox = __esm({
|
|
|
3883
3900
|
*
|
|
3884
3901
|
* Resource targets use create's cpus, memoryMb, and diskMb names. Resize
|
|
3885
3902
|
* waits by default; wait=false returns admission. Timeout does not cancel it.
|
|
3886
|
-
*
|
|
3887
|
-
*
|
|
3888
|
-
* Non-CAS sandboxes do not support live resize.
|
|
3903
|
+
* Which runtimes and dimensions support a live resize is decided by the
|
|
3904
|
+
* server, whose policy error is thrown unchanged.
|
|
3889
3905
|
* Wait, timeout, and pollInterval are ignored on non-resource updates.
|
|
3890
3906
|
* A no-op returns current resources with absent or earlier resize metadata.
|
|
3891
3907
|
*
|
|
@@ -4303,29 +4319,29 @@ var init_sandbox = __esm({
|
|
|
4303
4319
|
}
|
|
4304
4320
|
// --- File operations ---
|
|
4305
4321
|
/** Read a file from the sandbox and return its raw bytes. */
|
|
4306
|
-
async readFile(
|
|
4322
|
+
async readFile(path5) {
|
|
4307
4323
|
const proxy = await this.proxy.client();
|
|
4308
|
-
const { traceId, data } = await callNative(() => proxy.readFile(
|
|
4324
|
+
const { traceId, data } = await callNative(() => proxy.readFile(path5), {
|
|
4309
4325
|
sandboxId: this.sandboxId
|
|
4310
4326
|
});
|
|
4311
4327
|
return Object.assign(Uint8Array.from(data), { traceId });
|
|
4312
4328
|
}
|
|
4313
4329
|
/** Write raw bytes to a file in the sandbox, creating it if it does not exist. */
|
|
4314
|
-
async writeFile(
|
|
4330
|
+
async writeFile(path5, content) {
|
|
4315
4331
|
const proxy = await this.proxy.client();
|
|
4316
|
-
await callNative(() => proxy.writeFile(
|
|
4332
|
+
await callNative(() => proxy.writeFile(path5, Buffer.from(content)), {
|
|
4317
4333
|
sandboxId: this.sandboxId
|
|
4318
4334
|
});
|
|
4319
4335
|
}
|
|
4320
4336
|
/** Delete a file from the sandbox. */
|
|
4321
|
-
async deleteFile(
|
|
4337
|
+
async deleteFile(path5) {
|
|
4322
4338
|
const proxy = await this.proxy.client();
|
|
4323
|
-
await callNative(() => proxy.deleteFile(
|
|
4339
|
+
await callNative(() => proxy.deleteFile(path5), { sandboxId: this.sandboxId });
|
|
4324
4340
|
}
|
|
4325
4341
|
/** List the contents of a directory in the sandbox. */
|
|
4326
|
-
async listDirectory(
|
|
4342
|
+
async listDirectory(path5) {
|
|
4327
4343
|
const proxy = await this.proxy.client();
|
|
4328
|
-
const { traceId, json } = await callNative(() => proxy.listDirectory(
|
|
4344
|
+
const { traceId, json } = await callNative(() => proxy.listDirectory(path5), {
|
|
4329
4345
|
sandboxId: this.sandboxId
|
|
4330
4346
|
});
|
|
4331
4347
|
return Object.assign(fromSnakeKeys(JSON.parse(json)), {
|
|
@@ -4492,6 +4508,18 @@ __export(client_exports, {
|
|
|
4492
4508
|
DEFAULT_WAIT_POLL_INTERVAL_SEC: () => DEFAULT_WAIT_POLL_INTERVAL_SEC,
|
|
4493
4509
|
SandboxClient: () => SandboxClient
|
|
4494
4510
|
});
|
|
4511
|
+
function parseSnapshot(raw) {
|
|
4512
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
4513
|
+
throw new SandboxError("Invalid snapshot response: expected an object");
|
|
4514
|
+
}
|
|
4515
|
+
if (raw.status == null) {
|
|
4516
|
+
throw new SandboxError("Invalid snapshot response: missing status");
|
|
4517
|
+
}
|
|
4518
|
+
return withRaw({
|
|
4519
|
+
...fromSnakeKeys(raw, "snapshotId"),
|
|
4520
|
+
status: enumValue(SnapshotStatus, raw.status)
|
|
4521
|
+
}, raw);
|
|
4522
|
+
}
|
|
4495
4523
|
function requireReadOnlySnapshotPin(fileSystemId, mountPath, readOnly, snapshotId) {
|
|
4496
4524
|
if (snapshotId != null && readOnly !== true) {
|
|
4497
4525
|
throw new SandboxError(
|
|
@@ -4613,6 +4641,7 @@ var init_client = __esm({
|
|
|
4613
4641
|
"use strict";
|
|
4614
4642
|
init_esm_shims();
|
|
4615
4643
|
init_defaults();
|
|
4644
|
+
init_enum();
|
|
4616
4645
|
init_errors();
|
|
4617
4646
|
init_native_worker_client();
|
|
4618
4647
|
init_native_sandbox();
|
|
@@ -4991,9 +5020,9 @@ var init_client = __esm({
|
|
|
4991
5020
|
});
|
|
4992
5021
|
}
|
|
4993
5022
|
/**
|
|
4994
|
-
* Update properties or resize a running sandbox.
|
|
4995
|
-
*
|
|
4996
|
-
*
|
|
5023
|
+
* Update properties or resize a running sandbox. Which runtimes and
|
|
5024
|
+
* dimensions support a live resize is decided by the server, whose policy
|
|
5025
|
+
* error is thrown unchanged.
|
|
4997
5026
|
* Resource names match create. Resize waits by default; wait=false returns
|
|
4998
5027
|
* admission. Timeout leaves the resize running and reports its generation.
|
|
4999
5028
|
* Wait, timeout, and pollInterval are ignored on non-resource updates.
|
|
@@ -5260,18 +5289,18 @@ var init_client = __esm({
|
|
|
5260
5289
|
* block automatically.
|
|
5261
5290
|
*/
|
|
5262
5291
|
async snapshot(sandboxId, options) {
|
|
5263
|
-
|
|
5292
|
+
const { json } = await callNative(
|
|
5264
5293
|
() => this.native.createSnapshot(sandboxId, options?.snapshotType ?? null),
|
|
5265
|
-
"snapshotId",
|
|
5266
5294
|
{ sandboxId, notFoundKind: "sandbox" }
|
|
5267
5295
|
);
|
|
5296
|
+
return parseSnapshot(JSON.parse(json));
|
|
5268
5297
|
}
|
|
5269
5298
|
/** Get current status and metadata for a snapshot by ID. */
|
|
5270
5299
|
async getSnapshot(snapshotId) {
|
|
5271
|
-
|
|
5272
|
-
() => this.native.getSnapshot(snapshotId)
|
|
5273
|
-
"snapshotId"
|
|
5300
|
+
const { traceId, json } = await callNative(
|
|
5301
|
+
() => this.native.getSnapshot(snapshotId)
|
|
5274
5302
|
);
|
|
5303
|
+
return Object.assign(parseSnapshot(JSON.parse(json)), { traceId });
|
|
5275
5304
|
}
|
|
5276
5305
|
/** List all snapshots in the namespace. */
|
|
5277
5306
|
async listSnapshots() {
|
|
@@ -5279,9 +5308,14 @@ var init_client = __esm({
|
|
|
5279
5308
|
() => this.native.listSnapshots()
|
|
5280
5309
|
);
|
|
5281
5310
|
const parsed = JSON.parse(json);
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5311
|
+
if (parsed !== null && (typeof parsed !== "object" || Array.isArray(parsed))) {
|
|
5312
|
+
throw new SandboxError("Invalid snapshot list response: expected an object");
|
|
5313
|
+
}
|
|
5314
|
+
const records = parsed?.snapshots ?? [];
|
|
5315
|
+
if (!Array.isArray(records)) {
|
|
5316
|
+
throw new SandboxError("Invalid snapshot list response: snapshots must be an array");
|
|
5317
|
+
}
|
|
5318
|
+
const snapshots = records.map((s) => parseSnapshot(s));
|
|
5285
5319
|
return Object.assign(snapshots, { traceId });
|
|
5286
5320
|
}
|
|
5287
5321
|
/** Delete a snapshot by ID. */
|
|
@@ -5312,6 +5346,11 @@ var init_client = __esm({
|
|
|
5312
5346
|
`Snapshot ${result.snapshotId} failed: ${info.error}`
|
|
5313
5347
|
);
|
|
5314
5348
|
}
|
|
5349
|
+
if (info.status === "deleting" /* DELETING */) {
|
|
5350
|
+
throw new SandboxError(
|
|
5351
|
+
`Snapshot ${result.snapshotId} is being deleted`
|
|
5352
|
+
);
|
|
5353
|
+
}
|
|
5315
5354
|
await sleep2(pollInterval * 1e3);
|
|
5316
5355
|
}
|
|
5317
5356
|
throw new SandboxError(
|
|
@@ -5569,694 +5608,115 @@ var init_client = __esm({
|
|
|
5569
5608
|
}
|
|
5570
5609
|
});
|
|
5571
5610
|
|
|
5572
|
-
// src/
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
headers["Content-Type"] = "application/json";
|
|
5580
|
-
}
|
|
5581
|
-
}
|
|
5582
|
-
const request = {
|
|
5583
|
-
method,
|
|
5584
|
-
path: path4,
|
|
5585
|
-
headersJson: JSON.stringify(headers),
|
|
5586
|
-
statusOnlyCodes: [...options?.statusOnlyCodes ?? []]
|
|
5611
|
+
// src/image.ts
|
|
5612
|
+
import { randomUUID } from "crypto";
|
|
5613
|
+
function cloneOperation(op) {
|
|
5614
|
+
return {
|
|
5615
|
+
type: op.type,
|
|
5616
|
+
args: [...op.args],
|
|
5617
|
+
options: { ...op.options }
|
|
5587
5618
|
};
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
} else if (body !== void 0) {
|
|
5594
|
-
if (body instanceof Blob) request.body = Buffer.from(await body.arrayBuffer());
|
|
5595
|
-
else if (typeof body === "string") request.body = Buffer.from(body);
|
|
5596
|
-
else if (body instanceof ArrayBuffer) request.body = Buffer.from(new Uint8Array(body));
|
|
5597
|
-
else request.body = Buffer.from(body);
|
|
5619
|
+
}
|
|
5620
|
+
function renderOptions(options) {
|
|
5621
|
+
const entries = Object.entries(options);
|
|
5622
|
+
if (entries.length === 0) {
|
|
5623
|
+
return "";
|
|
5598
5624
|
}
|
|
5599
|
-
return
|
|
5625
|
+
return ` ${entries.map(([key, value]) => `--${key}=${value}`).join(" ")}`;
|
|
5626
|
+
}
|
|
5627
|
+
function renderBuildOp(op) {
|
|
5628
|
+
const options = renderOptions(op.options);
|
|
5629
|
+
if (op.type === ImageBuildOperationType.ENV) {
|
|
5630
|
+
return `ENV${options} ${op.args[0]}=${JSON.stringify(op.args[1])}`;
|
|
5631
|
+
}
|
|
5632
|
+
return `${op.type}${options} ${op.args.join(" ")}`;
|
|
5633
|
+
}
|
|
5634
|
+
function dockerfileContent(image) {
|
|
5635
|
+
const lines = image.baseImage == null ? [] : [`FROM ${image.baseImage}`];
|
|
5636
|
+
lines.push(...image.buildOperations.map((op) => renderBuildOp(op)));
|
|
5637
|
+
return lines.join("\n");
|
|
5600
5638
|
}
|
|
5601
|
-
var
|
|
5602
|
-
var
|
|
5603
|
-
"src/
|
|
5639
|
+
var DEFAULT_IMAGE_NAME, ImageBuildOperationType, Image;
|
|
5640
|
+
var init_image = __esm({
|
|
5641
|
+
"src/image.ts"() {
|
|
5604
5642
|
"use strict";
|
|
5605
5643
|
init_esm_shims();
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5644
|
+
DEFAULT_IMAGE_NAME = "default";
|
|
5645
|
+
ImageBuildOperationType = {
|
|
5646
|
+
ADD: "ADD",
|
|
5647
|
+
COPY: "COPY",
|
|
5648
|
+
ENV: "ENV",
|
|
5649
|
+
RUN: "RUN",
|
|
5650
|
+
WORKDIR: "WORKDIR"
|
|
5651
|
+
};
|
|
5652
|
+
Image = class {
|
|
5653
|
+
_id;
|
|
5654
|
+
_name;
|
|
5655
|
+
_tag;
|
|
5656
|
+
_baseImage;
|
|
5657
|
+
_buildOperations;
|
|
5658
|
+
constructor(nameOrOptions = {}, tag = "latest", baseImage = null) {
|
|
5659
|
+
this._id = randomUUID();
|
|
5660
|
+
this._buildOperations = [];
|
|
5661
|
+
if (typeof nameOrOptions === "string") {
|
|
5662
|
+
this._name = nameOrOptions;
|
|
5663
|
+
this._tag = tag;
|
|
5664
|
+
this._baseImage = baseImage;
|
|
5665
|
+
return;
|
|
5616
5666
|
}
|
|
5667
|
+
this._name = nameOrOptions.name ?? DEFAULT_IMAGE_NAME;
|
|
5668
|
+
this._tag = nameOrOptions.tag ?? "latest";
|
|
5669
|
+
this._baseImage = nameOrOptions.baseImage ?? null;
|
|
5617
5670
|
}
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
client() {
|
|
5621
|
-
if (this.closed) throw new Error("Tensorlake native client is closed");
|
|
5622
|
-
if (this.native) return this.native;
|
|
5623
|
-
const ctor = loadNativeSandboxBinding().NativeCloudClient;
|
|
5624
|
-
if (!ctor) throw new Error("Native binding does not export NativeCloudClient; rebuild with 'npm run build:native'");
|
|
5625
|
-
return this.native = new ctor(JSON.stringify(this.options));
|
|
5671
|
+
get name() {
|
|
5672
|
+
return this._name;
|
|
5626
5673
|
}
|
|
5627
|
-
|
|
5628
|
-
this.
|
|
5629
|
-
releaseNativeHandle(this.native ?? null);
|
|
5630
|
-
this.native = void 0;
|
|
5631
|
-
}
|
|
5632
|
-
async requestResponse(method, path4, options) {
|
|
5633
|
-
const request = await serializeRequest(method, path4, options);
|
|
5634
|
-
const raw = await callNative(() => this.client().request(request));
|
|
5635
|
-
const response = new Response(
|
|
5636
|
-
[204, 205, 304].includes(raw.status) ? null : Uint8Array.from(raw.data).buffer,
|
|
5637
|
-
{ status: raw.status, headers: JSON.parse(raw.headersJson) }
|
|
5638
|
-
);
|
|
5639
|
-
return Object.assign(response, { traceId: raw.traceId });
|
|
5674
|
+
get tag() {
|
|
5675
|
+
return this._tag;
|
|
5640
5676
|
}
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
const text = await response.text();
|
|
5644
|
-
const value = text ? JSON.parse(text) : null;
|
|
5645
|
-
return Object.assign(value ?? {}, { traceId: response.traceId });
|
|
5677
|
+
get baseImage() {
|
|
5678
|
+
return this._baseImage;
|
|
5646
5679
|
}
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
const request = await serializeRequest(method, path4, { headers: { Accept: "text/event-stream" } });
|
|
5650
|
-
yield* nativeEventStream((emit) => this.client().stream(request, emit), void 0, signal);
|
|
5680
|
+
get buildOperations() {
|
|
5681
|
+
return this._buildOperations.map(cloneOperation);
|
|
5651
5682
|
}
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
import { nanoid } from "nanoid";
|
|
5658
|
-
function secretFromMetadata(metadata) {
|
|
5659
|
-
return {
|
|
5660
|
-
id: metadata.id,
|
|
5661
|
-
name: metadata.name,
|
|
5662
|
-
createdAt: new Date(metadata.created_at_ms)
|
|
5663
|
-
};
|
|
5664
|
-
}
|
|
5665
|
-
function applicationAllowsUnauthenticatedRequests(manifest) {
|
|
5666
|
-
return Array.isArray(manifest.allow) && manifest.allow.includes(UNAUTHENTICATED_REQUESTS);
|
|
5667
|
-
}
|
|
5668
|
-
function publicEndpointIdFromManifest(manifest) {
|
|
5669
|
-
for (const key of ["public_endpoint_id", "publicEndpointId"]) {
|
|
5670
|
-
const value = manifest[key];
|
|
5671
|
-
if (typeof value === "string" && value.length > 0) {
|
|
5672
|
-
return value;
|
|
5673
|
-
}
|
|
5674
|
-
}
|
|
5675
|
-
return void 0;
|
|
5676
|
-
}
|
|
5677
|
-
function generatePublicEndpointId() {
|
|
5678
|
-
return `endpoint_${nanoid()}`;
|
|
5679
|
-
}
|
|
5680
|
-
function createApplicationBuildForm(request, imageContexts) {
|
|
5681
|
-
const contextsByPartName = /* @__PURE__ */ new Map();
|
|
5682
|
-
for (const context of imageContexts) {
|
|
5683
|
-
if (contextsByPartName.has(context.contextTarPartName)) {
|
|
5684
|
-
throw new Error(
|
|
5685
|
-
`duplicate image context part name '${context.contextTarPartName}'`
|
|
5686
|
-
);
|
|
5687
|
-
}
|
|
5688
|
-
contextsByPartName.set(context.contextTarPartName, context);
|
|
5689
|
-
}
|
|
5690
|
-
const form = new FormData();
|
|
5691
|
-
form.append(
|
|
5692
|
-
"app_version",
|
|
5693
|
-
new Blob([JSON.stringify(request)], { type: "application/json" }),
|
|
5694
|
-
"app_version"
|
|
5695
|
-
);
|
|
5696
|
-
for (const image of request.images) {
|
|
5697
|
-
const context = contextsByPartName.get(image.contextTarPartName);
|
|
5698
|
-
if (!context) {
|
|
5699
|
-
throw new Error(
|
|
5700
|
-
`missing image context for part '${image.contextTarPartName}'`
|
|
5701
|
-
);
|
|
5702
|
-
}
|
|
5703
|
-
form.append(
|
|
5704
|
-
image.contextTarPartName,
|
|
5705
|
-
new Blob([toBlobPart(context.contextTarGz)]),
|
|
5706
|
-
`${image.contextTarPartName}.tar.gz`
|
|
5707
|
-
);
|
|
5708
|
-
}
|
|
5709
|
-
for (const context of imageContexts) {
|
|
5710
|
-
if (!request.images.some((image) => image.contextTarPartName === context.contextTarPartName)) {
|
|
5711
|
-
throw new Error(
|
|
5712
|
-
`unexpected image context for part '${context.contextTarPartName}'`
|
|
5713
|
-
);
|
|
5714
|
-
}
|
|
5715
|
-
}
|
|
5716
|
-
return form;
|
|
5717
|
-
}
|
|
5718
|
-
function trimTrailingSlashes2(value) {
|
|
5719
|
-
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
5720
|
-
}
|
|
5721
|
-
function nextRequestPath(next) {
|
|
5722
|
-
const schemeIndex = next.indexOf("://");
|
|
5723
|
-
if (schemeIndex !== -1) {
|
|
5724
|
-
const afterScheme = next.slice(schemeIndex + 3);
|
|
5725
|
-
const slashIndex = afterScheme.indexOf("/");
|
|
5726
|
-
return slashIndex === -1 ? "/" : afterScheme.slice(slashIndex);
|
|
5727
|
-
}
|
|
5728
|
-
return next.startsWith("/") ? next : `/${next}`;
|
|
5729
|
-
}
|
|
5730
|
-
function toBlobPart(data) {
|
|
5731
|
-
if (typeof data === "string" || data instanceof Blob) {
|
|
5732
|
-
return data;
|
|
5733
|
-
}
|
|
5734
|
-
if (data instanceof Uint8Array) {
|
|
5735
|
-
return Uint8Array.from(data).buffer;
|
|
5736
|
-
}
|
|
5737
|
-
return data;
|
|
5738
|
-
}
|
|
5739
|
-
function toRequestBody(data) {
|
|
5740
|
-
return toBlobPart(data);
|
|
5741
|
-
}
|
|
5742
|
-
async function parseJsonResponse(response) {
|
|
5743
|
-
const text = await response.text();
|
|
5744
|
-
if (!text) {
|
|
5745
|
-
return void 0;
|
|
5746
|
-
}
|
|
5747
|
-
return JSON.parse(text);
|
|
5748
|
-
}
|
|
5749
|
-
var CloudClient, UNAUTHENTICATED_REQUESTS;
|
|
5750
|
-
var init_cloud_client = __esm({
|
|
5751
|
-
"src/cloud-client.ts"() {
|
|
5752
|
-
"use strict";
|
|
5753
|
-
init_esm_shims();
|
|
5754
|
-
init_defaults();
|
|
5755
|
-
init_native_cloud();
|
|
5756
|
-
init_models();
|
|
5757
|
-
CloudClient = class _CloudClient {
|
|
5758
|
-
transport;
|
|
5759
|
-
organizationId;
|
|
5760
|
-
projectId;
|
|
5761
|
-
namespace;
|
|
5762
|
-
constructor(options) {
|
|
5763
|
-
this.organizationId = options?.organizationId;
|
|
5764
|
-
this.projectId = options?.projectId;
|
|
5765
|
-
this.namespace = options?.namespace ?? NAMESPACE;
|
|
5766
|
-
this.transport = new NativeCloudTransport({
|
|
5767
|
-
baseUrl: options?.apiUrl ?? API_URL,
|
|
5768
|
-
apiKey: options?.apiKey ?? API_KEY,
|
|
5769
|
-
organizationId: this.organizationId,
|
|
5770
|
-
projectId: this.projectId,
|
|
5771
|
-
maxRetries: options?.maxRetries ?? MAX_RETRIES,
|
|
5772
|
-
retryBackoffMs: options?.retryBackoffMs ?? RETRY_BACKOFF_MS,
|
|
5773
|
-
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
5774
|
-
userAgent: `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
5683
|
+
add(src, dest, options = void 0) {
|
|
5684
|
+
return this._addOperation({
|
|
5685
|
+
type: ImageBuildOperationType.ADD,
|
|
5686
|
+
args: [src, dest],
|
|
5687
|
+
options: options == null ? {} : { ...options }
|
|
5775
5688
|
});
|
|
5776
5689
|
}
|
|
5777
|
-
|
|
5778
|
-
return
|
|
5690
|
+
copy(src, dest, options = void 0) {
|
|
5691
|
+
return this._addOperation({
|
|
5692
|
+
type: ImageBuildOperationType.COPY,
|
|
5693
|
+
args: [src, dest],
|
|
5694
|
+
options: options == null ? {} : { ...options }
|
|
5695
|
+
});
|
|
5779
5696
|
}
|
|
5780
|
-
|
|
5781
|
-
this.
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
let publicEndpointId = publicEndpointIdFromManifest(applicationManifest);
|
|
5786
|
-
if (applicationAllowsUnauthenticatedRequests(applicationManifest) && publicEndpointId === void 0) {
|
|
5787
|
-
const applicationName = applicationManifest.name;
|
|
5788
|
-
if (typeof applicationName === "string" && applicationName.length > 0) {
|
|
5789
|
-
publicEndpointId = await this.existingApplicationPublicEndpointId(applicationName);
|
|
5790
|
-
}
|
|
5791
|
-
publicEndpointId ??= generatePublicEndpointId();
|
|
5792
|
-
}
|
|
5793
|
-
if (publicEndpointId !== void 0) {
|
|
5794
|
-
applicationManifest.public_endpoint_id = publicEndpointId;
|
|
5795
|
-
delete applicationManifest.publicEndpointId;
|
|
5796
|
-
}
|
|
5797
|
-
const form = new FormData();
|
|
5798
|
-
form.append(
|
|
5799
|
-
"code",
|
|
5800
|
-
new Blob([toBlobPart(codeZip)], { type: "application/zip" }),
|
|
5801
|
-
"code.zip"
|
|
5802
|
-
);
|
|
5803
|
-
form.append("code_content_type", "application/zip");
|
|
5804
|
-
form.append("application", JSON.stringify(applicationManifest));
|
|
5805
|
-
form.append(
|
|
5806
|
-
"upgrade_requests_to_latest_code",
|
|
5807
|
-
String(upgradeRunningRequests)
|
|
5808
|
-
);
|
|
5809
|
-
await this.transport.requestResponse("POST", this.namespacePath("applications"), {
|
|
5810
|
-
body: form
|
|
5697
|
+
env(key, value) {
|
|
5698
|
+
return this._addOperation({
|
|
5699
|
+
type: ImageBuildOperationType.ENV,
|
|
5700
|
+
args: [key, value],
|
|
5701
|
+
options: {}
|
|
5811
5702
|
});
|
|
5812
5703
|
}
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5704
|
+
run(commands, options = void 0) {
|
|
5705
|
+
return this._addOperation({
|
|
5706
|
+
type: ImageBuildOperationType.RUN,
|
|
5707
|
+
args: Array.isArray(commands) ? [...commands] : [commands],
|
|
5708
|
+
options: options == null ? {} : { ...options }
|
|
5709
|
+
});
|
|
5818
5710
|
}
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5711
|
+
workdir(directory) {
|
|
5712
|
+
return this._addOperation({
|
|
5713
|
+
type: ImageBuildOperationType.WORKDIR,
|
|
5714
|
+
args: [directory],
|
|
5715
|
+
options: {}
|
|
5716
|
+
});
|
|
5824
5717
|
}
|
|
5825
5718
|
/**
|
|
5826
|
-
*
|
|
5827
|
-
*
|
|
5828
|
-
* Returns the template, or `null` when no image with that name exists.
|
|
5829
|
-
* API-key clients may omit organization/project IDs and use the
|
|
5830
|
-
* token-scoped Platform API route directly. Explicit scope remains
|
|
5831
|
-
* available for PAT callers.
|
|
5832
|
-
*/
|
|
5833
|
-
async findSandboxImageByName(imageName, options) {
|
|
5834
|
-
const base = this.platformProjectPath(
|
|
5835
|
-
"sandbox-templates",
|
|
5836
|
-
options?.organizationId,
|
|
5837
|
-
options?.projectId
|
|
5838
|
-
);
|
|
5839
|
-
const response = await this.transport.requestResponse(
|
|
5840
|
-
"GET",
|
|
5841
|
-
`${base}/by-name/${encodeURIComponent(imageName)}`,
|
|
5842
|
-
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
5843
|
-
);
|
|
5844
|
-
if (response.status === 404) {
|
|
5845
|
-
return null;
|
|
5846
|
-
}
|
|
5847
|
-
const raw = await parseJsonResponse(response);
|
|
5848
|
-
return fromSnakeKeys(raw);
|
|
5849
|
-
}
|
|
5850
|
-
/**
|
|
5851
|
-
* List all registered sandbox images (templates), following pagination to
|
|
5852
|
-
* the end. API-key clients may omit organization/project IDs and use the
|
|
5853
|
-
* token-scoped Platform API route directly.
|
|
5854
|
-
*/
|
|
5855
|
-
async listSandboxImages(options) {
|
|
5856
|
-
const base = this.platformProjectPath(
|
|
5857
|
-
"sandbox-templates",
|
|
5858
|
-
options?.organizationId,
|
|
5859
|
-
options?.projectId
|
|
5860
|
-
);
|
|
5861
|
-
let path4 = `${base}?pageSize=100`;
|
|
5862
|
-
const templates = [];
|
|
5863
|
-
while (path4 !== null) {
|
|
5864
|
-
const page = await this.transport.requestJson(
|
|
5865
|
-
"GET",
|
|
5866
|
-
path4
|
|
5867
|
-
);
|
|
5868
|
-
for (const item of page.items ?? []) {
|
|
5869
|
-
templates.push(fromSnakeKeys(item));
|
|
5870
|
-
}
|
|
5871
|
-
const next = page.pagination?.next;
|
|
5872
|
-
path4 = next ? nextRequestPath(next) : null;
|
|
5873
|
-
}
|
|
5874
|
-
return templates;
|
|
5875
|
-
}
|
|
5876
|
-
async applications() {
|
|
5877
|
-
const raw = await this.transport.requestJson(
|
|
5878
|
-
"GET",
|
|
5879
|
-
this.namespacePath("applications")
|
|
5880
|
-
);
|
|
5881
|
-
return (raw.applications ?? []).map(
|
|
5882
|
-
(application) => fromSnakeKeys(application)
|
|
5883
|
-
);
|
|
5884
|
-
}
|
|
5885
|
-
async applicationManifest(applicationName) {
|
|
5886
|
-
const raw = await this.transport.requestJson(
|
|
5887
|
-
"GET",
|
|
5888
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
5889
|
-
);
|
|
5890
|
-
return fromSnakeKeys(raw);
|
|
5891
|
-
}
|
|
5892
|
-
async runRequest(applicationName, inputs = []) {
|
|
5893
|
-
const path4 = this.namespacePath(
|
|
5894
|
-
`applications/${encodeURIComponent(applicationName)}`
|
|
5895
|
-
);
|
|
5896
|
-
const response = inputs.length === 0 ? await this.transport.requestResponse("POST", path4, {
|
|
5897
|
-
body: new Uint8Array(),
|
|
5898
|
-
headers: { Accept: "application/json" }
|
|
5899
|
-
}) : inputs.length === 1 && inputs[0].name === "0" ? await this.transport.requestResponse("POST", path4, {
|
|
5900
|
-
body: toRequestBody(inputs[0].data),
|
|
5901
|
-
headers: {
|
|
5902
|
-
Accept: "application/json",
|
|
5903
|
-
"Content-Type": inputs[0].contentType
|
|
5904
|
-
}
|
|
5905
|
-
}) : await this.runMultipartRequest(path4, inputs);
|
|
5906
|
-
const body = await parseJsonResponse(response);
|
|
5907
|
-
const requestId = body?.request_id;
|
|
5908
|
-
if (!requestId) {
|
|
5909
|
-
throw new Error("missing request_id in run request response body");
|
|
5910
|
-
}
|
|
5911
|
-
return requestId;
|
|
5912
|
-
}
|
|
5913
|
-
async waitOnRequestCompletion(applicationName, requestId) {
|
|
5914
|
-
const stream = this.transport.stream(
|
|
5915
|
-
"GET",
|
|
5916
|
-
this.namespacePath(
|
|
5917
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/progress`
|
|
5918
|
-
)
|
|
5919
|
-
);
|
|
5920
|
-
for await (const event of stream) {
|
|
5921
|
-
if (Object.prototype.hasOwnProperty.call(event, "RequestFinished")) {
|
|
5922
|
-
return;
|
|
5923
|
-
}
|
|
5924
|
-
}
|
|
5925
|
-
throw new Error("progress stream ended before request completion");
|
|
5926
|
-
}
|
|
5927
|
-
async requestMetadata(applicationName, requestId) {
|
|
5928
|
-
const raw = await this.transport.requestJson(
|
|
5929
|
-
"GET",
|
|
5930
|
-
this.namespacePath(
|
|
5931
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}`
|
|
5932
|
-
)
|
|
5933
|
-
);
|
|
5934
|
-
return fromSnakeKeys(raw);
|
|
5935
|
-
}
|
|
5936
|
-
async requestOutput(applicationName, requestId) {
|
|
5937
|
-
const response = await this.transport.requestResponse(
|
|
5938
|
-
"GET",
|
|
5939
|
-
this.namespacePath(
|
|
5940
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/output`
|
|
5941
|
-
)
|
|
5942
|
-
);
|
|
5943
|
-
const serializedValue = new Uint8Array(await response.arrayBuffer());
|
|
5944
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
5945
|
-
return {
|
|
5946
|
-
serializedValue,
|
|
5947
|
-
contentType
|
|
5948
|
-
};
|
|
5949
|
-
}
|
|
5950
|
-
async listSecrets(options) {
|
|
5951
|
-
const base = this.secretCollectionPath(
|
|
5952
|
-
options?.organizationId,
|
|
5953
|
-
options?.projectId
|
|
5954
|
-
);
|
|
5955
|
-
const raw = await this.transport.requestJson("GET", base);
|
|
5956
|
-
const pageSize = Math.max(0, options?.pageSize ?? 100);
|
|
5957
|
-
return Object.assign(
|
|
5958
|
-
{
|
|
5959
|
-
items: raw.slice(0, pageSize).map(secretFromMetadata),
|
|
5960
|
-
pagination: { total: raw.length }
|
|
5961
|
-
},
|
|
5962
|
-
{ traceId: raw.traceId }
|
|
5963
|
-
);
|
|
5964
|
-
}
|
|
5965
|
-
async getSecret(secretId, options) {
|
|
5966
|
-
const base = this.secretCollectionPath(
|
|
5967
|
-
options?.organizationId,
|
|
5968
|
-
options?.projectId
|
|
5969
|
-
);
|
|
5970
|
-
const raw = await this.transport.requestJson(
|
|
5971
|
-
"GET",
|
|
5972
|
-
`${base}/${encodeURIComponent(secretId)}`
|
|
5973
|
-
);
|
|
5974
|
-
return Object.assign(secretFromMetadata(raw), { traceId: raw.traceId });
|
|
5975
|
-
}
|
|
5976
|
-
async upsertSecrets(secrets, options) {
|
|
5977
|
-
const base = this.secretCollectionPath(
|
|
5978
|
-
options?.organizationId,
|
|
5979
|
-
options?.projectId
|
|
5980
|
-
);
|
|
5981
|
-
if (Array.isArray(secrets)) {
|
|
5982
|
-
const results = [];
|
|
5983
|
-
for (const secret of secrets) {
|
|
5984
|
-
results.push(await this.upsertSecret(base, secret));
|
|
5985
|
-
}
|
|
5986
|
-
return results;
|
|
5987
|
-
}
|
|
5988
|
-
return this.upsertSecret(base, secrets);
|
|
5989
|
-
}
|
|
5990
|
-
async deleteSecret(secretId, options) {
|
|
5991
|
-
const base = this.secretCollectionPath(
|
|
5992
|
-
options?.organizationId,
|
|
5993
|
-
options?.projectId
|
|
5994
|
-
);
|
|
5995
|
-
await this.transport.requestResponse(
|
|
5996
|
-
"DELETE",
|
|
5997
|
-
`${base}/${encodeURIComponent(secretId)}`
|
|
5998
|
-
);
|
|
5999
|
-
}
|
|
6000
|
-
async upsertSecret(base, secret) {
|
|
6001
|
-
let response = await this.transport.requestResponse("POST", base, {
|
|
6002
|
-
json: secret,
|
|
6003
|
-
headers: { "Idempotency-Key": nanoid() },
|
|
6004
|
-
statusOnlyCodes: /* @__PURE__ */ new Set([409])
|
|
6005
|
-
});
|
|
6006
|
-
if (response.status === 409) {
|
|
6007
|
-
const prefix = base.slice(0, -"/secrets".length);
|
|
6008
|
-
const existing = await this.transport.requestJson(
|
|
6009
|
-
"GET",
|
|
6010
|
-
`${prefix}/secret-names/${encodeURIComponent(secret.name)}`
|
|
6011
|
-
);
|
|
6012
|
-
response = await this.transport.requestResponse(
|
|
6013
|
-
"POST",
|
|
6014
|
-
`${base}/${encodeURIComponent(existing.id)}/versions`,
|
|
6015
|
-
{
|
|
6016
|
-
json: { value: secret.value },
|
|
6017
|
-
headers: { "Idempotency-Key": nanoid() }
|
|
6018
|
-
}
|
|
6019
|
-
);
|
|
6020
|
-
}
|
|
6021
|
-
const metadata = await parseJsonResponse(response);
|
|
6022
|
-
return Object.assign(secretFromMetadata(metadata), {
|
|
6023
|
-
traceId: response.traceId
|
|
6024
|
-
});
|
|
6025
|
-
}
|
|
6026
|
-
async startImageBuild(buildServicePath, request) {
|
|
6027
|
-
const form = new FormData();
|
|
6028
|
-
form.append("graph_name", request.applicationName);
|
|
6029
|
-
form.append("graph_version", request.applicationVersion);
|
|
6030
|
-
form.append("graph_function_name", request.functionName);
|
|
6031
|
-
form.append("image_name", request.imageName);
|
|
6032
|
-
form.append("image_id", request.imageId);
|
|
6033
|
-
form.append(
|
|
6034
|
-
"context",
|
|
6035
|
-
new Blob([toBlobPart(request.buildContext)]),
|
|
6036
|
-
"context.tar.gz"
|
|
6037
|
-
);
|
|
6038
|
-
const response = await this.transport.requestResponse(
|
|
6039
|
-
"PUT",
|
|
6040
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds`,
|
|
6041
|
-
{ body: form }
|
|
6042
|
-
);
|
|
6043
|
-
const raw = await parseJsonResponse(response);
|
|
6044
|
-
return fromSnakeKeys(raw);
|
|
6045
|
-
}
|
|
6046
|
-
async createApplicationBuild(buildServicePath, request, imageContexts) {
|
|
6047
|
-
const form = createApplicationBuildForm(request, imageContexts);
|
|
6048
|
-
const response = await this.transport.requestResponse(
|
|
6049
|
-
"POST",
|
|
6050
|
-
trimTrailingSlashes2(buildServicePath),
|
|
6051
|
-
{ body: form }
|
|
6052
|
-
);
|
|
6053
|
-
const raw = await parseJsonResponse(response);
|
|
6054
|
-
return fromSnakeKeys(raw);
|
|
6055
|
-
}
|
|
6056
|
-
async applicationBuildInfo(buildServicePath, applicationBuildId) {
|
|
6057
|
-
const raw = await this.transport.requestJson(
|
|
6058
|
-
"GET",
|
|
6059
|
-
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}`
|
|
6060
|
-
);
|
|
6061
|
-
return fromSnakeKeys(raw);
|
|
6062
|
-
}
|
|
6063
|
-
async cancelApplicationBuild(buildServicePath, applicationBuildId) {
|
|
6064
|
-
const raw = await this.transport.requestJson(
|
|
6065
|
-
"POST",
|
|
6066
|
-
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}/cancel`
|
|
6067
|
-
);
|
|
6068
|
-
return fromSnakeKeys(raw);
|
|
6069
|
-
}
|
|
6070
|
-
async buildInfo(buildServicePath, buildId) {
|
|
6071
|
-
const raw = await this.transport.requestJson(
|
|
6072
|
-
"GET",
|
|
6073
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}`
|
|
6074
|
-
);
|
|
6075
|
-
return fromSnakeKeys(raw);
|
|
6076
|
-
}
|
|
6077
|
-
async cancelBuild(buildServicePath, buildId) {
|
|
6078
|
-
await this.transport.requestResponse(
|
|
6079
|
-
"POST",
|
|
6080
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/cancel`
|
|
6081
|
-
);
|
|
6082
|
-
}
|
|
6083
|
-
async *streamBuildLogs(buildServicePath, buildId, signal) {
|
|
6084
|
-
const stream = this.transport.stream(
|
|
6085
|
-
"GET",
|
|
6086
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/logs`,
|
|
6087
|
-
signal
|
|
6088
|
-
);
|
|
6089
|
-
for await (const event of stream) {
|
|
6090
|
-
yield fromSnakeKeys(event);
|
|
6091
|
-
}
|
|
6092
|
-
}
|
|
6093
|
-
async runMultipartRequest(path4, inputs) {
|
|
6094
|
-
const form = new FormData();
|
|
6095
|
-
for (const input of inputs) {
|
|
6096
|
-
form.append(
|
|
6097
|
-
input.name,
|
|
6098
|
-
new Blob([toBlobPart(input.data)], { type: input.contentType }),
|
|
6099
|
-
input.name
|
|
6100
|
-
);
|
|
6101
|
-
}
|
|
6102
|
-
return this.transport.requestResponse("POST", path4, {
|
|
6103
|
-
body: form,
|
|
6104
|
-
headers: { Accept: "application/json" }
|
|
6105
|
-
});
|
|
6106
|
-
}
|
|
6107
|
-
namespacePath(subpath) {
|
|
6108
|
-
return `/v1/namespaces/${encodeURIComponent(this.namespace)}/${subpath.replace(/^\/+/, "")}`;
|
|
6109
|
-
}
|
|
6110
|
-
async existingApplicationPublicEndpointId(applicationName) {
|
|
6111
|
-
const response = await this.transport.requestResponse(
|
|
6112
|
-
"GET",
|
|
6113
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`),
|
|
6114
|
-
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
6115
|
-
);
|
|
6116
|
-
if (response.status === 404) {
|
|
6117
|
-
return void 0;
|
|
6118
|
-
}
|
|
6119
|
-
const application = await parseJsonResponse(response);
|
|
6120
|
-
return publicEndpointIdFromManifest(application);
|
|
6121
|
-
}
|
|
6122
|
-
platformProjectPath(resource, organizationId, projectId) {
|
|
6123
|
-
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
6124
|
-
const resolvedProjectId = projectId ?? this.projectId;
|
|
6125
|
-
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
6126
|
-
return `/platform/v1/${resource}`;
|
|
6127
|
-
}
|
|
6128
|
-
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
6129
|
-
throw new Error(
|
|
6130
|
-
"organizationId and projectId must be provided together"
|
|
6131
|
-
);
|
|
6132
|
-
}
|
|
6133
|
-
return `/platform/v1/organizations/${encodeURIComponent(resolvedOrganizationId)}/projects/${encodeURIComponent(resolvedProjectId)}/${resource}`;
|
|
6134
|
-
}
|
|
6135
|
-
secretCollectionPath(organizationId, projectId) {
|
|
6136
|
-
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
6137
|
-
const resolvedProjectId = projectId ?? this.projectId;
|
|
6138
|
-
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
6139
|
-
return this.namespacePath("secrets");
|
|
6140
|
-
}
|
|
6141
|
-
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
6142
|
-
throw new Error("organizationId and projectId must be provided together");
|
|
6143
|
-
}
|
|
6144
|
-
return this.namespacePath("secrets");
|
|
6145
|
-
}
|
|
6146
|
-
};
|
|
6147
|
-
UNAUTHENTICATED_REQUESTS = "unauthenticated_requests";
|
|
6148
|
-
}
|
|
6149
|
-
});
|
|
6150
|
-
|
|
6151
|
-
// src/image.ts
|
|
6152
|
-
import { randomUUID } from "crypto";
|
|
6153
|
-
function cloneOperation(op) {
|
|
6154
|
-
return {
|
|
6155
|
-
type: op.type,
|
|
6156
|
-
args: [...op.args],
|
|
6157
|
-
options: { ...op.options }
|
|
6158
|
-
};
|
|
6159
|
-
}
|
|
6160
|
-
function renderOptions(options) {
|
|
6161
|
-
const entries = Object.entries(options);
|
|
6162
|
-
if (entries.length === 0) {
|
|
6163
|
-
return "";
|
|
6164
|
-
}
|
|
6165
|
-
return ` ${entries.map(([key, value]) => `--${key}=${value}`).join(" ")}`;
|
|
6166
|
-
}
|
|
6167
|
-
function renderBuildOp(op) {
|
|
6168
|
-
const options = renderOptions(op.options);
|
|
6169
|
-
if (op.type === ImageBuildOperationType.ENV) {
|
|
6170
|
-
return `ENV${options} ${op.args[0]}=${JSON.stringify(op.args[1])}`;
|
|
6171
|
-
}
|
|
6172
|
-
return `${op.type}${options} ${op.args.join(" ")}`;
|
|
6173
|
-
}
|
|
6174
|
-
function dockerfileContent(image) {
|
|
6175
|
-
const lines = image.baseImage == null ? [] : [`FROM ${image.baseImage}`];
|
|
6176
|
-
lines.push(...image.buildOperations.map((op) => renderBuildOp(op)));
|
|
6177
|
-
return lines.join("\n");
|
|
6178
|
-
}
|
|
6179
|
-
var DEFAULT_IMAGE_NAME, ImageBuildOperationType, Image;
|
|
6180
|
-
var init_image = __esm({
|
|
6181
|
-
"src/image.ts"() {
|
|
6182
|
-
"use strict";
|
|
6183
|
-
init_esm_shims();
|
|
6184
|
-
DEFAULT_IMAGE_NAME = "default";
|
|
6185
|
-
ImageBuildOperationType = {
|
|
6186
|
-
ADD: "ADD",
|
|
6187
|
-
COPY: "COPY",
|
|
6188
|
-
ENV: "ENV",
|
|
6189
|
-
RUN: "RUN",
|
|
6190
|
-
WORKDIR: "WORKDIR"
|
|
6191
|
-
};
|
|
6192
|
-
Image = class {
|
|
6193
|
-
_id;
|
|
6194
|
-
_name;
|
|
6195
|
-
_tag;
|
|
6196
|
-
_baseImage;
|
|
6197
|
-
_buildOperations;
|
|
6198
|
-
constructor(nameOrOptions = {}, tag = "latest", baseImage = null) {
|
|
6199
|
-
this._id = randomUUID();
|
|
6200
|
-
this._buildOperations = [];
|
|
6201
|
-
if (typeof nameOrOptions === "string") {
|
|
6202
|
-
this._name = nameOrOptions;
|
|
6203
|
-
this._tag = tag;
|
|
6204
|
-
this._baseImage = baseImage;
|
|
6205
|
-
return;
|
|
6206
|
-
}
|
|
6207
|
-
this._name = nameOrOptions.name ?? DEFAULT_IMAGE_NAME;
|
|
6208
|
-
this._tag = nameOrOptions.tag ?? "latest";
|
|
6209
|
-
this._baseImage = nameOrOptions.baseImage ?? null;
|
|
6210
|
-
}
|
|
6211
|
-
get name() {
|
|
6212
|
-
return this._name;
|
|
6213
|
-
}
|
|
6214
|
-
get tag() {
|
|
6215
|
-
return this._tag;
|
|
6216
|
-
}
|
|
6217
|
-
get baseImage() {
|
|
6218
|
-
return this._baseImage;
|
|
6219
|
-
}
|
|
6220
|
-
get buildOperations() {
|
|
6221
|
-
return this._buildOperations.map(cloneOperation);
|
|
6222
|
-
}
|
|
6223
|
-
add(src, dest, options = void 0) {
|
|
6224
|
-
return this._addOperation({
|
|
6225
|
-
type: ImageBuildOperationType.ADD,
|
|
6226
|
-
args: [src, dest],
|
|
6227
|
-
options: options == null ? {} : { ...options }
|
|
6228
|
-
});
|
|
6229
|
-
}
|
|
6230
|
-
copy(src, dest, options = void 0) {
|
|
6231
|
-
return this._addOperation({
|
|
6232
|
-
type: ImageBuildOperationType.COPY,
|
|
6233
|
-
args: [src, dest],
|
|
6234
|
-
options: options == null ? {} : { ...options }
|
|
6235
|
-
});
|
|
6236
|
-
}
|
|
6237
|
-
env(key, value) {
|
|
6238
|
-
return this._addOperation({
|
|
6239
|
-
type: ImageBuildOperationType.ENV,
|
|
6240
|
-
args: [key, value],
|
|
6241
|
-
options: {}
|
|
6242
|
-
});
|
|
6243
|
-
}
|
|
6244
|
-
run(commands, options = void 0) {
|
|
6245
|
-
return this._addOperation({
|
|
6246
|
-
type: ImageBuildOperationType.RUN,
|
|
6247
|
-
args: Array.isArray(commands) ? [...commands] : [commands],
|
|
6248
|
-
options: options == null ? {} : { ...options }
|
|
6249
|
-
});
|
|
6250
|
-
}
|
|
6251
|
-
workdir(directory) {
|
|
6252
|
-
return this._addOperation({
|
|
6253
|
-
type: ImageBuildOperationType.WORKDIR,
|
|
6254
|
-
args: [directory],
|
|
6255
|
-
options: {}
|
|
6256
|
-
});
|
|
6257
|
-
}
|
|
6258
|
-
/**
|
|
6259
|
-
* Build this image as a sandbox template and register it.
|
|
5719
|
+
* Build this image as a sandbox template and register it.
|
|
6260
5720
|
*
|
|
6261
5721
|
* Materializes the image in a build sandbox, snapshots the filesystem,
|
|
6262
5722
|
* and registers the snapshot as a named sandbox template.
|
|
@@ -6419,22 +5879,568 @@ var init_native_binding = __esm({
|
|
|
6419
5879
|
}
|
|
6420
5880
|
});
|
|
6421
5881
|
|
|
5882
|
+
// src/image-builds.ts
|
|
5883
|
+
import path3 from "path";
|
|
5884
|
+
import os from "os";
|
|
5885
|
+
import { existsSync as existsSync2, mkdtempSync, rmSync } from "fs";
|
|
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 = path3.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 = mkdtempSync(path3.join(os.tmpdir(), "tl-build-context-"));
|
|
6085
|
+
contextDir = tempContextDir;
|
|
6086
|
+
}
|
|
6087
|
+
dockerfilePath = path3.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 = path3.resolve(source);
|
|
6094
|
+
if (!existsSync2(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) 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 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_esm_shims();
|
|
6230
|
+
init_enum();
|
|
6231
|
+
init_image();
|
|
6232
|
+
init_sandbox_image();
|
|
6233
|
+
ImageBuildStatus = /* @__PURE__ */ ((ImageBuildStatus2) => {
|
|
6234
|
+
ImageBuildStatus2["PENDING"] = "pending";
|
|
6235
|
+
ImageBuildStatus2["RUNNING"] = "running";
|
|
6236
|
+
ImageBuildStatus2["SUCCEEDED"] = "succeeded";
|
|
6237
|
+
ImageBuildStatus2["FAILED"] = "failed";
|
|
6238
|
+
ImageBuildStatus2["CANCELLED"] = "cancelled";
|
|
6239
|
+
ImageBuildStatus2["UNKNOWN"] = "unknown";
|
|
6240
|
+
return ImageBuildStatus2;
|
|
6241
|
+
})(ImageBuildStatus || {});
|
|
6242
|
+
ImageBuildPhase = /* @__PURE__ */ ((ImageBuildPhase2) => {
|
|
6243
|
+
ImageBuildPhase2["AWAITING_CONTEXT"] = "awaiting_context";
|
|
6244
|
+
ImageBuildPhase2["STARTING_BUILDER"] = "starting_builder";
|
|
6245
|
+
ImageBuildPhase2["EXECUTING"] = "executing";
|
|
6246
|
+
ImageBuildPhase2["SNAPSHOTTING"] = "snapshotting";
|
|
6247
|
+
ImageBuildPhase2["PUBLISHING"] = "publishing";
|
|
6248
|
+
ImageBuildPhase2["FINISHED"] = "finished";
|
|
6249
|
+
ImageBuildPhase2["UNKNOWN"] = "unknown";
|
|
6250
|
+
return ImageBuildPhase2;
|
|
6251
|
+
})(ImageBuildPhase || {});
|
|
6252
|
+
ImageBuildKind = /* @__PURE__ */ ((ImageBuildKind2) => {
|
|
6253
|
+
ImageBuildKind2["DOCKERFILE"] = "dockerfile";
|
|
6254
|
+
ImageBuildKind2["IMPORT"] = "import";
|
|
6255
|
+
ImageBuildKind2["DIRECT"] = "direct";
|
|
6256
|
+
ImageBuildKind2["UNKNOWN"] = "unknown";
|
|
6257
|
+
return ImageBuildKind2;
|
|
6258
|
+
})(ImageBuildKind || {});
|
|
6259
|
+
ImageBuildCancellationOutcome = /* @__PURE__ */ ((ImageBuildCancellationOutcome2) => {
|
|
6260
|
+
ImageBuildCancellationOutcome2["CANCELLED"] = "cancelled";
|
|
6261
|
+
ImageBuildCancellationOutcome2["ALREADY_CANCELLED"] = "already_cancelled";
|
|
6262
|
+
ImageBuildCancellationOutcome2["ALREADY_COMPLETED"] = "already_completed";
|
|
6263
|
+
ImageBuildCancellationOutcome2["ALREADY_FAILED"] = "already_failed";
|
|
6264
|
+
ImageBuildCancellationOutcome2["NOT_ADMITTED"] = "not_admitted";
|
|
6265
|
+
ImageBuildCancellationOutcome2["UNCONFIRMED"] = "unconfirmed";
|
|
6266
|
+
ImageBuildCancellationOutcome2["UNKNOWN"] = "unknown";
|
|
6267
|
+
return ImageBuildCancellationOutcome2;
|
|
6268
|
+
})(ImageBuildCancellationOutcome || {});
|
|
6269
|
+
ImageBuildErrorCode = /* @__PURE__ */ ((ImageBuildErrorCode2) => {
|
|
6270
|
+
ImageBuildErrorCode2["USAGE"] = "usage";
|
|
6271
|
+
ImageBuildErrorCode2["AUTH"] = "auth";
|
|
6272
|
+
ImageBuildErrorCode2["NOT_FOUND"] = "not_found";
|
|
6273
|
+
ImageBuildErrorCode2["IMAGE_BUILD_IN_PROGRESS"] = "image_build_in_progress";
|
|
6274
|
+
ImageBuildErrorCode2["CLIENT_REQUEST_ID_MISMATCH"] = "client_request_id_mismatch";
|
|
6275
|
+
ImageBuildErrorCode2["FAILED"] = "failed";
|
|
6276
|
+
ImageBuildErrorCode2["CANCELLED"] = "cancelled";
|
|
6277
|
+
ImageBuildErrorCode2["TIMEOUT"] = "timeout";
|
|
6278
|
+
ImageBuildErrorCode2["INTERRUPTED"] = "interrupted";
|
|
6279
|
+
ImageBuildErrorCode2["SERVICE"] = "service";
|
|
6280
|
+
ImageBuildErrorCode2["INTERNAL"] = "internal";
|
|
6281
|
+
ImageBuildErrorCode2["UNKNOWN"] = "unknown";
|
|
6282
|
+
return ImageBuildErrorCode2;
|
|
6283
|
+
})(ImageBuildErrorCode || {});
|
|
6284
|
+
ImageBuildError = class extends Error {
|
|
6285
|
+
code;
|
|
6286
|
+
buildId;
|
|
6287
|
+
clientRequestId;
|
|
6288
|
+
details;
|
|
6289
|
+
constructor(details) {
|
|
6290
|
+
super(details.message);
|
|
6291
|
+
this.name = "ImageBuildError";
|
|
6292
|
+
this.code = details.code;
|
|
6293
|
+
this.details = { ...details };
|
|
6294
|
+
withRaw(this, {});
|
|
6295
|
+
if ("confirmed" in details) {
|
|
6296
|
+
this.details.confirmed = details.confirmed === true && isConfirmedCancellation(details.outcome);
|
|
6297
|
+
}
|
|
6298
|
+
if (details.buildId) this.buildId = details.buildId;
|
|
6299
|
+
if (details.clientRequestId) this.clientRequestId = details.clientRequestId;
|
|
6300
|
+
}
|
|
6301
|
+
};
|
|
6302
|
+
ImageBuildNotFoundError = class extends ImageBuildError {
|
|
6303
|
+
constructor(details) {
|
|
6304
|
+
super(details);
|
|
6305
|
+
this.name = "ImageBuildNotFoundError";
|
|
6306
|
+
}
|
|
6307
|
+
};
|
|
6308
|
+
ImageBuildInProgressError = class extends ImageBuildError {
|
|
6309
|
+
imageName;
|
|
6310
|
+
activeBuildId;
|
|
6311
|
+
activeKind;
|
|
6312
|
+
activeStatus;
|
|
6313
|
+
constructor(details) {
|
|
6314
|
+
super(details);
|
|
6315
|
+
this.name = "ImageBuildInProgressError";
|
|
6316
|
+
if (details.imageName) this.imageName = details.imageName;
|
|
6317
|
+
if (details.activeBuildId) this.activeBuildId = details.activeBuildId;
|
|
6318
|
+
if (details.activeKind) this.activeKind = details.activeKind;
|
|
6319
|
+
if (details.activeStatus) this.activeStatus = details.activeStatus;
|
|
6320
|
+
}
|
|
6321
|
+
};
|
|
6322
|
+
ImageBuildFailedError = class extends ImageBuildError {
|
|
6323
|
+
error;
|
|
6324
|
+
info;
|
|
6325
|
+
constructor(details) {
|
|
6326
|
+
super(details);
|
|
6327
|
+
this.name = "ImageBuildFailedError";
|
|
6328
|
+
this.error = details.error ?? "no error recorded";
|
|
6329
|
+
if (details.info) this.info = details.info;
|
|
6330
|
+
}
|
|
6331
|
+
};
|
|
6332
|
+
ImageBuildCancelledError = class extends ImageBuildError {
|
|
6333
|
+
info;
|
|
6334
|
+
constructor(details) {
|
|
6335
|
+
super(details);
|
|
6336
|
+
this.name = "ImageBuildCancelledError";
|
|
6337
|
+
if (details.info) this.info = details.info;
|
|
6338
|
+
}
|
|
6339
|
+
};
|
|
6340
|
+
ImageBuildTimeoutError = class extends ImageBuildError {
|
|
6341
|
+
constructor(details) {
|
|
6342
|
+
super(details);
|
|
6343
|
+
this.name = "ImageBuildTimeoutError";
|
|
6344
|
+
}
|
|
6345
|
+
};
|
|
6346
|
+
ImageBuildInterruptedError = class extends ImageBuildError {
|
|
6347
|
+
outcome;
|
|
6348
|
+
confirmed;
|
|
6349
|
+
result;
|
|
6350
|
+
constructor(details) {
|
|
6351
|
+
super(details);
|
|
6352
|
+
this.name = "ImageBuildInterruptedError";
|
|
6353
|
+
this.outcome = details.outcome ?? "unconfirmed" /* UNCONFIRMED */;
|
|
6354
|
+
this.confirmed = this.details.confirmed === true;
|
|
6355
|
+
if (details.result) this.result = details.result;
|
|
6356
|
+
}
|
|
6357
|
+
};
|
|
6358
|
+
ImageBuildHandle = class {
|
|
6359
|
+
buildId;
|
|
6360
|
+
/**
|
|
6361
|
+
* The admission's request id, when this handle started the build. Never
|
|
6362
|
+
* needed to cancel; a recovery aid for a lost admission answer.
|
|
6363
|
+
*/
|
|
6364
|
+
clientRequestId;
|
|
6365
|
+
#info;
|
|
6366
|
+
#credentials;
|
|
6367
|
+
/** @internal */
|
|
6368
|
+
constructor(info, credentials, clientRequestId) {
|
|
6369
|
+
this.buildId = info.buildId;
|
|
6370
|
+
this.clientRequestId = clientRequestId ?? info.clientRequestId ?? null;
|
|
6371
|
+
this.#info = info;
|
|
6372
|
+
this.#credentials = credentials;
|
|
6373
|
+
}
|
|
6374
|
+
/** The last observed state. */
|
|
6375
|
+
get info() {
|
|
6376
|
+
return this.#info;
|
|
6377
|
+
}
|
|
6378
|
+
/** Re-read the current state. */
|
|
6379
|
+
async refresh() {
|
|
6380
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6381
|
+
let json;
|
|
6382
|
+
try {
|
|
6383
|
+
json = await binding.getImageBuild(clientOptions(this.#credentials), this.buildId);
|
|
6384
|
+
} catch (error) {
|
|
6385
|
+
throw toImageBuildError(error);
|
|
6386
|
+
}
|
|
6387
|
+
this.#info = parseBuildInfo(json);
|
|
6388
|
+
return this.#info;
|
|
6389
|
+
}
|
|
6390
|
+
/**
|
|
6391
|
+
* Wait for publication and return this build's immutable result. See
|
|
6392
|
+
* {@link ImageBuildWaitOptions} for the timeout/abort distinction.
|
|
6393
|
+
*/
|
|
6394
|
+
async wait(options = {}) {
|
|
6395
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6396
|
+
const emitter = makeEmitter(options);
|
|
6397
|
+
const json = await __runWithInterrupt(
|
|
6398
|
+
options.signal,
|
|
6399
|
+
(interruptId) => binding.waitImageBuild(
|
|
6400
|
+
clientOptions(this.#credentials),
|
|
6401
|
+
this.buildId,
|
|
6402
|
+
{ timeoutMs: options.timeoutMs, followLogs: options.followLogs ?? false },
|
|
6403
|
+
emitter.forward,
|
|
6404
|
+
interruptId
|
|
6405
|
+
)
|
|
6406
|
+
);
|
|
6407
|
+
emitter.rethrow();
|
|
6408
|
+
const raw = decodeResponse(json);
|
|
6409
|
+
const result = camelizeRecord(raw);
|
|
6410
|
+
this.#info = withRaw(
|
|
6411
|
+
{ ...this.#info, status: "succeeded" /* SUCCEEDED */, result },
|
|
6412
|
+
{ ...this.#info.raw, status: "succeeded", result: raw }
|
|
6413
|
+
);
|
|
6414
|
+
return result;
|
|
6415
|
+
}
|
|
6416
|
+
/** Cancel this build by its id (the sufficient selector). */
|
|
6417
|
+
async cancel() {
|
|
6418
|
+
return cancelImageBuildWith(this.#credentials, { buildId: this.buildId });
|
|
6419
|
+
}
|
|
6420
|
+
};
|
|
6421
|
+
}
|
|
6422
|
+
});
|
|
6423
|
+
|
|
6422
6424
|
// src/sandbox-image.ts
|
|
6423
6425
|
var sandbox_image_exports = {};
|
|
6424
6426
|
__export(sandbox_image_exports, {
|
|
6427
|
+
__imageBuildInternals: () => __imageBuildInternals,
|
|
6425
6428
|
__setNativeBindingForTest: () => __setNativeBindingForTest,
|
|
6426
6429
|
buildContextFromEnv: () => buildContextFromEnv,
|
|
6427
6430
|
createSandboxImage: () => createSandboxImage,
|
|
6428
6431
|
deleteSandboxImage: () => deleteSandboxImage,
|
|
6432
|
+
deleteSandboxImageWithCredentials: () => deleteSandboxImageWithCredentials,
|
|
6429
6433
|
findSandboxImageByName: () => findSandboxImageByName,
|
|
6434
|
+
findSandboxImageByNameWithCredentials: () => findSandboxImageByNameWithCredentials,
|
|
6430
6435
|
importSandboxImage: () => importSandboxImage,
|
|
6431
6436
|
listSandboxImages: () => listSandboxImages,
|
|
6437
|
+
listSandboxImagesWithCredentials: () => listSandboxImagesWithCredentials,
|
|
6432
6438
|
runCreateSandboxImageCli: () => runCreateSandboxImageCli,
|
|
6433
6439
|
runImportSandboxImageCli: () => runImportSandboxImageCli
|
|
6434
6440
|
});
|
|
6435
|
-
import
|
|
6436
|
-
import
|
|
6437
|
-
import { existsSync as
|
|
6441
|
+
import path4 from "path";
|
|
6442
|
+
import os2 from "os";
|
|
6443
|
+
import { existsSync as existsSync3, mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "fs";
|
|
6438
6444
|
import { parseArgs } from "util";
|
|
6439
6445
|
function loadNativeBinding() {
|
|
6440
6446
|
if (cachedNativeBinding) return cachedNativeBinding;
|
|
@@ -6468,9 +6474,9 @@ function buildContextFromEnv() {
|
|
|
6468
6474
|
};
|
|
6469
6475
|
}
|
|
6470
6476
|
function defaultRegisteredName(dockerfilePath) {
|
|
6471
|
-
const parsed =
|
|
6477
|
+
const parsed = path4.parse(dockerfilePath);
|
|
6472
6478
|
if (parsed.name.toLowerCase() === "dockerfile") {
|
|
6473
|
-
const parentName =
|
|
6479
|
+
const parentName = path4.basename(path4.dirname(dockerfilePath)).trim();
|
|
6474
6480
|
return parentName || "sandbox-image";
|
|
6475
6481
|
}
|
|
6476
6482
|
return parsed.name || "sandbox-image";
|
|
@@ -6506,6 +6512,15 @@ function eventToEmitDict(event) {
|
|
|
6506
6512
|
message: event.message
|
|
6507
6513
|
};
|
|
6508
6514
|
if (event.stream != null) out.stream = event.stream;
|
|
6515
|
+
if (event.buildId != null) out.build_id = event.buildId;
|
|
6516
|
+
if (event.clientRequestId !== void 0 && event.eventType !== "status") {
|
|
6517
|
+
out.client_request_id = event.clientRequestId;
|
|
6518
|
+
}
|
|
6519
|
+
if (event.status != null) out.status = event.status;
|
|
6520
|
+
if (event.phase !== void 0 && event.eventType.startsWith("build_")) out.phase = event.phase;
|
|
6521
|
+
if (event.attempt != null) out.attempt = event.attempt;
|
|
6522
|
+
if (event.outcome != null) out.outcome = event.outcome;
|
|
6523
|
+
if (event.confirmed != null) out.confirmed = event.confirmed;
|
|
6509
6524
|
return out;
|
|
6510
6525
|
}
|
|
6511
6526
|
function runOpMountsContext(op) {
|
|
@@ -6560,24 +6575,24 @@ async function createSandboxImage(source, options = {}, deps = {}) {
|
|
|
6560
6575
|
}
|
|
6561
6576
|
let resolvedContext;
|
|
6562
6577
|
if (options.contextDir != null) {
|
|
6563
|
-
resolvedContext =
|
|
6578
|
+
resolvedContext = path4.resolve(options.contextDir);
|
|
6564
6579
|
} else if (imageRequiresContext(source)) {
|
|
6565
6580
|
throw new Error(
|
|
6566
6581
|
"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>`."
|
|
6567
6582
|
);
|
|
6568
6583
|
} else {
|
|
6569
|
-
tempContextDir =
|
|
6584
|
+
tempContextDir = mkdtempSync2(path4.join(os2.tmpdir(), "tl-build-context-"));
|
|
6570
6585
|
resolvedContext = tempContextDir;
|
|
6571
6586
|
}
|
|
6572
|
-
dockerfilePath =
|
|
6587
|
+
dockerfilePath = path4.join(resolvedContext, "Dockerfile");
|
|
6573
6588
|
let text = dockerfileContent(source);
|
|
6574
6589
|
if (!text.endsWith("\n")) text += "\n";
|
|
6575
6590
|
dockerfileText = text;
|
|
6576
6591
|
nativeContextDir = resolvedContext;
|
|
6577
6592
|
effectiveName = options.registeredName ?? source.name;
|
|
6578
6593
|
} else if (typeof source === "string") {
|
|
6579
|
-
const resolvedPath =
|
|
6580
|
-
if (!
|
|
6594
|
+
const resolvedPath = path4.resolve(source);
|
|
6595
|
+
if (!existsSync3(resolvedPath)) {
|
|
6581
6596
|
throw new Error(`Dockerfile not found: ${source}`);
|
|
6582
6597
|
}
|
|
6583
6598
|
dockerfilePath = resolvedPath;
|
|
@@ -6607,38 +6622,47 @@ async function createSandboxImage(source, options = {}, deps = {}) {
|
|
|
6607
6622
|
deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
|
|
6608
6623
|
);
|
|
6609
6624
|
}
|
|
6625
|
+
if (options.signal !== void 0 && !options.cas) {
|
|
6626
|
+
throw new Error(
|
|
6627
|
+
"signal is only supported for CAS image builds (cas: true); a legacy build has no Image Service build operation to cancel"
|
|
6628
|
+
);
|
|
6629
|
+
}
|
|
6610
6630
|
emit({ type: "status", message: `Building image '${effectiveName}'...` });
|
|
6611
6631
|
const binding = loadNativeBinding();
|
|
6612
6632
|
let emitError;
|
|
6613
|
-
const
|
|
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
|
-
|
|
6639
|
-
|
|
6633
|
+
const nativeOptions = {
|
|
6634
|
+
apiUrl: context.apiUrl,
|
|
6635
|
+
bearerToken,
|
|
6636
|
+
dockerfilePath,
|
|
6637
|
+
registeredName: effectiveName,
|
|
6638
|
+
diskMb: options.diskMb,
|
|
6639
|
+
builderDiskMb: options.builderDiskMb,
|
|
6640
|
+
cpus: options.cpus,
|
|
6641
|
+
memoryMb: options.memoryMb,
|
|
6642
|
+
isPublic: options.isPublic ?? false,
|
|
6643
|
+
organizationId: usePat ? context.organizationId : void 0,
|
|
6644
|
+
projectId: usePat ? context.projectId : void 0,
|
|
6645
|
+
namespace: context.namespace,
|
|
6646
|
+
useScopeHeaders: usePat,
|
|
6647
|
+
userAgent: void 0,
|
|
6648
|
+
dockerCompat: options.dockerCompat ?? false,
|
|
6649
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6650
|
+
dockerfileText,
|
|
6651
|
+
contextDir: nativeContextDir,
|
|
6652
|
+
cas: options.cas ?? false,
|
|
6653
|
+
buildArgs: options.buildArgs
|
|
6654
|
+
};
|
|
6655
|
+
const forward = (event) => {
|
|
6656
|
+
try {
|
|
6657
|
+
emit(eventToEmitDict(event));
|
|
6658
|
+
} catch (error) {
|
|
6659
|
+
emitError ??= error;
|
|
6640
6660
|
}
|
|
6641
|
-
|
|
6661
|
+
};
|
|
6662
|
+
const resultJson = options.cas ? await __runWithInterrupt(
|
|
6663
|
+
options.signal,
|
|
6664
|
+
(interruptId) => binding.buildSandboxImage(nativeOptions, forward, interruptId)
|
|
6665
|
+
) : await binding.buildSandboxImage(nativeOptions, forward);
|
|
6642
6666
|
if (emitError != null) {
|
|
6643
6667
|
throw emitError;
|
|
6644
6668
|
}
|
|
@@ -6655,7 +6679,7 @@ async function createSandboxImage(source, options = {}, deps = {}) {
|
|
|
6655
6679
|
return result;
|
|
6656
6680
|
} finally {
|
|
6657
6681
|
if (tempContextDir != null) {
|
|
6658
|
-
|
|
6682
|
+
rmSync2(tempContextDir, { recursive: true, force: true });
|
|
6659
6683
|
}
|
|
6660
6684
|
}
|
|
6661
6685
|
}
|
|
@@ -6684,39 +6708,47 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
|
|
|
6684
6708
|
deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
|
|
6685
6709
|
);
|
|
6686
6710
|
}
|
|
6711
|
+
if (options.signal !== void 0 && !options.cas) {
|
|
6712
|
+
throw new Error(
|
|
6713
|
+
"signal is only supported for CAS image imports (cas: true); a legacy import has no Image Service build operation to cancel"
|
|
6714
|
+
);
|
|
6715
|
+
}
|
|
6687
6716
|
emit({
|
|
6688
6717
|
type: "status",
|
|
6689
6718
|
message: `Importing image '${reference}' as '${effectiveName}'...`
|
|
6690
6719
|
});
|
|
6691
6720
|
const binding = loadNativeBinding();
|
|
6692
6721
|
let emitError;
|
|
6693
|
-
const
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
}
|
|
6722
|
+
const nativeOptions = {
|
|
6723
|
+
apiUrl: context.apiUrl,
|
|
6724
|
+
bearerToken,
|
|
6725
|
+
imageReference: reference,
|
|
6726
|
+
registeredName: effectiveName,
|
|
6727
|
+
diskMb: options.diskMb,
|
|
6728
|
+
builderDiskMb: options.builderDiskMb,
|
|
6729
|
+
cpus: options.cpus,
|
|
6730
|
+
memoryMb: options.memoryMb,
|
|
6731
|
+
isPublic: options.isPublic ?? false,
|
|
6732
|
+
organizationId: usePat ? context.organizationId : void 0,
|
|
6733
|
+
projectId: usePat ? context.projectId : void 0,
|
|
6734
|
+
namespace: context.namespace,
|
|
6735
|
+
useScopeHeaders: usePat,
|
|
6736
|
+
userAgent: void 0,
|
|
6737
|
+
dockerCompat: options.dockerCompat ?? false,
|
|
6738
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6739
|
+
cas: options.cas ?? false
|
|
6740
|
+
};
|
|
6741
|
+
const forward = (event) => {
|
|
6742
|
+
try {
|
|
6743
|
+
emit(eventToEmitDict(event));
|
|
6744
|
+
} catch (error) {
|
|
6745
|
+
emitError ??= error;
|
|
6718
6746
|
}
|
|
6719
|
-
|
|
6747
|
+
};
|
|
6748
|
+
const resultJson = options.cas ? await __runWithInterrupt(
|
|
6749
|
+
options.signal,
|
|
6750
|
+
(interruptId) => binding.importSandboxImage(nativeOptions, forward, interruptId)
|
|
6751
|
+
) : await binding.importSandboxImage(nativeOptions, forward);
|
|
6720
6752
|
if (emitError != null) {
|
|
6721
6753
|
throw emitError;
|
|
6722
6754
|
}
|
|
@@ -6732,10 +6764,7 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
|
|
|
6732
6764
|
emit({ type: "done" });
|
|
6733
6765
|
return result;
|
|
6734
6766
|
}
|
|
6735
|
-
|
|
6736
|
-
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6737
|
-
throw new TypeError("imageName must be a non-empty string");
|
|
6738
|
-
}
|
|
6767
|
+
function catalogOptionsFromEnv() {
|
|
6739
6768
|
const context = buildContextFromEnv();
|
|
6740
6769
|
const bearerToken = context.apiKey;
|
|
6741
6770
|
if (!bearerToken) {
|
|
@@ -6746,63 +6775,73 @@ async function deleteSandboxImage(imageName) {
|
|
|
6746
6775
|
}
|
|
6747
6776
|
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6748
6777
|
}
|
|
6749
|
-
|
|
6750
|
-
apiUrl: context.apiUrl,
|
|
6751
|
-
apiKey: bearerToken,
|
|
6752
|
-
namespace: context.namespace
|
|
6753
|
-
});
|
|
6754
|
-
try {
|
|
6755
|
-
await client.deleteSandboxImage(imageName);
|
|
6756
|
-
} finally {
|
|
6757
|
-
client.close();
|
|
6758
|
-
}
|
|
6778
|
+
return { apiUrl: context.apiUrl, bearerToken, useScopeHeaders: false };
|
|
6759
6779
|
}
|
|
6760
|
-
|
|
6761
|
-
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6762
|
-
throw new TypeError("imageName must be a non-empty string");
|
|
6763
|
-
}
|
|
6780
|
+
function catalogOptionsFromCredentials(credentials) {
|
|
6764
6781
|
const context = buildContextFromEnv();
|
|
6765
|
-
const bearerToken = context.apiKey;
|
|
6782
|
+
const bearerToken = credentials.apiKey ?? context.apiKey;
|
|
6766
6783
|
if (!bearerToken) {
|
|
6767
|
-
if (context.personalAccessToken) {
|
|
6768
|
-
throw new Error(
|
|
6769
|
-
"Sandbox image SDKs require TENSORLAKE_API_KEY. Personal access tokens are CLI-only."
|
|
6770
|
-
);
|
|
6771
|
-
}
|
|
6772
6784
|
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6773
6785
|
}
|
|
6774
|
-
const
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
namespace: context.namespace
|
|
6778
|
-
});
|
|
6779
|
-
try {
|
|
6780
|
-
return await client.findSandboxImageByName(imageName);
|
|
6781
|
-
} finally {
|
|
6782
|
-
client.close();
|
|
6786
|
+
const { organizationId, projectId } = credentials;
|
|
6787
|
+
if (organizationId === void 0 !== (projectId === void 0)) {
|
|
6788
|
+
throw new TypeError("organizationId and projectId must be given together");
|
|
6783
6789
|
}
|
|
6790
|
+
return {
|
|
6791
|
+
apiUrl: credentials.apiUrl ?? context.apiUrl,
|
|
6792
|
+
bearerToken,
|
|
6793
|
+
organizationId,
|
|
6794
|
+
projectId,
|
|
6795
|
+
useScopeHeaders: organizationId !== void 0
|
|
6796
|
+
};
|
|
6784
6797
|
}
|
|
6785
|
-
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
|
|
6798
|
+
function parseTemplate(json) {
|
|
6799
|
+
return JSON.parse(json);
|
|
6800
|
+
}
|
|
6801
|
+
async function deleteSandboxImage(imageName) {
|
|
6802
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6803
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6804
|
+
}
|
|
6805
|
+
await loadNativeBinding().deleteSandboxImage(catalogOptionsFromEnv(), imageName);
|
|
6806
|
+
}
|
|
6807
|
+
async function deleteSandboxImageWithCredentials(credentials, imageName) {
|
|
6808
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6809
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6810
|
+
}
|
|
6811
|
+
await loadNativeBinding().deleteSandboxImage(
|
|
6812
|
+
catalogOptionsFromCredentials(credentials),
|
|
6813
|
+
imageName
|
|
6814
|
+
);
|
|
6815
|
+
}
|
|
6816
|
+
async function findSandboxImageByName(imageName) {
|
|
6817
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6818
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6795
6819
|
}
|
|
6796
|
-
const
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6820
|
+
const json = await loadNativeBinding().findSandboxImage(
|
|
6821
|
+
catalogOptionsFromEnv(),
|
|
6822
|
+
imageName
|
|
6823
|
+
);
|
|
6824
|
+
return json == null ? null : parseTemplate(json);
|
|
6825
|
+
}
|
|
6826
|
+
async function findSandboxImageByNameWithCredentials(credentials, imageName) {
|
|
6827
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6828
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6805
6829
|
}
|
|
6830
|
+
const json = await loadNativeBinding().findSandboxImage(
|
|
6831
|
+
catalogOptionsFromCredentials(credentials),
|
|
6832
|
+
imageName
|
|
6833
|
+
);
|
|
6834
|
+
return json == null ? null : parseTemplate(json);
|
|
6835
|
+
}
|
|
6836
|
+
async function listSandboxImages() {
|
|
6837
|
+
const json = await loadNativeBinding().listSandboxImages(catalogOptionsFromEnv());
|
|
6838
|
+
return JSON.parse(json);
|
|
6839
|
+
}
|
|
6840
|
+
async function listSandboxImagesWithCredentials(credentials) {
|
|
6841
|
+
const json = await loadNativeBinding().listSandboxImages(
|
|
6842
|
+
catalogOptionsFromCredentials(credentials)
|
|
6843
|
+
);
|
|
6844
|
+
return JSON.parse(json);
|
|
6806
6845
|
}
|
|
6807
6846
|
async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
|
|
6808
6847
|
const parsed = parseArgs({
|
|
@@ -6912,15 +6951,25 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
|
|
|
6912
6951
|
{ emit: ndjsonStdoutEmit, _allowPat: true }
|
|
6913
6952
|
);
|
|
6914
6953
|
}
|
|
6915
|
-
var cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME2;
|
|
6954
|
+
var cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME2, __imageBuildInternals;
|
|
6916
6955
|
var init_sandbox_image = __esm({
|
|
6917
6956
|
"src/sandbox-image.ts"() {
|
|
6918
6957
|
"use strict";
|
|
6919
6958
|
init_esm_shims();
|
|
6920
|
-
init_cloud_client();
|
|
6921
6959
|
init_image();
|
|
6922
6960
|
init_native_binding();
|
|
6961
|
+
init_image_builds();
|
|
6923
6962
|
DEFAULT_IMAGE_NAME2 = "default";
|
|
6963
|
+
__imageBuildInternals = {
|
|
6964
|
+
loadNativeBinding: () => loadNativeBinding(),
|
|
6965
|
+
buildContextFromEnv: () => buildContextFromEnv(),
|
|
6966
|
+
stderrEmit: (event) => stderrEmit(event),
|
|
6967
|
+
noopEmit: (event) => noopEmit(event),
|
|
6968
|
+
eventToEmitDict: (event) => eventToEmitDict(event),
|
|
6969
|
+
imageRequiresContext: (image) => imageRequiresContext(image),
|
|
6970
|
+
defaultRegisteredName: (dockerfilePath) => defaultRegisteredName(dockerfilePath),
|
|
6971
|
+
defaultRegisteredNameFromImage: (reference) => defaultRegisteredNameFromImage(reference)
|
|
6972
|
+
};
|
|
6924
6973
|
}
|
|
6925
6974
|
});
|
|
6926
6975
|
|
|
@@ -6932,11 +6981,546 @@ init_pending_sandbox();
|
|
|
6932
6981
|
init_sandbox();
|
|
6933
6982
|
init_desktop();
|
|
6934
6983
|
init_tunnel();
|
|
6935
|
-
|
|
6984
|
+
|
|
6985
|
+
// src/cloud-client.ts
|
|
6986
|
+
init_esm_shims();
|
|
6987
|
+
init_defaults();
|
|
6988
|
+
import { nanoid } from "nanoid";
|
|
6989
|
+
|
|
6990
|
+
// src/native-cloud.ts
|
|
6991
|
+
init_esm_shims();
|
|
6992
|
+
init_native_sandbox();
|
|
6993
|
+
init_native_worker_client();
|
|
6994
|
+
var NativeCloudTransport = class {
|
|
6995
|
+
constructor(options) {
|
|
6996
|
+
this.options = options;
|
|
6997
|
+
if (!Number.isSafeInteger(options.maxRetries) || options.maxRetries < 0 || options.maxRetries > 4294967295) {
|
|
6998
|
+
throw new RangeError("maxRetries must be a non-negative 32-bit integer");
|
|
6999
|
+
}
|
|
7000
|
+
if (!Number.isFinite(options.retryBackoffMs) || options.retryBackoffMs < 0) {
|
|
7001
|
+
throw new RangeError("retryBackoffMs must be a non-negative finite number");
|
|
7002
|
+
}
|
|
7003
|
+
}
|
|
7004
|
+
native;
|
|
7005
|
+
closed = false;
|
|
7006
|
+
client() {
|
|
7007
|
+
if (this.closed) throw new Error("Tensorlake native client is closed");
|
|
7008
|
+
if (this.native) return this.native;
|
|
7009
|
+
const ctor = loadNativeSandboxBinding().NativeCloudClient;
|
|
7010
|
+
if (!ctor) throw new Error("Native binding does not export NativeCloudClient; rebuild with 'npm run build:native'");
|
|
7011
|
+
return this.native = new ctor(JSON.stringify(this.options));
|
|
7012
|
+
}
|
|
7013
|
+
close() {
|
|
7014
|
+
this.closed = true;
|
|
7015
|
+
releaseNativeHandle(this.native ?? null);
|
|
7016
|
+
this.native = void 0;
|
|
7017
|
+
}
|
|
7018
|
+
async requestResponse(method, path5, options) {
|
|
7019
|
+
const request = await serializeRequest(method, path5, options);
|
|
7020
|
+
const raw = await callNative(() => this.client().request(request));
|
|
7021
|
+
const response = new Response(
|
|
7022
|
+
[204, 205, 304].includes(raw.status) ? null : Uint8Array.from(raw.data).buffer,
|
|
7023
|
+
{ status: raw.status, headers: JSON.parse(raw.headersJson) }
|
|
7024
|
+
);
|
|
7025
|
+
return Object.assign(response, { traceId: raw.traceId });
|
|
7026
|
+
}
|
|
7027
|
+
async requestJson(method, path5) {
|
|
7028
|
+
const response = await this.requestResponse(method, path5);
|
|
7029
|
+
const text = await response.text();
|
|
7030
|
+
const value = text ? JSON.parse(text) : null;
|
|
7031
|
+
return Object.assign(value ?? {}, { traceId: response.traceId });
|
|
7032
|
+
}
|
|
7033
|
+
async *stream(method, path5, signal) {
|
|
7034
|
+
if (signal?.aborted) return;
|
|
7035
|
+
const request = await serializeRequest(method, path5, { headers: { Accept: "text/event-stream" } });
|
|
7036
|
+
yield* nativeEventStream((emit) => this.client().stream(request, emit), void 0, signal);
|
|
7037
|
+
}
|
|
7038
|
+
};
|
|
7039
|
+
async function serializeRequest(method, path5, options) {
|
|
7040
|
+
const headers = { ...options?.headers };
|
|
7041
|
+
let body = options?.body;
|
|
7042
|
+
if (options?.json !== void 0) {
|
|
7043
|
+
body = JSON.stringify(options.json);
|
|
7044
|
+
if (!Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) {
|
|
7045
|
+
headers["Content-Type"] = "application/json";
|
|
7046
|
+
}
|
|
7047
|
+
}
|
|
7048
|
+
const request = {
|
|
7049
|
+
method,
|
|
7050
|
+
path: path5,
|
|
7051
|
+
headersJson: JSON.stringify(headers),
|
|
7052
|
+
statusOnlyCodes: [...options?.statusOnlyCodes ?? []]
|
|
7053
|
+
};
|
|
7054
|
+
if (body instanceof FormData) {
|
|
7055
|
+
request.parts = [];
|
|
7056
|
+
for (const [name, value] of body.entries()) {
|
|
7057
|
+
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" });
|
|
7058
|
+
}
|
|
7059
|
+
} else if (body !== void 0) {
|
|
7060
|
+
if (body instanceof Blob) request.body = Buffer.from(await body.arrayBuffer());
|
|
7061
|
+
else if (typeof body === "string") request.body = Buffer.from(body);
|
|
7062
|
+
else if (body instanceof ArrayBuffer) request.body = Buffer.from(new Uint8Array(body));
|
|
7063
|
+
else request.body = Buffer.from(body);
|
|
7064
|
+
}
|
|
7065
|
+
return request;
|
|
7066
|
+
}
|
|
7067
|
+
|
|
7068
|
+
// src/cloud-client.ts
|
|
7069
|
+
init_models();
|
|
7070
|
+
init_sandbox_image();
|
|
7071
|
+
var CloudClient = class _CloudClient {
|
|
7072
|
+
transport;
|
|
7073
|
+
apiUrl;
|
|
7074
|
+
apiKey;
|
|
7075
|
+
organizationId;
|
|
7076
|
+
projectId;
|
|
7077
|
+
namespace;
|
|
7078
|
+
constructor(options) {
|
|
7079
|
+
this.apiUrl = options?.apiUrl ?? API_URL;
|
|
7080
|
+
this.apiKey = options?.apiKey ?? API_KEY;
|
|
7081
|
+
this.organizationId = options?.organizationId;
|
|
7082
|
+
this.projectId = options?.projectId;
|
|
7083
|
+
this.namespace = options?.namespace ?? NAMESPACE;
|
|
7084
|
+
this.transport = new NativeCloudTransport({
|
|
7085
|
+
baseUrl: options?.apiUrl ?? API_URL,
|
|
7086
|
+
apiKey: options?.apiKey ?? API_KEY,
|
|
7087
|
+
organizationId: this.organizationId,
|
|
7088
|
+
projectId: this.projectId,
|
|
7089
|
+
maxRetries: options?.maxRetries ?? MAX_RETRIES,
|
|
7090
|
+
retryBackoffMs: options?.retryBackoffMs ?? RETRY_BACKOFF_MS,
|
|
7091
|
+
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
7092
|
+
userAgent: `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
7093
|
+
});
|
|
7094
|
+
}
|
|
7095
|
+
static forCloud(options) {
|
|
7096
|
+
return new _CloudClient(options);
|
|
7097
|
+
}
|
|
7098
|
+
close() {
|
|
7099
|
+
this.transport.close();
|
|
7100
|
+
}
|
|
7101
|
+
async upsertApplication(manifest, codeZip, upgradeRunningRequests = false) {
|
|
7102
|
+
const applicationManifest = { ...manifest };
|
|
7103
|
+
let publicEndpointId = publicEndpointIdFromManifest(applicationManifest);
|
|
7104
|
+
if (applicationAllowsUnauthenticatedRequests(applicationManifest) && publicEndpointId === void 0) {
|
|
7105
|
+
const applicationName = applicationManifest.name;
|
|
7106
|
+
if (typeof applicationName === "string" && applicationName.length > 0) {
|
|
7107
|
+
publicEndpointId = await this.existingApplicationPublicEndpointId(applicationName);
|
|
7108
|
+
}
|
|
7109
|
+
publicEndpointId ??= generatePublicEndpointId();
|
|
7110
|
+
}
|
|
7111
|
+
if (publicEndpointId !== void 0) {
|
|
7112
|
+
applicationManifest.public_endpoint_id = publicEndpointId;
|
|
7113
|
+
delete applicationManifest.publicEndpointId;
|
|
7114
|
+
}
|
|
7115
|
+
const form = new FormData();
|
|
7116
|
+
form.append(
|
|
7117
|
+
"code",
|
|
7118
|
+
new Blob([toBlobPart(codeZip)], { type: "application/zip" }),
|
|
7119
|
+
"code.zip"
|
|
7120
|
+
);
|
|
7121
|
+
form.append("code_content_type", "application/zip");
|
|
7122
|
+
form.append("application", JSON.stringify(applicationManifest));
|
|
7123
|
+
form.append(
|
|
7124
|
+
"upgrade_requests_to_latest_code",
|
|
7125
|
+
String(upgradeRunningRequests)
|
|
7126
|
+
);
|
|
7127
|
+
await this.transport.requestResponse("POST", this.namespacePath("applications"), {
|
|
7128
|
+
body: form
|
|
7129
|
+
});
|
|
7130
|
+
}
|
|
7131
|
+
async deleteApplication(applicationName) {
|
|
7132
|
+
await this.transport.requestResponse(
|
|
7133
|
+
"DELETE",
|
|
7134
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
7135
|
+
);
|
|
7136
|
+
}
|
|
7137
|
+
/**
|
|
7138
|
+
* Delete a registered sandbox image by name or id through the merged
|
|
7139
|
+
* catalog, with this client's credentials: an `image_` id or a name the
|
|
7140
|
+
* Image Service knows deletes a CAS image, a `sandbox_template_` id or a
|
|
7141
|
+
* name registered only in the platform registry deletes a legacy image.
|
|
7142
|
+
* Rejects when neither catalog knows the reference. The same semantics
|
|
7143
|
+
* and accepted differences as the module-level `deleteSandboxImage`.
|
|
7144
|
+
*/
|
|
7145
|
+
async deleteSandboxImage(imageName) {
|
|
7146
|
+
await deleteSandboxImageWithCredentials(this.catalogCredentials(), imageName);
|
|
7147
|
+
}
|
|
7148
|
+
/**
|
|
7149
|
+
* Look up a registered sandbox image by name or id through the merged
|
|
7150
|
+
* catalog, with this client's credentials. Returns the image in the
|
|
7151
|
+
* sandbox-template shape, or `null` when neither the Image Service nor the
|
|
7152
|
+
* platform registry knows the reference. An explicit organization/project
|
|
7153
|
+
* scope (the client's, or the call's override) addresses that project's
|
|
7154
|
+
* routes directly, as before; without one the key's own scope applies.
|
|
7155
|
+
*/
|
|
7156
|
+
async findSandboxImageByName(imageName, options) {
|
|
7157
|
+
return findSandboxImageByNameWithCredentials(
|
|
7158
|
+
this.catalogCredentials(options),
|
|
7159
|
+
imageName
|
|
7160
|
+
);
|
|
7161
|
+
}
|
|
7162
|
+
/**
|
|
7163
|
+
* List every registered sandbox image of the project (CAS and legacy, in
|
|
7164
|
+
* the sandbox-template shape, newest first) through the merged catalog,
|
|
7165
|
+
* with this client's credentials. An explicit organization/project scope
|
|
7166
|
+
* (the client's, or the call's override) addresses that project's routes
|
|
7167
|
+
* directly, as before; without one the key's own scope applies.
|
|
7168
|
+
*/
|
|
7169
|
+
async listSandboxImages(options) {
|
|
7170
|
+
return listSandboxImagesWithCredentials(this.catalogCredentials(options));
|
|
7171
|
+
}
|
|
7172
|
+
catalogCredentials(options) {
|
|
7173
|
+
return {
|
|
7174
|
+
apiUrl: this.apiUrl,
|
|
7175
|
+
apiKey: this.apiKey,
|
|
7176
|
+
organizationId: options?.organizationId ?? this.organizationId,
|
|
7177
|
+
projectId: options?.projectId ?? this.projectId
|
|
7178
|
+
};
|
|
7179
|
+
}
|
|
7180
|
+
async applications() {
|
|
7181
|
+
const raw = await this.transport.requestJson(
|
|
7182
|
+
"GET",
|
|
7183
|
+
this.namespacePath("applications")
|
|
7184
|
+
);
|
|
7185
|
+
return (raw.applications ?? []).map(
|
|
7186
|
+
(application) => fromSnakeKeys(application)
|
|
7187
|
+
);
|
|
7188
|
+
}
|
|
7189
|
+
async applicationManifest(applicationName) {
|
|
7190
|
+
const raw = await this.transport.requestJson(
|
|
7191
|
+
"GET",
|
|
7192
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
7193
|
+
);
|
|
7194
|
+
return fromSnakeKeys(raw);
|
|
7195
|
+
}
|
|
7196
|
+
async runRequest(applicationName, inputs = []) {
|
|
7197
|
+
const path5 = this.namespacePath(
|
|
7198
|
+
`applications/${encodeURIComponent(applicationName)}`
|
|
7199
|
+
);
|
|
7200
|
+
const response = inputs.length === 0 ? await this.transport.requestResponse("POST", path5, {
|
|
7201
|
+
body: new Uint8Array(),
|
|
7202
|
+
headers: { Accept: "application/json" }
|
|
7203
|
+
}) : inputs.length === 1 && inputs[0].name === "0" ? await this.transport.requestResponse("POST", path5, {
|
|
7204
|
+
body: toRequestBody(inputs[0].data),
|
|
7205
|
+
headers: {
|
|
7206
|
+
Accept: "application/json",
|
|
7207
|
+
"Content-Type": inputs[0].contentType
|
|
7208
|
+
}
|
|
7209
|
+
}) : await this.runMultipartRequest(path5, inputs);
|
|
7210
|
+
const body = await parseJsonResponse(response);
|
|
7211
|
+
const requestId = body?.request_id;
|
|
7212
|
+
if (!requestId) {
|
|
7213
|
+
throw new Error("missing request_id in run request response body");
|
|
7214
|
+
}
|
|
7215
|
+
return requestId;
|
|
7216
|
+
}
|
|
7217
|
+
async waitOnRequestCompletion(applicationName, requestId) {
|
|
7218
|
+
const stream = this.transport.stream(
|
|
7219
|
+
"GET",
|
|
7220
|
+
this.namespacePath(
|
|
7221
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/progress`
|
|
7222
|
+
)
|
|
7223
|
+
);
|
|
7224
|
+
for await (const event of stream) {
|
|
7225
|
+
if (Object.prototype.hasOwnProperty.call(event, "RequestFinished")) {
|
|
7226
|
+
return;
|
|
7227
|
+
}
|
|
7228
|
+
}
|
|
7229
|
+
throw new Error("progress stream ended before request completion");
|
|
7230
|
+
}
|
|
7231
|
+
async requestMetadata(applicationName, requestId) {
|
|
7232
|
+
const raw = await this.transport.requestJson(
|
|
7233
|
+
"GET",
|
|
7234
|
+
this.namespacePath(
|
|
7235
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}`
|
|
7236
|
+
)
|
|
7237
|
+
);
|
|
7238
|
+
return fromSnakeKeys(raw);
|
|
7239
|
+
}
|
|
7240
|
+
async requestOutput(applicationName, requestId) {
|
|
7241
|
+
const response = await this.transport.requestResponse(
|
|
7242
|
+
"GET",
|
|
7243
|
+
this.namespacePath(
|
|
7244
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/output`
|
|
7245
|
+
)
|
|
7246
|
+
);
|
|
7247
|
+
const serializedValue = new Uint8Array(await response.arrayBuffer());
|
|
7248
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
7249
|
+
return {
|
|
7250
|
+
serializedValue,
|
|
7251
|
+
contentType
|
|
7252
|
+
};
|
|
7253
|
+
}
|
|
7254
|
+
async listSecrets(options) {
|
|
7255
|
+
const base = this.secretCollectionPath(
|
|
7256
|
+
options?.organizationId,
|
|
7257
|
+
options?.projectId
|
|
7258
|
+
);
|
|
7259
|
+
const raw = await this.transport.requestJson("GET", base);
|
|
7260
|
+
const pageSize = Math.max(0, options?.pageSize ?? 100);
|
|
7261
|
+
return Object.assign(
|
|
7262
|
+
{
|
|
7263
|
+
items: raw.slice(0, pageSize).map(secretFromMetadata),
|
|
7264
|
+
pagination: { total: raw.length }
|
|
7265
|
+
},
|
|
7266
|
+
{ traceId: raw.traceId }
|
|
7267
|
+
);
|
|
7268
|
+
}
|
|
7269
|
+
async getSecret(secretId, options) {
|
|
7270
|
+
const base = this.secretCollectionPath(
|
|
7271
|
+
options?.organizationId,
|
|
7272
|
+
options?.projectId
|
|
7273
|
+
);
|
|
7274
|
+
const raw = await this.transport.requestJson(
|
|
7275
|
+
"GET",
|
|
7276
|
+
`${base}/${encodeURIComponent(secretId)}`
|
|
7277
|
+
);
|
|
7278
|
+
return Object.assign(secretFromMetadata(raw), { traceId: raw.traceId });
|
|
7279
|
+
}
|
|
7280
|
+
async upsertSecrets(secrets, options) {
|
|
7281
|
+
const base = this.secretCollectionPath(
|
|
7282
|
+
options?.organizationId,
|
|
7283
|
+
options?.projectId
|
|
7284
|
+
);
|
|
7285
|
+
if (Array.isArray(secrets)) {
|
|
7286
|
+
const results = [];
|
|
7287
|
+
for (const secret of secrets) {
|
|
7288
|
+
results.push(await this.upsertSecret(base, secret));
|
|
7289
|
+
}
|
|
7290
|
+
return results;
|
|
7291
|
+
}
|
|
7292
|
+
return this.upsertSecret(base, secrets);
|
|
7293
|
+
}
|
|
7294
|
+
async deleteSecret(secretId, options) {
|
|
7295
|
+
const base = this.secretCollectionPath(
|
|
7296
|
+
options?.organizationId,
|
|
7297
|
+
options?.projectId
|
|
7298
|
+
);
|
|
7299
|
+
await this.transport.requestResponse(
|
|
7300
|
+
"DELETE",
|
|
7301
|
+
`${base}/${encodeURIComponent(secretId)}`
|
|
7302
|
+
);
|
|
7303
|
+
}
|
|
7304
|
+
async upsertSecret(base, secret) {
|
|
7305
|
+
let response = await this.transport.requestResponse("POST", base, {
|
|
7306
|
+
json: secret,
|
|
7307
|
+
headers: { "Idempotency-Key": nanoid() },
|
|
7308
|
+
statusOnlyCodes: /* @__PURE__ */ new Set([409])
|
|
7309
|
+
});
|
|
7310
|
+
if (response.status === 409) {
|
|
7311
|
+
const prefix = base.slice(0, -"/secrets".length);
|
|
7312
|
+
const existing = await this.transport.requestJson(
|
|
7313
|
+
"GET",
|
|
7314
|
+
`${prefix}/secret-names/${encodeURIComponent(secret.name)}`
|
|
7315
|
+
);
|
|
7316
|
+
response = await this.transport.requestResponse(
|
|
7317
|
+
"POST",
|
|
7318
|
+
`${base}/${encodeURIComponent(existing.id)}/versions`,
|
|
7319
|
+
{
|
|
7320
|
+
json: { value: secret.value },
|
|
7321
|
+
headers: { "Idempotency-Key": nanoid() }
|
|
7322
|
+
}
|
|
7323
|
+
);
|
|
7324
|
+
}
|
|
7325
|
+
const metadata = await parseJsonResponse(response);
|
|
7326
|
+
return Object.assign(secretFromMetadata(metadata), {
|
|
7327
|
+
traceId: response.traceId
|
|
7328
|
+
});
|
|
7329
|
+
}
|
|
7330
|
+
async startImageBuild(buildServicePath, request) {
|
|
7331
|
+
const form = new FormData();
|
|
7332
|
+
form.append("graph_name", request.applicationName);
|
|
7333
|
+
form.append("graph_version", request.applicationVersion);
|
|
7334
|
+
form.append("graph_function_name", request.functionName);
|
|
7335
|
+
form.append("image_name", request.imageName);
|
|
7336
|
+
form.append("image_id", request.imageId);
|
|
7337
|
+
form.append(
|
|
7338
|
+
"context",
|
|
7339
|
+
new Blob([toBlobPart(request.buildContext)]),
|
|
7340
|
+
"context.tar.gz"
|
|
7341
|
+
);
|
|
7342
|
+
const response = await this.transport.requestResponse(
|
|
7343
|
+
"PUT",
|
|
7344
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds`,
|
|
7345
|
+
{ body: form }
|
|
7346
|
+
);
|
|
7347
|
+
const raw = await parseJsonResponse(response);
|
|
7348
|
+
return fromSnakeKeys(raw);
|
|
7349
|
+
}
|
|
7350
|
+
async createApplicationBuild(buildServicePath, request, imageContexts) {
|
|
7351
|
+
const form = createApplicationBuildForm(request, imageContexts);
|
|
7352
|
+
const response = await this.transport.requestResponse(
|
|
7353
|
+
"POST",
|
|
7354
|
+
trimTrailingSlashes2(buildServicePath),
|
|
7355
|
+
{ body: form }
|
|
7356
|
+
);
|
|
7357
|
+
const raw = await parseJsonResponse(response);
|
|
7358
|
+
return fromSnakeKeys(raw);
|
|
7359
|
+
}
|
|
7360
|
+
async applicationBuildInfo(buildServicePath, applicationBuildId) {
|
|
7361
|
+
const raw = await this.transport.requestJson(
|
|
7362
|
+
"GET",
|
|
7363
|
+
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}`
|
|
7364
|
+
);
|
|
7365
|
+
return fromSnakeKeys(raw);
|
|
7366
|
+
}
|
|
7367
|
+
async cancelApplicationBuild(buildServicePath, applicationBuildId) {
|
|
7368
|
+
const raw = await this.transport.requestJson(
|
|
7369
|
+
"POST",
|
|
7370
|
+
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}/cancel`
|
|
7371
|
+
);
|
|
7372
|
+
return fromSnakeKeys(raw);
|
|
7373
|
+
}
|
|
7374
|
+
async buildInfo(buildServicePath, buildId) {
|
|
7375
|
+
const raw = await this.transport.requestJson(
|
|
7376
|
+
"GET",
|
|
7377
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}`
|
|
7378
|
+
);
|
|
7379
|
+
return fromSnakeKeys(raw);
|
|
7380
|
+
}
|
|
7381
|
+
async cancelBuild(buildServicePath, buildId) {
|
|
7382
|
+
await this.transport.requestResponse(
|
|
7383
|
+
"POST",
|
|
7384
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/cancel`
|
|
7385
|
+
);
|
|
7386
|
+
}
|
|
7387
|
+
async *streamBuildLogs(buildServicePath, buildId, signal) {
|
|
7388
|
+
const stream = this.transport.stream(
|
|
7389
|
+
"GET",
|
|
7390
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/logs`,
|
|
7391
|
+
signal
|
|
7392
|
+
);
|
|
7393
|
+
for await (const event of stream) {
|
|
7394
|
+
yield fromSnakeKeys(event);
|
|
7395
|
+
}
|
|
7396
|
+
}
|
|
7397
|
+
async runMultipartRequest(path5, inputs) {
|
|
7398
|
+
const form = new FormData();
|
|
7399
|
+
for (const input of inputs) {
|
|
7400
|
+
form.append(
|
|
7401
|
+
input.name,
|
|
7402
|
+
new Blob([toBlobPart(input.data)], { type: input.contentType }),
|
|
7403
|
+
input.name
|
|
7404
|
+
);
|
|
7405
|
+
}
|
|
7406
|
+
return this.transport.requestResponse("POST", path5, {
|
|
7407
|
+
body: form,
|
|
7408
|
+
headers: { Accept: "application/json" }
|
|
7409
|
+
});
|
|
7410
|
+
}
|
|
7411
|
+
namespacePath(subpath) {
|
|
7412
|
+
return `/v1/namespaces/${encodeURIComponent(this.namespace)}/${subpath.replace(/^\/+/, "")}`;
|
|
7413
|
+
}
|
|
7414
|
+
async existingApplicationPublicEndpointId(applicationName) {
|
|
7415
|
+
const response = await this.transport.requestResponse(
|
|
7416
|
+
"GET",
|
|
7417
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`),
|
|
7418
|
+
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
7419
|
+
);
|
|
7420
|
+
if (response.status === 404) {
|
|
7421
|
+
return void 0;
|
|
7422
|
+
}
|
|
7423
|
+
const application = await parseJsonResponse(response);
|
|
7424
|
+
return publicEndpointIdFromManifest(application);
|
|
7425
|
+
}
|
|
7426
|
+
secretCollectionPath(organizationId, projectId) {
|
|
7427
|
+
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
7428
|
+
const resolvedProjectId = projectId ?? this.projectId;
|
|
7429
|
+
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
7430
|
+
return this.namespacePath("secrets");
|
|
7431
|
+
}
|
|
7432
|
+
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
7433
|
+
throw new Error("organizationId and projectId must be provided together");
|
|
7434
|
+
}
|
|
7435
|
+
return this.namespacePath("secrets");
|
|
7436
|
+
}
|
|
7437
|
+
};
|
|
7438
|
+
function secretFromMetadata(metadata) {
|
|
7439
|
+
return {
|
|
7440
|
+
id: metadata.id,
|
|
7441
|
+
name: metadata.name,
|
|
7442
|
+
createdAt: new Date(metadata.created_at_ms)
|
|
7443
|
+
};
|
|
7444
|
+
}
|
|
7445
|
+
var UNAUTHENTICATED_REQUESTS = "unauthenticated_requests";
|
|
7446
|
+
function applicationAllowsUnauthenticatedRequests(manifest) {
|
|
7447
|
+
return Array.isArray(manifest.allow) && manifest.allow.includes(UNAUTHENTICATED_REQUESTS);
|
|
7448
|
+
}
|
|
7449
|
+
function publicEndpointIdFromManifest(manifest) {
|
|
7450
|
+
for (const key of ["public_endpoint_id", "publicEndpointId"]) {
|
|
7451
|
+
const value = manifest[key];
|
|
7452
|
+
if (typeof value === "string" && value.length > 0) {
|
|
7453
|
+
return value;
|
|
7454
|
+
}
|
|
7455
|
+
}
|
|
7456
|
+
return void 0;
|
|
7457
|
+
}
|
|
7458
|
+
function generatePublicEndpointId() {
|
|
7459
|
+
return `endpoint_${nanoid()}`;
|
|
7460
|
+
}
|
|
7461
|
+
function createApplicationBuildForm(request, imageContexts) {
|
|
7462
|
+
const contextsByPartName = /* @__PURE__ */ new Map();
|
|
7463
|
+
for (const context of imageContexts) {
|
|
7464
|
+
if (contextsByPartName.has(context.contextTarPartName)) {
|
|
7465
|
+
throw new Error(
|
|
7466
|
+
`duplicate image context part name '${context.contextTarPartName}'`
|
|
7467
|
+
);
|
|
7468
|
+
}
|
|
7469
|
+
contextsByPartName.set(context.contextTarPartName, context);
|
|
7470
|
+
}
|
|
7471
|
+
const form = new FormData();
|
|
7472
|
+
form.append(
|
|
7473
|
+
"app_version",
|
|
7474
|
+
new Blob([JSON.stringify(request)], { type: "application/json" }),
|
|
7475
|
+
"app_version"
|
|
7476
|
+
);
|
|
7477
|
+
for (const image of request.images) {
|
|
7478
|
+
const context = contextsByPartName.get(image.contextTarPartName);
|
|
7479
|
+
if (!context) {
|
|
7480
|
+
throw new Error(
|
|
7481
|
+
`missing image context for part '${image.contextTarPartName}'`
|
|
7482
|
+
);
|
|
7483
|
+
}
|
|
7484
|
+
form.append(
|
|
7485
|
+
image.contextTarPartName,
|
|
7486
|
+
new Blob([toBlobPart(context.contextTarGz)]),
|
|
7487
|
+
`${image.contextTarPartName}.tar.gz`
|
|
7488
|
+
);
|
|
7489
|
+
}
|
|
7490
|
+
for (const context of imageContexts) {
|
|
7491
|
+
if (!request.images.some((image) => image.contextTarPartName === context.contextTarPartName)) {
|
|
7492
|
+
throw new Error(
|
|
7493
|
+
`unexpected image context for part '${context.contextTarPartName}'`
|
|
7494
|
+
);
|
|
7495
|
+
}
|
|
7496
|
+
}
|
|
7497
|
+
return form;
|
|
7498
|
+
}
|
|
7499
|
+
function trimTrailingSlashes2(value) {
|
|
7500
|
+
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
7501
|
+
}
|
|
7502
|
+
function toBlobPart(data) {
|
|
7503
|
+
if (typeof data === "string" || data instanceof Blob) {
|
|
7504
|
+
return data;
|
|
7505
|
+
}
|
|
7506
|
+
if (data instanceof Uint8Array) {
|
|
7507
|
+
return Uint8Array.from(data).buffer;
|
|
7508
|
+
}
|
|
7509
|
+
return data;
|
|
7510
|
+
}
|
|
7511
|
+
function toRequestBody(data) {
|
|
7512
|
+
return toBlobPart(data);
|
|
7513
|
+
}
|
|
7514
|
+
async function parseJsonResponse(response) {
|
|
7515
|
+
const text = await response.text();
|
|
7516
|
+
if (!text) {
|
|
7517
|
+
return void 0;
|
|
7518
|
+
}
|
|
7519
|
+
return JSON.parse(text);
|
|
7520
|
+
}
|
|
6936
7521
|
|
|
6937
7522
|
// src/api-client.ts
|
|
6938
7523
|
init_esm_shims();
|
|
6939
|
-
init_cloud_client();
|
|
6940
7524
|
|
|
6941
7525
|
// src/filesystem.ts
|
|
6942
7526
|
init_esm_shims();
|
|
@@ -6954,12 +7538,12 @@ import { promisify } from "util";
|
|
|
6954
7538
|
init_esm_shims();
|
|
6955
7539
|
var GIT_MODE_DIR = 16384;
|
|
6956
7540
|
var GIT_MODE_SYMLINK = 40960;
|
|
6957
|
-
function trimSlashes(
|
|
7541
|
+
function trimSlashes(path5) {
|
|
6958
7542
|
let start = 0;
|
|
6959
|
-
let end =
|
|
6960
|
-
while (start < end &&
|
|
6961
|
-
while (end > start &&
|
|
6962
|
-
return
|
|
7543
|
+
let end = path5.length;
|
|
7544
|
+
while (start < end && path5.charCodeAt(start) === 47) start += 1;
|
|
7545
|
+
while (end > start && path5.charCodeAt(end - 1) === 47) end -= 1;
|
|
7546
|
+
return path5.slice(start, end);
|
|
6963
7547
|
}
|
|
6964
7548
|
function fileEntryFromWire(entry, dirPath) {
|
|
6965
7549
|
const mode = entry.mode ?? 33188;
|
|
@@ -6977,9 +7561,9 @@ function fileEntryFromWire(entry, dirPath) {
|
|
|
6977
7561
|
}
|
|
6978
7562
|
function mountStatusFromRaw(raw, localPath) {
|
|
6979
7563
|
const mounted = "mounted" in raw ? Boolean(raw.mounted) : "active" in raw ? Boolean(raw.active) : true;
|
|
6980
|
-
const
|
|
7564
|
+
const path5 = String(raw.path || raw.mount_path || localPath || "");
|
|
6981
7565
|
const filesystem = raw.filesystem || raw.file_system || raw.repository || null;
|
|
6982
|
-
return { path:
|
|
7566
|
+
return { path: path5, filesystem, mounted, raw };
|
|
6983
7567
|
}
|
|
6984
7568
|
var FilesystemError = class extends Error {
|
|
6985
7569
|
constructor(message) {
|
|
@@ -6998,11 +7582,11 @@ var FilesystemNotFoundError = class extends FilesystemError {
|
|
|
6998
7582
|
var FileNotFoundInFilesystemError = class extends FilesystemError {
|
|
6999
7583
|
filesystem;
|
|
7000
7584
|
path;
|
|
7001
|
-
constructor(filesystem,
|
|
7002
|
-
super(`File not found in filesystem ${filesystem}: ${
|
|
7585
|
+
constructor(filesystem, path5) {
|
|
7586
|
+
super(`File not found in filesystem ${filesystem}: ${path5}`);
|
|
7003
7587
|
this.name = "FileNotFoundInFilesystemError";
|
|
7004
7588
|
this.filesystem = filesystem;
|
|
7005
|
-
this.path =
|
|
7589
|
+
this.path = path5;
|
|
7006
7590
|
}
|
|
7007
7591
|
};
|
|
7008
7592
|
var FilesystemAPIError = class extends FilesystemError {
|
|
@@ -7356,8 +7940,8 @@ var Filesystem = class {
|
|
|
7356
7940
|
}
|
|
7357
7941
|
// -- writes -------------------------------------------------------------------
|
|
7358
7942
|
/** Write one file. Returns the snapshot (version) the write produced. */
|
|
7359
|
-
async writeFile(
|
|
7360
|
-
return await this.writeFiles(/* @__PURE__ */ new Map([[
|
|
7943
|
+
async writeFile(path5, data, message) {
|
|
7944
|
+
return await this.writeFiles(/* @__PURE__ */ new Map([[path5, data]]), message);
|
|
7361
7945
|
}
|
|
7362
7946
|
/** Write several files (and/or delete paths) in one atomic snapshot. */
|
|
7363
7947
|
async writeFiles(files, message, deletes = []) {
|
|
@@ -7365,8 +7949,8 @@ var Filesystem = class {
|
|
|
7365
7949
|
if (entries.length === 0 && deletes.length === 0) {
|
|
7366
7950
|
throw new FilesystemError("nothing to write: no files or deletions given");
|
|
7367
7951
|
}
|
|
7368
|
-
const writes = entries.map(([
|
|
7369
|
-
path:
|
|
7952
|
+
const writes = entries.map(([path5, data]) => ({
|
|
7953
|
+
path: path5,
|
|
7370
7954
|
content: toBuffer(data)
|
|
7371
7955
|
}));
|
|
7372
7956
|
const resolvedMessage = message || `write ${writes.length} file(s) via SDK`;
|
|
@@ -7382,9 +7966,9 @@ var Filesystem = class {
|
|
|
7382
7966
|
* Stream one local file directly to object storage in bounded parts.
|
|
7383
7967
|
* This is the memory-bounded API for multi-GiB files.
|
|
7384
7968
|
*/
|
|
7385
|
-
async writeFileFromPath(
|
|
7969
|
+
async writeFileFromPath(path5, localPath, message) {
|
|
7386
7970
|
return await this.writeFilesFromPaths(
|
|
7387
|
-
/* @__PURE__ */ new Map([[
|
|
7971
|
+
/* @__PURE__ */ new Map([[path5, localPath]]),
|
|
7388
7972
|
message
|
|
7389
7973
|
);
|
|
7390
7974
|
}
|
|
@@ -7397,7 +7981,7 @@ var Filesystem = class {
|
|
|
7397
7981
|
if (entries.length === 0) {
|
|
7398
7982
|
throw new FilesystemError("nothing to write: no local files given");
|
|
7399
7983
|
}
|
|
7400
|
-
const writes = entries.map(([
|
|
7984
|
+
const writes = entries.map(([path5, localPath]) => ({ path: path5, localPath }));
|
|
7401
7985
|
const resolvedMessage = message || `write ${writes.length} local file(s) via SDK`;
|
|
7402
7986
|
const branch = await this.branch();
|
|
7403
7987
|
const traced = await callNative2(
|
|
@@ -7474,11 +8058,11 @@ var Filesystem = class {
|
|
|
7474
8058
|
};
|
|
7475
8059
|
}
|
|
7476
8060
|
/** Delete one file. Returns the durable version the deletion produced. */
|
|
7477
|
-
async deleteFile(
|
|
8061
|
+
async deleteFile(path5, message) {
|
|
7478
8062
|
return await this.writeFiles(
|
|
7479
8063
|
/* @__PURE__ */ new Map(),
|
|
7480
|
-
message || `delete ${
|
|
7481
|
-
[
|
|
8064
|
+
message || `delete ${path5} via SDK`,
|
|
8065
|
+
[path5]
|
|
7482
8066
|
);
|
|
7483
8067
|
}
|
|
7484
8068
|
/**
|
|
@@ -7529,15 +8113,15 @@ var Filesystem = class {
|
|
|
7529
8113
|
* Read a file's bytes at `version` (the current `main` head or a retained
|
|
7530
8114
|
* snapshot id; defaults to the filesystem's current head).
|
|
7531
8115
|
*/
|
|
7532
|
-
async readFile(
|
|
7533
|
-
return (await this.readFileWithMetadata(
|
|
8116
|
+
async readFile(path5, version) {
|
|
8117
|
+
return (await this.readFileWithMetadata(path5, { version })).data;
|
|
7534
8118
|
}
|
|
7535
8119
|
/**
|
|
7536
8120
|
* Read bytes and immutable metadata in one request. A range is executed by
|
|
7537
8121
|
* Artifact Storage, so callers never download the unrequested remainder.
|
|
7538
8122
|
*/
|
|
7539
|
-
async readFileWithMetadata(
|
|
7540
|
-
if (trimSlashes(
|
|
8123
|
+
async readFileWithMetadata(path5, options = {}) {
|
|
8124
|
+
if (trimSlashes(path5) === "") {
|
|
7541
8125
|
throw new FilesystemError("file path must not be empty");
|
|
7542
8126
|
}
|
|
7543
8127
|
const range = options.range;
|
|
@@ -7550,12 +8134,12 @@ var Filesystem = class {
|
|
|
7550
8134
|
const traced = await callNative2(
|
|
7551
8135
|
() => this.native.readFilesystemFile(
|
|
7552
8136
|
this.name,
|
|
7553
|
-
|
|
8137
|
+
path5,
|
|
7554
8138
|
resolvedVersion,
|
|
7555
8139
|
range?.offset,
|
|
7556
8140
|
range?.length
|
|
7557
8141
|
),
|
|
7558
|
-
new FileNotFoundInFilesystemError(this.name,
|
|
8142
|
+
new FileNotFoundInFilesystemError(this.name, path5)
|
|
7559
8143
|
);
|
|
7560
8144
|
const fullSize = traced.fullSize;
|
|
7561
8145
|
if (!traced.contentId || fullSize === void 0 || !Number.isSafeInteger(fullSize) || fullSize < 0 || traced.data.byteLength > fullSize) {
|
|
@@ -7570,9 +8154,9 @@ var Filesystem = class {
|
|
|
7570
8154
|
};
|
|
7571
8155
|
}
|
|
7572
8156
|
/** Read a file as UTF-8 text at `version`. Throws on non-UTF-8 content. */
|
|
7573
|
-
async readText(
|
|
8157
|
+
async readText(path5, version) {
|
|
7574
8158
|
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
|
7575
|
-
await this.readFile(
|
|
8159
|
+
await this.readFile(path5, version)
|
|
7576
8160
|
);
|
|
7577
8161
|
}
|
|
7578
8162
|
/** List one directory (non-recursive) at `version`. */
|
|
@@ -7635,11 +8219,11 @@ var FilesystemMount = class {
|
|
|
7635
8219
|
path;
|
|
7636
8220
|
readonly;
|
|
7637
8221
|
/** @internal — obtain instances via `FilesystemClient.mount()`. */
|
|
7638
|
-
constructor(client, cli, filesystem,
|
|
8222
|
+
constructor(client, cli, filesystem, path5, readonly) {
|
|
7639
8223
|
this.client = client;
|
|
7640
8224
|
this.cli = cli;
|
|
7641
8225
|
this.filesystem = filesystem;
|
|
7642
|
-
this.path =
|
|
8226
|
+
this.path = path5;
|
|
7643
8227
|
this.readonly = readonly;
|
|
7644
8228
|
}
|
|
7645
8229
|
/** Flush pending local changes into a durable snapshot. */
|
|
@@ -7657,6 +8241,7 @@ var FilesystemMount = class {
|
|
|
7657
8241
|
};
|
|
7658
8242
|
|
|
7659
8243
|
// src/api-client.ts
|
|
8244
|
+
init_sandbox_image();
|
|
7660
8245
|
init_errors();
|
|
7661
8246
|
var APIClient = class {
|
|
7662
8247
|
cloudClient;
|
|
@@ -7684,7 +8269,7 @@ var APIClient = class {
|
|
|
7684
8269
|
await this.cloudClient.deleteApplication(applicationName);
|
|
7685
8270
|
}
|
|
7686
8271
|
async deleteSandboxImage(imageName) {
|
|
7687
|
-
await this.
|
|
8272
|
+
await deleteSandboxImageWithCredentials(this.filesystemOptions, imageName);
|
|
7688
8273
|
}
|
|
7689
8274
|
async createFileSystem(name, description, options) {
|
|
7690
8275
|
const filesystem = await new FilesystemClient(this.filesystemOptions).create(
|
|
@@ -7771,14 +8356,14 @@ var GitCli = class extends MountCli {
|
|
|
7771
8356
|
if (options.readOnly && (options.publish || options.workspace !== void 0) || options.publish && options.workspace !== void 0) {
|
|
7772
8357
|
throw new TypeError("readOnly, publish, and workspace are mutually exclusive");
|
|
7773
8358
|
}
|
|
7774
|
-
const
|
|
8359
|
+
const path5 = resolve(localPath);
|
|
7775
8360
|
const args = ["mount"];
|
|
7776
8361
|
if (options.readOnly) args.push("--ro");
|
|
7777
8362
|
if (options.publish) args.push("--publish");
|
|
7778
8363
|
if (options.workspace !== void 0) args.push(`--workspace=${options.workspace}`);
|
|
7779
|
-
args.push("--", target,
|
|
8364
|
+
args.push("--", target, path5);
|
|
7780
8365
|
await this.run(args);
|
|
7781
|
-
return new RepositoryMount(this, target,
|
|
8366
|
+
return new RepositoryMount(this, target, path5, options.readOnly ?? false);
|
|
7782
8367
|
}
|
|
7783
8368
|
async unmount(localPath, options = {}) {
|
|
7784
8369
|
requireNonEmpty(localPath, "localPath");
|
|
@@ -7816,44 +8401,44 @@ var GitCli = class extends MountCli {
|
|
|
7816
8401
|
raw
|
|
7817
8402
|
};
|
|
7818
8403
|
}
|
|
7819
|
-
async snapshot(
|
|
8404
|
+
async snapshot(path5, message) {
|
|
7820
8405
|
const args = ["snapshot"];
|
|
7821
8406
|
if (message !== void 0) args.push(`--message=${message}`);
|
|
7822
|
-
args.push("--",
|
|
8407
|
+
args.push("--", path5);
|
|
7823
8408
|
await this.run(args);
|
|
7824
8409
|
}
|
|
7825
|
-
async sync(
|
|
7826
|
-
const args = ["sync", "--",
|
|
8410
|
+
async sync(path5, target) {
|
|
8411
|
+
const args = ["sync", "--", path5];
|
|
7827
8412
|
if (target !== void 0) {
|
|
7828
8413
|
requireNonEmpty(target, "target");
|
|
7829
8414
|
args.push(target);
|
|
7830
8415
|
}
|
|
7831
8416
|
await this.run(args);
|
|
7832
8417
|
}
|
|
7833
|
-
async rebase(
|
|
8418
|
+
async rebase(path5, target, failOnConflict) {
|
|
7834
8419
|
requireNonEmpty(target, "target");
|
|
7835
8420
|
const args = ["rebase"];
|
|
7836
8421
|
if (failOnConflict) args.push("--fail-on-conflict");
|
|
7837
|
-
args.push("--",
|
|
8422
|
+
args.push("--", path5, target);
|
|
7838
8423
|
await this.run(args);
|
|
7839
8424
|
}
|
|
7840
|
-
async promote(
|
|
8425
|
+
async promote(path5, branch, merge) {
|
|
7841
8426
|
requireNonEmpty(branch, "branch");
|
|
7842
8427
|
const args = ["promote"];
|
|
7843
8428
|
if (merge) args.push("--merge");
|
|
7844
|
-
args.push("--",
|
|
8429
|
+
args.push("--", path5, branch);
|
|
7845
8430
|
await this.run(args);
|
|
7846
8431
|
}
|
|
7847
|
-
async prefetch(
|
|
7848
|
-
await this.run(["prefetch", "--",
|
|
8432
|
+
async prefetch(path5) {
|
|
8433
|
+
await this.run(["prefetch", "--", path5]);
|
|
7849
8434
|
}
|
|
7850
8435
|
};
|
|
7851
8436
|
var RepositoryMount = class {
|
|
7852
8437
|
/** @internal Obtain instances via RepositoryClient.mount(). */
|
|
7853
|
-
constructor(cli, target,
|
|
8438
|
+
constructor(cli, target, path5, readOnly) {
|
|
7854
8439
|
this.cli = cli;
|
|
7855
8440
|
this.target = target;
|
|
7856
|
-
this.path =
|
|
8441
|
+
this.path = path5;
|
|
7857
8442
|
this.readOnly = readOnly;
|
|
7858
8443
|
}
|
|
7859
8444
|
/** Inspect workspace state, pending changes, and daemon diagnostics. */
|
|
@@ -8088,6 +8673,7 @@ function validateTimeoutMs2(timeoutMs) {
|
|
|
8088
8673
|
|
|
8089
8674
|
// src/index.ts
|
|
8090
8675
|
init_sandbox_image();
|
|
8676
|
+
init_image_builds();
|
|
8091
8677
|
|
|
8092
8678
|
// src/file-system.ts
|
|
8093
8679
|
init_esm_shims();
|
|
@@ -9471,38 +10057,38 @@ init_esm_shims();
|
|
|
9471
10057
|
import { createHash } from "crypto";
|
|
9472
10058
|
var textEncoder = new TextEncoder();
|
|
9473
10059
|
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
9474
|
-
function assertJSONValue(value,
|
|
10060
|
+
function assertJSONValue(value, path5, seen) {
|
|
9475
10061
|
if (value === null || typeof value === "string" || typeof value === "boolean") return;
|
|
9476
10062
|
if (typeof value === "number") {
|
|
9477
|
-
if (!Number.isFinite(value)) throw new SerializationError(`${
|
|
10063
|
+
if (!Number.isFinite(value)) throw new SerializationError(`${path5} contains a non-finite number`);
|
|
9478
10064
|
return;
|
|
9479
10065
|
}
|
|
9480
10066
|
if (typeof value !== "object") {
|
|
9481
|
-
throw new SerializationError(`${
|
|
10067
|
+
throw new SerializationError(`${path5} contains unsupported ${typeof value}`);
|
|
9482
10068
|
}
|
|
9483
10069
|
if (isFile(value)) {
|
|
9484
|
-
throw new SerializationError(`${
|
|
10070
|
+
throw new SerializationError(`${path5} contains a nested File; File is only supported as a direct value`);
|
|
9485
10071
|
}
|
|
9486
10072
|
if (isHttpBody(value)) {
|
|
9487
10073
|
throw new SerializationError(
|
|
9488
|
-
`${
|
|
10074
|
+
`${path5} contains a nested HttpBody; HttpBody is only supported as a direct value`
|
|
9489
10075
|
);
|
|
9490
10076
|
}
|
|
9491
|
-
if (seen.has(value)) throw new SerializationError(`${
|
|
10077
|
+
if (seen.has(value)) throw new SerializationError(`${path5} contains a cycle`);
|
|
9492
10078
|
if (Object.getPrototypeOf(value) !== Object.prototype && !Array.isArray(value)) {
|
|
9493
|
-
throw new SerializationError(`${
|
|
10079
|
+
throw new SerializationError(`${path5} contains unsupported ${value.constructor?.name ?? "object"}`);
|
|
9494
10080
|
}
|
|
9495
10081
|
seen.add(value);
|
|
9496
10082
|
if (Array.isArray(value)) {
|
|
9497
10083
|
for (let index = 0; index < value.length; index += 1) {
|
|
9498
10084
|
if (!Object.prototype.hasOwnProperty.call(value, index)) {
|
|
9499
|
-
throw new SerializationError(`${
|
|
10085
|
+
throw new SerializationError(`${path5} contains a sparse array entry at index ${index}`);
|
|
9500
10086
|
}
|
|
9501
|
-
assertJSONValue(value[index], `${
|
|
10087
|
+
assertJSONValue(value[index], `${path5}[${index}]`, seen);
|
|
9502
10088
|
}
|
|
9503
10089
|
} else {
|
|
9504
10090
|
for (const [key, item] of Object.entries(value)) {
|
|
9505
|
-
assertJSONValue(item, `${
|
|
10091
|
+
assertJSONValue(item, `${path5}.${key}`, seen);
|
|
9506
10092
|
}
|
|
9507
10093
|
}
|
|
9508
10094
|
seen.delete(value);
|
|
@@ -9951,7 +10537,20 @@ export {
|
|
|
9951
10537
|
Headers,
|
|
9952
10538
|
HttpBody,
|
|
9953
10539
|
Image,
|
|
10540
|
+
ImageBuildCancellationOutcome,
|
|
10541
|
+
ImageBuildCancelledError,
|
|
10542
|
+
ImageBuildError,
|
|
10543
|
+
ImageBuildErrorCode,
|
|
10544
|
+
ImageBuildFailedError,
|
|
10545
|
+
ImageBuildHandle,
|
|
10546
|
+
ImageBuildInProgressError,
|
|
10547
|
+
ImageBuildInterruptedError,
|
|
10548
|
+
ImageBuildKind,
|
|
10549
|
+
ImageBuildNotFoundError,
|
|
9954
10550
|
ImageBuildOperationType,
|
|
10551
|
+
ImageBuildPhase,
|
|
10552
|
+
ImageBuildStatus,
|
|
10553
|
+
ImageBuildTimeoutError,
|
|
9955
10554
|
MountError,
|
|
9956
10555
|
OutputMode,
|
|
9957
10556
|
PendingSandbox,
|
|
@@ -9984,12 +10583,14 @@ export {
|
|
|
9984
10583
|
TERMINATION_REASON_CANCELLED,
|
|
9985
10584
|
TERMINATION_REASON_NO_CAPACITY,
|
|
9986
10585
|
TcpTunnel,
|
|
10586
|
+
cancelImageBuild,
|
|
9987
10587
|
createFileSystem,
|
|
9988
10588
|
createSandboxImage,
|
|
9989
10589
|
deleteFileSystem,
|
|
9990
10590
|
deleteSandboxImage,
|
|
9991
10591
|
dockerfileContent,
|
|
9992
10592
|
findSandboxImageByName,
|
|
10593
|
+
getImageBuild,
|
|
9993
10594
|
importSandboxImage,
|
|
9994
10595
|
isSandboxPending,
|
|
9995
10596
|
listFileSystems,
|
|
@@ -10001,6 +10602,9 @@ export {
|
|
|
10001
10602
|
runLocal,
|
|
10002
10603
|
runRemote,
|
|
10003
10604
|
sandboxUrlFromIngressEndpoint,
|
|
10004
|
-
schema
|
|
10605
|
+
schema,
|
|
10606
|
+
startImageBuild,
|
|
10607
|
+
startImageImport,
|
|
10608
|
+
waitImageBuild
|
|
10005
10609
|
};
|
|
10006
10610
|
//# sourceMappingURL=index.js.map
|