convex-cms 0.0.2 → 0.0.3

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 (265) hide show
  1. package/admin-dist/nitro.json +15 -0
  2. package/admin-dist/public/assets/CmsEmptyState-CRswfTzk.js +5 -0
  3. package/admin-dist/public/assets/CmsPageHeader-CirpXndm.js +1 -0
  4. package/admin-dist/public/assets/CmsStatusBadge-CbEUpQu-.js +1 -0
  5. package/admin-dist/public/assets/CmsToolbar-BI2nZOXp.js +1 -0
  6. package/admin-dist/public/assets/ContentEntryEditor-CBeCyK_m.js +4 -0
  7. package/admin-dist/public/assets/ErrorState-BIVaWmom.js +1 -0
  8. package/admin-dist/public/assets/TaxonomyFilter-ChaY6Y_x.js +1 -0
  9. package/admin-dist/public/assets/_contentTypeId-DQ8k_Rvw.js +1 -0
  10. package/admin-dist/public/assets/_entryId-CKU_glsK.js +1 -0
  11. package/admin-dist/public/assets/alert-BXjTqrwQ.js +1 -0
  12. package/admin-dist/public/assets/badge-hvUOzpVZ.js +1 -0
  13. package/admin-dist/public/assets/circle-check-big-CF_pR17r.js +1 -0
  14. package/admin-dist/public/assets/command-DU82cJlt.js +1 -0
  15. package/admin-dist/public/assets/content-_LXl3pp7.js +1 -0
  16. package/admin-dist/public/assets/content-types-KjxaXGxY.js +2 -0
  17. package/admin-dist/public/assets/globals-CS6BZ0zp.css +1 -0
  18. package/admin-dist/public/assets/index-DNGIZHL-.js +1 -0
  19. package/admin-dist/public/assets/label-KNtpL71g.js +1 -0
  20. package/admin-dist/public/assets/link-2-Bw2aI4V4.js +1 -0
  21. package/admin-dist/public/assets/list-sYepHjt_.js +1 -0
  22. package/admin-dist/public/assets/main-CKj5yfEi.js +97 -0
  23. package/admin-dist/public/assets/media-Bkrkffm7.js +1 -0
  24. package/admin-dist/public/assets/new._contentTypeId-C3LstjNs.js +1 -0
  25. package/admin-dist/public/assets/plus-DUn8v_Xf.js +1 -0
  26. package/admin-dist/public/assets/rotate-ccw-DJEoHcRI.js +1 -0
  27. package/admin-dist/public/assets/scroll-area-DfIlT0in.js +1 -0
  28. package/admin-dist/public/assets/search-MuAUDJKR.js +1 -0
  29. package/admin-dist/public/assets/select-BD29IXCI.js +1 -0
  30. package/admin-dist/public/assets/settings-DmMyn_6A.js +1 -0
  31. package/admin-dist/public/assets/switch-h3Rrnl5i.js +1 -0
  32. package/admin-dist/public/assets/tabs-imc8h-Dp.js +1 -0
  33. package/admin-dist/public/assets/taxonomies-dAsrT65H.js +1 -0
  34. package/admin-dist/public/assets/textarea-BTy7nwzR.js +1 -0
  35. package/admin-dist/public/assets/trash-SAWKZZHv.js +1 -0
  36. package/admin-dist/public/assets/triangle-alert-E52Vfeuh.js +1 -0
  37. package/admin-dist/public/assets/useBreadcrumbLabel-BECBMCzM.js +1 -0
  38. package/admin-dist/public/assets/usePermissions-Basjs9BT.js +1 -0
  39. package/admin-dist/public/favicon.ico +0 -0
  40. package/admin-dist/server/_chunks/_libs/@date-fns/tz.mjs +217 -0
  41. package/admin-dist/server/_chunks/_libs/@floating-ui/core.mjs +719 -0
  42. package/admin-dist/server/_chunks/_libs/@floating-ui/dom.mjs +622 -0
  43. package/admin-dist/server/_chunks/_libs/@floating-ui/react-dom.mjs +292 -0
  44. package/admin-dist/server/_chunks/_libs/@floating-ui/utils.mjs +320 -0
  45. package/admin-dist/server/_chunks/_libs/@radix-ui/number.mjs +6 -0
  46. package/admin-dist/server/_chunks/_libs/@radix-ui/primitive.mjs +11 -0
  47. package/admin-dist/server/_chunks/_libs/@radix-ui/react-arrow.mjs +23 -0
  48. package/admin-dist/server/_chunks/_libs/@radix-ui/react-avatar.mjs +119 -0
  49. package/admin-dist/server/_chunks/_libs/@radix-ui/react-checkbox.mjs +270 -0
  50. package/admin-dist/server/_chunks/_libs/@radix-ui/react-collection.mjs +69 -0
  51. package/admin-dist/server/_chunks/_libs/@radix-ui/react-compose-refs.mjs +39 -0
  52. package/admin-dist/server/_chunks/_libs/@radix-ui/react-context.mjs +137 -0
  53. package/admin-dist/server/_chunks/_libs/@radix-ui/react-dialog.mjs +325 -0
  54. package/admin-dist/server/_chunks/_libs/@radix-ui/react-direction.mjs +9 -0
  55. package/admin-dist/server/_chunks/_libs/@radix-ui/react-dismissable-layer.mjs +210 -0
  56. package/admin-dist/server/_chunks/_libs/@radix-ui/react-dropdown-menu.mjs +253 -0
  57. package/admin-dist/server/_chunks/_libs/@radix-ui/react-focus-guards.mjs +29 -0
  58. package/admin-dist/server/_chunks/_libs/@radix-ui/react-focus-scope.mjs +206 -0
  59. package/admin-dist/server/_chunks/_libs/@radix-ui/react-id.mjs +14 -0
  60. package/admin-dist/server/_chunks/_libs/@radix-ui/react-label.mjs +23 -0
  61. package/admin-dist/server/_chunks/_libs/@radix-ui/react-menu.mjs +812 -0
  62. package/admin-dist/server/_chunks/_libs/@radix-ui/react-popover.mjs +300 -0
  63. package/admin-dist/server/_chunks/_libs/@radix-ui/react-popper.mjs +286 -0
  64. package/admin-dist/server/_chunks/_libs/@radix-ui/react-portal.mjs +16 -0
  65. package/admin-dist/server/_chunks/_libs/@radix-ui/react-presence.mjs +128 -0
  66. package/admin-dist/server/_chunks/_libs/@radix-ui/react-primitive.mjs +141 -0
  67. package/admin-dist/server/_chunks/_libs/@radix-ui/react-roving-focus.mjs +224 -0
  68. package/admin-dist/server/_chunks/_libs/@radix-ui/react-scroll-area.mjs +721 -0
  69. package/admin-dist/server/_chunks/_libs/@radix-ui/react-select.mjs +1163 -0
  70. package/admin-dist/server/_chunks/_libs/@radix-ui/react-separator.mjs +28 -0
  71. package/admin-dist/server/_chunks/_libs/@radix-ui/react-slot.mjs +601 -0
  72. package/admin-dist/server/_chunks/_libs/@radix-ui/react-switch.mjs +152 -0
  73. package/admin-dist/server/_chunks/_libs/@radix-ui/react-tabs.mjs +189 -0
  74. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-callback-ref.mjs +11 -0
  75. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-controllable-state.mjs +69 -0
  76. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-effect-event.mjs +1 -0
  77. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-escape-keydown.mjs +17 -0
  78. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-is-hydrated.mjs +15 -0
  79. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-layout-effect.mjs +6 -0
  80. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-previous.mjs +14 -0
  81. package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-size.mjs +39 -0
  82. package/admin-dist/server/_chunks/_libs/@radix-ui/react-visually-hidden.mjs +33 -0
  83. package/admin-dist/server/_chunks/_libs/@tanstack/history.mjs +409 -0
  84. package/admin-dist/server/_chunks/_libs/@tanstack/react-router.mjs +1711 -0
  85. package/admin-dist/server/_chunks/_libs/@tanstack/react-store.mjs +56 -0
  86. package/admin-dist/server/_chunks/_libs/@tanstack/router-core.mjs +4829 -0
  87. package/admin-dist/server/_chunks/_libs/@tanstack/store.mjs +134 -0
  88. package/admin-dist/server/_chunks/_libs/react-dom.mjs +10781 -0
  89. package/admin-dist/server/_chunks/_libs/react.mjs +513 -0
  90. package/admin-dist/server/_libs/aria-hidden.mjs +122 -0
  91. package/admin-dist/server/_libs/class-variance-authority.mjs +44 -0
  92. package/admin-dist/server/_libs/clsx.mjs +16 -0
  93. package/admin-dist/server/_libs/cmdk.mjs +315 -0
  94. package/admin-dist/server/_libs/convex.mjs +4841 -0
  95. package/admin-dist/server/_libs/cookie-es.mjs +58 -0
  96. package/admin-dist/server/_libs/croner.mjs +1 -0
  97. package/admin-dist/server/_libs/crossws.mjs +1 -0
  98. package/admin-dist/server/_libs/date-fns.mjs +1716 -0
  99. package/admin-dist/server/_libs/detect-node-es.mjs +1 -0
  100. package/admin-dist/server/_libs/get-nonce.mjs +9 -0
  101. package/admin-dist/server/_libs/h3-v2.mjs +277 -0
  102. package/admin-dist/server/_libs/h3.mjs +401 -0
  103. package/admin-dist/server/_libs/hookable.mjs +1 -0
  104. package/admin-dist/server/_libs/isbot.mjs +20 -0
  105. package/admin-dist/server/_libs/lucide-react.mjs +850 -0
  106. package/admin-dist/server/_libs/ohash.mjs +1 -0
  107. package/admin-dist/server/_libs/react-day-picker.mjs +2201 -0
  108. package/admin-dist/server/_libs/react-remove-scroll-bar.mjs +82 -0
  109. package/admin-dist/server/_libs/react-remove-scroll.mjs +328 -0
  110. package/admin-dist/server/_libs/react-style-singleton.mjs +69 -0
  111. package/admin-dist/server/_libs/rou3.mjs +8 -0
  112. package/admin-dist/server/_libs/seroval-plugins.mjs +58 -0
  113. package/admin-dist/server/_libs/seroval.mjs +1765 -0
  114. package/admin-dist/server/_libs/srvx.mjs +719 -0
  115. package/admin-dist/server/_libs/tailwind-merge.mjs +3010 -0
  116. package/admin-dist/server/_libs/tiny-invariant.mjs +12 -0
  117. package/admin-dist/server/_libs/tiny-warning.mjs +5 -0
  118. package/admin-dist/server/_libs/tslib.mjs +39 -0
  119. package/admin-dist/server/_libs/ufo.mjs +54 -0
  120. package/admin-dist/server/_libs/unctx.mjs +1 -0
  121. package/admin-dist/server/_libs/unstorage.mjs +1 -0
  122. package/admin-dist/server/_libs/use-callback-ref.mjs +66 -0
  123. package/admin-dist/server/_libs/use-sidecar.mjs +106 -0
  124. package/admin-dist/server/_libs/use-sync-external-store.mjs +139 -0
  125. package/admin-dist/server/_libs/zod.mjs +4223 -0
  126. package/admin-dist/server/_ssr/CmsEmptyState-DU7-7-mV.mjs +290 -0
  127. package/admin-dist/server/_ssr/CmsPageHeader-CseW0AHm.mjs +24 -0
  128. package/admin-dist/server/_ssr/CmsStatusBadge-B_pi4KCp.mjs +127 -0
  129. package/admin-dist/server/_ssr/CmsToolbar-X75ex6ek.mjs +49 -0
  130. package/admin-dist/server/_ssr/ContentEntryEditor-CepusRsA.mjs +3720 -0
  131. package/admin-dist/server/_ssr/ErrorState-cI-bKLez.mjs +89 -0
  132. package/admin-dist/server/_ssr/TaxonomyFilter-Bwrq0-cz.mjs +188 -0
  133. package/admin-dist/server/_ssr/_contentTypeId-BqYKEcLr.mjs +379 -0
  134. package/admin-dist/server/_ssr/_entryId-CRfnqeDf.mjs +161 -0
  135. package/admin-dist/server/_ssr/_tanstack-start-manifest_v-BwDlABVk.mjs +4 -0
  136. package/admin-dist/server/_ssr/alert-CVt45UUP.mjs +92 -0
  137. package/admin-dist/server/_ssr/badge-6BsP37vG.mjs +125 -0
  138. package/admin-dist/server/_ssr/command-fy8epIKf.mjs +128 -0
  139. package/admin-dist/server/_ssr/config.server-D7JHDcDv.mjs +117 -0
  140. package/admin-dist/server/_ssr/content-B5RhL7uW.mjs +532 -0
  141. package/admin-dist/server/_ssr/content-types-BIOqCQYN.mjs +1166 -0
  142. package/admin-dist/server/_ssr/index-DHSHDPt1.mjs +193 -0
  143. package/admin-dist/server/_ssr/index.mjs +1275 -0
  144. package/admin-dist/server/_ssr/label-C8Dko1j7.mjs +22 -0
  145. package/admin-dist/server/_ssr/media-CSx3XttC.mjs +1832 -0
  146. package/admin-dist/server/_ssr/new._contentTypeId-DzanEZQM.mjs +144 -0
  147. package/admin-dist/server/_ssr/router-DDWcF-kt.mjs +1556 -0
  148. package/admin-dist/server/_ssr/scroll-area-bjPYwhXN.mjs +59 -0
  149. package/admin-dist/server/_ssr/select-BUhDDf4T.mjs +142 -0
  150. package/admin-dist/server/_ssr/settings-DAsxnw2q.mjs +348 -0
  151. package/admin-dist/server/_ssr/start-HYkvq4Ni.mjs +4 -0
  152. package/admin-dist/server/_ssr/switch-BgyRtQ1Z.mjs +31 -0
  153. package/admin-dist/server/_ssr/tabs-DzMdRB1A.mjs +628 -0
  154. package/admin-dist/server/_ssr/taxonomies-C8j8g5Q5.mjs +915 -0
  155. package/admin-dist/server/_ssr/textarea-9jNeYJSc.mjs +18 -0
  156. package/admin-dist/server/_ssr/trash-DYMxwhZB.mjs +291 -0
  157. package/admin-dist/server/_ssr/useBreadcrumbLabel-FNSAr2Ha.mjs +16 -0
  158. package/admin-dist/server/_ssr/usePermissions-BJGGahrJ.mjs +68 -0
  159. package/admin-dist/server/favicon.ico +0 -0
  160. package/admin-dist/server/index.mjs +627 -0
  161. package/dist/cli/index.js +0 -0
  162. package/dist/client/admin-config.d.ts +0 -1
  163. package/dist/client/admin-config.d.ts.map +1 -1
  164. package/dist/client/admin-config.js +0 -1
  165. package/dist/client/admin-config.js.map +1 -1
  166. package/dist/client/adminApi.d.ts.map +1 -1
  167. package/dist/client/agentTools.d.ts +1237 -135
  168. package/dist/client/agentTools.d.ts.map +1 -1
  169. package/dist/client/agentTools.js +33 -9
  170. package/dist/client/agentTools.js.map +1 -1
  171. package/dist/client/index.d.ts +1 -1
  172. package/dist/client/index.d.ts.map +1 -1
  173. package/dist/client/index.js.map +1 -1
  174. package/dist/component/_generated/component.d.ts +9 -0
  175. package/dist/component/_generated/component.d.ts.map +1 -1
  176. package/dist/component/mediaAssets.d.ts +35 -0
  177. package/dist/component/mediaAssets.d.ts.map +1 -1
  178. package/dist/component/mediaAssets.js +81 -0
  179. package/dist/component/mediaAssets.js.map +1 -1
  180. package/dist/test.d.ts.map +1 -1
  181. package/dist/test.js +2 -1
  182. package/dist/test.js.map +1 -1
  183. package/package.json +9 -5
  184. package/dist/component/auditLog.d.ts +0 -410
  185. package/dist/component/auditLog.d.ts.map +0 -1
  186. package/dist/component/auditLog.js +0 -607
  187. package/dist/component/auditLog.js.map +0 -1
  188. package/dist/component/types.d.ts +0 -4
  189. package/dist/component/types.d.ts.map +0 -1
  190. package/dist/component/types.js +0 -2
  191. package/dist/component/types.js.map +0 -1
  192. package/src/cli/commands/admin.ts +0 -104
  193. package/src/cli/index.ts +0 -21
  194. package/src/cli/utils/detectConvexUrl.ts +0 -54
  195. package/src/cli/utils/openBrowser.ts +0 -16
  196. package/src/client/admin-config.ts +0 -138
  197. package/src/client/adminApi.ts +0 -942
  198. package/src/client/agentTools.ts +0 -1311
  199. package/src/client/argTypes.ts +0 -316
  200. package/src/client/field-types.ts +0 -187
  201. package/src/client/index.ts +0 -1301
  202. package/src/client/queryBuilder.ts +0 -1100
  203. package/src/client/schema/codegen.ts +0 -500
  204. package/src/client/schema/defineContentType.ts +0 -501
  205. package/src/client/schema/index.ts +0 -169
  206. package/src/client/schema/schemaDrift.ts +0 -574
  207. package/src/client/schema/typedClient.ts +0 -688
  208. package/src/client/schema/types.ts +0 -666
  209. package/src/client/types.ts +0 -723
  210. package/src/client/workflows.ts +0 -141
  211. package/src/client/wrapper.ts +0 -4304
  212. package/src/component/_generated/api.ts +0 -140
  213. package/src/component/_generated/component.ts +0 -5029
  214. package/src/component/_generated/dataModel.ts +0 -60
  215. package/src/component/_generated/server.ts +0 -156
  216. package/src/component/authorization.ts +0 -647
  217. package/src/component/authorizationHooks.ts +0 -668
  218. package/src/component/bulkOperations.ts +0 -687
  219. package/src/component/contentEntries.ts +0 -1976
  220. package/src/component/contentEntryMutations.ts +0 -1223
  221. package/src/component/contentEntryValidation.ts +0 -707
  222. package/src/component/contentLock.ts +0 -550
  223. package/src/component/contentTypeMigration.ts +0 -1064
  224. package/src/component/contentTypeMutations.ts +0 -969
  225. package/src/component/contentTypes.ts +0 -346
  226. package/src/component/convex.config.ts +0 -44
  227. package/src/component/documentTypes.ts +0 -240
  228. package/src/component/eventEmitter.ts +0 -485
  229. package/src/component/exportImport.ts +0 -1169
  230. package/src/component/index.ts +0 -491
  231. package/src/component/lib/deepReferenceResolver.ts +0 -999
  232. package/src/component/lib/errors.ts +0 -816
  233. package/src/component/lib/index.ts +0 -145
  234. package/src/component/lib/mediaReferenceResolver.ts +0 -495
  235. package/src/component/lib/metadataExtractor.ts +0 -792
  236. package/src/component/lib/mutationAuth.ts +0 -199
  237. package/src/component/lib/queries.ts +0 -79
  238. package/src/component/lib/ragContentChunker.ts +0 -1371
  239. package/src/component/lib/referenceResolver.ts +0 -430
  240. package/src/component/lib/slugGenerator.ts +0 -262
  241. package/src/component/lib/slugUniqueness.ts +0 -333
  242. package/src/component/lib/softDelete.ts +0 -44
  243. package/src/component/localeFallbackChain.ts +0 -673
  244. package/src/component/localeFields.ts +0 -896
  245. package/src/component/mediaAssetMutations.ts +0 -725
  246. package/src/component/mediaAssets.ts +0 -932
  247. package/src/component/mediaFolderMutations.ts +0 -1046
  248. package/src/component/mediaUploadMutations.ts +0 -224
  249. package/src/component/mediaVariantMutations.ts +0 -900
  250. package/src/component/mediaVariants.ts +0 -793
  251. package/src/component/ragContentIndexer.ts +0 -1067
  252. package/src/component/rateLimitHooks.ts +0 -572
  253. package/src/component/roles.ts +0 -1360
  254. package/src/component/scheduledPublish.ts +0 -358
  255. package/src/component/schema.ts +0 -617
  256. package/src/component/taxonomies.ts +0 -949
  257. package/src/component/taxonomyMutations.ts +0 -1210
  258. package/src/component/trash.ts +0 -724
  259. package/src/component/userContext.ts +0 -898
  260. package/src/component/validation.ts +0 -1388
  261. package/src/component/validators.ts +0 -949
  262. package/src/component/versionMutations.ts +0 -392
  263. package/src/component/webhookTrigger.ts +0 -1922
  264. package/src/react/index.ts +0 -898
  265. package/src/test.ts +0 -1580
@@ -1,346 +0,0 @@
1
- /**
2
- * Content Type Query Functions
3
- *
4
- * Provides query functions for retrieving content type definitions from the CMS.
5
- * Content types are schema blueprints that define the structure of content entries.
6
- *
7
- * Available queries:
8
- * - `get`: Retrieve a single content type by ID or name
9
- * - `list`: List all content types with optional filtering, sorting, and pagination
10
- */
11
-
12
- import { v } from "convex/values";
13
- import { isDeleted } from "./lib/softDelete.js";
14
- import { paginationOptsValidator } from "convex/server";
15
- import { query } from "./_generated/server.js";
16
- import { contentTypeDoc } from "./validators.js";
17
-
18
- // =============================================================================
19
- // Constants
20
- // =============================================================================
21
-
22
- /**
23
- * Default number of items per page when not specified.
24
- */
25
- const DEFAULT_NUM_ITEMS = 50;
26
-
27
- /**
28
- * Maximum items per page to prevent excessive data fetching.
29
- */
30
- const MAX_NUM_ITEMS = 250;
31
-
32
- // =============================================================================
33
- // Get Content Type Query
34
- // =============================================================================
35
-
36
- /**
37
- * Arguments for retrieving a single content type.
38
- *
39
- * Either `id` or `name` must be provided, but not both.
40
- * - Use `id` for direct document lookup (most efficient)
41
- * - Use `name` for lookup by machine-readable name (uses by_name index)
42
- */
43
- const getContentTypeArgs = v.object({
44
- /** The ID of the content type to retrieve (direct lookup) */
45
- id: v.optional(v.id("contentTypes")),
46
- /** The machine-readable name of the content type (e.g., "blog_post") */
47
- name: v.optional(v.string()),
48
- /** Whether to include soft-deleted content types (default: false) */
49
- includeDeleted: v.optional(v.boolean()),
50
- });
51
-
52
- /**
53
- * Query to retrieve a single content type by ID or name.
54
- *
55
- * Returns the full content type definition including all field configurations.
56
- * This is useful for:
57
- * - Loading a content type's schema before creating entries
58
- * - Displaying content type information in admin interfaces
59
- * - Validating content against the type's field definitions
60
- *
61
- * @param id - The content type ID for direct lookup (most efficient)
62
- * @param name - The machine-readable name for index-based lookup
63
- * @param includeDeleted - Whether to return soft-deleted types (default: false)
64
- *
65
- * @returns The content type document, or null if not found
66
- *
67
- * @example
68
- * ```typescript
69
- * // Get by ID (fastest - direct document lookup)
70
- * const type = await ctx.runQuery(api.contentTypes.get, {
71
- * id: contentTypeId,
72
- * });
73
- *
74
- * // Get by name (uses by_name index)
75
- * const blogType = await ctx.runQuery(api.contentTypes.get, {
76
- * name: "blog_post",
77
- * });
78
- *
79
- * // Access field definitions
80
- * if (blogType) {
81
- * console.log("Fields:", blogType.fields);
82
- * console.log("Is singleton:", blogType.singleton);
83
- * }
84
- * ```
85
- */
86
- export const get = query({
87
- args: getContentTypeArgs.fields,
88
- returns: v.union(contentTypeDoc, v.null()),
89
- handler: async (ctx, args) => {
90
- const { id, name, includeDeleted = false } = args;
91
-
92
- // Validate that at least one identifier is provided
93
- if (!id && !name) {
94
- // Return null if neither id nor name is provided
95
- // This matches the pattern used in other get functions
96
- return null;
97
- }
98
-
99
- let contentType;
100
-
101
- // Lookup by ID (direct document access - O(1))
102
- if (id) {
103
- contentType = await ctx.db.get(id);
104
- }
105
- // Lookup by name using the by_name index
106
- else if (name) {
107
- contentType = await ctx.db
108
- .query("contentTypes")
109
- .withIndex("by_name", (q) => q.eq("name", name))
110
- .first();
111
- }
112
-
113
- // Return null if not found
114
- if (!contentType) {
115
- return null;
116
- }
117
-
118
- // Filter out soft-deleted types unless explicitly requested
119
- if (!includeDeleted && isDeleted(contentType)) {
120
- return null;
121
- }
122
-
123
- return contentType;
124
- },
125
- });
126
-
127
- // =============================================================================
128
- // List Content Types Query
129
- // =============================================================================
130
-
131
- /**
132
- * Sort field options for content type listing.
133
- */
134
- const sortByValidator = v.optional(
135
- v.union(v.literal("name"), v.literal("createdAt")),
136
- );
137
-
138
- /**
139
- * Sort direction options.
140
- */
141
- const sortDirectionValidator = v.optional(
142
- v.union(v.literal("asc"), v.literal("desc")),
143
- );
144
-
145
- /**
146
- * Arguments for listing content types with filtering and pagination.
147
- */
148
- const listContentTypesArgs = v.object({
149
- /** Filter by active status: true = active only, false = inactive only, undefined = all */
150
- isActive: v.optional(v.boolean()),
151
- /** Whether to include soft-deleted content types (default: false) */
152
- includeDeleted: v.optional(v.boolean()),
153
- /** Field to sort by: "name" (alphabetical) or "createdAt" (by creation date). Default: "name" */
154
- sortBy: sortByValidator,
155
- /** Sort direction: "asc" (ascending) or "desc" (descending). Default: "asc" for name, "desc" for createdAt */
156
- sortDirection: sortDirectionValidator,
157
- /**
158
- * Pagination options using standard Convex pagination format.
159
- * Compatible with usePaginatedQuery hook on the client.
160
- * If not provided, returns all matching results (non-paginated).
161
- */
162
- paginationOpts: v.optional(paginationOptsValidator),
163
- });
164
-
165
- /**
166
- * Paginated response using standard Convex PaginationResult format.
167
- */
168
- const paginatedContentTypesResponse = v.object({
169
- /** Array of content type documents for this page */
170
- page: v.array(contentTypeDoc),
171
- /** Cursor for fetching the next page (pass to next query's paginationOpts.cursor) */
172
- continueCursor: v.union(v.string(), v.null()),
173
- /** Whether this is the last page (no more results) */
174
- isDone: v.boolean(),
175
- });
176
-
177
- /**
178
- * Query to list all defined content types with optional filtering and sorting.
179
- *
180
- * Returns content type definitions sorted by name (alphabetically) or creation date.
181
- * Supports filtering by active status, soft-delete status, and cursor-based pagination.
182
- *
183
- * **Index Usage:**
184
- * - When filtering by `isActive`: Uses the `by_active` index for efficient filtering
185
- * - Without active filter: Performs a table scan (acceptable since content types are few)
186
- *
187
- * **Sorting Behavior:**
188
- * - `sortBy: "name"` (default): Sorts alphabetically by the machine-readable name
189
- * - `sortBy: "createdAt"`: Sorts by creation timestamp
190
- * - Default sort direction is "asc" for name, "desc" for createdAt
191
- *
192
- * @param isActive - Optional filter: true = active only, false = inactive only, undefined = all
193
- * @param includeDeleted - Whether to include soft-deleted types (default: false)
194
- * @param sortBy - Sort field: "name" (default) or "createdAt"
195
- * @param sortDirection - Sort direction: "asc" or "desc"
196
- * @param paginationOpts - Optional Convex pagination options (numItems, cursor)
197
- *
198
- * @returns PaginationResult with page, continueCursor, and isDone
199
- *
200
- * @example
201
- * ```typescript
202
- * // List all active content types sorted by name (most common use case)
203
- * const { page, continueCursor, isDone } = await ctx.runQuery(
204
- * components.convexCms.contentTypes.list,
205
- * {
206
- * isActive: true,
207
- * paginationOpts: { numItems: 20 },
208
- * }
209
- * );
210
- *
211
- * // List all content types sorted by creation date (newest first)
212
- * const newest = await ctx.runQuery(
213
- * components.convexCms.contentTypes.list,
214
- * {
215
- * sortBy: "createdAt",
216
- * sortDirection: "desc",
217
- * paginationOpts: { numItems: 10 },
218
- * }
219
- * );
220
- *
221
- * // List inactive content types only (for admin cleanup views)
222
- * const inactive = await ctx.runQuery(
223
- * components.convexCms.contentTypes.list,
224
- * {
225
- * isActive: false,
226
- * paginationOpts: { numItems: 50 },
227
- * }
228
- * );
229
- *
230
- * // Paginate through results using cursor
231
- * const page2 = await ctx.runQuery(
232
- * components.convexCms.contentTypes.list,
233
- * {
234
- * isActive: true,
235
- * paginationOpts: {
236
- * numItems: 20,
237
- * cursor: previousResult.continueCursor,
238
- * },
239
- * }
240
- * );
241
- *
242
- * // Use with usePaginatedQuery React hook
243
- * const { results, status, loadMore } = usePaginatedQuery(
244
- * api.contentTypes.list,
245
- * { isActive: true, sortBy: "name" },
246
- * { initialNumItems: 20 }
247
- * );
248
- *
249
- * // Non-paginated mode (returns all matching content types)
250
- * const allTypes = await ctx.runQuery(
251
- * components.convexCms.contentTypes.list,
252
- * { isActive: true }
253
- * );
254
- * console.log("Total types:", allTypes.page.length);
255
- * ```
256
- */
257
- export const list = query({
258
- args: listContentTypesArgs.fields,
259
- returns: paginatedContentTypesResponse,
260
- handler: async (ctx, args) => {
261
- const {
262
- isActive,
263
- includeDeleted = false,
264
- sortBy = "name",
265
- sortDirection,
266
- paginationOpts,
267
- } = args;
268
-
269
- // Determine default sort direction based on sortBy field
270
- // For name sorting, ascending (A-Z) is most intuitive
271
- // For date sorting, descending (newest first) is most intuitive
272
- const resolvedSortDirection =
273
- sortDirection ?? (sortBy === "name" ? "asc" : "desc");
274
-
275
- // Clamp numItems to valid range if pagination is requested
276
- const numItems = paginationOpts
277
- ? Math.min(
278
- Math.max(1, paginationOpts.numItems ?? DEFAULT_NUM_ITEMS),
279
- MAX_NUM_ITEMS,
280
- )
281
- : MAX_NUM_ITEMS; // When not paginating, fetch up to max
282
-
283
- // Build and execute query - choose strategy based on isActive filter
284
- let results;
285
-
286
- if (isActive !== undefined) {
287
- // Use by_active index for efficient filtering by active status
288
- results = await ctx.db
289
- .query("contentTypes")
290
- .withIndex("by_active", (q) => q.eq("isActive", isActive))
291
- .collect();
292
- } else {
293
- // Fetch all content types (no filter)
294
- results = await ctx.db.query("contentTypes").collect();
295
- }
296
-
297
- // Filter out soft-deleted types unless explicitly requested
298
- if (!includeDeleted) {
299
- results = results.filter((ct) => !isDeleted(ct));
300
- }
301
-
302
- // Apply sorting based on sortBy parameter
303
- if (sortBy === "name") {
304
- // Sort alphabetically by name (case-insensitive)
305
- results.sort((a, b) => {
306
- const nameA = a.name.toLowerCase();
307
- const nameB = b.name.toLowerCase();
308
- const comparison = nameA.localeCompare(nameB);
309
- return resolvedSortDirection === "asc" ? comparison : -comparison;
310
- });
311
- } else {
312
- // Sort by creation time
313
- results.sort((a, b) => {
314
- const comparison = a._creationTime - b._creationTime;
315
- return resolvedSortDirection === "asc" ? comparison : -comparison;
316
- });
317
- }
318
-
319
- // Handle cursor-based pagination
320
- let startIndex = 0;
321
- const cursor = paginationOpts?.cursor;
322
-
323
- if (cursor) {
324
- // Find the index of the cursor in results
325
- const cursorIndex = results.findIndex((ct) => ct._id === cursor);
326
- if (cursorIndex !== -1) {
327
- startIndex = cursorIndex + 1;
328
- }
329
- }
330
-
331
- // Get the page of results (fetch one extra to determine if there's more)
332
- const pageResults = results.slice(startIndex, startIndex + numItems + 1);
333
- const isDone = pageResults.length <= numItems;
334
- const page = isDone ? pageResults : pageResults.slice(0, numItems);
335
-
336
- // Calculate continuation cursor
337
- const continueCursor =
338
- !isDone && page.length > 0 ? page[page.length - 1]._id : null;
339
-
340
- return {
341
- page,
342
- continueCursor,
343
- isDone,
344
- };
345
- },
346
- });
@@ -1,44 +0,0 @@
1
- import { defineComponent } from "convex/server";
2
-
3
- /**
4
- * Convex CMS Component
5
- *
6
- * A developer-first content management system component with:
7
- * - Content type definitions with typed fields
8
- * - Content versioning and publishing workflows
9
- * - Media asset management
10
- * - Flexible RBAC
11
- * - Built-in AI tools for content management
12
- *
13
- *
14
- * @example
15
- * ```typescript
16
- * // In your app's convex/convex.config.ts:
17
- * import { defineApp } from "convex/server";
18
- * import convexCms from "@convex-cms/core/convex.config";
19
- *
20
- * const app = defineApp();
21
- * app.use(convexCms);
22
- *
23
- * export default app;
24
- * ```
25
- *
26
- * @example
27
- * ```typescript
28
- * // Using the component with configuration:
29
- * import { createCmsClient, type ComponentConfig } from "@convex-cms/core";
30
- *
31
- * const config: ComponentConfig = {
32
- * defaultLocale: "en-US",
33
- * features: {
34
- * versioning: true,
35
- * localization: true,
36
- * },
37
- * };
38
- *
39
- * export const cms = createCmsClient(components.convexCms, config);
40
- * ```
41
- */
42
- const component = defineComponent("convexCms");
43
-
44
- export default component;
@@ -1,240 +0,0 @@
1
- /**
2
- * Derived TypeScript Types for CMS Documents
3
- *
4
- * This module provides TypeScript types derived from validators using Convex's `Infer<>`.
5
- * These types are the single source of truth for document shapes throughout the codebase.
6
- *
7
- * Two type variants are provided:
8
- * 1. **Internal types** (with `Id<TableName>`) - For use within Convex functions
9
- * 2. **Client types** (with `string` IDs) - For use at API boundaries where IDs are serialized
10
- *
11
- * @example
12
- * ```typescript
13
- * // Internal use (within Convex functions)
14
- * import type { ContentTypeInternal } from "./documentTypes.js";
15
- * const type: ContentTypeInternal = await ctx.db.get(id);
16
- *
17
- * // Client use (API boundary)
18
- * import type { ContentType } from "./documentTypes.js";
19
- * const type: ContentType = await cms.contentTypes.get(ctx, { id });
20
- * ```
21
- */
22
-
23
- import type { Infer } from "convex/values";
24
- import type { GenericId } from "convex/values";
25
- import * as validators from "./validators.js";
26
-
27
- // =============================================================================
28
- // Utility Types
29
- // =============================================================================
30
-
31
- /**
32
- * Recursively converts all `Id<T>` types to `string` for API boundary serialization.
33
- * This is used when passing documents from Convex functions to client code,
34
- * where Convex IDs are serialized as strings.
35
- */
36
- export type StringifyIds<T> = T extends GenericId<infer _TableName>
37
- ? string
38
- : T extends (infer U)[]
39
- ? StringifyIds<U>[]
40
- : T extends Record<string, unknown>
41
- ? { [K in keyof T]: StringifyIds<T[K]> }
42
- : T;
43
-
44
- // =============================================================================
45
- // Internal Types (with Id<TableName>)
46
- // =============================================================================
47
-
48
- /**
49
- * Content type document - internal use with typed IDs.
50
- */
51
- export type ContentTypeInternal = Infer<typeof validators.contentTypeDoc>;
52
-
53
- /**
54
- * Content entry document - internal use with typed IDs.
55
- */
56
- export type ContentEntryInternal = Infer<typeof validators.contentEntryDoc>;
57
-
58
- /**
59
- * Content version document - internal use with typed IDs.
60
- */
61
- export type ContentVersionInternal = Infer<typeof validators.contentVersionDoc>;
62
-
63
- /**
64
- * Media item document (unified asset/folder) - internal use with typed IDs.
65
- */
66
- export type MediaItemInternal = Infer<typeof validators.mediaItemDoc>;
67
-
68
- /**
69
- * Media asset document - internal use with typed IDs.
70
- * Extracts only the asset variant from the MediaItem union.
71
- */
72
- export type MediaAssetInternal = Extract<MediaItemInternal, { kind: "asset" }>;
73
-
74
- /**
75
- * Media folder document - internal use with typed IDs.
76
- * Extracts only the folder variant from the MediaItem union.
77
- */
78
- export type MediaFolderInternal = Extract<MediaItemInternal, { kind: "folder" }>;
79
-
80
- /**
81
- * Media variant document - internal use with typed IDs.
82
- */
83
- export type MediaVariantInternal = Infer<typeof validators.mediaVariantDoc>;
84
-
85
- /**
86
- * Taxonomy document - internal use with typed IDs.
87
- */
88
- export type TaxonomyInternal = Infer<typeof validators.taxonomyDoc>;
89
-
90
- /**
91
- * Taxonomy term document - internal use with typed IDs.
92
- */
93
- export type TaxonomyTermInternal = Infer<typeof validators.taxonomyTermDoc>;
94
-
95
- /**
96
- * Content entry tag junction - internal use with typed IDs.
97
- */
98
- export type ContentEntryTagInternal = Infer<
99
- typeof validators.contentEntryTagDoc
100
- >;
101
-
102
- /**
103
- * CMS event document - internal use with typed IDs.
104
- */
105
- export type CmsEventInternal = Infer<typeof validators.cmsEventDoc>;
106
-
107
- /**
108
- * Trash config document - internal use with typed IDs.
109
- */
110
- export type TrashConfigInternal = Infer<typeof validators.trashConfigDoc>;
111
-
112
- /**
113
- * Webhook config document - internal use with typed IDs.
114
- */
115
- export type WebhookConfigInternal = Infer<typeof validators.webhookConfigDoc>;
116
-
117
- /**
118
- * Webhook delivery document - internal use with typed IDs.
119
- */
120
- export type WebhookDeliveryInternal = Infer<
121
- typeof validators.webhookDeliveryDoc
122
- >;
123
-
124
- // =============================================================================
125
- // Client Types (IDs as strings for API boundary)
126
- // =============================================================================
127
-
128
- /**
129
- * Content type - client-facing with string IDs.
130
- */
131
- export type ContentType = StringifyIds<ContentTypeInternal>;
132
-
133
- /**
134
- * Content entry - client-facing with string IDs.
135
- */
136
- export type ContentEntry = StringifyIds<ContentEntryInternal>;
137
-
138
- /**
139
- * Content version - client-facing with string IDs.
140
- */
141
- export type ContentVersion = StringifyIds<ContentVersionInternal>;
142
-
143
- /**
144
- * Media item (unified asset/folder) - client-facing with string IDs.
145
- */
146
- export type MediaItem = StringifyIds<MediaItemInternal>;
147
-
148
- /**
149
- * Media asset - client-facing with string IDs.
150
- * Extracts only the asset variant from the MediaItem union.
151
- */
152
- export type MediaAsset = Extract<MediaItem, { kind: "asset" }>;
153
-
154
- /**
155
- * Media folder - client-facing with string IDs.
156
- * Extracts only the folder variant from the MediaItem union.
157
- */
158
- export type MediaFolder = Extract<MediaItem, { kind: "folder" }>;
159
-
160
- /**
161
- * Media variant - client-facing with string IDs.
162
- */
163
- export type MediaVariant = StringifyIds<MediaVariantInternal>;
164
-
165
- /**
166
- * Taxonomy - client-facing with string IDs.
167
- */
168
- export type Taxonomy = StringifyIds<TaxonomyInternal>;
169
-
170
- /**
171
- * Taxonomy term - client-facing with string IDs.
172
- */
173
- export type TaxonomyTerm = StringifyIds<TaxonomyTermInternal>;
174
-
175
- /**
176
- * Content entry tag - client-facing with string IDs.
177
- */
178
- export type ContentEntryTag = StringifyIds<ContentEntryTagInternal>;
179
-
180
- /**
181
- * CMS event - client-facing with string IDs.
182
- */
183
- export type CmsEvent = StringifyIds<CmsEventInternal>;
184
-
185
- /**
186
- * Trash config - client-facing with string IDs.
187
- */
188
- export type TrashConfig = StringifyIds<TrashConfigInternal>;
189
-
190
- /**
191
- * Webhook config - client-facing with string IDs.
192
- */
193
- export type WebhookConfig = StringifyIds<WebhookConfigInternal>;
194
-
195
- /**
196
- * Webhook delivery - client-facing with string IDs.
197
- */
198
- export type WebhookDelivery = StringifyIds<WebhookDeliveryInternal>;
199
-
200
- // =============================================================================
201
- // Field Definition Types (Client-Facing)
202
- // =============================================================================
203
-
204
- /**
205
- * Internal field definition type (with typed IDs).
206
- */
207
- export type FieldDefinitionInternal = Infer<typeof validators.fieldDefinitionValidator>;
208
-
209
- /**
210
- * Client-facing field definition type (IDs as strings).
211
- * Used at the API boundary where Convex IDs are serialized as strings.
212
- */
213
- export type FieldDefinition = StringifyIds<FieldDefinitionInternal>;
214
-
215
- // =============================================================================
216
- // Extended Types
217
- // =============================================================================
218
-
219
- /**
220
- * Media variant with resolved URL.
221
- */
222
- export type MediaVariantWithUrl = MediaVariant & {
223
- url: string | null;
224
- };
225
-
226
- /**
227
- * Trash item with deletion metadata.
228
- */
229
- export type TrashItem = ContentEntry & {
230
- deletedDaysAgo: number;
231
- expiresAt?: number;
232
- contentTypeName?: string;
233
- };
234
-
235
- /**
236
- * Taxonomy term with children (for hierarchical display).
237
- */
238
- export type TaxonomyTermWithChildren = TaxonomyTerm & {
239
- children: TaxonomyTermWithChildren[];
240
- };