router-kit 1.2.6 → 1.3.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.
- package/dist/context/RouterProvider.js +20 -2
- package/dist/hooks/useDynamicComponents.js +5 -7
- package/dist/hooks/useRouter.d.ts +2 -1
- package/dist/hooks/useRouter.js +2 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/utils/error/errors.d.ts +44 -0
- package/dist/utils/error/errors.js +77 -0
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import join from "url-join";
|
|
4
4
|
import Page404 from "../pages/404";
|
|
5
|
+
import { createRouterError, RouterErrorCode, RouterErrors, } from "../utils/error/errors";
|
|
5
6
|
import RouterContext from "./RouterContext";
|
|
6
7
|
const validateUrl = (url) => {
|
|
7
8
|
try {
|
|
@@ -56,7 +57,22 @@ const RouterProvider = ({ routes }) => {
|
|
|
56
57
|
}, []);
|
|
57
58
|
const pathValidation = (routeFullPath, currentPath) => {
|
|
58
59
|
const routePaths = routeFullPath.split("|");
|
|
60
|
+
const staticPaths = [];
|
|
61
|
+
const dynamicPaths = [];
|
|
59
62
|
for (const routePath of routePaths) {
|
|
63
|
+
if (routePath.includes(":")) {
|
|
64
|
+
dynamicPaths.push(routePath);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
staticPaths.push(routePath);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
for (const routePath of staticPaths) {
|
|
71
|
+
if (routePath === currentPath) {
|
|
72
|
+
return routePath;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const routePath of dynamicPaths) {
|
|
60
76
|
const routeParts = routePath.split("/").filter(Boolean);
|
|
61
77
|
const pathParts = currentPath.split("/").filter(Boolean);
|
|
62
78
|
if (routeParts.length !== pathParts.length)
|
|
@@ -105,7 +121,7 @@ const RouterProvider = ({ routes }) => {
|
|
|
105
121
|
to = to.startsWith("/") ? to : `/${to}`;
|
|
106
122
|
}
|
|
107
123
|
if (!validateUrl(to)) {
|
|
108
|
-
|
|
124
|
+
RouterErrors.invalidRoute(to, "Invalid URL format");
|
|
109
125
|
return;
|
|
110
126
|
}
|
|
111
127
|
try {
|
|
@@ -118,7 +134,9 @@ const RouterProvider = ({ routes }) => {
|
|
|
118
134
|
setPath(to);
|
|
119
135
|
}
|
|
120
136
|
catch (error) {
|
|
121
|
-
|
|
137
|
+
const navError = createRouterError(RouterErrorCode.NAVIGATION_ABORTED, `Navigation to "${to}" failed: ${error instanceof Error ? error.message : String(error)}`, { to, error });
|
|
138
|
+
console.error(navError.toConsoleMessage());
|
|
139
|
+
throw navError;
|
|
122
140
|
}
|
|
123
141
|
};
|
|
124
142
|
const matchedComponent = getComponent(routes, path);
|
|
@@ -1,22 +1,20 @@
|
|
|
1
|
+
import { RouterErrors } from "../utils/error/errors";
|
|
1
2
|
import { useParams } from "./useParams";
|
|
2
3
|
export const useDynamicComponents = (dynamicComponentsObject, variationParam) => {
|
|
3
4
|
const params = useParams();
|
|
4
5
|
const variation = params[variationParam];
|
|
5
6
|
if (variation == null) {
|
|
6
|
-
|
|
7
|
+
RouterErrors.paramNotDefined(variationParam, Object.keys(params));
|
|
7
8
|
}
|
|
8
9
|
if (typeof variation !== "string") {
|
|
9
|
-
|
|
10
|
+
RouterErrors.paramInvalidType(variationParam, "string", typeof variation);
|
|
10
11
|
}
|
|
11
12
|
if (variation.trim() === "") {
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
if (!variation) {
|
|
15
|
-
throw new Error(`[router-kit] Parameter "${variationParam}" is required but not found in route params`);
|
|
13
|
+
RouterErrors.paramEmptyString(variationParam);
|
|
16
14
|
}
|
|
17
15
|
const component = dynamicComponentsObject[variation];
|
|
18
16
|
if (!component) {
|
|
19
|
-
|
|
17
|
+
RouterErrors.componentNotFound(variation, Object.keys(dynamicComponentsObject));
|
|
20
18
|
}
|
|
21
19
|
return component;
|
|
22
20
|
};
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { RouterContextType } from "../types";
|
|
2
|
+
export declare function useRouter(): RouterContextType;
|
package/dist/hooks/useRouter.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { useContext } from "react";
|
|
2
2
|
import RouterContext from "../context/RouterContext";
|
|
3
|
+
import { RouterErrors } from "../utils/error/errors";
|
|
3
4
|
export function useRouter() {
|
|
4
5
|
const ctx = useContext(RouterContext);
|
|
5
6
|
if (!ctx) {
|
|
6
|
-
|
|
7
|
-
throw new Error("RouterKit: useRouter cannot be used during server side rendering");
|
|
8
|
-
}
|
|
9
|
-
throw new Error("RouterKit: useRouter must be used within RouterProvider");
|
|
7
|
+
RouterErrors.routerNotInitialized();
|
|
10
8
|
}
|
|
11
9
|
return ctx;
|
|
12
10
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,4 +6,5 @@ export { useDynamicComponents } from "./hooks/useDynamicComponents";
|
|
|
6
6
|
export { useLocation } from "./hooks/useLocation";
|
|
7
7
|
export { useParams } from "./hooks/useParams";
|
|
8
8
|
export { useQuery } from "./hooks/useQuery";
|
|
9
|
-
export type { DynamicComponents, GetComponent, Location, NavigateOptions, Route, RouterContextType, RouterError, Routes, } from "./types/index";
|
|
9
|
+
export type { DynamicComponents, GetComponent, Location, NavigateOptions, Route, RouterContextType, RouterError, RouterKitError, Routes, } from "./types/index";
|
|
10
|
+
export { createRouterError, RouterErrorCode, RouterErrors, } from "./utils/error/errors";
|
package/dist/index.js
CHANGED
|
@@ -6,3 +6,4 @@ export { useDynamicComponents } from "./hooks/useDynamicComponents";
|
|
|
6
6
|
export { useLocation } from "./hooks/useLocation";
|
|
7
7
|
export { useParams } from "./hooks/useParams";
|
|
8
8
|
export { useQuery } from "./hooks/useQuery";
|
|
9
|
+
export { createRouterError, RouterErrorCode, RouterErrors, } from "./utils/error/errors";
|
package/dist/types/index.d.ts
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error codes for router-kit
|
|
3
|
+
*/
|
|
4
|
+
export declare enum RouterErrorCode {
|
|
5
|
+
ROUTER_NOT_INITIALIZED = "ROUTER_NOT_INITIALIZED",
|
|
6
|
+
PARAM_NOT_DEFINED = "PARAM_NOT_DEFINED",
|
|
7
|
+
PARAM_INVALID_TYPE = "PARAM_INVALID_TYPE",
|
|
8
|
+
PARAM_EMPTY_STRING = "PARAM_EMPTY_STRING",
|
|
9
|
+
COMPONENT_NOT_FOUND = "COMPONENT_NOT_FOUND",
|
|
10
|
+
NAVIGATION_ABORTED = "NAVIGATION_ABORTED",
|
|
11
|
+
INVALID_ROUTE = "INVALID_ROUTE"
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Custom error class for router-kit
|
|
15
|
+
*/
|
|
16
|
+
export declare class RouterKitError extends Error {
|
|
17
|
+
readonly code: RouterErrorCode;
|
|
18
|
+
readonly context?: Record<string, any>;
|
|
19
|
+
constructor(code: RouterErrorCode, message: string, context?: Record<string, any>);
|
|
20
|
+
/**
|
|
21
|
+
* Returns a formatted error message for console output
|
|
22
|
+
*/
|
|
23
|
+
toConsoleMessage(): string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates a standardized RouterKitError
|
|
27
|
+
*/
|
|
28
|
+
export declare function createRouterError(code: RouterErrorCode, message: string, context?: Record<string, any>): RouterKitError;
|
|
29
|
+
/**
|
|
30
|
+
* Throws a RouterKitError with optional console styling
|
|
31
|
+
*/
|
|
32
|
+
export declare function throwRouterError(code: RouterErrorCode, message: string, context?: Record<string, any>): never;
|
|
33
|
+
/**
|
|
34
|
+
* Pre-configured error creators for common scenarios
|
|
35
|
+
*/
|
|
36
|
+
export declare const RouterErrors: {
|
|
37
|
+
routerNotInitialized: (additionalInfo?: string) => never;
|
|
38
|
+
paramNotDefined: (paramName: string, availableParams?: string[]) => never;
|
|
39
|
+
paramInvalidType: (paramName: string, expectedType: string, receivedType: string) => never;
|
|
40
|
+
paramEmptyString: (paramName: string) => never;
|
|
41
|
+
componentNotFound: (variation: string, availableVariations: string[]) => never;
|
|
42
|
+
navigationAborted: (reason: string) => never;
|
|
43
|
+
invalidRoute: (path: string, reason?: string) => never;
|
|
44
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error codes for router-kit
|
|
3
|
+
*/
|
|
4
|
+
export var RouterErrorCode;
|
|
5
|
+
(function (RouterErrorCode) {
|
|
6
|
+
// Router context errors
|
|
7
|
+
RouterErrorCode["ROUTER_NOT_INITIALIZED"] = "ROUTER_NOT_INITIALIZED";
|
|
8
|
+
// Dynamic components errors
|
|
9
|
+
RouterErrorCode["PARAM_NOT_DEFINED"] = "PARAM_NOT_DEFINED";
|
|
10
|
+
RouterErrorCode["PARAM_INVALID_TYPE"] = "PARAM_INVALID_TYPE";
|
|
11
|
+
RouterErrorCode["PARAM_EMPTY_STRING"] = "PARAM_EMPTY_STRING";
|
|
12
|
+
RouterErrorCode["COMPONENT_NOT_FOUND"] = "COMPONENT_NOT_FOUND";
|
|
13
|
+
// Navigation errors
|
|
14
|
+
RouterErrorCode["NAVIGATION_ABORTED"] = "NAVIGATION_ABORTED";
|
|
15
|
+
RouterErrorCode["INVALID_ROUTE"] = "INVALID_ROUTE";
|
|
16
|
+
})(RouterErrorCode || (RouterErrorCode = {}));
|
|
17
|
+
/**
|
|
18
|
+
* Custom error class for router-kit
|
|
19
|
+
*/
|
|
20
|
+
export class RouterKitError extends Error {
|
|
21
|
+
constructor(code, message, context) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "RouterKitError";
|
|
24
|
+
this.code = code;
|
|
25
|
+
this.context = context;
|
|
26
|
+
// Maintains proper stack trace for where our error was thrown (only available on V8)
|
|
27
|
+
if (Error.captureStackTrace) {
|
|
28
|
+
Error.captureStackTrace(this, RouterKitError);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Returns a formatted error message for console output
|
|
33
|
+
*/
|
|
34
|
+
toConsoleMessage() {
|
|
35
|
+
const contextStr = this.context
|
|
36
|
+
? `\n\nContext: ${JSON.stringify(this.context, null, 2)}`
|
|
37
|
+
: "";
|
|
38
|
+
return `[router-kit] ${this.code}: ${this.message}${contextStr}`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Creates a standardized RouterKitError
|
|
43
|
+
*/
|
|
44
|
+
export function createRouterError(code, message, context) {
|
|
45
|
+
return new RouterKitError(code, message, context);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Throws a RouterKitError with optional console styling
|
|
49
|
+
*/
|
|
50
|
+
export function throwRouterError(code, message, context) {
|
|
51
|
+
const error = createRouterError(code, message, context);
|
|
52
|
+
// Enhanced console error with styling (if available)
|
|
53
|
+
if (typeof window !== "undefined" && window.console && console.error) {
|
|
54
|
+
console.error(`%c[router-kit]%c ${code}`, "color: #fff; background: #d9534f; font-weight: 700; padding: 2px 6px; border-radius: 3px;", "color: #d9534f; font-weight: 600;");
|
|
55
|
+
console.error(`%c${message}`, "color: #d9534f;");
|
|
56
|
+
if (context) {
|
|
57
|
+
console.error("Context:", context);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
console.error(error.toConsoleMessage());
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Pre-configured error creators for common scenarios
|
|
67
|
+
*/
|
|
68
|
+
export const RouterErrors = {
|
|
69
|
+
routerNotInitialized: (additionalInfo) => throwRouterError(RouterErrorCode.ROUTER_NOT_INITIALIZED, `Router context is not initialized. ${additionalInfo ||
|
|
70
|
+
"Common hooks and components must be used within the RouterProvider returned by createRouter(). Wrap your app with the RouterProvider."}`),
|
|
71
|
+
paramNotDefined: (paramName, availableParams) => throwRouterError(RouterErrorCode.PARAM_NOT_DEFINED, `Parameter "${paramName}" is not defined in route params`, availableParams ? { paramName, availableParams } : { paramName }),
|
|
72
|
+
paramInvalidType: (paramName, expectedType, receivedType) => throwRouterError(RouterErrorCode.PARAM_INVALID_TYPE, `Parameter "${paramName}" must be a ${expectedType}, got ${receivedType}`, { paramName, expectedType, receivedType }),
|
|
73
|
+
paramEmptyString: (paramName) => throwRouterError(RouterErrorCode.PARAM_EMPTY_STRING, `Parameter "${paramName}" cannot be an empty string`, { paramName }),
|
|
74
|
+
componentNotFound: (variation, availableVariations) => throwRouterError(RouterErrorCode.COMPONENT_NOT_FOUND, `Component not found for variation "${variation}". Available variations: ${availableVariations.join(", ")}`, { variation, availableVariations }),
|
|
75
|
+
navigationAborted: (reason) => throwRouterError(RouterErrorCode.NAVIGATION_ABORTED, `Navigation aborted: ${reason}`),
|
|
76
|
+
invalidRoute: (path, reason) => throwRouterError(RouterErrorCode.INVALID_ROUTE, `Invalid route "${path}"${reason ? `: ${reason}` : ""}`, { path }),
|
|
77
|
+
};
|
package/package.json
CHANGED