@jini-ai/admin 0.3.10 → 0.4.1

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 (387) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +71 -37
  3. package/dist/agent-plugins/adapters/http.d.ts +7 -0
  4. package/dist/agent-plugins/adapters/http.js +15 -0
  5. package/dist/agent-plugins/adapters/memory.d.ts +8 -0
  6. package/dist/agent-plugins/adapters/memory.js +25 -0
  7. package/dist/agent-plugins/agent-plugins.module.d.ts +51 -0
  8. package/dist/agent-plugins/agent-plugins.module.js +6 -0
  9. package/dist/agent-plugins/conformance/agent-plugins-api.conformance.d.ts +12 -0
  10. package/dist/agent-plugins/conformance/agent-plugins-api.conformance.js +47 -0
  11. package/dist/agent-plugins/controllers/agent-plugin-files.controller.d.ts +20 -0
  12. package/dist/agent-plugins/controllers/agent-plugin-files.controller.js +43 -0
  13. package/dist/agent-plugins/controllers/agent-plugins.controller.d.ts +25 -0
  14. package/dist/agent-plugins/controllers/agent-plugins.controller.js +91 -0
  15. package/dist/agent-plugins/index.d.ts +9 -0
  16. package/dist/agent-plugins/index.js +9 -0
  17. package/dist/agent-plugins/messages.en.d.ts +23 -0
  18. package/dist/agent-plugins/messages.en.js +14 -0
  19. package/dist/agent-plugins/models.d.ts +57 -0
  20. package/dist/agent-plugins/models.js +2 -0
  21. package/dist/agent-plugins/package-file-tree.d.ts +111 -0
  22. package/dist/agent-plugins/package-file-tree.js +188 -0
  23. package/dist/agent-plugins/ports.d.ts +18 -0
  24. package/dist/agent-plugins/ports.js +3 -0
  25. package/dist/agent-plugins/react/components/AgentPluginFileContent.d.ts +5 -0
  26. package/dist/agent-plugins/react/components/AgentPluginFileContent.js +9 -0
  27. package/dist/agent-plugins/react/components/AgentPluginFileTree.d.ts +9 -0
  28. package/dist/agent-plugins/react/components/AgentPluginFileTree.js +7 -0
  29. package/dist/agent-plugins/react/components/AgentPluginInspector.d.ts +3 -0
  30. package/dist/agent-plugins/react/components/AgentPluginInspector.js +11 -0
  31. package/dist/agent-plugins/react/components/AgentPluginListPanel.d.ts +6 -0
  32. package/dist/agent-plugins/react/components/AgentPluginListPanel.js +10 -0
  33. package/dist/agent-plugins/react/components/AgentPluginRow.d.ts +5 -0
  34. package/dist/agent-plugins/react/components/AgentPluginRow.js +8 -0
  35. package/dist/agent-plugins/react/hooks/AgentPluginInspector.hooks.d.ts +90 -0
  36. package/dist/agent-plugins/react/hooks/AgentPluginInspector.hooks.js +74 -0
  37. package/dist/agent-plugins/react/hooks/AgentPluginPanel.hooks.d.ts +67 -0
  38. package/dist/agent-plugins/react/hooks/AgentPluginPanel.hooks.js +50 -0
  39. package/dist/agent-plugins/react/hooks/AgentPluginRow.hooks.d.ts +55 -0
  40. package/dist/agent-plugins/react/hooks/AgentPluginRow.hooks.js +6 -0
  41. package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.d.ts +64 -0
  42. package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.js +39 -0
  43. package/dist/agent-plugins/react/hooks/AgentPluginsPorts.hooks.d.ts +7 -0
  44. package/dist/agent-plugins/react/hooks/AgentPluginsPorts.hooks.js +10 -0
  45. package/dist/agent-plugins/react/hooks/MarketplaceTab.hooks.d.ts +6 -0
  46. package/dist/agent-plugins/react/hooks/MarketplaceTab.hooks.js +3 -0
  47. package/dist/agent-plugins/react/index.d.ts +245 -0
  48. package/dist/agent-plugins/react/index.js +13 -0
  49. package/dist/agent-plugins/react/pages/AgentPluginsPage.d.ts +4 -0
  50. package/dist/agent-plugins/react/pages/AgentPluginsPage.js +12 -0
  51. package/dist/agent-plugins/react/tabs/DownloadedTab.d.ts +4 -0
  52. package/dist/agent-plugins/react/tabs/DownloadedTab.js +5 -0
  53. package/dist/agent-plugins/react/tabs/InstalledTab.d.ts +4 -0
  54. package/dist/agent-plugins/react/tabs/InstalledTab.js +5 -0
  55. package/dist/agent-plugins/react/tabs/MarketplaceTab.d.ts +4 -0
  56. package/dist/agent-plugins/react/tabs/MarketplaceTab.js +10 -0
  57. package/dist/agent-plugins/rules.d.ts +33 -0
  58. package/dist/agent-plugins/rules.js +51 -0
  59. package/dist/browser/index.d.ts +1 -0
  60. package/dist/browser/index.js +1 -0
  61. package/dist/browser/navigation.d.ts +19 -4
  62. package/dist/browser/navigation.js +8 -8
  63. package/dist/browser/shell-navigation.d.ts +12 -0
  64. package/dist/browser/shell-navigation.js +16 -0
  65. package/dist/contracts/credential-management.d.ts +8 -0
  66. package/dist/contracts/credential-management.js +3 -0
  67. package/dist/contracts/media-picker.d.ts +17 -0
  68. package/dist/contracts/media-picker.js +5 -0
  69. package/dist/contracts/playground-render-target.d.ts +18 -0
  70. package/dist/contracts/playground-render-target.js +3 -0
  71. package/dist/core/entities/rules.d.ts +138 -0
  72. package/dist/core/entities/rules.js +344 -0
  73. package/dist/core/gated/types.d.ts +8 -4
  74. package/dist/core/index.d.ts +4 -0
  75. package/dist/core/index.js +1 -0
  76. package/dist/core/manifest/rules.d.ts +24 -6
  77. package/dist/core/manifest/rules.js +12 -11
  78. package/dist/core/module/controller-store.d.ts +22 -0
  79. package/dist/core/module/controller-store.js +32 -0
  80. package/dist/core/module/create-admin.d.ts +41 -0
  81. package/dist/core/module/create-admin.js +187 -0
  82. package/dist/core/module/define-admin-module.d.ts +4 -0
  83. package/dist/core/module/define-admin-module.js +5 -0
  84. package/dist/core/module/index.d.ts +7 -0
  85. package/dist/core/module/index.js +4 -0
  86. package/dist/core/module/token.d.ts +19 -0
  87. package/dist/core/module/token.js +4 -0
  88. package/dist/core/module/types.d.ts +79 -0
  89. package/dist/core/module/types.js +2 -0
  90. package/dist/core/permissions/rules.d.ts +4 -1
  91. package/dist/core/permissions/rules.js +1 -1
  92. package/dist/core/ports/analytics.d.ts +1 -1
  93. package/dist/core/ports/auth.d.ts +2 -2
  94. package/dist/core/ports/comments.d.ts +9 -6
  95. package/dist/core/ports/database.d.ts +13 -10
  96. package/dist/core/ports/entities.d.ts +302 -0
  97. package/dist/core/ports/entities.js +47 -0
  98. package/dist/core/ports/forms.d.ts +19 -7
  99. package/dist/core/ports/identity.d.ts +42 -17
  100. package/dist/core/ports/index.d.ts +2 -0
  101. package/dist/core/ports/integrations.d.ts +9 -4
  102. package/dist/core/ports/media.d.ts +16 -7
  103. package/dist/core/ports/members.d.ts +7 -3
  104. package/dist/core/ports/menus.d.ts +46 -0
  105. package/dist/core/ports/menus.js +43 -0
  106. package/dist/core/ports/plugins.d.ts +3 -2
  107. package/dist/core/ports/recovery.d.ts +10 -6
  108. package/dist/core/ports/redirects.d.ts +17 -7
  109. package/dist/core/ports/seo.d.ts +12 -6
  110. package/dist/core/ports/shell.d.ts +41 -0
  111. package/dist/core/ports/shell.js +2 -0
  112. package/dist/core/ports/workspace.d.ts +3 -3
  113. package/dist/core/routing/rules.d.ts +17 -4
  114. package/dist/core/routing/rules.js +4 -4
  115. package/dist/core/transport/errors.d.ts +13 -4
  116. package/dist/core/transport/errors.js +4 -4
  117. package/dist/core/transport/http.d.ts +26 -16
  118. package/dist/core/transport/http.js +59 -21
  119. package/dist/core/transport/types.d.ts +26 -14
  120. package/dist/core/transport/types.js +9 -7
  121. package/dist/media/adapters/http.d.ts +27 -0
  122. package/dist/media/adapters/http.js +44 -0
  123. package/dist/media/adapters/memory.d.ts +11 -0
  124. package/dist/media/adapters/memory.js +139 -0
  125. package/dist/media/conformance/media-api.conformance.d.ts +7 -0
  126. package/dist/media/conformance/media-api.conformance.js +69 -0
  127. package/dist/media/controllers/edit-media.controller.d.ts +24 -0
  128. package/dist/media/controllers/edit-media.controller.js +69 -0
  129. package/dist/media/controllers/library.controller.d.ts +47 -0
  130. package/dist/media/controllers/library.controller.js +173 -0
  131. package/dist/media/controllers/providers.controller.d.ts +30 -0
  132. package/dist/media/controllers/providers.controller.js +76 -0
  133. package/dist/media/html-attributes.d.ts +82 -0
  134. package/dist/media/html-attributes.js +204 -0
  135. package/dist/media/index.d.ts +12 -0
  136. package/dist/media/index.js +9 -0
  137. package/dist/media/media.module.d.ts +83 -0
  138. package/dist/media/media.module.js +43 -0
  139. package/dist/media/messages.en.d.ts +24 -0
  140. package/dist/media/messages.en.js +24 -0
  141. package/dist/media/models.d.ts +72 -0
  142. package/dist/media/models.js +2 -0
  143. package/dist/media/ports.d.ts +75 -0
  144. package/dist/media/ports.js +7 -0
  145. package/dist/media/react/components/EditMediaPanel.d.ts +3 -0
  146. package/dist/media/react/components/EditMediaPanel.js +10 -0
  147. package/dist/media/react/components/MediaCard.d.ts +5 -0
  148. package/dist/media/react/components/MediaCard.js +17 -0
  149. package/dist/media/react/components/MediaDialog.d.ts +3 -0
  150. package/dist/media/react/components/MediaDialog.js +8 -0
  151. package/dist/media/react/components/MediaGrid.d.ts +4 -0
  152. package/dist/media/react/components/MediaGrid.js +8 -0
  153. package/dist/media/react/components/MediaIcons.d.ts +14 -0
  154. package/dist/media/react/components/MediaIcons.js +39 -0
  155. package/dist/media/react/components/MediaLightbox.d.ts +5 -0
  156. package/dist/media/react/components/MediaLightbox.js +12 -0
  157. package/dist/media/react/components/MediaPicker.d.ts +3 -0
  158. package/dist/media/react/components/MediaPicker.js +10 -0
  159. package/dist/media/react/components/MediaPurgeDialog.d.ts +4 -0
  160. package/dist/media/react/components/MediaPurgeDialog.js +9 -0
  161. package/dist/media/react/components/UploadButton.d.ts +3 -0
  162. package/dist/media/react/components/UploadButton.js +8 -0
  163. package/dist/media/react/hooks/EditMediaPanel.hooks.d.ts +84 -0
  164. package/dist/media/react/hooks/EditMediaPanel.hooks.js +105 -0
  165. package/dist/media/react/hooks/LibraryTab.hooks.d.ts +103 -0
  166. package/dist/media/react/hooks/LibraryTab.hooks.js +164 -0
  167. package/dist/media/react/hooks/MediaCard.hooks.d.ts +83 -0
  168. package/dist/media/react/hooks/MediaCard.hooks.js +66 -0
  169. package/dist/media/react/hooks/MediaDialog.hooks.d.ts +10 -0
  170. package/dist/media/react/hooks/MediaDialog.hooks.js +20 -0
  171. package/dist/media/react/hooks/MediaGrid.hooks.d.ts +29 -0
  172. package/dist/media/react/hooks/MediaGrid.hooks.js +6 -0
  173. package/dist/media/react/hooks/MediaLightbox.hooks.d.ts +27 -0
  174. package/dist/media/react/hooks/MediaLightbox.hooks.js +64 -0
  175. package/dist/media/react/hooks/MediaPage.hooks.d.ts +68 -0
  176. package/dist/media/react/hooks/MediaPage.hooks.js +68 -0
  177. package/dist/media/react/hooks/MediaPicker.hooks.d.ts +26 -0
  178. package/dist/media/react/hooks/MediaPicker.hooks.js +25 -0
  179. package/dist/media/react/hooks/MediaPorts.hooks.d.ts +9 -0
  180. package/dist/media/react/hooks/MediaPorts.hooks.js +10 -0
  181. package/dist/media/react/hooks/MediaPurgeDialog.hooks.d.ts +22 -0
  182. package/dist/media/react/hooks/MediaPurgeDialog.hooks.js +6 -0
  183. package/dist/media/react/hooks/ProvidersTab.hooks.d.ts +55 -0
  184. package/dist/media/react/hooks/ProvidersTab.hooks.js +124 -0
  185. package/dist/media/react/hooks/UploadButton.hooks.d.ts +48 -0
  186. package/dist/media/react/hooks/UploadButton.hooks.js +118 -0
  187. package/dist/media/react/index.d.ts +373 -0
  188. package/dist/media/react/index.js +73 -0
  189. package/dist/media/react/pages/MediaPage.d.ts +4 -0
  190. package/dist/media/react/pages/MediaPage.js +9 -0
  191. package/dist/media/react/tabs/LibraryTab.d.ts +4 -0
  192. package/dist/media/react/tabs/LibraryTab.js +14 -0
  193. package/dist/media/react/tabs/ProvidersTab.d.ts +4 -0
  194. package/dist/media/react/tabs/ProvidersTab.js +10 -0
  195. package/dist/media/rules.d.ts +86 -0
  196. package/dist/media/rules.js +134 -0
  197. package/dist/media/styles.d.ts +4 -0
  198. package/dist/media/styles.js +5 -0
  199. package/dist/playground/adapters/http.d.ts +8 -0
  200. package/dist/playground/adapters/http.js +4 -0
  201. package/dist/playground/adapters/memory.d.ts +10 -0
  202. package/dist/playground/adapters/memory.js +30 -0
  203. package/dist/playground/conformance/playground-api.conformance.d.ts +6 -0
  204. package/dist/playground/conformance/playground-api.conformance.js +37 -0
  205. package/dist/playground/controllers/playground.controller.d.ts +16 -0
  206. package/dist/playground/controllers/playground.controller.js +21 -0
  207. package/dist/playground/index.d.ts +7 -0
  208. package/dist/playground/index.js +5 -0
  209. package/dist/playground/messages.en.d.ts +9 -0
  210. package/dist/playground/messages.en.js +2 -0
  211. package/dist/playground/models.d.ts +4 -0
  212. package/dist/playground/models.js +2 -0
  213. package/dist/playground/playground.module.d.ts +31 -0
  214. package/dist/playground/playground.module.js +5 -0
  215. package/dist/playground/ports.d.ts +5 -0
  216. package/dist/playground/ports.js +2 -0
  217. package/dist/playground/react/components/Canvas.d.ts +3 -0
  218. package/dist/playground/react/components/Canvas.js +9 -0
  219. package/dist/playground/react/hooks/Canvas.hooks.d.ts +7 -0
  220. package/dist/playground/react/hooks/Canvas.hooks.js +18 -0
  221. package/dist/playground/react/hooks/PlaygroundPage.hooks.d.ts +8 -0
  222. package/dist/playground/react/hooks/PlaygroundPage.hooks.js +2 -0
  223. package/dist/playground/react/hooks/PlaygroundPorts.hooks.d.ts +4 -0
  224. package/dist/playground/react/hooks/PlaygroundPorts.hooks.js +6 -0
  225. package/dist/playground/react/index.d.ts +136 -0
  226. package/dist/playground/react/index.js +10 -0
  227. package/dist/playground/react/pages/PlaygroundPage.d.ts +4 -0
  228. package/dist/playground/react/pages/PlaygroundPage.js +11 -0
  229. package/dist/playground/react/tabs/CanvasTab.d.ts +4 -0
  230. package/dist/playground/react/tabs/CanvasTab.js +5 -0
  231. package/dist/playground/rules.d.ts +4 -0
  232. package/dist/playground/rules.js +2 -0
  233. package/dist/react/OverlayHost.d.ts +3 -0
  234. package/dist/react/OverlayHost.hooks.d.ts +9 -0
  235. package/dist/react/OverlayHost.hooks.js +9 -0
  236. package/dist/react/OverlayHost.js +7 -0
  237. package/dist/react/bind-react.d.ts +46 -0
  238. package/dist/react/bind-react.js +28 -0
  239. package/dist/react/components/ConfirmButton/ConfirmButton.hooks.d.ts +7 -1
  240. package/dist/react/components/ConfirmButton/ConfirmButton.hooks.js +2 -2
  241. package/dist/react/components/ConfirmButton/ConfirmButton.js +1 -1
  242. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts +17 -3
  243. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js +3 -3
  244. package/dist/react/components/ConfirmDialog/ConfirmDialog.js +5 -5
  245. package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.d.ts +6 -2
  246. package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.js +7 -8
  247. package/dist/react/components/RowMenu/RowMenu.d.ts +5 -1
  248. package/dist/react/components/RowMenu/RowMenu.hooks.d.ts +8 -2
  249. package/dist/react/components/RowMenu/RowMenu.hooks.js +4 -4
  250. package/dist/react/components/RowMenu/RowMenu.js +6 -6
  251. package/dist/react/components/Sidebar.d.ts +1 -1
  252. package/dist/react/components/Sidebar.js +103 -7
  253. package/dist/react/entities/EntityCell.d.ts +10 -0
  254. package/dist/react/entities/EntityCell.js +18 -0
  255. package/dist/react/entities/EntityDetail.d.ts +3 -0
  256. package/dist/react/entities/EntityDetail.js +21 -0
  257. package/dist/react/entities/EntityEdit.d.ts +13 -0
  258. package/dist/react/entities/EntityEdit.js +45 -0
  259. package/dist/react/entities/EntityField.d.ts +20 -0
  260. package/dist/react/entities/EntityField.js +31 -0
  261. package/dist/react/entities/EntityIndex.d.ts +3 -0
  262. package/dist/react/entities/EntityIndex.js +10 -0
  263. package/dist/react/entities/EntityList.d.ts +7 -0
  264. package/dist/react/entities/EntityList.js +52 -0
  265. package/dist/react/entities/contribution.d.ts +26 -0
  266. package/dist/react/entities/contribution.js +78 -0
  267. package/dist/react/entities/index.d.ts +10 -0
  268. package/dist/react/entities/index.js +7 -0
  269. package/dist/react/entities/rules.d.ts +179 -0
  270. package/dist/react/entities/rules.js +224 -0
  271. package/dist/react/entities/types.d.ts +45 -0
  272. package/dist/react/entities/types.js +5 -0
  273. package/dist/react/entities/use-entity-edit.d.ts +35 -0
  274. package/dist/react/entities/use-entity-edit.js +98 -0
  275. package/dist/react/entities/use-entity-read.d.ts +22 -0
  276. package/dist/react/entities/use-entity-read.js +27 -0
  277. package/dist/react/hooks/use-nav-sections.d.ts +12 -3
  278. package/dist/react/hooks/use-nav-sections.js +14 -14
  279. package/dist/react/hooks/use-sidebar-rail.d.ts +7 -1
  280. package/dist/react/hooks/use-sidebar-rail.js +11 -11
  281. package/dist/react/index.d.ts +3 -1
  282. package/dist/react/index.js +5 -2
  283. package/dist/react/overlays.d.ts +38 -0
  284. package/dist/react/overlays.js +46 -0
  285. package/dist/react/shell/AdminShell.d.ts +9 -0
  286. package/dist/react/shell/AdminShell.hooks.d.ts +15 -0
  287. package/dist/react/shell/AdminShell.hooks.js +27 -0
  288. package/dist/react/shell/AdminShell.js +46 -0
  289. package/dist/react/shell/index.d.ts +7 -0
  290. package/dist/react/shell/index.js +5 -0
  291. package/dist/react/shell/model.d.ts +25 -0
  292. package/dist/react/shell/model.js +29 -0
  293. package/dist/react/shell/theme-ports.d.ts +28 -0
  294. package/dist/react/shell/theme-ports.js +2 -0
  295. package/dist/react/shell/types.d.ts +99 -0
  296. package/dist/react/shell/types.js +2 -0
  297. package/dist/react/shell/use-admin-shell-session.d.ts +13 -0
  298. package/dist/react/shell/use-admin-shell-session.js +81 -0
  299. package/dist/react/shell/use-admin-theme.d.ts +16 -0
  300. package/dist/react/shell/use-admin-theme.js +57 -0
  301. package/dist/react/types.d.ts +6 -4
  302. package/dist/react/types.js +2 -2
  303. package/dist/react/use-controller.d.ts +16 -0
  304. package/dist/react/use-controller.js +18 -0
  305. package/dist/security/adapters/http.d.ts +16 -0
  306. package/dist/security/adapters/http.js +94 -0
  307. package/dist/security/adapters/memory.d.ts +15 -0
  308. package/dist/security/adapters/memory.js +60 -0
  309. package/dist/security/conformance/security-api.conformance.d.ts +10 -0
  310. package/dist/security/conformance/security-api.conformance.js +48 -0
  311. package/dist/security/controllers/access-tokens.controller.d.ts +44 -0
  312. package/dist/security/controllers/access-tokens.controller.js +112 -0
  313. package/dist/security/controllers/other-credentials.controller.d.ts +30 -0
  314. package/dist/security/controllers/other-credentials.controller.js +74 -0
  315. package/dist/security/controllers/root-key.controller.d.ts +35 -0
  316. package/dist/security/controllers/root-key.controller.js +90 -0
  317. package/dist/security/index.d.ts +9 -0
  318. package/dist/security/index.js +9 -0
  319. package/dist/security/messages.en.d.ts +12 -0
  320. package/dist/security/messages.en.js +2 -0
  321. package/dist/security/models.d.ts +112 -0
  322. package/dist/security/models.js +2 -0
  323. package/dist/security/ports.d.ts +58 -0
  324. package/dist/security/ports.js +5 -0
  325. package/dist/security/react/components/CredentialEditor.d.ts +3 -0
  326. package/dist/security/react/components/CredentialEditor.js +8 -0
  327. package/dist/security/react/hooks/AccessTokensTab.hooks.d.ts +94 -0
  328. package/dist/security/react/hooks/AccessTokensTab.hooks.js +36 -0
  329. package/dist/security/react/hooks/CredentialEditor.hooks.d.ts +49 -0
  330. package/dist/security/react/hooks/CredentialEditor.hooks.js +14 -0
  331. package/dist/security/react/hooks/RootKeyTab.hooks.d.ts +29 -0
  332. package/dist/security/react/hooks/RootKeyTab.hooks.js +19 -0
  333. package/dist/security/react/hooks/SecurityPage.hooks.d.ts +17 -0
  334. package/dist/security/react/hooks/SecurityPage.hooks.js +12 -0
  335. package/dist/security/react/hooks/SecurityPorts.hooks.d.ts +9 -0
  336. package/dist/security/react/hooks/SecurityPorts.hooks.js +6 -0
  337. package/dist/security/react/index.d.ts +215 -0
  338. package/dist/security/react/index.js +10 -0
  339. package/dist/security/react/pages/SecurityPage.d.ts +4 -0
  340. package/dist/security/react/pages/SecurityPage.js +10 -0
  341. package/dist/security/react/tabs/AccessTokensTab.d.ts +4 -0
  342. package/dist/security/react/tabs/AccessTokensTab.js +10 -0
  343. package/dist/security/react/tabs/RootKeyTab.d.ts +4 -0
  344. package/dist/security/react/tabs/RootKeyTab.js +9 -0
  345. package/dist/security/rules.d.ts +57 -0
  346. package/dist/security/rules.js +63 -0
  347. package/dist/security/security.module.d.ts +45 -0
  348. package/dist/security/security.module.js +5 -0
  349. package/dist/source-control/adapters/http.d.ts +6 -0
  350. package/dist/source-control/adapters/http.js +13 -0
  351. package/dist/source-control/adapters/memory.d.ts +9 -0
  352. package/dist/source-control/adapters/memory.js +35 -0
  353. package/dist/source-control/conformance/source-control-api.conformance.d.ts +10 -0
  354. package/dist/source-control/conformance/source-control-api.conformance.js +48 -0
  355. package/dist/source-control/controllers/source-control.controller.d.ts +26 -0
  356. package/dist/source-control/controllers/source-control.controller.js +70 -0
  357. package/dist/source-control/index.d.ts +8 -0
  358. package/dist/source-control/index.js +6 -0
  359. package/dist/source-control/messages.en.d.ts +11 -0
  360. package/dist/source-control/messages.en.js +2 -0
  361. package/dist/source-control/models.d.ts +70 -0
  362. package/dist/source-control/models.js +2 -0
  363. package/dist/source-control/ports.d.ts +23 -0
  364. package/dist/source-control/ports.js +3 -0
  365. package/dist/source-control/react/components/SourceControlCredentialFields.d.ts +5 -0
  366. package/dist/source-control/react/components/SourceControlCredentialFields.js +8 -0
  367. package/dist/source-control/react/components/SourceControlProviderRow.d.ts +5 -0
  368. package/dist/source-control/react/components/SourceControlProviderRow.js +7 -0
  369. package/dist/source-control/react/hooks/ProvidersTab.hooks.d.ts +45 -0
  370. package/dist/source-control/react/hooks/ProvidersTab.hooks.js +20 -0
  371. package/dist/source-control/react/hooks/SourceControlCredentialFields.hooks.d.ts +43 -0
  372. package/dist/source-control/react/hooks/SourceControlCredentialFields.hooks.js +9 -0
  373. package/dist/source-control/react/hooks/SourceControlPage.hooks.d.ts +17 -0
  374. package/dist/source-control/react/hooks/SourceControlPage.hooks.js +5 -0
  375. package/dist/source-control/react/hooks/SourceControlPorts.hooks.d.ts +9 -0
  376. package/dist/source-control/react/hooks/SourceControlPorts.hooks.js +6 -0
  377. package/dist/source-control/react/index.d.ts +156 -0
  378. package/dist/source-control/react/index.js +10 -0
  379. package/dist/source-control/react/pages/SourceControlPage.d.ts +4 -0
  380. package/dist/source-control/react/pages/SourceControlPage.js +11 -0
  381. package/dist/source-control/react/tabs/ProvidersTab.d.ts +4 -0
  382. package/dist/source-control/react/tabs/ProvidersTab.js +10 -0
  383. package/dist/source-control/rules.d.ts +32 -0
  384. package/dist/source-control/rules.js +35 -0
  385. package/dist/source-control/source-control.module.d.ts +36 -0
  386. package/dist/source-control/source-control.module.js +6 -0
  387. package/package.json +207 -4
@@ -0,0 +1,6 @@
1
+ import { mediaRowHandles } from '../../rules.js';
2
+ export function useMediaGrid(props, _optional = {}) {
3
+ const handles = mediaRowHandles({ media: props.actions.map(action => action.item) });
4
+ return { className: props.actions.length ? 'jini-media-grid' : 'jini-media-grid-empty', ...props, actions: props.actions.map((action, index) => ({ ...action, handleBase: handles[index] })) };
5
+ }
6
+ //# sourceMappingURL=MediaGrid.hooks.js.map
@@ -0,0 +1,27 @@
1
+ import type { MediaAsset } from '../../models.js';
2
+ import type { MediaApiPort } from '../../ports.js';
3
+ export interface MediaLightboxProps {
4
+ readonly items: readonly MediaAsset[];
5
+ readonly api: MediaApiPort;
6
+ readonly activeIndex: number | null;
7
+ readonly onNavigate: (index: number) => void;
8
+ readonly onClose: () => void;
9
+ }
10
+ export declare function useMediaLightbox(props: MediaLightboxProps, _optional?: Record<string, never>): {
11
+ item: MediaAsset | null;
12
+ open: boolean;
13
+ hasPrev: boolean;
14
+ hasNext: boolean;
15
+ previous: () => void;
16
+ next: () => void;
17
+ items: readonly MediaAsset[];
18
+ api: MediaApiPort;
19
+ activeIndex: number | null;
20
+ onNavigate: (index: number) => void;
21
+ onClose: () => void;
22
+ dialogRef: import("react").RefObject<HTMLDialogElement | null>;
23
+ closeRef: import("react").RefObject<HTMLButtonElement | null>;
24
+ title: string;
25
+ position: string;
26
+ };
27
+ //# sourceMappingURL=MediaLightbox.hooks.d.ts.map
@@ -0,0 +1,64 @@
1
+ import { useEffect, useRef } from 'react';
2
+ export function useMediaLightbox(props, _optional = {}) {
3
+ const item = props.activeIndex === null ? null : props.items[props.activeIndex] ?? null;
4
+ function go(index) {
5
+ // Clamps rather than wrapping: staying on the last asset is the less surprising
6
+ // default for an operator navigating a specific set of uploads, not a slideshow.
7
+ if (index >= 0 && index < props.items.length) {
8
+ const focusedPart = dialogRef.current?.ownerDocument.activeElement?.getAttribute('data-jini-part');
9
+ // Keep focus in the dialog when the focused arrow disappears at a boundary.
10
+ // Interior navigation leaves focus where the operator put it.
11
+ if ((index === 0 && focusedPart === 'media.lightbox.previous') ||
12
+ (index === props.items.length - 1 && focusedPart === 'media.lightbox.next'))
13
+ closeRef.current?.focus({ preventScroll: true });
14
+ props.onNavigate(index);
15
+ }
16
+ }
17
+ const closeRef = useRef(null);
18
+ const dialogRef = useRef(null);
19
+ const open = !!item;
20
+ useEffect(() => {
21
+ // Close exists at every position, so it is a stable initial focus target. Only
22
+ // opening focuses it; navigation must preserve the operator's current focus.
23
+ if (open)
24
+ closeRef.current?.focus();
25
+ }, [open]);
26
+ // Dialog owns open/close/focus, keyed on open rather than index: navigation must not
27
+ // reopen an already-open dialog or recapture its trigger from inside the lightbox.
28
+ useEffect(() => {
29
+ const dialog = dialogRef.current;
30
+ if (!dialog || !item)
31
+ return;
32
+ const onKey = (event) => {
33
+ if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight')
34
+ return;
35
+ event.preventDefault();
36
+ if (props.activeIndex !== null)
37
+ go(props.activeIndex + (event.key === 'ArrowRight' ? 1 : -1));
38
+ // Native video controls may also seek while focused, as in the legacy lightbox.
39
+ // Preview stage remains private, so do not silently infer it from contentType.
40
+ };
41
+ dialog.ownerDocument.addEventListener('keydown', onKey);
42
+ return () => dialog.ownerDocument.removeEventListener('keydown', onKey);
43
+ }, [props.activeIndex, props.items, props.onNavigate, !!item]);
44
+ return {
45
+ dialogRef,
46
+ closeRef,
47
+ title: item ? `Media preview: ${item.title}` : 'Media preview',
48
+ position: item && props.activeIndex !== null ? `${props.activeIndex + 1} / ${props.items.length}` : '',
49
+ ...props,
50
+ item,
51
+ open: !!item,
52
+ hasPrev: props.activeIndex !== null && props.activeIndex > 0,
53
+ hasNext: props.activeIndex !== null && props.activeIndex + 1 < props.items.length,
54
+ previous: () => {
55
+ if (props.activeIndex !== null)
56
+ go(props.activeIndex - 1);
57
+ },
58
+ next: () => {
59
+ if (props.activeIndex !== null)
60
+ go(props.activeIndex + 1);
61
+ },
62
+ };
63
+ }
64
+ //# sourceMappingURL=MediaLightbox.hooks.js.map
@@ -0,0 +1,68 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { ModulePageProps } from '../../../react/bind-react.js';
3
+ import { createLibraryController } from '../../controllers/library.controller.js';
4
+ import type { LibraryState } from '../../controllers/library.controller.js';
5
+ export declare const MediaLibraryContext: import("react").Context<{
6
+ controller: ReturnType<typeof createLibraryController> | null;
7
+ snapshot: LibraryState | null;
8
+ } | null>;
9
+ export declare function useSharedMediaLibrary(_required?: Record<string, never>, _optional?: Record<string, never>): {
10
+ controller: ReturnType<typeof createLibraryController> | null;
11
+ snapshot: LibraryState | null;
12
+ } | null;
13
+ export interface MediaPageProps extends ModulePageProps {
14
+ readonly headerActions?: ReactNode;
15
+ }
16
+ export declare function useMediaPage(props: MediaPageProps, _optional?: Record<string, never>): {
17
+ library: {
18
+ controller: {
19
+ getSnapshot: () => Readonly<LibraryState>;
20
+ subscribe: ({ listener }: {
21
+ listener: () => void;
22
+ }) => () => void;
23
+ load: (_required?: Record<string, never>, _optional?: Record<string, never>) => Promise<void>;
24
+ setQuery({ query }: {
25
+ query: import("../../models.js").MediaQuery;
26
+ }, _optional?: Record<string, never>): Promise<void>;
27
+ upload({ input, alt }: {
28
+ input: import("../../models.js").UploadInput;
29
+ alt?: string;
30
+ }, _optional?: Record<string, never>): Promise<boolean>;
31
+ trash({ id }: {
32
+ id: string;
33
+ }, _optional?: Record<string, never>): Promise<boolean>;
34
+ restore({ id }: {
35
+ id: string;
36
+ }, _optional?: Record<string, never>): Promise<boolean>;
37
+ requestPurge({ item }: {
38
+ item: import("../../models.js").MediaAsset;
39
+ }, _optional?: Record<string, never>): void;
40
+ cancelPurge(_required?: Record<string, never>, _optional?: Record<string, never>): void;
41
+ confirmPurge({ confirmed }: {
42
+ confirmed: boolean;
43
+ }, _optional?: Record<string, never>): Promise<boolean>;
44
+ dispose(_required?: Record<string, never>, _optional?: Record<string, never>): void;
45
+ } | null;
46
+ snapshot: Readonly<LibraryState> | null;
47
+ };
48
+ headerActions: ReactNode;
49
+ activeId: string | undefined;
50
+ tabs: {
51
+ id: string;
52
+ handle: string;
53
+ icon: import("react").FunctionComponentElement<Record<string, never>>;
54
+ count: number | null | undefined;
55
+ selected: boolean;
56
+ onPress: () => void;
57
+ label: string;
58
+ visible: boolean;
59
+ reason: string | null;
60
+ params: Readonly<Record<string, unknown>>;
61
+ agentReachable: boolean;
62
+ }[];
63
+ ActiveTab: import("react").LazyExoticComponent<import("react").ComponentType<import("../../../react/bind-react.js").TabViewProps>> | undefined;
64
+ params: Readonly<Record<string, unknown>>;
65
+ permissions: readonly string[];
66
+ denied: boolean;
67
+ };
68
+ //# sourceMappingURL=MediaPage.hooks.d.ts.map
@@ -0,0 +1,68 @@
1
+ import { createElement, createContext, useContext, useEffect, useState } from 'react';
2
+ import { useController } from '../../../react/use-controller.js';
3
+ import { createLibraryController } from '../../controllers/library.controller.js';
4
+ import { useMediaPorts } from './MediaPorts.hooks.js';
5
+ import { AllIcon, ImageIcon, VideoIcon, CloudIcon } from '../components/MediaIcons.js';
6
+ import { resolveActiveTab } from '../../rules.js';
7
+ export const MediaLibraryContext = createContext(null);
8
+ export function useSharedMediaLibrary(_required = {}, _optional = {}) {
9
+ return useContext(MediaLibraryContext);
10
+ }
11
+ export function useMediaPage(props, _optional = {}) {
12
+ const [localTab, setLocalTab] = useState('all');
13
+ const { mediaApi, mediaEvents, mediaProviders } = useMediaPorts();
14
+ const library = useController({ create: () => createLibraryController({ api: mediaApi }, { query: { filter: requestedFilter({ tabId: props.requestedTab ?? localTab }) } }), dependencies: [mediaApi] }, { start: ({ controller }) => { if (props.description.visible)
15
+ void controller.load(); } });
16
+ useEffect(() => props.description.visible ? mediaEvents?.subscribe({ onRefresh: () => { void library.controller?.load(); } }) : undefined, [props.description.visible, mediaEvents, library.controller]);
17
+ const [providerCount, setProviderCount] = useState(null);
18
+ useEffect(() => {
19
+ if (!props.description.visible || !mediaProviders || !props.description.grants.includes('media.providers'))
20
+ return;
21
+ const abort = new AbortController();
22
+ void mediaProviders.list({}, { signal: abort.signal }).then(items => {
23
+ if (!abort.signal.aborted && items)
24
+ setProviderCount(items.length);
25
+ }).catch(() => { });
26
+ return () => abort.abort();
27
+ }, [mediaProviders, props.description.grants, props.description.visible]);
28
+ const visible = props.description.visible
29
+ ? props.description.tabs.filter((tab) => tab.visible)
30
+ : [];
31
+ const requested = resolveActiveTab({ tabId: props.requestedTab ?? localTab });
32
+ const active = visible.find((tab) => tab.id.endsWith(`.${requested}`)) ?? visible[0];
33
+ const tabs = visible.map((tab) => {
34
+ const id = tab.id.slice(tab.id.lastIndexOf('.') + 1);
35
+ return {
36
+ ...tab,
37
+ id,
38
+ handle: `media-tab-${id}`,
39
+ icon: createElement(id === 'images' ? ImageIcon : id === 'videos' ? VideoIcon : id === 'external-providers' ? CloudIcon : AllIcon, {}),
40
+ count: id === 'external-providers' ? providerCount : library.snapshot?.counts?.[id],
41
+ selected: active?.id === tab.id,
42
+ onPress: () => {
43
+ setLocalTab(id);
44
+ props.onTabChange?.({ tab: id });
45
+ },
46
+ };
47
+ });
48
+ const id = active?.id.slice(active.id.lastIndexOf('.') + 1);
49
+ useEffect(() => {
50
+ if (props.description.visible && (id === 'all' || id === 'images' || id === 'videos') && library.controller?.getSnapshot().query.filter !== id)
51
+ void library.controller?.setQuery({ query: { ...library.controller.getSnapshot().query, filter: id } });
52
+ }, [id, library.controller, props.description.visible]);
53
+ return {
54
+ library,
55
+ headerActions: props.headerActions,
56
+ activeId: id,
57
+ tabs,
58
+ ActiveTab: id ? props.tabs[id] : undefined,
59
+ params: active?.params ?? {},
60
+ permissions: props.description.grants,
61
+ denied: !props.description.visible,
62
+ };
63
+ }
64
+ function requestedFilter({ tabId }) {
65
+ const tab = resolveActiveTab({ tabId });
66
+ return tab === 'external-providers' ? 'all' : tab;
67
+ }
68
+ //# sourceMappingURL=MediaPage.hooks.js.map
@@ -0,0 +1,26 @@
1
+ import type { MediaAsset } from '../../models.js';
2
+ import type { MediaApiPort } from '../../ports.js';
3
+ export interface MediaPickerProps {
4
+ readonly api: MediaApiPort;
5
+ readonly accept: readonly string[];
6
+ readonly onChoose: (asset: MediaAsset | null) => void;
7
+ readonly onClose: () => void;
8
+ }
9
+ export declare function useMediaPicker(props: MediaPickerProps, _optional?: Record<string, never>): {
10
+ snapshot: Readonly<import("../../index.js").LibraryState> | null;
11
+ actions: {
12
+ item: MediaAsset;
13
+ onChoose: () => void;
14
+ }[];
15
+ loading: boolean;
16
+ onRetry: () => void;
17
+ onSearch: ({ value: search }: {
18
+ value: string;
19
+ }) => void;
20
+ search: string;
21
+ api: MediaApiPort;
22
+ accept: readonly string[];
23
+ onChoose: (asset: MediaAsset | null) => void;
24
+ onClose: () => void;
25
+ };
26
+ //# sourceMappingURL=MediaPicker.hooks.d.ts.map
@@ -0,0 +1,25 @@
1
+ import { useController } from '../../../react/use-controller.js';
2
+ import { createLibraryController } from '../../controllers/library.controller.js';
3
+ import { acceptsMedia } from '../../rules.js';
4
+ export function useMediaPicker(props, _optional = {}) {
5
+ const { controller, snapshot } = useController({ create: () => createLibraryController({ api: props.api }), dependencies: [props.api] }, {
6
+ start: ({ controller }) => {
7
+ void controller.load();
8
+ },
9
+ });
10
+ const actions = (snapshot?.items ?? [])
11
+ .filter((item) => item.status === 'active' && acceptsMedia({ item, accept: props.accept }))
12
+ .map((item) => ({ item, onChoose: () => props.onChoose(item) }));
13
+ return {
14
+ ...props,
15
+ snapshot,
16
+ actions,
17
+ loading: !snapshot || (snapshot.loading && !snapshot.error),
18
+ onRetry: () => { void controller?.load(); },
19
+ onSearch: ({ value: search }) => {
20
+ void controller?.setQuery({ query: { search } });
21
+ },
22
+ search: snapshot?.query.search ?? '',
23
+ };
24
+ }
25
+ //# sourceMappingURL=MediaPicker.hooks.js.map
@@ -0,0 +1,9 @@
1
+ import type { MediaApiPort, MediaProvidersPort, MediaEventsPort } from '../../ports.js';
2
+ export interface MediaPorts {
3
+ readonly mediaApi: MediaApiPort;
4
+ readonly mediaProviders?: MediaProvidersPort;
5
+ readonly mediaEvents?: MediaEventsPort;
6
+ }
7
+ export declare const MediaPortsContext: import("react").Context<MediaPorts | null>;
8
+ export declare function useMediaPorts(_required?: Record<string, never>, _optional?: Record<string, never>): MediaPorts;
9
+ //# sourceMappingURL=MediaPorts.hooks.d.ts.map
@@ -0,0 +1,10 @@
1
+ import { createContext, useContext } from 'react';
2
+ import { AdminConfigError } from '../../../core/module/index.js';
3
+ export const MediaPortsContext = createContext(null);
4
+ export function useMediaPorts(_required = {}, _optional = {}) {
5
+ const ports = useContext(MediaPortsContext);
6
+ if (!ports)
7
+ throw new AdminConfigError({ issues: ['React scope unavailable: media'] });
8
+ return ports;
9
+ }
10
+ //# sourceMappingURL=MediaPorts.hooks.js.map
@@ -0,0 +1,22 @@
1
+ /** Confirmation safety moved to ui-kit's framework-free controller. Cancel-first focus,
2
+ * pending dismissal/activation and trigger restoration remain enforced for every view. */
3
+ export interface MediaPurgeDialogProps {
4
+ readonly filename?: string;
5
+ readonly open: boolean;
6
+ readonly pending: boolean;
7
+ readonly onCancel: () => void;
8
+ readonly onConfirm: () => void | Promise<void>;
9
+ }
10
+ export declare function useMediaPurgeDialog(props: MediaPurgeDialogProps, _optional?: Record<string, never>): {
11
+ actionAccessibleNames: {
12
+ cancel: string;
13
+ confirm: string;
14
+ };
15
+ consequence: string;
16
+ filename?: string;
17
+ open: boolean;
18
+ pending: boolean;
19
+ onCancel: () => void;
20
+ onConfirm: () => void | Promise<void>;
21
+ };
22
+ //# sourceMappingURL=MediaPurgeDialog.hooks.d.ts.map
@@ -0,0 +1,6 @@
1
+ export function useMediaPurgeDialog(props, _optional = {}) {
2
+ return { ...props, actionAccessibleNames: { cancel: 'Cancel', confirm: 'Delete permanently' }, consequence: props.filename
3
+ ? `Permanently delete "${props.filename}"? This cannot be undone.`
4
+ : 'This permanently deletes the file. This cannot be undone.' };
5
+ }
6
+ //# sourceMappingURL=MediaPurgeDialog.hooks.js.map
@@ -0,0 +1,55 @@
1
+ import type { ChangeEvent } from 'react';
2
+ export declare function useProvidersTab(_required?: Record<string, never>, _optional?: Record<string, never>): {
3
+ rows: {
4
+ divider: boolean;
5
+ statusLabel: string | null;
6
+ statusClassName: string;
7
+ credential: string;
8
+ credentialType: "text" | "password";
9
+ credentialPlaceholder: string;
10
+ credentialAttrs: {
11
+ 'data-jini-part': string;
12
+ 'data-agent-private': boolean;
13
+ 'data-agent-element': string;
14
+ 'aria-label': string;
15
+ };
16
+ toggleLabel: string;
17
+ visible: boolean;
18
+ toggle(): void;
19
+ onCredential: (event: ChangeEvent<HTMLInputElement>) => void;
20
+ baseUrl: string;
21
+ baseUrlPlaceholder: string;
22
+ baseUrlLabel: string;
23
+ onBaseUrl: (event: ChangeEvent<HTMLInputElement>) => void;
24
+ model: string;
25
+ modelLabel: string;
26
+ modelsId: string;
27
+ hasModels: boolean;
28
+ onModel: (event: ChangeEvent<HTMLInputElement>) => void;
29
+ clearLabel: string;
30
+ clearDisabled: boolean;
31
+ clear: () => void;
32
+ invalid: boolean;
33
+ hint: string | null;
34
+ hintClassName: string;
35
+ hintRole: "alert" | undefined;
36
+ ariaInvalid: true | undefined;
37
+ id: string;
38
+ label: string;
39
+ defaultBaseUrl?: string;
40
+ models?: readonly string[];
41
+ }[];
42
+ reload: () => void;
43
+ reloadDisabled: boolean;
44
+ reloadLabel: string;
45
+ unreachable: boolean;
46
+ empty: boolean;
47
+ save: () => void;
48
+ saveLabel: string;
49
+ saveDisabled: boolean;
50
+ saved: boolean;
51
+ saveError: boolean;
52
+ disabled: boolean;
53
+ settingsDisabled: boolean;
54
+ };
55
+ //# sourceMappingURL=ProvidersTab.hooks.d.ts.map
@@ -0,0 +1,124 @@
1
+ import { useEffect, useMemo, useRef, useState } from 'react';
2
+ import { useMediaProvidersTab, sortProvidersByConfigured, isEntryPresent, isMarkerOnlyEntry, maskedKeyLabel, isProviderBaseUrlInvalid, invalidBaseUrlProviderIds } from '@jini-ai/ui';
3
+ import { useMediaPorts } from './MediaPorts.hooks.js';
4
+ function configuration({ items }, _optional = {}) {
5
+ return Object.fromEntries(items.filter(item => item.configured || item.apiKeyTail || item.baseUrl?.trim() || item.model?.trim())
6
+ .map(item => [item.id, { apiKeyConfigured: item.configured,
7
+ ...(item.apiKeyTail === undefined ? {} : { apiKeyTail: item.apiKeyTail }),
8
+ ...(item.baseUrl === undefined ? {} : { baseUrl: item.baseUrl }),
9
+ ...(item.model === undefined ? {} : { model: item.model }) }]));
10
+ }
11
+ export function useProvidersTab(_required = {}, _optional = {}) {
12
+ const { mediaProviders } = useMediaPorts();
13
+ const [discoveredCatalog, setDiscoveredCatalog] = useState([]);
14
+ const [visibleKeys, setVisibleKeys] = useState(() => new Set());
15
+ const lifetime = useRef(null);
16
+ useEffect(() => {
17
+ const abort = new AbortController();
18
+ lifetime.current = abort;
19
+ return () => abort.abort();
20
+ }, [mediaProviders]);
21
+ // Always invoke the hook. An unavailable optional port uses an inert, scoped fallback.
22
+ // Reuse the established editor's send-time serialization, reload merge and clear rollback.
23
+ const editorPort = useMemo(() => {
24
+ let lastRead = [];
25
+ return {
26
+ async fetchMediaProviders() {
27
+ try {
28
+ const signal = lifetime.current.signal;
29
+ const items = await mediaProviders?.list({}, { signal });
30
+ if (!items || signal.aborted)
31
+ return null;
32
+ lastRead = items;
33
+ setDiscoveredCatalog(items.map(({ id, label }) => ({ id, label })));
34
+ return configuration({ items });
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ },
40
+ async saveMediaProviders(providers) {
41
+ if (!mediaProviders)
42
+ throw new Error('Provider service unavailable');
43
+ const signal = lifetime.current.signal;
44
+ if (mediaProviders.saveChanges) {
45
+ const items = await mediaProviders.saveChanges({ providers }, { signal });
46
+ lastRead = items;
47
+ return configuration({ items });
48
+ }
49
+ // Older hosts retain the one-button editor; writes remain sequential and failures
50
+ // retain local edits. Atomic whole-set hosts should implement saveChanges instead.
51
+ for (const item of lastRead) {
52
+ const entry = providers[item.id];
53
+ if (!entry) {
54
+ if (item.configured || item.baseUrl || item.model)
55
+ await mediaProviders.removeCredential({ id: item.id }, { signal });
56
+ continue;
57
+ }
58
+ if ((entry.baseUrl ?? '') !== (item.baseUrl ?? '') || (entry.model ?? '') !== (item.model ?? '')) {
59
+ if (!mediaProviders.saveSettings)
60
+ throw new Error('Provider settings unavailable');
61
+ await mediaProviders.saveSettings({ id: item.id, baseUrl: entry.baseUrl ?? '', model: entry.model ?? '' }, { signal });
62
+ }
63
+ if (entry.apiKey?.trim())
64
+ await mediaProviders.saveCredential({ id: item.id, credential: entry.apiKey }, { signal });
65
+ }
66
+ const items = await mediaProviders.list({}, { signal });
67
+ if (!items)
68
+ throw new Error('Provider service unavailable');
69
+ lastRead = items;
70
+ return configuration({ items });
71
+ },
72
+ };
73
+ }, [mediaProviders]);
74
+ const editor = useMediaProvidersTab({ port: editorPort });
75
+ const catalog = mediaProviders?.catalog ?? discoveredCatalog;
76
+ const pinnedIds = mediaProviders?.pinnedProviderIds ?? [];
77
+ const ordered = sortProvidersByConfigured(catalog, editor.providers, pinnedIds);
78
+ const rows = ordered.map((item, index) => {
79
+ const entry = editor.providers[item.id] ?? {};
80
+ const saved = isMarkerOnlyEntry(entry);
81
+ const mask = saved ? maskedKeyLabel(entry) : null;
82
+ const visible = visibleKeys.has(item.id);
83
+ const invalid = isProviderBaseUrlInvalid(entry);
84
+ const modelsId = `jini-media-provider-models-${item.id}`;
85
+ return {
86
+ ...item,
87
+ divider: index > 0 && !pinnedIds.includes(item.id) && pinnedIds.includes(ordered[index - 1].id),
88
+ statusLabel: saved ? `Saved (${mask})` : editor.pendingProviderIds.has(item.id) ? 'Unsaved' : null,
89
+ statusClassName: saved ? 'jini-field-status-badge jini-field-status-badge-success' : 'jini-field-status-badge',
90
+ credential: entry.apiKey ?? '', credentialType: visible ? 'text' : 'password',
91
+ credentialPlaceholder: mask ?? 'Paste your API key',
92
+ credentialAttrs: { 'data-jini-part': 'media.provider.credential', 'data-agent-private': true,
93
+ 'data-agent-element': `media-provider-${item.id}-api-key`, 'aria-label': `${item.label} credential` },
94
+ toggleLabel: `${item.label} ${visible ? 'Hide' : 'Show'}`, visible,
95
+ toggle() { setVisibleKeys(current => { const next = new Set(current); if (next.has(item.id))
96
+ next.delete(item.id);
97
+ else
98
+ next.add(item.id); return next; }); },
99
+ onCredential: (event) => editor.updateProvider(item.id, { apiKey: event.currentTarget.value }),
100
+ baseUrl: entry.baseUrl ?? '', baseUrlPlaceholder: item.defaultBaseUrl || 'https://api.example.com',
101
+ baseUrlLabel: `${item.label} base URL`,
102
+ onBaseUrl: (event) => editor.updateProvider(item.id, { baseUrl: event.currentTarget.value }),
103
+ model: entry.model ?? '', modelLabel: `${item.label} model`, modelsId, hasModels: !!item.models?.length,
104
+ onModel: (event) => editor.updateProvider(item.id, { model: event.currentTarget.value }),
105
+ clearLabel: `${item.label} Clear`, clearDisabled: !isEntryPresent(entry) || !mediaProviders,
106
+ clear: () => editor.clearProvider(item.id),
107
+ invalid, hint: invalid ? 'Enter an absolute http:// or https:// URL that is not a private or internal address.'
108
+ : !entry.baseUrl?.trim() && item.defaultBaseUrl ? `Uses ${item.defaultBaseUrl} by default.` : null,
109
+ hintClassName: invalid ? 'jini-field-hint jini-hint-error' : 'jini-field-hint',
110
+ hintRole: invalid ? 'alert' : undefined,
111
+ ariaInvalid: invalid || undefined,
112
+ };
113
+ });
114
+ return { rows, reload: editor.reload, reloadDisabled: editor.load.status === 'loading',
115
+ reloadLabel: editor.load.status === 'loading' ? 'Reloading…' : 'Reload',
116
+ unreachable: editor.load.status === 'unreachable', empty: !editor.hasAnyConfigured,
117
+ save: editor.saveChanges, saveLabel: editor.save.status === 'saving' ? 'Saving…' : 'Save changes',
118
+ saveDisabled: !mediaProviders || editor.save.status === 'saving' || !editor.pendingProviderIds.size || !!invalidBaseUrlProviderIds(editor.providers).length,
119
+ saved: editor.save.status === 'saved', saveError: editor.save.status === 'save-error', disabled: !mediaProviders,
120
+ // Fail closed: a host that can persist neither the whole set nor per-provider settings
121
+ // must not accept endpoint/model edits that would only surface as a failed save.
122
+ settingsDisabled: !mediaProviders || (!mediaProviders.saveChanges && !mediaProviders.saveSettings) };
123
+ }
124
+ //# sourceMappingURL=ProvidersTab.hooks.js.map
@@ -0,0 +1,48 @@
1
+ import type { ChangeEvent, DragEvent } from 'react';
2
+ import type { UploadInput } from '../../models.js';
3
+ export interface UploadButtonProps {
4
+ readonly upload: (required: {
5
+ input: UploadInput;
6
+ alt?: string;
7
+ }, optional?: Record<string, never>) => Promise<boolean>;
8
+ readonly disabled?: boolean;
9
+ readonly label?: string;
10
+ readonly multiple?: boolean;
11
+ /** Replacement keeps the asset's metadata, so its toolbar has no alt input to fill. */
12
+ readonly withAlt?: boolean;
13
+ }
14
+ /** Reads a browser File at the React boundary; headless controllers only receive bytes. */
15
+ export declare function readMediaFile({ file }: {
16
+ file: File;
17
+ }, { signal }?: {
18
+ signal?: AbortSignal;
19
+ }): Promise<UploadInput>;
20
+ export declare function useUploadButton(props: UploadButtonProps, _optional?: Record<string, never>): {
21
+ alt: string;
22
+ withAlt: boolean;
23
+ multiple: boolean;
24
+ chooseLabel: string;
25
+ altLabel: string;
26
+ handles: {
27
+ toolbar: string;
28
+ file: string;
29
+ alt: string;
30
+ submit: string;
31
+ };
32
+ selectedFileName: string;
33
+ onUpload: () => void;
34
+ onDragOver: (event: DragEvent) => void;
35
+ onDrop: (event: DragEvent) => void;
36
+ uploadDisabled: boolean;
37
+ setAlt: ({ value }: {
38
+ value: string;
39
+ }) => void;
40
+ inputRef: import("react").RefObject<HTMLInputElement | null>;
41
+ onFile: (event: ChangeEvent<HTMLInputElement>) => void;
42
+ error: string | null;
43
+ success: string | null;
44
+ disabled: boolean;
45
+ onPress: () => void | undefined;
46
+ label: string;
47
+ };
48
+ //# sourceMappingURL=UploadButton.hooks.d.ts.map