2022-08-07 21:16:10 +02:00
|
|
|
import { isServerRuntime } from '../../server/config-shared'
|
2022-05-20 14:24:00 +02:00
|
|
|
import type { NextConfig } from '../../server/config-shared'
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
import type { Middleware, RouteHas } from '../../lib/load-custom-routes'
|
2022-07-21 21:56:52 +02:00
|
|
|
import {
|
|
|
|
extractExportedConstValue,
|
|
|
|
UnsupportedValueError,
|
|
|
|
} from './extract-const-value'
|
2022-05-20 14:24:00 +02:00
|
|
|
import { parseModule } from './parse-module'
|
|
|
|
import { promises as fs } from 'fs'
|
2022-06-03 18:35:44 +02:00
|
|
|
import { tryToParsePath } from '../../lib/try-to-parse-path'
|
2022-06-13 20:17:44 +02:00
|
|
|
import * as Log from '../output/log'
|
2022-06-27 03:02:24 +02:00
|
|
|
import { SERVER_RUNTIME } from '../../lib/constants'
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
import { ServerRuntime } from 'next/types'
|
|
|
|
import { checkCustomRoutes } from '../../lib/load-custom-routes'
|
2022-06-03 18:35:44 +02:00
|
|
|
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
export interface MiddlewareConfig {
|
|
|
|
matchers: MiddlewareMatcher[]
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface MiddlewareMatcher {
|
|
|
|
regexp: string
|
|
|
|
locale?: false
|
|
|
|
has?: RouteHas[]
|
2022-06-03 18:35:44 +02:00
|
|
|
}
|
2022-05-20 14:24:00 +02:00
|
|
|
|
|
|
|
export interface PageStaticInfo {
|
2022-06-27 03:02:24 +02:00
|
|
|
runtime?: ServerRuntime
|
2022-05-20 14:24:00 +02:00
|
|
|
ssg?: boolean
|
|
|
|
ssr?: boolean
|
2022-06-03 18:35:44 +02:00
|
|
|
middleware?: Partial<MiddlewareConfig>
|
2022-05-20 14:24:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Receives a parsed AST from SWC and checks if it belongs to a module that
|
|
|
|
* requires a runtime to be specified. Those are:
|
|
|
|
* - Modules with `export function getStaticProps | getServerSideProps`
|
|
|
|
* - Modules with `export { getStaticProps | getServerSideProps } <from ...>`
|
|
|
|
*/
|
2022-08-29 16:47:06 +02:00
|
|
|
export function checkExports(swcAST: any): { ssr: boolean; ssg: boolean } {
|
2022-05-20 14:24:00 +02:00
|
|
|
if (Array.isArray(swcAST?.body)) {
|
|
|
|
try {
|
|
|
|
for (const node of swcAST.body) {
|
|
|
|
if (
|
|
|
|
node.type === 'ExportDeclaration' &&
|
|
|
|
node.declaration?.type === 'FunctionDeclaration' &&
|
|
|
|
['getStaticProps', 'getServerSideProps'].includes(
|
|
|
|
node.declaration.identifier?.value
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
return {
|
|
|
|
ssg: node.declaration.identifier.value === 'getStaticProps',
|
|
|
|
ssr: node.declaration.identifier.value === 'getServerSideProps',
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (node.type === 'ExportNamedDeclaration') {
|
|
|
|
const values = node.specifiers.map(
|
|
|
|
(specifier: any) =>
|
|
|
|
specifier.type === 'ExportSpecifier' &&
|
|
|
|
specifier.orig?.type === 'Identifier' &&
|
|
|
|
specifier.orig?.value
|
|
|
|
)
|
|
|
|
|
|
|
|
return {
|
|
|
|
ssg: values.some((value: any) =>
|
|
|
|
['getStaticProps'].includes(value)
|
|
|
|
),
|
|
|
|
ssr: values.some((value: any) =>
|
|
|
|
['getServerSideProps'].includes(value)
|
|
|
|
),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (err) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
return { ssg: false, ssr: false }
|
|
|
|
}
|
|
|
|
|
|
|
|
async function tryToReadFile(filePath: string, shouldThrow: boolean) {
|
|
|
|
try {
|
|
|
|
return await fs.readFile(filePath, {
|
|
|
|
encoding: 'utf8',
|
|
|
|
})
|
|
|
|
} catch (error) {
|
|
|
|
if (shouldThrow) {
|
|
|
|
throw error
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-06-03 18:35:44 +02:00
|
|
|
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
function getMiddlewareMatchers(
|
2022-06-21 00:34:03 +02:00
|
|
|
matcherOrMatchers: unknown,
|
|
|
|
nextConfig: NextConfig
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
): MiddlewareMatcher[] {
|
|
|
|
let matchers: unknown[] = []
|
2022-06-03 18:35:44 +02:00
|
|
|
if (Array.isArray(matcherOrMatchers)) {
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
matchers = matcherOrMatchers
|
|
|
|
} else {
|
|
|
|
matchers.push(matcherOrMatchers)
|
2022-06-03 18:35:44 +02:00
|
|
|
}
|
2022-08-10 00:58:40 +02:00
|
|
|
const { i18n } = nextConfig
|
2022-06-03 18:35:44 +02:00
|
|
|
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
let routes = matchers.map(
|
|
|
|
(m) => (typeof m === 'string' ? { source: m } : m) as Middleware
|
|
|
|
)
|
2022-06-03 18:35:44 +02:00
|
|
|
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
// check before we process the routes and after to ensure
|
|
|
|
// they are still valid
|
|
|
|
checkCustomRoutes(routes, 'middleware')
|
2022-06-03 18:35:44 +02:00
|
|
|
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
routes = routes.map((r) => {
|
|
|
|
let { source } = r
|
2022-06-03 18:35:44 +02:00
|
|
|
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
const isRoot = source === '/'
|
2022-06-21 00:34:03 +02:00
|
|
|
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
if (i18n?.locales && r.locale !== false) {
|
|
|
|
source = `/:nextInternalLocale([^/.]{1,})${isRoot ? '' : source}`
|
|
|
|
}
|
2022-08-10 00:58:40 +02:00
|
|
|
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
source = `/:nextData(_next/data/[^/]{1,})?${source}${
|
|
|
|
isRoot
|
|
|
|
? `(${nextConfig.i18n ? '|\\.json|' : ''}/?index|/?index\\.json)?`
|
|
|
|
: '(.json)?'
|
|
|
|
}`
|
2022-08-10 00:58:40 +02:00
|
|
|
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
if (nextConfig.basePath) {
|
|
|
|
source = `${nextConfig.basePath}${source}`
|
|
|
|
}
|
2022-06-03 18:35:44 +02:00
|
|
|
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
return { ...r, source }
|
|
|
|
})
|
|
|
|
|
|
|
|
checkCustomRoutes(routes, 'middleware')
|
|
|
|
|
|
|
|
return routes.map((r) => {
|
|
|
|
const { source, ...rest } = r
|
|
|
|
const parsedPage = tryToParsePath(source)
|
|
|
|
|
|
|
|
if (parsedPage.error || !parsedPage.regexStr) {
|
|
|
|
throw new Error(`Invalid source: ${source}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
...rest,
|
|
|
|
regexp: parsedPage.regexStr,
|
|
|
|
}
|
|
|
|
})
|
2022-06-03 18:35:44 +02:00
|
|
|
}
|
2022-06-13 20:17:44 +02:00
|
|
|
|
2022-08-15 16:29:51 +02:00
|
|
|
function getMiddlewareConfig(
|
|
|
|
config: any,
|
|
|
|
nextConfig: NextConfig
|
|
|
|
): Partial<MiddlewareConfig> {
|
|
|
|
const result: Partial<MiddlewareConfig> = {}
|
|
|
|
|
|
|
|
if (config.matcher) {
|
feat(next): Support has match and locale option on middleware config (#39257)
## Feature
As the title, support `has` match, `local` that works the same with the `rewrites` and `redirects` of next.config.js on middleware config. With this PR, you can write the config like the following:
```js
export const config = {
matcher: [
"/foo",
{ source: "/bar" },
{
source: "/baz",
has: [
{
type: 'header',
key: 'x-my-header',
value: 'my-value',
}
]
},
{
source: "/en/asdf",
locale: false,
},
]
}
```
Also, fixes https://github.com/vercel/next.js/issues/39428
related https://github.com/vercel/edge-functions/issues/178, https://github.com/vercel/edge-functions/issues/179
- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-08-31 18:23:30 +02:00
|
|
|
result.matchers = getMiddlewareMatchers(config.matcher, nextConfig)
|
2022-08-15 16:29:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2022-08-11 23:32:52 +02:00
|
|
|
let warnedAboutExperimentalEdgeApiFunctions = false
|
2022-06-13 20:17:44 +02:00
|
|
|
function warnAboutExperimentalEdgeApiFunctions() {
|
|
|
|
if (warnedAboutExperimentalEdgeApiFunctions) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
Log.warn(`You are using an experimental edge runtime, the API might change.`)
|
|
|
|
warnedAboutExperimentalEdgeApiFunctions = true
|
|
|
|
}
|
|
|
|
|
2022-07-21 21:56:52 +02:00
|
|
|
const warnedUnsupportedValueMap = new Map<string, boolean>()
|
|
|
|
function warnAboutUnsupportedValue(
|
|
|
|
pageFilePath: string,
|
2022-07-22 21:31:47 +02:00
|
|
|
page: string | undefined,
|
|
|
|
error: UnsupportedValueError
|
2022-07-21 21:56:52 +02:00
|
|
|
) {
|
|
|
|
if (warnedUnsupportedValueMap.has(pageFilePath)) {
|
|
|
|
return
|
|
|
|
}
|
2022-07-22 21:31:47 +02:00
|
|
|
|
2022-07-21 21:56:52 +02:00
|
|
|
Log.warn(
|
2022-07-22 21:31:47 +02:00
|
|
|
`Next.js can't recognize the exported \`config\` field in ` +
|
|
|
|
(page ? `route "${page}"` : `"${pageFilePath}"`) +
|
|
|
|
':\n' +
|
|
|
|
error.message +
|
|
|
|
(error.path ? ` at "${error.path}"` : '') +
|
|
|
|
'.\n' +
|
|
|
|
'The default config will be used instead.\n' +
|
|
|
|
'Read More - https://nextjs.org/docs/messages/invalid-page-config'
|
2022-07-21 21:56:52 +02:00
|
|
|
)
|
2022-07-22 21:31:47 +02:00
|
|
|
|
2022-07-21 21:56:52 +02:00
|
|
|
warnedUnsupportedValueMap.set(pageFilePath, true)
|
|
|
|
}
|
2022-08-15 16:29:51 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* For a given pageFilePath and nextConfig, if the config supports it, this
|
|
|
|
* function will read the file and return the runtime that should be used.
|
|
|
|
* It will look into the file content only if the page *requires* a runtime
|
|
|
|
* to be specified, that is, when gSSP or gSP is used.
|
|
|
|
* Related discussion: https://github.com/vercel/next.js/discussions/34179
|
|
|
|
*/
|
|
|
|
export async function getPageStaticInfo(params: {
|
|
|
|
nextConfig: Partial<NextConfig>
|
|
|
|
pageFilePath: string
|
|
|
|
isDev?: boolean
|
|
|
|
page?: string
|
|
|
|
}): Promise<PageStaticInfo> {
|
|
|
|
const { isDev, pageFilePath, nextConfig, page } = params
|
|
|
|
|
|
|
|
const fileContent = (await tryToReadFile(pageFilePath, !isDev)) || ''
|
|
|
|
if (/runtime|getStaticProps|getServerSideProps|matcher/.test(fileContent)) {
|
|
|
|
const swcAST = await parseModule(pageFilePath, fileContent)
|
|
|
|
const { ssg, ssr } = checkExports(swcAST)
|
|
|
|
|
|
|
|
// default / failsafe value for config
|
|
|
|
let config: any = {}
|
|
|
|
try {
|
|
|
|
config = extractExportedConstValue(swcAST, 'config')
|
|
|
|
} catch (e) {
|
|
|
|
if (e instanceof UnsupportedValueError) {
|
|
|
|
warnAboutUnsupportedValue(pageFilePath, page, e)
|
|
|
|
}
|
|
|
|
// `export config` doesn't exist, or other unknown error throw by swc, silence them
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
typeof config.runtime !== 'string' &&
|
|
|
|
typeof config.runtime !== 'undefined'
|
|
|
|
) {
|
|
|
|
throw new Error(`Provided runtime `)
|
|
|
|
} else if (!isServerRuntime(config.runtime)) {
|
|
|
|
const options = Object.values(SERVER_RUNTIME).join(', ')
|
|
|
|
if (typeof config.runtime !== 'string') {
|
|
|
|
throw new Error(
|
|
|
|
`The \`runtime\` config must be a string. Please leave it empty or choose one of: ${options}`
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
throw new Error(
|
|
|
|
`Provided runtime "${config.runtime}" is not supported. Please leave it empty or choose one of: ${options}`
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let runtime =
|
|
|
|
SERVER_RUNTIME.edge === config?.runtime
|
|
|
|
? SERVER_RUNTIME.edge
|
|
|
|
: ssr || ssg
|
|
|
|
? config?.runtime || nextConfig.experimental?.runtime
|
|
|
|
: undefined
|
|
|
|
|
|
|
|
if (runtime === SERVER_RUNTIME.edge) {
|
|
|
|
warnAboutExperimentalEdgeApiFunctions()
|
|
|
|
}
|
|
|
|
|
|
|
|
const middlewareConfig = getMiddlewareConfig(config, nextConfig)
|
|
|
|
|
|
|
|
return {
|
|
|
|
ssr,
|
|
|
|
ssg,
|
|
|
|
...(middlewareConfig && { middleware: middlewareConfig }),
|
|
|
|
...(runtime && { runtime }),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-24 21:49:47 +02:00
|
|
|
return { ssr: false, ssg: false, runtime: nextConfig.experimental?.runtime }
|
2022-08-15 16:29:51 +02:00
|
|
|
}
|