@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.
Files changed (89) hide show
  1. package/README.md +27 -5
  2. package/dist/cjs/Router-B-Pev7K2.d.ts +46 -0
  3. package/dist/cjs/RouterValidator-mx2Zooya.d.ts +136 -0
  4. package/dist/cjs/api.d.ts +2 -1
  5. package/dist/cjs/api.js +1 -1
  6. package/dist/cjs/api.js.map +1 -1
  7. package/dist/cjs/index.d-y2b-8_3Y.d.ts +236 -0
  8. package/dist/cjs/index.d.ts +7 -24
  9. package/dist/cjs/index.js +1 -1
  10. package/dist/cjs/index.js.map +1 -1
  11. package/dist/cjs/metafile-cjs.json +1 -1
  12. package/dist/cjs/utils.d.ts +6 -1
  13. package/dist/cjs/utils.js +1 -1
  14. package/dist/cjs/utils.js.map +1 -1
  15. package/dist/cjs/validation.d.ts +184 -0
  16. package/dist/cjs/validation.js +1 -0
  17. package/dist/cjs/validation.js.map +1 -0
  18. package/dist/esm/Router-B-Pev7K2.d.mts +46 -0
  19. package/dist/esm/RouterValidator-mx2Zooya.d.mts +136 -0
  20. package/dist/esm/api.d.mts +2 -1
  21. package/dist/esm/api.mjs +1 -1
  22. package/dist/esm/api.mjs.map +1 -1
  23. package/dist/esm/chunk-5QXFUUDL.mjs +1 -0
  24. package/dist/esm/chunk-5QXFUUDL.mjs.map +1 -0
  25. package/dist/esm/chunk-HHIXK5UM.mjs +1 -0
  26. package/dist/esm/chunk-HHIXK5UM.mjs.map +1 -0
  27. package/dist/esm/chunk-QUUNDESP.mjs +1 -0
  28. package/dist/esm/chunk-QUUNDESP.mjs.map +1 -0
  29. package/dist/esm/chunk-RA5VYM7M.mjs +1 -0
  30. package/dist/esm/chunk-RA5VYM7M.mjs.map +1 -0
  31. package/dist/esm/index.d-y2b-8_3Y.d.mts +236 -0
  32. package/dist/esm/index.d.mts +7 -24
  33. package/dist/esm/index.mjs +1 -1
  34. package/dist/esm/metafile-esm.json +1 -1
  35. package/dist/esm/utils.d.mts +6 -1
  36. package/dist/esm/utils.mjs +1 -1
  37. package/dist/esm/utils.mjs.map +1 -1
  38. package/dist/esm/validation.d.mts +184 -0
  39. package/dist/esm/validation.mjs +1 -0
  40. package/dist/esm/validation.mjs.map +1 -0
  41. package/package.json +18 -5
  42. package/src/Router.ts +73 -99
  43. package/src/api/cloneRouter.ts +1 -30
  44. package/src/api/getDependenciesApi.ts +45 -86
  45. package/src/api/getLifecycleApi.ts +24 -19
  46. package/src/api/getPluginApi.ts +20 -28
  47. package/src/api/getRoutesApi.ts +49 -106
  48. package/src/constants.ts +0 -30
  49. package/src/guards.ts +46 -0
  50. package/src/helpers.ts +0 -17
  51. package/src/index.ts +4 -0
  52. package/src/internals.ts +6 -5
  53. package/src/namespaces/EventBusNamespace/EventBusNamespace.ts +2 -2
  54. package/src/namespaces/NavigationNamespace/NavigationNamespace.ts +0 -25
  55. package/src/namespaces/OptionsNamespace/OptionsNamespace.ts +4 -26
  56. package/src/namespaces/OptionsNamespace/constants.ts +0 -20
  57. package/src/namespaces/OptionsNamespace/index.ts +1 -5
  58. package/src/namespaces/OptionsNamespace/validators.ts +6 -245
  59. package/src/namespaces/PluginsNamespace/PluginsNamespace.ts +18 -59
  60. package/src/namespaces/PluginsNamespace/constants.ts +3 -6
  61. package/src/namespaces/PluginsNamespace/validators.ts +2 -57
  62. package/src/namespaces/RouteLifecycleNamespace/RouteLifecycleNamespace.ts +27 -84
  63. package/src/namespaces/RouterLifecycleNamespace/RouterLifecycleNamespace.ts +0 -16
  64. package/src/namespaces/RoutesNamespace/RoutesNamespace.ts +3 -12
  65. package/src/namespaces/RoutesNamespace/constants.ts +0 -8
  66. package/src/namespaces/RoutesNamespace/forwardChain.ts +34 -0
  67. package/src/namespaces/RoutesNamespace/index.ts +1 -1
  68. package/src/namespaces/RoutesNamespace/routeGuards.ts +62 -0
  69. package/src/namespaces/RoutesNamespace/routesStore.ts +7 -51
  70. package/src/namespaces/StateNamespace/StateNamespace.ts +0 -33
  71. package/src/namespaces/StateNamespace/helpers.ts +1 -1
  72. package/src/namespaces/index.ts +0 -3
  73. package/src/typeGuards.ts +1 -15
  74. package/src/types/RouterValidator.ts +155 -0
  75. package/src/utils/getStaticPaths.ts +50 -0
  76. package/src/utils/index.ts +4 -0
  77. package/src/validation.ts +12 -0
  78. package/src/wiring/RouterWiringBuilder.ts +32 -9
  79. package/dist/cjs/index.d-DDimDpYc.d.ts +0 -165
  80. package/dist/esm/chunk-CG7TKDP3.mjs +0 -1
  81. package/dist/esm/chunk-CG7TKDP3.mjs.map +0 -1
  82. package/dist/esm/index.d-DDimDpYc.d.mts +0 -165
  83. package/src/namespaces/DependenciesNamespace/validators.ts +0 -103
  84. package/src/namespaces/EventBusNamespace/validators.ts +0 -36
  85. package/src/namespaces/NavigationNamespace/validators.ts +0 -47
  86. package/src/namespaces/RouteLifecycleNamespace/validators.ts +0 -65
  87. package/src/namespaces/RoutesNamespace/forwardToValidation.ts +0 -408
  88. package/src/namespaces/RoutesNamespace/validators.ts +0 -566
  89. package/src/namespaces/StateNamespace/validators.ts +0 -46
@@ -1,64 +1,20 @@
1
- import { logger } from "@real-router/logger";
2
- import { getTypeDescription } from "type-guards";
3
-
4
1
  import { throwIfDisposed } from "./helpers";
5
- import { computeThresholds } from "../helpers";
6
2
  import { getInternals } from "../internals";
7
- import {
8
- validateDependenciesObject,
9
- validateDependencyExists,
10
- validateDependencyLimit,
11
- validateDependencyName,
12
- validateSetDependencyArgs,
13
- } from "../namespaces/DependenciesNamespace/validators";
14
3
 
15
4
  import type { DependenciesApi } from "./types";
16
5
  import type { DependenciesStore } from "../namespaces";
6
+ import type { RouterValidator } from "../types/RouterValidator";
17
7
  import type { DefaultDependencies, Router } from "@real-router/types";
18
8
 
19
9
  // =============================================================================
20
10
  // Module-private CRUD functions
21
11
  // =============================================================================
22
12
 
23
- function checkDependencyCount(
24
- store: DependenciesStore,
25
- methodName: string,
26
- ): void {
27
- const maxDependencies = store.limits.maxDependencies;
28
-
29
- if (maxDependencies === 0) {
30
- return;
31
- }
32
-
33
- const currentCount = Object.keys(store.dependencies).length;
34
-
35
- const { warn, error } = computeThresholds(maxDependencies);
36
-
37
- if (currentCount === warn) {
38
- logger.warn(
39
- `router.${methodName}`,
40
- `${warn} dependencies registered. ` + `Consider if all are necessary.`,
41
- );
42
- } else if (currentCount === error) {
43
- logger.error(
44
- `router.${methodName}`,
45
- `${error} dependencies registered! ` +
46
- `This indicates architectural problems. ` +
47
- `Hard limit at ${maxDependencies}.`,
48
- );
49
- } else if (currentCount >= maxDependencies) {
50
- throw new Error(
51
- `[router.${methodName}] Dependency limit exceeded (${maxDependencies}). ` +
52
- `Current: ${currentCount}. This is likely a bug in your code. ` +
53
- `If you genuinely need more dependencies, your architecture needs refactoring.`,
54
- );
55
- }
56
- }
57
-
58
13
  function setDependency(
59
14
  store: DependenciesStore,
60
15
  dependencyName: string,
61
16
  dependencyValue: unknown,
17
+ validator?: RouterValidator | null,
62
18
  ): boolean {
63
19
  // undefined = "don't set" (feature for conditional setting)
64
20
  if (dependencyValue === undefined) {
@@ -69,7 +25,7 @@ function setDependency(
69
25
 
70
26
  if (isNewKey) {
71
27
  // Only check limit when adding new keys (overwrites don't increase count)
72
- checkDependencyCount(store, "setDependency");
28
+ validator?.dependencies.validateDependencyCount(store, "setDependency");
73
29
  } else {
74
30
  const oldValue = (store.dependencies as Record<string, unknown>)[
75
31
  dependencyName
@@ -79,11 +35,7 @@ function setDependency(
79
35
  const bothAreNaN = Number.isNaN(oldValue) && Number.isNaN(dependencyValue);
80
36
 
81
37
  if (isChanging && !bothAreNaN) {
82
- logger.warn(
83
- "router.setDependency",
84
- "Router dependency already exists and is being overwritten:",
85
- dependencyName,
86
- );
38
+ validator?.dependencies.warnOverwrite(dependencyName, "setDependency");
87
39
  }
88
40
  }
89
41
 
@@ -96,6 +48,7 @@ function setDependency(
96
48
  function setMultipleDependencies(
97
49
  store: DependenciesStore,
98
50
  deps: Record<string, unknown>,
51
+ validator?: RouterValidator | null,
99
52
  ): void {
100
53
  const overwrittenKeys: string[] = [];
101
54
 
@@ -103,6 +56,11 @@ function setMultipleDependencies(
103
56
  if (deps[key] !== undefined) {
104
57
  if (Object.hasOwn(store.dependencies, key)) {
105
58
  overwrittenKeys.push(key);
59
+ } else {
60
+ validator?.dependencies.validateDependencyCount(
61
+ store,
62
+ "setDependencies",
63
+ );
106
64
  }
107
65
 
108
66
  (store.dependencies as Record<string, unknown>)[key] = deps[key];
@@ -110,10 +68,9 @@ function setMultipleDependencies(
110
68
  }
111
69
 
112
70
  if (overwrittenKeys.length > 0) {
113
- logger.warn(
114
- "router.setDependencies",
115
- "Overwritten:",
116
- overwrittenKeys.join(", "),
71
+ validator?.dependencies.warnBatchOverwrite(
72
+ overwrittenKeys,
73
+ "setDependencies",
117
74
  );
118
75
  }
119
76
  }
@@ -129,18 +86,17 @@ export function getDependenciesApi<
129
86
 
130
87
  return {
131
88
  get: (name) => {
132
- if (!ctx.noValidate) {
133
- validateDependencyName(name, "getDependency");
134
- }
89
+ ctx.validator?.dependencies.validateDependencyName(name, "getDependency");
135
90
 
136
91
  const store = ctx.dependenciesGetStore();
137
92
  const value = (store.dependencies as Record<string, unknown>)[
138
93
  name as string
139
94
  ];
140
95
 
141
- if (!ctx.noValidate) {
142
- validateDependencyExists(value, name as string);
143
- }
96
+ ctx.validator?.dependencies.validateDependencyExists(
97
+ name as string,
98
+ store,
99
+ );
144
100
 
145
101
  return value as Dependencies[typeof name];
146
102
  },
@@ -148,43 +104,48 @@ export function getDependenciesApi<
148
104
  set: (name, value) => {
149
105
  throwIfDisposed(ctx.isDisposed);
150
106
 
151
- if (!ctx.noValidate) {
152
- validateSetDependencyArgs(name);
153
- }
107
+ ctx.validator?.dependencies.validateSetDependencyArgs(
108
+ name,
109
+ value,
110
+ "setDependency",
111
+ );
154
112
 
155
- setDependency(ctx.dependenciesGetStore(), name as string, value);
113
+ setDependency(
114
+ ctx.dependenciesGetStore(),
115
+ name as string,
116
+ value,
117
+ ctx.validator,
118
+ );
156
119
  },
157
120
  setAll: (deps) => {
158
121
  throwIfDisposed(ctx.isDisposed);
159
122
 
160
123
  const store = ctx.dependenciesGetStore();
161
124
 
162
- if (!ctx.noValidate) {
163
- validateDependenciesObject(deps, "setDependencies");
164
- validateDependencyLimit(
165
- Object.keys(store.dependencies).length,
166
- Object.keys(deps).length,
167
- "setDependencies",
168
- store.limits.maxDependencies,
169
- );
170
- }
125
+ ctx.validator?.dependencies.validateDependenciesObject(
126
+ deps,
127
+ "setDependencies",
128
+ );
129
+ ctx.validator?.dependencies.validateDependencyLimit(store, store.limits);
171
130
 
172
- setMultipleDependencies(store, deps as Record<string, unknown>);
131
+ setMultipleDependencies(
132
+ store,
133
+ deps as Record<string, unknown>,
134
+ ctx.validator,
135
+ );
173
136
  },
174
137
  remove: (name) => {
175
138
  throwIfDisposed(ctx.isDisposed);
176
139
 
177
- if (!ctx.noValidate) {
178
- validateDependencyName(name, "removeDependency");
179
- }
140
+ ctx.validator?.dependencies.validateDependencyName(
141
+ name,
142
+ "removeDependency",
143
+ );
180
144
 
181
145
  const store = ctx.dependenciesGetStore();
182
146
 
183
147
  if (!Object.hasOwn(store.dependencies, name as string)) {
184
- logger.warn(
185
- `router.removeDependency`,
186
- `Attempted to remove non-existent dependency: "${getTypeDescription(name)}"`,
187
- );
148
+ ctx.validator?.dependencies.warnRemoveNonExistent(name);
188
149
  }
189
150
 
190
151
  delete (store.dependencies as Record<string, unknown>)[name as string];
@@ -196,9 +157,7 @@ export function getDependenciesApi<
196
157
  store.dependencies = Object.create(null) as Partial<Dependencies>;
197
158
  },
198
159
  has: (name) => {
199
- if (!ctx.noValidate) {
200
- validateDependencyName(name, "hasDependency");
201
- }
160
+ ctx.validator?.dependencies.validateDependencyName(name, "hasDependency");
202
161
 
203
162
  return Object.hasOwn(
204
163
  ctx.dependenciesGetStore().dependencies,
@@ -1,8 +1,5 @@
1
- import { validateRouteName } from "type-guards";
2
-
3
1
  import { throwIfDisposed } from "./helpers";
4
2
  import { getInternals } from "../internals";
5
- import { validateHandler } from "../namespaces/RouteLifecycleNamespace/validators";
6
3
 
7
4
  import type { LifecycleApi } from "./types";
8
5
  import type { DefaultDependencies, Router } from "@real-router/types";
@@ -18,31 +15,41 @@ export function getLifecycleApi<
18
15
  addActivateGuard(name, handler) {
19
16
  throwIfDisposed(ctx.isDisposed);
20
17
 
21
- if (!ctx.noValidate) {
22
- validateRouteName(name, "addActivateGuard");
23
- validateHandler(handler, "addActivateGuard");
24
- }
18
+ ctx.validator?.routes.validateRouteName(name, "addActivateGuard");
19
+ ctx.validator?.lifecycle.validateHandler(handler, "addActivateGuard");
20
+
21
+ const activateCount = lifecycleNamespace.getHandlerCount("activate");
22
+
23
+ ctx.validator?.lifecycle.validateHandlerLimit(
24
+ activateCount,
25
+ ctx.dependenciesGetStore().limits,
26
+ "canActivate",
27
+ );
25
28
 
26
- lifecycleNamespace.addCanActivate(name, handler, ctx.noValidate);
29
+ lifecycleNamespace.addCanActivate(name, handler);
27
30
  },
28
31
 
29
32
  addDeactivateGuard(name, handler) {
30
33
  throwIfDisposed(ctx.isDisposed);
31
34
 
32
- if (!ctx.noValidate) {
33
- validateRouteName(name, "addDeactivateGuard");
34
- validateHandler(handler, "addDeactivateGuard");
35
- }
35
+ ctx.validator?.routes.validateRouteName(name, "addDeactivateGuard");
36
+ ctx.validator?.lifecycle.validateHandler(handler, "addDeactivateGuard");
37
+
38
+ const deactivateCount = lifecycleNamespace.getHandlerCount("deactivate");
39
+
40
+ ctx.validator?.lifecycle.validateHandlerLimit(
41
+ deactivateCount,
42
+ ctx.dependenciesGetStore().limits,
43
+ "canDeactivate",
44
+ );
36
45
 
37
- lifecycleNamespace.addCanDeactivate(name, handler, ctx.noValidate);
46
+ lifecycleNamespace.addCanDeactivate(name, handler);
38
47
  },
39
48
 
40
49
  removeActivateGuard(name) {
41
50
  throwIfDisposed(ctx.isDisposed);
42
51
 
43
- if (!ctx.noValidate) {
44
- validateRouteName(name, "removeActivateGuard");
45
- }
52
+ ctx.validator?.routes.validateRouteName(name, "removeActivateGuard");
46
53
 
47
54
  lifecycleNamespace.clearCanActivate(name);
48
55
  },
@@ -50,9 +57,7 @@ export function getLifecycleApi<
50
57
  removeDeactivateGuard(name) {
51
58
  throwIfDisposed(ctx.isDisposed);
52
59
 
53
- if (!ctx.noValidate) {
54
- validateRouteName(name, "removeDeactivateGuard");
55
- }
60
+ ctx.validator?.routes.validateRouteName(name, "removeDeactivateGuard");
56
61
 
57
62
  lifecycleNamespace.clearCanDeactivate(name);
58
63
  },
@@ -1,13 +1,6 @@
1
1
  import { throwIfDisposed } from "./helpers";
2
2
  import { errorCodes } from "../constants";
3
3
  import { getInternals } from "../internals";
4
- import { validateListenerArgs } from "../namespaces/EventBusNamespace/validators";
5
- import {
6
- validateMatchPathArgs,
7
- validateSetRootPathArgs,
8
- validateStateBuilderArgs,
9
- } from "../namespaces/RoutesNamespace/validators";
10
- import { validateMakeStateArgs } from "../namespaces/StateNamespace/validators";
11
4
  import { RouterError } from "../RouterError";
12
5
 
13
6
  import type { PluginApi } from "./types";
@@ -20,9 +13,7 @@ export function getPluginApi<
20
13
 
21
14
  return {
22
15
  makeState: (name, params, path, meta, forceId) => {
23
- if (!ctx.noValidate) {
24
- validateMakeStateArgs(name, params, path, forceId);
25
- }
16
+ ctx.validator?.state.validateMakeStateArgs(name, params, path, forceId);
26
17
 
27
18
  return ctx.makeState(
28
19
  name,
@@ -35,9 +26,11 @@ export function getPluginApi<
35
26
  );
36
27
  },
37
28
  buildState: (routeName, routeParams) => {
38
- if (!ctx.noValidate) {
39
- validateStateBuilderArgs(routeName, routeParams, "buildState");
40
- }
29
+ ctx.validator?.routes.validateStateBuilderArgs(
30
+ routeName,
31
+ routeParams,
32
+ "buildState",
33
+ );
41
34
 
42
35
  const { name, params } = ctx.forwardState(routeName, routeParams);
43
36
 
@@ -47,25 +40,23 @@ export function getPluginApi<
47
40
  routeName: string,
48
41
  routeParams: P,
49
42
  ) => {
50
- if (!ctx.noValidate) {
51
- validateStateBuilderArgs(routeName, routeParams, "forwardState");
52
- }
43
+ ctx.validator?.routes.validateStateBuilderArgs(
44
+ routeName,
45
+ routeParams,
46
+ "forwardState",
47
+ );
53
48
 
54
49
  return ctx.forwardState(routeName, routeParams);
55
50
  },
56
51
  matchPath: (path) => {
57
- if (!ctx.noValidate) {
58
- validateMatchPathArgs(path);
59
- }
52
+ ctx.validator?.routes.validateMatchPathArgs(path);
60
53
 
61
54
  return ctx.matchPath(path, ctx.getOptions());
62
55
  },
63
56
  setRootPath: (rootPath) => {
64
57
  throwIfDisposed(ctx.isDisposed);
65
58
 
66
- if (!ctx.noValidate) {
67
- validateSetRootPathArgs(rootPath);
68
- }
59
+ ctx.validator?.routes.validateSetRootPathArgs(rootPath);
69
60
 
70
61
  ctx.setRootPath(rootPath);
71
62
  },
@@ -73,16 +64,16 @@ export function getPluginApi<
73
64
  addEventListener: (eventName, cb) => {
74
65
  throwIfDisposed(ctx.isDisposed);
75
66
 
76
- if (!ctx.noValidate) {
77
- validateListenerArgs(eventName, cb);
78
- }
67
+ ctx.validator?.eventBus.validateListenerArgs(eventName, cb);
79
68
 
80
69
  return ctx.addEventListener(eventName, cb);
81
70
  },
82
71
  buildNavigationState: (name, params = {}) => {
83
- if (!ctx.noValidate) {
84
- validateStateBuilderArgs(name, params, "buildNavigationState");
85
- }
72
+ ctx.validator?.routes.validateStateBuilderArgs(
73
+ name,
74
+ params,
75
+ "buildNavigationState",
76
+ );
86
77
 
87
78
  const { name: resolvedName, params: resolvedParams } = ctx.forwardState(
88
79
  name,
@@ -105,6 +96,7 @@ export function getPluginApi<
105
96
  getTree: ctx.getTree,
106
97
  addInterceptor: (method, fn) => {
107
98
  throwIfDisposed(ctx.isDisposed);
99
+ ctx.validator?.plugins.validateAddInterceptorArgs(method, fn);
108
100
  let list = ctx.interceptors.get(method);
109
101
 
110
102
  if (!list) {