expo-router
Version:
Expo Router is a file-based router for React Native and web applications.
106 lines (104 loc) • 3.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "getPatternParts", {
enumerable: true,
get: function() {
return getPatternParts;
}
});
function getPatternParts(path) {
const parts = [];
let current = {
segment: ''
};
let isRegex = false;
let isParam = false;
let regexInnerParens = 0;
// One extra iteration to add the last character
for(let i = 0; i <= path.length; i++){
const char = path[i];
if (char != null) {
current.segment += char;
}
if (char === ':') {
// The segment must start with a colon if it's a param
if (current.segment === ':') {
isParam = true;
} else if (!isRegex) {
throw new Error(`Encountered ':' in the middle of a segment in path: ${path}`);
}
} else if (char === '(') {
if (isParam) {
if (isRegex) {
// The '(' is part of the regex if we're already inside one
regexInnerParens++;
} else {
isRegex = true;
}
} else {
throw new Error(`Encountered '(' without preceding ':' in path: ${path}`);
}
} else if (char === ')') {
if (isParam && isRegex) {
if (regexInnerParens) {
// The ')' is part of the regex if we're already inside one
regexInnerParens--;
current.regex += char;
} else {
isRegex = false;
isParam = false;
}
} else {
throw new Error(`Encountered ')' without preceding '(' in path: ${path}`);
}
} else if (char === '?') {
if (current.param) {
isParam = false;
current.optional = true;
} else {
throw new Error(`Encountered '?' without preceding ':' in path: ${path}`);
}
} else if (char == null || char === '/' && !isRegex) {
isParam = false;
// Remove trailing slash from segment
current.segment = current.segment.replace(/\/$/, '');
if (current.segment === '') {
continue;
}
if (current.param) {
current.param = current.param.replace(/^:/, '');
}
if (current.regex) {
current.regex = current.regex.replace(/^\(/, '').replace(/\)$/, '');
}
parts.push(current);
if (char == null) {
break;
}
current = {
segment: ''
};
}
if (isRegex) {
current.regex = current.regex || '';
current.regex += char;
}
if (isParam && !isRegex) {
current.param = current.param || '';
current.param += char;
}
}
if (isRegex) {
throw new Error(`Could not find closing ')' in path: ${path}`);
}
const params = parts.map((part)=>part.param).filter(Boolean);
for (const [index, param] of params.entries()){
if (params.indexOf(param) !== index) {
throw new Error(`Duplicate param name '${param}' found in path: ${path}`);
}
}
return parts;
}
//# sourceMappingURL=getPatternParts.js.map