@bluelibs/runner 4.8.0 → 4.8.2
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/AI.md +44 -5
- package/README.md +24 -25
- package/dist/browser/index.cjs +362 -175
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.mjs +362 -175
- package/dist/browser/index.mjs.map +1 -1
- package/dist/edge/index.cjs +362 -175
- package/dist/edge/index.cjs.map +1 -1
- package/dist/edge/index.mjs +362 -175
- package/dist/edge/index.mjs.map +1 -1
- package/dist/globals/globalResources.d.ts +17 -8
- package/dist/globals/resources/httpClientFactory.resource.d.ts +28 -0
- package/dist/http-client.d.ts +1 -3
- package/dist/index.d.ts +15 -8
- package/dist/node/http-mixed-client.d.ts +3 -0
- package/dist/node/node.cjs +1125 -4525
- package/dist/node/node.cjs.map +1 -1
- package/dist/node/node.d.ts +93 -0
- package/dist/node/node.mjs +1121 -4523
- package/dist/node/node.mjs.map +1 -1
- package/dist/node/resources/http-mixed-client.factory.resource.d.ts +17 -0
- package/dist/node/resources/http-smart-client.factory.resource.d.ts +16 -0
- package/dist/universal/index.cjs +362 -175
- package/dist/universal/index.cjs.map +1 -1
- package/dist/universal/index.mjs +362 -175
- package/dist/universal/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MixedHttpClient } from "../http-mixed-client";
|
|
2
|
+
export interface HttpMixedClientFactoryConfig {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
auth?: {
|
|
5
|
+
header?: string;
|
|
6
|
+
token: string;
|
|
7
|
+
};
|
|
8
|
+
timeoutMs?: number;
|
|
9
|
+
fetchImpl?: typeof fetch;
|
|
10
|
+
onRequest?: (ctx: {
|
|
11
|
+
url: string;
|
|
12
|
+
headers: Record<string, string>;
|
|
13
|
+
}) => void | Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export type HttpMixedClientFactory = (config: HttpMixedClientFactoryConfig) => MixedHttpClient;
|
|
16
|
+
export declare const httpMixedClientFactory: import("..").IResource<void, Promise<HttpMixedClientFactory>, {}, any, any, import("..").TagType[], import("..").ResourceMiddlewareAttachmentType[]>;
|
|
17
|
+
export type { MixedHttpClient };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { HttpSmartClient } from "../http-smart-client.model";
|
|
2
|
+
export interface HttpSmartClientFactoryConfig {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
auth?: {
|
|
5
|
+
header?: string;
|
|
6
|
+
token: string;
|
|
7
|
+
};
|
|
8
|
+
timeoutMs?: number;
|
|
9
|
+
onRequest?: (ctx: {
|
|
10
|
+
url: string;
|
|
11
|
+
headers: Record<string, string>;
|
|
12
|
+
}) => void | Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export type HttpSmartClientFactory = (config: HttpSmartClientFactoryConfig) => HttpSmartClient;
|
|
15
|
+
export declare const httpSmartClientFactory: import("..").IResource<void, Promise<HttpSmartClientFactory>, {}, any, any, import("..").TagType[], import("..").ResourceMiddlewareAttachmentType[]>;
|
|
16
|
+
export type { HttpSmartClient };
|
package/dist/universal/index.cjs
CHANGED
|
@@ -362,7 +362,7 @@ var error = errorBuilder;
|
|
|
362
362
|
|
|
363
363
|
// src/platform/adapters/node-als.ts
|
|
364
364
|
async function loadAsyncLocalStorageClass() {
|
|
365
|
-
const mod =
|
|
365
|
+
const mod = __require("async_hooks");
|
|
366
366
|
return mod.AsyncLocalStorage;
|
|
367
367
|
}
|
|
368
368
|
__name(loadAsyncLocalStorageClass, "loadAsyncLocalStorageClass");
|
|
@@ -1248,7 +1248,7 @@ function defineAsyncContext(def) {
|
|
|
1248
1248
|
map.set(ctxId, value);
|
|
1249
1249
|
return storage.run(map, fn);
|
|
1250
1250
|
}, "provide");
|
|
1251
|
-
const
|
|
1251
|
+
const serializer2 = getDefaultSerializer();
|
|
1252
1252
|
const api = {
|
|
1253
1253
|
id: ctxId,
|
|
1254
1254
|
[symbolAsyncContext]: true,
|
|
@@ -1264,9 +1264,9 @@ function defineAsyncContext(def) {
|
|
|
1264
1264
|
});
|
|
1265
1265
|
},
|
|
1266
1266
|
/* istanbul ignore next */
|
|
1267
|
-
serialize: def.serialize || ((data) =>
|
|
1267
|
+
serialize: def.serialize || ((data) => serializer2.stringify(data)),
|
|
1268
1268
|
/* istanbul ignore next */
|
|
1269
|
-
parse: def.parse || ((data) =>
|
|
1269
|
+
parse: def.parse || ((data) => serializer2.parse(data)),
|
|
1270
1270
|
optional() {
|
|
1271
1271
|
return {
|
|
1272
1272
|
inner: api,
|
|
@@ -1427,6 +1427,352 @@ var queueResource = defineResource({
|
|
|
1427
1427
|
}
|
|
1428
1428
|
});
|
|
1429
1429
|
|
|
1430
|
+
// src/globals/resources/tunnel/protocol.ts
|
|
1431
|
+
var TunnelError = class extends Error {
|
|
1432
|
+
static {
|
|
1433
|
+
__name(this, "TunnelError");
|
|
1434
|
+
}
|
|
1435
|
+
constructor(code, message, details, extras) {
|
|
1436
|
+
super(message);
|
|
1437
|
+
this.name = "TunnelError";
|
|
1438
|
+
this.code = code;
|
|
1439
|
+
this.details = details;
|
|
1440
|
+
this.id = extras?.id;
|
|
1441
|
+
this.data = extras?.data;
|
|
1442
|
+
}
|
|
1443
|
+
};
|
|
1444
|
+
function toTunnelError(input, fallbackMessage) {
|
|
1445
|
+
if (input instanceof Error) {
|
|
1446
|
+
return new TunnelError("UNKNOWN", input.message);
|
|
1447
|
+
}
|
|
1448
|
+
if (input && typeof input === "object" && "code" in input && "message" in input && typeof input.message === "string" && typeof input.code === "string") {
|
|
1449
|
+
const pe = input;
|
|
1450
|
+
const msg = pe.message || fallbackMessage || "Tunnel error";
|
|
1451
|
+
return new TunnelError(pe.code, msg, pe.details, {
|
|
1452
|
+
id: pe.id,
|
|
1453
|
+
data: pe.data
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1456
|
+
if (input && typeof input === "object" && "message" in input && typeof input.message === "string") {
|
|
1457
|
+
return new TunnelError("UNKNOWN", input.message);
|
|
1458
|
+
}
|
|
1459
|
+
return new TunnelError(
|
|
1460
|
+
"UNKNOWN",
|
|
1461
|
+
typeof input === "string" && input || fallbackMessage || "Tunnel error"
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1464
|
+
__name(toTunnelError, "toTunnelError");
|
|
1465
|
+
function assertOkEnvelope(envelope, opts) {
|
|
1466
|
+
if (!envelope || typeof envelope !== "object") {
|
|
1467
|
+
throw new TunnelError(
|
|
1468
|
+
"INVALID_RESPONSE",
|
|
1469
|
+
opts?.fallbackMessage || "Invalid or empty response"
|
|
1470
|
+
);
|
|
1471
|
+
}
|
|
1472
|
+
if (envelope.ok) {
|
|
1473
|
+
return envelope.result;
|
|
1474
|
+
}
|
|
1475
|
+
if (envelope.error) {
|
|
1476
|
+
return (() => {
|
|
1477
|
+
throw toTunnelError(envelope.error, opts?.fallbackMessage);
|
|
1478
|
+
})();
|
|
1479
|
+
}
|
|
1480
|
+
throw new TunnelError("UNKNOWN", opts?.fallbackMessage || "Tunnel error");
|
|
1481
|
+
}
|
|
1482
|
+
__name(assertOkEnvelope, "assertOkEnvelope");
|
|
1483
|
+
|
|
1484
|
+
// src/http-fetch-tunnel.resource.ts
|
|
1485
|
+
async function postSerialized(fetchFn, url, body, headers, timeoutMs, serializer2, onRequest, contextHeaderText) {
|
|
1486
|
+
const controller = timeoutMs && timeoutMs > 0 ? new AbortController() : void 0;
|
|
1487
|
+
let timeout;
|
|
1488
|
+
try {
|
|
1489
|
+
if (controller) {
|
|
1490
|
+
timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
1491
|
+
}
|
|
1492
|
+
const reqHeaders = {
|
|
1493
|
+
"content-type": "application/json; charset=utf-8",
|
|
1494
|
+
...headers
|
|
1495
|
+
};
|
|
1496
|
+
if (contextHeaderText) reqHeaders["x-runner-context"] = contextHeaderText;
|
|
1497
|
+
if (onRequest) await onRequest({ url, headers: reqHeaders });
|
|
1498
|
+
const res = await fetchFn(url, {
|
|
1499
|
+
method: "POST",
|
|
1500
|
+
headers: reqHeaders,
|
|
1501
|
+
body: serializer2.stringify(body),
|
|
1502
|
+
signal: controller?.signal
|
|
1503
|
+
});
|
|
1504
|
+
const text = await res.text();
|
|
1505
|
+
const json = text ? serializer2.parse(text) : void 0;
|
|
1506
|
+
return json;
|
|
1507
|
+
} finally {
|
|
1508
|
+
if (timeout) clearTimeout(timeout);
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
__name(postSerialized, "postSerialized");
|
|
1512
|
+
function createExposureFetch(cfg) {
|
|
1513
|
+
const baseUrl = (cfg?.baseUrl).replace(/\/$/, "");
|
|
1514
|
+
if (!baseUrl) throw new Error("createExposureFetch requires baseUrl");
|
|
1515
|
+
const headerName = (cfg?.auth?.header ?? "x-runner-token").toLowerCase();
|
|
1516
|
+
const buildHeaders = /* @__PURE__ */ __name(() => {
|
|
1517
|
+
const headers = {};
|
|
1518
|
+
if (cfg?.auth?.token) headers[headerName] = cfg.auth.token;
|
|
1519
|
+
return headers;
|
|
1520
|
+
}, "buildHeaders");
|
|
1521
|
+
const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
|
|
1522
|
+
if (typeof fetchImpl !== "function") {
|
|
1523
|
+
throw new Error(
|
|
1524
|
+
"global fetch is not available; provide fetchImpl in config"
|
|
1525
|
+
);
|
|
1526
|
+
}
|
|
1527
|
+
const buildContextHeader = /* @__PURE__ */ __name(() => {
|
|
1528
|
+
if (!cfg.contexts || cfg.contexts.length === 0) return void 0;
|
|
1529
|
+
const map = {};
|
|
1530
|
+
for (const ctx of cfg.contexts) {
|
|
1531
|
+
try {
|
|
1532
|
+
const v = ctx.use();
|
|
1533
|
+
map[ctx.id] = ctx.serialize(v);
|
|
1534
|
+
} catch {
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
const keys = Object.keys(map);
|
|
1538
|
+
if (keys.length === 0) return void 0;
|
|
1539
|
+
return cfg.serializer.stringify(map);
|
|
1540
|
+
}, "buildContextHeader");
|
|
1541
|
+
return {
|
|
1542
|
+
async task(id2, input) {
|
|
1543
|
+
const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
|
|
1544
|
+
const r2 = await postSerialized(
|
|
1545
|
+
fetchImpl,
|
|
1546
|
+
url,
|
|
1547
|
+
{ input },
|
|
1548
|
+
buildHeaders(),
|
|
1549
|
+
cfg?.timeoutMs,
|
|
1550
|
+
cfg.serializer,
|
|
1551
|
+
cfg?.onRequest,
|
|
1552
|
+
buildContextHeader()
|
|
1553
|
+
);
|
|
1554
|
+
try {
|
|
1555
|
+
return assertOkEnvelope(r2, { fallbackMessage: "Tunnel task error" });
|
|
1556
|
+
} catch (e) {
|
|
1557
|
+
const te = e;
|
|
1558
|
+
if (te && cfg.errorRegistry && te.id && te.data) {
|
|
1559
|
+
const helper = cfg.errorRegistry.get(String(te.id));
|
|
1560
|
+
if (helper) helper.throw(te.data);
|
|
1561
|
+
}
|
|
1562
|
+
throw e;
|
|
1563
|
+
}
|
|
1564
|
+
},
|
|
1565
|
+
async event(id2, payload) {
|
|
1566
|
+
const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
|
|
1567
|
+
const r2 = await postSerialized(
|
|
1568
|
+
fetchImpl,
|
|
1569
|
+
url,
|
|
1570
|
+
{ payload },
|
|
1571
|
+
buildHeaders(),
|
|
1572
|
+
cfg?.timeoutMs,
|
|
1573
|
+
cfg.serializer,
|
|
1574
|
+
cfg?.onRequest,
|
|
1575
|
+
buildContextHeader()
|
|
1576
|
+
);
|
|
1577
|
+
try {
|
|
1578
|
+
assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
|
|
1579
|
+
} catch (e) {
|
|
1580
|
+
const te = e;
|
|
1581
|
+
if (te && cfg.errorRegistry && te.id && te.data) {
|
|
1582
|
+
const helper = cfg.errorRegistry.get(String(te.id));
|
|
1583
|
+
if (helper) helper.throw(te.data);
|
|
1584
|
+
}
|
|
1585
|
+
throw e;
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
__name(createExposureFetch, "createExposureFetch");
|
|
1591
|
+
|
|
1592
|
+
// src/tunnels/buildUniversalManifest.ts
|
|
1593
|
+
function buildUniversalManifest(input) {
|
|
1594
|
+
const nodeFiles = [];
|
|
1595
|
+
const webFiles = [];
|
|
1596
|
+
function visit(value) {
|
|
1597
|
+
if (!value || typeof value !== "object") return value;
|
|
1598
|
+
if (value.$ejson === "File" && typeof value.id === "string") {
|
|
1599
|
+
const v = value;
|
|
1600
|
+
const id2 = v.id;
|
|
1601
|
+
const meta = v.meta;
|
|
1602
|
+
const node = v._node;
|
|
1603
|
+
const web = v._web;
|
|
1604
|
+
if (node?.buffer) {
|
|
1605
|
+
nodeFiles.push({
|
|
1606
|
+
id: id2,
|
|
1607
|
+
meta,
|
|
1608
|
+
source: { type: "buffer", buffer: node.buffer }
|
|
1609
|
+
});
|
|
1610
|
+
} else if (node?.stream) {
|
|
1611
|
+
nodeFiles.push({
|
|
1612
|
+
id: id2,
|
|
1613
|
+
meta,
|
|
1614
|
+
source: { type: "stream", stream: node.stream }
|
|
1615
|
+
});
|
|
1616
|
+
} else if (web?.blob) {
|
|
1617
|
+
webFiles.push({ id: id2, meta, blob: web.blob });
|
|
1618
|
+
}
|
|
1619
|
+
const copy = { $ejson: "File", id: id2, meta };
|
|
1620
|
+
return copy;
|
|
1621
|
+
}
|
|
1622
|
+
if (Array.isArray(value)) {
|
|
1623
|
+
return value.map((x) => visit(x));
|
|
1624
|
+
}
|
|
1625
|
+
const out = {};
|
|
1626
|
+
for (const k of Object.keys(value)) {
|
|
1627
|
+
out[k] = visit(value[k]);
|
|
1628
|
+
}
|
|
1629
|
+
return out;
|
|
1630
|
+
}
|
|
1631
|
+
__name(visit, "visit");
|
|
1632
|
+
const cloned = visit(input);
|
|
1633
|
+
return {
|
|
1634
|
+
input: cloned,
|
|
1635
|
+
nodeFiles,
|
|
1636
|
+
webFiles
|
|
1637
|
+
};
|
|
1638
|
+
}
|
|
1639
|
+
__name(buildUniversalManifest, "buildUniversalManifest");
|
|
1640
|
+
|
|
1641
|
+
// src/http-client.ts
|
|
1642
|
+
function toHeaders(auth) {
|
|
1643
|
+
const headers = {};
|
|
1644
|
+
if (auth?.token)
|
|
1645
|
+
headers[(auth.header ?? "x-runner-token").toLowerCase()] = auth.token;
|
|
1646
|
+
return headers;
|
|
1647
|
+
}
|
|
1648
|
+
__name(toHeaders, "toHeaders");
|
|
1649
|
+
function createHttpClient(cfg) {
|
|
1650
|
+
const baseUrl = cfg.baseUrl.replace(/\/$/, "");
|
|
1651
|
+
if (!baseUrl) throw new Error("createHttpClient requires baseUrl");
|
|
1652
|
+
const fetchClient = createExposureFetch({
|
|
1653
|
+
baseUrl,
|
|
1654
|
+
auth: cfg.auth,
|
|
1655
|
+
timeoutMs: cfg.timeoutMs,
|
|
1656
|
+
fetchImpl: cfg.fetchImpl,
|
|
1657
|
+
serializer: cfg.serializer,
|
|
1658
|
+
onRequest: cfg.onRequest,
|
|
1659
|
+
contexts: cfg.contexts,
|
|
1660
|
+
errorRegistry: cfg.errorRegistry
|
|
1661
|
+
});
|
|
1662
|
+
async function postMultipartBrowser(url, manifestText, files) {
|
|
1663
|
+
const fd = new FormData();
|
|
1664
|
+
fd.append("__manifest", manifestText);
|
|
1665
|
+
for (const f of files) {
|
|
1666
|
+
const filename = f.meta?.name ?? "upload";
|
|
1667
|
+
fd.append(`file:${f.id}`, f.blob, filename);
|
|
1668
|
+
}
|
|
1669
|
+
const headers = toHeaders(cfg.auth);
|
|
1670
|
+
if (cfg.contexts && cfg.contexts.length > 0) {
|
|
1671
|
+
const map = {};
|
|
1672
|
+
for (const ctx of cfg.contexts) {
|
|
1673
|
+
try {
|
|
1674
|
+
const v = ctx.use();
|
|
1675
|
+
map[ctx.id] = ctx.serialize(v);
|
|
1676
|
+
} catch {
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
if (Object.keys(map).length > 0) {
|
|
1680
|
+
headers["x-runner-context"] = cfg.serializer.stringify(map);
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
if (cfg.onRequest) await cfg.onRequest({ url, headers });
|
|
1684
|
+
const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
|
|
1685
|
+
const res = await fetchImpl(url, { method: "POST", body: fd, headers });
|
|
1686
|
+
const text = await res.text();
|
|
1687
|
+
const json = text ? cfg.serializer.parse(text) : void 0;
|
|
1688
|
+
return json;
|
|
1689
|
+
}
|
|
1690
|
+
__name(postMultipartBrowser, "postMultipartBrowser");
|
|
1691
|
+
return {
|
|
1692
|
+
async task(id2, input) {
|
|
1693
|
+
const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
|
|
1694
|
+
if (input && typeof input.pipe === "function") {
|
|
1695
|
+
throw new Error(
|
|
1696
|
+
"createHttpClient (universal) cannot send a Node stream. Use @bluelibs/runner/node createHttpSmartClient or createHttpMixedClient for duplex/streaming."
|
|
1697
|
+
);
|
|
1698
|
+
}
|
|
1699
|
+
const manifest = buildUniversalManifest(input);
|
|
1700
|
+
if (manifest.webFiles.length > 0) {
|
|
1701
|
+
const manifestText = cfg.serializer.stringify({ input: manifest.input });
|
|
1702
|
+
const r2 = await postMultipartBrowser(url, manifestText, manifest.webFiles);
|
|
1703
|
+
try {
|
|
1704
|
+
return assertOkEnvelope(r2, {
|
|
1705
|
+
fallbackMessage: "Tunnel task error"
|
|
1706
|
+
});
|
|
1707
|
+
} catch (e) {
|
|
1708
|
+
const te = e;
|
|
1709
|
+
if (te && cfg.errorRegistry && te.id && te.data) {
|
|
1710
|
+
const helper = cfg.errorRegistry.get(String(te.id));
|
|
1711
|
+
if (helper) helper.throw(te.data);
|
|
1712
|
+
}
|
|
1713
|
+
throw e;
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
if (manifest.nodeFiles.length > 0) {
|
|
1717
|
+
throw new Error(
|
|
1718
|
+
"createHttpClient (universal) detected Node file input. Use @bluelibs/runner/node createHttpSmartClient or createHttpMixedClient for Node streaming/multipart."
|
|
1719
|
+
);
|
|
1720
|
+
}
|
|
1721
|
+
try {
|
|
1722
|
+
return await fetchClient.task(id2, input);
|
|
1723
|
+
} catch (e) {
|
|
1724
|
+
const te = e;
|
|
1725
|
+
if (te && cfg.errorRegistry && te.id && te.data) {
|
|
1726
|
+
const helper = cfg.errorRegistry.get(String(te.id));
|
|
1727
|
+
if (helper) helper.throw(te.data);
|
|
1728
|
+
}
|
|
1729
|
+
throw e;
|
|
1730
|
+
}
|
|
1731
|
+
},
|
|
1732
|
+
async event(id2, payload) {
|
|
1733
|
+
try {
|
|
1734
|
+
return await fetchClient.event(id2, payload);
|
|
1735
|
+
} catch (e) {
|
|
1736
|
+
const te = e;
|
|
1737
|
+
if (te && cfg.errorRegistry && te.id && te.data) {
|
|
1738
|
+
const helper = cfg.errorRegistry.get(String(te.id));
|
|
1739
|
+
if (helper) helper.throw(te.data);
|
|
1740
|
+
}
|
|
1741
|
+
throw e;
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
};
|
|
1745
|
+
}
|
|
1746
|
+
__name(createHttpClient, "createHttpClient");
|
|
1747
|
+
|
|
1748
|
+
// src/globals/resources/httpClientFactory.resource.ts
|
|
1749
|
+
var httpClientFactory = defineResource({
|
|
1750
|
+
id: "globals.resources.httpClientFactory",
|
|
1751
|
+
meta: {
|
|
1752
|
+
title: "HTTP Client Factory",
|
|
1753
|
+
description: "Factory for creating HTTP clients with automatic injection of serializer, error registry, and async contexts from the store."
|
|
1754
|
+
},
|
|
1755
|
+
// Use it as a function to avoid circular dependencies, and undefined
|
|
1756
|
+
dependencies: /* @__PURE__ */ __name(() => ({
|
|
1757
|
+
serializer,
|
|
1758
|
+
store
|
|
1759
|
+
}), "dependencies"),
|
|
1760
|
+
init: /* @__PURE__ */ __name(async (_, { serializer: serializer2, store: store2 }) => {
|
|
1761
|
+
const errorRegistry = /* @__PURE__ */ new Map();
|
|
1762
|
+
for (const [id2, helper] of store2.errors) {
|
|
1763
|
+
errorRegistry.set(id2, helper);
|
|
1764
|
+
}
|
|
1765
|
+
const contexts = Array.from(store2.asyncContexts.values());
|
|
1766
|
+
const create = /* @__PURE__ */ __name((config) => createHttpClient({
|
|
1767
|
+
...config,
|
|
1768
|
+
serializer: serializer2,
|
|
1769
|
+
errorRegistry,
|
|
1770
|
+
contexts
|
|
1771
|
+
}), "create");
|
|
1772
|
+
return create;
|
|
1773
|
+
}, "init")
|
|
1774
|
+
});
|
|
1775
|
+
|
|
1430
1776
|
// src/globals/globalResources.ts
|
|
1431
1777
|
var systemTag2 = globalTags.system;
|
|
1432
1778
|
var store = defineResource({
|
|
@@ -1437,6 +1783,14 @@ var store = defineResource({
|
|
|
1437
1783
|
},
|
|
1438
1784
|
tags: [systemTag2]
|
|
1439
1785
|
});
|
|
1786
|
+
var serializer = defineResource({
|
|
1787
|
+
id: "globals.resources.serializer",
|
|
1788
|
+
meta: {
|
|
1789
|
+
title: "Serializer",
|
|
1790
|
+
description: "Serializes and deserializes data. Provides EJSON-compatible stringify/parse and custom type registration via addType."
|
|
1791
|
+
},
|
|
1792
|
+
tags: [systemTag2]
|
|
1793
|
+
});
|
|
1440
1794
|
var globalResources = {
|
|
1441
1795
|
store,
|
|
1442
1796
|
middlewareManager: defineResource({
|
|
@@ -1472,16 +1826,10 @@ var globalResources = {
|
|
|
1472
1826
|
},
|
|
1473
1827
|
tags: [systemTag2]
|
|
1474
1828
|
}),
|
|
1475
|
-
serializer
|
|
1476
|
-
id: "globals.resources.serializer",
|
|
1477
|
-
meta: {
|
|
1478
|
-
title: "Serializer",
|
|
1479
|
-
description: "Serializes and deserializes data. Provides EJSON-compatible stringify/parse and custom type registration via addType."
|
|
1480
|
-
},
|
|
1481
|
-
tags: [systemTag2]
|
|
1482
|
-
}),
|
|
1829
|
+
serializer,
|
|
1483
1830
|
cache: cacheResource,
|
|
1484
|
-
queue: queueResource
|
|
1831
|
+
queue: queueResource,
|
|
1832
|
+
httpClientFactory
|
|
1485
1833
|
};
|
|
1486
1834
|
|
|
1487
1835
|
// src/globals/middleware/retry.middleware.ts
|
|
@@ -4043,6 +4391,7 @@ var Store = class {
|
|
|
4043
4391
|
this.middlewareManager
|
|
4044
4392
|
);
|
|
4045
4393
|
this.registry.storeGenericItem(globalResources.queue);
|
|
4394
|
+
this.registry.storeGenericItem(globalResources.httpClientFactory);
|
|
4046
4395
|
for (const [resource2, value] of builtInResourcesMap.entries()) {
|
|
4047
4396
|
this.registry.storeGenericItem(resource2);
|
|
4048
4397
|
const entry = this.resources.get(resource2.id);
|
|
@@ -4708,168 +5057,6 @@ function extractResourceAndConfig(resourceOrResourceWithConfig) {
|
|
|
4708
5057
|
}
|
|
4709
5058
|
__name(extractResourceAndConfig, "extractResourceAndConfig");
|
|
4710
5059
|
|
|
4711
|
-
// src/globals/resources/tunnel/protocol.ts
|
|
4712
|
-
var TunnelError = class extends Error {
|
|
4713
|
-
static {
|
|
4714
|
-
__name(this, "TunnelError");
|
|
4715
|
-
}
|
|
4716
|
-
constructor(code, message, details, extras) {
|
|
4717
|
-
super(message);
|
|
4718
|
-
this.name = "TunnelError";
|
|
4719
|
-
this.code = code;
|
|
4720
|
-
this.details = details;
|
|
4721
|
-
this.id = extras?.id;
|
|
4722
|
-
this.data = extras?.data;
|
|
4723
|
-
}
|
|
4724
|
-
};
|
|
4725
|
-
function toTunnelError(input, fallbackMessage) {
|
|
4726
|
-
if (input instanceof Error) {
|
|
4727
|
-
return new TunnelError("UNKNOWN", input.message);
|
|
4728
|
-
}
|
|
4729
|
-
if (input && typeof input === "object" && "code" in input && "message" in input && typeof input.message === "string" && typeof input.code === "string") {
|
|
4730
|
-
const pe = input;
|
|
4731
|
-
const msg = pe.message || fallbackMessage || "Tunnel error";
|
|
4732
|
-
return new TunnelError(pe.code, msg, pe.details, {
|
|
4733
|
-
id: pe.id,
|
|
4734
|
-
data: pe.data
|
|
4735
|
-
});
|
|
4736
|
-
}
|
|
4737
|
-
if (input && typeof input === "object" && "message" in input && typeof input.message === "string") {
|
|
4738
|
-
return new TunnelError("UNKNOWN", input.message);
|
|
4739
|
-
}
|
|
4740
|
-
return new TunnelError(
|
|
4741
|
-
"UNKNOWN",
|
|
4742
|
-
typeof input === "string" && input || fallbackMessage || "Tunnel error"
|
|
4743
|
-
);
|
|
4744
|
-
}
|
|
4745
|
-
__name(toTunnelError, "toTunnelError");
|
|
4746
|
-
function assertOkEnvelope(envelope, opts) {
|
|
4747
|
-
if (!envelope || typeof envelope !== "object") {
|
|
4748
|
-
throw new TunnelError(
|
|
4749
|
-
"INVALID_RESPONSE",
|
|
4750
|
-
opts?.fallbackMessage || "Invalid or empty response"
|
|
4751
|
-
);
|
|
4752
|
-
}
|
|
4753
|
-
if (envelope.ok) {
|
|
4754
|
-
return envelope.result;
|
|
4755
|
-
}
|
|
4756
|
-
if (envelope.error) {
|
|
4757
|
-
return (() => {
|
|
4758
|
-
throw toTunnelError(envelope.error, opts?.fallbackMessage);
|
|
4759
|
-
})();
|
|
4760
|
-
}
|
|
4761
|
-
throw new TunnelError("UNKNOWN", opts?.fallbackMessage || "Tunnel error");
|
|
4762
|
-
}
|
|
4763
|
-
__name(assertOkEnvelope, "assertOkEnvelope");
|
|
4764
|
-
|
|
4765
|
-
// src/http-fetch-tunnel.resource.ts
|
|
4766
|
-
async function postSerialized(fetchFn, url, body, headers, timeoutMs, serializer, onRequest, contextHeaderText) {
|
|
4767
|
-
const controller = timeoutMs && timeoutMs > 0 ? new AbortController() : void 0;
|
|
4768
|
-
let timeout;
|
|
4769
|
-
try {
|
|
4770
|
-
if (controller) {
|
|
4771
|
-
timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
4772
|
-
}
|
|
4773
|
-
const reqHeaders = {
|
|
4774
|
-
"content-type": "application/json; charset=utf-8",
|
|
4775
|
-
...headers
|
|
4776
|
-
};
|
|
4777
|
-
if (contextHeaderText) reqHeaders["x-runner-context"] = contextHeaderText;
|
|
4778
|
-
if (onRequest) await onRequest({ url, headers: reqHeaders });
|
|
4779
|
-
const res = await fetchFn(url, {
|
|
4780
|
-
method: "POST",
|
|
4781
|
-
headers: reqHeaders,
|
|
4782
|
-
body: serializer.stringify(body),
|
|
4783
|
-
signal: controller?.signal
|
|
4784
|
-
});
|
|
4785
|
-
const text = await res.text();
|
|
4786
|
-
const json = text ? serializer.parse(text) : void 0;
|
|
4787
|
-
return json;
|
|
4788
|
-
} finally {
|
|
4789
|
-
if (timeout) clearTimeout(timeout);
|
|
4790
|
-
}
|
|
4791
|
-
}
|
|
4792
|
-
__name(postSerialized, "postSerialized");
|
|
4793
|
-
function createExposureFetch(cfg) {
|
|
4794
|
-
const baseUrl = (cfg?.baseUrl).replace(/\/$/, "");
|
|
4795
|
-
if (!baseUrl) throw new Error("createExposureFetch requires baseUrl");
|
|
4796
|
-
const headerName = (cfg?.auth?.header ?? "x-runner-token").toLowerCase();
|
|
4797
|
-
const buildHeaders = /* @__PURE__ */ __name(() => {
|
|
4798
|
-
const headers = {};
|
|
4799
|
-
if (cfg?.auth?.token) headers[headerName] = cfg.auth.token;
|
|
4800
|
-
return headers;
|
|
4801
|
-
}, "buildHeaders");
|
|
4802
|
-
const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
|
|
4803
|
-
if (typeof fetchImpl !== "function") {
|
|
4804
|
-
throw new Error(
|
|
4805
|
-
"global fetch is not available; provide fetchImpl in config"
|
|
4806
|
-
);
|
|
4807
|
-
}
|
|
4808
|
-
const buildContextHeader = /* @__PURE__ */ __name(() => {
|
|
4809
|
-
if (!cfg.contexts || cfg.contexts.length === 0) return void 0;
|
|
4810
|
-
const map = {};
|
|
4811
|
-
for (const ctx of cfg.contexts) {
|
|
4812
|
-
try {
|
|
4813
|
-
const v = ctx.use();
|
|
4814
|
-
map[ctx.id] = ctx.serialize(v);
|
|
4815
|
-
} catch {
|
|
4816
|
-
}
|
|
4817
|
-
}
|
|
4818
|
-
const keys = Object.keys(map);
|
|
4819
|
-
if (keys.length === 0) return void 0;
|
|
4820
|
-
return cfg.serializer.stringify(map);
|
|
4821
|
-
}, "buildContextHeader");
|
|
4822
|
-
return {
|
|
4823
|
-
async task(id2, input) {
|
|
4824
|
-
const url = `${baseUrl}/task/${encodeURIComponent(id2)}`;
|
|
4825
|
-
const r2 = await postSerialized(
|
|
4826
|
-
fetchImpl,
|
|
4827
|
-
url,
|
|
4828
|
-
{ input },
|
|
4829
|
-
buildHeaders(),
|
|
4830
|
-
cfg?.timeoutMs,
|
|
4831
|
-
cfg.serializer,
|
|
4832
|
-
cfg?.onRequest,
|
|
4833
|
-
buildContextHeader()
|
|
4834
|
-
);
|
|
4835
|
-
try {
|
|
4836
|
-
return assertOkEnvelope(r2, { fallbackMessage: "Tunnel task error" });
|
|
4837
|
-
} catch (e) {
|
|
4838
|
-
const te = e;
|
|
4839
|
-
if (te && cfg.errorRegistry && te.id && te.data) {
|
|
4840
|
-
const helper = cfg.errorRegistry.get(String(te.id));
|
|
4841
|
-
if (helper) helper.throw(te.data);
|
|
4842
|
-
}
|
|
4843
|
-
throw e;
|
|
4844
|
-
}
|
|
4845
|
-
},
|
|
4846
|
-
async event(id2, payload) {
|
|
4847
|
-
const url = `${baseUrl}/event/${encodeURIComponent(id2)}`;
|
|
4848
|
-
const r2 = await postSerialized(
|
|
4849
|
-
fetchImpl,
|
|
4850
|
-
url,
|
|
4851
|
-
{ payload },
|
|
4852
|
-
buildHeaders(),
|
|
4853
|
-
cfg?.timeoutMs,
|
|
4854
|
-
cfg.serializer,
|
|
4855
|
-
cfg?.onRequest,
|
|
4856
|
-
buildContextHeader()
|
|
4857
|
-
);
|
|
4858
|
-
try {
|
|
4859
|
-
assertOkEnvelope(r2, { fallbackMessage: "Tunnel event error" });
|
|
4860
|
-
} catch (e) {
|
|
4861
|
-
const te = e;
|
|
4862
|
-
if (te && cfg.errorRegistry && te.id && te.data) {
|
|
4863
|
-
const helper = cfg.errorRegistry.get(String(te.id));
|
|
4864
|
-
if (helper) helper.throw(te.data);
|
|
4865
|
-
}
|
|
4866
|
-
throw e;
|
|
4867
|
-
}
|
|
4868
|
-
}
|
|
4869
|
-
};
|
|
4870
|
-
}
|
|
4871
|
-
__name(createExposureFetch, "createExposureFetch");
|
|
4872
|
-
|
|
4873
5060
|
// src/globals/tunnels/index.ts
|
|
4874
5061
|
var http = Object.freeze({
|
|
4875
5062
|
createClient(cfg) {
|