@tensorlakeai/tensorlake 0.5.152 → 0.5.153
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 +3515 -3394
- 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 +3470 -3349
- 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 +1270 -782
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +311 -21
- package/dist/index.d.ts +311 -21
- package/dist/index.js +1248 -773
- 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 +339 -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 +338 -1299
- package/dist/sandbox-image.js.map +1 -1
- package/package.json +7 -7
- package/runtime/function-executor/manifest.json +5 -5
- package/runtime/function-executor/package/dist/function-executor/main.js +2 -2
- package/runtime/function-executor/package/npm-shrinkwrap.json +2 -2
- package/runtime/function-executor/package/package.json +1 -1
- package/runtime/typescript-function-runner/manifest.json +5 -5
- package/runtime/typescript-function-runner/package/dist/function-agent/main.js +1 -1
- package/runtime/typescript-function-runner/package/npm-shrinkwrap.json +26 -26
- package/runtime/typescript-function-runner/package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -49,7 +49,7 @@ var init_defaults = __esm({
|
|
|
49
49
|
"src/defaults.ts"() {
|
|
50
50
|
"use strict";
|
|
51
51
|
init_cjs_shims();
|
|
52
|
-
SDK_VERSION = "0.5.
|
|
52
|
+
SDK_VERSION = "0.5.153";
|
|
53
53
|
API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
|
|
54
54
|
API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
|
|
55
55
|
NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
|
|
@@ -498,7 +498,7 @@ var init_native_worker_client = __esm({
|
|
|
498
498
|
}
|
|
499
499
|
};
|
|
500
500
|
runtimeKey = /* @__PURE__ */ Symbol.for(
|
|
501
|
-
`tensorlake.native.worker.${false ? "source" : "0.5.
|
|
501
|
+
`tensorlake.native.worker.${false ? "source" : "0.5.153"}.v1`
|
|
502
502
|
);
|
|
503
503
|
runtimes = globalThis;
|
|
504
504
|
}
|
|
@@ -598,6 +598,8 @@ var init_models = __esm({
|
|
|
598
598
|
SnapshotStatus2["LOCAL_READY"] = "local_ready";
|
|
599
599
|
SnapshotStatus2["COMPLETED"] = "completed";
|
|
600
600
|
SnapshotStatus2["FAILED"] = "failed";
|
|
601
|
+
SnapshotStatus2["DELETING"] = "deleting";
|
|
602
|
+
SnapshotStatus2["REPLICATING"] = "replicating";
|
|
601
603
|
return SnapshotStatus2;
|
|
602
604
|
})(SnapshotStatus || {});
|
|
603
605
|
ProcessStatus = /* @__PURE__ */ ((ProcessStatus2) => {
|
|
@@ -3886,9 +3888,8 @@ var init_sandbox = __esm({
|
|
|
3886
3888
|
*
|
|
3887
3889
|
* Resource targets use create's cpus, memoryMb, and diskMb names. Resize
|
|
3888
3890
|
* waits by default; wait=false returns admission. Timeout does not cancel it.
|
|
3889
|
-
*
|
|
3890
|
-
*
|
|
3891
|
-
* Non-CAS sandboxes do not support live resize.
|
|
3891
|
+
* Which runtimes and dimensions support a live resize is decided by the
|
|
3892
|
+
* server, whose policy error is thrown unchanged.
|
|
3892
3893
|
* Wait, timeout, and pollInterval are ignored on non-resource updates.
|
|
3893
3894
|
* A no-op returns current resources with absent or earlier resize metadata.
|
|
3894
3895
|
*
|
|
@@ -4306,29 +4307,29 @@ var init_sandbox = __esm({
|
|
|
4306
4307
|
}
|
|
4307
4308
|
// --- File operations ---
|
|
4308
4309
|
/** Read a file from the sandbox and return its raw bytes. */
|
|
4309
|
-
async readFile(
|
|
4310
|
+
async readFile(path4) {
|
|
4310
4311
|
const proxy = await this.proxy.client();
|
|
4311
|
-
const { traceId, data } = await callNative(() => proxy.readFile(
|
|
4312
|
+
const { traceId, data } = await callNative(() => proxy.readFile(path4), {
|
|
4312
4313
|
sandboxId: this.sandboxId
|
|
4313
4314
|
});
|
|
4314
4315
|
return Object.assign(Uint8Array.from(data), { traceId });
|
|
4315
4316
|
}
|
|
4316
4317
|
/** Write raw bytes to a file in the sandbox, creating it if it does not exist. */
|
|
4317
|
-
async writeFile(
|
|
4318
|
+
async writeFile(path4, content) {
|
|
4318
4319
|
const proxy = await this.proxy.client();
|
|
4319
|
-
await callNative(() => proxy.writeFile(
|
|
4320
|
+
await callNative(() => proxy.writeFile(path4, Buffer.from(content)), {
|
|
4320
4321
|
sandboxId: this.sandboxId
|
|
4321
4322
|
});
|
|
4322
4323
|
}
|
|
4323
4324
|
/** Delete a file from the sandbox. */
|
|
4324
|
-
async deleteFile(
|
|
4325
|
+
async deleteFile(path4) {
|
|
4325
4326
|
const proxy = await this.proxy.client();
|
|
4326
|
-
await callNative(() => proxy.deleteFile(
|
|
4327
|
+
await callNative(() => proxy.deleteFile(path4), { sandboxId: this.sandboxId });
|
|
4327
4328
|
}
|
|
4328
4329
|
/** List the contents of a directory in the sandbox. */
|
|
4329
|
-
async listDirectory(
|
|
4330
|
+
async listDirectory(path4) {
|
|
4330
4331
|
const proxy = await this.proxy.client();
|
|
4331
|
-
const { traceId, json } = await callNative(() => proxy.listDirectory(
|
|
4332
|
+
const { traceId, json } = await callNative(() => proxy.listDirectory(path4), {
|
|
4332
4333
|
sandboxId: this.sandboxId
|
|
4333
4334
|
});
|
|
4334
4335
|
return Object.assign(fromSnakeKeys(JSON.parse(json)), {
|
|
@@ -4994,9 +4995,9 @@ var init_client = __esm({
|
|
|
4994
4995
|
});
|
|
4995
4996
|
}
|
|
4996
4997
|
/**
|
|
4997
|
-
* Update properties or resize a running sandbox.
|
|
4998
|
-
*
|
|
4999
|
-
*
|
|
4998
|
+
* Update properties or resize a running sandbox. Which runtimes and
|
|
4999
|
+
* dimensions support a live resize is decided by the server, whose policy
|
|
5000
|
+
* error is thrown unchanged.
|
|
5000
5001
|
* Resource names match create. Resize waits by default; wait=false returns
|
|
5001
5002
|
* admission. Timeout leaves the resize running and reports its generation.
|
|
5002
5003
|
* Wait, timeout, and pollInterval are ignored on non-resource updates.
|
|
@@ -5315,6 +5316,11 @@ var init_client = __esm({
|
|
|
5315
5316
|
`Snapshot ${result.snapshotId} failed: ${info.error}`
|
|
5316
5317
|
);
|
|
5317
5318
|
}
|
|
5319
|
+
if (info.status === "deleting" /* DELETING */) {
|
|
5320
|
+
throw new SandboxError(
|
|
5321
|
+
`Snapshot ${result.snapshotId} is being deleted`
|
|
5322
|
+
);
|
|
5323
|
+
}
|
|
5318
5324
|
await sleep2(pollInterval * 1e3);
|
|
5319
5325
|
}
|
|
5320
5326
|
throw new SandboxError(
|
|
@@ -5572,585 +5578,6 @@ var init_client = __esm({
|
|
|
5572
5578
|
}
|
|
5573
5579
|
});
|
|
5574
5580
|
|
|
5575
|
-
// src/native-cloud.ts
|
|
5576
|
-
async function serializeRequest(method, path3, options) {
|
|
5577
|
-
const headers = { ...options?.headers };
|
|
5578
|
-
let body = options?.body;
|
|
5579
|
-
if (options?.json !== void 0) {
|
|
5580
|
-
body = JSON.stringify(options.json);
|
|
5581
|
-
if (!Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) {
|
|
5582
|
-
headers["Content-Type"] = "application/json";
|
|
5583
|
-
}
|
|
5584
|
-
}
|
|
5585
|
-
const request = {
|
|
5586
|
-
method,
|
|
5587
|
-
path: path3,
|
|
5588
|
-
headersJson: JSON.stringify(headers),
|
|
5589
|
-
statusOnlyCodes: [...options?.statusOnlyCodes ?? []]
|
|
5590
|
-
};
|
|
5591
|
-
if (body instanceof FormData) {
|
|
5592
|
-
request.parts = [];
|
|
5593
|
-
for (const [name, value] of body.entries()) {
|
|
5594
|
-
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" });
|
|
5595
|
-
}
|
|
5596
|
-
} else if (body !== void 0) {
|
|
5597
|
-
if (body instanceof Blob) request.body = Buffer.from(await body.arrayBuffer());
|
|
5598
|
-
else if (typeof body === "string") request.body = Buffer.from(body);
|
|
5599
|
-
else if (body instanceof ArrayBuffer) request.body = Buffer.from(new Uint8Array(body));
|
|
5600
|
-
else request.body = Buffer.from(body);
|
|
5601
|
-
}
|
|
5602
|
-
return request;
|
|
5603
|
-
}
|
|
5604
|
-
var NativeCloudTransport;
|
|
5605
|
-
var init_native_cloud = __esm({
|
|
5606
|
-
"src/native-cloud.ts"() {
|
|
5607
|
-
"use strict";
|
|
5608
|
-
init_cjs_shims();
|
|
5609
|
-
init_native_sandbox();
|
|
5610
|
-
init_native_worker_client();
|
|
5611
|
-
NativeCloudTransport = class {
|
|
5612
|
-
constructor(options) {
|
|
5613
|
-
this.options = options;
|
|
5614
|
-
if (!Number.isSafeInteger(options.maxRetries) || options.maxRetries < 0 || options.maxRetries > 4294967295) {
|
|
5615
|
-
throw new RangeError("maxRetries must be a non-negative 32-bit integer");
|
|
5616
|
-
}
|
|
5617
|
-
if (!Number.isFinite(options.retryBackoffMs) || options.retryBackoffMs < 0) {
|
|
5618
|
-
throw new RangeError("retryBackoffMs must be a non-negative finite number");
|
|
5619
|
-
}
|
|
5620
|
-
}
|
|
5621
|
-
native;
|
|
5622
|
-
closed = false;
|
|
5623
|
-
client() {
|
|
5624
|
-
if (this.closed) throw new Error("Tensorlake native client is closed");
|
|
5625
|
-
if (this.native) return this.native;
|
|
5626
|
-
const ctor = loadNativeSandboxBinding().NativeCloudClient;
|
|
5627
|
-
if (!ctor) throw new Error("Native binding does not export NativeCloudClient; rebuild with 'npm run build:native'");
|
|
5628
|
-
return this.native = new ctor(JSON.stringify(this.options));
|
|
5629
|
-
}
|
|
5630
|
-
close() {
|
|
5631
|
-
this.closed = true;
|
|
5632
|
-
releaseNativeHandle(this.native ?? null);
|
|
5633
|
-
this.native = void 0;
|
|
5634
|
-
}
|
|
5635
|
-
async requestResponse(method, path3, options) {
|
|
5636
|
-
const request = await serializeRequest(method, path3, options);
|
|
5637
|
-
const raw = await callNative(() => this.client().request(request));
|
|
5638
|
-
const response = new Response(
|
|
5639
|
-
[204, 205, 304].includes(raw.status) ? null : Uint8Array.from(raw.data).buffer,
|
|
5640
|
-
{ status: raw.status, headers: JSON.parse(raw.headersJson) }
|
|
5641
|
-
);
|
|
5642
|
-
return Object.assign(response, { traceId: raw.traceId });
|
|
5643
|
-
}
|
|
5644
|
-
async requestJson(method, path3) {
|
|
5645
|
-
const response = await this.requestResponse(method, path3);
|
|
5646
|
-
const text = await response.text();
|
|
5647
|
-
const value = text ? JSON.parse(text) : null;
|
|
5648
|
-
return Object.assign(value ?? {}, { traceId: response.traceId });
|
|
5649
|
-
}
|
|
5650
|
-
async *stream(method, path3, signal) {
|
|
5651
|
-
if (signal?.aborted) return;
|
|
5652
|
-
const request = await serializeRequest(method, path3, { headers: { Accept: "text/event-stream" } });
|
|
5653
|
-
yield* nativeEventStream((emit) => this.client().stream(request, emit), void 0, signal);
|
|
5654
|
-
}
|
|
5655
|
-
};
|
|
5656
|
-
}
|
|
5657
|
-
});
|
|
5658
|
-
|
|
5659
|
-
// src/cloud-client.ts
|
|
5660
|
-
function secretFromMetadata(metadata) {
|
|
5661
|
-
return {
|
|
5662
|
-
id: metadata.id,
|
|
5663
|
-
name: metadata.name,
|
|
5664
|
-
createdAt: new Date(metadata.created_at_ms)
|
|
5665
|
-
};
|
|
5666
|
-
}
|
|
5667
|
-
function applicationAllowsUnauthenticatedRequests(manifest) {
|
|
5668
|
-
return Array.isArray(manifest.allow) && manifest.allow.includes(UNAUTHENTICATED_REQUESTS);
|
|
5669
|
-
}
|
|
5670
|
-
function publicEndpointIdFromManifest(manifest) {
|
|
5671
|
-
for (const key of ["public_endpoint_id", "publicEndpointId"]) {
|
|
5672
|
-
const value = manifest[key];
|
|
5673
|
-
if (typeof value === "string" && value.length > 0) {
|
|
5674
|
-
return value;
|
|
5675
|
-
}
|
|
5676
|
-
}
|
|
5677
|
-
return void 0;
|
|
5678
|
-
}
|
|
5679
|
-
function generatePublicEndpointId() {
|
|
5680
|
-
return `endpoint_${(0, import_nanoid.nanoid)()}`;
|
|
5681
|
-
}
|
|
5682
|
-
function createApplicationBuildForm(request, imageContexts) {
|
|
5683
|
-
const contextsByPartName = /* @__PURE__ */ new Map();
|
|
5684
|
-
for (const context of imageContexts) {
|
|
5685
|
-
if (contextsByPartName.has(context.contextTarPartName)) {
|
|
5686
|
-
throw new Error(
|
|
5687
|
-
`duplicate image context part name '${context.contextTarPartName}'`
|
|
5688
|
-
);
|
|
5689
|
-
}
|
|
5690
|
-
contextsByPartName.set(context.contextTarPartName, context);
|
|
5691
|
-
}
|
|
5692
|
-
const form = new FormData();
|
|
5693
|
-
form.append(
|
|
5694
|
-
"app_version",
|
|
5695
|
-
new Blob([JSON.stringify(request)], { type: "application/json" }),
|
|
5696
|
-
"app_version"
|
|
5697
|
-
);
|
|
5698
|
-
for (const image of request.images) {
|
|
5699
|
-
const context = contextsByPartName.get(image.contextTarPartName);
|
|
5700
|
-
if (!context) {
|
|
5701
|
-
throw new Error(
|
|
5702
|
-
`missing image context for part '${image.contextTarPartName}'`
|
|
5703
|
-
);
|
|
5704
|
-
}
|
|
5705
|
-
form.append(
|
|
5706
|
-
image.contextTarPartName,
|
|
5707
|
-
new Blob([toBlobPart(context.contextTarGz)]),
|
|
5708
|
-
`${image.contextTarPartName}.tar.gz`
|
|
5709
|
-
);
|
|
5710
|
-
}
|
|
5711
|
-
for (const context of imageContexts) {
|
|
5712
|
-
if (!request.images.some((image) => image.contextTarPartName === context.contextTarPartName)) {
|
|
5713
|
-
throw new Error(
|
|
5714
|
-
`unexpected image context for part '${context.contextTarPartName}'`
|
|
5715
|
-
);
|
|
5716
|
-
}
|
|
5717
|
-
}
|
|
5718
|
-
return form;
|
|
5719
|
-
}
|
|
5720
|
-
function trimTrailingSlashes2(value) {
|
|
5721
|
-
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
5722
|
-
}
|
|
5723
|
-
function nextRequestPath(next) {
|
|
5724
|
-
const schemeIndex = next.indexOf("://");
|
|
5725
|
-
if (schemeIndex !== -1) {
|
|
5726
|
-
const afterScheme = next.slice(schemeIndex + 3);
|
|
5727
|
-
const slashIndex = afterScheme.indexOf("/");
|
|
5728
|
-
return slashIndex === -1 ? "/" : afterScheme.slice(slashIndex);
|
|
5729
|
-
}
|
|
5730
|
-
return next.startsWith("/") ? next : `/${next}`;
|
|
5731
|
-
}
|
|
5732
|
-
function toBlobPart(data) {
|
|
5733
|
-
if (typeof data === "string" || data instanceof Blob) {
|
|
5734
|
-
return data;
|
|
5735
|
-
}
|
|
5736
|
-
if (data instanceof Uint8Array) {
|
|
5737
|
-
return Uint8Array.from(data).buffer;
|
|
5738
|
-
}
|
|
5739
|
-
return data;
|
|
5740
|
-
}
|
|
5741
|
-
function toRequestBody(data) {
|
|
5742
|
-
return toBlobPart(data);
|
|
5743
|
-
}
|
|
5744
|
-
async function parseJsonResponse(response) {
|
|
5745
|
-
const text = await response.text();
|
|
5746
|
-
if (!text) {
|
|
5747
|
-
return void 0;
|
|
5748
|
-
}
|
|
5749
|
-
return JSON.parse(text);
|
|
5750
|
-
}
|
|
5751
|
-
var import_nanoid, CloudClient, UNAUTHENTICATED_REQUESTS;
|
|
5752
|
-
var init_cloud_client = __esm({
|
|
5753
|
-
"src/cloud-client.ts"() {
|
|
5754
|
-
"use strict";
|
|
5755
|
-
init_cjs_shims();
|
|
5756
|
-
import_nanoid = require("nanoid");
|
|
5757
|
-
init_defaults();
|
|
5758
|
-
init_native_cloud();
|
|
5759
|
-
init_models();
|
|
5760
|
-
CloudClient = class _CloudClient {
|
|
5761
|
-
transport;
|
|
5762
|
-
organizationId;
|
|
5763
|
-
projectId;
|
|
5764
|
-
namespace;
|
|
5765
|
-
constructor(options) {
|
|
5766
|
-
this.organizationId = options?.organizationId;
|
|
5767
|
-
this.projectId = options?.projectId;
|
|
5768
|
-
this.namespace = options?.namespace ?? NAMESPACE;
|
|
5769
|
-
this.transport = new NativeCloudTransport({
|
|
5770
|
-
baseUrl: options?.apiUrl ?? API_URL,
|
|
5771
|
-
apiKey: options?.apiKey ?? API_KEY,
|
|
5772
|
-
organizationId: this.organizationId,
|
|
5773
|
-
projectId: this.projectId,
|
|
5774
|
-
maxRetries: options?.maxRetries ?? MAX_RETRIES,
|
|
5775
|
-
retryBackoffMs: options?.retryBackoffMs ?? RETRY_BACKOFF_MS,
|
|
5776
|
-
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
5777
|
-
userAgent: `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
5778
|
-
});
|
|
5779
|
-
}
|
|
5780
|
-
static forCloud(options) {
|
|
5781
|
-
return new _CloudClient(options);
|
|
5782
|
-
}
|
|
5783
|
-
close() {
|
|
5784
|
-
this.transport.close();
|
|
5785
|
-
}
|
|
5786
|
-
async upsertApplication(manifest, codeZip, upgradeRunningRequests = false) {
|
|
5787
|
-
const applicationManifest = { ...manifest };
|
|
5788
|
-
let publicEndpointId = publicEndpointIdFromManifest(applicationManifest);
|
|
5789
|
-
if (applicationAllowsUnauthenticatedRequests(applicationManifest) && publicEndpointId === void 0) {
|
|
5790
|
-
const applicationName = applicationManifest.name;
|
|
5791
|
-
if (typeof applicationName === "string" && applicationName.length > 0) {
|
|
5792
|
-
publicEndpointId = await this.existingApplicationPublicEndpointId(applicationName);
|
|
5793
|
-
}
|
|
5794
|
-
publicEndpointId ??= generatePublicEndpointId();
|
|
5795
|
-
}
|
|
5796
|
-
if (publicEndpointId !== void 0) {
|
|
5797
|
-
applicationManifest.public_endpoint_id = publicEndpointId;
|
|
5798
|
-
delete applicationManifest.publicEndpointId;
|
|
5799
|
-
}
|
|
5800
|
-
const form = new FormData();
|
|
5801
|
-
form.append(
|
|
5802
|
-
"code",
|
|
5803
|
-
new Blob([toBlobPart(codeZip)], { type: "application/zip" }),
|
|
5804
|
-
"code.zip"
|
|
5805
|
-
);
|
|
5806
|
-
form.append("code_content_type", "application/zip");
|
|
5807
|
-
form.append("application", JSON.stringify(applicationManifest));
|
|
5808
|
-
form.append(
|
|
5809
|
-
"upgrade_requests_to_latest_code",
|
|
5810
|
-
String(upgradeRunningRequests)
|
|
5811
|
-
);
|
|
5812
|
-
await this.transport.requestResponse("POST", this.namespacePath("applications"), {
|
|
5813
|
-
body: form
|
|
5814
|
-
});
|
|
5815
|
-
}
|
|
5816
|
-
async deleteApplication(applicationName) {
|
|
5817
|
-
await this.transport.requestResponse(
|
|
5818
|
-
"DELETE",
|
|
5819
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
5820
|
-
);
|
|
5821
|
-
}
|
|
5822
|
-
async deleteSandboxImage(imageName) {
|
|
5823
|
-
await this.transport.requestResponse(
|
|
5824
|
-
"DELETE",
|
|
5825
|
-
this.namespacePath(`sandbox-images/${encodeURIComponent(imageName)}`)
|
|
5826
|
-
);
|
|
5827
|
-
}
|
|
5828
|
-
/**
|
|
5829
|
-
* Look up a registered sandbox image (template) by its registered name.
|
|
5830
|
-
*
|
|
5831
|
-
* Returns the template, or `null` when no image with that name exists.
|
|
5832
|
-
* API-key clients may omit organization/project IDs and use the
|
|
5833
|
-
* token-scoped Platform API route directly. Explicit scope remains
|
|
5834
|
-
* available for PAT callers.
|
|
5835
|
-
*/
|
|
5836
|
-
async findSandboxImageByName(imageName, options) {
|
|
5837
|
-
const base = this.platformProjectPath(
|
|
5838
|
-
"sandbox-templates",
|
|
5839
|
-
options?.organizationId,
|
|
5840
|
-
options?.projectId
|
|
5841
|
-
);
|
|
5842
|
-
const response = await this.transport.requestResponse(
|
|
5843
|
-
"GET",
|
|
5844
|
-
`${base}/by-name/${encodeURIComponent(imageName)}`,
|
|
5845
|
-
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
5846
|
-
);
|
|
5847
|
-
if (response.status === 404) {
|
|
5848
|
-
return null;
|
|
5849
|
-
}
|
|
5850
|
-
const raw = await parseJsonResponse(response);
|
|
5851
|
-
return fromSnakeKeys(raw);
|
|
5852
|
-
}
|
|
5853
|
-
/**
|
|
5854
|
-
* List all registered sandbox images (templates), following pagination to
|
|
5855
|
-
* the end. API-key clients may omit organization/project IDs and use the
|
|
5856
|
-
* token-scoped Platform API route directly.
|
|
5857
|
-
*/
|
|
5858
|
-
async listSandboxImages(options) {
|
|
5859
|
-
const base = this.platformProjectPath(
|
|
5860
|
-
"sandbox-templates",
|
|
5861
|
-
options?.organizationId,
|
|
5862
|
-
options?.projectId
|
|
5863
|
-
);
|
|
5864
|
-
let path3 = `${base}?pageSize=100`;
|
|
5865
|
-
const templates = [];
|
|
5866
|
-
while (path3 !== null) {
|
|
5867
|
-
const page = await this.transport.requestJson(
|
|
5868
|
-
"GET",
|
|
5869
|
-
path3
|
|
5870
|
-
);
|
|
5871
|
-
for (const item of page.items ?? []) {
|
|
5872
|
-
templates.push(fromSnakeKeys(item));
|
|
5873
|
-
}
|
|
5874
|
-
const next = page.pagination?.next;
|
|
5875
|
-
path3 = next ? nextRequestPath(next) : null;
|
|
5876
|
-
}
|
|
5877
|
-
return templates;
|
|
5878
|
-
}
|
|
5879
|
-
async applications() {
|
|
5880
|
-
const raw = await this.transport.requestJson(
|
|
5881
|
-
"GET",
|
|
5882
|
-
this.namespacePath("applications")
|
|
5883
|
-
);
|
|
5884
|
-
return (raw.applications ?? []).map(
|
|
5885
|
-
(application) => fromSnakeKeys(application)
|
|
5886
|
-
);
|
|
5887
|
-
}
|
|
5888
|
-
async applicationManifest(applicationName) {
|
|
5889
|
-
const raw = await this.transport.requestJson(
|
|
5890
|
-
"GET",
|
|
5891
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
5892
|
-
);
|
|
5893
|
-
return fromSnakeKeys(raw);
|
|
5894
|
-
}
|
|
5895
|
-
async runRequest(applicationName, inputs = []) {
|
|
5896
|
-
const path3 = this.namespacePath(
|
|
5897
|
-
`applications/${encodeURIComponent(applicationName)}`
|
|
5898
|
-
);
|
|
5899
|
-
const response = inputs.length === 0 ? await this.transport.requestResponse("POST", path3, {
|
|
5900
|
-
body: new Uint8Array(),
|
|
5901
|
-
headers: { Accept: "application/json" }
|
|
5902
|
-
}) : inputs.length === 1 && inputs[0].name === "0" ? await this.transport.requestResponse("POST", path3, {
|
|
5903
|
-
body: toRequestBody(inputs[0].data),
|
|
5904
|
-
headers: {
|
|
5905
|
-
Accept: "application/json",
|
|
5906
|
-
"Content-Type": inputs[0].contentType
|
|
5907
|
-
}
|
|
5908
|
-
}) : await this.runMultipartRequest(path3, inputs);
|
|
5909
|
-
const body = await parseJsonResponse(response);
|
|
5910
|
-
const requestId = body?.request_id;
|
|
5911
|
-
if (!requestId) {
|
|
5912
|
-
throw new Error("missing request_id in run request response body");
|
|
5913
|
-
}
|
|
5914
|
-
return requestId;
|
|
5915
|
-
}
|
|
5916
|
-
async waitOnRequestCompletion(applicationName, requestId) {
|
|
5917
|
-
const stream = this.transport.stream(
|
|
5918
|
-
"GET",
|
|
5919
|
-
this.namespacePath(
|
|
5920
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/progress`
|
|
5921
|
-
)
|
|
5922
|
-
);
|
|
5923
|
-
for await (const event of stream) {
|
|
5924
|
-
if (Object.prototype.hasOwnProperty.call(event, "RequestFinished")) {
|
|
5925
|
-
return;
|
|
5926
|
-
}
|
|
5927
|
-
}
|
|
5928
|
-
throw new Error("progress stream ended before request completion");
|
|
5929
|
-
}
|
|
5930
|
-
async requestMetadata(applicationName, requestId) {
|
|
5931
|
-
const raw = await this.transport.requestJson(
|
|
5932
|
-
"GET",
|
|
5933
|
-
this.namespacePath(
|
|
5934
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}`
|
|
5935
|
-
)
|
|
5936
|
-
);
|
|
5937
|
-
return fromSnakeKeys(raw);
|
|
5938
|
-
}
|
|
5939
|
-
async requestOutput(applicationName, requestId) {
|
|
5940
|
-
const response = await this.transport.requestResponse(
|
|
5941
|
-
"GET",
|
|
5942
|
-
this.namespacePath(
|
|
5943
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/output`
|
|
5944
|
-
)
|
|
5945
|
-
);
|
|
5946
|
-
const serializedValue = new Uint8Array(await response.arrayBuffer());
|
|
5947
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
5948
|
-
return {
|
|
5949
|
-
serializedValue,
|
|
5950
|
-
contentType
|
|
5951
|
-
};
|
|
5952
|
-
}
|
|
5953
|
-
async listSecrets(options) {
|
|
5954
|
-
const base = this.secretCollectionPath(
|
|
5955
|
-
options?.organizationId,
|
|
5956
|
-
options?.projectId
|
|
5957
|
-
);
|
|
5958
|
-
const raw = await this.transport.requestJson("GET", base);
|
|
5959
|
-
const pageSize = Math.max(0, options?.pageSize ?? 100);
|
|
5960
|
-
return Object.assign(
|
|
5961
|
-
{
|
|
5962
|
-
items: raw.slice(0, pageSize).map(secretFromMetadata),
|
|
5963
|
-
pagination: { total: raw.length }
|
|
5964
|
-
},
|
|
5965
|
-
{ traceId: raw.traceId }
|
|
5966
|
-
);
|
|
5967
|
-
}
|
|
5968
|
-
async getSecret(secretId, options) {
|
|
5969
|
-
const base = this.secretCollectionPath(
|
|
5970
|
-
options?.organizationId,
|
|
5971
|
-
options?.projectId
|
|
5972
|
-
);
|
|
5973
|
-
const raw = await this.transport.requestJson(
|
|
5974
|
-
"GET",
|
|
5975
|
-
`${base}/${encodeURIComponent(secretId)}`
|
|
5976
|
-
);
|
|
5977
|
-
return Object.assign(secretFromMetadata(raw), { traceId: raw.traceId });
|
|
5978
|
-
}
|
|
5979
|
-
async upsertSecrets(secrets, options) {
|
|
5980
|
-
const base = this.secretCollectionPath(
|
|
5981
|
-
options?.organizationId,
|
|
5982
|
-
options?.projectId
|
|
5983
|
-
);
|
|
5984
|
-
if (Array.isArray(secrets)) {
|
|
5985
|
-
const results = [];
|
|
5986
|
-
for (const secret of secrets) {
|
|
5987
|
-
results.push(await this.upsertSecret(base, secret));
|
|
5988
|
-
}
|
|
5989
|
-
return results;
|
|
5990
|
-
}
|
|
5991
|
-
return this.upsertSecret(base, secrets);
|
|
5992
|
-
}
|
|
5993
|
-
async deleteSecret(secretId, options) {
|
|
5994
|
-
const base = this.secretCollectionPath(
|
|
5995
|
-
options?.organizationId,
|
|
5996
|
-
options?.projectId
|
|
5997
|
-
);
|
|
5998
|
-
await this.transport.requestResponse(
|
|
5999
|
-
"DELETE",
|
|
6000
|
-
`${base}/${encodeURIComponent(secretId)}`
|
|
6001
|
-
);
|
|
6002
|
-
}
|
|
6003
|
-
async upsertSecret(base, secret) {
|
|
6004
|
-
let response = await this.transport.requestResponse("POST", base, {
|
|
6005
|
-
json: secret,
|
|
6006
|
-
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() },
|
|
6007
|
-
statusOnlyCodes: /* @__PURE__ */ new Set([409])
|
|
6008
|
-
});
|
|
6009
|
-
if (response.status === 409) {
|
|
6010
|
-
const prefix = base.slice(0, -"/secrets".length);
|
|
6011
|
-
const existing = await this.transport.requestJson(
|
|
6012
|
-
"GET",
|
|
6013
|
-
`${prefix}/secret-names/${encodeURIComponent(secret.name)}`
|
|
6014
|
-
);
|
|
6015
|
-
response = await this.transport.requestResponse(
|
|
6016
|
-
"POST",
|
|
6017
|
-
`${base}/${encodeURIComponent(existing.id)}/versions`,
|
|
6018
|
-
{
|
|
6019
|
-
json: { value: secret.value },
|
|
6020
|
-
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() }
|
|
6021
|
-
}
|
|
6022
|
-
);
|
|
6023
|
-
}
|
|
6024
|
-
const metadata = await parseJsonResponse(response);
|
|
6025
|
-
return Object.assign(secretFromMetadata(metadata), {
|
|
6026
|
-
traceId: response.traceId
|
|
6027
|
-
});
|
|
6028
|
-
}
|
|
6029
|
-
async startImageBuild(buildServicePath, request) {
|
|
6030
|
-
const form = new FormData();
|
|
6031
|
-
form.append("graph_name", request.applicationName);
|
|
6032
|
-
form.append("graph_version", request.applicationVersion);
|
|
6033
|
-
form.append("graph_function_name", request.functionName);
|
|
6034
|
-
form.append("image_name", request.imageName);
|
|
6035
|
-
form.append("image_id", request.imageId);
|
|
6036
|
-
form.append(
|
|
6037
|
-
"context",
|
|
6038
|
-
new Blob([toBlobPart(request.buildContext)]),
|
|
6039
|
-
"context.tar.gz"
|
|
6040
|
-
);
|
|
6041
|
-
const response = await this.transport.requestResponse(
|
|
6042
|
-
"PUT",
|
|
6043
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds`,
|
|
6044
|
-
{ body: form }
|
|
6045
|
-
);
|
|
6046
|
-
const raw = await parseJsonResponse(response);
|
|
6047
|
-
return fromSnakeKeys(raw);
|
|
6048
|
-
}
|
|
6049
|
-
async createApplicationBuild(buildServicePath, request, imageContexts) {
|
|
6050
|
-
const form = createApplicationBuildForm(request, imageContexts);
|
|
6051
|
-
const response = await this.transport.requestResponse(
|
|
6052
|
-
"POST",
|
|
6053
|
-
trimTrailingSlashes2(buildServicePath),
|
|
6054
|
-
{ body: form }
|
|
6055
|
-
);
|
|
6056
|
-
const raw = await parseJsonResponse(response);
|
|
6057
|
-
return fromSnakeKeys(raw);
|
|
6058
|
-
}
|
|
6059
|
-
async applicationBuildInfo(buildServicePath, applicationBuildId) {
|
|
6060
|
-
const raw = await this.transport.requestJson(
|
|
6061
|
-
"GET",
|
|
6062
|
-
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}`
|
|
6063
|
-
);
|
|
6064
|
-
return fromSnakeKeys(raw);
|
|
6065
|
-
}
|
|
6066
|
-
async cancelApplicationBuild(buildServicePath, applicationBuildId) {
|
|
6067
|
-
const raw = await this.transport.requestJson(
|
|
6068
|
-
"POST",
|
|
6069
|
-
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}/cancel`
|
|
6070
|
-
);
|
|
6071
|
-
return fromSnakeKeys(raw);
|
|
6072
|
-
}
|
|
6073
|
-
async buildInfo(buildServicePath, buildId) {
|
|
6074
|
-
const raw = await this.transport.requestJson(
|
|
6075
|
-
"GET",
|
|
6076
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}`
|
|
6077
|
-
);
|
|
6078
|
-
return fromSnakeKeys(raw);
|
|
6079
|
-
}
|
|
6080
|
-
async cancelBuild(buildServicePath, buildId) {
|
|
6081
|
-
await this.transport.requestResponse(
|
|
6082
|
-
"POST",
|
|
6083
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/cancel`
|
|
6084
|
-
);
|
|
6085
|
-
}
|
|
6086
|
-
async *streamBuildLogs(buildServicePath, buildId, signal) {
|
|
6087
|
-
const stream = this.transport.stream(
|
|
6088
|
-
"GET",
|
|
6089
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/logs`,
|
|
6090
|
-
signal
|
|
6091
|
-
);
|
|
6092
|
-
for await (const event of stream) {
|
|
6093
|
-
yield fromSnakeKeys(event);
|
|
6094
|
-
}
|
|
6095
|
-
}
|
|
6096
|
-
async runMultipartRequest(path3, inputs) {
|
|
6097
|
-
const form = new FormData();
|
|
6098
|
-
for (const input of inputs) {
|
|
6099
|
-
form.append(
|
|
6100
|
-
input.name,
|
|
6101
|
-
new Blob([toBlobPart(input.data)], { type: input.contentType }),
|
|
6102
|
-
input.name
|
|
6103
|
-
);
|
|
6104
|
-
}
|
|
6105
|
-
return this.transport.requestResponse("POST", path3, {
|
|
6106
|
-
body: form,
|
|
6107
|
-
headers: { Accept: "application/json" }
|
|
6108
|
-
});
|
|
6109
|
-
}
|
|
6110
|
-
namespacePath(subpath) {
|
|
6111
|
-
return `/v1/namespaces/${encodeURIComponent(this.namespace)}/${subpath.replace(/^\/+/, "")}`;
|
|
6112
|
-
}
|
|
6113
|
-
async existingApplicationPublicEndpointId(applicationName) {
|
|
6114
|
-
const response = await this.transport.requestResponse(
|
|
6115
|
-
"GET",
|
|
6116
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`),
|
|
6117
|
-
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
6118
|
-
);
|
|
6119
|
-
if (response.status === 404) {
|
|
6120
|
-
return void 0;
|
|
6121
|
-
}
|
|
6122
|
-
const application = await parseJsonResponse(response);
|
|
6123
|
-
return publicEndpointIdFromManifest(application);
|
|
6124
|
-
}
|
|
6125
|
-
platformProjectPath(resource, organizationId, projectId) {
|
|
6126
|
-
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
6127
|
-
const resolvedProjectId = projectId ?? this.projectId;
|
|
6128
|
-
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
6129
|
-
return `/platform/v1/${resource}`;
|
|
6130
|
-
}
|
|
6131
|
-
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
6132
|
-
throw new Error(
|
|
6133
|
-
"organizationId and projectId must be provided together"
|
|
6134
|
-
);
|
|
6135
|
-
}
|
|
6136
|
-
return `/platform/v1/organizations/${encodeURIComponent(resolvedOrganizationId)}/projects/${encodeURIComponent(resolvedProjectId)}/${resource}`;
|
|
6137
|
-
}
|
|
6138
|
-
secretCollectionPath(organizationId, projectId) {
|
|
6139
|
-
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
6140
|
-
const resolvedProjectId = projectId ?? this.projectId;
|
|
6141
|
-
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
6142
|
-
return this.namespacePath("secrets");
|
|
6143
|
-
}
|
|
6144
|
-
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
6145
|
-
throw new Error("organizationId and projectId must be provided together");
|
|
6146
|
-
}
|
|
6147
|
-
return this.namespacePath("secrets");
|
|
6148
|
-
}
|
|
6149
|
-
};
|
|
6150
|
-
UNAUTHENTICATED_REQUESTS = "unauthenticated_requests";
|
|
6151
|
-
}
|
|
6152
|
-
});
|
|
6153
|
-
|
|
6154
5581
|
// src/image.ts
|
|
6155
5582
|
function cloneOperation(op) {
|
|
6156
5583
|
return {
|
|
@@ -6343,9 +5770,9 @@ var require_libc = __commonJS({
|
|
|
6343
5770
|
// src/native-binding.ts
|
|
6344
5771
|
function packageRoot() {
|
|
6345
5772
|
const parent = (0, import_node_url.fileURLToPath)(new URL("../", importMetaUrl));
|
|
6346
|
-
if (fs.existsSync(
|
|
5773
|
+
if (fs.existsSync(import_node_path.default.join(parent, "package.json"))) return parent;
|
|
6347
5774
|
const grandparent = (0, import_node_url.fileURLToPath)(new URL("../../", importMetaUrl));
|
|
6348
|
-
if (fs.existsSync(
|
|
5775
|
+
if (fs.existsSync(import_node_path.default.join(grandparent, "package.json"))) return grandparent;
|
|
6349
5776
|
return parent;
|
|
6350
5777
|
}
|
|
6351
5778
|
function linuxLibcFamily(options) {
|
|
@@ -6368,7 +5795,7 @@ function nativeTargetId(platform = process.platform, arch = process.arch, option
|
|
|
6368
5795
|
function nativeBindingPath(options = {}) {
|
|
6369
5796
|
const platform = options.platform ?? process.platform;
|
|
6370
5797
|
const arch = options.arch ?? process.arch;
|
|
6371
|
-
return
|
|
5798
|
+
return import_node_path.default.join(
|
|
6372
5799
|
options.packageRoot ?? packageRoot(),
|
|
6373
5800
|
"dist",
|
|
6374
5801
|
"native",
|
|
@@ -6401,7 +5828,7 @@ function loadNative() {
|
|
|
6401
5828
|
}
|
|
6402
5829
|
return require2(packageEntry);
|
|
6403
5830
|
}
|
|
6404
|
-
var import_libc, fs, import_node_module2,
|
|
5831
|
+
var import_libc, fs, import_node_module2, import_node_path, import_node_url, NATIVE_PACKAGES, cachedLinuxLibc;
|
|
6405
5832
|
var init_native_binding = __esm({
|
|
6406
5833
|
"src/native-binding.ts"() {
|
|
6407
5834
|
"use strict";
|
|
@@ -6409,7 +5836,7 @@ var init_native_binding = __esm({
|
|
|
6409
5836
|
import_libc = __toESM(require_libc(), 1);
|
|
6410
5837
|
fs = __toESM(require("fs"), 1);
|
|
6411
5838
|
import_node_module2 = require("module");
|
|
6412
|
-
|
|
5839
|
+
import_node_path = __toESM(require("path"), 1);
|
|
6413
5840
|
import_node_url = require("url");
|
|
6414
5841
|
NATIVE_PACKAGES = {
|
|
6415
5842
|
"darwin-arm64": "@tensorlakeai/native-darwin-arm64",
|
|
@@ -6422,16 +5849,471 @@ var init_native_binding = __esm({
|
|
|
6422
5849
|
}
|
|
6423
5850
|
});
|
|
6424
5851
|
|
|
5852
|
+
// src/image-builds.ts
|
|
5853
|
+
function camelize(key) {
|
|
5854
|
+
return key.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
5855
|
+
}
|
|
5856
|
+
function toImageBuildError(error) {
|
|
5857
|
+
if (!(error instanceof Error)) return error;
|
|
5858
|
+
let payload;
|
|
5859
|
+
try {
|
|
5860
|
+
payload = JSON.parse(error.message);
|
|
5861
|
+
} catch {
|
|
5862
|
+
return error;
|
|
5863
|
+
}
|
|
5864
|
+
if (!payload || payload.category !== "image_build") return error;
|
|
5865
|
+
const details = {};
|
|
5866
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
5867
|
+
if (key === "category") continue;
|
|
5868
|
+
details[camelize(key)] = value;
|
|
5869
|
+
}
|
|
5870
|
+
const typed = details;
|
|
5871
|
+
switch (typed.code) {
|
|
5872
|
+
case "not_found":
|
|
5873
|
+
return new ImageBuildNotFoundError(typed);
|
|
5874
|
+
case "image_build_in_progress":
|
|
5875
|
+
return new ImageBuildInProgressError(typed);
|
|
5876
|
+
case "failed":
|
|
5877
|
+
return new ImageBuildFailedError(typed);
|
|
5878
|
+
case "cancelled":
|
|
5879
|
+
return new ImageBuildCancelledError(typed);
|
|
5880
|
+
case "timeout":
|
|
5881
|
+
return new ImageBuildTimeoutError(typed);
|
|
5882
|
+
case "interrupted":
|
|
5883
|
+
return new ImageBuildInterruptedError(typed);
|
|
5884
|
+
default:
|
|
5885
|
+
return new ImageBuildError(typed);
|
|
5886
|
+
}
|
|
5887
|
+
}
|
|
5888
|
+
function camelizeRecord(value) {
|
|
5889
|
+
const out = {};
|
|
5890
|
+
for (const [key, inner] of Object.entries(value)) out[camelize(key)] = inner;
|
|
5891
|
+
return out;
|
|
5892
|
+
}
|
|
5893
|
+
function parseBuildInfo(raw) {
|
|
5894
|
+
const camel = camelizeRecord(raw);
|
|
5895
|
+
const result = raw.result && typeof raw.result === "object" ? camelizeRecord(raw.result) : null;
|
|
5896
|
+
return {
|
|
5897
|
+
buildId: String(raw.build_id ?? ""),
|
|
5898
|
+
clientRequestId: camel.clientRequestId ?? null,
|
|
5899
|
+
kind: String(raw.kind ?? ""),
|
|
5900
|
+
name: raw.name ?? null,
|
|
5901
|
+
status: String(raw.status ?? ""),
|
|
5902
|
+
phase: raw.phase ?? null,
|
|
5903
|
+
attemptNo: Number(raw.attempt_no ?? 0),
|
|
5904
|
+
builderSandboxId: camel.builderSandboxId ?? null,
|
|
5905
|
+
error: raw.error ?? null,
|
|
5906
|
+
result,
|
|
5907
|
+
operationDeadlineMs: camel.operationDeadlineMs ?? null,
|
|
5908
|
+
createdAtMs: camel.createdAtMs ?? null,
|
|
5909
|
+
updatedAtMs: camel.updatedAtMs ?? null,
|
|
5910
|
+
raw
|
|
5911
|
+
};
|
|
5912
|
+
}
|
|
5913
|
+
function parseResult(json) {
|
|
5914
|
+
return camelizeRecord(JSON.parse(json));
|
|
5915
|
+
}
|
|
5916
|
+
function credentialsFromEnv() {
|
|
5917
|
+
const context = __imageBuildInternals.buildContextFromEnv();
|
|
5918
|
+
if (!context.apiKey) {
|
|
5919
|
+
if (context.personalAccessToken) {
|
|
5920
|
+
throw new ImageBuildError({
|
|
5921
|
+
code: "auth",
|
|
5922
|
+
message: "Sandbox image SDKs require TENSORLAKE_API_KEY. Personal access tokens are CLI-only."
|
|
5923
|
+
});
|
|
5924
|
+
}
|
|
5925
|
+
throw new ImageBuildError({ code: "auth", message: "Missing TENSORLAKE_API_KEY credentials." });
|
|
5926
|
+
}
|
|
5927
|
+
return { apiUrl: context.apiUrl, bearerToken: context.apiKey, namespace: context.namespace };
|
|
5928
|
+
}
|
|
5929
|
+
function clientOptions(credentials) {
|
|
5930
|
+
return {
|
|
5931
|
+
apiUrl: credentials.apiUrl,
|
|
5932
|
+
bearerToken: credentials.bearerToken,
|
|
5933
|
+
namespace: credentials.namespace,
|
|
5934
|
+
useScopeHeaders: false
|
|
5935
|
+
};
|
|
5936
|
+
}
|
|
5937
|
+
function rejectLegacyReference(buildId) {
|
|
5938
|
+
if (typeof buildId !== "string" || buildId.trim().length === 0) {
|
|
5939
|
+
throw new ImageBuildError({ code: "usage", message: "buildId must be a non-empty string" });
|
|
5940
|
+
}
|
|
5941
|
+
if (buildId.startsWith("sandbox_template_")) {
|
|
5942
|
+
throw new ImageBuildError({
|
|
5943
|
+
code: "usage",
|
|
5944
|
+
message: `'${buildId}' is a legacy sandbox template id; legacy images have no build operation to get, wait for or cancel`,
|
|
5945
|
+
buildId
|
|
5946
|
+
});
|
|
5947
|
+
}
|
|
5948
|
+
if (buildId.startsWith("image_")) {
|
|
5949
|
+
throw new ImageBuildError({
|
|
5950
|
+
code: "usage",
|
|
5951
|
+
message: `'${buildId}' is an image id, not a build id; look the image up with findSandboxImageByName or use the build id admission returned`,
|
|
5952
|
+
buildId
|
|
5953
|
+
});
|
|
5954
|
+
}
|
|
5955
|
+
}
|
|
5956
|
+
async function __runWithInterrupt(signal, run) {
|
|
5957
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
5958
|
+
if (signal === void 0) {
|
|
5959
|
+
try {
|
|
5960
|
+
return await run(void 0);
|
|
5961
|
+
} catch (error) {
|
|
5962
|
+
throw toImageBuildError(error);
|
|
5963
|
+
}
|
|
5964
|
+
}
|
|
5965
|
+
const interruptId = binding.createImageBuildInterrupt();
|
|
5966
|
+
const onAbort = () => binding.triggerImageBuildInterrupt(interruptId);
|
|
5967
|
+
if (signal.aborted) onAbort();
|
|
5968
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
5969
|
+
try {
|
|
5970
|
+
return await run(interruptId);
|
|
5971
|
+
} catch (error) {
|
|
5972
|
+
throw toImageBuildError(error);
|
|
5973
|
+
} finally {
|
|
5974
|
+
signal.removeEventListener("abort", onAbort);
|
|
5975
|
+
binding.releaseImageBuildInterrupt(interruptId);
|
|
5976
|
+
}
|
|
5977
|
+
}
|
|
5978
|
+
function makeEmitter(options) {
|
|
5979
|
+
const emit = options.emit ?? (options.verbose ? __imageBuildInternals.stderrEmit : __imageBuildInternals.noopEmit);
|
|
5980
|
+
let emitError;
|
|
5981
|
+
const forward = (event) => {
|
|
5982
|
+
try {
|
|
5983
|
+
emit(__imageBuildInternals.eventToEmitDict(event));
|
|
5984
|
+
} catch (error) {
|
|
5985
|
+
emitError ??= error;
|
|
5986
|
+
}
|
|
5987
|
+
};
|
|
5988
|
+
return {
|
|
5989
|
+
forward,
|
|
5990
|
+
emit,
|
|
5991
|
+
rethrow() {
|
|
5992
|
+
if (emitError != null) throw emitError;
|
|
5993
|
+
}
|
|
5994
|
+
};
|
|
5995
|
+
}
|
|
5996
|
+
function decodeStarted(json, credentials) {
|
|
5997
|
+
const payload = JSON.parse(json);
|
|
5998
|
+
return new ImageBuildHandle(parseBuildInfo(payload.build ?? {}), credentials, payload.client_request_id);
|
|
5999
|
+
}
|
|
6000
|
+
async function startImageBuild(source, options = {}, deps = {}) {
|
|
6001
|
+
const emitter = makeEmitter({ emit: deps.emit ?? options.emit, verbose: options.verbose });
|
|
6002
|
+
let dockerfilePath;
|
|
6003
|
+
let dockerfileText;
|
|
6004
|
+
let contextDir;
|
|
6005
|
+
let name;
|
|
6006
|
+
let tempContextDir;
|
|
6007
|
+
if (source instanceof Image) {
|
|
6008
|
+
if (!source.baseImage) throw new Error("Image must have a baseImage to build");
|
|
6009
|
+
if (options.contextDir != null) {
|
|
6010
|
+
contextDir = import_node_path2.default.resolve(options.contextDir);
|
|
6011
|
+
} else if (__imageBuildInternals.imageRequiresContext(source)) {
|
|
6012
|
+
throw new Error(
|
|
6013
|
+
"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>`."
|
|
6014
|
+
);
|
|
6015
|
+
} else {
|
|
6016
|
+
tempContextDir = (0, import_node_fs.mkdtempSync)(import_node_path2.default.join(import_node_os.default.tmpdir(), "tl-build-context-"));
|
|
6017
|
+
contextDir = tempContextDir;
|
|
6018
|
+
}
|
|
6019
|
+
dockerfilePath = import_node_path2.default.join(contextDir, "Dockerfile");
|
|
6020
|
+
let text = dockerfileContent(source);
|
|
6021
|
+
if (!text.endsWith("\n")) text += "\n";
|
|
6022
|
+
dockerfileText = text;
|
|
6023
|
+
name = options.registeredName ?? source.name;
|
|
6024
|
+
} else if (typeof source === "string") {
|
|
6025
|
+
const resolved = import_node_path2.default.resolve(source);
|
|
6026
|
+
if (!(0, import_node_fs.existsSync)(resolved)) throw new Error(`Dockerfile not found: ${source}`);
|
|
6027
|
+
dockerfilePath = resolved;
|
|
6028
|
+
name = options.registeredName ?? __imageBuildInternals.defaultRegisteredName(resolved);
|
|
6029
|
+
} else {
|
|
6030
|
+
throw new TypeError(`source must be an Image or a Dockerfile path, got ${typeof source}`);
|
|
6031
|
+
}
|
|
6032
|
+
try {
|
|
6033
|
+
const credentials = credentialsFromEnv();
|
|
6034
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6035
|
+
emitter.emit({ type: "status", message: `Building image '${name}'...` });
|
|
6036
|
+
const json = await __runWithInterrupt(
|
|
6037
|
+
options.signal,
|
|
6038
|
+
(interruptId) => binding.startImageBuild(
|
|
6039
|
+
{
|
|
6040
|
+
apiUrl: credentials.apiUrl,
|
|
6041
|
+
bearerToken: credentials.bearerToken,
|
|
6042
|
+
dockerfilePath,
|
|
6043
|
+
registeredName: name,
|
|
6044
|
+
diskMb: options.diskMb,
|
|
6045
|
+
cpus: options.cpus,
|
|
6046
|
+
memoryMb: options.memoryMb,
|
|
6047
|
+
isPublic: options.isPublic ?? false,
|
|
6048
|
+
namespace: credentials.namespace,
|
|
6049
|
+
useScopeHeaders: false,
|
|
6050
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6051
|
+
dockerfileText,
|
|
6052
|
+
contextDir,
|
|
6053
|
+
cas: true,
|
|
6054
|
+
buildArgs: options.buildArgs
|
|
6055
|
+
},
|
|
6056
|
+
emitter.forward,
|
|
6057
|
+
interruptId
|
|
6058
|
+
)
|
|
6059
|
+
);
|
|
6060
|
+
emitter.rethrow();
|
|
6061
|
+
return decodeStarted(json, credentials);
|
|
6062
|
+
} finally {
|
|
6063
|
+
if (tempContextDir != null) (0, import_node_fs.rmSync)(tempContextDir, { recursive: true, force: true });
|
|
6064
|
+
}
|
|
6065
|
+
}
|
|
6066
|
+
async function startImageImport(imageReference, options = {}, deps = {}) {
|
|
6067
|
+
if (typeof imageReference !== "string" || imageReference.trim().length === 0) {
|
|
6068
|
+
throw new Error("image reference to import must not be empty");
|
|
6069
|
+
}
|
|
6070
|
+
const reference = imageReference.trim();
|
|
6071
|
+
const name = options.registeredName ?? __imageBuildInternals.defaultRegisteredNameFromImage(reference);
|
|
6072
|
+
const emitter = makeEmitter({ emit: deps.emit ?? options.emit, verbose: options.verbose });
|
|
6073
|
+
const credentials = credentialsFromEnv();
|
|
6074
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6075
|
+
emitter.emit({ type: "status", message: `Importing image '${reference}' as '${name}'...` });
|
|
6076
|
+
const json = await __runWithInterrupt(
|
|
6077
|
+
options.signal,
|
|
6078
|
+
(interruptId) => binding.startImageImport(
|
|
6079
|
+
{
|
|
6080
|
+
apiUrl: credentials.apiUrl,
|
|
6081
|
+
bearerToken: credentials.bearerToken,
|
|
6082
|
+
imageReference: reference,
|
|
6083
|
+
registeredName: name,
|
|
6084
|
+
diskMb: options.diskMb,
|
|
6085
|
+
cpus: options.cpus,
|
|
6086
|
+
memoryMb: options.memoryMb,
|
|
6087
|
+
isPublic: options.isPublic ?? false,
|
|
6088
|
+
namespace: credentials.namespace,
|
|
6089
|
+
useScopeHeaders: false,
|
|
6090
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6091
|
+
cas: true
|
|
6092
|
+
},
|
|
6093
|
+
emitter.forward,
|
|
6094
|
+
interruptId
|
|
6095
|
+
)
|
|
6096
|
+
);
|
|
6097
|
+
emitter.rethrow();
|
|
6098
|
+
return decodeStarted(json, credentials);
|
|
6099
|
+
}
|
|
6100
|
+
async function getImageBuild(buildId) {
|
|
6101
|
+
rejectLegacyReference(buildId);
|
|
6102
|
+
const credentials = credentialsFromEnv();
|
|
6103
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6104
|
+
let json;
|
|
6105
|
+
try {
|
|
6106
|
+
json = await binding.getImageBuild(clientOptions(credentials), buildId);
|
|
6107
|
+
} catch (error) {
|
|
6108
|
+
throw toImageBuildError(error);
|
|
6109
|
+
}
|
|
6110
|
+
return new ImageBuildHandle(parseBuildInfo(JSON.parse(json)), credentials);
|
|
6111
|
+
}
|
|
6112
|
+
async function waitImageBuild(buildId, options = {}) {
|
|
6113
|
+
rejectLegacyReference(buildId);
|
|
6114
|
+
const credentials = credentialsFromEnv();
|
|
6115
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6116
|
+
const emitter = makeEmitter(options);
|
|
6117
|
+
const json = await __runWithInterrupt(
|
|
6118
|
+
options.signal,
|
|
6119
|
+
(interruptId) => binding.waitImageBuild(
|
|
6120
|
+
clientOptions(credentials),
|
|
6121
|
+
buildId,
|
|
6122
|
+
{ timeoutMs: options.timeoutMs, followLogs: options.followLogs ?? false },
|
|
6123
|
+
emitter.forward,
|
|
6124
|
+
interruptId
|
|
6125
|
+
)
|
|
6126
|
+
);
|
|
6127
|
+
emitter.rethrow();
|
|
6128
|
+
return parseResult(json);
|
|
6129
|
+
}
|
|
6130
|
+
async function cancelImageBuildWith(credentials, selector) {
|
|
6131
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6132
|
+
let json;
|
|
6133
|
+
try {
|
|
6134
|
+
json = await binding.cancelImageBuild(clientOptions(credentials), {
|
|
6135
|
+
buildId: selector.buildId,
|
|
6136
|
+
clientRequestId: selector.clientRequestId
|
|
6137
|
+
});
|
|
6138
|
+
} catch (error) {
|
|
6139
|
+
throw toImageBuildError(error);
|
|
6140
|
+
}
|
|
6141
|
+
const payload = JSON.parse(json);
|
|
6142
|
+
const outcome = String(payload.outcome ?? "");
|
|
6143
|
+
return {
|
|
6144
|
+
outcome,
|
|
6145
|
+
build: payload.build ? parseBuildInfo(payload.build) : null,
|
|
6146
|
+
confirmed: ["cancelled", "already_cancelled", "already_failed"].includes(outcome)
|
|
6147
|
+
};
|
|
6148
|
+
}
|
|
6149
|
+
async function cancelImageBuild(selector) {
|
|
6150
|
+
const hasBuild = selector.buildId != null;
|
|
6151
|
+
const hasRequest = selector.clientRequestId != null;
|
|
6152
|
+
if (hasBuild === hasRequest) {
|
|
6153
|
+
throw new ImageBuildError({
|
|
6154
|
+
code: "usage",
|
|
6155
|
+
message: "pass exactly one of buildId or clientRequestId"
|
|
6156
|
+
});
|
|
6157
|
+
}
|
|
6158
|
+
if (selector.buildId != null) rejectLegacyReference(selector.buildId);
|
|
6159
|
+
return cancelImageBuildWith(credentialsFromEnv(), selector);
|
|
6160
|
+
}
|
|
6161
|
+
var import_node_path2, import_node_os, import_node_fs, ImageBuildError, ImageBuildNotFoundError, ImageBuildInProgressError, ImageBuildFailedError, ImageBuildCancelledError, ImageBuildTimeoutError, ImageBuildInterruptedError, ImageBuildHandle;
|
|
6162
|
+
var init_image_builds = __esm({
|
|
6163
|
+
"src/image-builds.ts"() {
|
|
6164
|
+
"use strict";
|
|
6165
|
+
init_cjs_shims();
|
|
6166
|
+
import_node_path2 = __toESM(require("path"), 1);
|
|
6167
|
+
import_node_os = __toESM(require("os"), 1);
|
|
6168
|
+
import_node_fs = require("fs");
|
|
6169
|
+
init_image();
|
|
6170
|
+
init_sandbox_image();
|
|
6171
|
+
ImageBuildError = class extends Error {
|
|
6172
|
+
code;
|
|
6173
|
+
buildId;
|
|
6174
|
+
clientRequestId;
|
|
6175
|
+
details;
|
|
6176
|
+
constructor(details) {
|
|
6177
|
+
super(details.message);
|
|
6178
|
+
this.name = "ImageBuildError";
|
|
6179
|
+
this.code = details.code;
|
|
6180
|
+
this.details = details;
|
|
6181
|
+
if (details.buildId) this.buildId = details.buildId;
|
|
6182
|
+
if (details.clientRequestId) this.clientRequestId = details.clientRequestId;
|
|
6183
|
+
}
|
|
6184
|
+
};
|
|
6185
|
+
ImageBuildNotFoundError = class extends ImageBuildError {
|
|
6186
|
+
constructor(details) {
|
|
6187
|
+
super(details);
|
|
6188
|
+
this.name = "ImageBuildNotFoundError";
|
|
6189
|
+
}
|
|
6190
|
+
};
|
|
6191
|
+
ImageBuildInProgressError = class extends ImageBuildError {
|
|
6192
|
+
imageName;
|
|
6193
|
+
activeBuildId;
|
|
6194
|
+
activeKind;
|
|
6195
|
+
activeStatus;
|
|
6196
|
+
constructor(details) {
|
|
6197
|
+
super(details);
|
|
6198
|
+
this.name = "ImageBuildInProgressError";
|
|
6199
|
+
if (details.imageName) this.imageName = details.imageName;
|
|
6200
|
+
if (details.activeBuildId) this.activeBuildId = details.activeBuildId;
|
|
6201
|
+
if (details.activeKind) this.activeKind = details.activeKind;
|
|
6202
|
+
if (details.activeStatus) this.activeStatus = details.activeStatus;
|
|
6203
|
+
}
|
|
6204
|
+
};
|
|
6205
|
+
ImageBuildFailedError = class extends ImageBuildError {
|
|
6206
|
+
error;
|
|
6207
|
+
info;
|
|
6208
|
+
constructor(details) {
|
|
6209
|
+
super(details);
|
|
6210
|
+
this.name = "ImageBuildFailedError";
|
|
6211
|
+
this.error = details.error ?? "no error recorded";
|
|
6212
|
+
if (details.info) this.info = parseBuildInfo(details.info);
|
|
6213
|
+
}
|
|
6214
|
+
};
|
|
6215
|
+
ImageBuildCancelledError = class extends ImageBuildError {
|
|
6216
|
+
info;
|
|
6217
|
+
constructor(details) {
|
|
6218
|
+
super(details);
|
|
6219
|
+
this.name = "ImageBuildCancelledError";
|
|
6220
|
+
if (details.info) this.info = parseBuildInfo(details.info);
|
|
6221
|
+
}
|
|
6222
|
+
};
|
|
6223
|
+
ImageBuildTimeoutError = class extends ImageBuildError {
|
|
6224
|
+
constructor(details) {
|
|
6225
|
+
super(details);
|
|
6226
|
+
this.name = "ImageBuildTimeoutError";
|
|
6227
|
+
}
|
|
6228
|
+
};
|
|
6229
|
+
ImageBuildInterruptedError = class extends ImageBuildError {
|
|
6230
|
+
outcome;
|
|
6231
|
+
confirmed;
|
|
6232
|
+
result;
|
|
6233
|
+
constructor(details) {
|
|
6234
|
+
super(details);
|
|
6235
|
+
this.name = "ImageBuildInterruptedError";
|
|
6236
|
+
this.outcome = details.outcome ?? "unconfirmed";
|
|
6237
|
+
this.confirmed = details.confirmed === true;
|
|
6238
|
+
if (details.result) this.result = details.result;
|
|
6239
|
+
}
|
|
6240
|
+
};
|
|
6241
|
+
ImageBuildHandle = class {
|
|
6242
|
+
buildId;
|
|
6243
|
+
/**
|
|
6244
|
+
* The admission's request id, when this handle started the build. Never
|
|
6245
|
+
* needed to cancel; a recovery aid for a lost admission answer.
|
|
6246
|
+
*/
|
|
6247
|
+
clientRequestId;
|
|
6248
|
+
#info;
|
|
6249
|
+
#credentials;
|
|
6250
|
+
/** @internal */
|
|
6251
|
+
constructor(info, credentials, clientRequestId) {
|
|
6252
|
+
this.buildId = info.buildId;
|
|
6253
|
+
this.clientRequestId = clientRequestId ?? info.clientRequestId ?? null;
|
|
6254
|
+
this.#info = info;
|
|
6255
|
+
this.#credentials = credentials;
|
|
6256
|
+
}
|
|
6257
|
+
/** The last observed state. */
|
|
6258
|
+
get info() {
|
|
6259
|
+
return this.#info;
|
|
6260
|
+
}
|
|
6261
|
+
/** Re-read the current state. */
|
|
6262
|
+
async refresh() {
|
|
6263
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6264
|
+
let json;
|
|
6265
|
+
try {
|
|
6266
|
+
json = await binding.getImageBuild(clientOptions(this.#credentials), this.buildId);
|
|
6267
|
+
} catch (error) {
|
|
6268
|
+
throw toImageBuildError(error);
|
|
6269
|
+
}
|
|
6270
|
+
this.#info = parseBuildInfo(JSON.parse(json));
|
|
6271
|
+
return this.#info;
|
|
6272
|
+
}
|
|
6273
|
+
/**
|
|
6274
|
+
* Wait for publication and return this build's immutable result. See
|
|
6275
|
+
* {@link ImageBuildWaitOptions} for the timeout/abort distinction.
|
|
6276
|
+
*/
|
|
6277
|
+
async wait(options = {}) {
|
|
6278
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6279
|
+
const emitter = makeEmitter(options);
|
|
6280
|
+
const json = await __runWithInterrupt(
|
|
6281
|
+
options.signal,
|
|
6282
|
+
(interruptId) => binding.waitImageBuild(
|
|
6283
|
+
clientOptions(this.#credentials),
|
|
6284
|
+
this.buildId,
|
|
6285
|
+
{ timeoutMs: options.timeoutMs, followLogs: options.followLogs ?? false },
|
|
6286
|
+
emitter.forward,
|
|
6287
|
+
interruptId
|
|
6288
|
+
)
|
|
6289
|
+
);
|
|
6290
|
+
emitter.rethrow();
|
|
6291
|
+
const result = parseResult(json);
|
|
6292
|
+
this.#info = { ...this.#info, status: "succeeded", result };
|
|
6293
|
+
return result;
|
|
6294
|
+
}
|
|
6295
|
+
/** Cancel this build by its id (the sufficient selector). */
|
|
6296
|
+
async cancel() {
|
|
6297
|
+
return cancelImageBuildWith(this.#credentials, { buildId: this.buildId });
|
|
6298
|
+
}
|
|
6299
|
+
};
|
|
6300
|
+
}
|
|
6301
|
+
});
|
|
6302
|
+
|
|
6425
6303
|
// src/sandbox-image.ts
|
|
6426
6304
|
var sandbox_image_exports = {};
|
|
6427
6305
|
__export(sandbox_image_exports, {
|
|
6306
|
+
__imageBuildInternals: () => __imageBuildInternals,
|
|
6428
6307
|
__setNativeBindingForTest: () => __setNativeBindingForTest,
|
|
6429
6308
|
buildContextFromEnv: () => buildContextFromEnv,
|
|
6430
6309
|
createSandboxImage: () => createSandboxImage,
|
|
6431
6310
|
deleteSandboxImage: () => deleteSandboxImage,
|
|
6311
|
+
deleteSandboxImageWithCredentials: () => deleteSandboxImageWithCredentials,
|
|
6432
6312
|
findSandboxImageByName: () => findSandboxImageByName,
|
|
6313
|
+
findSandboxImageByNameWithCredentials: () => findSandboxImageByNameWithCredentials,
|
|
6433
6314
|
importSandboxImage: () => importSandboxImage,
|
|
6434
6315
|
listSandboxImages: () => listSandboxImages,
|
|
6316
|
+
listSandboxImagesWithCredentials: () => listSandboxImagesWithCredentials,
|
|
6435
6317
|
runCreateSandboxImageCli: () => runCreateSandboxImageCli,
|
|
6436
6318
|
runImportSandboxImageCli: () => runImportSandboxImageCli
|
|
6437
6319
|
});
|
|
@@ -6505,6 +6387,15 @@ function eventToEmitDict(event) {
|
|
|
6505
6387
|
message: event.message
|
|
6506
6388
|
};
|
|
6507
6389
|
if (event.stream != null) out.stream = event.stream;
|
|
6390
|
+
if (event.buildId != null) out.build_id = event.buildId;
|
|
6391
|
+
if (event.clientRequestId !== void 0 && event.eventType !== "status") {
|
|
6392
|
+
out.client_request_id = event.clientRequestId;
|
|
6393
|
+
}
|
|
6394
|
+
if (event.status != null) out.status = event.status;
|
|
6395
|
+
if (event.phase !== void 0 && event.eventType.startsWith("build_")) out.phase = event.phase;
|
|
6396
|
+
if (event.attempt != null) out.attempt = event.attempt;
|
|
6397
|
+
if (event.outcome != null) out.outcome = event.outcome;
|
|
6398
|
+
if (event.confirmed != null) out.confirmed = event.confirmed;
|
|
6508
6399
|
return out;
|
|
6509
6400
|
}
|
|
6510
6401
|
function runOpMountsContext(op) {
|
|
@@ -6606,38 +6497,47 @@ async function createSandboxImage(source, options = {}, deps = {}) {
|
|
|
6606
6497
|
deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
|
|
6607
6498
|
);
|
|
6608
6499
|
}
|
|
6500
|
+
if (options.signal !== void 0 && !options.cas) {
|
|
6501
|
+
throw new Error(
|
|
6502
|
+
"signal is only supported for CAS image builds (cas: true); a legacy build has no Image Service build operation to cancel"
|
|
6503
|
+
);
|
|
6504
|
+
}
|
|
6609
6505
|
emit({ type: "status", message: `Building image '${effectiveName}'...` });
|
|
6610
6506
|
const binding = loadNativeBinding();
|
|
6611
6507
|
let emitError;
|
|
6612
|
-
const
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
6508
|
+
const nativeOptions = {
|
|
6509
|
+
apiUrl: context.apiUrl,
|
|
6510
|
+
bearerToken,
|
|
6511
|
+
dockerfilePath,
|
|
6512
|
+
registeredName: effectiveName,
|
|
6513
|
+
diskMb: options.diskMb,
|
|
6514
|
+
builderDiskMb: options.builderDiskMb,
|
|
6515
|
+
cpus: options.cpus,
|
|
6516
|
+
memoryMb: options.memoryMb,
|
|
6517
|
+
isPublic: options.isPublic ?? false,
|
|
6518
|
+
organizationId: usePat ? context.organizationId : void 0,
|
|
6519
|
+
projectId: usePat ? context.projectId : void 0,
|
|
6520
|
+
namespace: context.namespace,
|
|
6521
|
+
useScopeHeaders: usePat,
|
|
6522
|
+
userAgent: void 0,
|
|
6523
|
+
dockerCompat: options.dockerCompat ?? false,
|
|
6524
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6525
|
+
dockerfileText,
|
|
6526
|
+
contextDir: nativeContextDir,
|
|
6527
|
+
cas: options.cas ?? false,
|
|
6528
|
+
buildArgs: options.buildArgs
|
|
6529
|
+
};
|
|
6530
|
+
const forward = (event) => {
|
|
6531
|
+
try {
|
|
6532
|
+
emit(eventToEmitDict(event));
|
|
6533
|
+
} catch (error) {
|
|
6534
|
+
emitError ??= error;
|
|
6639
6535
|
}
|
|
6640
|
-
|
|
6536
|
+
};
|
|
6537
|
+
const resultJson = options.cas ? await __runWithInterrupt(
|
|
6538
|
+
options.signal,
|
|
6539
|
+
(interruptId) => binding.buildSandboxImage(nativeOptions, forward, interruptId)
|
|
6540
|
+
) : await binding.buildSandboxImage(nativeOptions, forward);
|
|
6641
6541
|
if (emitError != null) {
|
|
6642
6542
|
throw emitError;
|
|
6643
6543
|
}
|
|
@@ -6683,39 +6583,47 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
|
|
|
6683
6583
|
deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
|
|
6684
6584
|
);
|
|
6685
6585
|
}
|
|
6586
|
+
if (options.signal !== void 0 && !options.cas) {
|
|
6587
|
+
throw new Error(
|
|
6588
|
+
"signal is only supported for CAS image imports (cas: true); a legacy import has no Image Service build operation to cancel"
|
|
6589
|
+
);
|
|
6590
|
+
}
|
|
6686
6591
|
emit({
|
|
6687
6592
|
type: "status",
|
|
6688
6593
|
message: `Importing image '${reference}' as '${effectiveName}'...`
|
|
6689
6594
|
});
|
|
6690
6595
|
const binding = loadNativeBinding();
|
|
6691
6596
|
let emitError;
|
|
6692
|
-
const
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
}
|
|
6597
|
+
const nativeOptions = {
|
|
6598
|
+
apiUrl: context.apiUrl,
|
|
6599
|
+
bearerToken,
|
|
6600
|
+
imageReference: reference,
|
|
6601
|
+
registeredName: effectiveName,
|
|
6602
|
+
diskMb: options.diskMb,
|
|
6603
|
+
builderDiskMb: options.builderDiskMb,
|
|
6604
|
+
cpus: options.cpus,
|
|
6605
|
+
memoryMb: options.memoryMb,
|
|
6606
|
+
isPublic: options.isPublic ?? false,
|
|
6607
|
+
organizationId: usePat ? context.organizationId : void 0,
|
|
6608
|
+
projectId: usePat ? context.projectId : void 0,
|
|
6609
|
+
namespace: context.namespace,
|
|
6610
|
+
useScopeHeaders: usePat,
|
|
6611
|
+
userAgent: void 0,
|
|
6612
|
+
dockerCompat: options.dockerCompat ?? false,
|
|
6613
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6614
|
+
cas: options.cas ?? false
|
|
6615
|
+
};
|
|
6616
|
+
const forward = (event) => {
|
|
6617
|
+
try {
|
|
6618
|
+
emit(eventToEmitDict(event));
|
|
6619
|
+
} catch (error) {
|
|
6620
|
+
emitError ??= error;
|
|
6717
6621
|
}
|
|
6718
|
-
|
|
6622
|
+
};
|
|
6623
|
+
const resultJson = options.cas ? await __runWithInterrupt(
|
|
6624
|
+
options.signal,
|
|
6625
|
+
(interruptId) => binding.importSandboxImage(nativeOptions, forward, interruptId)
|
|
6626
|
+
) : await binding.importSandboxImage(nativeOptions, forward);
|
|
6719
6627
|
if (emitError != null) {
|
|
6720
6628
|
throw emitError;
|
|
6721
6629
|
}
|
|
@@ -6731,10 +6639,7 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
|
|
|
6731
6639
|
emit({ type: "done" });
|
|
6732
6640
|
return result;
|
|
6733
6641
|
}
|
|
6734
|
-
|
|
6735
|
-
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6736
|
-
throw new TypeError("imageName must be a non-empty string");
|
|
6737
|
-
}
|
|
6642
|
+
function catalogOptionsFromEnv() {
|
|
6738
6643
|
const context = buildContextFromEnv();
|
|
6739
6644
|
const bearerToken = context.apiKey;
|
|
6740
6645
|
if (!bearerToken) {
|
|
@@ -6745,66 +6650,76 @@ async function deleteSandboxImage(imageName) {
|
|
|
6745
6650
|
}
|
|
6746
6651
|
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6747
6652
|
}
|
|
6748
|
-
|
|
6749
|
-
apiUrl: context.apiUrl,
|
|
6750
|
-
apiKey: bearerToken,
|
|
6751
|
-
namespace: context.namespace
|
|
6752
|
-
});
|
|
6753
|
-
try {
|
|
6754
|
-
await client.deleteSandboxImage(imageName);
|
|
6755
|
-
} finally {
|
|
6756
|
-
client.close();
|
|
6757
|
-
}
|
|
6653
|
+
return { apiUrl: context.apiUrl, bearerToken, useScopeHeaders: false };
|
|
6758
6654
|
}
|
|
6759
|
-
|
|
6760
|
-
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6761
|
-
throw new TypeError("imageName must be a non-empty string");
|
|
6762
|
-
}
|
|
6655
|
+
function catalogOptionsFromCredentials(credentials) {
|
|
6763
6656
|
const context = buildContextFromEnv();
|
|
6764
|
-
const bearerToken = context.apiKey;
|
|
6657
|
+
const bearerToken = credentials.apiKey ?? context.apiKey;
|
|
6765
6658
|
if (!bearerToken) {
|
|
6766
|
-
if (context.personalAccessToken) {
|
|
6767
|
-
throw new Error(
|
|
6768
|
-
"Sandbox image SDKs require TENSORLAKE_API_KEY. Personal access tokens are CLI-only."
|
|
6769
|
-
);
|
|
6770
|
-
}
|
|
6771
6659
|
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6772
6660
|
}
|
|
6773
|
-
const
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
namespace: context.namespace
|
|
6777
|
-
});
|
|
6778
|
-
try {
|
|
6779
|
-
return await client.findSandboxImageByName(imageName);
|
|
6780
|
-
} finally {
|
|
6781
|
-
client.close();
|
|
6661
|
+
const { organizationId, projectId } = credentials;
|
|
6662
|
+
if (organizationId === void 0 !== (projectId === void 0)) {
|
|
6663
|
+
throw new TypeError("organizationId and projectId must be given together");
|
|
6782
6664
|
}
|
|
6665
|
+
return {
|
|
6666
|
+
apiUrl: credentials.apiUrl ?? context.apiUrl,
|
|
6667
|
+
bearerToken,
|
|
6668
|
+
organizationId,
|
|
6669
|
+
projectId,
|
|
6670
|
+
useScopeHeaders: organizationId !== void 0
|
|
6671
|
+
};
|
|
6783
6672
|
}
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
"Sandbox image SDKs require TENSORLAKE_API_KEY. Personal access tokens are CLI-only."
|
|
6791
|
-
);
|
|
6792
|
-
}
|
|
6793
|
-
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6673
|
+
function parseTemplate(json) {
|
|
6674
|
+
return JSON.parse(json);
|
|
6675
|
+
}
|
|
6676
|
+
async function deleteSandboxImage(imageName) {
|
|
6677
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6678
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6794
6679
|
}
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6680
|
+
await loadNativeBinding().deleteSandboxImage(catalogOptionsFromEnv(), imageName);
|
|
6681
|
+
}
|
|
6682
|
+
async function deleteSandboxImageWithCredentials(credentials, imageName) {
|
|
6683
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6684
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6685
|
+
}
|
|
6686
|
+
await loadNativeBinding().deleteSandboxImage(
|
|
6687
|
+
catalogOptionsFromCredentials(credentials),
|
|
6688
|
+
imageName
|
|
6689
|
+
);
|
|
6690
|
+
}
|
|
6691
|
+
async function findSandboxImageByName(imageName) {
|
|
6692
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6693
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6694
|
+
}
|
|
6695
|
+
const json = await loadNativeBinding().findSandboxImage(
|
|
6696
|
+
catalogOptionsFromEnv(),
|
|
6697
|
+
imageName
|
|
6698
|
+
);
|
|
6699
|
+
return json == null ? null : parseTemplate(json);
|
|
6700
|
+
}
|
|
6701
|
+
async function findSandboxImageByNameWithCredentials(credentials, imageName) {
|
|
6702
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6703
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6804
6704
|
}
|
|
6705
|
+
const json = await loadNativeBinding().findSandboxImage(
|
|
6706
|
+
catalogOptionsFromCredentials(credentials),
|
|
6707
|
+
imageName
|
|
6708
|
+
);
|
|
6709
|
+
return json == null ? null : parseTemplate(json);
|
|
6710
|
+
}
|
|
6711
|
+
async function listSandboxImages() {
|
|
6712
|
+
const json = await loadNativeBinding().listSandboxImages(catalogOptionsFromEnv());
|
|
6713
|
+
return JSON.parse(json);
|
|
6714
|
+
}
|
|
6715
|
+
async function listSandboxImagesWithCredentials(credentials) {
|
|
6716
|
+
const json = await loadNativeBinding().listSandboxImages(
|
|
6717
|
+
catalogOptionsFromCredentials(credentials)
|
|
6718
|
+
);
|
|
6719
|
+
return JSON.parse(json);
|
|
6805
6720
|
}
|
|
6806
6721
|
async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
|
|
6807
|
-
const parsed = (0,
|
|
6722
|
+
const parsed = (0, import_node_util.parseArgs)({
|
|
6808
6723
|
args: argv,
|
|
6809
6724
|
allowPositionals: true,
|
|
6810
6725
|
options: {
|
|
@@ -6858,7 +6773,7 @@ async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
|
|
|
6858
6773
|
);
|
|
6859
6774
|
}
|
|
6860
6775
|
async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
|
|
6861
|
-
const parsed = (0,
|
|
6776
|
+
const parsed = (0, import_node_util.parseArgs)({
|
|
6862
6777
|
args: argv,
|
|
6863
6778
|
allowPositionals: true,
|
|
6864
6779
|
options: {
|
|
@@ -6911,7 +6826,7 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
|
|
|
6911
6826
|
{ emit: ndjsonStdoutEmit, _allowPat: true }
|
|
6912
6827
|
);
|
|
6913
6828
|
}
|
|
6914
|
-
var import_node_path3, import_node_os2, import_node_fs2,
|
|
6829
|
+
var import_node_path3, import_node_os2, import_node_fs2, import_node_util, cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME2, __imageBuildInternals;
|
|
6915
6830
|
var init_sandbox_image = __esm({
|
|
6916
6831
|
"src/sandbox-image.ts"() {
|
|
6917
6832
|
"use strict";
|
|
@@ -6919,11 +6834,21 @@ var init_sandbox_image = __esm({
|
|
|
6919
6834
|
import_node_path3 = __toESM(require("path"), 1);
|
|
6920
6835
|
import_node_os2 = __toESM(require("os"), 1);
|
|
6921
6836
|
import_node_fs2 = require("fs");
|
|
6922
|
-
|
|
6923
|
-
init_cloud_client();
|
|
6837
|
+
import_node_util = require("util");
|
|
6924
6838
|
init_image();
|
|
6925
6839
|
init_native_binding();
|
|
6840
|
+
init_image_builds();
|
|
6926
6841
|
DEFAULT_IMAGE_NAME2 = "default";
|
|
6842
|
+
__imageBuildInternals = {
|
|
6843
|
+
loadNativeBinding: () => loadNativeBinding(),
|
|
6844
|
+
buildContextFromEnv: () => buildContextFromEnv(),
|
|
6845
|
+
stderrEmit: (event) => stderrEmit(event),
|
|
6846
|
+
noopEmit: (event) => noopEmit(event),
|
|
6847
|
+
eventToEmitDict: (event) => eventToEmitDict(event),
|
|
6848
|
+
imageRequiresContext: (image) => imageRequiresContext(image),
|
|
6849
|
+
defaultRegisteredName: (dockerfilePath) => defaultRegisteredName(dockerfilePath),
|
|
6850
|
+
defaultRegisteredNameFromImage: (reference) => defaultRegisteredNameFromImage(reference)
|
|
6851
|
+
};
|
|
6927
6852
|
}
|
|
6928
6853
|
});
|
|
6929
6854
|
|
|
@@ -6948,7 +6873,15 @@ __export(index_exports, {
|
|
|
6948
6873
|
Headers: () => Headers,
|
|
6949
6874
|
HttpBody: () => HttpBody,
|
|
6950
6875
|
Image: () => Image,
|
|
6876
|
+
ImageBuildCancelledError: () => ImageBuildCancelledError,
|
|
6877
|
+
ImageBuildError: () => ImageBuildError,
|
|
6878
|
+
ImageBuildFailedError: () => ImageBuildFailedError,
|
|
6879
|
+
ImageBuildHandle: () => ImageBuildHandle,
|
|
6880
|
+
ImageBuildInProgressError: () => ImageBuildInProgressError,
|
|
6881
|
+
ImageBuildInterruptedError: () => ImageBuildInterruptedError,
|
|
6882
|
+
ImageBuildNotFoundError: () => ImageBuildNotFoundError,
|
|
6951
6883
|
ImageBuildOperationType: () => ImageBuildOperationType,
|
|
6884
|
+
ImageBuildTimeoutError: () => ImageBuildTimeoutError,
|
|
6952
6885
|
MountError: () => MountError,
|
|
6953
6886
|
OutputMode: () => OutputMode,
|
|
6954
6887
|
PendingSandbox: () => PendingSandbox,
|
|
@@ -6981,12 +6914,14 @@ __export(index_exports, {
|
|
|
6981
6914
|
TERMINATION_REASON_CANCELLED: () => TERMINATION_REASON_CANCELLED,
|
|
6982
6915
|
TERMINATION_REASON_NO_CAPACITY: () => TERMINATION_REASON_NO_CAPACITY,
|
|
6983
6916
|
TcpTunnel: () => TcpTunnel,
|
|
6917
|
+
cancelImageBuild: () => cancelImageBuild,
|
|
6984
6918
|
createFileSystem: () => createFileSystem,
|
|
6985
6919
|
createSandboxImage: () => createSandboxImage,
|
|
6986
6920
|
deleteFileSystem: () => deleteFileSystem,
|
|
6987
6921
|
deleteSandboxImage: () => deleteSandboxImage,
|
|
6988
6922
|
dockerfileContent: () => dockerfileContent,
|
|
6989
6923
|
findSandboxImageByName: () => findSandboxImageByName,
|
|
6924
|
+
getImageBuild: () => getImageBuild,
|
|
6990
6925
|
importSandboxImage: () => importSandboxImage,
|
|
6991
6926
|
isSandboxPending: () => isSandboxPending,
|
|
6992
6927
|
listFileSystems: () => listFileSystems,
|
|
@@ -6998,7 +6933,10 @@ __export(index_exports, {
|
|
|
6998
6933
|
runLocal: () => runLocal,
|
|
6999
6934
|
runRemote: () => runRemote,
|
|
7000
6935
|
sandboxUrlFromIngressEndpoint: () => sandboxUrlFromIngressEndpoint,
|
|
7001
|
-
schema: () => schema
|
|
6936
|
+
schema: () => schema,
|
|
6937
|
+
startImageBuild: () => startImageBuild,
|
|
6938
|
+
startImageImport: () => startImageImport,
|
|
6939
|
+
waitImageBuild: () => waitImageBuild
|
|
7002
6940
|
});
|
|
7003
6941
|
module.exports = __toCommonJS(index_exports);
|
|
7004
6942
|
init_cjs_shims();
|
|
@@ -7008,11 +6946,546 @@ init_pending_sandbox();
|
|
|
7008
6946
|
init_sandbox();
|
|
7009
6947
|
init_desktop();
|
|
7010
6948
|
init_tunnel();
|
|
7011
|
-
|
|
6949
|
+
|
|
6950
|
+
// src/cloud-client.ts
|
|
6951
|
+
init_cjs_shims();
|
|
6952
|
+
var import_nanoid = require("nanoid");
|
|
6953
|
+
init_defaults();
|
|
6954
|
+
|
|
6955
|
+
// src/native-cloud.ts
|
|
6956
|
+
init_cjs_shims();
|
|
6957
|
+
init_native_sandbox();
|
|
6958
|
+
init_native_worker_client();
|
|
6959
|
+
var NativeCloudTransport = class {
|
|
6960
|
+
constructor(options) {
|
|
6961
|
+
this.options = options;
|
|
6962
|
+
if (!Number.isSafeInteger(options.maxRetries) || options.maxRetries < 0 || options.maxRetries > 4294967295) {
|
|
6963
|
+
throw new RangeError("maxRetries must be a non-negative 32-bit integer");
|
|
6964
|
+
}
|
|
6965
|
+
if (!Number.isFinite(options.retryBackoffMs) || options.retryBackoffMs < 0) {
|
|
6966
|
+
throw new RangeError("retryBackoffMs must be a non-negative finite number");
|
|
6967
|
+
}
|
|
6968
|
+
}
|
|
6969
|
+
native;
|
|
6970
|
+
closed = false;
|
|
6971
|
+
client() {
|
|
6972
|
+
if (this.closed) throw new Error("Tensorlake native client is closed");
|
|
6973
|
+
if (this.native) return this.native;
|
|
6974
|
+
const ctor = loadNativeSandboxBinding().NativeCloudClient;
|
|
6975
|
+
if (!ctor) throw new Error("Native binding does not export NativeCloudClient; rebuild with 'npm run build:native'");
|
|
6976
|
+
return this.native = new ctor(JSON.stringify(this.options));
|
|
6977
|
+
}
|
|
6978
|
+
close() {
|
|
6979
|
+
this.closed = true;
|
|
6980
|
+
releaseNativeHandle(this.native ?? null);
|
|
6981
|
+
this.native = void 0;
|
|
6982
|
+
}
|
|
6983
|
+
async requestResponse(method, path4, options) {
|
|
6984
|
+
const request = await serializeRequest(method, path4, options);
|
|
6985
|
+
const raw = await callNative(() => this.client().request(request));
|
|
6986
|
+
const response = new Response(
|
|
6987
|
+
[204, 205, 304].includes(raw.status) ? null : Uint8Array.from(raw.data).buffer,
|
|
6988
|
+
{ status: raw.status, headers: JSON.parse(raw.headersJson) }
|
|
6989
|
+
);
|
|
6990
|
+
return Object.assign(response, { traceId: raw.traceId });
|
|
6991
|
+
}
|
|
6992
|
+
async requestJson(method, path4) {
|
|
6993
|
+
const response = await this.requestResponse(method, path4);
|
|
6994
|
+
const text = await response.text();
|
|
6995
|
+
const value = text ? JSON.parse(text) : null;
|
|
6996
|
+
return Object.assign(value ?? {}, { traceId: response.traceId });
|
|
6997
|
+
}
|
|
6998
|
+
async *stream(method, path4, signal) {
|
|
6999
|
+
if (signal?.aborted) return;
|
|
7000
|
+
const request = await serializeRequest(method, path4, { headers: { Accept: "text/event-stream" } });
|
|
7001
|
+
yield* nativeEventStream((emit) => this.client().stream(request, emit), void 0, signal);
|
|
7002
|
+
}
|
|
7003
|
+
};
|
|
7004
|
+
async function serializeRequest(method, path4, options) {
|
|
7005
|
+
const headers = { ...options?.headers };
|
|
7006
|
+
let body = options?.body;
|
|
7007
|
+
if (options?.json !== void 0) {
|
|
7008
|
+
body = JSON.stringify(options.json);
|
|
7009
|
+
if (!Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) {
|
|
7010
|
+
headers["Content-Type"] = "application/json";
|
|
7011
|
+
}
|
|
7012
|
+
}
|
|
7013
|
+
const request = {
|
|
7014
|
+
method,
|
|
7015
|
+
path: path4,
|
|
7016
|
+
headersJson: JSON.stringify(headers),
|
|
7017
|
+
statusOnlyCodes: [...options?.statusOnlyCodes ?? []]
|
|
7018
|
+
};
|
|
7019
|
+
if (body instanceof FormData) {
|
|
7020
|
+
request.parts = [];
|
|
7021
|
+
for (const [name, value] of body.entries()) {
|
|
7022
|
+
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" });
|
|
7023
|
+
}
|
|
7024
|
+
} else if (body !== void 0) {
|
|
7025
|
+
if (body instanceof Blob) request.body = Buffer.from(await body.arrayBuffer());
|
|
7026
|
+
else if (typeof body === "string") request.body = Buffer.from(body);
|
|
7027
|
+
else if (body instanceof ArrayBuffer) request.body = Buffer.from(new Uint8Array(body));
|
|
7028
|
+
else request.body = Buffer.from(body);
|
|
7029
|
+
}
|
|
7030
|
+
return request;
|
|
7031
|
+
}
|
|
7032
|
+
|
|
7033
|
+
// src/cloud-client.ts
|
|
7034
|
+
init_models();
|
|
7035
|
+
init_sandbox_image();
|
|
7036
|
+
var CloudClient = class _CloudClient {
|
|
7037
|
+
transport;
|
|
7038
|
+
apiUrl;
|
|
7039
|
+
apiKey;
|
|
7040
|
+
organizationId;
|
|
7041
|
+
projectId;
|
|
7042
|
+
namespace;
|
|
7043
|
+
constructor(options) {
|
|
7044
|
+
this.apiUrl = options?.apiUrl ?? API_URL;
|
|
7045
|
+
this.apiKey = options?.apiKey ?? API_KEY;
|
|
7046
|
+
this.organizationId = options?.organizationId;
|
|
7047
|
+
this.projectId = options?.projectId;
|
|
7048
|
+
this.namespace = options?.namespace ?? NAMESPACE;
|
|
7049
|
+
this.transport = new NativeCloudTransport({
|
|
7050
|
+
baseUrl: options?.apiUrl ?? API_URL,
|
|
7051
|
+
apiKey: options?.apiKey ?? API_KEY,
|
|
7052
|
+
organizationId: this.organizationId,
|
|
7053
|
+
projectId: this.projectId,
|
|
7054
|
+
maxRetries: options?.maxRetries ?? MAX_RETRIES,
|
|
7055
|
+
retryBackoffMs: options?.retryBackoffMs ?? RETRY_BACKOFF_MS,
|
|
7056
|
+
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
7057
|
+
userAgent: `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
7058
|
+
});
|
|
7059
|
+
}
|
|
7060
|
+
static forCloud(options) {
|
|
7061
|
+
return new _CloudClient(options);
|
|
7062
|
+
}
|
|
7063
|
+
close() {
|
|
7064
|
+
this.transport.close();
|
|
7065
|
+
}
|
|
7066
|
+
async upsertApplication(manifest, codeZip, upgradeRunningRequests = false) {
|
|
7067
|
+
const applicationManifest = { ...manifest };
|
|
7068
|
+
let publicEndpointId = publicEndpointIdFromManifest(applicationManifest);
|
|
7069
|
+
if (applicationAllowsUnauthenticatedRequests(applicationManifest) && publicEndpointId === void 0) {
|
|
7070
|
+
const applicationName = applicationManifest.name;
|
|
7071
|
+
if (typeof applicationName === "string" && applicationName.length > 0) {
|
|
7072
|
+
publicEndpointId = await this.existingApplicationPublicEndpointId(applicationName);
|
|
7073
|
+
}
|
|
7074
|
+
publicEndpointId ??= generatePublicEndpointId();
|
|
7075
|
+
}
|
|
7076
|
+
if (publicEndpointId !== void 0) {
|
|
7077
|
+
applicationManifest.public_endpoint_id = publicEndpointId;
|
|
7078
|
+
delete applicationManifest.publicEndpointId;
|
|
7079
|
+
}
|
|
7080
|
+
const form = new FormData();
|
|
7081
|
+
form.append(
|
|
7082
|
+
"code",
|
|
7083
|
+
new Blob([toBlobPart(codeZip)], { type: "application/zip" }),
|
|
7084
|
+
"code.zip"
|
|
7085
|
+
);
|
|
7086
|
+
form.append("code_content_type", "application/zip");
|
|
7087
|
+
form.append("application", JSON.stringify(applicationManifest));
|
|
7088
|
+
form.append(
|
|
7089
|
+
"upgrade_requests_to_latest_code",
|
|
7090
|
+
String(upgradeRunningRequests)
|
|
7091
|
+
);
|
|
7092
|
+
await this.transport.requestResponse("POST", this.namespacePath("applications"), {
|
|
7093
|
+
body: form
|
|
7094
|
+
});
|
|
7095
|
+
}
|
|
7096
|
+
async deleteApplication(applicationName) {
|
|
7097
|
+
await this.transport.requestResponse(
|
|
7098
|
+
"DELETE",
|
|
7099
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
7100
|
+
);
|
|
7101
|
+
}
|
|
7102
|
+
/**
|
|
7103
|
+
* Delete a registered sandbox image by name or id through the merged
|
|
7104
|
+
* catalog, with this client's credentials: an `image_` id or a name the
|
|
7105
|
+
* Image Service knows deletes a CAS image, a `sandbox_template_` id or a
|
|
7106
|
+
* name registered only in the platform registry deletes a legacy image.
|
|
7107
|
+
* Rejects when neither catalog knows the reference. The same semantics
|
|
7108
|
+
* and accepted differences as the module-level `deleteSandboxImage`.
|
|
7109
|
+
*/
|
|
7110
|
+
async deleteSandboxImage(imageName) {
|
|
7111
|
+
await deleteSandboxImageWithCredentials(this.catalogCredentials(), imageName);
|
|
7112
|
+
}
|
|
7113
|
+
/**
|
|
7114
|
+
* Look up a registered sandbox image by name or id through the merged
|
|
7115
|
+
* catalog, with this client's credentials. Returns the image in the
|
|
7116
|
+
* sandbox-template shape, or `null` when neither the Image Service nor the
|
|
7117
|
+
* platform registry knows the reference. An explicit organization/project
|
|
7118
|
+
* scope (the client's, or the call's override) addresses that project's
|
|
7119
|
+
* routes directly, as before; without one the key's own scope applies.
|
|
7120
|
+
*/
|
|
7121
|
+
async findSandboxImageByName(imageName, options) {
|
|
7122
|
+
return findSandboxImageByNameWithCredentials(
|
|
7123
|
+
this.catalogCredentials(options),
|
|
7124
|
+
imageName
|
|
7125
|
+
);
|
|
7126
|
+
}
|
|
7127
|
+
/**
|
|
7128
|
+
* List every registered sandbox image of the project (CAS and legacy, in
|
|
7129
|
+
* the sandbox-template shape, newest first) through the merged catalog,
|
|
7130
|
+
* with this client's credentials. An explicit organization/project scope
|
|
7131
|
+
* (the client's, or the call's override) addresses that project's routes
|
|
7132
|
+
* directly, as before; without one the key's own scope applies.
|
|
7133
|
+
*/
|
|
7134
|
+
async listSandboxImages(options) {
|
|
7135
|
+
return listSandboxImagesWithCredentials(this.catalogCredentials(options));
|
|
7136
|
+
}
|
|
7137
|
+
catalogCredentials(options) {
|
|
7138
|
+
return {
|
|
7139
|
+
apiUrl: this.apiUrl,
|
|
7140
|
+
apiKey: this.apiKey,
|
|
7141
|
+
organizationId: options?.organizationId ?? this.organizationId,
|
|
7142
|
+
projectId: options?.projectId ?? this.projectId
|
|
7143
|
+
};
|
|
7144
|
+
}
|
|
7145
|
+
async applications() {
|
|
7146
|
+
const raw = await this.transport.requestJson(
|
|
7147
|
+
"GET",
|
|
7148
|
+
this.namespacePath("applications")
|
|
7149
|
+
);
|
|
7150
|
+
return (raw.applications ?? []).map(
|
|
7151
|
+
(application) => fromSnakeKeys(application)
|
|
7152
|
+
);
|
|
7153
|
+
}
|
|
7154
|
+
async applicationManifest(applicationName) {
|
|
7155
|
+
const raw = await this.transport.requestJson(
|
|
7156
|
+
"GET",
|
|
7157
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
7158
|
+
);
|
|
7159
|
+
return fromSnakeKeys(raw);
|
|
7160
|
+
}
|
|
7161
|
+
async runRequest(applicationName, inputs = []) {
|
|
7162
|
+
const path4 = this.namespacePath(
|
|
7163
|
+
`applications/${encodeURIComponent(applicationName)}`
|
|
7164
|
+
);
|
|
7165
|
+
const response = inputs.length === 0 ? await this.transport.requestResponse("POST", path4, {
|
|
7166
|
+
body: new Uint8Array(),
|
|
7167
|
+
headers: { Accept: "application/json" }
|
|
7168
|
+
}) : inputs.length === 1 && inputs[0].name === "0" ? await this.transport.requestResponse("POST", path4, {
|
|
7169
|
+
body: toRequestBody(inputs[0].data),
|
|
7170
|
+
headers: {
|
|
7171
|
+
Accept: "application/json",
|
|
7172
|
+
"Content-Type": inputs[0].contentType
|
|
7173
|
+
}
|
|
7174
|
+
}) : await this.runMultipartRequest(path4, inputs);
|
|
7175
|
+
const body = await parseJsonResponse(response);
|
|
7176
|
+
const requestId = body?.request_id;
|
|
7177
|
+
if (!requestId) {
|
|
7178
|
+
throw new Error("missing request_id in run request response body");
|
|
7179
|
+
}
|
|
7180
|
+
return requestId;
|
|
7181
|
+
}
|
|
7182
|
+
async waitOnRequestCompletion(applicationName, requestId) {
|
|
7183
|
+
const stream = this.transport.stream(
|
|
7184
|
+
"GET",
|
|
7185
|
+
this.namespacePath(
|
|
7186
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/progress`
|
|
7187
|
+
)
|
|
7188
|
+
);
|
|
7189
|
+
for await (const event of stream) {
|
|
7190
|
+
if (Object.prototype.hasOwnProperty.call(event, "RequestFinished")) {
|
|
7191
|
+
return;
|
|
7192
|
+
}
|
|
7193
|
+
}
|
|
7194
|
+
throw new Error("progress stream ended before request completion");
|
|
7195
|
+
}
|
|
7196
|
+
async requestMetadata(applicationName, requestId) {
|
|
7197
|
+
const raw = await this.transport.requestJson(
|
|
7198
|
+
"GET",
|
|
7199
|
+
this.namespacePath(
|
|
7200
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}`
|
|
7201
|
+
)
|
|
7202
|
+
);
|
|
7203
|
+
return fromSnakeKeys(raw);
|
|
7204
|
+
}
|
|
7205
|
+
async requestOutput(applicationName, requestId) {
|
|
7206
|
+
const response = await this.transport.requestResponse(
|
|
7207
|
+
"GET",
|
|
7208
|
+
this.namespacePath(
|
|
7209
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/output`
|
|
7210
|
+
)
|
|
7211
|
+
);
|
|
7212
|
+
const serializedValue = new Uint8Array(await response.arrayBuffer());
|
|
7213
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
7214
|
+
return {
|
|
7215
|
+
serializedValue,
|
|
7216
|
+
contentType
|
|
7217
|
+
};
|
|
7218
|
+
}
|
|
7219
|
+
async listSecrets(options) {
|
|
7220
|
+
const base = this.secretCollectionPath(
|
|
7221
|
+
options?.organizationId,
|
|
7222
|
+
options?.projectId
|
|
7223
|
+
);
|
|
7224
|
+
const raw = await this.transport.requestJson("GET", base);
|
|
7225
|
+
const pageSize = Math.max(0, options?.pageSize ?? 100);
|
|
7226
|
+
return Object.assign(
|
|
7227
|
+
{
|
|
7228
|
+
items: raw.slice(0, pageSize).map(secretFromMetadata),
|
|
7229
|
+
pagination: { total: raw.length }
|
|
7230
|
+
},
|
|
7231
|
+
{ traceId: raw.traceId }
|
|
7232
|
+
);
|
|
7233
|
+
}
|
|
7234
|
+
async getSecret(secretId, options) {
|
|
7235
|
+
const base = this.secretCollectionPath(
|
|
7236
|
+
options?.organizationId,
|
|
7237
|
+
options?.projectId
|
|
7238
|
+
);
|
|
7239
|
+
const raw = await this.transport.requestJson(
|
|
7240
|
+
"GET",
|
|
7241
|
+
`${base}/${encodeURIComponent(secretId)}`
|
|
7242
|
+
);
|
|
7243
|
+
return Object.assign(secretFromMetadata(raw), { traceId: raw.traceId });
|
|
7244
|
+
}
|
|
7245
|
+
async upsertSecrets(secrets, options) {
|
|
7246
|
+
const base = this.secretCollectionPath(
|
|
7247
|
+
options?.organizationId,
|
|
7248
|
+
options?.projectId
|
|
7249
|
+
);
|
|
7250
|
+
if (Array.isArray(secrets)) {
|
|
7251
|
+
const results = [];
|
|
7252
|
+
for (const secret of secrets) {
|
|
7253
|
+
results.push(await this.upsertSecret(base, secret));
|
|
7254
|
+
}
|
|
7255
|
+
return results;
|
|
7256
|
+
}
|
|
7257
|
+
return this.upsertSecret(base, secrets);
|
|
7258
|
+
}
|
|
7259
|
+
async deleteSecret(secretId, options) {
|
|
7260
|
+
const base = this.secretCollectionPath(
|
|
7261
|
+
options?.organizationId,
|
|
7262
|
+
options?.projectId
|
|
7263
|
+
);
|
|
7264
|
+
await this.transport.requestResponse(
|
|
7265
|
+
"DELETE",
|
|
7266
|
+
`${base}/${encodeURIComponent(secretId)}`
|
|
7267
|
+
);
|
|
7268
|
+
}
|
|
7269
|
+
async upsertSecret(base, secret) {
|
|
7270
|
+
let response = await this.transport.requestResponse("POST", base, {
|
|
7271
|
+
json: secret,
|
|
7272
|
+
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() },
|
|
7273
|
+
statusOnlyCodes: /* @__PURE__ */ new Set([409])
|
|
7274
|
+
});
|
|
7275
|
+
if (response.status === 409) {
|
|
7276
|
+
const prefix = base.slice(0, -"/secrets".length);
|
|
7277
|
+
const existing = await this.transport.requestJson(
|
|
7278
|
+
"GET",
|
|
7279
|
+
`${prefix}/secret-names/${encodeURIComponent(secret.name)}`
|
|
7280
|
+
);
|
|
7281
|
+
response = await this.transport.requestResponse(
|
|
7282
|
+
"POST",
|
|
7283
|
+
`${base}/${encodeURIComponent(existing.id)}/versions`,
|
|
7284
|
+
{
|
|
7285
|
+
json: { value: secret.value },
|
|
7286
|
+
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() }
|
|
7287
|
+
}
|
|
7288
|
+
);
|
|
7289
|
+
}
|
|
7290
|
+
const metadata = await parseJsonResponse(response);
|
|
7291
|
+
return Object.assign(secretFromMetadata(metadata), {
|
|
7292
|
+
traceId: response.traceId
|
|
7293
|
+
});
|
|
7294
|
+
}
|
|
7295
|
+
async startImageBuild(buildServicePath, request) {
|
|
7296
|
+
const form = new FormData();
|
|
7297
|
+
form.append("graph_name", request.applicationName);
|
|
7298
|
+
form.append("graph_version", request.applicationVersion);
|
|
7299
|
+
form.append("graph_function_name", request.functionName);
|
|
7300
|
+
form.append("image_name", request.imageName);
|
|
7301
|
+
form.append("image_id", request.imageId);
|
|
7302
|
+
form.append(
|
|
7303
|
+
"context",
|
|
7304
|
+
new Blob([toBlobPart(request.buildContext)]),
|
|
7305
|
+
"context.tar.gz"
|
|
7306
|
+
);
|
|
7307
|
+
const response = await this.transport.requestResponse(
|
|
7308
|
+
"PUT",
|
|
7309
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds`,
|
|
7310
|
+
{ body: form }
|
|
7311
|
+
);
|
|
7312
|
+
const raw = await parseJsonResponse(response);
|
|
7313
|
+
return fromSnakeKeys(raw);
|
|
7314
|
+
}
|
|
7315
|
+
async createApplicationBuild(buildServicePath, request, imageContexts) {
|
|
7316
|
+
const form = createApplicationBuildForm(request, imageContexts);
|
|
7317
|
+
const response = await this.transport.requestResponse(
|
|
7318
|
+
"POST",
|
|
7319
|
+
trimTrailingSlashes2(buildServicePath),
|
|
7320
|
+
{ body: form }
|
|
7321
|
+
);
|
|
7322
|
+
const raw = await parseJsonResponse(response);
|
|
7323
|
+
return fromSnakeKeys(raw);
|
|
7324
|
+
}
|
|
7325
|
+
async applicationBuildInfo(buildServicePath, applicationBuildId) {
|
|
7326
|
+
const raw = await this.transport.requestJson(
|
|
7327
|
+
"GET",
|
|
7328
|
+
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}`
|
|
7329
|
+
);
|
|
7330
|
+
return fromSnakeKeys(raw);
|
|
7331
|
+
}
|
|
7332
|
+
async cancelApplicationBuild(buildServicePath, applicationBuildId) {
|
|
7333
|
+
const raw = await this.transport.requestJson(
|
|
7334
|
+
"POST",
|
|
7335
|
+
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}/cancel`
|
|
7336
|
+
);
|
|
7337
|
+
return fromSnakeKeys(raw);
|
|
7338
|
+
}
|
|
7339
|
+
async buildInfo(buildServicePath, buildId) {
|
|
7340
|
+
const raw = await this.transport.requestJson(
|
|
7341
|
+
"GET",
|
|
7342
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}`
|
|
7343
|
+
);
|
|
7344
|
+
return fromSnakeKeys(raw);
|
|
7345
|
+
}
|
|
7346
|
+
async cancelBuild(buildServicePath, buildId) {
|
|
7347
|
+
await this.transport.requestResponse(
|
|
7348
|
+
"POST",
|
|
7349
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/cancel`
|
|
7350
|
+
);
|
|
7351
|
+
}
|
|
7352
|
+
async *streamBuildLogs(buildServicePath, buildId, signal) {
|
|
7353
|
+
const stream = this.transport.stream(
|
|
7354
|
+
"GET",
|
|
7355
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/logs`,
|
|
7356
|
+
signal
|
|
7357
|
+
);
|
|
7358
|
+
for await (const event of stream) {
|
|
7359
|
+
yield fromSnakeKeys(event);
|
|
7360
|
+
}
|
|
7361
|
+
}
|
|
7362
|
+
async runMultipartRequest(path4, inputs) {
|
|
7363
|
+
const form = new FormData();
|
|
7364
|
+
for (const input of inputs) {
|
|
7365
|
+
form.append(
|
|
7366
|
+
input.name,
|
|
7367
|
+
new Blob([toBlobPart(input.data)], { type: input.contentType }),
|
|
7368
|
+
input.name
|
|
7369
|
+
);
|
|
7370
|
+
}
|
|
7371
|
+
return this.transport.requestResponse("POST", path4, {
|
|
7372
|
+
body: form,
|
|
7373
|
+
headers: { Accept: "application/json" }
|
|
7374
|
+
});
|
|
7375
|
+
}
|
|
7376
|
+
namespacePath(subpath) {
|
|
7377
|
+
return `/v1/namespaces/${encodeURIComponent(this.namespace)}/${subpath.replace(/^\/+/, "")}`;
|
|
7378
|
+
}
|
|
7379
|
+
async existingApplicationPublicEndpointId(applicationName) {
|
|
7380
|
+
const response = await this.transport.requestResponse(
|
|
7381
|
+
"GET",
|
|
7382
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`),
|
|
7383
|
+
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
7384
|
+
);
|
|
7385
|
+
if (response.status === 404) {
|
|
7386
|
+
return void 0;
|
|
7387
|
+
}
|
|
7388
|
+
const application = await parseJsonResponse(response);
|
|
7389
|
+
return publicEndpointIdFromManifest(application);
|
|
7390
|
+
}
|
|
7391
|
+
secretCollectionPath(organizationId, projectId) {
|
|
7392
|
+
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
7393
|
+
const resolvedProjectId = projectId ?? this.projectId;
|
|
7394
|
+
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
7395
|
+
return this.namespacePath("secrets");
|
|
7396
|
+
}
|
|
7397
|
+
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
7398
|
+
throw new Error("organizationId and projectId must be provided together");
|
|
7399
|
+
}
|
|
7400
|
+
return this.namespacePath("secrets");
|
|
7401
|
+
}
|
|
7402
|
+
};
|
|
7403
|
+
function secretFromMetadata(metadata) {
|
|
7404
|
+
return {
|
|
7405
|
+
id: metadata.id,
|
|
7406
|
+
name: metadata.name,
|
|
7407
|
+
createdAt: new Date(metadata.created_at_ms)
|
|
7408
|
+
};
|
|
7409
|
+
}
|
|
7410
|
+
var UNAUTHENTICATED_REQUESTS = "unauthenticated_requests";
|
|
7411
|
+
function applicationAllowsUnauthenticatedRequests(manifest) {
|
|
7412
|
+
return Array.isArray(manifest.allow) && manifest.allow.includes(UNAUTHENTICATED_REQUESTS);
|
|
7413
|
+
}
|
|
7414
|
+
function publicEndpointIdFromManifest(manifest) {
|
|
7415
|
+
for (const key of ["public_endpoint_id", "publicEndpointId"]) {
|
|
7416
|
+
const value = manifest[key];
|
|
7417
|
+
if (typeof value === "string" && value.length > 0) {
|
|
7418
|
+
return value;
|
|
7419
|
+
}
|
|
7420
|
+
}
|
|
7421
|
+
return void 0;
|
|
7422
|
+
}
|
|
7423
|
+
function generatePublicEndpointId() {
|
|
7424
|
+
return `endpoint_${(0, import_nanoid.nanoid)()}`;
|
|
7425
|
+
}
|
|
7426
|
+
function createApplicationBuildForm(request, imageContexts) {
|
|
7427
|
+
const contextsByPartName = /* @__PURE__ */ new Map();
|
|
7428
|
+
for (const context of imageContexts) {
|
|
7429
|
+
if (contextsByPartName.has(context.contextTarPartName)) {
|
|
7430
|
+
throw new Error(
|
|
7431
|
+
`duplicate image context part name '${context.contextTarPartName}'`
|
|
7432
|
+
);
|
|
7433
|
+
}
|
|
7434
|
+
contextsByPartName.set(context.contextTarPartName, context);
|
|
7435
|
+
}
|
|
7436
|
+
const form = new FormData();
|
|
7437
|
+
form.append(
|
|
7438
|
+
"app_version",
|
|
7439
|
+
new Blob([JSON.stringify(request)], { type: "application/json" }),
|
|
7440
|
+
"app_version"
|
|
7441
|
+
);
|
|
7442
|
+
for (const image of request.images) {
|
|
7443
|
+
const context = contextsByPartName.get(image.contextTarPartName);
|
|
7444
|
+
if (!context) {
|
|
7445
|
+
throw new Error(
|
|
7446
|
+
`missing image context for part '${image.contextTarPartName}'`
|
|
7447
|
+
);
|
|
7448
|
+
}
|
|
7449
|
+
form.append(
|
|
7450
|
+
image.contextTarPartName,
|
|
7451
|
+
new Blob([toBlobPart(context.contextTarGz)]),
|
|
7452
|
+
`${image.contextTarPartName}.tar.gz`
|
|
7453
|
+
);
|
|
7454
|
+
}
|
|
7455
|
+
for (const context of imageContexts) {
|
|
7456
|
+
if (!request.images.some((image) => image.contextTarPartName === context.contextTarPartName)) {
|
|
7457
|
+
throw new Error(
|
|
7458
|
+
`unexpected image context for part '${context.contextTarPartName}'`
|
|
7459
|
+
);
|
|
7460
|
+
}
|
|
7461
|
+
}
|
|
7462
|
+
return form;
|
|
7463
|
+
}
|
|
7464
|
+
function trimTrailingSlashes2(value) {
|
|
7465
|
+
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
7466
|
+
}
|
|
7467
|
+
function toBlobPart(data) {
|
|
7468
|
+
if (typeof data === "string" || data instanceof Blob) {
|
|
7469
|
+
return data;
|
|
7470
|
+
}
|
|
7471
|
+
if (data instanceof Uint8Array) {
|
|
7472
|
+
return Uint8Array.from(data).buffer;
|
|
7473
|
+
}
|
|
7474
|
+
return data;
|
|
7475
|
+
}
|
|
7476
|
+
function toRequestBody(data) {
|
|
7477
|
+
return toBlobPart(data);
|
|
7478
|
+
}
|
|
7479
|
+
async function parseJsonResponse(response) {
|
|
7480
|
+
const text = await response.text();
|
|
7481
|
+
if (!text) {
|
|
7482
|
+
return void 0;
|
|
7483
|
+
}
|
|
7484
|
+
return JSON.parse(text);
|
|
7485
|
+
}
|
|
7012
7486
|
|
|
7013
7487
|
// src/api-client.ts
|
|
7014
7488
|
init_cjs_shims();
|
|
7015
|
-
init_cloud_client();
|
|
7016
7489
|
|
|
7017
7490
|
// src/filesystem.ts
|
|
7018
7491
|
init_cjs_shims();
|
|
@@ -7021,21 +7494,21 @@ var import_node_crypto2 = require("crypto");
|
|
|
7021
7494
|
// src/mount-cli.ts
|
|
7022
7495
|
init_cjs_shims();
|
|
7023
7496
|
var import_node_child_process = require("child_process");
|
|
7024
|
-
var
|
|
7025
|
-
var
|
|
7026
|
-
var
|
|
7027
|
-
var
|
|
7497
|
+
var import_node_fs3 = require("fs");
|
|
7498
|
+
var import_node_os3 = require("os");
|
|
7499
|
+
var import_node_path4 = require("path");
|
|
7500
|
+
var import_node_util2 = require("util");
|
|
7028
7501
|
|
|
7029
7502
|
// src/filesystem-models.ts
|
|
7030
7503
|
init_cjs_shims();
|
|
7031
7504
|
var GIT_MODE_DIR = 16384;
|
|
7032
7505
|
var GIT_MODE_SYMLINK = 40960;
|
|
7033
|
-
function trimSlashes(
|
|
7506
|
+
function trimSlashes(path4) {
|
|
7034
7507
|
let start = 0;
|
|
7035
|
-
let end =
|
|
7036
|
-
while (start < end &&
|
|
7037
|
-
while (end > start &&
|
|
7038
|
-
return
|
|
7508
|
+
let end = path4.length;
|
|
7509
|
+
while (start < end && path4.charCodeAt(start) === 47) start += 1;
|
|
7510
|
+
while (end > start && path4.charCodeAt(end - 1) === 47) end -= 1;
|
|
7511
|
+
return path4.slice(start, end);
|
|
7039
7512
|
}
|
|
7040
7513
|
function fileEntryFromWire(entry, dirPath) {
|
|
7041
7514
|
const mode = entry.mode ?? 33188;
|
|
@@ -7053,9 +7526,9 @@ function fileEntryFromWire(entry, dirPath) {
|
|
|
7053
7526
|
}
|
|
7054
7527
|
function mountStatusFromRaw(raw, localPath) {
|
|
7055
7528
|
const mounted = "mounted" in raw ? Boolean(raw.mounted) : "active" in raw ? Boolean(raw.active) : true;
|
|
7056
|
-
const
|
|
7529
|
+
const path4 = String(raw.path || raw.mount_path || localPath || "");
|
|
7057
7530
|
const filesystem = raw.filesystem || raw.file_system || raw.repository || null;
|
|
7058
|
-
return { path:
|
|
7531
|
+
return { path: path4, filesystem, mounted, raw };
|
|
7059
7532
|
}
|
|
7060
7533
|
var FilesystemError = class extends Error {
|
|
7061
7534
|
constructor(message) {
|
|
@@ -7074,11 +7547,11 @@ var FilesystemNotFoundError = class extends FilesystemError {
|
|
|
7074
7547
|
var FileNotFoundInFilesystemError = class extends FilesystemError {
|
|
7075
7548
|
filesystem;
|
|
7076
7549
|
path;
|
|
7077
|
-
constructor(filesystem,
|
|
7078
|
-
super(`File not found in filesystem ${filesystem}: ${
|
|
7550
|
+
constructor(filesystem, path4) {
|
|
7551
|
+
super(`File not found in filesystem ${filesystem}: ${path4}`);
|
|
7079
7552
|
this.name = "FileNotFoundInFilesystemError";
|
|
7080
7553
|
this.filesystem = filesystem;
|
|
7081
|
-
this.path =
|
|
7554
|
+
this.path = path4;
|
|
7082
7555
|
}
|
|
7083
7556
|
};
|
|
7084
7557
|
var FilesystemAPIError = class extends FilesystemError {
|
|
@@ -7113,7 +7586,7 @@ var CliNotFoundError = class extends MountError {
|
|
|
7113
7586
|
};
|
|
7114
7587
|
|
|
7115
7588
|
// src/mount-cli.ts
|
|
7116
|
-
var execFileAsync = (0,
|
|
7589
|
+
var execFileAsync = (0, import_node_util2.promisify)(import_node_child_process.execFile);
|
|
7117
7590
|
var MountCli = class {
|
|
7118
7591
|
constructor(command, envOverrides) {
|
|
7119
7592
|
this.command = command;
|
|
@@ -7124,9 +7597,9 @@ var MountCli = class {
|
|
|
7124
7597
|
const candidates = [];
|
|
7125
7598
|
if (process.env.TENSORLAKE_CLI) candidates.push(process.env.TENSORLAKE_CLI);
|
|
7126
7599
|
candidates.push("tl");
|
|
7127
|
-
const installed = (0,
|
|
7600
|
+
const installed = (0, import_node_path4.join)((0, import_node_os3.homedir)(), ".tensorlake", "bin", "tl");
|
|
7128
7601
|
try {
|
|
7129
|
-
(0,
|
|
7602
|
+
(0, import_node_fs3.accessSync)(installed, import_node_fs3.constants.F_OK);
|
|
7130
7603
|
candidates.push(installed);
|
|
7131
7604
|
} catch {
|
|
7132
7605
|
}
|
|
@@ -7432,8 +7905,8 @@ var Filesystem = class {
|
|
|
7432
7905
|
}
|
|
7433
7906
|
// -- writes -------------------------------------------------------------------
|
|
7434
7907
|
/** Write one file. Returns the snapshot (version) the write produced. */
|
|
7435
|
-
async writeFile(
|
|
7436
|
-
return await this.writeFiles(/* @__PURE__ */ new Map([[
|
|
7908
|
+
async writeFile(path4, data, message) {
|
|
7909
|
+
return await this.writeFiles(/* @__PURE__ */ new Map([[path4, data]]), message);
|
|
7437
7910
|
}
|
|
7438
7911
|
/** Write several files (and/or delete paths) in one atomic snapshot. */
|
|
7439
7912
|
async writeFiles(files, message, deletes = []) {
|
|
@@ -7441,8 +7914,8 @@ var Filesystem = class {
|
|
|
7441
7914
|
if (entries.length === 0 && deletes.length === 0) {
|
|
7442
7915
|
throw new FilesystemError("nothing to write: no files or deletions given");
|
|
7443
7916
|
}
|
|
7444
|
-
const writes = entries.map(([
|
|
7445
|
-
path:
|
|
7917
|
+
const writes = entries.map(([path4, data]) => ({
|
|
7918
|
+
path: path4,
|
|
7446
7919
|
content: toBuffer(data)
|
|
7447
7920
|
}));
|
|
7448
7921
|
const resolvedMessage = message || `write ${writes.length} file(s) via SDK`;
|
|
@@ -7458,9 +7931,9 @@ var Filesystem = class {
|
|
|
7458
7931
|
* Stream one local file directly to object storage in bounded parts.
|
|
7459
7932
|
* This is the memory-bounded API for multi-GiB files.
|
|
7460
7933
|
*/
|
|
7461
|
-
async writeFileFromPath(
|
|
7934
|
+
async writeFileFromPath(path4, localPath, message) {
|
|
7462
7935
|
return await this.writeFilesFromPaths(
|
|
7463
|
-
/* @__PURE__ */ new Map([[
|
|
7936
|
+
/* @__PURE__ */ new Map([[path4, localPath]]),
|
|
7464
7937
|
message
|
|
7465
7938
|
);
|
|
7466
7939
|
}
|
|
@@ -7473,7 +7946,7 @@ var Filesystem = class {
|
|
|
7473
7946
|
if (entries.length === 0) {
|
|
7474
7947
|
throw new FilesystemError("nothing to write: no local files given");
|
|
7475
7948
|
}
|
|
7476
|
-
const writes = entries.map(([
|
|
7949
|
+
const writes = entries.map(([path4, localPath]) => ({ path: path4, localPath }));
|
|
7477
7950
|
const resolvedMessage = message || `write ${writes.length} local file(s) via SDK`;
|
|
7478
7951
|
const branch = await this.branch();
|
|
7479
7952
|
const traced = await callNative2(
|
|
@@ -7550,11 +8023,11 @@ var Filesystem = class {
|
|
|
7550
8023
|
};
|
|
7551
8024
|
}
|
|
7552
8025
|
/** Delete one file. Returns the durable version the deletion produced. */
|
|
7553
|
-
async deleteFile(
|
|
8026
|
+
async deleteFile(path4, message) {
|
|
7554
8027
|
return await this.writeFiles(
|
|
7555
8028
|
/* @__PURE__ */ new Map(),
|
|
7556
|
-
message || `delete ${
|
|
7557
|
-
[
|
|
8029
|
+
message || `delete ${path4} via SDK`,
|
|
8030
|
+
[path4]
|
|
7558
8031
|
);
|
|
7559
8032
|
}
|
|
7560
8033
|
/**
|
|
@@ -7605,15 +8078,15 @@ var Filesystem = class {
|
|
|
7605
8078
|
* Read a file's bytes at `version` (the current `main` head or a retained
|
|
7606
8079
|
* snapshot id; defaults to the filesystem's current head).
|
|
7607
8080
|
*/
|
|
7608
|
-
async readFile(
|
|
7609
|
-
return (await this.readFileWithMetadata(
|
|
8081
|
+
async readFile(path4, version) {
|
|
8082
|
+
return (await this.readFileWithMetadata(path4, { version })).data;
|
|
7610
8083
|
}
|
|
7611
8084
|
/**
|
|
7612
8085
|
* Read bytes and immutable metadata in one request. A range is executed by
|
|
7613
8086
|
* Artifact Storage, so callers never download the unrequested remainder.
|
|
7614
8087
|
*/
|
|
7615
|
-
async readFileWithMetadata(
|
|
7616
|
-
if (trimSlashes(
|
|
8088
|
+
async readFileWithMetadata(path4, options = {}) {
|
|
8089
|
+
if (trimSlashes(path4) === "") {
|
|
7617
8090
|
throw new FilesystemError("file path must not be empty");
|
|
7618
8091
|
}
|
|
7619
8092
|
const range = options.range;
|
|
@@ -7626,12 +8099,12 @@ var Filesystem = class {
|
|
|
7626
8099
|
const traced = await callNative2(
|
|
7627
8100
|
() => this.native.readFilesystemFile(
|
|
7628
8101
|
this.name,
|
|
7629
|
-
|
|
8102
|
+
path4,
|
|
7630
8103
|
resolvedVersion,
|
|
7631
8104
|
range?.offset,
|
|
7632
8105
|
range?.length
|
|
7633
8106
|
),
|
|
7634
|
-
new FileNotFoundInFilesystemError(this.name,
|
|
8107
|
+
new FileNotFoundInFilesystemError(this.name, path4)
|
|
7635
8108
|
);
|
|
7636
8109
|
const fullSize = traced.fullSize;
|
|
7637
8110
|
if (!traced.contentId || fullSize === void 0 || !Number.isSafeInteger(fullSize) || fullSize < 0 || traced.data.byteLength > fullSize) {
|
|
@@ -7646,9 +8119,9 @@ var Filesystem = class {
|
|
|
7646
8119
|
};
|
|
7647
8120
|
}
|
|
7648
8121
|
/** Read a file as UTF-8 text at `version`. Throws on non-UTF-8 content. */
|
|
7649
|
-
async readText(
|
|
8122
|
+
async readText(path4, version) {
|
|
7650
8123
|
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
|
7651
|
-
await this.readFile(
|
|
8124
|
+
await this.readFile(path4, version)
|
|
7652
8125
|
);
|
|
7653
8126
|
}
|
|
7654
8127
|
/** List one directory (non-recursive) at `version`. */
|
|
@@ -7711,11 +8184,11 @@ var FilesystemMount = class {
|
|
|
7711
8184
|
path;
|
|
7712
8185
|
readonly;
|
|
7713
8186
|
/** @internal — obtain instances via `FilesystemClient.mount()`. */
|
|
7714
|
-
constructor(client, cli, filesystem,
|
|
8187
|
+
constructor(client, cli, filesystem, path4, readonly) {
|
|
7715
8188
|
this.client = client;
|
|
7716
8189
|
this.cli = cli;
|
|
7717
8190
|
this.filesystem = filesystem;
|
|
7718
|
-
this.path =
|
|
8191
|
+
this.path = path4;
|
|
7719
8192
|
this.readonly = readonly;
|
|
7720
8193
|
}
|
|
7721
8194
|
/** Flush pending local changes into a durable snapshot. */
|
|
@@ -7733,6 +8206,7 @@ var FilesystemMount = class {
|
|
|
7733
8206
|
};
|
|
7734
8207
|
|
|
7735
8208
|
// src/api-client.ts
|
|
8209
|
+
init_sandbox_image();
|
|
7736
8210
|
init_errors();
|
|
7737
8211
|
var APIClient = class {
|
|
7738
8212
|
cloudClient;
|
|
@@ -7760,7 +8234,7 @@ var APIClient = class {
|
|
|
7760
8234
|
await this.cloudClient.deleteApplication(applicationName);
|
|
7761
8235
|
}
|
|
7762
8236
|
async deleteSandboxImage(imageName) {
|
|
7763
|
-
await this.
|
|
8237
|
+
await deleteSandboxImageWithCredentials(this.filesystemOptions, imageName);
|
|
7764
8238
|
}
|
|
7765
8239
|
async createFileSystem(name, description, options) {
|
|
7766
8240
|
const filesystem = await new FilesystemClient(this.filesystemOptions).create(
|
|
@@ -7830,7 +8304,7 @@ init_sandbox_image();
|
|
|
7830
8304
|
|
|
7831
8305
|
// src/repository-mount.ts
|
|
7832
8306
|
init_cjs_shims();
|
|
7833
|
-
var
|
|
8307
|
+
var import_node_path5 = require("path");
|
|
7834
8308
|
function requireNonEmpty(value, name) {
|
|
7835
8309
|
if (typeof value !== "string" || value.length === 0) {
|
|
7836
8310
|
throw new TypeError(`${name} must be a non-empty string`);
|
|
@@ -7847,28 +8321,28 @@ var GitCli = class extends MountCli {
|
|
|
7847
8321
|
if (options.readOnly && (options.publish || options.workspace !== void 0) || options.publish && options.workspace !== void 0) {
|
|
7848
8322
|
throw new TypeError("readOnly, publish, and workspace are mutually exclusive");
|
|
7849
8323
|
}
|
|
7850
|
-
const
|
|
8324
|
+
const path4 = (0, import_node_path5.resolve)(localPath);
|
|
7851
8325
|
const args = ["mount"];
|
|
7852
8326
|
if (options.readOnly) args.push("--ro");
|
|
7853
8327
|
if (options.publish) args.push("--publish");
|
|
7854
8328
|
if (options.workspace !== void 0) args.push(`--workspace=${options.workspace}`);
|
|
7855
|
-
args.push("--", target,
|
|
8329
|
+
args.push("--", target, path4);
|
|
7856
8330
|
await this.run(args);
|
|
7857
|
-
return new RepositoryMount(this, target,
|
|
8331
|
+
return new RepositoryMount(this, target, path4, options.readOnly ?? false);
|
|
7858
8332
|
}
|
|
7859
8333
|
async unmount(localPath, options = {}) {
|
|
7860
8334
|
requireNonEmpty(localPath, "localPath");
|
|
7861
8335
|
const args = ["unmount"];
|
|
7862
8336
|
if (options.deleteWorkspace) args.push("--delete");
|
|
7863
8337
|
if (options.discard) args.push("--discard");
|
|
7864
|
-
args.push("--", (0,
|
|
8338
|
+
args.push("--", (0, import_node_path5.resolve)(localPath));
|
|
7865
8339
|
await this.run(args);
|
|
7866
8340
|
}
|
|
7867
8341
|
async status(localPath) {
|
|
7868
8342
|
const args = ["status", "--json"];
|
|
7869
8343
|
if (localPath !== void 0) {
|
|
7870
8344
|
requireNonEmpty(localPath, "localPath");
|
|
7871
|
-
args.push("--", (0,
|
|
8345
|
+
args.push("--", (0, import_node_path5.resolve)(localPath));
|
|
7872
8346
|
}
|
|
7873
8347
|
const output = await this.run(args, 6e4);
|
|
7874
8348
|
let raw;
|
|
@@ -7883,7 +8357,7 @@ var GitCli = class extends MountCli {
|
|
|
7883
8357
|
}
|
|
7884
8358
|
const stringField = (key) => typeof raw[key] === "string" ? raw[key] : null;
|
|
7885
8359
|
return {
|
|
7886
|
-
path: stringField("mountpoint") ?? (localPath === void 0 ? "" : (0,
|
|
8360
|
+
path: stringField("mountpoint") ?? (localPath === void 0 ? "" : (0, import_node_path5.resolve)(localPath)),
|
|
7887
8361
|
repository: stringField("repository"),
|
|
7888
8362
|
reference: stringField("reference"),
|
|
7889
8363
|
workspaceId: stringField("workspace"),
|
|
@@ -7892,44 +8366,44 @@ var GitCli = class extends MountCli {
|
|
|
7892
8366
|
raw
|
|
7893
8367
|
};
|
|
7894
8368
|
}
|
|
7895
|
-
async snapshot(
|
|
8369
|
+
async snapshot(path4, message) {
|
|
7896
8370
|
const args = ["snapshot"];
|
|
7897
8371
|
if (message !== void 0) args.push(`--message=${message}`);
|
|
7898
|
-
args.push("--",
|
|
8372
|
+
args.push("--", path4);
|
|
7899
8373
|
await this.run(args);
|
|
7900
8374
|
}
|
|
7901
|
-
async sync(
|
|
7902
|
-
const args = ["sync", "--",
|
|
8375
|
+
async sync(path4, target) {
|
|
8376
|
+
const args = ["sync", "--", path4];
|
|
7903
8377
|
if (target !== void 0) {
|
|
7904
8378
|
requireNonEmpty(target, "target");
|
|
7905
8379
|
args.push(target);
|
|
7906
8380
|
}
|
|
7907
8381
|
await this.run(args);
|
|
7908
8382
|
}
|
|
7909
|
-
async rebase(
|
|
8383
|
+
async rebase(path4, target, failOnConflict) {
|
|
7910
8384
|
requireNonEmpty(target, "target");
|
|
7911
8385
|
const args = ["rebase"];
|
|
7912
8386
|
if (failOnConflict) args.push("--fail-on-conflict");
|
|
7913
|
-
args.push("--",
|
|
8387
|
+
args.push("--", path4, target);
|
|
7914
8388
|
await this.run(args);
|
|
7915
8389
|
}
|
|
7916
|
-
async promote(
|
|
8390
|
+
async promote(path4, branch, merge) {
|
|
7917
8391
|
requireNonEmpty(branch, "branch");
|
|
7918
8392
|
const args = ["promote"];
|
|
7919
8393
|
if (merge) args.push("--merge");
|
|
7920
|
-
args.push("--",
|
|
8394
|
+
args.push("--", path4, branch);
|
|
7921
8395
|
await this.run(args);
|
|
7922
8396
|
}
|
|
7923
|
-
async prefetch(
|
|
7924
|
-
await this.run(["prefetch", "--",
|
|
8397
|
+
async prefetch(path4) {
|
|
8398
|
+
await this.run(["prefetch", "--", path4]);
|
|
7925
8399
|
}
|
|
7926
8400
|
};
|
|
7927
8401
|
var RepositoryMount = class {
|
|
7928
8402
|
/** @internal Obtain instances via RepositoryClient.mount(). */
|
|
7929
|
-
constructor(cli, target,
|
|
8403
|
+
constructor(cli, target, path4, readOnly) {
|
|
7930
8404
|
this.cli = cli;
|
|
7931
8405
|
this.target = target;
|
|
7932
|
-
this.path =
|
|
8406
|
+
this.path = path4;
|
|
7933
8407
|
this.readOnly = readOnly;
|
|
7934
8408
|
}
|
|
7935
8409
|
/** Inspect workspace state, pending changes, and daemon diagnostics. */
|
|
@@ -8164,6 +8638,7 @@ function validateTimeoutMs2(timeoutMs) {
|
|
|
8164
8638
|
|
|
8165
8639
|
// src/index.ts
|
|
8166
8640
|
init_sandbox_image();
|
|
8641
|
+
init_image_builds();
|
|
8167
8642
|
|
|
8168
8643
|
// src/file-system.ts
|
|
8169
8644
|
init_cjs_shims();
|
|
@@ -9547,38 +10022,38 @@ init_cjs_shims();
|
|
|
9547
10022
|
var import_node_crypto4 = require("crypto");
|
|
9548
10023
|
var textEncoder = new TextEncoder();
|
|
9549
10024
|
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
9550
|
-
function assertJSONValue(value,
|
|
10025
|
+
function assertJSONValue(value, path4, seen) {
|
|
9551
10026
|
if (value === null || typeof value === "string" || typeof value === "boolean") return;
|
|
9552
10027
|
if (typeof value === "number") {
|
|
9553
|
-
if (!Number.isFinite(value)) throw new SerializationError(`${
|
|
10028
|
+
if (!Number.isFinite(value)) throw new SerializationError(`${path4} contains a non-finite number`);
|
|
9554
10029
|
return;
|
|
9555
10030
|
}
|
|
9556
10031
|
if (typeof value !== "object") {
|
|
9557
|
-
throw new SerializationError(`${
|
|
10032
|
+
throw new SerializationError(`${path4} contains unsupported ${typeof value}`);
|
|
9558
10033
|
}
|
|
9559
10034
|
if (isFile(value)) {
|
|
9560
|
-
throw new SerializationError(`${
|
|
10035
|
+
throw new SerializationError(`${path4} contains a nested File; File is only supported as a direct value`);
|
|
9561
10036
|
}
|
|
9562
10037
|
if (isHttpBody(value)) {
|
|
9563
10038
|
throw new SerializationError(
|
|
9564
|
-
`${
|
|
10039
|
+
`${path4} contains a nested HttpBody; HttpBody is only supported as a direct value`
|
|
9565
10040
|
);
|
|
9566
10041
|
}
|
|
9567
|
-
if (seen.has(value)) throw new SerializationError(`${
|
|
10042
|
+
if (seen.has(value)) throw new SerializationError(`${path4} contains a cycle`);
|
|
9568
10043
|
if (Object.getPrototypeOf(value) !== Object.prototype && !Array.isArray(value)) {
|
|
9569
|
-
throw new SerializationError(`${
|
|
10044
|
+
throw new SerializationError(`${path4} contains unsupported ${value.constructor?.name ?? "object"}`);
|
|
9570
10045
|
}
|
|
9571
10046
|
seen.add(value);
|
|
9572
10047
|
if (Array.isArray(value)) {
|
|
9573
10048
|
for (let index = 0; index < value.length; index += 1) {
|
|
9574
10049
|
if (!Object.prototype.hasOwnProperty.call(value, index)) {
|
|
9575
|
-
throw new SerializationError(`${
|
|
10050
|
+
throw new SerializationError(`${path4} contains a sparse array entry at index ${index}`);
|
|
9576
10051
|
}
|
|
9577
|
-
assertJSONValue(value[index], `${
|
|
10052
|
+
assertJSONValue(value[index], `${path4}[${index}]`, seen);
|
|
9578
10053
|
}
|
|
9579
10054
|
} else {
|
|
9580
10055
|
for (const [key, item] of Object.entries(value)) {
|
|
9581
|
-
assertJSONValue(item, `${
|
|
10056
|
+
assertJSONValue(item, `${path4}.${key}`, seen);
|
|
9582
10057
|
}
|
|
9583
10058
|
}
|
|
9584
10059
|
seen.delete(value);
|
|
@@ -10028,7 +10503,15 @@ init_models();
|
|
|
10028
10503
|
Headers,
|
|
10029
10504
|
HttpBody,
|
|
10030
10505
|
Image,
|
|
10506
|
+
ImageBuildCancelledError,
|
|
10507
|
+
ImageBuildError,
|
|
10508
|
+
ImageBuildFailedError,
|
|
10509
|
+
ImageBuildHandle,
|
|
10510
|
+
ImageBuildInProgressError,
|
|
10511
|
+
ImageBuildInterruptedError,
|
|
10512
|
+
ImageBuildNotFoundError,
|
|
10031
10513
|
ImageBuildOperationType,
|
|
10514
|
+
ImageBuildTimeoutError,
|
|
10032
10515
|
MountError,
|
|
10033
10516
|
OutputMode,
|
|
10034
10517
|
PendingSandbox,
|
|
@@ -10061,12 +10544,14 @@ init_models();
|
|
|
10061
10544
|
TERMINATION_REASON_CANCELLED,
|
|
10062
10545
|
TERMINATION_REASON_NO_CAPACITY,
|
|
10063
10546
|
TcpTunnel,
|
|
10547
|
+
cancelImageBuild,
|
|
10064
10548
|
createFileSystem,
|
|
10065
10549
|
createSandboxImage,
|
|
10066
10550
|
deleteFileSystem,
|
|
10067
10551
|
deleteSandboxImage,
|
|
10068
10552
|
dockerfileContent,
|
|
10069
10553
|
findSandboxImageByName,
|
|
10554
|
+
getImageBuild,
|
|
10070
10555
|
importSandboxImage,
|
|
10071
10556
|
isSandboxPending,
|
|
10072
10557
|
listFileSystems,
|
|
@@ -10078,6 +10563,9 @@ init_models();
|
|
|
10078
10563
|
runLocal,
|
|
10079
10564
|
runRemote,
|
|
10080
10565
|
sandboxUrlFromIngressEndpoint,
|
|
10081
|
-
schema
|
|
10566
|
+
schema,
|
|
10567
|
+
startImageBuild,
|
|
10568
|
+
startImageImport,
|
|
10569
|
+
waitImageBuild
|
|
10082
10570
|
});
|
|
10083
10571
|
//# sourceMappingURL=index.cjs.map
|