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