UNPKG

universal-router

Version:

Isomorphic router for JavaScript web applications

95 lines 3.55 kB
/** * Universal Router (https://www.kriasoft.com/universal-router/) * * Copyright (c) 2015-present Kriasoft. * * This source code is licensed under the MIT license found in the * LICENSE.txt file in the root directory of this source tree. */ import { parse, compile, stringify, TokenData } from './path-to-regexp.js'; function cacheRoutes(routesByName, route, routes, name, sep) { if (route.name && name && routesByName.has(name)) { throw new Error(`Route "${name}" already exists`); } if (route.name && name) { routesByName.set(name, route); } if (routes) { for (let i = 0; i < routes.length; i++) { const childRoute = routes[i]; const childName = childRoute.name; childRoute.parent = route; cacheRoutes(routesByName, childRoute, childRoute.children, name && sep ? (childName ? name + sep + childName : name) : childName, sep); } } } /** * Create a function to generate urls by route names. */ function generateUrls(router, options) { if (!router) { throw new ReferenceError('Router is not defined'); } const routesByName = new Map(); const regexpByRoute = new Map(); const opts = { encode: encodeURIComponent, ...options }; return (routeName, params) => { let route = routesByName.get(routeName); if (!route) { routesByName.clear(); regexpByRoute.clear(); cacheRoutes(routesByName, router.root, router.root.children, router.root.name, opts.uniqueRouteNameSep); route = routesByName.get(routeName); if (!route) { throw new Error(`Route "${routeName}" not found`); } } let regexp = regexpByRoute.get(route); if (!regexp) { let fullPath = ''; let rt = route; while (rt) { const path = Array.isArray(rt.path) ? rt.path[0] : rt.path; if (path) { fullPath = (path instanceof TokenData ? stringify(path) : path) + fullPath; } rt = rt.parent; } const tokens = parse(fullPath, opts); const toPath = compile(fullPath, opts); const keys = Object.create(null); for (let i = 0; i < tokens.tokens.length; i++) { const token = tokens.tokens[i]; if (token && token.type !== 'text') { if (token.type === 'group') { keys[String(i)] = true; } else { keys[token.name] = true; } } } regexp = { toPath, keys }; regexpByRoute.set(route, regexp); } let url = router.baseUrl + regexp.toPath(params) || '/'; if (opts.stringifyQueryParams && params) { const queryParams = {}; const keys = Object.keys(params); for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (key && !regexp.keys[key] && params[key] != null) { queryParams[key] = params[key]; } } const query = opts.stringifyQueryParams(queryParams); if (query) { url += query.charAt(0) === '?' ? query : `?${query}`; } } return url; }; } export default generateUrls; //# sourceMappingURL=generate-urls.js.map