@strapi/upload 5.15.0 → 5.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/components/AssetDialog/AssetDialog.js +3 -1
- package/dist/admin/components/AssetDialog/AssetDialog.js.map +1 -1
- package/dist/admin/components/AssetDialog/AssetDialog.mjs +3 -1
- package/dist/admin/components/AssetDialog/AssetDialog.mjs.map +1 -1
- package/dist/admin/package.json.js +7 -7
- package/dist/admin/package.json.mjs +7 -7
- package/dist/server/services/image-manipulation.js +11 -1
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs +12 -2
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/services/upload.js +2 -10
- package/dist/server/services/upload.js.map +1 -1
- package/dist/server/services/upload.mjs +3 -11
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/src/index.d.ts +1 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/services/image-manipulation.d.ts +1 -0
- package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +1 -0
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/upload.d.ts.map +1 -1
- package/package.json +7 -7
|
@@ -87,6 +87,7 @@ const AssetContent = ({ allowedTypes = [], folderId = null, onClose, onAddAsset,
|
|
|
87
87
|
};
|
|
88
88
|
const isLoading = isLoadingPermissions || isLoadingAssets || isLoadingFolders;
|
|
89
89
|
const hasError = errorAssets || errorFolders;
|
|
90
|
+
const [activeTab, setActiveTab] = React__namespace.useState(selectedAssets.length > 0 ? 'selected' : 'browse');
|
|
90
91
|
if (isLoading) {
|
|
91
92
|
return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
92
93
|
children: [
|
|
@@ -193,7 +194,8 @@ const AssetContent = ({ allowedTypes = [], folderId = null, onClose, onAddAsset,
|
|
|
193
194
|
}),
|
|
194
195
|
/*#__PURE__*/ jsxRuntime.jsxs(TabsRoot, {
|
|
195
196
|
variant: "simple",
|
|
196
|
-
|
|
197
|
+
value: activeTab,
|
|
198
|
+
onValueChange: setActiveTab,
|
|
197
199
|
children: [
|
|
198
200
|
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
199
201
|
paddingLeft: 8,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetDialog.js","sources":["../../../../admin/src/components/AssetDialog/AssetDialog.tsx"],"sourcesContent":["// TODO: find a better naming convention for the file that was an index file before\nimport * as React from 'react';\n\nimport { Page } from '@strapi/admin/strapi-admin';\nimport { Badge, Button, Divider, Flex, Loader, Modal, Tabs } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useAssets } from '../../hooks/useAssets';\nimport { useFolders } from '../../hooks/useFolders';\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { useModalQueryParams } from '../../hooks/useModalQueryParams';\nimport { useSelectionState } from '../../hooks/useSelectionState';\nimport {\n containsAssetFilter,\n getTrad,\n getAllowedFiles,\n moveElement,\n AllowedFiles,\n} from '../../utils';\nimport { EditAssetContent, Asset as EditAsset } from '../EditAssetDialog/EditAssetContent';\nimport { EditFolderContent } from '../EditFolderDialog/EditFolderDialog';\n\nimport {\n BrowseStep,\n FolderWithType,\n FileWithType,\n Filter as BrowseFilter,\n} from './BrowseStep/BrowseStep';\nimport { DialogFooter } from './DialogFooter';\nimport { SelectedStep } from './SelectedStep/SelectedStep';\n\nimport type { File as Asset, FilterCondition, Query } from '../../../../shared/contracts/files';\nimport type { Folder, FolderDefinition } from '../../../../shared/contracts/folders';\nimport type { AllowedTypes } from '../AssetCard/AssetCard';\n\nconst LoadingBody = styled(Flex)`\n /* 80px are coming from the Tabs component that is not included in the ModalBody */\n min-height: ${() => `calc(60vh + 8rem)`};\n`;\n\nexport interface FileRow extends Asset {\n folderURL?: string;\n isSelectable?: boolean;\n type?: string;\n}\n\nexport interface FolderRow extends Folder {\n folderURL?: string;\n isSelectable?: boolean;\n type?: string;\n}\n\ninterface AssetContentProps {\n allowedTypes?: AllowedTypes[];\n folderId?: number | null;\n onClose: () => void;\n onAddAsset: (arg?: { folderId: number | { id: number } | null | undefined }) => void;\n onAddFolder: ({ folderId }: { folderId: number | { id: number } | null | undefined }) => void;\n onChangeFolder: (folderId: number | null) => void;\n onValidate: (selectedAssets: Asset[]) => void;\n multiple?: boolean;\n trackedLocation?: string;\n initiallySelectedAssets?: Asset[];\n}\n\nexport const AssetContent = ({\n allowedTypes = [],\n folderId = null,\n onClose,\n onAddAsset,\n onAddFolder,\n onChangeFolder,\n onValidate,\n multiple = false,\n initiallySelectedAssets = [],\n trackedLocation,\n}: AssetContentProps) => {\n const [assetToEdit, setAssetToEdit] = React.useState<FileWithType | undefined>(undefined);\n const [folderToEdit, setFolderToEdit] = React.useState<FolderRow | undefined>(undefined);\n const { formatMessage } = useIntl();\n const {\n canRead,\n canCreate,\n isLoading: isLoadingPermissions,\n canUpdate,\n canCopyLink,\n canDownload,\n } = useMediaLibraryPermissions();\n\n const [\n { queryObject },\n {\n onChangeFilters,\n onChangePage,\n onChangePageSize,\n onChangeSort,\n onChangeSearch,\n onChangeFolder: onChangeFolderParam,\n },\n ] = useModalQueryParams({ folder: folderId });\n\n const {\n data: { pagination, results: assets } = {},\n isLoading: isLoadingAssets,\n error: errorAssets,\n } = useAssets({ skipWhen: !canRead, query: queryObject });\n\n const {\n data: folders,\n isLoading: isLoadingFolders,\n error: errorFolders,\n } = useFolders({\n enabled: canRead && !containsAssetFilter(queryObject!) && pagination?.page === 1,\n query: queryObject,\n });\n\n const [\n selectedAssets,\n { selectOne, selectOnly, setSelections, selectMultiple, deselectMultiple },\n ] = useSelectionState(['id'], initiallySelectedAssets);\n\n const handleSelectAllAssets = () => {\n const allowedAssets = getAllowedFiles(allowedTypes, assets as AllowedFiles[]);\n\n if (!multiple) {\n return undefined;\n }\n\n // selected files in current folder\n const alreadySelected = allowedAssets.filter(\n (asset) => selectedAssets.findIndex((selectedAsset) => selectedAsset.id === asset.id) !== -1\n );\n\n if (alreadySelected.length > 0) {\n deselectMultiple(alreadySelected);\n } else {\n selectMultiple(allowedAssets);\n }\n };\n\n const handleSelectAsset = (asset: Asset | FileRow | FolderRow) => {\n return multiple ? selectOne(asset as Asset) : selectOnly(asset as Asset);\n };\n\n const isLoading = isLoadingPermissions || isLoadingAssets || isLoadingFolders;\n const hasError = errorAssets || errorFolders;\n\n if (isLoading) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <LoadingBody justifyContent=\"center\" paddingTop={4} paddingBottom={4}>\n <Loader>\n {formatMessage({\n id: getTrad('content.isLoading'),\n defaultMessage: 'Content is loading.',\n })}\n </Loader>\n </LoadingBody>\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (hasError) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <Page.Error />\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (!canRead) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <Page.NoPermissions />\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (assetToEdit) {\n return (\n <EditAssetContent\n onClose={() => setAssetToEdit(undefined)}\n asset={assetToEdit as EditAsset}\n canUpdate={canUpdate}\n canCopyLink={canCopyLink}\n canDownload={canDownload}\n trackedLocation={trackedLocation}\n />\n );\n }\n\n if (folderToEdit) {\n return (\n <EditFolderContent\n folder={folderToEdit as FolderDefinition}\n onClose={() => setFolderToEdit(undefined)}\n location=\"content-manager\"\n parentFolderId={queryObject?.folder as string | number | null | undefined}\n />\n );\n }\n\n const handleMoveItem = (hoverIndex: number, destIndex: number) => {\n const offset = destIndex - hoverIndex;\n const orderedAssetsClone = selectedAssets.slice();\n const nextAssets = moveElement<Asset>(orderedAssetsClone, hoverIndex, offset);\n setSelections(nextAssets);\n };\n\n const handleFolderChange = (folderId: number, folderPath?: string) => {\n onChangeFolder(folderId);\n if (onChangeFolderParam) {\n onChangeFolderParam(folderId, folderPath);\n }\n };\n\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n\n <TabsRoot variant=\"simple\" defaultValue={selectedAssets.length > 0 ? 'selected' : 'browse'}>\n <Flex paddingLeft={8} paddingRight={8} paddingTop={6} justifyContent=\"space-between\">\n <Tabs.List>\n <Tabs.Trigger value=\"browse\">\n {formatMessage({\n id: getTrad('modal.nav.browse'),\n defaultMessage: 'Browse',\n })}\n </Tabs.Trigger>\n <Tabs.Trigger value=\"selected\">\n {formatMessage({\n id: getTrad('modal.header.select-files'),\n defaultMessage: 'Selected files',\n })}\n <Badge marginLeft={2}>{selectedAssets.length}</Badge>\n </Tabs.Trigger>\n </Tabs.List>\n <Flex gap={2}>\n <Button\n variant=\"secondary\"\n onClick={() => onAddFolder({ folderId: queryObject?.folder })}\n >\n {formatMessage({\n id: getTrad('modal.upload-list.sub-header.add-folder'),\n defaultMessage: 'Add folder',\n })}\n </Button>\n <Button onClick={() => onAddAsset({ folderId: queryObject?.folder })}>\n {formatMessage({\n id: getTrad('modal.upload-list.sub-header.button'),\n defaultMessage: 'Add more assets',\n })}\n </Button>\n </Flex>\n </Flex>\n <Divider />\n <Modal.Body>\n <Tabs.Content value=\"browse\">\n <BrowseStep\n allowedTypes={allowedTypes}\n assets={assets!}\n canCreate={canCreate}\n canRead={canRead}\n folders={folders as FolderWithType[]}\n onSelectAsset={handleSelectAsset}\n selectedAssets={selectedAssets}\n multiple={multiple}\n onSelectAllAsset={handleSelectAllAssets}\n onEditAsset={setAssetToEdit}\n onEditFolder={setFolderToEdit}\n pagination={pagination!}\n queryObject={queryObject!}\n onAddAsset={onAddAsset}\n onChangeFilters={(filters: FilterCondition<string>[] | BrowseFilter[]) =>\n onChangeFilters!(filters as FilterCondition<string>[])\n }\n onChangeFolder={handleFolderChange}\n onChangePage={onChangePage!}\n onChangePageSize={onChangePageSize!}\n onChangeSort={(sort: string | undefined) => onChangeSort!(sort as Query['sort'])}\n onChangeSearch={onChangeSearch!}\n />\n </Tabs.Content>\n <Tabs.Content value=\"selected\">\n <SelectedStep\n selectedAssets={selectedAssets}\n onSelectAsset={handleSelectAsset}\n onReorderAsset={handleMoveItem}\n />\n </Tabs.Content>\n </Modal.Body>\n </TabsRoot>\n <DialogFooter onClose={onClose} onValidate={() => onValidate(selectedAssets)} />\n </>\n );\n};\n\ninterface AssetDialogProps extends AssetContentProps {\n open?: boolean;\n}\n\nexport const AssetDialog = ({ open = false, onClose, ...restProps }: AssetDialogProps) => {\n return (\n <Modal.Root open={open} onOpenChange={onClose}>\n <Modal.Content>\n <AssetContent onClose={onClose} {...restProps} />\n </Modal.Content>\n </Modal.Root>\n );\n};\n\nconst TabsRoot = styled(Tabs.Root)`\n display: flex;\n flex-direction: column;\n overflow: hidden;\n`;\n"],"names":["LoadingBody","styled","Flex","AssetContent","allowedTypes","folderId","onClose","onAddAsset","onAddFolder","onChangeFolder","onValidate","multiple","initiallySelectedAssets","trackedLocation","assetToEdit","setAssetToEdit","React","useState","undefined","folderToEdit","setFolderToEdit","formatMessage","useIntl","canRead","canCreate","isLoading","isLoadingPermissions","canUpdate","canCopyLink","canDownload","useMediaLibraryPermissions","queryObject","onChangeFilters","onChangePage","onChangePageSize","onChangeSort","onChangeSearch","onChangeFolderParam","useModalQueryParams","folder","data","pagination","results","assets","isLoadingAssets","error","errorAssets","useAssets","skipWhen","query","folders","isLoadingFolders","errorFolders","useFolders","enabled","containsAssetFilter","page","selectedAssets","selectOne","selectOnly","setSelections","selectMultiple","deselectMultiple","useSelectionState","handleSelectAllAssets","allowedAssets","getAllowedFiles","alreadySelected","filter","asset","findIndex","selectedAsset","id","length","handleSelectAsset","hasError","_jsxs","_Fragment","_jsx","Modal","Header","Title","getTrad","defaultMessage","justifyContent","paddingTop","paddingBottom","Loader","DialogFooter","Page","Error","NoPermissions","EditAssetContent","EditFolderContent","location","parentFolderId","handleMoveItem","hoverIndex","destIndex","offset","orderedAssetsClone","slice","nextAssets","moveElement","handleFolderChange","folderPath","TabsRoot","variant","defaultValue","paddingLeft","paddingRight","Tabs","List","Trigger","value","Badge","marginLeft","gap","Button","onClick","Divider","Body","Content","BrowseStep","onSelectAsset","onSelectAllAsset","onEditAsset","onEditFolder","filters","sort","SelectedStep","onReorderAsset","AssetDialog","open","restProps","Root","onOpenChange"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AssetDialog.js","sources":["../../../../admin/src/components/AssetDialog/AssetDialog.tsx"],"sourcesContent":["// TODO: find a better naming convention for the file that was an index file before\nimport * as React from 'react';\n\nimport { Page } from '@strapi/admin/strapi-admin';\nimport { Badge, Button, Divider, Flex, Loader, Modal, Tabs } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useAssets } from '../../hooks/useAssets';\nimport { useFolders } from '../../hooks/useFolders';\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { useModalQueryParams } from '../../hooks/useModalQueryParams';\nimport { useSelectionState } from '../../hooks/useSelectionState';\nimport {\n containsAssetFilter,\n getTrad,\n getAllowedFiles,\n moveElement,\n AllowedFiles,\n} from '../../utils';\nimport { EditAssetContent, Asset as EditAsset } from '../EditAssetDialog/EditAssetContent';\nimport { EditFolderContent } from '../EditFolderDialog/EditFolderDialog';\n\nimport {\n BrowseStep,\n FolderWithType,\n FileWithType,\n Filter as BrowseFilter,\n} from './BrowseStep/BrowseStep';\nimport { DialogFooter } from './DialogFooter';\nimport { SelectedStep } from './SelectedStep/SelectedStep';\n\nimport type { File as Asset, FilterCondition, Query } from '../../../../shared/contracts/files';\nimport type { Folder, FolderDefinition } from '../../../../shared/contracts/folders';\nimport type { AllowedTypes } from '../AssetCard/AssetCard';\n\nconst LoadingBody = styled(Flex)`\n /* 80px are coming from the Tabs component that is not included in the ModalBody */\n min-height: ${() => `calc(60vh + 8rem)`};\n`;\n\nexport interface FileRow extends Asset {\n folderURL?: string;\n isSelectable?: boolean;\n type?: string;\n}\n\nexport interface FolderRow extends Folder {\n folderURL?: string;\n isSelectable?: boolean;\n type?: string;\n}\n\ninterface AssetContentProps {\n allowedTypes?: AllowedTypes[];\n folderId?: number | null;\n onClose: () => void;\n onAddAsset: (arg?: { folderId: number | { id: number } | null | undefined }) => void;\n onAddFolder: ({ folderId }: { folderId: number | { id: number } | null | undefined }) => void;\n onChangeFolder: (folderId: number | null) => void;\n onValidate: (selectedAssets: Asset[]) => void;\n multiple?: boolean;\n trackedLocation?: string;\n initiallySelectedAssets?: Asset[];\n}\n\nexport const AssetContent = ({\n allowedTypes = [],\n folderId = null,\n onClose,\n onAddAsset,\n onAddFolder,\n onChangeFolder,\n onValidate,\n multiple = false,\n initiallySelectedAssets = [],\n trackedLocation,\n}: AssetContentProps) => {\n const [assetToEdit, setAssetToEdit] = React.useState<FileWithType | undefined>(undefined);\n const [folderToEdit, setFolderToEdit] = React.useState<FolderRow | undefined>(undefined);\n const { formatMessage } = useIntl();\n const {\n canRead,\n canCreate,\n isLoading: isLoadingPermissions,\n canUpdate,\n canCopyLink,\n canDownload,\n } = useMediaLibraryPermissions();\n\n const [\n { queryObject },\n {\n onChangeFilters,\n onChangePage,\n onChangePageSize,\n onChangeSort,\n onChangeSearch,\n onChangeFolder: onChangeFolderParam,\n },\n ] = useModalQueryParams({ folder: folderId });\n\n const {\n data: { pagination, results: assets } = {},\n isLoading: isLoadingAssets,\n error: errorAssets,\n } = useAssets({ skipWhen: !canRead, query: queryObject });\n\n const {\n data: folders,\n isLoading: isLoadingFolders,\n error: errorFolders,\n } = useFolders({\n enabled: canRead && !containsAssetFilter(queryObject!) && pagination?.page === 1,\n query: queryObject,\n });\n\n const [\n selectedAssets,\n { selectOne, selectOnly, setSelections, selectMultiple, deselectMultiple },\n ] = useSelectionState(['id'], initiallySelectedAssets);\n\n const handleSelectAllAssets = () => {\n const allowedAssets = getAllowedFiles(allowedTypes, assets as AllowedFiles[]);\n\n if (!multiple) {\n return undefined;\n }\n\n // selected files in current folder\n const alreadySelected = allowedAssets.filter(\n (asset) => selectedAssets.findIndex((selectedAsset) => selectedAsset.id === asset.id) !== -1\n );\n\n if (alreadySelected.length > 0) {\n deselectMultiple(alreadySelected);\n } else {\n selectMultiple(allowedAssets);\n }\n };\n\n const handleSelectAsset = (asset: Asset | FileRow | FolderRow) => {\n return multiple ? selectOne(asset as Asset) : selectOnly(asset as Asset);\n };\n\n const isLoading = isLoadingPermissions || isLoadingAssets || isLoadingFolders;\n const hasError = errorAssets || errorFolders;\n\n const [activeTab, setActiveTab] = React.useState(\n selectedAssets.length > 0 ? 'selected' : 'browse'\n );\n\n if (isLoading) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <LoadingBody justifyContent=\"center\" paddingTop={4} paddingBottom={4}>\n <Loader>\n {formatMessage({\n id: getTrad('content.isLoading'),\n defaultMessage: 'Content is loading.',\n })}\n </Loader>\n </LoadingBody>\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (hasError) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <Page.Error />\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (!canRead) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <Page.NoPermissions />\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (assetToEdit) {\n return (\n <EditAssetContent\n onClose={() => setAssetToEdit(undefined)}\n asset={assetToEdit as EditAsset}\n canUpdate={canUpdate}\n canCopyLink={canCopyLink}\n canDownload={canDownload}\n trackedLocation={trackedLocation}\n />\n );\n }\n\n if (folderToEdit) {\n return (\n <EditFolderContent\n folder={folderToEdit as FolderDefinition}\n onClose={() => setFolderToEdit(undefined)}\n location=\"content-manager\"\n parentFolderId={queryObject?.folder as string | number | null | undefined}\n />\n );\n }\n\n const handleMoveItem = (hoverIndex: number, destIndex: number) => {\n const offset = destIndex - hoverIndex;\n const orderedAssetsClone = selectedAssets.slice();\n const nextAssets = moveElement<Asset>(orderedAssetsClone, hoverIndex, offset);\n setSelections(nextAssets);\n };\n\n const handleFolderChange = (folderId: number, folderPath?: string) => {\n onChangeFolder(folderId);\n if (onChangeFolderParam) {\n onChangeFolderParam(folderId, folderPath);\n }\n };\n\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n\n <TabsRoot variant=\"simple\" value={activeTab} onValueChange={setActiveTab}>\n <Flex paddingLeft={8} paddingRight={8} paddingTop={6} justifyContent=\"space-between\">\n <Tabs.List>\n <Tabs.Trigger value=\"browse\">\n {formatMessage({\n id: getTrad('modal.nav.browse'),\n defaultMessage: 'Browse',\n })}\n </Tabs.Trigger>\n <Tabs.Trigger value=\"selected\">\n {formatMessage({\n id: getTrad('modal.header.select-files'),\n defaultMessage: 'Selected files',\n })}\n <Badge marginLeft={2}>{selectedAssets.length}</Badge>\n </Tabs.Trigger>\n </Tabs.List>\n <Flex gap={2}>\n <Button\n variant=\"secondary\"\n onClick={() => onAddFolder({ folderId: queryObject?.folder })}\n >\n {formatMessage({\n id: getTrad('modal.upload-list.sub-header.add-folder'),\n defaultMessage: 'Add folder',\n })}\n </Button>\n <Button onClick={() => onAddAsset({ folderId: queryObject?.folder })}>\n {formatMessage({\n id: getTrad('modal.upload-list.sub-header.button'),\n defaultMessage: 'Add more assets',\n })}\n </Button>\n </Flex>\n </Flex>\n <Divider />\n <Modal.Body>\n <Tabs.Content value=\"browse\">\n <BrowseStep\n allowedTypes={allowedTypes}\n assets={assets!}\n canCreate={canCreate}\n canRead={canRead}\n folders={folders as FolderWithType[]}\n onSelectAsset={handleSelectAsset}\n selectedAssets={selectedAssets}\n multiple={multiple}\n onSelectAllAsset={handleSelectAllAssets}\n onEditAsset={setAssetToEdit}\n onEditFolder={setFolderToEdit}\n pagination={pagination!}\n queryObject={queryObject!}\n onAddAsset={onAddAsset}\n onChangeFilters={(filters: FilterCondition<string>[] | BrowseFilter[]) =>\n onChangeFilters!(filters as FilterCondition<string>[])\n }\n onChangeFolder={handleFolderChange}\n onChangePage={onChangePage!}\n onChangePageSize={onChangePageSize!}\n onChangeSort={(sort: string | undefined) => onChangeSort!(sort as Query['sort'])}\n onChangeSearch={onChangeSearch!}\n />\n </Tabs.Content>\n <Tabs.Content value=\"selected\">\n <SelectedStep\n selectedAssets={selectedAssets}\n onSelectAsset={handleSelectAsset}\n onReorderAsset={handleMoveItem}\n />\n </Tabs.Content>\n </Modal.Body>\n </TabsRoot>\n <DialogFooter onClose={onClose} onValidate={() => onValidate(selectedAssets)} />\n </>\n );\n};\n\ninterface AssetDialogProps extends AssetContentProps {\n open?: boolean;\n}\n\nexport const AssetDialog = ({ open = false, onClose, ...restProps }: AssetDialogProps) => {\n return (\n <Modal.Root open={open} onOpenChange={onClose}>\n <Modal.Content>\n <AssetContent onClose={onClose} {...restProps} />\n </Modal.Content>\n </Modal.Root>\n );\n};\n\nconst TabsRoot = styled(Tabs.Root)`\n display: flex;\n flex-direction: column;\n overflow: hidden;\n`;\n"],"names":["LoadingBody","styled","Flex","AssetContent","allowedTypes","folderId","onClose","onAddAsset","onAddFolder","onChangeFolder","onValidate","multiple","initiallySelectedAssets","trackedLocation","assetToEdit","setAssetToEdit","React","useState","undefined","folderToEdit","setFolderToEdit","formatMessage","useIntl","canRead","canCreate","isLoading","isLoadingPermissions","canUpdate","canCopyLink","canDownload","useMediaLibraryPermissions","queryObject","onChangeFilters","onChangePage","onChangePageSize","onChangeSort","onChangeSearch","onChangeFolderParam","useModalQueryParams","folder","data","pagination","results","assets","isLoadingAssets","error","errorAssets","useAssets","skipWhen","query","folders","isLoadingFolders","errorFolders","useFolders","enabled","containsAssetFilter","page","selectedAssets","selectOne","selectOnly","setSelections","selectMultiple","deselectMultiple","useSelectionState","handleSelectAllAssets","allowedAssets","getAllowedFiles","alreadySelected","filter","asset","findIndex","selectedAsset","id","length","handleSelectAsset","hasError","activeTab","setActiveTab","_jsxs","_Fragment","_jsx","Modal","Header","Title","getTrad","defaultMessage","justifyContent","paddingTop","paddingBottom","Loader","DialogFooter","Page","Error","NoPermissions","EditAssetContent","EditFolderContent","location","parentFolderId","handleMoveItem","hoverIndex","destIndex","offset","orderedAssetsClone","slice","nextAssets","moveElement","handleFolderChange","folderPath","TabsRoot","variant","value","onValueChange","paddingLeft","paddingRight","Tabs","List","Trigger","Badge","marginLeft","gap","Button","onClick","Divider","Body","Content","BrowseStep","onSelectAsset","onSelectAllAsset","onEditAsset","onEditFolder","filters","sort","SelectedStep","onReorderAsset","AssetDialog","open","restProps","Root","onOpenChange"],"mappings":"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"}
|
|
@@ -66,6 +66,7 @@ const AssetContent = ({ allowedTypes = [], folderId = null, onClose, onAddAsset,
|
|
|
66
66
|
};
|
|
67
67
|
const isLoading = isLoadingPermissions || isLoadingAssets || isLoadingFolders;
|
|
68
68
|
const hasError = errorAssets || errorFolders;
|
|
69
|
+
const [activeTab, setActiveTab] = React.useState(selectedAssets.length > 0 ? 'selected' : 'browse');
|
|
69
70
|
if (isLoading) {
|
|
70
71
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
71
72
|
children: [
|
|
@@ -172,7 +173,8 @@ const AssetContent = ({ allowedTypes = [], folderId = null, onClose, onAddAsset,
|
|
|
172
173
|
}),
|
|
173
174
|
/*#__PURE__*/ jsxs(TabsRoot, {
|
|
174
175
|
variant: "simple",
|
|
175
|
-
|
|
176
|
+
value: activeTab,
|
|
177
|
+
onValueChange: setActiveTab,
|
|
176
178
|
children: [
|
|
177
179
|
/*#__PURE__*/ jsxs(Flex, {
|
|
178
180
|
paddingLeft: 8,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetDialog.mjs","sources":["../../../../admin/src/components/AssetDialog/AssetDialog.tsx"],"sourcesContent":["// TODO: find a better naming convention for the file that was an index file before\nimport * as React from 'react';\n\nimport { Page } from '@strapi/admin/strapi-admin';\nimport { Badge, Button, Divider, Flex, Loader, Modal, Tabs } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useAssets } from '../../hooks/useAssets';\nimport { useFolders } from '../../hooks/useFolders';\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { useModalQueryParams } from '../../hooks/useModalQueryParams';\nimport { useSelectionState } from '../../hooks/useSelectionState';\nimport {\n containsAssetFilter,\n getTrad,\n getAllowedFiles,\n moveElement,\n AllowedFiles,\n} from '../../utils';\nimport { EditAssetContent, Asset as EditAsset } from '../EditAssetDialog/EditAssetContent';\nimport { EditFolderContent } from '../EditFolderDialog/EditFolderDialog';\n\nimport {\n BrowseStep,\n FolderWithType,\n FileWithType,\n Filter as BrowseFilter,\n} from './BrowseStep/BrowseStep';\nimport { DialogFooter } from './DialogFooter';\nimport { SelectedStep } from './SelectedStep/SelectedStep';\n\nimport type { File as Asset, FilterCondition, Query } from '../../../../shared/contracts/files';\nimport type { Folder, FolderDefinition } from '../../../../shared/contracts/folders';\nimport type { AllowedTypes } from '../AssetCard/AssetCard';\n\nconst LoadingBody = styled(Flex)`\n /* 80px are coming from the Tabs component that is not included in the ModalBody */\n min-height: ${() => `calc(60vh + 8rem)`};\n`;\n\nexport interface FileRow extends Asset {\n folderURL?: string;\n isSelectable?: boolean;\n type?: string;\n}\n\nexport interface FolderRow extends Folder {\n folderURL?: string;\n isSelectable?: boolean;\n type?: string;\n}\n\ninterface AssetContentProps {\n allowedTypes?: AllowedTypes[];\n folderId?: number | null;\n onClose: () => void;\n onAddAsset: (arg?: { folderId: number | { id: number } | null | undefined }) => void;\n onAddFolder: ({ folderId }: { folderId: number | { id: number } | null | undefined }) => void;\n onChangeFolder: (folderId: number | null) => void;\n onValidate: (selectedAssets: Asset[]) => void;\n multiple?: boolean;\n trackedLocation?: string;\n initiallySelectedAssets?: Asset[];\n}\n\nexport const AssetContent = ({\n allowedTypes = [],\n folderId = null,\n onClose,\n onAddAsset,\n onAddFolder,\n onChangeFolder,\n onValidate,\n multiple = false,\n initiallySelectedAssets = [],\n trackedLocation,\n}: AssetContentProps) => {\n const [assetToEdit, setAssetToEdit] = React.useState<FileWithType | undefined>(undefined);\n const [folderToEdit, setFolderToEdit] = React.useState<FolderRow | undefined>(undefined);\n const { formatMessage } = useIntl();\n const {\n canRead,\n canCreate,\n isLoading: isLoadingPermissions,\n canUpdate,\n canCopyLink,\n canDownload,\n } = useMediaLibraryPermissions();\n\n const [\n { queryObject },\n {\n onChangeFilters,\n onChangePage,\n onChangePageSize,\n onChangeSort,\n onChangeSearch,\n onChangeFolder: onChangeFolderParam,\n },\n ] = useModalQueryParams({ folder: folderId });\n\n const {\n data: { pagination, results: assets } = {},\n isLoading: isLoadingAssets,\n error: errorAssets,\n } = useAssets({ skipWhen: !canRead, query: queryObject });\n\n const {\n data: folders,\n isLoading: isLoadingFolders,\n error: errorFolders,\n } = useFolders({\n enabled: canRead && !containsAssetFilter(queryObject!) && pagination?.page === 1,\n query: queryObject,\n });\n\n const [\n selectedAssets,\n { selectOne, selectOnly, setSelections, selectMultiple, deselectMultiple },\n ] = useSelectionState(['id'], initiallySelectedAssets);\n\n const handleSelectAllAssets = () => {\n const allowedAssets = getAllowedFiles(allowedTypes, assets as AllowedFiles[]);\n\n if (!multiple) {\n return undefined;\n }\n\n // selected files in current folder\n const alreadySelected = allowedAssets.filter(\n (asset) => selectedAssets.findIndex((selectedAsset) => selectedAsset.id === asset.id) !== -1\n );\n\n if (alreadySelected.length > 0) {\n deselectMultiple(alreadySelected);\n } else {\n selectMultiple(allowedAssets);\n }\n };\n\n const handleSelectAsset = (asset: Asset | FileRow | FolderRow) => {\n return multiple ? selectOne(asset as Asset) : selectOnly(asset as Asset);\n };\n\n const isLoading = isLoadingPermissions || isLoadingAssets || isLoadingFolders;\n const hasError = errorAssets || errorFolders;\n\n if (isLoading) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <LoadingBody justifyContent=\"center\" paddingTop={4} paddingBottom={4}>\n <Loader>\n {formatMessage({\n id: getTrad('content.isLoading'),\n defaultMessage: 'Content is loading.',\n })}\n </Loader>\n </LoadingBody>\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (hasError) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <Page.Error />\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (!canRead) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <Page.NoPermissions />\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (assetToEdit) {\n return (\n <EditAssetContent\n onClose={() => setAssetToEdit(undefined)}\n asset={assetToEdit as EditAsset}\n canUpdate={canUpdate}\n canCopyLink={canCopyLink}\n canDownload={canDownload}\n trackedLocation={trackedLocation}\n />\n );\n }\n\n if (folderToEdit) {\n return (\n <EditFolderContent\n folder={folderToEdit as FolderDefinition}\n onClose={() => setFolderToEdit(undefined)}\n location=\"content-manager\"\n parentFolderId={queryObject?.folder as string | number | null | undefined}\n />\n );\n }\n\n const handleMoveItem = (hoverIndex: number, destIndex: number) => {\n const offset = destIndex - hoverIndex;\n const orderedAssetsClone = selectedAssets.slice();\n const nextAssets = moveElement<Asset>(orderedAssetsClone, hoverIndex, offset);\n setSelections(nextAssets);\n };\n\n const handleFolderChange = (folderId: number, folderPath?: string) => {\n onChangeFolder(folderId);\n if (onChangeFolderParam) {\n onChangeFolderParam(folderId, folderPath);\n }\n };\n\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n\n <TabsRoot variant=\"simple\" defaultValue={selectedAssets.length > 0 ? 'selected' : 'browse'}>\n <Flex paddingLeft={8} paddingRight={8} paddingTop={6} justifyContent=\"space-between\">\n <Tabs.List>\n <Tabs.Trigger value=\"browse\">\n {formatMessage({\n id: getTrad('modal.nav.browse'),\n defaultMessage: 'Browse',\n })}\n </Tabs.Trigger>\n <Tabs.Trigger value=\"selected\">\n {formatMessage({\n id: getTrad('modal.header.select-files'),\n defaultMessage: 'Selected files',\n })}\n <Badge marginLeft={2}>{selectedAssets.length}</Badge>\n </Tabs.Trigger>\n </Tabs.List>\n <Flex gap={2}>\n <Button\n variant=\"secondary\"\n onClick={() => onAddFolder({ folderId: queryObject?.folder })}\n >\n {formatMessage({\n id: getTrad('modal.upload-list.sub-header.add-folder'),\n defaultMessage: 'Add folder',\n })}\n </Button>\n <Button onClick={() => onAddAsset({ folderId: queryObject?.folder })}>\n {formatMessage({\n id: getTrad('modal.upload-list.sub-header.button'),\n defaultMessage: 'Add more assets',\n })}\n </Button>\n </Flex>\n </Flex>\n <Divider />\n <Modal.Body>\n <Tabs.Content value=\"browse\">\n <BrowseStep\n allowedTypes={allowedTypes}\n assets={assets!}\n canCreate={canCreate}\n canRead={canRead}\n folders={folders as FolderWithType[]}\n onSelectAsset={handleSelectAsset}\n selectedAssets={selectedAssets}\n multiple={multiple}\n onSelectAllAsset={handleSelectAllAssets}\n onEditAsset={setAssetToEdit}\n onEditFolder={setFolderToEdit}\n pagination={pagination!}\n queryObject={queryObject!}\n onAddAsset={onAddAsset}\n onChangeFilters={(filters: FilterCondition<string>[] | BrowseFilter[]) =>\n onChangeFilters!(filters as FilterCondition<string>[])\n }\n onChangeFolder={handleFolderChange}\n onChangePage={onChangePage!}\n onChangePageSize={onChangePageSize!}\n onChangeSort={(sort: string | undefined) => onChangeSort!(sort as Query['sort'])}\n onChangeSearch={onChangeSearch!}\n />\n </Tabs.Content>\n <Tabs.Content value=\"selected\">\n <SelectedStep\n selectedAssets={selectedAssets}\n onSelectAsset={handleSelectAsset}\n onReorderAsset={handleMoveItem}\n />\n </Tabs.Content>\n </Modal.Body>\n </TabsRoot>\n <DialogFooter onClose={onClose} onValidate={() => onValidate(selectedAssets)} />\n </>\n );\n};\n\ninterface AssetDialogProps extends AssetContentProps {\n open?: boolean;\n}\n\nexport const AssetDialog = ({ open = false, onClose, ...restProps }: AssetDialogProps) => {\n return (\n <Modal.Root open={open} onOpenChange={onClose}>\n <Modal.Content>\n <AssetContent onClose={onClose} {...restProps} />\n </Modal.Content>\n </Modal.Root>\n );\n};\n\nconst TabsRoot = styled(Tabs.Root)`\n display: flex;\n flex-direction: column;\n overflow: hidden;\n`;\n"],"names":["LoadingBody","styled","Flex","AssetContent","allowedTypes","folderId","onClose","onAddAsset","onAddFolder","onChangeFolder","onValidate","multiple","initiallySelectedAssets","trackedLocation","assetToEdit","setAssetToEdit","React","useState","undefined","folderToEdit","setFolderToEdit","formatMessage","useIntl","canRead","canCreate","isLoading","isLoadingPermissions","canUpdate","canCopyLink","canDownload","useMediaLibraryPermissions","queryObject","onChangeFilters","onChangePage","onChangePageSize","onChangeSort","onChangeSearch","onChangeFolderParam","useModalQueryParams","folder","data","pagination","results","assets","isLoadingAssets","error","errorAssets","useAssets","skipWhen","query","folders","isLoadingFolders","errorFolders","useFolders","enabled","containsAssetFilter","page","selectedAssets","selectOne","selectOnly","setSelections","selectMultiple","deselectMultiple","useSelectionState","handleSelectAllAssets","allowedAssets","getAllowedFiles","alreadySelected","filter","asset","findIndex","selectedAsset","id","length","handleSelectAsset","hasError","_jsxs","_Fragment","_jsx","Modal","Header","Title","getTrad","defaultMessage","justifyContent","paddingTop","paddingBottom","Loader","DialogFooter","Page","Error","NoPermissions","EditAssetContent","EditFolderContent","location","parentFolderId","handleMoveItem","hoverIndex","destIndex","offset","orderedAssetsClone","slice","nextAssets","moveElement","handleFolderChange","folderPath","TabsRoot","variant","defaultValue","paddingLeft","paddingRight","Tabs","List","Trigger","value","Badge","marginLeft","gap","Button","onClick","Divider","Body","Content","BrowseStep","onSelectAsset","onSelectAllAsset","onEditAsset","onEditFolder","filters","sort","SelectedStep","onReorderAsset","AssetDialog","open","restProps","Root","onOpenChange"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AssetDialog.mjs","sources":["../../../../admin/src/components/AssetDialog/AssetDialog.tsx"],"sourcesContent":["// TODO: find a better naming convention for the file that was an index file before\nimport * as React from 'react';\n\nimport { Page } from '@strapi/admin/strapi-admin';\nimport { Badge, Button, Divider, Flex, Loader, Modal, Tabs } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\nimport { styled } from 'styled-components';\n\nimport { useAssets } from '../../hooks/useAssets';\nimport { useFolders } from '../../hooks/useFolders';\nimport { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';\nimport { useModalQueryParams } from '../../hooks/useModalQueryParams';\nimport { useSelectionState } from '../../hooks/useSelectionState';\nimport {\n containsAssetFilter,\n getTrad,\n getAllowedFiles,\n moveElement,\n AllowedFiles,\n} from '../../utils';\nimport { EditAssetContent, Asset as EditAsset } from '../EditAssetDialog/EditAssetContent';\nimport { EditFolderContent } from '../EditFolderDialog/EditFolderDialog';\n\nimport {\n BrowseStep,\n FolderWithType,\n FileWithType,\n Filter as BrowseFilter,\n} from './BrowseStep/BrowseStep';\nimport { DialogFooter } from './DialogFooter';\nimport { SelectedStep } from './SelectedStep/SelectedStep';\n\nimport type { File as Asset, FilterCondition, Query } from '../../../../shared/contracts/files';\nimport type { Folder, FolderDefinition } from '../../../../shared/contracts/folders';\nimport type { AllowedTypes } from '../AssetCard/AssetCard';\n\nconst LoadingBody = styled(Flex)`\n /* 80px are coming from the Tabs component that is not included in the ModalBody */\n min-height: ${() => `calc(60vh + 8rem)`};\n`;\n\nexport interface FileRow extends Asset {\n folderURL?: string;\n isSelectable?: boolean;\n type?: string;\n}\n\nexport interface FolderRow extends Folder {\n folderURL?: string;\n isSelectable?: boolean;\n type?: string;\n}\n\ninterface AssetContentProps {\n allowedTypes?: AllowedTypes[];\n folderId?: number | null;\n onClose: () => void;\n onAddAsset: (arg?: { folderId: number | { id: number } | null | undefined }) => void;\n onAddFolder: ({ folderId }: { folderId: number | { id: number } | null | undefined }) => void;\n onChangeFolder: (folderId: number | null) => void;\n onValidate: (selectedAssets: Asset[]) => void;\n multiple?: boolean;\n trackedLocation?: string;\n initiallySelectedAssets?: Asset[];\n}\n\nexport const AssetContent = ({\n allowedTypes = [],\n folderId = null,\n onClose,\n onAddAsset,\n onAddFolder,\n onChangeFolder,\n onValidate,\n multiple = false,\n initiallySelectedAssets = [],\n trackedLocation,\n}: AssetContentProps) => {\n const [assetToEdit, setAssetToEdit] = React.useState<FileWithType | undefined>(undefined);\n const [folderToEdit, setFolderToEdit] = React.useState<FolderRow | undefined>(undefined);\n const { formatMessage } = useIntl();\n const {\n canRead,\n canCreate,\n isLoading: isLoadingPermissions,\n canUpdate,\n canCopyLink,\n canDownload,\n } = useMediaLibraryPermissions();\n\n const [\n { queryObject },\n {\n onChangeFilters,\n onChangePage,\n onChangePageSize,\n onChangeSort,\n onChangeSearch,\n onChangeFolder: onChangeFolderParam,\n },\n ] = useModalQueryParams({ folder: folderId });\n\n const {\n data: { pagination, results: assets } = {},\n isLoading: isLoadingAssets,\n error: errorAssets,\n } = useAssets({ skipWhen: !canRead, query: queryObject });\n\n const {\n data: folders,\n isLoading: isLoadingFolders,\n error: errorFolders,\n } = useFolders({\n enabled: canRead && !containsAssetFilter(queryObject!) && pagination?.page === 1,\n query: queryObject,\n });\n\n const [\n selectedAssets,\n { selectOne, selectOnly, setSelections, selectMultiple, deselectMultiple },\n ] = useSelectionState(['id'], initiallySelectedAssets);\n\n const handleSelectAllAssets = () => {\n const allowedAssets = getAllowedFiles(allowedTypes, assets as AllowedFiles[]);\n\n if (!multiple) {\n return undefined;\n }\n\n // selected files in current folder\n const alreadySelected = allowedAssets.filter(\n (asset) => selectedAssets.findIndex((selectedAsset) => selectedAsset.id === asset.id) !== -1\n );\n\n if (alreadySelected.length > 0) {\n deselectMultiple(alreadySelected);\n } else {\n selectMultiple(allowedAssets);\n }\n };\n\n const handleSelectAsset = (asset: Asset | FileRow | FolderRow) => {\n return multiple ? selectOne(asset as Asset) : selectOnly(asset as Asset);\n };\n\n const isLoading = isLoadingPermissions || isLoadingAssets || isLoadingFolders;\n const hasError = errorAssets || errorFolders;\n\n const [activeTab, setActiveTab] = React.useState(\n selectedAssets.length > 0 ? 'selected' : 'browse'\n );\n\n if (isLoading) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <LoadingBody justifyContent=\"center\" paddingTop={4} paddingBottom={4}>\n <Loader>\n {formatMessage({\n id: getTrad('content.isLoading'),\n defaultMessage: 'Content is loading.',\n })}\n </Loader>\n </LoadingBody>\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (hasError) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <Page.Error />\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (!canRead) {\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n <Page.NoPermissions />\n <DialogFooter onClose={onClose} />\n </>\n );\n }\n\n if (assetToEdit) {\n return (\n <EditAssetContent\n onClose={() => setAssetToEdit(undefined)}\n asset={assetToEdit as EditAsset}\n canUpdate={canUpdate}\n canCopyLink={canCopyLink}\n canDownload={canDownload}\n trackedLocation={trackedLocation}\n />\n );\n }\n\n if (folderToEdit) {\n return (\n <EditFolderContent\n folder={folderToEdit as FolderDefinition}\n onClose={() => setFolderToEdit(undefined)}\n location=\"content-manager\"\n parentFolderId={queryObject?.folder as string | number | null | undefined}\n />\n );\n }\n\n const handleMoveItem = (hoverIndex: number, destIndex: number) => {\n const offset = destIndex - hoverIndex;\n const orderedAssetsClone = selectedAssets.slice();\n const nextAssets = moveElement<Asset>(orderedAssetsClone, hoverIndex, offset);\n setSelections(nextAssets);\n };\n\n const handleFolderChange = (folderId: number, folderPath?: string) => {\n onChangeFolder(folderId);\n if (onChangeFolderParam) {\n onChangeFolderParam(folderId, folderPath);\n }\n };\n\n return (\n <>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: getTrad('header.actions.add-assets'),\n defaultMessage: 'Add new assets',\n })}\n </Modal.Title>\n </Modal.Header>\n\n <TabsRoot variant=\"simple\" value={activeTab} onValueChange={setActiveTab}>\n <Flex paddingLeft={8} paddingRight={8} paddingTop={6} justifyContent=\"space-between\">\n <Tabs.List>\n <Tabs.Trigger value=\"browse\">\n {formatMessage({\n id: getTrad('modal.nav.browse'),\n defaultMessage: 'Browse',\n })}\n </Tabs.Trigger>\n <Tabs.Trigger value=\"selected\">\n {formatMessage({\n id: getTrad('modal.header.select-files'),\n defaultMessage: 'Selected files',\n })}\n <Badge marginLeft={2}>{selectedAssets.length}</Badge>\n </Tabs.Trigger>\n </Tabs.List>\n <Flex gap={2}>\n <Button\n variant=\"secondary\"\n onClick={() => onAddFolder({ folderId: queryObject?.folder })}\n >\n {formatMessage({\n id: getTrad('modal.upload-list.sub-header.add-folder'),\n defaultMessage: 'Add folder',\n })}\n </Button>\n <Button onClick={() => onAddAsset({ folderId: queryObject?.folder })}>\n {formatMessage({\n id: getTrad('modal.upload-list.sub-header.button'),\n defaultMessage: 'Add more assets',\n })}\n </Button>\n </Flex>\n </Flex>\n <Divider />\n <Modal.Body>\n <Tabs.Content value=\"browse\">\n <BrowseStep\n allowedTypes={allowedTypes}\n assets={assets!}\n canCreate={canCreate}\n canRead={canRead}\n folders={folders as FolderWithType[]}\n onSelectAsset={handleSelectAsset}\n selectedAssets={selectedAssets}\n multiple={multiple}\n onSelectAllAsset={handleSelectAllAssets}\n onEditAsset={setAssetToEdit}\n onEditFolder={setFolderToEdit}\n pagination={pagination!}\n queryObject={queryObject!}\n onAddAsset={onAddAsset}\n onChangeFilters={(filters: FilterCondition<string>[] | BrowseFilter[]) =>\n onChangeFilters!(filters as FilterCondition<string>[])\n }\n onChangeFolder={handleFolderChange}\n onChangePage={onChangePage!}\n onChangePageSize={onChangePageSize!}\n onChangeSort={(sort: string | undefined) => onChangeSort!(sort as Query['sort'])}\n onChangeSearch={onChangeSearch!}\n />\n </Tabs.Content>\n <Tabs.Content value=\"selected\">\n <SelectedStep\n selectedAssets={selectedAssets}\n onSelectAsset={handleSelectAsset}\n onReorderAsset={handleMoveItem}\n />\n </Tabs.Content>\n </Modal.Body>\n </TabsRoot>\n <DialogFooter onClose={onClose} onValidate={() => onValidate(selectedAssets)} />\n </>\n );\n};\n\ninterface AssetDialogProps extends AssetContentProps {\n open?: boolean;\n}\n\nexport const AssetDialog = ({ open = false, onClose, ...restProps }: AssetDialogProps) => {\n return (\n <Modal.Root open={open} onOpenChange={onClose}>\n <Modal.Content>\n <AssetContent onClose={onClose} {...restProps} />\n </Modal.Content>\n </Modal.Root>\n );\n};\n\nconst TabsRoot = styled(Tabs.Root)`\n display: flex;\n flex-direction: column;\n overflow: hidden;\n`;\n"],"names":["LoadingBody","styled","Flex","AssetContent","allowedTypes","folderId","onClose","onAddAsset","onAddFolder","onChangeFolder","onValidate","multiple","initiallySelectedAssets","trackedLocation","assetToEdit","setAssetToEdit","React","useState","undefined","folderToEdit","setFolderToEdit","formatMessage","useIntl","canRead","canCreate","isLoading","isLoadingPermissions","canUpdate","canCopyLink","canDownload","useMediaLibraryPermissions","queryObject","onChangeFilters","onChangePage","onChangePageSize","onChangeSort","onChangeSearch","onChangeFolderParam","useModalQueryParams","folder","data","pagination","results","assets","isLoadingAssets","error","errorAssets","useAssets","skipWhen","query","folders","isLoadingFolders","errorFolders","useFolders","enabled","containsAssetFilter","page","selectedAssets","selectOne","selectOnly","setSelections","selectMultiple","deselectMultiple","useSelectionState","handleSelectAllAssets","allowedAssets","getAllowedFiles","alreadySelected","filter","asset","findIndex","selectedAsset","id","length","handleSelectAsset","hasError","activeTab","setActiveTab","_jsxs","_Fragment","_jsx","Modal","Header","Title","getTrad","defaultMessage","justifyContent","paddingTop","paddingBottom","Loader","DialogFooter","Page","Error","NoPermissions","EditAssetContent","EditFolderContent","location","parentFolderId","handleMoveItem","hoverIndex","destIndex","offset","orderedAssetsClone","slice","nextAssets","moveElement","handleFolderChange","folderPath","TabsRoot","variant","value","onValueChange","paddingLeft","paddingRight","Tabs","List","Trigger","Badge","marginLeft","gap","Button","onClick","Divider","Body","Content","BrowseStep","onSelectAsset","onSelectAllAsset","onEditAsset","onEditFolder","filters","sort","SelectedStep","onReorderAsset","AssetDialog","open","restProps","Root","onOpenChange"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var name = "@strapi/upload";
|
|
6
|
-
var version = "5.
|
|
6
|
+
var version = "5.15.0";
|
|
7
7
|
var description = "Makes it easy to upload images and files to your Strapi Application.";
|
|
8
8
|
var license = "SEE LICENSE IN LICENSE";
|
|
9
9
|
var author = {
|
|
@@ -64,10 +64,10 @@ var scripts = {
|
|
|
64
64
|
};
|
|
65
65
|
var dependencies = {
|
|
66
66
|
"@mux/mux-player-react": "3.1.0",
|
|
67
|
-
"@strapi/design-system": "2.0.0-rc.
|
|
68
|
-
"@strapi/icons": "2.0.0-rc.
|
|
69
|
-
"@strapi/provider-upload-local": "5.
|
|
70
|
-
"@strapi/utils": "5.
|
|
67
|
+
"@strapi/design-system": "2.0.0-rc.25",
|
|
68
|
+
"@strapi/icons": "2.0.0-rc.25",
|
|
69
|
+
"@strapi/provider-upload-local": "5.15.0",
|
|
70
|
+
"@strapi/utils": "5.15.0",
|
|
71
71
|
"byte-size": "8.1.1",
|
|
72
72
|
cropperjs: "1.6.1",
|
|
73
73
|
"date-fns": "2.30.0",
|
|
@@ -89,8 +89,8 @@ var dependencies = {
|
|
|
89
89
|
yup: "0.32.9"
|
|
90
90
|
};
|
|
91
91
|
var devDependencies = {
|
|
92
|
-
"@strapi/admin": "5.
|
|
93
|
-
"@strapi/types": "5.
|
|
92
|
+
"@strapi/admin": "5.15.0",
|
|
93
|
+
"@strapi/types": "5.15.0",
|
|
94
94
|
"@testing-library/dom": "10.1.0",
|
|
95
95
|
"@testing-library/react": "15.0.7",
|
|
96
96
|
"@testing-library/user-event": "14.5.2",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var name = "@strapi/upload";
|
|
2
|
-
var version = "5.
|
|
2
|
+
var version = "5.15.0";
|
|
3
3
|
var description = "Makes it easy to upload images and files to your Strapi Application.";
|
|
4
4
|
var license = "SEE LICENSE IN LICENSE";
|
|
5
5
|
var author = {
|
|
@@ -60,10 +60,10 @@ var scripts = {
|
|
|
60
60
|
};
|
|
61
61
|
var dependencies = {
|
|
62
62
|
"@mux/mux-player-react": "3.1.0",
|
|
63
|
-
"@strapi/design-system": "2.0.0-rc.
|
|
64
|
-
"@strapi/icons": "2.0.0-rc.
|
|
65
|
-
"@strapi/provider-upload-local": "5.
|
|
66
|
-
"@strapi/utils": "5.
|
|
63
|
+
"@strapi/design-system": "2.0.0-rc.25",
|
|
64
|
+
"@strapi/icons": "2.0.0-rc.25",
|
|
65
|
+
"@strapi/provider-upload-local": "5.15.0",
|
|
66
|
+
"@strapi/utils": "5.15.0",
|
|
67
67
|
"byte-size": "8.1.1",
|
|
68
68
|
cropperjs: "1.6.1",
|
|
69
69
|
"date-fns": "2.30.0",
|
|
@@ -85,8 +85,8 @@ var dependencies = {
|
|
|
85
85
|
yup: "0.32.9"
|
|
86
86
|
};
|
|
87
87
|
var devDependencies = {
|
|
88
|
-
"@strapi/admin": "5.
|
|
89
|
-
"@strapi/types": "5.
|
|
88
|
+
"@strapi/admin": "5.15.0",
|
|
89
|
+
"@strapi/types": "5.15.0",
|
|
90
90
|
"@testing-library/dom": "10.1.0",
|
|
91
91
|
"@testing-library/react": "15.0.7",
|
|
92
92
|
"@testing-library/user-event": "14.5.2",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var fs = require('fs');
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var sharp = require('sharp');
|
|
6
|
+
var crypto = require('crypto');
|
|
6
7
|
var utils = require('@strapi/utils');
|
|
7
8
|
var index = require('../utils/index.js');
|
|
8
9
|
|
|
@@ -240,6 +241,14 @@ const isImage = async (file)=>{
|
|
|
240
241
|
}
|
|
241
242
|
return format && FORMATS_TO_PROCESS.includes(format);
|
|
242
243
|
};
|
|
244
|
+
const generateFileName = (name)=>{
|
|
245
|
+
const randomSuffix = ()=>crypto.randomBytes(5).toString('hex');
|
|
246
|
+
const baseName = utils.strings.nameToSlug(name, {
|
|
247
|
+
separator: '_',
|
|
248
|
+
lowercase: false
|
|
249
|
+
});
|
|
250
|
+
return `${baseName}_${randomSuffix()}`;
|
|
251
|
+
};
|
|
243
252
|
var imageManipulation = {
|
|
244
253
|
isFaultyImage,
|
|
245
254
|
isOptimizableImage,
|
|
@@ -248,7 +257,8 @@ var imageManipulation = {
|
|
|
248
257
|
getDimensions,
|
|
249
258
|
generateResponsiveFormats,
|
|
250
259
|
generateThumbnail,
|
|
251
|
-
optimize
|
|
260
|
+
optimize,
|
|
261
|
+
generateFileName
|
|
252
262
|
};
|
|
253
263
|
|
|
254
264
|
module.exports = imageManipulation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-manipulation.js","sources":["../../../server/src/services/image-manipulation.ts"],"sourcesContent":["import fs from 'fs';\nimport { join } from 'path';\nimport sharp from 'sharp';\nimport { file as fileUtils } from '@strapi/utils';\n\nimport { getService } from '../utils';\n\nimport type { UploadableFile } from '../types';\n\ntype Dimensions = {\n width: number | null;\n height: number | null;\n};\n\nconst { bytesToKbytes } = fileUtils;\n\nconst FORMATS_TO_RESIZE = ['jpeg', 'png', 'webp', 'tiff', 'gif'];\nconst FORMATS_TO_PROCESS = ['jpeg', 'png', 'webp', 'tiff', 'svg', 'gif', 'avif'];\nconst FORMATS_TO_OPTIMIZE = ['jpeg', 'png', 'webp', 'tiff', 'avif'];\n\nconst isOptimizableFormat = (\n format: string | undefined\n): format is 'jpeg' | 'png' | 'webp' | 'tiff' | 'avif' =>\n format !== undefined && FORMATS_TO_OPTIMIZE.includes(format);\n\nconst writeStreamToFile = (stream: NodeJS.ReadWriteStream, path: string) =>\n new Promise((resolve, reject) => {\n const writeStream = fs.createWriteStream(path);\n // Reject promise if there is an error with the provided stream\n stream.on('error', reject);\n stream.pipe(writeStream);\n writeStream.on('close', resolve);\n writeStream.on('error', reject);\n });\n\nconst getMetadata = (file: UploadableFile): Promise<sharp.Metadata> => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.metadata().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n return sharp(file.filepath).metadata();\n};\n\nconst getDimensions = async (file: UploadableFile): Promise<Dimensions> => {\n const { width = null, height = null } = await getMetadata(file);\n\n return { width, height };\n};\n\nconst THUMBNAIL_RESIZE_OPTIONS = {\n width: 245,\n height: 156,\n fit: 'inside',\n} satisfies sharp.ResizeOptions;\n\nconst resizeFileTo = async (\n file: UploadableFile,\n options: sharp.ResizeOptions,\n {\n name,\n hash,\n }: {\n name: string;\n hash: string;\n }\n) => {\n const filePath = file.tmpWorkingDirectory ? join(file.tmpWorkingDirectory, hash) : hash;\n\n let newInfo;\n if (!file.filepath) {\n const transform = sharp()\n .resize(options)\n .on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transform), filePath);\n } else {\n newInfo = await sharp(file.filepath).resize(options).toFile(filePath);\n }\n\n const { width, height, size } = newInfo ?? {};\n\n const newFile: UploadableFile = {\n name,\n hash,\n ext: file.ext,\n mime: file.mime,\n filepath: filePath,\n path: file.path || null,\n getStream: () => fs.createReadStream(filePath),\n };\n\n Object.assign(newFile, {\n width,\n height,\n size: size ? bytesToKbytes(size) : 0,\n sizeInBytes: size,\n });\n return newFile;\n};\n\nconst generateThumbnail = async (file: UploadableFile) => {\n if (\n file.width &&\n file.height &&\n (file.width > THUMBNAIL_RESIZE_OPTIONS.width || file.height > THUMBNAIL_RESIZE_OPTIONS.height)\n ) {\n return resizeFileTo(file, THUMBNAIL_RESIZE_OPTIONS, {\n name: `thumbnail_${file.name}`,\n hash: `thumbnail_${file.hash}`,\n });\n }\n\n return null;\n};\n\n/**\n * Optimize image by:\n * - auto orienting image based on EXIF data\n * - reduce image quality\n *\n */\nconst optimize = async (file: UploadableFile) => {\n const { sizeOptimization = false, autoOrientation = false } =\n (await getService('upload').getSettings()) ?? {};\n\n const { format, size } = await getMetadata(file);\n\n if ((sizeOptimization || autoOrientation) && isOptimizableFormat(format)) {\n let transformer;\n if (!file.filepath) {\n transformer = sharp();\n } else {\n transformer = sharp(file.filepath);\n }\n // reduce image quality\n transformer[format]({ quality: sizeOptimization ? 80 : 100 });\n // rotate image based on EXIF data\n if (autoOrientation) {\n transformer.rotate();\n }\n const filePath = file.tmpWorkingDirectory\n ? join(file.tmpWorkingDirectory, `optimized-${file.hash}`)\n : `optimized-${file.hash}`;\n\n let newInfo;\n if (!file.filepath) {\n transformer.on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transformer), filePath);\n } else {\n newInfo = await transformer.toFile(filePath);\n }\n\n const { width: newWidth, height: newHeight, size: newSize } = newInfo ?? {};\n\n const newFile = { ...file };\n\n newFile.getStream = () => fs.createReadStream(filePath);\n newFile.filepath = filePath;\n\n if (newSize && size && newSize > size) {\n // Ignore optimization if output is bigger than original\n return file;\n }\n\n return Object.assign(newFile, {\n width: newWidth,\n height: newHeight,\n size: newSize ? bytesToKbytes(newSize) : 0,\n sizeInBytes: newSize,\n });\n }\n\n return file;\n};\n\nconst DEFAULT_BREAKPOINTS = {\n large: 1000,\n medium: 750,\n small: 500,\n};\n\nconst getBreakpoints = () =>\n strapi.config.get<Record<string, number>>('plugin::upload.breakpoints', DEFAULT_BREAKPOINTS);\n\nconst generateResponsiveFormats = async (file: UploadableFile) => {\n const { responsiveDimensions = false } = (await getService('upload').getSettings()) ?? {};\n\n if (!responsiveDimensions) return [];\n\n const originalDimensions = await getDimensions(file);\n\n const breakpoints = getBreakpoints();\n return Promise.all(\n Object.keys(breakpoints).map((key) => {\n const breakpoint = breakpoints[key];\n\n if (breakpointSmallerThan(breakpoint, originalDimensions)) {\n return generateBreakpoint(key, { file, breakpoint });\n }\n\n return undefined;\n })\n );\n};\n\nconst generateBreakpoint = async (\n key: string,\n { file, breakpoint }: { file: UploadableFile; breakpoint: number }\n) => {\n const newFile = await resizeFileTo(\n file,\n {\n width: breakpoint,\n height: breakpoint,\n fit: 'inside',\n },\n {\n name: `${key}_${file.name}`,\n hash: `${key}_${file.hash}`,\n }\n );\n return {\n key,\n file: newFile,\n };\n};\n\nconst breakpointSmallerThan = (breakpoint: number, { width, height }: Dimensions) => {\n return breakpoint < (width ?? 0) || breakpoint < (height ?? 0);\n};\n\n/**\n * Applies a simple image transformation to see if the image is faulty/corrupted.\n */\nconst isFaultyImage = async (file: UploadableFile) => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.stats().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n try {\n await sharp(file.filepath).stats();\n return false;\n } catch (e) {\n return true;\n }\n};\n\nconst isOptimizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_OPTIMIZE.includes(format);\n};\n\nconst isResizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_RESIZE.includes(format);\n};\n\nconst isImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_PROCESS.includes(format);\n};\n\nexport default {\n isFaultyImage,\n isOptimizableImage,\n isResizableImage,\n isImage,\n getDimensions,\n generateResponsiveFormats,\n generateThumbnail,\n optimize,\n};\n"],"names":["bytesToKbytes","fileUtils","FORMATS_TO_RESIZE","FORMATS_TO_PROCESS","FORMATS_TO_OPTIMIZE","isOptimizableFormat","format","undefined","includes","writeStreamToFile","stream","path","Promise","resolve","reject","writeStream","fs","createWriteStream","on","pipe","getMetadata","file","filepath","pipeline","sharp","metadata","then","catch","getStream","getDimensions","width","height","THUMBNAIL_RESIZE_OPTIONS","fit","resizeFileTo","options","name","hash","filePath","tmpWorkingDirectory","join","newInfo","transform","resize","info","toFile","size","newFile","ext","mime","createReadStream","Object","assign","sizeInBytes","generateThumbnail","optimize","sizeOptimization","autoOrientation","getService","getSettings","transformer","quality","rotate","newWidth","newHeight","newSize","DEFAULT_BREAKPOINTS","large","medium","small","getBreakpoints","strapi","config","get","generateResponsiveFormats","responsiveDimensions","originalDimensions","breakpoints","all","keys","map","key","breakpoint","breakpointSmallerThan","generateBreakpoint","isFaultyImage","stats","e","isOptimizableImage","isResizableImage","isImage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"image-manipulation.js","sources":["../../../server/src/services/image-manipulation.ts"],"sourcesContent":["import fs from 'fs';\nimport { join } from 'path';\nimport sharp from 'sharp';\nimport crypto from 'crypto';\nimport { strings, file as fileUtils } from '@strapi/utils';\n\nimport { getService } from '../utils';\n\nimport type { UploadableFile } from '../types';\n\ntype Dimensions = {\n width: number | null;\n height: number | null;\n};\n\nconst { bytesToKbytes } = fileUtils;\n\nconst FORMATS_TO_RESIZE = ['jpeg', 'png', 'webp', 'tiff', 'gif'];\nconst FORMATS_TO_PROCESS = ['jpeg', 'png', 'webp', 'tiff', 'svg', 'gif', 'avif'];\nconst FORMATS_TO_OPTIMIZE = ['jpeg', 'png', 'webp', 'tiff', 'avif'];\n\nconst isOptimizableFormat = (\n format: string | undefined\n): format is 'jpeg' | 'png' | 'webp' | 'tiff' | 'avif' =>\n format !== undefined && FORMATS_TO_OPTIMIZE.includes(format);\n\nconst writeStreamToFile = (stream: NodeJS.ReadWriteStream, path: string) =>\n new Promise((resolve, reject) => {\n const writeStream = fs.createWriteStream(path);\n // Reject promise if there is an error with the provided stream\n stream.on('error', reject);\n stream.pipe(writeStream);\n writeStream.on('close', resolve);\n writeStream.on('error', reject);\n });\n\nconst getMetadata = (file: UploadableFile): Promise<sharp.Metadata> => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.metadata().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n return sharp(file.filepath).metadata();\n};\n\nconst getDimensions = async (file: UploadableFile): Promise<Dimensions> => {\n const { width = null, height = null } = await getMetadata(file);\n\n return { width, height };\n};\n\nconst THUMBNAIL_RESIZE_OPTIONS = {\n width: 245,\n height: 156,\n fit: 'inside',\n} satisfies sharp.ResizeOptions;\n\nconst resizeFileTo = async (\n file: UploadableFile,\n options: sharp.ResizeOptions,\n {\n name,\n hash,\n }: {\n name: string;\n hash: string;\n }\n) => {\n const filePath = file.tmpWorkingDirectory ? join(file.tmpWorkingDirectory, hash) : hash;\n\n let newInfo;\n if (!file.filepath) {\n const transform = sharp()\n .resize(options)\n .on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transform), filePath);\n } else {\n newInfo = await sharp(file.filepath).resize(options).toFile(filePath);\n }\n\n const { width, height, size } = newInfo ?? {};\n\n const newFile: UploadableFile = {\n name,\n hash,\n ext: file.ext,\n mime: file.mime,\n filepath: filePath,\n path: file.path || null,\n getStream: () => fs.createReadStream(filePath),\n };\n\n Object.assign(newFile, {\n width,\n height,\n size: size ? bytesToKbytes(size) : 0,\n sizeInBytes: size,\n });\n return newFile;\n};\n\nconst generateThumbnail = async (file: UploadableFile) => {\n if (\n file.width &&\n file.height &&\n (file.width > THUMBNAIL_RESIZE_OPTIONS.width || file.height > THUMBNAIL_RESIZE_OPTIONS.height)\n ) {\n return resizeFileTo(file, THUMBNAIL_RESIZE_OPTIONS, {\n name: `thumbnail_${file.name}`,\n hash: `thumbnail_${file.hash}`,\n });\n }\n\n return null;\n};\n\n/**\n * Optimize image by:\n * - auto orienting image based on EXIF data\n * - reduce image quality\n *\n */\nconst optimize = async (file: UploadableFile) => {\n const { sizeOptimization = false, autoOrientation = false } =\n (await getService('upload').getSettings()) ?? {};\n\n const { format, size } = await getMetadata(file);\n\n if ((sizeOptimization || autoOrientation) && isOptimizableFormat(format)) {\n let transformer;\n if (!file.filepath) {\n transformer = sharp();\n } else {\n transformer = sharp(file.filepath);\n }\n // reduce image quality\n transformer[format]({ quality: sizeOptimization ? 80 : 100 });\n // rotate image based on EXIF data\n if (autoOrientation) {\n transformer.rotate();\n }\n const filePath = file.tmpWorkingDirectory\n ? join(file.tmpWorkingDirectory, `optimized-${file.hash}`)\n : `optimized-${file.hash}`;\n\n let newInfo;\n if (!file.filepath) {\n transformer.on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transformer), filePath);\n } else {\n newInfo = await transformer.toFile(filePath);\n }\n\n const { width: newWidth, height: newHeight, size: newSize } = newInfo ?? {};\n\n const newFile = { ...file };\n\n newFile.getStream = () => fs.createReadStream(filePath);\n newFile.filepath = filePath;\n\n if (newSize && size && newSize > size) {\n // Ignore optimization if output is bigger than original\n return file;\n }\n\n return Object.assign(newFile, {\n width: newWidth,\n height: newHeight,\n size: newSize ? bytesToKbytes(newSize) : 0,\n sizeInBytes: newSize,\n });\n }\n\n return file;\n};\n\nconst DEFAULT_BREAKPOINTS = {\n large: 1000,\n medium: 750,\n small: 500,\n};\n\nconst getBreakpoints = () =>\n strapi.config.get<Record<string, number>>('plugin::upload.breakpoints', DEFAULT_BREAKPOINTS);\n\nconst generateResponsiveFormats = async (file: UploadableFile) => {\n const { responsiveDimensions = false } = (await getService('upload').getSettings()) ?? {};\n\n if (!responsiveDimensions) return [];\n\n const originalDimensions = await getDimensions(file);\n\n const breakpoints = getBreakpoints();\n return Promise.all(\n Object.keys(breakpoints).map((key) => {\n const breakpoint = breakpoints[key];\n\n if (breakpointSmallerThan(breakpoint, originalDimensions)) {\n return generateBreakpoint(key, { file, breakpoint });\n }\n\n return undefined;\n })\n );\n};\n\nconst generateBreakpoint = async (\n key: string,\n { file, breakpoint }: { file: UploadableFile; breakpoint: number }\n) => {\n const newFile = await resizeFileTo(\n file,\n {\n width: breakpoint,\n height: breakpoint,\n fit: 'inside',\n },\n {\n name: `${key}_${file.name}`,\n hash: `${key}_${file.hash}`,\n }\n );\n return {\n key,\n file: newFile,\n };\n};\n\nconst breakpointSmallerThan = (breakpoint: number, { width, height }: Dimensions) => {\n return breakpoint < (width ?? 0) || breakpoint < (height ?? 0);\n};\n\n/**\n * Applies a simple image transformation to see if the image is faulty/corrupted.\n */\nconst isFaultyImage = async (file: UploadableFile) => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.stats().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n try {\n await sharp(file.filepath).stats();\n return false;\n } catch (e) {\n return true;\n }\n};\n\nconst isOptimizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_OPTIMIZE.includes(format);\n};\n\nconst isResizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_RESIZE.includes(format);\n};\n\nconst isImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_PROCESS.includes(format);\n};\n\nconst generateFileName = (name: string) => {\n const randomSuffix = () => crypto.randomBytes(5).toString('hex');\n const baseName = strings.nameToSlug(name, { separator: '_', lowercase: false });\n\n return `${baseName}_${randomSuffix()}`;\n};\n\nexport default {\n isFaultyImage,\n isOptimizableImage,\n isResizableImage,\n isImage,\n getDimensions,\n generateResponsiveFormats,\n generateThumbnail,\n optimize,\n generateFileName,\n};\n"],"names":["bytesToKbytes","fileUtils","FORMATS_TO_RESIZE","FORMATS_TO_PROCESS","FORMATS_TO_OPTIMIZE","isOptimizableFormat","format","undefined","includes","writeStreamToFile","stream","path","Promise","resolve","reject","writeStream","fs","createWriteStream","on","pipe","getMetadata","file","filepath","pipeline","sharp","metadata","then","catch","getStream","getDimensions","width","height","THUMBNAIL_RESIZE_OPTIONS","fit","resizeFileTo","options","name","hash","filePath","tmpWorkingDirectory","join","newInfo","transform","resize","info","toFile","size","newFile","ext","mime","createReadStream","Object","assign","sizeInBytes","generateThumbnail","optimize","sizeOptimization","autoOrientation","getService","getSettings","transformer","quality","rotate","newWidth","newHeight","newSize","DEFAULT_BREAKPOINTS","large","medium","small","getBreakpoints","strapi","config","get","generateResponsiveFormats","responsiveDimensions","originalDimensions","breakpoints","all","keys","map","key","breakpoint","breakpointSmallerThan","generateBreakpoint","isFaultyImage","stats","e","isOptimizableImage","isResizableImage","isImage","generateFileName","randomSuffix","crypto","randomBytes","toString","baseName","strings","nameToSlug","separator","lowercase"],"mappings":";;;;;;;;;AAeA,MAAM,EAAEA,aAAa,EAAE,GAAGC,UAAAA;AAE1B,MAAMC,iBAAoB,GAAA;AAAC,IAAA,MAAA;AAAQ,IAAA,KAAA;AAAO,IAAA,MAAA;AAAQ,IAAA,MAAA;AAAQ,IAAA;AAAM,CAAA;AAChE,MAAMC,kBAAqB,GAAA;AAAC,IAAA,MAAA;AAAQ,IAAA,KAAA;AAAO,IAAA,MAAA;AAAQ,IAAA,MAAA;AAAQ,IAAA,KAAA;AAAO,IAAA,KAAA;AAAO,IAAA;AAAO,CAAA;AAChF,MAAMC,mBAAsB,GAAA;AAAC,IAAA,MAAA;AAAQ,IAAA,KAAA;AAAO,IAAA,MAAA;AAAQ,IAAA,MAAA;AAAQ,IAAA;AAAO,CAAA;AAEnE,MAAMC,sBAAsB,CAC1BC,MAAAA,GAEAA,WAAWC,SAAaH,IAAAA,mBAAAA,CAAoBI,QAAQ,CAACF,MAAAA,CAAAA;AAEvD,MAAMG,oBAAoB,CAACC,MAAAA,EAAgCC,OACzD,IAAIC,OAAAA,CAAQ,CAACC,OAASC,EAAAA,MAAAA,GAAAA;QACpB,MAAMC,WAAAA,GAAcC,EAAGC,CAAAA,iBAAiB,CAACN,IAAAA,CAAAA;;QAEzCD,MAAOQ,CAAAA,EAAE,CAAC,OAASJ,EAAAA,MAAAA,CAAAA;AACnBJ,QAAAA,MAAAA,CAAOS,IAAI,CAACJ,WAAAA,CAAAA;QACZA,WAAYG,CAAAA,EAAE,CAAC,OAASL,EAAAA,OAAAA,CAAAA;QACxBE,WAAYG,CAAAA,EAAE,CAAC,OAASJ,EAAAA,MAAAA,CAAAA;AAC1B,KAAA,CAAA;AAEF,MAAMM,cAAc,CAACC,IAAAA,GAAAA;IACnB,IAAI,CAACA,IAAKC,CAAAA,QAAQ,EAAE;QAClB,OAAO,IAAIV,OAAQ,CAAA,CAACC,OAASC,EAAAA,MAAAA,GAAAA;AAC3B,YAAA,MAAMS,QAAWC,GAAAA,KAAAA,EAAAA;AACjBD,YAAAA,QAAAA,CAASE,QAAQ,EAAGC,CAAAA,IAAI,CAACb,OAAAA,CAAAA,CAASc,KAAK,CAACb,MAAAA,CAAAA;YACxCO,IAAKO,CAAAA,SAAS,EAAGT,CAAAA,IAAI,CAACI,QAAAA,CAAAA;AACxB,SAAA,CAAA;AACF;AAEA,IAAA,OAAOC,KAAMH,CAAAA,IAAAA,CAAKC,QAAQ,CAAA,CAAEG,QAAQ,EAAA;AACtC,CAAA;AAEA,MAAMI,gBAAgB,OAAOR,IAAAA,GAAAA;IAC3B,MAAM,EAAES,QAAQ,IAAI,EAAEC,SAAS,IAAI,EAAE,GAAG,MAAMX,WAAYC,CAAAA,IAAAA,CAAAA;IAE1D,OAAO;AAAES,QAAAA,KAAAA;AAAOC,QAAAA;AAAO,KAAA;AACzB,CAAA;AAEA,MAAMC,wBAA2B,GAAA;IAC/BF,KAAO,EAAA,GAAA;IACPC,MAAQ,EAAA,GAAA;IACRE,GAAK,EAAA;AACP,CAAA;AAEA,MAAMC,YAAAA,GAAe,OACnBb,IACAc,EAAAA,OAAAA,EACA,EACEC,IAAI,EACJC,IAAI,EAIL,GAAA;IAED,MAAMC,QAAAA,GAAWjB,KAAKkB,mBAAmB,GAAGC,UAAKnB,IAAKkB,CAAAA,mBAAmB,EAAEF,IAAQA,CAAAA,GAAAA,IAAAA;IAEnF,IAAII,OAAAA;IACJ,IAAI,CAACpB,IAAKC,CAAAA,QAAQ,EAAE;QAClB,MAAMoB,SAAAA,GAAYlB,QACfmB,MAAM,CAACR,SACPjB,EAAE,CAAC,QAAQ,CAAC0B,IAAAA,GAAAA;YACXH,OAAUG,GAAAA,IAAAA;AACZ,SAAA,CAAA;AAEF,QAAA,MAAMnC,kBAAkBY,IAAKO,CAAAA,SAAS,EAAGT,CAAAA,IAAI,CAACuB,SAAYJ,CAAAA,EAAAA,QAAAA,CAAAA;KACrD,MAAA;QACLG,OAAU,GAAA,MAAMjB,MAAMH,IAAKC,CAAAA,QAAQ,EAAEqB,MAAM,CAACR,OAASU,CAAAA,CAAAA,MAAM,CAACP,QAAAA,CAAAA;AAC9D;IAEA,MAAM,EAAER,KAAK,EAAEC,MAAM,EAAEe,IAAI,EAAE,GAAGL,OAAAA,IAAW,EAAC;AAE5C,IAAA,MAAMM,OAA0B,GAAA;AAC9BX,QAAAA,IAAAA;AACAC,QAAAA,IAAAA;AACAW,QAAAA,GAAAA,EAAK3B,KAAK2B,GAAG;AACbC,QAAAA,IAAAA,EAAM5B,KAAK4B,IAAI;QACf3B,QAAUgB,EAAAA,QAAAA;QACV3B,IAAMU,EAAAA,IAAAA,CAAKV,IAAI,IAAI,IAAA;QACnBiB,SAAW,EAAA,IAAMZ,EAAGkC,CAAAA,gBAAgB,CAACZ,QAAAA;AACvC,KAAA;IAEAa,MAAOC,CAAAA,MAAM,CAACL,OAAS,EAAA;AACrBjB,QAAAA,KAAAA;AACAC,QAAAA,MAAAA;QACAe,IAAMA,EAAAA,IAAAA,GAAO9C,cAAc8C,IAAQ,CAAA,GAAA,CAAA;QACnCO,WAAaP,EAAAA;AACf,KAAA,CAAA;IACA,OAAOC,OAAAA;AACT,CAAA;AAEA,MAAMO,oBAAoB,OAAOjC,IAAAA,GAAAA;AAC/B,IAAA,IACEA,KAAKS,KAAK,IACVT,KAAKU,MAAM,KACVV,IAAKS,CAAAA,KAAK,GAAGE,wBAAyBF,CAAAA,KAAK,IAAIT,IAAKU,CAAAA,MAAM,GAAGC,wBAAyBD,CAAAA,MAAM,CAC7F,EAAA;QACA,OAAOG,YAAAA,CAAab,MAAMW,wBAA0B,EAAA;AAClDI,YAAAA,IAAAA,EAAM,CAAC,UAAU,EAAEf,IAAKe,CAAAA,IAAI,CAAC,CAAC;AAC9BC,YAAAA,IAAAA,EAAM,CAAC,UAAU,EAAEhB,IAAKgB,CAAAA,IAAI,CAAC;AAC/B,SAAA,CAAA;AACF;IAEA,OAAO,IAAA;AACT,CAAA;AAEA;;;;;IAMA,MAAMkB,WAAW,OAAOlC,IAAAA,GAAAA;AACtB,IAAA,MAAM,EAAEmC,gBAAAA,GAAmB,KAAK,EAAEC,kBAAkB,KAAK,EAAE,GACxD,MAAMC,gBAAAA,CAAW,QAAUC,CAAAA,CAAAA,WAAW,MAAO,EAAC;AAEjD,IAAA,MAAM,EAAErD,MAAM,EAAEwC,IAAI,EAAE,GAAG,MAAM1B,WAAYC,CAAAA,IAAAA,CAAAA;AAE3C,IAAA,IAAI,CAACmC,gBAAAA,IAAoBC,eAAc,KAAMpD,oBAAoBC,MAAS,CAAA,EAAA;QACxE,IAAIsD,WAAAA;QACJ,IAAI,CAACvC,IAAKC,CAAAA,QAAQ,EAAE;YAClBsC,WAAcpC,GAAAA,KAAAA,EAAAA;SACT,MAAA;YACLoC,WAAcpC,GAAAA,KAAAA,CAAMH,KAAKC,QAAQ,CAAA;AACnC;;QAEAsC,WAAW,CAACtD,OAAO,CAAC;AAAEuD,YAAAA,OAAAA,EAASL,mBAAmB,EAAK,GAAA;AAAI,SAAA,CAAA;;AAE3D,QAAA,IAAIC,eAAiB,EAAA;AACnBG,YAAAA,WAAAA,CAAYE,MAAM,EAAA;AACpB;QACA,MAAMxB,QAAAA,GAAWjB,KAAKkB,mBAAmB,GACrCC,UAAKnB,IAAKkB,CAAAA,mBAAmB,EAAE,CAAC,UAAU,EAAElB,KAAKgB,IAAI,CAAC,CAAC,CACvD,GAAA,CAAC,UAAU,EAAEhB,IAAAA,CAAKgB,IAAI,CAAC,CAAC;QAE5B,IAAII,OAAAA;QACJ,IAAI,CAACpB,IAAKC,CAAAA,QAAQ,EAAE;YAClBsC,WAAY1C,CAAAA,EAAE,CAAC,MAAA,EAAQ,CAAC0B,IAAAA,GAAAA;gBACtBH,OAAUG,GAAAA,IAAAA;AACZ,aAAA,CAAA;AAEA,YAAA,MAAMnC,kBAAkBY,IAAKO,CAAAA,SAAS,EAAGT,CAAAA,IAAI,CAACyC,WAActB,CAAAA,EAAAA,QAAAA,CAAAA;SACvD,MAAA;YACLG,OAAU,GAAA,MAAMmB,WAAYf,CAAAA,MAAM,CAACP,QAAAA,CAAAA;AACrC;AAEA,QAAA,MAAM,EAAER,KAAAA,EAAOiC,QAAQ,EAAEhC,MAAQiC,EAAAA,SAAS,EAAElB,IAAAA,EAAMmB,OAAO,EAAE,GAAGxB,OAAAA,IAAW,EAAC;AAE1E,QAAA,MAAMM,OAAU,GAAA;AAAE,YAAA,GAAG1B;AAAK,SAAA;AAE1B0B,QAAAA,OAAAA,CAAQnB,SAAS,GAAG,IAAMZ,EAAAA,CAAGkC,gBAAgB,CAACZ,QAAAA,CAAAA;AAC9CS,QAAAA,OAAAA,CAAQzB,QAAQ,GAAGgB,QAAAA;QAEnB,IAAI2B,OAAAA,IAAWnB,IAAQmB,IAAAA,OAAAA,GAAUnB,IAAM,EAAA;;YAErC,OAAOzB,IAAAA;AACT;QAEA,OAAO8B,MAAAA,CAAOC,MAAM,CAACL,OAAS,EAAA;YAC5BjB,KAAOiC,EAAAA,QAAAA;YACPhC,MAAQiC,EAAAA,SAAAA;YACRlB,IAAMmB,EAAAA,OAAAA,GAAUjE,cAAciE,OAAW,CAAA,GAAA,CAAA;YACzCZ,WAAaY,EAAAA;AACf,SAAA,CAAA;AACF;IAEA,OAAO5C,IAAAA;AACT,CAAA;AAEA,MAAM6C,mBAAsB,GAAA;IAC1BC,KAAO,EAAA,IAAA;IACPC,MAAQ,EAAA,GAAA;IACRC,KAAO,EAAA;AACT,CAAA;AAEA,MAAMC,iBAAiB,IACrBC,MAAAA,CAAOC,MAAM,CAACC,GAAG,CAAyB,4BAA8BP,EAAAA,mBAAAA,CAAAA;AAE1E,MAAMQ,4BAA4B,OAAOrD,IAAAA,GAAAA;IACvC,MAAM,EAAEsD,oBAAuB,GAAA,KAAK,EAAE,GAAG,MAAOjB,gBAAW,CAAA,QAAA,CAAA,CAAUC,WAAW,EAAA,IAAO,EAAC;IAExF,IAAI,CAACgB,oBAAsB,EAAA,OAAO,EAAE;IAEpC,MAAMC,kBAAAA,GAAqB,MAAM/C,aAAcR,CAAAA,IAAAA,CAAAA;AAE/C,IAAA,MAAMwD,WAAcP,GAAAA,cAAAA,EAAAA;IACpB,OAAO1D,OAAAA,CAAQkE,GAAG,CAChB3B,MAAAA,CAAO4B,IAAI,CAACF,WAAAA,CAAAA,CAAaG,GAAG,CAAC,CAACC,GAAAA,GAAAA;QAC5B,MAAMC,UAAAA,GAAaL,WAAW,CAACI,GAAI,CAAA;QAEnC,IAAIE,qBAAAA,CAAsBD,YAAYN,kBAAqB,CAAA,EAAA;AACzD,YAAA,OAAOQ,mBAAmBH,GAAK,EAAA;AAAE5D,gBAAAA,IAAAA;AAAM6D,gBAAAA;AAAW,aAAA,CAAA;AACpD;QAEA,OAAO3E,SAAAA;AACT,KAAA,CAAA,CAAA;AAEJ,CAAA;AAEA,MAAM6E,qBAAqB,OACzBH,GAAAA,EACA,EAAE5D,IAAI,EAAE6D,UAAU,EAAgD,GAAA;IAElE,MAAMnC,OAAAA,GAAU,MAAMb,YAAAA,CACpBb,IACA,EAAA;QACES,KAAOoD,EAAAA,UAAAA;QACPnD,MAAQmD,EAAAA,UAAAA;QACRjD,GAAK,EAAA;KAEP,EAAA;QACEG,IAAM,EAAA,CAAC,EAAE6C,GAAI,CAAA,CAAC,EAAE5D,IAAKe,CAAAA,IAAI,CAAC,CAAC;QAC3BC,IAAM,EAAA,CAAC,EAAE4C,GAAI,CAAA,CAAC,EAAE5D,IAAKgB,CAAAA,IAAI,CAAC;AAC5B,KAAA,CAAA;IAEF,OAAO;AACL4C,QAAAA,GAAAA;QACA5D,IAAM0B,EAAAA;AACR,KAAA;AACF,CAAA;AAEA,MAAMoC,wBAAwB,CAACD,UAAAA,EAAoB,EAAEpD,KAAK,EAAEC,MAAM,EAAc,GAAA;IAC9E,OAAOmD,UAAAA,IAAcpD,KAAS,IAAA,CAAA,KAAMoD,UAAcnD,IAAAA,UAAU,CAAA,CAAA;AAC9D,CAAA;AAEA;;IAGA,MAAMsD,gBAAgB,OAAOhE,IAAAA,GAAAA;IAC3B,IAAI,CAACA,IAAKC,CAAAA,QAAQ,EAAE;QAClB,OAAO,IAAIV,OAAQ,CAAA,CAACC,OAASC,EAAAA,MAAAA,GAAAA;AAC3B,YAAA,MAAMS,QAAWC,GAAAA,KAAAA,EAAAA;AACjBD,YAAAA,QAAAA,CAAS+D,KAAK,EAAG5D,CAAAA,IAAI,CAACb,OAAAA,CAAAA,CAASc,KAAK,CAACb,MAAAA,CAAAA;YACrCO,IAAKO,CAAAA,SAAS,EAAGT,CAAAA,IAAI,CAACI,QAAAA,CAAAA;AACxB,SAAA,CAAA;AACF;IAEA,IAAI;AACF,QAAA,MAAMC,KAAMH,CAAAA,IAAAA,CAAKC,QAAQ,CAAA,CAAEgE,KAAK,EAAA;QAChC,OAAO,KAAA;AACT,KAAA,CAAE,OAAOC,CAAG,EAAA;QACV,OAAO,IAAA;AACT;AACF,CAAA;AAEA,MAAMC,qBAAqB,OAAOnE,IAAAA,GAAAA;IAChC,IAAIf,MAAAA;IACJ,IAAI;QACF,MAAMmB,QAAAA,GAAW,MAAML,WAAYC,CAAAA,IAAAA,CAAAA;AACnCf,QAAAA,MAAAA,GAASmB,SAASnB,MAAM;AAC1B,KAAA,CAAE,OAAOiF,CAAG,EAAA;;QAEV,OAAO,KAAA;AACT;IACA,OAAOjF,MAAAA,IAAUF,mBAAoBI,CAAAA,QAAQ,CAACF,MAAAA,CAAAA;AAChD,CAAA;AAEA,MAAMmF,mBAAmB,OAAOpE,IAAAA,GAAAA;IAC9B,IAAIf,MAAAA;IACJ,IAAI;QACF,MAAMmB,QAAAA,GAAW,MAAML,WAAYC,CAAAA,IAAAA,CAAAA;AACnCf,QAAAA,MAAAA,GAASmB,SAASnB,MAAM;AAC1B,KAAA,CAAE,OAAOiF,CAAG,EAAA;;QAEV,OAAO,KAAA;AACT;IACA,OAAOjF,MAAAA,IAAUJ,iBAAkBM,CAAAA,QAAQ,CAACF,MAAAA,CAAAA;AAC9C,CAAA;AAEA,MAAMoF,UAAU,OAAOrE,IAAAA,GAAAA;IACrB,IAAIf,MAAAA;IACJ,IAAI;QACF,MAAMmB,QAAAA,GAAW,MAAML,WAAYC,CAAAA,IAAAA,CAAAA;AACnCf,QAAAA,MAAAA,GAASmB,SAASnB,MAAM;AAC1B,KAAA,CAAE,OAAOiF,CAAG,EAAA;;QAEV,OAAO,KAAA;AACT;IACA,OAAOjF,MAAAA,IAAUH,kBAAmBK,CAAAA,QAAQ,CAACF,MAAAA,CAAAA;AAC/C,CAAA;AAEA,MAAMqF,mBAAmB,CAACvD,IAAAA,GAAAA;AACxB,IAAA,MAAMwD,eAAe,IAAMC,MAAAA,CAAOC,WAAW,CAAC,CAAA,CAAA,CAAGC,QAAQ,CAAC,KAAA,CAAA;AAC1D,IAAA,MAAMC,QAAWC,GAAAA,aAAAA,CAAQC,UAAU,CAAC9D,IAAM,EAAA;QAAE+D,SAAW,EAAA,GAAA;QAAKC,SAAW,EAAA;AAAM,KAAA,CAAA;AAE7E,IAAA,OAAO,CAAC,EAAEJ,QAAAA,CAAS,CAAC,EAAEJ,eAAe,CAAC;AACxC,CAAA;AAEA,wBAAe;AACbP,IAAAA,aAAAA;AACAG,IAAAA,kBAAAA;AACAC,IAAAA,gBAAAA;AACAC,IAAAA,OAAAA;AACA7D,IAAAA,aAAAA;AACA6C,IAAAA,yBAAAA;AACApB,IAAAA,iBAAAA;AACAC,IAAAA,QAAAA;AACAoC,IAAAA;AACF,CAAE;;;;"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import sharp from 'sharp';
|
|
4
|
-
import
|
|
4
|
+
import crypto from 'crypto';
|
|
5
|
+
import { strings, file } from '@strapi/utils';
|
|
5
6
|
import { getService } from '../utils/index.mjs';
|
|
6
7
|
|
|
7
8
|
const { bytesToKbytes } = file;
|
|
@@ -238,6 +239,14 @@ const isImage = async (file)=>{
|
|
|
238
239
|
}
|
|
239
240
|
return format && FORMATS_TO_PROCESS.includes(format);
|
|
240
241
|
};
|
|
242
|
+
const generateFileName = (name)=>{
|
|
243
|
+
const randomSuffix = ()=>crypto.randomBytes(5).toString('hex');
|
|
244
|
+
const baseName = strings.nameToSlug(name, {
|
|
245
|
+
separator: '_',
|
|
246
|
+
lowercase: false
|
|
247
|
+
});
|
|
248
|
+
return `${baseName}_${randomSuffix()}`;
|
|
249
|
+
};
|
|
241
250
|
var imageManipulation = {
|
|
242
251
|
isFaultyImage,
|
|
243
252
|
isOptimizableImage,
|
|
@@ -246,7 +255,8 @@ var imageManipulation = {
|
|
|
246
255
|
getDimensions,
|
|
247
256
|
generateResponsiveFormats,
|
|
248
257
|
generateThumbnail,
|
|
249
|
-
optimize
|
|
258
|
+
optimize,
|
|
259
|
+
generateFileName
|
|
250
260
|
};
|
|
251
261
|
|
|
252
262
|
export { imageManipulation as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-manipulation.mjs","sources":["../../../server/src/services/image-manipulation.ts"],"sourcesContent":["import fs from 'fs';\nimport { join } from 'path';\nimport sharp from 'sharp';\nimport { file as fileUtils } from '@strapi/utils';\n\nimport { getService } from '../utils';\n\nimport type { UploadableFile } from '../types';\n\ntype Dimensions = {\n width: number | null;\n height: number | null;\n};\n\nconst { bytesToKbytes } = fileUtils;\n\nconst FORMATS_TO_RESIZE = ['jpeg', 'png', 'webp', 'tiff', 'gif'];\nconst FORMATS_TO_PROCESS = ['jpeg', 'png', 'webp', 'tiff', 'svg', 'gif', 'avif'];\nconst FORMATS_TO_OPTIMIZE = ['jpeg', 'png', 'webp', 'tiff', 'avif'];\n\nconst isOptimizableFormat = (\n format: string | undefined\n): format is 'jpeg' | 'png' | 'webp' | 'tiff' | 'avif' =>\n format !== undefined && FORMATS_TO_OPTIMIZE.includes(format);\n\nconst writeStreamToFile = (stream: NodeJS.ReadWriteStream, path: string) =>\n new Promise((resolve, reject) => {\n const writeStream = fs.createWriteStream(path);\n // Reject promise if there is an error with the provided stream\n stream.on('error', reject);\n stream.pipe(writeStream);\n writeStream.on('close', resolve);\n writeStream.on('error', reject);\n });\n\nconst getMetadata = (file: UploadableFile): Promise<sharp.Metadata> => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.metadata().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n return sharp(file.filepath).metadata();\n};\n\nconst getDimensions = async (file: UploadableFile): Promise<Dimensions> => {\n const { width = null, height = null } = await getMetadata(file);\n\n return { width, height };\n};\n\nconst THUMBNAIL_RESIZE_OPTIONS = {\n width: 245,\n height: 156,\n fit: 'inside',\n} satisfies sharp.ResizeOptions;\n\nconst resizeFileTo = async (\n file: UploadableFile,\n options: sharp.ResizeOptions,\n {\n name,\n hash,\n }: {\n name: string;\n hash: string;\n }\n) => {\n const filePath = file.tmpWorkingDirectory ? join(file.tmpWorkingDirectory, hash) : hash;\n\n let newInfo;\n if (!file.filepath) {\n const transform = sharp()\n .resize(options)\n .on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transform), filePath);\n } else {\n newInfo = await sharp(file.filepath).resize(options).toFile(filePath);\n }\n\n const { width, height, size } = newInfo ?? {};\n\n const newFile: UploadableFile = {\n name,\n hash,\n ext: file.ext,\n mime: file.mime,\n filepath: filePath,\n path: file.path || null,\n getStream: () => fs.createReadStream(filePath),\n };\n\n Object.assign(newFile, {\n width,\n height,\n size: size ? bytesToKbytes(size) : 0,\n sizeInBytes: size,\n });\n return newFile;\n};\n\nconst generateThumbnail = async (file: UploadableFile) => {\n if (\n file.width &&\n file.height &&\n (file.width > THUMBNAIL_RESIZE_OPTIONS.width || file.height > THUMBNAIL_RESIZE_OPTIONS.height)\n ) {\n return resizeFileTo(file, THUMBNAIL_RESIZE_OPTIONS, {\n name: `thumbnail_${file.name}`,\n hash: `thumbnail_${file.hash}`,\n });\n }\n\n return null;\n};\n\n/**\n * Optimize image by:\n * - auto orienting image based on EXIF data\n * - reduce image quality\n *\n */\nconst optimize = async (file: UploadableFile) => {\n const { sizeOptimization = false, autoOrientation = false } =\n (await getService('upload').getSettings()) ?? {};\n\n const { format, size } = await getMetadata(file);\n\n if ((sizeOptimization || autoOrientation) && isOptimizableFormat(format)) {\n let transformer;\n if (!file.filepath) {\n transformer = sharp();\n } else {\n transformer = sharp(file.filepath);\n }\n // reduce image quality\n transformer[format]({ quality: sizeOptimization ? 80 : 100 });\n // rotate image based on EXIF data\n if (autoOrientation) {\n transformer.rotate();\n }\n const filePath = file.tmpWorkingDirectory\n ? join(file.tmpWorkingDirectory, `optimized-${file.hash}`)\n : `optimized-${file.hash}`;\n\n let newInfo;\n if (!file.filepath) {\n transformer.on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transformer), filePath);\n } else {\n newInfo = await transformer.toFile(filePath);\n }\n\n const { width: newWidth, height: newHeight, size: newSize } = newInfo ?? {};\n\n const newFile = { ...file };\n\n newFile.getStream = () => fs.createReadStream(filePath);\n newFile.filepath = filePath;\n\n if (newSize && size && newSize > size) {\n // Ignore optimization if output is bigger than original\n return file;\n }\n\n return Object.assign(newFile, {\n width: newWidth,\n height: newHeight,\n size: newSize ? bytesToKbytes(newSize) : 0,\n sizeInBytes: newSize,\n });\n }\n\n return file;\n};\n\nconst DEFAULT_BREAKPOINTS = {\n large: 1000,\n medium: 750,\n small: 500,\n};\n\nconst getBreakpoints = () =>\n strapi.config.get<Record<string, number>>('plugin::upload.breakpoints', DEFAULT_BREAKPOINTS);\n\nconst generateResponsiveFormats = async (file: UploadableFile) => {\n const { responsiveDimensions = false } = (await getService('upload').getSettings()) ?? {};\n\n if (!responsiveDimensions) return [];\n\n const originalDimensions = await getDimensions(file);\n\n const breakpoints = getBreakpoints();\n return Promise.all(\n Object.keys(breakpoints).map((key) => {\n const breakpoint = breakpoints[key];\n\n if (breakpointSmallerThan(breakpoint, originalDimensions)) {\n return generateBreakpoint(key, { file, breakpoint });\n }\n\n return undefined;\n })\n );\n};\n\nconst generateBreakpoint = async (\n key: string,\n { file, breakpoint }: { file: UploadableFile; breakpoint: number }\n) => {\n const newFile = await resizeFileTo(\n file,\n {\n width: breakpoint,\n height: breakpoint,\n fit: 'inside',\n },\n {\n name: `${key}_${file.name}`,\n hash: `${key}_${file.hash}`,\n }\n );\n return {\n key,\n file: newFile,\n };\n};\n\nconst breakpointSmallerThan = (breakpoint: number, { width, height }: Dimensions) => {\n return breakpoint < (width ?? 0) || breakpoint < (height ?? 0);\n};\n\n/**\n * Applies a simple image transformation to see if the image is faulty/corrupted.\n */\nconst isFaultyImage = async (file: UploadableFile) => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.stats().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n try {\n await sharp(file.filepath).stats();\n return false;\n } catch (e) {\n return true;\n }\n};\n\nconst isOptimizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_OPTIMIZE.includes(format);\n};\n\nconst isResizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_RESIZE.includes(format);\n};\n\nconst isImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_PROCESS.includes(format);\n};\n\nexport default {\n isFaultyImage,\n isOptimizableImage,\n isResizableImage,\n isImage,\n getDimensions,\n generateResponsiveFormats,\n generateThumbnail,\n optimize,\n};\n"],"names":["bytesToKbytes","fileUtils","FORMATS_TO_RESIZE","FORMATS_TO_PROCESS","FORMATS_TO_OPTIMIZE","isOptimizableFormat","format","undefined","includes","writeStreamToFile","stream","path","Promise","resolve","reject","writeStream","fs","createWriteStream","on","pipe","getMetadata","file","filepath","pipeline","sharp","metadata","then","catch","getStream","getDimensions","width","height","THUMBNAIL_RESIZE_OPTIONS","fit","resizeFileTo","options","name","hash","filePath","tmpWorkingDirectory","join","newInfo","transform","resize","info","toFile","size","newFile","ext","mime","createReadStream","Object","assign","sizeInBytes","generateThumbnail","optimize","sizeOptimization","autoOrientation","getService","getSettings","transformer","quality","rotate","newWidth","newHeight","newSize","DEFAULT_BREAKPOINTS","large","medium","small","getBreakpoints","strapi","config","get","generateResponsiveFormats","responsiveDimensions","originalDimensions","breakpoints","all","keys","map","key","breakpoint","breakpointSmallerThan","generateBreakpoint","isFaultyImage","stats","e","isOptimizableImage","isResizableImage","isImage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"image-manipulation.mjs","sources":["../../../server/src/services/image-manipulation.ts"],"sourcesContent":["import fs from 'fs';\nimport { join } from 'path';\nimport sharp from 'sharp';\nimport crypto from 'crypto';\nimport { strings, file as fileUtils } from '@strapi/utils';\n\nimport { getService } from '../utils';\n\nimport type { UploadableFile } from '../types';\n\ntype Dimensions = {\n width: number | null;\n height: number | null;\n};\n\nconst { bytesToKbytes } = fileUtils;\n\nconst FORMATS_TO_RESIZE = ['jpeg', 'png', 'webp', 'tiff', 'gif'];\nconst FORMATS_TO_PROCESS = ['jpeg', 'png', 'webp', 'tiff', 'svg', 'gif', 'avif'];\nconst FORMATS_TO_OPTIMIZE = ['jpeg', 'png', 'webp', 'tiff', 'avif'];\n\nconst isOptimizableFormat = (\n format: string | undefined\n): format is 'jpeg' | 'png' | 'webp' | 'tiff' | 'avif' =>\n format !== undefined && FORMATS_TO_OPTIMIZE.includes(format);\n\nconst writeStreamToFile = (stream: NodeJS.ReadWriteStream, path: string) =>\n new Promise((resolve, reject) => {\n const writeStream = fs.createWriteStream(path);\n // Reject promise if there is an error with the provided stream\n stream.on('error', reject);\n stream.pipe(writeStream);\n writeStream.on('close', resolve);\n writeStream.on('error', reject);\n });\n\nconst getMetadata = (file: UploadableFile): Promise<sharp.Metadata> => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.metadata().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n return sharp(file.filepath).metadata();\n};\n\nconst getDimensions = async (file: UploadableFile): Promise<Dimensions> => {\n const { width = null, height = null } = await getMetadata(file);\n\n return { width, height };\n};\n\nconst THUMBNAIL_RESIZE_OPTIONS = {\n width: 245,\n height: 156,\n fit: 'inside',\n} satisfies sharp.ResizeOptions;\n\nconst resizeFileTo = async (\n file: UploadableFile,\n options: sharp.ResizeOptions,\n {\n name,\n hash,\n }: {\n name: string;\n hash: string;\n }\n) => {\n const filePath = file.tmpWorkingDirectory ? join(file.tmpWorkingDirectory, hash) : hash;\n\n let newInfo;\n if (!file.filepath) {\n const transform = sharp()\n .resize(options)\n .on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transform), filePath);\n } else {\n newInfo = await sharp(file.filepath).resize(options).toFile(filePath);\n }\n\n const { width, height, size } = newInfo ?? {};\n\n const newFile: UploadableFile = {\n name,\n hash,\n ext: file.ext,\n mime: file.mime,\n filepath: filePath,\n path: file.path || null,\n getStream: () => fs.createReadStream(filePath),\n };\n\n Object.assign(newFile, {\n width,\n height,\n size: size ? bytesToKbytes(size) : 0,\n sizeInBytes: size,\n });\n return newFile;\n};\n\nconst generateThumbnail = async (file: UploadableFile) => {\n if (\n file.width &&\n file.height &&\n (file.width > THUMBNAIL_RESIZE_OPTIONS.width || file.height > THUMBNAIL_RESIZE_OPTIONS.height)\n ) {\n return resizeFileTo(file, THUMBNAIL_RESIZE_OPTIONS, {\n name: `thumbnail_${file.name}`,\n hash: `thumbnail_${file.hash}`,\n });\n }\n\n return null;\n};\n\n/**\n * Optimize image by:\n * - auto orienting image based on EXIF data\n * - reduce image quality\n *\n */\nconst optimize = async (file: UploadableFile) => {\n const { sizeOptimization = false, autoOrientation = false } =\n (await getService('upload').getSettings()) ?? {};\n\n const { format, size } = await getMetadata(file);\n\n if ((sizeOptimization || autoOrientation) && isOptimizableFormat(format)) {\n let transformer;\n if (!file.filepath) {\n transformer = sharp();\n } else {\n transformer = sharp(file.filepath);\n }\n // reduce image quality\n transformer[format]({ quality: sizeOptimization ? 80 : 100 });\n // rotate image based on EXIF data\n if (autoOrientation) {\n transformer.rotate();\n }\n const filePath = file.tmpWorkingDirectory\n ? join(file.tmpWorkingDirectory, `optimized-${file.hash}`)\n : `optimized-${file.hash}`;\n\n let newInfo;\n if (!file.filepath) {\n transformer.on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transformer), filePath);\n } else {\n newInfo = await transformer.toFile(filePath);\n }\n\n const { width: newWidth, height: newHeight, size: newSize } = newInfo ?? {};\n\n const newFile = { ...file };\n\n newFile.getStream = () => fs.createReadStream(filePath);\n newFile.filepath = filePath;\n\n if (newSize && size && newSize > size) {\n // Ignore optimization if output is bigger than original\n return file;\n }\n\n return Object.assign(newFile, {\n width: newWidth,\n height: newHeight,\n size: newSize ? bytesToKbytes(newSize) : 0,\n sizeInBytes: newSize,\n });\n }\n\n return file;\n};\n\nconst DEFAULT_BREAKPOINTS = {\n large: 1000,\n medium: 750,\n small: 500,\n};\n\nconst getBreakpoints = () =>\n strapi.config.get<Record<string, number>>('plugin::upload.breakpoints', DEFAULT_BREAKPOINTS);\n\nconst generateResponsiveFormats = async (file: UploadableFile) => {\n const { responsiveDimensions = false } = (await getService('upload').getSettings()) ?? {};\n\n if (!responsiveDimensions) return [];\n\n const originalDimensions = await getDimensions(file);\n\n const breakpoints = getBreakpoints();\n return Promise.all(\n Object.keys(breakpoints).map((key) => {\n const breakpoint = breakpoints[key];\n\n if (breakpointSmallerThan(breakpoint, originalDimensions)) {\n return generateBreakpoint(key, { file, breakpoint });\n }\n\n return undefined;\n })\n );\n};\n\nconst generateBreakpoint = async (\n key: string,\n { file, breakpoint }: { file: UploadableFile; breakpoint: number }\n) => {\n const newFile = await resizeFileTo(\n file,\n {\n width: breakpoint,\n height: breakpoint,\n fit: 'inside',\n },\n {\n name: `${key}_${file.name}`,\n hash: `${key}_${file.hash}`,\n }\n );\n return {\n key,\n file: newFile,\n };\n};\n\nconst breakpointSmallerThan = (breakpoint: number, { width, height }: Dimensions) => {\n return breakpoint < (width ?? 0) || breakpoint < (height ?? 0);\n};\n\n/**\n * Applies a simple image transformation to see if the image is faulty/corrupted.\n */\nconst isFaultyImage = async (file: UploadableFile) => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.stats().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n try {\n await sharp(file.filepath).stats();\n return false;\n } catch (e) {\n return true;\n }\n};\n\nconst isOptimizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_OPTIMIZE.includes(format);\n};\n\nconst isResizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_RESIZE.includes(format);\n};\n\nconst isImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_PROCESS.includes(format);\n};\n\nconst generateFileName = (name: string) => {\n const randomSuffix = () => crypto.randomBytes(5).toString('hex');\n const baseName = strings.nameToSlug(name, { separator: '_', lowercase: false });\n\n return `${baseName}_${randomSuffix()}`;\n};\n\nexport default {\n isFaultyImage,\n isOptimizableImage,\n isResizableImage,\n isImage,\n getDimensions,\n generateResponsiveFormats,\n generateThumbnail,\n optimize,\n generateFileName,\n};\n"],"names":["bytesToKbytes","fileUtils","FORMATS_TO_RESIZE","FORMATS_TO_PROCESS","FORMATS_TO_OPTIMIZE","isOptimizableFormat","format","undefined","includes","writeStreamToFile","stream","path","Promise","resolve","reject","writeStream","fs","createWriteStream","on","pipe","getMetadata","file","filepath","pipeline","sharp","metadata","then","catch","getStream","getDimensions","width","height","THUMBNAIL_RESIZE_OPTIONS","fit","resizeFileTo","options","name","hash","filePath","tmpWorkingDirectory","join","newInfo","transform","resize","info","toFile","size","newFile","ext","mime","createReadStream","Object","assign","sizeInBytes","generateThumbnail","optimize","sizeOptimization","autoOrientation","getService","getSettings","transformer","quality","rotate","newWidth","newHeight","newSize","DEFAULT_BREAKPOINTS","large","medium","small","getBreakpoints","strapi","config","get","generateResponsiveFormats","responsiveDimensions","originalDimensions","breakpoints","all","keys","map","key","breakpoint","breakpointSmallerThan","generateBreakpoint","isFaultyImage","stats","e","isOptimizableImage","isResizableImage","isImage","generateFileName","randomSuffix","crypto","randomBytes","toString","baseName","strings","nameToSlug","separator","lowercase"],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var os = require('os');
|
|
4
4
|
var path = require('path');
|
|
5
|
-
var crypto = require('crypto');
|
|
6
5
|
var fs = require('fs');
|
|
7
6
|
var fse = require('fs-extra');
|
|
8
7
|
var _ = require('lodash');
|
|
@@ -16,14 +15,6 @@ const { MEDIA_CREATE, MEDIA_UPDATE, MEDIA_DELETE } = constants.ALLOWED_WEBHOOK_E
|
|
|
16
15
|
const { ApplicationError, NotFoundError } = utils.errors;
|
|
17
16
|
const { bytesToKbytes } = utils.file;
|
|
18
17
|
var upload = (({ strapi })=>{
|
|
19
|
-
const randomSuffix = ()=>crypto.randomBytes(5).toString('hex');
|
|
20
|
-
const generateFileName = (name)=>{
|
|
21
|
-
const baseName = utils.strings.nameToSlug(name, {
|
|
22
|
-
separator: '_',
|
|
23
|
-
lowercase: false
|
|
24
|
-
});
|
|
25
|
-
return `${baseName}_${randomSuffix()}`;
|
|
26
|
-
};
|
|
27
18
|
const sendMediaMetrics = (data)=>{
|
|
28
19
|
if (_.has(data, 'caption') && !_.isEmpty(data.caption)) {
|
|
29
20
|
strapi.telemetry.send('didSaveMediaWithCaption');
|
|
@@ -78,6 +69,7 @@ var upload = (({ strapi })=>{
|
|
|
78
69
|
}
|
|
79
70
|
async function formatFileInfo({ filename, type, size }, fileInfo = {}, metas = {}) {
|
|
80
71
|
const fileService = index.getService('file');
|
|
72
|
+
const imageManipulationService = index.getService('image-manipulation');
|
|
81
73
|
if (!isValidFilename(filename)) {
|
|
82
74
|
throw new ApplicationError('File name contains invalid characters');
|
|
83
75
|
}
|
|
@@ -97,7 +89,7 @@ var upload = (({ strapi })=>{
|
|
|
97
89
|
caption: fileInfo.caption,
|
|
98
90
|
folder: fileInfo.folder,
|
|
99
91
|
folderPath: await fileService.getFolderPath(fileInfo.folder),
|
|
100
|
-
hash: generateFileName(basename),
|
|
92
|
+
hash: imageManipulationService.generateFileName(basename),
|
|
101
93
|
ext,
|
|
102
94
|
mime: type,
|
|
103
95
|
size: bytesToKbytes(size),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sources":["../../../server/src/services/upload.ts"],"sourcesContent":["import os from 'os';\nimport path from 'path';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport fse from 'fs-extra';\nimport _ from 'lodash';\nimport { extension } from 'mime-types';\nimport {\n sanitize,\n strings,\n contentTypes as contentTypesUtils,\n errors,\n file as fileUtils,\n} from '@strapi/utils';\n\nimport type { Core, UID } from '@strapi/types';\n\nimport { FILE_MODEL_UID, ALLOWED_WEBHOOK_EVENTS } from '../constants';\nimport { getService } from '../utils';\n\nimport type { Config, File, InputFile, UploadableFile, FileInfo } from '../types';\nimport type { ViewConfiguration } from '../controllers/validation/admin/configureView';\nimport type { Settings } from '../controllers/validation/admin/settings';\n\ntype User = {\n id: string | number;\n};\n\ntype ID = string | number;\n\ntype CommonOptions = {\n user?: User;\n};\n\ntype Metas = {\n refId?: ID;\n ref?: string;\n field?: string;\n path?: string;\n tmpWorkingDirectory?: string;\n};\n\nconst { UPDATED_BY_ATTRIBUTE, CREATED_BY_ATTRIBUTE } = contentTypesUtils.constants;\nconst { MEDIA_CREATE, MEDIA_UPDATE, MEDIA_DELETE } = ALLOWED_WEBHOOK_EVENTS;\n\nconst { ApplicationError, NotFoundError } = errors;\nconst { bytesToKbytes } = fileUtils;\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => {\n const randomSuffix = () => crypto.randomBytes(5).toString('hex');\n\n const generateFileName = (name: string) => {\n const baseName = strings.nameToSlug(name, { separator: '_', lowercase: false });\n\n return `${baseName}_${randomSuffix()}`;\n };\n\n const sendMediaMetrics = (data: Pick<File, 'caption' | 'alternativeText'>) => {\n if (_.has(data, 'caption') && !_.isEmpty(data.caption)) {\n strapi.telemetry.send('didSaveMediaWithCaption');\n }\n\n if (_.has(data, 'alternativeText') && !_.isEmpty(data.alternativeText)) {\n strapi.telemetry.send('didSaveMediaWithAlternativeText');\n }\n };\n\n const createAndAssignTmpWorkingDirectoryToFiles = async (\n files: InputFile | InputFile[]\n ): Promise<string> => {\n const tmpWorkingDirectory = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-upload-'));\n\n if (Array.isArray(files)) {\n files.forEach((file) => {\n file.tmpWorkingDirectory = tmpWorkingDirectory;\n });\n } else {\n files.tmpWorkingDirectory = tmpWorkingDirectory;\n }\n\n return tmpWorkingDirectory;\n };\n\n function filenameReservedRegex() {\n // eslint-disable-next-line no-control-regex\n return /[<>:\"/\\\\|?*\\u0000-\\u001F]/g;\n }\n\n function windowsReservedNameRegex() {\n return /^(con|prn|aux|nul|com\\d|lpt\\d)$/i;\n }\n\n /**\n * Copied from https://github.com/sindresorhus/valid-filename package\n */\n function isValidFilename(string: string) {\n if (!string || string.length > 255) {\n return false;\n }\n if (filenameReservedRegex().test(string) || windowsReservedNameRegex().test(string)) {\n return false;\n }\n if (string === '.' || string === '..') {\n return false;\n }\n return true;\n }\n\n async function emitEvent(event: string, data: Record<string, any>) {\n const modelDef = strapi.getModel(FILE_MODEL_UID);\n const sanitizedData = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: modelDef,\n getModel(uid: string) {\n return strapi.getModel(uid as UID.Schema);\n },\n },\n data\n );\n\n strapi.eventHub.emit(event, { media: sanitizedData });\n }\n\n async function formatFileInfo(\n { filename, type, size }: { filename: string; type: string; size: number },\n fileInfo: Partial<FileInfo> = {},\n metas: {\n refId?: ID;\n ref?: string;\n field?: string;\n path?: string;\n tmpWorkingDirectory?: string;\n } = {}\n ): Promise<Omit<UploadableFile, 'getStream'>> {\n const fileService = getService('file');\n\n if (!isValidFilename(filename)) {\n throw new ApplicationError('File name contains invalid characters');\n }\n\n let ext = path.extname(filename);\n if (!ext) {\n ext = `.${extension(type)}`;\n }\n const usedName = (fileInfo.name || filename).normalize();\n const basename = path.basename(usedName, ext);\n\n // Prevent null characters in file name\n if (!isValidFilename(filename)) {\n throw new ApplicationError('File name contains invalid characters');\n }\n\n const entity: Omit<UploadableFile, 'getStream'> = {\n name: usedName,\n alternativeText: fileInfo.alternativeText,\n caption: fileInfo.caption,\n folder: fileInfo.folder,\n folderPath: await fileService.getFolderPath(fileInfo.folder),\n hash: generateFileName(basename),\n ext,\n mime: type,\n size: bytesToKbytes(size),\n sizeInBytes: size,\n };\n\n const { refId, ref, field } = metas;\n\n if (refId && ref && field) {\n entity.related = [\n {\n id: refId,\n __type: ref,\n __pivot: { field },\n },\n ];\n }\n\n if (metas.path) {\n entity.path = metas.path;\n }\n\n if (metas.tmpWorkingDirectory) {\n entity.tmpWorkingDirectory = metas.tmpWorkingDirectory;\n }\n\n return entity;\n }\n\n async function enhanceAndValidateFile(\n file: InputFile,\n fileInfo: FileInfo,\n metas?: Metas\n ): Promise<UploadableFile> {\n const currentFile = (await formatFileInfo(\n {\n filename: file.originalFilename ?? 'unamed',\n type: file.mimetype ?? 'application/octet-stream',\n size: file.size,\n },\n fileInfo,\n {\n ...metas,\n tmpWorkingDirectory: file.tmpWorkingDirectory,\n }\n )) as UploadableFile;\n\n currentFile.filepath = file.filepath;\n currentFile.getStream = () => fs.createReadStream(file.filepath);\n\n const { optimize, isImage, isFaultyImage, isOptimizableImage } = strapi\n .plugin('upload')\n .service('image-manipulation');\n\n if (await isImage(currentFile)) {\n if (await isFaultyImage(currentFile)) {\n throw new ApplicationError('File is not a valid image');\n }\n if (await isOptimizableImage(currentFile)) {\n return optimize(currentFile);\n }\n }\n\n return currentFile;\n }\n\n async function upload(\n {\n data,\n files,\n }: {\n data: Record<string, unknown>;\n files: InputFile | InputFile[];\n },\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n // create temporary folder to store files for stream manipulation\n const tmpWorkingDirectory = await createAndAssignTmpWorkingDirectoryToFiles(files);\n\n let uploadedFiles: any[] = [];\n\n try {\n const { fileInfo, ...metas } = data;\n\n const fileArray = Array.isArray(files) ? files : [files];\n const fileInfoArray = Array.isArray(fileInfo) ? fileInfo : [fileInfo];\n\n const doUpload = async (file: InputFile, fileInfo: FileInfo) => {\n const fileData = await enhanceAndValidateFile(file, fileInfo, metas);\n return uploadFileAndPersist(fileData, { user });\n };\n\n uploadedFiles = await Promise.all(\n fileArray.map((file, idx) => doUpload(file, fileInfoArray[idx] || {}))\n );\n } finally {\n // delete temporary folder\n await fse.remove(tmpWorkingDirectory);\n }\n\n return uploadedFiles;\n }\n\n /**\n * When uploading an image, an additional thumbnail is generated.\n * Also, if there are responsive formats defined, another set of images will be generated too.\n *\n * @param {*} fileData\n */\n async function uploadImage(fileData: UploadableFile) {\n const { getDimensions, generateThumbnail, generateResponsiveFormats, isResizableImage } =\n getService('image-manipulation');\n\n // Store width and height of the original image\n const { width, height } = await getDimensions(fileData);\n\n // Make sure this is assigned before calling any upload\n // That way it can mutate the width and height\n _.assign(fileData, {\n width,\n height,\n });\n\n // For performance reasons, all uploads are wrapped in a single Promise.all\n const uploadThumbnail = async (thumbnailFile: UploadableFile) => {\n await getService('provider').upload(thumbnailFile);\n _.set(fileData, 'formats.thumbnail', thumbnailFile);\n };\n\n // Generate thumbnail and responsive formats\n const uploadResponsiveFormat = async (format: { key: string; file: UploadableFile }) => {\n const { key, file } = format;\n await getService('provider').upload(file);\n _.set(fileData, ['formats', key], file);\n };\n\n const uploadPromises: Promise<void>[] = [];\n\n // Upload image\n uploadPromises.push(getService('provider').upload(fileData));\n\n // Generate & Upload thumbnail and responsive formats\n if (await isResizableImage(fileData)) {\n const thumbnailFile = await generateThumbnail(fileData);\n if (thumbnailFile) {\n uploadPromises.push(uploadThumbnail(thumbnailFile));\n }\n\n const formats = await generateResponsiveFormats(fileData);\n if (Array.isArray(formats) && formats.length > 0) {\n for (const format of formats) {\n // eslint-disable-next-line no-continue\n if (!format) continue;\n uploadPromises.push(uploadResponsiveFormat(format));\n }\n }\n }\n // Wait for all uploads to finish\n await Promise.all(uploadPromises);\n }\n\n /**\n * Upload a file. If it is an image it will generate a thumbnail\n * and responsive formats (if enabled).\n */\n async function uploadFileAndPersist(fileData: UploadableFile, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const config = strapi.config.get<Config>('plugin::upload');\n const { isImage } = getService('image-manipulation');\n\n await getService('provider').checkFileSize(fileData);\n\n if (await isImage(fileData)) {\n await uploadImage(fileData);\n } else {\n await getService('provider').upload(fileData);\n }\n\n _.set(fileData, 'provider', config.provider);\n\n // Persist file(s)\n return add(fileData, { user });\n }\n\n async function updateFileInfo(\n id: ID,\n { name, alternativeText, caption, folder }: FileInfo,\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n\n const dbFile = await findOne(id);\n\n if (!dbFile) {\n throw new NotFoundError();\n }\n\n const fileService = getService('file');\n\n const newName = _.isNil(name) ? dbFile.name : name;\n const newInfos = {\n name: newName,\n alternativeText: _.isNil(alternativeText) ? dbFile.alternativeText : alternativeText,\n caption: _.isNil(caption) ? dbFile.caption : caption,\n folder: _.isUndefined(folder) ? dbFile.folder : folder,\n folderPath: _.isUndefined(folder) ? dbFile.path : await fileService.getFolderPath(folder),\n };\n\n return update(id, newInfos, { user });\n }\n\n async function replace(\n id: ID,\n { data, file }: { data: { fileInfo: FileInfo }; file: InputFile },\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n\n const config = strapi.config.get<Config>('plugin::upload');\n\n const { isImage } = getService('image-manipulation');\n\n const dbFile = await findOne(id);\n if (!dbFile) {\n throw new NotFoundError();\n }\n\n // create temporary folder to store files for stream manipulation\n const tmpWorkingDirectory = await createAndAssignTmpWorkingDirectoryToFiles(file);\n\n let fileData: UploadableFile;\n\n try {\n const { fileInfo } = data;\n fileData = await enhanceAndValidateFile(file, fileInfo);\n\n // keep a constant hash and extension so the file url doesn't change when the file is replaced\n _.assign(fileData, {\n hash: dbFile.hash,\n ext: dbFile.ext,\n });\n\n // execute delete function of the provider\n if (dbFile.provider === config.provider) {\n await strapi.plugin('upload').provider.delete(dbFile);\n\n if (dbFile.formats) {\n await Promise.all(\n Object.keys(dbFile.formats).map((key) => {\n return strapi.plugin('upload').provider.delete(dbFile.formats[key]);\n })\n );\n }\n }\n\n // clear old formats\n _.set(fileData, 'formats', {});\n\n if (await isImage(fileData)) {\n await uploadImage(fileData);\n } else {\n await getService('provider').upload(fileData);\n }\n\n _.set(fileData, 'provider', config.provider);\n } finally {\n // delete temporary folder\n await fse.remove(tmpWorkingDirectory);\n }\n\n return update(id, fileData, { user });\n }\n\n async function update(id: ID, values: Partial<File>, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const fileValues = { ...values };\n if (user) {\n Object.assign(fileValues, {\n [UPDATED_BY_ATTRIBUTE]: user.id,\n });\n }\n\n sendMediaMetrics(fileValues);\n\n const res = await strapi.db.query(FILE_MODEL_UID).update({ where: { id }, data: fileValues });\n\n await emitEvent(MEDIA_UPDATE, res);\n\n return res;\n }\n\n async function add(values: any, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const fileValues = { ...values };\n if (user) {\n Object.assign(fileValues, {\n [UPDATED_BY_ATTRIBUTE]: user.id,\n [CREATED_BY_ATTRIBUTE]: user.id,\n });\n }\n\n sendMediaMetrics(fileValues);\n\n const res = await strapi.db.query(FILE_MODEL_UID).create({ data: fileValues });\n\n await emitEvent(MEDIA_CREATE, res);\n\n return res;\n }\n\n function findOne(id: ID, populate = {}) {\n const query = strapi.get('query-params').transform(FILE_MODEL_UID, {\n populate,\n });\n\n return strapi.db.query(FILE_MODEL_UID).findOne({\n where: { id },\n ...query,\n });\n }\n\n function findMany(query: any = {}): Promise<File[]> {\n return strapi.db\n .query(FILE_MODEL_UID)\n .findMany(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n }\n\n function findPage(query: any = {}) {\n return strapi.db\n .query(FILE_MODEL_UID)\n .findPage(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n }\n\n async function remove(file: File) {\n const config = strapi.config.get<Config>('plugin::upload');\n\n // execute delete function of the provider\n if (file.provider === config.provider) {\n await strapi.plugin('upload').provider.delete(file);\n\n if (file.formats) {\n const keys = Object.keys(file.formats);\n\n await Promise.all(\n keys.map((key) => {\n return strapi.plugin('upload').provider.delete(file.formats![key]);\n })\n );\n }\n }\n\n const media = await strapi.db.query(FILE_MODEL_UID).findOne({\n where: { id: file.id },\n });\n\n await emitEvent(MEDIA_DELETE, media);\n\n return strapi.db.query(FILE_MODEL_UID).delete({ where: { id: file.id } });\n }\n\n async function getSettings() {\n const res = await strapi.store!({ type: 'plugin', name: 'upload', key: 'settings' }).get({});\n\n return res as Settings | null;\n }\n\n function setSettings(value: Settings) {\n if (value.responsiveDimensions === true) {\n strapi.telemetry.send('didEnableResponsiveDimensions');\n } else {\n strapi.telemetry.send('didDisableResponsiveDimensions');\n }\n\n return strapi.store!({ type: 'plugin', name: 'upload', key: 'settings' }).set({ value });\n }\n\n async function getConfiguration() {\n const res = await strapi.store!({\n type: 'plugin',\n name: 'upload',\n key: 'view_configuration',\n }).get({});\n\n return res as ViewConfiguration | null;\n }\n\n function setConfiguration(value: ViewConfiguration) {\n return strapi.store!({ type: 'plugin', name: 'upload', key: 'view_configuration' }).set({\n value,\n });\n }\n\n return {\n formatFileInfo,\n upload,\n updateFileInfo,\n replace,\n findOne,\n findMany,\n findPage,\n remove,\n getSettings,\n setSettings,\n getConfiguration,\n setConfiguration,\n\n /**\n * exposed for testing only\n * @internal\n */\n _uploadImage: uploadImage,\n };\n};\n"],"names":["UPDATED_BY_ATTRIBUTE","CREATED_BY_ATTRIBUTE","contentTypesUtils","constants","MEDIA_CREATE","MEDIA_UPDATE","MEDIA_DELETE","ALLOWED_WEBHOOK_EVENTS","ApplicationError","NotFoundError","errors","bytesToKbytes","fileUtils","strapi","randomSuffix","crypto","randomBytes","toString","generateFileName","name","baseName","strings","nameToSlug","separator","lowercase","sendMediaMetrics","data","_","has","isEmpty","caption","telemetry","send","alternativeText","createAndAssignTmpWorkingDirectoryToFiles","files","tmpWorkingDirectory","fse","mkdtemp","path","join","os","tmpdir","Array","isArray","forEach","file","filenameReservedRegex","windowsReservedNameRegex","isValidFilename","string","length","test","emitEvent","event","modelDef","getModel","FILE_MODEL_UID","sanitizedData","sanitize","sanitizers","defaultSanitizeOutput","schema","uid","eventHub","emit","media","formatFileInfo","filename","type","size","fileInfo","metas","fileService","getService","ext","extname","extension","usedName","normalize","basename","entity","folder","folderPath","getFolderPath","hash","mime","sizeInBytes","refId","ref","field","related","id","__type","__pivot","enhanceAndValidateFile","currentFile","originalFilename","mimetype","filepath","getStream","fs","createReadStream","optimize","isImage","isFaultyImage","isOptimizableImage","plugin","service","upload","opts","user","uploadedFiles","fileArray","fileInfoArray","doUpload","fileData","uploadFileAndPersist","Promise","all","map","idx","remove","uploadImage","getDimensions","generateThumbnail","generateResponsiveFormats","isResizableImage","width","height","assign","uploadThumbnail","thumbnailFile","set","uploadResponsiveFormat","format","key","uploadPromises","push","formats","config","get","checkFileSize","provider","add","updateFileInfo","dbFile","findOne","newName","isNil","newInfos","isUndefined","update","replace","delete","Object","keys","values","fileValues","res","db","query","where","create","populate","transform","findMany","findPage","getSettings","store","setSettings","value","responsiveDimensions","getConfiguration","setConfiguration","_uploadImage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"upload.js","sources":["../../../server/src/services/upload.ts"],"sourcesContent":["import os from 'os';\nimport path from 'path';\nimport fs from 'fs';\nimport fse from 'fs-extra';\nimport _ from 'lodash';\nimport { extension } from 'mime-types';\nimport {\n sanitize,\n contentTypes as contentTypesUtils,\n errors,\n file as fileUtils,\n} from '@strapi/utils';\n\nimport type { Core, UID } from '@strapi/types';\n\nimport { FILE_MODEL_UID, ALLOWED_WEBHOOK_EVENTS } from '../constants';\nimport { getService } from '../utils';\n\nimport type { Config, File, InputFile, UploadableFile, FileInfo } from '../types';\nimport type { ViewConfiguration } from '../controllers/validation/admin/configureView';\nimport type { Settings } from '../controllers/validation/admin/settings';\n\ntype User = {\n id: string | number;\n};\n\ntype ID = string | number;\n\ntype CommonOptions = {\n user?: User;\n};\n\ntype Metas = {\n refId?: ID;\n ref?: string;\n field?: string;\n path?: string;\n tmpWorkingDirectory?: string;\n};\n\nconst { UPDATED_BY_ATTRIBUTE, CREATED_BY_ATTRIBUTE } = contentTypesUtils.constants;\nconst { MEDIA_CREATE, MEDIA_UPDATE, MEDIA_DELETE } = ALLOWED_WEBHOOK_EVENTS;\n\nconst { ApplicationError, NotFoundError } = errors;\nconst { bytesToKbytes } = fileUtils;\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => {\n const sendMediaMetrics = (data: Pick<File, 'caption' | 'alternativeText'>) => {\n if (_.has(data, 'caption') && !_.isEmpty(data.caption)) {\n strapi.telemetry.send('didSaveMediaWithCaption');\n }\n\n if (_.has(data, 'alternativeText') && !_.isEmpty(data.alternativeText)) {\n strapi.telemetry.send('didSaveMediaWithAlternativeText');\n }\n };\n\n const createAndAssignTmpWorkingDirectoryToFiles = async (\n files: InputFile | InputFile[]\n ): Promise<string> => {\n const tmpWorkingDirectory = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-upload-'));\n\n if (Array.isArray(files)) {\n files.forEach((file) => {\n file.tmpWorkingDirectory = tmpWorkingDirectory;\n });\n } else {\n files.tmpWorkingDirectory = tmpWorkingDirectory;\n }\n\n return tmpWorkingDirectory;\n };\n\n function filenameReservedRegex() {\n // eslint-disable-next-line no-control-regex\n return /[<>:\"/\\\\|?*\\u0000-\\u001F]/g;\n }\n\n function windowsReservedNameRegex() {\n return /^(con|prn|aux|nul|com\\d|lpt\\d)$/i;\n }\n\n /**\n * Copied from https://github.com/sindresorhus/valid-filename package\n */\n function isValidFilename(string: string) {\n if (!string || string.length > 255) {\n return false;\n }\n if (filenameReservedRegex().test(string) || windowsReservedNameRegex().test(string)) {\n return false;\n }\n if (string === '.' || string === '..') {\n return false;\n }\n return true;\n }\n\n async function emitEvent(event: string, data: Record<string, any>) {\n const modelDef = strapi.getModel(FILE_MODEL_UID);\n const sanitizedData = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: modelDef,\n getModel(uid: string) {\n return strapi.getModel(uid as UID.Schema);\n },\n },\n data\n );\n\n strapi.eventHub.emit(event, { media: sanitizedData });\n }\n\n async function formatFileInfo(\n { filename, type, size }: { filename: string; type: string; size: number },\n fileInfo: Partial<FileInfo> = {},\n metas: {\n refId?: ID;\n ref?: string;\n field?: string;\n path?: string;\n tmpWorkingDirectory?: string;\n } = {}\n ): Promise<Omit<UploadableFile, 'getStream'>> {\n const fileService = getService('file');\n const imageManipulationService = getService('image-manipulation');\n\n if (!isValidFilename(filename)) {\n throw new ApplicationError('File name contains invalid characters');\n }\n\n let ext = path.extname(filename);\n if (!ext) {\n ext = `.${extension(type)}`;\n }\n const usedName = (fileInfo.name || filename).normalize();\n const basename = path.basename(usedName, ext);\n\n // Prevent null characters in file name\n if (!isValidFilename(filename)) {\n throw new ApplicationError('File name contains invalid characters');\n }\n\n const entity: Omit<UploadableFile, 'getStream'> = {\n name: usedName,\n alternativeText: fileInfo.alternativeText,\n caption: fileInfo.caption,\n folder: fileInfo.folder,\n folderPath: await fileService.getFolderPath(fileInfo.folder),\n hash: imageManipulationService.generateFileName(basename),\n ext,\n mime: type,\n size: bytesToKbytes(size),\n sizeInBytes: size,\n };\n\n const { refId, ref, field } = metas;\n\n if (refId && ref && field) {\n entity.related = [\n {\n id: refId,\n __type: ref,\n __pivot: { field },\n },\n ];\n }\n\n if (metas.path) {\n entity.path = metas.path;\n }\n\n if (metas.tmpWorkingDirectory) {\n entity.tmpWorkingDirectory = metas.tmpWorkingDirectory;\n }\n\n return entity;\n }\n\n async function enhanceAndValidateFile(\n file: InputFile,\n fileInfo: FileInfo,\n metas?: Metas\n ): Promise<UploadableFile> {\n const currentFile = (await formatFileInfo(\n {\n filename: file.originalFilename ?? 'unamed',\n type: file.mimetype ?? 'application/octet-stream',\n size: file.size,\n },\n fileInfo,\n {\n ...metas,\n tmpWorkingDirectory: file.tmpWorkingDirectory,\n }\n )) as UploadableFile;\n\n currentFile.filepath = file.filepath;\n currentFile.getStream = () => fs.createReadStream(file.filepath);\n\n const { optimize, isImage, isFaultyImage, isOptimizableImage } = strapi\n .plugin('upload')\n .service('image-manipulation');\n\n if (await isImage(currentFile)) {\n if (await isFaultyImage(currentFile)) {\n throw new ApplicationError('File is not a valid image');\n }\n if (await isOptimizableImage(currentFile)) {\n return optimize(currentFile);\n }\n }\n\n return currentFile;\n }\n\n async function upload(\n {\n data,\n files,\n }: {\n data: Record<string, unknown>;\n files: InputFile | InputFile[];\n },\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n // create temporary folder to store files for stream manipulation\n const tmpWorkingDirectory = await createAndAssignTmpWorkingDirectoryToFiles(files);\n\n let uploadedFiles: any[] = [];\n\n try {\n const { fileInfo, ...metas } = data;\n\n const fileArray = Array.isArray(files) ? files : [files];\n const fileInfoArray = Array.isArray(fileInfo) ? fileInfo : [fileInfo];\n\n const doUpload = async (file: InputFile, fileInfo: FileInfo) => {\n const fileData = await enhanceAndValidateFile(file, fileInfo, metas);\n return uploadFileAndPersist(fileData, { user });\n };\n\n uploadedFiles = await Promise.all(\n fileArray.map((file, idx) => doUpload(file, fileInfoArray[idx] || {}))\n );\n } finally {\n // delete temporary folder\n await fse.remove(tmpWorkingDirectory);\n }\n\n return uploadedFiles;\n }\n\n /**\n * When uploading an image, an additional thumbnail is generated.\n * Also, if there are responsive formats defined, another set of images will be generated too.\n *\n * @param {*} fileData\n */\n async function uploadImage(fileData: UploadableFile) {\n const { getDimensions, generateThumbnail, generateResponsiveFormats, isResizableImage } =\n getService('image-manipulation');\n\n // Store width and height of the original image\n const { width, height } = await getDimensions(fileData);\n\n // Make sure this is assigned before calling any upload\n // That way it can mutate the width and height\n _.assign(fileData, {\n width,\n height,\n });\n\n // For performance reasons, all uploads are wrapped in a single Promise.all\n const uploadThumbnail = async (thumbnailFile: UploadableFile) => {\n await getService('provider').upload(thumbnailFile);\n _.set(fileData, 'formats.thumbnail', thumbnailFile);\n };\n\n // Generate thumbnail and responsive formats\n const uploadResponsiveFormat = async (format: { key: string; file: UploadableFile }) => {\n const { key, file } = format;\n await getService('provider').upload(file);\n _.set(fileData, ['formats', key], file);\n };\n\n const uploadPromises: Promise<void>[] = [];\n\n // Upload image\n uploadPromises.push(getService('provider').upload(fileData));\n\n // Generate & Upload thumbnail and responsive formats\n if (await isResizableImage(fileData)) {\n const thumbnailFile = await generateThumbnail(fileData);\n if (thumbnailFile) {\n uploadPromises.push(uploadThumbnail(thumbnailFile));\n }\n\n const formats = await generateResponsiveFormats(fileData);\n if (Array.isArray(formats) && formats.length > 0) {\n for (const format of formats) {\n // eslint-disable-next-line no-continue\n if (!format) continue;\n uploadPromises.push(uploadResponsiveFormat(format));\n }\n }\n }\n // Wait for all uploads to finish\n await Promise.all(uploadPromises);\n }\n\n /**\n * Upload a file. If it is an image it will generate a thumbnail\n * and responsive formats (if enabled).\n */\n async function uploadFileAndPersist(fileData: UploadableFile, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const config = strapi.config.get<Config>('plugin::upload');\n const { isImage } = getService('image-manipulation');\n\n await getService('provider').checkFileSize(fileData);\n\n if (await isImage(fileData)) {\n await uploadImage(fileData);\n } else {\n await getService('provider').upload(fileData);\n }\n\n _.set(fileData, 'provider', config.provider);\n\n // Persist file(s)\n return add(fileData, { user });\n }\n\n async function updateFileInfo(\n id: ID,\n { name, alternativeText, caption, folder }: FileInfo,\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n\n const dbFile = await findOne(id);\n\n if (!dbFile) {\n throw new NotFoundError();\n }\n\n const fileService = getService('file');\n\n const newName = _.isNil(name) ? dbFile.name : name;\n const newInfos = {\n name: newName,\n alternativeText: _.isNil(alternativeText) ? dbFile.alternativeText : alternativeText,\n caption: _.isNil(caption) ? dbFile.caption : caption,\n folder: _.isUndefined(folder) ? dbFile.folder : folder,\n folderPath: _.isUndefined(folder) ? dbFile.path : await fileService.getFolderPath(folder),\n };\n\n return update(id, newInfos, { user });\n }\n\n async function replace(\n id: ID,\n { data, file }: { data: { fileInfo: FileInfo }; file: InputFile },\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n\n const config = strapi.config.get<Config>('plugin::upload');\n\n const { isImage } = getService('image-manipulation');\n\n const dbFile = await findOne(id);\n if (!dbFile) {\n throw new NotFoundError();\n }\n\n // create temporary folder to store files for stream manipulation\n const tmpWorkingDirectory = await createAndAssignTmpWorkingDirectoryToFiles(file);\n\n let fileData: UploadableFile;\n\n try {\n const { fileInfo } = data;\n fileData = await enhanceAndValidateFile(file, fileInfo);\n\n // keep a constant hash and extension so the file url doesn't change when the file is replaced\n _.assign(fileData, {\n hash: dbFile.hash,\n ext: dbFile.ext,\n });\n\n // execute delete function of the provider\n if (dbFile.provider === config.provider) {\n await strapi.plugin('upload').provider.delete(dbFile);\n\n if (dbFile.formats) {\n await Promise.all(\n Object.keys(dbFile.formats).map((key) => {\n return strapi.plugin('upload').provider.delete(dbFile.formats[key]);\n })\n );\n }\n }\n\n // clear old formats\n _.set(fileData, 'formats', {});\n\n if (await isImage(fileData)) {\n await uploadImage(fileData);\n } else {\n await getService('provider').upload(fileData);\n }\n\n _.set(fileData, 'provider', config.provider);\n } finally {\n // delete temporary folder\n await fse.remove(tmpWorkingDirectory);\n }\n\n return update(id, fileData, { user });\n }\n\n async function update(id: ID, values: Partial<File>, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const fileValues = { ...values };\n if (user) {\n Object.assign(fileValues, {\n [UPDATED_BY_ATTRIBUTE]: user.id,\n });\n }\n\n sendMediaMetrics(fileValues);\n\n const res = await strapi.db.query(FILE_MODEL_UID).update({ where: { id }, data: fileValues });\n\n await emitEvent(MEDIA_UPDATE, res);\n\n return res;\n }\n\n async function add(values: any, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const fileValues = { ...values };\n if (user) {\n Object.assign(fileValues, {\n [UPDATED_BY_ATTRIBUTE]: user.id,\n [CREATED_BY_ATTRIBUTE]: user.id,\n });\n }\n\n sendMediaMetrics(fileValues);\n\n const res = await strapi.db.query(FILE_MODEL_UID).create({ data: fileValues });\n\n await emitEvent(MEDIA_CREATE, res);\n\n return res;\n }\n\n function findOne(id: ID, populate = {}) {\n const query = strapi.get('query-params').transform(FILE_MODEL_UID, {\n populate,\n });\n\n return strapi.db.query(FILE_MODEL_UID).findOne({\n where: { id },\n ...query,\n });\n }\n\n function findMany(query: any = {}): Promise<File[]> {\n return strapi.db\n .query(FILE_MODEL_UID)\n .findMany(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n }\n\n function findPage(query: any = {}) {\n return strapi.db\n .query(FILE_MODEL_UID)\n .findPage(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n }\n\n async function remove(file: File) {\n const config = strapi.config.get<Config>('plugin::upload');\n\n // execute delete function of the provider\n if (file.provider === config.provider) {\n await strapi.plugin('upload').provider.delete(file);\n\n if (file.formats) {\n const keys = Object.keys(file.formats);\n\n await Promise.all(\n keys.map((key) => {\n return strapi.plugin('upload').provider.delete(file.formats![key]);\n })\n );\n }\n }\n\n const media = await strapi.db.query(FILE_MODEL_UID).findOne({\n where: { id: file.id },\n });\n\n await emitEvent(MEDIA_DELETE, media);\n\n return strapi.db.query(FILE_MODEL_UID).delete({ where: { id: file.id } });\n }\n\n async function getSettings() {\n const res = await strapi.store!({ type: 'plugin', name: 'upload', key: 'settings' }).get({});\n\n return res as Settings | null;\n }\n\n function setSettings(value: Settings) {\n if (value.responsiveDimensions === true) {\n strapi.telemetry.send('didEnableResponsiveDimensions');\n } else {\n strapi.telemetry.send('didDisableResponsiveDimensions');\n }\n\n return strapi.store!({ type: 'plugin', name: 'upload', key: 'settings' }).set({ value });\n }\n\n async function getConfiguration() {\n const res = await strapi.store!({\n type: 'plugin',\n name: 'upload',\n key: 'view_configuration',\n }).get({});\n\n return res as ViewConfiguration | null;\n }\n\n function setConfiguration(value: ViewConfiguration) {\n return strapi.store!({ type: 'plugin', name: 'upload', key: 'view_configuration' }).set({\n value,\n });\n }\n\n return {\n formatFileInfo,\n upload,\n updateFileInfo,\n replace,\n findOne,\n findMany,\n findPage,\n remove,\n getSettings,\n setSettings,\n getConfiguration,\n setConfiguration,\n\n /**\n * exposed for testing only\n * @internal\n */\n _uploadImage: uploadImage,\n };\n};\n"],"names":["UPDATED_BY_ATTRIBUTE","CREATED_BY_ATTRIBUTE","contentTypesUtils","constants","MEDIA_CREATE","MEDIA_UPDATE","MEDIA_DELETE","ALLOWED_WEBHOOK_EVENTS","ApplicationError","NotFoundError","errors","bytesToKbytes","fileUtils","strapi","sendMediaMetrics","data","_","has","isEmpty","caption","telemetry","send","alternativeText","createAndAssignTmpWorkingDirectoryToFiles","files","tmpWorkingDirectory","fse","mkdtemp","path","join","os","tmpdir","Array","isArray","forEach","file","filenameReservedRegex","windowsReservedNameRegex","isValidFilename","string","length","test","emitEvent","event","modelDef","getModel","FILE_MODEL_UID","sanitizedData","sanitize","sanitizers","defaultSanitizeOutput","schema","uid","eventHub","emit","media","formatFileInfo","filename","type","size","fileInfo","metas","fileService","getService","imageManipulationService","ext","extname","extension","usedName","name","normalize","basename","entity","folder","folderPath","getFolderPath","hash","generateFileName","mime","sizeInBytes","refId","ref","field","related","id","__type","__pivot","enhanceAndValidateFile","currentFile","originalFilename","mimetype","filepath","getStream","fs","createReadStream","optimize","isImage","isFaultyImage","isOptimizableImage","plugin","service","upload","opts","user","uploadedFiles","fileArray","fileInfoArray","doUpload","fileData","uploadFileAndPersist","Promise","all","map","idx","remove","uploadImage","getDimensions","generateThumbnail","generateResponsiveFormats","isResizableImage","width","height","assign","uploadThumbnail","thumbnailFile","set","uploadResponsiveFormat","format","key","uploadPromises","push","formats","config","get","checkFileSize","provider","add","updateFileInfo","dbFile","findOne","newName","isNil","newInfos","isUndefined","update","replace","delete","Object","keys","values","fileValues","res","db","query","where","create","populate","transform","findMany","findPage","getSettings","store","setSettings","value","responsiveDimensions","getConfiguration","setConfiguration","_uploadImage"],"mappings":"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"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import os from 'os';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import crypto from 'crypto';
|
|
4
3
|
import fs from 'fs';
|
|
5
4
|
import fse from 'fs-extra';
|
|
6
5
|
import _ from 'lodash';
|
|
7
6
|
import { extension } from 'mime-types';
|
|
8
|
-
import { contentTypes, errors, file,
|
|
7
|
+
import { contentTypes, errors, file, sanitize } from '@strapi/utils';
|
|
9
8
|
import { FILE_MODEL_UID, ALLOWED_WEBHOOK_EVENTS } from '../constants.mjs';
|
|
10
9
|
import { getService } from '../utils/index.mjs';
|
|
11
10
|
|
|
@@ -14,14 +13,6 @@ const { MEDIA_CREATE, MEDIA_UPDATE, MEDIA_DELETE } = ALLOWED_WEBHOOK_EVENTS;
|
|
|
14
13
|
const { ApplicationError, NotFoundError } = errors;
|
|
15
14
|
const { bytesToKbytes } = file;
|
|
16
15
|
var upload = (({ strapi })=>{
|
|
17
|
-
const randomSuffix = ()=>crypto.randomBytes(5).toString('hex');
|
|
18
|
-
const generateFileName = (name)=>{
|
|
19
|
-
const baseName = strings.nameToSlug(name, {
|
|
20
|
-
separator: '_',
|
|
21
|
-
lowercase: false
|
|
22
|
-
});
|
|
23
|
-
return `${baseName}_${randomSuffix()}`;
|
|
24
|
-
};
|
|
25
16
|
const sendMediaMetrics = (data)=>{
|
|
26
17
|
if (_.has(data, 'caption') && !_.isEmpty(data.caption)) {
|
|
27
18
|
strapi.telemetry.send('didSaveMediaWithCaption');
|
|
@@ -76,6 +67,7 @@ var upload = (({ strapi })=>{
|
|
|
76
67
|
}
|
|
77
68
|
async function formatFileInfo({ filename, type, size }, fileInfo = {}, metas = {}) {
|
|
78
69
|
const fileService = getService('file');
|
|
70
|
+
const imageManipulationService = getService('image-manipulation');
|
|
79
71
|
if (!isValidFilename(filename)) {
|
|
80
72
|
throw new ApplicationError('File name contains invalid characters');
|
|
81
73
|
}
|
|
@@ -95,7 +87,7 @@ var upload = (({ strapi })=>{
|
|
|
95
87
|
caption: fileInfo.caption,
|
|
96
88
|
folder: fileInfo.folder,
|
|
97
89
|
folderPath: await fileService.getFolderPath(fileInfo.folder),
|
|
98
|
-
hash: generateFileName(basename),
|
|
90
|
+
hash: imageManipulationService.generateFileName(basename),
|
|
99
91
|
ext,
|
|
100
92
|
mime: type,
|
|
101
93
|
size: bytesToKbytes(size),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.mjs","sources":["../../../server/src/services/upload.ts"],"sourcesContent":["import os from 'os';\nimport path from 'path';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport fse from 'fs-extra';\nimport _ from 'lodash';\nimport { extension } from 'mime-types';\nimport {\n sanitize,\n strings,\n contentTypes as contentTypesUtils,\n errors,\n file as fileUtils,\n} from '@strapi/utils';\n\nimport type { Core, UID } from '@strapi/types';\n\nimport { FILE_MODEL_UID, ALLOWED_WEBHOOK_EVENTS } from '../constants';\nimport { getService } from '../utils';\n\nimport type { Config, File, InputFile, UploadableFile, FileInfo } from '../types';\nimport type { ViewConfiguration } from '../controllers/validation/admin/configureView';\nimport type { Settings } from '../controllers/validation/admin/settings';\n\ntype User = {\n id: string | number;\n};\n\ntype ID = string | number;\n\ntype CommonOptions = {\n user?: User;\n};\n\ntype Metas = {\n refId?: ID;\n ref?: string;\n field?: string;\n path?: string;\n tmpWorkingDirectory?: string;\n};\n\nconst { UPDATED_BY_ATTRIBUTE, CREATED_BY_ATTRIBUTE } = contentTypesUtils.constants;\nconst { MEDIA_CREATE, MEDIA_UPDATE, MEDIA_DELETE } = ALLOWED_WEBHOOK_EVENTS;\n\nconst { ApplicationError, NotFoundError } = errors;\nconst { bytesToKbytes } = fileUtils;\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => {\n const randomSuffix = () => crypto.randomBytes(5).toString('hex');\n\n const generateFileName = (name: string) => {\n const baseName = strings.nameToSlug(name, { separator: '_', lowercase: false });\n\n return `${baseName}_${randomSuffix()}`;\n };\n\n const sendMediaMetrics = (data: Pick<File, 'caption' | 'alternativeText'>) => {\n if (_.has(data, 'caption') && !_.isEmpty(data.caption)) {\n strapi.telemetry.send('didSaveMediaWithCaption');\n }\n\n if (_.has(data, 'alternativeText') && !_.isEmpty(data.alternativeText)) {\n strapi.telemetry.send('didSaveMediaWithAlternativeText');\n }\n };\n\n const createAndAssignTmpWorkingDirectoryToFiles = async (\n files: InputFile | InputFile[]\n ): Promise<string> => {\n const tmpWorkingDirectory = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-upload-'));\n\n if (Array.isArray(files)) {\n files.forEach((file) => {\n file.tmpWorkingDirectory = tmpWorkingDirectory;\n });\n } else {\n files.tmpWorkingDirectory = tmpWorkingDirectory;\n }\n\n return tmpWorkingDirectory;\n };\n\n function filenameReservedRegex() {\n // eslint-disable-next-line no-control-regex\n return /[<>:\"/\\\\|?*\\u0000-\\u001F]/g;\n }\n\n function windowsReservedNameRegex() {\n return /^(con|prn|aux|nul|com\\d|lpt\\d)$/i;\n }\n\n /**\n * Copied from https://github.com/sindresorhus/valid-filename package\n */\n function isValidFilename(string: string) {\n if (!string || string.length > 255) {\n return false;\n }\n if (filenameReservedRegex().test(string) || windowsReservedNameRegex().test(string)) {\n return false;\n }\n if (string === '.' || string === '..') {\n return false;\n }\n return true;\n }\n\n async function emitEvent(event: string, data: Record<string, any>) {\n const modelDef = strapi.getModel(FILE_MODEL_UID);\n const sanitizedData = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: modelDef,\n getModel(uid: string) {\n return strapi.getModel(uid as UID.Schema);\n },\n },\n data\n );\n\n strapi.eventHub.emit(event, { media: sanitizedData });\n }\n\n async function formatFileInfo(\n { filename, type, size }: { filename: string; type: string; size: number },\n fileInfo: Partial<FileInfo> = {},\n metas: {\n refId?: ID;\n ref?: string;\n field?: string;\n path?: string;\n tmpWorkingDirectory?: string;\n } = {}\n ): Promise<Omit<UploadableFile, 'getStream'>> {\n const fileService = getService('file');\n\n if (!isValidFilename(filename)) {\n throw new ApplicationError('File name contains invalid characters');\n }\n\n let ext = path.extname(filename);\n if (!ext) {\n ext = `.${extension(type)}`;\n }\n const usedName = (fileInfo.name || filename).normalize();\n const basename = path.basename(usedName, ext);\n\n // Prevent null characters in file name\n if (!isValidFilename(filename)) {\n throw new ApplicationError('File name contains invalid characters');\n }\n\n const entity: Omit<UploadableFile, 'getStream'> = {\n name: usedName,\n alternativeText: fileInfo.alternativeText,\n caption: fileInfo.caption,\n folder: fileInfo.folder,\n folderPath: await fileService.getFolderPath(fileInfo.folder),\n hash: generateFileName(basename),\n ext,\n mime: type,\n size: bytesToKbytes(size),\n sizeInBytes: size,\n };\n\n const { refId, ref, field } = metas;\n\n if (refId && ref && field) {\n entity.related = [\n {\n id: refId,\n __type: ref,\n __pivot: { field },\n },\n ];\n }\n\n if (metas.path) {\n entity.path = metas.path;\n }\n\n if (metas.tmpWorkingDirectory) {\n entity.tmpWorkingDirectory = metas.tmpWorkingDirectory;\n }\n\n return entity;\n }\n\n async function enhanceAndValidateFile(\n file: InputFile,\n fileInfo: FileInfo,\n metas?: Metas\n ): Promise<UploadableFile> {\n const currentFile = (await formatFileInfo(\n {\n filename: file.originalFilename ?? 'unamed',\n type: file.mimetype ?? 'application/octet-stream',\n size: file.size,\n },\n fileInfo,\n {\n ...metas,\n tmpWorkingDirectory: file.tmpWorkingDirectory,\n }\n )) as UploadableFile;\n\n currentFile.filepath = file.filepath;\n currentFile.getStream = () => fs.createReadStream(file.filepath);\n\n const { optimize, isImage, isFaultyImage, isOptimizableImage } = strapi\n .plugin('upload')\n .service('image-manipulation');\n\n if (await isImage(currentFile)) {\n if (await isFaultyImage(currentFile)) {\n throw new ApplicationError('File is not a valid image');\n }\n if (await isOptimizableImage(currentFile)) {\n return optimize(currentFile);\n }\n }\n\n return currentFile;\n }\n\n async function upload(\n {\n data,\n files,\n }: {\n data: Record<string, unknown>;\n files: InputFile | InputFile[];\n },\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n // create temporary folder to store files for stream manipulation\n const tmpWorkingDirectory = await createAndAssignTmpWorkingDirectoryToFiles(files);\n\n let uploadedFiles: any[] = [];\n\n try {\n const { fileInfo, ...metas } = data;\n\n const fileArray = Array.isArray(files) ? files : [files];\n const fileInfoArray = Array.isArray(fileInfo) ? fileInfo : [fileInfo];\n\n const doUpload = async (file: InputFile, fileInfo: FileInfo) => {\n const fileData = await enhanceAndValidateFile(file, fileInfo, metas);\n return uploadFileAndPersist(fileData, { user });\n };\n\n uploadedFiles = await Promise.all(\n fileArray.map((file, idx) => doUpload(file, fileInfoArray[idx] || {}))\n );\n } finally {\n // delete temporary folder\n await fse.remove(tmpWorkingDirectory);\n }\n\n return uploadedFiles;\n }\n\n /**\n * When uploading an image, an additional thumbnail is generated.\n * Also, if there are responsive formats defined, another set of images will be generated too.\n *\n * @param {*} fileData\n */\n async function uploadImage(fileData: UploadableFile) {\n const { getDimensions, generateThumbnail, generateResponsiveFormats, isResizableImage } =\n getService('image-manipulation');\n\n // Store width and height of the original image\n const { width, height } = await getDimensions(fileData);\n\n // Make sure this is assigned before calling any upload\n // That way it can mutate the width and height\n _.assign(fileData, {\n width,\n height,\n });\n\n // For performance reasons, all uploads are wrapped in a single Promise.all\n const uploadThumbnail = async (thumbnailFile: UploadableFile) => {\n await getService('provider').upload(thumbnailFile);\n _.set(fileData, 'formats.thumbnail', thumbnailFile);\n };\n\n // Generate thumbnail and responsive formats\n const uploadResponsiveFormat = async (format: { key: string; file: UploadableFile }) => {\n const { key, file } = format;\n await getService('provider').upload(file);\n _.set(fileData, ['formats', key], file);\n };\n\n const uploadPromises: Promise<void>[] = [];\n\n // Upload image\n uploadPromises.push(getService('provider').upload(fileData));\n\n // Generate & Upload thumbnail and responsive formats\n if (await isResizableImage(fileData)) {\n const thumbnailFile = await generateThumbnail(fileData);\n if (thumbnailFile) {\n uploadPromises.push(uploadThumbnail(thumbnailFile));\n }\n\n const formats = await generateResponsiveFormats(fileData);\n if (Array.isArray(formats) && formats.length > 0) {\n for (const format of formats) {\n // eslint-disable-next-line no-continue\n if (!format) continue;\n uploadPromises.push(uploadResponsiveFormat(format));\n }\n }\n }\n // Wait for all uploads to finish\n await Promise.all(uploadPromises);\n }\n\n /**\n * Upload a file. If it is an image it will generate a thumbnail\n * and responsive formats (if enabled).\n */\n async function uploadFileAndPersist(fileData: UploadableFile, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const config = strapi.config.get<Config>('plugin::upload');\n const { isImage } = getService('image-manipulation');\n\n await getService('provider').checkFileSize(fileData);\n\n if (await isImage(fileData)) {\n await uploadImage(fileData);\n } else {\n await getService('provider').upload(fileData);\n }\n\n _.set(fileData, 'provider', config.provider);\n\n // Persist file(s)\n return add(fileData, { user });\n }\n\n async function updateFileInfo(\n id: ID,\n { name, alternativeText, caption, folder }: FileInfo,\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n\n const dbFile = await findOne(id);\n\n if (!dbFile) {\n throw new NotFoundError();\n }\n\n const fileService = getService('file');\n\n const newName = _.isNil(name) ? dbFile.name : name;\n const newInfos = {\n name: newName,\n alternativeText: _.isNil(alternativeText) ? dbFile.alternativeText : alternativeText,\n caption: _.isNil(caption) ? dbFile.caption : caption,\n folder: _.isUndefined(folder) ? dbFile.folder : folder,\n folderPath: _.isUndefined(folder) ? dbFile.path : await fileService.getFolderPath(folder),\n };\n\n return update(id, newInfos, { user });\n }\n\n async function replace(\n id: ID,\n { data, file }: { data: { fileInfo: FileInfo }; file: InputFile },\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n\n const config = strapi.config.get<Config>('plugin::upload');\n\n const { isImage } = getService('image-manipulation');\n\n const dbFile = await findOne(id);\n if (!dbFile) {\n throw new NotFoundError();\n }\n\n // create temporary folder to store files for stream manipulation\n const tmpWorkingDirectory = await createAndAssignTmpWorkingDirectoryToFiles(file);\n\n let fileData: UploadableFile;\n\n try {\n const { fileInfo } = data;\n fileData = await enhanceAndValidateFile(file, fileInfo);\n\n // keep a constant hash and extension so the file url doesn't change when the file is replaced\n _.assign(fileData, {\n hash: dbFile.hash,\n ext: dbFile.ext,\n });\n\n // execute delete function of the provider\n if (dbFile.provider === config.provider) {\n await strapi.plugin('upload').provider.delete(dbFile);\n\n if (dbFile.formats) {\n await Promise.all(\n Object.keys(dbFile.formats).map((key) => {\n return strapi.plugin('upload').provider.delete(dbFile.formats[key]);\n })\n );\n }\n }\n\n // clear old formats\n _.set(fileData, 'formats', {});\n\n if (await isImage(fileData)) {\n await uploadImage(fileData);\n } else {\n await getService('provider').upload(fileData);\n }\n\n _.set(fileData, 'provider', config.provider);\n } finally {\n // delete temporary folder\n await fse.remove(tmpWorkingDirectory);\n }\n\n return update(id, fileData, { user });\n }\n\n async function update(id: ID, values: Partial<File>, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const fileValues = { ...values };\n if (user) {\n Object.assign(fileValues, {\n [UPDATED_BY_ATTRIBUTE]: user.id,\n });\n }\n\n sendMediaMetrics(fileValues);\n\n const res = await strapi.db.query(FILE_MODEL_UID).update({ where: { id }, data: fileValues });\n\n await emitEvent(MEDIA_UPDATE, res);\n\n return res;\n }\n\n async function add(values: any, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const fileValues = { ...values };\n if (user) {\n Object.assign(fileValues, {\n [UPDATED_BY_ATTRIBUTE]: user.id,\n [CREATED_BY_ATTRIBUTE]: user.id,\n });\n }\n\n sendMediaMetrics(fileValues);\n\n const res = await strapi.db.query(FILE_MODEL_UID).create({ data: fileValues });\n\n await emitEvent(MEDIA_CREATE, res);\n\n return res;\n }\n\n function findOne(id: ID, populate = {}) {\n const query = strapi.get('query-params').transform(FILE_MODEL_UID, {\n populate,\n });\n\n return strapi.db.query(FILE_MODEL_UID).findOne({\n where: { id },\n ...query,\n });\n }\n\n function findMany(query: any = {}): Promise<File[]> {\n return strapi.db\n .query(FILE_MODEL_UID)\n .findMany(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n }\n\n function findPage(query: any = {}) {\n return strapi.db\n .query(FILE_MODEL_UID)\n .findPage(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n }\n\n async function remove(file: File) {\n const config = strapi.config.get<Config>('plugin::upload');\n\n // execute delete function of the provider\n if (file.provider === config.provider) {\n await strapi.plugin('upload').provider.delete(file);\n\n if (file.formats) {\n const keys = Object.keys(file.formats);\n\n await Promise.all(\n keys.map((key) => {\n return strapi.plugin('upload').provider.delete(file.formats![key]);\n })\n );\n }\n }\n\n const media = await strapi.db.query(FILE_MODEL_UID).findOne({\n where: { id: file.id },\n });\n\n await emitEvent(MEDIA_DELETE, media);\n\n return strapi.db.query(FILE_MODEL_UID).delete({ where: { id: file.id } });\n }\n\n async function getSettings() {\n const res = await strapi.store!({ type: 'plugin', name: 'upload', key: 'settings' }).get({});\n\n return res as Settings | null;\n }\n\n function setSettings(value: Settings) {\n if (value.responsiveDimensions === true) {\n strapi.telemetry.send('didEnableResponsiveDimensions');\n } else {\n strapi.telemetry.send('didDisableResponsiveDimensions');\n }\n\n return strapi.store!({ type: 'plugin', name: 'upload', key: 'settings' }).set({ value });\n }\n\n async function getConfiguration() {\n const res = await strapi.store!({\n type: 'plugin',\n name: 'upload',\n key: 'view_configuration',\n }).get({});\n\n return res as ViewConfiguration | null;\n }\n\n function setConfiguration(value: ViewConfiguration) {\n return strapi.store!({ type: 'plugin', name: 'upload', key: 'view_configuration' }).set({\n value,\n });\n }\n\n return {\n formatFileInfo,\n upload,\n updateFileInfo,\n replace,\n findOne,\n findMany,\n findPage,\n remove,\n getSettings,\n setSettings,\n getConfiguration,\n setConfiguration,\n\n /**\n * exposed for testing only\n * @internal\n */\n _uploadImage: uploadImage,\n };\n};\n"],"names":["UPDATED_BY_ATTRIBUTE","CREATED_BY_ATTRIBUTE","contentTypesUtils","constants","MEDIA_CREATE","MEDIA_UPDATE","MEDIA_DELETE","ALLOWED_WEBHOOK_EVENTS","ApplicationError","NotFoundError","errors","bytesToKbytes","fileUtils","strapi","randomSuffix","crypto","randomBytes","toString","generateFileName","name","baseName","strings","nameToSlug","separator","lowercase","sendMediaMetrics","data","_","has","isEmpty","caption","telemetry","send","alternativeText","createAndAssignTmpWorkingDirectoryToFiles","files","tmpWorkingDirectory","fse","mkdtemp","path","join","os","tmpdir","Array","isArray","forEach","file","filenameReservedRegex","windowsReservedNameRegex","isValidFilename","string","length","test","emitEvent","event","modelDef","getModel","FILE_MODEL_UID","sanitizedData","sanitize","sanitizers","defaultSanitizeOutput","schema","uid","eventHub","emit","media","formatFileInfo","filename","type","size","fileInfo","metas","fileService","getService","ext","extname","extension","usedName","normalize","basename","entity","folder","folderPath","getFolderPath","hash","mime","sizeInBytes","refId","ref","field","related","id","__type","__pivot","enhanceAndValidateFile","currentFile","originalFilename","mimetype","filepath","getStream","fs","createReadStream","optimize","isImage","isFaultyImage","isOptimizableImage","plugin","service","upload","opts","user","uploadedFiles","fileArray","fileInfoArray","doUpload","fileData","uploadFileAndPersist","Promise","all","map","idx","remove","uploadImage","getDimensions","generateThumbnail","generateResponsiveFormats","isResizableImage","width","height","assign","uploadThumbnail","thumbnailFile","set","uploadResponsiveFormat","format","key","uploadPromises","push","formats","config","get","checkFileSize","provider","add","updateFileInfo","dbFile","findOne","newName","isNil","newInfos","isUndefined","update","replace","delete","Object","keys","values","fileValues","res","db","query","where","create","populate","transform","findMany","findPage","getSettings","store","setSettings","value","responsiveDimensions","getConfiguration","setConfiguration","_uploadImage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"upload.mjs","sources":["../../../server/src/services/upload.ts"],"sourcesContent":["import os from 'os';\nimport path from 'path';\nimport fs from 'fs';\nimport fse from 'fs-extra';\nimport _ from 'lodash';\nimport { extension } from 'mime-types';\nimport {\n sanitize,\n contentTypes as contentTypesUtils,\n errors,\n file as fileUtils,\n} from '@strapi/utils';\n\nimport type { Core, UID } from '@strapi/types';\n\nimport { FILE_MODEL_UID, ALLOWED_WEBHOOK_EVENTS } from '../constants';\nimport { getService } from '../utils';\n\nimport type { Config, File, InputFile, UploadableFile, FileInfo } from '../types';\nimport type { ViewConfiguration } from '../controllers/validation/admin/configureView';\nimport type { Settings } from '../controllers/validation/admin/settings';\n\ntype User = {\n id: string | number;\n};\n\ntype ID = string | number;\n\ntype CommonOptions = {\n user?: User;\n};\n\ntype Metas = {\n refId?: ID;\n ref?: string;\n field?: string;\n path?: string;\n tmpWorkingDirectory?: string;\n};\n\nconst { UPDATED_BY_ATTRIBUTE, CREATED_BY_ATTRIBUTE } = contentTypesUtils.constants;\nconst { MEDIA_CREATE, MEDIA_UPDATE, MEDIA_DELETE } = ALLOWED_WEBHOOK_EVENTS;\n\nconst { ApplicationError, NotFoundError } = errors;\nconst { bytesToKbytes } = fileUtils;\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => {\n const sendMediaMetrics = (data: Pick<File, 'caption' | 'alternativeText'>) => {\n if (_.has(data, 'caption') && !_.isEmpty(data.caption)) {\n strapi.telemetry.send('didSaveMediaWithCaption');\n }\n\n if (_.has(data, 'alternativeText') && !_.isEmpty(data.alternativeText)) {\n strapi.telemetry.send('didSaveMediaWithAlternativeText');\n }\n };\n\n const createAndAssignTmpWorkingDirectoryToFiles = async (\n files: InputFile | InputFile[]\n ): Promise<string> => {\n const tmpWorkingDirectory = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-upload-'));\n\n if (Array.isArray(files)) {\n files.forEach((file) => {\n file.tmpWorkingDirectory = tmpWorkingDirectory;\n });\n } else {\n files.tmpWorkingDirectory = tmpWorkingDirectory;\n }\n\n return tmpWorkingDirectory;\n };\n\n function filenameReservedRegex() {\n // eslint-disable-next-line no-control-regex\n return /[<>:\"/\\\\|?*\\u0000-\\u001F]/g;\n }\n\n function windowsReservedNameRegex() {\n return /^(con|prn|aux|nul|com\\d|lpt\\d)$/i;\n }\n\n /**\n * Copied from https://github.com/sindresorhus/valid-filename package\n */\n function isValidFilename(string: string) {\n if (!string || string.length > 255) {\n return false;\n }\n if (filenameReservedRegex().test(string) || windowsReservedNameRegex().test(string)) {\n return false;\n }\n if (string === '.' || string === '..') {\n return false;\n }\n return true;\n }\n\n async function emitEvent(event: string, data: Record<string, any>) {\n const modelDef = strapi.getModel(FILE_MODEL_UID);\n const sanitizedData = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: modelDef,\n getModel(uid: string) {\n return strapi.getModel(uid as UID.Schema);\n },\n },\n data\n );\n\n strapi.eventHub.emit(event, { media: sanitizedData });\n }\n\n async function formatFileInfo(\n { filename, type, size }: { filename: string; type: string; size: number },\n fileInfo: Partial<FileInfo> = {},\n metas: {\n refId?: ID;\n ref?: string;\n field?: string;\n path?: string;\n tmpWorkingDirectory?: string;\n } = {}\n ): Promise<Omit<UploadableFile, 'getStream'>> {\n const fileService = getService('file');\n const imageManipulationService = getService('image-manipulation');\n\n if (!isValidFilename(filename)) {\n throw new ApplicationError('File name contains invalid characters');\n }\n\n let ext = path.extname(filename);\n if (!ext) {\n ext = `.${extension(type)}`;\n }\n const usedName = (fileInfo.name || filename).normalize();\n const basename = path.basename(usedName, ext);\n\n // Prevent null characters in file name\n if (!isValidFilename(filename)) {\n throw new ApplicationError('File name contains invalid characters');\n }\n\n const entity: Omit<UploadableFile, 'getStream'> = {\n name: usedName,\n alternativeText: fileInfo.alternativeText,\n caption: fileInfo.caption,\n folder: fileInfo.folder,\n folderPath: await fileService.getFolderPath(fileInfo.folder),\n hash: imageManipulationService.generateFileName(basename),\n ext,\n mime: type,\n size: bytesToKbytes(size),\n sizeInBytes: size,\n };\n\n const { refId, ref, field } = metas;\n\n if (refId && ref && field) {\n entity.related = [\n {\n id: refId,\n __type: ref,\n __pivot: { field },\n },\n ];\n }\n\n if (metas.path) {\n entity.path = metas.path;\n }\n\n if (metas.tmpWorkingDirectory) {\n entity.tmpWorkingDirectory = metas.tmpWorkingDirectory;\n }\n\n return entity;\n }\n\n async function enhanceAndValidateFile(\n file: InputFile,\n fileInfo: FileInfo,\n metas?: Metas\n ): Promise<UploadableFile> {\n const currentFile = (await formatFileInfo(\n {\n filename: file.originalFilename ?? 'unamed',\n type: file.mimetype ?? 'application/octet-stream',\n size: file.size,\n },\n fileInfo,\n {\n ...metas,\n tmpWorkingDirectory: file.tmpWorkingDirectory,\n }\n )) as UploadableFile;\n\n currentFile.filepath = file.filepath;\n currentFile.getStream = () => fs.createReadStream(file.filepath);\n\n const { optimize, isImage, isFaultyImage, isOptimizableImage } = strapi\n .plugin('upload')\n .service('image-manipulation');\n\n if (await isImage(currentFile)) {\n if (await isFaultyImage(currentFile)) {\n throw new ApplicationError('File is not a valid image');\n }\n if (await isOptimizableImage(currentFile)) {\n return optimize(currentFile);\n }\n }\n\n return currentFile;\n }\n\n async function upload(\n {\n data,\n files,\n }: {\n data: Record<string, unknown>;\n files: InputFile | InputFile[];\n },\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n // create temporary folder to store files for stream manipulation\n const tmpWorkingDirectory = await createAndAssignTmpWorkingDirectoryToFiles(files);\n\n let uploadedFiles: any[] = [];\n\n try {\n const { fileInfo, ...metas } = data;\n\n const fileArray = Array.isArray(files) ? files : [files];\n const fileInfoArray = Array.isArray(fileInfo) ? fileInfo : [fileInfo];\n\n const doUpload = async (file: InputFile, fileInfo: FileInfo) => {\n const fileData = await enhanceAndValidateFile(file, fileInfo, metas);\n return uploadFileAndPersist(fileData, { user });\n };\n\n uploadedFiles = await Promise.all(\n fileArray.map((file, idx) => doUpload(file, fileInfoArray[idx] || {}))\n );\n } finally {\n // delete temporary folder\n await fse.remove(tmpWorkingDirectory);\n }\n\n return uploadedFiles;\n }\n\n /**\n * When uploading an image, an additional thumbnail is generated.\n * Also, if there are responsive formats defined, another set of images will be generated too.\n *\n * @param {*} fileData\n */\n async function uploadImage(fileData: UploadableFile) {\n const { getDimensions, generateThumbnail, generateResponsiveFormats, isResizableImage } =\n getService('image-manipulation');\n\n // Store width and height of the original image\n const { width, height } = await getDimensions(fileData);\n\n // Make sure this is assigned before calling any upload\n // That way it can mutate the width and height\n _.assign(fileData, {\n width,\n height,\n });\n\n // For performance reasons, all uploads are wrapped in a single Promise.all\n const uploadThumbnail = async (thumbnailFile: UploadableFile) => {\n await getService('provider').upload(thumbnailFile);\n _.set(fileData, 'formats.thumbnail', thumbnailFile);\n };\n\n // Generate thumbnail and responsive formats\n const uploadResponsiveFormat = async (format: { key: string; file: UploadableFile }) => {\n const { key, file } = format;\n await getService('provider').upload(file);\n _.set(fileData, ['formats', key], file);\n };\n\n const uploadPromises: Promise<void>[] = [];\n\n // Upload image\n uploadPromises.push(getService('provider').upload(fileData));\n\n // Generate & Upload thumbnail and responsive formats\n if (await isResizableImage(fileData)) {\n const thumbnailFile = await generateThumbnail(fileData);\n if (thumbnailFile) {\n uploadPromises.push(uploadThumbnail(thumbnailFile));\n }\n\n const formats = await generateResponsiveFormats(fileData);\n if (Array.isArray(formats) && formats.length > 0) {\n for (const format of formats) {\n // eslint-disable-next-line no-continue\n if (!format) continue;\n uploadPromises.push(uploadResponsiveFormat(format));\n }\n }\n }\n // Wait for all uploads to finish\n await Promise.all(uploadPromises);\n }\n\n /**\n * Upload a file. If it is an image it will generate a thumbnail\n * and responsive formats (if enabled).\n */\n async function uploadFileAndPersist(fileData: UploadableFile, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const config = strapi.config.get<Config>('plugin::upload');\n const { isImage } = getService('image-manipulation');\n\n await getService('provider').checkFileSize(fileData);\n\n if (await isImage(fileData)) {\n await uploadImage(fileData);\n } else {\n await getService('provider').upload(fileData);\n }\n\n _.set(fileData, 'provider', config.provider);\n\n // Persist file(s)\n return add(fileData, { user });\n }\n\n async function updateFileInfo(\n id: ID,\n { name, alternativeText, caption, folder }: FileInfo,\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n\n const dbFile = await findOne(id);\n\n if (!dbFile) {\n throw new NotFoundError();\n }\n\n const fileService = getService('file');\n\n const newName = _.isNil(name) ? dbFile.name : name;\n const newInfos = {\n name: newName,\n alternativeText: _.isNil(alternativeText) ? dbFile.alternativeText : alternativeText,\n caption: _.isNil(caption) ? dbFile.caption : caption,\n folder: _.isUndefined(folder) ? dbFile.folder : folder,\n folderPath: _.isUndefined(folder) ? dbFile.path : await fileService.getFolderPath(folder),\n };\n\n return update(id, newInfos, { user });\n }\n\n async function replace(\n id: ID,\n { data, file }: { data: { fileInfo: FileInfo }; file: InputFile },\n opts?: CommonOptions\n ) {\n const { user } = opts ?? {};\n\n const config = strapi.config.get<Config>('plugin::upload');\n\n const { isImage } = getService('image-manipulation');\n\n const dbFile = await findOne(id);\n if (!dbFile) {\n throw new NotFoundError();\n }\n\n // create temporary folder to store files for stream manipulation\n const tmpWorkingDirectory = await createAndAssignTmpWorkingDirectoryToFiles(file);\n\n let fileData: UploadableFile;\n\n try {\n const { fileInfo } = data;\n fileData = await enhanceAndValidateFile(file, fileInfo);\n\n // keep a constant hash and extension so the file url doesn't change when the file is replaced\n _.assign(fileData, {\n hash: dbFile.hash,\n ext: dbFile.ext,\n });\n\n // execute delete function of the provider\n if (dbFile.provider === config.provider) {\n await strapi.plugin('upload').provider.delete(dbFile);\n\n if (dbFile.formats) {\n await Promise.all(\n Object.keys(dbFile.formats).map((key) => {\n return strapi.plugin('upload').provider.delete(dbFile.formats[key]);\n })\n );\n }\n }\n\n // clear old formats\n _.set(fileData, 'formats', {});\n\n if (await isImage(fileData)) {\n await uploadImage(fileData);\n } else {\n await getService('provider').upload(fileData);\n }\n\n _.set(fileData, 'provider', config.provider);\n } finally {\n // delete temporary folder\n await fse.remove(tmpWorkingDirectory);\n }\n\n return update(id, fileData, { user });\n }\n\n async function update(id: ID, values: Partial<File>, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const fileValues = { ...values };\n if (user) {\n Object.assign(fileValues, {\n [UPDATED_BY_ATTRIBUTE]: user.id,\n });\n }\n\n sendMediaMetrics(fileValues);\n\n const res = await strapi.db.query(FILE_MODEL_UID).update({ where: { id }, data: fileValues });\n\n await emitEvent(MEDIA_UPDATE, res);\n\n return res;\n }\n\n async function add(values: any, opts?: CommonOptions) {\n const { user } = opts ?? {};\n\n const fileValues = { ...values };\n if (user) {\n Object.assign(fileValues, {\n [UPDATED_BY_ATTRIBUTE]: user.id,\n [CREATED_BY_ATTRIBUTE]: user.id,\n });\n }\n\n sendMediaMetrics(fileValues);\n\n const res = await strapi.db.query(FILE_MODEL_UID).create({ data: fileValues });\n\n await emitEvent(MEDIA_CREATE, res);\n\n return res;\n }\n\n function findOne(id: ID, populate = {}) {\n const query = strapi.get('query-params').transform(FILE_MODEL_UID, {\n populate,\n });\n\n return strapi.db.query(FILE_MODEL_UID).findOne({\n where: { id },\n ...query,\n });\n }\n\n function findMany(query: any = {}): Promise<File[]> {\n return strapi.db\n .query(FILE_MODEL_UID)\n .findMany(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n }\n\n function findPage(query: any = {}) {\n return strapi.db\n .query(FILE_MODEL_UID)\n .findPage(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n }\n\n async function remove(file: File) {\n const config = strapi.config.get<Config>('plugin::upload');\n\n // execute delete function of the provider\n if (file.provider === config.provider) {\n await strapi.plugin('upload').provider.delete(file);\n\n if (file.formats) {\n const keys = Object.keys(file.formats);\n\n await Promise.all(\n keys.map((key) => {\n return strapi.plugin('upload').provider.delete(file.formats![key]);\n })\n );\n }\n }\n\n const media = await strapi.db.query(FILE_MODEL_UID).findOne({\n where: { id: file.id },\n });\n\n await emitEvent(MEDIA_DELETE, media);\n\n return strapi.db.query(FILE_MODEL_UID).delete({ where: { id: file.id } });\n }\n\n async function getSettings() {\n const res = await strapi.store!({ type: 'plugin', name: 'upload', key: 'settings' }).get({});\n\n return res as Settings | null;\n }\n\n function setSettings(value: Settings) {\n if (value.responsiveDimensions === true) {\n strapi.telemetry.send('didEnableResponsiveDimensions');\n } else {\n strapi.telemetry.send('didDisableResponsiveDimensions');\n }\n\n return strapi.store!({ type: 'plugin', name: 'upload', key: 'settings' }).set({ value });\n }\n\n async function getConfiguration() {\n const res = await strapi.store!({\n type: 'plugin',\n name: 'upload',\n key: 'view_configuration',\n }).get({});\n\n return res as ViewConfiguration | null;\n }\n\n function setConfiguration(value: ViewConfiguration) {\n return strapi.store!({ type: 'plugin', name: 'upload', key: 'view_configuration' }).set({\n value,\n });\n }\n\n return {\n formatFileInfo,\n upload,\n updateFileInfo,\n replace,\n findOne,\n findMany,\n findPage,\n remove,\n getSettings,\n setSettings,\n getConfiguration,\n setConfiguration,\n\n /**\n * exposed for testing only\n * @internal\n */\n _uploadImage: uploadImage,\n };\n};\n"],"names":["UPDATED_BY_ATTRIBUTE","CREATED_BY_ATTRIBUTE","contentTypesUtils","constants","MEDIA_CREATE","MEDIA_UPDATE","MEDIA_DELETE","ALLOWED_WEBHOOK_EVENTS","ApplicationError","NotFoundError","errors","bytesToKbytes","fileUtils","strapi","sendMediaMetrics","data","_","has","isEmpty","caption","telemetry","send","alternativeText","createAndAssignTmpWorkingDirectoryToFiles","files","tmpWorkingDirectory","fse","mkdtemp","path","join","os","tmpdir","Array","isArray","forEach","file","filenameReservedRegex","windowsReservedNameRegex","isValidFilename","string","length","test","emitEvent","event","modelDef","getModel","FILE_MODEL_UID","sanitizedData","sanitize","sanitizers","defaultSanitizeOutput","schema","uid","eventHub","emit","media","formatFileInfo","filename","type","size","fileInfo","metas","fileService","getService","imageManipulationService","ext","extname","extension","usedName","name","normalize","basename","entity","folder","folderPath","getFolderPath","hash","generateFileName","mime","sizeInBytes","refId","ref","field","related","id","__type","__pivot","enhanceAndValidateFile","currentFile","originalFilename","mimetype","filepath","getStream","fs","createReadStream","optimize","isImage","isFaultyImage","isOptimizableImage","plugin","service","upload","opts","user","uploadedFiles","fileArray","fileInfoArray","doUpload","fileData","uploadFileAndPersist","Promise","all","map","idx","remove","uploadImage","getDimensions","generateThumbnail","generateResponsiveFormats","isResizableImage","width","height","assign","uploadThumbnail","thumbnailFile","set","uploadResponsiveFormat","format","key","uploadPromises","push","formats","config","get","checkFileSize","provider","add","updateFileInfo","dbFile","findOne","newName","isNil","newInfos","isUndefined","update","replace","delete","Object","keys","values","fileValues","res","db","query","where","create","populate","transform","findMany","findPage","getSettings","store","setSettings","value","responsiveDimensions","getConfiguration","setConfiguration","_uploadImage"],"mappings":"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"}
|
|
@@ -418,6 +418,7 @@ declare const _default: () => {
|
|
|
418
418
|
} | undefined)[]>;
|
|
419
419
|
generateThumbnail: (file: import("./types").UploadableFile) => Promise<import("./types").UploadableFile | null>;
|
|
420
420
|
optimize: (file: import("./types").UploadableFile) => Promise<import("./types").UploadableFile>;
|
|
421
|
+
generateFileName: (name: string) => string;
|
|
421
422
|
};
|
|
422
423
|
'api-upload-folder': {
|
|
423
424
|
getAPIUploadFolder: () => Promise<any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../server/src/index.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../server/src/index.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOxC,wBAQG"}
|
|
@@ -15,6 +15,7 @@ declare const _default: {
|
|
|
15
15
|
} | undefined)[]>;
|
|
16
16
|
generateThumbnail: (file: UploadableFile) => Promise<UploadableFile | null>;
|
|
17
17
|
optimize: (file: UploadableFile) => Promise<UploadableFile>;
|
|
18
|
+
generateFileName: (name: string) => string;
|
|
18
19
|
};
|
|
19
20
|
export default _default;
|
|
20
21
|
//# sourceMappingURL=image-manipulation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-manipulation.d.ts","sourceRoot":"","sources":["../../../../server/src/services/image-manipulation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"image-manipulation.d.ts","sourceRoot":"","sources":["../../../../server/src/services/image-manipulation.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;;;;;;;;;;;;;;;AAmSF,wBAUE"}
|
|
@@ -141,6 +141,7 @@ export declare const services: {
|
|
|
141
141
|
} | undefined)[]>;
|
|
142
142
|
generateThumbnail: (file: import("../types").UploadableFile) => Promise<import("../types").UploadableFile | null>;
|
|
143
143
|
optimize: (file: import("../types").UploadableFile) => Promise<import("../types").UploadableFile>;
|
|
144
|
+
generateFileName: (name: string) => string;
|
|
144
145
|
};
|
|
145
146
|
'api-upload-folder': {
|
|
146
147
|
getAPIUploadFolder: () => Promise<any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/services/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,QAAQ
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/services/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAUpB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../../server/src/services/upload.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../../server/src/services/upload.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,IAAI,EAAO,MAAM,eAAe,CAAC;AAK/C,OAAO,KAAK,EAAU,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAClF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AACvF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AAEzE,KAAK,IAAI,GAAG;IACV,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1B,KAAK,aAAa,GAAG;IACnB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,CAAC;qCAgB0B;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;+CAoErB;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,aAChE,QAAQ,QAAQ,CAAC,UACpB;QACL,KAAK,CAAC,EAAE,EAAE,CAAC;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,KACA,QAAQ,KAAK,cAAc,EAAE,WAAW,CAAC,CAAC;+BAiGxC;QACD,IAAI,EAAE,OAAO,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,KAAK,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;KAChC,SACM,aAAa;yBAiHhB,EAAE,8CACsC,QAAQ,SAC7C,aAAa;kBAyBhB,EAAE,kBACU;QAAE,IAAI,EAAE;YAAE,QAAQ,EAAE,QAAQ,CAAA;SAAE,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,SAC1D,aAAa;kBAkGD,EAAE;uBAWE,GAAG,KAAQ,QAAQ,IAAI,EAAE,CAAC;uBAM1B,GAAG;;;;;;;;;mBAMA,IAAI;;;;;;yBAiCJ,QAAQ;;;;;8BAoBH,iBAAiB;IAoBhD;;;OAGG;6BA/SgC,cAAc;;AAtNrD,wBAwgBE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/upload",
|
|
3
|
-
"version": "5.15.
|
|
3
|
+
"version": "5.15.1",
|
|
4
4
|
"description": "Makes it easy to upload images and files to your Strapi Application.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": {
|
|
@@ -61,10 +61,10 @@
|
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@mux/mux-player-react": "3.1.0",
|
|
64
|
-
"@strapi/design-system": "2.0.0-rc.
|
|
65
|
-
"@strapi/icons": "2.0.0-rc.
|
|
66
|
-
"@strapi/provider-upload-local": "5.15.
|
|
67
|
-
"@strapi/utils": "5.15.
|
|
64
|
+
"@strapi/design-system": "2.0.0-rc.25",
|
|
65
|
+
"@strapi/icons": "2.0.0-rc.25",
|
|
66
|
+
"@strapi/provider-upload-local": "5.15.1",
|
|
67
|
+
"@strapi/utils": "5.15.1",
|
|
68
68
|
"byte-size": "8.1.1",
|
|
69
69
|
"cropperjs": "1.6.1",
|
|
70
70
|
"date-fns": "2.30.0",
|
|
@@ -86,8 +86,8 @@
|
|
|
86
86
|
"yup": "0.32.9"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
|
-
"@strapi/admin": "5.15.
|
|
90
|
-
"@strapi/types": "5.15.
|
|
89
|
+
"@strapi/admin": "5.15.1",
|
|
90
|
+
"@strapi/types": "5.15.1",
|
|
91
91
|
"@testing-library/dom": "10.1.0",
|
|
92
92
|
"@testing-library/react": "15.0.7",
|
|
93
93
|
"@testing-library/user-event": "14.5.2",
|