convex-cms 0.0.1

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 (379) hide show
  1. package/dist/cli/commands/admin.d.ts +16 -0
  2. package/dist/cli/commands/admin.d.ts.map +1 -0
  3. package/dist/cli/commands/admin.js +88 -0
  4. package/dist/cli/commands/admin.js.map +1 -0
  5. package/dist/cli/index.d.ts +3 -0
  6. package/dist/cli/index.d.ts.map +1 -0
  7. package/dist/cli/index.js +18 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/cli/utils/detectConvexUrl.d.ts +13 -0
  10. package/dist/cli/utils/detectConvexUrl.d.ts.map +1 -0
  11. package/dist/cli/utils/detectConvexUrl.js +48 -0
  12. package/dist/cli/utils/detectConvexUrl.js.map +1 -0
  13. package/dist/cli/utils/openBrowser.d.ts +7 -0
  14. package/dist/cli/utils/openBrowser.d.ts.map +1 -0
  15. package/dist/cli/utils/openBrowser.js +17 -0
  16. package/dist/cli/utils/openBrowser.js.map +1 -0
  17. package/dist/client/admin-config.d.ts +126 -0
  18. package/dist/client/admin-config.d.ts.map +1 -0
  19. package/dist/client/admin-config.js +117 -0
  20. package/dist/client/admin-config.js.map +1 -0
  21. package/dist/client/adminApi.d.ts +2273 -0
  22. package/dist/client/adminApi.d.ts.map +1 -0
  23. package/dist/client/adminApi.js +716 -0
  24. package/dist/client/adminApi.js.map +1 -0
  25. package/dist/client/agentTools.d.ts +933 -0
  26. package/dist/client/agentTools.d.ts.map +1 -0
  27. package/dist/client/agentTools.js +1004 -0
  28. package/dist/client/agentTools.js.map +1 -0
  29. package/dist/client/argTypes.d.ts +212 -0
  30. package/dist/client/argTypes.d.ts.map +1 -0
  31. package/dist/client/argTypes.js +5 -0
  32. package/dist/client/argTypes.js.map +1 -0
  33. package/dist/client/field-types.d.ts +55 -0
  34. package/dist/client/field-types.d.ts.map +1 -0
  35. package/dist/client/field-types.js +152 -0
  36. package/dist/client/field-types.js.map +1 -0
  37. package/dist/client/index.d.ts +189 -0
  38. package/dist/client/index.d.ts.map +1 -0
  39. package/dist/client/index.js +668 -0
  40. package/dist/client/index.js.map +1 -0
  41. package/dist/client/queryBuilder.d.ts +765 -0
  42. package/dist/client/queryBuilder.d.ts.map +1 -0
  43. package/dist/client/queryBuilder.js +970 -0
  44. package/dist/client/queryBuilder.js.map +1 -0
  45. package/dist/client/schema/codegen.d.ts +128 -0
  46. package/dist/client/schema/codegen.d.ts.map +1 -0
  47. package/dist/client/schema/codegen.js +318 -0
  48. package/dist/client/schema/codegen.js.map +1 -0
  49. package/dist/client/schema/defineContentType.d.ts +221 -0
  50. package/dist/client/schema/defineContentType.d.ts.map +1 -0
  51. package/dist/client/schema/defineContentType.js +380 -0
  52. package/dist/client/schema/defineContentType.js.map +1 -0
  53. package/dist/client/schema/index.d.ts +85 -0
  54. package/dist/client/schema/index.d.ts.map +1 -0
  55. package/dist/client/schema/index.js +92 -0
  56. package/dist/client/schema/index.js.map +1 -0
  57. package/dist/client/schema/schemaDrift.d.ts +199 -0
  58. package/dist/client/schema/schemaDrift.d.ts.map +1 -0
  59. package/dist/client/schema/schemaDrift.js +340 -0
  60. package/dist/client/schema/schemaDrift.js.map +1 -0
  61. package/dist/client/schema/typedClient.d.ts +401 -0
  62. package/dist/client/schema/typedClient.d.ts.map +1 -0
  63. package/dist/client/schema/typedClient.js +269 -0
  64. package/dist/client/schema/typedClient.js.map +1 -0
  65. package/dist/client/schema/types.d.ts +477 -0
  66. package/dist/client/schema/types.d.ts.map +1 -0
  67. package/dist/client/schema/types.js +39 -0
  68. package/dist/client/schema/types.js.map +1 -0
  69. package/dist/client/types.d.ts +449 -0
  70. package/dist/client/types.d.ts.map +1 -0
  71. package/dist/client/types.js +149 -0
  72. package/dist/client/types.js.map +1 -0
  73. package/dist/client/workflows.d.ts +51 -0
  74. package/dist/client/workflows.d.ts.map +1 -0
  75. package/dist/client/workflows.js +103 -0
  76. package/dist/client/workflows.js.map +1 -0
  77. package/dist/client/wrapper.d.ts +2198 -0
  78. package/dist/client/wrapper.d.ts.map +1 -0
  79. package/dist/client/wrapper.js +2651 -0
  80. package/dist/client/wrapper.js.map +1 -0
  81. package/dist/component/_generated/api.d.ts +124 -0
  82. package/dist/component/_generated/api.d.ts.map +1 -0
  83. package/dist/component/_generated/api.js +31 -0
  84. package/dist/component/_generated/api.js.map +1 -0
  85. package/dist/component/_generated/component.d.ts +4321 -0
  86. package/dist/component/_generated/component.d.ts.map +1 -0
  87. package/dist/component/_generated/component.js +11 -0
  88. package/dist/component/_generated/component.js.map +1 -0
  89. package/dist/component/_generated/dataModel.d.ts +46 -0
  90. package/dist/component/_generated/dataModel.d.ts.map +1 -0
  91. package/dist/component/_generated/dataModel.js +11 -0
  92. package/dist/component/_generated/dataModel.js.map +1 -0
  93. package/dist/component/_generated/server.d.ts +121 -0
  94. package/dist/component/_generated/server.d.ts.map +1 -0
  95. package/dist/component/_generated/server.js +78 -0
  96. package/dist/component/_generated/server.js.map +1 -0
  97. package/dist/component/auditLog.d.ts +410 -0
  98. package/dist/component/auditLog.d.ts.map +1 -0
  99. package/dist/component/auditLog.js +607 -0
  100. package/dist/component/auditLog.js.map +1 -0
  101. package/dist/component/authorization.d.ts +323 -0
  102. package/dist/component/authorization.d.ts.map +1 -0
  103. package/dist/component/authorization.js +464 -0
  104. package/dist/component/authorization.js.map +1 -0
  105. package/dist/component/authorizationHooks.d.ts +184 -0
  106. package/dist/component/authorizationHooks.d.ts.map +1 -0
  107. package/dist/component/authorizationHooks.js +521 -0
  108. package/dist/component/authorizationHooks.js.map +1 -0
  109. package/dist/component/bulkOperations.d.ts +200 -0
  110. package/dist/component/bulkOperations.d.ts.map +1 -0
  111. package/dist/component/bulkOperations.js +568 -0
  112. package/dist/component/bulkOperations.js.map +1 -0
  113. package/dist/component/contentEntries.d.ts +719 -0
  114. package/dist/component/contentEntries.d.ts.map +1 -0
  115. package/dist/component/contentEntries.js +1617 -0
  116. package/dist/component/contentEntries.js.map +1 -0
  117. package/dist/component/contentEntryMutations.d.ts +505 -0
  118. package/dist/component/contentEntryMutations.d.ts.map +1 -0
  119. package/dist/component/contentEntryMutations.js +1009 -0
  120. package/dist/component/contentEntryMutations.js.map +1 -0
  121. package/dist/component/contentEntryValidation.d.ts +115 -0
  122. package/dist/component/contentEntryValidation.d.ts.map +1 -0
  123. package/dist/component/contentEntryValidation.js +546 -0
  124. package/dist/component/contentEntryValidation.js.map +1 -0
  125. package/dist/component/contentLock.d.ts +328 -0
  126. package/dist/component/contentLock.d.ts.map +1 -0
  127. package/dist/component/contentLock.js +471 -0
  128. package/dist/component/contentLock.js.map +1 -0
  129. package/dist/component/contentTypeMigration.d.ts +411 -0
  130. package/dist/component/contentTypeMigration.d.ts.map +1 -0
  131. package/dist/component/contentTypeMigration.js +805 -0
  132. package/dist/component/contentTypeMigration.js.map +1 -0
  133. package/dist/component/contentTypeMutations.d.ts +975 -0
  134. package/dist/component/contentTypeMutations.d.ts.map +1 -0
  135. package/dist/component/contentTypeMutations.js +768 -0
  136. package/dist/component/contentTypeMutations.js.map +1 -0
  137. package/dist/component/contentTypes.d.ts +538 -0
  138. package/dist/component/contentTypes.d.ts.map +1 -0
  139. package/dist/component/contentTypes.js +304 -0
  140. package/dist/component/contentTypes.js.map +1 -0
  141. package/dist/component/convex.config.d.ts +42 -0
  142. package/dist/component/convex.config.d.ts.map +1 -0
  143. package/dist/component/convex.config.js +43 -0
  144. package/dist/component/convex.config.js.map +1 -0
  145. package/dist/component/documentTypes.d.ts +186 -0
  146. package/dist/component/documentTypes.d.ts.map +1 -0
  147. package/dist/component/documentTypes.js +23 -0
  148. package/dist/component/documentTypes.js.map +1 -0
  149. package/dist/component/eventEmitter.d.ts +281 -0
  150. package/dist/component/eventEmitter.d.ts.map +1 -0
  151. package/dist/component/eventEmitter.js +300 -0
  152. package/dist/component/eventEmitter.js.map +1 -0
  153. package/dist/component/exportImport.d.ts +1120 -0
  154. package/dist/component/exportImport.d.ts.map +1 -0
  155. package/dist/component/exportImport.js +931 -0
  156. package/dist/component/exportImport.js.map +1 -0
  157. package/dist/component/index.d.ts +28 -0
  158. package/dist/component/index.d.ts.map +1 -0
  159. package/dist/component/index.js +142 -0
  160. package/dist/component/index.js.map +1 -0
  161. package/dist/component/lib/deepReferenceResolver.d.ts +252 -0
  162. package/dist/component/lib/deepReferenceResolver.d.ts.map +1 -0
  163. package/dist/component/lib/deepReferenceResolver.js +601 -0
  164. package/dist/component/lib/deepReferenceResolver.js.map +1 -0
  165. package/dist/component/lib/errors.d.ts +306 -0
  166. package/dist/component/lib/errors.d.ts.map +1 -0
  167. package/dist/component/lib/errors.js +407 -0
  168. package/dist/component/lib/errors.js.map +1 -0
  169. package/dist/component/lib/index.d.ts +10 -0
  170. package/dist/component/lib/index.d.ts.map +1 -0
  171. package/dist/component/lib/index.js +33 -0
  172. package/dist/component/lib/index.js.map +1 -0
  173. package/dist/component/lib/mediaReferenceResolver.d.ts +217 -0
  174. package/dist/component/lib/mediaReferenceResolver.d.ts.map +1 -0
  175. package/dist/component/lib/mediaReferenceResolver.js +326 -0
  176. package/dist/component/lib/mediaReferenceResolver.js.map +1 -0
  177. package/dist/component/lib/metadataExtractor.d.ts +245 -0
  178. package/dist/component/lib/metadataExtractor.d.ts.map +1 -0
  179. package/dist/component/lib/metadataExtractor.js +548 -0
  180. package/dist/component/lib/metadataExtractor.js.map +1 -0
  181. package/dist/component/lib/mutationAuth.d.ts +95 -0
  182. package/dist/component/lib/mutationAuth.d.ts.map +1 -0
  183. package/dist/component/lib/mutationAuth.js +146 -0
  184. package/dist/component/lib/mutationAuth.js.map +1 -0
  185. package/dist/component/lib/queries.d.ts +17 -0
  186. package/dist/component/lib/queries.d.ts.map +1 -0
  187. package/dist/component/lib/queries.js +49 -0
  188. package/dist/component/lib/queries.js.map +1 -0
  189. package/dist/component/lib/ragContentChunker.d.ts +423 -0
  190. package/dist/component/lib/ragContentChunker.d.ts.map +1 -0
  191. package/dist/component/lib/ragContentChunker.js +897 -0
  192. package/dist/component/lib/ragContentChunker.js.map +1 -0
  193. package/dist/component/lib/referenceResolver.d.ts +175 -0
  194. package/dist/component/lib/referenceResolver.d.ts.map +1 -0
  195. package/dist/component/lib/referenceResolver.js +293 -0
  196. package/dist/component/lib/referenceResolver.js.map +1 -0
  197. package/dist/component/lib/slugGenerator.d.ts +71 -0
  198. package/dist/component/lib/slugGenerator.d.ts.map +1 -0
  199. package/dist/component/lib/slugGenerator.js +207 -0
  200. package/dist/component/lib/slugGenerator.js.map +1 -0
  201. package/dist/component/lib/slugUniqueness.d.ts +131 -0
  202. package/dist/component/lib/slugUniqueness.d.ts.map +1 -0
  203. package/dist/component/lib/slugUniqueness.js +229 -0
  204. package/dist/component/lib/slugUniqueness.js.map +1 -0
  205. package/dist/component/lib/softDelete.d.ts +18 -0
  206. package/dist/component/lib/softDelete.d.ts.map +1 -0
  207. package/dist/component/lib/softDelete.js +29 -0
  208. package/dist/component/lib/softDelete.js.map +1 -0
  209. package/dist/component/localeFallbackChain.d.ts +410 -0
  210. package/dist/component/localeFallbackChain.d.ts.map +1 -0
  211. package/dist/component/localeFallbackChain.js +467 -0
  212. package/dist/component/localeFallbackChain.js.map +1 -0
  213. package/dist/component/localeFields.d.ts +508 -0
  214. package/dist/component/localeFields.d.ts.map +1 -0
  215. package/dist/component/localeFields.js +592 -0
  216. package/dist/component/localeFields.js.map +1 -0
  217. package/dist/component/mediaAssetMutations.d.ts +235 -0
  218. package/dist/component/mediaAssetMutations.d.ts.map +1 -0
  219. package/dist/component/mediaAssetMutations.js +558 -0
  220. package/dist/component/mediaAssetMutations.js.map +1 -0
  221. package/dist/component/mediaAssets.d.ts +168 -0
  222. package/dist/component/mediaAssets.d.ts.map +1 -0
  223. package/dist/component/mediaAssets.js +618 -0
  224. package/dist/component/mediaAssets.js.map +1 -0
  225. package/dist/component/mediaFolderMutations.d.ts +642 -0
  226. package/dist/component/mediaFolderMutations.d.ts.map +1 -0
  227. package/dist/component/mediaFolderMutations.js +849 -0
  228. package/dist/component/mediaFolderMutations.js.map +1 -0
  229. package/dist/component/mediaUploadMutations.d.ts +136 -0
  230. package/dist/component/mediaUploadMutations.d.ts.map +1 -0
  231. package/dist/component/mediaUploadMutations.js +205 -0
  232. package/dist/component/mediaUploadMutations.js.map +1 -0
  233. package/dist/component/mediaVariantMutations.d.ts +468 -0
  234. package/dist/component/mediaVariantMutations.d.ts.map +1 -0
  235. package/dist/component/mediaVariantMutations.js +737 -0
  236. package/dist/component/mediaVariantMutations.js.map +1 -0
  237. package/dist/component/mediaVariants.d.ts +525 -0
  238. package/dist/component/mediaVariants.d.ts.map +1 -0
  239. package/dist/component/mediaVariants.js +661 -0
  240. package/dist/component/mediaVariants.js.map +1 -0
  241. package/dist/component/ragContentIndexer.d.ts +595 -0
  242. package/dist/component/ragContentIndexer.d.ts.map +1 -0
  243. package/dist/component/ragContentIndexer.js +794 -0
  244. package/dist/component/ragContentIndexer.js.map +1 -0
  245. package/dist/component/rateLimitHooks.d.ts +266 -0
  246. package/dist/component/rateLimitHooks.d.ts.map +1 -0
  247. package/dist/component/rateLimitHooks.js +412 -0
  248. package/dist/component/rateLimitHooks.js.map +1 -0
  249. package/dist/component/roles.d.ts +649 -0
  250. package/dist/component/roles.d.ts.map +1 -0
  251. package/dist/component/roles.js +884 -0
  252. package/dist/component/roles.js.map +1 -0
  253. package/dist/component/scheduledPublish.d.ts +182 -0
  254. package/dist/component/scheduledPublish.d.ts.map +1 -0
  255. package/dist/component/scheduledPublish.js +304 -0
  256. package/dist/component/scheduledPublish.js.map +1 -0
  257. package/dist/component/schema.d.ts +4114 -0
  258. package/dist/component/schema.d.ts.map +1 -0
  259. package/dist/component/schema.js +469 -0
  260. package/dist/component/schema.js.map +1 -0
  261. package/dist/component/taxonomies.d.ts +476 -0
  262. package/dist/component/taxonomies.d.ts.map +1 -0
  263. package/dist/component/taxonomies.js +785 -0
  264. package/dist/component/taxonomies.js.map +1 -0
  265. package/dist/component/taxonomyMutations.d.ts +206 -0
  266. package/dist/component/taxonomyMutations.d.ts.map +1 -0
  267. package/dist/component/taxonomyMutations.js +1001 -0
  268. package/dist/component/taxonomyMutations.js.map +1 -0
  269. package/dist/component/trash.d.ts +265 -0
  270. package/dist/component/trash.d.ts.map +1 -0
  271. package/dist/component/trash.js +621 -0
  272. package/dist/component/trash.js.map +1 -0
  273. package/dist/component/types.d.ts +4 -0
  274. package/dist/component/types.d.ts.map +1 -0
  275. package/dist/component/types.js +2 -0
  276. package/dist/component/types.js.map +1 -0
  277. package/dist/component/userContext.d.ts +508 -0
  278. package/dist/component/userContext.d.ts.map +1 -0
  279. package/dist/component/userContext.js +615 -0
  280. package/dist/component/userContext.js.map +1 -0
  281. package/dist/component/validation.d.ts +387 -0
  282. package/dist/component/validation.d.ts.map +1 -0
  283. package/dist/component/validation.js +1052 -0
  284. package/dist/component/validation.js.map +1 -0
  285. package/dist/component/validators.d.ts +4645 -0
  286. package/dist/component/validators.d.ts.map +1 -0
  287. package/dist/component/validators.js +641 -0
  288. package/dist/component/validators.js.map +1 -0
  289. package/dist/component/versionMutations.d.ts +216 -0
  290. package/dist/component/versionMutations.d.ts.map +1 -0
  291. package/dist/component/versionMutations.js +321 -0
  292. package/dist/component/versionMutations.js.map +1 -0
  293. package/dist/component/webhookTrigger.d.ts +770 -0
  294. package/dist/component/webhookTrigger.d.ts.map +1 -0
  295. package/dist/component/webhookTrigger.js +1413 -0
  296. package/dist/component/webhookTrigger.js.map +1 -0
  297. package/dist/react/index.d.ts +316 -0
  298. package/dist/react/index.d.ts.map +1 -0
  299. package/dist/react/index.js +558 -0
  300. package/dist/react/index.js.map +1 -0
  301. package/dist/test.d.ts +2230 -0
  302. package/dist/test.d.ts.map +1 -0
  303. package/dist/test.js +1107 -0
  304. package/dist/test.js.map +1 -0
  305. package/package.json +95 -0
  306. package/src/cli/commands/admin.ts +104 -0
  307. package/src/cli/index.ts +21 -0
  308. package/src/cli/utils/detectConvexUrl.ts +54 -0
  309. package/src/cli/utils/openBrowser.ts +16 -0
  310. package/src/client/admin-config.ts +138 -0
  311. package/src/client/adminApi.ts +942 -0
  312. package/src/client/agentTools.ts +1311 -0
  313. package/src/client/argTypes.ts +316 -0
  314. package/src/client/field-types.ts +187 -0
  315. package/src/client/index.ts +1301 -0
  316. package/src/client/queryBuilder.ts +1100 -0
  317. package/src/client/schema/codegen.ts +500 -0
  318. package/src/client/schema/defineContentType.ts +501 -0
  319. package/src/client/schema/index.ts +169 -0
  320. package/src/client/schema/schemaDrift.ts +574 -0
  321. package/src/client/schema/typedClient.ts +688 -0
  322. package/src/client/schema/types.ts +666 -0
  323. package/src/client/types.ts +723 -0
  324. package/src/client/workflows.ts +141 -0
  325. package/src/client/wrapper.ts +4304 -0
  326. package/src/component/_generated/api.ts +140 -0
  327. package/src/component/_generated/component.ts +5029 -0
  328. package/src/component/_generated/dataModel.ts +60 -0
  329. package/src/component/_generated/server.ts +156 -0
  330. package/src/component/authorization.ts +647 -0
  331. package/src/component/authorizationHooks.ts +668 -0
  332. package/src/component/bulkOperations.ts +687 -0
  333. package/src/component/contentEntries.ts +1976 -0
  334. package/src/component/contentEntryMutations.ts +1223 -0
  335. package/src/component/contentEntryValidation.ts +707 -0
  336. package/src/component/contentLock.ts +550 -0
  337. package/src/component/contentTypeMigration.ts +1064 -0
  338. package/src/component/contentTypeMutations.ts +969 -0
  339. package/src/component/contentTypes.ts +346 -0
  340. package/src/component/convex.config.ts +44 -0
  341. package/src/component/documentTypes.ts +240 -0
  342. package/src/component/eventEmitter.ts +485 -0
  343. package/src/component/exportImport.ts +1169 -0
  344. package/src/component/index.ts +491 -0
  345. package/src/component/lib/deepReferenceResolver.ts +999 -0
  346. package/src/component/lib/errors.ts +816 -0
  347. package/src/component/lib/index.ts +145 -0
  348. package/src/component/lib/mediaReferenceResolver.ts +495 -0
  349. package/src/component/lib/metadataExtractor.ts +792 -0
  350. package/src/component/lib/mutationAuth.ts +199 -0
  351. package/src/component/lib/queries.ts +79 -0
  352. package/src/component/lib/ragContentChunker.ts +1371 -0
  353. package/src/component/lib/referenceResolver.ts +430 -0
  354. package/src/component/lib/slugGenerator.ts +262 -0
  355. package/src/component/lib/slugUniqueness.ts +333 -0
  356. package/src/component/lib/softDelete.ts +44 -0
  357. package/src/component/localeFallbackChain.ts +673 -0
  358. package/src/component/localeFields.ts +896 -0
  359. package/src/component/mediaAssetMutations.ts +725 -0
  360. package/src/component/mediaAssets.ts +932 -0
  361. package/src/component/mediaFolderMutations.ts +1046 -0
  362. package/src/component/mediaUploadMutations.ts +224 -0
  363. package/src/component/mediaVariantMutations.ts +900 -0
  364. package/src/component/mediaVariants.ts +793 -0
  365. package/src/component/ragContentIndexer.ts +1067 -0
  366. package/src/component/rateLimitHooks.ts +572 -0
  367. package/src/component/roles.ts +1360 -0
  368. package/src/component/scheduledPublish.ts +358 -0
  369. package/src/component/schema.ts +617 -0
  370. package/src/component/taxonomies.ts +949 -0
  371. package/src/component/taxonomyMutations.ts +1210 -0
  372. package/src/component/trash.ts +724 -0
  373. package/src/component/userContext.ts +898 -0
  374. package/src/component/validation.ts +1388 -0
  375. package/src/component/validators.ts +949 -0
  376. package/src/component/versionMutations.ts +392 -0
  377. package/src/component/webhookTrigger.ts +1922 -0
  378. package/src/react/index.ts +898 -0
  379. package/src/test.ts +1580 -0
@@ -0,0 +1,485 @@
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
+ }