@jay-js/system
Version:
A powerful and flexible TypeScript library for UI, state management, lazy loading, routing and managing draggable elements in modern web applications.
81 lines • 3.76 kB
JavaScript
import { routerOptions } from "./configuration";
/**
* Processes and registers route definitions for the router
*
* This function transforms the user-provided route definitions into internal route instances
* that the router can work with. It handles nested routes, layouts, and target resolution.
*
* @param {Array<TRoute>} inputRoutes - Array of route configurations to register
* @param {HTMLElement|string} [target] - Default rendering target for routes that don't specify their own
* @param {string} [prefix=''] - Path prefix to prepend to all routes in this set
* @returns {Array<TRouteInstance>} Array of processed route instances
*/
export function Routes(inputRoutes, target, prefix = "") {
const outputRoutes = [];
const prefixOptions = routerOptions.prefix || "";
function buildRoutes(routes, prefix, parentLayoutId) {
if (prefixOptions && prefix.includes(prefixOptions)) {
prefix = prefix.replace(prefixOptions, "");
}
for (const route of routes) {
// Special handling for index routes under a layout
// If the child route path is "/" and we're in a nested route context,
// use the parent's path directly instead of concatenating
const childIsIndexRoute = route.path === "/" && prefix !== "";
const newPath = childIsIndexRoute
? [prefixOptions, prefix]
.join("/")
.replace(/\/+$/, "")
.replace(/\/{2,}/g, "/")
: [prefixOptions, prefix, route.path]
.join("/")
.replace(/\/+$/, "")
.replace(/\/{2,}/g, "/");
const routeId = crypto.randomUUID();
if (route.element || route.import) {
let routeTarget = route.target || target || document.body;
if (typeof routeTarget === "string") {
const targetElement = document.querySelector(routeTarget);
if (!targetElement && routerOptions.onError) {
routerOptions.onError(new Error(`Target element not found: ${routeTarget}`, { cause: "invalid-target" }));
routeTarget = document.body;
}
else if (targetElement) {
routeTarget = targetElement;
}
}
const routeBuild = {
id: routeId,
path: newPath,
target: routeTarget,
};
// Copy properties from the route
if (route.element)
routeBuild.element = route.element;
if (route.import)
routeBuild.import = route.import;
if (route.module)
routeBuild.module = route.module;
if (route.params)
routeBuild.params = route.params;
if (route.layout)
routeBuild.layout = route.layout;
if (route.loader)
routeBuild.loader = route.loader;
if (route.guard)
routeBuild.guard = route.guard;
if (route.metadata)
routeBuild.metadata = route.metadata;
if (parentLayoutId)
routeBuild.parentLayoutId = parentLayoutId;
outputRoutes.push(routeBuild);
}
if (route.children) {
buildRoutes(route.children, newPath, route.layout ? routeId : parentLayoutId);
}
}
}
buildRoutes(inputRoutes, prefix);
return outputRoutes;
}
//# sourceMappingURL=route-registry.js.map