@jini-ai/admin 0.4.2 → 0.4.4

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 (361) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +7 -0
  3. package/dist/agent-plugins/react/components/AgentPluginListPanel.d.ts +1 -1
  4. package/dist/agent-plugins/react/hooks/AgentPluginInspector.hooks.js +1 -1
  5. package/dist/agent-plugins/react/hooks/AgentPluginPanel.hooks.d.ts +1 -1
  6. package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.d.ts +1 -1
  7. package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.js +1 -1
  8. package/dist/agent-plugins/react/hooks/MarketplaceTab.hooks.d.ts +1 -1
  9. package/dist/agent-plugins/react/index.js +1 -1
  10. package/dist/agent-plugins/react/pages/AgentPluginsPage.d.ts +1 -1
  11. package/dist/agent-plugins/react/tabs/DownloadedTab.d.ts +1 -1
  12. package/dist/agent-plugins/react/tabs/InstalledTab.d.ts +1 -1
  13. package/dist/agent-plugins/react/tabs/MarketplaceTab.d.ts +1 -1
  14. package/dist/comments/adapters/http.d.ts +29 -0
  15. package/dist/comments/adapters/http.js +50 -0
  16. package/dist/comments/adapters/memory.d.ts +17 -0
  17. package/dist/comments/adapters/memory.js +61 -0
  18. package/dist/comments/comments.module.d.ts +73 -0
  19. package/dist/comments/comments.module.js +16 -0
  20. package/dist/comments/conformance/comments-api.conformance.d.ts +9 -0
  21. package/dist/comments/conformance/comments-api.conformance.js +63 -0
  22. package/dist/comments/controllers/comment-queue.controller.d.ts +48 -0
  23. package/dist/comments/controllers/comment-queue.controller.js +164 -0
  24. package/dist/comments/controllers/comment-settings.controller.d.ts +32 -0
  25. package/dist/comments/controllers/comment-settings.controller.js +77 -0
  26. package/dist/comments/controllers/comments.controller.d.ts +16 -0
  27. package/dist/comments/controllers/comments.controller.js +16 -0
  28. package/dist/comments/index.d.ts +13 -0
  29. package/dist/comments/index.js +8 -0
  30. package/dist/comments/messages.en.d.ts +54 -0
  31. package/dist/comments/messages.en.js +56 -0
  32. package/dist/comments/models.d.ts +22 -0
  33. package/dist/comments/models.js +2 -0
  34. package/dist/comments/ports.d.ts +14 -0
  35. package/dist/comments/ports.js +5 -0
  36. package/dist/comments/react/components/QueueSection.d.ts +30 -0
  37. package/dist/comments/react/components/QueueSection.js +57 -0
  38. package/dist/comments/react/components/SettingsSection.d.ts +14 -0
  39. package/dist/comments/react/components/SettingsSection.js +23 -0
  40. package/dist/comments/react/hooks/CommentsPage.hooks.d.ts +9 -0
  41. package/dist/comments/react/hooks/CommentsPage.hooks.js +10 -0
  42. package/dist/comments/react/hooks/CommentsPorts.hooks.d.ts +13 -0
  43. package/dist/comments/react/hooks/CommentsPorts.hooks.js +15 -0
  44. package/dist/comments/react/hooks/QueueSection.hooks.d.ts +62 -0
  45. package/dist/comments/react/hooks/QueueSection.hooks.js +57 -0
  46. package/dist/comments/react/hooks/SettingsSection.hooks.d.ts +12 -0
  47. package/dist/comments/react/hooks/SettingsSection.hooks.js +21 -0
  48. package/dist/comments/react/hooks/use-comment-queue.hooks.d.ts +34 -0
  49. package/dist/comments/react/hooks/use-comment-queue.hooks.js +47 -0
  50. package/dist/comments/react/hooks/use-comment-settings.hooks.d.ts +22 -0
  51. package/dist/comments/react/hooks/use-comment-settings.hooks.js +30 -0
  52. package/dist/comments/react/hooks/use-comments.hooks.d.ts +15 -0
  53. package/dist/comments/react/hooks/use-comments.hooks.js +20 -0
  54. package/dist/comments/react/index.d.ts +316 -0
  55. package/dist/comments/react/index.js +35 -0
  56. package/dist/comments/react/pages/CommentsPage.d.ts +12 -0
  57. package/dist/comments/react/pages/CommentsPage.js +15 -0
  58. package/dist/comments/rules.d.ts +140 -0
  59. package/dist/comments/rules.js +199 -0
  60. package/dist/core/index.d.ts +3 -1
  61. package/dist/core/index.js +1 -0
  62. package/dist/core/ledger-slice.d.ts +90 -0
  63. package/dist/core/ledger-slice.js +81 -0
  64. package/dist/core/ports/comments.d.ts +2 -0
  65. package/dist/core/ports/forms.d.ts +19 -7
  66. package/dist/core/ports/forms.js +4 -4
  67. package/dist/core/ports/index.d.ts +1 -1
  68. package/dist/core/ports/seo.d.ts +33 -6
  69. package/dist/core/react/bind-react.d.ts +46 -0
  70. package/dist/core/react/bind-react.js +28 -0
  71. package/dist/core/react/index.d.ts +3 -0
  72. package/dist/core/react/index.js +3 -0
  73. package/dist/core/react/use-controller.d.ts +16 -0
  74. package/dist/core/react/use-controller.js +18 -0
  75. package/dist/forms/adapters/http.d.ts +26 -0
  76. package/dist/forms/adapters/http.js +43 -0
  77. package/dist/forms/adapters/memory.d.ts +14 -0
  78. package/dist/forms/adapters/memory.js +77 -0
  79. package/dist/forms/conformance/forms-api.conformance.d.ts +17 -0
  80. package/dist/forms/conformance/forms-api.conformance.js +71 -0
  81. package/dist/forms/controllers/draft-store.d.ts +18 -0
  82. package/dist/forms/controllers/draft-store.js +17 -0
  83. package/dist/forms/controllers/field-attributes-dialog.controller.d.ts +37 -0
  84. package/dist/forms/controllers/field-attributes-dialog.controller.js +27 -0
  85. package/dist/forms/controllers/form-editor.controller.d.ts +36 -0
  86. package/dist/forms/controllers/form-editor.controller.js +22 -0
  87. package/dist/forms/controllers/form-fields-editor.controller.d.ts +20 -0
  88. package/dist/forms/controllers/form-fields-editor.controller.js +10 -0
  89. package/dist/forms/controllers/form-submission-detail.controller.d.ts +20 -0
  90. package/dist/forms/controllers/form-submission-detail.controller.js +10 -0
  91. package/dist/forms/controllers/form-submissions.controller.d.ts +25 -0
  92. package/dist/forms/controllers/form-submissions.controller.js +10 -0
  93. package/dist/forms/controllers/forms-list.controller.d.ts +22 -0
  94. package/dist/forms/controllers/forms-list.controller.js +10 -0
  95. package/dist/forms/forms.module.d.ts +138 -0
  96. package/dist/forms/forms.module.js +17 -0
  97. package/dist/forms/html-rules.d.ts +34 -0
  98. package/dist/forms/html-rules.js +34 -0
  99. package/dist/forms/index.d.ts +14 -0
  100. package/dist/forms/index.js +12 -0
  101. package/dist/forms/messages.en.d.ts +101 -0
  102. package/dist/forms/messages.en.js +105 -0
  103. package/dist/forms/models.d.ts +29 -0
  104. package/dist/forms/models.js +8 -0
  105. package/dist/forms/ports.d.ts +26 -0
  106. package/dist/forms/ports.js +6 -0
  107. package/dist/forms/react/components/FieldAttributesDialog.d.ts +14 -0
  108. package/dist/forms/react/components/FieldAttributesDialog.js +47 -0
  109. package/dist/forms/react/components/FormEditorFieldsBody.d.ts +28 -0
  110. package/dist/forms/react/components/FormEditorFieldsBody.js +24 -0
  111. package/dist/forms/react/components/FormEditorHeaderText.d.ts +7 -0
  112. package/dist/forms/react/components/FormEditorHeaderText.js +8 -0
  113. package/dist/forms/react/components/FormEditorMainPanel.d.ts +12 -0
  114. package/dist/forms/react/components/FormEditorMainPanel.js +13 -0
  115. package/dist/forms/react/components/FormEditorTabStrip.d.ts +13 -0
  116. package/dist/forms/react/components/FormEditorTabStrip.js +14 -0
  117. package/dist/forms/react/components/FormFieldsEditor.d.ts +13 -0
  118. package/dist/forms/react/components/FormFieldsEditor.js +39 -0
  119. package/dist/forms/react/components/FormSubmissionDate.d.ts +8 -0
  120. package/dist/forms/react/components/FormSubmissionDate.js +5 -0
  121. package/dist/forms/react/components/FormSubmissionDetail.d.ts +15 -0
  122. package/dist/forms/react/components/FormSubmissionDetail.js +30 -0
  123. package/dist/forms/react/components/FormSubmissions.d.ts +12 -0
  124. package/dist/forms/react/components/FormSubmissions.js +46 -0
  125. package/dist/forms/react/hooks/FormsPorts.hooks.d.ts +41 -0
  126. package/dist/forms/react/hooks/FormsPorts.hooks.js +16 -0
  127. package/dist/forms/react/hooks/forms-view.hooks.d.ts +117 -0
  128. package/dist/forms/react/hooks/forms-view.hooks.js +78 -0
  129. package/dist/forms/react/hooks/use-field-attributes-dialog.hooks.d.ts +31 -0
  130. package/dist/forms/react/hooks/use-field-attributes-dialog.hooks.js +22 -0
  131. package/dist/forms/react/hooks/use-form-editor.hooks.d.ts +118 -0
  132. package/dist/forms/react/hooks/use-form-editor.hooks.js +208 -0
  133. package/dist/forms/react/hooks/use-form-fields-editor.hooks.d.ts +34 -0
  134. package/dist/forms/react/hooks/use-form-fields-editor.hooks.js +36 -0
  135. package/dist/forms/react/hooks/use-form-submission-date.hooks.d.ts +12 -0
  136. package/dist/forms/react/hooks/use-form-submission-date.hooks.js +9 -0
  137. package/dist/forms/react/hooks/use-form-submission-detail.hooks.d.ts +68 -0
  138. package/dist/forms/react/hooks/use-form-submission-detail.hooks.js +81 -0
  139. package/dist/forms/react/hooks/use-form-submissions.hooks.d.ts +67 -0
  140. package/dist/forms/react/hooks/use-form-submissions.hooks.js +110 -0
  141. package/dist/forms/react/hooks/use-forms-list.hooks.d.ts +78 -0
  142. package/dist/forms/react/hooks/use-forms-list.hooks.js +103 -0
  143. package/dist/forms/react/index.d.ts +452 -0
  144. package/dist/forms/react/index.js +35 -0
  145. package/dist/forms/react/pages/FormEditor.d.ts +19 -0
  146. package/dist/forms/react/pages/FormEditor.js +40 -0
  147. package/dist/forms/react/pages/FormsList.d.ts +39 -0
  148. package/dist/forms/react/pages/FormsList.js +50 -0
  149. package/dist/forms/rules.d.ts +291 -0
  150. package/dist/forms/rules.js +338 -0
  151. package/dist/media/react/hooks/EditMediaPanel.hooks.js +1 -1
  152. package/dist/media/react/hooks/LibraryTab.hooks.d.ts +1 -1
  153. package/dist/media/react/hooks/LibraryTab.hooks.js +1 -1
  154. package/dist/media/react/hooks/MediaCard.hooks.js +6 -20
  155. package/dist/media/react/hooks/MediaGrid.hooks.d.ts +2 -2
  156. package/dist/media/react/hooks/MediaPage.hooks.d.ts +1 -1
  157. package/dist/media/react/hooks/MediaPage.hooks.js +1 -1
  158. package/dist/media/react/hooks/MediaPicker.hooks.js +1 -1
  159. package/dist/media/react/index.js +1 -1
  160. package/dist/media/react/tabs/LibraryTab.d.ts +1 -1
  161. package/dist/media/react/tabs/ProvidersTab.d.ts +1 -1
  162. package/dist/playground/react/components/Canvas.d.ts +1 -1
  163. package/dist/playground/react/hooks/Canvas.hooks.d.ts +1 -1
  164. package/dist/playground/react/hooks/Canvas.hooks.js +1 -1
  165. package/dist/playground/react/hooks/PlaygroundPage.hooks.d.ts +1 -1
  166. package/dist/playground/react/index.js +1 -1
  167. package/dist/playground/react/pages/PlaygroundPage.d.ts +1 -1
  168. package/dist/playground/react/tabs/CanvasTab.d.ts +1 -1
  169. package/dist/react/bind-react.d.ts +1 -45
  170. package/dist/react/bind-react.js +2 -27
  171. package/dist/react/components/ConfirmDialog/ConfirmDialog.d.ts +22 -5
  172. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts +2 -2
  173. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js +17 -55
  174. package/dist/react/components/ConfirmDialog/ConfirmDialog.js +33 -70
  175. package/dist/react/components/RowMenu/RowMenu.hooks.js +14 -3
  176. package/dist/react/use-controller.d.ts +1 -15
  177. package/dist/react/use-controller.js +2 -17
  178. package/dist/redirects/adapters/http.d.ts +20 -0
  179. package/dist/redirects/adapters/http.js +31 -0
  180. package/dist/redirects/adapters/memory.d.ts +13 -0
  181. package/dist/redirects/adapters/memory.js +83 -0
  182. package/dist/redirects/conformance/redirects-api.conformance.d.ts +12 -0
  183. package/dist/redirects/conformance/redirects-api.conformance.js +66 -0
  184. package/dist/redirects/controllers/hit-count.controller.d.ts +14 -0
  185. package/dist/redirects/controllers/hit-count.controller.js +10 -0
  186. package/dist/redirects/controllers/import-redirects.controller.d.ts +28 -0
  187. package/dist/redirects/controllers/import-redirects.controller.js +29 -0
  188. package/dist/redirects/controllers/redirects.controller.d.ts +37 -0
  189. package/dist/redirects/controllers/redirects.controller.js +38 -0
  190. package/dist/redirects/index.d.ts +11 -0
  191. package/dist/redirects/index.js +10 -0
  192. package/dist/redirects/messages.en.d.ts +58 -0
  193. package/dist/redirects/messages.en.js +60 -0
  194. package/dist/redirects/models.d.ts +14 -0
  195. package/dist/redirects/models.js +2 -0
  196. package/dist/redirects/ports.d.ts +9 -0
  197. package/dist/redirects/ports.js +4 -0
  198. package/dist/redirects/react/components/HitCountCell.d.ts +19 -0
  199. package/dist/redirects/react/components/HitCountCell.js +19 -0
  200. package/dist/redirects/react/components/ImportRedirectsForm.d.ts +17 -0
  201. package/dist/redirects/react/components/ImportRedirectsForm.js +12 -0
  202. package/dist/redirects/react/hooks/RedirectsOptions.hooks.d.ts +27 -0
  203. package/dist/redirects/react/hooks/RedirectsOptions.hooks.js +15 -0
  204. package/dist/redirects/react/hooks/RedirectsPage.hooks.d.ts +50 -0
  205. package/dist/redirects/react/hooks/RedirectsPage.hooks.js +30 -0
  206. package/dist/redirects/react/hooks/RedirectsPorts.hooks.d.ts +10 -0
  207. package/dist/redirects/react/hooks/RedirectsPorts.hooks.js +11 -0
  208. package/dist/redirects/react/hooks/use-hit-count-cell.hooks.d.ts +19 -0
  209. package/dist/redirects/react/hooks/use-hit-count-cell.hooks.js +15 -0
  210. package/dist/redirects/react/hooks/use-import-redirects-form.hooks.d.ts +21 -0
  211. package/dist/redirects/react/hooks/use-import-redirects-form.hooks.js +25 -0
  212. package/dist/redirects/react/hooks/use-redirects.hooks.d.ts +34 -0
  213. package/dist/redirects/react/hooks/use-redirects.hooks.js +63 -0
  214. package/dist/redirects/react/hooks/wired.hooks.d.ts +55 -0
  215. package/dist/redirects/react/hooks/wired.hooks.js +31 -0
  216. package/dist/redirects/react/index.d.ts +324 -0
  217. package/dist/redirects/react/index.js +28 -0
  218. package/dist/redirects/react/pages/RedirectsPage.d.ts +15 -0
  219. package/dist/redirects/react/pages/RedirectsPage.js +20 -0
  220. package/dist/redirects/redirects.module.d.ts +77 -0
  221. package/dist/redirects/redirects.module.js +13 -0
  222. package/dist/redirects/rules.d.ts +131 -0
  223. package/dist/redirects/rules.js +134 -0
  224. package/dist/security/react/hooks/AccessTokensTab.hooks.d.ts +1 -1
  225. package/dist/security/react/hooks/AccessTokensTab.hooks.js +1 -1
  226. package/dist/security/react/hooks/RootKeyTab.hooks.d.ts +1 -1
  227. package/dist/security/react/hooks/RootKeyTab.hooks.js +1 -1
  228. package/dist/security/react/hooks/SecurityPage.hooks.d.ts +1 -1
  229. package/dist/security/react/index.js +1 -1
  230. package/dist/security/react/pages/SecurityPage.d.ts +1 -1
  231. package/dist/security/react/tabs/AccessTokensTab.d.ts +1 -1
  232. package/dist/security/react/tabs/RootKeyTab.d.ts +1 -1
  233. package/dist/seo/adapters/http.d.ts +31 -0
  234. package/dist/seo/adapters/http.js +37 -0
  235. package/dist/seo/adapters/memory.d.ts +28 -0
  236. package/dist/seo/adapters/memory.js +129 -0
  237. package/dist/seo/conformance/seo-api.conformance.d.ts +8 -0
  238. package/dist/seo/conformance/seo-api.conformance.js +44 -0
  239. package/dist/seo/controllers/entry-picker.controller.d.ts +21 -0
  240. package/dist/seo/controllers/entry-picker.controller.js +17 -0
  241. package/dist/seo/controllers/entry-section.controller.d.ts +20 -0
  242. package/dist/seo/controllers/entry-section.controller.js +7 -0
  243. package/dist/seo/controllers/media-ref.controller.d.ts +26 -0
  244. package/dist/seo/controllers/media-ref.controller.js +14 -0
  245. package/dist/seo/controllers/seo-entry.controller.d.ts +31 -0
  246. package/dist/seo/controllers/seo-entry.controller.js +52 -0
  247. package/dist/seo/controllers/seo.controller.d.ts +29 -0
  248. package/dist/seo/controllers/seo.controller.js +50 -0
  249. package/dist/seo/controllers/sitemap.controller.d.ts +25 -0
  250. package/dist/seo/controllers/sitemap.controller.js +27 -0
  251. package/dist/seo/index.d.ts +14 -0
  252. package/dist/seo/index.js +12 -0
  253. package/dist/seo/messages.en.d.ts +79 -0
  254. package/dist/seo/messages.en.js +79 -0
  255. package/dist/seo/models.d.ts +179 -0
  256. package/dist/seo/models.js +8 -0
  257. package/dist/seo/ports.d.ts +11 -0
  258. package/dist/seo/ports.js +4 -0
  259. package/dist/seo/react/components/MediaPickerBridge.d.ts +4 -0
  260. package/dist/seo/react/components/MediaPickerBridge.js +8 -0
  261. package/dist/seo/react/components/MediaRefField.d.ts +40 -0
  262. package/dist/seo/react/components/MediaRefField.js +12 -0
  263. package/dist/seo/react/components/SeoIcons.d.ts +13 -0
  264. package/dist/seo/react/components/SeoIcons.js +32 -0
  265. package/dist/seo/react/components/SitemapModal.d.ts +48 -0
  266. package/dist/seo/react/components/SitemapModal.js +72 -0
  267. package/dist/seo/react/hooks/MediaPickerBridge.hooks.d.ts +6 -0
  268. package/dist/seo/react/hooks/MediaPickerBridge.hooks.js +27 -0
  269. package/dist/seo/react/hooks/MediaRefField.hooks.d.ts +25 -0
  270. package/dist/seo/react/hooks/MediaRefField.hooks.js +30 -0
  271. package/dist/seo/react/hooks/SeoModuleTabs.d.ts +14 -0
  272. package/dist/seo/react/hooks/SeoModuleTabs.js +18 -0
  273. package/dist/seo/react/hooks/SeoPage.hooks.d.ts +69 -0
  274. package/dist/seo/react/hooks/SeoPage.hooks.js +37 -0
  275. package/dist/seo/react/hooks/SeoPorts.hooks.d.ts +19 -0
  276. package/dist/seo/react/hooks/SeoPorts.hooks.js +22 -0
  277. package/dist/seo/react/hooks/SitemapModal.hooks.d.ts +26 -0
  278. package/dist/seo/react/hooks/SitemapModal.hooks.js +20 -0
  279. package/dist/seo/react/hooks/use-entry-picker.hooks.d.ts +11 -0
  280. package/dist/seo/react/hooks/use-entry-picker.hooks.js +20 -0
  281. package/dist/seo/react/hooks/use-seo-entry-panel.hooks.d.ts +14 -0
  282. package/dist/seo/react/hooks/use-seo-entry-panel.hooks.js +26 -0
  283. package/dist/seo/react/hooks/use-seo-entry-section.hooks.d.ts +4 -0
  284. package/dist/seo/react/hooks/use-seo-entry-section.hooks.js +7 -0
  285. package/dist/seo/react/hooks/use-seo.hooks.d.ts +11 -0
  286. package/dist/seo/react/hooks/use-seo.hooks.js +29 -0
  287. package/dist/seo/react/hooks/use-sitemap-modal.hooks.d.ts +10 -0
  288. package/dist/seo/react/hooks/use-sitemap-modal.hooks.js +18 -0
  289. package/dist/seo/react/index.d.ts +369 -0
  290. package/dist/seo/react/index.js +30 -0
  291. package/dist/seo/react/options.d.ts +26 -0
  292. package/dist/seo/react/options.js +2 -0
  293. package/dist/seo/react/pages/SeoPage.d.ts +161 -0
  294. package/dist/seo/react/pages/SeoPage.js +215 -0
  295. package/dist/seo/rules.d.ts +142 -0
  296. package/dist/seo/rules.js +220 -0
  297. package/dist/seo/seo.module.d.ts +115 -0
  298. package/dist/seo/seo.module.js +14 -0
  299. package/dist/source-control/react/hooks/ProvidersTab.hooks.d.ts +1 -1
  300. package/dist/source-control/react/hooks/ProvidersTab.hooks.js +1 -1
  301. package/dist/source-control/react/hooks/SourceControlPage.hooks.d.ts +1 -1
  302. package/dist/source-control/react/index.js +1 -1
  303. package/dist/source-control/react/pages/SourceControlPage.d.ts +1 -1
  304. package/dist/source-control/react/tabs/ProvidersTab.d.ts +1 -1
  305. package/dist/widgets/adapters/http.d.ts +19 -0
  306. package/dist/widgets/adapters/http.js +33 -0
  307. package/dist/widgets/adapters/memory.d.ts +22 -0
  308. package/dist/widgets/adapters/memory.js +93 -0
  309. package/dist/widgets/conformance/widgets-api.conformance.d.ts +6 -0
  310. package/dist/widgets/conformance/widgets-api.conformance.js +55 -0
  311. package/dist/widgets/controllers/instance-editor.controller.d.ts +49 -0
  312. package/dist/widgets/controllers/instance-editor.controller.js +87 -0
  313. package/dist/widgets/controllers/library.controller.d.ts +33 -0
  314. package/dist/widgets/controllers/library.controller.js +53 -0
  315. package/dist/widgets/controllers/region-editor.controller.d.ts +42 -0
  316. package/dist/widgets/controllers/region-editor.controller.js +69 -0
  317. package/dist/widgets/controllers/regions.controller.d.ts +27 -0
  318. package/dist/widgets/controllers/regions.controller.js +44 -0
  319. package/dist/widgets/index.d.ts +11 -0
  320. package/dist/widgets/index.js +9 -0
  321. package/dist/widgets/messages.en.d.ts +78 -0
  322. package/dist/widgets/messages.en.js +83 -0
  323. package/dist/widgets/models.d.ts +62 -0
  324. package/dist/widgets/models.js +2 -0
  325. package/dist/widgets/ports.d.ts +79 -0
  326. package/dist/widgets/ports.js +5 -0
  327. package/dist/widgets/react/components/WidgetInstanceNotices.d.ts +14 -0
  328. package/dist/widgets/react/components/WidgetInstanceNotices.js +25 -0
  329. package/dist/widgets/react/components/WidgetRegionEditorHeaderActions.d.ts +22 -0
  330. package/dist/widgets/react/components/WidgetRegionEditorHeaderActions.js +18 -0
  331. package/dist/widgets/react/components/WidgetsLibraryNotices.d.ts +13 -0
  332. package/dist/widgets/react/components/WidgetsLibraryNotices.js +10 -0
  333. package/dist/widgets/react/hooks/WidgetsPorts.hooks.d.ts +270 -0
  334. package/dist/widgets/react/hooks/WidgetsPorts.hooks.js +17 -0
  335. package/dist/widgets/react/hooks/navigation.hooks.d.ts +9 -0
  336. package/dist/widgets/react/hooks/navigation.hooks.js +6 -0
  337. package/dist/widgets/react/hooks/page-views.hooks.d.ts +87 -0
  338. package/dist/widgets/react/hooks/page-views.hooks.js +30 -0
  339. package/dist/widgets/react/hooks/use-widget-instance-editor.hooks.d.ts +56 -0
  340. package/dist/widgets/react/hooks/use-widget-instance-editor.hooks.js +38 -0
  341. package/dist/widgets/react/hooks/use-widget-region-editor.hooks.d.ts +32 -0
  342. package/dist/widgets/react/hooks/use-widget-region-editor.hooks.js +22 -0
  343. package/dist/widgets/react/hooks/use-widget-regions.hooks.d.ts +23 -0
  344. package/dist/widgets/react/hooks/use-widget-regions.hooks.js +22 -0
  345. package/dist/widgets/react/hooks/use-widgets-library.hooks.d.ts +37 -0
  346. package/dist/widgets/react/hooks/use-widgets-library.hooks.js +23 -0
  347. package/dist/widgets/react/index.d.ts +391 -0
  348. package/dist/widgets/react/index.js +31 -0
  349. package/dist/widgets/react/pages/WidgetInstanceEditor.d.ts +23 -0
  350. package/dist/widgets/react/pages/WidgetInstanceEditor.js +37 -0
  351. package/dist/widgets/react/pages/WidgetRegionEditor.d.ts +22 -0
  352. package/dist/widgets/react/pages/WidgetRegionEditor.js +25 -0
  353. package/dist/widgets/react/pages/WidgetRegions.d.ts +21 -0
  354. package/dist/widgets/react/pages/WidgetRegions.js +31 -0
  355. package/dist/widgets/react/pages/WidgetsLibrary.d.ts +24 -0
  356. package/dist/widgets/react/pages/WidgetsLibrary.js +61 -0
  357. package/dist/widgets/rules.d.ts +94 -0
  358. package/dist/widgets/rules.js +83 -0
  359. package/dist/widgets/widgets.module.d.ts +122 -0
  360. package/dist/widgets/widgets.module.js +21 -0
  361. package/package.json +206 -9
@@ -0,0 +1,199 @@
1
+ import { describeApiError } from '../core/transport/errors.js';
2
+ import { hasPermission } from '../core/permissions/rules.js';
3
+ import { englishComments } from './messages.en.js';
4
+ /** Host transports retain their error class; status/body are the shared wire contract. */
5
+ function isCommentsConflict({ e }) {
6
+ return e instanceof Error && 'status' in e && e.status === 409;
7
+ }
8
+ /**
9
+ * @file Pure logic for the `comments` feature — everything that computes a value rather than
10
+ * rendering one. Follows the `posts/rules.ts` convention: no React import, no hooks, directly
11
+ * testable.
12
+ *
13
+ * Moved here from `react/pages/CommentsPage.tsx`: `RowActionState`/`emptyRowState` and `describeModerationError`/
14
+ * `truncate` (already module-scope free functions in the original, just not exported), the
15
+ * moderation-queue row-menu item builder (a permission-and-status branch per action), and the
16
+ * Comments-settings patch builder plus its validation (REQ-08/09/10).
17
+ *
18
+ * `KEYS` (fetch-query migration, 2026-08-12): three independent resources this feature's three
19
+ * hooks each own — the operator's own effective permissions, the moderation queue (one cache
20
+ * identity PER status filter, `queue(status)`), and the settings form. `queueRoot` is the
21
+ * INVALIDATION target for a moderation action succeeding, not a read key of its own: a moderate/
22
+ * purge action always moves a comment to a DIFFERENT status than the one currently filtered, so the
23
+ * pre-migration `reloadFirstPage()` only ever refreshed the CURRENT filter's page — leaving a
24
+ * previously-visited OTHER status tab's cache stale (missing the comment) until the operator
25
+ * happened to force a reload. Invalidating the shared `["comments","queue"]` prefix instead
26
+ * refreshes every status tab's cache at once (matching by prefix — see `@jini-ai/ui/fetch-query`'s
27
+ * `QueryKey` doc), closing that gap; see `react/hooks/use-comment-queue.hooks.ts`'s own doc comment.
28
+ */
29
+ export const KEYS = {
30
+ permissions: ["comments", "permissions"],
31
+ queueRoot: ["comments", "queue"],
32
+ queue: (status) => ["comments", "queue", status],
33
+ settings: ["comments", "settings"],
34
+ };
35
+ /** The moderation queue's name on `lib/content-refresh-bus.ts` — see `taxonomy/rules.ts`'s
36
+ * `TAXONOMY_RESOURCE` for why this is a plain colocated constant rather than a shared registry.
37
+ * Agent-writable via `comments_approve_comment`/`comments_mark_comment_spam`/
38
+ * `comments_trash_comment`/`comments_restore_comment` (`apps/website/src/features/comments/
39
+ * agent-tools.ts`), all of which move a comment between statuses this queue lists.
40
+ *
41
+ * There is deliberately NO sibling `COMMENTS_SETTINGS_RESOURCE`: `react/hooks/use-comment-settings.hooks.ts`'s
42
+ * own header records a real, already-fixed lost-update bug (TM-TOVU-2026-08-12-A) whose fix is a
43
+ * ONE-SHOT seed guard that refuses to re-seed `settings` from any later successful load, including
44
+ * this bus's own out-of-band notification. Wiring that hook to the bus would either do nothing
45
+ * (the guard blocks it) or, if the guard were bypassed instead, reintroduce the exact silent
46
+ * revert the guard exists to prevent — so `comments_update_settings` stays unwired to this bus on
47
+ * purpose. See that hook's own file header for the full incident record. */
48
+ export const COMMENTS_QUEUE_RESOURCE = "comments-queue";
49
+ export function emptyRowState(_required = {}, _optional = {}) {
50
+ return { busy: false, error: null };
51
+ }
52
+ /** REQ-07: a 409 (stale `expectedVersion`) gets its own message instead of the generic fallback,
53
+ * using the route's own `{error, currentVersion}` body when present. */
54
+ export function describeModerationError({ e }, { t = englishComments } = {}) {
55
+ if (isCommentsConflict({ e })) {
56
+ const currentVersion = typeof e.body?.currentVersion === "number" ? e.body.currentVersion : undefined;
57
+ if (currentVersion !== undefined) {
58
+ return t("This comment changed since you loaded it (current version {currentVersion}) — refresh and try again.").replace("{currentVersion}", String(currentVersion));
59
+ }
60
+ return t("This comment changed since you loaded it — refresh and try again.");
61
+ }
62
+ return describeApiError({ e, fallback: t("Failed to update comment.") });
63
+ }
64
+ export function truncate({ text, max }, _optional = {}) {
65
+ return text.length > max ? `${text.slice(0, max)}…` : text;
66
+ }
67
+ function approveItem(comment, perms, handlers, t) {
68
+ if (comment.status === "approved" || !perms.canModerate)
69
+ return null;
70
+ return { key: "approve", label: t("Approve"), onSelect: () => handlers.onModerate(comment, "approve") };
71
+ }
72
+ function spamItem(comment, perms, handlers, t) {
73
+ if (comment.status === "spam" || !perms.canModerate)
74
+ return null;
75
+ return { key: "spam", label: t("Spam"), onSelect: () => handlers.onModerate(comment, "spam") };
76
+ }
77
+ function trashItem(comment, perms, handlers, t) {
78
+ if (comment.status === "trash" || !perms.canDelete)
79
+ return null;
80
+ return { key: "trash", label: t("Trash"), onSelect: () => handlers.onModerate(comment, "trash") };
81
+ }
82
+ function restoreItem(comment, perms, handlers, t) {
83
+ const isRestorable = comment.status === "spam" || comment.status === "trash";
84
+ if (!isRestorable || !perms.canModerate)
85
+ return null;
86
+ return { key: "restore", label: t("Restore"), onSelect: () => handlers.onModerate(comment, "restore") };
87
+ }
88
+ /** REQ-06: purge only ever surfaces from the trash filter view (`currentFilterStatus === "trash"`),
89
+ * not merely a trashed comment reached under a different filter. Genuinely destructive (its own
90
+ * confirm copy: "cannot be undone") — `destructive: true`, unlike the reversible actions above. */
91
+ function purgeItem(comment, currentFilterStatus, perms, handlers, t) {
92
+ const inTrashFilter = currentFilterStatus === "trash" && comment.status === "trash";
93
+ if (!inTrashFilter || !perms.canForceDelete)
94
+ return null;
95
+ return { key: "purge", label: t("Purge"), destructive: true, onSelect: () => handlers.onRequestPurge(comment) };
96
+ }
97
+ /** At-rest row actions for `RowMenu` — every condition here is copied verbatim from the inline
98
+ * buttons this replaces, so a permission/status combination that used to hide a button still
99
+ * omits the matching menu item rather than rendering a guaranteed-failing click. Each candidate
100
+ * item is its own single-condition pure function above; this just resolves permissions once and
101
+ * filters out the misses.
102
+ *
103
+ * @complexity Time: O(p) for three permission scans, p = effective grant count; output space is
104
+ * constant, with at most five menu entries. Permission ownership stays in the core helper.
105
+ */
106
+ export function commentRowMenuItems({ comment, context, handlers }, { t = englishComments } = {}) {
107
+ const perms = {
108
+ canModerate: hasPermission({ permissions: context.permissions, permission: "comments.moderate" }),
109
+ canDelete: hasPermission({ permissions: context.permissions, permission: "comments.delete" }),
110
+ canForceDelete: hasPermission({ permissions: context.permissions, permission: "comments.delete.force" }),
111
+ };
112
+ const candidates = [
113
+ approveItem(comment, perms, handlers, t),
114
+ spamItem(comment, perms, handlers, t),
115
+ trashItem(comment, perms, handlers, t),
116
+ restoreItem(comment, perms, handlers, t),
117
+ purgeItem(comment, context.currentFilterStatus, perms, handlers, t),
118
+ ];
119
+ return candidates.filter((item) => item !== null);
120
+ }
121
+ /** A blank or non-numeric raw value means "no opinion" — the field is left out of the patch
122
+ * rather than coerced to `0`/`NaN`. Shared by every numeric settings field except
123
+ * `closeAfterDays`, whose blank case means something else (see {@link parseCloseAfterDays}). */
124
+ export function parseOptionalNumber({ raw }, _optional = {}) {
125
+ if (raw === "")
126
+ return undefined;
127
+ const value = Number(raw);
128
+ return Number.isFinite(value) ? value : undefined;
129
+ }
130
+ /** REQ-10: blank means "never closes" -> `null` on the wire; the UI never sends the backend's own
131
+ * `-1` sentinel, only `null` or a positive number. A non-numeric raw value is "no opinion"
132
+ * (`undefined`), same as the other numeric fields. */
133
+ export function parseCloseAfterDays({ raw }, _optional = {}) {
134
+ const trimmed = raw.trim();
135
+ if (trimmed === "")
136
+ return null;
137
+ const value = Number(trimmed);
138
+ return Number.isFinite(value) ? value : undefined;
139
+ }
140
+ function diffCheckboxField(form, key, current) {
141
+ const value = form.get(key) === "on";
142
+ return value !== current[key] ? { [key]: value } : undefined;
143
+ }
144
+ function diffNumberField(form, key, current) {
145
+ const value = parseOptionalNumber({ raw: String(form.get(key) ?? "") });
146
+ return value !== undefined && value !== current[key] ? { [key]: value } : undefined;
147
+ }
148
+ function diffCloseAfterDaysField(form, current) {
149
+ const closeAfterDays = parseCloseAfterDays({ raw: String(form.get("closeAfterDays") ?? "") });
150
+ return closeAfterDays !== undefined && closeAfterDays !== current.closeAfterDays ? { closeAfterDays } : undefined;
151
+ }
152
+ /** REQ-08/09/10: builds a partial patch containing only the fields the operator actually changed
153
+ * (the backend's `setCommentsSettings` is a partial-patch contract — REQ-08 asks the client to
154
+ * mirror that instead of always sending the full object, as `Seo.tsx`'s form does). Each field's
155
+ * diff logic is a standalone pure helper above so it can be tested (and reasoned about) on its
156
+ * own; this function is just the merge. */
157
+ export function buildSettingsPatch(required, _optional = {}) {
158
+ const { form, current } = required;
159
+ return {
160
+ ...diffCheckboxField(form, "enabled", current),
161
+ ...diffCheckboxField(form, "requireModeration", current),
162
+ ...diffNumberField(form, "maxDepth", current),
163
+ ...diffCloseAfterDaysField(form, current),
164
+ ...diffNumberField(form, "spamAutoRejectScore", current),
165
+ ...diffNumberField(form, "maxPerIpPerHour", current),
166
+ };
167
+ }
168
+ /** REQ-09: client-side validates `spamAutoRejectScore` before the network call — mirrors the
169
+ * backend's own `validateCommentsSettingsPatch` bound (`src/comments/settings.ts`). Returns the
170
+ * error message to show, or `null` when the patch is valid. Split out of `save`'s body (originally
171
+ * an inline `if`) because it is the one piece of that flow that computes a value rather than
172
+ * performing an effect. */
173
+ export function validateSettingsPatch({ patch }, { t = englishComments } = {}) {
174
+ if (patch.spamAutoRejectScore !== undefined && (patch.spamAutoRejectScore < 0 || patch.spamAutoRejectScore > 1)) {
175
+ return t("Spam auto-reject score must be between 0 and 1.");
176
+ }
177
+ return null;
178
+ }
179
+ /**
180
+ * `useCommentSettings`'s error banner, extracted out of that hook (`refactor/fetch-query`
181
+ * complexity pass, 2026-08-12 — same reason `redirects/rules.ts`'s `visibleRedirectsError` was
182
+ * extracted). Precedence, highest first: a client-side validation failure (the operator hasn't even
183
+ * submitted a valid patch yet — a stale write/list error underneath it would be a confusing second
184
+ * message), then the save write's own failure, then — only before `settings` has ever loaded — the
185
+ * list-read failure, matching every other migrated feature's "a later background failure must not
186
+ * blank an already-rendered screen" guard.
187
+ *
188
+ * @complexity Time/space: O(1) — four fixed checks, no iteration.
189
+ */
190
+ export function visibleCommentSettingsError(params, _optional = {}) {
191
+ if (params.validationError)
192
+ return params.validationError;
193
+ if (params.saveError)
194
+ return describeApiError({ e: params.saveError, fallback: params.saveFallback });
195
+ if (params.hasSettings)
196
+ return null;
197
+ return params.listError ? describeApiError({ e: params.listError, fallback: params.listFallback }) : null;
198
+ }
199
+ //# sourceMappingURL=rules.js.map
@@ -17,9 +17,11 @@ export type { AdminClient, AdminRouteGroupFactory, AdminTransport, AdminFetch, H
17
17
  export type { GatedConfirmResult, GatedOperation, GatedPlanResult } from './gated/types.js';
18
18
  export type { DataTableSortDirection, DataTableSortState } from './data-table/types.js';
19
19
  export type { AdminAnalyticsHit, AdminAnalyticsPort, AdminAuthPort, AdminAuthUser, AdminComment, AdminCommentsPort, AdminCommentsQueuePage, AdminDatabasePort, AdminDegradedBanner, AdminDisclosureResult, AdminExtensionEnabledResult, AdminExtensionsPort, AdminIdentityPort, AdminIdentityUser, AdminIntegrationDelivery, AdminIntegrationDeliverySummary, AdminIntegrationSubscription, AdminIntegrationsPort, AdminLedgerRow, AdminMedia, AdminMediaPort, AdminMember, AdminMembersPort, AdminPlugin, AdminPolicy, AdminRecoveryDeepLinkResult, AdminRecoveryPort, AdminRecoveryStatus, AdminRestorePoint, AdminRestorePointSummary, AdminRole, AdminSettingsPort, AdminWorkspace, AdminWorkspacePort, CategoryCount, CommentModerationAction, CommentsSettings, CommentStatus, DatabaseContextEnvelope, DegradedBannerActionKind, DegradedBannerKind, MigrateForwardResult, RestoreConfirmInput, RestoreExecuteInput, RestoreExecuteResult, RestorePointCostClass, SettingResolvedValue, SettingResetResponse, SettingScope, SettingValueResponse, } from './ports/index.js';
20
- export type { AdminAssignMenuLocationResult, AdminDeleteMenuResult, AdminFormCreateInput, AdminFormDefinition, AdminFormField, AdminFormNotifyConfig, AdminFormsPort, AdminFormSubmission, AdminFormSubmissionPage, AdminFormUpdatePatch, AdminMenu, AdminMenuBinding, AdminMenuCreateInput, AdminMenuCustomTarget, AdminMenuEntryTarget, AdminMenuItem, AdminMenuItemAttrs, AdminMenuRouteTarget, AdminMenusPort, AdminMenuTarget, AdminMenuTermTarget, AdminMenuUpdateTreeInput, AdminMenuUrlTarget, AdminRedirect, AdminRedirectCreateInput, AdminRedirectHitStats, AdminRedirectImportFailure, AdminRedirectImportResult, AdminRedirectListFilter, AdminRedirectsPort, AdminRedirectUpdatePatch, AdminSeoAnalysis, AdminSeoIssue, AdminSeoMeta, AdminSeoOpenGraph, AdminSeoOverrides, AdminSeoPort, AdminSeoRobotsDirective, AdminSeoRobotsRule, AdminSeoSettings, AdminSeoTwitterCard, FormDefinitionStatus, FormFieldType, MenuStatus, NavTargetKind, RedirectMatchType, RedirectSource, RedirectStatus, RedirectStatusCode, SeoIssueSeverity, SeoOpenGraphType, SeoTwitterCardKind, } from './ports/index.js';
20
+ export type { AdminAssignMenuLocationResult, AdminDeleteMenuResult, AdminFormCreateInput, AdminFormDefinition, AdminFormField, AdminFormNotifyConfig, AdminFormsPort, AdminFormSubmission, AdminFormSubmissionPage, AdminFormUpdatePatch, AdminMenu, AdminMenuBinding, AdminMenuCreateInput, AdminMenuCustomTarget, AdminMenuEntryTarget, AdminMenuItem, AdminMenuItemAttrs, AdminMenuRouteTarget, AdminMenusPort, AdminMenuTarget, AdminMenuTermTarget, AdminMenuUpdateTreeInput, AdminMenuUrlTarget, AdminRedirect, AdminRedirectCreateInput, AdminRedirectHitStats, AdminRedirectImportFailure, AdminRedirectImportResult, AdminRedirectListFilter, AdminRedirectsPort, AdminRedirectUpdatePatch, AdminSeoAnalysis, AdminSeoEntryChoice, AdminSeoIssue, AdminSeoMeta, AdminSeoOpenGraph, AdminSeoOverrides, AdminSeoOverridesPatch, AdminSeoPort, AdminSeoRobotsDirective, AdminSeoRobotsRule, AdminSeoSettings, AdminSeoSettingsPatch, AdminSeoTwitterCard, FormDefinitionStatus, FormFieldType, MenuStatus, NavTargetKind, RedirectMatchType, RedirectSource, RedirectStatus, RedirectStatusCode, SeoIssueSeverity, SeoOpenGraphType, SeoTwitterCardKind, } from './ports/index.js';
21
21
  export type { AdminEntityDescriptor, AdminEntityField, AdminEntityFieldKind, AdminEntityFilter, AdminEntityJsonField, AdminEntityListQuery, AdminEntityPage, AdminEntityPort, AdminEntityRegistry, AdminEntityRelationField, AdminEntityRow, AdminEntityRowData, AdminEntityScalarField, AdminErasedEntityPort, } from './ports/index.js';
22
22
  export { createAdminEntityRegistry, describeAdminEntityFieldMismatch, eraseEntityPort, getErasedEntityPort, listErasedEntityPorts, } from './entities/rules.js';
23
23
  export type { AdminEntityErasureOptions, AdminEntityRowViolation } from './entities/rules.js';
24
24
  export type { AdminShellContext, AdminShellNavigationPort, AdminShellSession, AdminShellSessionPort } from './ports/shell.js';
25
+ export { loadNamespaceValues, saveChangedEntries, readString, readBoolean, readNumber } from './ledger-slice.js';
26
+ export type { LedgerEntry, LedgerCandidate } from './ledger-slice.js';
25
27
  //# sourceMappingURL=index.d.ts.map
@@ -13,4 +13,5 @@ export { hasPermission } from './permissions/rules.js';
13
13
  // Transport — the seam every route group is built on.
14
14
  export { AdminApiError, createAdminClient, createHttpTransport, describeApiError, } from './transport/index.js';
15
15
  export { createAdminEntityRegistry, describeAdminEntityFieldMismatch, eraseEntityPort, getErasedEntityPort, listErasedEntityPorts, } from './entities/rules.js';
16
+ export { loadNamespaceValues, saveChangedEntries, readString, readBoolean, readNumber } from './ledger-slice.js';
16
17
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @file The shared read/diff-write half of every settings-dialog tab adapter.
3
+ *
4
+ * Each tab maps a SPEC-007 ledger namespace onto one `@jini-ai/ui` config
5
+ * object. Three things are identical across all of them and live here:
6
+ *
7
+ * 1. **Cold-start tolerance.** A namespace with no registered definitions
8
+ * 404s, which is the expected state before the boot registrar has run (or
9
+ * on a database predating the tab). That is not an error worth surfacing —
10
+ * it means "use defaults". Every OTHER failure still propagates.
11
+ * 2. **Field-level diffing.** The ledger is append-only per key
12
+ * (ADR-028 §4), so writing all N keys on every save would burn N revisions
13
+ * per keystroke. Only changed keys are written.
14
+ * 3. **Typed reads.** Ledger values arrive as `unknown`; a missing or
15
+ * wrong-typed value falls back field by field rather than throwing, so a
16
+ * partially-written namespace still yields a usable config.
17
+ *
18
+ * What deliberately does NOT live here: anything about a specific tab's
19
+ * shape, and anything about credentials. `execution-settings.ts` keeps its own
20
+ * localStorage half because the ADR-028 §6 secret gate is an execution-tab
21
+ * problem, not a general one — see that file's header.
22
+ */
23
+ import type { AdminSettingsPort, SettingScope } from "./ports/settings.js";
24
+ /** A single ledger write: the key within the namespace and its new JSON value. */
25
+ export interface LedgerEntry {
26
+ key: string;
27
+ valueJson: unknown;
28
+ }
29
+ /** A candidate write plus whether it actually differs from the persisted value. */
30
+ export interface LedgerCandidate extends LedgerEntry {
31
+ changed: boolean;
32
+ }
33
+ /**
34
+ * Reads every effective value in `namespace` as a key -> value map.
35
+ *
36
+ * Returns an EMPTY map (not an error) when the namespace has no registered
37
+ * definitions yet — see this file's header, item 1. Any other failure
38
+ * propagates, per the error-reporting contract: a network error or a 500 must
39
+ * not be laundered into "no settings", which would silently show defaults and
40
+ * then overwrite real saved values on the next keystroke.
41
+ */
42
+ export declare function loadNamespaceValues({ namespace, port }: {
43
+ namespace: string;
44
+ port: Pick<AdminSettingsPort, "getSettingsEffective">;
45
+ }, { isUnregisteredNamespace }: {
46
+ isUnregisteredNamespace: (required: {
47
+ error: unknown;
48
+ }, optional?: Record<string, never>) => boolean;
49
+ }): Promise<Map<string, unknown>>;
50
+ /**
51
+ * Writes the changed subset of `candidates`, in order, and returns the keys
52
+ * actually written.
53
+ *
54
+ * Sequential rather than parallel on purpose: each `setSetting` opens the
55
+ * settings write chokepoint's transaction, and concurrent openers throw on the
56
+ * SQLite root — the same hazard the server's boot registrars chain around.
57
+ */
58
+ export declare function saveChangedEntries({ namespace, scope, candidates, port }: {
59
+ namespace: string;
60
+ scope: SettingScope;
61
+ candidates: readonly LedgerCandidate[];
62
+ port: Pick<AdminSettingsPort, "setSetting">;
63
+ }, _options?: Record<string, never>): Promise<readonly string[]>;
64
+ /** Reads a string, falling back when the key is absent or holds another type. */
65
+ export declare function readString({ values, key, fallback }: {
66
+ values: ReadonlyMap<string, unknown>;
67
+ key: string;
68
+ fallback: string;
69
+ }, _options?: Record<string, never>): string;
70
+ /** Reads a boolean, falling back when the key is absent or holds another type. */
71
+ export declare function readBoolean({ values, key, fallback }: {
72
+ values: ReadonlyMap<string, unknown>;
73
+ key: string;
74
+ fallback: boolean;
75
+ }, _options?: Record<string, never>): boolean;
76
+ /**
77
+ * Reads a finite number, falling back when the key is absent, holds another
78
+ * type, or holds `NaN`/`Infinity`.
79
+ *
80
+ * The finiteness check matters because these values round-trip through JSON,
81
+ * where `NaN` and `Infinity` serialize to `null` — a value that survived a
82
+ * write but not a read would otherwise reach a tab as a number it cannot
83
+ * render.
84
+ */
85
+ export declare function readNumber({ values, key, fallback }: {
86
+ values: ReadonlyMap<string, unknown>;
87
+ key: string;
88
+ fallback: number;
89
+ }, _options?: Record<string, never>): number;
90
+ //# sourceMappingURL=ledger-slice.d.ts.map
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @file The shared read/diff-write half of every settings-dialog tab adapter.
3
+ *
4
+ * Each tab maps a SPEC-007 ledger namespace onto one `@jini-ai/ui` config
5
+ * object. Three things are identical across all of them and live here:
6
+ *
7
+ * 1. **Cold-start tolerance.** A namespace with no registered definitions
8
+ * 404s, which is the expected state before the boot registrar has run (or
9
+ * on a database predating the tab). That is not an error worth surfacing —
10
+ * it means "use defaults". Every OTHER failure still propagates.
11
+ * 2. **Field-level diffing.** The ledger is append-only per key
12
+ * (ADR-028 §4), so writing all N keys on every save would burn N revisions
13
+ * per keystroke. Only changed keys are written.
14
+ * 3. **Typed reads.** Ledger values arrive as `unknown`; a missing or
15
+ * wrong-typed value falls back field by field rather than throwing, so a
16
+ * partially-written namespace still yields a usable config.
17
+ *
18
+ * What deliberately does NOT live here: anything about a specific tab's
19
+ * shape, and anything about credentials. `execution-settings.ts` keeps its own
20
+ * localStorage half because the ADR-028 §6 secret gate is an execution-tab
21
+ * problem, not a general one — see that file's header.
22
+ */
23
+ /**
24
+ * Reads every effective value in `namespace` as a key -> value map.
25
+ *
26
+ * Returns an EMPTY map (not an error) when the namespace has no registered
27
+ * definitions yet — see this file's header, item 1. Any other failure
28
+ * propagates, per the error-reporting contract: a network error or a 500 must
29
+ * not be laundered into "no settings", which would silently show defaults and
30
+ * then overwrite real saved values on the next keystroke.
31
+ */
32
+ export async function loadNamespaceValues({ namespace, port }, { isUnregisteredNamespace }) {
33
+ try {
34
+ const data = await port.getSettingsEffective({ namespace }, {});
35
+ return new Map(data.map((row) => [row.key, row.value]));
36
+ }
37
+ catch (error) {
38
+ if (isUnregisteredNamespace({ error }, {}))
39
+ return new Map();
40
+ throw error;
41
+ }
42
+ }
43
+ /**
44
+ * Writes the changed subset of `candidates`, in order, and returns the keys
45
+ * actually written.
46
+ *
47
+ * Sequential rather than parallel on purpose: each `setSetting` opens the
48
+ * settings write chokepoint's transaction, and concurrent openers throw on the
49
+ * SQLite root — the same hazard the server's boot registrars chain around.
50
+ */
51
+ export async function saveChangedEntries({ namespace, scope, candidates, port }, _options = {}) {
52
+ const changed = candidates.filter((candidate) => candidate.changed);
53
+ for (const { key, valueJson } of changed) {
54
+ await port.setSetting({ namespace, key, scope, value: valueJson }, {});
55
+ }
56
+ return changed.map((entry) => entry.key);
57
+ }
58
+ /** Reads a string, falling back when the key is absent or holds another type. */
59
+ export function readString({ values, key, fallback }, _options = {}) {
60
+ const value = values.get(key);
61
+ return typeof value === "string" ? value : fallback;
62
+ }
63
+ /** Reads a boolean, falling back when the key is absent or holds another type. */
64
+ export function readBoolean({ values, key, fallback }, _options = {}) {
65
+ const value = values.get(key);
66
+ return typeof value === "boolean" ? value : fallback;
67
+ }
68
+ /**
69
+ * Reads a finite number, falling back when the key is absent, holds another
70
+ * type, or holds `NaN`/`Infinity`.
71
+ *
72
+ * The finiteness check matters because these values round-trip through JSON,
73
+ * where `NaN` and `Infinity` serialize to `null` — a value that survived a
74
+ * write but not a read would otherwise reach a tab as a number it cannot
75
+ * render.
76
+ */
77
+ export function readNumber({ values, key, fallback }, _options = {}) {
78
+ const value = values.get(key);
79
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
80
+ }
81
+ //# sourceMappingURL=ledger-slice.js.map
@@ -24,6 +24,8 @@ export type CommentStatus = "pending" | "approved" | "spam" | "trash";
24
24
  /** A comment as it appears in the moderation queue. */
25
25
  export interface AdminComment {
26
26
  readonly id: string;
27
+ /** Optional workspace metadata retained from host queue responses; scoping stays in the transport. */
28
+ readonly workspaceId?: string;
27
29
  readonly entryId: string;
28
30
  /** Null for a top-level comment. */
29
31
  readonly parentId: string | null;
@@ -44,11 +44,11 @@
44
44
  * constraint documented, rather than being narrowed to a shape that can't express a removal
45
45
  * attempt at all.
46
46
  *
47
- * ## Submissions are the one place with a real hard delete
47
+ * ## Submission deletion moves to Trash
48
48
  *
49
- * Unlike definitions, `FormSubmissionRepoPort` does expose a permanent delete — the reference repo
50
- * port's own doc comment calls this out as "the one asymmetry." `deleteFormSubmission` is
51
- * genuinely irreversible; do not offer it with "undo" affordances.
49
+ * `deleteFormSubmission` models the admin HTTP operation: reversible removal from active reads.
50
+ * The underlying repository's hard-delete primitive is not this admin contract. Restoration and
51
+ * permanent deletion belong to the generic Trash owner (Coordinator authorization, 2026-10-08).
52
52
  *
53
53
  * ## Open vs. closed unions
54
54
  *
@@ -69,6 +69,8 @@ export interface AdminFormField {
69
69
  readonly type: FormFieldType;
70
70
  readonly required: boolean;
71
71
  readonly maxLength?: number | null;
72
+ readonly className?: string | undefined;
73
+ readonly attributes?: Readonly<Record<string, string>> | undefined;
72
74
  }
73
75
  export interface AdminFormNotifyConfig {
74
76
  readonly enabled: boolean;
@@ -83,6 +85,9 @@ export interface AdminFormDefinition {
83
85
  readonly status: FormDefinitionStatus;
84
86
  readonly createdAt: string;
85
87
  readonly updatedAt: string;
88
+ /** HTML authoring is explicit; absent mode means the existing Builder contract. */
89
+ readonly mode?: "builder" | "html" | undefined;
90
+ readonly html?: string | undefined;
86
91
  }
87
92
  export interface AdminFormSubmission {
88
93
  readonly id: string;
@@ -91,6 +96,8 @@ export interface AdminFormSubmission {
91
96
  readonly data: Readonly<Record<string, string | boolean>>;
92
97
  readonly sourceIp: string;
93
98
  readonly submittedAt: string;
99
+ /** Missing means active for older wire records. Trash preserves the original submission data. */
100
+ readonly status?: "active" | "trash";
94
101
  }
95
102
  /** A keyset-paginated page of submissions, newest-first. */
96
103
  export interface AdminFormSubmissionPage {
@@ -101,11 +108,16 @@ export interface AdminFormCreateInput {
101
108
  readonly name: string;
102
109
  readonly slug: string;
103
110
  readonly fields: readonly AdminFormField[];
111
+ readonly mode?: "builder" | "html" | undefined;
112
+ readonly html?: string | undefined;
104
113
  readonly notify?: AdminFormNotifyConfig;
105
114
  }
106
115
  /** No `slug` — see file header. */
107
116
  export interface AdminFormUpdatePatch {
108
117
  readonly name?: string;
118
+ /** A mode/body patch uses the authoring route; an ordinary patch keeps the CRUD route. */
119
+ readonly mode?: "builder" | "html" | undefined;
120
+ readonly html?: string | undefined;
109
121
  /** Whole-array replace with an add/edit-only constraint — see file header. */
110
122
  readonly fields?: readonly AdminFormField[];
111
123
  readonly notify?: AdminFormNotifyConfig;
@@ -132,11 +144,11 @@ export interface AdminFormsPort {
132
144
  formId: string;
133
145
  submissionId: string;
134
146
  }): Promise<AdminFormSubmission>;
135
- /** Permanent delete — the one hard delete in this port. See file header on why form
136
- * DEFINITIONS have no equivalent. */
147
+ /** Move to Trash, preserving data while hiding it from active list/detail reads. The form must
148
+ * own this submission; restoration and permanent deletion remain with the generic Trash owner. */
137
149
  deleteFormSubmission(requiredArgs: {
138
150
  formId: string;
139
151
  submissionId: string;
140
- }): Promise<void>;
152
+ }, optionalArgs?: Record<string, never>): Promise<void>;
141
153
  }
142
154
  //# sourceMappingURL=forms.d.ts.map
@@ -44,11 +44,11 @@
44
44
  * constraint documented, rather than being narrowed to a shape that can't express a removal
45
45
  * attempt at all.
46
46
  *
47
- * ## Submissions are the one place with a real hard delete
47
+ * ## Submission deletion moves to Trash
48
48
  *
49
- * Unlike definitions, `FormSubmissionRepoPort` does expose a permanent delete — the reference repo
50
- * port's own doc comment calls this out as "the one asymmetry." `deleteFormSubmission` is
51
- * genuinely irreversible; do not offer it with "undo" affordances.
49
+ * `deleteFormSubmission` models the admin HTTP operation: reversible removal from active reads.
50
+ * The underlying repository's hard-delete primitive is not this admin contract. Restoration and
51
+ * permanent deletion belong to the generic Trash owner (Coordinator authorization, 2026-10-08).
52
52
  *
53
53
  * ## Open vs. closed unions
54
54
  *
@@ -14,7 +14,7 @@ export type { AdminExtensionEnabledResult, AdminExtensionsPort, AdminPlugin } fr
14
14
  export type { AdminAnalyticsHit, AdminAnalyticsPort } from './analytics.js';
15
15
  export type { AdminWorkspace, AdminWorkspacePort } from './workspace.js';
16
16
  export type { AdminIdentityPort, AdminIdentityUser, AdminPolicy, AdminRole, } from './identity.js';
17
- export type { AdminSeoAnalysis, AdminSeoIssue, AdminSeoMeta, AdminSeoOpenGraph, AdminSeoOverrides, AdminSeoPort, AdminSeoRobotsDirective, AdminSeoRobotsRule, AdminSeoSettings, AdminSeoTwitterCard, SeoIssueSeverity, SeoOpenGraphType, SeoTwitterCardKind, } from './seo.js';
17
+ export type { AdminSeoAnalysis, AdminSeoEntryChoice, AdminSeoIssue, AdminSeoMeta, AdminSeoOpenGraph, AdminSeoOverrides, AdminSeoOverridesPatch, AdminSeoPort, AdminSeoRobotsDirective, AdminSeoRobotsRule, AdminSeoSettings, AdminSeoSettingsPatch, AdminSeoTwitterCard, SeoIssueSeverity, SeoOpenGraphType, SeoTwitterCardKind, } from './seo.js';
18
18
  export type { AdminRedirect, AdminRedirectCreateInput, AdminRedirectHitStats, AdminRedirectImportFailure, AdminRedirectImportResult, AdminRedirectListFilter, AdminRedirectsPort, AdminRedirectUpdatePatch, RedirectMatchType, RedirectSource, RedirectStatus, RedirectStatusCode, } from './redirects.js';
19
19
  export type { AdminAssignMenuLocationResult, AdminDeleteMenuResult, AdminMenu, AdminMenuBinding, AdminMenuCreateInput, AdminMenuCustomTarget, AdminMenuEntryTarget, AdminMenuItem, AdminMenuItemAttrs, AdminMenuRouteTarget, AdminMenusPort, AdminMenuTarget, AdminMenuTermTarget, AdminMenuUpdateTreeInput, AdminMenuUrlTarget, MenuStatus, NavTargetKind, } from './menus.js';
20
20
  export type { AdminFormCreateInput, AdminFormDefinition, AdminFormField, AdminFormNotifyConfig, AdminFormsPort, AdminFormSubmission, AdminFormSubmissionPage, AdminFormUpdatePatch, FormDefinitionStatus, FormFieldType, } from './forms.js';
@@ -43,10 +43,9 @@ export type SeoTwitterCardKind = "summary" | "summary_large_image";
43
43
  export type SeoIssueSeverity = "error" | "warning" | "info" | (string & {});
44
44
  /**
45
45
  * The author-authored override bag for one entry. Every field is OPTIONAL — omitting a field
46
- * means "derive from site defaults / the content itself," not "clear it"; `putSeoEntry` merge-
47
- * patches this bag onto whatever was previously stored; there is no way to unset a single
48
- * previously-set field back to "derive" short of the host's own reset affordance (the reference
49
- * implementation has none either).
46
+ * means "derive from site defaults / the content itself," not "clear it". `putSeoEntry` accepts
47
+ * AdminSeoOverridesPatch, which adds null as the remove-override sentinel; omission leaves a
48
+ * previously stored override unchanged. The resolved read shape never contains null clears.
50
49
  */
51
50
  export interface AdminSeoOverrides {
52
51
  readonly title?: string;
@@ -132,6 +131,21 @@ export interface AdminSeoSettings {
132
131
  readonly sitemapEnabled: boolean;
133
132
  readonly robotsRules: readonly AdminSeoRobotsRule[];
134
133
  }
134
+ /** Write-only clear sentinels: null removes a value; omission leaves it unchanged. */
135
+ export type AdminSeoOverridesPatch = {
136
+ [K in keyof AdminSeoOverrides]?: AdminSeoOverrides[K] | null;
137
+ };
138
+ export type AdminSeoSettingsPatch = Partial<Omit<AdminSeoSettings, 'defaultDescription' | 'defaultOgImage' | 'twitterSite'>> & {
139
+ defaultDescription?: string | null;
140
+ defaultOgImage?: string | null;
141
+ twitterSite?: string | null;
142
+ };
143
+ /** Picker projection. Hosts may return additional content fields without a CMS dependency. */
144
+ export interface AdminSeoEntryChoice {
145
+ readonly id: string;
146
+ readonly title: string;
147
+ readonly status: string;
148
+ }
135
149
  export interface AdminSeoPort {
136
150
  getSeoEntry(requiredArgs: {
137
151
  entryId: string;
@@ -139,15 +153,28 @@ export interface AdminSeoPort {
139
153
  /** Merge-patches the override bag and returns the newly-resolved meta — see file header. */
140
154
  putSeoEntry(requiredArgs: {
141
155
  entryId: string;
142
- }, optionalArgs?: AdminSeoOverrides): Promise<AdminSeoMeta>;
156
+ }, optionalArgs?: AdminSeoOverridesPatch): Promise<AdminSeoMeta>;
143
157
  analyzeSeoEntry(requiredArgs: {
144
158
  entryId: string;
145
159
  }): Promise<AdminSeoAnalysis>;
146
160
  getSeoSettings(requiredArgs: Record<string, never>): Promise<AdminSeoSettings>;
147
- putSeoSettings(requiredArgs: Record<string, never>, optionalArgs?: Partial<AdminSeoSettings>): Promise<AdminSeoSettings>;
161
+ putSeoSettings(requiredArgs: Record<string, never>, optionalArgs?: AdminSeoSettingsPatch): Promise<AdminSeoSettings>;
148
162
  /** Fire-and-accept trigger, not a trackable job — see file header. */
149
163
  regenerateSeoSitemap(requiredArgs: Record<string, never>): Promise<{
150
164
  accepted: boolean;
151
165
  }>;
166
+ /** Existing post/page reads, in their original order; authorization remains host-owned. */
167
+ listSeoPosts(requiredArgs: Record<string, never>, optionalArgs?: Record<string, never>): Promise<readonly AdminSeoEntryChoice[]>;
168
+ listSeoPages(requiredArgs: Record<string, never>, optionalArgs?: Record<string, never>): Promise<readonly AdminSeoEntryChoice[]>;
169
+ /** Exact public sitemap response, never reconstructed from admin entries. */
170
+ fetchSitemapXml(requiredArgs: Record<string, never>, optionalArgs?: {
171
+ signal?: AbortSignal;
172
+ }): Promise<{
173
+ text: string;
174
+ }>;
175
+ /** Original thumbnail URL; media-reference resolution stays on the server. */
176
+ mediaOriginalUrl(requiredArgs: {
177
+ id: string;
178
+ }, optionalArgs?: Record<string, never>): string;
152
179
  }
153
180
  //# sourceMappingURL=seo.d.ts.map
@@ -0,0 +1,46 @@
1
+ import type { ComponentType, ReactNode, LazyExoticComponent, Context as ReactContext } from 'react';
2
+ import type { AdminInstance, AdminModule, ScopedPorts } from '../module/types.js';
3
+ export interface TabViewProps {
4
+ readonly params: Readonly<Record<string, unknown>>;
5
+ readonly permissions?: readonly string[];
6
+ }
7
+ export interface ModulePageProps {
8
+ readonly tabs: Readonly<Record<string, LazyExoticComponent<ComponentType<TabViewProps>>>>;
9
+ readonly description: ReturnType<AdminInstance['describe']>['pages'][number];
10
+ readonly requestedTab?: string;
11
+ readonly onTabChange?: (required: {
12
+ tab: string;
13
+ }, optional?: Record<string, never>) => void;
14
+ }
15
+ type Loader<P> = () => Promise<{
16
+ default: ComponentType<P>;
17
+ }>;
18
+ export type ReactViews<M extends AdminModule> = {
19
+ readonly [P in keyof M['pages']]: {
20
+ readonly page: Loader<ModulePageProps>;
21
+ readonly tabs: {
22
+ readonly [T in keyof M['pages'][P]['tabs']]: Loader<TabViewProps>;
23
+ };
24
+ };
25
+ };
26
+ /** Every page and tab is lazy. The only port context is private to this binding;
27
+ * a sibling module can never read another module's dependencies through a global locator. */
28
+ export declare function bindReact<const M extends AdminModule>({ module, views }: {
29
+ module: M;
30
+ views: ReactViews<M>;
31
+ }, { context }?: {
32
+ context?: ReactContext<ScopedPorts<M> | null>;
33
+ }): {
34
+ module: M;
35
+ pages: { [P in keyof M["pages"]]: {
36
+ Page: LazyExoticComponent<ComponentType<ModulePageProps>>;
37
+ tabs: { [T in keyof M["pages"][P]["tabs"]]: LazyExoticComponent<ComponentType<TabViewProps>>; };
38
+ }; };
39
+ Provider: ({ admin, children }: {
40
+ admin: AdminInstance;
41
+ children: ReactNode;
42
+ }, _optional?: Record<string, never>) => import("react").FunctionComponentElement<import("react").ProviderProps<ScopedPorts<M> | null>>;
43
+ usePorts: (_required?: Record<string, never>, _optional?: Record<string, never>) => ScopedPorts<M>;
44
+ };
45
+ export {};
46
+ //# sourceMappingURL=bind-react.d.ts.map