@wular/pnext 0.0.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 (371) hide show
  1. package/README.md +153 -0
  2. package/bin/pnext +67 -0
  3. package/config/lint/base.js +48 -0
  4. package/config/ts/base.json +26 -0
  5. package/config/ts/react.json +13 -0
  6. package/package.json +70 -0
  7. package/reference/compat.md +63 -0
  8. package/reference/config.md +120 -0
  9. package/reference/css.md +58 -0
  10. package/reference/dev.md +69 -0
  11. package/reference/env.md +40 -0
  12. package/reference/metadata.md +86 -0
  13. package/reference/navigation.md +149 -0
  14. package/reference/overview.md +35 -0
  15. package/reference/performance.md +97 -0
  16. package/reference/rendering.md +127 -0
  17. package/reference/routing.md +167 -0
  18. package/reference/typegen.md +64 -0
  19. package/src/api/cache.ts +80 -0
  20. package/src/api/client-cache.ts +9 -0
  21. package/src/api/client-navigation.ts +279 -0
  22. package/src/api/dynamic.tsx +102 -0
  23. package/src/api/link.tsx +119 -0
  24. package/src/api/navigation.ts +198 -0
  25. package/src/api/router/events.ts +53 -0
  26. package/src/api/router/history.ts +70 -0
  27. package/src/api/router/hub.ts +194 -0
  28. package/src/api/router/policies.ts +107 -0
  29. package/src/api/router/runtime.ts +5238 -0
  30. package/src/api/router/types.ts +299 -0
  31. package/src/api/router.ts +167 -0
  32. package/src/api/server.ts +323 -0
  33. package/src/api/suspense.ts +16 -0
  34. package/src/cache/context.ts +61 -0
  35. package/src/cli/adapters/vercel-warm.ts +375 -0
  36. package/src/cli/adapters/vercel.ts +1310 -0
  37. package/src/cli/analyze-print.ts +181 -0
  38. package/src/cli/analyze.ts +328 -0
  39. package/src/cli/boot-trace.ts +29 -0
  40. package/src/cli/build.ts +3114 -0
  41. package/src/cli/dev.ts +276 -0
  42. package/src/cli/index.ts +196 -0
  43. package/src/cli/named-bin.ts +119 -0
  44. package/src/cli/serve-ui.ts +160 -0
  45. package/src/cli/start.ts +1425 -0
  46. package/src/client/build.ts +2136 -0
  47. package/src/client/chunk-fold.ts +526 -0
  48. package/src/client/entry.ts +1525 -0
  49. package/src/client/paths.ts +22 -0
  50. package/src/client/prebuilt.ts +621 -0
  51. package/src/client/profile.ts +75 -0
  52. package/src/client/react-compiler.ts +94 -0
  53. package/src/client/reference-stub.ts +145 -0
  54. package/src/client/reference.ts +47 -0
  55. package/src/compat/actions/action-client.ts +531 -0
  56. package/src/compat/actions/action-dispatch.ts +676 -0
  57. package/src/compat/actions/action-router.ts +40 -0
  58. package/src/compat/actions/action-shared.ts +95 -0
  59. package/src/compat/actions/client-plugin.ts +135 -0
  60. package/src/compat/actions/client-stub.ts +65 -0
  61. package/src/compat/actions/config.ts +164 -0
  62. package/src/compat/actions/detect.ts +208 -0
  63. package/src/compat/actions/discovery.ts +244 -0
  64. package/src/compat/actions/early-submit.ts +40 -0
  65. package/src/compat/actions/endpoint.ts +602 -0
  66. package/src/compat/actions/flight.ts +52 -0
  67. package/src/compat/actions/form-state.ts +73 -0
  68. package/src/compat/actions/hoist.ts +485 -0
  69. package/src/compat/actions/ids.ts +39 -0
  70. package/src/compat/actions/index.ts +41 -0
  71. package/src/compat/actions/instances.ts +144 -0
  72. package/src/compat/actions/origin.ts +109 -0
  73. package/src/compat/actions/protocol.ts +125 -0
  74. package/src/compat/actions/registry.ts +74 -0
  75. package/src/compat/actions/rewrite.ts +282 -0
  76. package/src/compat/actions/serve.ts +414 -0
  77. package/src/compat/actions/server-tag.ts +21 -0
  78. package/src/compat/actions/unrecognized-error.ts +30 -0
  79. package/src/compat/adapter/build-complete.ts +257 -0
  80. package/src/compat/bundler/bun-externals.ts +53 -0
  81. package/src/compat/bundler/cjs-exports.ts +542 -0
  82. package/src/compat/bundler/config.ts +363 -0
  83. package/src/compat/bundler/externals.ts +34 -0
  84. package/src/compat/bundler/import-meta-url.ts +60 -0
  85. package/src/compat/bundler/modularize-imports.ts +119 -0
  86. package/src/compat/bundler/new-url-asset.ts +87 -0
  87. package/src/compat/bundler/optimize-package-imports.ts +273 -0
  88. package/src/compat/bundler/polyfill.ts +88 -0
  89. package/src/compat/bundler/react-compiler.ts +61 -0
  90. package/src/compat/bundler/react-profiler.tsx +25 -0
  91. package/src/compat/bundler/relay-transform.ts +116 -0
  92. package/src/compat/bundler/require-context.ts +281 -0
  93. package/src/compat/bundler/resolve-extensions.ts +75 -0
  94. package/src/compat/bundler/source-cache.ts +61 -0
  95. package/src/compat/bundler/static-imports.ts +25 -0
  96. package/src/compat/bundler/symlink-imports.ts +119 -0
  97. package/src/compat/bundler/tsconfig-paths.ts +50 -0
  98. package/src/compat/bundler/wasm.ts +153 -0
  99. package/src/compat/bundler/webpack-loaders.ts +685 -0
  100. package/src/compat/bundler/worker.ts +278 -0
  101. package/src/compat/cache/build-flags.ts +81 -0
  102. package/src/compat/cache/build-prerender-errors.ts +163 -0
  103. package/src/compat/cache/custom-handler.ts +159 -0
  104. package/src/compat/cache/fetch-patch.ts +745 -0
  105. package/src/compat/cache/handler.ts +100 -0
  106. package/src/compat/cache/modern-handler.ts +275 -0
  107. package/src/compat/cache/resume-data-cache.ts +143 -0
  108. package/src/compat/cache/revalidate.ts +759 -0
  109. package/src/compat/cache/runtime-error.ts +124 -0
  110. package/src/compat/cache/use-cache-transform.ts +961 -0
  111. package/src/compat/cache/use-cache.ts +1695 -0
  112. package/src/compat/cache-control.ts +269 -0
  113. package/src/compat/client/base-path.ts +64 -0
  114. package/src/compat/client/css-order.ts +36 -0
  115. package/src/compat/client/errors/control-flow.ts +92 -0
  116. package/src/compat/client/errors/error-boundary.ts +222 -0
  117. package/src/compat/client/errors/global-error.ts +238 -0
  118. package/src/compat/client/errors/install.ts +217 -0
  119. package/src/compat/client/errors/lazy.ts +53 -0
  120. package/src/compat/client/errors/primitive-throw.ts +126 -0
  121. package/src/compat/client/errors/soft-refresh.ts +14 -0
  122. package/src/compat/client/link-status.ts +86 -0
  123. package/src/compat/client/nav-compat-runtime.ts +57 -0
  124. package/src/compat/client/nav-compat.ts +42 -0
  125. package/src/compat/client/navigation-scroll.ts +154 -0
  126. package/src/compat/client/optimistic-routing.ts +206 -0
  127. package/src/compat/client/prefetch-cache.ts +111 -0
  128. package/src/compat/client/route-announcer.ts +72 -0
  129. package/src/compat/client/segment-cache-policy.ts +159 -0
  130. package/src/compat/client/segment-cache.ts +1077 -0
  131. package/src/compat/client/segment-prefetch.ts +375 -0
  132. package/src/compat/client/trailing-slash.ts +24 -0
  133. package/src/compat/css/chunking.ts +254 -0
  134. package/src/compat/css/inline-css.ts +73 -0
  135. package/src/compat/css/lightningcss.ts +90 -0
  136. package/src/compat/css/modules.ts +373 -0
  137. package/src/compat/css/nonce.ts +30 -0
  138. package/src/compat/css/sass-plugin.ts +65 -0
  139. package/src/compat/css/sass.ts +392 -0
  140. package/src/compat/css/styled-jsx-runtime.ts +80 -0
  141. package/src/compat/css/styled-jsx.ts +49 -0
  142. package/src/compat/edge-runtime.ts +71 -0
  143. package/src/compat/export/client.ts +112 -0
  144. package/src/compat/export/index.ts +272 -0
  145. package/src/compat/export/standalone.ts +207 -0
  146. package/src/compat/image-optimizer/cache.ts +119 -0
  147. package/src/compat/image-optimizer/detect.ts +143 -0
  148. package/src/compat/image-optimizer/index.ts +601 -0
  149. package/src/compat/image-optimizer/source.ts +243 -0
  150. package/src/compat/index.ts +458 -0
  151. package/src/compat/lifecycle/after-scope.ts +86 -0
  152. package/src/compat/lifecycle/after.ts +173 -0
  153. package/src/compat/lifecycle/error-funnel.ts +306 -0
  154. package/src/compat/lifecycle/error-serialize.ts +87 -0
  155. package/src/compat/lifecycle/error-ui.ts +167 -0
  156. package/src/compat/lifecycle/instrumentation-client.ts +138 -0
  157. package/src/compat/lifecycle/instrumentation.ts +277 -0
  158. package/src/compat/lifecycle/node-console.ts +19 -0
  159. package/src/compat/lifecycle/testmode.ts +263 -0
  160. package/src/compat/mdx/compile.ts +219 -0
  161. package/src/compat/mdx/next-mdx-stub.ts +46 -0
  162. package/src/compat/mdx/plugin.ts +37 -0
  163. package/src/compat/metadata-route-artifacts.ts +458 -0
  164. package/src/compat/metadata.ts +295 -0
  165. package/src/compat/middleware/manifest.ts +210 -0
  166. package/src/compat/misc/action-return.ts +173 -0
  167. package/src/compat/next/cache.ts +211 -0
  168. package/src/compat/next/canonical-url.ts +35 -0
  169. package/src/compat/next/client-cache.ts +57 -0
  170. package/src/compat/next/client-navigation.ts +313 -0
  171. package/src/compat/next/client-only.ts +3 -0
  172. package/src/compat/next/client-script.tsx +215 -0
  173. package/src/compat/next/client-server.ts +39 -0
  174. package/src/compat/next/config-loader.ts +569 -0
  175. package/src/compat/next/config.ts +29 -0
  176. package/src/compat/next/constants.cjs +6 -0
  177. package/src/compat/next/constants.ts +6 -0
  178. package/src/compat/next/custom-server.ts +236 -0
  179. package/src/compat/next/dist/client/components/app-router-headers.ts +32 -0
  180. package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +38 -0
  181. package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -0
  182. package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -0
  183. package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -0
  184. package/src/compat/next/dynamic.tsx +46 -0
  185. package/src/compat/next/error.tsx +148 -0
  186. package/src/compat/next/font/cache.ts +171 -0
  187. package/src/compat/next/font/google.ts +2 -0
  188. package/src/compat/next/font/index.ts +8 -0
  189. package/src/compat/next/font/local.ts +5 -0
  190. package/src/compat/next/font/runtime-client.ts +71 -0
  191. package/src/compat/next/font/runtime.ts +974 -0
  192. package/src/compat/next/font/shared.ts +281 -0
  193. package/src/compat/next/form.tsx +156 -0
  194. package/src/compat/next/head.tsx +10 -0
  195. package/src/compat/next/headers.ts +247 -0
  196. package/src/compat/next/image/config.ts +196 -0
  197. package/src/compat/next/image/optimizer.ts +96 -0
  198. package/src/compat/next/image/patterns.ts +103 -0
  199. package/src/compat/next/image/shared.ts +141 -0
  200. package/src/compat/next/image/static-metadata.ts +283 -0
  201. package/src/compat/next/image/validate.ts +269 -0
  202. package/src/compat/next/image-client.tsx +215 -0
  203. package/src/compat/next/image-props.ts +575 -0
  204. package/src/compat/next/image-usage.ts +102 -0
  205. package/src/compat/next/image.tsx +56 -0
  206. package/src/compat/next/index.ts +1 -0
  207. package/src/compat/next/legacy-image.tsx +97 -0
  208. package/src/compat/next/link-usage.ts +29 -0
  209. package/src/compat/next/link-validation-transform.ts +200 -0
  210. package/src/compat/next/link.tsx +466 -0
  211. package/src/compat/next/navigation.cjs +21 -0
  212. package/src/compat/next/navigation.ts +188 -0
  213. package/src/compat/next/offline.ts +51 -0
  214. package/src/compat/next/og.ts +324 -0
  215. package/src/compat/next/optimistic-route-state.ts +188 -0
  216. package/src/compat/next/preferred-region.ts +39 -0
  217. package/src/compat/next/redirects.ts +131 -0
  218. package/src/compat/next/resource-hints.ts +136 -0
  219. package/src/compat/next/rewrites.ts +350 -0
  220. package/src/compat/next/root-params.ts +142 -0
  221. package/src/compat/next/router.cjs +49 -0
  222. package/src/compat/next/router.ts +143 -0
  223. package/src/compat/next/script.tsx +355 -0
  224. package/src/compat/next/server-only.ts +3 -0
  225. package/src/compat/next/server.ts +28 -0
  226. package/src/compat/next/svgr.ts +58 -0
  227. package/src/compat/next/telemetry.ts +77 -0
  228. package/src/compat/next/user-agent.ts +100 -0
  229. package/src/compat/next/web-vitals.ts +56 -0
  230. package/src/compat/otel/api.ts +95 -0
  231. package/src/compat/otel/client-trace-metadata.ts +71 -0
  232. package/src/compat/otel/fetch-span.ts +77 -0
  233. package/src/compat/otel/tracer.ts +944 -0
  234. package/src/compat/pages/client-plugin.ts +108 -0
  235. package/src/compat/pages/index.ts +527 -0
  236. package/src/compat/pages/router-state.ts +94 -0
  237. package/src/compat/ppr/io.ts +38 -0
  238. package/src/compat/ppr/missing-root-params.ts +105 -0
  239. package/src/compat/ppr/root-params-scan.ts +164 -0
  240. package/src/compat/ppr/root-params-transform.ts +75 -0
  241. package/src/compat/ppr/root-params.ts +129 -0
  242. package/src/compat/ppr/segment-config-incompat.ts +34 -0
  243. package/src/compat/protocol.ts +202 -0
  244. package/src/compat/react/client.ts +59 -0
  245. package/src/compat/react/compiler-runtime.ts +60 -0
  246. package/src/compat/react/dom-client.ts +115 -0
  247. package/src/compat/react/dom-react-server.ts +20 -0
  248. package/src/compat/react/dom-server.ts +40 -0
  249. package/src/compat/react/dom.ts +154 -0
  250. package/src/compat/react/preact.ts +522 -0
  251. package/src/compat/react/react-server.ts +84 -0
  252. package/src/compat/react/router-shim.ts +26 -0
  253. package/src/compat/react/server-component-use.ts +48 -0
  254. package/src/compat/react/server-inserted-html.ts +87 -0
  255. package/src/compat/react/server.ts +156 -0
  256. package/src/compat/react/view-transition.ts +60 -0
  257. package/src/compat/register/actions.ts +875 -0
  258. package/src/compat/register/boot.ts +141 -0
  259. package/src/compat/register/build-tier.ts +11 -0
  260. package/src/compat/register/build.ts +182 -0
  261. package/src/compat/register/bundler.ts +587 -0
  262. package/src/compat/register/cache.ts +85 -0
  263. package/src/compat/register/client-errors.ts +18 -0
  264. package/src/compat/register/config.ts +17 -0
  265. package/src/compat/register/css-extras.ts +120 -0
  266. package/src/compat/register/edge-runtime.ts +6 -0
  267. package/src/compat/register/errors.ts +46 -0
  268. package/src/compat/register/export.ts +23 -0
  269. package/src/compat/register/font.ts +36 -0
  270. package/src/compat/register/hooks.ts +34 -0
  271. package/src/compat/register/image.ts +133 -0
  272. package/src/compat/register/index.ts +111 -0
  273. package/src/compat/register/instrumentation-client.ts +35 -0
  274. package/src/compat/register/lifecycle.ts +86 -0
  275. package/src/compat/register/mdx.ts +48 -0
  276. package/src/compat/register/middleware.ts +36 -0
  277. package/src/compat/register/misc.ts +44 -0
  278. package/src/compat/register/otel.ts +288 -0
  279. package/src/compat/register/pages-api.ts +473 -0
  280. package/src/compat/register/ppr.ts +56 -0
  281. package/src/compat/register/protocol.ts +57 -0
  282. package/src/compat/register/proxy.ts +127 -0
  283. package/src/compat/register/render.ts +268 -0
  284. package/src/compat/register/routing.ts +410 -0
  285. package/src/compat/register/segment.ts +1903 -0
  286. package/src/compat/register/static-image.ts +21 -0
  287. package/src/compat/register/typed-routes.ts +35 -0
  288. package/src/compat/register/usecache.ts +131 -0
  289. package/src/compat/register/validation.ts +56 -0
  290. package/src/compat/segment/loading-boundary.ts +113 -0
  291. package/src/compat/segment/page-slot.ts +200 -0
  292. package/src/compat/segment/tree.ts +481 -0
  293. package/src/compat/segment/vary-key.ts +102 -0
  294. package/src/compat/segment/vary-params.ts +551 -0
  295. package/src/compat/static-params.ts +33 -0
  296. package/src/compat/tsconfig-defaults.ts +301 -0
  297. package/src/compat/typecheck/index.ts +1481 -0
  298. package/src/compat/typecheck/worker.ts +26 -0
  299. package/src/compat/typed-routes/index.ts +92 -0
  300. package/src/compat/typed-routes/manifest.ts +356 -0
  301. package/src/compat/typed-routes/typegen.ts +566 -0
  302. package/src/compat/validation/errors.ts +159 -0
  303. package/src/compat/validation/index.ts +1770 -0
  304. package/src/compat/validation/prerender-diagnostics.ts +1508 -0
  305. package/src/compat-bootstrap.ts +67 -0
  306. package/src/config.ts +218 -0
  307. package/src/css/build.ts +697 -0
  308. package/src/css/index.ts +2 -0
  309. package/src/css/postcss.ts +236 -0
  310. package/src/css/worker.ts +34 -0
  311. package/src/dev/client-actions.ts +35 -0
  312. package/src/dev/client-chunk-store.ts +92 -0
  313. package/src/dev/client-key-cache.ts +178 -0
  314. package/src/dev/global-css-cache.ts +212 -0
  315. package/src/dev/imports.ts +2430 -0
  316. package/src/dev/module-cache.ts +721 -0
  317. package/src/dev/module-generations.ts +38 -0
  318. package/src/dev/module-transform.ts +188 -0
  319. package/src/dev/node-module-bundle-cache.ts +63 -0
  320. package/src/dev/restart-cache.ts +10 -0
  321. package/src/dev/route-bundle-key-cache.ts +154 -0
  322. package/src/dev/route-facts-cache.ts +223 -0
  323. package/src/dev/server.ts +1710 -0
  324. package/src/dynamic/source.ts +307 -0
  325. package/src/dynamic/tree-shake.ts +262 -0
  326. package/src/env.ts +92 -0
  327. package/src/extensions.ts +1898 -0
  328. package/src/index.ts +34 -0
  329. package/src/internal.ts +43 -0
  330. package/src/islands/boundary-error.ts +8 -0
  331. package/src/islands/static-children.ts +37 -0
  332. package/src/islands/static-slots.ts +106 -0
  333. package/src/ppr-postpone.ts +24 -0
  334. package/src/ppr.ts +784 -0
  335. package/src/proxy.ts +752 -0
  336. package/src/render/hooks.ts +384 -0
  337. package/src/render/index.ts +1 -0
  338. package/src/render/island-context.ts +47 -0
  339. package/src/render/metadata.ts +857 -0
  340. package/src/render/renderer.ts +7391 -0
  341. package/src/render/resource-hints.ts +44 -0
  342. package/src/render/slots.tsx +679 -0
  343. package/src/request/context.ts +396 -0
  344. package/src/resolve/engine.ts +219 -0
  345. package/src/resolve/imports.ts +1104 -0
  346. package/src/resolve/scan-facts.ts +474 -0
  347. package/src/resolve/source-text.ts +86 -0
  348. package/src/routing/forwarded.ts +41 -0
  349. package/src/routing/handler.ts +271 -0
  350. package/src/routing/href.ts +203 -0
  351. package/src/routing/metadata.ts +1018 -0
  352. package/src/routing/request-runtime.ts +43 -0
  353. package/src/routing/routes.ts +2560 -0
  354. package/src/routing/slots.ts +432 -0
  355. package/src/runtime/server.ts +3453 -0
  356. package/src/runtime/vendor.ts +1160 -0
  357. package/src/style-modules.d.ts +9 -0
  358. package/src/typegen.ts +151 -0
  359. package/src/types.ts +725 -0
  360. package/src/utils/ansi.ts +9 -0
  361. package/src/utils/content-type.ts +31 -0
  362. package/src/utils/decode.ts +7 -0
  363. package/src/utils/dev-profile.ts +31 -0
  364. package/src/utils/error-log.ts +29 -0
  365. package/src/utils/fs-cache.ts +31 -0
  366. package/src/utils/fs.ts +119 -0
  367. package/src/utils/html.ts +46 -0
  368. package/src/utils/serialize.ts +378 -0
  369. package/src/utils/source.ts +35 -0
  370. package/src/utils/verbose.ts +39 -0
  371. package/tsconfig.json +10 -0
@@ -0,0 +1,1481 @@
1
+ import { existsSync, statSync } from 'node:fs';
2
+ import { mkdir, writeFile } from 'node:fs/promises';
3
+ import { createRequire } from 'node:module';
4
+ import path from 'node:path';
5
+ import { Worker } from 'node:worker_threads';
6
+ import type * as TS from 'typescript';
7
+ import type { ResolvedConfig } from '../../config';
8
+ import { getNextConfig, type NextConfigObject } from '../next/config-loader';
9
+ import { turbopackLoaderRules } from '../bundler/config';
10
+ import { scanRootParamTypes, type RootParamValueType } from '../ppr/root-params-scan';
11
+
12
+ export class PnextTypecheckError extends Error {
13
+ /** The individual diagnostics, kept so the worker can ship them across intact. */
14
+ readonly messages: string[];
15
+ constructor(messages: string[]) {
16
+ super(messages.join('\n'));
17
+ this.name = 'PnextTypecheckError';
18
+ this.messages = messages;
19
+ }
20
+ }
21
+
22
+ // `typescript` is 8 MB of JS and is needed ONLY to read the app's tsconfig
23
+ // (extends chains, ambient file lists) and as the fallback checker. Loading it
24
+ // lazily keeps it out of every build that never reaches this step.
25
+ let typescriptModule: typeof TS | undefined;
26
+ async function loadTypescript(): Promise<typeof TS> {
27
+ typescriptModule ??= (await import('typescript')) as unknown as typeof TS;
28
+ return typescriptModule;
29
+ }
30
+
31
+ /**
32
+ * `typescript.ignoreBuildErrors` in next.config disables the production typecheck entirely. Fixtures that
33
+ * ship intentional type errors - a `fetch(..., { next: { revalidate: '1' } })` whose runtime error is what
34
+ * the test asserts - rely on the build completing so the app can start and surface it.
35
+ */
36
+ export function typecheckDisabled(): boolean {
37
+ const typescript = getNextConfig().typescript as { ignoreBuildErrors?: unknown } | undefined;
38
+ return typescript?.ignoreBuildErrors === true;
39
+ }
40
+
41
+ /** What ./worker.ts needs to run the check without re-loading the app config. */
42
+ export interface TypecheckWorkerInput {
43
+ root: string;
44
+ outPath: string;
45
+ nextConfig: NextConfigObject;
46
+ }
47
+
48
+ export type TypecheckWorkerResult =
49
+ | { ok: true }
50
+ | { ok: false; messages?: string[]; failure?: string };
51
+
52
+ /**
53
+ * Run the check on a worker thread, so `typescript`'s large import and the diagnostics pass land
54
+ * off the build thread and overlap client bundling and prerendering.
55
+ *
56
+ * The checker reads only `typescript`, `typedRoutes` and `turbopack.rules` from next.config, so a
57
+ * structured-cloneable projection of those goes across rather than the real object (which can carry
58
+ * functions) or a second config load (which would re-run its telemetry and deprecation warnings).
59
+ * A worker that cannot start at all falls back to the in-process path rather than failing the build.
60
+ */
61
+ export async function validateTypesOffThread(config: ResolvedConfig): Promise<void> {
62
+ if (typecheckDisabled()) return;
63
+ const next = getNextConfig();
64
+ const input: TypecheckWorkerInput = {
65
+ root: config.root,
66
+ outPath: config.outPath,
67
+ nextConfig: cloneable({
68
+ typescript: next.typescript,
69
+ typedRoutes: next.typedRoutes,
70
+ turbopack: next.turbopack,
71
+ }),
72
+ };
73
+ let worker: Worker;
74
+ try {
75
+ worker = new Worker(new URL('./worker.ts', import.meta.url), { workerData: input });
76
+ } catch {
77
+ return validateTypes(config);
78
+ }
79
+ const result = await new Promise<TypecheckWorkerResult>((resolve, reject) => {
80
+ worker.on('message', resolve);
81
+ worker.on('error', reject);
82
+ // A worker that exits without a message crashed in a way `error` missed;
83
+ // treat it as a clean check rather than failing a build over the harness.
84
+ worker.on('exit', () => resolve({ ok: true }));
85
+ }).finally(() => void worker.terminate());
86
+ if (result.ok) return;
87
+ if (result.messages) throw new PnextTypecheckError(result.messages);
88
+ throw new Error(result.failure ?? 'typecheck worker failed');
89
+ }
90
+
91
+ /** Drop anything structured-clone would reject (a `turbopack.rules` function). */
92
+ function cloneable(value: NextConfigObject): NextConfigObject {
93
+ try {
94
+ return JSON.parse(JSON.stringify(value)) as NextConfigObject;
95
+ } catch {
96
+ return {};
97
+ }
98
+ }
99
+
100
+ /**
101
+ * TypeScript 7 (`tsgo`) is a separate process, so the check genuinely overlaps bundling instead of
102
+ * blocking the event loop - and it is much faster. It runs as the GATE: a clean TS 7 pass ends the check,
103
+ * which is every successful build.
104
+ *
105
+ * When it does report something, tsc 5.9 re-runs and owns the message text. The two compilers agree on
106
+ * which code is wrong but not always on how they say it - TS 7 collapses a failed generic constraint to
107
+ * the specific cause where 5.9 leads with the constraint itself, and Next's own wording is what the compat
108
+ * suites match. That second pass only ever runs on a build that is already failing.
109
+ */
110
+ export async function validateTypes(config: ResolvedConfig): Promise<void> {
111
+ if (typecheckDisabled()) return;
112
+ const native = await nativeCheckerBin(config.root);
113
+ const project = await writeTypecheckProject(config, native);
114
+ if (native && (await checkWithNative(native, project, config)).length === 0) return;
115
+ const messages = await checkInProcess(project, config);
116
+ if (messages.length === 0) return;
117
+ throw new PnextTypecheckError(messages);
118
+ }
119
+
120
+ async function checkInProcess(project: string, config: ResolvedConfig): Promise<string[]> {
121
+ const ts = await loadTypescript();
122
+ const parsed = readProject(ts, project);
123
+ const program = ts.createProgram(parsed.fileNames, parsed.options);
124
+ const diagnostics = ts
125
+ .getPreEmitDiagnostics(program)
126
+ .filter(diagnostic => appDiagnostic(diagnostic.file?.fileName, config));
127
+ return formatDiagnostics(ts, diagnostics);
128
+ }
129
+
130
+ /**
131
+ * The `tsgo` binary (`@typescript/native-preview`), resolved from the app first so a project pinning its
132
+ * own TS 7 wins. Absent means the in-process fallback. `PNEXT_TYPECHECK=classic` forces the fallback.
133
+ */
134
+ async function nativeCheckerBin(root: string): Promise<string | undefined> {
135
+ // eslint-disable-next-line turbo/no-undeclared-env-vars
136
+ if (process.env.PNEXT_TYPECHECK === 'classic') return undefined;
137
+ for (const base of [root, import.meta.dirname]) {
138
+ try {
139
+ const require = createRequire(path.join(base, 'noop.js'));
140
+ const pkg = require.resolve('@typescript/native-preview/package.json');
141
+ // The package exposes the platform binary only through its own resolver
142
+ // (the published `.` export is just a version stub).
143
+ const { default: getExePath } = (await import(
144
+ path.join(path.dirname(pkg), 'lib', 'getExePath.js')
145
+ )) as { default: () => string };
146
+ const bin = getExePath();
147
+ if (bin && existsSync(bin)) return bin;
148
+ } catch {
149
+ // keep looking
150
+ }
151
+ }
152
+ return undefined;
153
+ }
154
+
155
+ async function checkWithNative(
156
+ bin: string,
157
+ project: string,
158
+ config: ResolvedConfig,
159
+ ): Promise<string[]> {
160
+ const proc = Bun.spawn([bin, '--noEmit', '--pretty', 'false', '-p', project], {
161
+ cwd: config.root,
162
+ stdout: 'pipe',
163
+ stderr: 'pipe',
164
+ });
165
+ const [stdout, stderr] = await Promise.all([
166
+ new Response(proc.stdout).text(),
167
+ new Response(proc.stderr).text(),
168
+ ]);
169
+ await proc.exited;
170
+ return nativeDiagnostics(`${stdout}${stderr}`, config);
171
+ }
172
+
173
+ /**
174
+ * Reshape `tsgo --pretty false` output into the same `<file>:<line>:<col>` plus `Type error: <message>`
175
+ * lines the in-process path produces. A diagnostic is one `file(line,col): error TSxxxx: message` header
176
+ * plus every indented elaboration line under it - the same text `flattenDiagnosticMessageText` builds from
177
+ * a message chain.
178
+ */
179
+ function nativeDiagnostics(output: string, config: ResolvedConfig): string[] {
180
+ const header = /^(?:(.+)\((\d+),(\d+)\): )?error TS\d+: (.*)$/;
181
+ const messages = new Set<string>();
182
+ const lines = output.split('\n');
183
+ for (let index = 0; index < lines.length; index += 1) {
184
+ const match = header.exec(lines[index]!);
185
+ if (!match) continue;
186
+ const [, file, line, column, text] = match;
187
+ const elaborations: string[] = [];
188
+ while (index + 1 < lines.length && /^\s+\S/.test(lines[index + 1]!)) {
189
+ elaborations.push(lines[index + 1]!);
190
+ index += 1;
191
+ }
192
+ const resolved = file ? path.resolve(config.root, file) : undefined;
193
+ if (!appDiagnostic(resolved, config)) continue;
194
+ const raw = [text, ...elaborations].join('\n');
195
+ const location = resolved ? `${resolved}:${line}:${column}\n` : '';
196
+ messages.add(`${location}Type error: ${typedRouteMessage(raw) ?? raw}`);
197
+ }
198
+ return [...messages];
199
+ }
200
+
201
+ // Only diagnostics originating in the app's own sources may fail the build;
202
+ // errors inside node_modules, pnext shims, or generated files are never the
203
+ // app author's fault (Next.js typechecks with the same scoping).
204
+ function appDiagnostic(file: string | undefined, config: ResolvedConfig): boolean {
205
+ if (!file) return true;
206
+ const resolved = path.resolve(file);
207
+ // The generated project is pnext's own; an option error in it (TS5102 and
208
+ // friends) is a framework bug and must never be silently swallowed.
209
+ if (resolved === generatedProjectPath(config)) return true;
210
+ if (!resolved.startsWith(config.root + path.sep)) return false;
211
+ if (resolved.includes(`${path.sep}node_modules${path.sep}`)) return false;
212
+ if (resolved.startsWith(path.resolve(config.outPath) + path.sep)) return false;
213
+ return true;
214
+ }
215
+
216
+ function generatedProjectPath(config: ResolvedConfig): string {
217
+ return path.resolve(config.outPath, 'typecheck', 'tsconfig.json');
218
+ }
219
+
220
+ /**
221
+ * The app's `react` import resolves to pnext's preact compat shim at runtime, whose types cannot satisfy
222
+ * React-typed app code. Point the typechecker at real `@types/react` instead - the app's own copy if
223
+ * installed, otherwise the one visible from pnext. React mappings intentionally override app paths, since
224
+ * they describe pnext's runtime aliases, while unrelated path mappings remain.
225
+ *
226
+ * Written INTO the generated tsconfig rather than patched onto parsed options, so the out-of-process
227
+ * checker sees exactly what the in-process one does.
228
+ */
229
+ function reactTypePaths(
230
+ root: string,
231
+ basePaths: Record<string, string[]> | undefined,
232
+ compatPreact?: string,
233
+ ): Record<string, string[]> | undefined {
234
+ const react = resolveTypesDir('react', root);
235
+ if (!react) return basePaths;
236
+ const reactDom = resolveTypesDir('react-dom', root);
237
+ const paths: Record<string, string[]> = { ...basePaths };
238
+ const mappings: Record<string, string | undefined> = {
239
+ react: path.join(react, 'index.d.ts'),
240
+ 'react/*': path.join(react, '*'),
241
+ 'react-dom': reactDom && path.join(reactDom, 'index.d.ts'),
242
+ 'react-dom/*': reactDom && path.join(reactDom, '*'),
243
+ preact: compatPreact,
244
+ };
245
+ for (const [key, value] of Object.entries(mappings)) {
246
+ if (value) paths[key] = [value];
247
+ }
248
+ return paths;
249
+ }
250
+
251
+ function resolveTypesDir(name: string, root: string): string | undefined {
252
+ for (const base of [root, import.meta.dirname]) {
253
+ try {
254
+ const require = createRequire(path.join(base, 'noop.js'));
255
+ return path.dirname(require.resolve(`@types/${name}/package.json`));
256
+ } catch {
257
+ // keep looking
258
+ }
259
+ }
260
+ return undefined;
261
+ }
262
+
263
+ // Rebase an app's `paths` onto absolute targets so the generated project (which
264
+ // lives elsewhere and can no longer carry a `baseUrl`) resolves them identically.
265
+ function absolutePaths(
266
+ paths: TS.MapLike<string[]> | undefined,
267
+ basePath: string,
268
+ ): Record<string, string[]> | undefined {
269
+ if (!paths) return undefined;
270
+ return Object.fromEntries(
271
+ Object.entries(paths).map(([key, targets]) => [
272
+ key,
273
+ targets.map(target => (path.isAbsolute(target) ? target : path.resolve(basePath, target))),
274
+ ]),
275
+ );
276
+ }
277
+
278
+ function resolvePackageDir(name: string, root: string): string | undefined {
279
+ for (const base of [root, import.meta.dirname]) {
280
+ try {
281
+ const require = createRequire(path.join(base, 'noop.js'));
282
+ return path.dirname(require.resolve(`${name}/package.json`));
283
+ } catch {
284
+ // keep looking
285
+ }
286
+ }
287
+ return undefined;
288
+ }
289
+
290
+ async function writeTypecheckProject(
291
+ config: ResolvedConfig,
292
+ native: string | undefined,
293
+ ): Promise<string> {
294
+ const dir = path.join(config.outPath, 'typecheck');
295
+ await mkdir(dir, { recursive: true });
296
+ const reactTypes = resolveTypesDir('react', config.root);
297
+ const hasReactTypes = reactTypes !== undefined;
298
+ const rootParams = scanRootParamTypes(path.join(config.root, 'app'));
299
+ // With `typedRoutes` on, the build generates `.next/types/link.d.ts`, whose next/link, next/navigation
300
+ // and next augmentations layer the RouteImpl type onto the *real* next package. pnext's own permissive
301
+ // `next/*` shims would shadow those and mask the typed-route errors the suite asserts. When the real next
302
+ // package is resolvable from the app, drop the next-module shims and let real next plus the generated
303
+ // files drive the check - exactly what `next build` does.
304
+ const omitNextModuleShims = typedRoutesEnabled() && realNextResolvable(config.root);
305
+ await writeFile(
306
+ path.join(dir, 'next-shims.d.ts'),
307
+ nextShims(hasReactTypes, rootParams, omitNextModuleShims),
308
+ );
309
+ const preact = resolvePackageDir('preact', config.root);
310
+ if (reactTypes && preact) {
311
+ await writeFile(preactTypeShimPath(config), preactTypeShim(preact, reactTypes));
312
+ }
313
+ const base = tsconfigPath(config.root);
314
+ const baseProject = base ? await readBaseProject(base, native) : undefined;
315
+ const baseOptions = baseProject?.options ?? {};
316
+ const preactShim = preactTypeShimPath(config);
317
+ const project = generatedProjectPath(config);
318
+ const paths = reactTypePaths(
319
+ config.root,
320
+ absolutePaths(
321
+ baseOptions.paths,
322
+ baseOptions.baseUrl ?? (base ? path.dirname(base) : config.root),
323
+ ),
324
+ existsSync(preactShim) ? preactShim : undefined,
325
+ );
326
+ // App sources (and fixture helpers they import) may use node builtins
327
+ // (`node:fs`, `node:path`). Next resolves them through @types/node; put the
328
+ // app's copy (or pnext's fallback) in the program so `Cannot find module
329
+ // 'node:*'` never fails an app build.
330
+ const nodeTypes = resolveTypesDir('node', config.root);
331
+ await writeFile(
332
+ project,
333
+ JSON.stringify(
334
+ {
335
+ ...(base ? { extends: base } : {}),
336
+ compilerOptions: {
337
+ noEmit: true,
338
+ // TS keeps only the buildinfo under noEmit, so a re-check of an
339
+ // unchanged app is near-free. It lives outside outPath, which every
340
+ // build wipes.
341
+ incremental: true,
342
+ tsBuildInfoFile: path.join(
343
+ config.root,
344
+ 'node_modules',
345
+ '.cache',
346
+ 'pnext',
347
+ 'typecheck.tsbuildinfo',
348
+ ),
349
+ skipLibCheck: true,
350
+ allowJs: true,
351
+ resolveJsonModule: true,
352
+ isolatedModules: true,
353
+ jsx: 'react-jsx',
354
+ // Runtime JSX targets Preact, but compat typechecking validates the
355
+ // React/Next contract: an inherited `jsxImportSource: 'preact'` would
356
+ // make app components return Preact VNodes, which the React validator
357
+ // rejects. 'react' is TS's own default for react-jsx.
358
+ jsxImportSource: 'react',
359
+ // `paths` only, never `baseUrl` — TS 7 removed it (TS5102). The
360
+ // mappings are absolutized above so they resolve the same from here.
361
+ ...(paths ? { paths } : {}),
362
+ // Fallbacks for apps whose tsconfig leaves these unset (the ES3 default rejects modern syntax).
363
+ // The app's own values win - `next build` checks with the app's options, and overriding
364
+ // lib/strict/target changes inference.
365
+ ...(baseOptions.strict === undefined ? { strict: false } : {}),
366
+ ...(baseOptions.target === undefined ? { target: 'es2022' } : {}),
367
+ ...(baseOptions.module === undefined ? { module: 'esnext' } : {}),
368
+ ...(baseOptions.moduleResolution === undefined
369
+ ? { moduleResolution: 'bundler' }
370
+ : {}),
371
+ ...(baseOptions.lib === undefined ? { lib: ['es2022', 'dom', 'dom.iterable'] } : {}),
372
+ },
373
+ include: [
374
+ path.join(dir, 'next-shims.d.ts'),
375
+ ...(nodeTypes ? [path.join(nodeTypes, 'index.d.ts')] : []),
376
+ path.join(config.root, 'next-env.d.ts'),
377
+ // The build emits `.next/types/validator.ts` (page/layout/route-handler export validation) just
378
+ // before this typecheck. Next includes it in the program so invalid exports fail the build with a
379
+ // constraint type error; include it here too. It lives outside the `.pnext` outPath, so its
380
+ // diagnostics survive appDiagnostic's scoping.
381
+ ...(existsSync(path.join(config.root, '.next/types/validator.ts'))
382
+ ? [path.join(config.root, '.next/types/validator.ts')]
383
+ : []),
384
+ path.join(config.root, 'middleware.*'),
385
+ path.join(config.root, 'proxy.*'),
386
+ // Next type-checks the project's next.config.(ts|mts|cts) as part of
387
+ // `next build`; a type error in the config fails the build (the
388
+ // next-config-ts*/type-error suites assert this). JS configs carry no
389
+ // types to check, so only the TS variants are included.
390
+ path.join(config.root, 'next.config.ts'),
391
+ path.join(config.root, 'next.config.mts'),
392
+ path.join(config.root, 'next.config.cts'),
393
+ path.join(config.root, 'app/**/*.ts'),
394
+ path.join(config.root, 'app/**/*.tsx'),
395
+ path.join(config.root, 'pages/**/*.ts'),
396
+ path.join(config.root, 'pages/**/*.tsx'),
397
+ // The app tsconfig's own file list contributes ambient declarations
398
+ // (global .d.ts JSX/module augmentations) nothing imports; merge just
399
+ // those in. Merging its `include` PATTERNS instead would also drag in
400
+ // every stray root-level source (e2e fixtures keep collectors, custom
401
+ // servers and loader inputs there) that no app entry imports, failing
402
+ // builds on helper files the app never bundles.
403
+ ...baseAmbientDeclarations(baseProject?.fileNames, config),
404
+ ],
405
+ exclude: [
406
+ path.join(config.root, 'node_modules'),
407
+ path.join(config.root, '**/*.test.ts'),
408
+ path.join(config.root, '**/*.test.tsx'),
409
+ ],
410
+ },
411
+ null,
412
+ 2,
413
+ ),
414
+ );
415
+ return project;
416
+ }
417
+
418
+ function preactTypeShimPath(config: ResolvedConfig): string {
419
+ return path.join(config.outPath, 'typecheck', 'preact-compat.d.ts');
420
+ }
421
+
422
+ function preactTypeShim(preact: string, react: string): string {
423
+ const preactTypes = JSON.stringify(path.join(preact, 'src', 'index.d.ts'));
424
+ const types = JSON.stringify(path.join(react, 'index.d.ts'));
425
+ return `import type { ReactNode } from ${types}
426
+
427
+ export * from ${preactTypes}
428
+ export type ComponentChild = ReactNode
429
+ export type ComponentChildren = ReactNode
430
+ `;
431
+ }
432
+
433
+ function typedRoutesEnabled(): boolean {
434
+ return (getNextConfig() as { typedRoutes?: unknown }).typedRoutes === true;
435
+ }
436
+
437
+ // Whether the real `next` package's type entry resolves from the app root.
438
+ function realNextResolvable(root: string): boolean {
439
+ try {
440
+ createRequire(path.join(root, 'noop.js')).resolve('next/package.json');
441
+ return true;
442
+ } catch {
443
+ return false;
444
+ }
445
+ }
446
+
447
+ /** Absolute `.d.ts` paths the app's own tsconfig would have put in the program. */
448
+ function baseAmbientDeclarations(fileNames: readonly string[] | undefined, config: ResolvedConfig): string[] {
449
+ if (!fileNames) return [];
450
+ const outPath = path.resolve(config.outPath) + path.sep;
451
+ return fileNames
452
+ .map(name => path.resolve(name))
453
+ .filter(
454
+ name =>
455
+ name.endsWith('.d.ts') &&
456
+ !name.includes(`${path.sep}node_modules${path.sep}`) &&
457
+ !name.startsWith(outPath),
458
+ );
459
+ }
460
+
461
+ interface BaseProject {
462
+ options: {
463
+ paths?: TS.MapLike<string[]>;
464
+ baseUrl?: string;
465
+ strict?: unknown;
466
+ target?: unknown;
467
+ module?: unknown;
468
+ moduleResolution?: unknown;
469
+ lib?: unknown;
470
+ };
471
+ fileNames: string[];
472
+ }
473
+
474
+ /**
475
+ * Resolves the app tsconfig's extends chain and include globs via `tsgo --showConfig` so the native
476
+ * fast path never imports the classic `typescript` package. Any failure falls back to the classic
477
+ * reader.
478
+ */
479
+ async function readBaseProject(file: string, native: string | undefined): Promise<BaseProject> {
480
+ const shown = native ? await showConfigViaNative(native, file) : undefined;
481
+ if (shown) return shown;
482
+ const ts = await loadTypescript();
483
+ const parsed = readProject(ts, file);
484
+ return { options: parsed.options, fileNames: [...parsed.fileNames] };
485
+ }
486
+
487
+ async function showConfigViaNative(bin: string, file: string): Promise<BaseProject | undefined> {
488
+ try {
489
+ const proc = Bun.spawn([bin, '--showConfig', '-p', file], { stdout: 'pipe', stderr: 'pipe' });
490
+ const stdout = await new Response(proc.stdout).text();
491
+ await proc.exited;
492
+ if (proc.exitCode !== 0) return undefined;
493
+ const shown = JSON.parse(stdout) as { compilerOptions?: BaseProject['options']; files?: string[] };
494
+ const dir = path.dirname(file);
495
+ const options = shown.compilerOptions ?? {};
496
+ if (typeof options.baseUrl === 'string') options.baseUrl = path.resolve(dir, options.baseUrl);
497
+ const fileNames = (shown.files ?? []).map(f => path.resolve(dir, f));
498
+ return { options, fileNames };
499
+ } catch {
500
+ return undefined;
501
+ }
502
+ }
503
+
504
+ function tsconfigPath(root: string): string | undefined {
505
+ const tsConfig = getNextConfig().typescript as { tsconfigPath?: unknown } | undefined;
506
+ const configured = tsConfig?.tsconfigPath;
507
+ const file =
508
+ typeof configured === 'string' && configured.length > 0
509
+ ? path.join(root, configured)
510
+ : path.join(root, 'tsconfig.json');
511
+ return existsSync(file) ? file : undefined;
512
+ }
513
+
514
+ /**
515
+ * Memoized per project path: `parseJsonConfigFileContent` walks every `include` glob to build
516
+ * `fileNames`. The cache lives for the process, which for the checker is one build (dev never
517
+ * typechecks).
518
+ */
519
+ const parsedProjects = new Map<string, { stamp: number; parsed: TS.ParsedCommandLine }>();
520
+
521
+ function readProject(ts: typeof TS, project: string): TS.ParsedCommandLine {
522
+ // The generated project is rewritten before every check, so the cache is
523
+ // keyed on the file's mtime rather than its path alone.
524
+ let stamp = 0;
525
+ try {
526
+ stamp = statSync(project).mtimeMs;
527
+ } catch {
528
+ /* unreadable: parse and let readConfigFile report it */
529
+ }
530
+ const cached = parsedProjects.get(project);
531
+ if (cached?.stamp === stamp) return cached.parsed;
532
+ const read = ts.readConfigFile(project, file => ts.sys.readFile(file));
533
+ if (read.error) throw new PnextTypecheckError(formatDiagnostics(ts, [read.error]));
534
+ const parsed = ts.parseJsonConfigFileContent(read.config, ts.sys, path.dirname(project));
535
+ parsedProjects.set(project, { stamp, parsed });
536
+ return parsed;
537
+ }
538
+
539
+ function formatDiagnostics(ts: typeof TS, diagnostics: readonly TS.Diagnostic[]): string[] {
540
+ const messages = new Set<string>();
541
+ for (const diagnostic of diagnostics) {
542
+ const raw = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
543
+ const typedRoute = typedRouteMessage(raw);
544
+ // Next prints `./relative/file.ts:line:col` on its own line above the
545
+ // message; mirror that so build failures name their source.
546
+ let location = '';
547
+ if (diagnostic.file && diagnostic.start !== undefined) {
548
+ const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
549
+ location = `${diagnostic.file.fileName}:${line + 1}:${character + 1}\n`;
550
+ }
551
+ messages.add(`${location}Type error: ${typedRoute ?? raw}`);
552
+ }
553
+ return [...messages];
554
+ }
555
+
556
+ function typedRouteMessage(message: string): string | undefined {
557
+ const match = /^Type '(".*")' is not assignable to type '.*RouteImpl<\1>/.exec(message);
558
+ if (!match?.[1]) return undefined;
559
+ return `${match[1]} is not an existing route. If it is intentional, please type it explicitly with \`as Route\`.`;
560
+ }
561
+
562
+ function rootParamsModule(rootParams: Map<string, Set<RootParamValueType>>): string {
563
+ // Real Next generates `next/root-params`'s exports per-build from the app's
564
+ // actual root params (dynamic segments at/above a root layout). Mirror that:
565
+ // one getter per scanned param with its scanned value type (`string` for
566
+ // `[name]`, `string[]` for catch-alls, `| undefined` when optional or absent
567
+ // from some root layout). When the scan finds nothing (no root layout / no
568
+ // dynamic root segments), fall back to the static `lang`/`locale` exports
569
+ // that existing suites rely on.
570
+ const order: RootParamValueType[] = ['string', 'string[]', 'undefined'];
571
+ const entries: [string, string][] =
572
+ rootParams.size > 0
573
+ ? [...rootParams.entries()].map(([name, types]) => [
574
+ name,
575
+ order.filter(type => types.has(type)).join(' | '),
576
+ ])
577
+ : [
578
+ ['lang', 'string | string[] | undefined'],
579
+ ['locale', 'string | string[] | undefined'],
580
+ ];
581
+ const getters = entries
582
+ .map(([name, union]) => ` export function ${name}(): Promise<${union}>`)
583
+ .join('\n');
584
+ return `declare module 'next/root-params' {
585
+ ${getters}
586
+ const rootParams: (...args: any[]) => Promise<any>
587
+ export default rootParams
588
+ }`;
589
+ }
590
+
591
+ // Remove every top-level `declare module 'next...' { ... }` block from a shim
592
+ // source by brace-counting. Used when the real next package is present and
593
+ // should own the `next/*` type surface (typedRoutes). Non-next ambient
594
+ // declarations (node builtins, asset wildcards, RequestInit augmentation) are
595
+ // left intact.
596
+ function stripNextModuleDeclarations(source: string): string {
597
+ const lines = source.split('\n');
598
+ const out: string[] = [];
599
+ for (let i = 0; i < lines.length; i++) {
600
+ const line = lines[i]!;
601
+ if (/^declare module 'next[^']*' \{/.test(line)) {
602
+ let depth = 0;
603
+ for (; i < lines.length; i++) {
604
+ const current = lines[i]!;
605
+ depth += (current.match(/\{/g)?.length ?? 0) - (current.match(/\}/g)?.length ?? 0);
606
+ if (depth === 0) break;
607
+ }
608
+ continue;
609
+ }
610
+ out.push(line);
611
+ }
612
+ return out.join('\n');
613
+ }
614
+
615
+ function nextShims(
616
+ hasReactTypes: boolean,
617
+ rootParams: Map<string, Set<RootParamValueType>>,
618
+ omitNextModuleShims = false,
619
+ ): string {
620
+ // Ambient module declarations override real module resolution, so the react
621
+ // fallbacks below must only exist when no real `@types/react` was found —
622
+ // otherwise `import { JSX } from 'react'` etc. fail against the stub.
623
+ const reactShims = hasReactTypes
624
+ ? ''
625
+ : `
626
+ declare namespace JSX {
627
+ interface Element {}
628
+ interface IntrinsicElements {
629
+ [name: string]: any
630
+ }
631
+ }
632
+
633
+ declare namespace React {
634
+ type ReactNode = any
635
+ type ComponentType<P = any> = (props: P) => ReactNode
636
+ }
637
+
638
+ declare module 'react' {
639
+ export type ReactNode = any
640
+ export type ComponentType<P = any> = (props: P) => ReactNode
641
+ export type AnchorHTMLAttributes<T> = any
642
+ export type DetailedHTMLProps<E, T> = any
643
+ export const Suspense: ComponentType<any>
644
+ export const ViewTransition: ComponentType<any>
645
+ export function addTransitionType(type: string): void
646
+ }
647
+
648
+ declare module 'react/jsx-runtime' {
649
+ export const jsx: any
650
+ export const jsxs: any
651
+ export const Fragment: any
652
+ }
653
+ `;
654
+ const source = `${reactShims}
655
+ declare const process: {
656
+ env: Record<string, string | undefined>
657
+ emit?: (...args: any[]) => boolean
658
+ cwd(): string
659
+ platform: string
660
+ arch: string
661
+ version: string
662
+ versions: Record<string, string>
663
+ nextTick(callback: (...args: any[]) => void, ...args: any[]): void
664
+ argv: string[]
665
+ pid: number
666
+ exit(code?: number): never
667
+ [key: string]: any
668
+ }
669
+
670
+ declare const EdgeRuntime: string
671
+
672
+ declare const require: (id: string) => any
673
+
674
+ declare class Buffer extends Uint8Array {}
675
+
676
+ declare module 'async_hooks' {
677
+ export class AsyncLocalStorage<T> {
678
+ run<R>(store: T, callback: () => R): R
679
+ getStore(): T | undefined
680
+ }
681
+ }
682
+
683
+ declare module 'timers/promises' {
684
+ export function setTimeout<T = void>(delay?: number, value?: T, options?: any): Promise<T>
685
+ export function setImmediate<T = void>(value?: T, options?: any): Promise<T>
686
+ export function setInterval<T = void>(delay?: number, value?: T, options?: any): AsyncIterable<T>
687
+ }
688
+
689
+ declare module 'node:timers/promises' {
690
+ export * from 'timers/promises'
691
+ }
692
+
693
+ declare module 'node:crypto' {
694
+ interface KeyObject {
695
+ export(...args: any[]): any
696
+ toString(...args: any[]): string
697
+ }
698
+ export function randomInt(...args: any[]): number
699
+ export function randomBytes(...args: any[]): Buffer
700
+ export function randomFillSync<T extends Uint8Array>(buffer: T, ...args: any[]): T
701
+ export function randomUUID(...args: any[]): string
702
+ export function getRandomValues<T extends Uint8Array>(array: T): T
703
+ export function generateKeyPairSync(...args: any[]): { publicKey: any; privateKey: any }
704
+ export function generateKeySync(...args: any[]): KeyObject
705
+ export function generatePrimeSync(...args: any[]): ArrayBuffer | Uint8Array
706
+ const crypto: {
707
+ randomInt: typeof randomInt
708
+ randomBytes: typeof randomBytes
709
+ randomFillSync: typeof randomFillSync
710
+ randomUUID: typeof randomUUID
711
+ getRandomValues: typeof getRandomValues
712
+ generateKeyPairSync: typeof generateKeyPairSync
713
+ generateKeySync: typeof generateKeySync
714
+ generatePrimeSync: typeof generatePrimeSync
715
+ }
716
+ export default crypto
717
+ }
718
+
719
+ declare module 'crypto' {
720
+ export * from 'node:crypto'
721
+ export { default } from 'node:crypto'
722
+ }
723
+
724
+ // Next.js augments the fetch RequestInit with a "next" field for its extended
725
+ // fetch semantics (revalidate/tags); mirror that here so app code using
726
+ // fetch(url, next revalidate) typechecks.
727
+ interface RequestInit {
728
+ next?: {
729
+ revalidate?: number | false
730
+ tags?: string[]
731
+ }
732
+ }
733
+
734
+ interface ResponseInit {
735
+ request?: {
736
+ headers?: HeadersInit
737
+ }
738
+ }
739
+
740
+ declare module 'node:buffer' {
741
+ export const Buffer: any
742
+ export const constants: any
743
+ export const kMaxLength: number
744
+ export const kStringMaxLength: number
745
+ export const SlowBuffer: any
746
+ }
747
+
748
+ declare module 'url' {
749
+ export interface UrlObject {
750
+ pathname?: string
751
+ query?: Record<string, string | string[]>
752
+ hash?: string
753
+ }
754
+ }
755
+
756
+ declare module 'next/types.js' {
757
+ export interface NextConfig {
758
+ env?: Record<string, string | number | boolean | undefined>
759
+ typedRoutes?: boolean
760
+ typescript?: { tsconfigPath?: string; ignoreBuildErrors?: boolean }
761
+ eslint?: { ignoreDuringBuilds?: boolean; dirs?: string[] }
762
+ [key: string]: any
763
+ }
764
+ export type Metadata = any
765
+ export type Viewport = any
766
+ export type ResolvingMetadata = Promise<Metadata>
767
+ export type ResolvingViewport = Promise<Viewport>
768
+ export type NextApiHandler<T = any> = (...args: any[]) => any
769
+ export type NextApiRequest = any
770
+ export type NextApiResponse<T = any> = any
771
+ export namespace MetadataRoute {
772
+ type Robots = any
773
+ type Sitemap = any[]
774
+ type Manifest = any
775
+ }
776
+ export type Route<T = string> = string
777
+ export type NextPage<P = {}, IP = P> = ((props: P) => any) & { [key: string]: any }
778
+ export type NextComponentType<C = any, IP = any, P = any> = any
779
+ export type PageProps<P = any> = any
780
+ export type LayoutProps<P = any> = any
781
+ }
782
+
783
+ declare module 'next/types' {
784
+ export * from 'next/types.js'
785
+ export { MetadataRoute } from 'next/types.js'
786
+ }
787
+
788
+ declare module 'next' {
789
+ export type {
790
+ NextConfig,
791
+ Metadata,
792
+ Viewport,
793
+ ResolvingMetadata,
794
+ ResolvingViewport,
795
+ NextApiRequest,
796
+ NextApiResponse,
797
+ NextApiHandler,
798
+ Route,
799
+ NextPage,
800
+ NextComponentType,
801
+ PageProps,
802
+ LayoutProps,
803
+ } from 'next/types.js'
804
+ export { MetadataRoute } from 'next/types.js'
805
+ export type GetServerSideProps<P = any, Q = any> = any
806
+ export type GetStaticProps<P = any, Q = any> = any
807
+ export type GetStaticPaths<Q = any> = any
808
+ export type InferGetServerSidePropsType<T = any> = any
809
+ export type InferGetStaticPropsType<T = any> = any
810
+ }
811
+
812
+ declare module 'next/cache' {
813
+ export function revalidatePath(path: string, type?: 'page' | 'layout'): void
814
+ export function revalidateTag(tag: string, profile: string | { expire?: number }): void
815
+ export function updateTag(tag: string): void
816
+ export function unstable_cache(...args: any[]): any
817
+ export function unstable_noStore(): void
818
+ export function unstable_expirePath(path: string, type?: 'page' | 'layout'): void
819
+ export function unstable_expireTag(...tags: string[]): void
820
+ export function expirePath(path: string, type?: 'page' | 'layout'): void
821
+ export function expireTag(...tags: string[]): void
822
+ export function refresh(): void
823
+ export function unstable_refresh(): void
824
+ export const io: any
825
+ export const cacheTag: (...tags: string[]) => void
826
+ export const cacheLife: (...args: any[]) => void
827
+ export const unstable_cacheTag: (...tags: string[]) => void
828
+ export const unstable_cacheLife: (...args: any[]) => void
829
+ }
830
+
831
+ declare module 'next/headers' {
832
+ interface CookieSetOptions {
833
+ name?: string
834
+ value?: string
835
+ path?: string
836
+ maxAge?: number
837
+ expires?: Date | number
838
+ httpOnly?: boolean
839
+ secure?: boolean
840
+ sameSite?: 'strict' | 'lax' | 'none' | boolean
841
+ domain?: string
842
+ }
843
+ interface CookieStore {
844
+ get(name: string): { name: string; value: string } | undefined
845
+ get(options: { name: string; value?: string }): { name: string; value: string } | undefined
846
+ getAll(name?: string): { name: string; value: string }[]
847
+ getAll(options: { name: string; value?: string }): { name: string; value: string }[]
848
+ has(name: string): boolean
849
+ readonly size: number
850
+ set(name: string, value: string, options?: CookieSetOptions): CookieStore
851
+ set(options: CookieSetOptions): CookieStore
852
+ delete(name: string): boolean
853
+ clear(): CookieStore
854
+ [Symbol.iterator](): IterableIterator<readonly [string, { name?: string; value: string }]>
855
+ }
856
+ export function cookies(): Promise<CookieStore>
857
+ export function headers(): Promise<Headers>
858
+ export function draftMode(): Promise<{
859
+ isEnabled: boolean
860
+ enable(): void
861
+ disable(): void
862
+ }>
863
+ }
864
+
865
+ declare module 'next/server' {
866
+ interface NextURL extends URL {
867
+ clone(): NextURL
868
+ basePath: string
869
+ buildId?: string
870
+ locale: string
871
+ defaultLocale?: string
872
+ }
873
+ interface RequestCookie {
874
+ name: string
875
+ value: string
876
+ }
877
+ interface RequestCookies {
878
+ get(name: string): RequestCookie | undefined
879
+ getAll(name?: string): RequestCookie[]
880
+ has(name: string): boolean
881
+ set(name: string, value: string): RequestCookies
882
+ set(cookie: RequestCookie): RequestCookies
883
+ delete(name: string | string[]): boolean | boolean[]
884
+ clear(): RequestCookies
885
+ readonly size: number
886
+ [Symbol.iterator](): IterableIterator<[string, RequestCookie]>
887
+ }
888
+ interface ResponseCookies {
889
+ get(name: string): (RequestCookie & Record<string, any>) | undefined
890
+ getAll(name?: string): (RequestCookie & Record<string, any>)[]
891
+ has(name: string): boolean
892
+ set(name: string, value: string, options?: any): ResponseCookies
893
+ set(options: { name: string; value: string; [key: string]: any }): ResponseCookies
894
+ delete(name: string, options?: any): ResponseCookies
895
+ [Symbol.iterator](): IterableIterator<[string, RequestCookie & Record<string, any>]>
896
+ }
897
+ export class NextRequest extends Request {
898
+ nextUrl: NextURL
899
+ cookies: RequestCookies
900
+ geo?: any
901
+ ip?: string
902
+ }
903
+ export class NextResponse extends Response {
904
+ cookies: ResponseCookies
905
+ static json(body: any, init?: ResponseInit): NextResponse
906
+ static next(init?: ResponseInit): NextResponse
907
+ static redirect(url: string | URL, init?: number | ResponseInit): NextResponse
908
+ static rewrite(url: string | URL, init?: ResponseInit): NextResponse
909
+ }
910
+ export type NextFetchEvent = any
911
+ export type NextMiddleware = (...args: any[]) => any
912
+ export type NextMiddlewareResult = any
913
+ export interface ProxyConfig {
914
+ matcher?: string | { source: string } | Array<string | { source: string }>
915
+ }
916
+ export class ImageResponse extends Response {
917
+ constructor(element: any, options?: any)
918
+ }
919
+ export const URLPattern: any
920
+ export function userAgent(request: { headers: Headers }): any
921
+ export function userAgentFromString(ua: string | undefined): any
922
+ export function after(task: any): void
923
+ export function connection(): Promise<void>
924
+ export const io: any
925
+ }
926
+
927
+ declare module 'next/server.js' {
928
+ export * from 'next/server'
929
+ }
930
+
931
+ declare module 'next/navigation.js' {
932
+ export * from 'next/navigation'
933
+ }
934
+
935
+ declare module 'next/headers.js' {
936
+ export * from 'next/headers'
937
+ }
938
+
939
+ declare module 'next/cache.js' {
940
+ export * from 'next/cache'
941
+ }
942
+
943
+ declare module 'next/link.js' {
944
+ export * from 'next/link'
945
+ export { default } from 'next/link'
946
+ }
947
+
948
+ declare module 'next/image.js' {
949
+ export * from 'next/image'
950
+ export { default } from 'next/image'
951
+ }
952
+
953
+ declare module 'next/script.js' {
954
+ export * from 'next/script'
955
+ export { default } from 'next/script'
956
+ }
957
+
958
+ declare module 'next/dist/client/link.js' {
959
+ export interface LinkProps {
960
+ href: any
961
+ }
962
+ export function useLinkStatus(): any
963
+ }
964
+
965
+ declare module 'next/link' {
966
+ import type { AnchorHTMLAttributes, ComponentType } from 'react'
967
+ // Mirror Next's public LinkProps: standard anchor attributes plus Link's own
968
+ // props, but NO catch-all index signature. A wildcard string index signature
969
+ // would silently accept non-public props (e.g. unstable_dynamicOnHover),
970
+ // making a fixture's ts-expect-error on such a prop report as unused.
971
+ export interface LinkProps
972
+ extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {
973
+ href: any
974
+ // Next 16's public prefetch type. The unstable_forceStale value is
975
+ // runtime-only and Next deliberately keeps it OUT of the public union, so an
976
+ // exhaustive switch over prefetch ending in "prefetch satisfies never"
977
+ // stays valid. Including it here would leave that value in the default
978
+ // branch and break such fixtures under our shim.
979
+ prefetch?: boolean | 'auto' | null
980
+ scroll?: boolean
981
+ replace?: boolean
982
+ as?: any
983
+ shallow?: boolean
984
+ passHref?: boolean
985
+ locale?: string | false
986
+ legacyBehavior?: boolean
987
+ onNavigate?: (event: { preventDefault(): void }) => void
988
+ transitionTypes?: string[]
989
+ children?: any
990
+ }
991
+ const Link: ComponentType<LinkProps>
992
+ export default Link
993
+ export function useLinkStatus(): { pending: boolean }
994
+ }
995
+
996
+ declare module 'next/image' {
997
+ import type { ComponentType } from 'react'
998
+ export interface ImageProps {
999
+ src: any
1000
+ alt: string
1001
+ width?: number | string
1002
+ height?: number | string
1003
+ fill?: boolean
1004
+ priority?: boolean
1005
+ loading?: 'lazy' | 'eager'
1006
+ placeholder?: string
1007
+ blurDataURL?: string
1008
+ unoptimized?: boolean
1009
+ sizes?: string
1010
+ quality?: number | string
1011
+ className?: string
1012
+ [key: string]: any
1013
+ }
1014
+ export interface StaticImageData {
1015
+ src: string
1016
+ height: number
1017
+ width: number
1018
+ blurDataURL?: string
1019
+ blurWidth?: number
1020
+ blurHeight?: number
1021
+ }
1022
+ const Image: ComponentType<ImageProps>
1023
+ export default Image
1024
+ export function getImageProps(props: ImageProps): { props: any }
1025
+ export function unstable_getImgProps(props: ImageProps): { props: any }
1026
+ }
1027
+
1028
+ declare module '@vercel/og' {
1029
+ export class ImageResponse extends Response {
1030
+ constructor(element: any, options?: any)
1031
+ }
1032
+ export type ImageResponseOptions = any
1033
+ }
1034
+
1035
+ declare module 'next/og' {
1036
+ export class ImageResponse extends Response {
1037
+ constructor(element: any, options?: any)
1038
+ static json(...args: any[]): ImageResponse
1039
+ }
1040
+ export interface ImageResponseOptions {
1041
+ width?: number
1042
+ height?: number
1043
+ fonts?: any[]
1044
+ debug?: boolean
1045
+ status?: number
1046
+ statusText?: string
1047
+ headers?: HeadersInit
1048
+ emoji?: string
1049
+ [key: string]: any
1050
+ }
1051
+ }
1052
+
1053
+ declare module 'next/dynamic' {
1054
+ import type { ComponentType } from 'react'
1055
+ export interface DynamicOptions {
1056
+ loading?: ComponentType<any>
1057
+ ssr?: boolean
1058
+ loadableGenerated?: any
1059
+ suspense?: boolean
1060
+ [key: string]: any
1061
+ }
1062
+ // Infer P from the loader like real next/dynamic's Loader<P>; a bare
1063
+ // Promise<any> loader would collapse P to any and strip prop types.
1064
+ type LoaderComponent<P> = ComponentType<P> | { default: ComponentType<P> }
1065
+ export default function dynamic<P = {}>(
1066
+ loader: (() => Promise<LoaderComponent<P>>) | Promise<LoaderComponent<P>>,
1067
+ options?: DynamicOptions,
1068
+ ): ComponentType<P>
1069
+ }
1070
+
1071
+ declare module 'next/error' {
1072
+ import type { ComponentType, ReactNode } from 'react'
1073
+ export interface ErrorInfo {
1074
+ error: Error
1075
+ reset: () => void
1076
+ unstable_retry: () => void
1077
+ [key: string]: any
1078
+ }
1079
+ export interface ErrorProps {
1080
+ statusCode: number
1081
+ title?: string
1082
+ withDarkMode?: boolean
1083
+ [key: string]: any
1084
+ }
1085
+ const ErrorComponent: ComponentType<ErrorProps>
1086
+ export default ErrorComponent
1087
+ // Wraps a fallback renderer (props, info) => JSX in an error boundary. The
1088
+ // returned component takes the fallback's own props plus children (the
1089
+ // guarded subtree) and an optional clearError reset callback. Mirrors the
1090
+ // runtime in src/compat/next/error.tsx.
1091
+ export function unstable_catchError<P extends Record<string, any> = any>(
1092
+ fallback: (props: P, info: ErrorInfo) => ReactNode,
1093
+ ): ComponentType<P & { children?: ReactNode; clearError?: () => void }>
1094
+ }
1095
+
1096
+ declare module 'next/font' {
1097
+ export interface FontModule {
1098
+ className: string
1099
+ style: { fontFamily: string; fontWeight?: number; fontStyle?: string }
1100
+ variable: string
1101
+ }
1102
+ }
1103
+
1104
+ declare module 'next/font/local' {
1105
+ import type { FontModule } from 'next/font'
1106
+ export default function localFont(options: any): FontModule
1107
+ }
1108
+
1109
+ declare module 'next/font/google' {
1110
+ import type { FontModule } from 'next/font'
1111
+ type FontLoader = (options?: any) => FontModule
1112
+ const font: FontLoader
1113
+ export default font
1114
+ export const Inter: FontLoader
1115
+ export const Geist: FontLoader
1116
+ export const Geist_Mono: FontLoader
1117
+ export const Roboto: FontLoader
1118
+ export const Roboto_Mono: FontLoader
1119
+ export const Open_Sans: FontLoader
1120
+ export const Lato: FontLoader
1121
+ export const Montserrat: FontLoader
1122
+ export const Poppins: FontLoader
1123
+ export const Noto_Sans: FontLoader
1124
+ }
1125
+
1126
+ declare module 'next/script' {
1127
+ import type { ComponentType } from 'react'
1128
+ export interface ScriptProps {
1129
+ src?: string
1130
+ strategy?: 'afterInteractive' | 'lazyOnload' | 'beforeInteractive' | 'worker'
1131
+ onLoad?: (...args: any[]) => void
1132
+ onReady?: (...args: any[]) => void
1133
+ onError?: (...args: any[]) => void
1134
+ id?: string
1135
+ children?: any
1136
+ [key: string]: any
1137
+ }
1138
+ const Script: ComponentType<ScriptProps>
1139
+ export default Script
1140
+ }
1141
+
1142
+ declare module 'next/legacy/image' {
1143
+ import type { ComponentType } from 'react'
1144
+ export interface ImageProps {
1145
+ src: any
1146
+ alt?: string
1147
+ width?: number | string
1148
+ height?: number | string
1149
+ layout?: 'fixed' | 'intrinsic' | 'responsive' | 'fill'
1150
+ objectFit?: string
1151
+ objectPosition?: string
1152
+ priority?: boolean
1153
+ loading?: 'lazy' | 'eager'
1154
+ placeholder?: string
1155
+ blurDataURL?: string
1156
+ unoptimized?: boolean
1157
+ sizes?: string
1158
+ quality?: number | string
1159
+ [key: string]: any
1160
+ }
1161
+ const Image: ComponentType<ImageProps>
1162
+ export default Image
1163
+ }
1164
+
1165
+ ${rootParamsModule(rootParams)}
1166
+
1167
+ declare module 'next/web-vitals' {
1168
+ export interface NextWebVitalsMetric {
1169
+ id: string
1170
+ name: string
1171
+ startTime: number
1172
+ value: number
1173
+ label: 'web-vital' | 'custom'
1174
+ [key: string]: any
1175
+ }
1176
+ export function useReportWebVitals(reportFn: (metric: NextWebVitalsMetric) => void): void
1177
+ }
1178
+
1179
+ declare module 'next/dist/client/components/app-router-headers' {
1180
+ export const NEXT_RSC_UNION_QUERY: string
1181
+ export const RSC_HEADER: string
1182
+ export const NEXT_ROUTER_STATE_TREE_HEADER: string
1183
+ export const NEXT_ROUTER_PREFETCH_HEADER: string
1184
+ export const NEXT_URL: string
1185
+ const headers: Record<string, string>
1186
+ export default headers
1187
+ }
1188
+
1189
+ declare module 'next/dist/server/app-render/work-unit-async-storage.external' {
1190
+ export const workUnitAsyncStorage: {
1191
+ getStore(): any
1192
+ run<R>(store: any, callback: () => R): R
1193
+ }
1194
+ }
1195
+
1196
+ declare module 'next/dist/server/web/spec-extension/adapters/headers' {
1197
+ export class ReadonlyHeaders extends Headers {}
1198
+ }
1199
+
1200
+ declare module 'next/dist/server/web/spec-extension/adapters/request-cookies' {
1201
+ export interface ReadonlyRequestCookies {
1202
+ get(name: string): { name: string; value: string } | undefined
1203
+ getAll(name?: string): { name: string; value: string }[]
1204
+ has(name: string): boolean
1205
+ readonly size: number
1206
+ [Symbol.iterator](): IterableIterator<[string, { name: string; value: string }]>
1207
+ }
1208
+ }
1209
+
1210
+ declare module 'node-fetch' {
1211
+ export class Headers {
1212
+ get(name: string): string | null
1213
+ has(name: string): boolean
1214
+ set(name: string, value: string): void
1215
+ append(name: string, value: string): void
1216
+ delete(name: string): void
1217
+ forEach(callback: (value: string, name: string) => void): void
1218
+ [Symbol.iterator](): IterableIterator<[string, string]>
1219
+ }
1220
+ const fetch: (...args: any[]) => Promise<any>
1221
+ export default fetch
1222
+ }
1223
+
1224
+ declare module 'next/router' {
1225
+ export interface NextRouter {
1226
+ route: string
1227
+ pathname: string
1228
+ asPath: string
1229
+ query: Record<string, string | string[] | undefined>
1230
+ push(url: any, as?: any, options?: any): Promise<boolean>
1231
+ replace(url: any, as?: any, options?: any): Promise<boolean>
1232
+ prefetch(url: string): Promise<void>
1233
+ back(): void
1234
+ reload(): void
1235
+ beforePopState(callback: (...args: any[]) => boolean): void
1236
+ events: {
1237
+ on(type: string, handler: (...args: any[]) => void): void
1238
+ off(type: string, handler: (...args: any[]) => void): void
1239
+ emit(type: string, ...args: any[]): void
1240
+ }
1241
+ }
1242
+ export function useRouter(): NextRouter
1243
+ const router: NextRouter
1244
+ export default router
1245
+ }
1246
+
1247
+ declare module 'next/app' {
1248
+ // Pages-router shim: pnext builds the app directory only, but fixtures and
1249
+ // hybrid apps may carry a pages/ tree whose _app imports next/app. The type
1250
+ // program includes pages/**, so this keeps the typecheck from failing a
1251
+ // build over files pnext never bundles.
1252
+ export interface AppProps<P = any> {
1253
+ Component: (props: P) => any
1254
+ pageProps: P
1255
+ router?: any
1256
+ [key: string]: any
1257
+ }
1258
+ export type AppType = (props: AppProps) => any
1259
+ const App: AppType
1260
+ export default App
1261
+ }
1262
+
1263
+ declare module 'next/dist/client/components/navigation.js' {
1264
+ export interface NavigateOptions {
1265
+ scroll?: boolean
1266
+ }
1267
+ export interface PrefetchOptions {
1268
+ kind?: 'auto' | 'full'
1269
+ onInvalidate?: () => void
1270
+ }
1271
+ export interface AppRouterInstance {
1272
+ push(href: string, options?: NavigateOptions): void
1273
+ replace(href: string, options?: NavigateOptions): void
1274
+ prefetch(href: string, options?: PrefetchOptions): void
1275
+ refresh(): void
1276
+ back(): void
1277
+ forward(): void
1278
+ bfcacheId: string
1279
+ }
1280
+ export function useRouter(): AppRouterInstance
1281
+ export function notFound(): never
1282
+ }
1283
+
1284
+ declare module 'next/navigation' {
1285
+ export interface NavigateOptions {
1286
+ scroll?: boolean
1287
+ }
1288
+ export interface PrefetchOptions {
1289
+ kind?: 'auto' | 'full'
1290
+ onInvalidate?: () => void
1291
+ }
1292
+ export interface AppRouterInstance {
1293
+ push(href: string, options?: NavigateOptions): void
1294
+ replace(href: string, options?: NavigateOptions): void
1295
+ prefetch(href: string, options?: PrefetchOptions): void
1296
+ refresh(): void
1297
+ back(): void
1298
+ forward(): void
1299
+ bfcacheId: string
1300
+ }
1301
+ export function useRouter(): AppRouterInstance
1302
+ export function usePathname(): string
1303
+ export class ReadonlyURLSearchParams extends URLSearchParams {
1304
+ append(): never
1305
+ delete(): never
1306
+ set(): never
1307
+ sort(): never
1308
+ }
1309
+ export function useSearchParams(): ReadonlyURLSearchParams
1310
+ export function useParams<T = Record<string, string | string[]>>(): T
1311
+ export function useSelectedLayoutSegment(parallelRoutesKey?: string): string | null
1312
+ export function useSelectedLayoutSegments(parallelRoutesKey?: string): string[]
1313
+ export function useLayoutSegments(parallelRoutesKey?: string): string[]
1314
+ export function useLinkStatus(): { pending: boolean }
1315
+ export function unstable_isUnrecognizedActionError(error: unknown): boolean
1316
+ export const RedirectType: { push: 'push'; replace: 'replace' }
1317
+ export type RedirectType = 'push' | 'replace'
1318
+ export function notFound(): never
1319
+ export function forbidden(): never
1320
+ export function unauthorized(): never
1321
+ export function redirect(url: string, type?: RedirectType): never
1322
+ export function permanentRedirect(url: string, type?: RedirectType): never
1323
+ export function unstable_rethrow(error: unknown): void
1324
+ export function useServerInsertedHTML(callback: () => any): void
1325
+ }
1326
+
1327
+ declare module 'next/dist/shared/lib/app-router-context.shared-runtime.js' {
1328
+ export interface NavigateOptions {
1329
+ scroll?: boolean
1330
+ }
1331
+ export interface PrefetchOptions {
1332
+ kind?: 'auto' | 'full'
1333
+ onInvalidate?: () => void
1334
+ }
1335
+ export interface AppRouterInstance {
1336
+ push(href: string, options?: NavigateOptions): void
1337
+ replace(href: string, options?: NavigateOptions): void
1338
+ prefetch(href: string, options?: PrefetchOptions): void
1339
+ refresh(): void
1340
+ back(): void
1341
+ forward(): void
1342
+ bfcacheId: string
1343
+ }
1344
+ }
1345
+
1346
+ declare module 'next/dist/client/components/redirect-error.js' {
1347
+ export type RedirectType = 'replace' | 'push'
1348
+ }
1349
+
1350
+ declare module 'next/dist/client/form.js' {
1351
+ export interface FormProps {
1352
+ action: any
1353
+ }
1354
+ }
1355
+
1356
+ declare module 'next/form' {
1357
+ export interface FormProps {
1358
+ action: string | ((formData: FormData) => void | Promise<void>)
1359
+ replace?: boolean
1360
+ scroll?: boolean
1361
+ prefetch?: boolean
1362
+ [key: string]: any
1363
+ }
1364
+ export default function Form(props: FormProps): any
1365
+ }
1366
+
1367
+ declare module '*.module.css' {
1368
+ const classes: Record<string, string>
1369
+ export default classes
1370
+ }
1371
+
1372
+ declare module '*.module.scss' {
1373
+ const classes: Record<string, string>
1374
+ export default classes
1375
+ }
1376
+
1377
+ declare module '*.module.sass' {
1378
+ const classes: Record<string, string>
1379
+ export default classes
1380
+ }
1381
+
1382
+ declare module '*.css' {
1383
+ const href: string | undefined
1384
+ export default href
1385
+ }
1386
+
1387
+ declare module '*.scss' {
1388
+ const href: string | undefined
1389
+ export default href
1390
+ }
1391
+
1392
+ declare module '*.sass' {
1393
+ const href: string | undefined
1394
+ export default href
1395
+ }
1396
+
1397
+ declare module '*.png' {
1398
+ const content: { src: string; height: number; width: number; blurDataURL?: string }
1399
+ export default content
1400
+ }
1401
+
1402
+ declare module '*.jpg' {
1403
+ const content: { src: string; height: number; width: number; blurDataURL?: string }
1404
+ export default content
1405
+ }
1406
+
1407
+ declare module '*.jpeg' {
1408
+ const content: { src: string; height: number; width: number; blurDataURL?: string }
1409
+ export default content
1410
+ }
1411
+
1412
+ declare module '*.gif' {
1413
+ const content: { src: string; height: number; width: number; blurDataURL?: string }
1414
+ export default content
1415
+ }
1416
+
1417
+ declare module '*.svg' {
1418
+ // \`any\` (not the static-image descriptor shape used above) to avoid
1419
+ // conflicts with \`@svgr/webpack\`-style loader rules that import an SVG as
1420
+ // a component, matching Next's own image-types/global.d.ts.
1421
+ const content: any
1422
+ export default content
1423
+ }
1424
+
1425
+ declare module '*.webp' {
1426
+ const content: { src: string; height: number; width: number; blurDataURL?: string }
1427
+ export default content
1428
+ }
1429
+
1430
+ declare module '*.wasm' {
1431
+ const content: any
1432
+ export default content
1433
+ }
1434
+
1435
+ declare module '*.mdx' {
1436
+ const MDXComponent: (props: any) => any
1437
+ export default MDXComponent
1438
+ }
1439
+
1440
+ declare module '*.md' {
1441
+ const MDXComponent: (props: any) => any
1442
+ export default MDXComponent
1443
+ }
1444
+ ${loaderRuleAssetDeclarations()}`;
1445
+ return omitNextModuleShims ? stripNextModuleDeclarations(source) : source;
1446
+ }
1447
+
1448
+ // Next's generated `next-env.d.ts` carries ambient wildcard module declarations
1449
+ // for every asset extension its loaders/rules handle, so `import x from
1450
+ // './x.data'` typechecks even though tsc has no on-disk `.data` module. pnext's
1451
+ // generated typecheck env ships the standard set above; add one `any`-typed
1452
+ // wildcard per configured `turbopack.rules` extension that the standard set
1453
+ // (and TS's own source/JSON resolution) does not already cover.
1454
+ const STANDARD_ASSET_DECLARATIONS = new Set([
1455
+ '.css', '.scss', '.sass', '.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp',
1456
+ '.wasm', '.mdx', '.md',
1457
+ ]);
1458
+ const TS_RESOLVED_EXTENSIONS = new Set([
1459
+ '.ts', '.tsx', '.mts', '.cts', '.d.ts', '.js', '.jsx', '.mjs', '.cjs', '.json',
1460
+ ]);
1461
+
1462
+ function loaderRuleAssetDeclarations(): string {
1463
+ const specs = new Set<string>();
1464
+ for (const rule of turbopackLoaderRules()) {
1465
+ // Only leading-`*` globs form a valid ambient wildcard module ('*.data').
1466
+ if (!rule.glob.startsWith('*')) continue;
1467
+ const ext = rule.glob.slice(1).toLowerCase();
1468
+ if (STANDARD_ASSET_DECLARATIONS.has(ext) || TS_RESOLVED_EXTENSIONS.has(ext)) continue;
1469
+ specs.add(rule.glob);
1470
+ }
1471
+ if (specs.size === 0) return '';
1472
+ return `${[...specs]
1473
+ .map(
1474
+ spec => `
1475
+ declare module '${spec}' {
1476
+ const content: any
1477
+ export default content
1478
+ }`,
1479
+ )
1480
+ .join('')}\n`;
1481
+ }