@strapi/upload 5.26.0 → 5.28.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/ai/components/AIAssetCard.js +589 -0
- package/dist/admin/ai/components/AIAssetCard.js.map +1 -0
- package/dist/admin/ai/components/AIAssetCard.mjs +567 -0
- package/dist/admin/ai/components/AIAssetCard.mjs.map +1 -0
- package/dist/admin/ai/components/AIUploadModal.js +363 -0
- package/dist/admin/ai/components/AIUploadModal.js.map +1 -0
- package/dist/admin/ai/components/AIUploadModal.mjs +341 -0
- package/dist/admin/ai/components/AIUploadModal.mjs.map +1 -0
- package/dist/admin/components/AssetDialog/AssetDialog.js +1 -1
- package/dist/admin/components/AssetDialog/AssetDialog.js.map +1 -1
- package/dist/admin/components/AssetDialog/AssetDialog.mjs +1 -1
- package/dist/admin/components/AssetDialog/AssetDialog.mjs.map +1 -1
- package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.js +3 -3
- package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.js.map +1 -1
- package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs +4 -4
- package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.js +5 -5
- package/dist/admin/components/EditAssetDialog/EditAssetContent.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs +5 -5
- package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.js +2 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.mjs +2 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.mjs.map +1 -1
- package/dist/admin/components/SelectTree/utils/flattenTree.js +11 -6
- package/dist/admin/components/SelectTree/utils/flattenTree.js.map +1 -1
- package/dist/admin/components/SelectTree/utils/flattenTree.mjs +11 -6
- package/dist/admin/components/SelectTree/utils/flattenTree.mjs.map +1 -1
- package/dist/admin/hooks/useAiAvailability.js +22 -0
- package/dist/admin/hooks/useAiAvailability.js.map +1 -0
- package/dist/admin/hooks/useAiAvailability.mjs +20 -0
- package/dist/admin/hooks/useAiAvailability.mjs.map +1 -0
- package/dist/admin/hooks/useBulkEdit.js +66 -0
- package/dist/admin/hooks/useBulkEdit.js.map +1 -0
- package/dist/admin/hooks/useBulkEdit.mjs +64 -0
- package/dist/admin/hooks/useBulkEdit.mjs.map +1 -0
- package/dist/admin/hooks/useSettings.js +22 -0
- package/dist/admin/hooks/useSettings.js.map +1 -0
- package/dist/admin/hooks/useSettings.mjs +20 -0
- package/dist/admin/hooks/useSettings.mjs.map +1 -0
- package/dist/admin/hooks/useUpload.js +25 -14
- package/dist/admin/hooks/useUpload.js.map +1 -1
- package/dist/admin/hooks/useUpload.mjs +25 -14
- package/dist/admin/hooks/useUpload.mjs.map +1 -1
- package/dist/admin/package.json.js +5 -5
- package/dist/admin/package.json.mjs +5 -5
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js +0 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs +0 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
- package/dist/admin/pages/App/MediaLibrary/MediaLibrary.js +19 -5
- package/dist/admin/pages/App/MediaLibrary/MediaLibrary.js.map +1 -1
- package/dist/admin/pages/App/MediaLibrary/MediaLibrary.mjs +19 -5
- package/dist/admin/pages/App/MediaLibrary/MediaLibrary.mjs.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.js +222 -144
- package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs +225 -147
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
- package/dist/admin/pages/SettingsPage/reducer.js +9 -10
- package/dist/admin/pages/SettingsPage/reducer.js.map +1 -1
- package/dist/admin/pages/SettingsPage/reducer.mjs +9 -10
- package/dist/admin/pages/SettingsPage/reducer.mjs.map +1 -1
- package/dist/admin/src/ai/components/AIAssetCard.d.ts +13 -0
- package/dist/admin/src/ai/components/AIUploadModal.d.ts +55 -0
- package/dist/admin/src/components/EditAssetDialog/EditAssetContent.d.ts +3 -1
- package/dist/admin/src/components/SelectTree/utils/flattenTree.d.ts +3 -1
- package/dist/admin/src/hooks/useAiAvailability.d.ts +4 -0
- package/dist/admin/src/hooks/useBulkEdit.d.ts +91 -0
- package/dist/admin/src/hooks/useSettings.d.ts +7 -0
- package/dist/admin/src/hooks/useUpload.d.ts +1 -1
- package/dist/admin/src/pages/SettingsPage/reducer.d.ts +3 -12
- package/dist/admin/translations/en.json.js +7 -1
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +7 -1
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/utils/getFolderParents.js +2 -1
- package/dist/admin/utils/getFolderParents.js.map +1 -1
- package/dist/admin/utils/getFolderParents.mjs +2 -1
- package/dist/admin/utils/getFolderParents.mjs.map +1 -1
- package/dist/server/bootstrap.js +2 -1
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/bootstrap.mjs +2 -1
- package/dist/server/bootstrap.mjs.map +1 -1
- package/dist/server/controllers/admin-upload.js +57 -2
- package/dist/server/controllers/admin-upload.js.map +1 -1
- package/dist/server/controllers/admin-upload.mjs +59 -4
- package/dist/server/controllers/admin-upload.mjs.map +1 -1
- package/dist/server/controllers/content-api.js +3 -1
- package/dist/server/controllers/content-api.js.map +1 -1
- package/dist/server/controllers/content-api.mjs +3 -1
- package/dist/server/controllers/content-api.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/settings.js +2 -1
- package/dist/server/controllers/validation/admin/settings.js.map +1 -1
- package/dist/server/controllers/validation/admin/settings.mjs +2 -1
- package/dist/server/controllers/validation/admin/settings.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/upload.js +8 -0
- package/dist/server/controllers/validation/admin/upload.js.map +1 -1
- package/dist/server/controllers/validation/admin/upload.mjs +8 -1
- package/dist/server/controllers/validation/admin/upload.mjs.map +1 -1
- package/dist/server/routes/admin.js +18 -0
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +18 -0
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/services/ai-metadata.js +97 -0
- package/dist/server/services/ai-metadata.js.map +1 -0
- package/dist/server/services/ai-metadata.mjs +95 -0
- package/dist/server/services/ai-metadata.mjs.map +1 -0
- 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/upload.js.map +1 -1
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/services/weekly-metrics.js +5 -1
- package/dist/server/services/weekly-metrics.js.map +1 -1
- package/dist/server/services/weekly-metrics.mjs +5 -1
- 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-upload.d.ts +1 -0
- package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +1 -0
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/settings.d.ts +3 -0
- package/dist/server/src/controllers/validation/admin/settings.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/admin/upload.d.ts +42 -0
- package/dist/server/src/controllers/validation/admin/upload.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +14 -1
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/services/ai-metadata.d.ts +13 -0
- package/dist/server/src/services/ai-metadata.d.ts.map +1 -0
- package/dist/server/src/services/index.d.ts +13 -1
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/upload.d.ts +2 -1
- package/dist/server/src/services/upload.d.ts.map +1 -1
- package/dist/server/src/services/weekly-metrics.d.ts +1 -0
- package/dist/server/src/services/weekly-metrics.d.ts.map +1 -1
- package/dist/server/src/types.d.ts +1 -0
- package/dist/server/src/types.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/index.js.map +1 -1
- package/dist/server/utils/index.mjs.map +1 -1
- package/dist/shared/contracts/files.d.ts +22 -0
- package/dist/shared/contracts/settings.d.ts +2 -0
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reducer.mjs","sources":["../../../../admin/src/pages/SettingsPage/reducer.ts"],"sourcesContent":["import { produce } from 'immer';\nimport set from 'lodash/set';\n\
|
|
1
|
+
{"version":3,"file":"reducer.mjs","sources":["../../../../admin/src/pages/SettingsPage/reducer.ts"],"sourcesContent":["import { produce } from 'immer';\nimport set from 'lodash/set';\n\nimport { SettingsData } from '../../../../shared/contracts/settings';\n\nconst initialData: SettingsData = {\n responsiveDimensions: true,\n sizeOptimization: true,\n autoOrientation: false,\n videoPreview: false,\n aiMetadata: true,\n};\n\nexport type InitialState = {\n initialData: SettingsData | null;\n modifiedData: SettingsData | null;\n};\n\ninterface ActionGetDataSucceeded {\n type: 'GET_DATA_SUCCEEDED';\n data: InitialState['initialData'];\n}\n\ninterface ActionOnChange {\n type: 'ON_CHANGE';\n keys: keyof NonNullable<InitialState['initialData']>;\n value: boolean;\n}\n\nexport type Action = ActionGetDataSucceeded | ActionOnChange;\n\nconst initialState: InitialState = {\n initialData,\n modifiedData: { ...initialData },\n};\n\nconst reducer = (state: InitialState, action: Action) =>\n produce(state, (drafState) => {\n switch (action.type) {\n case 'GET_DATA_SUCCEEDED': {\n drafState.initialData = action.data;\n drafState.modifiedData = action.data;\n break;\n }\n case 'ON_CHANGE': {\n set(drafState, ['modifiedData', ...action.keys.split('.')], action.value);\n break;\n }\n default:\n return state;\n }\n });\n\nexport { initialState, reducer };\n"],"names":["initialData","responsiveDimensions","sizeOptimization","autoOrientation","videoPreview","aiMetadata","initialState","modifiedData","reducer","state","action","produce","drafState","type","data","set","keys","split","value"],"mappings":";;;AAKA,MAAMA,WAA4B,GAAA;IAChCC,oBAAsB,EAAA,IAAA;IACtBC,gBAAkB,EAAA,IAAA;IAClBC,eAAiB,EAAA,KAAA;IACjBC,YAAc,EAAA,KAAA;IACdC,UAAY,EAAA;AACd,CAAA;AAoBA,MAAMC,YAA6B,GAAA;AACjCN,IAAAA,WAAAA;IACAO,YAAc,EAAA;AAAE,QAAA,GAAGP;AAAY;AACjC;AAEA,MAAMQ,UAAU,CAACC,KAAAA,EAAqBC,MACpCC,GAAAA,OAAAA,CAAQF,OAAO,CAACG,SAAAA,GAAAA;AACd,QAAA,OAAQF,OAAOG,IAAI;YACjB,KAAK,oBAAA;AAAsB,gBAAA;oBACzBD,SAAUZ,CAAAA,WAAW,GAAGU,MAAAA,CAAOI,IAAI;oBACnCF,SAAUL,CAAAA,YAAY,GAAGG,MAAAA,CAAOI,IAAI;AACpC,oBAAA;AACF;YACA,KAAK,WAAA;AAAa,gBAAA;AAChBC,oBAAAA,GAAAA,CAAIH,SAAW,EAAA;AAAC,wBAAA,cAAA;2BAAmBF,MAAOM,CAAAA,IAAI,CAACC,KAAK,CAAC,GAAA;AAAK,qBAAA,EAAEP,OAAOQ,KAAK,CAAA;AACxE,oBAAA;AACF;AACA,YAAA;gBACE,OAAOT,KAAAA;AACX;AACF,KAAA;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { File } from '../../../../shared/contracts/files';
|
|
2
|
+
interface AssetCardProps {
|
|
3
|
+
asset: File;
|
|
4
|
+
onCaptionChange: (caption: string) => void;
|
|
5
|
+
onAltTextChange: (altText: string) => void;
|
|
6
|
+
wasCaptionChanged: boolean;
|
|
7
|
+
wasAltTextChanged: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const AIAssetCard: ({ asset, onCaptionChange, onAltTextChange, wasAltTextChanged, wasCaptionChanged, }: AssetCardProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare const AIAssetCardSkeletons: ({ count }: {
|
|
11
|
+
count?: number;
|
|
12
|
+
}) => import("react/jsx-runtime").JSX.Element[];
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { File } from '../../../../shared/contracts/files';
|
|
3
|
+
interface AIUploadModalProps {
|
|
4
|
+
open: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
folderId?: number | null;
|
|
7
|
+
}
|
|
8
|
+
type State = {
|
|
9
|
+
uploadedAssets: Array<{
|
|
10
|
+
file: File;
|
|
11
|
+
wasCaptionChanged: boolean;
|
|
12
|
+
wasAltTextChanged: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
assetsToUploadLength: number;
|
|
15
|
+
hasUnsavedChanges: boolean;
|
|
16
|
+
};
|
|
17
|
+
type Action = {
|
|
18
|
+
type: 'set_uploaded_assets';
|
|
19
|
+
payload: File[];
|
|
20
|
+
} | {
|
|
21
|
+
type: 'set_assets_to_upload_length';
|
|
22
|
+
payload: number;
|
|
23
|
+
} | {
|
|
24
|
+
type: 'set_uploaded_asset_caption';
|
|
25
|
+
payload: {
|
|
26
|
+
id: number;
|
|
27
|
+
caption: string;
|
|
28
|
+
};
|
|
29
|
+
} | {
|
|
30
|
+
type: 'set_uploaded_asset_alt_text';
|
|
31
|
+
payload: {
|
|
32
|
+
id: number;
|
|
33
|
+
altText: string;
|
|
34
|
+
};
|
|
35
|
+
} | {
|
|
36
|
+
type: 'remove_uploaded_asset';
|
|
37
|
+
payload: {
|
|
38
|
+
id: number;
|
|
39
|
+
};
|
|
40
|
+
} | {
|
|
41
|
+
type: 'edit_uploaded_asset';
|
|
42
|
+
payload: {
|
|
43
|
+
editedAsset: File;
|
|
44
|
+
};
|
|
45
|
+
} | {
|
|
46
|
+
type: 'clear_unsaved_changes';
|
|
47
|
+
};
|
|
48
|
+
declare const useAIUploadModalContext: <Selected, ShouldThrow extends boolean = true>(consumerName: string, selector: (value: {
|
|
49
|
+
state: State;
|
|
50
|
+
dispatch: React.Dispatch<Action>;
|
|
51
|
+
folderId: number | null;
|
|
52
|
+
onClose: () => void;
|
|
53
|
+
}) => Selected, shouldThrowOnMissingContext?: ShouldThrow | undefined) => ShouldThrow extends true ? Selected : Selected | undefined;
|
|
54
|
+
export declare const AIUploadModal: ({ open, onClose, folderId }: AIUploadModalProps) => import("react/jsx-runtime").JSX.Element;
|
|
55
|
+
export { useAIUploadModalContext };
|
|
@@ -13,8 +13,10 @@ interface EditAssetContentProps {
|
|
|
13
13
|
canDownload?: boolean;
|
|
14
14
|
trackedLocation?: string;
|
|
15
15
|
onClose: (arg?: Asset | null | boolean) => void;
|
|
16
|
+
omitFields?: ('caption' | 'alternativeText')[];
|
|
17
|
+
omitActions?: 'replace'[];
|
|
16
18
|
}
|
|
17
|
-
export declare const EditAssetContent: ({ onClose, asset, canUpdate, canCopyLink, canDownload, trackedLocation, }: EditAssetContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export declare const EditAssetContent: ({ onClose, asset, canUpdate, canCopyLink, canDownload, trackedLocation, omitFields, omitActions, }: EditAssetContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
18
20
|
interface EditAssetDialogProps {
|
|
19
21
|
asset: Asset;
|
|
20
22
|
canUpdate?: boolean;
|
|
@@ -2,13 +2,15 @@ type TreeNode<T> = {
|
|
|
2
2
|
value: T;
|
|
3
3
|
children?: TreeNode<T>[];
|
|
4
4
|
label?: string;
|
|
5
|
+
path?: string;
|
|
5
6
|
};
|
|
6
7
|
export type FlattenedNode<T> = {
|
|
7
8
|
value: T;
|
|
8
9
|
parent?: T;
|
|
9
10
|
depth: number;
|
|
10
11
|
label?: string;
|
|
12
|
+
path?: string;
|
|
11
13
|
children?: TreeNode<T>[];
|
|
12
14
|
};
|
|
13
|
-
export declare function flattenTree<T>(tree: TreeNode<T>[], parent?: TreeNode<T> | null, depth?: number): FlattenedNode<T>[];
|
|
15
|
+
export declare function flattenTree<T>(tree: TreeNode<T>[], parent?: TreeNode<T> | null, depth?: number, path?: string): FlattenedNode<T>[];
|
|
14
16
|
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { BulkUpdateFiles } from '../../../shared/contracts/files';
|
|
2
|
+
interface FileInfoUpdate {
|
|
3
|
+
name: string;
|
|
4
|
+
alternativeText: string | null;
|
|
5
|
+
caption: string | null;
|
|
6
|
+
folder: number | null;
|
|
7
|
+
}
|
|
8
|
+
interface BulkEditParams {
|
|
9
|
+
updates: Array<{
|
|
10
|
+
id: number;
|
|
11
|
+
fileInfo: FileInfoUpdate;
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
14
|
+
export declare const useBulkEdit: () => {
|
|
15
|
+
edit: (updates: Array<{
|
|
16
|
+
id: number;
|
|
17
|
+
fileInfo: FileInfoUpdate;
|
|
18
|
+
}>) => Promise<BulkUpdateFiles.Response>;
|
|
19
|
+
data: undefined;
|
|
20
|
+
error: null;
|
|
21
|
+
isError: false;
|
|
22
|
+
isIdle: true;
|
|
23
|
+
isLoading: false;
|
|
24
|
+
isSuccess: false;
|
|
25
|
+
status: "idle";
|
|
26
|
+
mutate: import("react-query").UseMutateFunction<BulkUpdateFiles.Response, import("@strapi/utils/dist/errors").ApplicationError<"ApplicationError", string, unknown> | import("@strapi/utils/dist/errors").ValidationError<string, unknown> | undefined, BulkEditParams, unknown>;
|
|
27
|
+
reset: () => void;
|
|
28
|
+
context: unknown;
|
|
29
|
+
failureCount: number;
|
|
30
|
+
isPaused: boolean;
|
|
31
|
+
variables: BulkEditParams | undefined;
|
|
32
|
+
mutateAsync: import("react-query").UseMutateAsyncFunction<BulkUpdateFiles.Response, import("@strapi/utils/dist/errors").ApplicationError<"ApplicationError", string, unknown> | import("@strapi/utils/dist/errors").ValidationError<string, unknown> | undefined, BulkEditParams, unknown>;
|
|
33
|
+
} | {
|
|
34
|
+
edit: (updates: Array<{
|
|
35
|
+
id: number;
|
|
36
|
+
fileInfo: FileInfoUpdate;
|
|
37
|
+
}>) => Promise<BulkUpdateFiles.Response>;
|
|
38
|
+
data: undefined;
|
|
39
|
+
error: null;
|
|
40
|
+
isError: false;
|
|
41
|
+
isIdle: false;
|
|
42
|
+
isLoading: true;
|
|
43
|
+
isSuccess: false;
|
|
44
|
+
status: "loading";
|
|
45
|
+
mutate: import("react-query").UseMutateFunction<BulkUpdateFiles.Response, import("@strapi/utils/dist/errors").ApplicationError<"ApplicationError", string, unknown> | import("@strapi/utils/dist/errors").ValidationError<string, unknown> | undefined, BulkEditParams, unknown>;
|
|
46
|
+
reset: () => void;
|
|
47
|
+
context: unknown;
|
|
48
|
+
failureCount: number;
|
|
49
|
+
isPaused: boolean;
|
|
50
|
+
variables: BulkEditParams | undefined;
|
|
51
|
+
mutateAsync: import("react-query").UseMutateAsyncFunction<BulkUpdateFiles.Response, import("@strapi/utils/dist/errors").ApplicationError<"ApplicationError", string, unknown> | import("@strapi/utils/dist/errors").ValidationError<string, unknown> | undefined, BulkEditParams, unknown>;
|
|
52
|
+
} | {
|
|
53
|
+
edit: (updates: Array<{
|
|
54
|
+
id: number;
|
|
55
|
+
fileInfo: FileInfoUpdate;
|
|
56
|
+
}>) => Promise<BulkUpdateFiles.Response>;
|
|
57
|
+
data: undefined;
|
|
58
|
+
error: import("@strapi/utils/dist/errors").ApplicationError<"ApplicationError", string, unknown> | import("@strapi/utils/dist/errors").ValidationError<string, unknown> | undefined;
|
|
59
|
+
isError: true;
|
|
60
|
+
isIdle: false;
|
|
61
|
+
isLoading: false;
|
|
62
|
+
isSuccess: false;
|
|
63
|
+
status: "error";
|
|
64
|
+
mutate: import("react-query").UseMutateFunction<BulkUpdateFiles.Response, import("@strapi/utils/dist/errors").ApplicationError<"ApplicationError", string, unknown> | import("@strapi/utils/dist/errors").ValidationError<string, unknown> | undefined, BulkEditParams, unknown>;
|
|
65
|
+
reset: () => void;
|
|
66
|
+
context: unknown;
|
|
67
|
+
failureCount: number;
|
|
68
|
+
isPaused: boolean;
|
|
69
|
+
variables: BulkEditParams | undefined;
|
|
70
|
+
mutateAsync: import("react-query").UseMutateAsyncFunction<BulkUpdateFiles.Response, import("@strapi/utils/dist/errors").ApplicationError<"ApplicationError", string, unknown> | import("@strapi/utils/dist/errors").ValidationError<string, unknown> | undefined, BulkEditParams, unknown>;
|
|
71
|
+
} | {
|
|
72
|
+
edit: (updates: Array<{
|
|
73
|
+
id: number;
|
|
74
|
+
fileInfo: FileInfoUpdate;
|
|
75
|
+
}>) => Promise<BulkUpdateFiles.Response>;
|
|
76
|
+
data: BulkUpdateFiles.Response;
|
|
77
|
+
error: null;
|
|
78
|
+
isError: false;
|
|
79
|
+
isIdle: false;
|
|
80
|
+
isLoading: false;
|
|
81
|
+
isSuccess: true;
|
|
82
|
+
status: "success";
|
|
83
|
+
mutate: import("react-query").UseMutateFunction<BulkUpdateFiles.Response, import("@strapi/utils/dist/errors").ApplicationError<"ApplicationError", string, unknown> | import("@strapi/utils/dist/errors").ValidationError<string, unknown> | undefined, BulkEditParams, unknown>;
|
|
84
|
+
reset: () => void;
|
|
85
|
+
context: unknown;
|
|
86
|
+
failureCount: number;
|
|
87
|
+
isPaused: boolean;
|
|
88
|
+
variables: BulkEditParams | undefined;
|
|
89
|
+
mutateAsync: import("react-query").UseMutateAsyncFunction<BulkUpdateFiles.Response, import("@strapi/utils/dist/errors").ApplicationError<"ApplicationError", string, unknown> | import("@strapi/utils/dist/errors").ValidationError<string, unknown> | undefined, BulkEditParams, unknown>;
|
|
90
|
+
};
|
|
91
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function useSettings(isEnabled?: boolean): import("react-query").UseQueryResult<{
|
|
2
|
+
sizeOptimization?: boolean | undefined;
|
|
3
|
+
responsiveDimensions?: boolean | undefined;
|
|
4
|
+
autoOrientation?: boolean | undefined;
|
|
5
|
+
videoPreview?: boolean | undefined;
|
|
6
|
+
aiMetadata?: boolean | undefined;
|
|
7
|
+
}, unknown>;
|
|
@@ -5,7 +5,7 @@ interface Asset extends Omit<File, 'id' | 'hash'> {
|
|
|
5
5
|
hash?: File['hash'];
|
|
6
6
|
}
|
|
7
7
|
export declare const useUpload: () => {
|
|
8
|
-
upload: (
|
|
8
|
+
upload: (assets: Asset | Asset[], folderId: number | null) => Promise<File[]>;
|
|
9
9
|
isLoading: boolean;
|
|
10
10
|
cancel: () => void;
|
|
11
11
|
error: import("@strapi/utils/dist/errors").ApplicationError<"ApplicationError", string, unknown> | import("@strapi/utils/dist/errors").ValidationError<string, unknown> | null | undefined;
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
+
import { SettingsData } from '../../../../shared/contracts/settings';
|
|
1
2
|
export type InitialState = {
|
|
2
|
-
initialData:
|
|
3
|
-
|
|
4
|
-
sizeOptimization?: boolean;
|
|
5
|
-
autoOrientation?: boolean;
|
|
6
|
-
videoPreview?: boolean;
|
|
7
|
-
} | null;
|
|
8
|
-
modifiedData: {
|
|
9
|
-
responsiveDimensions?: boolean;
|
|
10
|
-
sizeOptimization?: boolean;
|
|
11
|
-
autoOrientation?: boolean;
|
|
12
|
-
videoPreview?: boolean;
|
|
13
|
-
} | null;
|
|
3
|
+
initialData: SettingsData | null;
|
|
4
|
+
modifiedData: SettingsData | null;
|
|
14
5
|
};
|
|
15
6
|
interface ActionGetDataSucceeded {
|
|
16
7
|
type: 'GET_DATA_SUCCEEDED';
|
|
@@ -14,6 +14,7 @@ var en = {
|
|
|
14
14
|
"control-card.crop": "Crop",
|
|
15
15
|
"control-card.download": "Download",
|
|
16
16
|
"control-card.edit": "Edit",
|
|
17
|
+
"control-card.remove-selection": "Remove from selection",
|
|
17
18
|
"control-card.replace-media": "Replace Media",
|
|
18
19
|
"control-card.save": "Save",
|
|
19
20
|
"control-card.stop-crop": "Stop cropping",
|
|
@@ -22,6 +23,7 @@ var en = {
|
|
|
22
23
|
"form.input.description.file-alt": "This text will be displayed if the asset can’t be shown.",
|
|
23
24
|
"form.input.label.file-alt": "Alternative text",
|
|
24
25
|
"form.input.label.file-caption": "Caption",
|
|
26
|
+
"form.input.placeholder.file-caption": "Enter caption",
|
|
25
27
|
"form.input.label.file-name": "File name",
|
|
26
28
|
"form.upload-url.error.url.invalid": "One URL is invalid",
|
|
27
29
|
"form.upload-url.error.url.invalids": "{number} URLs are invalids",
|
|
@@ -107,6 +109,7 @@ var en = {
|
|
|
107
109
|
"settings.form.videoPreview.description": "It will generate a six-second preview of the video (GIF)",
|
|
108
110
|
"settings.form.videoPreview.label": "Preview",
|
|
109
111
|
"settings.header.label": "Media Library",
|
|
112
|
+
"settings.section.audio.label": "Audio",
|
|
110
113
|
"settings.section.doc.label": "Doc",
|
|
111
114
|
"settings.section.image.label": "Image",
|
|
112
115
|
"settings.section.video.label": "Video",
|
|
@@ -138,7 +141,10 @@ var en = {
|
|
|
138
141
|
"config.note": "Note: You can override this value in the media library.",
|
|
139
142
|
"config.popUpWarning.warning.updateAllSettings": "This will modify all your settings",
|
|
140
143
|
"view-switch.list": "List View",
|
|
141
|
-
"view-switch.grid": "Grid View"
|
|
144
|
+
"view-switch.grid": "Grid View",
|
|
145
|
+
"ai.modal.uploading.title": "Uploading and processing with AI...",
|
|
146
|
+
"ai.modal.title": "{count, plural, one {# asset uploaded} other {# assets uploaded}}, review AI generated metadata",
|
|
147
|
+
"ai.modal.error": "Could not generate AI metadata for the uploaded files."
|
|
142
148
|
};
|
|
143
149
|
|
|
144
150
|
module.exports = en;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -12,6 +12,7 @@ var en = {
|
|
|
12
12
|
"control-card.crop": "Crop",
|
|
13
13
|
"control-card.download": "Download",
|
|
14
14
|
"control-card.edit": "Edit",
|
|
15
|
+
"control-card.remove-selection": "Remove from selection",
|
|
15
16
|
"control-card.replace-media": "Replace Media",
|
|
16
17
|
"control-card.save": "Save",
|
|
17
18
|
"control-card.stop-crop": "Stop cropping",
|
|
@@ -20,6 +21,7 @@ var en = {
|
|
|
20
21
|
"form.input.description.file-alt": "This text will be displayed if the asset can’t be shown.",
|
|
21
22
|
"form.input.label.file-alt": "Alternative text",
|
|
22
23
|
"form.input.label.file-caption": "Caption",
|
|
24
|
+
"form.input.placeholder.file-caption": "Enter caption",
|
|
23
25
|
"form.input.label.file-name": "File name",
|
|
24
26
|
"form.upload-url.error.url.invalid": "One URL is invalid",
|
|
25
27
|
"form.upload-url.error.url.invalids": "{number} URLs are invalids",
|
|
@@ -105,6 +107,7 @@ var en = {
|
|
|
105
107
|
"settings.form.videoPreview.description": "It will generate a six-second preview of the video (GIF)",
|
|
106
108
|
"settings.form.videoPreview.label": "Preview",
|
|
107
109
|
"settings.header.label": "Media Library",
|
|
110
|
+
"settings.section.audio.label": "Audio",
|
|
108
111
|
"settings.section.doc.label": "Doc",
|
|
109
112
|
"settings.section.image.label": "Image",
|
|
110
113
|
"settings.section.video.label": "Video",
|
|
@@ -136,7 +139,10 @@ var en = {
|
|
|
136
139
|
"config.note": "Note: You can override this value in the media library.",
|
|
137
140
|
"config.popUpWarning.warning.updateAllSettings": "This will modify all your settings",
|
|
138
141
|
"view-switch.list": "List View",
|
|
139
|
-
"view-switch.grid": "Grid View"
|
|
142
|
+
"view-switch.grid": "Grid View",
|
|
143
|
+
"ai.modal.uploading.title": "Uploading and processing with AI...",
|
|
144
|
+
"ai.modal.title": "{count, plural, one {# asset uploaded} other {# assets uploaded}}, review AI generated metadata",
|
|
145
|
+
"ai.modal.error": "Could not generate AI metadata for the uploaded files."
|
|
140
146
|
};
|
|
141
147
|
|
|
142
148
|
export { en as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -15,7 +15,8 @@ const getFolderParents = (folders, currentFolderId)=>{
|
|
|
15
15
|
const parentToStore = flatFolders.find(({ value })=>value === parent);
|
|
16
16
|
parents.push({
|
|
17
17
|
id: parentToStore?.value,
|
|
18
|
-
label: parentToStore?.label
|
|
18
|
+
label: parentToStore?.label,
|
|
19
|
+
path: parentToStore?.path
|
|
19
20
|
});
|
|
20
21
|
parent = parentToStore?.parent;
|
|
21
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFolderParents.js","sources":["../../../admin/src/utils/getFolderParents.ts"],"sourcesContent":["import { flattenTree } from '../components/SelectTree/utils/flattenTree';\n\nimport type { FolderNode } from '../../../shared/contracts/folders';\n\ninterface FolderStructureValue extends Omit<FolderNode, 'children'> {\n value: string | number | null;\n children?: FolderStructureValue[];\n}\n\ntype Parents = { id?: number | string | null; label?: string; path?: string }[];\n\nexport const getFolderParents = (folders: FolderStructureValue[], currentFolderId: number) => {\n const parents: Parents = [];\n const flatFolders = flattenTree(folders);\n const currentFolder = flatFolders.find((folder) => folder.value === currentFolderId);\n\n if (!currentFolder) {\n return [];\n }\n\n let { parent } = currentFolder;\n\n while (parent !== undefined) {\n // eslint-disable-next-line no-loop-func\n const parentToStore = flatFolders.find(({ value }) => value === parent);\n parents.push({
|
|
1
|
+
{"version":3,"file":"getFolderParents.js","sources":["../../../admin/src/utils/getFolderParents.ts"],"sourcesContent":["import { flattenTree } from '../components/SelectTree/utils/flattenTree';\n\nimport type { FolderNode } from '../../../shared/contracts/folders';\n\ninterface FolderStructureValue extends Omit<FolderNode, 'children'> {\n value: string | number | null;\n children?: FolderStructureValue[];\n}\n\ntype Parents = { id?: number | string | null; label?: string; path?: string }[];\n\nexport const getFolderParents = (folders: FolderStructureValue[], currentFolderId: number) => {\n const parents: Parents = [];\n const flatFolders = flattenTree(folders);\n const currentFolder = flatFolders.find((folder) => folder.value === currentFolderId);\n\n if (!currentFolder) {\n return [];\n }\n\n let { parent } = currentFolder;\n\n while (parent !== undefined) {\n // eslint-disable-next-line no-loop-func\n const parentToStore = flatFolders.find(({ value }) => value === parent);\n parents.push({\n id: parentToStore?.value,\n label: parentToStore?.label,\n path: parentToStore?.path,\n });\n parent = parentToStore?.parent;\n }\n\n return parents.reverse();\n};\n"],"names":["getFolderParents","folders","currentFolderId","parents","flatFolders","flattenTree","currentFolder","find","folder","value","parent","undefined","parentToStore","push","id","label","path","reverse"],"mappings":";;;;AAWO,MAAMA,gBAAmB,GAAA,CAACC,OAAiCC,EAAAA,eAAAA,GAAAA;AAChE,IAAA,MAAMC,UAAmB,EAAE;AAC3B,IAAA,MAAMC,cAAcC,uBAAYJ,CAAAA,OAAAA,CAAAA;IAChC,MAAMK,aAAAA,GAAgBF,YAAYG,IAAI,CAAC,CAACC,MAAWA,GAAAA,MAAAA,CAAOC,KAAK,KAAKP,eAAAA,CAAAA;AAEpE,IAAA,IAAI,CAACI,aAAe,EAAA;AAClB,QAAA,OAAO,EAAE;AACX;IAEA,IAAI,EAAEI,MAAM,EAAE,GAAGJ,aAAAA;AAEjB,IAAA,MAAOI,WAAWC,SAAW,CAAA;;QAE3B,MAAMC,aAAAA,GAAgBR,YAAYG,IAAI,CAAC,CAAC,EAAEE,KAAK,EAAE,GAAKA,KAAUC,KAAAA,MAAAA,CAAAA;AAChEP,QAAAA,OAAAA,CAAQU,IAAI,CAAC;AACXC,YAAAA,EAAAA,EAAIF,aAAeH,EAAAA,KAAAA;AACnBM,YAAAA,KAAAA,EAAOH,aAAeG,EAAAA,KAAAA;AACtBC,YAAAA,IAAAA,EAAMJ,aAAeI,EAAAA;AACvB,SAAA,CAAA;AACAN,QAAAA,MAAAA,GAASE,aAAeF,EAAAA,MAAAA;AAC1B;AAEA,IAAA,OAAOP,QAAQc,OAAO,EAAA;AACxB;;;;"}
|
|
@@ -13,7 +13,8 @@ const getFolderParents = (folders, currentFolderId)=>{
|
|
|
13
13
|
const parentToStore = flatFolders.find(({ value })=>value === parent);
|
|
14
14
|
parents.push({
|
|
15
15
|
id: parentToStore?.value,
|
|
16
|
-
label: parentToStore?.label
|
|
16
|
+
label: parentToStore?.label,
|
|
17
|
+
path: parentToStore?.path
|
|
17
18
|
});
|
|
18
19
|
parent = parentToStore?.parent;
|
|
19
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFolderParents.mjs","sources":["../../../admin/src/utils/getFolderParents.ts"],"sourcesContent":["import { flattenTree } from '../components/SelectTree/utils/flattenTree';\n\nimport type { FolderNode } from '../../../shared/contracts/folders';\n\ninterface FolderStructureValue extends Omit<FolderNode, 'children'> {\n value: string | number | null;\n children?: FolderStructureValue[];\n}\n\ntype Parents = { id?: number | string | null; label?: string; path?: string }[];\n\nexport const getFolderParents = (folders: FolderStructureValue[], currentFolderId: number) => {\n const parents: Parents = [];\n const flatFolders = flattenTree(folders);\n const currentFolder = flatFolders.find((folder) => folder.value === currentFolderId);\n\n if (!currentFolder) {\n return [];\n }\n\n let { parent } = currentFolder;\n\n while (parent !== undefined) {\n // eslint-disable-next-line no-loop-func\n const parentToStore = flatFolders.find(({ value }) => value === parent);\n parents.push({
|
|
1
|
+
{"version":3,"file":"getFolderParents.mjs","sources":["../../../admin/src/utils/getFolderParents.ts"],"sourcesContent":["import { flattenTree } from '../components/SelectTree/utils/flattenTree';\n\nimport type { FolderNode } from '../../../shared/contracts/folders';\n\ninterface FolderStructureValue extends Omit<FolderNode, 'children'> {\n value: string | number | null;\n children?: FolderStructureValue[];\n}\n\ntype Parents = { id?: number | string | null; label?: string; path?: string }[];\n\nexport const getFolderParents = (folders: FolderStructureValue[], currentFolderId: number) => {\n const parents: Parents = [];\n const flatFolders = flattenTree(folders);\n const currentFolder = flatFolders.find((folder) => folder.value === currentFolderId);\n\n if (!currentFolder) {\n return [];\n }\n\n let { parent } = currentFolder;\n\n while (parent !== undefined) {\n // eslint-disable-next-line no-loop-func\n const parentToStore = flatFolders.find(({ value }) => value === parent);\n parents.push({\n id: parentToStore?.value,\n label: parentToStore?.label,\n path: parentToStore?.path,\n });\n parent = parentToStore?.parent;\n }\n\n return parents.reverse();\n};\n"],"names":["getFolderParents","folders","currentFolderId","parents","flatFolders","flattenTree","currentFolder","find","folder","value","parent","undefined","parentToStore","push","id","label","path","reverse"],"mappings":";;AAWO,MAAMA,gBAAmB,GAAA,CAACC,OAAiCC,EAAAA,eAAAA,GAAAA;AAChE,IAAA,MAAMC,UAAmB,EAAE;AAC3B,IAAA,MAAMC,cAAcC,WAAYJ,CAAAA,OAAAA,CAAAA;IAChC,MAAMK,aAAAA,GAAgBF,YAAYG,IAAI,CAAC,CAACC,MAAWA,GAAAA,MAAAA,CAAOC,KAAK,KAAKP,eAAAA,CAAAA;AAEpE,IAAA,IAAI,CAACI,aAAe,EAAA;AAClB,QAAA,OAAO,EAAE;AACX;IAEA,IAAI,EAAEI,MAAM,EAAE,GAAGJ,aAAAA;AAEjB,IAAA,MAAOI,WAAWC,SAAW,CAAA;;QAE3B,MAAMC,aAAAA,GAAgBR,YAAYG,IAAI,CAAC,CAAC,EAAEE,KAAK,EAAE,GAAKA,KAAUC,KAAAA,MAAAA,CAAAA;AAChEP,QAAAA,OAAAA,CAAQU,IAAI,CAAC;AACXC,YAAAA,EAAAA,EAAIF,aAAeH,EAAAA,KAAAA;AACnBM,YAAAA,KAAAA,EAAOH,aAAeG,EAAAA,KAAAA;AACtBC,YAAAA,IAAAA,EAAMJ,aAAeI,EAAAA;AACvB,SAAA,CAAA;AACAN,QAAAA,MAAAA,GAASE,aAAeF,EAAAA,MAAAA;AAC1B;AAEA,IAAA,OAAOP,QAAQc,OAAO,EAAA;AACxB;;;;"}
|
package/dist/server/bootstrap.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":";;;;;AAKO,eAAeA,SAAAA,CAAU,EAAEC,MAAAA,EAAAA,OAAM,EAA2B,EAAA;AACjE,IAAA,MAAMC,aAAgB,GAAA;QACpBC,QAAU,EAAA;YACRC,gBAAkB,EAAA,IAAA;YAClBC,oBAAsB,EAAA,IAAA;YACtBC,eAAiB,EAAA;
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":";;;AAKO,eAAeA,SAAAA,CAAU,EAAEC,MAAAA,EAAAA,OAAM,EAA2B,EAAA;AACjE,IAAA,MAAMC,aAAgB,GAAA;QACpBC,QAAU,EAAA;YACRC,gBAAkB,EAAA,IAAA;YAClBC,oBAAsB,EAAA,IAAA;YACtBC,eAAiB,EAAA;
|
|
1
|
+
{"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
|
|
@@ -8,6 +8,21 @@ var upload = require('./validation/admin/upload.js');
|
|
|
8
8
|
var findEntityAndCheckPermissions = require('./utils/find-entity-and-check-permissions.js');
|
|
9
9
|
|
|
10
10
|
var adminUpload = {
|
|
11
|
+
async bulkUpdateFileInfo (ctx) {
|
|
12
|
+
const { state: { userAbility, user }, request: { body } } = ctx;
|
|
13
|
+
const { updates } = await upload.validateBulkUpdateBody(body);
|
|
14
|
+
const uploadService = index.getService('upload');
|
|
15
|
+
const results = await utils.async.map(updates, async ({ id, fileInfo })=>{
|
|
16
|
+
const { pm } = await findEntityAndCheckPermissions.findEntityAndCheckPermissions(userAbility, constants.ACTIONS.update, constants.FILE_MODEL_UID, id);
|
|
17
|
+
const updated = await uploadService.updateFileInfo(id, fileInfo, {
|
|
18
|
+
user
|
|
19
|
+
});
|
|
20
|
+
return pm.sanitizeOutput(updated, {
|
|
21
|
+
action: constants.ACTIONS.read
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
ctx.body = results;
|
|
25
|
+
},
|
|
11
26
|
async updateFileInfo (ctx) {
|
|
12
27
|
const { state: { userAbility, user }, query: { id }, request: { body } } = ctx;
|
|
13
28
|
if (typeof id !== 'string') {
|
|
@@ -57,13 +72,53 @@ var adminUpload = {
|
|
|
57
72
|
if (!pm.isAllowed) {
|
|
58
73
|
return ctx.forbidden();
|
|
59
74
|
}
|
|
60
|
-
const data = await upload.validateUploadBody(body);
|
|
75
|
+
const data = await upload.validateUploadBody(body, Array.isArray(files));
|
|
76
|
+
const filesArray = Array.isArray(files) ? files : [
|
|
77
|
+
files
|
|
78
|
+
];
|
|
79
|
+
// Upload files first to get thumbnails
|
|
61
80
|
const uploadedFiles = await uploadService.upload({
|
|
62
81
|
data,
|
|
63
|
-
files
|
|
82
|
+
files: filesArray
|
|
64
83
|
}, {
|
|
65
84
|
user
|
|
66
85
|
});
|
|
86
|
+
if (uploadedFiles.some((file)=>file.mime?.startsWith('image/'))) {
|
|
87
|
+
strapi.telemetry.send('didUploadImage');
|
|
88
|
+
}
|
|
89
|
+
const aiMetadataService = index.getService('aiMetadata');
|
|
90
|
+
// AFTER upload - use thumbnail versions for AI processing
|
|
91
|
+
if (await aiMetadataService.isEnabled()) {
|
|
92
|
+
try {
|
|
93
|
+
// Use thumbnail URLs instead of original files
|
|
94
|
+
const thumbnailFiles = uploadedFiles.map((file)=>({
|
|
95
|
+
filepath: file.formats?.thumbnail?.url || file.url,
|
|
96
|
+
mimetype: file.mime,
|
|
97
|
+
originalFilename: file.name,
|
|
98
|
+
size: file.formats?.thumbnail?.size || file.size,
|
|
99
|
+
provider: file.provider
|
|
100
|
+
}));
|
|
101
|
+
const metadataResults = await aiMetadataService.processFiles(thumbnailFiles);
|
|
102
|
+
// Update the uploaded files with AI metadata
|
|
103
|
+
await Promise.all(uploadedFiles.map(async (uploadedFile, index)=>{
|
|
104
|
+
const aiMetadata = metadataResults[index];
|
|
105
|
+
if (aiMetadata) {
|
|
106
|
+
await uploadService.updateFileInfo(uploadedFile.id, {
|
|
107
|
+
alternativeText: aiMetadata.altText,
|
|
108
|
+
caption: aiMetadata.caption
|
|
109
|
+
}, {
|
|
110
|
+
user
|
|
111
|
+
});
|
|
112
|
+
uploadedFiles[index].alternativeText = aiMetadata.altText;
|
|
113
|
+
uploadedFiles[index].caption = aiMetadata.caption;
|
|
114
|
+
}
|
|
115
|
+
}));
|
|
116
|
+
} catch (error) {
|
|
117
|
+
strapi.log.warn('AI metadata generation failed, proceeding without AI enhancements', {
|
|
118
|
+
error: error instanceof Error ? error.message : String(error)
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
67
122
|
// Sign file urls for private providers
|
|
68
123
|
const signedFiles = await utils.async.map(uploadedFiles, index.getService('file').signFileUrls);
|
|
69
124
|
ctx.body = await pm.sanitizeOutput(signedFiles, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-upload.js","sources":["../../../server/src/controllers/admin-upload.ts"],"sourcesContent":["import _ from 'lodash';\nimport { errors, async } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport { validateUploadBody } from './validation/admin/upload';\nimport { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions';\nimport { FileInfo } from '../types';\n\nexport default {\n async updateFileInfo(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const data = await validateUploadBody(body);\n\n const file = await uploadService.updateFileInfo(id, data.fileInfo as any, { user });\n\n ctx.body = await pm.sanitizeOutput(file, { action: ACTIONS.read });\n },\n\n async replaceFile(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body, files: { files } = {} },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n if (Array.isArray(files)) {\n throw new errors.ApplicationError('Cannot replace a file with multiple ones');\n }\n\n const data = (await validateUploadBody(body)) as { fileInfo: FileInfo };\n const replacedFile = await uploadService.replace(id, { data, file: files }, { user });\n\n // Sign file urls for private providers\n const signedFile = await getService('file').signFileUrls(replacedFile);\n\n ctx.body = await pm.sanitizeOutput(signedFile, { action: ACTIONS.read });\n },\n\n async uploadFiles(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body, files: { files } = {} },\n } = ctx;\n\n const uploadService = getService('upload');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const data = await validateUploadBody(body);\n const uploadedFiles = await uploadService.upload({ data, files }, { user });\n\n // Sign file urls for private providers\n const signedFiles = await async.map(uploadedFiles, getService('file').signFileUrls);\n\n ctx.body = await pm.sanitizeOutput(signedFiles, { action: ACTIONS.read });\n ctx.status = 201;\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new errors.ApplicationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n};\n"],"names":["updateFileInfo","ctx","state","userAbility","user","query","id","request","body","errors","ValidationError","uploadService","getService","pm","findEntityAndCheckPermissions","ACTIONS","update","FILE_MODEL_UID","data","validateUploadBody","file","fileInfo","sanitizeOutput","action","read","replaceFile","files","Array","isArray","ApplicationError","replacedFile","replace","signedFile","signFileUrls","uploadFiles","strapi","service","createPermissionsManager","ability","create","model","isAllowed","forbidden","uploadedFiles","upload","signedFiles","async","map","status","_","isEmpty","size"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"admin-upload.js","sources":["../../../server/src/controllers/admin-upload.ts"],"sourcesContent":["import _ from 'lodash';\nimport { errors, async } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport { validateBulkUpdateBody, validateUploadBody } from './validation/admin/upload';\nimport { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions';\nimport { FileInfo } from '../types';\n\nexport default {\n async bulkUpdateFileInfo(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body },\n } = ctx;\n\n const { updates } = await validateBulkUpdateBody(body);\n const uploadService = getService('upload');\n\n const results = await async.map(\n updates,\n async ({ id, fileInfo }: { id: number; fileInfo: FileInfo }) => {\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const updated = await uploadService.updateFileInfo(id, fileInfo as any, { user });\n return pm.sanitizeOutput(updated, { action: ACTIONS.read });\n }\n );\n\n ctx.body = results;\n },\n\n async updateFileInfo(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const data = await validateUploadBody(body);\n\n const file = await uploadService.updateFileInfo(id, data.fileInfo as any, { user });\n\n ctx.body = await pm.sanitizeOutput(file, { action: ACTIONS.read });\n },\n\n async replaceFile(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body, files: { files } = {} },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n if (Array.isArray(files)) {\n throw new errors.ApplicationError('Cannot replace a file with multiple ones');\n }\n\n const data = (await validateUploadBody(body)) as { fileInfo: FileInfo };\n const replacedFile = await uploadService.replace(id, { data, file: files }, { user });\n\n // Sign file urls for private providers\n const signedFile = await getService('file').signFileUrls(replacedFile);\n\n ctx.body = await pm.sanitizeOutput(signedFile, { action: ACTIONS.read });\n },\n\n async uploadFiles(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body, files: { files } = {} },\n } = ctx;\n\n const uploadService = getService('upload');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const data = await validateUploadBody(body, Array.isArray(files));\n const filesArray = Array.isArray(files) ? files : [files];\n\n // Upload files first to get thumbnails\n const uploadedFiles = await uploadService.upload({ data, files: filesArray }, { user });\n if (uploadedFiles.some((file) => file.mime?.startsWith('image/'))) {\n strapi.telemetry.send('didUploadImage');\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // AFTER upload - use thumbnail versions for AI processing\n if (await aiMetadataService.isEnabled()) {\n try {\n // Use thumbnail URLs instead of original files\n const thumbnailFiles = uploadedFiles.map(\n (file) =>\n ({\n filepath: file.formats?.thumbnail?.url || file.url, // Use thumbnail if available\n mimetype: file.mime,\n originalFilename: file.name,\n size: file.formats?.thumbnail?.size || file.size,\n provider: file.provider,\n }) as unknown as any\n );\n\n const metadataResults = await aiMetadataService.processFiles(thumbnailFiles);\n\n // Update the uploaded files with AI metadata\n await Promise.all(\n uploadedFiles.map(async (uploadedFile, index) => {\n const aiMetadata = metadataResults[index];\n if (aiMetadata) {\n await uploadService.updateFileInfo(\n uploadedFile.id,\n {\n alternativeText: aiMetadata.altText,\n caption: aiMetadata.caption,\n },\n { user }\n );\n\n uploadedFiles[index].alternativeText = aiMetadata.altText;\n uploadedFiles[index].caption = aiMetadata.caption;\n }\n })\n );\n } catch (error) {\n strapi.log.warn('AI metadata generation failed, proceeding without AI enhancements', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Sign file urls for private providers\n const signedFiles = await async.map(uploadedFiles, getService('file').signFileUrls);\n\n ctx.body = await pm.sanitizeOutput(signedFiles, { action: ACTIONS.read });\n ctx.status = 201;\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new errors.ApplicationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n};\n"],"names":["bulkUpdateFileInfo","ctx","state","userAbility","user","request","body","updates","validateBulkUpdateBody","uploadService","getService","results","async","map","id","fileInfo","pm","findEntityAndCheckPermissions","ACTIONS","update","FILE_MODEL_UID","updated","updateFileInfo","sanitizeOutput","action","read","query","errors","ValidationError","data","validateUploadBody","file","replaceFile","files","Array","isArray","ApplicationError","replacedFile","replace","signedFile","signFileUrls","uploadFiles","strapi","service","createPermissionsManager","ability","create","model","isAllowed","forbidden","filesArray","uploadedFiles","upload","some","mime","startsWith","telemetry","send","aiMetadataService","isEnabled","thumbnailFiles","filepath","formats","thumbnail","url","mimetype","originalFilename","name","size","provider","metadataResults","processFiles","Promise","all","uploadedFile","index","aiMetadata","alternativeText","altText","caption","error","log","warn","Error","message","String","signedFiles","status","_","isEmpty"],"mappings":"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"}
|