Files
scrap/node_modules/next/dist/shared/lib/router/utils/route-regex.js
2024-09-24 03:52:46 +00:00

196 lines
7.4 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
getNamedMiddlewareRegex: null,
getNamedRouteRegex: null,
getRouteRegex: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
getNamedMiddlewareRegex: function() {
return getNamedMiddlewareRegex;
},
getNamedRouteRegex: function() {
return getNamedRouteRegex;
},
getRouteRegex: function() {
return getRouteRegex;
}
});
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 { interceptionMarker, 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;
}
// if the segment has an interception marker, make sure that's part of the regex pattern
// this is to ensure that the route with the interception marker doesn't incorrectly match
// the non-intercepted route (ie /app/(.)[username] should not match /app/[username])
const interceptionPrefix = interceptionMarker ? (0, _escaperegexp.escapeStringRegexp)(interceptionMarker) : "";
return repeat ? optional ? "(?:/" + interceptionPrefix + "(?<" + cleanedKey + ">.+?))?" : "/" + interceptionPrefix + "(?<" + cleanedKey + ">.+?)" : "/" + interceptionPrefix + "(?<" + 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) {
const [usedMarker] = segment.split(paramMatches[0]);
return getSafeKeyFromSegment({
getSafeRouteKey,
interceptionMarker: usedMarker,
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