@aphexcms/cms-core 9.4.0 → 9.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (403) hide show
  1. package/dist/admin/block-previews.svelte.d.ts +46 -0
  2. package/dist/admin/block-previews.svelte.d.ts.map +1 -0
  3. package/dist/admin/block-previews.svelte.js +26 -0
  4. package/dist/admin/field-components.svelte.d.ts +16 -0
  5. package/dist/admin/field-components.svelte.d.ts.map +1 -0
  6. package/dist/admin/field-components.svelte.js +18 -0
  7. package/dist/admin/nav.svelte.d.ts +34 -0
  8. package/dist/admin/nav.svelte.d.ts.map +1 -0
  9. package/dist/admin/nav.svelte.js +78 -0
  10. package/dist/admin/slots.svelte.d.ts +50 -0
  11. package/dist/admin/slots.svelte.d.ts.map +1 -0
  12. package/dist/admin/slots.svelte.js +67 -0
  13. package/dist/admin/types.d.ts +7 -0
  14. package/dist/admin/types.d.ts.map +1 -0
  15. package/dist/admin/types.js +1 -0
  16. package/dist/api/schemas/api-keys.d.ts +4 -37
  17. package/dist/api/schemas/api-keys.d.ts.map +1 -1
  18. package/dist/api/schemas/api-keys.js +5 -2
  19. package/dist/api/schemas/assets.d.ts +4 -0
  20. package/dist/api/schemas/assets.d.ts.map +1 -1
  21. package/dist/api/schemas/assets.js +3 -0
  22. package/dist/api/schemas/plugin-settings.d.ts +6 -0
  23. package/dist/api/schemas/plugin-settings.d.ts.map +1 -0
  24. package/dist/api/schemas/plugin-settings.js +8 -0
  25. package/dist/api/schemas/roles.d.ts +7 -56
  26. package/dist/api/schemas/roles.d.ts.map +1 -1
  27. package/dist/api/schemas/roles.js +11 -6
  28. package/dist/api/schemas/user.d.ts +2 -1
  29. package/dist/api/schemas/user.d.ts.map +1 -1
  30. package/dist/api/schemas/user.js +7 -2
  31. package/dist/app-augment.d.ts +11 -0
  32. package/dist/app-augment.d.ts.map +1 -1
  33. package/dist/app.d.ts +2 -0
  34. package/dist/auth/provider.d.ts +3 -0
  35. package/dist/auth/provider.d.ts.map +1 -1
  36. package/dist/cli/generate-types.d.ts +1 -4
  37. package/dist/cli/generate-types.d.ts.map +1 -1
  38. package/dist/cli/generate-types.js +99 -65
  39. package/dist/cli/generate-types.js.map +1 -1
  40. package/dist/cli/index.js +3 -3
  41. package/dist/cli/index.js.map +1 -1
  42. package/dist/client/index.d.ts +6 -0
  43. package/dist/client/index.d.ts.map +1 -1
  44. package/dist/client/index.js +9 -0
  45. package/dist/components/AdminApp.svelte +259 -113
  46. package/dist/components/AdminApp.svelte.d.ts +18 -2
  47. package/dist/components/AdminApp.svelte.d.ts.map +1 -1
  48. package/dist/components/admin/AdminSlot.svelte +18 -0
  49. package/dist/components/admin/AdminSlot.svelte.d.ts +12 -0
  50. package/dist/components/admin/AdminSlot.svelte.d.ts.map +1 -0
  51. package/dist/components/admin/DocumentEditor.svelte +646 -385
  52. package/dist/components/admin/DocumentEditor.svelte.d.ts +13 -0
  53. package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
  54. package/dist/components/admin/MediaBrowser.svelte +13 -3
  55. package/dist/components/admin/MediaBrowser.svelte.d.ts.map +1 -1
  56. package/dist/components/admin/PluginSettingsPanel.svelte +231 -0
  57. package/dist/components/admin/PluginSettingsPanel.svelte.d.ts +8 -0
  58. package/dist/components/admin/PluginSettingsPanel.svelte.d.ts.map +1 -0
  59. package/dist/components/admin/SchemaField.svelte +76 -95
  60. package/dist/components/admin/SchemaField.svelte.d.ts +7 -0
  61. package/dist/components/admin/SchemaField.svelte.d.ts.map +1 -1
  62. package/dist/components/admin/fields/ArrayField.svelte +24 -2
  63. package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
  64. package/dist/components/admin/fields/FieldInput.svelte +109 -0
  65. package/dist/components/admin/fields/FieldInput.svelte.d.ts +17 -0
  66. package/dist/components/admin/fields/FieldInput.svelte.d.ts.map +1 -0
  67. package/dist/components/admin/fields/richtext/PortableTextImageView.svelte +5 -12
  68. package/dist/components/admin/fields/richtext/PortableTextImageView.svelte.d.ts +2 -9
  69. package/dist/components/admin/fields/richtext/PortableTextImageView.svelte.d.ts.map +1 -1
  70. package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte +18 -17
  71. package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte.d.ts +2 -9
  72. package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte.d.ts.map +1 -1
  73. package/dist/components/admin/fields/richtext/RichtextField.svelte +55 -2
  74. package/dist/components/admin/fields/richtext/RichtextField.svelte.d.ts.map +1 -1
  75. package/dist/components/admin/fields/richtext/portable-text-object-node.d.ts +7 -0
  76. package/dist/components/admin/fields/richtext/portable-text-object-node.d.ts.map +1 -1
  77. package/dist/components/admin/fields/richtext/portable-text-object-node.js +4 -2
  78. package/dist/components/admin/fields/richtext/svelte-node-view.d.ts +16 -1
  79. package/dist/components/admin/fields/richtext/svelte-node-view.d.ts.map +1 -1
  80. package/dist/components/admin/fields/richtext/svelte-node-view.js +20 -1
  81. package/dist/components/layout/OrganizationSwitcher.svelte +31 -10
  82. package/dist/components/layout/OrganizationSwitcher.svelte.d.ts.map +1 -1
  83. package/dist/components/layout/Sidebar.svelte +49 -11
  84. package/dist/components/layout/Sidebar.svelte.d.ts +5 -1
  85. package/dist/components/layout/Sidebar.svelte.d.ts.map +1 -1
  86. package/dist/components/layout/sidebar/AppSidebar.svelte +66 -3
  87. package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts +5 -0
  88. package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts.map +1 -1
  89. package/dist/components/layout/sidebar/NavMain.svelte +3 -2
  90. package/dist/components/layout/sidebar/NavMain.svelte.d.ts +4 -3
  91. package/dist/components/layout/sidebar/NavMain.svelte.d.ts.map +1 -1
  92. package/dist/components/layout/sidebar/NavUser.svelte +5 -1
  93. package/dist/config.d.ts.map +1 -1
  94. package/dist/config.js +11 -0
  95. package/dist/db/interfaces/asset.d.ts +1 -0
  96. package/dist/db/interfaces/asset.d.ts.map +1 -1
  97. package/dist/db/interfaces/index.d.ts +3 -1
  98. package/dist/db/interfaces/index.d.ts.map +1 -1
  99. package/dist/db/interfaces/plugin-settings.d.ts +23 -0
  100. package/dist/db/interfaces/plugin-settings.d.ts.map +1 -0
  101. package/dist/db/interfaces/plugin-settings.js +13 -0
  102. package/dist/db/interfaces/role.d.ts +14 -5
  103. package/dist/db/interfaces/role.d.ts.map +1 -1
  104. package/dist/engine.d.ts +28 -0
  105. package/dist/engine.d.ts.map +1 -1
  106. package/dist/engine.js +44 -0
  107. package/dist/hooks.d.ts +6 -0
  108. package/dist/hooks.d.ts.map +1 -1
  109. package/dist/hooks.js +59 -2
  110. package/dist/index.d.ts +2 -0
  111. package/dist/index.d.ts.map +1 -1
  112. package/dist/index.js +5 -0
  113. package/dist/lib/admin/block-previews.svelte.d.ts +46 -0
  114. package/dist/lib/admin/block-previews.svelte.d.ts.map +1 -0
  115. package/dist/lib/admin/block-previews.svelte.js +27 -0
  116. package/dist/lib/admin/block-previews.svelte.js.map +1 -0
  117. package/dist/lib/admin/field-components.svelte.d.ts +16 -0
  118. package/dist/lib/admin/field-components.svelte.d.ts.map +1 -0
  119. package/dist/lib/admin/field-components.svelte.js +19 -0
  120. package/dist/lib/admin/field-components.svelte.js.map +1 -0
  121. package/dist/lib/admin/nav.svelte.d.ts +34 -0
  122. package/dist/lib/admin/nav.svelte.d.ts.map +1 -0
  123. package/dist/lib/admin/nav.svelte.js +79 -0
  124. package/dist/lib/admin/nav.svelte.js.map +1 -0
  125. package/dist/lib/admin/slots.svelte.d.ts +50 -0
  126. package/dist/lib/admin/slots.svelte.d.ts.map +1 -0
  127. package/dist/lib/admin/slots.svelte.js +68 -0
  128. package/dist/lib/admin/slots.svelte.js.map +1 -0
  129. package/dist/lib/admin/types.d.ts +7 -0
  130. package/dist/lib/admin/types.d.ts.map +1 -0
  131. package/dist/lib/admin/types.js +2 -0
  132. package/dist/lib/admin/types.js.map +1 -0
  133. package/dist/lib/api/schemas/api-keys.d.ts +4 -37
  134. package/dist/lib/api/schemas/api-keys.d.ts.map +1 -1
  135. package/dist/lib/api/schemas/api-keys.js +5 -2
  136. package/dist/lib/api/schemas/api-keys.js.map +1 -1
  137. package/dist/lib/api/schemas/assets.d.ts +4 -0
  138. package/dist/lib/api/schemas/assets.d.ts.map +1 -1
  139. package/dist/lib/api/schemas/assets.js +3 -0
  140. package/dist/lib/api/schemas/assets.js.map +1 -1
  141. package/dist/lib/api/schemas/plugin-settings.d.ts +6 -0
  142. package/dist/lib/api/schemas/plugin-settings.d.ts.map +1 -0
  143. package/dist/lib/api/schemas/plugin-settings.js +9 -0
  144. package/dist/lib/api/schemas/plugin-settings.js.map +1 -0
  145. package/dist/lib/api/schemas/roles.d.ts +7 -56
  146. package/dist/lib/api/schemas/roles.d.ts.map +1 -1
  147. package/dist/lib/api/schemas/roles.js +11 -6
  148. package/dist/lib/api/schemas/roles.js.map +1 -1
  149. package/dist/lib/api/schemas/user.d.ts +2 -1
  150. package/dist/lib/api/schemas/user.d.ts.map +1 -1
  151. package/dist/lib/api/schemas/user.js +7 -2
  152. package/dist/lib/api/schemas/user.js.map +1 -1
  153. package/dist/lib/app-augment.d.ts +11 -0
  154. package/dist/lib/app-augment.d.ts.map +1 -1
  155. package/dist/lib/auth/provider.d.ts +3 -0
  156. package/dist/lib/auth/provider.d.ts.map +1 -1
  157. package/dist/lib/client/index.d.ts +6 -0
  158. package/dist/lib/client/index.d.ts.map +1 -1
  159. package/dist/lib/client/index.js +9 -0
  160. package/dist/lib/client/index.js.map +1 -1
  161. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.d.ts +7 -0
  162. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.d.ts.map +1 -1
  163. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.js +4 -2
  164. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.js.map +1 -1
  165. package/dist/lib/components/admin/fields/richtext/svelte-node-view.d.ts +16 -1
  166. package/dist/lib/components/admin/fields/richtext/svelte-node-view.d.ts.map +1 -1
  167. package/dist/lib/components/admin/fields/richtext/svelte-node-view.js +20 -1
  168. package/dist/lib/components/admin/fields/richtext/svelte-node-view.js.map +1 -1
  169. package/dist/lib/config.d.ts.map +1 -1
  170. package/dist/lib/config.js +11 -0
  171. package/dist/lib/config.js.map +1 -1
  172. package/dist/lib/db/interfaces/asset.d.ts +1 -0
  173. package/dist/lib/db/interfaces/asset.d.ts.map +1 -1
  174. package/dist/lib/db/interfaces/index.d.ts +3 -1
  175. package/dist/lib/db/interfaces/index.d.ts.map +1 -1
  176. package/dist/lib/db/interfaces/plugin-settings.d.ts +23 -0
  177. package/dist/lib/db/interfaces/plugin-settings.d.ts.map +1 -0
  178. package/dist/lib/db/interfaces/plugin-settings.js +14 -0
  179. package/dist/lib/db/interfaces/plugin-settings.js.map +1 -0
  180. package/dist/lib/db/interfaces/role.d.ts +14 -5
  181. package/dist/lib/db/interfaces/role.d.ts.map +1 -1
  182. package/dist/lib/engine.d.ts +28 -0
  183. package/dist/lib/engine.d.ts.map +1 -1
  184. package/dist/lib/engine.js +44 -0
  185. package/dist/lib/engine.js.map +1 -1
  186. package/dist/lib/hooks.d.ts +6 -0
  187. package/dist/lib/hooks.d.ts.map +1 -1
  188. package/dist/lib/hooks.js +59 -2
  189. package/dist/lib/hooks.js.map +1 -1
  190. package/dist/lib/index.d.ts +2 -0
  191. package/dist/lib/index.d.ts.map +1 -1
  192. package/dist/lib/index.js +5 -0
  193. package/dist/lib/index.js.map +1 -1
  194. package/dist/lib/local-api/collection-api.d.ts.map +1 -1
  195. package/dist/lib/local-api/collection-api.js +4 -2
  196. package/dist/lib/local-api/collection-api.js.map +1 -1
  197. package/dist/lib/local-api/types.d.ts +8 -0
  198. package/dist/lib/local-api/types.d.ts.map +1 -1
  199. package/dist/lib/mcp/tools.d.ts.map +1 -1
  200. package/dist/lib/mcp/tools.js +68 -0
  201. package/dist/lib/mcp/tools.js.map +1 -1
  202. package/dist/lib/permissions-context.svelte.d.ts +7 -4
  203. package/dist/lib/permissions-context.svelte.d.ts.map +1 -1
  204. package/dist/lib/permissions-context.svelte.js.map +1 -1
  205. package/dist/lib/plugins/index.d.ts +3 -0
  206. package/dist/lib/plugins/index.d.ts.map +1 -0
  207. package/dist/lib/plugins/index.js +3 -0
  208. package/dist/lib/plugins/index.js.map +1 -0
  209. package/dist/lib/plugins/resolver.d.ts +49 -0
  210. package/dist/lib/plugins/resolver.d.ts.map +1 -0
  211. package/dist/lib/plugins/resolver.js +66 -0
  212. package/dist/lib/plugins/resolver.js.map +1 -0
  213. package/dist/lib/plugins/types.d.ts +233 -0
  214. package/dist/lib/plugins/types.d.ts.map +1 -0
  215. package/dist/lib/plugins/types.js +9 -0
  216. package/dist/lib/plugins/types.js.map +1 -0
  217. package/dist/lib/schema-utils/desugar.d.ts +27 -0
  218. package/dist/lib/schema-utils/desugar.d.ts.map +1 -0
  219. package/dist/lib/schema-utils/desugar.js +102 -0
  220. package/dist/lib/schema-utils/desugar.js.map +1 -0
  221. package/dist/lib/schema-utils/index.d.ts +2 -0
  222. package/dist/lib/schema-utils/index.d.ts.map +1 -1
  223. package/dist/lib/schema-utils/index.js +2 -0
  224. package/dist/lib/schema-utils/index.js.map +1 -1
  225. package/dist/lib/schema-utils/settings.d.ts +17 -0
  226. package/dist/lib/schema-utils/settings.d.ts.map +1 -0
  227. package/dist/lib/schema-utils/settings.js +23 -0
  228. package/dist/lib/schema-utils/settings.js.map +1 -0
  229. package/dist/lib/schema-utils/validator.d.ts.map +1 -1
  230. package/dist/lib/schema-utils/validator.js +11 -0
  231. package/dist/lib/schema-utils/validator.js.map +1 -1
  232. package/dist/lib/security/secret-crypto.d.ts +18 -0
  233. package/dist/lib/security/secret-crypto.d.ts.map +1 -0
  234. package/dist/lib/security/secret-crypto.js +71 -0
  235. package/dist/lib/security/secret-crypto.js.map +1 -0
  236. package/dist/lib/server/api/index.d.ts.map +1 -1
  237. package/dist/lib/server/api/index.js +3 -0
  238. package/dist/lib/server/api/index.js.map +1 -1
  239. package/dist/lib/server/api/routes/assets.d.ts.map +1 -1
  240. package/dist/lib/server/api/routes/assets.js +8 -2
  241. package/dist/lib/server/api/routes/assets.js.map +1 -1
  242. package/dist/lib/server/api/routes/organizations.d.ts.map +1 -1
  243. package/dist/lib/server/api/routes/organizations.js +4 -1
  244. package/dist/lib/server/api/routes/organizations.js.map +1 -1
  245. package/dist/lib/server/api/routes/plugin-settings.d.ts +4 -0
  246. package/dist/lib/server/api/routes/plugin-settings.d.ts.map +1 -0
  247. package/dist/lib/server/api/routes/plugin-settings.js +109 -0
  248. package/dist/lib/server/api/routes/plugin-settings.js.map +1 -0
  249. package/dist/lib/server/api/routes/roles.d.ts.map +1 -1
  250. package/dist/lib/server/api/routes/roles.js +37 -0
  251. package/dist/lib/server/api/routes/roles.js.map +1 -1
  252. package/dist/lib/server/api/routes/user.d.ts.map +1 -1
  253. package/dist/lib/server/api/routes/user.js +14 -3
  254. package/dist/lib/server/api/routes/user.js.map +1 -1
  255. package/dist/lib/services/asset-service.d.ts +1 -0
  256. package/dist/lib/services/asset-service.d.ts.map +1 -1
  257. package/dist/lib/services/asset-service.js.map +1 -1
  258. package/dist/lib/services/index.d.ts +2 -0
  259. package/dist/lib/services/index.d.ts.map +1 -1
  260. package/dist/lib/services/index.js +1 -0
  261. package/dist/lib/services/index.js.map +1 -1
  262. package/dist/lib/services/plugin-settings-service.d.ts +76 -0
  263. package/dist/lib/services/plugin-settings-service.d.ts.map +1 -0
  264. package/dist/lib/services/plugin-settings-service.js +236 -0
  265. package/dist/lib/services/plugin-settings-service.js.map +1 -0
  266. package/dist/lib/services/roles-service.d.ts +2 -2
  267. package/dist/lib/services/roles-service.d.ts.map +1 -1
  268. package/dist/lib/services/roles-service.js.map +1 -1
  269. package/dist/lib/theme/css.d.ts +30 -0
  270. package/dist/lib/theme/css.d.ts.map +1 -0
  271. package/dist/lib/theme/css.js +54 -0
  272. package/dist/lib/theme/css.js.map +1 -0
  273. package/dist/lib/theme/derive.d.ts +27 -0
  274. package/dist/lib/theme/derive.d.ts.map +1 -0
  275. package/dist/lib/theme/derive.js +108 -0
  276. package/dist/lib/theme/derive.js.map +1 -0
  277. package/dist/lib/theme/index.d.ts +5 -0
  278. package/dist/lib/theme/index.d.ts.map +1 -0
  279. package/dist/lib/theme/index.js +5 -0
  280. package/dist/lib/theme/index.js.map +1 -0
  281. package/dist/lib/theme/schemes.d.ts +60 -0
  282. package/dist/lib/theme/schemes.d.ts.map +1 -0
  283. package/dist/lib/theme/schemes.js +150 -0
  284. package/dist/lib/theme/schemes.js.map +1 -0
  285. package/dist/lib/theme/tokens.d.ts +57 -0
  286. package/dist/lib/theme/tokens.d.ts.map +1 -0
  287. package/dist/lib/theme/tokens.js +11 -0
  288. package/dist/lib/theme/tokens.js.map +1 -0
  289. package/dist/lib/types/auth.d.ts +10 -10
  290. package/dist/lib/types/auth.d.ts.map +1 -1
  291. package/dist/lib/types/capabilities.d.ts +50 -9
  292. package/dist/lib/types/capabilities.d.ts.map +1 -1
  293. package/dist/lib/types/capabilities.js +147 -5
  294. package/dist/lib/types/capabilities.js.map +1 -1
  295. package/dist/lib/types/config.d.ts +30 -1
  296. package/dist/lib/types/config.d.ts.map +1 -1
  297. package/dist/lib/types/schemas.d.ts +90 -2
  298. package/dist/lib/types/schemas.d.ts.map +1 -1
  299. package/dist/lib/types/schemas.js.map +1 -1
  300. package/dist/lib/types/sidebar.d.ts +3 -1
  301. package/dist/lib/types/sidebar.d.ts.map +1 -1
  302. package/dist/lib/utils/index.d.ts +1 -0
  303. package/dist/lib/utils/index.d.ts.map +1 -1
  304. package/dist/lib/utils/index.js +1 -0
  305. package/dist/lib/utils/index.js.map +1 -1
  306. package/dist/lib/utils/preview.d.ts +16 -5
  307. package/dist/lib/utils/preview.d.ts.map +1 -1
  308. package/dist/lib/utils/preview.js +7 -2
  309. package/dist/lib/utils/preview.js.map +1 -1
  310. package/dist/lib/vite/index.d.ts +7 -0
  311. package/dist/lib/vite/index.d.ts.map +1 -1
  312. package/dist/lib/vite/index.js +37 -6
  313. package/dist/lib/vite/index.js.map +1 -1
  314. package/dist/local-api/collection-api.d.ts.map +1 -1
  315. package/dist/local-api/collection-api.js +4 -2
  316. package/dist/local-api/types.d.ts +8 -0
  317. package/dist/local-api/types.d.ts.map +1 -1
  318. package/dist/mcp/tools.d.ts.map +1 -1
  319. package/dist/mcp/tools.js +68 -0
  320. package/dist/permissions-context.svelte.d.ts +7 -4
  321. package/dist/permissions-context.svelte.d.ts.map +1 -1
  322. package/dist/plugins/index.d.ts +3 -0
  323. package/dist/plugins/index.d.ts.map +1 -0
  324. package/dist/plugins/index.js +2 -0
  325. package/dist/plugins/resolver.d.ts +49 -0
  326. package/dist/plugins/resolver.d.ts.map +1 -0
  327. package/dist/plugins/resolver.js +65 -0
  328. package/dist/plugins/types.d.ts +233 -0
  329. package/dist/plugins/types.d.ts.map +1 -0
  330. package/dist/plugins/types.js +8 -0
  331. package/dist/schema-utils/desugar.d.ts +27 -0
  332. package/dist/schema-utils/desugar.d.ts.map +1 -0
  333. package/dist/schema-utils/desugar.js +101 -0
  334. package/dist/schema-utils/index.d.ts +2 -0
  335. package/dist/schema-utils/index.d.ts.map +1 -1
  336. package/dist/schema-utils/index.js +2 -0
  337. package/dist/schema-utils/settings.d.ts +17 -0
  338. package/dist/schema-utils/settings.d.ts.map +1 -0
  339. package/dist/schema-utils/settings.js +22 -0
  340. package/dist/schema-utils/validator.d.ts.map +1 -1
  341. package/dist/schema-utils/validator.js +11 -0
  342. package/dist/security/secret-crypto.d.ts +18 -0
  343. package/dist/security/secret-crypto.d.ts.map +1 -0
  344. package/dist/security/secret-crypto.js +70 -0
  345. package/dist/server/api/index.d.ts.map +1 -1
  346. package/dist/server/api/index.js +3 -0
  347. package/dist/server/api/routes/assets.d.ts.map +1 -1
  348. package/dist/server/api/routes/assets.js +8 -2
  349. package/dist/server/api/routes/organizations.d.ts.map +1 -1
  350. package/dist/server/api/routes/organizations.js +4 -1
  351. package/dist/server/api/routes/plugin-settings.d.ts +4 -0
  352. package/dist/server/api/routes/plugin-settings.d.ts.map +1 -0
  353. package/dist/server/api/routes/plugin-settings.js +108 -0
  354. package/dist/server/api/routes/roles.d.ts.map +1 -1
  355. package/dist/server/api/routes/roles.js +37 -0
  356. package/dist/server/api/routes/user.d.ts.map +1 -1
  357. package/dist/server/api/routes/user.js +14 -3
  358. package/dist/services/asset-service.d.ts +1 -0
  359. package/dist/services/asset-service.d.ts.map +1 -1
  360. package/dist/services/index.d.ts +2 -0
  361. package/dist/services/index.d.ts.map +1 -1
  362. package/dist/services/index.js +1 -0
  363. package/dist/services/plugin-settings-service.d.ts +76 -0
  364. package/dist/services/plugin-settings-service.d.ts.map +1 -0
  365. package/dist/services/plugin-settings-service.js +235 -0
  366. package/dist/services/roles-service.d.ts +2 -2
  367. package/dist/services/roles-service.d.ts.map +1 -1
  368. package/dist/theme/css.d.ts +30 -0
  369. package/dist/theme/css.d.ts.map +1 -0
  370. package/dist/theme/css.js +53 -0
  371. package/dist/theme/derive.d.ts +27 -0
  372. package/dist/theme/derive.d.ts.map +1 -0
  373. package/dist/theme/derive.js +107 -0
  374. package/dist/theme/index.d.ts +5 -0
  375. package/dist/theme/index.d.ts.map +1 -0
  376. package/dist/theme/index.js +4 -0
  377. package/dist/theme/schemes.d.ts +60 -0
  378. package/dist/theme/schemes.d.ts.map +1 -0
  379. package/dist/theme/schemes.js +149 -0
  380. package/dist/theme/tokens.d.ts +57 -0
  381. package/dist/theme/tokens.d.ts.map +1 -0
  382. package/dist/theme/tokens.js +10 -0
  383. package/dist/types/auth.d.ts +10 -10
  384. package/dist/types/auth.d.ts.map +1 -1
  385. package/dist/types/capabilities.d.ts +50 -9
  386. package/dist/types/capabilities.d.ts.map +1 -1
  387. package/dist/types/capabilities.js +147 -5
  388. package/dist/types/config.d.ts +30 -1
  389. package/dist/types/config.d.ts.map +1 -1
  390. package/dist/types/schemas.d.ts +90 -2
  391. package/dist/types/schemas.d.ts.map +1 -1
  392. package/dist/types/sidebar.d.ts +3 -1
  393. package/dist/types/sidebar.d.ts.map +1 -1
  394. package/dist/utils/index.d.ts +1 -0
  395. package/dist/utils/index.d.ts.map +1 -1
  396. package/dist/utils/index.js +1 -0
  397. package/dist/utils/preview.d.ts +16 -5
  398. package/dist/utils/preview.d.ts.map +1 -1
  399. package/dist/utils/preview.js +7 -2
  400. package/dist/vite/index.d.ts +7 -0
  401. package/dist/vite/index.d.ts.map +1 -1
  402. package/dist/vite/index.js +37 -6
  403. package/package.json +6 -4
@@ -0,0 +1,17 @@
1
+ import type { SettingsField } from '../types/schemas.js';
2
+ /** A normalized select option: what the user sees, and what gets stored. */
3
+ export interface SettingsListItem {
4
+ title: string;
5
+ value: string;
6
+ }
7
+ /**
8
+ * The select options for a settings field, normalized from `StringField.list`'s
9
+ * loose shape (bare strings, or `{title, value}` objects) — empty when the field
10
+ * isn't a select.
11
+ *
12
+ * A `DependentList` yields no options: its valid values are a function of another
13
+ * field's value, which settings doesn't resolve. The panel renders such a field as a
14
+ * free-text input, so the validator must not treat it as a closed set either.
15
+ */
16
+ export declare function settingsListItems(field: SettingsField): SettingsListItem[];
17
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/settings.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,gBAAgB,EAAE,CAK1E"}
@@ -0,0 +1,22 @@
1
+ // Helpers for plugin settings declarations (`aphex/settings`).
2
+ //
3
+ // Shared by the settings panel (which renders the options) and PluginSettingsService
4
+ // (which validates a submitted value against them). They must agree: if they drift,
5
+ // the panel offers a choice the server rejects. So the normalization lives here once.
6
+ /**
7
+ * The select options for a settings field, normalized from `StringField.list`'s
8
+ * loose shape (bare strings, or `{title, value}` objects) — empty when the field
9
+ * isn't a select.
10
+ *
11
+ * A `DependentList` yields no options: its valid values are a function of another
12
+ * field's value, which settings doesn't resolve. The panel renders such a field as a
13
+ * free-text input, so the validator must not treat it as a closed set either.
14
+ */
15
+ export function settingsListItems(field) {
16
+ if (field.type !== 'string')
17
+ return [];
18
+ const list = field.list;
19
+ if (!Array.isArray(list))
20
+ return [];
21
+ return list.map((item) => (typeof item === 'string' ? { title: item, value: item } : item));
22
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;AAmB1D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,sFAAsF;AACtF,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAAyB,CAAC;AAEvE,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAYzC,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAAkD,CAAC;AAEzF;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAsNpE"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;AAmB1D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,sFAAsF;AACtF,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAAyB,CAAC;AAEvE,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAYzC,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAAkD,CAAC;AAEzF;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAmOpE"}
@@ -44,6 +44,17 @@ export const VALID_FIELD_TYPES = [...PRIMITIVE_FIELD_TYPES, 'array', 'object'];
44
44
  export function validateSchemaReferences(schemas) {
45
45
  const schemaNames = new Set(schemas.map((schema) => schema.name));
46
46
  const errors = [];
47
+ // Duplicate schema names are a hard error — no silent overrides. This matters
48
+ // most once plugins merge their schemas into the app's: a collision would
49
+ // otherwise let one type shadow another. Report every duplicate name once.
50
+ const nameCounts = new Map();
51
+ for (const schema of schemas)
52
+ nameCounts.set(schema.name, (nameCounts.get(schema.name) ?? 0) + 1);
53
+ for (const [name, count] of nameCounts) {
54
+ if (count > 1) {
55
+ errors.push(`Duplicate schema name "${name}" (defined ${count} times). Schema names must be unique across app and plugin schemas.`);
56
+ }
57
+ }
47
58
  // Field-type lists live at module scope (shared source of truth).
48
59
  const primitiveTypes = PRIMITIVE_FIELD_TYPES;
49
60
  const validFieldTypes = VALID_FIELD_TYPES;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Encrypt a plaintext string into a self-describing envelope
3
+ * `v1:<iv>:<authTag>:<ciphertext>` (base64 segments). Safe to store as an ordinary
4
+ * string in the settings blob.
5
+ */
6
+ export declare function encryptSecret(plaintext: string, secret: string): string;
7
+ /**
8
+ * Decrypt an envelope produced by {@link encryptSecret}. Throws if the envelope is
9
+ * malformed, the version is unknown, or authentication fails (wrong key / tampering).
10
+ */
11
+ export declare function decryptSecret(envelope: string, secret: string): string;
12
+ /**
13
+ * Whether a stored value looks like one of our encryption envelopes. Lets the service
14
+ * tell "already-encrypted ciphertext" from "a value that still needs encrypting"
15
+ * without trying to decrypt.
16
+ */
17
+ export declare function isEncryptedSecret(value: unknown): value is string;
18
+ //# sourceMappingURL=secret-crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-crypto.d.ts","sourceRoot":"","sources":["../../src/lib/security/secret-crypto.ts"],"names":[],"mappings":"AA6BA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CActE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEjE"}
@@ -0,0 +1,70 @@
1
+ // security/secret-crypto.ts
2
+ //
3
+ // Authenticated symmetric encryption for plugin secrets (the one genuinely-new
4
+ // brick of the settings/secrets feature — see references/plugin-settings-and-secrets-scope.md).
5
+ //
6
+ // SERVER ONLY: imports `node:crypto`. Never import this from client/admin code — a
7
+ // decrypted secret must never reach the browser. It's kept out of the cms-core client
8
+ // barrel deliberately.
9
+ //
10
+ // Design (mirrors the good ideas from Better Auth's `symmetricEncrypt`, without the
11
+ // dependency — cms-core stays auth-provider-agnostic):
12
+ // - AES-256-GCM: authenticated (AEAD), so tampering is detected on decrypt.
13
+ // - Random 96-bit IV per encryption (never reused).
14
+ // - Versioned envelope `v1:<iv>:<tag>:<ciphertext>` (all base64). The version prefix
15
+ // is what makes key rotation possible later: add `v2`, decrypt either, re-encrypt
16
+ // on next write — no data migration.
17
+ // - Key derived via SHA-256 so any-length configured secret becomes a valid 32-byte key.
18
+ import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'node:crypto';
19
+ const VERSION = 'v1';
20
+ const ALGORITHM = 'aes-256-gcm';
21
+ const IV_BYTES = 12; // 96-bit nonce, the GCM standard.
22
+ /** Derive a 32-byte AES key from an arbitrary-length configured secret. */
23
+ function deriveKey(secret) {
24
+ return createHash('sha256').update(secret, 'utf8').digest();
25
+ }
26
+ /**
27
+ * Encrypt a plaintext string into a self-describing envelope
28
+ * `v1:<iv>:<authTag>:<ciphertext>` (base64 segments). Safe to store as an ordinary
29
+ * string in the settings blob.
30
+ */
31
+ export function encryptSecret(plaintext, secret) {
32
+ const key = deriveKey(secret);
33
+ const iv = randomBytes(IV_BYTES);
34
+ const cipher = createCipheriv(ALGORITHM, key, iv);
35
+ const ciphertext = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
36
+ const authTag = cipher.getAuthTag();
37
+ return [
38
+ VERSION,
39
+ iv.toString('base64'),
40
+ authTag.toString('base64'),
41
+ ciphertext.toString('base64')
42
+ ].join(':');
43
+ }
44
+ /**
45
+ * Decrypt an envelope produced by {@link encryptSecret}. Throws if the envelope is
46
+ * malformed, the version is unknown, or authentication fails (wrong key / tampering).
47
+ */
48
+ export function decryptSecret(envelope, secret) {
49
+ const parts = envelope.split(':');
50
+ const [version, ivB64, tagB64, ctB64] = parts;
51
+ if (parts.length !== 4 || version !== VERSION || !ivB64 || !tagB64 || !ctB64) {
52
+ throw new Error('Malformed or unsupported secret envelope');
53
+ }
54
+ const key = deriveKey(secret);
55
+ const decipher = createDecipheriv(ALGORITHM, key, Buffer.from(ivB64, 'base64'));
56
+ decipher.setAuthTag(Buffer.from(tagB64, 'base64'));
57
+ const plaintext = Buffer.concat([
58
+ decipher.update(Buffer.from(ctB64, 'base64')),
59
+ decipher.final()
60
+ ]);
61
+ return plaintext.toString('utf8');
62
+ }
63
+ /**
64
+ * Whether a stored value looks like one of our encryption envelopes. Lets the service
65
+ * tell "already-encrypted ciphertext" from "a value that still needs encrypting"
66
+ * without trying to decrypt.
67
+ */
68
+ export function isEncryptedSecret(value) {
69
+ return typeof value === 'string' && value.startsWith(`${VERSION}:`);
70
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAoB7C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG;IACtB,SAAS,EAAE;QACV,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE;QACT,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,cAAc,kGAqB7B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,QAkDrD;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,IACtE,GAAG,OAAO,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,uBAejD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAqB7C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG;IACtB,SAAS,EAAE;QACV,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE;QACT,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,cAAc,kGAqB7B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,QAqDrD;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,IACtE,GAAG,OAAO,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,uBAejD"}
@@ -16,6 +16,7 @@ import { organizationsInvitationsRouter } from './routes/organizations-invitatio
16
16
  import { organizationsMembersRouter } from './routes/organizations-members.js';
17
17
  import { organizationsSwitchRouter } from './routes/organizations-switch.js';
18
18
  import { rolesRouter } from './routes/roles.js';
19
+ import { pluginSettingsRouter } from './routes/plugin-settings.js';
19
20
  import { userPreferencesRouter } from './routes/user-preferences.js';
20
21
  import { userRouter } from './routes/user.js';
21
22
  /**
@@ -77,6 +78,8 @@ export function mountAphexBuiltins(app) {
77
78
  app.route('/organizations', organizationsRouter);
78
79
  // Roles — combined router covers /, /:name, no precedence concern.
79
80
  app.route('/roles', rolesRouter);
81
+ // Plugin settings — the config plane. `/`, `/:pluginId`, no precedence concern.
82
+ app.route('/plugin-settings', pluginSettingsRouter);
80
83
  // User account routes — register specifics first.
81
84
  // `/user/cms-preference`, `/user/request-password-reset`,
82
85
  // `/user/reset-password` need to win over `/user` PATCH otherwise
@@ -1 +1 @@
1
- {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IAAI,CAAC,QAAQ,CA8JrC,CAAC"}
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IAAI,CAAC,QAAQ,CAoKrC,CAAC"}
@@ -25,6 +25,7 @@ export const assetsRouter = new Hono()
25
25
  assetType: q.assetType,
26
26
  mimeType: q.mimeType,
27
27
  search: q.search,
28
+ includeSystem: q.includeSystem ?? false,
28
29
  limit: q.limit ?? 20,
29
30
  offset: q.offset ?? 0
30
31
  };
@@ -34,7 +35,8 @@ export const assetsRouter = new Hono()
34
35
  databaseAdapter.countAssets(auth.organizationId, {
35
36
  assetType: filters.assetType,
36
37
  mimeType: filters.mimeType,
37
- search: filters.search
38
+ search: filters.search,
39
+ includeSystem: filters.includeSystem
38
40
  })
39
41
  ]);
40
42
  const pageSize = filters.limit || 20;
@@ -101,6 +103,8 @@ export const assetsRouter = new Hono()
101
103
  const creditLine = formData.get('creditLine') || undefined;
102
104
  const schemaType = formData.get('schemaType') || undefined;
103
105
  const fieldPath = formData.get('fieldPath') || undefined;
106
+ const system = formData.get('system') === 'true' || undefined;
107
+ const usage = formData.get('usage') || undefined;
104
108
  const targetOrganizationId = auth.organizationId;
105
109
  const uploadData = {
106
110
  organizationId: targetOrganizationId,
@@ -115,7 +119,9 @@ export const assetsRouter = new Hono()
115
119
  createdBy: auth.type === 'session' ? auth.user.id : undefined,
116
120
  metadata: {
117
121
  schemaType,
118
- fieldPath
122
+ fieldPath,
123
+ system,
124
+ usage
119
125
  }
120
126
  };
121
127
  const asset = await assetService.uploadAsset(targetOrganizationId, uploadData);
@@ -1 +1 @@
1
- {"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/organizations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,mBAAmB,EAAE,IAAI,CAAC,QAAQ,CA8H7C,CAAC"}
1
+ {"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/organizations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,mBAAmB,EAAE,IAAI,CAAC,QAAQ,CAoI7C,CAAC"}
@@ -78,7 +78,10 @@ export const organizationsRouter = new Hono()
78
78
  parentOrganizationId: auth.organizationId,
79
79
  createdBy: auth.user.id
80
80
  });
81
- await databaseAdapter.seedBuiltinRoles(newOrganization.id);
81
+ // Seed with the install's full capability set (core + plugin-declared), the
82
+ // same one the boot reconcile uses — otherwise a brand-new org's owner would
83
+ // be missing every capability its plugins declare until the next restart.
84
+ await databaseAdapter.seedBuiltinRoles(newOrganization.id, c.var.aphexCMS.cmsEngine.ownerCapabilities());
82
85
  await databaseAdapter.addMember({
83
86
  organizationId: newOrganization.id,
84
87
  userId: auth.user.id,
@@ -0,0 +1,4 @@
1
+ import { Hono } from 'hono';
2
+ import type { AphexEnv } from '../index.js';
3
+ export declare const pluginSettingsRouter: Hono<AphexEnv>;
4
+ //# sourceMappingURL=plugin-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-settings.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/plugin-settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AA6DzC,eAAO,MAAM,oBAAoB,EAAE,IAAI,CAAC,QAAQ,CA2E7C,CAAC"}
@@ -0,0 +1,108 @@
1
+ import { Hono } from 'hono';
2
+ import { zValidator } from '@hono/zod-validator';
3
+ import { cmsLogger } from '../../../utils/logger.js';
4
+ import { hasCapability } from '../../../types/capabilities.js';
5
+ import { savePluginSettingsRequest } from '../../../api/schemas/plugin-settings.js';
6
+ import { PluginSettingsValidationError } from '../../../services/plugin-settings-service.js';
7
+ /**
8
+ * Require a session with `plugin.settings.manage`. Returns the narrowed session auth
9
+ * to proceed, or a 401/403 Response to short-circuit — so callers get a typed org id
10
+ * without a non-null assertion.
11
+ */
12
+ function requireManage(c) {
13
+ const auth = c.var.auth;
14
+ if (!auth || auth.type !== 'session') {
15
+ return c.json({ success: false, error: 'Unauthorized', message: 'Session authentication required' }, 401);
16
+ }
17
+ if (!hasCapability(auth, 'plugin.settings.manage')) {
18
+ return c.json({
19
+ success: false,
20
+ error: 'Forbidden',
21
+ message: 'The plugin.settings.manage capability is required'
22
+ }, 403);
23
+ }
24
+ return auth;
25
+ }
26
+ /**
27
+ * Does this session satisfy a settings section's own `requiredCapabilities`?
28
+ *
29
+ * `plugin.settings.manage` is the floor, checked by `requireManage`. A declaration may
30
+ * additionally name narrower capabilities to gate itself more tightly — the part's
31
+ * documented contract, and the same convention `hooks.ts` applies to plugin routes and
32
+ * `resolver.ts` applies to actions and tools. Without this the declared gate was
33
+ * silently ignored, so anyone who could manage settings could overwrite every plugin's
34
+ * secrets regardless of what the plugin asked for.
35
+ */
36
+ function canAccessSettings(auth, required) {
37
+ if (!required || required.length === 0)
38
+ return true;
39
+ return required.every((capability) => hasCapability(auth, capability));
40
+ }
41
+ export const pluginSettingsRouter = new Hono()
42
+ .get('/', async (c) => {
43
+ try {
44
+ const auth = requireManage(c);
45
+ if (auth instanceof Response)
46
+ return auth;
47
+ const { pluginSettingsService, partResolver } = c.var.aphexCMS;
48
+ // One entry per plugin that declared settings AND that this session is
49
+ // allowed to see, with the org's effective values. `getMasked` — never
50
+ // `get` — so secret plaintext never reaches the client (secrets come back
51
+ // as a mask placeholder).
52
+ const declarations = partResolver
53
+ .settingsDeclarations()
54
+ .filter((decl) => canAccessSettings(auth, decl.requiredCapabilities));
55
+ const secretsEnabled = pluginSettingsService.secretsEnabled;
56
+ const data = await Promise.all(declarations.map(async (decl) => ({
57
+ pluginId: decl.pluginId,
58
+ title: decl.title,
59
+ values: await pluginSettingsService.getMasked(auth.organizationId, decl.pluginId)
60
+ })));
61
+ return c.json({ success: true, data, secretsEnabled });
62
+ }
63
+ catch (error) {
64
+ cmsLogger.error('Failed to list plugin settings:', error);
65
+ return c.json({ success: false, error: 'Internal error' }, 500);
66
+ }
67
+ })
68
+ .put('/:pluginId', zValidator('json', savePluginSettingsRequest), async (c) => {
69
+ try {
70
+ const auth = requireManage(c);
71
+ if (auth instanceof Response)
72
+ return auth;
73
+ const { pluginSettingsService, partResolver } = c.var.aphexCMS;
74
+ const pluginId = c.req.param('pluginId');
75
+ // Reject plugins that never declared settings — nothing to write to.
76
+ const declaration = partResolver.settingsDeclaration(pluginId);
77
+ if (!declaration) {
78
+ return c.json({
79
+ success: false,
80
+ error: 'Unknown plugin settings',
81
+ message: `Plugin "${pluginId}" has not declared any settings.`
82
+ }, 404);
83
+ }
84
+ // Honour the declaration's own gate. GET only ever returns masked secrets,
85
+ // so the exposure this closes is write: without it, anyone holding
86
+ // `plugin.settings.manage` could overwrite the secrets of a plugin that
87
+ // asked for a narrower capability.
88
+ if (!canAccessSettings(auth, declaration.requiredCapabilities)) {
89
+ return c.json({
90
+ success: false,
91
+ error: 'Forbidden',
92
+ message: `Plugin "${pluginId}" requires: ${declaration.requiredCapabilities?.join(', ')}`
93
+ }, 403);
94
+ }
95
+ const { values } = c.req.valid('json');
96
+ const saved = await pluginSettingsService.save(auth.organizationId, pluginId, values);
97
+ return c.json({ success: true, data: { pluginId, values: saved } });
98
+ }
99
+ catch (error) {
100
+ // A value that doesn't match its declared field type is the caller's fault, not
101
+ // ours — report it as such, with the specific issues, rather than an opaque 500.
102
+ if (error instanceof PluginSettingsValidationError) {
103
+ return c.json({ success: false, error: 'Validation failed', issues: error.issues }, 400);
104
+ }
105
+ cmsLogger.error('Failed to save plugin settings:', error);
106
+ return c.json({ success: false, error: 'Internal error' }, 500);
107
+ }
108
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/roles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,EAAE,IAAI,CAAC,QAAQ,CAuSpC,CAAC"}
1
+ {"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/roles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAwBzC;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,EAAE,IAAI,CAAC,QAAQ,CA+TpC,CAAC"}
@@ -3,6 +3,24 @@ import { zValidator } from '@hono/zod-validator';
3
3
  import { cmsLogger } from '../../../utils/logger.js';
4
4
  import { hasCapability, BUILTIN_ROLE_NAMES } from '../../../types/capabilities.js';
5
5
  import { createRoleRequest, updateRoleRequest } from '../../../api/schemas/roles.js';
6
+ /**
7
+ * Authoritative capability validation against the runtime registry. The zod schema
8
+ * only guards the id *format*; this rejects ids that don't actually exist in the
9
+ * catalog (built-in + plugin-declared), so a role can't be granted a phantom
10
+ * capability. Returns a 400 Response to short-circuit, or null when all are valid.
11
+ */
12
+ function rejectUnknownCapabilities(c, caps) {
13
+ const known = new Set(c.var.aphexCMS.partResolver.capabilityCatalog().map((d) => d.id));
14
+ const unknown = caps.filter((cap) => !known.has(cap));
15
+ if (unknown.length === 0)
16
+ return null;
17
+ return c.json({
18
+ success: false,
19
+ error: 'Unknown capability',
20
+ message: `These capabilities are not registered: ${unknown.join(', ')}`,
21
+ unknownCapabilities: unknown
22
+ }, 400);
23
+ }
6
24
  /**
7
25
  * Roles router. Combines `/roles` (list, create) and `/roles/:name`
8
26
  * (update, delete) so the wire URLs are
@@ -63,6 +81,9 @@ export const rolesRouter = new Hono()
63
81
  }, 403);
64
82
  }
65
83
  const body = c.req.valid('json');
84
+ const badCaps = rejectUnknownCapabilities(c, body.capabilities);
85
+ if (badCaps)
86
+ return badCaps;
66
87
  if (BUILTIN_ROLE_NAMES.includes(body.name)) {
67
88
  return c.json({
68
89
  success: false,
@@ -132,6 +153,22 @@ export const rolesRouter = new Hono()
132
153
  }, 400);
133
154
  }
134
155
  const body = c.req.valid('json');
156
+ // `owner` is defined as "every capability" and is reconciled back to the
157
+ // full set on every boot, so accepting an edit here would appear to work
158
+ // and then silently revert on the next restart. Same reasoning as the
159
+ // hardcoded block on deleting built-in roles below.
160
+ if (name === 'owner' && body.capabilities !== undefined) {
161
+ return c.json({
162
+ success: false,
163
+ error: 'Forbidden',
164
+ message: '"owner" always holds every capability and its permissions cannot be changed. Create a custom role to grant narrower access.'
165
+ }, 403);
166
+ }
167
+ if (body.capabilities) {
168
+ const badCaps = rejectUnknownCapabilities(c, body.capabilities);
169
+ if (badCaps)
170
+ return badCaps;
171
+ }
135
172
  const updated = await databaseAdapter.updateRole(auth.organizationId, name, body);
136
173
  if (!updated) {
137
174
  return c.json({
@@ -1 +1 @@
1
- {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAQ5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,EAAE,IAAI,CAAC,QAAQ,CA6IpC,CAAC"}
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAQ5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,EAAE,IAAI,CAAC,QAAQ,CA2JpC,CAAC"}
@@ -16,7 +16,7 @@ export const userRouter = new Hono()
16
16
  return c.json({
17
17
  success: false,
18
18
  error: 'Invalid request body',
19
- message: 'name is required',
19
+ message: 'name or image is required',
20
20
  issues: result.error.issues
21
21
  }, 400);
22
22
  }
@@ -37,8 +37,19 @@ export const userRouter = new Hono()
37
37
  error: 'Auth provider not configured'
38
38
  }, 500);
39
39
  }
40
- const { name } = c.req.valid('json');
41
- await provider.changeUserName(auth.user.id, name);
40
+ const { name, image } = c.req.valid('json');
41
+ if (name !== undefined) {
42
+ await provider.changeUserName(auth.user.id, name);
43
+ }
44
+ if (image !== undefined) {
45
+ if (!provider.changeUserImage) {
46
+ return c.json({
47
+ success: false,
48
+ error: 'Auth provider does not support profile image updates'
49
+ }, 500);
50
+ }
51
+ await provider.changeUserImage(auth.user.id, image);
52
+ }
42
53
  return c.json({ success: true, message: 'User updated successfully' });
43
54
  }
44
55
  catch (error) {
@@ -21,6 +21,7 @@ export interface AssetFilters {
21
21
  assetType?: 'image' | 'file';
22
22
  mimeType?: string;
23
23
  search?: string;
24
+ includeSystem?: boolean;
24
25
  limit?: number;
25
26
  offset?: number;
26
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"asset-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/asset-service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAI5C,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IAIrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE;QACV,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACnB,CAAC;CACF;AAED,MAAM,WAAW,YAAY;IAC5B,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,YAAY;IAEvB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;gBADR,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,eAAe;IAGlC;;OAEG;IACG,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC;IAsFhF;;OAEG;IACG,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAI9E;;;;;;;;;;OAUG;IACG,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBhF;;;OAGG;IACG,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAmB5D;;OAEG;IACG,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAItF;;;;;OAKG;IACG,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BvE;;OAEG;IACG,mBAAmB,CACxB,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE;QACT,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GACC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAIxB;;OAEG;IACG,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QACpD,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KAClB,CAAC;IAeF;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC;QAChC,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;KAClB,CAAC;CAWF"}
1
+ {"version":3,"file":"asset-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/asset-service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAI5C,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IAIrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE;QACV,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACnB,CAAC;CACF;AAED,MAAM,WAAW,YAAY;IAC5B,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,YAAY;IAEvB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;gBADR,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,eAAe;IAGlC;;OAEG;IACG,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC;IAsFhF;;OAEG;IACG,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAI9E;;;;;;;;;;OAUG;IACG,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBhF;;;OAGG;IACG,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAmB5D;;OAEG;IACG,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAItF;;;;;OAKG;IACG,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BvE;;OAEG;IACG,mBAAmB,CACxB,cAAc,EAAE,MAAM,EACtB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE;QACT,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GACC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAIxB;;OAEG;IACG,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QACpD,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KAClB,CAAC;IAeF;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC;QAChC,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;KAClB,CAAC;CAWF"}
@@ -3,4 +3,6 @@ export type { AssetUploadData, AssetFilters } from './asset-service.js';
3
3
  export { HierarchyService } from './hierarchy-service.js';
4
4
  export { RolesService } from './roles-service.js';
5
5
  export { VersionService } from './version-service.js';
6
+ export { PluginSettingsService } from './plugin-settings-service.js';
7
+ export type { ResolvedSettings } from './plugin-settings-service.js';
6
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/services/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/services/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -5,3 +5,4 @@ export { AssetService } from './asset-service.js';
5
5
  export { HierarchyService } from './hierarchy-service.js';
6
6
  export { RolesService } from './roles-service.js';
7
7
  export { VersionService } from './version-service.js';
8
+ export { PluginSettingsService } from './plugin-settings-service.js';
@@ -0,0 +1,76 @@
1
+ import type { DatabaseAdapter } from '../db/index.js';
2
+ import type { PartResolver } from '../plugins/resolver.js';
3
+ import type { SettingsPart } from '../plugins/types.js';
4
+ /** Placeholder shown to the client for a secret that has a stored value. */
5
+ export declare const SECRET_MASK = "\u2022\u2022\u2022\u2022\u2022\u2022";
6
+ /**
7
+ * The persistence this service needs — the settings slice of `DatabaseAdapter`, which
8
+ * satisfies it structurally. Declaring the narrow dependency rather than the whole
9
+ * adapter keeps the service honest about its reach (config values only, never content)
10
+ * and lets it be constructed against a stub.
11
+ */
12
+ export type PluginSettingsStore = Pick<DatabaseAdapter, 'getPluginSettings' | 'setPluginSettings'>;
13
+ /** Likewise the resolver slice: this service only ever looks up settings declarations. */
14
+ export type SettingsDeclarationSource = Pick<PartResolver, 'settingsDeclaration'>;
15
+ /** A declared settings section plus whether the plugin registered one at all. */
16
+ export interface ResolvedSettings {
17
+ /** The plugin's settings declaration, or `null` if it declared none. */
18
+ declaration: SettingsPart | null;
19
+ /** Declared defaults merged with the org's stored values (secrets masked). */
20
+ values: Record<string, unknown>;
21
+ /** Whether an encryption key is configured — the UI flags secret fields read-only if not. */
22
+ secretsEnabled: boolean;
23
+ }
24
+ /** Raised when a submitted value doesn't match its declared field type. */
25
+ export declare class PluginSettingsValidationError extends Error {
26
+ readonly issues: string[];
27
+ constructor(issues: string[]);
28
+ }
29
+ export declare class PluginSettingsService {
30
+ /** Narrowed to the two methods this service uses — the full adapter satisfies it. */
31
+ private db;
32
+ /** Likewise: settings resolution is the only part of the resolver needed here. */
33
+ private resolver;
34
+ /** Key for encrypting `secret` fields; when absent, secrets are disabled (fail safe). */
35
+ private encryptionKey;
36
+ constructor(
37
+ /** Narrowed to the two methods this service uses — the full adapter satisfies it. */
38
+ db: PluginSettingsStore,
39
+ /** Likewise: settings resolution is the only part of the resolver needed here. */
40
+ resolver: SettingsDeclarationSource,
41
+ /** Key for encrypting `secret` fields; when absent, secrets are disabled (fail safe). */
42
+ encryptionKey?: string | null);
43
+ /** Whether secret fields can be stored/read (an encryption key is configured). */
44
+ get secretsEnabled(): boolean;
45
+ private secretFieldNames;
46
+ /**
47
+ * Effective values for injection into plugin **server** code: declared defaults
48
+ * overlaid with stored values, with secrets **decrypted** to plaintext. Secrets
49
+ * that can't be decrypted (no key, or a bad envelope) are omitted, never returned
50
+ * as ciphertext. This is the sensitive read — never send its result to a client.
51
+ */
52
+ get(organizationId: string, pluginId: string): Promise<Record<string, unknown>>;
53
+ /**
54
+ * Effective values for the **client/API**: same merge, but secrets are **masked** —
55
+ * a stored secret becomes {@link SECRET_MASK}, an unset one an empty string. Plaintext
56
+ * secrets never cross this boundary.
57
+ */
58
+ getMasked(organizationId: string, pluginId: string): Promise<Record<string, unknown>>;
59
+ /**
60
+ * Resolve for the admin surface: the declaration plus masked values plus whether
61
+ * secrets are enabled. `declaration: null` when the plugin declares no settings.
62
+ */
63
+ resolve(organizationId: string, pluginId: string): Promise<ResolvedSettings>;
64
+ /**
65
+ * Persist a partial edit. Only declared field names are accepted, and each value is
66
+ * type-checked against its declaration — an invalid patch is rejected whole, never
67
+ * applied in part, so a failed save can't leave settings half-written. Secret fields
68
+ * are encrypted; a blank or still-masked secret submission means "leave unchanged"
69
+ * (so the client never has to echo the real value back). Returns the new **masked**
70
+ * values — a save response never leaks a plaintext secret.
71
+ *
72
+ * @throws {PluginSettingsValidationError} when a value doesn't match its field type.
73
+ */
74
+ save(organizationId: string, pluginId: string, patch: Record<string, unknown>): Promise<Record<string, unknown>>;
75
+ }
76
+ //# sourceMappingURL=plugin-settings-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-settings-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/plugin-settings-service.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAMrD,4EAA4E;AAC5E,eAAO,MAAM,WAAW,yCAAW,CAAC;AAEpC;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,eAAe,EAAE,mBAAmB,GAAG,mBAAmB,CAAC,CAAC;AAEnG,0FAA0F;AAC1F,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,YAAY,EAAE,qBAAqB,CAAC,CAAC;AAElF,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAChC,wEAAwE;IACxE,WAAW,EAAE,YAAY,GAAG,IAAI,CAAC;IACjC,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,6FAA6F;IAC7F,cAAc,EAAE,OAAO,CAAC;CACxB;AAwBD,2EAA2E;AAC3E,qBAAa,6BAA8B,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE;gBAAhB,MAAM,EAAE,MAAM,EAAE;CAIrC;AAkDD,qBAAa,qBAAqB;IAEhC,qFAAqF;IACrF,OAAO,CAAC,EAAE;IACV,kFAAkF;IAClF,OAAO,CAAC,QAAQ;IAChB,yFAAyF;IACzF,OAAO,CAAC,aAAa;;IALrB,qFAAqF;IAC7E,EAAE,EAAE,mBAAmB;IAC/B,kFAAkF;IAC1E,QAAQ,EAAE,yBAAyB;IAC3C,yFAAyF;IACjF,aAAa,GAAE,MAAM,GAAG,IAAW;IAG5C,kFAAkF;IAClF,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,OAAO,CAAC,gBAAgB;IAIxB;;;;;OAKG;IACG,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IA6BrF;;;;OAIG;IACG,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAc3F;;;OAGG;IACG,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAMlF;;;;;;;;;OASG;IACG,IAAI,CACT,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CA2CnC"}