@real-router/core 0.45.0 → 0.45.1
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/package.json +6 -7
- package/src/Router.ts +0 -684
- package/src/RouterError.ts +0 -324
- package/src/api/cloneRouter.ts +0 -77
- package/src/api/getDependenciesApi.ts +0 -168
- package/src/api/getLifecycleApi.ts +0 -65
- package/src/api/getPluginApi.ts +0 -167
- package/src/api/getRoutesApi.ts +0 -573
- package/src/api/helpers.ts +0 -10
- package/src/api/index.ts +0 -16
- package/src/api/types.ts +0 -12
- package/src/constants.ts +0 -87
- package/src/createRouter.ts +0 -32
- package/src/fsm/index.ts +0 -5
- package/src/fsm/routerFSM.ts +0 -120
- package/src/getNavigator.ts +0 -30
- package/src/guards.ts +0 -46
- package/src/helpers.ts +0 -179
- package/src/index.ts +0 -50
- package/src/internals.ts +0 -173
- package/src/namespaces/DependenciesNamespace/dependenciesStore.ts +0 -30
- package/src/namespaces/DependenciesNamespace/index.ts +0 -5
- package/src/namespaces/EventBusNamespace/EventBusNamespace.ts +0 -311
- package/src/namespaces/EventBusNamespace/index.ts +0 -5
- package/src/namespaces/EventBusNamespace/types.ts +0 -11
- package/src/namespaces/NavigationNamespace/NavigationNamespace.ts +0 -405
- package/src/namespaces/NavigationNamespace/constants.ts +0 -55
- package/src/namespaces/NavigationNamespace/index.ts +0 -5
- package/src/namespaces/NavigationNamespace/transition/completeTransition.ts +0 -100
- package/src/namespaces/NavigationNamespace/transition/errorHandling.ts +0 -124
- package/src/namespaces/NavigationNamespace/transition/guardPhase.ts +0 -221
- package/src/namespaces/NavigationNamespace/types.ts +0 -100
- package/src/namespaces/OptionsNamespace/OptionsNamespace.ts +0 -28
- package/src/namespaces/OptionsNamespace/constants.ts +0 -19
- package/src/namespaces/OptionsNamespace/helpers.ts +0 -50
- package/src/namespaces/OptionsNamespace/index.ts +0 -7
- package/src/namespaces/OptionsNamespace/validators.ts +0 -13
- package/src/namespaces/PluginsNamespace/PluginsNamespace.ts +0 -291
- package/src/namespaces/PluginsNamespace/constants.ts +0 -34
- package/src/namespaces/PluginsNamespace/index.ts +0 -7
- package/src/namespaces/PluginsNamespace/types.ts +0 -22
- package/src/namespaces/PluginsNamespace/validators.ts +0 -28
- package/src/namespaces/RouteLifecycleNamespace/RouteLifecycleNamespace.ts +0 -377
- package/src/namespaces/RouteLifecycleNamespace/index.ts +0 -5
- package/src/namespaces/RouteLifecycleNamespace/types.ts +0 -10
- package/src/namespaces/RouterLifecycleNamespace/RouterLifecycleNamespace.ts +0 -81
- package/src/namespaces/RouterLifecycleNamespace/constants.ts +0 -25
- package/src/namespaces/RouterLifecycleNamespace/index.ts +0 -5
- package/src/namespaces/RouterLifecycleNamespace/types.ts +0 -26
- package/src/namespaces/RoutesNamespace/RoutesNamespace.ts +0 -535
- package/src/namespaces/RoutesNamespace/constants.ts +0 -6
- package/src/namespaces/RoutesNamespace/forwardChain.ts +0 -34
- package/src/namespaces/RoutesNamespace/helpers.ts +0 -126
- package/src/namespaces/RoutesNamespace/index.ts +0 -11
- package/src/namespaces/RoutesNamespace/routeGuards.ts +0 -62
- package/src/namespaces/RoutesNamespace/routesStore.ts +0 -346
- package/src/namespaces/RoutesNamespace/types.ts +0 -81
- package/src/namespaces/StateNamespace/StateNamespace.ts +0 -211
- package/src/namespaces/StateNamespace/helpers.ts +0 -24
- package/src/namespaces/StateNamespace/index.ts +0 -5
- package/src/namespaces/StateNamespace/types.ts +0 -15
- package/src/namespaces/index.ts +0 -35
- package/src/stateMetaStore.ts +0 -15
- package/src/transitionPath.ts +0 -436
- package/src/typeGuards.ts +0 -59
- package/src/types/RouterValidator.ts +0 -154
- package/src/types.ts +0 -69
- package/src/utils/getStaticPaths.ts +0 -50
- package/src/utils/index.ts +0 -5
- package/src/utils/serializeState.ts +0 -22
- package/src/validation.ts +0 -12
- package/src/wiring/RouterWiringBuilder.ts +0 -261
- package/src/wiring/index.ts +0 -7
- package/src/wiring/types.ts +0 -47
- package/src/wiring/wireRouter.ts +0 -26
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import { handleGuardError } from "./errorHandling";
|
|
2
|
-
import { errorCodes } from "../../../constants";
|
|
3
|
-
import { RouterError } from "../../../RouterError";
|
|
4
|
-
|
|
5
|
-
import type { GuardFn, State } from "@real-router/types";
|
|
6
|
-
|
|
7
|
-
async function resolveAsyncGuard(
|
|
8
|
-
promise: Promise<boolean>,
|
|
9
|
-
errorCode: string,
|
|
10
|
-
segment: string,
|
|
11
|
-
): Promise<void> {
|
|
12
|
-
let result: boolean;
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
result = await promise;
|
|
16
|
-
} catch (error: unknown) {
|
|
17
|
-
handleGuardError(error, errorCode, segment);
|
|
18
|
-
|
|
19
|
-
return; // unreachable — handleGuardError returns never
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (!result) {
|
|
23
|
-
throw new RouterError(errorCode, { segment });
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async function resolveRemainingGuards( // NOSONAR -- params kept flat to avoid object allocation on hot path
|
|
28
|
-
guards: Map<string, GuardFn>,
|
|
29
|
-
segments: string[],
|
|
30
|
-
errorCode: string,
|
|
31
|
-
toState: State,
|
|
32
|
-
fromState: State | undefined,
|
|
33
|
-
signal: AbortSignal | undefined,
|
|
34
|
-
isActive: () => boolean,
|
|
35
|
-
startIndex: number,
|
|
36
|
-
firstResult: Promise<boolean>,
|
|
37
|
-
firstSegment: string,
|
|
38
|
-
): Promise<void> {
|
|
39
|
-
await resolveAsyncGuard(firstResult, errorCode, firstSegment);
|
|
40
|
-
|
|
41
|
-
for (let i = startIndex; i < segments.length; i++) {
|
|
42
|
-
if (!isActive()) {
|
|
43
|
-
throw new RouterError(errorCodes.TRANSITION_CANCELLED);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const segment = segments[i];
|
|
47
|
-
const guardFn = guards.get(segment);
|
|
48
|
-
|
|
49
|
-
if (!guardFn) {
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
let guardResult: boolean | Promise<boolean> = false;
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
guardResult = guardFn(toState, fromState, signal);
|
|
57
|
-
} catch (error: unknown) {
|
|
58
|
-
handleGuardError(error, errorCode, segment);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (guardResult instanceof Promise) {
|
|
62
|
-
await resolveAsyncGuard(guardResult, errorCode, segment);
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (!guardResult) {
|
|
67
|
-
throw new RouterError(errorCode, { segment });
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async function finishAsyncPipeline( // NOSONAR
|
|
73
|
-
deactivateCompletion: Promise<void>,
|
|
74
|
-
activateGuards: Map<string, GuardFn>,
|
|
75
|
-
toActivate: string[],
|
|
76
|
-
shouldActivate: boolean,
|
|
77
|
-
toState: State,
|
|
78
|
-
fromState: State | undefined,
|
|
79
|
-
signal: AbortSignal,
|
|
80
|
-
isActive: () => boolean,
|
|
81
|
-
emitLeaveApprove: () => void,
|
|
82
|
-
): Promise<void> {
|
|
83
|
-
await deactivateCompletion;
|
|
84
|
-
|
|
85
|
-
if (!isActive()) {
|
|
86
|
-
throw new RouterError(errorCodes.TRANSITION_CANCELLED);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
emitLeaveApprove();
|
|
90
|
-
|
|
91
|
-
if (shouldActivate) {
|
|
92
|
-
const pending = runGuards(
|
|
93
|
-
activateGuards,
|
|
94
|
-
toActivate,
|
|
95
|
-
errorCodes.CANNOT_ACTIVATE,
|
|
96
|
-
toState,
|
|
97
|
-
fromState,
|
|
98
|
-
signal,
|
|
99
|
-
isActive,
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
if (pending !== undefined) {
|
|
103
|
-
await pending;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (!isActive()) {
|
|
107
|
-
throw new RouterError(errorCodes.TRANSITION_CANCELLED);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export function executeGuardPipeline( // NOSONAR
|
|
113
|
-
deactivateGuards: Map<string, GuardFn>,
|
|
114
|
-
activateGuards: Map<string, GuardFn>,
|
|
115
|
-
toDeactivate: string[],
|
|
116
|
-
toActivate: string[],
|
|
117
|
-
shouldDeactivate: boolean,
|
|
118
|
-
shouldActivate: boolean,
|
|
119
|
-
toState: State,
|
|
120
|
-
fromState: State | undefined,
|
|
121
|
-
signal: AbortSignal,
|
|
122
|
-
isActive: () => boolean,
|
|
123
|
-
emitLeaveApprove: () => void,
|
|
124
|
-
): Promise<void> | undefined {
|
|
125
|
-
if (shouldDeactivate) {
|
|
126
|
-
const pending = runGuards(
|
|
127
|
-
deactivateGuards,
|
|
128
|
-
toDeactivate,
|
|
129
|
-
errorCodes.CANNOT_DEACTIVATE,
|
|
130
|
-
toState,
|
|
131
|
-
fromState,
|
|
132
|
-
signal,
|
|
133
|
-
isActive,
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
if (pending !== undefined) {
|
|
137
|
-
return finishAsyncPipeline(
|
|
138
|
-
pending,
|
|
139
|
-
activateGuards,
|
|
140
|
-
toActivate,
|
|
141
|
-
shouldActivate,
|
|
142
|
-
toState,
|
|
143
|
-
fromState,
|
|
144
|
-
signal,
|
|
145
|
-
isActive,
|
|
146
|
-
emitLeaveApprove,
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (!isActive()) {
|
|
152
|
-
throw new RouterError(errorCodes.TRANSITION_CANCELLED);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
emitLeaveApprove();
|
|
156
|
-
|
|
157
|
-
if (shouldActivate) {
|
|
158
|
-
return runGuards(
|
|
159
|
-
activateGuards,
|
|
160
|
-
toActivate,
|
|
161
|
-
errorCodes.CANNOT_ACTIVATE,
|
|
162
|
-
toState,
|
|
163
|
-
fromState,
|
|
164
|
-
signal,
|
|
165
|
-
isActive,
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return undefined;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function runGuards(
|
|
173
|
-
guards: Map<string, GuardFn>,
|
|
174
|
-
segments: string[],
|
|
175
|
-
errorCode: string,
|
|
176
|
-
toState: State,
|
|
177
|
-
fromState: State | undefined,
|
|
178
|
-
signal: AbortSignal | undefined,
|
|
179
|
-
isActive: () => boolean,
|
|
180
|
-
): Promise<void> | undefined {
|
|
181
|
-
for (const [i, segment] of segments.entries()) {
|
|
182
|
-
if (!isActive()) {
|
|
183
|
-
throw new RouterError(errorCodes.TRANSITION_CANCELLED);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const guardFn = guards.get(segment);
|
|
187
|
-
|
|
188
|
-
if (!guardFn) {
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
let guardResult: boolean | Promise<boolean> = false;
|
|
193
|
-
|
|
194
|
-
try {
|
|
195
|
-
guardResult = guardFn(toState, fromState, signal);
|
|
196
|
-
} catch (error: unknown) {
|
|
197
|
-
handleGuardError(error, errorCode, segment);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (guardResult instanceof Promise) {
|
|
201
|
-
return resolveRemainingGuards(
|
|
202
|
-
guards,
|
|
203
|
-
segments,
|
|
204
|
-
errorCode,
|
|
205
|
-
toState,
|
|
206
|
-
fromState,
|
|
207
|
-
signal,
|
|
208
|
-
isActive,
|
|
209
|
-
i + 1,
|
|
210
|
-
guardResult,
|
|
211
|
-
segment,
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (!guardResult) {
|
|
216
|
-
throw new RouterError(errorCode, { segment });
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return undefined;
|
|
221
|
-
}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
// packages/core/src/namespaces/NavigationNamespace/types.ts
|
|
2
|
-
|
|
3
|
-
import type {
|
|
4
|
-
GuardFn,
|
|
5
|
-
NavigationOptions,
|
|
6
|
-
Options,
|
|
7
|
-
Params,
|
|
8
|
-
State,
|
|
9
|
-
} from "@real-router/types";
|
|
10
|
-
|
|
11
|
-
export interface NavigationContext {
|
|
12
|
-
toState: State;
|
|
13
|
-
fromState: State | undefined;
|
|
14
|
-
opts: NavigationOptions;
|
|
15
|
-
toDeactivate: string[];
|
|
16
|
-
toActivate: string[];
|
|
17
|
-
intersection: string;
|
|
18
|
-
canDeactivateFunctions: Map<string, GuardFn>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Dependencies injected into NavigationNamespace.
|
|
23
|
-
*
|
|
24
|
-
* These are function references from other namespaces/facade,
|
|
25
|
-
* avoiding the need to pass the entire Router object.
|
|
26
|
-
**/
|
|
27
|
-
export interface NavigationDependencies {
|
|
28
|
-
/** Get router options */
|
|
29
|
-
getOptions: () => Options;
|
|
30
|
-
|
|
31
|
-
/** Check if route exists */
|
|
32
|
-
hasRoute: (name: string) => boolean;
|
|
33
|
-
|
|
34
|
-
/** Get current state */
|
|
35
|
-
getState: () => State | undefined;
|
|
36
|
-
|
|
37
|
-
/** Set router state */
|
|
38
|
-
setState: (state: State) => void;
|
|
39
|
-
|
|
40
|
-
/** Build complete navigate state: forwardState + route check + buildPath + makeState in one step */
|
|
41
|
-
buildNavigateState: (
|
|
42
|
-
routeName: string,
|
|
43
|
-
routeParams: Params,
|
|
44
|
-
) => State | undefined;
|
|
45
|
-
|
|
46
|
-
/** Resolve defaultRoute and defaultParams options (static value or callback) */
|
|
47
|
-
resolveDefault: () => { route: string; params: Params };
|
|
48
|
-
|
|
49
|
-
/** Start transition and send NAVIGATE event to routerFSM */
|
|
50
|
-
startTransition: (toState: State, fromState: State | undefined) => void;
|
|
51
|
-
|
|
52
|
-
/** Cancel navigation if transition is running */
|
|
53
|
-
cancelNavigation: () => void;
|
|
54
|
-
|
|
55
|
-
/** Send COMPLETE event to routerFSM */
|
|
56
|
-
sendTransitionDone: (
|
|
57
|
-
state: State,
|
|
58
|
-
fromState: State | undefined,
|
|
59
|
-
opts: NavigationOptions,
|
|
60
|
-
) => void;
|
|
61
|
-
|
|
62
|
-
/** Send FAIL event to routerFSM */
|
|
63
|
-
sendTransitionFail: (
|
|
64
|
-
toState: State,
|
|
65
|
-
fromState: State | undefined,
|
|
66
|
-
error: unknown,
|
|
67
|
-
) => void;
|
|
68
|
-
|
|
69
|
-
/** Emit TRANSITION_ERROR event to listeners */
|
|
70
|
-
emitTransitionError: (
|
|
71
|
-
toState: State | undefined,
|
|
72
|
-
fromState: State | undefined,
|
|
73
|
-
error: unknown,
|
|
74
|
-
) => void;
|
|
75
|
-
|
|
76
|
-
/** Emit TRANSITION_SUCCESS event to listeners (without FSM transition) */
|
|
77
|
-
emitTransitionSuccess: (
|
|
78
|
-
toState: State,
|
|
79
|
-
fromState?: State,
|
|
80
|
-
opts?: NavigationOptions,
|
|
81
|
-
) => void;
|
|
82
|
-
|
|
83
|
-
/** Send LEAVE_APPROVE event to routerFSM and emit to listeners */
|
|
84
|
-
sendLeaveApprove: (toState: State, fromState: State | undefined) => void;
|
|
85
|
-
|
|
86
|
-
/** Check if navigation can begin (router is started) */
|
|
87
|
-
canNavigate: () => boolean;
|
|
88
|
-
|
|
89
|
-
/** Get lifecycle functions (canDeactivate, canActivate maps) */
|
|
90
|
-
getLifecycleFunctions: () => [Map<string, GuardFn>, Map<string, GuardFn>];
|
|
91
|
-
|
|
92
|
-
/** Check if router is active (for cancellation check on stop()) */
|
|
93
|
-
isActive: () => boolean;
|
|
94
|
-
|
|
95
|
-
/** Check if a transition is currently in progress */
|
|
96
|
-
isTransitioning: () => boolean;
|
|
97
|
-
|
|
98
|
-
/** Clear canDeactivate guard for a route */
|
|
99
|
-
clearCanDeactivate: (name: string) => void;
|
|
100
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// packages/core/src/namespaces/OptionsNamespace/OptionsNamespace.ts
|
|
2
|
-
|
|
3
|
-
import { defaultOptions } from "./constants";
|
|
4
|
-
import { deepFreeze } from "./helpers";
|
|
5
|
-
import { validateOptionsIsObject } from "./validators";
|
|
6
|
-
|
|
7
|
-
import type { Options } from "@real-router/types";
|
|
8
|
-
|
|
9
|
-
export class OptionsNamespace {
|
|
10
|
-
readonly #options: Readonly<Options>;
|
|
11
|
-
|
|
12
|
-
constructor(initialOptions: Partial<Options> = {}) {
|
|
13
|
-
this.#options = deepFreeze({
|
|
14
|
-
...defaultOptions,
|
|
15
|
-
...initialOptions,
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
static validateOptionsIsObject(
|
|
20
|
-
options: unknown,
|
|
21
|
-
): asserts options is Record<string, unknown> {
|
|
22
|
-
validateOptionsIsObject(options);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
get(): Readonly<Options> {
|
|
26
|
-
return this.#options;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// packages/core/src/namespaces/OptionsNamespace/constants.ts
|
|
2
|
-
|
|
3
|
-
import { DEFAULT_QUERY_PARAMS } from "route-tree";
|
|
4
|
-
|
|
5
|
-
import type { Options } from "@real-router/types";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Default options for the router.
|
|
9
|
-
*/
|
|
10
|
-
export const defaultOptions: Options = {
|
|
11
|
-
defaultRoute: "",
|
|
12
|
-
defaultParams: {},
|
|
13
|
-
trailingSlash: "preserve",
|
|
14
|
-
queryParamsMode: "loose",
|
|
15
|
-
queryParams: DEFAULT_QUERY_PARAMS,
|
|
16
|
-
urlParamsEncoding: "default",
|
|
17
|
-
allowNotFound: true,
|
|
18
|
-
rewritePathOnMatch: true,
|
|
19
|
-
} satisfies Options;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
// packages/core/src/namespaces/OptionsNamespace/helpers.ts
|
|
2
|
-
|
|
3
|
-
import type { Options, Params } from "@real-router/types";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Recursively freezes an object and all nested objects.
|
|
7
|
-
* Only freezes plain objects, not primitives or special objects.
|
|
8
|
-
*/
|
|
9
|
-
export function deepFreeze<T extends object>(obj: T): Readonly<T> {
|
|
10
|
-
Object.freeze(obj);
|
|
11
|
-
|
|
12
|
-
for (const key of Object.keys(obj)) {
|
|
13
|
-
const value = (obj as Record<string, unknown>)[key];
|
|
14
|
-
|
|
15
|
-
if (value && typeof value === "object" && value.constructor === Object) {
|
|
16
|
-
deepFreeze(value);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return obj;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Resolves an option value that can be static or a callback.
|
|
25
|
-
* If the value is a function, calls it with getDependency and returns the result.
|
|
26
|
-
* Otherwise, returns the value as-is.
|
|
27
|
-
*/
|
|
28
|
-
export function resolveOption(
|
|
29
|
-
value: Options["defaultRoute"],
|
|
30
|
-
getDependency: (name: string) => unknown,
|
|
31
|
-
): string;
|
|
32
|
-
|
|
33
|
-
export function resolveOption(
|
|
34
|
-
value: Options["defaultParams"],
|
|
35
|
-
getDependency: (name: string) => unknown,
|
|
36
|
-
): Params;
|
|
37
|
-
|
|
38
|
-
export function resolveOption(
|
|
39
|
-
value: Options["defaultRoute"] | Options["defaultParams"],
|
|
40
|
-
getDependency: (name: string) => unknown,
|
|
41
|
-
): string | Params {
|
|
42
|
-
if (typeof value === "function") {
|
|
43
|
-
// Runtime getDependency is (name: string) => unknown, but DefaultRouteCallback<object>
|
|
44
|
-
// expects <K extends keyof object>(name: K) => object[K] where keyof object = never.
|
|
45
|
-
// Cast needed to bridge generic constraint mismatch.
|
|
46
|
-
return value(getDependency as never);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return value;
|
|
50
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// packages/core/src/namespaces/OptionsNamespace/validators.ts
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Minimal crash guard for options.
|
|
5
|
-
* Full DX validation moved to @real-router/validation-plugin (retrospective pattern).
|
|
6
|
-
*/
|
|
7
|
-
export function validateOptionsIsObject(
|
|
8
|
-
options: unknown,
|
|
9
|
-
): asserts options is Record<string, unknown> {
|
|
10
|
-
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
11
|
-
throw new TypeError("[router.constructor] options must be a plain object");
|
|
12
|
-
}
|
|
13
|
-
}
|