gazetta 0.6.0 → 0.8.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 (983) hide show
  1. package/admin-dist/assets/index-CBeq0rRb.js +693 -0
  2. package/admin-dist/assets/index-Dtg1dTZQ.css +1 -0
  3. package/admin-dist/assets/rolldown-runtime-BYbx6iT9.js +1 -0
  4. package/admin-dist/assets/{vendor-primevue-C0Q_YTCb.js → vendor-primevue-CBGHkaXv.js} +183 -39
  5. package/admin-dist/assets/{vendor-react-BipDVGow.js → vendor-react-BdW_kNCG.js} +2 -2
  6. package/admin-dist/assets/vendor-rjsf-lN2SztQt.js +33 -0
  7. package/admin-dist/assets/vendor-tiptap-C36yDquB.js +141 -0
  8. package/admin-dist/assets/vendor-vue-Bt5uR1VW.js +1 -0
  9. package/admin-dist/assets/workbox-window.prod.es5-DGMtIXHc.js +2 -0
  10. package/admin-dist/index.html +8 -8
  11. package/admin-dist/sw.js +1 -0
  12. package/dist/admin-api/archived-name-conflict.d.ts +31 -0
  13. package/dist/admin-api/archived-name-conflict.d.ts.map +1 -0
  14. package/dist/admin-api/archived-name-conflict.js +226 -0
  15. package/dist/admin-api/archived-name-conflict.js.map +1 -0
  16. package/dist/admin-api/cache-stats-logger.d.ts +83 -0
  17. package/dist/admin-api/cache-stats-logger.d.ts.map +1 -0
  18. package/dist/admin-api/cache-stats-logger.js +59 -0
  19. package/dist/admin-api/cache-stats-logger.js.map +1 -0
  20. package/dist/admin-api/error-response.d.ts +21 -0
  21. package/dist/admin-api/error-response.d.ts.map +1 -0
  22. package/dist/admin-api/error-response.js +12 -0
  23. package/dist/admin-api/error-response.js.map +1 -0
  24. package/dist/admin-api/hook-audit-emitter.d.ts +38 -0
  25. package/dist/admin-api/hook-audit-emitter.d.ts.map +1 -0
  26. package/dist/admin-api/hook-audit-emitter.js +21 -0
  27. package/dist/admin-api/hook-audit-emitter.js.map +1 -0
  28. package/dist/admin-api/index.d.ts +84 -2
  29. package/dist/admin-api/index.d.ts.map +1 -1
  30. package/dist/admin-api/index.js +257 -32
  31. package/dist/admin-api/index.js.map +1 -1
  32. package/dist/admin-api/middleware/audit.d.ts +25 -0
  33. package/dist/admin-api/middleware/audit.d.ts.map +1 -0
  34. package/dist/admin-api/middleware/audit.js +65 -0
  35. package/dist/admin-api/middleware/audit.js.map +1 -0
  36. package/dist/admin-api/middleware/capability.d.ts +8 -0
  37. package/dist/admin-api/middleware/capability.d.ts.map +1 -0
  38. package/dist/admin-api/middleware/capability.js +65 -0
  39. package/dist/admin-api/middleware/capability.js.map +1 -0
  40. package/dist/admin-api/middleware/principal.d.ts +18 -0
  41. package/dist/admin-api/middleware/principal.d.ts.map +1 -0
  42. package/dist/admin-api/middleware/principal.js +128 -0
  43. package/dist/admin-api/middleware/principal.js.map +1 -0
  44. package/dist/admin-api/routes/archive-review.d.ts +80 -0
  45. package/dist/admin-api/routes/archive-review.d.ts.map +1 -0
  46. package/dist/admin-api/routes/archive-review.js +70 -0
  47. package/dist/admin-api/routes/archive-review.js.map +1 -0
  48. package/dist/admin-api/routes/archive.d.ts +145 -0
  49. package/dist/admin-api/routes/archive.d.ts.map +1 -0
  50. package/dist/admin-api/routes/archive.js +540 -0
  51. package/dist/admin-api/routes/archive.js.map +1 -0
  52. package/dist/admin-api/routes/assets.d.ts +21 -0
  53. package/dist/admin-api/routes/assets.d.ts.map +1 -0
  54. package/dist/admin-api/routes/assets.js +586 -0
  55. package/dist/admin-api/routes/assets.js.map +1 -0
  56. package/dist/admin-api/routes/audit.d.ts +71 -0
  57. package/dist/admin-api/routes/audit.d.ts.map +1 -0
  58. package/dist/admin-api/routes/audit.js +178 -0
  59. package/dist/admin-api/routes/audit.js.map +1 -0
  60. package/dist/admin-api/routes/compare.d.ts.map +1 -1
  61. package/dist/admin-api/routes/compare.js +3 -2
  62. package/dist/admin-api/routes/compare.js.map +1 -1
  63. package/dist/admin-api/routes/fields.d.ts.map +1 -1
  64. package/dist/admin-api/routes/fields.js +2 -1
  65. package/dist/admin-api/routes/fields.js.map +1 -1
  66. package/dist/admin-api/routes/fragments.d.ts +13 -1
  67. package/dist/admin-api/routes/fragments.d.ts.map +1 -1
  68. package/dist/admin-api/routes/fragments.js +128 -67
  69. package/dist/admin-api/routes/fragments.js.map +1 -1
  70. package/dist/admin-api/routes/health.d.ts +60 -0
  71. package/dist/admin-api/routes/health.d.ts.map +1 -0
  72. package/dist/admin-api/routes/health.js +65 -0
  73. package/dist/admin-api/routes/health.js.map +1 -0
  74. package/dist/admin-api/routes/history.d.ts +2 -1
  75. package/dist/admin-api/routes/history.d.ts.map +1 -1
  76. package/dist/admin-api/routes/history.js +26 -4
  77. package/dist/admin-api/routes/history.js.map +1 -1
  78. package/dist/admin-api/routes/pages.d.ts +20 -1
  79. package/dist/admin-api/routes/pages.d.ts.map +1 -1
  80. package/dist/admin-api/routes/pages.js +158 -85
  81. package/dist/admin-api/routes/pages.js.map +1 -1
  82. package/dist/admin-api/routes/preview.d.ts.map +1 -1
  83. package/dist/admin-api/routes/preview.js +56 -17
  84. package/dist/admin-api/routes/preview.js.map +1 -1
  85. package/dist/admin-api/routes/publish.d.ts +19 -1
  86. package/dist/admin-api/routes/publish.d.ts.map +1 -1
  87. package/dist/admin-api/routes/publish.js +548 -99
  88. package/dist/admin-api/routes/publish.js.map +1 -1
  89. package/dist/admin-api/routes/rename.d.ts +62 -0
  90. package/dist/admin-api/routes/rename.d.ts.map +1 -0
  91. package/dist/admin-api/routes/rename.js +366 -0
  92. package/dist/admin-api/routes/rename.js.map +1 -0
  93. package/dist/admin-api/routes/site.d.ts.map +1 -1
  94. package/dist/admin-api/routes/site.js +6 -18
  95. package/dist/admin-api/routes/site.js.map +1 -1
  96. package/dist/admin-api/routes/system.d.ts +23 -0
  97. package/dist/admin-api/routes/system.d.ts.map +1 -0
  98. package/dist/admin-api/routes/system.js +115 -0
  99. package/dist/admin-api/routes/system.js.map +1 -0
  100. package/dist/admin-api/routes/templates.d.ts +11 -1
  101. package/dist/admin-api/routes/templates.d.ts.map +1 -1
  102. package/dist/admin-api/routes/templates.js +36 -3
  103. package/dist/admin-api/routes/templates.js.map +1 -1
  104. package/dist/admin-api/routes/validation.d.ts +47 -0
  105. package/dist/admin-api/routes/validation.d.ts.map +1 -0
  106. package/dist/admin-api/routes/validation.js +120 -0
  107. package/dist/admin-api/routes/validation.js.map +1 -0
  108. package/dist/admin-api/schemas/archive.d.ts +124 -0
  109. package/dist/admin-api/schemas/archive.d.ts.map +1 -0
  110. package/dist/admin-api/schemas/archive.js +93 -0
  111. package/dist/admin-api/schemas/archive.js.map +1 -0
  112. package/dist/admin-api/schemas/assets.d.ts +64 -0
  113. package/dist/admin-api/schemas/assets.d.ts.map +1 -0
  114. package/dist/admin-api/schemas/assets.js +59 -0
  115. package/dist/admin-api/schemas/assets.js.map +1 -0
  116. package/dist/admin-api/schemas/audit.d.ts +175 -0
  117. package/dist/admin-api/schemas/audit.d.ts.map +1 -0
  118. package/dist/admin-api/schemas/audit.js +91 -0
  119. package/dist/admin-api/schemas/audit.js.map +1 -0
  120. package/dist/admin-api/schemas/error.d.ts +94 -0
  121. package/dist/admin-api/schemas/error.d.ts.map +1 -0
  122. package/dist/admin-api/schemas/error.js +79 -0
  123. package/dist/admin-api/schemas/error.js.map +1 -0
  124. package/dist/admin-api/schemas/fragments.d.ts +2 -0
  125. package/dist/admin-api/schemas/fragments.d.ts.map +1 -1
  126. package/dist/admin-api/schemas/fragments.js +4 -0
  127. package/dist/admin-api/schemas/fragments.js.map +1 -1
  128. package/dist/admin-api/schemas/index.d.ts +10 -0
  129. package/dist/admin-api/schemas/index.d.ts.map +1 -1
  130. package/dist/admin-api/schemas/index.js +10 -0
  131. package/dist/admin-api/schemas/index.js.map +1 -1
  132. package/dist/admin-api/schemas/pages.d.ts +2 -0
  133. package/dist/admin-api/schemas/pages.d.ts.map +1 -1
  134. package/dist/admin-api/schemas/pages.js +11 -0
  135. package/dist/admin-api/schemas/pages.js.map +1 -1
  136. package/dist/admin-api/schemas/rename.d.ts +77 -0
  137. package/dist/admin-api/schemas/rename.d.ts.map +1 -0
  138. package/dist/admin-api/schemas/rename.js +75 -0
  139. package/dist/admin-api/schemas/rename.js.map +1 -0
  140. package/dist/admin-api/schemas/site.d.ts +3 -2
  141. package/dist/admin-api/schemas/site.d.ts.map +1 -1
  142. package/dist/admin-api/schemas/site.js +3 -2
  143. package/dist/admin-api/schemas/site.js.map +1 -1
  144. package/dist/admin-api/schemas/system.d.ts +28 -0
  145. package/dist/admin-api/schemas/system.d.ts.map +1 -0
  146. package/dist/admin-api/schemas/system.js +35 -0
  147. package/dist/admin-api/schemas/system.js.map +1 -0
  148. package/dist/admin-api/schemas/targets.d.ts +55 -0
  149. package/dist/admin-api/schemas/targets.d.ts.map +1 -1
  150. package/dist/admin-api/schemas/targets.js +46 -0
  151. package/dist/admin-api/schemas/targets.js.map +1 -1
  152. package/dist/admin-api/schemas/templates.d.ts +54 -0
  153. package/dist/admin-api/schemas/templates.d.ts.map +1 -1
  154. package/dist/admin-api/schemas/templates.js +21 -0
  155. package/dist/admin-api/schemas/templates.js.map +1 -1
  156. package/dist/admin-api/schemas/validation.d.ts +101 -0
  157. package/dist/admin-api/schemas/validation.d.ts.map +1 -0
  158. package/dist/admin-api/schemas/validation.js +57 -0
  159. package/dist/admin-api/schemas/validation.js.map +1 -0
  160. package/dist/admin-api/source-context.d.ts +66 -17
  161. package/dist/admin-api/source-context.d.ts.map +1 -1
  162. package/dist/admin-api/source-context.js +43 -8
  163. package/dist/admin-api/source-context.js.map +1 -1
  164. package/dist/ai/adapter-scaffold.d.ts +63 -0
  165. package/dist/ai/adapter-scaffold.d.ts.map +1 -0
  166. package/dist/ai/adapter-scaffold.js +89 -0
  167. package/dist/ai/adapter-scaffold.js.map +1 -0
  168. package/dist/ai/compose-prompt.d.ts +50 -0
  169. package/dist/ai/compose-prompt.d.ts.map +1 -0
  170. package/dist/ai/compose-prompt.js +49 -0
  171. package/dist/ai/compose-prompt.js.map +1 -0
  172. package/dist/ai/errors.d.ts +65 -0
  173. package/dist/ai/errors.d.ts.map +1 -0
  174. package/dist/ai/errors.js +59 -0
  175. package/dist/ai/errors.js.map +1 -0
  176. package/dist/ai/index.d.ts +17 -0
  177. package/dist/ai/index.d.ts.map +1 -0
  178. package/dist/ai/index.js +16 -0
  179. package/dist/ai/index.js.map +1 -0
  180. package/dist/ai/provider.d.ts +76 -0
  181. package/dist/ai/provider.d.ts.map +1 -0
  182. package/dist/ai/provider.js +13 -0
  183. package/dist/ai/provider.js.map +1 -0
  184. package/dist/ai/refusal.d.ts +50 -0
  185. package/dist/ai/refusal.d.ts.map +1 -0
  186. package/dist/ai/refusal.js +100 -0
  187. package/dist/ai/refusal.js.map +1 -0
  188. package/dist/ai/vision-prep.d.ts +32 -0
  189. package/dist/ai/vision-prep.d.ts.map +1 -0
  190. package/dist/ai/vision-prep.js +113 -0
  191. package/dist/ai/vision-prep.js.map +1 -0
  192. package/dist/alt/adapter.d.ts +140 -0
  193. package/dist/alt/adapter.d.ts.map +1 -0
  194. package/dist/alt/adapter.js +7 -0
  195. package/dist/alt/adapter.js.map +1 -0
  196. package/dist/alt/anthropic.d.ts +63 -0
  197. package/dist/alt/anthropic.d.ts.map +1 -0
  198. package/dist/alt/anthropic.js +147 -0
  199. package/dist/alt/anthropic.js.map +1 -0
  200. package/dist/alt/config.d.ts +67 -0
  201. package/dist/alt/config.d.ts.map +1 -0
  202. package/dist/alt/config.js +41 -0
  203. package/dist/alt/config.js.map +1 -0
  204. package/dist/alt/factory.d.ts +19 -0
  205. package/dist/alt/factory.d.ts.map +1 -0
  206. package/dist/alt/factory.js +69 -0
  207. package/dist/alt/factory.js.map +1 -0
  208. package/dist/alt/null-adapter.d.ts +3 -0
  209. package/dist/alt/null-adapter.d.ts.map +1 -0
  210. package/dist/alt/null-adapter.js +43 -0
  211. package/dist/alt/null-adapter.js.map +1 -0
  212. package/dist/alt/ollama.d.ts +40 -0
  213. package/dist/alt/ollama.d.ts.map +1 -0
  214. package/dist/alt/ollama.js +139 -0
  215. package/dist/alt/ollama.js.map +1 -0
  216. package/dist/alt/openai.d.ts +46 -0
  217. package/dist/alt/openai.d.ts.map +1 -0
  218. package/dist/alt/openai.js +118 -0
  219. package/dist/alt/openai.js.map +1 -0
  220. package/dist/alt/prompt-policies.d.ts +79 -0
  221. package/dist/alt/prompt-policies.d.ts.map +1 -0
  222. package/dist/alt/prompt-policies.js +67 -0
  223. package/dist/alt/prompt-policies.js.map +1 -0
  224. package/dist/alt/route-handler.d.ts +56 -0
  225. package/dist/alt/route-handler.d.ts.map +1 -0
  226. package/dist/alt/route-handler.js +122 -0
  227. package/dist/alt/route-handler.js.map +1 -0
  228. package/dist/alt/suggester.d.ts +57 -0
  229. package/dist/alt/suggester.d.ts.map +1 -0
  230. package/dist/alt/suggester.js +133 -0
  231. package/dist/alt/suggester.js.map +1 -0
  232. package/dist/app.js +1 -1
  233. package/dist/app.js.map +1 -1
  234. package/dist/archive-aliases.d.ts +79 -0
  235. package/dist/archive-aliases.d.ts.map +1 -0
  236. package/dist/archive-aliases.js +60 -0
  237. package/dist/archive-aliases.js.map +1 -0
  238. package/dist/archive-helpers.d.ts +73 -0
  239. package/dist/archive-helpers.d.ts.map +1 -0
  240. package/dist/archive-helpers.js +94 -0
  241. package/dist/archive-helpers.js.map +1 -0
  242. package/dist/assets/analyze-audio.d.ts +3 -0
  243. package/dist/assets/analyze-audio.d.ts.map +1 -0
  244. package/dist/assets/analyze-audio.js +80 -0
  245. package/dist/assets/analyze-audio.js.map +1 -0
  246. package/dist/assets/analyze-image.d.ts +19 -0
  247. package/dist/assets/analyze-image.d.ts.map +1 -0
  248. package/dist/assets/analyze-image.js +123 -0
  249. package/dist/assets/analyze-image.js.map +1 -0
  250. package/dist/assets/analyze.d.ts +94 -0
  251. package/dist/assets/analyze.d.ts.map +1 -0
  252. package/dist/assets/analyze.js +45 -0
  253. package/dist/assets/analyze.js.map +1 -0
  254. package/dist/assets/asset-deps.d.ts +30 -0
  255. package/dist/assets/asset-deps.d.ts.map +1 -0
  256. package/dist/assets/asset-deps.js +42 -0
  257. package/dist/assets/asset-deps.js.map +1 -0
  258. package/dist/assets/asset-paths.d.ts +155 -0
  259. package/dist/assets/asset-paths.d.ts.map +1 -0
  260. package/dist/assets/asset-paths.js +197 -0
  261. package/dist/assets/asset-paths.js.map +1 -0
  262. package/dist/assets/delete.d.ts +75 -0
  263. package/dist/assets/delete.d.ts.map +1 -0
  264. package/dist/assets/delete.js +82 -0
  265. package/dist/assets/delete.js.map +1 -0
  266. package/dist/assets/errors.d.ts +241 -0
  267. package/dist/assets/errors.d.ts.map +1 -0
  268. package/dist/assets/errors.js +300 -0
  269. package/dist/assets/errors.js.map +1 -0
  270. package/dist/assets/find-refs.d.ts +37 -0
  271. package/dist/assets/find-refs.d.ts.map +1 -0
  272. package/dist/assets/find-refs.js +35 -0
  273. package/dist/assets/find-refs.js.map +1 -0
  274. package/dist/assets/hash.d.ts +13 -0
  275. package/dist/assets/hash.d.ts.map +1 -0
  276. package/dist/assets/hash.js +43 -0
  277. package/dist/assets/hash.js.map +1 -0
  278. package/dist/assets/image-metadata.d.ts +11 -0
  279. package/dist/assets/image-metadata.d.ts.map +1 -0
  280. package/dist/assets/image-metadata.js +31 -0
  281. package/dist/assets/image-metadata.js.map +1 -0
  282. package/dist/assets/ingest-locale.d.ts +86 -0
  283. package/dist/assets/ingest-locale.d.ts.map +1 -0
  284. package/dist/assets/ingest-locale.js +209 -0
  285. package/dist/assets/ingest-locale.js.map +1 -0
  286. package/dist/assets/ingest.d.ts +96 -0
  287. package/dist/assets/ingest.d.ts.map +1 -0
  288. package/dist/assets/ingest.js +308 -0
  289. package/dist/assets/ingest.js.map +1 -0
  290. package/dist/assets/kind-compat.d.ts +34 -0
  291. package/dist/assets/kind-compat.d.ts.map +1 -0
  292. package/dist/assets/kind-compat.js +33 -0
  293. package/dist/assets/kind-compat.js.map +1 -0
  294. package/dist/assets/list.d.ts +46 -0
  295. package/dist/assets/list.d.ts.map +1 -0
  296. package/dist/assets/list.js +102 -0
  297. package/dist/assets/list.js.map +1 -0
  298. package/dist/assets/manifest-default.d.ts +56 -0
  299. package/dist/assets/manifest-default.d.ts.map +1 -0
  300. package/dist/assets/manifest-default.js +120 -0
  301. package/dist/assets/manifest-default.js.map +1 -0
  302. package/dist/assets/manifest-filename.d.ts +52 -0
  303. package/dist/assets/manifest-filename.d.ts.map +1 -0
  304. package/dist/assets/manifest-filename.js +104 -0
  305. package/dist/assets/manifest-filename.js.map +1 -0
  306. package/dist/assets/manifest-locale.d.ts +60 -0
  307. package/dist/assets/manifest-locale.d.ts.map +1 -0
  308. package/dist/assets/manifest-locale.js +206 -0
  309. package/dist/assets/manifest-locale.js.map +1 -0
  310. package/dist/assets/manifest-merge.d.ts +66 -0
  311. package/dist/assets/manifest-merge.d.ts.map +1 -0
  312. package/dist/assets/manifest-merge.js +82 -0
  313. package/dist/assets/manifest-merge.js.map +1 -0
  314. package/dist/assets/manifest.d.ts +83 -0
  315. package/dist/assets/manifest.d.ts.map +1 -0
  316. package/dist/assets/manifest.js +93 -0
  317. package/dist/assets/manifest.js.map +1 -0
  318. package/dist/assets/mime-sniff.d.ts +18 -0
  319. package/dist/assets/mime-sniff.d.ts.map +1 -0
  320. package/dist/assets/mime-sniff.js +84 -0
  321. package/dist/assets/mime-sniff.js.map +1 -0
  322. package/dist/assets/preprocess-svg.d.ts +3 -0
  323. package/dist/assets/preprocess-svg.d.ts.map +1 -0
  324. package/dist/assets/preprocess-svg.js +49 -0
  325. package/dist/assets/preprocess-svg.js.map +1 -0
  326. package/dist/assets/preprocess.d.ts +62 -0
  327. package/dist/assets/preprocess.d.ts.map +1 -0
  328. package/dist/assets/preprocess.js +86 -0
  329. package/dist/assets/preprocess.js.map +1 -0
  330. package/dist/assets/publish-plan.d.ts +41 -0
  331. package/dist/assets/publish-plan.d.ts.map +1 -0
  332. package/dist/assets/publish-plan.js +49 -0
  333. package/dist/assets/publish-plan.js.map +1 -0
  334. package/dist/assets/publish.d.ts +33 -0
  335. package/dist/assets/publish.d.ts.map +1 -0
  336. package/dist/assets/publish.js +81 -0
  337. package/dist/assets/publish.js.map +1 -0
  338. package/dist/assets/refs.d.ts +37 -0
  339. package/dist/assets/refs.d.ts.map +1 -0
  340. package/dist/assets/refs.js +33 -0
  341. package/dist/assets/refs.js.map +1 -0
  342. package/dist/assets/remove-override.d.ts +42 -0
  343. package/dist/assets/remove-override.d.ts.map +1 -0
  344. package/dist/assets/remove-override.js +53 -0
  345. package/dist/assets/remove-override.js.map +1 -0
  346. package/dist/assets/rename.d.ts +43 -0
  347. package/dist/assets/rename.d.ts.map +1 -0
  348. package/dist/assets/rename.js +271 -0
  349. package/dist/assets/rename.js.map +1 -0
  350. package/dist/assets/replace.d.ts +37 -0
  351. package/dist/assets/replace.d.ts.map +1 -0
  352. package/dist/assets/replace.js +195 -0
  353. package/dist/assets/replace.js.map +1 -0
  354. package/dist/assets/resolve.d.ts +141 -0
  355. package/dist/assets/resolve.d.ts.map +1 -0
  356. package/dist/assets/resolve.js +381 -0
  357. package/dist/assets/resolve.js.map +1 -0
  358. package/dist/assets/rewrite-manifest-asset-ref.d.ts +44 -0
  359. package/dist/assets/rewrite-manifest-asset-ref.d.ts.map +1 -0
  360. package/dist/assets/rewrite-manifest-asset-ref.js +51 -0
  361. package/dist/assets/rewrite-manifest-asset-ref.js.map +1 -0
  362. package/dist/assets/scan-manifest-for-asset.d.ts +63 -0
  363. package/dist/assets/scan-manifest-for-asset.d.ts.map +1 -0
  364. package/dist/assets/scan-manifest-for-asset.js +105 -0
  365. package/dist/assets/scan-manifest-for-asset.js.map +1 -0
  366. package/dist/assets/serve-route.d.ts +45 -0
  367. package/dist/assets/serve-route.d.ts.map +1 -0
  368. package/dist/assets/serve-route.js +123 -0
  369. package/dist/assets/serve-route.js.map +1 -0
  370. package/dist/assets/svg-sanitize.d.ts +38 -0
  371. package/dist/assets/svg-sanitize.d.ts.map +1 -0
  372. package/dist/assets/svg-sanitize.js +209 -0
  373. package/dist/assets/svg-sanitize.js.map +1 -0
  374. package/dist/assets/update-metadata.d.ts +61 -0
  375. package/dist/assets/update-metadata.d.ts.map +1 -0
  376. package/dist/assets/update-metadata.js +82 -0
  377. package/dist/assets/update-metadata.js.map +1 -0
  378. package/dist/assets/url.d.ts +82 -0
  379. package/dist/assets/url.d.ts.map +1 -0
  380. package/dist/assets/url.js +103 -0
  381. package/dist/assets/url.js.map +1 -0
  382. package/dist/assets/validate.d.ts +74 -0
  383. package/dist/assets/validate.d.ts.map +1 -0
  384. package/dist/assets/validate.js +136 -0
  385. package/dist/assets/validate.js.map +1 -0
  386. package/dist/assets/variants.d.ts +23 -0
  387. package/dist/assets/variants.d.ts.map +1 -0
  388. package/dist/assets/variants.js +74 -0
  389. package/dist/assets/variants.js.map +1 -0
  390. package/dist/audit/config.d.ts +75 -0
  391. package/dist/audit/config.d.ts.map +1 -0
  392. package/dist/audit/config.js +91 -0
  393. package/dist/audit/config.js.map +1 -0
  394. package/dist/audit/context.d.ts +98 -0
  395. package/dist/audit/context.d.ts.map +1 -0
  396. package/dist/audit/context.js +51 -0
  397. package/dist/audit/context.js.map +1 -0
  398. package/dist/audit/errors.d.ts +73 -0
  399. package/dist/audit/errors.d.ts.map +1 -0
  400. package/dist/audit/errors.js +78 -0
  401. package/dist/audit/errors.js.map +1 -0
  402. package/dist/audit/index.d.ts +16 -0
  403. package/dist/audit/index.d.ts.map +1 -0
  404. package/dist/audit/index.js +10 -0
  405. package/dist/audit/index.js.map +1 -0
  406. package/dist/audit/provider.d.ts +73 -0
  407. package/dist/audit/provider.d.ts.map +1 -0
  408. package/dist/audit/provider.js +2 -0
  409. package/dist/audit/provider.js.map +1 -0
  410. package/dist/audit/providers/history.d.ts +66 -0
  411. package/dist/audit/providers/history.d.ts.map +1 -0
  412. package/dist/audit/providers/history.js +102 -0
  413. package/dist/audit/providers/history.js.map +1 -0
  414. package/dist/audit/pseudonymize.d.ts +26 -0
  415. package/dist/audit/pseudonymize.d.ts.map +1 -0
  416. package/dist/audit/pseudonymize.js +86 -0
  417. package/dist/audit/pseudonymize.js.map +1 -0
  418. package/dist/audit/recorder.d.ts +102 -0
  419. package/dist/audit/recorder.d.ts.map +1 -0
  420. package/dist/audit/recorder.js +55 -0
  421. package/dist/audit/recorder.js.map +1 -0
  422. package/dist/audit/retention.d.ts +83 -0
  423. package/dist/audit/retention.d.ts.map +1 -0
  424. package/dist/audit/retention.js +142 -0
  425. package/dist/audit/retention.js.map +1 -0
  426. package/dist/audit/source-ip.d.ts +32 -0
  427. package/dist/audit/source-ip.d.ts.map +1 -0
  428. package/dist/audit/source-ip.js +164 -0
  429. package/dist/audit/source-ip.js.map +1 -0
  430. package/dist/audit/types.d.ts +143 -0
  431. package/dist/audit/types.d.ts.map +1 -0
  432. package/dist/audit/types.js +33 -0
  433. package/dist/audit/types.js.map +1 -0
  434. package/dist/audit/user-agent.d.ts +28 -0
  435. package/dist/audit/user-agent.d.ts.map +1 -0
  436. package/dist/audit/user-agent.js +63 -0
  437. package/dist/audit/user-agent.js.map +1 -0
  438. package/dist/auth/capabilities.d.ts +28 -0
  439. package/dist/auth/capabilities.d.ts.map +1 -0
  440. package/dist/auth/capabilities.js +101 -0
  441. package/dist/auth/capabilities.js.map +1 -0
  442. package/dist/auth/config.d.ts +109 -0
  443. package/dist/auth/config.d.ts.map +1 -0
  444. package/dist/auth/config.js +221 -0
  445. package/dist/auth/config.js.map +1 -0
  446. package/dist/auth/errors.d.ts +72 -0
  447. package/dist/auth/errors.d.ts.map +1 -0
  448. package/dist/auth/errors.js +78 -0
  449. package/dist/auth/errors.js.map +1 -0
  450. package/dist/auth/factory.d.ts +43 -0
  451. package/dist/auth/factory.d.ts.map +1 -0
  452. package/dist/auth/factory.js +48 -0
  453. package/dist/auth/factory.js.map +1 -0
  454. package/dist/auth/index.d.ts +21 -0
  455. package/dist/auth/index.d.ts.map +1 -0
  456. package/dist/auth/index.js +14 -0
  457. package/dist/auth/index.js.map +1 -0
  458. package/dist/auth/ip-match.d.ts +29 -0
  459. package/dist/auth/ip-match.d.ts.map +1 -0
  460. package/dist/auth/ip-match.js +162 -0
  461. package/dist/auth/ip-match.js.map +1 -0
  462. package/dist/auth/provider.d.ts +76 -0
  463. package/dist/auth/provider.d.ts.map +1 -0
  464. package/dist/auth/provider.js +2 -0
  465. package/dist/auth/provider.js.map +1 -0
  466. package/dist/auth/providers/aws-cognito.d.ts +55 -0
  467. package/dist/auth/providers/aws-cognito.d.ts.map +1 -0
  468. package/dist/auth/providers/aws-cognito.js +114 -0
  469. package/dist/auth/providers/aws-cognito.js.map +1 -0
  470. package/dist/auth/providers/azure-easy-auth.d.ts +7 -0
  471. package/dist/auth/providers/azure-easy-auth.d.ts.map +1 -0
  472. package/dist/auth/providers/azure-easy-auth.js +48 -0
  473. package/dist/auth/providers/azure-easy-auth.js.map +1 -0
  474. package/dist/auth/providers/cloudflare-access.d.ts +71 -0
  475. package/dist/auth/providers/cloudflare-access.d.ts.map +1 -0
  476. package/dist/auth/providers/cloudflare-access.js +120 -0
  477. package/dist/auth/providers/cloudflare-access.js.map +1 -0
  478. package/dist/auth/providers/forwarded-user.d.ts +31 -0
  479. package/dist/auth/providers/forwarded-user.d.ts.map +1 -0
  480. package/dist/auth/providers/forwarded-user.js +72 -0
  481. package/dist/auth/providers/forwarded-user.js.map +1 -0
  482. package/dist/auth/providers/none.d.ts +6 -0
  483. package/dist/auth/providers/none.d.ts.map +1 -0
  484. package/dist/auth/providers/none.js +19 -0
  485. package/dist/auth/providers/none.js.map +1 -0
  486. package/dist/auth/providers/tailscale.d.ts +7 -0
  487. package/dist/auth/providers/tailscale.d.ts.map +1 -0
  488. package/dist/auth/providers/tailscale.js +30 -0
  489. package/dist/auth/providers/tailscale.js.map +1 -0
  490. package/dist/auth/role-resolver.d.ts +38 -0
  491. package/dist/auth/role-resolver.d.ts.map +1 -0
  492. package/dist/auth/role-resolver.js +92 -0
  493. package/dist/auth/role-resolver.js.map +1 -0
  494. package/dist/auth/types.d.ts +150 -0
  495. package/dist/auth/types.d.ts.map +1 -0
  496. package/dist/auth/types.js +60 -0
  497. package/dist/auth/types.js.map +1 -0
  498. package/dist/cache/errors.d.ts +41 -0
  499. package/dist/cache/errors.d.ts.map +1 -0
  500. package/dist/cache/errors.js +44 -0
  501. package/dist/cache/errors.js.map +1 -0
  502. package/dist/cache/factories.d.ts +17 -0
  503. package/dist/cache/factories.d.ts.map +1 -0
  504. package/dist/cache/factories.js +17 -0
  505. package/dist/cache/factories.js.map +1 -0
  506. package/dist/cache/keys.d.ts +63 -0
  507. package/dist/cache/keys.d.ts.map +1 -0
  508. package/dist/cache/keys.js +145 -0
  509. package/dist/cache/keys.js.map +1 -0
  510. package/dist/cache/memory.d.ts +51 -0
  511. package/dist/cache/memory.d.ts.map +1 -0
  512. package/dist/cache/memory.js +204 -0
  513. package/dist/cache/memory.js.map +1 -0
  514. package/dist/cache/per-site.d.ts +22 -0
  515. package/dist/cache/per-site.d.ts.map +1 -0
  516. package/dist/cache/per-site.js +114 -0
  517. package/dist/cache/per-site.js.map +1 -0
  518. package/dist/cache/types.d.ts +142 -0
  519. package/dist/cache/types.d.ts.map +1 -0
  520. package/dist/cache/types.js +33 -0
  521. package/dist/cache/types.js.map +1 -0
  522. package/dist/cli/archive.d.ts +44 -0
  523. package/dist/cli/archive.d.ts.map +1 -0
  524. package/dist/cli/archive.js +310 -0
  525. package/dist/cli/archive.js.map +1 -0
  526. package/dist/cli/assets-cli.d.ts +58 -0
  527. package/dist/cli/assets-cli.d.ts.map +1 -0
  528. package/dist/cli/assets-cli.js +233 -0
  529. package/dist/cli/assets-cli.js.map +1 -0
  530. package/dist/cli/assets-display.d.ts +112 -0
  531. package/dist/cli/assets-display.d.ts.map +1 -0
  532. package/dist/cli/assets-display.js +106 -0
  533. package/dist/cli/assets-display.js.map +1 -0
  534. package/dist/cli/bootstrap.d.ts +15 -10
  535. package/dist/cli/bootstrap.d.ts.map +1 -1
  536. package/dist/cli/bootstrap.js +59 -24
  537. package/dist/cli/bootstrap.js.map +1 -1
  538. package/dist/cli/dev-template-watcher.d.ts +29 -0
  539. package/dist/cli/dev-template-watcher.d.ts.map +1 -0
  540. package/dist/cli/dev-template-watcher.js +38 -0
  541. package/dist/cli/dev-template-watcher.js.map +1 -0
  542. package/dist/cli/history.d.ts.map +1 -1
  543. package/dist/cli/history.js +5 -3
  544. package/dist/cli/history.js.map +1 -1
  545. package/dist/cli/index.js +737 -374
  546. package/dist/cli/index.js.map +1 -1
  547. package/dist/cli/validate-flags.d.ts +29 -0
  548. package/dist/cli/validate-flags.d.ts.map +1 -0
  549. package/dist/cli/validate-flags.js +49 -0
  550. package/dist/cli/validate-flags.js.map +1 -0
  551. package/dist/compare.d.ts +1 -1
  552. package/dist/compare.d.ts.map +1 -1
  553. package/dist/compare.js +40 -35
  554. package/dist/compare.js.map +1 -1
  555. package/dist/component-ids.d.ts +25 -0
  556. package/dist/component-ids.d.ts.map +1 -0
  557. package/dist/component-ids.js +83 -0
  558. package/dist/component-ids.js.map +1 -0
  559. package/dist/config/define.d.ts +61 -0
  560. package/dist/config/define.d.ts.map +1 -0
  561. package/dist/config/define.js +64 -0
  562. package/dist/config/define.js.map +1 -0
  563. package/dist/config/errors.d.ts +32 -0
  564. package/dist/config/errors.d.ts.map +1 -0
  565. package/dist/config/errors.js +40 -0
  566. package/dist/config/errors.js.map +1 -0
  567. package/dist/config/index.d.ts +13 -0
  568. package/dist/config/index.d.ts.map +1 -0
  569. package/dist/config/index.js +20 -0
  570. package/dist/config/index.js.map +1 -0
  571. package/dist/config/loader.d.ts +105 -0
  572. package/dist/config/loader.d.ts.map +1 -0
  573. package/dist/config/loader.js +265 -0
  574. package/dist/config/loader.js.map +1 -0
  575. package/dist/config/schemas.d.ts +89 -0
  576. package/dist/config/schemas.d.ts.map +1 -0
  577. package/dist/config/schemas.js +172 -0
  578. package/dist/config/schemas.js.map +1 -0
  579. package/dist/config/types.d.ts +32 -0
  580. package/dist/config/types.d.ts.map +1 -0
  581. package/dist/config/types.js +15 -0
  582. package/dist/config/types.js.map +1 -0
  583. package/dist/dep-sidecars.d.ts +127 -0
  584. package/dist/dep-sidecars.d.ts.map +1 -0
  585. package/dist/dep-sidecars.js +122 -0
  586. package/dist/dep-sidecars.js.map +1 -0
  587. package/dist/deploy/cloudflare-workers.d.ts +46 -0
  588. package/dist/deploy/cloudflare-workers.d.ts.map +1 -0
  589. package/dist/deploy/cloudflare-workers.js +213 -0
  590. package/dist/deploy/cloudflare-workers.js.map +1 -0
  591. package/dist/deploy/errors.d.ts +66 -0
  592. package/dist/deploy/errors.d.ts.map +1 -0
  593. package/dist/deploy/errors.js +82 -0
  594. package/dist/deploy/errors.js.map +1 -0
  595. package/dist/deploy/index.d.ts +9 -0
  596. package/dist/deploy/index.d.ts.map +1 -0
  597. package/dist/deploy/index.js +3 -0
  598. package/dist/deploy/index.js.map +1 -0
  599. package/dist/deploy/types.d.ts +162 -0
  600. package/dist/deploy/types.d.ts.map +1 -0
  601. package/dist/deploy/types.js +2 -0
  602. package/dist/deploy/types.js.map +1 -0
  603. package/dist/editor/AssetEmbeddedWidget.d.ts +3 -0
  604. package/dist/editor/AssetEmbeddedWidget.d.ts.map +1 -0
  605. package/dist/editor/AssetEmbeddedWidget.js +146 -0
  606. package/dist/editor/AssetEmbeddedWidget.js.map +1 -0
  607. package/dist/editor/mount.d.ts +12 -1
  608. package/dist/editor/mount.d.ts.map +1 -1
  609. package/dist/editor/mount.js +36 -5
  610. package/dist/editor/mount.js.map +1 -1
  611. package/dist/format.d.ts +44 -0
  612. package/dist/format.d.ts.map +1 -0
  613. package/dist/format.js +65 -0
  614. package/dist/format.js.map +1 -0
  615. package/dist/fragment-deps.d.ts +24 -0
  616. package/dist/fragment-deps.d.ts.map +1 -0
  617. package/dist/fragment-deps.js +20 -0
  618. package/dist/fragment-deps.js.map +1 -0
  619. package/dist/fragments/create.d.ts +70 -0
  620. package/dist/fragments/create.d.ts.map +1 -0
  621. package/dist/fragments/create.js +93 -0
  622. package/dist/fragments/create.js.map +1 -0
  623. package/dist/fragments/publish.d.ts +37 -0
  624. package/dist/fragments/publish.d.ts.map +1 -0
  625. package/dist/fragments/publish.js +52 -0
  626. package/dist/fragments/publish.js.map +1 -0
  627. package/dist/fragments/save.d.ts +81 -0
  628. package/dist/fragments/save.d.ts.map +1 -0
  629. package/dist/fragments/save.js +105 -0
  630. package/dist/fragments/save.js.map +1 -0
  631. package/dist/hash.d.ts +0 -6
  632. package/dist/hash.d.ts.map +1 -1
  633. package/dist/hash.js +0 -18
  634. package/dist/hash.js.map +1 -1
  635. package/dist/history-provider.d.ts.map +1 -1
  636. package/dist/history-provider.js +30 -8
  637. package/dist/history-provider.js.map +1 -1
  638. package/dist/history-recorder.d.ts +10 -6
  639. package/dist/history-recorder.d.ts.map +1 -1
  640. package/dist/history-recorder.js +13 -5
  641. package/dist/history-recorder.js.map +1 -1
  642. package/dist/history-restorer.d.ts.map +1 -1
  643. package/dist/history-restorer.js +34 -2
  644. package/dist/history-restorer.js.map +1 -1
  645. package/dist/history.d.ts +26 -8
  646. package/dist/history.d.ts.map +1 -1
  647. package/dist/hooks/audit-emitter.d.ts +73 -0
  648. package/dist/hooks/audit-emitter.d.ts.map +1 -0
  649. package/dist/hooks/audit-emitter.js +13 -0
  650. package/dist/hooks/audit-emitter.js.map +1 -0
  651. package/dist/hooks/context.d.ts +78 -0
  652. package/dist/hooks/context.d.ts.map +1 -0
  653. package/dist/hooks/context.js +56 -0
  654. package/dist/hooks/context.js.map +1 -0
  655. package/dist/hooks/contribution.d.ts +90 -0
  656. package/dist/hooks/contribution.d.ts.map +1 -0
  657. package/dist/hooks/contribution.js +2 -0
  658. package/dist/hooks/contribution.js.map +1 -0
  659. package/dist/hooks/dispatch.d.ts +30 -0
  660. package/dist/hooks/dispatch.d.ts.map +1 -0
  661. package/dist/hooks/dispatch.js +252 -0
  662. package/dist/hooks/dispatch.js.map +1 -0
  663. package/dist/hooks/errors.d.ts +100 -0
  664. package/dist/hooks/errors.d.ts.map +1 -0
  665. package/dist/hooks/errors.js +103 -0
  666. package/dist/hooks/errors.js.map +1 -0
  667. package/dist/hooks/index.d.ts +15 -0
  668. package/dist/hooks/index.d.ts.map +1 -0
  669. package/dist/hooks/index.js +6 -0
  670. package/dist/hooks/index.js.map +1 -0
  671. package/dist/hooks/registry.d.ts +53 -0
  672. package/dist/hooks/registry.d.ts.map +1 -0
  673. package/dist/hooks/registry.js +139 -0
  674. package/dist/hooks/registry.js.map +1 -0
  675. package/dist/hooks/storage.d.ts +43 -0
  676. package/dist/hooks/storage.d.ts.map +1 -0
  677. package/dist/hooks/storage.js +2 -0
  678. package/dist/hooks/storage.js.map +1 -0
  679. package/dist/hooks/types.d.ts +324 -0
  680. package/dist/hooks/types.d.ts.map +1 -0
  681. package/dist/hooks/types.js +2 -0
  682. package/dist/hooks/types.js.map +1 -0
  683. package/dist/index.d.ts +27 -9
  684. package/dist/index.d.ts.map +1 -1
  685. package/dist/index.js +50 -7
  686. package/dist/index.js.map +1 -1
  687. package/dist/locale.d.ts +25 -1
  688. package/dist/locale.d.ts.map +1 -1
  689. package/dist/locale.js +44 -2
  690. package/dist/locale.js.map +1 -1
  691. package/dist/manifest-save.d.ts +255 -0
  692. package/dist/manifest-save.d.ts.map +1 -0
  693. package/dist/manifest-save.js +260 -0
  694. package/dist/manifest-save.js.map +1 -0
  695. package/dist/manifest.d.ts +1 -2
  696. package/dist/manifest.d.ts.map +1 -1
  697. package/dist/manifest.js +43 -44
  698. package/dist/manifest.js.map +1 -1
  699. package/dist/node-floor.d.ts +3 -0
  700. package/dist/node-floor.d.ts.map +1 -0
  701. package/dist/node-floor.js +3 -0
  702. package/dist/node-floor.js.map +1 -0
  703. package/dist/pages/create.d.ts +103 -0
  704. package/dist/pages/create.d.ts.map +1 -0
  705. package/dist/pages/create.js +117 -0
  706. package/dist/pages/create.js.map +1 -0
  707. package/dist/pages/publish.d.ts +59 -0
  708. package/dist/pages/publish.d.ts.map +1 -0
  709. package/dist/pages/publish.js +78 -0
  710. package/dist/pages/publish.js.map +1 -0
  711. package/dist/pages/save.d.ts +97 -0
  712. package/dist/pages/save.d.ts.map +1 -0
  713. package/dist/pages/save.js +138 -0
  714. package/dist/pages/save.js.map +1 -0
  715. package/dist/providers/_atomic-write.d.ts +9 -0
  716. package/dist/providers/_atomic-write.d.ts.map +1 -0
  717. package/dist/providers/_atomic-write.js +72 -0
  718. package/dist/providers/_atomic-write.js.map +1 -0
  719. package/dist/providers/_rm-ignore-missing.d.ts +31 -0
  720. package/dist/providers/_rm-ignore-missing.d.ts.map +1 -0
  721. package/dist/providers/_rm-ignore-missing.js +12 -0
  722. package/dist/providers/_rm-ignore-missing.js.map +1 -0
  723. package/dist/providers/_stream-interop.d.ts +23 -0
  724. package/dist/providers/_stream-interop.d.ts.map +1 -0
  725. package/dist/providers/_stream-interop.js +21 -0
  726. package/dist/providers/_stream-interop.js.map +1 -0
  727. package/dist/providers/azure-blob.d.ts.map +1 -1
  728. package/dist/providers/azure-blob.js +60 -0
  729. package/dist/providers/azure-blob.js.map +1 -1
  730. package/dist/providers/factories.d.ts +65 -0
  731. package/dist/providers/factories.d.ts.map +1 -0
  732. package/dist/providers/factories.js +189 -0
  733. package/dist/providers/factories.js.map +1 -0
  734. package/dist/providers/filesystem.d.ts +4 -0
  735. package/dist/providers/filesystem.d.ts.map +1 -1
  736. package/dist/providers/filesystem.js +63 -2
  737. package/dist/providers/filesystem.js.map +1 -1
  738. package/dist/providers/s3.d.ts.map +1 -1
  739. package/dist/providers/s3.js +84 -1
  740. package/dist/providers/s3.js.map +1 -1
  741. package/dist/publish-item.d.ts +225 -0
  742. package/dist/publish-item.d.ts.map +1 -0
  743. package/dist/publish-item.js +210 -0
  744. package/dist/publish-item.js.map +1 -0
  745. package/dist/publish-rendered.d.ts +37 -17
  746. package/dist/publish-rendered.d.ts.map +1 -1
  747. package/dist/publish-rendered.js +144 -71
  748. package/dist/publish-rendered.js.map +1 -1
  749. package/dist/publish-renderers.d.ts +132 -0
  750. package/dist/publish-renderers.d.ts.map +1 -0
  751. package/dist/publish-renderers.js +240 -0
  752. package/dist/publish-renderers.js.map +1 -0
  753. package/dist/publish-run.d.ts +223 -0
  754. package/dist/publish-run.d.ts.map +1 -0
  755. package/dist/publish-run.js +307 -0
  756. package/dist/publish-run.js.map +1 -0
  757. package/dist/publish.d.ts +13 -12
  758. package/dist/publish.d.ts.map +1 -1
  759. package/dist/publish.js +24 -57
  760. package/dist/publish.js.map +1 -1
  761. package/dist/render-for-analysis.d.ts +24 -0
  762. package/dist/render-for-analysis.d.ts.map +1 -0
  763. package/dist/render-for-analysis.js +146 -0
  764. package/dist/render-for-analysis.js.map +1 -0
  765. package/dist/resolver.d.ts +12 -2
  766. package/dist/resolver.d.ts.map +1 -1
  767. package/dist/resolver.js +101 -32
  768. package/dist/resolver.js.map +1 -1
  769. package/dist/runtime/archive-marker.d.ts +62 -0
  770. package/dist/runtime/archive-marker.d.ts.map +1 -0
  771. package/dist/runtime/archive-marker.js +88 -0
  772. package/dist/runtime/archive-marker.js.map +1 -0
  773. package/dist/runtime/capability-gap-warnings.d.ts +42 -0
  774. package/dist/runtime/capability-gap-warnings.d.ts.map +1 -0
  775. package/dist/runtime/capability-gap-warnings.js +28 -0
  776. package/dist/runtime/capability-gap-warnings.js.map +1 -0
  777. package/dist/runtime/redirects-emit.d.ts +93 -0
  778. package/dist/runtime/redirects-emit.d.ts.map +1 -0
  779. package/dist/runtime/redirects-emit.js +89 -0
  780. package/dist/runtime/redirects-emit.js.map +1 -0
  781. package/dist/runtime/runtime-capabilities.d.ts +79 -0
  782. package/dist/runtime/runtime-capabilities.d.ts.map +1 -0
  783. package/dist/runtime/runtime-capabilities.js +60 -0
  784. package/dist/runtime/runtime-capabilities.js.map +1 -0
  785. package/dist/save-etag.d.ts +69 -0
  786. package/dist/save-etag.d.ts.map +1 -0
  787. package/dist/save-etag.js +118 -0
  788. package/dist/save-etag.js.map +1 -0
  789. package/dist/schema/dimensions.d.ts +78 -0
  790. package/dist/schema/dimensions.d.ts.map +1 -0
  791. package/dist/schema/dimensions.js +97 -0
  792. package/dist/schema/dimensions.js.map +1 -0
  793. package/dist/schema/helpers.d.ts +108 -0
  794. package/dist/schema/helpers.d.ts.map +1 -0
  795. package/dist/schema/helpers.js +133 -0
  796. package/dist/schema/helpers.js.map +1 -0
  797. package/dist/schema/index.d.ts +27 -0
  798. package/dist/schema/index.d.ts.map +1 -0
  799. package/dist/schema/index.js +25 -0
  800. package/dist/schema/index.js.map +1 -0
  801. package/dist/schema/types.d.ts +390 -0
  802. package/dist/schema/types.d.ts.map +1 -0
  803. package/dist/schema/types.js +25 -0
  804. package/dist/schema/types.js.map +1 -0
  805. package/dist/selector-chain.d.ts +63 -0
  806. package/dist/selector-chain.d.ts.map +1 -0
  807. package/dist/selector-chain.js +58 -0
  808. package/dist/selector-chain.js.map +1 -0
  809. package/dist/sidecars.d.ts +19 -18
  810. package/dist/sidecars.d.ts.map +1 -1
  811. package/dist/sidecars.js +70 -62
  812. package/dist/sidecars.js.map +1 -1
  813. package/dist/site-loader.d.ts +42 -4
  814. package/dist/site-loader.d.ts.map +1 -1
  815. package/dist/site-loader.js +27 -8
  816. package/dist/site-loader.js.map +1 -1
  817. package/dist/targets.d.ts +21 -12
  818. package/dist/targets.d.ts.map +1 -1
  819. package/dist/targets.js +27 -117
  820. package/dist/targets.js.map +1 -1
  821. package/dist/testing/admin-cache-contract.d.ts +52 -0
  822. package/dist/testing/admin-cache-contract.d.ts.map +1 -0
  823. package/dist/testing/admin-cache-contract.js +203 -0
  824. package/dist/testing/admin-cache-contract.js.map +1 -0
  825. package/dist/testing/index.d.ts +11 -0
  826. package/dist/testing/index.d.ts.map +1 -0
  827. package/dist/testing/index.js +11 -0
  828. package/dist/testing/index.js.map +1 -0
  829. package/dist/themes.d.ts +69 -0
  830. package/dist/themes.d.ts.map +1 -0
  831. package/dist/themes.js +85 -0
  832. package/dist/themes.js.map +1 -0
  833. package/dist/transforms/adapter.d.ts +115 -0
  834. package/dist/transforms/adapter.d.ts.map +1 -0
  835. package/dist/transforms/adapter.js +2 -0
  836. package/dist/transforms/adapter.js.map +1 -0
  837. package/dist/transforms/cloudflare.d.ts +17 -0
  838. package/dist/transforms/cloudflare.d.ts.map +1 -0
  839. package/dist/transforms/cloudflare.js +110 -0
  840. package/dist/transforms/cloudflare.js.map +1 -0
  841. package/dist/transforms/factories.d.ts +16 -0
  842. package/dist/transforms/factories.d.ts.map +1 -0
  843. package/dist/transforms/factories.js +18 -0
  844. package/dist/transforms/factories.js.map +1 -0
  845. package/dist/transforms/index.d.ts +17 -0
  846. package/dist/transforms/index.d.ts.map +1 -0
  847. package/dist/transforms/index.js +6 -0
  848. package/dist/transforms/index.js.map +1 -0
  849. package/dist/transforms/sharp.d.ts +17 -0
  850. package/dist/transforms/sharp.d.ts.map +1 -0
  851. package/dist/transforms/sharp.js +57 -0
  852. package/dist/transforms/sharp.js.map +1 -0
  853. package/dist/types.d.ts +485 -34
  854. package/dist/types.d.ts.map +1 -1
  855. package/dist/types.js +20 -1
  856. package/dist/types.js.map +1 -1
  857. package/dist/validation/alt-required-walker.d.ts +27 -0
  858. package/dist/validation/alt-required-walker.d.ts.map +1 -0
  859. package/dist/validation/alt-required-walker.js +108 -0
  860. package/dist/validation/alt-required-walker.js.map +1 -0
  861. package/dist/validation/default-registry.d.ts +12 -0
  862. package/dist/validation/default-registry.d.ts.map +1 -0
  863. package/dist/validation/default-registry.js +55 -0
  864. package/dist/validation/default-registry.js.map +1 -0
  865. package/dist/validation/publish-audit.d.ts +44 -0
  866. package/dist/validation/publish-audit.d.ts.map +1 -0
  867. package/dist/validation/publish-audit.js +64 -0
  868. package/dist/validation/publish-audit.js.map +1 -0
  869. package/dist/validation/registry.d.ts +23 -0
  870. package/dist/validation/registry.d.ts.map +1 -0
  871. package/dist/validation/registry.js +15 -0
  872. package/dist/validation/registry.js.map +1 -0
  873. package/dist/validation/save-delta.d.ts +46 -0
  874. package/dist/validation/save-delta.d.ts.map +1 -0
  875. package/dist/validation/save-delta.js +57 -0
  876. package/dist/validation/save-delta.js.map +1 -0
  877. package/dist/validation/scanner.d.ts +91 -0
  878. package/dist/validation/scanner.d.ts.map +1 -0
  879. package/dist/validation/scanner.js +327 -0
  880. package/dist/validation/scanner.js.map +1 -0
  881. package/dist/validation/template-impact.d.ts +52 -0
  882. package/dist/validation/template-impact.d.ts.map +1 -0
  883. package/dist/validation/template-impact.js +53 -0
  884. package/dist/validation/template-impact.js.map +1 -0
  885. package/dist/validation/types.d.ts +123 -0
  886. package/dist/validation/types.d.ts.map +1 -0
  887. package/dist/validation/types.js +7 -0
  888. package/dist/validation/types.js.map +1 -0
  889. package/dist/validation/validators/accessibility.d.ts +3 -0
  890. package/dist/validation/validators/accessibility.d.ts.map +1 -0
  891. package/dist/validation/validators/accessibility.js +106 -0
  892. package/dist/validation/validators/accessibility.js.map +1 -0
  893. package/dist/validation/validators/aliasof-points-to-archived.d.ts +40 -0
  894. package/dist/validation/validators/aliasof-points-to-archived.d.ts.map +1 -0
  895. package/dist/validation/validators/aliasof-points-to-archived.js +34 -0
  896. package/dist/validation/validators/aliasof-points-to-archived.js.map +1 -0
  897. package/dist/validation/validators/alt-required.d.ts +3 -0
  898. package/dist/validation/validators/alt-required.d.ts.map +1 -0
  899. package/dist/validation/validators/alt-required.js +118 -0
  900. package/dist/validation/validators/alt-required.js.map +1 -0
  901. package/dist/validation/validators/archive-not-supported-on-target.d.ts +3 -0
  902. package/dist/validation/validators/archive-not-supported-on-target.d.ts.map +1 -0
  903. package/dist/validation/validators/archive-not-supported-on-target.js +38 -0
  904. package/dist/validation/validators/archive-not-supported-on-target.js.map +1 -0
  905. package/dist/validation/validators/broken-links.d.ts +3 -0
  906. package/dist/validation/validators/broken-links.d.ts.map +1 -0
  907. package/dist/validation/validators/broken-links.js +190 -0
  908. package/dist/validation/validators/broken-links.js.map +1 -0
  909. package/dist/validation/validators/circular-alias.d.ts +36 -0
  910. package/dist/validation/validators/circular-alias.d.ts.map +1 -0
  911. package/dist/validation/validators/circular-alias.js +63 -0
  912. package/dist/validation/validators/circular-alias.js.map +1 -0
  913. package/dist/validation/validators/circular-fragment.d.ts +15 -0
  914. package/dist/validation/validators/circular-fragment.d.ts.map +1 -0
  915. package/dist/validation/validators/circular-fragment.js +97 -0
  916. package/dist/validation/validators/circular-fragment.js.map +1 -0
  917. package/dist/validation/validators/dangling-alias.d.ts +38 -0
  918. package/dist/validation/validators/dangling-alias.d.ts.map +1 -0
  919. package/dist/validation/validators/dangling-alias.js +31 -0
  920. package/dist/validation/validators/dangling-alias.js.map +1 -0
  921. package/dist/validation/validators/deploy-target-type-supported.d.ts +3 -0
  922. package/dist/validation/validators/deploy-target-type-supported.d.ts.map +1 -0
  923. package/dist/validation/validators/deploy-target-type-supported.js +32 -0
  924. package/dist/validation/validators/deploy-target-type-supported.js.map +1 -0
  925. package/dist/validation/validators/dynamic-route-conflict.d.ts +18 -0
  926. package/dist/validation/validators/dynamic-route-conflict.d.ts.map +1 -0
  927. package/dist/validation/validators/dynamic-route-conflict.js +80 -0
  928. package/dist/validation/validators/dynamic-route-conflict.js.map +1 -0
  929. package/dist/validation/validators/html-validity.d.ts +3 -0
  930. package/dist/validation/validators/html-validity.d.ts.map +1 -0
  931. package/dist/validation/validators/html-validity.js +89 -0
  932. package/dist/validation/validators/html-validity.js.map +1 -0
  933. package/dist/validation/validators/orphaned-locale-file.d.ts +21 -0
  934. package/dist/validation/validators/orphaned-locale-file.d.ts.map +1 -0
  935. package/dist/validation/validators/orphaned-locale-file.js +84 -0
  936. package/dist/validation/validators/orphaned-locale-file.js.map +1 -0
  937. package/dist/validation/validators/referenced-archived-without-alias.d.ts +3 -0
  938. package/dist/validation/validators/referenced-archived-without-alias.d.ts.map +1 -0
  939. package/dist/validation/validators/referenced-archived-without-alias.js +65 -0
  940. package/dist/validation/validators/referenced-archived-without-alias.js.map +1 -0
  941. package/dist/validation/validators/referenced-asset-exists.d.ts +13 -0
  942. package/dist/validation/validators/referenced-asset-exists.d.ts.map +1 -0
  943. package/dist/validation/validators/referenced-asset-exists.js +80 -0
  944. package/dist/validation/validators/referenced-asset-exists.js.map +1 -0
  945. package/dist/validation/validators/referenced-fragment-exists.d.ts +9 -0
  946. package/dist/validation/validators/referenced-fragment-exists.d.ts.map +1 -0
  947. package/dist/validation/validators/referenced-fragment-exists.js +52 -0
  948. package/dist/validation/validators/referenced-fragment-exists.js.map +1 -0
  949. package/dist/validation/validators/referenced-template-exists.d.ts +10 -0
  950. package/dist/validation/validators/referenced-template-exists.d.ts.map +1 -0
  951. package/dist/validation/validators/referenced-template-exists.js +74 -0
  952. package/dist/validation/validators/referenced-template-exists.js.map +1 -0
  953. package/dist/validation/validators/schema-conformance.d.ts +17 -0
  954. package/dist/validation/validators/schema-conformance.d.ts.map +1 -0
  955. package/dist/validation/validators/schema-conformance.js +94 -0
  956. package/dist/validation/validators/schema-conformance.js.map +1 -0
  957. package/dist/validation/validators/target-deploy-coverage.d.ts +3 -0
  958. package/dist/validation/validators/target-deploy-coverage.d.ts.map +1 -0
  959. package/dist/validation/validators/target-deploy-coverage.js +37 -0
  960. package/dist/validation/validators/target-deploy-coverage.js.map +1 -0
  961. package/dist/validation/validators/unused-fragment.d.ts +16 -0
  962. package/dist/validation/validators/unused-fragment.d.ts.map +1 -0
  963. package/dist/validation/validators/unused-fragment.js +86 -0
  964. package/dist/validation/validators/unused-fragment.js.map +1 -0
  965. package/package.json +69 -27
  966. package/admin-dist/assets/index-B6pVot0Y.css +0 -1
  967. package/admin-dist/assets/index-DniLwxJA.js +0 -609
  968. package/admin-dist/assets/rolldown-runtime-COnpUsM8.js +0 -1
  969. package/admin-dist/assets/vendor-rjsf-HKBAjOmQ.js +0 -32
  970. package/admin-dist/assets/vendor-tiptap-IyO99U4R.js +0 -142
  971. package/admin-dist/assets/vendor-vue-D3wBSmDf.js +0 -1
  972. package/dist/providers/r2.d.ts +0 -8
  973. package/dist/providers/r2.d.ts.map +0 -1
  974. package/dist/providers/r2.js +0 -86
  975. package/dist/providers/r2.js.map +0 -1
  976. package/dist/publish-locale.d.ts +0 -44
  977. package/dist/publish-locale.d.ts.map +0 -1
  978. package/dist/publish-locale.js +0 -103
  979. package/dist/publish-locale.js.map +0 -1
  980. package/dist/source-sidecars.d.ts +0 -32
  981. package/dist/source-sidecars.d.ts.map +0 -1
  982. package/dist/source-sidecars.js +0 -98
  983. package/dist/source-sidecars.js.map +0 -1
@@ -2,23 +2,92 @@ import { Hono } from 'hono';
2
2
  import { streamSSE } from 'hono/streaming';
3
3
  import { getType, getEnvironment, isEditable, isHistoryEnabled, getHistoryRetention } from '../../types.js';
4
4
  import { publishItems, resolveDependencies, findFragmentDependents, findDependentsFromSidecars } from '../../publish.js';
5
- import { mapLimitStream } from '../../concurrency.js';
6
- import { publishPageStatic, publishSiteManifest, publishFragmentIndex, createCloudflarePurge, lookupCloudflareZoneId, } from '../../publish-rendered.js';
5
+ import { createCloudflarePurge, lookupCloudflareZoneId } from '../../publish-rendered.js';
7
6
  import { loadSiteFromSource } from '../source-context.js';
8
- import { publishPageAllLocales, publishFragmentAllLocales } from '../../publish-locale.js';
9
7
  import { resolveEnvVars } from '../../targets.js';
10
- import { scanTemplates, templateHashesFrom } from '../../templates-scan.js';
11
- import { hashManifest } from '../../hash.js';
8
+ import { isAltAdapterConfigured } from '../../alt/factory.js';
9
+ import { resolveAltConfig } from '../../alt/config.js';
10
+ import { inspectTarget } from '../../runtime/runtime-capabilities.js';
11
+ import { scanTemplates } from '../../templates-scan.js';
12
12
  import { createContentRoot } from '../../content-root.js';
13
13
  import { createHistoryProvider } from '../../history-provider.js';
14
14
  import { recordWrite } from '../../history-recorder.js';
15
+ import { requireCapability } from '../middleware/capability.js';
16
+ import { buildHookContext, dispatchAfterPublish, dispatchBeforePublish, HookCancellation, HookTimeout, } from '../../hooks/index.js';
17
+ import { makeAuditFiringEmitter } from '../hook-audit-emitter.js';
18
+ import { runPublishAudit } from '../../validation/publish-audit.js';
15
19
  export function publishRoutes(resolve, preInitTargets, targetConfigs, templatesDir,
16
20
  // Optional injected scanner — the admin-api server memoizes it and
17
21
  // clears the cache via its template file watcher. Default: fresh scan
18
22
  // on every call (used by the CLI and tests).
19
- scanTemplatesInjected) {
23
+ scanTemplatesInjected, opts = {}) {
20
24
  const scan = scanTemplatesInjected ?? scanTemplates;
25
+ const hooks = opts.hooks;
21
26
  const app = new Hono();
27
+ /**
28
+ * Categorize an item path into the hook payload shape.
29
+ * Items arrive as e.g. `pages/home`, `fragments/header`,
30
+ * `assets/hero`. Hooks see kind + name + path; if the prefix
31
+ * doesn't match, default to 'asset' (covers loose path forms).
32
+ */
33
+ function toPublishItem(itemPath) {
34
+ if (itemPath.startsWith('pages/')) {
35
+ return { kind: 'page', name: itemPath.slice('pages/'.length), path: itemPath };
36
+ }
37
+ if (itemPath.startsWith('fragments/')) {
38
+ return { kind: 'fragment', name: itemPath.slice('fragments/'.length), path: itemPath };
39
+ }
40
+ return {
41
+ kind: 'asset',
42
+ name: itemPath.startsWith('assets/') ? itemPath.slice('assets/'.length) : itemPath,
43
+ path: itemPath,
44
+ };
45
+ }
46
+ /**
47
+ * Server-side publish gate (Validation Cut 4).
48
+ *
49
+ * Runs `runPublishAudit` for every (target × items) pair the request is
50
+ * asking to publish, applies the per-target `publishAudit.strict`
51
+ * promotion, and returns any error-severity issues. The publish
52
+ * handlers refuse with 409 when this returns non-empty results — the
53
+ * client-side audit modal is the polite UX, this gate is the
54
+ * enforcement layer so a determined client can't bypass.
55
+ *
56
+ * Returns `{ target, issues }` per target that produced errors. Targets
57
+ * with only warns/infos are omitted (errors-only gate).
58
+ */
59
+ async function evaluatePublishGate(source, targetNames, itemPaths) {
60
+ if (!opts.validators)
61
+ return [];
62
+ const items = [];
63
+ for (const p of itemPaths) {
64
+ const i = toPublishItem(p);
65
+ if (i.kind === 'page' || i.kind === 'fragment')
66
+ items.push({ kind: i.kind, name: i.name });
67
+ }
68
+ if (items.length === 0)
69
+ return [];
70
+ const site = await loadSiteFromSource(source);
71
+ const blocked = [];
72
+ for (const targetName of targetNames) {
73
+ const targetCfg = source.manifest?.targets?.[targetName];
74
+ const strict = !!targetCfg?.publishAudit?.strict;
75
+ const issues = await runPublishAudit({
76
+ items,
77
+ site,
78
+ contentRoot: source.contentRoot,
79
+ storage: source.storage,
80
+ registry: opts.validators,
81
+ cache: source.cache,
82
+ strict,
83
+ templatesDir: site.templatesDir,
84
+ });
85
+ const errors = issues.filter(i => i.severity === 'error');
86
+ if (errors.length > 0)
87
+ blocked.push({ target: targetName, issues: errors });
88
+ }
89
+ return blocked;
90
+ }
22
91
  // Background target initialization — lazy, needs the resolved source's
23
92
  // projectSiteDir to resolve filesystem target paths. We call resolve()
24
93
  // once with undefined (→ default editable) to obtain projectSiteDir.
@@ -35,7 +104,7 @@ scanTemplatesInjected) {
35
104
  initPromise = (async () => {
36
105
  const { createTargetRegistry } = await import('../../targets.js');
37
106
  const bootstrapSource = await resolve(undefined);
38
- const t = await createTargetRegistry(targetConfigs, bootstrapSource.projectSiteDir);
107
+ const t = await createTargetRegistry(targetConfigs);
39
108
  targets = t;
40
109
  return t;
41
110
  })().catch(() => {
@@ -48,15 +117,76 @@ scanTemplatesInjected) {
48
117
  function getTargetConfig(name) {
49
118
  return targetConfigs?.[name];
50
119
  }
51
- app.get('/api/targets', async (c) => {
120
+ // First-time dependents lookup against a source target needs the
121
+ // `.gazetta/fragment-deps/` index to be present. Save handlers write
122
+ // it incrementally on every save, but a fresh dev server pointed at
123
+ // a content tree that's never been saved through admin will have an
124
+ // empty index. Rebuild once per (source-target) and memoize the
125
+ // in-flight Promise so concurrent tree badges share one walk.
126
+ const fragmentDepsBackfill = new Map();
127
+ async function ensureFragmentDepsIndex(source) {
128
+ const key = source.targetName ?? '__source__';
129
+ let p = fragmentDepsBackfill.get(key);
130
+ if (p)
131
+ return p;
132
+ p = (async () => {
133
+ const indexRoot = source.contentRoot.path('.gazetta', 'fragment-deps');
134
+ // Cheap existence probe — if any entry is present, the index has
135
+ // been written at least once and incremental save handlers keep
136
+ // it consistent thereafter.
137
+ const exists = await source.storage.exists(indexRoot);
138
+ if (exists)
139
+ return;
140
+ const { rebuildDepIndex } = await import('../../publish-rendered.js');
141
+ const { FRAGMENT_DEPS } = await import('../../fragment-deps.js');
142
+ const site = await loadSiteFromSource(source);
143
+ await rebuildDepIndex(FRAGMENT_DEPS, site, source.storage, source.contentRoot.rootPath);
144
+ })().catch(err => {
145
+ // Clear on failure so the next caller retries.
146
+ fragmentDepsBackfill.delete(key);
147
+ throw err;
148
+ });
149
+ fragmentDepsBackfill.set(key, p);
150
+ return p;
151
+ }
152
+ app.get('/api/targets', requireCapability('read:pages'), async (c) => {
52
153
  const t = await getTargets();
154
+ // Resolve once — the site manifest is the same across all
155
+ // targets in this loop. resolve(undefined) returns the source
156
+ // context whose .manifest holds `ai:` and `altText:`.
157
+ const source = await resolve(undefined);
158
+ const site = source.manifest;
53
159
  return c.json([...t.keys()].map(name => {
54
160
  const cfg = getTargetConfig(name);
161
+ // AI alt-text capability — site + target inherit chain. When
162
+ // the site manifest isn't available (legacy/test setups), the
163
+ // feature is reported off uniformly.
164
+ const altResolved = site ? resolveAltConfig(site, cfg) : null;
165
+ const altAvailable = site ? isAltAdapterConfigured(site, cfg) : false;
166
+ // Runtime capability inspection per
167
+ // `feature-design-process.md`'s capability-gap UX discipline
168
+ // (surface #2 — author-time modal data source). The admin
169
+ // archive modal renders per-target capability badges from
170
+ // these fields; Cut 10 wires the UI.
171
+ const inspection = cfg
172
+ ? inspectTarget(cfg)
173
+ : { has: new Set(), gaps: [] };
55
174
  return {
56
175
  name,
57
176
  environment: cfg ? getEnvironment(cfg) : 'local',
58
177
  type: cfg ? getType(cfg) : 'static',
59
178
  editable: cfg ? isEditable(cfg) : true,
179
+ altText: {
180
+ available: altAvailable,
181
+ // When not configured, the resolved value is null — surface
182
+ // false rather than the hardcoded default so the UI doesn't
183
+ // imply "auto-fire is on" for an unconfigured target.
184
+ auto: altResolved?.auto ?? false,
185
+ },
186
+ capabilities: {
187
+ has: [...inspection.has],
188
+ gaps: inspection.gaps.map(g => ({ capability: g.capability, reason: g.reason })),
189
+ },
60
190
  };
61
191
  }));
62
192
  });
@@ -65,37 +195,23 @@ scanTemplatesInjected) {
65
195
  * GET /api/dependents?item=fragments/header[&target=staging]
66
196
  * → { pages: string[], fragments: string[] }
67
197
  *
68
- * Without `target`: scans local source manifests (authoritative for the
69
- * current draft state what's about to be published). Slow-ish on very
70
- * large sites since it reads every manifest.
71
- *
72
- * With `target`: uses published .uses-* / .tpl-* sidecars on that target.
73
- * Listings only, no content reads — scales to 10k+ items at the cost of
74
- * reflecting only what's been published (not unsaved local changes).
75
- * Useful for answering "what pages would need republish if this fragment
76
- * changed" on large sites.
198
+ * Reads `.gazetta/fragment-deps/` per-edge sidecars on the requested
199
+ * target (or the source when `target` is omitted or names the source).
200
+ * Save handlers maintain the index incrementally; a fresh dev server
201
+ * with no prior saves triggers a one-time rebuild via
202
+ * `ensureFragmentDepsIndex`. Listings only, no content reads
203
+ * scales to 10k+ items.
77
204
  */
78
- app.get('/api/dependents', async (c) => {
205
+ app.get('/api/dependents', requireCapability('read:pages'), async (c) => {
79
206
  const item = c.req.query('item');
80
207
  if (!item || !item.startsWith('fragments/')) {
81
208
  return c.json({ error: 'Missing or invalid "item" query (must be fragments/<name>)' }, 400);
82
209
  }
83
210
  const fragmentName = item.slice('fragments/'.length);
84
- // `target` — specific published target's sidecars (read-only listing).
85
- // Useful for "what would need republish on staging?" queries
86
- // where sidecars reflect the last publish, not the draft.
87
- // `source` — the editable source target (authoritative for the draft).
88
- // When target === source (common case: client sends the
89
- // active editable target), route through source so the
90
- // sidecar writer can backfill missing entries.
91
211
  const targetName = c.req.query('target');
92
212
  const sourceName = c.req.query('source');
93
213
  try {
94
214
  const source = await resolve(sourceName);
95
- // Treat `target=local` (the active editable target) the same as no
96
- // target — the source path is the authoritative one for the draft,
97
- // and it's the only path that knows how to backfill sidecars on a
98
- // fresh dev server.
99
215
  const isTargetTheSource = !targetName || targetName === source.targetName;
100
216
  if (!isTargetTheSource) {
101
217
  const t = await getTargets();
@@ -105,17 +221,8 @@ scanTemplatesInjected) {
105
221
  const result = await findDependentsFromSidecars(createContentRoot(targetStorage), { fragment: fragmentName });
106
222
  return c.json(result);
107
223
  }
108
- // Source-side path: ensure every item has a sidecar before reading.
109
- // The writer memoizes the backfill concurrent tree badges on a
110
- // fresh dev server share one pass instead of racing to an empty index.
111
- const sidecarWriter = source.sidecarWriter;
112
- if (sidecarWriter) {
113
- await sidecarWriter.ensureBackfilled();
114
- const result = await findDependentsFromSidecars(source.contentRoot, { fragment: fragmentName });
115
- return c.json(result);
116
- }
117
- // No writer injected (legacy setup) — fall back to the manifest walker.
118
- const result = await findFragmentDependents(source.contentRoot, fragmentName);
224
+ await ensureFragmentDepsIndex(source);
225
+ const result = await findDependentsFromSidecars(source.contentRoot, { fragment: fragmentName });
119
226
  return c.json(result);
120
227
  }
121
228
  catch (err) {
@@ -174,7 +281,9 @@ scanTemplatesInjected) {
174
281
  };
175
282
  return;
176
283
  }
177
- const templateHashes = templateHashesFrom(templateInfos);
284
+ // Per Cut 7 cutover: per-item hash composition lives inside publishRun
285
+ // (consumes templateInfos, computes per-item hashManifest including
286
+ // fragmentHashes for static-mode pages). Route doesn't precompute.
178
287
  const site = await loadSiteFromSource(source, { templatesDir: tdir });
179
288
  yield { kind: 'start', targets: targetNames, itemsPerTarget: allItems.length };
180
289
  const results = [];
@@ -204,6 +313,12 @@ scanTemplatesInjected) {
204
313
  const total = 1 + targetItems.length + 1 + (purgeConfig?.type === 'cloudflare' ? 1 : 0);
205
314
  yield { kind: 'target-start', target: targetName, total };
206
315
  let current = 0;
316
+ // Buffer for publishRun's progress events. The route's outer
317
+ // generator yields SSE frames; publishRun's onProgress callback
318
+ // can't yield directly (different generator). Push events into
319
+ // this queue inside the callback; drain after publishRun resolves.
320
+ // Order preserved (publishRun runs items sequentially per target).
321
+ const progressQueue = [];
207
322
  try {
208
323
  let totalFiles = 0;
209
324
  const targetRoot = createContentRoot(targetStorage);
@@ -238,63 +353,92 @@ scanTemplatesInjected) {
238
353
  totalFiles += copiedFiles;
239
354
  current++;
240
355
  yield { kind: 'progress', target: targetName, current, total, label: 'source files' };
241
- // 2. Render items in bounded parallel. Progress events are yielded
242
- // in completion order the UI shows X/N + whatever finished last,
243
- // which stays meaningful without needing input-order. Preserves the
244
- // event contract: one 'progress' per item between 'target-start'
245
- // and 'target-result'.
246
- // Static-mode page hashes must include fragment hashes (a fragment
247
- // change invalidates every page that bakes it in). Matches the
248
- // combination used by compareTargets.
249
- const fragmentHashes = new Map();
250
- if (isStatic) {
251
- for (const [fragName, frag] of site.fragments) {
252
- fragmentHashes.set(fragName, hashManifest(frag, { templateHashes }));
253
- }
254
- }
255
- const pageHashOpts = isStatic ? { templateHashes, fragmentHashes } : { templateHashes };
256
- // SEO context for this target — built once, shared across all page renders.
257
- const seo = {
258
- siteName: site.manifest.name,
259
- siteUrl: config?.siteUrl,
260
- locale: site.manifest.locale,
261
- defaultOgImage: site.manifest.defaultOgImage,
262
- };
263
- const renderItem = async (item) => {
264
- if (item.startsWith('pages/')) {
265
- const raw = item.replace('pages/', '');
266
- // Support locale-qualified items: pages/home:fr → publish only FR
267
- const [pageName, itemLocale] = raw.includes(':') ? raw.split(':') : [raw, undefined];
268
- const page = site.pages.get(pageName);
269
- const manifestHash = page ? hashManifest(page, pageHashOpts) : undefined;
270
- if (isStatic) {
271
- return publishPageStatic(pageName, source.contentRoot, targetStorage, tdir, manifestHash, site, seo, itemLocale);
356
+ // Cutover (Cut 7 of publish-pipeline-extraction): asset publish +
357
+ // per-item render loop + dep indices + site manifest now go through
358
+ // `publishRun`. The route keeps history record (above), source-copy
359
+ // (publishItems above), sitemap/robots/redirects/purge (below) and
360
+ // the SSE progress emit. publishRun's onProgress feeds the SSE
361
+ // generator one progress event per item-done; admin's UI counts
362
+ // items toward `total`.
363
+ //
364
+ // Item-string layout (`pages/home:fr`) split into ItemRefs. Static
365
+ // targets emit only page items (fragments are baked); ESI emits
366
+ // both. Static-mode page hash composition (fragmentHashes) is
367
+ // handled inside publishRun when templateInfos is supplied.
368
+ const itemRefs = [];
369
+ for (const it of targetItems) {
370
+ if (it.startsWith('pages/')) {
371
+ const raw = it.replace('pages/', '');
372
+ const [name, locale] = raw.includes(':') ? raw.split(':') : [raw, undefined];
373
+ // Locale-qualified: just the requested variant. Else: default
374
+ // + every supported locale (subject to target.locales filter).
375
+ if (locale) {
376
+ itemRefs.push({ kind: 'page', name, locale });
377
+ }
378
+ else {
379
+ itemRefs.push({ kind: 'page', name });
380
+ const pageLocales = site.pageLocales.get(name);
381
+ if (pageLocales) {
382
+ for (const loc of pageLocales.locales.keys()) {
383
+ if (config?.locales && !config.locales.includes(loc))
384
+ continue;
385
+ itemRefs.push({ kind: 'page', name, locale: loc });
386
+ }
387
+ }
272
388
  }
273
- // When a specific locale is requested, only publish that one
274
- const onlyLocales = itemLocale ? [itemLocale] : undefined;
275
- const { files } = await publishPageAllLocales(pageName, source.contentRoot, targetStorage, site, pageHashOpts, { cache: config?.cache, templatesDir: tdir, seo, targetLocales: onlyLocales ?? config?.locales });
276
- return { files };
277
389
  }
278
- if (item.startsWith('fragments/') && !isStatic) {
279
- const raw = item.replace('fragments/', '');
280
- const [fragName, itemLocale] = raw.includes(':') ? raw.split(':') : [raw, undefined];
281
- const onlyLocales = itemLocale ? [itemLocale] : undefined;
282
- const { files } = await publishFragmentAllLocales(fragName, source.contentRoot, targetStorage, site, { templateHashes }, { templatesDir: tdir, targetLocales: onlyLocales ?? config?.locales });
283
- return { files };
390
+ else if (it.startsWith('fragments/') && !isStatic) {
391
+ const raw = it.replace('fragments/', '');
392
+ const [name, locale] = raw.includes(':') ? raw.split(':') : [raw, undefined];
393
+ if (locale) {
394
+ itemRefs.push({ kind: 'fragment', name, locale });
395
+ }
396
+ else {
397
+ itemRefs.push({ kind: 'fragment', name });
398
+ const fragLocales = site.fragmentLocales.get(name);
399
+ if (fragLocales) {
400
+ for (const loc of fragLocales.locales.keys()) {
401
+ if (config?.locales && !config.locales.includes(loc))
402
+ continue;
403
+ itemRefs.push({ kind: 'fragment', name, locale: loc });
404
+ }
405
+ }
406
+ }
284
407
  }
285
- return { files: 0 }; // skipped (e.g. fragment on static target)
286
- };
287
- // Render concurrency is lower than listing concurrency — each render
288
- // may do multiple writes, so 10 in flight is the safe default.
289
- for await (const { item, result } of mapLimitStream(targetItems, renderItem, 10)) {
290
- totalFiles += result.files;
291
- current++;
292
- yield { kind: 'progress', target: targetName, current, total, label: item };
293
408
  }
294
- // 3. Site manifest + fragment index
295
- await publishSiteManifest(source.contentRoot, targetStorage, site);
296
- await publishFragmentIndex(source.contentRoot, targetStorage, site);
297
- totalFiles += 2;
409
+ const { publishRun } = await import('../../publish-run.js');
410
+ const runResult = await publishRun({
411
+ items: itemRefs,
412
+ targets: [targetName],
413
+ site,
414
+ sourceRoot: source.contentRoot,
415
+ siteManifest: source.manifest ?? { name: '(publish)' },
416
+ targetStorages: new Map([[targetName, targetStorage]]),
417
+ templateInfos,
418
+ onProgress: ev => {
419
+ if (ev.kind === 'item-done') {
420
+ const label = (ev.result.kind === 'fragment' ? `@${ev.result.name}` : `pages/${ev.result.name}`) +
421
+ (ev.result.locale ? `:${ev.result.locale}` : '');
422
+ current++;
423
+ // SSE consumer reads per-item progress; admin UI updates X/N.
424
+ // Yield is bridged via the outer generator below.
425
+ progressQueue.push({ kind: 'progress', target: targetName, current, total, label });
426
+ }
427
+ },
428
+ });
429
+ // publishRun doesn't throw on per-target init failure (assets
430
+ // missing → target failed); surface as the same error the inline
431
+ // path used to throw so the per-target try/catch projects to
432
+ // `target-result success: false`.
433
+ const tr = runResult.targets.find(t => t.name === targetName);
434
+ if (tr?.failed) {
435
+ throw new Error(tr.failureReason ?? 'all items failed');
436
+ }
437
+ totalFiles += tr?.filesWritten ?? 0;
438
+ // Drain queued progress events from the publishRun callback.
439
+ for (const ev of progressQueue)
440
+ yield ev;
441
+ progressQueue.length = 0;
298
442
  current++;
299
443
  yield { kind: 'progress', target: targetName, current, total, label: 'site manifest' };
300
444
  // 3b. Sitemap + robots.txt
@@ -327,6 +471,34 @@ scanTemplatesInjected) {
327
471
  totalFiles++;
328
472
  }
329
473
  }
474
+ // 3c. Host-format redirects file (e.g. _redirects). Per
475
+ // design-soft-delete.md Q10: plain-static targets without a
476
+ // worker can't read the per-page HTML marker; this file is the
477
+ // host glue for archive-driven redirects. Independent of
478
+ // siteUrl — the format determines whether to emit at all.
479
+ const redirectsFormat = config?.redirects?.format;
480
+ if (redirectsFormat && redirectsFormat !== 'none') {
481
+ const { emitRedirects } = await import('../../runtime/redirects-emit.js');
482
+ const { allPageEntries, deriveRoute } = await import('../../site-loader.js');
483
+ const archives = [];
484
+ for (const entry of allPageEntries(site)) {
485
+ if (entry.page.archived !== true)
486
+ continue;
487
+ // Locale variants share the parent's archive state in v1
488
+ // (per design-soft-delete.md future directions). Default-
489
+ // locale row is the canonical entry.
490
+ if (entry.locale)
491
+ continue;
492
+ const from = deriveRoute(entry.name);
493
+ const to = entry.page.aliasOf ? deriveRoute(entry.page.aliasOf) : undefined;
494
+ archives.push(to !== undefined ? { from, to } : { from });
495
+ }
496
+ const result = emitRedirects(redirectsFormat, archives);
497
+ if (result && result.body !== '') {
498
+ await targetStorage.writeFile(result.filename, result.body);
499
+ totalFiles++;
500
+ }
501
+ }
330
502
  // 4. Purge CDN cache
331
503
  if (purgeConfig?.type === 'cloudflare') {
332
504
  const apiToken = resolveEnvVars(purgeConfig.apiToken);
@@ -362,6 +534,25 @@ scanTemplatesInjected) {
362
534
  const result = { target: targetName, success: true, copiedFiles: totalFiles };
363
535
  results.push(result);
364
536
  console.log(` ${targetName}: ${totalFiles} files`);
537
+ // Publish wrote new manifests to the target's storage. Any
538
+ // SourceContext for that target has a stale cached page /
539
+ // fragment summary. Resolve the target's SourceContext (if
540
+ // the resolver has built one) and invalidate. Cheap; covers
541
+ // the case where the admin UI's active target is the publish
542
+ // destination and the next /api/pages should reflect the
543
+ // newly-published items.
544
+ try {
545
+ const targetSource = await resolve(targetName);
546
+ await Promise.all([
547
+ targetSource.cache.invalidatePrefix('pages:'),
548
+ targetSource.cache.invalidatePrefix('fragments:'),
549
+ ]);
550
+ }
551
+ catch {
552
+ // Resolver may not know this target (registry not configured;
553
+ // legacy single-target setup). Cache invalidation is best-
554
+ // effort; ignore.
555
+ }
365
556
  yield { kind: 'target-result', result };
366
557
  }
367
558
  catch (err) {
@@ -374,11 +565,87 @@ scanTemplatesInjected) {
374
565
  }
375
566
  yield { kind: 'done', results };
376
567
  }
377
- app.post('/api/publish', async (c) => {
568
+ // Publish routes gate on `publish:non-production` as the baseline.
569
+ // Production-target gating runs inside the handler when iterating
570
+ // requested targets (per design-auth-rbac.md "Failure mode": publish
571
+ // to a production target requires `publish:production`). Cut 9
572
+ // ships the route-level gate; per-target enforcement lands when
573
+ // the route is rewritten to consult the resolved target's
574
+ // environment field.
575
+ app.post('/api/publish', requireCapability('publish:non-production'), async (c) => {
378
576
  const body = (await c.req.json());
577
+ // beforePublish hooks per design-hooks.md "Publish lifecycle".
578
+ // Hooks see the requested items + active target; can mutate
579
+ // the item set (drop / reorder / extend) or throw to cancel
580
+ // the operation. One dispatch per target — operators wanting
581
+ // per-target item filtering branch on `target` inside their
582
+ // handler.
583
+ const hookCtx = hooks
584
+ ? buildHookContext({
585
+ principal: c.var.principal,
586
+ storage: (await resolve(body.source)).storage,
587
+ requestId: c.req.header('x-request-id') ?? crypto.randomUUID(),
588
+ site: { name: undefined },
589
+ auditEmit: makeAuditFiringEmitter(c.var.audit),
590
+ })
591
+ : null;
592
+ let finalItems = body.items;
593
+ if (hooks && hookCtx) {
594
+ try {
595
+ const inputItems = body.items.map(toPublishItem);
596
+ // Dispatch once per target. Cancellation by any handler
597
+ // aborts the entire publish (multi-target).
598
+ let mutated = inputItems;
599
+ for (const target of body.targets) {
600
+ mutated = await dispatchBeforePublish(hooks, target, mutated, hookCtx);
601
+ }
602
+ finalItems = mutated.map(i => i.path);
603
+ }
604
+ catch (err) {
605
+ if (err instanceof HookCancellation || err instanceof HookTimeout) {
606
+ // Per design-hooks.md Q3 audit lock: cancelled publishes
607
+ // record outcome 'hook-cancelled' (not 'forbidden' — hook
608
+ // policy is operator decision, not a capability denial).
609
+ await c.var.audit.record({
610
+ action: 'publish',
611
+ outcome: 'hook-cancelled',
612
+ scope: { kind: 'site' },
613
+ metadata: {
614
+ items: body.items,
615
+ targets: body.targets,
616
+ source: body.source,
617
+ hookCancelled: err instanceof HookCancellation ? err.hookName : undefined,
618
+ hookTimeout: err instanceof HookTimeout ? err.hookName : undefined,
619
+ },
620
+ });
621
+ return c.json({ code: 'HOOK_CANCELLED', hook: err.hookName, reason: err.message }, 409);
622
+ }
623
+ throw err;
624
+ }
625
+ }
626
+ // Server-side publish gate per design-validation.md Cut 4. Runs the
627
+ // same `runPublishAudit` the client-side modal calls; refuses on
628
+ // remaining error-severity issues so a determined client can't
629
+ // bypass the dialog. `publishAudit.strict` is applied per-target.
630
+ const sourceForGate = await resolve(body.source);
631
+ const blocked = await evaluatePublishGate(sourceForGate, body.targets, finalItems);
632
+ if (blocked.length > 0) {
633
+ await c.var.audit.record({
634
+ action: 'publish',
635
+ outcome: 'validation-failed',
636
+ scope: { kind: 'site' },
637
+ metadata: {
638
+ items: finalItems,
639
+ targets: body.targets,
640
+ source: body.source,
641
+ blockedTargets: blocked.map(b => b.target),
642
+ },
643
+ });
644
+ return c.json({ code: 'PUBLISH_AUDIT_FAILED', blocked }, 409);
645
+ }
379
646
  let results = [];
380
647
  let fatal = null;
381
- for await (const ev of runPublish(body.items, body.targets, body.source)) {
648
+ for await (const ev of runPublish(finalItems, body.targets, body.source)) {
382
649
  if (ev.kind === 'fatal')
383
650
  fatal = ev;
384
651
  else if (ev.kind === 'done')
@@ -389,16 +656,115 @@ scanTemplatesInjected) {
389
656
  return c.json({ error: fatal.error, ...(fatal.invalidTemplates ? { invalidTemplates: fatal.invalidTemplates } : {}) }, status);
390
657
  }
391
658
  const allSuccess = results.every(r => r.success);
659
+ // Audit: one event per publish operation. metadata carries the
660
+ // requested items + targets for forensic queries; per-item
661
+ // events would explode volume on multi-item publishes.
662
+ await c.var.audit.record({
663
+ action: 'publish',
664
+ outcome: 'success',
665
+ scope: { kind: 'site' },
666
+ metadata: { items: finalItems, targets: body.targets, source: body.source },
667
+ });
668
+ // afterPublish hooks per design-hooks.md "Publish lifecycle"
669
+ // step 5. Observational; failures logged. One dispatch per
670
+ // target with that target's per-target result.
671
+ if (hooks && hookCtx) {
672
+ const finalPublishItems = finalItems.map(toPublishItem);
673
+ for (const r of results) {
674
+ const hookResult = {
675
+ target: r.target,
676
+ itemsPublished: r.success ? finalPublishItems : [],
677
+ itemsFailed: r.success ? [] : finalPublishItems.map(item => ({ item, reason: r.error ?? 'unknown' })),
678
+ };
679
+ await dispatchAfterPublish(hooks, r.target, hookResult, hookCtx);
680
+ }
681
+ }
392
682
  return c.json({ results }, allSuccess ? 200 : 207);
393
683
  });
394
- app.post('/api/publish/stream', async (c) => {
684
+ app.post('/api/publish/stream', requireCapability('publish:non-production'), async (c) => {
395
685
  const body = (await c.req.json());
686
+ // beforePublish hooks fire BEFORE the SSE stream opens — a
687
+ // cancellation surfaces as a 409 (synchronous) rather than as
688
+ // an SSE 'fatal' event, matching the sync /api/publish path.
689
+ const hookCtx = hooks
690
+ ? buildHookContext({
691
+ principal: c.var.principal,
692
+ storage: (await resolve(body.source)).storage,
693
+ requestId: c.req.header('x-request-id') ?? crypto.randomUUID(),
694
+ site: { name: undefined },
695
+ auditEmit: makeAuditFiringEmitter(c.var.audit),
696
+ })
697
+ : null;
698
+ let finalItems = body.items;
699
+ if (hooks && hookCtx) {
700
+ try {
701
+ let mutated = body.items.map(toPublishItem);
702
+ for (const target of body.targets) {
703
+ mutated = await dispatchBeforePublish(hooks, target, mutated, hookCtx);
704
+ }
705
+ finalItems = mutated.map(i => i.path);
706
+ }
707
+ catch (err) {
708
+ if (err instanceof HookCancellation || err instanceof HookTimeout) {
709
+ // Per design-hooks.md Q3 audit lock: cancelled publishes
710
+ // record outcome 'hook-cancelled' (not 'forbidden' — hook
711
+ // policy is operator decision, not a capability denial).
712
+ await c.var.audit.record({
713
+ action: 'publish',
714
+ outcome: 'hook-cancelled',
715
+ scope: { kind: 'site' },
716
+ metadata: {
717
+ items: body.items,
718
+ targets: body.targets,
719
+ source: body.source,
720
+ hookCancelled: err instanceof HookCancellation ? err.hookName : undefined,
721
+ hookTimeout: err instanceof HookTimeout ? err.hookName : undefined,
722
+ },
723
+ });
724
+ return c.json({ code: 'HOOK_CANCELLED', hook: err.hookName, reason: err.message }, 409);
725
+ }
726
+ throw err;
727
+ }
728
+ }
729
+ // Server-side publish gate (mirrors /api/publish). Surfaces as a
730
+ // synchronous 409 before the SSE stream opens, so the client can
731
+ // treat audit-failure identically across the two endpoints.
732
+ const sourceForGate = await resolve(body.source);
733
+ const blocked = await evaluatePublishGate(sourceForGate, body.targets, finalItems);
734
+ if (blocked.length > 0) {
735
+ await c.var.audit.record({
736
+ action: 'publish',
737
+ outcome: 'validation-failed',
738
+ scope: { kind: 'site' },
739
+ metadata: {
740
+ items: finalItems,
741
+ targets: body.targets,
742
+ source: body.source,
743
+ blockedTargets: blocked.map(b => b.target),
744
+ },
745
+ });
746
+ return c.json({ code: 'PUBLISH_AUDIT_FAILED', blocked }, 409);
747
+ }
396
748
  return streamSSE(c, async (stream) => {
749
+ let recordedSuccess = false;
750
+ const collectedResults = [];
397
751
  try {
398
- for await (const ev of runPublish(body.items, body.targets, body.source)) {
752
+ for await (const ev of runPublish(finalItems, body.targets, body.source)) {
399
753
  if (stream.aborted)
400
754
  return;
401
755
  await stream.writeSSE({ event: ev.kind, data: JSON.stringify(ev) });
756
+ if (ev.kind === 'done') {
757
+ // Record once per stream — same shape as the
758
+ // synchronous /api/publish endpoint.
759
+ await c.var.audit.record({
760
+ action: 'publish',
761
+ outcome: 'success',
762
+ scope: { kind: 'site' },
763
+ metadata: { items: finalItems, targets: body.targets, source: body.source },
764
+ });
765
+ recordedSuccess = true;
766
+ collectedResults.push(...ev.results);
767
+ }
402
768
  }
403
769
  }
404
770
  catch (err) {
@@ -409,9 +775,28 @@ scanTemplatesInjected) {
409
775
  });
410
776
  }
411
777
  }
778
+ // afterPublish hooks fire after the stream's `done` event —
779
+ // observational; failures logged via ctx.log without
780
+ // affecting the already-streamed response.
781
+ if (hooks && hookCtx && recordedSuccess) {
782
+ const finalPublishItems = finalItems.map(toPublishItem);
783
+ for (const r of collectedResults) {
784
+ const hookResult = {
785
+ target: r.target,
786
+ itemsPublished: r.success ? finalPublishItems : [],
787
+ itemsFailed: r.success ? [] : finalPublishItems.map(item => ({ item, reason: r.error ?? 'unknown' })),
788
+ };
789
+ await dispatchAfterPublish(hooks, r.target, hookResult, hookCtx);
790
+ }
791
+ }
792
+ // Avoid recording a duplicate when the loop completed without
793
+ // a 'done' event (rare — happens if runPublish yields fatal
794
+ // before done). Suppresses double-audit; the absence of a
795
+ // success event is itself the forensic signal.
796
+ void recordedSuccess;
412
797
  });
413
798
  });
414
- app.post('/api/fetch', async (c) => {
799
+ app.post('/api/fetch', requireCapability('publish:non-production'), async (c) => {
415
800
  // `source` (body) — target to fetch FROM (a published target)
416
801
  // `destination` (body) — optional editable target to write INTO; defaults
417
802
  // to the resolver's default editable target (the author's current source)
@@ -479,6 +864,70 @@ scanTemplatesInjected) {
479
864
  return c.json({ error }, 500);
480
865
  }
481
866
  });
867
+ /**
868
+ * POST /api/publish/audit — runs pre-publish-stage validators against the
869
+ * items operator is about to publish. Returns the consolidated `Issue[]`,
870
+ * with `publishAudit.strict` promotion already applied (warns → errors)
871
+ * for the destination target.
872
+ *
873
+ * The audit is read-only: it doesn't write to storage, doesn't fire hooks,
874
+ * doesn't trigger publish. It's the pre-flight check the publish dialog
875
+ * surfaces before the user clicks "Publish."
876
+ *
877
+ * Server-side enforcement of the audit happens at `POST /api/publish` —
878
+ * this endpoint is the read surface; the gate is the publish handler
879
+ * itself. Defense in depth: client-side dialog uses this endpoint for
880
+ * display; server-side publish re-runs the same audit and refuses on
881
+ * errors, so a determined client can't bypass.
882
+ */
883
+ app.post('/api/publish/audit', requireCapability('publish:non-production'), async (c) => {
884
+ const body = await c.req.json().catch(() => null);
885
+ if (!body || typeof body !== 'object') {
886
+ return c.json({ error: 'invalid request body' }, 400);
887
+ }
888
+ const targetName = body.target;
889
+ const items = body.items;
890
+ if (typeof targetName !== 'string' || !Array.isArray(items)) {
891
+ return c.json({ error: 'expected { target: string, items: SavedItem[] }' }, 400);
892
+ }
893
+ const source = await resolve(c.req.query('target'));
894
+ const site = await loadSiteFromSource(source);
895
+ const targetCfg = source.manifest?.targets?.[targetName];
896
+ const strict = !!targetCfg?.publishAudit?.strict;
897
+ if (!opts.validators) {
898
+ // No validator registry wired; return empty issues.
899
+ return c.json({ issues: [], strict });
900
+ }
901
+ const issues = await runPublishAudit({
902
+ items: items,
903
+ site,
904
+ contentRoot: source.contentRoot,
905
+ storage: source.storage,
906
+ registry: opts.validators,
907
+ cache: source.cache,
908
+ strict,
909
+ templatesDir: site.templatesDir,
910
+ });
911
+ // Capability-gap UX surface #4 (pre-publish gate) per
912
+ // `feature-design-process.md`'s capability-gap-UX discipline.
913
+ // When the publish set includes any archived items, surface the
914
+ // destination target's capability info so the publish dialog can
915
+ // warn operators (e.g., "this target won't emit 301 redirects").
916
+ const itemList = items;
917
+ const includesArchived = itemList.some(i => {
918
+ const m = i.kind === 'page' ? site.pages.get(i.name) : site.fragments.get(i.name);
919
+ return m?.archived === true;
920
+ });
921
+ let capabilities;
922
+ if (includesArchived && targetCfg) {
923
+ const inspection = inspectTarget(targetCfg);
924
+ capabilities = {
925
+ has: [...inspection.has],
926
+ gaps: inspection.gaps.map(g => ({ capability: g.capability, reason: g.reason })),
927
+ };
928
+ }
929
+ return c.json({ issues, strict, ...(capabilities ? { capabilities } : {}) });
930
+ });
482
931
  return app;
483
932
  }
484
933
  /**