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,970 @@
1
+ /**
2
+ * Fluent Query Builder for Content Entries
3
+ *
4
+ * Provides a chainable, type-safe interface for constructing complex
5
+ * content queries. Supports filtering, sorting, pagination, and search
6
+ * with TypeScript inference.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * // Simple query with chaining
11
+ * const posts = await cms.contentEntries
12
+ * .query()
13
+ * .contentType("blog_post")
14
+ * .status("published")
15
+ * .limit(10)
16
+ * .execute(ctx);
17
+ *
18
+ * // Complex query with field filters
19
+ * const featured = await cms.contentEntries
20
+ * .query()
21
+ * .contentType("blog_post")
22
+ * .where("category", "eq", "technology")
23
+ * .where("featured", "eq", true)
24
+ * .whereIn("tags", ["javascript", "typescript"])
25
+ * .orderBy("_creationTime", "desc")
26
+ * .limit(5)
27
+ * .execute(ctx);
28
+ *
29
+ * // Pagination with cursor
30
+ * const page1 = await cms.contentEntries
31
+ * .query()
32
+ * .contentType("blog_post")
33
+ * .limit(20)
34
+ * .execute(ctx);
35
+ *
36
+ * const page2 = await cms.contentEntries
37
+ * .query()
38
+ * .contentType("blog_post")
39
+ * .limit(20)
40
+ * .cursor(page1.continueCursor)
41
+ * .execute(ctx);
42
+ * ```
43
+ */
44
+ // =============================================================================
45
+ // Query Builder Class
46
+ // =============================================================================
47
+ /**
48
+ * Fluent query builder for constructing content entry queries.
49
+ *
50
+ * Provides a chainable API for building complex queries with:
51
+ * - Content type filtering
52
+ * - Status filtering (single or multiple)
53
+ * - Field-level filters with various operators
54
+ * - Full-text search
55
+ * - Locale filtering
56
+ * - Cursor-based pagination
57
+ * - Sort direction
58
+ *
59
+ * All methods return `this` for chaining, except terminal methods
60
+ * (`execute()`, `first()`, `count()`) which execute the query.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * // The query builder is obtained from contentEntries.query()
65
+ * const builder = cms.contentEntries.query();
66
+ *
67
+ * // Chain methods to build the query
68
+ * const result = await builder
69
+ * .contentType("blog_post")
70
+ * .status("published")
71
+ * .where("author", "eq", "user_123")
72
+ * .search("typescript")
73
+ * .limit(10)
74
+ * .execute(ctx);
75
+ * ```
76
+ */
77
+ export class ContentQueryBuilder {
78
+ state;
79
+ api;
80
+ constructor(api) {
81
+ this.api = api;
82
+ this.state = {
83
+ fieldFilters: [],
84
+ numItems: 50, // Default page size
85
+ };
86
+ }
87
+ // ===========================================================================
88
+ // Content Type Filtering
89
+ // ===========================================================================
90
+ /**
91
+ * Filter by content type name.
92
+ *
93
+ * @param name - The content type name (e.g., "blog_post")
94
+ * @returns this for chaining
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * const posts = await cms.contentEntries
99
+ * .query()
100
+ * .contentType("blog_post")
101
+ * .execute(ctx);
102
+ * ```
103
+ */
104
+ contentType(name) {
105
+ this.state.contentTypeName = name;
106
+ this.state.contentTypeId = undefined; // Clear ID if name is set
107
+ return this;
108
+ }
109
+ /**
110
+ * Filter by content type ID.
111
+ *
112
+ * @param id - The content type ID
113
+ * @returns this for chaining
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const posts = await cms.contentEntries
118
+ * .query()
119
+ * .contentTypeById(typeId)
120
+ * .execute(ctx);
121
+ * ```
122
+ */
123
+ contentTypeById(id) {
124
+ this.state.contentTypeId = id;
125
+ this.state.contentTypeName = undefined; // Clear name if ID is set
126
+ return this;
127
+ }
128
+ // ===========================================================================
129
+ // Status Filtering
130
+ // ===========================================================================
131
+ /**
132
+ * Filter by a single status.
133
+ *
134
+ * @param status - The status to filter by
135
+ * @returns this for chaining
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * const published = await cms.contentEntries
140
+ * .query()
141
+ * .status("published")
142
+ * .execute(ctx);
143
+ * ```
144
+ */
145
+ status(status) {
146
+ this.state.status = status;
147
+ this.state.statusIn = undefined; // Clear statusIn if single status is set
148
+ return this;
149
+ }
150
+ /**
151
+ * Filter by multiple statuses (OR logic).
152
+ *
153
+ * Useful for admin views that need to show content in various states.
154
+ *
155
+ * @param statuses - Array of statuses to include
156
+ * @returns this for chaining
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * // Show all non-archived content in admin
161
+ * const editorial = await cms.contentEntries
162
+ * .query()
163
+ * .statusIn(["draft", "published", "scheduled"])
164
+ * .execute(ctx);
165
+ * ```
166
+ */
167
+ statusIn(statuses) {
168
+ this.state.statusIn = statuses;
169
+ this.state.status = undefined; // Clear single status if statusIn is set
170
+ return this;
171
+ }
172
+ /**
173
+ * Shorthand for status("published").
174
+ *
175
+ * @returns this for chaining
176
+ */
177
+ published() {
178
+ return this.status("published");
179
+ }
180
+ /**
181
+ * Shorthand for status("draft").
182
+ *
183
+ * @returns this for chaining
184
+ */
185
+ drafts() {
186
+ return this.status("draft");
187
+ }
188
+ /**
189
+ * Shorthand for status("archived").
190
+ *
191
+ * @returns this for chaining
192
+ */
193
+ archived() {
194
+ return this.status("archived");
195
+ }
196
+ /**
197
+ * Shorthand for status("scheduled").
198
+ *
199
+ * @returns this for chaining
200
+ */
201
+ scheduled() {
202
+ return this.status("scheduled");
203
+ }
204
+ // ===========================================================================
205
+ // Locale Filtering
206
+ // ===========================================================================
207
+ /**
208
+ * Filter by locale.
209
+ *
210
+ * @param locale - The locale code (e.g., "en-US", "es-ES")
211
+ * @returns this for chaining
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * const spanishPosts = await cms.contentEntries
216
+ * .query()
217
+ * .contentType("blog_post")
218
+ * .locale("es-ES")
219
+ * .execute(ctx);
220
+ * ```
221
+ */
222
+ locale(locale) {
223
+ this.state.locale = locale;
224
+ return this;
225
+ }
226
+ // ===========================================================================
227
+ // Soft Delete Filtering
228
+ // ===========================================================================
229
+ /**
230
+ * Include soft-deleted entries in results.
231
+ *
232
+ * By default, soft-deleted entries are excluded.
233
+ *
234
+ * @param include - Whether to include deleted entries (default: true)
235
+ * @returns this for chaining
236
+ *
237
+ * @example
238
+ * ```typescript
239
+ * // Show all entries including deleted ones
240
+ * const all = await cms.contentEntries
241
+ * .query()
242
+ * .includeDeleted()
243
+ * .execute(ctx);
244
+ *
245
+ * // Explicitly exclude deleted (same as default)
246
+ * const active = await cms.contentEntries
247
+ * .query()
248
+ * .includeDeleted(false)
249
+ * .execute(ctx);
250
+ * ```
251
+ */
252
+ includeDeleted(include = true) {
253
+ this.state.includeDeleted = include;
254
+ return this;
255
+ }
256
+ /**
257
+ * Only return soft-deleted entries.
258
+ *
259
+ * @returns this for chaining
260
+ *
261
+ * @example
262
+ * ```typescript
263
+ * const trash = await cms.contentEntries
264
+ * .query()
265
+ * .onlyDeleted()
266
+ * .execute(ctx);
267
+ * ```
268
+ */
269
+ onlyDeleted() {
270
+ this.state.includeDeleted = true;
271
+ // Add a field filter for deletedAt being defined
272
+ // This is handled in the component layer
273
+ return this;
274
+ }
275
+ // ===========================================================================
276
+ // Full-Text Search
277
+ // ===========================================================================
278
+ /**
279
+ * Search content using full-text search.
280
+ *
281
+ * Searches indexed fields in the content entry data.
282
+ * Requires the searchIndexing feature to be enabled.
283
+ *
284
+ * @param query - The search query string
285
+ * @returns this for chaining
286
+ *
287
+ * @example
288
+ * ```typescript
289
+ * const results = await cms.contentEntries
290
+ * .query()
291
+ * .contentType("blog_post")
292
+ * .search("typescript tutorial")
293
+ * .execute(ctx);
294
+ * ```
295
+ */
296
+ search(query) {
297
+ this.state.search = query;
298
+ return this;
299
+ }
300
+ // ===========================================================================
301
+ // Field Filters
302
+ // ===========================================================================
303
+ /**
304
+ * Add a field filter condition.
305
+ *
306
+ * Multiple filters are combined with AND logic.
307
+ *
308
+ * @param field - The field name in the content data
309
+ * @param operator - The comparison operator
310
+ * @param value - The value to compare against
311
+ * @returns this for chaining
312
+ *
313
+ * @example
314
+ * ```typescript
315
+ * const techPosts = await cms.contentEntries
316
+ * .query()
317
+ * .contentType("blog_post")
318
+ * .where("category", "eq", "technology")
319
+ * .where("views", "gte", 100)
320
+ * .execute(ctx);
321
+ * ```
322
+ */
323
+ where(field, operator, value) {
324
+ this.state.fieldFilters.push({ field, operator, value });
325
+ return this;
326
+ }
327
+ /**
328
+ * Filter where field equals value.
329
+ * Shorthand for where(field, "eq", value).
330
+ *
331
+ * @param field - The field name
332
+ * @param value - The value to match
333
+ * @returns this for chaining
334
+ *
335
+ * @example
336
+ * ```typescript
337
+ * const featured = await cms.contentEntries
338
+ * .query()
339
+ * .whereEquals("featured", true)
340
+ * .execute(ctx);
341
+ * ```
342
+ */
343
+ whereEquals(field, value) {
344
+ return this.where(field, "eq", value);
345
+ }
346
+ /**
347
+ * Filter where field does not equal value.
348
+ * Shorthand for where(field, "ne", value).
349
+ *
350
+ * @param field - The field name
351
+ * @param value - The value to exclude
352
+ * @returns this for chaining
353
+ */
354
+ whereNotEquals(field, value) {
355
+ return this.where(field, "ne", value);
356
+ }
357
+ /**
358
+ * Filter where field is greater than value.
359
+ * Shorthand for where(field, "gt", value).
360
+ *
361
+ * @param field - The field name
362
+ * @param value - The minimum value (exclusive)
363
+ * @returns this for chaining
364
+ *
365
+ * @example
366
+ * ```typescript
367
+ * const expensive = await cms.contentEntries
368
+ * .query()
369
+ * .contentType("product")
370
+ * .whereGreaterThan("price", 100)
371
+ * .execute(ctx);
372
+ * ```
373
+ */
374
+ whereGreaterThan(field, value) {
375
+ const filterValue = value instanceof Date ? value.getTime() : value;
376
+ return this.where(field, "gt", filterValue);
377
+ }
378
+ /**
379
+ * Filter where field is greater than or equal to value.
380
+ * Shorthand for where(field, "gte", value).
381
+ *
382
+ * @param field - The field name
383
+ * @param value - The minimum value (inclusive)
384
+ * @returns this for chaining
385
+ */
386
+ whereGreaterThanOrEquals(field, value) {
387
+ const filterValue = value instanceof Date ? value.getTime() : value;
388
+ return this.where(field, "gte", filterValue);
389
+ }
390
+ /**
391
+ * Filter where field is less than value.
392
+ * Shorthand for where(field, "lt", value).
393
+ *
394
+ * @param field - The field name
395
+ * @param value - The maximum value (exclusive)
396
+ * @returns this for chaining
397
+ */
398
+ whereLessThan(field, value) {
399
+ const filterValue = value instanceof Date ? value.getTime() : value;
400
+ return this.where(field, "lt", filterValue);
401
+ }
402
+ /**
403
+ * Filter where field is less than or equal to value.
404
+ * Shorthand for where(field, "lte", value).
405
+ *
406
+ * @param field - The field name
407
+ * @param value - The maximum value (inclusive)
408
+ * @returns this for chaining
409
+ */
410
+ whereLessThanOrEquals(field, value) {
411
+ const filterValue = value instanceof Date ? value.getTime() : value;
412
+ return this.where(field, "lte", filterValue);
413
+ }
414
+ /**
415
+ * Filter where field is in a range (inclusive).
416
+ *
417
+ * @param field - The field name
418
+ * @param min - The minimum value (inclusive)
419
+ * @param max - The maximum value (inclusive)
420
+ * @returns this for chaining
421
+ *
422
+ * @example
423
+ * ```typescript
424
+ * const midRange = await cms.contentEntries
425
+ * .query()
426
+ * .contentType("product")
427
+ * .whereBetween("price", 50, 150)
428
+ * .execute(ctx);
429
+ * ```
430
+ */
431
+ whereBetween(field, min, max) {
432
+ const minValue = min instanceof Date ? min.getTime() : min;
433
+ const maxValue = max instanceof Date ? max.getTime() : max;
434
+ return this
435
+ .where(field, "gte", minValue)
436
+ .where(field, "lte", maxValue);
437
+ }
438
+ /**
439
+ * Filter where field value is in an array of allowed values.
440
+ * Shorthand for where(field, "in", values).
441
+ *
442
+ * @param field - The field name
443
+ * @param values - Array of allowed values
444
+ * @returns this for chaining
445
+ *
446
+ * @example
447
+ * ```typescript
448
+ * const categoryPosts = await cms.contentEntries
449
+ * .query()
450
+ * .whereIn("category", ["tech", "science", "design"])
451
+ * .execute(ctx);
452
+ * ```
453
+ */
454
+ whereIn(field, values) {
455
+ return this.where(field, "in", values);
456
+ }
457
+ /**
458
+ * Filter where field value is NOT in an array of values.
459
+ * Shorthand for where(field, "notIn", values).
460
+ *
461
+ * @param field - The field name
462
+ * @param values - Array of excluded values
463
+ * @returns this for chaining
464
+ */
465
+ whereNotIn(field, values) {
466
+ return this.where(field, "notIn", values);
467
+ }
468
+ /**
469
+ * Filter where string field contains a substring.
470
+ * For array fields, checks if the array contains the value.
471
+ * Shorthand for where(field, "contains", value).
472
+ *
473
+ * @param field - The field name
474
+ * @param value - The substring or array value to find
475
+ * @returns this for chaining
476
+ *
477
+ * @example
478
+ * ```typescript
479
+ * // String contains
480
+ * const results = await cms.contentEntries
481
+ * .query()
482
+ * .whereContains("title", "guide")
483
+ * .execute(ctx);
484
+ *
485
+ * // Array contains
486
+ * const tagged = await cms.contentEntries
487
+ * .query()
488
+ * .whereContains("tags", "featured")
489
+ * .execute(ctx);
490
+ * ```
491
+ */
492
+ whereContains(field, value) {
493
+ return this.where(field, "contains", value);
494
+ }
495
+ /**
496
+ * Filter where string field starts with a prefix.
497
+ * Shorthand for where(field, "startsWith", prefix).
498
+ *
499
+ * @param field - The field name
500
+ * @param prefix - The prefix to match
501
+ * @returns this for chaining
502
+ *
503
+ * @example
504
+ * ```typescript
505
+ * const year2026 = await cms.contentEntries
506
+ * .query()
507
+ * .whereStartsWith("slug", "2026-")
508
+ * .execute(ctx);
509
+ * ```
510
+ */
511
+ whereStartsWith(field, prefix) {
512
+ return this.where(field, "startsWith", prefix);
513
+ }
514
+ /**
515
+ * Filter where string field ends with a suffix.
516
+ * Shorthand for where(field, "endsWith", suffix).
517
+ *
518
+ * @param field - The field name
519
+ * @param suffix - The suffix to match
520
+ * @returns this for chaining
521
+ */
522
+ whereEndsWith(field, suffix) {
523
+ return this.where(field, "endsWith", suffix);
524
+ }
525
+ // ===========================================================================
526
+ // Sorting
527
+ // ===========================================================================
528
+ /**
529
+ * Set the sort order for results.
530
+ *
531
+ * Supports sorting by:
532
+ * - System fields: "_creationTime", "_id", "firstPublishedAt", "lastPublishedAt", "scheduledPublishAt", "version"
533
+ * - Custom data fields: Use "data.fieldName" format (e.g., "data.price", "data.sortOrder")
534
+ *
535
+ * Results are sorted in descending order by default.
536
+ *
537
+ * @param field - The field to sort by (system field or "data.fieldName" for custom fields)
538
+ * @param direction - Sort direction ("asc" or "desc")
539
+ * @returns this for chaining
540
+ *
541
+ * @example
542
+ * ```typescript
543
+ * // Newest first (default)
544
+ * const newest = await cms.contentEntries
545
+ * .query()
546
+ * .orderBy("_creationTime", "desc")
547
+ * .execute(ctx);
548
+ *
549
+ * // Oldest first
550
+ * const oldest = await cms.contentEntries
551
+ * .query()
552
+ * .orderBy("_creationTime", "asc")
553
+ * .execute(ctx);
554
+ *
555
+ * // Sort by publish date
556
+ * const byPublishDate = await cms.contentEntries
557
+ * .query()
558
+ * .orderBy("firstPublishedAt", "desc")
559
+ * .execute(ctx);
560
+ *
561
+ * // Sort by custom field (price, low to high)
562
+ * const byPrice = await cms.contentEntries
563
+ * .query()
564
+ * .contentType("product")
565
+ * .orderBy("data.price", "asc")
566
+ * .execute(ctx);
567
+ *
568
+ * // Sort by custom order field
569
+ * const byOrder = await cms.contentEntries
570
+ * .query()
571
+ * .contentType("menu_item")
572
+ * .orderBy("data.sortOrder", "asc")
573
+ * .execute(ctx);
574
+ * ```
575
+ */
576
+ orderBy(field, direction = "desc") {
577
+ this.state.sortField = field;
578
+ this.state.sortDirection = direction;
579
+ return this;
580
+ }
581
+ /**
582
+ * Sort by first publish date (newest published first).
583
+ * Useful for showing recently published content.
584
+ *
585
+ * @param direction - Sort direction ("asc" or "desc", default "desc")
586
+ * @returns this for chaining
587
+ *
588
+ * @example
589
+ * ```typescript
590
+ * const recentlyPublished = await cms.contentEntries
591
+ * .query()
592
+ * .status("published")
593
+ * .byPublishDate()
594
+ * .execute(ctx);
595
+ * ```
596
+ */
597
+ byPublishDate(direction = "desc") {
598
+ return this.orderBy("firstPublishedAt", direction);
599
+ }
600
+ /**
601
+ * Sort by last publish date (most recently updated first).
602
+ * Useful for showing recently updated content.
603
+ *
604
+ * @param direction - Sort direction ("asc" or "desc", default "desc")
605
+ * @returns this for chaining
606
+ */
607
+ byLastPublishDate(direction = "desc") {
608
+ return this.orderBy("lastPublishedAt", direction);
609
+ }
610
+ /**
611
+ * Sort by a custom data field.
612
+ * Convenience method that automatically prefixes field name with "data.".
613
+ *
614
+ * @param fieldName - The field name in the content entry's data object
615
+ * @param direction - Sort direction ("asc" or "desc", default "desc")
616
+ * @returns this for chaining
617
+ *
618
+ * @example
619
+ * ```typescript
620
+ * // Sort by price (low to high)
621
+ * const cheapest = await cms.contentEntries
622
+ * .query()
623
+ * .contentType("product")
624
+ * .orderByField("price", "asc")
625
+ * .execute(ctx);
626
+ *
627
+ * // Sort by title alphabetically
628
+ * const alphabetical = await cms.contentEntries
629
+ * .query()
630
+ * .orderByField("title", "asc")
631
+ * .execute(ctx);
632
+ * ```
633
+ */
634
+ orderByField(fieldName, direction = "desc") {
635
+ return this.orderBy(`data.${fieldName}`, direction);
636
+ }
637
+ /**
638
+ * Sort by newest first (descending creation time).
639
+ * Shorthand for orderBy("_creationTime", "desc").
640
+ *
641
+ * @returns this for chaining
642
+ */
643
+ newestFirst() {
644
+ return this.orderBy("_creationTime", "desc");
645
+ }
646
+ /**
647
+ * Sort by oldest first (ascending creation time).
648
+ * Shorthand for orderBy("_creationTime", "asc").
649
+ *
650
+ * @returns this for chaining
651
+ */
652
+ oldestFirst() {
653
+ return this.orderBy("_creationTime", "asc");
654
+ }
655
+ // ===========================================================================
656
+ // Pagination
657
+ // ===========================================================================
658
+ /**
659
+ * Set the maximum number of results to return.
660
+ *
661
+ * @param count - Number of items per page (1-250)
662
+ * @returns this for chaining
663
+ *
664
+ * @example
665
+ * ```typescript
666
+ * const firstTen = await cms.contentEntries
667
+ * .query()
668
+ * .limit(10)
669
+ * .execute(ctx);
670
+ * ```
671
+ */
672
+ limit(count) {
673
+ this.state.numItems = Math.max(1, Math.min(250, count));
674
+ return this;
675
+ }
676
+ /**
677
+ * Set the pagination cursor for fetching the next page.
678
+ *
679
+ * Use the `continueCursor` from the previous query result.
680
+ *
681
+ * @param cursor - The cursor from the previous page
682
+ * @returns this for chaining
683
+ *
684
+ * @example
685
+ * ```typescript
686
+ * const page1 = await cms.contentEntries
687
+ * .query()
688
+ * .limit(20)
689
+ * .execute(ctx);
690
+ *
691
+ * if (!page1.isDone) {
692
+ * const page2 = await cms.contentEntries
693
+ * .query()
694
+ * .limit(20)
695
+ * .cursor(page1.continueCursor)
696
+ * .execute(ctx);
697
+ * }
698
+ * ```
699
+ */
700
+ cursor(cursor) {
701
+ this.state.cursorValue = cursor;
702
+ return this;
703
+ }
704
+ /**
705
+ * Alias for cursor() for more natural chaining.
706
+ *
707
+ * @param cursor - The cursor from the previous page
708
+ * @returns this for chaining
709
+ */
710
+ after(cursor) {
711
+ return this.cursor(cursor);
712
+ }
713
+ // ===========================================================================
714
+ // Build Query Options
715
+ // ===========================================================================
716
+ /**
717
+ * Build the query options object from the current state.
718
+ *
719
+ * This is primarily for internal use, but can be useful for debugging
720
+ * or when you need to pass options to the underlying API directly.
721
+ *
722
+ * @returns The compiled ContentQueryOptions
723
+ *
724
+ * @example
725
+ * ```typescript
726
+ * const options = cms.contentEntries
727
+ * .query()
728
+ * .contentType("blog_post")
729
+ * .status("published")
730
+ * .orderBy("data.price", "asc")
731
+ * .toOptions();
732
+ *
733
+ * console.log(options);
734
+ * // {
735
+ * // contentTypeName: "blog_post",
736
+ * // status: "published",
737
+ * // sortField: "data.price",
738
+ * // sortDirection: "asc",
739
+ * // fieldFilters: [],
740
+ * // paginationOpts: { numItems: 50 }
741
+ * // }
742
+ * ```
743
+ */
744
+ toOptions() {
745
+ const options = {
746
+ paginationOpts: {
747
+ numItems: this.state.numItems,
748
+ // Convert undefined to null since the API expects string | null, not undefined
749
+ cursor: this.state.cursorValue ?? null,
750
+ },
751
+ };
752
+ if (this.state.contentTypeId) {
753
+ options.contentTypeId = this.state.contentTypeId;
754
+ }
755
+ if (this.state.contentTypeName) {
756
+ options.contentTypeName = this.state.contentTypeName;
757
+ }
758
+ if (this.state.status) {
759
+ options.status = this.state.status;
760
+ }
761
+ if (this.state.statusIn && this.state.statusIn.length > 0) {
762
+ options.statusIn = this.state.statusIn;
763
+ }
764
+ if (this.state.locale) {
765
+ options.locale = this.state.locale;
766
+ }
767
+ if (this.state.search) {
768
+ options.search = this.state.search;
769
+ }
770
+ if (this.state.includeDeleted !== undefined) {
771
+ options.includeDeleted = this.state.includeDeleted;
772
+ }
773
+ if (this.state.fieldFilters.length > 0) {
774
+ options.fieldFilters = this.state.fieldFilters;
775
+ }
776
+ // Include sort options if set
777
+ if (this.state.sortField) {
778
+ options.sortField = this.state.sortField;
779
+ }
780
+ if (this.state.sortDirection) {
781
+ options.sortDirection = this.state.sortDirection;
782
+ }
783
+ return options;
784
+ }
785
+ // ===========================================================================
786
+ // Terminal Methods (Execute Query)
787
+ // ===========================================================================
788
+ /**
789
+ * Execute the query and return paginated results.
790
+ *
791
+ * This is the primary terminal method that runs the built query.
792
+ *
793
+ * @param ctx - Convex query context
794
+ * @returns Promise resolving to paginated results
795
+ *
796
+ * @example
797
+ * ```typescript
798
+ * const result = await cms.contentEntries
799
+ * .query()
800
+ * .contentType("blog_post")
801
+ * .status("published")
802
+ * .limit(10)
803
+ * .execute(ctx);
804
+ *
805
+ * console.log(result.page); // Array of entries
806
+ * console.log(result.isDone); // true if no more results
807
+ * console.log(result.continueCursor); // Cursor for next page
808
+ * console.log(result.hasMore); // Convenience: !isDone
809
+ * ```
810
+ */
811
+ async execute(ctx) {
812
+ const options = this.toOptions();
813
+ const result = await ctx.runQuery(this.api.contentEntries.list, options);
814
+ return {
815
+ page: result.page,
816
+ continueCursor: result.continueCursor,
817
+ isDone: result.isDone,
818
+ hasMore: !result.isDone,
819
+ };
820
+ }
821
+ /**
822
+ * Execute the query and return only the first result.
823
+ *
824
+ * Convenience method that sets limit(1) and returns the first item or null.
825
+ *
826
+ * @param ctx - Convex query context
827
+ * @returns Promise resolving to the first entry or null
828
+ *
829
+ * @example
830
+ * ```typescript
831
+ * const latest = await cms.contentEntries
832
+ * .query()
833
+ * .contentType("blog_post")
834
+ * .status("published")
835
+ * .newestFirst()
836
+ * .first(ctx);
837
+ *
838
+ * if (latest) {
839
+ * console.log(latest.data.title);
840
+ * }
841
+ * ```
842
+ */
843
+ async first(ctx) {
844
+ this.state.numItems = 1;
845
+ const result = await this.execute(ctx);
846
+ return result.page[0] ?? null;
847
+ }
848
+ /**
849
+ * Execute the query and check if any results exist.
850
+ *
851
+ * Convenience method that sets limit(1) and returns boolean.
852
+ *
853
+ * @param ctx - Convex query context
854
+ * @returns Promise resolving to true if results exist
855
+ *
856
+ * @example
857
+ * ```typescript
858
+ * const hasPublished = await cms.contentEntries
859
+ * .query()
860
+ * .contentType("blog_post")
861
+ * .status("published")
862
+ * .exists(ctx);
863
+ *
864
+ * if (!hasPublished) {
865
+ * console.log("No published posts yet");
866
+ * }
867
+ * ```
868
+ */
869
+ async exists(ctx) {
870
+ const entry = await this.first(ctx);
871
+ return entry !== null;
872
+ }
873
+ /**
874
+ * Execute the query and collect all results into a single array.
875
+ *
876
+ * WARNING: This fetches ALL matching results, potentially making
877
+ * multiple paginated requests. Use with caution on large datasets.
878
+ *
879
+ * @param ctx - Convex query context
880
+ * @param maxPages - Maximum number of pages to fetch (default: 10)
881
+ * @returns Promise resolving to array of all entries
882
+ *
883
+ * @example
884
+ * ```typescript
885
+ * // Get all published posts (use with caution!)
886
+ * const allPosts = await cms.contentEntries
887
+ * .query()
888
+ * .contentType("blog_post")
889
+ * .status("published")
890
+ * .all(ctx);
891
+ * ```
892
+ */
893
+ async all(ctx, maxPages = 10) {
894
+ const results = [];
895
+ let currentCursor = this.state.cursorValue;
896
+ let pageCount = 0;
897
+ while (pageCount < maxPages) {
898
+ this.state.cursorValue = currentCursor;
899
+ const result = await this.execute(ctx);
900
+ results.push(...result.page);
901
+ if (result.isDone || !result.continueCursor) {
902
+ break;
903
+ }
904
+ currentCursor = result.continueCursor;
905
+ pageCount++;
906
+ }
907
+ return results;
908
+ }
909
+ // ===========================================================================
910
+ // Clone / Reset
911
+ // ===========================================================================
912
+ /**
913
+ * Create a copy of this query builder with the current state.
914
+ *
915
+ * Useful for creating variations of a base query.
916
+ *
917
+ * @returns A new QueryBuilder with the same state
918
+ *
919
+ * @example
920
+ * ```typescript
921
+ * const baseQuery = cms.contentEntries
922
+ * .query()
923
+ * .contentType("blog_post");
924
+ *
925
+ * const published = await baseQuery.clone()
926
+ * .status("published")
927
+ * .execute(ctx);
928
+ *
929
+ * const drafts = await baseQuery.clone()
930
+ * .status("draft")
931
+ * .execute(ctx);
932
+ * ```
933
+ */
934
+ clone() {
935
+ const cloned = new ContentQueryBuilder(this.api);
936
+ cloned.state = {
937
+ ...this.state,
938
+ fieldFilters: [...this.state.fieldFilters],
939
+ statusIn: this.state.statusIn ? [...this.state.statusIn] : undefined,
940
+ };
941
+ return cloned;
942
+ }
943
+ /**
944
+ * Reset the query builder to its initial state.
945
+ *
946
+ * @returns this for chaining
947
+ */
948
+ reset() {
949
+ this.state = {
950
+ fieldFilters: [],
951
+ numItems: 50,
952
+ };
953
+ return this;
954
+ }
955
+ }
956
+ // =============================================================================
957
+ // Factory Function
958
+ // =============================================================================
959
+ /**
960
+ * Create a new content query builder.
961
+ *
962
+ * This is typically called internally by ContentEntriesApi.query().
963
+ *
964
+ * @param api - The typed component API
965
+ * @returns A new ContentQueryBuilder instance
966
+ */
967
+ export function createQueryBuilder(api) {
968
+ return new ContentQueryBuilder(api);
969
+ }
970
+ //# sourceMappingURL=queryBuilder.js.map