@e22m4u/js-trie-router 0.5.14 → 0.6.1
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/cjs/index.cjs +137 -119
- package/package.json +6 -6
- package/src/branch/merge-router-branch-definition.spec.js +32 -16
- package/src/branch/merge-router-branch-definitions.js +6 -3
- package/src/branch/router-branch.js +5 -5
- package/src/branch/router-branch.spec.js +81 -19
- package/src/branch/validate-router-branch-definition.js +16 -9
- package/src/branch/validate-router-branch-definition.spec.js +28 -19
- package/src/debuggable-service.spec.js +10 -2
- package/src/hooks/router-hook-invoker.js +5 -3
- package/src/hooks/router-hook-invoker.spec.js +19 -17
- package/src/hooks/router-hook-registry.spec.js +32 -18
- package/src/parsers/body-parser.d.ts +11 -4
- package/src/parsers/body-parser.js +28 -12
- package/src/parsers/body-parser.spec.js +136 -92
- package/src/parsers/cookies-parser.spec.js +3 -3
- package/src/parsers/query-parser.spec.js +3 -3
- package/src/parsers/request-parser.js +2 -2
- package/src/parsers/request-parser.spec.js +9 -9
- package/src/request-context.js +7 -8
- package/src/request-context.spec.js +17 -18
- package/src/route/route.spec.js +47 -36
- package/src/route/validate-route-definition.js +14 -6
- package/src/route/validate-route-definition.spec.js +32 -18
- package/src/route-registry.js +3 -3
- package/src/route-registry.spec.js +6 -6
- package/src/router-options.js +2 -2
- package/src/router-options.spec.js +6 -6
- package/src/senders/data-sender.spec.js +7 -7
- package/src/senders/error-sender.spec.js +3 -3
- package/src/trie-router.d.ts +6 -6
- package/src/trie-router.js +4 -4
- package/src/trie-router.spec.js +90 -23
- package/src/utils/clone-deep.spec.js +7 -7
- package/src/utils/create-cookie-string.js +1 -2
- package/src/utils/create-cookie-string.spec.js +4 -8
- package/src/utils/create-error.js +2 -4
- package/src/utils/create-error.spec.js +5 -13
- package/src/utils/create-request-mock.d.ts +5 -5
- package/src/utils/create-request-mock.js +74 -91
- package/src/utils/create-request-mock.spec.js +61 -98
- package/src/utils/create-response-mock.spec.js +13 -13
- package/src/utils/create-route-mock.spec.js +6 -6
- package/src/utils/fetch-request-body.js +3 -4
- package/src/utils/fetch-request-body.spec.js +22 -23
- package/src/utils/get-request-pathname.js +2 -2
- package/src/utils/get-request-pathname.spec.js +11 -4
- package/src/utils/index.d.ts +0 -1
- package/src/utils/index.js +0 -1
- package/src/utils/is-promise.spec.js +2 -2
- package/src/utils/is-readable-stream.spec.js +2 -2
- package/src/utils/is-response-sent.js +2 -2
- package/src/utils/is-response-sent.spec.js +5 -5
- package/src/utils/is-writable-stream.spec.js +2 -2
- package/src/utils/merge-deep.spec.js +2 -2
- package/src/utils/parse-content-type.js +1 -2
- package/src/utils/parse-content-type.spec.js +7 -11
- package/src/utils/parse-cookie-string.js +1 -2
- package/src/utils/parse-cookie-string.spec.js +2 -6
- package/src/utils/to-camel-case.js +1 -2
- package/src/utils/to-camel-case.spec.js +3 -7
- package/src/utils/to-pascal-case.spec.js +1 -1
- package/src/utils/normalize-path.d.ts +0 -12
- package/src/utils/normalize-path.js +0 -22
- package/src/utils/normalize-path.spec.js +0 -56
package/dist/cjs/index.cjs
CHANGED
|
@@ -65,7 +65,6 @@ __export(index_exports, {
|
|
|
65
65
|
isResponseSent: () => isResponseSent,
|
|
66
66
|
isWritableStream: () => isWritableStream,
|
|
67
67
|
mergeDeep: () => mergeDeep,
|
|
68
|
-
normalizePath: () => normalizePath,
|
|
69
68
|
parseContentType: () => parseContentType,
|
|
70
69
|
parseCookieString: () => parseCookieString,
|
|
71
70
|
parseJsonBody: () => parseJsonBody,
|
|
@@ -167,13 +166,13 @@ var import_js_format = require("@e22m4u/js-format");
|
|
|
167
166
|
function createError(errorCtor, message, ...args) {
|
|
168
167
|
if (typeof errorCtor !== "function") {
|
|
169
168
|
throw new import_js_format.InvalidArgumentError(
|
|
170
|
-
'
|
|
169
|
+
'Parameter "errorCtor" must be a Function, but %v was given.',
|
|
171
170
|
errorCtor
|
|
172
171
|
);
|
|
173
172
|
}
|
|
174
173
|
if (message != null && typeof message !== "string") {
|
|
175
174
|
throw new import_js_format.InvalidArgumentError(
|
|
176
|
-
'
|
|
175
|
+
'Parameter "message" must be a String, but %v was given.',
|
|
177
176
|
message
|
|
178
177
|
);
|
|
179
178
|
}
|
|
@@ -190,7 +189,7 @@ var import_js_format2 = require("@e22m4u/js-format");
|
|
|
190
189
|
function toCamelCase(input) {
|
|
191
190
|
if (typeof input !== "string") {
|
|
192
191
|
throw new import_js_format2.InvalidArgumentError(
|
|
193
|
-
'
|
|
192
|
+
'Parameter "input" must be a String, but %v was given.',
|
|
194
193
|
input
|
|
195
194
|
);
|
|
196
195
|
}
|
|
@@ -207,22 +206,12 @@ function toPascalCase(input) {
|
|
|
207
206
|
}
|
|
208
207
|
__name(toPascalCase, "toPascalCase");
|
|
209
208
|
|
|
210
|
-
// src/utils/normalize-path.js
|
|
211
|
-
function normalizePath(value, noStartingSlash = false) {
|
|
212
|
-
if (typeof value !== "string") {
|
|
213
|
-
return "/";
|
|
214
|
-
}
|
|
215
|
-
const res = value.trim().replace(/\/+/g, "/").replace(/(^\/|\/$)/g, "");
|
|
216
|
-
return noStartingSlash ? res : "/" + res;
|
|
217
|
-
}
|
|
218
|
-
__name(normalizePath, "normalizePath");
|
|
219
|
-
|
|
220
209
|
// src/utils/is-response-sent.js
|
|
221
210
|
var import_js_format3 = require("@e22m4u/js-format");
|
|
222
211
|
function isResponseSent(response) {
|
|
223
212
|
if (!response || typeof response !== "object" || Array.isArray(response) || typeof response.headersSent !== "boolean") {
|
|
224
213
|
throw new import_js_format3.InvalidArgumentError(
|
|
225
|
-
'
|
|
214
|
+
'Parameter "response" must be an instance of ServerResponse, but %v was given.',
|
|
226
215
|
response
|
|
227
216
|
);
|
|
228
217
|
}
|
|
@@ -254,7 +243,7 @@ var import_js_format4 = require("@e22m4u/js-format");
|
|
|
254
243
|
function parseContentType(input) {
|
|
255
244
|
if (typeof input !== "string") {
|
|
256
245
|
throw new import_js_format4.InvalidArgumentError(
|
|
257
|
-
"
|
|
246
|
+
'Parameter "input" must be a String, but %v was given.',
|
|
258
247
|
input
|
|
259
248
|
);
|
|
260
249
|
}
|
|
@@ -300,13 +289,13 @@ var CHARACTER_ENCODING_LIST = [
|
|
|
300
289
|
function fetchRequestBody(request, bodyBytesLimit = 0) {
|
|
301
290
|
if (!(request instanceof import_http.IncomingMessage)) {
|
|
302
291
|
throw new import_js_format5.InvalidArgumentError(
|
|
303
|
-
'
|
|
292
|
+
'Parameter "request" must be an instance of IncomingMessage, but %v was given.',
|
|
304
293
|
request
|
|
305
294
|
);
|
|
306
295
|
}
|
|
307
296
|
if (typeof bodyBytesLimit !== "number") {
|
|
308
297
|
throw new import_js_format5.InvalidArgumentError(
|
|
309
|
-
'
|
|
298
|
+
'Parameter "bodyBytesLimit" must be a Number, but %v was given.',
|
|
310
299
|
bodyBytesLimit
|
|
311
300
|
);
|
|
312
301
|
}
|
|
@@ -393,7 +382,7 @@ var import_js_format6 = require("@e22m4u/js-format");
|
|
|
393
382
|
function parseCookieString(input) {
|
|
394
383
|
if (typeof input !== "string") {
|
|
395
384
|
throw new import_js_format6.InvalidArgumentError(
|
|
396
|
-
'
|
|
385
|
+
'Parameter "input" must be a String, but %v was given.',
|
|
397
386
|
input
|
|
398
387
|
);
|
|
399
388
|
}
|
|
@@ -421,7 +410,7 @@ var import_js_format7 = require("@e22m4u/js-format");
|
|
|
421
410
|
function createCookieString(data) {
|
|
422
411
|
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
423
412
|
throw new import_js_format7.InvalidArgumentError(
|
|
424
|
-
|
|
413
|
+
"Cookie data must be an Object, but %v was given.",
|
|
425
414
|
data
|
|
426
415
|
);
|
|
427
416
|
}
|
|
@@ -441,111 +430,111 @@ function createCookieString(data) {
|
|
|
441
430
|
__name(createCookieString, "createCookieString");
|
|
442
431
|
|
|
443
432
|
// src/utils/create-request-mock.js
|
|
444
|
-
function createRequestMock(
|
|
445
|
-
if (
|
|
433
|
+
function createRequestMock(options) {
|
|
434
|
+
if (options != null && typeof options !== "object" || Array.isArray(options)) {
|
|
446
435
|
throw new import_js_format8.InvalidArgumentError(
|
|
447
|
-
'
|
|
448
|
-
|
|
436
|
+
'Parameter "options" must be an Object, but %v was given.',
|
|
437
|
+
options
|
|
449
438
|
);
|
|
450
439
|
}
|
|
451
|
-
|
|
452
|
-
if (
|
|
440
|
+
options = options || {};
|
|
441
|
+
if (options.host != null && typeof options.host !== "string") {
|
|
453
442
|
throw new import_js_format8.InvalidArgumentError(
|
|
454
|
-
'
|
|
455
|
-
|
|
443
|
+
'Option "host" must be a String, but %v was given.',
|
|
444
|
+
options.host
|
|
456
445
|
);
|
|
457
446
|
}
|
|
458
|
-
if (
|
|
447
|
+
if (options.method != null && typeof options.method !== "string") {
|
|
459
448
|
throw new import_js_format8.InvalidArgumentError(
|
|
460
|
-
'
|
|
461
|
-
|
|
449
|
+
'Option "method" must be a String, but %v was given.',
|
|
450
|
+
options.method
|
|
462
451
|
);
|
|
463
452
|
}
|
|
464
|
-
if (
|
|
453
|
+
if (options.secure != null && typeof options.secure !== "boolean") {
|
|
465
454
|
throw new import_js_format8.InvalidArgumentError(
|
|
466
|
-
'
|
|
467
|
-
|
|
455
|
+
'Option "secure" must be a Boolean, but %v was given.',
|
|
456
|
+
options.secure
|
|
468
457
|
);
|
|
469
458
|
}
|
|
470
|
-
if (
|
|
459
|
+
if (options.path != null && typeof options.path !== "string") {
|
|
471
460
|
throw new import_js_format8.InvalidArgumentError(
|
|
472
|
-
'
|
|
473
|
-
|
|
461
|
+
'Option "path" must be a String, but %v was given.',
|
|
462
|
+
options.path
|
|
474
463
|
);
|
|
475
464
|
}
|
|
476
|
-
if (
|
|
465
|
+
if (options.query != null && typeof options.query !== "object" && typeof options.query !== "string" || Array.isArray(options.query)) {
|
|
477
466
|
throw new import_js_format8.InvalidArgumentError(
|
|
478
|
-
'
|
|
479
|
-
|
|
467
|
+
'Option "query" must be a String or Object, but %v was given.',
|
|
468
|
+
options.query
|
|
480
469
|
);
|
|
481
470
|
}
|
|
482
|
-
if (
|
|
471
|
+
if (options.cookies != null && typeof options.cookies !== "string" && typeof options.cookies !== "object" || Array.isArray(options.cookies)) {
|
|
483
472
|
throw new import_js_format8.InvalidArgumentError(
|
|
484
|
-
'
|
|
485
|
-
|
|
473
|
+
'Option "cookies" must be a String or Object, but %v was given.',
|
|
474
|
+
options.cookies
|
|
486
475
|
);
|
|
487
476
|
}
|
|
488
|
-
if (
|
|
477
|
+
if (options.headers != null && typeof options.headers !== "object" || Array.isArray(options.headers)) {
|
|
489
478
|
throw new import_js_format8.InvalidArgumentError(
|
|
490
|
-
'
|
|
491
|
-
|
|
479
|
+
'Option "headers" must be an Object, but %v was given.',
|
|
480
|
+
options.headers
|
|
492
481
|
);
|
|
493
482
|
}
|
|
494
|
-
if (
|
|
483
|
+
if (options.stream != null && !isReadableStream(options.stream)) {
|
|
495
484
|
throw new import_js_format8.InvalidArgumentError(
|
|
496
|
-
'
|
|
497
|
-
|
|
485
|
+
'Option "stream" must be a Stream, but %v was given.',
|
|
486
|
+
options.stream
|
|
498
487
|
);
|
|
499
488
|
}
|
|
500
|
-
if (
|
|
501
|
-
if (typeof
|
|
489
|
+
if (options.encoding != null) {
|
|
490
|
+
if (typeof options.encoding !== "string") {
|
|
502
491
|
throw new import_js_format8.InvalidArgumentError(
|
|
503
|
-
'
|
|
504
|
-
|
|
492
|
+
'Option "encoding" must be a String, but %v was given.',
|
|
493
|
+
options.encoding
|
|
505
494
|
);
|
|
506
495
|
}
|
|
507
|
-
if (!CHARACTER_ENCODING_LIST.includes(
|
|
496
|
+
if (!CHARACTER_ENCODING_LIST.includes(options.encoding)) {
|
|
508
497
|
throw new import_js_format8.InvalidArgumentError(
|
|
509
498
|
"Character encoding %v is not supported.",
|
|
510
|
-
|
|
499
|
+
options.encoding
|
|
511
500
|
);
|
|
512
501
|
}
|
|
513
502
|
}
|
|
514
|
-
if (
|
|
515
|
-
if (
|
|
503
|
+
if (options.stream) {
|
|
504
|
+
if (options.secure != null) {
|
|
516
505
|
throw new import_js_format8.InvalidArgumentError(
|
|
517
|
-
'The "
|
|
506
|
+
'The "stream" and "secure" options cannot be used together.'
|
|
518
507
|
);
|
|
519
508
|
}
|
|
520
|
-
if (
|
|
509
|
+
if (options.body != null) {
|
|
521
510
|
throw new import_js_format8.InvalidArgumentError(
|
|
522
|
-
'The "
|
|
511
|
+
'The "stream" and "body" options cannot be used together.'
|
|
523
512
|
);
|
|
524
513
|
}
|
|
525
|
-
if (
|
|
514
|
+
if (options.encoding != null) {
|
|
526
515
|
throw new import_js_format8.InvalidArgumentError(
|
|
527
|
-
'The "
|
|
516
|
+
'The "stream" and "encoding" options cannot be used together.'
|
|
528
517
|
);
|
|
529
518
|
}
|
|
530
519
|
}
|
|
531
|
-
const request =
|
|
532
|
-
request.url = createRequestUrl(
|
|
520
|
+
const request = options.stream || createRequestStream(options.secure, options.body, options.encoding);
|
|
521
|
+
request.url = createRequestUrl(options.path || "/", options.query);
|
|
533
522
|
request.headers = createRequestHeaders(
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
523
|
+
options.host,
|
|
524
|
+
options.secure,
|
|
525
|
+
options.body,
|
|
526
|
+
options.cookies,
|
|
527
|
+
options.encoding,
|
|
528
|
+
options.headers
|
|
540
529
|
);
|
|
541
|
-
request.method = (
|
|
530
|
+
request.method = (options.method || "get").toUpperCase();
|
|
542
531
|
return request;
|
|
543
532
|
}
|
|
544
533
|
__name(createRequestMock, "createRequestMock");
|
|
545
534
|
function createRequestStream(secure, body, encoding) {
|
|
546
535
|
if (encoding != null && typeof encoding !== "string") {
|
|
547
536
|
throw new import_js_format8.InvalidArgumentError(
|
|
548
|
-
'
|
|
537
|
+
'Parameter "encoding" must be a String, but %v was given.',
|
|
549
538
|
encoding
|
|
550
539
|
);
|
|
551
540
|
}
|
|
@@ -571,13 +560,13 @@ __name(createRequestStream, "createRequestStream");
|
|
|
571
560
|
function createRequestUrl(path, query) {
|
|
572
561
|
if (typeof path !== "string") {
|
|
573
562
|
throw new import_js_format8.InvalidArgumentError(
|
|
574
|
-
'
|
|
563
|
+
'Parameter "path" must be a String, but %v was given.',
|
|
575
564
|
path
|
|
576
565
|
);
|
|
577
566
|
}
|
|
578
567
|
if (query != null && typeof query !== "string" && typeof query !== "object" || Array.isArray(query)) {
|
|
579
568
|
throw new import_js_format8.InvalidArgumentError(
|
|
580
|
-
'
|
|
569
|
+
'Parameter "query" must be a String or Object, but %v was given.',
|
|
581
570
|
query
|
|
582
571
|
);
|
|
583
572
|
}
|
|
@@ -596,34 +585,34 @@ __name(createRequestUrl, "createRequestUrl");
|
|
|
596
585
|
function createRequestHeaders(host, secure, body, cookies, encoding, headers) {
|
|
597
586
|
if (host != null && typeof host !== "string") {
|
|
598
587
|
throw new import_js_format8.InvalidArgumentError(
|
|
599
|
-
'
|
|
588
|
+
'Parameter "host" must be a non-empty String, but %v was given.',
|
|
600
589
|
host
|
|
601
590
|
);
|
|
602
591
|
}
|
|
603
592
|
host = host || "localhost";
|
|
604
593
|
if (secure != null && typeof secure !== "boolean") {
|
|
605
594
|
throw new import_js_format8.InvalidArgumentError(
|
|
606
|
-
'
|
|
595
|
+
'Parameter "secure" must be a String, but %v was given.',
|
|
607
596
|
secure
|
|
608
597
|
);
|
|
609
598
|
}
|
|
610
599
|
secure = Boolean(secure);
|
|
611
600
|
if (cookies != null && typeof cookies !== "object" && typeof cookies !== "string" || Array.isArray(cookies)) {
|
|
612
601
|
throw new import_js_format8.InvalidArgumentError(
|
|
613
|
-
'
|
|
602
|
+
'Parameter "cookies" must be a String or an Object, but %v was given.',
|
|
614
603
|
cookies
|
|
615
604
|
);
|
|
616
605
|
}
|
|
617
606
|
if (headers != null && typeof headers !== "object" || Array.isArray(headers)) {
|
|
618
607
|
throw new import_js_format8.InvalidArgumentError(
|
|
619
|
-
'
|
|
608
|
+
'Parameter "headers" must be an Object, but %v was given.',
|
|
620
609
|
headers
|
|
621
610
|
);
|
|
622
611
|
}
|
|
623
612
|
headers = headers || {};
|
|
624
613
|
if (encoding != null && typeof encoding !== "string") {
|
|
625
614
|
throw new import_js_format8.InvalidArgumentError(
|
|
626
|
-
'
|
|
615
|
+
'Parameter "encoding" must be a String, but %v was given.',
|
|
627
616
|
encoding
|
|
628
617
|
);
|
|
629
618
|
}
|
|
@@ -779,7 +768,7 @@ var import_js_format9 = require("@e22m4u/js-format");
|
|
|
779
768
|
function getRequestPathname(request) {
|
|
780
769
|
if (!request || typeof request !== "object" || Array.isArray(request) || typeof request.url !== "string") {
|
|
781
770
|
throw new import_js_format9.InvalidArgumentError(
|
|
782
|
-
'
|
|
771
|
+
'Parameter "request" must be an instance of IncomingMessage, but %v was given.',
|
|
783
772
|
request
|
|
784
773
|
);
|
|
785
774
|
}
|
|
@@ -902,7 +891,7 @@ var _RouterHookInvoker = class _RouterHookInvoker extends DebuggableService {
|
|
|
902
891
|
invokeAndContinueUntilValueReceived(route, hookType, response, ...args) {
|
|
903
892
|
if (!route || !(route instanceof Route)) {
|
|
904
893
|
throw new import_js_format11.InvalidArgumentError(
|
|
905
|
-
'Parameter "route" must be
|
|
894
|
+
'Parameter "route" must be an instance of Route, but %v was given.',
|
|
906
895
|
route
|
|
907
896
|
);
|
|
908
897
|
}
|
|
@@ -920,7 +909,7 @@ var _RouterHookInvoker = class _RouterHookInvoker extends DebuggableService {
|
|
|
920
909
|
}
|
|
921
910
|
if (!response || typeof response !== "object" || Array.isArray(response) || typeof response.headersSent !== "boolean") {
|
|
922
911
|
throw new import_js_format11.InvalidArgumentError(
|
|
923
|
-
'Parameter "response" must be
|
|
912
|
+
'Parameter "response" must be an instance of ServerResponse, but %v was given.',
|
|
924
913
|
response
|
|
925
914
|
);
|
|
926
915
|
}
|
|
@@ -1006,9 +995,15 @@ function validateRouteDefinition(routeDef) {
|
|
|
1006
995
|
routeDef.method
|
|
1007
996
|
);
|
|
1008
997
|
}
|
|
1009
|
-
if (
|
|
998
|
+
if (typeof routeDef.path !== "string") {
|
|
1010
999
|
throw new import_js_format12.InvalidArgumentError(
|
|
1011
|
-
'Option "path" must be a
|
|
1000
|
+
'Option "path" must be a String, but %v was given.',
|
|
1001
|
+
routeDef.path
|
|
1002
|
+
);
|
|
1003
|
+
}
|
|
1004
|
+
if (!routeDef.path.startsWith("/")) {
|
|
1005
|
+
throw new import_js_format12.InvalidArgumentError(
|
|
1006
|
+
'Option "path" must start with "/", but %v was given.',
|
|
1012
1007
|
routeDef.path
|
|
1013
1008
|
);
|
|
1014
1009
|
}
|
|
@@ -1023,7 +1018,7 @@ function validateRouteDefinition(routeDef) {
|
|
|
1023
1018
|
routeDef.preHandler.forEach((preHandler) => {
|
|
1024
1019
|
if (typeof preHandler !== "function") {
|
|
1025
1020
|
throw new import_js_format12.InvalidArgumentError(
|
|
1026
|
-
"
|
|
1021
|
+
'Hook "preHandler" must be a Function, but %v was given.',
|
|
1027
1022
|
preHandler
|
|
1028
1023
|
);
|
|
1029
1024
|
}
|
|
@@ -1040,7 +1035,7 @@ function validateRouteDefinition(routeDef) {
|
|
|
1040
1035
|
routeDef.postHandler.forEach((postHandler) => {
|
|
1041
1036
|
if (typeof postHandler !== "function") {
|
|
1042
1037
|
throw new import_js_format12.InvalidArgumentError(
|
|
1043
|
-
"
|
|
1038
|
+
'Hook "postHandler" must be a Function, but %v was given.',
|
|
1044
1039
|
postHandler
|
|
1045
1040
|
);
|
|
1046
1041
|
}
|
|
@@ -1208,7 +1203,7 @@ var _RouterOptions = class _RouterOptions extends DebuggableService {
|
|
|
1208
1203
|
setRequestBodyBytesLimit(input) {
|
|
1209
1204
|
if (typeof input !== "number" || input < 0) {
|
|
1210
1205
|
throw new import_js_format13.InvalidArgumentError(
|
|
1211
|
-
'
|
|
1206
|
+
'Option "requestBodyBytesLimit" must be a positive Number or 0, but %v was given.',
|
|
1212
1207
|
input
|
|
1213
1208
|
);
|
|
1214
1209
|
}
|
|
@@ -1243,13 +1238,13 @@ var _BodyParser = class _BodyParser extends DebuggableService {
|
|
|
1243
1238
|
defineParser(mediaType, parser) {
|
|
1244
1239
|
if (!mediaType || typeof mediaType !== "string") {
|
|
1245
1240
|
throw new import_js_format14.InvalidArgumentError(
|
|
1246
|
-
'
|
|
1241
|
+
'Parameter "mediaType" must be a non-empty String, but %v was given.',
|
|
1247
1242
|
mediaType
|
|
1248
1243
|
);
|
|
1249
1244
|
}
|
|
1250
1245
|
if (!parser || typeof parser !== "function") {
|
|
1251
1246
|
throw new import_js_format14.InvalidArgumentError(
|
|
1252
|
-
'
|
|
1247
|
+
'Parameter "parser" must be a Function, but %v was given.',
|
|
1253
1248
|
parser
|
|
1254
1249
|
);
|
|
1255
1250
|
}
|
|
@@ -1265,29 +1260,44 @@ var _BodyParser = class _BodyParser extends DebuggableService {
|
|
|
1265
1260
|
hasParser(mediaType) {
|
|
1266
1261
|
if (!mediaType || typeof mediaType !== "string") {
|
|
1267
1262
|
throw new import_js_format14.InvalidArgumentError(
|
|
1268
|
-
'
|
|
1263
|
+
'Parameter "mediaType" must be a non-empty String, but %v was given.',
|
|
1269
1264
|
mediaType
|
|
1270
1265
|
);
|
|
1271
1266
|
}
|
|
1272
1267
|
return Boolean(this._parsers[mediaType]);
|
|
1273
1268
|
}
|
|
1274
1269
|
/**
|
|
1275
|
-
*
|
|
1270
|
+
* Get parser.
|
|
1276
1271
|
*
|
|
1277
1272
|
* @param {string} mediaType
|
|
1278
|
-
* @returns {
|
|
1273
|
+
* @returns {Function}
|
|
1279
1274
|
*/
|
|
1280
|
-
|
|
1275
|
+
getParser(mediaType) {
|
|
1281
1276
|
if (!mediaType || typeof mediaType !== "string") {
|
|
1282
1277
|
throw new import_js_format14.InvalidArgumentError(
|
|
1283
|
-
'
|
|
1278
|
+
'Parameter "mediaType" must be a non-empty String, but %v was given.',
|
|
1284
1279
|
mediaType
|
|
1285
1280
|
);
|
|
1286
1281
|
}
|
|
1287
1282
|
const parser = this._parsers[mediaType];
|
|
1288
1283
|
if (!parser) {
|
|
1289
1284
|
throw new import_js_format14.InvalidArgumentError(
|
|
1290
|
-
"
|
|
1285
|
+
"Media type %v does not have a parser.",
|
|
1286
|
+
mediaType
|
|
1287
|
+
);
|
|
1288
|
+
}
|
|
1289
|
+
return parser;
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* Remove parser.
|
|
1293
|
+
*
|
|
1294
|
+
* @param {string} mediaType
|
|
1295
|
+
* @returns {this}
|
|
1296
|
+
*/
|
|
1297
|
+
removeParser(mediaType) {
|
|
1298
|
+
if (!mediaType || typeof mediaType !== "string") {
|
|
1299
|
+
throw new import_js_format14.InvalidArgumentError(
|
|
1300
|
+
'Parameter "mediaType" must be a non-empty String, but %v was given.',
|
|
1291
1301
|
mediaType
|
|
1292
1302
|
);
|
|
1293
1303
|
}
|
|
@@ -1442,7 +1452,7 @@ var _RequestParser = class _RequestParser extends DebuggableService {
|
|
|
1442
1452
|
parse(request) {
|
|
1443
1453
|
if (!(request instanceof import_http3.IncomingMessage)) {
|
|
1444
1454
|
throw new import_js_format15.InvalidArgumentError(
|
|
1445
|
-
"
|
|
1455
|
+
'Parameter "request" must be an instance of IncomingMessage, but %v was given.',
|
|
1446
1456
|
request
|
|
1447
1457
|
);
|
|
1448
1458
|
}
|
|
@@ -1497,7 +1507,7 @@ var _RouteRegistry = class _RouteRegistry extends DebuggableService {
|
|
|
1497
1507
|
const debug = this.getDebuggerFor(this.defineRoute);
|
|
1498
1508
|
if (!routeDef || typeof routeDef !== "object" || Array.isArray(routeDef)) {
|
|
1499
1509
|
throw new import_js_format16.InvalidArgumentError(
|
|
1500
|
-
"
|
|
1510
|
+
"Route definition must be an Object, but %v was given.",
|
|
1501
1511
|
routeDef
|
|
1502
1512
|
);
|
|
1503
1513
|
}
|
|
@@ -1721,28 +1731,28 @@ var _RequestContext = class _RequestContext {
|
|
|
1721
1731
|
constructor(container, request, response, route) {
|
|
1722
1732
|
if (!(0, import_js_service3.isServiceContainer)(container)) {
|
|
1723
1733
|
throw new import_js_format17.InvalidArgumentError(
|
|
1724
|
-
'
|
|
1734
|
+
'Parameter "container" must be an instance of ServiceContainer, but %v was given.',
|
|
1725
1735
|
container
|
|
1726
1736
|
);
|
|
1727
1737
|
}
|
|
1728
1738
|
this._container = container;
|
|
1729
1739
|
if (!request || typeof request !== "object" || Array.isArray(request) || !isReadableStream(request)) {
|
|
1730
1740
|
throw new import_js_format17.InvalidArgumentError(
|
|
1731
|
-
'
|
|
1741
|
+
'Parameter "request" must be an instance of IncomingMessage, but %v was given.',
|
|
1732
1742
|
request
|
|
1733
1743
|
);
|
|
1734
1744
|
}
|
|
1735
1745
|
this._request = request;
|
|
1736
1746
|
if (!response || typeof response !== "object" || Array.isArray(response) || !isWritableStream(response)) {
|
|
1737
1747
|
throw new import_js_format17.InvalidArgumentError(
|
|
1738
|
-
'
|
|
1748
|
+
'Parameter "response" must be an instance of ServerResponse, but %v was given.',
|
|
1739
1749
|
response
|
|
1740
1750
|
);
|
|
1741
1751
|
}
|
|
1742
1752
|
this._response = response;
|
|
1743
1753
|
if (!(route instanceof Route)) {
|
|
1744
1754
|
throw new import_js_format17.InvalidArgumentError(
|
|
1745
|
-
'
|
|
1755
|
+
'Parameter "route" must be an instance of Route, but %v was given.',
|
|
1746
1756
|
route
|
|
1747
1757
|
);
|
|
1748
1758
|
}
|
|
@@ -1774,16 +1784,22 @@ function validateRouterBranchDefinition(branchDef) {
|
|
|
1774
1784
|
branchDef.method
|
|
1775
1785
|
);
|
|
1776
1786
|
}
|
|
1777
|
-
if (
|
|
1787
|
+
if (branchDef.handler !== void 0) {
|
|
1788
|
+
throw new import_js_format18.InvalidArgumentError(
|
|
1789
|
+
'Option "handler" is not supported for the router branch, but %v was given.',
|
|
1790
|
+
branchDef.handler
|
|
1791
|
+
);
|
|
1792
|
+
}
|
|
1793
|
+
if (typeof branchDef.path !== "string") {
|
|
1778
1794
|
throw new import_js_format18.InvalidArgumentError(
|
|
1779
|
-
'Option "path" must be a
|
|
1795
|
+
'Option "path" must be a String, but %v was given.',
|
|
1780
1796
|
branchDef.path
|
|
1781
1797
|
);
|
|
1782
1798
|
}
|
|
1783
|
-
if (branchDef.
|
|
1799
|
+
if (!branchDef.path.startsWith("/")) {
|
|
1784
1800
|
throw new import_js_format18.InvalidArgumentError(
|
|
1785
|
-
'Option "
|
|
1786
|
-
branchDef.
|
|
1801
|
+
'Option "path" must start with "/", but %v was given.',
|
|
1802
|
+
branchDef.path
|
|
1787
1803
|
);
|
|
1788
1804
|
}
|
|
1789
1805
|
if (branchDef.preHandler !== void 0) {
|
|
@@ -1791,7 +1807,7 @@ function validateRouterBranchDefinition(branchDef) {
|
|
|
1791
1807
|
branchDef.preHandler.forEach((preHandler) => {
|
|
1792
1808
|
if (typeof preHandler !== "function") {
|
|
1793
1809
|
throw new import_js_format18.InvalidArgumentError(
|
|
1794
|
-
"
|
|
1810
|
+
'Hook "preHandler" must be a Function, but %v was given.',
|
|
1795
1811
|
preHandler
|
|
1796
1812
|
);
|
|
1797
1813
|
}
|
|
@@ -1808,7 +1824,7 @@ function validateRouterBranchDefinition(branchDef) {
|
|
|
1808
1824
|
branchDef.postHandler.forEach((postHandler) => {
|
|
1809
1825
|
if (typeof postHandler !== "function") {
|
|
1810
1826
|
throw new import_js_format18.InvalidArgumentError(
|
|
1811
|
-
"
|
|
1827
|
+
'Hook "postHandler" must be a Function, but %v was given.',
|
|
1812
1828
|
postHandler
|
|
1813
1829
|
);
|
|
1814
1830
|
}
|
|
@@ -1836,8 +1852,11 @@ function mergeRouterBranchDefinitions(firstDef, secondDef) {
|
|
|
1836
1852
|
validateRouterBranchDefinition(firstDef);
|
|
1837
1853
|
validateRouterBranchDefinition(secondDef);
|
|
1838
1854
|
const mergedDef = {};
|
|
1839
|
-
|
|
1840
|
-
|
|
1855
|
+
let fullPath = "/" + (firstDef.path || "");
|
|
1856
|
+
if (secondDef.path && secondDef.path !== "/") {
|
|
1857
|
+
fullPath += "/" + secondDef.path;
|
|
1858
|
+
}
|
|
1859
|
+
mergedDef.path = fullPath.replace(/\/+/g, "/");
|
|
1841
1860
|
if (firstDef.preHandler || secondDef.preHandler) {
|
|
1842
1861
|
mergedDef.preHandler = [firstDef.preHandler, secondDef.preHandler].flat().filter(Boolean);
|
|
1843
1862
|
}
|
|
@@ -1920,17 +1939,17 @@ var _RouterBranch = class _RouterBranch extends DebuggableService {
|
|
|
1920
1939
|
* @param {RouterBranch} [parentBranch]
|
|
1921
1940
|
*/
|
|
1922
1941
|
constructor(router, branchDef, parentBranch) {
|
|
1923
|
-
super(router.container);
|
|
1924
1942
|
if (!(router instanceof TrieRouter)) {
|
|
1925
1943
|
throw new import_js_format19.InvalidArgumentError(
|
|
1926
|
-
'Parameter "router" must be
|
|
1944
|
+
'Parameter "router" must be an instance of TrieRouter, but %v was given.',
|
|
1927
1945
|
router
|
|
1928
1946
|
);
|
|
1929
1947
|
}
|
|
1948
|
+
super(router.container);
|
|
1930
1949
|
this._router = router;
|
|
1931
1950
|
if (parentBranch !== void 0 && !(parentBranch instanceof _RouterBranch)) {
|
|
1932
1951
|
throw new import_js_format19.InvalidArgumentError(
|
|
1933
|
-
'Parameter "parentBranch" must be
|
|
1952
|
+
'Parameter "parentBranch" must be an instance of RouterBranch, but %v was given.',
|
|
1934
1953
|
parentBranch
|
|
1935
1954
|
);
|
|
1936
1955
|
}
|
|
@@ -1945,7 +1964,7 @@ var _RouterBranch = class _RouterBranch extends DebuggableService {
|
|
|
1945
1964
|
validateRouterBranchDefinition(branchDef);
|
|
1946
1965
|
this._definition = cloneDeep(branchDef);
|
|
1947
1966
|
}
|
|
1948
|
-
this.ctorDebug("Created a branch %v.",
|
|
1967
|
+
this.ctorDebug("Created a branch %v.", branchDef.path);
|
|
1949
1968
|
this.ctorDebug("Branch path is %v.", this._definition.path);
|
|
1950
1969
|
}
|
|
1951
1970
|
/**
|
|
@@ -2138,7 +2157,7 @@ var _TrieRouter = class _TrieRouter extends DebuggableService {
|
|
|
2138
2157
|
* ```
|
|
2139
2158
|
* const router = new TrieRouter();
|
|
2140
2159
|
* router.defineRoute({
|
|
2141
|
-
* method: HttpMethod.GET,
|
|
2160
|
+
* method: HttpMethod.GET, // Request method.
|
|
2142
2161
|
* path: '/', // Path template.
|
|
2143
2162
|
* handler: ctx => 'Hello world!', // Request handler.
|
|
2144
2163
|
* });
|
|
@@ -2150,9 +2169,9 @@ var _TrieRouter = class _TrieRouter extends DebuggableService {
|
|
|
2150
2169
|
* router.defineRoute({
|
|
2151
2170
|
* method: HttpMethod.POST, // Request method.
|
|
2152
2171
|
* path: '/users/:id', // The path template may have parameters.
|
|
2153
|
-
* preHandler(ctx) { ... }, // The "preHandler" executes before a route handler.
|
|
2154
|
-
* handler(ctx) { ... }, //
|
|
2155
|
-
* postHandler(ctx, data) { ... }, // The "postHandler" executes after a route handler.
|
|
2172
|
+
* preHandler(ctx) { ... }, // The hook "preHandler" executes before a route handler.
|
|
2173
|
+
* handler(ctx) { ... }, // Route handler function.
|
|
2174
|
+
* postHandler(ctx, data) { ... }, // The hook "postHandler" executes after a route handler.
|
|
2156
2175
|
* });
|
|
2157
2176
|
* ```
|
|
2158
2177
|
*
|
|
@@ -2338,7 +2357,6 @@ var TrieRouter = _TrieRouter;
|
|
|
2338
2357
|
isResponseSent,
|
|
2339
2358
|
isWritableStream,
|
|
2340
2359
|
mergeDeep,
|
|
2341
|
-
normalizePath,
|
|
2342
2360
|
parseContentType,
|
|
2343
2361
|
parseCookieString,
|
|
2344
2362
|
parseJsonBody,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e22m4u/js-trie-router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "HTTP маршрутизатор для Node.js на основе префиксного дерева",
|
|
5
5
|
"author": "Mikhail Evstropov <e22m4u@yandex.ru>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@e22m4u/js-debug": "~0.4.1",
|
|
42
|
-
"@e22m4u/js-format": "~0.
|
|
43
|
-
"@e22m4u/js-path-trie": "~0.
|
|
42
|
+
"@e22m4u/js-format": "~0.4.0",
|
|
43
|
+
"@e22m4u/js-path-trie": "~0.2.0",
|
|
44
44
|
"@e22m4u/js-service": "~0.5.1",
|
|
45
45
|
"debug": "~4.4.3",
|
|
46
46
|
"http-errors": "~2.0.1",
|
|
@@ -56,18 +56,18 @@
|
|
|
56
56
|
"c8": "~10.1.3",
|
|
57
57
|
"chai": "~6.2.2",
|
|
58
58
|
"chai-as-promised": "~8.0.2",
|
|
59
|
-
"esbuild": "~0.27.
|
|
59
|
+
"esbuild": "~0.27.3",
|
|
60
60
|
"eslint": "~9.39.2",
|
|
61
61
|
"eslint-config-prettier": "~10.1.8",
|
|
62
62
|
"eslint-plugin-chai-expect": "~3.1.0",
|
|
63
63
|
"eslint-plugin-import": "~2.32.0",
|
|
64
|
-
"eslint-plugin-jsdoc": "~62.
|
|
64
|
+
"eslint-plugin-jsdoc": "~62.6.0",
|
|
65
65
|
"eslint-plugin-mocha": "~11.2.0",
|
|
66
66
|
"globals": "~17.3.0",
|
|
67
67
|
"husky": "~9.1.7",
|
|
68
68
|
"mocha": "~11.7.5",
|
|
69
69
|
"prettier": "~3.8.1",
|
|
70
|
-
"rimraf": "~6.1.
|
|
70
|
+
"rimraf": "~6.1.3",
|
|
71
71
|
"typescript": "~5.9.3"
|
|
72
72
|
}
|
|
73
73
|
}
|