@devp0nt/route0 1.0.0-next.73 → 1.0.0-next.75
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 +104 -25
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +24 -11
- package/dist/esm/index.d.ts +24 -11
- package/dist/esm/index.js +104 -25
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cjs/index.d.cts
CHANGED
|
@@ -28,6 +28,16 @@ declare class Route0<TDefinition extends string, TSearchInput extends UnknownSea
|
|
|
28
28
|
readonly params: _ParamsDefinition<TDefinition>;
|
|
29
29
|
private _origin;
|
|
30
30
|
private _callable;
|
|
31
|
+
private _regexBaseStrictString?;
|
|
32
|
+
private _regexBaseString?;
|
|
33
|
+
private _regexStrictString?;
|
|
34
|
+
private _regexString?;
|
|
35
|
+
private _regexStrict?;
|
|
36
|
+
private _regex?;
|
|
37
|
+
private _regexAncestor?;
|
|
38
|
+
private _captureKeys?;
|
|
39
|
+
private _normalizedDefinition?;
|
|
40
|
+
private _definitionParts?;
|
|
31
41
|
Infer: {
|
|
32
42
|
ParamsDefinition: _ParamsDefinition<TDefinition>;
|
|
33
43
|
ParamsInput: _ParamsInput<TDefinition>;
|
|
@@ -63,12 +73,18 @@ declare class Route0<TDefinition extends string, TSearchInput extends UnknownSea
|
|
|
63
73
|
getTokens(): RouteToken[];
|
|
64
74
|
/** Clones route with optional config override. */
|
|
65
75
|
clone(config?: RouteConfigInput): CallableRoute<TDefinition>;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
76
|
+
get regexBaseStrictString(): string;
|
|
77
|
+
get regexBaseString(): string;
|
|
78
|
+
get regexStrictString(): string;
|
|
79
|
+
get regexString(): string;
|
|
80
|
+
get regexStrict(): RegExp;
|
|
81
|
+
get regex(): RegExp;
|
|
82
|
+
get regexAncestor(): RegExp;
|
|
83
|
+
private get captureKeys();
|
|
84
|
+
private get normalizedDefinition();
|
|
85
|
+
private get definitionParts();
|
|
86
|
+
/** Fast pathname check without building a full location object. */
|
|
87
|
+
isExactPathnameMatch(pathname: string): boolean;
|
|
72
88
|
/** Creates a grouped strict regex pattern string from many routes. */
|
|
73
89
|
static getRegexStrictStringGroup(routes: AnyRoute[]): string;
|
|
74
90
|
/** Creates a strict grouped regex from many routes. */
|
|
@@ -353,10 +369,7 @@ type UnknownSearchParsedValue = string | UnknownSearchParsed | Array<UnknownSear
|
|
|
353
369
|
interface UnknownSearchParsed {
|
|
354
370
|
[key: string]: UnknownSearchParsedValue;
|
|
355
371
|
}
|
|
356
|
-
type
|
|
357
|
-
interface UnknownSearchInput {
|
|
358
|
-
[key: string]: UnknownSearchInputValue;
|
|
359
|
-
}
|
|
372
|
+
type UnknownSearchInput = Record<string, unknown>;
|
|
360
373
|
/** It is when route not match at all, but params partially match. */
|
|
361
374
|
type WeakDescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {
|
|
362
375
|
known: true;
|
|
@@ -437,4 +450,4 @@ type SchemaRoute0<TInput extends Record<string, unknown>, TOutput extends Record
|
|
|
437
450
|
safeParse: (input: unknown) => _SafeParseInputResult<TOutput>;
|
|
438
451
|
};
|
|
439
452
|
|
|
440
|
-
export { type AncestorLocation, type AncestorLocationState, type AnyLocation, type AnyRoute, type AnyRouteOrDefinition, type CallableRoute, type DedupeSlashes, type Definition, type DescendantLocation, type DescendantLocationState, type EmptyRecord, type ExactLocation, type ExactLocationState, type Extended, type ExtractRoute, type ExtractRoutesKeys, type GetPathInput, type GetPathInputByRoute, type HasParams, type HasRequiredParams, type HasWildcard, type IsAncestor, type IsAny, type IsDescendant, type IsParamsOptional, type IsSame, type IsSameParams, type JoinPath, type KnownLocation, type LocationParams, type OnlyIfHasParams, type OnlyIfNoParams, type ParamsDefinition, type ParamsInput, type ParamsInputStringOnly, type ParamsOutput, type PathExtended, type ReplacePathParams, Route0, type RouteConfigInput, type RouteToken, Routes, type RoutesPretty, type RoutesRecord, type RoutesRecordHydrated, type SchemaRoute0, type StripTrailingWildcard, type UnknownLocation, type UnknownLocationState, type UnknownSearchInput, type
|
|
453
|
+
export { type AncestorLocation, type AncestorLocationState, type AnyLocation, type AnyRoute, type AnyRouteOrDefinition, type CallableRoute, type DedupeSlashes, type Definition, type DescendantLocation, type DescendantLocationState, type EmptyRecord, type ExactLocation, type ExactLocationState, type Extended, type ExtractRoute, type ExtractRoutesKeys, type GetPathInput, type GetPathInputByRoute, type HasParams, type HasRequiredParams, type HasWildcard, type IsAncestor, type IsAny, type IsDescendant, type IsParamsOptional, type IsSame, type IsSameParams, type JoinPath, type KnownLocation, type LocationParams, type OnlyIfHasParams, type OnlyIfNoParams, type ParamsDefinition, type ParamsInput, type ParamsInputStringOnly, type ParamsOutput, type PathExtended, type ReplacePathParams, Route0, type RouteConfigInput, type RouteToken, Routes, type RoutesPretty, type RoutesRecord, type RoutesRecordHydrated, type SchemaRoute0, type StripTrailingWildcard, type UnknownLocation, type UnknownLocationState, type UnknownSearchInput, type UnknownSearchParsed, type UnknownSearchParsedValue, type UnmatchedLocation, type UnmatchedLocationState, type WeakAncestorLocation, type WeakAncestorLocationState, type WeakDescendantLocation, type WeakDescendantLocationState, type _ExtractParamsDefinitionBySegments, type _GeneralLocation, type _IfNoKeys, type _IsAncestor, type _IsDescendant, type _IsSame, type _IsSameParams, type _MergeParamDefinitions, type _ParamDefinitionFromSegment, type _ParamsDefinition, type _ParamsInput, type _ParamsInputStringOnly, type _RequiredParamKeys, type _SafeParseInputResult, type _Simplify, type _SplitPathSegments };
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -28,6 +28,16 @@ declare class Route0<TDefinition extends string, TSearchInput extends UnknownSea
|
|
|
28
28
|
readonly params: _ParamsDefinition<TDefinition>;
|
|
29
29
|
private _origin;
|
|
30
30
|
private _callable;
|
|
31
|
+
private _regexBaseStrictString?;
|
|
32
|
+
private _regexBaseString?;
|
|
33
|
+
private _regexStrictString?;
|
|
34
|
+
private _regexString?;
|
|
35
|
+
private _regexStrict?;
|
|
36
|
+
private _regex?;
|
|
37
|
+
private _regexAncestor?;
|
|
38
|
+
private _captureKeys?;
|
|
39
|
+
private _normalizedDefinition?;
|
|
40
|
+
private _definitionParts?;
|
|
31
41
|
Infer: {
|
|
32
42
|
ParamsDefinition: _ParamsDefinition<TDefinition>;
|
|
33
43
|
ParamsInput: _ParamsInput<TDefinition>;
|
|
@@ -63,12 +73,18 @@ declare class Route0<TDefinition extends string, TSearchInput extends UnknownSea
|
|
|
63
73
|
getTokens(): RouteToken[];
|
|
64
74
|
/** Clones route with optional config override. */
|
|
65
75
|
clone(config?: RouteConfigInput): CallableRoute<TDefinition>;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
76
|
+
get regexBaseStrictString(): string;
|
|
77
|
+
get regexBaseString(): string;
|
|
78
|
+
get regexStrictString(): string;
|
|
79
|
+
get regexString(): string;
|
|
80
|
+
get regexStrict(): RegExp;
|
|
81
|
+
get regex(): RegExp;
|
|
82
|
+
get regexAncestor(): RegExp;
|
|
83
|
+
private get captureKeys();
|
|
84
|
+
private get normalizedDefinition();
|
|
85
|
+
private get definitionParts();
|
|
86
|
+
/** Fast pathname check without building a full location object. */
|
|
87
|
+
isExactPathnameMatch(pathname: string): boolean;
|
|
72
88
|
/** Creates a grouped strict regex pattern string from many routes. */
|
|
73
89
|
static getRegexStrictStringGroup(routes: AnyRoute[]): string;
|
|
74
90
|
/** Creates a strict grouped regex from many routes. */
|
|
@@ -353,10 +369,7 @@ type UnknownSearchParsedValue = string | UnknownSearchParsed | Array<UnknownSear
|
|
|
353
369
|
interface UnknownSearchParsed {
|
|
354
370
|
[key: string]: UnknownSearchParsedValue;
|
|
355
371
|
}
|
|
356
|
-
type
|
|
357
|
-
interface UnknownSearchInput {
|
|
358
|
-
[key: string]: UnknownSearchInputValue;
|
|
359
|
-
}
|
|
372
|
+
type UnknownSearchInput = Record<string, unknown>;
|
|
360
373
|
/** It is when route not match at all, but params partially match. */
|
|
361
374
|
type WeakDescendantLocationState<TRoute extends AnyRoute | string = AnyRoute | string> = {
|
|
362
375
|
known: true;
|
|
@@ -437,4 +450,4 @@ type SchemaRoute0<TInput extends Record<string, unknown>, TOutput extends Record
|
|
|
437
450
|
safeParse: (input: unknown) => _SafeParseInputResult<TOutput>;
|
|
438
451
|
};
|
|
439
452
|
|
|
440
|
-
export { type AncestorLocation, type AncestorLocationState, type AnyLocation, type AnyRoute, type AnyRouteOrDefinition, type CallableRoute, type DedupeSlashes, type Definition, type DescendantLocation, type DescendantLocationState, type EmptyRecord, type ExactLocation, type ExactLocationState, type Extended, type ExtractRoute, type ExtractRoutesKeys, type GetPathInput, type GetPathInputByRoute, type HasParams, type HasRequiredParams, type HasWildcard, type IsAncestor, type IsAny, type IsDescendant, type IsParamsOptional, type IsSame, type IsSameParams, type JoinPath, type KnownLocation, type LocationParams, type OnlyIfHasParams, type OnlyIfNoParams, type ParamsDefinition, type ParamsInput, type ParamsInputStringOnly, type ParamsOutput, type PathExtended, type ReplacePathParams, Route0, type RouteConfigInput, type RouteToken, Routes, type RoutesPretty, type RoutesRecord, type RoutesRecordHydrated, type SchemaRoute0, type StripTrailingWildcard, type UnknownLocation, type UnknownLocationState, type UnknownSearchInput, type
|
|
453
|
+
export { type AncestorLocation, type AncestorLocationState, type AnyLocation, type AnyRoute, type AnyRouteOrDefinition, type CallableRoute, type DedupeSlashes, type Definition, type DescendantLocation, type DescendantLocationState, type EmptyRecord, type ExactLocation, type ExactLocationState, type Extended, type ExtractRoute, type ExtractRoutesKeys, type GetPathInput, type GetPathInputByRoute, type HasParams, type HasRequiredParams, type HasWildcard, type IsAncestor, type IsAny, type IsDescendant, type IsParamsOptional, type IsSame, type IsSameParams, type JoinPath, type KnownLocation, type LocationParams, type OnlyIfHasParams, type OnlyIfNoParams, type ParamsDefinition, type ParamsInput, type ParamsInputStringOnly, type ParamsOutput, type PathExtended, type ReplacePathParams, Route0, type RouteConfigInput, type RouteToken, Routes, type RoutesPretty, type RoutesRecord, type RoutesRecordHydrated, type SchemaRoute0, type StripTrailingWildcard, type UnknownLocation, type UnknownLocationState, type UnknownSearchInput, type UnknownSearchParsed, type UnknownSearchParsedValue, type UnmatchedLocation, type UnmatchedLocationState, type WeakAncestorLocation, type WeakAncestorLocationState, type WeakDescendantLocation, type WeakDescendantLocationState, type _ExtractParamsDefinitionBySegments, type _GeneralLocation, type _IfNoKeys, type _IsAncestor, type _IsDescendant, type _IsSame, type _IsSameParams, type _MergeParamDefinitions, type _ParamDefinitionFromSegment, type _ParamsDefinition, type _ParamsInput, type _ParamsInputStringOnly, type _RequiredParamKeys, type _SafeParseInputResult, type _Simplify, type _SplitPathSegments };
|
package/dist/esm/index.js
CHANGED
|
@@ -71,11 +71,42 @@ const validateRouteDefinition = (definition) => {
|
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
73
|
const stripTrailingWildcard = (definition) => definition.replace(/\*\??$/, "");
|
|
74
|
+
const normalizePathname = (pathname) => {
|
|
75
|
+
if (pathname.length > 1 && pathname.endsWith("/")) {
|
|
76
|
+
return pathname.slice(0, -1);
|
|
77
|
+
}
|
|
78
|
+
return pathname;
|
|
79
|
+
};
|
|
80
|
+
const getNormalizedPathnameFromInput = (hrefOrHrefRelOrLocation) => {
|
|
81
|
+
if (hrefOrHrefRelOrLocation instanceof URL) {
|
|
82
|
+
return normalizePathname(hrefOrHrefRelOrLocation.pathname);
|
|
83
|
+
}
|
|
84
|
+
if (typeof hrefOrHrefRelOrLocation !== "string") {
|
|
85
|
+
if (typeof hrefOrHrefRelOrLocation.pathname === "string") {
|
|
86
|
+
return normalizePathname(hrefOrHrefRelOrLocation.pathname);
|
|
87
|
+
}
|
|
88
|
+
hrefOrHrefRelOrLocation = hrefOrHrefRelOrLocation.href || hrefOrHrefRelOrLocation.hrefRel;
|
|
89
|
+
}
|
|
90
|
+
const abs = /^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(hrefOrHrefRelOrLocation);
|
|
91
|
+
const base = abs ? void 0 : "http://example.com";
|
|
92
|
+
const url = new URL(hrefOrHrefRelOrLocation, base);
|
|
93
|
+
return normalizePathname(url.pathname);
|
|
94
|
+
};
|
|
74
95
|
class Route0 {
|
|
75
96
|
definition;
|
|
76
97
|
params;
|
|
77
98
|
_origin;
|
|
78
99
|
_callable;
|
|
100
|
+
_regexBaseStrictString;
|
|
101
|
+
_regexBaseString;
|
|
102
|
+
_regexStrictString;
|
|
103
|
+
_regexString;
|
|
104
|
+
_regexStrict;
|
|
105
|
+
_regex;
|
|
106
|
+
_regexAncestor;
|
|
107
|
+
_captureKeys;
|
|
108
|
+
_normalizedDefinition;
|
|
109
|
+
_definitionParts;
|
|
79
110
|
Infer = null;
|
|
80
111
|
/** Base URL used when generating absolute URLs (`abs: true`). */
|
|
81
112
|
get origin() {
|
|
@@ -240,27 +271,73 @@ class Route0 {
|
|
|
240
271
|
clone(config) {
|
|
241
272
|
return Route0.create(this.definition, config);
|
|
242
273
|
}
|
|
243
|
-
|
|
244
|
-
|
|
274
|
+
get regexBaseStrictString() {
|
|
275
|
+
if (this._regexBaseStrictString === void 0) {
|
|
276
|
+
this._regexBaseStrictString = getRouteRegexBaseStrictString(this.definition);
|
|
277
|
+
}
|
|
278
|
+
return this._regexBaseStrictString;
|
|
245
279
|
}
|
|
246
|
-
|
|
247
|
-
|
|
280
|
+
get regexBaseString() {
|
|
281
|
+
if (this._regexBaseString === void 0) {
|
|
282
|
+
this._regexBaseString = this.regexBaseStrictString.replace(/\/+$/, "") + "/?";
|
|
283
|
+
}
|
|
284
|
+
return this._regexBaseString;
|
|
248
285
|
}
|
|
249
|
-
|
|
250
|
-
|
|
286
|
+
get regexStrictString() {
|
|
287
|
+
if (this._regexStrictString === void 0) {
|
|
288
|
+
this._regexStrictString = `^${this.regexBaseStrictString}$`;
|
|
289
|
+
}
|
|
290
|
+
return this._regexStrictString;
|
|
251
291
|
}
|
|
252
|
-
|
|
253
|
-
|
|
292
|
+
get regexString() {
|
|
293
|
+
if (this._regexString === void 0) {
|
|
294
|
+
this._regexString = `^${this.regexBaseString}$`;
|
|
295
|
+
}
|
|
296
|
+
return this._regexString;
|
|
254
297
|
}
|
|
255
|
-
|
|
256
|
-
|
|
298
|
+
get regexStrict() {
|
|
299
|
+
if (this._regexStrict === void 0) {
|
|
300
|
+
this._regexStrict = new RegExp(this.regexStrictString);
|
|
301
|
+
}
|
|
302
|
+
return this._regexStrict;
|
|
257
303
|
}
|
|
258
|
-
|
|
259
|
-
|
|
304
|
+
get regex() {
|
|
305
|
+
if (this._regex === void 0) {
|
|
306
|
+
this._regex = new RegExp(this.regexString);
|
|
307
|
+
}
|
|
308
|
+
return this._regex;
|
|
309
|
+
}
|
|
310
|
+
get regexAncestor() {
|
|
311
|
+
if (this._regexAncestor === void 0) {
|
|
312
|
+
this._regexAncestor = new RegExp(`^${this.regexBaseString}(?:/.*)?$`);
|
|
313
|
+
}
|
|
314
|
+
return this._regexAncestor;
|
|
315
|
+
}
|
|
316
|
+
get captureKeys() {
|
|
317
|
+
if (this._captureKeys === void 0) {
|
|
318
|
+
this._captureKeys = getRouteCaptureKeys(this.definition);
|
|
319
|
+
}
|
|
320
|
+
return this._captureKeys;
|
|
321
|
+
}
|
|
322
|
+
get normalizedDefinition() {
|
|
323
|
+
if (this._normalizedDefinition === void 0) {
|
|
324
|
+
this._normalizedDefinition = this.definition.length > 1 && this.definition.endsWith("/") ? this.definition.slice(0, -1) : this.definition;
|
|
325
|
+
}
|
|
326
|
+
return this._normalizedDefinition;
|
|
327
|
+
}
|
|
328
|
+
get definitionParts() {
|
|
329
|
+
if (this._definitionParts === void 0) {
|
|
330
|
+
this._definitionParts = this.normalizedDefinition === "/" ? ["/"] : this.normalizedDefinition.split("/").filter(Boolean);
|
|
331
|
+
}
|
|
332
|
+
return this._definitionParts;
|
|
333
|
+
}
|
|
334
|
+
/** Fast pathname check without building a full location object. */
|
|
335
|
+
isExactPathnameMatch(pathname) {
|
|
336
|
+
return this.regex.test(normalizePathname(pathname));
|
|
260
337
|
}
|
|
261
338
|
/** Creates a grouped strict regex pattern string from many routes. */
|
|
262
339
|
static getRegexStrictStringGroup(routes) {
|
|
263
|
-
const patterns = routes.map((route) => route.
|
|
340
|
+
const patterns = routes.map((route) => route.regexStrictString).join("|");
|
|
264
341
|
return `(${patterns})`;
|
|
265
342
|
}
|
|
266
343
|
/** Creates a strict grouped regex from many routes. */
|
|
@@ -270,7 +347,7 @@ class Route0 {
|
|
|
270
347
|
}
|
|
271
348
|
/** Creates a grouped regex pattern string from many routes. */
|
|
272
349
|
static getRegexStringGroup(routes) {
|
|
273
|
-
const patterns = routes.map((route) => route.
|
|
350
|
+
const patterns = routes.map((route) => route.regexString).join("|");
|
|
274
351
|
return `(${patterns})`;
|
|
275
352
|
}
|
|
276
353
|
/** Creates a grouped regex from many routes. */
|
|
@@ -354,11 +431,11 @@ class Route0 {
|
|
|
354
431
|
const location = Route0.getLocation(hrefOrHrefRelOrLocation);
|
|
355
432
|
location.route = this.definition;
|
|
356
433
|
location.params = {};
|
|
357
|
-
const pathname =
|
|
358
|
-
const paramNames =
|
|
359
|
-
const
|
|
360
|
-
const exactRe =
|
|
361
|
-
const ancestorRe =
|
|
434
|
+
const pathname = normalizePathname(location.pathname);
|
|
435
|
+
const paramNames = this.captureKeys;
|
|
436
|
+
const defParts = this.definitionParts;
|
|
437
|
+
const exactRe = this.regex;
|
|
438
|
+
const ancestorRe = this.regexAncestor;
|
|
362
439
|
const exactMatch = pathname.match(exactRe);
|
|
363
440
|
const ancestorMatch = pathname.match(ancestorRe);
|
|
364
441
|
const exact = !!exactMatch;
|
|
@@ -376,9 +453,7 @@ class Route0 {
|
|
|
376
453
|
} else {
|
|
377
454
|
location.params = {};
|
|
378
455
|
}
|
|
379
|
-
const
|
|
380
|
-
const defParts = getParts(def);
|
|
381
|
-
const pathParts = getParts(pathname);
|
|
456
|
+
const pathParts = pathname === "/" ? ["/"] : pathname.split("/").filter(Boolean);
|
|
382
457
|
let isPrefix = true;
|
|
383
458
|
if (pathParts.length > defParts.length) {
|
|
384
459
|
isPrefix = false;
|
|
@@ -579,8 +654,8 @@ class Route0 {
|
|
|
579
654
|
isConflict(other) {
|
|
580
655
|
if (!other) return false;
|
|
581
656
|
other = Route0.create(other);
|
|
582
|
-
const thisRegex = this.
|
|
583
|
-
const otherRegex = other.
|
|
657
|
+
const thisRegex = this.regex;
|
|
658
|
+
const otherRegex = other.regex;
|
|
584
659
|
const makeCandidates = (definition) => {
|
|
585
660
|
const tokens = getRouteTokens(definition);
|
|
586
661
|
const values = (token) => {
|
|
@@ -709,8 +784,12 @@ class Routes {
|
|
|
709
784
|
}
|
|
710
785
|
_getLocation(hrefOrHrefRelOrLocation) {
|
|
711
786
|
const input = hrefOrHrefRelOrLocation;
|
|
787
|
+
const pathname = getNormalizedPathnameFromInput(input);
|
|
712
788
|
for (const route of this._ordered) {
|
|
713
|
-
|
|
789
|
+
if (!route.isExactPathnameMatch(pathname)) {
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
const loc = route.getLocation(input);
|
|
714
793
|
if (loc.exact) {
|
|
715
794
|
return loc;
|
|
716
795
|
}
|