next
Version:
The React Framework
104 lines (103 loc) • 4.5 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
hasAdjacentParameterIssues: null,
normalizeAdjacentParameters: null,
normalizeTokensForRegexp: null,
stripParameterSeparators: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
hasAdjacentParameterIssues: function() {
return hasAdjacentParameterIssues;
},
normalizeAdjacentParameters: function() {
return normalizeAdjacentParameters;
},
normalizeTokensForRegexp: function() {
return normalizeTokensForRegexp;
},
stripParameterSeparators: function() {
return stripParameterSeparators;
}
});
/**
* Route pattern normalization utilities for path-to-regexp compatibility.
*
* path-to-regexp 6.3.0+ introduced stricter validation that rejects certain
* patterns commonly used in Next.js interception routes. This module provides
* normalization functions to make Next.js route patterns compatible with the
* updated library while preserving all functionality.
*/ /**
* Internal separator used to normalize adjacent parameter patterns.
* This unique marker is inserted between adjacent parameters and stripped out
* during parameter extraction to avoid conflicts with real URL content.
*/ const PARAM_SEPARATOR = '_NEXTSEP_';
function hasAdjacentParameterIssues(route) {
if (typeof route !== 'string') return false;
// Check for interception route markers followed immediately by parameters
// Pattern: /(.):param, /(..):param, /(...):param, /(.)(.):param etc.
// These patterns cause "Must have text between two parameters" errors
if (/\/\(\.{1,3}\):[^/\s]+/.test(route)) {
return true;
}
// Check for basic adjacent parameters without separators
// Pattern: :param1:param2 (but not :param* or other URL patterns)
if (/:[a-zA-Z_][a-zA-Z0-9_]*:[a-zA-Z_][a-zA-Z0-9_]*/.test(route)) {
return true;
}
return false;
}
function normalizeAdjacentParameters(route) {
let normalized = route;
// Handle interception route patterns: (.):param -> (.)_NEXTSEP_:param
normalized = normalized.replace(/(\([^)]*\)):([^/\s]+)/g, `$1${PARAM_SEPARATOR}:$2`);
// Handle other adjacent parameter patterns: :param1:param2 -> :param1_NEXTSEP_:param2
normalized = normalized.replace(/:([^:/\s)]+)(?=:)/g, `:$1${PARAM_SEPARATOR}`);
return normalized;
}
function normalizeTokensForRegexp(tokens) {
return tokens.map((token)=>{
// Token union type: Token = string | TokenObject
// Literal path segments are strings, parameters/wildcards are objects
if (typeof token === 'object' && token !== null && // Not all token objects have 'modifier' property (e.g., simple text tokens)
'modifier' in token && // Only repeating modifiers (* or +) cause the validation error
// Other modifiers like '?' (optional) are fine
(token.modifier === '*' || token.modifier === '+') && // Token objects can have different shapes depending on route pattern
'prefix' in token && 'suffix' in token && // Both prefix and suffix must be empty strings
// This is what causes the validation error in path-to-regexp
token.prefix === '' && token.suffix === '') {
// Add minimal prefix to satisfy path-to-regexp validation
// We use '/' as it's the most common path delimiter and won't break route matching
// The prefix gets used in regex generation but doesn't affect parameter extraction
return {
...token,
prefix: '/'
};
}
return token;
});
}
function stripParameterSeparators(params) {
const cleaned = {};
for (const [key, value] of Object.entries(params)){
if (typeof value === 'string') {
// Remove the separator if it appears at the start of parameter values
cleaned[key] = value.replace(new RegExp(`^${PARAM_SEPARATOR}`), '');
} else if (Array.isArray(value)) {
// Handle array parameters (from repeated route segments)
cleaned[key] = value.map((item)=>typeof item === 'string' ? item.replace(new RegExp(`^${PARAM_SEPARATOR}`), '') : item);
} else {
cleaned[key] = value;
}
}
return cleaned;
}
//# sourceMappingURL=route-pattern-normalizer.js.map
;