@arker-ai/sdk 0.6.3 → 0.7.0
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/{chunk-7BHPVQNG.js → chunk-4NHUAVXK.js} +132 -10
- package/dist/{chunk-35IEV6BU.js → chunk-YFJEL7PF.js} +1 -1
- package/dist/cli.cjs +132 -10
- package/dist/cli.js +1 -1
- package/dist/daytona.cjs +132 -10
- package/dist/daytona.js +2 -2
- package/dist/e2b.cjs +132 -10
- package/dist/e2b.js +2 -2
- package/dist/index.cjs +132 -10
- package/dist/index.d.cts +103 -2
- package/dist/index.d.ts +103 -2
- package/dist/index.js +1 -1
- package/dist/modal.cjs +132 -10
- package/dist/modal.js +2 -2
- package/package.json +2 -2
package/dist/e2b.cjs
CHANGED
|
@@ -167,6 +167,7 @@ var Arker = class {
|
|
|
167
167
|
provider;
|
|
168
168
|
apiKey;
|
|
169
169
|
fetchImpl;
|
|
170
|
+
http2;
|
|
170
171
|
retry;
|
|
171
172
|
constructor(opts = {}) {
|
|
172
173
|
const apiKey = opts.apiKey ?? env("ARKER_API_KEY") ?? env("AUTH_KEY");
|
|
@@ -188,6 +189,7 @@ var Arker = class {
|
|
|
188
189
|
this.region = region ? normalizeRegion(region) : void 0;
|
|
189
190
|
this.provider = effectiveProvider;
|
|
190
191
|
this.fetchImpl = opts.fetch ?? globalThis.fetch;
|
|
192
|
+
this.http2 = opts.fetch === void 0;
|
|
191
193
|
this.retry = normalizeRetry(opts.retry);
|
|
192
194
|
if (!this.fetchImpl) throw new Error("fetch is required in this runtime");
|
|
193
195
|
}
|
|
@@ -248,7 +250,10 @@ var Arker = class {
|
|
|
248
250
|
egress: src.egress ?? null,
|
|
249
251
|
disk: src.disk ?? true,
|
|
250
252
|
durable: src.durable ?? null,
|
|
251
|
-
resources
|
|
253
|
+
resources,
|
|
254
|
+
// ARK-125: omit to inherit the source's policy; pass a doc to override
|
|
255
|
+
// (an empty `{ policies: [] }` clears to allow-all, NOT inherit).
|
|
256
|
+
policies: src.policies ?? null
|
|
252
257
|
};
|
|
253
258
|
const useBurst = sourceOrgId === ARKER_ORG_ID && src.sourceVmName !== void 0 && isBurstRef(src.sourceVmName);
|
|
254
259
|
const baseUrl = useBurst && this.burstBaseUrl ? this.burstBaseUrl : this.baseUrl;
|
|
@@ -343,30 +348,29 @@ var Arker = class {
|
|
|
343
348
|
if (value !== void 0) headers[key] = value;
|
|
344
349
|
}
|
|
345
350
|
}
|
|
346
|
-
|
|
351
|
+
let requestBody;
|
|
347
352
|
if (body !== void 0) {
|
|
348
353
|
headers["content-type"] = "application/json";
|
|
349
|
-
|
|
354
|
+
requestBody = JSON.stringify(withoutUndefined(body));
|
|
350
355
|
}
|
|
351
356
|
let lastStatus = 0;
|
|
352
357
|
let lastText = "";
|
|
353
358
|
let lastError;
|
|
354
359
|
for (let attempt = 0; attempt < this.retry.attempts; attempt++) {
|
|
355
360
|
try {
|
|
356
|
-
const
|
|
357
|
-
const text = await response.text();
|
|
361
|
+
const { status, ok, text } = await sendRequest(url, { method, headers, body: requestBody }, this.fetchImpl, this.http2);
|
|
358
362
|
const payload = parseJson(text);
|
|
359
363
|
const parsedError = extractError(payload);
|
|
360
|
-
lastStatus =
|
|
364
|
+
lastStatus = status;
|
|
361
365
|
lastText = text;
|
|
362
366
|
lastError = parsedError;
|
|
363
|
-
if (isRetryable(
|
|
367
|
+
if (isRetryable(status, parsedError) && attempt < this.retry.attempts - 1) {
|
|
364
368
|
await sleep(retryDelay(this.retry, attempt));
|
|
365
369
|
continue;
|
|
366
370
|
}
|
|
367
|
-
if (parsedError) throw new ArkerError(parsedError.code, parsedError.message,
|
|
368
|
-
if (!
|
|
369
|
-
throw new ArkerError("internal", lastText.slice(0, 300) || `HTTP ${
|
|
371
|
+
if (parsedError) throw new ArkerError(parsedError.code, parsedError.message, status);
|
|
372
|
+
if (!ok) {
|
|
373
|
+
throw new ArkerError("internal", lastText.slice(0, 300) || `HTTP ${status}`, status);
|
|
370
374
|
}
|
|
371
375
|
return payload;
|
|
372
376
|
} catch (error) {
|
|
@@ -578,6 +582,32 @@ var VM = class _VM {
|
|
|
578
582
|
async delete() {
|
|
579
583
|
return this._client._request("DELETE", vmPath(this.id), void 0, this.baseUrl);
|
|
580
584
|
}
|
|
585
|
+
// ── ARK-125 egress policy ────────────────────────────────────────
|
|
586
|
+
/**
|
|
587
|
+
* Read this VM's outbound egress policy document (ARK-125). Returns an
|
|
588
|
+
* empty doc (`{}`) when no policy is set.
|
|
589
|
+
*/
|
|
590
|
+
async getPolicies() {
|
|
591
|
+
return this._client._request("GET", `${vmPath(this.id)}/policies`, void 0, this.baseUrl);
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Replace this VM's outbound egress policy with `doc` — an ordered,
|
|
595
|
+
* first-match-wins rule list. An empty doc (`{}` or `{ policies: [] }`)
|
|
596
|
+
* clears the policy to allow-all. Returns the stored policy plus the
|
|
597
|
+
* domains it escalates to MITM and any degrade warnings.
|
|
598
|
+
*
|
|
599
|
+
* await vm.setPolicies({
|
|
600
|
+
* policies: [
|
|
601
|
+
* { type: "network.outbound",
|
|
602
|
+
* match: { domains: ["github.com"], ports: [443] },
|
|
603
|
+
* action: "allow" },
|
|
604
|
+
* { type: "network.outbound", action: "deny" },
|
|
605
|
+
* ],
|
|
606
|
+
* });
|
|
607
|
+
*/
|
|
608
|
+
async setPolicies(doc) {
|
|
609
|
+
return this._client._request("PUT", `${vmPath(this.id)}/policies`, doc, this.baseUrl);
|
|
610
|
+
}
|
|
581
611
|
// ── Syncs: bindings of a filesystem into this VM at a path ────────
|
|
582
612
|
async listSyncs(opts = {}) {
|
|
583
613
|
return this._client._request("GET", buildQuery(`${vmPath(this.id)}/syncs`, {
|
|
@@ -629,6 +659,20 @@ var VM = class _VM {
|
|
|
629
659
|
async deleteSession(sessionId) {
|
|
630
660
|
return this._client._request("DELETE", `${vmPath(this.id)}/sessions/${pathSegment(sessionId)}`, void 0, this.baseUrl);
|
|
631
661
|
}
|
|
662
|
+
/**
|
|
663
|
+
* Update a session via `PATCH /v1/vms/{id}/sessions/{sid}`: resize its PTY
|
|
664
|
+
* (`cols`/`rows`) and/or set the idle `timeoutSecs`. Works whether or not a
|
|
665
|
+
* PTY is currently attached — the REST equivalent of {@link PtyConnection.resize}
|
|
666
|
+
* (which sends an in-band control frame on the live WebSocket).
|
|
667
|
+
*/
|
|
668
|
+
async updateSession(sessionId, update) {
|
|
669
|
+
return this._client._request(
|
|
670
|
+
"PATCH",
|
|
671
|
+
`${vmPath(this.id)}/sessions/${pathSegment(sessionId)}`,
|
|
672
|
+
{ cols: update.cols, rows: update.rows, timeout_secs: update.timeoutSecs },
|
|
673
|
+
this.baseUrl
|
|
674
|
+
);
|
|
675
|
+
}
|
|
632
676
|
async connectPty(options = {}) {
|
|
633
677
|
const sessionId = options.sessionId ?? sessionIdFrom(await this.createSession());
|
|
634
678
|
const useTicket = options.useTicket ?? !isNodeRuntime();
|
|
@@ -1040,6 +1084,84 @@ function base64ToBytes(text) {
|
|
|
1040
1084
|
function bufferConstructor() {
|
|
1041
1085
|
return globalThis.Buffer;
|
|
1042
1086
|
}
|
|
1087
|
+
var http2Module;
|
|
1088
|
+
function loadHttp2() {
|
|
1089
|
+
return http2Module ??= (async () => {
|
|
1090
|
+
const proc = globalThis.process;
|
|
1091
|
+
if (!proc?.versions?.node) return null;
|
|
1092
|
+
try {
|
|
1093
|
+
return await import(
|
|
1094
|
+
/* webpackIgnore: true */
|
|
1095
|
+
/* @vite-ignore */
|
|
1096
|
+
"http2"
|
|
1097
|
+
);
|
|
1098
|
+
} catch {
|
|
1099
|
+
return null;
|
|
1100
|
+
}
|
|
1101
|
+
})();
|
|
1102
|
+
}
|
|
1103
|
+
var HTTP2_REQUEST_TIMEOUT_MS = 12e4;
|
|
1104
|
+
var Http2Connection = class {
|
|
1105
|
+
confirmed = false;
|
|
1106
|
+
streams = 0;
|
|
1107
|
+
session;
|
|
1108
|
+
constructor(http2, origin) {
|
|
1109
|
+
this.session = http2.connect(origin);
|
|
1110
|
+
this.session.on("error", () => {
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
get closed() {
|
|
1114
|
+
return this.session.closed || this.session.destroyed;
|
|
1115
|
+
}
|
|
1116
|
+
request(method, path, headers, body) {
|
|
1117
|
+
if (this.streams === 0) this.session.ref();
|
|
1118
|
+
this.streams++;
|
|
1119
|
+
return new Promise((resolve, reject) => {
|
|
1120
|
+
const stream = this.session.request({ ...headers, ":method": method, ":path": path });
|
|
1121
|
+
let status = 0;
|
|
1122
|
+
let text = "";
|
|
1123
|
+
stream.setEncoding("utf8");
|
|
1124
|
+
stream.setTimeout(HTTP2_REQUEST_TIMEOUT_MS, () => stream.destroy(new Error("HTTP/2 request timed out")));
|
|
1125
|
+
stream.on("response", (responseHeaders) => {
|
|
1126
|
+
this.confirmed = true;
|
|
1127
|
+
status = Number(responseHeaders[":status"]) || 0;
|
|
1128
|
+
});
|
|
1129
|
+
stream.on("data", (chunk) => {
|
|
1130
|
+
text += chunk;
|
|
1131
|
+
});
|
|
1132
|
+
stream.on("end", () => resolve({ status, ok: status >= 200 && status < 300, text }));
|
|
1133
|
+
stream.on("error", reject);
|
|
1134
|
+
stream.end(body);
|
|
1135
|
+
}).finally(() => {
|
|
1136
|
+
if (--this.streams === 0) this.session.unref();
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
var http2Connections = /* @__PURE__ */ new Map();
|
|
1141
|
+
async function sendRequest(url, init, fetchImpl, http2Enabled) {
|
|
1142
|
+
if (http2Enabled) {
|
|
1143
|
+
const http2 = await loadHttp2();
|
|
1144
|
+
if (http2) {
|
|
1145
|
+
const { origin, pathname, search } = new URL(url);
|
|
1146
|
+
const cached = http2Connections.get(origin);
|
|
1147
|
+
if (cached !== null) {
|
|
1148
|
+
let connection = cached;
|
|
1149
|
+
if (!connection || connection.closed) {
|
|
1150
|
+
connection = new Http2Connection(http2, origin);
|
|
1151
|
+
http2Connections.set(origin, connection);
|
|
1152
|
+
}
|
|
1153
|
+
try {
|
|
1154
|
+
return await connection.request(init.method, `${pathname}${search}`, init.headers, init.body);
|
|
1155
|
+
} catch (error) {
|
|
1156
|
+
if (connection.confirmed) throw error;
|
|
1157
|
+
http2Connections.set(origin, null);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
const response = await fetchImpl(url, init);
|
|
1163
|
+
return { status: response.status, ok: response.ok, text: await response.text() };
|
|
1164
|
+
}
|
|
1043
1165
|
|
|
1044
1166
|
// src/compat/arker-provider.ts
|
|
1045
1167
|
var DEFAULT_REGION = "aws-us-east-1";
|
package/dist/e2b.js
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
createCompatSdk,
|
|
4
4
|
guardUnsupported,
|
|
5
5
|
resolveTimeout
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-YFJEL7PF.js";
|
|
7
|
+
import "./chunk-4NHUAVXK.js";
|
|
8
8
|
|
|
9
9
|
// src/e2b.ts
|
|
10
10
|
import { e2b as createE2BProvider } from "@computesdk/e2b";
|
package/dist/index.cjs
CHANGED
|
@@ -94,6 +94,7 @@ var Arker = class {
|
|
|
94
94
|
provider;
|
|
95
95
|
apiKey;
|
|
96
96
|
fetchImpl;
|
|
97
|
+
http2;
|
|
97
98
|
retry;
|
|
98
99
|
constructor(opts = {}) {
|
|
99
100
|
const apiKey = opts.apiKey ?? env("ARKER_API_KEY") ?? env("AUTH_KEY");
|
|
@@ -115,6 +116,7 @@ var Arker = class {
|
|
|
115
116
|
this.region = region ? normalizeRegion(region) : void 0;
|
|
116
117
|
this.provider = effectiveProvider;
|
|
117
118
|
this.fetchImpl = opts.fetch ?? globalThis.fetch;
|
|
119
|
+
this.http2 = opts.fetch === void 0;
|
|
118
120
|
this.retry = normalizeRetry(opts.retry);
|
|
119
121
|
if (!this.fetchImpl) throw new Error("fetch is required in this runtime");
|
|
120
122
|
}
|
|
@@ -175,7 +177,10 @@ var Arker = class {
|
|
|
175
177
|
egress: src.egress ?? null,
|
|
176
178
|
disk: src.disk ?? true,
|
|
177
179
|
durable: src.durable ?? null,
|
|
178
|
-
resources
|
|
180
|
+
resources,
|
|
181
|
+
// ARK-125: omit to inherit the source's policy; pass a doc to override
|
|
182
|
+
// (an empty `{ policies: [] }` clears to allow-all, NOT inherit).
|
|
183
|
+
policies: src.policies ?? null
|
|
179
184
|
};
|
|
180
185
|
const useBurst = sourceOrgId === ARKER_ORG_ID && src.sourceVmName !== void 0 && isBurstRef(src.sourceVmName);
|
|
181
186
|
const baseUrl = useBurst && this.burstBaseUrl ? this.burstBaseUrl : this.baseUrl;
|
|
@@ -270,30 +275,29 @@ var Arker = class {
|
|
|
270
275
|
if (value !== void 0) headers[key] = value;
|
|
271
276
|
}
|
|
272
277
|
}
|
|
273
|
-
|
|
278
|
+
let requestBody;
|
|
274
279
|
if (body !== void 0) {
|
|
275
280
|
headers["content-type"] = "application/json";
|
|
276
|
-
|
|
281
|
+
requestBody = JSON.stringify(withoutUndefined(body));
|
|
277
282
|
}
|
|
278
283
|
let lastStatus = 0;
|
|
279
284
|
let lastText = "";
|
|
280
285
|
let lastError;
|
|
281
286
|
for (let attempt = 0; attempt < this.retry.attempts; attempt++) {
|
|
282
287
|
try {
|
|
283
|
-
const
|
|
284
|
-
const text = await response.text();
|
|
288
|
+
const { status, ok, text } = await sendRequest(url, { method, headers, body: requestBody }, this.fetchImpl, this.http2);
|
|
285
289
|
const payload = parseJson(text);
|
|
286
290
|
const parsedError = extractError(payload);
|
|
287
|
-
lastStatus =
|
|
291
|
+
lastStatus = status;
|
|
288
292
|
lastText = text;
|
|
289
293
|
lastError = parsedError;
|
|
290
|
-
if (isRetryable(
|
|
294
|
+
if (isRetryable(status, parsedError) && attempt < this.retry.attempts - 1) {
|
|
291
295
|
await sleep(retryDelay(this.retry, attempt));
|
|
292
296
|
continue;
|
|
293
297
|
}
|
|
294
|
-
if (parsedError) throw new ArkerError(parsedError.code, parsedError.message,
|
|
295
|
-
if (!
|
|
296
|
-
throw new ArkerError("internal", lastText.slice(0, 300) || `HTTP ${
|
|
298
|
+
if (parsedError) throw new ArkerError(parsedError.code, parsedError.message, status);
|
|
299
|
+
if (!ok) {
|
|
300
|
+
throw new ArkerError("internal", lastText.slice(0, 300) || `HTTP ${status}`, status);
|
|
297
301
|
}
|
|
298
302
|
return payload;
|
|
299
303
|
} catch (error) {
|
|
@@ -505,6 +509,32 @@ var VM = class _VM {
|
|
|
505
509
|
async delete() {
|
|
506
510
|
return this._client._request("DELETE", vmPath(this.id), void 0, this.baseUrl);
|
|
507
511
|
}
|
|
512
|
+
// ── ARK-125 egress policy ────────────────────────────────────────
|
|
513
|
+
/**
|
|
514
|
+
* Read this VM's outbound egress policy document (ARK-125). Returns an
|
|
515
|
+
* empty doc (`{}`) when no policy is set.
|
|
516
|
+
*/
|
|
517
|
+
async getPolicies() {
|
|
518
|
+
return this._client._request("GET", `${vmPath(this.id)}/policies`, void 0, this.baseUrl);
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Replace this VM's outbound egress policy with `doc` — an ordered,
|
|
522
|
+
* first-match-wins rule list. An empty doc (`{}` or `{ policies: [] }`)
|
|
523
|
+
* clears the policy to allow-all. Returns the stored policy plus the
|
|
524
|
+
* domains it escalates to MITM and any degrade warnings.
|
|
525
|
+
*
|
|
526
|
+
* await vm.setPolicies({
|
|
527
|
+
* policies: [
|
|
528
|
+
* { type: "network.outbound",
|
|
529
|
+
* match: { domains: ["github.com"], ports: [443] },
|
|
530
|
+
* action: "allow" },
|
|
531
|
+
* { type: "network.outbound", action: "deny" },
|
|
532
|
+
* ],
|
|
533
|
+
* });
|
|
534
|
+
*/
|
|
535
|
+
async setPolicies(doc) {
|
|
536
|
+
return this._client._request("PUT", `${vmPath(this.id)}/policies`, doc, this.baseUrl);
|
|
537
|
+
}
|
|
508
538
|
// ── Syncs: bindings of a filesystem into this VM at a path ────────
|
|
509
539
|
async listSyncs(opts = {}) {
|
|
510
540
|
return this._client._request("GET", buildQuery(`${vmPath(this.id)}/syncs`, {
|
|
@@ -556,6 +586,20 @@ var VM = class _VM {
|
|
|
556
586
|
async deleteSession(sessionId) {
|
|
557
587
|
return this._client._request("DELETE", `${vmPath(this.id)}/sessions/${pathSegment(sessionId)}`, void 0, this.baseUrl);
|
|
558
588
|
}
|
|
589
|
+
/**
|
|
590
|
+
* Update a session via `PATCH /v1/vms/{id}/sessions/{sid}`: resize its PTY
|
|
591
|
+
* (`cols`/`rows`) and/or set the idle `timeoutSecs`. Works whether or not a
|
|
592
|
+
* PTY is currently attached — the REST equivalent of {@link PtyConnection.resize}
|
|
593
|
+
* (which sends an in-band control frame on the live WebSocket).
|
|
594
|
+
*/
|
|
595
|
+
async updateSession(sessionId, update) {
|
|
596
|
+
return this._client._request(
|
|
597
|
+
"PATCH",
|
|
598
|
+
`${vmPath(this.id)}/sessions/${pathSegment(sessionId)}`,
|
|
599
|
+
{ cols: update.cols, rows: update.rows, timeout_secs: update.timeoutSecs },
|
|
600
|
+
this.baseUrl
|
|
601
|
+
);
|
|
602
|
+
}
|
|
559
603
|
async connectPty(options = {}) {
|
|
560
604
|
const sessionId = options.sessionId ?? sessionIdFrom(await this.createSession());
|
|
561
605
|
const useTicket = options.useTicket ?? !isNodeRuntime();
|
|
@@ -967,6 +1011,84 @@ function base64ToBytes(text) {
|
|
|
967
1011
|
function bufferConstructor() {
|
|
968
1012
|
return globalThis.Buffer;
|
|
969
1013
|
}
|
|
1014
|
+
var http2Module;
|
|
1015
|
+
function loadHttp2() {
|
|
1016
|
+
return http2Module ??= (async () => {
|
|
1017
|
+
const proc = globalThis.process;
|
|
1018
|
+
if (!proc?.versions?.node) return null;
|
|
1019
|
+
try {
|
|
1020
|
+
return await import(
|
|
1021
|
+
/* webpackIgnore: true */
|
|
1022
|
+
/* @vite-ignore */
|
|
1023
|
+
"http2"
|
|
1024
|
+
);
|
|
1025
|
+
} catch {
|
|
1026
|
+
return null;
|
|
1027
|
+
}
|
|
1028
|
+
})();
|
|
1029
|
+
}
|
|
1030
|
+
var HTTP2_REQUEST_TIMEOUT_MS = 12e4;
|
|
1031
|
+
var Http2Connection = class {
|
|
1032
|
+
confirmed = false;
|
|
1033
|
+
streams = 0;
|
|
1034
|
+
session;
|
|
1035
|
+
constructor(http2, origin) {
|
|
1036
|
+
this.session = http2.connect(origin);
|
|
1037
|
+
this.session.on("error", () => {
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
get closed() {
|
|
1041
|
+
return this.session.closed || this.session.destroyed;
|
|
1042
|
+
}
|
|
1043
|
+
request(method, path, headers, body) {
|
|
1044
|
+
if (this.streams === 0) this.session.ref();
|
|
1045
|
+
this.streams++;
|
|
1046
|
+
return new Promise((resolve, reject) => {
|
|
1047
|
+
const stream = this.session.request({ ...headers, ":method": method, ":path": path });
|
|
1048
|
+
let status = 0;
|
|
1049
|
+
let text = "";
|
|
1050
|
+
stream.setEncoding("utf8");
|
|
1051
|
+
stream.setTimeout(HTTP2_REQUEST_TIMEOUT_MS, () => stream.destroy(new Error("HTTP/2 request timed out")));
|
|
1052
|
+
stream.on("response", (responseHeaders) => {
|
|
1053
|
+
this.confirmed = true;
|
|
1054
|
+
status = Number(responseHeaders[":status"]) || 0;
|
|
1055
|
+
});
|
|
1056
|
+
stream.on("data", (chunk) => {
|
|
1057
|
+
text += chunk;
|
|
1058
|
+
});
|
|
1059
|
+
stream.on("end", () => resolve({ status, ok: status >= 200 && status < 300, text }));
|
|
1060
|
+
stream.on("error", reject);
|
|
1061
|
+
stream.end(body);
|
|
1062
|
+
}).finally(() => {
|
|
1063
|
+
if (--this.streams === 0) this.session.unref();
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
var http2Connections = /* @__PURE__ */ new Map();
|
|
1068
|
+
async function sendRequest(url, init, fetchImpl, http2Enabled) {
|
|
1069
|
+
if (http2Enabled) {
|
|
1070
|
+
const http2 = await loadHttp2();
|
|
1071
|
+
if (http2) {
|
|
1072
|
+
const { origin, pathname, search } = new URL(url);
|
|
1073
|
+
const cached = http2Connections.get(origin);
|
|
1074
|
+
if (cached !== null) {
|
|
1075
|
+
let connection = cached;
|
|
1076
|
+
if (!connection || connection.closed) {
|
|
1077
|
+
connection = new Http2Connection(http2, origin);
|
|
1078
|
+
http2Connections.set(origin, connection);
|
|
1079
|
+
}
|
|
1080
|
+
try {
|
|
1081
|
+
return await connection.request(init.method, `${pathname}${search}`, init.headers, init.body);
|
|
1082
|
+
} catch (error) {
|
|
1083
|
+
if (connection.confirmed) throw error;
|
|
1084
|
+
http2Connections.set(origin, null);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
const response = await fetchImpl(url, init);
|
|
1090
|
+
return { status: response.status, ok: response.ok, text: await response.text() };
|
|
1091
|
+
}
|
|
970
1092
|
// Annotate the CommonJS export names for ESM import in node:
|
|
971
1093
|
0 && (module.exports = {
|
|
972
1094
|
ARKER_ORG_ID,
|
package/dist/index.d.cts
CHANGED
|
@@ -66,6 +66,62 @@ interface components {
|
|
|
66
66
|
durable?: boolean | null;
|
|
67
67
|
/** @description Resource shape for the new VM. */
|
|
68
68
|
resources?: components["schemas"]["VmResources"] | null;
|
|
69
|
+
/** @description ARK-125 outbound policy for the new VM. Omit (null) to inherit the source VM's policy, re-encrypted under the child's own key. Present (even an empty doc) replaces it: an empty doc clears to allow-all rather than inheriting. Distinct from `egress` (legacy NetworkPolicy) and `network` (inbound). */
|
|
70
|
+
policies?: components["schemas"]["PolicyDoc"] | null;
|
|
71
|
+
};
|
|
72
|
+
/** @description A VM's egress policy document (ARK-125): an ordered, first-match-wins rule list. Empty `policies` means no policy (allow-all). The engine default when no rule matches is DENY (fail-closed); an explicit catch-all `{ "type": "network.outbound", "action": "allow" }` rule expresses default-allow. */
|
|
73
|
+
PolicyDoc: {
|
|
74
|
+
policies?: components["schemas"]["PolicyEntry"][];
|
|
75
|
+
};
|
|
76
|
+
/** @description One policy rule. `match` AND's its present fields (absent ⇒ catch-all). */
|
|
77
|
+
PolicyEntry: {
|
|
78
|
+
/**
|
|
79
|
+
* @description Event family. Only network.outbound is supported; an unknown value is rejected with 400.
|
|
80
|
+
* @enum {string}
|
|
81
|
+
*/
|
|
82
|
+
type: "network.outbound";
|
|
83
|
+
match?: components["schemas"]["PolicyMatch"];
|
|
84
|
+
action: components["schemas"]["PolicyAction"];
|
|
85
|
+
};
|
|
86
|
+
/** @description Match criteria: present fields AND'd; list items OR'd. `ips` and `domains` are mutually exclusive. L4 fields = ports/ips/domains; L7 fields = methods/paths/headers/body_contains. A rule with any L7 field needs the MITM proxy (not built yet); until it ships an L7 rule degrades to its domain/L4 projection — allow → domain-allow, deny/rewrite → fail-closed deny. */
|
|
87
|
+
PolicyMatch: {
|
|
88
|
+
/** @description Single ports and/or inclusive [start, end] ranges, e.g. [80, 443, [1000, 2000]]. Empty/absent = any port. */
|
|
89
|
+
ports?: (number | number[])[];
|
|
90
|
+
/** @description IPs or CIDRs. */
|
|
91
|
+
ips?: string[];
|
|
92
|
+
/** @description Label-boundary suffix match: `github.com` matches `api.github.com`, not `evilgithub.com`. */
|
|
93
|
+
domains?: string[];
|
|
94
|
+
methods?: string[];
|
|
95
|
+
/** @description Full-segment path prefixes. */
|
|
96
|
+
paths?: string[];
|
|
97
|
+
/** @description Header name → any-of values (names AND'd, a name's values OR'd). */
|
|
98
|
+
headers?: {
|
|
99
|
+
[key: string]: string[];
|
|
100
|
+
};
|
|
101
|
+
body_contains?: string[];
|
|
102
|
+
};
|
|
103
|
+
/** @description allow / deny, or a rewrite object. `rewrite` needs the MITM data-path; until it ships a rewrite rule is inert (treated as deny). */
|
|
104
|
+
PolicyAction: ("allow" | "deny") | {
|
|
105
|
+
rewrite: components["schemas"]["Rewrite"];
|
|
106
|
+
};
|
|
107
|
+
/** @description Mutate-and-forward (the only mutating action). Static for now — request-time interpolation is future work. */
|
|
108
|
+
Rewrite: {
|
|
109
|
+
host?: string;
|
|
110
|
+
path?: string;
|
|
111
|
+
/** @description Merge-set these request headers (not replace-all). */
|
|
112
|
+
headers?: {
|
|
113
|
+
[key: string]: string;
|
|
114
|
+
};
|
|
115
|
+
remove_headers?: string[];
|
|
116
|
+
};
|
|
117
|
+
/** @description Response to PUT /v1/vms/{id}/policies. */
|
|
118
|
+
PutPoliciesResponse: {
|
|
119
|
+
/** @description The stored policy document — read its rules as `policy.policies`. */
|
|
120
|
+
policy: components["schemas"]["PolicyDoc"];
|
|
121
|
+
/** @description Domains the policy would escalate to MITM once the data-path ships. */
|
|
122
|
+
mitm_domains?: string[];
|
|
123
|
+
/** @description Non-fatal notes (e.g. L7/rewrite rules degraded until the MITM data-path ships). */
|
|
124
|
+
warnings?: string[];
|
|
69
125
|
};
|
|
70
126
|
Session: {
|
|
71
127
|
session_id: string;
|
|
@@ -528,7 +584,7 @@ declare const CHUNK_SIZE: number;
|
|
|
528
584
|
*/
|
|
529
585
|
declare const ARKER_ORG_ID = "ArkerHQ";
|
|
530
586
|
type FetchLike = typeof fetch;
|
|
531
|
-
type HttpMethod = "GET" | "POST" | "PATCH" | "DELETE";
|
|
587
|
+
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
532
588
|
interface RetryOptions {
|
|
533
589
|
attempts?: number;
|
|
534
590
|
baseDelayMs?: number;
|
|
@@ -565,6 +621,15 @@ type ResourceKind = ApiSchema<"ResourceKind">;
|
|
|
565
621
|
type ErrorCode = ApiSchema<"ErrorCode">;
|
|
566
622
|
type NetworkPolicy = ApiSchema<"NetworkPolicy">;
|
|
567
623
|
type NetworkPolicyInput = ApiSchema<"NetworkPolicyInput">;
|
|
624
|
+
type PolicyDoc = ApiSchema<"PolicyDoc">;
|
|
625
|
+
type PolicyEntry = ApiSchema<"PolicyEntry">;
|
|
626
|
+
type PolicyMatch = ApiSchema<"PolicyMatch">;
|
|
627
|
+
type PolicyAction = ApiSchema<"PolicyAction">;
|
|
628
|
+
type Rewrite = ApiSchema<"Rewrite">;
|
|
629
|
+
type PutPoliciesResponse = ApiSchema<"PutPoliciesResponse">;
|
|
630
|
+
/** A `ports` element: a single port (`80`) or an inclusive `[start, end]`
|
|
631
|
+
* range (`[1000, 2000]`). A `ports` list may mix the two. */
|
|
632
|
+
type PortSpec = NonNullable<PolicyMatch["ports"]>[number];
|
|
568
633
|
type ForkRequest = ApiSchema<"ForkRequest">;
|
|
569
634
|
type ForkOptions = ForkRequest;
|
|
570
635
|
type VmResources = ApiSchema<"VmResources">;
|
|
@@ -759,6 +824,7 @@ declare class Arker {
|
|
|
759
824
|
readonly provider: "aws" | "aws-burst";
|
|
760
825
|
private readonly apiKey;
|
|
761
826
|
private readonly fetchImpl;
|
|
827
|
+
private readonly http2;
|
|
762
828
|
private readonly retry;
|
|
763
829
|
constructor(opts?: ArkerOptions);
|
|
764
830
|
/**
|
|
@@ -897,6 +963,27 @@ declare class VM {
|
|
|
897
963
|
*/
|
|
898
964
|
resize(request: PatchVmRequest | (VmResources & Pick<PatchVmRequest, "network">)): Promise<Vm>;
|
|
899
965
|
delete(): Promise<DeleteVmResponse>;
|
|
966
|
+
/**
|
|
967
|
+
* Read this VM's outbound egress policy document (ARK-125). Returns an
|
|
968
|
+
* empty doc (`{}`) when no policy is set.
|
|
969
|
+
*/
|
|
970
|
+
getPolicies(): Promise<PolicyDoc>;
|
|
971
|
+
/**
|
|
972
|
+
* Replace this VM's outbound egress policy with `doc` — an ordered,
|
|
973
|
+
* first-match-wins rule list. An empty doc (`{}` or `{ policies: [] }`)
|
|
974
|
+
* clears the policy to allow-all. Returns the stored policy plus the
|
|
975
|
+
* domains it escalates to MITM and any degrade warnings.
|
|
976
|
+
*
|
|
977
|
+
* await vm.setPolicies({
|
|
978
|
+
* policies: [
|
|
979
|
+
* { type: "network.outbound",
|
|
980
|
+
* match: { domains: ["github.com"], ports: [443] },
|
|
981
|
+
* action: "allow" },
|
|
982
|
+
* { type: "network.outbound", action: "deny" },
|
|
983
|
+
* ],
|
|
984
|
+
* });
|
|
985
|
+
*/
|
|
986
|
+
setPolicies(doc: PolicyDoc): Promise<PutPoliciesResponse>;
|
|
900
987
|
listSyncs(opts?: ListOpts & {
|
|
901
988
|
filesystemId?: string;
|
|
902
989
|
}): Promise<ListSyncsResponse>;
|
|
@@ -919,7 +1006,21 @@ declare class VM {
|
|
|
919
1006
|
createSession(request?: CreateSessionRequest): Promise<Session>;
|
|
920
1007
|
getSession(sessionId: string): Promise<Session>;
|
|
921
1008
|
deleteSession(sessionId: string): Promise<DeleteSessionResponse>;
|
|
1009
|
+
/**
|
|
1010
|
+
* Update a session via `PATCH /v1/vms/{id}/sessions/{sid}`: resize its PTY
|
|
1011
|
+
* (`cols`/`rows`) and/or set the idle `timeoutSecs`. Works whether or not a
|
|
1012
|
+
* PTY is currently attached — the REST equivalent of {@link PtyConnection.resize}
|
|
1013
|
+
* (which sends an in-band control frame on the live WebSocket).
|
|
1014
|
+
*/
|
|
1015
|
+
updateSession(sessionId: string, update: {
|
|
1016
|
+
cols?: number;
|
|
1017
|
+
rows?: number;
|
|
1018
|
+
timeoutSecs?: number;
|
|
1019
|
+
}): Promise<{
|
|
1020
|
+
ok: boolean;
|
|
1021
|
+
session_id: string;
|
|
1022
|
+
}>;
|
|
922
1023
|
connectPty(options?: PtyConnectOptions): Promise<PtyConnection>;
|
|
923
1024
|
}
|
|
924
1025
|
|
|
925
|
-
export { ARKER_ORG_ID, Arker, ArkerError, type ArkerOptions, type BackgroundRunResponse, type BackgroundRunResult, CHUNK_SIZE, type CancelRunResponse, type CompletedRunResponse, type CompletedRunResult, type CreateSessionRequest, type DeleteFilesystemResponse, type DeleteSessionResponse, type DeleteSyncResponse, type DeleteVmResponse, type ErrorCode, type ErrorResponse, type Filesystem, type FilesystemCreateRequest, type ForkOptions, type ForkRequest, type ForkSource, type InboundPortRequest, type ListFilesystemsResponse, type ListOpts, type ListOrgRunsOptions, type ListOrgRunsResponse, type ListRunsResponse, type ListSessionsResponse, type ListSyncsResponse, type ListVmsResponse, type NetworkInput, type NetworkPolicy, type NetworkPolicyInput, type NetworkRequest, type NetworkStatus, type OrgRunListRow, type PatchVmRequest, type PtyCloseEvent, type PtyConnectOptions, type PtyConnection, type PtyInput, type PtyWebSocketFactory, type ResourceKind, type RetryOptions, type Run, type RunInboundPortRequest, type RunListRow, type RunNetworkRequest, type RunNetworkStatus, type RunOptions, type RunRequest, type RunResponse, type RunResult, type RunState, type RunStatusResponse, type RunSummary, type Session, type SessionInfo, type SessionState, type Sync, type SyncByteRange, type SyncChunkWriteResult, type SyncCommitWriteResult, type SyncCreateRequest, type SyncPresignedWriteRequestResult, type SyncReadInlineResponse, type SyncReadPresignedResponse, type SyncReadRequest, type SyncReadResponse, type SyncWriteRequest, type SyncWriteResponse, type SyncWriteResult, VM, type Vm, type VmNetwork, type VmResources, type VmState };
|
|
1026
|
+
export { ARKER_ORG_ID, Arker, ArkerError, type ArkerOptions, type BackgroundRunResponse, type BackgroundRunResult, CHUNK_SIZE, type CancelRunResponse, type CompletedRunResponse, type CompletedRunResult, type CreateSessionRequest, type DeleteFilesystemResponse, type DeleteSessionResponse, type DeleteSyncResponse, type DeleteVmResponse, type ErrorCode, type ErrorResponse, type Filesystem, type FilesystemCreateRequest, type ForkOptions, type ForkRequest, type ForkSource, type InboundPortRequest, type ListFilesystemsResponse, type ListOpts, type ListOrgRunsOptions, type ListOrgRunsResponse, type ListRunsResponse, type ListSessionsResponse, type ListSyncsResponse, type ListVmsResponse, type NetworkInput, type NetworkPolicy, type NetworkPolicyInput, type NetworkRequest, type NetworkStatus, type OrgRunListRow, type PatchVmRequest, type PolicyAction, type PolicyDoc, type PolicyEntry, type PolicyMatch, type PortSpec, type PtyCloseEvent, type PtyConnectOptions, type PtyConnection, type PtyInput, type PtyWebSocketFactory, type PutPoliciesResponse, type ResourceKind, type RetryOptions, type Rewrite, type Run, type RunInboundPortRequest, type RunListRow, type RunNetworkRequest, type RunNetworkStatus, type RunOptions, type RunRequest, type RunResponse, type RunResult, type RunState, type RunStatusResponse, type RunSummary, type Session, type SessionInfo, type SessionState, type Sync, type SyncByteRange, type SyncChunkWriteResult, type SyncCommitWriteResult, type SyncCreateRequest, type SyncPresignedWriteRequestResult, type SyncReadInlineResponse, type SyncReadPresignedResponse, type SyncReadRequest, type SyncReadResponse, type SyncWriteRequest, type SyncWriteResponse, type SyncWriteResult, VM, type Vm, type VmNetwork, type VmResources, type VmState };
|