@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,392 @@
1
+ // Sass / SCSS compiler (COMPAT).
2
+ //
3
+ // pnext core treats `.scss`/`.sass` as EMPTY modules (no compiler). This module supplies the missing
4
+ // compiler using the optional `sass` package (Dart Sass, JS API), consumed at every CSS build and
5
+ // runtime seam through the CSS-extras registry.
6
+ //
7
+ // Two products, mirroring how core handles `.module.css`:
8
+ // - compileSassCss(file) -> compiled CSS text, module class selectors already rewritten to their
9
+ // scoped names.
10
+ // - sassModuleMapping(file) -> { localClass: scopedClass } for a `.module.scss` / `.module.sass` file.
11
+ //
12
+ // The scoped class-name algorithm is a byte-for-byte replica of core's `cssModuleClassName` so a class
13
+ // referenced in a component matches the selector emitted in the CSS chunk. If core's algorithm changes,
14
+ // this replica MUST change with it.
15
+ //
16
+ // `sass` is an optionalDependency; when absent the module degrades to core's behavior (empty CSS, empty
17
+ // map) so a non-sass app is never broken by loading compat.
18
+
19
+ import { createRequire } from 'node:module';
20
+ import { existsSync, readFileSync } from 'node:fs';
21
+ import path from 'node:path';
22
+ import { resolveImport } from '../../resolve/imports';
23
+ import { nextCssSource } from './modules';
24
+
25
+ // Structural typing of the slice of the Dart Sass JS API we use. Avoids a hard
26
+ // type dependency on the optional `sass` package (mirrors how css.ts/runtime.ts
27
+ // type postcss/sharp via local structural shapes).
28
+ interface SassCompileOptions {
29
+ loadPaths?: string[];
30
+ style?: 'expanded' | 'compressed';
31
+ syntax?: 'scss' | 'indented' | 'css';
32
+ sourceMap?: boolean;
33
+ }
34
+ interface SassCompileResult {
35
+ css: string;
36
+ }
37
+ interface SassApi {
38
+ compile: (path: string, options?: SassCompileOptions) => SassCompileResult;
39
+ compileString: (source: string, options?: SassCompileOptions) => SassCompileResult;
40
+ }
41
+
42
+ const sassApis = new Map<string, SassApi | null>();
43
+
44
+ /** Resolve the optional `sass` package once, from the project root. */
45
+ function loadSass(root: string): SassApi | undefined {
46
+ const cacheKey = path.resolve(root);
47
+ if (sassApis.has(cacheKey)) return sassApis.get(cacheKey) ?? undefined;
48
+ // eslint-disable-next-line turbo/no-undeclared-env-vars
49
+ const roots = [root, path.resolve(import.meta.dirname, '../../..'), process.env.PNEXT_NEXTJS_REPO]
50
+ .filter(
51
+ (candidate): candidate is string => typeof candidate === 'string' && candidate.length > 0,
52
+ )
53
+ .map(candidate => path.join(path.resolve(candidate), 'package.json'));
54
+
55
+ for (const packageJson of roots) {
56
+ try {
57
+ const appRequire = createRequire(packageJson);
58
+ const sass = appRequire('sass') as SassApi;
59
+ sassApis.set(cacheKey, sass);
60
+ return sass;
61
+ } catch {
62
+ // Try the next resolution root.
63
+ }
64
+ }
65
+
66
+ // Not installed / not resolvable — degrade to core's empty-module behavior.
67
+ sassApis.set(cacheKey, null);
68
+ return undefined;
69
+ }
70
+
71
+ /** True for `.scss` / `.sass` (module or global). */
72
+ export function isSassFile(file: string): boolean {
73
+ return /\.(?:scss|sass)$/.test(file);
74
+ }
75
+
76
+ /** True for `.module.scss` / `.module.sass`. */
77
+ export function isSassModuleFile(file: string): boolean {
78
+ return /\.module\.(?:scss|sass)$/.test(file);
79
+ }
80
+
81
+ /**
82
+ * Compile a `.scss`/`.sass` file to CSS. For a `*.module.*` file the class
83
+ * selectors in the compiled output are rewritten to their scoped names so the
84
+ * emitted stylesheet matches the class map a component imports.
85
+ *
86
+ * `includePaths` (Next / node-sass compatibility) are threaded to Dart Sass as
87
+ * `loadPaths`. When `sass` is not installed this returns '' (core's prior
88
+ * empty-module behavior) so the bundle still succeeds.
89
+ */
90
+ export function compileSassCss(file: string, root: string, includePaths: string[] = []): string {
91
+ file = nextCssSource(file, root);
92
+ const sass = loadSass(root);
93
+ if (!sass) return '';
94
+ const compiled = sass.compile(file, {
95
+ loadPaths: [path.dirname(file), ...includePaths],
96
+ style: 'expanded',
97
+ syntax: file.endsWith('.sass') ? 'indented' : 'scss',
98
+ }).css;
99
+
100
+ if (!isSassModuleFile(file)) return compiled;
101
+ return transformCssModule(compiled, file, root, includePaths);
102
+ }
103
+
104
+ /**
105
+ * Compile a `.module.scss`/`.module.sass` and return its `{ local: scoped }`
106
+ * class-name map (parallel to core's `cssModuleMapping` for `.module.css`).
107
+ * Class names are read from the COMPILED css (so classes produced by mixins /
108
+ * `@extend` are included). When `sass` is absent, returns `{}`.
109
+ */
110
+ export function sassModuleMapping(
111
+ file: string,
112
+ root: string,
113
+ includePaths: string[] = [],
114
+ ): Record<string, string> {
115
+ file = nextCssSource(file, root);
116
+ const sass = loadSass(root);
117
+ if (!sass) return {};
118
+ const compiled = sass.compile(file, {
119
+ loadPaths: [path.dirname(file), ...includePaths],
120
+ style: 'expanded',
121
+ syntax: file.endsWith('.sass') ? 'indented' : 'scss',
122
+ }).css;
123
+
124
+ return cssModuleMappingFromSource(compiled, file, root, includePaths);
125
+ }
126
+
127
+ // ---------------------------------------------------------------------------
128
+ // Class-scoping — replicated from src/css/index.ts so scoped names match exactly.
129
+ // ---------------------------------------------------------------------------
130
+
131
+ interface ComposeRef {
132
+ names: string[];
133
+ from?: string;
134
+ }
135
+
136
+ interface CssModuleInfo {
137
+ classes: Set<string>;
138
+ composes: Map<string, ComposeRef[]>;
139
+ dependencies: string[];
140
+ }
141
+
142
+ function cssModuleMappingFromSource(
143
+ source: string,
144
+ file: string,
145
+ root: string,
146
+ includePaths: string[],
147
+ ): Record<string, string> {
148
+ const cache = new Map<string, CssModuleInfo>();
149
+ const info = moduleInfoFromSource(source, file, root);
150
+ cache.set(path.resolve(file), info);
151
+ return Object.fromEntries(
152
+ [...info.classes].map(className => [
153
+ className,
154
+ classValue(file, className, root, includePaths, cache, new Set()),
155
+ ]),
156
+ );
157
+ }
158
+
159
+ function transformCssModule(
160
+ source: string,
161
+ file: string,
162
+ root: string,
163
+ _includePaths: string[],
164
+ ): string {
165
+ const info = moduleInfoFromSource(source, file, root);
166
+ const imports = info.dependencies.map(dep => `@import ${JSON.stringify(dep)};`).join('\n');
167
+ const css = scopeKeyframes(rewriteModuleSelectors(stripComposes(source), file), file);
168
+ return [imports, css].filter(Boolean).join('\n');
169
+ }
170
+
171
+ function moduleInfo(
172
+ file: string,
173
+ root: string,
174
+ includePaths: string[],
175
+ cache: Map<string, CssModuleInfo>,
176
+ ): CssModuleInfo {
177
+ const key = path.resolve(file);
178
+ const cached = cache.get(key);
179
+ if (cached) return cached;
180
+ const source = isSassFile(key)
181
+ ? compileSassCssSource(key, root, includePaths)
182
+ : readFileSync(key, 'utf8');
183
+ const info = moduleInfoFromSource(source, key, root);
184
+ cache.set(key, info);
185
+ return info;
186
+ }
187
+
188
+ function compileSassCssSource(file: string, root: string, includePaths: string[]): string {
189
+ const sass = loadSass(root);
190
+ if (!sass) return '';
191
+ return sass.compile(file, {
192
+ loadPaths: [path.dirname(file), ...includePaths],
193
+ style: 'expanded',
194
+ syntax: file.endsWith('.sass') ? 'indented' : 'scss',
195
+ }).css;
196
+ }
197
+
198
+ function moduleInfoFromSource(source: string, file: string, root: string): CssModuleInfo {
199
+ const classes = cssClassNames(source);
200
+ const composes = new Map<string, ComposeRef[]>();
201
+ const dependencies: string[] = [];
202
+ const seenDependencies = new Set<string>();
203
+ const rulePattern = /(^|})([^{}]+)\{([^{}]*)\}/g;
204
+ let match: RegExpExecArray | null;
205
+
206
+ while ((match = rulePattern.exec(source))) {
207
+ const [, , selector, body] = match;
208
+ if (!selector || !body) continue;
209
+ const localClasses = selectorClassNames(selector).filter(className => classes.has(className));
210
+ if (localClasses.length === 0) continue;
211
+
212
+ for (const ref of composeRefs(body)) {
213
+ for (const localClass of localClasses) {
214
+ const refs = composes.get(localClass) ?? [];
215
+ refs.push(ref);
216
+ composes.set(localClass, refs);
217
+ }
218
+ if (!ref.from || ref.from === 'global') continue;
219
+ const dependency = resolveCssModuleImport(root, file, ref.from);
220
+ if (!dependency || seenDependencies.has(dependency)) continue;
221
+ dependencies.push(dependency);
222
+ seenDependencies.add(dependency);
223
+ }
224
+ }
225
+
226
+ return { classes, composes, dependencies };
227
+ }
228
+
229
+ function classValue(
230
+ file: string,
231
+ className: string,
232
+ root: string,
233
+ includePaths: string[],
234
+ cache: Map<string, CssModuleInfo>,
235
+ stack: Set<string>,
236
+ ): string {
237
+ const key = `${path.resolve(file)}\0${className}`;
238
+ if (stack.has(key)) return cssModuleClassName(file, className);
239
+ stack.add(key);
240
+
241
+ const info = moduleInfo(file, root, includePaths, cache);
242
+ const parts = [cssModuleClassName(file, className)];
243
+ for (const ref of info.composes.get(className) ?? []) {
244
+ if (ref.from === 'global') {
245
+ parts.push(...ref.names);
246
+ continue;
247
+ }
248
+ const refFile = ref.from ? resolveCssModuleImport(root, file, ref.from) : file;
249
+ if (!refFile) continue;
250
+ const refInfo = moduleInfo(refFile, root, includePaths, cache);
251
+ for (const name of ref.names) {
252
+ if (!refInfo.classes.has(name)) continue;
253
+ parts.push(...classValue(refFile, name, root, includePaths, cache, stack).split(/\s+/));
254
+ }
255
+ }
256
+
257
+ stack.delete(key);
258
+ return [...new Set(parts)].join(' ');
259
+ }
260
+
261
+ function composeRefs(body: string): ComposeRef[] {
262
+ const refs: ComposeRef[] = [];
263
+ const pattern = /\bcomposes\s*:\s*([^;]+);/g;
264
+ let match: RegExpExecArray | null;
265
+
266
+ while ((match = pattern.exec(body))) {
267
+ const value = match[1]?.trim();
268
+ if (!value) continue;
269
+ const fromMatch = /^(.+?)\s+from\s+(['"]?)([^'"]+)\2$/.exec(value);
270
+ const names = (fromMatch?.[1] ?? value).split(/\s+/).filter(Boolean);
271
+ if (names.length === 0) continue;
272
+ refs.push({ names, ...(fromMatch?.[3] ? { from: fromMatch[3] } : {}) });
273
+ }
274
+
275
+ return refs;
276
+ }
277
+
278
+ function resolveCssModuleImport(root: string, fromFile: string, specifier: string): string | undefined {
279
+ const resolved = resolveImport(root, fromFile, specifier);
280
+ if (resolved && isCssModuleFile(resolved)) return path.resolve(resolved);
281
+ if (specifier.startsWith('.') || path.isAbsolute(specifier)) return undefined;
282
+
283
+ const sibling = path.resolve(path.dirname(fromFile), specifier);
284
+ return existsSync(sibling) && isCssModuleFile(sibling) ? sibling : undefined;
285
+ }
286
+
287
+ function isCssModuleFile(file: string): boolean {
288
+ return /\.module\.(?:css|scss|sass)$/.test(file);
289
+ }
290
+
291
+ function stripComposes(source: string): string {
292
+ return source.replace(/\s*composes\s*:[^;{}]+;/g, '');
293
+ }
294
+
295
+ function rewriteModuleSelectors(css: string, file: string): string {
296
+ return css.replace(/(^|})([^{}]+)\{/g, (match, boundary: string, selector: string) => {
297
+ if (selector.trimStart().startsWith('@')) return match;
298
+ let out = selector;
299
+ for (const className of selectorClassNames(selector)) {
300
+ out = rewriteClassSelector(out, cssModuleClassName(file, className), className);
301
+ }
302
+ return `${boundary}${out}{`;
303
+ });
304
+ }
305
+
306
+ function cssClassNames(source: string): Set<string> {
307
+ return new Set(selectorClassNames(source.replace(/\{[^{}]*\}/g, '{')));
308
+ }
309
+
310
+ function selectorClassNames(selector: string): string[] {
311
+ const classNames: string[] = [];
312
+ const classPattern = /(^|[\s,>+~])\.(-?[_a-zA-Z][\w-]*)/g;
313
+ let match: RegExpExecArray | null;
314
+ while ((match = classPattern.exec(selector))) {
315
+ if (match[2]) classNames.push(match[2]);
316
+ }
317
+ return classNames;
318
+ }
319
+
320
+ function cssModuleClassName(file: string, className: string): string {
321
+ const base = path
322
+ .basename(file)
323
+ .replace(/\.module\.(?:css|scss|sass)$/, '')
324
+ .replace(/[^_a-zA-Z0-9]/g, '_');
325
+ const hash = pathHash(cssModuleScopePath(file));
326
+ return `${base}_${className}_${hash}`;
327
+ }
328
+
329
+ function scopeKeyframes(css: string, file: string): string {
330
+ let out = css;
331
+ for (const name of keyframeNames(css)) {
332
+ const scoped = cssModuleClassName(file, name);
333
+ out = out.replace(
334
+ new RegExp(`(@(?:-webkit-)?keyframes\\s+)${escapeRegex(name)}(?![-_a-zA-Z0-9])`, 'g'),
335
+ `$1${scoped}`,
336
+ );
337
+ out = out.replace(
338
+ new RegExp(
339
+ `(animation-name\\s*:\\s*)${escapeRegex(name)}(?![-_a-zA-Z0-9])`,
340
+ 'g',
341
+ ),
342
+ `$1${scoped}`,
343
+ );
344
+ out = out.replace(
345
+ new RegExp(
346
+ `(animation\\s*:[^;{}]*?(?<![-_a-zA-Z0-9]))${escapeRegex(name)}(?![-_a-zA-Z0-9])`,
347
+ 'g',
348
+ ),
349
+ `$1${scoped}`,
350
+ );
351
+ }
352
+ return out;
353
+ }
354
+
355
+ function keyframeNames(css: string): Set<string> {
356
+ const names = new Set<string>();
357
+ const pattern = /@(?:-webkit-)?keyframes\s+(-?[_a-zA-Z][\w-]*)/g;
358
+ let match: RegExpExecArray | null;
359
+ while ((match = pattern.exec(css))) {
360
+ if (match[1]) names.add(match[1]);
361
+ }
362
+ return names;
363
+ }
364
+
365
+ function cssModuleScopePath(file: string): string {
366
+ const normalized = file.split(path.sep).join('/');
367
+ const appIndex = normalized.lastIndexOf('/app/');
368
+ if (appIndex !== -1) return normalized.slice(appIndex + 1);
369
+ return normalized.split('/').slice(-3).join('/');
370
+ }
371
+
372
+ function rewriteClassSelector(
373
+ css: string,
374
+ scopedClassName: string,
375
+ originalClassName: string,
376
+ ): string {
377
+ const esbuildNamePattern = new RegExp(
378
+ `\\.${escapeRegex(originalClassName)}(?![-_a-zA-Z0-9])`,
379
+ 'g',
380
+ );
381
+ return css.replace(esbuildNamePattern, `.${scopedClassName}`);
382
+ }
383
+
384
+ function pathHash(file: string): string {
385
+ let hash = 5381;
386
+ for (const char of file) hash = ((hash << 5) + hash) ^ char.charCodeAt(0);
387
+ return (hash >>> 0).toString(36).slice(0, 5);
388
+ }
389
+
390
+ function escapeRegex(value: string): string {
391
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
392
+ }
@@ -0,0 +1,80 @@
1
+ // styled-jsx compat runtime, aliased in place of the styled-jsx package (the css/styled-jsx.ts source
2
+ // transform rewrites <style jsx> blocks to import `style` from here, so apps never install styled-jsx).
3
+ //
4
+ // Two modes:
5
+ // - No <StyleRegistry> mounted: `style` renders an inline <style> tag right where the block appeared.
6
+ // - A <StyleRegistry registry={...}> ancestor (the app-registry pattern): `style` registers its CSS on
7
+ // the registry and renders nothing; the app flushes `registry.styles()` through
8
+ // useServerInsertedHTML so the rules land in the streamed document head. On the client the registry
9
+ // mirrors new rules into document.head imperatively, matching styled-jsx's client runtime.
10
+ import { createContext, h, type ComponentChildren } from 'preact';
11
+ import { useContext } from 'preact/hooks';
12
+
13
+ interface StyleProps {
14
+ id: string;
15
+ children?: ComponentChildren;
16
+ }
17
+
18
+ export class PNextStyleRegistry {
19
+ private rules = new Map<string, string>();
20
+
21
+ add(id: string, css: string): void {
22
+ if (this.rules.has(id)) return;
23
+ this.rules.set(id, css);
24
+ if (typeof document !== 'undefined') {
25
+ const domId = `__jsx-${id}`;
26
+ if (!document.getElementById(domId)) {
27
+ const element = document.createElement('style');
28
+ element.id = domId;
29
+ element.textContent = css;
30
+ document.head.appendChild(element);
31
+ }
32
+ }
33
+ }
34
+
35
+ /** The collected <style> elements, styled-jsx's `registry.styles()` shape. */
36
+ styles() {
37
+ return [...this.rules.entries()].map(([id, css]) =>
38
+ h('style', { id: `__jsx-${id}`, key: `__jsx-${id}` }, css),
39
+ );
40
+ }
41
+
42
+ flush(): void {
43
+ this.rules.clear();
44
+ }
45
+ }
46
+
47
+ const StyleRegistryContext = createContext<PNextStyleRegistry | undefined>(undefined);
48
+
49
+ export function createStyleRegistry(): PNextStyleRegistry {
50
+ return new PNextStyleRegistry();
51
+ }
52
+
53
+ export function StyleRegistry({
54
+ registry,
55
+ children,
56
+ }: {
57
+ registry?: PNextStyleRegistry;
58
+ children?: ComponentChildren;
59
+ }) {
60
+ return h(StyleRegistryContext.Provider, { value: registry ?? createStyleRegistry() }, children);
61
+ }
62
+
63
+ export function useStyleRegistry(): PNextStyleRegistry | undefined {
64
+ return useContext(StyleRegistryContext);
65
+ }
66
+
67
+ export function style({ id, children }: StyleProps) {
68
+ const registry = useContext(StyleRegistryContext);
69
+ if (registry) {
70
+ registry.add(id, childrenToCss(children));
71
+ return null;
72
+ }
73
+ return h('style', { id: `__jsx-${id}` }, children);
74
+ }
75
+
76
+ function childrenToCss(children: ComponentChildren): string {
77
+ if (typeof children === 'string' || typeof children === 'number') return String(children);
78
+ if (Array.isArray(children)) return children.map(childrenToCss).join('');
79
+ return '';
80
+ }
@@ -0,0 +1,49 @@
1
+ import { createHash } from 'node:crypto';
2
+
3
+ import { isIdentifier, uniqueIdentifier } from '../../utils/source';
4
+
5
+ export function rewriteStyledJsxSource(source: string, file: string): string {
6
+ if (!source.includes('<style') || !/\bjsx\b/.test(source)) return source;
7
+
8
+ let next = source;
9
+ for (const match of source.matchAll(
10
+ /import\s+([A-Za-z_$][\w$]*)\s+from\s+['"]styled-jsx\/css['"]\s*;?/g,
11
+ )) {
12
+ const [statement, binding] = match;
13
+ if (!statement || !binding || !isIdentifier(binding)) continue;
14
+ next = next.replace(statement, '');
15
+ next = next.replace(
16
+ new RegExp(`\\b${binding}\`((?:\\\\.|[^\`])*)\``, 'g'),
17
+ (_statement, css: string) => `\`${minifyStaticCss(css)}\``,
18
+ );
19
+ }
20
+
21
+ const component = uniqueIdentifier(next, '__PNextStyledJsx');
22
+ let index = 0;
23
+ next = next.replace(
24
+ /<style\s+(?:global\s+)?jsx\s*>\s*\{([\s\S]*?)\}\s*<\/style>/g,
25
+ (_statement, css: string) => {
26
+ const id = createHash('sha256').update(`${file}:${index++}`).digest('hex').slice(0, 12);
27
+ return `<${component} id=${JSON.stringify(id)}>{${minifyTemplate(css)}}</${component}>`;
28
+ },
29
+ );
30
+ if (index === 0) return source;
31
+
32
+ const directives = /^(?:\s*['"][^'"]+['"];?\s*)*/.exec(next)?.[0] ?? '';
33
+ return `${directives}import { style as ${component} } from 'styled-jsx';\n${next.slice(directives.length)}`;
34
+ }
35
+
36
+ function minifyTemplate(expression: string): string {
37
+ const match = /^\s*`([\s\S]*)`\s*$/.exec(expression);
38
+ if (!match?.[1] || match[1].includes('${')) return expression;
39
+ return `\`${minifyStaticCss(match[1])}\``;
40
+ }
41
+
42
+ function minifyStaticCss(css: string): string {
43
+ if (css.includes('${')) return css;
44
+ return css
45
+ .replace(/\/\*[\s\S]*?\*\//g, '')
46
+ .replace(/\s+/g, ' ')
47
+ .replace(/\s*([{}:;,])\s*/g, '$1')
48
+ .trim();
49
+ }
@@ -0,0 +1,71 @@
1
+ import { reinstallCustomCacheHandlerForEdge } from './cache/custom-handler';
2
+
3
+ type GlobalDescriptor = PropertyDescriptor | undefined;
4
+
5
+ export function withEdgeRuntime<T>(callback: () => T): T {
6
+ const globalObject = globalThis as typeof globalThis & {
7
+ EdgeRuntime?: string;
8
+ process?: NodeJS.Process;
9
+ };
10
+ const previousEdgeRuntime = Object.getOwnPropertyDescriptor(globalObject, 'EdgeRuntime');
11
+ const previousProcess = Object.getOwnPropertyDescriptor(globalObject, 'process');
12
+ const currentProcess = globalObject.process as NodeJS.Process | undefined;
13
+ const edgeProcess = currentProcess
14
+ ? new Proxy(currentProcess, {
15
+ get(target, property, receiver) {
16
+ if (property === 'emit') return undefined;
17
+ // Next's Edge runtime exposes only a minimal `process` polyfill —
18
+ // notably no Node `version`/`versions`. Code that branches on
19
+ // `process.version` (to detect Node vs Edge) must see it absent.
20
+ if (property === 'version' || property === 'versions') return undefined;
21
+ const value: unknown = Reflect.get(target, property, receiver);
22
+ return typeof value === 'function' ? (value as () => unknown).bind(target) : value;
23
+ },
24
+ })
25
+ : undefined;
26
+
27
+ Object.defineProperty(globalObject, 'EdgeRuntime', {
28
+ configurable: true,
29
+ enumerable: false,
30
+ writable: true,
31
+ value: 'edge-runtime',
32
+ });
33
+ Object.defineProperty(globalObject, 'process', {
34
+ configurable: true,
35
+ enumerable: false,
36
+ writable: true,
37
+ value: edgeProcess ?? { env: {} },
38
+ });
39
+
40
+ try {
41
+ reinstallCustomCacheHandlerForEdge();
42
+ const result = callback();
43
+ if (isThenable(result)) {
44
+ return Promise.resolve(result).finally(() =>
45
+ restore(previousEdgeRuntime, previousProcess),
46
+ ) as T;
47
+ }
48
+ restore(previousEdgeRuntime, previousProcess);
49
+ return result;
50
+ } catch (error) {
51
+ restore(previousEdgeRuntime, previousProcess);
52
+ throw error;
53
+ }
54
+ }
55
+
56
+ function restore(edgeRuntime: GlobalDescriptor, process: GlobalDescriptor): void {
57
+ restoreProperty('EdgeRuntime', edgeRuntime);
58
+ restoreProperty('process', process);
59
+ }
60
+
61
+ function restoreProperty(name: 'EdgeRuntime' | 'process', descriptor: GlobalDescriptor): void {
62
+ if (descriptor) {
63
+ Object.defineProperty(globalThis, name, descriptor);
64
+ } else {
65
+ delete (globalThis as Record<string, unknown>)[name];
66
+ }
67
+ }
68
+
69
+ function isThenable<T>(value: T): value is T & PromiseLike<unknown> {
70
+ return typeof (value as { then?: unknown } | null | undefined)?.then === 'function';
71
+ }