Skip to content

Commit 772ff00

Browse files
committed
Add ability to add custom include & exclude patterns. Blacklist static assets for middleware
1 parent ecbc834 commit 772ff00

File tree

3 files changed

+31
-12
lines changed

3 files changed

+31
-12
lines changed

astro.config.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,9 @@ export default defineConfig({
210210
supportedLanguages: SUPPORTED_LANGUAGES,
211211
manualMatchers: ["/en", "/en/:path*"],
212212
}),
213-
vercelMiddlewareIntegration(),
213+
vercelMiddlewareIntegration({
214+
exclude: ["/(.*).(png|jpg|jpeg|gif|svg|webp|avif|ico|css|js|map|ico)"],
215+
}),
214216
],
215217
adapter: process.env.VERCEL
216218
? vercel({

integrations/vercel-middleware/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { fileURLToPath } from "node:url";
22
import type { AstroConfig, AstroIntegration, IntegrationResolvedRoute } from "astro";
33
import { getAstroMiddlewarePath } from "./utils/astro";
4-
import { buildMiddlewareMatcherRegexp } from "./utils/matcher";
4+
import { buildMiddlewareMatcherRegexp, type MatcherOptions } from "./utils/matcher";
55
import { generateEdgeMiddlewareFile } from "./utils/middleware";
66
import {
77
generateFunctionConfig,
@@ -13,7 +13,9 @@ const INTEGRATION_NAME = "vercel-middleware";
1313
const VERCEL_ADAPTER_LINK = "[@astrojs/vercel](https://www.npmjs.com/package/@astrojs/vercel)";
1414
const VERCEL_MIDDLEWARE_FUNCTION_NAME = "_middleware";
1515

16-
export default function vercelMiddlewareIntegration() {
16+
type VercelMiddlewareIntegrationOptions = MatcherOptions;
17+
18+
export default function vercelMiddlewareIntegration(options?: VercelMiddlewareIntegrationOptions) {
1719
let astroConfig: AstroConfig;
1820
let resolvedRoutes: IntegrationResolvedRoute[];
1921

@@ -68,6 +70,7 @@ export default function vercelMiddlewareIntegration() {
6870
const matcher = buildMiddlewareMatcherRegexp({
6971
assetsDir: astroConfig.build.assets,
7072
routes: resolvedRoutes,
73+
...options,
7174
});
7275

7376
logger.info("Inserting generated middleware into vercel output config…");
Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,45 @@
11
import type { IntegrationResolvedRoute } from "astro";
22

3-
interface BuildMiddlewareMatcherRegexpOptions {
3+
export interface MatcherOptions {
4+
include?: (string | RegExp)[];
5+
exclude?: (string | RegExp)[];
6+
}
7+
8+
interface BuildMiddlewareMatcherRegexpOptions extends MatcherOptions {
49
assetsDir: string;
510
routes: IntegrationResolvedRoute[];
611
}
712

813
export function buildMiddlewareMatcherRegexp({
914
routes,
1015
assetsDir,
16+
exclude,
17+
include,
1118
}: BuildMiddlewareMatcherRegexpOptions) {
12-
const assetsPattern = `/${assetsDir}/(.*)`;
1319
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)];
1626

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.join("|")})$`;
2031
}
2132

2233
// Strips leading ^ and trailing $ from a RegExp pattern string
2334
const PATTERN_STRIP_LINE_START = /^\^/;
2435
const PATTERN_STRIP_LINE_END = /\$$/;
25-
function stripPatternRegexp(pattern: RegExp) {
36+
function stripRoutePattern(pattern: string | RegExp) {
2637
return pattern
2738
.toString()
28-
.slice(1, -1)
2939
.replace(PATTERN_STRIP_LINE_START, "")
3040
.replace(PATTERN_STRIP_LINE_END, "");
3141
}
42+
43+
function stripAstroRoutePatternRegexp(pattern: RegExp) {
44+
return stripRoutePattern(pattern.toString().slice(1, -1));
45+
}

0 commit comments

Comments
 (0)