@real-router/core 0.56.0 → 0.57.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 (108) hide show
  1. package/dist/cjs/Router-BSGzVINO.js +6 -0
  2. package/dist/cjs/Router-BSGzVINO.js.map +1 -0
  3. package/dist/cjs/api.d.ts +1 -1
  4. package/dist/cjs/api.js +1 -1
  5. package/dist/cjs/{cloneRouter-DRieJvam.js → cloneRouter-7z-60z_f.js} +2 -2
  6. package/dist/cjs/{cloneRouter-DRieJvam.js.map → cloneRouter-7z-60z_f.js.map} +1 -1
  7. package/dist/cjs/{index-C-i6vx5Y.d.ts → index-BWUmnecT.d.ts} +1 -2
  8. package/dist/cjs/index-BWUmnecT.d.ts.map +1 -0
  9. package/dist/cjs/index.d.ts +1 -1
  10. package/dist/cjs/index.js +1 -1
  11. package/dist/cjs/utils.js +1 -1
  12. package/dist/cjs/validation.d.ts +1 -1
  13. package/dist/esm/Router-B7txWo9N.mjs +6 -0
  14. package/dist/esm/Router-B7txWo9N.mjs.map +1 -0
  15. package/dist/esm/api.d.mts +1 -1
  16. package/dist/esm/api.mjs +1 -1
  17. package/dist/esm/{cloneRouter-DHrH6D_z.mjs → cloneRouter-BNCQ7tIa.mjs} +2 -2
  18. package/dist/esm/{cloneRouter-DHrH6D_z.mjs.map → cloneRouter-BNCQ7tIa.mjs.map} +1 -1
  19. package/dist/esm/{index-C-i6vx5Y.d.mts → index-BWUmnecT.d.mts} +1 -2
  20. package/dist/esm/index-BWUmnecT.d.mts.map +1 -0
  21. package/dist/esm/index.d.mts +1 -1
  22. package/dist/esm/index.mjs +1 -1
  23. package/dist/esm/utils.mjs +1 -1
  24. package/dist/esm/validation.d.mts +1 -1
  25. package/package.json +2 -3
  26. package/dist/cjs/Router-IEGavTKk.js +0 -6
  27. package/dist/cjs/Router-IEGavTKk.js.map +0 -1
  28. package/dist/cjs/index-C-i6vx5Y.d.ts.map +0 -1
  29. package/dist/esm/Router-B3aeavRb.mjs +0 -6
  30. package/dist/esm/Router-B3aeavRb.mjs.map +0 -1
  31. package/dist/esm/index-C-i6vx5Y.d.mts.map +0 -1
  32. package/src/Router.ts +0 -737
  33. package/src/RouterError.ts +0 -324
  34. package/src/api/cloneRouter.ts +0 -159
  35. package/src/api/getDependenciesApi.ts +0 -160
  36. package/src/api/getLifecycleApi.ts +0 -65
  37. package/src/api/getPluginApi.ts +0 -228
  38. package/src/api/getRoutesApi.ts +0 -831
  39. package/src/api/helpers.ts +0 -10
  40. package/src/api/index.ts +0 -16
  41. package/src/api/types.ts +0 -12
  42. package/src/constants.ts +0 -101
  43. package/src/createRouter.ts +0 -32
  44. package/src/fsm/index.ts +0 -5
  45. package/src/fsm/routerFSM.ts +0 -130
  46. package/src/getNavigator.ts +0 -30
  47. package/src/guards.ts +0 -46
  48. package/src/helpers.ts +0 -197
  49. package/src/index.ts +0 -66
  50. package/src/internals.ts +0 -228
  51. package/src/namespaces/DependenciesNamespace/dependenciesStore.ts +0 -30
  52. package/src/namespaces/DependenciesNamespace/index.ts +0 -5
  53. package/src/namespaces/EventBusNamespace/EventBusNamespace.ts +0 -522
  54. package/src/namespaces/EventBusNamespace/index.ts +0 -5
  55. package/src/namespaces/EventBusNamespace/types.ts +0 -11
  56. package/src/namespaces/NavigationNamespace/NavigationNamespace.ts +0 -552
  57. package/src/namespaces/NavigationNamespace/constants.ts +0 -55
  58. package/src/namespaces/NavigationNamespace/index.ts +0 -5
  59. package/src/namespaces/NavigationNamespace/transition/completeTransition.ts +0 -108
  60. package/src/namespaces/NavigationNamespace/transition/errorHandling.ts +0 -124
  61. package/src/namespaces/NavigationNamespace/transition/guardPhase.ts +0 -283
  62. package/src/namespaces/NavigationNamespace/types.ts +0 -110
  63. package/src/namespaces/OptionsNamespace/OptionsNamespace.ts +0 -28
  64. package/src/namespaces/OptionsNamespace/constants.ts +0 -19
  65. package/src/namespaces/OptionsNamespace/helpers.ts +0 -50
  66. package/src/namespaces/OptionsNamespace/index.ts +0 -7
  67. package/src/namespaces/OptionsNamespace/validators.ts +0 -13
  68. package/src/namespaces/PluginsNamespace/PluginsNamespace.ts +0 -291
  69. package/src/namespaces/PluginsNamespace/constants.ts +0 -34
  70. package/src/namespaces/PluginsNamespace/index.ts +0 -7
  71. package/src/namespaces/PluginsNamespace/types.ts +0 -22
  72. package/src/namespaces/PluginsNamespace/validators.ts +0 -28
  73. package/src/namespaces/RouteLifecycleNamespace/RouteLifecycleNamespace.ts +0 -558
  74. package/src/namespaces/RouteLifecycleNamespace/index.ts +0 -5
  75. package/src/namespaces/RouteLifecycleNamespace/types.ts +0 -10
  76. package/src/namespaces/RouterLifecycleNamespace/RouterLifecycleNamespace.ts +0 -81
  77. package/src/namespaces/RouterLifecycleNamespace/constants.ts +0 -25
  78. package/src/namespaces/RouterLifecycleNamespace/index.ts +0 -5
  79. package/src/namespaces/RouterLifecycleNamespace/types.ts +0 -30
  80. package/src/namespaces/RoutesNamespace/RoutesNamespace.ts +0 -582
  81. package/src/namespaces/RoutesNamespace/constants.ts +0 -6
  82. package/src/namespaces/RoutesNamespace/forwardChain.ts +0 -34
  83. package/src/namespaces/RoutesNamespace/helpers.ts +0 -204
  84. package/src/namespaces/RoutesNamespace/index.ts +0 -11
  85. package/src/namespaces/RoutesNamespace/routeGuards.ts +0 -62
  86. package/src/namespaces/RoutesNamespace/routesStore.ts +0 -566
  87. package/src/namespaces/RoutesNamespace/types.ts +0 -81
  88. package/src/namespaces/StateNamespace/StateNamespace.ts +0 -224
  89. package/src/namespaces/StateNamespace/helpers.ts +0 -24
  90. package/src/namespaces/StateNamespace/index.ts +0 -5
  91. package/src/namespaces/StateNamespace/types.ts +0 -15
  92. package/src/namespaces/index.ts +0 -35
  93. package/src/stateMetaStore.ts +0 -15
  94. package/src/transitionPath.ts +0 -440
  95. package/src/typeGuards.ts +0 -59
  96. package/src/types/RouterValidator.ts +0 -156
  97. package/src/types.ts +0 -77
  98. package/src/utils/createRequestScope.ts +0 -174
  99. package/src/utils/getStaticPaths.ts +0 -50
  100. package/src/utils/hydrateRouter.ts +0 -89
  101. package/src/utils/index.ts +0 -27
  102. package/src/utils/serializeRouterState.ts +0 -120
  103. package/src/utils/serializeState.ts +0 -63
  104. package/src/validation.ts +0 -12
  105. package/src/wiring/RouterWiringBuilder.ts +0 -275
  106. package/src/wiring/index.ts +0 -7
  107. package/src/wiring/types.ts +0 -47
  108. package/src/wiring/wireRouter.ts +0 -26
@@ -1,440 +0,0 @@
1
- // packages/core/src/transitionPath.ts
2
-
3
- import { getStateMetaParams } from "./stateMetaStore";
4
-
5
- import type { State } from "@real-router/types";
6
-
7
- /**
8
- * Parameters extracted from a route segment.
9
- * Maps parameter names to their string values.
10
- */
11
- type PrimitiveParam = string | number | boolean;
12
-
13
- /**
14
- * Represents a transition path between two router states.
15
- * Contains information about which route segments need to be activated/deactivated.
16
- */
17
- export interface TransitionPath {
18
- /** The common ancestor route segment where paths diverge */
19
- intersection: string;
20
- /** Route segments that need to be deactivated (in reverse order) */
21
- toDeactivate: string[];
22
- /** Route segments that need to be activated (in order) */
23
- toActivate: string[];
24
- }
25
-
26
- // Constants for better maintainability
27
- const ROUTE_SEGMENT_SEPARATOR = ".";
28
- const EMPTY_INTERSECTION = "";
29
- const DEFAULT_ROUTE_NAME = "";
30
- const FROZEN_EMPTY_ARRAY: string[] = [];
31
-
32
- Object.freeze(FROZEN_EMPTY_ARRAY);
33
-
34
- /**
35
- * Builds a reversed copy of a string array.
36
- * Optimization: single pass instead of creating intermediate array with .toReversed().
37
- *
38
- * @param arr - Source array
39
- * @returns New array with elements in reverse order
40
- * @internal
41
- */
42
- function reverseArray(arr: string[]): string[] {
43
- const length = arr.length;
44
- const result: string[] = [];
45
-
46
- for (let i = length - 1; i >= 0; i--) {
47
- result.push(arr[i]);
48
- }
49
-
50
- return result;
51
- }
52
-
53
- /**
54
- * Handles conversion of route names with many segments (5+).
55
- * Internal helper for nameToIDs function.
56
- *
57
- * Uses optimized hybrid approach: split to get segments, then slice original
58
- * string to build cumulative paths. This approach is 65-81% faster than
59
- * string concatenation for typical cases (5-10 segments).
60
- *
61
- * @param name - Route name with 5 or more segments
62
- * @returns Array of cumulative segment IDs
63
- * @throws {Error} If route depth exceeds maximum allowed
64
- * @internal
65
- */
66
- function nameToIDsGeneral(name: string): string[] {
67
- // We know there are at least 5 segments at this point (after fast paths)
68
- const segments = name.split(ROUTE_SEGMENT_SEPARATOR);
69
- const segmentCount = segments.length;
70
-
71
- // First segment is always just itself
72
- const ids: string[] = [segments[0]];
73
-
74
- // Calculate cumulative lengths and slice from original string
75
- // This avoids repeated string concatenation (O(k²) → O(k))
76
- let cumulativeLength = segments[0].length;
77
-
78
- for (let i = 1; i < segmentCount - 1; i++) {
79
- cumulativeLength += 1 + segments[i].length; // +1 for dot separator
80
- ids.push(name.slice(0, cumulativeLength));
81
- }
82
-
83
- // Last segment is always the full route name
84
- ids.push(name);
85
-
86
- return ids;
87
- }
88
-
89
- const PRIMITIVE_TYPES: ReadonlySet<string> = new Set([
90
- "string",
91
- "number",
92
- "boolean",
93
- ]);
94
-
95
- function isPrimitive(value: unknown): value is PrimitiveParam {
96
- return PRIMITIVE_TYPES.has(typeof value);
97
- }
98
-
99
- /**
100
- * Compares segment parameters between two states without creating intermediate objects.
101
- * Returns true if all primitive params for the given segment are equal in both states.
102
- */
103
- function segmentParamsEqual(
104
- name: string,
105
- toMetaParams: Record<string, unknown>,
106
- toState: State,
107
- fromState: State,
108
- ): boolean {
109
- const keys = toMetaParams[name];
110
-
111
- if (!keys || typeof keys !== "object") {
112
- return true;
113
- }
114
-
115
- for (const key of Object.keys(keys)) {
116
- const toVal = toState.params[key];
117
- const fromVal = fromState.params[key];
118
-
119
- if (
120
- isPrimitive(toVal) &&
121
- isPrimitive(fromVal) &&
122
- String(toVal) !== String(fromVal)
123
- ) {
124
- return false;
125
- }
126
- }
127
-
128
- return true;
129
- }
130
-
131
- /**
132
- * Finds the point where two state paths diverge based on segments and parameters.
133
- * Compares both segment names and their parameters to find the first difference.
134
- *
135
- * @param toMetaParams - Cached meta.params from toState (avoids per-segment WeakMap lookup)
136
- * @param toState - Target state
137
- * @param fromState - Source state
138
- * @param toStateIds - Segment IDs for target state
139
- * @param fromStateIds - Segment IDs for source state
140
- * @param maxI - Maximum index to check (minimum of both arrays)
141
- * @returns Index of first difference, or maxI if all checked segments match
142
- */
143
- function pointOfDifference(
144
- toMetaParams: Record<string, unknown>,
145
- toState: State,
146
- fromState: State,
147
- toStateIds: string[],
148
- fromStateIds: string[],
149
- maxI: number,
150
- ): number {
151
- for (let i = 0; i < maxI; i++) {
152
- const toSegment = toStateIds[i];
153
- const fromSegment = fromStateIds[i];
154
-
155
- // Different segment names - immediate difference
156
- if (toSegment !== fromSegment) {
157
- return i;
158
- }
159
-
160
- if (!segmentParamsEqual(toSegment, toMetaParams, toState, fromState)) {
161
- return i;
162
- }
163
- }
164
-
165
- return maxI;
166
- }
167
-
168
- /**
169
- * Converts a route name to an array of hierarchical segment identifiers.
170
- * Each segment ID includes all parent segments in the path.
171
- *
172
- * @param name - Route name in dot notation (e.g., 'users.profile.edit')
173
- * @returns Array of cumulative segment IDs
174
- * @throws {Error} If route depth exceeds maximum allowed depth
175
- *
176
- * @example
177
- * // Simple route
178
- * nameToIDs('users');
179
- * // Returns: ['users']
180
- *
181
- * @example
182
- * // Nested route
183
- * nameToIDs('users.profile.edit');
184
- * // Returns: ['users', 'users.profile', 'users.profile.edit']
185
- *
186
- * @example
187
- * // Empty string (root route)
188
- * nameToIDs('');
189
- * // Returns: ['']
190
- *
191
- * @remarks
192
- * Input parameter is NOT validated in this function for performance reasons.
193
- * Validation significantly slows down nameToIDs execution.
194
- * The input should be validated by the function/method that calls nameToIDs.
195
- */
196
- const nameToIDsCache = new Map<string, string[]>();
197
-
198
- export function nameToIDs(name: string): string[] {
199
- const cached = nameToIDsCache.get(name);
200
-
201
- if (cached) {
202
- return cached;
203
- }
204
-
205
- const result = computeNameToIDs(name);
206
-
207
- Object.freeze(result);
208
- nameToIDsCache.set(name, result);
209
-
210
- return result;
211
- }
212
-
213
- function computeNameToIDs(name: string): string[] {
214
- if (!name) {
215
- return [DEFAULT_ROUTE_NAME];
216
- }
217
-
218
- const firstDot = name.indexOf(ROUTE_SEGMENT_SEPARATOR);
219
-
220
- if (firstDot === -1) {
221
- return [name];
222
- }
223
-
224
- const secondDot = name.indexOf(ROUTE_SEGMENT_SEPARATOR, firstDot + 1);
225
-
226
- if (secondDot === -1) {
227
- return [name.slice(0, firstDot), name];
228
- }
229
-
230
- const thirdDot = name.indexOf(ROUTE_SEGMENT_SEPARATOR, secondDot + 1);
231
-
232
- if (thirdDot === -1) {
233
- return [name.slice(0, firstDot), name.slice(0, secondDot), name];
234
- }
235
-
236
- const fourthDot = name.indexOf(ROUTE_SEGMENT_SEPARATOR, thirdDot + 1);
237
-
238
- if (fourthDot === -1) {
239
- return [
240
- name.slice(0, firstDot),
241
- name.slice(0, secondDot),
242
- name.slice(0, thirdDot),
243
- name,
244
- ];
245
- }
246
-
247
- return nameToIDsGeneral(name);
248
- }
249
-
250
- /**
251
- * Calculates the transition path between two router states.
252
- * Determines which route segments need to be deactivated and activated
253
- * to transition from one state to another.
254
- *
255
- * @param toState - Target state to transition to
256
- * @param fromState - Current state to transition from (optional)
257
- * @returns Transition path with intersection and segments to activate/deactivate
258
- *
259
- * @throws {TypeError} When toState is null or undefined
260
- * @throws {TypeError} When toState is not an object
261
- * @throws {TypeError} When toState.name is missing or not a string
262
- * @throws {TypeError} When toState.params is missing or not an object
263
- * @throws {TypeError} When toState.path is missing or not a string
264
- * @throws {TypeError} When toState.name contains invalid route format:
265
- * - Contains only whitespace (e.g., " ")
266
- * - Has consecutive dots (e.g., "users..profile")
267
- * - Has leading/trailing dots (e.g., ".users" or "users.")
268
- * - Segments don't match pattern [a-zA-Z_][a-zA-Z0-9_-]* (e.g., "users.123")
269
- * - Contains spaces or special characters (e.g., "users profile")
270
- * - Exceeds maximum length (8192 characters)
271
- * @throws {TypeError} When fromState is provided and has any of the validation errors listed above for toState
272
- *
273
- * @example
274
- * // ✅ Valid calls
275
- * getTransitionPath({ name: 'users.profile', params: {}, path: '/users/profile' });
276
- * getTransitionPath(toState, fromState);
277
- * getTransitionPath({ name: '', params: {}, path: '/' }); // root route
278
- *
279
- * @example
280
- * // ❌ Invalid calls that throw TypeError
281
- * getTransitionPath(null); // toState is null
282
- * getTransitionPath(undefined); // toState is undefined
283
- * getTransitionPath({}); // missing required fields
284
- * getTransitionPath({ name: 123, params: {}, path: '/' }); // name not a string
285
- * getTransitionPath({ name: 'home', path: '/' }); // missing params
286
- * getTransitionPath({ name: 'users..profile', params: {}, path: '/' }); // consecutive dots
287
- * getTransitionPath({ name: '.users', params: {}, path: '/' }); // leading dot
288
- * getTransitionPath({ name: 'users.', params: {}, path: '/' }); // trailing dot
289
- * getTransitionPath({ name: 'users profile', params: {}, path: '/' }); // contains space
290
- * getTransitionPath({ name: 'users.123', params: {}, path: '/' }); // segment starts with number
291
- * getTransitionPath(validToState, { name: 'invalid..route', params: {}, path: '/' }); // fromState invalid
292
- *
293
- * @example
294
- * // Full activation (no fromState)
295
- * getTransitionPath(makeState('users.profile'));
296
- * // Returns: {
297
- * // intersection: '',
298
- * // toActivate: ['users', 'users.profile'],
299
- * // toDeactivate: []
300
- * // }
301
- *
302
- * @example
303
- * // Partial transition with common ancestor
304
- * getTransitionPath(
305
- * makeState('users.profile'),
306
- * makeState('users.list')
307
- * );
308
- * // Returns: {
309
- * // intersection: 'users',
310
- * // toActivate: ['users.profile'],
311
- * // toDeactivate: ['users.list']
312
- * // }
313
- *
314
- * @example
315
- * // Complete route change
316
- * getTransitionPath(
317
- * makeState('admin.dashboard'),
318
- * makeState('users.profile')
319
- * );
320
- * // Returns: {
321
- * // intersection: '',
322
- * // toActivate: ['admin', 'admin.dashboard'],
323
- * // toDeactivate: ['users.profile', 'users']
324
- * // }
325
- */
326
- // Single-entry cache: shouldUpdateNode calls getTransitionPath N times per
327
- // navigation with the same state objects (once per subscribed node).
328
- // Cache by reference eliminates N-1 redundant computations.
329
- let cached1To: State | undefined;
330
- let cached1From: State | undefined;
331
- let cached1Result: TransitionPath | null = null;
332
-
333
- let cached2To: State | undefined;
334
- let cached2From: State | undefined;
335
- let cached2Result: TransitionPath | null = null;
336
-
337
- function computeTransitionPath(
338
- toState: State,
339
- fromState?: State,
340
- ): TransitionPath {
341
- // ===== FAST PATH 1: Initial navigation (no fromState) =====
342
- // This is the best performing case in benchmarks (5M ops/sec)
343
- if (!fromState) {
344
- return {
345
- intersection: EMPTY_INTERSECTION,
346
- toActivate: nameToIDs(toState.name),
347
- toDeactivate: FROZEN_EMPTY_ARRAY,
348
- };
349
- }
350
-
351
- // ===== FAST PATH 3: Missing meta requires full reload =====
352
- // Single WeakMap lookup per state, reused in pointOfDifference/segmentParamsEqual
353
- const toMetaParams = getStateMetaParams(toState);
354
- const fromMetaParams = getStateMetaParams(fromState);
355
-
356
- if (!toMetaParams && !fromMetaParams) {
357
- return {
358
- intersection: EMPTY_INTERSECTION,
359
- toActivate: nameToIDs(toState.name),
360
- toDeactivate: reverseArray(nameToIDs(fromState.name)),
361
- };
362
- }
363
-
364
- // ===== STANDARD PATH: Routes with parameters =====
365
- const toStateIds = nameToIDs(toState.name);
366
- const fromStateIds = nameToIDs(fromState.name);
367
- const maxI = Math.min(fromStateIds.length, toStateIds.length);
368
-
369
- const i = pointOfDifference(
370
- (toMetaParams ?? fromMetaParams) as Record<string, unknown>,
371
- toState,
372
- fromState,
373
- toStateIds,
374
- fromStateIds,
375
- maxI,
376
- );
377
-
378
- // Optimization: Build deactivation list in reverse order directly
379
- // instead of slice(i).toReversed() which creates 2 arrays
380
- let toDeactivate: string[];
381
-
382
- if (i >= fromStateIds.length) {
383
- toDeactivate = FROZEN_EMPTY_ARRAY;
384
- } else if (i === 0 && fromStateIds.length === 1) {
385
- // Single-segment route: reversed = original, reuse cached frozen array
386
- toDeactivate = fromStateIds;
387
- } else {
388
- toDeactivate = [];
389
-
390
- for (let j = fromStateIds.length - 1; j >= i; j--) {
391
- toDeactivate.push(fromStateIds[j]);
392
- }
393
- }
394
-
395
- // Build activation list — reuse cached frozen array when using full list
396
- const toActivate = i === 0 ? toStateIds : toStateIds.slice(i);
397
-
398
- // Determine intersection point (common ancestor)
399
- const intersection = i > 0 ? fromStateIds[i - 1] : EMPTY_INTERSECTION;
400
-
401
- return {
402
- intersection,
403
- toDeactivate,
404
- toActivate,
405
- };
406
- }
407
-
408
- export function getTransitionPath(
409
- toState: State,
410
- fromState?: State,
411
- ): TransitionPath {
412
- if (
413
- cached1Result !== null &&
414
- toState === cached1To &&
415
- fromState === cached1From
416
- ) {
417
- return cached1Result;
418
- }
419
-
420
- /* v8 ignore next 6 -- @preserve: 2nd cache slot hit path exercised by alternating navigation benchmarks, not unit tests */
421
- if (
422
- cached2Result !== null &&
423
- toState === cached2To &&
424
- fromState === cached2From
425
- ) {
426
- return cached2Result;
427
- }
428
-
429
- const result = computeTransitionPath(toState, fromState);
430
-
431
- cached2To = cached1To;
432
- cached2From = cached1From;
433
- cached2Result = cached1Result;
434
-
435
- cached1To = toState;
436
- cached1From = fromState;
437
- cached1Result = result;
438
-
439
- return result;
440
- }
package/src/typeGuards.ts DELETED
@@ -1,59 +0,0 @@
1
- // packages/core/src/typeGuards.ts
2
-
3
- /**
4
- * RealRouter-specific type guards for logger configuration
5
- */
6
- import type { LoggerConfig, LogLevelConfig } from "@real-router/logger";
7
-
8
- const VALID_LEVELS_SET = new Set<string>(["all", "warn-error", "error-only"]);
9
-
10
- function isValidLevel(value: unknown): value is LogLevelConfig {
11
- return typeof value === "string" && VALID_LEVELS_SET.has(value);
12
- }
13
-
14
- function formatValue(value: unknown): string {
15
- if (typeof value === "string") {
16
- return `"${value}"`;
17
- }
18
- if (typeof value === "object") {
19
- return JSON.stringify(value);
20
- }
21
-
22
- // eslint-disable-next-line @typescript-eslint/no-base-to-string
23
- return String(value);
24
- }
25
-
26
- export function isLoggerConfig(config: unknown): config is LoggerConfig {
27
- if (typeof config !== "object" || config === null) {
28
- throw new TypeError("Logger config must be an object");
29
- }
30
-
31
- const obj = config;
32
-
33
- // Check for unknown properties
34
- for (const key of Object.keys(obj)) {
35
- if (key !== "level" && key !== "callback") {
36
- throw new TypeError(`Unknown logger config property: "${key}"`);
37
- }
38
- }
39
-
40
- // Validate level if present
41
- if ("level" in obj && obj.level !== undefined && !isValidLevel(obj.level)) {
42
- throw new TypeError(
43
- `Invalid logger level: ${formatValue(obj.level)}. Expected: "all" | "warn-error" | "error-only"`,
44
- );
45
- }
46
-
47
- // Validate callback if present
48
- if (
49
- "callback" in obj &&
50
- obj.callback !== undefined &&
51
- typeof obj.callback !== "function"
52
- ) {
53
- throw new TypeError(
54
- `Logger callback must be a function, got ${typeof obj.callback}`,
55
- );
56
- }
57
-
58
- return true;
59
- }
@@ -1,156 +0,0 @@
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
- validateResolvedDefaultRoute: (routeName: unknown, store: unknown) => void;
60
- };
61
-
62
- /**
63
- * Dependencies validation methods
64
- */
65
- dependencies: {
66
- validateDependencyName: (name: unknown, caller: string) => void;
67
- validateSetDependencyArgs: (
68
- name: unknown,
69
- value: unknown,
70
- caller: string,
71
- ) => void;
72
- validateDependenciesObject: (deps: unknown, caller: string) => void;
73
- validateDependencyExists: (name: string, store: unknown) => void;
74
- validateDependencyLimit: (store: unknown, limits: unknown) => void;
75
- // Retrospective validation
76
- validateDependenciesStructure: (store: unknown) => void;
77
- validateDependencyCount: (store: unknown, methodName: string) => void;
78
- validateCloneArgs: (dependencies: unknown) => void;
79
- warnOverwrite: (name: string, methodName: string) => void;
80
- warnBatchOverwrite: (keys: string[], methodName: string) => void;
81
- warnRemoveNonExistent: (name: unknown) => void;
82
- };
83
-
84
- /**
85
- * Plugin validation methods
86
- */
87
- plugins: {
88
- validatePluginLimit: (count: number, limits: unknown) => void;
89
- validateNoDuplicatePlugins: (
90
- factory: unknown,
91
- factories: unknown[],
92
- ) => void;
93
- validatePluginKeys: (plugin: unknown) => void;
94
- validateCountThresholds: (count: number) => void;
95
- warnBatchDuplicates: (plugins: unknown[]) => void;
96
- warnPluginMethodType: (methodName: string) => void;
97
- warnPluginAfterStart: (methodName: string) => void;
98
- validateAddInterceptorArgs: (method: unknown, fn: unknown) => void;
99
- };
100
-
101
- /**
102
- * Lifecycle guard validation methods
103
- */
104
- lifecycle: {
105
- validateHandler: (handler: unknown, caller: string) => void;
106
- validateNotRegistering: (
107
- name: string,
108
- guards: unknown,
109
- caller: string,
110
- ) => void;
111
- validateHandlerLimit: (
112
- count: number,
113
- limits: unknown,
114
- caller: string,
115
- ) => void;
116
- validateCountThresholds: (count: number, methodName: string) => void;
117
- warnOverwrite: (name: string, type: string, methodName: string) => void;
118
- warnAsyncGuardSync: (name: string, methodName: string) => void;
119
- };
120
-
121
- /**
122
- * Navigation validation methods
123
- */
124
- navigation: {
125
- validateNavigateArgs: (name: unknown) => void;
126
- validateNavigateToDefaultArgs: (options: unknown) => void;
127
- validateNavigateToStateArgs: (state: unknown) => void;
128
- validateNavigationOptions: (options: unknown, caller: string) => void;
129
- validateParams: (params: unknown, methodName: string) => void;
130
- validateStartArgs: (path: unknown) => void;
131
- };
132
-
133
- /**
134
- * State validation methods
135
- */
136
- state: {
137
- validateMakeStateArgs: (
138
- name: unknown,
139
- params: unknown,
140
- path: unknown,
141
- ) => void;
142
- validateAreStatesEqualArgs: (
143
- s1: unknown,
144
- s2: unknown,
145
- ignoreQP: unknown,
146
- ) => void;
147
- };
148
-
149
- /**
150
- * Event bus validation methods
151
- */
152
- eventBus: {
153
- validateEventName: (name: unknown) => void;
154
- validateListenerArgs: (name: unknown, cb: unknown) => void;
155
- };
156
- }