@aphexcms/cms-core 2.0.9 → 2.0.11

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 (381) hide show
  1. package/LICENSE +21 -0
  2. package/dist/api/api-keys.d.ts +8 -7
  3. package/dist/api/api-keys.d.ts.map +1 -1
  4. package/dist/api/assets.d.ts +7 -22
  5. package/dist/api/assets.d.ts.map +1 -1
  6. package/dist/api/assets.js +1 -10
  7. package/dist/api/documents.d.ts +17 -16
  8. package/dist/api/documents.d.ts.map +1 -1
  9. package/dist/api/documents.js +2 -2
  10. package/dist/api/index.d.ts +1 -0
  11. package/dist/api/index.d.ts.map +1 -1
  12. package/dist/api/index.js +1 -0
  13. package/dist/api/organizations.d.ts +15 -35
  14. package/dist/api/organizations.d.ts.map +1 -1
  15. package/dist/api/roles.d.ts +22 -0
  16. package/dist/api/roles.d.ts.map +1 -0
  17. package/dist/api/roles.js +26 -0
  18. package/dist/api/schemas/api-keys.d.ts +62 -0
  19. package/dist/api/schemas/api-keys.d.ts.map +1 -0
  20. package/dist/api/schemas/api-keys.js +28 -0
  21. package/dist/api/schemas/assets.d.ts +174 -0
  22. package/dist/api/schemas/assets.d.ts.map +1 -0
  23. package/dist/api/schemas/assets.js +99 -0
  24. package/dist/api/schemas/documents.d.ts +325 -0
  25. package/dist/api/schemas/documents.d.ts.map +1 -0
  26. package/dist/api/schemas/documents.js +161 -0
  27. package/dist/api/schemas/organizations.d.ts +41 -0
  28. package/dist/api/schemas/organizations.d.ts.map +1 -0
  29. package/dist/api/schemas/organizations.js +56 -0
  30. package/dist/api/schemas/roles.d.ts +77 -0
  31. package/dist/api/schemas/roles.d.ts.map +1 -0
  32. package/dist/api/schemas/roles.js +42 -0
  33. package/dist/api/schemas/user.d.ts +10 -0
  34. package/dist/api/schemas/user.d.ts.map +1 -0
  35. package/dist/api/schemas/user.js +11 -0
  36. package/dist/api/user.d.ts +4 -6
  37. package/dist/api/user.d.ts.map +1 -1
  38. package/dist/app-augment.d.ts +32 -0
  39. package/dist/app-augment.d.ts.map +1 -0
  40. package/dist/app-augment.js +18 -0
  41. package/dist/auth/auth-hooks.d.ts +2 -1
  42. package/dist/auth/auth-hooks.d.ts.map +1 -1
  43. package/dist/auth/auth-hooks.js +22 -2
  44. package/dist/auth/provider.d.ts +5 -0
  45. package/dist/auth/provider.d.ts.map +1 -1
  46. package/dist/cli/index.js +0 -0
  47. package/dist/client/index.d.ts +4 -0
  48. package/dist/client/index.d.ts.map +1 -1
  49. package/dist/client/index.js +7 -0
  50. package/dist/components/AdminApp.svelte +306 -142
  51. package/dist/components/AdminApp.svelte.d.ts +8 -0
  52. package/dist/components/AdminApp.svelte.d.ts.map +1 -1
  53. package/dist/components/admin/DocumentEditor.svelte +653 -365
  54. package/dist/components/admin/DocumentEditor.svelte.d.ts +2 -0
  55. package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
  56. package/dist/components/admin/DocumentVersionPanel.svelte +57 -44
  57. package/dist/components/admin/DocumentVersionPanel.svelte.d.ts.map +1 -1
  58. package/dist/components/admin/MediaBrowser.svelte +70 -30
  59. package/dist/components/admin/MediaBrowser.svelte.d.ts.map +1 -1
  60. package/dist/components/admin/ObjectModal.svelte +70 -95
  61. package/dist/components/admin/ObjectModal.svelte.d.ts +1 -2
  62. package/dist/components/admin/ObjectModal.svelte.d.ts.map +1 -1
  63. package/dist/components/admin/PermissionsDebug.svelte +119 -0
  64. package/dist/components/admin/PermissionsDebug.svelte.d.ts +4 -0
  65. package/dist/components/admin/PermissionsDebug.svelte.d.ts.map +1 -0
  66. package/dist/components/admin/SchemaField.svelte +3 -1
  67. package/dist/components/admin/SchemaField.svelte.d.ts.map +1 -1
  68. package/dist/components/admin/confirm-dialog/ConfirmDialogHost.svelte +35 -0
  69. package/dist/components/admin/confirm-dialog/ConfirmDialogHost.svelte.d.ts +19 -0
  70. package/dist/components/admin/confirm-dialog/ConfirmDialogHost.svelte.d.ts.map +1 -0
  71. package/dist/components/admin/confirm-dialog/confirm-dialog.svelte.d.ts +16 -0
  72. package/dist/components/admin/confirm-dialog/confirm-dialog.svelte.d.ts.map +1 -0
  73. package/dist/components/admin/confirm-dialog/confirm-dialog.svelte.js +29 -0
  74. package/dist/components/admin/fields/ArrayField.svelte +104 -108
  75. package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
  76. package/dist/components/admin/fields/FileField.svelte +22 -17
  77. package/dist/components/admin/fields/FileField.svelte.d.ts.map +1 -1
  78. package/dist/components/admin/fields/ImageField.svelte +21 -15
  79. package/dist/components/admin/fields/ImageField.svelte.d.ts.map +1 -1
  80. package/dist/components/admin/fields/ReferenceField.svelte +142 -112
  81. package/dist/components/admin/fields/ReferenceField.svelte.d.ts.map +1 -1
  82. package/dist/components/admin/fields/TextareaField.svelte +4 -3
  83. package/dist/components/admin/fields/TextareaField.svelte.d.ts +2 -2
  84. package/dist/components/admin/fields/TextareaField.svelte.d.ts.map +1 -1
  85. package/dist/components/layout/Sidebar.svelte +21 -11
  86. package/dist/components/layout/Sidebar.svelte.d.ts.map +1 -1
  87. package/dist/components/layout/sidebar/NavMain.svelte +1 -0
  88. package/dist/db/interfaces/document.d.ts.map +1 -1
  89. package/dist/db/interfaces/index.d.ts +3 -1
  90. package/dist/db/interfaces/index.d.ts.map +1 -1
  91. package/dist/db/interfaces/organization.d.ts +1 -1
  92. package/dist/db/interfaces/organization.d.ts.map +1 -1
  93. package/dist/db/interfaces/role.d.ts +25 -0
  94. package/dist/db/interfaces/role.d.ts.map +1 -0
  95. package/dist/db/interfaces/role.js +1 -0
  96. package/dist/engine.d.ts.map +1 -1
  97. package/dist/engine.js +5 -0
  98. package/dist/field-access.d.ts +30 -0
  99. package/dist/field-access.d.ts.map +1 -0
  100. package/dist/field-access.js +79 -0
  101. package/dist/hooks.d.ts +2 -0
  102. package/dist/hooks.d.ts.map +1 -1
  103. package/dist/hooks.js +23 -13
  104. package/dist/lib/api/api-keys.d.ts +8 -7
  105. package/dist/lib/api/api-keys.d.ts.map +1 -1
  106. package/dist/lib/api/api-keys.js.map +1 -1
  107. package/dist/lib/api/assets.d.ts +7 -22
  108. package/dist/lib/api/assets.d.ts.map +1 -1
  109. package/dist/lib/api/assets.js +1 -10
  110. package/dist/lib/api/assets.js.map +1 -1
  111. package/dist/lib/api/documents.d.ts +17 -16
  112. package/dist/lib/api/documents.d.ts.map +1 -1
  113. package/dist/lib/api/documents.js +2 -2
  114. package/dist/lib/api/documents.js.map +1 -1
  115. package/dist/lib/api/index.d.ts +1 -0
  116. package/dist/lib/api/index.d.ts.map +1 -1
  117. package/dist/lib/api/index.js +1 -0
  118. package/dist/lib/api/index.js.map +1 -1
  119. package/dist/lib/api/organizations.d.ts +15 -35
  120. package/dist/lib/api/organizations.d.ts.map +1 -1
  121. package/dist/lib/api/organizations.js.map +1 -1
  122. package/dist/lib/api/roles.d.ts +22 -0
  123. package/dist/lib/api/roles.d.ts.map +1 -0
  124. package/dist/lib/api/roles.js +27 -0
  125. package/dist/lib/api/roles.js.map +1 -0
  126. package/dist/lib/api/schemas/api-keys.d.ts +62 -0
  127. package/dist/lib/api/schemas/api-keys.d.ts.map +1 -0
  128. package/dist/lib/api/schemas/api-keys.js +29 -0
  129. package/dist/lib/api/schemas/api-keys.js.map +1 -0
  130. package/dist/lib/api/schemas/assets.d.ts +174 -0
  131. package/dist/lib/api/schemas/assets.d.ts.map +1 -0
  132. package/dist/lib/api/schemas/assets.js +100 -0
  133. package/dist/lib/api/schemas/assets.js.map +1 -0
  134. package/dist/lib/api/schemas/documents.d.ts +325 -0
  135. package/dist/lib/api/schemas/documents.d.ts.map +1 -0
  136. package/dist/lib/api/schemas/documents.js +162 -0
  137. package/dist/lib/api/schemas/documents.js.map +1 -0
  138. package/dist/lib/api/schemas/organizations.d.ts +41 -0
  139. package/dist/lib/api/schemas/organizations.d.ts.map +1 -0
  140. package/dist/lib/api/schemas/organizations.js +57 -0
  141. package/dist/lib/api/schemas/organizations.js.map +1 -0
  142. package/dist/lib/api/schemas/roles.d.ts +77 -0
  143. package/dist/lib/api/schemas/roles.d.ts.map +1 -0
  144. package/dist/lib/api/schemas/roles.js +43 -0
  145. package/dist/lib/api/schemas/roles.js.map +1 -0
  146. package/dist/lib/api/schemas/user.d.ts +10 -0
  147. package/dist/lib/api/schemas/user.d.ts.map +1 -0
  148. package/dist/lib/api/schemas/user.js +12 -0
  149. package/dist/lib/api/schemas/user.js.map +1 -0
  150. package/dist/lib/api/user.d.ts +4 -6
  151. package/dist/lib/api/user.d.ts.map +1 -1
  152. package/dist/lib/api/user.js.map +1 -1
  153. package/dist/lib/app-augment.d.ts +32 -0
  154. package/dist/lib/app-augment.d.ts.map +1 -0
  155. package/dist/lib/app-augment.js +19 -0
  156. package/dist/lib/app-augment.js.map +1 -0
  157. package/dist/lib/auth/auth-hooks.d.ts +2 -1
  158. package/dist/lib/auth/auth-hooks.d.ts.map +1 -1
  159. package/dist/lib/auth/auth-hooks.js +22 -2
  160. package/dist/lib/auth/auth-hooks.js.map +1 -1
  161. package/dist/lib/auth/provider.d.ts +5 -0
  162. package/dist/lib/auth/provider.d.ts.map +1 -1
  163. package/dist/lib/client/index.d.ts +4 -0
  164. package/dist/lib/client/index.d.ts.map +1 -1
  165. package/dist/lib/client/index.js +7 -0
  166. package/dist/lib/client/index.js.map +1 -1
  167. package/dist/lib/components/admin/confirm-dialog/confirm-dialog.svelte.d.ts +16 -0
  168. package/dist/lib/components/admin/confirm-dialog/confirm-dialog.svelte.d.ts.map +1 -0
  169. package/dist/lib/components/admin/confirm-dialog/confirm-dialog.svelte.js +30 -0
  170. package/dist/lib/components/admin/confirm-dialog/confirm-dialog.svelte.js.map +1 -0
  171. package/dist/lib/db/interfaces/document.d.ts.map +1 -1
  172. package/dist/lib/db/interfaces/index.d.ts +3 -1
  173. package/dist/lib/db/interfaces/index.d.ts.map +1 -1
  174. package/dist/lib/db/interfaces/organization.d.ts +1 -1
  175. package/dist/lib/db/interfaces/organization.d.ts.map +1 -1
  176. package/dist/lib/db/interfaces/role.d.ts +25 -0
  177. package/dist/lib/db/interfaces/role.d.ts.map +1 -0
  178. package/dist/lib/db/interfaces/role.js +2 -0
  179. package/dist/lib/db/interfaces/role.js.map +1 -0
  180. package/dist/lib/engine.d.ts.map +1 -1
  181. package/dist/lib/engine.js +5 -0
  182. package/dist/lib/engine.js.map +1 -1
  183. package/dist/lib/field-access.d.ts +30 -0
  184. package/dist/lib/field-access.d.ts.map +1 -0
  185. package/dist/lib/field-access.js +80 -0
  186. package/dist/lib/field-access.js.map +1 -0
  187. package/dist/lib/hooks.d.ts +2 -0
  188. package/dist/lib/hooks.d.ts.map +1 -1
  189. package/dist/lib/hooks.js +23 -13
  190. package/dist/lib/hooks.js.map +1 -1
  191. package/dist/lib/local-api/collection-api.d.ts +2 -0
  192. package/dist/lib/local-api/collection-api.d.ts.map +1 -1
  193. package/dist/lib/local-api/collection-api.js +98 -30
  194. package/dist/lib/local-api/collection-api.js.map +1 -1
  195. package/dist/lib/local-api/index.d.ts.map +1 -1
  196. package/dist/lib/local-api/index.js.map +1 -1
  197. package/dist/lib/local-api/permissions.d.ts +26 -26
  198. package/dist/lib/local-api/permissions.d.ts.map +1 -1
  199. package/dist/lib/local-api/permissions.js +122 -80
  200. package/dist/lib/local-api/permissions.js.map +1 -1
  201. package/dist/lib/permissions-context.svelte.d.ts +44 -0
  202. package/dist/lib/permissions-context.svelte.d.ts.map +1 -0
  203. package/dist/lib/permissions-context.svelte.js +80 -0
  204. package/dist/lib/permissions-context.svelte.js.map +1 -0
  205. package/dist/lib/routes/assets-bulk.d.ts.map +1 -1
  206. package/dist/lib/routes/assets-bulk.js +10 -3
  207. package/dist/lib/routes/assets-bulk.js.map +1 -1
  208. package/dist/lib/routes/assets-by-id.d.ts.map +1 -1
  209. package/dist/lib/routes/assets-by-id.js +11 -1
  210. package/dist/lib/routes/assets-by-id.js.map +1 -1
  211. package/dist/lib/routes/assets-references-counts.d.ts.map +1 -1
  212. package/dist/lib/routes/assets-references-counts.js +12 -2
  213. package/dist/lib/routes/assets-references-counts.js.map +1 -1
  214. package/dist/lib/routes/assets.d.ts.map +1 -1
  215. package/dist/lib/routes/assets.js +14 -13
  216. package/dist/lib/routes/assets.js.map +1 -1
  217. package/dist/lib/routes/document-versions.d.ts.map +1 -1
  218. package/dist/lib/routes/document-versions.js +16 -2
  219. package/dist/lib/routes/document-versions.js.map +1 -1
  220. package/dist/lib/routes/documents-by-id.d.ts.map +1 -1
  221. package/dist/lib/routes/documents-by-id.js +15 -3
  222. package/dist/lib/routes/documents-by-id.js.map +1 -1
  223. package/dist/lib/routes/documents-query.d.ts.map +1 -1
  224. package/dist/lib/routes/documents-query.js +13 -10
  225. package/dist/lib/routes/documents-query.js.map +1 -1
  226. package/dist/lib/routes/documents.d.ts.map +1 -1
  227. package/dist/lib/routes/documents.js +29 -26
  228. package/dist/lib/routes/documents.js.map +1 -1
  229. package/dist/lib/routes/organizations-by-id.d.ts.map +1 -1
  230. package/dist/lib/routes/organizations-by-id.js +17 -4
  231. package/dist/lib/routes/organizations-by-id.js.map +1 -1
  232. package/dist/lib/routes/organizations-invitations.d.ts.map +1 -1
  233. package/dist/lib/routes/organizations-invitations.js +48 -18
  234. package/dist/lib/routes/organizations-invitations.js.map +1 -1
  235. package/dist/lib/routes/organizations-members.d.ts.map +1 -1
  236. package/dist/lib/routes/organizations-members.js +24 -18
  237. package/dist/lib/routes/organizations-members.js.map +1 -1
  238. package/dist/lib/routes/organizations-switch.d.ts.map +1 -1
  239. package/dist/lib/routes/organizations-switch.js +7 -3
  240. package/dist/lib/routes/organizations-switch.js.map +1 -1
  241. package/dist/lib/routes/organizations.d.ts.map +1 -1
  242. package/dist/lib/routes/organizations.js +11 -5
  243. package/dist/lib/routes/organizations.js.map +1 -1
  244. package/dist/lib/routes/roles-by-name.d.ts +4 -0
  245. package/dist/lib/routes/roles-by-name.d.ts.map +1 -0
  246. package/dist/lib/routes/roles-by-name.js +112 -0
  247. package/dist/lib/routes/roles-by-name.js.map +1 -0
  248. package/dist/lib/routes/roles.d.ts +4 -0
  249. package/dist/lib/routes/roles.d.ts.map +1 -0
  250. package/dist/lib/routes/roles.js +91 -0
  251. package/dist/lib/routes/roles.js.map +1 -0
  252. package/dist/lib/routes/user-preferences.d.ts.map +1 -1
  253. package/dist/lib/routes/user-preferences.js +7 -13
  254. package/dist/lib/routes/user-preferences.js.map +1 -1
  255. package/dist/lib/routes-exports.d.ts +2 -0
  256. package/dist/lib/routes-exports.d.ts.map +1 -1
  257. package/dist/lib/routes-exports.js +3 -0
  258. package/dist/lib/routes-exports.js.map +1 -1
  259. package/dist/lib/save-state-context.svelte.d.ts +8 -0
  260. package/dist/lib/save-state-context.svelte.d.ts.map +1 -0
  261. package/dist/lib/save-state-context.svelte.js +9 -0
  262. package/dist/lib/save-state-context.svelte.js.map +1 -0
  263. package/dist/lib/schema-utils/validator.d.ts.map +1 -1
  264. package/dist/lib/schema-utils/validator.js +14 -0
  265. package/dist/lib/schema-utils/validator.js.map +1 -1
  266. package/dist/lib/server/index.d.ts +1 -0
  267. package/dist/lib/server/index.d.ts.map +1 -1
  268. package/dist/lib/server/index.js +1 -0
  269. package/dist/lib/server/index.js.map +1 -1
  270. package/dist/lib/services/index.d.ts +1 -0
  271. package/dist/lib/services/index.d.ts.map +1 -1
  272. package/dist/lib/services/index.js +1 -0
  273. package/dist/lib/services/index.js.map +1 -1
  274. package/dist/lib/services/roles-service.d.ts +35 -0
  275. package/dist/lib/services/roles-service.d.ts.map +1 -0
  276. package/dist/lib/services/roles-service.js +91 -0
  277. package/dist/lib/services/roles-service.js.map +1 -0
  278. package/dist/lib/services/version-service.d.ts.map +1 -1
  279. package/dist/lib/services/version-service.js.map +1 -1
  280. package/dist/lib/types/auth.d.ts +43 -9
  281. package/dist/lib/types/auth.d.ts.map +1 -1
  282. package/dist/lib/types/auth.js +31 -26
  283. package/dist/lib/types/auth.js.map +1 -1
  284. package/dist/lib/types/capabilities.d.ts +104 -0
  285. package/dist/lib/types/capabilities.d.ts.map +1 -0
  286. package/dist/lib/types/capabilities.js +217 -0
  287. package/dist/lib/types/capabilities.js.map +1 -0
  288. package/dist/lib/types/index.d.ts +1 -0
  289. package/dist/lib/types/index.d.ts.map +1 -1
  290. package/dist/lib/types/index.js +1 -0
  291. package/dist/lib/types/index.js.map +1 -1
  292. package/dist/lib/types/organization.d.ts +13 -4
  293. package/dist/lib/types/organization.d.ts.map +1 -1
  294. package/dist/lib/types/schemas.d.ts +71 -0
  295. package/dist/lib/types/schemas.d.ts.map +1 -1
  296. package/dist/lib/types/sidebar.d.ts +1 -1
  297. package/dist/lib/types/sidebar.d.ts.map +1 -1
  298. package/dist/lib/utils/mime-detect.d.ts.map +1 -1
  299. package/dist/lib/utils/mime-detect.js +28 -6
  300. package/dist/lib/utils/mime-detect.js.map +1 -1
  301. package/dist/local-api/collection-api.d.ts +2 -0
  302. package/dist/local-api/collection-api.d.ts.map +1 -1
  303. package/dist/local-api/collection-api.js +98 -30
  304. package/dist/local-api/index.d.ts.map +1 -1
  305. package/dist/local-api/permissions.d.ts +26 -26
  306. package/dist/local-api/permissions.d.ts.map +1 -1
  307. package/dist/local-api/permissions.js +122 -80
  308. package/dist/permissions-context.svelte.d.ts +44 -0
  309. package/dist/permissions-context.svelte.d.ts.map +1 -0
  310. package/dist/permissions-context.svelte.js +79 -0
  311. package/dist/plugins/README.md +20 -20
  312. package/dist/routes/assets-bulk.d.ts.map +1 -1
  313. package/dist/routes/assets-bulk.js +10 -3
  314. package/dist/routes/assets-by-id.d.ts.map +1 -1
  315. package/dist/routes/assets-by-id.js +11 -1
  316. package/dist/routes/assets-references-counts.d.ts.map +1 -1
  317. package/dist/routes/assets-references-counts.js +12 -2
  318. package/dist/routes/assets.d.ts.map +1 -1
  319. package/dist/routes/assets.js +14 -13
  320. package/dist/routes/document-versions.d.ts.map +1 -1
  321. package/dist/routes/document-versions.js +16 -2
  322. package/dist/routes/documents-by-id.d.ts.map +1 -1
  323. package/dist/routes/documents-by-id.js +15 -3
  324. package/dist/routes/documents-query.d.ts.map +1 -1
  325. package/dist/routes/documents-query.js +13 -10
  326. package/dist/routes/documents.d.ts.map +1 -1
  327. package/dist/routes/documents.js +29 -26
  328. package/dist/routes/organizations-by-id.d.ts.map +1 -1
  329. package/dist/routes/organizations-by-id.js +17 -4
  330. package/dist/routes/organizations-invitations.d.ts.map +1 -1
  331. package/dist/routes/organizations-invitations.js +48 -18
  332. package/dist/routes/organizations-members.d.ts.map +1 -1
  333. package/dist/routes/organizations-members.js +24 -18
  334. package/dist/routes/organizations-switch.d.ts.map +1 -1
  335. package/dist/routes/organizations-switch.js +7 -3
  336. package/dist/routes/organizations.d.ts.map +1 -1
  337. package/dist/routes/organizations.js +11 -5
  338. package/dist/routes/roles-by-name.d.ts +4 -0
  339. package/dist/routes/roles-by-name.d.ts.map +1 -0
  340. package/dist/routes/roles-by-name.js +111 -0
  341. package/dist/routes/roles.d.ts +4 -0
  342. package/dist/routes/roles.d.ts.map +1 -0
  343. package/dist/routes/roles.js +90 -0
  344. package/dist/routes/user-preferences.d.ts.map +1 -1
  345. package/dist/routes/user-preferences.js +7 -13
  346. package/dist/routes-exports.d.ts +2 -0
  347. package/dist/routes-exports.d.ts.map +1 -1
  348. package/dist/routes-exports.js +3 -0
  349. package/dist/save-state-context.svelte.d.ts +8 -0
  350. package/dist/save-state-context.svelte.d.ts.map +1 -0
  351. package/dist/save-state-context.svelte.js +8 -0
  352. package/dist/schema-utils/validator.d.ts.map +1 -1
  353. package/dist/schema-utils/validator.js +14 -0
  354. package/dist/server/index.d.ts +1 -0
  355. package/dist/server/index.d.ts.map +1 -1
  356. package/dist/server/index.js +1 -0
  357. package/dist/services/index.d.ts +1 -0
  358. package/dist/services/index.d.ts.map +1 -1
  359. package/dist/services/index.js +1 -0
  360. package/dist/services/roles-service.d.ts +35 -0
  361. package/dist/services/roles-service.d.ts.map +1 -0
  362. package/dist/services/roles-service.js +90 -0
  363. package/dist/services/version-service.d.ts.map +1 -1
  364. package/dist/types/auth.d.ts +43 -9
  365. package/dist/types/auth.d.ts.map +1 -1
  366. package/dist/types/auth.js +31 -26
  367. package/dist/types/capabilities.d.ts +104 -0
  368. package/dist/types/capabilities.d.ts.map +1 -0
  369. package/dist/types/capabilities.js +216 -0
  370. package/dist/types/index.d.ts +1 -0
  371. package/dist/types/index.d.ts.map +1 -1
  372. package/dist/types/index.js +1 -0
  373. package/dist/types/organization.d.ts +13 -4
  374. package/dist/types/organization.d.ts.map +1 -1
  375. package/dist/types/schemas.d.ts +71 -0
  376. package/dist/types/schemas.d.ts.map +1 -1
  377. package/dist/types/sidebar.d.ts +1 -1
  378. package/dist/types/sidebar.d.ts.map +1 -1
  379. package/dist/utils/mime-detect.d.ts.map +1 -1
  380. package/dist/utils/mime-detect.js +28 -6
  381. package/package.json +142 -138
@@ -1,6 +1,8 @@
1
1
  // Aphex CMS Organization Invitations API Handlers
2
2
  import { json } from '@sveltejs/kit';
3
3
  import { cmsLogger } from '../utils/logger.js';
4
+ import { inviteMemberRequest, cancelInvitationRequest } from '../api/schemas/organizations.js';
5
+ import { hasCapability } from '../types/capabilities.js';
4
6
  // POST /api/organizations/invitations - Create/send an invitation
5
7
  export const POST = async ({ request, locals }) => {
6
8
  try {
@@ -13,31 +15,57 @@ export const POST = async ({ request, locals }) => {
13
15
  message: 'Session authentication required'
14
16
  }, { status: 401 });
15
17
  }
16
- // Only owners and admins can invite members
17
- if (auth.organizationRole !== 'owner' && auth.organizationRole !== 'admin') {
18
+ if (!hasCapability(auth, 'member.invite')) {
18
19
  return json({
19
20
  success: false,
20
21
  error: 'Forbidden',
21
- message: 'Only owners and admins can invite members'
22
+ message: 'You do not have permission to invite members'
22
23
  }, { status: 403 });
23
24
  }
24
- const body = await request.json();
25
- if (!body.email || !body.role) {
25
+ const rawBody = await request.json();
26
+ const parsed = inviteMemberRequest.safeParse(rawBody);
27
+ if (!parsed.success) {
26
28
  return json({
27
29
  success: false,
28
- error: 'Missing required fields',
29
- message: 'email and role are required'
30
+ error: 'Invalid request body',
31
+ message: 'email and role are required',
32
+ issues: parsed.error.issues
30
33
  }, { status: 400 });
31
34
  }
32
- // Validate role
33
- const validRoles = ['admin', 'editor', 'viewer'];
34
- if (!validRoles.includes(body.role)) {
35
+ const body = parsed.data;
36
+ // Verify the role exists in this organization. Defends against
37
+ // clients sending a role name that was deleted between page load
38
+ // and submit, or against typos slipping past the format regex.
39
+ const roleRow = await databaseAdapter.findRoleByName(auth.organizationId, body.role);
40
+ if (!roleRow) {
35
41
  return json({
36
42
  success: false,
37
- error: 'Invalid role',
38
- message: 'Role must be one of: admin, editor, viewer'
43
+ error: 'Unknown role',
44
+ message: `No role named "${body.role}" in this organization`
39
45
  }, { status: 400 });
40
46
  }
47
+ // Reject self-invitation
48
+ if (body.email.toLowerCase() === auth.user.email.toLowerCase()) {
49
+ return json({
50
+ success: false,
51
+ error: 'Invalid invitation',
52
+ message: 'You cannot invite yourself'
53
+ }, { status: 400 });
54
+ }
55
+ // Reject if the invitee is already a member of the organization
56
+ if (locals.aphexCMS.auth) {
57
+ const existingUser = await locals.aphexCMS.auth.getUserByEmail(body.email);
58
+ if (existingUser) {
59
+ const existingMembership = await databaseAdapter.findUserMembership(existingUser.id, auth.organizationId);
60
+ if (existingMembership) {
61
+ return json({
62
+ success: false,
63
+ error: 'Already a member',
64
+ message: 'This user is already a member of the organization'
65
+ }, { status: 400 });
66
+ }
67
+ }
68
+ }
41
69
  // Check if there's already a pending invitation for this email
42
70
  const existingInvitations = await databaseAdapter.findOrganizationInvitations(auth.organizationId);
43
71
  const pendingInvitation = existingInvitations.find((inv) => inv.email.toLowerCase() === body.email.toLowerCase() && inv.acceptedAt === null);
@@ -86,22 +114,24 @@ export const DELETE = async ({ request, locals }) => {
86
114
  message: 'Session authentication required'
87
115
  }, { status: 401 });
88
116
  }
89
- // Only owners and admins can cancel invitations
90
- if (auth.organizationRole !== 'owner' && auth.organizationRole !== 'admin') {
117
+ if (!hasCapability(auth, 'member.invite')) {
91
118
  return json({
92
119
  success: false,
93
120
  error: 'Forbidden',
94
- message: 'Only owners and admins can cancel invitations'
121
+ message: 'You do not have permission to cancel invitations'
95
122
  }, { status: 403 });
96
123
  }
97
- const body = await request.json();
98
- if (!body.invitationId) {
124
+ const rawBody = await request.json();
125
+ const parsed = cancelInvitationRequest.safeParse(rawBody);
126
+ if (!parsed.success) {
99
127
  return json({
100
128
  success: false,
101
129
  error: 'Missing required field',
102
- message: 'invitationId is required'
130
+ message: 'invitationId is required',
131
+ issues: parsed.error.issues
103
132
  }, { status: 400 });
104
133
  }
134
+ const body = parsed.data;
105
135
  // Delete the invitation
106
136
  const deleted = await databaseAdapter.deleteInvitation(body.invitationId);
107
137
  if (!deleted) {
@@ -1 +1 @@
1
- {"version":3,"file":"organizations-members.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-members.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,eAAO,MAAM,GAAG,EAAE,cAkCjB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cAmIpB,CAAC;AAGF,eAAO,MAAM,KAAK,EAAE,cA4HnB,CAAC"}
1
+ {"version":3,"file":"organizations-members.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-members.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAMpD,eAAO,MAAM,GAAG,EAAE,cAkCjB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cAoIpB,CAAC;AAGF,eAAO,MAAM,KAAK,EAAE,cA6HnB,CAAC"}
@@ -1,6 +1,8 @@
1
1
  // Aphex CMS Organization Members API Handlers
2
2
  import { json } from '@sveltejs/kit';
3
3
  import { cmsLogger } from '../utils/logger.js';
4
+ import { removeMemberRequest, updateMemberRoleRequest } from '../api/schemas/organizations.js';
5
+ import { hasCapability } from '../types/capabilities.js';
4
6
  // GET /api/organizations/members - List organization members
5
7
  export const GET = async ({ locals }) => {
6
8
  try {
@@ -41,22 +43,24 @@ export const DELETE = async ({ request, locals }) => {
41
43
  message: 'Session authentication required'
42
44
  }, { status: 401 });
43
45
  }
44
- // Only owners and admins can remove members
45
- if (auth.organizationRole !== 'owner' && auth.organizationRole !== 'admin') {
46
+ if (!hasCapability(auth, 'member.remove')) {
46
47
  return json({
47
48
  success: false,
48
49
  error: 'Forbidden',
49
- message: 'Only owners and admins can remove members'
50
+ message: 'You do not have permission to remove members'
50
51
  }, { status: 403 });
51
52
  }
52
- const body = await request.json();
53
- if (!body.userId) {
53
+ const rawBody = await request.json();
54
+ const parsed = removeMemberRequest.safeParse(rawBody);
55
+ if (!parsed.success) {
54
56
  return json({
55
57
  success: false,
56
58
  error: 'Missing required field',
57
- message: 'userId is required'
59
+ message: 'userId is required',
60
+ issues: parsed.error.issues
58
61
  }, { status: 400 });
59
62
  }
63
+ const body = parsed.data;
60
64
  // Prevent removing yourself
61
65
  if (body.userId === auth.user.id) {
62
66
  return json({
@@ -133,29 +137,31 @@ export const PATCH = async ({ request, locals }) => {
133
137
  message: 'Session authentication required'
134
138
  }, { status: 401 });
135
139
  }
136
- // Only owners and admins can update roles
137
- if (auth.organizationRole !== 'owner' && auth.organizationRole !== 'admin') {
140
+ if (!hasCapability(auth, 'member.changeRole')) {
138
141
  return json({
139
142
  success: false,
140
143
  error: 'Forbidden',
141
- message: 'Only owners and admins can update member roles'
144
+ message: 'You do not have permission to change member roles'
142
145
  }, { status: 403 });
143
146
  }
144
- const body = await request.json();
145
- if (!body.userId || !body.role) {
147
+ const rawBody = await request.json();
148
+ const parsed = updateMemberRoleRequest.safeParse(rawBody);
149
+ if (!parsed.success) {
146
150
  return json({
147
151
  success: false,
148
- error: 'Missing required fields',
149
- message: 'userId and role are required'
152
+ error: 'Invalid request body',
153
+ message: 'userId and role are required',
154
+ issues: parsed.error.issues
150
155
  }, { status: 400 });
151
156
  }
152
- // Validate role
153
- const validRoles = ['owner', 'admin', 'editor', 'viewer'];
154
- if (!validRoles.includes(body.role)) {
157
+ const body = parsed.data;
158
+ // Verify the target role exists in this organization.
159
+ const roleRow = await databaseAdapter.findRoleByName(auth.organizationId, body.role);
160
+ if (!roleRow) {
155
161
  return json({
156
162
  success: false,
157
- error: 'Invalid role',
158
- message: 'Role must be one of: owner, admin, editor, viewer'
163
+ error: 'Unknown role',
164
+ message: `No role named "${body.role}" in this organization`
159
165
  }, { status: 400 });
160
166
  }
161
167
  // Prevent changing your own role
@@ -1 +1 @@
1
- {"version":3,"file":"organizations-switch.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-switch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,eAAO,MAAM,IAAI,EAAE,cAoElB,CAAC"}
1
+ {"version":3,"file":"organizations-switch.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-switch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,IAAI,EAAE,cAsElB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  // Aphex CMS Organization Switch API Handler
2
2
  import { json } from '@sveltejs/kit';
3
3
  import { cmsLogger } from '../utils/logger.js';
4
+ import { switchOrganizationRequest } from '../api/schemas/organizations.js';
4
5
  // POST /api/organizations/switch - Switch active organization
5
6
  export const POST = async ({ request, locals }) => {
6
7
  try {
@@ -13,14 +14,17 @@ export const POST = async ({ request, locals }) => {
13
14
  message: 'Session authentication required'
14
15
  }, { status: 401 });
15
16
  }
16
- const body = await request.json();
17
- if (!body.organizationId) {
17
+ const rawBody = await request.json();
18
+ const parsed = switchOrganizationRequest.safeParse(rawBody);
19
+ if (!parsed.success) {
18
20
  return json({
19
21
  success: false,
20
22
  error: 'Missing required field',
21
- message: 'organizationId is required'
23
+ message: 'organizationId is required',
24
+ issues: parsed.error.issues
22
25
  }, { status: 400 });
23
26
  }
27
+ const body = parsed.data;
24
28
  // Verify user is a member of the target organization
25
29
  const membership = await databaseAdapter.findUserMembership(auth.user.id, body.organizationId);
26
30
  if (!membership) {
@@ -1 +1 @@
1
- {"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,eAAO,MAAM,GAAG,EAAE,cA6CjB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,cA6FlB,CAAC"}
1
+ {"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,GAAG,EAAE,cA6CjB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,cAkGlB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  // Aphex CMS Organization API Handlers
2
2
  import { json } from '@sveltejs/kit';
3
3
  import { cmsLogger } from '../utils/logger.js';
4
+ import { createOrganizationRequest } from '../api/schemas/organizations.js';
4
5
  // GET /api/organizations - List user's organizations
5
6
  export const GET = async ({ locals }) => {
6
7
  try {
@@ -59,15 +60,17 @@ export const POST = async ({ request, locals }) => {
59
60
  message: 'Only super admins can create organizations'
60
61
  }, { status: 403 });
61
62
  }
62
- const body = await request.json();
63
- // Validate required fields
64
- if (!body.name || !body.slug) {
63
+ const rawBody = await request.json();
64
+ const parsed = createOrganizationRequest.safeParse(rawBody);
65
+ if (!parsed.success) {
65
66
  return json({
66
67
  success: false,
67
- error: 'Missing required fields',
68
- message: 'Organization name and slug are required'
68
+ error: 'Invalid request body',
69
+ message: 'Organization name and slug are required',
70
+ issues: parsed.error.issues
69
71
  }, { status: 400 });
70
72
  }
73
+ const body = parsed.data;
71
74
  // Check if slug is already taken
72
75
  const existingOrg = await databaseAdapter.findOrganizationBySlug(body.slug);
73
76
  if (existingOrg) {
@@ -86,6 +89,9 @@ export const POST = async ({ request, locals }) => {
86
89
  parentOrganizationId: auth.organizationId, // Current active org becomes parent
87
90
  createdBy: auth.user.id
88
91
  });
92
+ // Seed the four built-in roles for this org before assigning membership.
93
+ // The member row references the role by name, so the rows must exist.
94
+ await databaseAdapter.seedBuiltinRoles(newOrganization.id);
89
95
  // Add the creator as owner
90
96
  await databaseAdapter.addMember({
91
97
  organizationId: newOrganization.id,
@@ -0,0 +1,4 @@
1
+ import type { RequestHandler } from '@sveltejs/kit';
2
+ export declare const PATCH: RequestHandler;
3
+ export declare const DELETE: RequestHandler;
4
+ //# sourceMappingURL=roles-by-name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles-by-name.d.ts","sourceRoot":"","sources":["../../src/lib/routes/roles-by-name.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAgBpD,eAAO,MAAM,KAAK,EAAE,cA4DnB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,cAoEpB,CAAC"}
@@ -0,0 +1,111 @@
1
+ // Aphex CMS Roles API Handlers (by-name)
2
+ //
3
+ // PATCH /api/roles/[name] — edit description / capabilities
4
+ // DELETE /api/roles/[name] — delete a custom role (built-ins cannot be deleted)
5
+ import { json } from '@sveltejs/kit';
6
+ import { cmsLogger } from '../utils/logger.js';
7
+ import { hasCapability, BUILTIN_ROLE_NAMES } from '../types/capabilities.js';
8
+ import { updateRoleRequest } from '../api/schemas/roles.js';
9
+ function unauthorized() {
10
+ return json({ success: false, error: 'Unauthorized', message: 'Session authentication required' }, { status: 401 });
11
+ }
12
+ function forbidden(message) {
13
+ return json({ success: false, error: 'Forbidden', message }, { status: 403 });
14
+ }
15
+ export const PATCH = async ({ params, request, locals }) => {
16
+ try {
17
+ const { databaseAdapter, rolesService } = locals.aphexCMS;
18
+ const auth = locals.auth;
19
+ if (!auth || auth.type !== 'session')
20
+ return unauthorized();
21
+ if (!hasCapability(auth, 'role.manage')) {
22
+ return forbidden('You do not have permission to manage roles');
23
+ }
24
+ const name = params.name;
25
+ if (!name) {
26
+ return json({ success: false, error: 'Invalid request', message: 'Role name is required' }, { status: 400 });
27
+ }
28
+ const rawBody = await request.json();
29
+ const parsed = updateRoleRequest.safeParse(rawBody);
30
+ if (!parsed.success) {
31
+ return json({
32
+ success: false,
33
+ error: 'Invalid request body',
34
+ issues: parsed.error.issues
35
+ }, { status: 400 });
36
+ }
37
+ const body = parsed.data;
38
+ const updated = await databaseAdapter.updateRole(auth.organizationId, name, body);
39
+ if (!updated) {
40
+ return json({
41
+ success: false,
42
+ error: 'Not found',
43
+ message: `No role named "${name}" in this organization`
44
+ }, { status: 404 });
45
+ }
46
+ // Bust the capability cache so open sessions pick up the change on
47
+ // their next request instead of waiting for TTL.
48
+ await rolesService.invalidate(auth.organizationId, name);
49
+ return json({ success: true, data: updated });
50
+ }
51
+ catch (error) {
52
+ cmsLogger.error('Failed to update role:', error);
53
+ return json({
54
+ success: false,
55
+ error: 'Failed to update role',
56
+ message: error instanceof Error ? error.message : 'Unknown error'
57
+ }, { status: 500 });
58
+ }
59
+ };
60
+ export const DELETE = async ({ params, locals }) => {
61
+ try {
62
+ const { databaseAdapter, rolesService } = locals.aphexCMS;
63
+ const auth = locals.auth;
64
+ if (!auth || auth.type !== 'session')
65
+ return unauthorized();
66
+ if (!hasCapability(auth, 'role.manage')) {
67
+ return forbidden('You do not have permission to manage roles');
68
+ }
69
+ const name = params.name;
70
+ if (!name) {
71
+ return json({ success: false, error: 'Invalid request', message: 'Role name is required' }, { status: 400 });
72
+ }
73
+ // Built-ins are part of the org's guaranteed floor — deleting one
74
+ // would let a seed run re-create it with stale capabilities. Force the
75
+ // user to edit instead.
76
+ if (BUILTIN_ROLE_NAMES.includes(name)) {
77
+ return forbidden(`"${name}" is a built-in role and cannot be deleted.`);
78
+ }
79
+ // Block deletion while the role is assigned to any member or invitation.
80
+ // Avoids silently orphaning memberships to an unknown role name.
81
+ const members = await databaseAdapter.findOrganizationMembers(auth.organizationId);
82
+ const inUseByMember = members.some((m) => m.role === name);
83
+ const invitations = await databaseAdapter.findOrganizationInvitations(auth.organizationId);
84
+ const inUseByInvitation = invitations.some((i) => i.role === name && !i.acceptedAt);
85
+ if (inUseByMember || inUseByInvitation) {
86
+ return json({
87
+ success: false,
88
+ error: 'Role in use',
89
+ message: `Cannot delete "${name}": reassign affected members or invitations first.`
90
+ }, { status: 409 });
91
+ }
92
+ const deleted = await databaseAdapter.deleteRole(auth.organizationId, name);
93
+ if (!deleted) {
94
+ return json({
95
+ success: false,
96
+ error: 'Not found',
97
+ message: `No role named "${name}" in this organization`
98
+ }, { status: 404 });
99
+ }
100
+ await rolesService.invalidate(auth.organizationId, name);
101
+ return json({ success: true, message: 'Role deleted' });
102
+ }
103
+ catch (error) {
104
+ cmsLogger.error('Failed to delete role:', error);
105
+ return json({
106
+ success: false,
107
+ error: 'Failed to delete role',
108
+ message: error instanceof Error ? error.message : 'Unknown error'
109
+ }, { status: 500 });
110
+ }
111
+ };
@@ -0,0 +1,4 @@
1
+ import type { RequestHandler } from '@sveltejs/kit';
2
+ export declare const GET: RequestHandler;
3
+ export declare const POST: RequestHandler;
4
+ //# sourceMappingURL=roles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../src/lib/routes/roles.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAgBpD,eAAO,MAAM,GAAG,EAAE,cAoBjB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,cA0ElB,CAAC"}
@@ -0,0 +1,90 @@
1
+ // Aphex CMS Roles API Handlers
2
+ //
3
+ // GET /api/roles — list roles for the active org
4
+ // POST /api/roles — create a custom role (requires role.manage)
5
+ import { json } from '@sveltejs/kit';
6
+ import { cmsLogger } from '../utils/logger.js';
7
+ import { hasCapability, BUILTIN_ROLE_NAMES } from '../types/capabilities.js';
8
+ import { createRoleRequest } from '../api/schemas/roles.js';
9
+ function unauthorized() {
10
+ return json({ success: false, error: 'Unauthorized', message: 'Session authentication required' }, { status: 401 });
11
+ }
12
+ function forbidden(message) {
13
+ return json({ success: false, error: 'Forbidden', message }, { status: 403 });
14
+ }
15
+ export const GET = async ({ locals }) => {
16
+ try {
17
+ const { rolesService } = locals.aphexCMS;
18
+ const auth = locals.auth;
19
+ if (!auth || auth.type !== 'session')
20
+ return unauthorized();
21
+ const roles = await rolesService.listRoles(auth.organizationId);
22
+ return json({ success: true, data: roles });
23
+ }
24
+ catch (error) {
25
+ cmsLogger.error('Failed to list roles:', error);
26
+ return json({
27
+ success: false,
28
+ error: 'Failed to list roles',
29
+ message: error instanceof Error ? error.message : 'Unknown error'
30
+ }, { status: 500 });
31
+ }
32
+ };
33
+ export const POST = async ({ request, locals }) => {
34
+ try {
35
+ const { databaseAdapter, rolesService } = locals.aphexCMS;
36
+ const auth = locals.auth;
37
+ if (!auth || auth.type !== 'session')
38
+ return unauthorized();
39
+ if (!hasCapability(auth, 'role.manage')) {
40
+ return forbidden('You do not have permission to manage roles');
41
+ }
42
+ const rawBody = await request.json();
43
+ const parsed = createRoleRequest.safeParse(rawBody);
44
+ if (!parsed.success) {
45
+ return json({
46
+ success: false,
47
+ error: 'Invalid request body',
48
+ message: 'name and capabilities are required',
49
+ issues: parsed.error.issues
50
+ }, { status: 400 });
51
+ }
52
+ const body = parsed.data;
53
+ // Reject collisions with reserved built-in names — built-ins are seeded
54
+ // on every org; a matching custom row would never be reachable.
55
+ if (BUILTIN_ROLE_NAMES.includes(body.name)) {
56
+ return json({
57
+ success: false,
58
+ error: 'Reserved name',
59
+ message: `"${body.name}" is a built-in role name. Edit the existing role instead.`
60
+ }, { status: 409 });
61
+ }
62
+ const existing = await databaseAdapter.findRoleByName(auth.organizationId, body.name);
63
+ if (existing) {
64
+ return json({
65
+ success: false,
66
+ error: 'Conflict',
67
+ message: `A role named "${body.name}" already exists in this organization.`
68
+ }, { status: 409 });
69
+ }
70
+ const role = await databaseAdapter.createRole({
71
+ organizationId: auth.organizationId,
72
+ name: body.name,
73
+ description: body.description ?? null,
74
+ capabilities: body.capabilities,
75
+ isBuiltIn: false
76
+ });
77
+ // New role can't be in use yet, but invalidate the prefix just in case
78
+ // a prior lookup populated the cache with an empty fallback entry.
79
+ await rolesService.invalidate(auth.organizationId, body.name);
80
+ return json({ success: true, data: role }, { status: 201 });
81
+ }
82
+ catch (error) {
83
+ cmsLogger.error('Failed to create role:', error);
84
+ return json({
85
+ success: false,
86
+ error: 'Failed to create role',
87
+ message: error instanceof Error ? error.message : 'Unknown error'
88
+ }, { status: 500 });
89
+ }
90
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"user-preferences.d.ts","sourceRoot":"","sources":["../../src/lib/routes/user-preferences.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,GAAG,EAAE,cAiCjB,CAAC;AAGF,eAAO,MAAM,KAAK,EAAE,cAkEnB,CAAC"}
1
+ {"version":3,"file":"user-preferences.d.ts","sourceRoot":"","sources":["../../src/lib/routes/user-preferences.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,GAAG,EAAE,cAiCjB,CAAC;AAGF,eAAO,MAAM,KAAK,EAAE,cAoDnB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  // Aphex CMS User Preferences API Handler
2
2
  import { json } from '@sveltejs/kit';
3
3
  import { cmsLogger } from '../utils/logger.js';
4
+ import { updateUserPreferencesRequest } from '../api/schemas/user.js';
4
5
  // GET /api/user/preferences - Get user preferences
5
6
  export const GET = async ({ locals }) => {
6
7
  try {
@@ -40,24 +41,17 @@ export const PATCH = async ({ request, locals }) => {
40
41
  message: 'Session authentication required'
41
42
  }, { status: 401 });
42
43
  }
43
- const body = (await request.json());
44
- // Validate the preferences object
45
- if (typeof body !== 'object' || body === null) {
44
+ const rawBody = await request.json();
45
+ const parsed = updateUserPreferencesRequest.safeParse(rawBody);
46
+ if (!parsed.success) {
46
47
  return json({
47
48
  success: false,
48
49
  error: 'Invalid request body',
49
- message: 'Expected an object with preference values'
50
- }, { status: 400 });
51
- }
52
- // Validate individual preference types
53
- if (body.includeChildOrganizations !== undefined &&
54
- typeof body.includeChildOrganizations !== 'boolean') {
55
- return json({
56
- success: false,
57
- error: 'Invalid preference value',
58
- message: 'includeChildOrganizations must be a boolean'
50
+ message: 'Invalid preference values',
51
+ issues: parsed.error.issues
59
52
  }, { status: 400 });
60
53
  }
54
+ const body = parsed.data;
61
55
  // Update preferences
62
56
  await databaseAdapter.updateUserPreferences(auth.user.id, body);
63
57
  // Get updated profile
@@ -15,4 +15,6 @@ export { GET as getOrganizationById, PATCH as updateOrganization, DELETE as dele
15
15
  export { POST as switchOrganization } from './routes/organizations-switch.js';
16
16
  export { GET as getOrganizationMembers, DELETE as removeMember, PATCH as updateMemberRole } from './routes/organizations-members.js';
17
17
  export { POST as inviteMember, DELETE as cancelInvitation } from './routes/organizations-invitations.js';
18
+ export { GET as getRoles, POST as createRole } from './routes/roles.js';
19
+ export { PATCH as updateRole, DELETE as deleteRole } from './routes/roles-by-name.js';
18
20
  //# sourceMappingURL=routes-exports.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"routes-exports.d.ts","sourceRoot":"","sources":["../src/lib/routes-exports.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,GAAG,IAAI,YAAY,EAAE,IAAI,IAAI,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EACN,GAAG,IAAI,eAAe,EACtB,GAAG,IAAI,cAAc,EACrB,MAAM,IAAI,cAAc,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAClG,OAAO,EACN,GAAG,IAAI,mBAAmB,EAC1B,UAAU,IAAI,kBAAkB,EAChC,cAAc,IAAI,sBAAsB,EACxC,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,GAAG,IAAI,SAAS,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACN,GAAG,IAAI,YAAY,EACnB,KAAK,IAAI,WAAW,EACpB,MAAM,IAAI,WAAW,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,GAAG,IAAI,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,IAAI,IAAI,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAGpF,OAAO,EAAE,GAAG,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,GAAG,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,GAAG,IAAI,gBAAgB,EAAE,IAAI,IAAI,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EACN,GAAG,IAAI,mBAAmB,EAC1B,KAAK,IAAI,kBAAkB,EAC3B,MAAM,IAAI,kBAAkB,EAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,IAAI,IAAI,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EACN,GAAG,IAAI,sBAAsB,EAC7B,MAAM,IAAI,YAAY,EACtB,KAAK,IAAI,gBAAgB,EACzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACN,IAAI,IAAI,YAAY,EACpB,MAAM,IAAI,gBAAgB,EAC1B,MAAM,oCAAoC,CAAC"}
1
+ {"version":3,"file":"routes-exports.d.ts","sourceRoot":"","sources":["../src/lib/routes-exports.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,GAAG,IAAI,YAAY,EAAE,IAAI,IAAI,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EACN,GAAG,IAAI,eAAe,EACtB,GAAG,IAAI,cAAc,EACrB,MAAM,IAAI,cAAc,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAClG,OAAO,EACN,GAAG,IAAI,mBAAmB,EAC1B,UAAU,IAAI,kBAAkB,EAChC,cAAc,IAAI,sBAAsB,EACxC,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,GAAG,IAAI,SAAS,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACN,GAAG,IAAI,YAAY,EACnB,KAAK,IAAI,WAAW,EACpB,MAAM,IAAI,WAAW,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,GAAG,IAAI,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,IAAI,IAAI,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAGpF,OAAO,EAAE,GAAG,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,GAAG,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,GAAG,IAAI,gBAAgB,EAAE,IAAI,IAAI,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EACN,GAAG,IAAI,mBAAmB,EAC1B,KAAK,IAAI,kBAAkB,EAC3B,MAAM,IAAI,kBAAkB,EAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,IAAI,IAAI,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EACN,GAAG,IAAI,sBAAsB,EAC7B,MAAM,IAAI,YAAY,EACtB,KAAK,IAAI,gBAAgB,EACzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACN,IAAI,IAAI,YAAY,EACpB,MAAM,IAAI,gBAAgB,EAC1B,MAAM,oCAAoC,CAAC;AAG5C,OAAO,EAAE,GAAG,IAAI,QAAQ,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,wBAAwB,CAAC"}
@@ -21,3 +21,6 @@ export { GET as getOrganizationById, PATCH as updateOrganization, DELETE as dele
21
21
  export { POST as switchOrganization } from './routes/organizations-switch.js';
22
22
  export { GET as getOrganizationMembers, DELETE as removeMember, PATCH as updateMemberRole } from './routes/organizations-members.js';
23
23
  export { POST as inviteMember, DELETE as cancelInvitation } from './routes/organizations-invitations.js';
24
+ // Role management routes
25
+ export { GET as getRoles, POST as createRole } from './routes/roles.js';
26
+ export { PATCH as updateRole, DELETE as deleteRole } from './routes/roles-by-name.js';
@@ -0,0 +1,8 @@
1
+ export interface SaveState {
2
+ readonly saving: boolean;
3
+ readonly hasUnsavedChanges: boolean;
4
+ readonly savedAgoText: string | null;
5
+ }
6
+ export declare function setSaveStateContext(state: SaveState): void;
7
+ export declare function getSaveStateContext(): SaveState | null;
8
+ //# sourceMappingURL=save-state-context.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-state-context.svelte.d.ts","sourceRoot":"","sources":["../src/lib/save-state-context.svelte.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,QAEnD;AAED,wBAAgB,mBAAmB,IAAI,SAAS,GAAG,IAAI,CAEtD"}
@@ -0,0 +1,8 @@
1
+ import { getContext, setContext } from 'svelte';
2
+ const SAVE_STATE_KEY = Symbol('aphex-save-state');
3
+ export function setSaveStateContext(state) {
4
+ setContext(SAVE_STATE_KEY, state);
5
+ }
6
+ export function getSaveStateContext() {
7
+ return getContext(SAVE_STATE_KEY) ?? null;
8
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;AAmB1D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAqMpE"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;AAmB1D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAqNpE"}
@@ -103,6 +103,20 @@ export function validateSchemaReferences(schemas) {
103
103
  validateField(field, schema.name);
104
104
  }
105
105
  }
106
+ // Validate field.group references against schema.groups
107
+ if (schema.fields) {
108
+ const groupNames = new Set((schema.groups ?? []).map((g) => g.name));
109
+ for (const field of schema.fields) {
110
+ if (!field.group)
111
+ continue;
112
+ const refs = Array.isArray(field.group) ? field.group : [field.group];
113
+ for (const ref of refs) {
114
+ if (!groupNames.has(ref)) {
115
+ errors.push(`Schema "${schema.name}" field "${field.name}" references unknown group "${ref}". Declare it in schema.groups.`);
116
+ }
117
+ }
118
+ }
119
+ }
106
120
  // Validate preview config references
107
121
  if (schema.preview?.select) {
108
122
  const fieldNames = new Set(schema.fields?.map((f) => f.name) || []);
@@ -12,6 +12,7 @@ export * from '../storage/interfaces/index.js';
12
12
  export * from '../storage/providers/storage.js';
13
13
  export * from '../services/index.js';
14
14
  export { AssetService } from '../services/asset-service.js';
15
+ export { RolesService } from '../services/roles-service.js';
15
16
  export * from '../routes-exports.js';
16
17
  export * from '../schema-utils/index.js';
17
18
  export { createHashForPublishing } from '../utils/content-hash.js';