@strapi/upload 5.55.1 → 5.57.0
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/admin/hooks/useAIMetadataAvailability.js +14 -0
- package/dist/admin/hooks/useAIMetadataAvailability.js.map +1 -0
- package/dist/admin/hooks/useAIMetadataAvailability.mjs +12 -0
- package/dist/admin/hooks/useAIMetadataAvailability.mjs.map +1 -0
- package/dist/admin/hooks/useAIMetadataEnabled.js +7 -5
- package/dist/admin/hooks/useAIMetadataEnabled.js.map +1 -1
- package/dist/admin/hooks/useAIMetadataEnabled.mjs +7 -5
- package/dist/admin/hooks/useAIMetadataEnabled.mjs.map +1 -1
- package/dist/admin/hooks/useTracking.js +4 -10
- package/dist/admin/hooks/useTracking.js.map +1 -1
- package/dist/admin/hooks/useTracking.mjs +5 -10
- package/dist/admin/hooks/useTracking.mjs.map +1 -1
- package/dist/admin/legacy/hooks/useAIMetadataAvailability.js +14 -0
- package/dist/admin/legacy/hooks/useAIMetadataAvailability.js.map +1 -0
- package/dist/admin/legacy/hooks/useAIMetadataAvailability.mjs +12 -0
- package/dist/admin/legacy/hooks/useAIMetadataAvailability.mjs.map +1 -0
- package/dist/admin/legacy/hooks/useAIMetadataEnabled.js +23 -0
- package/dist/admin/legacy/hooks/useAIMetadataEnabled.js.map +1 -0
- package/dist/admin/legacy/hooks/useAIMetadataEnabled.mjs +21 -0
- package/dist/admin/legacy/hooks/useAIMetadataEnabled.mjs.map +1 -0
- package/dist/admin/legacy/hooks/useTracking.js +5 -3
- package/dist/admin/legacy/hooks/useTracking.js.map +1 -1
- package/dist/admin/legacy/hooks/useTracking.mjs +5 -3
- package/dist/admin/legacy/hooks/useTracking.mjs.map +1 -1
- package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.js +2 -1
- package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
- package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.mjs +2 -1
- package/dist/admin/legacy/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
- package/dist/admin/legacy/pages/App/MediaLibrary.js +6 -5
- package/dist/admin/legacy/pages/App/MediaLibrary.js.map +1 -1
- package/dist/admin/legacy/pages/App/MediaLibrary.mjs +6 -5
- package/dist/admin/legacy/pages/App/MediaLibrary.mjs.map +1 -1
- package/dist/admin/pages/Assets/AssetsPage.js +24 -12
- package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/pages/Assets/AssetsPage.mjs +25 -13
- package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetActions.js +326 -0
- package/dist/admin/pages/Assets/components/AssetActions.js.map +1 -0
- package/dist/admin/pages/Assets/components/AssetActions.mjs +324 -0
- package/dist/admin/pages/Assets/components/AssetActions.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/AssetActionsMenu.js +28 -309
- package/dist/admin/pages/Assets/components/AssetActionsMenu.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetActionsMenu.mjs +31 -312
- package/dist/admin/pages/Assets/components/AssetActionsMenu.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetContextMenu.js +79 -0
- package/dist/admin/pages/Assets/components/AssetContextMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/AssetContextMenu.mjs +77 -0
- package/dist/admin/pages/Assets/components/AssetContextMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.js +87 -5
- package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +89 -7
- package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +3 -3
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +3 -3
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.js +62 -5
- package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.mjs +60 -6
- package/dist/admin/pages/Assets/components/AssetDetails/useCropImg.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.js +27 -4
- package/dist/admin/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsGrid.mjs +27 -4
- package/dist/admin/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsTable.js +27 -4
- package/dist/admin/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetsTable.mjs +27 -4
- package/dist/admin/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/CursorAnchoredMenu.js +77 -0
- package/dist/admin/pages/Assets/components/CursorAnchoredMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/CursorAnchoredMenu.mjs +75 -0
- package/dist/admin/pages/Assets/components/CursorAnchoredMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/DeleteItemsDialog.js +4 -2
- package/dist/admin/pages/Assets/components/DeleteItemsDialog.js.map +1 -1
- package/dist/admin/pages/Assets/components/DeleteItemsDialog.mjs +4 -2
- package/dist/admin/pages/Assets/components/DeleteItemsDialog.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/FolderActions.js +139 -0
- package/dist/admin/pages/Assets/components/FolderActions.js.map +1 -0
- package/dist/admin/pages/Assets/components/FolderActions.mjs +137 -0
- package/dist/admin/pages/Assets/components/FolderActions.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/FolderActionsMenu.js +25 -119
- package/dist/admin/pages/Assets/components/FolderActionsMenu.js.map +1 -1
- package/dist/admin/pages/Assets/components/FolderActionsMenu.mjs +27 -121
- package/dist/admin/pages/Assets/components/FolderActionsMenu.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/FolderContextMenu.js +67 -0
- package/dist/admin/pages/Assets/components/FolderContextMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/FolderContextMenu.mjs +65 -0
- package/dist/admin/pages/Assets/components/FolderContextMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js +139 -45
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs +140 -47
- package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.js +115 -0
- package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.mjs +113 -0
- package/dist/admin/pages/Assets/components/FolderTree/FolderTreeRowMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/ItemContextMenu.js +125 -0
- package/dist/admin/pages/Assets/components/ItemContextMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/ItemContextMenu.mjs +122 -0
- package/dist/admin/pages/Assets/components/ItemContextMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/MainAreaContextMenu.js +88 -63
- package/dist/admin/pages/Assets/components/MainAreaContextMenu.js.map +1 -1
- package/dist/admin/pages/Assets/components/MainAreaContextMenu.mjs +88 -63
- package/dist/admin/pages/Assets/components/MainAreaContextMenu.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/SelectionActions.js +111 -0
- package/dist/admin/pages/Assets/components/SelectionActions.js.map +1 -0
- package/dist/admin/pages/Assets/components/SelectionActions.mjs +109 -0
- package/dist/admin/pages/Assets/components/SelectionActions.mjs.map +1 -0
- package/dist/admin/pages/Assets/components/SelectionContextMenu.js +82 -0
- package/dist/admin/pages/Assets/components/SelectionContextMenu.js.map +1 -0
- package/dist/admin/pages/Assets/components/SelectionContextMenu.mjs +80 -0
- package/dist/admin/pages/Assets/components/SelectionContextMenu.mjs.map +1 -0
- package/dist/admin/pages/Assets/hooks/useAssetSelection.js +10 -0
- package/dist/admin/pages/Assets/hooks/useAssetSelection.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs +10 -0
- package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.js +10 -3
- package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs +10 -3
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
- package/dist/admin/services/api.js.map +1 -1
- package/dist/admin/services/api.mjs.map +1 -1
- package/dist/admin/src/hooks/useAIMetadataAvailability.d.ts +5 -0
- package/dist/admin/src/hooks/useAIMetadataEnabled.d.ts +5 -3
- package/dist/admin/src/hooks/useTracking.d.ts +0 -7
- package/dist/admin/src/legacy/components/EditAssetDialog/PreviewBox/PreviewComponents.d.ts +2 -2
- package/dist/admin/src/legacy/hooks/useAIMetadataAvailability.d.ts +5 -0
- package/dist/admin/src/legacy/hooks/useAIMetadataEnabled.d.ts +12 -0
- package/dist/admin/src/legacy/hooks/useSettings.d.ts +1 -0
- package/dist/admin/src/pages/Assets/components/ActionsMenuContent.d.ts +2 -2
- package/dist/admin/src/pages/Assets/components/AssetActions.d.ts +70 -0
- package/dist/admin/src/pages/Assets/components/AssetActionsMenu.d.ts +5 -14
- package/dist/admin/src/pages/Assets/components/AssetContextMenu.d.ts +27 -0
- package/dist/admin/src/pages/Assets/components/AssetDetails/useCropImg.d.ts +16 -0
- package/dist/admin/src/pages/Assets/components/CursorAnchoredMenu.d.ts +32 -0
- package/dist/admin/src/pages/Assets/components/FolderActions.d.ts +48 -0
- package/dist/admin/src/pages/Assets/components/FolderActionsMenu.d.ts +4 -8
- package/dist/admin/src/pages/Assets/components/FolderContextMenu.d.ts +21 -0
- package/dist/admin/src/pages/Assets/components/FolderTree/FolderTree.d.ts +5 -1
- package/dist/admin/src/pages/Assets/components/FolderTree/FolderTreeRowMenu.d.ts +25 -0
- package/dist/admin/src/pages/Assets/components/ItemContextMenu.d.ts +53 -0
- package/dist/admin/src/pages/Assets/components/MainAreaContextMenu.d.ts +15 -1
- package/dist/admin/src/pages/Assets/components/SelectionActions.d.ts +40 -0
- package/dist/admin/src/pages/Assets/components/SelectionContextMenu.d.ts +25 -0
- package/dist/admin/src/pages/Assets/hooks/useAssetSelection.d.ts +5 -0
- package/dist/admin/src/utils/mediaLibraryVersion.d.ts +18 -0
- package/dist/admin/translations/en.json.js +9 -3
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +9 -3
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/utils/mediaLibraryVersion.js +24 -0
- package/dist/admin/utils/mediaLibraryVersion.js.map +1 -0
- package/dist/admin/utils/mediaLibraryVersion.mjs +20 -0
- package/dist/admin/utils/mediaLibraryVersion.mjs.map +1 -0
- package/dist/server/bootstrap.js +7 -0
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/bootstrap.mjs +7 -0
- package/dist/server/bootstrap.mjs.map +1 -1
- package/dist/server/controllers/admin-file.js +2 -2
- package/dist/server/controllers/admin-file.js.map +1 -1
- package/dist/server/controllers/admin-file.mjs +2 -2
- package/dist/server/controllers/admin-file.mjs.map +1 -1
- package/dist/server/controllers/admin-folder-file.js +51 -4
- package/dist/server/controllers/admin-folder-file.js.map +1 -1
- package/dist/server/controllers/admin-folder-file.mjs +52 -5
- package/dist/server/controllers/admin-folder-file.mjs.map +1 -1
- package/dist/server/controllers/admin-folder.js +5 -5
- package/dist/server/controllers/admin-folder.js.map +1 -1
- package/dist/server/controllers/admin-folder.mjs +5 -5
- package/dist/server/controllers/admin-folder.mjs.map +1 -1
- package/dist/server/controllers/admin-settings.js +2 -1
- package/dist/server/controllers/admin-settings.js.map +1 -1
- package/dist/server/controllers/admin-settings.mjs +2 -1
- package/dist/server/controllers/admin-settings.mjs.map +1 -1
- package/dist/server/controllers/content-api.js +30 -7
- package/dist/server/controllers/content-api.js.map +1 -1
- package/dist/server/controllers/content-api.mjs +30 -7
- package/dist/server/controllers/content-api.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/folder-file.js +4 -4
- package/dist/server/controllers/validation/admin/folder-file.js.map +1 -1
- package/dist/server/controllers/validation/admin/folder-file.mjs +2 -2
- package/dist/server/controllers/validation/admin/folder-file.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/folder.js +3 -4
- package/dist/server/controllers/validation/admin/folder.js.map +1 -1
- package/dist/server/controllers/validation/admin/folder.mjs +3 -4
- package/dist/server/controllers/validation/admin/folder.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/upload.js +1 -2
- package/dist/server/controllers/validation/admin/upload.js.map +1 -1
- package/dist/server/controllers/validation/admin/upload.mjs +1 -2
- package/dist/server/controllers/validation/admin/upload.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/utils.js +1 -2
- package/dist/server/controllers/validation/admin/utils.js.map +1 -1
- package/dist/server/controllers/validation/admin/utils.mjs +1 -2
- package/dist/server/controllers/validation/admin/utils.mjs.map +1 -1
- package/dist/server/errors.js +12 -0
- package/dist/server/errors.js.map +1 -0
- package/dist/server/errors.mjs +10 -0
- package/dist/server/errors.mjs.map +1 -0
- package/dist/server/migrations/unsign-richtext-and-blocks-urls.js +2 -2
- package/dist/server/migrations/unsign-richtext-and-blocks-urls.js.map +1 -1
- package/dist/server/migrations/unsign-richtext-and-blocks-urls.mjs +1 -1
- package/dist/server/migrations/unsign-richtext-and-blocks-urls.mjs.map +1 -1
- package/dist/server/routes/content-api.js +3 -3
- package/dist/server/routes/content-api.js.map +1 -1
- package/dist/server/routes/content-api.mjs +3 -3
- package/dist/server/routes/content-api.mjs.map +1 -1
- package/dist/server/routes/validation/upload.js +8 -0
- package/dist/server/routes/validation/upload.js.map +1 -1
- package/dist/server/routes/validation/upload.mjs +8 -0
- package/dist/server/routes/validation/upload.mjs.map +1 -1
- package/dist/server/services/ai-metadata-provider.js +83 -0
- package/dist/server/services/ai-metadata-provider.js.map +1 -0
- package/dist/server/services/ai-metadata-provider.mjs +61 -0
- package/dist/server/services/ai-metadata-provider.mjs.map +1 -0
- package/dist/server/services/ai-metadata-strapi-managed.js +48 -0
- package/dist/server/services/ai-metadata-strapi-managed.js.map +1 -0
- package/dist/server/services/ai-metadata-strapi-managed.mjs +46 -0
- package/dist/server/services/ai-metadata-strapi-managed.mjs.map +1 -0
- package/dist/server/services/ai-metadata.js +5 -58
- package/dist/server/services/ai-metadata.js.map +1 -1
- package/dist/server/services/ai-metadata.mjs +6 -39
- package/dist/server/services/ai-metadata.mjs.map +1 -1
- package/dist/server/services/api-upload-folder.js +3 -3
- package/dist/server/services/api-upload-folder.js.map +1 -1
- package/dist/server/services/api-upload-folder.mjs +3 -3
- package/dist/server/services/api-upload-folder.mjs.map +1 -1
- package/dist/server/services/extensions/utils.js +19 -15
- package/dist/server/services/extensions/utils.js.map +1 -1
- package/dist/server/services/extensions/utils.mjs +19 -15
- package/dist/server/services/extensions/utils.mjs.map +1 -1
- package/dist/server/services/file.js +2 -2
- package/dist/server/services/file.js.map +1 -1
- package/dist/server/services/file.mjs +1 -1
- package/dist/server/services/file.mjs.map +1 -1
- package/dist/server/services/folder.js +9 -6
- package/dist/server/services/folder.js.map +1 -1
- package/dist/server/services/folder.mjs +9 -6
- package/dist/server/services/folder.mjs.map +1 -1
- package/dist/server/services/index.js +3 -1
- package/dist/server/services/index.js.map +1 -1
- package/dist/server/services/index.mjs +3 -1
- package/dist/server/services/index.mjs.map +1 -1
- package/dist/server/services/metrics.js +1 -1
- package/dist/server/services/metrics.js.map +1 -1
- package/dist/server/services/metrics.mjs +1 -1
- package/dist/server/services/metrics.mjs.map +1 -1
- package/dist/server/services/provider.js +3 -4
- package/dist/server/services/provider.js.map +1 -1
- package/dist/server/services/provider.mjs +3 -4
- package/dist/server/services/provider.mjs.map +1 -1
- package/dist/server/services/upload.js +5 -6
- package/dist/server/services/upload.js.map +1 -1
- package/dist/server/services/upload.mjs +4 -5
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/services/weekly-metrics.js +2 -2
- package/dist/server/services/weekly-metrics.js.map +1 -1
- package/dist/server/services/weekly-metrics.mjs +2 -2
- package/dist/server/services/weekly-metrics.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-folder-file.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-folder.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
- package/dist/server/src/controllers/content-api.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/folder.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/upload.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/utils.d.ts.map +1 -1
- package/dist/server/src/errors.d.ts +6 -0
- package/dist/server/src/errors.d.ts.map +1 -0
- package/dist/server/src/index.d.ts +6 -1
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/mcp/ambient-instance.d.ts +3 -1
- package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -1
- package/dist/server/src/routes/validation/upload.d.ts +4 -0
- package/dist/server/src/routes/validation/upload.d.ts.map +1 -1
- package/dist/server/src/services/ai-metadata-provider.d.ts +26 -0
- package/dist/server/src/services/ai-metadata-provider.d.ts.map +1 -0
- package/dist/server/src/services/ai-metadata-strapi-managed.d.ts +7 -0
- package/dist/server/src/services/ai-metadata-strapi-managed.d.ts.map +1 -0
- package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
- package/dist/server/src/services/extensions/utils.d.ts +33 -1
- package/dist/server/src/services/extensions/utils.d.ts.map +1 -1
- package/dist/server/src/services/folder.d.ts +5 -2
- package/dist/server/src/services/folder.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +6 -1
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/provider.d.ts.map +1 -1
- package/dist/server/src/services/upload.d.ts.map +1 -1
- package/dist/server/src/utils/images.d.ts +2 -2
- package/dist/server/src/utils/images.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/server/utils/images.js +6 -7
- package/dist/server/utils/images.js.map +1 -1
- package/dist/server/utils/images.mjs +6 -7
- package/dist/server/utils/images.mjs.map +1 -1
- package/dist/server/utils/index.js.map +1 -1
- package/dist/server/utils/index.mjs.map +1 -1
- package/dist/shared/contracts/settings.d.ts +6 -0
- package/package.json +11 -11
- package/dist/admin/legacy/hooks/useAiAvailability.js +0 -22
- package/dist/admin/legacy/hooks/useAiAvailability.js.map +0 -1
- package/dist/admin/legacy/hooks/useAiAvailability.mjs +0 -20
- package/dist/admin/legacy/hooks/useAiAvailability.mjs.map +0 -1
- package/dist/admin/src/legacy/hooks/useAiAvailability.d.ts +0 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-api.js","sources":["../../../server/src/routes/content-api.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport * as z from 'zod/v4';\nimport { createContentApiRoutesFactory } from '@strapi/utils';\nimport { UploadRouteValidator } from './validation';\n\nconst createRoutes = createContentApiRoutesFactory((): Core.RouterInput['routes'] => {\n const validator = new UploadRouteValidator(strapi);\n\n return [\n {\n method: 'POST',\n path: '/',\n handler: 'content-api.upload',\n request: {\n query: { id: validator.
|
|
1
|
+
{"version":3,"file":"content-api.js","sources":["../../../server/src/routes/content-api.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport * as z from 'zod/v4';\nimport { createContentApiRoutesFactory } from '@strapi/utils';\nimport { UploadRouteValidator } from './validation';\n\nconst createRoutes = createContentApiRoutesFactory((): Core.RouterInput['routes'] => {\n const validator = new UploadRouteValidator(strapi);\n\n return [\n {\n method: 'POST',\n path: '/',\n handler: 'content-api.upload',\n request: {\n query: { id: validator.fileIdOrDocumentId.optional() },\n // Note: multipart/form-data is handled by Koa middleware, not Zod\n },\n response: z.union([validator.file, validator.files]),\n },\n {\n method: 'GET',\n path: '/files',\n handler: 'content-api.find',\n request: {\n query: {\n fields: validator.queryFields.optional(),\n populate: validator.queryPopulate.optional(),\n sort: validator.querySort.optional(),\n pagination: validator.pagination.optional(),\n filters: validator.filters.optional(),\n },\n },\n response: validator.files,\n },\n {\n method: 'GET',\n path: '/files/page',\n handler: 'content-api.findPage',\n request: {\n query: {\n fields: validator.queryFields.optional(),\n populate: validator.queryPopulate.optional(),\n sort: validator.querySort.optional(),\n pagination: validator.pagination.optional(),\n filters: validator.filters.optional(),\n },\n },\n response: validator.paginatedFiles,\n },\n {\n method: 'GET',\n path: '/files/:id',\n handler: 'content-api.findOne',\n request: {\n params: { id: validator.fileIdOrDocumentId },\n query: {\n fields: validator.queryFields.optional(),\n populate: validator.queryPopulate.optional(),\n },\n },\n response: validator.file,\n },\n {\n method: 'DELETE',\n path: '/files/:id',\n handler: 'content-api.destroy',\n request: {\n params: { id: validator.fileIdOrDocumentId },\n },\n response: validator.file,\n },\n ];\n});\n\nexport const routes = createRoutes;\n"],"names":["createRoutes","createContentApiRoutesFactory","validator","UploadRouteValidator","strapi","method","path","handler","request","query","id","fileIdOrDocumentId","optional","response","z","union","file","files","fields","queryFields","populate","queryPopulate","sort","querySort","pagination","filters","paginatedFiles","params","routes"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAMA,eAAeC,mCAAAA,CAA8B,IAAA;IACjD,MAAMC,SAAAA,GAAY,IAAIC,2BAAAA,CAAqBC,MAAAA,CAAAA;IAE3C,OAAO;AACL,QAAA;YACEC,MAAAA,EAAQ,MAAA;YACRC,IAAAA,EAAM,GAAA;YACNC,OAAAA,EAAS,oBAAA;YACTC,OAAAA,EAAS;gBACPC,KAAAA,EAAO;oBAAEC,EAAAA,EAAIR,SAAAA,CAAUS,kBAAkB,CAACC,QAAQ;AAAG;AAEvD,aAAA;YACAC,QAAAA,EAAUC,YAAAA,CAAEC,KAAK,CAAC;AAACb,gBAAAA,SAAAA,CAAUc,IAAI;AAAEd,gBAAAA,SAAAA,CAAUe;AAAM,aAAA;AACrD,SAAA;AACA,QAAA;YACEZ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,QAAA;YACNC,OAAAA,EAAS,kBAAA;YACTC,OAAAA,EAAS;gBACPC,KAAAA,EAAO;oBACLS,MAAAA,EAAQhB,SAAAA,CAAUiB,WAAW,CAACP,QAAQ,EAAA;oBACtCQ,QAAAA,EAAUlB,SAAAA,CAAUmB,aAAa,CAACT,QAAQ,EAAA;oBAC1CU,IAAAA,EAAMpB,SAAAA,CAAUqB,SAAS,CAACX,QAAQ,EAAA;oBAClCY,UAAAA,EAAYtB,SAAAA,CAAUsB,UAAU,CAACZ,QAAQ,EAAA;oBACzCa,OAAAA,EAASvB,SAAAA,CAAUuB,OAAO,CAACb,QAAQ;AACrC;AACF,aAAA;AACAC,YAAAA,QAAAA,EAAUX,UAAUe;AACtB,SAAA;AACA,QAAA;YACEZ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,aAAA;YACNC,OAAAA,EAAS,sBAAA;YACTC,OAAAA,EAAS;gBACPC,KAAAA,EAAO;oBACLS,MAAAA,EAAQhB,SAAAA,CAAUiB,WAAW,CAACP,QAAQ,EAAA;oBACtCQ,QAAAA,EAAUlB,SAAAA,CAAUmB,aAAa,CAACT,QAAQ,EAAA;oBAC1CU,IAAAA,EAAMpB,SAAAA,CAAUqB,SAAS,CAACX,QAAQ,EAAA;oBAClCY,UAAAA,EAAYtB,SAAAA,CAAUsB,UAAU,CAACZ,QAAQ,EAAA;oBACzCa,OAAAA,EAASvB,SAAAA,CAAUuB,OAAO,CAACb,QAAQ;AACrC;AACF,aAAA;AACAC,YAAAA,QAAAA,EAAUX,UAAUwB;AACtB,SAAA;AACA,QAAA;YACErB,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,YAAA;YACNC,OAAAA,EAAS,qBAAA;YACTC,OAAAA,EAAS;gBACPmB,MAAAA,EAAQ;AAAEjB,oBAAAA,EAAAA,EAAIR,UAAUS;AAAmB,iBAAA;gBAC3CF,KAAAA,EAAO;oBACLS,MAAAA,EAAQhB,SAAAA,CAAUiB,WAAW,CAACP,QAAQ,EAAA;oBACtCQ,QAAAA,EAAUlB,SAAAA,CAAUmB,aAAa,CAACT,QAAQ;AAC5C;AACF,aAAA;AACAC,YAAAA,QAAAA,EAAUX,UAAUc;AACtB,SAAA;AACA,QAAA;YACEX,MAAAA,EAAQ,QAAA;YACRC,IAAAA,EAAM,YAAA;YACNC,OAAAA,EAAS,qBAAA;YACTC,OAAAA,EAAS;gBACPmB,MAAAA,EAAQ;AAAEjB,oBAAAA,EAAAA,EAAIR,UAAUS;AAAmB;AAC7C,aAAA;AACAE,YAAAA,QAAAA,EAAUX,UAAUc;AACtB;AACD,KAAA;AACH,CAAA,CAAA;AAEO,MAAMY,SAAS5B;;;;"}
|
|
@@ -11,7 +11,7 @@ const createRoutes = createContentApiRoutesFactory(()=>{
|
|
|
11
11
|
handler: 'content-api.upload',
|
|
12
12
|
request: {
|
|
13
13
|
query: {
|
|
14
|
-
id: validator.
|
|
14
|
+
id: validator.fileIdOrDocumentId.optional()
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
response: z.union([
|
|
@@ -55,7 +55,7 @@ const createRoutes = createContentApiRoutesFactory(()=>{
|
|
|
55
55
|
handler: 'content-api.findOne',
|
|
56
56
|
request: {
|
|
57
57
|
params: {
|
|
58
|
-
id: validator.
|
|
58
|
+
id: validator.fileIdOrDocumentId
|
|
59
59
|
},
|
|
60
60
|
query: {
|
|
61
61
|
fields: validator.queryFields.optional(),
|
|
@@ -70,7 +70,7 @@ const createRoutes = createContentApiRoutesFactory(()=>{
|
|
|
70
70
|
handler: 'content-api.destroy',
|
|
71
71
|
request: {
|
|
72
72
|
params: {
|
|
73
|
-
id: validator.
|
|
73
|
+
id: validator.fileIdOrDocumentId
|
|
74
74
|
}
|
|
75
75
|
},
|
|
76
76
|
response: validator.file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-api.mjs","sources":["../../../server/src/routes/content-api.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport * as z from 'zod/v4';\nimport { createContentApiRoutesFactory } from '@strapi/utils';\nimport { UploadRouteValidator } from './validation';\n\nconst createRoutes = createContentApiRoutesFactory((): Core.RouterInput['routes'] => {\n const validator = new UploadRouteValidator(strapi);\n\n return [\n {\n method: 'POST',\n path: '/',\n handler: 'content-api.upload',\n request: {\n query: { id: validator.
|
|
1
|
+
{"version":3,"file":"content-api.mjs","sources":["../../../server/src/routes/content-api.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport * as z from 'zod/v4';\nimport { createContentApiRoutesFactory } from '@strapi/utils';\nimport { UploadRouteValidator } from './validation';\n\nconst createRoutes = createContentApiRoutesFactory((): Core.RouterInput['routes'] => {\n const validator = new UploadRouteValidator(strapi);\n\n return [\n {\n method: 'POST',\n path: '/',\n handler: 'content-api.upload',\n request: {\n query: { id: validator.fileIdOrDocumentId.optional() },\n // Note: multipart/form-data is handled by Koa middleware, not Zod\n },\n response: z.union([validator.file, validator.files]),\n },\n {\n method: 'GET',\n path: '/files',\n handler: 'content-api.find',\n request: {\n query: {\n fields: validator.queryFields.optional(),\n populate: validator.queryPopulate.optional(),\n sort: validator.querySort.optional(),\n pagination: validator.pagination.optional(),\n filters: validator.filters.optional(),\n },\n },\n response: validator.files,\n },\n {\n method: 'GET',\n path: '/files/page',\n handler: 'content-api.findPage',\n request: {\n query: {\n fields: validator.queryFields.optional(),\n populate: validator.queryPopulate.optional(),\n sort: validator.querySort.optional(),\n pagination: validator.pagination.optional(),\n filters: validator.filters.optional(),\n },\n },\n response: validator.paginatedFiles,\n },\n {\n method: 'GET',\n path: '/files/:id',\n handler: 'content-api.findOne',\n request: {\n params: { id: validator.fileIdOrDocumentId },\n query: {\n fields: validator.queryFields.optional(),\n populate: validator.queryPopulate.optional(),\n },\n },\n response: validator.file,\n },\n {\n method: 'DELETE',\n path: '/files/:id',\n handler: 'content-api.destroy',\n request: {\n params: { id: validator.fileIdOrDocumentId },\n },\n response: validator.file,\n },\n ];\n});\n\nexport const routes = createRoutes;\n"],"names":["createRoutes","createContentApiRoutesFactory","validator","UploadRouteValidator","strapi","method","path","handler","request","query","id","fileIdOrDocumentId","optional","response","z","union","file","files","fields","queryFields","populate","queryPopulate","sort","querySort","pagination","filters","paginatedFiles","params","routes"],"mappings":";;;;AAKA,MAAMA,eAAeC,6BAAAA,CAA8B,IAAA;IACjD,MAAMC,SAAAA,GAAY,IAAIC,oBAAAA,CAAqBC,MAAAA,CAAAA;IAE3C,OAAO;AACL,QAAA;YACEC,MAAAA,EAAQ,MAAA;YACRC,IAAAA,EAAM,GAAA;YACNC,OAAAA,EAAS,oBAAA;YACTC,OAAAA,EAAS;gBACPC,KAAAA,EAAO;oBAAEC,EAAAA,EAAIR,SAAAA,CAAUS,kBAAkB,CAACC,QAAQ;AAAG;AAEvD,aAAA;YACAC,QAAAA,EAAUC,CAAAA,CAAEC,KAAK,CAAC;AAACb,gBAAAA,SAAAA,CAAUc,IAAI;AAAEd,gBAAAA,SAAAA,CAAUe;AAAM,aAAA;AACrD,SAAA;AACA,QAAA;YACEZ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,QAAA;YACNC,OAAAA,EAAS,kBAAA;YACTC,OAAAA,EAAS;gBACPC,KAAAA,EAAO;oBACLS,MAAAA,EAAQhB,SAAAA,CAAUiB,WAAW,CAACP,QAAQ,EAAA;oBACtCQ,QAAAA,EAAUlB,SAAAA,CAAUmB,aAAa,CAACT,QAAQ,EAAA;oBAC1CU,IAAAA,EAAMpB,SAAAA,CAAUqB,SAAS,CAACX,QAAQ,EAAA;oBAClCY,UAAAA,EAAYtB,SAAAA,CAAUsB,UAAU,CAACZ,QAAQ,EAAA;oBACzCa,OAAAA,EAASvB,SAAAA,CAAUuB,OAAO,CAACb,QAAQ;AACrC;AACF,aAAA;AACAC,YAAAA,QAAAA,EAAUX,UAAUe;AACtB,SAAA;AACA,QAAA;YACEZ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,aAAA;YACNC,OAAAA,EAAS,sBAAA;YACTC,OAAAA,EAAS;gBACPC,KAAAA,EAAO;oBACLS,MAAAA,EAAQhB,SAAAA,CAAUiB,WAAW,CAACP,QAAQ,EAAA;oBACtCQ,QAAAA,EAAUlB,SAAAA,CAAUmB,aAAa,CAACT,QAAQ,EAAA;oBAC1CU,IAAAA,EAAMpB,SAAAA,CAAUqB,SAAS,CAACX,QAAQ,EAAA;oBAClCY,UAAAA,EAAYtB,SAAAA,CAAUsB,UAAU,CAACZ,QAAQ,EAAA;oBACzCa,OAAAA,EAASvB,SAAAA,CAAUuB,OAAO,CAACb,QAAQ;AACrC;AACF,aAAA;AACAC,YAAAA,QAAAA,EAAUX,UAAUwB;AACtB,SAAA;AACA,QAAA;YACErB,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,YAAA;YACNC,OAAAA,EAAS,qBAAA;YACTC,OAAAA,EAAS;gBACPmB,MAAAA,EAAQ;AAAEjB,oBAAAA,EAAAA,EAAIR,UAAUS;AAAmB,iBAAA;gBAC3CF,KAAAA,EAAO;oBACLS,MAAAA,EAAQhB,SAAAA,CAAUiB,WAAW,CAACP,QAAQ,EAAA;oBACtCQ,QAAAA,EAAUlB,SAAAA,CAAUmB,aAAa,CAACT,QAAQ;AAC5C;AACF,aAAA;AACAC,YAAAA,QAAAA,EAAUX,UAAUc;AACtB,SAAA;AACA,QAAA;YACEX,MAAAA,EAAQ,QAAA;YACRC,IAAAA,EAAM,YAAA;YACNC,OAAAA,EAAS,qBAAA;YACTC,OAAAA,EAAS;gBACPmB,MAAAA,EAAQ;AAAEjB,oBAAAA,EAAAA,EAAIR,UAAUS;AAAmB;AAC7C,aAAA;AACAE,YAAAA,QAAAA,EAAUX,UAAUc;AACtB;AACD,KAAA;AACH,CAAA,CAAA;AAEO,MAAMY,SAAS5B;;;;"}
|
|
@@ -97,6 +97,14 @@ var z__namespace = /*#__PURE__*/_interopNamespace(z);
|
|
|
97
97
|
return z__namespace.number().int().positive();
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
|
+
* Content API file lookup parameter: a numeric id or a documentId
|
|
101
|
+
*/ get fileIdOrDocumentId() {
|
|
102
|
+
return z__namespace.union([
|
|
103
|
+
this.fileId,
|
|
104
|
+
z__namespace.string()
|
|
105
|
+
]);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
100
108
|
* Upload request body schema for single file uploads
|
|
101
109
|
*/ get uploadBody() {
|
|
102
110
|
return z__namespace.object({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sources":["../../../../server/src/routes/validation/upload.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport { AbstractRouteValidator, type QueryParam } from '@strapi/utils';\nimport * as z from 'zod/v4';\n\nexport type FileQueryParam = QueryParam;\n\n/**\n * UploadRouteValidator provides validation for upload/file routes.\n *\n * Extends the AbstractRouteValidator to inherit common query parameter validation\n * while adding file-specific validation schemas.\n */\nexport class UploadRouteValidator extends AbstractRouteValidator {\n protected readonly _strapi: Core.Strapi;\n\n public constructor(strapi: Core.Strapi) {\n super();\n this._strapi = strapi;\n }\n\n /**\n * File schema for upload responses\n * Defines the structure of a file object returned by the upload API\n */\n get file() {\n return z.object({\n id: this.fileId,\n documentId: z.uuid(),\n name: z.string(),\n alternativeText: z.string().nullable().optional(),\n caption: z.string().nullable().optional(),\n width: z.number().int().optional(),\n height: z.number().int().optional(),\n formats: z.record(z.string(), z.unknown()).optional(),\n hash: z.string(),\n ext: z.string().optional(),\n mime: z.string(),\n size: z.number(),\n url: z.string(),\n previewUrl: z.string().nullable().optional(),\n folder: z.number().optional(),\n folderPath: z.string(),\n provider: z.string(),\n provider_metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n createdAt: z.string(),\n updatedAt: z.string(),\n createdBy: z.number().optional(),\n updatedBy: z.number().optional(),\n });\n }\n\n /**\n * Array of files schema\n */\n get files() {\n return z.array(this.file);\n }\n\n /**\n * Paginated files response schema: `{ data, meta: { pagination } }`.\n *\n * Pagination meta is either page-based (`page`/`pageSize`) or offset-based\n * (`start`/`limit`), and `total`/`pageCount` are omitted when\n * `pagination[withCount]=false`.\n */\n get paginatedFiles() {\n const pagedPagination = z.object({\n page: z.number().int(),\n pageSize: z.number().int(),\n pageCount: z.number().int().optional(),\n total: z.number().int().optional(),\n });\n\n const offsetPagination = z.object({\n start: z.number().int(),\n limit: z.number().int(),\n total: z.number().int().optional(),\n });\n\n return z.object({\n data: this.files,\n meta: z.object({\n pagination: z.union([pagedPagination, offsetPagination]),\n }),\n });\n }\n\n /**\n * File ID parameter validation\n */\n get fileId() {\n return z.number().int().positive();\n }\n\n /**\n * Upload request body schema for single file uploads\n */\n get uploadBody() {\n return z.object({\n fileInfo: z\n .object({\n name: z.string().optional(),\n alternativeText: z.string().optional(),\n caption: z.string().optional(),\n })\n .optional(),\n });\n }\n\n /**\n * Upload request body schema for multiple file uploads\n */\n get multiUploadBody() {\n return z.object({\n fileInfo: z\n .array(\n z.object({\n name: z.string().optional(),\n alternativeText: z.string().optional(),\n caption: z.string().optional(),\n })\n )\n .optional(),\n });\n }\n\n // Note: queryParams() method is inherited from AbstractRouteValidator\n // and provides validation for ['fields', 'populate', 'sort', 'pagination', 'filters']\n}\n"],"names":["UploadRouteValidator","AbstractRouteValidator","file","z","object","id","fileId","documentId","uuid","name","string","alternativeText","nullable","optional","caption","width","number","int","height","formats","record","unknown","hash","ext","mime","size","url","previewUrl","folder","folderPath","provider","provider_metadata","createdAt","updatedAt","createdBy","updatedBy","files","array","paginatedFiles","pagedPagination","page","pageSize","pageCount","total","offsetPagination","start","limit","data","meta","pagination","union","positive","uploadBody","fileInfo","multiUploadBody","strapi","_strapi"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"upload.js","sources":["../../../../server/src/routes/validation/upload.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport { AbstractRouteValidator, type QueryParam } from '@strapi/utils';\nimport * as z from 'zod/v4';\n\nexport type FileQueryParam = QueryParam;\n\n/**\n * UploadRouteValidator provides validation for upload/file routes.\n *\n * Extends the AbstractRouteValidator to inherit common query parameter validation\n * while adding file-specific validation schemas.\n */\nexport class UploadRouteValidator extends AbstractRouteValidator {\n protected readonly _strapi: Core.Strapi;\n\n public constructor(strapi: Core.Strapi) {\n super();\n this._strapi = strapi;\n }\n\n /**\n * File schema for upload responses\n * Defines the structure of a file object returned by the upload API\n */\n get file() {\n return z.object({\n id: this.fileId,\n documentId: z.uuid(),\n name: z.string(),\n alternativeText: z.string().nullable().optional(),\n caption: z.string().nullable().optional(),\n width: z.number().int().optional(),\n height: z.number().int().optional(),\n formats: z.record(z.string(), z.unknown()).optional(),\n hash: z.string(),\n ext: z.string().optional(),\n mime: z.string(),\n size: z.number(),\n url: z.string(),\n previewUrl: z.string().nullable().optional(),\n folder: z.number().optional(),\n folderPath: z.string(),\n provider: z.string(),\n provider_metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n createdAt: z.string(),\n updatedAt: z.string(),\n createdBy: z.number().optional(),\n updatedBy: z.number().optional(),\n });\n }\n\n /**\n * Array of files schema\n */\n get files() {\n return z.array(this.file);\n }\n\n /**\n * Paginated files response schema: `{ data, meta: { pagination } }`.\n *\n * Pagination meta is either page-based (`page`/`pageSize`) or offset-based\n * (`start`/`limit`), and `total`/`pageCount` are omitted when\n * `pagination[withCount]=false`.\n */\n get paginatedFiles() {\n const pagedPagination = z.object({\n page: z.number().int(),\n pageSize: z.number().int(),\n pageCount: z.number().int().optional(),\n total: z.number().int().optional(),\n });\n\n const offsetPagination = z.object({\n start: z.number().int(),\n limit: z.number().int(),\n total: z.number().int().optional(),\n });\n\n return z.object({\n data: this.files,\n meta: z.object({\n pagination: z.union([pagedPagination, offsetPagination]),\n }),\n });\n }\n\n /**\n * File ID parameter validation\n */\n get fileId() {\n return z.number().int().positive();\n }\n\n /**\n * Content API file lookup parameter: a numeric id or a documentId\n */\n get fileIdOrDocumentId() {\n return z.union([this.fileId, z.string()]);\n }\n\n /**\n * Upload request body schema for single file uploads\n */\n get uploadBody() {\n return z.object({\n fileInfo: z\n .object({\n name: z.string().optional(),\n alternativeText: z.string().optional(),\n caption: z.string().optional(),\n })\n .optional(),\n });\n }\n\n /**\n * Upload request body schema for multiple file uploads\n */\n get multiUploadBody() {\n return z.object({\n fileInfo: z\n .array(\n z.object({\n name: z.string().optional(),\n alternativeText: z.string().optional(),\n caption: z.string().optional(),\n })\n )\n .optional(),\n });\n }\n\n // Note: queryParams() method is inherited from AbstractRouteValidator\n // and provides validation for ['fields', 'populate', 'sort', 'pagination', 'filters']\n}\n"],"names":["UploadRouteValidator","AbstractRouteValidator","file","z","object","id","fileId","documentId","uuid","name","string","alternativeText","nullable","optional","caption","width","number","int","height","formats","record","unknown","hash","ext","mime","size","url","previewUrl","folder","folderPath","provider","provider_metadata","createdAt","updatedAt","createdBy","updatedBy","files","array","paginatedFiles","pagedPagination","page","pageSize","pageCount","total","offsetPagination","start","limit","data","meta","pagination","union","positive","fileIdOrDocumentId","uploadBody","fileInfo","multiUploadBody","strapi","_strapi"],"mappings":"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"}
|
|
@@ -75,6 +75,14 @@ import * as z from 'zod/v4';
|
|
|
75
75
|
return z.number().int().positive();
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
|
+
* Content API file lookup parameter: a numeric id or a documentId
|
|
79
|
+
*/ get fileIdOrDocumentId() {
|
|
80
|
+
return z.union([
|
|
81
|
+
this.fileId,
|
|
82
|
+
z.string()
|
|
83
|
+
]);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
78
86
|
* Upload request body schema for single file uploads
|
|
79
87
|
*/ get uploadBody() {
|
|
80
88
|
return z.object({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.mjs","sources":["../../../../server/src/routes/validation/upload.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport { AbstractRouteValidator, type QueryParam } from '@strapi/utils';\nimport * as z from 'zod/v4';\n\nexport type FileQueryParam = QueryParam;\n\n/**\n * UploadRouteValidator provides validation for upload/file routes.\n *\n * Extends the AbstractRouteValidator to inherit common query parameter validation\n * while adding file-specific validation schemas.\n */\nexport class UploadRouteValidator extends AbstractRouteValidator {\n protected readonly _strapi: Core.Strapi;\n\n public constructor(strapi: Core.Strapi) {\n super();\n this._strapi = strapi;\n }\n\n /**\n * File schema for upload responses\n * Defines the structure of a file object returned by the upload API\n */\n get file() {\n return z.object({\n id: this.fileId,\n documentId: z.uuid(),\n name: z.string(),\n alternativeText: z.string().nullable().optional(),\n caption: z.string().nullable().optional(),\n width: z.number().int().optional(),\n height: z.number().int().optional(),\n formats: z.record(z.string(), z.unknown()).optional(),\n hash: z.string(),\n ext: z.string().optional(),\n mime: z.string(),\n size: z.number(),\n url: z.string(),\n previewUrl: z.string().nullable().optional(),\n folder: z.number().optional(),\n folderPath: z.string(),\n provider: z.string(),\n provider_metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n createdAt: z.string(),\n updatedAt: z.string(),\n createdBy: z.number().optional(),\n updatedBy: z.number().optional(),\n });\n }\n\n /**\n * Array of files schema\n */\n get files() {\n return z.array(this.file);\n }\n\n /**\n * Paginated files response schema: `{ data, meta: { pagination } }`.\n *\n * Pagination meta is either page-based (`page`/`pageSize`) or offset-based\n * (`start`/`limit`), and `total`/`pageCount` are omitted when\n * `pagination[withCount]=false`.\n */\n get paginatedFiles() {\n const pagedPagination = z.object({\n page: z.number().int(),\n pageSize: z.number().int(),\n pageCount: z.number().int().optional(),\n total: z.number().int().optional(),\n });\n\n const offsetPagination = z.object({\n start: z.number().int(),\n limit: z.number().int(),\n total: z.number().int().optional(),\n });\n\n return z.object({\n data: this.files,\n meta: z.object({\n pagination: z.union([pagedPagination, offsetPagination]),\n }),\n });\n }\n\n /**\n * File ID parameter validation\n */\n get fileId() {\n return z.number().int().positive();\n }\n\n /**\n * Upload request body schema for single file uploads\n */\n get uploadBody() {\n return z.object({\n fileInfo: z\n .object({\n name: z.string().optional(),\n alternativeText: z.string().optional(),\n caption: z.string().optional(),\n })\n .optional(),\n });\n }\n\n /**\n * Upload request body schema for multiple file uploads\n */\n get multiUploadBody() {\n return z.object({\n fileInfo: z\n .array(\n z.object({\n name: z.string().optional(),\n alternativeText: z.string().optional(),\n caption: z.string().optional(),\n })\n )\n .optional(),\n });\n }\n\n // Note: queryParams() method is inherited from AbstractRouteValidator\n // and provides validation for ['fields', 'populate', 'sort', 'pagination', 'filters']\n}\n"],"names":["UploadRouteValidator","AbstractRouteValidator","file","z","object","id","fileId","documentId","uuid","name","string","alternativeText","nullable","optional","caption","width","number","int","height","formats","record","unknown","hash","ext","mime","size","url","previewUrl","folder","folderPath","provider","provider_metadata","createdAt","updatedAt","createdBy","updatedBy","files","array","paginatedFiles","pagedPagination","page","pageSize","pageCount","total","offsetPagination","start","limit","data","meta","pagination","union","positive","uploadBody","fileInfo","multiUploadBody","strapi","_strapi"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"upload.mjs","sources":["../../../../server/src/routes/validation/upload.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport { AbstractRouteValidator, type QueryParam } from '@strapi/utils';\nimport * as z from 'zod/v4';\n\nexport type FileQueryParam = QueryParam;\n\n/**\n * UploadRouteValidator provides validation for upload/file routes.\n *\n * Extends the AbstractRouteValidator to inherit common query parameter validation\n * while adding file-specific validation schemas.\n */\nexport class UploadRouteValidator extends AbstractRouteValidator {\n protected readonly _strapi: Core.Strapi;\n\n public constructor(strapi: Core.Strapi) {\n super();\n this._strapi = strapi;\n }\n\n /**\n * File schema for upload responses\n * Defines the structure of a file object returned by the upload API\n */\n get file() {\n return z.object({\n id: this.fileId,\n documentId: z.uuid(),\n name: z.string(),\n alternativeText: z.string().nullable().optional(),\n caption: z.string().nullable().optional(),\n width: z.number().int().optional(),\n height: z.number().int().optional(),\n formats: z.record(z.string(), z.unknown()).optional(),\n hash: z.string(),\n ext: z.string().optional(),\n mime: z.string(),\n size: z.number(),\n url: z.string(),\n previewUrl: z.string().nullable().optional(),\n folder: z.number().optional(),\n folderPath: z.string(),\n provider: z.string(),\n provider_metadata: z.record(z.string(), z.unknown()).nullable().optional(),\n createdAt: z.string(),\n updatedAt: z.string(),\n createdBy: z.number().optional(),\n updatedBy: z.number().optional(),\n });\n }\n\n /**\n * Array of files schema\n */\n get files() {\n return z.array(this.file);\n }\n\n /**\n * Paginated files response schema: `{ data, meta: { pagination } }`.\n *\n * Pagination meta is either page-based (`page`/`pageSize`) or offset-based\n * (`start`/`limit`), and `total`/`pageCount` are omitted when\n * `pagination[withCount]=false`.\n */\n get paginatedFiles() {\n const pagedPagination = z.object({\n page: z.number().int(),\n pageSize: z.number().int(),\n pageCount: z.number().int().optional(),\n total: z.number().int().optional(),\n });\n\n const offsetPagination = z.object({\n start: z.number().int(),\n limit: z.number().int(),\n total: z.number().int().optional(),\n });\n\n return z.object({\n data: this.files,\n meta: z.object({\n pagination: z.union([pagedPagination, offsetPagination]),\n }),\n });\n }\n\n /**\n * File ID parameter validation\n */\n get fileId() {\n return z.number().int().positive();\n }\n\n /**\n * Content API file lookup parameter: a numeric id or a documentId\n */\n get fileIdOrDocumentId() {\n return z.union([this.fileId, z.string()]);\n }\n\n /**\n * Upload request body schema for single file uploads\n */\n get uploadBody() {\n return z.object({\n fileInfo: z\n .object({\n name: z.string().optional(),\n alternativeText: z.string().optional(),\n caption: z.string().optional(),\n })\n .optional(),\n });\n }\n\n /**\n * Upload request body schema for multiple file uploads\n */\n get multiUploadBody() {\n return z.object({\n fileInfo: z\n .array(\n z.object({\n name: z.string().optional(),\n alternativeText: z.string().optional(),\n caption: z.string().optional(),\n })\n )\n .optional(),\n });\n }\n\n // Note: queryParams() method is inherited from AbstractRouteValidator\n // and provides validation for ['fields', 'populate', 'sort', 'pagination', 'filters']\n}\n"],"names":["UploadRouteValidator","AbstractRouteValidator","file","z","object","id","fileId","documentId","uuid","name","string","alternativeText","nullable","optional","caption","width","number","int","height","formats","record","unknown","hash","ext","mime","size","url","previewUrl","folder","folderPath","provider","provider_metadata","createdAt","updatedAt","createdBy","updatedBy","files","array","paginatedFiles","pagedPagination","page","pageSize","pageCount","total","offsetPagination","start","limit","data","meta","pagination","union","positive","fileIdOrDocumentId","uploadBody","fileInfo","multiUploadBody","strapi","_strapi"],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var z = require('zod/v4');
|
|
4
|
+
var aiMetadataStrapiManaged = require('./ai-metadata-strapi-managed.js');
|
|
5
|
+
|
|
6
|
+
function _interopNamespace(e) {
|
|
7
|
+
if (e && e.__esModule) return e;
|
|
8
|
+
var n = Object.create(null);
|
|
9
|
+
if (e) {
|
|
10
|
+
Object.keys(e).forEach(function (k) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return e[k]; }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var z__namespace = /*#__PURE__*/_interopNamespace(z);
|
|
25
|
+
|
|
26
|
+
const resultSchema = z__namespace.object({
|
|
27
|
+
results: z__namespace.array(z__namespace.object({
|
|
28
|
+
altText: z__namespace.string(),
|
|
29
|
+
caption: z__namespace.string()
|
|
30
|
+
}))
|
|
31
|
+
});
|
|
32
|
+
// This service mirrors i18n's ai-translations service on purpose. Keep the two in sync,
|
|
33
|
+
// and only extract the shared logic once a third feature needs it.
|
|
34
|
+
const createAIMetadataProviderService = ({ strapi })=>{
|
|
35
|
+
let registeredProvider = null;
|
|
36
|
+
const resolveProvider = ()=>{
|
|
37
|
+
if (!strapi.ai.admin.isAvailable()) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return registeredProvider;
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
hasProvider () {
|
|
44
|
+
return resolveProvider() !== null;
|
|
45
|
+
},
|
|
46
|
+
registerProvider ({ provider }) {
|
|
47
|
+
if (!strapi.ai.admin.authorizeCustomProvider()) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (registeredProvider !== null) {
|
|
51
|
+
throw new Error(`The AI metadata provider "${registeredProvider.name}" is already registered, "${provider.name}" cannot replace it.`);
|
|
52
|
+
}
|
|
53
|
+
registeredProvider = provider;
|
|
54
|
+
},
|
|
55
|
+
registerStrapiManagedProvider () {
|
|
56
|
+
if (!strapi.ai.admin.isStrapiManagedAiEnabled()) {
|
|
57
|
+
strapi.log.warn('The Strapi-managed AI metadata provider was ignored: the Strapi license does not include the "cms-ai" feature.');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const provider = aiMetadataStrapiManaged.createStrapiManagedAiMetadataProvider({
|
|
61
|
+
strapi
|
|
62
|
+
});
|
|
63
|
+
if (registeredProvider !== null) {
|
|
64
|
+
throw new Error(`The AI metadata provider "${registeredProvider.name}" is already registered, "${provider.name}" cannot replace it.`);
|
|
65
|
+
}
|
|
66
|
+
registeredProvider = provider;
|
|
67
|
+
},
|
|
68
|
+
async generateMetadata (params) {
|
|
69
|
+
const provider = resolveProvider();
|
|
70
|
+
if (provider === null) {
|
|
71
|
+
throw new Error('No AI metadata provider is registered.');
|
|
72
|
+
}
|
|
73
|
+
const raw = await provider.generateMetadata(params);
|
|
74
|
+
const result = resultSchema.parse(raw);
|
|
75
|
+
const fileCount = result.results.length;
|
|
76
|
+
strapi.log.http(`AI generated metadata successfully for ${fileCount} file${fileCount === 1 ? '' : 's'}`);
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
exports.createAIMetadataProviderService = createAIMetadataProviderService;
|
|
83
|
+
//# sourceMappingURL=ai-metadata-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-metadata-provider.js","sources":["../../../server/src/services/ai-metadata-provider.ts"],"sourcesContent":["import type { Core, Modules } from '@strapi/types';\nimport * as z from 'zod/v4';\n\nimport { createStrapiManagedAiMetadataProvider } from './ai-metadata-strapi-managed';\n\nexport type GenerateMetadataParams = { images: Blob[] };\n\nexport type GenerateMetadataResult = {\n results: Array<{ altText: string; caption: string }>;\n};\n\nexport type AiMetadataProvider = Modules.AI.AiProvider & {\n generateMetadata: (params: GenerateMetadataParams) => Promise<GenerateMetadataResult>;\n};\n\nexport interface AiMetadataProviderService {\n hasProvider(): boolean;\n registerProvider(params: { provider: AiMetadataProvider }): void;\n registerStrapiManagedProvider(): void;\n generateMetadata(params: GenerateMetadataParams): Promise<GenerateMetadataResult>;\n}\n\nconst resultSchema = z.object({\n results: z.array(\n z.object({\n altText: z.string(),\n caption: z.string(),\n })\n ),\n});\n\n// This service mirrors i18n's ai-translations service on purpose. Keep the two in sync,\n// and only extract the shared logic once a third feature needs it.\nconst createAIMetadataProviderService = ({\n strapi,\n}: {\n strapi: Core.Strapi;\n}): AiMetadataProviderService => {\n let registeredProvider: AiMetadataProvider | null = null;\n\n const resolveProvider = (): AiMetadataProvider | null => {\n if (!strapi.ai.admin.isAvailable()) {\n return null;\n }\n\n return registeredProvider;\n };\n\n return {\n hasProvider(): boolean {\n return resolveProvider() !== null;\n },\n\n registerProvider({ provider }: { provider: AiMetadataProvider }) {\n if (!strapi.ai.admin.authorizeCustomProvider()) {\n return;\n }\n\n if (registeredProvider !== null) {\n throw new Error(\n `The AI metadata provider \"${registeredProvider.name}\" is already registered, \"${provider.name}\" cannot replace it.`\n );\n }\n\n registeredProvider = provider;\n },\n\n registerStrapiManagedProvider() {\n if (!strapi.ai.admin.isStrapiManagedAiEnabled()) {\n strapi.log.warn(\n 'The Strapi-managed AI metadata provider was ignored: the Strapi license does not include the \"cms-ai\" feature.'\n );\n return;\n }\n\n const provider = createStrapiManagedAiMetadataProvider({ strapi });\n\n if (registeredProvider !== null) {\n throw new Error(\n `The AI metadata provider \"${registeredProvider.name}\" is already registered, \"${provider.name}\" cannot replace it.`\n );\n }\n\n registeredProvider = provider;\n },\n\n async generateMetadata(params: GenerateMetadataParams): Promise<GenerateMetadataResult> {\n const provider = resolveProvider();\n\n if (provider === null) {\n throw new Error('No AI metadata provider is registered.');\n }\n\n const raw = await provider.generateMetadata(params);\n const result = resultSchema.parse(raw);\n\n const fileCount = result.results.length;\n\n strapi.log.http(\n `AI generated metadata successfully for ${fileCount} file${fileCount === 1 ? '' : 's'}`\n );\n\n return result;\n },\n };\n};\n\nexport { createAIMetadataProviderService };\n"],"names":["resultSchema","z","object","results","array","altText","string","caption","createAIMetadataProviderService","strapi","registeredProvider","resolveProvider","ai","admin","isAvailable","hasProvider","registerProvider","provider","authorizeCustomProvider","Error","name","registerStrapiManagedProvider","isStrapiManagedAiEnabled","log","warn","createStrapiManagedAiMetadataProvider","generateMetadata","params","raw","result","parse","fileCount","length","http"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAMA,YAAAA,GAAeC,YAAAA,CAAEC,MAAM,CAAC;AAC5BC,IAAAA,OAAAA,EAASF,YAAAA,CAAEG,KAAK,CACdH,YAAAA,CAAEC,MAAM,CAAC;AACPG,QAAAA,OAAAA,EAASJ,aAAEK,MAAM,EAAA;AACjBC,QAAAA,OAAAA,EAASN,aAAEK,MAAM;AACnB,KAAA,CAAA;AAEJ,CAAA,CAAA;AAEA;AACA;AACA,MAAME,+BAAAA,GAAkC,CAAC,EACvCC,MAAM,EAGP,GAAA;AACC,IAAA,IAAIC,kBAAAA,GAAgD,IAAA;AAEpD,IAAA,MAAMC,eAAAA,GAAkB,IAAA;AACtB,QAAA,IAAI,CAACF,MAAAA,CAAOG,EAAE,CAACC,KAAK,CAACC,WAAW,EAAA,EAAI;YAClC,OAAO,IAAA;AACT,QAAA;QAEA,OAAOJ,kBAAAA;AACT,IAAA,CAAA;IAEA,OAAO;AACLK,QAAAA,WAAAA,CAAAA,GAAAA;AACE,YAAA,OAAOJ,eAAAA,EAAAA,KAAsB,IAAA;AAC/B,QAAA,CAAA;QAEAK,gBAAAA,CAAAA,CAAiB,EAAEC,QAAQ,EAAoC,EAAA;AAC7D,YAAA,IAAI,CAACR,MAAAA,CAAOG,EAAE,CAACC,KAAK,CAACK,uBAAuB,EAAA,EAAI;AAC9C,gBAAA;AACF,YAAA;AAEA,YAAA,IAAIR,uBAAuB,IAAA,EAAM;AAC/B,gBAAA,MAAM,IAAIS,KAAAA,CACR,CAAC,0BAA0B,EAAET,kBAAAA,CAAmBU,IAAI,CAAC,0BAA0B,EAAEH,QAAAA,CAASG,IAAI,CAAC,oBAAoB,CAAC,CAAA;AAExH,YAAA;YAEAV,kBAAAA,GAAqBO,QAAAA;AACvB,QAAA,CAAA;AAEAI,QAAAA,6BAAAA,CAAAA,GAAAA;AACE,YAAA,IAAI,CAACZ,MAAAA,CAAOG,EAAE,CAACC,KAAK,CAACS,wBAAwB,EAAA,EAAI;gBAC/Cb,MAAAA,CAAOc,GAAG,CAACC,IAAI,CACb,gHAAA,CAAA;AAEF,gBAAA;AACF,YAAA;AAEA,YAAA,MAAMP,WAAWQ,6DAAAA,CAAsC;AAAEhB,gBAAAA;AAAO,aAAA,CAAA;AAEhE,YAAA,IAAIC,uBAAuB,IAAA,EAAM;AAC/B,gBAAA,MAAM,IAAIS,KAAAA,CACR,CAAC,0BAA0B,EAAET,kBAAAA,CAAmBU,IAAI,CAAC,0BAA0B,EAAEH,QAAAA,CAASG,IAAI,CAAC,oBAAoB,CAAC,CAAA;AAExH,YAAA;YAEAV,kBAAAA,GAAqBO,QAAAA;AACvB,QAAA,CAAA;AAEA,QAAA,MAAMS,kBAAiBC,MAA8B,EAAA;AACnD,YAAA,MAAMV,QAAAA,GAAWN,eAAAA,EAAAA;AAEjB,YAAA,IAAIM,aAAa,IAAA,EAAM;AACrB,gBAAA,MAAM,IAAIE,KAAAA,CAAM,wCAAA,CAAA;AAClB,YAAA;AAEA,YAAA,MAAMS,GAAAA,GAAM,MAAMX,QAAAA,CAASS,gBAAgB,CAACC,MAAAA,CAAAA;YAC5C,MAAME,MAAAA,GAAS7B,YAAAA,CAAa8B,KAAK,CAACF,GAAAA,CAAAA;AAElC,YAAA,MAAMG,SAAAA,GAAYF,MAAAA,CAAO1B,OAAO,CAAC6B,MAAM;AAEvCvB,YAAAA,MAAAA,CAAOc,GAAG,CAACU,IAAI,CACb,CAAC,uCAAuC,EAAEF,SAAAA,CAAU,KAAK,EAAEA,SAAAA,KAAc,CAAA,GAAI,KAAK,GAAA,CAAA,CAAK,CAAA;YAGzF,OAAOF,MAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as z from 'zod/v4';
|
|
2
|
+
import { createStrapiManagedAiMetadataProvider } from './ai-metadata-strapi-managed.mjs';
|
|
3
|
+
|
|
4
|
+
const resultSchema = z.object({
|
|
5
|
+
results: z.array(z.object({
|
|
6
|
+
altText: z.string(),
|
|
7
|
+
caption: z.string()
|
|
8
|
+
}))
|
|
9
|
+
});
|
|
10
|
+
// This service mirrors i18n's ai-translations service on purpose. Keep the two in sync,
|
|
11
|
+
// and only extract the shared logic once a third feature needs it.
|
|
12
|
+
const createAIMetadataProviderService = ({ strapi })=>{
|
|
13
|
+
let registeredProvider = null;
|
|
14
|
+
const resolveProvider = ()=>{
|
|
15
|
+
if (!strapi.ai.admin.isAvailable()) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return registeredProvider;
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
hasProvider () {
|
|
22
|
+
return resolveProvider() !== null;
|
|
23
|
+
},
|
|
24
|
+
registerProvider ({ provider }) {
|
|
25
|
+
if (!strapi.ai.admin.authorizeCustomProvider()) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (registeredProvider !== null) {
|
|
29
|
+
throw new Error(`The AI metadata provider "${registeredProvider.name}" is already registered, "${provider.name}" cannot replace it.`);
|
|
30
|
+
}
|
|
31
|
+
registeredProvider = provider;
|
|
32
|
+
},
|
|
33
|
+
registerStrapiManagedProvider () {
|
|
34
|
+
if (!strapi.ai.admin.isStrapiManagedAiEnabled()) {
|
|
35
|
+
strapi.log.warn('The Strapi-managed AI metadata provider was ignored: the Strapi license does not include the "cms-ai" feature.');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const provider = createStrapiManagedAiMetadataProvider({
|
|
39
|
+
strapi
|
|
40
|
+
});
|
|
41
|
+
if (registeredProvider !== null) {
|
|
42
|
+
throw new Error(`The AI metadata provider "${registeredProvider.name}" is already registered, "${provider.name}" cannot replace it.`);
|
|
43
|
+
}
|
|
44
|
+
registeredProvider = provider;
|
|
45
|
+
},
|
|
46
|
+
async generateMetadata (params) {
|
|
47
|
+
const provider = resolveProvider();
|
|
48
|
+
if (provider === null) {
|
|
49
|
+
throw new Error('No AI metadata provider is registered.');
|
|
50
|
+
}
|
|
51
|
+
const raw = await provider.generateMetadata(params);
|
|
52
|
+
const result = resultSchema.parse(raw);
|
|
53
|
+
const fileCount = result.results.length;
|
|
54
|
+
strapi.log.http(`AI generated metadata successfully for ${fileCount} file${fileCount === 1 ? '' : 's'}`);
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export { createAIMetadataProviderService };
|
|
61
|
+
//# sourceMappingURL=ai-metadata-provider.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-metadata-provider.mjs","sources":["../../../server/src/services/ai-metadata-provider.ts"],"sourcesContent":["import type { Core, Modules } from '@strapi/types';\nimport * as z from 'zod/v4';\n\nimport { createStrapiManagedAiMetadataProvider } from './ai-metadata-strapi-managed';\n\nexport type GenerateMetadataParams = { images: Blob[] };\n\nexport type GenerateMetadataResult = {\n results: Array<{ altText: string; caption: string }>;\n};\n\nexport type AiMetadataProvider = Modules.AI.AiProvider & {\n generateMetadata: (params: GenerateMetadataParams) => Promise<GenerateMetadataResult>;\n};\n\nexport interface AiMetadataProviderService {\n hasProvider(): boolean;\n registerProvider(params: { provider: AiMetadataProvider }): void;\n registerStrapiManagedProvider(): void;\n generateMetadata(params: GenerateMetadataParams): Promise<GenerateMetadataResult>;\n}\n\nconst resultSchema = z.object({\n results: z.array(\n z.object({\n altText: z.string(),\n caption: z.string(),\n })\n ),\n});\n\n// This service mirrors i18n's ai-translations service on purpose. Keep the two in sync,\n// and only extract the shared logic once a third feature needs it.\nconst createAIMetadataProviderService = ({\n strapi,\n}: {\n strapi: Core.Strapi;\n}): AiMetadataProviderService => {\n let registeredProvider: AiMetadataProvider | null = null;\n\n const resolveProvider = (): AiMetadataProvider | null => {\n if (!strapi.ai.admin.isAvailable()) {\n return null;\n }\n\n return registeredProvider;\n };\n\n return {\n hasProvider(): boolean {\n return resolveProvider() !== null;\n },\n\n registerProvider({ provider }: { provider: AiMetadataProvider }) {\n if (!strapi.ai.admin.authorizeCustomProvider()) {\n return;\n }\n\n if (registeredProvider !== null) {\n throw new Error(\n `The AI metadata provider \"${registeredProvider.name}\" is already registered, \"${provider.name}\" cannot replace it.`\n );\n }\n\n registeredProvider = provider;\n },\n\n registerStrapiManagedProvider() {\n if (!strapi.ai.admin.isStrapiManagedAiEnabled()) {\n strapi.log.warn(\n 'The Strapi-managed AI metadata provider was ignored: the Strapi license does not include the \"cms-ai\" feature.'\n );\n return;\n }\n\n const provider = createStrapiManagedAiMetadataProvider({ strapi });\n\n if (registeredProvider !== null) {\n throw new Error(\n `The AI metadata provider \"${registeredProvider.name}\" is already registered, \"${provider.name}\" cannot replace it.`\n );\n }\n\n registeredProvider = provider;\n },\n\n async generateMetadata(params: GenerateMetadataParams): Promise<GenerateMetadataResult> {\n const provider = resolveProvider();\n\n if (provider === null) {\n throw new Error('No AI metadata provider is registered.');\n }\n\n const raw = await provider.generateMetadata(params);\n const result = resultSchema.parse(raw);\n\n const fileCount = result.results.length;\n\n strapi.log.http(\n `AI generated metadata successfully for ${fileCount} file${fileCount === 1 ? '' : 's'}`\n );\n\n return result;\n },\n };\n};\n\nexport { createAIMetadataProviderService };\n"],"names":["resultSchema","z","object","results","array","altText","string","caption","createAIMetadataProviderService","strapi","registeredProvider","resolveProvider","ai","admin","isAvailable","hasProvider","registerProvider","provider","authorizeCustomProvider","Error","name","registerStrapiManagedProvider","isStrapiManagedAiEnabled","log","warn","createStrapiManagedAiMetadataProvider","generateMetadata","params","raw","result","parse","fileCount","length","http"],"mappings":";;;AAsBA,MAAMA,YAAAA,GAAeC,CAAAA,CAAEC,MAAM,CAAC;AAC5BC,IAAAA,OAAAA,EAASF,CAAAA,CAAEG,KAAK,CACdH,CAAAA,CAAEC,MAAM,CAAC;AACPG,QAAAA,OAAAA,EAASJ,EAAEK,MAAM,EAAA;AACjBC,QAAAA,OAAAA,EAASN,EAAEK,MAAM;AACnB,KAAA,CAAA;AAEJ,CAAA,CAAA;AAEA;AACA;AACA,MAAME,+BAAAA,GAAkC,CAAC,EACvCC,MAAM,EAGP,GAAA;AACC,IAAA,IAAIC,kBAAAA,GAAgD,IAAA;AAEpD,IAAA,MAAMC,eAAAA,GAAkB,IAAA;AACtB,QAAA,IAAI,CAACF,MAAAA,CAAOG,EAAE,CAACC,KAAK,CAACC,WAAW,EAAA,EAAI;YAClC,OAAO,IAAA;AACT,QAAA;QAEA,OAAOJ,kBAAAA;AACT,IAAA,CAAA;IAEA,OAAO;AACLK,QAAAA,WAAAA,CAAAA,GAAAA;AACE,YAAA,OAAOJ,eAAAA,EAAAA,KAAsB,IAAA;AAC/B,QAAA,CAAA;QAEAK,gBAAAA,CAAAA,CAAiB,EAAEC,QAAQ,EAAoC,EAAA;AAC7D,YAAA,IAAI,CAACR,MAAAA,CAAOG,EAAE,CAACC,KAAK,CAACK,uBAAuB,EAAA,EAAI;AAC9C,gBAAA;AACF,YAAA;AAEA,YAAA,IAAIR,uBAAuB,IAAA,EAAM;AAC/B,gBAAA,MAAM,IAAIS,KAAAA,CACR,CAAC,0BAA0B,EAAET,kBAAAA,CAAmBU,IAAI,CAAC,0BAA0B,EAAEH,QAAAA,CAASG,IAAI,CAAC,oBAAoB,CAAC,CAAA;AAExH,YAAA;YAEAV,kBAAAA,GAAqBO,QAAAA;AACvB,QAAA,CAAA;AAEAI,QAAAA,6BAAAA,CAAAA,GAAAA;AACE,YAAA,IAAI,CAACZ,MAAAA,CAAOG,EAAE,CAACC,KAAK,CAACS,wBAAwB,EAAA,EAAI;gBAC/Cb,MAAAA,CAAOc,GAAG,CAACC,IAAI,CACb,gHAAA,CAAA;AAEF,gBAAA;AACF,YAAA;AAEA,YAAA,MAAMP,WAAWQ,qCAAAA,CAAsC;AAAEhB,gBAAAA;AAAO,aAAA,CAAA;AAEhE,YAAA,IAAIC,uBAAuB,IAAA,EAAM;AAC/B,gBAAA,MAAM,IAAIS,KAAAA,CACR,CAAC,0BAA0B,EAAET,kBAAAA,CAAmBU,IAAI,CAAC,0BAA0B,EAAEH,QAAAA,CAASG,IAAI,CAAC,oBAAoB,CAAC,CAAA;AAExH,YAAA;YAEAV,kBAAAA,GAAqBO,QAAAA;AACvB,QAAA,CAAA;AAEA,QAAA,MAAMS,kBAAiBC,MAA8B,EAAA;AACnD,YAAA,MAAMV,QAAAA,GAAWN,eAAAA,EAAAA;AAEjB,YAAA,IAAIM,aAAa,IAAA,EAAM;AACrB,gBAAA,MAAM,IAAIE,KAAAA,CAAM,wCAAA,CAAA;AAClB,YAAA;AAEA,YAAA,MAAMS,GAAAA,GAAM,MAAMX,QAAAA,CAASS,gBAAgB,CAACC,MAAAA,CAAAA;YAC5C,MAAME,MAAAA,GAAS7B,YAAAA,CAAa8B,KAAK,CAACF,GAAAA,CAAAA;AAElC,YAAA,MAAMG,SAAAA,GAAYF,MAAAA,CAAO1B,OAAO,CAAC6B,MAAM;AAEvCvB,YAAAA,MAAAA,CAAOc,GAAG,CAACU,IAAI,CACb,CAAC,uCAAuC,EAAEF,SAAAA,CAAU,KAAK,EAAEA,SAAAA,KAAc,CAAA,GAAI,KAAK,GAAA,CAAA,CAAK,CAAA;YAGzF,OAAOF,MAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const createStrapiManagedAiMetadataProvider = ({ strapi })=>{
|
|
4
|
+
// TODO(ai): add a helper function to get the AI server URL
|
|
5
|
+
const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';
|
|
6
|
+
const getAiToken = async ()=>{
|
|
7
|
+
try {
|
|
8
|
+
const { token } = await strapi.ai.admin.getAiToken();
|
|
9
|
+
return token;
|
|
10
|
+
} catch (error) {
|
|
11
|
+
throw new Error('Failed to retrieve AI token', {
|
|
12
|
+
cause: error instanceof Error ? error : undefined
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
name: 'strapi-managed',
|
|
18
|
+
async generateMetadata ({ images }) {
|
|
19
|
+
const formData = new FormData();
|
|
20
|
+
for (const image of images){
|
|
21
|
+
formData.append('files', image);
|
|
22
|
+
}
|
|
23
|
+
const token = await getAiToken();
|
|
24
|
+
strapi.log.http('Contacting AI Server for media metadata generation', {
|
|
25
|
+
aiServerUrl,
|
|
26
|
+
imageCount: images.length
|
|
27
|
+
});
|
|
28
|
+
const res = await fetch(`${aiServerUrl}/media-library/generate-metadata`, {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
body: formData,
|
|
31
|
+
headers: {
|
|
32
|
+
Authorization: `Bearer ${token}`
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
const errorText = await res.text();
|
|
37
|
+
strapi.log.error(`AI metadata generation request failed: ${res.status} ${res.statusText}`);
|
|
38
|
+
throw Error(`AI metadata generation failed`, {
|
|
39
|
+
cause: errorText
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return await res.json();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
exports.createStrapiManagedAiMetadataProvider = createStrapiManagedAiMetadataProvider;
|
|
48
|
+
//# sourceMappingURL=ai-metadata-strapi-managed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-metadata-strapi-managed.js","sources":["../../../server/src/services/ai-metadata-strapi-managed.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport type { AiMetadataProvider } from './ai-metadata-provider';\n\nconst createStrapiManagedAiMetadataProvider = ({\n strapi,\n}: {\n strapi: Core.Strapi;\n}): AiMetadataProvider => {\n // TODO(ai): add a helper function to get the AI server URL\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n const getAiToken = async () => {\n try {\n const { token } = await strapi.ai.admin.getAiToken();\n return token;\n } catch (error) {\n throw new Error('Failed to retrieve AI token', {\n cause: error instanceof Error ? error : undefined,\n });\n }\n };\n\n return {\n name: 'strapi-managed',\n\n async generateMetadata({ images }) {\n const formData = new FormData();\n\n for (const image of images) {\n formData.append('files', image);\n }\n\n const token = await getAiToken();\n\n strapi.log.http('Contacting AI Server for media metadata generation', {\n aiServerUrl,\n imageCount: images.length,\n });\n\n const res = await fetch(`${aiServerUrl}/media-library/generate-metadata`, {\n method: 'POST',\n body: formData,\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!res.ok) {\n const errorText = await res.text();\n strapi.log.error(`AI metadata generation request failed: ${res.status} ${res.statusText}`);\n\n throw Error(`AI metadata generation failed`, { cause: errorText });\n }\n\n return (await res.json()) as Awaited<ReturnType<AiMetadataProvider['generateMetadata']>>;\n },\n };\n};\n\nexport { createStrapiManagedAiMetadataProvider };\n"],"names":["createStrapiManagedAiMetadataProvider","strapi","aiServerUrl","process","env","STRAPI_AI_URL","getAiToken","token","ai","admin","error","Error","cause","undefined","name","generateMetadata","images","formData","FormData","image","append","log","http","imageCount","length","res","fetch","method","body","headers","Authorization","ok","errorText","text","status","statusText","json"],"mappings":";;AAIA,MAAMA,qCAAAA,GAAwC,CAAC,EAC7CC,MAAM,EAGP,GAAA;;AAEC,IAAA,MAAMC,WAAAA,GAAcC,OAAAA,CAAQC,GAAG,CAACC,aAAa,IAAI,kCAAA;AAEjD,IAAA,MAAMC,UAAAA,GAAa,UAAA;QACjB,IAAI;YACF,MAAM,EAAEC,KAAK,EAAE,GAAG,MAAMN,OAAOO,EAAE,CAACC,KAAK,CAACH,UAAU,EAAA;YAClD,OAAOC,KAAAA;AACT,QAAA,CAAA,CAAE,OAAOG,KAAAA,EAAO;YACd,MAAM,IAAIC,MAAM,6BAAA,EAA+B;gBAC7CC,KAAAA,EAAOF,KAAAA,YAAiBC,QAAQD,KAAAA,GAAQG;AAC1C,aAAA,CAAA;AACF,QAAA;AACF,IAAA,CAAA;IAEA,OAAO;QACLC,IAAAA,EAAM,gBAAA;QAEN,MAAMC,gBAAAA,CAAAA,CAAiB,EAAEC,MAAM,EAAE,EAAA;AAC/B,YAAA,MAAMC,WAAW,IAAIC,QAAAA,EAAAA;YAErB,KAAK,MAAMC,SAASH,MAAAA,CAAQ;gBAC1BC,QAAAA,CAASG,MAAM,CAAC,OAAA,EAASD,KAAAA,CAAAA;AAC3B,YAAA;AAEA,YAAA,MAAMZ,QAAQ,MAAMD,UAAAA,EAAAA;AAEpBL,YAAAA,MAAAA,CAAOoB,GAAG,CAACC,IAAI,CAAC,oDAAA,EAAsD;AACpEpB,gBAAAA,WAAAA;AACAqB,gBAAAA,UAAAA,EAAYP,OAAOQ;AACrB,aAAA,CAAA;AAEA,YAAA,MAAMC,MAAM,MAAMC,KAAAA,CAAM,GAAGxB,WAAAA,CAAY,gCAAgC,CAAC,EAAE;gBACxEyB,MAAAA,EAAQ,MAAA;gBACRC,IAAAA,EAAMX,QAAAA;gBACNY,OAAAA,EAAS;oBACPC,aAAAA,EAAe,CAAC,OAAO,EAAEvB,KAAAA,CAAAA;AAC3B;AACF,aAAA,CAAA;YAEA,IAAI,CAACkB,GAAAA,CAAIM,EAAE,EAAE;gBACX,MAAMC,SAAAA,GAAY,MAAMP,GAAAA,CAAIQ,IAAI,EAAA;AAChChC,gBAAAA,MAAAA,CAAOoB,GAAG,CAACX,KAAK,CAAC,CAAC,uCAAuC,EAAEe,GAAAA,CAAIS,MAAM,CAAC,CAAC,EAAET,GAAAA,CAAIU,UAAU,CAAA,CAAE,CAAA;AAEzF,gBAAA,MAAMxB,KAAAA,CAAM,CAAC,6BAA6B,CAAC,EAAE;oBAAEC,KAAAA,EAAOoB;AAAU,iBAAA,CAAA;AAClE,YAAA;YAEA,OAAQ,MAAMP,IAAIW,IAAI,EAAA;AACxB,QAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const createStrapiManagedAiMetadataProvider = ({ strapi })=>{
|
|
2
|
+
// TODO(ai): add a helper function to get the AI server URL
|
|
3
|
+
const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';
|
|
4
|
+
const getAiToken = async ()=>{
|
|
5
|
+
try {
|
|
6
|
+
const { token } = await strapi.ai.admin.getAiToken();
|
|
7
|
+
return token;
|
|
8
|
+
} catch (error) {
|
|
9
|
+
throw new Error('Failed to retrieve AI token', {
|
|
10
|
+
cause: error instanceof Error ? error : undefined
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
name: 'strapi-managed',
|
|
16
|
+
async generateMetadata ({ images }) {
|
|
17
|
+
const formData = new FormData();
|
|
18
|
+
for (const image of images){
|
|
19
|
+
formData.append('files', image);
|
|
20
|
+
}
|
|
21
|
+
const token = await getAiToken();
|
|
22
|
+
strapi.log.http('Contacting AI Server for media metadata generation', {
|
|
23
|
+
aiServerUrl,
|
|
24
|
+
imageCount: images.length
|
|
25
|
+
});
|
|
26
|
+
const res = await fetch(`${aiServerUrl}/media-library/generate-metadata`, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
body: formData,
|
|
29
|
+
headers: {
|
|
30
|
+
Authorization: `Bearer ${token}`
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
const errorText = await res.text();
|
|
35
|
+
strapi.log.error(`AI metadata generation request failed: ${res.status} ${res.statusText}`);
|
|
36
|
+
throw Error(`AI metadata generation failed`, {
|
|
37
|
+
cause: errorText
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return await res.json();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { createStrapiManagedAiMetadataProvider };
|
|
46
|
+
//# sourceMappingURL=ai-metadata-strapi-managed.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-metadata-strapi-managed.mjs","sources":["../../../server/src/services/ai-metadata-strapi-managed.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport type { AiMetadataProvider } from './ai-metadata-provider';\n\nconst createStrapiManagedAiMetadataProvider = ({\n strapi,\n}: {\n strapi: Core.Strapi;\n}): AiMetadataProvider => {\n // TODO(ai): add a helper function to get the AI server URL\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n const getAiToken = async () => {\n try {\n const { token } = await strapi.ai.admin.getAiToken();\n return token;\n } catch (error) {\n throw new Error('Failed to retrieve AI token', {\n cause: error instanceof Error ? error : undefined,\n });\n }\n };\n\n return {\n name: 'strapi-managed',\n\n async generateMetadata({ images }) {\n const formData = new FormData();\n\n for (const image of images) {\n formData.append('files', image);\n }\n\n const token = await getAiToken();\n\n strapi.log.http('Contacting AI Server for media metadata generation', {\n aiServerUrl,\n imageCount: images.length,\n });\n\n const res = await fetch(`${aiServerUrl}/media-library/generate-metadata`, {\n method: 'POST',\n body: formData,\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!res.ok) {\n const errorText = await res.text();\n strapi.log.error(`AI metadata generation request failed: ${res.status} ${res.statusText}`);\n\n throw Error(`AI metadata generation failed`, { cause: errorText });\n }\n\n return (await res.json()) as Awaited<ReturnType<AiMetadataProvider['generateMetadata']>>;\n },\n };\n};\n\nexport { createStrapiManagedAiMetadataProvider };\n"],"names":["createStrapiManagedAiMetadataProvider","strapi","aiServerUrl","process","env","STRAPI_AI_URL","getAiToken","token","ai","admin","error","Error","cause","undefined","name","generateMetadata","images","formData","FormData","image","append","log","http","imageCount","length","res","fetch","method","body","headers","Authorization","ok","errorText","text","status","statusText","json"],"mappings":"AAIA,MAAMA,qCAAAA,GAAwC,CAAC,EAC7CC,MAAM,EAGP,GAAA;;AAEC,IAAA,MAAMC,WAAAA,GAAcC,OAAAA,CAAQC,GAAG,CAACC,aAAa,IAAI,kCAAA;AAEjD,IAAA,MAAMC,UAAAA,GAAa,UAAA;QACjB,IAAI;YACF,MAAM,EAAEC,KAAK,EAAE,GAAG,MAAMN,OAAOO,EAAE,CAACC,KAAK,CAACH,UAAU,EAAA;YAClD,OAAOC,KAAAA;AACT,QAAA,CAAA,CAAE,OAAOG,KAAAA,EAAO;YACd,MAAM,IAAIC,MAAM,6BAAA,EAA+B;gBAC7CC,KAAAA,EAAOF,KAAAA,YAAiBC,QAAQD,KAAAA,GAAQG;AAC1C,aAAA,CAAA;AACF,QAAA;AACF,IAAA,CAAA;IAEA,OAAO;QACLC,IAAAA,EAAM,gBAAA;QAEN,MAAMC,gBAAAA,CAAAA,CAAiB,EAAEC,MAAM,EAAE,EAAA;AAC/B,YAAA,MAAMC,WAAW,IAAIC,QAAAA,EAAAA;YAErB,KAAK,MAAMC,SAASH,MAAAA,CAAQ;gBAC1BC,QAAAA,CAASG,MAAM,CAAC,OAAA,EAASD,KAAAA,CAAAA;AAC3B,YAAA;AAEA,YAAA,MAAMZ,QAAQ,MAAMD,UAAAA,EAAAA;AAEpBL,YAAAA,MAAAA,CAAOoB,GAAG,CAACC,IAAI,CAAC,oDAAA,EAAsD;AACpEpB,gBAAAA,WAAAA;AACAqB,gBAAAA,UAAAA,EAAYP,OAAOQ;AACrB,aAAA,CAAA;AAEA,YAAA,MAAMC,MAAM,MAAMC,KAAAA,CAAM,GAAGxB,WAAAA,CAAY,gCAAgC,CAAC,EAAE;gBACxEyB,MAAAA,EAAQ,MAAA;gBACRC,IAAAA,EAAMX,QAAAA;gBACNY,OAAAA,EAAS;oBACPC,aAAAA,EAAe,CAAC,OAAO,EAAEvB,KAAAA,CAAAA;AAC3B;AACF,aAAA,CAAA;YAEA,IAAI,CAACkB,GAAAA,CAAIM,EAAE,EAAE;gBACX,MAAMC,SAAAA,GAAY,MAAMP,GAAAA,CAAIQ,IAAI,EAAA;AAChChC,gBAAAA,MAAAA,CAAOoB,GAAG,CAACX,KAAK,CAAC,CAAC,uCAAuC,EAAEe,GAAAA,CAAIS,MAAM,CAAC,CAAC,EAAET,GAAAA,CAAIU,UAAU,CAAA,CAAE,CAAA;AAEzF,gBAAA,MAAMxB,KAAAA,CAAM,CAAC,6BAA6B,CAAC,EAAE;oBAAEC,KAAAA,EAAOoB;AAAU,iBAAA,CAAA;AAClE,YAAA;YAEA,OAAQ,MAAMP,IAAIW,IAAI,EAAA;AACxB,QAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -1,30 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var z = require('zod/v4');
|
|
4
3
|
var index = require('../utils/index.js');
|
|
5
4
|
var images = require('../utils/images.js');
|
|
6
5
|
var constants = require('../shared/constants.js');
|
|
7
6
|
|
|
8
|
-
function _interopNamespace(e) {
|
|
9
|
-
if (e && e.__esModule) return e;
|
|
10
|
-
var n = Object.create(null);
|
|
11
|
-
if (e) {
|
|
12
|
-
Object.keys(e).forEach(function (k) {
|
|
13
|
-
if (k !== 'default') {
|
|
14
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
15
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
16
|
-
enumerable: true,
|
|
17
|
-
get: function () { return e[k]; }
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
n.default = e;
|
|
23
|
-
return Object.freeze(n);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
var z__namespace = /*#__PURE__*/_interopNamespace(z);
|
|
27
|
-
|
|
28
7
|
/**
|
|
29
8
|
* Supported image types for AI metadata generation. Lives in `shared/` so the
|
|
30
9
|
* admin panel gates the bulk action on exactly what the provider accepts.
|
|
@@ -38,10 +17,9 @@ const chunk = (items, size)=>{
|
|
|
38
17
|
return chunks;
|
|
39
18
|
};
|
|
40
19
|
const createAIMetadataService = ({ strapi })=>{
|
|
41
|
-
const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';
|
|
42
20
|
return {
|
|
43
21
|
async isEnabled () {
|
|
44
|
-
if (
|
|
22
|
+
if (!index.getService('aiMetadataProvider').hasProvider()) {
|
|
45
23
|
return false;
|
|
46
24
|
}
|
|
47
25
|
const settings = await strapi.plugin('upload').service('upload').getSettings();
|
|
@@ -276,7 +254,7 @@ const createAIMetadataService = ({ strapi })=>{
|
|
|
276
254
|
/**
|
|
277
255
|
* Processes provided files for AI metadata generation
|
|
278
256
|
*/ async processFiles (files) {
|
|
279
|
-
if (!await this.isEnabled()
|
|
257
|
+
if (!await this.isEnabled()) {
|
|
280
258
|
throw new Error('AI Metadata service is not enabled');
|
|
281
259
|
}
|
|
282
260
|
// Filter for image files only and track their original positions
|
|
@@ -304,41 +282,10 @@ const createAIMetadataService = ({ strapi })=>{
|
|
|
304
282
|
if (imageFiles.length === 0) {
|
|
305
283
|
return createEmptyMetadataResults();
|
|
306
284
|
}
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
const tokenData = await strapi.ai.admin.getAiToken();
|
|
311
|
-
token = tokenData.token;
|
|
312
|
-
} catch (error) {
|
|
313
|
-
throw new Error('Failed to retrieve AI token', {
|
|
314
|
-
cause: error instanceof Error ? error : undefined
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
strapi.log.http('Contacting AI Server for media metadata generation', {
|
|
318
|
-
aiServerUrl,
|
|
319
|
-
imageCount: imageFiles.length
|
|
320
|
-
});
|
|
321
|
-
const res = await fetch(`${aiServerUrl}/media-library/generate-metadata`, {
|
|
322
|
-
method: 'POST',
|
|
323
|
-
body: formData,
|
|
324
|
-
headers: {
|
|
325
|
-
Authorization: `Bearer ${token}`
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
if (!res.ok) {
|
|
329
|
-
const errorText = await res.text();
|
|
330
|
-
throw Error(`AI metadata generation failed`, {
|
|
331
|
-
cause: errorText
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
const responseSchema = z__namespace.object({
|
|
335
|
-
results: z__namespace.array(z__namespace.object({
|
|
336
|
-
altText: z__namespace.string(),
|
|
337
|
-
caption: z__namespace.string()
|
|
338
|
-
}))
|
|
285
|
+
const images$1 = await images.fetchImagesAsBlobs(imageInputFiles, strapi.config.get('server.absoluteUrl'), strapi.log);
|
|
286
|
+
const { results } = await index.getService('aiMetadataProvider').generateMetadata({
|
|
287
|
+
images: images$1
|
|
339
288
|
});
|
|
340
|
-
const { results } = responseSchema.parse(await res.json());
|
|
341
|
-
strapi.log.http(`AI generated metadata successfully for ${results.length} files`);
|
|
342
289
|
// Create sparse array with results at original indices
|
|
343
290
|
// Example: files=[img1, pdf, img2] -> imageFiles=[{img1, index:0}, {img2, index:2}]
|
|
344
291
|
// AI results=[meta1, meta2] -> sparse=[meta1, null, meta2]
|