@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,235 @@
1
+ // services/plugin-settings-service.ts
2
+ //
3
+ // Resolves and persists a plugin's per-organization settings — the "config plane"
4
+ // (see references/plugin-settings-and-secrets-scope.md). A plugin declares its
5
+ // settings shape via an `aphex/settings` part; this service merges the declared
6
+ // defaults with the stored per-(org, plugin) values and writes edits back, scoped
7
+ // to the org.
8
+ //
9
+ // Secrets (`type: 'secret'` fields) are handled specially:
10
+ // - stored AES-256-GCM-encrypted (never plaintext),
11
+ // - decrypted only for server injection (`get`), never for the client (`getMasked`),
12
+ // - write-only: a blank/masked submission means "leave unchanged".
13
+ // When no encryption key is configured, secret writes are refused and secret reads
14
+ // return nothing — fail safe, never store or reveal a plaintext secret.
15
+ import { encryptSecret, decryptSecret, isEncryptedSecret } from '../security/secret-crypto.js';
16
+ import { settingsListItems } from '../schema-utils/settings.js';
17
+ import { cmsLogger } from '../utils/logger.js';
18
+ /** Placeholder shown to the client for a secret that has a stored value. */
19
+ export const SECRET_MASK = '••••••';
20
+ const isSecret = (f) => f.type === 'secret';
21
+ /**
22
+ * Static default for a field — its `initialValue` when that's a plain value (not a
23
+ * function/thunk). Secrets never carry a default.
24
+ */
25
+ function fieldDefault(field) {
26
+ if (isSecret(field))
27
+ return undefined;
28
+ const initial = field.initialValue;
29
+ return typeof initial === 'function' ? undefined : initial;
30
+ }
31
+ /** Build the defaults object from a declaration's fields (skips undefined). */
32
+ function defaultsFor(fields) {
33
+ const out = {};
34
+ for (const field of fields) {
35
+ const value = fieldDefault(field);
36
+ if (value !== undefined)
37
+ out[field.name] = value;
38
+ }
39
+ return out;
40
+ }
41
+ /** Raised when a submitted value doesn't match its declared field type. */
42
+ export class PluginSettingsValidationError extends Error {
43
+ issues;
44
+ constructor(issues) {
45
+ super(`Invalid plugin settings: ${issues.join('; ')}`);
46
+ this.issues = issues;
47
+ this.name = 'PluginSettingsValidationError';
48
+ }
49
+ }
50
+ /**
51
+ * Check one submitted value against its declared field type, returning an error
52
+ * message or `null`.
53
+ *
54
+ * The declaration is the contract, so the host enforces it here rather than leaving
55
+ * every plugin to re-guard values it already described. Without this a `string` field
56
+ * would happily store an object, and the plugin would find out at request time, deep
57
+ * in its own code, with no useful trace back to the save that caused it.
58
+ *
59
+ * `null` is always allowed — it's how the panel represents "cleared".
60
+ */
61
+ function checkValue(field, value) {
62
+ if (value === null)
63
+ return null;
64
+ switch (field.type) {
65
+ case 'string': {
66
+ if (typeof value !== 'string')
67
+ return `"${field.name}" must be a string`;
68
+ // A select-style string field may only hold one of its declared options.
69
+ const items = settingsListItems(field);
70
+ if (items.length > 0 && !items.some((item) => item.value === value)) {
71
+ return `"${field.name}" must be one of: ${items.map((i) => i.value).join(', ')}`;
72
+ }
73
+ return null;
74
+ }
75
+ case 'text':
76
+ if (typeof value !== 'string')
77
+ return `"${field.name}" must be a string`;
78
+ return null;
79
+ case 'number':
80
+ // Reject NaN/Infinity too — they survive JSON as null and corrupt round-trips.
81
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
82
+ return `"${field.name}" must be a finite number`;
83
+ }
84
+ if (field.min !== undefined && value < field.min) {
85
+ return `"${field.name}" must be >= ${field.min}`;
86
+ }
87
+ if (field.max !== undefined && value > field.max) {
88
+ return `"${field.name}" must be <= ${field.max}`;
89
+ }
90
+ return null;
91
+ case 'boolean':
92
+ if (typeof value !== 'boolean')
93
+ return `"${field.name}" must be a boolean`;
94
+ return null;
95
+ case 'secret':
96
+ // Secrets are write-only strings; blank/mask is handled before this point.
97
+ if (typeof value !== 'string')
98
+ return `"${field.name}" must be a string`;
99
+ return null;
100
+ }
101
+ }
102
+ export class PluginSettingsService {
103
+ db;
104
+ resolver;
105
+ encryptionKey;
106
+ constructor(
107
+ /** Narrowed to the two methods this service uses — the full adapter satisfies it. */
108
+ db,
109
+ /** Likewise: settings resolution is the only part of the resolver needed here. */
110
+ resolver,
111
+ /** Key for encrypting `secret` fields; when absent, secrets are disabled (fail safe). */
112
+ encryptionKey = null) {
113
+ this.db = db;
114
+ this.resolver = resolver;
115
+ this.encryptionKey = encryptionKey;
116
+ }
117
+ /** Whether secret fields can be stored/read (an encryption key is configured). */
118
+ get secretsEnabled() {
119
+ return typeof this.encryptionKey === 'string' && this.encryptionKey.length > 0;
120
+ }
121
+ secretFieldNames(declaration) {
122
+ return new Set(declaration.fields.filter(isSecret).map((f) => f.name));
123
+ }
124
+ /**
125
+ * Effective values for injection into plugin **server** code: declared defaults
126
+ * overlaid with stored values, with secrets **decrypted** to plaintext. Secrets
127
+ * that can't be decrypted (no key, or a bad envelope) are omitted, never returned
128
+ * as ciphertext. This is the sensitive read — never send its result to a client.
129
+ */
130
+ async get(organizationId, pluginId) {
131
+ const declaration = this.resolver.settingsDeclaration(pluginId);
132
+ const stored = (await this.db.getPluginSettings(organizationId, pluginId)) ?? {};
133
+ const defaults = declaration ? defaultsFor(declaration.fields) : {};
134
+ const merged = { ...defaults, ...stored };
135
+ if (!declaration)
136
+ return merged;
137
+ const secrets = this.secretFieldNames(declaration);
138
+ for (const name of secrets) {
139
+ const value = merged[name];
140
+ if (!isEncryptedSecret(value)) {
141
+ // Unset or non-envelope — nothing usable to inject.
142
+ delete merged[name];
143
+ continue;
144
+ }
145
+ if (!this.secretsEnabled) {
146
+ delete merged[name];
147
+ continue;
148
+ }
149
+ try {
150
+ merged[name] = decryptSecret(value, this.encryptionKey);
151
+ }
152
+ catch (error) {
153
+ cmsLogger.error(`Failed to decrypt secret "${pluginId}.${name}":`, error);
154
+ delete merged[name];
155
+ }
156
+ }
157
+ return merged;
158
+ }
159
+ /**
160
+ * Effective values for the **client/API**: same merge, but secrets are **masked** —
161
+ * a stored secret becomes {@link SECRET_MASK}, an unset one an empty string. Plaintext
162
+ * secrets never cross this boundary.
163
+ */
164
+ async getMasked(organizationId, pluginId) {
165
+ const declaration = this.resolver.settingsDeclaration(pluginId);
166
+ const stored = (await this.db.getPluginSettings(organizationId, pluginId)) ?? {};
167
+ const defaults = declaration ? defaultsFor(declaration.fields) : {};
168
+ const merged = { ...defaults, ...stored };
169
+ if (declaration) {
170
+ for (const name of this.secretFieldNames(declaration)) {
171
+ merged[name] = isEncryptedSecret(merged[name]) ? SECRET_MASK : '';
172
+ }
173
+ }
174
+ return merged;
175
+ }
176
+ /**
177
+ * Resolve for the admin surface: the declaration plus masked values plus whether
178
+ * secrets are enabled. `declaration: null` when the plugin declares no settings.
179
+ */
180
+ async resolve(organizationId, pluginId) {
181
+ const declaration = this.resolver.settingsDeclaration(pluginId) ?? null;
182
+ const values = await this.getMasked(organizationId, pluginId);
183
+ return { declaration, values, secretsEnabled: this.secretsEnabled };
184
+ }
185
+ /**
186
+ * Persist a partial edit. Only declared field names are accepted, and each value is
187
+ * type-checked against its declaration — an invalid patch is rejected whole, never
188
+ * applied in part, so a failed save can't leave settings half-written. Secret fields
189
+ * are encrypted; a blank or still-masked secret submission means "leave unchanged"
190
+ * (so the client never has to echo the real value back). Returns the new **masked**
191
+ * values — a save response never leaks a plaintext secret.
192
+ *
193
+ * @throws {PluginSettingsValidationError} when a value doesn't match its field type.
194
+ */
195
+ async save(organizationId, pluginId, patch) {
196
+ const declaration = this.resolver.settingsDeclaration(pluginId);
197
+ if (!declaration) {
198
+ throw new Error(`Plugin "${pluginId}" has not declared any settings.`);
199
+ }
200
+ const fieldsByName = new Map(declaration.fields.map((f) => [f.name, f]));
201
+ const secrets = this.secretFieldNames(declaration);
202
+ const stored = (await this.db.getPluginSettings(organizationId, pluginId)) ?? {};
203
+ const next = { ...stored };
204
+ // Validate the whole patch before writing any of it.
205
+ const issues = [];
206
+ const pending = [];
207
+ for (const [key, value] of Object.entries(patch)) {
208
+ const field = fieldsByName.get(key);
209
+ if (!field)
210
+ continue; // undeclared → dropped
211
+ if (secrets.has(key)) {
212
+ // Write-only: blank or the untouched mask means "keep the current value".
213
+ if (value === '' || value === SECRET_MASK || value == null)
214
+ continue;
215
+ if (!this.secretsEnabled) {
216
+ throw new Error(`Cannot store secret "${pluginId}.${key}": no secretEncryptionKey configured.`);
217
+ }
218
+ }
219
+ const issue = checkValue(field, value);
220
+ if (issue)
221
+ issues.push(issue);
222
+ else
223
+ pending.push([key, value]);
224
+ }
225
+ if (issues.length > 0)
226
+ throw new PluginSettingsValidationError(issues);
227
+ for (const [key, value] of pending) {
228
+ next[key] = secrets.has(key)
229
+ ? encryptSecret(String(value), this.encryptionKey)
230
+ : value;
231
+ }
232
+ await this.db.setPluginSettings(organizationId, pluginId, next);
233
+ return this.getMasked(organizationId, pluginId);
234
+ }
235
+ }
@@ -1,6 +1,6 @@
1
1
  import type { CacheAdapter } from '../cache/index.js';
2
2
  import type { DatabaseAdapter } from '../db/index.js';
3
- import { type Capability, type Role } from '../types/capabilities.js';
3
+ import { type Role } from '../types/capabilities.js';
4
4
  /**
5
5
  * RolesService — caches per-org role capability lookups.
6
6
  *
@@ -23,7 +23,7 @@ export declare class RolesService {
23
23
  * 3. Built-in seed if the name matches a built-in.
24
24
  * 4. Empty list — unknown role → no capabilities.
25
25
  */
26
- getCapabilities(organizationId: string, roleName: string): Promise<Capability[]>;
26
+ getCapabilities(organizationId: string, roleName: string): Promise<string[]>;
27
27
  /** List every role defined for an organization. */
28
28
  listRoles(organizationId: string): Promise<Role[]>;
29
29
  /** Idempotent — safe to call on every request if you want. */
@@ -1 +1 @@
1
- {"version":3,"file":"roles-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/roles-service.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAGN,KAAK,UAAU,EACf,KAAK,IAAI,EACT,MAAM,uBAAuB,CAAC;AAI/B;;;;;GAKG;AACH,qBAAa,YAAY;IAKvB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG;IANZ,OAAO,CAAC,MAAM,CAAC,WAAW,CAAM;IAChC,OAAO,CAAC,QAAQ,CAA4C;gBAGnD,EAAE,EAAE,eAAe,EACnB,KAAK,GAAE,YAAY,GAAG,IAAW,EACjC,GAAG,GAAE,MAAiC;IAG/C;;;;;;;;OAQG;IACG,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAqBtF,mDAAmD;IAC7C,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAIxD,8DAA8D;IACxD,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,uEAAuE;IACjE,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAW5D,aAAa;CA2B3B"}
1
+ {"version":3,"file":"roles-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/roles-service.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAyC,KAAK,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAIzF;;;;;GAKG;AACH,qBAAa,YAAY;IAKvB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG;IANZ,OAAO,CAAC,MAAM,CAAC,WAAW,CAAM;IAChC,OAAO,CAAC,QAAQ,CAAwC;gBAG/C,EAAE,EAAE,eAAe,EACnB,KAAK,GAAE,YAAY,GAAG,IAAW,EACjC,GAAG,GAAE,MAAiC;IAG/C;;;;;;;;OAQG;IACG,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAqBlF,mDAAmD;IAC7C,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAIxD,8DAA8D;IACxD,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,uEAAuE;IACjE,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAW5D,aAAa;CA2B3B"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Emit theme tokens as a scoped `<style>` body.
3
+ *
4
+ * Two hard rules, both learned the expensive way:
5
+ * 1. NEVER emit site tokens at `:root` — they'd bleed into the admin chrome.
6
+ * Always scope to the site shell selector.
7
+ * 2. Theme values are user-authored, so sanitize before interpolating. Any value
8
+ * that could break out of the `--var: value;` declaration (contains `;`, `{`,
9
+ * `}`, `<`, `>`, or a CSS `url(`/`expression(`) is dropped, and the token's
10
+ * CSS fallback in the layout applies instead.
11
+ */
12
+ /** Return the value if safe to interpolate into a CSS declaration, else null. */
13
+ export declare function sanitizeTokenValue(value: string): string | null;
14
+ /**
15
+ * Build a sanitized `--var: value; …` declaration list from a `cssVar → value`
16
+ * map (see deriveThemeVars). Suitable for an inline `style` attribute on the site
17
+ * shell element — the simplest way to scope tokens to the site subtree while
18
+ * beating component-CSS specificity, with no `<style>` injection to guard. Returns
19
+ * `''` when nothing survives sanitization.
20
+ */
21
+ export declare function emitThemeVars(vars: Record<string, string>): string;
22
+ /**
23
+ * Build a scoped style *rule* from a `cssVar → value` map, for callers that
24
+ * prefer injecting a `<style>` block over an inline attribute. Returns `''` when
25
+ * nothing survives sanitization, so callers can skip rendering an empty `<style>`.
26
+ *
27
+ * @param selector CSS selector to scope the custom properties to, e.g. `.blog-shell`.
28
+ */
29
+ export declare function emitThemeStyle(selector: string, vars: Record<string, string>): string;
30
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/lib/theme/css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK/D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAWlE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAIrF"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Emit theme tokens as a scoped `<style>` body.
3
+ *
4
+ * Two hard rules, both learned the expensive way:
5
+ * 1. NEVER emit site tokens at `:root` — they'd bleed into the admin chrome.
6
+ * Always scope to the site shell selector.
7
+ * 2. Theme values are user-authored, so sanitize before interpolating. Any value
8
+ * that could break out of the `--var: value;` declaration (contains `;`, `{`,
9
+ * `}`, `<`, `>`, or a CSS `url(`/`expression(`) is dropped, and the token's
10
+ * CSS fallback in the layout applies instead.
11
+ */
12
+ const UNSAFE = /[;{}<>]|url\s*\(|expression\s*\(/i;
13
+ /** Return the value if safe to interpolate into a CSS declaration, else null. */
14
+ export function sanitizeTokenValue(value) {
15
+ const trimmed = value.trim();
16
+ if (trimmed === '')
17
+ return null;
18
+ if (UNSAFE.test(trimmed))
19
+ return null;
20
+ return trimmed;
21
+ }
22
+ /**
23
+ * Build a sanitized `--var: value; …` declaration list from a `cssVar → value`
24
+ * map (see deriveThemeVars). Suitable for an inline `style` attribute on the site
25
+ * shell element — the simplest way to scope tokens to the site subtree while
26
+ * beating component-CSS specificity, with no `<style>` injection to guard. Returns
27
+ * `''` when nothing survives sanitization.
28
+ */
29
+ export function emitThemeVars(vars) {
30
+ const declarations = [];
31
+ for (const [cssVar, rawValue] of Object.entries(vars)) {
32
+ if (!cssVar.startsWith('--'))
33
+ continue;
34
+ const value = sanitizeTokenValue(rawValue);
35
+ if (value === null)
36
+ continue;
37
+ declarations.push(`${cssVar}: ${value};`);
38
+ }
39
+ return declarations.join(' ');
40
+ }
41
+ /**
42
+ * Build a scoped style *rule* from a `cssVar → value` map, for callers that
43
+ * prefer injecting a `<style>` block over an inline attribute. Returns `''` when
44
+ * nothing survives sanitization, so callers can skip rendering an empty `<style>`.
45
+ *
46
+ * @param selector CSS selector to scope the custom properties to, e.g. `.blog-shell`.
47
+ */
48
+ export function emitThemeStyle(selector, vars) {
49
+ const body = emitThemeVars(vars);
50
+ if (body === '')
51
+ return '';
52
+ return `${selector} { ${body} }`;
53
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Derive the admin schema and the runtime CSS-var map from a token list.
3
+ *
4
+ * `deriveThemeFields()` feeds the `theme` singleton schema; `deriveThemeVars()`
5
+ * turns a saved theme document into `{ '--accent': '#…', … }`. Both walk the same
6
+ * token list, so the form and the rendered CSS can never drift. The app supplies
7
+ * the tokens (see the app's `theme/tokens.ts`).
8
+ */
9
+ import type { Field, FieldGroup } from '../types/schemas.js';
10
+ import type { ThemeToken } from './tokens.js';
11
+ /**
12
+ * Build the field-group list for a theme singleton, one group per distinct
13
+ * `token.group` in first-seen order. The first group is marked `default`.
14
+ */
15
+ export declare function deriveThemeFieldGroups(tokens: ThemeToken[]): FieldGroup[];
16
+ /** Build the field list for the `theme` singleton schema from the token set. */
17
+ export declare function deriveThemeFields(tokens: ThemeToken[]): Field[];
18
+ /**
19
+ * Resolve a theme document into a `cssVar → value` map, falling back to each
20
+ * token's default when the document omits or blanks a value. Font values are
21
+ * resolved to their full CSS stack; colors pass through (sanitized in ./css.ts).
22
+ *
23
+ * Accepts `unknown` so callers can pass a concrete generated document type (which
24
+ * lacks a string index signature) without casting; keys are read dynamically.
25
+ */
26
+ export declare function deriveThemeVars(values: unknown, tokens: ThemeToken[]): Record<string, string>;
27
+ //# sourceMappingURL=derive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../src/lib/theme/derive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAWzE;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,CA0C/D;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAuC7F"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Build the field-group list for a theme singleton, one group per distinct
3
+ * `token.group` in first-seen order. The first group is marked `default`.
4
+ */
5
+ export function deriveThemeFieldGroups(tokens) {
6
+ const seen = new Map();
7
+ for (const token of tokens) {
8
+ if (seen.has(token.group))
9
+ continue;
10
+ seen.set(token.group, {
11
+ name: token.group,
12
+ title: token.group.charAt(0).toUpperCase() + token.group.slice(1),
13
+ default: seen.size === 0
14
+ });
15
+ }
16
+ return [...seen.values()];
17
+ }
18
+ /** Build the field list for the `theme` singleton schema from the token set. */
19
+ export function deriveThemeFields(tokens) {
20
+ return tokens.map((token) => {
21
+ const base = {
22
+ name: token.name,
23
+ title: token.title,
24
+ description: token.description,
25
+ group: token.group
26
+ };
27
+ switch (token.kind) {
28
+ case 'color':
29
+ // Color is a plugin field widget, not a built-in type. Emit a string
30
+ // field wired to the color-picker input; without the plugin installed it
31
+ // degrades to a plain text input (still a valid CSS color string).
32
+ return { ...base, type: 'string', input: 'color', initialValue: token.default };
33
+ case 'range':
34
+ return {
35
+ ...base,
36
+ type: 'number',
37
+ min: token.min,
38
+ max: token.max,
39
+ step: token.step,
40
+ initialValue: token.default,
41
+ options: { layout: 'slider', unit: token.unit }
42
+ };
43
+ case 'select':
44
+ return {
45
+ ...base,
46
+ type: 'string',
47
+ initialValue: token.default,
48
+ list: token.options.map((o) => ({ title: o.title, value: o.value })),
49
+ options: { layout: 'dropdown' }
50
+ };
51
+ case 'font':
52
+ return {
53
+ ...base,
54
+ type: 'string',
55
+ initialValue: token.default,
56
+ list: token.options.map((o) => ({ title: o.title, value: o.value })),
57
+ options: { layout: 'dropdown' }
58
+ };
59
+ }
60
+ });
61
+ }
62
+ /**
63
+ * Resolve a theme document into a `cssVar → value` map, falling back to each
64
+ * token's default when the document omits or blanks a value. Font values are
65
+ * resolved to their full CSS stack; colors pass through (sanitized in ./css.ts).
66
+ *
67
+ * Accepts `unknown` so callers can pass a concrete generated document type (which
68
+ * lacks a string index signature) without casting; keys are read dynamically.
69
+ */
70
+ export function deriveThemeVars(values, tokens) {
71
+ const vars = {};
72
+ const doc = {};
73
+ if (values && typeof values === 'object')
74
+ Object.assign(doc, values);
75
+ for (const token of tokens) {
76
+ const raw = doc[token.name];
77
+ switch (token.kind) {
78
+ case 'color': {
79
+ vars[token.cssVar] =
80
+ typeof raw === 'string' && raw.trim() !== '' ? raw.trim() : token.default;
81
+ break;
82
+ }
83
+ case 'select': {
84
+ const selected = typeof raw === 'string' && raw.trim() !== '' ? raw.trim() : token.default;
85
+ const known = token.options.some((o) => o.value === selected);
86
+ vars[token.cssVar] = known ? selected : token.default;
87
+ break;
88
+ }
89
+ case 'range': {
90
+ const n = typeof raw === 'number' && Number.isFinite(raw) ? raw : token.default;
91
+ vars[token.cssVar] = `${n}${token.unit ?? ''}`;
92
+ break;
93
+ }
94
+ case 'font': {
95
+ // Map the stored value to its stack; unknown/blank → default option.
96
+ const selected = typeof raw === 'string' && raw.trim() !== '' ? raw.trim() : token.default;
97
+ const option = token.options.find((o) => o.value === selected) ??
98
+ token.options.find((o) => o.value === token.default) ??
99
+ token.options[0];
100
+ if (option)
101
+ vars[token.cssVar] = option.stack;
102
+ break;
103
+ }
104
+ }
105
+ }
106
+ return vars;
107
+ }
@@ -0,0 +1,5 @@
1
+ export * from './tokens.js';
2
+ export * from './derive.js';
3
+ export * from './css.js';
4
+ export * from './schemes.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/theme/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './tokens.js';
2
+ export * from './derive.js';
3
+ export * from './css.js';
4
+ export * from './schemes.js';
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Color schemes — the reusable palette unit.
3
+ *
4
+ * A scheme is seeded with THREE colors (surface, text, primary). Everything else —
5
+ * the on-primary contrast color, muted/faint text, hairline borders, raised
6
+ * surfaces, the hover-ink of the accent — is DERIVED, so every scheme is
7
+ * internally consistent and the editor tunes three dials instead of eight.
8
+ *
9
+ * Each scheme is emitted as a scoped class (`.scheme-<name>`) that remaps the same
10
+ * CSS custom properties the site components already consume (`--paper`, `--ink`,
11
+ * `--accent`, …). The site shell wears the default scheme; any section can wear a
12
+ * different one by adding its class — that's the page-builder primitive.
13
+ *
14
+ * Typography and layout are deliberately NOT part of a scheme: they're global,
15
+ * the same way Shopify keeps type/layout out of its color schemes.
16
+ */
17
+ import type { ArrayField } from '../types/schemas.js';
18
+ /** The three seed colors an editor sets per scheme. */
19
+ export interface ColorScheme {
20
+ /** Human label; also slugified into the scheme's CSS class. */
21
+ name: string;
22
+ /** Background. */
23
+ surface: string;
24
+ /** Foreground text. */
25
+ text: string;
26
+ /** Accent — links, buttons, highlights. */
27
+ primary: string;
28
+ }
29
+ /** Slugify a scheme name into a stable, safe CSS class fragment. */
30
+ export declare function schemeSlug(name: string): string;
31
+ /** The CSS class that carries a scheme's tokens, e.g. `scheme-dark`. */
32
+ export declare function schemeClass(name: string): string;
33
+ /**
34
+ * Pick a readable on-color (near-black or white) for text/icons that sit on top
35
+ * of `background`. Falls back to white when the color can't be parsed.
36
+ */
37
+ export declare function contrastColor(background: string): string;
38
+ /**
39
+ * Resolve a scheme's three seeds into the full CSS-var role map. Seeds are
40
+ * sanitized; anything invalid falls back to a sensible default so a scheme always
41
+ * emits a complete, coherent palette. The derived roles are `color-mix`
42
+ * expressions over `var(--ink)`/`var(--paper)`, so they recompute correctly for
43
+ * whichever scheme is in scope — no per-shade user input, no drift.
44
+ */
45
+ export declare function resolveSchemeVars(scheme: ColorScheme): Record<string, string>;
46
+ /**
47
+ * Emit one scoped rule per scheme, prefixed so it only styles the site subtree
48
+ * (never `:root`/admin chrome). Returns `''` when there are no schemes.
49
+ *
50
+ * @param scopeSelector Ancestor selector the scheme classes live under, e.g. `.blog-shell`.
51
+ */
52
+ export declare function emitSchemeStyles(schemes: ColorScheme[], scopeSelector: string): string;
53
+ /** Read a theme document's `schemes` array, falling back to `defaults` when absent. */
54
+ export declare function readSchemes(values: unknown, defaults: ColorScheme[]): ColorScheme[];
55
+ /**
56
+ * Build the `schemes` array field for the theme singleton — a repeatable object
57
+ * of { name, surface, text, primary }. The first scheme is the site default.
58
+ */
59
+ export declare function deriveSchemesField(defaults: ColorScheme[], group: string): ArrayField;
60
+ //# sourceMappingURL=schemes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemes.d.ts","sourceRoot":"","sources":["../../src/lib/theme/schemes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC3B,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;CAChB;AAQD,oEAAoE;AACpE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AA0BD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAQxD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkB7E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAYtF;AAED,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAmBnF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAwBrF"}