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