@nifrajs/web 3.5.0 → 4.0.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 (390) hide show
  1. package/dist/backend-only.d.ts +15 -0
  2. package/dist/backend-only.d.ts.map +1 -0
  3. package/dist/backend-only.js +16 -0
  4. package/dist/backend-only.js.map +1 -0
  5. package/dist/boundary.d.ts +5 -0
  6. package/dist/boundary.d.ts.map +1 -1
  7. package/dist/boundary.js +11 -2
  8. package/dist/boundary.js.map +1 -1
  9. package/dist/build-plan.d.ts +18 -6
  10. package/dist/build-plan.d.ts.map +1 -1
  11. package/dist/build-plan.js +82 -34
  12. package/dist/build-plan.js.map +1 -1
  13. package/dist/build-vite.d.ts +4 -0
  14. package/dist/build-vite.d.ts.map +1 -1
  15. package/dist/build-vite.js +68 -13
  16. package/dist/build-vite.js.map +1 -1
  17. package/dist/build.d.ts +57 -23
  18. package/dist/build.d.ts.map +1 -1
  19. package/dist/build.js +356 -85
  20. package/dist/build.js.map +1 -1
  21. package/dist/bun-dev-entry.d.ts +1 -1
  22. package/dist/bun-dev-entry.js +1 -1
  23. package/dist/cdn.d.ts +74 -0
  24. package/dist/cdn.d.ts.map +1 -0
  25. package/dist/cdn.js +132 -0
  26. package/dist/cdn.js.map +1 -0
  27. package/dist/client.d.ts +3 -1
  28. package/dist/client.d.ts.map +1 -1
  29. package/dist/client.js +111 -15
  30. package/dist/client.js.map +1 -1
  31. package/dist/conformance.d.ts +4 -3
  32. package/dist/conformance.d.ts.map +1 -1
  33. package/dist/conformance.js +12 -3
  34. package/dist/conformance.js.map +1 -1
  35. package/dist/csp.d.ts +93 -0
  36. package/dist/csp.d.ts.map +1 -0
  37. package/dist/csp.js +122 -0
  38. package/dist/csp.js.map +1 -0
  39. package/dist/dev-client.d.ts +76 -0
  40. package/dist/dev-client.d.ts.map +1 -0
  41. package/dist/dev-client.js +280 -0
  42. package/dist/dev-client.js.map +1 -0
  43. package/dist/dev-diagnostics.d.ts +26 -2
  44. package/dist/dev-diagnostics.d.ts.map +1 -1
  45. package/dist/dev-diagnostics.js +38 -7
  46. package/dist/dev-diagnostics.js.map +1 -1
  47. package/dist/dev-error.d.ts +4 -13
  48. package/dist/dev-error.d.ts.map +1 -1
  49. package/dist/dev-error.js +46 -4
  50. package/dist/dev-error.js.map +1 -1
  51. package/dist/dev-feed.d.ts +298 -0
  52. package/dist/dev-feed.d.ts.map +1 -0
  53. package/dist/dev-feed.js +797 -0
  54. package/dist/dev-feed.js.map +1 -0
  55. package/dist/dev-indicator.d.ts +38 -0
  56. package/dist/dev-indicator.d.ts.map +1 -0
  57. package/dist/dev-indicator.js +93 -0
  58. package/dist/dev-indicator.js.map +1 -0
  59. package/dist/dev-session.d.ts +77 -0
  60. package/dist/dev-session.d.ts.map +1 -0
  61. package/dist/dev-session.js +580 -0
  62. package/dist/dev-session.js.map +1 -0
  63. package/dist/dev-sourcemap.d.ts +27 -0
  64. package/dist/dev-sourcemap.d.ts.map +1 -0
  65. package/dist/dev-sourcemap.js +235 -0
  66. package/dist/dev-sourcemap.js.map +1 -0
  67. package/dist/dev-ssr-graph.d.ts.map +1 -1
  68. package/dist/dev-ssr-graph.js +13 -5
  69. package/dist/dev-ssr-graph.js.map +1 -1
  70. package/dist/dev.d.ts +15 -2
  71. package/dist/dev.d.ts.map +1 -1
  72. package/dist/dev.js +69 -44
  73. package/dist/dev.js.map +1 -1
  74. package/dist/diagnostic-catalog.d.ts +35 -0
  75. package/dist/diagnostic-catalog.d.ts.map +1 -0
  76. package/dist/diagnostic-catalog.js +203 -0
  77. package/dist/diagnostic-catalog.js.map +1 -0
  78. package/dist/diagnostic-prompt.d.ts +49 -0
  79. package/dist/diagnostic-prompt.d.ts.map +1 -0
  80. package/dist/diagnostic-prompt.js +303 -0
  81. package/dist/diagnostic-prompt.js.map +1 -0
  82. package/dist/diagnostic.d.ts +17 -23
  83. package/dist/diagnostic.d.ts.map +1 -1
  84. package/dist/diagnostic.js +31 -39
  85. package/dist/diagnostic.js.map +1 -1
  86. package/dist/draft.d.ts.map +1 -1
  87. package/dist/draft.js +4 -1
  88. package/dist/draft.js.map +1 -1
  89. package/dist/fn.d.ts +5 -0
  90. package/dist/fn.d.ts.map +1 -1
  91. package/dist/fn.js +13 -3
  92. package/dist/fn.js.map +1 -1
  93. package/dist/fs.d.ts.map +1 -1
  94. package/dist/fs.js +4 -2
  95. package/dist/fs.js.map +1 -1
  96. package/dist/index.d.ts +13 -15
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +11 -12
  99. package/dist/index.js.map +1 -1
  100. package/dist/internal/cdn/cloudflare.d.ts +48 -0
  101. package/dist/internal/cdn/cloudflare.d.ts.map +1 -0
  102. package/dist/internal/cdn/cloudflare.js +94 -0
  103. package/dist/internal/cdn/cloudflare.js.map +1 -0
  104. package/dist/internal/cdn/core.d.ts +91 -0
  105. package/dist/internal/cdn/core.d.ts.map +1 -0
  106. package/dist/internal/cdn/core.js +220 -0
  107. package/dist/internal/cdn/core.js.map +1 -0
  108. package/dist/internal/cdn/fastly.d.ts +17 -0
  109. package/dist/internal/cdn/fastly.d.ts.map +1 -0
  110. package/dist/internal/cdn/fastly.js +43 -0
  111. package/dist/internal/cdn/fastly.js.map +1 -0
  112. package/dist/internal/cdn/vercel.d.ts +31 -0
  113. package/dist/internal/cdn/vercel.d.ts.map +1 -0
  114. package/dist/internal/cdn/vercel.js +56 -0
  115. package/dist/internal/cdn/vercel.js.map +1 -0
  116. package/dist/internal/code-unit-order.d.ts +4 -0
  117. package/dist/internal/code-unit-order.d.ts.map +1 -0
  118. package/dist/internal/code-unit-order.js +6 -0
  119. package/dist/internal/code-unit-order.js.map +1 -0
  120. package/dist/internal/codegen.d.ts.map +1 -1
  121. package/dist/internal/codegen.js +141 -25
  122. package/dist/internal/codegen.js.map +1 -1
  123. package/dist/internal/dev-csp.d.ts +24 -0
  124. package/dist/internal/dev-csp.d.ts.map +1 -0
  125. package/dist/internal/dev-csp.js +160 -0
  126. package/dist/internal/dev-csp.js.map +1 -0
  127. package/dist/internal/dev-reserved.d.ts +25 -0
  128. package/dist/internal/dev-reserved.d.ts.map +1 -0
  129. package/dist/internal/dev-reserved.js +39 -0
  130. package/dist/internal/dev-reserved.js.map +1 -0
  131. package/dist/internal/html-spans.d.ts +10 -0
  132. package/dist/internal/html-spans.d.ts.map +1 -0
  133. package/dist/internal/html-spans.js +46 -0
  134. package/dist/internal/html-spans.js.map +1 -0
  135. package/dist/internal/loading-runtime.d.ts +44 -0
  136. package/dist/internal/loading-runtime.d.ts.map +1 -0
  137. package/dist/internal/loading-runtime.js +206 -0
  138. package/dist/internal/loading-runtime.js.map +1 -0
  139. package/dist/internal/matches-runtime.d.ts +8 -0
  140. package/dist/internal/matches-runtime.d.ts.map +1 -0
  141. package/dist/internal/matches-runtime.js +61 -0
  142. package/dist/internal/matches-runtime.js.map +1 -0
  143. package/dist/internal/mount-shadow.d.ts +36 -0
  144. package/dist/internal/mount-shadow.d.ts.map +1 -0
  145. package/dist/internal/mount-shadow.js +65 -0
  146. package/dist/internal/mount-shadow.js.map +1 -0
  147. package/dist/internal/node-builtins.d.ts +3 -0
  148. package/dist/internal/node-builtins.d.ts.map +1 -0
  149. package/dist/internal/node-builtins.js +79 -0
  150. package/dist/internal/node-builtins.js.map +1 -0
  151. package/dist/internal/output-guard.d.ts +65 -0
  152. package/dist/internal/output-guard.d.ts.map +1 -0
  153. package/dist/internal/output-guard.js +630 -0
  154. package/dist/internal/output-guard.js.map +1 -0
  155. package/dist/internal/page-execution.d.ts +20 -8
  156. package/dist/internal/page-execution.d.ts.map +1 -1
  157. package/dist/internal/page-execution.js +571 -105
  158. package/dist/internal/page-execution.js.map +1 -1
  159. package/dist/internal/parity.d.ts +21 -0
  160. package/dist/internal/parity.d.ts.map +1 -1
  161. package/dist/internal/parity.js +104 -22
  162. package/dist/internal/parity.js.map +1 -1
  163. package/dist/internal/private-env.d.ts +12 -0
  164. package/dist/internal/private-env.d.ts.map +1 -0
  165. package/dist/internal/private-env.js +335 -0
  166. package/dist/internal/private-env.js.map +1 -0
  167. package/dist/internal/public-url.d.ts +3 -0
  168. package/dist/internal/public-url.d.ts.map +1 -0
  169. package/dist/internal/public-url.js +18 -0
  170. package/dist/internal/public-url.js.map +1 -0
  171. package/dist/internal/render-document.d.ts +25 -19
  172. package/dist/internal/render-document.d.ts.map +1 -1
  173. package/dist/internal/render-document.js +77 -61
  174. package/dist/internal/render-document.js.map +1 -1
  175. package/dist/internal/response-controls.d.ts +75 -0
  176. package/dist/internal/response-controls.d.ts.map +1 -0
  177. package/dist/internal/response-controls.js +256 -0
  178. package/dist/internal/response-controls.js.map +1 -0
  179. package/dist/internal/runtime-contract.d.ts +11 -16
  180. package/dist/internal/runtime-contract.d.ts.map +1 -1
  181. package/dist/internal/runtime-contract.js.map +1 -1
  182. package/dist/internal/secret-scan.d.ts +104 -0
  183. package/dist/internal/secret-scan.d.ts.map +1 -0
  184. package/dist/internal/secret-scan.js +485 -0
  185. package/dist/internal/secret-scan.js.map +1 -0
  186. package/dist/internal/server-boundary.d.ts +6 -29
  187. package/dist/internal/server-boundary.d.ts.map +1 -1
  188. package/dist/internal/server-boundary.js +6 -66
  189. package/dist/internal/server-boundary.js.map +1 -1
  190. package/dist/internal/source-map.d.ts +47 -0
  191. package/dist/internal/source-map.d.ts.map +1 -0
  192. package/dist/internal/source-map.js +225 -0
  193. package/dist/internal/source-map.js.map +1 -0
  194. package/dist/internal/target-compat.d.ts +27 -0
  195. package/dist/internal/target-compat.d.ts.map +1 -0
  196. package/dist/internal/target-compat.js +77 -0
  197. package/dist/internal/target-compat.js.map +1 -0
  198. package/dist/internal/timing-safe-equal.d.ts +6 -0
  199. package/dist/internal/timing-safe-equal.d.ts.map +1 -1
  200. package/dist/internal/timing-safe-equal.js +10 -0
  201. package/dist/internal/timing-safe-equal.js.map +1 -1
  202. package/dist/internal/vitals-runtime.d.ts +18 -0
  203. package/dist/internal/vitals-runtime.d.ts.map +1 -0
  204. package/dist/internal/vitals-runtime.js +38 -0
  205. package/dist/internal/vitals-runtime.js.map +1 -0
  206. package/dist/internal/web-app.d.ts +38 -9
  207. package/dist/internal/web-app.d.ts.map +1 -1
  208. package/dist/internal/web-app.js +199 -59
  209. package/dist/internal/web-app.js.map +1 -1
  210. package/dist/internal/zone-graph.d.ts +89 -0
  211. package/dist/internal/zone-graph.d.ts.map +1 -0
  212. package/dist/internal/zone-graph.js +492 -0
  213. package/dist/internal/zone-graph.js.map +1 -0
  214. package/dist/isr.d.ts +83 -6
  215. package/dist/isr.d.ts.map +1 -1
  216. package/dist/isr.js +263 -36
  217. package/dist/isr.js.map +1 -1
  218. package/dist/llms-txt.d.ts.map +1 -1
  219. package/dist/llms-txt.js +31 -6
  220. package/dist/llms-txt.js.map +1 -1
  221. package/dist/manifest.d.ts +220 -13
  222. package/dist/manifest.d.ts.map +1 -1
  223. package/dist/manifest.js +386 -9
  224. package/dist/manifest.js.map +1 -1
  225. package/dist/module-graph.d.ts +26 -5
  226. package/dist/module-graph.d.ts.map +1 -1
  227. package/dist/module-graph.js +17 -7
  228. package/dist/module-graph.js.map +1 -1
  229. package/dist/navigation.d.ts +17 -3
  230. package/dist/navigation.d.ts.map +1 -1
  231. package/dist/navigation.js +11 -5
  232. package/dist/navigation.js.map +1 -1
  233. package/dist/nonce.d.ts +47 -0
  234. package/dist/nonce.d.ts.map +1 -0
  235. package/dist/nonce.js +63 -0
  236. package/dist/nonce.js.map +1 -0
  237. package/dist/plugins/css-modules.d.ts.map +1 -1
  238. package/dist/plugins/css-modules.js +4 -3
  239. package/dist/plugins/css-modules.js.map +1 -1
  240. package/dist/plugins/kit.d.ts +9 -0
  241. package/dist/plugins/kit.d.ts.map +1 -1
  242. package/dist/plugins/kit.js +18 -0
  243. package/dist/plugins/kit.js.map +1 -1
  244. package/dist/plugins/svg.d.ts +22 -3
  245. package/dist/plugins/svg.d.ts.map +1 -1
  246. package/dist/plugins/svg.js +112 -1
  247. package/dist/plugins/svg.js.map +1 -1
  248. package/dist/plugins/vite-leak-guard.d.ts +107 -3
  249. package/dist/plugins/vite-leak-guard.d.ts.map +1 -1
  250. package/dist/plugins/vite-leak-guard.js +378 -17
  251. package/dist/plugins/vite-leak-guard.js.map +1 -1
  252. package/dist/plugins/vite-zone-guard.d.ts +61 -0
  253. package/dist/plugins/vite-zone-guard.d.ts.map +1 -0
  254. package/dist/plugins/vite-zone-guard.js +208 -0
  255. package/dist/plugins/vite-zone-guard.js.map +1 -0
  256. package/dist/plugins/zone-guard.d.ts +27 -0
  257. package/dist/plugins/zone-guard.d.ts.map +1 -0
  258. package/dist/plugins/zone-guard.js +72 -0
  259. package/dist/plugins/zone-guard.js.map +1 -0
  260. package/dist/prerender.d.ts +10 -0
  261. package/dist/prerender.d.ts.map +1 -1
  262. package/dist/prerender.js +35 -3
  263. package/dist/prerender.js.map +1 -1
  264. package/dist/public-dir.d.ts +9 -0
  265. package/dist/public-dir.d.ts.map +1 -1
  266. package/dist/public-dir.js +67 -9
  267. package/dist/public-dir.js.map +1 -1
  268. package/dist/pwa-manifest.d.ts +68 -0
  269. package/dist/pwa-manifest.d.ts.map +1 -0
  270. package/dist/pwa-manifest.js +178 -0
  271. package/dist/pwa-manifest.js.map +1 -0
  272. package/dist/query.js +4 -4
  273. package/dist/query.js.map +1 -1
  274. package/dist/render-seam.d.ts +42 -2
  275. package/dist/render-seam.d.ts.map +1 -1
  276. package/dist/render-seam.js +6 -0
  277. package/dist/render-seam.js.map +1 -1
  278. package/dist/route-manifest.d.ts +3 -0
  279. package/dist/route-manifest.d.ts.map +1 -1
  280. package/dist/route-manifest.js +26 -3
  281. package/dist/route-manifest.js.map +1 -1
  282. package/dist/route-types.d.ts +24 -0
  283. package/dist/route-types.d.ts.map +1 -0
  284. package/dist/route-types.js +195 -0
  285. package/dist/route-types.js.map +1 -0
  286. package/dist/router.d.ts +28 -6
  287. package/dist/router.d.ts.map +1 -1
  288. package/dist/router.js +129 -40
  289. package/dist/router.js.map +1 -1
  290. package/dist/vitals.d.ts +33 -0
  291. package/dist/vitals.d.ts.map +1 -0
  292. package/dist/vitals.js +16 -0
  293. package/dist/vitals.js.map +1 -0
  294. package/dist/vite.d.ts +16 -1
  295. package/dist/vite.d.ts.map +1 -1
  296. package/dist/vite.js +187 -36
  297. package/dist/vite.js.map +1 -1
  298. package/dist/zones.d.ts +70 -0
  299. package/dist/zones.d.ts.map +1 -0
  300. package/dist/zones.js +365 -0
  301. package/dist/zones.js.map +1 -0
  302. package/package.json +67 -14
  303. package/src/backend-only.ts +16 -0
  304. package/src/boundary.ts +18 -5
  305. package/src/build-plan.ts +90 -35
  306. package/src/build-vite.ts +77 -11
  307. package/src/build.ts +466 -96
  308. package/src/bun-dev-entry.ts +1 -1
  309. package/src/cdn.ts +216 -0
  310. package/src/client.ts +111 -18
  311. package/src/conformance.ts +16 -3
  312. package/src/csp.ts +194 -0
  313. package/src/dev-client.ts +349 -0
  314. package/src/dev-diagnostics.ts +60 -7
  315. package/src/dev-error.ts +49 -5
  316. package/src/dev-feed.ts +1140 -0
  317. package/src/dev-indicator.ts +113 -0
  318. package/src/dev-session.ts +729 -0
  319. package/src/dev-sourcemap.ts +281 -0
  320. package/src/dev-ssr-graph.ts +16 -5
  321. package/src/dev.ts +86 -43
  322. package/src/diagnostic-catalog.ts +243 -0
  323. package/src/diagnostic-prompt.ts +355 -0
  324. package/src/diagnostic.ts +63 -66
  325. package/src/draft.ts +4 -1
  326. package/src/fn.ts +19 -3
  327. package/src/fs.ts +13 -2
  328. package/src/index.ts +42 -10
  329. package/src/internal/cdn/cloudflare.ts +146 -0
  330. package/src/internal/cdn/core.ts +316 -0
  331. package/src/internal/cdn/fastly.ts +62 -0
  332. package/src/internal/cdn/vercel.ts +95 -0
  333. package/src/internal/code-unit-order.ts +5 -0
  334. package/src/internal/codegen.ts +161 -24
  335. package/src/internal/dev-csp.ts +176 -0
  336. package/src/internal/dev-reserved.ts +52 -0
  337. package/src/internal/html-spans.ts +50 -0
  338. package/src/internal/loading-runtime.ts +244 -0
  339. package/src/internal/matches-runtime.ts +62 -0
  340. package/src/internal/mount-shadow.ts +88 -0
  341. package/src/internal/node-builtins.ts +79 -0
  342. package/src/internal/output-guard.ts +701 -0
  343. package/src/internal/page-execution.ts +795 -185
  344. package/src/internal/parity.ts +150 -36
  345. package/src/internal/private-env.ts +334 -0
  346. package/src/internal/public-url.ts +22 -0
  347. package/src/internal/render-document.ts +114 -67
  348. package/src/internal/response-controls.ts +284 -0
  349. package/src/internal/runtime-contract.ts +10 -15
  350. package/src/internal/secret-scan.ts +623 -0
  351. package/src/internal/server-boundary.ts +6 -69
  352. package/src/internal/source-map.ts +256 -0
  353. package/src/internal/target-compat.ts +92 -0
  354. package/src/internal/timing-safe-equal.ts +13 -0
  355. package/src/internal/vitals-runtime.ts +53 -0
  356. package/src/internal/web-app.ts +262 -84
  357. package/src/internal/zone-graph.ts +593 -0
  358. package/src/isr.ts +325 -37
  359. package/src/llms-txt.ts +28 -4
  360. package/src/manifest.ts +670 -16
  361. package/src/module-graph.ts +53 -9
  362. package/src/navigation.ts +29 -6
  363. package/src/nonce.ts +104 -0
  364. package/src/plugins/css-modules.ts +5 -3
  365. package/src/plugins/kit.ts +24 -0
  366. package/src/plugins/svg.ts +135 -4
  367. package/src/plugins/vite-leak-guard.ts +529 -16
  368. package/src/plugins/vite-zone-guard.ts +263 -0
  369. package/src/plugins/zone-guard.ts +110 -0
  370. package/src/prerender.ts +49 -3
  371. package/src/public-dir.ts +69 -8
  372. package/src/pwa-manifest.ts +226 -0
  373. package/src/query.ts +4 -4
  374. package/src/render-seam.ts +46 -1
  375. package/src/route-manifest.ts +15 -3
  376. package/src/route-types.ts +264 -0
  377. package/src/router.ts +163 -63
  378. package/src/vitals.ts +44 -0
  379. package/src/vite.ts +207 -36
  380. package/src/zones.ts +430 -0
  381. package/dist/plugins/vite-server-only.d.ts +0 -49
  382. package/dist/plugins/vite-server-only.d.ts.map +0 -1
  383. package/dist/plugins/vite-server-only.js +0 -57
  384. package/dist/plugins/vite-server-only.js.map +0 -1
  385. package/dist/server-only.d.ts +0 -21
  386. package/dist/server-only.d.ts.map +0 -1
  387. package/dist/server-only.js +0 -25
  388. package/dist/server-only.js.map +0 -1
  389. package/src/plugins/vite-server-only.ts +0 -75
  390. package/src/server-only.ts +0 -25
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The browser half of the dev feed: a small inline script a dev server puts first in each page's
3
+ * `<head>`, so the agent sees what the page did after it left the server - uncaught errors, unhandled
4
+ * rejections, failed script/stylesheet loads, hydration mismatches and console output.
5
+ *
6
+ * Inline and first, rather than a module, so it is listening before any module (the framework, the
7
+ * HMR client, the app) runs. Dev only: nothing here is reachable from a production build.
8
+ */
9
+ import { type DevLogLevel } from "./dev-feed.js";
10
+ export interface DevClientConfig {
11
+ /** Where the batches go (same origin). */
12
+ readonly ingestPath: string;
13
+ /** Proves a batch came from a page this server served. */
14
+ readonly pageToken: string;
15
+ /** The request that rendered this document: browser entries from it carry the same id. */
16
+ readonly requestId?: string | undefined;
17
+ /** The document's path + search, so a client-side navigation away stops claiming that request. */
18
+ readonly documentPath?: string | undefined;
19
+ /** The issues indicator module, loaded on the first error the server answers for; none when off. */
20
+ readonly indicatorPath?: string | undefined;
21
+ }
22
+ /** The script's text (without the `<script>` element). */
23
+ export declare function devClientSource(config: DevClientConfig): string;
24
+ /** The CSP source that admits exactly `source`. */
25
+ export declare function scriptHash(source: string): string;
26
+ /** Whether a response is a page the script belongs in: HTML, with a body nobody has encoded yet. */
27
+ export declare function isInjectablePage(response: Response, method: string): boolean;
28
+ /**
29
+ * Prepare `headers` for the script: admit it in the page's CSP, by hash unless `nonced` (the caller
30
+ * puts a nonce on every script afterwards). Returns the `<script>` element to insert, or undefined
31
+ * when the page's CSP forbids scripts and nothing should be inserted.
32
+ */
33
+ export declare function devClientTag(config: DevClientConfig, headers: Headers, origin: string, nonced?: boolean): string | undefined;
34
+ /** `html` with `tag` inserted into its head; unchanged when there is no `<head>`. */
35
+ export declare function injectIntoHtml(html: string, tag: string): string;
36
+ /**
37
+ * Stream `body` with `tag` inserted into its head. Only the prefix up to the insertion point is held
38
+ * back; the rest streams through untouched, so a streamed SSR page keeps its first-byte time.
39
+ */
40
+ export declare function injectIntoStream(body: ReadableStream<Uint8Array>, tag: string): ReadableStream<Uint8Array>;
41
+ /** One batch is bounded by what `fetch(keepalive)` may carry. */
42
+ export declare const CLIENT_BATCH_MAX_BYTES: number;
43
+ export declare const CLIENT_BATCH_MAX_EVENTS = 50;
44
+ interface EventContext {
45
+ readonly page: string;
46
+ readonly requestId?: string | undefined;
47
+ }
48
+ export interface BrowserError {
49
+ readonly name: string;
50
+ readonly message: string;
51
+ readonly stack: string;
52
+ }
53
+ export type ClientEvent = EventContext & ({
54
+ readonly kind: "error" | "rejection";
55
+ readonly name: string;
56
+ readonly message: string;
57
+ readonly stack: string;
58
+ } | {
59
+ readonly kind: "resource";
60
+ readonly tag: string;
61
+ readonly url: string;
62
+ } | {
63
+ readonly kind: "console";
64
+ readonly level: DevLogLevel;
65
+ readonly message: string;
66
+ /** The first Error a `console.error` call was given: frameworks report caught errors so. */
67
+ readonly error?: BrowserError | undefined;
68
+ });
69
+ export interface ClientBatch {
70
+ readonly token: string;
71
+ readonly events: readonly ClientEvent[];
72
+ }
73
+ /** A batch the script could have sent, or undefined. Malformed events are dropped, not fatal. */
74
+ export declare function parseClientBatch(value: unknown): ClientBatch | undefined;
75
+ export {};
76
+ //# sourceMappingURL=dev-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-client.d.ts","sourceRoot":"","sources":["../src/dev-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,KAAK,WAAW,EAAiB,MAAM,eAAe,CAAA;AAG/D,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,0FAA0F;IAC1F,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,kGAAkG;IAClG,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1C,oGAAoG;IACpG,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5C;AA0FD,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAQ/D;AAED,mDAAmD;AACnD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAK5E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,UAAQ,GACb,MAAM,GAAG,SAAS,CASpB;AA2BD,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGhE;AAYD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,EAChC,GAAG,EAAE,MAAM,GACV,cAAc,CAAC,UAAU,CAAC,CAuC5B;AAMD,iEAAiE;AACjE,eAAO,MAAM,sBAAsB,QAAY,CAAA;AAC/C,eAAO,MAAM,uBAAuB,KAAK,CAAA;AAEzC,UAAU,YAAY;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,MAAM,WAAW,GAAG,YAAY,GACpC,CACI;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CAAA;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACzE;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,4FAA4F;IAC5F,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,GAAG,SAAS,CAAA;CAC1C,CACJ,CAAA;AAEH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAA;CACxC;AAiDD,iGAAiG;AACjG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,CAUxE"}
@@ -0,0 +1,280 @@
1
+ /**
2
+ * The browser half of the dev feed: a small inline script a dev server puts first in each page's
3
+ * `<head>`, so the agent sees what the page did after it left the server - uncaught errors, unhandled
4
+ * rejections, failed script/stylesheet loads, hydration mismatches and console output.
5
+ *
6
+ * Inline and first, rather than a module, so it is listening before any module (the framework, the
7
+ * HMR client, the app) runs. Dev only: nothing here is reachable from a production build.
8
+ */
9
+ import { createHash } from "node:crypto";
10
+ import { isDevLogLevel } from "./dev-feed.js";
11
+ import { admitInlineScript } from "./internal/dev-csp.js";
12
+ // ES2017, no dependencies, one global: `__nifraDevClient`, the idempotence flag that also queues issues
13
+ // for the indicator module. Keep it small: it ships in every dev page, and its hash goes into every CSP
14
+ // that needs one.
15
+ const CLIENT_SOURCE = String.raw `(function(C){
16
+ if(window.__nifraDevClient)return;var S=window.__nifraDevClient={issues:[]};
17
+ var nonce=document.currentScript&&document.currentScript.nonce,loading=0;
18
+ var q=[],timer=0,inside=0,MSG=8000,STACK=16000;
19
+ function cap(s,n){s=String(s);return s.length>n?s.slice(0,n)+"...":s}
20
+ function where(){return location.pathname+location.search}
21
+ function ser(v,d){
22
+ if(typeof v==="string")return v;
23
+ if(v instanceof Error)return v.stack||v.name+": "+v.message;
24
+ if(typeof v==="function")return"[Function "+(v.name||"anonymous")+"]";
25
+ if(typeof v!=="object"||v===null)return String(v);
26
+ if(typeof Element!=="undefined"&&v instanceof Element)return"<"+v.tagName.toLowerCase()+(v.id?"#"+v.id:"")+">";
27
+ if(d>2)return Array.isArray(v)?"[Array]":"[Object]";
28
+ var seen=[];
29
+ try{return JSON.stringify(v,function(k,x){
30
+ if(typeof x==="object"&&x!==null){if(seen.indexOf(x)!==-1)return"[Circular]";seen.push(x)}
31
+ if(typeof x==="bigint")return x+"n";
32
+ if(x instanceof Error)return x.name+": "+x.message;
33
+ return x})}catch(e){return Object.prototype.toString.call(v)}}
34
+ function fmt(a){
35
+ var args=Array.prototype.slice.call(a),out=[];
36
+ if(typeof args[0]==="string"&&args[0].indexOf("%")!==-1){
37
+ var rest=args.slice(1);
38
+ out.push(args[0].replace(/%([sdifoOjc%])/g,function(m,k){
39
+ if(k==="%")return"%";
40
+ if(!rest.length)return m;
41
+ var v=rest.shift();
42
+ if(k==="c")return"";
43
+ if(k==="d"||k==="i")return String(parseInt(v,10));
44
+ if(k==="f")return String(parseFloat(v));
45
+ return ser(v,0)}));
46
+ args=rest}
47
+ for(var i=0;i<args.length;i++)out.push(ser(args[i],0));
48
+ return out.join(" ")}
49
+ function send(keep){
50
+ clearTimeout(timer);timer=0;
51
+ while(q.length){
52
+ var body=JSON.stringify({token:C.t,events:q.splice(0,50)});
53
+ try{fetch(C.u,{method:"POST",body:body,keepalive:!!keep&&body.length<60000,headers:{"content-type":"application/json"},credentials:"same-origin"}).then(function(r){if(r.status===200&&C.i)return r.json().then(issues)}).catch(function(){})}catch(e){}}}
54
+ function issues(j){
55
+ var list=j&&j.issues;if(!list||!list.length)return;
56
+ if(S.indicator){S.indicator.add(list);return}
57
+ S.issues=S.issues.concat(list);if(loading)return;loading=1;
58
+ var s=document.createElement("script");s.type="module";s.src=C.i;if(nonce)s.nonce=nonce;
59
+ (document.head||document.documentElement).appendChild(s)}
60
+ function push(e){
61
+ e.page=cap(where(),2000);
62
+ if(C.r&&e.page===C.p)e.requestId=C.r;
63
+ q.push(e);
64
+ if(q.length>=50)send(false);else if(!timer)timer=setTimeout(send,100)}
65
+ ["debug","info","log","warn","error"].forEach(function(level){
66
+ var orig=console[level];if(typeof orig!=="function")return;
67
+ console[level]=function(){
68
+ if(!inside){inside=1;try{
69
+ var ev={kind:"console",level:level,message:cap(fmt(arguments),MSG)};
70
+ if(level==="error")for(var i=0;i<arguments.length;i++){var x=arguments[i];
71
+ if(x instanceof Error){ev.error={name:cap(x.name,200),message:cap(x.message,MSG),stack:cap(x.stack||"",STACK)};break}}
72
+ push(ev)}catch(e){}inside=0}
73
+ return orig.apply(this,arguments)}});
74
+ addEventListener("error",function(ev){
75
+ var t=ev.target;
76
+ if(t&&t!==window&&t.tagName){
77
+ var tag=t.tagName.toLowerCase(),rel=(t.rel||"").toLowerCase();
78
+ if(tag==="script"||(tag==="link"&&/stylesheet|modulepreload|preload/.test(rel)))push({kind:"resource",tag:tag,url:cap(t.src||t.href||"",2000)});
79
+ return}
80
+ var e=ev.error;
81
+ if(!e&&ev.message==="Script error.")return;
82
+ push({kind:"error",name:cap(e&&e.name?e.name:"Error",200),message:cap(e&&e.message!=null?e.message:ev.message,MSG),
83
+ stack:cap(e&&e.stack?e.stack:(ev.filename?" at "+ev.filename+":"+ev.lineno+":"+ev.colno:""),STACK)})},true);
84
+ addEventListener("unhandledrejection",function(ev){
85
+ var r=ev.reason;
86
+ if(r instanceof Error)push({kind:"rejection",name:cap(r.name,200),message:cap(r.message,MSG),stack:cap(r.stack||"",STACK)});
87
+ else push({kind:"rejection",name:"UnhandledRejection",message:cap(ser(r,0),MSG)})});
88
+ addEventListener("pagehide",function(){send(true)});
89
+ document.addEventListener("visibilitychange",function(){if(document.visibilityState==="hidden")send(true)});
90
+ })`;
91
+ // `</script` inside a JSON value would end the element early; `<!--` can start a script-data escape.
92
+ const scriptSafe = (json) => json
93
+ .replaceAll("<", "\\u003c")
94
+ .replaceAll(">", "\\u003e")
95
+ .replaceAll("\u2028", "\\u2028")
96
+ .replaceAll("\u2029", "\\u2029");
97
+ /** The script's text (without the `<script>` element). */
98
+ export function devClientSource(config) {
99
+ const settings = { u: config.ingestPath, t: config.pageToken };
100
+ if (config.indicatorPath !== undefined)
101
+ settings.i = config.indicatorPath;
102
+ if (config.requestId !== undefined && config.documentPath !== undefined) {
103
+ settings.r = config.requestId;
104
+ settings.p = config.documentPath;
105
+ }
106
+ return `${CLIENT_SOURCE}(${scriptSafe(JSON.stringify(settings))})`;
107
+ }
108
+ /** The CSP source that admits exactly `source`. */
109
+ export function scriptHash(source) {
110
+ return `'sha256-${createHash("sha256").update(source).digest("base64")}'`;
111
+ }
112
+ /** Whether a response is a page the script belongs in: HTML, with a body nobody has encoded yet. */
113
+ export function isInjectablePage(response, method) {
114
+ if (method === "HEAD" || response.body === null)
115
+ return false;
116
+ if (response.status === 204 || response.status === 304)
117
+ return false;
118
+ if (response.headers.has("content-encoding"))
119
+ return false;
120
+ return (response.headers.get("content-type") ?? "").toLowerCase().includes("text/html");
121
+ }
122
+ /**
123
+ * Prepare `headers` for the script: admit it in the page's CSP, by hash unless `nonced` (the caller
124
+ * puts a nonce on every script afterwards). Returns the `<script>` element to insert, or undefined
125
+ * when the page's CSP forbids scripts and nothing should be inserted.
126
+ */
127
+ export function devClientTag(config, headers, origin, nonced = false) {
128
+ const source = devClientSource(config);
129
+ const hash = nonced ? undefined : scriptHash(source);
130
+ // A nonced client hands its nonce to the module it loads, so only a hashed one needs the URL admitted.
131
+ const indicator = nonced || config.indicatorPath === undefined ? undefined : new URL(config.indicatorPath, origin);
132
+ if (!admitInlineScript(headers, hash, new URL(config.ingestPath, origin), indicator))
133
+ return undefined;
134
+ return `<script data-nifra-dev>${source}</script>`;
135
+ }
136
+ // Latin-1 views keep string offsets equal to byte offsets, so a match position is a splice point.
137
+ const latin1 = new TextDecoder("latin1");
138
+ const HEAD_OPEN = /<head(?:\s[^>]*)?>/i;
139
+ const META_CHARSET = /^\s*<meta\s[^>]*charset\s*=[^>]*>/i;
140
+ // Past this, a page without `<head>` is a fragment: stop looking and stream it as it is.
141
+ const HEAD_SEARCH_LIMIT = 64 * 1024;
142
+ // Enough to see a `<meta charset>` that immediately follows `<head>`.
143
+ const META_LOOKAHEAD = 256;
144
+ /** Where the script goes in `text`: after `<head>`, and after a `<meta charset>` that leads it. */
145
+ function insertionPoint(text, final) {
146
+ const head = HEAD_OPEN.exec(text);
147
+ if (head === null) {
148
+ const body = /<body[\s>]/i.test(text);
149
+ return final || body || text.length > HEAD_SEARCH_LIMIT ? "none" : "wait";
150
+ }
151
+ const afterHead = head.index + head[0].length;
152
+ const rest = text.slice(afterHead);
153
+ const meta = META_CHARSET.exec(rest);
154
+ if (meta !== null)
155
+ return afterHead + meta[0].length;
156
+ if (!final && rest.length < META_LOOKAHEAD && !/<(?!meta)/i.test(rest.replace(/^\s+/, "")))
157
+ return "wait";
158
+ return afterHead;
159
+ }
160
+ /** `html` with `tag` inserted into its head; unchanged when there is no `<head>`. */
161
+ export function injectIntoHtml(html, tag) {
162
+ const at = insertionPoint(html, true);
163
+ return typeof at === "number" ? html.slice(0, at) + tag + html.slice(at) : html;
164
+ }
165
+ function concat(chunks, length) {
166
+ const out = new Uint8Array(length);
167
+ let offset = 0;
168
+ for (const chunk of chunks) {
169
+ out.set(chunk, offset);
170
+ offset += chunk.byteLength;
171
+ }
172
+ return out;
173
+ }
174
+ /**
175
+ * Stream `body` with `tag` inserted into its head. Only the prefix up to the insertion point is held
176
+ * back; the rest streams through untouched, so a streamed SSR page keeps its first-byte time.
177
+ */
178
+ export function injectIntoStream(body, tag) {
179
+ const insert = new TextEncoder().encode(tag);
180
+ const held = [];
181
+ let heldBytes = 0;
182
+ let done = false;
183
+ const release = (controller, final) => {
184
+ const bytes = concat(held, heldBytes);
185
+ const at = insertionPoint(latin1.decode(bytes), final);
186
+ if (at === "wait")
187
+ return;
188
+ held.length = 0;
189
+ heldBytes = 0;
190
+ done = true;
191
+ if (at === "none") {
192
+ controller.enqueue(bytes);
193
+ return;
194
+ }
195
+ controller.enqueue(bytes.subarray(0, at));
196
+ controller.enqueue(insert);
197
+ controller.enqueue(bytes.subarray(at));
198
+ };
199
+ return body.pipeThrough(new TransformStream({
200
+ transform(chunk, controller) {
201
+ if (done) {
202
+ controller.enqueue(chunk);
203
+ return;
204
+ }
205
+ held.push(chunk);
206
+ heldBytes += chunk.byteLength;
207
+ release(controller, false);
208
+ },
209
+ flush(controller) {
210
+ if (!done && heldBytes > 0)
211
+ release(controller, true);
212
+ },
213
+ }));
214
+ }
215
+ // ---------------------------------------------------------------------------------------------------
216
+ // What the script sends
217
+ // ---------------------------------------------------------------------------------------------------
218
+ /** One batch is bounded by what `fetch(keepalive)` may carry. */
219
+ export const CLIENT_BATCH_MAX_BYTES = 64 * 1024;
220
+ export const CLIENT_BATCH_MAX_EVENTS = 50;
221
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
222
+ const text = (value, max) => typeof value === "string" ? value.slice(0, max) : undefined;
223
+ // The script only ever tags an event with the id the server put in it; anything else is dropped.
224
+ const REQUEST_ID = /^r\d{1,12}$/;
225
+ function parseBrowserError(value) {
226
+ if (!isRecord(value))
227
+ return undefined;
228
+ const message = text(value.message, 8 * 1024);
229
+ if (message === undefined)
230
+ return undefined;
231
+ return {
232
+ name: text(value.name, 200) || "Error",
233
+ message,
234
+ stack: text(value.stack, 16 * 1024) ?? "",
235
+ };
236
+ }
237
+ function parseEvent(value) {
238
+ if (!isRecord(value))
239
+ return undefined;
240
+ const page = text(value.page, 2048);
241
+ if (page === undefined || !page.startsWith("/"))
242
+ return undefined;
243
+ const requestId = typeof value.requestId === "string" && REQUEST_ID.test(value.requestId)
244
+ ? value.requestId
245
+ : undefined;
246
+ if (value.kind === "error" || value.kind === "rejection") {
247
+ const error = parseBrowserError(value);
248
+ return error === undefined ? undefined : { kind: value.kind, ...error, page, requestId };
249
+ }
250
+ if (value.kind === "resource") {
251
+ const tag = text(value.tag, 20);
252
+ const url = text(value.url, 2048);
253
+ if (tag === undefined || url === undefined)
254
+ return undefined;
255
+ return { kind: "resource", tag, url, page, requestId };
256
+ }
257
+ if (value.kind === "console") {
258
+ const message = text(value.message, 8 * 1024);
259
+ if (message === undefined || !isDevLogLevel(value.level))
260
+ return undefined;
261
+ const error = parseBrowserError(value.error);
262
+ return { kind: "console", level: value.level, message, error, page, requestId };
263
+ }
264
+ return undefined;
265
+ }
266
+ /** A batch the script could have sent, or undefined. Malformed events are dropped, not fatal. */
267
+ export function parseClientBatch(value) {
268
+ if (!isRecord(value) || typeof value.token !== "string" || !Array.isArray(value.events))
269
+ return undefined;
270
+ if (value.events.length > CLIENT_BATCH_MAX_EVENTS)
271
+ return undefined;
272
+ const events = [];
273
+ for (const raw of value.events) {
274
+ const event = parseEvent(raw);
275
+ if (event !== undefined)
276
+ events.push(event);
277
+ }
278
+ return { token: value.token, events };
279
+ }
280
+ //# sourceMappingURL=dev-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-client.js","sourceRoot":"","sources":["../src/dev-client.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,20 @@
1
+ import { type Diagnostic } from "./diagnostic.js";
2
+ /**
3
+ * Whether a codeframe may show `file` (the canonical path it would read) to a browser: source in a
4
+ * browser zone. A page reports its own stack frames, so it can name any path: data files and the dev
5
+ * server's own `.nifra/` files (the discovery record holds the agent token) never qualify.
6
+ */
7
+ export declare function createSourceGate(root: string): (file: string) => boolean;
8
+ /** A failure as the dev feed recorded it: the entry and request let its agent prompt name a check. */
9
+ export interface CapturedFailure {
10
+ readonly diagnostic: Diagnostic;
11
+ readonly entry?: {
12
+ readonly id: string;
13
+ readonly seq: number;
14
+ } | undefined;
15
+ readonly requestId?: string | undefined;
16
+ readonly category?: string | undefined;
17
+ }
1
18
  export interface DevDiagnostics {
2
19
  /** True when a request path targets the structured last-error endpoint. */
3
20
  isLastErrorPath(pathname: string): boolean;
@@ -13,8 +30,15 @@ export interface DevDiagnostics {
13
30
  readonly method: string;
14
31
  readonly url: string;
15
32
  }): string;
33
+ /** The overlay HTML for a failure the feed already recorded, which also becomes the last error. */
34
+ show(captured: CapturedFailure): string;
16
35
  }
17
36
  /** One diagnostics surface per dev server. `root` is the resolved project root; it scopes the codeframe
18
- * to the project (see buildDiagnostic). Both dev servers resolve a concrete root before calling this. */
19
- export declare function createDevDiagnostics(root: string): DevDiagnostics;
37
+ * to the project (see buildDiagnostic). Both dev servers resolve a concrete root before calling this.
38
+ * `build` replaces the default Diagnostic builder: the dev session passes one that also records the
39
+ * failure in its feed (redacted), so the overlay, this endpoint and the feed show the same object. */
40
+ export declare function createDevDiagnostics(root: string, build?: (err: unknown, request: {
41
+ readonly method: string;
42
+ readonly url: string;
43
+ }) => CapturedFailure): DevDiagnostics;
20
44
  //# sourceMappingURL=dev-diagnostics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev-diagnostics.d.ts","sourceRoot":"","sources":["../src/dev-diagnostics.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IAC1C;wGACoG;IACpG,SAAS,IAAI;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;KAAE,CAAA;IAC1F;4GACwG;IACxG,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAA;CAC1F;AAED;yGACyG;AACzG,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAoBjE"}
1
+ {"version":3,"file":"dev-diagnostics.d.ts","sourceRoot":"","sources":["../src/dev-diagnostics.ts"],"names":[],"mappings":"AAYA,OAAO,EAAmB,KAAK,UAAU,EAA+B,MAAM,iBAAiB,CAAA;AAK/F;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAOxE;AAED,sGAAsG;AACtG,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAA;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAA;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IAC1C;wGACoG;IACpG,SAAS,IAAI;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;KAAE,CAAA;IAC1F;4GACwG;IACxG,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAA;IACzF,mGAAmG;IACnG,IAAI,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAAA;CACxC;AAED;;;sGAGsG;AACtG,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,CACN,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KACvD,eAAe,GACnB,cAAc,CAqChB"}
@@ -8,12 +8,43 @@
8
8
  *
9
9
  * Vite once shipped without the `/__nifra/last-error` endpoint at all - the drift this module prevents.
10
10
  */
11
+ import { relative } from "node:path";
11
12
  import { renderDiagnosticOverlay } from "./dev-error.js";
12
- import { buildDiagnostic, LAST_ERROR_PATH } from "./diagnostic.js";
13
+ import { buildDiagnostic, fixPrompts, LAST_ERROR_PATH } from "./diagnostic.js";
14
+ import { browserDenial, createZoneClassifier } from "./zones.js";
15
+ const CODEFRAME_SOURCE = /\.(?:[cm]?[jt]sx?|vue|svelte|astro|mdx)$/i;
16
+ /**
17
+ * Whether a codeframe may show `file` (the canonical path it would read) to a browser: source in a
18
+ * browser zone. A page reports its own stack frames, so it can name any path: data files and the dev
19
+ * server's own `.nifra/` files (the discovery record holds the agent token) never qualify.
20
+ */
21
+ export function createSourceGate(root) {
22
+ const zones = createZoneClassifier({ appRoot: root });
23
+ return (file) => {
24
+ if (!CODEFRAME_SOURCE.test(file))
25
+ return false;
26
+ if ((relative(zones.appRoot, file).split(/[\\/]/)[0] ?? "").startsWith(".nifra"))
27
+ return false;
28
+ return browserDenial(zones.classify(file)) === undefined;
29
+ };
30
+ }
13
31
  /** One diagnostics surface per dev server. `root` is the resolved project root; it scopes the codeframe
14
- * to the project (see buildDiagnostic). Both dev servers resolve a concrete root before calling this. */
15
- export function createDevDiagnostics(root) {
32
+ * to the project (see buildDiagnostic). Both dev servers resolve a concrete root before calling this.
33
+ * `build` replaces the default Diagnostic builder: the dev session passes one that also records the
34
+ * failure in its feed (redacted), so the overlay, this endpoint and the feed show the same object. */
35
+ export function createDevDiagnostics(root, build) {
16
36
  let last;
37
+ const showSource = createSourceGate(root);
38
+ const show = (captured) => {
39
+ last = captured.diagnostic;
40
+ return renderDiagnosticOverlay(last, fixPrompts(last, {
41
+ surface: "overlay",
42
+ root,
43
+ entry: captured.entry,
44
+ requestId: captured.requestId,
45
+ category: captured.category ?? "ssr",
46
+ }));
47
+ };
17
48
  return {
18
49
  isLastErrorPath: (pathname) => pathname === LAST_ERROR_PATH,
19
50
  lastError: () => ({
@@ -25,10 +56,10 @@ export function createDevDiagnostics(root) {
25
56
  "x-nifra-diagnostic": "true",
26
57
  },
27
58
  }),
28
- capture: (err, request) => {
29
- last = buildDiagnostic(err, { root, request });
30
- return renderDiagnosticOverlay(last);
31
- },
59
+ capture: (err, request) => show(build?.(err, request) ?? {
60
+ diagnostic: buildDiagnostic(err, { root, request, showSource }),
61
+ }),
62
+ show,
32
63
  };
33
64
  }
34
65
  //# sourceMappingURL=dev-diagnostics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev-diagnostics.js","sourceRoot":"","sources":["../src/dev-diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AACxD,OAAO,EAAE,eAAe,EAAmB,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAanF;yGACyG;AACzG,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,IAA4B,CAAA;IAChC,OAAO;QACL,eAAe,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,eAAe;QAC3D,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;YAChB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB,IAAI,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAC3F;YACD,OAAO,EAAE;gBACP,cAAc,EAAE,iCAAiC;gBACjD,eAAe,EAAE,UAAU;gBAC3B,wBAAwB,EAAE,SAAS;gBACnC,oBAAoB,EAAE,MAAM;aAC7B;SACF,CAAC;QACF,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE;YACxB,IAAI,GAAG,eAAe,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;YAC9C,OAAO,uBAAuB,CAAC,IAAI,CAAC,CAAA;QACtC,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"dev-diagnostics.js","sourceRoot":"","sources":["../src/dev-diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AACxD,OAAO,EAAE,eAAe,EAAmB,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC/F,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAEhE,MAAM,gBAAgB,GAAG,2CAA2C,CAAA;AAEpE;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,oBAAoB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;IACrD,OAAO,CAAC,IAAI,EAAE,EAAE;QACd,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAA;QAC9C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAA;QAC9F,OAAO,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,SAAS,CAAA;IAC1D,CAAC,CAAA;AACH,CAAC;AAuBD;;;sGAGsG;AACtG,MAAM,UAAU,oBAAoB,CAClC,IAAY,EACZ,KAGoB;IAEpB,IAAI,IAA4B,CAAA;IAChC,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACzC,MAAM,IAAI,GAAG,CAAC,QAAyB,EAAU,EAAE;QACjD,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAA;QAC1B,OAAO,uBAAuB,CAC5B,IAAI,EACJ,UAAU,CAAC,IAAI,EAAE;YACf,OAAO,EAAE,SAAS;YAClB,IAAI;YACJ,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,KAAK;SACrC,CAAC,CACH,CAAA;IACH,CAAC,CAAA;IACD,OAAO;QACL,eAAe,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,eAAe;QAC3D,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;YAChB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB,IAAI,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAC3F;YACD,OAAO,EAAE;gBACP,cAAc,EAAE,iCAAiC;gBACjD,eAAe,EAAE,UAAU;gBAC3B,wBAAwB,EAAE,SAAS;gBACnC,oBAAoB,EAAE,MAAM;aAC7B;SACF,CAAC;QACF,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CACxB,IAAI,CACF,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI;YACvB,UAAU,EAAE,eAAe,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;SAChE,CACF;QACH,IAAI;KACL,CAAA;AACH,CAAC"}
@@ -1,14 +1,5 @@
1
- /**
2
- * Dev-only error overlay. When a loader/action/render throws during `@nifrajs/web/vite` dev, this
3
- * renders a readable full-page overlay from a structured [Diagnostic] - the code, the message, a source
4
- * codeframe around the offending line, the recognised cause/fix when nifra has one, and the stack -
5
- * instead of a bare `err.stack` text dump. Dev-only by construction: it's called solely from the dev
6
- * server's catch, never in production (production maps errors to the `_error` route boundary).
7
- *
8
- * The overlay and the agent surfaces (`/__nifra/last-error`, `nifra_explain`) render from the SAME
9
- * `Diagnostic`, so a person and an agent see the identical failure, one as HTML and one as JSON.
10
- */
11
- import type { Diagnostic } from "./diagnostic.js";
12
- /** Render the overlay HTML from a prebuilt Diagnostic (the same object the agent surfaces serve). */
13
- export declare function renderDiagnosticOverlay(diagnostic: Diagnostic): string;
1
+ import type { Diagnostic, FixPrompt } from "./diagnostic.js";
2
+ /** Render the overlay HTML from a prebuilt Diagnostic (the same object the agent surfaces serve), with
3
+ * the paste-ready agent prompts for it when the caller built them. */
4
+ export declare function renderDiagnosticOverlay(diagnostic: Diagnostic, prompts?: readonly FixPrompt[]): string;
14
5
  //# sourceMappingURL=dev-error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev-error.d.ts","sourceRoot":"","sources":["../src/dev-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AA+BjD,qGAAqG;AACrG,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAkDtE"}
1
+ {"version":3,"file":"dev-error.d.ts","sourceRoot":"","sources":["../src/dev-error.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AA4D5D;sEACsE;AACtE,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,GAC7B,MAAM,CA4DR"}
package/dist/dev-error.js CHANGED
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Dev-only error overlay. When a loader/action/render throws during `@nifrajs/web/vite` dev, this
3
+ * renders a readable full-page overlay from a structured [Diagnostic] - the code, the message, a source
4
+ * codeframe around the offending line, the recognised cause/fix when nifra has one, and the stack -
5
+ * instead of a bare `err.stack` text dump. Dev-only by construction: it's called solely from the dev
6
+ * server's catch, never in production (production maps errors to the `_error` route boundary).
7
+ *
8
+ * The overlay and the agent surfaces (`/__nifra/last-error`, `nifra_explain`) render from the SAME
9
+ * `Diagnostic`, so a person and an agent see the identical failure, one as HTML and one as JSON.
10
+ */
11
+ import { createHash } from "node:crypto";
1
12
  const esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
2
13
  /** The source codeframe block: numbered lines with the offending one highlighted. */
3
14
  function codeframeHtml(diagnostic) {
@@ -15,13 +26,34 @@ function fixHtml(diagnostic) {
15
26
  if (diagnostic.fix === undefined)
16
27
  return "";
17
28
  const anchor = diagnostic.docsAnchor !== undefined
18
- ? `<div class="fix-docs">docs: <code>${esc(diagnostic.docsAnchor)}</code></div>`
29
+ ? `<div class="fix-docs">docs: <a href="https://nifra.dev/docs/${esc(diagnostic.docsAnchor)}" target="_blank" rel="noreferrer"><code>${esc(diagnostic.docsAnchor)}</code></a></div>`
19
30
  : "";
20
31
  const cause = diagnostic.cause !== undefined ? `<p class="fix-cause">${esc(diagnostic.cause)}</p>` : "";
21
32
  return `<div class="fix"><div class="fix-tag">likely fix</div>${cause}<p class="fix-do">${esc(diagnostic.fix)}</p>${anchor}</div>`;
22
33
  }
23
- /** Render the overlay HTML from a prebuilt Diagnostic (the same object the agent surfaces serve). */
24
- export function renderDiagnosticOverlay(diagnostic) {
34
+ // Copies a prompt; falls back to selecting it in its textarea where the Clipboard API is unavailable
35
+ // (a dev server reached over plain http from another machine is not a secure context).
36
+ const COPY_SCRIPT = `(function(){var s=document.getElementById("nifra-copied");document.querySelectorAll("button[data-prompt]").forEach(function(b){b.addEventListener("click",function(){var t=document.getElementById("nifra-prompt-"+b.getAttribute("data-prompt"));if(!t)return;var d=t.closest("details");function done(ok){s.textContent=ok?"Copied. Paste it into your coding agent.":"Select the text below and copy it."}function manual(){var was=d.open;d.open=true;t.focus();t.select();var ok=false;try{ok=document.execCommand("copy")}catch(e){}if(ok)d.open=was;done(ok)}if(window.isSecureContext&&navigator.clipboard)navigator.clipboard.writeText(t.value).then(function(){done(true)},manual);else manual()})})})()`;
37
+ const COPY_SCRIPT_HASH = `'sha256-${createHash("sha256").update(COPY_SCRIPT).digest("base64")}'`;
38
+ // The overlay renders text a request can influence (its URL, a thrown message), so it allows only its
39
+ // own copy script.
40
+ const OVERLAY_CSP = `default-src 'none'; script-src ${COPY_SCRIPT_HASH}; style-src 'unsafe-inline'; base-uri 'none'; form-action 'none'`;
41
+ /** The copy-a-prompt block: one button per fix, the prompts themselves readable without JS. */
42
+ function promptsHtml(prompts) {
43
+ if (prompts === undefined || prompts.length === 0)
44
+ return "";
45
+ const single = prompts.length === 1;
46
+ const buttons = prompts
47
+ .map((p, i) => `<button type="button" data-prompt="${i}">${single ? "Copy prompt" : `Copy prompt: ${esc(p.label)}`}</button>`)
48
+ .join("");
49
+ const areas = prompts
50
+ .map((p, i) => `<label for="nifra-prompt-${i}">${esc(p.label)}</label><textarea id="nifra-prompt-${i}" readonly rows="12">${esc(p.prompt)}</textarea>`)
51
+ .join("");
52
+ return `<section class="prompts"><h1>Prompt for your coding agent</h1><p class="prompts-note">The error, the code and ${single ? "the fix" : "one fix"}, ready to paste. Paths are relative to the project and known secrets are redacted.</p><div class="prompt-buttons">${buttons}<span id="nifra-copied" aria-live="polite"></span></div><details><summary>Show the prompt${single ? "" : "s"}</summary>${areas}</details></section><script>${COPY_SCRIPT}</script>`;
53
+ }
54
+ /** Render the overlay HTML from a prebuilt Diagnostic (the same object the agent surfaces serve), with
55
+ * the paste-ready agent prompts for it when the caller built them. */
56
+ export function renderDiagnosticOverlay(diagnostic, prompts) {
25
57
  const name = esc(diagnostic.name || "Error");
26
58
  const code = esc(diagnostic.code);
27
59
  const reqLine = diagnostic.request !== undefined
@@ -30,7 +62,7 @@ export function renderDiagnosticOverlay(diagnostic) {
30
62
  const framesHtml = diagnostic.frames.length > 0
31
63
  ? `<ol class="frames">${diagnostic.frames.map((f) => `<li>${esc(f.raw)}</li>`).join("")}</ol>`
32
64
  : `<p class="no-frames">No stack frames.</p>`;
33
- return `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>${name} - nifra dev</title>
65
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="Content-Security-Policy" content="${OVERLAY_CSP}"><title>${name} - nifra dev</title>
34
66
  <style>
35
67
  :root { color-scheme: dark }
36
68
  body { margin: 0; background: #0b0d10; color: #e6e6e6; font: 14px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace; }
@@ -59,11 +91,21 @@ export function renderDiagnosticOverlay(diagnostic) {
59
91
  .frames li:first-child { color: #d6e2ee; }
60
92
  .no-frames { color: #778; }
61
93
  footer { margin-top: 28px; color: #667; font-size: 12px; }
94
+ .prompts-note { margin: 0 0 10px; color: #9aa; }
95
+ .prompt-buttons { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
96
+ .prompt-buttons button { font: inherit; font-size: 13px; color: #d6f2e4; background: #10241a; border: 1px solid #1f4d38; border-radius: 6px; padding: 6px 12px; cursor: pointer; }
97
+ .prompt-buttons button:hover, .prompt-buttons button:focus-visible { border-color: #7fe0af; outline: none; }
98
+ #nifra-copied { color: #7fe0af; font-size: 12px; }
99
+ details { margin-top: 10px; }
100
+ summary { cursor: pointer; color: #9aa; }
101
+ details label { display: block; margin: 12px 0 4px; color: #c98; font-size: 12px; }
102
+ textarea { width: 100%; box-sizing: border-box; background: #0f1319; color: #cdd6e0; border: 1px solid #222; border-radius: 8px; font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; padding: 8px; }
62
103
  </style></head><body>
63
104
  <div class="bar"><span class="tag">nifra dev</span><span class="code">${code}</span><span>${name}</span>${reqLine}</div>
64
105
  <main>
65
106
  <p class="message">${esc(diagnostic.message)}</p>
66
107
  ${fixHtml(diagnostic)}
108
+ ${promptsHtml(prompts)}
67
109
  ${codeframeHtml(diagnostic)}
68
110
  <h1>Stack</h1>
69
111
  ${framesHtml}
@@ -1 +1 @@
1
- {"version":3,"file":"dev-error.js","sourceRoot":"","sources":["../src/dev-error.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dev-error.js","sourceRoot":"","sources":["../src/dev-error.ts"],"names":[],"mappings":"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"}