UNPKG

14.8 kBSource Map (JSON)View Raw
1{"version":3,"file":"UniversalRouter.js","sourceRoot":"","sources":["UniversalRouter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Universal Router (https://www.kriasoft.com/universal-router/)\n *\n * Copyright (c) 2015-present Kriasoft.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE.txt file in the root directory of this source tree.\n */\n\nimport {\n match,\n Path,\n Match,\n MatchFunction,\n ParseOptions,\n TokensToRegexpOptions,\n RegexpToFunctionOptions,\n} from 'path-to-regexp'\n\n/**\n * Params is a key/value object that represents extracted URL parameters.\n */\nexport interface RouteParams {\n [paramName: string]: string | string[]\n}\n\n/**\n * In addition to a URL path string, any arbitrary data can be passed to\n * the `router.resolve()` method, that becomes available inside action functions.\n */\nexport interface RouterContext {\n [propName: string]: any\n}\n\nexport interface ResolveContext extends RouterContext {\n /**\n * URL which was transmitted to `router.resolve()`.\n */\n pathname: string\n}\n\nexport interface RouteContext<R = any, C extends RouterContext = RouterContext>\n extends ResolveContext {\n /**\n * Current router instance.\n */\n router: UniversalRouter<R, C>\n /**\n * Matched route object.\n */\n route: Route<R, C>\n /**\n * Base URL path relative to the path of the current route.\n */\n baseUrl: string\n /**\n * Matched path.\n */\n path: string\n /**\n * Matched path params.\n */\n params: RouteParams\n /**\n * Middleware style function which can continue resolving.\n */\n next: (resume?: boolean) => Promise<R>\n}\n\nexport type RouteResult<T> = T | Promise<T | null | undefined> | null | undefined\n\n/**\n * A Route is a singular route in your application. It contains a path, an\n * action function, and optional children which are an array of Route.\n * @template C User context that is made union with RouterContext.\n * @template R Result that every action function resolves to.\n * If the action returns a Promise, R can be the type the Promise resolves to.\n */\nexport interface Route<R = any, C extends RouterContext = RouterContext> {\n /**\n * A string, array of strings, or a regular expression. Defaults to an empty string.\n */\n path?: Path\n /**\n * A unique string that can be used to generate the route URL.\n */\n name?: string\n /**\n * The link to the parent route is automatically populated by the router. Useful for breadcrumbs.\n */\n parent?: Route<R, C> | null\n /**\n * An array of Route objects. Nested routes are perfect to be used in middleware routes.\n */\n children?: Routes<R, C> | null\n /**\n * Action method should return anything except `null` or `undefined` to be resolved by router\n * otherwise router will throw `Page not found` error if all matched routes returned nothing.\n */\n action?: (context: RouteContext<R, C>, params: RouteParams) => RouteResult<R>\n /**\n * The route path match function. Used for internal caching.\n */\n match?: MatchFunction<RouteParams>\n}\n\n/**\n * Routes is an array of type Route.\n * @template C User context that is made union with RouterContext.\n * @template R Result that every action function resolves to.\n * If the action returns a Promise, R can be the type the Promise resolves to.\n */\nexport type Routes<R = any, C extends RouterContext = RouterContext> = Array<Route<R, C>>\n\nexport type ResolveRoute<R = any, C extends RouterContext = RouterContext> = (\n context: RouteContext<R, C>,\n params: RouteParams,\n) => RouteResult<R>\n\nexport type RouteError = Error & { status?: number }\n\nexport type ErrorHandler<R = any> = (error: RouteError, context: ResolveContext) => RouteResult<R>\n\nexport interface RouterOptions<R = any, C extends RouterContext = RouterContext>\n extends ParseOptions,\n TokensToRegexpOptions,\n RegexpToFunctionOptions {\n context?: C\n baseUrl?: string\n resolveRoute?: ResolveRoute<R, C>\n errorHandler?: ErrorHandler<R>\n}\n\nexport interface RouteMatch<R = any, C extends RouterContext = RouterContext> {\n route: Route<R, C>\n baseUrl: string\n path: string\n params: RouteParams\n}\n\nfunction decode(val: string): string {\n try {\n return decodeURIComponent(val)\n } catch (err) {\n return val\n }\n}\n\nfunction matchRoute<R, C>(\n route: Route<R, C>,\n baseUrl: string,\n options: RouterOptions<R, C>,\n pathname: string,\n parentParams?: RouteParams,\n): Iterator<RouteMatch<R, C>, false, Route<R, C> | false> {\n let matchResult: Match<RouteParams>\n let childMatches: Iterator<RouteMatch<R, C>, false, Route<R, C> | false> | null\n let childIndex = 0\n\n return {\n next(routeToSkip: Route<R, C> | false): IteratorResult<RouteMatch<R, C>, false> {\n if (route === routeToSkip) {\n return { done: true, value: false }\n }\n\n if (!matchResult) {\n const rt = route\n const end = !rt.children\n if (!rt.match) {\n rt.match = match<RouteParams>(rt.path || '', { end, ...options })\n }\n matchResult = rt.match(pathname)\n\n if (matchResult) {\n const { path } = matchResult\n matchResult.path = !end && path.charAt(path.length - 1) === '/' ? path.substr(1) : path\n matchResult.params = { ...parentParams, ...matchResult.params }\n return {\n done: false,\n value: {\n route,\n baseUrl,\n path: matchResult.path,\n params: matchResult.params,\n },\n }\n }\n }\n\n if (matchResult && route.children) {\n while (childIndex < route.children.length) {\n if (!childMatches) {\n const childRoute = route.children[childIndex]\n childRoute.parent = route\n\n childMatches = matchRoute<R, C>(\n childRoute,\n baseUrl + matchResult.path,\n options,\n pathname.substr(matchResult.path.length),\n matchResult.params,\n )\n }\n\n const childMatch = childMatches.next(routeToSkip)\n if (!childMatch.done) {\n return {\n done: false,\n value: childMatch.value,\n }\n }\n\n childMatches = null\n childIndex++\n }\n }\n\n return { done: true, value: false }\n },\n }\n}\n\nfunction resolveRoute<R = any, C extends RouterContext = object>(\n context: RouteContext<R, C>,\n params: RouteParams,\n): RouteResult<R> {\n if (typeof context.route.action === 'function') {\n return context.route.action(context, params)\n }\n return undefined\n}\n\nfunction isChildRoute<R = any, C extends RouterContext = object>(\n parentRoute: Route<R, C> | false,\n childRoute: Route<R, C>,\n): boolean {\n let route: Route<R, C> | null | undefined = childRoute\n while (route) {\n route = route.parent\n if (route === parentRoute) {\n return true\n }\n }\n return false\n}\n\nclass UniversalRouter<R = any, C extends RouterContext = RouterContext> {\n root: Route<R, C>\n\n baseUrl: string\n\n options: RouterOptions<R, C>\n\n constructor(routes: Routes<R, C> | Route<R, C>, options?: RouterOptions<R, C>) {\n if (!routes || typeof routes !== 'object') {\n throw new TypeError('Invalid routes')\n }\n\n this.options = { decode, ...options }\n this.baseUrl = this.options.baseUrl || ''\n this.root = Array.isArray(routes) ? { path: '', children: routes, parent: null } : routes\n this.root.parent = null\n }\n\n /**\n * Traverses the list of routes in the order they are defined until it finds\n * the first route that matches provided URL path string and whose action function\n * returns anything other than `null` or `undefined`.\n */\n resolve(pathnameOrContext: string | ResolveContext): RouteResult<R> {\n const context: ResolveContext = {\n router: this,\n ...this.options.context,\n ...(typeof pathnameOrContext === 'string'\n ? { pathname: pathnameOrContext }\n : pathnameOrContext),\n }\n const matchResult = matchRoute(\n this.root,\n this.baseUrl,\n this.options,\n context.pathname.substr(this.baseUrl.length),\n )\n const resolve = this.options.resolveRoute || resolveRoute\n let matches: IteratorResult<RouteMatch<R, C>, false>\n let nextMatches: IteratorResult<RouteMatch<R, C>, false> | null\n let currentContext = context\n\n function next(\n resume: boolean,\n parent: Route<R, C> | false = !matches.done && matches.value.route,\n prevResult?: RouteResult<R>,\n ): RouteResult<R> {\n const routeToSkip = prevResult === null && !matches.done && matches.value.route\n matches = nextMatches || matchResult.next(routeToSkip)\n nextMatches = null\n\n if (!resume) {\n if (matches.done || !isChildRoute(parent, matches.value.route)) {\n nextMatches = matches\n return Promise.resolve(null)\n }\n }\n\n if (matches.done) {\n const error: RouteError = new Error('Route not found')\n error.status = 404\n return Promise.reject(error)\n }\n\n currentContext = { ...context, ...matches.value }\n\n return Promise.resolve(\n resolve(currentContext as RouteContext<R, C>, matches.value.params),\n ).then((result) => {\n if (result !== null && result !== undefined) {\n return result\n }\n return next(resume, parent, result)\n })\n }\n\n context.next = next\n\n return Promise.resolve()\n .then(() => next(true, this.root))\n .catch((error) => {\n if (this.options.errorHandler) {\n return this.options.errorHandler(error, currentContext)\n }\n throw error\n })\n }\n}\n\nexport default UniversalRouter\n"]}
\No newline at end of file