@sourceregistry/node-webserver 1.3.1 → 1.4.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/README.md +111 -60
- package/dist/app.d.ts +1 -0
- package/dist/index.cjs.js +2 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +251 -123
- package/dist/index.es.js.map +1 -1
- package/dist/middlewares/index.d.ts +3 -0
- package/dist/middlewares/requestid/index.d.ts +16 -0
- package/dist/middlewares/security/index.d.ts +39 -0
- package/dist/middlewares/timeout/index.d.ts +22 -0
- package/dist/types/router.d.ts +0 -1
- package/dist/types/server.d.ts +30 -3
- package/examples/public-baseline.ts +75 -0
- package/package.json +1 -1
package/dist/index.es.js
CHANGED
|
@@ -1,36 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createServer as t } from "
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
1
|
+
import { randomUUID as e } from "node:crypto";
|
|
2
|
+
import { createServer as t } from "http";
|
|
3
|
+
import { createServer as n } from "https";
|
|
4
|
+
import { TLSSocket as r } from "tls";
|
|
5
|
+
import { Readable as i, Transform as a, Writable as o } from "stream";
|
|
6
|
+
import { WebSocket as s, WebSocketServer as c } from "ws";
|
|
7
|
+
import { parse as l, serialize as u } from "cookie";
|
|
8
|
+
import { createReadStream as d } from "node:fs";
|
|
9
|
+
import { lstat as f, realpath as p, stat as m } from "node:fs/promises";
|
|
10
|
+
import { extname as h, isAbsolute as g, relative as _, resolve as v, sep as y } from "node:path";
|
|
11
|
+
import { Readable as b } from "node:stream";
|
|
11
12
|
//#region \0rolldown/runtime.js
|
|
12
|
-
var
|
|
13
|
+
var x = Object.defineProperty, S = (e, t) => {
|
|
13
14
|
let n = {};
|
|
14
|
-
for (var r in e)
|
|
15
|
+
for (var r in e) x(n, r, {
|
|
15
16
|
get: e[r],
|
|
16
17
|
enumerable: !0
|
|
17
18
|
});
|
|
18
|
-
return t ||
|
|
19
|
+
return t || x(n, Symbol.toStringTag, { value: "Module" }), n;
|
|
19
20
|
};
|
|
20
21
|
//#endregion
|
|
21
22
|
//#region src/utils.ts
|
|
22
|
-
function S(e) {
|
|
23
|
-
return w(e) && e.status >= 400 && e.status < 600;
|
|
24
|
-
}
|
|
25
23
|
function C(e) {
|
|
26
|
-
return
|
|
24
|
+
return T(e) && e.status >= 400 && e.status < 600;
|
|
27
25
|
}
|
|
28
26
|
function w(e) {
|
|
27
|
+
return T(e) && e.status >= 300 && e.status < 400;
|
|
28
|
+
}
|
|
29
|
+
function T(e) {
|
|
29
30
|
return e instanceof Response;
|
|
30
31
|
}
|
|
31
32
|
//#endregion
|
|
32
33
|
//#region src/middlewares/ratelimiter/InMemory.ts
|
|
33
|
-
var
|
|
34
|
+
var E = class {
|
|
34
35
|
constructor(e) {
|
|
35
36
|
this.data = /* @__PURE__ */ new Map(), this.windowMs = e.windowMs, this.startCleanup();
|
|
36
37
|
}
|
|
@@ -56,9 +57,9 @@ var T = class {
|
|
|
56
57
|
async resetAll() {
|
|
57
58
|
this.data.clear();
|
|
58
59
|
}
|
|
59
|
-
},
|
|
60
|
-
function
|
|
61
|
-
let { windowMs: t = 6e4, max: n, key: r = (e) => e.getClientAddress(), message: i = "Too many requests, please try again later.", statusCode: a = 429, headers: o = "include", onRateLimit: s, store: c = new
|
|
60
|
+
}, D = /* @__PURE__ */ S({ fixedWindowLimit: () => O });
|
|
61
|
+
function O(e) {
|
|
62
|
+
let { windowMs: t = 6e4, max: n, key: r = (e) => e.getClientAddress(), message: i = "Too many requests, please try again later.", statusCode: a = 429, headers: o = "include", onRateLimit: s, store: c = new E({ windowMs: t }) } = e;
|
|
62
63
|
return async (e, t) => {
|
|
63
64
|
let l = `rl:${r(e)}`, { current: u, reset: d } = await c.incr(l), f = Math.ceil((d - Date.now()) / 1e3);
|
|
64
65
|
if (u > n) {
|
|
@@ -98,7 +99,7 @@ function D(e) {
|
|
|
98
99
|
}
|
|
99
100
|
//#endregion
|
|
100
101
|
//#region src/middlewares/cros/index.ts
|
|
101
|
-
var
|
|
102
|
+
var ee = /* @__PURE__ */ S({ policy: () => M }), te = [
|
|
102
103
|
"GET",
|
|
103
104
|
"POST",
|
|
104
105
|
"PUT",
|
|
@@ -106,13 +107,13 @@ var O = /* @__PURE__ */ x({ policy: () => P }), k = [
|
|
|
106
107
|
"PATCH",
|
|
107
108
|
"HEAD",
|
|
108
109
|
"OPTIONS"
|
|
109
|
-
],
|
|
110
|
+
], ne = [
|
|
110
111
|
"Accept",
|
|
111
112
|
"Accept-Language",
|
|
112
113
|
"Content-Language",
|
|
113
114
|
"Content-Type",
|
|
114
115
|
"Range"
|
|
115
|
-
],
|
|
116
|
+
], k = [
|
|
116
117
|
"Authorization",
|
|
117
118
|
"X-Auth-Token",
|
|
118
119
|
"X-Requested-With",
|
|
@@ -122,21 +123,21 @@ var O = /* @__PURE__ */ x({ policy: () => P }), k = [
|
|
|
122
123
|
"X-Real-IP",
|
|
123
124
|
"X-Custom-Header"
|
|
124
125
|
];
|
|
125
|
-
function
|
|
126
|
-
return !e || !t ? !1 : t === "*" ? !0 : t === "null" ? e === "null" : Array.isArray(t) ? t.some((t) =>
|
|
126
|
+
function A(e, t) {
|
|
127
|
+
return !e || !t ? !1 : t === "*" ? !0 : t === "null" ? e === "null" : Array.isArray(t) ? t.some((t) => A(e, t)) : typeof t == "function" ? t(e) : t instanceof RegExp ? t.test(e) : e === t;
|
|
127
128
|
}
|
|
128
|
-
function
|
|
129
|
+
function j(e, t) {
|
|
129
130
|
let { origin: n = "*" } = t;
|
|
130
|
-
return e ? n === "*" ? t.credentials ? e : "*" :
|
|
131
|
+
return e ? n === "*" ? t.credentials ? e : "*" : A(e, n) ? e : null : n === "*" ? "*" : null;
|
|
131
132
|
}
|
|
132
|
-
function
|
|
133
|
-
let { methods: t =
|
|
133
|
+
function M(e = {}) {
|
|
134
|
+
let { methods: t = te, allowedHeaders: n = k, exposedHeaders: r, credentials: i = !1, maxAge: a = 86400, onResponse: o } = e, s = t.join(","), c = [...ne, ...n].join(","), l = [
|
|
134
135
|
["Vary", "Origin,Access-Control-Request-Method,Access-Control-Request-Headers"],
|
|
135
136
|
["Access-Control-Allow-Methods", s],
|
|
136
137
|
["Access-Control-Allow-Headers", c]
|
|
137
138
|
];
|
|
138
139
|
return r && l.push(["Access-Control-Expose-Headers", r.join(",")]), i && l.push(["Access-Control-Allow-Credentials", "true"]), a && l.push(["Access-Control-Max-Age", a.toString()]), async (t, n) => {
|
|
139
|
-
let r = t.request, i = r.headers.get("Origin"), a = r.method === "OPTIONS" && i !== null && r.headers.has("Access-Control-Request-Method"), s =
|
|
140
|
+
let r = t.request, i = r.headers.get("Origin"), a = r.method === "OPTIONS" && i !== null && r.headers.has("Access-Control-Request-Method"), s = j(i, e);
|
|
140
141
|
if (a) {
|
|
141
142
|
if (!s) return new Response(null, { status: 403 });
|
|
142
143
|
let e = new Response(null, { status: 204 });
|
|
@@ -158,8 +159,83 @@ function P(e = {}) {
|
|
|
158
159
|
};
|
|
159
160
|
}
|
|
160
161
|
//#endregion
|
|
162
|
+
//#region src/middlewares/security/index.ts
|
|
163
|
+
var N = /* @__PURE__ */ S({ headers: () => F }), P = {
|
|
164
|
+
contentSecurityPolicy: "default-src 'self'; base-uri 'self'; frame-ancestors 'none'; object-src 'none'",
|
|
165
|
+
frameOptions: "DENY",
|
|
166
|
+
referrerPolicy: "no-referrer",
|
|
167
|
+
permissionsPolicy: "geolocation=(), microphone=(), camera=()",
|
|
168
|
+
crossOriginOpenerPolicy: "same-origin",
|
|
169
|
+
crossOriginResourcePolicy: "same-origin",
|
|
170
|
+
strictTransportSecurity: !1
|
|
171
|
+
};
|
|
172
|
+
function F(e = {}) {
|
|
173
|
+
let t = {
|
|
174
|
+
...P,
|
|
175
|
+
...e
|
|
176
|
+
};
|
|
177
|
+
return async (e, n) => {
|
|
178
|
+
let r = await n();
|
|
179
|
+
if (!r) return;
|
|
180
|
+
let i = new Headers(r.headers);
|
|
181
|
+
return I(i, "content-security-policy", t.contentSecurityPolicy), I(i, "x-frame-options", t.frameOptions), I(i, "referrer-policy", t.referrerPolicy), I(i, "permissions-policy", t.permissionsPolicy), I(i, "cross-origin-opener-policy", t.crossOriginOpenerPolicy), I(i, "cross-origin-resource-policy", t.crossOriginResourcePolicy), I(i, "strict-transport-security", t.strictTransportSecurity), new Response(r.body, {
|
|
182
|
+
status: r.status,
|
|
183
|
+
statusText: r.statusText,
|
|
184
|
+
headers: i
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function I(e, t, n) {
|
|
189
|
+
!n || e.has(t) || e.set(t, n);
|
|
190
|
+
}
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region src/middlewares/requestid/index.ts
|
|
193
|
+
var L = /* @__PURE__ */ S({ assign: () => R });
|
|
194
|
+
function R(t = {}) {
|
|
195
|
+
let n = t.headerName?.toLowerCase() ?? "x-request-id", r = t.generate ?? e;
|
|
196
|
+
return async (e, t) => {
|
|
197
|
+
let i = e.request.headers.get(n) ?? r();
|
|
198
|
+
Object.assign(e.locals, { requestId: i });
|
|
199
|
+
let a = await t();
|
|
200
|
+
if (!a) return;
|
|
201
|
+
if (a.headers.has(n)) return a;
|
|
202
|
+
let o = new Headers(a.headers);
|
|
203
|
+
return o.set(n, i), new Response(a.body, {
|
|
204
|
+
status: a.status,
|
|
205
|
+
statusText: a.statusText,
|
|
206
|
+
headers: o
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/middlewares/timeout/index.ts
|
|
212
|
+
var z = /* @__PURE__ */ S({ deadline: () => B });
|
|
213
|
+
function B(e) {
|
|
214
|
+
let { ms: t, status: n = 504, body: r = "Gateway Timeout", onTimeout: i } = e;
|
|
215
|
+
if (!Number.isFinite(t) || t <= 0) throw TypeError("Timeout.deadline requires a positive ms value");
|
|
216
|
+
return async (e, a) => {
|
|
217
|
+
let o = e.request, s = new AbortController(), c = () => s.abort();
|
|
218
|
+
o.signal.addEventListener("abort", c, { once: !0 });
|
|
219
|
+
let l = AbortSignal.any([o.signal, s.signal]);
|
|
220
|
+
e.request = new Request(o, {
|
|
221
|
+
signal: l,
|
|
222
|
+
duplex: o.body ? "half" : void 0
|
|
223
|
+
});
|
|
224
|
+
let u;
|
|
225
|
+
try {
|
|
226
|
+
return await Promise.race([a(), new Promise((e) => {
|
|
227
|
+
u = setTimeout(() => {
|
|
228
|
+
s.abort(), i?.(), e(new Response(r, { status: n }));
|
|
229
|
+
}, t);
|
|
230
|
+
})]);
|
|
231
|
+
} finally {
|
|
232
|
+
o.signal.removeEventListener("abort", c), u && clearTimeout(u);
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
//#endregion
|
|
161
237
|
//#region src/types/RequestMethod.ts
|
|
162
|
-
var
|
|
238
|
+
var V = [
|
|
163
239
|
"GET",
|
|
164
240
|
"PUT",
|
|
165
241
|
"POST",
|
|
@@ -167,7 +243,7 @@ var F = [
|
|
|
167
243
|
"PATCH",
|
|
168
244
|
"HEAD",
|
|
169
245
|
"OPTIONS"
|
|
170
|
-
],
|
|
246
|
+
], H = class {
|
|
171
247
|
static {
|
|
172
248
|
this.cache = /* @__PURE__ */ new Map();
|
|
173
249
|
}
|
|
@@ -177,7 +253,7 @@ var F = [
|
|
|
177
253
|
static set(e, t) {
|
|
178
254
|
this.cache.set(e, t);
|
|
179
255
|
}
|
|
180
|
-
},
|
|
256
|
+
}, U = class {
|
|
181
257
|
constructor() {
|
|
182
258
|
this._routes = [], this._wsRoutes = [], this._nestedRouters = [], this._middlewares = [], this._preHandlers = [], this._postHandlers = [], this.routesSorted = !1, this.wsRoutesSorted = !1;
|
|
183
259
|
}
|
|
@@ -209,7 +285,7 @@ var F = [
|
|
|
209
285
|
return this.addHandler("OPTIONS", e, t, n);
|
|
210
286
|
}
|
|
211
287
|
USE(e, t, ...n) {
|
|
212
|
-
return
|
|
288
|
+
return V.forEach((r) => this.addHandler(r, e, t, n)), this;
|
|
213
289
|
}
|
|
214
290
|
action(e, t, ...n) {
|
|
215
291
|
return this.addHandler("POST", e, async (e) => {
|
|
@@ -300,7 +376,10 @@ var F = [
|
|
|
300
376
|
if (!r.regex.test(n)) continue;
|
|
301
377
|
let i = n.match(r.regex);
|
|
302
378
|
if (!i) continue;
|
|
303
|
-
let a = Object.fromEntries(r.paramNames.map((e, t) =>
|
|
379
|
+
let a = Object.fromEntries(r.paramNames.map((e, t) => {
|
|
380
|
+
let n = i[t + 1];
|
|
381
|
+
return n === void 0 ? void 0 : [e, decodeURIComponent(n)];
|
|
382
|
+
}).filter((e) => e !== void 0)), o = {
|
|
304
383
|
...e,
|
|
305
384
|
params: {
|
|
306
385
|
...e.params,
|
|
@@ -312,7 +391,7 @@ var F = [
|
|
|
312
391
|
},
|
|
313
392
|
websocket: t
|
|
314
393
|
}, s = [...this._middlewares, ...r.middlewares];
|
|
315
|
-
if (await this.applyMiddlewaresWithList(o, s, () => r.handler(o))
|
|
394
|
+
if (await this.applyMiddlewaresWithList(o, s, () => r.handler(o)) !== void 0) return !0;
|
|
316
395
|
}
|
|
317
396
|
return !1;
|
|
318
397
|
}
|
|
@@ -326,7 +405,7 @@ var F = [
|
|
|
326
405
|
let i = r || new Response("No Content", { status: 204 });
|
|
327
406
|
return await this.runPostHandlers(e, i);
|
|
328
407
|
} catch (e) {
|
|
329
|
-
if (
|
|
408
|
+
if (T(e)) return e;
|
|
330
409
|
throw e;
|
|
331
410
|
}
|
|
332
411
|
}
|
|
@@ -362,7 +441,7 @@ var F = [
|
|
|
362
441
|
}), this.routesSorted = !1, this;
|
|
363
442
|
}
|
|
364
443
|
createPathRegex(e) {
|
|
365
|
-
let t =
|
|
444
|
+
let t = H.get(e);
|
|
366
445
|
if (t) return t;
|
|
367
446
|
let n = [], r = !1, i, a = e.split("/").filter(Boolean);
|
|
368
447
|
i = a.reduce((e, t) => t.startsWith("[...") ? e - 10 : t.startsWith("[[") ? e - 5 : t.startsWith("[") ? e - 1 : e + 1, 0);
|
|
@@ -385,7 +464,7 @@ var F = [
|
|
|
385
464
|
isCatchAll: r,
|
|
386
465
|
priority: i
|
|
387
466
|
};
|
|
388
|
-
return
|
|
467
|
+
return H.set(e, s), s;
|
|
389
468
|
}
|
|
390
469
|
createPrefixRegex(e) {
|
|
391
470
|
let t = [], n = !1, r, i = e.split("/").filter(Boolean);
|
|
@@ -416,9 +495,14 @@ var F = [
|
|
|
416
495
|
let n = t.match(e.regex);
|
|
417
496
|
if (!n) return {};
|
|
418
497
|
let r = {};
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
498
|
+
if (e.isCatchAll && e.paramNames.length === 1) {
|
|
499
|
+
let t = n[1]?.replace(/^\//, "");
|
|
500
|
+
t !== void 0 && (r[e.paramNames[0]] = decodeURIComponent(t));
|
|
501
|
+
} else e.paramNames.forEach((e, t) => {
|
|
502
|
+
let i = n[t + 1];
|
|
503
|
+
i !== void 0 && (r[e] = decodeURIComponent(i));
|
|
504
|
+
});
|
|
505
|
+
return r;
|
|
422
506
|
}
|
|
423
507
|
async handleNestedRouters(e, t) {
|
|
424
508
|
let n = [...this._nestedRouters].sort((e, t) => t.priority - e.priority);
|
|
@@ -442,7 +526,10 @@ var F = [
|
|
|
442
526
|
if (!a.regex.test(n) || (r.add(a.method), a.method === "GET" && (i = !0, r.add("HEAD")), !(a.method === t || t === "HEAD" && a.method === "GET"))) continue;
|
|
443
527
|
let o = n.match(a.regex);
|
|
444
528
|
if (!o) continue;
|
|
445
|
-
let s = Object.fromEntries(a.paramNames.map((e, t) =>
|
|
529
|
+
let s = Object.fromEntries(a.paramNames.map((e, t) => {
|
|
530
|
+
let n = o[t + 1];
|
|
531
|
+
return n === void 0 ? void 0 : [e, decodeURIComponent(n)];
|
|
532
|
+
}).filter((e) => e !== void 0));
|
|
446
533
|
return e.params = {
|
|
447
534
|
...e.params,
|
|
448
535
|
...s
|
|
@@ -470,20 +557,17 @@ var F = [
|
|
|
470
557
|
this._wsRoutes.sort((e, t) => t.priority - e.priority), this.wsRoutesSorted = !0;
|
|
471
558
|
}
|
|
472
559
|
formatActionResult(e) {
|
|
473
|
-
return e instanceof Response ? e : e?.type === "failure" && "status" in e ?
|
|
560
|
+
return e instanceof Response ? e : e?.type === "failure" && "status" in e ? W.fail(e.status, e.data) : W.success(200, e ?? void 0);
|
|
474
561
|
}
|
|
475
562
|
handleActionError(e) {
|
|
476
|
-
if (
|
|
477
|
-
if (
|
|
563
|
+
if (C(e)) return W.error(e.status, { message: e.statusText || "Error" });
|
|
564
|
+
if (w(e)) {
|
|
478
565
|
let t = e.headers.get("Location") || "/";
|
|
479
|
-
return
|
|
566
|
+
return W.redirect(e.status, t);
|
|
480
567
|
}
|
|
481
|
-
return console.error(e),
|
|
568
|
+
return console.error(e), W.error(500, { message: "Internal Server Error" });
|
|
482
569
|
}
|
|
483
|
-
|
|
484
|
-
return new e();
|
|
485
|
-
}
|
|
486
|
-
}, R = {
|
|
570
|
+
}, W = {
|
|
487
571
|
success: (e = 200, t) => new Response(JSON.stringify({
|
|
488
572
|
data: t,
|
|
489
573
|
type: "success",
|
|
@@ -516,21 +600,21 @@ var F = [
|
|
|
516
600
|
status: e,
|
|
517
601
|
headers: { "Content-Type": "application/json" }
|
|
518
602
|
})
|
|
519
|
-
},
|
|
603
|
+
}, re = class {
|
|
520
604
|
constructor(e, t) {
|
|
521
605
|
this.raw = e.headers.get("cookie") ?? "", this.setCookieHeader = t;
|
|
522
606
|
}
|
|
523
607
|
get(e, t) {
|
|
524
|
-
return
|
|
608
|
+
return l(this.raw, t)[e];
|
|
525
609
|
}
|
|
526
610
|
getAll(e) {
|
|
527
|
-
return Object.entries(
|
|
611
|
+
return Object.entries(l(this.raw, e)).filter(([, e]) => e !== void 0).map(([e, t]) => ({
|
|
528
612
|
name: e,
|
|
529
613
|
value: t
|
|
530
614
|
}));
|
|
531
615
|
}
|
|
532
616
|
set(e, t, n) {
|
|
533
|
-
this.setCookieHeader(
|
|
617
|
+
this.setCookieHeader(u(e, t, n));
|
|
534
618
|
}
|
|
535
619
|
delete(e, t) {
|
|
536
620
|
this.set(e, "", {
|
|
@@ -538,28 +622,28 @@ var F = [
|
|
|
538
622
|
maxAge: 0
|
|
539
623
|
});
|
|
540
624
|
}
|
|
541
|
-
},
|
|
625
|
+
}, G = class extends Error {
|
|
542
626
|
constructor(e = "Payload Too Large") {
|
|
543
627
|
super(e), this.status = 413, this.name = "PayloadTooLargeError";
|
|
544
628
|
}
|
|
545
|
-
},
|
|
629
|
+
}, K = class extends U {
|
|
546
630
|
constructor(e) {
|
|
547
631
|
super(), this.upgradeHandlerInstalled = !1, this.config = e ?? {
|
|
548
632
|
type: "http",
|
|
549
633
|
options: {}
|
|
550
|
-
}, this.wss = new
|
|
634
|
+
}, this.wss = new c({
|
|
551
635
|
noServer: !0,
|
|
552
636
|
maxPayload: this.config.security?.maxWebSocketPayload ?? 1024 * 1024
|
|
553
637
|
});
|
|
554
638
|
}
|
|
555
639
|
get server() {
|
|
556
640
|
if (!this._server) {
|
|
557
|
-
let
|
|
641
|
+
let e = (e, t) => {
|
|
558
642
|
this.handleRequest(e, t).catch((e) => {
|
|
559
643
|
console.error("Unhandled request error:", e), t.statusCode = 500, t.end("Internal Server Error");
|
|
560
644
|
});
|
|
561
645
|
};
|
|
562
|
-
this._server = this.config.type === "https" ?
|
|
646
|
+
this._server = this.config.type === "https" ? n(this.config.options, e) : t(this.config.options, e), this.configureServerTimeouts(this._server);
|
|
563
647
|
}
|
|
564
648
|
return this._server;
|
|
565
649
|
}
|
|
@@ -580,7 +664,7 @@ var F = [
|
|
|
580
664
|
return;
|
|
581
665
|
}
|
|
582
666
|
let a = this.toRequestEvent(i, r, {
|
|
583
|
-
getClientAddress: () => e
|
|
667
|
+
getClientAddress: () => this.getClientAddress(e),
|
|
584
668
|
setHeader: () => {},
|
|
585
669
|
pushSetCookie: () => {}
|
|
586
670
|
});
|
|
@@ -591,9 +675,9 @@ var F = [
|
|
|
591
675
|
}
|
|
592
676
|
this.wss.handleUpgrade(e, t, n, (e) => {
|
|
593
677
|
this.handleWebSocket(a, e).then((t) => {
|
|
594
|
-
!t && e.readyState ===
|
|
678
|
+
!t && e.readyState === s.OPEN && e.close(1008, "Route not found");
|
|
595
679
|
}).catch((t) => {
|
|
596
|
-
console.error("WebSocket routing error:", t), e.readyState ===
|
|
680
|
+
console.error("WebSocket routing error:", t), e.readyState === s.OPEN && e.close(1011, "Internal error");
|
|
597
681
|
});
|
|
598
682
|
});
|
|
599
683
|
}).catch(() => t.destroy());
|
|
@@ -618,7 +702,7 @@ var F = [
|
|
|
618
702
|
let n = new AbortController(), r = () => n.abort();
|
|
619
703
|
e.once("aborted", r), e.once("close", r), t.once("close", r);
|
|
620
704
|
let i = this.toWebRequest(e, n.signal), a = new URL(i.url), o = {}, s = [], c = this.toRequestEvent(i, a, {
|
|
621
|
-
getClientAddress: () => e
|
|
705
|
+
getClientAddress: () => this.getClientAddress(e),
|
|
622
706
|
setHeader: (e, t) => {
|
|
623
707
|
o[e.toLowerCase()] = t;
|
|
624
708
|
},
|
|
@@ -638,21 +722,21 @@ var F = [
|
|
|
638
722
|
let n = this.toURL(e, !1);
|
|
639
723
|
return this.toRequest(e, n, !1, t);
|
|
640
724
|
}
|
|
641
|
-
toRequest(e, t, n,
|
|
725
|
+
toRequest(e, t, n, r) {
|
|
642
726
|
let a = {
|
|
643
727
|
method: n ? "GET" : e.method,
|
|
644
728
|
headers: this.toHeaders(e.headers),
|
|
645
|
-
signal:
|
|
729
|
+
signal: r,
|
|
646
730
|
duplex: "half"
|
|
647
731
|
};
|
|
648
|
-
return !n && e.method !== "GET" && e.method !== "HEAD" && (a.body =
|
|
732
|
+
return !n && e.method !== "GET" && e.method !== "HEAD" && (a.body = i.toWeb(this.wrapRequestBody(e))), new Request(t, a);
|
|
649
733
|
}
|
|
650
734
|
wrapRequestBody(e) {
|
|
651
735
|
let t = this.config.security?.maxRequestBodySize;
|
|
652
736
|
if (!t) return e;
|
|
653
|
-
let n = 0, r = new
|
|
737
|
+
let n = 0, r = new a({ transform(e, r, i) {
|
|
654
738
|
if (n += Buffer.byteLength(e), n > t) {
|
|
655
|
-
i(new
|
|
739
|
+
i(new G());
|
|
656
740
|
return;
|
|
657
741
|
}
|
|
658
742
|
i(null, e);
|
|
@@ -660,14 +744,31 @@ var F = [
|
|
|
660
744
|
return e.on("aborted", () => r.destroy(/* @__PURE__ */ Error("Request aborted"))), e.on("error", (e) => r.destroy(e)), e.pipe(r), r;
|
|
661
745
|
}
|
|
662
746
|
toURL(e, t) {
|
|
663
|
-
let
|
|
664
|
-
return new URL(e.url ?? "/", `${
|
|
747
|
+
let n = this.resolveProtocol(e, t), r = this.resolveAuthority(e);
|
|
748
|
+
return new URL(e.url ?? "/", `${n}://${r}`);
|
|
749
|
+
}
|
|
750
|
+
resolveProtocol(e, t) {
|
|
751
|
+
let n = this.getTrustedForwardedHeader(e, "x-forwarded-proto")?.split(",")[0]?.trim().toLowerCase();
|
|
752
|
+
return n === "http" || n === "https" ? t ? n === "https" ? "wss" : "ws" : n : e.socket instanceof r ? t ? "wss" : "https" : t ? "ws" : "http";
|
|
665
753
|
}
|
|
666
754
|
resolveAuthority(e) {
|
|
667
|
-
let t = this.config.security?.trustHostHeader ? this.normalizeTrustedHost(
|
|
668
|
-
if (
|
|
669
|
-
let
|
|
670
|
-
return
|
|
755
|
+
let t = this.getTrustedForwardedHeader(e, "x-forwarded-host") ?? e.headers.host, n = this.config.security?.trustHostHeader ? this.normalizeTrustedHost(t) : null;
|
|
756
|
+
if (n) return n;
|
|
757
|
+
let r = this.server.address();
|
|
758
|
+
return r && typeof r == "object" ? `${r.address.includes(":") ? `[${r.address}]` : r.address}:${r.port}` : e.socket.localPort ? `127.0.0.1:${e.socket.localPort}` : "localhost";
|
|
759
|
+
}
|
|
760
|
+
getClientAddress(e) {
|
|
761
|
+
let t = e.socket.remoteAddress ?? "127.0.0.1";
|
|
762
|
+
if (!this.isTrustedProxy(t)) return this.normalizeAddress(t);
|
|
763
|
+
let n = e.headers["x-forwarded-for"];
|
|
764
|
+
if (!n) return this.normalizeAddress(t);
|
|
765
|
+
let r = this.parseForwardedHeader(n);
|
|
766
|
+
r.push(t);
|
|
767
|
+
for (let e = r.length - 1; e >= 0; --e) {
|
|
768
|
+
let t = r[e];
|
|
769
|
+
if (!this.isTrustedProxy(t)) return this.normalizeAddress(t);
|
|
770
|
+
}
|
|
771
|
+
return this.normalizeAddress(r[0] ?? t);
|
|
671
772
|
}
|
|
672
773
|
normalizeTrustedHost(e) {
|
|
673
774
|
if (!e) return null;
|
|
@@ -684,6 +785,30 @@ var F = [
|
|
|
684
785
|
matchesValue(e, t) {
|
|
685
786
|
return (Array.isArray(t) ? t : [t]).some((t) => typeof t == "string" ? t === e : t instanceof RegExp ? t.test(e) : t(e));
|
|
686
787
|
}
|
|
788
|
+
configureServerTimeouts(e) {
|
|
789
|
+
let t = this.config.security, n = this.isDevelopment();
|
|
790
|
+
e.headersTimeout = t?.headersTimeoutMs ?? 3e4, e.requestTimeout = t?.requestTimeoutMs ?? (n ? 0 : 6e4), e.keepAliveTimeout = t?.keepAliveTimeoutMs ?? 5e3;
|
|
791
|
+
}
|
|
792
|
+
isDevelopment() {
|
|
793
|
+
return process.env.NODE_ENV !== "production";
|
|
794
|
+
}
|
|
795
|
+
getTrustedForwardedHeader(e, t) {
|
|
796
|
+
if (!this.isTrustedProxy(e.socket.remoteAddress ?? "")) return;
|
|
797
|
+
let n = e.headers[t];
|
|
798
|
+
return Array.isArray(n) ? n[0] : n;
|
|
799
|
+
}
|
|
800
|
+
isTrustedProxy(e) {
|
|
801
|
+
let t = this.config.security?.trustedProxies;
|
|
802
|
+
if (!t) return !1;
|
|
803
|
+
let n = this.normalizeAddress(e);
|
|
804
|
+
return n !== e && this.matchesValue(n, t) ? !0 : this.matchesValue(e, t);
|
|
805
|
+
}
|
|
806
|
+
normalizeAddress(e) {
|
|
807
|
+
return e.startsWith("::ffff:") ? e.slice(7) : e;
|
|
808
|
+
}
|
|
809
|
+
parseForwardedHeader(e) {
|
|
810
|
+
return (Array.isArray(e) ? e.join(",") : e).split(",").map((e) => this.normalizeAddress(e.trim())).filter(Boolean);
|
|
811
|
+
}
|
|
687
812
|
toHeaders(e) {
|
|
688
813
|
let t = new Headers();
|
|
689
814
|
for (let [n, r] of Object.entries(e)) if (r !== void 0) {
|
|
@@ -705,15 +830,15 @@ var F = [
|
|
|
705
830
|
return Number.isFinite(r) && r <= t;
|
|
706
831
|
}
|
|
707
832
|
handleError(e) {
|
|
708
|
-
if (e instanceof
|
|
709
|
-
if (
|
|
833
|
+
if (e instanceof G) return new Response(e.message, { status: e.status });
|
|
834
|
+
if (C(e)) return new Response(JSON.stringify({
|
|
710
835
|
error: e.statusText || "Error",
|
|
711
836
|
status: e.status
|
|
712
837
|
}), {
|
|
713
838
|
status: e.status,
|
|
714
839
|
headers: { "Content-Type": "application/json" }
|
|
715
840
|
});
|
|
716
|
-
if (
|
|
841
|
+
if (w(e)) {
|
|
717
842
|
let t = e.headers.get("Location") || "/";
|
|
718
843
|
return new Response(null, {
|
|
719
844
|
status: e.status,
|
|
@@ -729,10 +854,10 @@ var F = [
|
|
|
729
854
|
e.end();
|
|
730
855
|
return;
|
|
731
856
|
}
|
|
732
|
-
let n = t.body.getReader(), r =
|
|
857
|
+
let n = t.body.getReader(), r = o.toWeb(e).getWriter(), i = !1, a = async () => {
|
|
733
858
|
i || (i = !0, await n.cancel().catch(() => {}));
|
|
734
859
|
}, s = () => {
|
|
735
|
-
|
|
860
|
+
a();
|
|
736
861
|
};
|
|
737
862
|
e.once("close", s);
|
|
738
863
|
try {
|
|
@@ -743,7 +868,7 @@ var F = [
|
|
|
743
868
|
}
|
|
744
869
|
i = !0;
|
|
745
870
|
} catch (e) {
|
|
746
|
-
if (await
|
|
871
|
+
if (await a(), !this.isPrematureCloseError(e)) throw e;
|
|
747
872
|
} finally {
|
|
748
873
|
e.off("close", s), await r.close().catch(() => {});
|
|
749
874
|
}
|
|
@@ -803,7 +928,10 @@ var F = [
|
|
|
803
928
|
r && t.set(n, r);
|
|
804
929
|
}
|
|
805
930
|
toRequestEvent(e, t, n) {
|
|
806
|
-
let r = new
|
|
931
|
+
let r = new re(e, n.pushSetCookie), i = this.config, a = {}, o = {
|
|
932
|
+
name: "node-webserver",
|
|
933
|
+
dev: this.isDevelopment()
|
|
934
|
+
}, s = /* @__PURE__ */ new Set(), c = {
|
|
807
935
|
request: e,
|
|
808
936
|
url: t,
|
|
809
937
|
cookies: r,
|
|
@@ -828,7 +956,7 @@ var F = [
|
|
|
828
956
|
}, l = this.createEventFetch(c, n);
|
|
829
957
|
return i.locals && Object.assign(a, i.locals(c)), i.platform && Object.assign(o, i.platform(c)), c;
|
|
830
958
|
}
|
|
831
|
-
},
|
|
959
|
+
}, q = {
|
|
832
960
|
".avif": "image/avif",
|
|
833
961
|
".css": "text/css; charset=utf-8",
|
|
834
962
|
".gif": "image/gif",
|
|
@@ -846,24 +974,24 @@ var F = [
|
|
|
846
974
|
".wasm": "application/wasm",
|
|
847
975
|
".webp": "image/webp",
|
|
848
976
|
".xml": "application/xml; charset=utf-8"
|
|
849
|
-
},
|
|
977
|
+
}, J = {
|
|
850
978
|
index: "index.html",
|
|
851
979
|
cacheControl: "public, max-age=0",
|
|
852
980
|
dotFiles: "ignore"
|
|
853
981
|
};
|
|
854
|
-
async function
|
|
855
|
-
let r =
|
|
856
|
-
...
|
|
982
|
+
async function Y(e, t, n = {}) {
|
|
983
|
+
let r = $(t), i = {
|
|
984
|
+
...J,
|
|
857
985
|
...n
|
|
858
|
-
}, a = await
|
|
986
|
+
}, a = await X(e), o = ie(r, i.dotFiles);
|
|
859
987
|
if (o instanceof Response) return o;
|
|
860
|
-
let s =
|
|
861
|
-
if (!
|
|
862
|
-
let c = await
|
|
988
|
+
let s = v(a, o.length > 0 ? o.join(y) : "");
|
|
989
|
+
if (!Q(a, s)) return new Response("Forbidden", { status: 403 });
|
|
990
|
+
let c = await ae(s, a, i.index);
|
|
863
991
|
if (c instanceof Response) return c;
|
|
864
|
-
let l = await
|
|
992
|
+
let l = await m(c), u = new Headers({
|
|
865
993
|
"content-length": String(l.size),
|
|
866
|
-
"content-type":
|
|
994
|
+
"content-type": oe(c),
|
|
867
995
|
"cache-control": i.cacheControl,
|
|
868
996
|
"last-modified": l.mtime.toUTCString(),
|
|
869
997
|
"x-content-type-options": "nosniff"
|
|
@@ -871,18 +999,18 @@ async function W(e, t, n = {}) {
|
|
|
871
999
|
if (n.headers) {
|
|
872
1000
|
let e = typeof n.headers == "function" ? n.headers(c, l) : n.headers;
|
|
873
1001
|
new Headers(e).forEach((e, t) => {
|
|
874
|
-
|
|
1002
|
+
u.set(t, e);
|
|
875
1003
|
});
|
|
876
1004
|
}
|
|
877
|
-
return new Response(
|
|
1005
|
+
return new Response(b.toWeb(d(c)), {
|
|
878
1006
|
status: 200,
|
|
879
|
-
headers:
|
|
1007
|
+
headers: u
|
|
880
1008
|
});
|
|
881
1009
|
}
|
|
882
|
-
async function
|
|
883
|
-
return
|
|
1010
|
+
async function X(e) {
|
|
1011
|
+
return p(e);
|
|
884
1012
|
}
|
|
885
|
-
function
|
|
1013
|
+
function ie(e, t) {
|
|
886
1014
|
if (e.includes("\0")) return new Response("Bad Request", { status: 400 });
|
|
887
1015
|
let n = e.replace(/\\/g, "/").split("/").filter(Boolean), r = [];
|
|
888
1016
|
for (let e of n) {
|
|
@@ -903,43 +1031,43 @@ function K(e, t) {
|
|
|
903
1031
|
}
|
|
904
1032
|
return r;
|
|
905
1033
|
}
|
|
906
|
-
async function
|
|
1034
|
+
async function ae(e, t, n) {
|
|
907
1035
|
try {
|
|
908
|
-
return (await
|
|
1036
|
+
return (await f(e)).isDirectory() ? Z(v(e, n), t) : Z(e, t);
|
|
909
1037
|
} catch {
|
|
910
1038
|
return new Response("Not Found", { status: 404 });
|
|
911
1039
|
}
|
|
912
1040
|
}
|
|
913
|
-
async function
|
|
1041
|
+
async function Z(e, t) {
|
|
914
1042
|
try {
|
|
915
|
-
let n = await
|
|
916
|
-
return
|
|
1043
|
+
let n = await p(e);
|
|
1044
|
+
return Q(t, n) ? (await m(n)).isFile() ? n : new Response("Not Found", { status: 404 }) : new Response("Forbidden", { status: 403 });
|
|
917
1045
|
} catch {
|
|
918
1046
|
return new Response("Not Found", { status: 404 });
|
|
919
1047
|
}
|
|
920
1048
|
}
|
|
921
|
-
function
|
|
922
|
-
let n =
|
|
923
|
-
return n === "" || !n.startsWith("..") && !
|
|
1049
|
+
function Q(e, t) {
|
|
1050
|
+
let n = _(e, t);
|
|
1051
|
+
return n === "" || !n.startsWith("..") && !g(n);
|
|
924
1052
|
}
|
|
925
|
-
function
|
|
926
|
-
return
|
|
1053
|
+
function oe(e) {
|
|
1054
|
+
return q[h(e).toLowerCase()] ?? "application/octet-stream";
|
|
927
1055
|
}
|
|
928
|
-
function
|
|
1056
|
+
function $(e) {
|
|
929
1057
|
return typeof e.params.path == "string" ? e.params.path : e.url.pathname.replace(/^\/+/, "");
|
|
930
1058
|
}
|
|
931
|
-
var
|
|
1059
|
+
var se = (e, t = {}) => (n) => Y(e, n, t), ce = (e, ...t) => async (n) => {
|
|
932
1060
|
let r = {};
|
|
933
1061
|
for (let e of t) {
|
|
934
1062
|
let t = await e(n);
|
|
935
|
-
if (
|
|
1063
|
+
if (T(t)) return t;
|
|
936
1064
|
t && typeof t == "object" && Object.assign(r, t);
|
|
937
1065
|
}
|
|
938
1066
|
return e(Object.assign(n, { context: r }));
|
|
939
1067
|
};
|
|
940
1068
|
//#endregion
|
|
941
1069
|
//#region src/helpers/sse.ts
|
|
942
|
-
function
|
|
1070
|
+
function le(e, t = {}) {
|
|
943
1071
|
let n = [];
|
|
944
1072
|
if (t.comment) for (let e of t.comment.split(/\r?\n/)) n.push(`: ${e}`);
|
|
945
1073
|
if (t.event && n.push(`event: ${t.event}`), t.id && n.push(`id: ${t.id}`), t.retry !== void 0 && n.push(`retry: ${t.retry}`), e !== void 0) {
|
|
@@ -948,7 +1076,7 @@ function ee(e, t = {}) {
|
|
|
948
1076
|
}
|
|
949
1077
|
return `${n.join("\n")}\n\n`;
|
|
950
1078
|
}
|
|
951
|
-
var
|
|
1079
|
+
var ue = (e, t = {}) => (n) => {
|
|
952
1080
|
let r = new TextEncoder(), i = null, a = !1, o, s = async () => {
|
|
953
1081
|
if (!a) {
|
|
954
1082
|
a = !0;
|
|
@@ -964,7 +1092,7 @@ var te = (e, t = {}) => (n) => {
|
|
|
964
1092
|
async start(t) {
|
|
965
1093
|
i = t;
|
|
966
1094
|
let c = (e, n = {}) => {
|
|
967
|
-
a || t.enqueue(r.encode(
|
|
1095
|
+
a || t.enqueue(r.encode(le(e, n)));
|
|
968
1096
|
};
|
|
969
1097
|
n.request.signal.addEventListener("abort", () => {
|
|
970
1098
|
s();
|
|
@@ -992,7 +1120,7 @@ var te = (e, t = {}) => (n) => {
|
|
|
992
1120
|
...t.headers
|
|
993
1121
|
}
|
|
994
1122
|
});
|
|
995
|
-
},
|
|
1123
|
+
}, de = async (e, t) => {
|
|
996
1124
|
let n = JSON.stringify(await e);
|
|
997
1125
|
return new Response(n, {
|
|
998
1126
|
...t,
|
|
@@ -1003,19 +1131,19 @@ var te = (e, t = {}) => (n) => {
|
|
|
1003
1131
|
}
|
|
1004
1132
|
});
|
|
1005
1133
|
};
|
|
1006
|
-
function
|
|
1134
|
+
function fe(e, t) {
|
|
1007
1135
|
throw new Response(null, {
|
|
1008
1136
|
status: e,
|
|
1009
1137
|
headers: { location: t.toString() }
|
|
1010
1138
|
});
|
|
1011
1139
|
}
|
|
1012
|
-
function
|
|
1140
|
+
function pe(e, t) {
|
|
1013
1141
|
throw new Response(JSON.stringify(typeof t == "string" ? { message: t } : t), {
|
|
1014
1142
|
status: e,
|
|
1015
1143
|
headers: { "content-type": "application/json" }
|
|
1016
1144
|
});
|
|
1017
1145
|
}
|
|
1018
|
-
var
|
|
1146
|
+
var me = async (e, t) => {
|
|
1019
1147
|
let n = await e;
|
|
1020
1148
|
return new Response(n, {
|
|
1021
1149
|
...t,
|
|
@@ -1025,7 +1153,7 @@ var ae = async (e, t) => {
|
|
|
1025
1153
|
...t?.headers
|
|
1026
1154
|
}
|
|
1027
1155
|
});
|
|
1028
|
-
},
|
|
1156
|
+
}, he = async (e, t) => {
|
|
1029
1157
|
let n = await e;
|
|
1030
1158
|
return new Response(n, {
|
|
1031
1159
|
...t,
|
|
@@ -1037,6 +1165,6 @@ var ae = async (e, t) => {
|
|
|
1037
1165
|
});
|
|
1038
1166
|
};
|
|
1039
1167
|
//#endregion
|
|
1040
|
-
export {
|
|
1168
|
+
export { W as Action, ee as CORS, D as RateLimiter, L as RequestId, V as RequestMethods, U as Router, N as Security, z as Timeout, K as WebServer, se as dir, ce as enhance, pe as error, he as html, C as isHttpError, w as isRedirect, T as isResponse, de as json, fe as redirect, Y as serveStatic, ue as sse, me as text };
|
|
1041
1169
|
|
|
1042
1170
|
//# sourceMappingURL=index.es.js.map
|