UNPKG

25.6 kBSource Map (JSON)View Raw
1{"version":3,"file":"universal-router.min.js","sources":["../node_modules/path-to-regexp/index.js","../src/matchPath.js","../src/matchRoute.js","../src/resolveRoute.js","../src/Router.js","../node_modules/path-to-regexp/node_modules/isarray/index.js"],"sourcesContent":["var isarray = require('isarray')\n\n/**\n * Expose `pathToRegexp`.\n */\nmodule.exports = pathToRegexp\nmodule.exports.parse = parse\nmodule.exports.compile = compile\nmodule.exports.tokensToFunction = tokensToFunction\nmodule.exports.tokensToRegExp = tokensToRegExp\n\n/**\n * The main path matching regexp utility.\n *\n * @type {RegExp}\n */\nvar PATH_REGEXP = new RegExp([\n // Match escaped characters that would otherwise appear in future matches.\n // This allows the user to escape special characters that won't transform.\n '(\\\\\\\\.)',\n // Match Express-style parameters and un-named parameters with a prefix\n // and optional suffixes. Matches appear as:\n //\n // \"/:test(\\\\d+)?\" => [\"/\", \"test\", \"\\d+\", undefined, \"?\", undefined]\n // \"/route(\\\\d+)\" => [undefined, undefined, undefined, \"\\d+\", undefined, undefined]\n // \"/*\" => [\"/\", undefined, undefined, undefined, undefined, \"*\"]\n '([\\\\/.])?(?:(?:\\\\:(\\\\w+)(?:\\\\(((?:\\\\\\\\.|[^\\\\\\\\()])+)\\\\))?|\\\\(((?:\\\\\\\\.|[^\\\\\\\\()])+)\\\\))([+*?])?|(\\\\*))'\n].join('|'), 'g')\n\n/**\n * Parse a string for the raw tokens.\n *\n * @param {string} str\n * @param {Object=} options\n * @return {!Array}\n */\nfunction parse (str, options) {\n var tokens = []\n var key = 0\n var index = 0\n var path = ''\n var defaultDelimiter = options && options.delimiter || '/'\n var res\n\n while ((res = PATH_REGEXP.exec(str)) != null) {\n var m = res[0]\n var escaped = res[1]\n var offset = res.index\n path += str.slice(index, offset)\n index = offset + m.length\n\n // Ignore already escaped sequences.\n if (escaped) {\n path += escaped[1]\n continue\n }\n\n var next = str[index]\n var prefix = res[2]\n var name = res[3]\n var capture = res[4]\n var group = res[5]\n var modifier = res[6]\n var asterisk = res[7]\n\n // Push the current path onto the tokens.\n if (path) {\n tokens.push(path)\n path = ''\n }\n\n var partial = prefix != null && next != null && next !== prefix\n var repeat = modifier === '+' || modifier === '*'\n var optional = modifier === '?' || modifier === '*'\n var delimiter = res[2] || defaultDelimiter\n var pattern = capture || group\n\n tokens.push({\n name: name || key++,\n prefix: prefix || '',\n delimiter: delimiter,\n optional: optional,\n repeat: repeat,\n partial: partial,\n asterisk: !!asterisk,\n pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')\n })\n }\n\n // Match any characters still remaining.\n if (index < str.length) {\n path += str.substr(index)\n }\n\n // If the path exists, push it onto the end.\n if (path) {\n tokens.push(path)\n }\n\n return tokens\n}\n\n/**\n * Compile a string to a template function for the path.\n *\n * @param {string} str\n * @param {Object=} options\n * @return {!function(Object=, Object=)}\n */\nfunction compile (str, options) {\n return tokensToFunction(parse(str, options))\n}\n\n/**\n * Prettier encoding of URI path segments.\n *\n * @param {string}\n * @return {string}\n */\nfunction encodeURIComponentPretty (str) {\n return encodeURI(str).replace(/[\\/?#]/g, function (c) {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase()\n })\n}\n\n/**\n * Encode the asterisk parameter. Similar to `pretty`, but allows slashes.\n *\n * @param {string}\n * @return {string}\n */\nfunction encodeAsterisk (str) {\n return encodeURI(str).replace(/[?#]/g, function (c) {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase()\n })\n}\n\n/**\n * Expose a method for transforming tokens into the path function.\n */\nfunction tokensToFunction (tokens) {\n // Compile all the tokens into regexps.\n var matches = new Array(tokens.length)\n\n // Compile all the patterns before compilation.\n for (var i = 0; i < tokens.length; i++) {\n if (typeof tokens[i] === 'object') {\n matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$')\n }\n }\n\n return function (obj, opts) {\n var path = ''\n var data = obj || {}\n var options = opts || {}\n var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent\n\n for (var i = 0; i < tokens.length; i++) {\n var token = tokens[i]\n\n if (typeof token === 'string') {\n path += token\n\n continue\n }\n\n var value = data[token.name]\n var segment\n\n if (value == null) {\n if (token.optional) {\n // Prepend partial segment prefixes.\n if (token.partial) {\n path += token.prefix\n }\n\n continue\n } else {\n throw new TypeError('Expected \"' + token.name + '\" to be defined')\n }\n }\n\n if (isarray(value)) {\n if (!token.repeat) {\n throw new TypeError('Expected \"' + token.name + '\" to not repeat, but received `' + JSON.stringify(value) + '`')\n }\n\n if (value.length === 0) {\n if (token.optional) {\n continue\n } else {\n throw new TypeError('Expected \"' + token.name + '\" to not be empty')\n }\n }\n\n for (var j = 0; j < value.length; j++) {\n segment = encode(value[j])\n\n if (!matches[i].test(segment)) {\n throw new TypeError('Expected all \"' + token.name + '\" to match \"' + token.pattern + '\", but received `' + JSON.stringify(segment) + '`')\n }\n\n path += (j === 0 ? token.prefix : token.delimiter) + segment\n }\n\n continue\n }\n\n segment = token.asterisk ? encodeAsterisk(value) : encode(value)\n\n if (!matches[i].test(segment)) {\n throw new TypeError('Expected \"' + token.name + '\" to match \"' + token.pattern + '\", but received \"' + segment + '\"')\n }\n\n path += token.prefix + segment\n }\n\n return path\n }\n}\n\n/**\n * Escape a regular expression string.\n *\n * @param {string} str\n * @return {string}\n */\nfunction escapeString (str) {\n return str.replace(/([.+*?=^!:${}()[\\]|\\/\\\\])/g, '\\\\$1')\n}\n\n/**\n * Escape the capturing group by escaping special characters and meaning.\n *\n * @param {string} group\n * @return {string}\n */\nfunction escapeGroup (group) {\n return group.replace(/([=!:$\\/()])/g, '\\\\$1')\n}\n\n/**\n * Attach the keys as a property of the regexp.\n *\n * @param {!RegExp} re\n * @param {Array} keys\n * @return {!RegExp}\n */\nfunction attachKeys (re, keys) {\n re.keys = keys\n return re\n}\n\n/**\n * Get the flags for a regexp from the options.\n *\n * @param {Object} options\n * @return {string}\n */\nfunction flags (options) {\n return options.sensitive ? '' : 'i'\n}\n\n/**\n * Pull out keys from a regexp.\n *\n * @param {!RegExp} path\n * @param {!Array} keys\n * @return {!RegExp}\n */\nfunction regexpToRegexp (path, keys) {\n // Use a negative lookahead to match only capturing groups.\n var groups = path.source.match(/\\((?!\\?)/g)\n\n if (groups) {\n for (var i = 0; i < groups.length; i++) {\n keys.push({\n name: i,\n prefix: null,\n delimiter: null,\n optional: false,\n repeat: false,\n partial: false,\n asterisk: false,\n pattern: null\n })\n }\n }\n\n return attachKeys(path, keys)\n}\n\n/**\n * Transform an array into a regexp.\n *\n * @param {!Array} path\n * @param {Array} keys\n * @param {!Object} options\n * @return {!RegExp}\n */\nfunction arrayToRegexp (path, keys, options) {\n var parts = []\n\n for (var i = 0; i < path.length; i++) {\n parts.push(pathToRegexp(path[i], keys, options).source)\n }\n\n var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))\n\n return attachKeys(regexp, keys)\n}\n\n/**\n * Create a path regexp from string input.\n *\n * @param {string} path\n * @param {!Array} keys\n * @param {!Object} options\n * @return {!RegExp}\n */\nfunction stringToRegexp (path, keys, options) {\n return tokensToRegExp(parse(path, options), keys, options)\n}\n\n/**\n * Expose a function for taking tokens and returning a RegExp.\n *\n * @param {!Array} tokens\n * @param {(Array|Object)=} keys\n * @param {Object=} options\n * @return {!RegExp}\n */\nfunction tokensToRegExp (tokens, keys, options) {\n if (!isarray(keys)) {\n options = /** @type {!Object} */ (keys || options)\n keys = []\n }\n\n options = options || {}\n\n var strict = options.strict\n var end = options.end !== false\n var route = ''\n\n // Iterate over the tokens and create our regexp string.\n for (var i = 0; i < tokens.length; i++) {\n var token = tokens[i]\n\n if (typeof token === 'string') {\n route += escapeString(token)\n } else {\n var prefix = escapeString(token.prefix)\n var capture = '(?:' + token.pattern + ')'\n\n keys.push(token)\n\n if (token.repeat) {\n capture += '(?:' + prefix + capture + ')*'\n }\n\n if (token.optional) {\n if (!token.partial) {\n capture = '(?:' + prefix + '(' + capture + '))?'\n } else {\n capture = prefix + '(' + capture + ')?'\n }\n } else {\n capture = prefix + '(' + capture + ')'\n }\n\n route += capture\n }\n }\n\n var delimiter = escapeString(options.delimiter || '/')\n var endsWithDelimiter = route.slice(-delimiter.length) === delimiter\n\n // In non-strict mode we allow a slash at the end of match. If the path to\n // match already ends with a slash, we remove it for consistency. The slash\n // is valid at the end of a path match, not in the middle. This is important\n // in non-ending mode, where \"/test/\" shouldn't match \"/test//route\".\n if (!strict) {\n route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?'\n }\n\n if (end) {\n route += '$'\n } else {\n // In non-ending mode, we need the capturing groups to match as much as\n // possible by using a positive lookahead to the end or next path segment.\n route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)'\n }\n\n return attachKeys(new RegExp('^' + route, flags(options)), keys)\n}\n\n/**\n * Normalize the given path string, returning a regular expression.\n *\n * An empty array can be passed in for the keys, which will hold the\n * placeholder key descriptions. For example, using `/user/:id`, `keys` will\n * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.\n *\n * @param {(string|RegExp|Array)} path\n * @param {(Array|Object)=} keys\n * @param {Object=} options\n * @return {!RegExp}\n */\nfunction pathToRegexp (path, keys, options) {\n if (!isarray(keys)) {\n options = /** @type {!Object} */ (keys || options)\n keys = []\n }\n\n options = options || {}\n\n if (path instanceof RegExp) {\n return regexpToRegexp(path, /** @type {!Array} */ (keys))\n }\n\n if (isarray(path)) {\n return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)\n }\n\n return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)\n}\n","/**\n * Universal Router (https://www.kriasoft.com/universal-router/)\n *\n * Copyright © 2015-present Kriasoft, LLC. All rights reserved.\n *\n * This source code is licensed under the Apache 2.0 license found in the\n * LICENSE.txt file in the root directory of this source tree.\n */\n\nimport pathToRegexp from 'path-to-regexp';\n\nconst cache = new Map();\n\nfunction decodeParam(val) {\n try {\n return decodeURIComponent(val);\n } catch (err) {\n return val;\n }\n}\n\nfunction matchPath(routePath, urlPath, end, parentParams) {\n const key = `${routePath}|${end}`;\n let regexp = cache.get(key);\n\n if (!regexp) {\n const keys = [];\n regexp = { pattern: pathToRegexp(routePath, keys, { end }), keys };\n cache.set(key, regexp);\n }\n\n const m = regexp.pattern.exec(urlPath);\n if (!m) {\n return null;\n }\n\n const path = m[0];\n const params = Object.create(null);\n\n if (parentParams) {\n Object.assign(params, parentParams);\n }\n\n for (let i = 1; i < m.length; i += 1) {\n params[regexp.keys[i - 1].name] = m[i] && decodeParam(m[i]);\n }\n\n return { path: path === '' ? '/' : path, keys: regexp.keys.slice(), params };\n}\n\nexport default matchPath;\n","/**\n * Universal Router (https://www.kriasoft.com/universal-router/)\n *\n * Copyright © 2015-present Kriasoft, LLC. All rights reserved.\n *\n * This source code is licensed under the Apache 2.0 license found in the\n * LICENSE.txt file in the root directory of this source tree.\n */\n\nimport matchPath from './matchPath';\n\nfunction matchRoute(route, baseUrl, path, parentParams) {\n let match;\n let childMatches;\n let childIndex = 0;\n\n return {\n next() {\n if (!match) {\n match = matchPath(route.path, path, !route.children, parentParams);\n\n if (match) {\n return {\n done: false,\n value: {\n route,\n baseUrl,\n path: match.path,\n keys: match.keys,\n params: match.params,\n },\n };\n }\n }\n\n if (match && route.children) {\n while (childIndex < route.children.length) {\n if (!childMatches) {\n const newPath = path.substr(match.path.length);\n const childRoute = route.children[childIndex];\n childRoute.parent = route;\n\n childMatches = matchRoute(\n childRoute,\n baseUrl + (match.path === '/' ? '' : match.path),\n newPath.charAt(0) === '/' ? newPath : `/${newPath}`,\n match.params,\n );\n }\n\n const childMatch = childMatches.next();\n if (!childMatch.done) {\n return {\n done: false,\n value: childMatch.value,\n };\n }\n\n childMatches = null;\n childIndex += 1;\n }\n }\n\n return { done: true };\n },\n };\n}\n\nexport default matchRoute;\n","/**\n * Universal Router (https://www.kriasoft.com/universal-router/)\n *\n * Copyright © 2015-present Kriasoft, LLC. All rights reserved.\n *\n * This source code is licensed under the Apache 2.0 license found in the\n * LICENSE.txt file in the root directory of this source tree.\n */\n\nfunction resolveRoute(context, params) {\n if (typeof context.route.action === 'function') {\n return context.route.action(context, params);\n }\n\n return null;\n}\n\nexport default resolveRoute;\n","/**\n * Universal Router (https://www.kriasoft.com/universal-router/)\n *\n * Copyright © 2015-present Kriasoft, LLC. All rights reserved.\n *\n * This source code is licensed under the Apache 2.0 license found in the\n * LICENSE.txt file in the root directory of this source tree.\n */\n\nimport pathToRegexp from 'path-to-regexp';\nimport matchPath from './matchPath';\nimport matchRoute from './matchRoute';\nimport resolveRoute from './resolveRoute';\n\nfunction isChildRoute(parentRoute, childRoute) {\n let route = childRoute;\n while (route) {\n route = route.parent;\n if (route === parentRoute) {\n return true;\n }\n }\n return false;\n}\n\nclass Router {\n constructor(routes, options = {}) {\n if (Object(routes) !== routes) {\n throw new TypeError('Invalid routes');\n }\n\n this.baseUrl = options.baseUrl || '';\n this.resolveRoute = options.resolveRoute || resolveRoute;\n this.context = Object.assign({ router: this }, options.context);\n this.root = Array.isArray(routes) ? { path: '/', children: routes, parent: null } : routes;\n this.root.parent = null;\n }\n\n resolve(pathOrContext) {\n const context = Object.assign({}, this.context,\n typeof pathOrContext === 'string' ? { path: pathOrContext } : pathOrContext);\n const match = matchRoute(this.root, this.baseUrl, context.path.substr(this.baseUrl.length));\n const resolve = this.resolveRoute;\n let matches = null;\n let nextMatches = null;\n\n function next(resume, parent = matches.value.route) {\n matches = nextMatches || match.next();\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 return Promise.reject(Object.assign(\n new Error('Page not found'),\n { context, status: 404, statusCode: 404 },\n ));\n }\n\n return Promise.resolve(resolve(\n Object.assign({}, context, matches.value),\n matches.value.params,\n )).then((result) => {\n if (result !== null && result !== undefined) {\n return result;\n }\n\n return next(resume, parent);\n });\n }\n\n context.url = context.path;\n context.next = next;\n\n return next(true, this.root);\n }\n}\n\nRouter.pathToRegexp = pathToRegexp;\nRouter.matchPath = matchPath;\nRouter.matchRoute = matchRoute;\nRouter.resolveRoute = resolveRoute;\n\nexport default Router;\n","module.exports = Array.isArray || function (arr) {\n return Object.prototype.toString.call(arr) == '[object Array]';\n};\n"],"names":["parse","str","options","res","tokens","key","index","path","defaultDelimiter","delimiter","PATH_REGEXP","exec","m","escaped","offset","slice","length","next","prefix","name","capture","group","modifier","asterisk","push","partial","repeat","optional","pattern","escapeGroup","escapeString","substr","compile","tokensToFunction","encodeURIComponentPretty","encodeURI","replace","c","charCodeAt","toString","toUpperCase","encodeAsterisk","matches","Array","i","RegExp","obj","opts","data","encode","pretty","encodeURIComponent","token","segment","value","TypeError","isarray","JSON","stringify","j","test","attachKeys","re","keys","flags","sensitive","regexpToRegexp","groups","source","match","arrayToRegexp","parts","pathToRegexp","join","stringToRegexp","tokensToRegExp","strict","end","route","endsWithDelimiter","decodeParam","val","decodeURIComponent","err","matchPath","routePath","urlPath","parentParams","regexp","cache","get","set","params","Object","create","assign","matchRoute","baseUrl","childMatches","childIndex","children","newPath","childRoute","parent","charAt","childMatch","done","resolveRoute","context","action","isChildRoute","parentRoute","isArray","arr","prototype","call","Map","Router","routes","router","this","root","pathOrContext","resume","nextMatches","Promise","reject","Error","status","statusCode","resolve","then","result","undefined","url"],"mappings":"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"}
\No newline at end of file