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,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Library utilities for the CMS component
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
generateSlug,
|
|
7
|
+
isValidSlug,
|
|
8
|
+
generateUniqueSlug,
|
|
9
|
+
type SlugOptions,
|
|
10
|
+
} from "./slugGenerator.js";
|
|
11
|
+
|
|
12
|
+
// Error handling exports
|
|
13
|
+
export {
|
|
14
|
+
// Error class and types
|
|
15
|
+
CMSError,
|
|
16
|
+
isCMSError,
|
|
17
|
+
hasErrorCode,
|
|
18
|
+
isErrorCategory,
|
|
19
|
+
// Error codes
|
|
20
|
+
ErrorCodes,
|
|
21
|
+
ContentTypeErrorCodes,
|
|
22
|
+
ContentEntryErrorCodes,
|
|
23
|
+
MediaAssetErrorCodes,
|
|
24
|
+
MediaFolderErrorCodes,
|
|
25
|
+
VersionErrorCodes,
|
|
26
|
+
GeneralErrorCodes,
|
|
27
|
+
// Error factory functions - Content Types
|
|
28
|
+
contentTypeNotFound,
|
|
29
|
+
contentTypeDeleted,
|
|
30
|
+
contentTypeInactive,
|
|
31
|
+
contentTypeNameInvalid,
|
|
32
|
+
contentTypeNameDuplicate,
|
|
33
|
+
contentTypeFieldValidationFailed,
|
|
34
|
+
contentTypeSlugFieldInvalid,
|
|
35
|
+
contentTypeTitleFieldInvalid,
|
|
36
|
+
contentTypeHasEntries,
|
|
37
|
+
contentTypeBreakingChange,
|
|
38
|
+
// Error factory functions - Content Entries
|
|
39
|
+
contentEntryNotFound,
|
|
40
|
+
contentEntryDeleted,
|
|
41
|
+
contentEntryNotDeleted,
|
|
42
|
+
contentEntryAlreadyPublished,
|
|
43
|
+
contentEntryNotPublished,
|
|
44
|
+
contentEntryArchived,
|
|
45
|
+
contentEntryValidationFailed,
|
|
46
|
+
contentEntryLocked,
|
|
47
|
+
contentEntryCreateFailed,
|
|
48
|
+
contentEntryUpdateFailed,
|
|
49
|
+
// Error factory functions - Media Assets
|
|
50
|
+
mediaAssetNotFound,
|
|
51
|
+
mediaAssetDeleted,
|
|
52
|
+
mediaAssetNotDeleted,
|
|
53
|
+
mediaAssetHasReferences,
|
|
54
|
+
mediaAssetCreateFailed,
|
|
55
|
+
mediaAssetUpdateFailed,
|
|
56
|
+
// Error factory functions - Media Folders
|
|
57
|
+
mediaFolderNotFound,
|
|
58
|
+
mediaFolderDeleted,
|
|
59
|
+
mediaFolderNotDeleted,
|
|
60
|
+
mediaFolderNameInvalid,
|
|
61
|
+
mediaFolderNameDuplicate,
|
|
62
|
+
mediaFolderDepthExceeded,
|
|
63
|
+
mediaFolderPathTooLong,
|
|
64
|
+
mediaFolderHasContents,
|
|
65
|
+
mediaFolderCircularMove,
|
|
66
|
+
mediaFolderParentDeleted,
|
|
67
|
+
mediaFolderCreateFailed,
|
|
68
|
+
// Error factory functions - Versions
|
|
69
|
+
versionNotFound,
|
|
70
|
+
versionEntryNotFound,
|
|
71
|
+
versionEntryDeleted,
|
|
72
|
+
versionMismatch,
|
|
73
|
+
versionRollbackFailed,
|
|
74
|
+
// Error factory functions - General
|
|
75
|
+
batchSizeExceeded,
|
|
76
|
+
permissionDenied,
|
|
77
|
+
internalError,
|
|
78
|
+
// Types
|
|
79
|
+
type ErrorCode,
|
|
80
|
+
type ErrorCategory,
|
|
81
|
+
type CMSErrorContext,
|
|
82
|
+
type ResourceErrorContext,
|
|
83
|
+
type ValidationErrorContext,
|
|
84
|
+
type LockErrorContext,
|
|
85
|
+
type ReferenceErrorContext,
|
|
86
|
+
} from "./errors.js";
|
|
87
|
+
|
|
88
|
+
export {
|
|
89
|
+
checkSlugUniqueness,
|
|
90
|
+
ensureUniqueSlug,
|
|
91
|
+
findNextAvailableSlug,
|
|
92
|
+
validateSlugFormat,
|
|
93
|
+
type SlugUniquenessOptions,
|
|
94
|
+
type SlugCheckResult,
|
|
95
|
+
type SlugEntry,
|
|
96
|
+
type SlugQueryFn,
|
|
97
|
+
type SlugPrefixQueryFn,
|
|
98
|
+
} from "./slugUniqueness.js";
|
|
99
|
+
|
|
100
|
+
export {
|
|
101
|
+
isDeleted,
|
|
102
|
+
isActive,
|
|
103
|
+
filterActive,
|
|
104
|
+
filterDeleted,
|
|
105
|
+
requireNotDeleted,
|
|
106
|
+
requireDeleted,
|
|
107
|
+
type SoftDeletable,
|
|
108
|
+
} from "./softDelete.js";
|
|
109
|
+
|
|
110
|
+
export {
|
|
111
|
+
getContentTypeByName,
|
|
112
|
+
getTaxonomyByName,
|
|
113
|
+
contentTypeExists,
|
|
114
|
+
taxonomyExists,
|
|
115
|
+
getActiveById,
|
|
116
|
+
type GetByIdOptions,
|
|
117
|
+
} from "./queries.js";
|
|
118
|
+
|
|
119
|
+
export {
|
|
120
|
+
// Main API functions
|
|
121
|
+
chunkContentEntry,
|
|
122
|
+
extractContent,
|
|
123
|
+
chunkText,
|
|
124
|
+
chunkMultipleEntries,
|
|
125
|
+
estimateChunkingStats,
|
|
126
|
+
// Text extraction utilities
|
|
127
|
+
extractTextFromRichText,
|
|
128
|
+
extractTextFromJson,
|
|
129
|
+
extractTextFromSelect,
|
|
130
|
+
stripHtmlTags,
|
|
131
|
+
// Configuration defaults
|
|
132
|
+
DEFAULT_CHUNK_OPTIONS,
|
|
133
|
+
DEFAULT_EXTRACTION_OPTIONS,
|
|
134
|
+
// Types
|
|
135
|
+
type ContentChunk,
|
|
136
|
+
type ChunkMetadata,
|
|
137
|
+
type ChunkSemanticType,
|
|
138
|
+
type ChunkOptions,
|
|
139
|
+
type RagExtractionOptions,
|
|
140
|
+
type ExtractedContent,
|
|
141
|
+
type ContentTypeInfo,
|
|
142
|
+
type ContentEntryInfo,
|
|
143
|
+
type ResolvedReferenceInfo,
|
|
144
|
+
type FieldDefinition as RagFieldDefinition,
|
|
145
|
+
} from "./ragContentChunker.js";
|
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media Reference Resolution Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides functions for resolving and validating media asset references.
|
|
5
|
+
* These utilities help with fetching referenced media assets and validating
|
|
6
|
+
* MIME type constraints for media fields.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { Id } from "../_generated/dataModel.js";
|
|
10
|
+
import { isDeleted } from "./softDelete.js";
|
|
11
|
+
import { QueryCtx } from "../_generated/server.js";
|
|
12
|
+
import { classifyMimeType } from "./metadataExtractor.js";
|
|
13
|
+
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// Types
|
|
16
|
+
// =============================================================================
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A single media reference value (media asset ID as string)
|
|
20
|
+
*/
|
|
21
|
+
export type SingleMediaReference = string;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Multiple media reference values (array of media asset IDs) - used for galleries
|
|
25
|
+
*/
|
|
26
|
+
export type MultipleMediaReferences = string[];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Media field value - either single or multiple based on field configuration
|
|
30
|
+
*/
|
|
31
|
+
export type MediaReferenceValue =
|
|
32
|
+
| SingleMediaReference
|
|
33
|
+
| MultipleMediaReferences;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* A resolved media reference with full asset data
|
|
37
|
+
*/
|
|
38
|
+
export interface ResolvedMediaReference {
|
|
39
|
+
/** The media asset ID */
|
|
40
|
+
id: string;
|
|
41
|
+
/** The storage ID for the file */
|
|
42
|
+
storageId: string;
|
|
43
|
+
/** The resolved public URL for the asset */
|
|
44
|
+
url: string | null;
|
|
45
|
+
/** Original filename (name field) */
|
|
46
|
+
name: string;
|
|
47
|
+
/** MIME type of the file */
|
|
48
|
+
mimeType: string;
|
|
49
|
+
/** File size in bytes */
|
|
50
|
+
size: number;
|
|
51
|
+
/** Classified media type */
|
|
52
|
+
type: "image" | "video" | "audio" | "document" | "other";
|
|
53
|
+
/** Human-readable title */
|
|
54
|
+
title?: string;
|
|
55
|
+
/** Description/caption */
|
|
56
|
+
description?: string;
|
|
57
|
+
/** Alt text for accessibility */
|
|
58
|
+
altText?: string;
|
|
59
|
+
/** Image dimensions (if applicable) */
|
|
60
|
+
width?: number;
|
|
61
|
+
height?: number;
|
|
62
|
+
/** Duration in seconds (for video/audio) */
|
|
63
|
+
duration?: number;
|
|
64
|
+
/** Whether the asset exists and is not deleted */
|
|
65
|
+
exists: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Options for resolving media references
|
|
70
|
+
*/
|
|
71
|
+
export interface MediaResolveOptions {
|
|
72
|
+
/** Include soft-deleted assets (default: false) */
|
|
73
|
+
includeDeleted?: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Result of a media resolution operation
|
|
78
|
+
*/
|
|
79
|
+
export interface MediaResolveResult {
|
|
80
|
+
/** Successfully resolved media references */
|
|
81
|
+
resolved: ResolvedMediaReference[];
|
|
82
|
+
/** IDs that could not be resolved (not found or deleted) */
|
|
83
|
+
unresolved: string[];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Result of validating a media reference
|
|
88
|
+
*/
|
|
89
|
+
export interface MediaValidationResult {
|
|
90
|
+
/** Whether the reference is valid */
|
|
91
|
+
valid: boolean;
|
|
92
|
+
/** Error message if not valid */
|
|
93
|
+
error?: string;
|
|
94
|
+
/** The MIME type of the referenced asset (if found) */
|
|
95
|
+
mimeType?: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// =============================================================================
|
|
99
|
+
// Core Resolution Functions
|
|
100
|
+
// =============================================================================
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Resolve a single media reference to its full asset data.
|
|
104
|
+
*
|
|
105
|
+
* @param ctx - Convex query context
|
|
106
|
+
* @param mediaId - The media asset ID to resolve
|
|
107
|
+
* @param options - Resolution options
|
|
108
|
+
* @returns The resolved media reference or null if not found
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* // In a query handler:
|
|
113
|
+
* const image = await resolveMediaReference(ctx, entry.data.featuredImage);
|
|
114
|
+
* if (image) {
|
|
115
|
+
* console.log("Image URL:", image.url);
|
|
116
|
+
* console.log("Alt text:", image.altText);
|
|
117
|
+
* }
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export async function resolveMediaReference(
|
|
121
|
+
ctx: QueryCtx,
|
|
122
|
+
mediaId: string,
|
|
123
|
+
options: MediaResolveOptions = {},
|
|
124
|
+
): Promise<ResolvedMediaReference | null> {
|
|
125
|
+
const { includeDeleted = false } = options;
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
// Get the media item
|
|
129
|
+
const item = await ctx.db.get(mediaId as Id<"mediaItems">);
|
|
130
|
+
|
|
131
|
+
if (!item) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Only assets can be resolved as media references
|
|
136
|
+
if (item.kind !== "asset") {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Check soft-delete status
|
|
141
|
+
if (!includeDeleted && isDeleted(item)) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Resolve the storage URL
|
|
146
|
+
const url = await ctx.storage.getUrl(item.storageId);
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
id: mediaId,
|
|
150
|
+
storageId: item.storageId as string,
|
|
151
|
+
url,
|
|
152
|
+
name: item.name,
|
|
153
|
+
mimeType: item.mimeType,
|
|
154
|
+
size: item.size ?? 0,
|
|
155
|
+
type: classifyMimeType(item.mimeType),
|
|
156
|
+
title: item.title,
|
|
157
|
+
description: item.description,
|
|
158
|
+
altText: item.altText,
|
|
159
|
+
width: item.width,
|
|
160
|
+
height: item.height,
|
|
161
|
+
duration: item.duration,
|
|
162
|
+
exists: true,
|
|
163
|
+
};
|
|
164
|
+
} catch {
|
|
165
|
+
// Invalid ID format or other error
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Resolve multiple media references to their full asset data.
|
|
172
|
+
*
|
|
173
|
+
* @param ctx - Convex query context
|
|
174
|
+
* @param mediaIds - Array of media asset IDs to resolve
|
|
175
|
+
* @param options - Resolution options
|
|
176
|
+
* @returns Result with resolved references and unresolved IDs
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* // In a query handler - resolving a gallery:
|
|
181
|
+
* const result = await resolveMediaReferences(ctx, entry.data.galleryImages);
|
|
182
|
+
*
|
|
183
|
+
* console.log("Found:", result.resolved.length, "images");
|
|
184
|
+
* console.log("Missing:", result.unresolved);
|
|
185
|
+
*
|
|
186
|
+
* for (const image of result.resolved) {
|
|
187
|
+
* console.log(image.url, image.width, "x", image.height);
|
|
188
|
+
* }
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
export async function resolveMediaReferences(
|
|
192
|
+
ctx: QueryCtx,
|
|
193
|
+
mediaIds: string[],
|
|
194
|
+
options: MediaResolveOptions = {},
|
|
195
|
+
): Promise<MediaResolveResult> {
|
|
196
|
+
const resolved: ResolvedMediaReference[] = [];
|
|
197
|
+
const unresolved: string[] = [];
|
|
198
|
+
|
|
199
|
+
// Resolve each reference in parallel for efficiency
|
|
200
|
+
const promises = mediaIds.map(async (id) => {
|
|
201
|
+
const result = await resolveMediaReference(ctx, id, options);
|
|
202
|
+
return { id, result };
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
const results = await Promise.all(promises);
|
|
206
|
+
|
|
207
|
+
for (const { id, result } of results) {
|
|
208
|
+
if (result) {
|
|
209
|
+
resolved.push(result);
|
|
210
|
+
} else {
|
|
211
|
+
unresolved.push(id);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return { resolved, unresolved };
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// =============================================================================
|
|
219
|
+
// Validation Functions
|
|
220
|
+
// =============================================================================
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Check if a media reference ID points to a valid, existing media asset.
|
|
224
|
+
*
|
|
225
|
+
* @param ctx - Convex query context
|
|
226
|
+
* @param mediaId - The media asset ID to check
|
|
227
|
+
* @param allowedMimeTypes - Optional array of allowed MIME types
|
|
228
|
+
* @returns Object with validity status and optional error message
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* // Validate a media reference before saving:
|
|
233
|
+
* const check = await isValidMediaReference(ctx, imageId, ["image/jpeg", "image/png"]);
|
|
234
|
+
* if (!check.valid) {
|
|
235
|
+
* throw new Error(check.error);
|
|
236
|
+
* }
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
export async function isValidMediaReference(
|
|
240
|
+
ctx: QueryCtx,
|
|
241
|
+
mediaId: string,
|
|
242
|
+
allowedMimeTypes?: string[],
|
|
243
|
+
): Promise<MediaValidationResult> {
|
|
244
|
+
try {
|
|
245
|
+
// Get the media item
|
|
246
|
+
const item = await ctx.db.get(mediaId as Id<"mediaItems">);
|
|
247
|
+
|
|
248
|
+
if (!item) {
|
|
249
|
+
return { valid: false, error: `Media asset not found: ${mediaId}` };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Only assets can be validated as media references
|
|
253
|
+
if (item.kind !== "asset") {
|
|
254
|
+
return {
|
|
255
|
+
valid: false,
|
|
256
|
+
error: `Media reference is a folder, not an asset: ${mediaId}`,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Check soft-delete status
|
|
261
|
+
if (isDeleted(item)) {
|
|
262
|
+
return {
|
|
263
|
+
valid: false,
|
|
264
|
+
error: `Media asset has been deleted: ${mediaId}`,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// If MIME type constraints specified, check them
|
|
269
|
+
if (allowedMimeTypes && allowedMimeTypes.length > 0) {
|
|
270
|
+
// Support wildcard patterns like "image/*"
|
|
271
|
+
const isAllowed = allowedMimeTypes.some((pattern) => {
|
|
272
|
+
if (pattern.endsWith("/*")) {
|
|
273
|
+
// Wildcard pattern: "image/*" matches "image/jpeg", "image/png", etc.
|
|
274
|
+
const prefix = pattern.slice(0, -1); // Remove the trailing "*"
|
|
275
|
+
return item.mimeType.startsWith(prefix);
|
|
276
|
+
}
|
|
277
|
+
return item.mimeType === pattern;
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
if (!isAllowed) {
|
|
281
|
+
return {
|
|
282
|
+
valid: false,
|
|
283
|
+
error: `Media asset MIME type "${
|
|
284
|
+
item.mimeType
|
|
285
|
+
}" is not allowed. Expected: ${allowedMimeTypes.join(", ")}`,
|
|
286
|
+
mimeType: item.mimeType,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return { valid: true, mimeType: item.mimeType };
|
|
292
|
+
} catch {
|
|
293
|
+
return { valid: false, error: `Invalid media asset ID format: ${mediaId}` };
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Validate all media references in a content entry's data.
|
|
299
|
+
*
|
|
300
|
+
* Iterates through all media fields and validates that each reference
|
|
301
|
+
* points to a valid, existing media asset with an allowed MIME type.
|
|
302
|
+
*
|
|
303
|
+
* @param ctx - Convex query context
|
|
304
|
+
* @param data - The content entry data containing media fields
|
|
305
|
+
* @param fields - Array of field definitions (to identify media fields)
|
|
306
|
+
* @returns Object with overall validity and array of errors
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* ```typescript
|
|
310
|
+
* // Validate all media references before creating/updating an entry:
|
|
311
|
+
* const validation = await validateAllMediaReferences(ctx, data, contentType.fields);
|
|
312
|
+
* if (!validation.valid) {
|
|
313
|
+
* throw new Error(validation.errors.join(", "));
|
|
314
|
+
* }
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
export async function validateAllMediaReferences(
|
|
318
|
+
ctx: QueryCtx,
|
|
319
|
+
data: Record<string, unknown>,
|
|
320
|
+
fields: Array<{
|
|
321
|
+
name: string;
|
|
322
|
+
type: string;
|
|
323
|
+
options?: {
|
|
324
|
+
allowedMimeTypes?: string[];
|
|
325
|
+
multiple?: boolean;
|
|
326
|
+
};
|
|
327
|
+
}>,
|
|
328
|
+
): Promise<{ valid: boolean; errors: string[] }> {
|
|
329
|
+
const errors: string[] = [];
|
|
330
|
+
|
|
331
|
+
// Find all media fields
|
|
332
|
+
const mediaFields = fields.filter((f) => f.type === "media");
|
|
333
|
+
|
|
334
|
+
for (const field of mediaFields) {
|
|
335
|
+
const value = data[field.name];
|
|
336
|
+
|
|
337
|
+
if (value === null || value === undefined) {
|
|
338
|
+
continue; // Skip empty values (required validation is separate)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const allowedMimeTypes = field.options?.allowedMimeTypes;
|
|
342
|
+
const multiple = field.options?.multiple ?? false;
|
|
343
|
+
|
|
344
|
+
if (multiple) {
|
|
345
|
+
// Validate array of media references (gallery)
|
|
346
|
+
if (!Array.isArray(value)) {
|
|
347
|
+
errors.push(`${field.name}: Expected array of media asset IDs`);
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
for (const mediaId of value) {
|
|
352
|
+
if (typeof mediaId !== "string") {
|
|
353
|
+
errors.push(`${field.name}: Invalid media asset ID type`);
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const check = await isValidMediaReference(
|
|
358
|
+
ctx,
|
|
359
|
+
mediaId,
|
|
360
|
+
allowedMimeTypes,
|
|
361
|
+
);
|
|
362
|
+
if (!check.valid) {
|
|
363
|
+
errors.push(`${field.name}: ${check.error}`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
// Validate single media reference
|
|
368
|
+
if (typeof value !== "string") {
|
|
369
|
+
errors.push(`${field.name}: Expected string media asset ID`);
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const check = await isValidMediaReference(ctx, value, allowedMimeTypes);
|
|
374
|
+
if (!check.valid) {
|
|
375
|
+
errors.push(`${field.name}: ${check.error}`);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return {
|
|
381
|
+
valid: errors.length === 0,
|
|
382
|
+
errors,
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// =============================================================================
|
|
387
|
+
// Utility Functions
|
|
388
|
+
// =============================================================================
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Extract all media asset IDs from a content entry's data.
|
|
392
|
+
*
|
|
393
|
+
* @param data - The content entry data
|
|
394
|
+
* @param fields - Array of field definitions
|
|
395
|
+
* @returns Array of all media asset IDs found in the data
|
|
396
|
+
*/
|
|
397
|
+
export function extractMediaIds(
|
|
398
|
+
data: Record<string, unknown>,
|
|
399
|
+
fields: Array<{
|
|
400
|
+
name: string;
|
|
401
|
+
type: string;
|
|
402
|
+
options?: { multiple?: boolean };
|
|
403
|
+
}>,
|
|
404
|
+
): string[] {
|
|
405
|
+
const ids: string[] = [];
|
|
406
|
+
|
|
407
|
+
const mediaFields = fields.filter((f) => f.type === "media");
|
|
408
|
+
|
|
409
|
+
for (const field of mediaFields) {
|
|
410
|
+
const value = data[field.name];
|
|
411
|
+
|
|
412
|
+
if (value === null || value === undefined) {
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const multiple = field.options?.multiple ?? false;
|
|
417
|
+
|
|
418
|
+
if (multiple && Array.isArray(value)) {
|
|
419
|
+
for (const id of value) {
|
|
420
|
+
if (typeof id === "string") {
|
|
421
|
+
ids.push(id);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
} else if (typeof value === "string") {
|
|
425
|
+
ids.push(value);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return ids;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Get the MIME type for a media asset ID.
|
|
434
|
+
*
|
|
435
|
+
* This is a helper function for validation purposes.
|
|
436
|
+
*
|
|
437
|
+
* @param ctx - Convex query context
|
|
438
|
+
* @param mediaId - The media asset ID
|
|
439
|
+
* @returns The MIME type or null if not found
|
|
440
|
+
*/
|
|
441
|
+
export async function getMediaMimeType(
|
|
442
|
+
ctx: QueryCtx,
|
|
443
|
+
mediaId: string,
|
|
444
|
+
): Promise<string | null> {
|
|
445
|
+
try {
|
|
446
|
+
const item = await ctx.db.get(mediaId as Id<"mediaItems">);
|
|
447
|
+
|
|
448
|
+
if (!item || item.kind !== "asset" || isDeleted(item)) {
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
return item.mimeType;
|
|
453
|
+
} catch {
|
|
454
|
+
return null;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Check if a MIME type matches a pattern (supports wildcards like "image/*").
|
|
460
|
+
*
|
|
461
|
+
* @param mimeType - The MIME type to check
|
|
462
|
+
* @param pattern - The pattern to match against (e.g., "image/*", "image/jpeg")
|
|
463
|
+
* @returns Whether the MIME type matches the pattern
|
|
464
|
+
*
|
|
465
|
+
* @example
|
|
466
|
+
* ```typescript
|
|
467
|
+
* matchesMimeTypePattern("image/jpeg", "image/*"); // true
|
|
468
|
+
* matchesMimeTypePattern("image/jpeg", "image/jpeg"); // true
|
|
469
|
+
* matchesMimeTypePattern("image/jpeg", "video/*"); // false
|
|
470
|
+
* ```
|
|
471
|
+
*/
|
|
472
|
+
export function matchesMimeTypePattern(
|
|
473
|
+
mimeType: string,
|
|
474
|
+
pattern: string,
|
|
475
|
+
): boolean {
|
|
476
|
+
if (pattern.endsWith("/*")) {
|
|
477
|
+
const prefix = pattern.slice(0, -1);
|
|
478
|
+
return mimeType.startsWith(prefix);
|
|
479
|
+
}
|
|
480
|
+
return mimeType === pattern;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Check if a MIME type matches any of the given patterns.
|
|
485
|
+
*
|
|
486
|
+
* @param mimeType - The MIME type to check
|
|
487
|
+
* @param patterns - Array of patterns to match against
|
|
488
|
+
* @returns Whether the MIME type matches any pattern
|
|
489
|
+
*/
|
|
490
|
+
export function matchesAnyMimeTypePattern(
|
|
491
|
+
mimeType: string,
|
|
492
|
+
patterns: string[],
|
|
493
|
+
): boolean {
|
|
494
|
+
return patterns.some((pattern) => matchesMimeTypePattern(mimeType, pattern));
|
|
495
|
+
}
|