Spaces:
Paused
Paused
| ; | |
| Object.defineProperty(exports, "__esModule", { value: true }); | |
| exports.pathToRegexp = exports.tokensToRegexp = exports.regexpToFunction = exports.match = exports.tokensToFunction = exports.compile = exports.parse = void 0; | |
| /** | |
| * Tokenize input string. | |
| */ | |
| function lexer(str) { | |
| var tokens = []; | |
| var i = 0; | |
| while (i < str.length) { | |
| var char = str[i]; | |
| if (char === "*" || char === "+" || char === "?") { | |
| tokens.push({ type: "MODIFIER", index: i, value: str[i++] }); | |
| continue; | |
| } | |
| if (char === "\\") { | |
| tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] }); | |
| continue; | |
| } | |
| if (char === "{") { | |
| tokens.push({ type: "OPEN", index: i, value: str[i++] }); | |
| continue; | |
| } | |
| if (char === "}") { | |
| tokens.push({ type: "CLOSE", index: i, value: str[i++] }); | |
| continue; | |
| } | |
| if (char === ":") { | |
| var name = ""; | |
| var j = i + 1; | |
| while (j < str.length) { | |
| var code = str.charCodeAt(j); | |
| if ( | |
| // `0-9` | |
| (code >= 48 && code <= 57) || | |
| // `A-Z` | |
| (code >= 65 && code <= 90) || | |
| // `a-z` | |
| (code >= 97 && code <= 122) || | |
| // `_` | |
| code === 95) { | |
| name += str[j++]; | |
| continue; | |
| } | |
| break; | |
| } | |
| if (!name) | |
| throw new TypeError("Missing parameter name at ".concat(i)); | |
| tokens.push({ type: "NAME", index: i, value: name }); | |
| i = j; | |
| continue; | |
| } | |
| if (char === "(") { | |
| var count = 1; | |
| var pattern = ""; | |
| var j = i + 1; | |
| if (str[j] === "?") { | |
| throw new TypeError("Pattern cannot start with \"?\" at ".concat(j)); | |
| } | |
| while (j < str.length) { | |
| if (str[j] === "\\") { | |
| pattern += str[j++] + str[j++]; | |
| continue; | |
| } | |
| if (str[j] === ")") { | |
| count--; | |
| if (count === 0) { | |
| j++; | |
| break; | |
| } | |
| } | |
| else if (str[j] === "(") { | |
| count++; | |
| if (str[j + 1] !== "?") { | |
| throw new TypeError("Capturing groups are not allowed at ".concat(j)); | |
| } | |
| } | |
| pattern += str[j++]; | |
| } | |
| if (count) | |
| throw new TypeError("Unbalanced pattern at ".concat(i)); | |
| if (!pattern) | |
| throw new TypeError("Missing pattern at ".concat(i)); | |
| tokens.push({ type: "PATTERN", index: i, value: pattern }); | |
| i = j; | |
| continue; | |
| } | |
| tokens.push({ type: "CHAR", index: i, value: str[i++] }); | |
| } | |
| tokens.push({ type: "END", index: i, value: "" }); | |
| return tokens; | |
| } | |
| /** | |
| * Parse a string for the raw tokens. | |
| */ | |
| function parse(str, options) { | |
| if (options === void 0) { options = {}; } | |
| var tokens = lexer(str); | |
| var _a = options.prefixes, prefixes = _a === void 0 ? "./" : _a, _b = options.delimiter, delimiter = _b === void 0 ? "/#?" : _b; | |
| var result = []; | |
| var key = 0; | |
| var i = 0; | |
| var path = ""; | |
| var tryConsume = function (type) { | |
| if (i < tokens.length && tokens[i].type === type) | |
| return tokens[i++].value; | |
| }; | |
| var mustConsume = function (type) { | |
| var value = tryConsume(type); | |
| if (value !== undefined) | |
| return value; | |
| var _a = tokens[i], nextType = _a.type, index = _a.index; | |
| throw new TypeError("Unexpected ".concat(nextType, " at ").concat(index, ", expected ").concat(type)); | |
| }; | |
| var consumeText = function () { | |
| var result = ""; | |
| var value; | |
| while ((value = tryConsume("CHAR") || tryConsume("ESCAPED_CHAR"))) { | |
| result += value; | |
| } | |
| return result; | |
| }; | |
| var isSafe = function (value) { | |
| for (var _i = 0, delimiter_1 = delimiter; _i < delimiter_1.length; _i++) { | |
| var char = delimiter_1[_i]; | |
| if (value.indexOf(char) > -1) | |
| return true; | |
| } | |
| return false; | |
| }; | |
| var safePattern = function (prefix) { | |
| var prev = result[result.length - 1]; | |
| var prevText = prefix || (prev && typeof prev === "string" ? prev : ""); | |
| if (prev && !prevText) { | |
| throw new TypeError("Must have text between two parameters, missing text after \"".concat(prev.name, "\"")); | |
| } | |
| if (!prevText || isSafe(prevText)) | |
| return "[^".concat(escapeString(delimiter), "]+?"); | |
| return "(?:(?!".concat(escapeString(prevText), ")[^").concat(escapeString(delimiter), "])+?"); | |
| }; | |
| while (i < tokens.length) { | |
| var char = tryConsume("CHAR"); | |
| var name = tryConsume("NAME"); | |
| var pattern = tryConsume("PATTERN"); | |
| if (name || pattern) { | |
| var prefix = char || ""; | |
| if (prefixes.indexOf(prefix) === -1) { | |
| path += prefix; | |
| prefix = ""; | |
| } | |
| if (path) { | |
| result.push(path); | |
| path = ""; | |
| } | |
| result.push({ | |
| name: name || key++, | |
| prefix: prefix, | |
| suffix: "", | |
| pattern: pattern || safePattern(prefix), | |
| modifier: tryConsume("MODIFIER") || "", | |
| }); | |
| continue; | |
| } | |
| var value = char || tryConsume("ESCAPED_CHAR"); | |
| if (value) { | |
| path += value; | |
| continue; | |
| } | |
| if (path) { | |
| result.push(path); | |
| path = ""; | |
| } | |
| var open = tryConsume("OPEN"); | |
| if (open) { | |
| var prefix = consumeText(); | |
| var name_1 = tryConsume("NAME") || ""; | |
| var pattern_1 = tryConsume("PATTERN") || ""; | |
| var suffix = consumeText(); | |
| mustConsume("CLOSE"); | |
| result.push({ | |
| name: name_1 || (pattern_1 ? key++ : ""), | |
| pattern: name_1 && !pattern_1 ? safePattern(prefix) : pattern_1, | |
| prefix: prefix, | |
| suffix: suffix, | |
| modifier: tryConsume("MODIFIER") || "", | |
| }); | |
| continue; | |
| } | |
| mustConsume("END"); | |
| } | |
| return result; | |
| } | |
| exports.parse = parse; | |
| /** | |
| * Compile a string to a template function for the path. | |
| */ | |
| function compile(str, options) { | |
| return tokensToFunction(parse(str, options), options); | |
| } | |
| exports.compile = compile; | |
| /** | |
| * Expose a method for transforming tokens into the path function. | |
| */ | |
| function tokensToFunction(tokens, options) { | |
| if (options === void 0) { options = {}; } | |
| var reFlags = flags(options); | |
| var _a = options.encode, encode = _a === void 0 ? function (x) { return x; } : _a, _b = options.validate, validate = _b === void 0 ? true : _b; | |
| // Compile all the tokens into regexps. | |
| var matches = tokens.map(function (token) { | |
| if (typeof token === "object") { | |
| return new RegExp("^(?:".concat(token.pattern, ")$"), reFlags); | |
| } | |
| }); | |
| return function (data) { | |
| var path = ""; | |
| for (var i = 0; i < tokens.length; i++) { | |
| var token = tokens[i]; | |
| if (typeof token === "string") { | |
| path += token; | |
| continue; | |
| } | |
| var value = data ? data[token.name] : undefined; | |
| var optional = token.modifier === "?" || token.modifier === "*"; | |
| var repeat = token.modifier === "*" || token.modifier === "+"; | |
| if (Array.isArray(value)) { | |
| if (!repeat) { | |
| throw new TypeError("Expected \"".concat(token.name, "\" to not repeat, but got an array")); | |
| } | |
| if (value.length === 0) { | |
| if (optional) | |
| continue; | |
| throw new TypeError("Expected \"".concat(token.name, "\" to not be empty")); | |
| } | |
| for (var j = 0; j < value.length; j++) { | |
| var segment = encode(value[j], token); | |
| if (validate && !matches[i].test(segment)) { | |
| throw new TypeError("Expected all \"".concat(token.name, "\" to match \"").concat(token.pattern, "\", but got \"").concat(segment, "\"")); | |
| } | |
| path += token.prefix + segment + token.suffix; | |
| } | |
| continue; | |
| } | |
| if (typeof value === "string" || typeof value === "number") { | |
| var segment = encode(String(value), token); | |
| if (validate && !matches[i].test(segment)) { | |
| throw new TypeError("Expected \"".concat(token.name, "\" to match \"").concat(token.pattern, "\", but got \"").concat(segment, "\"")); | |
| } | |
| path += token.prefix + segment + token.suffix; | |
| continue; | |
| } | |
| if (optional) | |
| continue; | |
| var typeOfMessage = repeat ? "an array" : "a string"; | |
| throw new TypeError("Expected \"".concat(token.name, "\" to be ").concat(typeOfMessage)); | |
| } | |
| return path; | |
| }; | |
| } | |
| exports.tokensToFunction = tokensToFunction; | |
| /** | |
| * Create path match function from `path-to-regexp` spec. | |
| */ | |
| function match(str, options) { | |
| var keys = []; | |
| var re = pathToRegexp(str, keys, options); | |
| return regexpToFunction(re, keys, options); | |
| } | |
| exports.match = match; | |
| /** | |
| * Create a path match function from `path-to-regexp` output. | |
| */ | |
| function regexpToFunction(re, keys, options) { | |
| if (options === void 0) { options = {}; } | |
| var _a = options.decode, decode = _a === void 0 ? function (x) { return x; } : _a; | |
| return function (pathname) { | |
| var m = re.exec(pathname); | |
| if (!m) | |
| return false; | |
| var path = m[0], index = m.index; | |
| var params = Object.create(null); | |
| var _loop_1 = function (i) { | |
| if (m[i] === undefined) | |
| return "continue"; | |
| var key = keys[i - 1]; | |
| if (key.modifier === "*" || key.modifier === "+") { | |
| params[key.name] = m[i].split(key.prefix + key.suffix).map(function (value) { | |
| return decode(value, key); | |
| }); | |
| } | |
| else { | |
| params[key.name] = decode(m[i], key); | |
| } | |
| }; | |
| for (var i = 1; i < m.length; i++) { | |
| _loop_1(i); | |
| } | |
| return { path: path, index: index, params: params }; | |
| }; | |
| } | |
| exports.regexpToFunction = regexpToFunction; | |
| /** | |
| * Escape a regular expression string. | |
| */ | |
| function escapeString(str) { | |
| return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1"); | |
| } | |
| /** | |
| * Get the flags for a regexp from the options. | |
| */ | |
| function flags(options) { | |
| return options && options.sensitive ? "" : "i"; | |
| } | |
| /** | |
| * Pull out keys from a regexp. | |
| */ | |
| function regexpToRegexp(path, keys) { | |
| if (!keys) | |
| return path; | |
| var groupsRegex = /\((?:\?<(.*?)>)?(?!\?)/g; | |
| var index = 0; | |
| var execResult = groupsRegex.exec(path.source); | |
| while (execResult) { | |
| keys.push({ | |
| // Use parenthesized substring match if available, index otherwise | |
| name: execResult[1] || index++, | |
| prefix: "", | |
| suffix: "", | |
| modifier: "", | |
| pattern: "", | |
| }); | |
| execResult = groupsRegex.exec(path.source); | |
| } | |
| return path; | |
| } | |
| /** | |
| * Transform an array into a regexp. | |
| */ | |
| function arrayToRegexp(paths, keys, options) { | |
| var parts = paths.map(function (path) { return pathToRegexp(path, keys, options).source; }); | |
| return new RegExp("(?:".concat(parts.join("|"), ")"), flags(options)); | |
| } | |
| /** | |
| * Create a path regexp from string input. | |
| */ | |
| function stringToRegexp(path, keys, options) { | |
| return tokensToRegexp(parse(path, options), keys, options); | |
| } | |
| /** | |
| * Expose a function for taking tokens and returning a RegExp. | |
| */ | |
| function tokensToRegexp(tokens, keys, options) { | |
| if (options === void 0) { options = {}; } | |
| var _a = options.strict, strict = _a === void 0 ? false : _a, _b = options.start, start = _b === void 0 ? true : _b, _c = options.end, end = _c === void 0 ? true : _c, _d = options.encode, encode = _d === void 0 ? function (x) { return x; } : _d, _e = options.delimiter, delimiter = _e === void 0 ? "/#?" : _e, _f = options.endsWith, endsWith = _f === void 0 ? "" : _f; | |
| var endsWithRe = "[".concat(escapeString(endsWith), "]|$"); | |
| var delimiterRe = "[".concat(escapeString(delimiter), "]"); | |
| var route = start ? "^" : ""; | |
| // Iterate over the tokens and create our regexp string. | |
| for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) { | |
| var token = tokens_1[_i]; | |
| if (typeof token === "string") { | |
| route += escapeString(encode(token)); | |
| } | |
| else { | |
| var prefix = escapeString(encode(token.prefix)); | |
| var suffix = escapeString(encode(token.suffix)); | |
| if (token.pattern) { | |
| if (keys) | |
| keys.push(token); | |
| if (prefix || suffix) { | |
| if (token.modifier === "+" || token.modifier === "*") { | |
| var mod = token.modifier === "*" ? "?" : ""; | |
| route += "(?:".concat(prefix, "((?:").concat(token.pattern, ")(?:").concat(suffix).concat(prefix, "(?:").concat(token.pattern, "))*)").concat(suffix, ")").concat(mod); | |
| } | |
| else { | |
| route += "(?:".concat(prefix, "(").concat(token.pattern, ")").concat(suffix, ")").concat(token.modifier); | |
| } | |
| } | |
| else { | |
| if (token.modifier === "+" || token.modifier === "*") { | |
| throw new TypeError("Can not repeat \"".concat(token.name, "\" without a prefix and suffix")); | |
| } | |
| route += "(".concat(token.pattern, ")").concat(token.modifier); | |
| } | |
| } | |
| else { | |
| route += "(?:".concat(prefix).concat(suffix, ")").concat(token.modifier); | |
| } | |
| } | |
| } | |
| if (end) { | |
| if (!strict) | |
| route += "".concat(delimiterRe, "?"); | |
| route += !options.endsWith ? "$" : "(?=".concat(endsWithRe, ")"); | |
| } | |
| else { | |
| var endToken = tokens[tokens.length - 1]; | |
| var isEndDelimited = typeof endToken === "string" | |
| ? delimiterRe.indexOf(endToken[endToken.length - 1]) > -1 | |
| : endToken === undefined; | |
| if (!strict) { | |
| route += "(?:".concat(delimiterRe, "(?=").concat(endsWithRe, "))?"); | |
| } | |
| if (!isEndDelimited) { | |
| route += "(?=".concat(delimiterRe, "|").concat(endsWithRe, ")"); | |
| } | |
| } | |
| return new RegExp(route, flags(options)); | |
| } | |
| exports.tokensToRegexp = tokensToRegexp; | |
| /** | |
| * Normalize the given path string, returning a regular expression. | |
| * | |
| * An empty array can be passed in for the keys, which will hold the | |
| * placeholder key descriptions. For example, using `/user/:id`, `keys` will | |
| * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`. | |
| */ | |
| function pathToRegexp(path, keys, options) { | |
| if (path instanceof RegExp) | |
| return regexpToRegexp(path, keys); | |
| if (Array.isArray(path)) | |
| return arrayToRegexp(path, keys, options); | |
| return stringToRegexp(path, keys, options); | |
| } | |
| exports.pathToRegexp = pathToRegexp; | |
| //# sourceMappingURL=index.js.map |