@tensorlakeai/tensorlake 0.5.151 → 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/README.md +8 -0
- package/dist/applications/index.cjs +3510 -3384
- 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 +3286 -3160
- package/dist/applications/index.js.map +1 -1
- package/dist/function-agent/main.cjs +1 -1
- package/dist/function-agent/main.cjs.map +1 -1
- package/dist/function-agent/main.js +1 -1
- package/dist/function-agent/main.js.map +1 -1
- package/dist/function-executor/main.cjs +2 -2
- package/dist/function-executor/main.cjs.map +1 -1
- package/dist/function-executor/main.js +2 -2
- package/dist/function-executor/main.js.map +1 -1
- package/dist/index.cjs +1424 -1079
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +313 -27
- package/dist/index.d.ts +313 -27
- package/dist/index.js +1401 -1069
- 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 -1295
- 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 -1294
- package/dist/sandbox-image.js.map +1 -1
- package/package.json +8 -7
- package/runtime/function-executor/manifest.json +7 -7
- package/runtime/function-executor/package/dist/function-executor/main.js +2 -2
- package/runtime/function-executor/package/dist/function-executor/main.js.map +1 -1
- 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 +7 -7
- package/runtime/typescript-function-runner/package/dist/function-agent/main.js +1 -1
- package/runtime/typescript-function-runner/package/dist/function-agent/main.js.map +1 -1
- package/runtime/typescript-function-runner/package/npm-shrinkwrap.json +26 -26
- package/runtime/typescript-function-runner/package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -49,7 +49,7 @@ var init_defaults = __esm({
|
|
|
49
49
|
"src/defaults.ts"() {
|
|
50
50
|
"use strict";
|
|
51
51
|
init_cjs_shims();
|
|
52
|
-
SDK_VERSION = "0.5.
|
|
52
|
+
SDK_VERSION = "0.5.153";
|
|
53
53
|
API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
|
|
54
54
|
API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
|
|
55
55
|
NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
|
|
@@ -314,6 +314,11 @@ function createWorkerBinding(runtime) {
|
|
|
314
314
|
return runtime.handle("NativeRepositoryClient", args);
|
|
315
315
|
}
|
|
316
316
|
},
|
|
317
|
+
NativeTcpTunnel: class {
|
|
318
|
+
constructor() {
|
|
319
|
+
return runtime.handle("NativeTcpTunnel", []);
|
|
320
|
+
}
|
|
321
|
+
},
|
|
317
322
|
validateManagedName: (name) => runtime.call(void 0, "validateManagedName", [name])
|
|
318
323
|
};
|
|
319
324
|
}
|
|
@@ -493,7 +498,7 @@ var init_native_worker_client = __esm({
|
|
|
493
498
|
}
|
|
494
499
|
};
|
|
495
500
|
runtimeKey = /* @__PURE__ */ Symbol.for(
|
|
496
|
-
`tensorlake.native.worker.${false ? "source" : "0.5.
|
|
501
|
+
`tensorlake.native.worker.${false ? "source" : "0.5.153"}.v1`
|
|
497
502
|
);
|
|
498
503
|
runtimes = globalThis;
|
|
499
504
|
}
|
|
@@ -593,6 +598,8 @@ var init_models = __esm({
|
|
|
593
598
|
SnapshotStatus2["LOCAL_READY"] = "local_ready";
|
|
594
599
|
SnapshotStatus2["COMPLETED"] = "completed";
|
|
595
600
|
SnapshotStatus2["FAILED"] = "failed";
|
|
601
|
+
SnapshotStatus2["DELETING"] = "deleting";
|
|
602
|
+
SnapshotStatus2["REPLICATING"] = "replicating";
|
|
596
603
|
return SnapshotStatus2;
|
|
597
604
|
})(SnapshotStatus || {});
|
|
598
605
|
ProcessStatus = /* @__PURE__ */ ((ProcessStatus2) => {
|
|
@@ -941,116 +948,6 @@ function normalizeWebSocketData(message) {
|
|
|
941
948
|
}
|
|
942
949
|
return Buffer.from(message);
|
|
943
950
|
}
|
|
944
|
-
async function relaySocket(localSocket, websocket) {
|
|
945
|
-
return new Promise((resolve2) => {
|
|
946
|
-
let settled = false;
|
|
947
|
-
const keepAliveInterval = setInterval(() => {
|
|
948
|
-
if (websocket.readyState === import_ws.default.OPEN) {
|
|
949
|
-
websocket.ping();
|
|
950
|
-
}
|
|
951
|
-
}, WEBSOCKET_KEEPALIVE_INTERVAL_MS);
|
|
952
|
-
keepAliveInterval.unref?.();
|
|
953
|
-
const finish = () => {
|
|
954
|
-
if (settled) return;
|
|
955
|
-
settled = true;
|
|
956
|
-
clearInterval(keepAliveInterval);
|
|
957
|
-
cleanup();
|
|
958
|
-
resolve2();
|
|
959
|
-
};
|
|
960
|
-
const cleanup = () => {
|
|
961
|
-
localSocket.removeListener("data", onLocalData);
|
|
962
|
-
localSocket.removeListener("end", onLocalEnd);
|
|
963
|
-
localSocket.removeListener("close", onLocalClose);
|
|
964
|
-
localSocket.removeListener("error", onLocalError);
|
|
965
|
-
websocket.removeListener("message", onWsMessage);
|
|
966
|
-
websocket.removeListener("close", onWsClose);
|
|
967
|
-
websocket.removeListener("error", onWsError);
|
|
968
|
-
websocket.removeListener("ping", onWsPing);
|
|
969
|
-
};
|
|
970
|
-
const onLocalData = (chunk) => {
|
|
971
|
-
if (websocket.readyState !== import_ws.default.OPEN) {
|
|
972
|
-
localSocket.destroy();
|
|
973
|
-
return;
|
|
974
|
-
}
|
|
975
|
-
websocket.send(chunk, { binary: true }, (error) => {
|
|
976
|
-
if (error) {
|
|
977
|
-
localSocket.destroy(error);
|
|
978
|
-
}
|
|
979
|
-
});
|
|
980
|
-
};
|
|
981
|
-
const onLocalEnd = () => {
|
|
982
|
-
if (websocket.readyState === import_ws.default.OPEN) {
|
|
983
|
-
websocket.close();
|
|
984
|
-
}
|
|
985
|
-
};
|
|
986
|
-
const onLocalClose = () => {
|
|
987
|
-
if (websocket.readyState === import_ws.default.OPEN || websocket.readyState === import_ws.default.CONNECTING) {
|
|
988
|
-
websocket.close();
|
|
989
|
-
}
|
|
990
|
-
finish();
|
|
991
|
-
};
|
|
992
|
-
const onLocalError = () => {
|
|
993
|
-
websocket.close();
|
|
994
|
-
finish();
|
|
995
|
-
};
|
|
996
|
-
const onWsMessage = (message, isBinary) => {
|
|
997
|
-
if (!isBinary) {
|
|
998
|
-
localSocket.destroy(
|
|
999
|
-
new SandboxError("received unexpected text frame from tunnel")
|
|
1000
|
-
);
|
|
1001
|
-
websocket.close();
|
|
1002
|
-
return;
|
|
1003
|
-
}
|
|
1004
|
-
const payload = normalizeWebSocketData(message);
|
|
1005
|
-
if (!localSocket.destroyed) {
|
|
1006
|
-
localSocket.write(payload);
|
|
1007
|
-
}
|
|
1008
|
-
};
|
|
1009
|
-
const onWsClose = () => {
|
|
1010
|
-
if (!localSocket.destroyed) {
|
|
1011
|
-
localSocket.end();
|
|
1012
|
-
}
|
|
1013
|
-
finish();
|
|
1014
|
-
};
|
|
1015
|
-
const onWsError = (error) => {
|
|
1016
|
-
localSocket.destroy(error);
|
|
1017
|
-
finish();
|
|
1018
|
-
};
|
|
1019
|
-
const onWsPing = (data) => {
|
|
1020
|
-
if (websocket.readyState === import_ws.default.OPEN) {
|
|
1021
|
-
websocket.pong(data, false, () => {
|
|
1022
|
-
});
|
|
1023
|
-
}
|
|
1024
|
-
};
|
|
1025
|
-
localSocket.on("data", onLocalData);
|
|
1026
|
-
localSocket.on("end", onLocalEnd);
|
|
1027
|
-
localSocket.on("close", onLocalClose);
|
|
1028
|
-
localSocket.on("error", onLocalError);
|
|
1029
|
-
websocket.on("message", onWsMessage);
|
|
1030
|
-
websocket.on("close", onWsClose);
|
|
1031
|
-
websocket.on("error", onWsError);
|
|
1032
|
-
websocket.on("ping", onWsPing);
|
|
1033
|
-
});
|
|
1034
|
-
}
|
|
1035
|
-
async function listenServer(server, localPort, localHost) {
|
|
1036
|
-
await new Promise((resolve2, reject) => {
|
|
1037
|
-
const onError = (error) => {
|
|
1038
|
-
server.removeListener("listening", onListening);
|
|
1039
|
-
reject(
|
|
1040
|
-
new SandboxError(
|
|
1041
|
-
`failed to bind local tunnel listener on ${localHost}:${localPort}: ${error.message}`
|
|
1042
|
-
)
|
|
1043
|
-
);
|
|
1044
|
-
};
|
|
1045
|
-
const onListening = () => {
|
|
1046
|
-
server.removeListener("error", onError);
|
|
1047
|
-
resolve2();
|
|
1048
|
-
};
|
|
1049
|
-
server.once("error", onError);
|
|
1050
|
-
server.once("listening", onListening);
|
|
1051
|
-
server.listen(localPort, localHost);
|
|
1052
|
-
});
|
|
1053
|
-
}
|
|
1054
951
|
function validatePort(port, label, allowZero = false) {
|
|
1055
952
|
if (!Number.isInteger(port)) {
|
|
1056
953
|
throw new SandboxError(`${label} must be an integer, got ${port}`);
|
|
@@ -1083,14 +980,15 @@ async function withTimeout(timeoutMs, operation, timeoutMessage) {
|
|
|
1083
980
|
});
|
|
1084
981
|
});
|
|
1085
982
|
}
|
|
1086
|
-
var
|
|
983
|
+
var import_ws, DEFAULT_TUNNEL_CONNECT_TIMEOUT_MS, WEBSOCKET_KEEPALIVE_INTERVAL_MS, TunnelByteStream, TcpTunnel;
|
|
1087
984
|
var init_tunnel = __esm({
|
|
1088
985
|
"src/tunnel.ts"() {
|
|
1089
986
|
"use strict";
|
|
1090
987
|
init_cjs_shims();
|
|
1091
|
-
net = __toESM(require("net"), 1);
|
|
1092
988
|
init_errors();
|
|
1093
989
|
import_ws = __toESM(require("ws"), 1);
|
|
990
|
+
init_native_sandbox();
|
|
991
|
+
init_native_worker_client();
|
|
1094
992
|
DEFAULT_TUNNEL_CONNECT_TIMEOUT_MS = 1e4;
|
|
1095
993
|
WEBSOCKET_KEEPALIVE_INTERVAL_MS = 15e3;
|
|
1096
994
|
TunnelByteStream = class _TunnelByteStream {
|
|
@@ -1220,24 +1118,17 @@ var init_tunnel = __esm({
|
|
|
1220
1118
|
}
|
|
1221
1119
|
};
|
|
1222
1120
|
TcpTunnel = class _TcpTunnel {
|
|
1223
|
-
remotePort
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
closePromise = null;
|
|
1232
|
-
constructor(options) {
|
|
1233
|
-
this.baseUrl = options.baseUrl;
|
|
1234
|
-
this.wsHeaders = options.wsHeaders;
|
|
1235
|
-
this.remotePort = options.remotePort;
|
|
1236
|
-
this.localHost = options.localHost;
|
|
1237
|
-
this.localPort = options.localPort;
|
|
1238
|
-
this.server = options.server;
|
|
1239
|
-
this.connectTimeoutMs = options.connectTimeoutMs;
|
|
1121
|
+
constructor(native, remotePort, localHost, localPort) {
|
|
1122
|
+
this.native = native;
|
|
1123
|
+
this.remotePort = remotePort;
|
|
1124
|
+
this.localHost = localHost;
|
|
1125
|
+
this.localPort = localPort;
|
|
1126
|
+
this.lifetime = native.waitClosed();
|
|
1127
|
+
void this.lifetime.catch(() => {
|
|
1128
|
+
});
|
|
1240
1129
|
}
|
|
1130
|
+
closePromise = null;
|
|
1131
|
+
lifetime;
|
|
1241
1132
|
static async listen(options) {
|
|
1242
1133
|
const remotePort = validatePort(options.remotePort, "remote port");
|
|
1243
1134
|
const localHost = options.localHost ?? "127.0.0.1";
|
|
@@ -1246,69 +1137,37 @@ var init_tunnel = __esm({
|
|
|
1246
1137
|
"local port",
|
|
1247
1138
|
true
|
|
1248
1139
|
);
|
|
1249
|
-
const
|
|
1250
|
-
const
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
void tunnel.handleConnection(localSocket);
|
|
1268
|
-
});
|
|
1269
|
-
return tunnel;
|
|
1140
|
+
const timeout = secondsToMillis(options.connectTimeout ?? 10) / 1e3;
|
|
1141
|
+
const native = new (loadNativeSandboxBinding()).NativeTcpTunnel();
|
|
1142
|
+
try {
|
|
1143
|
+
const port = await callNative(
|
|
1144
|
+
() => native.listen(
|
|
1145
|
+
options.baseUrl,
|
|
1146
|
+
options.wsHeaders,
|
|
1147
|
+
remotePort,
|
|
1148
|
+
localHost,
|
|
1149
|
+
localPort,
|
|
1150
|
+
timeout
|
|
1151
|
+
)
|
|
1152
|
+
);
|
|
1153
|
+
return new _TcpTunnel(native, remotePort, localHost, port);
|
|
1154
|
+
} catch (error) {
|
|
1155
|
+
releaseNativeHandle(native);
|
|
1156
|
+
throw error;
|
|
1157
|
+
}
|
|
1270
1158
|
}
|
|
1271
1159
|
address() {
|
|
1272
1160
|
return { host: this.localHost, port: this.localPort };
|
|
1273
1161
|
}
|
|
1274
1162
|
async close() {
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
this.server.close((error) => {
|
|
1284
|
-
if (error) {
|
|
1285
|
-
reject(new SandboxError(`failed to close tunnel listener: ${error.message}`));
|
|
1286
|
-
return;
|
|
1287
|
-
}
|
|
1288
|
-
resolve2();
|
|
1289
|
-
});
|
|
1290
|
-
});
|
|
1291
|
-
return this.closePromise;
|
|
1292
|
-
}
|
|
1293
|
-
async handleConnection(localSocket) {
|
|
1294
|
-
localSocket.setNoDelay(true);
|
|
1295
|
-
const relay = { localSocket, websocket: null };
|
|
1296
|
-
this.activeRelays.add(relay);
|
|
1297
|
-
try {
|
|
1298
|
-
relay.websocket = await openTunnelWebSocket({
|
|
1299
|
-
baseUrl: this.baseUrl,
|
|
1300
|
-
wsHeaders: this.wsHeaders,
|
|
1301
|
-
remotePort: this.remotePort,
|
|
1302
|
-
connectTimeoutMs: this.connectTimeoutMs
|
|
1303
|
-
});
|
|
1304
|
-
await relaySocket(localSocket, relay.websocket);
|
|
1305
|
-
} catch (error) {
|
|
1306
|
-
localSocket.destroy(
|
|
1307
|
-
error instanceof Error ? error : new Error(String(error))
|
|
1308
|
-
);
|
|
1309
|
-
} finally {
|
|
1310
|
-
this.activeRelays.delete(relay);
|
|
1311
|
-
}
|
|
1163
|
+
return this.closePromise ??= (async () => {
|
|
1164
|
+
try {
|
|
1165
|
+
await callNative(() => this.native.close());
|
|
1166
|
+
await this.lifetime;
|
|
1167
|
+
} finally {
|
|
1168
|
+
releaseNativeHandle(this.native);
|
|
1169
|
+
}
|
|
1170
|
+
})();
|
|
1312
1171
|
}
|
|
1313
1172
|
};
|
|
1314
1173
|
}
|
|
@@ -4029,9 +3888,8 @@ var init_sandbox = __esm({
|
|
|
4029
3888
|
*
|
|
4030
3889
|
* Resource targets use create's cpus, memoryMb, and diskMb names. Resize
|
|
4031
3890
|
* waits by default; wait=false returns admission. Timeout does not cancel it.
|
|
4032
|
-
*
|
|
4033
|
-
*
|
|
4034
|
-
* Non-CAS sandboxes do not support live resize.
|
|
3891
|
+
* Which runtimes and dimensions support a live resize is decided by the
|
|
3892
|
+
* server, whose policy error is thrown unchanged.
|
|
4035
3893
|
* Wait, timeout, and pollInterval are ignored on non-resource updates.
|
|
4036
3894
|
* A no-op returns current resources with absent or earlier resize metadata.
|
|
4037
3895
|
*
|
|
@@ -4449,29 +4307,29 @@ var init_sandbox = __esm({
|
|
|
4449
4307
|
}
|
|
4450
4308
|
// --- File operations ---
|
|
4451
4309
|
/** Read a file from the sandbox and return its raw bytes. */
|
|
4452
|
-
async readFile(
|
|
4310
|
+
async readFile(path4) {
|
|
4453
4311
|
const proxy = await this.proxy.client();
|
|
4454
|
-
const { traceId, data } = await callNative(() => proxy.readFile(
|
|
4312
|
+
const { traceId, data } = await callNative(() => proxy.readFile(path4), {
|
|
4455
4313
|
sandboxId: this.sandboxId
|
|
4456
4314
|
});
|
|
4457
4315
|
return Object.assign(Uint8Array.from(data), { traceId });
|
|
4458
4316
|
}
|
|
4459
4317
|
/** Write raw bytes to a file in the sandbox, creating it if it does not exist. */
|
|
4460
|
-
async writeFile(
|
|
4318
|
+
async writeFile(path4, content) {
|
|
4461
4319
|
const proxy = await this.proxy.client();
|
|
4462
|
-
await callNative(() => proxy.writeFile(
|
|
4320
|
+
await callNative(() => proxy.writeFile(path4, Buffer.from(content)), {
|
|
4463
4321
|
sandboxId: this.sandboxId
|
|
4464
4322
|
});
|
|
4465
4323
|
}
|
|
4466
4324
|
/** Delete a file from the sandbox. */
|
|
4467
|
-
async deleteFile(
|
|
4325
|
+
async deleteFile(path4) {
|
|
4468
4326
|
const proxy = await this.proxy.client();
|
|
4469
|
-
await callNative(() => proxy.deleteFile(
|
|
4327
|
+
await callNative(() => proxy.deleteFile(path4), { sandboxId: this.sandboxId });
|
|
4470
4328
|
}
|
|
4471
4329
|
/** List the contents of a directory in the sandbox. */
|
|
4472
|
-
async listDirectory(
|
|
4330
|
+
async listDirectory(path4) {
|
|
4473
4331
|
const proxy = await this.proxy.client();
|
|
4474
|
-
const { traceId, json } = await callNative(() => proxy.listDirectory(
|
|
4332
|
+
const { traceId, json } = await callNative(() => proxy.listDirectory(path4), {
|
|
4475
4333
|
sandboxId: this.sandboxId
|
|
4476
4334
|
});
|
|
4477
4335
|
return Object.assign(fromSnakeKeys(JSON.parse(json)), {
|
|
@@ -5137,9 +4995,9 @@ var init_client = __esm({
|
|
|
5137
4995
|
});
|
|
5138
4996
|
}
|
|
5139
4997
|
/**
|
|
5140
|
-
* Update properties or resize a running sandbox.
|
|
5141
|
-
*
|
|
5142
|
-
*
|
|
4998
|
+
* Update properties or resize a running sandbox. Which runtimes and
|
|
4999
|
+
* dimensions support a live resize is decided by the server, whose policy
|
|
5000
|
+
* error is thrown unchanged.
|
|
5143
5001
|
* Resource names match create. Resize waits by default; wait=false returns
|
|
5144
5002
|
* admission. Timeout leaves the resize running and reports its generation.
|
|
5145
5003
|
* Wait, timeout, and pollInterval are ignored on non-resource updates.
|
|
@@ -5458,6 +5316,11 @@ var init_client = __esm({
|
|
|
5458
5316
|
`Snapshot ${result.snapshotId} failed: ${info.error}`
|
|
5459
5317
|
);
|
|
5460
5318
|
}
|
|
5319
|
+
if (info.status === "deleting" /* DELETING */) {
|
|
5320
|
+
throw new SandboxError(
|
|
5321
|
+
`Snapshot ${result.snapshotId} is being deleted`
|
|
5322
|
+
);
|
|
5323
|
+
}
|
|
5461
5324
|
await sleep2(pollInterval * 1e3);
|
|
5462
5325
|
}
|
|
5463
5326
|
throw new SandboxError(
|
|
@@ -5715,705 +5578,126 @@ var init_client = __esm({
|
|
|
5715
5578
|
}
|
|
5716
5579
|
});
|
|
5717
5580
|
|
|
5718
|
-
// src/
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
if (!Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) {
|
|
5725
|
-
headers["Content-Type"] = "application/json";
|
|
5726
|
-
}
|
|
5727
|
-
}
|
|
5728
|
-
const request = {
|
|
5729
|
-
method,
|
|
5730
|
-
path: path3,
|
|
5731
|
-
headersJson: JSON.stringify(headers),
|
|
5732
|
-
statusOnlyCodes: [...options?.statusOnlyCodes ?? []]
|
|
5581
|
+
// src/image.ts
|
|
5582
|
+
function cloneOperation(op) {
|
|
5583
|
+
return {
|
|
5584
|
+
type: op.type,
|
|
5585
|
+
args: [...op.args],
|
|
5586
|
+
options: { ...op.options }
|
|
5733
5587
|
};
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
} else if (body !== void 0) {
|
|
5740
|
-
if (body instanceof Blob) request.body = Buffer.from(await body.arrayBuffer());
|
|
5741
|
-
else if (typeof body === "string") request.body = Buffer.from(body);
|
|
5742
|
-
else if (body instanceof ArrayBuffer) request.body = Buffer.from(new Uint8Array(body));
|
|
5743
|
-
else request.body = Buffer.from(body);
|
|
5588
|
+
}
|
|
5589
|
+
function renderOptions(options) {
|
|
5590
|
+
const entries = Object.entries(options);
|
|
5591
|
+
if (entries.length === 0) {
|
|
5592
|
+
return "";
|
|
5744
5593
|
}
|
|
5745
|
-
return
|
|
5594
|
+
return ` ${entries.map(([key, value]) => `--${key}=${value}`).join(" ")}`;
|
|
5595
|
+
}
|
|
5596
|
+
function renderBuildOp(op) {
|
|
5597
|
+
const options = renderOptions(op.options);
|
|
5598
|
+
if (op.type === ImageBuildOperationType.ENV) {
|
|
5599
|
+
return `ENV${options} ${op.args[0]}=${JSON.stringify(op.args[1])}`;
|
|
5600
|
+
}
|
|
5601
|
+
return `${op.type}${options} ${op.args.join(" ")}`;
|
|
5602
|
+
}
|
|
5603
|
+
function dockerfileContent(image) {
|
|
5604
|
+
const lines = image.baseImage == null ? [] : [`FROM ${image.baseImage}`];
|
|
5605
|
+
lines.push(...image.buildOperations.map((op) => renderBuildOp(op)));
|
|
5606
|
+
return lines.join("\n");
|
|
5746
5607
|
}
|
|
5747
|
-
var
|
|
5748
|
-
var
|
|
5749
|
-
"src/
|
|
5608
|
+
var import_node_crypto, DEFAULT_IMAGE_NAME, ImageBuildOperationType, Image;
|
|
5609
|
+
var init_image = __esm({
|
|
5610
|
+
"src/image.ts"() {
|
|
5750
5611
|
"use strict";
|
|
5751
5612
|
init_cjs_shims();
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5613
|
+
import_node_crypto = require("crypto");
|
|
5614
|
+
DEFAULT_IMAGE_NAME = "default";
|
|
5615
|
+
ImageBuildOperationType = {
|
|
5616
|
+
ADD: "ADD",
|
|
5617
|
+
COPY: "COPY",
|
|
5618
|
+
ENV: "ENV",
|
|
5619
|
+
RUN: "RUN",
|
|
5620
|
+
WORKDIR: "WORKDIR"
|
|
5621
|
+
};
|
|
5622
|
+
Image = class {
|
|
5623
|
+
_id;
|
|
5624
|
+
_name;
|
|
5625
|
+
_tag;
|
|
5626
|
+
_baseImage;
|
|
5627
|
+
_buildOperations;
|
|
5628
|
+
constructor(nameOrOptions = {}, tag = "latest", baseImage = null) {
|
|
5629
|
+
this._id = (0, import_node_crypto.randomUUID)();
|
|
5630
|
+
this._buildOperations = [];
|
|
5631
|
+
if (typeof nameOrOptions === "string") {
|
|
5632
|
+
this._name = nameOrOptions;
|
|
5633
|
+
this._tag = tag;
|
|
5634
|
+
this._baseImage = baseImage;
|
|
5635
|
+
return;
|
|
5762
5636
|
}
|
|
5637
|
+
this._name = nameOrOptions.name ?? DEFAULT_IMAGE_NAME;
|
|
5638
|
+
this._tag = nameOrOptions.tag ?? "latest";
|
|
5639
|
+
this._baseImage = nameOrOptions.baseImage ?? null;
|
|
5763
5640
|
}
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
client() {
|
|
5767
|
-
if (this.closed) throw new Error("Tensorlake native client is closed");
|
|
5768
|
-
if (this.native) return this.native;
|
|
5769
|
-
const ctor = loadNativeSandboxBinding().NativeCloudClient;
|
|
5770
|
-
if (!ctor) throw new Error("Native binding does not export NativeCloudClient; rebuild with 'npm run build:native'");
|
|
5771
|
-
return this.native = new ctor(JSON.stringify(this.options));
|
|
5641
|
+
get name() {
|
|
5642
|
+
return this._name;
|
|
5772
5643
|
}
|
|
5773
|
-
|
|
5774
|
-
this.
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5644
|
+
get tag() {
|
|
5645
|
+
return this._tag;
|
|
5646
|
+
}
|
|
5647
|
+
get baseImage() {
|
|
5648
|
+
return this._baseImage;
|
|
5649
|
+
}
|
|
5650
|
+
get buildOperations() {
|
|
5651
|
+
return this._buildOperations.map(cloneOperation);
|
|
5652
|
+
}
|
|
5653
|
+
add(src, dest, options = void 0) {
|
|
5654
|
+
return this._addOperation({
|
|
5655
|
+
type: ImageBuildOperationType.ADD,
|
|
5656
|
+
args: [src, dest],
|
|
5657
|
+
options: options == null ? {} : { ...options }
|
|
5658
|
+
});
|
|
5659
|
+
}
|
|
5660
|
+
copy(src, dest, options = void 0) {
|
|
5661
|
+
return this._addOperation({
|
|
5662
|
+
type: ImageBuildOperationType.COPY,
|
|
5663
|
+
args: [src, dest],
|
|
5664
|
+
options: options == null ? {} : { ...options }
|
|
5665
|
+
});
|
|
5666
|
+
}
|
|
5667
|
+
env(key, value) {
|
|
5668
|
+
return this._addOperation({
|
|
5669
|
+
type: ImageBuildOperationType.ENV,
|
|
5670
|
+
args: [key, value],
|
|
5671
|
+
options: {}
|
|
5672
|
+
});
|
|
5673
|
+
}
|
|
5674
|
+
run(commands, options = void 0) {
|
|
5675
|
+
return this._addOperation({
|
|
5676
|
+
type: ImageBuildOperationType.RUN,
|
|
5677
|
+
args: Array.isArray(commands) ? [...commands] : [commands],
|
|
5678
|
+
options: options == null ? {} : { ...options }
|
|
5679
|
+
});
|
|
5680
|
+
}
|
|
5681
|
+
workdir(directory) {
|
|
5682
|
+
return this._addOperation({
|
|
5683
|
+
type: ImageBuildOperationType.WORKDIR,
|
|
5684
|
+
args: [directory],
|
|
5685
|
+
options: {}
|
|
5686
|
+
});
|
|
5786
5687
|
}
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5688
|
+
/**
|
|
5689
|
+
* Build this image as a sandbox template and register it.
|
|
5690
|
+
*
|
|
5691
|
+
* Materializes the image in a build sandbox, snapshots the filesystem,
|
|
5692
|
+
* and registers the snapshot as a named sandbox template.
|
|
5693
|
+
*/
|
|
5694
|
+
async build(options = {}) {
|
|
5695
|
+
const { createSandboxImage: createSandboxImage2 } = await Promise.resolve().then(() => (init_sandbox_image(), sandbox_image_exports));
|
|
5696
|
+
return createSandboxImage2(this, options);
|
|
5792
5697
|
}
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
yield* nativeEventStream((emit) => this.client().stream(request, emit), void 0, signal);
|
|
5797
|
-
}
|
|
5798
|
-
};
|
|
5799
|
-
}
|
|
5800
|
-
});
|
|
5801
|
-
|
|
5802
|
-
// src/cloud-client.ts
|
|
5803
|
-
function secretFromMetadata(metadata) {
|
|
5804
|
-
return {
|
|
5805
|
-
id: metadata.id,
|
|
5806
|
-
name: metadata.name,
|
|
5807
|
-
createdAt: new Date(metadata.created_at_ms)
|
|
5808
|
-
};
|
|
5809
|
-
}
|
|
5810
|
-
function applicationAllowsUnauthenticatedRequests(manifest) {
|
|
5811
|
-
return Array.isArray(manifest.allow) && manifest.allow.includes(UNAUTHENTICATED_REQUESTS);
|
|
5812
|
-
}
|
|
5813
|
-
function publicEndpointIdFromManifest(manifest) {
|
|
5814
|
-
for (const key of ["public_endpoint_id", "publicEndpointId"]) {
|
|
5815
|
-
const value = manifest[key];
|
|
5816
|
-
if (typeof value === "string" && value.length > 0) {
|
|
5817
|
-
return value;
|
|
5818
|
-
}
|
|
5819
|
-
}
|
|
5820
|
-
return void 0;
|
|
5821
|
-
}
|
|
5822
|
-
function generatePublicEndpointId() {
|
|
5823
|
-
return `endpoint_${(0, import_nanoid.nanoid)()}`;
|
|
5824
|
-
}
|
|
5825
|
-
function createApplicationBuildForm(request, imageContexts) {
|
|
5826
|
-
const contextsByPartName = /* @__PURE__ */ new Map();
|
|
5827
|
-
for (const context of imageContexts) {
|
|
5828
|
-
if (contextsByPartName.has(context.contextTarPartName)) {
|
|
5829
|
-
throw new Error(
|
|
5830
|
-
`duplicate image context part name '${context.contextTarPartName}'`
|
|
5831
|
-
);
|
|
5832
|
-
}
|
|
5833
|
-
contextsByPartName.set(context.contextTarPartName, context);
|
|
5834
|
-
}
|
|
5835
|
-
const form = new FormData();
|
|
5836
|
-
form.append(
|
|
5837
|
-
"app_version",
|
|
5838
|
-
new Blob([JSON.stringify(request)], { type: "application/json" }),
|
|
5839
|
-
"app_version"
|
|
5840
|
-
);
|
|
5841
|
-
for (const image of request.images) {
|
|
5842
|
-
const context = contextsByPartName.get(image.contextTarPartName);
|
|
5843
|
-
if (!context) {
|
|
5844
|
-
throw new Error(
|
|
5845
|
-
`missing image context for part '${image.contextTarPartName}'`
|
|
5846
|
-
);
|
|
5847
|
-
}
|
|
5848
|
-
form.append(
|
|
5849
|
-
image.contextTarPartName,
|
|
5850
|
-
new Blob([toBlobPart(context.contextTarGz)]),
|
|
5851
|
-
`${image.contextTarPartName}.tar.gz`
|
|
5852
|
-
);
|
|
5853
|
-
}
|
|
5854
|
-
for (const context of imageContexts) {
|
|
5855
|
-
if (!request.images.some((image) => image.contextTarPartName === context.contextTarPartName)) {
|
|
5856
|
-
throw new Error(
|
|
5857
|
-
`unexpected image context for part '${context.contextTarPartName}'`
|
|
5858
|
-
);
|
|
5859
|
-
}
|
|
5860
|
-
}
|
|
5861
|
-
return form;
|
|
5862
|
-
}
|
|
5863
|
-
function trimTrailingSlashes2(value) {
|
|
5864
|
-
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
5865
|
-
}
|
|
5866
|
-
function nextRequestPath(next) {
|
|
5867
|
-
const schemeIndex = next.indexOf("://");
|
|
5868
|
-
if (schemeIndex !== -1) {
|
|
5869
|
-
const afterScheme = next.slice(schemeIndex + 3);
|
|
5870
|
-
const slashIndex = afterScheme.indexOf("/");
|
|
5871
|
-
return slashIndex === -1 ? "/" : afterScheme.slice(slashIndex);
|
|
5872
|
-
}
|
|
5873
|
-
return next.startsWith("/") ? next : `/${next}`;
|
|
5874
|
-
}
|
|
5875
|
-
function toBlobPart(data) {
|
|
5876
|
-
if (typeof data === "string" || data instanceof Blob) {
|
|
5877
|
-
return data;
|
|
5878
|
-
}
|
|
5879
|
-
if (data instanceof Uint8Array) {
|
|
5880
|
-
return Uint8Array.from(data).buffer;
|
|
5881
|
-
}
|
|
5882
|
-
return data;
|
|
5883
|
-
}
|
|
5884
|
-
function toRequestBody(data) {
|
|
5885
|
-
return toBlobPart(data);
|
|
5886
|
-
}
|
|
5887
|
-
async function parseJsonResponse(response) {
|
|
5888
|
-
const text = await response.text();
|
|
5889
|
-
if (!text) {
|
|
5890
|
-
return void 0;
|
|
5891
|
-
}
|
|
5892
|
-
return JSON.parse(text);
|
|
5893
|
-
}
|
|
5894
|
-
var import_nanoid, CloudClient, UNAUTHENTICATED_REQUESTS;
|
|
5895
|
-
var init_cloud_client = __esm({
|
|
5896
|
-
"src/cloud-client.ts"() {
|
|
5897
|
-
"use strict";
|
|
5898
|
-
init_cjs_shims();
|
|
5899
|
-
import_nanoid = require("nanoid");
|
|
5900
|
-
init_defaults();
|
|
5901
|
-
init_native_cloud();
|
|
5902
|
-
init_models();
|
|
5903
|
-
CloudClient = class _CloudClient {
|
|
5904
|
-
transport;
|
|
5905
|
-
organizationId;
|
|
5906
|
-
projectId;
|
|
5907
|
-
namespace;
|
|
5908
|
-
constructor(options) {
|
|
5909
|
-
this.organizationId = options?.organizationId;
|
|
5910
|
-
this.projectId = options?.projectId;
|
|
5911
|
-
this.namespace = options?.namespace ?? NAMESPACE;
|
|
5912
|
-
this.transport = new NativeCloudTransport({
|
|
5913
|
-
baseUrl: options?.apiUrl ?? API_URL,
|
|
5914
|
-
apiKey: options?.apiKey ?? API_KEY,
|
|
5915
|
-
organizationId: this.organizationId,
|
|
5916
|
-
projectId: this.projectId,
|
|
5917
|
-
maxRetries: options?.maxRetries ?? MAX_RETRIES,
|
|
5918
|
-
retryBackoffMs: options?.retryBackoffMs ?? RETRY_BACKOFF_MS,
|
|
5919
|
-
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
5920
|
-
userAgent: `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
5921
|
-
});
|
|
5922
|
-
}
|
|
5923
|
-
static forCloud(options) {
|
|
5924
|
-
return new _CloudClient(options);
|
|
5925
|
-
}
|
|
5926
|
-
close() {
|
|
5927
|
-
this.transport.close();
|
|
5928
|
-
}
|
|
5929
|
-
async upsertApplication(manifest, codeZip, upgradeRunningRequests = false) {
|
|
5930
|
-
const applicationManifest = { ...manifest };
|
|
5931
|
-
let publicEndpointId = publicEndpointIdFromManifest(applicationManifest);
|
|
5932
|
-
if (applicationAllowsUnauthenticatedRequests(applicationManifest) && publicEndpointId === void 0) {
|
|
5933
|
-
const applicationName = applicationManifest.name;
|
|
5934
|
-
if (typeof applicationName === "string" && applicationName.length > 0) {
|
|
5935
|
-
publicEndpointId = await this.existingApplicationPublicEndpointId(applicationName);
|
|
5936
|
-
}
|
|
5937
|
-
publicEndpointId ??= generatePublicEndpointId();
|
|
5938
|
-
}
|
|
5939
|
-
if (publicEndpointId !== void 0) {
|
|
5940
|
-
applicationManifest.public_endpoint_id = publicEndpointId;
|
|
5941
|
-
delete applicationManifest.publicEndpointId;
|
|
5942
|
-
}
|
|
5943
|
-
const form = new FormData();
|
|
5944
|
-
form.append(
|
|
5945
|
-
"code",
|
|
5946
|
-
new Blob([toBlobPart(codeZip)], { type: "application/zip" }),
|
|
5947
|
-
"code.zip"
|
|
5948
|
-
);
|
|
5949
|
-
form.append("code_content_type", "application/zip");
|
|
5950
|
-
form.append("application", JSON.stringify(applicationManifest));
|
|
5951
|
-
form.append(
|
|
5952
|
-
"upgrade_requests_to_latest_code",
|
|
5953
|
-
String(upgradeRunningRequests)
|
|
5954
|
-
);
|
|
5955
|
-
await this.transport.requestResponse("POST", this.namespacePath("applications"), {
|
|
5956
|
-
body: form
|
|
5957
|
-
});
|
|
5958
|
-
}
|
|
5959
|
-
async deleteApplication(applicationName) {
|
|
5960
|
-
await this.transport.requestResponse(
|
|
5961
|
-
"DELETE",
|
|
5962
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
5963
|
-
);
|
|
5964
|
-
}
|
|
5965
|
-
async deleteSandboxImage(imageName) {
|
|
5966
|
-
await this.transport.requestResponse(
|
|
5967
|
-
"DELETE",
|
|
5968
|
-
this.namespacePath(`sandbox-images/${encodeURIComponent(imageName)}`)
|
|
5969
|
-
);
|
|
5970
|
-
}
|
|
5971
|
-
/**
|
|
5972
|
-
* Look up a registered sandbox image (template) by its registered name.
|
|
5973
|
-
*
|
|
5974
|
-
* Returns the template, or `null` when no image with that name exists.
|
|
5975
|
-
* API-key clients may omit organization/project IDs and use the
|
|
5976
|
-
* token-scoped Platform API route directly. Explicit scope remains
|
|
5977
|
-
* available for PAT callers.
|
|
5978
|
-
*/
|
|
5979
|
-
async findSandboxImageByName(imageName, options) {
|
|
5980
|
-
const base = this.platformProjectPath(
|
|
5981
|
-
"sandbox-templates",
|
|
5982
|
-
options?.organizationId,
|
|
5983
|
-
options?.projectId
|
|
5984
|
-
);
|
|
5985
|
-
const response = await this.transport.requestResponse(
|
|
5986
|
-
"GET",
|
|
5987
|
-
`${base}/by-name/${encodeURIComponent(imageName)}`,
|
|
5988
|
-
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
5989
|
-
);
|
|
5990
|
-
if (response.status === 404) {
|
|
5991
|
-
return null;
|
|
5992
|
-
}
|
|
5993
|
-
const raw = await parseJsonResponse(response);
|
|
5994
|
-
return fromSnakeKeys(raw);
|
|
5995
|
-
}
|
|
5996
|
-
/**
|
|
5997
|
-
* List all registered sandbox images (templates), following pagination to
|
|
5998
|
-
* the end. API-key clients may omit organization/project IDs and use the
|
|
5999
|
-
* token-scoped Platform API route directly.
|
|
6000
|
-
*/
|
|
6001
|
-
async listSandboxImages(options) {
|
|
6002
|
-
const base = this.platformProjectPath(
|
|
6003
|
-
"sandbox-templates",
|
|
6004
|
-
options?.organizationId,
|
|
6005
|
-
options?.projectId
|
|
6006
|
-
);
|
|
6007
|
-
let path3 = `${base}?pageSize=100`;
|
|
6008
|
-
const templates = [];
|
|
6009
|
-
while (path3 !== null) {
|
|
6010
|
-
const page = await this.transport.requestJson(
|
|
6011
|
-
"GET",
|
|
6012
|
-
path3
|
|
6013
|
-
);
|
|
6014
|
-
for (const item of page.items ?? []) {
|
|
6015
|
-
templates.push(fromSnakeKeys(item));
|
|
6016
|
-
}
|
|
6017
|
-
const next = page.pagination?.next;
|
|
6018
|
-
path3 = next ? nextRequestPath(next) : null;
|
|
6019
|
-
}
|
|
6020
|
-
return templates;
|
|
6021
|
-
}
|
|
6022
|
-
async applications() {
|
|
6023
|
-
const raw = await this.transport.requestJson(
|
|
6024
|
-
"GET",
|
|
6025
|
-
this.namespacePath("applications")
|
|
6026
|
-
);
|
|
6027
|
-
return (raw.applications ?? []).map(
|
|
6028
|
-
(application) => fromSnakeKeys(application)
|
|
6029
|
-
);
|
|
6030
|
-
}
|
|
6031
|
-
async applicationManifest(applicationName) {
|
|
6032
|
-
const raw = await this.transport.requestJson(
|
|
6033
|
-
"GET",
|
|
6034
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
6035
|
-
);
|
|
6036
|
-
return fromSnakeKeys(raw);
|
|
6037
|
-
}
|
|
6038
|
-
async runRequest(applicationName, inputs = []) {
|
|
6039
|
-
const path3 = this.namespacePath(
|
|
6040
|
-
`applications/${encodeURIComponent(applicationName)}`
|
|
6041
|
-
);
|
|
6042
|
-
const response = inputs.length === 0 ? await this.transport.requestResponse("POST", path3, {
|
|
6043
|
-
body: new Uint8Array(),
|
|
6044
|
-
headers: { Accept: "application/json" }
|
|
6045
|
-
}) : inputs.length === 1 && inputs[0].name === "0" ? await this.transport.requestResponse("POST", path3, {
|
|
6046
|
-
body: toRequestBody(inputs[0].data),
|
|
6047
|
-
headers: {
|
|
6048
|
-
Accept: "application/json",
|
|
6049
|
-
"Content-Type": inputs[0].contentType
|
|
6050
|
-
}
|
|
6051
|
-
}) : await this.runMultipartRequest(path3, inputs);
|
|
6052
|
-
const body = await parseJsonResponse(response);
|
|
6053
|
-
const requestId = body?.request_id;
|
|
6054
|
-
if (!requestId) {
|
|
6055
|
-
throw new Error("missing request_id in run request response body");
|
|
6056
|
-
}
|
|
6057
|
-
return requestId;
|
|
6058
|
-
}
|
|
6059
|
-
async waitOnRequestCompletion(applicationName, requestId) {
|
|
6060
|
-
const stream = this.transport.stream(
|
|
6061
|
-
"GET",
|
|
6062
|
-
this.namespacePath(
|
|
6063
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/progress`
|
|
6064
|
-
)
|
|
6065
|
-
);
|
|
6066
|
-
for await (const event of stream) {
|
|
6067
|
-
if (Object.prototype.hasOwnProperty.call(event, "RequestFinished")) {
|
|
6068
|
-
return;
|
|
6069
|
-
}
|
|
6070
|
-
}
|
|
6071
|
-
throw new Error("progress stream ended before request completion");
|
|
6072
|
-
}
|
|
6073
|
-
async requestMetadata(applicationName, requestId) {
|
|
6074
|
-
const raw = await this.transport.requestJson(
|
|
6075
|
-
"GET",
|
|
6076
|
-
this.namespacePath(
|
|
6077
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}`
|
|
6078
|
-
)
|
|
6079
|
-
);
|
|
6080
|
-
return fromSnakeKeys(raw);
|
|
6081
|
-
}
|
|
6082
|
-
async requestOutput(applicationName, requestId) {
|
|
6083
|
-
const response = await this.transport.requestResponse(
|
|
6084
|
-
"GET",
|
|
6085
|
-
this.namespacePath(
|
|
6086
|
-
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/output`
|
|
6087
|
-
)
|
|
6088
|
-
);
|
|
6089
|
-
const serializedValue = new Uint8Array(await response.arrayBuffer());
|
|
6090
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
6091
|
-
return {
|
|
6092
|
-
serializedValue,
|
|
6093
|
-
contentType
|
|
6094
|
-
};
|
|
6095
|
-
}
|
|
6096
|
-
async listSecrets(options) {
|
|
6097
|
-
const base = this.secretCollectionPath(
|
|
6098
|
-
options?.organizationId,
|
|
6099
|
-
options?.projectId
|
|
6100
|
-
);
|
|
6101
|
-
const raw = await this.transport.requestJson("GET", base);
|
|
6102
|
-
const pageSize = Math.max(0, options?.pageSize ?? 100);
|
|
6103
|
-
return Object.assign(
|
|
6104
|
-
{
|
|
6105
|
-
items: raw.slice(0, pageSize).map(secretFromMetadata),
|
|
6106
|
-
pagination: { total: raw.length }
|
|
6107
|
-
},
|
|
6108
|
-
{ traceId: raw.traceId }
|
|
6109
|
-
);
|
|
6110
|
-
}
|
|
6111
|
-
async getSecret(secretId, options) {
|
|
6112
|
-
const base = this.secretCollectionPath(
|
|
6113
|
-
options?.organizationId,
|
|
6114
|
-
options?.projectId
|
|
6115
|
-
);
|
|
6116
|
-
const raw = await this.transport.requestJson(
|
|
6117
|
-
"GET",
|
|
6118
|
-
`${base}/${encodeURIComponent(secretId)}`
|
|
6119
|
-
);
|
|
6120
|
-
return Object.assign(secretFromMetadata(raw), { traceId: raw.traceId });
|
|
6121
|
-
}
|
|
6122
|
-
async upsertSecrets(secrets, options) {
|
|
6123
|
-
const base = this.secretCollectionPath(
|
|
6124
|
-
options?.organizationId,
|
|
6125
|
-
options?.projectId
|
|
6126
|
-
);
|
|
6127
|
-
if (Array.isArray(secrets)) {
|
|
6128
|
-
const results = [];
|
|
6129
|
-
for (const secret of secrets) {
|
|
6130
|
-
results.push(await this.upsertSecret(base, secret));
|
|
6131
|
-
}
|
|
6132
|
-
return results;
|
|
6133
|
-
}
|
|
6134
|
-
return this.upsertSecret(base, secrets);
|
|
6135
|
-
}
|
|
6136
|
-
async deleteSecret(secretId, options) {
|
|
6137
|
-
const base = this.secretCollectionPath(
|
|
6138
|
-
options?.organizationId,
|
|
6139
|
-
options?.projectId
|
|
6140
|
-
);
|
|
6141
|
-
await this.transport.requestResponse(
|
|
6142
|
-
"DELETE",
|
|
6143
|
-
`${base}/${encodeURIComponent(secretId)}`
|
|
6144
|
-
);
|
|
6145
|
-
}
|
|
6146
|
-
async upsertSecret(base, secret) {
|
|
6147
|
-
let response = await this.transport.requestResponse("POST", base, {
|
|
6148
|
-
json: secret,
|
|
6149
|
-
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() },
|
|
6150
|
-
statusOnlyCodes: /* @__PURE__ */ new Set([409])
|
|
6151
|
-
});
|
|
6152
|
-
if (response.status === 409) {
|
|
6153
|
-
const prefix = base.slice(0, -"/secrets".length);
|
|
6154
|
-
const existing = await this.transport.requestJson(
|
|
6155
|
-
"GET",
|
|
6156
|
-
`${prefix}/secret-names/${encodeURIComponent(secret.name)}`
|
|
6157
|
-
);
|
|
6158
|
-
response = await this.transport.requestResponse(
|
|
6159
|
-
"POST",
|
|
6160
|
-
`${base}/${encodeURIComponent(existing.id)}/versions`,
|
|
6161
|
-
{
|
|
6162
|
-
json: { value: secret.value },
|
|
6163
|
-
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() }
|
|
6164
|
-
}
|
|
6165
|
-
);
|
|
6166
|
-
}
|
|
6167
|
-
const metadata = await parseJsonResponse(response);
|
|
6168
|
-
return Object.assign(secretFromMetadata(metadata), {
|
|
6169
|
-
traceId: response.traceId
|
|
6170
|
-
});
|
|
6171
|
-
}
|
|
6172
|
-
async startImageBuild(buildServicePath, request) {
|
|
6173
|
-
const form = new FormData();
|
|
6174
|
-
form.append("graph_name", request.applicationName);
|
|
6175
|
-
form.append("graph_version", request.applicationVersion);
|
|
6176
|
-
form.append("graph_function_name", request.functionName);
|
|
6177
|
-
form.append("image_name", request.imageName);
|
|
6178
|
-
form.append("image_id", request.imageId);
|
|
6179
|
-
form.append(
|
|
6180
|
-
"context",
|
|
6181
|
-
new Blob([toBlobPart(request.buildContext)]),
|
|
6182
|
-
"context.tar.gz"
|
|
6183
|
-
);
|
|
6184
|
-
const response = await this.transport.requestResponse(
|
|
6185
|
-
"PUT",
|
|
6186
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds`,
|
|
6187
|
-
{ body: form }
|
|
6188
|
-
);
|
|
6189
|
-
const raw = await parseJsonResponse(response);
|
|
6190
|
-
return fromSnakeKeys(raw);
|
|
6191
|
-
}
|
|
6192
|
-
async createApplicationBuild(buildServicePath, request, imageContexts) {
|
|
6193
|
-
const form = createApplicationBuildForm(request, imageContexts);
|
|
6194
|
-
const response = await this.transport.requestResponse(
|
|
6195
|
-
"POST",
|
|
6196
|
-
trimTrailingSlashes2(buildServicePath),
|
|
6197
|
-
{ body: form }
|
|
6198
|
-
);
|
|
6199
|
-
const raw = await parseJsonResponse(response);
|
|
6200
|
-
return fromSnakeKeys(raw);
|
|
6201
|
-
}
|
|
6202
|
-
async applicationBuildInfo(buildServicePath, applicationBuildId) {
|
|
6203
|
-
const raw = await this.transport.requestJson(
|
|
6204
|
-
"GET",
|
|
6205
|
-
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}`
|
|
6206
|
-
);
|
|
6207
|
-
return fromSnakeKeys(raw);
|
|
6208
|
-
}
|
|
6209
|
-
async cancelApplicationBuild(buildServicePath, applicationBuildId) {
|
|
6210
|
-
const raw = await this.transport.requestJson(
|
|
6211
|
-
"POST",
|
|
6212
|
-
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}/cancel`
|
|
6213
|
-
);
|
|
6214
|
-
return fromSnakeKeys(raw);
|
|
6215
|
-
}
|
|
6216
|
-
async buildInfo(buildServicePath, buildId) {
|
|
6217
|
-
const raw = await this.transport.requestJson(
|
|
6218
|
-
"GET",
|
|
6219
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}`
|
|
6220
|
-
);
|
|
6221
|
-
return fromSnakeKeys(raw);
|
|
6222
|
-
}
|
|
6223
|
-
async cancelBuild(buildServicePath, buildId) {
|
|
6224
|
-
await this.transport.requestResponse(
|
|
6225
|
-
"POST",
|
|
6226
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/cancel`
|
|
6227
|
-
);
|
|
6228
|
-
}
|
|
6229
|
-
async *streamBuildLogs(buildServicePath, buildId, signal) {
|
|
6230
|
-
const stream = this.transport.stream(
|
|
6231
|
-
"GET",
|
|
6232
|
-
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/logs`,
|
|
6233
|
-
signal
|
|
6234
|
-
);
|
|
6235
|
-
for await (const event of stream) {
|
|
6236
|
-
yield fromSnakeKeys(event);
|
|
6237
|
-
}
|
|
6238
|
-
}
|
|
6239
|
-
async runMultipartRequest(path3, inputs) {
|
|
6240
|
-
const form = new FormData();
|
|
6241
|
-
for (const input of inputs) {
|
|
6242
|
-
form.append(
|
|
6243
|
-
input.name,
|
|
6244
|
-
new Blob([toBlobPart(input.data)], { type: input.contentType }),
|
|
6245
|
-
input.name
|
|
6246
|
-
);
|
|
6247
|
-
}
|
|
6248
|
-
return this.transport.requestResponse("POST", path3, {
|
|
6249
|
-
body: form,
|
|
6250
|
-
headers: { Accept: "application/json" }
|
|
6251
|
-
});
|
|
6252
|
-
}
|
|
6253
|
-
namespacePath(subpath) {
|
|
6254
|
-
return `/v1/namespaces/${encodeURIComponent(this.namespace)}/${subpath.replace(/^\/+/, "")}`;
|
|
6255
|
-
}
|
|
6256
|
-
async existingApplicationPublicEndpointId(applicationName) {
|
|
6257
|
-
const response = await this.transport.requestResponse(
|
|
6258
|
-
"GET",
|
|
6259
|
-
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`),
|
|
6260
|
-
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
6261
|
-
);
|
|
6262
|
-
if (response.status === 404) {
|
|
6263
|
-
return void 0;
|
|
6264
|
-
}
|
|
6265
|
-
const application = await parseJsonResponse(response);
|
|
6266
|
-
return publicEndpointIdFromManifest(application);
|
|
6267
|
-
}
|
|
6268
|
-
platformProjectPath(resource, organizationId, projectId) {
|
|
6269
|
-
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
6270
|
-
const resolvedProjectId = projectId ?? this.projectId;
|
|
6271
|
-
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
6272
|
-
return `/platform/v1/${resource}`;
|
|
6273
|
-
}
|
|
6274
|
-
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
6275
|
-
throw new Error(
|
|
6276
|
-
"organizationId and projectId must be provided together"
|
|
6277
|
-
);
|
|
6278
|
-
}
|
|
6279
|
-
return `/platform/v1/organizations/${encodeURIComponent(resolvedOrganizationId)}/projects/${encodeURIComponent(resolvedProjectId)}/${resource}`;
|
|
6280
|
-
}
|
|
6281
|
-
secretCollectionPath(organizationId, projectId) {
|
|
6282
|
-
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
6283
|
-
const resolvedProjectId = projectId ?? this.projectId;
|
|
6284
|
-
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
6285
|
-
return this.namespacePath("secrets");
|
|
6286
|
-
}
|
|
6287
|
-
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
6288
|
-
throw new Error("organizationId and projectId must be provided together");
|
|
6289
|
-
}
|
|
6290
|
-
return this.namespacePath("secrets");
|
|
6291
|
-
}
|
|
6292
|
-
};
|
|
6293
|
-
UNAUTHENTICATED_REQUESTS = "unauthenticated_requests";
|
|
6294
|
-
}
|
|
6295
|
-
});
|
|
6296
|
-
|
|
6297
|
-
// src/image.ts
|
|
6298
|
-
function cloneOperation(op) {
|
|
6299
|
-
return {
|
|
6300
|
-
type: op.type,
|
|
6301
|
-
args: [...op.args],
|
|
6302
|
-
options: { ...op.options }
|
|
6303
|
-
};
|
|
6304
|
-
}
|
|
6305
|
-
function renderOptions(options) {
|
|
6306
|
-
const entries = Object.entries(options);
|
|
6307
|
-
if (entries.length === 0) {
|
|
6308
|
-
return "";
|
|
6309
|
-
}
|
|
6310
|
-
return ` ${entries.map(([key, value]) => `--${key}=${value}`).join(" ")}`;
|
|
6311
|
-
}
|
|
6312
|
-
function renderBuildOp(op) {
|
|
6313
|
-
const options = renderOptions(op.options);
|
|
6314
|
-
if (op.type === ImageBuildOperationType.ENV) {
|
|
6315
|
-
return `ENV${options} ${op.args[0]}=${JSON.stringify(op.args[1])}`;
|
|
6316
|
-
}
|
|
6317
|
-
return `${op.type}${options} ${op.args.join(" ")}`;
|
|
6318
|
-
}
|
|
6319
|
-
function dockerfileContent(image) {
|
|
6320
|
-
const lines = image.baseImage == null ? [] : [`FROM ${image.baseImage}`];
|
|
6321
|
-
lines.push(...image.buildOperations.map((op) => renderBuildOp(op)));
|
|
6322
|
-
return lines.join("\n");
|
|
6323
|
-
}
|
|
6324
|
-
var import_node_crypto, DEFAULT_IMAGE_NAME, ImageBuildOperationType, Image;
|
|
6325
|
-
var init_image = __esm({
|
|
6326
|
-
"src/image.ts"() {
|
|
6327
|
-
"use strict";
|
|
6328
|
-
init_cjs_shims();
|
|
6329
|
-
import_node_crypto = require("crypto");
|
|
6330
|
-
DEFAULT_IMAGE_NAME = "default";
|
|
6331
|
-
ImageBuildOperationType = {
|
|
6332
|
-
ADD: "ADD",
|
|
6333
|
-
COPY: "COPY",
|
|
6334
|
-
ENV: "ENV",
|
|
6335
|
-
RUN: "RUN",
|
|
6336
|
-
WORKDIR: "WORKDIR"
|
|
6337
|
-
};
|
|
6338
|
-
Image = class {
|
|
6339
|
-
_id;
|
|
6340
|
-
_name;
|
|
6341
|
-
_tag;
|
|
6342
|
-
_baseImage;
|
|
6343
|
-
_buildOperations;
|
|
6344
|
-
constructor(nameOrOptions = {}, tag = "latest", baseImage = null) {
|
|
6345
|
-
this._id = (0, import_node_crypto.randomUUID)();
|
|
6346
|
-
this._buildOperations = [];
|
|
6347
|
-
if (typeof nameOrOptions === "string") {
|
|
6348
|
-
this._name = nameOrOptions;
|
|
6349
|
-
this._tag = tag;
|
|
6350
|
-
this._baseImage = baseImage;
|
|
6351
|
-
return;
|
|
6352
|
-
}
|
|
6353
|
-
this._name = nameOrOptions.name ?? DEFAULT_IMAGE_NAME;
|
|
6354
|
-
this._tag = nameOrOptions.tag ?? "latest";
|
|
6355
|
-
this._baseImage = nameOrOptions.baseImage ?? null;
|
|
6356
|
-
}
|
|
6357
|
-
get name() {
|
|
6358
|
-
return this._name;
|
|
6359
|
-
}
|
|
6360
|
-
get tag() {
|
|
6361
|
-
return this._tag;
|
|
6362
|
-
}
|
|
6363
|
-
get baseImage() {
|
|
6364
|
-
return this._baseImage;
|
|
6365
|
-
}
|
|
6366
|
-
get buildOperations() {
|
|
6367
|
-
return this._buildOperations.map(cloneOperation);
|
|
6368
|
-
}
|
|
6369
|
-
add(src, dest, options = void 0) {
|
|
6370
|
-
return this._addOperation({
|
|
6371
|
-
type: ImageBuildOperationType.ADD,
|
|
6372
|
-
args: [src, dest],
|
|
6373
|
-
options: options == null ? {} : { ...options }
|
|
6374
|
-
});
|
|
6375
|
-
}
|
|
6376
|
-
copy(src, dest, options = void 0) {
|
|
6377
|
-
return this._addOperation({
|
|
6378
|
-
type: ImageBuildOperationType.COPY,
|
|
6379
|
-
args: [src, dest],
|
|
6380
|
-
options: options == null ? {} : { ...options }
|
|
6381
|
-
});
|
|
6382
|
-
}
|
|
6383
|
-
env(key, value) {
|
|
6384
|
-
return this._addOperation({
|
|
6385
|
-
type: ImageBuildOperationType.ENV,
|
|
6386
|
-
args: [key, value],
|
|
6387
|
-
options: {}
|
|
6388
|
-
});
|
|
6389
|
-
}
|
|
6390
|
-
run(commands, options = void 0) {
|
|
6391
|
-
return this._addOperation({
|
|
6392
|
-
type: ImageBuildOperationType.RUN,
|
|
6393
|
-
args: Array.isArray(commands) ? [...commands] : [commands],
|
|
6394
|
-
options: options == null ? {} : { ...options }
|
|
6395
|
-
});
|
|
6396
|
-
}
|
|
6397
|
-
workdir(directory) {
|
|
6398
|
-
return this._addOperation({
|
|
6399
|
-
type: ImageBuildOperationType.WORKDIR,
|
|
6400
|
-
args: [directory],
|
|
6401
|
-
options: {}
|
|
6402
|
-
});
|
|
6403
|
-
}
|
|
6404
|
-
/**
|
|
6405
|
-
* Build this image as a sandbox template and register it.
|
|
6406
|
-
*
|
|
6407
|
-
* Materializes the image in a build sandbox, snapshots the filesystem,
|
|
6408
|
-
* and registers the snapshot as a named sandbox template.
|
|
6409
|
-
*/
|
|
6410
|
-
async build(options = {}) {
|
|
6411
|
-
const { createSandboxImage: createSandboxImage2 } = await Promise.resolve().then(() => (init_sandbox_image(), sandbox_image_exports));
|
|
6412
|
-
return createSandboxImage2(this, options);
|
|
6413
|
-
}
|
|
6414
|
-
_addOperation(op) {
|
|
6415
|
-
this._buildOperations.push(op);
|
|
6416
|
-
return this;
|
|
5698
|
+
_addOperation(op) {
|
|
5699
|
+
this._buildOperations.push(op);
|
|
5700
|
+
return this;
|
|
6417
5701
|
}
|
|
6418
5702
|
};
|
|
6419
5703
|
}
|
|
@@ -6486,9 +5770,9 @@ var require_libc = __commonJS({
|
|
|
6486
5770
|
// src/native-binding.ts
|
|
6487
5771
|
function packageRoot() {
|
|
6488
5772
|
const parent = (0, import_node_url.fileURLToPath)(new URL("../", importMetaUrl));
|
|
6489
|
-
if (fs.existsSync(
|
|
5773
|
+
if (fs.existsSync(import_node_path.default.join(parent, "package.json"))) return parent;
|
|
6490
5774
|
const grandparent = (0, import_node_url.fileURLToPath)(new URL("../../", importMetaUrl));
|
|
6491
|
-
if (fs.existsSync(
|
|
5775
|
+
if (fs.existsSync(import_node_path.default.join(grandparent, "package.json"))) return grandparent;
|
|
6492
5776
|
return parent;
|
|
6493
5777
|
}
|
|
6494
5778
|
function linuxLibcFamily(options) {
|
|
@@ -6511,7 +5795,7 @@ function nativeTargetId(platform = process.platform, arch = process.arch, option
|
|
|
6511
5795
|
function nativeBindingPath(options = {}) {
|
|
6512
5796
|
const platform = options.platform ?? process.platform;
|
|
6513
5797
|
const arch = options.arch ?? process.arch;
|
|
6514
|
-
return
|
|
5798
|
+
return import_node_path.default.join(
|
|
6515
5799
|
options.packageRoot ?? packageRoot(),
|
|
6516
5800
|
"dist",
|
|
6517
5801
|
"native",
|
|
@@ -6544,7 +5828,7 @@ function loadNative() {
|
|
|
6544
5828
|
}
|
|
6545
5829
|
return require2(packageEntry);
|
|
6546
5830
|
}
|
|
6547
|
-
var import_libc, fs, import_node_module2,
|
|
5831
|
+
var import_libc, fs, import_node_module2, import_node_path, import_node_url, NATIVE_PACKAGES, cachedLinuxLibc;
|
|
6548
5832
|
var init_native_binding = __esm({
|
|
6549
5833
|
"src/native-binding.ts"() {
|
|
6550
5834
|
"use strict";
|
|
@@ -6552,7 +5836,7 @@ var init_native_binding = __esm({
|
|
|
6552
5836
|
import_libc = __toESM(require_libc(), 1);
|
|
6553
5837
|
fs = __toESM(require("fs"), 1);
|
|
6554
5838
|
import_node_module2 = require("module");
|
|
6555
|
-
|
|
5839
|
+
import_node_path = __toESM(require("path"), 1);
|
|
6556
5840
|
import_node_url = require("url");
|
|
6557
5841
|
NATIVE_PACKAGES = {
|
|
6558
5842
|
"darwin-arm64": "@tensorlakeai/native-darwin-arm64",
|
|
@@ -6565,16 +5849,471 @@ var init_native_binding = __esm({
|
|
|
6565
5849
|
}
|
|
6566
5850
|
});
|
|
6567
5851
|
|
|
5852
|
+
// src/image-builds.ts
|
|
5853
|
+
function camelize(key) {
|
|
5854
|
+
return key.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
5855
|
+
}
|
|
5856
|
+
function toImageBuildError(error) {
|
|
5857
|
+
if (!(error instanceof Error)) return error;
|
|
5858
|
+
let payload;
|
|
5859
|
+
try {
|
|
5860
|
+
payload = JSON.parse(error.message);
|
|
5861
|
+
} catch {
|
|
5862
|
+
return error;
|
|
5863
|
+
}
|
|
5864
|
+
if (!payload || payload.category !== "image_build") return error;
|
|
5865
|
+
const details = {};
|
|
5866
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
5867
|
+
if (key === "category") continue;
|
|
5868
|
+
details[camelize(key)] = value;
|
|
5869
|
+
}
|
|
5870
|
+
const typed = details;
|
|
5871
|
+
switch (typed.code) {
|
|
5872
|
+
case "not_found":
|
|
5873
|
+
return new ImageBuildNotFoundError(typed);
|
|
5874
|
+
case "image_build_in_progress":
|
|
5875
|
+
return new ImageBuildInProgressError(typed);
|
|
5876
|
+
case "failed":
|
|
5877
|
+
return new ImageBuildFailedError(typed);
|
|
5878
|
+
case "cancelled":
|
|
5879
|
+
return new ImageBuildCancelledError(typed);
|
|
5880
|
+
case "timeout":
|
|
5881
|
+
return new ImageBuildTimeoutError(typed);
|
|
5882
|
+
case "interrupted":
|
|
5883
|
+
return new ImageBuildInterruptedError(typed);
|
|
5884
|
+
default:
|
|
5885
|
+
return new ImageBuildError(typed);
|
|
5886
|
+
}
|
|
5887
|
+
}
|
|
5888
|
+
function camelizeRecord(value) {
|
|
5889
|
+
const out = {};
|
|
5890
|
+
for (const [key, inner] of Object.entries(value)) out[camelize(key)] = inner;
|
|
5891
|
+
return out;
|
|
5892
|
+
}
|
|
5893
|
+
function parseBuildInfo(raw) {
|
|
5894
|
+
const camel = camelizeRecord(raw);
|
|
5895
|
+
const result = raw.result && typeof raw.result === "object" ? camelizeRecord(raw.result) : null;
|
|
5896
|
+
return {
|
|
5897
|
+
buildId: String(raw.build_id ?? ""),
|
|
5898
|
+
clientRequestId: camel.clientRequestId ?? null,
|
|
5899
|
+
kind: String(raw.kind ?? ""),
|
|
5900
|
+
name: raw.name ?? null,
|
|
5901
|
+
status: String(raw.status ?? ""),
|
|
5902
|
+
phase: raw.phase ?? null,
|
|
5903
|
+
attemptNo: Number(raw.attempt_no ?? 0),
|
|
5904
|
+
builderSandboxId: camel.builderSandboxId ?? null,
|
|
5905
|
+
error: raw.error ?? null,
|
|
5906
|
+
result,
|
|
5907
|
+
operationDeadlineMs: camel.operationDeadlineMs ?? null,
|
|
5908
|
+
createdAtMs: camel.createdAtMs ?? null,
|
|
5909
|
+
updatedAtMs: camel.updatedAtMs ?? null,
|
|
5910
|
+
raw
|
|
5911
|
+
};
|
|
5912
|
+
}
|
|
5913
|
+
function parseResult(json) {
|
|
5914
|
+
return camelizeRecord(JSON.parse(json));
|
|
5915
|
+
}
|
|
5916
|
+
function credentialsFromEnv() {
|
|
5917
|
+
const context = __imageBuildInternals.buildContextFromEnv();
|
|
5918
|
+
if (!context.apiKey) {
|
|
5919
|
+
if (context.personalAccessToken) {
|
|
5920
|
+
throw new ImageBuildError({
|
|
5921
|
+
code: "auth",
|
|
5922
|
+
message: "Sandbox image SDKs require TENSORLAKE_API_KEY. Personal access tokens are CLI-only."
|
|
5923
|
+
});
|
|
5924
|
+
}
|
|
5925
|
+
throw new ImageBuildError({ code: "auth", message: "Missing TENSORLAKE_API_KEY credentials." });
|
|
5926
|
+
}
|
|
5927
|
+
return { apiUrl: context.apiUrl, bearerToken: context.apiKey, namespace: context.namespace };
|
|
5928
|
+
}
|
|
5929
|
+
function clientOptions(credentials) {
|
|
5930
|
+
return {
|
|
5931
|
+
apiUrl: credentials.apiUrl,
|
|
5932
|
+
bearerToken: credentials.bearerToken,
|
|
5933
|
+
namespace: credentials.namespace,
|
|
5934
|
+
useScopeHeaders: false
|
|
5935
|
+
};
|
|
5936
|
+
}
|
|
5937
|
+
function rejectLegacyReference(buildId) {
|
|
5938
|
+
if (typeof buildId !== "string" || buildId.trim().length === 0) {
|
|
5939
|
+
throw new ImageBuildError({ code: "usage", message: "buildId must be a non-empty string" });
|
|
5940
|
+
}
|
|
5941
|
+
if (buildId.startsWith("sandbox_template_")) {
|
|
5942
|
+
throw new ImageBuildError({
|
|
5943
|
+
code: "usage",
|
|
5944
|
+
message: `'${buildId}' is a legacy sandbox template id; legacy images have no build operation to get, wait for or cancel`,
|
|
5945
|
+
buildId
|
|
5946
|
+
});
|
|
5947
|
+
}
|
|
5948
|
+
if (buildId.startsWith("image_")) {
|
|
5949
|
+
throw new ImageBuildError({
|
|
5950
|
+
code: "usage",
|
|
5951
|
+
message: `'${buildId}' is an image id, not a build id; look the image up with findSandboxImageByName or use the build id admission returned`,
|
|
5952
|
+
buildId
|
|
5953
|
+
});
|
|
5954
|
+
}
|
|
5955
|
+
}
|
|
5956
|
+
async function __runWithInterrupt(signal, run) {
|
|
5957
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
5958
|
+
if (signal === void 0) {
|
|
5959
|
+
try {
|
|
5960
|
+
return await run(void 0);
|
|
5961
|
+
} catch (error) {
|
|
5962
|
+
throw toImageBuildError(error);
|
|
5963
|
+
}
|
|
5964
|
+
}
|
|
5965
|
+
const interruptId = binding.createImageBuildInterrupt();
|
|
5966
|
+
const onAbort = () => binding.triggerImageBuildInterrupt(interruptId);
|
|
5967
|
+
if (signal.aborted) onAbort();
|
|
5968
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
5969
|
+
try {
|
|
5970
|
+
return await run(interruptId);
|
|
5971
|
+
} catch (error) {
|
|
5972
|
+
throw toImageBuildError(error);
|
|
5973
|
+
} finally {
|
|
5974
|
+
signal.removeEventListener("abort", onAbort);
|
|
5975
|
+
binding.releaseImageBuildInterrupt(interruptId);
|
|
5976
|
+
}
|
|
5977
|
+
}
|
|
5978
|
+
function makeEmitter(options) {
|
|
5979
|
+
const emit = options.emit ?? (options.verbose ? __imageBuildInternals.stderrEmit : __imageBuildInternals.noopEmit);
|
|
5980
|
+
let emitError;
|
|
5981
|
+
const forward = (event) => {
|
|
5982
|
+
try {
|
|
5983
|
+
emit(__imageBuildInternals.eventToEmitDict(event));
|
|
5984
|
+
} catch (error) {
|
|
5985
|
+
emitError ??= error;
|
|
5986
|
+
}
|
|
5987
|
+
};
|
|
5988
|
+
return {
|
|
5989
|
+
forward,
|
|
5990
|
+
emit,
|
|
5991
|
+
rethrow() {
|
|
5992
|
+
if (emitError != null) throw emitError;
|
|
5993
|
+
}
|
|
5994
|
+
};
|
|
5995
|
+
}
|
|
5996
|
+
function decodeStarted(json, credentials) {
|
|
5997
|
+
const payload = JSON.parse(json);
|
|
5998
|
+
return new ImageBuildHandle(parseBuildInfo(payload.build ?? {}), credentials, payload.client_request_id);
|
|
5999
|
+
}
|
|
6000
|
+
async function startImageBuild(source, options = {}, deps = {}) {
|
|
6001
|
+
const emitter = makeEmitter({ emit: deps.emit ?? options.emit, verbose: options.verbose });
|
|
6002
|
+
let dockerfilePath;
|
|
6003
|
+
let dockerfileText;
|
|
6004
|
+
let contextDir;
|
|
6005
|
+
let name;
|
|
6006
|
+
let tempContextDir;
|
|
6007
|
+
if (source instanceof Image) {
|
|
6008
|
+
if (!source.baseImage) throw new Error("Image must have a baseImage to build");
|
|
6009
|
+
if (options.contextDir != null) {
|
|
6010
|
+
contextDir = import_node_path2.default.resolve(options.contextDir);
|
|
6011
|
+
} else if (__imageBuildInternals.imageRequiresContext(source)) {
|
|
6012
|
+
throw new Error(
|
|
6013
|
+
"This image reads files from the host (via COPY/ADD or a RUN bind mount), so it needs a build context. Pass `contextDir` pointing at the directory that contains those sources; they resolve relative to it, like `docker build <contextDir>`."
|
|
6014
|
+
);
|
|
6015
|
+
} else {
|
|
6016
|
+
tempContextDir = (0, import_node_fs.mkdtempSync)(import_node_path2.default.join(import_node_os.default.tmpdir(), "tl-build-context-"));
|
|
6017
|
+
contextDir = tempContextDir;
|
|
6018
|
+
}
|
|
6019
|
+
dockerfilePath = import_node_path2.default.join(contextDir, "Dockerfile");
|
|
6020
|
+
let text = dockerfileContent(source);
|
|
6021
|
+
if (!text.endsWith("\n")) text += "\n";
|
|
6022
|
+
dockerfileText = text;
|
|
6023
|
+
name = options.registeredName ?? source.name;
|
|
6024
|
+
} else if (typeof source === "string") {
|
|
6025
|
+
const resolved = import_node_path2.default.resolve(source);
|
|
6026
|
+
if (!(0, import_node_fs.existsSync)(resolved)) throw new Error(`Dockerfile not found: ${source}`);
|
|
6027
|
+
dockerfilePath = resolved;
|
|
6028
|
+
name = options.registeredName ?? __imageBuildInternals.defaultRegisteredName(resolved);
|
|
6029
|
+
} else {
|
|
6030
|
+
throw new TypeError(`source must be an Image or a Dockerfile path, got ${typeof source}`);
|
|
6031
|
+
}
|
|
6032
|
+
try {
|
|
6033
|
+
const credentials = credentialsFromEnv();
|
|
6034
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6035
|
+
emitter.emit({ type: "status", message: `Building image '${name}'...` });
|
|
6036
|
+
const json = await __runWithInterrupt(
|
|
6037
|
+
options.signal,
|
|
6038
|
+
(interruptId) => binding.startImageBuild(
|
|
6039
|
+
{
|
|
6040
|
+
apiUrl: credentials.apiUrl,
|
|
6041
|
+
bearerToken: credentials.bearerToken,
|
|
6042
|
+
dockerfilePath,
|
|
6043
|
+
registeredName: name,
|
|
6044
|
+
diskMb: options.diskMb,
|
|
6045
|
+
cpus: options.cpus,
|
|
6046
|
+
memoryMb: options.memoryMb,
|
|
6047
|
+
isPublic: options.isPublic ?? false,
|
|
6048
|
+
namespace: credentials.namespace,
|
|
6049
|
+
useScopeHeaders: false,
|
|
6050
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6051
|
+
dockerfileText,
|
|
6052
|
+
contextDir,
|
|
6053
|
+
cas: true,
|
|
6054
|
+
buildArgs: options.buildArgs
|
|
6055
|
+
},
|
|
6056
|
+
emitter.forward,
|
|
6057
|
+
interruptId
|
|
6058
|
+
)
|
|
6059
|
+
);
|
|
6060
|
+
emitter.rethrow();
|
|
6061
|
+
return decodeStarted(json, credentials);
|
|
6062
|
+
} finally {
|
|
6063
|
+
if (tempContextDir != null) (0, import_node_fs.rmSync)(tempContextDir, { recursive: true, force: true });
|
|
6064
|
+
}
|
|
6065
|
+
}
|
|
6066
|
+
async function startImageImport(imageReference, options = {}, deps = {}) {
|
|
6067
|
+
if (typeof imageReference !== "string" || imageReference.trim().length === 0) {
|
|
6068
|
+
throw new Error("image reference to import must not be empty");
|
|
6069
|
+
}
|
|
6070
|
+
const reference = imageReference.trim();
|
|
6071
|
+
const name = options.registeredName ?? __imageBuildInternals.defaultRegisteredNameFromImage(reference);
|
|
6072
|
+
const emitter = makeEmitter({ emit: deps.emit ?? options.emit, verbose: options.verbose });
|
|
6073
|
+
const credentials = credentialsFromEnv();
|
|
6074
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6075
|
+
emitter.emit({ type: "status", message: `Importing image '${reference}' as '${name}'...` });
|
|
6076
|
+
const json = await __runWithInterrupt(
|
|
6077
|
+
options.signal,
|
|
6078
|
+
(interruptId) => binding.startImageImport(
|
|
6079
|
+
{
|
|
6080
|
+
apiUrl: credentials.apiUrl,
|
|
6081
|
+
bearerToken: credentials.bearerToken,
|
|
6082
|
+
imageReference: reference,
|
|
6083
|
+
registeredName: name,
|
|
6084
|
+
diskMb: options.diskMb,
|
|
6085
|
+
cpus: options.cpus,
|
|
6086
|
+
memoryMb: options.memoryMb,
|
|
6087
|
+
isPublic: options.isPublic ?? false,
|
|
6088
|
+
namespace: credentials.namespace,
|
|
6089
|
+
useScopeHeaders: false,
|
|
6090
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6091
|
+
cas: true
|
|
6092
|
+
},
|
|
6093
|
+
emitter.forward,
|
|
6094
|
+
interruptId
|
|
6095
|
+
)
|
|
6096
|
+
);
|
|
6097
|
+
emitter.rethrow();
|
|
6098
|
+
return decodeStarted(json, credentials);
|
|
6099
|
+
}
|
|
6100
|
+
async function getImageBuild(buildId) {
|
|
6101
|
+
rejectLegacyReference(buildId);
|
|
6102
|
+
const credentials = credentialsFromEnv();
|
|
6103
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6104
|
+
let json;
|
|
6105
|
+
try {
|
|
6106
|
+
json = await binding.getImageBuild(clientOptions(credentials), buildId);
|
|
6107
|
+
} catch (error) {
|
|
6108
|
+
throw toImageBuildError(error);
|
|
6109
|
+
}
|
|
6110
|
+
return new ImageBuildHandle(parseBuildInfo(JSON.parse(json)), credentials);
|
|
6111
|
+
}
|
|
6112
|
+
async function waitImageBuild(buildId, options = {}) {
|
|
6113
|
+
rejectLegacyReference(buildId);
|
|
6114
|
+
const credentials = credentialsFromEnv();
|
|
6115
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6116
|
+
const emitter = makeEmitter(options);
|
|
6117
|
+
const json = await __runWithInterrupt(
|
|
6118
|
+
options.signal,
|
|
6119
|
+
(interruptId) => binding.waitImageBuild(
|
|
6120
|
+
clientOptions(credentials),
|
|
6121
|
+
buildId,
|
|
6122
|
+
{ timeoutMs: options.timeoutMs, followLogs: options.followLogs ?? false },
|
|
6123
|
+
emitter.forward,
|
|
6124
|
+
interruptId
|
|
6125
|
+
)
|
|
6126
|
+
);
|
|
6127
|
+
emitter.rethrow();
|
|
6128
|
+
return parseResult(json);
|
|
6129
|
+
}
|
|
6130
|
+
async function cancelImageBuildWith(credentials, selector) {
|
|
6131
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6132
|
+
let json;
|
|
6133
|
+
try {
|
|
6134
|
+
json = await binding.cancelImageBuild(clientOptions(credentials), {
|
|
6135
|
+
buildId: selector.buildId,
|
|
6136
|
+
clientRequestId: selector.clientRequestId
|
|
6137
|
+
});
|
|
6138
|
+
} catch (error) {
|
|
6139
|
+
throw toImageBuildError(error);
|
|
6140
|
+
}
|
|
6141
|
+
const payload = JSON.parse(json);
|
|
6142
|
+
const outcome = String(payload.outcome ?? "");
|
|
6143
|
+
return {
|
|
6144
|
+
outcome,
|
|
6145
|
+
build: payload.build ? parseBuildInfo(payload.build) : null,
|
|
6146
|
+
confirmed: ["cancelled", "already_cancelled", "already_failed"].includes(outcome)
|
|
6147
|
+
};
|
|
6148
|
+
}
|
|
6149
|
+
async function cancelImageBuild(selector) {
|
|
6150
|
+
const hasBuild = selector.buildId != null;
|
|
6151
|
+
const hasRequest = selector.clientRequestId != null;
|
|
6152
|
+
if (hasBuild === hasRequest) {
|
|
6153
|
+
throw new ImageBuildError({
|
|
6154
|
+
code: "usage",
|
|
6155
|
+
message: "pass exactly one of buildId or clientRequestId"
|
|
6156
|
+
});
|
|
6157
|
+
}
|
|
6158
|
+
if (selector.buildId != null) rejectLegacyReference(selector.buildId);
|
|
6159
|
+
return cancelImageBuildWith(credentialsFromEnv(), selector);
|
|
6160
|
+
}
|
|
6161
|
+
var import_node_path2, import_node_os, import_node_fs, ImageBuildError, ImageBuildNotFoundError, ImageBuildInProgressError, ImageBuildFailedError, ImageBuildCancelledError, ImageBuildTimeoutError, ImageBuildInterruptedError, ImageBuildHandle;
|
|
6162
|
+
var init_image_builds = __esm({
|
|
6163
|
+
"src/image-builds.ts"() {
|
|
6164
|
+
"use strict";
|
|
6165
|
+
init_cjs_shims();
|
|
6166
|
+
import_node_path2 = __toESM(require("path"), 1);
|
|
6167
|
+
import_node_os = __toESM(require("os"), 1);
|
|
6168
|
+
import_node_fs = require("fs");
|
|
6169
|
+
init_image();
|
|
6170
|
+
init_sandbox_image();
|
|
6171
|
+
ImageBuildError = class extends Error {
|
|
6172
|
+
code;
|
|
6173
|
+
buildId;
|
|
6174
|
+
clientRequestId;
|
|
6175
|
+
details;
|
|
6176
|
+
constructor(details) {
|
|
6177
|
+
super(details.message);
|
|
6178
|
+
this.name = "ImageBuildError";
|
|
6179
|
+
this.code = details.code;
|
|
6180
|
+
this.details = details;
|
|
6181
|
+
if (details.buildId) this.buildId = details.buildId;
|
|
6182
|
+
if (details.clientRequestId) this.clientRequestId = details.clientRequestId;
|
|
6183
|
+
}
|
|
6184
|
+
};
|
|
6185
|
+
ImageBuildNotFoundError = class extends ImageBuildError {
|
|
6186
|
+
constructor(details) {
|
|
6187
|
+
super(details);
|
|
6188
|
+
this.name = "ImageBuildNotFoundError";
|
|
6189
|
+
}
|
|
6190
|
+
};
|
|
6191
|
+
ImageBuildInProgressError = class extends ImageBuildError {
|
|
6192
|
+
imageName;
|
|
6193
|
+
activeBuildId;
|
|
6194
|
+
activeKind;
|
|
6195
|
+
activeStatus;
|
|
6196
|
+
constructor(details) {
|
|
6197
|
+
super(details);
|
|
6198
|
+
this.name = "ImageBuildInProgressError";
|
|
6199
|
+
if (details.imageName) this.imageName = details.imageName;
|
|
6200
|
+
if (details.activeBuildId) this.activeBuildId = details.activeBuildId;
|
|
6201
|
+
if (details.activeKind) this.activeKind = details.activeKind;
|
|
6202
|
+
if (details.activeStatus) this.activeStatus = details.activeStatus;
|
|
6203
|
+
}
|
|
6204
|
+
};
|
|
6205
|
+
ImageBuildFailedError = class extends ImageBuildError {
|
|
6206
|
+
error;
|
|
6207
|
+
info;
|
|
6208
|
+
constructor(details) {
|
|
6209
|
+
super(details);
|
|
6210
|
+
this.name = "ImageBuildFailedError";
|
|
6211
|
+
this.error = details.error ?? "no error recorded";
|
|
6212
|
+
if (details.info) this.info = parseBuildInfo(details.info);
|
|
6213
|
+
}
|
|
6214
|
+
};
|
|
6215
|
+
ImageBuildCancelledError = class extends ImageBuildError {
|
|
6216
|
+
info;
|
|
6217
|
+
constructor(details) {
|
|
6218
|
+
super(details);
|
|
6219
|
+
this.name = "ImageBuildCancelledError";
|
|
6220
|
+
if (details.info) this.info = parseBuildInfo(details.info);
|
|
6221
|
+
}
|
|
6222
|
+
};
|
|
6223
|
+
ImageBuildTimeoutError = class extends ImageBuildError {
|
|
6224
|
+
constructor(details) {
|
|
6225
|
+
super(details);
|
|
6226
|
+
this.name = "ImageBuildTimeoutError";
|
|
6227
|
+
}
|
|
6228
|
+
};
|
|
6229
|
+
ImageBuildInterruptedError = class extends ImageBuildError {
|
|
6230
|
+
outcome;
|
|
6231
|
+
confirmed;
|
|
6232
|
+
result;
|
|
6233
|
+
constructor(details) {
|
|
6234
|
+
super(details);
|
|
6235
|
+
this.name = "ImageBuildInterruptedError";
|
|
6236
|
+
this.outcome = details.outcome ?? "unconfirmed";
|
|
6237
|
+
this.confirmed = details.confirmed === true;
|
|
6238
|
+
if (details.result) this.result = details.result;
|
|
6239
|
+
}
|
|
6240
|
+
};
|
|
6241
|
+
ImageBuildHandle = class {
|
|
6242
|
+
buildId;
|
|
6243
|
+
/**
|
|
6244
|
+
* The admission's request id, when this handle started the build. Never
|
|
6245
|
+
* needed to cancel; a recovery aid for a lost admission answer.
|
|
6246
|
+
*/
|
|
6247
|
+
clientRequestId;
|
|
6248
|
+
#info;
|
|
6249
|
+
#credentials;
|
|
6250
|
+
/** @internal */
|
|
6251
|
+
constructor(info, credentials, clientRequestId) {
|
|
6252
|
+
this.buildId = info.buildId;
|
|
6253
|
+
this.clientRequestId = clientRequestId ?? info.clientRequestId ?? null;
|
|
6254
|
+
this.#info = info;
|
|
6255
|
+
this.#credentials = credentials;
|
|
6256
|
+
}
|
|
6257
|
+
/** The last observed state. */
|
|
6258
|
+
get info() {
|
|
6259
|
+
return this.#info;
|
|
6260
|
+
}
|
|
6261
|
+
/** Re-read the current state. */
|
|
6262
|
+
async refresh() {
|
|
6263
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6264
|
+
let json;
|
|
6265
|
+
try {
|
|
6266
|
+
json = await binding.getImageBuild(clientOptions(this.#credentials), this.buildId);
|
|
6267
|
+
} catch (error) {
|
|
6268
|
+
throw toImageBuildError(error);
|
|
6269
|
+
}
|
|
6270
|
+
this.#info = parseBuildInfo(JSON.parse(json));
|
|
6271
|
+
return this.#info;
|
|
6272
|
+
}
|
|
6273
|
+
/**
|
|
6274
|
+
* Wait for publication and return this build's immutable result. See
|
|
6275
|
+
* {@link ImageBuildWaitOptions} for the timeout/abort distinction.
|
|
6276
|
+
*/
|
|
6277
|
+
async wait(options = {}) {
|
|
6278
|
+
const binding = __imageBuildInternals.loadNativeBinding();
|
|
6279
|
+
const emitter = makeEmitter(options);
|
|
6280
|
+
const json = await __runWithInterrupt(
|
|
6281
|
+
options.signal,
|
|
6282
|
+
(interruptId) => binding.waitImageBuild(
|
|
6283
|
+
clientOptions(this.#credentials),
|
|
6284
|
+
this.buildId,
|
|
6285
|
+
{ timeoutMs: options.timeoutMs, followLogs: options.followLogs ?? false },
|
|
6286
|
+
emitter.forward,
|
|
6287
|
+
interruptId
|
|
6288
|
+
)
|
|
6289
|
+
);
|
|
6290
|
+
emitter.rethrow();
|
|
6291
|
+
const result = parseResult(json);
|
|
6292
|
+
this.#info = { ...this.#info, status: "succeeded", result };
|
|
6293
|
+
return result;
|
|
6294
|
+
}
|
|
6295
|
+
/** Cancel this build by its id (the sufficient selector). */
|
|
6296
|
+
async cancel() {
|
|
6297
|
+
return cancelImageBuildWith(this.#credentials, { buildId: this.buildId });
|
|
6298
|
+
}
|
|
6299
|
+
};
|
|
6300
|
+
}
|
|
6301
|
+
});
|
|
6302
|
+
|
|
6568
6303
|
// src/sandbox-image.ts
|
|
6569
6304
|
var sandbox_image_exports = {};
|
|
6570
6305
|
__export(sandbox_image_exports, {
|
|
6306
|
+
__imageBuildInternals: () => __imageBuildInternals,
|
|
6571
6307
|
__setNativeBindingForTest: () => __setNativeBindingForTest,
|
|
6572
6308
|
buildContextFromEnv: () => buildContextFromEnv,
|
|
6573
6309
|
createSandboxImage: () => createSandboxImage,
|
|
6574
6310
|
deleteSandboxImage: () => deleteSandboxImage,
|
|
6311
|
+
deleteSandboxImageWithCredentials: () => deleteSandboxImageWithCredentials,
|
|
6575
6312
|
findSandboxImageByName: () => findSandboxImageByName,
|
|
6313
|
+
findSandboxImageByNameWithCredentials: () => findSandboxImageByNameWithCredentials,
|
|
6576
6314
|
importSandboxImage: () => importSandboxImage,
|
|
6577
6315
|
listSandboxImages: () => listSandboxImages,
|
|
6316
|
+
listSandboxImagesWithCredentials: () => listSandboxImagesWithCredentials,
|
|
6578
6317
|
runCreateSandboxImageCli: () => runCreateSandboxImageCli,
|
|
6579
6318
|
runImportSandboxImageCli: () => runImportSandboxImageCli
|
|
6580
6319
|
});
|
|
@@ -6648,6 +6387,15 @@ function eventToEmitDict(event) {
|
|
|
6648
6387
|
message: event.message
|
|
6649
6388
|
};
|
|
6650
6389
|
if (event.stream != null) out.stream = event.stream;
|
|
6390
|
+
if (event.buildId != null) out.build_id = event.buildId;
|
|
6391
|
+
if (event.clientRequestId !== void 0 && event.eventType !== "status") {
|
|
6392
|
+
out.client_request_id = event.clientRequestId;
|
|
6393
|
+
}
|
|
6394
|
+
if (event.status != null) out.status = event.status;
|
|
6395
|
+
if (event.phase !== void 0 && event.eventType.startsWith("build_")) out.phase = event.phase;
|
|
6396
|
+
if (event.attempt != null) out.attempt = event.attempt;
|
|
6397
|
+
if (event.outcome != null) out.outcome = event.outcome;
|
|
6398
|
+
if (event.confirmed != null) out.confirmed = event.confirmed;
|
|
6651
6399
|
return out;
|
|
6652
6400
|
}
|
|
6653
6401
|
function runOpMountsContext(op) {
|
|
@@ -6749,38 +6497,47 @@ async function createSandboxImage(source, options = {}, deps = {}) {
|
|
|
6749
6497
|
deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
|
|
6750
6498
|
);
|
|
6751
6499
|
}
|
|
6500
|
+
if (options.signal !== void 0 && !options.cas) {
|
|
6501
|
+
throw new Error(
|
|
6502
|
+
"signal is only supported for CAS image builds (cas: true); a legacy build has no Image Service build operation to cancel"
|
|
6503
|
+
);
|
|
6504
|
+
}
|
|
6752
6505
|
emit({ type: "status", message: `Building image '${effectiveName}'...` });
|
|
6753
6506
|
const binding = loadNativeBinding();
|
|
6754
6507
|
let emitError;
|
|
6755
|
-
const
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6508
|
+
const nativeOptions = {
|
|
6509
|
+
apiUrl: context.apiUrl,
|
|
6510
|
+
bearerToken,
|
|
6511
|
+
dockerfilePath,
|
|
6512
|
+
registeredName: effectiveName,
|
|
6513
|
+
diskMb: options.diskMb,
|
|
6514
|
+
builderDiskMb: options.builderDiskMb,
|
|
6515
|
+
cpus: options.cpus,
|
|
6516
|
+
memoryMb: options.memoryMb,
|
|
6517
|
+
isPublic: options.isPublic ?? false,
|
|
6518
|
+
organizationId: usePat ? context.organizationId : void 0,
|
|
6519
|
+
projectId: usePat ? context.projectId : void 0,
|
|
6520
|
+
namespace: context.namespace,
|
|
6521
|
+
useScopeHeaders: usePat,
|
|
6522
|
+
userAgent: void 0,
|
|
6523
|
+
dockerCompat: options.dockerCompat ?? false,
|
|
6524
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6525
|
+
dockerfileText,
|
|
6526
|
+
contextDir: nativeContextDir,
|
|
6527
|
+
cas: options.cas ?? false,
|
|
6528
|
+
buildArgs: options.buildArgs
|
|
6529
|
+
};
|
|
6530
|
+
const forward = (event) => {
|
|
6531
|
+
try {
|
|
6532
|
+
emit(eventToEmitDict(event));
|
|
6533
|
+
} catch (error) {
|
|
6534
|
+
emitError ??= error;
|
|
6782
6535
|
}
|
|
6783
|
-
|
|
6536
|
+
};
|
|
6537
|
+
const resultJson = options.cas ? await __runWithInterrupt(
|
|
6538
|
+
options.signal,
|
|
6539
|
+
(interruptId) => binding.buildSandboxImage(nativeOptions, forward, interruptId)
|
|
6540
|
+
) : await binding.buildSandboxImage(nativeOptions, forward);
|
|
6784
6541
|
if (emitError != null) {
|
|
6785
6542
|
throw emitError;
|
|
6786
6543
|
}
|
|
@@ -6826,39 +6583,47 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
|
|
|
6826
6583
|
deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
|
|
6827
6584
|
);
|
|
6828
6585
|
}
|
|
6586
|
+
if (options.signal !== void 0 && !options.cas) {
|
|
6587
|
+
throw new Error(
|
|
6588
|
+
"signal is only supported for CAS image imports (cas: true); a legacy import has no Image Service build operation to cancel"
|
|
6589
|
+
);
|
|
6590
|
+
}
|
|
6829
6591
|
emit({
|
|
6830
6592
|
type: "status",
|
|
6831
6593
|
message: `Importing image '${reference}' as '${effectiveName}'...`
|
|
6832
6594
|
});
|
|
6833
6595
|
const binding = loadNativeBinding();
|
|
6834
6596
|
let emitError;
|
|
6835
|
-
const
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
}
|
|
6597
|
+
const nativeOptions = {
|
|
6598
|
+
apiUrl: context.apiUrl,
|
|
6599
|
+
bearerToken,
|
|
6600
|
+
imageReference: reference,
|
|
6601
|
+
registeredName: effectiveName,
|
|
6602
|
+
diskMb: options.diskMb,
|
|
6603
|
+
builderDiskMb: options.builderDiskMb,
|
|
6604
|
+
cpus: options.cpus,
|
|
6605
|
+
memoryMb: options.memoryMb,
|
|
6606
|
+
isPublic: options.isPublic ?? false,
|
|
6607
|
+
organizationId: usePat ? context.organizationId : void 0,
|
|
6608
|
+
projectId: usePat ? context.projectId : void 0,
|
|
6609
|
+
namespace: context.namespace,
|
|
6610
|
+
useScopeHeaders: usePat,
|
|
6611
|
+
userAgent: void 0,
|
|
6612
|
+
dockerCompat: options.dockerCompat ?? false,
|
|
6613
|
+
dockerConfigJson: options.dockerConfigJson,
|
|
6614
|
+
cas: options.cas ?? false
|
|
6615
|
+
};
|
|
6616
|
+
const forward = (event) => {
|
|
6617
|
+
try {
|
|
6618
|
+
emit(eventToEmitDict(event));
|
|
6619
|
+
} catch (error) {
|
|
6620
|
+
emitError ??= error;
|
|
6860
6621
|
}
|
|
6861
|
-
|
|
6622
|
+
};
|
|
6623
|
+
const resultJson = options.cas ? await __runWithInterrupt(
|
|
6624
|
+
options.signal,
|
|
6625
|
+
(interruptId) => binding.importSandboxImage(nativeOptions, forward, interruptId)
|
|
6626
|
+
) : await binding.importSandboxImage(nativeOptions, forward);
|
|
6862
6627
|
if (emitError != null) {
|
|
6863
6628
|
throw emitError;
|
|
6864
6629
|
}
|
|
@@ -6874,10 +6639,7 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
|
|
|
6874
6639
|
emit({ type: "done" });
|
|
6875
6640
|
return result;
|
|
6876
6641
|
}
|
|
6877
|
-
|
|
6878
|
-
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6879
|
-
throw new TypeError("imageName must be a non-empty string");
|
|
6880
|
-
}
|
|
6642
|
+
function catalogOptionsFromEnv() {
|
|
6881
6643
|
const context = buildContextFromEnv();
|
|
6882
6644
|
const bearerToken = context.apiKey;
|
|
6883
6645
|
if (!bearerToken) {
|
|
@@ -6888,66 +6650,76 @@ async function deleteSandboxImage(imageName) {
|
|
|
6888
6650
|
}
|
|
6889
6651
|
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6890
6652
|
}
|
|
6891
|
-
|
|
6892
|
-
apiUrl: context.apiUrl,
|
|
6893
|
-
apiKey: bearerToken,
|
|
6894
|
-
namespace: context.namespace
|
|
6895
|
-
});
|
|
6896
|
-
try {
|
|
6897
|
-
await client.deleteSandboxImage(imageName);
|
|
6898
|
-
} finally {
|
|
6899
|
-
client.close();
|
|
6900
|
-
}
|
|
6653
|
+
return { apiUrl: context.apiUrl, bearerToken, useScopeHeaders: false };
|
|
6901
6654
|
}
|
|
6902
|
-
|
|
6903
|
-
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6904
|
-
throw new TypeError("imageName must be a non-empty string");
|
|
6905
|
-
}
|
|
6655
|
+
function catalogOptionsFromCredentials(credentials) {
|
|
6906
6656
|
const context = buildContextFromEnv();
|
|
6907
|
-
const bearerToken = context.apiKey;
|
|
6657
|
+
const bearerToken = credentials.apiKey ?? context.apiKey;
|
|
6908
6658
|
if (!bearerToken) {
|
|
6909
|
-
if (context.personalAccessToken) {
|
|
6910
|
-
throw new Error(
|
|
6911
|
-
"Sandbox image SDKs require TENSORLAKE_API_KEY. Personal access tokens are CLI-only."
|
|
6912
|
-
);
|
|
6913
|
-
}
|
|
6914
6659
|
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6915
6660
|
}
|
|
6916
|
-
const
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
namespace: context.namespace
|
|
6920
|
-
});
|
|
6921
|
-
try {
|
|
6922
|
-
return await client.findSandboxImageByName(imageName);
|
|
6923
|
-
} finally {
|
|
6924
|
-
client.close();
|
|
6661
|
+
const { organizationId, projectId } = credentials;
|
|
6662
|
+
if (organizationId === void 0 !== (projectId === void 0)) {
|
|
6663
|
+
throw new TypeError("organizationId and projectId must be given together");
|
|
6925
6664
|
}
|
|
6665
|
+
return {
|
|
6666
|
+
apiUrl: credentials.apiUrl ?? context.apiUrl,
|
|
6667
|
+
bearerToken,
|
|
6668
|
+
organizationId,
|
|
6669
|
+
projectId,
|
|
6670
|
+
useScopeHeaders: organizationId !== void 0
|
|
6671
|
+
};
|
|
6926
6672
|
}
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
"Sandbox image SDKs require TENSORLAKE_API_KEY. Personal access tokens are CLI-only."
|
|
6934
|
-
);
|
|
6935
|
-
}
|
|
6936
|
-
throw new Error("Missing TENSORLAKE_API_KEY credentials.");
|
|
6673
|
+
function parseTemplate(json) {
|
|
6674
|
+
return JSON.parse(json);
|
|
6675
|
+
}
|
|
6676
|
+
async function deleteSandboxImage(imageName) {
|
|
6677
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6678
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6937
6679
|
}
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6680
|
+
await loadNativeBinding().deleteSandboxImage(catalogOptionsFromEnv(), imageName);
|
|
6681
|
+
}
|
|
6682
|
+
async function deleteSandboxImageWithCredentials(credentials, imageName) {
|
|
6683
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6684
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6685
|
+
}
|
|
6686
|
+
await loadNativeBinding().deleteSandboxImage(
|
|
6687
|
+
catalogOptionsFromCredentials(credentials),
|
|
6688
|
+
imageName
|
|
6689
|
+
);
|
|
6690
|
+
}
|
|
6691
|
+
async function findSandboxImageByName(imageName) {
|
|
6692
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6693
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6694
|
+
}
|
|
6695
|
+
const json = await loadNativeBinding().findSandboxImage(
|
|
6696
|
+
catalogOptionsFromEnv(),
|
|
6697
|
+
imageName
|
|
6698
|
+
);
|
|
6699
|
+
return json == null ? null : parseTemplate(json);
|
|
6700
|
+
}
|
|
6701
|
+
async function findSandboxImageByNameWithCredentials(credentials, imageName) {
|
|
6702
|
+
if (typeof imageName !== "string" || imageName.length === 0) {
|
|
6703
|
+
throw new TypeError("imageName must be a non-empty string");
|
|
6947
6704
|
}
|
|
6705
|
+
const json = await loadNativeBinding().findSandboxImage(
|
|
6706
|
+
catalogOptionsFromCredentials(credentials),
|
|
6707
|
+
imageName
|
|
6708
|
+
);
|
|
6709
|
+
return json == null ? null : parseTemplate(json);
|
|
6710
|
+
}
|
|
6711
|
+
async function listSandboxImages() {
|
|
6712
|
+
const json = await loadNativeBinding().listSandboxImages(catalogOptionsFromEnv());
|
|
6713
|
+
return JSON.parse(json);
|
|
6714
|
+
}
|
|
6715
|
+
async function listSandboxImagesWithCredentials(credentials) {
|
|
6716
|
+
const json = await loadNativeBinding().listSandboxImages(
|
|
6717
|
+
catalogOptionsFromCredentials(credentials)
|
|
6718
|
+
);
|
|
6719
|
+
return JSON.parse(json);
|
|
6948
6720
|
}
|
|
6949
6721
|
async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
|
|
6950
|
-
const parsed = (0,
|
|
6722
|
+
const parsed = (0, import_node_util.parseArgs)({
|
|
6951
6723
|
args: argv,
|
|
6952
6724
|
allowPositionals: true,
|
|
6953
6725
|
options: {
|
|
@@ -7001,7 +6773,7 @@ async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
|
|
|
7001
6773
|
);
|
|
7002
6774
|
}
|
|
7003
6775
|
async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
|
|
7004
|
-
const parsed = (0,
|
|
6776
|
+
const parsed = (0, import_node_util.parseArgs)({
|
|
7005
6777
|
args: argv,
|
|
7006
6778
|
allowPositionals: true,
|
|
7007
6779
|
options: {
|
|
@@ -7054,7 +6826,7 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
|
|
|
7054
6826
|
{ emit: ndjsonStdoutEmit, _allowPat: true }
|
|
7055
6827
|
);
|
|
7056
6828
|
}
|
|
7057
|
-
var import_node_path3, import_node_os2, import_node_fs2,
|
|
6829
|
+
var import_node_path3, import_node_os2, import_node_fs2, import_node_util, cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME2, __imageBuildInternals;
|
|
7058
6830
|
var init_sandbox_image = __esm({
|
|
7059
6831
|
"src/sandbox-image.ts"() {
|
|
7060
6832
|
"use strict";
|
|
@@ -7062,11 +6834,21 @@ var init_sandbox_image = __esm({
|
|
|
7062
6834
|
import_node_path3 = __toESM(require("path"), 1);
|
|
7063
6835
|
import_node_os2 = __toESM(require("os"), 1);
|
|
7064
6836
|
import_node_fs2 = require("fs");
|
|
7065
|
-
|
|
7066
|
-
init_cloud_client();
|
|
6837
|
+
import_node_util = require("util");
|
|
7067
6838
|
init_image();
|
|
7068
6839
|
init_native_binding();
|
|
6840
|
+
init_image_builds();
|
|
7069
6841
|
DEFAULT_IMAGE_NAME2 = "default";
|
|
6842
|
+
__imageBuildInternals = {
|
|
6843
|
+
loadNativeBinding: () => loadNativeBinding(),
|
|
6844
|
+
buildContextFromEnv: () => buildContextFromEnv(),
|
|
6845
|
+
stderrEmit: (event) => stderrEmit(event),
|
|
6846
|
+
noopEmit: (event) => noopEmit(event),
|
|
6847
|
+
eventToEmitDict: (event) => eventToEmitDict(event),
|
|
6848
|
+
imageRequiresContext: (image) => imageRequiresContext(image),
|
|
6849
|
+
defaultRegisteredName: (dockerfilePath) => defaultRegisteredName(dockerfilePath),
|
|
6850
|
+
defaultRegisteredNameFromImage: (reference) => defaultRegisteredNameFromImage(reference)
|
|
6851
|
+
};
|
|
7070
6852
|
}
|
|
7071
6853
|
});
|
|
7072
6854
|
|
|
@@ -7091,7 +6873,15 @@ __export(index_exports, {
|
|
|
7091
6873
|
Headers: () => Headers,
|
|
7092
6874
|
HttpBody: () => HttpBody,
|
|
7093
6875
|
Image: () => Image,
|
|
6876
|
+
ImageBuildCancelledError: () => ImageBuildCancelledError,
|
|
6877
|
+
ImageBuildError: () => ImageBuildError,
|
|
6878
|
+
ImageBuildFailedError: () => ImageBuildFailedError,
|
|
6879
|
+
ImageBuildHandle: () => ImageBuildHandle,
|
|
6880
|
+
ImageBuildInProgressError: () => ImageBuildInProgressError,
|
|
6881
|
+
ImageBuildInterruptedError: () => ImageBuildInterruptedError,
|
|
6882
|
+
ImageBuildNotFoundError: () => ImageBuildNotFoundError,
|
|
7094
6883
|
ImageBuildOperationType: () => ImageBuildOperationType,
|
|
6884
|
+
ImageBuildTimeoutError: () => ImageBuildTimeoutError,
|
|
7095
6885
|
MountError: () => MountError,
|
|
7096
6886
|
OutputMode: () => OutputMode,
|
|
7097
6887
|
PendingSandbox: () => PendingSandbox,
|
|
@@ -7124,12 +6914,14 @@ __export(index_exports, {
|
|
|
7124
6914
|
TERMINATION_REASON_CANCELLED: () => TERMINATION_REASON_CANCELLED,
|
|
7125
6915
|
TERMINATION_REASON_NO_CAPACITY: () => TERMINATION_REASON_NO_CAPACITY,
|
|
7126
6916
|
TcpTunnel: () => TcpTunnel,
|
|
6917
|
+
cancelImageBuild: () => cancelImageBuild,
|
|
7127
6918
|
createFileSystem: () => createFileSystem,
|
|
7128
6919
|
createSandboxImage: () => createSandboxImage,
|
|
7129
6920
|
deleteFileSystem: () => deleteFileSystem,
|
|
7130
6921
|
deleteSandboxImage: () => deleteSandboxImage,
|
|
7131
6922
|
dockerfileContent: () => dockerfileContent,
|
|
7132
6923
|
findSandboxImageByName: () => findSandboxImageByName,
|
|
6924
|
+
getImageBuild: () => getImageBuild,
|
|
7133
6925
|
importSandboxImage: () => importSandboxImage,
|
|
7134
6926
|
isSandboxPending: () => isSandboxPending,
|
|
7135
6927
|
listFileSystems: () => listFileSystems,
|
|
@@ -7141,7 +6933,10 @@ __export(index_exports, {
|
|
|
7141
6933
|
runLocal: () => runLocal,
|
|
7142
6934
|
runRemote: () => runRemote,
|
|
7143
6935
|
sandboxUrlFromIngressEndpoint: () => sandboxUrlFromIngressEndpoint,
|
|
7144
|
-
schema: () => schema
|
|
6936
|
+
schema: () => schema,
|
|
6937
|
+
startImageBuild: () => startImageBuild,
|
|
6938
|
+
startImageImport: () => startImageImport,
|
|
6939
|
+
waitImageBuild: () => waitImageBuild
|
|
7145
6940
|
});
|
|
7146
6941
|
module.exports = __toCommonJS(index_exports);
|
|
7147
6942
|
init_cjs_shims();
|
|
@@ -7151,11 +6946,546 @@ init_pending_sandbox();
|
|
|
7151
6946
|
init_sandbox();
|
|
7152
6947
|
init_desktop();
|
|
7153
6948
|
init_tunnel();
|
|
7154
|
-
|
|
6949
|
+
|
|
6950
|
+
// src/cloud-client.ts
|
|
6951
|
+
init_cjs_shims();
|
|
6952
|
+
var import_nanoid = require("nanoid");
|
|
6953
|
+
init_defaults();
|
|
6954
|
+
|
|
6955
|
+
// src/native-cloud.ts
|
|
6956
|
+
init_cjs_shims();
|
|
6957
|
+
init_native_sandbox();
|
|
6958
|
+
init_native_worker_client();
|
|
6959
|
+
var NativeCloudTransport = class {
|
|
6960
|
+
constructor(options) {
|
|
6961
|
+
this.options = options;
|
|
6962
|
+
if (!Number.isSafeInteger(options.maxRetries) || options.maxRetries < 0 || options.maxRetries > 4294967295) {
|
|
6963
|
+
throw new RangeError("maxRetries must be a non-negative 32-bit integer");
|
|
6964
|
+
}
|
|
6965
|
+
if (!Number.isFinite(options.retryBackoffMs) || options.retryBackoffMs < 0) {
|
|
6966
|
+
throw new RangeError("retryBackoffMs must be a non-negative finite number");
|
|
6967
|
+
}
|
|
6968
|
+
}
|
|
6969
|
+
native;
|
|
6970
|
+
closed = false;
|
|
6971
|
+
client() {
|
|
6972
|
+
if (this.closed) throw new Error("Tensorlake native client is closed");
|
|
6973
|
+
if (this.native) return this.native;
|
|
6974
|
+
const ctor = loadNativeSandboxBinding().NativeCloudClient;
|
|
6975
|
+
if (!ctor) throw new Error("Native binding does not export NativeCloudClient; rebuild with 'npm run build:native'");
|
|
6976
|
+
return this.native = new ctor(JSON.stringify(this.options));
|
|
6977
|
+
}
|
|
6978
|
+
close() {
|
|
6979
|
+
this.closed = true;
|
|
6980
|
+
releaseNativeHandle(this.native ?? null);
|
|
6981
|
+
this.native = void 0;
|
|
6982
|
+
}
|
|
6983
|
+
async requestResponse(method, path4, options) {
|
|
6984
|
+
const request = await serializeRequest(method, path4, options);
|
|
6985
|
+
const raw = await callNative(() => this.client().request(request));
|
|
6986
|
+
const response = new Response(
|
|
6987
|
+
[204, 205, 304].includes(raw.status) ? null : Uint8Array.from(raw.data).buffer,
|
|
6988
|
+
{ status: raw.status, headers: JSON.parse(raw.headersJson) }
|
|
6989
|
+
);
|
|
6990
|
+
return Object.assign(response, { traceId: raw.traceId });
|
|
6991
|
+
}
|
|
6992
|
+
async requestJson(method, path4) {
|
|
6993
|
+
const response = await this.requestResponse(method, path4);
|
|
6994
|
+
const text = await response.text();
|
|
6995
|
+
const value = text ? JSON.parse(text) : null;
|
|
6996
|
+
return Object.assign(value ?? {}, { traceId: response.traceId });
|
|
6997
|
+
}
|
|
6998
|
+
async *stream(method, path4, signal) {
|
|
6999
|
+
if (signal?.aborted) return;
|
|
7000
|
+
const request = await serializeRequest(method, path4, { headers: { Accept: "text/event-stream" } });
|
|
7001
|
+
yield* nativeEventStream((emit) => this.client().stream(request, emit), void 0, signal);
|
|
7002
|
+
}
|
|
7003
|
+
};
|
|
7004
|
+
async function serializeRequest(method, path4, options) {
|
|
7005
|
+
const headers = { ...options?.headers };
|
|
7006
|
+
let body = options?.body;
|
|
7007
|
+
if (options?.json !== void 0) {
|
|
7008
|
+
body = JSON.stringify(options.json);
|
|
7009
|
+
if (!Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) {
|
|
7010
|
+
headers["Content-Type"] = "application/json";
|
|
7011
|
+
}
|
|
7012
|
+
}
|
|
7013
|
+
const request = {
|
|
7014
|
+
method,
|
|
7015
|
+
path: path4,
|
|
7016
|
+
headersJson: JSON.stringify(headers),
|
|
7017
|
+
statusOnlyCodes: [...options?.statusOnlyCodes ?? []]
|
|
7018
|
+
};
|
|
7019
|
+
if (body instanceof FormData) {
|
|
7020
|
+
request.parts = [];
|
|
7021
|
+
for (const [name, value] of body.entries()) {
|
|
7022
|
+
request.parts.push(typeof value === "string" ? { name, data: Buffer.from(value) } : { name, data: Buffer.from(await value.arrayBuffer()), filename: value.name, contentType: value.type || "application/octet-stream" });
|
|
7023
|
+
}
|
|
7024
|
+
} else if (body !== void 0) {
|
|
7025
|
+
if (body instanceof Blob) request.body = Buffer.from(await body.arrayBuffer());
|
|
7026
|
+
else if (typeof body === "string") request.body = Buffer.from(body);
|
|
7027
|
+
else if (body instanceof ArrayBuffer) request.body = Buffer.from(new Uint8Array(body));
|
|
7028
|
+
else request.body = Buffer.from(body);
|
|
7029
|
+
}
|
|
7030
|
+
return request;
|
|
7031
|
+
}
|
|
7032
|
+
|
|
7033
|
+
// src/cloud-client.ts
|
|
7034
|
+
init_models();
|
|
7035
|
+
init_sandbox_image();
|
|
7036
|
+
var CloudClient = class _CloudClient {
|
|
7037
|
+
transport;
|
|
7038
|
+
apiUrl;
|
|
7039
|
+
apiKey;
|
|
7040
|
+
organizationId;
|
|
7041
|
+
projectId;
|
|
7042
|
+
namespace;
|
|
7043
|
+
constructor(options) {
|
|
7044
|
+
this.apiUrl = options?.apiUrl ?? API_URL;
|
|
7045
|
+
this.apiKey = options?.apiKey ?? API_KEY;
|
|
7046
|
+
this.organizationId = options?.organizationId;
|
|
7047
|
+
this.projectId = options?.projectId;
|
|
7048
|
+
this.namespace = options?.namespace ?? NAMESPACE;
|
|
7049
|
+
this.transport = new NativeCloudTransport({
|
|
7050
|
+
baseUrl: options?.apiUrl ?? API_URL,
|
|
7051
|
+
apiKey: options?.apiKey ?? API_KEY,
|
|
7052
|
+
organizationId: this.organizationId,
|
|
7053
|
+
projectId: this.projectId,
|
|
7054
|
+
maxRetries: options?.maxRetries ?? MAX_RETRIES,
|
|
7055
|
+
retryBackoffMs: options?.retryBackoffMs ?? RETRY_BACKOFF_MS,
|
|
7056
|
+
timeoutMs: DEFAULT_HTTP_TIMEOUT_MS,
|
|
7057
|
+
userAgent: `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
7058
|
+
});
|
|
7059
|
+
}
|
|
7060
|
+
static forCloud(options) {
|
|
7061
|
+
return new _CloudClient(options);
|
|
7062
|
+
}
|
|
7063
|
+
close() {
|
|
7064
|
+
this.transport.close();
|
|
7065
|
+
}
|
|
7066
|
+
async upsertApplication(manifest, codeZip, upgradeRunningRequests = false) {
|
|
7067
|
+
const applicationManifest = { ...manifest };
|
|
7068
|
+
let publicEndpointId = publicEndpointIdFromManifest(applicationManifest);
|
|
7069
|
+
if (applicationAllowsUnauthenticatedRequests(applicationManifest) && publicEndpointId === void 0) {
|
|
7070
|
+
const applicationName = applicationManifest.name;
|
|
7071
|
+
if (typeof applicationName === "string" && applicationName.length > 0) {
|
|
7072
|
+
publicEndpointId = await this.existingApplicationPublicEndpointId(applicationName);
|
|
7073
|
+
}
|
|
7074
|
+
publicEndpointId ??= generatePublicEndpointId();
|
|
7075
|
+
}
|
|
7076
|
+
if (publicEndpointId !== void 0) {
|
|
7077
|
+
applicationManifest.public_endpoint_id = publicEndpointId;
|
|
7078
|
+
delete applicationManifest.publicEndpointId;
|
|
7079
|
+
}
|
|
7080
|
+
const form = new FormData();
|
|
7081
|
+
form.append(
|
|
7082
|
+
"code",
|
|
7083
|
+
new Blob([toBlobPart(codeZip)], { type: "application/zip" }),
|
|
7084
|
+
"code.zip"
|
|
7085
|
+
);
|
|
7086
|
+
form.append("code_content_type", "application/zip");
|
|
7087
|
+
form.append("application", JSON.stringify(applicationManifest));
|
|
7088
|
+
form.append(
|
|
7089
|
+
"upgrade_requests_to_latest_code",
|
|
7090
|
+
String(upgradeRunningRequests)
|
|
7091
|
+
);
|
|
7092
|
+
await this.transport.requestResponse("POST", this.namespacePath("applications"), {
|
|
7093
|
+
body: form
|
|
7094
|
+
});
|
|
7095
|
+
}
|
|
7096
|
+
async deleteApplication(applicationName) {
|
|
7097
|
+
await this.transport.requestResponse(
|
|
7098
|
+
"DELETE",
|
|
7099
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
7100
|
+
);
|
|
7101
|
+
}
|
|
7102
|
+
/**
|
|
7103
|
+
* Delete a registered sandbox image by name or id through the merged
|
|
7104
|
+
* catalog, with this client's credentials: an `image_` id or a name the
|
|
7105
|
+
* Image Service knows deletes a CAS image, a `sandbox_template_` id or a
|
|
7106
|
+
* name registered only in the platform registry deletes a legacy image.
|
|
7107
|
+
* Rejects when neither catalog knows the reference. The same semantics
|
|
7108
|
+
* and accepted differences as the module-level `deleteSandboxImage`.
|
|
7109
|
+
*/
|
|
7110
|
+
async deleteSandboxImage(imageName) {
|
|
7111
|
+
await deleteSandboxImageWithCredentials(this.catalogCredentials(), imageName);
|
|
7112
|
+
}
|
|
7113
|
+
/**
|
|
7114
|
+
* Look up a registered sandbox image by name or id through the merged
|
|
7115
|
+
* catalog, with this client's credentials. Returns the image in the
|
|
7116
|
+
* sandbox-template shape, or `null` when neither the Image Service nor the
|
|
7117
|
+
* platform registry knows the reference. An explicit organization/project
|
|
7118
|
+
* scope (the client's, or the call's override) addresses that project's
|
|
7119
|
+
* routes directly, as before; without one the key's own scope applies.
|
|
7120
|
+
*/
|
|
7121
|
+
async findSandboxImageByName(imageName, options) {
|
|
7122
|
+
return findSandboxImageByNameWithCredentials(
|
|
7123
|
+
this.catalogCredentials(options),
|
|
7124
|
+
imageName
|
|
7125
|
+
);
|
|
7126
|
+
}
|
|
7127
|
+
/**
|
|
7128
|
+
* List every registered sandbox image of the project (CAS and legacy, in
|
|
7129
|
+
* the sandbox-template shape, newest first) through the merged catalog,
|
|
7130
|
+
* with this client's credentials. An explicit organization/project scope
|
|
7131
|
+
* (the client's, or the call's override) addresses that project's routes
|
|
7132
|
+
* directly, as before; without one the key's own scope applies.
|
|
7133
|
+
*/
|
|
7134
|
+
async listSandboxImages(options) {
|
|
7135
|
+
return listSandboxImagesWithCredentials(this.catalogCredentials(options));
|
|
7136
|
+
}
|
|
7137
|
+
catalogCredentials(options) {
|
|
7138
|
+
return {
|
|
7139
|
+
apiUrl: this.apiUrl,
|
|
7140
|
+
apiKey: this.apiKey,
|
|
7141
|
+
organizationId: options?.organizationId ?? this.organizationId,
|
|
7142
|
+
projectId: options?.projectId ?? this.projectId
|
|
7143
|
+
};
|
|
7144
|
+
}
|
|
7145
|
+
async applications() {
|
|
7146
|
+
const raw = await this.transport.requestJson(
|
|
7147
|
+
"GET",
|
|
7148
|
+
this.namespacePath("applications")
|
|
7149
|
+
);
|
|
7150
|
+
return (raw.applications ?? []).map(
|
|
7151
|
+
(application) => fromSnakeKeys(application)
|
|
7152
|
+
);
|
|
7153
|
+
}
|
|
7154
|
+
async applicationManifest(applicationName) {
|
|
7155
|
+
const raw = await this.transport.requestJson(
|
|
7156
|
+
"GET",
|
|
7157
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`)
|
|
7158
|
+
);
|
|
7159
|
+
return fromSnakeKeys(raw);
|
|
7160
|
+
}
|
|
7161
|
+
async runRequest(applicationName, inputs = []) {
|
|
7162
|
+
const path4 = this.namespacePath(
|
|
7163
|
+
`applications/${encodeURIComponent(applicationName)}`
|
|
7164
|
+
);
|
|
7165
|
+
const response = inputs.length === 0 ? await this.transport.requestResponse("POST", path4, {
|
|
7166
|
+
body: new Uint8Array(),
|
|
7167
|
+
headers: { Accept: "application/json" }
|
|
7168
|
+
}) : inputs.length === 1 && inputs[0].name === "0" ? await this.transport.requestResponse("POST", path4, {
|
|
7169
|
+
body: toRequestBody(inputs[0].data),
|
|
7170
|
+
headers: {
|
|
7171
|
+
Accept: "application/json",
|
|
7172
|
+
"Content-Type": inputs[0].contentType
|
|
7173
|
+
}
|
|
7174
|
+
}) : await this.runMultipartRequest(path4, inputs);
|
|
7175
|
+
const body = await parseJsonResponse(response);
|
|
7176
|
+
const requestId = body?.request_id;
|
|
7177
|
+
if (!requestId) {
|
|
7178
|
+
throw new Error("missing request_id in run request response body");
|
|
7179
|
+
}
|
|
7180
|
+
return requestId;
|
|
7181
|
+
}
|
|
7182
|
+
async waitOnRequestCompletion(applicationName, requestId) {
|
|
7183
|
+
const stream = this.transport.stream(
|
|
7184
|
+
"GET",
|
|
7185
|
+
this.namespacePath(
|
|
7186
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/progress`
|
|
7187
|
+
)
|
|
7188
|
+
);
|
|
7189
|
+
for await (const event of stream) {
|
|
7190
|
+
if (Object.prototype.hasOwnProperty.call(event, "RequestFinished")) {
|
|
7191
|
+
return;
|
|
7192
|
+
}
|
|
7193
|
+
}
|
|
7194
|
+
throw new Error("progress stream ended before request completion");
|
|
7195
|
+
}
|
|
7196
|
+
async requestMetadata(applicationName, requestId) {
|
|
7197
|
+
const raw = await this.transport.requestJson(
|
|
7198
|
+
"GET",
|
|
7199
|
+
this.namespacePath(
|
|
7200
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}`
|
|
7201
|
+
)
|
|
7202
|
+
);
|
|
7203
|
+
return fromSnakeKeys(raw);
|
|
7204
|
+
}
|
|
7205
|
+
async requestOutput(applicationName, requestId) {
|
|
7206
|
+
const response = await this.transport.requestResponse(
|
|
7207
|
+
"GET",
|
|
7208
|
+
this.namespacePath(
|
|
7209
|
+
`applications/${encodeURIComponent(applicationName)}/requests/${encodeURIComponent(requestId)}/output`
|
|
7210
|
+
)
|
|
7211
|
+
);
|
|
7212
|
+
const serializedValue = new Uint8Array(await response.arrayBuffer());
|
|
7213
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
7214
|
+
return {
|
|
7215
|
+
serializedValue,
|
|
7216
|
+
contentType
|
|
7217
|
+
};
|
|
7218
|
+
}
|
|
7219
|
+
async listSecrets(options) {
|
|
7220
|
+
const base = this.secretCollectionPath(
|
|
7221
|
+
options?.organizationId,
|
|
7222
|
+
options?.projectId
|
|
7223
|
+
);
|
|
7224
|
+
const raw = await this.transport.requestJson("GET", base);
|
|
7225
|
+
const pageSize = Math.max(0, options?.pageSize ?? 100);
|
|
7226
|
+
return Object.assign(
|
|
7227
|
+
{
|
|
7228
|
+
items: raw.slice(0, pageSize).map(secretFromMetadata),
|
|
7229
|
+
pagination: { total: raw.length }
|
|
7230
|
+
},
|
|
7231
|
+
{ traceId: raw.traceId }
|
|
7232
|
+
);
|
|
7233
|
+
}
|
|
7234
|
+
async getSecret(secretId, options) {
|
|
7235
|
+
const base = this.secretCollectionPath(
|
|
7236
|
+
options?.organizationId,
|
|
7237
|
+
options?.projectId
|
|
7238
|
+
);
|
|
7239
|
+
const raw = await this.transport.requestJson(
|
|
7240
|
+
"GET",
|
|
7241
|
+
`${base}/${encodeURIComponent(secretId)}`
|
|
7242
|
+
);
|
|
7243
|
+
return Object.assign(secretFromMetadata(raw), { traceId: raw.traceId });
|
|
7244
|
+
}
|
|
7245
|
+
async upsertSecrets(secrets, options) {
|
|
7246
|
+
const base = this.secretCollectionPath(
|
|
7247
|
+
options?.organizationId,
|
|
7248
|
+
options?.projectId
|
|
7249
|
+
);
|
|
7250
|
+
if (Array.isArray(secrets)) {
|
|
7251
|
+
const results = [];
|
|
7252
|
+
for (const secret of secrets) {
|
|
7253
|
+
results.push(await this.upsertSecret(base, secret));
|
|
7254
|
+
}
|
|
7255
|
+
return results;
|
|
7256
|
+
}
|
|
7257
|
+
return this.upsertSecret(base, secrets);
|
|
7258
|
+
}
|
|
7259
|
+
async deleteSecret(secretId, options) {
|
|
7260
|
+
const base = this.secretCollectionPath(
|
|
7261
|
+
options?.organizationId,
|
|
7262
|
+
options?.projectId
|
|
7263
|
+
);
|
|
7264
|
+
await this.transport.requestResponse(
|
|
7265
|
+
"DELETE",
|
|
7266
|
+
`${base}/${encodeURIComponent(secretId)}`
|
|
7267
|
+
);
|
|
7268
|
+
}
|
|
7269
|
+
async upsertSecret(base, secret) {
|
|
7270
|
+
let response = await this.transport.requestResponse("POST", base, {
|
|
7271
|
+
json: secret,
|
|
7272
|
+
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() },
|
|
7273
|
+
statusOnlyCodes: /* @__PURE__ */ new Set([409])
|
|
7274
|
+
});
|
|
7275
|
+
if (response.status === 409) {
|
|
7276
|
+
const prefix = base.slice(0, -"/secrets".length);
|
|
7277
|
+
const existing = await this.transport.requestJson(
|
|
7278
|
+
"GET",
|
|
7279
|
+
`${prefix}/secret-names/${encodeURIComponent(secret.name)}`
|
|
7280
|
+
);
|
|
7281
|
+
response = await this.transport.requestResponse(
|
|
7282
|
+
"POST",
|
|
7283
|
+
`${base}/${encodeURIComponent(existing.id)}/versions`,
|
|
7284
|
+
{
|
|
7285
|
+
json: { value: secret.value },
|
|
7286
|
+
headers: { "Idempotency-Key": (0, import_nanoid.nanoid)() }
|
|
7287
|
+
}
|
|
7288
|
+
);
|
|
7289
|
+
}
|
|
7290
|
+
const metadata = await parseJsonResponse(response);
|
|
7291
|
+
return Object.assign(secretFromMetadata(metadata), {
|
|
7292
|
+
traceId: response.traceId
|
|
7293
|
+
});
|
|
7294
|
+
}
|
|
7295
|
+
async startImageBuild(buildServicePath, request) {
|
|
7296
|
+
const form = new FormData();
|
|
7297
|
+
form.append("graph_name", request.applicationName);
|
|
7298
|
+
form.append("graph_version", request.applicationVersion);
|
|
7299
|
+
form.append("graph_function_name", request.functionName);
|
|
7300
|
+
form.append("image_name", request.imageName);
|
|
7301
|
+
form.append("image_id", request.imageId);
|
|
7302
|
+
form.append(
|
|
7303
|
+
"context",
|
|
7304
|
+
new Blob([toBlobPart(request.buildContext)]),
|
|
7305
|
+
"context.tar.gz"
|
|
7306
|
+
);
|
|
7307
|
+
const response = await this.transport.requestResponse(
|
|
7308
|
+
"PUT",
|
|
7309
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds`,
|
|
7310
|
+
{ body: form }
|
|
7311
|
+
);
|
|
7312
|
+
const raw = await parseJsonResponse(response);
|
|
7313
|
+
return fromSnakeKeys(raw);
|
|
7314
|
+
}
|
|
7315
|
+
async createApplicationBuild(buildServicePath, request, imageContexts) {
|
|
7316
|
+
const form = createApplicationBuildForm(request, imageContexts);
|
|
7317
|
+
const response = await this.transport.requestResponse(
|
|
7318
|
+
"POST",
|
|
7319
|
+
trimTrailingSlashes2(buildServicePath),
|
|
7320
|
+
{ body: form }
|
|
7321
|
+
);
|
|
7322
|
+
const raw = await parseJsonResponse(response);
|
|
7323
|
+
return fromSnakeKeys(raw);
|
|
7324
|
+
}
|
|
7325
|
+
async applicationBuildInfo(buildServicePath, applicationBuildId) {
|
|
7326
|
+
const raw = await this.transport.requestJson(
|
|
7327
|
+
"GET",
|
|
7328
|
+
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}`
|
|
7329
|
+
);
|
|
7330
|
+
return fromSnakeKeys(raw);
|
|
7331
|
+
}
|
|
7332
|
+
async cancelApplicationBuild(buildServicePath, applicationBuildId) {
|
|
7333
|
+
const raw = await this.transport.requestJson(
|
|
7334
|
+
"POST",
|
|
7335
|
+
`${trimTrailingSlashes2(buildServicePath)}/${encodeURIComponent(applicationBuildId)}/cancel`
|
|
7336
|
+
);
|
|
7337
|
+
return fromSnakeKeys(raw);
|
|
7338
|
+
}
|
|
7339
|
+
async buildInfo(buildServicePath, buildId) {
|
|
7340
|
+
const raw = await this.transport.requestJson(
|
|
7341
|
+
"GET",
|
|
7342
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}`
|
|
7343
|
+
);
|
|
7344
|
+
return fromSnakeKeys(raw);
|
|
7345
|
+
}
|
|
7346
|
+
async cancelBuild(buildServicePath, buildId) {
|
|
7347
|
+
await this.transport.requestResponse(
|
|
7348
|
+
"POST",
|
|
7349
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/cancel`
|
|
7350
|
+
);
|
|
7351
|
+
}
|
|
7352
|
+
async *streamBuildLogs(buildServicePath, buildId, signal) {
|
|
7353
|
+
const stream = this.transport.stream(
|
|
7354
|
+
"GET",
|
|
7355
|
+
`${trimTrailingSlashes2(buildServicePath)}/builds/${encodeURIComponent(buildId)}/logs`,
|
|
7356
|
+
signal
|
|
7357
|
+
);
|
|
7358
|
+
for await (const event of stream) {
|
|
7359
|
+
yield fromSnakeKeys(event);
|
|
7360
|
+
}
|
|
7361
|
+
}
|
|
7362
|
+
async runMultipartRequest(path4, inputs) {
|
|
7363
|
+
const form = new FormData();
|
|
7364
|
+
for (const input of inputs) {
|
|
7365
|
+
form.append(
|
|
7366
|
+
input.name,
|
|
7367
|
+
new Blob([toBlobPart(input.data)], { type: input.contentType }),
|
|
7368
|
+
input.name
|
|
7369
|
+
);
|
|
7370
|
+
}
|
|
7371
|
+
return this.transport.requestResponse("POST", path4, {
|
|
7372
|
+
body: form,
|
|
7373
|
+
headers: { Accept: "application/json" }
|
|
7374
|
+
});
|
|
7375
|
+
}
|
|
7376
|
+
namespacePath(subpath) {
|
|
7377
|
+
return `/v1/namespaces/${encodeURIComponent(this.namespace)}/${subpath.replace(/^\/+/, "")}`;
|
|
7378
|
+
}
|
|
7379
|
+
async existingApplicationPublicEndpointId(applicationName) {
|
|
7380
|
+
const response = await this.transport.requestResponse(
|
|
7381
|
+
"GET",
|
|
7382
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`),
|
|
7383
|
+
{ statusOnlyCodes: /* @__PURE__ */ new Set([404]) }
|
|
7384
|
+
);
|
|
7385
|
+
if (response.status === 404) {
|
|
7386
|
+
return void 0;
|
|
7387
|
+
}
|
|
7388
|
+
const application = await parseJsonResponse(response);
|
|
7389
|
+
return publicEndpointIdFromManifest(application);
|
|
7390
|
+
}
|
|
7391
|
+
secretCollectionPath(organizationId, projectId) {
|
|
7392
|
+
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
7393
|
+
const resolvedProjectId = projectId ?? this.projectId;
|
|
7394
|
+
if (!resolvedOrganizationId && !resolvedProjectId) {
|
|
7395
|
+
return this.namespacePath("secrets");
|
|
7396
|
+
}
|
|
7397
|
+
if (!resolvedOrganizationId || !resolvedProjectId) {
|
|
7398
|
+
throw new Error("organizationId and projectId must be provided together");
|
|
7399
|
+
}
|
|
7400
|
+
return this.namespacePath("secrets");
|
|
7401
|
+
}
|
|
7402
|
+
};
|
|
7403
|
+
function secretFromMetadata(metadata) {
|
|
7404
|
+
return {
|
|
7405
|
+
id: metadata.id,
|
|
7406
|
+
name: metadata.name,
|
|
7407
|
+
createdAt: new Date(metadata.created_at_ms)
|
|
7408
|
+
};
|
|
7409
|
+
}
|
|
7410
|
+
var UNAUTHENTICATED_REQUESTS = "unauthenticated_requests";
|
|
7411
|
+
function applicationAllowsUnauthenticatedRequests(manifest) {
|
|
7412
|
+
return Array.isArray(manifest.allow) && manifest.allow.includes(UNAUTHENTICATED_REQUESTS);
|
|
7413
|
+
}
|
|
7414
|
+
function publicEndpointIdFromManifest(manifest) {
|
|
7415
|
+
for (const key of ["public_endpoint_id", "publicEndpointId"]) {
|
|
7416
|
+
const value = manifest[key];
|
|
7417
|
+
if (typeof value === "string" && value.length > 0) {
|
|
7418
|
+
return value;
|
|
7419
|
+
}
|
|
7420
|
+
}
|
|
7421
|
+
return void 0;
|
|
7422
|
+
}
|
|
7423
|
+
function generatePublicEndpointId() {
|
|
7424
|
+
return `endpoint_${(0, import_nanoid.nanoid)()}`;
|
|
7425
|
+
}
|
|
7426
|
+
function createApplicationBuildForm(request, imageContexts) {
|
|
7427
|
+
const contextsByPartName = /* @__PURE__ */ new Map();
|
|
7428
|
+
for (const context of imageContexts) {
|
|
7429
|
+
if (contextsByPartName.has(context.contextTarPartName)) {
|
|
7430
|
+
throw new Error(
|
|
7431
|
+
`duplicate image context part name '${context.contextTarPartName}'`
|
|
7432
|
+
);
|
|
7433
|
+
}
|
|
7434
|
+
contextsByPartName.set(context.contextTarPartName, context);
|
|
7435
|
+
}
|
|
7436
|
+
const form = new FormData();
|
|
7437
|
+
form.append(
|
|
7438
|
+
"app_version",
|
|
7439
|
+
new Blob([JSON.stringify(request)], { type: "application/json" }),
|
|
7440
|
+
"app_version"
|
|
7441
|
+
);
|
|
7442
|
+
for (const image of request.images) {
|
|
7443
|
+
const context = contextsByPartName.get(image.contextTarPartName);
|
|
7444
|
+
if (!context) {
|
|
7445
|
+
throw new Error(
|
|
7446
|
+
`missing image context for part '${image.contextTarPartName}'`
|
|
7447
|
+
);
|
|
7448
|
+
}
|
|
7449
|
+
form.append(
|
|
7450
|
+
image.contextTarPartName,
|
|
7451
|
+
new Blob([toBlobPart(context.contextTarGz)]),
|
|
7452
|
+
`${image.contextTarPartName}.tar.gz`
|
|
7453
|
+
);
|
|
7454
|
+
}
|
|
7455
|
+
for (const context of imageContexts) {
|
|
7456
|
+
if (!request.images.some((image) => image.contextTarPartName === context.contextTarPartName)) {
|
|
7457
|
+
throw new Error(
|
|
7458
|
+
`unexpected image context for part '${context.contextTarPartName}'`
|
|
7459
|
+
);
|
|
7460
|
+
}
|
|
7461
|
+
}
|
|
7462
|
+
return form;
|
|
7463
|
+
}
|
|
7464
|
+
function trimTrailingSlashes2(value) {
|
|
7465
|
+
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
7466
|
+
}
|
|
7467
|
+
function toBlobPart(data) {
|
|
7468
|
+
if (typeof data === "string" || data instanceof Blob) {
|
|
7469
|
+
return data;
|
|
7470
|
+
}
|
|
7471
|
+
if (data instanceof Uint8Array) {
|
|
7472
|
+
return Uint8Array.from(data).buffer;
|
|
7473
|
+
}
|
|
7474
|
+
return data;
|
|
7475
|
+
}
|
|
7476
|
+
function toRequestBody(data) {
|
|
7477
|
+
return toBlobPart(data);
|
|
7478
|
+
}
|
|
7479
|
+
async function parseJsonResponse(response) {
|
|
7480
|
+
const text = await response.text();
|
|
7481
|
+
if (!text) {
|
|
7482
|
+
return void 0;
|
|
7483
|
+
}
|
|
7484
|
+
return JSON.parse(text);
|
|
7485
|
+
}
|
|
7155
7486
|
|
|
7156
7487
|
// src/api-client.ts
|
|
7157
7488
|
init_cjs_shims();
|
|
7158
|
-
init_cloud_client();
|
|
7159
7489
|
|
|
7160
7490
|
// src/filesystem.ts
|
|
7161
7491
|
init_cjs_shims();
|
|
@@ -7164,21 +7494,21 @@ var import_node_crypto2 = require("crypto");
|
|
|
7164
7494
|
// src/mount-cli.ts
|
|
7165
7495
|
init_cjs_shims();
|
|
7166
7496
|
var import_node_child_process = require("child_process");
|
|
7167
|
-
var
|
|
7168
|
-
var
|
|
7169
|
-
var
|
|
7170
|
-
var
|
|
7497
|
+
var import_node_fs3 = require("fs");
|
|
7498
|
+
var import_node_os3 = require("os");
|
|
7499
|
+
var import_node_path4 = require("path");
|
|
7500
|
+
var import_node_util2 = require("util");
|
|
7171
7501
|
|
|
7172
7502
|
// src/filesystem-models.ts
|
|
7173
7503
|
init_cjs_shims();
|
|
7174
7504
|
var GIT_MODE_DIR = 16384;
|
|
7175
7505
|
var GIT_MODE_SYMLINK = 40960;
|
|
7176
|
-
function trimSlashes(
|
|
7506
|
+
function trimSlashes(path4) {
|
|
7177
7507
|
let start = 0;
|
|
7178
|
-
let end =
|
|
7179
|
-
while (start < end &&
|
|
7180
|
-
while (end > start &&
|
|
7181
|
-
return
|
|
7508
|
+
let end = path4.length;
|
|
7509
|
+
while (start < end && path4.charCodeAt(start) === 47) start += 1;
|
|
7510
|
+
while (end > start && path4.charCodeAt(end - 1) === 47) end -= 1;
|
|
7511
|
+
return path4.slice(start, end);
|
|
7182
7512
|
}
|
|
7183
7513
|
function fileEntryFromWire(entry, dirPath) {
|
|
7184
7514
|
const mode = entry.mode ?? 33188;
|
|
@@ -7196,9 +7526,9 @@ function fileEntryFromWire(entry, dirPath) {
|
|
|
7196
7526
|
}
|
|
7197
7527
|
function mountStatusFromRaw(raw, localPath) {
|
|
7198
7528
|
const mounted = "mounted" in raw ? Boolean(raw.mounted) : "active" in raw ? Boolean(raw.active) : true;
|
|
7199
|
-
const
|
|
7529
|
+
const path4 = String(raw.path || raw.mount_path || localPath || "");
|
|
7200
7530
|
const filesystem = raw.filesystem || raw.file_system || raw.repository || null;
|
|
7201
|
-
return { path:
|
|
7531
|
+
return { path: path4, filesystem, mounted, raw };
|
|
7202
7532
|
}
|
|
7203
7533
|
var FilesystemError = class extends Error {
|
|
7204
7534
|
constructor(message) {
|
|
@@ -7217,11 +7547,11 @@ var FilesystemNotFoundError = class extends FilesystemError {
|
|
|
7217
7547
|
var FileNotFoundInFilesystemError = class extends FilesystemError {
|
|
7218
7548
|
filesystem;
|
|
7219
7549
|
path;
|
|
7220
|
-
constructor(filesystem,
|
|
7221
|
-
super(`File not found in filesystem ${filesystem}: ${
|
|
7550
|
+
constructor(filesystem, path4) {
|
|
7551
|
+
super(`File not found in filesystem ${filesystem}: ${path4}`);
|
|
7222
7552
|
this.name = "FileNotFoundInFilesystemError";
|
|
7223
7553
|
this.filesystem = filesystem;
|
|
7224
|
-
this.path =
|
|
7554
|
+
this.path = path4;
|
|
7225
7555
|
}
|
|
7226
7556
|
};
|
|
7227
7557
|
var FilesystemAPIError = class extends FilesystemError {
|
|
@@ -7256,7 +7586,7 @@ var CliNotFoundError = class extends MountError {
|
|
|
7256
7586
|
};
|
|
7257
7587
|
|
|
7258
7588
|
// src/mount-cli.ts
|
|
7259
|
-
var execFileAsync = (0,
|
|
7589
|
+
var execFileAsync = (0, import_node_util2.promisify)(import_node_child_process.execFile);
|
|
7260
7590
|
var MountCli = class {
|
|
7261
7591
|
constructor(command, envOverrides) {
|
|
7262
7592
|
this.command = command;
|
|
@@ -7267,9 +7597,9 @@ var MountCli = class {
|
|
|
7267
7597
|
const candidates = [];
|
|
7268
7598
|
if (process.env.TENSORLAKE_CLI) candidates.push(process.env.TENSORLAKE_CLI);
|
|
7269
7599
|
candidates.push("tl");
|
|
7270
|
-
const installed = (0,
|
|
7600
|
+
const installed = (0, import_node_path4.join)((0, import_node_os3.homedir)(), ".tensorlake", "bin", "tl");
|
|
7271
7601
|
try {
|
|
7272
|
-
(0,
|
|
7602
|
+
(0, import_node_fs3.accessSync)(installed, import_node_fs3.constants.F_OK);
|
|
7273
7603
|
candidates.push(installed);
|
|
7274
7604
|
} catch {
|
|
7275
7605
|
}
|
|
@@ -7575,8 +7905,8 @@ var Filesystem = class {
|
|
|
7575
7905
|
}
|
|
7576
7906
|
// -- writes -------------------------------------------------------------------
|
|
7577
7907
|
/** Write one file. Returns the snapshot (version) the write produced. */
|
|
7578
|
-
async writeFile(
|
|
7579
|
-
return await this.writeFiles(/* @__PURE__ */ new Map([[
|
|
7908
|
+
async writeFile(path4, data, message) {
|
|
7909
|
+
return await this.writeFiles(/* @__PURE__ */ new Map([[path4, data]]), message);
|
|
7580
7910
|
}
|
|
7581
7911
|
/** Write several files (and/or delete paths) in one atomic snapshot. */
|
|
7582
7912
|
async writeFiles(files, message, deletes = []) {
|
|
@@ -7584,8 +7914,8 @@ var Filesystem = class {
|
|
|
7584
7914
|
if (entries.length === 0 && deletes.length === 0) {
|
|
7585
7915
|
throw new FilesystemError("nothing to write: no files or deletions given");
|
|
7586
7916
|
}
|
|
7587
|
-
const writes = entries.map(([
|
|
7588
|
-
path:
|
|
7917
|
+
const writes = entries.map(([path4, data]) => ({
|
|
7918
|
+
path: path4,
|
|
7589
7919
|
content: toBuffer(data)
|
|
7590
7920
|
}));
|
|
7591
7921
|
const resolvedMessage = message || `write ${writes.length} file(s) via SDK`;
|
|
@@ -7601,9 +7931,9 @@ var Filesystem = class {
|
|
|
7601
7931
|
* Stream one local file directly to object storage in bounded parts.
|
|
7602
7932
|
* This is the memory-bounded API for multi-GiB files.
|
|
7603
7933
|
*/
|
|
7604
|
-
async writeFileFromPath(
|
|
7934
|
+
async writeFileFromPath(path4, localPath, message) {
|
|
7605
7935
|
return await this.writeFilesFromPaths(
|
|
7606
|
-
/* @__PURE__ */ new Map([[
|
|
7936
|
+
/* @__PURE__ */ new Map([[path4, localPath]]),
|
|
7607
7937
|
message
|
|
7608
7938
|
);
|
|
7609
7939
|
}
|
|
@@ -7616,7 +7946,7 @@ var Filesystem = class {
|
|
|
7616
7946
|
if (entries.length === 0) {
|
|
7617
7947
|
throw new FilesystemError("nothing to write: no local files given");
|
|
7618
7948
|
}
|
|
7619
|
-
const writes = entries.map(([
|
|
7949
|
+
const writes = entries.map(([path4, localPath]) => ({ path: path4, localPath }));
|
|
7620
7950
|
const resolvedMessage = message || `write ${writes.length} local file(s) via SDK`;
|
|
7621
7951
|
const branch = await this.branch();
|
|
7622
7952
|
const traced = await callNative2(
|
|
@@ -7693,11 +8023,11 @@ var Filesystem = class {
|
|
|
7693
8023
|
};
|
|
7694
8024
|
}
|
|
7695
8025
|
/** Delete one file. Returns the durable version the deletion produced. */
|
|
7696
|
-
async deleteFile(
|
|
8026
|
+
async deleteFile(path4, message) {
|
|
7697
8027
|
return await this.writeFiles(
|
|
7698
8028
|
/* @__PURE__ */ new Map(),
|
|
7699
|
-
message || `delete ${
|
|
7700
|
-
[
|
|
8029
|
+
message || `delete ${path4} via SDK`,
|
|
8030
|
+
[path4]
|
|
7701
8031
|
);
|
|
7702
8032
|
}
|
|
7703
8033
|
/**
|
|
@@ -7748,15 +8078,15 @@ var Filesystem = class {
|
|
|
7748
8078
|
* Read a file's bytes at `version` (the current `main` head or a retained
|
|
7749
8079
|
* snapshot id; defaults to the filesystem's current head).
|
|
7750
8080
|
*/
|
|
7751
|
-
async readFile(
|
|
7752
|
-
return (await this.readFileWithMetadata(
|
|
8081
|
+
async readFile(path4, version) {
|
|
8082
|
+
return (await this.readFileWithMetadata(path4, { version })).data;
|
|
7753
8083
|
}
|
|
7754
8084
|
/**
|
|
7755
8085
|
* Read bytes and immutable metadata in one request. A range is executed by
|
|
7756
8086
|
* Artifact Storage, so callers never download the unrequested remainder.
|
|
7757
8087
|
*/
|
|
7758
|
-
async readFileWithMetadata(
|
|
7759
|
-
if (trimSlashes(
|
|
8088
|
+
async readFileWithMetadata(path4, options = {}) {
|
|
8089
|
+
if (trimSlashes(path4) === "") {
|
|
7760
8090
|
throw new FilesystemError("file path must not be empty");
|
|
7761
8091
|
}
|
|
7762
8092
|
const range = options.range;
|
|
@@ -7769,12 +8099,12 @@ var Filesystem = class {
|
|
|
7769
8099
|
const traced = await callNative2(
|
|
7770
8100
|
() => this.native.readFilesystemFile(
|
|
7771
8101
|
this.name,
|
|
7772
|
-
|
|
8102
|
+
path4,
|
|
7773
8103
|
resolvedVersion,
|
|
7774
8104
|
range?.offset,
|
|
7775
8105
|
range?.length
|
|
7776
8106
|
),
|
|
7777
|
-
new FileNotFoundInFilesystemError(this.name,
|
|
8107
|
+
new FileNotFoundInFilesystemError(this.name, path4)
|
|
7778
8108
|
);
|
|
7779
8109
|
const fullSize = traced.fullSize;
|
|
7780
8110
|
if (!traced.contentId || fullSize === void 0 || !Number.isSafeInteger(fullSize) || fullSize < 0 || traced.data.byteLength > fullSize) {
|
|
@@ -7789,9 +8119,9 @@ var Filesystem = class {
|
|
|
7789
8119
|
};
|
|
7790
8120
|
}
|
|
7791
8121
|
/** Read a file as UTF-8 text at `version`. Throws on non-UTF-8 content. */
|
|
7792
|
-
async readText(
|
|
8122
|
+
async readText(path4, version) {
|
|
7793
8123
|
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
|
7794
|
-
await this.readFile(
|
|
8124
|
+
await this.readFile(path4, version)
|
|
7795
8125
|
);
|
|
7796
8126
|
}
|
|
7797
8127
|
/** List one directory (non-recursive) at `version`. */
|
|
@@ -7854,11 +8184,11 @@ var FilesystemMount = class {
|
|
|
7854
8184
|
path;
|
|
7855
8185
|
readonly;
|
|
7856
8186
|
/** @internal — obtain instances via `FilesystemClient.mount()`. */
|
|
7857
|
-
constructor(client, cli, filesystem,
|
|
8187
|
+
constructor(client, cli, filesystem, path4, readonly) {
|
|
7858
8188
|
this.client = client;
|
|
7859
8189
|
this.cli = cli;
|
|
7860
8190
|
this.filesystem = filesystem;
|
|
7861
|
-
this.path =
|
|
8191
|
+
this.path = path4;
|
|
7862
8192
|
this.readonly = readonly;
|
|
7863
8193
|
}
|
|
7864
8194
|
/** Flush pending local changes into a durable snapshot. */
|
|
@@ -7876,6 +8206,7 @@ var FilesystemMount = class {
|
|
|
7876
8206
|
};
|
|
7877
8207
|
|
|
7878
8208
|
// src/api-client.ts
|
|
8209
|
+
init_sandbox_image();
|
|
7879
8210
|
init_errors();
|
|
7880
8211
|
var APIClient = class {
|
|
7881
8212
|
cloudClient;
|
|
@@ -7903,7 +8234,7 @@ var APIClient = class {
|
|
|
7903
8234
|
await this.cloudClient.deleteApplication(applicationName);
|
|
7904
8235
|
}
|
|
7905
8236
|
async deleteSandboxImage(imageName) {
|
|
7906
|
-
await this.
|
|
8237
|
+
await deleteSandboxImageWithCredentials(this.filesystemOptions, imageName);
|
|
7907
8238
|
}
|
|
7908
8239
|
async createFileSystem(name, description, options) {
|
|
7909
8240
|
const filesystem = await new FilesystemClient(this.filesystemOptions).create(
|
|
@@ -7973,7 +8304,7 @@ init_sandbox_image();
|
|
|
7973
8304
|
|
|
7974
8305
|
// src/repository-mount.ts
|
|
7975
8306
|
init_cjs_shims();
|
|
7976
|
-
var
|
|
8307
|
+
var import_node_path5 = require("path");
|
|
7977
8308
|
function requireNonEmpty(value, name) {
|
|
7978
8309
|
if (typeof value !== "string" || value.length === 0) {
|
|
7979
8310
|
throw new TypeError(`${name} must be a non-empty string`);
|
|
@@ -7990,28 +8321,28 @@ var GitCli = class extends MountCli {
|
|
|
7990
8321
|
if (options.readOnly && (options.publish || options.workspace !== void 0) || options.publish && options.workspace !== void 0) {
|
|
7991
8322
|
throw new TypeError("readOnly, publish, and workspace are mutually exclusive");
|
|
7992
8323
|
}
|
|
7993
|
-
const
|
|
8324
|
+
const path4 = (0, import_node_path5.resolve)(localPath);
|
|
7994
8325
|
const args = ["mount"];
|
|
7995
8326
|
if (options.readOnly) args.push("--ro");
|
|
7996
8327
|
if (options.publish) args.push("--publish");
|
|
7997
8328
|
if (options.workspace !== void 0) args.push(`--workspace=${options.workspace}`);
|
|
7998
|
-
args.push("--", target,
|
|
8329
|
+
args.push("--", target, path4);
|
|
7999
8330
|
await this.run(args);
|
|
8000
|
-
return new RepositoryMount(this, target,
|
|
8331
|
+
return new RepositoryMount(this, target, path4, options.readOnly ?? false);
|
|
8001
8332
|
}
|
|
8002
8333
|
async unmount(localPath, options = {}) {
|
|
8003
8334
|
requireNonEmpty(localPath, "localPath");
|
|
8004
8335
|
const args = ["unmount"];
|
|
8005
8336
|
if (options.deleteWorkspace) args.push("--delete");
|
|
8006
8337
|
if (options.discard) args.push("--discard");
|
|
8007
|
-
args.push("--", (0,
|
|
8338
|
+
args.push("--", (0, import_node_path5.resolve)(localPath));
|
|
8008
8339
|
await this.run(args);
|
|
8009
8340
|
}
|
|
8010
8341
|
async status(localPath) {
|
|
8011
8342
|
const args = ["status", "--json"];
|
|
8012
8343
|
if (localPath !== void 0) {
|
|
8013
8344
|
requireNonEmpty(localPath, "localPath");
|
|
8014
|
-
args.push("--", (0,
|
|
8345
|
+
args.push("--", (0, import_node_path5.resolve)(localPath));
|
|
8015
8346
|
}
|
|
8016
8347
|
const output = await this.run(args, 6e4);
|
|
8017
8348
|
let raw;
|
|
@@ -8026,7 +8357,7 @@ var GitCli = class extends MountCli {
|
|
|
8026
8357
|
}
|
|
8027
8358
|
const stringField = (key) => typeof raw[key] === "string" ? raw[key] : null;
|
|
8028
8359
|
return {
|
|
8029
|
-
path: stringField("mountpoint") ?? (localPath === void 0 ? "" : (0,
|
|
8360
|
+
path: stringField("mountpoint") ?? (localPath === void 0 ? "" : (0, import_node_path5.resolve)(localPath)),
|
|
8030
8361
|
repository: stringField("repository"),
|
|
8031
8362
|
reference: stringField("reference"),
|
|
8032
8363
|
workspaceId: stringField("workspace"),
|
|
@@ -8035,44 +8366,44 @@ var GitCli = class extends MountCli {
|
|
|
8035
8366
|
raw
|
|
8036
8367
|
};
|
|
8037
8368
|
}
|
|
8038
|
-
async snapshot(
|
|
8369
|
+
async snapshot(path4, message) {
|
|
8039
8370
|
const args = ["snapshot"];
|
|
8040
8371
|
if (message !== void 0) args.push(`--message=${message}`);
|
|
8041
|
-
args.push("--",
|
|
8372
|
+
args.push("--", path4);
|
|
8042
8373
|
await this.run(args);
|
|
8043
8374
|
}
|
|
8044
|
-
async sync(
|
|
8045
|
-
const args = ["sync", "--",
|
|
8375
|
+
async sync(path4, target) {
|
|
8376
|
+
const args = ["sync", "--", path4];
|
|
8046
8377
|
if (target !== void 0) {
|
|
8047
8378
|
requireNonEmpty(target, "target");
|
|
8048
8379
|
args.push(target);
|
|
8049
8380
|
}
|
|
8050
8381
|
await this.run(args);
|
|
8051
8382
|
}
|
|
8052
|
-
async rebase(
|
|
8383
|
+
async rebase(path4, target, failOnConflict) {
|
|
8053
8384
|
requireNonEmpty(target, "target");
|
|
8054
8385
|
const args = ["rebase"];
|
|
8055
8386
|
if (failOnConflict) args.push("--fail-on-conflict");
|
|
8056
|
-
args.push("--",
|
|
8387
|
+
args.push("--", path4, target);
|
|
8057
8388
|
await this.run(args);
|
|
8058
8389
|
}
|
|
8059
|
-
async promote(
|
|
8390
|
+
async promote(path4, branch, merge) {
|
|
8060
8391
|
requireNonEmpty(branch, "branch");
|
|
8061
8392
|
const args = ["promote"];
|
|
8062
8393
|
if (merge) args.push("--merge");
|
|
8063
|
-
args.push("--",
|
|
8394
|
+
args.push("--", path4, branch);
|
|
8064
8395
|
await this.run(args);
|
|
8065
8396
|
}
|
|
8066
|
-
async prefetch(
|
|
8067
|
-
await this.run(["prefetch", "--",
|
|
8397
|
+
async prefetch(path4) {
|
|
8398
|
+
await this.run(["prefetch", "--", path4]);
|
|
8068
8399
|
}
|
|
8069
8400
|
};
|
|
8070
8401
|
var RepositoryMount = class {
|
|
8071
8402
|
/** @internal Obtain instances via RepositoryClient.mount(). */
|
|
8072
|
-
constructor(cli, target,
|
|
8403
|
+
constructor(cli, target, path4, readOnly) {
|
|
8073
8404
|
this.cli = cli;
|
|
8074
8405
|
this.target = target;
|
|
8075
|
-
this.path =
|
|
8406
|
+
this.path = path4;
|
|
8076
8407
|
this.readOnly = readOnly;
|
|
8077
8408
|
}
|
|
8078
8409
|
/** Inspect workspace state, pending changes, and daemon diagnostics. */
|
|
@@ -8307,6 +8638,7 @@ function validateTimeoutMs2(timeoutMs) {
|
|
|
8307
8638
|
|
|
8308
8639
|
// src/index.ts
|
|
8309
8640
|
init_sandbox_image();
|
|
8641
|
+
init_image_builds();
|
|
8310
8642
|
|
|
8311
8643
|
// src/file-system.ts
|
|
8312
8644
|
init_cjs_shims();
|
|
@@ -9690,38 +10022,38 @@ init_cjs_shims();
|
|
|
9690
10022
|
var import_node_crypto4 = require("crypto");
|
|
9691
10023
|
var textEncoder = new TextEncoder();
|
|
9692
10024
|
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
9693
|
-
function assertJSONValue(value,
|
|
10025
|
+
function assertJSONValue(value, path4, seen) {
|
|
9694
10026
|
if (value === null || typeof value === "string" || typeof value === "boolean") return;
|
|
9695
10027
|
if (typeof value === "number") {
|
|
9696
|
-
if (!Number.isFinite(value)) throw new SerializationError(`${
|
|
10028
|
+
if (!Number.isFinite(value)) throw new SerializationError(`${path4} contains a non-finite number`);
|
|
9697
10029
|
return;
|
|
9698
10030
|
}
|
|
9699
10031
|
if (typeof value !== "object") {
|
|
9700
|
-
throw new SerializationError(`${
|
|
10032
|
+
throw new SerializationError(`${path4} contains unsupported ${typeof value}`);
|
|
9701
10033
|
}
|
|
9702
10034
|
if (isFile(value)) {
|
|
9703
|
-
throw new SerializationError(`${
|
|
10035
|
+
throw new SerializationError(`${path4} contains a nested File; File is only supported as a direct value`);
|
|
9704
10036
|
}
|
|
9705
10037
|
if (isHttpBody(value)) {
|
|
9706
10038
|
throw new SerializationError(
|
|
9707
|
-
`${
|
|
10039
|
+
`${path4} contains a nested HttpBody; HttpBody is only supported as a direct value`
|
|
9708
10040
|
);
|
|
9709
10041
|
}
|
|
9710
|
-
if (seen.has(value)) throw new SerializationError(`${
|
|
10042
|
+
if (seen.has(value)) throw new SerializationError(`${path4} contains a cycle`);
|
|
9711
10043
|
if (Object.getPrototypeOf(value) !== Object.prototype && !Array.isArray(value)) {
|
|
9712
|
-
throw new SerializationError(`${
|
|
10044
|
+
throw new SerializationError(`${path4} contains unsupported ${value.constructor?.name ?? "object"}`);
|
|
9713
10045
|
}
|
|
9714
10046
|
seen.add(value);
|
|
9715
10047
|
if (Array.isArray(value)) {
|
|
9716
10048
|
for (let index = 0; index < value.length; index += 1) {
|
|
9717
10049
|
if (!Object.prototype.hasOwnProperty.call(value, index)) {
|
|
9718
|
-
throw new SerializationError(`${
|
|
10050
|
+
throw new SerializationError(`${path4} contains a sparse array entry at index ${index}`);
|
|
9719
10051
|
}
|
|
9720
|
-
assertJSONValue(value[index], `${
|
|
10052
|
+
assertJSONValue(value[index], `${path4}[${index}]`, seen);
|
|
9721
10053
|
}
|
|
9722
10054
|
} else {
|
|
9723
10055
|
for (const [key, item] of Object.entries(value)) {
|
|
9724
|
-
assertJSONValue(item, `${
|
|
10056
|
+
assertJSONValue(item, `${path4}.${key}`, seen);
|
|
9725
10057
|
}
|
|
9726
10058
|
}
|
|
9727
10059
|
seen.delete(value);
|
|
@@ -10171,7 +10503,15 @@ init_models();
|
|
|
10171
10503
|
Headers,
|
|
10172
10504
|
HttpBody,
|
|
10173
10505
|
Image,
|
|
10506
|
+
ImageBuildCancelledError,
|
|
10507
|
+
ImageBuildError,
|
|
10508
|
+
ImageBuildFailedError,
|
|
10509
|
+
ImageBuildHandle,
|
|
10510
|
+
ImageBuildInProgressError,
|
|
10511
|
+
ImageBuildInterruptedError,
|
|
10512
|
+
ImageBuildNotFoundError,
|
|
10174
10513
|
ImageBuildOperationType,
|
|
10514
|
+
ImageBuildTimeoutError,
|
|
10175
10515
|
MountError,
|
|
10176
10516
|
OutputMode,
|
|
10177
10517
|
PendingSandbox,
|
|
@@ -10204,12 +10544,14 @@ init_models();
|
|
|
10204
10544
|
TERMINATION_REASON_CANCELLED,
|
|
10205
10545
|
TERMINATION_REASON_NO_CAPACITY,
|
|
10206
10546
|
TcpTunnel,
|
|
10547
|
+
cancelImageBuild,
|
|
10207
10548
|
createFileSystem,
|
|
10208
10549
|
createSandboxImage,
|
|
10209
10550
|
deleteFileSystem,
|
|
10210
10551
|
deleteSandboxImage,
|
|
10211
10552
|
dockerfileContent,
|
|
10212
10553
|
findSandboxImageByName,
|
|
10554
|
+
getImageBuild,
|
|
10213
10555
|
importSandboxImage,
|
|
10214
10556
|
isSandboxPending,
|
|
10215
10557
|
listFileSystems,
|
|
@@ -10221,6 +10563,9 @@ init_models();
|
|
|
10221
10563
|
runLocal,
|
|
10222
10564
|
runRemote,
|
|
10223
10565
|
sandboxUrlFromIngressEndpoint,
|
|
10224
|
-
schema
|
|
10566
|
+
schema,
|
|
10567
|
+
startImageBuild,
|
|
10568
|
+
startImageImport,
|
|
10569
|
+
waitImageBuild
|
|
10225
10570
|
});
|
|
10226
10571
|
//# sourceMappingURL=index.cjs.map
|