vinext 0.0.50 → 0.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/google-fonts/fallback-metrics-data.js +14031 -0
- package/dist/build/google-fonts/fallback-metrics-data.js.map +1 -0
- package/dist/build/google-fonts/fallback-metrics.d.ts +13 -0
- package/dist/build/google-fonts/fallback-metrics.js +46 -0
- package/dist/build/google-fonts/fallback-metrics.js.map +1 -0
- package/dist/build/precompress.d.ts +13 -2
- package/dist/build/precompress.js +12 -3
- package/dist/build/precompress.js.map +1 -1
- package/dist/build/prerender.d.ts +1 -1
- package/dist/build/prerender.js +44 -14
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/report.d.ts +5 -4
- package/dist/build/report.js +196 -348
- package/dist/build/report.js.map +1 -1
- package/dist/check.js +1 -0
- package/dist/check.js.map +1 -1
- package/dist/cli.js +60 -3
- package/dist/cli.js.map +1 -1
- package/dist/client/window-next.d.ts +3 -1
- package/dist/client/window-next.js.map +1 -1
- package/dist/config/dotenv.d.ts +11 -1
- package/dist/config/dotenv.js.map +1 -1
- package/dist/config/next-config.d.ts +87 -3
- package/dist/config/next-config.js +222 -6
- package/dist/config/next-config.js.map +1 -1
- package/dist/config/tsconfig-paths.d.ts +13 -0
- package/dist/config/tsconfig-paths.js +117 -0
- package/dist/config/tsconfig-paths.js.map +1 -0
- package/dist/deploy.js +3 -2
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.d.ts +2 -2
- package/dist/entries/app-browser-entry.js +26 -1
- package/dist/entries/app-browser-entry.js.map +1 -1
- package/dist/entries/app-rsc-entry.d.ts +19 -1
- package/dist/entries/app-rsc-entry.js +38 -12
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +9 -0
- package/dist/entries/app-rsc-manifest.js +4 -1
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/pages-client-entry.js +3 -5
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-server-entry.js +19 -1
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/index.js +130 -37
- package/dist/index.js.map +1 -1
- package/dist/plugins/client-reference-dedup.d.ts +15 -2
- package/dist/plugins/client-reference-dedup.js +138 -16
- package/dist/plugins/client-reference-dedup.js.map +1 -1
- package/dist/plugins/fonts.d.ts +2 -2
- package/dist/plugins/fonts.js +15 -6
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/sass.d.ts +34 -0
- package/dist/plugins/sass.js +22 -0
- package/dist/plugins/sass.js.map +1 -0
- package/dist/routing/app-route-graph.d.ts +31 -2
- package/dist/routing/app-route-graph.js +82 -10
- package/dist/routing/app-route-graph.js.map +1 -1
- package/dist/routing/route-pattern.d.ts +56 -1
- package/dist/routing/route-pattern.js +60 -1
- package/dist/routing/route-pattern.js.map +1 -1
- package/dist/server/app-browser-action-result.d.ts +27 -2
- package/dist/server/app-browser-action-result.js +63 -2
- package/dist/server/app-browser-action-result.js.map +1 -1
- package/dist/server/app-browser-entry.js +262 -108
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-hydration.d.ts +13 -1
- package/dist/server/app-browser-hydration.js +9 -1
- package/dist/server/app-browser-hydration.js.map +1 -1
- package/dist/server/app-browser-navigation-controller.d.ts +14 -1
- package/dist/server/app-browser-navigation-controller.js +28 -9
- package/dist/server/app-browser-navigation-controller.js.map +1 -1
- package/dist/server/app-browser-popstate.d.ts +16 -0
- package/dist/server/app-browser-popstate.js +17 -0
- package/dist/server/app-browser-popstate.js.map +1 -0
- package/dist/server/app-browser-rsc-redirect.d.ts +28 -0
- package/dist/server/app-browser-rsc-redirect.js +37 -0
- package/dist/server/app-browser-rsc-redirect.js.map +1 -0
- package/dist/server/app-browser-state.d.ts +11 -7
- package/dist/server/app-browser-state.js +45 -27
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-browser-stream.d.ts +5 -4
- package/dist/server/app-browser-stream.js +5 -6
- package/dist/server/app-browser-stream.js.map +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +5 -0
- package/dist/server/app-browser-visible-commit.js +38 -5
- package/dist/server/app-browser-visible-commit.js.map +1 -1
- package/dist/server/app-elements-wire.d.ts +38 -6
- package/dist/server/app-elements-wire.js +106 -6
- package/dist/server/app-elements-wire.js.map +1 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.d.ts +10 -1
- package/dist/server/app-fallback-renderer.js +37 -1
- package/dist/server/app-fallback-renderer.js.map +1 -1
- package/dist/server/app-history-state.d.ts +26 -0
- package/dist/server/app-history-state.js +53 -0
- package/dist/server/app-history-state.js.map +1 -0
- package/dist/server/app-page-boundary-render.d.ts +10 -1
- package/dist/server/app-page-boundary-render.js +13 -6
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.js +3 -2
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +13 -0
- package/dist/server/app-page-cache.js +25 -8
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +5 -0
- package/dist/server/app-page-dispatch.js +68 -11
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.d.ts +7 -0
- package/dist/server/app-page-element-builder.js +32 -4
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-execution.js +2 -3
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.d.ts +7 -0
- package/dist/server/app-page-head.js +2 -1
- package/dist/server/app-page-head.js.map +1 -1
- package/dist/server/app-page-probe.d.ts +23 -1
- package/dist/server/app-page-probe.js +29 -1
- package/dist/server/app-page-probe.js.map +1 -1
- package/dist/server/app-page-render-observation.d.ts +35 -0
- package/dist/server/app-page-render-observation.js +68 -0
- package/dist/server/app-page-render-observation.js.map +1 -0
- package/dist/server/app-page-render.d.ts +5 -1
- package/dist/server/app-page-render.js +79 -3
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +1 -0
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.js +3 -2
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +42 -14
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +2 -0
- package/dist/server/app-page-stream.js +1 -0
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-router-entry.js +1 -13
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +19 -1
- package/dist/server/app-rsc-cache-busting.js +36 -1
- package/dist/server/app-rsc-cache-busting.js.map +1 -1
- package/dist/server/app-rsc-embedded-chunks.d.ts +9 -0
- package/dist/server/app-rsc-embedded-chunks.js +34 -0
- package/dist/server/app-rsc-embedded-chunks.js.map +1 -0
- package/dist/server/app-rsc-errors.d.ts +4 -1
- package/dist/server/app-rsc-errors.js +1 -1
- package/dist/server/app-rsc-errors.js.map +1 -1
- package/dist/server/app-rsc-handler.d.ts +12 -4
- package/dist/server/app-rsc-handler.js +6 -1
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +23 -0
- package/dist/server/app-rsc-route-matching.js +45 -23
- package/dist/server/app-rsc-route-matching.js.map +1 -1
- package/dist/server/app-server-action-execution.d.ts +35 -3
- package/dist/server/app-server-action-execution.js +87 -33
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +1 -0
- package/dist/server/app-ssr-entry.js +37 -13
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-error-meta.d.ts +14 -0
- package/dist/server/app-ssr-error-meta.js +50 -0
- package/dist/server/app-ssr-error-meta.js.map +1 -0
- package/dist/server/app-ssr-stream.d.ts +1 -1
- package/dist/server/app-ssr-stream.js +9 -12
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/artifact-compatibility.d.ts +12 -2
- package/dist/server/artifact-compatibility.js +12 -8
- package/dist/server/artifact-compatibility.js.map +1 -1
- package/dist/server/cache-proof.d.ts +124 -5
- package/dist/server/cache-proof.js +416 -18
- package/dist/server/cache-proof.js.map +1 -1
- package/dist/server/dev-lockfile.d.ts +110 -0
- package/dist/server/dev-lockfile.js +180 -0
- package/dist/server/dev-lockfile.js.map +1 -0
- package/dist/server/dev-server.js +15 -5
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/file-based-metadata.d.ts +13 -0
- package/dist/server/file-based-metadata.js +49 -2
- package/dist/server/file-based-metadata.js.map +1 -1
- package/dist/server/headers.d.ts +3 -1
- package/dist/server/headers.js +5 -2
- package/dist/server/headers.js.map +1 -1
- package/dist/server/html.js +1 -1
- package/dist/server/html.js.map +1 -1
- package/dist/server/http-error-responses.d.ts +10 -0
- package/dist/server/http-error-responses.js +11 -1
- package/dist/server/http-error-responses.js.map +1 -1
- package/dist/server/isr-cache.d.ts +2 -1
- package/dist/server/isr-cache.js +4 -2
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/metadata-route-response.js +22 -5
- package/dist/server/metadata-route-response.js.map +1 -1
- package/dist/server/metadata-routes.js +27 -8
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware-runtime.js +1 -0
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/middleware.d.ts +12 -0
- package/dist/server/middleware.js +12 -0
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/navigation-planner.d.ts +19 -5
- package/dist/server/navigation-planner.js +278 -17
- package/dist/server/navigation-planner.js.map +1 -1
- package/dist/server/navigation-trace.d.ts +8 -1
- package/dist/server/navigation-trace.js +7 -0
- package/dist/server/navigation-trace.js.map +1 -1
- package/dist/server/normalize-path.d.ts +2 -1
- package/dist/server/normalize-path.js +4 -1
- package/dist/server/normalize-path.js.map +1 -1
- package/dist/server/pages-api-route.js +1 -0
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-page-data.d.ts +3 -2
- package/dist/server/pages-page-data.js +22 -3
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.js +1 -1
- package/dist/server/prod-server.d.ts +28 -1
- package/dist/server/prod-server.js +62 -9
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/server-action-not-found.d.ts +16 -3
- package/dist/server/server-action-not-found.js +19 -1
- package/dist/server/server-action-not-found.js.map +1 -1
- package/dist/server/server-globals.d.ts +5 -0
- package/dist/server/server-globals.js +37 -0
- package/dist/server/server-globals.js.map +1 -0
- package/dist/server/static-file-cache.js +1 -1
- package/dist/server/static-file-cache.js.map +1 -1
- package/dist/shims/cache-runtime.d.ts +19 -2
- package/dist/shims/cache-runtime.js +67 -11
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +5 -18
- package/dist/shims/cache.js +2 -0
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/error-boundary.js +6 -8
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/error.d.ts +18 -1
- package/dist/shims/error.js +56 -1
- package/dist/shims/error.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts +4 -1
- package/dist/shims/fetch-cache.js +40 -5
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/font-google-base.d.ts +22 -8
- package/dist/shims/font-google-base.js +41 -71
- package/dist/shims/font-google-base.js.map +1 -1
- package/dist/shims/font-local.d.ts +3 -20
- package/dist/shims/font-local.js +23 -75
- package/dist/shims/font-local.js.map +1 -1
- package/dist/shims/font-utils.d.ts +51 -0
- package/dist/shims/font-utils.js +97 -0
- package/dist/shims/font-utils.js.map +1 -0
- package/dist/shims/hash-scroll.d.ts +7 -0
- package/dist/shims/hash-scroll.js +30 -0
- package/dist/shims/hash-scroll.js.map +1 -0
- package/dist/shims/headers.d.ts +8 -11
- package/dist/shims/headers.js +22 -2
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/image.d.ts +1 -0
- package/dist/shims/image.js +144 -78
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/app-router-context.d.ts +6 -6
- package/dist/shims/internal/app-router-context.js +17 -6
- package/dist/shims/internal/app-router-context.js.map +1 -1
- package/dist/shims/link-prefetch.d.ts +9 -1
- package/dist/shims/link-prefetch.js +11 -6
- package/dist/shims/link-prefetch.js.map +1 -1
- package/dist/shims/link.d.ts +12 -2
- package/dist/shims/link.js +78 -32
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +16 -30
- package/dist/shims/metadata.js +87 -28
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation.d.ts +158 -17
- package/dist/shims/navigation.js +324 -74
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/navigation.react-server.d.ts +3 -2
- package/dist/shims/navigation.react-server.js +5 -2
- package/dist/shims/navigation.react-server.js.map +1 -1
- package/dist/shims/pages-router-runtime.d.ts +7 -0
- package/dist/shims/pages-router-runtime.js +16 -0
- package/dist/shims/pages-router-runtime.js.map +1 -0
- package/dist/shims/router.d.ts +32 -6
- package/dist/shims/router.js +197 -242
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script.js +110 -32
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.js +2 -1
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/slot.d.ts +1 -0
- package/dist/shims/slot.js +41 -1
- package/dist/shims/slot.js.map +1 -1
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/shims/unrecognized-action-error.d.ts +35 -0
- package/dist/shims/unrecognized-action-error.js +41 -0
- package/dist/shims/unrecognized-action-error.js.map +1 -0
- package/dist/shims/url-utils.d.ts +21 -1
- package/dist/shims/url-utils.js +67 -3
- package/dist/shims/url-utils.js.map +1 -1
- package/dist/utils/asset-prefix.d.ts +69 -0
- package/dist/utils/asset-prefix.js +91 -0
- package/dist/utils/asset-prefix.js.map +1 -0
- package/dist/utils/base-path.d.ts +7 -1
- package/dist/utils/base-path.js +10 -1
- package/dist/utils/base-path.js.map +1 -1
- package/dist/utils/navigation-signal.d.ts +1 -2
- package/dist/utils/navigation-signal.js +1 -1
- package/dist/utils/navigation-signal.js.map +1 -1
- package/dist/utils/sorted-array.d.ts +9 -0
- package/dist/utils/sorted-array.js +22 -0
- package/dist/utils/sorted-array.js.map +1 -0
- package/package.json +3 -3
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { normalizePageExtensions } from "../routing/file-matcher.js";
|
|
2
2
|
import { isExternalUrl } from "./config-matchers.js";
|
|
3
3
|
import { PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD } from "../shims/constants.js";
|
|
4
|
+
import { loadTsconfigPathAliasesForRoot } from "./tsconfig-paths.js";
|
|
4
5
|
import { createRequire } from "node:module";
|
|
5
6
|
import fs from "node:fs";
|
|
6
7
|
import path from "node:path";
|
|
7
8
|
import { fileURLToPath } from "node:url";
|
|
8
9
|
import { randomUUID } from "node:crypto";
|
|
10
|
+
import commonjs from "vite-plugin-commonjs";
|
|
9
11
|
//#region src/config/next-config.ts
|
|
10
12
|
/**
|
|
11
13
|
* next.config.js / next.config.mjs / next.config.ts parser
|
|
@@ -60,6 +62,7 @@ function parseBodySizeLimit(value) {
|
|
|
60
62
|
}
|
|
61
63
|
const CONFIG_FILES = [
|
|
62
64
|
"next.config.ts",
|
|
65
|
+
"next.config.mts",
|
|
63
66
|
"next.config.mjs",
|
|
64
67
|
"next.config.js",
|
|
65
68
|
"next.config.cjs"
|
|
@@ -97,11 +100,138 @@ async function resolveConfigValue(config, phase = DEFAULT_PHASE) {
|
|
|
97
100
|
return config;
|
|
98
101
|
}
|
|
99
102
|
/**
|
|
103
|
+
* Named export attached by `cjsGlobalsInjectorPlugin` when the source
|
|
104
|
+
* statically looks like it assigns to `module.exports`. Holds the wrapper
|
|
105
|
+
* `module` object so {@link unwrapConfig} can read back the user's CJS-style
|
|
106
|
+
* export. Pure-ESM configs skip the wrapper entirely and rely on the ESM
|
|
107
|
+
* `default` export instead.
|
|
108
|
+
*/
|
|
109
|
+
const VINEXT_CJS_EXPORTS_KEY = "__vinext_cjs_exports";
|
|
110
|
+
/**
|
|
111
|
+
* Companion named export pointing at the initial empty `{}` that the wrapper
|
|
112
|
+
* is constructed with. Lets {@link unwrapConfig} distinguish "user reassigned
|
|
113
|
+
* or mutated module.exports" from "module.exports is still the untouched
|
|
114
|
+
* empty wrapper" — the latter happens when {@link reassignsModuleExports}
|
|
115
|
+
* matches inside a string or comment (a harmless false positive that should
|
|
116
|
+
* still fall through to the ESM `default` export).
|
|
117
|
+
*/
|
|
118
|
+
const VINEXT_CJS_INITIAL_KEY = "__vinext_cjs_initial_exports";
|
|
119
|
+
/**
|
|
100
120
|
* Unwrap the config value from a loaded module namespace.
|
|
121
|
+
*
|
|
122
|
+
* Prefers `module.exports` (CJS style) when the config file reassigned it,
|
|
123
|
+
* otherwise falls back to `default`/the namespace itself. Mirrors Next.js's
|
|
124
|
+
* behaviour, where the config is loaded through `Module._compile` and CJS
|
|
125
|
+
* assignments override any ESM-style exports.
|
|
126
|
+
*
|
|
127
|
+
* The presence of the `__vinext_cjs_exports` named export is the static
|
|
128
|
+
* signal (set by `cjsGlobalsInjectorPlugin` when `reassignsModuleExports`
|
|
129
|
+
* matched) that this file might use CJS-style exports. We then disambiguate
|
|
130
|
+
* "user actually touched module.exports" from "static heuristic was a false
|
|
131
|
+
* positive" by comparing identity against the initial empty wrapper: if
|
|
132
|
+
* `module.exports` is still the original `{}`, fall back to ESM `default`.
|
|
101
133
|
*/
|
|
102
134
|
async function unwrapConfig(mod, phase = PHASE_DEVELOPMENT_SERVER) {
|
|
135
|
+
const cjsExports = (mod?.[VINEXT_CJS_EXPORTS_KEY])?.exports;
|
|
136
|
+
const cjsInitial = mod?.[VINEXT_CJS_INITIAL_KEY];
|
|
137
|
+
if (cjsExports !== void 0 && cjsExports !== null && (cjsExports !== cjsInitial || typeof cjsExports === "object" && Object.keys(cjsExports).length > 0)) return await resolveConfigValue(cjsExports, phase);
|
|
103
138
|
return await resolveConfigValue(mod.default ?? mod, phase);
|
|
104
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Resolve a path through filesystem symlinks, falling back to the original
|
|
142
|
+
* path when the file does not exist (e.g. virtual ids, query-suffixed ids).
|
|
143
|
+
*/
|
|
144
|
+
function safeRealpath(p) {
|
|
145
|
+
try {
|
|
146
|
+
return fs.realpathSync(p);
|
|
147
|
+
} catch {
|
|
148
|
+
return p;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Whole-word substring check for any of the CJS-style globals that the
|
|
153
|
+
* injector plugin would shim. Used to skip the transform entirely for the
|
|
154
|
+
* common case where the config is pure ESM (no `__filename`, `__dirname`,
|
|
155
|
+
* `require`, `module`, or `exports` references).
|
|
156
|
+
*
|
|
157
|
+
* False positives are harmless: a comment, string literal, or unrelated
|
|
158
|
+
* identifier like `node:module` will trigger the transform unnecessarily,
|
|
159
|
+
* but the resulting injection is idempotent and the loaded config is
|
|
160
|
+
* unaffected. False negatives would be a correctness bug, so we err on the
|
|
161
|
+
* side of matching too eagerly.
|
|
162
|
+
*
|
|
163
|
+
* Note: `\bexports\b` does not match `export default` (different word
|
|
164
|
+
* boundaries), and `\brequire\b` does not match `requireSomething`.
|
|
165
|
+
*/
|
|
166
|
+
function referencesCjsGlobals(source) {
|
|
167
|
+
return /\b(?:__filename|__dirname|require|module|exports)\b/.test(source);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Static heuristic: returns true when the source appears to assign to
|
|
171
|
+
* `module.exports` — either via `module.exports = …`, `module.exports.foo = …`,
|
|
172
|
+
* or `module.exports[…] = …`. Used to decide whether the injector plugin
|
|
173
|
+
* needs to wire up the wrapper `module` object so {@link unwrapConfig} can
|
|
174
|
+
* read back the user's CJS-style export.
|
|
175
|
+
*
|
|
176
|
+
* Pure-ESM configs skip the wrapper entirely, which means a faster transform
|
|
177
|
+
* (no extra `export const` line) and a simpler unwrap path (no need to
|
|
178
|
+
* disambiguate "initial empty object" from "user reassigned to {}").
|
|
179
|
+
*
|
|
180
|
+
* Like {@link referencesCjsGlobals}, false positives are harmless: at worst
|
|
181
|
+
* we emit an unused `__vinext_cjs_exports` named export, and `unwrapConfig`
|
|
182
|
+
* still prefers it (it points at an empty object, which then gets treated
|
|
183
|
+
* as the config — equivalent to today's sentinel logic for pure-ESM files
|
|
184
|
+
* that happen to mention `module.exports` only in a string).
|
|
185
|
+
*/
|
|
186
|
+
function reassignsModuleExports(source) {
|
|
187
|
+
return /\bmodule\s*\.\s*exports\b\s*(?:=(?!=)|\.\s*[A-Za-z_$][\w$]*\s*=(?!=)|\[)/.test(source);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Vite plugin that prepends CJS-style globals (`__filename`, `__dirname`,
|
|
191
|
+
* `module`, `exports`, `require`) to the next.config.* source before
|
|
192
|
+
* Vite's module runner evaluates it.
|
|
193
|
+
*
|
|
194
|
+
* Next.js's `next.config.ts` loader (packages/next/src/build/next-config-ts/
|
|
195
|
+
* transpile-config.ts → require-hook.ts) feeds the file through Node's
|
|
196
|
+
* `Module._compile`, which provides these CJS globals even when the source
|
|
197
|
+
* uses ESM syntax. Upstream test fixtures in `test/e2e/app-dir/next-config-ts*`
|
|
198
|
+
* rely on that, e.g. `node-api-cjs/next.config.ts` reads
|
|
199
|
+
* `fs.readFileSync(path.join(__dirname, 'foo.txt'), 'utf8')`. vinext loads
|
|
200
|
+
* configs through Vite's ESM-only module runner, so we inject the same
|
|
201
|
+
* globals as plain `const` declarations.
|
|
202
|
+
*
|
|
203
|
+
* For configs that don't reference any CJS global (the common case — every
|
|
204
|
+
* upstream `next-config-ts` fixture except `node-api-cjs` is pure ESM) we
|
|
205
|
+
* skip the transform entirely; see {@link referencesCjsGlobals}.
|
|
206
|
+
*
|
|
207
|
+
* `module.exports` reassignment is preserved by exposing the injected
|
|
208
|
+
* `module` object as a named export (see {@link VINEXT_CJS_EXPORTS_KEY}) and
|
|
209
|
+
* reading it back in {@link unwrapConfig}.
|
|
210
|
+
*/
|
|
211
|
+
function cjsGlobalsInjectorPlugin(configPath) {
|
|
212
|
+
const normalizedTarget = safeRealpath(path.resolve(configPath));
|
|
213
|
+
return {
|
|
214
|
+
name: "vinext:next-config-cjs-globals",
|
|
215
|
+
enforce: "pre",
|
|
216
|
+
transform(code, id) {
|
|
217
|
+
const idPath = id.startsWith("file://") ? fileURLToPath(id) : id.split("?")[0];
|
|
218
|
+
if (safeRealpath(path.resolve(idPath)) !== normalizedTarget) return null;
|
|
219
|
+
if (!referencesCjsGlobals(code)) return null;
|
|
220
|
+
const dirname = path.dirname(normalizedTarget);
|
|
221
|
+
const filenameLiteral = JSON.stringify(normalizedTarget);
|
|
222
|
+
const dirnameLiteral = JSON.stringify(dirname);
|
|
223
|
+
const requireBaseLiteral = JSON.stringify(path.join(dirname, "package.json"));
|
|
224
|
+
const moduleLines = reassignsModuleExports(code) ? `const __vinextInitialExports = {};
|
|
225
|
+
const module = { exports: __vinextInitialExports };
|
|
226
|
+
const exports = module.exports;
|
|
227
|
+
export const ${VINEXT_CJS_EXPORTS_KEY} = module;\nexport const ${VINEXT_CJS_INITIAL_KEY} = __vinextInitialExports;\n` : "";
|
|
228
|
+
return {
|
|
229
|
+
code: `import { createRequire as __vinextCreateRequire } from "node:module";\nconst __filename = ${filenameLiteral};\nconst __dirname = ${dirnameLiteral};\nconst require = __vinextCreateRequire(${requireBaseLiteral});\n` + moduleLines + code,
|
|
230
|
+
map: null
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}
|
|
105
235
|
function findNextConfigPath(root) {
|
|
106
236
|
for (const filename of CONFIG_FILES) {
|
|
107
237
|
const configPath = path.join(root, filename);
|
|
@@ -113,29 +243,84 @@ async function resolveNextConfigInput(config, phase = PHASE_DEVELOPMENT_SERVER)
|
|
|
113
243
|
return await resolveConfigValue(config, phase);
|
|
114
244
|
}
|
|
115
245
|
/**
|
|
246
|
+
* Load a CJS-flavoured next.config.{js,cjs} via createRequire.
|
|
247
|
+
*
|
|
248
|
+
* For `.cjs` (or `.js` in a non-type-module package) Node's loader picks the
|
|
249
|
+
* right format automatically and `require()` just works. For `.js` in a
|
|
250
|
+
* `"type": "module"` package, Node infers ESM from package.json and the file
|
|
251
|
+
* fails with `require is not defined`. In that case we copy the source to a
|
|
252
|
+
* sibling temp `.cjs` (where the explicit extension forces CJS regardless of
|
|
253
|
+
* the parent type field) and require *that*. Relative imports inside the
|
|
254
|
+
* config still resolve against the original directory.
|
|
255
|
+
*/
|
|
256
|
+
async function loadConfigViaRequire(configPath, root, phase) {
|
|
257
|
+
const require = createRequire(path.join(root, "package.json"));
|
|
258
|
+
try {
|
|
259
|
+
return await unwrapConfig(require(configPath), phase);
|
|
260
|
+
} catch (e) {
|
|
261
|
+
if (!isCjsError(e) || !configPath.endsWith(".js")) throw e;
|
|
262
|
+
return await loadConfigViaCjsTempCopy(configPath, root, phase);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
async function loadConfigViaCjsTempCopy(configPath, root, phase) {
|
|
266
|
+
const dir = path.dirname(configPath);
|
|
267
|
+
const tmpPath = path.join(dir, `.vinext-next-config.${process.pid}.${Date.now()}.cjs`);
|
|
268
|
+
fs.copyFileSync(configPath, tmpPath);
|
|
269
|
+
try {
|
|
270
|
+
return await unwrapConfig(createRequire(path.join(root, "package.json"))(tmpPath), phase);
|
|
271
|
+
} finally {
|
|
272
|
+
try {
|
|
273
|
+
fs.unlinkSync(tmpPath);
|
|
274
|
+
} catch {}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
116
278
|
* Find and load the next.config file from the project root.
|
|
117
279
|
* Returns null if no config file is found.
|
|
118
280
|
*
|
|
119
281
|
* Attempts Vite's module runner first so TS configs and extensionless local
|
|
120
282
|
* imports (e.g. `import "./env"`) resolve consistently. If loading fails due
|
|
121
283
|
* to CJS constructs (`require`, `module.exports`), falls back to `createRequire`
|
|
122
|
-
* so common CJS plugin wrappers (nextra, @next/mdx, etc.) still work
|
|
284
|
+
* so common CJS plugin wrappers (nextra, @next/mdx, etc.) still work, including
|
|
285
|
+
* `next.config.js` files written in CJS syntax inside a `"type": "module"`
|
|
286
|
+
* package (the common shape after `vinext init`).
|
|
123
287
|
*/
|
|
124
288
|
async function loadNextConfig(root, phase = DEFAULT_PHASE) {
|
|
125
289
|
const configPath = findNextConfigPath(root);
|
|
126
290
|
if (!configPath) return null;
|
|
127
291
|
const filename = path.basename(configPath);
|
|
292
|
+
const tsconfigAliases = loadTsconfigPathAliasesForRoot(root);
|
|
293
|
+
const normalizedConfigPath = safeRealpath(path.resolve(configPath));
|
|
128
294
|
try {
|
|
129
295
|
const { runnerImport } = await import("vite");
|
|
130
296
|
const { module: mod } = await runnerImport(configPath, {
|
|
131
297
|
root,
|
|
132
298
|
logLevel: "error",
|
|
133
|
-
clearScreen: false
|
|
299
|
+
clearScreen: false,
|
|
300
|
+
resolve: {
|
|
301
|
+
alias: tsconfigAliases,
|
|
302
|
+
extensions: [
|
|
303
|
+
".mjs",
|
|
304
|
+
".js",
|
|
305
|
+
".cjs",
|
|
306
|
+
".mts",
|
|
307
|
+
".ts",
|
|
308
|
+
".cts",
|
|
309
|
+
".jsx",
|
|
310
|
+
".tsx",
|
|
311
|
+
".json"
|
|
312
|
+
]
|
|
313
|
+
},
|
|
314
|
+
plugins: [.../\.[cm]?ts$/.test(configPath) ? [cjsGlobalsInjectorPlugin(configPath)] : [], commonjs({ filter: (id) => {
|
|
315
|
+
const idPath = id.startsWith("file://") ? fileURLToPath(id) : id.split("?")[0];
|
|
316
|
+
if (safeRealpath(path.resolve(idPath)) === normalizedConfigPath) return false;
|
|
317
|
+
return id.includes("node_modules") ? true : void 0;
|
|
318
|
+
} })]
|
|
134
319
|
});
|
|
135
320
|
return await unwrapConfig(mod, phase);
|
|
136
321
|
} catch (e) {
|
|
137
322
|
if (isCjsError(e) && (filename.endsWith(".js") || filename.endsWith(".cjs"))) try {
|
|
138
|
-
return await
|
|
323
|
+
return await loadConfigViaRequire(configPath, root, phase);
|
|
139
324
|
} catch (e2) {
|
|
140
325
|
warnConfigLoadFailure(filename, e2);
|
|
141
326
|
throw e2;
|
|
@@ -169,6 +354,32 @@ async function resolveBuildId(generate) {
|
|
|
169
354
|
if (trimmed.length === 0) throw new Error("generateBuildId returned an empty string. https://nextjs.org/docs/messages/generatebuildid-not-a-string");
|
|
170
355
|
return trimmed;
|
|
171
356
|
}
|
|
357
|
+
/**
|
|
358
|
+
* Normalize the `assetPrefix` option from next.config.
|
|
359
|
+
*
|
|
360
|
+
* Accepts both absolute URLs (`https://cdn.example.com[/subpath]`) and
|
|
361
|
+
* path prefixes (`/custom-asset-prefix`). Trailing slashes are trimmed.
|
|
362
|
+
* Empty/whitespace-only strings are treated as unset and return `""`.
|
|
363
|
+
*
|
|
364
|
+
* Path prefixes that omit the leading slash get one added so they always
|
|
365
|
+
* begin with `/` — this matches how Next.js routes match against them.
|
|
366
|
+
*
|
|
367
|
+
* Non-string values are rejected to surface config mistakes early.
|
|
368
|
+
*
|
|
369
|
+
* @see https://nextjs.org/docs/app/api-reference/config/next-config-js/assetPrefix
|
|
370
|
+
*/
|
|
371
|
+
function normalizeAssetPrefix(value) {
|
|
372
|
+
if (value === void 0 || value === null || value === "") return "";
|
|
373
|
+
if (typeof value !== "string") throw new Error(`Invalid \`assetPrefix\` configuration: must be a string, got ${typeof value}. Accepts a path prefix ("/custom-asset-prefix") or an absolute URL ("https://cdn.example.com").`);
|
|
374
|
+
let trimmed = value.trim();
|
|
375
|
+
while (trimmed.endsWith("/")) trimmed = trimmed.slice(0, -1);
|
|
376
|
+
if (trimmed === "") return "";
|
|
377
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
378
|
+
if (!URL.canParse(trimmed)) throw new Error(`Invalid \`assetPrefix\` configuration: "${value}" is not a parseable URL.`);
|
|
379
|
+
return trimmed;
|
|
380
|
+
}
|
|
381
|
+
return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
382
|
+
}
|
|
172
383
|
function resolveDeploymentId(configDeploymentId) {
|
|
173
384
|
const deploymentId = configDeploymentId !== void 0 ? configDeploymentId : process.env.NEXT_DEPLOYMENT_ID;
|
|
174
385
|
if (deploymentId === void 0 || deploymentId === "") return void 0;
|
|
@@ -198,6 +409,7 @@ async function resolveNextConfig(config, root = process.cwd()) {
|
|
|
198
409
|
const resolved = {
|
|
199
410
|
env: {},
|
|
200
411
|
basePath: "",
|
|
412
|
+
assetPrefix: "",
|
|
201
413
|
trailingSlash: false,
|
|
202
414
|
output: "",
|
|
203
415
|
pageExtensions: normalizePageExtensions(),
|
|
@@ -224,7 +436,8 @@ async function resolveNextConfig(config, root = process.cwd()) {
|
|
|
224
436
|
enablePrerenderSourceMaps: true,
|
|
225
437
|
hashSalt: process.env.NEXT_HASH_SALT ?? "",
|
|
226
438
|
buildId,
|
|
227
|
-
deploymentId
|
|
439
|
+
deploymentId,
|
|
440
|
+
sassOptions: null
|
|
228
441
|
};
|
|
229
442
|
detectNextIntlConfig(root, resolved);
|
|
230
443
|
return resolved;
|
|
@@ -298,6 +511,7 @@ async function resolveNextConfig(config, root = process.cwd()) {
|
|
|
298
511
|
const resolved = {
|
|
299
512
|
env: config.env ?? {},
|
|
300
513
|
basePath: config.basePath ?? "",
|
|
514
|
+
assetPrefix: normalizeAssetPrefix(config.assetPrefix),
|
|
301
515
|
trailingSlash: config.trailingSlash ?? false,
|
|
302
516
|
output: output === "export" || output === "standalone" ? output : "",
|
|
303
517
|
pageExtensions,
|
|
@@ -320,9 +534,11 @@ async function resolveNextConfig(config, root = process.cwd()) {
|
|
|
320
534
|
enablePrerenderSourceMaps: config.enablePrerenderSourceMaps ?? true,
|
|
321
535
|
hashSalt,
|
|
322
536
|
buildId,
|
|
323
|
-
deploymentId
|
|
537
|
+
deploymentId,
|
|
538
|
+
sassOptions: config.sassOptions && typeof config.sassOptions === "object" ? config.sassOptions : null
|
|
324
539
|
};
|
|
325
540
|
detectNextIntlConfig(root, resolved);
|
|
541
|
+
if (resolved.basePath !== "" && resolved.basePath !== "/" && resolved.assetPrefix === "") resolved.assetPrefix = resolved.basePath;
|
|
326
542
|
return resolved;
|
|
327
543
|
}
|
|
328
544
|
function normalizeAliasEntries(aliases, root) {
|
|
@@ -476,6 +692,6 @@ function extractPluginsFromOptions(opts) {
|
|
|
476
692
|
return null;
|
|
477
693
|
}
|
|
478
694
|
//#endregion
|
|
479
|
-
export { PHASE_PRODUCTION_BUILD, detectNextIntlConfig, extractMdxOptions, findNextConfigPath, loadNextConfig, parseBodySizeLimit, resolveNextConfig, resolveNextConfigInput };
|
|
695
|
+
export { PHASE_PRODUCTION_BUILD, detectNextIntlConfig, extractMdxOptions, findNextConfigPath, loadNextConfig, normalizeAssetPrefix, parseBodySizeLimit, reassignsModuleExports, referencesCjsGlobals, resolveNextConfig, resolveNextConfigInput };
|
|
480
696
|
|
|
481
697
|
//# sourceMappingURL=next-config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"next-config.js","names":[],"sources":["../../src/config/next-config.ts"],"sourcesContent":["/**\n * next.config.js / next.config.mjs / next.config.ts parser\n *\n * Loads the Next.js config file (if present) and extracts supported options.\n * Unsupported options are logged as warnings.\n */\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport fs from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { randomUUID } from \"node:crypto\";\nimport { PHASE_DEVELOPMENT_SERVER } from \"vinext/shims/constants\";\nimport { normalizePageExtensions } from \"../routing/file-matcher.js\";\nimport { isExternalUrl } from \"./config-matchers.js\";\n\n/**\n * Parse a body size limit value (string or number) into bytes.\n * Accepts Next.js-style strings like \"1mb\", \"500kb\", \"10mb\", bare number strings like \"1048576\" (bytes),\n * and numeric values. Supports b, kb, mb, gb, tb, pb units.\n * Returns the default 1MB if the value is not provided or invalid.\n * Throws if the parsed value is less than 1.\n */\nexport function parseBodySizeLimit(value: string | number | undefined | null): number {\n if (value === undefined || value === null) return 1 * 1024 * 1024;\n if (typeof value === \"number\") {\n if (value < 1) throw new Error(`Body size limit must be a positive number, got ${value}`);\n return value;\n }\n const trimmed = value.trim();\n const match = trimmed.match(/^(\\d+(?:\\.\\d+)?)\\s*(b|kb|mb|gb|tb|pb)?$/i);\n if (!match) {\n console.warn(\n `[vinext] Invalid bodySizeLimit value: \"${value}\". Expected a number or a string like \"1mb\", \"500kb\". Falling back to 1MB.`,\n );\n return 1 * 1024 * 1024;\n }\n const num = parseFloat(match[1]);\n const unit = (match[2] ?? \"b\").toLowerCase();\n let bytes: number;\n switch (unit) {\n case \"b\":\n bytes = Math.floor(num);\n break;\n case \"kb\":\n bytes = Math.floor(num * 1024);\n break;\n case \"mb\":\n bytes = Math.floor(num * 1024 * 1024);\n break;\n case \"gb\":\n bytes = Math.floor(num * 1024 * 1024 * 1024);\n break;\n case \"tb\":\n bytes = Math.floor(num * 1024 * 1024 * 1024 * 1024);\n break;\n case \"pb\":\n bytes = Math.floor(num * 1024 * 1024 * 1024 * 1024 * 1024);\n break;\n default:\n return 1 * 1024 * 1024;\n }\n if (bytes < 1) throw new Error(`Body size limit must be a positive number, got ${bytes}`);\n return bytes;\n}\n\nexport type HasCondition = {\n type: \"header\" | \"cookie\" | \"query\" | \"host\";\n key: string;\n value?: string;\n};\n\nexport type NextRedirect = {\n source: string;\n destination: string;\n permanent: boolean;\n has?: HasCondition[];\n missing?: HasCondition[];\n};\n\nexport type NextRewrite = {\n source: string;\n destination: string;\n has?: HasCondition[];\n missing?: HasCondition[];\n};\n\nexport type NextHeader = {\n source: string;\n has?: HasCondition[];\n missing?: HasCondition[];\n headers: Array<{ key: string; value: string }>;\n};\n\nexport type NextI18nConfig = {\n /** List of supported locales */\n locales: string[];\n /** The default locale (used when no locale prefix is in the URL) */\n defaultLocale: string;\n /**\n * Whether to auto-detect locale from Accept-Language header.\n * Defaults to true in Next.js.\n */\n localeDetection?: boolean;\n /**\n * Domain-based routing. Each domain maps to a specific locale.\n */\n domains?: Array<{\n domain: string;\n defaultLocale: string;\n locales?: string[];\n http?: boolean;\n }>;\n};\n\n/**\n * MDX compilation options extracted from @next/mdx config.\n * These are passed through to @mdx-js/rollup so that custom\n * remark/rehype/recma plugins configured in next.config work with Vite.\n */\nexport type MdxOptions = {\n remarkPlugins?: unknown[];\n rehypePlugins?: unknown[];\n recmaPlugins?: unknown[];\n};\n\nexport type NextConfig = {\n /** Additional env variables */\n env?: Record<string, string>;\n /** Base URL path prefix */\n basePath?: string;\n /** Whether to add trailing slashes */\n trailingSlash?: boolean;\n /** Internationalization routing config */\n i18n?: NextI18nConfig;\n /** URL redirect rules */\n redirects?: () => Promise<NextRedirect[]> | NextRedirect[];\n /** URL rewrite rules */\n rewrites?: () =>\n | Promise<\n | NextRewrite[]\n | {\n beforeFiles: NextRewrite[];\n afterFiles: NextRewrite[];\n fallback: NextRewrite[];\n }\n >\n | NextRewrite[]\n | {\n beforeFiles: NextRewrite[];\n afterFiles: NextRewrite[];\n fallback: NextRewrite[];\n };\n /** Custom response headers */\n headers?: () => Promise<NextHeader[]> | NextHeader[];\n /** Image optimization config */\n images?: {\n remotePatterns?: Array<{\n protocol?: string;\n hostname: string;\n port?: string;\n pathname?: string;\n search?: string;\n }>;\n domains?: string[];\n unoptimized?: boolean;\n /** Allowed device widths for image optimization. Defaults to Next.js defaults: [640, 750, 828, 1080, 1200, 1920, 2048, 3840] */\n deviceSizes?: number[];\n /** Allowed image sizes for fixed-width images. Defaults to Next.js defaults: [16, 32, 48, 64, 96, 128, 256, 384] */\n imageSizes?: number[];\n /** Allow SVG images through the image optimization endpoint. SVG can contain scripts, so only enable if you trust all image sources. */\n dangerouslyAllowSVG?: boolean;\n /** Allow image optimization for hostnames that resolve to private IP addresses. This is a security risk (SSRF) — only enable for private networks when you understand the risk. */\n dangerouslyAllowLocalIP?: boolean;\n /** Content-Disposition header for image responses. Defaults to \"inline\". */\n contentDispositionType?: \"inline\" | \"attachment\";\n /** Content-Security-Policy header for image responses. Defaults to \"script-src 'none'; frame-src 'none'; sandbox;\" */\n contentSecurityPolicy?: string;\n };\n /** Build output mode: 'export' for full static export, 'standalone' for single server */\n output?: \"export\" | \"standalone\";\n /** File extensions treated as routable pages/routes (Next.js pageExtensions) */\n pageExtensions?: string[];\n /** Extra origins allowed to access the dev server. */\n allowedDevOrigins?: string[];\n /** Maximum age in seconds for stale ISR entries before blocking regeneration. */\n expireTime?: number;\n /**\n * Enable Cache Components (Next.js 16).\n * When true, enables the \"use cache\" directive for pages, components, and functions.\n * Replaces the removed experimental.ppr and experimental.dynamicIO flags.\n */\n cacheComponents?: boolean;\n /**\n * Enables source maps while generating static pages.\n * Helps with errors during the prerender phase in `vinext build`.\n * Defaults to `true`. Set to `false` to disable.\n */\n enablePrerenderSourceMaps?: boolean;\n /** Transpile packages (Vite handles this natively) */\n transpilePackages?: string[];\n /**\n * Packages that should be treated as server-external (not bundled by Vite).\n * Corresponds to Next.js `serverExternalPackages` (or the legacy\n * `experimental.serverComponentsExternalPackages`).\n */\n serverExternalPackages?: string[];\n /** Webpack config (ignored — we use Vite) */\n webpack?: unknown;\n /**\n * Path to a custom cache handler module (e.g., KV, Redis, DynamoDB).\n * Accepts relative paths, absolute paths, or file:// URLs from import.meta.resolve().\n * When \"type\": \"module\" is set in package.json, use import.meta.resolve() instead of\n * require.resolve() to get a valid path.\n */\n cacheHandler?: string;\n /**\n * Maximum memory size (bytes) for the default in-memory cache handler.\n * Set to 0 to disable in-memory caching entirely.\n */\n cacheMaxMemorySize?: number;\n /**\n * Custom build ID generator. If provided, called once at build/dev start.\n * Must return a non-empty string, or null to use the default random ID.\n */\n generateBuildId?: () => string | null | Promise<string | null>;\n /** Identifier for deployment-aware cache keys and version skew protection. */\n deploymentId?: string;\n /** Any other options */\n [key: string]: unknown;\n};\n\nexport type NextConfigFactory = (\n phase: string,\n opts: { defaultConfig: NextConfig },\n) => NextConfig | Promise<NextConfig>;\n\nexport type NextConfigInput = NextConfig | NextConfigFactory;\n\n/**\n * Resolved configuration with all async values awaited.\n */\nexport type ResolvedNextConfig = {\n env: Record<string, string>;\n basePath: string;\n trailingSlash: boolean;\n output: \"\" | \"export\" | \"standalone\";\n pageExtensions: string[];\n cacheComponents: boolean;\n redirects: NextRedirect[];\n rewrites: {\n beforeFiles: NextRewrite[];\n afterFiles: NextRewrite[];\n fallback: NextRewrite[];\n };\n headers: NextHeader[];\n images: NextConfig[\"images\"];\n i18n: NextI18nConfig | null;\n /** MDX remark/rehype/recma plugins extracted from @next/mdx config */\n mdx: MdxOptions | null;\n /** Explicit module aliases preserved from wrapped next.config plugins. */\n aliases: Record<string, string>;\n /** Extra allowed origins for dev server access (from allowedDevOrigins). */\n allowedDevOrigins: string[];\n /** Extra allowed origins for server action CSRF validation (from experimental.serverActions.allowedOrigins). */\n serverActionsAllowedOrigins: string[];\n /** Packages whose barrel imports should be optimized (from experimental.optimizePackageImports). */\n optimizePackageImports: string[];\n /** Parsed body size limit for server actions in bytes (from experimental.serverActions.bodySizeLimit). Defaults to 1MB. */\n serverActionsBodySizeLimit: number;\n /** Route-level expire fallback in seconds for ISR entries with numeric revalidate. */\n expireTime: number;\n /**\n * Packages that should be treated as server-external (not bundled by Vite).\n * Sourced from `serverExternalPackages` or the legacy\n * `experimental.serverComponentsExternalPackages` in next.config.\n */\n serverExternalPackages: string[];\n /** Enable sourcemaps for prerender error stack traces. Defaults to true. */\n enablePrerenderSourceMaps: boolean;\n /** Resolved build ID (from generateBuildId, or a random UUID if not provided). */\n buildId: string;\n /** Resolved deployment ID from next.config.js or NEXT_DEPLOYMENT_ID. */\n deploymentId: string | undefined;\n /**\n * Path to a custom cache handler module. file:// URLs are resolved to\n * filesystem paths via fileURLToPath() during config resolution.\n */\n cacheHandler: string | undefined;\n /**\n * Maximum memory size (bytes) for the default in-memory cache handler.\n * Set to 0 to disable in-memory caching entirely.\n */\n cacheMaxMemorySize: number | undefined;\n /**\n * Concatenated hash salt from `experimental.outputHashSalt` config option\n * and `NEXT_HASH_SALT` environment variable. Empty string when neither is set.\n * When non-empty, mix into content-addressed output filenames so hash values\n * change without modifying source — useful for cache-busting after CDN poisoning.\n */\n hashSalt: string;\n};\n\nconst CONFIG_FILES = [\"next.config.ts\", \"next.config.mjs\", \"next.config.js\", \"next.config.cjs\"];\nconst DEFAULT_EXPIRE_TIME = 31_536_000;\n\n/**\n * Check whether an error indicates a CJS module was loaded in an ESM context\n * (i.e. the file uses `require()` which is not available in ESM).\n */\nfunction isCjsError(e: unknown): boolean {\n if (!(e instanceof Error)) return false;\n const msg = e.message;\n return (\n msg.includes(\"require is not a function\") ||\n msg.includes(\"require is not defined\") ||\n msg.includes(\"exports is not defined\") ||\n msg.includes(\"module is not defined\") ||\n msg.includes(\"__dirname is not defined\") ||\n msg.includes(\"__filename is not defined\")\n );\n}\n\n// Dev-server phase is the safe default for config loading: it enables all\n// optional config sections (headers, redirects, rewrites) without triggering\n// build-only behaviour. Used in two default parameter values below to avoid\n// repeating PHASE_DEVELOPMENT_SERVER inline.\nconst DEFAULT_PHASE = PHASE_DEVELOPMENT_SERVER;\n\n/**\n * Emit a warning when config loading fails, with a targeted hint for\n * known plugin wrappers that are unnecessary in vinext.\n */\nfunction warnConfigLoadFailure(filename: string, err: Error): void {\n const msg = err.message ?? \"\";\n const stack = err.stack ?? \"\";\n const isNextIntlPlugin =\n msg.includes(\"next-intl\") ||\n stack.includes(\"next-intl/plugin\") ||\n stack.includes(\"next-intl/dist\");\n\n console.log();\n console.error(`[vinext] Failed to load ${filename}: ${msg}`);\n console.log();\n if (isNextIntlPlugin) {\n console.warn(\n \"[vinext] Hint: createNextIntlPlugin() is not needed with vinext. \" +\n \"Remove the next-intl/plugin wrapper from your next.config — \" +\n \"vinext auto-detects next-intl and registers the i18n config alias automatically.\",\n );\n }\n}\n\n/**\n * Resolve a Next-style config value, calling it if it's a function-form config\n * (Next.js supports `module.exports = (phase, opts) => config`).\n */\nasync function resolveConfigValue(\n config: unknown,\n phase: string = DEFAULT_PHASE,\n): Promise<NextConfig> {\n if (typeof config === \"function\") {\n const result = await config(phase, {\n defaultConfig: {},\n });\n return result as NextConfig;\n }\n return config as NextConfig;\n}\n\n/**\n * Unwrap the config value from a loaded module namespace.\n */\nasync function unwrapConfig(\n // oxlint-disable-next-line typescript/no-explicit-any\n mod: any,\n phase: string = PHASE_DEVELOPMENT_SERVER,\n): Promise<NextConfig> {\n return await resolveConfigValue(mod.default ?? mod, phase);\n}\n\nexport function findNextConfigPath(root: string): string | null {\n for (const filename of CONFIG_FILES) {\n const configPath = path.join(root, filename);\n if (fs.existsSync(configPath)) return configPath;\n }\n return null;\n}\n\nexport async function resolveNextConfigInput(\n config: NextConfigInput,\n phase: string = PHASE_DEVELOPMENT_SERVER,\n): Promise<NextConfig> {\n // Inline vinext({ nextConfig }) already receives the config value itself,\n // not a module namespace object, so do not treat a \"default\" key specially.\n return await resolveConfigValue(config, phase);\n}\n\n/**\n * Find and load the next.config file from the project root.\n * Returns null if no config file is found.\n *\n * Attempts Vite's module runner first so TS configs and extensionless local\n * imports (e.g. `import \"./env\"`) resolve consistently. If loading fails due\n * to CJS constructs (`require`, `module.exports`), falls back to `createRequire`\n * so common CJS plugin wrappers (nextra, @next/mdx, etc.) still work.\n */\nexport async function loadNextConfig(\n root: string,\n phase: string = DEFAULT_PHASE,\n): Promise<NextConfig | null> {\n const configPath = findNextConfigPath(root);\n if (!configPath) return null;\n\n const filename = path.basename(configPath);\n\n try {\n // Load config via Vite's module runner (TS + extensionless import support)\n const { runnerImport } = await import(\"vite\");\n const { module: mod } = await runnerImport(configPath, {\n root,\n logLevel: \"error\",\n clearScreen: false,\n });\n return await unwrapConfig(mod, phase);\n } catch (e) {\n // If the error indicates a CJS file loaded in ESM context, retry with\n // createRequire which provides a proper CommonJS environment.\n if (isCjsError(e) && (filename.endsWith(\".js\") || filename.endsWith(\".cjs\"))) {\n try {\n const require = createRequire(path.join(root, \"package.json\"));\n const mod = require(configPath);\n return await unwrapConfig(mod, phase);\n } catch (e2) {\n warnConfigLoadFailure(filename, e2 as Error);\n throw e2;\n }\n }\n\n warnConfigLoadFailure(filename, e as Error);\n throw e;\n }\n}\n\n/**\n * Generate a UUID that doesn't contain \"ad\" to avoid false-positive ad-blocker hits.\n * Mirrors Next.js's own nanoid retry loop.\n */\nfunction safeUUID(): string {\n let id = randomUUID();\n while (/ad/i.test(id)) id = randomUUID();\n return id;\n}\n\n/**\n * Call the user's generateBuildId function and validate its return value.\n * Follows Next.js semantics: null return falls back to a random UUID; any\n * other non-string throws. Leading/trailing whitespace is trimmed.\n *\n * @see https://nextjs.org/docs/app/api-reference/config/next-config-js/generateBuildId\n */\nasync function resolveBuildId(\n generate: (() => string | null | Promise<string | null>) | undefined,\n): Promise<string> {\n if (!generate) return safeUUID();\n\n const result = await generate();\n\n if (result === null) return safeUUID();\n\n if (typeof result !== \"string\") {\n throw new Error(\n \"generateBuildId did not return a string. https://nextjs.org/docs/messages/generatebuildid-not-a-string\",\n );\n }\n\n const trimmed = result.trim();\n if (trimmed.length === 0) {\n throw new Error(\n \"generateBuildId returned an empty string. https://nextjs.org/docs/messages/generatebuildid-not-a-string\",\n );\n }\n\n return trimmed;\n}\n\nfunction resolveDeploymentId(configDeploymentId: unknown): string | undefined {\n const deploymentId =\n configDeploymentId !== undefined ? configDeploymentId : process.env.NEXT_DEPLOYMENT_ID;\n if (deploymentId === undefined || deploymentId === \"\") return undefined;\n\n if (typeof deploymentId !== \"string\") {\n throw new Error(\n \"Invalid `deploymentId` configuration: must be a string. https://nextjs.org/docs/messages/deploymentid-not-a-string\",\n );\n }\n\n if (!/^[a-zA-Z0-9_-]+$/.test(deploymentId)) {\n throw new Error(\n \"Invalid `deploymentId` configuration: contains invalid characters. Only alphanumeric characters, hyphens, and underscores are allowed. https://nextjs.org/docs/messages/deploymentid-invalid-characters\",\n );\n }\n\n return deploymentId;\n}\n\n/**\n * Converts a cache handler path to a filesystem path.\n * ESM's import.meta.resolve() returns file:// URLs which break when concatenated\n * with path operations like path.join or path.relative.\n * @param filePath - Absolute path, relative path, or file:// URL (e.g. from import.meta.resolve)\n * @returns A filesystem path suitable for path operations\n */\nfunction resolveCacheHandlerPathToFilesystem(filePath: string): string {\n if (filePath.startsWith(\"file://\")) {\n return fileURLToPath(filePath);\n }\n return filePath;\n}\n\n/**\n * Resolve a NextConfig into a fully-resolved ResolvedNextConfig.\n * Awaits async functions for redirects/rewrites/headers.\n */\nexport async function resolveNextConfig(\n config: NextConfig | null,\n root: string = process.cwd(),\n): Promise<ResolvedNextConfig> {\n if (!config) {\n const buildId = await resolveBuildId(undefined);\n const deploymentId = resolveDeploymentId(undefined);\n const resolved: ResolvedNextConfig = {\n env: {},\n basePath: \"\",\n trailingSlash: false,\n output: \"\",\n pageExtensions: normalizePageExtensions(),\n cacheComponents: false,\n redirects: [],\n rewrites: { beforeFiles: [], afterFiles: [], fallback: [] },\n headers: [],\n images: undefined,\n i18n: null,\n mdx: null,\n aliases: {},\n allowedDevOrigins: [],\n serverActionsAllowedOrigins: [],\n optimizePackageImports: [],\n serverActionsBodySizeLimit: 1 * 1024 * 1024,\n expireTime: DEFAULT_EXPIRE_TIME,\n serverExternalPackages: [],\n cacheHandler: undefined,\n cacheMaxMemorySize: undefined,\n enablePrerenderSourceMaps: true,\n hashSalt: process.env.NEXT_HASH_SALT ?? \"\",\n buildId,\n deploymentId,\n };\n detectNextIntlConfig(root, resolved);\n return resolved;\n }\n\n // Resolve redirects\n let redirects: NextRedirect[] = [];\n if (config.redirects) {\n const result = await config.redirects();\n redirects = Array.isArray(result) ? result : [];\n }\n\n // Resolve rewrites\n let rewrites = {\n beforeFiles: [] as NextRewrite[],\n afterFiles: [] as NextRewrite[],\n fallback: [] as NextRewrite[],\n };\n if (config.rewrites) {\n const result = await config.rewrites();\n if (Array.isArray(result)) {\n rewrites.afterFiles = result;\n } else {\n rewrites = {\n beforeFiles: result.beforeFiles ?? [],\n afterFiles: result.afterFiles ?? [],\n fallback: result.fallback ?? [],\n };\n }\n }\n\n {\n const allRewrites = [...rewrites.beforeFiles, ...rewrites.afterFiles, ...rewrites.fallback];\n const externalRewrites = allRewrites.filter((rewrite) => isExternalUrl(rewrite.destination));\n\n if (externalRewrites.length > 0) {\n const noun = externalRewrites.length === 1 ? \"external rewrite\" : \"external rewrites\";\n const listing = externalRewrites\n .map((rewrite) => ` ${rewrite.source} → ${rewrite.destination}`)\n .join(\"\\n\");\n\n console.warn(\n `[vinext] Found ${externalRewrites.length} ${noun} that proxy requests to external origins:\\n` +\n `${listing}\\n` +\n `Request headers, including credential headers (cookie, authorization, proxy-authorization, x-api-key), ` +\n `are forwarded to the external origin to match Next.js behavior. ` +\n `If you do not want to forward credentials, use an API route or route handler where you control exactly which headers are sent.`,\n );\n }\n }\n\n // Resolve headers\n let headers: NextHeader[] = [];\n if (config.headers) {\n headers = await config.headers();\n }\n\n // Probe wrapped webpack config once so alias extraction and MDX extraction\n // observe the same mock environment.\n const webpackProbe = await probeWebpackConfig(config, root);\n const mdx = webpackProbe.mdx;\n const aliases = {\n ...extractTurboAliases(config, root),\n ...webpackProbe.aliases,\n };\n\n const allowedDevOrigins = Array.isArray(config.allowedDevOrigins) ? config.allowedDevOrigins : [];\n\n // Resolve serverActions.allowedOrigins and bodySizeLimit from experimental config\n const experimental = config.experimental as Record<string, unknown> | undefined;\n const serverActionsConfig = experimental?.serverActions as Record<string, unknown> | undefined;\n const serverActionsAllowedOrigins = Array.isArray(serverActionsConfig?.allowedOrigins)\n ? (serverActionsConfig.allowedOrigins as string[])\n : [];\n const serverActionsBodySizeLimit = parseBodySizeLimit(\n serverActionsConfig?.bodySizeLimit as string | number | undefined,\n );\n\n // Resolve hashSalt from experimental.outputHashSalt config + NEXT_HASH_SALT env var.\n // Next.js concatenates them: config value first, then env var.\n const configOutputHashSalt = experimental?.outputHashSalt as string | undefined;\n const hashSalt = (configOutputHashSalt ?? \"\") + (process.env.NEXT_HASH_SALT ?? \"\");\n\n // Resolve optimizePackageImports from experimental config\n const rawOptimize = experimental?.optimizePackageImports;\n const optimizePackageImports = Array.isArray(rawOptimize)\n ? rawOptimize.filter((x): x is string => typeof x === \"string\")\n : [];\n\n // Resolve serverExternalPackages — support the current top-level key and the\n // legacy experimental.serverComponentsExternalPackages name that Next.js still\n // accepts (it moved out of experimental in Next.js 14.2).\n const legacyServerComponentsExternal = experimental?.serverComponentsExternalPackages;\n const serverExternalPackages: string[] = Array.isArray(config.serverExternalPackages)\n ? (config.serverExternalPackages as string[])\n : Array.isArray(legacyServerComponentsExternal)\n ? (legacyServerComponentsExternal as string[])\n : [];\n\n // Warn about unsupported experimental.swcEnvOptions. vinext uses Vite for\n // transforms, not SWC, so automatic polyfill injection is not applicable.\n if (experimental?.swcEnvOptions !== undefined) {\n console.warn(\n '[vinext] next.config option \"experimental.swcEnvOptions\" is not applicable and will be ignored (vinext uses Vite, not SWC). ' +\n \"A Vite-compatible polyfill solution may be explored in the future.\",\n );\n }\n\n // Warn about unsupported webpack usage. We preserve alias injection and\n // extract MDX settings, but all other webpack customization is still ignored.\n if (config.webpack !== undefined) {\n if (mdx || Object.keys(webpackProbe.aliases).length > 0) {\n console.warn(\n '[vinext] next.config option \"webpack\" is only partially supported. ' +\n \"vinext preserves resolve.alias entries and MDX loader settings, but other webpack customization is ignored\",\n );\n } else {\n console.warn(\n '[vinext] next.config option \"webpack\" is not yet supported and will be ignored',\n );\n }\n }\n\n const output = config.output ?? \"\";\n if (output && output !== \"export\" && output !== \"standalone\") {\n console.warn(`[vinext] Unknown output mode \"${output as string}\", ignoring`);\n }\n\n const pageExtensions = normalizePageExtensions(config.pageExtensions);\n\n // Parse i18n config\n let i18n: NextI18nConfig | null = null;\n if (config.i18n) {\n i18n = {\n locales: config.i18n.locales,\n defaultLocale: config.i18n.defaultLocale,\n localeDetection: config.i18n.localeDetection ?? true,\n domains: config.i18n.domains,\n };\n }\n\n const buildId = await resolveBuildId(\n config.generateBuildId as (() => string | null | Promise<string | null>) | undefined,\n );\n const deploymentId = resolveDeploymentId(config.deploymentId);\n\n // Resolve cacheHandler path — handle file:// URLs from import.meta.resolve()\n const cacheHandler: string | undefined =\n typeof config.cacheHandler === \"string\"\n ? resolveCacheHandlerPathToFilesystem(config.cacheHandler)\n : undefined;\n\n // Resolve cacheMaxMemorySize\n const cacheMaxMemorySize: number | undefined =\n typeof config.cacheMaxMemorySize === \"number\" ? config.cacheMaxMemorySize : undefined;\n\n const resolved: ResolvedNextConfig = {\n env: config.env ?? {},\n basePath: config.basePath ?? \"\",\n trailingSlash: config.trailingSlash ?? false,\n output: output === \"export\" || output === \"standalone\" ? output : \"\",\n pageExtensions,\n cacheComponents: config.cacheComponents ?? false,\n redirects,\n rewrites,\n headers,\n images: config.images,\n i18n,\n mdx,\n aliases,\n allowedDevOrigins,\n serverActionsAllowedOrigins,\n optimizePackageImports,\n serverActionsBodySizeLimit,\n expireTime: typeof config.expireTime === \"number\" ? config.expireTime : DEFAULT_EXPIRE_TIME,\n serverExternalPackages,\n cacheHandler,\n cacheMaxMemorySize,\n enablePrerenderSourceMaps: config.enablePrerenderSourceMaps ?? true,\n hashSalt,\n buildId,\n deploymentId,\n };\n\n // Auto-detect next-intl (lowest priority — explicit aliases from\n // webpack/turbopack already in `aliases` take precedence)\n detectNextIntlConfig(root, resolved);\n\n return resolved;\n}\n\nfunction normalizeAliasEntries(\n aliases: Record<string, unknown> | undefined,\n root: string,\n): Record<string, string> {\n if (!aliases) return {};\n\n const normalized: Record<string, string> = {};\n for (const [key, value] of Object.entries(aliases)) {\n if (typeof value !== \"string\") continue;\n normalized[key] = path.isAbsolute(value) ? value : path.resolve(root, value);\n }\n return normalized;\n}\n\nfunction extractTurboAliases(config: NextConfig, root: string): Record<string, string> {\n const experimental = config.experimental as Record<string, unknown> | undefined;\n const experimentalTurbo = experimental?.turbo as Record<string, unknown> | undefined;\n const topLevelTurbopack = config.turbopack as Record<string, unknown> | undefined;\n\n return {\n ...normalizeAliasEntries(\n experimentalTurbo?.resolveAlias as Record<string, unknown> | undefined,\n root,\n ),\n ...normalizeAliasEntries(\n topLevelTurbopack?.resolveAlias as Record<string, unknown> | undefined,\n root,\n ),\n };\n}\n\nasync function probeWebpackConfig(\n config: NextConfig,\n root: string,\n): Promise<{ aliases: Record<string, string>; mdx: MdxOptions | null }> {\n if (typeof config.webpack !== \"function\") {\n return { aliases: {}, mdx: null };\n }\n\n // oxlint-disable-next-line typescript/no-explicit-any\n const mockModuleRules: any[] = [];\n const mockConfig = {\n context: root,\n resolve: { alias: {} as Record<string, unknown> },\n module: { rules: mockModuleRules },\n // oxlint-disable-next-line typescript/no-explicit-any\n plugins: [] as any[],\n };\n const mockOptions = {\n defaultLoaders: { babel: { loader: \"next-babel-loader\" } },\n isServer: false,\n dev: false,\n dir: root,\n };\n\n try {\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n const result = await (config.webpack as Function)(mockConfig, mockOptions);\n const finalConfig = result ?? mockConfig;\n // oxlint-disable-next-line typescript/no-explicit-any\n const rules: any[] = finalConfig.module?.rules ?? mockModuleRules;\n return {\n aliases: normalizeAliasEntries(finalConfig.resolve?.alias, root),\n mdx: extractMdxOptionsFromRules(rules),\n };\n } catch {\n return { aliases: {}, mdx: null };\n }\n}\n\n/**\n * Extract MDX compilation options (remark/rehype/recma plugins) from\n * a Next.js config that uses @next/mdx.\n *\n * @next/mdx wraps the config with a webpack function that injects an MDX\n * loader rule. The remark/rehype plugins are captured in that closure.\n * We probe the webpack function with a mock config to extract them.\n */\nexport async function extractMdxOptions(\n config: NextConfig,\n root: string = process.cwd(),\n): Promise<MdxOptions | null> {\n return (await probeWebpackConfig(config, root)).mdx;\n}\n\n/**\n * Probe file candidates relative to root. Returns the first one that exists,\n * or null if none match.\n */\nfunction probeFiles(root: string, candidates: string[]): string | null {\n for (const candidate of candidates) {\n const abs = path.resolve(root, candidate);\n if (fs.existsSync(abs)) return abs;\n }\n return null;\n}\n\nconst I18N_REQUEST_CANDIDATES = [\n \"i18n/request.ts\",\n \"i18n/request.tsx\",\n \"i18n/request.js\",\n \"i18n/request.jsx\",\n \"src/i18n/request.ts\",\n \"src/i18n/request.tsx\",\n \"src/i18n/request.js\",\n \"src/i18n/request.jsx\",\n];\n\n/**\n * Detect next-intl in the project and auto-register the `next-intl/config`\n * alias if needed.\n *\n * next-intl's `createNextIntlPlugin()` crashes in vinext because it calls\n * `require('next/package.json')` to check the Next.js version. Instead,\n * vinext detects next-intl and registers the alias automatically.\n *\n * Note: `require.resolve('next-intl')` walks up to parent `node_modules`\n * directories via standard Node module resolution. In a monorepo, next-intl\n * installed at the workspace root will trigger detection even if not listed\n * in the project's own package.json. This is acceptable since a workspace-root\n * install implies the user wants it available.\n *\n * Mutates `resolved.aliases` and `resolved.env` in place.\n */\nexport function detectNextIntlConfig(root: string, resolved: ResolvedNextConfig): void {\n // Explicit alias wins — user or plugin already set it\n if (resolved.aliases[\"next-intl/config\"]) return;\n\n // Check if next-intl is installed (use main entry — some packages\n // don't expose ./package.json in their exports map)\n const require = createRequire(path.join(root, \"package.json\"));\n try {\n require.resolve(\"next-intl\");\n } catch {\n return; // next-intl not installed\n }\n\n // Probe for the i18n request config file\n const configPath = probeFiles(root, I18N_REQUEST_CANDIDATES);\n if (!configPath) return;\n\n resolved.aliases[\"next-intl/config\"] = configPath;\n\n if (resolved.trailingSlash) {\n resolved.env._next_intl_trailing_slash = \"true\";\n }\n}\n\n// oxlint-disable-next-line typescript/no-explicit-any\nfunction extractMdxOptionsFromRules(rules: any[]): MdxOptions | null {\n // Search through webpack rules for the MDX loader injected by @next/mdx\n for (const rule of rules) {\n const loaders = extractMdxLoaders(rule);\n if (loaders) return loaders;\n }\n return null;\n}\n\n/**\n * Recursively search a webpack rule (which may have nested `oneOf` arrays)\n * for an MDX loader and extract its remark/rehype/recma plugin options.\n */\n// oxlint-disable-next-line typescript/no-explicit-any\nfunction extractMdxLoaders(rule: any): MdxOptions | null {\n if (!rule) return null;\n\n // Check `oneOf` arrays (Next.js uses these extensively)\n if (Array.isArray(rule.oneOf)) {\n for (const child of rule.oneOf) {\n const result = extractMdxLoaders(child);\n if (result) return result;\n }\n }\n\n // Check `use` array (loader chain)\n const use = Array.isArray(rule.use) ? rule.use : rule.use ? [rule.use] : [];\n for (const loader of use) {\n const loaderPath = typeof loader === \"string\" ? loader : loader?.loader;\n if (typeof loaderPath === \"string\" && isMdxLoader(loaderPath)) {\n const opts = typeof loader === \"object\" ? loader.options : {};\n return extractPluginsFromOptions(opts);\n }\n }\n\n // Check direct `loader` field\n if (typeof rule.loader === \"string\" && isMdxLoader(rule.loader)) {\n return extractPluginsFromOptions(rule.options);\n }\n\n return null;\n}\n\nfunction isMdxLoader(loaderPath: string): boolean {\n return (\n loaderPath.includes(\"mdx\") &&\n (loaderPath.includes(\"@next\") ||\n loaderPath.includes(\"@mdx-js\") ||\n loaderPath.includes(\"mdx-js-loader\") ||\n loaderPath.includes(\"next-mdx\"))\n );\n}\n\n// oxlint-disable-next-line typescript/no-explicit-any\nfunction extractPluginsFromOptions(opts: any): MdxOptions | null {\n if (!opts || typeof opts !== \"object\") return null;\n\n const remarkPlugins = Array.isArray(opts.remarkPlugins) ? opts.remarkPlugins : undefined;\n const rehypePlugins = Array.isArray(opts.rehypePlugins) ? opts.rehypePlugins : undefined;\n const recmaPlugins = Array.isArray(opts.recmaPlugins) ? opts.recmaPlugins : undefined;\n\n // Only return if at least one plugin array is non-empty\n if (\n (remarkPlugins && remarkPlugins.length > 0) ||\n (rehypePlugins && rehypePlugins.length > 0) ||\n (recmaPlugins && recmaPlugins.length > 0)\n ) {\n return {\n ...(remarkPlugins && remarkPlugins.length > 0 ? { remarkPlugins } : {}),\n ...(rehypePlugins && rehypePlugins.length > 0 ? { rehypePlugins } : {}),\n ...(recmaPlugins && recmaPlugins.length > 0 ? { recmaPlugins } : {}),\n };\n }\n\n return null;\n}\n\nexport { PHASE_PRODUCTION_BUILD } from \"vinext/shims/constants\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"next-config.js","names":[],"sources":["../../src/config/next-config.ts"],"sourcesContent":["/**\n * next.config.js / next.config.mjs / next.config.ts parser\n *\n * Loads the Next.js config file (if present) and extracts supported options.\n * Unsupported options are logged as warnings.\n */\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport fs from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { randomUUID } from \"node:crypto\";\nimport commonjs from \"vite-plugin-commonjs\";\nimport { PHASE_DEVELOPMENT_SERVER } from \"vinext/shims/constants\";\nimport { normalizePageExtensions } from \"../routing/file-matcher.js\";\nimport { isExternalUrl } from \"./config-matchers.js\";\nimport { loadTsconfigPathAliasesForRoot } from \"./tsconfig-paths.js\";\n\n/**\n * Parse a body size limit value (string or number) into bytes.\n * Accepts Next.js-style strings like \"1mb\", \"500kb\", \"10mb\", bare number strings like \"1048576\" (bytes),\n * and numeric values. Supports b, kb, mb, gb, tb, pb units.\n * Returns the default 1MB if the value is not provided or invalid.\n * Throws if the parsed value is less than 1.\n */\nexport function parseBodySizeLimit(value: string | number | undefined | null): number {\n if (value === undefined || value === null) return 1 * 1024 * 1024;\n if (typeof value === \"number\") {\n if (value < 1) throw new Error(`Body size limit must be a positive number, got ${value}`);\n return value;\n }\n const trimmed = value.trim();\n const match = trimmed.match(/^(\\d+(?:\\.\\d+)?)\\s*(b|kb|mb|gb|tb|pb)?$/i);\n if (!match) {\n console.warn(\n `[vinext] Invalid bodySizeLimit value: \"${value}\". Expected a number or a string like \"1mb\", \"500kb\". Falling back to 1MB.`,\n );\n return 1 * 1024 * 1024;\n }\n const num = parseFloat(match[1]);\n const unit = (match[2] ?? \"b\").toLowerCase();\n let bytes: number;\n switch (unit) {\n case \"b\":\n bytes = Math.floor(num);\n break;\n case \"kb\":\n bytes = Math.floor(num * 1024);\n break;\n case \"mb\":\n bytes = Math.floor(num * 1024 * 1024);\n break;\n case \"gb\":\n bytes = Math.floor(num * 1024 * 1024 * 1024);\n break;\n case \"tb\":\n bytes = Math.floor(num * 1024 * 1024 * 1024 * 1024);\n break;\n case \"pb\":\n bytes = Math.floor(num * 1024 * 1024 * 1024 * 1024 * 1024);\n break;\n default:\n return 1 * 1024 * 1024;\n }\n if (bytes < 1) throw new Error(`Body size limit must be a positive number, got ${bytes}`);\n return bytes;\n}\n\nexport type HasCondition = {\n type: \"header\" | \"cookie\" | \"query\" | \"host\";\n key: string;\n value?: string;\n};\n\nexport type NextRedirect = {\n source: string;\n destination: string;\n permanent: boolean;\n has?: HasCondition[];\n missing?: HasCondition[];\n};\n\nexport type NextRewrite = {\n source: string;\n destination: string;\n has?: HasCondition[];\n missing?: HasCondition[];\n};\n\nexport type NextHeader = {\n source: string;\n has?: HasCondition[];\n missing?: HasCondition[];\n headers: Array<{ key: string; value: string }>;\n};\n\nexport type NextI18nConfig = {\n /** List of supported locales */\n locales: string[];\n /** The default locale (used when no locale prefix is in the URL) */\n defaultLocale: string;\n /**\n * Whether to auto-detect locale from Accept-Language header.\n * Defaults to true in Next.js.\n */\n localeDetection?: boolean;\n /**\n * Domain-based routing. Each domain maps to a specific locale.\n */\n domains?: Array<{\n domain: string;\n defaultLocale: string;\n locales?: string[];\n http?: boolean;\n }>;\n};\n\n/**\n * MDX compilation options extracted from @next/mdx config.\n * These are passed through to @mdx-js/rollup so that custom\n * remark/rehype/recma plugins configured in next.config work with Vite.\n */\nexport type MdxOptions = {\n remarkPlugins?: unknown[];\n rehypePlugins?: unknown[];\n recmaPlugins?: unknown[];\n};\n\nexport type NextConfig = {\n /** Additional env variables */\n env?: Record<string, string>;\n /** Base URL path prefix */\n basePath?: string;\n /**\n * Prefix applied to every emitted JS/CSS/image/static asset URL.\n * Accepts a path prefix (e.g. `/custom-asset-prefix`) or an absolute\n * URL (e.g. `https://cdn.example.com`). Distinct from `basePath`:\n * `basePath` affects route URLs; `assetPrefix` only affects asset URLs.\n * @see https://nextjs.org/docs/app/api-reference/config/next-config-js/assetPrefix\n */\n assetPrefix?: string;\n /** Whether to add trailing slashes */\n trailingSlash?: boolean;\n /** Internationalization routing config */\n i18n?: NextI18nConfig;\n /** URL redirect rules */\n redirects?: () => Promise<NextRedirect[]> | NextRedirect[];\n /** URL rewrite rules */\n rewrites?: () =>\n | Promise<\n | NextRewrite[]\n | {\n beforeFiles: NextRewrite[];\n afterFiles: NextRewrite[];\n fallback: NextRewrite[];\n }\n >\n | NextRewrite[]\n | {\n beforeFiles: NextRewrite[];\n afterFiles: NextRewrite[];\n fallback: NextRewrite[];\n };\n /** Custom response headers */\n headers?: () => Promise<NextHeader[]> | NextHeader[];\n /** Image optimization config */\n images?: {\n remotePatterns?: Array<{\n protocol?: string;\n hostname: string;\n port?: string;\n pathname?: string;\n search?: string;\n }>;\n domains?: string[];\n unoptimized?: boolean;\n /** Allowed device widths for image optimization. Defaults to Next.js defaults: [640, 750, 828, 1080, 1200, 1920, 2048, 3840] */\n deviceSizes?: number[];\n /** Allowed image sizes for fixed-width images. Defaults to Next.js defaults: [16, 32, 48, 64, 96, 128, 256, 384] */\n imageSizes?: number[];\n /** Allow SVG images through the image optimization endpoint. SVG can contain scripts, so only enable if you trust all image sources. */\n dangerouslyAllowSVG?: boolean;\n /** Allow image optimization for hostnames that resolve to private IP addresses. This is a security risk (SSRF) — only enable for private networks when you understand the risk. */\n dangerouslyAllowLocalIP?: boolean;\n /** Content-Disposition header for image responses. Defaults to \"inline\". */\n contentDispositionType?: \"inline\" | \"attachment\";\n /** Content-Security-Policy header for image responses. Defaults to \"script-src 'none'; frame-src 'none'; sandbox;\" */\n contentSecurityPolicy?: string;\n };\n /** Build output mode: 'export' for full static export, 'standalone' for single server */\n output?: \"export\" | \"standalone\";\n /** File extensions treated as routable pages/routes (Next.js pageExtensions) */\n pageExtensions?: string[];\n /** Extra origins allowed to access the dev server. */\n allowedDevOrigins?: string[];\n /** Maximum age in seconds for stale ISR entries before blocking regeneration. */\n expireTime?: number;\n /**\n * Enable Cache Components (Next.js 16).\n * When true, enables the \"use cache\" directive for pages, components, and functions.\n * Replaces the removed experimental.ppr and experimental.dynamicIO flags.\n */\n cacheComponents?: boolean;\n /**\n * Enables source maps while generating static pages.\n * Helps with errors during the prerender phase in `vinext build`.\n * Defaults to `true`. Set to `false` to disable.\n */\n enablePrerenderSourceMaps?: boolean;\n /** Transpile packages (Vite handles this natively) */\n transpilePackages?: string[];\n /**\n * Packages that should be treated as server-external (not bundled by Vite).\n * Corresponds to Next.js `serverExternalPackages` (or the legacy\n * `experimental.serverComponentsExternalPackages`).\n */\n serverExternalPackages?: string[];\n /** Webpack config (ignored — we use Vite) */\n webpack?: unknown;\n /**\n * Path to a custom cache handler module (e.g., KV, Redis, DynamoDB).\n * Accepts relative paths, absolute paths, or file:// URLs from import.meta.resolve().\n * When \"type\": \"module\" is set in package.json, use import.meta.resolve() instead of\n * require.resolve() to get a valid path.\n */\n cacheHandler?: string;\n /**\n * Maximum memory size (bytes) for the default in-memory cache handler.\n * Set to 0 to disable in-memory caching entirely.\n */\n cacheMaxMemorySize?: number;\n /**\n * Custom build ID generator. If provided, called once at build/dev start.\n * Must return a non-empty string, or null to use the default random ID.\n */\n generateBuildId?: () => string | null | Promise<string | null>;\n /** Identifier for deployment-aware cache keys and version skew protection. */\n deploymentId?: string;\n /** Any other options */\n [key: string]: unknown;\n};\n\nexport type NextConfigFactory = (\n phase: string,\n opts: { defaultConfig: NextConfig },\n) => NextConfig | Promise<NextConfig>;\n\nexport type NextConfigInput = NextConfig | NextConfigFactory;\n\n/**\n * Resolved configuration with all async values awaited.\n */\nexport type ResolvedNextConfig = {\n env: Record<string, string>;\n basePath: string;\n /**\n * Resolved `assetPrefix` from next.config.\n *\n * Empty string when unset. Trailing slashes are trimmed. May be either:\n * - a path prefix beginning with `/` (e.g. `\"/custom-asset-prefix\"`), or\n * - an absolute URL with `http(s)://` origin (e.g. `\"https://cdn.example.com\"`\n * or `\"https://cdn.example.com/sub\"`).\n *\n * Mirrors Next.js semantics — `assetPrefix` controls emitted asset URLs\n * only; route URLs continue to live under `basePath`.\n *\n * @see https://nextjs.org/docs/app/api-reference/config/next-config-js/assetPrefix\n */\n assetPrefix: string;\n trailingSlash: boolean;\n output: \"\" | \"export\" | \"standalone\";\n pageExtensions: string[];\n cacheComponents: boolean;\n redirects: NextRedirect[];\n rewrites: {\n beforeFiles: NextRewrite[];\n afterFiles: NextRewrite[];\n fallback: NextRewrite[];\n };\n headers: NextHeader[];\n images: NextConfig[\"images\"];\n i18n: NextI18nConfig | null;\n /** MDX remark/rehype/recma plugins extracted from @next/mdx config */\n mdx: MdxOptions | null;\n /** Explicit module aliases preserved from wrapped next.config plugins. */\n aliases: Record<string, string>;\n /** Extra allowed origins for dev server access (from allowedDevOrigins). */\n allowedDevOrigins: string[];\n /** Extra allowed origins for server action CSRF validation (from experimental.serverActions.allowedOrigins). */\n serverActionsAllowedOrigins: string[];\n /** Packages whose barrel imports should be optimized (from experimental.optimizePackageImports). */\n optimizePackageImports: string[];\n /** Parsed body size limit for server actions in bytes (from experimental.serverActions.bodySizeLimit). Defaults to 1MB. */\n serverActionsBodySizeLimit: number;\n /** Route-level expire fallback in seconds for ISR entries with numeric revalidate. */\n expireTime: number;\n /**\n * Packages that should be treated as server-external (not bundled by Vite).\n * Sourced from `serverExternalPackages` or the legacy\n * `experimental.serverComponentsExternalPackages` in next.config.\n */\n serverExternalPackages: string[];\n /** Enable sourcemaps for prerender error stack traces. Defaults to true. */\n enablePrerenderSourceMaps: boolean;\n /** Resolved build ID (from generateBuildId, or a random UUID if not provided). */\n buildId: string;\n /** Resolved deployment ID from next.config.js or NEXT_DEPLOYMENT_ID. */\n deploymentId: string | undefined;\n /**\n * Path to a custom cache handler module. file:// URLs are resolved to\n * filesystem paths via fileURLToPath() during config resolution.\n */\n cacheHandler: string | undefined;\n /**\n * Maximum memory size (bytes) for the default in-memory cache handler.\n * Set to 0 to disable in-memory caching entirely.\n */\n cacheMaxMemorySize: number | undefined;\n /**\n * Concatenated hash salt from `experimental.outputHashSalt` config option\n * and `NEXT_HASH_SALT` environment variable. Empty string when neither is set.\n * When non-empty, mix into content-addressed output filenames so hash values\n * change without modifying source — useful for cache-busting after CDN poisoning.\n */\n hashSalt: string;\n /**\n * Raw `sassOptions` object from next.config (or `null` when unset). vinext\n * passes the relevant keys through to Vite's `css.preprocessorOptions.scss`\n * so SCSS variables defined via `additionalData` / `prependData`, partials\n * resolved via `includePaths` / `loadPaths`, and a custom `implementation`\n * all behave the same as in Next.js.\n *\n * Kept loose (`Record<string, unknown> | null`) to match Next.js's typing —\n * the object is forwarded to Sass and may contain any modern Sass option.\n */\n sassOptions: Record<string, unknown> | null;\n};\n\n// Mirrors Next.js's accepted set in packages/next/src/shared/lib/constants.ts\n// (`.js`/`.mjs`/`.ts`/`.mts`) and adds `.cjs` for parity with vinext's own\n// loader, which has historically accepted CJS configs as well. The order is\n// significant: findNextConfigPath returns the first match, so prefer the more\n// modern flavours first.\nconst CONFIG_FILES = [\n \"next.config.ts\",\n \"next.config.mts\",\n \"next.config.mjs\",\n \"next.config.js\",\n \"next.config.cjs\",\n];\nconst DEFAULT_EXPIRE_TIME = 31_536_000;\n\n/**\n * Check whether an error indicates a CJS module was loaded in an ESM context\n * (i.e. the file uses `require()` which is not available in ESM).\n */\nfunction isCjsError(e: unknown): boolean {\n if (!(e instanceof Error)) return false;\n const msg = e.message;\n return (\n msg.includes(\"require is not a function\") ||\n msg.includes(\"require is not defined\") ||\n msg.includes(\"exports is not defined\") ||\n msg.includes(\"module is not defined\") ||\n msg.includes(\"__dirname is not defined\") ||\n msg.includes(\"__filename is not defined\")\n );\n}\n\n// Dev-server phase is the safe default for config loading: it enables all\n// optional config sections (headers, redirects, rewrites) without triggering\n// build-only behaviour. Used in two default parameter values below to avoid\n// repeating PHASE_DEVELOPMENT_SERVER inline.\nconst DEFAULT_PHASE = PHASE_DEVELOPMENT_SERVER;\n\n/**\n * Emit a warning when config loading fails, with a targeted hint for\n * known plugin wrappers that are unnecessary in vinext.\n */\nfunction warnConfigLoadFailure(filename: string, err: Error): void {\n const msg = err.message ?? \"\";\n const stack = err.stack ?? \"\";\n const isNextIntlPlugin =\n msg.includes(\"next-intl\") ||\n stack.includes(\"next-intl/plugin\") ||\n stack.includes(\"next-intl/dist\");\n\n console.log();\n console.error(`[vinext] Failed to load ${filename}: ${msg}`);\n console.log();\n if (isNextIntlPlugin) {\n console.warn(\n \"[vinext] Hint: createNextIntlPlugin() is not needed with vinext. \" +\n \"Remove the next-intl/plugin wrapper from your next.config — \" +\n \"vinext auto-detects next-intl and registers the i18n config alias automatically.\",\n );\n }\n}\n\n/**\n * Resolve a Next-style config value, calling it if it's a function-form config\n * (Next.js supports `module.exports = (phase, opts) => config`).\n */\nasync function resolveConfigValue(\n config: unknown,\n phase: string = DEFAULT_PHASE,\n): Promise<NextConfig> {\n if (typeof config === \"function\") {\n const result = await config(phase, {\n defaultConfig: {},\n });\n return result as NextConfig;\n }\n return config as NextConfig;\n}\n\n/**\n * Named export attached by `cjsGlobalsInjectorPlugin` when the source\n * statically looks like it assigns to `module.exports`. Holds the wrapper\n * `module` object so {@link unwrapConfig} can read back the user's CJS-style\n * export. Pure-ESM configs skip the wrapper entirely and rely on the ESM\n * `default` export instead.\n */\nconst VINEXT_CJS_EXPORTS_KEY = \"__vinext_cjs_exports\";\n\n/**\n * Companion named export pointing at the initial empty `{}` that the wrapper\n * is constructed with. Lets {@link unwrapConfig} distinguish \"user reassigned\n * or mutated module.exports\" from \"module.exports is still the untouched\n * empty wrapper\" — the latter happens when {@link reassignsModuleExports}\n * matches inside a string or comment (a harmless false positive that should\n * still fall through to the ESM `default` export).\n */\nconst VINEXT_CJS_INITIAL_KEY = \"__vinext_cjs_initial_exports\";\n\n/**\n * Unwrap the config value from a loaded module namespace.\n *\n * Prefers `module.exports` (CJS style) when the config file reassigned it,\n * otherwise falls back to `default`/the namespace itself. Mirrors Next.js's\n * behaviour, where the config is loaded through `Module._compile` and CJS\n * assignments override any ESM-style exports.\n *\n * The presence of the `__vinext_cjs_exports` named export is the static\n * signal (set by `cjsGlobalsInjectorPlugin` when `reassignsModuleExports`\n * matched) that this file might use CJS-style exports. We then disambiguate\n * \"user actually touched module.exports\" from \"static heuristic was a false\n * positive\" by comparing identity against the initial empty wrapper: if\n * `module.exports` is still the original `{}`, fall back to ESM `default`.\n */\nasync function unwrapConfig(\n // oxlint-disable-next-line typescript/no-explicit-any\n mod: any,\n phase: string = PHASE_DEVELOPMENT_SERVER,\n): Promise<NextConfig> {\n const cjsModule = mod?.[VINEXT_CJS_EXPORTS_KEY];\n const cjsExports = cjsModule?.exports;\n const cjsInitial = mod?.[VINEXT_CJS_INITIAL_KEY];\n const userTouchedExports =\n cjsExports !== undefined &&\n cjsExports !== null &&\n // Either reassigned outright, or mutated keys on the initial object.\n (cjsExports !== cjsInitial ||\n (typeof cjsExports === \"object\" && Object.keys(cjsExports).length > 0));\n if (userTouchedExports) {\n return await resolveConfigValue(cjsExports, phase);\n }\n return await resolveConfigValue(mod.default ?? mod, phase);\n}\n\n/**\n * Resolve a path through filesystem symlinks, falling back to the original\n * path when the file does not exist (e.g. virtual ids, query-suffixed ids).\n */\nfunction safeRealpath(p: string): string {\n try {\n return fs.realpathSync(p);\n } catch {\n return p;\n }\n}\n\n/**\n * Whole-word substring check for any of the CJS-style globals that the\n * injector plugin would shim. Used to skip the transform entirely for the\n * common case where the config is pure ESM (no `__filename`, `__dirname`,\n * `require`, `module`, or `exports` references).\n *\n * False positives are harmless: a comment, string literal, or unrelated\n * identifier like `node:module` will trigger the transform unnecessarily,\n * but the resulting injection is idempotent and the loaded config is\n * unaffected. False negatives would be a correctness bug, so we err on the\n * side of matching too eagerly.\n *\n * Note: `\\bexports\\b` does not match `export default` (different word\n * boundaries), and `\\brequire\\b` does not match `requireSomething`.\n */\nexport function referencesCjsGlobals(source: string): boolean {\n return /\\b(?:__filename|__dirname|require|module|exports)\\b/.test(source);\n}\n\n/**\n * Static heuristic: returns true when the source appears to assign to\n * `module.exports` — either via `module.exports = …`, `module.exports.foo = …`,\n * or `module.exports[…] = …`. Used to decide whether the injector plugin\n * needs to wire up the wrapper `module` object so {@link unwrapConfig} can\n * read back the user's CJS-style export.\n *\n * Pure-ESM configs skip the wrapper entirely, which means a faster transform\n * (no extra `export const` line) and a simpler unwrap path (no need to\n * disambiguate \"initial empty object\" from \"user reassigned to {}\").\n *\n * Like {@link referencesCjsGlobals}, false positives are harmless: at worst\n * we emit an unused `__vinext_cjs_exports` named export, and `unwrapConfig`\n * still prefers it (it points at an empty object, which then gets treated\n * as the config — equivalent to today's sentinel logic for pure-ESM files\n * that happen to mention `module.exports` only in a string).\n */\nexport function reassignsModuleExports(source: string): boolean {\n // Match `module.exports` followed by `=` (not `==` / `===`), `.identifier =`,\n // or `[...] =`. Whitespace allowed around the dot.\n return /\\bmodule\\s*\\.\\s*exports\\b\\s*(?:=(?!=)|\\.\\s*[A-Za-z_$][\\w$]*\\s*=(?!=)|\\[)/.test(source);\n}\n\n/**\n * Vite plugin that prepends CJS-style globals (`__filename`, `__dirname`,\n * `module`, `exports`, `require`) to the next.config.* source before\n * Vite's module runner evaluates it.\n *\n * Next.js's `next.config.ts` loader (packages/next/src/build/next-config-ts/\n * transpile-config.ts → require-hook.ts) feeds the file through Node's\n * `Module._compile`, which provides these CJS globals even when the source\n * uses ESM syntax. Upstream test fixtures in `test/e2e/app-dir/next-config-ts*`\n * rely on that, e.g. `node-api-cjs/next.config.ts` reads\n * `fs.readFileSync(path.join(__dirname, 'foo.txt'), 'utf8')`. vinext loads\n * configs through Vite's ESM-only module runner, so we inject the same\n * globals as plain `const` declarations.\n *\n * For configs that don't reference any CJS global (the common case — every\n * upstream `next-config-ts` fixture except `node-api-cjs` is pure ESM) we\n * skip the transform entirely; see {@link referencesCjsGlobals}.\n *\n * `module.exports` reassignment is preserved by exposing the injected\n * `module` object as a named export (see {@link VINEXT_CJS_EXPORTS_KEY}) and\n * reading it back in {@link unwrapConfig}.\n */\nfunction cjsGlobalsInjectorPlugin(configPath: string): {\n name: string;\n enforce: \"pre\";\n // oxlint-disable-next-line typescript/no-explicit-any\n transform(this: unknown, code: string, id: string): any;\n} {\n // Resolve symlinks once so we can compare against the (possibly\n // symlink-resolved) id Vite passes to `transform`. On macOS, `/var/folders`\n // is a symlink to `/private/var/folders`, so the temp-dir path in tests\n // would otherwise mismatch.\n const normalizedTarget = safeRealpath(path.resolve(configPath));\n return {\n name: \"vinext:next-config-cjs-globals\",\n enforce: \"pre\",\n transform(code: string, id: string) {\n // Vite may pass an id with a query suffix (?v=...) or as a file URL.\n const idPath = id.startsWith(\"file://\") ? fileURLToPath(id) : id.split(\"?\")[0];\n const resolvedId = safeRealpath(path.resolve(idPath));\n if (resolvedId !== normalizedTarget) return null;\n\n // Fast path: skip the transform when the source contains no bareword\n // reference to any of the shimmed globals. The vast majority of\n // `next.config.ts` files are pure ESM (`export default { ... }`) and\n // pay no cost from this plugin.\n if (!referencesCjsGlobals(code)) return null;\n\n const dirname = path.dirname(normalizedTarget);\n // JSON.stringify produces safe JS string literals for paths.\n const filenameLiteral = JSON.stringify(normalizedTarget);\n const dirnameLiteral = JSON.stringify(dirname);\n const requireBaseLiteral = JSON.stringify(path.join(dirname, \"package.json\"));\n\n // Only wire up the wrapper `module` object — and the corresponding\n // named export read by unwrapConfig — when the source statically looks\n // like it assigns to module.exports. Pure-ESM configs avoid the extra\n // export and the unwrap-by-wrapper code path.\n const needsModuleWrapper = reassignsModuleExports(code);\n const moduleLines = needsModuleWrapper\n ? `const __vinextInitialExports = {};\\n` +\n `const module = { exports: __vinextInitialExports };\\n` +\n `const exports = module.exports;\\n` +\n `export const ${VINEXT_CJS_EXPORTS_KEY} = module;\\n` +\n `export const ${VINEXT_CJS_INITIAL_KEY} = __vinextInitialExports;\\n`\n : \"\";\n\n // Preamble runs after ESM imports are hoisted; the const bindings shadow\n // any global lookups the source would otherwise perform.\n const preamble =\n `import { createRequire as __vinextCreateRequire } from \"node:module\";\\n` +\n `const __filename = ${filenameLiteral};\\n` +\n `const __dirname = ${dirnameLiteral};\\n` +\n `const require = __vinextCreateRequire(${requireBaseLiteral});\\n` +\n moduleLines;\n\n return {\n code: preamble + code,\n map: null,\n };\n },\n };\n}\n\nexport function findNextConfigPath(root: string): string | null {\n for (const filename of CONFIG_FILES) {\n const configPath = path.join(root, filename);\n if (fs.existsSync(configPath)) return configPath;\n }\n return null;\n}\n\nexport async function resolveNextConfigInput(\n config: NextConfigInput,\n phase: string = PHASE_DEVELOPMENT_SERVER,\n): Promise<NextConfig> {\n // Inline vinext({ nextConfig }) already receives the config value itself,\n // not a module namespace object, so do not treat a \"default\" key specially.\n return await resolveConfigValue(config, phase);\n}\n\n/**\n * Load a CJS-flavoured next.config.{js,cjs} via createRequire.\n *\n * For `.cjs` (or `.js` in a non-type-module package) Node's loader picks the\n * right format automatically and `require()` just works. For `.js` in a\n * `\"type\": \"module\"` package, Node infers ESM from package.json and the file\n * fails with `require is not defined`. In that case we copy the source to a\n * sibling temp `.cjs` (where the explicit extension forces CJS regardless of\n * the parent type field) and require *that*. Relative imports inside the\n * config still resolve against the original directory.\n */\nasync function loadConfigViaRequire(\n configPath: string,\n root: string,\n phase: string,\n): Promise<NextConfig> {\n const require = createRequire(path.join(root, \"package.json\"));\n try {\n return await unwrapConfig(require(configPath), phase);\n } catch (e) {\n if (!isCjsError(e) || !configPath.endsWith(\".js\")) throw e;\n return await loadConfigViaCjsTempCopy(configPath, root, phase);\n }\n}\n\nasync function loadConfigViaCjsTempCopy(\n configPath: string,\n root: string,\n phase: string,\n): Promise<NextConfig> {\n const dir = path.dirname(configPath);\n // Hidden + uniquely-named to avoid clashing with user files or being picked\n // up by next.js's own config scanner if a concurrent next dev is running.\n const tmpPath = path.join(dir, `.vinext-next-config.${process.pid}.${Date.now()}.cjs`);\n fs.copyFileSync(configPath, tmpPath);\n try {\n const require = createRequire(path.join(root, \"package.json\"));\n return await unwrapConfig(require(tmpPath), phase);\n } finally {\n try {\n fs.unlinkSync(tmpPath);\n } catch {\n // Best-effort cleanup; a stray tmp file is harmless.\n }\n }\n}\n\n/**\n * Find and load the next.config file from the project root.\n * Returns null if no config file is found.\n *\n * Attempts Vite's module runner first so TS configs and extensionless local\n * imports (e.g. `import \"./env\"`) resolve consistently. If loading fails due\n * to CJS constructs (`require`, `module.exports`), falls back to `createRequire`\n * so common CJS plugin wrappers (nextra, @next/mdx, etc.) still work, including\n * `next.config.js` files written in CJS syntax inside a `\"type\": \"module\"`\n * package (the common shape after `vinext init`).\n */\nexport async function loadNextConfig(\n root: string,\n phase: string = DEFAULT_PHASE,\n): Promise<NextConfig | null> {\n const configPath = findNextConfigPath(root);\n if (!configPath) return null;\n\n const filename = path.basename(configPath);\n\n // Mirror Next.js: read `compilerOptions.paths` from the project's\n // tsconfig.json so aliased imports inside next.config.ts (e.g.\n // `import { foo } from '@/foo'`) resolve at config-load time. Next.js\n // passes these to SWC; we pass them to Vite's resolver as `resolve.alias`.\n // See packages/next/src/build/next-config-ts/transpile-config.ts.\n const tsconfigAliases = loadTsconfigPathAliasesForRoot(root);\n\n // Symlink-resolved config path, used by the `commonjs()` filter below to\n // exclude the config file itself. macOS uses /private/var symlinks, so\n // string-compare without realpath would falsely include the config.\n const normalizedConfigPath = safeRealpath(path.resolve(configPath));\n\n try {\n // Load config via Vite's module runner (TS + extensionless import support)\n const { runnerImport } = await import(\"vite\");\n const { module: mod } = await runnerImport(configPath, {\n root,\n logLevel: \"error\",\n clearScreen: false,\n resolve: {\n alias: tsconfigAliases,\n // Include `.cjs` and `.cts` so `vite-plugin-commonjs` recognises\n // those extensions (the plugin keys off `config.resolve.extensions`,\n // which on Vite defaults to `[.mjs, .js, .mts, .ts, .jsx, .tsx,\n // .json]` — no CJS extensions). This also lets the runner's resolver\n // find `./foo` style imports that resolve to a `.cjs`/`.cts` sibling.\n extensions: [\".mjs\", \".js\", \".cjs\", \".mts\", \".ts\", \".cts\", \".jsx\", \".tsx\", \".json\"],\n },\n // Only inject CJS globals for TypeScript config flavours. Next.js\n // applies its `Module._compile` / SWC pipeline (which exposes the\n // CJS globals) exclusively to `.ts`/`.mts`/`.cts`; legacy `.js`/`.cjs`\n // configs are loaded through Node and already have `require`/`module`,\n // and `.mjs` configs are explicitly ESM-only.\n //\n // Pair that with `vite-plugin-commonjs` (the same plugin used for\n // application code in index.ts) so sibling imports like `.cjs`/`.cts`,\n // or `.js`/`.ts` files that assign to `module.exports`, are converted\n // to ESM before Vite's runner evaluates them. The default `filter`\n // skips `node_modules`; we opt back in so bare-import packages\n // imported by next.config.* (e.g. CJS plugin wrappers) keep working —\n // this mirrors how Next.js's SWC pipeline handles those imports too.\n //\n // The config file itself is excluded from `commonjs()`: when it needs\n // CJS globals it goes through `cjsGlobalsInjectorPlugin`, which sets\n // up a specific `__vinext_cjs_exports` wiring that `unwrapConfig` reads\n // back. Letting both plugins inject `module = { exports: {} }` for the\n // same source produces an `Identifier 'module' has already been\n // declared` syntax error.\n plugins: [\n ...(/\\.[cm]?ts$/.test(configPath) ? [cjsGlobalsInjectorPlugin(configPath)] : []),\n commonjs({\n filter: (id: string) => {\n const idPath = id.startsWith(\"file://\") ? fileURLToPath(id) : id.split(\"?\")[0];\n const resolvedId = safeRealpath(path.resolve(idPath));\n if (resolvedId === normalizedConfigPath) return false;\n // Returning `true` forces the transform to run even for ids\n // inside `node_modules` (default behaviour skips them);\n // `undefined` falls through to the plugin's default for\n // user code.\n return id.includes(\"node_modules\") ? true : undefined;\n },\n }),\n ],\n });\n return await unwrapConfig(mod, phase);\n } catch (e) {\n // If the error indicates a CJS file loaded in ESM context, retry with\n // createRequire which provides a proper CommonJS environment.\n if (isCjsError(e) && (filename.endsWith(\".js\") || filename.endsWith(\".cjs\"))) {\n try {\n return await loadConfigViaRequire(configPath, root, phase);\n } catch (e2) {\n warnConfigLoadFailure(filename, e2 as Error);\n throw e2;\n }\n }\n\n warnConfigLoadFailure(filename, e as Error);\n throw e;\n }\n}\n\n/**\n * Generate a UUID that doesn't contain \"ad\" to avoid false-positive ad-blocker hits.\n * Mirrors Next.js's own nanoid retry loop.\n */\nfunction safeUUID(): string {\n let id = randomUUID();\n while (/ad/i.test(id)) id = randomUUID();\n return id;\n}\n\n/**\n * Call the user's generateBuildId function and validate its return value.\n * Follows Next.js semantics: null return falls back to a random UUID; any\n * other non-string throws. Leading/trailing whitespace is trimmed.\n *\n * @see https://nextjs.org/docs/app/api-reference/config/next-config-js/generateBuildId\n */\nasync function resolveBuildId(\n generate: (() => string | null | Promise<string | null>) | undefined,\n): Promise<string> {\n if (!generate) return safeUUID();\n\n const result = await generate();\n\n if (result === null) return safeUUID();\n\n if (typeof result !== \"string\") {\n throw new Error(\n \"generateBuildId did not return a string. https://nextjs.org/docs/messages/generatebuildid-not-a-string\",\n );\n }\n\n const trimmed = result.trim();\n if (trimmed.length === 0) {\n throw new Error(\n \"generateBuildId returned an empty string. https://nextjs.org/docs/messages/generatebuildid-not-a-string\",\n );\n }\n\n return trimmed;\n}\n\n/**\n * Normalize the `assetPrefix` option from next.config.\n *\n * Accepts both absolute URLs (`https://cdn.example.com[/subpath]`) and\n * path prefixes (`/custom-asset-prefix`). Trailing slashes are trimmed.\n * Empty/whitespace-only strings are treated as unset and return `\"\"`.\n *\n * Path prefixes that omit the leading slash get one added so they always\n * begin with `/` — this matches how Next.js routes match against them.\n *\n * Non-string values are rejected to surface config mistakes early.\n *\n * @see https://nextjs.org/docs/app/api-reference/config/next-config-js/assetPrefix\n */\nexport function normalizeAssetPrefix(value: unknown): string {\n if (value === undefined || value === null || value === \"\") return \"\";\n\n if (typeof value !== \"string\") {\n throw new Error(\n `Invalid \\`assetPrefix\\` configuration: must be a string, got ${typeof value}. ` +\n `Accepts a path prefix (\"/custom-asset-prefix\") or an absolute URL ` +\n `(\"https://cdn.example.com\").`,\n );\n }\n\n // Avoid `replace(/\\/+$/, \"\")` — CodeQL flags it as polynomial backtracking\n // on uncontrolled input. An explicit loop has the same effect with linear time.\n let trimmed = value.trim();\n while (trimmed.endsWith(\"/\")) trimmed = trimmed.slice(0, -1);\n if (trimmed === \"\") return \"\";\n\n // Absolute URL — keep origin verbatim, validate parseability so a typo\n // surfaces at config-load time instead of as a confusing build error.\n if (/^https?:\\/\\//i.test(trimmed)) {\n if (!URL.canParse(trimmed)) {\n throw new Error(`Invalid \\`assetPrefix\\` configuration: \"${value}\" is not a parseable URL.`);\n }\n return trimmed;\n }\n\n // Path prefix — always begin with \"/\", consistent with basePath.\n return trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n}\n\nfunction resolveDeploymentId(configDeploymentId: unknown): string | undefined {\n const deploymentId =\n configDeploymentId !== undefined ? configDeploymentId : process.env.NEXT_DEPLOYMENT_ID;\n if (deploymentId === undefined || deploymentId === \"\") return undefined;\n\n if (typeof deploymentId !== \"string\") {\n throw new Error(\n \"Invalid `deploymentId` configuration: must be a string. https://nextjs.org/docs/messages/deploymentid-not-a-string\",\n );\n }\n\n if (!/^[a-zA-Z0-9_-]+$/.test(deploymentId)) {\n throw new Error(\n \"Invalid `deploymentId` configuration: contains invalid characters. Only alphanumeric characters, hyphens, and underscores are allowed. https://nextjs.org/docs/messages/deploymentid-invalid-characters\",\n );\n }\n\n return deploymentId;\n}\n\n/**\n * Converts a cache handler path to a filesystem path.\n * ESM's import.meta.resolve() returns file:// URLs which break when concatenated\n * with path operations like path.join or path.relative.\n * @param filePath - Absolute path, relative path, or file:// URL (e.g. from import.meta.resolve)\n * @returns A filesystem path suitable for path operations\n */\nfunction resolveCacheHandlerPathToFilesystem(filePath: string): string {\n if (filePath.startsWith(\"file://\")) {\n return fileURLToPath(filePath);\n }\n return filePath;\n}\n\n/**\n * Resolve a NextConfig into a fully-resolved ResolvedNextConfig.\n * Awaits async functions for redirects/rewrites/headers.\n */\nexport async function resolveNextConfig(\n config: NextConfig | null,\n root: string = process.cwd(),\n): Promise<ResolvedNextConfig> {\n if (!config) {\n const buildId = await resolveBuildId(undefined);\n const deploymentId = resolveDeploymentId(undefined);\n const resolved: ResolvedNextConfig = {\n env: {},\n basePath: \"\",\n assetPrefix: \"\",\n trailingSlash: false,\n output: \"\",\n pageExtensions: normalizePageExtensions(),\n cacheComponents: false,\n redirects: [],\n rewrites: { beforeFiles: [], afterFiles: [], fallback: [] },\n headers: [],\n images: undefined,\n i18n: null,\n mdx: null,\n aliases: {},\n allowedDevOrigins: [],\n serverActionsAllowedOrigins: [],\n optimizePackageImports: [],\n serverActionsBodySizeLimit: 1 * 1024 * 1024,\n expireTime: DEFAULT_EXPIRE_TIME,\n serverExternalPackages: [],\n cacheHandler: undefined,\n cacheMaxMemorySize: undefined,\n enablePrerenderSourceMaps: true,\n hashSalt: process.env.NEXT_HASH_SALT ?? \"\",\n buildId,\n deploymentId,\n sassOptions: null,\n };\n detectNextIntlConfig(root, resolved);\n return resolved;\n }\n\n // Resolve redirects\n let redirects: NextRedirect[] = [];\n if (config.redirects) {\n const result = await config.redirects();\n redirects = Array.isArray(result) ? result : [];\n }\n\n // Resolve rewrites\n let rewrites = {\n beforeFiles: [] as NextRewrite[],\n afterFiles: [] as NextRewrite[],\n fallback: [] as NextRewrite[],\n };\n if (config.rewrites) {\n const result = await config.rewrites();\n if (Array.isArray(result)) {\n rewrites.afterFiles = result;\n } else {\n rewrites = {\n beforeFiles: result.beforeFiles ?? [],\n afterFiles: result.afterFiles ?? [],\n fallback: result.fallback ?? [],\n };\n }\n }\n\n {\n const allRewrites = [...rewrites.beforeFiles, ...rewrites.afterFiles, ...rewrites.fallback];\n const externalRewrites = allRewrites.filter((rewrite) => isExternalUrl(rewrite.destination));\n\n if (externalRewrites.length > 0) {\n const noun = externalRewrites.length === 1 ? \"external rewrite\" : \"external rewrites\";\n const listing = externalRewrites\n .map((rewrite) => ` ${rewrite.source} → ${rewrite.destination}`)\n .join(\"\\n\");\n\n console.warn(\n `[vinext] Found ${externalRewrites.length} ${noun} that proxy requests to external origins:\\n` +\n `${listing}\\n` +\n `Request headers, including credential headers (cookie, authorization, proxy-authorization, x-api-key), ` +\n `are forwarded to the external origin to match Next.js behavior. ` +\n `If you do not want to forward credentials, use an API route or route handler where you control exactly which headers are sent.`,\n );\n }\n }\n\n // Resolve headers\n let headers: NextHeader[] = [];\n if (config.headers) {\n headers = await config.headers();\n }\n\n // Probe wrapped webpack config once so alias extraction and MDX extraction\n // observe the same mock environment.\n const webpackProbe = await probeWebpackConfig(config, root);\n const mdx = webpackProbe.mdx;\n const aliases = {\n ...extractTurboAliases(config, root),\n ...webpackProbe.aliases,\n };\n\n const allowedDevOrigins = Array.isArray(config.allowedDevOrigins) ? config.allowedDevOrigins : [];\n\n // Resolve serverActions.allowedOrigins and bodySizeLimit from experimental config\n const experimental = config.experimental as Record<string, unknown> | undefined;\n const serverActionsConfig = experimental?.serverActions as Record<string, unknown> | undefined;\n const serverActionsAllowedOrigins = Array.isArray(serverActionsConfig?.allowedOrigins)\n ? (serverActionsConfig.allowedOrigins as string[])\n : [];\n const serverActionsBodySizeLimit = parseBodySizeLimit(\n serverActionsConfig?.bodySizeLimit as string | number | undefined,\n );\n\n // Resolve hashSalt from experimental.outputHashSalt config + NEXT_HASH_SALT env var.\n // Next.js concatenates them: config value first, then env var.\n const configOutputHashSalt = experimental?.outputHashSalt as string | undefined;\n const hashSalt = (configOutputHashSalt ?? \"\") + (process.env.NEXT_HASH_SALT ?? \"\");\n\n // Resolve optimizePackageImports from experimental config\n const rawOptimize = experimental?.optimizePackageImports;\n const optimizePackageImports = Array.isArray(rawOptimize)\n ? rawOptimize.filter((x): x is string => typeof x === \"string\")\n : [];\n\n // Resolve serverExternalPackages — support the current top-level key and the\n // legacy experimental.serverComponentsExternalPackages name that Next.js still\n // accepts (it moved out of experimental in Next.js 14.2).\n const legacyServerComponentsExternal = experimental?.serverComponentsExternalPackages;\n const serverExternalPackages: string[] = Array.isArray(config.serverExternalPackages)\n ? (config.serverExternalPackages as string[])\n : Array.isArray(legacyServerComponentsExternal)\n ? (legacyServerComponentsExternal as string[])\n : [];\n\n // Warn about unsupported experimental.swcEnvOptions. vinext uses Vite for\n // transforms, not SWC, so automatic polyfill injection is not applicable.\n if (experimental?.swcEnvOptions !== undefined) {\n console.warn(\n '[vinext] next.config option \"experimental.swcEnvOptions\" is not applicable and will be ignored (vinext uses Vite, not SWC). ' +\n \"A Vite-compatible polyfill solution may be explored in the future.\",\n );\n }\n\n // Warn about unsupported webpack usage. We preserve alias injection and\n // extract MDX settings, but all other webpack customization is still ignored.\n if (config.webpack !== undefined) {\n if (mdx || Object.keys(webpackProbe.aliases).length > 0) {\n console.warn(\n '[vinext] next.config option \"webpack\" is only partially supported. ' +\n \"vinext preserves resolve.alias entries and MDX loader settings, but other webpack customization is ignored\",\n );\n } else {\n console.warn(\n '[vinext] next.config option \"webpack\" is not yet supported and will be ignored',\n );\n }\n }\n\n const output = config.output ?? \"\";\n if (output && output !== \"export\" && output !== \"standalone\") {\n console.warn(`[vinext] Unknown output mode \"${output as string}\", ignoring`);\n }\n\n const pageExtensions = normalizePageExtensions(config.pageExtensions);\n\n // Parse i18n config\n let i18n: NextI18nConfig | null = null;\n if (config.i18n) {\n i18n = {\n locales: config.i18n.locales,\n defaultLocale: config.i18n.defaultLocale,\n localeDetection: config.i18n.localeDetection ?? true,\n domains: config.i18n.domains,\n };\n }\n\n const buildId = await resolveBuildId(\n config.generateBuildId as (() => string | null | Promise<string | null>) | undefined,\n );\n const deploymentId = resolveDeploymentId(config.deploymentId);\n\n // Resolve cacheHandler path — handle file:// URLs from import.meta.resolve()\n const cacheHandler: string | undefined =\n typeof config.cacheHandler === \"string\"\n ? resolveCacheHandlerPathToFilesystem(config.cacheHandler)\n : undefined;\n\n // Resolve cacheMaxMemorySize\n const cacheMaxMemorySize: number | undefined =\n typeof config.cacheMaxMemorySize === \"number\" ? config.cacheMaxMemorySize : undefined;\n\n const resolved: ResolvedNextConfig = {\n env: config.env ?? {},\n basePath: config.basePath ?? \"\",\n assetPrefix: normalizeAssetPrefix(config.assetPrefix),\n trailingSlash: config.trailingSlash ?? false,\n output: output === \"export\" || output === \"standalone\" ? output : \"\",\n pageExtensions,\n cacheComponents: config.cacheComponents ?? false,\n redirects,\n rewrites,\n headers,\n images: config.images,\n i18n,\n mdx,\n aliases,\n allowedDevOrigins,\n serverActionsAllowedOrigins,\n optimizePackageImports,\n serverActionsBodySizeLimit,\n expireTime: typeof config.expireTime === \"number\" ? config.expireTime : DEFAULT_EXPIRE_TIME,\n serverExternalPackages,\n cacheHandler,\n cacheMaxMemorySize,\n enablePrerenderSourceMaps: config.enablePrerenderSourceMaps ?? true,\n hashSalt,\n buildId,\n deploymentId,\n sassOptions:\n config.sassOptions && typeof config.sassOptions === \"object\"\n ? (config.sassOptions as Record<string, unknown>)\n : null,\n };\n\n // Auto-detect next-intl (lowest priority — explicit aliases from\n // webpack/turbopack already in `aliases` take precedence)\n detectNextIntlConfig(root, resolved);\n\n // Parity with Next.js: when `basePath` is configured but `assetPrefix` is\n // not, fall back to using `basePath` as the asset prefix. Without this, an\n // app deployed under a basePath would serve its routes correctly but emit\n // its assets from `<basePath>/assets/...` (Vite's default `base + assetsDir`\n // composition) rather than from the Next.js-canonical\n // `<basePath>/_next/static/...`.\n //\n // Mirrors Next.js: packages/next/src/server/config.ts:509-532\n // https://github.com/vercel/next.js/blob/canary/packages/next/src/server/config.ts\n // Conditions copied verbatim:\n // - `basePath !== \"\"` (skips when basePath is unset)\n // - `basePath !== \"/\"` (Next.js rejects this earlier, but we mirror the\n // guard so we don't silently produce `assetPrefix === \"/\"`)\n // - `assetPrefix === \"\"` (user did not explicitly opt out by setting it)\n if (resolved.basePath !== \"\" && resolved.basePath !== \"/\" && resolved.assetPrefix === \"\") {\n resolved.assetPrefix = resolved.basePath;\n }\n\n return resolved;\n}\n\nfunction normalizeAliasEntries(\n aliases: Record<string, unknown> | undefined,\n root: string,\n): Record<string, string> {\n if (!aliases) return {};\n\n const normalized: Record<string, string> = {};\n for (const [key, value] of Object.entries(aliases)) {\n if (typeof value !== \"string\") continue;\n normalized[key] = path.isAbsolute(value) ? value : path.resolve(root, value);\n }\n return normalized;\n}\n\nfunction extractTurboAliases(config: NextConfig, root: string): Record<string, string> {\n const experimental = config.experimental as Record<string, unknown> | undefined;\n const experimentalTurbo = experimental?.turbo as Record<string, unknown> | undefined;\n const topLevelTurbopack = config.turbopack as Record<string, unknown> | undefined;\n\n return {\n ...normalizeAliasEntries(\n experimentalTurbo?.resolveAlias as Record<string, unknown> | undefined,\n root,\n ),\n ...normalizeAliasEntries(\n topLevelTurbopack?.resolveAlias as Record<string, unknown> | undefined,\n root,\n ),\n };\n}\n\nasync function probeWebpackConfig(\n config: NextConfig,\n root: string,\n): Promise<{ aliases: Record<string, string>; mdx: MdxOptions | null }> {\n if (typeof config.webpack !== \"function\") {\n return { aliases: {}, mdx: null };\n }\n\n // oxlint-disable-next-line typescript/no-explicit-any\n const mockModuleRules: any[] = [];\n const mockConfig = {\n context: root,\n resolve: { alias: {} as Record<string, unknown> },\n module: { rules: mockModuleRules },\n // oxlint-disable-next-line typescript/no-explicit-any\n plugins: [] as any[],\n };\n const mockOptions = {\n defaultLoaders: { babel: { loader: \"next-babel-loader\" } },\n isServer: false,\n dev: false,\n dir: root,\n };\n\n try {\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n const result = await (config.webpack as Function)(mockConfig, mockOptions);\n const finalConfig = result ?? mockConfig;\n // oxlint-disable-next-line typescript/no-explicit-any\n const rules: any[] = finalConfig.module?.rules ?? mockModuleRules;\n return {\n aliases: normalizeAliasEntries(finalConfig.resolve?.alias, root),\n mdx: extractMdxOptionsFromRules(rules),\n };\n } catch {\n return { aliases: {}, mdx: null };\n }\n}\n\n/**\n * Extract MDX compilation options (remark/rehype/recma plugins) from\n * a Next.js config that uses @next/mdx.\n *\n * @next/mdx wraps the config with a webpack function that injects an MDX\n * loader rule. The remark/rehype plugins are captured in that closure.\n * We probe the webpack function with a mock config to extract them.\n */\nexport async function extractMdxOptions(\n config: NextConfig,\n root: string = process.cwd(),\n): Promise<MdxOptions | null> {\n return (await probeWebpackConfig(config, root)).mdx;\n}\n\n/**\n * Probe file candidates relative to root. Returns the first one that exists,\n * or null if none match.\n */\nfunction probeFiles(root: string, candidates: string[]): string | null {\n for (const candidate of candidates) {\n const abs = path.resolve(root, candidate);\n if (fs.existsSync(abs)) return abs;\n }\n return null;\n}\n\nconst I18N_REQUEST_CANDIDATES = [\n \"i18n/request.ts\",\n \"i18n/request.tsx\",\n \"i18n/request.js\",\n \"i18n/request.jsx\",\n \"src/i18n/request.ts\",\n \"src/i18n/request.tsx\",\n \"src/i18n/request.js\",\n \"src/i18n/request.jsx\",\n];\n\n/**\n * Detect next-intl in the project and auto-register the `next-intl/config`\n * alias if needed.\n *\n * next-intl's `createNextIntlPlugin()` crashes in vinext because it calls\n * `require('next/package.json')` to check the Next.js version. Instead,\n * vinext detects next-intl and registers the alias automatically.\n *\n * Note: `require.resolve('next-intl')` walks up to parent `node_modules`\n * directories via standard Node module resolution. In a monorepo, next-intl\n * installed at the workspace root will trigger detection even if not listed\n * in the project's own package.json. This is acceptable since a workspace-root\n * install implies the user wants it available.\n *\n * Mutates `resolved.aliases` and `resolved.env` in place.\n */\nexport function detectNextIntlConfig(root: string, resolved: ResolvedNextConfig): void {\n // Explicit alias wins — user or plugin already set it\n if (resolved.aliases[\"next-intl/config\"]) return;\n\n // Check if next-intl is installed (use main entry — some packages\n // don't expose ./package.json in their exports map)\n const require = createRequire(path.join(root, \"package.json\"));\n try {\n require.resolve(\"next-intl\");\n } catch {\n return; // next-intl not installed\n }\n\n // Probe for the i18n request config file\n const configPath = probeFiles(root, I18N_REQUEST_CANDIDATES);\n if (!configPath) return;\n\n resolved.aliases[\"next-intl/config\"] = configPath;\n\n if (resolved.trailingSlash) {\n resolved.env._next_intl_trailing_slash = \"true\";\n }\n}\n\n// oxlint-disable-next-line typescript/no-explicit-any\nfunction extractMdxOptionsFromRules(rules: any[]): MdxOptions | null {\n // Search through webpack rules for the MDX loader injected by @next/mdx\n for (const rule of rules) {\n const loaders = extractMdxLoaders(rule);\n if (loaders) return loaders;\n }\n return null;\n}\n\n/**\n * Recursively search a webpack rule (which may have nested `oneOf` arrays)\n * for an MDX loader and extract its remark/rehype/recma plugin options.\n */\n// oxlint-disable-next-line typescript/no-explicit-any\nfunction extractMdxLoaders(rule: any): MdxOptions | null {\n if (!rule) return null;\n\n // Check `oneOf` arrays (Next.js uses these extensively)\n if (Array.isArray(rule.oneOf)) {\n for (const child of rule.oneOf) {\n const result = extractMdxLoaders(child);\n if (result) return result;\n }\n }\n\n // Check `use` array (loader chain)\n const use = Array.isArray(rule.use) ? rule.use : rule.use ? [rule.use] : [];\n for (const loader of use) {\n const loaderPath = typeof loader === \"string\" ? loader : loader?.loader;\n if (typeof loaderPath === \"string\" && isMdxLoader(loaderPath)) {\n const opts = typeof loader === \"object\" ? loader.options : {};\n return extractPluginsFromOptions(opts);\n }\n }\n\n // Check direct `loader` field\n if (typeof rule.loader === \"string\" && isMdxLoader(rule.loader)) {\n return extractPluginsFromOptions(rule.options);\n }\n\n return null;\n}\n\nfunction isMdxLoader(loaderPath: string): boolean {\n return (\n loaderPath.includes(\"mdx\") &&\n (loaderPath.includes(\"@next\") ||\n loaderPath.includes(\"@mdx-js\") ||\n loaderPath.includes(\"mdx-js-loader\") ||\n loaderPath.includes(\"next-mdx\"))\n );\n}\n\n// oxlint-disable-next-line typescript/no-explicit-any\nfunction extractPluginsFromOptions(opts: any): MdxOptions | null {\n if (!opts || typeof opts !== \"object\") return null;\n\n const remarkPlugins = Array.isArray(opts.remarkPlugins) ? opts.remarkPlugins : undefined;\n const rehypePlugins = Array.isArray(opts.rehypePlugins) ? opts.rehypePlugins : undefined;\n const recmaPlugins = Array.isArray(opts.recmaPlugins) ? opts.recmaPlugins : undefined;\n\n // Only return if at least one plugin array is non-empty\n if (\n (remarkPlugins && remarkPlugins.length > 0) ||\n (rehypePlugins && rehypePlugins.length > 0) ||\n (recmaPlugins && recmaPlugins.length > 0)\n ) {\n return {\n ...(remarkPlugins && remarkPlugins.length > 0 ? { remarkPlugins } : {}),\n ...(rehypePlugins && rehypePlugins.length > 0 ? { rehypePlugins } : {}),\n ...(recmaPlugins && recmaPlugins.length > 0 ? { recmaPlugins } : {}),\n };\n }\n\n return null;\n}\n\nexport { PHASE_PRODUCTION_BUILD } from \"vinext/shims/constants\";\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/config/tsconfig-paths.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Read the project's tsconfig.json (or jsconfig.json) and return its
|
|
4
|
+
* `compilerOptions.paths` as absolute-path Vite `resolve.alias` entries.
|
|
5
|
+
*
|
|
6
|
+
* Returns an empty object if no config is found or no paths are configured.
|
|
7
|
+
* Errors during parsing are swallowed — this is a best-effort helper that
|
|
8
|
+
* must not break config loading.
|
|
9
|
+
*/
|
|
10
|
+
declare function loadTsconfigPathAliasesForRoot(projectRoot: string): Record<string, string>;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { loadTsconfigPathAliasesForRoot };
|
|
13
|
+
//# sourceMappingURL=tsconfig-paths.d.ts.map
|