@sourceregistry/node-webserver 1.0.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/LICENSE +201 -0
- package/README.md +452 -0
- package/dist/app.d.ts +12 -0
- package/dist/index.cjs.js +2 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.es.js +936 -0
- package/dist/index.es.js.map +1 -0
- package/dist/middlewares/cros/index.d.ts +66 -0
- package/dist/middlewares/index.d.ts +2 -0
- package/dist/middlewares/ratelimiter/InMemory.d.ts +16 -0
- package/dist/middlewares/ratelimiter/index.d.ts +50 -0
- package/dist/middlewares/ratelimiter/storage.d.ts +8 -0
- package/dist/static.d.ts +9 -0
- package/dist/types/Cookies.d.ts +17 -0
- package/dist/types/MaybePromise.d.ts +1 -0
- package/dist/types/RequestEvent.d.ts +48 -0
- package/dist/types/RequestMethod.d.ts +2 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/router.d.ts +109 -0
- package/dist/types/server.d.ts +84 -0
- package/dist/utils.d.ts +2 -0
- package/examples/simple.ts +11 -0
- package/package.json +103 -0
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,936 @@
|
|
|
1
|
+
import { createReadStream as k } from "node:fs";
|
|
2
|
+
import { stat as W, realpath as L, lstat as I } from "node:fs/promises";
|
|
3
|
+
import { sep as D, resolve as O, relative as $, isAbsolute as U, extname as F } from "node:path";
|
|
4
|
+
import { Readable as z } from "node:stream";
|
|
5
|
+
import { createServer as B } from "http";
|
|
6
|
+
import { createServer as q } from "https";
|
|
7
|
+
import { TLSSocket as X } from "tls";
|
|
8
|
+
import { Readable as G, Transform as J, Writable as V } from "stream";
|
|
9
|
+
import { WebSocketServer as K, WebSocket as P } from "ws";
|
|
10
|
+
import { parse as E, serialize as Y } from "cookie";
|
|
11
|
+
const Q = {
|
|
12
|
+
".avif": "image/avif",
|
|
13
|
+
".css": "text/css; charset=utf-8",
|
|
14
|
+
".gif": "image/gif",
|
|
15
|
+
".html": "text/html; charset=utf-8",
|
|
16
|
+
".ico": "image/x-icon",
|
|
17
|
+
".jpg": "image/jpeg",
|
|
18
|
+
".jpeg": "image/jpeg",
|
|
19
|
+
".js": "text/javascript; charset=utf-8",
|
|
20
|
+
".json": "application/json; charset=utf-8",
|
|
21
|
+
".mjs": "text/javascript; charset=utf-8",
|
|
22
|
+
".pdf": "application/pdf",
|
|
23
|
+
".png": "image/png",
|
|
24
|
+
".svg": "image/svg+xml; charset=utf-8",
|
|
25
|
+
".txt": "text/plain; charset=utf-8",
|
|
26
|
+
".wasm": "application/wasm",
|
|
27
|
+
".webp": "image/webp",
|
|
28
|
+
".xml": "application/xml; charset=utf-8"
|
|
29
|
+
}, Z = {
|
|
30
|
+
index: "index.html",
|
|
31
|
+
cacheControl: "public, max-age=0",
|
|
32
|
+
dotFiles: "ignore"
|
|
33
|
+
};
|
|
34
|
+
async function ee(a, e, t = {}) {
|
|
35
|
+
const s = oe(e), r = {
|
|
36
|
+
...Z,
|
|
37
|
+
...t
|
|
38
|
+
}, n = await te(a), o = se(s, r.dotFiles);
|
|
39
|
+
if (o instanceof Response)
|
|
40
|
+
return o;
|
|
41
|
+
const i = o.length > 0 ? o.join(D) : "", u = O(n, i);
|
|
42
|
+
if (!v(n, u))
|
|
43
|
+
return new Response("Forbidden", { status: 403 });
|
|
44
|
+
const c = await re(u, n, r.index);
|
|
45
|
+
if (c instanceof Response)
|
|
46
|
+
return c;
|
|
47
|
+
const l = await W(c), d = new Headers({
|
|
48
|
+
"content-length": String(l.size),
|
|
49
|
+
"content-type": ne(c),
|
|
50
|
+
"cache-control": r.cacheControl,
|
|
51
|
+
"last-modified": l.mtime.toUTCString(),
|
|
52
|
+
"x-content-type-options": "nosniff"
|
|
53
|
+
});
|
|
54
|
+
if (t.headers) {
|
|
55
|
+
const h = typeof t.headers == "function" ? t.headers(c, l) : t.headers;
|
|
56
|
+
new Headers(h).forEach((f, y) => {
|
|
57
|
+
d.set(y, f);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return new Response(z.toWeb(k(c)), {
|
|
61
|
+
status: 200,
|
|
62
|
+
headers: d
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async function te(a) {
|
|
66
|
+
return L(a);
|
|
67
|
+
}
|
|
68
|
+
function se(a, e) {
|
|
69
|
+
if (a.includes("\0"))
|
|
70
|
+
return new Response("Bad Request", { status: 400 });
|
|
71
|
+
const t = a.replace(/\\/g, "/").split("/").filter(Boolean), s = [];
|
|
72
|
+
for (const r of t) {
|
|
73
|
+
let n;
|
|
74
|
+
try {
|
|
75
|
+
n = decodeURIComponent(r);
|
|
76
|
+
} catch {
|
|
77
|
+
return new Response("Bad Request", { status: 400 });
|
|
78
|
+
}
|
|
79
|
+
if (!(!n || n === ".")) {
|
|
80
|
+
if (n === ".." || n.includes("/") || n.includes("\\") || n.includes("\0"))
|
|
81
|
+
return new Response("Forbidden", { status: 403 });
|
|
82
|
+
if (n.startsWith(".")) {
|
|
83
|
+
if (e === "deny")
|
|
84
|
+
return new Response("Forbidden", { status: 403 });
|
|
85
|
+
if (e !== "allow")
|
|
86
|
+
return new Response("Not Found", { status: 404 });
|
|
87
|
+
}
|
|
88
|
+
s.push(n);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return s;
|
|
92
|
+
}
|
|
93
|
+
async function re(a, e, t) {
|
|
94
|
+
try {
|
|
95
|
+
if ((await I(a)).isDirectory()) {
|
|
96
|
+
const r = O(a, t);
|
|
97
|
+
return T(r, e);
|
|
98
|
+
}
|
|
99
|
+
return T(a, e);
|
|
100
|
+
} catch {
|
|
101
|
+
return new Response("Not Found", { status: 404 });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function T(a, e) {
|
|
105
|
+
try {
|
|
106
|
+
const t = await L(a);
|
|
107
|
+
return v(e, t) ? (await W(t)).isFile() ? t : new Response("Not Found", { status: 404 }) : new Response("Forbidden", { status: 403 });
|
|
108
|
+
} catch {
|
|
109
|
+
return new Response("Not Found", { status: 404 });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function v(a, e) {
|
|
113
|
+
const t = $(a, e);
|
|
114
|
+
return t === "" || !t.startsWith("..") && !U(t);
|
|
115
|
+
}
|
|
116
|
+
function ne(a) {
|
|
117
|
+
return Q[F(a).toLowerCase()] ?? "application/octet-stream";
|
|
118
|
+
}
|
|
119
|
+
function oe(a) {
|
|
120
|
+
return typeof a.params.path == "string" ? a.params.path : a.url.pathname.replace(/^\/+/, "");
|
|
121
|
+
}
|
|
122
|
+
function _(a) {
|
|
123
|
+
return a instanceof Response && a.status >= 400 && a.status < 600;
|
|
124
|
+
}
|
|
125
|
+
function N(a) {
|
|
126
|
+
return a instanceof Response && a.status >= 300 && a.status < 400;
|
|
127
|
+
}
|
|
128
|
+
class ae {
|
|
129
|
+
constructor(e) {
|
|
130
|
+
this.data = /* @__PURE__ */ new Map(), this.windowMs = e.windowMs, this.startCleanup();
|
|
131
|
+
}
|
|
132
|
+
async incr(e) {
|
|
133
|
+
const t = Date.now();
|
|
134
|
+
let s = this.data.get(e);
|
|
135
|
+
return !s || t >= s.reset ? (s = { count: 1, reset: t + this.windowMs }, this.data.set(e, s)) : s.count++, { current: s.count, reset: s.reset };
|
|
136
|
+
}
|
|
137
|
+
startCleanup() {
|
|
138
|
+
this.cleanupInterval = setInterval(() => {
|
|
139
|
+
const e = Date.now();
|
|
140
|
+
for (const [t, { reset: s }] of this.data)
|
|
141
|
+
e >= s && this.data.delete(t);
|
|
142
|
+
}, Math.min(this.windowMs, 3e5));
|
|
143
|
+
}
|
|
144
|
+
stop() {
|
|
145
|
+
this.cleanupInterval && clearInterval(this.cleanupInterval);
|
|
146
|
+
}
|
|
147
|
+
async resetAll() {
|
|
148
|
+
this.data.clear();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function ie(a) {
|
|
152
|
+
const {
|
|
153
|
+
windowMs: e = 6e4,
|
|
154
|
+
max: t,
|
|
155
|
+
key: s = (c) => c.getClientAddress(),
|
|
156
|
+
message: r = "Too many requests, please try again later.",
|
|
157
|
+
statusCode: n = 429,
|
|
158
|
+
headers: o = "include",
|
|
159
|
+
onRateLimit: i,
|
|
160
|
+
store: u = new ae({ windowMs: e })
|
|
161
|
+
} = a;
|
|
162
|
+
return async (c, l) => {
|
|
163
|
+
const d = `rl:${s(c)}`, { current: h, reset: f } = await u.incr(d), y = Math.ceil((f - Date.now()) / 1e3);
|
|
164
|
+
if (h > t) {
|
|
165
|
+
i && i(c, { current: h, max: t, key: d });
|
|
166
|
+
const w = {
|
|
167
|
+
status: n,
|
|
168
|
+
headers: new Headers()
|
|
169
|
+
}, p = w.headers;
|
|
170
|
+
o === "include" && (p.set("X-RateLimit-Limit", String(t)), p.set("X-RateLimit-Remaining", "0"), p.set("X-RateLimit-Reset", String(Math.floor(f / 1e3))), p.set("Retry-After", String(y)));
|
|
171
|
+
let m;
|
|
172
|
+
return typeof r == "string" ? (m = r, p.set("Content-Type", "text/plain")) : (m = JSON.stringify(r), p.set("Content-Type", "application/json")), new Response(m, w);
|
|
173
|
+
}
|
|
174
|
+
if (c.rateLimit = {
|
|
175
|
+
current: h,
|
|
176
|
+
limit: t,
|
|
177
|
+
reset: new Date(f),
|
|
178
|
+
remaining: t - h
|
|
179
|
+
}, o === "include") {
|
|
180
|
+
const w = {
|
|
181
|
+
"X-RateLimit-Limit": String(t),
|
|
182
|
+
"X-RateLimit-Remaining": String(t - h),
|
|
183
|
+
"X-RateLimit-Reset": String(Math.floor(f / 1e3))
|
|
184
|
+
}, p = c.setHeaders;
|
|
185
|
+
c.setHeaders = (m) => {
|
|
186
|
+
p({
|
|
187
|
+
...w,
|
|
188
|
+
...m
|
|
189
|
+
});
|
|
190
|
+
}, p(w);
|
|
191
|
+
}
|
|
192
|
+
return l();
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
const Ee = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
196
|
+
__proto__: null,
|
|
197
|
+
fixedWindowLimit: ie
|
|
198
|
+
}, Symbol.toStringTag, { value: "Module" })), ce = [
|
|
199
|
+
"GET",
|
|
200
|
+
"POST",
|
|
201
|
+
"PUT",
|
|
202
|
+
"DELETE",
|
|
203
|
+
"PATCH",
|
|
204
|
+
"HEAD",
|
|
205
|
+
"OPTIONS"
|
|
206
|
+
], ue = [
|
|
207
|
+
"Accept",
|
|
208
|
+
"Accept-Language",
|
|
209
|
+
"Content-Language",
|
|
210
|
+
"Content-Type",
|
|
211
|
+
"Range"
|
|
212
|
+
], le = [
|
|
213
|
+
"Authorization",
|
|
214
|
+
"X-Auth-Token",
|
|
215
|
+
"X-Requested-With",
|
|
216
|
+
"X-CSRF-Token",
|
|
217
|
+
"X-HTTP-Method-Override",
|
|
218
|
+
"X-Forwarded-For",
|
|
219
|
+
"X-Real-IP",
|
|
220
|
+
"X-Custom-Header"
|
|
221
|
+
];
|
|
222
|
+
function j(a, e) {
|
|
223
|
+
return !a || !e ? !1 : e === "*" ? !0 : e === "null" ? a === "null" : Array.isArray(e) ? e.some((t) => j(a, t)) : typeof e == "function" ? e(a) : e instanceof RegExp ? e.test(a) : a === e;
|
|
224
|
+
}
|
|
225
|
+
function de(a, e) {
|
|
226
|
+
const { origin: t = "*" } = e;
|
|
227
|
+
return a ? t === "*" ? e.credentials ? a : "*" : j(a, t) ? a : null : t === "*" ? "*" : null;
|
|
228
|
+
}
|
|
229
|
+
function he(a = {}) {
|
|
230
|
+
const {
|
|
231
|
+
methods: e = ce,
|
|
232
|
+
allowedHeaders: t = le,
|
|
233
|
+
exposedHeaders: s,
|
|
234
|
+
credentials: r = !1,
|
|
235
|
+
maxAge: n = 86400,
|
|
236
|
+
onResponse: o
|
|
237
|
+
} = a, i = "Origin,Access-Control-Request-Method,Access-Control-Request-Headers", u = e.join(","), c = [...ue, ...t].join(","), l = [
|
|
238
|
+
["Vary", i],
|
|
239
|
+
["Access-Control-Allow-Methods", u],
|
|
240
|
+
["Access-Control-Allow-Headers", c]
|
|
241
|
+
];
|
|
242
|
+
return s && l.push(["Access-Control-Expose-Headers", s.join(",")]), r && l.push(["Access-Control-Allow-Credentials", "true"]), n && l.push(["Access-Control-Max-Age", n.toString()]), async (d, h) => {
|
|
243
|
+
const f = d.request, y = f.headers.get("Origin"), w = f.method === "OPTIONS" && y !== null && f.headers.has("Access-Control-Request-Method"), p = de(y, a);
|
|
244
|
+
if (w) {
|
|
245
|
+
if (!p)
|
|
246
|
+
return new Response(null, { status: 403 });
|
|
247
|
+
const g = new Response(null, { status: 204 });
|
|
248
|
+
for (const [H, M] of l)
|
|
249
|
+
g.headers.set(H, M);
|
|
250
|
+
return g.headers.set("Access-Control-Allow-Origin", p), g;
|
|
251
|
+
}
|
|
252
|
+
const m = await h();
|
|
253
|
+
if (!m) return;
|
|
254
|
+
if (!p) return m;
|
|
255
|
+
const S = new Response(m.body, m);
|
|
256
|
+
for (const [g, H] of l)
|
|
257
|
+
S.headers.set(g, H);
|
|
258
|
+
S.headers.set("Access-Control-Allow-Origin", p);
|
|
259
|
+
let A = S;
|
|
260
|
+
if (o) {
|
|
261
|
+
const g = o(A);
|
|
262
|
+
g && (A = g);
|
|
263
|
+
}
|
|
264
|
+
return A;
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const Te = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
268
|
+
__proto__: null,
|
|
269
|
+
policy: he
|
|
270
|
+
}, Symbol.toStringTag, { value: "Module" })), fe = ["GET", "PUT", "POST", "DELETE", "PATCH", "HEAD", "OPTIONS"];
|
|
271
|
+
class b {
|
|
272
|
+
static {
|
|
273
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
274
|
+
}
|
|
275
|
+
static get(e) {
|
|
276
|
+
return this.cache.get(e);
|
|
277
|
+
}
|
|
278
|
+
static set(e, t) {
|
|
279
|
+
this.cache.set(e, t);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
class x {
|
|
283
|
+
constructor() {
|
|
284
|
+
this._routes = [], this._wsRoutes = [], this._nestedRouters = [], this._middlewares = [], this._preHandlers = [], this._postHandlers = [], this.routesSorted = !1, this.wsRoutesSorted = !1;
|
|
285
|
+
}
|
|
286
|
+
get routes() {
|
|
287
|
+
return this._routes;
|
|
288
|
+
}
|
|
289
|
+
get nestedRouters() {
|
|
290
|
+
return this._nestedRouters;
|
|
291
|
+
}
|
|
292
|
+
// HTTP method handlers
|
|
293
|
+
GET(e, t, ...s) {
|
|
294
|
+
return this.addHandler("GET", e, t, s);
|
|
295
|
+
}
|
|
296
|
+
POST(e, t, ...s) {
|
|
297
|
+
return this.addHandler("POST", e, t, s);
|
|
298
|
+
}
|
|
299
|
+
PUT(e, t, ...s) {
|
|
300
|
+
return this.addHandler("PUT", e, t, s);
|
|
301
|
+
}
|
|
302
|
+
PATCH(e, t, ...s) {
|
|
303
|
+
return this.addHandler("PATCH", e, t, s);
|
|
304
|
+
}
|
|
305
|
+
DELETE(e, t, ...s) {
|
|
306
|
+
return this.addHandler("DELETE", e, t, s);
|
|
307
|
+
}
|
|
308
|
+
HEAD(e, t, ...s) {
|
|
309
|
+
return this.addHandler("HEAD", e, t, s);
|
|
310
|
+
}
|
|
311
|
+
OPTIONS(e, t, ...s) {
|
|
312
|
+
return this.addHandler("OPTIONS", e, t, s);
|
|
313
|
+
}
|
|
314
|
+
// Universal method
|
|
315
|
+
USE(e, t, ...s) {
|
|
316
|
+
return fe.forEach((r) => this.addHandler(r, e, t, s)), this;
|
|
317
|
+
}
|
|
318
|
+
// Action handler (POST only)
|
|
319
|
+
action(e, t, ...s) {
|
|
320
|
+
const r = async (n) => {
|
|
321
|
+
try {
|
|
322
|
+
const o = await t(n);
|
|
323
|
+
return this.formatActionResult(o);
|
|
324
|
+
} catch (o) {
|
|
325
|
+
return this.handleActionError(o);
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
return this.addHandler("POST", e, r, s);
|
|
329
|
+
}
|
|
330
|
+
use(e, t, ...s) {
|
|
331
|
+
let r, n, o = s;
|
|
332
|
+
Array.isArray(e) ? ([r, n] = e, o = e.length > 2 ? e.slice(2) : []) : (r = e, n = t);
|
|
333
|
+
const i = this.normalizePrefix(r), { regex: u, paramNames: c, isCatchAll: l, priority: d } = this.createPrefixRegex(i);
|
|
334
|
+
return this._nestedRouters.push({
|
|
335
|
+
prefix: i,
|
|
336
|
+
router: n,
|
|
337
|
+
regex: u,
|
|
338
|
+
paramNames: c,
|
|
339
|
+
isCatchAll: l,
|
|
340
|
+
priority: d,
|
|
341
|
+
middlewares: o
|
|
342
|
+
}), this;
|
|
343
|
+
}
|
|
344
|
+
// Global middleware
|
|
345
|
+
useMiddleware(...e) {
|
|
346
|
+
return this._middlewares.push(...e), this;
|
|
347
|
+
}
|
|
348
|
+
pre(...e) {
|
|
349
|
+
return this._preHandlers.push(...e), this;
|
|
350
|
+
}
|
|
351
|
+
post(...e) {
|
|
352
|
+
return this._postHandlers.push(...e), this;
|
|
353
|
+
}
|
|
354
|
+
// Discard routes or nested routers
|
|
355
|
+
discard(e, t) {
|
|
356
|
+
return this._nestedRouters = this._nestedRouters.filter((s) => s.prefix !== e), this._routes = this._routes.filter(
|
|
357
|
+
(s) => s.path !== e || t && s.method !== t
|
|
358
|
+
), this;
|
|
359
|
+
}
|
|
360
|
+
// WebSocket route
|
|
361
|
+
WS(e, t, ...s) {
|
|
362
|
+
const { regex: r, paramNames: n, isCatchAll: o, priority: i } = this.createPathRegex(e);
|
|
363
|
+
return this._wsRoutes.push({
|
|
364
|
+
path: e,
|
|
365
|
+
regex: r,
|
|
366
|
+
paramNames: n,
|
|
367
|
+
isCatchAll: o,
|
|
368
|
+
priority: i,
|
|
369
|
+
handler: t,
|
|
370
|
+
middlewares: s
|
|
371
|
+
}), this.wsRoutesSorted = !1, this;
|
|
372
|
+
}
|
|
373
|
+
// Add this method to your Router class
|
|
374
|
+
/**
|
|
375
|
+
* Check if the router can handle a WebSocket connection for the given path
|
|
376
|
+
* This is used during the upgrade process to validate routes before attempting connection
|
|
377
|
+
*/
|
|
378
|
+
async canHandleWebSocket(e) {
|
|
379
|
+
return this.canHandleWebSocketAtPath(e, e.url.pathname);
|
|
380
|
+
}
|
|
381
|
+
async canHandleWebSocketAtPath(e, t) {
|
|
382
|
+
this.wsRoutesSorted || this.sortWsRoutes();
|
|
383
|
+
for (const s of [...this._nestedRouters].sort((r, n) => n.priority - r.priority)) {
|
|
384
|
+
const r = t.match(s.regex);
|
|
385
|
+
if (!r || r.index !== 0) continue;
|
|
386
|
+
const n = r[0], o = t.slice(n.length) || "/", i = {
|
|
387
|
+
...e,
|
|
388
|
+
params: { ...e.params, ...this.extractPrefixParams(s, n) }
|
|
389
|
+
};
|
|
390
|
+
if (await s.router.canHandleWebSocketAtPath(i, o))
|
|
391
|
+
return !0;
|
|
392
|
+
}
|
|
393
|
+
for (const s of this._wsRoutes)
|
|
394
|
+
if (s.regex.test(t))
|
|
395
|
+
return !0;
|
|
396
|
+
return !1;
|
|
397
|
+
}
|
|
398
|
+
// Handle WebSocket upgrade
|
|
399
|
+
async handleWebSocket(e, t) {
|
|
400
|
+
return this.handleWebSocketAtPath(e, t, e.url.pathname);
|
|
401
|
+
}
|
|
402
|
+
async handleWebSocketAtPath(e, t, s) {
|
|
403
|
+
this.wsRoutesSorted || this.sortWsRoutes();
|
|
404
|
+
for (const r of [...this._nestedRouters].sort((n, o) => o.priority - n.priority)) {
|
|
405
|
+
const n = s.match(r.regex);
|
|
406
|
+
if (!n || n.index !== 0) continue;
|
|
407
|
+
const o = n[0], i = s.slice(o.length) || "/", u = this.extractPrefixParams(r, o), c = {
|
|
408
|
+
...e,
|
|
409
|
+
params: { ...e.params, ...u }
|
|
410
|
+
}, l = [...this._middlewares, ...r.middlewares], d = () => r.router.handleWebSocketAtPath(c, t, i);
|
|
411
|
+
if (await this.applyMiddlewaresWithList(c, l, d)) return !0;
|
|
412
|
+
}
|
|
413
|
+
for (const r of this._wsRoutes) {
|
|
414
|
+
if (!r.regex.test(s)) continue;
|
|
415
|
+
const n = s.match(r.regex);
|
|
416
|
+
if (!n) continue;
|
|
417
|
+
const o = Object.fromEntries(
|
|
418
|
+
r.paramNames.map((l, d) => [l, n[d + 1] || ""])
|
|
419
|
+
), i = {
|
|
420
|
+
...e,
|
|
421
|
+
params: { ...e.params, ...o },
|
|
422
|
+
route: { ...e.route, id: r.path },
|
|
423
|
+
websocket: t
|
|
424
|
+
}, u = [...this._middlewares, ...r.middlewares];
|
|
425
|
+
if (await this.applyMiddlewaresWithList(i, u, () => r.handler(i)) === void 0)
|
|
426
|
+
return !0;
|
|
427
|
+
}
|
|
428
|
+
return !1;
|
|
429
|
+
}
|
|
430
|
+
// Handle HTTP request - FIXED: Single middleware application
|
|
431
|
+
async handle(e) {
|
|
432
|
+
return this.handleAtPath(e, e.url.pathname);
|
|
433
|
+
}
|
|
434
|
+
async handleAtPath(e, t) {
|
|
435
|
+
const s = e.request.method;
|
|
436
|
+
let r = await this.runPreHandlers(e);
|
|
437
|
+
if (!r) {
|
|
438
|
+
const o = async () => {
|
|
439
|
+
const i = await this.handleNestedRouters(e, t);
|
|
440
|
+
return i || (this.routesSorted || this.sortRoutes(), this.handleLocalRoutes(e, s, t));
|
|
441
|
+
};
|
|
442
|
+
r = await this.applyMiddlewaresWithList(e, this._middlewares, o);
|
|
443
|
+
}
|
|
444
|
+
const n = r || new Response("No Content", { status: 204 });
|
|
445
|
+
return this.runPostHandlers(e, n);
|
|
446
|
+
}
|
|
447
|
+
// Apply middlewares utility
|
|
448
|
+
async applyMiddlewaresWithList(e, t, s) {
|
|
449
|
+
const r = [...t], n = async (o) => o >= r.length ? s() : r[o](e, () => n(o + 1));
|
|
450
|
+
return n(0);
|
|
451
|
+
}
|
|
452
|
+
async runPreHandlers(e) {
|
|
453
|
+
for (const t of this._preHandlers) {
|
|
454
|
+
const s = await t(e);
|
|
455
|
+
if (s instanceof Response)
|
|
456
|
+
return s;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
async runPostHandlers(e, t) {
|
|
460
|
+
let s = t;
|
|
461
|
+
for (const r of this._postHandlers) {
|
|
462
|
+
const n = await r(e, s);
|
|
463
|
+
n instanceof Response && (s = n);
|
|
464
|
+
}
|
|
465
|
+
return s;
|
|
466
|
+
}
|
|
467
|
+
// Add route handler
|
|
468
|
+
addHandler(e, t, s, r = []) {
|
|
469
|
+
const { regex: n, paramNames: o, isCatchAll: i, priority: u } = this.createPathRegex(t);
|
|
470
|
+
return this._routes.push({
|
|
471
|
+
method: e,
|
|
472
|
+
path: t,
|
|
473
|
+
regex: n,
|
|
474
|
+
paramNames: o,
|
|
475
|
+
isCatchAll: i,
|
|
476
|
+
priority: u,
|
|
477
|
+
handler: s,
|
|
478
|
+
middlewares: r
|
|
479
|
+
}), this.routesSorted = !1, this;
|
|
480
|
+
}
|
|
481
|
+
// Create regex for route path
|
|
482
|
+
createPathRegex(e) {
|
|
483
|
+
const t = b.get(e);
|
|
484
|
+
if (t) return t;
|
|
485
|
+
const s = [];
|
|
486
|
+
let r = !1, n;
|
|
487
|
+
const o = e.split("/").filter(Boolean);
|
|
488
|
+
n = o.reduce((c, l) => l.startsWith("[...") ? c - 10 : l.startsWith("[[") ? c - 5 : l.startsWith("[") ? c - 1 : c + 1, 0);
|
|
489
|
+
let i = "^";
|
|
490
|
+
for (const c of o)
|
|
491
|
+
if (c.startsWith("[...") && c.endsWith("]")) {
|
|
492
|
+
r = !0;
|
|
493
|
+
const l = c.slice(4, -1);
|
|
494
|
+
s.push(l), i += "/(.+)";
|
|
495
|
+
} else if (c.startsWith("[[") && c.endsWith("]]")) {
|
|
496
|
+
const l = c.slice(2, -2);
|
|
497
|
+
s.push(l), i += "(?:/([^/]+))?";
|
|
498
|
+
} else if (c.startsWith("[") && c.endsWith("]")) {
|
|
499
|
+
const l = c.slice(1, -1);
|
|
500
|
+
s.push(l), i += "/([^/]+)";
|
|
501
|
+
} else
|
|
502
|
+
i += "/" + c.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
503
|
+
i += "/?$";
|
|
504
|
+
const u = { regex: new RegExp(i), paramNames: s, isCatchAll: r, priority: n };
|
|
505
|
+
return b.set(e, u), u;
|
|
506
|
+
}
|
|
507
|
+
// Create regex for prefix
|
|
508
|
+
createPrefixRegex(e) {
|
|
509
|
+
const t = [];
|
|
510
|
+
let s = !1, r;
|
|
511
|
+
const n = e.split("/").filter(Boolean);
|
|
512
|
+
r = n.reduce((i, u) => u.startsWith("[...") ? i - 10 : u.startsWith("[[") ? i - 5 : u.startsWith("[") ? i - 1 : i + 1, 0);
|
|
513
|
+
let o = "^";
|
|
514
|
+
for (const i of n)
|
|
515
|
+
if (i.startsWith("[...") && i.endsWith("]")) {
|
|
516
|
+
s = !0;
|
|
517
|
+
const u = i.slice(4, -1);
|
|
518
|
+
t.push(u), o += "/(.+)";
|
|
519
|
+
} else if (i.startsWith("[[") && i.endsWith("]]")) {
|
|
520
|
+
const u = i.slice(2, -2);
|
|
521
|
+
t.push(u), o += "(?:/([^/]+))?";
|
|
522
|
+
} else if (i.startsWith("[") && i.endsWith("]")) {
|
|
523
|
+
const u = i.slice(1, -1);
|
|
524
|
+
t.push(u), o += "/([^/]+)";
|
|
525
|
+
} else
|
|
526
|
+
o += "/" + i.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
527
|
+
return o += "(?=/|$)", { regex: new RegExp(o), paramNames: t, isCatchAll: s, priority: r };
|
|
528
|
+
}
|
|
529
|
+
normalizePrefix(e) {
|
|
530
|
+
return e.startsWith("/") ? e.replace(/\/$/, "") : `/${e.replace(/\/$/, "")}`;
|
|
531
|
+
}
|
|
532
|
+
extractPrefixParams(e, t) {
|
|
533
|
+
const s = t.match(e.regex);
|
|
534
|
+
if (!s) return {};
|
|
535
|
+
const r = {};
|
|
536
|
+
return e.isCatchAll && e.paramNames.length === 1 ? r[e.paramNames[0]] = s[1]?.replace(/^\//, "") || "" : e.paramNames.forEach((n, o) => {
|
|
537
|
+
r[n] = s[o + 1] || "";
|
|
538
|
+
}), r;
|
|
539
|
+
}
|
|
540
|
+
// FIXED: Nested router handling without duplicate middleware application
|
|
541
|
+
async handleNestedRouters(e, t) {
|
|
542
|
+
const s = [...this._nestedRouters].sort((r, n) => n.priority - r.priority);
|
|
543
|
+
for (const r of s) {
|
|
544
|
+
const n = t.match(r.regex);
|
|
545
|
+
if (!n || n.index !== 0) continue;
|
|
546
|
+
const o = n[0], i = t.slice(o.length) || "/", u = this.extractPrefixParams(r, o), c = {
|
|
547
|
+
...e,
|
|
548
|
+
params: { ...e.params, ...u }
|
|
549
|
+
}, l = async () => await r.router.handleAtPath(c, i), d = await this.applyMiddlewaresWithList(c, r.middlewares, l);
|
|
550
|
+
if (d) return d;
|
|
551
|
+
}
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
// FIXED: Local route handling without duplicate middleware application
|
|
555
|
+
async handleLocalRoutes(e, t, s) {
|
|
556
|
+
const r = /* @__PURE__ */ new Set();
|
|
557
|
+
let n = !1;
|
|
558
|
+
for (const o of this._routes) {
|
|
559
|
+
if (!o.regex.test(s) || (r.add(o.method), o.method === "GET" && (n = !0, r.add("HEAD")), !(o.method === t || t === "HEAD" && o.method === "GET"))) continue;
|
|
560
|
+
const u = s.match(o.regex);
|
|
561
|
+
if (!u) continue;
|
|
562
|
+
const c = Object.fromEntries(
|
|
563
|
+
o.paramNames.map((d, h) => [d, u[h + 1] || ""])
|
|
564
|
+
);
|
|
565
|
+
e.params = { ...e.params, ...c }, e.route = { ...e.route, id: o.path };
|
|
566
|
+
const l = () => o.handler(e);
|
|
567
|
+
return await this.applyMiddlewaresWithList(e, o.middlewares, l);
|
|
568
|
+
}
|
|
569
|
+
if (r.size > 0 || t === "HEAD" && n) {
|
|
570
|
+
const o = [...r].join(", ");
|
|
571
|
+
return t === "OPTIONS" ? new Response(null, {
|
|
572
|
+
status: 200,
|
|
573
|
+
headers: { Allow: o }
|
|
574
|
+
}) : new Response("Method Not Allowed", {
|
|
575
|
+
status: 405,
|
|
576
|
+
headers: { Allow: o }
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
return new Response("Not Found", { status: 404 });
|
|
580
|
+
}
|
|
581
|
+
sortRoutes() {
|
|
582
|
+
this._routes.sort((e, t) => t.priority - e.priority), this.routesSorted = !0;
|
|
583
|
+
}
|
|
584
|
+
sortWsRoutes() {
|
|
585
|
+
this._wsRoutes.sort((e, t) => t.priority - e.priority), this.wsRoutesSorted = !0;
|
|
586
|
+
}
|
|
587
|
+
formatActionResult(e) {
|
|
588
|
+
return e instanceof Response ? e : e?.type === "failure" && "status" in e ? R.fail(e.status, e.data) : R.success(200, e ?? void 0);
|
|
589
|
+
}
|
|
590
|
+
handleActionError(e) {
|
|
591
|
+
if (_(e))
|
|
592
|
+
return R.error(e.status, e);
|
|
593
|
+
if (N(e)) {
|
|
594
|
+
const t = e.headers.get("Location") || "/";
|
|
595
|
+
return R.redirect(e.status, t);
|
|
596
|
+
}
|
|
597
|
+
return console.error(e), R.error(500, { message: "Internal Server Error" });
|
|
598
|
+
}
|
|
599
|
+
static New() {
|
|
600
|
+
return new x();
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
const R = {
|
|
604
|
+
success: (a = 200, e) => new Response(JSON.stringify({ data: e, type: "success", status: a }), {
|
|
605
|
+
status: a,
|
|
606
|
+
headers: { "Content-Type": "application/json" }
|
|
607
|
+
}),
|
|
608
|
+
redirect: (a = 302, e) => new Response(JSON.stringify({ location: e, type: "redirect", status: a }), {
|
|
609
|
+
status: a,
|
|
610
|
+
headers: { "Content-Type": "application/json" }
|
|
611
|
+
}),
|
|
612
|
+
error: (a = 500, e) => new Response(JSON.stringify({ error: e, type: "error", status: a }), {
|
|
613
|
+
status: a,
|
|
614
|
+
headers: { "Content-Type": "application/json" }
|
|
615
|
+
}),
|
|
616
|
+
fail: (a = 400, e) => new Response(JSON.stringify({ data: e, type: "failure", status: a }), {
|
|
617
|
+
status: a,
|
|
618
|
+
headers: { "Content-Type": "application/json" }
|
|
619
|
+
})
|
|
620
|
+
};
|
|
621
|
+
class pe {
|
|
622
|
+
constructor(e, t) {
|
|
623
|
+
this.raw = e.headers.get("cookie") ?? "", this.setCookieHeader = t;
|
|
624
|
+
}
|
|
625
|
+
get(e, t) {
|
|
626
|
+
return E(this.raw, t)[e];
|
|
627
|
+
}
|
|
628
|
+
getAll(e) {
|
|
629
|
+
return Object.entries(E(this.raw, e)).filter(([, t]) => t !== void 0).map(([t, s]) => ({ name: t, value: s }));
|
|
630
|
+
}
|
|
631
|
+
set(e, t, s) {
|
|
632
|
+
this.setCookieHeader(Y(e, t, s));
|
|
633
|
+
}
|
|
634
|
+
delete(e, t) {
|
|
635
|
+
this.set(e, "", { ...t, maxAge: 0 });
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
class C extends Error {
|
|
639
|
+
constructor(e = "Payload Too Large") {
|
|
640
|
+
super(e), this.status = 413, this.name = "PayloadTooLargeError";
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
class be {
|
|
644
|
+
constructor(e) {
|
|
645
|
+
this.upgradeHandlerInstalled = !1, this.config = e ?? { type: "http", options: {} }, this.router = new x(), this.wss = new K({
|
|
646
|
+
noServer: !0,
|
|
647
|
+
maxPayload: this.config.security?.maxWebSocketPayload ?? 1024 * 1024
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
get server() {
|
|
651
|
+
if (!this._server) {
|
|
652
|
+
const e = (t, s) => {
|
|
653
|
+
this.handleRequest(t, s).catch((r) => {
|
|
654
|
+
console.error("Unhandled request error:", r), s.statusCode = 500, s.end("Internal Server Error");
|
|
655
|
+
});
|
|
656
|
+
};
|
|
657
|
+
this._server = this.config.type === "https" ? q(this.config.options, e) : B(this.config.options, e);
|
|
658
|
+
}
|
|
659
|
+
return this._server;
|
|
660
|
+
}
|
|
661
|
+
discard(e, t) {
|
|
662
|
+
return this.router.discard(e, t), this;
|
|
663
|
+
}
|
|
664
|
+
listen(...e) {
|
|
665
|
+
return this.upgradeHandlerInstalled || (this.installUpgradeHandler(), this.upgradeHandlerInstalled = !0), this.server.listen(...e), this;
|
|
666
|
+
}
|
|
667
|
+
installUpgradeHandler() {
|
|
668
|
+
this.server.on("upgrade", (e, t, s) => {
|
|
669
|
+
if (e.headers.upgrade?.toLowerCase() !== "websocket") {
|
|
670
|
+
t.destroy();
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
let r, n;
|
|
674
|
+
try {
|
|
675
|
+
r = this.toURL(e, !0), n = this.toRequest(e, r, !0);
|
|
676
|
+
} catch {
|
|
677
|
+
t.destroy();
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
const o = this.toRequestEvent(n, r, {
|
|
681
|
+
getClientAddress: () => e.socket.remoteAddress ?? "127.0.0.1",
|
|
682
|
+
setHeader: () => {
|
|
683
|
+
},
|
|
684
|
+
pushSetCookie: () => {
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
this.router.canHandleWebSocket(o).then((i) => {
|
|
688
|
+
if (!i || !this.isAllowedWebSocketOrigin(e)) {
|
|
689
|
+
t.destroy();
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
this.wss.handleUpgrade(e, t, s, (u) => {
|
|
693
|
+
this.router.handleWebSocket(o, u).then((c) => {
|
|
694
|
+
!c && u.readyState === P.OPEN && u.close(1008, "Route not found");
|
|
695
|
+
}).catch((c) => {
|
|
696
|
+
console.error("WebSocket routing error:", c), u.readyState === P.OPEN && u.close(1011, "Internal error");
|
|
697
|
+
});
|
|
698
|
+
});
|
|
699
|
+
}).catch(() => t.destroy());
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
close(e) {
|
|
703
|
+
this.wss.close(() => {
|
|
704
|
+
this.server.close(e);
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
address() {
|
|
708
|
+
return this.server.address();
|
|
709
|
+
}
|
|
710
|
+
get listening() {
|
|
711
|
+
return this.server.listening;
|
|
712
|
+
}
|
|
713
|
+
async handleRequest(e, t) {
|
|
714
|
+
if (!this.isRequestBodyAllowed(e)) {
|
|
715
|
+
t.statusCode = 413, t.end("Payload Too Large");
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
const s = this.toWebRequest(e), r = new URL(s.url), n = {}, o = [], i = this.toRequestEvent(s, r, {
|
|
719
|
+
getClientAddress: () => e.socket.remoteAddress ?? "127.0.0.1",
|
|
720
|
+
setHeader: (c, l) => {
|
|
721
|
+
n[c.toLowerCase()] = l;
|
|
722
|
+
},
|
|
723
|
+
pushSetCookie: (c) => {
|
|
724
|
+
o.push(c);
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
let u;
|
|
728
|
+
try {
|
|
729
|
+
u = await this.router.handle(i);
|
|
730
|
+
} catch (c) {
|
|
731
|
+
u = this.handleError(c);
|
|
732
|
+
}
|
|
733
|
+
for (const [c, l] of Object.entries(n))
|
|
734
|
+
t.setHeader(c, l);
|
|
735
|
+
o.length > 0 && t.setHeader("Set-Cookie", o), await this.sendWebResponse(t, u);
|
|
736
|
+
}
|
|
737
|
+
toWebRequest(e) {
|
|
738
|
+
const t = this.toURL(e, !1);
|
|
739
|
+
return this.toRequest(e, t, !1);
|
|
740
|
+
}
|
|
741
|
+
toRequest(e, t, s) {
|
|
742
|
+
const r = {
|
|
743
|
+
method: s ? "GET" : e.method,
|
|
744
|
+
headers: this.toHeaders(e.headers),
|
|
745
|
+
// @ts-ignore
|
|
746
|
+
duplex: "half"
|
|
747
|
+
};
|
|
748
|
+
return !s && e.method !== "GET" && e.method !== "HEAD" && (r.body = G.toWeb(this.wrapRequestBody(e))), new Request(t, r);
|
|
749
|
+
}
|
|
750
|
+
wrapRequestBody(e) {
|
|
751
|
+
const t = this.config.security?.maxRequestBodySize;
|
|
752
|
+
if (!t)
|
|
753
|
+
return e;
|
|
754
|
+
let s = 0;
|
|
755
|
+
const r = new J({
|
|
756
|
+
transform(n, o, i) {
|
|
757
|
+
if (s += Buffer.byteLength(n), s > t) {
|
|
758
|
+
i(new C());
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
i(null, n);
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
return e.on("aborted", () => r.destroy(new Error("Request aborted"))), e.on("error", (n) => r.destroy(n)), e.pipe(r), r;
|
|
765
|
+
}
|
|
766
|
+
toURL(e, t) {
|
|
767
|
+
const s = e.socket instanceof X ? t ? "wss" : "https" : t ? "ws" : "http", r = this.resolveAuthority(e);
|
|
768
|
+
return new URL(e.url ?? "/", `${s}://${r}`);
|
|
769
|
+
}
|
|
770
|
+
resolveAuthority(e) {
|
|
771
|
+
const t = this.config.security?.trustHostHeader ? this.normalizeTrustedHost(e.headers.host) : null;
|
|
772
|
+
if (t)
|
|
773
|
+
return t;
|
|
774
|
+
const s = this.server.address();
|
|
775
|
+
return s && typeof s == "object" ? `${s.address.includes(":") ? `[${s.address}]` : s.address}:${s.port}` : e.socket.localPort ? `127.0.0.1:${e.socket.localPort}` : "localhost";
|
|
776
|
+
}
|
|
777
|
+
normalizeTrustedHost(e) {
|
|
778
|
+
if (!e) return null;
|
|
779
|
+
let t;
|
|
780
|
+
try {
|
|
781
|
+
t = new URL(`http://${e}`);
|
|
782
|
+
} catch {
|
|
783
|
+
return null;
|
|
784
|
+
}
|
|
785
|
+
if (t.username || t.password || t.pathname !== "/" || t.search || t.hash)
|
|
786
|
+
return null;
|
|
787
|
+
const s = t.port ? `${t.hostname}:${t.port}` : t.hostname, r = this.config.security?.allowedHosts;
|
|
788
|
+
return !r || this.matchesValue(s, r) ? s : null;
|
|
789
|
+
}
|
|
790
|
+
matchesValue(e, t) {
|
|
791
|
+
return (Array.isArray(t) ? t : [t]).some((r) => typeof r == "string" ? r === e : r instanceof RegExp ? r.test(e) : r(e));
|
|
792
|
+
}
|
|
793
|
+
toHeaders(e) {
|
|
794
|
+
const t = new Headers();
|
|
795
|
+
for (const [s, r] of Object.entries(e))
|
|
796
|
+
if (r !== void 0) {
|
|
797
|
+
if (Array.isArray(r)) {
|
|
798
|
+
const n = s.toLowerCase() === "cookie" ? r.join("; ") : r.join(", ");
|
|
799
|
+
t.set(s, n);
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
t.set(s, r);
|
|
803
|
+
}
|
|
804
|
+
return t;
|
|
805
|
+
}
|
|
806
|
+
isRequestBodyAllowed(e) {
|
|
807
|
+
const t = this.config.security?.maxRequestBodySize;
|
|
808
|
+
if (!t) return !0;
|
|
809
|
+
const s = e.headers["content-length"];
|
|
810
|
+
if (!s) return !0;
|
|
811
|
+
const r = Number.parseInt(Array.isArray(s) ? s[0] : s, 10);
|
|
812
|
+
return Number.isFinite(r) && r <= t;
|
|
813
|
+
}
|
|
814
|
+
handleError(e) {
|
|
815
|
+
if (e instanceof C)
|
|
816
|
+
return new Response(e.message, { status: e.status });
|
|
817
|
+
if (_(e))
|
|
818
|
+
return new Response(JSON.stringify({
|
|
819
|
+
error: e.statusText || "Error",
|
|
820
|
+
status: e.status
|
|
821
|
+
}), {
|
|
822
|
+
status: e.status,
|
|
823
|
+
headers: { "Content-Type": "application/json" }
|
|
824
|
+
});
|
|
825
|
+
if (N(e)) {
|
|
826
|
+
const t = e.headers.get("Location") || "/";
|
|
827
|
+
return new Response(null, {
|
|
828
|
+
status: e.status,
|
|
829
|
+
headers: { Location: t }
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
return console.error("Unhandled error:", e), new Response("Internal Server Error", { status: 500 });
|
|
833
|
+
}
|
|
834
|
+
async sendWebResponse(e, t) {
|
|
835
|
+
if (e.statusCode = t.status, t.headers.forEach((n, o) => {
|
|
836
|
+
e.setHeader(o, n);
|
|
837
|
+
}), e.hasHeader("Server") || e.setHeader("Server", "WebHTTPServer"), !t.body || this.shouldOmitResponseBody(t, e.req?.method)) {
|
|
838
|
+
e.end();
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
const s = t.body.getReader(), r = V.toWeb(e).getWriter();
|
|
842
|
+
try {
|
|
843
|
+
for (; ; ) {
|
|
844
|
+
const { done: n, value: o } = await s.read();
|
|
845
|
+
if (n) break;
|
|
846
|
+
await r.write(o);
|
|
847
|
+
}
|
|
848
|
+
} finally {
|
|
849
|
+
await r.close().catch(() => {
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
shouldOmitResponseBody(e, t) {
|
|
854
|
+
return t === "HEAD" ? !0 : e.status === 204 || e.status === 205 || e.status === 304;
|
|
855
|
+
}
|
|
856
|
+
isAllowedWebSocketOrigin(e) {
|
|
857
|
+
const t = e.headers.origin;
|
|
858
|
+
if (!t) return !0;
|
|
859
|
+
const s = this.config.security?.allowedWebSocketOrigins;
|
|
860
|
+
return s ? this.matchesValue(t, s) : !0;
|
|
861
|
+
}
|
|
862
|
+
toRequestEvent(e, t, s) {
|
|
863
|
+
const r = new pe(e, s.pushSetCookie), n = this.config, o = {}, i = { name: "WebHTTPServer" }, u = /* @__PURE__ */ new Set(), c = {
|
|
864
|
+
request: e,
|
|
865
|
+
url: t,
|
|
866
|
+
cookies: r,
|
|
867
|
+
getClientAddress: s.getClientAddress,
|
|
868
|
+
get locals() {
|
|
869
|
+
return o;
|
|
870
|
+
},
|
|
871
|
+
get platform() {
|
|
872
|
+
return i;
|
|
873
|
+
},
|
|
874
|
+
params: {},
|
|
875
|
+
route: { id: "" },
|
|
876
|
+
setHeaders: (l) => {
|
|
877
|
+
for (const [d, h] of Object.entries(l)) {
|
|
878
|
+
const f = d.toLowerCase();
|
|
879
|
+
if (f === "set-cookie")
|
|
880
|
+
throw new TypeError("Use event.cookies for Set-Cookie headers");
|
|
881
|
+
if (u.has(f))
|
|
882
|
+
throw new TypeError(`Header "${d}" has already been set`);
|
|
883
|
+
u.add(f), s.setHeader(d, h);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
};
|
|
887
|
+
return n.locals && Object.assign(o, n.locals(c)), n.platform && Object.assign(i, n.platform(c)), c;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
const Ce = async (a, e) => {
|
|
891
|
+
const t = JSON.stringify(await a);
|
|
892
|
+
return new Response(t, {
|
|
893
|
+
...e,
|
|
894
|
+
headers: {
|
|
895
|
+
"content-type": "application/json",
|
|
896
|
+
"content-length": Buffer.byteLength(t).toString(),
|
|
897
|
+
...e?.headers
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
}, We = async (a, e) => {
|
|
901
|
+
const t = await a;
|
|
902
|
+
return new Response(t, {
|
|
903
|
+
...e,
|
|
904
|
+
headers: {
|
|
905
|
+
"content-type": "text/plain",
|
|
906
|
+
"content-length": Buffer.byteLength(t).toString(),
|
|
907
|
+
...e?.headers
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
}, Le = async (a, e) => {
|
|
911
|
+
const t = await a;
|
|
912
|
+
return new Response(t, {
|
|
913
|
+
...e,
|
|
914
|
+
headers: {
|
|
915
|
+
"content-type": "text/html",
|
|
916
|
+
"content-length": Buffer.byteLength(t).toString(),
|
|
917
|
+
...e?.headers
|
|
918
|
+
}
|
|
919
|
+
});
|
|
920
|
+
}, Oe = (a, e = {}) => (t) => ee(a, t, e);
|
|
921
|
+
export {
|
|
922
|
+
R as Action,
|
|
923
|
+
Te as CORS,
|
|
924
|
+
Ee as RateLimiter,
|
|
925
|
+
fe as RequestMethods,
|
|
926
|
+
x as Router,
|
|
927
|
+
be as WebServer,
|
|
928
|
+
Oe as dir,
|
|
929
|
+
Le as html,
|
|
930
|
+
_ as isHttpError,
|
|
931
|
+
N as isRedirect,
|
|
932
|
+
Ce as json,
|
|
933
|
+
ee as serveStatic,
|
|
934
|
+
We as text
|
|
935
|
+
};
|
|
936
|
+
//# sourceMappingURL=index.es.js.map
|