@ozanarslan/corpus 0.1.4 → 0.1.6

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.js CHANGED
@@ -14,23 +14,51 @@ var __export = (target, all) => {
14
14
  });
15
15
  };
16
16
 
17
- // src/exports.ts
18
- var exports_exports = {};
19
- __export(exports_exports, {
17
+ // src/Store/StoreAbstract.ts
18
+ class StoreAbstract {
19
+ set(value) {
20
+ this.value = value;
21
+ }
22
+ get() {
23
+ return this.value;
24
+ }
25
+ }
26
+
27
+ // src/Store/globals/GlobalPrefixStore.ts
28
+ class GlobalPrefixStore extends StoreAbstract {
29
+ value = "";
30
+ }
31
+
32
+ // src/Store/globals/GlobalRouterStore.ts
33
+ class GlobalRouterStore extends StoreAbstract {
34
+ value = null;
35
+ get() {
36
+ if (!this.value) {
37
+ console.error("Router instance is not set. Please instantiate your Server before your routes.");
38
+ process.exit(1);
39
+ }
40
+ return this.value;
41
+ }
42
+ }
43
+
44
+ // src/Store/globals/GlobalCorsStore.ts
45
+ class GlobalCorsStore extends StoreAbstract {
46
+ value = null;
47
+ }
48
+
49
+ // src/C.ts
50
+ var exports_C = {};
51
+ __export(exports_C, {
20
52
  Status: () => Status,
21
53
  StaticRoute: () => StaticRoute,
22
54
  Server: () => Server,
23
55
  Route: () => Route,
24
- Response: () => HttpResponse,
25
- Request: () => HttpRequest,
26
- Repository: () => RepositoryAbstract,
27
- Parser: () => Parser,
56
+ Response: () => CResponse,
57
+ Request: () => CRequest,
28
58
  Middleware: () => Middleware,
29
59
  Method: () => Method,
30
- Headers: () => HttpHeaders,
31
- FileWalker: () => FileWalker,
32
- Error: () => HttpError,
33
- DefaultStatusTexts: () => DefaultStatusTexts,
60
+ Headers: () => CHeaders,
61
+ Error: () => CError,
34
62
  Cookies: () => Cookies,
35
63
  Controller: () => ControllerAbstract,
36
64
  Context: () => Context,
@@ -106,7 +134,7 @@ class Config {
106
134
  this.env[key] = value;
107
135
  }
108
136
  }
109
- // src/Response/enums/Status.ts
137
+ // src/CResponse/enums/Status.ts
110
138
  var Status = {
111
139
  CONTINUE: 100,
112
140
  SWITCHING_PROTOCOLS: 101,
@@ -172,7 +200,7 @@ var Status = {
172
200
  NETWORK_AUTHENTICATION_REQUIRED: 511
173
201
  };
174
202
 
175
- // src/Response/enums/DefaultStatusTexts.ts
203
+ // src/CResponse/enums/DefaultStatusTexts.ts
176
204
  var DefaultStatusTexts = {
177
205
  [Status.OK]: "OK",
178
206
  [Status.CREATED]: "Created",
@@ -189,11 +217,12 @@ var DefaultStatusTexts = {
189
217
  [Status.INTERNAL_SERVER_ERROR]: "Internal Server Error"
190
218
  };
191
219
 
192
- // src/Headers/enums/CommonHeaders.ts
220
+ // src/CHeaders/enums/CommonHeaders.ts
193
221
  var CommonHeaders = {
194
222
  CacheControl: "Cache-Control",
195
223
  ContentType: "Content-Type",
196
224
  ContentLength: "Content-Length",
225
+ ContentDisposition: "Content-Disposition",
197
226
  AcceptEncoding: "Accept-Encoding",
198
227
  Accept: "Accept",
199
228
  Authorization: "Authorization",
@@ -283,8 +312,8 @@ class CookiesUsingBun extends CookiesAbstract {
283
312
  class Cookies extends CookiesUsingBun {
284
313
  }
285
314
 
286
- // src/Headers/HttpHeaders.ts
287
- class HttpHeaders extends Headers {
315
+ // src/CHeaders/CHeaders.ts
316
+ class CHeaders extends Headers {
288
317
  constructor(init) {
289
318
  super(init);
290
319
  }
@@ -314,7 +343,7 @@ class HttpHeaders extends Headers {
314
343
  return target;
315
344
  }
316
345
  innerCombine(source) {
317
- HttpHeaders.combine(source, this);
346
+ CHeaders.combine(source, this);
318
347
  }
319
348
  setMany(init) {
320
349
  const entries = Array.isArray(init) ? init : Object.entries(init);
@@ -325,7 +354,7 @@ class HttpHeaders extends Headers {
325
354
  }
326
355
  }
327
356
  static findHeaderInInit(init, name) {
328
- if (init instanceof HttpHeaders || init instanceof Headers) {
357
+ if (init instanceof CHeaders || init instanceof Headers) {
329
358
  return init.get(name);
330
359
  } else if (Array.isArray(init)) {
331
360
  return init.find((entry) => entry[0] === name)?.[1] ?? null;
@@ -335,19 +364,139 @@ class HttpHeaders extends Headers {
335
364
  }
336
365
  }
337
366
 
338
- // src/Response/HttpResponse.ts
339
- class HttpResponse {
340
- body;
367
+ // src/utils/isNil.ts
368
+ function isNil(input) {
369
+ return input === null || input === undefined;
370
+ }
371
+
372
+ // src/utils/isPrimitive.ts
373
+ function isPrimitive(input) {
374
+ return typeof input === "string" || typeof input === "number" || typeof input === "boolean" || typeof input === "bigint";
375
+ }
376
+
377
+ // src/utils/isPlainObject.ts
378
+ function isPlainObject(input) {
379
+ return typeof input === "object" && input !== null && input.constructor === Object;
380
+ }
381
+
382
+ // src/CError/CError.ts
383
+ class CError extends Error {
384
+ message;
385
+ status;
386
+ data;
387
+ constructor(message, status, data) {
388
+ super(message);
389
+ this.message = message;
390
+ this.status = status;
391
+ this.data = data;
392
+ }
393
+ toResponse() {
394
+ return new CResponse(this.data ? { error: this.data, message: this.message } : { error: true, message: this.message }, { status: this.status });
395
+ }
396
+ isStatusOf(status) {
397
+ return this.status === status;
398
+ }
399
+ static internalServerError(msg) {
400
+ const status = Status.INTERNAL_SERVER_ERROR;
401
+ return new this(msg ?? status.toString(), status);
402
+ }
403
+ static badRequest(msg) {
404
+ const status = Status.BAD_REQUEST;
405
+ return new this(msg ?? status.toString(), status);
406
+ }
407
+ static notFound(msg) {
408
+ const status = Status.NOT_FOUND;
409
+ return new this(msg ?? status.toString(), status);
410
+ }
411
+ static methodNotAllowed(msg) {
412
+ const status = Status.METHOD_NOT_ALLOWED;
413
+ return new this(msg ?? status.toString(), status);
414
+ }
415
+ static unprocessableEntity(msg) {
416
+ const status = Status.UNPROCESSABLE_ENTITY;
417
+ return new this(msg ?? status.toString(), status);
418
+ }
419
+ }
420
+
421
+ // src/XFile/XFileAbstract.ts
422
+ class XFileAbstract {
423
+ path;
424
+ fallbackExtension;
425
+ constructor(path2, fallbackExtension) {
426
+ this.path = path2;
427
+ this.fallbackExtension = fallbackExtension;
428
+ }
429
+ get name() {
430
+ return this.path.split("/").pop() ?? this.path;
431
+ }
432
+ get extension() {
433
+ return this.path.split(".").pop() ?? this.fallbackExtension ?? "txt";
434
+ }
435
+ get mimeType() {
436
+ const mimeTypes = {
437
+ html: "text/html",
438
+ htm: "text/html",
439
+ css: "text/css",
440
+ js: "application/javascript",
441
+ ts: "application/javascript",
442
+ mjs: "application/javascript",
443
+ json: "application/json",
444
+ png: "image/png",
445
+ jpg: "image/jpeg",
446
+ jpeg: "image/jpeg",
447
+ gif: "image/gif",
448
+ svg: "image/svg+xml",
449
+ ico: "image/x-icon",
450
+ txt: "text/plain",
451
+ xml: "application/xml",
452
+ pdf: "application/pdf",
453
+ zip: "application/zip",
454
+ mp3: "audio/mpeg",
455
+ mp4: "video/mp4",
456
+ webm: "video/webm",
457
+ woff: "font/woff",
458
+ woff2: "font/woff2",
459
+ ttf: "font/ttf"
460
+ };
461
+ return mimeTypes[this.extension] ?? "application/octet-stream";
462
+ }
463
+ }
464
+
465
+ // src/XFile/XFileUsingBun.ts
466
+ class XFileUsingBun extends XFileAbstract {
467
+ constructor(...args) {
468
+ super(...args);
469
+ this.file = Bun.file(args[0]);
470
+ }
471
+ file;
472
+ async exists() {
473
+ return await this.file.exists();
474
+ }
475
+ async text() {
476
+ return await this.file.text();
477
+ }
478
+ stream() {
479
+ return this.file.stream();
480
+ }
481
+ }
482
+
483
+ // src/XFile/XFile.ts
484
+ class XFile extends XFileUsingBun {
485
+ }
486
+ // src/CResponse/CResponse.ts
487
+ class CResponse {
488
+ data;
341
489
  init;
342
- constructor(body, init) {
343
- this.body = body;
490
+ constructor(data, init) {
491
+ this.data = data;
344
492
  this.init = init;
345
- this.cookies = this.getCookies();
346
- this.headers = this.getHeaders();
347
- this.body = this.getBody();
348
- this.status = this.getStatus();
493
+ this.cookies = this.resolveCookies();
494
+ this.headers = this.resolveHeaders();
495
+ this.body = this.resolveBody();
496
+ this.status = this.resolveStatus();
349
497
  this.statusText = this.getDefaultStatusText();
350
498
  }
499
+ body;
351
500
  headers;
352
501
  status;
353
502
  statusText;
@@ -359,11 +508,126 @@ class HttpResponse {
359
508
  headers: this.headers
360
509
  });
361
510
  }
362
- getCookies() {
511
+ static redirect(url, init) {
512
+ const res = new CResponse(undefined, {
513
+ ...init,
514
+ status: init?.status ?? Status.FOUND,
515
+ statusText: init?.statusText ?? DefaultStatusTexts[Status.FOUND]
516
+ });
517
+ const urlString = url instanceof URL ? url.toString() : url;
518
+ res.headers.set(CommonHeaders.Location, urlString);
519
+ return res;
520
+ }
521
+ static permanentRedirect(url, init) {
522
+ return this.redirect(url, {
523
+ ...init,
524
+ status: Status.MOVED_PERMANENTLY
525
+ });
526
+ }
527
+ static temporaryRedirect(url, init) {
528
+ return this.redirect(url, { ...init, status: Status.TEMPORARY_REDIRECT });
529
+ }
530
+ static seeOther(url, init) {
531
+ return this.redirect(url, { ...init, status: Status.SEE_OTHER });
532
+ }
533
+ static createStream(execute) {
534
+ let cancelled = false;
535
+ let cleanup;
536
+ return new ReadableStream({
537
+ start(controller) {
538
+ try {
539
+ cleanup = execute(controller, () => cancelled);
540
+ if (typeof cleanup !== "function") {
541
+ controller.close();
542
+ }
543
+ } catch (err) {
544
+ controller.error(err);
545
+ }
546
+ },
547
+ cancel() {
548
+ cancelled = true;
549
+ cleanup?.();
550
+ }
551
+ });
552
+ }
553
+ static sse(source, init, retry) {
554
+ const encoder = new TextEncoder;
555
+ const stream = CResponse.createStream((controller, isCancelled) => {
556
+ return source((event) => {
557
+ if (isCancelled())
558
+ return;
559
+ let chunk = "";
560
+ if (retry !== undefined)
561
+ chunk += `retry: ${retry}
562
+ `;
563
+ if (event.id)
564
+ chunk += `id: ${event.id}
565
+ `;
566
+ if (event.event)
567
+ chunk += `event: ${event.event}
568
+ `;
569
+ chunk += `data: ${JSON.stringify(event.data)}
570
+
571
+ `;
572
+ controller.enqueue(encoder.encode(chunk));
573
+ });
574
+ });
575
+ const res = new CResponse(stream, { ...init, status: Status.OK });
576
+ res.headers.setMany({
577
+ [CommonHeaders.ContentType]: "text/event-stream",
578
+ [CommonHeaders.CacheControl]: "no-cache",
579
+ [CommonHeaders.Connection]: "keep-alive"
580
+ });
581
+ return res;
582
+ }
583
+ static ndjson(source, init) {
584
+ const encoder = new TextEncoder;
585
+ const stream = CResponse.createStream((controller, isCancelled) => {
586
+ return source((item) => {
587
+ if (isCancelled())
588
+ return;
589
+ controller.enqueue(encoder.encode(`${JSON.stringify(item)}
590
+ `));
591
+ });
592
+ });
593
+ const res = new CResponse(stream, { ...init, status: Status.OK });
594
+ res.headers.setMany({
595
+ [CommonHeaders.ContentType]: "application/x-ndjson",
596
+ [CommonHeaders.CacheControl]: "no-cache"
597
+ });
598
+ return res;
599
+ }
600
+ static async streamFile(filePath, disposition = "attachment", init) {
601
+ const file = new XFile(filePath);
602
+ if (!file) {
603
+ throw CError.notFound();
604
+ }
605
+ const stream = file.stream();
606
+ const res = new CResponse(stream, { ...init, status: Status.OK });
607
+ res.headers.setMany({
608
+ [CommonHeaders.ContentType]: file.mimeType,
609
+ [CommonHeaders.ContentDisposition]: `${disposition}; filename="${file.name}"`
610
+ });
611
+ return res;
612
+ }
613
+ static async file(filePath, init) {
614
+ const file = new XFile(filePath);
615
+ if (!file) {
616
+ throw CError.notFound();
617
+ }
618
+ const content = await file.text();
619
+ const res = new CResponse(content, init);
620
+ res.headers.setMany({
621
+ [CommonHeaders.ContentType]: file.mimeType,
622
+ [CommonHeaders.ContentLength]: content.length.toString()
623
+ });
624
+ return res;
625
+ }
626
+ resolveCookies() {
363
627
  return new Cookies(this.init?.cookies);
364
628
  }
365
- getHeaders() {
366
- const headers = new HttpHeaders(this.init?.headers);
629
+ resolveHeaders() {
630
+ const headers = new CHeaders(this.init?.headers);
367
631
  const setCookieHeaders = this.cookies.toSetCookieHeaders();
368
632
  if (setCookieHeaders.length > 0) {
369
633
  for (const header of setCookieHeaders) {
@@ -372,7 +636,7 @@ class HttpResponse {
372
636
  }
373
637
  return headers;
374
638
  }
375
- getStatus() {
639
+ resolveStatus() {
376
640
  if (this.init?.status)
377
641
  return this.init.status;
378
642
  if (this.headers.has(CommonHeaders.Location)) {
@@ -385,58 +649,53 @@ class HttpResponse {
385
649
  this.headers.set(CommonHeaders.ContentType, value);
386
650
  }
387
651
  }
388
- getBody() {
389
- if (this.body === null || this.body === undefined) {
652
+ resolveBody() {
653
+ if (isNil(this.data)) {
390
654
  this.setContentType("text/plain");
391
655
  return "";
392
656
  }
393
- if (typeof this.body !== "object") {
657
+ if (isPrimitive(this.data)) {
394
658
  this.setContentType("text/plain");
395
- return String(this.body);
659
+ return String(this.data);
660
+ }
661
+ if (this.data instanceof ArrayBuffer) {
662
+ this.setContentType("application/octet-stream");
663
+ return this.data;
664
+ }
665
+ if (this.data instanceof Blob) {
666
+ if (this.data.type)
667
+ this.setContentType(this.data.type);
668
+ return this.data;
669
+ }
670
+ if (this.data instanceof FormData) {
671
+ this.setContentType("multipart/form-data");
672
+ return this.data;
673
+ }
674
+ if (this.data instanceof URLSearchParams) {
675
+ this.setContentType("application/x-www-form-urlencoded");
676
+ return this.data;
396
677
  }
397
- if (this.body instanceof ArrayBuffer || this.body instanceof Blob || this.body instanceof FormData || this.body instanceof URLSearchParams || this.body instanceof ReadableStream) {
398
- throw new Error("Unsupported response body: ArrayBuffer | Blob | FormData | URLSearchParams | ReadableStream");
678
+ if (this.data instanceof ReadableStream) {
679
+ return this.data;
399
680
  }
400
- if (this.body instanceof Date) {
681
+ if (this.data instanceof Date) {
401
682
  this.setContentType("text/plain");
402
- return this.body.toISOString();
683
+ return this.data.toISOString();
403
684
  }
404
- if (Array.isArray(this.body) || this.body.constructor === Object) {
685
+ if (Array.isArray(this.data) || isPlainObject(this.data)) {
405
686
  this.setContentType("application/json");
406
- return JSON.stringify(this.body);
687
+ return JSON.stringify(this.data);
407
688
  }
408
689
  this.setContentType("text/plain");
409
- return String(this.body);
690
+ return String(this.data);
410
691
  }
411
692
  getDefaultStatusText() {
412
693
  const key = this.status;
413
694
  return DefaultStatusTexts[key] ?? "Unknown";
414
695
  }
415
- static redirect(url, init) {
416
- const res = new HttpResponse(undefined, {
417
- ...init,
418
- status: init?.status ?? Status.FOUND,
419
- statusText: init?.statusText ?? DefaultStatusTexts[Status.FOUND]
420
- });
421
- const urlString = url instanceof URL ? url.toString() : url;
422
- res.headers.set(CommonHeaders.Location, urlString);
423
- return res;
424
- }
425
- static permanentRedirect(url, init) {
426
- return this.redirect(url, {
427
- ...init,
428
- status: Status.MOVED_PERMANENTLY
429
- });
430
- }
431
- static temporaryRedirect(url, init) {
432
- return this.redirect(url, { ...init, status: Status.TEMPORARY_REDIRECT });
433
- }
434
- static seeOther(url, init) {
435
- return this.redirect(url, { ...init, status: Status.SEE_OTHER });
436
- }
437
696
  }
438
697
 
439
- // src/Request/enums/Method.ts
698
+ // src/CRequest/enums/Method.ts
440
699
  var Method = {
441
700
  GET: "GET",
442
701
  POST: "POST",
@@ -449,45 +708,6 @@ var Method = {
449
708
  TRACE: "TRACE"
450
709
  };
451
710
 
452
- // src/Error/HttpError.ts
453
- class HttpError extends Error {
454
- message;
455
- status;
456
- data;
457
- constructor(message, status, data) {
458
- super(message);
459
- this.message = message;
460
- this.status = status;
461
- this.data = data;
462
- }
463
- toResponse() {
464
- return new HttpResponse(this.data ? { error: this.data, message: this.message } : { error: true, message: this.message }, { status: this.status });
465
- }
466
- isStatusOf(status) {
467
- return this.status === status;
468
- }
469
- static internalServerError(msg) {
470
- const status = Status.INTERNAL_SERVER_ERROR;
471
- return new this(msg ?? status.toString(), status);
472
- }
473
- static badRequest(msg) {
474
- const status = Status.BAD_REQUEST;
475
- return new this(msg ?? status.toString(), status);
476
- }
477
- static notFound(msg) {
478
- const status = Status.NOT_FOUND;
479
- return new this(msg ?? status.toString(), status);
480
- }
481
- static methodNotAllowed(msg) {
482
- const status = Status.METHOD_NOT_ALLOWED;
483
- return new this(msg ?? status.toString(), status);
484
- }
485
- static unprocessableEntity(msg) {
486
- const status = Status.UNPROCESSABLE_ENTITY;
487
- return new this(msg ?? status.toString(), status);
488
- }
489
- }
490
-
491
711
  // src/utils/arrIncludes.ts
492
712
  function arrIncludes(input, array) {
493
713
  return array.includes(input);
@@ -516,7 +736,7 @@ class Parser {
516
736
  const result = await validate(data);
517
737
  if (result.issues !== undefined) {
518
738
  const msg = this.issuesToErrorMessage(result.issues);
519
- throw HttpError.unprocessableEntity(msg);
739
+ throw CError.unprocessableEntity(msg);
520
740
  }
521
741
  return result.value;
522
742
  }
@@ -532,14 +752,14 @@ class Parser {
532
752
  }).join(`
533
753
  `);
534
754
  }
535
- static async getSearch(url, validate) {
755
+ static async parseUrlData(params, validate) {
536
756
  const data = {};
537
- for (const [key, value] of url.searchParams ?? {}) {
538
- data[key] = this.processString(value);
757
+ for (const [key, value] of Object.entries(params)) {
758
+ data[key] = decodeURIComponent(value);
539
759
  }
540
760
  return await this.parse(data, validate);
541
761
  }
542
- static async getBody(r, validate) {
762
+ static async parseBody(r, validate) {
543
763
  let data;
544
764
  const empty = {};
545
765
  const input = r instanceof Request ? r : r instanceof Response ? r : r.response;
@@ -566,7 +786,7 @@ class Parser {
566
786
  case "image":
567
787
  case "audio":
568
788
  case "video":
569
- throw new HttpError("unprocessable.contentType", Status.UNPROCESSABLE_ENTITY);
789
+ throw new CError("unprocessable.contentType", Status.UNPROCESSABLE_ENTITY);
570
790
  case "no-body-allowed":
571
791
  default:
572
792
  return empty;
@@ -578,23 +798,6 @@ class Parser {
578
798
  throw err;
579
799
  }
580
800
  }
581
- static async getParams(endpoint, url, validate) {
582
- const data = {};
583
- if (!endpoint.includes(":")) {
584
- return data;
585
- }
586
- const defParts = endpoint.split("/");
587
- const reqParts = url.pathname.split("/");
588
- for (const [i, defPart] of defParts.entries()) {
589
- const reqPart = reqParts[i];
590
- if (defPart.startsWith(":") && reqPart !== undefined) {
591
- const key = defPart.slice(1);
592
- const value = this.processString(decodeURIComponent(reqPart));
593
- data[key] = value;
594
- }
595
- }
596
- return await this.parse(data, validate);
597
- }
598
801
  static async getUnknownBody(input, validate) {
599
802
  if (!validate) {
600
803
  return await this.getTextBody(input);
@@ -616,7 +819,7 @@ class Parser {
616
819
  const params = new URLSearchParams(text);
617
820
  const body = {};
618
821
  for (const [key, value] of params.entries()) {
619
- objAppendEntry(body, key, this.processString(value));
822
+ objAppendEntry(body, key, value);
620
823
  }
621
824
  return body;
622
825
  }
@@ -628,7 +831,7 @@ class Parser {
628
831
  if (value instanceof File) {
629
832
  body[key] = value;
630
833
  } else {
631
- objAppendEntry(body, key, this.processString(value));
834
+ objAppendEntry(body, key, value);
632
835
  }
633
836
  }
634
837
  return body;
@@ -637,16 +840,14 @@ class Parser {
637
840
  const contentLength = input.headers.get(CommonHeaders.ContentLength);
638
841
  const length = contentLength ? parseInt(contentLength) : 0;
639
842
  if (length > 0 && length < 1024 * 1024) {
640
- const text2 = await input.text();
641
- return this.processString(text2);
843
+ return await input.text();
642
844
  }
643
845
  const buffer = await input.arrayBuffer();
644
846
  const contentType = input.headers.get(CommonHeaders.ContentType) || "";
645
847
  const match = contentType.match(/charset=([^;]+)/i);
646
848
  const charset = match?.[1] ? match[1].trim() : null;
647
849
  const decoder = new TextDecoder(charset || "utf-8");
648
- const text = decoder.decode(buffer);
649
- return this.processString(text);
850
+ return decoder.decode(buffer);
650
851
  }
651
852
  static getNormalizedContentType(input) {
652
853
  const contentTypeHeader = input.headers.get(CommonHeaders.ContentType) || "";
@@ -683,17 +884,6 @@ class Parser {
683
884
  }
684
885
  return "unknown";
685
886
  }
686
- static processString(value) {
687
- let processedValue = value;
688
- if (!strIsDefined(value))
689
- return "";
690
- if (/^-?\d+(\.\d+)?$/.test(value)) {
691
- processedValue = Number(value);
692
- } else if (value.toLowerCase() === "true" || value.toLowerCase() === "false") {
693
- processedValue = value.toLowerCase() === "true";
694
- }
695
- return processedValue;
696
- }
697
887
  }
698
888
 
699
889
  // src/Context/Context.ts
@@ -706,7 +896,7 @@ class Context {
706
896
  this.body = body;
707
897
  this.search = search;
708
898
  this.params = params;
709
- this.res = res ?? new HttpResponse;
899
+ this.res = res ?? new CResponse;
710
900
  }
711
901
  req;
712
902
  url;
@@ -720,10 +910,10 @@ class Context {
720
910
  static makeFromRequest(req) {
721
911
  return new Context(req, {}, {}, {});
722
912
  }
723
- static async appendParsedData(ctx, req, endpoint, model) {
724
- ctx.body = await Parser.getBody(req, model?.body);
725
- ctx.search = await Parser.getSearch(ctx.url, model?.search);
726
- ctx.params = await Parser.getParams(endpoint, ctx.url, model?.params);
913
+ static async appendParsedData(ctx, req, params, search, model) {
914
+ ctx.body = await Parser.parseBody(req, model?.body);
915
+ ctx.params = await Parser.parseUrlData(params, model?.params);
916
+ ctx.search = await Parser.parseUrlData(search, model?.search);
727
917
  }
728
918
  }
729
919
  // src/Route/enums/RouteVariant.ts
@@ -738,15 +928,12 @@ function joinPathSegments(...segments) {
738
928
  return `/${joined}`;
739
929
  }
740
930
 
741
- // src/Config/constants/_globalPrefixEnvKey.ts
742
- var _globalPrefixEnvKey = "CORPUS_GLOBAL_PREFIX";
743
-
744
931
  // src/Route/RouteAbstract.ts
745
932
  class RouteAbstract {
746
933
  resolveEndpoint(definition, variant) {
747
934
  const endpoint = typeof definition === "string" ? definition : definition.path;
748
935
  if (variant === RouteVariant.dynamic) {
749
- return joinPathSegments(Config.get(_globalPrefixEnvKey, { fallback: "" }), endpoint);
936
+ return joinPathSegments(_prefixStore.get(), endpoint);
750
937
  }
751
938
  return endpoint;
752
939
  }
@@ -754,8 +941,7 @@ class RouteAbstract {
754
941
  return typeof definition === "string" ? Method.GET : definition.method;
755
942
  }
756
943
  resolvePattern(endpoint) {
757
- const regex = endpoint.split("/").map((part) => part.startsWith(":") ? "([^\\/]+)" : part).join("/");
758
- return new RegExp(`^${regex}$`);
944
+ return Route.makeRoutePattern(endpoint);
759
945
  }
760
946
  resolveId(method, endpoint) {
761
947
  return Route.makeRouteId(method, endpoint);
@@ -773,9 +959,9 @@ class Route extends RouteAbstract {
773
959
  this.id = this.resolveId(this.method, this.endpoint);
774
960
  this.model = model;
775
961
  this.handler = handler;
776
- getRouterInstance().addRoute(this);
962
+ _routerStore.get().addRoute(this);
777
963
  if (model) {
778
- getRouterInstance().addModel(this.id, model);
964
+ _routerStore.get().addModel(this, model);
779
965
  }
780
966
  }
781
967
  variant;
@@ -788,61 +974,25 @@ class Route extends RouteAbstract {
788
974
  static makeRouteId(method, endpoint) {
789
975
  return `${method.toUpperCase()} ${endpoint}`;
790
976
  }
791
- }
792
-
793
- // src/FileWalker/FileWalkerUsingBun.ts
794
- class FileWalkerUsingBun {
795
- static async read(address) {
796
- try {
797
- const file = await this.find(address);
798
- if (!file)
799
- return null;
800
- return await file.text();
801
- } catch {
802
- return null;
803
- }
804
- }
805
- static async exists(address) {
806
- return await this.find(address) !== null;
807
- }
808
- static getExtension(address) {
809
- return address.split(".").pop() ?? "txt";
810
- }
811
- static async find(address) {
812
- const file = Bun.file(address);
813
- const exists = await file.exists();
814
- if (exists) {
815
- return { text: () => file.text() };
816
- }
817
- return null;
977
+ static makeRoutePattern(endpoint) {
978
+ const regex = endpoint.split("/").map((part) => part.startsWith(":") ? "([^\\/]+)" : part).join("/");
979
+ return new RegExp(`^${regex}$`);
818
980
  }
819
981
  }
820
982
 
821
- // src/FileWalker/FileWalker.ts
822
- class FileWalker extends FileWalkerUsingBun {
823
- }
824
-
825
983
  // src/Route/StaticRoute.ts
826
984
  class StaticRoute extends RouteAbstract {
827
- filePath;
828
- constructor(path2, filePath, handler, model) {
985
+ constructor(path2, definition, handler, model) {
829
986
  super();
830
- this.filePath = filePath;
831
987
  this.variant = RouteVariant.static;
832
988
  this.endpoint = this.resolveEndpoint(path2, this.variant);
833
989
  this.method = Method.GET;
834
990
  this.pattern = this.resolvePattern(this.endpoint);
835
991
  this.id = this.resolveId(this.method, this.endpoint);
836
992
  this.model = model;
837
- if (handler) {
838
- this.handler = async (c) => {
839
- const content = await this.defaultHandler(c);
840
- return handler(c, content);
841
- };
842
- } else {
843
- this.handler = this.defaultHandler;
844
- }
845
- getRouterInstance().addRoute(this);
993
+ this.filePath = this.resolveFilePath(definition);
994
+ this.handler = this.resolveHandler(definition, handler);
995
+ _routerStore.get().addRoute(this);
846
996
  }
847
997
  id;
848
998
  variant;
@@ -851,73 +1001,30 @@ class StaticRoute extends RouteAbstract {
851
1001
  pattern;
852
1002
  model;
853
1003
  handler;
854
- defaultHandler = async (c) => {
855
- let content = "";
856
- switch (this.extension) {
857
- case "html":
858
- content = await this.handleHtml();
859
- break;
860
- case "css":
861
- content = await this.handleCss();
862
- break;
863
- case "js":
864
- content = await this.handleJs();
865
- break;
866
- default:
867
- content = await this.handleFile();
868
- break;
1004
+ filePath;
1005
+ resolveFilePath(definition) {
1006
+ return typeof definition === "string" ? definition : definition.filePath;
1007
+ }
1008
+ resolveHandler(definition, customHandler) {
1009
+ if (customHandler !== undefined) {
1010
+ return async (c) => {
1011
+ const file = new XFile(this.filePath);
1012
+ if (!file) {
1013
+ console.error("File not found at:", this.filePath);
1014
+ throw CError.notFound();
1015
+ }
1016
+ const content = await file.text();
1017
+ c.res.headers.setMany({
1018
+ [CommonHeaders.ContentType]: file.mimeType,
1019
+ [CommonHeaders.ContentLength]: content.length.toString()
1020
+ });
1021
+ return customHandler(c, content);
1022
+ };
1023
+ } else if (typeof definition === "string") {
1024
+ return async () => await CResponse.file(this.filePath);
1025
+ } else {
1026
+ return async () => await CResponse.streamFile(this.filePath);
869
1027
  }
870
- c.res.headers.set(CommonHeaders.ContentType, this.mimeTypes[this.extension] || "application/octet-stream");
871
- c.res.headers.set(CommonHeaders.ContentLength, content.length.toString());
872
- return content;
873
- };
874
- get extension() {
875
- return this.filePath.split(".").pop() || "txt";
876
- }
877
- async getContent() {
878
- const content = await FileWalker.read(this.filePath);
879
- if (!content) {
880
- console.error("File not found at:", this.filePath);
881
- throw HttpError.notFound();
882
- }
883
- return content;
884
- }
885
- mimeTypes = {
886
- html: "text/html",
887
- htm: "text/html",
888
- css: "text/css",
889
- js: "application/javascript",
890
- ts: "application/javascript",
891
- mjs: "application/javascript",
892
- json: "application/json",
893
- png: "image/png",
894
- jpg: "image/jpeg",
895
- jpeg: "image/jpeg",
896
- gif: "image/gif",
897
- svg: "image/svg+xml",
898
- ico: "image/x-icon",
899
- txt: "text/plain",
900
- xml: "application/xml",
901
- pdf: "application/pdf",
902
- zip: "application/zip",
903
- mp3: "audio/mpeg",
904
- mp4: "video/mp4",
905
- webm: "video/webm",
906
- woff: "font/woff",
907
- woff2: "font/woff2",
908
- ttf: "font/ttf"
909
- };
910
- async handleHtml() {
911
- return await this.getContent();
912
- }
913
- async handleCss() {
914
- return await this.getContent();
915
- }
916
- async handleJs() {
917
- return await this.getContent();
918
- }
919
- async handleFile() {
920
- return await this.getContent();
921
1028
  }
922
1029
  }
923
1030
 
@@ -960,18 +1067,11 @@ class Middleware {
960
1067
  constructor(opts) {
961
1068
  this.useOn = opts.useOn;
962
1069
  this.handler = opts.handler;
963
- getRouterInstance().addMiddleware(opts);
1070
+ _routerStore.get().addMiddleware(opts);
964
1071
  }
965
1072
  useOn;
966
1073
  handler;
967
1074
  }
968
- // src/Repository/RepositoryAbstract.ts
969
- class RepositoryAbstract {
970
- db;
971
- constructor(db) {
972
- this.db = db;
973
- }
974
- }
975
1075
  // src/utils/assert.ts
976
1076
  function assert(condition, message) {
977
1077
  const conditionName = String(condition);
@@ -995,8 +1095,8 @@ function strSplit(mark, input, minLength) {
995
1095
  return parts;
996
1096
  }
997
1097
 
998
- // src/Request/HttpRequest.ts
999
- class HttpRequest extends Request {
1098
+ // src/CRequest/CRequest.ts
1099
+ class CRequest extends Request {
1000
1100
  info;
1001
1101
  init;
1002
1102
  constructor(info, init) {
@@ -1018,7 +1118,7 @@ class HttpRequest extends Request {
1018
1118
  case this.info instanceof URL:
1019
1119
  urlObject = this.info;
1020
1120
  break;
1021
- case this.info instanceof HttpRequest:
1121
+ case this.info instanceof CRequest:
1022
1122
  urlObject = this.info.urlObject;
1023
1123
  break;
1024
1124
  case this.info instanceof Request:
@@ -1035,12 +1135,12 @@ class HttpRequest extends Request {
1035
1135
  }
1036
1136
  resolveHeaders() {
1037
1137
  if (this.init?.headers !== undefined) {
1038
- return new HttpHeaders(this.init.headers);
1138
+ return new CHeaders(this.init.headers);
1039
1139
  }
1040
- if (this.info instanceof Request || this.info instanceof HttpRequest) {
1041
- return new HttpHeaders(this.info.headers);
1140
+ if (this.info instanceof Request || this.info instanceof CRequest) {
1141
+ return new CHeaders(this.info.headers);
1042
1142
  }
1043
- return new HttpHeaders;
1143
+ return new CHeaders;
1044
1144
  }
1045
1145
  resolveCookies() {
1046
1146
  const jar = new Cookies;
@@ -1079,96 +1179,45 @@ function strIsEqual(source, target, modifier) {
1079
1179
  return source === target;
1080
1180
  }
1081
1181
 
1182
+ // src/Store/LazyMap.ts
1183
+ class LazyMap {
1184
+ constructor() {
1185
+ return new Proxy(this, {
1186
+ get(target, prop) {
1187
+ const val = Reflect.get(target.map, prop);
1188
+ return typeof val === "function" ? val.bind(target.map) : val;
1189
+ }
1190
+ });
1191
+ }
1192
+ _map;
1193
+ get map() {
1194
+ if (!this._map) {
1195
+ this._map = new Map;
1196
+ }
1197
+ return this._map;
1198
+ }
1199
+ get [Symbol.toStringTag]() {
1200
+ return "LazyMap";
1201
+ }
1202
+ }
1203
+
1082
1204
  // src/utils/strRemoveWhitespace.ts
1083
1205
  function strRemoveWhitespace(str) {
1084
1206
  return str.trim().replace(/\s+/g, "");
1085
1207
  }
1086
1208
 
1087
- // src/Router/Router.ts
1088
- class Router {
1089
- _routes;
1090
- _middlewares;
1091
- _models;
1092
- internFuncMap = new Map;
1093
- cache = new WeakMap;
1094
- get routes() {
1095
- if (!this._routes) {
1096
- this._routes = new Map;
1097
- }
1098
- return this._routes;
1099
- }
1100
- get models() {
1101
- if (!this._models) {
1102
- this._models = new Map;
1103
- }
1104
- return this._models;
1105
- }
1106
- get middlewares() {
1107
- if (!this._middlewares) {
1108
- this._middlewares = new Map;
1109
- }
1110
- return this._middlewares;
1111
- }
1112
- globalPrefix = "";
1113
- setGlobalPrefix(value) {
1114
- this.globalPrefix = value;
1115
- }
1116
- getRouteHandler(req) {
1117
- const cached = this.cache.get(req);
1118
- if (cached) {
1119
- return cached;
1120
- }
1121
- const route = this.findRoute(req);
1122
- const ctx = Context.makeFromRequest(req);
1123
- const middleware = this.findRouterMiddlewareData(route.id);
1124
- const model = this.findModel(route.id);
1125
- const handler = async () => {
1126
- await middleware?.(ctx);
1127
- await Context.appendParsedData(ctx, req, route.endpoint, model);
1128
- const result = await route.handler(ctx);
1129
- return result instanceof HttpResponse ? result : new HttpResponse(result, {
1130
- cookies: ctx.res.cookies,
1131
- headers: ctx.res.headers,
1132
- status: ctx.res.status,
1133
- statusText: ctx.res.statusText
1134
- });
1135
- };
1136
- this.cache.set(req, handler);
1137
- return handler;
1138
- }
1139
- getRouteList() {
1140
- return Array.from(this.routes.values()).map((r) => [r.method, r.endpoint]);
1141
- }
1142
- addRoute(r) {
1143
- const handler = this.intern(r.handler, "route", r.id);
1144
- this.checkPossibleCollision(r);
1145
- this.routes.set(r.endpoint, {
1146
- id: r.id,
1147
- endpoint: r.endpoint,
1148
- method: r.method,
1149
- handler,
1150
- pattern: r.pattern
1151
- });
1152
- }
1153
- addMiddleware(m) {
1154
- const useOn = m.useOn;
1155
- const handler = this.intern(m.handler, "middleware", m.handler.toString());
1156
- if (useOn === "*") {
1157
- this.middlewares.set("*", this.compile([this.middlewares.get("*"), handler]));
1158
- return;
1159
- }
1160
- for (const target of Array.isArray(useOn) ? useOn : [useOn]) {
1161
- const routeIds = target instanceof Route ? [target.id] : target instanceof ControllerAbstract ? Array.from(target.routeIds) : [];
1162
- for (const routeId of routeIds) {
1163
- this.middlewares.set(routeId, this.compile([
1164
- this.middlewares.get("*"),
1165
- this.middlewares.get(routeId),
1166
- handler
1167
- ]));
1168
- }
1169
- }
1170
- }
1171
- addModel(routeId, model) {
1209
+ // src/Router/registries/ModelRegistry.ts
1210
+ class ModelRegistry {
1211
+ map = new LazyMap;
1212
+ add(method, endpoint, model) {
1213
+ const entry = ModelRegistry.toRouterModelData(model);
1214
+ this.map.set(Route.makeRouteId(method, endpoint), entry);
1215
+ }
1216
+ find(routeId) {
1217
+ return this.map.get(routeId);
1218
+ }
1219
+ static internFuncMap = new LazyMap;
1220
+ static toRouterModelData(model) {
1172
1221
  const entry = {};
1173
1222
  for (const k of Object.keys(model)) {
1174
1223
  const key = k;
@@ -1178,69 +1227,166 @@ class Router {
1178
1227
  const handler = schema["~standard"].validate;
1179
1228
  entry[key] = this.intern(handler, "model", strRemoveWhitespace(JSON.stringify(schema)));
1180
1229
  }
1181
- this.models.set(routeId, entry);
1230
+ return entry;
1182
1231
  }
1183
- findRouterMiddlewareData(routeId) {
1184
- return this.middlewares.get(routeId);
1232
+ static intern(value, ...namespace) {
1233
+ const key = namespace.join("::");
1234
+ const existing = this.internFuncMap.get(key);
1235
+ if (existing)
1236
+ return existing;
1237
+ this.internFuncMap.set(key, value);
1238
+ return value;
1185
1239
  }
1186
- findModel(routeId) {
1187
- return this.models.get(routeId);
1240
+ }
1241
+
1242
+ // src/utils/compile.ts
1243
+ function compile(fns) {
1244
+ return async (...args) => {
1245
+ for (const fn of fns) {
1246
+ if (!fn)
1247
+ continue;
1248
+ await fn(...args);
1249
+ }
1250
+ };
1251
+ }
1252
+
1253
+ // src/Router/registries/MiddlewareRegistry.ts
1254
+ class MiddlewareRegistry {
1255
+ middlewares = new LazyMap;
1256
+ add(m) {
1257
+ const resolved = MiddlewareRegistry.resolveRouteIds(m);
1258
+ if (resolved.isGlobal) {
1259
+ const existing = this.middlewares.get("*") ?? [];
1260
+ this.middlewares.set("*", [...existing, m.handler]);
1261
+ return;
1262
+ }
1263
+ for (const routeId of resolved.routeIds) {
1264
+ const existing = this.middlewares.get(routeId) ?? [];
1265
+ this.middlewares.set(routeId, [...existing, m.handler]);
1266
+ }
1267
+ }
1268
+ find(routeId) {
1269
+ const globals = this.middlewares.get("*") ?? [];
1270
+ const locals = this.middlewares.get(routeId) ?? [];
1271
+ return compile([...globals, ...locals]);
1272
+ }
1273
+ static resolveRouteIds(m) {
1274
+ if (m.useOn === "*")
1275
+ return { isGlobal: true };
1276
+ const targets = Array.isArray(m.useOn) ? m.useOn : [m.useOn];
1277
+ const routeIds = [];
1278
+ for (const target of targets) {
1279
+ if (target instanceof Route) {
1280
+ routeIds.push(target.id);
1281
+ } else if (target instanceof ControllerAbstract) {
1282
+ routeIds.push(...target.routeIds);
1283
+ }
1284
+ }
1285
+ return { isGlobal: false, routeIds };
1188
1286
  }
1189
- findRoute(req) {
1190
- const reqPath = req.urlObject.pathname;
1191
- const reqMethod = req.method;
1287
+ }
1288
+
1289
+ // src/Router/adapters/CorpusAdapter.ts
1290
+ class CorpusAdapter {
1291
+ routes = new Map;
1292
+ modelRegistry = new ModelRegistry;
1293
+ middlewareRegistry = new MiddlewareRegistry;
1294
+ addRoute(data) {
1295
+ this.checkPossibleCollision(data);
1296
+ this.routes.set(data.id, data);
1297
+ }
1298
+ addModel(route, model) {
1299
+ this.modelRegistry.add(route.method, route.endpoint, model);
1300
+ }
1301
+ addMiddleware(middleware) {
1302
+ this.middlewareRegistry.add(middleware);
1303
+ }
1304
+ find(req) {
1305
+ const method = req.method;
1306
+ const pathname = req.urlObject.pathname;
1307
+ const searchParams = req.urlObject.searchParams;
1192
1308
  let route = null;
1193
- for (const [endpoint, data] of this.routes.entries()) {
1194
- if (endpoint.includes(":")) {
1195
- if (isRegexMatch(reqPath, data.pattern)) {
1196
- route = data;
1197
- break;
1198
- }
1199
- if (this.hasLastPartParam(endpoint) && strIsEqual(endpoint.split("/").slice(0, -1).join("/"), reqPath, "lower")) {
1200
- route = data;
1201
- break;
1202
- }
1203
- } else if (strIsEqual(endpoint, reqPath)) {
1309
+ for (const data of this.routes.values()) {
1310
+ if (this.hasAnyParam(data.endpoint) && isRegexMatch(pathname, data.pattern)) {
1311
+ route = data;
1312
+ break;
1313
+ }
1314
+ if (this.hasLastPartParam(data.endpoint) && strIsEqual(this.removeLastParam(data.endpoint), pathname, "lower")) {
1315
+ route = data;
1316
+ break;
1317
+ }
1318
+ if (strIsEqual(data.endpoint, pathname)) {
1204
1319
  route = data;
1205
1320
  break;
1206
1321
  }
1207
1322
  }
1208
1323
  if (route === null) {
1209
- throw HttpError.notFound();
1324
+ throw CError.notFound();
1210
1325
  }
1211
- if (!strIsEqual(reqMethod, route.method, "upper")) {
1212
- throw HttpError.methodNotAllowed();
1326
+ if (!strIsEqual(method, route.method, "upper")) {
1327
+ throw CError.methodNotAllowed();
1213
1328
  }
1214
- return route;
1329
+ return {
1330
+ route,
1331
+ model: this.modelRegistry.find(route.id),
1332
+ middleware: this.middlewareRegistry.find(route.id),
1333
+ params: this.extractParams(pathname, route.endpoint),
1334
+ search: Object.fromEntries(searchParams)
1335
+ };
1215
1336
  }
1216
- checkPossibleCollision(r) {
1217
- const existingById = this.routes.get(r.id);
1218
- if (existingById) {
1219
- console.error(`\u26A0\uFE0F Collision: ${r.method} ${r.endpoint} clashes with ${existingById.method} ${existingById.endpoint}`);
1220
- }
1221
- for (const existing of this.routes.values()) {
1222
- if (existing.method !== r.method)
1337
+ list() {
1338
+ return Array.from(this.routes.values());
1339
+ }
1340
+ checkPossibleCollision(n) {
1341
+ const dupeMsg = (nId) => console.error(`Duplicate route detected. ${nId} has already been registered.`);
1342
+ const dynamicPatternMsg = (nId, oId) => console.error(`Ambiguous dynamic routes. ${nId} and ${oId} match the same URL patterns.`);
1343
+ const baseDupeMsg = (nId, oId) => console.error(`Dynamic route overlaps existing route. ${nId} \u2014 dropping the last param segment matches ${oId}.`);
1344
+ const shadowMsg = (nId, oId) => console.error(`Route shadowed by existing dynamic route. ${nId} will be unreachable \u2014 ${oId} captures the same URL space.`);
1345
+ const existing = this.routes.get(n.id);
1346
+ if (existing) {
1347
+ dupeMsg(n.id);
1348
+ return true;
1349
+ }
1350
+ const nHasAnyParam = this.hasAnyParam(n.endpoint);
1351
+ const nHasLastPartParam = this.hasLastPartParam(n.endpoint);
1352
+ for (const o of this.routes.values()) {
1353
+ if (o.method !== n.method)
1223
1354
  continue;
1224
- if (this.hasAnyParam(r.endpoint)) {
1225
- if (isRegexMatch(r.endpoint, existing.pattern)) {
1226
- console.error(`\u26A0\uFE0F Collision: ${r.method} ${r.endpoint} clashes with ${existing.method} ${existing.endpoint}`);
1355
+ if (nHasAnyParam) {
1356
+ if (isRegexMatch(n.endpoint, o.pattern) || isRegexMatch(o.endpoint, n.pattern)) {
1357
+ dynamicPatternMsg(n.id, o.id);
1358
+ return true;
1227
1359
  }
1228
- if (!this.hasAnyParam(existing.endpoint)) {
1229
- if (strIsEqual(this.removeLastParam(r.endpoint), existing.endpoint, "lower")) {
1230
- console.error(`\u26A0\uFE0F Param route ${r.method} ${r.endpoint} may conflict with static ${existing.method} ${existing.endpoint}`);
1231
- }
1232
- }
1233
- } else {
1234
- if (strIsEqual(r.endpoint, existing.endpoint, "lower")) {
1235
- console.error(`\u26A0\uFE0F Collision: ${r.method} ${r.endpoint} already exists`);
1360
+ }
1361
+ if (nHasLastPartParam) {
1362
+ if (isRegexMatch(this.removeLastParam(n.endpoint), o.pattern)) {
1363
+ baseDupeMsg(n.id, o.id);
1364
+ return true;
1236
1365
  }
1237
- if (this.hasLastPartParam(existing.endpoint)) {
1238
- if (strIsEqual(this.removeLastParam(r.endpoint), this.removeLastParam(existing.endpoint), "lower")) {
1239
- console.error(`\u26A0\uFE0F Static route ${r.method} ${r.endpoint} may be shadowed by param route ${existing.method} ${existing.endpoint}`);
1240
- }
1366
+ }
1367
+ const oHasLastPartParam = this.hasLastPartParam(o.endpoint);
1368
+ if (oHasLastPartParam) {
1369
+ if (isRegexMatch(n.endpoint, Route.makeRoutePattern(this.removeLastParam(o.endpoint)))) {
1370
+ shadowMsg(n.id, o.id);
1371
+ return true;
1241
1372
  }
1242
1373
  }
1243
1374
  }
1375
+ return false;
1376
+ }
1377
+ extractParams(pathname, endpoint) {
1378
+ const data = {};
1379
+ if (!this.hasAnyParam(endpoint))
1380
+ return data;
1381
+ const defParts = endpoint.split("/");
1382
+ const reqParts = pathname.split("/");
1383
+ for (const [i, defPart] of defParts.entries()) {
1384
+ const reqPart = reqParts[i];
1385
+ if (defPart.startsWith(":") && reqPart !== undefined) {
1386
+ data[defPart.slice(1)] = decodeURIComponent(reqPart);
1387
+ }
1388
+ }
1389
+ return data;
1244
1390
  }
1245
1391
  hasLastPartParam(endpoint) {
1246
1392
  if (!this.hasAnyParam(endpoint))
@@ -1252,94 +1398,83 @@ class Router {
1252
1398
  return endpoint.split("/").slice(0, -1).join("/");
1253
1399
  }
1254
1400
  hasAnyParam(endpoint) {
1255
- return endpoint.includes(":");
1256
- }
1257
- compile(fns) {
1258
- return async (...args) => {
1259
- for (const fn of fns) {
1260
- if (!fn)
1261
- continue;
1262
- await fn(...args);
1263
- }
1264
- };
1265
- }
1266
- intern(value, ...namespace) {
1267
- const key = namespace.join("::");
1268
- const existing = this.internFuncMap.get(key);
1269
- if (existing)
1270
- return existing;
1271
- this.internFuncMap.set(key, value);
1272
- return value;
1401
+ if (endpoint.includes("/:"))
1402
+ return true;
1403
+ if (!endpoint.includes(":"))
1404
+ return false;
1405
+ return endpoint.split("/").some((p) => p.startsWith(":"));
1273
1406
  }
1274
1407
  }
1275
1408
 
1276
- // src/utils/boolToString.ts
1277
- function boolToString(arg) {
1278
- return arg ? "true" : "false";
1279
- }
1280
-
1281
- // src/utils/isSomeArray.ts
1282
- function isSomeArray(arg) {
1283
- return arg !== undefined && Array.isArray(arg) && arg.length > 0 && arg.every((a) => a !== null && a !== undefined);
1284
- }
1285
-
1286
- // src/Cors/Cors.ts
1287
- class Cors {
1288
- opts;
1289
- constructor(opts) {
1290
- this.opts = opts;
1409
+ // src/Router/Router.ts
1410
+ class Router {
1411
+ constructor(adapter) {
1412
+ this._adapter = adapter ?? new CorpusAdapter;
1291
1413
  }
1292
- originKey = "Access-Control-Allow-Origin";
1293
- methodsKey = "Access-Control-Allow-Methods";
1294
- headersKey = "Access-Control-Allow-Headers";
1295
- credentialsKey = "Access-Control-Allow-Credentials";
1296
- getCorsHeaders(req, res) {
1297
- const reqOrigin = req.headers.get("origin") ?? "";
1298
- const { allowedOrigins, allowedMethods, allowedHeaders, credentials } = this.opts;
1299
- if (isSomeArray(allowedOrigins) && allowedOrigins.includes(reqOrigin)) {
1300
- res.headers.set(this.originKey, reqOrigin);
1301
- }
1302
- if (isSomeArray(allowedMethods)) {
1303
- res.headers.set(this.methodsKey, allowedMethods.join(", "));
1304
- }
1305
- if (isSomeArray(allowedHeaders)) {
1306
- res.headers.set(this.headersKey, allowedHeaders.join(", "));
1414
+ models = [];
1415
+ _adapter;
1416
+ cache = new WeakMap;
1417
+ checkPossibleCollision(n) {
1418
+ if (this._adapter instanceof CorpusAdapter) {
1419
+ return this._adapter.checkPossibleCollision(n);
1307
1420
  }
1308
- res.headers.set(this.credentialsKey, boolToString(credentials));
1309
- return res.headers;
1421
+ return false;
1310
1422
  }
1311
- apply(req, res) {
1312
- const headers = this.getCorsHeaders(req, res);
1313
- res.headers.innerCombine(headers);
1423
+ addModel(route, model) {
1424
+ this.models.push(model);
1425
+ this._adapter.addModel(route, model);
1426
+ }
1427
+ addMiddleware(middleware) {
1428
+ this._adapter.addMiddleware(middleware);
1429
+ }
1430
+ addRoute(r) {
1431
+ this._adapter.addRoute({
1432
+ id: r.id,
1433
+ endpoint: r.endpoint,
1434
+ method: r.method,
1435
+ handler: r.handler,
1436
+ pattern: r.pattern
1437
+ });
1438
+ }
1439
+ findRouteHandler(req) {
1440
+ const cached = this.cache.get(req);
1441
+ if (cached)
1442
+ return cached;
1443
+ const match = this._adapter.find(req);
1444
+ if (!match)
1445
+ throw CError.notFound();
1446
+ const ctx = Context.makeFromRequest(req);
1447
+ const handler = async () => {
1448
+ await match.middleware?.(ctx);
1449
+ await Context.appendParsedData(ctx, req, match.params, match.search, match.model);
1450
+ const res = await match.route.handler(ctx);
1451
+ return res instanceof CResponse ? res : new CResponse(res, {
1452
+ cookies: ctx.res.cookies,
1453
+ headers: ctx.res.headers,
1454
+ status: ctx.res.status,
1455
+ statusText: ctx.res.statusText
1456
+ });
1457
+ };
1458
+ this.cache.set(req, handler);
1459
+ return handler;
1460
+ }
1461
+ getRouteList() {
1462
+ return this._adapter.list().map((v) => [v.method, v.endpoint]);
1314
1463
  }
1315
1464
  }
1316
1465
 
1317
1466
  // src/Server/ServerAbstract.ts
1318
1467
  class ServerAbstract {
1319
- cors;
1468
+ opts;
1469
+ constructor(opts) {
1470
+ this.opts = opts;
1471
+ _routerStore.set(new Router(opts?.adapter));
1472
+ }
1320
1473
  get routes() {
1321
- return getRouterInstance().getRouteList();
1474
+ return _routerStore.get().getRouteList();
1322
1475
  }
1323
1476
  setGlobalPrefix(value) {
1324
- Config.set(_globalPrefixEnvKey, value);
1325
- }
1326
- setCors(cors) {
1327
- this.cors = new Cors(cors);
1328
- }
1329
- setOnError(handler) {
1330
- this.handleError = handler;
1331
- }
1332
- setOnNotFound(handler) {
1333
- this.handleNotFound = handler;
1334
- }
1335
- setOnBeforeListen(handler) {
1336
- this.handleBeforeListen = handler;
1337
- }
1338
- setOnBeforeClose(handler) {
1339
- this.handleBeforeClose = handler;
1340
- }
1341
- setOnAfterResponse(handler) {
1342
- this.handleAfterResponse = handler;
1477
+ _prefixStore.set(value);
1343
1478
  }
1344
1479
  async listen(port, hostname = "0.0.0.0") {
1345
1480
  try {
@@ -1358,10 +1493,11 @@ class ServerAbstract {
1358
1493
  }
1359
1494
  }
1360
1495
  async handle(request) {
1361
- const req = new HttpRequest(request);
1496
+ const req = new CRequest(request);
1362
1497
  let res = await this.getResponse(req);
1363
- if (this.cors !== undefined) {
1364
- this.cors.apply(req, res);
1498
+ const cors = _corsStore.get();
1499
+ if (cors !== null) {
1500
+ cors.apply(req, res);
1365
1501
  }
1366
1502
  if (this.handleAfterResponse) {
1367
1503
  res = await this.handleAfterResponse(res);
@@ -1371,12 +1507,12 @@ class ServerAbstract {
1371
1507
  async getResponse(req) {
1372
1508
  try {
1373
1509
  if (req.isPreflight) {
1374
- return new HttpResponse("Departed");
1510
+ return new CResponse("Departed");
1375
1511
  }
1376
- const handler = getRouterInstance().getRouteHandler(req);
1512
+ const handler = _routerStore.get().findRouteHandler(req);
1377
1513
  return await handler();
1378
1514
  } catch (err) {
1379
- if (err instanceof HttpError) {
1515
+ if (err instanceof CError) {
1380
1516
  if (err.isStatusOf(Status.NOT_FOUND)) {
1381
1517
  return await this.handleNotFound(req);
1382
1518
  }
@@ -1388,39 +1524,56 @@ class ServerAbstract {
1388
1524
  }
1389
1525
  }
1390
1526
  handleBeforeListen;
1527
+ setOnBeforeListen(handler) {
1528
+ this.handleBeforeListen = handler;
1529
+ }
1530
+ defaultOnBeforeListen = undefined;
1391
1531
  handleBeforeClose;
1532
+ setOnBeforeClose(handler) {
1533
+ this.handleBeforeClose = handler;
1534
+ }
1535
+ defaultOnBeforeClose = undefined;
1392
1536
  handleAfterResponse;
1393
- handleError = async (err) => {
1537
+ setOnAfterResponse(handler) {
1538
+ this.handleAfterResponse = handler;
1539
+ }
1540
+ defaultOnAfterResponse = undefined;
1541
+ handleError = (err) => this.defaultErrorHandler(err);
1542
+ setOnError(handler) {
1543
+ this.handleError = handler;
1544
+ }
1545
+ defaultErrorHandler = (err) => {
1394
1546
  if (!(err instanceof Error)) {
1395
- return new HttpResponse({ error: err, message: "Unknown" }, { status: Status.INTERNAL_SERVER_ERROR });
1547
+ return new CResponse({ error: err, message: "Unknown" }, { status: Status.INTERNAL_SERVER_ERROR });
1396
1548
  }
1397
- if (err instanceof HttpError) {
1549
+ if (err instanceof CError) {
1398
1550
  return err.toResponse();
1399
1551
  }
1400
- return new HttpResponse({ error: err, message: err.message }, { status: Status.INTERNAL_SERVER_ERROR });
1552
+ return new CResponse({ error: err, message: err.message }, { status: Status.INTERNAL_SERVER_ERROR });
1401
1553
  };
1402
- handleNotFound = async (req) => {
1403
- return new HttpResponse({ error: true, message: `${req.method} on ${req.url} does not exist.` }, { status: Status.NOT_FOUND });
1554
+ handleNotFound = (req) => this.defaultNotFoundHandler(req);
1555
+ setOnNotFound(handler) {
1556
+ this.handleNotFound = handler;
1557
+ }
1558
+ defaultNotFoundHandler = (req) => {
1559
+ return new CResponse({ error: true, message: `${req.method} on ${req.url} does not exist.` }, { status: Status.NOT_FOUND });
1404
1560
  };
1405
- handleMethodNotAllowed = async (req) => {
1406
- return new HttpResponse({ error: `${req.method} does not exist.` }, { status: Status.METHOD_NOT_ALLOWED });
1561
+ handleMethodNotAllowed = (req) => this.defaultMethodNotFoundHandler(req);
1562
+ defaultMethodNotFoundHandler = (req) => {
1563
+ return new CResponse({ error: `${req.method} ${req.url} does not exist.` }, { status: Status.METHOD_NOT_ALLOWED });
1407
1564
  };
1408
1565
  }
1409
1566
 
1410
1567
  // src/Server/ServerUsingBun.ts
1411
1568
  class ServerUsingBun extends ServerAbstract {
1412
1569
  app;
1413
- constructor() {
1414
- super();
1415
- setRouterInstance(new Router);
1416
- }
1417
- serve(options) {
1418
- this.app = this.createApp(options);
1570
+ serve(args) {
1571
+ this.app = this.createApp(args);
1419
1572
  }
1420
1573
  async close() {
1421
1574
  await this.handleBeforeClose?.();
1422
1575
  console.log("Closing...");
1423
- await this.app?.stop();
1576
+ await this.app?.stop(true);
1424
1577
  if (Config.nodeEnv !== "test") {
1425
1578
  process.exit(0);
1426
1579
  }
@@ -1429,7 +1582,9 @@ class ServerUsingBun extends ServerAbstract {
1429
1582
  return Bun.serve({
1430
1583
  port: options.port,
1431
1584
  hostname: options.hostname,
1432
- fetch: options.fetch
1585
+ fetch: options.fetch,
1586
+ idleTimeout: this.opts?.idleTimeout,
1587
+ tls: this.opts?.tls
1433
1588
  });
1434
1589
  }
1435
1590
  }
@@ -1437,41 +1592,371 @@ class ServerUsingBun extends ServerAbstract {
1437
1592
  // src/Server/Server.ts
1438
1593
  class Server extends ServerUsingBun {
1439
1594
  }
1440
- // src/index.ts
1441
- var RouterInstance;
1442
- function getRouterInstance() {
1443
- if (!RouterInstance) {
1444
- console.error("Router instance is not set. Please instantiate your Server before your routes.");
1445
- process.exit(1);
1595
+ // src/X.ts
1596
+ var exports_X = {};
1597
+ __export(exports_X, {
1598
+ Repository: () => RepositoryAbstract,
1599
+ Parser: () => Parser,
1600
+ MemoiristAdapter: () => MemoiristAdapter,
1601
+ File: () => XFile,
1602
+ Cors: () => Cors
1603
+ });
1604
+ // src/utils/boolToString.ts
1605
+ function boolToString(arg) {
1606
+ return arg ? "true" : "false";
1607
+ }
1608
+
1609
+ // src/utils/isSomeArray.ts
1610
+ function isSomeArray(arg) {
1611
+ return arg !== undefined && Array.isArray(arg) && arg.length > 0 && arg.every((a) => a !== null && a !== undefined);
1612
+ }
1613
+
1614
+ // src/Cors/Cors.ts
1615
+ class Cors {
1616
+ opts;
1617
+ constructor(opts) {
1618
+ this.opts = opts;
1619
+ if (opts === undefined) {
1620
+ _corsStore.set(null);
1621
+ } else {
1622
+ _corsStore.set(this);
1623
+ }
1624
+ }
1625
+ originKey = "Access-Control-Allow-Origin";
1626
+ methodsKey = "Access-Control-Allow-Methods";
1627
+ headersKey = "Access-Control-Allow-Headers";
1628
+ credentialsKey = "Access-Control-Allow-Credentials";
1629
+ getCorsHeaders(req, res) {
1630
+ const reqOrigin = req.headers.get("origin") ?? "";
1631
+ const { allowedOrigins, allowedMethods, allowedHeaders, credentials } = this.opts ?? {};
1632
+ if (isSomeArray(allowedOrigins) && allowedOrigins.includes(reqOrigin)) {
1633
+ res.headers.set(this.originKey, reqOrigin);
1634
+ }
1635
+ if (isSomeArray(allowedMethods)) {
1636
+ res.headers.set(this.methodsKey, allowedMethods.join(", "));
1637
+ }
1638
+ if (isSomeArray(allowedHeaders)) {
1639
+ res.headers.set(this.headersKey, allowedHeaders.join(", "));
1640
+ }
1641
+ res.headers.set(this.credentialsKey, boolToString(credentials));
1642
+ return res.headers;
1643
+ }
1644
+ apply(req, res) {
1645
+ const headers = this.getCorsHeaders(req, res);
1646
+ res.headers.innerCombine(headers);
1647
+ }
1648
+ }
1649
+ // src/Repository/RepositoryAbstract.ts
1650
+ class RepositoryAbstract {
1651
+ db;
1652
+ constructor(db) {
1653
+ this.db = db;
1654
+ }
1655
+ }
1656
+ // node_modules/memoirist/dist/bun/index.js
1657
+ var Y = (v, b) => {
1658
+ let A = b?.length ? {} : null;
1659
+ if (A)
1660
+ for (let Q of b)
1661
+ A[Q.part.charCodeAt(0)] = Q;
1662
+ return { part: v, store: null, inert: A, params: null, wildcardStore: null };
1663
+ };
1664
+ var k = (v, b) => ({ ...v, part: b });
1665
+ var T = (v) => ({ name: v, store: null, inert: null });
1666
+
1667
+ class _ {
1668
+ config;
1669
+ root = {};
1670
+ history = [];
1671
+ deferred = [];
1672
+ constructor(v = {}) {
1673
+ this.config = v;
1674
+ if (v.lazy)
1675
+ this.find = this.lazyFind;
1676
+ if (v.onParam && !Array.isArray(v.onParam))
1677
+ this.config.onParam = [this.config.onParam];
1678
+ }
1679
+ static regex = { static: /:.+?(?=\/|$)/, params: /:.+?(?=\/|$)/g, optionalParams: /(\/:\w+\?)/g };
1680
+ lazyFind = (v, b) => {
1681
+ if (!this.config.lazy)
1682
+ return this.find;
1683
+ return this.build(), this.find(v, b);
1684
+ };
1685
+ build() {
1686
+ if (!this.config.lazy)
1687
+ return;
1688
+ for (let [v, b, A] of this.deferred)
1689
+ this.add(v, b, A, { lazy: false, ignoreHistory: true });
1690
+ this.deferred = [], this.find = (v, b) => {
1691
+ let A = this.root[v];
1692
+ if (!A)
1693
+ return null;
1694
+ return $(b, b.length, A, 0, this.config.onParam);
1695
+ };
1696
+ }
1697
+ add(v, b, A, { ignoreError: Q = false, ignoreHistory: O = false, lazy: V = this.config.lazy } = {}) {
1698
+ if (V)
1699
+ return this.find = this.lazyFind, this.deferred.push([v, b, A]), A;
1700
+ if (typeof b !== "string")
1701
+ throw new TypeError("Route path must be a string");
1702
+ if (b === "")
1703
+ b = "/";
1704
+ else if (b[0] !== "/")
1705
+ b = `/${b}`;
1706
+ let X = b[b.length - 1] === "*", J = b.match(_.regex.optionalParams);
1707
+ if (J) {
1708
+ let F = b.replaceAll("?", "");
1709
+ this.add(v, F, A, { ignoreError: Q, ignoreHistory: O, lazy: V });
1710
+ for (let B = 0;B < J.length; B++) {
1711
+ let D = b.replace(J[B], "");
1712
+ this.add(v, D, A, { ignoreError: true, ignoreHistory: O, lazy: V });
1713
+ }
1714
+ return A;
1715
+ }
1716
+ if (J)
1717
+ b = b.replaceAll("?", "");
1718
+ if (this.history.find(([F, B, D]) => F === v && B === b))
1719
+ return A;
1720
+ if (X || J && b.charCodeAt(b.length - 1) === 63)
1721
+ b = b.slice(0, -1);
1722
+ if (!O)
1723
+ this.history.push([v, b, A]);
1724
+ let K = b.split(_.regex.static), G = b.match(_.regex.params) || [];
1725
+ if (K[K.length - 1] === "")
1726
+ K.pop();
1727
+ let q;
1728
+ if (!this.root[v])
1729
+ q = this.root[v] = Y("/");
1730
+ else
1731
+ q = this.root[v];
1732
+ let U = 0;
1733
+ for (let F = 0;F < K.length; ++F) {
1734
+ let B = K[F];
1735
+ if (F > 0) {
1736
+ let D = G[U++].slice(1);
1737
+ if (q.params === null)
1738
+ q.params = T(D);
1739
+ else if (q.params.name !== D)
1740
+ if (Q)
1741
+ return A;
1742
+ else
1743
+ 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`);
1744
+ let S = q.params;
1745
+ if (S.inert === null) {
1746
+ q = S.inert = Y(B);
1747
+ continue;
1748
+ }
1749
+ q = S.inert;
1750
+ }
1751
+ for (let D = 0;; ) {
1752
+ if (D === B.length) {
1753
+ if (D < q.part.length) {
1754
+ let S = k(q, q.part.slice(D));
1755
+ Object.assign(q, Y(B, [S]));
1756
+ }
1757
+ break;
1758
+ }
1759
+ if (D === q.part.length) {
1760
+ if (q.inert === null)
1761
+ q.inert = {};
1762
+ let S = q.inert[B.charCodeAt(D)];
1763
+ if (S) {
1764
+ q = S, B = B.slice(D), D = 0;
1765
+ continue;
1766
+ }
1767
+ let Z = Y(B.slice(D));
1768
+ q.inert[B.charCodeAt(D)] = Z, q = Z;
1769
+ break;
1770
+ }
1771
+ if (B[D] !== q.part[D]) {
1772
+ let S = k(q, q.part.slice(D)), Z = Y(B.slice(D));
1773
+ Object.assign(q, Y(q.part.slice(0, D), [S, Z])), q = Z;
1774
+ break;
1775
+ }
1776
+ ++D;
1777
+ }
1778
+ }
1779
+ if (U < G.length) {
1780
+ let B = G[U].slice(1);
1781
+ if (q.params === null)
1782
+ q.params = T(B);
1783
+ else if (q.params.name !== B)
1784
+ if (Q)
1785
+ return A;
1786
+ else
1787
+ 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`);
1788
+ if (q.params.store === null)
1789
+ q.params.store = A;
1790
+ return q.params.store;
1791
+ }
1792
+ if (X) {
1793
+ if (q.wildcardStore === null)
1794
+ q.wildcardStore = A;
1795
+ return q.wildcardStore;
1796
+ }
1797
+ if (q.store === null)
1798
+ q.store = A;
1799
+ return q.store;
1800
+ }
1801
+ find(v, b) {
1802
+ let A = this.root[v];
1803
+ if (!A)
1804
+ return null;
1805
+ return $(b, b.length, A, 0, this.config.onParam);
1446
1806
  }
1447
- return RouterInstance;
1448
1807
  }
1449
- function setRouterInstance(router) {
1450
- RouterInstance = router;
1808
+ var $ = (v, b, A, Q, O) => {
1809
+ let V = A.part, X = V.length, J = Q + X;
1810
+ if (X > 1) {
1811
+ if (J > b)
1812
+ return null;
1813
+ if (X < 15) {
1814
+ for (let K = 1, G = Q + 1;K < X; ++K, ++G)
1815
+ if (V.charCodeAt(K) !== v.charCodeAt(G))
1816
+ return null;
1817
+ } else if (v.slice(Q, J) !== V)
1818
+ return null;
1819
+ }
1820
+ if (J === b) {
1821
+ if (A.store !== null)
1822
+ return { store: A.store, params: {} };
1823
+ if (A.wildcardStore !== null)
1824
+ return { store: A.wildcardStore, params: { "*": "" } };
1825
+ return null;
1826
+ }
1827
+ if (A.inert !== null) {
1828
+ let K = A.inert[v.charCodeAt(J)];
1829
+ if (K !== undefined) {
1830
+ let G = $(v, b, K, J, O);
1831
+ if (G !== null)
1832
+ return G;
1833
+ }
1834
+ }
1835
+ if (A.params !== null) {
1836
+ let { store: K, name: G, inert: q } = A.params, U = v.indexOf("/", J);
1837
+ if (U !== J) {
1838
+ if (U === -1 || U >= b) {
1839
+ if (K !== null) {
1840
+ let F = {};
1841
+ if (F[G] = v.substring(J, b), O)
1842
+ for (let B = 0;B < O.length; B++) {
1843
+ let D = O[B](F[G], G);
1844
+ if (D !== undefined)
1845
+ F[G] = D;
1846
+ }
1847
+ return { store: K, params: F };
1848
+ }
1849
+ } else if (q !== null) {
1850
+ let F = $(v, b, q, U, O);
1851
+ if (F !== null) {
1852
+ if (F.params[G] = v.substring(J, U), O)
1853
+ for (let B = 0;B < O.length; B++) {
1854
+ let D = O[B](F.params[G], G);
1855
+ if (D !== undefined)
1856
+ F.params[G] = D;
1857
+ }
1858
+ return F;
1859
+ }
1860
+ }
1861
+ }
1862
+ }
1863
+ if (A.wildcardStore !== null)
1864
+ return { store: A.wildcardStore, params: { "*": v.substring(J, b) } };
1865
+ return null;
1866
+ };
1867
+ var w = _;
1868
+
1869
+ // src/Router/adapters/MemoiristAdapter.ts
1870
+ class MemoiristAdapter {
1871
+ router = new w;
1872
+ pendingMiddlewares = new Map;
1873
+ find(req) {
1874
+ const method = req.method;
1875
+ const pathname = req.urlObject.pathname;
1876
+ const searchParams = req.urlObject.searchParams;
1877
+ const result = this.router.find(method, pathname);
1878
+ if (!result)
1879
+ return null;
1880
+ return {
1881
+ route: result.store.route,
1882
+ model: result.store.model,
1883
+ params: result.params,
1884
+ search: Object.fromEntries(searchParams),
1885
+ middleware: compile(result.store.middlewares ?? [])
1886
+ };
1887
+ }
1888
+ list() {
1889
+ return this.router.history.map((v) => v[2].route);
1890
+ }
1891
+ addRoute(data) {
1892
+ this.router.add(data.method, data.endpoint, { route: data });
1893
+ const pending = this.pendingMiddlewares.get(data.id);
1894
+ if (pending) {
1895
+ const store = this.router.find(data.method, data.endpoint)?.store;
1896
+ if (store)
1897
+ store.middlewares = pending;
1898
+ this.pendingMiddlewares.delete(data.id);
1899
+ }
1900
+ }
1901
+ addModel(route, model) {
1902
+ const result = this.router.find(route.method, route.endpoint);
1903
+ if (!result)
1904
+ return;
1905
+ result.store.model = ModelRegistry.toRouterModelData(model);
1906
+ }
1907
+ addMiddleware(middleware) {
1908
+ const resolved = MiddlewareRegistry.resolveRouteIds(middleware);
1909
+ if (resolved.isGlobal) {
1910
+ for (const [, , store] of this.router.history) {
1911
+ store.middlewares = [...store.middlewares ?? [], middleware.handler];
1912
+ }
1913
+ return;
1914
+ }
1915
+ for (const routeId of resolved.routeIds) {
1916
+ const [method, endpoint] = routeId.split(" ", 2);
1917
+ const result = this.router.find(method, endpoint);
1918
+ if (result) {
1919
+ result.store.middlewares = [
1920
+ ...result.store.middlewares ?? [],
1921
+ middleware.handler
1922
+ ];
1923
+ } else {
1924
+ const pending = this.pendingMiddlewares.get(routeId) ?? [];
1925
+ this.pendingMiddlewares.set(routeId, [...pending, middleware.handler]);
1926
+ }
1927
+ }
1928
+ }
1451
1929
  }
1452
- var src_default = exports_exports;
1930
+ // src/index.ts
1931
+ var _prefixStore = new GlobalPrefixStore;
1932
+ var _routerStore = new GlobalRouterStore;
1933
+ var _corsStore = new GlobalCorsStore;
1453
1934
  export {
1454
- setRouterInstance,
1455
- getRouterInstance,
1456
- src_default as default,
1935
+ exports_C as default,
1936
+ _routerStore,
1937
+ _prefixStore,
1938
+ _corsStore,
1939
+ exports_X as X,
1457
1940
  Status,
1458
1941
  StaticRoute,
1459
1942
  Server,
1460
1943
  Route,
1461
- HttpResponse as Response,
1462
- HttpRequest as Request,
1944
+ CResponse as Response,
1945
+ CRequest as Request,
1463
1946
  RepositoryAbstract as Repository,
1464
1947
  Parser,
1465
1948
  Middleware,
1466
1949
  Method,
1467
- HttpHeaders as Headers,
1468
- FileWalker,
1469
- HttpError as Error,
1470
- DefaultStatusTexts,
1950
+ MemoiristAdapter,
1951
+ CHeaders as Headers,
1952
+ XFile as File,
1953
+ exports_X as Extra,
1954
+ CError as Error,
1955
+ Cors,
1471
1956
  Cookies,
1472
1957
  ControllerAbstract as Controller,
1473
1958
  Context,
1474
1959
  Config,
1475
1960
  CommonHeaders,
1476
- exports_exports as C
1961
+ exports_C as C
1477
1962
  };