Skip to content

Commit

Permalink
Allow RegExp values
Browse files Browse the repository at this point in the history
  • Loading branch information
Schniz committed May 25, 2022
1 parent a1d3b40 commit 5a269bb
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 25 deletions.
8 changes: 8 additions & 0 deletions packages/next/build/analysis/extract-const-value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
NullLiteral,
NumericLiteral,
ObjectExpression,
RegExpLiteral,
StringLiteral,
VariableDeclaration,
} from '@swc/core'
Expand Down Expand Up @@ -119,6 +120,10 @@ function isKeyValueProperty(node: Node): node is KeyValueProperty {
return node.type === 'KeyValueProperty'
}

function isRegExpLiteral(node: Node): node is RegExpLiteral {
return node.type === 'RegExpLiteral'
}

class UnsupportedValueError extends Error {}
class NoSuchDeclarationError extends Error {}

Expand All @@ -134,6 +139,9 @@ function extractValue(node: Node): any {
} else if (isNumericLiteral(node)) {
// e.g. 123
return node.value
} else if (isRegExpLiteral(node)) {
// e.g. /abc/i
return new RegExp(node.pattern, node.flags)
} else if (isIdentifier(node)) {
switch (node.value) {
case 'undefined':
Expand Down
4 changes: 3 additions & 1 deletion packages/next/build/analysis/get-page-static-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ function getMiddlewareConfig(config: any): Partial<MiddlewareConfig> {
const result: Partial<MiddlewareConfig> = {}

const matcher = config.matcher
if (typeof matcher === 'string') {
if (matcher instanceof RegExp) {
result.pathMatcher = matcher
} else if (typeof matcher === 'string') {
const parsed = tryToParsePath(matcher)
if (parsed.regexStr) {
result.pathMatcher = new RegExp(parsed.regexStr)
Expand Down
9 changes: 4 additions & 5 deletions packages/next/build/entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,14 @@ export function getEdgeServerEntry(opts: {
isServerComponent: boolean
page: string
pages: { [page: string]: string }
middleware?: { matcher?: RegExp }
middleware?: { pathMatcher?: RegExp }
}) {
if (opts.page === MIDDLEWARE_FILE) {
const loaderParams: MiddlewareLoaderOptions = {
absolutePagePath: opts.absolutePagePath,
page: opts.page,
matcherRegexp: opts.middleware?.matcher && opts.middleware.matcher.source,
matcherRegexp:
opts.middleware?.pathMatcher && opts.middleware.pathMatcher.source,
}

return `next-middleware-loader?${stringify(loaderParams)}!`
Expand Down Expand Up @@ -378,9 +379,7 @@ export async function createEntrypoints(params: CreateEntrypointsParams) {
isDev: false,
isServerComponent,
page,
middleware: {
matcher: staticInfo?.middleware?.pathMatcher,
},
middleware: staticInfo?.middleware,
})
},
})
Expand Down
86 changes: 67 additions & 19 deletions test/e2e/middleware-can-set-the-matcher-in-its-config/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@ import { NextInstance } from 'test/lib/next-modes/base'
import { fetchViaHTTP } from 'next-test-utils'

describe('Middleware can set the matcher in its config', () => {
let next: NextInstance
describe('using a path pattern', () => {
let next: NextInstance

beforeAll(async () => {
next = await createNext({
files: {
'pages/index.js': `
beforeAll(async () => {
next = await createNext({
files: {
'pages/index.js': `
export default function Page() {
return <p>root page</p>
}
`,
'pages/with-middleware/index.js': `
'pages/with-middleware/index.js': `
export default function Page() {
return <p>This should run the middleware</p>
}
`,
'middleware.js': `
'middleware.js': `
import { NextResponse } from 'next/server'
export const config = {
matcher: '/with-middleware/:path*'
Expand All @@ -29,21 +30,68 @@ describe('Middleware can set the matcher in its config', () => {
return res;
}
`,
},
dependencies: {},
},
dependencies: {},
})
})
afterAll(() => next.destroy())

it('does not add the header for root request', async () => {
const response = await fetchViaHTTP(next.url, '/')
expect(response.headers.get('X-From-Middleware')).toBeNull()
expect(await response.text()).toContain('root page')
})
})
afterAll(() => next.destroy())

it('does not add the header for root request', async () => {
const response = await fetchViaHTTP(next.url, '/')
expect(response.headers.get('X-From-Middleware')).toBeNull()
expect(await response.text()).toContain('root page')
it('adds the header for a matched path', async () => {
const response = await fetchViaHTTP(next.url, '/with-middleware')
expect(response.headers.get('X-From-Middleware')).toBe('true')
expect(await response.text()).toContain('This should run the middleware')
})
})

it('adds the header for a matched path', async () => {
const response = await fetchViaHTTP(next.url, '/with-middleware')
expect(response.headers.get('X-From-Middleware')).toBe('true')
expect(await response.text()).toContain('This should run the middleware')
describe('using RegExp', () => {
let next: NextInstance

beforeAll(async () => {
next = await createNext({
files: {
'pages/index.js': `
export default function Page() {
return <p>root page</p>
}
`,
'pages/with-middleware/index.js': `
export default function Page() {
return <p>This should run the middleware</p>
}
`,
'middleware.js': `
import { NextResponse } from 'next/server'
export const config = {
matcher: /middleware/,
};
export default (req) => {
const res = NextResponse.next();
res.headers.set('X-From-Middleware', 'true');
return res;
}
`,
},
dependencies: {},
})
})
afterAll(() => next.destroy())

it('does not add the header for root request', async () => {
const response = await fetchViaHTTP(next.url, '/')
expect(response.headers.get('X-From-Middleware')).toBeNull()
expect(await response.text()).toContain('root page')
})

it('adds the header for a matched path', async () => {
const response = await fetchViaHTTP(next.url, '/with-middleware')
expect(response.headers.get('X-From-Middleware')).toBe('true')
expect(await response.text()).toContain('This should run the middleware')
})
})
})

0 comments on commit 5a269bb

Please sign in to comment.