Skip to content

Commit

Permalink
Merge branch 'canary' into hotfix/wp5-alias-only
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored Aug 21, 2020
2 parents 766617f + 4507422 commit 2b07a8c
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 11 deletions.
34 changes: 23 additions & 11 deletions packages/next/build/webpack/loaders/next-serverless-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ const nextServerlessLoader: loader.Loader = function () {
`
: ''

const collectDynamicRouteParams = pageIsDynamicRoute
const normalizeDynamicRouteParams = pageIsDynamicRoute
? `
function collectDynamicRouteParams(query) {
function normalizeDynamicRouteParams(query) {
return Object.keys(defaultRouteRegex.groups)
.reduce((prev, key) => {
let value = query[key]
Expand All @@ -84,7 +84,14 @@ const nextServerlessLoader: loader.Loader = function () {
// non-provided optional values should be undefined so normalize
// them to undefined
}
if(defaultRouteRegex.groups[key].optional && !value) {
if(
defaultRouteRegex.groups[key].optional &&
(!value || (
Array.isArray(value) &&
value.length === 1 &&
value[0] === 'index'
))
) {
value = undefined
delete query[key]
}
Expand Down Expand Up @@ -223,7 +230,7 @@ const nextServerlessLoader: loader.Loader = function () {
${defaultRouteRegex}
${collectDynamicRouteParams}
${normalizeDynamicRouteParams}
${handleRewrites}
Expand All @@ -241,9 +248,11 @@ const nextServerlessLoader: loader.Loader = function () {
const params = ${
pageIsDynamicRoute
? `
trustQuery
? collectDynamicRouteParams(parsedUrl.query)
: dynamicRouteMatcher(parsedUrl.pathname)
normalizeDynamicRouteParams(
trustQuery
? parsedUrl.query
: dynamicRouteMatcher(parsedUrl.pathname)
)
`
: `{}`
}
Expand Down Expand Up @@ -316,7 +325,7 @@ const nextServerlessLoader: loader.Loader = function () {
${dynamicRouteMatcher}
${defaultRouteRegex}
${collectDynamicRouteParams}
${normalizeDynamicRouteParams}
${handleRewrites}
export const config = ComponentInfo['confi' + 'g'] || {}
Expand Down Expand Up @@ -394,9 +403,11 @@ const nextServerlessLoader: loader.Loader = function () {
!getStaticProps &&
!getServerSideProps
) ? {}
: trustQuery
? collectDynamicRouteParams(parsedUrl.query)
: dynamicRouteMatcher(parsedUrl.pathname) || {};
: normalizeDynamicRouteParams(
trustQuery
? parsedUrl.query
: dynamicRouteMatcher(parsedUrl.pathname)
)
`
: `const params = {};`
}
Expand Down Expand Up @@ -433,6 +444,7 @@ const nextServerlessLoader: loader.Loader = function () {
`
: `const nowParams = null;`
}
// make sure to set renderOpts to the correct params e.g. _params
// if provided from worker or params if we're parsing them here
renderOpts.params = _params || params
Expand Down
24 changes: 24 additions & 0 deletions test/integration/root-optional-revalidate/pages/[[...slug]].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export default function Home(props) {
return <pre id="props">{JSON.stringify(props)}</pre>
}

export async function getStaticPaths() {
return {
paths: [
{ params: { slug: false } },
{ params: { slug: ['a'] } },
{ params: { slug: ['hello', 'world'] } },
],
fallback: false,
}
}

export async function getStaticProps({ params }) {
return {
props: {
params,
random: Math.random(),
},
revalidate: 1,
}
}
27 changes: 27 additions & 0 deletions test/integration/root-optional-revalidate/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const path = require('path')
const http = require('http')

const server = http.createServer(async (req, res) => {
const render = async (page) => {
const mod = require(`./${path.join('.next/serverless/pages/', page)}`)
try {
return await (mod.render || mod.default || mod)(req, res)
} catch (err) {
res.statusCode = 500
return res.end('internal error')
}
}

try {
await render('/[[...slug]].js')
} catch (err) {
console.error('failed to render', err)
res.statusCode = 500
res.end('Internal Error')
}
})

const port = process.env.PORT || 3000
server.listen(port, () => {
console.log('ready on', port)
})
115 changes: 115 additions & 0 deletions test/integration/root-optional-revalidate/test/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/* eslint-env jest */

import { join } from 'path'
import cheerio from 'cheerio'
import {
killApp,
findPort,
File,
nextBuild,
nextStart,
initNextServerScript,
renderViaHTTP,
waitFor,
} from 'next-test-utils'

jest.setTimeout(1000 * 60 * 2)

const appDir = join(__dirname, '../')
const nextConfig = new File(join(appDir, 'next.config.js'))
let app
let appPort

const getProps = async (path, expected) => {
const html = await renderViaHTTP(appPort, path)
const $ = cheerio.load(html)
return JSON.parse($('#props').text())
}

const runTests = (rawServerless = false) => {
it('should render / correctly', async () => {
const props = await getProps('/', { params: {} })
expect(props.params).toEqual({})

await waitFor(1000)
await getProps('/')

const newProps = await getProps('/', { params: {} })
expect(newProps.params).toEqual({})
expect(props.random).not.toBe(newProps.random)
})

if (rawServerless) {
it('should render /index correctly', async () => {
const props = await getProps('/index')
expect(props.params).toEqual({})

await waitFor(1000)
await getProps('/index')

const newProps = await getProps('/index')
expect(newProps.params).toEqual({})
expect(props.random).not.toBe(newProps.random)
})
}

it('should render /a correctly', async () => {
const props = await getProps('/a')
expect(props.params).toEqual({ slug: ['a'] })

await waitFor(1000)
await getProps('/a')

const newProps = await getProps('/a')
expect(newProps.params).toEqual({ slug: ['a'] })
expect(props.random).not.toBe(newProps.random)
})

it('should render /hello/world correctly', async () => {
const props = await getProps('/hello/world')
expect(props.params).toEqual({ slug: ['hello', 'world'] })

await waitFor(1000)
await getProps('/hello/world')

const newProps = await getProps('/hello/world')
expect(newProps.params).toEqual({ slug: ['hello', 'world'] })
expect(props.random).not.toBe(newProps.random)
})
}

describe('Root Optional Catch-all Revalidate', () => {
describe('production mode', () => {
beforeAll(async () => {
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort)
})
afterAll(() => killApp(app))

runTests()
})

describe('raw serverless mode', () => {
beforeAll(async () => {
nextConfig.write(`
module.exports = {
target: 'experimental-serverless-trace'
}
`)
await nextBuild(appDir)
appPort = await findPort()

app = await initNextServerScript(join(appDir, 'server.js'), /ready on/i, {
...process.env,
PORT: appPort,
})
})
afterAll(async () => {
nextConfig.delete()
await killApp(app)
})

runTests(true)
})
})

0 comments on commit 2b07a8c

Please sign in to comment.