UNPKG

3.07 kBJavaScriptView Raw
1/**
2 * Universal Router (https://www.kriasoft.com/universal-router/)
3 *
4 * Copyright (c) 2015-present Kriasoft.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE.txt file in the root directory of this source tree.
8 */
9import { parse, tokensToFunction, } from 'path-to-regexp';
10function cacheRoutes(routesByName, route, routes) {
11 if (route.name && routesByName.has(route.name)) {
12 throw new Error(`Route "${route.name}" already exists`);
13 }
14 if (route.name) {
15 routesByName.set(route.name, route);
16 }
17 if (routes) {
18 for (let i = 0; i < routes.length; i++) {
19 const childRoute = routes[i];
20 childRoute.parent = route;
21 cacheRoutes(routesByName, childRoute, childRoute.children);
22 }
23 }
24}
25/**
26 * Create a function to generate urls by route names.
27 */
28function generateUrls(router, options) {
29 if (!router) {
30 throw new ReferenceError('Router is not defined');
31 }
32 const routesByName = new Map();
33 const regexpByRoute = new Map();
34 const opts = { encode: encodeURIComponent, ...options };
35 return (routeName, params) => {
36 let route = routesByName.get(routeName);
37 if (!route) {
38 routesByName.clear();
39 regexpByRoute.clear();
40 cacheRoutes(routesByName, router.root, router.root.children);
41 route = routesByName.get(routeName);
42 if (!route) {
43 throw new Error(`Route "${routeName}" not found`);
44 }
45 }
46 let regexp = regexpByRoute.get(route);
47 if (!regexp) {
48 let fullPath = '';
49 let rt = route;
50 while (rt) {
51 const path = Array.isArray(rt.path) ? rt.path[0] : rt.path;
52 if (path) {
53 fullPath = path + fullPath;
54 }
55 rt = rt.parent;
56 }
57 const tokens = parse(fullPath, opts);
58 const toPath = tokensToFunction(tokens, opts);
59 const keys = Object.create(null);
60 for (let i = 0; i < tokens.length; i++) {
61 const token = tokens[i];
62 if (typeof token !== 'string') {
63 keys[token.name] = true;
64 }
65 }
66 regexp = { toPath, keys };
67 regexpByRoute.set(route, regexp);
68 }
69 let url = router.baseUrl + regexp.toPath(params) || '/';
70 if (opts.stringifyQueryParams && params) {
71 const queryParams = {};
72 const keys = Object.keys(params);
73 for (let i = 0; i < keys.length; i++) {
74 const key = keys[i];
75 if (!regexp.keys[key]) {
76 queryParams[key] = params[key];
77 }
78 }
79 const query = opts.stringifyQueryParams(queryParams);
80 if (query) {
81 url += query.charAt(0) === '?' ? query : `?${query}`;
82 }
83 }
84 return url;
85 };
86}
87export default generateUrls;
88//# sourceMappingURL=generateUrls.js.map
\No newline at end of file