convex-cms 0.0.2 → 0.0.5-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/README.md +109 -13
  2. package/admin-dist/nitro.json +15 -0
  3. package/admin-dist/public/assets/CmsEmptyState-CiMQwSQV.js +5 -0
  4. package/admin-dist/public/assets/CmsPageHeader-ohOq0luT.js +1 -0
  5. package/admin-dist/public/assets/CmsStatusBadge-BdNf0V9v.js +1 -0
  6. package/admin-dist/public/assets/CmsSurface-CWup6Jh7.js +1 -0
  7. package/admin-dist/public/assets/CmsToolbar-cEBlCHa3.js +1 -0
  8. package/admin-dist/public/assets/ContentEntryEditor-BY5ypfUs.js +4 -0
  9. package/admin-dist/public/assets/ErrorState-C4nJ-ml4.js +1 -0
  10. package/admin-dist/public/assets/TaxonomyFilter-BgE_SR_O.js +1 -0
  11. package/admin-dist/public/assets/_contentTypeId-DtZectcC.js +1 -0
  12. package/admin-dist/public/assets/_entryId-BpSmrfAm.js +1 -0
  13. package/admin-dist/public/assets/alert-Bf2l8kxw.js +1 -0
  14. package/admin-dist/public/assets/badge-qPrc4AUM.js +1 -0
  15. package/admin-dist/public/assets/circle-check-big-Dgozy3vV.js +1 -0
  16. package/admin-dist/public/assets/command-QOmNhlb0.js +1 -0
  17. package/admin-dist/public/assets/content-OEBGlxg1.js +1 -0
  18. package/admin-dist/public/assets/content-types-CjQliqVV.js +2 -0
  19. package/admin-dist/public/assets/globals-hAmgC66w.css +1 -0
  20. package/admin-dist/public/assets/index-BH_ECMhv.js +1 -0
  21. package/admin-dist/public/assets/label-DCsUdvFh.js +1 -0
  22. package/admin-dist/public/assets/link-2-Czw1N61H.js +1 -0
  23. package/admin-dist/public/assets/list-DtCsXj8-.js +1 -0
  24. package/admin-dist/public/assets/main-CXgkZMhe.js +97 -0
  25. package/admin-dist/public/assets/media-DTJ3-ViE.js +1 -0
  26. package/admin-dist/public/assets/new._contentTypeId-CoTDxKzf.js +1 -0
  27. package/admin-dist/public/assets/plus-xCFJK0RC.js +1 -0
  28. package/admin-dist/public/assets/rotate-ccw-DIqK63wY.js +1 -0
  29. package/admin-dist/public/assets/scroll-area-B-yrE66a.js +1 -0
  30. package/admin-dist/public/assets/search-CbCbboeU.js +1 -0
  31. package/admin-dist/public/assets/select-Co3TZFJb.js +1 -0
  32. package/admin-dist/public/assets/settings-BspTTv_o.js +1 -0
  33. package/admin-dist/public/assets/switch-CfavASmR.js +1 -0
  34. package/admin-dist/public/assets/tabs-CN5s5u2W.js +1 -0
  35. package/admin-dist/public/assets/tanstack-adapter-npeE3RdY.js +1 -0
  36. package/admin-dist/public/assets/taxonomies-CgG46fIF.js +1 -0
  37. package/admin-dist/public/assets/textarea-BJ0XFZpT.js +1 -0
  38. package/admin-dist/public/assets/trash-B3daldm5.js +1 -0
  39. package/admin-dist/public/assets/triangle-alert-BZRcqsUg.js +1 -0
  40. package/admin-dist/public/assets/useBreadcrumbLabel-DwZlwvFF.js +1 -0
  41. package/admin-dist/public/assets/usePermissions-C1JQhfqb.js +1 -0
  42. package/admin-dist/public/favicon.ico +0 -0
  43. package/admin-dist/server/_chunks/_libs/@date-fns/tz.mjs +217 -0
  44. package/admin-dist/server/_chunks/_libs/@floating-ui/core.mjs +719 -0
  45. package/admin-dist/server/_chunks/_libs/@floating-ui/dom.mjs +622 -0
  46. package/admin-dist/server/_chunks/_libs/@floating-ui/react-dom.mjs +292 -0
  47. package/admin-dist/server/_chunks/_libs/@floating-ui/utils.mjs +320 -0
  48. package/admin-dist/server/_chunks/_libs/@radix-ui/number.mjs +6 -0
  49. package/admin-dist/server/_chunks/_libs/@radix-ui/primitive.mjs +11 -0
  50. package/admin-dist/server/_chunks/_libs/@radix-ui/react-arrow.mjs +23 -0
  51. package/admin-dist/server/_chunks/_libs/@radix-ui/react-avatar.mjs +119 -0
  52. package/admin-dist/server/_chunks/_libs/@radix-ui/react-checkbox.mjs +270 -0
  53. package/admin-dist/server/_chunks/_libs/@radix-ui/react-collection.mjs +69 -0
  54. package/admin-dist/server/_chunks/_libs/@radix-ui/react-compose-refs.mjs +39 -0
  55. package/admin-dist/server/_chunks/_libs/@radix-ui/react-context.mjs +137 -0
  56. package/admin-dist/server/_chunks/_libs/@radix-ui/react-dialog.mjs +325 -0
  57. package/admin-dist/server/_chunks/_libs/@radix-ui/react-direction.mjs +9 -0
  58. package/admin-dist/server/_chunks/_libs/@radix-ui/react-dismissable-layer.mjs +210 -0
  59. package/admin-dist/server/_chunks/_libs/@radix-ui/react-dropdown-menu.mjs +253 -0
  60. package/admin-dist/server/_chunks/_libs/@radix-ui/react-focus-guards.mjs +29 -0
  61. package/admin-dist/server/_chunks/_libs/@radix-ui/react-focus-scope.mjs +206 -0
  62. package/admin-dist/server/_chunks/_libs/@radix-ui/react-id.mjs +14 -0
  63. package/admin-dist/server/_chunks/_libs/@radix-ui/react-label.mjs +23 -0
  64. package/admin-dist/server/_chunks/_libs/@radix-ui/react-menu.mjs +812 -0
  65. package/admin-dist/server/_chunks/_libs/@radix-ui/react-popover.mjs +300 -0
  66. package/admin-dist/server/_chunks/_libs/@radix-ui/react-popper.mjs +286 -0
  67. package/admin-dist/server/_chunks/_libs/@radix-ui/react-portal.mjs +16 -0
  68. package/admin-dist/server/_chunks/_libs/@radix-ui/react-presence.mjs +128 -0
  69. package/admin-dist/server/_chunks/_libs/@radix-ui/react-primitive.mjs +141 -0
  70. package/admin-dist/server/_chunks/_libs/@radix-ui/react-roving-focus.mjs +224 -0
  71. package/admin-dist/server/_chunks/_libs/@radix-ui/react-scroll-area.mjs +721 -0
  72. package/admin-dist/server/_chunks/_libs/@radix-ui/react-select.mjs +1163 -0
  73. package/admin-dist/server/_chunks/_libs/@radix-ui/react-separator.mjs +28 -0
  74. package/admin-dist/server/_chunks/_libs/@radix-ui/react-slot.mjs +601 -0
  75. package/admin-dist/server/_chunks/_libs/@radix-ui/react-switch.mjs +152 -0
  76. package/admin-dist/server/_chunks/_libs/@radix-ui/react-tabs.mjs +189 -0
  77. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-callback-ref.mjs +11 -0
  78. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-controllable-state.mjs +69 -0
  79. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-effect-event.mjs +1 -0
  80. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-escape-keydown.mjs +17 -0
  81. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-is-hydrated.mjs +15 -0
  82. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-layout-effect.mjs +6 -0
  83. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-previous.mjs +14 -0
  84. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-size.mjs +39 -0
  85. package/admin-dist/server/_chunks/_libs/@radix-ui/react-visually-hidden.mjs +33 -0
  86. package/admin-dist/server/_chunks/_libs/@tanstack/history.mjs +409 -0
  87. package/admin-dist/server/_chunks/_libs/@tanstack/react-router.mjs +1718 -0
  88. package/admin-dist/server/_chunks/_libs/@tanstack/react-store.mjs +56 -0
  89. package/admin-dist/server/_chunks/_libs/@tanstack/router-core.mjs +4829 -0
  90. package/admin-dist/server/_chunks/_libs/@tanstack/store.mjs +134 -0
  91. package/admin-dist/server/_chunks/_libs/react-dom.mjs +10781 -0
  92. package/admin-dist/server/_chunks/_libs/react.mjs +513 -0
  93. package/admin-dist/server/_libs/aria-hidden.mjs +122 -0
  94. package/admin-dist/server/_libs/class-variance-authority.mjs +44 -0
  95. package/admin-dist/server/_libs/clsx.mjs +16 -0
  96. package/admin-dist/server/_libs/cmdk.mjs +315 -0
  97. package/admin-dist/server/_libs/convex.mjs +4841 -0
  98. package/admin-dist/server/_libs/cookie-es.mjs +58 -0
  99. package/admin-dist/server/_libs/croner.mjs +1 -0
  100. package/admin-dist/server/_libs/crossws.mjs +1 -0
  101. package/admin-dist/server/_libs/date-fns.mjs +1716 -0
  102. package/admin-dist/server/_libs/detect-node-es.mjs +1 -0
  103. package/admin-dist/server/_libs/get-nonce.mjs +9 -0
  104. package/admin-dist/server/_libs/h3-v2.mjs +277 -0
  105. package/admin-dist/server/_libs/h3.mjs +401 -0
  106. package/admin-dist/server/_libs/hookable.mjs +1 -0
  107. package/admin-dist/server/_libs/isbot.mjs +20 -0
  108. package/admin-dist/server/_libs/lucide-react.mjs +850 -0
  109. package/admin-dist/server/_libs/ohash.mjs +1 -0
  110. package/admin-dist/server/_libs/react-day-picker.mjs +2201 -0
  111. package/admin-dist/server/_libs/react-remove-scroll-bar.mjs +82 -0
  112. package/admin-dist/server/_libs/react-remove-scroll.mjs +328 -0
  113. package/admin-dist/server/_libs/react-style-singleton.mjs +69 -0
  114. package/admin-dist/server/_libs/rou3.mjs +8 -0
  115. package/admin-dist/server/_libs/seroval-plugins.mjs +58 -0
  116. package/admin-dist/server/_libs/seroval.mjs +1765 -0
  117. package/admin-dist/server/_libs/srvx.mjs +719 -0
  118. package/admin-dist/server/_libs/tailwind-merge.mjs +3010 -0
  119. package/admin-dist/server/_libs/tiny-invariant.mjs +12 -0
  120. package/admin-dist/server/_libs/tiny-warning.mjs +5 -0
  121. package/admin-dist/server/_libs/tslib.mjs +39 -0
  122. package/admin-dist/server/_libs/ufo.mjs +54 -0
  123. package/admin-dist/server/_libs/unctx.mjs +1 -0
  124. package/admin-dist/server/_libs/unstorage.mjs +1 -0
  125. package/admin-dist/server/_libs/use-callback-ref.mjs +66 -0
  126. package/admin-dist/server/_libs/use-sidecar.mjs +106 -0
  127. package/admin-dist/server/_libs/use-sync-external-store.mjs +139 -0
  128. package/admin-dist/server/_libs/zod.mjs +4223 -0
  129. package/admin-dist/server/_ssr/CmsButton-B45JAKR1.mjs +125 -0
  130. package/admin-dist/server/_ssr/CmsEmptyState-D_BQFAVR.mjs +290 -0
  131. package/admin-dist/server/_ssr/CmsPageHeader-CrUZA59A.mjs +24 -0
  132. package/admin-dist/server/_ssr/CmsStatusBadge-B-sj6yaj.mjs +127 -0
  133. package/admin-dist/server/_ssr/CmsSurface-DKJZhpjk.mjs +44 -0
  134. package/admin-dist/server/_ssr/CmsToolbar-ByaW5iXf.mjs +49 -0
  135. package/admin-dist/server/_ssr/ContentEntryEditor-D3_Jb1dq.mjs +3720 -0
  136. package/admin-dist/server/_ssr/ErrorState-cI-bKLez.mjs +89 -0
  137. package/admin-dist/server/_ssr/TaxonomyFilter-BRJkuCtA.mjs +188 -0
  138. package/admin-dist/server/_ssr/_contentTypeId-B9kA6CaM.mjs +379 -0
  139. package/admin-dist/server/_ssr/_entryId-BddcMkZN.mjs +161 -0
  140. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-Dd7AmelK.mjs +4 -0
  141. package/admin-dist/server/_ssr/command-CGtVr8Gb.mjs +128 -0
  142. package/admin-dist/server/_ssr/config.server-D7JHDcDv.mjs +117 -0
  143. package/admin-dist/server/_ssr/content-D1tbeOd0.mjs +647 -0
  144. package/admin-dist/server/_ssr/content-types-BZqY_BER.mjs +1342 -0
  145. package/admin-dist/server/_ssr/index-BIdq4xaC.mjs +264 -0
  146. package/admin-dist/server/_ssr/index.mjs +1275 -0
  147. package/admin-dist/server/_ssr/label-T-QNKAr6.mjs +22 -0
  148. package/admin-dist/server/_ssr/media-C-xqjBrl.mjs +1832 -0
  149. package/admin-dist/server/_ssr/new._contentTypeId-DWic9cRq.mjs +144 -0
  150. package/admin-dist/server/_ssr/router-D1BMAMJT.mjs +1556 -0
  151. package/admin-dist/server/_ssr/scroll-area-C0pic_WA.mjs +59 -0
  152. package/admin-dist/server/_ssr/select-CqmuN2F6.mjs +142 -0
  153. package/admin-dist/server/_ssr/settings-CAkncGGV.mjs +430 -0
  154. package/admin-dist/server/_ssr/start-HYkvq4Ni.mjs +4 -0
  155. package/admin-dist/server/_ssr/switch-CgmuJkT9.mjs +31 -0
  156. package/admin-dist/server/_ssr/tabs-CnMj0aRy.mjs +630 -0
  157. package/admin-dist/server/_ssr/tanstack-adapter-BXZrMauE.mjs +119 -0
  158. package/admin-dist/server/_ssr/taxonomies-thl3BfVm.mjs +1015 -0
  159. package/admin-dist/server/_ssr/textarea-4K5OJgeh.mjs +18 -0
  160. package/admin-dist/server/_ssr/trash-B40Gx5zP.mjs +411 -0
  161. package/admin-dist/server/_ssr/useBreadcrumbLabel-rn-fL4zV.mjs +16 -0
  162. package/admin-dist/server/_ssr/usePermissions-CKeM6_Vw.mjs +68 -0
  163. package/admin-dist/server/favicon.ico +0 -0
  164. package/admin-dist/server/index.mjs +641 -0
  165. package/dist/cli/commands/init.d.ts +6 -0
  166. package/dist/cli/commands/init.d.ts.map +1 -0
  167. package/dist/cli/commands/init.js +156 -0
  168. package/dist/cli/commands/init.js.map +1 -0
  169. package/dist/cli/index.js +6 -0
  170. package/dist/cli/index.js.map +1 -1
  171. package/dist/client/admin-config.d.ts +2 -3
  172. package/dist/client/admin-config.d.ts.map +1 -1
  173. package/dist/client/admin-config.js +2 -3
  174. package/dist/client/admin-config.js.map +1 -1
  175. package/dist/client/adminApi.d.ts +1877 -1851
  176. package/dist/client/adminApi.d.ts.map +1 -1
  177. package/dist/client/adminApi.js +649 -629
  178. package/dist/client/adminApi.js.map +1 -1
  179. package/dist/client/agentTools.d.ts +1231 -139
  180. package/dist/client/agentTools.d.ts.map +1 -1
  181. package/dist/client/agentTools.js +37 -13
  182. package/dist/client/agentTools.js.map +1 -1
  183. package/dist/client/index.d.ts +5 -5
  184. package/dist/client/index.d.ts.map +1 -1
  185. package/dist/client/index.js +4 -4
  186. package/dist/client/index.js.map +1 -1
  187. package/dist/client/schema/codegen.d.ts +2 -2
  188. package/dist/client/schema/codegen.d.ts.map +1 -1
  189. package/dist/client/schema/codegen.js +3 -3
  190. package/dist/client/schema/codegen.js.map +1 -1
  191. package/dist/client/schema/defineContentType.d.ts +3 -3
  192. package/dist/client/schema/defineContentType.js +3 -3
  193. package/dist/client/schema/index.d.ts +7 -7
  194. package/dist/client/schema/index.d.ts.map +1 -1
  195. package/dist/client/schema/index.js +5 -5
  196. package/dist/client/schema/index.js.map +1 -1
  197. package/dist/client/schema/schemaDrift.d.ts +1 -1
  198. package/dist/client/schema/schemaDrift.js +1 -1
  199. package/dist/client/schema/typedClient.d.ts +2 -2
  200. package/dist/client/schema/typedClient.js +2 -2
  201. package/dist/client/schema/types.d.ts +1 -1
  202. package/dist/client/schema/types.js +1 -1
  203. package/dist/client/wrapper.d.ts +108 -65
  204. package/dist/client/wrapper.d.ts.map +1 -1
  205. package/dist/client/wrapper.js +22 -22
  206. package/dist/client/wrapper.js.map +1 -1
  207. package/dist/component/_generated/component.d.ts +9 -0
  208. package/dist/component/_generated/component.d.ts.map +1 -1
  209. package/dist/component/convex.config.d.ts +2 -2
  210. package/dist/component/convex.config.js +2 -2
  211. package/dist/component/index.d.ts +1 -1
  212. package/dist/component/index.js +1 -1
  213. package/dist/component/lib/ragContentChunker.d.ts +1 -1
  214. package/dist/component/lib/ragContentChunker.js +1 -1
  215. package/dist/component/mediaAssets.d.ts +35 -0
  216. package/dist/component/mediaAssets.d.ts.map +1 -1
  217. package/dist/component/mediaAssets.js +81 -0
  218. package/dist/component/mediaAssets.js.map +1 -1
  219. package/dist/component/roles.d.ts +1 -1
  220. package/dist/component/roles.js +1 -1
  221. package/dist/react/index.d.ts +2 -2
  222. package/dist/react/index.d.ts.map +1 -1
  223. package/dist/react/index.js +13 -7
  224. package/dist/react/index.js.map +1 -1
  225. package/dist/test.d.ts +2 -2
  226. package/dist/test.d.ts.map +1 -1
  227. package/dist/test.js +4 -3
  228. package/dist/test.js.map +1 -1
  229. package/package.json +37 -13
  230. package/dist/component/auditLog.d.ts +0 -410
  231. package/dist/component/auditLog.d.ts.map +0 -1
  232. package/dist/component/auditLog.js +0 -607
  233. package/dist/component/auditLog.js.map +0 -1
  234. package/dist/component/types.d.ts +0 -4
  235. package/dist/component/types.d.ts.map +0 -1
  236. package/dist/component/types.js +0 -2
  237. package/dist/component/types.js.map +0 -1
  238. package/src/cli/commands/admin.ts +0 -104
  239. package/src/cli/index.ts +0 -21
  240. package/src/cli/utils/detectConvexUrl.ts +0 -54
  241. package/src/cli/utils/openBrowser.ts +0 -16
  242. package/src/client/admin-config.ts +0 -138
  243. package/src/client/adminApi.ts +0 -942
  244. package/src/client/agentTools.ts +0 -1311
  245. package/src/client/argTypes.ts +0 -316
  246. package/src/client/field-types.ts +0 -187
  247. package/src/client/index.ts +0 -1301
  248. package/src/client/queryBuilder.ts +0 -1100
  249. package/src/client/schema/codegen.ts +0 -500
  250. package/src/client/schema/defineContentType.ts +0 -501
  251. package/src/client/schema/index.ts +0 -169
  252. package/src/client/schema/schemaDrift.ts +0 -574
  253. package/src/client/schema/typedClient.ts +0 -688
  254. package/src/client/schema/types.ts +0 -666
  255. package/src/client/types.ts +0 -723
  256. package/src/client/workflows.ts +0 -141
  257. package/src/client/wrapper.ts +0 -4304
  258. package/src/component/_generated/api.ts +0 -140
  259. package/src/component/_generated/component.ts +0 -5029
  260. package/src/component/_generated/dataModel.ts +0 -60
  261. package/src/component/_generated/server.ts +0 -156
  262. package/src/component/authorization.ts +0 -647
  263. package/src/component/authorizationHooks.ts +0 -668
  264. package/src/component/bulkOperations.ts +0 -687
  265. package/src/component/contentEntries.ts +0 -1976
  266. package/src/component/contentEntryMutations.ts +0 -1223
  267. package/src/component/contentEntryValidation.ts +0 -707
  268. package/src/component/contentLock.ts +0 -550
  269. package/src/component/contentTypeMigration.ts +0 -1064
  270. package/src/component/contentTypeMutations.ts +0 -969
  271. package/src/component/contentTypes.ts +0 -346
  272. package/src/component/convex.config.ts +0 -44
  273. package/src/component/documentTypes.ts +0 -240
  274. package/src/component/eventEmitter.ts +0 -485
  275. package/src/component/exportImport.ts +0 -1169
  276. package/src/component/index.ts +0 -491
  277. package/src/component/lib/deepReferenceResolver.ts +0 -999
  278. package/src/component/lib/errors.ts +0 -816
  279. package/src/component/lib/index.ts +0 -145
  280. package/src/component/lib/mediaReferenceResolver.ts +0 -495
  281. package/src/component/lib/metadataExtractor.ts +0 -792
  282. package/src/component/lib/mutationAuth.ts +0 -199
  283. package/src/component/lib/queries.ts +0 -79
  284. package/src/component/lib/ragContentChunker.ts +0 -1371
  285. package/src/component/lib/referenceResolver.ts +0 -430
  286. package/src/component/lib/slugGenerator.ts +0 -262
  287. package/src/component/lib/slugUniqueness.ts +0 -333
  288. package/src/component/lib/softDelete.ts +0 -44
  289. package/src/component/localeFallbackChain.ts +0 -673
  290. package/src/component/localeFields.ts +0 -896
  291. package/src/component/mediaAssetMutations.ts +0 -725
  292. package/src/component/mediaAssets.ts +0 -932
  293. package/src/component/mediaFolderMutations.ts +0 -1046
  294. package/src/component/mediaUploadMutations.ts +0 -224
  295. package/src/component/mediaVariantMutations.ts +0 -900
  296. package/src/component/mediaVariants.ts +0 -793
  297. package/src/component/ragContentIndexer.ts +0 -1067
  298. package/src/component/rateLimitHooks.ts +0 -572
  299. package/src/component/roles.ts +0 -1360
  300. package/src/component/scheduledPublish.ts +0 -358
  301. package/src/component/schema.ts +0 -617
  302. package/src/component/taxonomies.ts +0 -949
  303. package/src/component/taxonomyMutations.ts +0 -1210
  304. package/src/component/trash.ts +0 -724
  305. package/src/component/userContext.ts +0 -898
  306. package/src/component/validation.ts +0 -1388
  307. package/src/component/validators.ts +0 -949
  308. package/src/component/versionMutations.ts +0 -392
  309. package/src/component/webhookTrigger.ts +0 -1922
  310. package/src/react/index.ts +0 -898
  311. package/src/test.ts +0 -1580
@@ -1,485 +0,0 @@
1
- /**
2
- * Event Emitter Module
3
- *
4
- * Internal system to emit events on content changes (created, updated, published, deleted).
5
- * Events are stored in the cmsEvents table for async processing by external systems,
6
- * webhooks, audit logging, and other integrations.
7
- *
8
- * Design Philosophy:
9
- * - Events are emitted synchronously within the same transaction as mutations
10
- * - This ensures atomicity: if the mutation fails, no event is created
11
- * - Events are stored for later processing (not real-time pub/sub)
12
- * - Consumers can poll events or use Convex reactivity to process them
13
- *
14
- * Usage:
15
- * ```typescript
16
- * // In a mutation handler:
17
- * await emitEvent(ctx, {
18
- * eventType: "contentEntry.created",
19
- * resourceType: "contentEntry",
20
- * resourceId: entry._id.toString(),
21
- * action: "created",
22
- * payload: { slug: entry.slug, contentTypeName: "blog_post" },
23
- * userId: createdBy,
24
- * });
25
- * ```
26
- */
27
-
28
- import { v } from "convex/values";
29
- import { mutation, query, internalMutation, MutationCtx } from "./_generated/server.js";
30
- import {
31
- eventResourceTypeValidator,
32
- eventActionValidator,
33
- cmsEventDoc,
34
- } from "./validators.js";
35
-
36
- // =============================================================================
37
- // Event Types
38
- // =============================================================================
39
-
40
- /**
41
- * Resource types that can emit events.
42
- */
43
- export type EventResourceType =
44
- | "contentEntry"
45
- | "contentType"
46
- | "mediaAsset"
47
- | "mediaFolder";
48
-
49
- /**
50
- * Actions that can be performed on resources.
51
- */
52
- export type EventAction =
53
- | "created"
54
- | "updated"
55
- | "published"
56
- | "unpublished"
57
- | "deleted"
58
- | "restored"
59
- | "duplicated"
60
- | "scheduled";
61
-
62
- /**
63
- * Full event type combining resource and action.
64
- */
65
- export type EventType = `${EventResourceType}.${EventAction}`;
66
-
67
- /**
68
- * Payload structure for content entry events.
69
- */
70
- export interface ContentEntryEventPayload {
71
- slug: string;
72
- contentTypeName: string;
73
- contentTypeId: string;
74
- status: string;
75
- version: number;
76
- locale?: string;
77
- /** For duplicate events, the source entry ID */
78
- sourceEntryId?: string;
79
- /** For scheduled events, the scheduled publish time */
80
- scheduledPublishAt?: number;
81
- /** Change description if provided */
82
- changeDescription?: string;
83
- }
84
-
85
- /**
86
- * Payload structure for content type events.
87
- */
88
- export interface ContentTypeEventPayload {
89
- name: string;
90
- displayName: string;
91
- fieldCount: number;
92
- isActive: boolean;
93
- /** For update events, list of changed field names */
94
- changedFields?: string[];
95
- }
96
-
97
- /**
98
- * Payload structure for media asset events.
99
- */
100
- export interface MediaAssetEventPayload {
101
- name: string;
102
- mimeType: string;
103
- type: string;
104
- size: number;
105
- parentId?: string;
106
- path?: string;
107
- }
108
-
109
- /**
110
- * Payload structure for media folder events.
111
- */
112
- export interface MediaFolderEventPayload {
113
- name: string;
114
- path: string;
115
- parentId?: string;
116
- }
117
-
118
- /**
119
- * Union type for all event payloads.
120
- */
121
- export type EventPayload =
122
- | ContentEntryEventPayload
123
- | ContentTypeEventPayload
124
- | MediaAssetEventPayload
125
- | MediaFolderEventPayload;
126
-
127
- /**
128
- * Parameters for emitting an event.
129
- */
130
- export interface EmitEventParams {
131
- eventType: EventType;
132
- resourceType: EventResourceType;
133
- resourceId: string;
134
- action: EventAction;
135
- payload: EventPayload;
136
- userId?: string;
137
- correlationId?: string;
138
- metadata?: Record<string, unknown>;
139
- }
140
-
141
- /**
142
- * CMS Event document structure (as stored in the database).
143
- */
144
- export interface CMSEvent {
145
- _id: string;
146
- _creationTime: number;
147
- eventType: string;
148
- resourceType: EventResourceType;
149
- resourceId: string;
150
- action: EventAction;
151
- payload: EventPayload;
152
- userId?: string;
153
- processed: boolean;
154
- processedAt?: number;
155
- correlationId?: string;
156
- metadata?: Record<string, unknown>;
157
- }
158
-
159
- // =============================================================================
160
- // Internal Event Emission Helper
161
- // =============================================================================
162
-
163
- /**
164
- * Internal helper function to emit events within mutation handlers.
165
- *
166
- * This function inserts an event record into the cmsEvents table.
167
- * It's designed to be called from within other mutations to ensure
168
- * the event is part of the same atomic transaction.
169
- *
170
- * @param ctx - The mutation context from Convex
171
- * @param params - Event parameters
172
- * @returns The created event ID as a string
173
- */
174
- export async function emitEvent(
175
- ctx: MutationCtx,
176
- params: EmitEventParams
177
- ): Promise<string> {
178
- const {
179
- eventType,
180
- resourceType,
181
- resourceId,
182
- action,
183
- payload,
184
- userId,
185
- correlationId,
186
- metadata,
187
- } = params;
188
-
189
- const eventId = await ctx.db.insert("cmsEvents", {
190
- eventType,
191
- resourceType,
192
- resourceId,
193
- action,
194
- payload,
195
- userId,
196
- processed: false,
197
- correlationId,
198
- metadata,
199
- });
200
-
201
- return eventId;
202
- }
203
-
204
- // =============================================================================
205
- // Event Query Functions
206
- // =============================================================================
207
-
208
- /**
209
- * Query to list recent events with optional filtering.
210
- *
211
- * @param resourceType - Filter by resource type
212
- * @param action - Filter by action
213
- * @param processed - Filter by processed status
214
- * @param limit - Maximum number of events to return
215
- *
216
- * @returns Array of recent events
217
- */
218
- export const listEvents = query({
219
- args: {
220
- resourceType: v.optional(eventResourceTypeValidator),
221
- action: v.optional(eventActionValidator),
222
- processed: v.optional(v.boolean()),
223
- limit: v.optional(v.number()),
224
- cursor: v.optional(v.string()),
225
- },
226
- returns: v.object({
227
- events: v.array(cmsEventDoc),
228
- hasMore: v.boolean(),
229
- }),
230
- handler: async (ctx, args) => {
231
- const { resourceType, action, processed, limit = 50 } = args;
232
-
233
- // Collect and filter in memory for other filters
234
- // (In a production system, you might want more specific indexes)
235
- let events;
236
- if (processed !== undefined) {
237
- events = await ctx.db
238
- .query("cmsEvents")
239
- .withIndex("by_processed", (q) => q.eq("processed", processed))
240
- .order("desc")
241
- .take(limit * 2);
242
- } else {
243
- events = await ctx.db
244
- .query("cmsEvents")
245
- .order("desc")
246
- .take(limit * 2);
247
- }
248
-
249
- // Apply additional filters
250
- if (resourceType !== undefined) {
251
- events = events.filter((e) => e.resourceType === resourceType);
252
- }
253
- if (action !== undefined) {
254
- events = events.filter((e) => e.action === action);
255
- }
256
-
257
- // Limit results
258
- const limitedEvents = events.slice(0, limit);
259
- const hasMore = events.length > limit;
260
-
261
- return {
262
- events: limitedEvents,
263
- hasMore,
264
- };
265
- },
266
- });
267
-
268
- /**
269
- * Query to get events for a specific resource.
270
- *
271
- * @param resourceType - The resource type
272
- * @param resourceId - The resource ID
273
- * @param limit - Maximum number of events to return
274
- *
275
- * @returns Array of events for the resource
276
- */
277
- export const getResourceEvents = query({
278
- args: {
279
- resourceType: eventResourceTypeValidator,
280
- resourceId: v.string(),
281
- limit: v.optional(v.number()),
282
- },
283
- returns: v.array(cmsEventDoc),
284
- handler: async (ctx, args) => {
285
- const { resourceType, resourceId, limit = 50 } = args;
286
-
287
- const events = await ctx.db
288
- .query("cmsEvents")
289
- .withIndex("by_resource", (q) =>
290
- q.eq("resourceType", resourceType).eq("resourceId", resourceId)
291
- )
292
- .order("desc")
293
- .take(limit);
294
-
295
- return events;
296
- },
297
- });
298
-
299
- /**
300
- * Query to get unprocessed events for async processing.
301
- *
302
- * This is useful for building event processors that handle events
303
- * asynchronously (e.g., sending webhooks, updating search indexes).
304
- *
305
- * @param limit - Maximum number of events to return
306
- *
307
- * @returns Array of unprocessed events
308
- */
309
- export const getUnprocessedEvents = query({
310
- args: {
311
- limit: v.optional(v.number()),
312
- },
313
- returns: v.array(cmsEventDoc),
314
- handler: async (ctx, args) => {
315
- const { limit = 100 } = args;
316
-
317
- const events = await ctx.db
318
- .query("cmsEvents")
319
- .withIndex("by_processed", (q) => q.eq("processed", false))
320
- .order("asc") // Process oldest first
321
- .take(limit);
322
-
323
- return events;
324
- },
325
- });
326
-
327
- // =============================================================================
328
- // Event Mutation Functions
329
- // =============================================================================
330
-
331
- /**
332
- * Mutation to mark events as processed.
333
- *
334
- * This should be called by event processors after successfully
335
- * handling an event. This enables at-least-once processing semantics.
336
- *
337
- * @param eventIds - Array of event IDs to mark as processed
338
- *
339
- * @returns Count of events marked as processed
340
- */
341
- export const markEventsProcessed = mutation({
342
- args: {
343
- eventIds: v.array(v.id("cmsEvents")),
344
- },
345
- returns: v.object({
346
- processedCount: v.number(),
347
- }),
348
- handler: async (ctx, args) => {
349
- const { eventIds } = args;
350
- const now = Date.now();
351
- let processedCount = 0;
352
-
353
- for (const eventId of eventIds) {
354
- const event = await ctx.db.get(eventId);
355
- if (event && !event.processed) {
356
- await ctx.db.patch(eventId, {
357
- processed: true,
358
- processedAt: now,
359
- });
360
- processedCount++;
361
- }
362
- }
363
-
364
- return { processedCount };
365
- },
366
- });
367
-
368
- /**
369
- * Internal mutation to emit an event from scheduled functions.
370
- *
371
- * This is used by internal scheduled functions that need to emit events
372
- * but don't have direct access to the emitEvent helper.
373
- */
374
- export const internalEmitEvent = internalMutation({
375
- args: {
376
- eventType: v.string(),
377
- resourceType: v.union(
378
- v.literal("contentEntry"),
379
- v.literal("contentType"),
380
- v.literal("mediaAsset"),
381
- v.literal("mediaFolder")
382
- ),
383
- resourceId: v.string(),
384
- action: v.union(
385
- v.literal("created"),
386
- v.literal("updated"),
387
- v.literal("published"),
388
- v.literal("unpublished"),
389
- v.literal("deleted"),
390
- v.literal("restored"),
391
- v.literal("duplicated"),
392
- v.literal("scheduled")
393
- ),
394
- payload: v.any(),
395
- userId: v.optional(v.string()),
396
- correlationId: v.optional(v.string()),
397
- metadata: v.optional(v.any()),
398
- },
399
- returns: v.id("cmsEvents"),
400
- handler: async (ctx, args) => {
401
- const eventId = await ctx.db.insert("cmsEvents", {
402
- eventType: args.eventType,
403
- resourceType: args.resourceType,
404
- resourceId: args.resourceId,
405
- action: args.action,
406
- payload: args.payload,
407
- userId: args.userId,
408
- processed: false,
409
- correlationId: args.correlationId,
410
- metadata: args.metadata,
411
- });
412
-
413
- return eventId;
414
- },
415
- });
416
-
417
- /**
418
- * Mutation to clean up old processed events.
419
- *
420
- * Events older than the retention period are permanently deleted.
421
- * This helps prevent unbounded growth of the events table.
422
- *
423
- * @param retentionDays - Number of days to retain processed events (default: 30)
424
- *
425
- * @returns Count of events deleted
426
- */
427
- export const cleanupOldEvents = mutation({
428
- args: {
429
- retentionDays: v.optional(v.number()),
430
- },
431
- returns: v.object({
432
- deletedCount: v.number(),
433
- }),
434
- handler: async (ctx, args) => {
435
- const { retentionDays = 30 } = args;
436
- const cutoffTime = Date.now() - retentionDays * 24 * 60 * 60 * 1000;
437
- let deletedCount = 0;
438
-
439
- // Get old processed events
440
- const oldEvents = await ctx.db
441
- .query("cmsEvents")
442
- .withIndex("by_processed", (q) => q.eq("processed", true))
443
- .filter((q) => q.lt(q.field("_creationTime"), cutoffTime))
444
- .take(1000); // Batch limit for safety
445
-
446
- for (const event of oldEvents) {
447
- await ctx.db.delete(event._id);
448
- deletedCount++;
449
- }
450
-
451
- return { deletedCount };
452
- },
453
- });
454
-
455
- // =============================================================================
456
- // Event Type Builders
457
- // =============================================================================
458
-
459
- /**
460
- * Helper function to build a content entry event type string.
461
- */
462
- export function contentEntryEventType(action: EventAction): EventType {
463
- return `contentEntry.${action}`;
464
- }
465
-
466
- /**
467
- * Helper function to build a content type event type string.
468
- */
469
- export function contentTypeEventType(action: EventAction): EventType {
470
- return `contentType.${action}`;
471
- }
472
-
473
- /**
474
- * Helper function to build a media asset event type string.
475
- */
476
- export function mediaAssetEventType(action: EventAction): EventType {
477
- return `mediaAsset.${action}`;
478
- }
479
-
480
- /**
481
- * Helper function to build a media folder event type string.
482
- */
483
- export function mediaFolderEventType(action: EventAction): EventType {
484
- return `mediaFolder.${action}`;
485
- }