@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/esm/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Strongly typed route descriptor and URL builder.
|
|
3
5
|
*
|
|
@@ -138,14 +140,19 @@ declare class Route0<TDefinition extends string> {
|
|
|
138
140
|
getLocation(location: AnyLocation): KnownLocation<TDefinition>;
|
|
139
141
|
getLocation(url: AnyLocation): KnownLocation<TDefinition>;
|
|
140
142
|
getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): KnownLocation<TDefinition>;
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
143
|
+
private _validateParamsInput;
|
|
144
|
+
private _validateSearchInput;
|
|
145
|
+
private _validateFlatInput;
|
|
146
|
+
private _safeParseSchemaResult;
|
|
147
|
+
private _parseSchemaResult;
|
|
148
|
+
/** Standard Schema for route params input. */
|
|
149
|
+
readonly paramsInputSchema: Route0Schema<ParamsInput<TDefinition> | undefined, ParamsOutput<TDefinition>>;
|
|
150
|
+
/** Standard Schema for strict search input. */
|
|
151
|
+
readonly strictSearchInputSchema: Route0Schema<StrictSearchInput<TDefinition> | undefined, StrictSearchOutput<TDefinition>>;
|
|
152
|
+
/** Standard Schema for loose search input. */
|
|
153
|
+
readonly looseSearchInputSchema: Route0Schema<LooseSearchInput<TDefinition> | undefined, LooseSearchOutput<TDefinition>>;
|
|
154
|
+
/** Standard Schema for route flat input (uses route default strict/loose mode). */
|
|
155
|
+
readonly flatInputSchema: Route0Schema<FlatInput<TDefinition, HasLooseSearch<TDefinition>> | undefined, FlatOutput<TDefinition, HasLooseSearch<TDefinition>>>;
|
|
149
156
|
/** True when path structure is equal (param names are ignored). */
|
|
150
157
|
isSame(other: AnyRoute): boolean;
|
|
151
158
|
/** Static convenience wrapper for `isSame`. */
|
|
@@ -173,7 +180,7 @@ declare class Routes<const T extends RoutesRecord = any> {
|
|
|
173
180
|
_: {
|
|
174
181
|
routes: Routes<T>['_routes'];
|
|
175
182
|
getLocation: Routes<T>['_getLocation'];
|
|
176
|
-
|
|
183
|
+
clone: Routes<T>['_clone'];
|
|
177
184
|
pathsOrdering: Routes<T>['_pathsOrdering'];
|
|
178
185
|
keysOrdering: Routes<T>['_keysOrdering'];
|
|
179
186
|
ordered: Routes<T>['_ordered'];
|
|
@@ -197,7 +204,7 @@ declare class Routes<const T extends RoutesRecord = any> {
|
|
|
197
204
|
_getLocation(hrefOrHrefRelOrLocation: string | AnyLocation | URL): UnknownLocation | ExactLocation;
|
|
198
205
|
private static makeOrdering;
|
|
199
206
|
/** Returns a cloned routes collection with config applied to each route. */
|
|
200
|
-
|
|
207
|
+
_clone(config: RouteConfigInput): RoutesPretty<T>;
|
|
201
208
|
static _: {
|
|
202
209
|
prettify: typeof Routes.prettify;
|
|
203
210
|
hydrate: typeof Routes.hydrate;
|
|
@@ -221,7 +228,7 @@ type RoutesRecordHydrated<TRoutesRecord extends RoutesRecord = any> = {
|
|
|
221
228
|
[K in keyof TRoutesRecord]: CallableRoute<TRoutesRecord[K]>;
|
|
222
229
|
};
|
|
223
230
|
/** Public shape returned by `Routes.create()`. Default `any` so `satisfies RoutesPretty` accepts any created routes. */
|
|
224
|
-
type RoutesPretty<TRoutesRecord extends RoutesRecord = any> = RoutesRecordHydrated<TRoutesRecord> & Omit<Routes<TRoutesRecord>, '_routes' | '_getLocation' | '
|
|
231
|
+
type RoutesPretty<TRoutesRecord extends RoutesRecord = any> = RoutesRecordHydrated<TRoutesRecord> & Omit<Routes<TRoutesRecord>, '_routes' | '_getLocation' | '_clone' | '_pathsOrdering' | '_keysOrdering' | '_ordered'>;
|
|
225
232
|
type ExtractRoutesKeys<TRoutes extends RoutesPretty | RoutesRecord> = TRoutes extends RoutesPretty ? Extract<keyof TRoutes['_']['routes'], string> : TRoutes extends RoutesRecord ? Extract<keyof TRoutes, string> : never;
|
|
226
233
|
type ExtractRoute<TRoutes extends RoutesPretty | RoutesRecord, TKey extends ExtractRoutesKeys<TRoutes>> = TRoutes extends RoutesPretty ? TRoutes['_']['routes'][TKey] : TRoutes extends RoutesRecord ? TRoutes[TKey] : never;
|
|
227
234
|
type Definition<T extends AnyRoute | string> = T extends AnyRoute ? T['definition'] : T extends string ? T : never;
|
|
@@ -508,5 +515,9 @@ type _SafeParseInputResult<TInputParsed extends Record<string, unknown>> = {
|
|
|
508
515
|
};
|
|
509
516
|
type SafeParseInputStrictResult<TDefinition extends string> = _SafeParseInputResult<StrictFlatOutput<TDefinition>>;
|
|
510
517
|
type SafeParseInputLooseResult<TDefinition extends string> = _SafeParseInputResult<LooseFlatOutput<TDefinition>>;
|
|
518
|
+
type Route0Schema<TInput extends Record<string, unknown> | undefined, TOutput extends Record<string, unknown>> = StandardSchemaV1<TInput, TOutput> & {
|
|
519
|
+
parse: (input: unknown) => TOutput;
|
|
520
|
+
safeParse: (input: unknown) => _SafeParseInputResult<TOutput>;
|
|
521
|
+
};
|
|
511
522
|
|
|
512
|
-
export { type AmpSplit, type AncestorLocation, type AncestorLocationState, type AnyLocation, type AnyRoute, type AnyRouteOrDefinition, type CallableRoute, type CanInputBeEmpty, type DedupeSlashes, type Definition, type DescendantLocation, type DescendantLocationState, type EmptyRecord, type ExactLocation, type ExactLocationState, type Extended, type ExtractPathParams, type ExtractRoute, type ExtractRoutesKeys, type FlatInput, type FlatInputStringOnly, type FlatInputWithHash, type FlatOutput, type FlatOutputWithHash, type HasLooseSearch, type HasNamedSearch, type HasParams, type HasSearch, type IsAncestor, type IsDescendant, type IsSame, type IsSameParams, type JoinPath, type KnownLocation, type LocationParams, type LocationSearch, type LooseFlatInput, type LooseFlatInputStringOnly, type LooseFlatInputWithHash, type LooseFlatOutput, type LooseFlatOutputWithHash, type LooseSearchInput, type LooseSearchInputStringOnly, type LooseSearchOutput, type NonEmpty, type OnlyIfHasParams, type OnlyIfNoParams, type ParamsDefinition, type ParamsInput, type ParamsInputStringOnly, type ParamsOutput, type PathDefinition, type PathExtended, type ReplacePathParams, Route0, type RouteConfigInput, Routes, type RoutesPretty, type RoutesRecord, type RoutesRecordHydrated, type SafeParseInputLooseResult, type SafeParseInputStrictResult, type SearchDefinition, type SearchTailDefinitionWithFirstAmp, type SearchTailDefinitionWithoutFirstAmp, type SearchTailDefinitionWithoutFirstAndLastAmp, type StrictFlatInput, type StrictFlatInputStringOnly, type StrictFlatInputWithHash, type StrictFlatOutput, type StrictFlatOutputWithHash, type StrictSearchInput, type StrictSearchInputStringOnly, type StrictSearchOutput, type TrimSearchTailDefinition, type UnknownLocation, type UnknownLocationState, type UnmatchedLocation, type UnmatchedLocationState, type WeakAncestorLocation, type WeakAncestorLocationState, type WeakDescendantLocation, type WeakDescendantLocationState, type WithParamsInput, type _GeneralLocation, type _IsAncestor, type _IsDescendant, type _IsSame, type _IsSameParams, type _LooseFlatInput, type _LooseFlatInputStringOnly, type _LooseSearchInput, type _LooseSearchInputStringOnly, type _ParamsDefinition, type _ParamsInput, type _ParamsInputStringOnly, type _PathDefinition, type _SafeParseInputResult, type _SearchDefinition, type _StrictFlatInput, type _StrictFlatInputStringOnly, type _StrictSearchInput, type _StrictSearchInputStringOnly };
|
|
523
|
+
export { type AmpSplit, type AncestorLocation, type AncestorLocationState, type AnyLocation, type AnyRoute, type AnyRouteOrDefinition, type CallableRoute, type CanInputBeEmpty, type DedupeSlashes, type Definition, type DescendantLocation, type DescendantLocationState, type EmptyRecord, type ExactLocation, type ExactLocationState, type Extended, type ExtractPathParams, type ExtractRoute, type ExtractRoutesKeys, type FlatInput, type FlatInputStringOnly, type FlatInputWithHash, type FlatOutput, type FlatOutputWithHash, type HasLooseSearch, type HasNamedSearch, type HasParams, type HasSearch, type IsAncestor, type IsDescendant, type IsSame, type IsSameParams, type JoinPath, type KnownLocation, type LocationParams, type LocationSearch, type LooseFlatInput, type LooseFlatInputStringOnly, type LooseFlatInputWithHash, type LooseFlatOutput, type LooseFlatOutputWithHash, type LooseSearchInput, type LooseSearchInputStringOnly, type LooseSearchOutput, type NonEmpty, type OnlyIfHasParams, type OnlyIfNoParams, type ParamsDefinition, type ParamsInput, type ParamsInputStringOnly, type ParamsOutput, type PathDefinition, type PathExtended, type ReplacePathParams, Route0, type Route0Schema, type RouteConfigInput, Routes, type RoutesPretty, type RoutesRecord, type RoutesRecordHydrated, type SafeParseInputLooseResult, type SafeParseInputStrictResult, type SearchDefinition, type SearchTailDefinitionWithFirstAmp, type SearchTailDefinitionWithoutFirstAmp, type SearchTailDefinitionWithoutFirstAndLastAmp, type StrictFlatInput, type StrictFlatInputStringOnly, type StrictFlatInputWithHash, type StrictFlatOutput, type StrictFlatOutputWithHash, type StrictSearchInput, type StrictSearchInputStringOnly, type StrictSearchOutput, type TrimSearchTailDefinition, type UnknownLocation, type UnknownLocationState, type UnmatchedLocation, type UnmatchedLocationState, type WeakAncestorLocation, type WeakAncestorLocationState, type WeakDescendantLocation, type WeakDescendantLocationState, type WithParamsInput, type _GeneralLocation, type _IsAncestor, type _IsDescendant, type _IsSame, type _IsSameParams, type _LooseFlatInput, type _LooseFlatInputStringOnly, type _LooseSearchInput, type _LooseSearchInputStringOnly, type _ParamsDefinition, type _ParamsInput, type _ParamsInputStringOnly, type _PathDefinition, type _SafeParseInputResult, type _SearchDefinition, type _StrictFlatInput, type _StrictFlatInputStringOnly, type _StrictSearchInput, type _StrictSearchInputStringOnly };
|
package/dist/esm/index.js
CHANGED
|
@@ -9,7 +9,7 @@ class Route0 {
|
|
|
9
9
|
get origin() {
|
|
10
10
|
if (!this._origin) {
|
|
11
11
|
throw new Error(
|
|
12
|
-
"origin for route " + this.definition + ' is not set, please provide it like Route0.create(route, {origin: "https://example.com"}) in config or set via
|
|
12
|
+
"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"})'
|
|
13
13
|
);
|
|
14
14
|
}
|
|
15
15
|
return this._origin;
|
|
@@ -434,76 +434,171 @@ class Route0 {
|
|
|
434
434
|
unmatched
|
|
435
435
|
};
|
|
436
436
|
}
|
|
437
|
-
|
|
438
|
-
* Safe parser for flat input objects.
|
|
439
|
-
*
|
|
440
|
-
* Returns structured success/error result instead of throwing.
|
|
441
|
-
*/
|
|
442
|
-
safeParseFlatInput(input, loose) {
|
|
443
|
-
loose ??= this.hasLooseSearch;
|
|
437
|
+
_validateParamsInput(input) {
|
|
444
438
|
const paramsKeys = this.getParamsKeys();
|
|
445
439
|
if (input === void 0) {
|
|
446
440
|
if (paramsKeys.length) {
|
|
447
441
|
return {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
442
|
+
issues: [
|
|
443
|
+
{
|
|
444
|
+
message: `Missing params: ${paramsKeys.map((k) => `"${k}"`).join(", ")}`
|
|
445
|
+
}
|
|
446
|
+
]
|
|
451
447
|
};
|
|
452
448
|
}
|
|
453
449
|
input = {};
|
|
454
450
|
}
|
|
455
451
|
if (typeof input !== "object" || input === null) {
|
|
456
452
|
return {
|
|
457
|
-
|
|
458
|
-
data: void 0,
|
|
459
|
-
error: new Error("Invalid input: expected object")
|
|
453
|
+
issues: [{ message: "Invalid input: expected object" }]
|
|
460
454
|
};
|
|
461
455
|
}
|
|
462
|
-
const
|
|
456
|
+
const inputObj = input;
|
|
457
|
+
const inputKeys = Object.keys(inputObj);
|
|
463
458
|
const notDefinedKeys = paramsKeys.filter((k) => !inputKeys.includes(k));
|
|
464
459
|
if (notDefinedKeys.length) {
|
|
465
460
|
return {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
461
|
+
issues: [
|
|
462
|
+
{
|
|
463
|
+
message: `Missing params: ${notDefinedKeys.map((k) => `"${k}"`).join(", ")}`
|
|
464
|
+
}
|
|
465
|
+
]
|
|
469
466
|
};
|
|
470
467
|
}
|
|
471
468
|
const data = {};
|
|
472
|
-
const
|
|
473
|
-
|
|
474
|
-
if (
|
|
475
|
-
|
|
469
|
+
for (const k of paramsKeys) {
|
|
470
|
+
const v = inputObj[k];
|
|
471
|
+
if (typeof v === "string") {
|
|
472
|
+
data[k] = v;
|
|
473
|
+
} else if (typeof v === "number") {
|
|
474
|
+
data[k] = String(v);
|
|
475
|
+
} else {
|
|
476
|
+
return {
|
|
477
|
+
issues: [{ message: `Invalid input: expected string, number, got ${typeof v} for "${k}"` }]
|
|
478
|
+
};
|
|
476
479
|
}
|
|
480
|
+
}
|
|
481
|
+
return {
|
|
482
|
+
value: data
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
_validateSearchInput(input, loose) {
|
|
486
|
+
if (input === void 0) {
|
|
487
|
+
input = {};
|
|
488
|
+
}
|
|
489
|
+
if (typeof input !== "object" || input === null) {
|
|
490
|
+
return {
|
|
491
|
+
issues: [{ message: "Invalid input: expected object" }]
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
const inputObj = input;
|
|
495
|
+
const paramsKeys = this.getParamsKeys();
|
|
496
|
+
const searchKeys = this.getSearchKeys();
|
|
497
|
+
const data = {};
|
|
498
|
+
for (const [k, v] of Object.entries(inputObj)) {
|
|
499
|
+
if (k === "hash") continue;
|
|
500
|
+
if (paramsKeys.includes(k)) continue;
|
|
501
|
+
if (!loose && !searchKeys.includes(k)) continue;
|
|
502
|
+
if (v === void 0) continue;
|
|
477
503
|
if (typeof v === "string") {
|
|
478
504
|
data[k] = v;
|
|
479
505
|
} else if (typeof v === "number") {
|
|
480
506
|
data[k] = String(v);
|
|
481
507
|
} else {
|
|
482
|
-
const isParamKey = paramsKeys.includes(k);
|
|
483
508
|
return {
|
|
484
|
-
|
|
485
|
-
data: void 0,
|
|
486
|
-
error: new Error(
|
|
487
|
-
`Invalid input: expected string, number,${!isParamKey ? " or undefined," : ""} got ${typeof v} for "${k}"`
|
|
488
|
-
)
|
|
509
|
+
issues: [{ message: `Invalid input: expected string, number, or undefined, got ${typeof v} for "${k}"` }]
|
|
489
510
|
};
|
|
490
511
|
}
|
|
491
512
|
}
|
|
492
513
|
return {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
514
|
+
value: data
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
_validateFlatInput(input, loose) {
|
|
518
|
+
const paramsResult = this._validateParamsInput(input);
|
|
519
|
+
if ("issues" in paramsResult) {
|
|
520
|
+
return {
|
|
521
|
+
issues: paramsResult.issues ?? []
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
const searchResult = this._validateSearchInput(input, loose);
|
|
525
|
+
if ("issues" in searchResult) {
|
|
526
|
+
return {
|
|
527
|
+
issues: searchResult.issues ?? []
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
return {
|
|
531
|
+
value: {
|
|
532
|
+
...searchResult.value,
|
|
533
|
+
...paramsResult.value
|
|
534
|
+
}
|
|
496
535
|
};
|
|
497
536
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
537
|
+
_safeParseSchemaResult(result) {
|
|
538
|
+
if ("issues" in result) {
|
|
539
|
+
return {
|
|
540
|
+
success: false,
|
|
541
|
+
data: void 0,
|
|
542
|
+
error: new Error(result.issues?.[0]?.message ?? "Invalid input")
|
|
543
|
+
};
|
|
504
544
|
}
|
|
505
|
-
return
|
|
545
|
+
return {
|
|
546
|
+
success: true,
|
|
547
|
+
data: result.value,
|
|
548
|
+
error: void 0
|
|
549
|
+
};
|
|
506
550
|
}
|
|
551
|
+
_parseSchemaResult(result) {
|
|
552
|
+
const safeResult = this._safeParseSchemaResult(result);
|
|
553
|
+
if (safeResult.error) {
|
|
554
|
+
throw safeResult.error;
|
|
555
|
+
}
|
|
556
|
+
return safeResult.data;
|
|
557
|
+
}
|
|
558
|
+
/** Standard Schema for route params input. */
|
|
559
|
+
paramsInputSchema = {
|
|
560
|
+
"~standard": {
|
|
561
|
+
version: 1,
|
|
562
|
+
vendor: "route0",
|
|
563
|
+
validate: (value) => this._validateParamsInput(value),
|
|
564
|
+
types: void 0
|
|
565
|
+
},
|
|
566
|
+
parse: (value) => this._parseSchemaResult(this._validateParamsInput(value)),
|
|
567
|
+
safeParse: (value) => this._safeParseSchemaResult(this._validateParamsInput(value))
|
|
568
|
+
};
|
|
569
|
+
/** Standard Schema for strict search input. */
|
|
570
|
+
strictSearchInputSchema = {
|
|
571
|
+
"~standard": {
|
|
572
|
+
version: 1,
|
|
573
|
+
vendor: "route0",
|
|
574
|
+
validate: (value) => this._validateSearchInput(value, false),
|
|
575
|
+
types: void 0
|
|
576
|
+
},
|
|
577
|
+
parse: (value) => this._parseSchemaResult(this._validateSearchInput(value, false)),
|
|
578
|
+
safeParse: (value) => this._safeParseSchemaResult(this._validateSearchInput(value, false))
|
|
579
|
+
};
|
|
580
|
+
/** Standard Schema for loose search input. */
|
|
581
|
+
looseSearchInputSchema = {
|
|
582
|
+
"~standard": {
|
|
583
|
+
version: 1,
|
|
584
|
+
vendor: "route0",
|
|
585
|
+
validate: (value) => this._validateSearchInput(value, true),
|
|
586
|
+
types: void 0
|
|
587
|
+
},
|
|
588
|
+
parse: (value) => this._parseSchemaResult(this._validateSearchInput(value, true)),
|
|
589
|
+
safeParse: (value) => this._safeParseSchemaResult(this._validateSearchInput(value, true))
|
|
590
|
+
};
|
|
591
|
+
/** Standard Schema for route flat input (uses route default strict/loose mode). */
|
|
592
|
+
flatInputSchema = {
|
|
593
|
+
"~standard": {
|
|
594
|
+
version: 1,
|
|
595
|
+
vendor: "route0",
|
|
596
|
+
validate: (value) => this._validateFlatInput(value, this.hasLooseSearch),
|
|
597
|
+
types: void 0
|
|
598
|
+
},
|
|
599
|
+
parse: (value) => this._parseSchemaResult(this._validateFlatInput(value, this.hasLooseSearch)),
|
|
600
|
+
safeParse: (value) => this._safeParseSchemaResult(this._validateFlatInput(value, this.hasLooseSearch))
|
|
601
|
+
};
|
|
507
602
|
/** True when path structure is equal (param names are ignored). */
|
|
508
603
|
isSame(other) {
|
|
509
604
|
return this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, "__PARAM__") === other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, "__PARAM__");
|
|
@@ -631,7 +726,7 @@ class Routes {
|
|
|
631
726
|
this._ = {
|
|
632
727
|
routes: this._routes,
|
|
633
728
|
getLocation: this._getLocation.bind(this),
|
|
634
|
-
|
|
729
|
+
clone: this._clone.bind(this),
|
|
635
730
|
pathsOrdering: this._pathsOrdering,
|
|
636
731
|
keysOrdering: this._keysOrdering,
|
|
637
732
|
ordered: this._ordered
|
|
@@ -643,7 +738,7 @@ class Routes {
|
|
|
643
738
|
if (!override) {
|
|
644
739
|
return result;
|
|
645
740
|
}
|
|
646
|
-
return result._.
|
|
741
|
+
return result._.clone(override);
|
|
647
742
|
}
|
|
648
743
|
static prettify(instance) {
|
|
649
744
|
Object.setPrototypeOf(instance, Routes.prototype);
|
|
@@ -651,7 +746,7 @@ class Routes {
|
|
|
651
746
|
value: "Routes"
|
|
652
747
|
});
|
|
653
748
|
Object.assign(instance, {
|
|
654
|
-
|
|
749
|
+
clone: instance._clone.bind(instance)
|
|
655
750
|
});
|
|
656
751
|
Object.assign(instance, instance._routes);
|
|
657
752
|
return instance;
|
|
@@ -700,7 +795,7 @@ class Routes {
|
|
|
700
795
|
return { pathsOrdering, keysOrdering };
|
|
701
796
|
}
|
|
702
797
|
/** Returns a cloned routes collection with config applied to each route. */
|
|
703
|
-
|
|
798
|
+
_clone(config) {
|
|
704
799
|
const newRoutes = {};
|
|
705
800
|
for (const key in this._routes) {
|
|
706
801
|
if (Object.hasOwn(this._routes, key)) {
|