@rxdi/router 0.7.219 → 0.7.221
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/README.md +101 -0
- package/dist/decorators.d.ts +1 -2
- package/dist/decorators.js +1 -1
- package/dist/helpers.d.ts +1 -1
- package/dist/helpers.js +11 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/injection.tokens.d.ts +23 -16
- package/dist/injection.tokens.js +3 -1
- package/dist/lib/constants.d.ts +3 -0
- package/dist/lib/constants.js +6 -0
- package/dist/lib/index.d.ts +4 -0
- package/dist/{slot → lib}/index.js +6 -4
- package/dist/lib/path-to-regexp.d.ts +6 -0
- package/dist/lib/path-to-regexp.js +228 -0
- package/dist/lib/resolver.d.ts +70 -0
- package/dist/lib/resolver.js +426 -0
- package/dist/{vaadin/vaadin-router.d.ts → lib/router.d.ts} +98 -201
- package/dist/lib/router.js +833 -0
- package/dist/lib/triggers.d.ts +6 -0
- package/dist/lib/triggers.js +98 -0
- package/dist/lib/types.d.ts +134 -0
- package/dist/lib/types.js +6 -0
- package/dist/lib/utils.d.ts +20 -0
- package/dist/lib/utils.js +155 -0
- package/dist/not-found.component.js +3 -3
- package/dist/outlet.d.ts +7 -62
- package/dist/outlet.js +15 -84
- package/dist/router.component.d.ts +3 -3
- package/dist/router.component.js +4 -4
- package/package.json +3 -3
- package/dist/slot/index.d.ts +0 -8
- package/dist/slot/slot.d.ts +0 -11
- package/dist/slot/slot.js +0 -44
- package/dist/vaadin/vaadin-router.js +0 -2065
- package/slot/index.d.ts +0 -8
- package/slot/index.js +0 -8
- package/slot/slot.d.ts +0 -11
- package/slot/slot.js +0 -45
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Resolver = void 0;
|
|
4
|
+
exports.generateUrls = generateUrls;
|
|
5
|
+
const path_to_regexp_1 = require("./path-to-regexp");
|
|
6
|
+
const types_1 = require("./types");
|
|
7
|
+
const utils_1 = require("./utils");
|
|
8
|
+
const { hasOwnProperty } = Object.prototype;
|
|
9
|
+
const cache = new Map();
|
|
10
|
+
cache.set('|false', {
|
|
11
|
+
keys: [],
|
|
12
|
+
pattern: /(?:)/,
|
|
13
|
+
});
|
|
14
|
+
function decodeParam(val) {
|
|
15
|
+
try {
|
|
16
|
+
return decodeURIComponent(val);
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
return val;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function matchPath(routepath, path, exact, parentKeys, parentParams) {
|
|
23
|
+
exact = !!exact;
|
|
24
|
+
const cacheKey = `${routepath}|${exact}`;
|
|
25
|
+
let regexp = cache.get(cacheKey);
|
|
26
|
+
if (!regexp) {
|
|
27
|
+
const keys = [];
|
|
28
|
+
regexp = {
|
|
29
|
+
keys,
|
|
30
|
+
pattern: (0, path_to_regexp_1.pathToRegexp)(routepath, keys, {
|
|
31
|
+
end: exact,
|
|
32
|
+
strict: routepath === '',
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
cache.set(cacheKey, regexp);
|
|
36
|
+
}
|
|
37
|
+
const m = regexp.pattern.exec(path);
|
|
38
|
+
if (!m) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const params = Object.assign({}, parentParams);
|
|
42
|
+
for (let i = 1; i < m.length; i++) {
|
|
43
|
+
const key = regexp.keys[i - 1];
|
|
44
|
+
const prop = key.name;
|
|
45
|
+
const value = m[i];
|
|
46
|
+
if (value !== undefined || !hasOwnProperty.call(params, prop)) {
|
|
47
|
+
if (key.repeat) {
|
|
48
|
+
params[prop] = value ? value.split(key.delimiter).map(decodeParam) : [];
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
params[prop] = value ? decodeParam(value) : value;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
path: m[0],
|
|
57
|
+
keys: (parentKeys || []).concat(regexp.keys),
|
|
58
|
+
params,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function matchRoute(route, pathname, ignoreLeadingSlash, parentKeys, parentParams) {
|
|
62
|
+
let match;
|
|
63
|
+
let childMatches;
|
|
64
|
+
let childIndex = 0;
|
|
65
|
+
let routepath = route.path || '';
|
|
66
|
+
let isAbsolute = false;
|
|
67
|
+
if (Array.isArray(routepath)) {
|
|
68
|
+
routepath = routepath.map((path) => {
|
|
69
|
+
if (path.charAt(0) === '/') {
|
|
70
|
+
isAbsolute = true;
|
|
71
|
+
return ignoreLeadingSlash ? path.substr(1) : path;
|
|
72
|
+
}
|
|
73
|
+
return path;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else if (routepath.charAt(0) === '/') {
|
|
77
|
+
isAbsolute = true;
|
|
78
|
+
if (ignoreLeadingSlash) {
|
|
79
|
+
routepath = routepath.substr(1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (isAbsolute) {
|
|
83
|
+
ignoreLeadingSlash = true;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
next(routeToSkip) {
|
|
87
|
+
if (route === routeToSkip) {
|
|
88
|
+
return { done: true, value: undefined };
|
|
89
|
+
}
|
|
90
|
+
const children = (route.__children = route.__children || route.children);
|
|
91
|
+
if (!match) {
|
|
92
|
+
match = matchPath(routepath, pathname, !children, parentKeys, parentParams);
|
|
93
|
+
if (match) {
|
|
94
|
+
return {
|
|
95
|
+
done: false,
|
|
96
|
+
value: {
|
|
97
|
+
route,
|
|
98
|
+
keys: match.keys,
|
|
99
|
+
params: match.params,
|
|
100
|
+
path: match.path,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (match && children) {
|
|
106
|
+
while (childIndex < children.length) {
|
|
107
|
+
if (!childMatches) {
|
|
108
|
+
const childRoute = children[childIndex];
|
|
109
|
+
childRoute.parent = route;
|
|
110
|
+
let matchedLength = match.path.length;
|
|
111
|
+
if (matchedLength > 0 && pathname.charAt(matchedLength) === '/') {
|
|
112
|
+
matchedLength += 1;
|
|
113
|
+
}
|
|
114
|
+
childMatches = matchRoute(childRoute, pathname.substr(matchedLength), ignoreLeadingSlash, match.keys, match.params);
|
|
115
|
+
}
|
|
116
|
+
const childMatch = childMatches.next(routeToSkip);
|
|
117
|
+
if (!childMatch.done) {
|
|
118
|
+
return {
|
|
119
|
+
done: false,
|
|
120
|
+
value: childMatch.value,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
childMatches = null;
|
|
124
|
+
childIndex++;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return { done: true, value: undefined };
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function resolveRoute(context) {
|
|
132
|
+
if ((0, utils_1.isFunction)(context.route.action)) {
|
|
133
|
+
return context.route.action(context);
|
|
134
|
+
}
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
function isChildRoute(parentRoute, childRoute) {
|
|
138
|
+
let route = childRoute;
|
|
139
|
+
while (route) {
|
|
140
|
+
route = route.parent;
|
|
141
|
+
if (route === parentRoute) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
function generateErrorMessage(currentContext) {
|
|
148
|
+
let errorMessage = `Path '${currentContext.pathname}' is not properly resolved due to an error.`;
|
|
149
|
+
const routePath = (currentContext.route || {}).path;
|
|
150
|
+
if (routePath) {
|
|
151
|
+
errorMessage += ` Resolution had failed on route: '${routePath}'`;
|
|
152
|
+
}
|
|
153
|
+
return errorMessage;
|
|
154
|
+
}
|
|
155
|
+
function updateChainForRoute(context, match) {
|
|
156
|
+
const { route, path } = match;
|
|
157
|
+
if (route && !route.__synthetic) {
|
|
158
|
+
const item = { path, route };
|
|
159
|
+
if (!context.chain) {
|
|
160
|
+
context.chain = [];
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
if (route.parent) {
|
|
164
|
+
let i = context.chain.length;
|
|
165
|
+
while (i-- && context.chain[i].route && context.chain[i].route !== route.parent) {
|
|
166
|
+
context.chain.pop();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
context.chain.push(item);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Universal Router (https://www.kriasoft.com/universal-router/)
|
|
175
|
+
*
|
|
176
|
+
* Copyright (c) 2015-present Kriasoft.
|
|
177
|
+
*
|
|
178
|
+
* This source code is licensed under the MIT license found in the
|
|
179
|
+
* LICENSE.txt file in the root directory of this source tree.
|
|
180
|
+
*/
|
|
181
|
+
class Resolver {
|
|
182
|
+
constructor(routes, options = {}) {
|
|
183
|
+
if (Object(routes) !== routes) {
|
|
184
|
+
throw new TypeError('Invalid routes');
|
|
185
|
+
}
|
|
186
|
+
this.baseUrl = options.baseUrl || '';
|
|
187
|
+
this.errorHandler = options.errorHandler;
|
|
188
|
+
this.resolveRoute = options.resolveRoute || resolveRoute;
|
|
189
|
+
this.context = Object.assign({ resolver: this }, options.context);
|
|
190
|
+
this.root = Array.isArray(routes) ? { path: '', __children: routes, parent: null, __synthetic: true } : routes;
|
|
191
|
+
this.root.parent = null;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Returns the current list of routes (as a shallow copy). Adding / removing
|
|
195
|
+
* routes to / from the returned array does not affect the routing config,
|
|
196
|
+
* but modifying the route objects does.
|
|
197
|
+
*
|
|
198
|
+
* @return
|
|
199
|
+
*/
|
|
200
|
+
getRoutes() {
|
|
201
|
+
const children = this.root.__children;
|
|
202
|
+
return Array.isArray(children) ? [...children] : [];
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Sets the routing config (replacing the existing one).
|
|
206
|
+
*
|
|
207
|
+
* @param routes a single route or an array of those
|
|
208
|
+
* (the array is shallow copied)
|
|
209
|
+
*/
|
|
210
|
+
setRoutes(routes) {
|
|
211
|
+
(0, utils_1.ensureRoutes)(routes);
|
|
212
|
+
const newRoutes = [...(0, utils_1.toArray)(routes)];
|
|
213
|
+
this.root.__children = newRoutes;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Appends one or several routes to the routing config and returns the
|
|
217
|
+
* effective routing config after the operation.
|
|
218
|
+
*
|
|
219
|
+
* @param routes a single route or an array of those
|
|
220
|
+
* (the array is shallow copied)
|
|
221
|
+
* @return
|
|
222
|
+
* @protected
|
|
223
|
+
*/
|
|
224
|
+
addRoutes(routes) {
|
|
225
|
+
(0, utils_1.ensureRoutes)(routes);
|
|
226
|
+
if (!this.root.__children || !Array.isArray(this.root.__children)) {
|
|
227
|
+
this.root.__children = [];
|
|
228
|
+
}
|
|
229
|
+
this.root.__children.push(...(0, utils_1.toArray)(routes));
|
|
230
|
+
return this.getRoutes();
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Removes all existing routes from the routing config.
|
|
234
|
+
*/
|
|
235
|
+
removeRoutes() {
|
|
236
|
+
this.setRoutes([]);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Asynchronously resolves the given pathname, i.e. finds all routes matching
|
|
240
|
+
* the pathname and tries resolving them one after another in the order they
|
|
241
|
+
* are listed in the routes config until the first non-null result.
|
|
242
|
+
*
|
|
243
|
+
* Returns a promise that is fulfilled with the return value of an object that consists of the first
|
|
244
|
+
* route handler result that returns something other than `null` or `undefined` and context used to get this result.
|
|
245
|
+
*
|
|
246
|
+
* If no route handlers return a non-null result, or if no route matches the
|
|
247
|
+
* given pathname the returned promise is rejected with a 'page not found'
|
|
248
|
+
* `Error`.
|
|
249
|
+
*
|
|
250
|
+
* @param pathnameOrContext the pathname to
|
|
251
|
+
* resolve or a context object with a `pathname` property and other
|
|
252
|
+
* properties to pass to the route resolver functions.
|
|
253
|
+
* @return
|
|
254
|
+
*/
|
|
255
|
+
resolve(pathnameOrContext) {
|
|
256
|
+
const context = Object.assign({}, this.context, (0, utils_1.isString)(pathnameOrContext) ? { pathname: pathnameOrContext } : pathnameOrContext);
|
|
257
|
+
const match = matchRoute(this.root, this.__normalizePathname(context.pathname), !!this.baseUrl);
|
|
258
|
+
const resolve = this.resolveRoute;
|
|
259
|
+
let matches = null;
|
|
260
|
+
let nextMatches = null;
|
|
261
|
+
let currentContext = context;
|
|
262
|
+
function next(resume, parent = matches.value.route, prevResult) {
|
|
263
|
+
const routeToSkip = prevResult === null && matches.value.route;
|
|
264
|
+
matches = nextMatches || match.next(routeToSkip);
|
|
265
|
+
nextMatches = null;
|
|
266
|
+
if (!resume) {
|
|
267
|
+
if (matches.done || !isChildRoute(parent, matches.value.route)) {
|
|
268
|
+
nextMatches = matches;
|
|
269
|
+
return Promise.resolve(types_1.notFoundResult);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (matches.done) {
|
|
273
|
+
return Promise.reject((0, utils_1.getNotFoundError)(context));
|
|
274
|
+
}
|
|
275
|
+
currentContext = Object.assign(currentContext ? { chain: currentContext.chain ? currentContext.chain.slice(0) : [] } : {}, context, matches.value);
|
|
276
|
+
updateChainForRoute(currentContext, matches.value);
|
|
277
|
+
return Promise.resolve(resolve(currentContext)).then((resolution) => {
|
|
278
|
+
if (resolution !== null && resolution !== undefined && resolution !== types_1.notFoundResult) {
|
|
279
|
+
currentContext.result = resolution.redirect
|
|
280
|
+
? resolution
|
|
281
|
+
: resolution.tagName
|
|
282
|
+
? resolution
|
|
283
|
+
: resolution;
|
|
284
|
+
return currentContext;
|
|
285
|
+
}
|
|
286
|
+
return next(resume, parent, resolution);
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
context.next = next;
|
|
290
|
+
return Promise.resolve()
|
|
291
|
+
.then(() => next(true, this.root))
|
|
292
|
+
.then((result) => {
|
|
293
|
+
if (result === types_1.notFoundResult) {
|
|
294
|
+
throw (0, utils_1.getNotFoundError)(context);
|
|
295
|
+
}
|
|
296
|
+
return result;
|
|
297
|
+
})
|
|
298
|
+
.catch((error) => {
|
|
299
|
+
const errorMessage = generateErrorMessage(currentContext);
|
|
300
|
+
if (!error) {
|
|
301
|
+
error = new Error(errorMessage);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
console.warn(errorMessage);
|
|
305
|
+
}
|
|
306
|
+
error.context = error.context || currentContext;
|
|
307
|
+
if (!(error instanceof DOMException)) {
|
|
308
|
+
error.code = error.code || 500;
|
|
309
|
+
}
|
|
310
|
+
if (this.errorHandler) {
|
|
311
|
+
currentContext.result = this.errorHandler(error);
|
|
312
|
+
return currentContext;
|
|
313
|
+
}
|
|
314
|
+
throw error;
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
static __createUrl(url, base) {
|
|
318
|
+
return new URL(url, base);
|
|
319
|
+
}
|
|
320
|
+
__getEffectiveBaseUrl() {
|
|
321
|
+
return this.baseUrl
|
|
322
|
+
? this.constructor
|
|
323
|
+
.__createUrl(this.baseUrl, document.baseURI || document.URL)
|
|
324
|
+
.href.replace(/[^\/]*$/, '')
|
|
325
|
+
: '';
|
|
326
|
+
}
|
|
327
|
+
__normalizePathname(pathname) {
|
|
328
|
+
if (!this.baseUrl) {
|
|
329
|
+
return pathname;
|
|
330
|
+
}
|
|
331
|
+
const base = this.__getEffectiveBaseUrl();
|
|
332
|
+
const normalizedUrl = this.constructor.__createUrl(pathname, base).href;
|
|
333
|
+
if (normalizedUrl.slice(0, base.length) === base) {
|
|
334
|
+
return normalizedUrl.slice(base.length);
|
|
335
|
+
}
|
|
336
|
+
return undefined;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
exports.Resolver = Resolver;
|
|
340
|
+
const cache$1 = new Map();
|
|
341
|
+
function cacheRoutes(routesByName, route, routes) {
|
|
342
|
+
const name = route.name || route.component;
|
|
343
|
+
if (name) {
|
|
344
|
+
if (routesByName.has(name)) {
|
|
345
|
+
routesByName.get(name).push(route);
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
routesByName.set(name, [route]);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (Array.isArray(routes)) {
|
|
352
|
+
for (let i = 0; i < routes.length; i++) {
|
|
353
|
+
const childRoute = routes[i];
|
|
354
|
+
childRoute.parent = route;
|
|
355
|
+
cacheRoutes(routesByName, childRoute, childRoute.__children || childRoute.children);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
function getRouteByName(routesByName, routeName) {
|
|
360
|
+
const routes = routesByName.get(routeName);
|
|
361
|
+
if (routes && routes.length > 1) {
|
|
362
|
+
throw new Error(`Duplicate route with name "${routeName}".` + ` Try seting unique 'name' route properties.`);
|
|
363
|
+
}
|
|
364
|
+
return routes && routes[0];
|
|
365
|
+
}
|
|
366
|
+
function getRoutePath(route) {
|
|
367
|
+
let path = route.path;
|
|
368
|
+
path = Array.isArray(path) ? path[0] : path;
|
|
369
|
+
return path !== undefined ? path : '';
|
|
370
|
+
}
|
|
371
|
+
function generateUrls(router, options = {}) {
|
|
372
|
+
if (!(router instanceof Resolver)) {
|
|
373
|
+
throw new TypeError('An instance of Resolver is expected');
|
|
374
|
+
}
|
|
375
|
+
const routesByName = new Map();
|
|
376
|
+
return (routeName, params) => {
|
|
377
|
+
let route = getRouteByName(routesByName, routeName);
|
|
378
|
+
if (!route) {
|
|
379
|
+
routesByName.clear();
|
|
380
|
+
cacheRoutes(routesByName, router.root, router.root.__children);
|
|
381
|
+
route = getRouteByName(routesByName, routeName);
|
|
382
|
+
if (!route) {
|
|
383
|
+
throw new Error(`Route "${routeName}" not found`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
let regexp = cache$1.get(route.fullPath);
|
|
387
|
+
if (!regexp) {
|
|
388
|
+
let fullPath = getRoutePath(route);
|
|
389
|
+
let rt = route.parent;
|
|
390
|
+
while (rt) {
|
|
391
|
+
const path = getRoutePath(rt);
|
|
392
|
+
if (path) {
|
|
393
|
+
fullPath = path.replace(/\/$/, '') + '/' + fullPath.replace(/^\//, '');
|
|
394
|
+
}
|
|
395
|
+
rt = rt.parent;
|
|
396
|
+
}
|
|
397
|
+
const tokens = (0, path_to_regexp_1.parse)(fullPath);
|
|
398
|
+
const toPath = (0, path_to_regexp_1.tokensToFunction)(tokens);
|
|
399
|
+
const keys = Object.create(null);
|
|
400
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
401
|
+
if (!(0, utils_1.isString)(tokens[i])) {
|
|
402
|
+
keys[tokens[i].name] = true;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
regexp = { toPath, keys };
|
|
406
|
+
cache$1.set(fullPath, regexp);
|
|
407
|
+
route.fullPath = fullPath;
|
|
408
|
+
}
|
|
409
|
+
let url = regexp.toPath(params, options) || '/';
|
|
410
|
+
if (options.stringifyQueryParams && params) {
|
|
411
|
+
const queryParams = {};
|
|
412
|
+
const keys = Object.keys(params);
|
|
413
|
+
for (let i = 0; i < keys.length; i++) {
|
|
414
|
+
const key = keys[i];
|
|
415
|
+
if (!regexp.keys[key]) {
|
|
416
|
+
queryParams[key] = params[key];
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
const query = options.stringifyQueryParams(queryParams);
|
|
420
|
+
if (query) {
|
|
421
|
+
url += query.charAt(0) === '?' ? query : `?${query}`;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return url;
|
|
425
|
+
};
|
|
426
|
+
}
|