|
1 | 1 | import type { IntegrationResolvedRoute } from "astro"; |
2 | 2 |
|
3 | | -interface BuildMiddlewareMatcherRegexpOptions { |
| 3 | +export interface MatcherOptions { |
| 4 | + include?: (string | RegExp)[]; |
| 5 | + exclude?: (string | RegExp)[]; |
| 6 | +} |
| 7 | + |
| 8 | +interface BuildMiddlewareMatcherRegexpOptions extends MatcherOptions { |
4 | 9 | assetsDir: string; |
5 | 10 | routes: IntegrationResolvedRoute[]; |
6 | 11 | } |
7 | 12 |
|
8 | 13 | export function buildMiddlewareMatcherRegexp({ |
9 | 14 | routes, |
10 | 15 | assetsDir, |
| 16 | + exclude, |
| 17 | + include, |
11 | 18 | }: BuildMiddlewareMatcherRegexpOptions) { |
12 | | - const assetsPattern = `/${assetsDir}/(.*)`; |
13 | 19 | const groupedRoutes = Object.groupBy(routes, (r) => r.origin); |
14 | | - const internalPatterns = |
15 | | - groupedRoutes.internal?.map((r) => stripPatternRegexp(r.patternRegex)) ?? []; |
| 20 | + const dontMatchPatterns = [ |
| 21 | + `\\/${assetsDir}\\/(.*)`, |
| 22 | + ...(groupedRoutes.internal?.map((r) => stripAstroRoutePatternRegexp(r.patternRegex)) ?? []), |
| 23 | + ...(exclude ?? []).map(stripRoutePattern), |
| 24 | + ]; |
| 25 | + const matchPatterns = [...(include ?? []).map(stripRoutePattern)]; |
16 | 26 |
|
17 | | - // The regex is constructed to negate any internal Astro paths |
18 | | - // For example it can output such regexp: /^(?!.*\/(_server-islands\/[^\/]+\/?|_image\/?)$).*$/; |
19 | | - return `^(?!.*(${[assetsPattern, ...internalPatterns].join("|")})$).*$`; |
| 27 | + // The regex is constructed to first negate any paths that match the internal patterns |
| 28 | + // and then allow paths that match the project patterns. |
| 29 | + // For example it can output such regexp: /^(?!.*(\/_server-islands\/[^\/]+\/?|\/_image\/?)$)(?:\/(.*))$/; |
| 30 | + return `^(?!.*(${dontMatchPatterns.join("|")})$)(?:${matchPatterns.length ? matchPatterns.join("|") : "\\/.*"})$`; |
20 | 31 | } |
21 | 32 |
|
22 | 33 | // Strips leading ^ and trailing $ from a RegExp pattern string |
23 | 34 | const PATTERN_STRIP_LINE_START = /^\^/; |
24 | 35 | const PATTERN_STRIP_LINE_END = /\$$/; |
25 | | -function stripPatternRegexp(pattern: RegExp) { |
| 36 | +function stripRoutePattern(pattern: string | RegExp) { |
26 | 37 | return pattern |
27 | 38 | .toString() |
28 | | - .slice(1, -1) |
29 | 39 | .replace(PATTERN_STRIP_LINE_START, "") |
30 | 40 | .replace(PATTERN_STRIP_LINE_END, ""); |
31 | 41 | } |
| 42 | + |
| 43 | +function stripAstroRoutePatternRegexp(pattern: RegExp) { |
| 44 | + return stripRoutePattern(pattern.toString().slice(1, -1)); |
| 45 | +} |
0 commit comments