Initial commit
This commit is contained in:
commit
78f8d225ee
21173 changed files with 2907774 additions and 0 deletions
268
node_modules/next/dist/shared/lib/router/utils/route-regex.js
generated
vendored
Normal file
268
node_modules/next/dist/shared/lib/router/utils/route-regex.js
generated
vendored
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
0 && (module.exports = {
|
||||
getNamedMiddlewareRegex: null,
|
||||
getNamedRouteRegex: null,
|
||||
getRouteRegex: null,
|
||||
parseParameter: 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;
|
||||
},
|
||||
parseParameter: function() {
|
||||
return parseParameter;
|
||||
}
|
||||
});
|
||||
const _constants = require("../../../../lib/constants");
|
||||
const _interceptionroutes = require("./interception-routes");
|
||||
const _escaperegexp = require("../../escape-regexp");
|
||||
const _removetrailingslash = require("./remove-trailing-slash");
|
||||
/**
|
||||
* Regular expression pattern used to match route parameters.
|
||||
* Matches both single parameters and parameter groups.
|
||||
* Examples:
|
||||
* - `[[...slug]]` matches parameter group with key 'slug', repeat: true, optional: true
|
||||
* - `[...slug]` matches parameter group with key 'slug', repeat: true, optional: false
|
||||
* - `[[foo]]` matches parameter with key 'foo', repeat: false, optional: true
|
||||
* - `[bar]` matches parameter with key 'bar', repeat: false, optional: false
|
||||
*/ const PARAMETER_PATTERN = /^([^[]*)\[((?:\[[^\]]*\])|[^\]]+)\](.*)$/;
|
||||
function parseParameter(param) {
|
||||
const match = param.match(PARAMETER_PATTERN);
|
||||
if (!match) {
|
||||
return parseMatchedParameter(param);
|
||||
}
|
||||
return parseMatchedParameter(match[2]);
|
||||
}
|
||||
/**
|
||||
* Parses a matched parameter from the PARAMETER_PATTERN regex 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 }`
|
||||
* @param param - The matched parameter to parse.
|
||||
* @returns The parsed parameter as a data structure.
|
||||
*/ function parseMatchedParameter(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, includeSuffix, includePrefix) {
|
||||
const groups = {};
|
||||
let groupIndex = 1;
|
||||
const segments = [];
|
||||
for (const segment of (0, _removetrailingslash.removeTrailingSlash)(route).slice(1).split('/')){
|
||||
const markerMatch = _interceptionroutes.INTERCEPTION_ROUTE_MARKERS.find((m)=>segment.startsWith(m));
|
||||
const paramMatches = segment.match(PARAMETER_PATTERN) // Check for parameters
|
||||
;
|
||||
if (markerMatch && paramMatches && paramMatches[2]) {
|
||||
const { key, optional, repeat } = parseMatchedParameter(paramMatches[2]);
|
||||
groups[key] = {
|
||||
pos: groupIndex++,
|
||||
repeat,
|
||||
optional
|
||||
};
|
||||
segments.push("/" + (0, _escaperegexp.escapeStringRegexp)(markerMatch) + "([^/]+?)");
|
||||
} else if (paramMatches && paramMatches[2]) {
|
||||
const { key, repeat, optional } = parseMatchedParameter(paramMatches[2]);
|
||||
groups[key] = {
|
||||
pos: groupIndex++,
|
||||
repeat,
|
||||
optional
|
||||
};
|
||||
if (includePrefix && paramMatches[1]) {
|
||||
segments.push("/" + (0, _escaperegexp.escapeStringRegexp)(paramMatches[1]));
|
||||
}
|
||||
let s = repeat ? optional ? '(?:/(.+?))?' : '/(.+?)' : '/([^/]+?)';
|
||||
// Remove the leading slash if includePrefix already added it.
|
||||
if (includePrefix && paramMatches[1]) {
|
||||
s = s.substring(1);
|
||||
}
|
||||
segments.push(s);
|
||||
} else {
|
||||
segments.push("/" + (0, _escaperegexp.escapeStringRegexp)(segment));
|
||||
}
|
||||
// If there's a suffix, add it to the segments if it's enabled.
|
||||
if (includeSuffix && paramMatches && paramMatches[3]) {
|
||||
segments.push((0, _escaperegexp.escapeStringRegexp)(paramMatches[3]));
|
||||
}
|
||||
}
|
||||
return {
|
||||
parameterizedRoute: segments.join(''),
|
||||
groups
|
||||
};
|
||||
}
|
||||
function getRouteRegex(normalizedRoute, param) {
|
||||
let { includeSuffix = false, includePrefix = false, excludeOptionalTrailingSlash = false } = param === void 0 ? {} : param;
|
||||
const { parameterizedRoute, groups } = getParametrizedRoute(normalizedRoute, includeSuffix, includePrefix);
|
||||
let re = parameterizedRoute;
|
||||
if (!excludeOptionalTrailingSlash) {
|
||||
re += '(?:/)?';
|
||||
}
|
||||
return {
|
||||
re: new RegExp("^" + re + "$"),
|
||||
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, backreferenceDuplicateKeys } = param;
|
||||
const { key, optional, repeat } = parseMatchedParameter(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();
|
||||
}
|
||||
const duplicateKey = cleanedKey in routeKeys;
|
||||
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) : '';
|
||||
let pattern;
|
||||
if (duplicateKey && backreferenceDuplicateKeys) {
|
||||
// Use a backreference to the key to ensure that the key is the same value
|
||||
// in each of the placeholders.
|
||||
pattern = "\\k<" + cleanedKey + ">";
|
||||
} else if (repeat) {
|
||||
pattern = "(?<" + cleanedKey + ">.+?)";
|
||||
} else {
|
||||
pattern = "(?<" + cleanedKey + ">[^/]+?)";
|
||||
}
|
||||
return optional ? "(?:/" + interceptionPrefix + pattern + ")?" : "/" + interceptionPrefix + pattern;
|
||||
}
|
||||
function getNamedParametrizedRoute(route, prefixRouteKeys, includeSuffix, includePrefix, backreferenceDuplicateKeys) {
|
||||
const getSafeRouteKey = buildGetSafeRouteKey();
|
||||
const routeKeys = {};
|
||||
const segments = [];
|
||||
for (const segment of (0, _removetrailingslash.removeTrailingSlash)(route).slice(1).split('/')){
|
||||
const hasInterceptionMarker = _interceptionroutes.INTERCEPTION_ROUTE_MARKERS.some((m)=>segment.startsWith(m));
|
||||
const paramMatches = segment.match(PARAMETER_PATTERN) // Check for parameters
|
||||
;
|
||||
if (hasInterceptionMarker && paramMatches && paramMatches[2]) {
|
||||
// If there's an interception marker, add it to the segments.
|
||||
segments.push(getSafeKeyFromSegment({
|
||||
getSafeRouteKey,
|
||||
interceptionMarker: paramMatches[1],
|
||||
segment: paramMatches[2],
|
||||
routeKeys,
|
||||
keyPrefix: prefixRouteKeys ? _constants.NEXT_INTERCEPTION_MARKER_PREFIX : undefined,
|
||||
backreferenceDuplicateKeys
|
||||
}));
|
||||
} else if (paramMatches && paramMatches[2]) {
|
||||
// If there's a prefix, add it to the segments if it's enabled.
|
||||
if (includePrefix && paramMatches[1]) {
|
||||
segments.push("/" + (0, _escaperegexp.escapeStringRegexp)(paramMatches[1]));
|
||||
}
|
||||
let s = getSafeKeyFromSegment({
|
||||
getSafeRouteKey,
|
||||
segment: paramMatches[2],
|
||||
routeKeys,
|
||||
keyPrefix: prefixRouteKeys ? _constants.NEXT_QUERY_PARAM_PREFIX : undefined,
|
||||
backreferenceDuplicateKeys
|
||||
});
|
||||
// Remove the leading slash if includePrefix already added it.
|
||||
if (includePrefix && paramMatches[1]) {
|
||||
s = s.substring(1);
|
||||
}
|
||||
segments.push(s);
|
||||
} else {
|
||||
segments.push("/" + (0, _escaperegexp.escapeStringRegexp)(segment));
|
||||
}
|
||||
// If there's a suffix, add it to the segments if it's enabled.
|
||||
if (includeSuffix && paramMatches && paramMatches[3]) {
|
||||
segments.push((0, _escaperegexp.escapeStringRegexp)(paramMatches[3]));
|
||||
}
|
||||
}
|
||||
return {
|
||||
namedParameterizedRoute: segments.join(''),
|
||||
routeKeys
|
||||
};
|
||||
}
|
||||
function getNamedRouteRegex(normalizedRoute, options) {
|
||||
var _options_includeSuffix, _options_includePrefix, _options_backreferenceDuplicateKeys;
|
||||
const result = getNamedParametrizedRoute(normalizedRoute, options.prefixRouteKeys, (_options_includeSuffix = options.includeSuffix) != null ? _options_includeSuffix : false, (_options_includePrefix = options.includePrefix) != null ? _options_includePrefix : false, (_options_backreferenceDuplicateKeys = options.backreferenceDuplicateKeys) != null ? _options_backreferenceDuplicateKeys : false);
|
||||
let namedRegex = result.namedParameterizedRoute;
|
||||
if (!options.excludeOptionalTrailingSlash) {
|
||||
namedRegex += '(?:/)?';
|
||||
}
|
||||
return {
|
||||
...getRouteRegex(normalizedRoute, options),
|
||||
namedRegex: "^" + namedRegex + "$",
|
||||
routeKeys: result.routeKeys
|
||||
};
|
||||
}
|
||||
function getNamedMiddlewareRegex(normalizedRoute, options) {
|
||||
const { parameterizedRoute } = getParametrizedRoute(normalizedRoute, false, false);
|
||||
const { catchAll = true } = options;
|
||||
if (parameterizedRoute === '/') {
|
||||
let catchAllRegex = catchAll ? '.*' : '';
|
||||
return {
|
||||
namedRegex: "^/" + catchAllRegex + "$"
|
||||
};
|
||||
}
|
||||
const { namedParameterizedRoute } = getNamedParametrizedRoute(normalizedRoute, false, false, false, false);
|
||||
let catchAllGroupedRegex = catchAll ? '(?:(/.*)?)' : '';
|
||||
return {
|
||||
namedRegex: "^" + namedParameterizedRoute + catchAllGroupedRegex + "$"
|
||||
};
|
||||
}
|
||||
|
||||
//# sourceMappingURL=route-regex.js.map
|
||||
Loading…
Add table
Add a link
Reference in a new issue