@nifrajs/web 4.0.2 → 5.1.0

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 (426) hide show
  1. package/README.md +19 -0
  2. package/dist/build-vite.d.ts +19 -0
  3. package/dist/build-vite.d.ts.map +1 -1
  4. package/dist/build-vite.js +31 -10
  5. package/dist/build-vite.js.map +1 -1
  6. package/dist/build.d.ts +8 -10
  7. package/dist/build.d.ts.map +1 -1
  8. package/dist/build.js +90 -31
  9. package/dist/build.js.map +1 -1
  10. package/dist/cdn.d.ts +8 -0
  11. package/dist/cdn.d.ts.map +1 -1
  12. package/dist/cdn.js +14 -15
  13. package/dist/cdn.js.map +1 -1
  14. package/dist/client.d.ts +6 -6
  15. package/dist/client.d.ts.map +1 -1
  16. package/dist/client.js +46 -18
  17. package/dist/client.js.map +1 -1
  18. package/dist/deferred.d.ts +2 -2
  19. package/dist/deferred.d.ts.map +1 -1
  20. package/dist/deferred.js +28 -7
  21. package/dist/deferred.js.map +1 -1
  22. package/dist/dev-feed.d.ts.map +1 -1
  23. package/dist/dev-feed.js +24 -5
  24. package/dist/dev-feed.js.map +1 -1
  25. package/dist/dev-port.d.ts +3 -2
  26. package/dist/dev-port.d.ts.map +1 -1
  27. package/dist/dev-port.js +2 -6
  28. package/dist/dev-port.js.map +1 -1
  29. package/dist/dev-session.d.ts.map +1 -1
  30. package/dist/dev-session.js +4 -14
  31. package/dist/dev-session.js.map +1 -1
  32. package/dist/dev.d.ts +7 -17
  33. package/dist/dev.d.ts.map +1 -1
  34. package/dist/dev.js +13 -1
  35. package/dist/dev.js.map +1 -1
  36. package/dist/draft.d.ts +8 -5
  37. package/dist/draft.d.ts.map +1 -1
  38. package/dist/draft.js +30 -13
  39. package/dist/draft.js.map +1 -1
  40. package/dist/fonts-google.d.ts.map +1 -1
  41. package/dist/fonts-google.js +7 -0
  42. package/dist/fonts-google.js.map +1 -1
  43. package/dist/index.d.ts +5 -4
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +4 -3
  46. package/dist/index.js.map +1 -1
  47. package/dist/internal/codegen.d.ts +1 -0
  48. package/dist/internal/codegen.d.ts.map +1 -1
  49. package/dist/internal/codegen.js +56 -29
  50. package/dist/internal/codegen.js.map +1 -1
  51. package/dist/internal/disposable-dir.d.ts +8 -0
  52. package/dist/internal/disposable-dir.d.ts.map +1 -0
  53. package/dist/internal/disposable-dir.js +25 -0
  54. package/dist/internal/disposable-dir.js.map +1 -0
  55. package/dist/internal/entry-chunks.d.ts +9 -0
  56. package/dist/internal/entry-chunks.d.ts.map +1 -0
  57. package/dist/internal/entry-chunks.js +15 -0
  58. package/dist/internal/entry-chunks.js.map +1 -0
  59. package/dist/internal/evidence-traversal.d.ts +12 -0
  60. package/dist/internal/evidence-traversal.d.ts.map +1 -0
  61. package/dist/internal/evidence-traversal.js +48 -0
  62. package/dist/internal/evidence-traversal.js.map +1 -0
  63. package/dist/internal/head-merge.d.ts +6 -0
  64. package/dist/internal/head-merge.d.ts.map +1 -1
  65. package/dist/internal/head-merge.js +9 -0
  66. package/dist/internal/head-merge.js.map +1 -1
  67. package/dist/internal/js-string.d.ts +2 -0
  68. package/dist/internal/js-string.d.ts.map +1 -1
  69. package/dist/internal/js-string.js +5 -1
  70. package/dist/internal/js-string.js.map +1 -1
  71. package/dist/internal/mount-shadow.js +1 -1
  72. package/dist/internal/mount-shadow.js.map +1 -1
  73. package/dist/internal/output-guard.d.ts +7 -0
  74. package/dist/internal/output-guard.d.ts.map +1 -1
  75. package/dist/internal/output-guard.js +80 -8
  76. package/dist/internal/output-guard.js.map +1 -1
  77. package/dist/internal/package-entries.d.ts +34 -0
  78. package/dist/internal/package-entries.d.ts.map +1 -0
  79. package/dist/internal/package-entries.js +324 -0
  80. package/dist/internal/package-entries.js.map +1 -0
  81. package/dist/internal/page-execution.d.ts +6 -0
  82. package/dist/internal/page-execution.d.ts.map +1 -1
  83. package/dist/internal/page-execution.js +437 -114
  84. package/dist/internal/page-execution.js.map +1 -1
  85. package/dist/internal/parity.d.ts.map +1 -1
  86. package/dist/internal/parity.js +15 -2
  87. package/dist/internal/parity.js.map +1 -1
  88. package/dist/internal/private-env.d.ts +8 -0
  89. package/dist/internal/private-env.d.ts.map +1 -1
  90. package/dist/internal/private-env.js +25 -10
  91. package/dist/internal/private-env.js.map +1 -1
  92. package/dist/internal/progressive-cookies.d.ts +14 -0
  93. package/dist/internal/progressive-cookies.d.ts.map +1 -0
  94. package/dist/internal/progressive-cookies.js +43 -0
  95. package/dist/internal/progressive-cookies.js.map +1 -0
  96. package/dist/internal/public-env.d.ts +2 -0
  97. package/dist/internal/public-env.d.ts.map +1 -0
  98. package/dist/internal/public-env.js +13 -0
  99. package/dist/internal/public-env.js.map +1 -0
  100. package/dist/internal/render-document.d.ts +5 -44
  101. package/dist/internal/render-document.d.ts.map +1 -1
  102. package/dist/internal/render-document.js +51 -63
  103. package/dist/internal/render-document.js.map +1 -1
  104. package/dist/internal/response-controls.d.ts +2 -0
  105. package/dist/internal/response-controls.d.ts.map +1 -1
  106. package/dist/internal/response-controls.js +26 -16
  107. package/dist/internal/response-controls.js.map +1 -1
  108. package/dist/internal/revive-dates.d.ts +16 -0
  109. package/dist/internal/revive-dates.d.ts.map +1 -0
  110. package/dist/internal/revive-dates.js +32 -0
  111. package/dist/internal/revive-dates.js.map +1 -0
  112. package/dist/internal/route-path.d.ts +14 -0
  113. package/dist/internal/route-path.d.ts.map +1 -0
  114. package/dist/internal/route-path.js +19 -0
  115. package/dist/internal/route-path.js.map +1 -0
  116. package/dist/internal/secret-scan.d.ts.map +1 -1
  117. package/dist/internal/secret-scan.js +190 -20
  118. package/dist/internal/secret-scan.js.map +1 -1
  119. package/dist/internal/server-boundary.d.ts.map +1 -1
  120. package/dist/internal/server-boundary.js +33 -5
  121. package/dist/internal/server-boundary.js.map +1 -1
  122. package/dist/internal/web-app.d.ts +25 -18
  123. package/dist/internal/web-app.d.ts.map +1 -1
  124. package/dist/internal/web-app.js +81 -24
  125. package/dist/internal/web-app.js.map +1 -1
  126. package/dist/internal/wire-date.d.ts +3 -0
  127. package/dist/internal/wire-date.d.ts.map +1 -0
  128. package/dist/internal/wire-date.js +14 -0
  129. package/dist/internal/wire-date.js.map +1 -0
  130. package/dist/internal/without-query.d.ts +4 -0
  131. package/dist/internal/without-query.d.ts.map +1 -0
  132. package/dist/internal/without-query.js +9 -0
  133. package/dist/internal/without-query.js.map +1 -0
  134. package/dist/internal/zone-graph.d.ts +4 -0
  135. package/dist/internal/zone-graph.d.ts.map +1 -1
  136. package/dist/internal/zone-graph.js +71 -20
  137. package/dist/internal/zone-graph.js.map +1 -1
  138. package/dist/isr.d.ts +59 -3
  139. package/dist/isr.d.ts.map +1 -1
  140. package/dist/isr.js +311 -41
  141. package/dist/isr.js.map +1 -1
  142. package/dist/llms-txt.d.ts +2 -0
  143. package/dist/llms-txt.d.ts.map +1 -1
  144. package/dist/llms-txt.js +29 -3
  145. package/dist/llms-txt.js.map +1 -1
  146. package/dist/manifest.d.ts +37 -4
  147. package/dist/manifest.d.ts.map +1 -1
  148. package/dist/manifest.js +4 -0
  149. package/dist/manifest.js.map +1 -1
  150. package/dist/open-resolved.d.ts +18 -0
  151. package/dist/open-resolved.d.ts.map +1 -0
  152. package/dist/open-resolved.js +62 -0
  153. package/dist/open-resolved.js.map +1 -0
  154. package/dist/plugins/kit.d.ts +1 -0
  155. package/dist/plugins/kit.d.ts.map +1 -1
  156. package/dist/plugins/kit.js +26 -11
  157. package/dist/plugins/kit.js.map +1 -1
  158. package/dist/plugins/vite-leak-guard.d.ts +9 -1
  159. package/dist/plugins/vite-leak-guard.d.ts.map +1 -1
  160. package/dist/plugins/vite-leak-guard.js +84 -7
  161. package/dist/plugins/vite-leak-guard.js.map +1 -1
  162. package/dist/plugins/vite-zone-guard.d.ts.map +1 -1
  163. package/dist/plugins/vite-zone-guard.js +17 -21
  164. package/dist/plugins/vite-zone-guard.js.map +1 -1
  165. package/dist/plugins/zone-guard.d.ts.map +1 -1
  166. package/dist/plugins/zone-guard.js +44 -3
  167. package/dist/plugins/zone-guard.js.map +1 -1
  168. package/dist/prerender.d.ts +5 -1
  169. package/dist/prerender.d.ts.map +1 -1
  170. package/dist/prerender.js +41 -19
  171. package/dist/prerender.js.map +1 -1
  172. package/dist/public-dir.d.ts +8 -1
  173. package/dist/public-dir.d.ts.map +1 -1
  174. package/dist/public-dir.js +17 -6
  175. package/dist/public-dir.js.map +1 -1
  176. package/dist/query.d.ts +13 -4
  177. package/dist/query.d.ts.map +1 -1
  178. package/dist/query.js +89 -26
  179. package/dist/query.js.map +1 -1
  180. package/dist/render-seam.d.ts +25 -2
  181. package/dist/render-seam.d.ts.map +1 -1
  182. package/dist/render-seam.js +1 -0
  183. package/dist/render-seam.js.map +1 -1
  184. package/dist/route-types.d.ts.map +1 -1
  185. package/dist/route-types.js +20 -9
  186. package/dist/route-types.js.map +1 -1
  187. package/dist/router.d.ts +9 -2
  188. package/dist/router.d.ts.map +1 -1
  189. package/dist/router.js +47 -50
  190. package/dist/router.js.map +1 -1
  191. package/dist/seo.d.ts +49 -0
  192. package/dist/seo.d.ts.map +1 -0
  193. package/dist/seo.js +48 -0
  194. package/dist/seo.js.map +1 -0
  195. package/dist/server-components/build-info.d.ts +3 -0
  196. package/dist/server-components/build-info.d.ts.map +1 -0
  197. package/dist/server-components/build-info.js +7 -0
  198. package/dist/server-components/build-info.js.map +1 -0
  199. package/dist/server-components/build-target.d.ts +12 -0
  200. package/dist/server-components/build-target.d.ts.map +1 -0
  201. package/dist/server-components/build-target.js +153 -0
  202. package/dist/server-components/build-target.js.map +1 -0
  203. package/dist/server-components/build.d.ts +24 -0
  204. package/dist/server-components/build.d.ts.map +1 -0
  205. package/dist/server-components/build.js +366 -0
  206. package/dist/server-components/build.js.map +1 -0
  207. package/dist/server-components/bundle-proof.d.ts +3 -0
  208. package/dist/server-components/bundle-proof.d.ts.map +1 -0
  209. package/dist/server-components/bundle-proof.js +23 -0
  210. package/dist/server-components/bundle-proof.js.map +1 -0
  211. package/dist/server-components/client.d.ts +46 -0
  212. package/dist/server-components/client.d.ts.map +1 -0
  213. package/dist/server-components/client.js +594 -0
  214. package/dist/server-components/client.js.map +1 -0
  215. package/dist/server-components/definition.d.ts +11 -0
  216. package/dist/server-components/definition.d.ts.map +1 -0
  217. package/dist/server-components/definition.js +94 -0
  218. package/dist/server-components/definition.js.map +1 -0
  219. package/dist/server-components/dev-http.d.ts +5 -0
  220. package/dist/server-components/dev-http.d.ts.map +1 -0
  221. package/dist/server-components/dev-http.js +71 -0
  222. package/dist/server-components/dev-http.js.map +1 -0
  223. package/dist/server-components/error.d.ts +9 -0
  224. package/dist/server-components/error.d.ts.map +1 -0
  225. package/dist/server-components/error.js +24 -0
  226. package/dist/server-components/error.js.map +1 -0
  227. package/dist/server-components/frames.d.ts +7 -0
  228. package/dist/server-components/frames.d.ts.map +1 -0
  229. package/dist/server-components/frames.js +169 -0
  230. package/dist/server-components/frames.js.map +1 -0
  231. package/dist/server-components/html-policy.d.ts +6 -0
  232. package/dist/server-components/html-policy.d.ts.map +1 -0
  233. package/dist/server-components/html-policy.js +75 -0
  234. package/dist/server-components/html-policy.js.map +1 -0
  235. package/dist/server-components/html.d.ts +4 -0
  236. package/dist/server-components/html.d.ts.map +1 -0
  237. package/dist/server-components/html.js +67 -0
  238. package/dist/server-components/html.js.map +1 -0
  239. package/dist/server-components/islands.d.ts +44 -0
  240. package/dist/server-components/islands.d.ts.map +1 -0
  241. package/dist/server-components/islands.js +42 -0
  242. package/dist/server-components/islands.js.map +1 -0
  243. package/dist/server-components/native.d.ts +4 -0
  244. package/dist/server-components/native.d.ts.map +1 -0
  245. package/dist/server-components/native.js +81 -0
  246. package/dist/server-components/native.js.map +1 -0
  247. package/dist/server-components/portal.d.ts +6 -0
  248. package/dist/server-components/portal.d.ts.map +1 -0
  249. package/dist/server-components/portal.js +35 -0
  250. package/dist/server-components/portal.js.map +1 -0
  251. package/dist/server-components/props.d.ts +3 -0
  252. package/dist/server-components/props.d.ts.map +1 -0
  253. package/dist/server-components/props.js +14 -0
  254. package/dist/server-components/props.js.map +1 -0
  255. package/dist/server-components/protocol.d.ts +44 -0
  256. package/dist/server-components/protocol.d.ts.map +1 -0
  257. package/dist/server-components/protocol.js +139 -0
  258. package/dist/server-components/protocol.js.map +1 -0
  259. package/dist/server-components/range.d.ts +24 -0
  260. package/dist/server-components/range.d.ts.map +1 -0
  261. package/dist/server-components/range.js +263 -0
  262. package/dist/server-components/range.js.map +1 -0
  263. package/dist/server-components/registry.d.ts +6 -0
  264. package/dist/server-components/registry.d.ts.map +1 -0
  265. package/dist/server-components/registry.js +30 -0
  266. package/dist/server-components/registry.js.map +1 -0
  267. package/dist/server-components/response.d.ts +4 -0
  268. package/dist/server-components/response.d.ts.map +1 -0
  269. package/dist/server-components/response.js +32 -0
  270. package/dist/server-components/response.js.map +1 -0
  271. package/dist/server-components/router-integration.d.ts +9 -0
  272. package/dist/server-components/router-integration.d.ts.map +1 -0
  273. package/dist/server-components/router-integration.js +29 -0
  274. package/dist/server-components/router-integration.js.map +1 -0
  275. package/dist/server-components/runtime.d.ts +14 -0
  276. package/dist/server-components/runtime.d.ts.map +1 -0
  277. package/dist/server-components/runtime.js +276 -0
  278. package/dist/server-components/runtime.js.map +1 -0
  279. package/dist/server-components/scheduler.d.ts +14 -0
  280. package/dist/server-components/scheduler.d.ts.map +1 -0
  281. package/dist/server-components/scheduler.js +74 -0
  282. package/dist/server-components/scheduler.js.map +1 -0
  283. package/dist/server-components/schema.d.ts +4 -0
  284. package/dist/server-components/schema.d.ts.map +1 -0
  285. package/dist/server-components/schema.js +77 -0
  286. package/dist/server-components/schema.js.map +1 -0
  287. package/dist/server-components/server-entry.d.ts +12 -0
  288. package/dist/server-components/server-entry.d.ts.map +1 -0
  289. package/dist/server-components/server-entry.js +90 -0
  290. package/dist/server-components/server-entry.js.map +1 -0
  291. package/dist/server-components/source.d.ts +15 -0
  292. package/dist/server-components/source.d.ts.map +1 -0
  293. package/dist/server-components/source.js +269 -0
  294. package/dist/server-components/source.js.map +1 -0
  295. package/dist/server-components/state.d.ts +4 -0
  296. package/dist/server-components/state.d.ts.map +1 -0
  297. package/dist/server-components/state.js +123 -0
  298. package/dist/server-components/state.js.map +1 -0
  299. package/dist/server-components/stream.d.ts +6 -0
  300. package/dist/server-components/stream.d.ts.map +1 -0
  301. package/dist/server-components/stream.js +70 -0
  302. package/dist/server-components/stream.js.map +1 -0
  303. package/dist/server-components/trusted-html.d.ts +3 -0
  304. package/dist/server-components/trusted-html.d.ts.map +1 -0
  305. package/dist/server-components/trusted-html.js +14 -0
  306. package/dist/server-components/trusted-html.js.map +1 -0
  307. package/dist/server-components/types.d.ts +107 -0
  308. package/dist/server-components/types.d.ts.map +1 -0
  309. package/dist/server-components/types.js +2 -0
  310. package/dist/server-components/types.js.map +1 -0
  311. package/dist/server-components/typescript.d.ts +11 -0
  312. package/dist/server-components/typescript.d.ts.map +1 -0
  313. package/dist/server-components/typescript.js +28 -0
  314. package/dist/server-components/typescript.js.map +1 -0
  315. package/dist/server-components/value.d.ts +5 -0
  316. package/dist/server-components/value.d.ts.map +1 -0
  317. package/dist/server-components/value.js +77 -0
  318. package/dist/server-components/value.js.map +1 -0
  319. package/dist/server-components/vite.d.ts +12 -0
  320. package/dist/server-components/vite.d.ts.map +1 -0
  321. package/dist/server-components/vite.js +197 -0
  322. package/dist/server-components/vite.js.map +1 -0
  323. package/dist/server-components.d.ts +5 -0
  324. package/dist/server-components.d.ts.map +1 -0
  325. package/dist/server-components.js +4 -0
  326. package/dist/server-components.js.map +1 -0
  327. package/dist/service-worker.d.ts +8 -1
  328. package/dist/service-worker.d.ts.map +1 -1
  329. package/dist/service-worker.js +20 -6
  330. package/dist/service-worker.js.map +1 -1
  331. package/dist/vite.d.ts +12 -0
  332. package/dist/vite.d.ts.map +1 -1
  333. package/dist/vite.js +7 -1
  334. package/dist/vite.js.map +1 -1
  335. package/dist/zones.d.ts +64 -2
  336. package/dist/zones.d.ts.map +1 -1
  337. package/dist/zones.js +331 -28
  338. package/dist/zones.js.map +1 -1
  339. package/package.json +102 -4
  340. package/src/build-vite.ts +31 -9
  341. package/src/build.ts +109 -31
  342. package/src/cdn.ts +18 -12
  343. package/src/client.ts +48 -17
  344. package/src/deferred.ts +27 -9
  345. package/src/dev-feed.ts +24 -5
  346. package/src/dev-port.ts +4 -10
  347. package/src/dev-session.ts +4 -13
  348. package/src/dev.ts +29 -1
  349. package/src/draft.ts +35 -14
  350. package/src/fonts-google.ts +10 -0
  351. package/src/index.ts +5 -6
  352. package/src/internal/codegen.ts +60 -29
  353. package/src/internal/disposable-dir.ts +24 -0
  354. package/src/internal/entry-chunks.ts +18 -0
  355. package/src/internal/evidence-traversal.ts +57 -0
  356. package/src/internal/head-merge.ts +16 -0
  357. package/src/internal/js-string.ts +6 -1
  358. package/src/internal/mount-shadow.ts +1 -1
  359. package/src/internal/output-guard.ts +88 -7
  360. package/src/internal/package-entries.ts +331 -0
  361. package/src/internal/page-execution.ts +573 -114
  362. package/src/internal/parity.ts +15 -2
  363. package/src/internal/private-env.ts +27 -13
  364. package/src/internal/progressive-cookies.ts +60 -0
  365. package/src/internal/public-env.ts +14 -0
  366. package/src/internal/render-document.ts +66 -89
  367. package/src/internal/response-controls.ts +31 -14
  368. package/src/internal/revive-dates.ts +35 -0
  369. package/src/internal/route-path.ts +24 -0
  370. package/src/internal/secret-scan.ts +190 -18
  371. package/src/internal/server-boundary.ts +29 -5
  372. package/src/internal/web-app.ts +126 -42
  373. package/src/internal/wire-date.ts +16 -0
  374. package/src/internal/without-query.ts +8 -0
  375. package/src/internal/zone-graph.ts +78 -25
  376. package/src/isr.ts +364 -45
  377. package/src/llms-txt.ts +32 -3
  378. package/src/manifest.ts +38 -4
  379. package/src/open-resolved.ts +64 -0
  380. package/src/plugins/kit.ts +31 -11
  381. package/src/plugins/vite-leak-guard.ts +104 -8
  382. package/src/plugins/vite-zone-guard.ts +21 -19
  383. package/src/plugins/zone-guard.ts +41 -2
  384. package/src/prerender.ts +39 -18
  385. package/src/public-dir.ts +27 -8
  386. package/src/query.ts +107 -26
  387. package/src/render-seam.ts +30 -2
  388. package/src/route-types.ts +34 -7
  389. package/src/router.ts +66 -59
  390. package/src/seo.ts +68 -0
  391. package/src/server-components/build-info.ts +11 -0
  392. package/src/server-components/build-target.ts +194 -0
  393. package/src/server-components/build.ts +419 -0
  394. package/src/server-components/bundle-proof.ts +33 -0
  395. package/src/server-components/client.ts +663 -0
  396. package/src/server-components/definition.ts +125 -0
  397. package/src/server-components/dev-http.ts +75 -0
  398. package/src/server-components/error.ts +24 -0
  399. package/src/server-components/frames.ts +181 -0
  400. package/src/server-components/html-policy.ts +94 -0
  401. package/src/server-components/html.ts +81 -0
  402. package/src/server-components/islands.ts +111 -0
  403. package/src/server-components/native.ts +101 -0
  404. package/src/server-components/portal.ts +42 -0
  405. package/src/server-components/props.ts +19 -0
  406. package/src/server-components/protocol.ts +167 -0
  407. package/src/server-components/range.ts +313 -0
  408. package/src/server-components/registry.ts +34 -0
  409. package/src/server-components/response.ts +44 -0
  410. package/src/server-components/router-integration.ts +40 -0
  411. package/src/server-components/runtime.ts +376 -0
  412. package/src/server-components/scheduler.ts +84 -0
  413. package/src/server-components/schema.ts +69 -0
  414. package/src/server-components/server-entry.ts +98 -0
  415. package/src/server-components/source.ts +324 -0
  416. package/src/server-components/state.ts +143 -0
  417. package/src/server-components/stream.ts +71 -0
  418. package/src/server-components/trusted-html.ts +21 -0
  419. package/src/server-components/types.ts +138 -0
  420. package/src/server-components/typescript.ts +39 -0
  421. package/src/server-components/value.ts +82 -0
  422. package/src/server-components/vite.ts +242 -0
  423. package/src/server-components.ts +32 -0
  424. package/src/service-worker.ts +24 -7
  425. package/src/vite.ts +8 -1
  426. package/src/zones.ts +418 -32
@@ -0,0 +1,331 @@
1
+ /**
2
+ * Per-entry package sides: `"nifra": { "environment": { ".": "backend", "./react": "frontend" } }`.
3
+ *
4
+ * An import names an entry, and that entry's side decides it. A path names no entry, so a file is owned
5
+ * by every mapped entry that reaches it inside the package: the entry's targets under any export
6
+ * condition, followed through relative imports. A stage that sees only paths decides by those owners;
7
+ * which entry an import may name is decided where the import is written, from its specifier.
8
+ */
9
+ import { readdirSync, readFileSync, realpathSync, statSync } from "node:fs"
10
+ import { dirname, extname, join, relative } from "node:path"
11
+ import type { PackageEnvironment } from "../zones.ts"
12
+ import { type Token, tokenize } from "./private-env.ts"
13
+ import { withoutQuery } from "./without-query.ts"
14
+
15
+ export type EnvironmentDeclaration =
16
+ | { readonly kind: "none" }
17
+ | { readonly kind: "package"; readonly side: PackageEnvironment }
18
+ | { readonly kind: "entries"; readonly entries: Readonly<Record<string, PackageEnvironment>> }
19
+ | { readonly kind: "invalid"; readonly problem: string }
20
+
21
+ const SIDES: ReadonlySet<string> = new Set(["frontend", "backend", "shared", "library"])
22
+ const isSide = (value: unknown): value is PackageEnvironment =>
23
+ typeof value === "string" && SIDES.has(value)
24
+
25
+ /** A manifest's `nifra.environment`. A string naming no side declares nothing, as it always has. */
26
+ export function parseEnvironment(value: unknown): EnvironmentDeclaration {
27
+ if (isSide(value)) return { kind: "package", side: value }
28
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return { kind: "none" }
29
+ const entries: Record<string, PackageEnvironment> = {}
30
+ for (const [key, side] of Object.entries(value)) {
31
+ if (key !== "." && !key.startsWith("./"))
32
+ return {
33
+ kind: "invalid",
34
+ problem: `key "${key}" must be "." or a subpath starting with "./"`,
35
+ }
36
+ if (key.indexOf("*") !== key.lastIndexOf("*"))
37
+ return { kind: "invalid", problem: `key "${key}" may hold one "*"` }
38
+ if (!isSide(side))
39
+ return {
40
+ kind: "invalid",
41
+ problem: `"${key}" must be one of frontend, backend, shared, library`,
42
+ }
43
+ entries[key] = side
44
+ }
45
+ return Object.keys(entries).length === 0
46
+ ? {
47
+ kind: "invalid",
48
+ problem: 'maps no entry; give each export subpath (".", "./react") a side',
49
+ }
50
+ : { kind: "entries", entries }
51
+ }
52
+
53
+ /**
54
+ * The mapped key that decides `subpath`: the exact key, else the `*` pattern with the longest prefix,
55
+ * then the longest key, where `*` matches at least one character - as Node matches `exports`.
56
+ */
57
+ export function entryKey(
58
+ entries: Readonly<Record<string, PackageEnvironment>>,
59
+ subpath: string,
60
+ ): string | undefined {
61
+ if (Object.hasOwn(entries, subpath)) return subpath
62
+ let best: string | undefined
63
+ for (const key of Object.keys(entries)) {
64
+ const star = key.indexOf("*")
65
+ if (star === -1 || subpath.length < key.length) continue
66
+ if (!subpath.startsWith(key.slice(0, star)) || !subpath.endsWith(key.slice(star + 1))) continue
67
+ const bestStar = best?.indexOf("*") ?? -1
68
+ if (best === undefined || star > bestStar || (star === bestStar && key.length > best.length))
69
+ best = key
70
+ }
71
+ return best
72
+ }
73
+
74
+ export interface EntryOwnership {
75
+ /** Each file a mapped entry reaches, by real path, with the sides of every entry that reaches it. */
76
+ readonly owners: ReadonlyMap<string, ReadonlySet<PackageEnvironment>>
77
+ /** Export subpaths the map gives no side. */
78
+ readonly unmapped: readonly string[]
79
+ }
80
+
81
+ const isFile = (path: string): boolean =>
82
+ statSync(path, { throwIfNoEntry: false })?.isFile() ?? false
83
+
84
+ const real = (path: string): string => {
85
+ try {
86
+ return realpathSync.native(path).replaceAll("\\", "/")
87
+ } catch {
88
+ return path.replaceAll("\\", "/")
89
+ }
90
+ }
91
+
92
+ const SCRIPT = /\.(?:[cm]?[jt]sx?|svelte|vue)$/
93
+ const STYLESHEET = /\.(?:css|scss|sass|less|styl)$/
94
+ const DECLARATION = /\.d\.[cm]?ts$/
95
+ const PROBE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"]
96
+ /** A TypeScript source imports its sibling by the extension it compiles to. */
97
+ const SOURCE_TWINS: Readonly<Record<string, readonly string[]>> = {
98
+ ".js": [".ts", ".tsx"],
99
+ ".jsx": [".tsx"],
100
+ ".mjs": [".mts"],
101
+ ".cjs": [".cts"],
102
+ }
103
+
104
+ function probe(base: string): string | undefined {
105
+ if (isFile(base)) return base
106
+ const extension = extname(base)
107
+ for (const twin of SOURCE_TWINS[extension] ?? []) {
108
+ const candidate = `${base.slice(0, -extension.length)}${twin}`
109
+ if (isFile(candidate)) return candidate
110
+ }
111
+ for (const candidate of PROBE_EXTENSIONS.map((ext) => `${base}${ext}`)) {
112
+ if (isFile(candidate)) return candidate
113
+ }
114
+ for (const candidate of PROBE_EXTENSIONS.map((ext) => join(base, `index${ext}`))) {
115
+ if (isFile(candidate)) return candidate
116
+ }
117
+ return undefined
118
+ }
119
+
120
+ const CLAUSE_PUNCT: ReadonlySet<string> = new Set(["{", "}", ",", "*"])
121
+ const isPunct = (token: Token | undefined, value: string): boolean =>
122
+ token?.kind === "punct" && token.value === value
123
+ const isId = (token: Token | undefined, value: string): boolean =>
124
+ token?.kind === "id" && token.value === value
125
+
126
+ /**
127
+ * Whether the `import`/`export` clause ending at the `from` token `at` binds only types: `import type`,
128
+ * `export type`, or a `{ }` list whose every specifier is `type`. Such an edge grants no ownership - a
129
+ * backend file a frontend entry merely types against stays backend. `import { type A }` survives as
130
+ * `import {}` under Vite with `verbatimModuleSyntax`; dropping it then fails closed, since the guard
131
+ * judges that load by the file's remaining owners.
132
+ */
133
+ function typeOnlyClause(tokens: readonly Token[], at: number): boolean {
134
+ let start = at - 1
135
+ for (; start >= 0; start--) {
136
+ const token = tokens[start]
137
+ if (isId(token, "import") || isId(token, "export")) break
138
+ if (token?.kind !== "id" && !(token?.kind === "punct" && CLAUSE_PUNCT.has(token.value)))
139
+ return false
140
+ }
141
+ if (start < 0) return false
142
+ const clause = tokens.slice(start + 1, at)
143
+ // `import type from "./x"` and `import type, { a } from` bind a default import named `type`.
144
+ if (isId(clause[0], "type")) return clause.length > 1 && !isPunct(clause[1], ",")
145
+ if (!isPunct(clause[0], "{") || !isPunct(clause.at(-1), "}")) return false
146
+ const specifiers: Token[][] = [[]]
147
+ for (const token of clause.slice(1, -1)) {
148
+ if (isPunct(token, ",")) specifiers.push([])
149
+ else specifiers.at(-1)?.push(token)
150
+ }
151
+ const named = specifiers.filter((specifier) => specifier.length > 0)
152
+ // `{ type as x }` imports a value named `type`; `{ type A }` and `{ type A as B }` import types.
153
+ return (
154
+ named.length > 0 &&
155
+ named.every(
156
+ (specifier) =>
157
+ isId(specifier[0], "type") &&
158
+ (specifier.length === 2 || (specifier.length === 4 && isId(specifier[2], "as"))),
159
+ )
160
+ )
161
+ }
162
+
163
+ /** The relative specifiers a module loads: imports, re-exports, `import()`s, `require`s and
164
+ * `new URL()`s (a worker or an asset beside it). A clause binding only types loads nothing. */
165
+ function relativeImports(code: string): string[] {
166
+ const tokens = tokenize(code)
167
+ const found: string[] = []
168
+ for (let i = 0; i < tokens.length; i++) {
169
+ const token = tokens[i]
170
+ if (token?.kind !== "id") continue
171
+ const previous = tokens[i - 1]
172
+ if (previous?.kind === "punct" && previous.value === ".") continue
173
+ let next = tokens[i + 1]
174
+ const call = next?.kind === "punct" && next.value === "("
175
+ const url = token.value === "URL" && previous?.kind === "id" && previous.value === "new"
176
+ if (token.value === "require" || url || (token.value === "import" && call)) {
177
+ if (!call) continue
178
+ next = tokens[i + 2]
179
+ } else if (token.value !== "from" && token.value !== "import") continue
180
+ if (next?.kind !== "string" || !/^\.\.?\//.test(next.value)) continue
181
+ if (token.value === "from" && typeOnlyClause(tokens, i)) continue
182
+ found.push(next.value)
183
+ }
184
+ return found
185
+ }
186
+
187
+ /** What a stylesheet pulls in beside it: `@import`s and `url()`s that name no scheme or root. */
188
+ function stylesheetImports(code: string): string[] {
189
+ const text = code.replace(/\/\*[\s\S]*?\*\//g, "")
190
+ const found: string[] = []
191
+ for (const match of text.matchAll(
192
+ /@import\s+(?:url\(\s*)?["']?([^"'()\s;]+)|url\(\s*["']?([^"'()\s]+)/g,
193
+ )) {
194
+ const reference = match[1] ?? match[2] ?? ""
195
+ if (reference !== "" && !/^(?:[a-z][\w+.-]*:|\/|#|~)/i.test(reference)) found.push(reference)
196
+ }
197
+ return found
198
+ }
199
+
200
+ /** Every string target of an export value, under every condition. */
201
+ function targetsOf(value: unknown): string[] {
202
+ if (typeof value === "string") return value.startsWith("./") ? [value] : []
203
+ if (Array.isArray(value)) return value.flatMap(targetsOf)
204
+ if (typeof value === "object" && value !== null) return Object.values(value).flatMap(targetsOf)
205
+ return []
206
+ }
207
+
208
+ /** `exports` as subpath entries; without it, the root is `main`/`module`/`browser` and any file a subpath. */
209
+ function exportEntries(
210
+ manifest: Readonly<Record<string, unknown>>,
211
+ entries: Readonly<Record<string, PackageEnvironment>>,
212
+ ): Array<readonly [string, readonly string[]]> {
213
+ const exports = manifest.exports
214
+ if (exports === undefined || exports === null) {
215
+ const roots = [manifest.main, manifest.module, manifest.browser]
216
+ .filter((root): root is string => typeof root === "string")
217
+ .map((root) => (root.startsWith("./") ? root : `./${root}`))
218
+ return [
219
+ [".", roots.length > 0 ? roots : ["./index.js"]],
220
+ ...Object.keys(entries)
221
+ .filter((key) => key !== ".")
222
+ .map((key) => [key, [key]] as const),
223
+ ]
224
+ }
225
+ if (typeof exports !== "object" || Array.isArray(exports)) return [[".", targetsOf(exports)]]
226
+ const keys = Object.keys(exports)
227
+ if (keys.length === 0 || !keys.every((key) => key.startsWith(".")))
228
+ return [[".", targetsOf(exports)]]
229
+ return Object.entries(exports).map(([key, value]) => [key, targetsOf(value)] as const)
230
+ }
231
+
232
+ /** Every file under `dir`, outside `node_modules`. */
233
+ function filesUnder(dir: string): string[] {
234
+ let names: string[]
235
+ try {
236
+ names = readdirSync(dir, { recursive: true, encoding: "utf8" })
237
+ } catch {
238
+ return []
239
+ }
240
+ return names
241
+ .filter((name) => !/(?:^|[\\/])node_modules(?:[\\/]|$)/.test(name))
242
+ .map((name) => join(dir, name))
243
+ .filter(isFile)
244
+ }
245
+
246
+ /** Which mapped entries reach each file of the package at `dir` (a real path). */
247
+ export function entryOwnership(
248
+ dir: string,
249
+ manifest: Readonly<Record<string, unknown>>,
250
+ entries: Readonly<Record<string, PackageEnvironment>>,
251
+ ): EntryOwnership {
252
+ const owners = new Map<string, Set<PackageEnvironment>>()
253
+ const unmapped = new Set<string>()
254
+ const queue: Array<readonly [string, PackageEnvironment]> = []
255
+ const reach = (path: string, side: PackageEnvironment): void => {
256
+ const file = real(path)
257
+ if (!file.startsWith(`${dir}/`) || file.slice(dir.length).includes("/node_modules/")) return
258
+ const sides = owners.get(file) ?? new Set<PackageEnvironment>()
259
+ if (sides.has(side)) return
260
+ sides.add(side)
261
+ owners.set(file, sides)
262
+ queue.push([file, side])
263
+ }
264
+ const sideOf = (subpath: string, exportKey = subpath): PackageEnvironment | undefined => {
265
+ const key = entryKey(entries, subpath)
266
+ if (key === undefined) unmapped.add(exportKey)
267
+ return key === undefined ? undefined : entries[key]
268
+ }
269
+ for (const [key, targets] of exportEntries(manifest, entries)) {
270
+ const star = key.indexOf("*")
271
+ if (star === -1) {
272
+ const side = sideOf(key)
273
+ if (side === undefined) continue
274
+ for (const target of targets) {
275
+ const file = target.includes("*") ? undefined : probe(join(dir, target))
276
+ if (file !== undefined) reach(file, side)
277
+ }
278
+ continue
279
+ }
280
+ // A pattern entry: each file a target pattern matches is the subpath its `*` spells.
281
+ for (const target of targets) {
282
+ const at = target.indexOf("*")
283
+ if (at === -1) continue
284
+ const prefix = target.slice(0, at)
285
+ const suffix = target.slice(at + 1)
286
+ for (const file of filesUnder(join(dir, prefix.slice(0, prefix.lastIndexOf("/") + 1)))) {
287
+ const path = `./${relative(dir, file).replaceAll("\\", "/")}`
288
+ if (path.length <= prefix.length + suffix.length) continue
289
+ if (!path.startsWith(prefix) || !path.endsWith(suffix)) continue
290
+ const matched = path.slice(prefix.length, path.length - suffix.length)
291
+ const side = sideOf(`${key.slice(0, star)}${matched}${key.slice(star + 1)}`, key)
292
+ if (side !== undefined) reach(file, side)
293
+ }
294
+ }
295
+ }
296
+ const imports = new Map<string, readonly string[]>()
297
+ for (const [file, side] of queue) {
298
+ const script = SCRIPT.test(file) && !DECLARATION.test(file)
299
+ if (!script && !STYLESHEET.test(file)) continue
300
+ let specifiers = imports.get(file)
301
+ if (specifiers === undefined) {
302
+ try {
303
+ const code = readFileSync(file, "utf8")
304
+ specifiers = script ? relativeImports(code) : stylesheetImports(code)
305
+ } catch {
306
+ specifiers = []
307
+ }
308
+ imports.set(file, specifiers)
309
+ }
310
+ for (const specifier of specifiers) {
311
+ const found = probe(join(dirname(file), withoutQuery(specifier)))
312
+ if (found !== undefined) reach(found, side)
313
+ }
314
+ }
315
+ return { owners, unmapped: [...unmapped].sort() }
316
+ }
317
+
318
+ /**
319
+ * The `package.json` of the installed package `name`, as Node finds it: the nearest
320
+ * `node_modules/<name>` at or above `fromDir`.
321
+ */
322
+ export function installedManifest(fromDir: string, name: string): string | undefined {
323
+ let dir = fromDir
324
+ for (;;) {
325
+ const manifest = join(dir, "node_modules", name, "package.json")
326
+ if (isFile(manifest)) return manifest
327
+ const parent = dirname(dir)
328
+ if (parent === dir) return undefined
329
+ dir = parent
330
+ }
331
+ }