vinext 1.3.1 → 1.4.1

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 (271) hide show
  1. package/README.md +25 -22
  2. package/THIRD_PARTY_LICENSES.md +47 -0
  3. package/dist/_virtual/_rolldown/runtime.js +3 -2
  4. package/dist/build/prerender.js +4 -3
  5. package/dist/build/report.d.ts +0 -14
  6. package/dist/build/report.js +1 -51
  7. package/dist/check.js +4 -7
  8. package/dist/cli.js +3 -0
  9. package/dist/client/dev-error-overlay-store.d.ts +1 -0
  10. package/dist/client/dev-error-overlay.d.ts +2 -0
  11. package/dist/client/dev-error-overlay.js +20 -4
  12. package/dist/client/navigation-runtime.d.ts +13 -1
  13. package/dist/client/navigation-runtime.js +1 -1
  14. package/dist/config/config-matchers.js +2 -0
  15. package/dist/config/destination-params.d.ts +2 -1
  16. package/dist/config/destination-params.js +52 -2
  17. package/dist/config/next-config.d.ts +25 -0
  18. package/dist/config/next-config.js +82 -4
  19. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-codec.js +327 -0
  20. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-data.js +123 -0
  21. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/index.js +29 -0
  22. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/internal.js +134 -0
  23. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-codec.js +50 -0
  24. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data-generated.js +455 -0
  25. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data.js +147 -0
  26. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/big5-added.json.js +169 -0
  27. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp936.json.js +2584 -0
  28. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp949.json.js +2220 -0
  29. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp950.json.js +227 -0
  30. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/eucjp.json.js +425 -0
  31. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gb18030-ranges.json.js +427 -0
  32. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gbk-added.json.js +229 -0
  33. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/shiftjis.json.js +292 -0
  34. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf16.js +106 -0
  35. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf7.js +182 -0
  36. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/bom-handling.js +42 -0
  37. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/extend-node.js +147 -0
  38. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/index.js +94 -0
  39. package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/streams.js +95 -0
  40. package/dist/deps/.pnpm/safer-buffer@2.1.2/deps/safer-buffer/safer.js +45 -0
  41. package/dist/entries/app-rsc-entry.js +17 -49
  42. package/dist/entries/app-rsc-manifest.js +3 -4
  43. package/dist/entries/app-ssr-entry.js +1 -0
  44. package/dist/entries/pages-server-entry.js +36 -9
  45. package/dist/index.js +112 -90
  46. package/dist/init-cloudflare.d.ts +1 -3
  47. package/dist/init-cloudflare.js +10 -48
  48. package/dist/init-platform.d.ts +2 -0
  49. package/dist/init-platform.js +4 -0
  50. package/dist/plugins/extensionless-dynamic-import.js +6 -2
  51. package/dist/plugins/next-intl-catalog.d.ts +12 -0
  52. package/dist/plugins/next-intl-catalog.js +85 -0
  53. package/dist/plugins/pages-node-externals.d.ts +1 -0
  54. package/dist/plugins/pages-node-externals.js +1 -1
  55. package/dist/plugins/strip-server-exports.js +2 -1
  56. package/dist/plugins/use-cache-callable.d.ts +1 -1
  57. package/dist/plugins/use-cache-callable.js +136 -94
  58. package/dist/routing/app-route-graph.d.ts +6 -0
  59. package/dist/routing/app-route-graph.js +9 -1
  60. package/dist/server/api-handler.js +21 -5
  61. package/dist/server/app-bfcache-identity.js +1 -1
  62. package/dist/server/app-browser-entry.js +86 -66
  63. package/dist/server/app-browser-history-controller.d.ts +5 -4
  64. package/dist/server/app-browser-history-controller.js +93 -15
  65. package/dist/server/app-browser-navigation-controller.d.ts +2 -2
  66. package/dist/server/app-browser-navigation-controller.js +1 -2
  67. package/dist/server/app-browser-rsc-redirect.js +7 -7
  68. package/dist/server/app-browser-server-action-client.d.ts +2 -0
  69. package/dist/server/app-browser-server-action-client.js +5 -4
  70. package/dist/server/app-browser-state.d.ts +2 -4
  71. package/dist/server/app-browser-state.js +9 -4
  72. package/dist/server/app-browser-supplemental-refresh.js +16 -1
  73. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  74. package/dist/server/app-browser-visible-commit.js +4 -14
  75. package/dist/server/app-elements-wire.d.ts +6 -38
  76. package/dist/server/app-elements-wire.js +4 -41
  77. package/dist/server/app-elements.d.ts +2 -2
  78. package/dist/server/app-elements.js +2 -2
  79. package/dist/server/app-history-state.d.ts +2 -2
  80. package/dist/server/app-history-state.js +5 -2
  81. package/dist/server/app-mounted-layouts.d.ts +21 -0
  82. package/dist/server/app-mounted-layouts.js +67 -0
  83. package/dist/server/app-optimistic-routing.d.ts +19 -1
  84. package/dist/server/app-optimistic-routing.js +43 -4
  85. package/dist/server/app-page-boundary-render.js +10 -14
  86. package/dist/server/app-page-boundary.js +2 -2
  87. package/dist/server/app-page-cache-finalizer.d.ts +12 -1
  88. package/dist/server/app-page-cache-finalizer.js +70 -29
  89. package/dist/server/app-page-cache.d.ts +13 -1
  90. package/dist/server/app-page-cache.js +31 -9
  91. package/dist/server/app-page-dispatch.d.ts +5 -11
  92. package/dist/server/app-page-dispatch.js +84 -155
  93. package/dist/server/app-page-element-builder.d.ts +2 -2
  94. package/dist/server/app-page-element-builder.js +13 -12
  95. package/dist/server/app-page-execution.d.ts +17 -52
  96. package/dist/server/app-page-execution.js +102 -95
  97. package/dist/server/app-page-head.d.ts +13 -0
  98. package/dist/server/app-page-head.js +44 -16
  99. package/dist/server/app-page-http-access-fallback-metadata.d.ts +1 -0
  100. package/dist/server/app-page-http-access-fallback-metadata.js +2 -2
  101. package/dist/server/app-page-layout-gate.d.ts +35 -0
  102. package/dist/server/app-page-layout-gate.js +50 -0
  103. package/dist/server/app-page-params.d.ts +0 -1
  104. package/dist/server/app-page-params.js +1 -14
  105. package/dist/server/app-page-probe.d.ts +3 -21
  106. package/dist/server/app-page-probe.js +4 -37
  107. package/dist/server/app-page-render.d.ts +2 -13
  108. package/dist/server/app-page-render.js +103 -234
  109. package/dist/server/app-page-request.d.ts +1 -3
  110. package/dist/server/app-page-request.js +1 -1
  111. package/dist/server/app-page-response.js +3 -3
  112. package/dist/server/app-page-route-wiring.d.ts +13 -6
  113. package/dist/server/app-page-route-wiring.js +86 -63
  114. package/dist/server/app-page-rsc-render-status.d.ts +27 -1
  115. package/dist/server/app-page-rsc-render-status.js +121 -13
  116. package/dist/server/app-page-stream.d.ts +12 -8
  117. package/dist/server/app-page-stream.js +4 -3
  118. package/dist/server/app-pages-bridge.d.ts +4 -0
  119. package/dist/server/app-pages-bridge.js +7 -3
  120. package/dist/server/app-render-dependency.d.ts +11 -4
  121. package/dist/server/app-render-dependency.js +86 -38
  122. package/dist/server/app-request-stage-dispatch.js +1 -1
  123. package/dist/server/app-request-stage-independent-entry.js +1 -1
  124. package/dist/server/app-route-handler-cache.js +2 -2
  125. package/dist/server/app-route-handler-dispatch.js +14 -9
  126. package/dist/server/app-route-handler-execution.js +11 -5
  127. package/dist/server/app-route-handler-policy.d.ts +1 -1
  128. package/dist/server/app-route-handler-policy.js +3 -3
  129. package/dist/server/app-route-handler-response.js +1 -1
  130. package/dist/server/app-route-handler-runtime.d.ts +1 -1
  131. package/dist/server/app-route-handler-runtime.js +28 -11
  132. package/dist/server/app-router-entry.js +1 -1
  133. package/dist/server/app-rsc-cache-busting.d.ts +12 -12
  134. package/dist/server/app-rsc-cache-busting.js +31 -72
  135. package/dist/server/app-rsc-error-handler.d.ts +2 -1
  136. package/dist/server/app-rsc-error-handler.js +10 -2
  137. package/dist/server/app-rsc-errors.d.ts +8 -0
  138. package/dist/server/app-rsc-errors.js +11 -1
  139. package/dist/server/app-rsc-handler.d.ts +5 -5
  140. package/dist/server/app-rsc-handler.js +80 -83
  141. package/dist/server/app-rsc-request-normalization.d.ts +10 -16
  142. package/dist/server/app-rsc-request-normalization.js +12 -18
  143. package/dist/server/app-rsc-response-finalizer.js +2 -2
  144. package/dist/server/app-rsc-response-stage.js +9 -15
  145. package/dist/server/app-server-action-execution.d.ts +3 -1
  146. package/dist/server/app-server-action-execution.js +15 -8
  147. package/dist/server/app-ssr-entry.d.ts +8 -0
  148. package/dist/server/app-ssr-entry.js +22 -16
  149. package/dist/server/app-ssr-stream.js +1 -1
  150. package/dist/server/app-visited-response-cache.d.ts +36 -1
  151. package/dist/server/app-visited-response-cache.js +46 -5
  152. package/dist/server/app-worker-stages.d.ts +37 -6
  153. package/dist/server/app-worker-stages.js +81 -9
  154. package/dist/server/artifact-compatibility.d.ts +0 -1
  155. package/dist/server/artifact-compatibility.js +1 -10
  156. package/dist/server/bfcache-identity.d.ts +7 -0
  157. package/dist/server/bfcache-identity.js +10 -1
  158. package/dist/server/cache-proof.d.ts +1 -115
  159. package/dist/server/cache-proof.js +1 -544
  160. package/dist/server/cacheability-manifest.js +1 -2
  161. package/dist/server/cacheability-request.js +13 -8
  162. package/dist/server/dev-origin-check.d.ts +2 -1
  163. package/dist/server/dev-origin-check.js +2 -1
  164. package/dist/server/dev-server.js +6 -4
  165. package/dist/server/headers.d.ts +6 -3
  166. package/dist/server/headers.js +9 -5
  167. package/dist/server/image-optimization.d.ts +5 -0
  168. package/dist/server/image-optimization.js +6 -1
  169. package/dist/server/isr-cache.d.ts +8 -2
  170. package/dist/server/isr-cache.js +30 -2
  171. package/dist/server/metadata-route-response.js +32 -15
  172. package/dist/server/middleware-matcher.js +19 -6
  173. package/dist/server/middleware-runtime.js +6 -2
  174. package/dist/server/multi-stage.d.ts +57 -12
  175. package/dist/server/multi-stage.js +13 -1
  176. package/dist/server/navigation-planner.js +1 -1
  177. package/dist/server/pages-api-route.js +28 -19
  178. package/dist/server/pages-media-type.d.ts +21 -1
  179. package/dist/server/pages-media-type.js +69 -5
  180. package/dist/server/pages-node-compat.d.ts +1 -1
  181. package/dist/server/pages-node-compat.js +54 -27
  182. package/dist/server/pages-page-data.js +2 -1
  183. package/dist/server/pages-page-handler.js +28 -26
  184. package/dist/server/pages-page-response.d.ts +9 -0
  185. package/dist/server/pages-page-response.js +18 -4
  186. package/dist/server/pages-request-pipeline.d.ts +8 -0
  187. package/dist/server/pages-request-pipeline.js +2 -2
  188. package/dist/server/pages-request-stage-entry.js +36 -14
  189. package/dist/server/pages-response-stage-entry.js +9 -3
  190. package/dist/server/pages-router-entry.js +3 -2
  191. package/dist/server/prod-server.d.ts +2 -2
  192. package/dist/server/prod-server.js +47 -9
  193. package/dist/server/request-error-log.d.ts +9 -0
  194. package/dist/server/request-error-log.js +13 -0
  195. package/dist/server/request-pipeline.d.ts +15 -4
  196. package/dist/server/request-pipeline.js +43 -15
  197. package/dist/server/rsc-completion-metadata.js +3 -0
  198. package/dist/server/shared-cache-identity.d.ts +23 -0
  199. package/dist/server/shared-cache-identity.js +36 -0
  200. package/dist/server/static-file-cache.d.ts +9 -0
  201. package/dist/server/static-file-cache.js +13 -2
  202. package/dist/server/worker-stages.d.ts +16 -3
  203. package/dist/server/worker-stages.js +23 -4
  204. package/dist/shims/cache-handler.js +2 -2
  205. package/dist/shims/cache-request-state.d.ts +23 -26
  206. package/dist/shims/cache-request-state.js +22 -57
  207. package/dist/shims/cache-runtime.d.ts +3 -1
  208. package/dist/shims/cache-runtime.js +94 -48
  209. package/dist/shims/cache.d.ts +16 -10
  210. package/dist/shims/cache.js +47 -36
  211. package/dist/shims/cacheability-classification.d.ts +2 -0
  212. package/dist/shims/cdn-cache.d.ts +22 -5
  213. package/dist/shims/client-hook-error.d.ts +2 -0
  214. package/dist/shims/client-hook-error.js +16 -1
  215. package/dist/shims/client-page-root.js +2 -2
  216. package/dist/shims/dynamic.js +9 -6
  217. package/dist/shims/error-boundary.js +2 -2
  218. package/dist/shims/fetch-cache-state.d.ts +5 -1
  219. package/dist/shims/fetch-cache-state.js +1 -3
  220. package/dist/shims/fetch-cache.d.ts +2 -1
  221. package/dist/shims/fetch-cache.js +39 -25
  222. package/dist/shims/form.js +2 -2
  223. package/dist/shims/headers.d.ts +10 -24
  224. package/dist/shims/headers.js +22 -70
  225. package/dist/shims/internal/cache-context-accessor.d.ts +1 -1
  226. package/dist/shims/internal/navigation-untracked.js +1 -1
  227. package/dist/shims/link.js +8 -11
  228. package/dist/shims/metadata.d.ts +23 -21
  229. package/dist/shims/metadata.js +62 -24
  230. package/dist/shims/navigation-server.js +1 -1
  231. package/dist/shims/navigation.d.ts +74 -7
  232. package/dist/shims/navigation.js +184 -31
  233. package/dist/shims/navigation.react-server.js +2 -2
  234. package/dist/shims/request-state-types.d.ts +3 -2
  235. package/dist/shims/slot.d.ts +16 -0
  236. package/dist/shims/slot.js +44 -9
  237. package/dist/shims/unified-request-context.d.ts +7 -1
  238. package/dist/shims/unified-request-context.js +3 -3
  239. package/dist/utils/cache-control-metadata.d.ts +5 -0
  240. package/dist/utils/cache-control-metadata.js +9 -1
  241. package/dist/utils/cache-life-profiles.d.ts +33 -0
  242. package/dist/utils/cache-life-profiles.js +111 -0
  243. package/dist/utils/middleware-request-headers.d.ts +14 -3
  244. package/dist/utils/middleware-request-headers.js +54 -7
  245. package/dist/utils/project.d.ts +2 -2
  246. package/dist/utils/project.js +3 -16
  247. package/dist/utils/regex.d.ts +5 -0
  248. package/dist/utils/regex.js +11 -1
  249. package/dist/utils/text-stream.d.ts +10 -5
  250. package/dist/utils/text-stream.js +6 -6
  251. package/package.json +2 -1
  252. package/dist/build/layout-classification-types.d.ts +0 -60
  253. package/dist/build/layout-classification-types.js +0 -1
  254. package/dist/build/layout-classification.d.ts +0 -62
  255. package/dist/build/layout-classification.js +0 -98
  256. package/dist/build/route-classification-injector.d.ts +0 -33
  257. package/dist/build/route-classification-injector.js +0 -59
  258. package/dist/build/route-classification-manifest.d.ts +0 -54
  259. package/dist/build/route-classification-manifest.js +0 -143
  260. package/dist/server/app-browser-client-reuse-manifest.d.ts +0 -11
  261. package/dist/server/app-browser-client-reuse-manifest.js +0 -101
  262. package/dist/server/app-layout-param-observation.d.ts +0 -42
  263. package/dist/server/app-layout-param-observation.js +0 -168
  264. package/dist/server/client-reuse-manifest.d.ts +0 -103
  265. package/dist/server/client-reuse-manifest.js +0 -209
  266. package/dist/server/skip-cache-proof.d.ts +0 -60
  267. package/dist/server/skip-cache-proof.js +0 -168
  268. package/dist/server/static-layout-client-reuse-proof.d.ts +0 -14
  269. package/dist/server/static-layout-client-reuse-proof.js +0 -33
  270. package/dist/utils/sorted-array.d.ts +0 -8
  271. package/dist/utils/sorted-array.js +0 -20
@@ -32,14 +32,15 @@ const CACHE_METADATA_EXPORT = {
32
32
  const CTX_EXPORTS_DEFAULT_DATE = "2025-11-17";
33
33
  function validateCloudflarePlatformSetup(context, cloudflare) {
34
34
  if (cloudflare.name !== void 0) validateWorkerName(cloudflare.name);
35
+ if (cloudflare.legacyWrangler && cloudflare.ignoreWranglerConfig) throw new Error("--ignore-wrangler-config cannot be combined with --legacy-wrangler-cloudflare-init.");
35
36
  if (!cloudflare.legacyWrangler) {
36
- const existingWrangler = [
37
+ const existingWrangler = cloudflare.ignoreWranglerConfig ? void 0 : [
37
38
  "wrangler.toml",
38
39
  "wrangler.json",
39
40
  "wrangler.jsonc",
40
41
  RESPONSE_STORE_WRANGLER_CONFIG
41
42
  ].find((name) => fs.existsSync(path.join(context.root, name)));
42
- if (existingWrangler) throw new Error(`Cloudflare init cannot replace an existing Wrangler config (${existingWrangler}). Migrate its bindings to cloudflare.config.ts first, or use --legacy-wrangler-cloudflare-init to keep the Wrangler setup.`);
43
+ if (existingWrangler) throw new Error(`Cloudflare init cannot replace an existing Wrangler config (${existingWrangler}). Migrate its bindings to cloudflare.config.ts first, use --ignore-wrangler-config if it belongs to another Worker, or use --legacy-wrangler-cloudflare-init to keep the Wrangler setup.`);
43
44
  const typedConfigPath = path.join(context.root, "cloudflare.config.ts");
44
45
  if (cloudflare.cdnCache === "static-assets" && fs.existsSync(typedConfigPath)) throw new Error("Static Assets cache setup for an existing cloudflare.config.ts must be configured manually. Keep its assets binding aligned with staticAssetsAdapter({ binding }) and include \"/_vinext/static-cache/*\" in assets.runWorkerFirst to protect private cache files.");
45
46
  if (cloudflare.cdnCache === "response-store" && (cloudflare.responseStoreMode ?? "service-binding") === "service-binding" && fs.existsSync(typedConfigPath) && !fs.readFileSync(typedConfigPath, "utf-8").includes("export const responseStoreServiceBinding")) throw new Error("The existing cloudflare.config.ts must export responseStoreServiceBinding for the Response Store auxiliary Worker. Configure it before rerunning init.");
@@ -47,7 +48,6 @@ function validateCloudflarePlatformSetup(context, cloudflare) {
47
48
  if (context.existingViteConfigPath) {
48
49
  const updatedConfig = updateViteConfigForCloudflare(context.existingViteConfigPath, fs.readFileSync(context.existingViteConfigPath, "utf-8"), {
49
50
  isAppRouter: context.isAppRouter,
50
- nativeModulesToStub: detectProject(context.root).nativeModulesToStub,
51
51
  cache: cloudflare
52
52
  });
53
53
  if (context.hasCssModules) updateViteConfigForCssModules(context.existingViteConfigPath, updatedConfig);
@@ -56,7 +56,6 @@ function validateCloudflarePlatformSetup(context, cloudflare) {
56
56
  }
57
57
  const tomlPath = path.join(context.root, "wrangler.toml");
58
58
  if (fs.existsSync(tomlPath)) throw new Error("wrangler.toml is not supported by vinext init. Convert it to wrangler.jsonc and rerun.");
59
- const projectInfo = detectProject(context.root);
60
59
  const wranglerPath = ["wrangler.jsonc", "wrangler.json"].map((fileName) => path.join(context.root, fileName)).find((candidate) => fs.existsSync(candidate));
61
60
  const wranglerCode = wranglerPath ? fs.readFileSync(wranglerPath, "utf-8") : void 0;
62
61
  if (!wranglerCode && cloudflare.cdnCache === "response-store" && (cloudflare.responseStoreMode ?? "service-binding") === "service-binding" && fs.existsSync(path.join(context.root, RESPONSE_STORE_WRANGLER_CONFIG))) readResponseStoreServiceName(context.root, {});
@@ -71,7 +70,6 @@ function validateCloudflarePlatformSetup(context, cloudflare) {
71
70
  if (context.existingViteConfigPath) {
72
71
  const updatedConfig = updateViteConfigForCloudflare(context.existingViteConfigPath, fs.readFileSync(context.existingViteConfigPath, "utf-8"), {
73
72
  isAppRouter: context.isAppRouter,
74
- nativeModulesToStub: projectInfo.nativeModulesToStub,
75
73
  cache: cloudflare,
76
74
  assetsBinding,
77
75
  assetsDirectory,
@@ -101,7 +99,6 @@ function setupCloudflarePlatform(context, cloudflare) {
101
99
  const currentConfig = fs.readFileSync(context.existingViteConfigPath, "utf-8");
102
100
  let updatedConfig = updateViteConfigForCloudflare(context.existingViteConfigPath, currentConfig, {
103
101
  isAppRouter: context.isAppRouter,
104
- nativeModulesToStub: projectInfo.nativeModulesToStub,
105
102
  cache: cloudflare,
106
103
  assetsBinding,
107
104
  assetsDirectory,
@@ -118,7 +115,7 @@ function setupCloudflarePlatform(context, cloudflare) {
118
115
  generatedViteConfig = true;
119
116
  } else skippedViteConfig = true;
120
117
  } else {
121
- const configContent = context.isAppRouter ? generateAppRouterViteConfig(projectInfo, cloudflare, imagesBinding, versionMetadataBinding, false, assetsBinding, assetsDirectory, context.hasCssModules) : generatePagesRouterViteConfig(projectInfo, cloudflare, imagesBinding, versionMetadataBinding, false, context.hasCssModules, assetsBinding, assetsDirectory);
118
+ const configContent = context.isAppRouter ? generateAppRouterViteConfig(projectInfo, cloudflare, imagesBinding, versionMetadataBinding, false, assetsBinding, assetsDirectory, context.hasCssModules) : generatePagesRouterViteConfig(cloudflare, imagesBinding, versionMetadataBinding, false, context.hasCssModules, assetsBinding, assetsDirectory);
122
119
  fs.writeFileSync(path.join(context.root, "vite.config.ts"), configContent, "utf-8");
123
120
  generatedViteConfig = true;
124
121
  }
@@ -178,7 +175,6 @@ function setupCfPlatform(context, cloudflare) {
178
175
  const current = fs.readFileSync(context.existingViteConfigPath, "utf-8");
179
176
  let updated = updateViteConfigForCloudflare(context.existingViteConfigPath, current, {
180
177
  isAppRouter: context.isAppRouter,
181
- nativeModulesToStub: projectInfo.nativeModulesToStub,
182
178
  cache: cloudflare
183
179
  });
184
180
  if (context.hasCssModules) {
@@ -191,7 +187,7 @@ function setupCfPlatform(context, cloudflare) {
191
187
  generatedViteConfig = true;
192
188
  }
193
189
  } else {
194
- const viteConfig = context.isAppRouter ? generateAppRouterViteConfig(projectInfo, cloudflare, "IMAGES", DEFAULT_VERSION_METADATA_BINDING, serviceBinding, "ASSETS", "dist/client", context.hasCssModules) : generatePagesRouterViteConfig(projectInfo, cloudflare, "IMAGES", DEFAULT_VERSION_METADATA_BINDING, serviceBinding, context.hasCssModules);
190
+ const viteConfig = context.isAppRouter ? generateAppRouterViteConfig(projectInfo, cloudflare, "IMAGES", DEFAULT_VERSION_METADATA_BINDING, serviceBinding, "ASSETS", "dist/client", context.hasCssModules) : generatePagesRouterViteConfig(cloudflare, "IMAGES", DEFAULT_VERSION_METADATA_BINDING, serviceBinding, context.hasCssModules);
195
191
  fs.writeFileSync(path.join(context.root, "vite.config.ts"), viteConfig, "utf-8");
196
192
  generatedViteConfig = true;
197
193
  }
@@ -849,7 +845,7 @@ function generateAppRouterViteConfig(info, options = DEFAULT_CLOUDFLARE_INIT_OPT
849
845
  ...cacheImports(options),
850
846
  ...hasCssModules ? ["import { createHash } from \"node:crypto\";", "import { patchCssModules } from \"vite-css-modules\";"] : []
851
847
  ];
852
- if (hasCssModules || info?.nativeModulesToStub && info.nativeModulesToStub.length > 0) imports.push(`import path from "node:path";`);
848
+ if (hasCssModules) imports.push(`import path from "node:path";`);
853
849
  const plugins = [];
854
850
  if (hasCssModules) plugins.push(" patchCssModules({ exportMode: \"default\" }),");
855
851
  if (info?.hasMDX) plugins.push(` // vinext auto-injects @mdx-js/rollup with plugins from next.config`);
@@ -860,21 +856,17 @@ function generateAppRouterViteConfig(info, options = DEFAULT_CLOUDFLARE_INIT_OPT
860
856
  childEnvironments: ["ssr"],
861
857
  },
862
858
  }),`);
863
- let resolveBlock = "";
864
- const aliases = [];
865
- if (info?.nativeModulesToStub && info.nativeModulesToStub.length > 0) for (const mod of info.nativeModulesToStub) aliases.push(` "${mod}": path.resolve(__dirname, "empty-stub.js"),`);
866
- if (aliases.length > 0) resolveBlock = `\n resolve: {\n alias: {\n${aliases.join("\n")}\n },\n },`;
867
859
  return `${imports.join("\n")}
868
860
 
869
861
  export default defineConfig({
870
862
  plugins: [
871
863
  ${plugins.join("\n")}
872
- ],${resolveBlock}${hasCssModules ? cssModulesConfigSource() : ""}
864
+ ],${hasCssModules ? cssModulesConfigSource() : ""}
873
865
  });
874
866
  `;
875
867
  }
876
868
  /** Generate vite.config.ts for Pages Router */
877
- function generatePagesRouterViteConfig(info, options = DEFAULT_CLOUDFLARE_INIT_OPTIONS, imagesBinding = "IMAGES", versionMetadataBinding = DEFAULT_VERSION_METADATA_BINDING, serviceBinding = false, hasCssModules = false, assetsBinding = "ASSETS", assetsDirectory = "dist/client") {
869
+ function generatePagesRouterViteConfig(options = DEFAULT_CLOUDFLARE_INIT_OPTIONS, imagesBinding = "IMAGES", versionMetadataBinding = DEFAULT_VERSION_METADATA_BINDING, serviceBinding = false, hasCssModules = false, assetsBinding = "ASSETS", assetsDirectory = "dist/client") {
878
870
  const legacyStaticAssets = options.legacyWrangler && options.cdnCache === "static-assets";
879
871
  const imports = [
880
872
  `import { defineConfig } from "vite";`,
@@ -884,18 +876,14 @@ function generatePagesRouterViteConfig(info, options = DEFAULT_CLOUDFLARE_INIT_O
884
876
  ...cacheImports(options),
885
877
  ...hasCssModules ? ["import { createHash } from \"node:crypto\";", "import { patchCssModules } from \"vite-css-modules\";"] : []
886
878
  ];
887
- if (hasCssModules || info?.nativeModulesToStub && info.nativeModulesToStub.length > 0) imports.push(`import path from "node:path";`);
888
- let resolveBlock = "";
889
- const aliases = [];
890
- if (info?.nativeModulesToStub && info.nativeModulesToStub.length > 0) for (const mod of info.nativeModulesToStub) aliases.push(` "${mod}": path.resolve(__dirname, "empty-stub.js"),`);
891
- if (aliases.length > 0) resolveBlock = `\n resolve: {\n alias: {\n${aliases.join("\n")}\n },\n },`;
879
+ if (hasCssModules) imports.push(`import path from "node:path";`);
892
880
  return `${imports.join("\n")}
893
881
 
894
882
  export default defineConfig({
895
883
  ${legacyStaticAssets ? ` environments: { client: { build: { outDir: ${JSON.stringify(assetsDirectory)} } }, ssr: { build: { outDir: "dist/server" } } },\n` : ""} plugins: [
896
884
  ${hasCssModules ? " patchCssModules({ exportMode: \"default\" }),\n" : ""} ${vinextExpression(options, "vinext", "imagesOptimizer", imagesBinding, versionMetadataBinding, "responseStoreAdapter", assetsBinding, assetsDirectory).replace(/\n/g, "\n ")},
897
885
  cloudflare(${legacyStaticAssets ? "{ viteEnvironment: { name: \"ssr\" } }" : serviceBinding ? "{ auxiliaryWorkers: [{ config: responseStoreServiceBinding }] }" : ""}),
898
- ],${resolveBlock}${hasCssModules ? cssModulesConfigSource() : ""}
886
+ ],${hasCssModules ? cssModulesConfigSource() : ""}
899
887
  });
900
888
  `;
901
889
  }
@@ -1447,27 +1435,6 @@ function updateViteConfigForCssModules(filePath, code) {
1447
1435
  preservedExistingGenerateScopedName: Boolean(existingName)
1448
1436
  };
1449
1437
  }
1450
- function ensureNativeAliases(output, config, modules, pathBinding, code) {
1451
- if (modules.length === 0) return;
1452
- const resolve = findProperty(config, "resolve");
1453
- if (resolve && resolve.value.type !== "ObjectExpression") throw new Error("The Vite config's resolve option must be an object for vinext init to update it.");
1454
- const resolveObject = resolve?.value;
1455
- const alias = resolveObject ? findProperty(resolveObject, "alias") : void 0;
1456
- if (alias && alias.value.type !== "ObjectExpression") throw new Error("The Vite config's resolve.alias option must be an object for vinext init to update it.");
1457
- const aliasLines = modules.map((moduleName) => ` ${JSON.stringify(moduleName)}: ${pathBinding}.resolve(__dirname, "empty-stub.js"),`);
1458
- if (!resolveObject) {
1459
- insertObjectProperty(output, config, ` resolve: {\n alias: {\n${aliasLines.join("\n")}\n },\n },`, code);
1460
- return;
1461
- }
1462
- if (!alias) {
1463
- insertObjectProperty(output, resolveObject, ` alias: {\n${aliasLines.join("\n")}\n },`, code);
1464
- return;
1465
- }
1466
- const aliasObject = alias.value;
1467
- const existingAliases = new Set(aliasObject.properties.flatMap((property) => property.type === "Property" && propertyName(property) ? [propertyName(property)] : []));
1468
- const missingLines = aliasLines.filter((_, index) => !existingAliases.has(modules[index]));
1469
- if (missingLines.length > 0) insertObjectProperty(output, aliasObject, missingLines.join("\n"), code);
1470
- }
1471
1438
  function updateViteConfigForCloudflare(filePath, code, options) {
1472
1439
  const program = parseViteConfig(filePath, code);
1473
1440
  const cacheOptions = options.cache ?? DEFAULT_CLOUDFLARE_INIT_OPTIONS;
@@ -1604,11 +1571,6 @@ function updateViteConfigForCloudflare(filePath, code, options) {
1604
1571
  if (cacheOptions.cdnCache === "static-assets" || cacheOptions.prerender) ensureVinextPrerenderOptions(output, config, vinextBinding, cacheOptions.cdnCache === "static-assets" ? options.assetsDirectory ?? "dist/client" : void 0, code);
1605
1572
  }
1606
1573
  }
1607
- if (options.nativeModulesToStub.length > 0) {
1608
- const pathLocal = (commonJs ? findRequiredBinding(program, "node:path", "default") : program.body.filter((statement) => statement.type === "ImportDeclaration").find((statement) => statement.source.value === "node:path")?.specifiers.find((specifier) => specifier.type === "ImportDefaultSpecifier")?.local.name) ?? allocateBinding(bindings, "path");
1609
- const pathBinding = commonJs ? ensureDefaultRequire(program, output, "node:path", pathLocal) : ensureDefaultImport(program, output, "node:path", pathLocal);
1610
- ensureNativeAliases(output, config, options.nativeModulesToStub, pathBinding, code);
1611
- }
1612
1574
  return formatInlineConfig(filePath, output.toString(), code);
1613
1575
  }
1614
1576
  function usesCommonJsViteConfig(filePath, code) {
@@ -12,6 +12,8 @@ export type CloudflareInitOptions = {
12
12
  responseStoreMode?: InitResponseStoreMode;
13
13
  warmCdnCache?: boolean;
14
14
  legacyWrangler?: boolean;
15
+ /** Proceed even though the root Wrangler config belongs to another Worker. */
16
+ ignoreWranglerConfig?: boolean;
15
17
  prerender?: boolean;
16
18
  /** Worker name for generated config, instead of one derived from package.json. */
17
19
  name?: string;
@@ -137,11 +137,14 @@ async function resolveInitPlatform(args, options = {}) {
137
137
  }
138
138
  async function resolveInitOptions(args, options = {}) {
139
139
  const legacyWrangler = parseBooleanArg(args, "--legacy-wrangler-cloudflare-init", void 0, "--legacy-wrangler-cloudflare-init expects true or false when using the \"--legacy-wrangler-cloudflare-init=value\" form.");
140
+ const ignoreWranglerConfig = parseBooleanArg(args, "--ignore-wrangler-config", void 0, "--ignore-wrangler-config expects true or false when using the \"--ignore-wrangler-config=value\" form.");
140
141
  const name = parseNameArg(args);
141
142
  const platform = legacyWrangler && !parsePlatformArg(args) ? "cloudflare" : await resolveInitPlatform(args, options);
142
143
  const platformOptions = await INIT_PLATFORMS[platform].options(args, options);
143
144
  const explicitWarmCdnCache = parseWarmCdnCacheArg(args);
144
145
  if (legacyWrangler && platform !== "cloudflare") throw new Error("--legacy-wrangler-cloudflare-init requires --platform=cloudflare.");
146
+ if (ignoreWranglerConfig && platform !== "cloudflare") throw new Error("--ignore-wrangler-config requires --platform=cloudflare.");
147
+ if (ignoreWranglerConfig && legacyWrangler) throw new Error("--ignore-wrangler-config cannot be combined with --legacy-wrangler-cloudflare-init.");
145
148
  if (name && platform !== "cloudflare") throw new Error("--name requires --platform=cloudflare.");
146
149
  const explicitPrerender = parsePrerenderArg(args);
147
150
  if (platform === "cloudflare" && platformOptions?.cdnCache === "static-assets" && explicitPrerender === false) throw new Error("--no-prerender cannot be used with --cdn-cache=static-assets, which requires build-time prerendering.");
@@ -158,6 +161,7 @@ async function resolveInitOptions(args, options = {}) {
158
161
  ...platformOptions,
159
162
  warmCdnCache,
160
163
  ...legacyWrangler ? { legacyWrangler } : {},
164
+ ...ignoreWranglerConfig ? { ignoreWranglerConfig } : {},
161
165
  ...prerender ? { prerender: true } : {},
162
166
  ...name ? { name } : {}
163
167
  } : void 0
@@ -1,5 +1,5 @@
1
1
  import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
- import { escapeRegExp } from "../utils/regex.js";
2
+ import { escapeRegExp, exactRegExpLiteral } from "../utils/regex.js";
3
3
  import { DYNAMIC_IMPORT_PRESCAN, SCRIPT_MODULE_ID_RE, parseProgram, scriptParserLanguage, walkAst } from "./ast-utils.js";
4
4
  import { isUnknownRecord } from "../utils/record.js";
5
5
  import { magicStringTransformResult } from "./transform-result.js";
@@ -219,7 +219,11 @@ function aliasesMayMatch(aliases, requestPattern) {
219
219
  const requestPrefix = requestPattern.slice(0, requestPattern.indexOf("*"));
220
220
  return aliases.some((alias) => {
221
221
  const { find } = alias;
222
- if (find instanceof RegExp) return !isViteInternalAlias(alias);
222
+ if (find instanceof RegExp) {
223
+ const literal = exactRegExpLiteral(find);
224
+ if (literal !== null) return matchesTemplatePattern(requestPattern, literal);
225
+ return !isViteInternalAlias(alias);
226
+ }
223
227
  if (matchesTemplatePattern(requestPattern, find)) return true;
224
228
  const aliasPrefix = `${find}/`;
225
229
  return requestPrefix.startsWith(aliasPrefix) || aliasPrefix.startsWith(requestPrefix);
@@ -0,0 +1,12 @@
1
+ import { NextIntlCatalogLoader } from "../config/next-config.js";
2
+ import { Plugin } from "vite";
3
+ //#region src/plugins/next-intl-catalog.d.ts
4
+ /**
5
+ * Runs next-intl's catalog loader on its `experimental.messages` catalogs, as
6
+ * Next.js does through the webpack/Turbopack rule `createNextIntlPlugin` adds.
7
+ * With `precompile: true` the plugin also aliases use-intl's formatter to one
8
+ * that only formats precompiled messages, so raw catalogs would render their
9
+ * ICU placeholders literally.
10
+ */
11
+ export declare function createNextIntlCatalogPlugin(getRoot: () => string, getCatalogLoader: () => NextIntlCatalogLoader | null): Plugin;
12
+ //#endregion
@@ -0,0 +1,85 @@
1
+ import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
+ import { escapeRegExp } from "../utils/regex.js";
3
+ import { canonicalizeFilePath, stripViteModuleQuery } from "../utils/path.js";
4
+ import { createRequire } from "node:module";
5
+ import fsp from "node:fs/promises";
6
+ import { pathToFileURL } from "node:url";
7
+ //#region src/plugins/next-intl-catalog.ts
8
+ const SPECIAL_QUERY_RE = /[?&](?:worker|sharedworker|raw|url)\b/;
9
+ /**
10
+ * Runs next-intl's catalog loader on its `experimental.messages` catalogs, as
11
+ * Next.js does through the webpack/Turbopack rule `createNextIntlPlugin` adds.
12
+ * With `precompile: true` the plugin also aliases use-intl's formatter to one
13
+ * that only formats precompiled messages, so raw catalogs would render their
14
+ * ICU placeholders literally.
15
+ */
16
+ function createNextIntlCatalogPlugin(getRoot, getCatalogLoader) {
17
+ return {
18
+ name: "vinext:next-intl-catalog",
19
+ enforce: "pre",
20
+ applyToEnvironment() {
21
+ const catalogLoader = getCatalogLoader();
22
+ if (!catalogLoader) return false;
23
+ return createCatalogLoadPlugin(getRoot(), catalogLoader);
24
+ }
25
+ };
26
+ }
27
+ function createCatalogLoadPlugin(root, catalogLoader) {
28
+ const catalogDirs = [...new Set(catalogLoader.include.flatMap((dir) => [toSlash(dir), canonicalizeFilePath(dir)]))].map((dir) => `${escapeRegExp(dir)}/`);
29
+ let loaderPromise;
30
+ return {
31
+ name: "vinext:next-intl-catalog",
32
+ load: {
33
+ filter: { id: new RegExp(`^(?:${catalogDirs.join("|")})`) },
34
+ async handler(id) {
35
+ if (SPECIAL_QUERY_RE.test(id)) return null;
36
+ const file = stripViteModuleQuery(id);
37
+ catalogLoader.test.lastIndex = 0;
38
+ if (!catalogLoader.test.test(file)) return null;
39
+ loaderPromise ??= importCatalogLoader(root, catalogLoader.options);
40
+ return {
41
+ code: await runLoader(await loaderPromise, await fsp.readFile(file, "utf8"), {
42
+ resourcePath: file,
43
+ rootContext: root,
44
+ options: catalogLoader.options
45
+ }),
46
+ moduleType: "js"
47
+ };
48
+ }
49
+ }
50
+ };
51
+ }
52
+ async function importCatalogLoader(root, options) {
53
+ const loaderPath = createRequire(path.join(root, "package.json")).resolve("next-intl/extractor/catalogLoader");
54
+ const url = pathToFileURL(loaderPath);
55
+ url.searchParams.set("vinext-config", JSON.stringify([root, options]));
56
+ const loaderModule = await import(url.href);
57
+ if (typeof loaderModule.default !== "function") throw new Error(`[vinext] ${loaderPath} does not export a webpack loader`);
58
+ return loaderModule.default;
59
+ }
60
+ function runLoader(loader, source, context) {
61
+ return new Promise((resolve, reject) => {
62
+ let isAsync = false;
63
+ const callback = (error, result) => {
64
+ if (error) reject(error);
65
+ else resolve(String(result));
66
+ };
67
+ try {
68
+ const result = loader.call({
69
+ resourcePath: context.resourcePath,
70
+ rootContext: context.rootContext,
71
+ getOptions: () => context.options,
72
+ async: () => {
73
+ isAsync = true;
74
+ return callback;
75
+ },
76
+ callback
77
+ }, source);
78
+ if (!isAsync) callback(null, result);
79
+ } catch (error) {
80
+ reject(error);
81
+ }
82
+ });
83
+ }
84
+ //#endregion
85
+ export { createNextIntlCatalogPlugin };
@@ -5,6 +5,7 @@ type PagesNodeExternalsOptions = {
5
5
  getPagesDir: () => string | null;
6
6
  getAliases: () => Readonly<Record<string, string>>;
7
7
  getTsconfigAliases: () => Readonly<Record<string, string>>;
8
+ getTsconfigExactAliases: () => Readonly<Record<string, string>>;
8
9
  getBundledPackages: () => ReadonlySet<string>;
9
10
  isEnabled: () => boolean;
10
11
  };
@@ -141,7 +141,7 @@ function createPagesNodeExternalsPlugin(options) {
141
141
  }
142
142
  const packageName = packageNameFromSpecifier(id);
143
143
  if (!packageName || FRAMEWORK_PACKAGES.has(packageName) || id === "next" || id.startsWith("next/") || id.startsWith("vinext/") || id.startsWith("@vinext/") || options.getBundledPackages().has(packageName)) return null;
144
- if (matchesAlias(id, options.getAliases()) || matchesAlias(id, options.getTsconfigAliases())) {
144
+ if (matchesAlias(id, options.getAliases()) || matchesAlias(id, options.getTsconfigAliases()) || Object.hasOwn(options.getTsconfigExactAliases(), id)) {
145
145
  const aliased = await this.resolve(id, importer, { skipSelf: true });
146
146
  if (aliased && !aliased.external) {
147
147
  const aliasedFile = canonicalFile(aliased.id);
@@ -89,7 +89,8 @@ function isReferenceIdentifier(node, parent) {
89
89
  if (parent.type === "ImportSpecifier" || parent.type === "ImportDefaultSpecifier" || parent.type === "ImportNamespaceSpecifier") return false;
90
90
  if (parent.type === "ExportSpecifier") return false;
91
91
  if (parent.type === "MemberExpression" && parent.property === node && !parent.computed) return false;
92
- if ((parent.type === "Property" || parent.type === "MethodDefinition") && parent.key === node && !parent.computed && !(parent.type === "Property" && parent.shorthand)) return false;
92
+ if ((parent.type === "Property" || parent.type === "MethodDefinition" || parent.type === "PropertyDefinition" || parent.type === "AccessorProperty" || parent.type === "ImportAttribute") && parent.key === node && !parent.computed && !(parent.type === "Property" && parent.shorthand)) return false;
93
+ if (parent.type === "MetaProperty") return false;
93
94
  if ((parent.type === "LabeledStatement" || parent.type === "BreakStatement" || parent.type === "ContinueStatement") && parent.label === node) return false;
94
95
  const parameters = "params" in parent ? parent.params : void 0;
95
96
  if (Array.isArray(parameters) && parameters.includes(node)) return false;
@@ -28,6 +28,6 @@ export type UseCacheCallableApi = {
28
28
  transformWorkerModule(code: string, id: string, createReference: BrowserTransformOptions["createReference"]): Promise<BrowserTransformOutput["output"] | undefined>;
29
29
  };
30
30
  declare const PLUGIN_NAME = "vinext:server-function-directives";
31
- export declare function createUseCacheCallablePlugin(options: Options): Promise<Plugin<UseCacheCallableApi>>;
31
+ export declare function createUseCacheCallablePlugin(options: Options): Promise<[Plugin<UseCacheCallableApi>, Plugin]>;
32
32
  //#endregion
33
33
  export { PLUGIN_NAME as USE_CACHE_PLUGIN_NAME };
@@ -9,6 +9,7 @@ import { createHmac } from "node:crypto";
9
9
  //#region src/plugins/use-cache-callable.ts
10
10
  const PLUGIN_NAME = "vinext:server-function-directives";
11
11
  const SOURCE_MODULE_ID_RE = /\.(?:tsx?|jsx?|mjs)(?:\?.*)?$/;
12
+ const NODE_MODULES_SOURCE_MODULE_ID_RE = /[\\/]node_modules[\\/].*\.(?:tsx?|jsx?|mjs)(?:\?.*)?$/;
12
13
  const RESOLVED_VIRTUAL_MODULE_ID_RE = new RegExp(`^${String.fromCharCode(0)}`);
13
14
  const USE_CACHE_DIRECTIVE = /^use cache(?:: ([^\s].*))?$/;
14
15
  const USE_CACHE_DIRECTIVE_CANDIDATE = /^use cache.*$/;
@@ -40,6 +41,30 @@ function getArgumentCount(meta) {
40
41
  if (node?.type !== "FunctionDeclaration" && node?.type !== "FunctionExpression" && node?.type !== "ArrowFunctionExpression") return;
41
42
  return node.params.at(-1)?.type === "RestElement" ? void 0 : node.params.length;
42
43
  }
44
+ /**
45
+ * `export { fn }` carries no value node, so find the exported binding's
46
+ * `const` initializer, which records the function's parameters. Other
47
+ * bindings, function declarations included, can be reassigned before the
48
+ * module finishes evaluating, so their arity stays unknown.
49
+ */
50
+ function getSpecifierExportValueNodes(ast) {
51
+ const locals = /* @__PURE__ */ new Map();
52
+ for (const statement of ast.body) {
53
+ const declaration = statement.type === "ExportNamedDeclaration" ? statement.declaration : statement;
54
+ if (declaration?.type !== "VariableDeclaration" || declaration.kind !== "const") continue;
55
+ for (const declarator of declaration.declarations) if (declarator.id.type === "Identifier" && declarator.init) locals.set(declarator.id.name, declarator.init);
56
+ }
57
+ const values = /* @__PURE__ */ new Map();
58
+ for (const statement of ast.body) {
59
+ if (statement.type !== "ExportNamedDeclaration" || statement.declaration || statement.source) continue;
60
+ for (const specifier of statement.specifiers) {
61
+ if (specifier.local.type !== "Identifier" || specifier.exported.type !== "Identifier") continue;
62
+ const value = locals.get(specifier.local.name);
63
+ if (value) values.set(specifier.exported.name, value);
64
+ }
65
+ }
66
+ return values;
67
+ }
43
68
  function acceptsSecondArgument(meta) {
44
69
  const node = meta.valueNode;
45
70
  if (node?.type !== "FunctionDeclaration" && node?.type !== "FunctionExpression" && node?.type !== "ArrowFunctionExpression") return true;
@@ -150,7 +175,103 @@ async function createUseCacheCallablePlugin(options) {
150
175
  secureExportName
151
176
  };
152
177
  }
153
- return {
178
+ async function transformDirectives(code, id) {
179
+ const secret = referenceSecret;
180
+ if (!manager || !secret) return;
181
+ if (!code.includes("use cache")) {
182
+ manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
183
+ return;
184
+ }
185
+ const { ast, moduleDirective, useServerBoundary, reference, secureExportName } = await analyzeModule(manager, secret, code, id);
186
+ if (!(this.environment.name === "rsc")) {
187
+ if (useServerBoundary) {
188
+ manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
189
+ return;
190
+ }
191
+ const result = transformBrowserModule(transforms, code, ast, id, moduleDirective, {
192
+ environmentName: this.environment.name,
193
+ reference,
194
+ secureExportName,
195
+ createReference: (referenceId, name) => `$$ReactClient.createServerReference(${JSON.stringify(referenceId)},$$ReactClient.callServer,undefined,${this.environment.mode === "dev" ? "$$ReactClient.findSourceMapURL" : "undefined"},${JSON.stringify(name)})`
196
+ });
197
+ if (!result) {
198
+ manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
199
+ return;
200
+ }
201
+ manager.serverReferences.replaceClaim(PLUGIN_NAME, id, {
202
+ ...reference,
203
+ exportNames: result.referenceNames
204
+ });
205
+ const runtimeEnvironment = this.environment.name === "client" ? "browser" : "ssr";
206
+ result.output.prepend(`import * as $$ReactClient from "@vitejs/plugin-rsc/react/${runtimeEnvironment}";\n`);
207
+ return magicStringTransformResult(result.output, {
208
+ hires: "boundary",
209
+ source: id
210
+ });
211
+ }
212
+ const secureExports = /* @__PURE__ */ new Set();
213
+ const wrap = (value, name, directiveMatch, meta) => {
214
+ const variant = directiveMatch[1] ?? "";
215
+ const secureName = secureExportName(name);
216
+ secureExports.add(secureName);
217
+ const wrapperOptions = {
218
+ ...getCacheWrapperOptions(meta),
219
+ serverReferenceId: `${reference.referenceKey}#${secureName}`
220
+ };
221
+ return `$$cacheRuntime.registerCachedFunction(${value}, ${JSON.stringify(`${id}:${name}`)}, ${JSON.stringify(variant)}, ${JSON.stringify(wrapperOptions)})`;
222
+ };
223
+ let needsReactServer = false;
224
+ const runtime = (value, name, directiveMatch, meta) => {
225
+ const cached = wrap(value, name, directiveMatch, meta);
226
+ const secureName = secureExportName(name);
227
+ needsReactServer = true;
228
+ return `(${secureName} = $$VinextReactServer.registerServerReference(${cached}, ${JSON.stringify(reference.referenceKey)}, ${JSON.stringify(secureName)}))`;
229
+ };
230
+ const specifierValueNodes = moduleDirective ? getSpecifierExportValueNodes(ast) : void 0;
231
+ const result = moduleDirective ? transforms.transformWrapExport(code, ast, {
232
+ filter: (name, meta) => {
233
+ if (hasFunctionDirective(meta, "use server") || !shouldTransformModuleExport(name, id, meta)) return false;
234
+ validateModuleExport(transforms, meta);
235
+ return true;
236
+ },
237
+ runtime: (value, name, meta) => runtime(value, name, matchUseCacheDirective(moduleDirective), {
238
+ ...meta,
239
+ valueNode: meta.valueNode ?? specifierValueNodes?.get(name)
240
+ })
241
+ }) : transforms.transformHoistInlineDirective(code, ast, {
242
+ directive: USE_CACHE_DIRECTIVE_CANDIDATE,
243
+ rejectNonAsyncFunction: true,
244
+ hoistRuntime: true,
245
+ noExport: true,
246
+ runtime: (value, name, meta) => runtime(value, name, matchUseCacheDirective(meta.directiveMatch[0]), meta),
247
+ encode: (value, name) => {
248
+ if (name === void 0) throw new Error("vinext: inline \"use cache\" functions require @vitejs/plugin-rsc 0.5.37 or newer.");
249
+ const referenceId = `${reference.referenceKey}#${secureExportName(name)}`;
250
+ return `$$cacheRuntime.encryptCacheCaptures(${JSON.stringify(referenceId)}, ${value})`;
251
+ },
252
+ decode: (value) => value
253
+ });
254
+ if (!result.output.hasChanged()) {
255
+ manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
256
+ return;
257
+ }
258
+ manager.serverReferences.replaceClaim(PLUGIN_NAME, id, {
259
+ ...reference,
260
+ exportNames: [...secureExports]
261
+ });
262
+ const importPosition = ast.body.find((node) => !("directive" in node))?.start ?? code.length;
263
+ result.output.prependLeft(importPosition, [
264
+ `import * as $$cacheRuntime from ${JSON.stringify(options.cacheRuntime)};`,
265
+ needsReactServer && `import * as $$VinextReactServer from "@vitejs/plugin-rsc/react/rsc/server";`,
266
+ secureExports.size > 0 && `let ${[...secureExports].join(",")};`
267
+ ].filter(Boolean).join("\n") + "\n");
268
+ if (secureExports.size > 0) result.output.append(`\nexport { ${[...secureExports].join(",")} };\n`);
269
+ return magicStringTransformResult(result.output, {
270
+ hires: "boundary",
271
+ source: id
272
+ });
273
+ }
274
+ return [{
154
275
  name: PLUGIN_NAME,
155
276
  api: { async transformWorkerModule(code, id, createReference) {
156
277
  if (!code.includes("use cache")) return;
@@ -192,100 +313,21 @@ async function createUseCacheCallablePlugin(options) {
192
313
  include: SOURCE_MODULE_ID_RE,
193
314
  exclude: [NODE_MODULES_PATH_RE, RESOLVED_VIRTUAL_MODULE_ID_RE]
194
315
  } },
195
- async handler(code, id) {
196
- const secret = referenceSecret;
197
- if (!manager || !secret) return;
198
- if (!code.includes("use cache")) {
199
- manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
200
- return;
201
- }
202
- const { ast, moduleDirective, useServerBoundary, reference, secureExportName } = await analyzeModule(manager, secret, code, id);
203
- if (!(this.environment.name === "rsc")) {
204
- if (useServerBoundary) {
205
- manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
206
- return;
207
- }
208
- const result = transformBrowserModule(transforms, code, ast, id, moduleDirective, {
209
- environmentName: this.environment.name,
210
- reference,
211
- secureExportName,
212
- createReference: (referenceId, name) => `$$ReactClient.createServerReference(${JSON.stringify(referenceId)},$$ReactClient.callServer,undefined,${this.environment.mode === "dev" ? "$$ReactClient.findSourceMapURL" : "undefined"},${JSON.stringify(name)})`
213
- });
214
- if (!result) {
215
- manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
216
- return;
217
- }
218
- manager.serverReferences.replaceClaim(PLUGIN_NAME, id, {
219
- ...reference,
220
- exportNames: result.referenceNames
221
- });
222
- const runtimeEnvironment = this.environment.name === "client" ? "browser" : "ssr";
223
- result.output.prepend(`import * as $$ReactClient from "@vitejs/plugin-rsc/react/${runtimeEnvironment}";\n`);
224
- return magicStringTransformResult(result.output, {
225
- hires: "boundary",
226
- source: id
227
- });
228
- }
229
- const secureExports = /* @__PURE__ */ new Set();
230
- const wrap = (value, name, directiveMatch, meta) => {
231
- const variant = directiveMatch[1] ?? "";
232
- const secureName = secureExportName(name);
233
- secureExports.add(secureName);
234
- const wrapperOptions = {
235
- ...getCacheWrapperOptions(meta),
236
- serverReferenceId: `${reference.referenceKey}#${secureName}`
237
- };
238
- return `$$cacheRuntime.registerCachedFunction(${value}, ${JSON.stringify(`${id}:${name}`)}, ${JSON.stringify(variant)}, ${JSON.stringify(wrapperOptions)})`;
239
- };
240
- let needsReactServer = false;
241
- const runtime = (value, name, directiveMatch, meta) => {
242
- const cached = wrap(value, name, directiveMatch, meta);
243
- const secureName = secureExportName(name);
244
- needsReactServer = true;
245
- return `(${secureName} = $$VinextReactServer.registerServerReference(${cached}, ${JSON.stringify(reference.referenceKey)}, ${JSON.stringify(secureName)}))`;
246
- };
247
- const result = moduleDirective ? transforms.transformWrapExport(code, ast, {
248
- filter: (name, meta) => {
249
- if (hasFunctionDirective(meta, "use server") || !shouldTransformModuleExport(name, id, meta)) return false;
250
- validateModuleExport(transforms, meta);
251
- return true;
252
- },
253
- runtime: (value, name, meta) => runtime(value, name, matchUseCacheDirective(moduleDirective), meta)
254
- }) : transforms.transformHoistInlineDirective(code, ast, {
255
- directive: USE_CACHE_DIRECTIVE_CANDIDATE,
256
- rejectNonAsyncFunction: true,
257
- hoistRuntime: true,
258
- noExport: true,
259
- runtime: (value, name, meta) => runtime(value, name, matchUseCacheDirective(meta.directiveMatch[0]), meta),
260
- encode: (value, name) => {
261
- if (name === void 0) throw new Error("vinext: inline \"use cache\" functions require @vitejs/plugin-rsc 0.5.37 or newer.");
262
- const referenceId = `${reference.referenceKey}#${secureExportName(name)}`;
263
- return `$$cacheRuntime.encryptCacheCaptures(${JSON.stringify(referenceId)}, ${value})`;
264
- },
265
- decode: (value) => value
266
- });
267
- if (!result.output.hasChanged()) {
268
- manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
269
- return;
270
- }
271
- manager.serverReferences.replaceClaim(PLUGIN_NAME, id, {
272
- ...reference,
273
- exportNames: [...secureExports]
274
- });
275
- const importPosition = ast.body.find((node) => !("directive" in node))?.start ?? code.length;
276
- result.output.prependLeft(importPosition, [
277
- `import * as $$cacheRuntime from ${JSON.stringify(options.cacheRuntime)};`,
278
- needsReactServer && `import * as $$VinextReactServer from "@vitejs/plugin-rsc/react/rsc/server";`,
279
- secureExports.size > 0 && `let ${[...secureExports].join(",")};`
280
- ].filter(Boolean).join("\n") + "\n");
281
- if (secureExports.size > 0) result.output.append(`\nexport { ${[...secureExports].join(",")} };\n`);
282
- return magicStringTransformResult(result.output, {
283
- hires: "boundary",
284
- source: id
285
- });
286
- }
316
+ handler: transformDirectives
287
317
  }
288
- };
318
+ }, {
319
+ name: `${PLUGIN_NAME}:node-modules`,
320
+ transform: {
321
+ filter: {
322
+ id: {
323
+ include: NODE_MODULES_SOURCE_MODULE_ID_RE,
324
+ exclude: RESOLVED_VIRTUAL_MODULE_ID_RE
325
+ },
326
+ code: "use cache"
327
+ },
328
+ handler: transformDirectives
329
+ }
330
+ }];
289
331
  }
290
332
  //#endregion
291
333
  export { PLUGIN_NAME as USE_CACHE_PLUGIN_NAME, createUseCacheCallablePlugin };
@@ -411,6 +411,12 @@ export declare function buildAppRouteGraph(appDir: string, matcher: ValidFileMat
411
411
  routes: AppRouteGraphRoute[];
412
412
  routeManifest: RouteManifest;
413
413
  }>;
414
+ /**
415
+ * The tree position of a slot's active page relative to the slot root, in the
416
+ * coordinates of configLayoutTreePositions. Route groups count, unlike in
417
+ * `routeSegments`, since each is its own loader-tree segment.
418
+ */
419
+ export declare function findSlotPageTreePosition(slot: Pick<ParallelSlot, "ownerDir" | "pagePath">): number | null;
414
420
  export declare function computeRootParamNames(routeSegments: readonly string[], layoutTreePositions: readonly number[]): string[];
415
421
  export declare function patternsStructurallyEquivalent(a: readonly string[], b: readonly string[]): boolean;
416
422
  /**