@aphexcms/cms-core 9.3.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 (431) 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 +10 -5
  37. package/dist/cli/generate-types.d.ts.map +1 -1
  38. package/dist/cli/generate-types.js +117 -77
  39. package/dist/cli/generate-types.js.map +1 -1
  40. package/dist/cli/index.js +5 -5
  41. package/dist/cli/index.js.map +1 -1
  42. package/dist/cli/migrate.d.ts +1 -1
  43. package/dist/cli/migrate.d.ts.map +1 -1
  44. package/dist/cli/migrate.js +27 -2
  45. package/dist/cli/migrate.js.map +1 -1
  46. package/dist/client/index.d.ts +6 -0
  47. package/dist/client/index.d.ts.map +1 -1
  48. package/dist/client/index.js +9 -0
  49. package/dist/components/AdminApp.svelte +271 -113
  50. package/dist/components/AdminApp.svelte.d.ts +18 -2
  51. package/dist/components/AdminApp.svelte.d.ts.map +1 -1
  52. package/dist/components/admin/AdminSlot.svelte +18 -0
  53. package/dist/components/admin/AdminSlot.svelte.d.ts +12 -0
  54. package/dist/components/admin/AdminSlot.svelte.d.ts.map +1 -0
  55. package/dist/components/admin/DocumentEditor.svelte +646 -385
  56. package/dist/components/admin/DocumentEditor.svelte.d.ts +13 -0
  57. package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
  58. package/dist/components/admin/MediaBrowser.svelte +13 -3
  59. package/dist/components/admin/MediaBrowser.svelte.d.ts.map +1 -1
  60. package/dist/components/admin/PluginSettingsPanel.svelte +231 -0
  61. package/dist/components/admin/PluginSettingsPanel.svelte.d.ts +8 -0
  62. package/dist/components/admin/PluginSettingsPanel.svelte.d.ts.map +1 -0
  63. package/dist/components/admin/SchemaField.svelte +76 -95
  64. package/dist/components/admin/SchemaField.svelte.d.ts +7 -0
  65. package/dist/components/admin/SchemaField.svelte.d.ts.map +1 -1
  66. package/dist/components/admin/fields/ArrayField.svelte +24 -2
  67. package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
  68. package/dist/components/admin/fields/FieldInput.svelte +109 -0
  69. package/dist/components/admin/fields/FieldInput.svelte.d.ts +17 -0
  70. package/dist/components/admin/fields/FieldInput.svelte.d.ts.map +1 -0
  71. package/dist/components/admin/fields/richtext/PortableTextImageView.svelte +5 -12
  72. package/dist/components/admin/fields/richtext/PortableTextImageView.svelte.d.ts +2 -9
  73. package/dist/components/admin/fields/richtext/PortableTextImageView.svelte.d.ts.map +1 -1
  74. package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte +18 -17
  75. package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte.d.ts +2 -9
  76. package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte.d.ts.map +1 -1
  77. package/dist/components/admin/fields/richtext/RichtextField.svelte +55 -2
  78. package/dist/components/admin/fields/richtext/RichtextField.svelte.d.ts.map +1 -1
  79. package/dist/components/admin/fields/richtext/portable-text-object-node.d.ts +7 -0
  80. package/dist/components/admin/fields/richtext/portable-text-object-node.d.ts.map +1 -1
  81. package/dist/components/admin/fields/richtext/portable-text-object-node.js +4 -2
  82. package/dist/components/admin/fields/richtext/svelte-node-view.d.ts +16 -1
  83. package/dist/components/admin/fields/richtext/svelte-node-view.d.ts.map +1 -1
  84. package/dist/components/admin/fields/richtext/svelte-node-view.js +20 -1
  85. package/dist/components/layout/OrganizationSwitcher.svelte +31 -10
  86. package/dist/components/layout/OrganizationSwitcher.svelte.d.ts.map +1 -1
  87. package/dist/components/layout/Sidebar.svelte +49 -11
  88. package/dist/components/layout/Sidebar.svelte.d.ts +5 -1
  89. package/dist/components/layout/Sidebar.svelte.d.ts.map +1 -1
  90. package/dist/components/layout/sidebar/AppSidebar.svelte +66 -3
  91. package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts +5 -0
  92. package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts.map +1 -1
  93. package/dist/components/layout/sidebar/NavMain.svelte +3 -2
  94. package/dist/components/layout/sidebar/NavMain.svelte.d.ts +4 -3
  95. package/dist/components/layout/sidebar/NavMain.svelte.d.ts.map +1 -1
  96. package/dist/components/layout/sidebar/NavUser.svelte +5 -1
  97. package/dist/config.d.ts.map +1 -1
  98. package/dist/config.js +11 -0
  99. package/dist/db/interfaces/asset.d.ts +1 -0
  100. package/dist/db/interfaces/asset.d.ts.map +1 -1
  101. package/dist/db/interfaces/index.d.ts +3 -1
  102. package/dist/db/interfaces/index.d.ts.map +1 -1
  103. package/dist/db/interfaces/plugin-settings.d.ts +23 -0
  104. package/dist/db/interfaces/plugin-settings.d.ts.map +1 -0
  105. package/dist/db/interfaces/plugin-settings.js +13 -0
  106. package/dist/db/interfaces/role.d.ts +14 -5
  107. package/dist/db/interfaces/role.d.ts.map +1 -1
  108. package/dist/engine.d.ts +28 -0
  109. package/dist/engine.d.ts.map +1 -1
  110. package/dist/engine.js +44 -0
  111. package/dist/field-validation/utils.d.ts +15 -0
  112. package/dist/field-validation/utils.d.ts.map +1 -1
  113. package/dist/field-validation/utils.js +74 -0
  114. package/dist/graphql/resolvers.d.ts.map +1 -1
  115. package/dist/graphql/resolvers.js +9 -10
  116. package/dist/graphql/schema.d.ts.map +1 -1
  117. package/dist/graphql/schema.js +18 -19
  118. package/dist/hooks.d.ts +6 -0
  119. package/dist/hooks.d.ts.map +1 -1
  120. package/dist/hooks.js +59 -2
  121. package/dist/index.d.ts +2 -0
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +5 -0
  124. package/dist/lib/admin/block-previews.svelte.d.ts +46 -0
  125. package/dist/lib/admin/block-previews.svelte.d.ts.map +1 -0
  126. package/dist/lib/admin/block-previews.svelte.js +27 -0
  127. package/dist/lib/admin/block-previews.svelte.js.map +1 -0
  128. package/dist/lib/admin/field-components.svelte.d.ts +16 -0
  129. package/dist/lib/admin/field-components.svelte.d.ts.map +1 -0
  130. package/dist/lib/admin/field-components.svelte.js +19 -0
  131. package/dist/lib/admin/field-components.svelte.js.map +1 -0
  132. package/dist/lib/admin/nav.svelte.d.ts +34 -0
  133. package/dist/lib/admin/nav.svelte.d.ts.map +1 -0
  134. package/dist/lib/admin/nav.svelte.js +79 -0
  135. package/dist/lib/admin/nav.svelte.js.map +1 -0
  136. package/dist/lib/admin/slots.svelte.d.ts +50 -0
  137. package/dist/lib/admin/slots.svelte.d.ts.map +1 -0
  138. package/dist/lib/admin/slots.svelte.js +68 -0
  139. package/dist/lib/admin/slots.svelte.js.map +1 -0
  140. package/dist/lib/admin/types.d.ts +7 -0
  141. package/dist/lib/admin/types.d.ts.map +1 -0
  142. package/dist/lib/admin/types.js +2 -0
  143. package/dist/lib/admin/types.js.map +1 -0
  144. package/dist/lib/api/schemas/api-keys.d.ts +4 -37
  145. package/dist/lib/api/schemas/api-keys.d.ts.map +1 -1
  146. package/dist/lib/api/schemas/api-keys.js +5 -2
  147. package/dist/lib/api/schemas/api-keys.js.map +1 -1
  148. package/dist/lib/api/schemas/assets.d.ts +4 -0
  149. package/dist/lib/api/schemas/assets.d.ts.map +1 -1
  150. package/dist/lib/api/schemas/assets.js +3 -0
  151. package/dist/lib/api/schemas/assets.js.map +1 -1
  152. package/dist/lib/api/schemas/plugin-settings.d.ts +6 -0
  153. package/dist/lib/api/schemas/plugin-settings.d.ts.map +1 -0
  154. package/dist/lib/api/schemas/plugin-settings.js +9 -0
  155. package/dist/lib/api/schemas/plugin-settings.js.map +1 -0
  156. package/dist/lib/api/schemas/roles.d.ts +7 -56
  157. package/dist/lib/api/schemas/roles.d.ts.map +1 -1
  158. package/dist/lib/api/schemas/roles.js +11 -6
  159. package/dist/lib/api/schemas/roles.js.map +1 -1
  160. package/dist/lib/api/schemas/user.d.ts +2 -1
  161. package/dist/lib/api/schemas/user.d.ts.map +1 -1
  162. package/dist/lib/api/schemas/user.js +7 -2
  163. package/dist/lib/api/schemas/user.js.map +1 -1
  164. package/dist/lib/app-augment.d.ts +11 -0
  165. package/dist/lib/app-augment.d.ts.map +1 -1
  166. package/dist/lib/auth/provider.d.ts +3 -0
  167. package/dist/lib/auth/provider.d.ts.map +1 -1
  168. package/dist/lib/client/index.d.ts +6 -0
  169. package/dist/lib/client/index.d.ts.map +1 -1
  170. package/dist/lib/client/index.js +9 -0
  171. package/dist/lib/client/index.js.map +1 -1
  172. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.d.ts +7 -0
  173. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.d.ts.map +1 -1
  174. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.js +4 -2
  175. package/dist/lib/components/admin/fields/richtext/portable-text-object-node.js.map +1 -1
  176. package/dist/lib/components/admin/fields/richtext/svelte-node-view.d.ts +16 -1
  177. package/dist/lib/components/admin/fields/richtext/svelte-node-view.d.ts.map +1 -1
  178. package/dist/lib/components/admin/fields/richtext/svelte-node-view.js +20 -1
  179. package/dist/lib/components/admin/fields/richtext/svelte-node-view.js.map +1 -1
  180. package/dist/lib/config.d.ts.map +1 -1
  181. package/dist/lib/config.js +11 -0
  182. package/dist/lib/config.js.map +1 -1
  183. package/dist/lib/db/interfaces/asset.d.ts +1 -0
  184. package/dist/lib/db/interfaces/asset.d.ts.map +1 -1
  185. package/dist/lib/db/interfaces/index.d.ts +3 -1
  186. package/dist/lib/db/interfaces/index.d.ts.map +1 -1
  187. package/dist/lib/db/interfaces/plugin-settings.d.ts +23 -0
  188. package/dist/lib/db/interfaces/plugin-settings.d.ts.map +1 -0
  189. package/dist/lib/db/interfaces/plugin-settings.js +14 -0
  190. package/dist/lib/db/interfaces/plugin-settings.js.map +1 -0
  191. package/dist/lib/db/interfaces/role.d.ts +14 -5
  192. package/dist/lib/db/interfaces/role.d.ts.map +1 -1
  193. package/dist/lib/engine.d.ts +28 -0
  194. package/dist/lib/engine.d.ts.map +1 -1
  195. package/dist/lib/engine.js +44 -0
  196. package/dist/lib/engine.js.map +1 -1
  197. package/dist/lib/field-validation/utils.d.ts +15 -0
  198. package/dist/lib/field-validation/utils.d.ts.map +1 -1
  199. package/dist/lib/field-validation/utils.js +74 -0
  200. package/dist/lib/field-validation/utils.js.map +1 -1
  201. package/dist/lib/graphql/resolvers.d.ts.map +1 -1
  202. package/dist/lib/graphql/resolvers.js +9 -10
  203. package/dist/lib/graphql/resolvers.js.map +1 -1
  204. package/dist/lib/graphql/schema.d.ts.map +1 -1
  205. package/dist/lib/graphql/schema.js +18 -19
  206. package/dist/lib/graphql/schema.js.map +1 -1
  207. package/dist/lib/hooks.d.ts +6 -0
  208. package/dist/lib/hooks.d.ts.map +1 -1
  209. package/dist/lib/hooks.js +59 -2
  210. package/dist/lib/hooks.js.map +1 -1
  211. package/dist/lib/index.d.ts +2 -0
  212. package/dist/lib/index.d.ts.map +1 -1
  213. package/dist/lib/index.js +5 -0
  214. package/dist/lib/index.js.map +1 -1
  215. package/dist/lib/local-api/collection-api.d.ts.map +1 -1
  216. package/dist/lib/local-api/collection-api.js +4 -2
  217. package/dist/lib/local-api/collection-api.js.map +1 -1
  218. package/dist/lib/local-api/types.d.ts +8 -0
  219. package/dist/lib/local-api/types.d.ts.map +1 -1
  220. package/dist/lib/mcp/tools.d.ts.map +1 -1
  221. package/dist/lib/mcp/tools.js +110 -1
  222. package/dist/lib/mcp/tools.js.map +1 -1
  223. package/dist/lib/permissions-context.svelte.d.ts +7 -4
  224. package/dist/lib/permissions-context.svelte.d.ts.map +1 -1
  225. package/dist/lib/permissions-context.svelte.js.map +1 -1
  226. package/dist/lib/plugins/index.d.ts +3 -0
  227. package/dist/lib/plugins/index.d.ts.map +1 -0
  228. package/dist/lib/plugins/index.js +3 -0
  229. package/dist/lib/plugins/index.js.map +1 -0
  230. package/dist/lib/plugins/resolver.d.ts +49 -0
  231. package/dist/lib/plugins/resolver.d.ts.map +1 -0
  232. package/dist/lib/plugins/resolver.js +66 -0
  233. package/dist/lib/plugins/resolver.js.map +1 -0
  234. package/dist/lib/plugins/types.d.ts +233 -0
  235. package/dist/lib/plugins/types.d.ts.map +1 -0
  236. package/dist/lib/plugins/types.js +9 -0
  237. package/dist/lib/plugins/types.js.map +1 -0
  238. package/dist/lib/schema-utils/desugar.d.ts +27 -0
  239. package/dist/lib/schema-utils/desugar.d.ts.map +1 -0
  240. package/dist/lib/schema-utils/desugar.js +102 -0
  241. package/dist/lib/schema-utils/desugar.js.map +1 -0
  242. package/dist/lib/schema-utils/index.d.ts +2 -0
  243. package/dist/lib/schema-utils/index.d.ts.map +1 -1
  244. package/dist/lib/schema-utils/index.js +2 -0
  245. package/dist/lib/schema-utils/index.js.map +1 -1
  246. package/dist/lib/schema-utils/settings.d.ts +17 -0
  247. package/dist/lib/schema-utils/settings.d.ts.map +1 -0
  248. package/dist/lib/schema-utils/settings.js +23 -0
  249. package/dist/lib/schema-utils/settings.js.map +1 -0
  250. package/dist/lib/schema-utils/validator.d.ts.map +1 -1
  251. package/dist/lib/schema-utils/validator.js +11 -0
  252. package/dist/lib/schema-utils/validator.js.map +1 -1
  253. package/dist/lib/security/secret-crypto.d.ts +18 -0
  254. package/dist/lib/security/secret-crypto.d.ts.map +1 -0
  255. package/dist/lib/security/secret-crypto.js +71 -0
  256. package/dist/lib/security/secret-crypto.js.map +1 -0
  257. package/dist/lib/server/api/index.d.ts.map +1 -1
  258. package/dist/lib/server/api/index.js +3 -0
  259. package/dist/lib/server/api/index.js.map +1 -1
  260. package/dist/lib/server/api/routes/assets.d.ts.map +1 -1
  261. package/dist/lib/server/api/routes/assets.js +8 -2
  262. package/dist/lib/server/api/routes/assets.js.map +1 -1
  263. package/dist/lib/server/api/routes/organizations.d.ts.map +1 -1
  264. package/dist/lib/server/api/routes/organizations.js +4 -1
  265. package/dist/lib/server/api/routes/organizations.js.map +1 -1
  266. package/dist/lib/server/api/routes/plugin-settings.d.ts +4 -0
  267. package/dist/lib/server/api/routes/plugin-settings.d.ts.map +1 -0
  268. package/dist/lib/server/api/routes/plugin-settings.js +109 -0
  269. package/dist/lib/server/api/routes/plugin-settings.js.map +1 -0
  270. package/dist/lib/server/api/routes/roles.d.ts.map +1 -1
  271. package/dist/lib/server/api/routes/roles.js +37 -0
  272. package/dist/lib/server/api/routes/roles.js.map +1 -1
  273. package/dist/lib/server/api/routes/user.d.ts.map +1 -1
  274. package/dist/lib/server/api/routes/user.js +14 -3
  275. package/dist/lib/server/api/routes/user.js.map +1 -1
  276. package/dist/lib/services/asset-service.d.ts +1 -0
  277. package/dist/lib/services/asset-service.d.ts.map +1 -1
  278. package/dist/lib/services/asset-service.js.map +1 -1
  279. package/dist/lib/services/index.d.ts +2 -0
  280. package/dist/lib/services/index.d.ts.map +1 -1
  281. package/dist/lib/services/index.js +1 -0
  282. package/dist/lib/services/index.js.map +1 -1
  283. package/dist/lib/services/plugin-settings-service.d.ts +76 -0
  284. package/dist/lib/services/plugin-settings-service.d.ts.map +1 -0
  285. package/dist/lib/services/plugin-settings-service.js +236 -0
  286. package/dist/lib/services/plugin-settings-service.js.map +1 -0
  287. package/dist/lib/services/roles-service.d.ts +2 -2
  288. package/dist/lib/services/roles-service.d.ts.map +1 -1
  289. package/dist/lib/services/roles-service.js.map +1 -1
  290. package/dist/lib/theme/css.d.ts +30 -0
  291. package/dist/lib/theme/css.d.ts.map +1 -0
  292. package/dist/lib/theme/css.js +54 -0
  293. package/dist/lib/theme/css.js.map +1 -0
  294. package/dist/lib/theme/derive.d.ts +27 -0
  295. package/dist/lib/theme/derive.d.ts.map +1 -0
  296. package/dist/lib/theme/derive.js +108 -0
  297. package/dist/lib/theme/derive.js.map +1 -0
  298. package/dist/lib/theme/index.d.ts +5 -0
  299. package/dist/lib/theme/index.d.ts.map +1 -0
  300. package/dist/lib/theme/index.js +5 -0
  301. package/dist/lib/theme/index.js.map +1 -0
  302. package/dist/lib/theme/schemes.d.ts +60 -0
  303. package/dist/lib/theme/schemes.d.ts.map +1 -0
  304. package/dist/lib/theme/schemes.js +150 -0
  305. package/dist/lib/theme/schemes.js.map +1 -0
  306. package/dist/lib/theme/tokens.d.ts +57 -0
  307. package/dist/lib/theme/tokens.d.ts.map +1 -0
  308. package/dist/lib/theme/tokens.js +11 -0
  309. package/dist/lib/theme/tokens.js.map +1 -0
  310. package/dist/lib/types/auth.d.ts +10 -10
  311. package/dist/lib/types/auth.d.ts.map +1 -1
  312. package/dist/lib/types/capabilities.d.ts +50 -9
  313. package/dist/lib/types/capabilities.d.ts.map +1 -1
  314. package/dist/lib/types/capabilities.js +147 -5
  315. package/dist/lib/types/capabilities.js.map +1 -1
  316. package/dist/lib/types/config.d.ts +30 -1
  317. package/dist/lib/types/config.d.ts.map +1 -1
  318. package/dist/lib/types/schemas.d.ts +90 -2
  319. package/dist/lib/types/schemas.d.ts.map +1 -1
  320. package/dist/lib/types/schemas.js.map +1 -1
  321. package/dist/lib/types/sidebar.d.ts +3 -1
  322. package/dist/lib/types/sidebar.d.ts.map +1 -1
  323. package/dist/lib/utils/index.d.ts +1 -0
  324. package/dist/lib/utils/index.d.ts.map +1 -1
  325. package/dist/lib/utils/index.js +1 -0
  326. package/dist/lib/utils/index.js.map +1 -1
  327. package/dist/lib/utils/preview.d.ts +16 -5
  328. package/dist/lib/utils/preview.d.ts.map +1 -1
  329. package/dist/lib/utils/preview.js +7 -2
  330. package/dist/lib/utils/preview.js.map +1 -1
  331. package/dist/lib/utils/string-case.d.ts +21 -0
  332. package/dist/lib/utils/string-case.d.ts.map +1 -0
  333. package/dist/lib/utils/string-case.js +26 -0
  334. package/dist/lib/utils/string-case.js.map +1 -0
  335. package/dist/lib/vite/index.d.ts +7 -0
  336. package/dist/lib/vite/index.d.ts.map +1 -1
  337. package/dist/lib/vite/index.js +37 -6
  338. package/dist/lib/vite/index.js.map +1 -1
  339. package/dist/local-api/collection-api.d.ts.map +1 -1
  340. package/dist/local-api/collection-api.js +4 -2
  341. package/dist/local-api/types.d.ts +8 -0
  342. package/dist/local-api/types.d.ts.map +1 -1
  343. package/dist/mcp/tools.d.ts.map +1 -1
  344. package/dist/mcp/tools.js +110 -1
  345. package/dist/permissions-context.svelte.d.ts +7 -4
  346. package/dist/permissions-context.svelte.d.ts.map +1 -1
  347. package/dist/plugins/index.d.ts +3 -0
  348. package/dist/plugins/index.d.ts.map +1 -0
  349. package/dist/plugins/index.js +2 -0
  350. package/dist/plugins/resolver.d.ts +49 -0
  351. package/dist/plugins/resolver.d.ts.map +1 -0
  352. package/dist/plugins/resolver.js +65 -0
  353. package/dist/plugins/types.d.ts +233 -0
  354. package/dist/plugins/types.d.ts.map +1 -0
  355. package/dist/plugins/types.js +8 -0
  356. package/dist/schema-utils/desugar.d.ts +27 -0
  357. package/dist/schema-utils/desugar.d.ts.map +1 -0
  358. package/dist/schema-utils/desugar.js +101 -0
  359. package/dist/schema-utils/index.d.ts +2 -0
  360. package/dist/schema-utils/index.d.ts.map +1 -1
  361. package/dist/schema-utils/index.js +2 -0
  362. package/dist/schema-utils/settings.d.ts +17 -0
  363. package/dist/schema-utils/settings.d.ts.map +1 -0
  364. package/dist/schema-utils/settings.js +22 -0
  365. package/dist/schema-utils/validator.d.ts.map +1 -1
  366. package/dist/schema-utils/validator.js +11 -0
  367. package/dist/security/secret-crypto.d.ts +18 -0
  368. package/dist/security/secret-crypto.d.ts.map +1 -0
  369. package/dist/security/secret-crypto.js +70 -0
  370. package/dist/server/api/index.d.ts.map +1 -1
  371. package/dist/server/api/index.js +3 -0
  372. package/dist/server/api/routes/assets.d.ts.map +1 -1
  373. package/dist/server/api/routes/assets.js +8 -2
  374. package/dist/server/api/routes/organizations.d.ts.map +1 -1
  375. package/dist/server/api/routes/organizations.js +4 -1
  376. package/dist/server/api/routes/plugin-settings.d.ts +4 -0
  377. package/dist/server/api/routes/plugin-settings.d.ts.map +1 -0
  378. package/dist/server/api/routes/plugin-settings.js +108 -0
  379. package/dist/server/api/routes/roles.d.ts.map +1 -1
  380. package/dist/server/api/routes/roles.js +37 -0
  381. package/dist/server/api/routes/user.d.ts.map +1 -1
  382. package/dist/server/api/routes/user.js +14 -3
  383. package/dist/services/asset-service.d.ts +1 -0
  384. package/dist/services/asset-service.d.ts.map +1 -1
  385. package/dist/services/index.d.ts +2 -0
  386. package/dist/services/index.d.ts.map +1 -1
  387. package/dist/services/index.js +1 -0
  388. package/dist/services/plugin-settings-service.d.ts +76 -0
  389. package/dist/services/plugin-settings-service.d.ts.map +1 -0
  390. package/dist/services/plugin-settings-service.js +235 -0
  391. package/dist/services/roles-service.d.ts +2 -2
  392. package/dist/services/roles-service.d.ts.map +1 -1
  393. package/dist/theme/css.d.ts +30 -0
  394. package/dist/theme/css.d.ts.map +1 -0
  395. package/dist/theme/css.js +53 -0
  396. package/dist/theme/derive.d.ts +27 -0
  397. package/dist/theme/derive.d.ts.map +1 -0
  398. package/dist/theme/derive.js +107 -0
  399. package/dist/theme/index.d.ts +5 -0
  400. package/dist/theme/index.d.ts.map +1 -0
  401. package/dist/theme/index.js +4 -0
  402. package/dist/theme/schemes.d.ts +60 -0
  403. package/dist/theme/schemes.d.ts.map +1 -0
  404. package/dist/theme/schemes.js +149 -0
  405. package/dist/theme/tokens.d.ts +57 -0
  406. package/dist/theme/tokens.d.ts.map +1 -0
  407. package/dist/theme/tokens.js +10 -0
  408. package/dist/types/auth.d.ts +10 -10
  409. package/dist/types/auth.d.ts.map +1 -1
  410. package/dist/types/capabilities.d.ts +50 -9
  411. package/dist/types/capabilities.d.ts.map +1 -1
  412. package/dist/types/capabilities.js +147 -5
  413. package/dist/types/config.d.ts +30 -1
  414. package/dist/types/config.d.ts.map +1 -1
  415. package/dist/types/schemas.d.ts +90 -2
  416. package/dist/types/schemas.d.ts.map +1 -1
  417. package/dist/types/sidebar.d.ts +3 -1
  418. package/dist/types/sidebar.d.ts.map +1 -1
  419. package/dist/utils/index.d.ts +1 -0
  420. package/dist/utils/index.d.ts.map +1 -1
  421. package/dist/utils/index.js +1 -0
  422. package/dist/utils/preview.d.ts +16 -5
  423. package/dist/utils/preview.d.ts.map +1 -1
  424. package/dist/utils/preview.js +7 -2
  425. package/dist/utils/string-case.d.ts +21 -0
  426. package/dist/utils/string-case.d.ts.map +1 -0
  427. package/dist/utils/string-case.js +25 -0
  428. package/dist/vite/index.d.ts +7 -0
  429. package/dist/vite/index.d.ts.map +1 -1
  430. package/dist/vite/index.js +37 -6
  431. package/package.json +6 -4
@@ -1,10 +1,15 @@
1
1
  import type { SchemaType } from '../../types/schemas.js';
2
+ import type { CMSPlugin } from '../../plugins/types.js';
2
3
  interface Props {
3
4
  schemas: SchemaType[];
4
5
  documentType: string;
5
6
  documentId?: string | null;
6
7
  isCreating: boolean;
7
8
  onBack: () => void;
9
+ /** When set, the close control renders as a labelled "← {backLabel}" button
10
+ * instead of a bare close (✕) icon — used for reference editors so the action
11
+ * reads as "go back" rather than "close". */
12
+ backLabel?: string;
8
13
  onSaved?: (documentId: string) => void;
9
14
  onAutoSaved?: (documentId: string, title: string) => void;
10
15
  onDeleted?: () => void;
@@ -26,10 +31,18 @@ interface Props {
26
31
  onToggleFocus?: () => void;
27
32
  /** When true, split the editor with a live preview iframe on the right. */
28
33
  presentationMode?: boolean;
34
+ /**
35
+ * Bump this to ask the preview iframe to re-fetch its server-loaded data
36
+ * (`aphex:refresh` → `invalidateAll` in the overlay). Used when a *different*
37
+ * document — e.g. one this page renders in a list — was edited elsewhere.
38
+ */
39
+ refreshToken?: number;
29
40
  /** Toggle host-driven presentation mode. Omit to hide the button entirely. */
30
41
  onTogglePresentation?: () => void;
31
42
  /** Organization ID from the host context — used as fallback for new docs that haven't been saved yet. */
32
43
  organizationId?: string | null;
44
+ /** Build-time plugins; their document-action parts render in the toolbar. */
45
+ plugins?: CMSPlugin[];
33
46
  }
34
47
  declare const DocumentEditor: import("svelte").Component<Props, {}, "">;
35
48
  type DocumentEditor = ReturnType<typeof DocumentEditor>;
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentEditor.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/DocumentEditor.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA4BxD,UAAU,KAAK;IACd,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,sBAAsB,CAAC,EAAE;QACxB,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;IACT,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,8EAA8E;IAC9E,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,yGAAyG;IACzG,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAsgEF,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"DocumentEditor.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/DocumentEditor.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAQzD,OAAO,KAAK,EAAE,SAAS,EAAuB,MAAM,qBAAqB,CAAC;AA6BzE,UAAU,KAAK;IACd,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB;;kDAE8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,sBAAsB,CAAC,EAAE;QACxB,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;IACT,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,yGAAyG;IACzG,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,6EAA6E;IAC7E,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;CACtB;AA6rEF,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -211,6 +211,15 @@
211
211
  }
212
212
 
213
213
  // Sort assets client-side
214
+ function isSystemAsset(asset: Asset): boolean {
215
+ const metadata = asset.metadata as Record<string, unknown> | null | undefined;
216
+ return (
217
+ metadata?.system === true ||
218
+ metadata?.fieldPath === 'user.image' ||
219
+ metadata?.fieldPath === 'organization.metadata.logo'
220
+ );
221
+ }
222
+
214
223
  function sortAssets(list: Asset[]): Asset[] {
215
224
  const sorted = [...list];
216
225
  switch (sortOrder) {
@@ -234,14 +243,15 @@
234
243
  // Pinned assets (already in array) — separate from the main sorted list
235
244
  const pinnedAssets = $derived.by(() => {
236
245
  if (!(selectable && multiSelect && existingAssetIds && existingAssetIds.size > 0)) return [];
237
- return assetList.filter((a) => existingAssetIds!.has(a.id));
246
+ return assetList.filter((a) => !isSystemAsset(a) && existingAssetIds!.has(a.id));
238
247
  });
239
248
 
240
249
  const sortedAssets = $derived.by(() => {
250
+ const visibleAssets = assetList.filter((a) => !isSystemAsset(a));
241
251
  if (selectable && multiSelect && existingAssetIds && existingAssetIds.size > 0) {
242
- return sortAssets(assetList.filter((a) => !existingAssetIds!.has(a.id)));
252
+ return sortAssets(visibleAssets.filter((a) => !existingAssetIds!.has(a.id)));
243
253
  }
244
- return sortAssets(assetList);
254
+ return sortAssets(visibleAssets);
245
255
  });
246
256
 
247
257
  // Bulk selection derived (must be after sortedAssets)
@@ -1 +1 @@
1
- {"version":3,"file":"MediaBrowser.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/MediaBrowser.svelte.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAS9C,UAAU,KAAK;IACd,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yEAAyE;IACzE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IAC7C,oCAAoC;IACpC,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACnC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC/B;AA8qCF,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"MediaBrowser.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/MediaBrowser.svelte.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAS9C,UAAU,KAAK;IACd,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yEAAyE;IACzE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IAC7C,oCAAoC;IACpC,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACnC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC/B;AAwrCF,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -0,0 +1,231 @@
1
+ <script lang="ts">
2
+ import * as Card from '@aphexcms/ui/shadcn/card';
3
+ import * as Select from '@aphexcms/ui/shadcn/select';
4
+ import { Button } from '@aphexcms/ui/shadcn/button';
5
+ import { Input } from '@aphexcms/ui/shadcn/input';
6
+ import { Textarea } from '@aphexcms/ui/shadcn/textarea';
7
+ import { Label } from '@aphexcms/ui/shadcn/label';
8
+ import { Switch } from '@aphexcms/ui/shadcn/switch';
9
+ import { toast } from 'svelte-sonner';
10
+ import { onMount } from 'svelte';
11
+ import type { CMSPlugin, SettingsPart } from '../../plugins/types';
12
+ import type { SettingsField } from '../../types/schemas';
13
+ import { settingsListItems } from '../../schema-utils/settings';
14
+
15
+ /**
16
+ * Generic plugin-settings surface. The app mounts this in its settings area and
17
+ * passes its plugin registry; the panel reads each plugin's `aphex/settings`
18
+ * declaration, loads the org's masked values from the API, renders a form per
19
+ * plugin, and saves via the API. Secret fields are write-only (masked); a blank/
20
+ * untouched submission leaves them unchanged.
21
+ */
22
+ let { plugins = [] }: { plugins?: CMSPlugin[] } = $props();
23
+
24
+ // Settings declarations from the client plugin registry (component plane).
25
+ const declarations = $derived(
26
+ plugins
27
+ .flatMap((p) => p.parts ?? [])
28
+ .filter((part): part is SettingsPart => part.implements === 'aphex/settings')
29
+ );
30
+
31
+ // Placeholder the API returns for a secret that has a stored value.
32
+ const SECRET_MASK = '••••••';
33
+
34
+ // Per-plugin working values (non-secret fields + the masked marker for secrets),
35
+ // plus the last-saved snapshot for dirty detection.
36
+ let valuesByPlugin = $state<Record<string, Record<string, unknown>>>({});
37
+ let savedByPlugin = $state<Record<string, string>>({});
38
+ // Secret fields are edited through a SEPARATE draft that always starts empty — the
39
+ // mask never enters an editable input (typing into a masked field would prepend the
40
+ // bullets to the real value). Empty draft = "leave unchanged"; non-empty = replace.
41
+ let secretDrafts = $state<Record<string, Record<string, string>>>({});
42
+ let secretsEnabled = $state(true);
43
+ let loading = $state(true);
44
+ let loadError = $state<string | null>(null);
45
+ let savingId = $state<string | null>(null);
46
+
47
+ onMount(async () => {
48
+ try {
49
+ const res = await fetch('/api/plugin-settings');
50
+ const json = await res.json();
51
+ if (!res.ok || !json.success) {
52
+ loadError = json?.message ?? 'Failed to load plugin settings';
53
+ return;
54
+ }
55
+ secretsEnabled = json.secretsEnabled ?? true;
56
+ for (const entry of json.data as Array<{
57
+ pluginId: string;
58
+ values: Record<string, unknown>;
59
+ }>) {
60
+ valuesByPlugin[entry.pluginId] = { ...entry.values };
61
+ savedByPlugin[entry.pluginId] = JSON.stringify(entry.values);
62
+ }
63
+ } catch {
64
+ loadError = 'Failed to load plugin settings';
65
+ } finally {
66
+ loading = false;
67
+ }
68
+ });
69
+
70
+ function getVal(pluginId: string, name: string): unknown {
71
+ return valuesByPlugin[pluginId]?.[name];
72
+ }
73
+ function setVal(pluginId: string, name: string, value: unknown) {
74
+ valuesByPlugin[pluginId] = { ...(valuesByPlugin[pluginId] ?? {}), [name]: value };
75
+ }
76
+ /** Whether a secret already has a stored value (server sent the mask for it). */
77
+ function isSecretSet(pluginId: string, name: string): boolean {
78
+ return valuesByPlugin[pluginId]?.[name] === SECRET_MASK;
79
+ }
80
+ function getSecretDraft(pluginId: string, name: string): string {
81
+ return secretDrafts[pluginId]?.[name] ?? '';
82
+ }
83
+ function setSecretDraft(pluginId: string, name: string, value: string) {
84
+ secretDrafts[pluginId] = { ...(secretDrafts[pluginId] ?? {}), [name]: value };
85
+ }
86
+ function isDirty(pluginId: string): boolean {
87
+ const secretTyped = Object.values(secretDrafts[pluginId] ?? {}).some((v) => v !== '');
88
+ return (
89
+ secretTyped || JSON.stringify(valuesByPlugin[pluginId] ?? {}) !== savedByPlugin[pluginId]
90
+ );
91
+ }
92
+
93
+ // Normalize a string field's `list` to `{ title, value }[]`.
94
+ // Shared with PluginSettingsService's validator, so the options offered here are
95
+ // exactly the ones the server will accept.
96
+ const listItems = settingsListItems;
97
+
98
+ async function save(decl: SettingsPart) {
99
+ savingId = decl.pluginId;
100
+ try {
101
+ // Start from the working values (secrets are the mask here = "unchanged"),
102
+ // then overlay any secret the user actually typed (non-empty draft = replace).
103
+ const patch: Record<string, unknown> = { ...(valuesByPlugin[decl.pluginId] ?? {}) };
104
+ for (const [name, draft] of Object.entries(secretDrafts[decl.pluginId] ?? {})) {
105
+ if (draft !== '') patch[name] = draft;
106
+ }
107
+
108
+ const res = await fetch(`/api/plugin-settings/${encodeURIComponent(decl.pluginId)}`, {
109
+ method: 'PUT',
110
+ headers: { 'content-type': 'application/json' },
111
+ body: JSON.stringify({ values: patch })
112
+ });
113
+ const json = await res.json();
114
+ if (!res.ok || !json.success) {
115
+ toast.error(json?.message ?? 'Failed to save settings');
116
+ return;
117
+ }
118
+ valuesByPlugin[decl.pluginId] = { ...json.data.values };
119
+ savedByPlugin[decl.pluginId] = JSON.stringify(json.data.values);
120
+ secretDrafts[decl.pluginId] = {}; // clear typed secrets after a successful save
121
+ toast.success(`${decl.title} settings saved`);
122
+ } catch {
123
+ toast.error('Failed to save settings');
124
+ } finally {
125
+ savingId = null;
126
+ }
127
+ }
128
+ </script>
129
+
130
+ {#snippet fieldControl(decl: SettingsPart, field: SettingsField)}
131
+ {@const value = getVal(decl.pluginId, field.name)}
132
+ {#if field.type === 'secret'}
133
+ <Input
134
+ type="password"
135
+ autocomplete="off"
136
+ disabled={!secretsEnabled}
137
+ placeholder={!secretsEnabled
138
+ ? 'Encryption key not configured'
139
+ : isSecretSet(decl.pluginId, field.name)
140
+ ? 'Set — type a new value to replace'
141
+ : 'Enter a value'}
142
+ value={getSecretDraft(decl.pluginId, field.name)}
143
+ oninput={(e) => setSecretDraft(decl.pluginId, field.name, e.currentTarget.value)}
144
+ />
145
+ {:else if field.type === 'boolean'}
146
+ <Switch
147
+ checked={value === true}
148
+ onCheckedChange={(c) => setVal(decl.pluginId, field.name, c)}
149
+ />
150
+ {:else if field.type === 'number'}
151
+ <Input
152
+ type="number"
153
+ value={value == null ? '' : String(value)}
154
+ oninput={(e) =>
155
+ setVal(
156
+ decl.pluginId,
157
+ field.name,
158
+ e.currentTarget.value === '' ? null : Number(e.currentTarget.value)
159
+ )}
160
+ />
161
+ {:else if field.type === 'text'}
162
+ <Textarea
163
+ value={typeof value === 'string' ? value : ''}
164
+ oninput={(e) => setVal(decl.pluginId, field.name, e.currentTarget.value)}
165
+ />
166
+ {:else if field.type === 'string' && listItems(field).length > 0}
167
+ {@const items = listItems(field)}
168
+ <Select.Root
169
+ type="single"
170
+ value={typeof value === 'string' ? value : ''}
171
+ onValueChange={(v) => setVal(decl.pluginId, field.name, v)}
172
+ >
173
+ <Select.Trigger class="w-full">
174
+ {items.find((i) => i.value === value)?.title ?? 'Select…'}
175
+ </Select.Trigger>
176
+ <Select.Content>
177
+ {#each items as item (item.value)}
178
+ <Select.Item value={item.value} label={item.title}>{item.title}</Select.Item>
179
+ {/each}
180
+ </Select.Content>
181
+ </Select.Root>
182
+ {:else}
183
+ <Input
184
+ value={typeof value === 'string' ? value : ''}
185
+ placeholder={(field as { placeholder?: string }).placeholder ?? ''}
186
+ oninput={(e) => setVal(decl.pluginId, field.name, e.currentTarget.value)}
187
+ />
188
+ {/if}
189
+ {/snippet}
190
+
191
+ <div class="space-y-6">
192
+ {#if loading}
193
+ <p class="text-muted-foreground text-sm">Loading…</p>
194
+ {:else if loadError}
195
+ <p class="text-destructive text-sm">{loadError}</p>
196
+ {:else if declarations.length === 0}
197
+ <div class="border-muted-foreground/30 rounded-md border border-dashed p-8 text-center">
198
+ <p class="text-muted-foreground text-sm">No installed plugins have configurable settings.</p>
199
+ </div>
200
+ {:else}
201
+ {#each declarations as decl (decl.pluginId)}
202
+ <Card.Root>
203
+ <Card.Header>
204
+ <Card.Title>{decl.title}</Card.Title>
205
+ {#if decl.description}
206
+ <Card.Description>{decl.description}</Card.Description>
207
+ {/if}
208
+ </Card.Header>
209
+ <Card.Content class="space-y-4">
210
+ {#each decl.fields as field (field.name)}
211
+ <div class="space-y-1.5">
212
+ <Label for={`${decl.pluginId}-${field.name}`}>{field.title}</Label>
213
+ {@render fieldControl(decl, field)}
214
+ {#if field.description}
215
+ <p class="text-muted-foreground text-xs">{field.description}</p>
216
+ {/if}
217
+ </div>
218
+ {/each}
219
+ </Card.Content>
220
+ <Card.Footer class="justify-end">
221
+ <Button
222
+ onclick={() => save(decl)}
223
+ disabled={savingId === decl.pluginId || !isDirty(decl.pluginId)}
224
+ >
225
+ {savingId === decl.pluginId ? 'Saving…' : 'Save'}
226
+ </Button>
227
+ </Card.Footer>
228
+ </Card.Root>
229
+ {/each}
230
+ {/if}
231
+ </div>
@@ -0,0 +1,8 @@
1
+ import type { CMSPlugin } from '../../plugins/types.js';
2
+ type $$ComponentProps = {
3
+ plugins?: CMSPlugin[];
4
+ };
5
+ declare const PluginSettingsPanel: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type PluginSettingsPanel = ReturnType<typeof PluginSettingsPanel>;
7
+ export default PluginSettingsPanel;
8
+ //# sourceMappingURL=PluginSettingsPanel.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginSettingsPanel.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/PluginSettingsPanel.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,qBAAqB,CAAC;AAIlE,KAAK,gBAAgB,GAAI;IAAE,OAAO,CAAC,EAAE,SAAS,EAAE,CAAA;CAAE,CAAC;AA+MpD,QAAA,MAAM,mBAAmB,sDAAwC,CAAC;AAClE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { Label } from '@aphexcms/ui/shadcn/label';
3
- import { Badge } from '@aphexcms/ui/shadcn/badge';
4
3
  import * as Alert from '@aphexcms/ui/shadcn/alert';
4
+ import * as Tooltip from '@aphexcms/ui/shadcn/tooltip';
5
+ import { Info } from '@lucide/svelte';
5
6
  import type {
6
7
  Field,
7
8
  DateField as DateFieldType,
@@ -14,24 +15,16 @@
14
15
  type ValidationError
15
16
  } from '../../field-validation/utils';
16
17
  import { cmsLogger } from '../../utils/logger';
18
+ import { useFieldComponents } from '../../admin/field-components.svelte';
17
19
  import {
18
20
  convertDateToUserFormat,
19
21
  convertDateTimeToUserFormat
20
22
  } from '../../field-validation/date-utils';
21
23
 
22
- // Import individual field components
23
- import StringField from './fields/StringField.svelte';
24
- import SlugField from './fields/SlugField.svelte';
25
- import URLField from './fields/URLField.svelte';
26
- import TextareaField from './fields/TextareaField.svelte';
27
- import NumberField from './fields/NumberField.svelte';
28
- import BooleanField from './fields/BooleanField.svelte';
29
- import ImageField from './fields/ImageField.svelte';
30
- import FileField from './fields/FileField.svelte';
24
+ // Leaf/reference/custom-input fields resolve through the shared FieldInput;
25
+ // object/array containers recurse here.
26
+ import FieldInput from './fields/FieldInput.svelte';
31
27
  import ArrayField from './fields/ArrayField.svelte';
32
- import DateField from './fields/DateField.svelte';
33
- import DateTimeField from './fields/DateTimeField.svelte';
34
- import ReferenceField from './fields/ReferenceField.svelte';
35
28
  import SchemaField from './SchemaField.svelte';
36
29
 
37
30
  interface Props {
@@ -45,6 +38,13 @@
45
38
  parentPath?: string; // Parent field path for nested fields
46
39
  readonly?: boolean; // Read-only mode for viewers
47
40
  organizationId?: string; // Document's organization ID for asset uploads
41
+ /**
42
+ * How to present `field.description`. `'inline'` (default) shows it as a line
43
+ * under the label; `'tooltip'` shows an info icon that reveals it on hover/focus.
44
+ * Object containers pass `'tooltip'` to their subfields so nested groups don't
45
+ * become a wall of help text.
46
+ */
47
+ descriptionMode?: 'inline' | 'tooltip';
48
48
  }
49
49
 
50
50
  let {
@@ -57,12 +57,18 @@
57
57
  schemaType,
58
58
  parentPath,
59
59
  readonly = false,
60
- organizationId
60
+ organizationId,
61
+ descriptionMode = 'inline'
61
62
  }: Props = $props();
62
63
 
63
64
  // Build full field path
64
65
  const fieldPath = $derived(parentPath ? `${parentPath}.${field.name}` : field.name);
65
66
 
67
+ // Plugin-provided input widget for this field's `input` key, if any. When set,
68
+ // it replaces the built-in renderer for the field's type.
69
+ const fieldComponents = useFieldComponents();
70
+ const CustomInput = $derived(field.input ? fieldComponents(field.input) : undefined);
71
+
66
72
  // Validation state for the wrapper (displays errors and status)
67
73
  let validationErrors = $state<ValidationError[]>([]);
68
74
 
@@ -125,28 +131,46 @@
125
131
 
126
132
  <div class="space-y-2" data-field-path={fieldPath}>
127
133
  <div class="flex items-center justify-between">
128
- <Label for={field.name}>
129
- {field.title}
130
- {#if isFieldRequired(field)}
131
- <span class="text-destructive">*</span>
132
- {/if}
133
- </Label>
134
-
135
- <div class="flex items-center gap-2">
136
- {#if hasErrors}
137
- <span class="text-destructive text-sm">🚨</span>
138
- {/if}
139
-
140
- {#if field.type}
141
- <Badge variant="outline" class="text-xs">
142
- {field.type}
143
- </Badge>
134
+ <div class="flex items-center gap-1.5">
135
+ <Label for={field.name}>
136
+ {field.title}
137
+ {#if isFieldRequired(field)}
138
+ <span class="text-destructive">*</span>
139
+ {/if}
140
+ </Label>
141
+
142
+ <!-- In tooltip mode (object subfields) the description hides behind an info
143
+ icon on desktop to keep the group tidy. Desktop only — touch has no hover
144
+ and the tooltip is unreliable there, so on mobile the description falls
145
+ back to the inline line below (see `lg:hidden` on the <p>). -->
146
+ {#if descriptionMode === 'tooltip' && field.description}
147
+ <Tooltip.Provider delayDuration={150}>
148
+ <Tooltip.Root>
149
+ <Tooltip.Trigger
150
+ class="text-muted-foreground/60 hover:text-foreground focus-visible:text-foreground -my-1 hidden cursor-help rounded p-1 transition-colors outline-none lg:inline-flex"
151
+ aria-label="More info about {field.title}"
152
+ >
153
+ <Info class="size-3.5" />
154
+ </Tooltip.Trigger>
155
+ <Tooltip.Content class="max-w-xs text-xs leading-relaxed">
156
+ {field.description}
157
+ </Tooltip.Content>
158
+ </Tooltip.Root>
159
+ </Tooltip.Provider>
144
160
  {/if}
145
161
  </div>
162
+
163
+ {#if hasErrors}
164
+ <span class="text-destructive text-sm">🚨</span>
165
+ {/if}
146
166
  </div>
147
167
 
168
+ <!-- Inline description: always in inline mode; in tooltip mode only on mobile
169
+ (`lg:hidden`), where the desktop info icon is hidden. -->
148
170
  {#if field.description}
149
- <p class="text-muted-foreground text-sm">{field.description}</p>
171
+ <p class="text-muted-foreground text-sm {descriptionMode === 'tooltip' ? 'lg:hidden' : ''}">
172
+ {field.description}
173
+ </p>
150
174
  {/if}
151
175
 
152
176
  <!-- Validation errors display -->
@@ -177,53 +201,11 @@
177
201
  error
178
202
  )}
179
203
  >
180
- {#if field.type === 'string'}
181
- <StringField {field} {value} {documentData} {onUpdate} {validationClasses} {readonly} />
182
- {:else if field.type === 'text'}
183
- <TextareaField {field} {value} {onUpdate} {validationClasses} {readonly} />
184
- {:else if field.type === 'slug'}
185
- <SlugField {field} {value} {documentData} {onUpdate} {validationClasses} {readonly} />
186
- {:else if field.type === 'url'}
187
- <URLField {field} {value} {onUpdate} {validationClasses} {readonly} />
188
- {:else if field.type === 'number'}
189
- <NumberField {field} {value} {onUpdate} {validationClasses} {readonly} />
190
- {:else if field.type === 'boolean'}
191
- <BooleanField {field} {value} {onUpdate} {validationClasses} {readonly} />
192
- {:else if field.type === 'date'}
193
- <DateField {field} {value} {onUpdate} {validationClasses} {readonly} />
194
- {:else if field.type === 'datetime'}
195
- <DateTimeField {field} {value} {onUpdate} {validationClasses} {readonly} />
196
-
197
- <!-- Image Field -->
198
- {:else if field.type === 'image'}
199
- <ImageField
200
- {field}
201
- {value}
202
- {onUpdate}
203
- {validationClasses}
204
- {schemaType}
205
- {fieldPath}
206
- {readonly}
207
- {organizationId}
208
- />
209
-
210
- <!-- File Field -->
211
- {:else if field.type === 'file'}
212
- <FileField
213
- {field}
214
- {value}
215
- {onUpdate}
216
- {validationClasses}
217
- {schemaType}
218
- {fieldPath}
219
- {readonly}
220
- {organizationId}
221
- />
222
-
223
- <!-- Object Field -->
224
- {:else if field.type === 'object' && field.fields}
225
- <div class="border-border space-y-4 rounded-md border p-4">
226
- <h4 class="text-sm font-medium">{field.title}</h4>
204
+ {#if field.type === 'object' && field.fields && !CustomInput}
205
+ <!-- Object container: recurse. A custom `input` widget would override this.
206
+ The field's title is already shown by the <Label> above, so the card is
207
+ just a bordered group no repeated heading. -->
208
+ <div class="border-border space-y-6 rounded-md border p-4">
227
209
  {#each field.fields as subField, index (index)}
228
210
  <SchemaField
229
211
  field={subField}
@@ -235,28 +217,27 @@
235
217
  parentPath={fieldPath}
236
218
  {readonly}
237
219
  {organizationId}
220
+ descriptionMode="tooltip"
238
221
  />
239
222
  {/each}
240
223
  </div>
241
-
242
- <!-- Array Field (includes block content editor when of contains {type: 'block'}) -->
243
- {:else if field.type === 'array' && field.of}
224
+ {:else if field.type === 'array' && field.of && !CustomInput}
225
+ <!-- Array container (also the block-content editor when `of` has {type:'block'}). -->
244
226
  <ArrayField {field} {value} {onUpdate} {onOpenReference} {readonly} {organizationId} />
245
-
246
- <!-- Reference Field -->
247
- {:else if field.type === 'reference' && field.to}
248
- <ReferenceField {field} {value} {onUpdate} {onOpenReference} {readonly} />
249
-
250
- <!-- Unknown field type -->
251
227
  {:else}
252
- <div class="border-muted-foreground/30 rounded-md border border-dashed p-4 text-center">
253
- <p class="text-muted-foreground text-sm">
254
- Field type "{field.type}" not yet supported
255
- </p>
256
- <p class="text-muted-foreground mt-1 text-xs">
257
- Raw value: {JSON.stringify(value)}
258
- </p>
259
- </div>
228
+ <!-- Leaf / reference / custom-input fields — resolved uniformly. -->
229
+ <FieldInput
230
+ {field}
231
+ {value}
232
+ {onUpdate}
233
+ {readonly}
234
+ {validationClasses}
235
+ {documentData}
236
+ {schemaType}
237
+ {fieldPath}
238
+ {organizationId}
239
+ {onOpenReference}
240
+ />
260
241
  {/if}
261
242
 
262
243
  {#snippet failed(error, reset)}
@@ -11,6 +11,13 @@ interface Props {
11
11
  parentPath?: string;
12
12
  readonly?: boolean;
13
13
  organizationId?: string;
14
+ /**
15
+ * How to present `field.description`. `'inline'` (default) shows it as a line
16
+ * under the label; `'tooltip'` shows an info icon that reveals it on hover/focus.
17
+ * Object containers pass `'tooltip'` to their subfields so nested groups don't
18
+ * become a wall of help text.
19
+ */
20
+ descriptionMode?: 'inline' | 'tooltip';
14
21
  }
15
22
  declare const SchemaField: import("svelte").Component<Props, {
16
23
  performValidation: (currentValue: any, context?: any) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaField.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/SchemaField.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,KAAK,EAGL,MAAM,qBAAqB,CAAC;AAyB9B,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAG9C,UAAU,KAAK;IACd,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,GAAG,CAAC;IACX,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AA6NF,QAAA,MAAM,WAAW;sCA/KgC,GAAG,YAAW,GAAG;MA+KT,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"SchemaField.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/admin/SchemaField.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,KAAK,EAGL,MAAM,qBAAqB,CAAC;AAiB9B,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAG9C,UAAU,KAAK;IACd,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,GAAG,CAAC;IACX,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;CACvC;AAgMF,QAAA,MAAM,WAAW;sCAnJgC,GAAG,YAAW,GAAG;MAmJT,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -5,12 +5,13 @@
5
5
  import { Checkbox } from '@aphexcms/ui/shadcn/checkbox';
6
6
  import * as DropdownMenu from '@aphexcms/ui/shadcn/dropdown-menu';
7
7
  import * as Card from '@aphexcms/ui/shadcn/card';
8
- import type { ArrayField as ArrayFieldType, SchemaType } from '../../../types/schemas';
8
+ import type { ArrayField as ArrayFieldType, Field, SchemaType } from '../../../types/schemas';
9
9
  import { getArrayTypes, getSchemaByName } from '../../../schema-utils/utils';
10
10
  import { getSchemaContext } from '../../../schema-context.svelte';
11
11
  import ObjectModal from '../ObjectModal.svelte';
12
12
  import ImageField from './ImageField.svelte';
13
13
  import ReferenceField from './ReferenceField.svelte';
14
+ import FieldInput from './FieldInput.svelte';
14
15
  import { getDefaultValueForFieldType } from '../../../utils/field-defaults';
15
16
  import { DragDropProvider } from '@dnd-kit/svelte';
16
17
  import { createSortable, isSortable } from '@dnd-kit/svelte/sortable';
@@ -90,6 +91,20 @@
90
91
  const primitiveType = $derived(isPrimitiveArray ? field.of?.[0]?.type : null);
91
92
  const availableTypes = $derived(getArrayTypes(schemas, field));
92
93
 
94
+ // The item's field spec, used to render each primitive item through the shared
95
+ // FieldInput resolver (so a rich type or a plugin `input` widget works per item).
96
+ const primitiveItemField = $derived({
97
+ name: `${field.name}-item`,
98
+ title: '',
99
+ ...(field.of?.[0] ?? { type: 'string' })
100
+ } as Field);
101
+ // Route through FieldInput for rich types (color/url/slug/date…) or any custom
102
+ // `input`; keep the compact inline inputs for plain string/number/boolean.
103
+ const COMPACT_TYPES = ['string', 'number', 'boolean', 'text'];
104
+ const useResolvedItemInput = $derived(
105
+ !!field.of?.[0]?.input || (!!primitiveType && !COMPACT_TYPES.includes(primitiveType))
106
+ );
107
+
93
108
  // Synthetic ReferenceField definition reused for every row in an
94
109
  // array-of-references. We forward the array's first `of[]` entry's `to` so
95
110
  // the row picker honors the schema-author's allowed target types.
@@ -777,7 +792,14 @@
777
792
  {/if}
778
793
 
779
794
  <div class="min-w-0 flex-1">
780
- {#if primitiveType === 'boolean'}
795
+ {#if useResolvedItemInput}
796
+ <FieldInput
797
+ field={primitiveItemField}
798
+ value={item}
799
+ onUpdate={(v) => handleUpdatePrimitive(index, v)}
800
+ {readonly}
801
+ />
802
+ {:else if primitiveType === 'boolean'}
781
803
  <div class="flex items-center gap-2 px-1">
782
804
  <Checkbox
783
805
  checked={item}
@@ -1 +1 @@
1
- {"version":3,"file":"ArrayField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ArrayField.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAc,MAAM,wBAAwB,CAAC;AA+BtF,UAAU,KAAK;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AA65BF,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ArrayField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ArrayField.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAqB,MAAM,wBAAwB,CAAC;AAgC7F,UAAU,KAAK;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AA86BF,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}