@nadeshikon/plugin-nextjs
Version:
Run Next.js seamlessly on Netlify
71 lines (63 loc) • 3.36 kB
text/typescript
import { makeLocaleOptional, stripLookahead } from '../packages/runtime/src/helpers/matchers'
const makeDataPath = (path: string) => `/_next/data/build-id${path === '/' ? '/index' : path}.json`
function checkPath(path: string, regex: string) {
const re = new RegExp(regex)
const dataPath = makeDataPath(path)
const testPath = re.test(path)
const testData = re.test(dataPath)
// For easier debugging
// console.log({ path, regex, dataPath, testPath, testData })
return testPath && testData
}
describe('the middleware path matcher', () => {
it('makes the locale slug optional in the regex for the root', () => {
// The regex generated by Next for the path "/" with i18n enabled
const regex =
'^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))(|\\.json|\\/?index|\\/?index\\.json)?[\\/#\\?]?$'
expect(checkPath('/', regex)).toBe(false)
expect(checkPath('/', makeLocaleOptional(regex))).toBe(true)
expect(checkPath('/en', makeLocaleOptional(regex))).toBe(true)
})
it('makes the locale slug optional in the regex for a subpath', () => {
// The regex generated by Next for the path "/static" with i18n enabled
const regex = '^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))\\/static(.json)?[\\/#\\?]?$'
expect(checkPath('/static', regex)).toBe(false)
expect(checkPath('/static', makeLocaleOptional(regex))).toBe(true)
expect(checkPath('/en/static', makeLocaleOptional(regex))).toBe(true)
})
it('does not change the regex when calling makeLocaleOptional with a regex that has no locale', () => {
const regexes = [
'^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/(\\/?index|\\/?index\\.json))?[\\/#\\?]?$',
'^(?:\\/(_next\\/data\\/[^/]{1,}))?\\/api(?:\\/((?:[^\\/#\\?]+?)(?:\\/(?:[^\\/#\\?]+?))*))?(.json)?[\\/#\\?]?$',
'^(?:\\/(_next\\/data\\/[^/]{1,}))?\\/shows(?:\\/((?!99|88).*))(.json)?[\\/#\\?]?$',
]
for (const regex of regexes) {
expect(makeLocaleOptional(regex)).toBe(regex)
}
})
it('removes lookaheads from the regex', () => {
const regexes = [
'^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))\\/shows(?:\\/((?!99|88).*))(.json)?[\\/#\\?]?$',
'^(?:\\/(_next\\/data\\/[^/]{1,}))?\\/shows(?:\\/((?!99|88).*))(.json)?[\\/#\\?]?$',
]
for (const regex of regexes) {
const stripped = stripLookahead(regex)
expect(regex).toMatch(/\(\?!/)
expect(stripped).not.toMatch(/\(\?!/)
}
})
it('converts regexes with lookaheads to stripped ones that still match at least the same paths', () => {
const regex = '^(?:\\/(_next\\/data\\/[^/]{1,}))?\\/shows(?:\\/((?!99|88).*))(.json)?[\\/#\\?]?$'
expect(checkPath('/shows', regex)).toBe(false)
expect(checkPath('/shows/11', regex)).toBe(true)
expect(checkPath('/shows/99', regex)).toBe(false)
expect(checkPath('/shows/888', regex)).toBe(false)
const stripped = stripLookahead(regex)
expect(checkPath('/shows', stripped)).toBe(false)
expect(checkPath('/shows/11', stripped)).toBe(true)
// These will be true because the regex is not as strict as the original one
// The strict test will be done in the JS entrypoint
expect(checkPath('/shows/99', stripped)).toBe(true)
expect(checkPath('/shows/888', stripped)).toBe(true)
})
})