"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getRouteRegex = getRouteRegex; exports.getNamedRouteRegex = getNamedRouteRegex; exports.getNamedMiddlewareRegex = getNamedMiddlewareRegex; var _extends = require("@swc/helpers/lib/_extends.js").default; var _escapeRegexp = require("../../escape-regexp"); var _removeTrailingSlash = require("./remove-trailing-slash"); /** * Parses a given parameter from a route to a data structure that can be used * to generate the parametrized route. Examples: * - `[...slug]` -> `{ name: 'slug', repeat: true, optional: true }` * - `[foo]` -> `{ name: 'foo', repeat: false, optional: true }` * - `bar` -> `{ name: 'bar', repeat: false, optional: false }` */ function parseParameter(param) { const optional = param.startsWith('[') && param.endsWith(']'); if (optional) { param = param.slice(1, -1); } const repeat = param.startsWith('...'); if (repeat) { param = param.slice(3); } return { key: param, repeat, optional }; } function getParametrizedRoute(route) { const segments = (0, _removeTrailingSlash).removeTrailingSlash(route).slice(1).split('/'); const groups = {}; let groupIndex = 1; return { parameterizedRoute: segments.map((segment)=>{ if (segment.startsWith('[') && segment.endsWith(']')) { const { key , optional , repeat } = parseParameter(segment.slice(1, -1)); groups[key] = { pos: groupIndex++, repeat, optional }; return repeat ? optional ? '(?:/(.+?))?' : '/(.+?)' : '/([^/]+?)'; } else { return `/${(0, _escapeRegexp).escapeStringRegexp(segment)}`; } }).join(''), groups }; } function getRouteRegex(normalizedRoute) { const { parameterizedRoute , groups } = getParametrizedRoute(normalizedRoute); return { re: new RegExp(`^${parameterizedRoute}(?:/)?$`), groups: groups }; } /** * Builds a function to generate a minimal routeKey using only a-z and minimal * number of characters. */ function buildGetSafeRouteKey() { let routeKeyCharCode = 97; let routeKeyCharLength = 1; return ()=>{ let routeKey = ''; for(let i = 0; i < routeKeyCharLength; i++){ routeKey += String.fromCharCode(routeKeyCharCode); routeKeyCharCode++; if (routeKeyCharCode > 122) { routeKeyCharLength++; routeKeyCharCode = 97; } } return routeKey; }; } function getNamedParametrizedRoute(route) { const segments = (0, _removeTrailingSlash).removeTrailingSlash(route).slice(1).split('/'); const getSafeRouteKey = buildGetSafeRouteKey(); const routeKeys = {}; return { namedParameterizedRoute: segments.map((segment)=>{ if (segment.startsWith('[') && segment.endsWith(']')) { const { key , optional , repeat } = parseParameter(segment.slice(1, -1)); // replace any non-word characters since they can break // the named regex let cleanedKey = key.replace(/\W/g, ''); let invalidKey = false; // check if the key is still invalid and fallback to using a known // safe key if (cleanedKey.length === 0 || cleanedKey.length > 30) { invalidKey = true; } if (!isNaN(parseInt(cleanedKey.slice(0, 1)))) { invalidKey = true; } if (invalidKey) { cleanedKey = getSafeRouteKey(); } routeKeys[cleanedKey] = key; return repeat ? optional ? `(?:/(?<${cleanedKey}>.+?))?` : `/(?<${cleanedKey}>.+?)` : `/(?<${cleanedKey}>[^/]+?)`; } else { return `/${(0, _escapeRegexp).escapeStringRegexp(segment)}`; } }).join(''), routeKeys }; } function getNamedRouteRegex(normalizedRoute) { const result = getNamedParametrizedRoute(normalizedRoute); return _extends({}, getRouteRegex(normalizedRoute), { namedRegex: `^${result.namedParameterizedRoute}(?:/)?$`, routeKeys: result.routeKeys }); } function getNamedMiddlewareRegex(normalizedRoute, options) { const { parameterizedRoute } = getParametrizedRoute(normalizedRoute); const { catchAll =true } = options; if (parameterizedRoute === '/') { let catchAllRegex = catchAll ? '.*' : ''; return { namedRegex: `^/${catchAllRegex}$` }; } const { namedParameterizedRoute } = getNamedParametrizedRoute(normalizedRoute); let catchAllGroupedRegex = catchAll ? '(?:(/.*)?)' : ''; return { namedRegex: `^${namedParameterizedRoute}${catchAllGroupedRegex}$` }; } //# sourceMappingURL=route-regex.js.map