@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.js
CHANGED
|
@@ -46,7 +46,7 @@ var init_defaults = __esm({
|
|
|
46
46
|
"src/defaults.ts"() {
|
|
47
47
|
"use strict";
|
|
48
48
|
init_esm_shims();
|
|
49
|
-
SDK_VERSION = "0.5.
|
|
49
|
+
SDK_VERSION = "0.5.153";
|
|
50
50
|
API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
|
|
51
51
|
API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
|
|
52
52
|
NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
|
|
@@ -495,7 +495,7 @@ var init_native_worker_client = __esm({
|
|
|
495
495
|
}
|
|
496
496
|
};
|
|
497
497
|
runtimeKey = /* @__PURE__ */ Symbol.for(
|
|
498
|
-
`tensorlake.native.worker.${false ? "source" : "0.5.
|
|
498
|
+
`tensorlake.native.worker.${false ? "source" : "0.5.153"}.v1`
|
|
499
499
|
);
|
|
500
500
|
runtimes = globalThis;
|
|
501
501
|
}
|
|
@@ -595,6 +595,8 @@ var init_models = __esm({
|
|
|
595
595
|
SnapshotStatus2["LOCAL_READY"] = "local_ready";
|
|
596
596
|
SnapshotStatus2["COMPLETED"] = "completed";
|
|
597
597
|
SnapshotStatus2["FAILED"] = "failed";
|
|
598
|
+
SnapshotStatus2["DELETING"] = "deleting";
|
|
599
|
+
SnapshotStatus2["REPLICATING"] = "replicating";
|
|
598
600
|
return SnapshotStatus2;
|
|
599
601
|
})(SnapshotStatus || {});
|
|
600
602
|
ProcessStatus = /* @__PURE__ */ ((ProcessStatus2) => {
|
|
@@ -3883,9 +3885,8 @@ var init_sandbox = __esm({
|
|
|
3883
3885
|
*
|
|
3884
3886
|
* Resource targets use create's cpus, memoryMb, and diskMb names. Resize
|
|
3885
3887
|
* waits by default; wait=false returns admission. Timeout does not cancel it.
|
|
3886
|
-
*
|
|
3887
|
-
*
|
|
3888
|
-
* Non-CAS sandboxes do not support live resize.
|
|
3888
|
+
* Which runtimes and dimensions support a live resize is decided by the
|
|
3889
|
+
* server, whose policy error is thrown unchanged.
|
|
3889
3890
|
* Wait, timeout, and pollInterval are ignored on non-resource updates.
|
|
3890
3891
|
* A no-op returns current resources with absent or earlier resize metadata.
|
|
3891
3892
|
*
|
|
@@ -4303,29 +4304,29 @@ var init_sandbox = __esm({
|
|
|
4303
4304
|
}
|
|
4304
4305
|
// --- File operations ---
|
|
4305
4306
|
/** Read a file from the sandbox and return its raw bytes. */
|
|
4306
|
-
async readFile(
|
|
4307
|
+
async readFile(path5) {
|
|
4307
4308
|
const proxy = await this.proxy.client();
|
|
4308
|
-
const { traceId, data } = await callNative(() => proxy.readFile(
|
|
4309
|
+
const { traceId, data } = await callNative(() => proxy.readFile(path5), {
|
|
4309
4310
|
sandboxId: this.sandboxId
|
|
4310
4311
|
});
|
|
4311
4312
|
return Object.assign(Uint8Array.from(data), { traceId });
|
|
4312
4313
|
}
|
|
4313
4314
|
/** Write raw bytes to a file in the sandbox, creating it if it does not exist. */
|
|
4314
|
-
async writeFile(
|
|
4315
|
+
async writeFile(path5, content) {
|
|
4315
4316
|
const proxy = await this.proxy.client();
|
|
4316
|
-
await callNative(() => proxy.writeFile(
|
|
4317
|
+
await callNative(() => proxy.writeFile(path5, Buffer.from(content)), {
|
|
4317
4318
|
sandboxId: this.sandboxId
|
|
4318
4319
|
});
|
|
4319
4320
|
}
|
|
4320
4321
|
/** Delete a file from the sandbox. */
|
|
4321
|
-
async deleteFile(
|
|
4322
|
+
async deleteFile(path5) {
|
|
4322
4323
|
const proxy = await this.proxy.client();
|
|
4323
|
-
await callNative(() => proxy.deleteFile(
|
|
4324
|
+
await callNative(() => proxy.deleteFile(path5), { sandboxId: this.sandboxId });
|
|
4324
4325
|
}
|
|
4325
4326
|
/** List the contents of a directory in the sandbox. */
|
|
4326
|
-
async listDirectory(
|
|
4327
|
+
async listDirectory(path5) {
|
|
4327
4328
|
const proxy = await this.proxy.client();
|
|
4328
|
-
const { traceId, json } = await callNative(() => proxy.listDirectory(
|
|
4329
|
+
const { traceId, json } = await callNative(() => proxy.listDirectory(path5), {
|
|
4329
4330
|
sandboxId: this.sandboxId
|
|
4330
4331
|
});
|
|
4331
4332
|
return Object.assign(fromSnakeKeys(JSON.parse(json)), {
|
|
@@ -4991,9 +4992,9 @@ var init_client = __esm({
|
|
|
4991
4992
|
});
|
|
4992
4993
|
}
|
|
4993
4994
|
/**
|
|
4994
|
-
* Update properties or resize a running sandbox.
|
|
4995
|
-
*
|
|
4996
|
-
*
|
|
4995
|
+
* Update properties or resize a running sandbox. Which runtimes and
|
|
4996
|
+
* dimensions support a live resize is decided by the server, whose policy
|
|
4997
|
+
* error is thrown unchanged.
|
|
4997
4998
|
* Resource names match create. Resize waits by default; wait=false returns
|
|
4998
4999
|
* admission. Timeout leaves the resize running and reports its generation.
|
|
4999
5000
|
* Wait, timeout, and pollInterval are ignored on non-resource updates.
|
|
@@ -5312,6 +5313,11 @@ var init_client = __esm({
|
|
|
5312
5313
|
`Snapshot ${result.snapshotId} failed: ${info.error}`
|
|
5313
5314
|
);
|
|
5314
5315
|
}
|
|
5316
|
+
if (info.status === "deleting" /* DELETING */) {
|
|
5317
|
+
throw new SandboxError(
|
|
5318
|
+
`Snapshot ${result.snapshotId} is being deleted`
|
|
5319
|
+
);
|
|
5320
|
+
}
|
|
5315
5321
|
await sleep2(pollInterval * 1e3);
|
|
5316
5322
|
}
|
|
5317
5323
|
throw new SandboxError(
|
|
@@ -5569,585 +5575,6 @@ var init_client = __esm({
|
|
|
5569
5575
|
}
|
|
5570
5576
|
});
|
|
5571
5577
|
|
|
5572
|
-
// src/native-cloud.ts
|
|
5573
|
-
async function serializeRequest(method, path4, options) {
|
|
5574
|
-
const headers = { ...options?.headers };
|
|
5575
|
-
let body = options?.body;
|
|
5576
|
-
if (options?.json !== void 0) {
|
|
5577
|
-
body = JSON.stringify(options.json);
|
|
5578
|
-
if (!Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) {
|
|
5579
|
-
headers["Content-Type"] = "application/json";
|
|
5580
|
-
}
|
|
5581
|
-
}
|
|
5582
|
-
const request = {
|
|
5583
|
-
method,
|
|
5584
|
-
path: path4,
|
|
5585
|
-
headersJson: JSON.stringify(headers),
|
|
5586
|
-
statusOnlyCodes: [...options?.statusOnlyCodes ?? []]
|
|
5587
|
-
};
|
|
5588
|
-
if (body instanceof FormData) {
|
|
5589
|
-
request.parts = [];
|
|
5590
|
-
for (const [name, value] of body.entries()) {
|
|
5591
|
-
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" });
|
|
5592
|
-
}
|
|
5593
|
-
} else if (body !== void 0) {
|
|
5594
|
-
if (body instanceof Blob) request.body = Buffer.from(await body.arrayBuffer());
|
|
5595
|
-
else if (typeof body === "string") request.body = Buffer.from(body);
|
|
5596
|
-
else if (body instanceof ArrayBuffer) request.body = Buffer.from(new Uint8Array(body));
|
|
5597
|
-
else request.body = Buffer.from(body);
|
|
5598
|
-
}
|
|
5599
|
-
return request;
|
|
5600
|
-
}
|
|
5601
|
-
var NativeCloudTransport;
|
|
5602
|
-
var init_native_cloud = __esm({
|
|
5603
|
-
"src/native-cloud.ts"() {
|
|
5604
|
-
"use strict";
|
|
5605
|
-
init_esm_shims();
|
|
5606
|
-
init_native_sandbox();
|
|
5607
|
-
init_native_worker_client();
|
|
5608
|
-
NativeCloudTransport = class {
|
|
5609
|
-
constructor(options) {
|
|
5610
|
-
this.options = options;
|
|
5611
|
-
if (!Number.isSafeInteger(options.maxRetries) || options.maxRetries < 0 || options.maxRetries > 4294967295) {
|
|
5612
|
-
throw new RangeError("maxRetries must be a non-negative 32-bit integer");
|
|
5613
|
-
}
|
|
5614
|
-
if (!Number.isFinite(options.retryBackoffMs) || options.retryBackoffMs < 0) {
|
|
5615
|
-
throw new RangeError("retryBackoffMs must be a non-negative finite number");
|
|
5616
|
-
}
|
|
5617
|
-
}
|
|
5618
|
-
native;
|
|
5619
|
-
closed = false;
|
|
5620
|
-
client() {
|
|
5621
|
-
if (this.closed) throw new Error("Tensorlake native client is closed");
|
|
5622
|
-
if (this.native) return this.native;
|
|
5623
|
-
const ctor = loadNativeSandboxBinding().NativeCloudClient;
|
|
5624
|
-
if (!ctor) throw new Error("Native binding does not export NativeCloudClient; rebuild with 'npm run build:native'");
|
|
5625
|
-
return this.native = new ctor(JSON.stringify(this.options));
|
|
5626
|
-
}
|
|
5627
|
-
close() {
|
|
5628
|
-
this.closed = true;
|
|
5629
|
-
releaseNativeHandle(this.native ?? null);
|
|
5630
|
-
this.native = void 0;
|
|
5631
|
-
}
|
|
5632
|
-
async requestResponse(method, path4, options) {
|
|
5633
|
-
const request = await serializeRequest(method, path4, options);
|
|
5634
|
-
const raw = await callNative(() => this.client().request(request));
|
|
5635
|
-
const response = new Response(
|
|
5636
|
-
[204, 205, 304].includes(raw.status) ? null : Uint8Array.from(raw.data).buffer,
|
|
5637
|
-
{ status: raw.status, headers: JSON.parse(raw.headersJson) }
|
|
5638
|
-
);
|
|
5639
|
-
return Object.assign(response, { traceId: raw.traceId });
|
|
5640
|
-
}
|
|
5641
|
-
async requestJson(method, path4) {
|
|
5642
|
-
const response = await this.requestResponse(method, path4);
|
|
5643
|
-
const text = await response.text();
|
|
5644
|
-
const value = text ? JSON.parse(text) : null;
|
|
5645
|
-
return Object.assign(value ?? {}, { traceId: response.traceId });
|
|
5646
|
-
}
|
|
5647
|
-
async *stream(method, path4, signal) {
|
|
5648
|
-
if (signal?.aborted) return;
|
|
5649
|
-
const request = await serializeRequest(method, path4, { headers: { Accept: "text/event-stream" } });
|
|
5650
|
-
yield* nativeEventStream((emit) => this.client().stream(request, emit), void 0, signal);
|
|
5651
|
-
}
|
|
5652
|
-
};
|
|
5653
|
-
}
|
|
5654
|
-
});
|
|
5655
|
-
|
|
5656
|
-
// src/cloud-client.ts
|
|
5657
|
-
import { nanoid } from "nanoid";
|
|
5658
|
-
function secretFromMetadata(metadata) {
|
|
5659
|
-
return {
|
|
5660
|
-
id: metadata.id,
|
|
5661
|
-
name: metadata.name,
|
|
5662
|
-
createdAt: new Date(metadata.created_at_ms)
|
|
5663
|
-
};
|
|
5664
|
-
}
|
|
5665
|
-
function applicationAllowsUnauthenticatedRequests(manifest) {
|
|
5666
|
-
return Array.isArray(manifest.allow) && manifest.allow.includes(UNAUTHENTICATED_REQUESTS);
|
|
5667
|
-
}
|
|
5668
|
-
function publicEndpointIdFromManifest(manifest) {
|
|
5669
|
-
for (const key of ["public_endpoint_id", "publicEndpointId"]) {
|
|
5670
|
-
const value = manifest[key];
|
|
5671
|
-
if (typeof value === "string" && value.length > 0) {
|
|
5672
|
-
return value;
|
|
5673
|
-
}
|
|
5674
|
-
}
|
|
5675
|
-
return void 0;
|
|
5676
|
-
}
|
|
5677
|
-
function generatePublicEndpointId() {
|
|
5678
|
-
return `endpoint_${nanoid()}`;
|
|
5679
|
-
}
|
|
5680
|
-
function createApplicationBuildForm(request, imageContexts) {
|
|
5681
|
-
const contextsByPartName = /* @__PURE__ */ new Map();
|
|
5682
|
-
for (const context of imageContexts) {
|
|
5683
|
-
if (contextsByPartName.has(context.contextTarPartName)) {
|
|
5684
|
-
throw new Error(
|
|
5685
|
-
`duplicate image context part name '${context.contextTarPartName}'`
|
|
5686
|
-
);
|
|
5687
|
-
}
|
|
5688
|
-
contextsByPartName.set(context.contextTarPartName, context);
|
|
5689
|
-
}
|
|
5690
|
-
const form = new FormData();
|
|
5691
|
-
form.append(
|
|
5692
|
-
"app_version",
|
|
5693
|
-
new Blob([JSON.stringify(request)], { type: "application/json" }),
|
|
5694
|
-
"app_version"
|
|
5695
|
-
);
|
|
5696
|
-
for (const image of request.images) {
|
|
5697
|
-
const context = contextsByPartName.get(image.contextTarPartName);
|
|
5698
|
-
if (!context) {
|
|
5699
|
-
throw new Error(
|
|
5700
|
-
`missing image context for part '${image.contextTarPartName}'`
|
|
5701
|
-
);
|
|
5702
|
-
}
|
|
5703
|
-
form.append(
|
|
5704
|
-
image.contextTarPartName,
|
|
5705
|
-
new Blob([toBlobPart(context.contextTarGz)]),
|
|
5706
|
-
`${image.contextTarPartName}.tar.gz`
|
|
5707
|
-
);
|
|
5708
|
-
}
|
|
5709
|
-
for (const context of imageContexts) {
|
|
5710
|
-
if (!request.images.some((image) => image.contextTarPartName === context.contextTarPartName)) {
|
|
5711
|
-
throw new Error(
|
|
5712
|
-
`unexpected image context for part '${context.contextTarPartName}'`
|
|
5713
|
-
);
|
|
5714
|
-
}
|
|
5715
|
-
}
|
|
5716
|
-
return form;
|
|
5717
|
-
}
|
|
5718
|
-
function trimTrailingSlashes2(value) {
|
|
5719
|
-
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
5720
|
-
}
|
|
5721
|
-
function nextRequestPath(next) {
|
|
5722
|
-
const schemeIndex = next.indexOf("://");
|
|
5723
|
-
if (schemeIndex !== -1) {
|
|
5724
|
-
const afterScheme = next.slice(schemeIndex + 3);
|
|
5725
|
-
const slashIndex = afterScheme.indexOf("/");
|
|
5726
|
-
return slashIndex === -1 ? "/" : afterScheme.slice(slashIndex);
|
|
5727
|
-
}
|
|
5728
|
-
return next.startsWith("/") ? next : `/${next}`;
|
|
5729
|
-
}
|
|
5730
|
-
function toBlobPart(data) {
|
|
5731
|
-
if (typeof data === "string" || data instanceof Blob) {
|
|
5732
|
-
return data;
|
|
5733
|
-
}
|
|
5734
|
-
if (data instanceof Uint8Array) {
|
|
5735
|
-
return Uint8Array.from(data).buffer;
|
|
5736
|
-
}
|
|
5737
|
-
return data;
|
|
5738
|
-
}
|
|
5739
|
-
function toRequestBody(data) {
|
|
5740
|
-
return toBlobPart(data);
|
|
5741
|
-
}
|
|
5742
|
-
async function parseJsonResponse(response) {
|
|
5743
|
-
const text = await response.text();
|
|
5744
|
-
if (!text) {
|
|
5745
|
-
return void 0;
|
|
5746
|
-
}
|
|
5747
|
-
return JSON.parse(text);
|
|
5748
|
-
}
|
|
5749
|
-
var CloudClient, UNAUTHENTICATED_REQUESTS;
|
|
5750
|
-
var init_cloud_client = __esm({
|
|
5751
|
-
"src/cloud-client.ts"() {
|
|
5752
|
-
"use strict";
|
|
5753
|
-
init_esm_shims();
|
|
5754
|
-
init_defaults();
|
|
5755
|
-
init_native_cloud();
|
|
5756
|
-
init_models();
|
|
5757
|
-
CloudClient = class _CloudClient {
|
|
5758
|
-
transport;
|
|
5759
|
-
organizationId;
|
|
5760
|
-
projectId;
|
|
5761
|
-
namespace;
|
|
5762
|
-
constructor(options) {
|
|
5763
|
-
this.organizationId = options?.organizationId;
|
|
5764
|
-
this.projectId = options?.projectId;
|
|
5765
|
-
this.namespace = options?.namespace ?? NAMESPACE;
|
|
5766
|
-
this.transport = new NativeCloudTransport({
|
|
5767
|
-
baseUrl: options?.apiUrl ?? API_URL,
|
|
5768
|
-
apiKey: options?.apiKey ?? API_KEY,
|
|
5769
|
-
organizationId: this.organizationId,
|
|
5770
|
-
projectId: this.projectId,
|
|
5771
|
-
maxRetries: options?.maxRetries ?? MAX_RETRIES,
|
|
5772
|
-
retryBackoffMs: options?.retryBackoffMs ?? RETRY_BACKOFF_MS,
|
|
5773
|
-
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
5774
|
-
userAgent: `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
5775
|
-
});
|
|
5776
|
-
}
|
|
5777
|
-
static forCloud(options) {
|
|
5778
|
-
return new _CloudClient(options);
|
|
5779
|
-
}
|
|
5780
|
-
close() {
|
|
5781
|
-
this.transport.close();
|
|
5782
|
-
}
|
|
5783
|
-
async upsertApplication(manifest, codeZip, upgradeRunningRequests = false) {
|
|
5784
|
-
const applicationManifest = { ...manifest };
|
|
5785
|
-
let publicEndpointId = publicEndpointIdFromManifest(applicationManifest);
|
|
5786
|
-
if (applicationAllowsUnauthenticatedRequests(applicationManifest) && publicEndpointId === void 0) {
|
|
5787
|
-
const applicationName = applicationManifest.name;
|
|
5788
|
-
if (typeof applicationName === "string" && applicationName.length > 0) {
|
|
5789
|
-
publicEndpointId = await this.existingApplicationPublicEndpointId(applicationName);
|
|
5790
|
-
}
|
|
5791
|
-
publicEndpointId ??= generatePublicEndpointId();
|
|
5792
|
-
}
|
|
5793
|
-
if (publicEndpointId !== void 0) {
|
|
5794
|
-
applicationManifest.public_endpoint_id = publicEndpointId;
|
|
5795
|
-
delete applicationManifest.publicEndpointId;
|
|
5796
|
-
}
|
|
5797
|
-
const form = new FormData();
|
|
5798
|
-
form.append(
|
|
5799
|
-
"code",
|
|
5800
|
-
new Blob([toBlobPart(codeZip)], { type: "application/zip" }),
|
|
5801
|
-
"code.zip"
|
|
5802
|
-
);
|
|
5803
|
-
form.append("code_content_type", "application/zip");
|
|
5804
|
-
form.append("application", JSON.stringify(applicationManifest));
|
|
5805
|
-
form.append(
|
|
5806
|
-
"upgrade_requests_to_latest_code",
|
|
5807
|
-
String(upgradeRunningRequests)
|
|
5808
|
-
);
|
|
5809
|
-
await this.transport.requestResponse("POST", this.namespacePath("applications"), {
|
|
5810
|
-
body: form
|
|
5811
|
-
});
|
|
5812
|
-
}
|
|
5813
|
-
async deleteApplication(applicationName) {
|
|
5814
|
-
await this.transport.requestResponse(
|
|
5815
|
-
"DELETE",
|
|
5816
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
5817
|
-
);
|
|
5818
|
-
}
|
|
5819
|
-
async deleteSandboxImage(imageName) {
|
|
5820
|
-
await this.transport.requestResponse(
|
|
5821
|
-
"DELETE",
|
|
5822
|
-
this.namespacePath(`sandbox-images/${encodeURIComponent(imageName)}`)
|
|
5823
|
-
);
|
|
5824
|
-
}
|
|
5825
|
-
/**
|
|
5826
|
-
* Look up a registered sandbox image (template) by its registered name.
|
|
5827
|
-
*
|
|
5828
|
-
* Returns the template, or `null` when no image with that name exists.
|
|
5829
|
-
* API-key clients may omit organization/project IDs and use the
|
|
5830
|
-
* token-scoped Platform API route directly. Explicit scope remains
|
|
5831
|
-
* available for PAT callers.
|
|
5832
|
-
*/
|
|
5833
|
-
async findSandboxImageByName(imageName, options) {
|
|
5834
|
-
const base = this.platformProjectPath(
|
|
5835
|
-
"sandbox-templates",
|
|
5836
|
-
options?.organizationId,
|
|
5837
|
-
options?.projectId
|
|
5838
|
-
);
|
|
5839
|
-
const response = await this.transport.requestResponse(
|
|
5840
|
-
"GET",
|
|
5841
|
-
`${base}/by-name/${encodeURIComponent(imageName)}`,
|
|
5842
|
-
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
5843
|
-
);
|
|
5844
|
-
if (response.status === 404) {
|
|
5845
|
-
return null;
|
|
5846
|
-
}
|
|
5847
|
-
const raw = await parseJsonResponse(response);
|
|
5848
|
-
return fromSnakeKeys(raw);
|
|
5849
|
-
}
|
|
5850
|
-
/**
|
|
5851
|
-
* List all registered sandbox images (templates), following pagination to
|
|
5852
|
-
* the end. API-key clients may omit organization/project IDs and use the
|
|
5853
|
-
* token-scoped Platform API route directly.
|
|
5854
|
-
*/
|
|
5855
|
-
async listSandboxImages(options) {
|
|
5856
|
-
const base = this.platformProjectPath(
|
|
5857
|
-
"sandbox-templates",
|
|
5858
|
-
options?.organizationId,
|
|
5859
|
-
options?.projectId
|
|
5860
|
-
);
|
|
5861
|
-
let path4 = `${base}?pageSize=100`;
|
|
5862
|
-
const templates = [];
|
|
5863
|
-
while (path4 !== null) {
|
|
5864
|
-
const page = await this.transport.requestJson(
|
|
5865
|
-
"GET",
|
|
5866
|
-
path4
|
|
5867
|
-
);
|
|
5868
|
-
for (const item of page.items ?? []) {
|
|
5869
|
-
templates.push(fromSnakeKeys(item));
|
|
5870
|
-
}
|
|
5871
|
-
const next = page.pagination?.next;
|
|
5872
|
-
path4 = next ? nextRequestPath(next) : null;
|
|
5873
|
-
}
|
|
5874
|
-
return templates;
|
|
5875
|
-
}
|
|
5876
|
-
async applications() {
|
|
5877
|
-
const raw = await this.transport.requestJson(
|
|
5878
|
-
"GET",
|
|
5879
|
-
this.namespacePath("applications")
|
|
5880
|
-
);
|
|
5881
|
-
return (raw.applications ?? []).map(
|
|
5882
|
-
(application) => fromSnakeKeys(application)
|
|
5883
|
-
);
|
|
5884
|
-
}
|
|
5885
|
-
async applicationManifest(applicationName) {
|
|
5886
|
-
const raw = await this.transport.requestJson(
|
|
5887
|
-
"GET",
|
|
5888
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
5889
|
-
);
|
|
5890
|
-
return fromSnakeKeys(raw);
|
|
5891
|
-
}
|
|
5892
|
-
async runRequest(applicationName, inputs = []) {
|
|
5893
|
-
const path4 = this.namespacePath(
|
|
5894
|
-
`applications/${encodeURIComponent(applicationName)}`
|
|
5895
|
-
);
|
|
5896
|
-
const response = inputs.length === 0 ? await this.transport.requestResponse("POST", path4, {
|
|
5897
|
-
body: new Uint8Array(),
|
|
5898
|
-
headers: { Accept: "application/json" }
|
|
5899
|
-
}) : inputs.length === 1 && inputs[0].name === "0" ? await this.transport.requestResponse("POST", path4, {
|
|
5900
|
-
body: toRequestBody(inputs[0].data),
|
|
5901
|
-
headers: {
|
|
5902
|
-
Accept: "application/json",
|
|
5903
|
-
"Content-Type": inputs[0].contentType
|
|
5904
|
-
}
|
|
5905
|
-
}) : await this.runMultipartRequest(path4, inputs);
|
|
5906
|
-
const body = await parseJsonResponse(response);
|
|
5907
|
-
const requestId = body?.request_id;
|
|
5908
|
-
if (!requestId) {
|
|
5909
|
-
throw new Error("missing request_id in run request response body");
|
|
5910
|
-
}
|
|
5911
|
-
return requestId;
|
|
5912
|
-
}
|
|
5913
|
-
async waitOnRequestCompletion(applicationName, requestId) {
|
|
5914
|
-
const stream = this.transport.stream(
|
|
5915
|
-
"GET",
|
|
5916
|
-
this.namespacePath(
|
|
5917
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/progress`
|
|
5918
|
-
)
|
|
5919
|
-
);
|
|
5920
|
-
for await (const event of stream) {
|
|
5921
|
-
if (Object.prototype.hasOwnProperty.call(event, "RequestFinished")) {
|
|
5922
|
-
return;
|
|
5923
|
-
}
|
|
5924
|
-
}
|
|
5925
|
-
throw new Error("progress stream ended before request completion");
|
|
5926
|
-
}
|
|
5927
|
-
async requestMetadata(applicationName, requestId) {
|
|
5928
|
-
const raw = await this.transport.requestJson(
|
|
5929
|
-
"GET",
|
|
5930
|
-
this.namespacePath(
|
|
5931
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}`
|
|
5932
|
-
)
|
|
5933
|
-
);
|
|
5934
|
-
return fromSnakeKeys(raw);
|
|
5935
|
-
}
|
|
5936
|
-
async requestOutput(applicationName, requestId) {
|
|
5937
|
-
const response = await this.transport.requestResponse(
|
|
5938
|
-
"GET",
|
|
5939
|
-
this.namespacePath(
|
|
5940
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/output`
|
|
5941
|
-
)
|
|
5942
|
-
);
|
|
5943
|
-
const serializedValue = new Uint8Array(await response.arrayBuffer());
|
|
5944
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
5945
|
-
return {
|
|
5946
|
-
serializedValue,
|
|
5947
|
-
contentType
|
|
5948
|
-
};
|
|
5949
|
-
}
|
|
5950
|
-
async listSecrets(options) {
|
|
5951
|
-
const base = this.secretCollectionPath(
|
|
5952
|
-
options?.organizationId,
|
|
5953
|
-
options?.projectId
|
|
5954
|
-
);
|
|
5955
|
-
const raw = await this.transport.requestJson("GET", base);
|
|
5956
|
-
const pageSize = Math.max(0, options?.pageSize ?? 100);
|
|
5957
|
-
return Object.assign(
|
|
5958
|
-
{
|
|
5959
|
-
items: raw.slice(0, pageSize).map(secretFromMetadata),
|
|
5960
|
-
pagination: { total: raw.length }
|
|
5961
|
-
},
|
|
5962
|
-
{ traceId: raw.traceId }
|
|
5963
|
-
);
|
|
5964
|
-
}
|
|
5965
|
-
async getSecret(secretId, options) {
|
|
5966
|
-
const base = this.secretCollectionPath(
|
|
5967
|
-
options?.organizationId,
|
|
5968
|
-
options?.projectId
|
|
5969
|
-
);
|
|
5970
|
-
const raw = await this.transport.requestJson(
|
|
5971
|
-
"GET",
|
|
5972
|
-
`${base}/${encodeURIComponent(secretId)}`
|
|
5973
|
-
);
|
|
5974
|
-
return Object.assign(secretFromMetadata(raw), { traceId: raw.traceId });
|
|
5975
|
-
}
|
|
5976
|
-
async upsertSecrets(secrets, options) {
|
|
5977
|
-
const base = this.secretCollectionPath(
|
|
5978
|
-
options?.organizationId,
|
|
5979
|
-
options?.projectId
|
|
5980
|
-
);
|
|
5981
|
-
if (Array.isArray(secrets)) {
|
|
5982
|
-
const results = [];
|
|
5983
|
-
for (const secret of secrets) {
|
|
5984
|
-
results.push(await this.upsertSecret(base, secret));
|
|
5985
|
-
}
|
|
5986
|
-
return results;
|
|
5987
|
-
}
|
|
5988
|
-
return this.upsertSecret(base, secrets);
|
|
5989
|
-
}
|
|
5990
|
-
async deleteSecret(secretId, options) {
|
|
5991
|
-
const base = this.secretCollectionPath(
|
|
5992
|
-
options?.organizationId,
|
|
5993
|
-
options?.projectId
|
|
5994
|
-
);
|
|
5995
|
-
await this.transport.requestResponse(
|
|
5996
|
-
"DELETE",
|
|
5997
|
-
`${base}/${encodeURIComponent(secretId)}`
|
|
5998
|
-
);
|
|
5999
|
-
}
|
|
6000
|
-
async upsertSecret(base, secret) {
|
|
6001
|
-
let response = await this.transport.requestResponse("POST", base, {
|
|
6002
|
-
json: secret,
|
|
6003
|
-
headers: { "Idempotency-Key": nanoid() },
|
|
6004
|
-
statusOnlyCodes: /* @__PURE__ */ new Set([409])
|
|
6005
|
-
});
|
|
6006
|
-
if (response.status === 409) {
|
|
6007
|
-
const prefix = base.slice(0, -"/secrets".length);
|
|
6008
|
-
const existing = await this.transport.requestJson(
|
|
6009
|
-
"GET",
|
|
6010
|
-
`${prefix}/secret-names/${encodeURIComponent(secret.name)}`
|
|
6011
|
-
);
|
|
6012
|
-
response = await this.transport.requestResponse(
|
|
6013
|
-
"POST",
|
|
6014
|
-
`${base}/${encodeURIComponent(existing.id)}/versions`,
|
|
6015
|
-
{
|
|
6016
|
-
json: { value: secret.value },
|
|
6017
|
-
headers: { "Idempotency-Key": nanoid() }
|
|
6018
|
-
}
|
|
6019
|
-
);
|
|
6020
|
-
}
|
|
6021
|
-
const metadata = await parseJsonResponse(response);
|
|
6022
|
-
return Object.assign(secretFromMetadata(metadata), {
|
|
6023
|
-
traceId: response.traceId
|
|
6024
|
-
});
|
|
6025
|
-
}
|
|
6026
|
-
async startImageBuild(buildServicePath, request) {
|
|
6027
|
-
const form = new FormData();
|
|
6028
|
-
form.append("graph_name", request.applicationName);
|
|
6029
|
-
form.append("graph_version", request.applicationVersion);
|
|
6030
|
-
form.append("graph_function_name", request.functionName);
|
|
6031
|
-
form.append("image_name", request.imageName);
|
|
6032
|
-
form.append("image_id", request.imageId);
|
|
6033
|
-
form.append(
|
|
6034
|
-
"context",
|
|
6035
|
-
new Blob([toBlobPart(request.buildContext)]),
|
|
6036
|
-
"context.tar.gz"
|
|
6037
|
-
);
|
|
6038
|
-
const response = await this.transport.requestResponse(
|
|
6039
|
-
"PUT",
|
|
6040
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds`,
|
|
6041
|
-
{ body: form }
|
|
6042
|
-
);
|
|
6043
|
-
const raw = await parseJsonResponse(response);
|
|
6044
|
-
return fromSnakeKeys(raw);
|
|
6045
|
-
}
|
|
6046
|
-
async createApplicationBuild(buildServicePath, request, imageContexts) {
|
|
6047
|
-
const form = createApplicationBuildForm(request, imageContexts);
|
|
6048
|
-
const response = await this.transport.requestResponse(
|
|
6049
|
-
"POST",
|
|
6050
|
-
trimTrailingSlashes2(buildServicePath),
|
|
6051
|
-
{ body: form }
|
|
6052
|
-
);
|
|
6053
|
-
const raw = await parseJsonResponse(response);
|
|
6054
|
-
return fromSnakeKeys(raw);
|
|
6055
|
-
}
|
|
6056
|
-
async applicationBuildInfo(buildServicePath, applicationBuildId) {
|
|
6057
|
-
const raw = await this.transport.requestJson(
|
|
6058
|
-
"GET",
|
|
6059
|
-
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}`
|
|
6060
|
-
);
|
|
6061
|
-
return fromSnakeKeys(raw);
|
|
6062
|
-
}
|
|
6063
|
-
async cancelApplicationBuild(buildServicePath, applicationBuildId) {
|
|
6064
|
-
const raw = await this.transport.requestJson(
|
|
6065
|
-
"POST",
|
|
6066
|
-
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}/cancel`
|
|
6067
|
-
);
|
|
6068
|
-
return fromSnakeKeys(raw);
|
|
6069
|
-
}
|
|
6070
|
-
async buildInfo(buildServicePath, buildId) {
|
|
6071
|
-
const raw = await this.transport.requestJson(
|
|
6072
|
-
"GET",
|
|
6073
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}`
|
|
6074
|
-
);
|
|
6075
|
-
return fromSnakeKeys(raw);
|
|
6076
|
-
}
|
|
6077
|
-
async cancelBuild(buildServicePath, buildId) {
|
|
6078
|
-
await this.transport.requestResponse(
|
|
6079
|
-
"POST",
|
|
6080
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/cancel`
|
|
6081
|
-
);
|
|
6082
|
-
}
|
|
6083
|
-
async *streamBuildLogs(buildServicePath, buildId, signal) {
|
|
6084
|
-
const stream = this.transport.stream(
|
|
6085
|
-
"GET",
|
|
6086
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/logs`,
|
|
6087
|
-
signal
|
|
6088
|
-
);
|
|
6089
|
-
for await (const event of stream) {
|
|
6090
|
-
yield fromSnakeKeys(event);
|
|
6091
|
-
}
|
|
6092
|
-
}
|
|
6093
|
-
async runMultipartRequest(path4, inputs) {
|
|
6094
|
-
const form = new FormData();
|
|
6095
|
-
for (const input of inputs) {
|
|
6096
|
-
form.append(
|
|
6097
|
-
input.name,
|
|
6098
|
-
new Blob([toBlobPart(input.data)], { type: input.contentType }),
|
|
6099
|
-
input.name
|
|
6100
|
-
);
|
|
6101
|
-
}
|
|
6102
|
-
return this.transport.requestResponse("POST", path4, {
|
|
6103
|
-
body: form,
|
|
6104
|
-
headers: { Accept: "application/json" }
|
|
6105
|
-
});
|
|
6106
|
-
}
|
|
6107
|
-
namespacePath(subpath) {
|
|
6108
|
-
return `/v1/namespaces/${encodeURIComponent(this.namespace)}/${subpath.replace(/^\/+/, "")}`;
|
|
6109
|
-
}
|
|
6110
|
-
async existingApplicationPublicEndpointId(applicationName) {
|
|
6111
|
-
const response = await this.transport.requestResponse(
|
|
6112
|
-
"GET",
|
|
6113
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`),
|
|
6114
|
-
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
6115
|
-
);
|
|
6116
|
-
if (response.status === 404) {
|
|
6117
|
-
return void 0;
|
|
6118
|
-
}
|
|
6119
|
-
const application = await parseJsonResponse(response);
|
|
6120
|
-
return publicEndpointIdFromManifest(application);
|
|
6121
|
-
}
|
|
6122
|
-
platformProjectPath(resource, organizationId, projectId) {
|
|
6123
|
-
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
6124
|
-
const resolvedProjectId = projectId ?? this.projectId;
|
|
6125
|
-
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
6126
|
-
return `/platform/v1/${resource}`;
|
|
6127
|
-
}
|
|
6128
|
-
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
6129
|
-
throw new Error(
|
|
6130
|
-
"organizationId and projectId must be provided together"
|
|
6131
|
-
);
|
|
6132
|
-
}
|
|
6133
|
-
return `/platform/v1/organizations/${encodeURIComponent(resolvedOrganizationId)}/projects/${encodeURIComponent(resolvedProjectId)}/${resource}`;
|
|
6134
|
-
}
|
|
6135
|
-
secretCollectionPath(organizationId, projectId) {
|
|
6136
|
-
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
6137
|
-
const resolvedProjectId = projectId ?? this.projectId;
|
|
6138
|
-
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
6139
|
-
return this.namespacePath("secrets");
|
|
6140
|
-
}
|
|
6141
|
-
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
6142
|
-
throw new Error("organizationId and projectId must be provided together");
|
|
6143
|
-
}
|
|
6144
|
-
return this.namespacePath("secrets");
|
|
6145
|
-
}
|
|
6146
|
-
};
|
|
6147
|
-
UNAUTHENTICATED_REQUESTS = "unauthenticated_requests";
|
|
6148
|
-
}
|
|
6149
|
-
});
|
|
6150
|
-
|
|
6151
5578
|
// src/image.ts
|
|
6152
5579
|
import { randomUUID } from "crypto";
|
|
6153
5580
|
function cloneOperation(op) {
|
|
@@ -6419,22 +5846,477 @@ var init_native_binding = __esm({
|
|
|
6419
5846
|
}
|
|
6420
5847
|
});
|
|
6421
5848
|
|
|
5849
|
+
// src/image-builds.ts
|
|
5850
|
+
import path3 from "path";
|
|
5851
|
+
import os from "os";
|
|
5852
|
+
import { existsSync as existsSync2, mkdtempSync, rmSync } from "fs";
|
|
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 = path3.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 = mkdtempSync(path3.join(os.tmpdir(), "tl-build-context-"));
|
|
6017
|
+
contextDir = tempContextDir;
|
|
6018
|
+
}
|
|
6019
|
+
dockerfilePath = path3.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 = path3.resolve(source);
|
|
6026
|
+
if (!existsSync2(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) 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 ImageBuildError, ImageBuildNotFoundError, ImageBuildInProgressError, ImageBuildFailedError, ImageBuildCancelledError, ImageBuildTimeoutError, ImageBuildInterruptedError, ImageBuildHandle;
|
|
6162
|
+
var init_image_builds = __esm({
|
|
6163
|
+
"src/image-builds.ts"() {
|
|
6164
|
+
"use strict";
|
|
6165
|
+
init_esm_shims();
|
|
6166
|
+
init_image();
|
|
6167
|
+
init_sandbox_image();
|
|
6168
|
+
ImageBuildError = class extends Error {
|
|
6169
|
+
code;
|
|
6170
|
+
buildId;
|
|
6171
|
+
clientRequestId;
|
|
6172
|
+
details;
|
|
6173
|
+
constructor(details) {
|
|
6174
|
+
super(details.message);
|
|
6175
|
+
this.name = "ImageBuildError";
|
|
6176
|
+
this.code = details.code;
|
|
6177
|
+
this.details = details;
|
|
6178
|
+
if (details.buildId) this.buildId = details.buildId;
|
|
6179
|
+
if (details.clientRequestId) this.clientRequestId = details.clientRequestId;
|
|
6180
|
+
}
|
|
6181
|
+
};
|
|
6182
|
+
ImageBuildNotFoundError = class extends ImageBuildError {
|
|
6183
|
+
constructor(details) {
|
|
6184
|
+
super(details);
|
|
6185
|
+
this.name = "ImageBuildNotFoundError";
|
|
6186
|
+
}
|
|
6187
|
+
};
|
|
6188
|
+
ImageBuildInProgressError = class extends ImageBuildError {
|
|
6189
|
+
imageName;
|
|
6190
|
+
activeBuildId;
|
|
6191
|
+
activeKind;
|
|
6192
|
+
activeStatus;
|
|
6193
|
+
constructor(details) {
|
|
6194
|
+
super(details);
|
|
6195
|
+
this.name = "ImageBuildInProgressError";
|
|
6196
|
+
if (details.imageName) this.imageName = details.imageName;
|
|
6197
|
+
if (details.activeBuildId) this.activeBuildId = details.activeBuildId;
|
|
6198
|
+
if (details.activeKind) this.activeKind = details.activeKind;
|
|
6199
|
+
if (details.activeStatus) this.activeStatus = details.activeStatus;
|
|
6200
|
+
}
|
|
6201
|
+
};
|
|
6202
|
+
ImageBuildFailedError = class extends ImageBuildError {
|
|
6203
|
+
error;
|
|
6204
|
+
info;
|
|
6205
|
+
constructor(details) {
|
|
6206
|
+
super(details);
|
|
6207
|
+
this.name = "ImageBuildFailedError";
|
|
6208
|
+
this.error = details.error ?? "no error recorded";
|
|
6209
|
+
if (details.info) this.info = parseBuildInfo(details.info);
|
|
6210
|
+
}
|
|
6211
|
+
};
|
|
6212
|
+
ImageBuildCancelledError = class extends ImageBuildError {
|
|
6213
|
+
info;
|
|
6214
|
+
constructor(details) {
|
|
6215
|
+
super(details);
|
|
6216
|
+
this.name = "ImageBuildCancelledError";
|
|
6217
|
+
if (details.info) this.info = parseBuildInfo(details.info);
|
|
6218
|
+
}
|
|
6219
|
+
};
|
|
6220
|
+
ImageBuildTimeoutError = class extends ImageBuildError {
|
|
6221
|
+
constructor(details) {
|
|
6222
|
+
super(details);
|
|
6223
|
+
this.name = "ImageBuildTimeoutError";
|
|
6224
|
+
}
|
|
6225
|
+
};
|
|
6226
|
+
ImageBuildInterruptedError = class extends ImageBuildError {
|
|
6227
|
+
outcome;
|
|
6228
|
+
confirmed;
|
|
6229
|
+
result;
|
|
6230
|
+
constructor(details) {
|
|
6231
|
+
super(details);
|
|
6232
|
+
this.name = "ImageBuildInterruptedError";
|
|
6233
|
+
this.outcome = details.outcome ?? "unconfirmed";
|
|
6234
|
+
this.confirmed = details.confirmed === true;
|
|
6235
|
+
if (details.result) this.result = details.result;
|
|
6236
|
+
}
|
|
6237
|
+
};
|
|
6238
|
+
ImageBuildHandle = class {
|
|
6239
|
+
buildId;
|
|
6240
|
+
/**
|
|
6241
|
+
* The admission's request id, when this handle started the build. Never
|
|
6242
|
+
* needed to cancel; a recovery aid for a lost admission answer.
|
|
6243
|
+
*/
|
|
6244
|
+
clientRequestId;
|
|
6245
|
+
#info;
|
|
6246
|
+
#credentials;
|
|
6247
|
+
/** @internal */
|
|
6248
|
+
constructor(info, credentials, clientRequestId) {
|
|
6249
|
+
this.buildId = info.buildId;
|
|
6250
|
+
this.clientRequestId = clientRequestId ?? info.clientRequestId ?? null;
|
|
6251
|
+
this.#info = info;
|
|
6252
|
+
this.#credentials = credentials;
|
|
6253
|
+
}
|
|
6254
|
+
/** The last observed state. */
|
|
6255
|
+
get info() {
|
|
6256
|
+
return this.#info;
|
|
6257
|
+
}
|
|
6258
|
+
/** Re-read the current state. */
|
|
6259
|
+
async refresh() {
|
|
6260
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6261
|
+
let json;
|
|
6262
|
+
try {
|
|
6263
|
+
json = await binding.getImageBuild(clientOptions(this.#credentials), this.buildId);
|
|
6264
|
+
} catch (error) {
|
|
6265
|
+
throw toImageBuildError(error);
|
|
6266
|
+
}
|
|
6267
|
+
this.#info = parseBuildInfo(JSON.parse(json));
|
|
6268
|
+
return this.#info;
|
|
6269
|
+
}
|
|
6270
|
+
/**
|
|
6271
|
+
* Wait for publication and return this build's immutable result. See
|
|
6272
|
+
* {@link ImageBuildWaitOptions} for the timeout/abort distinction.
|
|
6273
|
+
*/
|
|
6274
|
+
async wait(options = {}) {
|
|
6275
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6276
|
+
const emitter = makeEmitter(options);
|
|
6277
|
+
const json = await __runWithInterrupt(
|
|
6278
|
+
options.signal,
|
|
6279
|
+
(interruptId) => binding.waitImageBuild(
|
|
6280
|
+
clientOptions(this.#credentials),
|
|
6281
|
+
this.buildId,
|
|
6282
|
+
{ timeoutMs: options.timeoutMs, followLogs: options.followLogs ?? false },
|
|
6283
|
+
emitter.forward,
|
|
6284
|
+
interruptId
|
|
6285
|
+
)
|
|
6286
|
+
);
|
|
6287
|
+
emitter.rethrow();
|
|
6288
|
+
const result = parseResult(json);
|
|
6289
|
+
this.#info = { ...this.#info, status: "succeeded", result };
|
|
6290
|
+
return result;
|
|
6291
|
+
}
|
|
6292
|
+
/** Cancel this build by its id (the sufficient selector). */
|
|
6293
|
+
async cancel() {
|
|
6294
|
+
return cancelImageBuildWith(this.#credentials, { buildId: this.buildId });
|
|
6295
|
+
}
|
|
6296
|
+
};
|
|
6297
|
+
}
|
|
6298
|
+
});
|
|
6299
|
+
|
|
6422
6300
|
// src/sandbox-image.ts
|
|
6423
6301
|
var sandbox_image_exports = {};
|
|
6424
6302
|
__export(sandbox_image_exports, {
|
|
6303
|
+
__imageBuildInternals: () => __imageBuildInternals,
|
|
6425
6304
|
__setNativeBindingForTest: () => __setNativeBindingForTest,
|
|
6426
6305
|
buildContextFromEnv: () => buildContextFromEnv,
|
|
6427
6306
|
createSandboxImage: () => createSandboxImage,
|
|
6428
6307
|
deleteSandboxImage: () => deleteSandboxImage,
|
|
6308
|
+
deleteSandboxImageWithCredentials: () => deleteSandboxImageWithCredentials,
|
|
6429
6309
|
findSandboxImageByName: () => findSandboxImageByName,
|
|
6310
|
+
findSandboxImageByNameWithCredentials: () => findSandboxImageByNameWithCredentials,
|
|
6430
6311
|
importSandboxImage: () => importSandboxImage,
|
|
6431
6312
|
listSandboxImages: () => listSandboxImages,
|
|
6313
|
+
listSandboxImagesWithCredentials: () => listSandboxImagesWithCredentials,
|
|
6432
6314
|
runCreateSandboxImageCli: () => runCreateSandboxImageCli,
|
|
6433
6315
|
runImportSandboxImageCli: () => runImportSandboxImageCli
|
|
6434
6316
|
});
|
|
6435
|
-
import
|
|
6436
|
-
import
|
|
6437
|
-
import { existsSync as
|
|
6317
|
+
import path4 from "path";
|
|
6318
|
+
import os2 from "os";
|
|
6319
|
+
import { existsSync as existsSync3, mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "fs";
|
|
6438
6320
|
import { parseArgs } from "util";
|
|
6439
6321
|
function loadNativeBinding() {
|
|
6440
6322
|
if (cachedNativeBinding) return cachedNativeBinding;
|
|
@@ -6468,9 +6350,9 @@ function buildContextFromEnv() {
|
|
|
6468
6350
|
};
|
|
6469
6351
|
}
|
|
6470
6352
|
function defaultRegisteredName(dockerfilePath) {
|
|
6471
|
-
const parsed =
|
|
6353
|
+
const parsed = path4.parse(dockerfilePath);
|
|
6472
6354
|
if (parsed.name.toLowerCase() === "dockerfile") {
|
|
6473
|
-
const parentName =
|
|
6355
|
+
const parentName = path4.basename(path4.dirname(dockerfilePath)).trim();
|
|
6474
6356
|
return parentName || "sandbox-image";
|
|
6475
6357
|
}
|
|
6476
6358
|
return parsed.name || "sandbox-image";
|
|
@@ -6506,6 +6388,15 @@ function eventToEmitDict(event) {
|
|
|
6506
6388
|
message: event.message
|
|
6507
6389
|
};
|
|
6508
6390
|
if (event.stream != null) out.stream = event.stream;
|
|
6391
|
+
if (event.buildId != null) out.build_id = event.buildId;
|
|
6392
|
+
if (event.clientRequestId !== void 0 && event.eventType !== "status") {
|
|
6393
|
+
out.client_request_id = event.clientRequestId;
|
|
6394
|
+
}
|
|
6395
|
+
if (event.status != null) out.status = event.status;
|
|
6396
|
+
if (event.phase !== void 0 && event.eventType.startsWith("build_")) out.phase = event.phase;
|
|
6397
|
+
if (event.attempt != null) out.attempt = event.attempt;
|
|
6398
|
+
if (event.outcome != null) out.outcome = event.outcome;
|
|
6399
|
+
if (event.confirmed != null) out.confirmed = event.confirmed;
|
|
6509
6400
|
return out;
|
|
6510
6401
|
}
|
|
6511
6402
|
function runOpMountsContext(op) {
|
|
@@ -6560,24 +6451,24 @@ async function createSandboxImage(source, options = {}, deps = {}) {
|
|
|
6560
6451
|
}
|
|
6561
6452
|
let resolvedContext;
|
|
6562
6453
|
if (options.contextDir != null) {
|
|
6563
|
-
resolvedContext =
|
|
6454
|
+
resolvedContext = path4.resolve(options.contextDir);
|
|
6564
6455
|
} else if (imageRequiresContext(source)) {
|
|
6565
6456
|
throw new Error(
|
|
6566
6457
|
"This image reads files from the host (via COPY/ADD or a RUN bind mount), so it needs a build context. Pass `contextDir` pointing at the directory that contains those sources; they resolve relative to it, like `docker build <contextDir>`."
|
|
6567
6458
|
);
|
|
6568
6459
|
} else {
|
|
6569
|
-
tempContextDir =
|
|
6460
|
+
tempContextDir = mkdtempSync2(path4.join(os2.tmpdir(), "tl-build-context-"));
|
|
6570
6461
|
resolvedContext = tempContextDir;
|
|
6571
6462
|
}
|
|
6572
|
-
dockerfilePath =
|
|
6463
|
+
dockerfilePath = path4.join(resolvedContext, "Dockerfile");
|
|
6573
6464
|
let text = dockerfileContent(source);
|
|
6574
6465
|
if (!text.endsWith("\n")) text += "\n";
|
|
6575
6466
|
dockerfileText = text;
|
|
6576
6467
|
nativeContextDir = resolvedContext;
|
|
6577
6468
|
effectiveName = options.registeredName ?? source.name;
|
|
6578
6469
|
} else if (typeof source === "string") {
|
|
6579
|
-
const resolvedPath =
|
|
6580
|
-
if (!
|
|
6470
|
+
const resolvedPath = path4.resolve(source);
|
|
6471
|
+
if (!existsSync3(resolvedPath)) {
|
|
6581
6472
|
throw new Error(`Dockerfile not found: ${source}`);
|
|
6582
6473
|
}
|
|
6583
6474
|
dockerfilePath = resolvedPath;
|
|
@@ -6607,38 +6498,47 @@ async function createSandboxImage(source, options = {}, deps = {}) {
|
|
|
6607
6498
|
deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
|
|
6608
6499
|
);
|
|
6609
6500
|
}
|
|
6501
|
+
if (options.signal !== void 0 && !options.cas) {
|
|
6502
|
+
throw new Error(
|
|
6503
|
+
"signal is only supported for CAS image builds (cas: true); a legacy build has no Image Service build operation to cancel"
|
|
6504
|
+
);
|
|
6505
|
+
}
|
|
6610
6506
|
emit({ type: "status", message: `Building image '${effectiveName}'...` });
|
|
6611
6507
|
const binding = loadNativeBinding();
|
|
6612
6508
|
let emitError;
|
|
6613
|
-
const
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6509
|
+
const nativeOptions = {
|
|
6510
|
+
apiUrl: context.apiUrl,
|
|
6511
|
+
bearerToken,
|
|
6512
|
+
dockerfilePath,
|
|
6513
|
+
registeredName: effectiveName,
|
|
6514
|
+
diskMb: options.diskMb,
|
|
6515
|
+
builderDiskMb: options.builderDiskMb,
|
|
6516
|
+
cpus: options.cpus,
|
|
6517
|
+
memoryMb: options.memoryMb,
|
|
6518
|
+
isPublic: options.isPublic ?? false,
|
|
6519
|
+
organizationId: usePat ? context.organizationId : void 0,
|
|
6520
|
+
projectId: usePat ? context.projectId : void 0,
|
|
6521
|
+
namespace: context.namespace,
|
|
6522
|
+
useScopeHeaders: usePat,
|
|
6523
|
+
userAgent: void 0,
|
|
6524
|
+
dockerCompat: options.dockerCompat ?? false,
|
|
6525
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6526
|
+
dockerfileText,
|
|
6527
|
+
contextDir: nativeContextDir,
|
|
6528
|
+
cas: options.cas ?? false,
|
|
6529
|
+
buildArgs: options.buildArgs
|
|
6530
|
+
};
|
|
6531
|
+
const forward = (event) => {
|
|
6532
|
+
try {
|
|
6533
|
+
emit(eventToEmitDict(event));
|
|
6534
|
+
} catch (error) {
|
|
6535
|
+
emitError ??= error;
|
|
6640
6536
|
}
|
|
6641
|
-
|
|
6537
|
+
};
|
|
6538
|
+
const resultJson = options.cas ? await __runWithInterrupt(
|
|
6539
|
+
options.signal,
|
|
6540
|
+
(interruptId) => binding.buildSandboxImage(nativeOptions, forward, interruptId)
|
|
6541
|
+
) : await binding.buildSandboxImage(nativeOptions, forward);
|
|
6642
6542
|
if (emitError != null) {
|
|
6643
6543
|
throw emitError;
|
|
6644
6544
|
}
|
|
@@ -6655,7 +6555,7 @@ async function createSandboxImage(source, options = {}, deps = {}) {
|
|
|
6655
6555
|
return result;
|
|
6656
6556
|
} finally {
|
|
6657
6557
|
if (tempContextDir != null) {
|
|
6658
|
-
|
|
6558
|
+
rmSync2(tempContextDir, { recursive: true, force: true });
|
|
6659
6559
|
}
|
|
6660
6560
|
}
|
|
6661
6561
|
}
|
|
@@ -6684,39 +6584,47 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
|
|
|
6684
6584
|
deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
|
|
6685
6585
|
);
|
|
6686
6586
|
}
|
|
6587
|
+
if (options.signal !== void 0 && !options.cas) {
|
|
6588
|
+
throw new Error(
|
|
6589
|
+
"signal is only supported for CAS image imports (cas: true); a legacy import has no Image Service build operation to cancel"
|
|
6590
|
+
);
|
|
6591
|
+
}
|
|
6687
6592
|
emit({
|
|
6688
6593
|
type: "status",
|
|
6689
6594
|
message: `Importing image '${reference}' as '${effectiveName}'...`
|
|
6690
6595
|
});
|
|
6691
6596
|
const binding = loadNativeBinding();
|
|
6692
6597
|
let emitError;
|
|
6693
|
-
const
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
}
|
|
6598
|
+
const nativeOptions = {
|
|
6599
|
+
apiUrl: context.apiUrl,
|
|
6600
|
+
bearerToken,
|
|
6601
|
+
imageReference: reference,
|
|
6602
|
+
registeredName: effectiveName,
|
|
6603
|
+
diskMb: options.diskMb,
|
|
6604
|
+
builderDiskMb: options.builderDiskMb,
|
|
6605
|
+
cpus: options.cpus,
|
|
6606
|
+
memoryMb: options.memoryMb,
|
|
6607
|
+
isPublic: options.isPublic ?? false,
|
|
6608
|
+
organizationId: usePat ? context.organizationId : void 0,
|
|
6609
|
+
projectId: usePat ? context.projectId : void 0,
|
|
6610
|
+
namespace: context.namespace,
|
|
6611
|
+
useScopeHeaders: usePat,
|
|
6612
|
+
userAgent: void 0,
|
|
6613
|
+
dockerCompat: options.dockerCompat ?? false,
|
|
6614
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6615
|
+
cas: options.cas ?? false
|
|
6616
|
+
};
|
|
6617
|
+
const forward = (event) => {
|
|
6618
|
+
try {
|
|
6619
|
+
emit(eventToEmitDict(event));
|
|
6620
|
+
} catch (error) {
|
|
6621
|
+
emitError ??= error;
|
|
6718
6622
|
}
|
|
6719
|
-
|
|
6623
|
+
};
|
|
6624
|
+
const resultJson = options.cas ? await __runWithInterrupt(
|
|
6625
|
+
options.signal,
|
|
6626
|
+
(interruptId) => binding.importSandboxImage(nativeOptions, forward, interruptId)
|
|
6627
|
+
) : await binding.importSandboxImage(nativeOptions, forward);
|
|
6720
6628
|
if (emitError != null) {
|
|
6721
6629
|
throw emitError;
|
|
6722
6630
|
}
|
|
@@ -6732,10 +6640,7 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
|
|
|
6732
6640
|
emit({ type: "done" });
|
|
6733
6641
|
return result;
|
|
6734
6642
|
}
|
|
6735
|
-
|
|
6736
|
-
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6737
|
-
throw new TypeError("imageName must be a non-empty string");
|
|
6738
|
-
}
|
|
6643
|
+
function catalogOptionsFromEnv() {
|
|
6739
6644
|
const context = buildContextFromEnv();
|
|
6740
6645
|
const bearerToken = context.apiKey;
|
|
6741
6646
|
if (!bearerToken) {
|
|
@@ -6746,63 +6651,73 @@ async function deleteSandboxImage(imageName) {
|
|
|
6746
6651
|
}
|
|
6747
6652
|
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6748
6653
|
}
|
|
6749
|
-
|
|
6750
|
-
apiUrl: context.apiUrl,
|
|
6751
|
-
apiKey: bearerToken,
|
|
6752
|
-
namespace: context.namespace
|
|
6753
|
-
});
|
|
6754
|
-
try {
|
|
6755
|
-
await client.deleteSandboxImage(imageName);
|
|
6756
|
-
} finally {
|
|
6757
|
-
client.close();
|
|
6758
|
-
}
|
|
6654
|
+
return { apiUrl: context.apiUrl, bearerToken, useScopeHeaders: false };
|
|
6759
6655
|
}
|
|
6760
|
-
|
|
6761
|
-
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6762
|
-
throw new TypeError("imageName must be a non-empty string");
|
|
6763
|
-
}
|
|
6656
|
+
function catalogOptionsFromCredentials(credentials) {
|
|
6764
6657
|
const context = buildContextFromEnv();
|
|
6765
|
-
const bearerToken = context.apiKey;
|
|
6658
|
+
const bearerToken = credentials.apiKey ?? context.apiKey;
|
|
6766
6659
|
if (!bearerToken) {
|
|
6767
|
-
if (context.personalAccessToken) {
|
|
6768
|
-
throw new Error(
|
|
6769
|
-
"Sandbox image SDKs require TENSORLAKE_API_KEY. Personal access tokens are CLI-only."
|
|
6770
|
-
);
|
|
6771
|
-
}
|
|
6772
6660
|
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6773
6661
|
}
|
|
6774
|
-
const
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
namespace: context.namespace
|
|
6778
|
-
});
|
|
6779
|
-
try {
|
|
6780
|
-
return await client.findSandboxImageByName(imageName);
|
|
6781
|
-
} finally {
|
|
6782
|
-
client.close();
|
|
6662
|
+
const { organizationId, projectId } = credentials;
|
|
6663
|
+
if (organizationId === void 0 !== (projectId === void 0)) {
|
|
6664
|
+
throw new TypeError("organizationId and projectId must be given together");
|
|
6783
6665
|
}
|
|
6666
|
+
return {
|
|
6667
|
+
apiUrl: credentials.apiUrl ?? context.apiUrl,
|
|
6668
|
+
bearerToken,
|
|
6669
|
+
organizationId,
|
|
6670
|
+
projectId,
|
|
6671
|
+
useScopeHeaders: organizationId !== void 0
|
|
6672
|
+
};
|
|
6784
6673
|
}
|
|
6785
|
-
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
|
|
6674
|
+
function parseTemplate(json) {
|
|
6675
|
+
return JSON.parse(json);
|
|
6676
|
+
}
|
|
6677
|
+
async function deleteSandboxImage(imageName) {
|
|
6678
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6679
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6680
|
+
}
|
|
6681
|
+
await loadNativeBinding().deleteSandboxImage(catalogOptionsFromEnv(), imageName);
|
|
6682
|
+
}
|
|
6683
|
+
async function deleteSandboxImageWithCredentials(credentials, imageName) {
|
|
6684
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6685
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6686
|
+
}
|
|
6687
|
+
await loadNativeBinding().deleteSandboxImage(
|
|
6688
|
+
catalogOptionsFromCredentials(credentials),
|
|
6689
|
+
imageName
|
|
6690
|
+
);
|
|
6691
|
+
}
|
|
6692
|
+
async function findSandboxImageByName(imageName) {
|
|
6693
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6694
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6795
6695
|
}
|
|
6796
|
-
const
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6696
|
+
const json = await loadNativeBinding().findSandboxImage(
|
|
6697
|
+
catalogOptionsFromEnv(),
|
|
6698
|
+
imageName
|
|
6699
|
+
);
|
|
6700
|
+
return json == null ? null : parseTemplate(json);
|
|
6701
|
+
}
|
|
6702
|
+
async function findSandboxImageByNameWithCredentials(credentials, imageName) {
|
|
6703
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6704
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6805
6705
|
}
|
|
6706
|
+
const json = await loadNativeBinding().findSandboxImage(
|
|
6707
|
+
catalogOptionsFromCredentials(credentials),
|
|
6708
|
+
imageName
|
|
6709
|
+
);
|
|
6710
|
+
return json == null ? null : parseTemplate(json);
|
|
6711
|
+
}
|
|
6712
|
+
async function listSandboxImages() {
|
|
6713
|
+
const json = await loadNativeBinding().listSandboxImages(catalogOptionsFromEnv());
|
|
6714
|
+
return JSON.parse(json);
|
|
6715
|
+
}
|
|
6716
|
+
async function listSandboxImagesWithCredentials(credentials) {
|
|
6717
|
+
const json = await loadNativeBinding().listSandboxImages(
|
|
6718
|
+
catalogOptionsFromCredentials(credentials)
|
|
6719
|
+
);
|
|
6720
|
+
return JSON.parse(json);
|
|
6806
6721
|
}
|
|
6807
6722
|
async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
|
|
6808
6723
|
const parsed = parseArgs({
|
|
@@ -6912,15 +6827,25 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
|
|
|
6912
6827
|
{ emit: ndjsonStdoutEmit, _allowPat: true }
|
|
6913
6828
|
);
|
|
6914
6829
|
}
|
|
6915
|
-
var cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME2;
|
|
6830
|
+
var cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME2, __imageBuildInternals;
|
|
6916
6831
|
var init_sandbox_image = __esm({
|
|
6917
6832
|
"src/sandbox-image.ts"() {
|
|
6918
6833
|
"use strict";
|
|
6919
6834
|
init_esm_shims();
|
|
6920
|
-
init_cloud_client();
|
|
6921
6835
|
init_image();
|
|
6922
6836
|
init_native_binding();
|
|
6837
|
+
init_image_builds();
|
|
6923
6838
|
DEFAULT_IMAGE_NAME2 = "default";
|
|
6839
|
+
__imageBuildInternals = {
|
|
6840
|
+
loadNativeBinding: () => loadNativeBinding(),
|
|
6841
|
+
buildContextFromEnv: () => buildContextFromEnv(),
|
|
6842
|
+
stderrEmit: (event) => stderrEmit(event),
|
|
6843
|
+
noopEmit: (event) => noopEmit(event),
|
|
6844
|
+
eventToEmitDict: (event) => eventToEmitDict(event),
|
|
6845
|
+
imageRequiresContext: (image) => imageRequiresContext(image),
|
|
6846
|
+
defaultRegisteredName: (dockerfilePath) => defaultRegisteredName(dockerfilePath),
|
|
6847
|
+
defaultRegisteredNameFromImage: (reference) => defaultRegisteredNameFromImage(reference)
|
|
6848
|
+
};
|
|
6924
6849
|
}
|
|
6925
6850
|
});
|
|
6926
6851
|
|
|
@@ -6932,11 +6857,546 @@ init_pending_sandbox();
|
|
|
6932
6857
|
init_sandbox();
|
|
6933
6858
|
init_desktop();
|
|
6934
6859
|
init_tunnel();
|
|
6935
|
-
|
|
6860
|
+
|
|
6861
|
+
// src/cloud-client.ts
|
|
6862
|
+
init_esm_shims();
|
|
6863
|
+
init_defaults();
|
|
6864
|
+
import { nanoid } from "nanoid";
|
|
6865
|
+
|
|
6866
|
+
// src/native-cloud.ts
|
|
6867
|
+
init_esm_shims();
|
|
6868
|
+
init_native_sandbox();
|
|
6869
|
+
init_native_worker_client();
|
|
6870
|
+
var NativeCloudTransport = class {
|
|
6871
|
+
constructor(options) {
|
|
6872
|
+
this.options = options;
|
|
6873
|
+
if (!Number.isSafeInteger(options.maxRetries) || options.maxRetries < 0 || options.maxRetries > 4294967295) {
|
|
6874
|
+
throw new RangeError("maxRetries must be a non-negative 32-bit integer");
|
|
6875
|
+
}
|
|
6876
|
+
if (!Number.isFinite(options.retryBackoffMs) || options.retryBackoffMs < 0) {
|
|
6877
|
+
throw new RangeError("retryBackoffMs must be a non-negative finite number");
|
|
6878
|
+
}
|
|
6879
|
+
}
|
|
6880
|
+
native;
|
|
6881
|
+
closed = false;
|
|
6882
|
+
client() {
|
|
6883
|
+
if (this.closed) throw new Error("Tensorlake native client is closed");
|
|
6884
|
+
if (this.native) return this.native;
|
|
6885
|
+
const ctor = loadNativeSandboxBinding().NativeCloudClient;
|
|
6886
|
+
if (!ctor) throw new Error("Native binding does not export NativeCloudClient; rebuild with 'npm run build:native'");
|
|
6887
|
+
return this.native = new ctor(JSON.stringify(this.options));
|
|
6888
|
+
}
|
|
6889
|
+
close() {
|
|
6890
|
+
this.closed = true;
|
|
6891
|
+
releaseNativeHandle(this.native ?? null);
|
|
6892
|
+
this.native = void 0;
|
|
6893
|
+
}
|
|
6894
|
+
async requestResponse(method, path5, options) {
|
|
6895
|
+
const request = await serializeRequest(method, path5, options);
|
|
6896
|
+
const raw = await callNative(() => this.client().request(request));
|
|
6897
|
+
const response = new Response(
|
|
6898
|
+
[204, 205, 304].includes(raw.status) ? null : Uint8Array.from(raw.data).buffer,
|
|
6899
|
+
{ status: raw.status, headers: JSON.parse(raw.headersJson) }
|
|
6900
|
+
);
|
|
6901
|
+
return Object.assign(response, { traceId: raw.traceId });
|
|
6902
|
+
}
|
|
6903
|
+
async requestJson(method, path5) {
|
|
6904
|
+
const response = await this.requestResponse(method, path5);
|
|
6905
|
+
const text = await response.text();
|
|
6906
|
+
const value = text ? JSON.parse(text) : null;
|
|
6907
|
+
return Object.assign(value ?? {}, { traceId: response.traceId });
|
|
6908
|
+
}
|
|
6909
|
+
async *stream(method, path5, signal) {
|
|
6910
|
+
if (signal?.aborted) return;
|
|
6911
|
+
const request = await serializeRequest(method, path5, { headers: { Accept: "text/event-stream" } });
|
|
6912
|
+
yield* nativeEventStream((emit) => this.client().stream(request, emit), void 0, signal);
|
|
6913
|
+
}
|
|
6914
|
+
};
|
|
6915
|
+
async function serializeRequest(method, path5, options) {
|
|
6916
|
+
const headers = { ...options?.headers };
|
|
6917
|
+
let body = options?.body;
|
|
6918
|
+
if (options?.json !== void 0) {
|
|
6919
|
+
body = JSON.stringify(options.json);
|
|
6920
|
+
if (!Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) {
|
|
6921
|
+
headers["Content-Type"] = "application/json";
|
|
6922
|
+
}
|
|
6923
|
+
}
|
|
6924
|
+
const request = {
|
|
6925
|
+
method,
|
|
6926
|
+
path: path5,
|
|
6927
|
+
headersJson: JSON.stringify(headers),
|
|
6928
|
+
statusOnlyCodes: [...options?.statusOnlyCodes ?? []]
|
|
6929
|
+
};
|
|
6930
|
+
if (body instanceof FormData) {
|
|
6931
|
+
request.parts = [];
|
|
6932
|
+
for (const [name, value] of body.entries()) {
|
|
6933
|
+
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" });
|
|
6934
|
+
}
|
|
6935
|
+
} else if (body !== void 0) {
|
|
6936
|
+
if (body instanceof Blob) request.body = Buffer.from(await body.arrayBuffer());
|
|
6937
|
+
else if (typeof body === "string") request.body = Buffer.from(body);
|
|
6938
|
+
else if (body instanceof ArrayBuffer) request.body = Buffer.from(new Uint8Array(body));
|
|
6939
|
+
else request.body = Buffer.from(body);
|
|
6940
|
+
}
|
|
6941
|
+
return request;
|
|
6942
|
+
}
|
|
6943
|
+
|
|
6944
|
+
// src/cloud-client.ts
|
|
6945
|
+
init_models();
|
|
6946
|
+
init_sandbox_image();
|
|
6947
|
+
var CloudClient = class _CloudClient {
|
|
6948
|
+
transport;
|
|
6949
|
+
apiUrl;
|
|
6950
|
+
apiKey;
|
|
6951
|
+
organizationId;
|
|
6952
|
+
projectId;
|
|
6953
|
+
namespace;
|
|
6954
|
+
constructor(options) {
|
|
6955
|
+
this.apiUrl = options?.apiUrl ?? API_URL;
|
|
6956
|
+
this.apiKey = options?.apiKey ?? API_KEY;
|
|
6957
|
+
this.organizationId = options?.organizationId;
|
|
6958
|
+
this.projectId = options?.projectId;
|
|
6959
|
+
this.namespace = options?.namespace ?? NAMESPACE;
|
|
6960
|
+
this.transport = new NativeCloudTransport({
|
|
6961
|
+
baseUrl: options?.apiUrl ?? API_URL,
|
|
6962
|
+
apiKey: options?.apiKey ?? API_KEY,
|
|
6963
|
+
organizationId: this.organizationId,
|
|
6964
|
+
projectId: this.projectId,
|
|
6965
|
+
maxRetries: options?.maxRetries ?? MAX_RETRIES,
|
|
6966
|
+
retryBackoffMs: options?.retryBackoffMs ?? RETRY_BACKOFF_MS,
|
|
6967
|
+
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
6968
|
+
userAgent: `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
6969
|
+
});
|
|
6970
|
+
}
|
|
6971
|
+
static forCloud(options) {
|
|
6972
|
+
return new _CloudClient(options);
|
|
6973
|
+
}
|
|
6974
|
+
close() {
|
|
6975
|
+
this.transport.close();
|
|
6976
|
+
}
|
|
6977
|
+
async upsertApplication(manifest, codeZip, upgradeRunningRequests = false) {
|
|
6978
|
+
const applicationManifest = { ...manifest };
|
|
6979
|
+
let publicEndpointId = publicEndpointIdFromManifest(applicationManifest);
|
|
6980
|
+
if (applicationAllowsUnauthenticatedRequests(applicationManifest) && publicEndpointId === void 0) {
|
|
6981
|
+
const applicationName = applicationManifest.name;
|
|
6982
|
+
if (typeof applicationName === "string" && applicationName.length > 0) {
|
|
6983
|
+
publicEndpointId = await this.existingApplicationPublicEndpointId(applicationName);
|
|
6984
|
+
}
|
|
6985
|
+
publicEndpointId ??= generatePublicEndpointId();
|
|
6986
|
+
}
|
|
6987
|
+
if (publicEndpointId !== void 0) {
|
|
6988
|
+
applicationManifest.public_endpoint_id = publicEndpointId;
|
|
6989
|
+
delete applicationManifest.publicEndpointId;
|
|
6990
|
+
}
|
|
6991
|
+
const form = new FormData();
|
|
6992
|
+
form.append(
|
|
6993
|
+
"code",
|
|
6994
|
+
new Blob([toBlobPart(codeZip)], { type: "application/zip" }),
|
|
6995
|
+
"code.zip"
|
|
6996
|
+
);
|
|
6997
|
+
form.append("code_content_type", "application/zip");
|
|
6998
|
+
form.append("application", JSON.stringify(applicationManifest));
|
|
6999
|
+
form.append(
|
|
7000
|
+
"upgrade_requests_to_latest_code",
|
|
7001
|
+
String(upgradeRunningRequests)
|
|
7002
|
+
);
|
|
7003
|
+
await this.transport.requestResponse("POST", this.namespacePath("applications"), {
|
|
7004
|
+
body: form
|
|
7005
|
+
});
|
|
7006
|
+
}
|
|
7007
|
+
async deleteApplication(applicationName) {
|
|
7008
|
+
await this.transport.requestResponse(
|
|
7009
|
+
"DELETE",
|
|
7010
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
7011
|
+
);
|
|
7012
|
+
}
|
|
7013
|
+
/**
|
|
7014
|
+
* Delete a registered sandbox image by name or id through the merged
|
|
7015
|
+
* catalog, with this client's credentials: an `image_` id or a name the
|
|
7016
|
+
* Image Service knows deletes a CAS image, a `sandbox_template_` id or a
|
|
7017
|
+
* name registered only in the platform registry deletes a legacy image.
|
|
7018
|
+
* Rejects when neither catalog knows the reference. The same semantics
|
|
7019
|
+
* and accepted differences as the module-level `deleteSandboxImage`.
|
|
7020
|
+
*/
|
|
7021
|
+
async deleteSandboxImage(imageName) {
|
|
7022
|
+
await deleteSandboxImageWithCredentials(this.catalogCredentials(), imageName);
|
|
7023
|
+
}
|
|
7024
|
+
/**
|
|
7025
|
+
* Look up a registered sandbox image by name or id through the merged
|
|
7026
|
+
* catalog, with this client's credentials. Returns the image in the
|
|
7027
|
+
* sandbox-template shape, or `null` when neither the Image Service nor the
|
|
7028
|
+
* platform registry knows the reference. An explicit organization/project
|
|
7029
|
+
* scope (the client's, or the call's override) addresses that project's
|
|
7030
|
+
* routes directly, as before; without one the key's own scope applies.
|
|
7031
|
+
*/
|
|
7032
|
+
async findSandboxImageByName(imageName, options) {
|
|
7033
|
+
return findSandboxImageByNameWithCredentials(
|
|
7034
|
+
this.catalogCredentials(options),
|
|
7035
|
+
imageName
|
|
7036
|
+
);
|
|
7037
|
+
}
|
|
7038
|
+
/**
|
|
7039
|
+
* List every registered sandbox image of the project (CAS and legacy, in
|
|
7040
|
+
* the sandbox-template shape, newest first) through the merged catalog,
|
|
7041
|
+
* with this client's credentials. An explicit organization/project scope
|
|
7042
|
+
* (the client's, or the call's override) addresses that project's routes
|
|
7043
|
+
* directly, as before; without one the key's own scope applies.
|
|
7044
|
+
*/
|
|
7045
|
+
async listSandboxImages(options) {
|
|
7046
|
+
return listSandboxImagesWithCredentials(this.catalogCredentials(options));
|
|
7047
|
+
}
|
|
7048
|
+
catalogCredentials(options) {
|
|
7049
|
+
return {
|
|
7050
|
+
apiUrl: this.apiUrl,
|
|
7051
|
+
apiKey: this.apiKey,
|
|
7052
|
+
organizationId: options?.organizationId ?? this.organizationId,
|
|
7053
|
+
projectId: options?.projectId ?? this.projectId
|
|
7054
|
+
};
|
|
7055
|
+
}
|
|
7056
|
+
async applications() {
|
|
7057
|
+
const raw = await this.transport.requestJson(
|
|
7058
|
+
"GET",
|
|
7059
|
+
this.namespacePath("applications")
|
|
7060
|
+
);
|
|
7061
|
+
return (raw.applications ?? []).map(
|
|
7062
|
+
(application) => fromSnakeKeys(application)
|
|
7063
|
+
);
|
|
7064
|
+
}
|
|
7065
|
+
async applicationManifest(applicationName) {
|
|
7066
|
+
const raw = await this.transport.requestJson(
|
|
7067
|
+
"GET",
|
|
7068
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
7069
|
+
);
|
|
7070
|
+
return fromSnakeKeys(raw);
|
|
7071
|
+
}
|
|
7072
|
+
async runRequest(applicationName, inputs = []) {
|
|
7073
|
+
const path5 = this.namespacePath(
|
|
7074
|
+
`applications/${encodeURIComponent(applicationName)}`
|
|
7075
|
+
);
|
|
7076
|
+
const response = inputs.length === 0 ? await this.transport.requestResponse("POST", path5, {
|
|
7077
|
+
body: new Uint8Array(),
|
|
7078
|
+
headers: { Accept: "application/json" }
|
|
7079
|
+
}) : inputs.length === 1 && inputs[0].name === "0" ? await this.transport.requestResponse("POST", path5, {
|
|
7080
|
+
body: toRequestBody(inputs[0].data),
|
|
7081
|
+
headers: {
|
|
7082
|
+
Accept: "application/json",
|
|
7083
|
+
"Content-Type": inputs[0].contentType
|
|
7084
|
+
}
|
|
7085
|
+
}) : await this.runMultipartRequest(path5, inputs);
|
|
7086
|
+
const body = await parseJsonResponse(response);
|
|
7087
|
+
const requestId = body?.request_id;
|
|
7088
|
+
if (!requestId) {
|
|
7089
|
+
throw new Error("missing request_id in run request response body");
|
|
7090
|
+
}
|
|
7091
|
+
return requestId;
|
|
7092
|
+
}
|
|
7093
|
+
async waitOnRequestCompletion(applicationName, requestId) {
|
|
7094
|
+
const stream = this.transport.stream(
|
|
7095
|
+
"GET",
|
|
7096
|
+
this.namespacePath(
|
|
7097
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/progress`
|
|
7098
|
+
)
|
|
7099
|
+
);
|
|
7100
|
+
for await (const event of stream) {
|
|
7101
|
+
if (Object.prototype.hasOwnProperty.call(event, "RequestFinished")) {
|
|
7102
|
+
return;
|
|
7103
|
+
}
|
|
7104
|
+
}
|
|
7105
|
+
throw new Error("progress stream ended before request completion");
|
|
7106
|
+
}
|
|
7107
|
+
async requestMetadata(applicationName, requestId) {
|
|
7108
|
+
const raw = await this.transport.requestJson(
|
|
7109
|
+
"GET",
|
|
7110
|
+
this.namespacePath(
|
|
7111
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}`
|
|
7112
|
+
)
|
|
7113
|
+
);
|
|
7114
|
+
return fromSnakeKeys(raw);
|
|
7115
|
+
}
|
|
7116
|
+
async requestOutput(applicationName, requestId) {
|
|
7117
|
+
const response = await this.transport.requestResponse(
|
|
7118
|
+
"GET",
|
|
7119
|
+
this.namespacePath(
|
|
7120
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/output`
|
|
7121
|
+
)
|
|
7122
|
+
);
|
|
7123
|
+
const serializedValue = new Uint8Array(await response.arrayBuffer());
|
|
7124
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
7125
|
+
return {
|
|
7126
|
+
serializedValue,
|
|
7127
|
+
contentType
|
|
7128
|
+
};
|
|
7129
|
+
}
|
|
7130
|
+
async listSecrets(options) {
|
|
7131
|
+
const base = this.secretCollectionPath(
|
|
7132
|
+
options?.organizationId,
|
|
7133
|
+
options?.projectId
|
|
7134
|
+
);
|
|
7135
|
+
const raw = await this.transport.requestJson("GET", base);
|
|
7136
|
+
const pageSize = Math.max(0, options?.pageSize ?? 100);
|
|
7137
|
+
return Object.assign(
|
|
7138
|
+
{
|
|
7139
|
+
items: raw.slice(0, pageSize).map(secretFromMetadata),
|
|
7140
|
+
pagination: { total: raw.length }
|
|
7141
|
+
},
|
|
7142
|
+
{ traceId: raw.traceId }
|
|
7143
|
+
);
|
|
7144
|
+
}
|
|
7145
|
+
async getSecret(secretId, options) {
|
|
7146
|
+
const base = this.secretCollectionPath(
|
|
7147
|
+
options?.organizationId,
|
|
7148
|
+
options?.projectId
|
|
7149
|
+
);
|
|
7150
|
+
const raw = await this.transport.requestJson(
|
|
7151
|
+
"GET",
|
|
7152
|
+
`${base}/${encodeURIComponent(secretId)}`
|
|
7153
|
+
);
|
|
7154
|
+
return Object.assign(secretFromMetadata(raw), { traceId: raw.traceId });
|
|
7155
|
+
}
|
|
7156
|
+
async upsertSecrets(secrets, options) {
|
|
7157
|
+
const base = this.secretCollectionPath(
|
|
7158
|
+
options?.organizationId,
|
|
7159
|
+
options?.projectId
|
|
7160
|
+
);
|
|
7161
|
+
if (Array.isArray(secrets)) {
|
|
7162
|
+
const results = [];
|
|
7163
|
+
for (const secret of secrets) {
|
|
7164
|
+
results.push(await this.upsertSecret(base, secret));
|
|
7165
|
+
}
|
|
7166
|
+
return results;
|
|
7167
|
+
}
|
|
7168
|
+
return this.upsertSecret(base, secrets);
|
|
7169
|
+
}
|
|
7170
|
+
async deleteSecret(secretId, options) {
|
|
7171
|
+
const base = this.secretCollectionPath(
|
|
7172
|
+
options?.organizationId,
|
|
7173
|
+
options?.projectId
|
|
7174
|
+
);
|
|
7175
|
+
await this.transport.requestResponse(
|
|
7176
|
+
"DELETE",
|
|
7177
|
+
`${base}/${encodeURIComponent(secretId)}`
|
|
7178
|
+
);
|
|
7179
|
+
}
|
|
7180
|
+
async upsertSecret(base, secret) {
|
|
7181
|
+
let response = await this.transport.requestResponse("POST", base, {
|
|
7182
|
+
json: secret,
|
|
7183
|
+
headers: { "Idempotency-Key": nanoid() },
|
|
7184
|
+
statusOnlyCodes: /* @__PURE__ */ new Set([409])
|
|
7185
|
+
});
|
|
7186
|
+
if (response.status === 409) {
|
|
7187
|
+
const prefix = base.slice(0, -"/secrets".length);
|
|
7188
|
+
const existing = await this.transport.requestJson(
|
|
7189
|
+
"GET",
|
|
7190
|
+
`${prefix}/secret-names/${encodeURIComponent(secret.name)}`
|
|
7191
|
+
);
|
|
7192
|
+
response = await this.transport.requestResponse(
|
|
7193
|
+
"POST",
|
|
7194
|
+
`${base}/${encodeURIComponent(existing.id)}/versions`,
|
|
7195
|
+
{
|
|
7196
|
+
json: { value: secret.value },
|
|
7197
|
+
headers: { "Idempotency-Key": nanoid() }
|
|
7198
|
+
}
|
|
7199
|
+
);
|
|
7200
|
+
}
|
|
7201
|
+
const metadata = await parseJsonResponse(response);
|
|
7202
|
+
return Object.assign(secretFromMetadata(metadata), {
|
|
7203
|
+
traceId: response.traceId
|
|
7204
|
+
});
|
|
7205
|
+
}
|
|
7206
|
+
async startImageBuild(buildServicePath, request) {
|
|
7207
|
+
const form = new FormData();
|
|
7208
|
+
form.append("graph_name", request.applicationName);
|
|
7209
|
+
form.append("graph_version", request.applicationVersion);
|
|
7210
|
+
form.append("graph_function_name", request.functionName);
|
|
7211
|
+
form.append("image_name", request.imageName);
|
|
7212
|
+
form.append("image_id", request.imageId);
|
|
7213
|
+
form.append(
|
|
7214
|
+
"context",
|
|
7215
|
+
new Blob([toBlobPart(request.buildContext)]),
|
|
7216
|
+
"context.tar.gz"
|
|
7217
|
+
);
|
|
7218
|
+
const response = await this.transport.requestResponse(
|
|
7219
|
+
"PUT",
|
|
7220
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds`,
|
|
7221
|
+
{ body: form }
|
|
7222
|
+
);
|
|
7223
|
+
const raw = await parseJsonResponse(response);
|
|
7224
|
+
return fromSnakeKeys(raw);
|
|
7225
|
+
}
|
|
7226
|
+
async createApplicationBuild(buildServicePath, request, imageContexts) {
|
|
7227
|
+
const form = createApplicationBuildForm(request, imageContexts);
|
|
7228
|
+
const response = await this.transport.requestResponse(
|
|
7229
|
+
"POST",
|
|
7230
|
+
trimTrailingSlashes2(buildServicePath),
|
|
7231
|
+
{ body: form }
|
|
7232
|
+
);
|
|
7233
|
+
const raw = await parseJsonResponse(response);
|
|
7234
|
+
return fromSnakeKeys(raw);
|
|
7235
|
+
}
|
|
7236
|
+
async applicationBuildInfo(buildServicePath, applicationBuildId) {
|
|
7237
|
+
const raw = await this.transport.requestJson(
|
|
7238
|
+
"GET",
|
|
7239
|
+
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}`
|
|
7240
|
+
);
|
|
7241
|
+
return fromSnakeKeys(raw);
|
|
7242
|
+
}
|
|
7243
|
+
async cancelApplicationBuild(buildServicePath, applicationBuildId) {
|
|
7244
|
+
const raw = await this.transport.requestJson(
|
|
7245
|
+
"POST",
|
|
7246
|
+
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}/cancel`
|
|
7247
|
+
);
|
|
7248
|
+
return fromSnakeKeys(raw);
|
|
7249
|
+
}
|
|
7250
|
+
async buildInfo(buildServicePath, buildId) {
|
|
7251
|
+
const raw = await this.transport.requestJson(
|
|
7252
|
+
"GET",
|
|
7253
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}`
|
|
7254
|
+
);
|
|
7255
|
+
return fromSnakeKeys(raw);
|
|
7256
|
+
}
|
|
7257
|
+
async cancelBuild(buildServicePath, buildId) {
|
|
7258
|
+
await this.transport.requestResponse(
|
|
7259
|
+
"POST",
|
|
7260
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/cancel`
|
|
7261
|
+
);
|
|
7262
|
+
}
|
|
7263
|
+
async *streamBuildLogs(buildServicePath, buildId, signal) {
|
|
7264
|
+
const stream = this.transport.stream(
|
|
7265
|
+
"GET",
|
|
7266
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/logs`,
|
|
7267
|
+
signal
|
|
7268
|
+
);
|
|
7269
|
+
for await (const event of stream) {
|
|
7270
|
+
yield fromSnakeKeys(event);
|
|
7271
|
+
}
|
|
7272
|
+
}
|
|
7273
|
+
async runMultipartRequest(path5, inputs) {
|
|
7274
|
+
const form = new FormData();
|
|
7275
|
+
for (const input of inputs) {
|
|
7276
|
+
form.append(
|
|
7277
|
+
input.name,
|
|
7278
|
+
new Blob([toBlobPart(input.data)], { type: input.contentType }),
|
|
7279
|
+
input.name
|
|
7280
|
+
);
|
|
7281
|
+
}
|
|
7282
|
+
return this.transport.requestResponse("POST", path5, {
|
|
7283
|
+
body: form,
|
|
7284
|
+
headers: { Accept: "application/json" }
|
|
7285
|
+
});
|
|
7286
|
+
}
|
|
7287
|
+
namespacePath(subpath) {
|
|
7288
|
+
return `/v1/namespaces/${encodeURIComponent(this.namespace)}/${subpath.replace(/^\/+/, "")}`;
|
|
7289
|
+
}
|
|
7290
|
+
async existingApplicationPublicEndpointId(applicationName) {
|
|
7291
|
+
const response = await this.transport.requestResponse(
|
|
7292
|
+
"GET",
|
|
7293
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`),
|
|
7294
|
+
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
7295
|
+
);
|
|
7296
|
+
if (response.status === 404) {
|
|
7297
|
+
return void 0;
|
|
7298
|
+
}
|
|
7299
|
+
const application = await parseJsonResponse(response);
|
|
7300
|
+
return publicEndpointIdFromManifest(application);
|
|
7301
|
+
}
|
|
7302
|
+
secretCollectionPath(organizationId, projectId) {
|
|
7303
|
+
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
7304
|
+
const resolvedProjectId = projectId ?? this.projectId;
|
|
7305
|
+
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
7306
|
+
return this.namespacePath("secrets");
|
|
7307
|
+
}
|
|
7308
|
+
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
7309
|
+
throw new Error("organizationId and projectId must be provided together");
|
|
7310
|
+
}
|
|
7311
|
+
return this.namespacePath("secrets");
|
|
7312
|
+
}
|
|
7313
|
+
};
|
|
7314
|
+
function secretFromMetadata(metadata) {
|
|
7315
|
+
return {
|
|
7316
|
+
id: metadata.id,
|
|
7317
|
+
name: metadata.name,
|
|
7318
|
+
createdAt: new Date(metadata.created_at_ms)
|
|
7319
|
+
};
|
|
7320
|
+
}
|
|
7321
|
+
var UNAUTHENTICATED_REQUESTS = "unauthenticated_requests";
|
|
7322
|
+
function applicationAllowsUnauthenticatedRequests(manifest) {
|
|
7323
|
+
return Array.isArray(manifest.allow) && manifest.allow.includes(UNAUTHENTICATED_REQUESTS);
|
|
7324
|
+
}
|
|
7325
|
+
function publicEndpointIdFromManifest(manifest) {
|
|
7326
|
+
for (const key of ["public_endpoint_id", "publicEndpointId"]) {
|
|
7327
|
+
const value = manifest[key];
|
|
7328
|
+
if (typeof value === "string" && value.length > 0) {
|
|
7329
|
+
return value;
|
|
7330
|
+
}
|
|
7331
|
+
}
|
|
7332
|
+
return void 0;
|
|
7333
|
+
}
|
|
7334
|
+
function generatePublicEndpointId() {
|
|
7335
|
+
return `endpoint_${nanoid()}`;
|
|
7336
|
+
}
|
|
7337
|
+
function createApplicationBuildForm(request, imageContexts) {
|
|
7338
|
+
const contextsByPartName = /* @__PURE__ */ new Map();
|
|
7339
|
+
for (const context of imageContexts) {
|
|
7340
|
+
if (contextsByPartName.has(context.contextTarPartName)) {
|
|
7341
|
+
throw new Error(
|
|
7342
|
+
`duplicate image context part name '${context.contextTarPartName}'`
|
|
7343
|
+
);
|
|
7344
|
+
}
|
|
7345
|
+
contextsByPartName.set(context.contextTarPartName, context);
|
|
7346
|
+
}
|
|
7347
|
+
const form = new FormData();
|
|
7348
|
+
form.append(
|
|
7349
|
+
"app_version",
|
|
7350
|
+
new Blob([JSON.stringify(request)], { type: "application/json" }),
|
|
7351
|
+
"app_version"
|
|
7352
|
+
);
|
|
7353
|
+
for (const image of request.images) {
|
|
7354
|
+
const context = contextsByPartName.get(image.contextTarPartName);
|
|
7355
|
+
if (!context) {
|
|
7356
|
+
throw new Error(
|
|
7357
|
+
`missing image context for part '${image.contextTarPartName}'`
|
|
7358
|
+
);
|
|
7359
|
+
}
|
|
7360
|
+
form.append(
|
|
7361
|
+
image.contextTarPartName,
|
|
7362
|
+
new Blob([toBlobPart(context.contextTarGz)]),
|
|
7363
|
+
`${image.contextTarPartName}.tar.gz`
|
|
7364
|
+
);
|
|
7365
|
+
}
|
|
7366
|
+
for (const context of imageContexts) {
|
|
7367
|
+
if (!request.images.some((image) => image.contextTarPartName === context.contextTarPartName)) {
|
|
7368
|
+
throw new Error(
|
|
7369
|
+
`unexpected image context for part '${context.contextTarPartName}'`
|
|
7370
|
+
);
|
|
7371
|
+
}
|
|
7372
|
+
}
|
|
7373
|
+
return form;
|
|
7374
|
+
}
|
|
7375
|
+
function trimTrailingSlashes2(value) {
|
|
7376
|
+
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
7377
|
+
}
|
|
7378
|
+
function toBlobPart(data) {
|
|
7379
|
+
if (typeof data === "string" || data instanceof Blob) {
|
|
7380
|
+
return data;
|
|
7381
|
+
}
|
|
7382
|
+
if (data instanceof Uint8Array) {
|
|
7383
|
+
return Uint8Array.from(data).buffer;
|
|
7384
|
+
}
|
|
7385
|
+
return data;
|
|
7386
|
+
}
|
|
7387
|
+
function toRequestBody(data) {
|
|
7388
|
+
return toBlobPart(data);
|
|
7389
|
+
}
|
|
7390
|
+
async function parseJsonResponse(response) {
|
|
7391
|
+
const text = await response.text();
|
|
7392
|
+
if (!text) {
|
|
7393
|
+
return void 0;
|
|
7394
|
+
}
|
|
7395
|
+
return JSON.parse(text);
|
|
7396
|
+
}
|
|
6936
7397
|
|
|
6937
7398
|
// src/api-client.ts
|
|
6938
7399
|
init_esm_shims();
|
|
6939
|
-
init_cloud_client();
|
|
6940
7400
|
|
|
6941
7401
|
// src/filesystem.ts
|
|
6942
7402
|
init_esm_shims();
|
|
@@ -6954,12 +7414,12 @@ import { promisify } from "util";
|
|
|
6954
7414
|
init_esm_shims();
|
|
6955
7415
|
var GIT_MODE_DIR = 16384;
|
|
6956
7416
|
var GIT_MODE_SYMLINK = 40960;
|
|
6957
|
-
function trimSlashes(
|
|
7417
|
+
function trimSlashes(path5) {
|
|
6958
7418
|
let start = 0;
|
|
6959
|
-
let end =
|
|
6960
|
-
while (start < end &&
|
|
6961
|
-
while (end > start &&
|
|
6962
|
-
return
|
|
7419
|
+
let end = path5.length;
|
|
7420
|
+
while (start < end && path5.charCodeAt(start) === 47) start += 1;
|
|
7421
|
+
while (end > start && path5.charCodeAt(end - 1) === 47) end -= 1;
|
|
7422
|
+
return path5.slice(start, end);
|
|
6963
7423
|
}
|
|
6964
7424
|
function fileEntryFromWire(entry, dirPath) {
|
|
6965
7425
|
const mode = entry.mode ?? 33188;
|
|
@@ -6977,9 +7437,9 @@ function fileEntryFromWire(entry, dirPath) {
|
|
|
6977
7437
|
}
|
|
6978
7438
|
function mountStatusFromRaw(raw, localPath) {
|
|
6979
7439
|
const mounted = "mounted" in raw ? Boolean(raw.mounted) : "active" in raw ? Boolean(raw.active) : true;
|
|
6980
|
-
const
|
|
7440
|
+
const path5 = String(raw.path || raw.mount_path || localPath || "");
|
|
6981
7441
|
const filesystem = raw.filesystem || raw.file_system || raw.repository || null;
|
|
6982
|
-
return { path:
|
|
7442
|
+
return { path: path5, filesystem, mounted, raw };
|
|
6983
7443
|
}
|
|
6984
7444
|
var FilesystemError = class extends Error {
|
|
6985
7445
|
constructor(message) {
|
|
@@ -6998,11 +7458,11 @@ var FilesystemNotFoundError = class extends FilesystemError {
|
|
|
6998
7458
|
var FileNotFoundInFilesystemError = class extends FilesystemError {
|
|
6999
7459
|
filesystem;
|
|
7000
7460
|
path;
|
|
7001
|
-
constructor(filesystem,
|
|
7002
|
-
super(`File not found in filesystem ${filesystem}: ${
|
|
7461
|
+
constructor(filesystem, path5) {
|
|
7462
|
+
super(`File not found in filesystem ${filesystem}: ${path5}`);
|
|
7003
7463
|
this.name = "FileNotFoundInFilesystemError";
|
|
7004
7464
|
this.filesystem = filesystem;
|
|
7005
|
-
this.path =
|
|
7465
|
+
this.path = path5;
|
|
7006
7466
|
}
|
|
7007
7467
|
};
|
|
7008
7468
|
var FilesystemAPIError = class extends FilesystemError {
|
|
@@ -7356,8 +7816,8 @@ var Filesystem = class {
|
|
|
7356
7816
|
}
|
|
7357
7817
|
// -- writes -------------------------------------------------------------------
|
|
7358
7818
|
/** Write one file. Returns the snapshot (version) the write produced. */
|
|
7359
|
-
async writeFile(
|
|
7360
|
-
return await this.writeFiles(/* @__PURE__ */ new Map([[
|
|
7819
|
+
async writeFile(path5, data, message) {
|
|
7820
|
+
return await this.writeFiles(/* @__PURE__ */ new Map([[path5, data]]), message);
|
|
7361
7821
|
}
|
|
7362
7822
|
/** Write several files (and/or delete paths) in one atomic snapshot. */
|
|
7363
7823
|
async writeFiles(files, message, deletes = []) {
|
|
@@ -7365,8 +7825,8 @@ var Filesystem = class {
|
|
|
7365
7825
|
if (entries.length === 0 && deletes.length === 0) {
|
|
7366
7826
|
throw new FilesystemError("nothing to write: no files or deletions given");
|
|
7367
7827
|
}
|
|
7368
|
-
const writes = entries.map(([
|
|
7369
|
-
path:
|
|
7828
|
+
const writes = entries.map(([path5, data]) => ({
|
|
7829
|
+
path: path5,
|
|
7370
7830
|
content: toBuffer(data)
|
|
7371
7831
|
}));
|
|
7372
7832
|
const resolvedMessage = message || `write ${writes.length} file(s) via SDK`;
|
|
@@ -7382,9 +7842,9 @@ var Filesystem = class {
|
|
|
7382
7842
|
* Stream one local file directly to object storage in bounded parts.
|
|
7383
7843
|
* This is the memory-bounded API for multi-GiB files.
|
|
7384
7844
|
*/
|
|
7385
|
-
async writeFileFromPath(
|
|
7845
|
+
async writeFileFromPath(path5, localPath, message) {
|
|
7386
7846
|
return await this.writeFilesFromPaths(
|
|
7387
|
-
/* @__PURE__ */ new Map([[
|
|
7847
|
+
/* @__PURE__ */ new Map([[path5, localPath]]),
|
|
7388
7848
|
message
|
|
7389
7849
|
);
|
|
7390
7850
|
}
|
|
@@ -7397,7 +7857,7 @@ var Filesystem = class {
|
|
|
7397
7857
|
if (entries.length === 0) {
|
|
7398
7858
|
throw new FilesystemError("nothing to write: no local files given");
|
|
7399
7859
|
}
|
|
7400
|
-
const writes = entries.map(([
|
|
7860
|
+
const writes = entries.map(([path5, localPath]) => ({ path: path5, localPath }));
|
|
7401
7861
|
const resolvedMessage = message || `write ${writes.length} local file(s) via SDK`;
|
|
7402
7862
|
const branch = await this.branch();
|
|
7403
7863
|
const traced = await callNative2(
|
|
@@ -7474,11 +7934,11 @@ var Filesystem = class {
|
|
|
7474
7934
|
};
|
|
7475
7935
|
}
|
|
7476
7936
|
/** Delete one file. Returns the durable version the deletion produced. */
|
|
7477
|
-
async deleteFile(
|
|
7937
|
+
async deleteFile(path5, message) {
|
|
7478
7938
|
return await this.writeFiles(
|
|
7479
7939
|
/* @__PURE__ */ new Map(),
|
|
7480
|
-
message || `delete ${
|
|
7481
|
-
[
|
|
7940
|
+
message || `delete ${path5} via SDK`,
|
|
7941
|
+
[path5]
|
|
7482
7942
|
);
|
|
7483
7943
|
}
|
|
7484
7944
|
/**
|
|
@@ -7529,15 +7989,15 @@ var Filesystem = class {
|
|
|
7529
7989
|
* Read a file's bytes at `version` (the current `main` head or a retained
|
|
7530
7990
|
* snapshot id; defaults to the filesystem's current head).
|
|
7531
7991
|
*/
|
|
7532
|
-
async readFile(
|
|
7533
|
-
return (await this.readFileWithMetadata(
|
|
7992
|
+
async readFile(path5, version) {
|
|
7993
|
+
return (await this.readFileWithMetadata(path5, { version })).data;
|
|
7534
7994
|
}
|
|
7535
7995
|
/**
|
|
7536
7996
|
* Read bytes and immutable metadata in one request. A range is executed by
|
|
7537
7997
|
* Artifact Storage, so callers never download the unrequested remainder.
|
|
7538
7998
|
*/
|
|
7539
|
-
async readFileWithMetadata(
|
|
7540
|
-
if (trimSlashes(
|
|
7999
|
+
async readFileWithMetadata(path5, options = {}) {
|
|
8000
|
+
if (trimSlashes(path5) === "") {
|
|
7541
8001
|
throw new FilesystemError("file path must not be empty");
|
|
7542
8002
|
}
|
|
7543
8003
|
const range = options.range;
|
|
@@ -7550,12 +8010,12 @@ var Filesystem = class {
|
|
|
7550
8010
|
const traced = await callNative2(
|
|
7551
8011
|
() => this.native.readFilesystemFile(
|
|
7552
8012
|
this.name,
|
|
7553
|
-
|
|
8013
|
+
path5,
|
|
7554
8014
|
resolvedVersion,
|
|
7555
8015
|
range?.offset,
|
|
7556
8016
|
range?.length
|
|
7557
8017
|
),
|
|
7558
|
-
new FileNotFoundInFilesystemError(this.name,
|
|
8018
|
+
new FileNotFoundInFilesystemError(this.name, path5)
|
|
7559
8019
|
);
|
|
7560
8020
|
const fullSize = traced.fullSize;
|
|
7561
8021
|
if (!traced.contentId || fullSize === void 0 || !Number.isSafeInteger(fullSize) || fullSize < 0 || traced.data.byteLength > fullSize) {
|
|
@@ -7570,9 +8030,9 @@ var Filesystem = class {
|
|
|
7570
8030
|
};
|
|
7571
8031
|
}
|
|
7572
8032
|
/** Read a file as UTF-8 text at `version`. Throws on non-UTF-8 content. */
|
|
7573
|
-
async readText(
|
|
8033
|
+
async readText(path5, version) {
|
|
7574
8034
|
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
|
7575
|
-
await this.readFile(
|
|
8035
|
+
await this.readFile(path5, version)
|
|
7576
8036
|
);
|
|
7577
8037
|
}
|
|
7578
8038
|
/** List one directory (non-recursive) at `version`. */
|
|
@@ -7635,11 +8095,11 @@ var FilesystemMount = class {
|
|
|
7635
8095
|
path;
|
|
7636
8096
|
readonly;
|
|
7637
8097
|
/** @internal — obtain instances via `FilesystemClient.mount()`. */
|
|
7638
|
-
constructor(client, cli, filesystem,
|
|
8098
|
+
constructor(client, cli, filesystem, path5, readonly) {
|
|
7639
8099
|
this.client = client;
|
|
7640
8100
|
this.cli = cli;
|
|
7641
8101
|
this.filesystem = filesystem;
|
|
7642
|
-
this.path =
|
|
8102
|
+
this.path = path5;
|
|
7643
8103
|
this.readonly = readonly;
|
|
7644
8104
|
}
|
|
7645
8105
|
/** Flush pending local changes into a durable snapshot. */
|
|
@@ -7657,6 +8117,7 @@ var FilesystemMount = class {
|
|
|
7657
8117
|
};
|
|
7658
8118
|
|
|
7659
8119
|
// src/api-client.ts
|
|
8120
|
+
init_sandbox_image();
|
|
7660
8121
|
init_errors();
|
|
7661
8122
|
var APIClient = class {
|
|
7662
8123
|
cloudClient;
|
|
@@ -7684,7 +8145,7 @@ var APIClient = class {
|
|
|
7684
8145
|
await this.cloudClient.deleteApplication(applicationName);
|
|
7685
8146
|
}
|
|
7686
8147
|
async deleteSandboxImage(imageName) {
|
|
7687
|
-
await this.
|
|
8148
|
+
await deleteSandboxImageWithCredentials(this.filesystemOptions, imageName);
|
|
7688
8149
|
}
|
|
7689
8150
|
async createFileSystem(name, description, options) {
|
|
7690
8151
|
const filesystem = await new FilesystemClient(this.filesystemOptions).create(
|
|
@@ -7771,14 +8232,14 @@ var GitCli = class extends MountCli {
|
|
|
7771
8232
|
if (options.readOnly && (options.publish || options.workspace !== void 0) || options.publish && options.workspace !== void 0) {
|
|
7772
8233
|
throw new TypeError("readOnly, publish, and workspace are mutually exclusive");
|
|
7773
8234
|
}
|
|
7774
|
-
const
|
|
8235
|
+
const path5 = resolve(localPath);
|
|
7775
8236
|
const args = ["mount"];
|
|
7776
8237
|
if (options.readOnly) args.push("--ro");
|
|
7777
8238
|
if (options.publish) args.push("--publish");
|
|
7778
8239
|
if (options.workspace !== void 0) args.push(`--workspace=${options.workspace}`);
|
|
7779
|
-
args.push("--", target,
|
|
8240
|
+
args.push("--", target, path5);
|
|
7780
8241
|
await this.run(args);
|
|
7781
|
-
return new RepositoryMount(this, target,
|
|
8242
|
+
return new RepositoryMount(this, target, path5, options.readOnly ?? false);
|
|
7782
8243
|
}
|
|
7783
8244
|
async unmount(localPath, options = {}) {
|
|
7784
8245
|
requireNonEmpty(localPath, "localPath");
|
|
@@ -7816,44 +8277,44 @@ var GitCli = class extends MountCli {
|
|
|
7816
8277
|
raw
|
|
7817
8278
|
};
|
|
7818
8279
|
}
|
|
7819
|
-
async snapshot(
|
|
8280
|
+
async snapshot(path5, message) {
|
|
7820
8281
|
const args = ["snapshot"];
|
|
7821
8282
|
if (message !== void 0) args.push(`--message=${message}`);
|
|
7822
|
-
args.push("--",
|
|
8283
|
+
args.push("--", path5);
|
|
7823
8284
|
await this.run(args);
|
|
7824
8285
|
}
|
|
7825
|
-
async sync(
|
|
7826
|
-
const args = ["sync", "--",
|
|
8286
|
+
async sync(path5, target) {
|
|
8287
|
+
const args = ["sync", "--", path5];
|
|
7827
8288
|
if (target !== void 0) {
|
|
7828
8289
|
requireNonEmpty(target, "target");
|
|
7829
8290
|
args.push(target);
|
|
7830
8291
|
}
|
|
7831
8292
|
await this.run(args);
|
|
7832
8293
|
}
|
|
7833
|
-
async rebase(
|
|
8294
|
+
async rebase(path5, target, failOnConflict) {
|
|
7834
8295
|
requireNonEmpty(target, "target");
|
|
7835
8296
|
const args = ["rebase"];
|
|
7836
8297
|
if (failOnConflict) args.push("--fail-on-conflict");
|
|
7837
|
-
args.push("--",
|
|
8298
|
+
args.push("--", path5, target);
|
|
7838
8299
|
await this.run(args);
|
|
7839
8300
|
}
|
|
7840
|
-
async promote(
|
|
8301
|
+
async promote(path5, branch, merge) {
|
|
7841
8302
|
requireNonEmpty(branch, "branch");
|
|
7842
8303
|
const args = ["promote"];
|
|
7843
8304
|
if (merge) args.push("--merge");
|
|
7844
|
-
args.push("--",
|
|
8305
|
+
args.push("--", path5, branch);
|
|
7845
8306
|
await this.run(args);
|
|
7846
8307
|
}
|
|
7847
|
-
async prefetch(
|
|
7848
|
-
await this.run(["prefetch", "--",
|
|
8308
|
+
async prefetch(path5) {
|
|
8309
|
+
await this.run(["prefetch", "--", path5]);
|
|
7849
8310
|
}
|
|
7850
8311
|
};
|
|
7851
8312
|
var RepositoryMount = class {
|
|
7852
8313
|
/** @internal Obtain instances via RepositoryClient.mount(). */
|
|
7853
|
-
constructor(cli, target,
|
|
8314
|
+
constructor(cli, target, path5, readOnly) {
|
|
7854
8315
|
this.cli = cli;
|
|
7855
8316
|
this.target = target;
|
|
7856
|
-
this.path =
|
|
8317
|
+
this.path = path5;
|
|
7857
8318
|
this.readOnly = readOnly;
|
|
7858
8319
|
}
|
|
7859
8320
|
/** Inspect workspace state, pending changes, and daemon diagnostics. */
|
|
@@ -8088,6 +8549,7 @@ function validateTimeoutMs2(timeoutMs) {
|
|
|
8088
8549
|
|
|
8089
8550
|
// src/index.ts
|
|
8090
8551
|
init_sandbox_image();
|
|
8552
|
+
init_image_builds();
|
|
8091
8553
|
|
|
8092
8554
|
// src/file-system.ts
|
|
8093
8555
|
init_esm_shims();
|
|
@@ -9471,38 +9933,38 @@ init_esm_shims();
|
|
|
9471
9933
|
import { createHash } from "crypto";
|
|
9472
9934
|
var textEncoder = new TextEncoder();
|
|
9473
9935
|
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
9474
|
-
function assertJSONValue(value,
|
|
9936
|
+
function assertJSONValue(value, path5, seen) {
|
|
9475
9937
|
if (value === null || typeof value === "string" || typeof value === "boolean") return;
|
|
9476
9938
|
if (typeof value === "number") {
|
|
9477
|
-
if (!Number.isFinite(value)) throw new SerializationError(`${
|
|
9939
|
+
if (!Number.isFinite(value)) throw new SerializationError(`${path5} contains a non-finite number`);
|
|
9478
9940
|
return;
|
|
9479
9941
|
}
|
|
9480
9942
|
if (typeof value !== "object") {
|
|
9481
|
-
throw new SerializationError(`${
|
|
9943
|
+
throw new SerializationError(`${path5} contains unsupported ${typeof value}`);
|
|
9482
9944
|
}
|
|
9483
9945
|
if (isFile(value)) {
|
|
9484
|
-
throw new SerializationError(`${
|
|
9946
|
+
throw new SerializationError(`${path5} contains a nested File; File is only supported as a direct value`);
|
|
9485
9947
|
}
|
|
9486
9948
|
if (isHttpBody(value)) {
|
|
9487
9949
|
throw new SerializationError(
|
|
9488
|
-
`${
|
|
9950
|
+
`${path5} contains a nested HttpBody; HttpBody is only supported as a direct value`
|
|
9489
9951
|
);
|
|
9490
9952
|
}
|
|
9491
|
-
if (seen.has(value)) throw new SerializationError(`${
|
|
9953
|
+
if (seen.has(value)) throw new SerializationError(`${path5} contains a cycle`);
|
|
9492
9954
|
if (Object.getPrototypeOf(value) !== Object.prototype && !Array.isArray(value)) {
|
|
9493
|
-
throw new SerializationError(`${
|
|
9955
|
+
throw new SerializationError(`${path5} contains unsupported ${value.constructor?.name ?? "object"}`);
|
|
9494
9956
|
}
|
|
9495
9957
|
seen.add(value);
|
|
9496
9958
|
if (Array.isArray(value)) {
|
|
9497
9959
|
for (let index = 0; index < value.length; index += 1) {
|
|
9498
9960
|
if (!Object.prototype.hasOwnProperty.call(value, index)) {
|
|
9499
|
-
throw new SerializationError(`${
|
|
9961
|
+
throw new SerializationError(`${path5} contains a sparse array entry at index ${index}`);
|
|
9500
9962
|
}
|
|
9501
|
-
assertJSONValue(value[index], `${
|
|
9963
|
+
assertJSONValue(value[index], `${path5}[${index}]`, seen);
|
|
9502
9964
|
}
|
|
9503
9965
|
} else {
|
|
9504
9966
|
for (const [key, item] of Object.entries(value)) {
|
|
9505
|
-
assertJSONValue(item, `${
|
|
9967
|
+
assertJSONValue(item, `${path5}.${key}`, seen);
|
|
9506
9968
|
}
|
|
9507
9969
|
}
|
|
9508
9970
|
seen.delete(value);
|
|
@@ -9951,7 +10413,15 @@ export {
|
|
|
9951
10413
|
Headers,
|
|
9952
10414
|
HttpBody,
|
|
9953
10415
|
Image,
|
|
10416
|
+
ImageBuildCancelledError,
|
|
10417
|
+
ImageBuildError,
|
|
10418
|
+
ImageBuildFailedError,
|
|
10419
|
+
ImageBuildHandle,
|
|
10420
|
+
ImageBuildInProgressError,
|
|
10421
|
+
ImageBuildInterruptedError,
|
|
10422
|
+
ImageBuildNotFoundError,
|
|
9954
10423
|
ImageBuildOperationType,
|
|
10424
|
+
ImageBuildTimeoutError,
|
|
9955
10425
|
MountError,
|
|
9956
10426
|
OutputMode,
|
|
9957
10427
|
PendingSandbox,
|
|
@@ -9984,12 +10454,14 @@ export {
|
|
|
9984
10454
|
TERMINATION_REASON_CANCELLED,
|
|
9985
10455
|
TERMINATION_REASON_NO_CAPACITY,
|
|
9986
10456
|
TcpTunnel,
|
|
10457
|
+
cancelImageBuild,
|
|
9987
10458
|
createFileSystem,
|
|
9988
10459
|
createSandboxImage,
|
|
9989
10460
|
deleteFileSystem,
|
|
9990
10461
|
deleteSandboxImage,
|
|
9991
10462
|
dockerfileContent,
|
|
9992
10463
|
findSandboxImageByName,
|
|
10464
|
+
getImageBuild,
|
|
9993
10465
|
importSandboxImage,
|
|
9994
10466
|
isSandboxPending,
|
|
9995
10467
|
listFileSystems,
|
|
@@ -10001,6 +10473,9 @@ export {
|
|
|
10001
10473
|
runLocal,
|
|
10002
10474
|
runRemote,
|
|
10003
10475
|
sandboxUrlFromIngressEndpoint,
|
|
10004
|
-
schema
|
|
10476
|
+
schema,
|
|
10477
|
+
startImageBuild,
|
|
10478
|
+
startImageImport,
|
|
10479
|
+
waitImageBuild
|
|
10005
10480
|
};
|
|
10006
10481
|
//# sourceMappingURL=index.js.map
|