@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
@@ -18,6 +18,69 @@ export function isFieldRequired(field) {
18
18
  return false;
19
19
  }
20
20
  }
21
+ function describeValue(value) {
22
+ if (Array.isArray(value))
23
+ return 'an array';
24
+ if (value === null)
25
+ return 'null';
26
+ if (typeof value === 'object')
27
+ return 'an object';
28
+ return `a ${typeof value}`;
29
+ }
30
+ const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
31
+ /**
32
+ * Structural (shape) validation for a field's stored value — the depth=0 write
33
+ * shape. This catches a caller (notably an AI agent over MCP) sending the wrong
34
+ * JSON shape that presence/required checks would miss: a slug as `{ current }`
35
+ * (Sanity's convention — AphexCMS stores slugs as plain strings), or a
36
+ * reference/image missing its `_ref`. Runs before the user's Rule validation
37
+ * and only when a value is meaningfully present (absent/empty is a required-ness
38
+ * concern, handled separately), so optional and half-filled fields are left
39
+ * alone. Returns an error message, or null when the shape is acceptable.
40
+ *
41
+ * Intentionally conservative: only unambiguous mismatches error, and empty
42
+ * placeholders (`''`, an image with no `asset`) are treated as absent so the
43
+ * admin's in-progress edit states don't trip it.
44
+ */
45
+ export function validateValueShape(field, value) {
46
+ // Absent (or an empty-string placeholder for a non-string field) → shape is
47
+ // irrelevant here; presence is enforced by Rule().required().
48
+ if (value === null || value === undefined)
49
+ return null;
50
+ switch (field.type) {
51
+ case 'string':
52
+ case 'text':
53
+ case 'slug':
54
+ case 'url':
55
+ return typeof value === 'string' ? null : `expected a string, got ${describeValue(value)}`;
56
+ case 'reference':
57
+ if (value === '')
58
+ return null;
59
+ return isPlainObject(value) && typeof value._ref === 'string'
60
+ ? null
61
+ : `expected a reference object { _type: 'reference', _ref: '<documentId>' }, got ${describeValue(value)}`;
62
+ case 'image':
63
+ case 'file': {
64
+ if (value === '')
65
+ return null;
66
+ if (!isPlainObject(value))
67
+ return `expected an ${field.type} object { _type: '${field.type}', asset: { _type: 'reference', _ref: '<assetId>' } }, got ${describeValue(value)}`;
68
+ // An object with no asset yet is a valid empty/in-progress state.
69
+ if (value.asset === undefined || value.asset === null)
70
+ return null;
71
+ return isPlainObject(value.asset) && typeof value.asset._ref === 'string'
72
+ ? null
73
+ : `${field.type} asset must be { _type: 'reference', _ref: '<assetId>' }`;
74
+ }
75
+ case 'array':
76
+ return Array.isArray(value) ? null : `expected an array, got ${describeValue(value)}`;
77
+ case 'object':
78
+ return isPlainObject(value) ? null : `expected an object, got ${describeValue(value)}`;
79
+ default:
80
+ // number/boolean/date/datetime — left to existing auto-rules / user rules.
81
+ return null;
82
+ }
83
+ }
21
84
  /**
22
85
  * Validate a field value against its validation rules
23
86
  */
@@ -28,6 +91,17 @@ export async function validateField(field, value, context = {}) {
28
91
  hasValidation: !!field.validation
29
92
  });
30
93
  const allErrors = [];
94
+ // Structural shape check first: if the value is the wrong JSON shape (e.g. a
95
+ // slug sent as `{ current }`, or a reference without `_ref`), report that and
96
+ // stop — the type-assuming auto-rules and user rules below expect the correct
97
+ // primitive/shape and would otherwise throw or emit confusing errors.
98
+ const shapeError = validateValueShape(field, value);
99
+ if (shapeError) {
100
+ return {
101
+ isValid: false,
102
+ errors: [{ level: 'error', message: `Field "${field.name}" ${shapeError}` }]
103
+ };
104
+ }
31
105
  // Add automatic validation for date/datetime/url fields based on type
32
106
  if (field.type === 'date') {
33
107
  const dateField = field;
@@ -1 +1 @@
1
- {"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../../src/lib/graphql/resolvers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;AA4H1D,wBAAgB,eAAe,CAC9B,GAAG,EAAE,YAAY,EACjB,WAAW,EAAE,UAAU,EAAE,EACzB,kBAAkB,GAAE,OAAO,GAAG,WAAyB,uBA2tBvD"}
1
+ {"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../../src/lib/graphql/resolvers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;AAyH1D,wBAAgB,eAAe,CAC9B,GAAG,EAAE,YAAY,EACjB,WAAW,EAAE,UAAU,EAAE,EACzB,kBAAkB,GAAE,OAAO,GAAG,WAAyB,uBA4tBvD"}
@@ -2,9 +2,7 @@ import { GraphQLError } from 'graphql';
2
2
  import { authToContext } from '../local-api/auth-helpers.js';
3
3
  import { getDefaultValueForFieldType } from '../utils/field-defaults.js';
4
4
  import { cmsLogger } from '../utils/logger.js';
5
- function capitalizeFirst(str) {
6
- return str.charAt(0).toUpperCase() + str.slice(1);
7
- }
5
+ import { toPascalCase, toCamelCase } from '../utils/string-case.js';
8
6
  // Normalize null/undefined field values to type-appropriate defaults (recursive)
9
7
  function normalizeDocumentFields(data, schemaType, allSchemaTypes) {
10
8
  if (!data)
@@ -130,7 +128,7 @@ export function createResolvers(cms, schemaTypes, defaultPerspective = 'publishe
130
128
  // Generate reference field resolvers for all types
131
129
  function generateReferenceFieldResolvers() {
132
130
  schemaTypes.forEach((schemaType) => {
133
- const typeName = capitalizeFirst(schemaType.name);
131
+ const typeName = toPascalCase(schemaType.name);
134
132
  function processFields(fields, currentTypeName) {
135
133
  fields.forEach((field) => {
136
134
  // Handle reference fields
@@ -244,7 +242,7 @@ export function createResolvers(cms, schemaTypes, defaultPerspective = 'publishe
244
242
  }
245
243
  // Handle nested objects
246
244
  if (field.type === 'object' && field.fields) {
247
- const nestedTypeName = capitalizeFirst(`${schemaType.name}${field.name}Object`);
245
+ const nestedTypeName = toPascalCase(`${schemaType.name}${field.name}Object`);
248
246
  processFields(field.fields, nestedTypeName);
249
247
  }
250
248
  });
@@ -262,11 +260,11 @@ export function createResolvers(cms, schemaTypes, defaultPerspective = 'publishe
262
260
  if (field.type === 'array' && field.of && field.of.length > 1) {
263
261
  const validTypes = field.of.filter((item) => schemaTypes.find((s) => s.name === item.type));
264
262
  if (validTypes.length > 1) {
265
- const unionName = `${capitalizeFirst(parentName)}${capitalizeFirst(field.name)}Item`;
263
+ const unionName = `${toPascalCase(parentName)}${toPascalCase(field.name)}Item`;
266
264
  resolvers[unionName] = {
267
265
  __resolveType(obj) {
268
266
  if (obj._type) {
269
- return capitalizeFirst(obj._type);
267
+ return toPascalCase(obj._type);
270
268
  }
271
269
  return null;
272
270
  }
@@ -286,7 +284,8 @@ export function createResolvers(cms, schemaTypes, defaultPerspective = 'publishe
286
284
  // Generate resolvers for each document type
287
285
  const documentTypes = schemaTypes.filter((type) => type.type === 'document');
288
286
  documentTypes.forEach((schemaType) => {
289
- const typeName = capitalizeFirst(schemaType.name);
287
+ const typeName = toPascalCase(schemaType.name);
288
+ const fieldName = toCamelCase(schemaType.name);
290
289
  // Singleton resolvers: no-arg query, no-id mutations.
291
290
  // Schema/codegen already differs for singletons (see schema.ts) — the
292
291
  // resolver just delegates to the singleton-aware CollectionAPI methods.
@@ -306,7 +305,7 @@ export function createResolvers(cms, schemaTypes, defaultPerspective = 'publishe
306
305
  ...normalizedData
307
306
  };
308
307
  };
309
- resolvers.Query[schemaType.name] = async (_, args, context) => {
308
+ resolvers.Query[fieldName] = async (_, args, context) => {
310
309
  try {
311
310
  const { localAPI, auth } = context;
312
311
  const apiContext = authToContext(auth);
@@ -404,7 +403,7 @@ export function createResolvers(cms, schemaTypes, defaultPerspective = 'publishe
404
403
  return; // skip the regular per-type resolvers below for singletons
405
404
  }
406
405
  // Single document resolver: page(id: "123", perspective: "draft")
407
- resolvers.Query[schemaType.name] = async (_, args, context) => {
406
+ resolvers.Query[fieldName] = async (_, args, context) => {
408
407
  try {
409
408
  const { localAPI, auth } = context;
410
409
  const apiContext = authToContext(auth);
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/lib/graphql/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAkD,MAAM,kBAAkB,CAAC;AA0YnG,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CA2FvE"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/lib/graphql/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAkD,MAAM,kBAAkB,CAAC;AAyYnG,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CA2FvE"}
@@ -1,6 +1,4 @@
1
- function capitalizeFirst(str) {
2
- return str.charAt(0).toUpperCase() + str.slice(1);
3
- }
1
+ import { toPascalCase, toCamelCase } from '../utils/string-case.js';
4
2
  function generateGraphQLField(field, schemaTypes, parentName = '') {
5
3
  const nullability = isFieldRequired(field) ? '!' : '';
6
4
  const fieldType = getGraphQLType(field, schemaTypes, parentName);
@@ -44,7 +42,7 @@ function handleArrayField(field, schemaTypes, parentName = '') {
44
42
  const refItem = refItems[0];
45
43
  const to = refItem.to;
46
44
  if (to && to.length === 1) {
47
- return `[${capitalizeFirst(to[0].type)}]`;
45
+ return `[${toPascalCase(to[0].type)}]`;
48
46
  }
49
47
  return '[JSON]';
50
48
  }
@@ -56,22 +54,22 @@ function handleArrayField(field, schemaTypes, parentName = '') {
56
54
  // If array contains only one type
57
55
  if (validTypes.length === 1) {
58
56
  const itemType = validTypes[0];
59
- return `[${capitalizeFirst(itemType.type)}]`;
57
+ return `[${toPascalCase(itemType.type)}]`;
60
58
  }
61
59
  // For multiple types in array, create union type with parent prefix
62
- const unionName = `${capitalizeFirst(parentName)}${capitalizeFirst(field.name)}Item`;
60
+ const unionName = `${toPascalCase(parentName)}${toPascalCase(field.name)}Item`;
63
61
  return `[${unionName}]`;
64
62
  }
65
63
  function handleObjectField(field, _schemaTypes, parentName = '') {
66
64
  if (field.fields && field.fields.length > 0) {
67
65
  // Inline object - create a unique type name with parent prefix
68
- return capitalizeFirst(`${parentName}${field.name}Object`);
66
+ return toPascalCase(`${parentName}${field.name}Object`);
69
67
  }
70
68
  return 'String'; // JSON string fallback
71
69
  }
72
70
  function handleReferenceField(field) {
73
71
  if (field.to && field.to.length === 1) {
74
- return capitalizeFirst(field.to[0].type);
72
+ return toPascalCase(field.to[0].type);
75
73
  }
76
74
  return 'String'; // ID reference for MVP
77
75
  }
@@ -82,7 +80,7 @@ function isFieldRequired(field) {
82
80
  return field.validation.toString().includes('required');
83
81
  }
84
82
  function generateObjectType(schemaType, allSchemaTypes) {
85
- const typeName = capitalizeFirst(schemaType.name);
83
+ const typeName = toPascalCase(schemaType.name);
86
84
  const fields = schemaType.fields
87
85
  .map((field) => generateGraphQLField(field, allSchemaTypes, schemaType.name))
88
86
  .join('\n');
@@ -91,7 +89,7 @@ ${fields}
91
89
  }`;
92
90
  }
93
91
  function generateDocumentType(schemaType, allSchemaTypes) {
94
- const typeName = capitalizeFirst(schemaType.name);
92
+ const typeName = toPascalCase(schemaType.name);
95
93
  const customFields = schemaType.fields
96
94
  .map((field) => generateGraphQLField(field, allSchemaTypes, schemaType.name))
97
95
  .join('\n');
@@ -111,7 +109,7 @@ function generateInlineObjectTypes(schemaTypes) {
111
109
  fields.forEach((field) => {
112
110
  if (field.type === 'object' && field.fields) {
113
111
  const objectField = field;
114
- const typeName = capitalizeFirst(`${parentName}${field.name}Object`);
112
+ const typeName = toPascalCase(`${parentName}${field.name}Object`);
115
113
  const fieldDefs = objectField.fields
116
114
  .map((f) => generateGraphQLField(f, schemaTypes, `${parentName}${field.name}`))
117
115
  .join('\n');
@@ -127,8 +125,8 @@ ${fieldDefs}
127
125
  // Only create union for types that exist in schemaTypes
128
126
  const validTypes = arrayField.of.filter((item) => schemaTypes.find((s) => s.name === item.type));
129
127
  if (validTypes.length > 1) {
130
- const unionName = `${capitalizeFirst(parentName)}${capitalizeFirst(field.name)}Item`;
131
- const unionTypes = validTypes.map((item) => capitalizeFirst(item.type)).join(' | ');
128
+ const unionName = `${toPascalCase(parentName)}${toPascalCase(field.name)}Item`;
129
+ const unionTypes = validTypes.map((item) => toPascalCase(item.type)).join(' | ');
132
130
  inlineTypes.push(`union ${unionName} = ${unionTypes}`);
133
131
  }
134
132
  }
@@ -186,7 +184,7 @@ input IDFilter {
186
184
  }
187
185
  // Generate where input type for a specific document type
188
186
  function generateWhereInputType(schemaType, _allSchemaTypes) {
189
- const typeName = capitalizeFirst(schemaType.name);
187
+ const typeName = toPascalCase(schemaType.name);
190
188
  const whereTypeName = `${typeName}WhereInput`;
191
189
  // Generate field filters
192
190
  const fieldFilters = [];
@@ -223,7 +221,7 @@ function getFilterType(field) {
223
221
  }
224
222
  // Generate data input type for mutations
225
223
  function generateDataInputType(schemaType, allSchemaTypes) {
226
- const typeName = capitalizeFirst(schemaType.name);
224
+ const typeName = toPascalCase(schemaType.name);
227
225
  const inputTypeName = `${typeName}DataInput`;
228
226
  const fields = [];
229
227
  schemaType.fields.forEach((field) => {
@@ -268,16 +266,17 @@ function generateQueryFields(schemaTypes) {
268
266
  const documentTypes = schemaTypes.filter((type) => type.type === 'document');
269
267
  return documentTypes
270
268
  .map((schemaType) => {
271
- const typeName = capitalizeFirst(schemaType.name);
269
+ const typeName = toPascalCase(schemaType.name);
272
270
  // Singletons resolve to a single canonical row — no id arg, no
273
271
  // `all` query. Lazy-creates on first access via the resolver.
272
+ const fieldName = toCamelCase(schemaType.name);
274
273
  if (schemaType.singleton) {
275
274
  return ` # Get the ${schemaType.name} singleton (lazy-creates an empty draft on first access)
276
- ${schemaType.name}(perspective: String, depth: Int): ${typeName}!`;
275
+ ${fieldName}(perspective: String, depth: Int): ${typeName}!`;
277
276
  }
278
277
  const whereInputType = `${typeName}WhereInput`;
279
278
  return ` # Get a single ${schemaType.name} by ID
280
- ${schemaType.name}(id: ID!, perspective: String, depth: Int): ${typeName}
279
+ ${fieldName}(id: ID!, perspective: String, depth: Int): ${typeName}
281
280
 
282
281
  # Get all ${schemaType.name} documents with filtering
283
282
  all${typeName}(
@@ -295,7 +294,7 @@ function generateMutationFields(schemaTypes) {
295
294
  const documentTypes = schemaTypes.filter((type) => type.type === 'document');
296
295
  return documentTypes
297
296
  .map((schemaType) => {
298
- const typeName = capitalizeFirst(schemaType.name);
297
+ const typeName = toPascalCase(schemaType.name);
299
298
  const dataInputType = `${typeName}DataInput`;
300
299
  // Singletons skip create/delete/all: there's only ever one row, with
301
300
  // a deterministic id, so update/publish/unpublish operate on it
package/dist/hooks.d.ts CHANGED
@@ -9,8 +9,10 @@ import type { AuthProvider } from './auth/provider.js';
9
9
  import type { GraphQLSettings } from './graphql/index.js';
10
10
  import type { Logger } from './utils/logger.js';
11
11
  import { RolesService } from './services/roles-service.js';
12
+ import { PluginSettingsService } from './services/plugin-settings-service.js';
12
13
  import { CMSEngine } from './engine.js';
13
14
  import { type LocalAPI } from './local-api/index.js';
15
+ import { type PartResolver } from './plugins/resolver.js';
14
16
  import { type AphexEnv } from './server/api/index.js';
15
17
  export interface CMSInstances {
16
18
  config: CMSConfig;
@@ -21,10 +23,14 @@ export interface CMSInstances {
21
23
  cmsEngine: CMSEngine;
22
24
  localAPI: LocalAPI;
23
25
  rolesService: RolesService;
26
+ /** Per-(org, plugin) settings store — the config plane for plugins. */
27
+ pluginSettingsService: PluginSettingsService;
24
28
  logger: Logger;
25
29
  auth?: AuthProvider;
26
30
  graphqlSettings?: GraphQLSettings | null;
27
31
  apiApp: Hono<AphexEnv>;
32
+ /** Indexed plugin parts (routes, document actions, admin tools, field components). */
33
+ partResolver: PartResolver;
28
34
  }
29
35
  /**
30
36
  * Called by the Vite HMR plugin (`@aphexcms/cms-core/vite`) when schema
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAK7C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAa,SAAS,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAIN,KAAK,QAAQ,EACb,MAAM,oBAAoB,CAAC;AAG5B,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;CACvB;AAQD;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAGrE;AAgBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CA0JvD"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAO7C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAa,SAAS,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAIN,KAAK,QAAQ,EACb,MAAM,oBAAoB,CAAC;AAG5B,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,uEAAuE;IACvE,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvB,sFAAsF;IACtF,YAAY,EAAE,YAAY,CAAC;CAC3B;AAmCD;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAGrE;AAgBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAmMvD"}
package/dist/hooks.js CHANGED
@@ -1,11 +1,35 @@
1
1
  import { handleAuthHook } from './auth/auth-hooks.js';
2
+ import { getPreviewPerspective } from './preview/perspective.js';
3
+ import { resolveCapabilities } from './types/capabilities.js';
2
4
  import { cmsLogger, setLogLevel, setLogger } from './utils/logger.js';
3
5
  import { createStorageAdapter as createStorageAdapterProvider } from './storage/providers/storage.js';
4
6
  import { AssetService as AssetServiceClass } from './services/asset-service.js';
5
7
  import { RolesService } from './services/roles-service.js';
8
+ import { PluginSettingsService } from './services/plugin-settings-service.js';
6
9
  import { createCMS } from './engine.js';
7
10
  import { createLocalAPI } from './local-api/index.js';
11
+ import { createPartResolver } from './plugins/resolver.js';
8
12
  import { createAphexApi, mountAphexBuiltins, toHonoHandler } from './server/api/index.js';
13
+ /**
14
+ * Wrap a plugin route handler so it enforces `requiredCapabilities` before running.
15
+ * 401 when there's no authenticated principal at all; 403 when authenticated but
16
+ * missing a required capability. Uses the same server-resolved capability set every
17
+ * core resource checks — the client can't forge it.
18
+ */
19
+ function gateHandler(handler, required) {
20
+ return (c) => {
21
+ const auth = c.var.auth;
22
+ if (!auth || auth.type === 'partial_session') {
23
+ return c.json({ success: false, error: 'Authentication required' }, 401);
24
+ }
25
+ const caps = resolveCapabilities(auth);
26
+ const missing = required.filter((cap) => !caps.has(cap));
27
+ if (missing.length > 0) {
28
+ return c.json({ success: false, error: 'Insufficient permissions', missingCapabilities: missing }, 403);
29
+ }
30
+ return handler(c);
31
+ };
32
+ }
9
33
  let cmsInstances = null;
10
34
  let schemaError = null;
11
35
  let initPromise = null;
@@ -89,8 +113,28 @@ export function createCMSHook(config) {
89
113
  // Build the Hono API app shell. User middleware/overrides register
90
114
  // FIRST (so they sit ahead of built-ins in the chain), then we mount
91
115
  // the built-in routes, then GraphQL.
116
+ // Index plugin parts (validates duplicate part ids). Mount plugin server
117
+ // routes after the user's `api` hook and before built-ins, so a plugin's
118
+ // `POST /bookings` becomes `POST /api/bookings`, overridable by the app.
119
+ const partResolver = createPartResolver(currentConfig.plugins ?? []);
120
+ // Per-(org, plugin) config store — merges declared defaults with stored
121
+ // values and writes edits back, scoped to the org. The encryption key gates
122
+ // `secret` fields (absent → secrets disabled, fail safe).
123
+ const pluginSettingsService = new PluginSettingsService(databaseAdapter, partResolver, currentConfig.security?.secretEncryptionKey ?? null);
92
124
  const apiApp = createAphexApi();
93
125
  currentConfig.api?.(apiApp);
126
+ for (const route of partResolver.serverRoutes()) {
127
+ // Gate every plugin route by its declared `requiredCapabilities` before the
128
+ // handler runs, so a declared capability is ENFORCED rather than merely
129
+ // documented. `'public'` is the single ungated path and the author had to
130
+ // write it: an empty list still requires authentication, and omitting the
131
+ // field entirely doesn't type-check. Ungated is therefore always a choice,
132
+ // never an oversight.
133
+ const handler = route.requiredCapabilities === 'public'
134
+ ? route.handler
135
+ : gateHandler(route.handler, route.requiredCapabilities);
136
+ apiApp.on(route.method, route.path, handler);
137
+ }
94
138
  mountAphexBuiltins(apiApp);
95
139
  // Initialize schemas with validation
96
140
  try {
@@ -115,9 +159,11 @@ export function createCMSHook(config) {
115
159
  cmsEngine,
116
160
  localAPI,
117
161
  rolesService,
162
+ pluginSettingsService,
118
163
  logger: cmsLogger,
119
164
  auth: currentConfig.auth?.provider,
120
- apiApp
165
+ apiApp,
166
+ partResolver
121
167
  }, currentConfig.schemaTypes, graphqlConfig);
122
168
  // Register GraphQL directly on the Hono app. The Yoga handler
123
169
  // internally distinguishes GET (GraphiQL UI) from POST (queries),
@@ -147,10 +193,12 @@ export function createCMSHook(config) {
147
193
  cmsEngine: cmsEngine,
148
194
  localAPI: localAPI,
149
195
  rolesService,
196
+ pluginSettingsService,
150
197
  logger: cmsLogger,
151
198
  auth: currentConfig.auth?.provider,
152
199
  graphqlSettings,
153
- apiApp
200
+ apiApp,
201
+ partResolver
154
202
  };
155
203
  resolveInit();
156
204
  }
@@ -166,6 +214,15 @@ export function createCMSHook(config) {
166
214
  if (authResponse)
167
215
  return authResponse;
168
216
  }
217
+ // Resolve the read perspective once per request so site loads inherit it
218
+ // (published normally / draft in an authenticated `?aphex-preview` session)
219
+ // via `locals.previewPerspective` — no per-load wiring. Apps can override the
220
+ // policy with `config.preview.resolvePerspective`.
221
+ event.locals.previewPerspective =
222
+ currentConfig.preview?.resolvePerspective?.({
223
+ auth: event.locals.auth,
224
+ url: event.url
225
+ }) ?? getPreviewPerspective(event.locals.auth, event.url);
169
226
  return resolve(event);
170
227
  };
171
228
  }
package/dist/index.d.ts CHANGED
@@ -4,6 +4,8 @@ export * from './field-validation/rule.js';
4
4
  export * from './field-validation/utils.js';
5
5
  export { createContentHash, hasUnpublishedChanges } from './utils/content-hash.js';
6
6
  export * from './schema-utils/index.js';
7
+ export * from './theme/index.js';
8
+ export * from './plugins/index.js';
7
9
  export * from './utils/index.js';
8
10
  export * from './api/index.js';
9
11
  export type { ApiResponse } from './api/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAkBA,cAAc,eAAe,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGjG,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AAGzC,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAGhF,cAAc,sBAAsB,CAAC;AAGrC,cAAc,eAAe,CAAC;AAG9B,cAAc,aAAa,CAAC;AAC5B,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAkBA,cAAc,eAAe,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGjG,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AAGzC,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAGhF,cAAc,sBAAsB,CAAC;AAGrC,cAAc,eAAe,CAAC;AAI9B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,eAAe,CAAC;AAG9B,cAAc,aAAa,CAAC;AAC5B,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -23,6 +23,11 @@ export * from './field-validation/utils.js';
23
23
  export { createContentHash, hasUnpublishedChanges } from './utils/content-hash.js';
24
24
  // Schema utilities
25
25
  export * from './schema-utils/index.js';
26
+ // Theme design-system tokens — plain TS (Svelte-free), safe for the universal barrel.
27
+ export * from './theme/index.js';
28
+ // Plugin API — definePlugin(), part types, part resolver. Runtime is plain JS
29
+ // (svelte/hono imports are type-only), so it's safe on both server and client.
30
+ export * from './plugins/index.js';
26
31
  // General utility functions (logger, image URL builder, etc)
27
32
  export * from './utils/index.js';
28
33
  // Unified API client
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Rich-text block preview registry (client-side context).
3
+ *
4
+ * By default a custom Portable Text block renders in the editor as a generic card
5
+ * (title/subtitle from its `preview` config). That's fine for data-ish blocks, but for
6
+ * visual ones — an embed, a gallery, a button — authors expect to see the real thing
7
+ * inline while writing (the Ghost/Sanity "what you see is what you get" editor).
8
+ *
9
+ * An app registers a preview per block `_type`; RichtextField resolves it and the
10
+ * ProseMirror node view mounts it INSTEAD of the generic card. The preview still gets
11
+ * `onEdit`/`onDelete` so the block stays editable and removable.
12
+ *
13
+ * Deliberately separate from the field-component registry: that one supplies *inputs*
14
+ * (`field`/`value`/`onUpdate`); this one supplies *renderers* (`data`/`onEdit`). Same
15
+ * idea, different contract.
16
+ */
17
+ import { type Component } from 'svelte';
18
+ import type { PreviewSource } from '../utils/preview.js';
19
+ /**
20
+ * The stable props a block preview component receives.
21
+ *
22
+ * Also the contract for core's own built-in views (the generic card and the image
23
+ * view), so all three are mountable by the node view through one type.
24
+ */
25
+ export interface BlockPreviewProps {
26
+ /** The block's `_type`. */
27
+ type: string;
28
+ /** The block's `_key` — its stable identity within the field's array. */
29
+ nodeKey: string;
30
+ /** The block's stored data (its fields). */
31
+ data: Record<string, unknown>;
32
+ /** The block type's schema, for reading its `preview` config if useful. */
33
+ schema?: PreviewSource;
34
+ /** True while the block is selected in the editor. */
35
+ selected?: boolean;
36
+ /** Open the block's edit modal — wire this to a click/edit affordance. */
37
+ onEdit: () => void;
38
+ /** Remove the block. */
39
+ onDelete: () => void;
40
+ }
41
+ export type BlockPreviewLookup = (type: string) => Component<BlockPreviewProps> | undefined;
42
+ /** Publish the block-preview lookup to descendants (call in the admin shell). */
43
+ export declare function setBlockPreviews(lookup: BlockPreviewLookup): void;
44
+ /** Resolve the lookup. Returns a no-op lookup outside the admin shell. */
45
+ export declare function useBlockPreviews(): BlockPreviewLookup;
46
+ //# sourceMappingURL=block-previews.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-previews.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/admin/block-previews.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IACjC,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,2EAA2E;IAC3E,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAAC;AAI5F,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAEjE;AAED,0EAA0E;AAC1E,wBAAgB,gBAAgB,IAAI,kBAAkB,CAErD"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Rich-text block preview registry (client-side context).
3
+ *
4
+ * By default a custom Portable Text block renders in the editor as a generic card
5
+ * (title/subtitle from its `preview` config). That's fine for data-ish blocks, but for
6
+ * visual ones — an embed, a gallery, a button — authors expect to see the real thing
7
+ * inline while writing (the Ghost/Sanity "what you see is what you get" editor).
8
+ *
9
+ * An app registers a preview per block `_type`; RichtextField resolves it and the
10
+ * ProseMirror node view mounts it INSTEAD of the generic card. The preview still gets
11
+ * `onEdit`/`onDelete` so the block stays editable and removable.
12
+ *
13
+ * Deliberately separate from the field-component registry: that one supplies *inputs*
14
+ * (`field`/`value`/`onUpdate`); this one supplies *renderers* (`data`/`onEdit`). Same
15
+ * idea, different contract.
16
+ */
17
+ import { getContext, setContext } from 'svelte';
18
+ const BLOCK_PREVIEWS_KEY = Symbol.for('aphex.admin.block-previews');
19
+ /** Publish the block-preview lookup to descendants (call in the admin shell). */
20
+ export function setBlockPreviews(lookup) {
21
+ setContext(BLOCK_PREVIEWS_KEY, lookup);
22
+ }
23
+ /** Resolve the lookup. Returns a no-op lookup outside the admin shell. */
24
+ export function useBlockPreviews() {
25
+ return getContext(BLOCK_PREVIEWS_KEY) ?? (() => undefined);
26
+ }
27
+ //# sourceMappingURL=block-previews.svelte.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-previews.svelte.js","sourceRoot":"","sources":["../../../src/lib/admin/block-previews.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAkB,MAAM,QAAQ,CAAC;AA4BhE,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;AAEpE,iFAAiF;AACjF,MAAM,UAAU,gBAAgB,CAAC,MAA0B;IAC1D,UAAU,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,gBAAgB;IAC/B,OAAO,UAAU,CAAiC,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;AAC5F,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Field-input widget registry (client-side context).
3
+ *
4
+ * Plugins contribute custom input widgets via `aphex/field/component` parts, keyed
5
+ * by an `input` string. A field opts into one with `{ …, input: 'color' }`.
6
+ * The admin shell publishes a lookup here; SchemaField (however deeply nested)
7
+ * resolves the widget and renders it in place of the built-in for that field type.
8
+ */
9
+ import { type Component } from 'svelte';
10
+ import type { FieldComponentProps } from '../plugins/types.js';
11
+ export type FieldComponentLookup = (input: string) => Component<FieldComponentProps> | undefined;
12
+ /** Publish the widget lookup to descendants (call in the admin shell). */
13
+ export declare function setFieldComponents(lookup: FieldComponentLookup): void;
14
+ /** Resolve the widget lookup. Returns a no-op lookup outside the admin shell. */
15
+ export declare function useFieldComponents(): FieldComponentLookup;
16
+ //# sourceMappingURL=field-components.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-components.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/admin/field-components.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC,mBAAmB,CAAC,GAAG,SAAS,CAAC;AAIjG,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAErE;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,IAAI,oBAAoB,CAEzD"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Field-input widget registry (client-side context).
3
+ *
4
+ * Plugins contribute custom input widgets via `aphex/field/component` parts, keyed
5
+ * by an `input` string. A field opts into one with `{ …, input: 'color' }`.
6
+ * The admin shell publishes a lookup here; SchemaField (however deeply nested)
7
+ * resolves the widget and renders it in place of the built-in for that field type.
8
+ */
9
+ import { getContext, setContext } from 'svelte';
10
+ const FIELD_COMPONENTS_KEY = Symbol.for('aphex.admin.field-components');
11
+ /** Publish the widget lookup to descendants (call in the admin shell). */
12
+ export function setFieldComponents(lookup) {
13
+ setContext(FIELD_COMPONENTS_KEY, lookup);
14
+ }
15
+ /** Resolve the widget lookup. Returns a no-op lookup outside the admin shell. */
16
+ export function useFieldComponents() {
17
+ return getContext(FIELD_COMPONENTS_KEY) ?? (() => undefined);
18
+ }
19
+ //# sourceMappingURL=field-components.svelte.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-components.svelte.js","sourceRoot":"","sources":["../../../src/lib/admin/field-components.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAkB,MAAM,QAAQ,CAAC;AAKhE,MAAM,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;AAExE,0EAA0E;AAC1E,MAAM,UAAU,kBAAkB,CAAC,MAA4B;IAC9D,UAAU,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,kBAAkB;IACjC,OAAO,UAAU,CAAmC,oBAAoB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;AAChG,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { AdminArea } from './types.js';
2
+ /** The known admin URL params. Central list so intents never typo a key. */
3
+ export type AdminParam = 'view' | 'docType' | 'docId' | 'action' | 'stack' | 'history' | 'focus' | 'orgId' | 'fromDocId' | 'fromDocType';
4
+ /** A set of param changes: a value sets the key, `null` clears it. */
5
+ export type ParamPatch = Partial<Record<AdminParam, string | null>>;
6
+ export interface AdminNav {
7
+ /** Apply a param patch and navigate. `replace` defaults to true. */
8
+ patch(changes: ParamPatch, opts?: {
9
+ replace?: boolean;
10
+ }): Promise<void>;
11
+ /** Switch the top-level area/tab. `structure` clears `?view`; others set it. */
12
+ openArea(area: AdminArea): Promise<void>;
13
+ /** Show a document type's list (structure area). */
14
+ openType(docType: string): Promise<void>;
15
+ /**
16
+ * Open a document in the editor (structure area). `docType` is optional — when
17
+ * omitted the existing `?docType` is preserved (the URL effect resolves it).
18
+ */
19
+ openDocument(docId: string, docType?: string, opts?: {
20
+ replace?: boolean;
21
+ }): Promise<void>;
22
+ /** Start creating a new document of a type. */
23
+ createDocument(docType: string): Promise<void>;
24
+ /** Close the current document, back to its type's list. */
25
+ closeToType(docType: string): Promise<void>;
26
+ /** Back to the dashboard (no type, no doc). */
27
+ goHome(): Promise<void>;
28
+ }
29
+ /** Create an admin nav and publish it to descendants (call once in the shell). */
30
+ export declare function setAdminNav(basePath?: string): AdminNav;
31
+ /** Read the admin nav. `undefined` outside the admin shell (safe to guard). */
32
+ export declare function useAdminNav(): AdminNav | undefined;
33
+ export declare function createAdminNav(basePath?: string): AdminNav;
34
+ //# sourceMappingURL=nav.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nav.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/admin/nav.svelte.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,4EAA4E;AAC5E,MAAM,MAAM,UAAU,GACnB,MAAM,GACN,SAAS,GACT,OAAO,GACP,QAAQ,GACR,OAAO,GACP,SAAS,GACT,OAAO,GACP,OAAO,GACP,WAAW,GACX,aAAa,CAAC;AAEjB,sEAAsE;AACtE,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;AAEpE,MAAM,WAAW,QAAQ;IACxB,oEAAoE;IACpE,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExE,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,oDAAoD;IACpD,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3F,+CAA+C;IAC/C,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,2DAA2D;IAC3D,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,+CAA+C;IAC/C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID,kFAAkF;AAClF,wBAAgB,WAAW,CAAC,QAAQ,SAAW,GAAG,QAAQ,CAIzD;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,IAAI,QAAQ,GAAG,SAAS,CAElD;AAED,wBAAgB,cAAc,CAAC,QAAQ,SAAW,GAAG,QAAQ,CAgE5D"}