@@ -8,6 +8,17 @@ import type {
88 RouterStateSnapshot ,
99} from "./types.js" ;
1010
11+ const NODE_ENV =
12+ ( globalThis as { process ?: { env ?: { NODE_ENV ?: string } } } ) . process ?. env ?. NODE_ENV ??
13+ "development" ;
14+ const DEV_MODE = NODE_ENV !== "production" ;
15+
16+ function warnDev ( message : string ) : void {
17+ if ( ! DEV_MODE ) return ;
18+ const c = ( globalThis as { console ?: { warn ?: ( msg : string ) => void } } ) . console ;
19+ c ?. warn ?.( message ) ;
20+ }
21+
1122const DEFAULT_HISTORY_DEPTH = 50 ;
1223
1324export type RouteRecord < S > = Readonly < {
@@ -30,6 +41,11 @@ function normalizeRouteId(routeId: string): string {
3041 if ( ! normalized ) {
3142 throwInvalidProps ( "route id must be a non-empty string" ) ;
3243 }
44+ if ( DEV_MODE && / [ ^ a - z A - Z 0 - 9 _ \- . ] / . test ( normalized ) ) {
45+ warnDev (
46+ `[rezi] route id "${ normalized } " contains non-identifier characters. Use only letters, digits, hyphens, underscores, and dots.` ,
47+ ) ;
48+ }
3349 return normalized ;
3450}
3551
@@ -40,7 +56,14 @@ export function normalizeRouteParams(params: RouteParams | undefined): RoutePara
4056 if ( ! params ) return Object . freeze ( { } ) ;
4157
4258 const entries = Object . entries ( params )
43- . map ( ( [ key , value ] ) => [ String ( key ) , String ( value ) ] as const )
59+ . map ( ( [ key , value ] ) => {
60+ if ( DEV_MODE && typeof value !== "string" ) {
61+ warnDev (
62+ `[rezi] route param "${ key } " has non-string value (${ typeof value } ), coerced to string. Pass string values to avoid implicit coercion.` ,
63+ ) ;
64+ }
65+ return [ String ( key ) , String ( value ) ] as const ;
66+ } )
4467 . sort ( ( a , b ) => {
4568 if ( a [ 0 ] < b [ 0 ] ) return - 1 ;
4669 if ( a [ 0 ] > b [ 0 ] ) return 1 ;
0 commit comments