From f9325253d75677b482b30539403006401393e4fe Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 12 Jan 2024 02:56:26 +0200 Subject: [PATCH 1/3] feat(nextjs): Introduce stable createRouteMatcher --- packages/nextjs/src/server/index.ts | 12 +----------- packages/nextjs/src/server/routeMatcher.ts | 16 +++++++--------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/packages/nextjs/src/server/index.ts b/packages/nextjs/src/server/index.ts index 58aa59ae55e..798b7e0bb1b 100644 --- a/packages/nextjs/src/server/index.ts +++ b/packages/nextjs/src/server/index.ts @@ -1,7 +1,7 @@ /** * Generic exports */ -import { createRouteMatcher } from './routeMatcher'; +export { createRouteMatcher } from './routeMatcher'; export { verifyToken, createClerkClient } from '@clerk/backend'; export type { WebhookEvent, WebhookEventType } from '@clerk/backend'; @@ -16,13 +16,3 @@ export { auth } from '../app-router/server/auth'; export { currentUser } from '../app-router/server/currentUser'; export { authMiddleware } from './authMiddleware'; export { clerkMiddleware } from './clerkMiddleware'; - -/** - * Returns a function that accepts a `Request` object and returns whether the request matches the list of - * predefined routes that can be passed in as the first argument. - * - * You can use glob patterns to match multiple routes or a function to match against the request object. - * Path patterns and regular expressions are supported, for example: `['/foo', '/bar(.*)'] or `[/^\/foo\/.*$/]` - * For more information, see: https://clerk.com/docs - */ -export const experimental_createRouteMatcher = createRouteMatcher; diff --git a/packages/nextjs/src/server/routeMatcher.ts b/packages/nextjs/src/server/routeMatcher.ts index c52216b9c82..304811d64a3 100644 --- a/packages/nextjs/src/server/routeMatcher.ts +++ b/packages/nextjs/src/server/routeMatcher.ts @@ -7,12 +7,7 @@ import { paths } from '../utils'; type WithPathPatternWildcard = `${T & string}(.*)`; type NextTypedRoute['0']['href']> = T extends string ? T : never; -// For extra safety, we won't recommend using a `/(.*)` route matcher. -type ExcludeRootPath = T extends '/' ? never : T; - -type RouteMatcherWithNextTypedRoutes = Autocomplete< - WithPathPatternWildcard> | NextTypedRoute ->; +type RouteMatcherWithNextTypedRoutes = Autocomplete | NextTypedRoute>; export type RouteMatcherParam = | Array @@ -21,9 +16,12 @@ export type RouteMatcherParam = | ((req: NextRequest) => boolean); /** - * Create a function that matches a request against the specified routes. - * Precomputes the glob matchers for the public routes, so we don't have to - * recompile the regular expressions on every request. + * Returns a function that accepts a `Request` object and returns whether the request matches the list of + * predefined routes that can be passed in as the first argument. + * + * You can use glob patterns to match multiple routes or a function to match against the request object. + * Path patterns and regular expressions are supported, for example: `['/foo', '/bar(.*)'] or `[/^\/foo\/.*$/]` + * For more information, see: https://clerk.com/docs */ export const createRouteMatcher = (routes: RouteMatcherParam) => { if (typeof routes === 'function') { From 5244dd3b90abdd919bcb60133046039a9ec4c7cb Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 12 Jan 2024 03:02:24 +0200 Subject: [PATCH 2/3] Create hungry-lies-burn.md --- .changeset/hungry-lies-burn.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .changeset/hungry-lies-burn.md diff --git a/.changeset/hungry-lies-burn.md b/.changeset/hungry-lies-burn.md new file mode 100644 index 00000000000..cb11797310e --- /dev/null +++ b/.changeset/hungry-lies-burn.md @@ -0,0 +1,16 @@ +--- +"@clerk/nextjs": patch +--- + +Introduce `createRouteMatcher` which is designed to generate and return a function that evaluates whether a given Request object matches a set of predefined routes. It provides flexibility in defining these routes through various patterns, including glob patterns, regular expressions, and custom functions. This composable helper can be used in combination with the `clerkMiddleware` helper to easily protect specific routes, eg: +```ts +import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'; + +const isProtectedRoute = createRouteMatcher(['/dashboard(.*)']); + +export default clerkMiddleware((auth, request) => { + if (isProtectedRoute(request)) { + auth().protect(); + } +}); +``` From b980afbe1498e5bdb9261a6ff258f9be8c72bbb9 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 12 Jan 2024 03:08:37 +0200 Subject: [PATCH 3/3] Create hungry-lies-burn.md --- .../src/server/__tests__/__snapshots__/exports.test.ts.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/src/server/__tests__/__snapshots__/exports.test.ts.snap b/packages/nextjs/src/server/__tests__/__snapshots__/exports.test.ts.snap index db01c5c1eb8..127181d0aad 100644 --- a/packages/nextjs/src/server/__tests__/__snapshots__/exports.test.ts.snap +++ b/packages/nextjs/src/server/__tests__/__snapshots__/exports.test.ts.snap @@ -8,8 +8,8 @@ exports[`/server public exports should not include a breaking change 1`] = ` "clerkClient", "clerkMiddleware", "createClerkClient", + "createRouteMatcher", "currentUser", - "experimental_createRouteMatcher", "getAuth", "redirectToSignIn", "redirectToSignUp",