keq 5.0.0-beta.9 → 5.0.1
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/CHANGELOG.md +162 -0
- package/dist/index.d.mts +62 -18
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +62 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +181 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +181 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -37,6 +37,14 @@ var TimeoutException = class extends AbortException {
|
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
39
|
//#endregion
|
|
40
|
+
//#region src/exception/mutex.exception.ts
|
|
41
|
+
var MutexException = class extends Exception {
|
|
42
|
+
constructor(message) {
|
|
43
|
+
super(message);
|
|
44
|
+
Object.defineProperty(this, "name", { value: "MutexException" });
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
//#endregion
|
|
40
48
|
//#region \0@oxc-project+runtime@0.127.0/helpers/typeof.js
|
|
41
49
|
function _typeof(o) {
|
|
42
50
|
"@babel/helpers - typeof";
|
|
@@ -77,13 +85,18 @@ function _defineProperty(e, r, t) {
|
|
|
77
85
|
//#endregion
|
|
78
86
|
//#region src/exception/http-exceptions/request.exception.ts
|
|
79
87
|
var RequestException = class extends Exception {
|
|
88
|
+
/** @deprecated Use `fatal` instead. `retry === true` is equivalent to `fatal === false`. */
|
|
89
|
+
get retry() {
|
|
90
|
+
return !this.fatal;
|
|
91
|
+
}
|
|
80
92
|
constructor(statusCode, message, options) {
|
|
81
93
|
super(message);
|
|
82
94
|
_defineProperty(this, "statusCode", void 0);
|
|
83
|
-
_defineProperty(this, "
|
|
95
|
+
_defineProperty(this, "fatal", void 0);
|
|
84
96
|
_defineProperty(this, "response", void 0);
|
|
97
|
+
if (typeof options === "boolean") options = { fatal: !options };
|
|
85
98
|
this.statusCode = statusCode;
|
|
86
|
-
this.
|
|
99
|
+
this.fatal = options?.fatal ?? false;
|
|
87
100
|
this.response = options?.response;
|
|
88
101
|
Object.defineProperty(this, "name", { value: "RequestException" });
|
|
89
102
|
}
|
|
@@ -849,6 +862,10 @@ var KeqSharedContext = class {
|
|
|
849
862
|
get locationId() {
|
|
850
863
|
return this[ContextLocationIdProperty];
|
|
851
864
|
}
|
|
865
|
+
/** @deprecated Use `locationId` instead */
|
|
866
|
+
get identifier() {
|
|
867
|
+
return this[ContextLocationIdProperty];
|
|
868
|
+
}
|
|
852
869
|
get request() {
|
|
853
870
|
return this[ContextRequestProperty];
|
|
854
871
|
}
|
|
@@ -1086,8 +1103,9 @@ async function intelligentParseResponse(response) {
|
|
|
1086
1103
|
try {
|
|
1087
1104
|
if (contentType.match(/^application\/(.+\+)?json/)) return resolveWith(response, "json");
|
|
1088
1105
|
else if (contentType.includes("multipart/form-data")) return resolveWith(response, "form-data");
|
|
1089
|
-
else if (contentType.includes("
|
|
1106
|
+
else if (contentType.startsWith("text/") && !contentType.includes("text/event-stream")) return resolveWith(response, "text");
|
|
1090
1107
|
else if (contentType.includes("text/event-stream")) return resolveWith(response, "sse");
|
|
1108
|
+
else if (contentType.startsWith("image/") || contentType.startsWith("audio/") || contentType.startsWith("video/") || contentType.startsWith("font/") || contentType === "application/octet-stream" || contentType === "application/pdf") return resolveWith(response, "array-buffer");
|
|
1091
1109
|
} catch (err) {
|
|
1092
1110
|
console.warn(`Failed to intelligent parse response body: ${response.url}`, err);
|
|
1093
1111
|
throw err;
|
|
@@ -1277,7 +1295,7 @@ var Core = class extends Promise {
|
|
|
1277
1295
|
error = err;
|
|
1278
1296
|
}
|
|
1279
1297
|
const retryOn = typeof sharedContext.options.retry?.on === "function" ? sharedContext.options.retry.on : (attempt, error) => {
|
|
1280
|
-
if (error instanceof RequestException && error.
|
|
1298
|
+
if (error instanceof RequestException && error.fatal) return false;
|
|
1281
1299
|
return !!error;
|
|
1282
1300
|
};
|
|
1283
1301
|
let retryTimes = sharedContext.options.retry?.times || 0;
|
|
@@ -1323,6 +1341,16 @@ var Core = class extends Promise {
|
|
|
1323
1341
|
this.__execute__().then(this.__resolve__, this.__reject__);
|
|
1324
1342
|
}
|
|
1325
1343
|
}
|
|
1344
|
+
/** @deprecated Await the Keq instance directly or use `.fire()` for fire-and-forget. */
|
|
1345
|
+
end() {
|
|
1346
|
+
if (!this.__triggered__) {
|
|
1347
|
+
this.__triggered__ = true;
|
|
1348
|
+
this.__execute__().then(this.__resolve__, this.__reject__);
|
|
1349
|
+
}
|
|
1350
|
+
return new Promise((resolve, reject) => {
|
|
1351
|
+
super.then(resolve, reject);
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1326
1354
|
then(onfulfilled, onrejected) {
|
|
1327
1355
|
if (!this.__triggered__) {
|
|
1328
1356
|
this.__triggered__ = true;
|
|
@@ -1498,6 +1526,9 @@ function keqMethodRoute(method) {
|
|
|
1498
1526
|
}
|
|
1499
1527
|
//#endregion
|
|
1500
1528
|
//#region src/router/keq-module-route.ts
|
|
1529
|
+
/**
|
|
1530
|
+
* @deprecated This function exists solely for backward compatibility with v2.
|
|
1531
|
+
*/
|
|
1501
1532
|
function keqModuleRoute(moduleName) {
|
|
1502
1533
|
if (!moduleName) throw new Exception("Module name should not be empty");
|
|
1503
1534
|
return (ctx) => ctx.options.module?.name === moduleName;
|
|
@@ -1512,6 +1543,9 @@ function keqPathnameRoute(pathname) {
|
|
|
1512
1543
|
}
|
|
1513
1544
|
//#endregion
|
|
1514
1545
|
//#region src/router/keq-router.ts
|
|
1546
|
+
/**
|
|
1547
|
+
* @deprecated Use `request.apply(...middlewares).forRoutes(...)` instead.
|
|
1548
|
+
*/
|
|
1515
1549
|
var KeqRouter = class KeqRouter {
|
|
1516
1550
|
constructor(middlewares = []) {
|
|
1517
1551
|
this.middlewares = middlewares;
|
|
@@ -1592,6 +1626,83 @@ var KeqRouter = class KeqRouter {
|
|
|
1592
1626
|
}
|
|
1593
1627
|
};
|
|
1594
1628
|
//#endregion
|
|
1629
|
+
//#region src/router/utils/build-route.ts
|
|
1630
|
+
function buildRoute(pattern) {
|
|
1631
|
+
const routes = [];
|
|
1632
|
+
if (pattern.host) routes.push(keqHostRoute(pattern.host));
|
|
1633
|
+
if (pattern.method) routes.push(keqMethodRoute(pattern.method));
|
|
1634
|
+
if (pattern.pathname) routes.push(keqPathnameRoute(pattern.pathname));
|
|
1635
|
+
if (routes.length === 0) {
|
|
1636
|
+
const always = () => true;
|
|
1637
|
+
always.__keqRouteName__ = "always";
|
|
1638
|
+
return always;
|
|
1639
|
+
}
|
|
1640
|
+
if (routes.length === 1) return routes[0];
|
|
1641
|
+
return composeRoute(routes);
|
|
1642
|
+
}
|
|
1643
|
+
//#endregion
|
|
1644
|
+
//#region src/router/utils/not-route.ts
|
|
1645
|
+
function notRoute(route) {
|
|
1646
|
+
const negated = async (ctx) => !await route(ctx);
|
|
1647
|
+
negated.__keqRouteName__ = `not(${route.__keqRouteName__ || route.name || "anonymous"})`;
|
|
1648
|
+
return negated;
|
|
1649
|
+
}
|
|
1650
|
+
//#endregion
|
|
1651
|
+
//#region src/router/utils/or-route.ts
|
|
1652
|
+
function orRoute(routes) {
|
|
1653
|
+
if (!routes.length) throw new Exception("At least one route");
|
|
1654
|
+
const combined = async (ctx) => {
|
|
1655
|
+
return (await Promise.all(routes.map((route) => route(ctx)))).some((result) => result === true);
|
|
1656
|
+
};
|
|
1657
|
+
combined.__keqRouteName__ = `or(${routes.map((r) => r.__keqRouteName__ || r.name || "anonymous").join(", ")})`;
|
|
1658
|
+
return combined;
|
|
1659
|
+
}
|
|
1660
|
+
//#endregion
|
|
1661
|
+
//#region src/router/keq-middleware-applicator.ts
|
|
1662
|
+
function normalizeTarget(target) {
|
|
1663
|
+
if (typeof target === "function") return target;
|
|
1664
|
+
return buildRoute(target);
|
|
1665
|
+
}
|
|
1666
|
+
var KeqMiddlewareApplicator = class {
|
|
1667
|
+
constructor(middlewares, registeredMiddlewares, returnValue) {
|
|
1668
|
+
this.middlewares = middlewares;
|
|
1669
|
+
this.registeredMiddlewares = registeredMiddlewares;
|
|
1670
|
+
this.returnValue = returnValue;
|
|
1671
|
+
_defineProperty(this, "excludedTargets", []);
|
|
1672
|
+
}
|
|
1673
|
+
exclude(...routes) {
|
|
1674
|
+
this.excludedTargets.push(...routes);
|
|
1675
|
+
return this;
|
|
1676
|
+
}
|
|
1677
|
+
forRoutes(...routes) {
|
|
1678
|
+
const inclusionRoutes = routes.map(normalizeTarget);
|
|
1679
|
+
const inclusionRoute = inclusionRoutes.length === 1 ? inclusionRoutes[0] : orRoute(inclusionRoutes);
|
|
1680
|
+
let finalRoute;
|
|
1681
|
+
if (this.excludedTargets.length > 0) {
|
|
1682
|
+
const exclusionRoutes = this.excludedTargets.map(normalizeTarget);
|
|
1683
|
+
finalRoute = composeRoute([inclusionRoute, notRoute(exclusionRoutes.length === 1 ? exclusionRoutes[0] : orRoute(exclusionRoutes))]);
|
|
1684
|
+
} else finalRoute = inclusionRoute;
|
|
1685
|
+
const composedMiddleware = this.middlewares.length > 1 ? composeMiddleware(this.middlewares) : this.middlewares[0];
|
|
1686
|
+
this.registeredMiddlewares.push(async function routeApply(ctx, next) {
|
|
1687
|
+
if (await finalRoute(ctx)) await composedMiddleware(ctx, next);
|
|
1688
|
+
else await next();
|
|
1689
|
+
});
|
|
1690
|
+
return this.returnValue;
|
|
1691
|
+
}
|
|
1692
|
+
forAllRoutes() {
|
|
1693
|
+
const composedMiddleware = this.middlewares.length > 1 ? composeMiddleware(this.middlewares) : this.middlewares[0];
|
|
1694
|
+
if (this.excludedTargets.length > 0) {
|
|
1695
|
+
const exclusionRoutes = this.excludedTargets.map(normalizeTarget);
|
|
1696
|
+
const finalRoute = notRoute(exclusionRoutes.length === 1 ? exclusionRoutes[0] : orRoute(exclusionRoutes));
|
|
1697
|
+
this.registeredMiddlewares.push(async function routeApply(ctx, next) {
|
|
1698
|
+
if (await finalRoute(ctx)) await composedMiddleware(ctx, next);
|
|
1699
|
+
else await next();
|
|
1700
|
+
});
|
|
1701
|
+
} else this.registeredMiddlewares.push(composedMiddleware);
|
|
1702
|
+
return this.returnValue;
|
|
1703
|
+
}
|
|
1704
|
+
};
|
|
1705
|
+
//#endregion
|
|
1595
1706
|
//#region src/middlewares/timeout-middleware/index.ts
|
|
1596
1707
|
function keqTimeoutMiddleware() {
|
|
1597
1708
|
return async function timeoutMiddleware(ctx, next) {
|
|
@@ -1660,9 +1771,34 @@ function keqAbortFlowControlMiddleware() {
|
|
|
1660
1771
|
};
|
|
1661
1772
|
}
|
|
1662
1773
|
//#endregion
|
|
1774
|
+
//#region src/middlewares/flow-control-middleware/mutex-flow-control-middleware.ts
|
|
1775
|
+
function keqMutexFlowControlMiddleware() {
|
|
1776
|
+
return async function mutexFlowControlMiddleware(ctx, next) {
|
|
1777
|
+
if (!ctx.options.flowControl || ctx.options.flowControl.mode !== "mutex") {
|
|
1778
|
+
await next();
|
|
1779
|
+
return;
|
|
1780
|
+
}
|
|
1781
|
+
const { signal } = ctx.options.flowControl;
|
|
1782
|
+
const key = typeof signal === "string" ? signal : signal(ctx);
|
|
1783
|
+
if (!ctx.global.core) ctx.global.core = {};
|
|
1784
|
+
if (!ctx.global.core.mutexFlowControl) ctx.global.core.mutexFlowControl = /* @__PURE__ */ new Set();
|
|
1785
|
+
if (ctx.global.core.mutexFlowControl.has(key)) throw new MutexException(`Request rejected by MutexFlowControl: a request with key "${key}" is already in-flight`);
|
|
1786
|
+
ctx.global.core.mutexFlowControl.add(key);
|
|
1787
|
+
try {
|
|
1788
|
+
await next();
|
|
1789
|
+
} finally {
|
|
1790
|
+
ctx.global.core.mutexFlowControl.delete(key);
|
|
1791
|
+
}
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
//#endregion
|
|
1663
1795
|
//#region src/middlewares/flow-control-middleware/index.ts
|
|
1664
1796
|
function keqFlowControlMiddleware() {
|
|
1665
|
-
return composeMiddleware([
|
|
1797
|
+
return composeMiddleware([
|
|
1798
|
+
keqMutexFlowControlMiddleware(),
|
|
1799
|
+
keqSerialFlowControlMiddleware(),
|
|
1800
|
+
keqAbortFlowControlMiddleware()
|
|
1801
|
+
], { name: "flowControlMiddleware" });
|
|
1666
1802
|
}
|
|
1667
1803
|
//#endregion
|
|
1668
1804
|
//#region src/middlewares/fetch-middleware/index.ts
|
|
@@ -1684,34 +1820,39 @@ function keqFetchMiddleware() {
|
|
|
1684
1820
|
* Keq instance factory class,
|
|
1685
1821
|
* and shares global data and middlewares across requests
|
|
1686
1822
|
*/
|
|
1687
|
-
var KeqRequest = class {
|
|
1823
|
+
var KeqRequest = class KeqRequest {
|
|
1688
1824
|
constructor(options) {
|
|
1689
1825
|
_defineProperty(this, "baseOrigin", void 0);
|
|
1690
1826
|
_defineProperty(this, "qs", void 0);
|
|
1691
1827
|
_defineProperty(this, "global", {});
|
|
1692
|
-
_defineProperty(this, "
|
|
1693
|
-
_defineProperty(this, "
|
|
1828
|
+
_defineProperty(this, "middlewares", []);
|
|
1829
|
+
_defineProperty(this, "__terminalMiddlewares__", []);
|
|
1830
|
+
_defineProperty(this, "__parent__", void 0);
|
|
1694
1831
|
if (options?.baseOrigin) this.baseOrigin = options.baseOrigin;
|
|
1695
1832
|
else this.baseOrigin = Validator.isBrowser() ? location.origin : "http://127.0.0.1";
|
|
1696
1833
|
this.qs = options?.qs;
|
|
1697
|
-
this.
|
|
1834
|
+
this.__terminalMiddlewares__ = options?.terminalMiddlewares || [
|
|
1698
1835
|
keqFlowControlMiddleware(),
|
|
1699
1836
|
keqTimeoutMiddleware(),
|
|
1700
1837
|
keqFetchMiddleware()
|
|
1701
1838
|
];
|
|
1702
|
-
this.
|
|
1839
|
+
this.middlewares = options?.middlewares || [];
|
|
1703
1840
|
}
|
|
1704
1841
|
__formatUrl__(url) {
|
|
1705
1842
|
if (typeof url === "string") return new URL(url, this.baseOrigin);
|
|
1706
1843
|
return new URL(url.href);
|
|
1707
1844
|
}
|
|
1845
|
+
resolveMiddlewares() {
|
|
1846
|
+
if (!this.__parent__) return this.middlewares;
|
|
1847
|
+
return [...this.__parent__.resolveMiddlewares(), ...this.middlewares];
|
|
1848
|
+
}
|
|
1708
1849
|
__fetch__(url, init, locationId) {
|
|
1709
1850
|
return new Keq(this.__formatUrl__(url), {
|
|
1710
1851
|
...init,
|
|
1711
1852
|
locationId,
|
|
1712
1853
|
global: this.global,
|
|
1713
1854
|
qs: this.qs,
|
|
1714
|
-
middlewares: [...this.
|
|
1855
|
+
middlewares: [...this.resolveMiddlewares(), ...this.__terminalMiddlewares__]
|
|
1715
1856
|
});
|
|
1716
1857
|
}
|
|
1717
1858
|
fetch(url, init) {
|
|
@@ -1742,11 +1883,37 @@ var KeqRequest = class {
|
|
|
1742
1883
|
return this.__fetch__(url, { method: "options" }, getLocationId(1));
|
|
1743
1884
|
}
|
|
1744
1885
|
use(firstMiddleware, ...middleware) {
|
|
1745
|
-
this.
|
|
1886
|
+
this.middlewares.push(firstMiddleware, ...middleware);
|
|
1746
1887
|
return this;
|
|
1747
1888
|
}
|
|
1889
|
+
apply(middleware, ...additionalMiddlewares) {
|
|
1890
|
+
return new KeqMiddlewareApplicator(Array.isArray(middleware) ? middleware : [middleware, ...additionalMiddlewares], this.middlewares, this);
|
|
1891
|
+
}
|
|
1892
|
+
/**
|
|
1893
|
+
* @deprecated Use `request.apply(...middlewares).forRoutes(...)` instead.
|
|
1894
|
+
*/
|
|
1748
1895
|
useRouter() {
|
|
1749
|
-
return new KeqRouter(this.
|
|
1896
|
+
return new KeqRouter(this.middlewares);
|
|
1897
|
+
}
|
|
1898
|
+
fork(options) {
|
|
1899
|
+
const child = new KeqRequest({
|
|
1900
|
+
baseOrigin: options?.baseOrigin ?? this.baseOrigin,
|
|
1901
|
+
qs: options?.qs ?? (this.qs ? { ...this.qs } : void 0)
|
|
1902
|
+
});
|
|
1903
|
+
child.__parent__ = this;
|
|
1904
|
+
return child;
|
|
1905
|
+
}
|
|
1906
|
+
inherit(parent) {
|
|
1907
|
+
this.__parent__ = parent;
|
|
1908
|
+
return this;
|
|
1909
|
+
}
|
|
1910
|
+
adopt(child) {
|
|
1911
|
+
child.__parent__ = this;
|
|
1912
|
+
return this;
|
|
1913
|
+
}
|
|
1914
|
+
/** @deprecated Use `middlewares` instead */
|
|
1915
|
+
get preMiddlewares() {
|
|
1916
|
+
return this.middlewares;
|
|
1750
1917
|
}
|
|
1751
1918
|
on(event, listener) {
|
|
1752
1919
|
const middleware = async (context, next) => {
|
|
@@ -1768,6 +1935,6 @@ function createRequest(options) {
|
|
|
1768
1935
|
return new KeqRequest(options);
|
|
1769
1936
|
}
|
|
1770
1937
|
//#endregion
|
|
1771
|
-
export { AbortException, BadGatewayException, BadRequestException, ConflictException, ContentTooLargeException, Exception, ForbiddenException, GatewayTimeoutException, ImATeapotException, InternalServerErrorException, Keq, KeqExecutionContext, KeqMiddlewareExecutor, KeqMiddlewareOrchestrator, KeqRequest, KeqSharedContext, MethodNotAllowedException, NotAcceptableException, NotFoundedException, NotImplementedException, PreconditionFailedException, ProxyAuthenticationRequiredException, RequestException, RequestTimeoutException, ServiceUnavailableException, TimeoutException, TooManyRequestsException, TypeException, UnauthorizedException, UnsupportedMediaTypeException, UriTooLongException, composeMiddleware, composeRoute, createProxyResponse, createRequest, request };
|
|
1938
|
+
export { AbortException, BadGatewayException, BadRequestException, ConflictException, ContentTooLargeException, Exception, ForbiddenException, GatewayTimeoutException, ImATeapotException, InternalServerErrorException, Keq, KeqExecutionContext, KeqMiddlewareApplicator, KeqMiddlewareExecutor, KeqMiddlewareOrchestrator, KeqRequest, KeqSharedContext, MethodNotAllowedException, NotAcceptableException, NotFoundedException, NotImplementedException, PreconditionFailedException, ProxyAuthenticationRequiredException, RequestException, RequestTimeoutException, ServiceUnavailableException, TimeoutException, TooManyRequestsException, TypeException, UnauthorizedException, UnsupportedMediaTypeException, UriTooLongException, composeMiddleware, composeRoute, createProxyResponse, createRequest, request };
|
|
1772
1939
|
|
|
1773
1940
|
//# sourceMappingURL=index.mjs.map
|