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,949 @@
1
+ /**
2
+ * Shared validators for the CMS component.
3
+ *
4
+ * These validators can be imported and used in function definitions
5
+ * to ensure type-safe arguments and return values.
6
+ *
7
+ * Provides:
8
+ * - Field type validators for content type definitions
9
+ * - Argument validators for CRUD operations
10
+ * - Document validators for return types (derived from schema)
11
+ *
12
+ * Document validators are derived from the schema using convex-helpers `doc()`
13
+ * function, ensuring they stay in sync with schema definitions automatically.
14
+ */
15
+
16
+ import { Infer,
17
+ v, type Validator } from "convex/values";
18
+ import { paginationOptsValidator } from "convex/server";
19
+ import { doc } from "convex-helpers/validators";
20
+ import schema, {
21
+ fieldTypeValidator,
22
+ fieldDefinitionValidator,
23
+ contentStatusValidator,
24
+ mediaTypeValidator,
25
+ variantTypeValidator,
26
+ variantStatusValidator,
27
+ mediaItemValidator,
28
+ mediaAssetItemValidator,
29
+ mediaFolderItemValidator,
30
+ fieldTypes,
31
+ contentStatuses,
32
+ mediaTypes,
33
+ variantTypes,
34
+ variantStatuses,
35
+ variantFormats,
36
+ } from "./schema.js";
37
+
38
+ // Re-export schema validators for convenience
39
+ export {
40
+ fieldTypeValidator,
41
+ fieldDefinitionValidator,
42
+ contentStatusValidator,
43
+ mediaTypeValidator,
44
+ variantTypeValidator,
45
+ variantStatusValidator,
46
+ };
47
+
48
+ // Re-export schema constants for convenience
49
+ export {
50
+ fieldTypes,
51
+ contentStatuses,
52
+ mediaTypes,
53
+ variantTypes,
54
+ variantStatuses,
55
+ variantFormats,
56
+ };
57
+
58
+ // =============================================================================
59
+ // Content Type Validators
60
+ // =============================================================================
61
+
62
+ /**
63
+ * Args for creating a content type - only user-provided fields.
64
+ * Fields like isActive, deletedAt are set by the mutation.
65
+ */
66
+ export const createContentTypeArgs = v.object({
67
+ name: v.string(),
68
+ displayName: v.string(),
69
+ createdBy: v.string(),
70
+ description: v.optional(v.string()),
71
+ fields: v.array(fieldDefinitionValidator),
72
+ icon: v.optional(v.string()),
73
+ singleton: v.optional(v.boolean()),
74
+ slugField: v.optional(v.string()),
75
+ titleField: v.optional(v.string()),
76
+ sortOrder: v.optional(v.number()),
77
+ // isActive defaults to true in the mutation
78
+ // deletedAt is not set on creation
79
+ });
80
+
81
+ /**
82
+ * Args for updating a content type - all fields optional except id.
83
+ */
84
+ export const updateContentTypeArgs = v.object({
85
+ id: v.id("contentTypes"),
86
+ displayName: v.optional(v.string()),
87
+ description: v.optional(v.string()),
88
+ fields: v.optional(v.array(fieldDefinitionValidator)),
89
+ icon: v.optional(v.string()),
90
+ singleton: v.optional(v.boolean()),
91
+ slugField: v.optional(v.string()),
92
+ titleField: v.optional(v.string()),
93
+ sortOrder: v.optional(v.number()),
94
+ isActive: v.optional(v.boolean()),
95
+ updatedBy: v.optional(v.string()),
96
+ // name cannot be updated (used as identifier)
97
+ });
98
+
99
+ export const deleteContentTypeArgs = v.object({
100
+ id: v.id("contentTypes"),
101
+ cascade: v.optional(v.boolean()),
102
+ hardDelete: v.optional(v.boolean()),
103
+ deletedBy: v.optional(v.string()),
104
+ });
105
+
106
+ // =============================================================================
107
+ // Content Entry Validators
108
+ // =============================================================================
109
+
110
+ /**
111
+ * Args for creating a content entry - only user-provided fields.
112
+ * Fields like version, deletedAt, searchText are set by the mutation.
113
+ */
114
+ export const createContentEntryArgs = v.object({
115
+ contentTypeId: v.id("contentTypes"),
116
+ slug: v.optional(v.string()), // Optional - auto-generated if not provided
117
+ data: v.any(),
118
+ locale: v.optional(v.string()),
119
+ primaryEntryId: v.optional(v.id("contentEntries")),
120
+ status: v.optional(contentStatusValidator), // Defaults to "draft"
121
+ scheduledPublishAt: v.optional(v.number()),
122
+ createdBy: v.optional(v.string()),
123
+ // version is set to 1 by the mutation
124
+ // deletedAt, searchText are not set on creation
125
+ });
126
+
127
+ export const updateContentEntryArgs = v.object({
128
+ id: v.id("contentEntries"),
129
+ slug: v.optional(v.string()),
130
+ data: v.optional(v.any()),
131
+ status: v.optional(contentStatusValidator),
132
+ scheduledPublishAt: v.optional(v.number()),
133
+ updatedBy: v.optional(v.string()),
134
+ regenerateSlug: v.optional(v.boolean()),
135
+ });
136
+
137
+ export const publishEntryArgs = v.object({
138
+ id: v.id("contentEntries"),
139
+ changeDescription: v.optional(v.string()),
140
+ updatedBy: v.optional(v.string()),
141
+ });
142
+
143
+ export const scheduleEntryArgs = v.object({
144
+ id: v.id("contentEntries"),
145
+ publishAt: v.number(),
146
+ updatedBy: v.optional(v.string()),
147
+ });
148
+
149
+ export const unpublishEntryArgs = v.object({
150
+ id: v.id("contentEntries"),
151
+ updatedBy: v.optional(v.string()),
152
+ });
153
+
154
+ export const deleteContentEntryArgs = v.object({
155
+ id: v.id("contentEntries"),
156
+ deletedBy: v.optional(v.string()),
157
+ hardDelete: v.optional(v.boolean()),
158
+ });
159
+
160
+ export const duplicateContentEntryArgs = v.object({
161
+ sourceEntryId: v.id("contentEntries"),
162
+ slug: v.optional(v.string()),
163
+ copyMediaReferences: v.optional(v.boolean()),
164
+ locale: v.optional(v.string()),
165
+ createdBy: v.optional(v.string()),
166
+ });
167
+
168
+ // =============================================================================
169
+ // Version Validators
170
+ // =============================================================================
171
+
172
+ export const getVersionHistoryArgs = v.object({
173
+ entryId: v.id("contentEntries"),
174
+ paginationOpts: paginationOptsValidator,
175
+ });
176
+
177
+ export const getVersionArgs = v.object({
178
+ entryId: v.id("contentEntries"),
179
+ versionId: v.optional(v.id("contentVersions")),
180
+ versionNumber: v.optional(v.number()),
181
+ });
182
+
183
+ export const rollbackVersionArgs = v.object({
184
+ entryId: v.id("contentEntries"),
185
+ versionNumber: v.number(),
186
+ updatedBy: v.optional(v.string()),
187
+ });
188
+
189
+ export const createVersionSnapshotArgs = v.object({
190
+ entryId: v.id("contentEntries"),
191
+ changeDescription: v.optional(v.string()),
192
+ createdBy: v.optional(v.string()),
193
+ wasPublished: v.optional(v.boolean()),
194
+ });
195
+
196
+ export const compareVersionsArgs = v.object({
197
+ entryId: v.id("contentEntries"),
198
+ fromVersionNumber: v.number(),
199
+ toVersionNumber: v.number(),
200
+ });
201
+
202
+ export const versionFieldDiff = v.object({
203
+ field: v.string(),
204
+ fromValue: v.optional(v.any()),
205
+ toValue: v.optional(v.any()),
206
+ changeType: v.union(
207
+ v.literal("added"),
208
+ v.literal("removed"),
209
+ v.literal("modified"),
210
+ ),
211
+ });
212
+
213
+ export const compareVersionsResult = v.object({
214
+ hasChanges: v.boolean(),
215
+ fromVersion: v.object({
216
+ versionNumber: v.number(),
217
+ status: contentStatusValidator,
218
+ slug: v.string(),
219
+ wasPublished: v.boolean(),
220
+ createdAt: v.number(),
221
+ }),
222
+ toVersion: v.object({
223
+ versionNumber: v.number(),
224
+ status: contentStatusValidator,
225
+ slug: v.string(),
226
+ wasPublished: v.boolean(),
227
+ createdAt: v.number(),
228
+ }),
229
+ changedFields: v.array(v.string()),
230
+ fieldDiffs: v.array(versionFieldDiff),
231
+ slugChanged: v.boolean(),
232
+ statusChanged: v.boolean(),
233
+ changeSummary: v.string(),
234
+ });
235
+
236
+ // =============================================================================
237
+ // Media Asset Validators
238
+ // =============================================================================
239
+
240
+ /**
241
+ * Args for creating a media asset.
242
+ * Required: storageId, mimeType, name
243
+ * Optional: metadata fields like title, description, altText
244
+ */
245
+ export const createMediaAssetArgs = v.object({
246
+ storageId: v.id("_storage"),
247
+ mimeType: v.string(),
248
+ name: v.string(),
249
+ title: v.optional(v.string()),
250
+ description: v.optional(v.string()),
251
+ parentId: v.optional(v.id("mediaItems")),
252
+ tags: v.optional(v.array(v.string())),
253
+ size: v.optional(v.number()),
254
+ metadata: v.optional(v.record(v.string(), v.any())),
255
+ width: v.optional(v.number()),
256
+ height: v.optional(v.number()),
257
+ duration: v.optional(v.number()),
258
+ altText: v.optional(v.string()),
259
+ createdBy: v.optional(v.string()),
260
+ });
261
+
262
+ /**
263
+ * Args for updating a media asset - all fields optional except id.
264
+ * Cannot change: storageId, mimeType (immutable properties)
265
+ */
266
+ export const updateMediaAssetArgs = v.object({
267
+ id: v.id("mediaItems"),
268
+ name: v.optional(v.string()),
269
+ title: v.optional(v.string()),
270
+ description: v.optional(v.string()),
271
+ parentId: v.optional(v.id("mediaItems")),
272
+ tags: v.optional(v.array(v.string())),
273
+ metadata: v.optional(v.record(v.string(), v.any())),
274
+ width: v.optional(v.number()),
275
+ height: v.optional(v.number()),
276
+ duration: v.optional(v.number()),
277
+ altText: v.optional(v.string()),
278
+ updatedBy: v.optional(v.string()),
279
+ });
280
+
281
+ export const deleteMediaAssetArgs = v.object({
282
+ id: v.id("mediaItems"),
283
+ deletedBy: v.optional(v.string()),
284
+ hardDelete: v.optional(v.boolean()),
285
+ forceDelete: v.optional(v.boolean()),
286
+ });
287
+
288
+ export const restoreMediaAssetArgs = v.object({
289
+ id: v.id("mediaItems"),
290
+ restoredBy: v.optional(v.string()),
291
+ });
292
+
293
+ // =============================================================================
294
+ // Media Folder Validators
295
+ // =============================================================================
296
+
297
+ /**
298
+ * Args for creating a media folder.
299
+ * Required: name
300
+ * Optional: title, description, parentId, etc.
301
+ */
302
+ export const createMediaFolderArgs = v.object({
303
+ name: v.string(),
304
+ title: v.optional(v.string()),
305
+ description: v.optional(v.string()),
306
+ parentId: v.optional(v.id("mediaItems")),
307
+ tags: v.optional(v.array(v.string())),
308
+ metadata: v.optional(v.record(v.string(), v.any())),
309
+ sortOrder: v.optional(v.number()),
310
+ createdBy: v.optional(v.string()),
311
+ });
312
+
313
+ /**
314
+ * Args for updating a media folder - all fields optional except id.
315
+ */
316
+ export const updateMediaFolderArgs = v.object({
317
+ id: v.id("mediaItems"),
318
+ name: v.optional(v.string()),
319
+ title: v.optional(v.string()),
320
+ description: v.optional(v.string()),
321
+ parentId: v.optional(v.id("mediaItems")),
322
+ tags: v.optional(v.array(v.string())),
323
+ metadata: v.optional(v.record(v.string(), v.any())),
324
+ sortOrder: v.optional(v.number()),
325
+ updatedBy: v.optional(v.string()),
326
+ });
327
+
328
+ export const moveFolderArgs = v.object({
329
+ id: v.id("mediaItems"),
330
+ newParentId: v.optional(v.id("mediaItems")),
331
+ updatedBy: v.optional(v.string()),
332
+ });
333
+
334
+ export const deleteMediaFolderArgs = v.object({
335
+ id: v.id("mediaItems"),
336
+ deletedBy: v.optional(v.string()),
337
+ hardDelete: v.optional(v.boolean()),
338
+ recursive: v.optional(v.boolean()),
339
+ });
340
+
341
+ export const restoreMediaFolderArgs = v.object({
342
+ id: v.id("mediaItems"),
343
+ restoredBy: v.optional(v.string()),
344
+ recursive: v.optional(v.boolean()),
345
+ });
346
+
347
+ export const moveMediaAssetsArgs = v.object({
348
+ assetIds: v.array(v.id("mediaItems")),
349
+ targetFolderId: v.optional(v.id("mediaItems")),
350
+ movedBy: v.optional(v.string()),
351
+ });
352
+
353
+ export const moveMediaAssetItemResult = v.object({
354
+ id: v.id("mediaItems"),
355
+ success: v.boolean(),
356
+ error: v.optional(v.string()),
357
+ previousFolderId: v.optional(v.id("mediaItems")),
358
+ });
359
+
360
+ export const moveMediaAssetsResult = v.object({
361
+ total: v.number(),
362
+ succeeded: v.number(),
363
+ failed: v.number(),
364
+ targetFolderId: v.optional(v.id("mediaItems")),
365
+ targetFolderPath: v.optional(v.string()),
366
+ results: v.array(moveMediaAssetItemResult),
367
+ });
368
+
369
+ // =============================================================================
370
+ // Media Variant Validators
371
+ // =============================================================================
372
+
373
+ export const createMediaVariantArgs = v.object({
374
+ assetId: v.id("mediaItems"),
375
+ storageId: v.id("_storage"),
376
+ variantType: variantTypeValidator,
377
+ width: v.optional(v.number()),
378
+ height: v.optional(v.number()),
379
+ format: v.string(),
380
+ mimeType: v.string(),
381
+ size: v.number(),
382
+ quality: v.optional(v.number()),
383
+ preset: v.optional(v.string()),
384
+ autoGenerated: v.optional(v.boolean()),
385
+ createdBy: v.optional(v.string()),
386
+ });
387
+
388
+ export const requestVariantGenerationArgs = v.object({
389
+ assetId: v.id("mediaItems"),
390
+ variantType: variantTypeValidator,
391
+ width: v.optional(v.number()),
392
+ height: v.optional(v.number()),
393
+ format: v.string(),
394
+ quality: v.optional(v.number()),
395
+ preset: v.optional(v.string()),
396
+ requestedBy: v.optional(v.string()),
397
+ });
398
+
399
+ export const updateVariantStatusArgs = v.object({
400
+ id: v.id("mediaVariants"),
401
+ status: variantStatusValidator,
402
+ storageId: v.optional(v.id("_storage")),
403
+ size: v.optional(v.number()),
404
+ mimeType: v.optional(v.string()),
405
+ width: v.optional(v.number()),
406
+ height: v.optional(v.number()),
407
+ errorMessage: v.optional(v.string()),
408
+ });
409
+
410
+ export const deleteMediaVariantArgs = v.object({
411
+ id: v.id("mediaVariants"),
412
+ hardDelete: v.optional(v.boolean()),
413
+ deletedBy: v.optional(v.string()),
414
+ });
415
+
416
+ export const deleteAssetVariantsArgs = v.object({
417
+ assetId: v.id("mediaItems"),
418
+ hardDelete: v.optional(v.boolean()),
419
+ deletedBy: v.optional(v.string()),
420
+ });
421
+
422
+ export const getMediaVariantArgs = v.object({
423
+ id: v.id("mediaVariants"),
424
+ includeDeleted: v.optional(v.boolean()),
425
+ });
426
+
427
+ export const listMediaVariantsArgs = v.object({
428
+ assetId: v.id("mediaItems"),
429
+ variantType: v.optional(variantTypeValidator),
430
+ format: v.optional(v.string()),
431
+ preset: v.optional(v.string()),
432
+ status: v.optional(variantStatusValidator),
433
+ includeDeleted: v.optional(v.boolean()),
434
+ });
435
+
436
+ export const getBestVariantArgs = v.object({
437
+ assetId: v.id("mediaItems"),
438
+ targetWidth: v.optional(v.number()),
439
+ targetHeight: v.optional(v.number()),
440
+ preferredFormat: v.optional(v.string()),
441
+ fallbackToOriginal: v.optional(v.boolean()),
442
+ });
443
+
444
+ export const mediaVariantDoc = doc(schema, "mediaVariants");
445
+
446
+ export const mediaVariantWithUrlDoc = v.object({
447
+ ...mediaVariantDoc.fields,
448
+ url: v.union(v.string(), v.null()),
449
+ });
450
+
451
+ export const variantPresetValidator = v.object({
452
+ name: v.string(),
453
+ variantType: variantTypeValidator,
454
+ width: v.optional(v.number()),
455
+ height: v.optional(v.number()),
456
+ format: v.string(),
457
+ quality: v.optional(v.number()),
458
+ description: v.optional(v.string()),
459
+ });
460
+
461
+ export const generateVariantsResult = v.object({
462
+ total: v.number(),
463
+ succeeded: v.number(),
464
+ failed: v.number(),
465
+ results: v.array(
466
+ v.object({
467
+ preset: v.string(),
468
+ success: v.boolean(),
469
+ variantId: v.optional(v.id("mediaVariants")),
470
+ error: v.optional(v.string()),
471
+ }),
472
+ ),
473
+ });
474
+
475
+ export const srcsetEntryValidator = v.object({
476
+ url: v.string(),
477
+ descriptor: v.string(),
478
+ width: v.number(),
479
+ format: v.string(),
480
+ });
481
+
482
+ export const responsiveSrcsetResult = v.object({
483
+ src: v.union(v.string(), v.null()),
484
+ srcset: v.string(),
485
+ entries: v.array(srcsetEntryValidator),
486
+ sizes: v.optional(v.string()),
487
+ });
488
+
489
+ // =============================================================================
490
+ // Query/Pagination Validators
491
+ // =============================================================================
492
+
493
+ export const paginationResultValidator = <T extends Validator<unknown, "required", string>>(itemValidator: T) =>
494
+ v.object({
495
+ page: v.array(itemValidator),
496
+ continueCursor: v.union(v.string(), v.null()),
497
+ isDone: v.boolean(),
498
+ });
499
+
500
+ export const contentQueryArgs = v.object({
501
+ contentTypeId: v.optional(v.id("contentTypes")),
502
+ contentTypeName: v.optional(v.string()),
503
+ status: v.optional(contentStatusValidator),
504
+ statusIn: v.optional(v.array(contentStatusValidator)),
505
+ locale: v.optional(v.string()),
506
+ search: v.optional(v.string()),
507
+ includeDeleted: v.optional(v.boolean()),
508
+ cursor: v.optional(v.string()),
509
+ limit: v.optional(v.number()),
510
+ });
511
+
512
+ export const mediaQueryArgs = v.object({
513
+ folderId: v.optional(v.id("mediaItems")),
514
+ type: v.optional(mediaTypeValidator),
515
+ mimeType: v.optional(v.string()),
516
+ search: v.optional(v.string()),
517
+ tags: v.optional(v.array(v.string())),
518
+ includeDeleted: v.optional(v.boolean()),
519
+ cursor: v.optional(v.string()),
520
+ limit: v.optional(v.number()),
521
+ });
522
+
523
+ export const mediaSortDirectionValidator = v.union(
524
+ v.literal("asc"),
525
+ v.literal("desc"),
526
+ );
527
+
528
+ export const mediaSortFieldValidator = v.union(
529
+ v.literal("_creationTime"),
530
+ v.literal("filename"),
531
+ v.literal("size"),
532
+ v.literal("type"),
533
+ v.literal("mimeType"),
534
+ );
535
+
536
+ export const listMediaAssetsArgs = v.object({
537
+ folderId: v.optional(v.id("mediaItems")),
538
+ includeRootLevel: v.optional(v.boolean()),
539
+ type: v.optional(mediaTypeValidator),
540
+ mimeType: v.optional(v.string()),
541
+ mimeTypePrefix: v.optional(v.string()),
542
+ search: v.optional(v.string()),
543
+ tags: v.optional(v.array(v.string())),
544
+ includeDeleted: v.optional(v.boolean()),
545
+ deletedOnly: v.optional(v.boolean()),
546
+ sortField: v.optional(mediaSortFieldValidator),
547
+ sortDirection: v.optional(mediaSortDirectionValidator),
548
+ paginationOpts: paginationOptsValidator,
549
+ });
550
+
551
+ // =============================================================================
552
+ // Document Validators (for return types)
553
+ // =============================================================================
554
+
555
+ export const contentTypeDoc = doc(schema, "contentTypes");
556
+ export const contentEntryDoc = doc(schema, "contentEntries");
557
+ export const contentVersionDoc = doc(schema, "contentVersions");
558
+ export const mediaItemDoc = doc(schema, "mediaItems");
559
+
560
+ // Re-export schema validators for media items
561
+ export {
562
+ mediaAssetItemValidator,
563
+ mediaFolderItemValidator,
564
+ mediaItemValidator,
565
+ } from "./schema.js";
566
+
567
+ export const taxonomyDoc = doc(schema, "taxonomies");
568
+ export const taxonomyTermDoc = doc(schema, "taxonomyTerms");
569
+ export const contentEntryTagDoc = doc(schema, "contentEntryTags");
570
+ export const webhookConfigDoc = doc(schema, "webhookConfigs");
571
+ export const webhookDeliveryDoc = doc(schema, "webhookDeliveries");
572
+
573
+ export const mediaAssetReference = v.object({
574
+ entryId: v.id("contentEntries"),
575
+ slug: v.string(),
576
+ contentTypeName: v.string(),
577
+ fields: v.array(v.string()),
578
+ });
579
+
580
+ // =============================================================================
581
+ // Bulk Operation Validators
582
+ // =============================================================================
583
+
584
+ /**
585
+ * Maximum number of entries that can be processed in a single bulk operation.
586
+ * Respects Convex transaction limits (16,000 documents written max).
587
+ */
588
+ export const BULK_OPERATION_BATCH_SIZE = 100;
589
+
590
+ export const bulkPublishArgs = v.object({
591
+ ids: v.array(v.id("contentEntries")),
592
+ changeDescription: v.optional(v.string()),
593
+ updatedBy: v.optional(v.string()),
594
+ });
595
+
596
+ export const bulkUnpublishArgs = v.object({
597
+ ids: v.array(v.id("contentEntries")),
598
+ updatedBy: v.optional(v.string()),
599
+ });
600
+
601
+ export const bulkDeleteArgs = v.object({
602
+ ids: v.array(v.id("contentEntries")),
603
+ deletedBy: v.optional(v.string()),
604
+ hardDelete: v.optional(v.boolean()),
605
+ });
606
+
607
+ export const bulkUpdateArgs = v.object({
608
+ ids: v.array(v.id("contentEntries")),
609
+ data: v.optional(v.any()),
610
+ status: v.optional(contentStatusValidator),
611
+ updatedBy: v.optional(v.string()),
612
+ });
613
+
614
+ export const bulkOperationItemResult = v.object({
615
+ id: v.id("contentEntries"),
616
+ success: v.boolean(),
617
+ error: v.optional(v.string()),
618
+ });
619
+
620
+ export const bulkOperationResult = v.object({
621
+ total: v.number(),
622
+ succeeded: v.number(),
623
+ failed: v.number(),
624
+ results: v.array(bulkOperationItemResult),
625
+ });
626
+
627
+ // =============================================================================
628
+ // Trash Operation Validators
629
+ // =============================================================================
630
+
631
+ /** Default retention period in days for soft-deleted items. */
632
+ export const DEFAULT_TRASH_RETENTION_DAYS = 30;
633
+
634
+ export const trashConfigDoc = doc(schema, "trashConfig");
635
+
636
+ export const updateTrashConfigArgs = v.object({
637
+ retentionDays: v.optional(v.number()),
638
+ autoCleanupEnabled: v.optional(v.boolean()),
639
+ updatedBy: v.optional(v.string()),
640
+ });
641
+
642
+ export const listTrashArgs = v.object({
643
+ contentTypeId: v.optional(v.id("contentTypes")),
644
+ contentTypeName: v.optional(v.string()),
645
+ search: v.optional(v.string()),
646
+ paginationOpts: paginationOptsValidator,
647
+ });
648
+
649
+ export const emptyTrashArgs = v.object({
650
+ olderThanDays: v.optional(v.number()),
651
+ contentTypeId: v.optional(v.id("contentTypes")),
652
+ deletedBy: v.optional(v.string()),
653
+ });
654
+
655
+ export const emptyTrashResult = v.object({
656
+ deletedCount: v.number(),
657
+ deletedVersionsCount: v.number(),
658
+ errors: v.array(
659
+ v.object({
660
+ id: v.id("contentEntries"),
661
+ error: v.string(),
662
+ }),
663
+ ),
664
+ });
665
+
666
+ export const trashItemDoc = v.object({
667
+ ...contentEntryDoc.fields,
668
+ deletedDaysAgo: v.number(),
669
+ expiresAt: v.optional(v.number()),
670
+ contentTypeName: v.optional(v.string()),
671
+ });
672
+
673
+ // =============================================================================
674
+ // Content Lock Validators
675
+ // =============================================================================
676
+
677
+ /** Default lock duration in milliseconds (30 minutes). */
678
+ export const DEFAULT_LOCK_DURATION_MS = 30 * 60 * 1000;
679
+
680
+ /** Maximum lock duration in milliseconds (4 hours). */
681
+ export const MAX_LOCK_DURATION_MS = 4 * 60 * 60 * 1000;
682
+
683
+ export const acquireLockArgs = v.object({
684
+ id: v.id("contentEntries"),
685
+ userId: v.string(),
686
+ lockDuration: v.optional(v.number()),
687
+ });
688
+
689
+ export const releaseLockArgs = v.object({
690
+ id: v.id("contentEntries"),
691
+ userId: v.string(),
692
+ });
693
+
694
+ export const forceReleaseLockArgs = v.object({
695
+ id: v.id("contentEntries"),
696
+ releasedBy: v.string(),
697
+ });
698
+
699
+ export const renewLockArgs = v.object({
700
+ id: v.id("contentEntries"),
701
+ userId: v.string(),
702
+ lockDuration: v.optional(v.number()),
703
+ });
704
+
705
+ export const checkLockArgs = v.object({
706
+ id: v.id("contentEntries"),
707
+ });
708
+
709
+ export const listLockedEntriesArgs = v.object({
710
+ contentTypeId: v.optional(v.id("contentTypes")),
711
+ lockedBy: v.optional(v.string()),
712
+ paginationOpts: paginationOptsValidator,
713
+ });
714
+
715
+ export const lockStatusDoc = v.object({
716
+ isLocked: v.boolean(),
717
+ lockedBy: v.optional(v.string()),
718
+ lockExpiresAt: v.optional(v.number()),
719
+ timeRemaining: v.optional(v.number()),
720
+ isExpired: v.optional(v.boolean()),
721
+ });
722
+
723
+ export const lockAcquisitionResult = v.object({
724
+ success: v.boolean(),
725
+ entry: v.optional(contentEntryDoc),
726
+ error: v.optional(v.string()),
727
+ currentLockHolder: v.optional(v.string()),
728
+ currentLockExpiresAt: v.optional(v.number()),
729
+ });
730
+
731
+ // =============================================================================
732
+ // CMS Event Validators
733
+ // =============================================================================
734
+
735
+ export const eventResourceTypes = [
736
+ "contentEntry",
737
+ "contentType",
738
+ "mediaAsset",
739
+ "mediaFolder",
740
+ ] as const;
741
+
742
+ export type EventResourceType = typeof eventResourceTypes[number];
743
+
744
+ export const eventActions = [
745
+ "created",
746
+ "updated",
747
+ "published",
748
+ "unpublished",
749
+ "deleted",
750
+ "restored",
751
+ "duplicated",
752
+ "scheduled",
753
+ ] as const;
754
+
755
+ export type EventAction = typeof eventActions[number];
756
+
757
+ export const eventResourceTypeValidator = v.union(
758
+ v.literal("contentEntry"),
759
+ v.literal("contentType"),
760
+ v.literal("mediaAsset"),
761
+ v.literal("mediaFolder"),
762
+ );
763
+
764
+ export const eventActionValidator = v.union(
765
+ v.literal("created"),
766
+ v.literal("updated"),
767
+ v.literal("published"),
768
+ v.literal("unpublished"),
769
+ v.literal("deleted"),
770
+ v.literal("restored"),
771
+ v.literal("duplicated"),
772
+ v.literal("scheduled"),
773
+ );
774
+
775
+ export const cmsEventDoc = doc(schema, "cmsEvents");
776
+
777
+ export const listEventsArgs = v.object({
778
+ resourceType: v.optional(eventResourceTypeValidator),
779
+ action: v.optional(eventActionValidator),
780
+ processed: v.optional(v.boolean()),
781
+ limit: v.optional(v.number()),
782
+ cursor: v.optional(v.string()),
783
+ });
784
+
785
+ export const getResourceEventsArgs = v.object({
786
+ resourceType: eventResourceTypeValidator,
787
+ resourceId: v.string(),
788
+ limit: v.optional(v.number()),
789
+ });
790
+
791
+ export const markEventsProcessedArgs = v.object({
792
+ eventIds: v.array(v.id("cmsEvents")),
793
+ });
794
+
795
+ export const cleanupEventsArgs = v.object({
796
+ retentionDays: v.optional(v.number()),
797
+ });
798
+
799
+ // =============================================================================
800
+ // Mutation Authorization Context
801
+ // =============================================================================
802
+
803
+ /**
804
+ * Validator for mutation-level authorization context.
805
+ * Enables defense-in-depth: client wrapper performs auth checks AND mutations
806
+ * can validate auth when context is provided.
807
+ */
808
+ export const mutationAuthContext = v.object({
809
+ userId: v.string(),
810
+ role: v.union(v.string(), v.null()),
811
+ resourceOwnerId: v.optional(v.string()),
812
+ });
813
+
814
+ export type MutationAuthContext = {
815
+ userId: string;
816
+ role: string | null;
817
+ resourceOwnerId?: string;
818
+ };
819
+
820
+ // Export the schema for reference
821
+ export { schema };
822
+
823
+ // =============================================================================
824
+ // Inferred Types (derived from validators using Infer<>)
825
+ // =============================================================================
826
+ // These types are automatically derived from validators and should be used
827
+ // instead of manually declaring interfaces. This ensures types stay in sync.
828
+
829
+ // Core types from schema validators
830
+ export type FieldType = Infer<typeof fieldTypeValidator>;
831
+ export type FieldDefinition = Infer<typeof fieldDefinitionValidator>;
832
+ export type ContentStatus = Infer<typeof contentStatusValidator>;
833
+ export type MediaType = Infer<typeof mediaTypeValidator>;
834
+ export type VariantType = Infer<typeof variantTypeValidator>;
835
+ export type VariantStatus = Infer<typeof variantStatusValidator>;
836
+
837
+ // Document types (full documents with _id and _creationTime)
838
+ export type ContentTypeDoc = Infer<typeof contentTypeDoc>;
839
+ export type ContentEntryDoc = Infer<typeof contentEntryDoc>;
840
+ export type ContentVersionDoc = Infer<typeof contentVersionDoc>;
841
+ export type MediaItemDoc = Infer<typeof mediaItemDoc>;
842
+ export type MediaVariantDoc = Infer<typeof mediaVariantDoc>;
843
+ export type TaxonomyDoc = Infer<typeof taxonomyDoc>;
844
+ export type TaxonomyTermDoc = Infer<typeof taxonomyTermDoc>;
845
+ export type ContentEntryTagDoc = Infer<typeof contentEntryTagDoc>;
846
+ export type WebhookConfigDoc = Infer<typeof webhookConfigDoc>;
847
+ export type WebhookDeliveryDoc = Infer<typeof webhookDeliveryDoc>;
848
+ export type CmsEventDoc = Infer<typeof cmsEventDoc>;
849
+ export type TrashConfigDoc = Infer<typeof trashConfigDoc>;
850
+
851
+ // Media item types
852
+ export type MediaAssetItem = Infer<typeof mediaAssetItemValidator>;
853
+ export type MediaFolderItem = Infer<typeof mediaFolderItemValidator>;
854
+ export type MediaItem = Infer<typeof mediaItemValidator>;
855
+
856
+ // Content Type mutation args
857
+ export type CreateContentTypeArgs = Infer<typeof createContentTypeArgs>;
858
+ export type UpdateContentTypeArgs = Infer<typeof updateContentTypeArgs>;
859
+ export type DeleteContentTypeArgs = Infer<typeof deleteContentTypeArgs>;
860
+
861
+ // Content Entry mutation args
862
+ export type CreateContentEntryArgs = Infer<typeof createContentEntryArgs>;
863
+ export type UpdateContentEntryArgs = Infer<typeof updateContentEntryArgs>;
864
+ export type DeleteContentEntryArgs = Infer<typeof deleteContentEntryArgs>;
865
+ export type PublishEntryArgs = Infer<typeof publishEntryArgs>;
866
+ export type UnpublishEntryArgs = Infer<typeof unpublishEntryArgs>;
867
+ export type ScheduleEntryArgs = Infer<typeof scheduleEntryArgs>;
868
+ export type DuplicateContentEntryArgs = Infer<typeof duplicateContentEntryArgs>;
869
+
870
+ // Version args
871
+ export type GetVersionHistoryArgs = Infer<typeof getVersionHistoryArgs>;
872
+ export type GetVersionArgs = Infer<typeof getVersionArgs>;
873
+ export type RollbackVersionArgs = Infer<typeof rollbackVersionArgs>;
874
+ export type CreateVersionSnapshotArgs = Infer<typeof createVersionSnapshotArgs>;
875
+ export type CompareVersionsArgs = Infer<typeof compareVersionsArgs>;
876
+ export type VersionFieldDiff = Infer<typeof versionFieldDiff>;
877
+ export type CompareVersionsResult = Infer<typeof compareVersionsResult>;
878
+
879
+ // Media Asset mutation args
880
+ export type CreateMediaAssetArgs = Infer<typeof createMediaAssetArgs>;
881
+ export type UpdateMediaAssetArgs = Infer<typeof updateMediaAssetArgs>;
882
+ export type DeleteMediaAssetArgs = Infer<typeof deleteMediaAssetArgs>;
883
+ export type RestoreMediaAssetArgs = Infer<typeof restoreMediaAssetArgs>;
884
+
885
+ // Media Folder mutation args
886
+ export type CreateMediaFolderArgs = Infer<typeof createMediaFolderArgs>;
887
+ export type UpdateMediaFolderArgs = Infer<typeof updateMediaFolderArgs>;
888
+ export type DeleteMediaFolderArgs = Infer<typeof deleteMediaFolderArgs>;
889
+ export type RestoreMediaFolderArgs = Infer<typeof restoreMediaFolderArgs>;
890
+ export type MoveFolderArgs = Infer<typeof moveFolderArgs>;
891
+ export type MoveMediaAssetsArgs = Infer<typeof moveMediaAssetsArgs>;
892
+ export type MoveMediaAssetItemResult = Infer<typeof moveMediaAssetItemResult>;
893
+ export type MoveMediaAssetsResult = Infer<typeof moveMediaAssetsResult>;
894
+
895
+ // Media Variant args
896
+ export type CreateMediaVariantArgs = Infer<typeof createMediaVariantArgs>;
897
+ export type RequestVariantGenerationArgs = Infer<typeof requestVariantGenerationArgs>;
898
+ export type UpdateVariantStatusArgs = Infer<typeof updateVariantStatusArgs>;
899
+ export type DeleteMediaVariantArgs = Infer<typeof deleteMediaVariantArgs>;
900
+ export type DeleteAssetVariantsArgs = Infer<typeof deleteAssetVariantsArgs>;
901
+ export type GetMediaVariantArgs = Infer<typeof getMediaVariantArgs>;
902
+ export type ListMediaVariantsArgs = Infer<typeof listMediaVariantsArgs>;
903
+ export type GetBestVariantArgs = Infer<typeof getBestVariantArgs>;
904
+ export type MediaVariantWithUrl = Infer<typeof mediaVariantWithUrlDoc>;
905
+ export type VariantPreset = Infer<typeof variantPresetValidator>;
906
+ export type GenerateVariantsResult = Infer<typeof generateVariantsResult>;
907
+ export type SrcsetEntry = Infer<typeof srcsetEntryValidator>;
908
+ export type ResponsiveSrcsetResult = Infer<typeof responsiveSrcsetResult>;
909
+
910
+ // Query args
911
+ export type ContentQueryArgs = Infer<typeof contentQueryArgs>;
912
+ export type MediaQueryArgs = Infer<typeof mediaQueryArgs>;
913
+ export type ListMediaAssetsArgs = Infer<typeof listMediaAssetsArgs>;
914
+ export type MediaSortDirection = Infer<typeof mediaSortDirectionValidator>;
915
+ export type MediaSortField = Infer<typeof mediaSortFieldValidator>;
916
+
917
+ // Bulk operation args
918
+ export type BulkPublishArgs = Infer<typeof bulkPublishArgs>;
919
+ export type BulkUnpublishArgs = Infer<typeof bulkUnpublishArgs>;
920
+ export type BulkDeleteArgs = Infer<typeof bulkDeleteArgs>;
921
+ export type BulkUpdateArgs = Infer<typeof bulkUpdateArgs>;
922
+ export type BulkOperationItemResult = Infer<typeof bulkOperationItemResult>;
923
+ export type BulkOperationResult = Infer<typeof bulkOperationResult>;
924
+
925
+ // Trash operation args
926
+ export type UpdateTrashConfigArgs = Infer<typeof updateTrashConfigArgs>;
927
+ export type ListTrashArgs = Infer<typeof listTrashArgs>;
928
+ export type EmptyTrashArgs = Infer<typeof emptyTrashArgs>;
929
+ export type EmptyTrashResult = Infer<typeof emptyTrashResult>;
930
+ export type TrashItem = Infer<typeof trashItemDoc>;
931
+
932
+ // Lock operation args
933
+ export type AcquireLockArgs = Infer<typeof acquireLockArgs>;
934
+ export type ReleaseLockArgs = Infer<typeof releaseLockArgs>;
935
+ export type ForceReleaseLockArgs = Infer<typeof forceReleaseLockArgs>;
936
+ export type RenewLockArgs = Infer<typeof renewLockArgs>;
937
+ export type CheckLockArgs = Infer<typeof checkLockArgs>;
938
+ export type ListLockedEntriesArgs = Infer<typeof listLockedEntriesArgs>;
939
+ export type LockStatus = Infer<typeof lockStatusDoc>;
940
+ export type LockAcquisitionResult = Infer<typeof lockAcquisitionResult>;
941
+
942
+ // Event args
943
+ export type ListEventsArgs = Infer<typeof listEventsArgs>;
944
+ export type GetResourceEventsArgs = Infer<typeof getResourceEventsArgs>;
945
+ export type MarkEventsProcessedArgs = Infer<typeof markEventsProcessedArgs>;
946
+ export type CleanupEventsArgs = Infer<typeof cleanupEventsArgs>;
947
+
948
+ // Media asset reference
949
+ export type MediaAssetReference = Infer<typeof mediaAssetReference>;