@slicervm/sdk 0.1.6 → 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/README.md +29 -1
- package/dist/index.cjs +390 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +313 -3
- package/dist/index.d.ts +313 -3
- package/dist/index.js +382 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript SDK for the [Slicer](https://slicervm.com) VM control-plane API.
|
|
4
4
|
|
|
5
|
-
Mirrors the [Go SDK](https://github.com/slicervm/sdk) semantically. The top-level `SlicerClient` exposes `hostGroups`, `vms`, and `secrets` namespaces for control-plane operations; per-VM operations live on a `VM` handle returned from `client.vms.create()` / `client.vms.attach()`.
|
|
5
|
+
Mirrors the [Go SDK](https://github.com/slicervm/sdk) semantically. The top-level `SlicerClient` exposes `hostGroups`, `vms`, `commits`, and `secrets` namespaces for control-plane operations; per-VM operations live on a `VM` handle returned from `client.vms.create()` / `client.vms.attach()`.
|
|
6
6
|
|
|
7
7
|
Supports Unix socket and HTTP(S) transports.
|
|
8
8
|
|
|
@@ -33,6 +33,34 @@ for await (const f of vm.bg.logs(bg.execId, { follow: true })) {
|
|
|
33
33
|
await vm.delete();
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
## Cold forks
|
|
37
|
+
|
|
38
|
+
A stopped persistent VM can be committed as an immutable disk parent, then
|
|
39
|
+
forked into cold-booted children. Fork calls always wait until the child agent
|
|
40
|
+
has finalised its guest identity.
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
await vm.shutdown();
|
|
44
|
+
const parent = await vm.commit({
|
|
45
|
+
tags: ['node-build'],
|
|
46
|
+
cacheKey: 'node-build-v1',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const child = await parent.fork({
|
|
50
|
+
waitTimeoutSec: 120,
|
|
51
|
+
network: { allow: [], drop: ['0.0.0.0/0'] },
|
|
52
|
+
tags: ['job=node-build'],
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const description = await child.describe();
|
|
56
|
+
console.log(description.parentCommitId, description.network.effective);
|
|
57
|
+
|
|
58
|
+
const cached = await client.commits.list({ cacheKey: 'node-build-v1' });
|
|
59
|
+
await child.delete();
|
|
60
|
+
await vm.delete();
|
|
61
|
+
await client.commits.delete(parent.commitId);
|
|
62
|
+
```
|
|
63
|
+
|
|
36
64
|
## Status
|
|
37
65
|
|
|
38
66
|
Pre-release. See `ts-plan.md`.
|
package/dist/index.cjs
CHANGED
|
@@ -266,6 +266,7 @@ function createVMReqToWire(r) {
|
|
|
266
266
|
if (r.ip !== void 0) o.ip = r.ip;
|
|
267
267
|
if (r.tags !== void 0) o.tags = r.tags;
|
|
268
268
|
if (r.secrets !== void 0) o.secrets = r.secrets;
|
|
269
|
+
if (r.network !== void 0) o.network = r.network;
|
|
269
270
|
return o;
|
|
270
271
|
}
|
|
271
272
|
function createVMResFromWire(w) {
|
|
@@ -283,7 +284,71 @@ function agentHealthFromWire(w) {
|
|
|
283
284
|
...w.agent_uptime !== void 0 && { agentUptime: w.agent_uptime },
|
|
284
285
|
...w.agent_version !== void 0 && { agentVersion: w.agent_version },
|
|
285
286
|
...w.system_uptime !== void 0 && { systemUptime: w.system_uptime },
|
|
286
|
-
...w.userdata_ran !== void 0 && { userdataRan: w.userdata_ran }
|
|
287
|
+
...w.userdata_ran !== void 0 && { userdataRan: w.userdata_ran },
|
|
288
|
+
...w.userdata_exit_code !== void 0 && { userdataExitCode: w.userdata_exit_code }
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
function vmCommitFromWire(w) {
|
|
292
|
+
return {
|
|
293
|
+
hostname: w.hostname,
|
|
294
|
+
commitId: w.commit_id,
|
|
295
|
+
status: w.status,
|
|
296
|
+
...w.parent_status !== void 0 && { parentStatus: w.parent_status },
|
|
297
|
+
mode: w.mode ?? "",
|
|
298
|
+
...w.tags !== void 0 && { tags: w.tags },
|
|
299
|
+
...w.labels !== void 0 && { labels: w.labels },
|
|
300
|
+
...w.cache_key !== void 0 && { cacheKey: w.cache_key }
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
function vmCommitInfoFromWire(w) {
|
|
304
|
+
return {
|
|
305
|
+
commitId: w.commit_id,
|
|
306
|
+
sourceHostname: w.source_hostname,
|
|
307
|
+
sourceHostGroup: w.source_host_group,
|
|
308
|
+
createdAt: w.created_at,
|
|
309
|
+
mode: w.mode,
|
|
310
|
+
...w.tags !== void 0 && { tags: w.tags },
|
|
311
|
+
...w.labels !== void 0 && { labels: w.labels },
|
|
312
|
+
...w.cache_key !== void 0 && { cacheKey: w.cache_key }
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
function vmCommitDeleteFromWire(w) {
|
|
316
|
+
return { commitId: w.commit_id, status: w.status };
|
|
317
|
+
}
|
|
318
|
+
function vmForkFromWire(w) {
|
|
319
|
+
return {
|
|
320
|
+
hostname: w.hostname,
|
|
321
|
+
sourceHostname: w.source_hostname,
|
|
322
|
+
...w.commit_id !== void 0 && { commitId: w.commit_id },
|
|
323
|
+
status: w.status,
|
|
324
|
+
...w.parent_status !== void 0 && { parentStatus: w.parent_status },
|
|
325
|
+
...w.child_status !== void 0 && { childStatus: w.child_status },
|
|
326
|
+
mode: w.mode ?? ""
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function vmDescriptionFromWire(w) {
|
|
330
|
+
return {
|
|
331
|
+
hostname: w.hostname,
|
|
332
|
+
...w.hostgroup !== void 0 && { hostGroup: w.hostgroup },
|
|
333
|
+
...w.ip !== void 0 && { ip: w.ip },
|
|
334
|
+
...w.ram_bytes !== void 0 && { ramBytes: w.ram_bytes },
|
|
335
|
+
...w.cpus !== void 0 && { cpus: w.cpus },
|
|
336
|
+
...w.created_at !== void 0 && { createdAt: w.created_at },
|
|
337
|
+
...w.arch !== void 0 && { arch: w.arch },
|
|
338
|
+
...w.tags !== void 0 && { tags: w.tags },
|
|
339
|
+
...w.status !== void 0 && { status: w.status },
|
|
340
|
+
...w.persistent !== void 0 && { persistent: w.persistent },
|
|
341
|
+
...w.storage !== void 0 && { storage: w.storage },
|
|
342
|
+
...w.image !== void 0 && { image: w.image },
|
|
343
|
+
...w.commit_id !== void 0 && { commitId: w.commit_id },
|
|
344
|
+
...w.parent_commit_id !== void 0 && { parentCommitId: w.parent_commit_id },
|
|
345
|
+
network: {
|
|
346
|
+
...w.network.mode !== void 0 && { mode: w.network.mode },
|
|
347
|
+
...w.network.policy_source !== void 0 && { policySource: w.network.policy_source },
|
|
348
|
+
hostGroup: w.network.host_group,
|
|
349
|
+
...w.network.override !== void 0 && { override: w.network.override },
|
|
350
|
+
effective: w.network.effective
|
|
351
|
+
}
|
|
287
352
|
};
|
|
288
353
|
}
|
|
289
354
|
function fsEntryFromWire(w) {
|
|
@@ -738,6 +803,48 @@ var VMFileSystem = class {
|
|
|
738
803
|
);
|
|
739
804
|
}
|
|
740
805
|
};
|
|
806
|
+
var CommittedVM = class {
|
|
807
|
+
constructor(transport, hostGroup, response) {
|
|
808
|
+
this.transport = transport;
|
|
809
|
+
this.hostname = response.hostname;
|
|
810
|
+
this.hostGroup = hostGroup;
|
|
811
|
+
this.commitId = response.commitId;
|
|
812
|
+
this.status = response.status;
|
|
813
|
+
if (response.parentStatus !== void 0) this.parentStatus = response.parentStatus;
|
|
814
|
+
this.mode = response.mode;
|
|
815
|
+
if (response.tags !== void 0) this.tags = response.tags;
|
|
816
|
+
if (response.labels !== void 0) this.labels = response.labels;
|
|
817
|
+
if (response.cacheKey !== void 0) this.cacheKey = response.cacheKey;
|
|
818
|
+
}
|
|
819
|
+
transport;
|
|
820
|
+
hostname;
|
|
821
|
+
hostGroup;
|
|
822
|
+
commitId;
|
|
823
|
+
status;
|
|
824
|
+
parentStatus;
|
|
825
|
+
mode;
|
|
826
|
+
tags;
|
|
827
|
+
labels;
|
|
828
|
+
cacheKey;
|
|
829
|
+
async fork(opts = {}) {
|
|
830
|
+
const res = await forkPath(
|
|
831
|
+
this.transport,
|
|
832
|
+
this.commitId,
|
|
833
|
+
opts
|
|
834
|
+
);
|
|
835
|
+
return new VM(this.transport, {
|
|
836
|
+
hostname: res.hostname,
|
|
837
|
+
hostGroup: this.hostGroup
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
async forkRaw(opts = {}) {
|
|
841
|
+
return forkPath(
|
|
842
|
+
this.transport,
|
|
843
|
+
this.commitId,
|
|
844
|
+
opts
|
|
845
|
+
);
|
|
846
|
+
}
|
|
847
|
+
};
|
|
741
848
|
var VM = class {
|
|
742
849
|
hostname;
|
|
743
850
|
hostGroup;
|
|
@@ -777,6 +884,14 @@ var VM = class {
|
|
|
777
884
|
async logs() {
|
|
778
885
|
return this.transport.request("GET", `/vm/${encodeURIComponent(this.hostname)}/logs`);
|
|
779
886
|
}
|
|
887
|
+
/** Return configuration, fork lineage, and effective network policy. */
|
|
888
|
+
async describe() {
|
|
889
|
+
const wire = await this.transport.request(
|
|
890
|
+
"GET",
|
|
891
|
+
`/vm/${encodeURIComponent(this.hostname)}`
|
|
892
|
+
);
|
|
893
|
+
return vmDescriptionFromWire(wire);
|
|
894
|
+
}
|
|
780
895
|
async waitForAgent(opts = {}) {
|
|
781
896
|
const timeoutMs = opts.timeoutMs ?? 12e4;
|
|
782
897
|
const intervalMs = opts.intervalMs ?? 500;
|
|
@@ -803,10 +918,15 @@ var VM = class {
|
|
|
803
918
|
while (Date.now() < deadline) {
|
|
804
919
|
try {
|
|
805
920
|
last = await this.health();
|
|
806
|
-
if (last.userdataRan) return last;
|
|
807
921
|
} catch (err) {
|
|
808
922
|
lastErr = err;
|
|
809
923
|
}
|
|
924
|
+
if (last?.userdataRan) {
|
|
925
|
+
if (last.userdataExitCode !== void 0 && last.userdataExitCode !== 0) {
|
|
926
|
+
throw new Error(`userdata failed with exit code ${last.userdataExitCode}`);
|
|
927
|
+
}
|
|
928
|
+
return last;
|
|
929
|
+
}
|
|
810
930
|
await sleep(intervalMs);
|
|
811
931
|
}
|
|
812
932
|
throw new Error(
|
|
@@ -838,6 +958,25 @@ var VM = class {
|
|
|
838
958
|
async restore() {
|
|
839
959
|
await this.transport.request("POST", `/vm/${encodeURIComponent(this.hostname)}/restore`);
|
|
840
960
|
}
|
|
961
|
+
/**
|
|
962
|
+
* Commit a stopped persistent VM disk into an immutable parent.
|
|
963
|
+
*/
|
|
964
|
+
async commit(opts = {}) {
|
|
965
|
+
const cacheKey = opts.cacheKey?.trim();
|
|
966
|
+
const tags = opts.tags && opts.tags.length > 0 ? opts.tags : void 0;
|
|
967
|
+
const labels = opts.labels && Object.keys(opts.labels).length > 0 ? opts.labels : void 0;
|
|
968
|
+
const body = tags !== void 0 || labels !== void 0 || cacheKey ? {
|
|
969
|
+
...tags !== void 0 && { tags },
|
|
970
|
+
...labels !== void 0 && { labels },
|
|
971
|
+
...cacheKey && { cache_key: cacheKey }
|
|
972
|
+
} : void 0;
|
|
973
|
+
const wire = await this.transport.request(
|
|
974
|
+
"POST",
|
|
975
|
+
`/vm/${encodeURIComponent(this.hostname)}/commit`,
|
|
976
|
+
body
|
|
977
|
+
);
|
|
978
|
+
return new CommittedVM(this.transport, this.hostGroup, vmCommitFromWire(wire));
|
|
979
|
+
}
|
|
841
980
|
// --- port forwarding ---------------------------------------------------
|
|
842
981
|
/**
|
|
843
982
|
* Open one or more port forwards from the host to this VM. Each spec follows
|
|
@@ -957,6 +1096,32 @@ function sleep(ms) {
|
|
|
957
1096
|
function errMsg(e) {
|
|
958
1097
|
return e instanceof Error ? e.message : String(e);
|
|
959
1098
|
}
|
|
1099
|
+
async function forkPath(transport, commitId, opts) {
|
|
1100
|
+
const id = validateCommitId(commitId);
|
|
1101
|
+
const q = new URLSearchParams();
|
|
1102
|
+
q.set("wait", "agent");
|
|
1103
|
+
if (opts.waitTimeoutSec !== void 0 && opts.waitTimeoutSec > 0) {
|
|
1104
|
+
q.set("timeout", `${opts.waitTimeoutSec}s`);
|
|
1105
|
+
}
|
|
1106
|
+
const query = q.toString() ? `?${q.toString()}` : "";
|
|
1107
|
+
const body = opts.network !== void 0 || (opts.tags?.length ?? 0) > 0 ? {
|
|
1108
|
+
...opts.network !== void 0 && { network: opts.network },
|
|
1109
|
+
...(opts.tags?.length ?? 0) > 0 && { tags: opts.tags }
|
|
1110
|
+
} : void 0;
|
|
1111
|
+
const wire = await transport.request(
|
|
1112
|
+
"POST",
|
|
1113
|
+
`/vm/commits/${encodeURIComponent(id)}/fork${query}`,
|
|
1114
|
+
body
|
|
1115
|
+
);
|
|
1116
|
+
return vmForkFromWire(wire);
|
|
1117
|
+
}
|
|
1118
|
+
function validateCommitId(commitId) {
|
|
1119
|
+
const value = commitId.trim();
|
|
1120
|
+
if (!value || value === "." || value === ".." || value.includes("..") || value.includes("/") || value.includes("\\") || value.includes("\0")) {
|
|
1121
|
+
throw new Error(`invalid commit ID ${JSON.stringify(value)}`);
|
|
1122
|
+
}
|
|
1123
|
+
return value;
|
|
1124
|
+
}
|
|
960
1125
|
var VMBg = class {
|
|
961
1126
|
constructor(transport, hostname) {
|
|
962
1127
|
this.transport = transport;
|
|
@@ -1215,6 +1380,54 @@ var VMsAPI = class {
|
|
|
1215
1380
|
return createVMResFromWire(wire);
|
|
1216
1381
|
}
|
|
1217
1382
|
};
|
|
1383
|
+
var CommitsAPI = class {
|
|
1384
|
+
constructor(transport) {
|
|
1385
|
+
this.transport = transport;
|
|
1386
|
+
}
|
|
1387
|
+
transport;
|
|
1388
|
+
async list(opts = {}) {
|
|
1389
|
+
const qs = new URLSearchParams();
|
|
1390
|
+
for (const tag of opts.tags ?? []) {
|
|
1391
|
+
const value = tag.trim();
|
|
1392
|
+
if (value) qs.append("tag", value);
|
|
1393
|
+
}
|
|
1394
|
+
const cacheKey = opts.cacheKey?.trim();
|
|
1395
|
+
const source = opts.source?.trim();
|
|
1396
|
+
const mode = opts.mode?.trim();
|
|
1397
|
+
if (cacheKey) qs.set("cache_key", cacheKey);
|
|
1398
|
+
if (source) qs.set("source", source);
|
|
1399
|
+
if (mode) qs.set("mode", mode);
|
|
1400
|
+
const encoded = qs.toString();
|
|
1401
|
+
const query = encoded ? `?${encoded}` : "";
|
|
1402
|
+
const wire = await this.transport.request("GET", `/vm/commits${query}`);
|
|
1403
|
+
return (wire ?? []).map(vmCommitInfoFromWire);
|
|
1404
|
+
}
|
|
1405
|
+
async delete(commitId) {
|
|
1406
|
+
const id = validateCommitId2(commitId);
|
|
1407
|
+
const wire = await this.transport.request(
|
|
1408
|
+
"DELETE",
|
|
1409
|
+
`/vm/commits/${encodeURIComponent(id)}`
|
|
1410
|
+
);
|
|
1411
|
+
return vmCommitDeleteFromWire(wire);
|
|
1412
|
+
}
|
|
1413
|
+
async fork(commitId, opts = {}) {
|
|
1414
|
+
const id = validateCommitId2(commitId);
|
|
1415
|
+
const qs = new URLSearchParams({ wait: "agent" });
|
|
1416
|
+
if (opts.waitTimeoutSec !== void 0 && opts.waitTimeoutSec > 0) {
|
|
1417
|
+
qs.set("timeout", `${opts.waitTimeoutSec}s`);
|
|
1418
|
+
}
|
|
1419
|
+
const body = opts.network !== void 0 || (opts.tags?.length ?? 0) > 0 ? {
|
|
1420
|
+
...opts.network !== void 0 && { network: opts.network },
|
|
1421
|
+
...(opts.tags?.length ?? 0) > 0 && { tags: opts.tags }
|
|
1422
|
+
} : void 0;
|
|
1423
|
+
const wire = await this.transport.request(
|
|
1424
|
+
"POST",
|
|
1425
|
+
`/vm/commits/${encodeURIComponent(id)}/fork?${qs.toString()}`,
|
|
1426
|
+
body
|
|
1427
|
+
);
|
|
1428
|
+
return vmForkFromWire(wire);
|
|
1429
|
+
}
|
|
1430
|
+
};
|
|
1218
1431
|
var SecretsAPI = class {
|
|
1219
1432
|
constructor(transport) {
|
|
1220
1433
|
this.transport = transport;
|
|
@@ -1261,18 +1474,184 @@ function buildListQuery(opts) {
|
|
|
1261
1474
|
const s = qs.toString();
|
|
1262
1475
|
return s ? `?${s}` : "";
|
|
1263
1476
|
}
|
|
1477
|
+
function validateCommitId2(commitId) {
|
|
1478
|
+
const value = commitId.trim();
|
|
1479
|
+
if (!value || value === "." || value === ".." || value.includes("..") || value.includes("/") || value.includes("\\") || value.includes("\0")) {
|
|
1480
|
+
throw new Error(`invalid commit ID ${JSON.stringify(value)}`);
|
|
1481
|
+
}
|
|
1482
|
+
return value;
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
// src/proxy.ts
|
|
1486
|
+
var ProxySecretBearer = "bearer";
|
|
1487
|
+
var ProxySecretBasic = "basic";
|
|
1488
|
+
var ProxySecretOAuthClientCredentials = "oauth-client-creds";
|
|
1489
|
+
function clientFromWire(w) {
|
|
1490
|
+
return { name: w.name, createdAt: w.created_at };
|
|
1491
|
+
}
|
|
1492
|
+
function clientCreatedFromWire(w) {
|
|
1493
|
+
return { name: w.name, token: w.token, createdAt: w.created_at };
|
|
1494
|
+
}
|
|
1495
|
+
function secretFromWire2(w) {
|
|
1496
|
+
const out = { name: w.name, host: w.host, createdAt: w.created_at };
|
|
1497
|
+
if (w.type) out.type = w.type;
|
|
1498
|
+
return out;
|
|
1499
|
+
}
|
|
1500
|
+
function ruleFromWire(w) {
|
|
1501
|
+
const out = { host: w.host };
|
|
1502
|
+
if (w.secret) out.secret = w.secret;
|
|
1503
|
+
if (w.methods && w.methods.length > 0) out.methods = w.methods;
|
|
1504
|
+
if (w.paths && w.paths.length > 0) out.paths = w.paths;
|
|
1505
|
+
if (w.expires && w.expires !== "0001-01-01T00:00:00Z") out.expires = w.expires;
|
|
1506
|
+
if (w.passthrough) out.passthrough = w.passthrough;
|
|
1507
|
+
return out;
|
|
1508
|
+
}
|
|
1509
|
+
var ProxyAPI = class {
|
|
1510
|
+
constructor(transport) {
|
|
1511
|
+
this.transport = transport;
|
|
1512
|
+
this.clients = new ProxyClientsAPI(transport);
|
|
1513
|
+
this.secrets = new ProxySecretsAPI(transport);
|
|
1514
|
+
this.allows = new ProxyAllowsAPI(transport);
|
|
1515
|
+
}
|
|
1516
|
+
transport;
|
|
1517
|
+
clients;
|
|
1518
|
+
secrets;
|
|
1519
|
+
allows;
|
|
1520
|
+
};
|
|
1521
|
+
var ProxyClientsAPI = class {
|
|
1522
|
+
constructor(transport) {
|
|
1523
|
+
this.transport = transport;
|
|
1524
|
+
}
|
|
1525
|
+
transport;
|
|
1526
|
+
/** Mint a new proxy client. The returned token is shown once. */
|
|
1527
|
+
async create(name, opts = {}) {
|
|
1528
|
+
const body = { name };
|
|
1529
|
+
if (opts.token) body.token = opts.token;
|
|
1530
|
+
const wire = await this.transport.request(
|
|
1531
|
+
"POST",
|
|
1532
|
+
"/proxy/v1/clients",
|
|
1533
|
+
body
|
|
1534
|
+
);
|
|
1535
|
+
return clientCreatedFromWire(wire);
|
|
1536
|
+
}
|
|
1537
|
+
async list() {
|
|
1538
|
+
const wire = await this.transport.request("GET", "/proxy/v1/clients");
|
|
1539
|
+
return (wire ?? []).map(clientFromWire);
|
|
1540
|
+
}
|
|
1541
|
+
/**
|
|
1542
|
+
* Revoke the token, drop every allow rule the client owned, and
|
|
1543
|
+
* remove the client.
|
|
1544
|
+
*/
|
|
1545
|
+
async delete(name) {
|
|
1546
|
+
await this.transport.request("DELETE", `/proxy/v1/clients/${encodeURIComponent(name)}`);
|
|
1547
|
+
}
|
|
1548
|
+
/** List a client's allow rules in declaration order (first-match-wins). */
|
|
1549
|
+
async rules(name) {
|
|
1550
|
+
const wire = await this.transport.request(
|
|
1551
|
+
"GET",
|
|
1552
|
+
`/proxy/v1/clients/${encodeURIComponent(name)}`
|
|
1553
|
+
);
|
|
1554
|
+
return (wire ?? []).map(ruleFromWire);
|
|
1555
|
+
}
|
|
1556
|
+
};
|
|
1557
|
+
var ProxySecretsAPI = class {
|
|
1558
|
+
constructor(transport) {
|
|
1559
|
+
this.transport = transport;
|
|
1560
|
+
}
|
|
1561
|
+
transport;
|
|
1562
|
+
async create(req) {
|
|
1563
|
+
const body = {
|
|
1564
|
+
name: req.name,
|
|
1565
|
+
host: req.host,
|
|
1566
|
+
value: req.value
|
|
1567
|
+
};
|
|
1568
|
+
if (req.type) body.type = req.type;
|
|
1569
|
+
await this.transport.request("POST", "/proxy/v1/secrets", body);
|
|
1570
|
+
}
|
|
1571
|
+
async list() {
|
|
1572
|
+
const wire = await this.transport.request("GET", "/proxy/v1/secrets");
|
|
1573
|
+
return (wire ?? []).map(secretFromWire2);
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* Remove a secret. Allow rules that reference it stop matching until
|
|
1577
|
+
* the secret is recreated or the rule is rewritten.
|
|
1578
|
+
*/
|
|
1579
|
+
async delete(name) {
|
|
1580
|
+
await this.transport.request("DELETE", `/proxy/v1/secrets/${encodeURIComponent(name)}`);
|
|
1581
|
+
}
|
|
1582
|
+
};
|
|
1583
|
+
var ProxyAllowsAPI = class {
|
|
1584
|
+
constructor(transport) {
|
|
1585
|
+
this.transport = transport;
|
|
1586
|
+
}
|
|
1587
|
+
transport;
|
|
1588
|
+
/** Add an allow rule. Returns the resolved rule with absolute `expires`. */
|
|
1589
|
+
async add(req) {
|
|
1590
|
+
const body = {
|
|
1591
|
+
client: req.client,
|
|
1592
|
+
host: req.host
|
|
1593
|
+
};
|
|
1594
|
+
if (req.secret) body.secret = req.secret;
|
|
1595
|
+
if (req.methods && req.methods.length > 0) body.methods = req.methods;
|
|
1596
|
+
if (req.paths && req.paths.length > 0) body.paths = req.paths;
|
|
1597
|
+
if (req.ttlSeconds && req.ttlSeconds > 0) body.ttl_seconds = req.ttlSeconds;
|
|
1598
|
+
if (req.passthrough) body.passthrough = true;
|
|
1599
|
+
const wire = await this.transport.request(
|
|
1600
|
+
"POST",
|
|
1601
|
+
"/proxy/v1/allows",
|
|
1602
|
+
body
|
|
1603
|
+
);
|
|
1604
|
+
return ruleFromWire(wire);
|
|
1605
|
+
}
|
|
1606
|
+
/**
|
|
1607
|
+
* Host-bulk revoke: removes **every** rule on the client whose host
|
|
1608
|
+
* matches. For surgical removal of one rule among siblings on the
|
|
1609
|
+
* same host (e.g. several path-scoped rules on `github.com`), use
|
|
1610
|
+
* `removeByTuple` instead.
|
|
1611
|
+
*/
|
|
1612
|
+
async remove(client, host) {
|
|
1613
|
+
await this.transport.request(
|
|
1614
|
+
"DELETE",
|
|
1615
|
+
`/proxy/v1/allows/${encodeURIComponent(client)}/${encodeURIComponent(host)}`
|
|
1616
|
+
);
|
|
1617
|
+
}
|
|
1618
|
+
/**
|
|
1619
|
+
* Surgical revoke: removes the single rule whose
|
|
1620
|
+
* (host, methods, paths, passthrough) tuple matches the request.
|
|
1621
|
+
* Pass exactly the same fields you used at create time. Method and
|
|
1622
|
+
* host casing are normalised server-side, so `"GET"` / `"get"` and
|
|
1623
|
+
* `"github.com"` / `"GITHUB.COM"` all match the same stored rule.
|
|
1624
|
+
*
|
|
1625
|
+
* Returns 404 (surfaced as a SlicerAPIError) when no rule matches.
|
|
1626
|
+
*/
|
|
1627
|
+
async removeByTuple(req) {
|
|
1628
|
+
const body = {
|
|
1629
|
+
client: req.client,
|
|
1630
|
+
host: req.host
|
|
1631
|
+
};
|
|
1632
|
+
if (req.secret) body.secret = req.secret;
|
|
1633
|
+
if (req.methods && req.methods.length > 0) body.methods = req.methods;
|
|
1634
|
+
if (req.paths && req.paths.length > 0) body.paths = req.paths;
|
|
1635
|
+
if (req.passthrough) body.passthrough = true;
|
|
1636
|
+
await this.transport.request("POST", "/proxy/v1/allows/revoke", body);
|
|
1637
|
+
}
|
|
1638
|
+
};
|
|
1264
1639
|
|
|
1265
1640
|
// src/client.ts
|
|
1266
1641
|
var SlicerClient = class _SlicerClient {
|
|
1267
1642
|
transport;
|
|
1268
1643
|
hostGroups;
|
|
1269
1644
|
vms;
|
|
1645
|
+
commits;
|
|
1270
1646
|
secrets;
|
|
1647
|
+
proxy;
|
|
1271
1648
|
constructor(opts) {
|
|
1272
1649
|
this.transport = new TransportClient(opts);
|
|
1273
1650
|
this.hostGroups = new HostGroupsAPI(this.transport);
|
|
1274
1651
|
this.vms = new VMsAPI(this.transport);
|
|
1652
|
+
this.commits = new CommitsAPI(this.transport);
|
|
1275
1653
|
this.secrets = new SecretsAPI(this.transport);
|
|
1654
|
+
this.proxy = new ProxyAPI(this.transport);
|
|
1276
1655
|
}
|
|
1277
1656
|
static fromEnv(overrides = {}) {
|
|
1278
1657
|
const baseURL = overrides.baseURL ?? process.env.SLICER_URL;
|
|
@@ -1429,6 +1808,8 @@ var SlicerShellSession = class {
|
|
|
1429
1808
|
}
|
|
1430
1809
|
};
|
|
1431
1810
|
|
|
1811
|
+
exports.CommitsAPI = CommitsAPI;
|
|
1812
|
+
exports.CommittedVM = CommittedVM;
|
|
1432
1813
|
exports.ExecStdioBase64 = ExecStdioBase64;
|
|
1433
1814
|
exports.ExecStdioText = ExecStdioText;
|
|
1434
1815
|
exports.FRAME_TYPE_DATA = FRAME_TYPE_DATA;
|
|
@@ -1441,6 +1822,13 @@ exports.GiB = GiB;
|
|
|
1441
1822
|
exports.HostGroupsAPI = HostGroupsAPI;
|
|
1442
1823
|
exports.MiB = MiB;
|
|
1443
1824
|
exports.NonRootUser = NonRootUser;
|
|
1825
|
+
exports.ProxyAPI = ProxyAPI;
|
|
1826
|
+
exports.ProxyAllowsAPI = ProxyAllowsAPI;
|
|
1827
|
+
exports.ProxyClientsAPI = ProxyClientsAPI;
|
|
1828
|
+
exports.ProxySecretBasic = ProxySecretBasic;
|
|
1829
|
+
exports.ProxySecretBearer = ProxySecretBearer;
|
|
1830
|
+
exports.ProxySecretOAuthClientCredentials = ProxySecretOAuthClientCredentials;
|
|
1831
|
+
exports.ProxySecretsAPI = ProxySecretsAPI;
|
|
1444
1832
|
exports.SecretExistsError = SecretExistsError;
|
|
1445
1833
|
exports.SecretsAPI = SecretsAPI;
|
|
1446
1834
|
exports.SlicerAPIError = SlicerAPIError;
|