UNPKG

6.68 kBJavaScriptView Raw
1/*! Universal Router | MIT License | https://www.kriasoft.com/universal-router/ */
2
3import pathToRegexp from 'path-to-regexp';
4
5/**
6 * Universal Router (https://www.kriasoft.com/universal-router/)
7 *
8 * Copyright © 2015-present Kriasoft, LLC. All rights reserved.
9 *
10 * This source code is licensed under the Apache 2.0 license found in the
11 * LICENSE.txt file in the root directory of this source tree.
12 */
13
14var cache = new Map();
15
16function decodeParam(val) {
17 try {
18 return decodeURIComponent(val);
19 } catch (err) {
20 return val;
21 }
22}
23
24function matchPath(routePath, urlPath, end, parentParams) {
25 var key = routePath + '|' + end;
26 var regexp = cache.get(key);
27
28 if (!regexp) {
29 var keys = [];
30 regexp = { pattern: pathToRegexp(routePath, keys, { end: end }), keys: keys };
31 cache.set(key, regexp);
32 }
33
34 var m = regexp.pattern.exec(urlPath);
35 if (!m) {
36 return null;
37 }
38
39 var path = m[0];
40 var params = Object.create(null);
41
42 if (parentParams) {
43 Object.assign(params, parentParams);
44 }
45
46 for (var i = 1; i < m.length; i += 1) {
47 params[regexp.keys[i - 1].name] = m[i] && decodeParam(m[i]);
48 }
49
50 return { path: path === '' ? '/' : path, keys: regexp.keys.slice(), params: params };
51}
52
53/**
54 * Universal Router (https://www.kriasoft.com/universal-router/)
55 *
56 * Copyright © 2015-present Kriasoft, LLC. All rights reserved.
57 *
58 * This source code is licensed under the Apache 2.0 license found in the
59 * LICENSE.txt file in the root directory of this source tree.
60 */
61
62function matchRoute(route, baseUrl, path, parentParams) {
63 var match = void 0;
64 var childMatches = void 0;
65 var childIndex = 0;
66
67 return {
68 next: function next() {
69 if (!match) {
70 match = matchPath(route.path, path, !route.children, parentParams);
71
72 if (match) {
73 return {
74 done: false,
75 value: {
76 route: route,
77 baseUrl: baseUrl,
78 path: match.path,
79 keys: match.keys,
80 params: match.params
81 }
82 };
83 }
84 }
85
86 if (match && route.children) {
87 while (childIndex < route.children.length) {
88 if (!childMatches) {
89 var newPath = path.substr(match.path.length);
90 var childRoute = route.children[childIndex];
91 childRoute.parent = route;
92
93 childMatches = matchRoute(childRoute, baseUrl + (match.path === '/' ? '' : match.path), newPath.charAt(0) === '/' ? newPath : '/' + newPath, match.params);
94 }
95
96 var childMatch = childMatches.next();
97 if (!childMatch.done) {
98 return {
99 done: false,
100 value: childMatch.value
101 };
102 }
103
104 childMatches = null;
105 childIndex += 1;
106 }
107 }
108
109 return { done: true };
110 }
111 };
112}
113
114/**
115 * Universal Router (https://www.kriasoft.com/universal-router/)
116 *
117 * Copyright © 2015-present Kriasoft, LLC. All rights reserved.
118 *
119 * This source code is licensed under the Apache 2.0 license found in the
120 * LICENSE.txt file in the root directory of this source tree.
121 */
122
123function resolveRoute(context, params) {
124 if (typeof context.route.action === 'function') {
125 return context.route.action(context, params);
126 }
127
128 return null;
129}
130
131var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
132
133function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
134
135/**
136 * Universal Router (https://www.kriasoft.com/universal-router/)
137 *
138 * Copyright © 2015-present Kriasoft, LLC. All rights reserved.
139 *
140 * This source code is licensed under the Apache 2.0 license found in the
141 * LICENSE.txt file in the root directory of this source tree.
142 */
143
144function isChildRoute(parentRoute, childRoute) {
145 var route = childRoute;
146 while (route) {
147 route = route.parent;
148 if (route === parentRoute) {
149 return true;
150 }
151 }
152 return false;
153}
154
155var Router = function () {
156 function Router(routes) {
157 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
158
159 _classCallCheck(this, Router);
160
161 if (Object(routes) !== routes) {
162 throw new TypeError('Invalid routes');
163 }
164
165 this.baseUrl = options.baseUrl || '';
166 this.resolveRoute = options.resolveRoute || resolveRoute;
167 this.context = Object.assign({ router: this }, options.context);
168 this.root = Array.isArray(routes) ? { path: '/', children: routes, parent: null } : routes;
169 this.root.parent = null;
170 }
171
172 _createClass(Router, [{
173 key: 'resolve',
174 value: function resolve(pathOrContext) {
175 var context = Object.assign({}, this.context, typeof pathOrContext === 'string' ? { path: pathOrContext } : pathOrContext);
176 var match = matchRoute(this.root, this.baseUrl, context.path.substr(this.baseUrl.length));
177 var resolve = this.resolveRoute;
178 var matches = null;
179 var nextMatches = null;
180
181 function next(resume) {
182 var parent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : matches.value.route;
183
184 matches = nextMatches || match.next();
185 nextMatches = null;
186
187 if (!resume) {
188 if (matches.done || !isChildRoute(parent, matches.value.route)) {
189 nextMatches = matches;
190 return Promise.resolve(null);
191 }
192 }
193
194 if (matches.done) {
195 return Promise.reject(Object.assign(new Error('Page not found'), { context: context, status: 404, statusCode: 404 }));
196 }
197
198 return Promise.resolve(resolve(Object.assign({}, context, matches.value), matches.value.params)).then(function (result) {
199 if (result !== null && result !== undefined) {
200 return result;
201 }
202
203 return next(resume, parent);
204 });
205 }
206
207 context.url = context.path;
208 context.next = next;
209
210 return next(true, this.root);
211 }
212 }]);
213
214 return Router;
215}();
216
217Router.pathToRegexp = pathToRegexp;
218Router.matchPath = matchPath;
219Router.matchRoute = matchRoute;
220Router.resolveRoute = resolveRoute;
221
222export default Router;
223//# sourceMappingURL=browser.mjs.map