Skip to content

Commit

Permalink
Merge branch 'canary' into refactor/next-server
Browse files Browse the repository at this point in the history
  • Loading branch information
Timer committed Dec 10, 2019
2 parents fc7245c + 6c103ef commit fe4a2fd
Show file tree
Hide file tree
Showing 18 changed files with 280 additions and 21 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "9.1.5"
"version": "9.1.6-canary.0"
}
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "9.1.5",
"version": "9.1.6-canary.0",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-bundle-analyzer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
"version": "9.1.5",
"version": "9.1.6-canary.0",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-mdx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
"version": "9.1.5",
"version": "9.1.6-canary.0",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-google-analytics/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-google-analytics",
"version": "9.1.5",
"version": "9.1.6-canary.0",
"nextjs": {
"name": "Google Analytics",
"required-env": [
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-material-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-material-ui",
"version": "9.1.5",
"version": "9.1.6-canary.0",
"nextjs": {
"name": "Material UI",
"required-env": []
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-sentry/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-sentry",
"version": "9.1.5",
"version": "9.1.6-canary.0",
"nextjs": {
"name": "Sentry",
"required-env": [
Expand Down
3 changes: 3 additions & 0 deletions packages/next/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
} from './utils'
import getBaseWebpackConfig from './webpack-config'
import { writeBuildId } from './write-build-id'
import checkCustomRoutes from '../lib/check-custom-routes'

const fsAccess = promisify(fs.access)
const fsUnlink = promisify(fs.unlink)
Expand Down Expand Up @@ -102,9 +103,11 @@ export default async function build(dir: string, conf = null): Promise<void> {

if (typeof config.experimental.redirects === 'function') {
redirects.push(...(await config.experimental.redirects()))
checkCustomRoutes(redirects, 'redirect')
}
if (typeof config.experimental.rewrites === 'function') {
rewrites.push(...(await config.experimental.rewrites()))
checkCustomRoutes(rewrites, 'rewrite')
}

if (ciEnvironment.isCI) {
Expand Down
2 changes: 1 addition & 1 deletion packages/next/build/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import prettyBytes from '../lib/pretty-bytes'
import { recursiveReadDir } from '../lib/recursive-readdir'
import { getRouteMatcher, getRouteRegex } from '../next-server/lib/router/utils'
import { isDynamicRoute } from '../next-server/lib/router/utils/is-dynamic'
import { Redirect, Rewrite } from '../next-server/server/next-server'
import { Redirect, Rewrite } from '../lib/check-custom-routes'
import { DEFAULT_REDIRECT_STATUS } from '../next-server/lib/constants'

const fsStatPromise = promisify(fs.stat)
Expand Down
88 changes: 88 additions & 0 deletions packages/next/lib/check-custom-routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
export type Rewrite = {
source: string
destination: string
}

export type Redirect = Rewrite & {
statusCode?: number
}

const allowedStatusCodes = new Set([301, 302, 303, 307, 308])

export default function checkCustomRoutes(
routes: Array<Rewrite | Redirect>,
type: 'redirect' | 'rewrite'
): void {
let numInvalidRoutes = 0
let hadInvalidStatus = false
const isRedirect = type === 'redirect'
const allowedKeys = new Set([
'source',
'destination',
...(isRedirect ? ['statusCode'] : []),
])

for (const route of routes) {
const keys = Object.keys(route)
const invalidKeys = keys.filter(key => !allowedKeys.has(key))
const invalidParts = []

// TODO: investigate allowing RegExp directly
if (!route.source) {
invalidParts.push('`source` is missing')
} else if (typeof route.source !== 'string') {
invalidParts.push('`source` is not a string')
} else if (!route.source.startsWith('/')) {
invalidParts.push('`source` does not start with /')
}

if (!route.destination) {
invalidParts.push('`destination` is missing')
} else if (typeof route.destination !== 'string') {
invalidParts.push('`destination` is not a string')
} else if (!route.destination.startsWith('/')) {
invalidParts.push('`destination` does not start with /')
}

if (isRedirect) {
const redirRoute = route as Redirect

if (
redirRoute.statusCode &&
!allowedStatusCodes.has(redirRoute.statusCode)
) {
hadInvalidStatus = true
invalidParts.push(`\`statusCode\` is not undefined or valid statusCode`)
}
}

const hasInvalidKeys = invalidKeys.length > 0
const hasInvalidParts = invalidParts.length > 0

if (hasInvalidKeys || hasInvalidParts) {
console.error(
`${invalidParts.join(', ')}${
invalidKeys.length
? (hasInvalidParts ? ',' : '') +
` invalid field${invalidKeys.length === 1 ? '' : 's'}: ` +
invalidKeys.join(',')
: ''
} for route ${JSON.stringify(route)}`
)
numInvalidRoutes++
}
}

if (numInvalidRoutes > 0) {
if (hadInvalidStatus) {
console.error(
`\nValid redirect statusCode values are ${[...allowedStatusCodes].join(
', '
)}`
)
}
console.error()

throw new Error(`Invalid ${type}${numInvalidRoutes === 1 ? '' : 's'} found`)
}
}
10 changes: 1 addition & 9 deletions packages/next/next-server/server/next-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,12 @@ import { sendHTML } from './send-html'
import { serveStatic } from './serve-static'
import { getSprCache, initializeSprCache, setSprCache } from './spr-cache'
import { isBlockedPage } from './utils'
import { Redirect, Rewrite } from '../../lib/check-custom-routes'

const getCustomRouteMatcher = pathMatch(true)

type NextConfig = any

export type Rewrite = {
source: string
destination: string
}

export type Redirect = Rewrite & {
statusCode?: number
}

type Middleware = (
req: IncomingMessage,
res: ServerResponse,
Expand Down
2 changes: 1 addition & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next",
"version": "9.1.5",
"version": "9.1.6-canary.0",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/next/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
AppPropsType,
} from '../next-server/lib/utils'
import { Router } from '../client/router'
import '../client/router'

export { AppInitialProps }

Expand Down
3 changes: 3 additions & 0 deletions packages/next/server/next-dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { Telemetry } from '../telemetry/storage'
import ErrorDebug from './error-debug'
import HotReloader from './hot-reloader'
import { findPageFile } from './lib/find-page-file'
import checkCustomRoutes from '../lib/check-custom-routes'

if (typeof React.Suspense === 'undefined') {
throw new Error(
Expand Down Expand Up @@ -319,9 +320,11 @@ export default class DevServer extends Server {

if (typeof redirects === 'function') {
result.redirects = await redirects()
checkCustomRoutes(result.redirects, 'redirect')
}
if (typeof rewrites === 'function') {
result.rewrites = await rewrites()
checkCustomRoutes(result.rewrites, 'rewrite')
}
this.customRoutes = result
}
Expand Down
2 changes: 0 additions & 2 deletions test/integration/chunking/pages/page2.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useState, useEffect } from 'react'
import _ from 'lodash'
import dynamic from 'next/dynamic'
import Link from 'next/link'

const One = dynamic(() => import('../components/one'))

Expand All @@ -17,7 +16,6 @@ const Page = () => {
page2
<p id="padded-str">{str}</p>
<One />
<Link href="/page3">Page3</Link>
</div>
)
}
Expand Down
1 change: 1 addition & 0 deletions test/integration/invalid-custom-routes/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => 'hi'
Loading

0 comments on commit fe4a2fd

Please sign in to comment.