vinext 0.1.0 → 0.1.2

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.
Files changed (205) hide show
  1. package/README.md +2 -5
  2. package/dist/build/assets-ignore.d.ts +32 -0
  3. package/dist/build/assets-ignore.js +48 -0
  4. package/dist/build/client-build-config.d.ts +33 -1
  5. package/dist/build/client-build-config.js +66 -1
  6. package/dist/check.js +4 -3
  7. package/dist/cli.js +2 -0
  8. package/dist/client/navigation-runtime.d.ts +11 -2
  9. package/dist/client/navigation-runtime.js +1 -1
  10. package/dist/client/vinext-next-data.d.ts +2 -1
  11. package/dist/client/window-next.d.ts +6 -4
  12. package/dist/config/config-matchers.d.ts +31 -5
  13. package/dist/config/config-matchers.js +50 -3
  14. package/dist/config/next-config.d.ts +29 -3
  15. package/dist/config/next-config.js +32 -2
  16. package/dist/deploy.js +47 -304
  17. package/dist/entries/app-rsc-entry.d.ts +8 -2
  18. package/dist/entries/app-rsc-entry.js +61 -5
  19. package/dist/entries/app-rsc-manifest.js +20 -2
  20. package/dist/entries/pages-client-entry.js +1 -1
  21. package/dist/entries/pages-server-entry.js +16 -7
  22. package/dist/index.d.ts +0 -2
  23. package/dist/index.js +233 -280
  24. package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
  25. package/dist/plugins/dynamic-preload-metadata.js +415 -0
  26. package/dist/plugins/og-assets.js +2 -2
  27. package/dist/plugins/optimize-imports.d.ts +8 -4
  28. package/dist/plugins/optimize-imports.js +16 -12
  29. package/dist/plugins/postcss.js +18 -14
  30. package/dist/plugins/require-context.d.ts +6 -0
  31. package/dist/plugins/require-context.js +184 -0
  32. package/dist/plugins/sass.d.ts +53 -24
  33. package/dist/plugins/sass.js +249 -1
  34. package/dist/plugins/wasm-module-import.d.ts +15 -0
  35. package/dist/plugins/wasm-module-import.js +50 -0
  36. package/dist/routing/app-route-graph.d.ts +35 -2
  37. package/dist/routing/app-route-graph.js +179 -8
  38. package/dist/routing/file-matcher.js +1 -1
  39. package/dist/routing/route-pattern.d.ts +2 -1
  40. package/dist/routing/route-pattern.js +16 -1
  41. package/dist/server/api-handler.js +4 -0
  42. package/dist/server/app-browser-entry.js +155 -215
  43. package/dist/server/app-browser-error.d.ts +4 -1
  44. package/dist/server/app-browser-error.js +7 -1
  45. package/dist/server/app-browser-history-controller.d.ts +104 -0
  46. package/dist/server/app-browser-history-controller.js +210 -0
  47. package/dist/server/app-browser-interception-context.d.ts +2 -1
  48. package/dist/server/app-browser-interception-context.js +15 -2
  49. package/dist/server/app-browser-navigation-controller.d.ts +13 -2
  50. package/dist/server/app-browser-navigation-controller.js +83 -4
  51. package/dist/server/app-browser-popstate.d.ts +12 -3
  52. package/dist/server/app-browser-popstate.js +19 -4
  53. package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
  54. package/dist/server/app-browser-rsc-redirect.js +30 -8
  55. package/dist/server/app-browser-state.d.ts +3 -0
  56. package/dist/server/app-browser-state.js +10 -10
  57. package/dist/server/app-browser-visible-commit.js +10 -8
  58. package/dist/server/app-fallback-renderer.d.ts +2 -1
  59. package/dist/server/app-fallback-renderer.js +3 -1
  60. package/dist/server/app-history-state.d.ts +45 -1
  61. package/dist/server/app-history-state.js +109 -1
  62. package/dist/server/app-middleware.js +1 -0
  63. package/dist/server/app-optimistic-routing.js +22 -1
  64. package/dist/server/app-page-boundary-render.d.ts +2 -1
  65. package/dist/server/app-page-boundary-render.js +45 -21
  66. package/dist/server/app-page-cache.js +9 -7
  67. package/dist/server/app-page-dispatch.d.ts +14 -0
  68. package/dist/server/app-page-dispatch.js +21 -6
  69. package/dist/server/app-page-element-builder.d.ts +23 -2
  70. package/dist/server/app-page-element-builder.js +58 -17
  71. package/dist/server/app-page-execution.d.ts +1 -1
  72. package/dist/server/app-page-execution.js +32 -17
  73. package/dist/server/app-page-render.d.ts +7 -1
  74. package/dist/server/app-page-render.js +11 -16
  75. package/dist/server/app-page-request.d.ts +9 -6
  76. package/dist/server/app-page-request.js +14 -10
  77. package/dist/server/app-page-response.d.ts +2 -2
  78. package/dist/server/app-page-response.js +2 -2
  79. package/dist/server/app-page-route-wiring.d.ts +3 -1
  80. package/dist/server/app-page-route-wiring.js +10 -8
  81. package/dist/server/app-page-stream.d.ts +37 -7
  82. package/dist/server/app-page-stream.js +36 -6
  83. package/dist/server/app-pages-bridge.d.ts +16 -0
  84. package/dist/server/app-pages-bridge.js +23 -3
  85. package/dist/server/app-route-handler-cache.d.ts +1 -0
  86. package/dist/server/app-route-handler-cache.js +1 -0
  87. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  88. package/dist/server/app-route-handler-dispatch.js +2 -0
  89. package/dist/server/app-route-handler-execution.d.ts +1 -0
  90. package/dist/server/app-route-handler-execution.js +1 -0
  91. package/dist/server/app-route-handler-response.js +11 -10
  92. package/dist/server/app-route-handler-runtime.d.ts +1 -0
  93. package/dist/server/app-route-handler-runtime.js +15 -3
  94. package/dist/server/app-rsc-handler.d.ts +1 -0
  95. package/dist/server/app-rsc-handler.js +5 -4
  96. package/dist/server/app-rsc-response-finalizer.js +1 -1
  97. package/dist/server/app-rsc-route-matching.d.ts +20 -1
  98. package/dist/server/app-rsc-route-matching.js +29 -4
  99. package/dist/server/app-server-action-execution.d.ts +22 -1
  100. package/dist/server/app-server-action-execution.js +73 -12
  101. package/dist/server/app-ssr-entry.d.ts +6 -0
  102. package/dist/server/app-ssr-entry.js +19 -3
  103. package/dist/server/app-ssr-stream.js +9 -1
  104. package/dist/server/dev-lockfile.js +2 -1
  105. package/dist/server/dev-server.d.ts +1 -1
  106. package/dist/server/dev-server.js +97 -43
  107. package/dist/server/headers.d.ts +8 -1
  108. package/dist/server/headers.js +8 -1
  109. package/dist/server/instrumentation-runtime.d.ts +6 -0
  110. package/dist/server/instrumentation-runtime.js +8 -0
  111. package/dist/server/isr-cache.d.ts +37 -1
  112. package/dist/server/isr-cache.js +85 -1
  113. package/dist/server/isr-decision.d.ts +79 -0
  114. package/dist/server/isr-decision.js +70 -0
  115. package/dist/server/metadata-route-response.js +5 -3
  116. package/dist/server/middleware-runtime.d.ts +13 -0
  117. package/dist/server/middleware-runtime.js +11 -7
  118. package/dist/server/middleware.js +1 -0
  119. package/dist/server/navigation-planner.d.ts +62 -1
  120. package/dist/server/navigation-planner.js +193 -3
  121. package/dist/server/navigation-trace.d.ts +12 -2
  122. package/dist/server/navigation-trace.js +11 -1
  123. package/dist/server/normalize-path.d.ts +0 -8
  124. package/dist/server/normalize-path.js +3 -1
  125. package/dist/server/otel-tracer-extension.d.ts +45 -0
  126. package/dist/server/otel-tracer-extension.js +89 -0
  127. package/dist/server/pages-api-route.d.ts +14 -3
  128. package/dist/server/pages-api-route.js +6 -1
  129. package/dist/server/pages-asset-tags.d.ts +15 -4
  130. package/dist/server/pages-asset-tags.js +18 -12
  131. package/dist/server/pages-data-route.js +5 -1
  132. package/dist/server/pages-node-compat.d.ts +5 -11
  133. package/dist/server/pages-node-compat.js +175 -118
  134. package/dist/server/pages-page-data.d.ts +38 -7
  135. package/dist/server/pages-page-data.js +64 -18
  136. package/dist/server/pages-page-handler.d.ts +10 -2
  137. package/dist/server/pages-page-handler.js +49 -20
  138. package/dist/server/pages-page-response.d.ts +55 -2
  139. package/dist/server/pages-page-response.js +74 -6
  140. package/dist/server/pages-readiness.d.ts +36 -0
  141. package/dist/server/pages-readiness.js +21 -0
  142. package/dist/server/pages-request-pipeline.d.ts +113 -0
  143. package/dist/server/pages-request-pipeline.js +230 -0
  144. package/dist/server/pages-revalidate.d.ts +15 -0
  145. package/dist/server/pages-revalidate.js +19 -0
  146. package/dist/server/prod-server.d.ts +45 -3
  147. package/dist/server/prod-server.js +182 -234
  148. package/dist/server/socket-error-backstop.d.ts +19 -1
  149. package/dist/server/socket-error-backstop.js +77 -4
  150. package/dist/shims/app-router-scroll.js +22 -4
  151. package/dist/shims/cache-runtime.js +39 -2
  152. package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
  153. package/dist/shims/dynamic-preload-chunks.js +77 -0
  154. package/dist/shims/dynamic.d.ts +4 -0
  155. package/dist/shims/dynamic.js +4 -2
  156. package/dist/shims/error-boundary.d.ts +17 -7
  157. package/dist/shims/error-boundary.js +8 -1
  158. package/dist/shims/error.js +37 -11
  159. package/dist/shims/fetch-cache.d.ts +22 -1
  160. package/dist/shims/fetch-cache.js +28 -1
  161. package/dist/shims/hash-scroll.d.ts +1 -0
  162. package/dist/shims/hash-scroll.js +3 -1
  163. package/dist/shims/head.js +6 -1
  164. package/dist/shims/headers.d.ts +16 -2
  165. package/dist/shims/headers.js +37 -1
  166. package/dist/shims/image-config.js +7 -1
  167. package/dist/shims/internal/app-route-detection.d.ts +6 -3
  168. package/dist/shims/internal/app-route-detection.js +10 -6
  169. package/dist/shims/internal/app-router-context.d.ts +5 -0
  170. package/dist/shims/internal/link-status-registry.d.ts +43 -0
  171. package/dist/shims/internal/link-status-registry.js +42 -0
  172. package/dist/shims/internal/route-pattern-for-warning.d.ts +27 -0
  173. package/dist/shims/internal/route-pattern-for-warning.js +40 -0
  174. package/dist/shims/internal/utils.d.ts +1 -0
  175. package/dist/shims/link.js +20 -6
  176. package/dist/shims/metadata.d.ts +6 -2
  177. package/dist/shims/metadata.js +32 -14
  178. package/dist/shims/navigation.d.ts +9 -18
  179. package/dist/shims/navigation.js +96 -23
  180. package/dist/shims/router-state.d.ts +1 -0
  181. package/dist/shims/router-state.js +2 -0
  182. package/dist/shims/router.d.ts +6 -3
  183. package/dist/shims/router.js +156 -22
  184. package/dist/shims/script-nonce-context.d.ts +1 -1
  185. package/dist/shims/script-nonce-context.js +11 -3
  186. package/dist/shims/server.d.ts +17 -1
  187. package/dist/shims/server.js +31 -6
  188. package/dist/shims/slot.js +1 -1
  189. package/dist/shims/unified-request-context.js +1 -0
  190. package/dist/typegen.js +1 -0
  191. package/dist/utils/client-build-manifest.d.ts +8 -1
  192. package/dist/utils/client-build-manifest.js +41 -6
  193. package/dist/utils/client-entry-manifest.d.ts +11 -0
  194. package/dist/utils/client-entry-manifest.js +29 -0
  195. package/dist/utils/client-runtime-metadata.d.ts +45 -0
  196. package/dist/utils/client-runtime-metadata.js +63 -0
  197. package/dist/utils/hash.d.ts +17 -1
  198. package/dist/utils/hash.js +36 -1
  199. package/dist/utils/lazy-chunks.d.ts +27 -1
  200. package/dist/utils/lazy-chunks.js +65 -1
  201. package/dist/utils/manifest-paths.d.ts +20 -2
  202. package/dist/utils/manifest-paths.js +38 -3
  203. package/dist/utils/path.d.ts +2 -1
  204. package/dist/utils/path.js +5 -1
  205. package/package.json +6 -2
package/dist/index.js CHANGED
@@ -1,13 +1,11 @@
1
1
  import { detectPackageManager } from "./utils/project.js";
2
+ import { normalizePathSeparators, stripViteModuleQuery } from "./utils/path.js";
2
3
  import { normalizePathnameForRouteMatchStrict } from "./routing/utils.js";
3
4
  import { buildViteResolveExtensions, createValidFileMatcher, findFileWithExts } from "./routing/file-matcher.js";
4
- import { hasBasePath } from "./utils/base-path.js";
5
5
  import { apiRouter, invalidateRouteCache, matchRoute, pagesRouter } from "./routing/pages-router.js";
6
- import { normalizePathSeparators } from "./utils/path.js";
7
- import { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, VINEXT_MW_CTX_HEADER, VINEXT_TIMING_HEADER } from "./server/headers.js";
8
- import { buildRequestHeadersFromMiddlewareResponse } from "./server/middleware-request-headers.js";
6
+ import { INTERNAL_HEADERS, NEXTJS_DEPLOYMENT_ID_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MW_CTX_HEADER, VINEXT_TIMING_HEADER } from "./server/headers.js";
9
7
  import { normalizePath as normalizePath$1 } from "./server/normalize-path.js";
10
- import { isExternalUrl, matchHeaders, matchRedirect, matchRewrite, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "./config/config-matchers.js";
8
+ import { proxyExternalRequest } from "./config/config-matchers.js";
11
9
  import { filterInternalHeaders, isOpenRedirectShaped, normalizeTrailingSlash } from "./server/request-pipeline.js";
12
10
  import { findMiddlewareFile, runMiddleware } from "./server/middleware.js";
13
11
  import { generateServerEntry } from "./entries/pages-server-entry.js";
@@ -15,9 +13,7 @@ import { generateClientEntry } from "./entries/pages-client-entry.js";
15
13
  import { appRouteGraph, appRouter, invalidateAppRouteCache } from "./routing/app-router.js";
16
14
  import { findInstrumentationClientFile, findInstrumentationFile, runInstrumentation } from "./server/instrumentation.js";
17
15
  import { isUnknownRecord } from "./utils/record.js";
18
- import { mergeRewriteQuery } from "./utils/query.js";
19
16
  import { logRequest, now } from "./server/request-log.js";
20
- import { normalizeDefaultLocalePathname, stripI18nLocaleForApiRoute } from "./server/pages-i18n.js";
21
17
  import { createSSRHandler } from "./server/dev-server.js";
22
18
  import { handleApiRoute } from "./server/api-handler.js";
23
19
  import { isImageOptimizationPath } from "./server/image-optimization.js";
@@ -39,10 +35,11 @@ import { getViteMajorVersion } from "./utils/vite-version.js";
39
35
  import { createRscCompatibilityId, findNextConfigPath, loadNextConfig, resolveNextConfig, resolveNextConfigInput } from "./config/next-config.js";
40
36
  import { isNextDataPathname, parseNextDataPathname } from "./server/pages-data-route.js";
41
37
  import { precompressAssets } from "./build/precompress.js";
38
+ import { ensureAssetsIgnore } from "./build/assets-ignore.js";
42
39
  import { emitNextClientRuntimeManifests } from "./build/next-client-runtime-manifests.js";
43
40
  import { collectInlineCssManifest, injectInlineCssManifestGlobal } from "./build/inline-css.js";
44
41
  import { installDevStackSourcemapMiddleware } from "./server/dev-stack-sourcemap.js";
45
- import { manifestFilesWithBase } from "./utils/manifest-paths.js";
42
+ import { runPagesRequest } from "./server/pages-request-pipeline.js";
46
43
  import { asyncHooksStubPlugin } from "./plugins/async-hooks-stub.js";
47
44
  import { clientReferenceDedupPlugin } from "./plugins/client-reference-dedup.js";
48
45
  import { dataUrlCssPlugin } from "./plugins/css-data-url.js";
@@ -51,21 +48,24 @@ import { createInstrumentationClientTransformPlugin } from "./plugins/instrument
51
48
  import { INSTRUMENTATION_CLIENT_EMPTY_MODULE, generateInstrumentationClientInjectModule } from "./client/instrumentation-client-inject.js";
52
49
  import { createMiddlewareServerOnlyPlugin } from "./plugins/middleware-server-only.js";
53
50
  import { createOptimizeImportsPlugin } from "./plugins/optimize-imports.js";
51
+ import { augmentSsrManifestFromBundle, relativeWithinRoot, tryRealpathSync } from "./build/ssr-manifest.js";
52
+ import { createDynamicPreloadMetadataPlugin } from "./plugins/dynamic-preload-metadata.js";
54
53
  import { createOgAssetsPlugin, createOgInlineFetchAssetsPlugin } from "./plugins/og-assets.js";
55
54
  import { generateRouteTypes } from "./typegen.js";
56
55
  import { SSR_EXTERNAL_REACT_ENTRIES, VINEXT_OPTIMIZE_DEPS_EXCLUDE, mergeOptimizeDepsExclude } from "./plugins/rsc-client-shim-excludes.js";
57
56
  import { createServerExternalsManifestPlugin } from "./plugins/server-externals-manifest.js";
58
- import { computeLazyChunks } from "./utils/lazy-chunks.js";
59
- import { findClientEntryFile, readClientBuildManifest } from "./utils/client-build-manifest.js";
57
+ import { VINEXT_CLIENT_ENTRY_MANIFEST } from "./utils/client-entry-manifest.js";
58
+ import { buildRuntimeGlobalsScript, computeClientRuntimeMetadata } from "./utils/client-runtime-metadata.js";
60
59
  import { formatMissingCloudflarePluginError, hasWranglerConfig } from "./deploy.js";
61
60
  import { resolvePostcssStringPlugins } from "./plugins/postcss.js";
62
- import { buildSassPreprocessorOptions } from "./plugins/sass.js";
63
- import { createClientAssetFileNames, createClientCodeSplittingConfig, createClientManualChunks, createClientOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfigForVite, withBuildBundlerOptions } from "./build/client-build-config.js";
61
+ import { buildSassPreprocessorOptions, createSassAwareFileSystemLoader, createSassTildeImporter } from "./plugins/sass.js";
62
+ import { createClientAssetFileNames, createClientCodeSplittingConfig, createClientFileNameConfig, createClientManualChunks, createClientOutputConfig, createRscFrameworkChunkOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfigForVite, withBuildBundlerOptions } from "./build/client-build-config.js";
64
63
  import { markCssUrlAssetReferences, restoreDedupedCssAssetReferences } from "./build/css-url-assets.js";
65
- import { augmentSsrManifestFromBundle, relativeWithinRoot, tryRealpathSync } from "./build/ssr-manifest.js";
66
64
  import { stripServerExports } from "./plugins/strip-server-exports.js";
67
65
  import { removeConsoleCalls } from "./plugins/remove-console.js";
68
66
  import { createImportMetaUrlPlugin } from "./plugins/import-meta-url.js";
67
+ import { createRequireContextPlugin } from "./plugins/require-context.js";
68
+ import { createWasmModuleImportPlugin } from "./plugins/wasm-module-import.js";
69
69
  import { hasMdxFiles } from "./utils/mdx-scan.js";
70
70
  import { scanPublicFileRoutes } from "./utils/public-routes.js";
71
71
  import { staticExportApp, staticExportPages } from "./build/static-export.js";
@@ -80,10 +80,6 @@ import MagicString from "magic-string";
80
80
  import tsconfigPaths from "vite-tsconfig-paths";
81
81
  //#region src/index.ts
82
82
  installSocketErrorBackstop();
83
- function stripViteModuleQuery(id) {
84
- const queryIndex = id.search(/[?#]/);
85
- return queryIndex === -1 ? id : id.slice(0, queryIndex);
86
- }
87
83
  function isInsideDirectory(dir, filePath) {
88
84
  const relativePath = path.relative(dir, filePath);
89
85
  return relativePath !== "" && !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
@@ -148,10 +144,10 @@ function resolveShimModulePath(shimsDir, moduleName) {
148
144
  ".tsx",
149
145
  ".js"
150
146
  ]) {
151
- const candidate = path.join(shimsDir, `${moduleName}${ext}`);
147
+ const candidate = path.posix.join(shimsDir, `${moduleName}${ext}`);
152
148
  if (fs.existsSync(candidate)) return candidate;
153
149
  }
154
- return path.join(shimsDir, `${moduleName}.js`);
150
+ return path.posix.join(shimsDir, `${moduleName}.js`);
155
151
  }
156
152
  function isVercelOgImport(id) {
157
153
  return id === "@vercel/og" || id === "@vercel/og.js";
@@ -300,12 +296,23 @@ const RESOLVED_INSTRUMENTATION_CLIENT = `\0${VIRTUAL_INSTRUMENTATION_CLIENT}.mjs
300
296
  /** Image file extensions handled by the vinext:image-imports plugin.
301
297
  * Shared between the Rolldown hook filter and the transform handler regex. */
302
298
  const IMAGE_EXTS = "png|jpe?g|gif|webp|avif|svg|ico|bmp|tiff?";
303
- /** Absolute path to vinext's shims directory, used by clientManualChunks. */
304
- const _shimsDir = path.resolve(__dirname, "shims") + "/";
299
+ /**
300
+ * Absolute path to vinext's shims directory, with a trailing slash. Normalized
301
+ * to forward slashes because it is prefix-matched against Vite module ids (which
302
+ * Vite always normalizes to forward slashes) in the font plugins and
303
+ * clientManualChunks — a raw path.resolve value has backslashes on Windows and
304
+ * the `id.startsWith(_shimsDir)` checks would never match.
305
+ */
306
+ const _shimsDir = normalizePathSeparators(path.resolve(__dirname, "shims")) + "/";
305
307
  const _fontGoogleShimPath = resolveShimModulePath(_shimsDir, "font-google");
306
308
  function isValidExportIdentifier(name) {
307
309
  return /^[$A-Z_a-z][$\w]*$/.test(name);
308
310
  }
311
+ function isVirtualEntryFacade(id, virtualId) {
312
+ if (!id) return false;
313
+ const cleanId = id.startsWith("\0") ? id.slice(1) : id;
314
+ return cleanId === virtualId || cleanId.endsWith("/" + virtualId) || cleanId.endsWith("\\" + virtualId);
315
+ }
309
316
  /**
310
317
  * Returns true when `code` starts with a React `"use client"` or `"use server"`
311
318
  * directive (after stripping leading comments, hashbang, and whitespace).
@@ -381,6 +388,7 @@ const clientManualChunks = createClientManualChunks(_shimsDir);
381
388
  const clientCodeSplittingConfig = createClientCodeSplittingConfig(clientManualChunks);
382
389
  function getClientOutputConfigForVite(viteMajorVersion, assetsDir) {
383
390
  return viteMajorVersion >= 8 ? {
391
+ ...createClientFileNameConfig(assetsDir),
384
392
  assetFileNames: createClientAssetFileNames(assetsDir),
385
393
  codeSplitting: clientCodeSplittingConfig
386
394
  } : createClientOutputConfig(clientManualChunks, assetsDir);
@@ -404,6 +412,7 @@ function vinext(options = {}) {
404
412
  let hasNitroPlugin = false;
405
413
  let rscCompatibilityId;
406
414
  const draftModeSecret = randomUUID();
415
+ const sassComposesLoader = createSassAwareFileSystemLoader();
407
416
  let rscClassificationManifest = null;
408
417
  const shimsDir = path.resolve(__dirname, "shims");
409
418
  const canonicalize = (p) => tryRealpathSync(p) ?? p;
@@ -542,7 +551,7 @@ function vinext(options = {}) {
542
551
  name: "vinext:config",
543
552
  enforce: "pre",
544
553
  async config(config, env) {
545
- root = config.root ?? process.cwd();
554
+ root = normalizePathSeparators(config.root ?? process.cwd());
546
555
  const userResolve = config.resolve;
547
556
  const shouldEnableNativeTsconfigPaths = viteMajorVersion >= 8 && userResolve?.tsconfigPaths === void 0;
548
557
  const tsconfigPathAliases = resolveTsconfigAliases(root);
@@ -555,18 +564,18 @@ function vinext(options = {}) {
555
564
  else resolvedNodeEnv = "development";
556
565
  if (process.env.NODE_ENV !== resolvedNodeEnv) process.env.NODE_ENV = resolvedNodeEnv;
557
566
  let baseDir;
558
- if (options.appDir) baseDir = path.isAbsolute(options.appDir) ? options.appDir : path.resolve(root, options.appDir);
567
+ if (options.appDir) baseDir = normalizePathSeparators(path.isAbsolute(options.appDir) ? options.appDir : path.resolve(root, options.appDir));
559
568
  else {
560
- const hasRootApp = fs.existsSync(path.join(root, "app"));
561
- const hasRootPages = fs.existsSync(path.join(root, "pages"));
562
- const hasSrcApp = fs.existsSync(path.join(root, "src", "app"));
563
- const hasSrcPages = fs.existsSync(path.join(root, "src", "pages"));
569
+ const hasRootApp = fs.existsSync(path.posix.join(root, "app"));
570
+ const hasRootPages = fs.existsSync(path.posix.join(root, "pages"));
571
+ const hasSrcApp = fs.existsSync(path.posix.join(root, "src", "app"));
572
+ const hasSrcPages = fs.existsSync(path.posix.join(root, "src", "pages"));
564
573
  if (hasRootApp || hasRootPages) baseDir = root;
565
- else if (hasSrcApp || hasSrcPages) baseDir = path.join(root, "src");
574
+ else if (hasSrcApp || hasSrcPages) baseDir = path.posix.join(root, "src");
566
575
  else baseDir = root;
567
576
  }
568
- pagesDir = path.join(baseDir, "pages");
569
- appDir = path.join(baseDir, "app");
577
+ pagesDir = path.posix.join(baseDir, "pages");
578
+ appDir = path.posix.join(baseDir, "app");
570
579
  hasPagesDir = fs.existsSync(pagesDir);
571
580
  hasAppDir = !options.disableAppRouter && fs.existsSync(appDir);
572
581
  if (!nextConfig) {
@@ -607,6 +616,7 @@ function vinext(options = {}) {
607
616
  defines["process.env.__NEXT_ROUTER_BASEPATH"] = JSON.stringify(nextConfig.basePath);
608
617
  defines["process.env.__NEXT_CLIENT_ROUTER_STATIC_STALETIME"] = JSON.stringify(String(nextConfig.staleTimes.static));
609
618
  defines["process.env.__VINEXT_PREFETCH_INLINING"] = JSON.stringify(nextConfig.prefetchInlining ? "true" : "false");
619
+ defines["process.env.__NEXT_GESTURE_TRANSITION"] = JSON.stringify(nextConfig.gestureTransition);
610
620
  defines["process.env.__VINEXT_TRAILING_SLASH"] = JSON.stringify(nextConfig.trailingSlash ? "true" : "false");
611
621
  defines["process.env.__VINEXT_IMAGE_REMOTE_PATTERNS"] = JSON.stringify(JSON.stringify(nextConfig.images?.remotePatterns ?? []));
612
622
  defines["process.env.__VINEXT_IMAGE_DOMAINS"] = JSON.stringify(JSON.stringify(nextConfig.images?.domains ?? []));
@@ -640,9 +650,10 @@ function vinext(options = {}) {
640
650
  defines["process.env.__VINEXT_RSC_COMPATIBILITY_ID"] = JSON.stringify(rscCompatibilityId);
641
651
  defines["process.env.__VINEXT_DEPLOYMENT_ID"] = JSON.stringify(nextConfig.deploymentId ?? "");
642
652
  defines["process.env.NEXT_DEPLOYMENT_ID"] = nextConfig.deploymentId ? JSON.stringify(nextConfig.deploymentId) : "false";
653
+ defines["process.env.NEXT_RUNTIME"] = "\"\"";
643
654
  defines["process.env.__NEXT_VERSION"] = JSON.stringify(getVinextVersion());
644
655
  defines["process.env.__NEXT_APP_SHELLS"] = JSON.stringify(nextConfig.appShells);
645
- defines["process.env.__NEXT_CACHE_COMPONENTS"] = JSON.stringify(String(nextConfig.cacheComponents ?? false));
656
+ defines["process.env.__NEXT_CACHE_COMPONENTS"] = JSON.stringify(nextConfig.cacheComponents ?? false);
646
657
  for (const [key, value] of Object.entries(nextConfig.compilerDefine)) {
647
658
  if (key in defines) throw new Error(`The \`compiler.define\` option is configured to replace the \`${key}\` variable. This variable is either part of a built-in or is already configured.`);
648
659
  defines[key] = value;
@@ -730,6 +741,7 @@ function vinext(options = {}) {
730
741
  ...typeof config.server?.hmr === "object" ? config.server.hmr : {},
731
742
  overlay: false
732
743
  };
744
+ const cssModulesOverride = config.css?.modules === false || typeof config.css?.modules === "object" && "Loader" in config.css.modules ? {} : { modules: { Loader: sassComposesLoader.Loader } };
733
745
  const viteConfig = {
734
746
  appType: "custom",
735
747
  build: {
@@ -796,13 +808,21 @@ function vinext(options = {}) {
796
808
  const dirPrefix = resolveAssetsDir(nextConfig.assetPrefix) + "/";
797
809
  return urlPrefix + (filename.startsWith(dirPrefix) ? filename.slice(dirPrefix.length) : filename.startsWith(`_next/static/`) ? filename.slice(ASSET_PREFIX_URL_DIR.length + 1) : filename);
798
810
  } } } : {},
799
- ...postcssOverride || sassPreprocessorOptions ? { css: {
811
+ css: {
800
812
  ...postcssOverride ? { postcss: postcssOverride } : {},
801
- ...sassPreprocessorOptions ? { preprocessorOptions: {
802
- scss: sassPreprocessorOptions,
803
- sass: sassPreprocessorOptions
804
- } } : {}
805
- } } : {}
813
+ preprocessorOptions: (() => {
814
+ const tildeImporter = createSassTildeImporter(root);
815
+ const baseOpts = {
816
+ ...sassPreprocessorOptions,
817
+ importers: [tildeImporter, ...sassPreprocessorOptions?.importers ?? []]
818
+ };
819
+ return {
820
+ scss: baseOpts,
821
+ sass: baseOpts
822
+ };
823
+ })(),
824
+ ...cssModulesOverride
825
+ }
806
826
  };
807
827
  const nextServerExternal = nextConfig?.serverExternalPackages ?? [];
808
828
  const userSsrExternal = Array.isArray(config.ssr?.external) ? [...config.ssr.external, ...nextServerExternal] : config.ssr?.external === true ? true : nextServerExternal;
@@ -825,6 +845,8 @@ function vinext(options = {}) {
825
845
  const appEntries = [`${path.relative(root, appDir)}/**/*.{tsx,ts,jsx,js}`];
826
846
  const explicitInstrumentationEntries = [instrumentationPath, instrumentationClientPath].flatMap((entry) => entry ? [toRelativeFileEntry(root, entry)] : []);
827
847
  const optimizeEntries = [...new Set([...appEntries, ...explicitInstrumentationEntries])];
848
+ const appClientInput = { index: VIRTUAL_APP_BROWSER_ENTRY };
849
+ if (hasPagesDir) appClientInput["vinext-client-entry"] = VIRTUAL_CLIENT_ENTRY;
828
850
  viteConfig.environments = {
829
851
  rsc: {
830
852
  ...hasCloudflarePlugin || hasNitroPlugin ? {} : { resolve: {
@@ -842,7 +864,10 @@ function vinext(options = {}) {
842
864
  },
843
865
  build: {
844
866
  outDir: options.rscOutDir ?? "dist/server",
845
- ...withBuildBundlerOptions(viteMajorVersion, { input: { index: VIRTUAL_RSC_ENTRY } })
867
+ ...withBuildBundlerOptions(viteMajorVersion, {
868
+ input: { index: VIRTUAL_RSC_ENTRY },
869
+ output: createRscFrameworkChunkOutputConfig(viteMajorVersion)
870
+ })
846
871
  }
847
872
  },
848
873
  ssr: {
@@ -874,10 +899,11 @@ function vinext(options = {}) {
874
899
  ])]
875
900
  },
876
901
  build: {
877
- ...hasCloudflarePlugin ? { manifest: true } : {},
902
+ manifest: true,
903
+ ...hasPagesDir ? { ssrManifest: true } : {},
878
904
  assetsInlineLimit: clientAssetsInlineLimit,
879
905
  ...withBuildBundlerOptions(viteMajorVersion, {
880
- input: { index: VIRTUAL_APP_BROWSER_ENTRY },
906
+ input: appClientInput,
881
907
  output: getClientOutputConfigForVite(viteMajorVersion, clientAssetsDir),
882
908
  treeshake: getClientTreeshakeConfigForVite(viteMajorVersion)
883
909
  })
@@ -941,6 +967,7 @@ function vinext(options = {}) {
941
967
  return viteConfig;
942
968
  },
943
969
  configResolved(config) {
970
+ sassComposesLoader.setResolvedConfig(config);
944
971
  if (hasAppDir) {
945
972
  const ssrEnv = config.environments?.ssr;
946
973
  if (ssrEnv?.resolve?.external === true && Array.isArray(ssrEnv.resolve.noExternal)) ssrEnv.resolve.noExternal = ssrEnv.resolve.noExternal.filter((entry) => typeof entry !== "string" || !SSR_EXTERNAL_REACT_ENTRIES.includes(entry));
@@ -1003,10 +1030,12 @@ function vinext(options = {}) {
1003
1030
  allowedOrigins: nextConfig?.serverActionsAllowedOrigins,
1004
1031
  allowedDevOrigins: nextConfig?.allowedDevOrigins,
1005
1032
  bodySizeLimit: nextConfig?.serverActionsBodySizeLimit,
1033
+ bodySizeLimitLabel: nextConfig?.serverActionsBodySizeLimitLabel,
1006
1034
  htmlLimitedBots: nextConfig?.htmlLimitedBots,
1007
1035
  clientTraceMetadata: nextConfig?.clientTraceMetadata,
1008
1036
  assetPrefix: nextConfig?.assetPrefix,
1009
1037
  expireTime: nextConfig?.expireTime,
1038
+ reactMaxHeadersLength: nextConfig?.reactMaxHeadersLength,
1010
1039
  cacheMaxMemorySize: nextConfig?.cacheMaxMemorySize,
1011
1040
  inlineCss: nextConfig?.inlineCss,
1012
1041
  i18n: nextConfig?.i18n,
@@ -1106,6 +1135,25 @@ function vinext(options = {}) {
1106
1135
  });
1107
1136
  }
1108
1137
  },
1138
+ {
1139
+ name: "vinext:client-entry-manifest",
1140
+ apply: "build",
1141
+ generateBundle(_options, bundle) {
1142
+ if (this.environment?.name !== "client") return;
1143
+ const manifest = {};
1144
+ for (const chunk of Object.values(bundle)) {
1145
+ if (chunk.type !== "chunk" || !chunk.isEntry) continue;
1146
+ if (isVirtualEntryFacade(chunk.facadeModuleId, VIRTUAL_CLIENT_ENTRY)) manifest.pagesClientEntry = chunk.fileName;
1147
+ else if (isVirtualEntryFacade(chunk.facadeModuleId, VIRTUAL_APP_BROWSER_ENTRY)) manifest.appBrowserEntry = chunk.fileName;
1148
+ }
1149
+ if (!manifest.pagesClientEntry && !manifest.appBrowserEntry) return;
1150
+ this.emitFile({
1151
+ type: "asset",
1152
+ fileName: VINEXT_CLIENT_ENTRY_MANIFEST,
1153
+ source: JSON.stringify(manifest, null, 2) + "\n"
1154
+ });
1155
+ }
1156
+ },
1109
1157
  asyncHooksStubPlugin,
1110
1158
  createInstrumentationClientTransformPlugin(() => instrumentationClientPath),
1111
1159
  {
@@ -1381,6 +1429,10 @@ function vinext(options = {}) {
1381
1429
  res.end("Bad Request");
1382
1430
  return;
1383
1431
  }
1432
+ {
1433
+ const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
1434
+ url = pathname + qs;
1435
+ }
1384
1436
  const bp = nextConfig?.basePath ?? "";
1385
1437
  if (bp && pathname.startsWith(bp)) {
1386
1438
  const stripped = pathname.slice(bp.length) || "/";
@@ -1408,7 +1460,10 @@ function vinext(options = {}) {
1408
1460
  pathname = dataMatch.pagePathname;
1409
1461
  req.url = url;
1410
1462
  } else {
1411
- res.writeHead(404, { "Content-Type": "application/json" });
1463
+ const deploymentId = process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID;
1464
+ const notFoundHeaders = { "Content-Type": "application/json" };
1465
+ if (deploymentId) notFoundHeaders[NEXTJS_DEPLOYMENT_ID_HEADER] = deploymentId;
1466
+ res.writeHead(404, notFoundHeaders);
1412
1467
  res.end("{}");
1413
1468
  return;
1414
1469
  }
@@ -1421,154 +1476,110 @@ function vinext(options = {}) {
1421
1476
  for (const header of INTERNAL_HEADERS) delete req.headers[header];
1422
1477
  for (const header of VINEXT_INTERNAL_HEADERS) delete req.headers[header];
1423
1478
  const requestOrigin = `http://${req.headers.host || "localhost"}`;
1424
- const preMiddlewareReqUrl = new URL(url, requestOrigin);
1425
- const preMiddlewareReqCtx = requestContextFromRequest(new Request(preMiddlewareReqUrl, { headers: nodeRequestHeaders }));
1426
- const matchPathname = nextConfig?.i18n ? normalizeDefaultLocalePathname(pathname, nextConfig.i18n, { hostname: preMiddlewareReqUrl.hostname }) : pathname;
1427
- const matchResolvedPathname = (p) => nextConfig?.i18n ? normalizeDefaultLocalePathname(p, nextConfig.i18n, { hostname: preMiddlewareReqUrl.hostname }) : p;
1428
- if (nextConfig?.redirects.length) {
1429
- if (applyRedirects(matchPathname, res, nextConfig.redirects, preMiddlewareReqCtx, nextConfig.basePath ?? "")) return;
1430
- }
1479
+ const method = req.method ?? "GET";
1480
+ const webRequest = new Request(new URL(url, requestOrigin), {
1481
+ method,
1482
+ headers: nodeRequestHeaders
1483
+ });
1431
1484
  const applyRequestHeadersToNodeRequest = (nextRequestHeaders) => {
1432
1485
  for (const key of Object.keys(req.headers)) delete req.headers[key];
1433
1486
  for (const [key, value] of nextRequestHeaders) req.headers[key] = value;
1434
1487
  };
1435
- let middlewareRequestHeaders = null;
1436
- let deferredMwResponseHeaders = null;
1437
- const applyDeferredMwHeaders = () => {
1438
- if (deferredMwResponseHeaders) for (const [key, value] of deferredMwResponseHeaders) res.appendHeader(key, value);
1439
- };
1440
- const applyMwRequestHeadersForExternalProxy = () => {
1441
- if (middlewareRequestHeaders) applyRequestHeadersToNodeRequest(middlewareRequestHeaders);
1442
- else delete req.headers[VINEXT_MW_CTX_HEADER];
1443
- };
1444
- if (middlewarePath) {
1488
+ const capturedMiddlewarePath = middlewarePath;
1489
+ const devRunMiddlewareAdapter = capturedMiddlewarePath ? async (_request, _ctx, opts) => {
1445
1490
  const rawProto = process.env.VINEXT_TRUST_PROXY === "1" || (process.env.VINEXT_TRUSTED_HOSTS ?? "").split(",").some((h) => h.trim()) ? String(req.headers["x-forwarded-proto"] || "").split(",")[0].trim() : "";
1446
- const origin = `${rawProto === "https" || rawProto === "http" ? rawProto : "http"}://${req.headers.host || "localhost"}`;
1447
- const middlewareRequest = new Request(new URL(url, origin), {
1491
+ const mwOrigin = `${rawProto === "https" || rawProto === "http" ? rawProto : "http"}://${req.headers.host || "localhost"}`;
1492
+ const middlewareRequest = new Request(new URL(url, mwOrigin), {
1448
1493
  method: req.method,
1449
1494
  headers: nodeRequestHeaders
1450
1495
  });
1451
- const result = await runMiddleware(getPagesRunner(), middlewarePath, middlewareRequest, nextConfig?.i18n, nextConfig?.basePath, nextConfig?.trailingSlash, isDataRequest);
1452
- if (result.waitUntilPromises?.length) Promise.allSettled(result.waitUntilPromises);
1453
- if (!result.continue) {
1454
- if (result.redirectUrl) {
1455
- const redirectHeaders = { Location: result.redirectUrl };
1456
- if (result.responseHeaders) for (const [key, value] of result.responseHeaders) {
1457
- const existing = redirectHeaders[key];
1458
- if (existing === void 0) redirectHeaders[key] = value;
1459
- else if (Array.isArray(existing)) existing.push(value);
1460
- else redirectHeaders[key] = [existing, value];
1461
- }
1462
- res.writeHead(result.redirectStatus ?? 307, redirectHeaders);
1463
- res.end();
1464
- return;
1465
- }
1466
- if (result.response) {
1467
- res.statusCode = result.response.status;
1468
- for (const [key, value] of result.response.headers) res.appendHeader(key, value);
1469
- const body = Buffer.from(await result.response.arrayBuffer());
1470
- res.end(body);
1471
- return;
1472
- }
1473
- }
1474
- if (result.responseHeaders) {
1475
- const currentRequestHeaders = new Headers();
1476
- for (const [key, value] of Object.entries(req.headers)) if (Array.isArray(value)) currentRequestHeaders.set(key, value.join(", "));
1477
- else if (value !== void 0) currentRequestHeaders.set(key, value);
1478
- middlewareRequestHeaders = buildRequestHeadersFromMiddlewareResponse(currentRequestHeaders, result.responseHeaders, { preserveCredentialHeaders: Boolean(result.rewriteUrl && isExternalUrl(result.rewriteUrl)) });
1479
- if (middlewareRequestHeaders && !hasAppDir) applyRequestHeadersToNodeRequest(middlewareRequestHeaders);
1480
- if (hasAppDir) {
1481
- deferredMwResponseHeaders = [];
1482
- for (const [key, value] of result.responseHeaders) if (!key.startsWith("x-middleware-")) deferredMwResponseHeaders.push([key, value]);
1483
- } else for (const [key, value] of result.responseHeaders) if (!key.startsWith("x-middleware-")) res.appendHeader(key, value);
1484
- }
1485
- if (result.rewriteUrl) {
1486
- url = result.rewriteUrl;
1487
- req.url = url;
1488
- }
1489
- const middlewareStatus = result.status ?? result.rewriteStatus;
1490
- if (middlewareStatus !== void 0) req.__vinextMiddlewareStatus = middlewareStatus;
1491
- if (hasAppDir) {
1496
+ const result = await runMiddleware(getPagesRunner(), capturedMiddlewarePath, middlewareRequest, nextConfig?.i18n, nextConfig?.basePath, nextConfig?.trailingSlash, opts.isDataRequest);
1497
+ if (hasAppDir && result.continue) {
1492
1498
  const mwCtxEntries = [];
1493
1499
  if (result.responseHeaders) {
1494
1500
  for (const [key, value] of result.responseHeaders) if (key !== "x-middleware-next" && key !== "x-middleware-rewrite") mwCtxEntries.push([key, value]);
1495
1501
  }
1502
+ const mwStatus = result.status ?? result.rewriteStatus;
1496
1503
  req.headers[VINEXT_MW_CTX_HEADER] = JSON.stringify({
1497
1504
  h: mwCtxEntries,
1498
- s: middlewareStatus ?? null,
1505
+ s: mwStatus ?? null,
1499
1506
  r: result.rewriteUrl ?? null
1500
1507
  });
1501
1508
  }
1502
- }
1503
- const reqUrl = new URL(url, requestOrigin);
1504
- const reqCtx = requestContextFromRequest(new Request(reqUrl, { headers: middlewareRequestHeaders ?? nodeRequestHeaders }));
1505
- if (nextConfig?.headers.length) applyHeaders(matchPathname, res, nextConfig.headers, preMiddlewareReqCtx, bp);
1506
- let resolvedUrl = url;
1507
- if (nextConfig?.rewrites.beforeFiles.length) {
1508
- const rewritten = applyRewrites(matchPathname, nextConfig.rewrites.beforeFiles, reqCtx, bp);
1509
- if (rewritten) resolvedUrl = mergeRewriteQuery(url, rewritten);
1510
- }
1511
- if (isExternalUrl(resolvedUrl)) {
1512
- applyDeferredMwHeaders();
1513
- applyMwRequestHeadersForExternalProxy();
1514
- await proxyExternalRewriteNode(req, res, resolvedUrl);
1509
+ return result;
1510
+ } : null;
1511
+ const devPageRoutes = await pagesRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher);
1512
+ const pipelineResult = await runPagesRequest(webRequest, {
1513
+ basePath: bp,
1514
+ trailingSlash: nextConfig?.trailingSlash ?? false,
1515
+ i18nConfig: nextConfig?.i18n ?? null,
1516
+ configRedirects: nextConfig?.redirects ?? [],
1517
+ configRewrites: nextConfig?.rewrites ?? {
1518
+ beforeFiles: [],
1519
+ afterFiles: [],
1520
+ fallback: []
1521
+ },
1522
+ configHeaders: nextConfig?.headers ?? [],
1523
+ hadBasePath: true,
1524
+ isDataReq,
1525
+ isDataRequest,
1526
+ rawSearch: url.includes("?") ? url.slice(url.indexOf("?")) : "",
1527
+ runMiddleware: devRunMiddlewareAdapter,
1528
+ matchPageRoute: (resolvedPathname) => {
1529
+ const m = matchRoute(resolvedPathname, devPageRoutes);
1530
+ return m ? { route: { isDynamic: m.route.isDynamic } } : null;
1531
+ },
1532
+ proxyExternal: async (currentRequest, externalUrl) => {
1533
+ const externalMethod = req.method ?? "GET";
1534
+ const hasBody = externalMethod !== "GET" && externalMethod !== "HEAD";
1535
+ const externalInit = {
1536
+ method: externalMethod,
1537
+ headers: currentRequest.headers
1538
+ };
1539
+ if (hasBody) {
1540
+ const { Readable } = await import("node:stream");
1541
+ externalInit.body = Readable.toWeb(req);
1542
+ externalInit.duplex = "half";
1543
+ }
1544
+ return proxyExternalRequest(new Request(new URL(url, requestOrigin), externalInit), externalUrl);
1545
+ }
1546
+ });
1547
+ if (pipelineResult.type === "response") {
1548
+ await writeWebResponseToNodeRes(res, pipelineResult.response);
1515
1549
  return;
1516
1550
  }
1517
- const apiLookupUrl = stripI18nLocaleForApiRoute(resolvedUrl, nextConfig?.i18n);
1518
- const resolvedPathname = apiLookupUrl.split("?")[0];
1519
- if (resolvedPathname.startsWith("/api/") || resolvedPathname === "/api") {
1551
+ if (pipelineResult.type === "next") return next();
1552
+ if (pipelineResult.type === "handled") return;
1553
+ const flushStagedHeaders = () => {
1554
+ for (const [key, value] of Object.entries(pipelineResult.stagedHeaders)) if (Array.isArray(value)) for (const v of value) res.appendHeader(key, v);
1555
+ else res.appendHeader(key, value);
1556
+ };
1557
+ const flushRequestHeaders = () => {
1558
+ applyRequestHeadersToNodeRequest(pipelineResult.requestHeaders);
1559
+ };
1560
+ if (pipelineResult.type === "api") {
1520
1561
  const apiRoutes = await apiRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher);
1521
- if (matchRoute(apiLookupUrl, apiRoutes)) {
1522
- applyDeferredMwHeaders();
1523
- if (middlewareRequestHeaders) applyRequestHeadersToNodeRequest(middlewareRequestHeaders);
1562
+ if (matchRoute(pipelineResult.apiUrl, apiRoutes)) {
1563
+ flushStagedHeaders();
1564
+ flushRequestHeaders();
1565
+ if (pipelineResult.middlewareStatus !== void 0) req.__vinextMiddlewareStatus = pipelineResult.middlewareStatus;
1524
1566
  }
1525
- if (await handleApiRoute(getPagesRunner(), req, res, apiLookupUrl, apiRoutes)) return;
1567
+ if (await handleApiRoute(getPagesRunner(), req, res, pipelineResult.apiUrl, apiRoutes)) return;
1526
1568
  if (hasAppDir) return next();
1527
1569
  res.statusCode = 404;
1528
1570
  res.end("404 - API route not found");
1529
1571
  return;
1530
1572
  }
1531
- const routes = await pagesRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher);
1532
- let match = matchRoute(resolvedUrl.split("?")[0], routes);
1533
- if ((!match || match.route.isDynamic) && nextConfig?.rewrites.afterFiles.length) {
1534
- const afterRewrite = applyRewrites(matchResolvedPathname(resolvedUrl.split("?")[0]), nextConfig.rewrites.afterFiles, reqCtx, bp);
1535
- if (afterRewrite) {
1536
- resolvedUrl = mergeRewriteQuery(resolvedUrl, afterRewrite);
1537
- match = matchRoute(resolvedUrl.split("?")[0], routes);
1538
- }
1539
- }
1540
- if (isExternalUrl(resolvedUrl)) {
1541
- applyDeferredMwHeaders();
1542
- applyMwRequestHeadersForExternalProxy();
1543
- await proxyExternalRewriteNode(req, res, resolvedUrl);
1544
- return;
1545
- }
1546
- const handler = createSSRHandler(server, getPagesRunner(), routes, pagesDir, nextConfig?.i18n, fileMatcher, nextConfig?.basePath ?? "", nextConfig?.trailingSlash ?? false, middlewarePath !== null, nextConfig?.clientTraceMetadata);
1547
- const mwStatus = req.__vinextMiddlewareStatus;
1548
- if (match) {
1549
- applyDeferredMwHeaders();
1550
- if (middlewareRequestHeaders) applyRequestHeadersToNodeRequest(middlewareRequestHeaders);
1551
- await handler(req, res, resolvedUrl, mwStatus, isDataReq);
1552
- return;
1553
- }
1554
- if (nextConfig?.rewrites.fallback.length) {
1555
- const fallbackRewrite = applyRewrites(matchResolvedPathname(resolvedUrl.split("?")[0]), nextConfig.rewrites.fallback, reqCtx, bp);
1556
- if (fallbackRewrite) {
1557
- if (isExternalUrl(fallbackRewrite)) {
1558
- applyDeferredMwHeaders();
1559
- applyMwRequestHeadersForExternalProxy();
1560
- await proxyExternalRewriteNode(req, res, fallbackRewrite);
1561
- return;
1562
- }
1563
- if (!matchRoute(fallbackRewrite.split("?")[0], routes) && hasAppDir) return next();
1564
- applyDeferredMwHeaders();
1565
- if (middlewareRequestHeaders) applyRequestHeadersToNodeRequest(middlewareRequestHeaders);
1566
- await handler(req, res, fallbackRewrite, mwStatus, isDataReq);
1567
- return;
1568
- }
1573
+ {
1574
+ const routes = await pagesRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher);
1575
+ if (!matchRoute(pipelineResult.resolvedUrl.split("?")[0], routes) && hasAppDir) return next();
1576
+ const handler = createSSRHandler(server, getPagesRunner(), routes, pagesDir, nextConfig?.i18n, fileMatcher, nextConfig?.basePath ?? "", nextConfig?.trailingSlash ?? false, middlewarePath !== null, (nextConfig?.rewrites.beforeFiles.length ?? 0) > 0 || (nextConfig?.rewrites.afterFiles.length ?? 0) > 0 || (nextConfig?.rewrites.fallback.length ?? 0) > 0, nextConfig?.clientTraceMetadata);
1577
+ flushStagedHeaders();
1578
+ flushRequestHeaders();
1579
+ if (pipelineResult.middlewareStatus !== void 0) req.__vinextMiddlewareStatus = pipelineResult.middlewareStatus;
1580
+ req.url = pipelineResult.resolvedUrl;
1581
+ await handler(req, res, pipelineResult.resolvedUrl, req.__vinextMiddlewareStatus, pipelineResult.isDataReq);
1569
1582
  }
1570
- if (hasAppDir) return next();
1571
- await handler(req, res, resolvedUrl, mwStatus, isDataReq);
1572
1583
  } catch (e) {
1573
1584
  next(e);
1574
1585
  }
@@ -1635,9 +1646,12 @@ function vinext(options = {}) {
1635
1646
  {
1636
1647
  name: "vinext:compiler-define-server",
1637
1648
  configEnvironment(name) {
1638
- if (Object.keys(nextConfig.compilerDefineServer).length === 0) return null;
1639
1649
  if (name === "client") return null;
1640
- return { define: { ...nextConfig.compilerDefineServer } };
1650
+ const serverDefines = { ...nextConfig.compilerDefineServer };
1651
+ serverDefines["process.env.NEXT_RUNTIME"] = JSON.stringify("nodejs");
1652
+ const sharedRevalidateSecret = process.env.__VINEXT_SHARED_REVALIDATE_SECRET;
1653
+ if (sharedRevalidateSecret) serverDefines["process.env.__VINEXT_REVALIDATE_SECRET"] = JSON.stringify(sharedRevalidateSecret);
1654
+ return { define: serverDefines };
1641
1655
  }
1642
1656
  },
1643
1657
  {
@@ -1726,6 +1740,7 @@ function vinext(options = {}) {
1726
1740
  createGoogleFontsPlugin(_fontGoogleShimPath, _shimsDir),
1727
1741
  createLocalFontsPlugin(_shimsDir),
1728
1742
  createOptimizeImportsPlugin(() => nextConfig, () => root),
1743
+ createDynamicPreloadMetadataPlugin(),
1729
1744
  {
1730
1745
  name: "vinext:use-cache",
1731
1746
  transform: {
@@ -1830,6 +1845,7 @@ function vinext(options = {}) {
1830
1845
  }
1831
1846
  },
1832
1847
  createImportMetaUrlPlugin({ getRoot: () => root }),
1848
+ createRequireContextPlugin(),
1833
1849
  createOgInlineFetchAssetsPlugin(),
1834
1850
  createOgAssetsPlugin(),
1835
1851
  createServerExternalsManifestPlugin(),
@@ -2061,20 +2077,15 @@ function vinext(options = {}) {
2061
2077
  const distDir = path.resolve(buildRoot, "dist");
2062
2078
  if (!fs.existsSync(distDir)) return;
2063
2079
  const clientDir = path.resolve(buildRoot, "dist", "client");
2064
- const clientBase = envConfig.base ?? "/";
2065
- let lazyChunksData = null;
2066
- let clientEntryFile = null;
2067
- const buildManifest = readClientBuildManifest(path.join(clientDir, ".vite", "manifest.json"));
2068
- if (buildManifest) {
2069
- clientEntryFile = findClientEntryFile({
2070
- buildManifest,
2071
- clientDir,
2072
- assetsSubdir: resolveAssetsDir(nextConfig?.assetPrefix),
2073
- assetBase: clientBase
2074
- }) ?? null;
2075
- const lazy = manifestFilesWithBase(computeLazyChunks(buildManifest), clientBase);
2076
- if (lazy.length > 0) lazyChunksData = lazy;
2077
- }
2080
+ const runtimeMetadata = computeClientRuntimeMetadata({
2081
+ clientDir,
2082
+ assetBase: envConfig.base ?? "/",
2083
+ assetPrefix: nextConfig.assetPrefix,
2084
+ includeClientEntry: !hasAppDir ? true : hasPagesDir ? "pages-client-entry" : false
2085
+ });
2086
+ const lazyChunksData = runtimeMetadata.lazyChunks ?? null;
2087
+ const dynamicPreloadsData = runtimeMetadata.dynamicPreloads ?? null;
2088
+ let clientEntryFile = runtimeMetadata.clientEntryFile ?? null;
2078
2089
  let ssrManifestData = null;
2079
2090
  const ssrManifestPath = path.join(clientDir, ".vite", "ssr-manifest.json");
2080
2091
  if (fs.existsSync(ssrManifestPath)) try {
@@ -2082,13 +2093,17 @@ function vinext(options = {}) {
2082
2093
  } catch {}
2083
2094
  if (hasAppDir) {
2084
2095
  const workerEntry = path.resolve(distDir, "server", "index.js");
2085
- if (fs.existsSync(workerEntry) && (lazyChunksData || ssrManifestData)) {
2086
- let code = fs.readFileSync(workerEntry, "utf-8");
2087
- const globals = [];
2088
- if (ssrManifestData) globals.push(`globalThis.__VINEXT_SSR_MANIFEST__ = ${JSON.stringify(ssrManifestData)};`);
2089
- if (lazyChunksData) globals.push(`globalThis.__VINEXT_LAZY_CHUNKS__ = ${JSON.stringify(lazyChunksData)};`);
2090
- code = globals.join("\n") + "\n" + code;
2091
- fs.writeFileSync(workerEntry, code);
2096
+ if (fs.existsSync(workerEntry)) {
2097
+ const script = buildRuntimeGlobalsScript({
2098
+ clientEntryFile,
2099
+ ssrManifest: ssrManifestData,
2100
+ lazyChunks: lazyChunksData,
2101
+ dynamicPreloads: dynamicPreloadsData
2102
+ });
2103
+ if (script) {
2104
+ const code = fs.readFileSync(workerEntry, "utf-8");
2105
+ fs.writeFileSync(workerEntry, script + "\n" + code);
2106
+ }
2092
2107
  }
2093
2108
  } else {
2094
2109
  let workerOutDir = null;
@@ -2103,19 +2118,15 @@ function vinext(options = {}) {
2103
2118
  if (!workerOutDir) return;
2104
2119
  const workerEntry = path.join(workerOutDir, "index.js");
2105
2120
  if (!fs.existsSync(workerEntry)) return;
2106
- if (!clientEntryFile) clientEntryFile = findClientEntryFile({
2107
- clientDir,
2108
- assetsSubdir: resolveAssetsDir(nextConfig?.assetPrefix),
2109
- assetBase: clientBase
2110
- }) ?? null;
2111
- if (clientEntryFile || ssrManifestData || lazyChunksData) {
2112
- let code = fs.readFileSync(workerEntry, "utf-8");
2113
- const globals = [];
2114
- if (clientEntryFile) globals.push(`globalThis.__VINEXT_CLIENT_ENTRY__ = ${JSON.stringify(clientEntryFile)};`);
2115
- if (ssrManifestData) globals.push(`globalThis.__VINEXT_SSR_MANIFEST__ = ${JSON.stringify(ssrManifestData)};`);
2116
- if (lazyChunksData) globals.push(`globalThis.__VINEXT_LAZY_CHUNKS__ = ${JSON.stringify(lazyChunksData)};`);
2117
- code = globals.join("\n") + "\n" + code;
2118
- fs.writeFileSync(workerEntry, code);
2121
+ const script = buildRuntimeGlobalsScript({
2122
+ clientEntryFile,
2123
+ ssrManifest: ssrManifestData,
2124
+ lazyChunks: lazyChunksData,
2125
+ dynamicPreloads: dynamicPreloadsData
2126
+ });
2127
+ if (script) {
2128
+ const code = fs.readFileSync(workerEntry, "utf-8");
2129
+ fs.writeFileSync(workerEntry, script + "\n" + code);
2119
2130
  }
2120
2131
  }
2121
2132
  const headersPath = path.join(clientDir, "_headers");
@@ -2129,9 +2140,11 @@ function vinext(options = {}) {
2129
2140
  fs.mkdirSync(clientDir, { recursive: true });
2130
2141
  fs.writeFileSync(headersPath, headersContent);
2131
2142
  }
2143
+ ensureAssetsIgnore(clientDir);
2132
2144
  }
2133
2145
  }
2134
2146
  },
2147
+ createWasmModuleImportPlugin(),
2135
2148
  {
2136
2149
  name: "vinext:og-font-patch",
2137
2150
  enforce: "pre",
@@ -2202,91 +2215,31 @@ function getNextPublicEnvDefines() {
2202
2215
  return defines;
2203
2216
  }
2204
2217
  /**
2205
- * Apply redirect rules from next.config.js.
2206
- * Returns true if a redirect was applied.
2218
+ * Write a Web API Response to a Node.js ServerResponse.
2219
+ * Handles multi-value headers (Set-Cookie) correctly.
2207
2220
  */
2208
- function applyRedirects(pathname, res, redirects, ctx, basePath = "") {
2209
- const result = matchRedirect(pathname, redirects, ctx, {
2210
- basePath,
2211
- hadBasePath: true
2221
+ async function writeWebResponseToNodeRes(res, response) {
2222
+ const nodeHeaders = {};
2223
+ response.headers.forEach((value, key) => {
2224
+ if (key === "set-cookie") return;
2225
+ const existing = nodeHeaders[key];
2226
+ if (existing !== void 0) nodeHeaders[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];
2227
+ else nodeHeaders[key] = value;
2212
2228
  });
2213
- if (result) {
2214
- const dest = sanitizeDestination(basePath && !isExternalUrl(result.destination) && !hasBasePath(result.destination, basePath) ? basePath + result.destination : result.destination);
2215
- res.writeHead(result.permanent ? 308 : 307, { Location: dest });
2216
- res.end();
2217
- return true;
2218
- }
2219
- return false;
2220
- }
2221
- async function proxyExternalRewriteNode(req, res, externalUrl) {
2222
- try {
2223
- const origin = `http://${req.headers.host || "localhost"}`;
2224
- const method = req.method ?? "GET";
2225
- const hasBody = method !== "GET" && method !== "HEAD";
2226
- const init = {
2227
- method,
2228
- headers: Object.fromEntries(Object.entries(req.headers).filter(([, v]) => v !== void 0).map(([k, v]) => [k, Array.isArray(v) ? v.join(", ") : String(v)]))
2229
- };
2230
- if (hasBody) {
2231
- const { Readable } = await import("node:stream");
2232
- init.body = Readable.toWeb(req);
2233
- init.duplex = "half";
2234
- }
2235
- const proxyResponse = await proxyExternalRequest(new Request(new URL(req.url ?? "/", origin), init), externalUrl);
2236
- const nodeHeaders = {};
2237
- proxyResponse.headers.forEach((value, key) => {
2238
- const existing = nodeHeaders[key];
2239
- if (existing !== void 0) nodeHeaders[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];
2240
- else nodeHeaders[key] = value;
2229
+ const cookies = response.headers.getSetCookie?.() ?? [];
2230
+ if (cookies.length > 0) nodeHeaders["set-cookie"] = cookies;
2231
+ if (response.statusText) res.writeHead(response.status, response.statusText, nodeHeaders);
2232
+ else res.writeHead(response.status, nodeHeaders);
2233
+ if (response.body) {
2234
+ const { Readable } = await import("node:stream");
2235
+ const nodeStream = Readable.fromWeb(response.body);
2236
+ await new Promise((resolve, reject) => {
2237
+ nodeStream.on("error", reject);
2238
+ res.on("error", reject);
2239
+ nodeStream.pipe(res);
2240
+ nodeStream.on("end", resolve);
2241
2241
  });
2242
- res.writeHead(proxyResponse.status, nodeHeaders);
2243
- if (proxyResponse.body) {
2244
- const { Readable: ReadableImport } = await import("node:stream");
2245
- ReadableImport.fromWeb(proxyResponse.body).pipe(res);
2246
- } else res.end();
2247
- } catch (e) {
2248
- console.error("[vinext] External rewrite proxy error:", e);
2249
- if (!res.headersSent) {
2250
- res.writeHead(502);
2251
- res.end("Bad Gateway");
2252
- }
2253
- }
2254
- }
2255
- /**
2256
- * Apply rewrite rules from next.config.js.
2257
- * Returns the rewritten URL or null if no rewrite matched.
2258
- */
2259
- function applyRewrites(pathname, rewrites, ctx, basePath = "") {
2260
- const dest = matchRewrite(pathname, rewrites, ctx, {
2261
- basePath,
2262
- hadBasePath: true
2263
- });
2264
- if (dest) return sanitizeDestination(dest);
2265
- return null;
2266
- }
2267
- /**
2268
- * Apply custom header rules from next.config.js.
2269
- * Middleware headers take precedence: if a header key was already set on the
2270
- * response (by middleware), the config value is skipped for that key.
2271
- */
2272
- function applyHeaders(pathname, res, headers, ctx, basePath = "") {
2273
- const matched = matchHeaders(pathname, headers, ctx, {
2274
- basePath,
2275
- hadBasePath: true
2276
- });
2277
- for (const header of matched) {
2278
- const lk = header.key.toLowerCase();
2279
- if (lk === "set-cookie") {
2280
- const existing = res.getHeader(lk);
2281
- if (Array.isArray(existing)) res.setHeader(header.key, [...existing, header.value]);
2282
- else if (existing) res.setHeader(header.key, [String(existing), header.value]);
2283
- else res.setHeader(header.key, header.value);
2284
- } else if (lk === "vary") {
2285
- const existing = res.getHeader(lk);
2286
- if (existing) res.setHeader(header.key, existing + ", " + header.value);
2287
- else res.setHeader(header.key, header.value);
2288
- } else if (!res.getHeader(lk)) res.setHeader(header.key, header.value);
2289
- }
2242
+ } else res.end();
2290
2243
  }
2291
2244
  //#endregion
2292
2245
  export { vinext as default, staticExportApp, staticExportPages };