@ozanarslan/corpus 0.1.5 → 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/README.md +24 -25
- package/dist/index.cjs +657 -430
- package/dist/index.d.ts +333 -202
- package/dist/index.js +657 -430
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -41,23 +41,24 @@ class GlobalRouterStore extends StoreAbstract {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
// src/
|
|
45
|
-
|
|
46
|
-
|
|
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, {
|
|
47
52
|
Status: () => Status,
|
|
48
53
|
StaticRoute: () => StaticRoute,
|
|
49
54
|
Server: () => Server,
|
|
50
55
|
Route: () => Route,
|
|
51
|
-
Response: () =>
|
|
52
|
-
Request: () =>
|
|
53
|
-
Repository: () => RepositoryAbstract,
|
|
54
|
-
Parser: () => Parser,
|
|
56
|
+
Response: () => CResponse,
|
|
57
|
+
Request: () => CRequest,
|
|
55
58
|
Middleware: () => Middleware,
|
|
56
59
|
Method: () => Method,
|
|
57
|
-
Headers: () =>
|
|
58
|
-
|
|
59
|
-
Error: () => HttpError,
|
|
60
|
-
DefaultStatusTexts: () => DefaultStatusTexts,
|
|
60
|
+
Headers: () => CHeaders,
|
|
61
|
+
Error: () => CError,
|
|
61
62
|
Cookies: () => Cookies,
|
|
62
63
|
Controller: () => ControllerAbstract,
|
|
63
64
|
Context: () => Context,
|
|
@@ -133,7 +134,7 @@ class Config {
|
|
|
133
134
|
this.env[key] = value;
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
|
-
// src/
|
|
137
|
+
// src/CResponse/enums/Status.ts
|
|
137
138
|
var Status = {
|
|
138
139
|
CONTINUE: 100,
|
|
139
140
|
SWITCHING_PROTOCOLS: 101,
|
|
@@ -199,7 +200,7 @@ var Status = {
|
|
|
199
200
|
NETWORK_AUTHENTICATION_REQUIRED: 511
|
|
200
201
|
};
|
|
201
202
|
|
|
202
|
-
// src/
|
|
203
|
+
// src/CResponse/enums/DefaultStatusTexts.ts
|
|
203
204
|
var DefaultStatusTexts = {
|
|
204
205
|
[Status.OK]: "OK",
|
|
205
206
|
[Status.CREATED]: "Created",
|
|
@@ -216,11 +217,12 @@ var DefaultStatusTexts = {
|
|
|
216
217
|
[Status.INTERNAL_SERVER_ERROR]: "Internal Server Error"
|
|
217
218
|
};
|
|
218
219
|
|
|
219
|
-
// src/
|
|
220
|
+
// src/CHeaders/enums/CommonHeaders.ts
|
|
220
221
|
var CommonHeaders = {
|
|
221
222
|
CacheControl: "Cache-Control",
|
|
222
223
|
ContentType: "Content-Type",
|
|
223
224
|
ContentLength: "Content-Length",
|
|
225
|
+
ContentDisposition: "Content-Disposition",
|
|
224
226
|
AcceptEncoding: "Accept-Encoding",
|
|
225
227
|
Accept: "Accept",
|
|
226
228
|
Authorization: "Authorization",
|
|
@@ -310,8 +312,8 @@ class CookiesUsingBun extends CookiesAbstract {
|
|
|
310
312
|
class Cookies extends CookiesUsingBun {
|
|
311
313
|
}
|
|
312
314
|
|
|
313
|
-
// src/
|
|
314
|
-
class
|
|
315
|
+
// src/CHeaders/CHeaders.ts
|
|
316
|
+
class CHeaders extends Headers {
|
|
315
317
|
constructor(init) {
|
|
316
318
|
super(init);
|
|
317
319
|
}
|
|
@@ -341,7 +343,7 @@ class HttpHeaders extends Headers {
|
|
|
341
343
|
return target;
|
|
342
344
|
}
|
|
343
345
|
innerCombine(source) {
|
|
344
|
-
|
|
346
|
+
CHeaders.combine(source, this);
|
|
345
347
|
}
|
|
346
348
|
setMany(init) {
|
|
347
349
|
const entries = Array.isArray(init) ? init : Object.entries(init);
|
|
@@ -352,7 +354,7 @@ class HttpHeaders extends Headers {
|
|
|
352
354
|
}
|
|
353
355
|
}
|
|
354
356
|
static findHeaderInInit(init, name) {
|
|
355
|
-
if (init instanceof
|
|
357
|
+
if (init instanceof CHeaders || init instanceof Headers) {
|
|
356
358
|
return init.get(name);
|
|
357
359
|
} else if (Array.isArray(init)) {
|
|
358
360
|
return init.find((entry) => entry[0] === name)?.[1] ?? null;
|
|
@@ -362,19 +364,139 @@ class HttpHeaders extends Headers {
|
|
|
362
364
|
}
|
|
363
365
|
}
|
|
364
366
|
|
|
365
|
-
// src/
|
|
366
|
-
|
|
367
|
-
|
|
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;
|
|
368
489
|
init;
|
|
369
|
-
constructor(
|
|
370
|
-
this.
|
|
490
|
+
constructor(data, init) {
|
|
491
|
+
this.data = data;
|
|
371
492
|
this.init = init;
|
|
372
|
-
this.cookies = this.
|
|
373
|
-
this.headers = this.
|
|
374
|
-
this.body = this.
|
|
375
|
-
this.status = this.
|
|
493
|
+
this.cookies = this.resolveCookies();
|
|
494
|
+
this.headers = this.resolveHeaders();
|
|
495
|
+
this.body = this.resolveBody();
|
|
496
|
+
this.status = this.resolveStatus();
|
|
376
497
|
this.statusText = this.getDefaultStatusText();
|
|
377
498
|
}
|
|
499
|
+
body;
|
|
378
500
|
headers;
|
|
379
501
|
status;
|
|
380
502
|
statusText;
|
|
@@ -386,11 +508,126 @@ class HttpResponse {
|
|
|
386
508
|
headers: this.headers
|
|
387
509
|
});
|
|
388
510
|
}
|
|
389
|
-
|
|
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() {
|
|
390
627
|
return new Cookies(this.init?.cookies);
|
|
391
628
|
}
|
|
392
|
-
|
|
393
|
-
const headers = new
|
|
629
|
+
resolveHeaders() {
|
|
630
|
+
const headers = new CHeaders(this.init?.headers);
|
|
394
631
|
const setCookieHeaders = this.cookies.toSetCookieHeaders();
|
|
395
632
|
if (setCookieHeaders.length > 0) {
|
|
396
633
|
for (const header of setCookieHeaders) {
|
|
@@ -399,7 +636,7 @@ class HttpResponse {
|
|
|
399
636
|
}
|
|
400
637
|
return headers;
|
|
401
638
|
}
|
|
402
|
-
|
|
639
|
+
resolveStatus() {
|
|
403
640
|
if (this.init?.status)
|
|
404
641
|
return this.init.status;
|
|
405
642
|
if (this.headers.has(CommonHeaders.Location)) {
|
|
@@ -412,58 +649,53 @@ class HttpResponse {
|
|
|
412
649
|
this.headers.set(CommonHeaders.ContentType, value);
|
|
413
650
|
}
|
|
414
651
|
}
|
|
415
|
-
|
|
416
|
-
if (this.
|
|
652
|
+
resolveBody() {
|
|
653
|
+
if (isNil(this.data)) {
|
|
417
654
|
this.setContentType("text/plain");
|
|
418
655
|
return "";
|
|
419
656
|
}
|
|
420
|
-
if (
|
|
657
|
+
if (isPrimitive(this.data)) {
|
|
421
658
|
this.setContentType("text/plain");
|
|
422
|
-
return String(this.
|
|
659
|
+
return String(this.data);
|
|
660
|
+
}
|
|
661
|
+
if (this.data instanceof ArrayBuffer) {
|
|
662
|
+
this.setContentType("application/octet-stream");
|
|
663
|
+
return this.data;
|
|
423
664
|
}
|
|
424
|
-
if (this.
|
|
425
|
-
|
|
665
|
+
if (this.data instanceof Blob) {
|
|
666
|
+
if (this.data.type)
|
|
667
|
+
this.setContentType(this.data.type);
|
|
668
|
+
return this.data;
|
|
426
669
|
}
|
|
427
|
-
if (this.
|
|
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;
|
|
677
|
+
}
|
|
678
|
+
if (this.data instanceof ReadableStream) {
|
|
679
|
+
return this.data;
|
|
680
|
+
}
|
|
681
|
+
if (this.data instanceof Date) {
|
|
428
682
|
this.setContentType("text/plain");
|
|
429
|
-
return this.
|
|
683
|
+
return this.data.toISOString();
|
|
430
684
|
}
|
|
431
|
-
if (Array.isArray(this.
|
|
685
|
+
if (Array.isArray(this.data) || isPlainObject(this.data)) {
|
|
432
686
|
this.setContentType("application/json");
|
|
433
|
-
return JSON.stringify(this.
|
|
687
|
+
return JSON.stringify(this.data);
|
|
434
688
|
}
|
|
435
689
|
this.setContentType("text/plain");
|
|
436
|
-
return String(this.
|
|
690
|
+
return String(this.data);
|
|
437
691
|
}
|
|
438
692
|
getDefaultStatusText() {
|
|
439
693
|
const key = this.status;
|
|
440
694
|
return DefaultStatusTexts[key] ?? "Unknown";
|
|
441
695
|
}
|
|
442
|
-
static redirect(url, init) {
|
|
443
|
-
const res = new HttpResponse(undefined, {
|
|
444
|
-
...init,
|
|
445
|
-
status: init?.status ?? Status.FOUND,
|
|
446
|
-
statusText: init?.statusText ?? DefaultStatusTexts[Status.FOUND]
|
|
447
|
-
});
|
|
448
|
-
const urlString = url instanceof URL ? url.toString() : url;
|
|
449
|
-
res.headers.set(CommonHeaders.Location, urlString);
|
|
450
|
-
return res;
|
|
451
|
-
}
|
|
452
|
-
static permanentRedirect(url, init) {
|
|
453
|
-
return this.redirect(url, {
|
|
454
|
-
...init,
|
|
455
|
-
status: Status.MOVED_PERMANENTLY
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
static temporaryRedirect(url, init) {
|
|
459
|
-
return this.redirect(url, { ...init, status: Status.TEMPORARY_REDIRECT });
|
|
460
|
-
}
|
|
461
|
-
static seeOther(url, init) {
|
|
462
|
-
return this.redirect(url, { ...init, status: Status.SEE_OTHER });
|
|
463
|
-
}
|
|
464
696
|
}
|
|
465
697
|
|
|
466
|
-
// src/
|
|
698
|
+
// src/CRequest/enums/Method.ts
|
|
467
699
|
var Method = {
|
|
468
700
|
GET: "GET",
|
|
469
701
|
POST: "POST",
|
|
@@ -476,45 +708,6 @@ var Method = {
|
|
|
476
708
|
TRACE: "TRACE"
|
|
477
709
|
};
|
|
478
710
|
|
|
479
|
-
// src/Error/HttpError.ts
|
|
480
|
-
class HttpError extends Error {
|
|
481
|
-
message;
|
|
482
|
-
status;
|
|
483
|
-
data;
|
|
484
|
-
constructor(message, status, data) {
|
|
485
|
-
super(message);
|
|
486
|
-
this.message = message;
|
|
487
|
-
this.status = status;
|
|
488
|
-
this.data = data;
|
|
489
|
-
}
|
|
490
|
-
toResponse() {
|
|
491
|
-
return new HttpResponse(this.data ? { error: this.data, message: this.message } : { error: true, message: this.message }, { status: this.status });
|
|
492
|
-
}
|
|
493
|
-
isStatusOf(status) {
|
|
494
|
-
return this.status === status;
|
|
495
|
-
}
|
|
496
|
-
static internalServerError(msg) {
|
|
497
|
-
const status = Status.INTERNAL_SERVER_ERROR;
|
|
498
|
-
return new this(msg ?? status.toString(), status);
|
|
499
|
-
}
|
|
500
|
-
static badRequest(msg) {
|
|
501
|
-
const status = Status.BAD_REQUEST;
|
|
502
|
-
return new this(msg ?? status.toString(), status);
|
|
503
|
-
}
|
|
504
|
-
static notFound(msg) {
|
|
505
|
-
const status = Status.NOT_FOUND;
|
|
506
|
-
return new this(msg ?? status.toString(), status);
|
|
507
|
-
}
|
|
508
|
-
static methodNotAllowed(msg) {
|
|
509
|
-
const status = Status.METHOD_NOT_ALLOWED;
|
|
510
|
-
return new this(msg ?? status.toString(), status);
|
|
511
|
-
}
|
|
512
|
-
static unprocessableEntity(msg) {
|
|
513
|
-
const status = Status.UNPROCESSABLE_ENTITY;
|
|
514
|
-
return new this(msg ?? status.toString(), status);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
|
|
518
711
|
// src/utils/arrIncludes.ts
|
|
519
712
|
function arrIncludes(input, array) {
|
|
520
713
|
return array.includes(input);
|
|
@@ -543,7 +736,7 @@ class Parser {
|
|
|
543
736
|
const result = await validate(data);
|
|
544
737
|
if (result.issues !== undefined) {
|
|
545
738
|
const msg = this.issuesToErrorMessage(result.issues);
|
|
546
|
-
throw
|
|
739
|
+
throw CError.unprocessableEntity(msg);
|
|
547
740
|
}
|
|
548
741
|
return result.value;
|
|
549
742
|
}
|
|
@@ -559,14 +752,14 @@ class Parser {
|
|
|
559
752
|
}).join(`
|
|
560
753
|
`);
|
|
561
754
|
}
|
|
562
|
-
static async
|
|
755
|
+
static async parseUrlData(params, validate) {
|
|
563
756
|
const data = {};
|
|
564
|
-
for (const [key, value] of
|
|
565
|
-
data[key] =
|
|
757
|
+
for (const [key, value] of Object.entries(params)) {
|
|
758
|
+
data[key] = decodeURIComponent(value);
|
|
566
759
|
}
|
|
567
760
|
return await this.parse(data, validate);
|
|
568
761
|
}
|
|
569
|
-
static async
|
|
762
|
+
static async parseBody(r, validate) {
|
|
570
763
|
let data;
|
|
571
764
|
const empty = {};
|
|
572
765
|
const input = r instanceof Request ? r : r instanceof Response ? r : r.response;
|
|
@@ -593,7 +786,7 @@ class Parser {
|
|
|
593
786
|
case "image":
|
|
594
787
|
case "audio":
|
|
595
788
|
case "video":
|
|
596
|
-
throw new
|
|
789
|
+
throw new CError("unprocessable.contentType", Status.UNPROCESSABLE_ENTITY);
|
|
597
790
|
case "no-body-allowed":
|
|
598
791
|
default:
|
|
599
792
|
return empty;
|
|
@@ -605,23 +798,6 @@ class Parser {
|
|
|
605
798
|
throw err;
|
|
606
799
|
}
|
|
607
800
|
}
|
|
608
|
-
static async getParams(endpoint, url, validate) {
|
|
609
|
-
const data = {};
|
|
610
|
-
if (!endpoint.includes(":")) {
|
|
611
|
-
return data;
|
|
612
|
-
}
|
|
613
|
-
const defParts = endpoint.split("/");
|
|
614
|
-
const reqParts = url.pathname.split("/");
|
|
615
|
-
for (const [i, defPart] of defParts.entries()) {
|
|
616
|
-
const reqPart = reqParts[i];
|
|
617
|
-
if (defPart.startsWith(":") && reqPart !== undefined) {
|
|
618
|
-
const key = defPart.slice(1);
|
|
619
|
-
const value = this.processString(decodeURIComponent(reqPart));
|
|
620
|
-
data[key] = value;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
return await this.parse(data, validate);
|
|
624
|
-
}
|
|
625
801
|
static async getUnknownBody(input, validate) {
|
|
626
802
|
if (!validate) {
|
|
627
803
|
return await this.getTextBody(input);
|
|
@@ -643,7 +819,7 @@ class Parser {
|
|
|
643
819
|
const params = new URLSearchParams(text);
|
|
644
820
|
const body = {};
|
|
645
821
|
for (const [key, value] of params.entries()) {
|
|
646
|
-
objAppendEntry(body, key,
|
|
822
|
+
objAppendEntry(body, key, value);
|
|
647
823
|
}
|
|
648
824
|
return body;
|
|
649
825
|
}
|
|
@@ -655,7 +831,7 @@ class Parser {
|
|
|
655
831
|
if (value instanceof File) {
|
|
656
832
|
body[key] = value;
|
|
657
833
|
} else {
|
|
658
|
-
objAppendEntry(body, key,
|
|
834
|
+
objAppendEntry(body, key, value);
|
|
659
835
|
}
|
|
660
836
|
}
|
|
661
837
|
return body;
|
|
@@ -664,16 +840,14 @@ class Parser {
|
|
|
664
840
|
const contentLength = input.headers.get(CommonHeaders.ContentLength);
|
|
665
841
|
const length = contentLength ? parseInt(contentLength) : 0;
|
|
666
842
|
if (length > 0 && length < 1024 * 1024) {
|
|
667
|
-
|
|
668
|
-
return this.processString(text2);
|
|
843
|
+
return await input.text();
|
|
669
844
|
}
|
|
670
845
|
const buffer = await input.arrayBuffer();
|
|
671
846
|
const contentType = input.headers.get(CommonHeaders.ContentType) || "";
|
|
672
847
|
const match = contentType.match(/charset=([^;]+)/i);
|
|
673
848
|
const charset = match?.[1] ? match[1].trim() : null;
|
|
674
849
|
const decoder = new TextDecoder(charset || "utf-8");
|
|
675
|
-
|
|
676
|
-
return this.processString(text);
|
|
850
|
+
return decoder.decode(buffer);
|
|
677
851
|
}
|
|
678
852
|
static getNormalizedContentType(input) {
|
|
679
853
|
const contentTypeHeader = input.headers.get(CommonHeaders.ContentType) || "";
|
|
@@ -710,17 +884,6 @@ class Parser {
|
|
|
710
884
|
}
|
|
711
885
|
return "unknown";
|
|
712
886
|
}
|
|
713
|
-
static processString(value) {
|
|
714
|
-
let processedValue = value;
|
|
715
|
-
if (!strIsDefined(value))
|
|
716
|
-
return "";
|
|
717
|
-
if (/^-?\d+(\.\d+)?$/.test(value)) {
|
|
718
|
-
processedValue = Number(value);
|
|
719
|
-
} else if (value.toLowerCase() === "true" || value.toLowerCase() === "false") {
|
|
720
|
-
processedValue = value.toLowerCase() === "true";
|
|
721
|
-
}
|
|
722
|
-
return processedValue;
|
|
723
|
-
}
|
|
724
887
|
}
|
|
725
888
|
|
|
726
889
|
// src/Context/Context.ts
|
|
@@ -733,7 +896,7 @@ class Context {
|
|
|
733
896
|
this.body = body;
|
|
734
897
|
this.search = search;
|
|
735
898
|
this.params = params;
|
|
736
|
-
this.res = res ?? new
|
|
899
|
+
this.res = res ?? new CResponse;
|
|
737
900
|
}
|
|
738
901
|
req;
|
|
739
902
|
url;
|
|
@@ -747,10 +910,10 @@ class Context {
|
|
|
747
910
|
static makeFromRequest(req) {
|
|
748
911
|
return new Context(req, {}, {}, {});
|
|
749
912
|
}
|
|
750
|
-
static async appendParsedData(ctx, req,
|
|
751
|
-
ctx.body = await Parser.
|
|
752
|
-
ctx.
|
|
753
|
-
ctx.
|
|
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);
|
|
754
917
|
}
|
|
755
918
|
}
|
|
756
919
|
// src/Route/enums/RouteVariant.ts
|
|
@@ -770,7 +933,7 @@ class RouteAbstract {
|
|
|
770
933
|
resolveEndpoint(definition, variant) {
|
|
771
934
|
const endpoint = typeof definition === "string" ? definition : definition.path;
|
|
772
935
|
if (variant === RouteVariant.dynamic) {
|
|
773
|
-
return joinPathSegments(
|
|
936
|
+
return joinPathSegments(_prefixStore.get(), endpoint);
|
|
774
937
|
}
|
|
775
938
|
return endpoint;
|
|
776
939
|
}
|
|
@@ -796,9 +959,9 @@ class Route extends RouteAbstract {
|
|
|
796
959
|
this.id = this.resolveId(this.method, this.endpoint);
|
|
797
960
|
this.model = model;
|
|
798
961
|
this.handler = handler;
|
|
799
|
-
|
|
962
|
+
_routerStore.get().addRoute(this);
|
|
800
963
|
if (model) {
|
|
801
|
-
|
|
964
|
+
_routerStore.get().addModel(this, model);
|
|
802
965
|
}
|
|
803
966
|
}
|
|
804
967
|
variant;
|
|
@@ -817,59 +980,19 @@ class Route extends RouteAbstract {
|
|
|
817
980
|
}
|
|
818
981
|
}
|
|
819
982
|
|
|
820
|
-
// src/FileWalker/FileWalkerUsingBun.ts
|
|
821
|
-
class FileWalkerUsingBun {
|
|
822
|
-
static async read(address) {
|
|
823
|
-
try {
|
|
824
|
-
const file = await this.find(address);
|
|
825
|
-
if (!file)
|
|
826
|
-
return null;
|
|
827
|
-
return await file.text();
|
|
828
|
-
} catch {
|
|
829
|
-
return null;
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
static async exists(address) {
|
|
833
|
-
return await this.find(address) !== null;
|
|
834
|
-
}
|
|
835
|
-
static getExtension(address) {
|
|
836
|
-
return address.split(".").pop() ?? "txt";
|
|
837
|
-
}
|
|
838
|
-
static async find(address) {
|
|
839
|
-
const file = Bun.file(address);
|
|
840
|
-
const exists = await file.exists();
|
|
841
|
-
if (exists) {
|
|
842
|
-
return { text: () => file.text() };
|
|
843
|
-
}
|
|
844
|
-
return null;
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
// src/FileWalker/FileWalker.ts
|
|
849
|
-
class FileWalker extends FileWalkerUsingBun {
|
|
850
|
-
}
|
|
851
|
-
|
|
852
983
|
// src/Route/StaticRoute.ts
|
|
853
984
|
class StaticRoute extends RouteAbstract {
|
|
854
|
-
|
|
855
|
-
constructor(path2, filePath, handler, model) {
|
|
985
|
+
constructor(path2, definition, handler, model) {
|
|
856
986
|
super();
|
|
857
|
-
this.filePath = filePath;
|
|
858
987
|
this.variant = RouteVariant.static;
|
|
859
988
|
this.endpoint = this.resolveEndpoint(path2, this.variant);
|
|
860
989
|
this.method = Method.GET;
|
|
861
990
|
this.pattern = this.resolvePattern(this.endpoint);
|
|
862
991
|
this.id = this.resolveId(this.method, this.endpoint);
|
|
863
992
|
this.model = model;
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
return handler(c, content);
|
|
868
|
-
};
|
|
869
|
-
} else {
|
|
870
|
-
this.handler = this.defaultHandler;
|
|
871
|
-
}
|
|
872
|
-
_router.get().addRoute(this);
|
|
993
|
+
this.filePath = this.resolveFilePath(definition);
|
|
994
|
+
this.handler = this.resolveHandler(definition, handler);
|
|
995
|
+
_routerStore.get().addRoute(this);
|
|
873
996
|
}
|
|
874
997
|
id;
|
|
875
998
|
variant;
|
|
@@ -878,48 +1001,31 @@ class StaticRoute extends RouteAbstract {
|
|
|
878
1001
|
pattern;
|
|
879
1002
|
model;
|
|
880
1003
|
handler;
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
png: "image/png",
|
|
907
|
-
jpg: "image/jpeg",
|
|
908
|
-
jpeg: "image/jpeg",
|
|
909
|
-
gif: "image/gif",
|
|
910
|
-
svg: "image/svg+xml",
|
|
911
|
-
ico: "image/x-icon",
|
|
912
|
-
txt: "text/plain",
|
|
913
|
-
xml: "application/xml",
|
|
914
|
-
pdf: "application/pdf",
|
|
915
|
-
zip: "application/zip",
|
|
916
|
-
mp3: "audio/mpeg",
|
|
917
|
-
mp4: "video/mp4",
|
|
918
|
-
webm: "video/webm",
|
|
919
|
-
woff: "font/woff",
|
|
920
|
-
woff2: "font/woff2",
|
|
921
|
-
ttf: "font/ttf"
|
|
922
|
-
};
|
|
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);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
923
1029
|
}
|
|
924
1030
|
|
|
925
1031
|
// src/Controller/ControllerAbstract.ts
|
|
@@ -961,18 +1067,11 @@ class Middleware {
|
|
|
961
1067
|
constructor(opts) {
|
|
962
1068
|
this.useOn = opts.useOn;
|
|
963
1069
|
this.handler = opts.handler;
|
|
964
|
-
|
|
1070
|
+
_routerStore.get().addMiddleware(opts);
|
|
965
1071
|
}
|
|
966
1072
|
useOn;
|
|
967
1073
|
handler;
|
|
968
1074
|
}
|
|
969
|
-
// src/Repository/RepositoryAbstract.ts
|
|
970
|
-
class RepositoryAbstract {
|
|
971
|
-
db;
|
|
972
|
-
constructor(db) {
|
|
973
|
-
this.db = db;
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
1075
|
// src/utils/assert.ts
|
|
977
1076
|
function assert(condition, message) {
|
|
978
1077
|
const conditionName = String(condition);
|
|
@@ -996,8 +1095,8 @@ function strSplit(mark, input, minLength) {
|
|
|
996
1095
|
return parts;
|
|
997
1096
|
}
|
|
998
1097
|
|
|
999
|
-
// src/
|
|
1000
|
-
class
|
|
1098
|
+
// src/CRequest/CRequest.ts
|
|
1099
|
+
class CRequest extends Request {
|
|
1001
1100
|
info;
|
|
1002
1101
|
init;
|
|
1003
1102
|
constructor(info, init) {
|
|
@@ -1019,7 +1118,7 @@ class HttpRequest extends Request {
|
|
|
1019
1118
|
case this.info instanceof URL:
|
|
1020
1119
|
urlObject = this.info;
|
|
1021
1120
|
break;
|
|
1022
|
-
case this.info instanceof
|
|
1121
|
+
case this.info instanceof CRequest:
|
|
1023
1122
|
urlObject = this.info.urlObject;
|
|
1024
1123
|
break;
|
|
1025
1124
|
case this.info instanceof Request:
|
|
@@ -1036,12 +1135,12 @@ class HttpRequest extends Request {
|
|
|
1036
1135
|
}
|
|
1037
1136
|
resolveHeaders() {
|
|
1038
1137
|
if (this.init?.headers !== undefined) {
|
|
1039
|
-
return new
|
|
1138
|
+
return new CHeaders(this.init.headers);
|
|
1040
1139
|
}
|
|
1041
|
-
if (this.info instanceof Request || this.info instanceof
|
|
1042
|
-
return new
|
|
1140
|
+
if (this.info instanceof Request || this.info instanceof CRequest) {
|
|
1141
|
+
return new CHeaders(this.info.headers);
|
|
1043
1142
|
}
|
|
1044
|
-
return new
|
|
1143
|
+
return new CHeaders;
|
|
1045
1144
|
}
|
|
1046
1145
|
resolveCookies() {
|
|
1047
1146
|
const jar = new Cookies;
|
|
@@ -1062,44 +1161,43 @@ class HttpRequest extends Request {
|
|
|
1062
1161
|
return this.method === Method.OPTIONS && accessControlRequestMethodHeader;
|
|
1063
1162
|
}
|
|
1064
1163
|
}
|
|
1065
|
-
// src/utils/
|
|
1066
|
-
function
|
|
1067
|
-
return
|
|
1164
|
+
// src/utils/isRegexMatch.ts
|
|
1165
|
+
function isRegexMatch(source, pattern) {
|
|
1166
|
+
return pattern.test(source);
|
|
1068
1167
|
}
|
|
1069
1168
|
|
|
1070
|
-
// src/utils/
|
|
1071
|
-
function
|
|
1072
|
-
|
|
1169
|
+
// src/utils/strIsEqual.ts
|
|
1170
|
+
function strIsEqual(source, target, modifier) {
|
|
1171
|
+
source = source.trim();
|
|
1172
|
+
target = target.trim();
|
|
1173
|
+
if (modifier === "upper") {
|
|
1174
|
+
return source.toUpperCase() === target.toUpperCase();
|
|
1175
|
+
}
|
|
1176
|
+
if (modifier === "lower") {
|
|
1177
|
+
return source.toUpperCase() === target.toUpperCase();
|
|
1178
|
+
}
|
|
1179
|
+
return source === target;
|
|
1073
1180
|
}
|
|
1074
1181
|
|
|
1075
|
-
// src/
|
|
1076
|
-
class
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
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
|
+
});
|
|
1080
1191
|
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
getCorsHeaders(req, res) {
|
|
1086
|
-
const reqOrigin = req.headers.get("origin") ?? "";
|
|
1087
|
-
const { allowedOrigins, allowedMethods, allowedHeaders, credentials } = this.opts;
|
|
1088
|
-
if (isSomeArray(allowedOrigins) && allowedOrigins.includes(reqOrigin)) {
|
|
1089
|
-
res.headers.set(this.originKey, reqOrigin);
|
|
1090
|
-
}
|
|
1091
|
-
if (isSomeArray(allowedMethods)) {
|
|
1092
|
-
res.headers.set(this.methodsKey, allowedMethods.join(", "));
|
|
1093
|
-
}
|
|
1094
|
-
if (isSomeArray(allowedHeaders)) {
|
|
1095
|
-
res.headers.set(this.headersKey, allowedHeaders.join(", "));
|
|
1192
|
+
_map;
|
|
1193
|
+
get map() {
|
|
1194
|
+
if (!this._map) {
|
|
1195
|
+
this._map = new Map;
|
|
1096
1196
|
}
|
|
1097
|
-
|
|
1098
|
-
return res.headers;
|
|
1197
|
+
return this._map;
|
|
1099
1198
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
res.headers.innerCombine(headers);
|
|
1199
|
+
get [Symbol.toStringTag]() {
|
|
1200
|
+
return "LazyMap";
|
|
1103
1201
|
}
|
|
1104
1202
|
}
|
|
1105
1203
|
|
|
@@ -1108,55 +1206,133 @@ function strRemoveWhitespace(str) {
|
|
|
1108
1206
|
return str.trim().replace(/\s+/g, "");
|
|
1109
1207
|
}
|
|
1110
1208
|
|
|
1111
|
-
// src/
|
|
1112
|
-
|
|
1113
|
-
|
|
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) {
|
|
1221
|
+
const entry = {};
|
|
1222
|
+
for (const k of Object.keys(model)) {
|
|
1223
|
+
const key = k;
|
|
1224
|
+
const schema = model[key];
|
|
1225
|
+
if (!schema)
|
|
1226
|
+
continue;
|
|
1227
|
+
const handler = schema["~standard"].validate;
|
|
1228
|
+
entry[key] = this.intern(handler, "model", strRemoveWhitespace(JSON.stringify(schema)));
|
|
1229
|
+
}
|
|
1230
|
+
return entry;
|
|
1231
|
+
}
|
|
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;
|
|
1239
|
+
}
|
|
1114
1240
|
}
|
|
1115
1241
|
|
|
1116
|
-
// src/utils/
|
|
1117
|
-
function
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
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
|
+
}
|
|
1122
1267
|
}
|
|
1123
|
-
|
|
1124
|
-
|
|
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 };
|
|
1125
1286
|
}
|
|
1126
|
-
return source === target;
|
|
1127
1287
|
}
|
|
1128
1288
|
|
|
1129
1289
|
// src/Router/adapters/CorpusAdapter.ts
|
|
1130
1290
|
class CorpusAdapter {
|
|
1131
1291
|
routes = new Map;
|
|
1132
|
-
|
|
1292
|
+
modelRegistry = new ModelRegistry;
|
|
1293
|
+
middlewareRegistry = new MiddlewareRegistry;
|
|
1294
|
+
addRoute(data) {
|
|
1133
1295
|
this.checkPossibleCollision(data);
|
|
1134
1296
|
this.routes.set(data.id, data);
|
|
1135
1297
|
}
|
|
1136
|
-
|
|
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;
|
|
1137
1308
|
let route = null;
|
|
1138
1309
|
for (const data of this.routes.values()) {
|
|
1139
|
-
|
|
1140
|
-
if (this.hasAnyParam(endpoint) && isRegexMatch(path2, data.pattern)) {
|
|
1310
|
+
if (this.hasAnyParam(data.endpoint) && isRegexMatch(pathname, data.pattern)) {
|
|
1141
1311
|
route = data;
|
|
1142
1312
|
break;
|
|
1143
1313
|
}
|
|
1144
|
-
if (this.hasLastPartParam(endpoint) && strIsEqual(this.removeLastParam(endpoint),
|
|
1314
|
+
if (this.hasLastPartParam(data.endpoint) && strIsEqual(this.removeLastParam(data.endpoint), pathname, "lower")) {
|
|
1145
1315
|
route = data;
|
|
1146
1316
|
break;
|
|
1147
1317
|
}
|
|
1148
|
-
if (strIsEqual(endpoint,
|
|
1318
|
+
if (strIsEqual(data.endpoint, pathname)) {
|
|
1149
1319
|
route = data;
|
|
1150
1320
|
break;
|
|
1151
1321
|
}
|
|
1152
1322
|
}
|
|
1153
1323
|
if (route === null) {
|
|
1154
|
-
throw
|
|
1324
|
+
throw CError.notFound();
|
|
1155
1325
|
}
|
|
1156
1326
|
if (!strIsEqual(method, route.method, "upper")) {
|
|
1157
|
-
throw
|
|
1327
|
+
throw CError.methodNotAllowed();
|
|
1158
1328
|
}
|
|
1159
|
-
return {
|
|
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
|
+
};
|
|
1160
1336
|
}
|
|
1161
1337
|
list() {
|
|
1162
1338
|
return Array.from(this.routes.values());
|
|
@@ -1198,6 +1374,20 @@ class CorpusAdapter {
|
|
|
1198
1374
|
}
|
|
1199
1375
|
return false;
|
|
1200
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;
|
|
1390
|
+
}
|
|
1201
1391
|
hasLastPartParam(endpoint) {
|
|
1202
1392
|
if (!this.hasAnyParam(endpoint))
|
|
1203
1393
|
return false;
|
|
@@ -1216,82 +1406,29 @@ class CorpusAdapter {
|
|
|
1216
1406
|
}
|
|
1217
1407
|
}
|
|
1218
1408
|
|
|
1219
|
-
// src/Store/LazyMap.ts
|
|
1220
|
-
class LazyMap {
|
|
1221
|
-
constructor() {
|
|
1222
|
-
return new Proxy(this, {
|
|
1223
|
-
get(target, prop) {
|
|
1224
|
-
const val = Reflect.get(target.map, prop);
|
|
1225
|
-
return typeof val === "function" ? val.bind(target.map) : val;
|
|
1226
|
-
}
|
|
1227
|
-
});
|
|
1228
|
-
}
|
|
1229
|
-
_map;
|
|
1230
|
-
get map() {
|
|
1231
|
-
if (!this._map) {
|
|
1232
|
-
this._map = new Map;
|
|
1233
|
-
}
|
|
1234
|
-
return this._map;
|
|
1235
|
-
}
|
|
1236
|
-
get [Symbol.toStringTag]() {
|
|
1237
|
-
return "LazyMap";
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
1409
|
// src/Router/Router.ts
|
|
1242
1410
|
class Router {
|
|
1243
1411
|
constructor(adapter) {
|
|
1244
1412
|
this._adapter = adapter ?? new CorpusAdapter;
|
|
1245
1413
|
}
|
|
1414
|
+
models = [];
|
|
1246
1415
|
_adapter;
|
|
1247
1416
|
cache = new WeakMap;
|
|
1248
|
-
internFuncMap = new LazyMap;
|
|
1249
|
-
middlewares = new LazyMap;
|
|
1250
|
-
models = new LazyMap;
|
|
1251
1417
|
checkPossibleCollision(n) {
|
|
1252
1418
|
if (this._adapter instanceof CorpusAdapter) {
|
|
1253
1419
|
return this._adapter.checkPossibleCollision(n);
|
|
1254
1420
|
}
|
|
1255
1421
|
return false;
|
|
1256
1422
|
}
|
|
1257
|
-
addModel(
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
const key = k;
|
|
1261
|
-
const schema = model[key];
|
|
1262
|
-
if (!schema)
|
|
1263
|
-
continue;
|
|
1264
|
-
const handler = schema["~standard"].validate;
|
|
1265
|
-
entry[key] = this.intern(handler, "model", strRemoveWhitespace(JSON.stringify(schema)));
|
|
1266
|
-
}
|
|
1267
|
-
this.models.set(routeId, entry);
|
|
1268
|
-
}
|
|
1269
|
-
findModel(routeId) {
|
|
1270
|
-
return this.models.get(routeId);
|
|
1271
|
-
}
|
|
1272
|
-
addMiddleware(m) {
|
|
1273
|
-
const useOn = m.useOn;
|
|
1274
|
-
const handler = m.handler;
|
|
1275
|
-
if (useOn === "*") {
|
|
1276
|
-
const existing = this.middlewares.get("*") ?? [];
|
|
1277
|
-
this.middlewares.set("*", [...existing, handler]);
|
|
1278
|
-
return;
|
|
1279
|
-
}
|
|
1280
|
-
for (const target of Array.isArray(useOn) ? useOn : [useOn]) {
|
|
1281
|
-
const routeIds = target instanceof Route ? [target.id] : target instanceof ControllerAbstract ? Array.from(target.routeIds) : [];
|
|
1282
|
-
for (const routeId of routeIds) {
|
|
1283
|
-
const existing = this.middlewares.get(routeId) ?? [];
|
|
1284
|
-
this.middlewares.set(routeId, [...existing, handler]);
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1423
|
+
addModel(route, model) {
|
|
1424
|
+
this.models.push(model);
|
|
1425
|
+
this._adapter.addModel(route, model);
|
|
1287
1426
|
}
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
const locals = this.middlewares.get(routeId) ?? [];
|
|
1291
|
-
return this.compile([...globals, ...locals]);
|
|
1427
|
+
addMiddleware(middleware) {
|
|
1428
|
+
this._adapter.addMiddleware(middleware);
|
|
1292
1429
|
}
|
|
1293
1430
|
addRoute(r) {
|
|
1294
|
-
this._adapter.
|
|
1431
|
+
this._adapter.addRoute({
|
|
1295
1432
|
id: r.id,
|
|
1296
1433
|
endpoint: r.endpoint,
|
|
1297
1434
|
method: r.method,
|
|
@@ -1303,17 +1440,15 @@ class Router {
|
|
|
1303
1440
|
const cached = this.cache.get(req);
|
|
1304
1441
|
if (cached)
|
|
1305
1442
|
return cached;
|
|
1306
|
-
const match = this._adapter.find(req
|
|
1443
|
+
const match = this._adapter.find(req);
|
|
1307
1444
|
if (!match)
|
|
1308
|
-
throw
|
|
1445
|
+
throw CError.notFound();
|
|
1309
1446
|
const ctx = Context.makeFromRequest(req);
|
|
1310
|
-
const mwHandler = this.findMiddleware(match.route.id);
|
|
1311
|
-
const model = this.findModel(match.route.id);
|
|
1312
1447
|
const handler = async () => {
|
|
1313
|
-
await
|
|
1314
|
-
await Context.appendParsedData(ctx, req, match.
|
|
1448
|
+
await match.middleware?.(ctx);
|
|
1449
|
+
await Context.appendParsedData(ctx, req, match.params, match.search, match.model);
|
|
1315
1450
|
const res = await match.route.handler(ctx);
|
|
1316
|
-
return res instanceof
|
|
1451
|
+
return res instanceof CResponse ? res : new CResponse(res, {
|
|
1317
1452
|
cookies: ctx.res.cookies,
|
|
1318
1453
|
headers: ctx.res.headers,
|
|
1319
1454
|
status: ctx.res.status,
|
|
@@ -1326,35 +1461,20 @@ class Router {
|
|
|
1326
1461
|
getRouteList() {
|
|
1327
1462
|
return this._adapter.list().map((v) => [v.method, v.endpoint]);
|
|
1328
1463
|
}
|
|
1329
|
-
compile(fns) {
|
|
1330
|
-
return async (...args) => {
|
|
1331
|
-
for (const fn of fns) {
|
|
1332
|
-
if (!fn)
|
|
1333
|
-
continue;
|
|
1334
|
-
await fn(...args);
|
|
1335
|
-
}
|
|
1336
|
-
};
|
|
1337
|
-
}
|
|
1338
|
-
intern(value, ...namespace) {
|
|
1339
|
-
const key = namespace.join("::");
|
|
1340
|
-
const existing = this.internFuncMap.get(key);
|
|
1341
|
-
if (existing)
|
|
1342
|
-
return existing;
|
|
1343
|
-
this.internFuncMap.set(key, value);
|
|
1344
|
-
return value;
|
|
1345
|
-
}
|
|
1346
1464
|
}
|
|
1347
1465
|
|
|
1348
1466
|
// src/Server/ServerAbstract.ts
|
|
1349
1467
|
class ServerAbstract {
|
|
1468
|
+
opts;
|
|
1350
1469
|
constructor(opts) {
|
|
1351
|
-
|
|
1470
|
+
this.opts = opts;
|
|
1471
|
+
_routerStore.set(new Router(opts?.adapter));
|
|
1352
1472
|
}
|
|
1353
1473
|
get routes() {
|
|
1354
|
-
return
|
|
1474
|
+
return _routerStore.get().getRouteList();
|
|
1355
1475
|
}
|
|
1356
1476
|
setGlobalPrefix(value) {
|
|
1357
|
-
|
|
1477
|
+
_prefixStore.set(value);
|
|
1358
1478
|
}
|
|
1359
1479
|
async listen(port, hostname = "0.0.0.0") {
|
|
1360
1480
|
try {
|
|
@@ -1373,10 +1493,11 @@ class ServerAbstract {
|
|
|
1373
1493
|
}
|
|
1374
1494
|
}
|
|
1375
1495
|
async handle(request) {
|
|
1376
|
-
const req = new
|
|
1496
|
+
const req = new CRequest(request);
|
|
1377
1497
|
let res = await this.getResponse(req);
|
|
1378
|
-
|
|
1379
|
-
|
|
1498
|
+
const cors = _corsStore.get();
|
|
1499
|
+
if (cors !== null) {
|
|
1500
|
+
cors.apply(req, res);
|
|
1380
1501
|
}
|
|
1381
1502
|
if (this.handleAfterResponse) {
|
|
1382
1503
|
res = await this.handleAfterResponse(res);
|
|
@@ -1386,12 +1507,12 @@ class ServerAbstract {
|
|
|
1386
1507
|
async getResponse(req) {
|
|
1387
1508
|
try {
|
|
1388
1509
|
if (req.isPreflight) {
|
|
1389
|
-
return new
|
|
1510
|
+
return new CResponse("Departed");
|
|
1390
1511
|
}
|
|
1391
|
-
const handler =
|
|
1512
|
+
const handler = _routerStore.get().findRouteHandler(req);
|
|
1392
1513
|
return await handler();
|
|
1393
1514
|
} catch (err) {
|
|
1394
|
-
if (err instanceof
|
|
1515
|
+
if (err instanceof CError) {
|
|
1395
1516
|
if (err.isStatusOf(Status.NOT_FOUND)) {
|
|
1396
1517
|
return await this.handleNotFound(req);
|
|
1397
1518
|
}
|
|
@@ -1402,10 +1523,6 @@ class ServerAbstract {
|
|
|
1402
1523
|
return await this.handleError(err);
|
|
1403
1524
|
}
|
|
1404
1525
|
}
|
|
1405
|
-
cors;
|
|
1406
|
-
setCors(opts) {
|
|
1407
|
-
this.cors = opts ? new Cors(opts) : undefined;
|
|
1408
|
-
}
|
|
1409
1526
|
handleBeforeListen;
|
|
1410
1527
|
setOnBeforeListen(handler) {
|
|
1411
1528
|
this.handleBeforeListen = handler;
|
|
@@ -1427,23 +1544,23 @@ class ServerAbstract {
|
|
|
1427
1544
|
}
|
|
1428
1545
|
defaultErrorHandler = (err) => {
|
|
1429
1546
|
if (!(err instanceof Error)) {
|
|
1430
|
-
return new
|
|
1547
|
+
return new CResponse({ error: err, message: "Unknown" }, { status: Status.INTERNAL_SERVER_ERROR });
|
|
1431
1548
|
}
|
|
1432
|
-
if (err instanceof
|
|
1549
|
+
if (err instanceof CError) {
|
|
1433
1550
|
return err.toResponse();
|
|
1434
1551
|
}
|
|
1435
|
-
return new
|
|
1552
|
+
return new CResponse({ error: err, message: err.message }, { status: Status.INTERNAL_SERVER_ERROR });
|
|
1436
1553
|
};
|
|
1437
1554
|
handleNotFound = (req) => this.defaultNotFoundHandler(req);
|
|
1438
1555
|
setOnNotFound(handler) {
|
|
1439
1556
|
this.handleNotFound = handler;
|
|
1440
1557
|
}
|
|
1441
1558
|
defaultNotFoundHandler = (req) => {
|
|
1442
|
-
return new
|
|
1559
|
+
return new CResponse({ error: true, message: `${req.method} on ${req.url} does not exist.` }, { status: Status.NOT_FOUND });
|
|
1443
1560
|
};
|
|
1444
1561
|
handleMethodNotAllowed = (req) => this.defaultMethodNotFoundHandler(req);
|
|
1445
1562
|
defaultMethodNotFoundHandler = (req) => {
|
|
1446
|
-
return new
|
|
1563
|
+
return new CResponse({ error: `${req.method} ${req.url} does not exist.` }, { status: Status.METHOD_NOT_ALLOWED });
|
|
1447
1564
|
};
|
|
1448
1565
|
}
|
|
1449
1566
|
|
|
@@ -1456,7 +1573,7 @@ class ServerUsingBun extends ServerAbstract {
|
|
|
1456
1573
|
async close() {
|
|
1457
1574
|
await this.handleBeforeClose?.();
|
|
1458
1575
|
console.log("Closing...");
|
|
1459
|
-
await this.app?.stop();
|
|
1576
|
+
await this.app?.stop(true);
|
|
1460
1577
|
if (Config.nodeEnv !== "test") {
|
|
1461
1578
|
process.exit(0);
|
|
1462
1579
|
}
|
|
@@ -1465,7 +1582,9 @@ class ServerUsingBun extends ServerAbstract {
|
|
|
1465
1582
|
return Bun.serve({
|
|
1466
1583
|
port: options.port,
|
|
1467
1584
|
hostname: options.hostname,
|
|
1468
|
-
fetch: options.fetch
|
|
1585
|
+
fetch: options.fetch,
|
|
1586
|
+
idleTimeout: this.opts?.idleTimeout,
|
|
1587
|
+
tls: this.opts?.tls
|
|
1469
1588
|
});
|
|
1470
1589
|
}
|
|
1471
1590
|
}
|
|
@@ -1473,6 +1592,67 @@ class ServerUsingBun extends ServerAbstract {
|
|
|
1473
1592
|
// src/Server/Server.ts
|
|
1474
1593
|
class Server extends ServerUsingBun {
|
|
1475
1594
|
}
|
|
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
|
+
}
|
|
1476
1656
|
// node_modules/memoirist/dist/bun/index.js
|
|
1477
1657
|
var Y = (v, b) => {
|
|
1478
1658
|
let A = b?.length ? {} : null;
|
|
@@ -1689,47 +1869,94 @@ var w = _;
|
|
|
1689
1869
|
// src/Router/adapters/MemoiristAdapter.ts
|
|
1690
1870
|
class MemoiristAdapter {
|
|
1691
1871
|
router = new w;
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
const
|
|
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);
|
|
1697
1878
|
if (!result)
|
|
1698
1879
|
return null;
|
|
1699
|
-
return {
|
|
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
|
+
};
|
|
1700
1887
|
}
|
|
1701
1888
|
list() {
|
|
1702
|
-
return this.router.history.map((v) => v[2]);
|
|
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
|
+
}
|
|
1703
1928
|
}
|
|
1704
1929
|
}
|
|
1705
|
-
|
|
1706
1930
|
// src/index.ts
|
|
1707
|
-
var
|
|
1708
|
-
var
|
|
1709
|
-
var
|
|
1931
|
+
var _prefixStore = new GlobalPrefixStore;
|
|
1932
|
+
var _routerStore = new GlobalRouterStore;
|
|
1933
|
+
var _corsStore = new GlobalCorsStore;
|
|
1710
1934
|
export {
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1935
|
+
exports_C as default,
|
|
1936
|
+
_routerStore,
|
|
1937
|
+
_prefixStore,
|
|
1938
|
+
_corsStore,
|
|
1939
|
+
exports_X as X,
|
|
1714
1940
|
Status,
|
|
1715
1941
|
StaticRoute,
|
|
1716
1942
|
Server,
|
|
1717
1943
|
Route,
|
|
1718
|
-
|
|
1719
|
-
|
|
1944
|
+
CResponse as Response,
|
|
1945
|
+
CRequest as Request,
|
|
1720
1946
|
RepositoryAbstract as Repository,
|
|
1721
1947
|
Parser,
|
|
1722
1948
|
Middleware,
|
|
1723
1949
|
Method,
|
|
1724
1950
|
MemoiristAdapter,
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1951
|
+
CHeaders as Headers,
|
|
1952
|
+
XFile as File,
|
|
1953
|
+
exports_X as Extra,
|
|
1954
|
+
CError as Error,
|
|
1955
|
+
Cors,
|
|
1729
1956
|
Cookies,
|
|
1730
1957
|
ControllerAbstract as Controller,
|
|
1731
1958
|
Context,
|
|
1732
1959
|
Config,
|
|
1733
1960
|
CommonHeaders,
|
|
1734
|
-
|
|
1961
|
+
exports_C as C
|
|
1735
1962
|
};
|