@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
@@ -0,0 +1,79 @@
1
+ // Svelte context for capability-based UI gating.
2
+ //
3
+ // Set once at the root of the admin shell with a reactive capability source;
4
+ // descendants consume via `usePermissions()`. Mirrors the server-side
5
+ // `hasCapability()` API so the same mental model applies on both sides.
6
+ import { getContext, setContext } from 'svelte';
7
+ const KEY = Symbol.for('aphex.permissions');
8
+ /**
9
+ * Publish a capability context to descendants.
10
+ *
11
+ * `getCapabilities` is a getter rather than a static array so reactive
12
+ * sources (Svelte state, `$page.data.rbac.capabilities`) propagate: every
13
+ * `can()` call re-reads through the closure.
14
+ *
15
+ * @example
16
+ * ```svelte
17
+ * <script>
18
+ * import { page } from '$app/state';
19
+ * import { setPermissionsContext } from '@aphexcms/cms-core';
20
+ * setPermissionsContext(() => page.data.rbac?.capabilities ?? []);
21
+ * </script>
22
+ * ```
23
+ */
24
+ export function setPermissionsContext(getCapabilities, getRole = () => null) {
25
+ const ctx = {
26
+ get capabilities() {
27
+ return getCapabilities();
28
+ },
29
+ get role() {
30
+ return getRole();
31
+ },
32
+ can(cap) {
33
+ return getCapabilities().includes(cap);
34
+ },
35
+ canAny(...caps) {
36
+ const current = getCapabilities();
37
+ return caps.some((c) => current.includes(c));
38
+ },
39
+ canAll(...caps) {
40
+ const current = getCapabilities();
41
+ return caps.every((c) => current.includes(c));
42
+ }
43
+ };
44
+ setContext(KEY, ctx);
45
+ return ctx;
46
+ }
47
+ /**
48
+ * Read the capability context set by an ancestor.
49
+ *
50
+ * When no provider is present (e.g. a component rendered in isolation during
51
+ * tests or Storybook), returns a deny-all stub with a one-time dev warning
52
+ * rather than throwing — that way consumers degrade to "no affordances shown"
53
+ * instead of crashing the tree.
54
+ */
55
+ export function usePermissions() {
56
+ const ctx = getContext(KEY);
57
+ if (ctx)
58
+ return ctx;
59
+ warnOnce();
60
+ return DENY_ALL;
61
+ }
62
+ const DENY_ALL = Object.freeze({
63
+ capabilities: Object.freeze([]),
64
+ role: null,
65
+ can: () => false,
66
+ canAny: () => false,
67
+ canAll: () => false
68
+ });
69
+ let warned = false;
70
+ function warnOnce() {
71
+ if (warned)
72
+ return;
73
+ warned = true;
74
+ if (typeof window !== 'undefined') {
75
+ // eslint-disable-next-line no-console
76
+ console.warn('[aphex] usePermissions() called outside a PermissionsContext provider. ' +
77
+ 'All capability checks will return false. Call setPermissionsContext() in an ancestor.');
78
+ }
79
+ }
@@ -124,26 +124,26 @@ Under this system, a plugin becomes a clean, declarative manifest of its parts.
124
124
  import AnalyticsDashboard from './AnalyticsDashboard.svelte';
125
125
 
126
126
  export function createAnalyticsPlugin(config: AnalyticsConfig = {}): CMSPlugin {
127
- const endpoint = config.endpoint ?? '/api/analytics';
128
-
129
- return {
130
- name: 'my-analytics-plugin',
131
- parts: [
132
- // Part 1: The API endpoint
133
- {
134
- implements: 'aphex/server/route',
135
- path: endpoint,
136
- handler: (event) => handleAnalyticsRequest(event)
137
- },
138
- // Part 2: The UI tab in the admin interface
139
- {
140
- implements: 'aphex/admin/tool',
141
- id: 'analytics',
142
- title: 'Analytics',
143
- component: AnalyticsDashboard
144
- }
145
- ]
146
- };
127
+ const endpoint = config.endpoint ?? '/api/analytics';
128
+
129
+ return {
130
+ name: 'my-analytics-plugin',
131
+ parts: [
132
+ // Part 1: The API endpoint
133
+ {
134
+ implements: 'aphex/server/route',
135
+ path: endpoint,
136
+ handler: (event) => handleAnalyticsRequest(event)
137
+ },
138
+ // Part 2: The UI tab in the admin interface
139
+ {
140
+ implements: 'aphex/admin/tool',
141
+ id: 'analytics',
142
+ title: 'Analytics',
143
+ component: AnalyticsDashboard
144
+ }
145
+ ]
146
+ };
147
147
  }
148
148
  ```
149
149
 
@@ -1 +1 @@
1
- {"version":3,"file":"assets-bulk.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-bulk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,eAAO,MAAM,MAAM,EAAE,cAwDpB,CAAC"}
1
+ {"version":3,"file":"assets-bulk.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-bulk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,eAAO,MAAM,MAAM,EAAE,cAgEpB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { json } from '@sveltejs/kit';
2
2
  import { cmsLogger } from '../utils/logger.js';
3
+ import { bulkDeleteAssetsRequest } from '../api/schemas/assets.js';
3
4
  export const DELETE = async ({ request, locals }) => {
4
5
  try {
5
6
  const { assetService, databaseAdapter } = locals.aphexCMS;
@@ -7,10 +8,16 @@ export const DELETE = async ({ request, locals }) => {
7
8
  if (!auth || auth.type === 'partial_session') {
8
9
  return json({ success: false, error: 'Unauthorized' }, { status: 401 });
9
10
  }
10
- const { ids } = await request.json();
11
- if (!Array.isArray(ids) || ids.length === 0) {
12
- return json({ success: false, error: 'No asset IDs provided' }, { status: 400 });
11
+ const rawBody = await request.json();
12
+ const parsed = bulkDeleteAssetsRequest.safeParse(rawBody);
13
+ if (!parsed.success) {
14
+ return json({
15
+ success: false,
16
+ error: 'No asset IDs provided',
17
+ issues: parsed.error.issues
18
+ }, { status: 400 });
13
19
  }
20
+ const { ids } = parsed.data;
14
21
  // Check for references before deleting
15
22
  let referencedIds = [];
16
23
  if (databaseAdapter.countDocumentReferencesForAssets) {
@@ -1 +1 @@
1
- {"version":3,"file":"assets-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-by-id.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,eAAO,MAAM,GAAG,EAAE,cA6BjB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,cA0CpB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,cAiDnB,CAAC"}
1
+ {"version":3,"file":"assets-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-by-id.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,GAAG,EAAE,cA6BjB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,cA0CpB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,cA6DnB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { json } from '@sveltejs/kit';
2
2
  import { cmsLogger } from '../utils/logger.js';
3
+ import { updateAssetRequest } from '../api/schemas/assets.js';
3
4
  export const GET = async ({ params, locals }) => {
4
5
  try {
5
6
  const { assetService } = locals.aphexCMS;
@@ -69,7 +70,16 @@ export const PATCH = async ({ params, locals, request }) => {
69
70
  if (!id) {
70
71
  return json({ success: false, error: 'Asset ID is required' }, { status: 400 });
71
72
  }
72
- const { title, description, alt, creditLine } = await request.json();
73
+ const rawBody = await request.json();
74
+ const parsed = updateAssetRequest.safeParse(rawBody);
75
+ if (!parsed.success) {
76
+ return json({
77
+ success: false,
78
+ error: 'Invalid request body',
79
+ issues: parsed.error.issues
80
+ }, { status: 400 });
81
+ }
82
+ const { title, description, alt, creditLine } = parsed.data;
73
83
  let updatedAsset;
74
84
  if (auth.type == 'session') {
75
85
  updatedAsset = await assetService.updateAssetMetadata(auth.organizationId, id, {
@@ -1 +1 @@
1
- {"version":3,"file":"assets-references-counts.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-references-counts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD;;;GAGG;AACH,eAAO,MAAM,IAAI,EAAE,cA4BlB,CAAC"}
1
+ {"version":3,"file":"assets-references-counts.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-references-counts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD;;;GAGG;AACH,eAAO,MAAM,IAAI,EAAE,cAwClB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { json } from '@sveltejs/kit';
2
2
  import { cmsLogger } from '../utils/logger.js';
3
+ import { assetReferenceCountsRequest } from '../api/schemas/assets.js';
3
4
  /**
4
5
  * POST /api/assets/references/counts
5
6
  * Get reference counts for multiple asset IDs in batch
@@ -11,8 +12,17 @@ export const POST = async ({ request, locals }) => {
11
12
  if (!auth || auth.type === 'partial_session') {
12
13
  return json({ success: false, error: 'Unauthorized' }, { status: 401 });
13
14
  }
14
- const { ids } = await request.json();
15
- if (!Array.isArray(ids) || ids.length === 0) {
15
+ const rawBody = await request.json();
16
+ const parsed = assetReferenceCountsRequest.safeParse(rawBody);
17
+ if (!parsed.success) {
18
+ return json({
19
+ success: false,
20
+ error: 'Invalid request body',
21
+ issues: parsed.error.issues
22
+ }, { status: 400 });
23
+ }
24
+ const { ids } = parsed.data;
25
+ if (ids.length === 0) {
16
26
  return json({ success: true, data: {} });
17
27
  }
18
28
  if (!databaseAdapter.countDocumentReferencesForAssets) {
@@ -1 +1 @@
1
- {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,eAAO,MAAM,IAAI,EAAE,cAuFlB,CAAC;AAEF,eAAO,MAAM,GAAG,EAAE,cAiEjB,CAAC"}
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,IAAI,EAAE,cAuFlB,CAAC;AAEF,eAAO,MAAM,GAAG,EAAE,cAmEjB,CAAC"}
@@ -2,6 +2,7 @@
2
2
  import { json } from '@sveltejs/kit';
3
3
  import { cmsLogger } from '../utils/logger.js';
4
4
  import { validateFile } from '../utils/mime-detect.js';
5
+ import { listAssetsQuery } from '../api/schemas/assets.js';
5
6
  export const POST = async ({ request, locals }) => {
6
7
  try {
7
8
  const { assetService } = locals.aphexCMS;
@@ -82,20 +83,20 @@ export const GET = async ({ url, locals }) => {
82
83
  if (!auth || auth.type === 'partial_session') {
83
84
  return json({ success: false, error: 'Unauthorized' }, { status: 401 });
84
85
  }
85
- // Parse query parameters
86
- const assetType = url.searchParams.get('assetType');
87
- const mimeType = url.searchParams.get('mimeType') || undefined;
88
- const search = url.searchParams.get('search') || undefined;
89
- const limitParam = url.searchParams.get('limit');
90
- const offsetParam = url.searchParams.get('offset');
91
- const limit = limitParam ? parseInt(limitParam) : 20;
92
- const offset = offsetParam ? parseInt(offsetParam) : 0;
86
+ const parsedQuery = listAssetsQuery.safeParse(Object.fromEntries(url.searchParams.entries()));
87
+ if (!parsedQuery.success) {
88
+ return json({
89
+ success: false,
90
+ error: 'Invalid query parameters',
91
+ issues: parsedQuery.error.issues
92
+ }, { status: 400 });
93
+ }
93
94
  const filters = {
94
- assetType,
95
- mimeType,
96
- search,
97
- limit: isNaN(limit) ? 20 : limit,
98
- offset: isNaN(offset) ? 0 : offset
95
+ assetType: parsedQuery.data.assetType,
96
+ mimeType: parsedQuery.data.mimeType,
97
+ search: parsedQuery.data.search,
98
+ limit: parsedQuery.data.limit ?? 20,
99
+ offset: parsedQuery.data.offset ?? 0
99
100
  };
100
101
  // Fetch assets and total count in parallel
101
102
  const [fetchedAssets, totalAssets] = await Promise.all([
@@ -1 +1 @@
1
- {"version":3,"file":"document-versions.d.ts","sourceRoot":"","sources":["../../src/lib/routes/document-versions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,eAAO,MAAM,GAAG,EAAE,cAuDjB,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,cAuCxB,CAAC;AAGF,eAAO,MAAM,cAAc,EAAE,cA4C5B,CAAC"}
1
+ {"version":3,"file":"document-versions.d.ts","sourceRoot":"","sources":["../../src/lib/routes/document-versions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAMpD,eAAO,MAAM,GAAG,EAAE,cAqEjB,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,cAkCxB,CAAC;AAGF,eAAO,MAAM,cAAc,EAAE,cA0C5B,CAAC"}
@@ -2,6 +2,7 @@
2
2
  import { json } from '@sveltejs/kit';
3
3
  import { authToContext } from '../local-api/auth-helpers.js';
4
4
  import { cmsLogger } from '../utils/logger.js';
5
+ import { listVersionsQuery } from '../api/schemas/documents.js';
5
6
  // GET /api/documents/[id]/versions - List version history
6
7
  export const GET = async ({ params, url, locals }) => {
7
8
  try {
@@ -11,14 +12,27 @@ export const GET = async ({ params, url, locals }) => {
11
12
  if (!id) {
12
13
  return json({ success: false, error: 'Document ID is required' }, { status: 400 });
13
14
  }
14
- const limit = parseInt(url.searchParams.get('limit') || '25');
15
- const offset = parseInt(url.searchParams.get('offset') || '0');
15
+ const parsedQuery = listVersionsQuery.safeParse(Object.fromEntries(url.searchParams.entries()));
16
+ if (!parsedQuery.success) {
17
+ return json({
18
+ success: false,
19
+ error: 'Invalid query parameters',
20
+ issues: parsedQuery.error.issues
21
+ }, { status: 400 });
22
+ }
23
+ const limit = parsedQuery.data.limit ?? 25;
24
+ const offset = parsedQuery.data.offset ?? 0;
16
25
  const result = await localAPI.versionService.listVersions(databaseAdapter, context.organizationId, id, { limit, offset });
17
26
  // Resolve user names for createdBy IDs
18
27
  const userIds = [...new Set(result.versions.map((v) => v.createdBy).filter(Boolean))];
19
28
  const userMap = new Map();
20
29
  if (userIds.length > 0 && locals.aphexCMS.auth) {
21
30
  await Promise.all(userIds.map(async (userId) => {
31
+ // API key actions are stored as "apikey:<id>" — resolve to a friendly label
32
+ if (userId.startsWith('apikey:')) {
33
+ userMap.set(userId, 'API Key');
34
+ return;
35
+ }
22
36
  try {
23
37
  const user = await locals.aphexCMS.auth.getUserById(userId);
24
38
  if (user) {
@@ -1 +1 @@
1
- {"version":3,"file":"documents-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-by-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAOpD,eAAO,MAAM,GAAG,EAAE,cAuEjB,CAAC;AAIF,eAAO,MAAM,GAAG,EAAE,cAkFjB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cA+DpB,CAAC"}
1
+ {"version":3,"file":"documents-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-by-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAQpD,eAAO,MAAM,GAAG,EAAE,cAuEjB,CAAC;AAIF,eAAO,MAAM,GAAG,EAAE,cAiGjB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cA+DpB,CAAC"}
@@ -3,6 +3,7 @@ import { json } from '@sveltejs/kit';
3
3
  import { authToContext } from '../local-api/auth-helpers.js';
4
4
  import { PermissionError } from '../local-api/permissions.js';
5
5
  import { cmsLogger } from '../utils/logger.js';
6
+ import { updateDocumentRequest } from '../api/schemas/documents.js';
6
7
  // GET /api/documents/[id] - Get document by ID
7
8
  // TODO ENABLE CHILDREN ORG ACCESS BY DEFAULT - BECAUSE IF A PARENT ORG IS TRYING TO ACCESS A CHILD ORG. It should already have access to said id.
8
9
  export const GET = async ({ params, url, locals }) => {
@@ -67,12 +68,23 @@ export const PUT = async ({ params, request, locals }) => {
67
68
  const { localAPI } = locals.aphexCMS;
68
69
  const context = authToContext(locals.auth);
69
70
  const { id } = params;
70
- const body = await request.json();
71
71
  if (!id) {
72
72
  return json({ success: false, error: 'Document ID is required' }, { status: 400 });
73
73
  }
74
- const documentData = body.draftData || body.data;
75
- const shouldPublish = body.publish || false;
74
+ const rawBody = await request.json();
75
+ const parsed = updateDocumentRequest.safeParse(rawBody);
76
+ if (!parsed.success) {
77
+ return json({
78
+ success: false,
79
+ error: 'Invalid request body',
80
+ issues: parsed.error.issues
81
+ }, { status: 400 });
82
+ }
83
+ const documentData = parsed.data.draftData ?? parsed.data.data;
84
+ if (!documentData) {
85
+ return json({ success: false, error: 'Document data is required' }, { status: 400 });
86
+ }
87
+ const shouldPublish = parsed.data.publish ?? false;
76
88
  // Fetch document to get its type (hierarchy-aware, no RLS transaction)
77
89
  const found = await localAPI.findDocumentById(context, id);
78
90
  if (!found) {
@@ -1 +1 @@
1
- {"version":3,"file":"documents-query.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-query.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAUpD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,IAAI,EAAE,cAuFlB,CAAC"}
1
+ {"version":3,"file":"documents-query.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-query.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAWpD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,IAAI,EAAE,cAyFlB,CAAC"}
@@ -3,6 +3,7 @@ import { json } from '@sveltejs/kit';
3
3
  import { authToContext } from '../local-api/auth-helpers.js';
4
4
  import { PermissionError } from '../local-api/permissions.js';
5
5
  import { cmsLogger } from '../utils/logger.js';
6
+ import { queryDocumentsRequest } from '../api/schemas/documents.js';
6
7
  // Default values
7
8
  const DEFAULT_PAGE_SIZE = 20;
8
9
  const DEFAULT_PAGE = 1;
@@ -33,16 +34,18 @@ export const POST = async ({ request, locals }) => {
33
34
  try {
34
35
  const { localAPI } = locals.aphexCMS;
35
36
  const context = authToContext(locals.auth);
36
- const body = await request.json();
37
- // Extract document type
38
- const documentType = body.type;
39
- if (!documentType) {
37
+ const rawBody = await request.json();
38
+ const parsed = queryDocumentsRequest.safeParse(rawBody);
39
+ if (!parsed.success) {
40
40
  return json({
41
41
  success: false,
42
42
  error: 'Bad Request',
43
- message: 'Document type is required in request body'
43
+ message: 'Document type is required in request body',
44
+ issues: parsed.error.issues
44
45
  }, { status: 400 });
45
46
  }
47
+ const body = parsed.data;
48
+ const documentType = body.type;
46
49
  // Check if collection exists
47
50
  if (!localAPI.hasCollection(documentType)) {
48
51
  return json({
@@ -52,18 +55,18 @@ export const POST = async ({ request, locals }) => {
52
55
  }, { status: 400 });
53
56
  }
54
57
  // Parse pagination - support both page-based and offset-based
55
- const page = body.page ? Math.max(1, parseInt(body.page)) : DEFAULT_PAGE;
56
- const pageSize = body.pageSize || body.limit || DEFAULT_PAGE_SIZE;
58
+ const page = body.page ?? DEFAULT_PAGE;
59
+ const pageSize = body.pageSize ?? body.limit ?? DEFAULT_PAGE_SIZE;
57
60
  const offset = body.offset !== undefined ? body.offset : (page - 1) * pageSize;
58
61
  // Build FindOptions from request body
59
62
  const findOptions = {
60
63
  where: body.where,
61
64
  limit: pageSize,
62
- offset: offset,
65
+ offset,
63
66
  sort: body.sort,
64
- depth: body.depth !== undefined ? Math.max(0, Math.min(body.depth, 5)) : 0,
67
+ depth: body.depth ?? 0,
65
68
  select: body.select,
66
- perspective: body.perspective || 'draft',
69
+ perspective: body.perspective ?? 'draft',
67
70
  includeChildOrganizations: body.includeChildOrganizations,
68
71
  filterOrganizationIds: body.filterOrganizationIds
69
72
  };
@@ -1 +1 @@
1
- {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAUpD,eAAO,MAAM,GAAG,EAAE,cAwGjB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,cAmFlB,CAAC"}
1
+ {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAWpD,eAAO,MAAM,GAAG,EAAE,cA6GjB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,cAkFlB,CAAC"}
@@ -3,6 +3,7 @@ import { json } from '@sveltejs/kit';
3
3
  import { authToContext } from '../local-api/auth-helpers.js';
4
4
  import { PermissionError } from '../local-api/permissions.js';
5
5
  import { cmsLogger } from '../utils/logger.js';
6
+ import { createDocumentRequest, listDocumentsQuery } from '../api/schemas/documents.js';
6
7
  // Default values for API
7
8
  const DEFAULT_PAGE_SIZE = 20;
8
9
  const DEFAULT_PAGE = 1;
@@ -11,25 +12,27 @@ export const GET = async ({ url, locals }) => {
11
12
  try {
12
13
  const { localAPI } = locals.aphexCMS;
13
14
  const context = authToContext(locals.auth);
14
- // Parse query params
15
- const docType = url.searchParams.get('type') || url.searchParams.get('docType');
16
- const status = url.searchParams.get('status');
17
- const pageParam = url.searchParams.get('page');
18
- const pageSizeParam = url.searchParams.get('pageSize') || url.searchParams.get('limit');
19
- const depthParam = url.searchParams.get('depth');
20
- const sortParam = url.searchParams.get('sort');
21
- const perspective = url.searchParams.get('perspective') || 'draft';
22
- const includeChildOrganizations = url.searchParams.get('includeChildOrganizations') === 'true';
23
- const filterOrganizationIds = url.searchParams
24
- .get('filterOrganizationIds')
25
- ?.split(',')
26
- .filter(Boolean);
27
- // Parse pagination
28
- const page = pageParam ? Math.max(1, parseInt(pageParam)) : DEFAULT_PAGE;
29
- const pageSize = pageSizeParam ? parseInt(pageSizeParam) : DEFAULT_PAGE_SIZE;
15
+ // Parse + validate query params with zod
16
+ const rawQuery = Object.fromEntries(url.searchParams.entries());
17
+ const parsedQuery = listDocumentsQuery.safeParse(rawQuery);
18
+ if (!parsedQuery.success) {
19
+ return json({
20
+ success: false,
21
+ error: 'Invalid query parameters',
22
+ issues: parsedQuery.error.issues
23
+ }, { status: 400 });
24
+ }
25
+ const q = parsedQuery.data;
26
+ const docType = q.type ?? q.docType;
27
+ const status = q.status;
28
+ const sortParam = Array.isArray(q.sort) ? q.sort.join(',') : q.sort;
29
+ const perspective = q.perspective ?? 'draft';
30
+ const includeChildOrganizations = q.includeChildOrganizations;
31
+ const filterOrganizationIds = q.filterOrganizationIds;
32
+ const page = q.page ?? DEFAULT_PAGE;
33
+ const pageSize = q.pageSize ?? q.limit ?? DEFAULT_PAGE_SIZE;
30
34
  const offset = (page - 1) * pageSize;
31
- // Parse depth (clamp between 0-5)
32
- const depth = depthParam ? Math.max(0, Math.min(parseInt(depthParam), 5)) : 0;
35
+ const depth = q.depth ?? 0;
33
36
  if (!docType) {
34
37
  return json({
35
38
  success: false,
@@ -96,18 +99,18 @@ export const POST = async ({ request, locals }) => {
96
99
  try {
97
100
  const { localAPI } = locals.aphexCMS;
98
101
  const context = authToContext(locals.auth);
99
- const body = await request.json();
100
- // Validate required fields (support both old and new format)
101
- const documentType = body.type;
102
- const documentData = body.draftData || body.data;
103
- const shouldPublish = body.publish || false;
104
- if (!documentType || !documentData) {
102
+ const rawBody = await request.json();
103
+ const parsed = createDocumentRequest.safeParse(rawBody);
104
+ if (!parsed.success) {
105
105
  return json({
106
106
  success: false,
107
- error: 'Missing required fields',
108
- message: 'Document type and data are required'
107
+ error: 'Invalid request body',
108
+ issues: parsed.error.issues
109
109
  }, { status: 400 });
110
110
  }
111
+ const documentType = parsed.data.type;
112
+ const documentData = (parsed.data.draftData ?? parsed.data.data);
113
+ const shouldPublish = parsed.data.publish ?? false;
111
114
  // Get collection API (TypeScript-safe)
112
115
  const collection = localAPI.collections[documentType];
113
116
  if (!collection) {
@@ -1 +1 @@
1
- {"version":3,"file":"organizations-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-by-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,eAAO,MAAM,GAAG,EAAE,cAmEjB,CAAC;AAGF,eAAO,MAAM,KAAK,EAAE,cAgGnB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cAmFpB,CAAC"}
1
+ {"version":3,"file":"organizations-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-by-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAMpD,eAAO,MAAM,GAAG,EAAE,cAmEjB,CAAC;AAGF,eAAO,MAAM,KAAK,EAAE,cA8GnB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cAmFpB,CAAC"}
@@ -1,6 +1,8 @@
1
1
  // Aphex CMS Organization by ID API Handlers
2
2
  import { json } from '@sveltejs/kit';
3
3
  import { cmsLogger } from '../utils/logger.js';
4
+ import { updateOrganizationRequest } from '../api/schemas/organizations.js';
5
+ import { hasCapability } from '../types/capabilities.js';
4
6
  // GET /api/organizations/[id] - Get organization by ID
5
7
  export const GET = async ({ params, locals }) => {
6
8
  try {
@@ -71,16 +73,27 @@ export const PATCH = async ({ params, request, locals }) => {
71
73
  message: 'Organization ID is required'
72
74
  }, { status: 400 });
73
75
  }
74
- // Check if user is owner or admin of this organization
76
+ // Require `org.settings` capability + membership in the target org.
77
+ // Membership check stands regardless — even a capability holder can only
78
+ // edit orgs they actually belong to.
75
79
  const membership = await databaseAdapter.findUserMembership(auth.user.id, id);
76
- if (!membership || (membership.role !== 'owner' && membership.role !== 'admin')) {
80
+ if (!membership || !hasCapability(auth, 'org.settings')) {
77
81
  return json({
78
82
  success: false,
79
83
  error: 'Forbidden',
80
- message: 'Only owners and admins can update organization settings'
84
+ message: 'You do not have permission to update organization settings'
81
85
  }, { status: 403 });
82
86
  }
83
- const body = await request.json();
87
+ const rawBody = await request.json();
88
+ const parsed = updateOrganizationRequest.safeParse(rawBody);
89
+ if (!parsed.success) {
90
+ return json({
91
+ success: false,
92
+ error: 'Invalid request body',
93
+ issues: parsed.error.issues
94
+ }, { status: 400 });
95
+ }
96
+ const body = parsed.data;
84
97
  // Validate: if slug is being changed, check it's not already taken
85
98
  if (body.slug) {
86
99
  const existingOrg = await databaseAdapter.findOrganizationBySlug(body.slug);
@@ -1 +1 @@
1
- {"version":3,"file":"organizations-invitations.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-invitations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,eAAO,MAAM,IAAI,EAAE,cAyGlB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cAqEpB,CAAC"}
1
+ {"version":3,"file":"organizations-invitations.d.ts","sourceRoot":"","sources":["../../src/lib/routes/organizations-invitations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAMpD,eAAO,MAAM,IAAI,EAAE,cA6IlB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cAsEpB,CAAC"}