@devp0nt/route0 1.0.0-next.64 → 1.0.0-next.66
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 -42
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +23 -12
- package/dist/esm/index.d.ts +23 -12
- package/dist/esm/index.js +137 -42
- package/dist/esm/index.js.map +1 -1
- package/package.json +3 -2
- package/src/index.test.ts +112 -160
- package/src/index.ts +188 -51
package/dist/cjs/index.cjs
CHANGED
|
@@ -33,7 +33,7 @@ class Route0 {
|
|
|
33
33
|
get origin() {
|
|
34
34
|
if (!this._origin) {
|
|
35
35
|
throw new Error(
|
|
36
|
-
"origin for route " + this.definition + ' is not set, please provide it like Route0.create(route, {origin: "https://example.com"}) in config or set via
|
|
36
|
+
"origin for route " + this.definition + ' is not set, please provide it like Route0.create(route, {origin: "https://example.com"}) in config or set via clones like routes._.clone({origin: "https://example.com"})'
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
39
|
return this._origin;
|
|
@@ -458,76 +458,171 @@ class Route0 {
|
|
|
458
458
|
unmatched
|
|
459
459
|
};
|
|
460
460
|
}
|
|
461
|
-
|
|
462
|
-
* Safe parser for flat input objects.
|
|
463
|
-
*
|
|
464
|
-
* Returns structured success/error result instead of throwing.
|
|
465
|
-
*/
|
|
466
|
-
safeParseFlatInput(input, loose) {
|
|
467
|
-
loose ??= this.hasLooseSearch;
|
|
461
|
+
_validateParamsInput(input) {
|
|
468
462
|
const paramsKeys = this.getParamsKeys();
|
|
469
463
|
if (input === void 0) {
|
|
470
464
|
if (paramsKeys.length) {
|
|
471
465
|
return {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
466
|
+
issues: [
|
|
467
|
+
{
|
|
468
|
+
message: `Missing params: ${paramsKeys.map((k) => `"${k}"`).join(", ")}`
|
|
469
|
+
}
|
|
470
|
+
]
|
|
475
471
|
};
|
|
476
472
|
}
|
|
477
473
|
input = {};
|
|
478
474
|
}
|
|
479
475
|
if (typeof input !== "object" || input === null) {
|
|
480
476
|
return {
|
|
481
|
-
|
|
482
|
-
data: void 0,
|
|
483
|
-
error: new Error("Invalid input: expected object")
|
|
477
|
+
issues: [{ message: "Invalid input: expected object" }]
|
|
484
478
|
};
|
|
485
479
|
}
|
|
486
|
-
const
|
|
480
|
+
const inputObj = input;
|
|
481
|
+
const inputKeys = Object.keys(inputObj);
|
|
487
482
|
const notDefinedKeys = paramsKeys.filter((k) => !inputKeys.includes(k));
|
|
488
483
|
if (notDefinedKeys.length) {
|
|
489
484
|
return {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
485
|
+
issues: [
|
|
486
|
+
{
|
|
487
|
+
message: `Missing params: ${notDefinedKeys.map((k) => `"${k}"`).join(", ")}`
|
|
488
|
+
}
|
|
489
|
+
]
|
|
493
490
|
};
|
|
494
491
|
}
|
|
495
492
|
const data = {};
|
|
496
|
-
const
|
|
497
|
-
|
|
498
|
-
if (
|
|
499
|
-
|
|
493
|
+
for (const k of paramsKeys) {
|
|
494
|
+
const v = inputObj[k];
|
|
495
|
+
if (typeof v === "string") {
|
|
496
|
+
data[k] = v;
|
|
497
|
+
} else if (typeof v === "number") {
|
|
498
|
+
data[k] = String(v);
|
|
499
|
+
} else {
|
|
500
|
+
return {
|
|
501
|
+
issues: [{ message: `Invalid input: expected string, number, got ${typeof v} for "${k}"` }]
|
|
502
|
+
};
|
|
500
503
|
}
|
|
504
|
+
}
|
|
505
|
+
return {
|
|
506
|
+
value: data
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
_validateSearchInput(input, loose) {
|
|
510
|
+
if (input === void 0) {
|
|
511
|
+
input = {};
|
|
512
|
+
}
|
|
513
|
+
if (typeof input !== "object" || input === null) {
|
|
514
|
+
return {
|
|
515
|
+
issues: [{ message: "Invalid input: expected object" }]
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
const inputObj = input;
|
|
519
|
+
const paramsKeys = this.getParamsKeys();
|
|
520
|
+
const searchKeys = this.getSearchKeys();
|
|
521
|
+
const data = {};
|
|
522
|
+
for (const [k, v] of Object.entries(inputObj)) {
|
|
523
|
+
if (k === "hash") continue;
|
|
524
|
+
if (paramsKeys.includes(k)) continue;
|
|
525
|
+
if (!loose && !searchKeys.includes(k)) continue;
|
|
526
|
+
if (v === void 0) continue;
|
|
501
527
|
if (typeof v === "string") {
|
|
502
528
|
data[k] = v;
|
|
503
529
|
} else if (typeof v === "number") {
|
|
504
530
|
data[k] = String(v);
|
|
505
531
|
} else {
|
|
506
|
-
const isParamKey = paramsKeys.includes(k);
|
|
507
532
|
return {
|
|
508
|
-
|
|
509
|
-
data: void 0,
|
|
510
|
-
error: new Error(
|
|
511
|
-
`Invalid input: expected string, number,${!isParamKey ? " or undefined," : ""} got ${typeof v} for "${k}"`
|
|
512
|
-
)
|
|
533
|
+
issues: [{ message: `Invalid input: expected string, number, or undefined, got ${typeof v} for "${k}"` }]
|
|
513
534
|
};
|
|
514
535
|
}
|
|
515
536
|
}
|
|
516
537
|
return {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
538
|
+
value: data
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
_validateFlatInput(input, loose) {
|
|
542
|
+
const paramsResult = this._validateParamsInput(input);
|
|
543
|
+
if ("issues" in paramsResult) {
|
|
544
|
+
return {
|
|
545
|
+
issues: paramsResult.issues ?? []
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
const searchResult = this._validateSearchInput(input, loose);
|
|
549
|
+
if ("issues" in searchResult) {
|
|
550
|
+
return {
|
|
551
|
+
issues: searchResult.issues ?? []
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
return {
|
|
555
|
+
value: {
|
|
556
|
+
...searchResult.value,
|
|
557
|
+
...paramsResult.value
|
|
558
|
+
}
|
|
520
559
|
};
|
|
521
560
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
561
|
+
_safeParseSchemaResult(result) {
|
|
562
|
+
if ("issues" in result) {
|
|
563
|
+
return {
|
|
564
|
+
success: false,
|
|
565
|
+
data: void 0,
|
|
566
|
+
error: new Error(result.issues?.[0]?.message ?? "Invalid input")
|
|
567
|
+
};
|
|
528
568
|
}
|
|
529
|
-
return
|
|
569
|
+
return {
|
|
570
|
+
success: true,
|
|
571
|
+
data: result.value,
|
|
572
|
+
error: void 0
|
|
573
|
+
};
|
|
530
574
|
}
|
|
575
|
+
_parseSchemaResult(result) {
|
|
576
|
+
const safeResult = this._safeParseSchemaResult(result);
|
|
577
|
+
if (safeResult.error) {
|
|
578
|
+
throw safeResult.error;
|
|
579
|
+
}
|
|
580
|
+
return safeResult.data;
|
|
581
|
+
}
|
|
582
|
+
/** Standard Schema for route params input. */
|
|
583
|
+
paramsInputSchema = {
|
|
584
|
+
"~standard": {
|
|
585
|
+
version: 1,
|
|
586
|
+
vendor: "route0",
|
|
587
|
+
validate: (value) => this._validateParamsInput(value),
|
|
588
|
+
types: void 0
|
|
589
|
+
},
|
|
590
|
+
parse: (value) => this._parseSchemaResult(this._validateParamsInput(value)),
|
|
591
|
+
safeParse: (value) => this._safeParseSchemaResult(this._validateParamsInput(value))
|
|
592
|
+
};
|
|
593
|
+
/** Standard Schema for strict search input. */
|
|
594
|
+
strictSearchInputSchema = {
|
|
595
|
+
"~standard": {
|
|
596
|
+
version: 1,
|
|
597
|
+
vendor: "route0",
|
|
598
|
+
validate: (value) => this._validateSearchInput(value, false),
|
|
599
|
+
types: void 0
|
|
600
|
+
},
|
|
601
|
+
parse: (value) => this._parseSchemaResult(this._validateSearchInput(value, false)),
|
|
602
|
+
safeParse: (value) => this._safeParseSchemaResult(this._validateSearchInput(value, false))
|
|
603
|
+
};
|
|
604
|
+
/** Standard Schema for loose search input. */
|
|
605
|
+
looseSearchInputSchema = {
|
|
606
|
+
"~standard": {
|
|
607
|
+
version: 1,
|
|
608
|
+
vendor: "route0",
|
|
609
|
+
validate: (value) => this._validateSearchInput(value, true),
|
|
610
|
+
types: void 0
|
|
611
|
+
},
|
|
612
|
+
parse: (value) => this._parseSchemaResult(this._validateSearchInput(value, true)),
|
|
613
|
+
safeParse: (value) => this._safeParseSchemaResult(this._validateSearchInput(value, true))
|
|
614
|
+
};
|
|
615
|
+
/** Standard Schema for route flat input (uses route default strict/loose mode). */
|
|
616
|
+
flatInputSchema = {
|
|
617
|
+
"~standard": {
|
|
618
|
+
version: 1,
|
|
619
|
+
vendor: "route0",
|
|
620
|
+
validate: (value) => this._validateFlatInput(value, this.hasLooseSearch),
|
|
621
|
+
types: void 0
|
|
622
|
+
},
|
|
623
|
+
parse: (value) => this._parseSchemaResult(this._validateFlatInput(value, this.hasLooseSearch)),
|
|
624
|
+
safeParse: (value) => this._safeParseSchemaResult(this._validateFlatInput(value, this.hasLooseSearch))
|
|
625
|
+
};
|
|
531
626
|
/** True when path structure is equal (param names are ignored). */
|
|
532
627
|
isSame(other) {
|
|
533
628
|
return this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, "__PARAM__") === other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, "__PARAM__");
|
|
@@ -655,7 +750,7 @@ class Routes {
|
|
|
655
750
|
this._ = {
|
|
656
751
|
routes: this._routes,
|
|
657
752
|
getLocation: this._getLocation.bind(this),
|
|
658
|
-
|
|
753
|
+
clone: this._clone.bind(this),
|
|
659
754
|
pathsOrdering: this._pathsOrdering,
|
|
660
755
|
keysOrdering: this._keysOrdering,
|
|
661
756
|
ordered: this._ordered
|
|
@@ -667,7 +762,7 @@ class Routes {
|
|
|
667
762
|
if (!override) {
|
|
668
763
|
return result;
|
|
669
764
|
}
|
|
670
|
-
return result._.
|
|
765
|
+
return result._.clone(override);
|
|
671
766
|
}
|
|
672
767
|
static prettify(instance) {
|
|
673
768
|
Object.setPrototypeOf(instance, Routes.prototype);
|
|
@@ -675,7 +770,7 @@ class Routes {
|
|
|
675
770
|
value: "Routes"
|
|
676
771
|
});
|
|
677
772
|
Object.assign(instance, {
|
|
678
|
-
|
|
773
|
+
clone: instance._clone.bind(instance)
|
|
679
774
|
});
|
|
680
775
|
Object.assign(instance, instance._routes);
|
|
681
776
|
return instance;
|
|
@@ -724,7 +819,7 @@ class Routes {
|
|
|
724
819
|
return { pathsOrdering, keysOrdering };
|
|
725
820
|
}
|
|
726
821
|
/** Returns a cloned routes collection with config applied to each route. */
|
|
727
|
-
|
|
822
|
+
_clone(config) {
|
|
728
823
|
const newRoutes = {};
|
|
729
824
|
for (const key in this._routes) {
|
|
730
825
|
if (Object.hasOwn(this._routes, key)) {
|