@wular/pnext 0.0.3 → 0.0.6

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 (392) hide show
  1. package/README.md +11 -11
  2. package/bin/pnext +1 -1
  3. package/config/lint/base.js +7 -7
  4. package/config/ts/base.json +2 -4
  5. package/config/ts/react.json +2 -6
  6. package/package.json +23 -2
  7. package/reference/compat.md +1 -1
  8. package/reference/config.md +2 -2
  9. package/reference/css.md +13 -9
  10. package/reference/dev.md +1 -1
  11. package/reference/metadata.md +7 -7
  12. package/reference/navigation.md +35 -28
  13. package/reference/performance.md +70 -70
  14. package/reference/rendering.md +17 -17
  15. package/reference/routing.md +17 -17
  16. package/reference/typegen.md +12 -8
  17. package/src/api/cache.ts +36 -37
  18. package/src/api/client-cache.ts +2 -2
  19. package/src/api/client-navigation.ts +113 -109
  20. package/src/api/dynamic.tsx +58 -55
  21. package/src/api/link.tsx +49 -52
  22. package/src/api/navigation.ts +59 -58
  23. package/src/api/server.ts +152 -144
  24. package/src/api/suspense.ts +4 -4
  25. package/src/cli/adapters/vercel-warm.ts +126 -121
  26. package/src/cli/adapters/vercel.ts +437 -443
  27. package/src/cli/analyze.ts +333 -144
  28. package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
  29. package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
  30. package/src/cli/build.ts +976 -978
  31. package/src/cli/create.ts +71 -63
  32. package/src/cli/dev.ts +116 -116
  33. package/src/cli/index.ts +88 -85
  34. package/src/cli/migrate/package-json.ts +73 -71
  35. package/src/cli/migrate/report.ts +32 -33
  36. package/src/cli/migrate/{index.ts → run.ts} +48 -49
  37. package/src/cli/migrate/scan.ts +46 -46
  38. package/src/cli/migrate/spinner.ts +9 -9
  39. package/src/cli/migrate/tsconfig.ts +35 -35
  40. package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
  41. package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
  42. package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
  43. package/src/cli/start.ts +65 -66
  44. package/src/{typegen.ts → cli/typegen.ts} +59 -59
  45. package/src/client/build.ts +794 -768
  46. package/src/client/chunk-fold.ts +245 -240
  47. package/src/client/{paths.ts → chunk-name.ts} +6 -6
  48. package/src/client/entry.ts +162 -147
  49. package/src/client/prebuilt.ts +231 -223
  50. package/src/client/profile.ts +29 -29
  51. package/src/client/react-compiler.ts +20 -15
  52. package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
  53. package/src/client/reference-stub.ts +51 -51
  54. package/src/client/reference.ts +19 -19
  55. package/src/{api → client}/router/events.ts +17 -17
  56. package/src/{api → client}/router/history.ts +16 -16
  57. package/src/{api → client}/router/hub.ts +52 -53
  58. package/src/{api/router.ts → client/router/index.ts} +61 -60
  59. package/src/{api → client}/router/policies.ts +24 -24
  60. package/src/{api → client}/router/runtime.ts +1988 -1961
  61. package/src/{api → client}/router/types.ts +93 -98
  62. package/src/compat/actions/client-plugin.ts +42 -43
  63. package/src/compat/actions/client-stub.ts +14 -14
  64. package/src/compat/actions/{action-client.ts → client.ts} +194 -193
  65. package/src/compat/actions/config.ts +63 -64
  66. package/src/compat/actions/detect.ts +68 -68
  67. package/src/compat/actions/discovery.ts +105 -105
  68. package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
  69. package/src/compat/actions/early-submit.ts +1 -1
  70. package/src/compat/actions/endpoint.ts +198 -198
  71. package/src/compat/actions/extensions.ts +811 -0
  72. package/src/compat/actions/flight.ts +23 -23
  73. package/src/compat/actions/form-state.ts +34 -34
  74. package/src/compat/actions/hoist.ts +382 -236
  75. package/src/compat/actions/ids.ts +7 -12
  76. package/src/compat/actions/index.ts +8 -8
  77. package/src/compat/actions/instances.ts +46 -46
  78. package/src/compat/actions/origin.ts +47 -48
  79. package/src/compat/actions/protocol.ts +22 -22
  80. package/src/compat/actions/registry.ts +19 -19
  81. package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
  82. package/src/compat/actions/rewrite.ts +125 -125
  83. package/src/compat/actions/{action-router.ts → router.ts} +10 -10
  84. package/src/compat/actions/serve.ts +132 -136
  85. package/src/compat/actions/server-tag.ts +4 -4
  86. package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
  87. package/src/compat/actions/unrecognized-error.ts +4 -4
  88. package/src/compat/{index.ts → aliases.ts} +112 -109
  89. package/src/compat/bundler/bun-externals.ts +18 -18
  90. package/src/compat/bundler/cjs-exports.ts +271 -223
  91. package/src/compat/bundler/config.ts +116 -111
  92. package/src/compat/bundler/externals.ts +12 -12
  93. package/src/compat/bundler/import-meta-url.ts +19 -19
  94. package/src/compat/bundler/modularize-imports.ts +36 -33
  95. package/src/compat/bundler/new-url-asset.ts +22 -24
  96. package/src/compat/bundler/optimize-package-imports.ts +111 -107
  97. package/src/compat/bundler/polyfill.ts +28 -28
  98. package/src/compat/bundler/react-compiler.ts +35 -29
  99. package/src/compat/bundler/react-profiler.tsx +11 -11
  100. package/src/compat/bundler/relay-transform.ts +48 -47
  101. package/src/compat/bundler/require-context.ts +119 -113
  102. package/src/compat/bundler/resolve-extensions.ts +19 -19
  103. package/src/compat/bundler/source-cache.ts +25 -25
  104. package/src/compat/bundler/static-imports.ts +7 -7
  105. package/src/compat/bundler/symlink-imports.ts +46 -46
  106. package/src/compat/bundler/tsconfig-paths.ts +13 -15
  107. package/src/compat/bundler/wasm.ts +58 -60
  108. package/src/compat/bundler/webpack-loaders.ts +254 -241
  109. package/src/compat/bundler/worker.ts +101 -104
  110. package/src/compat/cache/build-flags.ts +29 -29
  111. package/src/compat/cache/build-prerender-errors.ts +40 -44
  112. package/src/compat/cache/custom-handler.ts +60 -53
  113. package/src/compat/cache/fetch-patch.ts +240 -240
  114. package/src/compat/cache/handler.ts +27 -31
  115. package/src/compat/cache/modern-handler.ts +148 -126
  116. package/src/compat/cache/resume-data-cache.ts +47 -45
  117. package/src/compat/cache/revalidate.ts +233 -232
  118. package/src/compat/cache/runtime-error.ts +35 -35
  119. package/src/compat/cache/use-cache-transform.ts +442 -417
  120. package/src/compat/cache/use-cache.ts +650 -614
  121. package/src/compat/cache-control.ts +140 -142
  122. package/src/compat/client/base-path.ts +21 -20
  123. package/src/compat/client/css-order.ts +18 -18
  124. package/src/compat/client/errors/bare-boundary.ts +11 -11
  125. package/src/compat/client/errors/control-flow.ts +23 -23
  126. package/src/compat/client/errors/error-boundary.ts +61 -61
  127. package/src/compat/client/errors/global-error.ts +101 -91
  128. package/src/compat/client/errors/install.ts +71 -72
  129. package/src/compat/client/errors/lazy.ts +23 -23
  130. package/src/compat/client/errors/primitive-throw.ts +47 -45
  131. package/src/compat/client/errors/soft-refresh.ts +4 -4
  132. package/src/compat/client/link-status.ts +33 -33
  133. package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
  134. package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
  135. package/src/compat/client/navigation-scroll.ts +63 -63
  136. package/src/compat/client/optimistic-routing.ts +93 -88
  137. package/src/compat/client/prefetch-cache.ts +23 -24
  138. package/src/compat/client/route-announcer.ts +35 -35
  139. package/src/compat/client/segment-cache-policy.ts +20 -20
  140. package/src/compat/client/segment-cache.ts +309 -315
  141. package/src/compat/client/segment-prefetch.ts +127 -132
  142. package/src/compat/client/trailing-slash.ts +5 -4
  143. package/src/compat/css/chunking.ts +113 -116
  144. package/src/compat/css/inline-css.ts +21 -21
  145. package/src/compat/css/lightningcss.ts +37 -38
  146. package/src/compat/css/modules.ts +161 -175
  147. package/src/compat/css/nonce.ts +7 -7
  148. package/src/compat/css/sass-plugin.ts +18 -21
  149. package/src/compat/css/sass.ts +150 -152
  150. package/src/compat/css/styled-jsx-runtime.ts +27 -27
  151. package/src/compat/css/styled-jsx.ts +21 -21
  152. package/src/compat/edge-runtime.ts +27 -27
  153. package/src/compat/{adapter → export}/build-complete.ts +72 -75
  154. package/src/compat/export/client.ts +29 -31
  155. package/src/compat/export/{index.ts → emit.ts} +111 -110
  156. package/src/compat/export/standalone.ts +62 -54
  157. package/src/compat/image-optimizer/cache.ts +51 -49
  158. package/src/compat/image-optimizer/detect.ts +52 -52
  159. package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
  160. package/src/compat/image-optimizer/source.ts +77 -80
  161. package/src/compat/lifecycle/after-scope.ts +26 -26
  162. package/src/compat/lifecycle/after.ts +48 -45
  163. package/src/compat/lifecycle/error-funnel.ts +98 -102
  164. package/src/compat/lifecycle/error-serialize.ts +30 -26
  165. package/src/compat/lifecycle/error-ui.ts +67 -32
  166. package/src/compat/lifecycle/instrumentation-client.ts +36 -38
  167. package/src/compat/lifecycle/instrumentation.ts +85 -85
  168. package/src/compat/lifecycle/node-console.ts +11 -11
  169. package/src/compat/lifecycle/testmode.ts +160 -132
  170. package/src/compat/mdx/compile.ts +60 -57
  171. package/src/compat/mdx/plugin.ts +11 -11
  172. package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
  173. package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
  174. package/src/compat/metadata.ts +75 -81
  175. package/src/compat/next/cache.ts +68 -69
  176. package/src/compat/next/canonical-url.ts +9 -9
  177. package/src/compat/next/client-cache.ts +19 -19
  178. package/src/compat/next/client-navigation.ts +112 -116
  179. package/src/compat/next/client-only.ts +1 -1
  180. package/src/compat/next/client-script.tsx +99 -93
  181. package/src/compat/next/client-server.ts +10 -10
  182. package/src/compat/next/config-loader.ts +176 -173
  183. package/src/compat/next/config.ts +7 -7
  184. package/src/compat/next/constants.cjs +6 -6
  185. package/src/compat/next/constants.ts +6 -6
  186. package/src/compat/next/custom-server.ts +26 -24
  187. package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
  188. package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
  189. package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
  190. package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
  191. package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
  192. package/src/compat/next/dynamic.tsx +21 -18
  193. package/src/compat/next/error.tsx +52 -52
  194. package/src/compat/next/font/cache.ts +74 -74
  195. package/src/compat/next/font/google.ts +2 -2
  196. package/src/compat/next/font/index.ts +1 -1
  197. package/src/compat/next/font/local.ts +3 -3
  198. package/src/compat/next/font/runtime-client.ts +17 -15
  199. package/src/compat/next/font/runtime.ts +443 -408
  200. package/src/compat/next/font/shared.ts +120 -108
  201. package/src/compat/next/form.tsx +63 -63
  202. package/src/compat/next/head.tsx +2 -2
  203. package/src/compat/next/headers.ts +103 -95
  204. package/src/compat/next/image/client.tsx +220 -0
  205. package/src/compat/next/image/config.ts +56 -58
  206. package/src/compat/next/image/optimizer.ts +40 -36
  207. package/src/compat/next/image/patterns.ts +37 -40
  208. package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
  209. package/src/compat/next/image/shared.ts +65 -57
  210. package/src/compat/next/image/static-metadata.ts +98 -107
  211. package/src/compat/next/image/validate.ts +79 -88
  212. package/src/compat/next/image.tsx +19 -23
  213. package/src/compat/next/index.ts +1 -1
  214. package/src/compat/next/legacy-image.tsx +59 -60
  215. package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
  216. package/src/compat/next/link.tsx +158 -158
  217. package/src/compat/next/navigation.cjs +12 -3
  218. package/src/compat/next/navigation.ts +48 -50
  219. package/src/compat/next/offline.ts +27 -27
  220. package/src/compat/next/og.ts +121 -124
  221. package/src/compat/next/preferred-region.ts +13 -14
  222. package/src/compat/next/redirects.ts +58 -56
  223. package/src/compat/next/resource-hints.ts +73 -76
  224. package/src/compat/next/rewrites.ts +130 -133
  225. package/src/compat/next/root-params.ts +45 -45
  226. package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
  227. package/src/compat/next/router.cjs +4 -2
  228. package/src/compat/next/router.ts +58 -61
  229. package/src/compat/next/script.tsx +108 -108
  230. package/src/compat/next/server-only.ts +1 -1
  231. package/src/compat/next/server.ts +19 -19
  232. package/src/compat/next/svgr.ts +18 -17
  233. package/src/compat/next/telemetry.ts +24 -24
  234. package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
  235. package/src/compat/next/user-agent.ts +53 -49
  236. package/src/compat/next/web-vitals.ts +22 -24
  237. package/src/compat/otel/api.ts +41 -41
  238. package/src/compat/otel/client-trace-metadata.ts +25 -27
  239. package/src/compat/otel/fetch-span.ts +29 -29
  240. package/src/compat/otel/tracer.ts +331 -331
  241. package/src/compat/pages/api.ts +456 -0
  242. package/src/compat/pages/client-plugin.ts +36 -36
  243. package/src/compat/pages/router-state.ts +34 -34
  244. package/src/compat/pages/{index.ts → router.ts} +130 -135
  245. package/src/compat/ppr/io.ts +12 -12
  246. package/src/compat/ppr/missing-root-params.ts +34 -38
  247. package/src/compat/ppr/root-params-scan.ts +66 -66
  248. package/src/compat/ppr/root-params-transform.ts +24 -26
  249. package/src/compat/ppr/root-params.ts +30 -30
  250. package/src/compat/ppr/segment-config-incompat.ts +6 -7
  251. package/src/compat/protocol.ts +71 -70
  252. package/src/compat/react/action-state.ts +47 -48
  253. package/src/compat/react/client-lite.ts +15 -15
  254. package/src/compat/react/client.ts +4 -4
  255. package/src/compat/react/compiler-runtime.ts +11 -11
  256. package/src/compat/react/dom-client.ts +44 -44
  257. package/src/compat/react/dom-react-server.ts +10 -16
  258. package/src/compat/react/dom-server.ts +10 -10
  259. package/src/compat/react/dom.ts +52 -52
  260. package/src/compat/react/hooks-extra.ts +34 -35
  261. package/src/compat/react/parity.ts +64 -61
  262. package/src/compat/react/preact.ts +81 -82
  263. package/src/compat/react/react-server.ts +28 -28
  264. package/src/compat/react/router-shim.ts +1 -1
  265. package/src/compat/react/server-component-use.ts +8 -8
  266. package/src/compat/react/server-inserted-html.ts +30 -31
  267. package/src/compat/react/server.ts +53 -55
  268. package/src/compat/react/use.ts +32 -32
  269. package/src/compat/react/view-transition.ts +20 -20
  270. package/src/compat/register/actions.ts +35 -824
  271. package/src/compat/register/boot.ts +41 -41
  272. package/src/compat/register/build-tier.ts +5 -5
  273. package/src/compat/register/build.ts +74 -70
  274. package/src/compat/register/bundler.ts +161 -156
  275. package/src/compat/register/cache.ts +20 -20
  276. package/src/compat/register/client-errors.ts +3 -3
  277. package/src/compat/register/config.ts +6 -6
  278. package/src/compat/register/css-extras.ts +30 -34
  279. package/src/compat/register/edge-runtime.ts +3 -3
  280. package/src/compat/register/errors.ts +10 -12
  281. package/src/compat/register/export.ts +16 -16
  282. package/src/compat/register/font.ts +11 -11
  283. package/src/compat/register/hooks.ts +2 -2
  284. package/src/compat/register/image.ts +40 -40
  285. package/src/compat/register/index.ts +59 -62
  286. package/src/compat/register/instrumentation-client.ts +10 -10
  287. package/src/compat/register/lifecycle.ts +25 -28
  288. package/src/compat/register/mdx.ts +10 -10
  289. package/src/compat/register/middleware.ts +226 -16
  290. package/src/compat/register/otel.ts +80 -88
  291. package/src/compat/register/pages-api.ts +10 -463
  292. package/src/compat/register/ppr.ts +16 -16
  293. package/src/compat/register/protocol.ts +17 -18
  294. package/src/compat/register/proxy.ts +49 -51
  295. package/src/compat/register/render.ts +79 -76
  296. package/src/compat/register/routing.ts +162 -159
  297. package/src/compat/register/segment.ts +24 -1887
  298. package/src/compat/register/static-image.ts +3 -3
  299. package/src/compat/register/{misc.ts → taint.ts} +9 -9
  300. package/src/compat/register/typed-routes.ts +14 -14
  301. package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
  302. package/src/compat/register/validation.ts +18 -18
  303. package/src/compat/segment/loading-boundary.ts +43 -45
  304. package/src/compat/segment/page-slot.ts +69 -69
  305. package/src/compat/segment/serve.ts +1884 -0
  306. package/src/compat/segment/tree.ts +113 -112
  307. package/src/compat/segment/vary-key.ts +38 -38
  308. package/src/compat/segment/vary-params.ts +138 -142
  309. package/src/compat/static-params.ts +14 -12
  310. package/src/compat/tsconfig-defaults.ts +87 -91
  311. package/src/compat/typecheck/{index.ts → check.ts} +234 -212
  312. package/src/compat/typecheck/worker.ts +15 -12
  313. package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
  314. package/src/compat/typed-routes/manifest.ts +174 -170
  315. package/src/compat/typed-routes/typegen.ts +127 -110
  316. package/src/compat/validation/errors.ts +16 -19
  317. package/src/compat/validation/prerender-diagnostics.ts +521 -504
  318. package/src/compat/validation/{index.ts → validate.ts} +647 -648
  319. package/src/compat-bootstrap.ts +16 -16
  320. package/src/config.ts +69 -69
  321. package/src/css/build.ts +230 -227
  322. package/src/css/postcss.ts +79 -80
  323. package/src/css/worker.ts +14 -15
  324. package/src/dev/client-actions.ts +10 -10
  325. package/src/dev/client-chunk-store.ts +27 -27
  326. package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
  327. package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
  328. package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
  329. package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
  330. package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
  331. package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
  332. package/src/dev/server.ts +804 -820
  333. package/src/env.ts +46 -43
  334. package/src/extensions.ts +491 -478
  335. package/src/index.ts +8 -8
  336. package/src/internal.ts +20 -23
  337. package/src/{islands → render}/boundary-error.ts +3 -3
  338. package/src/render/hooks.ts +71 -71
  339. package/src/render/island-context.ts +14 -14
  340. package/src/render/metadata.ts +310 -310
  341. package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
  342. package/src/{ppr.ts → render/ppr.ts} +244 -245
  343. package/src/render/renderer.ts +2076 -2082
  344. package/src/render/resource-hints.ts +16 -17
  345. package/src/render/slots.tsx +224 -235
  346. package/src/{islands → render}/static-children.ts +9 -12
  347. package/src/{islands → render}/static-slots.ts +37 -37
  348. package/src/{cache/context.ts → request/cache.ts} +20 -20
  349. package/src/request/context.ts +107 -107
  350. package/src/{dynamic/source.ts → resolve/dynamic.ts} +152 -143
  351. package/src/resolve/engine.ts +90 -77
  352. package/src/resolve/imports.ts +475 -463
  353. package/src/resolve/scan-facts.ts +442 -186
  354. package/src/resolve/source-text.ts +37 -37
  355. package/src/{dynamic → resolve}/tree-shake.ts +132 -128
  356. package/src/routing/forwarded.ts +19 -19
  357. package/src/routing/handler.ts +84 -91
  358. package/src/routing/href.ts +69 -70
  359. package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
  360. package/src/{proxy.ts → routing/proxy.ts} +306 -312
  361. package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
  362. package/src/routing/routes.ts +833 -848
  363. package/src/routing/slots.ts +164 -160
  364. package/src/runtime/loader.ts +952 -0
  365. package/src/{dev → runtime}/module-cache.ts +309 -287
  366. package/src/{dev → runtime}/module-generations.ts +9 -9
  367. package/src/{dev → runtime}/module-transform.ts +81 -72
  368. package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
  369. package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
  370. package/src/runtime/vendor.ts +425 -404
  371. package/src/styles.d.ts +9 -0
  372. package/src/types.ts +320 -335
  373. package/src/utils/ansi.ts +5 -5
  374. package/src/utils/{source.ts → code.ts} +15 -12
  375. package/src/utils/content-type.ts +3 -3
  376. package/src/utils/decode.ts +2 -2
  377. package/src/utils/dev-profile.ts +13 -13
  378. package/src/utils/error-log.ts +6 -6
  379. package/src/utils/esbuild.ts +18 -18
  380. package/src/utils/fs-cache.ts +13 -13
  381. package/src/utils/fs.ts +57 -49
  382. package/src/utils/html.ts +20 -24
  383. package/src/utils/native-require.ts +8 -8
  384. package/src/utils/serialize.ts +139 -146
  385. package/src/utils/verbose.ts +18 -18
  386. package/src/cli/analyze-print.ts +0 -181
  387. package/src/compat/middleware/manifest.ts +0 -210
  388. package/src/compat/next/image-client.tsx +0 -215
  389. package/src/compat/next/link-usage.ts +0 -29
  390. package/src/css/index.ts +0 -2
  391. package/src/render/index.ts +0 -1
  392. package/src/style-modules.d.ts +0 -9
@@ -1,29 +1,29 @@
1
- import type { Plugin } from 'esbuild';
2
- import { readFileSync } from 'node:fs';
3
- import { readFile } from 'node:fs/promises';
4
- import { dirname, extname, isAbsolute } from 'node:path';
1
+ import type { Plugin } from 'esbuild'
2
+ import { readFileSync } from 'node:fs'
3
+ import { readFile } from 'node:fs/promises'
4
+ import { dirname, extname, isAbsolute } from 'node:path'
5
5
 
6
6
  import {
7
7
  isCommonJsModuleSource,
8
8
  providedEntryResolution,
9
9
  resolveLinkedPackageSpecifier,
10
10
  resolveRuntimeSpecifier,
11
- } from '../../resolve/imports';
12
- import { rewriteFacts } from '../../resolve/scan-facts';
13
- import { spliceSource } from '../../dev/module-transform';
14
- import { clientReferenceId } from '../../client/reference';
15
- import { hasUseClientDirective } from '../../client/reference-stub';
16
- import { isIdentifier, uniqueIdentifier } from '../../utils/source';
17
- import { fileMemo, fileMemoAsync } from './source-cache';
11
+ } from '../../resolve/imports'
12
+ import { rewriteFacts } from '../../resolve/scan-facts'
13
+ import { spliceSource } from '../../runtime/module-transform'
14
+ import { clientReferenceId } from '../../client/reference'
15
+ import { hasUseClientDirective } from '../../client/reference-stub'
16
+ import { isIdentifier, uniqueIdentifier } from '../../utils/code'
17
+ import { fileMemo, fileMemoAsync } from './source-cache'
18
18
 
19
- const encoder = new TextEncoder();
20
- const decoder = new TextDecoder();
19
+ const encoder = new TextEncoder()
20
+ const decoder = new TextDecoder()
21
21
 
22
22
  // esbuild treats a CommonJS entry point as `module.exports`, bypassing its
23
23
  // normal `__esModule` default-import interop. Route CJS package entries through
24
24
  // a JavaScript ESM facade so Babel/TypeScript-shaped modules expose
25
25
  // `exports.default`, while ordinary CJS continues to expose `module.exports`.
26
- const interopEntryPrefix = 'pnext-cjs-interop:';
26
+ const interopEntryPrefix = 'pnext-cjs-interop:'
27
27
 
28
28
  /**
29
29
  * Entry-point CJS classification, done ONCE where the caller already knows the entry - the marker keeps
@@ -36,9 +36,9 @@ export function commonJsInteropEntry(
36
36
  resolved?: string,
37
37
  ): string | undefined {
38
38
  const classified =
39
- resolved ?? (isAbsolute(specifier) ? specifier : resolveEntryPath(specifier, resolveDir));
40
- if (!classified || !isCommonJsJavaScriptFile(classified)) return undefined;
41
- return interopEntryPrefix + specifier;
39
+ resolved ?? (isAbsolute(specifier) ? specifier : resolveEntryPath(specifier, resolveDir))
40
+ if (!classified || !isCommonJsJavaScriptFile(classified)) return undefined
41
+ return interopEntryPrefix + specifier
42
42
  }
43
43
 
44
44
  export function commonJsDefaultInteropPlugin(): Plugin {
@@ -46,29 +46,29 @@ export function commonJsDefaultInteropPlugin(): Plugin {
46
46
  name: 'pnext-cjs-default-interop',
47
47
  setup(build) {
48
48
  build.onResolve({ filter: /^pnext-cjs-interop:/ }, args => {
49
- const source = args.path.slice(interopEntryPrefix.length);
49
+ const source = args.path.slice(interopEntryPrefix.length)
50
50
  const resolved = isAbsolute(source)
51
51
  ? source
52
- : resolveEntryPath(source, args.resolveDir || process.cwd());
52
+ : resolveEntryPath(source, args.resolveDir || process.cwd())
53
53
  return {
54
54
  path: `${source}.pnext-cjs-default-interop.js`,
55
55
  namespace: 'pnext-cjs-default-interop',
56
56
  pluginData: { source, resolved: resolved ?? source },
57
- };
58
- });
57
+ }
58
+ })
59
59
  build.onLoad({ filter: /.*/, namespace: 'pnext-cjs-default-interop' }, args => {
60
- const data = args.pluginData as { source?: string; resolved?: string } | undefined;
61
- const source = data?.source ?? args.path;
60
+ const data = args.pluginData as { source?: string; resolved?: string } | undefined
61
+ const source = data?.source ?? args.path
62
62
  // The facade's `export default` alone breaks a consumer's named import
63
63
  // (`import { Network } from 'relay-runtime'`), so mirror the entry's
64
64
  // statically discoverable CommonJS keys as named exports too. Read them
65
65
  // from the *resolved* file — `source` may be a bare specifier.
66
- const names = data?.resolved ? namedFacadeExportNames(data.resolved) : [];
67
- const namespaceName = '__pnext_cjs_ns';
66
+ const names = data?.resolved ? namedFacadeExportNames(data.resolved) : []
67
+ const namespaceName = '__pnext_cjs_ns'
68
68
  const bindings = names.map((name, index) => ({
69
69
  name,
70
70
  localName: `__pnext_cjs_named_${index}`,
71
- }));
71
+ }))
72
72
  return {
73
73
  contents: [
74
74
  `const value = require(${JSON.stringify(source)});`,
@@ -80,8 +80,8 @@ export function commonJsDefaultInteropPlugin(): Plugin {
80
80
  // is undefined). Read names off `value`, falling back to the
81
81
  // namespace for packages that expose them only under `.default`.
82
82
  ...bindings.map(({ name, localName }) => {
83
- const key = JSON.stringify(name);
84
- return `const ${localName} = value != null && value[${key}] !== undefined ? value[${key}] : (${namespaceName} == null ? undefined : ${namespaceName}[${key}]);`;
83
+ const key = JSON.stringify(name)
84
+ return `const ${localName} = value != null && value[${key}] !== undefined ? value[${key}] : (${namespaceName} == null ? undefined : ${namespaceName}[${key}]);`
85
85
  }),
86
86
  ...(bindings.length > 0
87
87
  ? [
@@ -97,10 +97,10 @@ export function commonJsDefaultInteropPlugin(): Plugin {
97
97
  // not walk up for node_modules from it; unscoped only worked by
98
98
  // accident ('pkg' -> '.'). Anchor on the resolved file.
99
99
  resolveDir: dirname(data?.resolved ?? source),
100
- };
101
- });
100
+ }
101
+ })
102
102
  },
103
- };
103
+ }
104
104
  }
105
105
 
106
106
  /**
@@ -109,75 +109,73 @@ export function commonJsDefaultInteropPlugin(): Plugin {
109
109
  * client reference" after a full read the bundler then repeats itself.
110
110
  */
111
111
  export const clientReferenceLoad = fileMemoAsync(async (file: string) => {
112
- let bytes: Buffer;
112
+ let bytes: Buffer
113
113
  try {
114
- bytes = await readFile(file);
114
+ bytes = await readFile(file)
115
115
  } catch {
116
- return undefined;
116
+ return undefined
117
117
  }
118
118
  // Almost every file the bundler loads has no directive at all. Search the
119
119
  // raw bytes for the only string one can be spelled with, and decode (plus
120
120
  // run the real directive-prologue test) for the few that could.
121
- if (!bytes.includes('use client')) return undefined;
122
- const source = bytes.toString('utf8');
123
- if (!isCommonJsModuleSource(source, file) || !hasUseClientDirective(source)) return undefined;
121
+ if (!bytes.includes('use client')) return undefined
122
+ const source = bytes.toString('utf8')
123
+ if (!isCommonJsModuleSource(source, file) || !hasUseClientDirective(source)) return undefined
124
124
  const references = commonJsExportNames(source)
125
125
  .map(name => {
126
- const value = name === 'default' ? 'exports.default' : `exports[${JSON.stringify(name)}]`;
126
+ const value = name === 'default' ? 'exports.default' : `exports[${JSON.stringify(name)}]`
127
127
  const reference = JSON.stringify({
128
128
  id: `c-${clientReferenceId(file, name)}`,
129
129
  file,
130
130
  exportName: name,
131
- });
132
- return `if (typeof ${value} === "function") ${value}[Symbol.for("pnext.clientReference")] = ${reference};`;
131
+ })
132
+ return `if (typeof ${value} === "function") ${value}[Symbol.for("pnext.clientReference")] = ${reference};`
133
133
  })
134
- .join('\n');
134
+ .join('\n')
135
135
  return {
136
136
  contents: references ? `${source}\n${references}\n` : source,
137
137
  loader: 'js' as const,
138
138
  resolveDir: dirname(file),
139
- };
140
- });
139
+ }
140
+ })
141
141
 
142
142
  export function commonJsClientReferencePlugin(): Plugin {
143
143
  return {
144
144
  name: 'pnext-cjs-client-references',
145
145
  setup(build) {
146
- build.onLoad({ filter: /\.c?js$/, namespace: 'file' }, args =>
147
- clientReferenceLoad(args.path),
148
- );
146
+ build.onLoad({ filter: /\.c?js$/, namespace: 'file' }, args => clientReferenceLoad(args.path))
149
147
  },
150
- };
148
+ }
151
149
  }
152
150
 
153
151
  const isCommonJsJavaScriptFile = fileMemo((file: string) => {
154
152
  try {
155
- return isCommonJsModuleSource(readFileSync(file, 'utf8'), file);
153
+ return isCommonJsModuleSource(readFileSync(file, 'utf8'), file)
156
154
  } catch {
157
- return true;
155
+ return true
158
156
  }
159
- });
157
+ })
160
158
 
161
159
  /** Entry classification is per (specifier, resolveDir) and never changes. */
162
- const entryResolutions = new Map<string, string | undefined>();
160
+ const entryResolutions = new Map<string, string | undefined>()
163
161
 
164
162
  function resolveEntryPath(specifier: string, resolveDir: string) {
165
- const key = `${specifier}\0${resolveDir}`;
166
- if (entryResolutions.has(key)) return entryResolutions.get(key);
163
+ const key = `${specifier}\0${resolveDir}`
164
+ if (entryResolutions.has(key)) return entryResolutions.get(key)
167
165
  // The vendor build already resolved bare entry specifiers; never re-resolve.
168
- const provided = providedEntryResolution(specifier, resolveDir);
166
+ const provided = providedEntryResolution(specifier, resolveDir)
169
167
  if (provided) {
170
- entryResolutions.set(key, provided);
171
- return provided;
168
+ entryResolutions.set(key, provided)
169
+ return provided
172
170
  }
173
- let resolved: string | undefined;
171
+ let resolved: string | undefined
174
172
  try {
175
- resolved = Bun.resolveSync(specifier, resolveDir);
173
+ resolved = Bun.resolveSync(specifier, resolveDir)
176
174
  } catch {
177
- resolved = undefined;
175
+ resolved = undefined
178
176
  }
179
- entryResolutions.set(key, resolved);
180
- return resolved;
177
+ entryResolutions.set(key, resolved)
178
+ return resolved
181
179
  }
182
180
 
183
181
  // esbuild turns a bundled CommonJS dependency into an ESM wrapper whose
@@ -186,38 +184,38 @@ function resolveEntryPath(specifier: string, resolveDir: string) {
186
184
  // own `.default` value (when present) as `namespace.default`. Dynamic import
187
185
  // intentionally retains the native ESM-wrapper namespace and is left alone.
188
186
  export function rewriteStaticCommonJsNamespaceImports(source: string, file: string): string {
189
- const facts = rewriteFacts(file, source);
190
- const edits: { start: number; end: number; value: string }[] = [];
191
- const taken: string[] = [];
187
+ const facts = rewriteFacts(file, source)
188
+ const edits: { start: number; end: number; value: string }[] = []
189
+ const taken: string[] = []
192
190
  for (const statement of facts.imports) {
193
191
  // Namespace-only: `import d, * as ns from 'x'` would lose its default.
194
- const binding = statement.bindings[0];
195
- if (statement.bindings.length !== 1 || binding?.imported !== '*') continue;
196
- if (!isCommonJsImport(statement.specifier, file)) continue;
197
-
198
- const defaultBinding = uniqueIdentifier(source, '__pnext_cjs_namespace_default', ...taken);
199
- taken.push(defaultBinding);
200
- const quote = source[statement.specifierStart] ?? "'";
201
- const indent = statementIndent(source, statement.start);
192
+ const binding = statement.bindings[0]
193
+ if (statement.bindings.length !== 1 || binding?.imported !== '*') continue
194
+ if (!isCommonJsImport(statement.specifier, file)) continue
195
+
196
+ const defaultBinding = uniqueIdentifier(source, '__pnext_cjs_namespace_default', ...taken)
197
+ taken.push(defaultBinding)
198
+ const quote = source[statement.specifierStart] ?? "'"
199
+ const indent = statementIndent(source, statement.start)
202
200
  edits.push({
203
201
  start: statement.start,
204
202
  end: statement.end,
205
203
  value: `import ${defaultBinding} from ${quote}${statement.specifier}${quote};\n${indent}const ${binding.local} = { ...${defaultBinding} };`,
206
- });
204
+ })
207
205
  }
208
- return edits.length > 0 ? spliceSource(source, edits) : source;
206
+ return edits.length > 0 ? spliceSource(source, edits) : source
209
207
  }
210
208
 
211
209
  /** Leading whitespace of the line the statement starts on. */
212
210
  function statementIndent(source: string, start: number) {
213
- const lineStart = source.lastIndexOf('\n', start - 1) + 1;
214
- const indent = source.slice(lineStart, start);
215
- return /^[\t ]*$/.test(indent) ? indent : '';
211
+ const lineStart = source.lastIndexOf('\n', start - 1) + 1
212
+ const indent = source.slice(lineStart, start)
213
+ return /^[\t ]*$/.test(indent) ? indent : ''
216
214
  }
217
215
 
218
216
  function isCommonJsImport(specifier: string, file: string): boolean {
219
- const resolved = resolveRuntimeSpecifier(dirname(file), specifier);
220
- return resolved !== undefined && extname(resolved) === '.cjs';
217
+ const resolved = resolveRuntimeSpecifier(dirname(file), specifier)
218
+ return resolved !== undefined && extname(resolved) === '.cjs'
221
219
  }
222
220
 
223
221
  export function recoverCommonJsNamedExportsPlugin(): Plugin {
@@ -225,16 +223,16 @@ export function recoverCommonJsNamedExportsPlugin(): Plugin {
225
223
  name: 'pnext-recover-cjs-named-exports',
226
224
  setup(build) {
227
225
  build.onEnd(result => {
228
- const output = result.outputFiles?.[0];
229
- if (!output) return;
230
- const next = recoverCommonJsNamedExports(decoder.decode(output.contents));
226
+ const output = result.outputFiles?.[0]
227
+ if (!output) return
228
+ const next = recoverCommonJsNamedExports(decoder.decode(output.contents))
231
229
  if (next === decoder.decode(output.contents)) {
232
- return;
230
+ return
233
231
  }
234
- output.contents = encoder.encode(next);
235
- });
232
+ output.contents = encoder.encode(next)
233
+ })
236
234
  },
237
- };
235
+ }
238
236
  }
239
237
 
240
238
  // esbuild's native CommonJS dynamic-import facade only exports `default`. Webpack's namespace has the
@@ -245,7 +243,7 @@ export function recoverCommonJsNamedExportsPlugin(): Plugin {
245
243
  // The filter admits any specifier that can still land on a `.cjs` file: a bare package name, a path
246
244
  // whose final segment carries no extension, or an explicit `.cjs`. Anything ending in another extension
247
245
  // is excluded in the FILTER - esbuild's Go regexp has no lookahead, so the rule is spelled positively.
248
- const dynamicCjsCandidate = /^[^./]|(^|\/)[^/.]+$|\.cjs([?#]|$)/;
246
+ const dynamicCjsCandidate = /^[^./]|(^|\/)[^/.]+$|\.cjs([?#]|$)/
249
247
 
250
248
  export function clientDynamicCommonJsImportsPlugin(root: string): Plugin {
251
249
  return {
@@ -254,9 +252,9 @@ export function clientDynamicCommonJsImportsPlugin(root: string): Plugin {
254
252
  // Per-BUILD memo of the whole classification. Each miss walks node_modules, probes package
255
253
  // targets and may parse the file for its CJS export names, overwhelmingly for the same handful
256
254
  // of lazily-imported specifiers.
257
- const classified = new Map<string, { path: string; names: string[] } | undefined>();
255
+ const classified = new Map<string, { path: string; names: string[] } | undefined>()
258
256
  const classify = (specifier: string, resolveDir: string) => {
259
- let file: string;
257
+ let file: string
260
258
  try {
261
259
  file =
262
260
  resolveLinkedPackageSpecifier(root, `${resolveDir}/pnext-resolve.ts`, specifier, [
@@ -264,42 +262,42 @@ export function clientDynamicCommonJsImportsPlugin(root: string): Plugin {
264
262
  'style',
265
263
  'import',
266
264
  'default',
267
- ]) ?? Bun.resolveSync(specifier, resolveDir);
265
+ ]) ?? Bun.resolveSync(specifier, resolveDir)
268
266
  } catch {
269
- return undefined;
267
+ return undefined
270
268
  }
271
- if (extname(file) !== '.cjs') return undefined;
272
- const names = commonJsExportNamesFromFile(file).filter(name => name !== 'default');
273
- return names.length === 0 ? undefined : { path: file, names };
274
- };
269
+ if (extname(file) !== '.cjs') return undefined
270
+ const names = commonJsExportNamesFromFile(file).filter(name => name !== 'default')
271
+ return names.length === 0 ? undefined : { path: file, names }
272
+ }
275
273
  build.onResolve({ filter: dynamicCjsCandidate }, args => {
276
- if (args.kind !== 'dynamic-import' || !args.resolveDir) return undefined;
277
- const key = `${args.resolveDir}\0${args.path}`;
278
- let hit = classified.get(key);
274
+ if (args.kind !== 'dynamic-import' || !args.resolveDir) return undefined
275
+ const key = `${args.resolveDir}\0${args.path}`
276
+ let hit = classified.get(key)
279
277
  if (hit === undefined && !classified.has(key)) {
280
- hit = classify(args.path, args.resolveDir);
281
- classified.set(key, hit);
278
+ hit = classify(args.path, args.resolveDir)
279
+ classified.set(key, hit)
282
280
  }
283
- if (!hit) return undefined;
281
+ if (!hit) return undefined
284
282
  return {
285
283
  path: hit.path,
286
284
  namespace: 'pnext-dynamic-cjs-facade',
287
285
  pluginData: { names: hit.names },
288
- };
289
- });
286
+ }
287
+ })
290
288
  build.onLoad({ filter: /.*/, namespace: 'pnext-dynamic-cjs-facade' }, args => {
291
- const names = (args.pluginData as { names?: string[] } | undefined)?.names ?? [];
289
+ const names = (args.pluginData as { names?: string[] } | undefined)?.names ?? []
292
290
  const forwards = names
293
291
  .map(name => `export const ${name} = value[${JSON.stringify(name)}];`)
294
- .join('\n');
292
+ .join('\n')
295
293
  return {
296
294
  contents: `import value from ${JSON.stringify(args.path)};\nexport default value;\n${forwards}\n`,
297
295
  loader: 'js',
298
296
  resolveDir: dirname(args.path),
299
- };
300
- });
297
+ }
298
+ })
301
299
  },
302
- };
300
+ }
303
301
  }
304
302
 
305
303
  // React 19 renders a thenable child by unwrapping it through `use()`. Preact
@@ -315,111 +313,118 @@ export function rewriteClientDynamicImportPromises(source: string): string {
315
313
  ),
316
314
  ]
317
315
  .map(match => match[1])
318
- .filter((name): name is string => Boolean(name));
319
- if (names.length === 0) return source;
316
+ .filter((name): name is string => Boolean(name))
317
+ if (names.length === 0) return source
320
318
 
321
- const hook = uniqueIdentifier(source, '__pnext_use');
322
- let next = source;
323
- let changed = false;
319
+ const hook = uniqueIdentifier(source, '__pnext_use')
320
+ let next = source
321
+ let changed = false
324
322
  for (const name of names) {
325
- const expression = new RegExp(`\\{${escapeRegExp(name)}\\}`, 'g');
326
- const rewritten = next.replace(expression, `{${hook}(${name})}`);
327
- changed ||= rewritten !== next;
328
- next = rewritten;
323
+ const expression = new RegExp(`\\{${escapeRegExp(name)}\\}`, 'g')
324
+ const rewritten = next.replace(expression, `{${hook}(${name})}`)
325
+ changed ||= rewritten !== next
326
+ next = rewritten
329
327
  }
330
- if (!changed) return source;
328
+ if (!changed) return source
331
329
 
332
- const directive = /^(?:\s*['"][^'"]+['"];?\s*)*/.exec(next)?.[0] ?? '';
333
- return `${directive}import { use as ${hook} } from 'react';\n${next.slice(directive.length)}`;
330
+ const directive = /^(?:\s*['"][^'"]+['"];?\s*)*/.exec(next)?.[0] ?? ''
331
+ return `${directive}import { use as ${hook} } from 'react';\n${next.slice(directive.length)}`
334
332
  }
335
333
 
336
334
  function recoverCommonJsNamedExports(code: string) {
337
- if (hasNonDefaultExport(code)) return code;
335
+ if (hasNonDefaultExport(code)) return code
338
336
  const names = [...new Set([...commonJsExportNames(code), ...esbuildEntryExportNames(code)])]
339
337
  .filter(name => name !== 'default' && name !== '__esModule')
340
- .sort();
341
- if (names.length === 0) return code;
342
-
343
- const directDefaultExport = /(^|\n)export default ([^;\n]+);/.exec(code);
344
- const listedDefaultExport = /(^|\n)export\s*\{\s*([A-Za-z_$][\w$]*)\s+as\s+default\s*,?\s*\};?/.exec(
345
- code,
346
- );
347
- const defaultExport = directDefaultExport ?? listedDefaultExport;
348
- if (!defaultExport?.[2]) return code;
349
-
350
- const defaultName = uniqueIdentifier(code, '__pnext_cjs_default');
351
- const namespaceName = commonJsNamespaceBinding(code, defaultExport[2]);
352
- const usedNames = [defaultName];
338
+ .sort()
339
+ if (names.length === 0) return code
340
+
341
+ const directDefaultExport = /(^|\n)export default ([^;\n]+);/.exec(code)
342
+ const listedDefaultExport =
343
+ /(^|\n)export\s*\{\s*([A-Za-z_$][\w$]*)\s+as\s+default\s*,?\s*\};?/.exec(code)
344
+ const defaultExport = directDefaultExport ?? listedDefaultExport
345
+ if (!defaultExport?.[2]) return code
346
+
347
+ const defaultName = uniqueIdentifier(code, '__pnext_cjs_default')
348
+ const namespaceName = commonJsNamespaceBinding(code, defaultExport[2])
349
+ const usedNames = [defaultName]
353
350
  const bindings = names.map(name => {
354
- const localName = uniqueIdentifier(code, `__pnext_cjs_export_${name}`, ...usedNames);
355
- usedNames.push(localName);
356
- return { name, localName };
357
- });
351
+ const localName = uniqueIdentifier(code, `__pnext_cjs_export_${name}`, ...usedNames)
352
+ usedNames.push(localName)
353
+ return { name, localName }
354
+ })
358
355
  const namedBindings = bindings
359
356
  .map(
360
357
  ({ name, localName }) =>
361
- `const ${localName} = ${(namespaceName ?? defaultName)}[${JSON.stringify(name)}];`,
358
+ `const ${localName} = ${namespaceName ?? defaultName}[${JSON.stringify(name)}];`,
362
359
  )
363
- .join('\n');
364
- const namedExports = bindings.map(({ name, localName }) => `${localName} as ${name}`).join(', ');
360
+ .join('\n')
361
+ const namedExports = bindings.map(({ name, localName }) => `${localName} as ${name}`).join(', ')
365
362
 
366
363
  return code.replace(
367
364
  defaultExport[0],
368
365
  `${defaultExport[1]}const ${defaultName} = ${defaultExport[2]};\nexport default ${defaultName};\n${namedBindings}\nexport { ${namedExports} };\n`,
369
- );
366
+ )
370
367
  }
371
368
 
372
369
  function commonJsNamespaceBinding(code: string, defaultName: string) {
373
370
  const assignment = new RegExp(
374
371
  `(?:^|\\n)(?:var|const|let)\\s+${escapeRegExp(defaultName)}\\s*=\\s*([A-Za-z_$][\\w$]*)\\.default\\s*;`,
375
- ).exec(code);
376
- if (assignment?.[1]) return assignment[1];
372
+ ).exec(code)
373
+ if (assignment?.[1]) return assignment[1]
377
374
 
378
375
  return new RegExp(
379
376
  `(?:^|\\n)(?:var|const|let)\\s+${escapeRegExp(defaultName)}\\s*=\\s*([A-Za-z_$][\\w$]*)\\s*!=\\s*null\\s*&&[\\s\\S]*?\\?\\s*\\1\\.default\\s*:\\s*\\1\\s*;`,
380
- ).exec(code)?.[1];
377
+ ).exec(code)?.[1]
381
378
  }
382
379
 
383
380
  function hasNonDefaultExport(code: string) {
384
- if (/(^|\n)export\s+(?:\*|(?:const|let|var|function|class)\s+)/.test(code)) return true;
381
+ if (/(^|\n)export\s+(?:\*|(?:const|let|var|function|class)\s+)/.test(code)) return true
385
382
  for (const statement of code.matchAll(/(^|\n)export\s*\{([^}]*)\}/g)) {
386
383
  const names = (statement[2] ?? '')
387
384
  .split(',')
388
- .map(name => name.trim().split(/\s+as\s+/i).at(-1))
389
- .filter((name): name is string => Boolean(name));
390
- if (names.some(name => name !== 'default')) return true;
385
+ .map(name =>
386
+ name
387
+ .trim()
388
+ .split(/\s+as\s+/i)
389
+ .at(-1),
390
+ )
391
+ .filter((name): name is string => Boolean(name))
392
+ if (names.some(name => name !== 'default')) return true
391
393
  }
392
- return false;
394
+ return false
393
395
  }
394
396
 
395
397
  function commonJsExportNames(code: string) {
396
398
  return [
397
- ...new Set([
398
- ...[...code.matchAll(/\bexports\.([A-Za-z_$][\w$]*)\s*=\s*/g)].map(match => match[1]),
399
- ...[
400
- ...code.matchAll(
401
- /\bObject\.defineProperty\(\s*exports\s*,\s*["']([A-Za-z_$][\w$]*)["']/g,
402
- ),
403
- ].map(match => match[1]),
404
- ...extractModuleExportsObjectNames(code),
405
- ]
406
- .filter((name): name is string => Boolean(name && name !== '__esModule' && isIdentifier(name)))
407
- .sort(),
399
+ ...new Set(
400
+ [
401
+ ...[...code.matchAll(/\bexports\.([A-Za-z_$][\w$]*)\s*=\s*/g)].map(match => match[1]),
402
+ ...[
403
+ ...code.matchAll(
404
+ /\bObject\.defineProperty\(\s*exports\s*,\s*["']([A-Za-z_$][\w$]*)["']/g,
405
+ ),
406
+ ].map(match => match[1]),
407
+ ...extractModuleExportsObjectNames(code),
408
+ ]
409
+ .filter((name): name is string =>
410
+ Boolean(name && name !== '__esModule' && isIdentifier(name)),
411
+ )
412
+ .sort(),
408
413
  ),
409
- ];
414
+ ]
410
415
  }
411
416
 
412
417
  function commonJsExportNamesFromFile(file: string, visited = new Set<string>()): string[] {
413
- if (visited.has(file)) return [];
414
- visited.add(file);
415
- let code: string;
418
+ if (visited.has(file)) return []
419
+ visited.add(file)
420
+ let code: string
416
421
  try {
417
- code = readFileSync(file, 'utf8');
422
+ code = readFileSync(file, 'utf8')
418
423
  } catch {
419
- return [];
424
+ return []
420
425
  }
421
- const names = commonJsExportNames(code);
422
- if (names.length > 0) return names;
426
+ const names = commonJsExportNames(code)
427
+ if (names.length > 0) return names
423
428
 
424
429
  // Follow the simple `const value = require('...'); module.exports = value`
425
430
  // form used by packages that re-export an `imports` map entry, plus the
@@ -427,116 +432,159 @@ function commonJsExportNamesFromFile(file: string, visited = new Set<string>()):
427
432
  const reexport =
428
433
  /\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*require\(\s*['"]([^'"]+)['"]\s*\)[\s\S]*?\bmodule\.exports\s*=\s*\1\s*;?/.exec(
429
434
  code,
430
- ) ?? /\bmodule\.exports\s*=\s*require\(\s*['"]([^'"]+)['"]\s*\)/.exec(code);
431
- const specifier = reexport?.[2] ?? reexport?.[1];
432
- if (!specifier) return [];
435
+ ) ?? /\bmodule\.exports\s*=\s*require\(\s*['"]([^'"]+)['"]\s*\)/.exec(code)
436
+ const specifier = reexport?.[2] ?? reexport?.[1]
437
+ if (!specifier) return []
433
438
  try {
434
- return commonJsExportNamesFromFile(Bun.resolveSync(specifier, dirname(file)), visited);
439
+ return commonJsExportNamesFromFile(Bun.resolveSync(specifier, dirname(file)), visited)
435
440
  } catch {
436
- return [];
441
+ return []
437
442
  }
438
443
  }
439
444
 
440
445
  function escapeRegExp(value: string) {
441
- return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
446
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
442
447
  }
443
448
 
444
449
  function extractModuleExportsObjectNames(code: string) {
445
- const start = /\bmodule\.exports\s*=\s*\{/.exec(code);
446
- if (!start) return [];
447
- const objectBody = topLevelObjectBody(code, start.index + start[0].length - 1);
448
- if (objectBody === undefined) return [];
449
- return [...objectBody.matchAll(/(?:^|,)\s*(?:([A-Za-z_$][\w$]*)\s*:|["']([A-Za-z_$][\w$]*)["']\s*:)/g)]
450
+ const start = /\bmodule\.exports\s*=\s*\{/.exec(code)
451
+ if (!start) return []
452
+ const objectBody = topLevelObjectBody(code, start.index + start[0].length - 1)
453
+ if (objectBody === undefined) return []
454
+ return [
455
+ ...objectBody.matchAll(/(?:^|,)\s*(?:([A-Za-z_$][\w$]*)\s*:|["']([A-Za-z_$][\w$]*)["']\s*:)/g),
456
+ ]
450
457
  .map(match => match[1] || match[2])
451
- .filter((name): name is string => Boolean(name && isIdentifier(name)));
458
+ .filter((name): name is string => Boolean(name && isIdentifier(name)))
452
459
  }
453
460
 
454
461
  // Scan an object literal from its opening brace, keeping only top-level text: nested bodies, strings
455
462
  // and comments are blanked out so a nested key (or a comment separating keys) cannot be mistaken for -
456
463
  // or hide - a top-level one. Returns undefined when the literal is unterminated.
457
464
  function topLevelObjectBody(code: string, openIndex: number): string | undefined {
458
- let depth = 0;
459
- let out = '';
465
+ let depth = 0
466
+ let out = ''
460
467
  for (let index = openIndex; index < code.length; index += 1) {
461
- const char = code[index]!;
468
+ const char = code[index]!
462
469
  if (char === '"' || char === "'" || char === '`') {
463
- const end = skipString(code, index, char);
464
- if (depth === 1) out += ' '.repeat(end - index + 1);
465
- index = end;
466
- continue;
470
+ const end = skipString(code, index, char)
471
+ if (depth === 1) out += ' '.repeat(end - index + 1)
472
+ index = end
473
+ continue
467
474
  }
468
475
  if (char === '/' && (code[index + 1] === '/' || code[index + 1] === '*')) {
469
- const end = commentEnd(code, index);
470
- if (depth === 1) out += ' '.repeat(end - index + 1);
471
- index = end;
472
- continue;
476
+ const end = commentEnd(code, index)
477
+ if (depth === 1) out += ' '.repeat(end - index + 1)
478
+ index = end
479
+ continue
473
480
  }
474
481
  if (char === '{' || char === '[' || char === '(') {
475
- depth += 1;
476
- if (depth === 1) continue;
477
- out += depth === 2 ? ' ' : '';
478
- continue;
482
+ depth += 1
483
+ if (depth === 1) continue
484
+ out += depth === 2 ? ' ' : ''
485
+ continue
479
486
  }
480
487
  if (char === '}' || char === ']' || char === ')') {
481
- depth -= 1;
482
- if (depth === 0) return out;
483
- continue;
488
+ depth -= 1
489
+ if (depth === 0) return out
490
+ continue
484
491
  }
485
- if (depth === 1) out += char;
492
+ if (depth === 1) out += char
486
493
  }
487
- return undefined;
494
+ return undefined
488
495
  }
489
496
 
490
497
  // Index of the last character of the comment starting at `start`.
491
498
  function commentEnd(code: string, start: number): number {
492
499
  if (code[start + 1] === '/') {
493
- const newline = code.indexOf('\n', start);
494
- return (newline < 0 ? code.length : newline) - 1;
500
+ const newline = code.indexOf('\n', start)
501
+ return (newline < 0 ? code.length : newline) - 1
495
502
  }
496
- const close = code.indexOf('*/', start);
497
- return close < 0 ? code.length - 1 : close + 1;
503
+ const close = code.indexOf('*/', start)
504
+ return close < 0 ? code.length - 1 : close + 1
498
505
  }
499
506
 
500
507
  function skipString(code: string, start: number, quote: string): number {
501
508
  for (let index = start + 1; index < code.length; index += 1) {
502
- const char = code[index];
509
+ const char = code[index]
503
510
  if (char === '\\') {
504
- index += 1;
505
- continue;
511
+ index += 1
512
+ continue
506
513
  }
507
- if (char === quote) return index;
514
+ if (char === quote) return index
508
515
  }
509
- return code.length - 1;
516
+ return code.length - 1
510
517
  }
511
518
 
512
519
  // Reserved words are legal CommonJS object keys but illegal export bindings, so
513
520
  // a `module.exports = { class: … }` entry must not reach the facade.
514
521
  const reservedWords = new Set([
515
- 'await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default',
516
- 'delete', 'do', 'else', 'enum', 'export', 'extends', 'false', 'finally', 'for', 'function',
517
- 'if', 'implements', 'import', 'in', 'instanceof', 'interface', 'let', 'new', 'null',
518
- 'package', 'private', 'protected', 'public', 'return', 'static', 'super', 'switch', 'this',
519
- 'throw', 'true', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield',
520
- ]);
522
+ 'await',
523
+ 'break',
524
+ 'case',
525
+ 'catch',
526
+ 'class',
527
+ 'const',
528
+ 'continue',
529
+ 'debugger',
530
+ 'default',
531
+ 'delete',
532
+ 'do',
533
+ 'else',
534
+ 'enum',
535
+ 'export',
536
+ 'extends',
537
+ 'false',
538
+ 'finally',
539
+ 'for',
540
+ 'function',
541
+ 'if',
542
+ 'implements',
543
+ 'import',
544
+ 'in',
545
+ 'instanceof',
546
+ 'interface',
547
+ 'let',
548
+ 'new',
549
+ 'null',
550
+ 'package',
551
+ 'private',
552
+ 'protected',
553
+ 'public',
554
+ 'return',
555
+ 'static',
556
+ 'super',
557
+ 'switch',
558
+ 'this',
559
+ 'throw',
560
+ 'true',
561
+ 'try',
562
+ 'typeof',
563
+ 'var',
564
+ 'void',
565
+ 'while',
566
+ 'with',
567
+ 'yield',
568
+ ])
521
569
 
522
570
  export const namedFacadeExportNames = fileMemo((file: string): string[] =>
523
571
  commonJsExportNamesFromFile(file).filter(
524
572
  name => name !== 'default' && name !== '__esModule' && !reservedWords.has(name),
525
573
  ),
526
- );
574
+ )
527
575
 
528
576
  // Recover named exports from esbuild's `__export(entry, {...}); module.exports = __toCommonJS(entry)` shape.
529
577
  function esbuildEntryExportNames(code: string) {
530
578
  const toCommonJs = [
531
579
  ...code.matchAll(/module\.exports\s*=\s*__toCommonJS\w*\(\s*([A-Za-z_$][\w$]*)\s*\)/g),
532
- ];
533
- const entryVar = toCommonJs.at(-1)?.[1];
534
- if (!entryVar) return [];
580
+ ]
581
+ const entryVar = toCommonJs.at(-1)?.[1]
582
+ if (!entryVar) return []
535
583
  const exportCall = new RegExp(
536
584
  `__export\\w*\\(\\s*${entryVar}\\s*,\\s*\\{([\\s\\S]*?)\\}\\s*\\)`,
537
- ).exec(code);
538
- if (!exportCall?.[1]) return [];
585
+ ).exec(code)
586
+ if (!exportCall?.[1]) return []
539
587
  return [...exportCall[1].matchAll(/(?:^|,)\s*([A-Za-z_$][\w$]*)\s*:/g)]
540
588
  .map(match => match[1])
541
- .filter((name): name is string => Boolean(name && isIdentifier(name)));
589
+ .filter((name): name is string => Boolean(name && isIdentifier(name)))
542
590
  }