(
path: string,
options?: { keepGroups: boolean },
)
| 185 | * Transform a filesystem URL path to a `path-to-regex` style matcher. |
| 186 | */ |
| 187 | export function pathToPattern( |
| 188 | path: string, |
| 189 | options?: { keepGroups: boolean }, |
| 190 | ): string { |
| 191 | const parts = path.split("/"); |
| 192 | if (parts[parts.length - 1] === "index") { |
| 193 | if (parts.length === 1) { |
| 194 | return "/"; |
| 195 | } |
| 196 | parts.pop(); |
| 197 | } |
| 198 | |
| 199 | let route = ""; |
| 200 | |
| 201 | let nonOptionalSegments = 0; |
| 202 | for (let i = 0; i < parts.length; i++) { |
| 203 | const part = parts[i]; |
| 204 | |
| 205 | // Case: /[...foo].tsx |
| 206 | if (part.startsWith("[...") && part.endsWith("]")) { |
| 207 | route += `/:${part.slice(4, part.length - 1)}*`; |
| 208 | continue; |
| 209 | } |
| 210 | |
| 211 | // Route groups like /foo/(bar) should not be included in URL |
| 212 | // matching. They are transparent and need to be removed here. |
| 213 | // Case: /foo/(bar) -> /foo |
| 214 | // Case: /foo/(bar)/bob -> /foo/bob |
| 215 | // Case: /(foo)/bar -> /bar |
| 216 | if (!options?.keepGroups && part.startsWith("(") && part.endsWith(")")) { |
| 217 | continue; |
| 218 | } |
| 219 | |
| 220 | // Disallow neighbouring params like `/[id][bar].tsx` because |
| 221 | // it's ambiguous where the `id` param ends and `bar` begins. |
| 222 | if (part.includes("][")) { |
| 223 | throw new SyntaxError( |
| 224 | `Invalid route pattern: "${path}". A parameter cannot be followed by another parameter without any characters in between.`, |
| 225 | ); |
| 226 | } |
| 227 | |
| 228 | // Case: /[[id]].tsx |
| 229 | // Case: /[id].tsx |
| 230 | // Case: /[id]@[bar].tsx |
| 231 | // Case: /[id]-asdf.tsx |
| 232 | // Case: /[id]-asdf[bar].tsx |
| 233 | // Case: /asdf[bar].tsx |
| 234 | let pattern = ""; |
| 235 | let groupOpen = 0; |
| 236 | let optional = false; |
| 237 | for (let j = 0; j < part.length; j++) { |
| 238 | const char = part[j]; |
| 239 | if (char === "[") { |
| 240 | if (part[j + 1] === "[") { |
| 241 | // Disallow optional dynamic params like `foo-[[bar]]` |
| 242 | if (part[j - 1] !== "/" && !!part[j - 1]) { |
| 243 | throw new SyntaxError( |
| 244 | `Invalid route pattern: "${path}". An optional parameter needs to be a full segment.`, |
no outgoing calls
no test coverage detected