feat(blog): add file-based blog with dynamic slugs, MDX content and layout shell

- Introduced blog routing using Next.js App Router
- Implemented dynamic [slug] pages for blog posts
- Added MDX-based content loading via lib/posts
- Integrated shared TopBar layout with navigation
- Established clear content, lib and component separation
This commit is contained in:
PascalSchattenburg
2026-01-22 14:14:15 +01:00
parent b717952234
commit d147843c76
10412 changed files with 2475583 additions and 0 deletions

49
apps/public-web/node_modules/next/README.md generated vendored Normal file
View File

@@ -0,0 +1,49 @@
<div align="center">
<a href="https://nextjs.org">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://assets.vercel.com/image/upload/v1662130559/nextjs/Icon_dark_background.png">
<img alt="Next.js logo" src="https://assets.vercel.com/image/upload/v1662130559/nextjs/Icon_light_background.png" height="128">
</picture>
</a>
<h1>Next.js</h1>
<a href="https://vercel.com"><img alt="Vercel logo" src="https://img.shields.io/badge/MADE%20BY%20Vercel-000000.svg?style=for-the-badge&logo=Vercel&labelColor=000"></a>
<a href="https://www.npmjs.com/package/next"><img alt="NPM version" src="https://img.shields.io/npm/v/next.svg?style=for-the-badge&labelColor=000000"></a>
<a href="https://github.com/vercel/next.js/blob/canary/license.md"><img alt="License" src="https://img.shields.io/npm/l/next.svg?style=for-the-badge&labelColor=000000"></a>
<a href="https://github.com/vercel/next.js/discussions"><img alt="Join the community on GitHub" src="https://img.shields.io/badge/Join%20the%20community-blueviolet.svg?style=for-the-badge&logo=Next.js&labelColor=000000&logoWidth=20"></a>
</div>
## Getting Started
Used by some of the world's largest companies, Next.js enables you to create full-stack web applications by extending the latest React features, and integrating powerful Rust-based JavaScript tooling for the fastest builds.
- Visit our [Learn Next.js](https://nextjs.org/learn) course to get started with Next.js.
- Visit the [Next.js Showcase](https://nextjs.org/showcase) to see more sites built with Next.js.
## Documentation
Visit [https://nextjs.org/docs](https://nextjs.org/docs) to view the full documentation.
## Community
The Next.js community can be found on [GitHub Discussions](https://github.com/vercel/next.js/discussions) where you can ask questions, voice ideas, and share your projects with other people.
To chat with other community members you can join the Next.js [Discord](https://nextjs.org/discord) server.
Do note that our [Code of Conduct](https://github.com/vercel/next.js/blob/canary/CODE_OF_CONDUCT.md) applies to all Next.js community channels. Users are **highly encouraged** to read and adhere to it to avoid repercussions.
## Contributing
Contributions to Next.js are welcome and highly appreciated. However, before you jump right into it, we would like you to review our [Contribution Guidelines](/contributing.md) to make sure you have a smooth experience contributing to Next.js.
### Good First Issues:
We have a list of **[good first issues](https://github.com/vercel/next.js/labels/good%20first%20issue)** that contain bugs that have a relatively limited scope. This is a great place for newcomers and beginners alike to get started, gain experience, and get familiar with our contribution process.
---
## Security
If you believe you have found a security vulnerability in Next.js, we encourage you to **_responsibly disclose this and NOT open a public issue_**.
To participate in our Open Source Software Bug Bounty program, please email [responsible.disclosure@vercel.com](mailto:responsible.disclosure@vercel.com). We will add you to the program and provide further instructions for submitting your report.

3
apps/public-web/node_modules/next/app.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import App from './dist/pages/_app'
export * from './dist/pages/_app'
export default App

1
apps/public-web/node_modules/next/app.js generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('./dist/pages/_app')

1
apps/public-web/node_modules/next/babel.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export * from './dist/build/babel/preset'

1
apps/public-web/node_modules/next/babel.js generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('./dist/build/babel/preset')

154
apps/public-web/node_modules/next/cache.d.ts generated vendored Normal file
View File

@@ -0,0 +1,154 @@
export { unstable_cache } from 'next/dist/server/web/spec-extension/unstable-cache'
export {
revalidatePath,
revalidateTag,
updateTag,
refresh,
} from 'next/dist/server/web/spec-extension/revalidate'
export { unstable_noStore } from 'next/dist/server/web/spec-extension/unstable-no-store'
import { cacheTag } from 'next/dist/server/use-cache/cache-tag'
export { cacheTag }
/**
* Cache this `"use cache"` for a timespan defined by the `"default"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 900 seconds (15 minutes)
* expire: never
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 15 minutes, start revalidating new values in the background.
* It lives for the maximum age of the server cache. If this entry has no traffic for a while, it may serve an old value the next request.
*/
export function cacheLife(profile: 'default'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"seconds"` profile.
* ```
* stale: 30 seconds
* revalidate: 1 second
* expire: 1 minute
* ```
*
* This cache may be stale on clients for 30 seconds before checking with the server.
* If the server receives a new request after 1 second, start revalidating new values in the background.
* If this entry has no traffic for 1 minute it will expire. The next request will recompute it.
*/
export function cacheLife(profile: 'seconds'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"minutes"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 60 seconds (1 minute)
* expire: 3600 seconds (1 hour)
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 1 minute, start revalidating new values in the background.
* If this entry has no traffic for 1 hour it will expire. The next request will recompute it.
*/
export function cacheLife(profile: 'minutes'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"hours"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 3600 seconds (1 hour)
* expire: 86400 seconds (1 day)
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 1 hour, start revalidating new values in the background.
* If this entry has no traffic for 1 day it will expire. The next request will recompute it.
*/
export function cacheLife(profile: 'hours'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"days"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 86400 seconds (1 day)
* expire: 604800 seconds (1 week)
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 1 day, start revalidating new values in the background.
* If this entry has no traffic for 1 week it will expire. The next request will recompute it.
*/
export function cacheLife(profile: 'days'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"weeks"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 604800 seconds (1 week)
* expire: 2592000 seconds (30 days)
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 1 week, start revalidating new values in the background.
* If this entry has no traffic for 30 days it will expire. The next request will recompute it.
*/
export function cacheLife(profile: 'weeks'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"max"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 2592000 seconds (30 days)
* expire: never
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 30 days, start revalidating new values in the background.
* It lives for the maximum age of the server cache. If this entry has no traffic for a while, it may serve an old value the next request.
*/
export function cacheLife(profile: 'max'): void
/**
* Cache this `"use cache"` using a custom profile "...".
* ```
* stale: ... // seconds
* revalidate: ... // seconds
* expire: ... // seconds
* ```
*
* You can define custom profiles in `next.config.ts`.
*/
export function cacheLife(profile: string): void
/**
* Cache this `"use cache"` using a custom timespan.
* ```
* stale: ... // seconds
* revalidate: ... // seconds
* expire: ... // seconds
* ```
*
* This is similar to Cache-Control: max-age=`stale`,s-max-age=`revalidate`,stale-while-revalidate=`expire-revalidate`
*
* If a value is left out, the lowest of other cacheLife() calls or the default, is used instead.
*/
export function cacheLife(profile: {
/**
* This cache may be stale on clients for ... seconds before checking with the server.
*/
stale?: number
/**
* If the server receives a new request after ... seconds, start revalidating new values in the background.
*/
revalidate?: number
/**
* If this entry has no traffic for ... seconds it will expire. The next request will recompute it.
*/
expire?: number
}): void
export const unstable_cacheLife: typeof cacheLife
export const unstable_cacheTag: typeof cacheTag

63
apps/public-web/node_modules/next/cache.js generated vendored Normal file
View File

@@ -0,0 +1,63 @@
const cacheExports = {
unstable_cache: require('next/dist/server/web/spec-extension/unstable-cache')
.unstable_cache,
updateTag: require('next/dist/server/web/spec-extension/revalidate')
.updateTag,
revalidateTag: require('next/dist/server/web/spec-extension/revalidate')
.revalidateTag,
revalidatePath: require('next/dist/server/web/spec-extension/revalidate')
.revalidatePath,
refresh: require('next/dist/server/web/spec-extension/revalidate').refresh,
unstable_noStore:
require('next/dist/server/web/spec-extension/unstable-no-store')
.unstable_noStore,
cacheLife: require('next/dist/server/use-cache/cache-life').cacheLife,
cacheTag: require('next/dist/server/use-cache/cache-tag').cacheTag,
}
let didWarnCacheLife = false
function unstable_cacheLife() {
if (!didWarnCacheLife) {
didWarnCacheLife = true
const error = new Error(
'`unstable_cacheLife` was recently stabilized and should be imported as `cacheLife`. The `unstable` prefixed form will be removed in a future version of Next.js.'
)
console.error(error)
}
return cacheExports.cacheLife.apply(this, arguments)
}
let didWarnCacheTag = false
function unstable_cacheTag() {
if (!didWarnCacheTag) {
didWarnCacheTag = true
const error = new Error(
'`unstable_cacheTag` was recently stabilized and should be imported as `cacheTag`. The `unstable` prefixed form will be removed in a future version of Next.js.'
)
console.error(error)
}
return cacheExports.cacheTag.apply(this, arguments)
}
cacheExports.unstable_cacheLife = unstable_cacheLife
cacheExports.unstable_cacheTag = unstable_cacheTag
// https://nodejs.org/api/esm.html#commonjs-namespaces
// When importing CommonJS modules, the module.exports object is provided as the default export
module.exports = cacheExports
// make import { xxx } from 'next/cache' work
exports.unstable_cache = cacheExports.unstable_cache
exports.revalidatePath = cacheExports.revalidatePath
exports.revalidateTag = cacheExports.revalidateTag
exports.updateTag = cacheExports.updateTag
exports.unstable_noStore = cacheExports.unstable_noStore
exports.cacheLife = cacheExports.cacheLife
exports.unstable_cacheLife = cacheExports.unstable_cacheLife
exports.cacheTag = cacheExports.cacheTag
exports.unstable_cacheTag = cacheExports.unstable_cacheTag
exports.refresh = cacheExports.refresh

1
apps/public-web/node_modules/next/client.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export * from './dist/client/index'

1
apps/public-web/node_modules/next/client.js generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('./dist/client/index')

1
apps/public-web/node_modules/next/compat/router.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export * from '../dist/client/compat/router'

1
apps/public-web/node_modules/next/compat/router.js generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('../dist/client/compat/router')

1
apps/public-web/node_modules/next/constants.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export * from './dist/shared/lib/constants'

1
apps/public-web/node_modules/next/constants.js generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('./dist/shared/lib/constants')

View File

@@ -0,0 +1,2 @@
export * from '../shared/lib/app-dynamic';
export { default } from '../shared/lib/app-dynamic';

View File

@@ -0,0 +1,4 @@
export * from '../shared/lib/app-dynamic';
export { default } from '../shared/lib/app-dynamic';
//# sourceMappingURL=app-dynamic.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/app-dynamic.ts"],"sourcesContent":["export * from '../shared/lib/app-dynamic'\nexport { default } from '../shared/lib/app-dynamic'\n"],"names":["default"],"mappings":"AAAA,cAAc,4BAA2B;AACzC,SAASA,OAAO,QAAQ,4BAA2B","ignoreList":[0]}

2
apps/public-web/node_modules/next/dist/api/app.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
export * from '../pages/_app';
export { default } from '../pages/_app';

4
apps/public-web/node_modules/next/dist/api/app.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export * from '../pages/_app';
export { default } from '../pages/_app';
//# sourceMappingURL=app.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/app.tsx"],"sourcesContent":["export * from '../pages/_app'\nexport { default } from '../pages/_app'\n"],"names":["default"],"mappings":"AAAA,cAAc,gBAAe;AAC7B,SAASA,OAAO,QAAQ,gBAAe","ignoreList":[0]}

View File

@@ -0,0 +1 @@
export * from '../shared/lib/constants';

View File

@@ -0,0 +1,3 @@
export * from '../shared/lib/constants';
//# sourceMappingURL=constants.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/constants.ts"],"sourcesContent":["export * from '../shared/lib/constants'\n"],"names":[],"mappings":"AAAA,cAAc,0BAAyB","ignoreList":[0]}

View File

@@ -0,0 +1,2 @@
export * from '../pages/_document';
export { default } from '../pages/_document';

View File

@@ -0,0 +1,4 @@
export * from '../pages/_document';
export { default } from '../pages/_document';
//# sourceMappingURL=document.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/document.tsx"],"sourcesContent":["export * from '../pages/_document'\nexport { default } from '../pages/_document'\n"],"names":["default"],"mappings":"AAAA,cAAc,qBAAoB;AAClC,SAASA,OAAO,QAAQ,qBAAoB","ignoreList":[0]}

View File

@@ -0,0 +1,2 @@
export { default } from '../shared/lib/dynamic';
export * from '../shared/lib/dynamic';

View File

@@ -0,0 +1,4 @@
export { default } from '../shared/lib/dynamic';
export * from '../shared/lib/dynamic';
//# sourceMappingURL=dynamic.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/dynamic.ts"],"sourcesContent":["export { default } from '../shared/lib/dynamic'\nexport * from '../shared/lib/dynamic'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,wBAAuB;AAC/C,cAAc,wBAAuB","ignoreList":[0]}

2
apps/public-web/node_modules/next/dist/api/form.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
export { default } from '../client/form';
export * from '../client/form';

4
apps/public-web/node_modules/next/dist/api/form.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export { default } from '../client/form';
export * from '../client/form';
//# sourceMappingURL=form.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/form.ts"],"sourcesContent":["export { default } from '../client/form'\nexport * from '../client/form'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,iBAAgB;AACxC,cAAc,iBAAgB","ignoreList":[0]}

2
apps/public-web/node_modules/next/dist/api/head.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
export { default } from '../shared/lib/head';
export * from '../shared/lib/head';

4
apps/public-web/node_modules/next/dist/api/head.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export { default } from '../shared/lib/head';
export * from '../shared/lib/head';
//# sourceMappingURL=head.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/head.ts"],"sourcesContent":["export { default } from '../shared/lib/head'\nexport * from '../shared/lib/head'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,qBAAoB;AAC5C,cAAc,qBAAoB","ignoreList":[0]}

View File

@@ -0,0 +1,3 @@
export * from '../server/request/cookies';
export * from '../server/request/headers';
export * from '../server/request/draft-mode';

View File

@@ -0,0 +1,5 @@
export * from '../server/request/cookies';
export * from '../server/request/headers';
export * from '../server/request/draft-mode';
//# sourceMappingURL=headers.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/headers.ts"],"sourcesContent":["export * from '../server/request/cookies'\nexport * from '../server/request/headers'\nexport * from '../server/request/draft-mode'\n"],"names":[],"mappings":"AAAA,cAAc,4BAA2B;AACzC,cAAc,4BAA2B;AACzC,cAAc,+BAA8B","ignoreList":[0]}

View File

@@ -0,0 +1,2 @@
export { default } from '../shared/lib/image-external';
export * from '../shared/lib/image-external';

4
apps/public-web/node_modules/next/dist/api/image.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export { default } from '../shared/lib/image-external';
export * from '../shared/lib/image-external';
//# sourceMappingURL=image.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/image.ts"],"sourcesContent":["export { default } from '../shared/lib/image-external'\nexport * from '../shared/lib/image-external'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,+BAA8B;AACtD,cAAc,+BAA8B","ignoreList":[0]}

2
apps/public-web/node_modules/next/dist/api/link.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
export { default } from '../client/link';
export * from '../client/link';

4
apps/public-web/node_modules/next/dist/api/link.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export { default } from '../client/link';
export * from '../client/link';
//# sourceMappingURL=link.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/link.ts"],"sourcesContent":["export { default } from '../client/link'\nexport * from '../client/link'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,iBAAgB;AACxC,cAAc,iBAAgB","ignoreList":[0]}

View File

@@ -0,0 +1 @@
export * from '../client/components/navigation';

View File

@@ -0,0 +1,3 @@
export * from '../client/components/navigation';
//# sourceMappingURL=navigation.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/navigation.ts"],"sourcesContent":["export * from '../client/components/navigation'\n"],"names":[],"mappings":"AAAA,cAAc,kCAAiC","ignoreList":[0]}

View File

@@ -0,0 +1 @@
export * from '../client/components/navigation.react-server';

View File

@@ -0,0 +1,3 @@
export * from '../client/components/navigation.react-server';
//# sourceMappingURL=navigation.react-server.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/navigation.react-server.ts"],"sourcesContent":["export * from '../client/components/navigation.react-server'\n"],"names":[],"mappings":"AAAA,cAAc,+CAA8C","ignoreList":[0]}

1
apps/public-web/node_modules/next/dist/api/og.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export * from '../server/og/image-response';

3
apps/public-web/node_modules/next/dist/api/og.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export * from '../server/og/image-response';
//# sourceMappingURL=og.js.map

1
apps/public-web/node_modules/next/dist/api/og.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/og.ts"],"sourcesContent":["export * from '../server/og/image-response'\n"],"names":[],"mappings":"AAAA,cAAc,8BAA6B","ignoreList":[0]}

View File

@@ -0,0 +1,2 @@
export { default } from '../client/router';
export * from '../client/router';

4
apps/public-web/node_modules/next/dist/api/router.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export { default } from '../client/router';
export * from '../client/router';
//# sourceMappingURL=router.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/router.ts"],"sourcesContent":["export { default } from '../client/router'\nexport * from '../client/router'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,mBAAkB;AAC1C,cAAc,mBAAkB","ignoreList":[0]}

View File

@@ -0,0 +1,2 @@
export { default } from '../client/script';
export * from '../client/script';

4
apps/public-web/node_modules/next/dist/api/script.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export { default } from '../client/script';
export * from '../client/script';
//# sourceMappingURL=script.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/script.ts"],"sourcesContent":["export { default } from '../client/script'\nexport * from '../client/script'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,mBAAkB;AAC1C,cAAc,mBAAkB","ignoreList":[0]}

View File

@@ -0,0 +1 @@
export * from '../server/web/exports/index';

3
apps/public-web/node_modules/next/dist/api/server.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export * from '../server/web/exports/index';
//# sourceMappingURL=server.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/server.ts"],"sourcesContent":["export * from '../server/web/exports/index'\n"],"names":[],"mappings":"AAAA,cAAc,8BAA6B","ignoreList":[0]}

155
apps/public-web/node_modules/next/dist/bin/next generated vendored Executable file
View File

@@ -0,0 +1,155 @@
#!/usr/bin/env node
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
require("../server/require-hook");
const _commander = require("next/dist/compiled/commander");
const _log = require("../build/output/log");
const _semver = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/semver"));
const _picocolors = require("../lib/picocolors");
const _formatclihelpoutput = require("../lib/format-cli-help-output");
const _constants = require("../lib/constants");
const _utils = require("../server/lib/utils");
const _nexttest = require("../cli/next-test.js");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
if (process.env.NEXT_RSPACK) {
// silent rspack's schema check
process.env.RSPACK_CONFIG_VALIDATE = 'loose-silent';
}
if (!_semver.default.satisfies(process.versions.node, ">=20.9.0", {
includePrerelease: true
})) {
console.error(`You are using Node.js ${process.versions.node}. For Next.js, Node.js version "${">=20.9.0"}" is required.`);
process.exit(1);
}
// Start performance profiling after Node.js version is checked
performance.mark('next-start');
for (const dependency of [
'react',
'react-dom'
]){
try {
// When 'npm link' is used it checks the clone location. Not the project.
require.resolve(dependency);
} catch (err) {
console.warn(`The module '${dependency}' was not found. Next.js requires that you include it in 'dependencies' of your 'package.json'. To add it, run 'npm install ${dependency}'`);
}
}
class NextRootCommand extends _commander.Command {
createCommand(name) {
const command = new _commander.Command(name);
command.hook('preAction', (event)=>{
const commandName = event.name();
const defaultEnv = commandName === 'dev' ? 'development' : 'production';
const standardEnv = [
'production',
'development',
'test'
];
if (process.env.NODE_ENV) {
const isNotStandard = !standardEnv.includes(process.env.NODE_ENV);
const shouldWarnCommands = process.env.NODE_ENV === 'development' ? [
'start',
'build'
] : process.env.NODE_ENV === 'production' ? [
'dev'
] : [];
if (isNotStandard || shouldWarnCommands.includes(commandName)) {
(0, _log.warn)(_constants.NON_STANDARD_NODE_ENV);
}
}
;
process.env.NODE_ENV = process.env.NODE_ENV || defaultEnv;
process.env.NEXT_RUNTIME = 'nodejs';
if (commandName !== 'dev' && event.getOptionValue('inspect') === true) {
console.error(`\`--inspect\` flag is deprecated. Use env variable NODE_OPTIONS instead: NODE_OPTIONS='--inspect' next ${commandName}`);
process.exit(1);
}
});
return command;
}
}
function parseValidInspectAddress(value) {
const address = (0, _utils.getParsedDebugAddress)(value);
if (Number.isNaN(address.port)) {
throw new _commander.InvalidArgumentError('The given value is not a valid inspect address. ' + 'Did you mean to pass an app path?\n' + `Try switching the order of the arguments or set the default address explicitly e.g.\n` + `next dev ${value} --inspect\n` + `next dev --inspect= ${value}`);
}
return address;
}
const program = new NextRootCommand();
program.name('next').description('The Next.js CLI allows you to develop, build, start your application, and more.').configureHelp({
formatHelp: (cmd, helper)=>(0, _formatclihelpoutput.formatCliHelpOutput)(cmd, helper),
subcommandTerm: (cmd)=>`${cmd.name()} ${cmd.usage()}`
}).helpCommand(false).helpOption('-h, --help', 'Displays this message.').version(`Next.js v${"16.1.4"}`, '-v, --version', 'Outputs the Next.js version.');
program.command('build').description('Creates an optimized production build of your application. The output displays information about each route.').argument('[directory]', `A directory on which to build the application. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).option('--experimental-analyze', 'Analyze bundle output. Only compatible with Turbopack.').option('-d, --debug', 'Enables a more verbose build output.').option('--debug-prerender', 'Enables debug mode for prerendering. Not for production use!').option('--no-mangling', 'Disables mangling.').option('--profile', 'Enables production profiling for React.').option('--experimental-app-only', 'Builds only App Router routes.').option('--turbo', 'Builds using Turbopack.').option('--turbopack', 'Builds using Turbopack.').option('--webpack', 'Builds using webpack.').addOption(new _commander.Option('--experimental-build-mode [mode]', 'Uses an experimental build mode.').choices([
'compile',
'generate',
'generate-env'
]).default('default')).option('--experimental-debug-memory-usage', 'Enables memory profiling features to debug memory consumption.').option('--experimental-upload-trace, <traceUrl>', 'Reports a subset of the debugging trace to a remote HTTP URL. Includes sensitive data.').option('--experimental-next-config-strip-types', 'Use Node.js native TypeScript resolution for next.config.(ts|mts)').option('--debug-build-paths <patterns>', 'Comma-separated glob patterns or explicit paths for selective builds. Examples: "app/*", "app/page.tsx", "app/**/page.tsx"').action((directory, options)=>{
if (options.experimentalNextConfigStripTypes) {
process.env.__NEXT_NODE_NATIVE_TS_LOADER_ENABLED = 'true';
}
// ensure process exits after build completes so open handles/connections
// don't cause process to hang
return import('../cli/next-build.js').then((mod)=>mod.nextBuild(options, directory).then(()=>process.exit(0)));
}).usage('[directory] [options]');
program.command('experimental-analyze').description('Analyze production bundle output with an interactive web ui. Does not produce an application build. Only compatible with Turbopack.').argument('[directory]', `A directory on which to analyze the application. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).option('--no-mangling', 'Disables mangling.').option('--profile', 'Enables production profiling for React.').option('-o, --output', 'Only write analysis files to disk. Does not start the server.').addOption(new _commander.Option('--port <port>', 'Specify a port number to serve the analyzer on.').implies({
serve: true
}).argParser(_utils.parseValidPositiveInteger).default(4000).env('PORT')).action((directory, options)=>{
return import('../cli/next-analyze.js').then((mod)=>mod.nextAnalyze(options, directory)).then(()=>{
if (options.output) {
// The Next.js process is held open by something on the event loop. Exit manually like the `build` command does.
// TODO: Fix the underlying issue so this is not necessary.
process.exit(0);
}
});
});
program.command('dev', {
isDefault: true
}).description('Starts Next.js in development mode with hot-code reloading, error reporting, and more.').argument('[directory]', `A directory on which to build the application. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).addOption(new _commander.Option('--inspect [[host:]port]', 'Allows inspecting server-side code. See https://nextjs.org/docs/app/guides/debugging#server-side-code').argParser(parseValidInspectAddress)).option('--turbo', 'Starts development mode using Turbopack.').option('--turbopack', 'Starts development mode using Turbopack.').option('--webpack', 'Starts development mode using webpack.').addOption(new _commander.Option('-p, --port <port>', 'Specify a port number on which to start the application.').argParser(_utils.parseValidPositiveInteger).default(3000).env('PORT')).option('-H, --hostname <hostname>', 'Specify a hostname on which to start the application (default: 0.0.0.0).').option('--disable-source-maps', "Don't start the Dev server with `--enable-source-maps`.", false).option('--experimental-https', 'Starts the server with HTTPS and generates a self-signed certificate.').option('--experimental-https-key, <path>', 'Path to a HTTPS key file.').option('--experimental-https-cert, <path>', 'Path to a HTTPS certificate file.').option('--experimental-https-ca, <path>', 'Path to a HTTPS certificate authority file.').option('--experimental-upload-trace, <traceUrl>', 'Reports a subset of the debugging trace to a remote HTTP URL. Includes sensitive data.').option('--experimental-next-config-strip-types', 'Use Node.js native TypeScript resolution for next.config.(ts|mts)').action((directory, options, { _optionValueSources })=>{
if (options.experimentalNextConfigStripTypes) {
process.env.__NEXT_NODE_NATIVE_TS_LOADER_ENABLED = 'true';
}
const portSource = _optionValueSources.port;
import('../cli/next-dev.js').then((mod)=>mod.nextDev(options, portSource, directory));
}).usage('[directory] [options]');
program.command('export', {
hidden: true
}).action(()=>import('../cli/next-export.js').then((mod)=>mod.nextExport())).helpOption(false);
program.command('info').description('Prints relevant details about the current system which can be used to report Next.js bugs.').addHelpText('after', `\nLearn more: ${(0, _picocolors.cyan)('https://nextjs.org/docs/api-reference/cli#info')}`).option('--verbose', 'Collects additional information for debugging.').action((options)=>import('../cli/next-info.js').then((mod)=>mod.nextInfo(options)));
program.command('start').description('Starts Next.js in production mode. The application should be compiled with `next build` first.').argument('[directory]', `A directory on which to start the application. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).addOption(new _commander.Option('-p, --port <port>', 'Specify a port number on which to start the application.').argParser(_utils.parseValidPositiveInteger).default(3000).env('PORT')).option('-H, --hostname <hostname>', 'Specify a hostname on which to start the application (default: 0.0.0.0).').addOption(new _commander.Option('--keepAliveTimeout <keepAliveTimeout>', 'Specify the maximum amount of milliseconds to wait before closing inactive connections.').argParser(_utils.parseValidPositiveInteger)).option('--experimental-next-config-strip-types', 'Use Node.js native TypeScript resolution for next.config.(ts|mts)').action((directory, options)=>{
if (options.experimentalNextConfigStripTypes) {
process.env.__NEXT_NODE_NATIVE_TS_LOADER_ENABLED = 'true';
}
return import('../cli/next-start.js').then((mod)=>mod.nextStart(options, directory));
}).usage('[directory] [options]');
program.command('telemetry').description(`Allows you to enable or disable Next.js' ${(0, _picocolors.bold)('completely anonymous')} telemetry collection.`).addArgument(new _commander.Argument('[arg]').choices([
'disable',
'enable',
'status'
])).addHelpText('after', `\nLearn more: ${(0, _picocolors.cyan)('https://nextjs.org/telemetry')}`).addOption(new _commander.Option('--enable', `Enables Next.js' telemetry collection.`).conflicts('disable')).option('--disable', `Disables Next.js' telemetry collection.`).action((arg, options)=>import('../cli/next-telemetry.js').then((mod)=>mod.nextTelemetry(options, arg)));
program.command('typegen').description('Generate TypeScript definitions for routes, pages, and layouts without running a full build.').argument('[directory]', `A directory on which to generate types. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).action((directory, options)=>// ensure process exits after typegen completes so open handles/connections
// don't cause process to hang
import('../cli/next-typegen.js').then((mod)=>mod.nextTypegen(options, directory).then(()=>process.exit(0)))).usage('[directory] [options]');
const nextVersion = "16.1.4" || 'unknown';
program.command('upgrade').description('Upgrade Next.js apps to desired versions with a single command.').argument('[directory]', `A Next.js project directory to upgrade. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).usage('[directory] [options]').option('--revision <revision>', 'Specify the target Next.js version using an NPM dist tag (e.g. "latest", "canary", "rc", "beta") or an exact version number (e.g. "15.0.0").', nextVersion.includes('-canary.') ? 'canary' : nextVersion.includes('-rc.') ? 'rc' : nextVersion.includes('-beta.') ? 'beta' : 'latest').option('--verbose', 'Verbose output', false).action(async (directory, options)=>{
const mod = await import('../cli/next-upgrade.js');
mod.spawnNextUpgrade(directory, options);
});
program.command('experimental-test').description(`Execute \`next/experimental/testmode\` tests using a specified test runner. The test runner defaults to 'playwright' if the \`experimental.defaultTestRunner\` configuration option or the \`--test-runner\` option are not set.`).argument('[directory]', `A Next.js project directory to execute the test runner on. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).argument('[test-runner-args...]', 'Any additional arguments or options to pass down to the test runner `test` command.').option('--test-runner [test-runner]', `Any supported test runner. Options: ${(0, _picocolors.bold)(_nexttest.SUPPORTED_TEST_RUNNERS_LIST.join(', '))}. ${(0, _picocolors.italic)("If no test runner is provided, the Next.js config option `experimental.defaultTestRunner`, or 'playwright' will be used.")}`).allowUnknownOption().action((directory, testRunnerArgs, options)=>{
return import('../cli/next-test.js').then((mod)=>{
mod.nextTest(directory, testRunnerArgs, options);
});
}).usage('[directory] [options]');
const internal = program.command('internal').description('Internal debugging commands. Use with caution. Not covered by semver.');
internal.command('trace').alias('turbo-trace-server').argument('file', 'Trace file to serve.').addOption(new _commander.Option('-p, --port <port>', 'Override the port.').argParser(_utils.parseValidPositiveInteger)).action((file, options)=>{
return import('../cli/internal/turbo-trace-server.js').then((mod)=>mod.startTurboTraceServerCli(file, options.port));
});
program.parse(process.argv);
//# sourceMappingURL=next.map

2
apps/public-web/node_modules/next/dist/bin/next.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env node
import '../server/require-hook';

1
apps/public-web/node_modules/next/dist/bin/next.map generated vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,326 @@
import { RenderingMode } from '../rendering-mode';
import type { RouteHas } from '../../lib/load-custom-routes';
import type { Revalidate } from '../../server/lib/cache-control';
import type { NextConfigComplete } from '../../server/config-shared';
import { AdapterOutputType, type PHASE_TYPE } from '../../shared/lib/constants';
import type { MiddlewareManifest } from '../webpack/plugins/middleware-plugin';
import type { RoutesManifest, PrerenderManifest, FunctionsConfigManifest, DynamicPrerenderManifestRoute } from '..';
interface SharedRouteFields {
/**
* id is the unique identifier of the output
*/
id: string;
/**
* filePath is the location on disk of the built entrypoint asset
*/
filePath: string;
/**
* pathname is the URL pathname the asset should be served at
*/
pathname: string;
/**
* sourcePage is the original source in the app or pages folder
*/
sourcePage: string;
/**
* runtime is which runtime the entrypoint is built for
*/
runtime: 'nodejs' | 'edge';
/**
* assets are all necessary traced assets that could be
* loaded by the output to handle a request e.g. traced
* node_modules or necessary manifests for Next.js.
* The key is the relative path from the repo root and the value
* is the absolute path to the file
*/
assets: Record<string, string>;
/**
* wasmAssets are bundled wasm files with mapping of name
* to filePath on disk
*/
wasmAssets?: Record<string, string>;
/**
* config related to the route
*/
config: {
/**
* maxDuration is a segment config to signal the max
* execution duration a route should be allowed before
* it's timed out
*/
maxDuration?: number;
/**
* preferredRegion is a segment config to signal deployment
* region preferences to the provider being used
*/
preferredRegion?: string | string[];
/**
* env is the environment variables to expose, this is only
* populated for edge runtime currently
*/
env?: Record<string, string>;
};
}
export interface AdapterOutput {
/**
* `PAGES` represents all the React pages that are under `pages/`.
*/
PAGES: SharedRouteFields & {
type: AdapterOutputType.PAGES;
};
/**
* `PAGES_API` represents all the API routes under `pages/api/`.
*/
PAGES_API: SharedRouteFields & {
type: AdapterOutputType.PAGES_API;
};
/**
* `APP_PAGE` represents all the React pages that are under `app/` with the
* filename of `page.{j,t}s{,x}`.
*/
APP_PAGE: SharedRouteFields & {
type: AdapterOutputType.APP_PAGE;
};
/**
* `APP_ROUTE` represents all the API routes and metadata routes that are under `app/` with the
* filename of `route.{j,t}s{,x}`.
*/
APP_ROUTE: SharedRouteFields & {
type: AdapterOutputType.APP_ROUTE;
};
/**
* `PRERENDER` represents an ISR enabled route that might
* have a seeded cache entry or fallback generated during build
*/
PRERENDER: {
id: string;
pathname: string;
type: AdapterOutputType.PRERENDER;
/**
* For prerenders the parent output is the originating
* page that the prerender is created from
*/
parentOutputId: string;
/**
* groupId is the identifier for a group of prerenders that should be
* revalidated together
*/
groupId: number;
pprChain?: {
headers: Record<string, string>;
};
/**
* parentFallbackMode signals whether additional routes can be generated
* e.g. fallback: false or 'blocking' in getStaticPaths in pages router
*/
parentFallbackMode?: DynamicPrerenderManifestRoute['fallback'];
/**
* fallback is initial cache data generated during build for a prerender
*/
fallback?: {
/**
* path to the fallback file can be HTML/JSON/RSC
*/
filePath: string;
/**
* initialStatus is the status code that should be applied
* when serving the fallback
*/
initialStatus?: number;
/**
* initialHeaders are the headers that should be sent when
* serving the fallback
*/
initialHeaders?: Record<string, string | string[]>;
/**
* initial expiration is how long until the fallback entry
* is considered expired and no longer valid to serve
*/
initialExpiration?: number;
/**
* initial revalidate is how long until the fallback is
* considered stale and should be revalidated
*/
initialRevalidate?: Revalidate;
/**
* postponedState is the PPR state when it postponed and is used for resuming
*/
postponedState?: string;
};
/**
* config related to the route
*/
config: {
/**
* allowQuery is the allowed query values to be passed
* to an ISR function and what should be considered for the cacheKey
* e.g. for /blog/[slug], "slug" is the only allowQuery
*/
allowQuery?: string[];
/**
* allowHeader is the allowed headers to be passed to an
* ISR function to prevent accidentally poisoning the cache
* from leaking additional information that can impact the render
*/
allowHeader?: string[];
/**
* bypass for is a list of has conditions the cache
* should be bypassed and invoked directly e.g. action header
*/
bypassFor?: RouteHas[];
/**
* renderingMode signals PPR or not for a prerender
*/
renderingMode?: RenderingMode;
/**
* bypassToken is the generated token that signals a prerender cache
* should be bypassed
*/
bypassToken?: string;
};
};
/**
* `STATIC_FILE` represents a static file (ie /_next/static) or a purely
* static HTML asset e.g. an automatically statically optimized page
* that does not use ISR
*/
STATIC_FILE: {
id: string;
filePath: string;
pathname: string;
type: AdapterOutputType.STATIC_FILE;
};
/**
* `MIDDLEWARE` represents the middleware output if present
*/
MIDDLEWARE: SharedRouteFields & {
type: AdapterOutputType.MIDDLEWARE;
/**
* config related to the route
*/
config: SharedRouteFields['config'] & {
/**
* matchers are the configured matchers for middleware
*/
matchers?: Array<{
source: string;
sourceRegex: string;
has: RouteHas[] | undefined;
missing: RouteHas[] | undefined;
}>;
};
};
}
export interface AdapterOutputs {
pages: Array<AdapterOutput['PAGES']>;
middleware?: AdapterOutput['MIDDLEWARE'];
appPages: Array<AdapterOutput['APP_PAGE']>;
pagesApi: Array<AdapterOutput['PAGES_API']>;
appRoutes: Array<AdapterOutput['APP_ROUTE']>;
prerenders: Array<AdapterOutput['PRERENDER']>;
staticFiles: Array<AdapterOutput['STATIC_FILE']>;
}
type RewriteItem = {
source: string;
sourceRegex: string;
destination: string;
has: RouteHas[] | undefined;
missing: RouteHas[] | undefined;
};
type DynamicRouteItem = {
source: string;
sourceRegex: string;
destination: string;
has: RouteHas[] | undefined;
missing: RouteHas[] | undefined;
};
export interface NextAdapter {
name: string;
/**
* modifyConfig is called for any CLI command that loads the next.config
* to only apply for specific commands the "phase" should be used
* @param config
* @param ctx
* @returns
*/
modifyConfig?: (config: NextConfigComplete, ctx: {
phase: PHASE_TYPE;
}) => Promise<NextConfigComplete> | NextConfigComplete;
onBuildComplete?: (ctx: {
routes: {
headers: Array<{
source: string;
sourceRegex: string;
headers: Record<string, string>;
has: RouteHas[] | undefined;
missing: RouteHas[] | undefined;
priority?: boolean;
}>;
redirects: Array<{
source: string;
sourceRegex: string;
destination: string;
statusCode: number;
has: RouteHas[] | undefined;
missing: RouteHas[] | undefined;
priority?: boolean;
}>;
rewrites: {
beforeFiles: RewriteItem[];
afterFiles: RewriteItem[];
fallback: RewriteItem[];
};
dynamicRoutes: Array<DynamicRouteItem>;
};
outputs: AdapterOutputs;
/**
* projectDir is the absolute directory the Next.js application is in
*/
projectDir: string;
/**
* repoRoot is the absolute path of the detected root of the repo
*/
repoRoot: string;
/**
* distDir is the absolute path to the dist directory
*/
distDir: string;
/**
* config is the loaded next.config (has modifyConfig applied)
*/
config: NextConfigComplete;
/**
* nextVersion is the current version of Next.js being used
*/
nextVersion: string;
/**
* buildId is the current unique ID for the build, this can be
* influenced by NextConfig.generateBuildId
*/
buildId: string;
}) => Promise<void> | void;
}
export declare function handleBuildComplete({ dir, config, buildId, configOutDir, distDir, pageKeys, tracingRoot, adapterPath, appPageKeys, staticPages, nextVersion, hasStatic404, hasStatic500, routesManifest, serverPropsPages, hasNodeMiddleware, prerenderManifest, middlewareManifest, requiredServerFiles, hasInstrumentationHook, functionsConfigManifest, }: {
dir: string;
distDir: string;
buildId: string;
configOutDir: string;
adapterPath: string;
tracingRoot: string;
nextVersion: string;
hasStatic404: boolean;
hasStatic500: boolean;
staticPages: Set<string>;
hasNodeMiddleware: boolean;
config: NextConfigComplete;
pageKeys: readonly string[];
serverPropsPages: Set<string>;
requiredServerFiles: string[];
routesManifest: RoutesManifest;
hasInstrumentationHook: boolean;
prerenderManifest: PrerenderManifest;
middlewareManifest: MiddlewareManifest;
appPageKeys?: readonly string[] | undefined;
functionsConfigManifest: FunctionsConfigManifest;
}): Promise<void>;
export {};

View File

@@ -0,0 +1,993 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "handleBuildComplete", {
enumerable: true,
get: function() {
return handleBuildComplete;
}
});
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
const _promises = /*#__PURE__*/ _interop_require_default(require("fs/promises"));
const _url = require("url");
const _log = /*#__PURE__*/ _interop_require_wildcard(require("../output/log"));
const _utils = require("../utils");
const _renderingmode = require("../rendering-mode");
const _interopdefault = require("../../lib/interop-default");
const _recursivereaddir = require("../../lib/recursive-readdir");
const _utils1 = require("../../shared/lib/router/utils");
const _apppaths = require("../../shared/lib/router/utils/app-paths");
const _constants = require("../../shared/lib/constants");
const _normalizepagepath = require("../../shared/lib/page-path/normalize-page-path");
const _routingutils = require("next/dist/compiled/@vercel/routing-utils");
const _constants1 = require("../../lib/constants");
const _normalizelocalepath = require("../../shared/lib/i18n/normalize-locale-path");
const _addpathprefix = require("../../shared/lib/router/utils/add-path-prefix");
const _redirectstatus = require("../../lib/redirect-status");
const _routeregex = require("../../shared/lib/router/utils/route-regex");
const _escaperegexp = require("../../shared/lib/escape-regexp");
const _sortableroutes = require("../../shared/lib/router/utils/sortable-routes");
const _nft = require("next/dist/compiled/@vercel/nft");
const _requirehook = require("../../server/require-hook");
const _collectbuildtraces = require("../collect-build-traces");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
function normalizePathnames(config, outputs) {
// normalize pathname field with basePath
if (config.basePath) {
for (const output of [
...outputs.pages,
...outputs.pagesApi,
...outputs.appPages,
...outputs.appRoutes,
...outputs.prerenders,
...outputs.staticFiles
]){
output.pathname = (0, _addpathprefix.addPathPrefix)(output.pathname, config.basePath).replace(/\/$/, '') || '/';
}
}
}
async function handleBuildComplete({ dir, config, buildId, configOutDir, distDir, pageKeys, tracingRoot, adapterPath, appPageKeys, staticPages, nextVersion, hasStatic404, hasStatic500, routesManifest, serverPropsPages, hasNodeMiddleware, prerenderManifest, middlewareManifest, requiredServerFiles, hasInstrumentationHook, functionsConfigManifest }) {
const adapterMod = (0, _interopdefault.interopDefault)(await import((0, _url.pathToFileURL)(require.resolve(adapterPath)).href));
if (typeof adapterMod.onBuildComplete === 'function') {
const outputs = {
pages: [],
pagesApi: [],
appPages: [],
appRoutes: [],
prerenders: [],
staticFiles: []
};
if (config.output === 'export') {
// collect export assets and provide as static files
const exportFiles = await (0, _recursivereaddir.recursiveReadDir)(configOutDir);
for (const file of exportFiles){
let pathname = (file.endsWith('.html') ? file.replace(/\.html$/, '') : file).replace(/\\/g, '/');
pathname = pathname.startsWith('/') ? pathname : `/${pathname}`;
outputs.staticFiles.push({
id: file,
pathname,
filePath: _path.default.join(configOutDir, file),
type: _constants.AdapterOutputType.STATIC_FILE
});
}
} else {
const staticFiles = await (0, _recursivereaddir.recursiveReadDir)(_path.default.join(distDir, 'static'));
for (const file of staticFiles){
const pathname = _path.default.posix.join('/_next/static', file);
const filePath = _path.default.join(distDir, 'static', file);
outputs.staticFiles.push({
type: _constants.AdapterOutputType.STATIC_FILE,
id: _path.default.join('static', file),
pathname,
filePath
});
}
const sharedNodeAssets = {};
const pagesSharedNodeAssets = {};
const appPagesSharedNodeAssets = {};
const sharedTraceIgnores = [
'**/next/dist/compiled/next-server/**/*.dev.js',
'**/next/dist/compiled/webpack/*',
'**/node_modules/webpack5/**/*',
'**/next/dist/server/lib/route-resolver*',
'next/dist/compiled/semver/semver/**/*.js',
'**/node_modules/react{,-dom,-dom-server-turbopack}/**/*.development.js',
'**/*.d.ts',
'**/*.map',
'**/next/dist/pages/**/*',
'**/node_modules/sharp/**/*',
'**/@img/sharp-libvips*/**/*',
'**/next/dist/compiled/edge-runtime/**/*',
'**/next/dist/server/web/sandbox/**/*',
'**/next/dist/server/post-process.js'
];
const sharedIgnoreFn = (0, _collectbuildtraces.makeIgnoreFn)(tracingRoot, sharedTraceIgnores);
for (const file of requiredServerFiles){
// add to shared node assets
const filePath = _path.default.join(dir, file);
const fileOutputPath = _path.default.relative(tracingRoot, filePath);
sharedNodeAssets[fileOutputPath] = filePath;
}
const moduleTypes = [
'app-page',
'pages'
];
for (const type of moduleTypes){
const currentDependencies = [];
const modulePath = require.resolve(`next/dist/server/route-modules/${type}/module.compiled`);
const contextDir = _path.default.join(_path.default.dirname(modulePath), 'vendored', 'contexts');
for (const item of (await _promises.default.readdir(contextDir))){
if (item.match(/\.(mjs|cjs|js)$/)) {
currentDependencies.push(_path.default.join(contextDir, item));
}
}
const { fileList, esmFileList } = await (0, _nft.nodeFileTrace)(currentDependencies, {
base: tracingRoot,
ignore: sharedIgnoreFn
});
esmFileList.forEach((item)=>fileList.add(item));
for (const rootRelativeFilePath of fileList){
if (type === 'pages') {
pagesSharedNodeAssets[rootRelativeFilePath] = _path.default.join(tracingRoot, rootRelativeFilePath);
} else {
appPagesSharedNodeAssets[rootRelativeFilePath] = _path.default.join(tracingRoot, rootRelativeFilePath);
}
}
}
// These are modules that are necessary for bootstrapping node env
const necessaryNodeDependencies = [
require.resolve('next/dist/server/node-environment'),
require.resolve('next/dist/server/require-hook'),
require.resolve('next/dist/server/node-polyfill-crypto'),
...Object.values(_requirehook.defaultOverrides).filter((item)=>_path.default.extname(item))
];
const { fileList, esmFileList } = await (0, _nft.nodeFileTrace)(necessaryNodeDependencies, {
base: tracingRoot,
ignore: sharedIgnoreFn
});
esmFileList.forEach((item)=>fileList.add(item));
for (const rootRelativeFilePath of fileList){
sharedNodeAssets[rootRelativeFilePath] = _path.default.join(tracingRoot, rootRelativeFilePath);
}
if (hasInstrumentationHook) {
const assets = await handleTraceFiles(_path.default.join(distDir, 'server', 'instrumentation.js.nft.json'), 'neutral');
const fileOutputPath = _path.default.relative(tracingRoot, _path.default.join(distDir, 'server', 'instrumentation.js'));
sharedNodeAssets[fileOutputPath] = _path.default.join(distDir, 'server', 'instrumentation.js');
Object.assign(sharedNodeAssets, assets);
}
async function handleTraceFiles(traceFilePath, type) {
const assets = Object.assign({}, sharedNodeAssets, type === 'pages' ? pagesSharedNodeAssets : {}, type === 'app' ? appPagesSharedNodeAssets : {});
const traceData = JSON.parse(await _promises.default.readFile(traceFilePath, 'utf8'));
const traceFileDir = _path.default.dirname(traceFilePath);
for (const relativeFile of traceData.files){
const tracedFilePath = _path.default.join(traceFileDir, relativeFile);
const fileOutputPath = _path.default.relative(tracingRoot, tracedFilePath);
assets[fileOutputPath] = tracedFilePath;
}
return assets;
}
async function handleEdgeFunction(page, isMiddleware = false) {
let type = _constants.AdapterOutputType.PAGES;
const isAppPrefix = page.name.startsWith('app/');
const isAppPage = isAppPrefix && page.name.endsWith('/page');
const isAppRoute = isAppPrefix && page.name.endsWith('/route');
let currentOutputs = outputs.pages;
if (isMiddleware) {
type = _constants.AdapterOutputType.MIDDLEWARE;
} else if (isAppPage) {
currentOutputs = outputs.appPages;
type = _constants.AdapterOutputType.APP_PAGE;
} else if (isAppRoute) {
currentOutputs = outputs.appRoutes;
type = _constants.AdapterOutputType.APP_ROUTE;
} else if (page.page.startsWith('/api')) {
currentOutputs = outputs.pagesApi;
type = _constants.AdapterOutputType.PAGES_API;
}
const route = page.page.replace(/^(app|pages)\//, '');
const output = {
type,
id: page.name,
runtime: 'edge',
sourcePage: route,
pathname: isAppPrefix ? (0, _apppaths.normalizeAppPath)(route) : route,
filePath: _path.default.join(distDir, page.files.find((item)=>item.startsWith('server/app') || item.startsWith('server/pages')) || // TODO: turbopack build doesn't name the main entry chunk
// identifiably so we don't know which to mark here but
// technically edge needs all chunks to load always so
// should this field even be provided?
page.files[0] || ''),
assets: {},
wasmAssets: {},
config: {
env: page.env
}
};
function handleFile(file) {
const originalPath = _path.default.join(distDir, file);
const fileOutputPath = _path.default.join(_path.default.relative(tracingRoot, distDir), file);
if (!output.assets) {
output.assets = {};
}
output.assets[fileOutputPath] = originalPath;
}
for (const file of page.files){
handleFile(file);
}
for (const item of [
...page.assets || []
]){
handleFile(item.filePath);
}
for (const item of page.wasm || []){
if (!output.wasmAssets) {
output.wasmAssets = {};
}
output.wasmAssets[item.name] = _path.default.join(distDir, item.filePath);
}
if (type === _constants.AdapterOutputType.MIDDLEWARE) {
;
output.config.matchers = page.matchers.map((item)=>{
return {
source: item.originalSource,
sourceRegex: item.regexp,
has: item.has,
missing: [
...item.missing || [],
// always skip middleware for on-demand revalidate
{
type: 'header',
key: 'x-prerender-revalidate',
value: prerenderManifest.preview.previewModeId
}
]
};
});
output.pathname = '/_middleware';
output.id = page.name;
outputs.middleware = output;
} else {
currentOutputs.push(output);
}
// need to add matching .rsc output
if (isAppPage) {
const rscPathname = (0, _normalizepagepath.normalizePagePath)(output.pathname) + '.rsc';
outputs.appPages.push({
...output,
pathname: rscPathname,
id: page.name + '.rsc'
});
}
}
const edgeFunctionHandlers = [];
for (const middleware of Object.values(middlewareManifest.middleware)){
if ((0, _utils.isMiddlewareFilename)(middleware.name)) {
edgeFunctionHandlers.push(handleEdgeFunction(middleware, true));
}
}
for (const page of Object.values(middlewareManifest.functions)){
edgeFunctionHandlers.push(handleEdgeFunction(page));
}
const pagesDistDir = _path.default.join(distDir, 'server', 'pages');
const pageOutputMap = {};
const rscFallbackPath = _path.default.join(distDir, 'server', 'rsc-fallback.json');
if (appPageKeys && appPageKeys.length > 0 && pageKeys.length > 0) {
await _promises.default.writeFile(rscFallbackPath, '{}');
}
for (const page of pageKeys){
if (page === '/_app' || page === '/_document') {
continue;
}
if (middlewareManifest.functions.hasOwnProperty(page)) {
continue;
}
const route = (0, _normalizepagepath.normalizePagePath)(page);
const pageFile = _path.default.join(pagesDistDir, `${route}.js`);
// if it's an auto static optimized page it's just
// a static file
if (staticPages.has(page)) {
if (config.i18n) {
for (const locale of config.i18n.locales || []){
const localePage = page === '/' ? `/${locale}` : (0, _addpathprefix.addPathPrefix)(page, `/${locale}`);
const localeOutput = {
id: localePage,
pathname: localePage,
type: _constants.AdapterOutputType.STATIC_FILE,
filePath: _path.default.join(pagesDistDir, `${(0, _normalizepagepath.normalizePagePath)(localePage)}.html`)
};
outputs.staticFiles.push(localeOutput);
if (appPageKeys && appPageKeys.length > 0) {
outputs.staticFiles.push({
id: `${localePage}.rsc`,
pathname: `${localePage}.rsc`,
type: _constants.AdapterOutputType.STATIC_FILE,
filePath: rscFallbackPath
});
}
}
} else {
const staticOutput = {
id: page,
pathname: route,
type: _constants.AdapterOutputType.STATIC_FILE,
filePath: pageFile.replace(/\.js$/, '.html')
};
outputs.staticFiles.push(staticOutput);
if (appPageKeys && appPageKeys.length > 0) {
outputs.staticFiles.push({
id: `${page}.rsc`,
pathname: `${route}.rsc`,
type: _constants.AdapterOutputType.STATIC_FILE,
filePath: rscFallbackPath
});
}
}
continue;
}
const pageTraceFile = `${pageFile}.nft.json`;
const assets = await handleTraceFiles(pageTraceFile, 'pages').catch((err)=>{
if (err.code !== 'ENOENT' || page !== '/404' && page !== '/500') {
_log.warn(`Failed to locate traced assets for ${pageFile}`, err);
}
return {};
});
const functionConfig = functionsConfigManifest.functions[route] || {};
let sourcePage = route.replace(/^\//, '');
sourcePage = sourcePage === 'api' ? 'api/index' : sourcePage;
const output = {
id: route,
type: page.startsWith('/api') ? _constants.AdapterOutputType.PAGES_API : _constants.AdapterOutputType.PAGES,
filePath: pageTraceFile.replace(/\.nft\.json$/, ''),
pathname: route,
sourcePage,
assets,
runtime: 'nodejs',
config: {
maxDuration: functionConfig.maxDuration,
preferredRegion: functionConfig.regions
}
};
pageOutputMap[page] = output;
if (output.type === _constants.AdapterOutputType.PAGES) {
var _config_i18n;
outputs.pages.push(output);
// if page is get server side props we need to create
// the _next/data output as well
if (serverPropsPages.has(page)) {
const dataPathname = _path.default.posix.join('/_next/data', buildId, (0, _normalizepagepath.normalizePagePath)(page) + '.json');
outputs.pages.push({
...output,
pathname: dataPathname,
id: dataPathname
});
}
for (const locale of ((_config_i18n = config.i18n) == null ? void 0 : _config_i18n.locales) || []){
const localePage = page === '/' ? `/${locale}` : (0, _addpathprefix.addPathPrefix)(page, `/${locale}`);
outputs.pages.push({
...output,
id: localePage,
pathname: localePage
});
if (serverPropsPages.has(page)) {
const dataPathname = _path.default.posix.join('/_next/data', buildId, localePage + '.json');
outputs.pages.push({
...output,
pathname: dataPathname,
id: dataPathname
});
}
}
} else {
outputs.pagesApi.push(output);
}
if (appPageKeys && appPageKeys.length > 0) {
outputs.staticFiles.push({
id: `${output.id}.rsc`,
pathname: `${output.pathname}.rsc`,
type: _constants.AdapterOutputType.STATIC_FILE,
filePath: rscFallbackPath
});
}
}
if (hasNodeMiddleware) {
var _functionConfig_matchers;
const middlewareFile = _path.default.join(distDir, 'server', 'middleware.js');
const middlewareTrace = `${middlewareFile}.nft.json`;
const assets = await handleTraceFiles(middlewareTrace, 'neutral');
const functionConfig = functionsConfigManifest.functions['/_middleware'] || {};
outputs.middleware = {
pathname: '/_middleware',
id: '/_middleware',
sourcePage: 'middleware',
assets,
type: _constants.AdapterOutputType.MIDDLEWARE,
runtime: 'nodejs',
filePath: middlewareFile,
config: {
matchers: ((_functionConfig_matchers = functionConfig.matchers) == null ? void 0 : _functionConfig_matchers.map((item)=>{
return {
source: item.originalSource,
sourceRegex: item.regexp,
has: item.has,
missing: [
...item.missing || [],
// always skip middleware for on-demand revalidate
{
type: 'header',
key: 'x-prerender-revalidate',
value: prerenderManifest.preview.previewModeId
}
]
};
})) || []
}
};
}
const appOutputMap = {};
const appDistDir = _path.default.join(distDir, 'server', 'app');
if (appPageKeys) {
for (const page of appPageKeys){
if (middlewareManifest.functions.hasOwnProperty(page)) {
continue;
}
const normalizedPage = (0, _apppaths.normalizeAppPath)(page);
const pageFile = _path.default.join(appDistDir, `${page}.js`);
const pageTraceFile = `${pageFile}.nft.json`;
const assets = await handleTraceFiles(pageTraceFile, 'app').catch((err)=>{
_log.warn(`Failed to copy traced files for ${pageFile}`, err);
return {};
});
// If this is a parallel route we just need to merge
// the assets as they share the same pathname
const existingOutput = appOutputMap[normalizedPage];
if (existingOutput) {
Object.assign(existingOutput.assets, assets);
existingOutput.assets[_path.default.relative(tracingRoot, pageFile)] = pageFile;
continue;
}
const functionConfig = functionsConfigManifest.functions[normalizedPage] || {};
const output = {
pathname: normalizedPage,
id: normalizedPage,
sourcePage: page,
assets,
type: page.endsWith('/route') ? _constants.AdapterOutputType.APP_ROUTE : _constants.AdapterOutputType.APP_PAGE,
runtime: 'nodejs',
filePath: pageFile,
config: {
maxDuration: functionConfig.maxDuration,
preferredRegion: functionConfig.regions
}
};
appOutputMap[normalizedPage] = output;
if (output.type === _constants.AdapterOutputType.APP_PAGE) {
outputs.appPages.push({
...output,
pathname: (0, _normalizepagepath.normalizePagePath)(output.pathname) + '.rsc',
id: (0, _normalizepagepath.normalizePagePath)(output.pathname) + '.rsc'
});
outputs.appPages.push(output);
} else {
outputs.appRoutes.push(output);
}
}
}
const getParentOutput = (srcRoute, childRoute, allowMissing)=>{
var _config_i18n;
const normalizedSrcRoute = (0, _normalizelocalepath.normalizeLocalePath)(srcRoute, ((_config_i18n = config.i18n) == null ? void 0 : _config_i18n.locales) || []).pathname;
const parentOutput = pageOutputMap[normalizedSrcRoute] || appOutputMap[normalizedSrcRoute];
if (!parentOutput && !allowMissing) {
console.error({
appOutputs: Object.keys(appOutputMap),
pageOutputs: Object.keys(pageOutputMap)
});
throw Object.defineProperty(new Error(`Invariant: failed to find source route ${srcRoute} for prerender ${childRoute}`), "__NEXT_ERROR_CODE", {
value: "E777",
enumerable: false,
configurable: true
});
}
return parentOutput;
};
const { prefetchSegmentDirSuffix, prefetchSegmentSuffix, varyHeader, didPostponeHeader, contentTypeHeader: rscContentTypeHeader } = routesManifest.rsc;
const handleAppMeta = async (route, initialOutput, meta)=>{
if (meta.postponed && initialOutput.fallback) {
initialOutput.fallback.postponedState = meta.postponed;
}
if (meta == null ? void 0 : meta.segmentPaths) {
const normalizedRoute = (0, _normalizepagepath.normalizePagePath)(route);
const segmentsDir = _path.default.join(appDistDir, `${normalizedRoute}${prefetchSegmentDirSuffix}`);
for (const segmentPath of meta.segmentPaths){
var _initialOutput_fallback, _initialOutput_fallback1, _initialOutput_fallback2;
const outputSegmentPath = _path.default.join(normalizedRoute + prefetchSegmentDirSuffix, segmentPath) + prefetchSegmentSuffix;
const fallbackPathname = _path.default.join(segmentsDir, segmentPath + prefetchSegmentSuffix);
outputs.prerenders.push({
id: outputSegmentPath,
pathname: outputSegmentPath,
type: _constants.AdapterOutputType.PRERENDER,
parentOutputId: initialOutput.parentOutputId,
groupId: initialOutput.groupId,
config: {
...initialOutput.config
},
fallback: {
filePath: fallbackPathname,
initialExpiration: (_initialOutput_fallback = initialOutput.fallback) == null ? void 0 : _initialOutput_fallback.initialExpiration,
initialRevalidate: (_initialOutput_fallback1 = initialOutput.fallback) == null ? void 0 : _initialOutput_fallback1.initialRevalidate,
initialHeaders: {
...(_initialOutput_fallback2 = initialOutput.fallback) == null ? void 0 : _initialOutput_fallback2.initialHeaders,
vary: varyHeader,
'content-type': rscContentTypeHeader,
[didPostponeHeader]: '2'
}
}
});
}
}
};
let prerenderGroupId = 1;
const getAppRouteMeta = async (route, isAppPage)=>{
const basename = route.endsWith('/') ? `${route}index` : route;
const meta = isAppPage ? JSON.parse(await _promises.default.readFile(_path.default.join(appDistDir, `${basename}.meta`), 'utf8').catch(()=>'{}')) : {};
if (meta.headers) {
// normalize these for consistency
for (const key of Object.keys(meta.headers)){
const keyLower = key.toLowerCase();
if (keyLower !== key) {
const value = meta.headers[key];
delete meta.headers[key];
meta.headers[keyLower] = value;
}
}
}
return meta;
};
const filePathCache = new Map();
const cachedFilePathCheck = async (filePath)=>{
if (filePathCache.has(filePath)) {
return filePathCache.get(filePath);
}
const newCheck = _promises.default.access(filePath).then(()=>true).catch(()=>false);
filePathCache.set(filePath, newCheck);
return newCheck;
};
for(const route in prerenderManifest.routes){
var _routesManifest_dynamicRoutes_find;
const { initialExpireSeconds: initialExpiration, initialRevalidateSeconds: initialRevalidate, initialHeaders, initialStatus, prefetchDataRoute, dataRoute, renderingMode, allowHeader, experimentalBypassFor } = prerenderManifest.routes[route];
const srcRoute = prerenderManifest.routes[route].srcRoute || route;
const srcRouteInfo = prerenderManifest.dynamicRoutes[srcRoute];
const isAppPage = Boolean(appOutputMap[srcRoute]) || srcRoute === '/_not-found';
const isNotFoundTrue = prerenderManifest.notFoundRoutes.includes(route);
let allowQuery;
const routeKeys = (_routesManifest_dynamicRoutes_find = routesManifest.dynamicRoutes.find((item)=>item.page === srcRoute)) == null ? void 0 : _routesManifest_dynamicRoutes_find.routeKeys;
if (!(0, _utils1.isDynamicRoute)(srcRoute)) {
// for non-dynamic routes we use an empty array since
// no query values bust the cache for non-dynamic prerenders
// prerendered paths also do not pass allowQuery as they match
// during handle: 'filesystem' so should not cache differently
// by query values
allowQuery = [];
} else if (routeKeys) {
// if we have routeKeys in the routes-manifest we use those
// for allowQuery for dynamic routes
allowQuery = Object.values(routeKeys);
}
let filePath = _path.default.join(isAppPage ? appDistDir : pagesDistDir, `${(0, _normalizepagepath.normalizePagePath)(route)}.${isAppPage && !dataRoute ? 'body' : 'html'}`);
// we use the static 404 for notFound: true if available
// if not we do a blocking invoke on first request
if (isNotFoundTrue && hasStatic404) {
var _config_i18n1;
const locale = config.i18n && (0, _normalizelocalepath.normalizeLocalePath)(route, (_config_i18n1 = config.i18n) == null ? void 0 : _config_i18n1.locales).detectedLocale;
for (const currentFilePath of [
_path.default.join(pagesDistDir, locale || '', '404.html'),
_path.default.join(pagesDistDir, '404.html')
]){
if (await cachedFilePathCheck(currentFilePath)) {
filePath = currentFilePath;
break;
}
}
}
const meta = await getAppRouteMeta(route, isAppPage);
const initialOutput = {
id: route,
type: _constants.AdapterOutputType.PRERENDER,
pathname: route,
parentOutputId: srcRoute === '/_not-found' ? srcRoute : getParentOutput(srcRoute, route).id,
groupId: prerenderGroupId,
pprChain: isAppPage && config.experimental.ppr ? {
headers: {
[_constants1.NEXT_RESUME_HEADER]: '1'
}
} : undefined,
parentFallbackMode: srcRouteInfo == null ? void 0 : srcRouteInfo.fallback,
fallback: !isNotFoundTrue || isNotFoundTrue && hasStatic404 ? {
filePath,
initialStatus: initialStatus ?? isNotFoundTrue ? 404 : undefined,
initialHeaders: {
...initialHeaders,
vary: varyHeader,
'content-type': _constants1.HTML_CONTENT_TYPE_HEADER,
...meta.headers
},
initialExpiration,
initialRevalidate: typeof initialRevalidate === 'undefined' ? 1 : initialRevalidate
} : undefined,
config: {
allowQuery,
allowHeader,
renderingMode,
bypassFor: experimentalBypassFor,
bypassToken: prerenderManifest.preview.previewModeId
}
};
outputs.prerenders.push(initialOutput);
if (dataRoute) {
var _initialOutput_fallback;
let dataFilePath = _path.default.join(pagesDistDir, `${(0, _normalizepagepath.normalizePagePath)(route)}.json`);
if (isAppPage) {
// When experimental PPR is enabled, we expect that the data
// that should be served as a part of the prerender should
// be from the prefetch data route. If this isn't enabled
// for ppr, the only way to get the data is from the data
// route.
dataFilePath = _path.default.join(appDistDir, prefetchDataRoute && renderingMode === _renderingmode.RenderingMode.PARTIALLY_STATIC ? prefetchDataRoute : dataRoute);
}
outputs.prerenders.push({
...initialOutput,
id: dataRoute,
pathname: dataRoute,
fallback: isNotFoundTrue ? undefined : {
...initialOutput.fallback,
initialHeaders: {
...(_initialOutput_fallback = initialOutput.fallback) == null ? void 0 : _initialOutput_fallback.initialHeaders,
'content-type': isAppPage ? rscContentTypeHeader : _constants1.JSON_CONTENT_TYPE_HEADER
},
filePath: dataFilePath
}
});
}
if (isAppPage) {
await handleAppMeta(route, initialOutput, meta);
}
prerenderGroupId += 1;
}
for(const dynamicRoute in prerenderManifest.dynamicRoutes){
var _routesManifest_dynamicRoutes_find1;
const { fallback, fallbackExpire, fallbackRevalidate, fallbackHeaders, fallbackStatus, allowHeader, dataRoute, renderingMode, experimentalBypassFor } = prerenderManifest.dynamicRoutes[dynamicRoute];
const isAppPage = Boolean(appOutputMap[dynamicRoute]);
const allowQuery = Object.values(((_routesManifest_dynamicRoutes_find1 = routesManifest.dynamicRoutes.find((item)=>item.page === dynamicRoute)) == null ? void 0 : _routesManifest_dynamicRoutes_find1.routeKeys) || {});
const meta = await getAppRouteMeta(dynamicRoute, isAppPage);
const initialOutput = {
id: dynamicRoute,
type: _constants.AdapterOutputType.PRERENDER,
pathname: dynamicRoute,
parentOutputId: getParentOutput(dynamicRoute, dynamicRoute).id,
groupId: prerenderGroupId,
config: {
allowQuery,
allowHeader,
renderingMode,
bypassFor: experimentalBypassFor,
bypassToken: prerenderManifest.preview.previewModeId
},
fallback: typeof fallback === 'string' ? {
filePath: _path.default.join(isAppPage ? appDistDir : pagesDistDir, // app router dynamic route fallbacks don't have the
// extension so ensure it's added here
fallback.endsWith('.html') ? fallback : `${fallback}.html`),
initialStatus: fallbackStatus,
initialHeaders: {
...fallbackHeaders,
'content-type': _constants1.HTML_CONTENT_TYPE_HEADER
},
initialExpiration: fallbackExpire,
initialRevalidate: fallbackRevalidate || 1
} : undefined
};
if (!config.i18n || isAppPage) {
outputs.prerenders.push(initialOutput);
if (isAppPage) {
await handleAppMeta(dynamicRoute, initialOutput, meta);
}
if (dataRoute) {
outputs.prerenders.push({
...initialOutput,
id: dataRoute,
pathname: dataRoute,
fallback: undefined
});
}
prerenderGroupId += 1;
} else {
for (const locale of config.i18n.locales){
const currentOutput = {
...initialOutput,
pathname: _path.default.posix.join(`/${locale}`, initialOutput.pathname),
id: _path.default.posix.join(`/${locale}`, initialOutput.id),
fallback: typeof fallback === 'string' ? {
...initialOutput.fallback,
filePath: _path.default.join(pagesDistDir, locale, // app router dynamic route fallbacks don't have the
// extension so ensure it's added here
fallback.endsWith('.html') ? fallback : `${fallback}.html`)
} : undefined,
groupId: prerenderGroupId
};
outputs.prerenders.push(currentOutput);
if (dataRoute) {
const dataPathname = _path.default.posix.join(`/_next/data`, buildId, locale, dynamicRoute + '.json');
outputs.prerenders.push({
...initialOutput,
id: dataPathname,
pathname: dataPathname,
// data route doesn't have skeleton fallback
fallback: undefined,
groupId: prerenderGroupId
});
}
prerenderGroupId += 1;
}
}
}
// ensure 404
const staticErrorDocs = [
...hasStatic404 ? [
'/404'
] : [],
...hasStatic500 ? [
'/500'
] : []
];
for (const errorDoc of staticErrorDocs){
var _config_i18n2;
const errorDocPath = _path.default.posix.join('/', ((_config_i18n2 = config.i18n) == null ? void 0 : _config_i18n2.defaultLocale) || '', errorDoc);
if (!prerenderManifest.routes[errorDocPath]) {
var _config_i18n_locales, _config_i18n3;
for (const currentDocPath of [
errorDocPath,
...((_config_i18n3 = config.i18n) == null ? void 0 : (_config_i18n_locales = _config_i18n3.locales) == null ? void 0 : _config_i18n_locales.map((locale)=>_path.default.posix.join('/', locale, errorDoc))) || []
]){
const currentFilePath = _path.default.join(pagesDistDir, `${currentDocPath}.html`);
if (await cachedFilePathCheck(currentFilePath)) {
outputs.staticFiles.push({
pathname: currentDocPath,
id: currentDocPath,
type: _constants.AdapterOutputType.STATIC_FILE,
filePath: currentFilePath
});
}
}
}
}
}
normalizePathnames(config, outputs);
const dynamicRoutes = [];
const dynamicDataRoutes = [];
const dynamicSegmentRoutes = [];
const getDestinationQuery = (routeKeys)=>{
const items = Object.entries(routeKeys ?? {});
if (items.length === 0) return '';
return '?' + items.map(([key, value])=>`${value}=$${key}`).join('&');
};
const fallbackFalseHasCondition = [
{
type: 'cookie',
key: '__prerender_bypass',
value: prerenderManifest.preview.previewModeId
},
{
type: 'cookie',
key: '__next_preview_data'
}
];
for (const route of routesManifest.dynamicRoutes){
var _prerenderManifest_dynamicRoutes_route_page;
const shouldLocalize = config.i18n;
const routeRegex = (0, _routeregex.getNamedRouteRegex)(route.page, {
prefixRouteKeys: true
});
const isFallbackFalse = ((_prerenderManifest_dynamicRoutes_route_page = prerenderManifest.dynamicRoutes[route.page]) == null ? void 0 : _prerenderManifest_dynamicRoutes_route_page.fallback) === false;
const { hasFallbackRootParams } = route;
const sourceRegex = routeRegex.namedRegex.replace('^', `^${config.basePath && config.basePath !== '/' ? _path.default.posix.join('/', config.basePath || '') : ''}[/]?${shouldLocalize ? '(?<nextLocale>[^/]{1,})?' : ''}`);
const destination = _path.default.posix.join('/', config.basePath, shouldLocalize ? '/$nextLocale' : '', route.page) + getDestinationQuery(route.routeKeys);
if (appPageKeys && appPageKeys.length > 0 && config.cacheComponents) {
// If we have fallback root params (implying we've already
// emitted a rewrite for the /_tree request), or if the route
// has PPR enabled and client param parsing is enabled, then
// we don't need to include any other suffixes.
const shouldSkipSuffixes = hasFallbackRootParams;
dynamicRoutes.push({
source: route.page + '.rsc',
sourceRegex: sourceRegex.replace(new RegExp((0, _escaperegexp.escapeStringRegexp)('(?:/)?$')), // Now than the upstream issues has been resolved, we can safely
// add the suffix back, this resolves a bug related to segment
// rewrites not capturing the correct suffix values when
// enabled.
shouldSkipSuffixes ? '(?<rscSuffix>\\.rsc|\\.segments/.+\\.segment\\.rsc)(?:/)?$' : '(?<rscSuffix>\\.rsc|\\.prefetch\\.rsc|\\.segments/.+\\.segment\\.rsc)(?:/)?$'),
destination: destination == null ? void 0 : destination.replace(/($|\?)/, '$rscSuffix$1'),
has: isFallbackFalse ? fallbackFalseHasCondition : undefined,
missing: undefined
});
}
// needs basePath and locale handling if pages router
dynamicRoutes.push({
source: route.page,
sourceRegex,
destination,
has: isFallbackFalse ? fallbackFalseHasCondition : undefined,
missing: undefined
});
for (const segmentRoute of route.prefetchSegmentDataRoutes || []){
dynamicSegmentRoutes.push({
source: route.page,
sourceRegex: segmentRoute.source.replace('^', `^${config.basePath && config.basePath !== '/' ? _path.default.posix.join('/', config.basePath || '') : ''}[/]?`),
destination: _path.default.posix.join('/', config.basePath, segmentRoute.destination + getDestinationQuery(segmentRoute.routeKeys)),
has: undefined,
missing: undefined
});
}
}
const needsMiddlewareResolveRoutes = outputs.middleware && outputs.pages.length > 0;
const dataRoutePages = new Set([
...routesManifest.dataRoutes.map((item)=>item.page)
]);
const sortedDataPages = (0, _sortableroutes.sortSortableRoutes)([
...needsMiddlewareResolveRoutes ? [
...staticPages
].map((page)=>({
sourcePage: page,
page
})) : [],
...routesManifest.dataRoutes.map((item)=>({
sourcePage: item.page,
page: item.page
}))
]);
for (const { page } of sortedDataPages){
if (needsMiddlewareResolveRoutes || (0, _utils1.isDynamicRoute)(page)) {
var _prerenderManifest_dynamicRoutes_page;
const shouldLocalize = config.i18n;
const isFallbackFalse = ((_prerenderManifest_dynamicRoutes_page = prerenderManifest.dynamicRoutes[page]) == null ? void 0 : _prerenderManifest_dynamicRoutes_page.fallback) === false;
const routeRegex = (0, _routeregex.getNamedRouteRegex)(page + '.json', {
prefixRouteKeys: true,
includeSuffix: true
});
const isDataRoute = dataRoutePages.has(page);
const destination = _path.default.posix.join('/', config.basePath, ...isDataRoute ? [
`_next/data`,
buildId
] : '', ...page === '/' ? [
shouldLocalize ? '$nextLocale.json' : 'index.json'
] : [
shouldLocalize ? '$nextLocale' : '',
page + (isDataRoute ? '.json' : '') + getDestinationQuery(routeRegex.routeKeys || {})
]);
dynamicDataRoutes.push({
source: page,
sourceRegex: shouldLocalize && page === '/' ? '^' + _path.default.posix.join('/', config.basePath, '_next/data', (0, _escaperegexp.escapeStringRegexp)(buildId), '(?<nextLocale>[^/]{1,}).json') : routeRegex.namedRegex.replace('^', `^${_path.default.posix.join('/', config.basePath, `_next/data`, (0, _escaperegexp.escapeStringRegexp)(buildId))}[/]?${shouldLocalize ? '(?<nextLocale>[^/]{1,})?' : ''}`),
destination,
has: isFallbackFalse ? fallbackFalseHasCondition : undefined,
missing: undefined
});
}
}
const buildRewriteItem = (route)=>{
const converted = (0, _routingutils.convertRewrites)([
route
], [
'nextInternalLocale'
])[0];
const regex = converted.src || route.regex;
return {
source: route.source,
sourceRegex: route.internal ? regex : (0, _redirectstatus.modifyRouteRegex)(regex),
destination: converted.dest || route.destination,
has: route.has,
missing: route.missing
};
};
try {
_log.info(`Running onBuildComplete from ${adapterMod.name}`);
await adapterMod.onBuildComplete({
routes: {
dynamicRoutes: [
...dynamicDataRoutes,
...dynamicSegmentRoutes,
...dynamicRoutes
],
rewrites: {
beforeFiles: routesManifest.rewrites.beforeFiles.map(buildRewriteItem),
afterFiles: routesManifest.rewrites.afterFiles.map(buildRewriteItem),
fallback: routesManifest.rewrites.fallback.map(buildRewriteItem)
},
redirects: routesManifest.redirects.map((route)=>{
var _converted_headers;
const converted = (0, _routingutils.convertRedirects)([
route
], 307)[0];
let dest = 'headers' in converted && ((_converted_headers = converted.headers) == null ? void 0 : _converted_headers.Location);
const regex = converted.src || route.regex;
return {
source: route.source,
sourceRegex: route.internal ? regex : (0, _redirectstatus.modifyRouteRegex)(regex),
destination: dest || route.destination,
statusCode: converted.status || (0, _redirectstatus.getRedirectStatus)(route),
has: route.has,
missing: route.missing,
priority: route.internal || undefined
};
}),
headers: routesManifest.headers.map((route)=>{
const converted = (0, _routingutils.convertHeaders)([
route
])[0];
const regex = converted.src || route.regex;
return {
source: route.source,
sourceRegex: route.internal ? regex : (0, _redirectstatus.modifyRouteRegex)(regex),
headers: 'headers' in converted ? converted.headers || {} : {},
has: route.has,
missing: route.missing,
priority: route.internal || undefined
};
})
},
outputs,
config,
distDir,
buildId,
nextVersion,
projectDir: dir,
repoRoot: tracingRoot
});
} catch (err) {
_log.error(`Failed to run onBuildComplete from ${adapterMod.name}`);
throw err;
}
}
}
//# sourceMappingURL=build-complete.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
import type { NextConfigComplete } from '../server/config-shared';
import type { Span } from '../trace';
import type { Telemetry } from '../telemetry/storage';
export declare function runAfterProductionCompile({ config, buildSpan, telemetry, metadata, }: {
config: NextConfigComplete;
buildSpan: Span;
telemetry: Telemetry;
metadata: {
projectDir: string;
distDir: string;
};
}): Promise<void>;

View File

@@ -0,0 +1,95 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "runAfterProductionCompile", {
enumerable: true,
get: function() {
return runAfterProductionCompile;
}
});
const _log = /*#__PURE__*/ _interop_require_wildcard(require("./output/log"));
const _spinner = /*#__PURE__*/ _interop_require_default(require("./spinner"));
const _iserror = /*#__PURE__*/ _interop_require_default(require("../lib/is-error"));
const _build = require("../telemetry/events/build");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
async function runAfterProductionCompile({ config, buildSpan, telemetry, metadata }) {
const run = config.compiler.runAfterProductionCompile;
if (!run) {
return;
}
telemetry.record([
{
eventName: _build.EVENT_BUILD_FEATURE_USAGE,
payload: {
featureName: 'runAfterProductionCompile',
invocationCount: 1
}
}
]);
const afterBuildSpinner = (0, _spinner.default)('Running next.config.js provided runAfterProductionCompile');
try {
const startTime = performance.now();
await buildSpan.traceChild('after-production-compile').traceAsyncFn(async ()=>{
await run(metadata);
});
const duration = performance.now() - startTime;
const formattedDuration = `${Math.round(duration)}ms`;
_log.event(`Completed runAfterProductionCompile in ${formattedDuration}`);
} catch (err) {
// Handle specific known errors differently if needed
if ((0, _iserror.default)(err)) {
_log.error(`Failed to run runAfterProductionCompile: ${err.message}`);
}
throw err;
} finally{
afterBuildSpinner == null ? void 0 : afterBuildSpinner.stop();
}
}
//# sourceMappingURL=after-production-compile.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../src/build/after-production-compile.ts"],"sourcesContent":["import type { NextConfigComplete } from '../server/config-shared'\nimport type { Span } from '../trace'\n\nimport * as Log from './output/log'\nimport createSpinner from './spinner'\nimport isError from '../lib/is-error'\nimport type { Telemetry } from '../telemetry/storage'\nimport { EVENT_BUILD_FEATURE_USAGE } from '../telemetry/events/build'\n\n// TODO: refactor this to account for more compiler lifecycle events\n// such as beforeProductionBuild, but for now this is the only one that is needed\nexport async function runAfterProductionCompile({\n config,\n buildSpan,\n telemetry,\n metadata,\n}: {\n config: NextConfigComplete\n buildSpan: Span\n telemetry: Telemetry\n metadata: {\n projectDir: string\n distDir: string\n }\n}): Promise<void> {\n const run = config.compiler.runAfterProductionCompile\n if (!run) {\n return\n }\n telemetry.record([\n {\n eventName: EVENT_BUILD_FEATURE_USAGE,\n payload: {\n featureName: 'runAfterProductionCompile',\n invocationCount: 1,\n },\n },\n ])\n const afterBuildSpinner = createSpinner(\n 'Running next.config.js provided runAfterProductionCompile'\n )\n\n try {\n const startTime = performance.now()\n await buildSpan\n .traceChild('after-production-compile')\n .traceAsyncFn(async () => {\n await run(metadata)\n })\n const duration = performance.now() - startTime\n const formattedDuration = `${Math.round(duration)}ms`\n Log.event(`Completed runAfterProductionCompile in ${formattedDuration}`)\n } catch (err) {\n // Handle specific known errors differently if needed\n if (isError(err)) {\n Log.error(`Failed to run runAfterProductionCompile: ${err.message}`)\n }\n\n throw err\n } finally {\n afterBuildSpinner?.stop()\n }\n}\n"],"names":["runAfterProductionCompile","config","buildSpan","telemetry","metadata","run","compiler","record","eventName","EVENT_BUILD_FEATURE_USAGE","payload","featureName","invocationCount","afterBuildSpinner","createSpinner","startTime","performance","now","traceChild","traceAsyncFn","duration","formattedDuration","Math","round","Log","event","err","isError","error","message","stop"],"mappings":";;;;+BAWsBA;;;eAAAA;;;6DARD;gEACK;gEACN;uBAEsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAInC,eAAeA,0BAA0B,EAC9CC,MAAM,EACNC,SAAS,EACTC,SAAS,EACTC,QAAQ,EAST;IACC,MAAMC,MAAMJ,OAAOK,QAAQ,CAACN,yBAAyB;IACrD,IAAI,CAACK,KAAK;QACR;IACF;IACAF,UAAUI,MAAM,CAAC;QACf;YACEC,WAAWC,gCAAyB;YACpCC,SAAS;gBACPC,aAAa;gBACbC,iBAAiB;YACnB;QACF;KACD;IACD,MAAMC,oBAAoBC,IAAAA,gBAAa,EACrC;IAGF,IAAI;QACF,MAAMC,YAAYC,YAAYC,GAAG;QACjC,MAAMf,UACHgB,UAAU,CAAC,4BACXC,YAAY,CAAC;YACZ,MAAMd,IAAID;QACZ;QACF,MAAMgB,WAAWJ,YAAYC,GAAG,KAAKF;QACrC,MAAMM,oBAAoB,GAAGC,KAAKC,KAAK,CAACH,UAAU,EAAE,CAAC;QACrDI,KAAIC,KAAK,CAAC,CAAC,uCAAuC,EAAEJ,mBAAmB;IACzE,EAAE,OAAOK,KAAK;QACZ,qDAAqD;QACrD,IAAIC,IAAAA,gBAAO,EAACD,MAAM;YAChBF,KAAII,KAAK,CAAC,CAAC,yCAAyC,EAAEF,IAAIG,OAAO,EAAE;QACrE;QAEA,MAAMH;IACR,SAAU;QACRb,qCAAAA,kBAAmBiB,IAAI;IACzB;AACF","ignoreList":[0]}

View File

@@ -0,0 +1,23 @@
import type { Module } from '@swc/core';
export declare class NoSuchDeclarationError extends Error {
}
export declare class UnsupportedValueError extends Error {
/** @example `config.runtime[0].value` */
path?: string;
constructor(message: string, paths?: string[]);
}
/**
* Extracts the value of an exported const variable named `exportedName`
* (e.g. "export const config = { runtime: 'edge' }") from swc's AST.
* The value must be one of (or throws UnsupportedValueError):
* - string
* - boolean
* - number
* - null
* - undefined
* - array containing values listed in this list
* - object containing values listed in this list
*
* Throws NoSuchDeclarationError if the declaration is not found.
*/
export declare function extractExportedConstValue(module: Module, exportedName: string): any;

View File

@@ -0,0 +1,205 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
NoSuchDeclarationError: null,
UnsupportedValueError: null,
extractExportedConstValue: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
NoSuchDeclarationError: function() {
return NoSuchDeclarationError;
},
UnsupportedValueError: function() {
return UnsupportedValueError;
},
extractExportedConstValue: function() {
return extractExportedConstValue;
}
});
class NoSuchDeclarationError extends Error {
}
function isExportDeclaration(node) {
return node.type === 'ExportDeclaration';
}
function isVariableDeclaration(node) {
return node.type === 'VariableDeclaration';
}
function isIdentifier(node) {
return node.type === 'Identifier';
}
function isBooleanLiteral(node) {
return node.type === 'BooleanLiteral';
}
function isNullLiteral(node) {
return node.type === 'NullLiteral';
}
function isStringLiteral(node) {
return node.type === 'StringLiteral';
}
function isNumericLiteral(node) {
return node.type === 'NumericLiteral';
}
function isArrayExpression(node) {
return node.type === 'ArrayExpression';
}
function isObjectExpression(node) {
return node.type === 'ObjectExpression';
}
function isKeyValueProperty(node) {
return node.type === 'KeyValueProperty';
}
function isRegExpLiteral(node) {
return node.type === 'RegExpLiteral';
}
function isTemplateLiteral(node) {
return node.type === 'TemplateLiteral';
}
function isTsSatisfiesExpression(node) {
return node.type === 'TsSatisfiesExpression';
}
class UnsupportedValueError extends Error {
constructor(message, paths){
super(message);
// Generating "path" that looks like "config.runtime[0].value"
let codePath;
if (paths) {
codePath = '';
for (const path of paths){
if (path[0] === '[') {
// "array" + "[0]"
codePath += path;
} else {
if (codePath === '') {
codePath = path;
} else {
// "object" + ".key"
codePath += `.${path}`;
}
}
}
}
this.path = codePath;
}
}
function extractValue(node, path) {
if (isNullLiteral(node)) {
return null;
} else if (isBooleanLiteral(node)) {
// e.g. true / false
return node.value;
} else if (isStringLiteral(node)) {
// e.g. "abc"
return node.value;
} 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':
return undefined;
default:
throw new UnsupportedValueError(`Unknown identifier "${node.value}"`, path);
}
} else if (isArrayExpression(node)) {
// e.g. [1, 2, 3]
const arr = [];
for(let i = 0, len = node.elements.length; i < len; i++){
const elem = node.elements[i];
if (elem) {
if (elem.spread) {
// e.g. [ ...a ]
throw new UnsupportedValueError('Unsupported spread operator in the Array Expression', path);
}
arr.push(extractValue(elem.expression, path && [
...path,
`[${i}]`
]));
} else {
// e.g. [1, , 2]
// ^^
arr.push(undefined);
}
}
return arr;
} else if (isObjectExpression(node)) {
// e.g. { a: 1, b: 2 }
const obj = {};
for (const prop of node.properties){
if (!isKeyValueProperty(prop)) {
// e.g. { ...a }
throw new UnsupportedValueError('Unsupported spread operator in the Object Expression', path);
}
let key;
if (isIdentifier(prop.key)) {
// e.g. { a: 1, b: 2 }
key = prop.key.value;
} else if (isStringLiteral(prop.key)) {
// e.g. { "a": 1, "b": 2 }
key = prop.key.value;
} else {
throw new UnsupportedValueError(`Unsupported key type "${prop.key.type}" in the Object Expression`, path);
}
obj[key] = extractValue(prop.value, path && [
...path,
key
]);
}
return obj;
} else if (isTemplateLiteral(node)) {
// e.g. `abc`
if (node.expressions.length !== 0) {
// TODO: should we add support for `${'e'}d${'g'}'e'`?
throw new UnsupportedValueError('Unsupported template literal with expressions', path);
}
// When TemplateLiteral has 0 expressions, the length of quasis is always 1.
// Because when parsing TemplateLiteral, the parser yields the first quasi,
// then the first expression, then the next quasi, then the next expression, etc.,
// until the last quasi.
// Thus if there is no expression, the parser ends at the frst and also last quasis
//
// A "cooked" interpretation where backslashes have special meaning, while a
// "raw" interpretation where backslashes do not have special meaning
// https://exploringjs.com/impatient-js/ch_template-literals.html#template-strings-cooked-vs-raw
const [{ cooked, raw }] = node.quasis;
return cooked ?? raw;
} else if (isTsSatisfiesExpression(node)) {
return extractValue(node.expression);
} else {
throw new UnsupportedValueError(`Unsupported node type "${node.type}"`, path);
}
}
function extractExportedConstValue(module1, exportedName) {
for (const moduleItem of module1.body){
if (!isExportDeclaration(moduleItem)) {
continue;
}
const declaration = moduleItem.declaration;
if (!isVariableDeclaration(declaration)) {
continue;
}
if (declaration.kind !== 'const') {
continue;
}
for (const decl of declaration.declarations){
if (isIdentifier(decl.id) && decl.id.value === exportedName && decl.init) {
return extractValue(decl.init, [
exportedName
]);
}
}
}
throw new NoSuchDeclarationError();
}
//# sourceMappingURL=extract-const-value.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,82 @@
import type { NextConfig } from '../../server/config-shared';
import type { RouteHas } from '../../lib/load-custom-routes';
import type { RSCMeta } from '../webpack/loaders/get-module-build-info';
import { PAGE_TYPES } from '../../lib/page-types';
import { type AppSegmentConfig } from '../segment-config/app/app-segment-config';
import { type PagesSegmentConfig, type PagesSegmentConfigConfig } from '../segment-config/pages/pages-segment-config';
export type ProxyMatcher = {
regexp: string;
locale?: false;
has?: RouteHas[];
missing?: RouteHas[];
originalSource: string;
};
export type ProxyConfig = {
/**
* The matcher for the proxy. Read more: [Next.js Docs: Proxy `matcher`](https://nextjs.org/docs/app/api-reference/file-conventions/proxy#matcher),
* [Next.js Docs: Proxy matching paths](https://nextjs.org/docs/app/building-your-application/routing/proxy#matching-paths)
*/
matchers?: ProxyMatcher[];
/**
* The regions that the proxy should run in.
*/
regions?: string | string[];
/**
* A glob, or an array of globs, ignoring dynamic code evaluation for specific
* files. The globs are relative to your application root folder.
*/
unstable_allowDynamic?: string[];
};
export interface AppPageStaticInfo {
type: PAGE_TYPES.APP;
ssg?: boolean;
ssr?: boolean;
rsc?: RSCModuleType;
generateStaticParams?: boolean;
generateSitemaps?: boolean;
generateImageMetadata?: boolean;
middleware?: ProxyConfig;
config: Omit<AppSegmentConfig, 'runtime' | 'maxDuration'> | undefined;
runtime: AppSegmentConfig['runtime'] | undefined;
preferredRegion: AppSegmentConfig['preferredRegion'] | undefined;
maxDuration: number | undefined;
hadUnsupportedValue: boolean;
}
export interface PagesPageStaticInfo {
type: PAGE_TYPES.PAGES;
getStaticProps?: boolean;
getServerSideProps?: boolean;
rsc?: RSCModuleType;
generateStaticParams?: boolean;
generateSitemaps?: boolean;
generateImageMetadata?: boolean;
middleware?: ProxyConfig;
config: (Omit<PagesSegmentConfig, 'runtime' | 'config' | 'maxDuration'> & {
config?: Omit<PagesSegmentConfigConfig, 'runtime' | 'maxDuration'>;
}) | undefined;
runtime: PagesSegmentConfig['runtime'] | undefined;
preferredRegion: PagesSegmentConfigConfig['regions'] | undefined;
maxDuration: number | undefined;
hadUnsupportedValue: boolean;
}
export type PageStaticInfo = AppPageStaticInfo | PagesPageStaticInfo;
export type RSCModuleType = 'server' | 'client';
export declare function getRSCModuleInformation(source: string, isReactServerLayer: boolean): RSCMeta;
type GetPageStaticInfoParams = {
pageFilePath: string;
nextConfig: Partial<NextConfig>;
isDev: boolean;
page: string;
pageType: PAGE_TYPES;
};
export declare function getAppPageStaticInfo({ pageFilePath, nextConfig, isDev, page, }: GetPageStaticInfoParams): Promise<AppPageStaticInfo>;
export declare function getPagesPageStaticInfo({ pageFilePath, nextConfig, isDev, page, }: GetPageStaticInfoParams): Promise<PagesPageStaticInfo>;
/**
* 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 declare function getPageStaticInfo(params: GetPageStaticInfoParams): Promise<PageStaticInfo>;
export {};

View File

@@ -0,0 +1,601 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
getAppPageStaticInfo: null,
getMiddlewareMatchers: null,
getPageStaticInfo: null,
getPagesPageStaticInfo: null,
getRSCModuleInformation: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
getAppPageStaticInfo: function() {
return getAppPageStaticInfo;
},
getMiddlewareMatchers: function() {
return getMiddlewareMatchers;
},
getPageStaticInfo: function() {
return getPageStaticInfo;
},
getPagesPageStaticInfo: function() {
return getPagesPageStaticInfo;
},
getRSCModuleInformation: function() {
return getRSCModuleInformation;
}
});
const _fs = require("fs");
const _path = require("path");
const _lrucache = require("../../server/lib/lru-cache");
const _extractconstvalue = require("./extract-const-value");
const _parsemodule = require("./parse-module");
const _log = /*#__PURE__*/ _interop_require_wildcard(require("../output/log"));
const _constants = require("../../lib/constants");
const _trytoparsepath = require("../../lib/try-to-parse-path");
const _isapiroute = require("../../lib/is-api-route");
const _isedgeruntime = require("../../lib/is-edge-runtime");
const _constants1 = require("../../shared/lib/constants");
const _pagetypes = require("../../lib/page-types");
const _appsegmentconfig = require("../segment-config/app/app-segment-config");
const _zod = require("../../shared/lib/zod");
const _pagessegmentconfig = require("../segment-config/pages/pages-segment-config");
const _middlewareconfig = require("../segment-config/middleware/middleware-config");
const _apppaths = require("../../shared/lib/router/utils/app-paths");
const _normalizepagepath = require("../../shared/lib/page-path/normalize-page-path");
const _utils = require("../utils");
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
const PARSE_PATTERN = /(?<!(_jsx|jsx-))runtime|preferredRegion|getStaticProps|getServerSideProps|generateStaticParams|export const|generateImageMetadata|generateSitemaps|middleware|proxy/;
const CLIENT_MODULE_LABEL = /\/\* __next_internal_client_entry_do_not_use__ ([^ ]*) (cjs|auto) \*\//;
const ACTION_MODULE_LABEL = /\/\* __next_internal_action_entry_do_not_use__ (\{[^}]+\}) \*\//;
const CLIENT_DIRECTIVE = 'use client';
const SERVER_ACTION_DIRECTIVE = 'use server';
function getRSCModuleInformation(source, isReactServerLayer) {
const actionsJson = source.match(ACTION_MODULE_LABEL);
const parsedActionsMeta = actionsJson ? JSON.parse(actionsJson[1]) : undefined;
const clientInfoMatch = source.match(CLIENT_MODULE_LABEL);
const isClientRef = !!clientInfoMatch;
if (!isReactServerLayer) {
return {
type: _constants1.RSC_MODULE_TYPES.client,
actionIds: parsedActionsMeta,
isClientRef
};
}
const clientRefsString = clientInfoMatch == null ? void 0 : clientInfoMatch[1];
const clientRefs = clientRefsString ? clientRefsString.split(',') : [];
const clientEntryType = clientInfoMatch == null ? void 0 : clientInfoMatch[2];
const type = clientInfoMatch ? _constants1.RSC_MODULE_TYPES.client : _constants1.RSC_MODULE_TYPES.server;
return {
type,
actionIds: parsedActionsMeta,
clientRefs,
clientEntryType,
isClientRef
};
}
/**
* 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 ...>`
* - Modules with `export const runtime = ...`
*/ function checkExports(ast, expectedExports, page) {
const exportsSet = new Set([
'getStaticProps',
'getServerSideProps',
'generateImageMetadata',
'generateSitemaps',
'generateStaticParams'
]);
if (!Array.isArray(ast == null ? void 0 : ast.body)) {
return {};
}
try {
let getStaticProps = false;
let getServerSideProps = false;
let generateImageMetadata = false;
let generateSitemaps = false;
let generateStaticParams = false;
let exports1 = new Set();
let directives = new Set();
let hasLeadingNonDirectiveNode = false;
for (const node of ast.body){
var _node_declaration, _node_declaration1, _node_declaration_identifier, _node_declaration2;
// There should be no non-string literals nodes before directives
if (node.type === 'ExpressionStatement' && node.expression.type === 'StringLiteral') {
if (!hasLeadingNonDirectiveNode) {
const directive = node.expression.value;
if (CLIENT_DIRECTIVE === directive) {
directives.add('client');
}
if (SERVER_ACTION_DIRECTIVE === directive) {
directives.add('server');
}
}
} else {
hasLeadingNonDirectiveNode = true;
}
if (node.type === 'ExportDeclaration' && ((_node_declaration = node.declaration) == null ? void 0 : _node_declaration.type) === 'VariableDeclaration') {
var _node_declaration3;
for (const declaration of (_node_declaration3 = node.declaration) == null ? void 0 : _node_declaration3.declarations){
if (expectedExports.includes(declaration.id.value)) {
exports1.add(declaration.id.value);
}
}
}
if (node.type === 'ExportDeclaration' && ((_node_declaration1 = node.declaration) == null ? void 0 : _node_declaration1.type) === 'FunctionDeclaration' && exportsSet.has((_node_declaration_identifier = node.declaration.identifier) == null ? void 0 : _node_declaration_identifier.value)) {
const id = node.declaration.identifier.value;
getServerSideProps = id === 'getServerSideProps';
getStaticProps = id === 'getStaticProps';
generateImageMetadata = id === 'generateImageMetadata';
generateSitemaps = id === 'generateSitemaps';
generateStaticParams = id === 'generateStaticParams';
}
if (node.type === 'ExportDeclaration' && ((_node_declaration2 = node.declaration) == null ? void 0 : _node_declaration2.type) === 'VariableDeclaration') {
var _node_declaration_declarations_, _node_declaration4;
const id = (_node_declaration4 = node.declaration) == null ? void 0 : (_node_declaration_declarations_ = _node_declaration4.declarations[0]) == null ? void 0 : _node_declaration_declarations_.id.value;
if (exportsSet.has(id)) {
getServerSideProps = id === 'getServerSideProps';
getStaticProps = id === 'getStaticProps';
generateImageMetadata = id === 'generateImageMetadata';
generateSitemaps = id === 'generateSitemaps';
generateStaticParams = id === 'generateStaticParams';
}
}
if (node.type === 'ExportNamedDeclaration') {
for (const specifier of node.specifiers){
var _specifier_orig;
if (specifier.type === 'ExportSpecifier' && ((_specifier_orig = specifier.orig) == null ? void 0 : _specifier_orig.type) === 'Identifier') {
const value = specifier.orig.value;
if (!getServerSideProps && value === 'getServerSideProps') {
getServerSideProps = true;
}
if (!getStaticProps && value === 'getStaticProps') {
getStaticProps = true;
}
if (!generateImageMetadata && value === 'generateImageMetadata') {
generateImageMetadata = true;
}
if (!generateSitemaps && value === 'generateSitemaps') {
generateSitemaps = true;
}
if (!generateStaticParams && value === 'generateStaticParams') {
generateStaticParams = true;
}
if (expectedExports.includes(value) && !exports1.has(value)) {
// An export was found that was actually a re-export, and not a
// literal value. We should warn here.
_log.warn(`Next.js can't recognize the exported \`${value}\` field in "${page}", it may be re-exported from another file. The default config will be used instead.`);
}
}
}
}
}
return {
getStaticProps,
getServerSideProps,
generateImageMetadata,
generateSitemaps,
generateStaticParams,
directives,
exports: exports1
};
} catch {}
return {};
}
function validateMiddlewareProxyExports({ ast, page, pageFilePath, isDev }) {
// Check if this is middleware/proxy
const isMiddleware = page === `/${_constants.MIDDLEWARE_FILENAME}` || page === `/src/${_constants.MIDDLEWARE_FILENAME}`;
const isProxy = page === `/${_constants.PROXY_FILENAME}` || page === `/src/${_constants.PROXY_FILENAME}`;
if (!isMiddleware && !isProxy) {
return;
}
if (!ast || !Array.isArray(ast.body)) {
return;
}
const fileName = isProxy ? _constants.PROXY_FILENAME : _constants.MIDDLEWARE_FILENAME;
// Parse AST to get export info (since checkExports doesn't return middleware/proxy info)
let hasDefaultExport = false;
let hasMiddlewareExport = false;
let hasProxyExport = false;
for (const node of ast.body){
var _node_declaration, _node_declaration1;
if (node.type === 'ExportDefaultDeclaration' || node.type === 'ExportDefaultExpression') {
hasDefaultExport = true;
}
if (node.type === 'ExportDeclaration' && ((_node_declaration = node.declaration) == null ? void 0 : _node_declaration.type) === 'FunctionDeclaration') {
var _node_declaration_identifier;
const id = (_node_declaration_identifier = node.declaration.identifier) == null ? void 0 : _node_declaration_identifier.value;
if (id === 'middleware') {
hasMiddlewareExport = true;
}
if (id === 'proxy') {
hasProxyExport = true;
}
}
if (node.type === 'ExportDeclaration' && ((_node_declaration1 = node.declaration) == null ? void 0 : _node_declaration1.type) === 'VariableDeclaration') {
var _node_declaration_declarations_, _node_declaration2;
const id = (_node_declaration2 = node.declaration) == null ? void 0 : (_node_declaration_declarations_ = _node_declaration2.declarations[0]) == null ? void 0 : _node_declaration_declarations_.id.value;
if (id === 'middleware') {
hasMiddlewareExport = true;
}
if (id === 'proxy') {
hasProxyExport = true;
}
}
if (node.type === 'ExportNamedDeclaration') {
for (const specifier of node.specifiers){
var _specifier_orig;
if (specifier.type === 'ExportSpecifier' && ((_specifier_orig = specifier.orig) == null ? void 0 : _specifier_orig.type) === 'Identifier') {
// Use the exported name if it exists (for aliased exports like `export { foo as proxy }`),
// otherwise fall back to the original name (for simple re-exports like `export { proxy }`)
const exportedIdentifier = specifier.exported || specifier.orig;
const value = exportedIdentifier.value;
if (value === 'middleware') {
hasMiddlewareExport = true;
}
if (value === 'proxy') {
hasProxyExport = true;
}
}
}
}
}
const hasValidExport = hasDefaultExport || isMiddleware && hasMiddlewareExport || isProxy && hasProxyExport;
const relativePath = (0, _path.relative)(process.cwd(), pageFilePath);
const resolvedPath = relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
if (!hasValidExport) {
const message = `The file "${resolvedPath}" must export a function, either as a default export or as a named "${fileName}" export.\n` + `This function is what Next.js runs for every request handled by this ${fileName === 'proxy' ? 'proxy (previously called middleware)' : 'middleware'}.\n\n` + `Why this happens:\n` + (isProxy ? "- You are migrating from `middleware` to `proxy`, but haven't updated the exported function.\n" : '') + `- The file exists but doesn't export a function.\n` + `- The export is not a function (e.g., an object or constant).\n` + `- There's a syntax error preventing the export from being recognized.\n\n` + `To fix it:\n` + `- Ensure this file has either a default or "${fileName}" function export.\n\n` + `Learn more: https://nextjs.org/docs/messages/middleware-to-proxy`;
if (isDev) {
// errorOnce as proxy/middleware runs per request including multiple
// internal _next/ routes and spams logs.
_log.errorOnce(message);
} else {
throw Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
}
}
async function tryToReadFile(filePath, shouldThrow) {
try {
return await _fs.promises.readFile(filePath, {
encoding: 'utf8'
});
} catch (error) {
if (shouldThrow) {
error.message = `Next.js ERROR: Failed to read file ${filePath}:\n${error.message}`;
throw error;
}
}
}
function getMiddlewareMatchers(matcherOrMatchers, nextConfig) {
const matchers = Array.isArray(matcherOrMatchers) ? matcherOrMatchers : [
matcherOrMatchers
];
const { i18n } = nextConfig;
return matchers.map((matcher)=>{
matcher = typeof matcher === 'string' ? {
source: matcher
} : matcher;
const originalSource = matcher.source;
let { source, ...rest } = matcher;
const isRoot = source === '/';
if ((i18n == null ? void 0 : i18n.locales) && matcher.locale !== false) {
source = `/:nextInternalLocale((?!_next/)[^/.]{1,})${isRoot ? '' : source}`;
}
source = `/:nextData(_next/data/[^/]{1,})?${source}${isRoot ? `(${nextConfig.i18n ? '|\\.json|' : ''}/?index|/?index\\.json)?` : '{(\\.json)}?'}`;
if (nextConfig.basePath) {
source = `${nextConfig.basePath}${source}`;
}
// Validate that the source is still.
const result = _middlewareconfig.SourceSchema.safeParse(source);
if (!result.success) {
(0, _zod.reportZodError)('Failed to parse middleware source', result.error);
// We need to exit here because middleware being built occurs before we
// finish setting up the server. Exiting here is the only way to ensure
// that we don't hang.
process.exit(1);
}
return {
...rest,
// We know that parsed.regexStr is not undefined because we already
// checked that the source is valid.
regexp: (0, _trytoparsepath.tryToParsePath)(result.data).regexStr,
originalSource: originalSource || source
};
});
}
function parseMiddlewareConfig(page, rawConfig, nextConfig) {
// If there's no config to parse, then return nothing.
if (typeof rawConfig !== 'object' || !rawConfig) return {};
const input = _middlewareconfig.MiddlewareConfigInputSchema.safeParse(rawConfig);
if (!input.success) {
(0, _zod.reportZodError)(`${page} contains invalid middleware config`, input.error);
// We need to exit here because middleware being built occurs before we
// finish setting up the server. Exiting here is the only way to ensure
// that we don't hang.
process.exit(1);
}
const config = {};
if (input.data.matcher) {
config.matchers = getMiddlewareMatchers(input.data.matcher, nextConfig);
}
if (input.data.unstable_allowDynamic) {
config.unstable_allowDynamic = Array.isArray(input.data.unstable_allowDynamic) ? input.data.unstable_allowDynamic : [
input.data.unstable_allowDynamic
];
}
if (input.data.regions) {
config.regions = input.data.regions;
}
return config;
}
const apiRouteWarnings = new _lrucache.LRUCache(250);
function warnAboutExperimentalEdge(apiRoute) {
if (process.env.NODE_ENV === 'production' && process.env.NEXT_PRIVATE_BUILD_WORKER === '1') {
return;
}
if (apiRoute && apiRouteWarnings.has(apiRoute)) {
return;
}
_log.warn(apiRoute ? `${apiRoute} provided runtime 'experimental-edge'. It can be updated to 'edge' instead.` : `You are using an experimental edge runtime, the API might change.`);
if (apiRoute) {
apiRouteWarnings.set(apiRoute, 1);
}
}
let hadUnsupportedValue = false;
const warnedUnsupportedValueMap = new _lrucache.LRUCache(250, ()=>1);
function warnAboutUnsupportedValue(pageFilePath, page, error) {
hadUnsupportedValue = true;
const isProductionBuild = process.env.NODE_ENV === 'production';
if (// we only log for the server compilation so it's not
// duplicated due to webpack build worker having fresh
// module scope for each compiler
process.env.NEXT_COMPILER_NAME !== 'server' || isProductionBuild && warnedUnsupportedValueMap.has(pageFilePath)) {
return;
}
warnedUnsupportedValueMap.set(pageFilePath, true);
const message = `Next.js can't recognize the exported \`config\` field in ` + (page ? `route "${page}"` : `"${pageFilePath}"`) + ':\n' + error.message + (error.path ? ` at "${error.path}"` : '') + '.\n' + 'Read More - https://nextjs.org/docs/messages/invalid-page-config';
// for a build we use `Log.error` instead of throwing
// so that all errors can be logged before exiting the process
if (isProductionBuild) {
_log.error(message);
} else {
throw Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
}
async function getAppPageStaticInfo({ pageFilePath, nextConfig, isDev, page }) {
const content = await tryToReadFile(pageFilePath, !isDev);
if (!content || !PARSE_PATTERN.test(content)) {
return {
type: _pagetypes.PAGE_TYPES.APP,
config: undefined,
runtime: undefined,
preferredRegion: undefined,
maxDuration: undefined,
hadUnsupportedValue: false
};
}
const ast = await (0, _parsemodule.parseModule)(pageFilePath, content);
validateMiddlewareProxyExports({
ast,
page,
pageFilePath,
isDev
});
const { generateStaticParams, generateImageMetadata, generateSitemaps, exports: exports1, directives } = checkExports(ast, _appsegmentconfig.AppSegmentConfigSchemaKeys, page);
const { type: rsc } = getRSCModuleInformation(content, true);
const exportedConfig = {};
if (exports1) {
for (const property of exports1){
try {
exportedConfig[property] = (0, _extractconstvalue.extractExportedConstValue)(ast, property);
} catch (e) {
if (e instanceof _extractconstvalue.UnsupportedValueError) {
warnAboutUnsupportedValue(pageFilePath, page, e);
}
}
}
}
try {
exportedConfig.config = (0, _extractconstvalue.extractExportedConstValue)(ast, 'config');
} catch (e) {
if (e instanceof _extractconstvalue.UnsupportedValueError) {
warnAboutUnsupportedValue(pageFilePath, page, e);
}
// `export config` doesn't exist, or other unknown error thrown by swc, silence them
}
const route = (0, _apppaths.normalizeAppPath)(page);
const config = (0, _appsegmentconfig.parseAppSegmentConfig)(exportedConfig, route);
// Prevent edge runtime and generateStaticParams in the same file.
if ((0, _isedgeruntime.isEdgeRuntime)(config.runtime) && generateStaticParams) {
throw Object.defineProperty(new Error(`Page "${page}" cannot use both \`export const runtime = 'edge'\` and export \`generateStaticParams\`.`), "__NEXT_ERROR_CODE", {
value: "E42",
enumerable: false,
configurable: true
});
}
// Prevent use client and generateStaticParams in the same file.
if ((directives == null ? void 0 : directives.has('client')) && generateStaticParams) {
throw Object.defineProperty(new Error(`Page "${page}" cannot use both "use client" and export function "generateStaticParams()".`), "__NEXT_ERROR_CODE", {
value: "E475",
enumerable: false,
configurable: true
});
}
if ('unstable_prefetch' in config && !nextConfig.cacheComponents) {
throw Object.defineProperty(new Error(`Page "${page}" cannot use \`export const unstable_prefetch = ...\` without enabling \`cacheComponents\`.`), "__NEXT_ERROR_CODE", {
value: "E905",
enumerable: false,
configurable: true
});
}
return {
type: _pagetypes.PAGE_TYPES.APP,
rsc,
generateImageMetadata,
generateSitemaps,
generateStaticParams,
config,
middleware: parseMiddlewareConfig(page, exportedConfig.config, nextConfig),
runtime: config.runtime,
preferredRegion: config.preferredRegion,
maxDuration: config.maxDuration,
hadUnsupportedValue
};
}
async function getPagesPageStaticInfo({ pageFilePath, nextConfig, isDev, page }) {
var _config_config, _config_config1, _config_config2;
const content = await tryToReadFile(pageFilePath, !isDev);
if (!content || !PARSE_PATTERN.test(content)) {
return {
type: _pagetypes.PAGE_TYPES.PAGES,
config: undefined,
runtime: undefined,
preferredRegion: undefined,
maxDuration: undefined,
hadUnsupportedValue: false
};
}
const ast = await (0, _parsemodule.parseModule)(pageFilePath, content);
validateMiddlewareProxyExports({
ast,
page,
pageFilePath,
isDev
});
const { getServerSideProps, getStaticProps, exports: exports1 } = checkExports(ast, _pagessegmentconfig.PagesSegmentConfigSchemaKeys, page);
const { type: rsc } = getRSCModuleInformation(content, true);
const exportedConfig = {};
if (exports1) {
for (const property of exports1){
try {
exportedConfig[property] = (0, _extractconstvalue.extractExportedConstValue)(ast, property);
} catch (e) {
if (e instanceof _extractconstvalue.UnsupportedValueError) {
warnAboutUnsupportedValue(pageFilePath, page, e);
}
}
}
}
try {
exportedConfig.config = (0, _extractconstvalue.extractExportedConstValue)(ast, 'config');
} catch (e) {
if (e instanceof _extractconstvalue.UnsupportedValueError) {
warnAboutUnsupportedValue(pageFilePath, page, e);
}
// `export config` doesn't exist, or other unknown error thrown by swc, silence them
}
// Validate the config.
const route = (0, _normalizepagepath.normalizePagePath)(page);
const config = (0, _pagessegmentconfig.parsePagesSegmentConfig)(exportedConfig, route);
const isAnAPIRoute = (0, _isapiroute.isAPIRoute)(route);
let resolvedRuntime = config.runtime ?? ((_config_config = config.config) == null ? void 0 : _config_config.runtime);
if ((0, _utils.isProxyFile)(page) && resolvedRuntime) {
const relativePath = (0, _path.relative)(process.cwd(), pageFilePath);
const resolvedPath = relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
const message = `Route segment config is not allowed in Proxy file at "${resolvedPath}". Proxy always runs on Node.js runtime. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy`;
if (isDev) {
// errorOnce as proxy/middleware runs per request including multiple
// internal _next/ routes and spams logs.
_log.errorOnce(message);
resolvedRuntime = _constants.SERVER_RUNTIME.nodejs;
} else {
throw Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
}
if (resolvedRuntime === _constants.SERVER_RUNTIME.experimentalEdge) {
warnAboutExperimentalEdge(isAnAPIRoute ? page : null);
}
if (!(0, _utils.isProxyFile)(page) && resolvedRuntime === _constants.SERVER_RUNTIME.edge && page && !isAnAPIRoute) {
const message = `Page ${page} provided runtime 'edge', the edge runtime for rendering is currently experimental. Use runtime 'experimental-edge' instead.`;
if (isDev) {
_log.error(message);
} else {
throw Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
}
return {
type: _pagetypes.PAGE_TYPES.PAGES,
getStaticProps,
getServerSideProps,
rsc,
config,
middleware: parseMiddlewareConfig(page, exportedConfig.config, nextConfig),
runtime: resolvedRuntime,
preferredRegion: (_config_config1 = config.config) == null ? void 0 : _config_config1.regions,
maxDuration: config.maxDuration ?? ((_config_config2 = config.config) == null ? void 0 : _config_config2.maxDuration),
hadUnsupportedValue
};
}
async function getPageStaticInfo(params) {
if (params.pageType === _pagetypes.PAGE_TYPES.APP) {
return getAppPageStaticInfo(params);
}
return getPagesPageStaticInfo(params);
}
//# sourceMappingURL=get-page-static-info.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
/**
* Parses a module with SWC using an LRU cache where the parsed module will
* be indexed by a sha of its content holding up to 500 entries.
*/
export declare const parseModule: (_: string, content: string) => Promise<any>;

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "parseModule", {
enumerable: true,
get: function() {
return parseModule;
}
});
const _lrucache = require("../../server/lib/lru-cache");
const _withpromisecache = require("../../lib/with-promise-cache");
const _crypto = require("crypto");
const _swc = require("../swc");
const parseModule = (0, _withpromisecache.withPromiseCache)(new _lrucache.LRUCache(500), async (filename, content)=>(0, _swc.parse)(content, {
isModule: 'unknown',
filename
}).catch(()=>null), (_, content)=>(0, _crypto.createHash)('sha1').update(content).digest('hex'));
//# sourceMappingURL=parse-module.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/build/analysis/parse-module.ts"],"sourcesContent":["import { LRUCache } from '../../server/lib/lru-cache'\nimport { withPromiseCache } from '../../lib/with-promise-cache'\nimport { createHash } from 'crypto'\nimport { parse } from '../swc'\n\n/**\n * Parses a module with SWC using an LRU cache where the parsed module will\n * be indexed by a sha of its content holding up to 500 entries.\n */\nexport const parseModule = withPromiseCache(\n new LRUCache<any>(500),\n async (filename: string, content: string) =>\n parse(content, { isModule: 'unknown', filename }).catch(() => null),\n (_, content) => createHash('sha1').update(content).digest('hex')\n)\n"],"names":["parseModule","withPromiseCache","LRUCache","filename","content","parse","isModule","catch","_","createHash","update","digest"],"mappings":";;;;+BASaA;;;eAAAA;;;0BATY;kCACQ;wBACN;qBACL;AAMf,MAAMA,cAAcC,IAAAA,kCAAgB,EACzC,IAAIC,kBAAQ,CAAM,MAClB,OAAOC,UAAkBC,UACvBC,IAAAA,UAAK,EAACD,SAAS;QAAEE,UAAU;QAAWH;IAAS,GAAGI,KAAK,CAAC,IAAM,OAChE,CAACC,GAAGJ,UAAYK,IAAAA,kBAAU,EAAC,QAAQC,MAAM,CAACN,SAASO,MAAM,CAAC","ignoreList":[0]}

View File

@@ -0,0 +1,9 @@
export type AnalyzeOptions = {
dir: string;
reactProductionProfiling?: boolean;
noMangling?: boolean;
appDirOnly?: boolean;
output?: boolean;
port?: number;
};
export default function analyze({ dir, reactProductionProfiling, noMangling, appDirOnly, output, port, }: AnalyzeOptions): Promise<void>;

View File

@@ -0,0 +1,242 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return analyze;
}
});
const _trace = require("../../trace");
const _log = /*#__PURE__*/ _interop_require_wildcard(require("../output/log"));
const _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
const _config = /*#__PURE__*/ _interop_require_default(require("../../server/config"));
const _constants = require("../../shared/lib/constants");
const _turbopackanalyze = require("../turbopack-analyze");
const _durationtostring = require("../duration-to-string");
const _promises = require("node:fs/promises");
const _entries = require("../entries");
const _findpagefile = require("../../server/lib/find-page-file");
const _findpagesdir = require("../../lib/find-pages-dir");
const _pagetypes = require("../../lib/page-types");
const _loadcustomroutes = /*#__PURE__*/ _interop_require_default(require("../../lib/load-custom-routes"));
const _generateroutesmanifest = require("../generate-routes-manifest");
const _ppr = require("../../server/lib/experimental/ppr");
const _apppaths = require("../../shared/lib/router/utils/app-paths");
const _nodehttp = /*#__PURE__*/ _interop_require_default(require("node:http"));
const _servehandler = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/serve-handler"));
const _storage = require("../../telemetry/storage");
const _events = require("../../telemetry/events");
const _shared = require("../../trace/shared");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
async function analyze({ dir, reactProductionProfiling = false, noMangling = false, appDirOnly = false, output = false, port = 4000 }) {
try {
const config = await (0, _config.default)(_constants.PHASE_ANALYZE, dir, {
silent: false,
reactProductionProfiling
});
process.env.NEXT_DEPLOYMENT_ID = config.deploymentId || '';
const distDir = _nodepath.join(dir, '.next');
const telemetry = new _storage.Telemetry({
distDir
});
(0, _trace.setGlobal)('phase', _constants.PHASE_ANALYZE);
(0, _trace.setGlobal)('distDir', distDir);
(0, _trace.setGlobal)('telemetry', telemetry);
_log.info('Analyzing a production build...');
const analyzeContext = {
config,
dir,
distDir,
noMangling,
appDirOnly
};
const { duration: analyzeDuration, shutdownPromise } = await (0, _turbopackanalyze.turbopackAnalyze)(analyzeContext);
const durationString = (0, _durationtostring.durationToString)(analyzeDuration);
const analyzeDir = _nodepath.join(distDir, 'diagnostics/analyze');
await shutdownPromise;
const routes = await collectRoutesForAnalyze(dir, config, appDirOnly);
await (0, _promises.cp)(_nodepath.join(__dirname, '../../bundle-analyzer'), analyzeDir, {
recursive: true
});
await (0, _promises.mkdir)(_nodepath.join(analyzeDir, 'data'), {
recursive: true
});
await (0, _promises.writeFile)(_nodepath.join(analyzeDir, 'data', 'routes.json'), JSON.stringify(routes, null, 2));
let logMessage = `Analyze completed in ${durationString}.`;
if (output) {
logMessage += ` Results written to ${analyzeDir}.\nTo explore the analyze results interactively, run \`next experimental-analyze\` without \`--output\`.`;
}
_log.event(logMessage);
telemetry.record((0, _events.eventAnalyzeCompleted)({
success: true,
durationInSeconds: Math.round(analyzeDuration),
totalPageCount: routes.length
}));
if (!output) {
await startServer(analyzeDir, port);
}
} catch (e) {
const telemetry = _shared.traceGlobals.get('telemetry');
if (telemetry) {
telemetry.record((0, _events.eventAnalyzeCompleted)({
success: false
}));
}
throw e;
}
}
/**
* Collects all routes from the project for the bundle analyzer.
* Returns a list of route paths (both static and dynamic).
*/ async function collectRoutesForAnalyze(dir, config, appDirOnly) {
const { pagesDir, appDir } = (0, _findpagesdir.findPagesDir)(dir);
const validFileMatcher = (0, _findpagefile.createValidFileMatcher)(config.pageExtensions, appDir);
let appType;
if (pagesDir && appDir) {
appType = 'hybrid';
} else if (pagesDir) {
appType = 'pages';
} else if (appDir) {
appType = 'app';
} else {
throw Object.defineProperty(new Error('No pages or app directory found.'), "__NEXT_ERROR_CODE", {
value: "E929",
enumerable: false,
configurable: true
});
}
const { appPaths } = appDir ? await (0, _entries.collectAppFiles)(appDir, validFileMatcher) : {
appPaths: []
};
const pagesPaths = pagesDir ? await (0, _entries.collectPagesFiles)(pagesDir, validFileMatcher) : null;
const appMapping = await (0, _entries.createPagesMapping)({
pagePaths: appPaths,
isDev: false,
pagesType: _pagetypes.PAGE_TYPES.APP,
pageExtensions: config.pageExtensions,
pagesDir,
appDir,
appDirOnly
});
const pagesMapping = pagesPaths ? await (0, _entries.createPagesMapping)({
pagePaths: pagesPaths,
isDev: false,
pagesType: _pagetypes.PAGE_TYPES.PAGES,
pageExtensions: config.pageExtensions,
pagesDir,
appDir,
appDirOnly
}) : null;
const pageKeys = {
pages: pagesMapping ? Object.keys(pagesMapping) : [],
app: appMapping ? Object.keys(appMapping).map((key)=>(0, _apppaths.normalizeAppPath)(key)) : undefined
};
// Load custom routes
const { redirects, headers, rewrites } = await (0, _loadcustomroutes.default)(config);
// Compute restricted redirect paths
const restrictedRedirectPaths = [
'/_next'
].map((pathPrefix)=>config.basePath ? `${config.basePath}${pathPrefix}` : pathPrefix);
const isAppPPREnabled = (0, _ppr.checkIsAppPPREnabled)(config.experimental.ppr);
// Generate routes manifest
const { routesManifest } = (0, _generateroutesmanifest.generateRoutesManifest)({
appType,
pageKeys,
config,
redirects,
headers,
rewrites,
restrictedRedirectPaths,
isAppPPREnabled
});
return routesManifest.dynamicRoutes.map((r)=>r.page).concat(routesManifest.staticRoutes.map((r)=>r.page));
}
function startServer(dir, port) {
const server = _nodehttp.default.createServer((req, res)=>{
return (0, _servehandler.default)(req, res, {
public: dir
});
});
return new Promise((resolve, reject)=>{
function onError(err) {
server.close(()=>{
reject(err);
});
}
server.on('error', onError);
server.listen(port, 'localhost', ()=>{
const address = server.address();
if (address == null) {
reject(Object.defineProperty(new Error('Unable to get server address'), "__NEXT_ERROR_CODE", {
value: "E928",
enumerable: false,
configurable: true
}));
return;
}
// No longer needed after startup
server.removeListener('error', onError);
let addressString;
if (typeof address === 'string') {
addressString = address;
} else if (address.family === 'IPv6' && (address.address === '::' || address.address === '::1')) {
addressString = `localhost:${address.port}`;
} else if (address.family === 'IPv6') {
addressString = `[${address.address}]:${address.port}`;
} else {
addressString = `${address.address}:${address.port}`;
}
_log.info(`Bundle analyzer available at http://${addressString}`);
resolve();
});
});
}
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,20 @@
import type { NextBabelLoaderOptions, NextJsLoaderContext } from './types';
import { type SourceMap, type BabelLoaderTransformOptions } from './util';
/**
* An internal (non-exported) type used by babel.
*/
export type ResolvedBabelConfig = {
options: BabelLoaderTransformOptions;
passes: BabelPluginPasses;
externalDependencies: ReadonlyArray<string>;
};
export type BabelPlugin = unknown;
export type BabelPluginPassList = ReadonlyArray<BabelPlugin>;
export type BabelPluginPasses = ReadonlyArray<BabelPluginPassList>;
export default function getConfig(ctx: NextJsLoaderContext, { source, target, loaderOptions, filename, inputSourceMap, }: {
source: string;
loaderOptions: NextBabelLoaderOptions;
target: string;
filename: string;
inputSourceMap?: SourceMap | undefined;
}): Promise<ResolvedBabelConfig | null>;

View File

@@ -0,0 +1,429 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return getConfig;
}
});
const _nodefs = require("node:fs");
const _nodeutil = require("node:util");
const _json5 = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/json5"));
const _core = require("next/dist/compiled/babel/core");
const _corelibconfig = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/core-lib-config"));
const _util = require("./util");
const _log = /*#__PURE__*/ _interop_require_wildcard(require("../../output/log"));
const _swc = require("../../swc");
const _installbindings = require("../../swc/install-bindings");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
const nextDistPath = /(next[\\/]dist[\\/]shared[\\/]lib)|(next[\\/]dist[\\/]client)|(next[\\/]dist[\\/]pages)/;
function shouldSkipBabel(transformMode, configFilePath, hasReactCompiler) {
return transformMode === 'standalone' && configFilePath == null && !hasReactCompiler;
}
const fileExtensionRegex = /\.([a-z]+)$/;
async function getCacheCharacteristics(loaderOptions, source, filename) {
var _fileExtensionRegex_exec;
let isStandalone, isServer, pagesDir;
switch(loaderOptions.transformMode){
case 'default':
isStandalone = false;
isServer = loaderOptions.isServer;
pagesDir = loaderOptions.pagesDir;
break;
case 'standalone':
isStandalone = true;
break;
default:
throw Object.defineProperty(new Error(`unsupported transformMode in loader options: ${(0, _nodeutil.inspect)(loaderOptions)}`), "__NEXT_ERROR_CODE", {
value: "E811",
enumerable: false,
configurable: true
});
}
const isPageFile = pagesDir != null && filename.startsWith(pagesDir);
const isNextDist = nextDistPath.test(filename);
const hasModuleExports = source.indexOf('module.exports') !== -1;
const fileExt = ((_fileExtensionRegex_exec = fileExtensionRegex.exec(filename)) == null ? void 0 : _fileExtensionRegex_exec[1]) || 'unknown';
let { reactCompilerPlugins, reactCompilerExclude, configFile: configFilePath, transformMode } = loaderOptions;
// Compute `hasReactCompiler` as part of the cache characteristics / key,
// rather than inside of `getFreshConfig`:
// - `isReactCompilerRequired` depends on the file contents
// - `node_modules` and `reactCompilerExclude` depend on the file path, which
// isn't part of the cache characteristics
let hasReactCompiler = reactCompilerPlugins != null && reactCompilerPlugins.length !== 0 && !loaderOptions.isServer && !/[/\\]node_modules[/\\]/.test(filename) && // Assumption: `reactCompilerExclude` is cheap because it should only
// operate on the file path and *not* the file contents (it's sync)
!(reactCompilerExclude == null ? void 0 : reactCompilerExclude(filename));
// `isReactCompilerRequired` is expensive to run (parses/visits with SWC), so
// only run it if there's a good chance we might be able to skip calling Babel
// entirely (speculatively call `shouldSkipBabel`).
//
// Otherwise, we can let react compiler handle this logic for us. It should
// behave equivalently.
if (hasReactCompiler && shouldSkipBabel(transformMode, configFilePath, /*hasReactCompiler*/ false)) {
hasReactCompiler &&= await (0, _swc.isReactCompilerRequired)(filename);
}
return {
isStandalone,
isServer,
isPageFile,
isNextDist,
hasModuleExports,
hasReactCompiler,
fileExt,
configFilePath
};
}
/**
* Return an array of Babel plugins, conditioned upon loader options and
* source file characteristics.
*/ function getPlugins(loaderOptions, cacheCharacteristics) {
const { isServer, isPageFile, isNextDist, hasModuleExports } = cacheCharacteristics;
const { development, hasReactRefresh } = loaderOptions;
const applyCommonJsItem = hasModuleExports ? (0, _core.createConfigItem)(require('../plugins/commonjs'), {
type: 'plugin'
}) : null;
const reactRefreshItem = hasReactRefresh ? (0, _core.createConfigItem)([
require('next/dist/compiled/react-refresh/babel'),
{
skipEnvCheck: true
}
], {
type: 'plugin'
}) : null;
const pageConfigItem = !isServer && isPageFile ? (0, _core.createConfigItem)([
require('../plugins/next-page-config')
], {
type: 'plugin'
}) : null;
const disallowExportAllItem = !isServer && isPageFile ? (0, _core.createConfigItem)([
require('../plugins/next-page-disallow-re-export-all-exports')
], {
type: 'plugin'
}) : null;
const transformDefineItem = (0, _core.createConfigItem)([
require.resolve('next/dist/compiled/babel/plugin-transform-define'),
{
'process.env.NODE_ENV': development ? 'development' : 'production',
'typeof window': isServer ? 'undefined' : 'object',
'process.browser': isServer ? false : true
},
'next-js-transform-define-instance'
], {
type: 'plugin'
});
const nextSsgItem = !isServer && isPageFile ? (0, _core.createConfigItem)([
require.resolve('../plugins/next-ssg-transform')
], {
type: 'plugin'
}) : null;
const commonJsItem = isNextDist ? (0, _core.createConfigItem)(require('next/dist/compiled/babel/plugin-transform-modules-commonjs'), {
type: 'plugin'
}) : null;
const nextFontUnsupported = (0, _core.createConfigItem)([
require('../plugins/next-font-unsupported')
], {
type: 'plugin'
});
return [
reactRefreshItem,
pageConfigItem,
disallowExportAllItem,
applyCommonJsItem,
transformDefineItem,
nextSsgItem,
commonJsItem,
nextFontUnsupported
].filter(Boolean);
}
const isJsonFile = /\.(json|babelrc)$/;
const isJsFile = /\.js$/;
/**
* While this function does block execution while reading from disk, it
* should not introduce any issues. The function is only invoked when
* generating a fresh config, and only a small handful of configs should
* be generated during compilation.
*/ function getCustomBabelConfig(configFilePath) {
if (isJsonFile.exec(configFilePath)) {
const babelConfigRaw = (0, _nodefs.readFileSync)(configFilePath, 'utf8');
return _json5.default.parse(babelConfigRaw);
} else if (isJsFile.exec(configFilePath)) {
return require(configFilePath);
}
throw Object.defineProperty(new Error('The Next.js Babel loader does not support .mjs or .cjs config files.'), "__NEXT_ERROR_CODE", {
value: "E477",
enumerable: false,
configurable: true
});
}
let babelConfigWarned = false;
/**
* Check if custom babel configuration from user only contains options that
* can be migrated into latest Next.js features supported by SWC.
*
* This raises soft warning messages only, not making any errors yet.
*/ function checkCustomBabelConfigDeprecation(config) {
if (!config || Object.keys(config).length === 0) {
return;
}
const { plugins, presets, ...otherOptions } = config;
if (Object.keys(otherOptions ?? {}).length > 0) {
return;
}
if (babelConfigWarned) {
return;
}
babelConfigWarned = true;
const isPresetReadyToDeprecate = !presets || presets.length === 0 || presets.length === 1 && presets[0] === 'next/babel';
const pluginReasons = [];
const unsupportedPlugins = [];
if (Array.isArray(plugins)) {
for (const plugin of plugins){
const pluginName = Array.isArray(plugin) ? plugin[0] : plugin;
// [NOTE]: We cannot detect if the user uses babel-plugin-macro based transform plugins,
// such as `styled-components/macro` in here.
switch(pluginName){
case 'styled-components':
case 'babel-plugin-styled-components':
pluginReasons.push(`\t- 'styled-components' can be enabled via 'compiler.styledComponents' in 'next.config.js'`);
break;
case '@emotion/babel-plugin':
pluginReasons.push(`\t- '@emotion/babel-plugin' can be enabled via 'compiler.emotion' in 'next.config.js'`);
break;
case 'babel-plugin-relay':
pluginReasons.push(`\t- 'babel-plugin-relay' can be enabled via 'compiler.relay' in 'next.config.js'`);
break;
case 'react-remove-properties':
pluginReasons.push(`\t- 'react-remove-properties' can be enabled via 'compiler.reactRemoveProperties' in 'next.config.js'`);
break;
case 'transform-remove-console':
pluginReasons.push(`\t- 'transform-remove-console' can be enabled via 'compiler.removeConsole' in 'next.config.js'`);
break;
default:
unsupportedPlugins.push(pluginName);
break;
}
}
}
if (isPresetReadyToDeprecate && unsupportedPlugins.length === 0) {
_log.warn(`It looks like there is a custom Babel configuration that can be removed${pluginReasons.length > 0 ? ':' : '.'}`);
if (pluginReasons.length > 0) {
_log.warn(`Next.js supports the following features natively: `);
_log.warn(pluginReasons.join(''));
_log.warn(`For more details configuration options, please refer https://nextjs.org/docs/architecture/nextjs-compiler#supported-features`);
}
}
}
/**
* Generate a new, flat Babel config, ready to be handed to Babel-traverse.
* This config should have no unresolved overrides, presets, etc.
*
* The config returned by this function is cached, so the function should not
* depend on file-specific configuration or configuration that could change
* across invocations without a process restart.
*/ async function getFreshConfig(ctx, cacheCharacteristics, loaderOptions, target) {
const { transformMode } = loaderOptions;
const { hasReactCompiler, configFilePath, fileExt } = cacheCharacteristics;
let customConfig = configFilePath && getCustomBabelConfig(configFilePath);
if (shouldSkipBabel(transformMode, configFilePath, hasReactCompiler)) {
// Optimization: There's nothing useful to do, bail out and skip babel on
// this file
return null;
}
checkCustomBabelConfigDeprecation(customConfig);
// We can assume that `reactCompilerPlugins` does not change without a process
// restart (it's safe to cache), as it's specified in the `next.config.js`,
// which always causes a full restart of `next dev` if changed.
const reactCompilerPluginsIfEnabled = hasReactCompiler ? loaderOptions.reactCompilerPlugins ?? [] : [];
let isServer, pagesDir, srcDir, development;
if (transformMode === 'default') {
isServer = loaderOptions.isServer;
pagesDir = loaderOptions.pagesDir;
srcDir = loaderOptions.srcDir;
development = loaderOptions.development;
}
let options = {
babelrc: false,
cloneInputAst: false,
// Use placeholder file info. `updateBabelConfigWithFileDetails` will
// replace this after caching.
filename: `basename.${fileExt}`,
inputSourceMap: undefined,
sourceFileName: `basename.${fileExt}`,
// Set the default sourcemap behavior based on Webpack's mapping flag,
// but allow users to override if they want.
sourceMaps: loaderOptions.sourceMaps === undefined ? ctx.sourceMap : loaderOptions.sourceMaps
};
const baseCaller = {
name: 'next-babel-turbo-loader',
supportsStaticESM: true,
supportsDynamicImport: true,
// Provide plugins with insight into webpack target.
// https://github.com/babel/babel-loader/issues/787
target,
// Webpack 5 supports TLA behind a flag. We enable it by default
// for Babel, and then webpack will throw an error if the experimental
// flag isn't enabled.
supportsTopLevelAwait: true,
isServer,
srcDir,
pagesDir,
isDev: development,
transformMode,
...loaderOptions.caller
};
options.plugins = [
...transformMode === 'default' ? getPlugins(loaderOptions, cacheCharacteristics) : [],
...reactCompilerPluginsIfEnabled,
...(customConfig == null ? void 0 : customConfig.plugins) || []
];
// target can be provided in babelrc
options.target = isServer ? undefined : customConfig == null ? void 0 : customConfig.target;
// env can be provided in babelrc
options.env = customConfig == null ? void 0 : customConfig.env;
options.presets = (()=>{
// If presets is defined the user will have next/babel in their babelrc
if (customConfig == null ? void 0 : customConfig.presets) {
return customConfig.presets;
}
// If presets is not defined the user will likely have "env" in their babelrc
if (customConfig) {
return undefined;
}
// If no custom config is provided the default is to use next/babel
return [
'next/babel'
];
})();
options.overrides = loaderOptions.overrides;
options.caller = {
...baseCaller,
hasJsxRuntime: transformMode === 'default' ? loaderOptions.hasJsxRuntime : undefined
};
// Babel does strict checks on the config so undefined is not allowed
if (typeof options.target === 'undefined') {
delete options.target;
}
Object.defineProperty(options.caller, 'onWarning', {
enumerable: false,
writable: false,
value: (reason)=>{
if (!(reason instanceof Error)) {
reason = Object.defineProperty(new Error(reason), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
ctx.emitWarning(reason);
}
});
const loadedOptions = (0, _core.loadOptions)(options);
const config = (0, _util.consumeIterator)((0, _corelibconfig.default)(loadedOptions));
return config;
}
/**
* Each key returned here corresponds with a Babel config that can be shared.
* The conditions of permissible sharing between files is dependent on specific
* file attributes and Next.js compiler states: `CharacteristicsGermaneToCaching`.
*/ function getCacheKey(cacheCharacteristics) {
const { isStandalone, isServer, isPageFile, isNextDist, hasModuleExports, hasReactCompiler, fileExt, configFilePath } = cacheCharacteristics;
const flags = 0 | (isStandalone ? 1 : 0) | (isServer ? 2 : 0) | (isPageFile ? 4 : 0) | (isNextDist ? 8 : 0) | (hasModuleExports ? 16 : 0) | (hasReactCompiler ? 32 : 0);
// separate strings with null bytes, assuming null bytes are not valid in file
// paths
return `${configFilePath || ''}\x00${fileExt}\x00${flags}`;
}
const configCache = new Map();
const configFiles = new Set();
/**
* Applies file-specific values to a potentially-cached configuration object.
*/ function updateBabelConfigWithFileDetails(cachedConfig, loaderOptions, filename, inputSourceMap) {
if (cachedConfig == null) {
return null;
}
return {
...cachedConfig,
options: {
...cachedConfig.options,
cwd: loaderOptions.cwd,
root: loaderOptions.cwd,
filename,
inputSourceMap,
// Ensure that Webpack will get a full absolute path in the sourcemap
// so that it can properly map the module back to its internal cached
// modules.
sourceFileName: filename
}
};
}
async function getConfig(ctx, { source, target, loaderOptions, filename, inputSourceMap }) {
// Install bindings early so they are definitely available to the loader.
// When run by webpack in next this is already done with correct configuration so this is a no-op.
// In turbopack loaders are run in a subprocess so it may or may not be done.
await (0, _installbindings.installBindings)();
const cacheCharacteristics = await getCacheCharacteristics(loaderOptions, source, filename);
if (loaderOptions.configFile) {
// Ensures webpack invalidates the cache for this loader when the config file changes
ctx.addDependency(loaderOptions.configFile);
}
const cacheKey = getCacheKey(cacheCharacteristics);
const cachedConfig = configCache.get(cacheKey);
if (cachedConfig !== undefined) {
return updateBabelConfigWithFileDetails(cachedConfig, loaderOptions, filename, inputSourceMap);
}
if (loaderOptions.configFile && !configFiles.has(loaderOptions.configFile)) {
configFiles.add(loaderOptions.configFile);
_log.info(`Using external babel configuration from ${loaderOptions.configFile}`);
}
const freshConfig = await getFreshConfig(ctx, cacheCharacteristics, loaderOptions, target);
configCache.set(cacheKey, freshConfig);
return updateBabelConfigWithFileDetails(freshConfig, loaderOptions, filename, inputSourceMap);
}
//# sourceMappingURL=get-config.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
import type { NextJsLoaderContext } from './types';
declare function nextBabelLoaderOuter(this: NextJsLoaderContext, inputSource: string, inputSourceMap?: any): void;
export default nextBabelLoaderOuter;

View File

@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return _default;
}
});
const _transform = /*#__PURE__*/ _interop_require_default(require("./transform"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
async function nextBabelLoader(ctx, parentTrace, inputSource, inputSourceMap) {
const filename = ctx.resourcePath;
// Ensure `.d.ts` are not processed.
if (filename.endsWith('.d.ts')) {
return [
inputSource,
inputSourceMap
];
}
const target = ctx.target;
const loaderOptions = parentTrace.traceChild('get-options')// @ts-ignore TODO: remove ignore once webpack 5 types are used
.traceFn(()=>ctx.getOptions());
if (loaderOptions.exclude && loaderOptions.exclude(filename)) {
return [
inputSource,
inputSourceMap
];
}
const loaderSpanInner = parentTrace.traceChild('next-babel-turbo-transform');
const { code: transformedSource, map: outputSourceMap } = await loaderSpanInner.traceAsyncFn(async ()=>await (0, _transform.default)(ctx, inputSource, inputSourceMap, loaderOptions, filename, target, loaderSpanInner));
return [
transformedSource,
outputSourceMap
];
}
function nextBabelLoaderOuter(inputSource, // webpack's source map format is compatible with babel, but the type signature doesn't match
inputSourceMap) {
const callback = this.async();
const loaderSpan = this.currentTraceSpan.traceChild('next-babel-turbo-loader');
loaderSpan.traceAsyncFn(()=>nextBabelLoader(this, loaderSpan, inputSource, inputSourceMap)).then(([transformedSource, outputSourceMap])=>callback == null ? void 0 : callback(/* err */ null, transformedSource, outputSourceMap ?? inputSourceMap), (err)=>{
callback == null ? void 0 : callback(err);
});
}
// check this type matches `webpack.LoaderDefinitionFunction`, but be careful
// not to publicly rely on the webpack type since the generated typescript
// declarations will be wrong.
const _nextBabelLoaderOuter = nextBabelLoaderOuter;
const _default = nextBabelLoaderOuter;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/build/babel/loader/index.ts"],"sourcesContent":["import type { Span } from '../../../trace'\nimport transform from './transform'\nimport type { NextJsLoaderContext } from './types'\nimport type { SourceMap } from './util'\nimport type { webpack } from 'next/dist/compiled/webpack/webpack'\n\nasync function nextBabelLoader(\n ctx: NextJsLoaderContext,\n parentTrace: Span,\n inputSource: string,\n inputSourceMap: SourceMap | null | undefined\n): Promise<[string, SourceMap | null | undefined]> {\n const filename = ctx.resourcePath\n\n // Ensure `.d.ts` are not processed.\n if (filename.endsWith('.d.ts')) {\n return [inputSource, inputSourceMap]\n }\n\n const target = ctx.target\n const loaderOptions: any = parentTrace\n .traceChild('get-options')\n // @ts-ignore TODO: remove ignore once webpack 5 types are used\n .traceFn(() => ctx.getOptions())\n\n if (loaderOptions.exclude && loaderOptions.exclude(filename)) {\n return [inputSource, inputSourceMap]\n }\n\n const loaderSpanInner = parentTrace.traceChild('next-babel-turbo-transform')\n const { code: transformedSource, map: outputSourceMap } =\n await loaderSpanInner.traceAsyncFn(\n async () =>\n await transform(\n ctx,\n inputSource,\n inputSourceMap,\n loaderOptions,\n filename,\n target,\n loaderSpanInner\n )\n )\n\n return [transformedSource, outputSourceMap]\n}\n\nfunction nextBabelLoaderOuter(\n this: NextJsLoaderContext,\n inputSource: string,\n // webpack's source map format is compatible with babel, but the type signature doesn't match\n inputSourceMap?: any\n) {\n const callback = this.async()\n\n const loaderSpan = this.currentTraceSpan.traceChild('next-babel-turbo-loader')\n loaderSpan\n .traceAsyncFn(() =>\n nextBabelLoader(this, loaderSpan, inputSource, inputSourceMap)\n )\n .then(\n ([transformedSource, outputSourceMap]) =>\n callback?.(\n /* err */ null,\n transformedSource,\n outputSourceMap ?? inputSourceMap\n ),\n (err) => {\n callback?.(err)\n }\n )\n}\n\n// check this type matches `webpack.LoaderDefinitionFunction`, but be careful\n// not to publicly rely on the webpack type since the generated typescript\n// declarations will be wrong.\nconst _nextBabelLoaderOuter: webpack.LoaderDefinitionFunction<\n {},\n NextJsLoaderContext\n> = nextBabelLoaderOuter\n\nexport default nextBabelLoaderOuter\n"],"names":["nextBabelLoader","ctx","parentTrace","inputSource","inputSourceMap","filename","resourcePath","endsWith","target","loaderOptions","traceChild","traceFn","getOptions","exclude","loaderSpanInner","code","transformedSource","map","outputSourceMap","traceAsyncFn","transform","nextBabelLoaderOuter","callback","async","loaderSpan","currentTraceSpan","then","err","_nextBabelLoaderOuter"],"mappings":";;;;+BAiFA;;;eAAA;;;kEAhFsB;;;;;;AAKtB,eAAeA,gBACbC,GAAwB,EACxBC,WAAiB,EACjBC,WAAmB,EACnBC,cAA4C;IAE5C,MAAMC,WAAWJ,IAAIK,YAAY;IAEjC,oCAAoC;IACpC,IAAID,SAASE,QAAQ,CAAC,UAAU;QAC9B,OAAO;YAACJ;YAAaC;SAAe;IACtC;IAEA,MAAMI,SAASP,IAAIO,MAAM;IACzB,MAAMC,gBAAqBP,YACxBQ,UAAU,CAAC,cACZ,+DAA+D;KAC9DC,OAAO,CAAC,IAAMV,IAAIW,UAAU;IAE/B,IAAIH,cAAcI,OAAO,IAAIJ,cAAcI,OAAO,CAACR,WAAW;QAC5D,OAAO;YAACF;YAAaC;SAAe;IACtC;IAEA,MAAMU,kBAAkBZ,YAAYQ,UAAU,CAAC;IAC/C,MAAM,EAAEK,MAAMC,iBAAiB,EAAEC,KAAKC,eAAe,EAAE,GACrD,MAAMJ,gBAAgBK,YAAY,CAChC,UACE,MAAMC,IAAAA,kBAAS,EACbnB,KACAE,aACAC,gBACAK,eACAJ,UACAG,QACAM;IAIR,OAAO;QAACE;QAAmBE;KAAgB;AAC7C;AAEA,SAASG,qBAEPlB,WAAmB,EACnB,6FAA6F;AAC7FC,cAAoB;IAEpB,MAAMkB,WAAW,IAAI,CAACC,KAAK;IAE3B,MAAMC,aAAa,IAAI,CAACC,gBAAgB,CAACf,UAAU,CAAC;IACpDc,WACGL,YAAY,CAAC,IACZnB,gBAAgB,IAAI,EAAEwB,YAAYrB,aAAaC,iBAEhDsB,IAAI,CACH,CAAC,CAACV,mBAAmBE,gBAAgB,GACnCI,4BAAAA,SACE,OAAO,GAAG,MACVN,mBACAE,mBAAmBd,iBAEvB,CAACuB;QACCL,4BAAAA,SAAWK;IACb;AAEN;AAEA,6EAA6E;AAC7E,0EAA0E;AAC1E,8BAA8B;AAC9B,MAAMC,wBAGFP;MAEJ,WAAeA","ignoreList":[0]}

View File

@@ -0,0 +1,5 @@
import { type GeneratorResult } from 'next/dist/compiled/babel/generator';
import type { Span } from '../../../trace';
import type { NextJsLoaderContext } from './types';
import type { SourceMap } from './util';
export default function transform(ctx: NextJsLoaderContext, source: string, inputSourceMap: SourceMap | null | undefined, loaderOptions: any, filename: string, target: string, parentSpan: Span): Promise<GeneratorResult>;

View File

@@ -0,0 +1,103 @@
/*
* Partially adapted from @babel/core (MIT license).
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return transform;
}
});
const _traverse = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/traverse"));
const _generator = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/generator"));
const _corelibnormalizefile = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/core-lib-normalize-file"));
const _corelibnormalizeopts = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/core-lib-normalize-opts"));
const _corelibblockhoistplugin = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/core-lib-block-hoist-plugin"));
const _corelibpluginpass = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/core-lib-plugin-pass"));
const _getconfig = /*#__PURE__*/ _interop_require_default(require("./get-config"));
const _util = require("./util");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function getTraversalParams(file, pluginPairs) {
const passPairs = [];
const passes = [];
const visitors = [];
for (const plugin of pluginPairs.concat((0, _corelibblockhoistplugin.default)())){
const pass = new _corelibpluginpass.default(file, plugin.key, plugin.options);
passPairs.push([
plugin,
pass
]);
passes.push(pass);
visitors.push(plugin.visitor);
}
return {
passPairs,
passes,
visitors
};
}
function invokePluginPre(file, passPairs) {
for (const [{ pre }, pass] of passPairs){
if (pre) {
pre.call(pass, file);
}
}
}
function invokePluginPost(file, passPairs) {
for (const [{ post }, pass] of passPairs){
if (post) {
post.call(pass, file);
}
}
}
function transformAstPass(file, pluginPairs, parentSpan) {
const { passPairs, passes, visitors } = getTraversalParams(file, pluginPairs);
invokePluginPre(file, passPairs);
const visitor = _traverse.default.visitors.merge(visitors, passes, // @ts-ignore - the exported types are incorrect here
file.opts.wrapPluginVisitorMethod);
parentSpan.traceChild('babel-turbo-traverse').traceFn(()=>(0, _traverse.default)(file.ast, visitor, file.scope));
invokePluginPost(file, passPairs);
}
function transformAst(file, babelConfig, parentSpan) {
for (const pluginPairs of babelConfig.passes){
transformAstPass(file, pluginPairs, parentSpan);
}
}
async function transform(ctx, source, inputSourceMap, loaderOptions, filename, target, parentSpan) {
const getConfigSpan = parentSpan.traceChild('babel-turbo-get-config');
const babelConfig = await (0, _getconfig.default)(ctx, {
source,
loaderOptions,
inputSourceMap: inputSourceMap ?? undefined,
target,
filename
});
if (!babelConfig) {
return {
code: source,
map: inputSourceMap ?? null
};
}
getConfigSpan.stop();
const normalizeSpan = parentSpan.traceChild('babel-turbo-normalize-file');
const file = (0, _util.consumeIterator)((0, _corelibnormalizefile.default)(babelConfig.passes, (0, _corelibnormalizeopts.default)(babelConfig), source));
normalizeSpan.stop();
const transformSpan = parentSpan.traceChild('babel-turbo-transform');
transformAst(file, babelConfig, transformSpan);
transformSpan.stop();
const generateSpan = parentSpan.traceChild('babel-turbo-generate');
const { code, map } = (0, _generator.default)(file.ast, file.opts.generatorOpts, file.code);
generateSpan.stop();
return {
code,
map
};
}
//# sourceMappingURL=transform.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,77 @@
import type { webpack } from 'next/dist/compiled/webpack/webpack'
import type { JSONValue } from '../../../server/config-shared'
import type { Span } from '../../../trace'
export interface NextJsLoaderContext extends webpack.LoaderContext<{}> {
currentTraceSpan: Span
target: string
}
export interface NextBabelLoaderBaseOptions {
cwd: string
/**
* Should we read the user-provided custom babel config? Used in both `transformMode`s.
*/
configFile?: string
/**
* Custom plugins to be added to the generated babel options.
*/
reactCompilerPlugins?: Array<JSONValue>
/**
* Paths that the loader should not apply the react-compiler to.
*/
reactCompilerExclude?: (excludePath: string) => boolean
overrides?: any
/**
* Extra fields to pass to presets/plugins via the Babel 'caller' API.
*/
caller?: any
/**
* Advanced: Can override webpack's sourcemap behavior (see `NextJsLoaderContext["sourceMap"]`).
*/
sourceMaps?: boolean | 'inline' | 'both' | null | undefined
}
/**
* Options to create babel loader for the default transformations.
*
* This is primary usecase of babel-loader configuration for running
* all of the necessary transforms for the ecmascript instead of swc loader.
*/
export type NextBabelLoaderOptionDefaultPresets = NextBabelLoaderBaseOptions & {
transformMode: 'default'
isServer: boolean
distDir: string
pagesDir: string | undefined
srcDir: string
development: boolean
hasJsxRuntime: boolean
hasReactRefresh: boolean
}
/**
* Options to create babel loader for 'standalone' transformations.
*
* This'll create a babel loader does not enable any of the default Next.js
* presets or plugins that perform transformations. Non-transforming syntax
* plugins (e.g. Typescript) will still be enabled.
*
* This is useful when Babel is used in combination with SWC, and we expect SWC
* to perform downleveling and Next.js-specific transforms. Standalone mode is
* used in Turbopack and when React Compiler is used with webpack.
*/
export type NextBabelLoaderOptionStandalone = NextBabelLoaderBaseOptions & {
transformMode: 'standalone'
isServer: boolean
}
export type NextBabelLoaderOptions =
| NextBabelLoaderOptionDefaultPresets
| NextBabelLoaderOptionStandalone

View File

@@ -0,0 +1,16 @@
import type { TransformOptions } from 'next/dist/compiled/babel/core';
export declare function consumeIterator(iter: Iterator<any>): any;
/**
* Source map standard format as to revision 3.
*
* `TransformOptions` uses this type, but doesn't export it separately
*/
export type SourceMap = NonNullable<TransformOptions['inputSourceMap']>;
/**
* An extension of the normal babel configuration, with extra `babel-loader`-specific fields that transforms can read.
*
* See: https://github.com/babel/babel-loader/blob/main/src/injectCaller.js
*/
export type BabelLoaderTransformOptions = TransformOptions & {
target?: string;
};

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "consumeIterator", {
enumerable: true,
get: function() {
return consumeIterator;
}
});
function consumeIterator(iter) {
while(true){
const { value, done } = iter.next();
if (done) {
return value;
}
}
}
//# sourceMappingURL=util.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/build/babel/loader/util.ts"],"sourcesContent":["import type { TransformOptions } from 'next/dist/compiled/babel/core'\n\nexport function consumeIterator(iter: Iterator<any>) {\n while (true) {\n const { value, done } = iter.next()\n if (done) {\n return value\n }\n }\n}\n\n/**\n * Source map standard format as to revision 3.\n *\n * `TransformOptions` uses this type, but doesn't export it separately\n */\nexport type SourceMap = NonNullable<TransformOptions['inputSourceMap']>\n\n/**\n * An extension of the normal babel configuration, with extra `babel-loader`-specific fields that transforms can read.\n *\n * See: https://github.com/babel/babel-loader/blob/main/src/injectCaller.js\n */\nexport type BabelLoaderTransformOptions = TransformOptions & {\n target?: string\n}\n"],"names":["consumeIterator","iter","value","done","next"],"mappings":";;;;+BAEgBA;;;eAAAA;;;AAAT,SAASA,gBAAgBC,IAAmB;IACjD,MAAO,KAAM;QACX,MAAM,EAAEC,KAAK,EAAEC,IAAI,EAAE,GAAGF,KAAKG,IAAI;QACjC,IAAID,MAAM;YACR,OAAOD;QACT;IACF;AACF","ignoreList":[0]}

View File

@@ -0,0 +1,2 @@
import type { PluginObj } from 'next/dist/compiled/babel/core';
export default function CommonJSModulePlugin(...args: any): PluginObj;

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, // Handle module.exports in user code
"default", {
enumerable: true,
get: function() {
return CommonJSModulePlugin;
}
});
const _plugintransformmodulescommonjs = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/plugin-transform-modules-commonjs"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function CommonJSModulePlugin(...args) {
const commonjs = (0, _plugintransformmodulescommonjs.default)(...args);
return {
visitor: {
Program: {
exit (path, state) {
let foundModuleExports = false;
path.traverse({
MemberExpression (expressionPath) {
if (expressionPath.node.object.name !== 'module') return;
if (expressionPath.node.property.name !== 'exports') return;
foundModuleExports = true;
}
});
if (!foundModuleExports) {
return;
}
commonjs.visitor.Program.exit.call(this, path, state);
}
}
}
};
}
//# sourceMappingURL=commonjs.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/build/babel/plugins/commonjs.ts"],"sourcesContent":["import type { NodePath, types } from 'next/dist/compiled/babel/core'\nimport type { PluginObj } from 'next/dist/compiled/babel/core'\nimport commonjsPlugin from 'next/dist/compiled/babel/plugin-transform-modules-commonjs'\n\n// Handle module.exports in user code\nexport default function CommonJSModulePlugin(...args: any): PluginObj {\n const commonjs = commonjsPlugin(...args)\n return {\n visitor: {\n Program: {\n exit(path: NodePath<types.Program>, state) {\n let foundModuleExports = false\n path.traverse({\n MemberExpression(expressionPath: any) {\n if (expressionPath.node.object.name !== 'module') return\n if (expressionPath.node.property.name !== 'exports') return\n foundModuleExports = true\n },\n })\n\n if (!foundModuleExports) {\n return\n }\n\n commonjs.visitor.Program.exit.call(this, path, state)\n },\n },\n },\n }\n}\n"],"names":["CommonJSModulePlugin","args","commonjs","commonjsPlugin","visitor","Program","exit","path","state","foundModuleExports","traverse","MemberExpression","expressionPath","node","object","name","property","call"],"mappings":";;;;+BAIA,qCAAqC;AACrC;;;eAAwBA;;;uFAHG;;;;;;AAGZ,SAASA,qBAAqB,GAAGC,IAAS;IACvD,MAAMC,WAAWC,IAAAA,uCAAc,KAAIF;IACnC,OAAO;QACLG,SAAS;YACPC,SAAS;gBACPC,MAAKC,IAA6B,EAAEC,KAAK;oBACvC,IAAIC,qBAAqB;oBACzBF,KAAKG,QAAQ,CAAC;wBACZC,kBAAiBC,cAAmB;4BAClC,IAAIA,eAAeC,IAAI,CAACC,MAAM,CAACC,IAAI,KAAK,UAAU;4BAClD,IAAIH,eAAeC,IAAI,CAACG,QAAQ,CAACD,IAAI,KAAK,WAAW;4BACrDN,qBAAqB;wBACvB;oBACF;oBAEA,IAAI,CAACA,oBAAoB;wBACvB;oBACF;oBAEAP,SAASE,OAAO,CAACC,OAAO,CAACC,IAAI,CAACW,IAAI,CAAC,IAAI,EAAEV,MAAMC;gBACjD;YACF;QACF;IACF;AACF","ignoreList":[0]}

View File

@@ -0,0 +1,5 @@
import type { types as BabelTypes } from 'next/dist/compiled/babel/core';
import type { PluginObj } from 'next/dist/compiled/babel/core';
export default function ({ types: t, }: {
types: typeof BabelTypes;
}): PluginObj<any>;

View File

@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return _default;
}
});
const _pluginsyntaxjsx = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/plugin-syntax-jsx"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _default({ types: t }) {
return {
inherits: _pluginsyntaxjsx.default,
visitor: {
JSXElement (_path, state) {
state.set('jsx', true);
},
// Fragment syntax is still JSX since it compiles to createElement(),
// but JSXFragment is not a JSXElement
JSXFragment (_path, state) {
state.set('jsx', true);
},
Program: {
exit (path, state) {
if (state.get('jsx')) {
const pragma = t.identifier(state.opts.pragma);
let importAs = pragma;
// if there's already a React in scope, use that instead of adding an import
const existingBinding = state.opts.reuseImport !== false && state.opts.importAs && path.scope.getBinding(state.opts.importAs);
// var _jsx = _pragma.createElement;
if (state.opts.property) {
if (state.opts.importAs) {
importAs = t.identifier(state.opts.importAs);
} else {
importAs = path.scope.generateUidIdentifier('pragma');
}
const mapping = t.variableDeclaration('var', [
t.variableDeclarator(pragma, t.memberExpression(importAs, t.identifier(state.opts.property)))
]);
// if the React binding came from a require('react'),
// make sure that our usage comes after it.
let newPath;
if (existingBinding && t.isVariableDeclarator(existingBinding.path.node) && t.isCallExpression(existingBinding.path.node.init) && t.isIdentifier(existingBinding.path.node.init.callee) && existingBinding.path.node.init.callee.name === 'require') {
;
[newPath] = existingBinding.path.parentPath.insertAfter(mapping);
} else {
;
[newPath] = path.unshiftContainer('body', mapping);
}
path.scope.registerDeclaration(newPath);
}
if (!existingBinding) {
const importSpecifier = t.importDeclaration([
state.opts.import ? t.importSpecifier(importAs, t.identifier(state.opts.import)) : state.opts.importNamespace ? t.importNamespaceSpecifier(importAs) : t.importDefaultSpecifier(importAs)
], t.stringLiteral(state.opts.module || 'react'));
const [newPath] = path.unshiftContainer('body', importSpecifier);
for (const specifier of newPath.get('specifiers')){
path.scope.registerBinding('module', specifier);
}
}
}
}
}
}
};
}
//# sourceMappingURL=jsx-pragma.js.map

Some files were not shown because too many files have changed in this diff Show More