@ozanarslan/corpus 0.1.4 → 0.1.5

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/index.cjs ADDED
@@ -0,0 +1,1787 @@
1
+ // @bun @bun-cjs
2
+ (function(exports, require, module, __filename, __dirname) {var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ function __accessProp(key) {
9
+ return this[key];
10
+ }
11
+ var __toESMCache_node;
12
+ var __toESMCache_esm;
13
+ var __toESM = (mod, isNodeMode, target) => {
14
+ var canCache = mod != null && typeof mod === "object";
15
+ if (canCache) {
16
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
+ var cached = cache.get(mod);
18
+ if (cached)
19
+ return cached;
20
+ }
21
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
22
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ if (canCache)
30
+ cache.set(mod, to);
31
+ return to;
32
+ };
33
+ var __toCommonJS = (from) => {
34
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
35
+ if (entry)
36
+ return entry;
37
+ entry = __defProp({}, "__esModule", { value: true });
38
+ if (from && typeof from === "object" || typeof from === "function") {
39
+ for (var key of __getOwnPropNames(from))
40
+ if (!__hasOwnProp.call(entry, key))
41
+ __defProp(entry, key, {
42
+ get: __accessProp.bind(from, key),
43
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
44
+ });
45
+ }
46
+ __moduleCache.set(from, entry);
47
+ return entry;
48
+ };
49
+ var __moduleCache;
50
+ var __returnValue = (v) => v;
51
+ function __exportSetter(name, newValue) {
52
+ this[name] = __returnValue.bind(null, newValue);
53
+ }
54
+ var __export = (target, all) => {
55
+ for (var name in all)
56
+ __defProp(target, name, {
57
+ get: all[name],
58
+ enumerable: true,
59
+ configurable: true,
60
+ set: __exportSetter.bind(all, name)
61
+ });
62
+ };
63
+
64
+ // src/index.ts
65
+ var exports_src = {};
66
+ __export(exports_src, {
67
+ default: () => src_default,
68
+ _router: () => _router,
69
+ _globalPrefix: () => _globalPrefix,
70
+ Status: () => Status,
71
+ StaticRoute: () => StaticRoute,
72
+ Server: () => Server,
73
+ Route: () => Route,
74
+ Response: () => HttpResponse,
75
+ Request: () => HttpRequest,
76
+ Repository: () => RepositoryAbstract,
77
+ Parser: () => Parser,
78
+ Middleware: () => Middleware,
79
+ Method: () => Method,
80
+ MemoiristAdapter: () => MemoiristAdapter,
81
+ Headers: () => HttpHeaders,
82
+ FileWalker: () => FileWalker,
83
+ Error: () => HttpError,
84
+ DefaultStatusTexts: () => DefaultStatusTexts,
85
+ Cookies: () => Cookies,
86
+ Controller: () => ControllerAbstract,
87
+ Context: () => Context,
88
+ Config: () => Config,
89
+ CommonHeaders: () => CommonHeaders,
90
+ C: () => exports_exports
91
+ });
92
+ module.exports = __toCommonJS(exports_src);
93
+
94
+ // src/Store/StoreAbstract.ts
95
+ class StoreAbstract {
96
+ set(value) {
97
+ this.value = value;
98
+ }
99
+ get() {
100
+ return this.value;
101
+ }
102
+ }
103
+
104
+ // src/Store/globals/GlobalPrefixStore.ts
105
+ class GlobalPrefixStore extends StoreAbstract {
106
+ value = "";
107
+ }
108
+
109
+ // src/Store/globals/GlobalRouterStore.ts
110
+ class GlobalRouterStore extends StoreAbstract {
111
+ value = null;
112
+ get() {
113
+ if (!this.value) {
114
+ console.error("Router instance is not set. Please instantiate your Server before your routes.");
115
+ process.exit(1);
116
+ }
117
+ return this.value;
118
+ }
119
+ }
120
+
121
+ // src/exports.ts
122
+ var exports_exports = {};
123
+ __export(exports_exports, {
124
+ Status: () => Status,
125
+ StaticRoute: () => StaticRoute,
126
+ Server: () => Server,
127
+ Route: () => Route,
128
+ Response: () => HttpResponse,
129
+ Request: () => HttpRequest,
130
+ Repository: () => RepositoryAbstract,
131
+ Parser: () => Parser,
132
+ Middleware: () => Middleware,
133
+ Method: () => Method,
134
+ Headers: () => HttpHeaders,
135
+ FileWalker: () => FileWalker,
136
+ Error: () => HttpError,
137
+ DefaultStatusTexts: () => DefaultStatusTexts,
138
+ Cookies: () => Cookies,
139
+ Controller: () => ControllerAbstract,
140
+ Context: () => Context,
141
+ Config: () => Config,
142
+ CommonHeaders: () => CommonHeaders
143
+ });
144
+
145
+ // src/Config/enums/RuntimeOptions.ts
146
+ var RuntimeOptions = {
147
+ bun: "bun",
148
+ node: "node"
149
+ };
150
+
151
+ // src/utils/strIsDefined.ts
152
+ function strIsDefined(input) {
153
+ return !!input?.trim() && typeof input === "string";
154
+ }
155
+
156
+ // src/Config/Config.ts
157
+ var import_path = __toESM(require("path"));
158
+
159
+ class Config {
160
+ static get runtime() {
161
+ if (typeof Bun !== "undefined") {
162
+ return RuntimeOptions.bun;
163
+ }
164
+ if (typeof process !== "undefined" && process?.env) {
165
+ return RuntimeOptions.node;
166
+ }
167
+ console.warn("\u26A0\uFE0F Runtime isn't Bun or NodeJS. Features may not be available. App might not start.");
168
+ return "unknown";
169
+ }
170
+ static get nodeEnv() {
171
+ return this.env.NODE_ENV ?? "development";
172
+ }
173
+ static get env() {
174
+ switch (this.runtime) {
175
+ case RuntimeOptions.bun:
176
+ return Bun.env;
177
+ case RuntimeOptions.node:
178
+ return process.env;
179
+ default:
180
+ console.warn("\u26A0\uFE0F process.env wasn't available. Your environment variables are in memory.");
181
+ return {};
182
+ }
183
+ }
184
+ static cwd() {
185
+ return process.cwd();
186
+ }
187
+ static resolvePath(...paths) {
188
+ return import_path.default.resolve(...paths);
189
+ }
190
+ static get(key, opts) {
191
+ const value = this.env[key];
192
+ if (strIsDefined(value)) {
193
+ return opts?.parser ? opts?.parser(value) : value;
194
+ }
195
+ if (opts?.fallback !== undefined) {
196
+ return opts?.fallback;
197
+ }
198
+ console.error(`${key} doesn't exist in env`);
199
+ return;
200
+ }
201
+ static set(key, value) {
202
+ if (typeof value === "number") {
203
+ this.env[key] = value.toString();
204
+ return;
205
+ }
206
+ if (typeof value === "boolean") {
207
+ this.env[key] = value ? "true" : "false";
208
+ return;
209
+ }
210
+ this.env[key] = value;
211
+ }
212
+ }
213
+ // src/Response/enums/Status.ts
214
+ var Status = {
215
+ CONTINUE: 100,
216
+ SWITCHING_PROTOCOLS: 101,
217
+ PROCESSING: 102,
218
+ EARLY_HINTS: 103,
219
+ OK: 200,
220
+ CREATED: 201,
221
+ ACCEPTED: 202,
222
+ NON_AUTHORITATIVE_INFORMATION: 203,
223
+ NO_CONTENT: 204,
224
+ RESET_CONTENT: 205,
225
+ PARTIAL_CONTENT: 206,
226
+ MULTI_STATUS: 207,
227
+ ALREADY_REPORTED: 208,
228
+ IM_USED: 226,
229
+ MULTIPLE_CHOICES: 300,
230
+ MOVED_PERMANENTLY: 301,
231
+ FOUND: 302,
232
+ SEE_OTHER: 303,
233
+ NOT_MODIFIED: 304,
234
+ USE_PROXY: 305,
235
+ TEMPORARY_REDIRECT: 307,
236
+ PERMANENT_REDIRECT: 308,
237
+ BAD_REQUEST: 400,
238
+ UNAUTHORIZED: 401,
239
+ PAYMENT_REQUIRED: 402,
240
+ FORBIDDEN: 403,
241
+ NOT_FOUND: 404,
242
+ METHOD_NOT_ALLOWED: 405,
243
+ NOT_ACCEPTABLE: 406,
244
+ PROXY_AUTHENTICATION_REQUIRED: 407,
245
+ REQUEST_TIMEOUT: 408,
246
+ CONFLICT: 409,
247
+ GONE: 410,
248
+ LENGTH_REQUIRED: 411,
249
+ PRECONDITION_FAILED: 412,
250
+ PAYLOAD_TOO_LARGE: 413,
251
+ URI_TOO_LONG: 414,
252
+ UNSUPPORTED_MEDIA_TYPE: 415,
253
+ RANGE_NOT_SATISFIABLE: 416,
254
+ EXPECTATION_FAILED: 417,
255
+ IM_A_TEAPOT: 418,
256
+ MISDIRECTED_REQUEST: 421,
257
+ UNPROCESSABLE_ENTITY: 422,
258
+ LOCKED: 423,
259
+ FAILED_DEPENDENCY: 424,
260
+ TOO_EARLY: 425,
261
+ UPGRADE_REQUIRED: 426,
262
+ PRECONDITION_REQUIRED: 428,
263
+ TOO_MANY_REQUESTS: 429,
264
+ REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
265
+ UNAVAILABLE_FOR_LEGAL_REASONS: 451,
266
+ INTERNAL_SERVER_ERROR: 500,
267
+ NOT_IMPLEMENTED: 501,
268
+ BAD_GATEWAY: 502,
269
+ SERVICE_UNAVAILABLE: 503,
270
+ GATEWAY_TIMEOUT: 504,
271
+ HTTP_VERSION_NOT_SUPPORTED: 505,
272
+ VARIANT_ALSO_NEGOTIATES: 506,
273
+ INSUFFICIENT_STORAGE: 507,
274
+ LOOP_DETECTED: 508,
275
+ NOT_EXTENDED: 510,
276
+ NETWORK_AUTHENTICATION_REQUIRED: 511
277
+ };
278
+
279
+ // src/Response/enums/DefaultStatusTexts.ts
280
+ var DefaultStatusTexts = {
281
+ [Status.OK]: "OK",
282
+ [Status.CREATED]: "Created",
283
+ [Status.NO_CONTENT]: "No Content",
284
+ [Status.MOVED_PERMANENTLY]: "Moved Permanently",
285
+ [Status.FOUND]: "Found",
286
+ [Status.SEE_OTHER]: "See Other",
287
+ [Status.TEMPORARY_REDIRECT]: "Temporary Redirect",
288
+ [Status.PERMANENT_REDIRECT]: "Permanent Redirect",
289
+ [Status.BAD_REQUEST]: "Bad Request",
290
+ [Status.UNAUTHORIZED]: "Unauthorized",
291
+ [Status.FORBIDDEN]: "Forbidden",
292
+ [Status.NOT_FOUND]: "Not Found",
293
+ [Status.INTERNAL_SERVER_ERROR]: "Internal Server Error"
294
+ };
295
+
296
+ // src/Headers/enums/CommonHeaders.ts
297
+ var CommonHeaders = {
298
+ CacheControl: "Cache-Control",
299
+ ContentType: "Content-Type",
300
+ ContentLength: "Content-Length",
301
+ AcceptEncoding: "Accept-Encoding",
302
+ Accept: "Accept",
303
+ Authorization: "Authorization",
304
+ UserAgent: "User-Agent",
305
+ Host: "Host",
306
+ Referer: "Referer",
307
+ Connection: "Connection",
308
+ Pragma: "Pragma",
309
+ Date: "Date",
310
+ IfNoneMatch: "If-None-Match",
311
+ IfModifiedSince: "If-Modified-Since",
312
+ ETag: "ETag",
313
+ Expires: "Expires",
314
+ LastModified: "Last-Modified",
315
+ Location: "Location",
316
+ WWWAuthenticate: "WWW-Authenticate",
317
+ AccessControlAllowOrigin: "Access-Control-Allow-Origin",
318
+ AccessControlMaxAge: "Access-Control-Max-Age",
319
+ AccessControlAllowCredentials: "Access-Control-Allow-Credentials",
320
+ AccessControlRequestMethod: "Access-Control-Request-Method",
321
+ SetCookie: "Set-Cookie",
322
+ Cookie: "Cookie"
323
+ };
324
+
325
+ // src/Cookies/CookiesAbstract.ts
326
+ class CookiesAbstract {
327
+ applyInit(init) {
328
+ if (!init)
329
+ return;
330
+ if (init instanceof CookiesAbstract) {
331
+ for (const name of init.keys()) {
332
+ const value = init.get(name) ?? "";
333
+ this.set({ name, value });
334
+ }
335
+ } else if (Array.isArray(init)) {
336
+ for (const opts of init) {
337
+ this.set(opts);
338
+ }
339
+ } else {
340
+ this.set(init);
341
+ }
342
+ }
343
+ }
344
+
345
+ // src/Cookies/CookiesUsingBun.ts
346
+ class CookiesUsingBun extends CookiesAbstract {
347
+ constructor(init) {
348
+ super();
349
+ this.applyInit(init);
350
+ }
351
+ map = new Bun.CookieMap;
352
+ toSetCookieHeaders() {
353
+ return this.map.toSetCookieHeaders();
354
+ }
355
+ set(opts) {
356
+ this.map.set(opts.name, opts.value, opts);
357
+ }
358
+ setMany(optsArr) {
359
+ for (const opts of optsArr) {
360
+ this.set(opts);
361
+ }
362
+ }
363
+ get(name) {
364
+ return this.map.get(name);
365
+ }
366
+ has(name) {
367
+ return this.map.has(name);
368
+ }
369
+ get count() {
370
+ return this.values().length;
371
+ }
372
+ delete(name) {
373
+ this.map.delete(name);
374
+ }
375
+ entries() {
376
+ return this.map.entries();
377
+ }
378
+ values() {
379
+ return Array.from(this.map.values());
380
+ }
381
+ keys() {
382
+ return Array.from(this.map.keys());
383
+ }
384
+ }
385
+
386
+ // src/Cookies/Cookies.ts
387
+ class Cookies extends CookiesUsingBun {
388
+ }
389
+
390
+ // src/Headers/HttpHeaders.ts
391
+ class HttpHeaders extends Headers {
392
+ constructor(init) {
393
+ super(init);
394
+ }
395
+ append(name, value) {
396
+ super.append(name, value);
397
+ }
398
+ set(name, value) {
399
+ super.set(name, value);
400
+ }
401
+ get(name) {
402
+ return super.get(name) || super.get(name.toLowerCase());
403
+ }
404
+ has(name) {
405
+ return super.has(name) || super.has(name.toLowerCase());
406
+ }
407
+ delete(name) {
408
+ return super.delete(name);
409
+ }
410
+ static combine(source, target) {
411
+ source.forEach((value, key) => {
412
+ if (key.toLowerCase() === "set-cookie") {
413
+ target.append(key, value);
414
+ } else {
415
+ target.set(key, value);
416
+ }
417
+ });
418
+ return target;
419
+ }
420
+ innerCombine(source) {
421
+ HttpHeaders.combine(source, this);
422
+ }
423
+ setMany(init) {
424
+ const entries = Array.isArray(init) ? init : Object.entries(init);
425
+ for (const [key, value] of entries) {
426
+ if (!strIsDefined(value))
427
+ continue;
428
+ this.set(key, value);
429
+ }
430
+ }
431
+ static findHeaderInInit(init, name) {
432
+ if (init instanceof HttpHeaders || init instanceof Headers) {
433
+ return init.get(name);
434
+ } else if (Array.isArray(init)) {
435
+ return init.find((entry) => entry[0] === name)?.[1] ?? null;
436
+ } else {
437
+ return init[name] ?? null;
438
+ }
439
+ }
440
+ }
441
+
442
+ // src/Response/HttpResponse.ts
443
+ class HttpResponse {
444
+ body;
445
+ init;
446
+ constructor(body, init) {
447
+ this.body = body;
448
+ this.init = init;
449
+ this.cookies = this.getCookies();
450
+ this.headers = this.getHeaders();
451
+ this.body = this.getBody();
452
+ this.status = this.getStatus();
453
+ this.statusText = this.getDefaultStatusText();
454
+ }
455
+ headers;
456
+ status;
457
+ statusText;
458
+ cookies;
459
+ get response() {
460
+ return new Response(this.body, {
461
+ status: this.status,
462
+ statusText: this.statusText,
463
+ headers: this.headers
464
+ });
465
+ }
466
+ getCookies() {
467
+ return new Cookies(this.init?.cookies);
468
+ }
469
+ getHeaders() {
470
+ const headers = new HttpHeaders(this.init?.headers);
471
+ const setCookieHeaders = this.cookies.toSetCookieHeaders();
472
+ if (setCookieHeaders.length > 0) {
473
+ for (const header of setCookieHeaders) {
474
+ headers.append(CommonHeaders.SetCookie, header);
475
+ }
476
+ }
477
+ return headers;
478
+ }
479
+ getStatus() {
480
+ if (this.init?.status)
481
+ return this.init.status;
482
+ if (this.headers.has(CommonHeaders.Location)) {
483
+ return Status.FOUND;
484
+ }
485
+ return Status.OK;
486
+ }
487
+ setContentType(value) {
488
+ if (!this.headers.has(CommonHeaders.ContentType) || this.headers.get(CommonHeaders.ContentType) === "text/plain") {
489
+ this.headers.set(CommonHeaders.ContentType, value);
490
+ }
491
+ }
492
+ getBody() {
493
+ if (this.body === null || this.body === undefined) {
494
+ this.setContentType("text/plain");
495
+ return "";
496
+ }
497
+ if (typeof this.body !== "object") {
498
+ this.setContentType("text/plain");
499
+ return String(this.body);
500
+ }
501
+ if (this.body instanceof ArrayBuffer || this.body instanceof Blob || this.body instanceof FormData || this.body instanceof URLSearchParams || this.body instanceof ReadableStream) {
502
+ throw new Error("Unsupported response body: ArrayBuffer | Blob | FormData | URLSearchParams | ReadableStream");
503
+ }
504
+ if (this.body instanceof Date) {
505
+ this.setContentType("text/plain");
506
+ return this.body.toISOString();
507
+ }
508
+ if (Array.isArray(this.body) || this.body.constructor === Object) {
509
+ this.setContentType("application/json");
510
+ return JSON.stringify(this.body);
511
+ }
512
+ this.setContentType("text/plain");
513
+ return String(this.body);
514
+ }
515
+ getDefaultStatusText() {
516
+ const key = this.status;
517
+ return DefaultStatusTexts[key] ?? "Unknown";
518
+ }
519
+ static redirect(url, init) {
520
+ const res = new HttpResponse(undefined, {
521
+ ...init,
522
+ status: init?.status ?? Status.FOUND,
523
+ statusText: init?.statusText ?? DefaultStatusTexts[Status.FOUND]
524
+ });
525
+ const urlString = url instanceof URL ? url.toString() : url;
526
+ res.headers.set(CommonHeaders.Location, urlString);
527
+ return res;
528
+ }
529
+ static permanentRedirect(url, init) {
530
+ return this.redirect(url, {
531
+ ...init,
532
+ status: Status.MOVED_PERMANENTLY
533
+ });
534
+ }
535
+ static temporaryRedirect(url, init) {
536
+ return this.redirect(url, { ...init, status: Status.TEMPORARY_REDIRECT });
537
+ }
538
+ static seeOther(url, init) {
539
+ return this.redirect(url, { ...init, status: Status.SEE_OTHER });
540
+ }
541
+ }
542
+
543
+ // src/Request/enums/Method.ts
544
+ var Method = {
545
+ GET: "GET",
546
+ POST: "POST",
547
+ PUT: "PUT",
548
+ PATCH: "PATCH",
549
+ DELETE: "DELETE",
550
+ HEAD: "HEAD",
551
+ OPTIONS: "OPTIONS",
552
+ CONNECT: "CONNECT",
553
+ TRACE: "TRACE"
554
+ };
555
+
556
+ // src/Error/HttpError.ts
557
+ class HttpError extends Error {
558
+ message;
559
+ status;
560
+ data;
561
+ constructor(message, status, data) {
562
+ super(message);
563
+ this.message = message;
564
+ this.status = status;
565
+ this.data = data;
566
+ }
567
+ toResponse() {
568
+ return new HttpResponse(this.data ? { error: this.data, message: this.message } : { error: true, message: this.message }, { status: this.status });
569
+ }
570
+ isStatusOf(status) {
571
+ return this.status === status;
572
+ }
573
+ static internalServerError(msg) {
574
+ const status = Status.INTERNAL_SERVER_ERROR;
575
+ return new this(msg ?? status.toString(), status);
576
+ }
577
+ static badRequest(msg) {
578
+ const status = Status.BAD_REQUEST;
579
+ return new this(msg ?? status.toString(), status);
580
+ }
581
+ static notFound(msg) {
582
+ const status = Status.NOT_FOUND;
583
+ return new this(msg ?? status.toString(), status);
584
+ }
585
+ static methodNotAllowed(msg) {
586
+ const status = Status.METHOD_NOT_ALLOWED;
587
+ return new this(msg ?? status.toString(), status);
588
+ }
589
+ static unprocessableEntity(msg) {
590
+ const status = Status.UNPROCESSABLE_ENTITY;
591
+ return new this(msg ?? status.toString(), status);
592
+ }
593
+ }
594
+
595
+ // src/utils/arrIncludes.ts
596
+ function arrIncludes(input, array) {
597
+ return array.includes(input);
598
+ }
599
+
600
+ // src/utils/isObjectWith.ts
601
+ function isObjectWith(item, key) {
602
+ return item !== null && item !== undefined && typeof item === "object" && key in item;
603
+ }
604
+
605
+ // src/utils/objAppendEntry.ts
606
+ function objAppendEntry(data, key, value) {
607
+ const existing = data[key];
608
+ if (existing !== undefined) {
609
+ data[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];
610
+ } else {
611
+ data[key] = value;
612
+ }
613
+ }
614
+
615
+ // src/Model/Parser.ts
616
+ class Parser {
617
+ static async parse(data, validate) {
618
+ if (!validate)
619
+ return data;
620
+ const result = await validate(data);
621
+ if (result.issues !== undefined) {
622
+ const msg = this.issuesToErrorMessage(result.issues);
623
+ throw HttpError.unprocessableEntity(msg);
624
+ }
625
+ return result.value;
626
+ }
627
+ static issuesToErrorMessage(issues) {
628
+ if (issues.length === 0)
629
+ return "";
630
+ return issues.map((issue) => {
631
+ if (!issue.path || issue.path.length === 0) {
632
+ return issue.message;
633
+ }
634
+ const key = issue.path.map((segment) => isObjectWith(segment, "key") ? String(segment.key) : String(segment)).join(".");
635
+ return `${key}: ${issue.message}`;
636
+ }).join(`
637
+ `);
638
+ }
639
+ static async getSearch(url, validate) {
640
+ const data = {};
641
+ for (const [key, value] of url.searchParams ?? {}) {
642
+ data[key] = this.processString(value);
643
+ }
644
+ return await this.parse(data, validate);
645
+ }
646
+ static async getBody(r, validate) {
647
+ let data;
648
+ const empty = {};
649
+ const input = r instanceof Request ? r : r instanceof Response ? r : r.response;
650
+ try {
651
+ switch (Parser.getNormalizedContentType(input)) {
652
+ case "json":
653
+ data = await this.getJsonBody(input);
654
+ break;
655
+ case "form-urlencoded":
656
+ data = await this.getFormUrlEncodedBody(input);
657
+ break;
658
+ case "form-data":
659
+ data = await this.getFormDataBody(input);
660
+ break;
661
+ case "text":
662
+ data = await this.getTextBody(input);
663
+ break;
664
+ case "unknown":
665
+ data = await this.getUnknownBody(input);
666
+ break;
667
+ case "xml":
668
+ case "binary":
669
+ case "pdf":
670
+ case "image":
671
+ case "audio":
672
+ case "video":
673
+ throw new HttpError("unprocessable.contentType", Status.UNPROCESSABLE_ENTITY);
674
+ case "no-body-allowed":
675
+ default:
676
+ return empty;
677
+ }
678
+ return await this.parse(data, validate);
679
+ } catch (err) {
680
+ if (err instanceof SyntaxError)
681
+ return empty;
682
+ throw err;
683
+ }
684
+ }
685
+ static async getParams(endpoint, url, validate) {
686
+ const data = {};
687
+ if (!endpoint.includes(":")) {
688
+ return data;
689
+ }
690
+ const defParts = endpoint.split("/");
691
+ const reqParts = url.pathname.split("/");
692
+ for (const [i, defPart] of defParts.entries()) {
693
+ const reqPart = reqParts[i];
694
+ if (defPart.startsWith(":") && reqPart !== undefined) {
695
+ const key = defPart.slice(1);
696
+ const value = this.processString(decodeURIComponent(reqPart));
697
+ data[key] = value;
698
+ }
699
+ }
700
+ return await this.parse(data, validate);
701
+ }
702
+ static async getUnknownBody(input, validate) {
703
+ if (!validate) {
704
+ return await this.getTextBody(input);
705
+ }
706
+ try {
707
+ return await this.getJsonBody(input);
708
+ } catch {
709
+ return await this.getTextBody(input);
710
+ }
711
+ }
712
+ static async getJsonBody(req) {
713
+ return await req.json();
714
+ }
715
+ static async getFormUrlEncodedBody(input) {
716
+ const text = await input.text();
717
+ if (!text || text.trim().length === 0) {
718
+ throw new SyntaxError("Body is empty");
719
+ }
720
+ const params = new URLSearchParams(text);
721
+ const body = {};
722
+ for (const [key, value] of params.entries()) {
723
+ objAppendEntry(body, key, this.processString(value));
724
+ }
725
+ return body;
726
+ }
727
+ static async getFormDataBody(input) {
728
+ const formData = await input.formData();
729
+ const entries = formData.entries();
730
+ const body = {};
731
+ for (const [key, value] of entries) {
732
+ if (value instanceof File) {
733
+ body[key] = value;
734
+ } else {
735
+ objAppendEntry(body, key, this.processString(value));
736
+ }
737
+ }
738
+ return body;
739
+ }
740
+ static async getTextBody(input) {
741
+ const contentLength = input.headers.get(CommonHeaders.ContentLength);
742
+ const length = contentLength ? parseInt(contentLength) : 0;
743
+ if (length > 0 && length < 1024 * 1024) {
744
+ const text2 = await input.text();
745
+ return this.processString(text2);
746
+ }
747
+ const buffer = await input.arrayBuffer();
748
+ const contentType = input.headers.get(CommonHeaders.ContentType) || "";
749
+ const match = contentType.match(/charset=([^;]+)/i);
750
+ const charset = match?.[1] ? match[1].trim() : null;
751
+ const decoder = new TextDecoder(charset || "utf-8");
752
+ const text = decoder.decode(buffer);
753
+ return this.processString(text);
754
+ }
755
+ static getNormalizedContentType(input) {
756
+ const contentTypeHeader = input.headers.get(CommonHeaders.ContentType) || "";
757
+ if ("method" in input && typeof input.method === "string" && !arrIncludes(input.method.toUpperCase(), [
758
+ Method.POST,
759
+ Method.PUT,
760
+ Method.PATCH,
761
+ Method.DELETE
762
+ ])) {
763
+ return "no-body-allowed";
764
+ }
765
+ if (contentTypeHeader.includes("application/json")) {
766
+ return "json";
767
+ } else if (contentTypeHeader.includes("application/x-www-form-urlencoded")) {
768
+ return "form-urlencoded";
769
+ } else if (contentTypeHeader.includes("multipart/form-data")) {
770
+ return "form-data";
771
+ } else if (contentTypeHeader.includes("text/plain")) {
772
+ return "text";
773
+ } else if (contentTypeHeader.includes("application/xml")) {
774
+ return "xml";
775
+ } else if (contentTypeHeader.includes("text/xml")) {
776
+ return "xml";
777
+ } else if (contentTypeHeader.includes("application/octet-stream")) {
778
+ return "binary";
779
+ } else if (contentTypeHeader.includes("application/pdf")) {
780
+ return "pdf";
781
+ } else if (contentTypeHeader.includes("image/")) {
782
+ return "image";
783
+ } else if (contentTypeHeader.includes("audio/")) {
784
+ return "audio";
785
+ } else if (contentTypeHeader.includes("video/")) {
786
+ return "video";
787
+ }
788
+ return "unknown";
789
+ }
790
+ static processString(value) {
791
+ let processedValue = value;
792
+ if (!strIsDefined(value))
793
+ return "";
794
+ if (/^-?\d+(\.\d+)?$/.test(value)) {
795
+ processedValue = Number(value);
796
+ } else if (value.toLowerCase() === "true" || value.toLowerCase() === "false") {
797
+ processedValue = value.toLowerCase() === "true";
798
+ }
799
+ return processedValue;
800
+ }
801
+ }
802
+
803
+ // src/Context/Context.ts
804
+ class Context {
805
+ constructor(req, body, search, params, res) {
806
+ this.req = req;
807
+ this.url = req.urlObject;
808
+ this.headers = req.headers;
809
+ this.cookies = req.cookies;
810
+ this.body = body;
811
+ this.search = search;
812
+ this.params = params;
813
+ this.res = res ?? new HttpResponse;
814
+ }
815
+ req;
816
+ url;
817
+ headers;
818
+ cookies;
819
+ body;
820
+ search;
821
+ params;
822
+ res;
823
+ data = {};
824
+ static makeFromRequest(req) {
825
+ return new Context(req, {}, {}, {});
826
+ }
827
+ static async appendParsedData(ctx, req, endpoint, model, parsedParams) {
828
+ ctx.body = await Parser.getBody(req, model?.body);
829
+ ctx.search = await Parser.getSearch(ctx.url, model?.search);
830
+ ctx.params = parsedParams !== undefined ? await Parser.parse(parsedParams, model?.params) : await Parser.getParams(endpoint, ctx.url, model?.params);
831
+ }
832
+ }
833
+ // src/Route/enums/RouteVariant.ts
834
+ var RouteVariant = {
835
+ static: "static",
836
+ dynamic: "dynamic"
837
+ };
838
+
839
+ // src/utils/joinPathSegments.ts
840
+ function joinPathSegments(...segments) {
841
+ const joined = segments.map((segment) => typeof segment === "number" ? segment.toString() : segment).filter((segment) => segment !== undefined && segment !== null && segment.trim() !== "").map((segment) => segment.replace(/^\/+|\/+$/g, "")).filter((segment) => segment.length > 0).join("/");
842
+ return `/${joined}`;
843
+ }
844
+
845
+ // src/Route/RouteAbstract.ts
846
+ class RouteAbstract {
847
+ resolveEndpoint(definition, variant) {
848
+ const endpoint = typeof definition === "string" ? definition : definition.path;
849
+ if (variant === RouteVariant.dynamic) {
850
+ return joinPathSegments(_globalPrefix.get(), endpoint);
851
+ }
852
+ return endpoint;
853
+ }
854
+ resolveMethod(definition) {
855
+ return typeof definition === "string" ? Method.GET : definition.method;
856
+ }
857
+ resolvePattern(endpoint) {
858
+ return Route.makeRoutePattern(endpoint);
859
+ }
860
+ resolveId(method, endpoint) {
861
+ return Route.makeRouteId(method, endpoint);
862
+ }
863
+ }
864
+
865
+ // src/Route/Route.ts
866
+ class Route extends RouteAbstract {
867
+ constructor(definition, handler, model) {
868
+ super();
869
+ this.variant = RouteVariant.dynamic;
870
+ this.endpoint = this.resolveEndpoint(definition, this.variant);
871
+ this.method = this.resolveMethod(definition);
872
+ this.pattern = this.resolvePattern(this.endpoint);
873
+ this.id = this.resolveId(this.method, this.endpoint);
874
+ this.model = model;
875
+ this.handler = handler;
876
+ _router.get().addRoute(this);
877
+ if (model) {
878
+ _router.get().addModel(this.id, model);
879
+ }
880
+ }
881
+ variant;
882
+ endpoint;
883
+ method;
884
+ pattern;
885
+ id;
886
+ handler;
887
+ model;
888
+ static makeRouteId(method, endpoint) {
889
+ return `${method.toUpperCase()} ${endpoint}`;
890
+ }
891
+ static makeRoutePattern(endpoint) {
892
+ const regex = endpoint.split("/").map((part) => part.startsWith(":") ? "([^\\/]+)" : part).join("/");
893
+ return new RegExp(`^${regex}$`);
894
+ }
895
+ }
896
+
897
+ // src/FileWalker/FileWalkerUsingBun.ts
898
+ class FileWalkerUsingBun {
899
+ static async read(address) {
900
+ try {
901
+ const file = await this.find(address);
902
+ if (!file)
903
+ return null;
904
+ return await file.text();
905
+ } catch {
906
+ return null;
907
+ }
908
+ }
909
+ static async exists(address) {
910
+ return await this.find(address) !== null;
911
+ }
912
+ static getExtension(address) {
913
+ return address.split(".").pop() ?? "txt";
914
+ }
915
+ static async find(address) {
916
+ const file = Bun.file(address);
917
+ const exists = await file.exists();
918
+ if (exists) {
919
+ return { text: () => file.text() };
920
+ }
921
+ return null;
922
+ }
923
+ }
924
+
925
+ // src/FileWalker/FileWalker.ts
926
+ class FileWalker extends FileWalkerUsingBun {
927
+ }
928
+
929
+ // src/Route/StaticRoute.ts
930
+ class StaticRoute extends RouteAbstract {
931
+ filePath;
932
+ constructor(path2, filePath, handler, model) {
933
+ super();
934
+ this.filePath = filePath;
935
+ this.variant = RouteVariant.static;
936
+ this.endpoint = this.resolveEndpoint(path2, this.variant);
937
+ this.method = Method.GET;
938
+ this.pattern = this.resolvePattern(this.endpoint);
939
+ this.id = this.resolveId(this.method, this.endpoint);
940
+ this.model = model;
941
+ if (handler) {
942
+ this.handler = async (c) => {
943
+ const content = await this.defaultHandler(c);
944
+ return handler(c, content);
945
+ };
946
+ } else {
947
+ this.handler = this.defaultHandler;
948
+ }
949
+ _router.get().addRoute(this);
950
+ }
951
+ id;
952
+ variant;
953
+ method;
954
+ endpoint;
955
+ pattern;
956
+ model;
957
+ handler;
958
+ defaultHandler = async (c) => {
959
+ const content = await this.getContent();
960
+ c.res.headers.set(CommonHeaders.ContentType, this.mimeTypes[this.extension] || "application/octet-stream");
961
+ c.res.headers.set(CommonHeaders.ContentLength, content.length.toString());
962
+ return content;
963
+ };
964
+ get extension() {
965
+ return this.filePath.split(".").pop() || "txt";
966
+ }
967
+ async getContent() {
968
+ const content = await FileWalker.read(this.filePath);
969
+ if (!content) {
970
+ console.error("File not found at:", this.filePath);
971
+ throw HttpError.notFound();
972
+ }
973
+ return content;
974
+ }
975
+ mimeTypes = {
976
+ html: "text/html",
977
+ htm: "text/html",
978
+ css: "text/css",
979
+ js: "application/javascript",
980
+ ts: "application/javascript",
981
+ mjs: "application/javascript",
982
+ json: "application/json",
983
+ png: "image/png",
984
+ jpg: "image/jpeg",
985
+ jpeg: "image/jpeg",
986
+ gif: "image/gif",
987
+ svg: "image/svg+xml",
988
+ ico: "image/x-icon",
989
+ txt: "text/plain",
990
+ xml: "application/xml",
991
+ pdf: "application/pdf",
992
+ zip: "application/zip",
993
+ mp3: "audio/mpeg",
994
+ mp4: "video/mp4",
995
+ webm: "video/webm",
996
+ woff: "font/woff",
997
+ woff2: "font/woff2",
998
+ ttf: "font/ttf"
999
+ };
1000
+ }
1001
+
1002
+ // src/Controller/ControllerAbstract.ts
1003
+ class ControllerAbstract {
1004
+ constructor(opts) {
1005
+ this.prefix = opts?.prefix;
1006
+ this.beforeEach = opts?.beforeEach;
1007
+ }
1008
+ routeIds = new Set;
1009
+ prefix;
1010
+ beforeEach;
1011
+ route(...args) {
1012
+ const [definition, handler, model] = args;
1013
+ const route = new Route(this.resolveRouteDefinition(definition), async (ctx) => {
1014
+ await this.beforeEach?.(ctx);
1015
+ return handler(ctx);
1016
+ }, model);
1017
+ this.routeIds.add(route.id);
1018
+ return route;
1019
+ }
1020
+ staticRoute(...args) {
1021
+ const [path2, filePath, handler, model] = args;
1022
+ const route = new StaticRoute(joinPathSegments(this.prefix, path2), filePath, handler, model);
1023
+ this.routeIds.add(route.id);
1024
+ return route;
1025
+ }
1026
+ resolveRouteDefinition(definition) {
1027
+ if (typeof definition === "string") {
1028
+ return joinPathSegments(this.prefix, definition);
1029
+ }
1030
+ return {
1031
+ method: definition.method,
1032
+ path: joinPathSegments(this.prefix, definition.path)
1033
+ };
1034
+ }
1035
+ }
1036
+ // src/Middleware/Middleware.ts
1037
+ class Middleware {
1038
+ constructor(opts) {
1039
+ this.useOn = opts.useOn;
1040
+ this.handler = opts.handler;
1041
+ _router.get().addMiddleware(opts);
1042
+ }
1043
+ useOn;
1044
+ handler;
1045
+ }
1046
+ // src/Repository/RepositoryAbstract.ts
1047
+ class RepositoryAbstract {
1048
+ db;
1049
+ constructor(db) {
1050
+ this.db = db;
1051
+ }
1052
+ }
1053
+ // src/utils/assert.ts
1054
+ function assert(condition, message) {
1055
+ const conditionName = String(condition);
1056
+ if (!condition) {
1057
+ if (!message) {
1058
+ message = `Assertion failed for ${conditionName}`;
1059
+ } else {
1060
+ message = `${conditionName}: ${message}`;
1061
+ }
1062
+ throw new Error(message);
1063
+ }
1064
+ }
1065
+
1066
+ // src/utils/strSplit.ts
1067
+ function strSplit(mark, input, minLength) {
1068
+ const parts = input.split(mark).map((part) => part.trim()).filter(Boolean);
1069
+ if (minLength) {
1070
+ assert(parts.length >= minLength);
1071
+ return parts;
1072
+ }
1073
+ return parts;
1074
+ }
1075
+
1076
+ // src/Request/HttpRequest.ts
1077
+ class HttpRequest extends Request {
1078
+ info;
1079
+ init;
1080
+ constructor(info, init) {
1081
+ super(info, init);
1082
+ this.info = info;
1083
+ this.init = init;
1084
+ this.urlObject = this.resolveUrlObject();
1085
+ this.headers = this.resolveHeaders();
1086
+ this.cookies = this.resolveCookies();
1087
+ this.isPreflight = this.resolveIsPreflight();
1088
+ }
1089
+ urlObject;
1090
+ isPreflight;
1091
+ cookies;
1092
+ headers;
1093
+ resolveUrlObject() {
1094
+ let urlObject;
1095
+ switch (true) {
1096
+ case this.info instanceof URL:
1097
+ urlObject = this.info;
1098
+ break;
1099
+ case this.info instanceof HttpRequest:
1100
+ urlObject = this.info.urlObject;
1101
+ break;
1102
+ case this.info instanceof Request:
1103
+ urlObject = new URL(this.info.url);
1104
+ break;
1105
+ default:
1106
+ urlObject = new URL(this.info);
1107
+ break;
1108
+ }
1109
+ if (!urlObject.pathname) {
1110
+ urlObject.pathname += "/";
1111
+ }
1112
+ return urlObject;
1113
+ }
1114
+ resolveHeaders() {
1115
+ if (this.init?.headers !== undefined) {
1116
+ return new HttpHeaders(this.init.headers);
1117
+ }
1118
+ if (this.info instanceof Request || this.info instanceof HttpRequest) {
1119
+ return new HttpHeaders(this.info.headers);
1120
+ }
1121
+ return new HttpHeaders;
1122
+ }
1123
+ resolveCookies() {
1124
+ const jar = new Cookies;
1125
+ const cookieHeader = this.headers.get(CommonHeaders.Cookie);
1126
+ if (cookieHeader) {
1127
+ const pairs = strSplit(";", cookieHeader);
1128
+ for (const pair of pairs) {
1129
+ const [name, value] = strSplit("=", pair);
1130
+ if (!name || !value)
1131
+ continue;
1132
+ jar.set({ name, value });
1133
+ }
1134
+ }
1135
+ return jar;
1136
+ }
1137
+ resolveIsPreflight() {
1138
+ const accessControlRequestMethodHeader = this.headers.has(CommonHeaders.AccessControlRequestMethod);
1139
+ return this.method === Method.OPTIONS && accessControlRequestMethodHeader;
1140
+ }
1141
+ }
1142
+ // src/utils/boolToString.ts
1143
+ function boolToString(arg) {
1144
+ return arg ? "true" : "false";
1145
+ }
1146
+
1147
+ // src/utils/isSomeArray.ts
1148
+ function isSomeArray(arg) {
1149
+ return arg !== undefined && Array.isArray(arg) && arg.length > 0 && arg.every((a) => a !== null && a !== undefined);
1150
+ }
1151
+
1152
+ // src/Cors/Cors.ts
1153
+ class Cors {
1154
+ opts;
1155
+ constructor(opts) {
1156
+ this.opts = opts;
1157
+ }
1158
+ originKey = "Access-Control-Allow-Origin";
1159
+ methodsKey = "Access-Control-Allow-Methods";
1160
+ headersKey = "Access-Control-Allow-Headers";
1161
+ credentialsKey = "Access-Control-Allow-Credentials";
1162
+ getCorsHeaders(req, res) {
1163
+ const reqOrigin = req.headers.get("origin") ?? "";
1164
+ const { allowedOrigins, allowedMethods, allowedHeaders, credentials } = this.opts;
1165
+ if (isSomeArray(allowedOrigins) && allowedOrigins.includes(reqOrigin)) {
1166
+ res.headers.set(this.originKey, reqOrigin);
1167
+ }
1168
+ if (isSomeArray(allowedMethods)) {
1169
+ res.headers.set(this.methodsKey, allowedMethods.join(", "));
1170
+ }
1171
+ if (isSomeArray(allowedHeaders)) {
1172
+ res.headers.set(this.headersKey, allowedHeaders.join(", "));
1173
+ }
1174
+ res.headers.set(this.credentialsKey, boolToString(credentials));
1175
+ return res.headers;
1176
+ }
1177
+ apply(req, res) {
1178
+ const headers = this.getCorsHeaders(req, res);
1179
+ res.headers.innerCombine(headers);
1180
+ }
1181
+ }
1182
+
1183
+ // src/utils/strRemoveWhitespace.ts
1184
+ function strRemoveWhitespace(str) {
1185
+ return str.trim().replace(/\s+/g, "");
1186
+ }
1187
+
1188
+ // src/utils/isRegexMatch.ts
1189
+ function isRegexMatch(source, pattern) {
1190
+ return pattern.test(source);
1191
+ }
1192
+
1193
+ // src/utils/strIsEqual.ts
1194
+ function strIsEqual(source, target, modifier) {
1195
+ source = source.trim();
1196
+ target = target.trim();
1197
+ if (modifier === "upper") {
1198
+ return source.toUpperCase() === target.toUpperCase();
1199
+ }
1200
+ if (modifier === "lower") {
1201
+ return source.toUpperCase() === target.toUpperCase();
1202
+ }
1203
+ return source === target;
1204
+ }
1205
+
1206
+ // src/Router/adapters/CorpusAdapter.ts
1207
+ class CorpusAdapter {
1208
+ routes = new Map;
1209
+ add(data) {
1210
+ this.checkPossibleCollision(data);
1211
+ this.routes.set(data.id, data);
1212
+ }
1213
+ find(method, path2) {
1214
+ let route = null;
1215
+ for (const data of this.routes.values()) {
1216
+ const endpoint = data.endpoint;
1217
+ if (this.hasAnyParam(endpoint) && isRegexMatch(path2, data.pattern)) {
1218
+ route = data;
1219
+ break;
1220
+ }
1221
+ if (this.hasLastPartParam(endpoint) && strIsEqual(this.removeLastParam(endpoint), path2, "lower")) {
1222
+ route = data;
1223
+ break;
1224
+ }
1225
+ if (strIsEqual(endpoint, path2)) {
1226
+ route = data;
1227
+ break;
1228
+ }
1229
+ }
1230
+ if (route === null) {
1231
+ throw HttpError.notFound();
1232
+ }
1233
+ if (!strIsEqual(method, route.method, "upper")) {
1234
+ throw HttpError.methodNotAllowed();
1235
+ }
1236
+ return { route };
1237
+ }
1238
+ list() {
1239
+ return Array.from(this.routes.values());
1240
+ }
1241
+ checkPossibleCollision(n) {
1242
+ const dupeMsg = (nId) => console.error(`Duplicate route detected. ${nId} has already been registered.`);
1243
+ const dynamicPatternMsg = (nId, oId) => console.error(`Ambiguous dynamic routes. ${nId} and ${oId} match the same URL patterns.`);
1244
+ const baseDupeMsg = (nId, oId) => console.error(`Dynamic route overlaps existing route. ${nId} \u2014 dropping the last param segment matches ${oId}.`);
1245
+ const shadowMsg = (nId, oId) => console.error(`Route shadowed by existing dynamic route. ${nId} will be unreachable \u2014 ${oId} captures the same URL space.`);
1246
+ const existing = this.routes.get(n.id);
1247
+ if (existing) {
1248
+ dupeMsg(n.id);
1249
+ return true;
1250
+ }
1251
+ const nHasAnyParam = this.hasAnyParam(n.endpoint);
1252
+ const nHasLastPartParam = this.hasLastPartParam(n.endpoint);
1253
+ for (const o of this.routes.values()) {
1254
+ if (o.method !== n.method)
1255
+ continue;
1256
+ if (nHasAnyParam) {
1257
+ if (isRegexMatch(n.endpoint, o.pattern) || isRegexMatch(o.endpoint, n.pattern)) {
1258
+ dynamicPatternMsg(n.id, o.id);
1259
+ return true;
1260
+ }
1261
+ }
1262
+ if (nHasLastPartParam) {
1263
+ if (isRegexMatch(this.removeLastParam(n.endpoint), o.pattern)) {
1264
+ baseDupeMsg(n.id, o.id);
1265
+ return true;
1266
+ }
1267
+ }
1268
+ const oHasLastPartParam = this.hasLastPartParam(o.endpoint);
1269
+ if (oHasLastPartParam) {
1270
+ if (isRegexMatch(n.endpoint, Route.makeRoutePattern(this.removeLastParam(o.endpoint)))) {
1271
+ shadowMsg(n.id, o.id);
1272
+ return true;
1273
+ }
1274
+ }
1275
+ }
1276
+ return false;
1277
+ }
1278
+ hasLastPartParam(endpoint) {
1279
+ if (!this.hasAnyParam(endpoint))
1280
+ return false;
1281
+ const parts = endpoint.split("/");
1282
+ return parts[parts.length - 1]?.startsWith(":") ?? false;
1283
+ }
1284
+ removeLastParam(endpoint) {
1285
+ return endpoint.split("/").slice(0, -1).join("/");
1286
+ }
1287
+ hasAnyParam(endpoint) {
1288
+ if (endpoint.includes("/:"))
1289
+ return true;
1290
+ if (!endpoint.includes(":"))
1291
+ return false;
1292
+ return endpoint.split("/").some((p) => p.startsWith(":"));
1293
+ }
1294
+ }
1295
+
1296
+ // src/Store/LazyMap.ts
1297
+ class LazyMap {
1298
+ constructor() {
1299
+ return new Proxy(this, {
1300
+ get(target, prop) {
1301
+ const val = Reflect.get(target.map, prop);
1302
+ return typeof val === "function" ? val.bind(target.map) : val;
1303
+ }
1304
+ });
1305
+ }
1306
+ _map;
1307
+ get map() {
1308
+ if (!this._map) {
1309
+ this._map = new Map;
1310
+ }
1311
+ return this._map;
1312
+ }
1313
+ get [Symbol.toStringTag]() {
1314
+ return "LazyMap";
1315
+ }
1316
+ }
1317
+
1318
+ // src/Router/Router.ts
1319
+ class Router {
1320
+ constructor(adapter) {
1321
+ this._adapter = adapter ?? new CorpusAdapter;
1322
+ }
1323
+ _adapter;
1324
+ cache = new WeakMap;
1325
+ internFuncMap = new LazyMap;
1326
+ middlewares = new LazyMap;
1327
+ models = new LazyMap;
1328
+ checkPossibleCollision(n) {
1329
+ if (this._adapter instanceof CorpusAdapter) {
1330
+ return this._adapter.checkPossibleCollision(n);
1331
+ }
1332
+ return false;
1333
+ }
1334
+ addModel(routeId, model) {
1335
+ const entry = {};
1336
+ for (const k of Object.keys(model)) {
1337
+ const key = k;
1338
+ const schema = model[key];
1339
+ if (!schema)
1340
+ continue;
1341
+ const handler = schema["~standard"].validate;
1342
+ entry[key] = this.intern(handler, "model", strRemoveWhitespace(JSON.stringify(schema)));
1343
+ }
1344
+ this.models.set(routeId, entry);
1345
+ }
1346
+ findModel(routeId) {
1347
+ return this.models.get(routeId);
1348
+ }
1349
+ addMiddleware(m) {
1350
+ const useOn = m.useOn;
1351
+ const handler = m.handler;
1352
+ if (useOn === "*") {
1353
+ const existing = this.middlewares.get("*") ?? [];
1354
+ this.middlewares.set("*", [...existing, handler]);
1355
+ return;
1356
+ }
1357
+ for (const target of Array.isArray(useOn) ? useOn : [useOn]) {
1358
+ const routeIds = target instanceof Route ? [target.id] : target instanceof ControllerAbstract ? Array.from(target.routeIds) : [];
1359
+ for (const routeId of routeIds) {
1360
+ const existing = this.middlewares.get(routeId) ?? [];
1361
+ this.middlewares.set(routeId, [...existing, handler]);
1362
+ }
1363
+ }
1364
+ }
1365
+ findMiddleware(routeId) {
1366
+ const globals = this.middlewares.get("*") ?? [];
1367
+ const locals = this.middlewares.get(routeId) ?? [];
1368
+ return this.compile([...globals, ...locals]);
1369
+ }
1370
+ addRoute(r) {
1371
+ this._adapter.add({
1372
+ id: r.id,
1373
+ endpoint: r.endpoint,
1374
+ method: r.method,
1375
+ handler: r.handler,
1376
+ pattern: r.pattern
1377
+ });
1378
+ }
1379
+ findRouteHandler(req) {
1380
+ const cached = this.cache.get(req);
1381
+ if (cached)
1382
+ return cached;
1383
+ const match = this._adapter.find(req.method, req.urlObject.pathname);
1384
+ if (!match)
1385
+ throw HttpError.notFound();
1386
+ const ctx = Context.makeFromRequest(req);
1387
+ const mwHandler = this.findMiddleware(match.route.id);
1388
+ const model = this.findModel(match.route.id);
1389
+ const handler = async () => {
1390
+ await mwHandler(ctx);
1391
+ await Context.appendParsedData(ctx, req, match.route.endpoint, model, match.params);
1392
+ const res = await match.route.handler(ctx);
1393
+ return res instanceof HttpResponse ? res : new HttpResponse(res, {
1394
+ cookies: ctx.res.cookies,
1395
+ headers: ctx.res.headers,
1396
+ status: ctx.res.status,
1397
+ statusText: ctx.res.statusText
1398
+ });
1399
+ };
1400
+ this.cache.set(req, handler);
1401
+ return handler;
1402
+ }
1403
+ getRouteList() {
1404
+ return this._adapter.list().map((v) => [v.method, v.endpoint]);
1405
+ }
1406
+ compile(fns) {
1407
+ return async (...args) => {
1408
+ for (const fn of fns) {
1409
+ if (!fn)
1410
+ continue;
1411
+ await fn(...args);
1412
+ }
1413
+ };
1414
+ }
1415
+ intern(value, ...namespace) {
1416
+ const key = namespace.join("::");
1417
+ const existing = this.internFuncMap.get(key);
1418
+ if (existing)
1419
+ return existing;
1420
+ this.internFuncMap.set(key, value);
1421
+ return value;
1422
+ }
1423
+ }
1424
+
1425
+ // src/Server/ServerAbstract.ts
1426
+ class ServerAbstract {
1427
+ constructor(opts) {
1428
+ _router.set(new Router(opts?.adapter));
1429
+ }
1430
+ get routes() {
1431
+ return _router.get().getRouteList();
1432
+ }
1433
+ setGlobalPrefix(value) {
1434
+ _globalPrefix.set(value);
1435
+ }
1436
+ async listen(port, hostname = "0.0.0.0") {
1437
+ try {
1438
+ process.on("SIGINT", () => this.close());
1439
+ process.on("SIGTERM", () => this.close());
1440
+ console.log(`Listening on ${hostname}:${port}`);
1441
+ await this.handleBeforeListen?.();
1442
+ this.serve({
1443
+ port,
1444
+ hostname,
1445
+ fetch: (r) => this.handle(r)
1446
+ });
1447
+ } catch (err) {
1448
+ console.error("Server unable to start:", err);
1449
+ await this.close();
1450
+ }
1451
+ }
1452
+ async handle(request) {
1453
+ const req = new HttpRequest(request);
1454
+ let res = await this.getResponse(req);
1455
+ if (this.cors !== undefined) {
1456
+ this.cors.apply(req, res);
1457
+ }
1458
+ if (this.handleAfterResponse) {
1459
+ res = await this.handleAfterResponse(res);
1460
+ }
1461
+ return res.response;
1462
+ }
1463
+ async getResponse(req) {
1464
+ try {
1465
+ if (req.isPreflight) {
1466
+ return new HttpResponse("Departed");
1467
+ }
1468
+ const handler = _router.get().findRouteHandler(req);
1469
+ return await handler();
1470
+ } catch (err) {
1471
+ if (err instanceof HttpError) {
1472
+ if (err.isStatusOf(Status.NOT_FOUND)) {
1473
+ return await this.handleNotFound(req);
1474
+ }
1475
+ if (err.isStatusOf(Status.METHOD_NOT_ALLOWED)) {
1476
+ return await this.handleMethodNotAllowed(req);
1477
+ }
1478
+ }
1479
+ return await this.handleError(err);
1480
+ }
1481
+ }
1482
+ cors;
1483
+ setCors(opts) {
1484
+ this.cors = opts ? new Cors(opts) : undefined;
1485
+ }
1486
+ handleBeforeListen;
1487
+ setOnBeforeListen(handler) {
1488
+ this.handleBeforeListen = handler;
1489
+ }
1490
+ defaultOnBeforeListen = undefined;
1491
+ handleBeforeClose;
1492
+ setOnBeforeClose(handler) {
1493
+ this.handleBeforeClose = handler;
1494
+ }
1495
+ defaultOnBeforeClose = undefined;
1496
+ handleAfterResponse;
1497
+ setOnAfterResponse(handler) {
1498
+ this.handleAfterResponse = handler;
1499
+ }
1500
+ defaultOnAfterResponse = undefined;
1501
+ handleError = (err) => this.defaultErrorHandler(err);
1502
+ setOnError(handler) {
1503
+ this.handleError = handler;
1504
+ }
1505
+ defaultErrorHandler = (err) => {
1506
+ if (!(err instanceof Error)) {
1507
+ return new HttpResponse({ error: err, message: "Unknown" }, { status: Status.INTERNAL_SERVER_ERROR });
1508
+ }
1509
+ if (err instanceof HttpError) {
1510
+ return err.toResponse();
1511
+ }
1512
+ return new HttpResponse({ error: err, message: err.message }, { status: Status.INTERNAL_SERVER_ERROR });
1513
+ };
1514
+ handleNotFound = (req) => this.defaultNotFoundHandler(req);
1515
+ setOnNotFound(handler) {
1516
+ this.handleNotFound = handler;
1517
+ }
1518
+ defaultNotFoundHandler = (req) => {
1519
+ return new HttpResponse({ error: true, message: `${req.method} on ${req.url} does not exist.` }, { status: Status.NOT_FOUND });
1520
+ };
1521
+ handleMethodNotAllowed = (req) => this.defaultMethodNotFoundHandler(req);
1522
+ defaultMethodNotFoundHandler = (req) => {
1523
+ return new HttpResponse({ error: `${req.method} ${req.url} does not exist.` }, { status: Status.METHOD_NOT_ALLOWED });
1524
+ };
1525
+ }
1526
+
1527
+ // src/Server/ServerUsingBun.ts
1528
+ class ServerUsingBun extends ServerAbstract {
1529
+ app;
1530
+ serve(args) {
1531
+ this.app = this.createApp(args);
1532
+ }
1533
+ async close() {
1534
+ await this.handleBeforeClose?.();
1535
+ console.log("Closing...");
1536
+ await this.app?.stop();
1537
+ if (Config.nodeEnv !== "test") {
1538
+ process.exit(0);
1539
+ }
1540
+ }
1541
+ createApp(options) {
1542
+ return Bun.serve({
1543
+ port: options.port,
1544
+ hostname: options.hostname,
1545
+ fetch: options.fetch
1546
+ });
1547
+ }
1548
+ }
1549
+
1550
+ // src/Server/Server.ts
1551
+ class Server extends ServerUsingBun {
1552
+ }
1553
+ // node_modules/memoirist/dist/bun/index.js
1554
+ var Y = (v, b) => {
1555
+ let A = b?.length ? {} : null;
1556
+ if (A)
1557
+ for (let Q of b)
1558
+ A[Q.part.charCodeAt(0)] = Q;
1559
+ return { part: v, store: null, inert: A, params: null, wildcardStore: null };
1560
+ };
1561
+ var k = (v, b) => ({ ...v, part: b });
1562
+ var T = (v) => ({ name: v, store: null, inert: null });
1563
+
1564
+ class _ {
1565
+ config;
1566
+ root = {};
1567
+ history = [];
1568
+ deferred = [];
1569
+ constructor(v = {}) {
1570
+ this.config = v;
1571
+ if (v.lazy)
1572
+ this.find = this.lazyFind;
1573
+ if (v.onParam && !Array.isArray(v.onParam))
1574
+ this.config.onParam = [this.config.onParam];
1575
+ }
1576
+ static regex = { static: /:.+?(?=\/|$)/, params: /:.+?(?=\/|$)/g, optionalParams: /(\/:\w+\?)/g };
1577
+ lazyFind = (v, b) => {
1578
+ if (!this.config.lazy)
1579
+ return this.find;
1580
+ return this.build(), this.find(v, b);
1581
+ };
1582
+ build() {
1583
+ if (!this.config.lazy)
1584
+ return;
1585
+ for (let [v, b, A] of this.deferred)
1586
+ this.add(v, b, A, { lazy: false, ignoreHistory: true });
1587
+ this.deferred = [], this.find = (v, b) => {
1588
+ let A = this.root[v];
1589
+ if (!A)
1590
+ return null;
1591
+ return $(b, b.length, A, 0, this.config.onParam);
1592
+ };
1593
+ }
1594
+ add(v, b, A, { ignoreError: Q = false, ignoreHistory: O = false, lazy: V = this.config.lazy } = {}) {
1595
+ if (V)
1596
+ return this.find = this.lazyFind, this.deferred.push([v, b, A]), A;
1597
+ if (typeof b !== "string")
1598
+ throw new TypeError("Route path must be a string");
1599
+ if (b === "")
1600
+ b = "/";
1601
+ else if (b[0] !== "/")
1602
+ b = `/${b}`;
1603
+ let X = b[b.length - 1] === "*", J = b.match(_.regex.optionalParams);
1604
+ if (J) {
1605
+ let F = b.replaceAll("?", "");
1606
+ this.add(v, F, A, { ignoreError: Q, ignoreHistory: O, lazy: V });
1607
+ for (let B = 0;B < J.length; B++) {
1608
+ let D = b.replace(J[B], "");
1609
+ this.add(v, D, A, { ignoreError: true, ignoreHistory: O, lazy: V });
1610
+ }
1611
+ return A;
1612
+ }
1613
+ if (J)
1614
+ b = b.replaceAll("?", "");
1615
+ if (this.history.find(([F, B, D]) => F === v && B === b))
1616
+ return A;
1617
+ if (X || J && b.charCodeAt(b.length - 1) === 63)
1618
+ b = b.slice(0, -1);
1619
+ if (!O)
1620
+ this.history.push([v, b, A]);
1621
+ let K = b.split(_.regex.static), G = b.match(_.regex.params) || [];
1622
+ if (K[K.length - 1] === "")
1623
+ K.pop();
1624
+ let q;
1625
+ if (!this.root[v])
1626
+ q = this.root[v] = Y("/");
1627
+ else
1628
+ q = this.root[v];
1629
+ let U = 0;
1630
+ for (let F = 0;F < K.length; ++F) {
1631
+ let B = K[F];
1632
+ if (F > 0) {
1633
+ let D = G[U++].slice(1);
1634
+ if (q.params === null)
1635
+ q.params = T(D);
1636
+ else if (q.params.name !== D)
1637
+ if (Q)
1638
+ return A;
1639
+ else
1640
+ throw new Error(`Cannot create route "${b}" with parameter "${D}" because a route already exists with a different parameter name ("${q.params.name}") in the same location`);
1641
+ let S = q.params;
1642
+ if (S.inert === null) {
1643
+ q = S.inert = Y(B);
1644
+ continue;
1645
+ }
1646
+ q = S.inert;
1647
+ }
1648
+ for (let D = 0;; ) {
1649
+ if (D === B.length) {
1650
+ if (D < q.part.length) {
1651
+ let S = k(q, q.part.slice(D));
1652
+ Object.assign(q, Y(B, [S]));
1653
+ }
1654
+ break;
1655
+ }
1656
+ if (D === q.part.length) {
1657
+ if (q.inert === null)
1658
+ q.inert = {};
1659
+ let S = q.inert[B.charCodeAt(D)];
1660
+ if (S) {
1661
+ q = S, B = B.slice(D), D = 0;
1662
+ continue;
1663
+ }
1664
+ let Z = Y(B.slice(D));
1665
+ q.inert[B.charCodeAt(D)] = Z, q = Z;
1666
+ break;
1667
+ }
1668
+ if (B[D] !== q.part[D]) {
1669
+ let S = k(q, q.part.slice(D)), Z = Y(B.slice(D));
1670
+ Object.assign(q, Y(q.part.slice(0, D), [S, Z])), q = Z;
1671
+ break;
1672
+ }
1673
+ ++D;
1674
+ }
1675
+ }
1676
+ if (U < G.length) {
1677
+ let B = G[U].slice(1);
1678
+ if (q.params === null)
1679
+ q.params = T(B);
1680
+ else if (q.params.name !== B)
1681
+ if (Q)
1682
+ return A;
1683
+ else
1684
+ throw new Error(`Cannot create route "${b}" with parameter "${B}" because a route already exists with a different parameter name ("${q.params.name}") in the same location`);
1685
+ if (q.params.store === null)
1686
+ q.params.store = A;
1687
+ return q.params.store;
1688
+ }
1689
+ if (X) {
1690
+ if (q.wildcardStore === null)
1691
+ q.wildcardStore = A;
1692
+ return q.wildcardStore;
1693
+ }
1694
+ if (q.store === null)
1695
+ q.store = A;
1696
+ return q.store;
1697
+ }
1698
+ find(v, b) {
1699
+ let A = this.root[v];
1700
+ if (!A)
1701
+ return null;
1702
+ return $(b, b.length, A, 0, this.config.onParam);
1703
+ }
1704
+ }
1705
+ var $ = (v, b, A, Q, O) => {
1706
+ let V = A.part, X = V.length, J = Q + X;
1707
+ if (X > 1) {
1708
+ if (J > b)
1709
+ return null;
1710
+ if (X < 15) {
1711
+ for (let K = 1, G = Q + 1;K < X; ++K, ++G)
1712
+ if (V.charCodeAt(K) !== v.charCodeAt(G))
1713
+ return null;
1714
+ } else if (v.slice(Q, J) !== V)
1715
+ return null;
1716
+ }
1717
+ if (J === b) {
1718
+ if (A.store !== null)
1719
+ return { store: A.store, params: {} };
1720
+ if (A.wildcardStore !== null)
1721
+ return { store: A.wildcardStore, params: { "*": "" } };
1722
+ return null;
1723
+ }
1724
+ if (A.inert !== null) {
1725
+ let K = A.inert[v.charCodeAt(J)];
1726
+ if (K !== undefined) {
1727
+ let G = $(v, b, K, J, O);
1728
+ if (G !== null)
1729
+ return G;
1730
+ }
1731
+ }
1732
+ if (A.params !== null) {
1733
+ let { store: K, name: G, inert: q } = A.params, U = v.indexOf("/", J);
1734
+ if (U !== J) {
1735
+ if (U === -1 || U >= b) {
1736
+ if (K !== null) {
1737
+ let F = {};
1738
+ if (F[G] = v.substring(J, b), O)
1739
+ for (let B = 0;B < O.length; B++) {
1740
+ let D = O[B](F[G], G);
1741
+ if (D !== undefined)
1742
+ F[G] = D;
1743
+ }
1744
+ return { store: K, params: F };
1745
+ }
1746
+ } else if (q !== null) {
1747
+ let F = $(v, b, q, U, O);
1748
+ if (F !== null) {
1749
+ if (F.params[G] = v.substring(J, U), O)
1750
+ for (let B = 0;B < O.length; B++) {
1751
+ let D = O[B](F.params[G], G);
1752
+ if (D !== undefined)
1753
+ F.params[G] = D;
1754
+ }
1755
+ return F;
1756
+ }
1757
+ }
1758
+ }
1759
+ }
1760
+ if (A.wildcardStore !== null)
1761
+ return { store: A.wildcardStore, params: { "*": v.substring(J, b) } };
1762
+ return null;
1763
+ };
1764
+ var w = _;
1765
+
1766
+ // src/Router/adapters/MemoiristAdapter.ts
1767
+ class MemoiristAdapter {
1768
+ router = new w;
1769
+ add(data) {
1770
+ this.router.add(data.method, data.endpoint, data);
1771
+ }
1772
+ find(method, path2) {
1773
+ const result = this.router.find(method, path2);
1774
+ if (!result)
1775
+ return null;
1776
+ return { route: result.store, params: result.params };
1777
+ }
1778
+ list() {
1779
+ return this.router.history.map((v) => v[2]);
1780
+ }
1781
+ }
1782
+
1783
+ // src/index.ts
1784
+ var _globalPrefix = new GlobalPrefixStore;
1785
+ var _router = new GlobalRouterStore;
1786
+ var src_default = exports_exports;
1787
+ })