@real-router/core 0.38.0 → 0.40.0
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 +27 -5
- package/dist/cjs/Router-B-Pev7K2.d.ts +46 -0
- package/dist/cjs/RouterValidator-mx2Zooya.d.ts +136 -0
- package/dist/cjs/api.d.ts +2 -1
- package/dist/cjs/api.js +1 -1
- package/dist/cjs/api.js.map +1 -1
- package/dist/cjs/index.d-y2b-8_3Y.d.ts +236 -0
- package/dist/cjs/index.d.ts +7 -24
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/metafile-cjs.json +1 -1
- package/dist/cjs/utils.d.ts +6 -1
- package/dist/cjs/utils.js +1 -1
- package/dist/cjs/utils.js.map +1 -1
- package/dist/cjs/validation.d.ts +184 -0
- package/dist/cjs/validation.js +1 -0
- package/dist/cjs/validation.js.map +1 -0
- package/dist/esm/Router-B-Pev7K2.d.mts +46 -0
- package/dist/esm/RouterValidator-mx2Zooya.d.mts +136 -0
- package/dist/esm/api.d.mts +2 -1
- package/dist/esm/api.mjs +1 -1
- package/dist/esm/api.mjs.map +1 -1
- package/dist/esm/chunk-5QXFUUDL.mjs +1 -0
- package/dist/esm/chunk-5QXFUUDL.mjs.map +1 -0
- package/dist/esm/chunk-HHIXK5UM.mjs +1 -0
- package/dist/esm/chunk-HHIXK5UM.mjs.map +1 -0
- package/dist/esm/chunk-QUUNDESP.mjs +1 -0
- package/dist/esm/chunk-QUUNDESP.mjs.map +1 -0
- package/dist/esm/chunk-RA5VYM7M.mjs +1 -0
- package/dist/esm/chunk-RA5VYM7M.mjs.map +1 -0
- package/dist/esm/index.d-y2b-8_3Y.d.mts +236 -0
- package/dist/esm/index.d.mts +7 -24
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/metafile-esm.json +1 -1
- package/dist/esm/utils.d.mts +6 -1
- package/dist/esm/utils.mjs +1 -1
- package/dist/esm/utils.mjs.map +1 -1
- package/dist/esm/validation.d.mts +184 -0
- package/dist/esm/validation.mjs +1 -0
- package/dist/esm/validation.mjs.map +1 -0
- package/package.json +18 -5
- package/src/Router.ts +73 -99
- package/src/api/cloneRouter.ts +1 -30
- package/src/api/getDependenciesApi.ts +45 -86
- package/src/api/getLifecycleApi.ts +24 -19
- package/src/api/getPluginApi.ts +20 -28
- package/src/api/getRoutesApi.ts +49 -106
- package/src/constants.ts +0 -30
- package/src/guards.ts +46 -0
- package/src/helpers.ts +0 -17
- package/src/index.ts +4 -0
- package/src/internals.ts +6 -5
- package/src/namespaces/EventBusNamespace/EventBusNamespace.ts +2 -2
- package/src/namespaces/NavigationNamespace/NavigationNamespace.ts +0 -25
- package/src/namespaces/OptionsNamespace/OptionsNamespace.ts +4 -26
- package/src/namespaces/OptionsNamespace/constants.ts +0 -20
- package/src/namespaces/OptionsNamespace/index.ts +1 -5
- package/src/namespaces/OptionsNamespace/validators.ts +6 -245
- package/src/namespaces/PluginsNamespace/PluginsNamespace.ts +18 -59
- package/src/namespaces/PluginsNamespace/constants.ts +3 -6
- package/src/namespaces/PluginsNamespace/validators.ts +2 -57
- package/src/namespaces/RouteLifecycleNamespace/RouteLifecycleNamespace.ts +27 -84
- package/src/namespaces/RouterLifecycleNamespace/RouterLifecycleNamespace.ts +0 -16
- package/src/namespaces/RoutesNamespace/RoutesNamespace.ts +3 -12
- package/src/namespaces/RoutesNamespace/constants.ts +0 -8
- package/src/namespaces/RoutesNamespace/forwardChain.ts +34 -0
- package/src/namespaces/RoutesNamespace/index.ts +1 -1
- package/src/namespaces/RoutesNamespace/routeGuards.ts +62 -0
- package/src/namespaces/RoutesNamespace/routesStore.ts +7 -51
- package/src/namespaces/StateNamespace/StateNamespace.ts +0 -33
- package/src/namespaces/StateNamespace/helpers.ts +1 -1
- package/src/namespaces/index.ts +0 -3
- package/src/typeGuards.ts +1 -15
- package/src/types/RouterValidator.ts +155 -0
- package/src/utils/getStaticPaths.ts +50 -0
- package/src/utils/index.ts +4 -0
- package/src/validation.ts +12 -0
- package/src/wiring/RouterWiringBuilder.ts +32 -9
- package/dist/cjs/index.d-DDimDpYc.d.ts +0 -165
- package/dist/esm/chunk-CG7TKDP3.mjs +0 -1
- package/dist/esm/chunk-CG7TKDP3.mjs.map +0 -1
- package/dist/esm/index.d-DDimDpYc.d.mts +0 -165
- package/src/namespaces/DependenciesNamespace/validators.ts +0 -103
- package/src/namespaces/EventBusNamespace/validators.ts +0 -36
- package/src/namespaces/NavigationNamespace/validators.ts +0 -47
- package/src/namespaces/RouteLifecycleNamespace/validators.ts +0 -65
- package/src/namespaces/RoutesNamespace/forwardToValidation.ts +0 -408
- package/src/namespaces/RoutesNamespace/validators.ts +0 -566
- package/src/namespaces/StateNamespace/validators.ts +0 -46
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RouterValidator interface - defines all validation methods used by the router.
|
|
3
|
+
*
|
|
4
|
+
* This interface is implemented by the validation plugin and injected into RouterInternals.
|
|
5
|
+
* When ctx.validator is null (default), validation is skipped.
|
|
6
|
+
* When ctx.validator is set (by validation plugin), all methods are called.
|
|
7
|
+
*
|
|
8
|
+
* All parameters use `unknown` type to avoid coupling to internal type names.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface RouterValidator {
|
|
12
|
+
/**
|
|
13
|
+
* Route validation methods
|
|
14
|
+
*/
|
|
15
|
+
routes: {
|
|
16
|
+
validateBuildPathArgs: (route: unknown) => void;
|
|
17
|
+
validateMatchPathArgs: (path: unknown) => void;
|
|
18
|
+
validateIsActiveRouteArgs: (
|
|
19
|
+
name: unknown,
|
|
20
|
+
params: unknown,
|
|
21
|
+
strict: unknown,
|
|
22
|
+
ignoreQP: unknown,
|
|
23
|
+
) => void;
|
|
24
|
+
validateShouldUpdateNodeArgs: (name: unknown) => void;
|
|
25
|
+
validateStateBuilderArgs: (
|
|
26
|
+
name: unknown,
|
|
27
|
+
params: unknown,
|
|
28
|
+
caller: string,
|
|
29
|
+
) => void;
|
|
30
|
+
validateAddRouteArgs: (routes: unknown) => void;
|
|
31
|
+
validateRoutes: (routes: unknown[], tree: unknown) => void;
|
|
32
|
+
validateRemoveRouteArgs: (name: unknown) => void;
|
|
33
|
+
validateUpdateRouteBasicArgs: (name: unknown, updates: unknown) => void;
|
|
34
|
+
validateUpdateRoutePropertyTypes: (name: string, updates: unknown) => void;
|
|
35
|
+
validateUpdateRoute: (
|
|
36
|
+
name: string,
|
|
37
|
+
updates: unknown,
|
|
38
|
+
tree: unknown,
|
|
39
|
+
) => void;
|
|
40
|
+
validateParentOption: (parent: unknown, tree: unknown) => void;
|
|
41
|
+
validateRouteName: (name: unknown, caller: string) => void;
|
|
42
|
+
throwIfInternalRoute: (name: unknown, caller: string) => void;
|
|
43
|
+
throwIfInternalRouteInArray: (routes: unknown[], caller: string) => void;
|
|
44
|
+
// Retrospective validation
|
|
45
|
+
validateExistingRoutes: (store: unknown) => void;
|
|
46
|
+
validateForwardToConsistency: (store: unknown) => void;
|
|
47
|
+
validateSetRootPathArgs: (rootPath: unknown) => void;
|
|
48
|
+
guardRouteCallbacks: (route: unknown) => void;
|
|
49
|
+
guardNoAsyncCallbacks: (route: unknown) => void;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Options validation methods
|
|
54
|
+
*/
|
|
55
|
+
options: {
|
|
56
|
+
validateLimitValue: (name: string, value: unknown) => void;
|
|
57
|
+
validateLimits: (limits: unknown) => void;
|
|
58
|
+
validateOptions: (options: unknown, methodName: string) => void;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Dependencies validation methods
|
|
63
|
+
*/
|
|
64
|
+
dependencies: {
|
|
65
|
+
validateDependencyName: (name: unknown, caller: string) => void;
|
|
66
|
+
validateSetDependencyArgs: (
|
|
67
|
+
name: unknown,
|
|
68
|
+
value: unknown,
|
|
69
|
+
caller: string,
|
|
70
|
+
) => void;
|
|
71
|
+
validateDependenciesObject: (deps: unknown, caller: string) => void;
|
|
72
|
+
validateDependencyExists: (name: string, store: unknown) => void;
|
|
73
|
+
validateDependencyLimit: (store: unknown, limits: unknown) => void;
|
|
74
|
+
// Retrospective validation
|
|
75
|
+
validateDependenciesStructure: (store: unknown) => void;
|
|
76
|
+
validateDependencyCount: (store: unknown, methodName: string) => void;
|
|
77
|
+
validateCloneArgs: (dependencies: unknown) => void;
|
|
78
|
+
warnOverwrite: (name: string, methodName: string) => void;
|
|
79
|
+
warnBatchOverwrite: (keys: string[], methodName: string) => void;
|
|
80
|
+
warnRemoveNonExistent: (name: unknown) => void;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Plugin validation methods
|
|
85
|
+
*/
|
|
86
|
+
plugins: {
|
|
87
|
+
validatePluginLimit: (count: number, limits: unknown) => void;
|
|
88
|
+
validateNoDuplicatePlugins: (
|
|
89
|
+
factory: unknown,
|
|
90
|
+
factories: unknown[],
|
|
91
|
+
) => void;
|
|
92
|
+
validatePluginKeys: (plugin: unknown) => void;
|
|
93
|
+
validateCountThresholds: (count: number) => void;
|
|
94
|
+
warnBatchDuplicates: (plugins: unknown[]) => void;
|
|
95
|
+
warnPluginMethodType: (methodName: string) => void;
|
|
96
|
+
warnPluginAfterStart: (methodName: string) => void;
|
|
97
|
+
validateAddInterceptorArgs: (method: unknown, fn: unknown) => void;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Lifecycle guard validation methods
|
|
102
|
+
*/
|
|
103
|
+
lifecycle: {
|
|
104
|
+
validateHandler: (handler: unknown, caller: string) => void;
|
|
105
|
+
validateNotRegistering: (
|
|
106
|
+
name: string,
|
|
107
|
+
guards: unknown,
|
|
108
|
+
caller: string,
|
|
109
|
+
) => void;
|
|
110
|
+
validateHandlerLimit: (
|
|
111
|
+
count: number,
|
|
112
|
+
limits: unknown,
|
|
113
|
+
caller: string,
|
|
114
|
+
) => void;
|
|
115
|
+
validateCountThresholds: (count: number, methodName: string) => void;
|
|
116
|
+
warnOverwrite: (name: string, type: string, methodName: string) => void;
|
|
117
|
+
warnAsyncGuardSync: (name: string, methodName: string) => void;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Navigation validation methods
|
|
122
|
+
*/
|
|
123
|
+
navigation: {
|
|
124
|
+
validateNavigateArgs: (name: unknown) => void;
|
|
125
|
+
validateNavigateToDefaultArgs: (options: unknown) => void;
|
|
126
|
+
validateNavigationOptions: (options: unknown, caller: string) => void;
|
|
127
|
+
validateParams: (params: unknown, methodName: string) => void;
|
|
128
|
+
validateStartArgs: (path: unknown) => void;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* State validation methods
|
|
133
|
+
*/
|
|
134
|
+
state: {
|
|
135
|
+
validateMakeStateArgs: (
|
|
136
|
+
name: unknown,
|
|
137
|
+
params: unknown,
|
|
138
|
+
path: unknown,
|
|
139
|
+
forceId: unknown,
|
|
140
|
+
) => void;
|
|
141
|
+
validateAreStatesEqualArgs: (
|
|
142
|
+
s1: unknown,
|
|
143
|
+
s2: unknown,
|
|
144
|
+
ignoreQP: unknown,
|
|
145
|
+
) => void;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Event bus validation methods
|
|
150
|
+
*/
|
|
151
|
+
eventBus: {
|
|
152
|
+
validateEventName: (name: unknown) => void;
|
|
153
|
+
validateListenerArgs: (name: unknown, cb: unknown) => void;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { getPluginApi } from "../api/getPluginApi";
|
|
2
|
+
|
|
3
|
+
import type { DefaultDependencies, Router } from "@real-router/types";
|
|
4
|
+
import type { RouteTree } from "route-tree";
|
|
5
|
+
|
|
6
|
+
export type StaticPathEntries = Record<
|
|
7
|
+
string,
|
|
8
|
+
() => Promise<Record<string, string>[]>
|
|
9
|
+
>;
|
|
10
|
+
|
|
11
|
+
function getLeafRouteNames(node: RouteTree): string[] {
|
|
12
|
+
const result: string[] = [];
|
|
13
|
+
|
|
14
|
+
for (const child of node.children.values()) {
|
|
15
|
+
if (child.children.size === 0) {
|
|
16
|
+
result.push(child.fullName);
|
|
17
|
+
} else {
|
|
18
|
+
result.push(...getLeafRouteNames(child));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function getStaticPaths<
|
|
26
|
+
Dependencies extends DefaultDependencies = DefaultDependencies,
|
|
27
|
+
>(
|
|
28
|
+
router: Router<Dependencies>,
|
|
29
|
+
entries?: StaticPathEntries,
|
|
30
|
+
): Promise<string[]> {
|
|
31
|
+
const tree = getPluginApi(router).getTree();
|
|
32
|
+
const leafRoutes = getLeafRouteNames(tree);
|
|
33
|
+
const paths: string[] = [];
|
|
34
|
+
|
|
35
|
+
for (const routeName of leafRoutes) {
|
|
36
|
+
const entryFn = entries?.[routeName];
|
|
37
|
+
|
|
38
|
+
if (entryFn) {
|
|
39
|
+
const paramSets = await entryFn();
|
|
40
|
+
|
|
41
|
+
for (const params of paramSets) {
|
|
42
|
+
paths.push(router.buildPath(routeName, params));
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
paths.push(router.buildPath(routeName, {}));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return paths;
|
|
50
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subpath export for @real-router/validation-plugin.
|
|
3
|
+
*
|
|
4
|
+
* Provides access to router internals so the plugin can install
|
|
5
|
+
* ctx.validator and run retrospective validation at registration time.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type { RouterValidator } from "./types/RouterValidator";
|
|
9
|
+
|
|
10
|
+
export { getInternals } from "./internals";
|
|
11
|
+
|
|
12
|
+
export type { RouterInternals } from "./internals";
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import { getInternals } from "../internals";
|
|
4
4
|
import { resolveOption } from "../namespaces/OptionsNamespace";
|
|
5
|
-
import { validateStateBuilderArgs } from "../namespaces/RoutesNamespace/validators";
|
|
6
5
|
|
|
7
6
|
import type { EventBusNamespace } from "../namespaces";
|
|
8
7
|
import type { WiringOptions } from "./types";
|
|
@@ -59,15 +58,25 @@ export class RouterWiringBuilder<
|
|
|
59
58
|
};
|
|
60
59
|
|
|
61
60
|
this.routeLifecycle.setDependencies(routeLifecycleDeps);
|
|
61
|
+
this.routeLifecycle.setValidatorGetter(
|
|
62
|
+
/* v8 ignore next 3 -- @preserve: returns null during construction (before registerInternals) */
|
|
63
|
+
() => {
|
|
64
|
+
try {
|
|
65
|
+
return getInternals(this.router).validator;
|
|
66
|
+
} catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
);
|
|
62
71
|
}
|
|
63
72
|
|
|
64
73
|
wireRoutesDeps(): void {
|
|
65
74
|
const routesDeps: RoutesDependencies<Dependencies> = {
|
|
66
75
|
addActivateGuard: (name, handler) => {
|
|
67
|
-
this.routeLifecycle.addCanActivate(name, handler, true
|
|
76
|
+
this.routeLifecycle.addCanActivate(name, handler, true);
|
|
68
77
|
},
|
|
69
78
|
addDeactivateGuard: (name, handler) => {
|
|
70
|
-
this.routeLifecycle.addCanDeactivate(name, handler, true
|
|
79
|
+
this.routeLifecycle.addCanDeactivate(name, handler, true);
|
|
71
80
|
},
|
|
72
81
|
makeState: (name, params, path, meta) =>
|
|
73
82
|
this.state.makeState(name, params, path, meta),
|
|
@@ -79,9 +88,11 @@ export class RouterWiringBuilder<
|
|
|
79
88
|
forwardState: <P extends Params = Params>(name: string, params: P) => {
|
|
80
89
|
const ctx = getInternals(this.router);
|
|
81
90
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
91
|
+
ctx.validator?.routes.validateStateBuilderArgs(
|
|
92
|
+
name,
|
|
93
|
+
params,
|
|
94
|
+
"forwardState",
|
|
95
|
+
);
|
|
85
96
|
|
|
86
97
|
return ctx.forwardState(name, params);
|
|
87
98
|
},
|
|
@@ -100,6 +111,16 @@ export class RouterWiringBuilder<
|
|
|
100
111
|
};
|
|
101
112
|
|
|
102
113
|
this.plugins.setDependencies(pluginsDeps);
|
|
114
|
+
this.plugins.setValidatorGetter(
|
|
115
|
+
/* v8 ignore next 3 -- @preserve: returns null during construction (before registerInternals) */
|
|
116
|
+
() => {
|
|
117
|
+
try {
|
|
118
|
+
return getInternals(this.router).validator;
|
|
119
|
+
} catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
);
|
|
103
124
|
}
|
|
104
125
|
|
|
105
126
|
wireNavigationDeps(): void {
|
|
@@ -113,9 +134,11 @@ export class RouterWiringBuilder<
|
|
|
113
134
|
buildNavigateState: (routeName, routeParams) => {
|
|
114
135
|
const ctx = getInternals(this.router);
|
|
115
136
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
137
|
+
ctx.validator?.routes.validateStateBuilderArgs(
|
|
138
|
+
routeName,
|
|
139
|
+
routeParams,
|
|
140
|
+
"navigate",
|
|
141
|
+
);
|
|
119
142
|
|
|
120
143
|
const { name, params } = ctx.forwardState(routeName, routeParams);
|
|
121
144
|
const meta = this.routes.getMetaForState(name);
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import { DefaultDependencies, Router as Router$1, Route, Options, Params, State, PluginFactory, Unsubscribe, SubscribeFn, NavigationOptions } from '@real-router/types';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Router class with integrated namespace architecture.
|
|
5
|
-
*
|
|
6
|
-
* All functionality is provided by namespace classes:
|
|
7
|
-
* - OptionsNamespace: getOptions (immutable)
|
|
8
|
-
* - DependenciesStore: get/set/remove dependencies
|
|
9
|
-
* - EventEmitter: subscribe
|
|
10
|
-
* - StateNamespace: state storage (getState, setState, getPreviousState)
|
|
11
|
-
* - RoutesNamespace: route tree operations
|
|
12
|
-
* - RouteLifecycleNamespace: canActivate/canDeactivate guards
|
|
13
|
-
* - PluginsNamespace: plugin lifecycle
|
|
14
|
-
* - NavigationNamespace: navigate
|
|
15
|
-
* - RouterLifecycleNamespace: start, stop, isStarted
|
|
16
|
-
*
|
|
17
|
-
* @internal This class implementation is internal. Use createRouter() instead.
|
|
18
|
-
*/
|
|
19
|
-
declare class Router<Dependencies extends DefaultDependencies = DefaultDependencies> implements Router$1<Dependencies> {
|
|
20
|
-
#private;
|
|
21
|
-
[key: string]: unknown;
|
|
22
|
-
/**
|
|
23
|
-
* @param routes - Route definitions
|
|
24
|
-
* @param options - Router options
|
|
25
|
-
* @param dependencies - DI dependencies
|
|
26
|
-
*/
|
|
27
|
-
constructor(routes?: Route<Dependencies>[], options?: Partial<Options>, dependencies?: Dependencies);
|
|
28
|
-
isActiveRoute(name: string, params?: Params, strictEquality?: boolean, ignoreQueryParams?: boolean): boolean;
|
|
29
|
-
buildPath(route: string, params?: Params): string;
|
|
30
|
-
getState<P extends Params = Params, MP extends Params = Params>(): State<P, MP> | undefined;
|
|
31
|
-
getPreviousState(): State | undefined;
|
|
32
|
-
areStatesEqual(state1: State | undefined, state2: State | undefined, ignoreQueryParams?: boolean): boolean;
|
|
33
|
-
shouldUpdateNode(nodeName: string): (toState: State, fromState?: State) => boolean;
|
|
34
|
-
isActive(): boolean;
|
|
35
|
-
start(startPath: string): Promise<State>;
|
|
36
|
-
stop(): this;
|
|
37
|
-
dispose(): void;
|
|
38
|
-
canNavigateTo(name: string, params?: Params): boolean;
|
|
39
|
-
usePlugin(...plugins: PluginFactory<Dependencies>[]): Unsubscribe;
|
|
40
|
-
subscribe(listener: SubscribeFn): Unsubscribe;
|
|
41
|
-
navigate(routeName: string, routeParams?: Params, options?: NavigationOptions): Promise<State>;
|
|
42
|
-
navigateToDefault(options?: NavigationOptions): Promise<State>;
|
|
43
|
-
navigateToNotFound(path?: string): State;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Path Matcher Type Definitions.
|
|
48
|
-
*
|
|
49
|
-
* Core types for path matching and parameter extraction.
|
|
50
|
-
*
|
|
51
|
-
* @module path-matcher/types
|
|
52
|
-
*/
|
|
53
|
-
/**
|
|
54
|
-
* Constraint pattern for a URL parameter.
|
|
55
|
-
*/
|
|
56
|
-
interface ConstraintPattern {
|
|
57
|
-
/**
|
|
58
|
-
* Compiled RegExp for validating the parameter value.
|
|
59
|
-
*
|
|
60
|
-
* @example /^(\d+)$/ for constraint "<\\d+>"
|
|
61
|
-
*/
|
|
62
|
-
readonly pattern: RegExp;
|
|
63
|
-
/**
|
|
64
|
-
* Raw constraint string from the route pattern.
|
|
65
|
-
*
|
|
66
|
-
* @example "<\\d+>"
|
|
67
|
-
*/
|
|
68
|
-
readonly constraint: string;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Parameter metadata extracted from a route path pattern.
|
|
72
|
-
*/
|
|
73
|
-
interface ParamMeta {
|
|
74
|
-
/**
|
|
75
|
-
* URL parameter names extracted from the path pattern.
|
|
76
|
-
*
|
|
77
|
-
* @example [":id", ":postId"] from "/users/:id/posts/:postId"
|
|
78
|
-
*/
|
|
79
|
-
readonly urlParams: readonly string[];
|
|
80
|
-
/**
|
|
81
|
-
* Query parameter names extracted from the path pattern.
|
|
82
|
-
*
|
|
83
|
-
* @example ["q", "page"] from "/search?q&page"
|
|
84
|
-
*/
|
|
85
|
-
readonly queryParams: readonly string[];
|
|
86
|
-
/**
|
|
87
|
-
* Splat parameter names extracted from the path pattern.
|
|
88
|
-
*
|
|
89
|
-
* @example ["path"] from "/files/*path"
|
|
90
|
-
*/
|
|
91
|
-
readonly spatParams: readonly string[];
|
|
92
|
-
/**
|
|
93
|
-
* Map of parameter names to their type (url or query).
|
|
94
|
-
*
|
|
95
|
-
* @example { id: "url", q: "query" }
|
|
96
|
-
*/
|
|
97
|
-
readonly paramTypeMap: Readonly<Record<string, "url" | "query">>;
|
|
98
|
-
/**
|
|
99
|
-
* Map of parameter names to their constraint patterns.
|
|
100
|
-
*
|
|
101
|
-
* Only includes parameters with explicit constraints (e.g., `:id<\\d+>`).
|
|
102
|
-
* Parameters without constraints are not included in this map.
|
|
103
|
-
*
|
|
104
|
-
* @example
|
|
105
|
-
* ```typescript
|
|
106
|
-
* buildParamMeta("/users/:id<\\d+>").constraintPatterns.get("id")
|
|
107
|
-
* // → { pattern: /^(\d+)$/, constraint: "<\\d+>" }
|
|
108
|
-
*
|
|
109
|
-
* buildParamMeta("/users/:id").constraintPatterns.size
|
|
110
|
-
* // → 0 (no constraints)
|
|
111
|
-
* ```
|
|
112
|
-
*/
|
|
113
|
-
readonly constraintPatterns: ReadonlyMap<string, ConstraintPattern>;
|
|
114
|
-
/**
|
|
115
|
-
* Path pattern without query string, pre-computed for buildPath.
|
|
116
|
-
*
|
|
117
|
-
* @example "/users/:id" from "/users/:id?q&page"
|
|
118
|
-
*/
|
|
119
|
-
readonly pathPattern: string;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Immutable route tree node.
|
|
124
|
-
*
|
|
125
|
-
* This is the core data structure of the new route-tree architecture.
|
|
126
|
-
* It contains only data (no methods) and is created by the builder.
|
|
127
|
-
*
|
|
128
|
-
* All caches are pre-computed at build time:
|
|
129
|
-
* - nonAbsoluteChildren: filtered children without absolute paths
|
|
130
|
-
* - absoluteDescendants: all descendants with absolute paths (recursive)
|
|
131
|
-
* - parentSegments: array from root to parent
|
|
132
|
-
* - fullName: pre-computed "users.profile" instead of runtime join
|
|
133
|
-
*/
|
|
134
|
-
interface RouteTree {
|
|
135
|
-
/** Route segment name (e.g., "users" in "users.profile") */
|
|
136
|
-
readonly name: string;
|
|
137
|
-
/** Route path pattern (e.g., "/users/:id") */
|
|
138
|
-
readonly path: string;
|
|
139
|
-
/** Whether this route uses absolute path matching (path starts with "~") */
|
|
140
|
-
readonly absolute: boolean;
|
|
141
|
-
/** Child route nodes (Map for O(1) lookup by name) */
|
|
142
|
-
readonly children: ReadonlyMap<string, RouteTree>;
|
|
143
|
-
/** Parameter metadata extracted from path pattern (replaces parser dependency) */
|
|
144
|
-
readonly paramMeta: ParamMeta;
|
|
145
|
-
/** Parent node (null for root) */
|
|
146
|
-
readonly parent: RouteTree | null;
|
|
147
|
-
/** Children without absolute paths (for regular matching) */
|
|
148
|
-
readonly nonAbsoluteChildren: readonly RouteTree[];
|
|
149
|
-
/** Pre-computed full name (e.g., "users.profile") */
|
|
150
|
-
readonly fullName: string;
|
|
151
|
-
/**
|
|
152
|
-
* Pre-computed static path for routes without parameters.
|
|
153
|
-
* Used by buildPath fast path to avoid inject() overhead.
|
|
154
|
-
* Only set when route has no URL params, query params, or splat params.
|
|
155
|
-
*/
|
|
156
|
-
readonly staticPath: string | null;
|
|
157
|
-
/**
|
|
158
|
-
* Pre-computed parameter type map for this segment.
|
|
159
|
-
* Cached to avoid recomputing on every navigation.
|
|
160
|
-
* Maps param name → "url" | "query".
|
|
161
|
-
*/
|
|
162
|
-
readonly paramTypeMap: Readonly<Record<string, "url" | "query">>;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export { Router as R, type RouteTree as a };
|