190 lines
6.8 KiB
JavaScript
190 lines
6.8 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
0 && (module.exports = {
|
|
getRouteRegex: null,
|
|
getNamedRouteRegex: null,
|
|
getNamedMiddlewareRegex: null
|
|
});
|
|
function _export(target, all) {
|
|
for(var name in all)Object.defineProperty(target, name, {
|
|
enumerable: true,
|
|
get: all[name]
|
|
});
|
|
}
|
|
_export(exports, {
|
|
getRouteRegex: function() {
|
|
return getRouteRegex;
|
|
},
|
|
getNamedRouteRegex: function() {
|
|
return getNamedRouteRegex;
|
|
},
|
|
getNamedMiddlewareRegex: function() {
|
|
return getNamedMiddlewareRegex;
|
|
}
|
|
});
|
|
const _interceptionroutes = require("../../../../server/future/helpers/interception-routes");
|
|
const _escaperegexp = require("../../escape-regexp");
|
|
const _removetrailingslash = require("./remove-trailing-slash");
|
|
const NEXT_QUERY_PARAM_PREFIX = "nxtP";
|
|
const NEXT_INTERCEPTION_MARKER_PREFIX = "nxtI";
|
|
/**
|
|
* Parses a given parameter from a route to a data structure that can be used
|
|
* to generate the parametrized route. Examples:
|
|
* - `[...slug]` -> `{ key: 'slug', repeat: true, optional: true }`
|
|
* - `...slug` -> `{ key: 'slug', repeat: true, optional: false }`
|
|
* - `[foo]` -> `{ key: 'foo', repeat: false, optional: true }`
|
|
* - `bar` -> `{ key: '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)=>{
|
|
const markerMatch = _interceptionroutes.INTERCEPTION_ROUTE_MARKERS.find((m)=>segment.startsWith(m));
|
|
const paramMatches = segment.match(/\[((?:\[.*\])|.+)\]/) // Check for parameters
|
|
;
|
|
if (markerMatch && paramMatches) {
|
|
const { key, optional, repeat } = parseParameter(paramMatches[1]);
|
|
groups[key] = {
|
|
pos: groupIndex++,
|
|
repeat,
|
|
optional
|
|
};
|
|
return "/" + (0, _escaperegexp.escapeStringRegexp)(markerMatch) + "([^/]+?)";
|
|
} else if (paramMatches) {
|
|
const { key, repeat, optional } = parseParameter(paramMatches[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 i = 0;
|
|
return ()=>{
|
|
let routeKey = "";
|
|
let j = ++i;
|
|
while(j > 0){
|
|
routeKey += String.fromCharCode(97 + (j - 1) % 26);
|
|
j = Math.floor((j - 1) / 26);
|
|
}
|
|
return routeKey;
|
|
};
|
|
}
|
|
function getSafeKeyFromSegment(param) {
|
|
let { getSafeRouteKey, segment, routeKeys, keyPrefix } = param;
|
|
const { key, optional, repeat } = parseParameter(segment);
|
|
// replace any non-word characters since they can break
|
|
// the named regex
|
|
let cleanedKey = key.replace(/\W/g, "");
|
|
if (keyPrefix) {
|
|
cleanedKey = "" + keyPrefix + cleanedKey;
|
|
}
|
|
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();
|
|
}
|
|
if (keyPrefix) {
|
|
routeKeys[cleanedKey] = "" + keyPrefix + key;
|
|
} else {
|
|
routeKeys[cleanedKey] = "" + key;
|
|
}
|
|
return repeat ? optional ? "(?:/(?<" + cleanedKey + ">.+?))?" : "/(?<" + cleanedKey + ">.+?)" : "/(?<" + cleanedKey + ">[^/]+?)";
|
|
}
|
|
function getNamedParametrizedRoute(route, prefixRouteKeys) {
|
|
const segments = (0, _removetrailingslash.removeTrailingSlash)(route).slice(1).split("/");
|
|
const getSafeRouteKey = buildGetSafeRouteKey();
|
|
const routeKeys = {};
|
|
return {
|
|
namedParameterizedRoute: segments.map((segment)=>{
|
|
const hasInterceptionMarker = _interceptionroutes.INTERCEPTION_ROUTE_MARKERS.some((m)=>segment.startsWith(m));
|
|
const paramMatches = segment.match(/\[((?:\[.*\])|.+)\]/) // Check for parameters
|
|
;
|
|
if (hasInterceptionMarker && paramMatches) {
|
|
return getSafeKeyFromSegment({
|
|
getSafeRouteKey,
|
|
segment: paramMatches[1],
|
|
routeKeys,
|
|
keyPrefix: prefixRouteKeys ? NEXT_INTERCEPTION_MARKER_PREFIX : undefined
|
|
});
|
|
} else if (paramMatches) {
|
|
return getSafeKeyFromSegment({
|
|
getSafeRouteKey,
|
|
segment: paramMatches[1],
|
|
routeKeys,
|
|
keyPrefix: prefixRouteKeys ? NEXT_QUERY_PARAM_PREFIX : undefined
|
|
});
|
|
} else {
|
|
return "/" + (0, _escaperegexp.escapeStringRegexp)(segment);
|
|
}
|
|
}).join(""),
|
|
routeKeys
|
|
};
|
|
}
|
|
function getNamedRouteRegex(normalizedRoute, prefixRouteKey) {
|
|
const result = getNamedParametrizedRoute(normalizedRoute, prefixRouteKey);
|
|
return {
|
|
...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, false);
|
|
let catchAllGroupedRegex = catchAll ? "(?:(/.*)?)" : "";
|
|
return {
|
|
namedRegex: "^" + namedParameterizedRoute + catchAllGroupedRegex + "$"
|
|
};
|
|
}
|
|
|
|
//# sourceMappingURL=route-regex.js.map
|