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,688 +0,0 @@
1
- /**
2
- * Schema-Aware Typed CMS Client
3
- *
4
- * This module provides type-safe access to content entries when a schema
5
- * is configured. The types are inferred from the Convex validators defined
6
- * in the schema.
7
- *
8
- * @example
9
- * ```typescript
10
- * import { v } from "convex/values";
11
- * import { defineContentType, createContentSchema, createTypedCmsClient } from "@convex-cms/core";
12
- * import { components } from "./_generated/api";
13
- *
14
- * // Define content types with validators
15
- * const blogPost = defineContentType({
16
- * name: "blog_post",
17
- * validator: v.object({ title: v.string(), content: v.string() }),
18
- * meta: { displayName: "Blog Post" },
19
- * });
20
- *
21
- * const contentSchema = createContentSchema({ blogPost });
22
- *
23
- * // Create a typed CMS client
24
- * export const cms = createTypedCmsClient(components.convexCms, {
25
- * schema: contentSchema,
26
- * });
27
- *
28
- * // Now methods return typed data
29
- * const post = await cms.contentEntries.get<"blog_post">(ctx, id);
30
- * post.data.title // ✅ string - TypeScript knows the type
31
- * post.data.typo // ❌ Error: Property 'typo' does not exist
32
- * ```
33
- */
34
-
35
- import type {
36
- ContentTypeDefinition,
37
- InferSchema,
38
- SchemaContentTypeNames,
39
- } from "./types.js";
40
- import type { ContentEntry, ContentStatus, PaginationOpts } from "../types.js";
41
- import type { ContentSchemaInstance } from "./defineContentType.js";
42
- import type { ConvexContext } from "../wrapper.js";
43
-
44
- // =============================================================================
45
- // Typed Content Entry Types
46
- // =============================================================================
47
-
48
- /**
49
- * A content entry with typed data based on the schema.
50
- *
51
- * @typeParam TData - The inferred data type from the content type's validator
52
- */
53
- export interface TypedContentEntry<TData extends Record<string, unknown>>
54
- extends Omit<ContentEntry, "data"> {
55
- /**
56
- * The content data with full type inference.
57
- */
58
- data: TData;
59
- }
60
-
61
- /**
62
- * A paginated result with typed content entries.
63
- */
64
- export interface TypedPaginationResult<TData extends Record<string, unknown>> {
65
- page: TypedContentEntry<TData>[];
66
- continueCursor: string | null;
67
- isDone: boolean;
68
- }
69
-
70
- // =============================================================================
71
- // Schema Type Utilities
72
- // =============================================================================
73
-
74
- /**
75
- * Extract the data type for a content type name from a schema.
76
- */
77
- export type SchemaDataType<
78
- TSchema extends ContentSchemaInstance<Record<string, ContentTypeDefinition>>,
79
- TName extends string
80
- > = TSchema extends ContentSchemaInstance<infer TDefs>
81
- ? TName extends keyof InferSchema<TDefs>
82
- ? InferSchema<TDefs>[TName] extends Record<string, unknown>
83
- ? InferSchema<TDefs>[TName]
84
- : Record<string, unknown>
85
- : Record<string, unknown>
86
- : Record<string, unknown>;
87
-
88
- /**
89
- * Extract all valid content type names from a schema.
90
- */
91
- export type ValidContentTypeName<
92
- TSchema extends ContentSchemaInstance<Record<string, ContentTypeDefinition>>
93
- > = TSchema extends ContentSchemaInstance<infer TDefs>
94
- ? SchemaContentTypeNames<TDefs>
95
- : string;
96
-
97
- // =============================================================================
98
- // Typed Content Entries API Interface
99
- // =============================================================================
100
-
101
- /**
102
- * Typed content entries API methods.
103
- *
104
- * These methods provide full type inference for content data when a schema
105
- * is configured.
106
- *
107
- * @typeParam TSchema - The content schema instance type
108
- */
109
- export interface TypedContentEntriesApi<
110
- TSchema extends ContentSchemaInstance<Record<string, ContentTypeDefinition>>
111
- > {
112
- /**
113
- * Get a content entry by ID with typed data.
114
- *
115
- * @param ctx - Convex context
116
- * @param id - The content entry ID
117
- * @returns The entry with typed data, or null if not found
118
- *
119
- * @example
120
- * ```typescript
121
- * const post = await cms.contentEntries.get<"blog_post">(ctx, id);
122
- * if (post) {
123
- * console.log(post.data.title); // ✅ TypeScript knows title is string
124
- * }
125
- * ```
126
- */
127
- get<TName extends ValidContentTypeName<TSchema>>(
128
- ctx: ConvexContext,
129
- id: string,
130
- ): Promise<TypedContentEntry<SchemaDataType<TSchema, TName>> | null>;
131
-
132
- /**
133
- * Get a content entry by slug with typed data.
134
- *
135
- * @param ctx - Convex context
136
- * @param options - Query options including contentTypeName and slug
137
- * @returns The entry with typed data, or null if not found
138
- */
139
- getBySlug<TName extends ValidContentTypeName<TSchema>>(
140
- ctx: ConvexContext,
141
- options: {
142
- contentTypeName: TName;
143
- slug: string;
144
- locale?: string;
145
- status?: ContentStatus | ContentStatus[];
146
- },
147
- ): Promise<TypedContentEntry<SchemaDataType<TSchema, TName>> | null>;
148
-
149
- /**
150
- * Create a new content entry with typed data.
151
- *
152
- * @param ctx - Convex context
153
- * @param options - Creation options including typed data
154
- * @returns The created entry with typed data
155
- *
156
- * @example
157
- * ```typescript
158
- * const post = await cms.contentEntries.create<"blog_post">(ctx, {
159
- * contentTypeName: "blog_post",
160
- * data: {
161
- * title: "Hello World", // ✅ TypeScript validates this
162
- * typo: "oops", // ❌ Error: 'typo' does not exist
163
- * },
164
- * });
165
- * ```
166
- */
167
- create<TName extends ValidContentTypeName<TSchema>>(
168
- ctx: ConvexContext,
169
- options: TypedCreateEntryOptions<TSchema, TName>,
170
- ): Promise<TypedContentEntry<SchemaDataType<TSchema, TName>>>;
171
-
172
- /**
173
- * Update an existing content entry with typed data.
174
- *
175
- * @param ctx - Convex context
176
- * @param options - Update options including partial typed data
177
- * @returns The updated entry with typed data
178
- */
179
- update<TName extends ValidContentTypeName<TSchema>>(
180
- ctx: ConvexContext,
181
- options: TypedUpdateEntryOptions<TSchema, TName>,
182
- ): Promise<TypedContentEntry<SchemaDataType<TSchema, TName>>>;
183
-
184
- /**
185
- * List content entries with typed data.
186
- *
187
- * @param ctx - Convex context
188
- * @param options - List options
189
- * @returns Paginated results with typed entries
190
- */
191
- list<TName extends ValidContentTypeName<TSchema>>(
192
- ctx: ConvexContext,
193
- options: TypedListEntriesOptions<TName>,
194
- ): Promise<TypedPaginationResult<SchemaDataType<TSchema, TName>>>;
195
- }
196
-
197
- // =============================================================================
198
- // Typed Method Options
199
- // =============================================================================
200
-
201
- /**
202
- * Options for creating a content entry with typed data.
203
- */
204
- export interface TypedCreateEntryOptions<
205
- TSchema extends ContentSchemaInstance<Record<string, ContentTypeDefinition>>,
206
- TName extends ValidContentTypeName<TSchema>
207
- > {
208
- /**
209
- * The content type name (must match a type in the schema).
210
- */
211
- contentTypeName: TName;
212
-
213
- /**
214
- * The content data (fully typed based on the content type's validator).
215
- */
216
- data: SchemaDataType<TSchema, TName>;
217
-
218
- /**
219
- * Optional slug (auto-generated if not provided).
220
- */
221
- slug?: string;
222
-
223
- /**
224
- * Optional locale for localized content.
225
- */
226
- locale?: string;
227
-
228
- /**
229
- * User ID of the creator.
230
- */
231
- createdBy?: string;
232
- }
233
-
234
- /**
235
- * Options for updating a content entry with typed data.
236
- */
237
- export interface TypedUpdateEntryOptions<
238
- TSchema extends ContentSchemaInstance<Record<string, ContentTypeDefinition>>,
239
- TName extends ValidContentTypeName<TSchema>
240
- > {
241
- /**
242
- * The content entry ID.
243
- */
244
- id: string;
245
-
246
- /**
247
- * Partial content data (typed based on the content type).
248
- */
249
- data?: Partial<SchemaDataType<TSchema, TName>>;
250
-
251
- /**
252
- * Optional updated slug.
253
- */
254
- slug?: string;
255
-
256
- /**
257
- * User ID of the updater.
258
- */
259
- updatedBy?: string;
260
- }
261
-
262
- /**
263
- * Options for listing content entries with typed results.
264
- */
265
- export interface TypedListEntriesOptions<TName extends string> {
266
- /**
267
- * Filter by content type name.
268
- */
269
- contentTypeName?: TName;
270
-
271
- /**
272
- * Filter by status.
273
- */
274
- status?: ContentStatus;
275
-
276
- /**
277
- * Filter by multiple statuses.
278
- */
279
- statusIn?: ContentStatus[];
280
-
281
- /**
282
- * Filter by locale.
283
- */
284
- locale?: string;
285
-
286
- /**
287
- * Search query.
288
- */
289
- search?: string;
290
-
291
- /**
292
- * Include soft-deleted entries.
293
- */
294
- includeDeleted?: boolean;
295
-
296
- /**
297
- * Pagination options.
298
- */
299
- paginationOpts: PaginationOpts;
300
- }
301
-
302
- // =============================================================================
303
- // Type Helpers for Schema Integration
304
- // =============================================================================
305
-
306
- /**
307
- * Helper type to check if a schema has a specific content type.
308
- */
309
- export type HasContentType<
310
- TSchema extends ContentSchemaInstance<Record<string, ContentTypeDefinition>>,
311
- TName extends string
312
- > = TName extends ValidContentTypeName<TSchema> ? true : false;
313
-
314
- /**
315
- * Utility type to get the definition for a specific content type.
316
- */
317
- export type GetContentTypeDefinition<
318
- TSchema extends ContentSchemaInstance<Record<string, ContentTypeDefinition>>,
319
- TName extends string
320
- > = TSchema extends ContentSchemaInstance<infer TDefs>
321
- ? {
322
- [K in keyof TDefs]: TDefs[K] extends ContentTypeDefinition<
323
- TName,
324
- infer _V
325
- >
326
- ? TDefs[K]
327
- : never;
328
- }[keyof TDefs]
329
- : never;
330
-
331
- // =============================================================================
332
- // Typed CMS Client Factory
333
- // =============================================================================
334
-
335
- import type { ComponentConfig } from "../types.js";
336
- import type { TypedComponentApi, CmsClient } from "../wrapper.js";
337
-
338
- /**
339
- * Configuration for creating a typed CMS client.
340
- */
341
- export interface TypedCmsClientConfig<
342
- TSchema extends ContentSchemaInstance<Record<string, ContentTypeDefinition>>
343
- > extends ComponentConfig {
344
- /**
345
- * The content schema instance containing type definitions.
346
- * Created using `createContentSchema()`.
347
- */
348
- schema: TSchema;
349
- }
350
-
351
- /**
352
- * A typed CMS client with schema-aware content entry methods.
353
- *
354
- * @typeParam TSchema - The content schema instance type
355
- */
356
- export interface TypedCmsClient<
357
- TSchema extends ContentSchemaInstance<Record<string, ContentTypeDefinition>>
358
- > extends CmsClient {
359
- /**
360
- * The content schema configured for this client.
361
- */
362
- readonly schema: TSchema;
363
-
364
- /**
365
- * Typed content entries API with methods that return properly typed data.
366
- */
367
- readonly typedContentEntries: TypedContentEntriesApiImpl<TSchema>;
368
- }
369
-
370
- /**
371
- * Implementation of typed content entries API.
372
- *
373
- * This provides typed wrappers around the base content entries API that
374
- * cast results to the appropriate types based on the schema.
375
- *
376
- * @typeParam TSchema - The content schema instance type
377
- */
378
- export class TypedContentEntriesApiImpl<
379
- TSchema extends ContentSchemaInstance<Record<string, ContentTypeDefinition>>
380
- > {
381
- private baseClient: CmsClient;
382
- private schema: TSchema;
383
-
384
- constructor(baseClient: CmsClient, schema: TSchema) {
385
- this.baseClient = baseClient;
386
- this.schema = schema;
387
- }
388
-
389
- /**
390
- * Get a content entry by ID with typed data.
391
- *
392
- * @param ctx - Convex context
393
- * @param id - The content entry ID
394
- * @returns The entry with typed data, or null if not found
395
- *
396
- * @example
397
- * ```typescript
398
- * const post = await cms.typedContentEntries.get<"blog_post">(ctx, id);
399
- * if (post) {
400
- * console.log(post.data.title); // ✅ TypeScript knows title is string
401
- * }
402
- * ```
403
- */
404
- async get<TName extends ValidContentTypeName<TSchema>>(
405
- ctx: ConvexContext,
406
- id: string,
407
- ): Promise<TypedContentEntry<SchemaDataType<TSchema, TName>> | null> {
408
- const entry = await this.baseClient.contentEntries.get(ctx, { id });
409
- if (!entry) return null;
410
-
411
- // Cast to typed entry - the data shape is validated at write time
412
- return (entry as unknown) as TypedContentEntry<
413
- SchemaDataType<TSchema, TName>
414
- >;
415
- }
416
-
417
- /**
418
- * Get a content entry by slug with typed data.
419
- *
420
- * @param ctx - Convex context
421
- * @param options - Query options including contentTypeName and slug
422
- * @returns The entry with typed data, or null if not found
423
- */
424
- async getBySlug<TName extends ValidContentTypeName<TSchema>>(
425
- ctx: ConvexContext,
426
- options: {
427
- contentTypeName: TName;
428
- slug: string;
429
- locale?: string;
430
- },
431
- ): Promise<TypedContentEntry<SchemaDataType<TSchema, TName>> | null> {
432
- const entry = await this.baseClient.contentEntries.getBySlug(ctx, {
433
- contentTypeName: options.contentTypeName,
434
- slug: options.slug,
435
- locale: options.locale,
436
- });
437
- if (!entry) return null;
438
-
439
- return (entry as unknown) as TypedContentEntry<
440
- SchemaDataType<TSchema, TName>
441
- >;
442
- }
443
-
444
- /**
445
- * Create a new content entry with typed data.
446
- *
447
- * @param ctx - Convex context
448
- * @param options - Creation options including typed data
449
- * @returns The created entry with typed data
450
- *
451
- * @example
452
- * ```typescript
453
- * const post = await cms.typedContentEntries.create<"blog_post">(ctx, {
454
- * contentTypeName: "blog_post",
455
- * data: {
456
- * title: "Hello World", // ✅ TypeScript validates this
457
- * content: "...",
458
- * },
459
- * });
460
- * ```
461
- */
462
- async create<TName extends ValidContentTypeName<TSchema>>(
463
- ctx: ConvexContext,
464
- options: TypedCreateEntryOptions<TSchema, TName>,
465
- ): Promise<TypedContentEntry<SchemaDataType<TSchema, TName>>> {
466
- // Look up the content type by name to get its ID
467
- const contentType = await this.baseClient.contentTypes.getByName(
468
- ctx,
469
- options.contentTypeName as string,
470
- );
471
-
472
- if (!contentType) {
473
- throw new Error(`Content type "${options.contentTypeName}" not found`);
474
- }
475
-
476
- const entry = await this.baseClient.contentEntries.create(ctx, {
477
- contentTypeId: contentType._id,
478
- data: options.data as Record<string, unknown>,
479
- slug: options.slug,
480
- locale: options.locale,
481
- createdBy: options.createdBy,
482
- });
483
-
484
- return (entry as unknown) as TypedContentEntry<
485
- SchemaDataType<TSchema, TName>
486
- >;
487
- }
488
-
489
- /**
490
- * Update an existing content entry with typed data.
491
- *
492
- * @param ctx - Convex context
493
- * @param options - Update options including partial typed data
494
- * @returns The updated entry with typed data
495
- */
496
- async update<TName extends ValidContentTypeName<TSchema>>(
497
- ctx: ConvexContext,
498
- options: TypedUpdateEntryOptions<TSchema, TName>,
499
- ): Promise<TypedContentEntry<SchemaDataType<TSchema, TName>>> {
500
- const entry = await this.baseClient.contentEntries.update(ctx, {
501
- id: options.id,
502
- data: options.data as Record<string, unknown> | undefined,
503
- slug: options.slug,
504
- updatedBy: options.updatedBy,
505
- });
506
-
507
- return (entry as unknown) as TypedContentEntry<
508
- SchemaDataType<TSchema, TName>
509
- >;
510
- }
511
-
512
- /**
513
- * List content entries with typed data.
514
- *
515
- * @param ctx - Convex context
516
- * @param options - List options
517
- * @returns Paginated results with typed entries
518
- */
519
- async list<TName extends ValidContentTypeName<TSchema>>(
520
- ctx: ConvexContext,
521
- options: TypedListEntriesOptions<TName>,
522
- ): Promise<TypedPaginationResult<SchemaDataType<TSchema, TName>>> {
523
- // If filtering by content type name, look up the content type ID
524
- let contentTypeId: string | undefined;
525
- if (options.contentTypeName) {
526
- const contentType = await this.baseClient.contentTypes.getByName(
527
- ctx,
528
- options.contentTypeName as string,
529
- );
530
- if (contentType) {
531
- contentTypeId = contentType._id;
532
- }
533
- }
534
-
535
- const result = await this.baseClient.contentEntries.list(ctx, {
536
- contentTypeId,
537
- status: options.status,
538
- statusIn: options.statusIn,
539
- locale: options.locale,
540
- search: options.search,
541
- includeDeleted: options.includeDeleted,
542
- paginationOpts: options.paginationOpts,
543
- });
544
-
545
- return {
546
- page: (result.page as unknown) as TypedContentEntry<
547
- SchemaDataType<TSchema, TName>
548
- >[],
549
- continueCursor: result.continueCursor,
550
- isDone: result.isDone,
551
- };
552
- }
553
-
554
- /**
555
- * Publish a content entry.
556
- *
557
- * @param ctx - Convex context
558
- * @param id - The entry ID to publish
559
- * @param updatedBy - Optional user ID who triggered the publish
560
- * @returns The published entry with typed data
561
- */
562
- async publish<TName extends ValidContentTypeName<TSchema>>(
563
- ctx: ConvexContext,
564
- id: string,
565
- updatedBy?: string,
566
- ): Promise<TypedContentEntry<SchemaDataType<TSchema, TName>>> {
567
- const entry = await this.baseClient.contentEntries.publish(ctx, {
568
- id,
569
- updatedBy,
570
- });
571
-
572
- return (entry as unknown) as TypedContentEntry<
573
- SchemaDataType<TSchema, TName>
574
- >;
575
- }
576
-
577
- /**
578
- * Unpublish a content entry.
579
- *
580
- * @param ctx - Convex context
581
- * @param id - The entry ID to unpublish
582
- * @param updatedBy - Optional user ID who triggered the unpublish
583
- * @returns The unpublished entry with typed data
584
- */
585
- async unpublish<TName extends ValidContentTypeName<TSchema>>(
586
- ctx: ConvexContext,
587
- id: string,
588
- updatedBy?: string,
589
- ): Promise<TypedContentEntry<SchemaDataType<TSchema, TName>>> {
590
- const entry = await this.baseClient.contentEntries.unpublish(ctx, {
591
- id,
592
- updatedBy,
593
- });
594
-
595
- return (entry as unknown) as TypedContentEntry<
596
- SchemaDataType<TSchema, TName>
597
- >;
598
- }
599
-
600
- /**
601
- * Get the schema configured for this typed client.
602
- */
603
- getSchema(): TSchema {
604
- return this.schema;
605
- }
606
-
607
- /**
608
- * Validate that a content type exists in the schema.
609
- *
610
- * @param name - The content type name to validate
611
- * @returns true if the content type exists
612
- */
613
- hasContentType(name: string): boolean {
614
- return this.schema.hasContentType(name);
615
- }
616
- }
617
-
618
- /**
619
- * Creates a typed CMS client with schema-aware content entry methods.
620
- *
621
- * This is the main entry point for using type-safe content operations.
622
- * The returned client extends the base `CmsClient` with additional
623
- * `typedContentEntries` methods that provide full TypeScript inference.
624
- *
625
- * @param componentApi - The component API from `components.convexCms`
626
- * @param config - Configuration including the content schema
627
- * @returns A typed CMS client instance
628
- *
629
- * @example
630
- * ```typescript
631
- * import { v } from "convex/values";
632
- * import { defineContentType, createContentSchema, createTypedCmsClient } from "@convex-cms/core";
633
- * import { components } from "./_generated/api";
634
- *
635
- * // Define content types
636
- * const blogPost = defineContentType({
637
- * name: "blog_post",
638
- * validator: v.object({
639
- * title: v.string(),
640
- * content: v.string(),
641
- * }),
642
- * meta: { displayName: "Blog Post" },
643
- * });
644
- *
645
- * const contentSchema = createContentSchema({ blogPost });
646
- *
647
- * // Create a typed client
648
- * export const cms = createTypedCmsClient(components.convexCms, {
649
- * schema: contentSchema,
650
- * });
651
- *
652
- * // Use with full type inference
653
- * const post = await cms.typedContentEntries.get<"blog_post">(ctx, id);
654
- * post.data.title; // ✅ string
655
- * post.data.typo; // ❌ Error: Property 'typo' does not exist
656
- * ```
657
- */
658
- export function createTypedCmsClient<
659
- TSchema extends ContentSchemaInstance<Record<string, ContentTypeDefinition>>
660
- >(
661
- componentApi: TypedComponentApi,
662
- config: TypedCmsClientConfig<TSchema>,
663
- ): TypedCmsClient<TSchema> {
664
- // Import createCmsClient dynamically to avoid circular imports
665
- // The actual import happens at runtime
666
- const { createCmsClient } = require("../index.js") as {
667
- createCmsClient: (
668
- api: TypedComponentApi,
669
- config?: ComponentConfig,
670
- ) => CmsClient;
671
- };
672
-
673
- // Create the base client with the provided config
674
- const baseClient = createCmsClient(componentApi, config);
675
-
676
- // Create the typed content entries API
677
- const typedContentEntries = new TypedContentEntriesApiImpl(
678
- baseClient,
679
- config.schema,
680
- );
681
-
682
- // Return an extended client with the typed API
683
- return {
684
- ...baseClient,
685
- schema: config.schema,
686
- typedContentEntries,
687
- };
688
- }