@orkestrel/middleware 0.0.20 → 0.0.22
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/src/core/index.cjs +27 -27
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.js +28 -28
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +6 -6
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.js +6 -6
- package/dist/src/server/index.js.map +1 -1
- package/package.json +19 -19
package/dist/src/core/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { integerShape, isBoolean, isFiniteNumber, isFunction, isRecord, isString, jsonShape, stringShape } from "@orkestrel/contract";
|
|
1
|
+
import { integerShape, isArray, isBoolean, isError, isFiniteNumber, isFunction, isInstance, isInteger, isNumber, isObject, isRecord, isString, jsonShape, stringShape } from "@orkestrel/contract";
|
|
2
2
|
import { HTTPError, clearCookie, computeBodyETag, computeClientKey, isCompressibleType, isHTTPError, isValidRequestId, matchesETag, mergeVary, negotiateEncoding, readSignedCookie, resolveOrigin, resolveSecure, resolveSecurityHeader, signToken, verifyToken, writeSignedCookie } from "@orkestrel/server";
|
|
3
3
|
import { linkSignal } from "@orkestrel/abort";
|
|
4
4
|
import { createBudget } from "@orkestrel/budget";
|
|
@@ -198,11 +198,11 @@ function matchesTrustedEntry(address, entry) {
|
|
|
198
198
|
const networkParts = network.split(".");
|
|
199
199
|
const addressParts = address.split(".");
|
|
200
200
|
if (networkParts.length !== 4 || addressParts.length !== 4) return false;
|
|
201
|
-
if (!
|
|
201
|
+
if (!isInteger(bits) || bits < 8 || bits > 32) return false;
|
|
202
202
|
const networkOctets = networkParts.map(Number);
|
|
203
203
|
const addressOctets = addressParts.map(Number);
|
|
204
|
-
if (networkOctets.some((value) => !
|
|
205
|
-
if (addressOctets.some((value) => !
|
|
204
|
+
if (networkOctets.some((value) => !isInteger(value) || value < 0 || value > 255)) return false;
|
|
205
|
+
if (addressOctets.some((value) => !isInteger(value) || value < 0 || value > 255)) return false;
|
|
206
206
|
const networkInt = (networkOctets[0] ?? 0) << 24 | (networkOctets[1] ?? 0) << 16 | (networkOctets[2] ?? 0) << 8 | (networkOctets[3] ?? 0);
|
|
207
207
|
const addressInt = (addressOctets[0] ?? 0) << 24 | (addressOctets[1] ?? 0) << 16 | (addressOctets[2] ?? 0) << 8 | (addressOctets[3] ?? 0);
|
|
208
208
|
const mask = bits === 32 ? -1 : ~((1 << 32 - bits) - 1);
|
|
@@ -437,7 +437,7 @@ async function compressResponse(request, context, response, options) {
|
|
|
437
437
|
const declaredLength = response.headers.get("content-length");
|
|
438
438
|
if (declaredLength !== null) {
|
|
439
439
|
const declared = Number(declaredLength);
|
|
440
|
-
if (
|
|
440
|
+
if (isFiniteNumber(declared) && declared < options.threshold) return response;
|
|
441
441
|
}
|
|
442
442
|
const buffer = await response.arrayBuffer();
|
|
443
443
|
if (buffer.byteLength < options.threshold) return rebuildResponse(buffer, response);
|
|
@@ -607,14 +607,14 @@ function snapshotSession(session) {
|
|
|
607
607
|
* ```
|
|
608
608
|
*/
|
|
609
609
|
function isSession(value) {
|
|
610
|
-
if (
|
|
610
|
+
if (!isObject(value)) return false;
|
|
611
611
|
const id = Reflect.get(value, "id");
|
|
612
612
|
const state = Reflect.get(value, "state");
|
|
613
|
-
if (!isString(id) || !(state
|
|
613
|
+
if (!isString(id) || !isInstance(state, Map)) return false;
|
|
614
614
|
const set = Reflect.get(value, "set");
|
|
615
615
|
const remove = Reflect.get(value, "delete");
|
|
616
616
|
const clear = Reflect.get(value, "clear");
|
|
617
|
-
return
|
|
617
|
+
return isFunction(set) && isFunction(remove) && isFunction(clear);
|
|
618
618
|
}
|
|
619
619
|
/**
|
|
620
620
|
* Determines whether a value implements {@link SessionControlInterface} — a
|
|
@@ -630,7 +630,7 @@ function isSession(value) {
|
|
|
630
630
|
*/
|
|
631
631
|
function isSessionControl(value) {
|
|
632
632
|
if (!isRecord(value)) return false;
|
|
633
|
-
return
|
|
633
|
+
return isFunction(value.regenerate) && isFunction(value.destroy);
|
|
634
634
|
}
|
|
635
635
|
/**
|
|
636
636
|
* Determines whether a value is one staged {@link MultipartFile} record — a
|
|
@@ -654,7 +654,7 @@ function isSessionControl(value) {
|
|
|
654
654
|
*/
|
|
655
655
|
function isMultipartFile(value) {
|
|
656
656
|
if (!isRecord(value)) return false;
|
|
657
|
-
return isString(value.field) && isString(value.name) &&
|
|
657
|
+
return isString(value.field) && isString(value.name) && isNumber(value.size) && isString(value.mime) && isBoolean(value.validated) && isString(value.status) && isString(value.path);
|
|
658
658
|
}
|
|
659
659
|
/**
|
|
660
660
|
* Determines whether a value implements {@link MultipartBody} — a total
|
|
@@ -673,7 +673,7 @@ function isMultipartBody(value) {
|
|
|
673
673
|
if (!isRecord(value)) return false;
|
|
674
674
|
if (!isRecord(value.files) || !isRecord(value.fields)) return false;
|
|
675
675
|
for (const entries of Object.values(value.files)) {
|
|
676
|
-
if (!
|
|
676
|
+
if (!isArray(entries)) return false;
|
|
677
677
|
for (const entry of entries) if (!isMultipartFile(entry)) return false;
|
|
678
678
|
}
|
|
679
679
|
for (const fieldValue of Object.values(value.fields)) if (!isString(fieldValue)) return false;
|
|
@@ -790,7 +790,7 @@ var MemorySessionStore = class {
|
|
|
790
790
|
#evict;
|
|
791
791
|
constructor(options) {
|
|
792
792
|
validateSessionLimits(options);
|
|
793
|
-
if (options?.capacity !== void 0 && (!
|
|
793
|
+
if (options?.capacity !== void 0 && (!isInteger(options.capacity) || options.capacity <= 0)) throw new TypeError("MemorySessionStore requires options.capacity to be a positive integer when provided");
|
|
794
794
|
if (options?.evict !== void 0 && !isFunction(options.evict)) throw new TypeError("MemorySessionStore requires options.evict to be a function when provided");
|
|
795
795
|
this.#entries = /* @__PURE__ */ new Map();
|
|
796
796
|
this.#ttl = options?.ttl;
|
|
@@ -976,7 +976,7 @@ function createBoundary(options) {
|
|
|
976
976
|
report(error);
|
|
977
977
|
} catch {}
|
|
978
978
|
if (isHTTPError(error)) return new Response(error.message, { status: error.status });
|
|
979
|
-
const message = expose ? error
|
|
979
|
+
const message = expose ? isError(error) ? error.message : String(error) : "internal server error";
|
|
980
980
|
return new Response(message, { status: 500 });
|
|
981
981
|
}
|
|
982
982
|
};
|
|
@@ -1035,7 +1035,7 @@ function createTelemetry(options) {
|
|
|
1035
1035
|
function createCompression(options) {
|
|
1036
1036
|
if (options?.threshold !== void 0 && (!isFiniteNumber(options.threshold) || options.threshold < 0)) throw new TypeError("CompressionOptions.threshold must be a finite number when provided");
|
|
1037
1037
|
if (options?.filter !== void 0 && !isFunction(options.filter)) throw new TypeError("CompressionOptions.filter must be a function when provided");
|
|
1038
|
-
if (options?.encodings !== void 0 && !
|
|
1038
|
+
if (options?.encodings !== void 0 && !isArray(options.encodings)) throw new TypeError("CompressionOptions.encodings must be an array when provided");
|
|
1039
1039
|
const threshold = options?.threshold ?? 1024;
|
|
1040
1040
|
const encodings = detectEncodings(options?.encodings ?? DEFAULT_COMPRESSION_ENCODINGS);
|
|
1041
1041
|
const filter = options?.filter;
|
|
@@ -1126,13 +1126,13 @@ function createSecurity(options) {
|
|
|
1126
1126
|
* ```
|
|
1127
1127
|
*/
|
|
1128
1128
|
function createCors(options) {
|
|
1129
|
-
if (options?.origin !== void 0 && !isString(options.origin) && !
|
|
1130
|
-
if (options?.methods !== void 0 && !
|
|
1131
|
-
if (options?.headers !== void 0 && !
|
|
1129
|
+
if (options?.origin !== void 0 && !isString(options.origin) && !isArray(options.origin)) throw new TypeError("CorsOptions.origin must be a string or string array when provided");
|
|
1130
|
+
if (options?.methods !== void 0 && !isArray(options.methods)) throw new TypeError("CorsOptions.methods must be an array when provided");
|
|
1131
|
+
if (options?.headers !== void 0 && !isArray(options.headers)) throw new TypeError("CorsOptions.headers must be an array when provided");
|
|
1132
1132
|
const origin = options?.origin ?? "*";
|
|
1133
1133
|
const methods = options?.methods ?? DEFAULT_CORS_METHODS;
|
|
1134
1134
|
const headers = options?.headers ?? DEFAULT_CORS_HEADERS;
|
|
1135
|
-
const reflecting =
|
|
1135
|
+
const reflecting = isArray(origin);
|
|
1136
1136
|
return async (request, context, next) => {
|
|
1137
1137
|
const requestOrigin = request.headers.get("origin") ?? void 0;
|
|
1138
1138
|
const allowOrigin = resolveOrigin(origin, requestOrigin);
|
|
@@ -1218,10 +1218,10 @@ function createForwarded(options) {
|
|
|
1218
1218
|
if (!isRecord(options) || hasProxies === hasTrusted) throw new TypeError("ForwardedOptions requires exactly one of proxies or trusted");
|
|
1219
1219
|
if (hasProxies) {
|
|
1220
1220
|
const proxies = options.proxies;
|
|
1221
|
-
if (!
|
|
1221
|
+
if (!isInteger(proxies) || proxies < 1) throw new TypeError("ForwardedOptions.proxies must be a positive integer");
|
|
1222
1222
|
} else {
|
|
1223
1223
|
const trusted = options.trusted;
|
|
1224
|
-
if (!
|
|
1224
|
+
if (!isArray(trusted)) throw new TypeError("ForwardedOptions.trusted must be an array when provided");
|
|
1225
1225
|
}
|
|
1226
1226
|
const trust = hasProxies ? { proxies: options.proxies } : { trusted: options.trusted };
|
|
1227
1227
|
return async (request, context, next) => {
|
|
@@ -1284,7 +1284,7 @@ function createETag(options) {
|
|
|
1284
1284
|
* ```
|
|
1285
1285
|
*/
|
|
1286
1286
|
function createBearer(options) {
|
|
1287
|
-
if (!isString(options.secret) && (!
|
|
1287
|
+
if (!isString(options.secret) && (!isArray(options.secret) || !options.secret.every(isString))) throw new TypeError("BearerOptions.secret must be a string or string array");
|
|
1288
1288
|
if (options.header !== void 0 && !isString(options.header)) throw new TypeError("BearerOptions.header must be a string when provided");
|
|
1289
1289
|
if (options.scheme !== void 0 && !isString(options.scheme)) throw new TypeError("BearerOptions.scheme must be a string when provided");
|
|
1290
1290
|
const secret = options.secret;
|
|
@@ -1320,9 +1320,9 @@ function createBearer(options) {
|
|
|
1320
1320
|
* ```
|
|
1321
1321
|
*/
|
|
1322
1322
|
function createLimiter(options) {
|
|
1323
|
-
if (!
|
|
1323
|
+
if (!isInteger(options.max) || options.max <= 0) throw new TypeError("LimiterOptions.max must be a positive integer");
|
|
1324
1324
|
if (!isFiniteNumber(options.window) || options.window <= 0) throw new TypeError("LimiterOptions.window must be a positive finite number");
|
|
1325
|
-
if (options.capacity !== void 0 && (!
|
|
1325
|
+
if (options.capacity !== void 0 && (!isInteger(options.capacity) || options.capacity <= 0)) throw new TypeError("LimiterOptions.capacity must be a positive integer when provided");
|
|
1326
1326
|
if (options.key !== void 0 && !isFunction(options.key)) throw new TypeError("LimiterOptions.key must be a function when provided");
|
|
1327
1327
|
if (options.message !== void 0 && !isString(options.message)) throw new TypeError("LimiterOptions.message must be a string when provided");
|
|
1328
1328
|
if (options.clock !== void 0 && !isFunction(options.clock)) throw new TypeError("LimiterOptions.clock must be a function when provided");
|
|
@@ -1512,11 +1512,11 @@ function createSession(options) {
|
|
|
1512
1512
|
* ```
|
|
1513
1513
|
*/
|
|
1514
1514
|
function createCSRF(options) {
|
|
1515
|
-
if (!isString(options.secret) && (!
|
|
1515
|
+
if (!isString(options.secret) && (!isArray(options.secret) || !options.secret.every(isString))) throw new TypeError("CSRFOptions.secret must be a string or string array");
|
|
1516
1516
|
if (options.cookie !== void 0 && !isString(options.cookie)) throw new TypeError("CSRFOptions.cookie must be a string when provided");
|
|
1517
1517
|
if (options.header !== void 0 && !isString(options.header)) throw new TypeError("CSRFOptions.header must be a string when provided");
|
|
1518
1518
|
if (options.field !== void 0 && !isString(options.field)) throw new TypeError("CSRFOptions.field must be a string when provided");
|
|
1519
|
-
if (options.safe !== void 0 && !
|
|
1519
|
+
if (options.safe !== void 0 && !isArray(options.safe)) throw new TypeError("CSRFOptions.safe must be an array when provided");
|
|
1520
1520
|
const secret = options.secret;
|
|
1521
1521
|
const cookieName = options.cookie ?? "csrf";
|
|
1522
1522
|
const header = options.header ?? "x-csrf-token";
|
|
@@ -1569,7 +1569,7 @@ function createCSRF(options) {
|
|
|
1569
1569
|
* ```
|
|
1570
1570
|
*/
|
|
1571
1571
|
function only(paths, handler) {
|
|
1572
|
-
const matches = new Set(
|
|
1572
|
+
const matches = new Set(isString(paths) ? [paths] : paths);
|
|
1573
1573
|
return async (request, context, next) => {
|
|
1574
1574
|
if (matches.has(context.url.pathname)) return handler(request, context, next);
|
|
1575
1575
|
return next();
|
|
@@ -1590,7 +1590,7 @@ function only(paths, handler) {
|
|
|
1590
1590
|
* ```
|
|
1591
1591
|
*/
|
|
1592
1592
|
function except(paths, handler) {
|
|
1593
|
-
const matches = new Set(
|
|
1593
|
+
const matches = new Set(isString(paths) ? [paths] : paths);
|
|
1594
1594
|
return async (request, context, next) => {
|
|
1595
1595
|
if (matches.has(context.url.pathname)) return next();
|
|
1596
1596
|
return handler(request, context, next);
|
|
@@ -1612,7 +1612,7 @@ function except(paths, handler) {
|
|
|
1612
1612
|
* ```
|
|
1613
1613
|
*/
|
|
1614
1614
|
function createCookieTransport(options) {
|
|
1615
|
-
if (!isString(options.secret) && (!
|
|
1615
|
+
if (!isString(options.secret) && (!isArray(options.secret) || !options.secret.every(isString))) throw new TypeError("CookieTransportOptions.secret must be a string or string array");
|
|
1616
1616
|
if (options.name !== void 0 && !isString(options.name)) throw new TypeError("CookieTransportOptions.name must be a string when provided");
|
|
1617
1617
|
const name = options.name ?? "session";
|
|
1618
1618
|
const secret = options.secret;
|