Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | 2x 2x 1133x 1133x 1132x 1130x 1130x 11x 1119x 1130x 1133x 2x 11461x 11461x 8167x 11461x 2x 2284x 2284x 2284x 2253x 2253x 31x 31x 2x 260x 254x 2x 252x 260x 237x 237x 2x 7619x 7619x 7619x 7619x 6600x 5811x 5796x 7619x 2x 528x 249x 249x 508x 1x 1x 278x 278x 278x 278x 278x 278x 2x 990x 990x 990x 990x 990x 625x 867x 363x 990x 166x 990x 95x 990x 1x 990x 990x 2x 2232x 2232x 2232x 2232x 1321x 1321x 3x 9x 3x 1321x 1318x 1318x 1321x 2232x 2232x | import type { Route, RouteConfirmHookResult, RouteMatchType } from './types';
export const isBrowser = typeof window === 'object';
export function isNotNullish(value: unknown): boolean {
return (
value !== undefined &&
value !== null &&
!Number.isNaN(
value instanceof Number
? value.valueOf() // For new Number() cases
: value
)
);
}
export function isPlainObject(o: unknown): o is Record<string, any> {
return (
o?.constructor === Object ||
Object.prototype.toString.call(o) === '[object Object]'
);
}
/**
* Check if value is a valid non-empty plain object
* Only check enumerable string keys to ensure it's a proper plain object
* @param value Value to check
* @returns true if it's a valid non-empty plain object
*/
export function isNonEmptyPlainObject(
value: unknown
): value is Record<string, any> {
if (!isPlainObject(value)) {
return false;
}
// Only check enumerable string keys to ensure valid properties of plain object
return Object.keys(value as Record<string, any>).length > 0;
}
export const removeFromArray = <T>(arr: T[], ele: T) => {
if (!Array.isArray(arr) || arr.length === 0) return;
const i = Number.isNaN(ele)
? // If ele is NaN, use findIndex to search for NaN, because NaN !== NaN, so we can't use indexOf directly
arr.findIndex((item) => Number.isNaN(item))
: arr.indexOf(ele);
if (i === -1) return;
arr.splice(i, 1);
};
export function isValidConfirmHookResult(
result: unknown
): result is Exclude<RouteConfirmHookResult, void> {
return (
result === false ||
typeof result === 'function' ||
typeof result === 'string' ||
isPlainObject(result)
);
}
export function isUrlEqual(url1: URL, url2?: URL | null): boolean {
// If url2 doesn't exist, return false
if (!url2) {
return false;
}
// If it's the same object reference, return true directly
if (url1 === url2) {
return true;
}
// Copy and sort query parameters
(url1 = new URL(url1)).searchParams.sort();
(url2 = new URL(url2)).searchParams.sort();
// Avoid trailing hash symbol impact from empty hash
url1.hash = url1.hash;
url2.hash = url2.hash;
return url1.href === url2.href;
}
/**
* Compare if two routes match
*
* @param fromRoute First route object
* @param toRoute Second route object, may be null
* @param matchType Match type
* - 'route': Route-level matching, compare if route configurations are the same
* - 'exact': Exact matching, compare if full paths are the same
* - 'include': Include matching, check if route1 path starts with route2 path
* @returns Whether they match
*/
export function isRouteMatched(
fromRoute: Route,
toRoute: Route | null,
matchType: RouteMatchType
): boolean {
if (!toRoute) return false;
switch (matchType) {
case 'route':
// Route-level matching - compare route configurations
return fromRoute.config === toRoute.config;
case 'exact':
// Exact matching - full paths are identical
return fromRoute.fullPath === toRoute.fullPath;
case 'include':
// Include matching - route1 path contains route2 path
return fromRoute.fullPath.startsWith(toRoute.fullPath);
default:
return false;
}
}
export function decodeParams<T extends Record<string, string | string[]>>(
params: T
): T {
const result = {} as T;
for (const key in params) {
const value = params[key];
if (Array.isArray(value)) {
result[key] = value.map((item) =>
decodeURIComponent(item)
) as T[typeof key];
} else {
result[key] = decodeURIComponent(value) as T[typeof key];
}
}
return result;
}
|