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,668 @@
|
|
|
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
|
+
// Export types for external use
|
|
83
|
+
export * from "./types.js";
|
|
84
|
+
// --- Admin API Helper ---
|
|
85
|
+
export { defineAdminAPI, } from "./adminApi.js";
|
|
86
|
+
// --- CMS Client Factory ---
|
|
87
|
+
import { resolveConfig, validateRequiredHooks, } from "./types.js";
|
|
88
|
+
import { ContentTypesApi, ContentEntriesApi, VersionsApi, MediaAssetsApi, MediaFoldersApi, MediaVariantsApi, } from "./wrapper.js";
|
|
89
|
+
// Re-export authorization hooks execution utilities
|
|
90
|
+
export { executeAuthorizationHooks, operationToRbac, contextToRbacOptions, createContentEntryAuthContext, requireAuthorization as requireAuthorizationHook, } from "../component/authorizationHooks.js";
|
|
91
|
+
// Re-export core authorization and ownership utilities
|
|
92
|
+
export {
|
|
93
|
+
// Error class
|
|
94
|
+
UnauthorizedError,
|
|
95
|
+
// Core permission checking
|
|
96
|
+
checkPermission, requirePermission,
|
|
97
|
+
// Ownership validation helpers
|
|
98
|
+
isResourceOwner, requireResourceOwnership,
|
|
99
|
+
// Authorization context helpers
|
|
100
|
+
createAuthContext, canPerform, mustPerform, } from "../component/authorization.js";
|
|
101
|
+
// Re-export user context handler utilities
|
|
102
|
+
export {
|
|
103
|
+
// Error class
|
|
104
|
+
UserContextError,
|
|
105
|
+
// Validation functions
|
|
106
|
+
isValidUserId, isValidRole, validateUserContextInput,
|
|
107
|
+
// User context creation
|
|
108
|
+
resolveUserRole, createUserContext, createUserContextSync,
|
|
109
|
+
// User ID extraction
|
|
110
|
+
extractUserId, extractUserIdFromAuth,
|
|
111
|
+
// Authorization context builders
|
|
112
|
+
buildAuthorizationContext, createAnonymousContext, createSystemContext,
|
|
113
|
+
// Utility functions
|
|
114
|
+
isAuthenticated, hasUserRole, isSystemContext, getUserDisplayId, validateUserContext, } from "../component/userContext.js";
|
|
115
|
+
import { executeAuthorizationHooks, operationToRbac, contextToRbacOptions, } from "../component/authorizationHooks.js";
|
|
116
|
+
import { UnauthorizedError as InternalUnauthorizedError } from "../component/authorization.js";
|
|
117
|
+
import { hasPermission, hasContentTypePermission, getPermittedContentTypes, DEFAULT_ROLES, } from "../component/roles.js";
|
|
118
|
+
// Import locale fallback chain utilities
|
|
119
|
+
import { resolveFallbackChain, getFallbackChain, } from "../component/localeFallbackChain.js";
|
|
120
|
+
// Re-export wrapper types and classes
|
|
121
|
+
export * from "./wrapper.js";
|
|
122
|
+
// Re-export query builder types and classes
|
|
123
|
+
export { ContentQueryBuilder, createQueryBuilder, } from "./queryBuilder.js";
|
|
124
|
+
/**
|
|
125
|
+
* Creates an enhanced CMS client with typed method wrappers.
|
|
126
|
+
*
|
|
127
|
+
* This is the main entry point for using the Convex CMS component.
|
|
128
|
+
* The returned client provides typed methods for all CMS operations,
|
|
129
|
+
* making it easy to interact with the CMS from your Convex functions.
|
|
130
|
+
*
|
|
131
|
+
* @param componentApi - The component API from `components.convexCms`
|
|
132
|
+
* @param config - Optional configuration options
|
|
133
|
+
* @returns An enhanced CMS client instance with typed methods
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* import { createCmsClient } from "@convex-cms/core";
|
|
138
|
+
* import { components } from "./_generated/api";
|
|
139
|
+
*
|
|
140
|
+
* // Create with default configuration
|
|
141
|
+
* export const cms = createCmsClient(components.convexCms);
|
|
142
|
+
*
|
|
143
|
+
* // Create with custom configuration
|
|
144
|
+
* export const cms = createCmsClient(components.convexCms, {
|
|
145
|
+
* defaultLocale: "en-US",
|
|
146
|
+
* supportedLocales: ["en-US", "es-ES", "fr-FR"],
|
|
147
|
+
* features: {
|
|
148
|
+
* versioning: true,
|
|
149
|
+
* localization: true,
|
|
150
|
+
* scheduling: true,
|
|
151
|
+
* },
|
|
152
|
+
* maxVersionsPerEntry: 100,
|
|
153
|
+
* });
|
|
154
|
+
* ```
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* // Use typed methods in mutations
|
|
159
|
+
* export const createPost = mutation({
|
|
160
|
+
* args: { title: v.string() },
|
|
161
|
+
* handler: async (ctx, args) => {
|
|
162
|
+
* // Create a content type
|
|
163
|
+
* const blogType = await cms.contentTypes.create(ctx, {
|
|
164
|
+
* name: "blog_post",
|
|
165
|
+
* displayName: "Blog Post",
|
|
166
|
+
* fields: [
|
|
167
|
+
* { name: "title", label: "Title", type: "text", required: true },
|
|
168
|
+
* ],
|
|
169
|
+
* });
|
|
170
|
+
*
|
|
171
|
+
* // Create an entry
|
|
172
|
+
* const entry = await cms.contentEntries.create(ctx, {
|
|
173
|
+
* contentTypeId: blogType._id,
|
|
174
|
+
* data: { title: args.title },
|
|
175
|
+
* });
|
|
176
|
+
*
|
|
177
|
+
* // Publish the entry
|
|
178
|
+
* return await cms.contentEntries.publish(ctx, { id: entry._id });
|
|
179
|
+
* },
|
|
180
|
+
* });
|
|
181
|
+
* ```
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* // Check feature flags
|
|
186
|
+
* if (cms.isFeatureEnabled("localization")) {
|
|
187
|
+
* // Handle localized content
|
|
188
|
+
* }
|
|
189
|
+
*
|
|
190
|
+
* if (cms.isLocaleSupported("es-ES")) {
|
|
191
|
+
* // Locale is valid
|
|
192
|
+
* }
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
export function createCmsClient(componentApi, config) {
|
|
196
|
+
// Validate required hooks at initialization time (fail-fast)
|
|
197
|
+
validateRequiredHooks(config);
|
|
198
|
+
// Register custom field types if provided
|
|
199
|
+
if (config?.fieldTypes && config.fieldTypes.length > 0) {
|
|
200
|
+
const { registerFieldTypes } = require("./field-types.js");
|
|
201
|
+
registerFieldTypes(config.fieldTypes);
|
|
202
|
+
}
|
|
203
|
+
const resolvedConfig = resolveConfig(config);
|
|
204
|
+
// Store the getUserRole hook from the original config (not resolved)
|
|
205
|
+
const getUserRoleHook = config?.getUserRole;
|
|
206
|
+
// Store authorization hooks from config
|
|
207
|
+
const authHooks = config?.authorizationHooks;
|
|
208
|
+
// Create authorization helper for API classes (only if getUserRole is configured)
|
|
209
|
+
const authHelper = getUserRoleHook
|
|
210
|
+
? {
|
|
211
|
+
async getUserRole(ctx, userId) {
|
|
212
|
+
// Pass ctx to the hook so it can access parent app's database and auth
|
|
213
|
+
return getUserRoleHook(ctx, { userId });
|
|
214
|
+
},
|
|
215
|
+
async requireAuthorization(ctx, context) {
|
|
216
|
+
// Augment the context with ctx for hooks to access
|
|
217
|
+
const fullContext = {
|
|
218
|
+
...context,
|
|
219
|
+
ctx: ctx,
|
|
220
|
+
};
|
|
221
|
+
const rbacOptions = contextToRbacOptions(fullContext);
|
|
222
|
+
const result = await executeAuthorizationHooks({
|
|
223
|
+
hooks: authHooks,
|
|
224
|
+
context: fullContext,
|
|
225
|
+
rbacOptions: rbacOptions ?? undefined,
|
|
226
|
+
skipRbac: resolvedConfig.skipRbac,
|
|
227
|
+
});
|
|
228
|
+
if (!result.allowed) {
|
|
229
|
+
const rbacMapping = operationToRbac(fullContext.operation);
|
|
230
|
+
throw new InternalUnauthorizedError(result.reason ?? "Operation not allowed", {
|
|
231
|
+
code: result.rbacResult?.allowed === false
|
|
232
|
+
? result.rbacResult.code
|
|
233
|
+
: "PERMISSION_DENIED",
|
|
234
|
+
resource: rbacMapping?.resource,
|
|
235
|
+
action: rbacMapping?.action,
|
|
236
|
+
role: fullContext.role ?? undefined,
|
|
237
|
+
userId: fullContext.userId,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
return result;
|
|
241
|
+
},
|
|
242
|
+
skipRbac: resolvedConfig.skipRbac ?? false,
|
|
243
|
+
}
|
|
244
|
+
: undefined;
|
|
245
|
+
return {
|
|
246
|
+
config: resolvedConfig,
|
|
247
|
+
api: componentApi,
|
|
248
|
+
contentTypes: new ContentTypesApi(componentApi, resolvedConfig, authHelper),
|
|
249
|
+
contentEntries: new ContentEntriesApi(componentApi, resolvedConfig, authHelper),
|
|
250
|
+
versions: new VersionsApi(componentApi, resolvedConfig, authHelper),
|
|
251
|
+
mediaAssets: new MediaAssetsApi(componentApi, resolvedConfig, authHelper),
|
|
252
|
+
mediaFolders: new MediaFoldersApi(componentApi, resolvedConfig, authHelper),
|
|
253
|
+
mediaVariants: new MediaVariantsApi(componentApi, resolvedConfig),
|
|
254
|
+
isFeatureEnabled(feature) {
|
|
255
|
+
return resolvedConfig.features[feature] ?? false;
|
|
256
|
+
},
|
|
257
|
+
isLocaleSupported(locale) {
|
|
258
|
+
return resolvedConfig.supportedLocales.includes(locale);
|
|
259
|
+
},
|
|
260
|
+
hasUserRoleHook() {
|
|
261
|
+
return getUserRoleHook !== undefined;
|
|
262
|
+
},
|
|
263
|
+
hasAuthorizationHooks() {
|
|
264
|
+
if (!authHooks)
|
|
265
|
+
return false;
|
|
266
|
+
return !!(authHooks.beforeRbac ||
|
|
267
|
+
authHooks.afterRbac ||
|
|
268
|
+
authHooks.authorize ||
|
|
269
|
+
authHooks.onDeny ||
|
|
270
|
+
(authHooks.operationHooks && Object.keys(authHooks.operationHooks).length > 0));
|
|
271
|
+
},
|
|
272
|
+
async getUserRole(ctx, userId) {
|
|
273
|
+
if (!getUserRoleHook) {
|
|
274
|
+
throw new Error("No getUserRole hook configured. " +
|
|
275
|
+
"Configure a getUserRole function in createCmsClient options to map user IDs to CMS roles.");
|
|
276
|
+
}
|
|
277
|
+
return await getUserRoleHook(ctx, { userId });
|
|
278
|
+
},
|
|
279
|
+
async hasPermissionForUser(ctx, userId, permission, options) {
|
|
280
|
+
if (!getUserRoleHook) {
|
|
281
|
+
throw new Error("No getUserRole hook configured. " +
|
|
282
|
+
"Configure a getUserRole function in createCmsClient options to map user IDs to CMS roles.");
|
|
283
|
+
}
|
|
284
|
+
const role = await getUserRoleHook(ctx, { userId });
|
|
285
|
+
// If user has no role, they have no permissions
|
|
286
|
+
if (role === null) {
|
|
287
|
+
return {
|
|
288
|
+
allowed: false,
|
|
289
|
+
role: null,
|
|
290
|
+
permission,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
// Merge custom roles from config with any passed options
|
|
294
|
+
const mergedCustomRoles = {
|
|
295
|
+
...resolvedConfig.customRoles,
|
|
296
|
+
...options?.customRoles,
|
|
297
|
+
};
|
|
298
|
+
// Check if the role has the requested permission
|
|
299
|
+
const allowed = hasPermission(role, permission, mergedCustomRoles);
|
|
300
|
+
return {
|
|
301
|
+
allowed,
|
|
302
|
+
role,
|
|
303
|
+
permission,
|
|
304
|
+
};
|
|
305
|
+
},
|
|
306
|
+
async authorize(context) {
|
|
307
|
+
// Build RBAC options from context
|
|
308
|
+
const rbacOptions = contextToRbacOptions(context);
|
|
309
|
+
return executeAuthorizationHooks({
|
|
310
|
+
hooks: authHooks,
|
|
311
|
+
context,
|
|
312
|
+
rbacOptions: rbacOptions ?? undefined,
|
|
313
|
+
skipRbac: resolvedConfig.skipRbac,
|
|
314
|
+
});
|
|
315
|
+
},
|
|
316
|
+
async requireAuthorization(context) {
|
|
317
|
+
const result = await this.authorize(context);
|
|
318
|
+
if (!result.allowed) {
|
|
319
|
+
const rbacMapping = operationToRbac(context.operation);
|
|
320
|
+
throw new InternalUnauthorizedError(result.reason ?? "Operation not allowed", {
|
|
321
|
+
code: result.rbacResult?.allowed === false
|
|
322
|
+
? result.rbacResult.code
|
|
323
|
+
: "PERMISSION_DENIED",
|
|
324
|
+
resource: rbacMapping?.resource,
|
|
325
|
+
action: rbacMapping?.action,
|
|
326
|
+
role: context.role ?? undefined,
|
|
327
|
+
userId: context.userId,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
return result;
|
|
331
|
+
},
|
|
332
|
+
// ==========================================================================
|
|
333
|
+
// ==========================================================================
|
|
334
|
+
// Consolidated Locale API (Simplified)
|
|
335
|
+
// ==========================================================================
|
|
336
|
+
/**
|
|
337
|
+
* Consolidated locale API with 3 core methods.
|
|
338
|
+
*
|
|
339
|
+
* Prefer using this namespace over the individual methods below.
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```typescript
|
|
343
|
+
* // Get locale configuration
|
|
344
|
+
* const config = cms.locale.getConfig();
|
|
345
|
+
* console.log(config.defaultLocale); // "en"
|
|
346
|
+
*
|
|
347
|
+
* // Get fallback chain for a locale
|
|
348
|
+
* const chain = cms.locale.getFallbackChain("es-MX");
|
|
349
|
+
* // ["es-ES", "en-US", "en"]
|
|
350
|
+
*
|
|
351
|
+
* // Resolve locale with full metadata
|
|
352
|
+
* const resolved = cms.locale.resolve("es-MX");
|
|
353
|
+
* // { requestedLocale: "es-MX", fallbackChain: [...], ... }
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
356
|
+
locale: {
|
|
357
|
+
/**
|
|
358
|
+
* Get the full locale configuration.
|
|
359
|
+
*
|
|
360
|
+
* @returns The configured locale settings including default locale,
|
|
361
|
+
* supported locales, and fallback chains.
|
|
362
|
+
*/
|
|
363
|
+
getConfig() {
|
|
364
|
+
return {
|
|
365
|
+
defaultLocale: resolvedConfig.defaultLocale,
|
|
366
|
+
fallbackChains: resolvedConfig.localeFallbackChains,
|
|
367
|
+
autoGenerateFallbacks: resolvedConfig.autoGenerateLocaleFallbacks,
|
|
368
|
+
supportedLocales: resolvedConfig.supportedLocales,
|
|
369
|
+
};
|
|
370
|
+
},
|
|
371
|
+
/**
|
|
372
|
+
* Get the fallback chain for a locale.
|
|
373
|
+
*
|
|
374
|
+
* Returns an array of locale codes to try in order when content
|
|
375
|
+
* is not available in the requested locale.
|
|
376
|
+
*
|
|
377
|
+
* @param locale - The locale code (e.g., "es-MX")
|
|
378
|
+
* @returns Array of fallback locale codes
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
* ```typescript
|
|
382
|
+
* cms.locale.getFallbackChain("es-MX");
|
|
383
|
+
* // Returns: ["es-ES", "es", "en"]
|
|
384
|
+
* ```
|
|
385
|
+
*/
|
|
386
|
+
getFallbackChain(locale) {
|
|
387
|
+
const fallbackConfig = this.getConfig();
|
|
388
|
+
return getFallbackChain(locale, fallbackConfig);
|
|
389
|
+
},
|
|
390
|
+
/**
|
|
391
|
+
* Resolve a locale with full metadata.
|
|
392
|
+
*
|
|
393
|
+
* Returns detailed information about the locale resolution including
|
|
394
|
+
* the fallback chain, whether it's supported, and parsing info.
|
|
395
|
+
*
|
|
396
|
+
* @param locale - The locale code to resolve
|
|
397
|
+
* @returns Resolved fallback chain with metadata
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* ```typescript
|
|
401
|
+
* const resolved = cms.locale.resolve("es-MX");
|
|
402
|
+
* // Returns: {
|
|
403
|
+
* // requestedLocale: "es-MX",
|
|
404
|
+
* // fallbackChain: ["es-MX", "es-ES", "es", "en"],
|
|
405
|
+
* // isSupported: true,
|
|
406
|
+
* // ...
|
|
407
|
+
* // }
|
|
408
|
+
* ```
|
|
409
|
+
*/
|
|
410
|
+
resolve(locale) {
|
|
411
|
+
const fallbackConfig = this.getConfig();
|
|
412
|
+
return resolveFallbackChain(locale, fallbackConfig);
|
|
413
|
+
},
|
|
414
|
+
},
|
|
415
|
+
// ==========================================================================
|
|
416
|
+
// Custom Roles Methods
|
|
417
|
+
// ==========================================================================
|
|
418
|
+
getCustomRoles() {
|
|
419
|
+
return resolvedConfig.customRoles;
|
|
420
|
+
},
|
|
421
|
+
getCustomRole(roleName) {
|
|
422
|
+
return resolvedConfig.customRoles[roleName];
|
|
423
|
+
},
|
|
424
|
+
isCustomRole(roleName) {
|
|
425
|
+
return roleName in resolvedConfig.customRoles;
|
|
426
|
+
},
|
|
427
|
+
async hasContentTypePermissionForUser(ctx, userId, permission, contentTypeName) {
|
|
428
|
+
if (!getUserRoleHook) {
|
|
429
|
+
throw new Error("No getUserRole hook configured. " +
|
|
430
|
+
"Configure a getUserRole function in createCmsClient options to map user IDs to CMS roles.");
|
|
431
|
+
}
|
|
432
|
+
const role = await getUserRoleHook(ctx, { userId });
|
|
433
|
+
if (role === null) {
|
|
434
|
+
return {
|
|
435
|
+
allowed: false,
|
|
436
|
+
role: null,
|
|
437
|
+
permission,
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
// Use the content-type-aware permission check
|
|
441
|
+
const allowed = hasContentTypePermission(role, permission, {
|
|
442
|
+
customRoles: resolvedConfig.customRoles,
|
|
443
|
+
contentTypeName,
|
|
444
|
+
});
|
|
445
|
+
return {
|
|
446
|
+
allowed,
|
|
447
|
+
role,
|
|
448
|
+
permission,
|
|
449
|
+
};
|
|
450
|
+
},
|
|
451
|
+
async getPermittedContentTypesForUser(ctx, userId, action) {
|
|
452
|
+
if (!getUserRoleHook) {
|
|
453
|
+
throw new Error("No getUserRole hook configured. " +
|
|
454
|
+
"Configure a getUserRole function in createCmsClient options to map user IDs to CMS roles.");
|
|
455
|
+
}
|
|
456
|
+
const role = await getUserRoleHook(ctx, { userId });
|
|
457
|
+
if (role === null) {
|
|
458
|
+
return [];
|
|
459
|
+
}
|
|
460
|
+
return getPermittedContentTypes(role, action, {
|
|
461
|
+
customRoles: resolvedConfig.customRoles,
|
|
462
|
+
});
|
|
463
|
+
},
|
|
464
|
+
getAllRoles() {
|
|
465
|
+
return {
|
|
466
|
+
...DEFAULT_ROLES,
|
|
467
|
+
...resolvedConfig.customRoles,
|
|
468
|
+
};
|
|
469
|
+
},
|
|
470
|
+
// ==========================================================================
|
|
471
|
+
// Resource Ownership Methods
|
|
472
|
+
// ==========================================================================
|
|
473
|
+
async canUserPerformOnResource(ctx, userId, resource, action, resourceOwnerId) {
|
|
474
|
+
if (!getUserRoleHook) {
|
|
475
|
+
throw new Error("No getUserRole hook configured. " +
|
|
476
|
+
"Configure a getUserRole function in createCmsClient options to map user IDs to CMS roles.");
|
|
477
|
+
}
|
|
478
|
+
const role = await getUserRoleHook(ctx, { userId });
|
|
479
|
+
// If user has no role, they have no permissions
|
|
480
|
+
if (role === null) {
|
|
481
|
+
return {
|
|
482
|
+
allowed: false,
|
|
483
|
+
role: null,
|
|
484
|
+
reason: "No role assigned to user",
|
|
485
|
+
code: "NO_ROLE",
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
// Use the core checkPermission function for comprehensive RBAC check
|
|
489
|
+
const { checkPermission } = await import("../component/authorization.js");
|
|
490
|
+
const result = checkPermission({
|
|
491
|
+
userId,
|
|
492
|
+
role,
|
|
493
|
+
resource,
|
|
494
|
+
action,
|
|
495
|
+
resourceOwnerId,
|
|
496
|
+
customRoles: resolvedConfig.customRoles,
|
|
497
|
+
});
|
|
498
|
+
if (result.allowed) {
|
|
499
|
+
return {
|
|
500
|
+
allowed: true,
|
|
501
|
+
role,
|
|
502
|
+
grantedScope: result.grantedScope,
|
|
503
|
+
ownershipVerified: result.ownershipVerified,
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
return {
|
|
508
|
+
allowed: false,
|
|
509
|
+
role,
|
|
510
|
+
reason: result.reason,
|
|
511
|
+
code: result.code,
|
|
512
|
+
ownershipRequired: result.code === "OWNERSHIP_REQUIRED",
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
},
|
|
516
|
+
async requireUserCanPerformOnResource(ctx, userId, resource, action, resourceOwnerId) {
|
|
517
|
+
const result = await this.canUserPerformOnResource(ctx, userId, resource, action, resourceOwnerId);
|
|
518
|
+
if (!result.allowed) {
|
|
519
|
+
throw new InternalUnauthorizedError(result.reason ?? "Operation not allowed", {
|
|
520
|
+
code: (result.code ?? "PERMISSION_DENIED"),
|
|
521
|
+
resource,
|
|
522
|
+
action,
|
|
523
|
+
role: result.role ?? undefined,
|
|
524
|
+
userId,
|
|
525
|
+
requiredScope: result.ownershipRequired ? "own" : undefined,
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
return {
|
|
529
|
+
allowed: true,
|
|
530
|
+
role: result.role,
|
|
531
|
+
grantedScope: result.grantedScope,
|
|
532
|
+
ownershipVerified: result.ownershipVerified ?? false,
|
|
533
|
+
};
|
|
534
|
+
},
|
|
535
|
+
isOwner(userId, resourceOwnerId) {
|
|
536
|
+
if (userId === undefined || resourceOwnerId === undefined) {
|
|
537
|
+
return false;
|
|
538
|
+
}
|
|
539
|
+
return userId === resourceOwnerId;
|
|
540
|
+
},
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
// --- Field Validators and Validation ---
|
|
544
|
+
export { fieldTypeValidator, fieldDefinitionValidator, contentStatusValidator, mediaTypeValidator, } from "../component/schema.js";
|
|
545
|
+
// --- Mutation Argument Validators ---
|
|
546
|
+
// These validators can be used in wrapper functions and custom mutations.
|
|
547
|
+
// Note: v.id() validators accept strings at runtime, making them work
|
|
548
|
+
// across the component boundary.
|
|
549
|
+
export {
|
|
550
|
+
// Content Type validators
|
|
551
|
+
createContentTypeArgs, updateContentTypeArgs, deleteContentTypeArgs,
|
|
552
|
+
// Content Entry validators
|
|
553
|
+
createContentEntryArgs, updateContentEntryArgs, publishEntryArgs, scheduleEntryArgs, unpublishEntryArgs, deleteContentEntryArgs, duplicateContentEntryArgs,
|
|
554
|
+
// Media Asset validators
|
|
555
|
+
createMediaAssetArgs, updateMediaAssetArgs, deleteMediaAssetArgs, restoreMediaAssetArgs, moveMediaAssetsArgs,
|
|
556
|
+
// Media Folder validators
|
|
557
|
+
createMediaFolderArgs, updateMediaFolderArgs, deleteMediaFolderArgs, restoreMediaFolderArgs, moveFolderArgs,
|
|
558
|
+
// Bulk Operation validators
|
|
559
|
+
bulkPublishArgs, bulkUnpublishArgs, bulkDeleteArgs, bulkUpdateArgs,
|
|
560
|
+
// Version validators
|
|
561
|
+
getVersionHistoryArgs, getVersionArgs, rollbackVersionArgs, compareVersionsArgs, createVersionSnapshotArgs,
|
|
562
|
+
// Query validators
|
|
563
|
+
contentQueryArgs, mediaQueryArgs, listMediaAssetsArgs,
|
|
564
|
+
// Lock validators
|
|
565
|
+
acquireLockArgs, releaseLockArgs, renewLockArgs, checkLockArgs,
|
|
566
|
+
// Trash validators
|
|
567
|
+
updateTrashConfigArgs, listTrashArgs, emptyTrashArgs, } from "../component/validators.js";
|
|
568
|
+
// Re-export field type constants
|
|
569
|
+
export { fieldTypes, contentStatuses, mediaTypes, } from "../component/schema.js";
|
|
570
|
+
// Re-export runtime validation functions
|
|
571
|
+
export { validateTextField, validateRichTextField, validateNumberField, validateBooleanField, validateDateField, validateReferenceField, validateMediaField, validateSelectField, validateMultiSelectField, validateJsonField, validateFieldValue, validateLocalizedFieldValue, validateContentData, applyFieldDefaults, getFieldType, isFieldRequired, } from "../component/validation.js";
|
|
572
|
+
// --- Locale Field Utilities ---
|
|
573
|
+
export {
|
|
574
|
+
// Type guards
|
|
575
|
+
isLocalizedFieldValue, isFieldLocalized,
|
|
576
|
+
// Field value operations
|
|
577
|
+
getLocalizedValue, setLocalizedValue, removeLocale, mergeLocalizedValues, getAvailableLocales, hasLocale,
|
|
578
|
+
// Content data operations
|
|
579
|
+
resolveContentData, setLocalizedContentData, getTranslationStatus,
|
|
580
|
+
// Locale content resolution (query enhancement)
|
|
581
|
+
resolveLocaleContent, resolveLocaleContentBatch, } from "../component/localeFields.js";
|
|
582
|
+
// --- Locale Fallback Chain ---
|
|
583
|
+
export {
|
|
584
|
+
// Configuration utilities
|
|
585
|
+
createFallbackConfig, validateFallbackConfig,
|
|
586
|
+
// Chain resolution functions
|
|
587
|
+
resolveFallbackChain, getFallbackChain, buildLocaleResolutionOptions,
|
|
588
|
+
// Locale parsing utilities
|
|
589
|
+
parseLocale, formatLocale, getLocaleHierarchy,
|
|
590
|
+
// Preset fallback chains
|
|
591
|
+
FALLBACK_PRESETS, mergeFallbackPresets,
|
|
592
|
+
// Default configuration
|
|
593
|
+
DEFAULT_FALLBACK_CONFIG, } from "../component/localeFallbackChain.js";
|
|
594
|
+
// Re-export slug utilities
|
|
595
|
+
export { generateSlug, isValidSlug, generateUniqueSlug, } from "../component/lib/slugGenerator.js";
|
|
596
|
+
// --- Deep Reference Resolution ---
|
|
597
|
+
export {
|
|
598
|
+
// Core resolution functions
|
|
599
|
+
resolveEntryReferences, resolveEntryReferencesBatch,
|
|
600
|
+
// Utility functions
|
|
601
|
+
findCircularReferenceMarkers, flattenResolvedReferences, countResolvedReferences, } from "../component/lib/deepReferenceResolver.js";
|
|
602
|
+
// Note: DeepResolveOptions, ResolvedContentEntry, and BatchResolveResult
|
|
603
|
+
// are already exported from ./types.js above
|
|
604
|
+
// --- RBAC Utilities ---
|
|
605
|
+
export {
|
|
606
|
+
// Role constants
|
|
607
|
+
roleNames, roleNameValidator,
|
|
608
|
+
// Resource and action constants
|
|
609
|
+
resources, resourceValidator, actions, actionValidator, permissionValidator,
|
|
610
|
+
// Default roles
|
|
611
|
+
ADMIN_ROLE, EDITOR_ROLE, AUTHOR_ROLE, VIEWER_ROLE, DEFAULT_ROLES, DEFAULT_ROLES_LIST,
|
|
612
|
+
// Permission check utilities
|
|
613
|
+
hasPermission, getRolePermissions, getRole, isBuiltInRole, getResourcePermissions, canAccessResource, permissionMatches,
|
|
614
|
+
// Custom role factory functions
|
|
615
|
+
createCustomRole, extendRole, mergeRolesWithDefaults, buildCustomRolesRecord,
|
|
616
|
+
// Content-type-aware permission checking
|
|
617
|
+
hasContentTypePermission, getPermittedContentTypes, getExcludedContentTypes,
|
|
618
|
+
// Permission factory helpers for custom roles
|
|
619
|
+
fullCrudForContentType, publishPermissionsForContentType, readOnlyForContentType,
|
|
620
|
+
// Validation utilities
|
|
621
|
+
validateCustomRoleConfig, validateExtendRoleConfig, } from "../component/roles.js";
|
|
622
|
+
// --- Rate Limiting ---
|
|
623
|
+
export {
|
|
624
|
+
// Main execution functions
|
|
625
|
+
executeRateLimitHooks, requireRateLimit,
|
|
626
|
+
// Error class
|
|
627
|
+
RateLimitedError,
|
|
628
|
+
// Context creation helpers
|
|
629
|
+
createRateLimitContext, operationToCategory,
|
|
630
|
+
// Key/name builders
|
|
631
|
+
createRateLimitKey, createRateLimitName,
|
|
632
|
+
// Default configurations
|
|
633
|
+
DEFAULT_TIER_LIMITS, getTierLimit, } from "../component/rateLimitHooks.js";
|
|
634
|
+
// --- Agent Tools ---
|
|
635
|
+
export {
|
|
636
|
+
// Main factory function
|
|
637
|
+
createCmsTools,
|
|
638
|
+
// Zod schemas for tool arguments (useful for custom tool creation)
|
|
639
|
+
fieldTypeSchema, contentStatusSchema, mediaTypeSchema, fieldOptionsSchema, fieldDefinitionSchema, filterOperatorSchema, fieldFilterSchema,
|
|
640
|
+
// Content Type schemas
|
|
641
|
+
createContentTypeArgsSchema, updateContentTypeArgsSchema, listContentTypesArgsSchema, getContentTypeArgsSchema,
|
|
642
|
+
// Content Entry schemas
|
|
643
|
+
createContentEntryArgsSchema, updateContentEntryArgsSchema, publishEntryArgsSchema, unpublishEntryArgsSchema, scheduleEntryArgsSchema, deleteContentEntryArgsSchema, duplicateContentEntryArgsSchema, listContentEntriesArgsSchema, getContentEntryArgsSchema, restoreContentEntryArgsSchema,
|
|
644
|
+
// Media Asset schemas
|
|
645
|
+
createMediaAssetArgsSchema, updateMediaAssetArgsSchema, listMediaAssetsArgsSchema, getMediaAssetArgsSchema, deleteMediaAssetArgsSchema,
|
|
646
|
+
// Bulk Operation schemas
|
|
647
|
+
bulkPublishArgsSchema, bulkUnpublishArgsSchema, bulkDeleteArgsSchema,
|
|
648
|
+
// Search schema
|
|
649
|
+
searchContentArgsSchema, } from "./agentTools.js";
|
|
650
|
+
// --- Code-Only Schema System ---
|
|
651
|
+
export {
|
|
652
|
+
// Core functions
|
|
653
|
+
defineContentType, createContentSchema, toFieldDefinitions,
|
|
654
|
+
// Runtime utilities
|
|
655
|
+
isContentTypeDefinition,
|
|
656
|
+
// Typed client factory
|
|
657
|
+
createTypedCmsClient, TypedContentEntriesApiImpl,
|
|
658
|
+
// Schema drift detection
|
|
659
|
+
detectSchemaDrift, formatDriftReport, hasErrors as hasDriftErrors, filterReportByContentTypes,
|
|
660
|
+
// Type code generation
|
|
661
|
+
generateTypesFromDatabase, generateTypesFromDefinitions, validateGeneratedCode, } from "./schema/index.js";
|
|
662
|
+
// --- Custom Field Types ---
|
|
663
|
+
export { defineFieldType, registerFieldType, registerFieldTypes, getFieldTypeDefinition, getAllFieldTypes, getCustomFieldTypes, isBuiltInFieldType, isCustomFieldType, hasFieldType, getFieldTypeDefaultValue, getFieldTypeIcon, BUILT_IN_TYPES, } from "./field-types.js";
|
|
664
|
+
// --- Custom Workflows ---
|
|
665
|
+
export { defineWorkflow, getWorkflowState, getAvailableTransitions, canTransition, isPublishedState, getInitialState, getAllPublishedStates, validateWorkflowTransition, DEFAULT_WORKFLOW, } from "./workflows.js";
|
|
666
|
+
// --- Admin UI Configuration ---
|
|
667
|
+
export { defineAdminConfig, resolveAdminConfig, adminConfigSchema, } from "./admin-config.js";
|
|
668
|
+
//# sourceMappingURL=index.js.map
|