@slicervm/sdk 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -273,7 +273,71 @@ function agentHealthFromWire(w) {
273
273
  ...w.agent_uptime !== void 0 && { agentUptime: w.agent_uptime },
274
274
  ...w.agent_version !== void 0 && { agentVersion: w.agent_version },
275
275
  ...w.system_uptime !== void 0 && { systemUptime: w.system_uptime },
276
- ...w.userdata_ran !== void 0 && { userdataRan: w.userdata_ran }
276
+ ...w.userdata_ran !== void 0 && { userdataRan: w.userdata_ran },
277
+ ...w.userdata_exit_code !== void 0 && { userdataExitCode: w.userdata_exit_code }
278
+ };
279
+ }
280
+ function vmCommitFromWire(w) {
281
+ return {
282
+ hostname: w.hostname,
283
+ commitId: w.commit_id,
284
+ status: w.status,
285
+ ...w.parent_status !== void 0 && { parentStatus: w.parent_status },
286
+ mode: w.mode ?? "",
287
+ ...w.tags !== void 0 && { tags: w.tags },
288
+ ...w.labels !== void 0 && { labels: w.labels },
289
+ ...w.cache_key !== void 0 && { cacheKey: w.cache_key }
290
+ };
291
+ }
292
+ function vmCommitInfoFromWire(w) {
293
+ return {
294
+ commitId: w.commit_id,
295
+ sourceHostname: w.source_hostname,
296
+ sourceHostGroup: w.source_host_group,
297
+ createdAt: w.created_at,
298
+ mode: w.mode,
299
+ ...w.tags !== void 0 && { tags: w.tags },
300
+ ...w.labels !== void 0 && { labels: w.labels },
301
+ ...w.cache_key !== void 0 && { cacheKey: w.cache_key }
302
+ };
303
+ }
304
+ function vmCommitDeleteFromWire(w) {
305
+ return { commitId: w.commit_id, status: w.status };
306
+ }
307
+ function vmForkFromWire(w) {
308
+ return {
309
+ hostname: w.hostname,
310
+ sourceHostname: w.source_hostname,
311
+ ...w.commit_id !== void 0 && { commitId: w.commit_id },
312
+ status: w.status,
313
+ ...w.parent_status !== void 0 && { parentStatus: w.parent_status },
314
+ ...w.child_status !== void 0 && { childStatus: w.child_status },
315
+ mode: w.mode ?? ""
316
+ };
317
+ }
318
+ function vmDescriptionFromWire(w) {
319
+ return {
320
+ hostname: w.hostname,
321
+ ...w.hostgroup !== void 0 && { hostGroup: w.hostgroup },
322
+ ...w.ip !== void 0 && { ip: w.ip },
323
+ ...w.ram_bytes !== void 0 && { ramBytes: w.ram_bytes },
324
+ ...w.cpus !== void 0 && { cpus: w.cpus },
325
+ ...w.created_at !== void 0 && { createdAt: w.created_at },
326
+ ...w.arch !== void 0 && { arch: w.arch },
327
+ ...w.tags !== void 0 && { tags: w.tags },
328
+ ...w.status !== void 0 && { status: w.status },
329
+ ...w.persistent !== void 0 && { persistent: w.persistent },
330
+ ...w.storage !== void 0 && { storage: w.storage },
331
+ ...w.image !== void 0 && { image: w.image },
332
+ ...w.commit_id !== void 0 && { commitId: w.commit_id },
333
+ ...w.parent_commit_id !== void 0 && { parentCommitId: w.parent_commit_id },
334
+ network: {
335
+ ...w.network.mode !== void 0 && { mode: w.network.mode },
336
+ ...w.network.policy_source !== void 0 && { policySource: w.network.policy_source },
337
+ hostGroup: w.network.host_group,
338
+ ...w.network.override !== void 0 && { override: w.network.override },
339
+ effective: w.network.effective
340
+ }
277
341
  };
278
342
  }
279
343
  function fsEntryFromWire(w) {
@@ -728,6 +792,48 @@ var VMFileSystem = class {
728
792
  );
729
793
  }
730
794
  };
795
+ var CommittedVM = class {
796
+ constructor(transport, hostGroup, response) {
797
+ this.transport = transport;
798
+ this.hostname = response.hostname;
799
+ this.hostGroup = hostGroup;
800
+ this.commitId = response.commitId;
801
+ this.status = response.status;
802
+ if (response.parentStatus !== void 0) this.parentStatus = response.parentStatus;
803
+ this.mode = response.mode;
804
+ if (response.tags !== void 0) this.tags = response.tags;
805
+ if (response.labels !== void 0) this.labels = response.labels;
806
+ if (response.cacheKey !== void 0) this.cacheKey = response.cacheKey;
807
+ }
808
+ transport;
809
+ hostname;
810
+ hostGroup;
811
+ commitId;
812
+ status;
813
+ parentStatus;
814
+ mode;
815
+ tags;
816
+ labels;
817
+ cacheKey;
818
+ async fork(opts = {}) {
819
+ const res = await forkPath(
820
+ this.transport,
821
+ this.commitId,
822
+ opts
823
+ );
824
+ return new VM(this.transport, {
825
+ hostname: res.hostname,
826
+ hostGroup: this.hostGroup
827
+ });
828
+ }
829
+ async forkRaw(opts = {}) {
830
+ return forkPath(
831
+ this.transport,
832
+ this.commitId,
833
+ opts
834
+ );
835
+ }
836
+ };
731
837
  var VM = class {
732
838
  hostname;
733
839
  hostGroup;
@@ -767,6 +873,14 @@ var VM = class {
767
873
  async logs() {
768
874
  return this.transport.request("GET", `/vm/${encodeURIComponent(this.hostname)}/logs`);
769
875
  }
876
+ /** Return configuration, fork lineage, and effective network policy. */
877
+ async describe() {
878
+ const wire = await this.transport.request(
879
+ "GET",
880
+ `/vm/${encodeURIComponent(this.hostname)}`
881
+ );
882
+ return vmDescriptionFromWire(wire);
883
+ }
770
884
  async waitForAgent(opts = {}) {
771
885
  const timeoutMs = opts.timeoutMs ?? 12e4;
772
886
  const intervalMs = opts.intervalMs ?? 500;
@@ -793,10 +907,15 @@ var VM = class {
793
907
  while (Date.now() < deadline) {
794
908
  try {
795
909
  last = await this.health();
796
- if (last.userdataRan) return last;
797
910
  } catch (err) {
798
911
  lastErr = err;
799
912
  }
913
+ if (last?.userdataRan) {
914
+ if (last.userdataExitCode !== void 0 && last.userdataExitCode !== 0) {
915
+ throw new Error(`userdata failed with exit code ${last.userdataExitCode}`);
916
+ }
917
+ return last;
918
+ }
800
919
  await sleep(intervalMs);
801
920
  }
802
921
  throw new Error(
@@ -828,6 +947,25 @@ var VM = class {
828
947
  async restore() {
829
948
  await this.transport.request("POST", `/vm/${encodeURIComponent(this.hostname)}/restore`);
830
949
  }
950
+ /**
951
+ * Commit a stopped persistent VM disk into an immutable parent.
952
+ */
953
+ async commit(opts = {}) {
954
+ const cacheKey = opts.cacheKey?.trim();
955
+ const tags = opts.tags && opts.tags.length > 0 ? opts.tags : void 0;
956
+ const labels = opts.labels && Object.keys(opts.labels).length > 0 ? opts.labels : void 0;
957
+ const body = tags !== void 0 || labels !== void 0 || cacheKey ? {
958
+ ...tags !== void 0 && { tags },
959
+ ...labels !== void 0 && { labels },
960
+ ...cacheKey && { cache_key: cacheKey }
961
+ } : void 0;
962
+ const wire = await this.transport.request(
963
+ "POST",
964
+ `/vm/${encodeURIComponent(this.hostname)}/commit`,
965
+ body
966
+ );
967
+ return new CommittedVM(this.transport, this.hostGroup, vmCommitFromWire(wire));
968
+ }
831
969
  // --- port forwarding ---------------------------------------------------
832
970
  /**
833
971
  * Open one or more port forwards from the host to this VM. Each spec follows
@@ -947,6 +1085,32 @@ function sleep(ms) {
947
1085
  function errMsg(e) {
948
1086
  return e instanceof Error ? e.message : String(e);
949
1087
  }
1088
+ async function forkPath(transport, commitId, opts) {
1089
+ const id = validateCommitId(commitId);
1090
+ const q = new URLSearchParams();
1091
+ q.set("wait", "agent");
1092
+ if (opts.waitTimeoutSec !== void 0 && opts.waitTimeoutSec > 0) {
1093
+ q.set("timeout", `${opts.waitTimeoutSec}s`);
1094
+ }
1095
+ const query = q.toString() ? `?${q.toString()}` : "";
1096
+ const body = opts.network !== void 0 || (opts.tags?.length ?? 0) > 0 ? {
1097
+ ...opts.network !== void 0 && { network: opts.network },
1098
+ ...(opts.tags?.length ?? 0) > 0 && { tags: opts.tags }
1099
+ } : void 0;
1100
+ const wire = await transport.request(
1101
+ "POST",
1102
+ `/vm/commits/${encodeURIComponent(id)}/fork${query}`,
1103
+ body
1104
+ );
1105
+ return vmForkFromWire(wire);
1106
+ }
1107
+ function validateCommitId(commitId) {
1108
+ const value = commitId.trim();
1109
+ if (!value || value === "." || value === ".." || value.includes("..") || value.includes("/") || value.includes("\\") || value.includes("\0")) {
1110
+ throw new Error(`invalid commit ID ${JSON.stringify(value)}`);
1111
+ }
1112
+ return value;
1113
+ }
950
1114
  var VMBg = class {
951
1115
  constructor(transport, hostname) {
952
1116
  this.transport = transport;
@@ -1205,6 +1369,54 @@ var VMsAPI = class {
1205
1369
  return createVMResFromWire(wire);
1206
1370
  }
1207
1371
  };
1372
+ var CommitsAPI = class {
1373
+ constructor(transport) {
1374
+ this.transport = transport;
1375
+ }
1376
+ transport;
1377
+ async list(opts = {}) {
1378
+ const qs = new URLSearchParams();
1379
+ for (const tag of opts.tags ?? []) {
1380
+ const value = tag.trim();
1381
+ if (value) qs.append("tag", value);
1382
+ }
1383
+ const cacheKey = opts.cacheKey?.trim();
1384
+ const source = opts.source?.trim();
1385
+ const mode = opts.mode?.trim();
1386
+ if (cacheKey) qs.set("cache_key", cacheKey);
1387
+ if (source) qs.set("source", source);
1388
+ if (mode) qs.set("mode", mode);
1389
+ const encoded = qs.toString();
1390
+ const query = encoded ? `?${encoded}` : "";
1391
+ const wire = await this.transport.request("GET", `/vm/commits${query}`);
1392
+ return (wire ?? []).map(vmCommitInfoFromWire);
1393
+ }
1394
+ async delete(commitId) {
1395
+ const id = validateCommitId2(commitId);
1396
+ const wire = await this.transport.request(
1397
+ "DELETE",
1398
+ `/vm/commits/${encodeURIComponent(id)}`
1399
+ );
1400
+ return vmCommitDeleteFromWire(wire);
1401
+ }
1402
+ async fork(commitId, opts = {}) {
1403
+ const id = validateCommitId2(commitId);
1404
+ const qs = new URLSearchParams({ wait: "agent" });
1405
+ if (opts.waitTimeoutSec !== void 0 && opts.waitTimeoutSec > 0) {
1406
+ qs.set("timeout", `${opts.waitTimeoutSec}s`);
1407
+ }
1408
+ const body = opts.network !== void 0 || (opts.tags?.length ?? 0) > 0 ? {
1409
+ ...opts.network !== void 0 && { network: opts.network },
1410
+ ...(opts.tags?.length ?? 0) > 0 && { tags: opts.tags }
1411
+ } : void 0;
1412
+ const wire = await this.transport.request(
1413
+ "POST",
1414
+ `/vm/commits/${encodeURIComponent(id)}/fork?${qs.toString()}`,
1415
+ body
1416
+ );
1417
+ return vmForkFromWire(wire);
1418
+ }
1419
+ };
1208
1420
  var SecretsAPI = class {
1209
1421
  constructor(transport) {
1210
1422
  this.transport = transport;
@@ -1251,10 +1463,18 @@ function buildListQuery(opts) {
1251
1463
  const s = qs.toString();
1252
1464
  return s ? `?${s}` : "";
1253
1465
  }
1466
+ function validateCommitId2(commitId) {
1467
+ const value = commitId.trim();
1468
+ if (!value || value === "." || value === ".." || value.includes("..") || value.includes("/") || value.includes("\\") || value.includes("\0")) {
1469
+ throw new Error(`invalid commit ID ${JSON.stringify(value)}`);
1470
+ }
1471
+ return value;
1472
+ }
1254
1473
 
1255
1474
  // src/proxy.ts
1256
1475
  var ProxySecretBearer = "bearer";
1257
1476
  var ProxySecretBasic = "basic";
1477
+ var ProxySecretOAuthClientCredentials = "oauth-client-creds";
1258
1478
  function clientFromWire(w) {
1259
1479
  return { name: w.name, createdAt: w.created_at };
1260
1480
  }
@@ -1411,12 +1631,14 @@ var SlicerClient = class _SlicerClient {
1411
1631
  transport;
1412
1632
  hostGroups;
1413
1633
  vms;
1634
+ commits;
1414
1635
  secrets;
1415
1636
  proxy;
1416
1637
  constructor(opts) {
1417
1638
  this.transport = new TransportClient(opts);
1418
1639
  this.hostGroups = new HostGroupsAPI(this.transport);
1419
1640
  this.vms = new VMsAPI(this.transport);
1641
+ this.commits = new CommitsAPI(this.transport);
1420
1642
  this.secrets = new SecretsAPI(this.transport);
1421
1643
  this.proxy = new ProxyAPI(this.transport);
1422
1644
  }
@@ -1575,6 +1797,6 @@ var SlicerShellSession = class {
1575
1797
  }
1576
1798
  };
1577
1799
 
1578
- export { ExecStdioBase64, ExecStdioText, FRAME_TYPE_DATA, FRAME_TYPE_HEARTBEAT, FRAME_TYPE_SESSION_CLOSE, FRAME_TYPE_SHUTDOWN, FRAME_TYPE_WINDOW_SIZE, Forwarder, GiB, HostGroupsAPI, MiB, NonRootUser, ProxyAPI, ProxyAllowsAPI, ProxyClientsAPI, ProxySecretBasic, ProxySecretBearer, ProxySecretsAPI, SecretExistsError, SecretsAPI, SlicerAPIError, SlicerClient, SlicerShellSession, VM, VMBg, VMFileSystem, VMsAPI, encodeFrame, parseAddressMapping, parseFrame, resolveTransport };
1800
+ export { CommitsAPI, CommittedVM, ExecStdioBase64, ExecStdioText, FRAME_TYPE_DATA, FRAME_TYPE_HEARTBEAT, FRAME_TYPE_SESSION_CLOSE, FRAME_TYPE_SHUTDOWN, FRAME_TYPE_WINDOW_SIZE, Forwarder, GiB, HostGroupsAPI, MiB, NonRootUser, ProxyAPI, ProxyAllowsAPI, ProxyClientsAPI, ProxySecretBasic, ProxySecretBearer, ProxySecretOAuthClientCredentials, ProxySecretsAPI, SecretExistsError, SecretsAPI, SlicerAPIError, SlicerClient, SlicerShellSession, VM, VMBg, VMFileSystem, VMsAPI, encodeFrame, parseAddressMapping, parseFrame, resolveTransport };
1579
1801
  //# sourceMappingURL=index.js.map
1580
1802
  //# sourceMappingURL=index.js.map