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,1301 @@
1
+ /**
2
+ * @convex-cms/core
3
+ *
4
+ * A developer-first Convex Component for content management with
5
+ * flexible RBAC and AI-ready architecture.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // Install the component in convex/convex.config.ts
10
+ * import { defineApp } from "convex/server";
11
+ * import convexCms from "@convex-cms/core/convex.config";
12
+ *
13
+ * const app = defineApp();
14
+ * app.use(convexCms);
15
+ * export default app;
16
+ * ```
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // Create a configured CMS client with typed methods and RBAC
21
+ * import { createCmsClient } from "@convex-cms/core";
22
+ * import { components } from "./_generated/api";
23
+ *
24
+ * export const cms = createCmsClient(components.convexCms, {
25
+ * defaultLocale: "en-US",
26
+ * features: {
27
+ * versioning: true,
28
+ * localization: true,
29
+ * },
30
+ * // Map user IDs to CMS roles for access control
31
+ * getUserRole: async ({ userId }) => {
32
+ * const user = await db.query("users")
33
+ * .filter(q => q.eq(q.field("_id"), userId))
34
+ * .first();
35
+ * return user?.cmsRole ?? null; // "admin" | "editor" | "author" | "viewer"
36
+ * },
37
+ * });
38
+ * ```
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * // Use typed methods in your functions
43
+ * import { mutation } from "./_generated/server";
44
+ * import { cms } from "./cms";
45
+ *
46
+ * export const createBlogPost = mutation({
47
+ * args: { title: v.string(), content: v.string() },
48
+ * handler: async (ctx, args) => {
49
+ * // Type-safe API with full autocompletion
50
+ * return await cms.contentEntries.create(ctx, {
51
+ * contentTypeId: "blog_type_id",
52
+ * data: { title: args.title, content: args.content },
53
+ * });
54
+ * },
55
+ * });
56
+ * ```
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * // Check user permissions before performing actions
61
+ * import { mutation } from "./_generated/server";
62
+ * import { cms } from "./cms";
63
+ *
64
+ * export const publishPost = mutation({
65
+ * args: { entryId: v.id("contentEntries"), userId: v.string() },
66
+ * handler: async (ctx, args) => {
67
+ * // Check if user can publish content
68
+ * const result = await cms.hasPermissionForUser(args.userId, {
69
+ * resource: "contentEntries",
70
+ * action: "publish",
71
+ * });
72
+ *
73
+ * if (!result.allowed) {
74
+ * throw new Error(`User with role '${result.role}' cannot publish content`);
75
+ * }
76
+ *
77
+ * return await cms.contentEntries.publish(ctx, { id: args.entryId });
78
+ * },
79
+ * });
80
+ * ```
81
+ */
82
+
83
+ // Export types for external use
84
+ export * from "./types.js";
85
+
86
+ // --- Admin API Helper ---
87
+ export {
88
+ defineAdminAPI,
89
+ type AdminApiOptions,
90
+ type AdminOperation,
91
+ } from "./adminApi.js";
92
+
93
+ // --- CMS Client Factory ---
94
+ import {
95
+ type ComponentConfig,
96
+ type FeatureFlags,
97
+ type LocaleCode,
98
+ type GetUserRoleResult,
99
+ type AuthorizationHookContext,
100
+ resolveConfig,
101
+ validateRequiredHooks,
102
+ } from "./types.js";
103
+
104
+ import {
105
+ type TypedComponentApi,
106
+ type CmsClient,
107
+ type ConvexContext,
108
+ type PermissionCheckOptions,
109
+ type UserPermissionResult,
110
+ type ResourcePermissionResult,
111
+ type ResourcePermissionGranted,
112
+ ContentTypesApi,
113
+ ContentEntriesApi,
114
+ VersionsApi,
115
+ MediaAssetsApi,
116
+ MediaFoldersApi,
117
+ MediaVariantsApi,
118
+ } from "./wrapper.js";
119
+
120
+ // Re-export authorization hooks execution utilities
121
+ export {
122
+ executeAuthorizationHooks,
123
+ operationToRbac,
124
+ contextToRbacOptions,
125
+ createContentEntryAuthContext,
126
+ requireAuthorization as requireAuthorizationHook,
127
+ type ExecuteAuthorizationOptions,
128
+ type AuthorizationResult,
129
+ } from "../component/authorizationHooks.js";
130
+
131
+ // Re-export core authorization and ownership utilities
132
+ export {
133
+ // Error class
134
+ UnauthorizedError,
135
+ type AuthorizationErrorCode,
136
+
137
+ // Core permission checking
138
+ checkPermission,
139
+ requirePermission,
140
+ type PermissionCheckOptions as CorePermissionCheckOptions,
141
+ type PermissionGranted,
142
+ type PermissionDenied,
143
+ type PermissionCheckResult,
144
+
145
+ // Ownership validation helpers
146
+ isResourceOwner,
147
+ requireResourceOwnership,
148
+
149
+ // Authorization context helpers
150
+ createAuthContext,
151
+ canPerform,
152
+ mustPerform,
153
+ type AuthorizationContext,
154
+ } from "../component/authorization.js";
155
+
156
+ // Re-export user context handler utilities
157
+ export {
158
+ // Types
159
+ type UserContextInput,
160
+ type UserContext,
161
+ type CreateUserContextOptions,
162
+ type UserContextValidationError,
163
+ type UserContextValidationResult,
164
+
165
+ // Error class
166
+ UserContextError,
167
+
168
+ // Validation functions
169
+ isValidUserId,
170
+ isValidRole,
171
+ validateUserContextInput,
172
+
173
+ // User context creation
174
+ resolveUserRole,
175
+ createUserContext,
176
+ createUserContextSync,
177
+
178
+ // User ID extraction
179
+ extractUserId,
180
+ extractUserIdFromAuth,
181
+
182
+ // Authorization context builders
183
+ buildAuthorizationContext,
184
+ createAnonymousContext,
185
+ createSystemContext,
186
+
187
+ // Utility functions
188
+ isAuthenticated,
189
+ hasUserRole,
190
+ isSystemContext,
191
+ getUserDisplayId,
192
+ validateUserContext,
193
+ } from "../component/userContext.js";
194
+
195
+ // Re-export resource permission types from wrapper
196
+ export type {
197
+ ResourcePermissionResult,
198
+ ResourcePermissionGranted,
199
+ } from "./wrapper.js";
200
+
201
+ import {
202
+ executeAuthorizationHooks,
203
+ operationToRbac,
204
+ contextToRbacOptions,
205
+ type AuthorizationResult,
206
+ } from "../component/authorizationHooks.js";
207
+ import { UnauthorizedError as InternalUnauthorizedError } from "../component/authorization.js";
208
+ import type { AuthorizationHelper } from "./wrapper.js";
209
+ import type { AuthorizationHookContext as InternalAuthHookContext } from "./types.js";
210
+
211
+ import {
212
+ hasPermission,
213
+ hasContentTypePermission,
214
+ getPermittedContentTypes,
215
+ DEFAULT_ROLES,
216
+ type Resource,
217
+ type Action,
218
+ type OwnershipScope,
219
+ } from "../component/roles.js";
220
+
221
+ // Import locale fallback chain utilities
222
+ import {
223
+ resolveFallbackChain,
224
+ getFallbackChain,
225
+ type LocaleFallbackConfig,
226
+ type ResolvedFallbackChain,
227
+ } from "../component/localeFallbackChain.js";
228
+
229
+ // Re-export wrapper types and classes
230
+ export * from "./wrapper.js";
231
+
232
+ // Re-export query builder types and classes
233
+ export {
234
+ ContentQueryBuilder,
235
+ createQueryBuilder,
236
+ type SortDirection,
237
+ type SortableField,
238
+ type QueryBuilderResult,
239
+ } from "./queryBuilder.js";
240
+
241
+ /**
242
+ * Creates an enhanced CMS client with typed method wrappers.
243
+ *
244
+ * This is the main entry point for using the Convex CMS component.
245
+ * The returned client provides typed methods for all CMS operations,
246
+ * making it easy to interact with the CMS from your Convex functions.
247
+ *
248
+ * @param componentApi - The component API from `components.convexCms`
249
+ * @param config - Optional configuration options
250
+ * @returns An enhanced CMS client instance with typed methods
251
+ *
252
+ * @example
253
+ * ```typescript
254
+ * import { createCmsClient } from "@convex-cms/core";
255
+ * import { components } from "./_generated/api";
256
+ *
257
+ * // Create with default configuration
258
+ * export const cms = createCmsClient(components.convexCms);
259
+ *
260
+ * // Create with custom configuration
261
+ * export const cms = createCmsClient(components.convexCms, {
262
+ * defaultLocale: "en-US",
263
+ * supportedLocales: ["en-US", "es-ES", "fr-FR"],
264
+ * features: {
265
+ * versioning: true,
266
+ * localization: true,
267
+ * scheduling: true,
268
+ * },
269
+ * maxVersionsPerEntry: 100,
270
+ * });
271
+ * ```
272
+ *
273
+ * @example
274
+ * ```typescript
275
+ * // Use typed methods in mutations
276
+ * export const createPost = mutation({
277
+ * args: { title: v.string() },
278
+ * handler: async (ctx, args) => {
279
+ * // Create a content type
280
+ * const blogType = await cms.contentTypes.create(ctx, {
281
+ * name: "blog_post",
282
+ * displayName: "Blog Post",
283
+ * fields: [
284
+ * { name: "title", label: "Title", type: "text", required: true },
285
+ * ],
286
+ * });
287
+ *
288
+ * // Create an entry
289
+ * const entry = await cms.contentEntries.create(ctx, {
290
+ * contentTypeId: blogType._id,
291
+ * data: { title: args.title },
292
+ * });
293
+ *
294
+ * // Publish the entry
295
+ * return await cms.contentEntries.publish(ctx, { id: entry._id });
296
+ * },
297
+ * });
298
+ * ```
299
+ *
300
+ * @example
301
+ * ```typescript
302
+ * // Check feature flags
303
+ * if (cms.isFeatureEnabled("localization")) {
304
+ * // Handle localized content
305
+ * }
306
+ *
307
+ * if (cms.isLocaleSupported("es-ES")) {
308
+ * // Locale is valid
309
+ * }
310
+ * ```
311
+ */
312
+ export function createCmsClient(
313
+ componentApi: TypedComponentApi,
314
+ config?: ComponentConfig
315
+ ): CmsClient {
316
+ // Validate required hooks at initialization time (fail-fast)
317
+ validateRequiredHooks(config);
318
+
319
+ // Register custom field types if provided
320
+ if (config?.fieldTypes && config.fieldTypes.length > 0) {
321
+ const { registerFieldTypes } = require("./field-types.js");
322
+ registerFieldTypes(config.fieldTypes);
323
+ }
324
+
325
+ const resolvedConfig = resolveConfig(config);
326
+ // Store the getUserRole hook from the original config (not resolved)
327
+ const getUserRoleHook = config?.getUserRole;
328
+ // Store authorization hooks from config
329
+ const authHooks = config?.authorizationHooks;
330
+
331
+ // Create authorization helper for API classes (only if getUserRole is configured)
332
+ const authHelper: AuthorizationHelper | undefined = getUserRoleHook
333
+ ? {
334
+ async getUserRole(ctx: ConvexContext, userId: string): Promise<string | null> {
335
+ // Pass ctx to the hook so it can access parent app's database and auth
336
+ return getUserRoleHook(ctx as unknown as import("./types.js").CmsHookContext, { userId });
337
+ },
338
+ async requireAuthorization(
339
+ ctx: ConvexContext,
340
+ context: Omit<InternalAuthHookContext, 'ctx'>
341
+ ): Promise<AuthorizationResult> {
342
+ // Augment the context with ctx for hooks to access
343
+ const fullContext: InternalAuthHookContext = {
344
+ ...context,
345
+ ctx: ctx as unknown as import("./types.js").CmsHookContext,
346
+ };
347
+
348
+ const rbacOptions = contextToRbacOptions(fullContext);
349
+
350
+ const result = await executeAuthorizationHooks({
351
+ hooks: authHooks,
352
+ context: fullContext,
353
+ rbacOptions: rbacOptions ?? undefined,
354
+ skipRbac: resolvedConfig.skipRbac,
355
+ });
356
+
357
+ if (!result.allowed) {
358
+ const rbacMapping = operationToRbac(fullContext.operation);
359
+
360
+ throw new InternalUnauthorizedError(
361
+ result.reason ?? "Operation not allowed",
362
+ {
363
+ code:
364
+ result.rbacResult?.allowed === false
365
+ ? result.rbacResult.code
366
+ : "PERMISSION_DENIED",
367
+ resource: rbacMapping?.resource,
368
+ action: rbacMapping?.action,
369
+ role: fullContext.role ?? undefined,
370
+ userId: fullContext.userId,
371
+ }
372
+ );
373
+ }
374
+
375
+ return result;
376
+ },
377
+ skipRbac: resolvedConfig.skipRbac ?? false,
378
+ }
379
+ : undefined;
380
+
381
+ return {
382
+ config: resolvedConfig,
383
+ api: componentApi,
384
+ contentTypes: new ContentTypesApi(componentApi, resolvedConfig, authHelper),
385
+ contentEntries: new ContentEntriesApi(componentApi, resolvedConfig, authHelper),
386
+ versions: new VersionsApi(componentApi, resolvedConfig, authHelper),
387
+ mediaAssets: new MediaAssetsApi(componentApi, resolvedConfig, authHelper),
388
+ mediaFolders: new MediaFoldersApi(componentApi, resolvedConfig, authHelper),
389
+ mediaVariants: new MediaVariantsApi(componentApi, resolvedConfig),
390
+
391
+ isFeatureEnabled(feature: keyof FeatureFlags): boolean {
392
+ return resolvedConfig.features[feature] ?? false;
393
+ },
394
+
395
+ isLocaleSupported(locale: LocaleCode): boolean {
396
+ return resolvedConfig.supportedLocales.includes(locale);
397
+ },
398
+
399
+ hasUserRoleHook(): boolean {
400
+ return getUserRoleHook !== undefined;
401
+ },
402
+
403
+ hasAuthorizationHooks(): boolean {
404
+ if (!authHooks) return false;
405
+ return !!(
406
+ authHooks.beforeRbac ||
407
+ authHooks.afterRbac ||
408
+ authHooks.authorize ||
409
+ authHooks.onDeny ||
410
+ (authHooks.operationHooks && Object.keys(authHooks.operationHooks).length > 0)
411
+ );
412
+ },
413
+
414
+ async getUserRole(ctx: ConvexContext, userId: string): Promise<GetUserRoleResult> {
415
+ if (!getUserRoleHook) {
416
+ throw new Error(
417
+ "No getUserRole hook configured. " +
418
+ "Configure a getUserRole function in createCmsClient options to map user IDs to CMS roles."
419
+ );
420
+ }
421
+ return await getUserRoleHook(ctx as unknown as import("./types.js").CmsHookContext, { userId });
422
+ },
423
+
424
+ async hasPermissionForUser(
425
+ ctx: ConvexContext,
426
+ userId: string,
427
+ permission: { resource: Resource; action: Action; scope?: OwnershipScope },
428
+ options?: PermissionCheckOptions
429
+ ): Promise<UserPermissionResult> {
430
+ if (!getUserRoleHook) {
431
+ throw new Error(
432
+ "No getUserRole hook configured. " +
433
+ "Configure a getUserRole function in createCmsClient options to map user IDs to CMS roles."
434
+ );
435
+ }
436
+
437
+ const role = await getUserRoleHook(ctx as unknown as import("./types.js").CmsHookContext, { userId });
438
+
439
+ // If user has no role, they have no permissions
440
+ if (role === null) {
441
+ return {
442
+ allowed: false,
443
+ role: null,
444
+ permission,
445
+ };
446
+ }
447
+
448
+ // Merge custom roles from config with any passed options
449
+ const mergedCustomRoles = {
450
+ ...resolvedConfig.customRoles,
451
+ ...options?.customRoles,
452
+ };
453
+
454
+ // Check if the role has the requested permission
455
+ const allowed = hasPermission(role, permission, mergedCustomRoles);
456
+
457
+ return {
458
+ allowed,
459
+ role,
460
+ permission,
461
+ };
462
+ },
463
+
464
+ async authorize(context: AuthorizationHookContext): Promise<any> {
465
+ // Build RBAC options from context
466
+ const rbacOptions = contextToRbacOptions(context);
467
+
468
+ return executeAuthorizationHooks({
469
+ hooks: authHooks,
470
+ context,
471
+ rbacOptions: rbacOptions ?? undefined,
472
+ skipRbac: resolvedConfig.skipRbac,
473
+ });
474
+ },
475
+
476
+ async requireAuthorization(context: AuthorizationHookContext): Promise<any> {
477
+ const result = await this.authorize(context);
478
+
479
+ if (!result.allowed) {
480
+ const rbacMapping = operationToRbac(context.operation);
481
+
482
+ throw new InternalUnauthorizedError(
483
+ result.reason ?? "Operation not allowed",
484
+ {
485
+ code: result.rbacResult?.allowed === false
486
+ ? result.rbacResult.code
487
+ : "PERMISSION_DENIED",
488
+ resource: rbacMapping?.resource,
489
+ action: rbacMapping?.action,
490
+ role: context.role ?? undefined,
491
+ userId: context.userId,
492
+ }
493
+ );
494
+ }
495
+
496
+ return result;
497
+ },
498
+
499
+ // ==========================================================================
500
+ // ==========================================================================
501
+ // Consolidated Locale API (Simplified)
502
+ // ==========================================================================
503
+
504
+ /**
505
+ * Consolidated locale API with 3 core methods.
506
+ *
507
+ * Prefer using this namespace over the individual methods below.
508
+ *
509
+ * @example
510
+ * ```typescript
511
+ * // Get locale configuration
512
+ * const config = cms.locale.getConfig();
513
+ * console.log(config.defaultLocale); // "en"
514
+ *
515
+ * // Get fallback chain for a locale
516
+ * const chain = cms.locale.getFallbackChain("es-MX");
517
+ * // ["es-ES", "en-US", "en"]
518
+ *
519
+ * // Resolve locale with full metadata
520
+ * const resolved = cms.locale.resolve("es-MX");
521
+ * // { requestedLocale: "es-MX", fallbackChain: [...], ... }
522
+ * ```
523
+ */
524
+ locale: {
525
+ /**
526
+ * Get the full locale configuration.
527
+ *
528
+ * @returns The configured locale settings including default locale,
529
+ * supported locales, and fallback chains.
530
+ */
531
+ getConfig(): LocaleFallbackConfig {
532
+ return {
533
+ defaultLocale: resolvedConfig.defaultLocale,
534
+ fallbackChains: resolvedConfig.localeFallbackChains,
535
+ autoGenerateFallbacks: resolvedConfig.autoGenerateLocaleFallbacks,
536
+ supportedLocales: resolvedConfig.supportedLocales,
537
+ };
538
+ },
539
+
540
+ /**
541
+ * Get the fallback chain for a locale.
542
+ *
543
+ * Returns an array of locale codes to try in order when content
544
+ * is not available in the requested locale.
545
+ *
546
+ * @param locale - The locale code (e.g., "es-MX")
547
+ * @returns Array of fallback locale codes
548
+ *
549
+ * @example
550
+ * ```typescript
551
+ * cms.locale.getFallbackChain("es-MX");
552
+ * // Returns: ["es-ES", "es", "en"]
553
+ * ```
554
+ */
555
+ getFallbackChain(locale: LocaleCode): LocaleCode[] {
556
+ const fallbackConfig = this.getConfig();
557
+ return getFallbackChain(locale, fallbackConfig);
558
+ },
559
+
560
+ /**
561
+ * Resolve a locale with full metadata.
562
+ *
563
+ * Returns detailed information about the locale resolution including
564
+ * the fallback chain, whether it's supported, and parsing info.
565
+ *
566
+ * @param locale - The locale code to resolve
567
+ * @returns Resolved fallback chain with metadata
568
+ *
569
+ * @example
570
+ * ```typescript
571
+ * const resolved = cms.locale.resolve("es-MX");
572
+ * // Returns: {
573
+ * // requestedLocale: "es-MX",
574
+ * // fallbackChain: ["es-MX", "es-ES", "es", "en"],
575
+ * // isSupported: true,
576
+ * // ...
577
+ * // }
578
+ * ```
579
+ */
580
+ resolve(locale: LocaleCode): ResolvedFallbackChain {
581
+ const fallbackConfig = this.getConfig();
582
+ return resolveFallbackChain(locale, fallbackConfig);
583
+ },
584
+ },
585
+
586
+ // ==========================================================================
587
+ // Custom Roles Methods
588
+ // ==========================================================================
589
+
590
+ getCustomRoles() {
591
+ return resolvedConfig.customRoles;
592
+ },
593
+
594
+ getCustomRole(roleName: string) {
595
+ return resolvedConfig.customRoles[roleName];
596
+ },
597
+
598
+ isCustomRole(roleName: string): boolean {
599
+ return roleName in resolvedConfig.customRoles;
600
+ },
601
+
602
+ async hasContentTypePermissionForUser(
603
+ ctx: ConvexContext,
604
+ userId: string,
605
+ permission: { resource: Resource; action: Action; scope?: OwnershipScope },
606
+ contentTypeName: string
607
+ ) {
608
+ if (!getUserRoleHook) {
609
+ throw new Error(
610
+ "No getUserRole hook configured. " +
611
+ "Configure a getUserRole function in createCmsClient options to map user IDs to CMS roles."
612
+ );
613
+ }
614
+
615
+ const role = await getUserRoleHook(ctx as unknown as import("./types.js").CmsHookContext, { userId });
616
+
617
+ if (role === null) {
618
+ return {
619
+ allowed: false,
620
+ role: null,
621
+ permission,
622
+ };
623
+ }
624
+
625
+ // Use the content-type-aware permission check
626
+ const allowed = hasContentTypePermission(role, permission, {
627
+ customRoles: resolvedConfig.customRoles,
628
+ contentTypeName,
629
+ });
630
+
631
+ return {
632
+ allowed,
633
+ role,
634
+ permission,
635
+ };
636
+ },
637
+
638
+ async getPermittedContentTypesForUser(ctx: ConvexContext, userId: string, action: Action) {
639
+ if (!getUserRoleHook) {
640
+ throw new Error(
641
+ "No getUserRole hook configured. " +
642
+ "Configure a getUserRole function in createCmsClient options to map user IDs to CMS roles."
643
+ );
644
+ }
645
+
646
+ const role = await getUserRoleHook(ctx as unknown as import("./types.js").CmsHookContext, { userId });
647
+
648
+ if (role === null) {
649
+ return [];
650
+ }
651
+
652
+ return getPermittedContentTypes(role, action, {
653
+ customRoles: resolvedConfig.customRoles,
654
+ });
655
+ },
656
+
657
+ getAllRoles() {
658
+ return {
659
+ ...DEFAULT_ROLES,
660
+ ...resolvedConfig.customRoles,
661
+ };
662
+ },
663
+
664
+ // ==========================================================================
665
+ // Resource Ownership Methods
666
+ // ==========================================================================
667
+
668
+ async canUserPerformOnResource(
669
+ ctx: ConvexContext,
670
+ userId: string,
671
+ resource: Resource,
672
+ action: Action,
673
+ resourceOwnerId?: string
674
+ ): Promise<ResourcePermissionResult> {
675
+ if (!getUserRoleHook) {
676
+ throw new Error(
677
+ "No getUserRole hook configured. " +
678
+ "Configure a getUserRole function in createCmsClient options to map user IDs to CMS roles."
679
+ );
680
+ }
681
+
682
+ const role = await getUserRoleHook(ctx as unknown as import("./types.js").CmsHookContext, { userId });
683
+
684
+ // If user has no role, they have no permissions
685
+ if (role === null) {
686
+ return {
687
+ allowed: false,
688
+ role: null,
689
+ reason: "No role assigned to user",
690
+ code: "NO_ROLE",
691
+ };
692
+ }
693
+
694
+ // Use the core checkPermission function for comprehensive RBAC check
695
+ const { checkPermission } = await import("../component/authorization.js");
696
+
697
+ const result = checkPermission({
698
+ userId,
699
+ role,
700
+ resource,
701
+ action,
702
+ resourceOwnerId,
703
+ customRoles: resolvedConfig.customRoles,
704
+ });
705
+
706
+ if (result.allowed) {
707
+ return {
708
+ allowed: true,
709
+ role,
710
+ grantedScope: result.grantedScope,
711
+ ownershipVerified: result.ownershipVerified,
712
+ };
713
+ } else {
714
+ return {
715
+ allowed: false,
716
+ role,
717
+ reason: result.reason,
718
+ code: result.code,
719
+ ownershipRequired: result.code === "OWNERSHIP_REQUIRED",
720
+ };
721
+ }
722
+ },
723
+
724
+ async requireUserCanPerformOnResource(
725
+ ctx: ConvexContext,
726
+ userId: string,
727
+ resource: Resource,
728
+ action: Action,
729
+ resourceOwnerId?: string
730
+ ): Promise<ResourcePermissionGranted> {
731
+ const result = await this.canUserPerformOnResource(
732
+ ctx,
733
+ userId,
734
+ resource,
735
+ action,
736
+ resourceOwnerId
737
+ );
738
+
739
+ if (!result.allowed) {
740
+ throw new InternalUnauthorizedError(
741
+ result.reason ?? "Operation not allowed",
742
+ {
743
+ code: (result.code ?? "PERMISSION_DENIED") as
744
+ | "NO_ROLE"
745
+ | "UNKNOWN_ROLE"
746
+ | "PERMISSION_DENIED"
747
+ | "OWNERSHIP_REQUIRED",
748
+ resource,
749
+ action,
750
+ role: result.role ?? undefined,
751
+ userId,
752
+ requiredScope: result.ownershipRequired ? "own" : undefined,
753
+ }
754
+ );
755
+ }
756
+
757
+ return {
758
+ allowed: true,
759
+ role: result.role!,
760
+ grantedScope: result.grantedScope!,
761
+ ownershipVerified: result.ownershipVerified ?? false,
762
+ };
763
+ },
764
+
765
+ isOwner(userId: string | undefined, resourceOwnerId: string | undefined): boolean {
766
+ if (userId === undefined || resourceOwnerId === undefined) {
767
+ return false;
768
+ }
769
+ return userId === resourceOwnerId;
770
+ },
771
+ };
772
+ }
773
+
774
+ // --- Field Validators and Validation ---
775
+ export {
776
+ fieldTypeValidator,
777
+ fieldDefinitionValidator,
778
+ contentStatusValidator,
779
+ mediaTypeValidator,
780
+ } from "../component/schema.js";
781
+
782
+ // --- Mutation Argument Validators ---
783
+ // These validators can be used in wrapper functions and custom mutations.
784
+ // Note: v.id() validators accept strings at runtime, making them work
785
+ // across the component boundary.
786
+ export {
787
+ // Content Type validators
788
+ createContentTypeArgs,
789
+ updateContentTypeArgs,
790
+ deleteContentTypeArgs,
791
+
792
+ // Content Entry validators
793
+ createContentEntryArgs,
794
+ updateContentEntryArgs,
795
+ publishEntryArgs,
796
+ scheduleEntryArgs,
797
+ unpublishEntryArgs,
798
+ deleteContentEntryArgs,
799
+ duplicateContentEntryArgs,
800
+
801
+ // Media Asset validators
802
+ createMediaAssetArgs,
803
+ updateMediaAssetArgs,
804
+ deleteMediaAssetArgs,
805
+ restoreMediaAssetArgs,
806
+ moveMediaAssetsArgs,
807
+
808
+ // Media Folder validators
809
+ createMediaFolderArgs,
810
+ updateMediaFolderArgs,
811
+ deleteMediaFolderArgs,
812
+ restoreMediaFolderArgs,
813
+ moveFolderArgs,
814
+
815
+ // Bulk Operation validators
816
+ bulkPublishArgs,
817
+ bulkUnpublishArgs,
818
+ bulkDeleteArgs,
819
+ bulkUpdateArgs,
820
+
821
+ // Version validators
822
+ getVersionHistoryArgs,
823
+ getVersionArgs,
824
+ rollbackVersionArgs,
825
+ compareVersionsArgs,
826
+ createVersionSnapshotArgs,
827
+
828
+ // Query validators
829
+ contentQueryArgs,
830
+ mediaQueryArgs,
831
+ listMediaAssetsArgs,
832
+
833
+ // Lock validators
834
+ acquireLockArgs,
835
+ releaseLockArgs,
836
+ renewLockArgs,
837
+ checkLockArgs,
838
+
839
+ // Trash validators
840
+ updateTrashConfigArgs,
841
+ listTrashArgs,
842
+ emptyTrashArgs,
843
+
844
+ // Inferred types from validators
845
+ type CreateContentTypeArgs,
846
+ type UpdateContentTypeArgs,
847
+ type DeleteContentTypeArgs,
848
+ type CreateContentEntryArgs,
849
+ type UpdateContentEntryArgs,
850
+ type DeleteContentEntryArgs,
851
+ type PublishEntryArgs,
852
+ type UnpublishEntryArgs,
853
+ type ScheduleEntryArgs,
854
+ type DuplicateContentEntryArgs,
855
+ type CreateMediaAssetArgs,
856
+ type UpdateMediaAssetArgs,
857
+ type DeleteMediaAssetArgs,
858
+ type RestoreMediaAssetArgs,
859
+ type CreateMediaFolderArgs,
860
+ type UpdateMediaFolderArgs,
861
+ type DeleteMediaFolderArgs,
862
+ type RestoreMediaFolderArgs,
863
+ type MoveFolderArgs,
864
+ type MoveMediaAssetsArgs,
865
+ type BulkPublishArgs,
866
+ type BulkUnpublishArgs,
867
+ type BulkDeleteArgs,
868
+ type BulkUpdateArgs,
869
+ type GetVersionHistoryArgs,
870
+ type GetVersionArgs,
871
+ type RollbackVersionArgs,
872
+ type CompareVersionsArgs,
873
+ } from "../component/validators.js";
874
+
875
+ // Re-export field type constants
876
+ export {
877
+ fieldTypes,
878
+ contentStatuses,
879
+ mediaTypes,
880
+ } from "../component/schema.js";
881
+
882
+ // Re-export runtime validation functions
883
+ export {
884
+ validateTextField,
885
+ validateRichTextField,
886
+ validateNumberField,
887
+ validateBooleanField,
888
+ validateDateField,
889
+ validateReferenceField,
890
+ validateMediaField,
891
+ validateSelectField,
892
+ validateMultiSelectField,
893
+ validateJsonField,
894
+ validateFieldValue,
895
+ validateLocalizedFieldValue,
896
+ validateContentData,
897
+ applyFieldDefaults,
898
+ getFieldType,
899
+ isFieldRequired,
900
+ } from "../component/validation.js";
901
+
902
+ // Re-export validation types
903
+ export type {
904
+ FieldOptions,
905
+ FieldDefinition as RuntimeFieldDefinition,
906
+ ContentTypeSchema as RuntimeContentTypeSchema,
907
+ ContentData as RuntimeContentData,
908
+ ValidationError,
909
+ ValidationErrorCode,
910
+ ValidationResult,
911
+ LocalizedValidationOptions,
912
+ ContentValidationOptions,
913
+ } from "../component/validation.js";
914
+
915
+ // --- Locale Field Utilities ---
916
+ export {
917
+ // Type guards
918
+ isLocalizedFieldValue,
919
+ isFieldLocalized,
920
+
921
+ // Field value operations
922
+ getLocalizedValue,
923
+ setLocalizedValue,
924
+ removeLocale,
925
+ mergeLocalizedValues,
926
+ getAvailableLocales,
927
+ hasLocale,
928
+
929
+ // Content data operations
930
+ resolveContentData,
931
+ setLocalizedContentData,
932
+ getTranslationStatus,
933
+
934
+ // Locale content resolution (query enhancement)
935
+ resolveLocaleContent,
936
+ resolveLocaleContentBatch,
937
+ } from "../component/localeFields.js";
938
+
939
+ // Re-export locale field types
940
+ export type {
941
+ LocalizedFieldValue,
942
+ FieldValue,
943
+ LocaleResolutionOptions,
944
+ LocaleResolutionResult,
945
+ ResolveContentDataOptions,
946
+ ResolvedContentData,
947
+ LocaleResolvedEntry,
948
+ ResolveLocaleOptions,
949
+ } from "../component/localeFields.js";
950
+
951
+ // --- Locale Fallback Chain ---
952
+ export {
953
+ // Configuration utilities
954
+ createFallbackConfig,
955
+ validateFallbackConfig,
956
+
957
+ // Chain resolution functions
958
+ resolveFallbackChain,
959
+ getFallbackChain,
960
+ buildLocaleResolutionOptions,
961
+
962
+ // Locale parsing utilities
963
+ parseLocale,
964
+ formatLocale,
965
+ getLocaleHierarchy,
966
+
967
+ // Preset fallback chains
968
+ FALLBACK_PRESETS,
969
+ mergeFallbackPresets,
970
+
971
+ // Default configuration
972
+ DEFAULT_FALLBACK_CONFIG,
973
+ } from "../component/localeFallbackChain.js";
974
+
975
+ // Re-export locale fallback chain types
976
+ export type {
977
+ LocaleCode,
978
+ LocaleFallbackConfig,
979
+ ResolvedFallbackChain,
980
+ BuildFallbackChainOptions,
981
+ ParsedLocale,
982
+ } from "../component/localeFallbackChain.js";
983
+
984
+ // Re-export slug utilities
985
+ export {
986
+ generateSlug,
987
+ isValidSlug,
988
+ generateUniqueSlug,
989
+ } from "../component/lib/slugGenerator.js";
990
+
991
+ export type { SlugOptions } from "../component/lib/slugGenerator.js";
992
+
993
+ // --- Deep Reference Resolution ---
994
+ export {
995
+ // Core resolution functions
996
+ resolveEntryReferences,
997
+ resolveEntryReferencesBatch,
998
+
999
+ // Utility functions
1000
+ findCircularReferenceMarkers,
1001
+ flattenResolvedReferences,
1002
+ countResolvedReferences,
1003
+ } from "../component/lib/deepReferenceResolver.js";
1004
+
1005
+ // Re-export deep reference resolution types from component
1006
+ export type {
1007
+ FieldDefinitionForResolver,
1008
+ } from "../component/lib/deepReferenceResolver.js";
1009
+
1010
+ // Note: DeepResolveOptions, ResolvedContentEntry, and BatchResolveResult
1011
+ // are already exported from ./types.js above
1012
+
1013
+ // --- RBAC Utilities ---
1014
+ export {
1015
+ // Role constants
1016
+ roleNames,
1017
+ type RoleName,
1018
+ roleNameValidator,
1019
+
1020
+ // Resource and action constants
1021
+ resources,
1022
+ type Resource,
1023
+ resourceValidator,
1024
+ actions,
1025
+ type Action,
1026
+ actionValidator,
1027
+
1028
+ // Permission types
1029
+ type OwnershipScope,
1030
+ type Permission,
1031
+ permissionValidator,
1032
+ type RoleDefinition,
1033
+
1034
+ // Default roles
1035
+ ADMIN_ROLE,
1036
+ EDITOR_ROLE,
1037
+ AUTHOR_ROLE,
1038
+ VIEWER_ROLE,
1039
+ DEFAULT_ROLES,
1040
+ DEFAULT_ROLES_LIST,
1041
+
1042
+ // Permission check utilities
1043
+ hasPermission,
1044
+ getRolePermissions,
1045
+ getRole,
1046
+ isBuiltInRole,
1047
+ getResourcePermissions,
1048
+ canAccessResource,
1049
+ permissionMatches,
1050
+
1051
+ // Custom role types
1052
+ type ContentTypePermission,
1053
+ type CustomRoleConfig,
1054
+ type ExtendRoleConfig,
1055
+ type ExtendedRoleDefinition,
1056
+ type ContentTypePermissionCheckOptions,
1057
+
1058
+ // Custom role factory functions
1059
+ createCustomRole,
1060
+ extendRole,
1061
+ mergeRolesWithDefaults,
1062
+ buildCustomRolesRecord,
1063
+
1064
+ // Content-type-aware permission checking
1065
+ hasContentTypePermission,
1066
+ getPermittedContentTypes,
1067
+ getExcludedContentTypes,
1068
+
1069
+ // Permission factory helpers for custom roles
1070
+ fullCrudForContentType,
1071
+ publishPermissionsForContentType,
1072
+ readOnlyForContentType,
1073
+
1074
+ // Validation utilities
1075
+ validateCustomRoleConfig,
1076
+ validateExtendRoleConfig,
1077
+ } from "../component/roles.js";
1078
+
1079
+ // Re-export custom role types from types.ts for convenience
1080
+ export type {
1081
+ CustomRoleDefinition,
1082
+ CustomRoleInput,
1083
+ CustomPermission,
1084
+ } from "./types.js";
1085
+
1086
+ // --- Rate Limiting ---
1087
+ export {
1088
+ // Main execution functions
1089
+ executeRateLimitHooks,
1090
+ requireRateLimit,
1091
+
1092
+ // Error class
1093
+ RateLimitedError,
1094
+
1095
+ // Context creation helpers
1096
+ createRateLimitContext,
1097
+ operationToCategory,
1098
+
1099
+ // Key/name builders
1100
+ createRateLimitKey,
1101
+ createRateLimitName,
1102
+
1103
+ // Default configurations
1104
+ DEFAULT_TIER_LIMITS,
1105
+ getTierLimit,
1106
+
1107
+ // Types
1108
+ type ExecuteRateLimitOptions,
1109
+ type RateLimitResult,
1110
+ type UserTier,
1111
+ } from "../component/rateLimitHooks.js";
1112
+
1113
+ // Re-export rate limit types from types.ts for convenience
1114
+ export type {
1115
+ RateLimitHooks,
1116
+ RateLimitHookContext,
1117
+ RateLimitCheckResult,
1118
+ RateLimitConsumeResult,
1119
+ RateLimitConfigResult,
1120
+ RateLimitCheckHook,
1121
+ RateLimitConsumeHook,
1122
+ RateLimitConfigHook,
1123
+ OperationCategory,
1124
+ } from "./types.js";
1125
+
1126
+ // --- Agent Tools ---
1127
+ export {
1128
+ // Main factory function
1129
+ createCmsTools,
1130
+
1131
+ // Types
1132
+ type AgentComponentApi,
1133
+ type CmsTools,
1134
+ type CmsToolName,
1135
+ type CreateCmsToolsOptions,
1136
+
1137
+ // Zod schemas for tool arguments (useful for custom tool creation)
1138
+ fieldTypeSchema,
1139
+ contentStatusSchema,
1140
+ mediaTypeSchema,
1141
+ fieldOptionsSchema,
1142
+ fieldDefinitionSchema,
1143
+ filterOperatorSchema,
1144
+ fieldFilterSchema,
1145
+
1146
+ // Content Type schemas
1147
+ createContentTypeArgsSchema,
1148
+ updateContentTypeArgsSchema,
1149
+ listContentTypesArgsSchema,
1150
+ getContentTypeArgsSchema,
1151
+
1152
+ // Content Entry schemas
1153
+ createContentEntryArgsSchema,
1154
+ updateContentEntryArgsSchema,
1155
+ publishEntryArgsSchema,
1156
+ unpublishEntryArgsSchema,
1157
+ scheduleEntryArgsSchema,
1158
+ deleteContentEntryArgsSchema,
1159
+ duplicateContentEntryArgsSchema,
1160
+ listContentEntriesArgsSchema,
1161
+ getContentEntryArgsSchema,
1162
+ restoreContentEntryArgsSchema,
1163
+
1164
+ // Media Asset schemas
1165
+ createMediaAssetArgsSchema,
1166
+ updateMediaAssetArgsSchema,
1167
+ listMediaAssetsArgsSchema,
1168
+ getMediaAssetArgsSchema,
1169
+ deleteMediaAssetArgsSchema,
1170
+
1171
+ // Bulk Operation schemas
1172
+ bulkPublishArgsSchema,
1173
+ bulkUnpublishArgsSchema,
1174
+ bulkDeleteArgsSchema,
1175
+
1176
+ // Search schema
1177
+ searchContentArgsSchema,
1178
+ } from "./agentTools.js";
1179
+
1180
+ // --- Code-Only Schema System ---
1181
+ export {
1182
+ // Core functions
1183
+ defineContentType,
1184
+ createContentSchema,
1185
+ toFieldDefinitions,
1186
+
1187
+ // Runtime utilities
1188
+ isContentTypeDefinition,
1189
+
1190
+ // Typed client factory
1191
+ createTypedCmsClient,
1192
+ TypedContentEntriesApiImpl,
1193
+
1194
+ // Schema drift detection
1195
+ detectSchemaDrift,
1196
+ formatDriftReport,
1197
+ hasErrors as hasDriftErrors,
1198
+ filterReportByContentTypes,
1199
+
1200
+ // Type code generation
1201
+ generateTypesFromDatabase,
1202
+ generateTypesFromDefinitions,
1203
+ validateGeneratedCode,
1204
+ } from "./schema/index.js";
1205
+
1206
+ // Re-export schema types
1207
+ export type {
1208
+ // Core definition types
1209
+ ContentTypeConfig,
1210
+ ContentTypeDefinition,
1211
+ ContentTypeMeta,
1212
+ FieldMeta,
1213
+ FieldRenderAs,
1214
+
1215
+ // Type inference utilities
1216
+ InferContentType,
1217
+ InferSchema,
1218
+ ContentSchema,
1219
+ SchemaContentTypeNames,
1220
+ SchemaContentType,
1221
+ ContentTypeFieldNames,
1222
+
1223
+ // Schema instance type
1224
+ ContentSchemaInstance,
1225
+ DatabaseFieldDefinition,
1226
+ } from "./schema/index.js";
1227
+
1228
+ // Re-export schema config types from types.ts
1229
+ export type {
1230
+ ContentSchemaConfig,
1231
+ ContentTypeDefinitionBase,
1232
+ } from "./types.js";
1233
+
1234
+ // Re-export typed client types for schema-aware access
1235
+ export type {
1236
+ TypedContentEntry,
1237
+ TypedPaginationResult,
1238
+ TypedContentEntriesApi,
1239
+ TypedCreateEntryOptions,
1240
+ TypedUpdateEntryOptions,
1241
+ TypedListEntriesOptions,
1242
+ SchemaDataType,
1243
+ ValidContentTypeName,
1244
+ HasContentType,
1245
+ GetContentTypeDefinition,
1246
+ TypedCmsClientConfig,
1247
+ TypedCmsClient,
1248
+ // Schema drift detection types
1249
+ DriftSeverity,
1250
+ DriftType,
1251
+ DriftIssue,
1252
+ DriftSummary,
1253
+ SchemaDriftReport,
1254
+ DetectDriftOptions,
1255
+ // Type code generation types
1256
+ CodegenOptions,
1257
+ CodegenResult,
1258
+ } from "./schema/index.js";
1259
+
1260
+ // --- Custom Field Types ---
1261
+ export {
1262
+ defineFieldType,
1263
+ registerFieldType,
1264
+ registerFieldTypes,
1265
+ getFieldTypeDefinition,
1266
+ getAllFieldTypes,
1267
+ getCustomFieldTypes,
1268
+ isBuiltInFieldType,
1269
+ isCustomFieldType,
1270
+ hasFieldType,
1271
+ getFieldTypeDefaultValue,
1272
+ getFieldTypeIcon,
1273
+ BUILT_IN_TYPES,
1274
+ type FieldTypeDefinition,
1275
+ type FieldValidationResult,
1276
+ } from "./field-types.js";
1277
+
1278
+ // --- Custom Workflows ---
1279
+ export {
1280
+ defineWorkflow,
1281
+ getWorkflowState,
1282
+ getAvailableTransitions,
1283
+ canTransition,
1284
+ isPublishedState,
1285
+ getInitialState,
1286
+ getAllPublishedStates,
1287
+ validateWorkflowTransition,
1288
+ DEFAULT_WORKFLOW,
1289
+ type WorkflowConfig,
1290
+ type WorkflowState,
1291
+ type WorkflowStateColor,
1292
+ } from "./workflows.js";
1293
+
1294
+ // --- Admin UI Configuration ---
1295
+ export {
1296
+ defineAdminConfig,
1297
+ resolveAdminConfig,
1298
+ adminConfigSchema,
1299
+ type AdminConfig,
1300
+ type NavItem,
1301
+ } from "./admin-config.js";