@strapi/upload 5.15.0 → 5.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/admin/components/AssetCard/AssetCard.js +3 -2
  2. package/dist/admin/components/AssetCard/AssetCard.js.map +1 -1
  3. package/dist/admin/components/AssetCard/AssetCard.mjs +3 -2
  4. package/dist/admin/components/AssetCard/AssetCard.mjs.map +1 -1
  5. package/dist/admin/components/AssetCard/AssetCardBase.js +7 -2
  6. package/dist/admin/components/AssetCard/AssetCardBase.js.map +1 -1
  7. package/dist/admin/components/AssetCard/AssetCardBase.mjs +7 -2
  8. package/dist/admin/components/AssetCard/AssetCardBase.mjs.map +1 -1
  9. package/dist/admin/components/AssetDialog/AssetDialog.js +3 -1
  10. package/dist/admin/components/AssetDialog/AssetDialog.js.map +1 -1
  11. package/dist/admin/components/AssetDialog/AssetDialog.mjs +3 -1
  12. package/dist/admin/components/AssetDialog/AssetDialog.mjs.map +1 -1
  13. package/dist/admin/components/AssetGridList/AssetGridList.js +7 -1
  14. package/dist/admin/components/AssetGridList/AssetGridList.js.map +1 -1
  15. package/dist/admin/components/AssetGridList/AssetGridList.mjs +7 -1
  16. package/dist/admin/components/AssetGridList/AssetGridList.mjs.map +1 -1
  17. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.js +5 -1
  18. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.js.map +1 -1
  19. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs +5 -1
  20. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs.map +1 -1
  21. package/dist/admin/package.json.js +8 -8
  22. package/dist/admin/package.json.mjs +8 -8
  23. package/dist/admin/src/components/AssetCard/AssetCard.d.ts +2 -1
  24. package/dist/admin/src/components/AssetCard/AssetCardBase.d.ts +2 -1
  25. package/dist/admin/src/components/MediaLibraryInput/Carousel/CarouselAsset.d.ts +1 -1
  26. package/dist/server/services/image-manipulation.js +11 -1
  27. package/dist/server/services/image-manipulation.js.map +1 -1
  28. package/dist/server/services/image-manipulation.mjs +12 -2
  29. package/dist/server/services/image-manipulation.mjs.map +1 -1
  30. package/dist/server/services/upload.js +2 -10
  31. package/dist/server/services/upload.js.map +1 -1
  32. package/dist/server/services/upload.mjs +3 -11
  33. package/dist/server/services/upload.mjs.map +1 -1
  34. package/dist/server/src/index.d.ts +1 -0
  35. package/dist/server/src/index.d.ts.map +1 -1
  36. package/dist/server/src/services/image-manipulation.d.ts +1 -0
  37. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  38. package/dist/server/src/services/index.d.ts +1 -0
  39. package/dist/server/src/services/index.d.ts.map +1 -1
  40. package/dist/server/src/services/upload.d.ts.map +1 -1
  41. package/package.json +8 -8
@@ -1,9 +1,15 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { KeyboardNavigable, Box, Typography, Grid } from '@strapi/design-system';
3
+ import { styled } from 'styled-components';
3
4
  import { AssetCard } from '../AssetCard/AssetCard.mjs';
4
5
  import { Draggable } from './Draggable.mjs';
5
6
 
6
7
  // TODO: find a better naming convention for the file that was an index file before
8
+ const DraggableAssetCard = styled(AssetCard)`
9
+ && {
10
+ cursor: inherit;
11
+ }
12
+ `;
7
13
  const AssetGridList = ({ allowedTypes = [
8
14
  'files',
9
15
  'images',
@@ -35,7 +41,7 @@ const AssetGridList = ({ allowedTypes = [
35
41
  index: index,
36
42
  moveItem: onReorderAsset,
37
43
  id: asset.id,
38
- children: /*#__PURE__*/ jsx(AssetCard, {
44
+ children: /*#__PURE__*/ jsx(DraggableAssetCard, {
39
45
  allowedTypes: allowedTypes,
40
46
  asset: asset,
41
47
  isSelected: isSelected,
@@ -1 +1 @@
1
- {"version":3,"file":"AssetGridList.mjs","sources":["../../../../admin/src/components/AssetGridList/AssetGridList.tsx"],"sourcesContent":["// TODO: find a better naming convention for the file that was an index file before\nimport { Box, Grid, KeyboardNavigable, Typography } from '@strapi/design-system';\n\nimport { AssetCard } from '../AssetCard/AssetCard';\n\nimport { Draggable } from './Draggable';\n\nimport type { File } from '../../../../shared/contracts/files';\nimport type { AllowedTypes } from '../AssetCard/AssetCard';\n\nexport interface AssetGridListProps {\n allowedTypes?: AllowedTypes[];\n assets: File[];\n onEditAsset?: (asset: File) => void;\n onSelectAsset: (asset: File) => void;\n selectedAssets: File[];\n size?: 'S' | 'M';\n onReorderAsset?: (fromIndex: number, toIndex: number) => void;\n title?: string | null;\n}\n\nexport const AssetGridList = ({\n allowedTypes = ['files', 'images', 'videos', 'audios'],\n assets,\n onEditAsset,\n onSelectAsset,\n selectedAssets,\n size = 'M',\n onReorderAsset,\n title = null,\n}: AssetGridListProps) => {\n return (\n <KeyboardNavigable tagName=\"article\">\n {title && (\n <Box paddingTop={2} paddingBottom={2}>\n <Typography tag=\"h2\" variant=\"delta\" fontWeight=\"semiBold\">\n {title}\n </Typography>\n </Box>\n )}\n\n <Grid.Root gap={4}>\n {assets.map((asset, index) => {\n const isSelected = !!selectedAssets.find((currentAsset) => currentAsset.id === asset.id);\n\n if (onReorderAsset) {\n return (\n <Grid.Item key={asset.id} col={3} height=\"100%\">\n <Draggable index={index} moveItem={onReorderAsset} id={asset.id}>\n <AssetCard\n allowedTypes={allowedTypes}\n asset={asset}\n isSelected={isSelected}\n onEdit={onEditAsset ? () => onEditAsset(asset) : undefined}\n onSelect={() => onSelectAsset(asset)}\n size={size}\n />\n </Draggable>\n </Grid.Item>\n );\n }\n\n return (\n <Grid.Item col={3} key={asset.id} height=\"100%\" direction=\"column\" alignItems=\"stretch\">\n <AssetCard\n key={asset.id}\n allowedTypes={allowedTypes}\n asset={asset}\n isSelected={isSelected}\n onEdit={onEditAsset ? () => onEditAsset(asset) : undefined}\n onSelect={() => onSelectAsset(asset)}\n size={size}\n />\n </Grid.Item>\n );\n })}\n </Grid.Root>\n </KeyboardNavigable>\n );\n};\n"],"names":["AssetGridList","allowedTypes","assets","onEditAsset","onSelectAsset","selectedAssets","size","onReorderAsset","title","_jsxs","KeyboardNavigable","tagName","_jsx","Box","paddingTop","paddingBottom","Typography","tag","variant","fontWeight","Grid","Root","gap","map","asset","index","isSelected","find","currentAsset","id","Item","col","height","Draggable","moveItem","AssetCard","onEdit","undefined","onSelect","direction","alignItems"],"mappings":";;;;;AAAA;AAqBaA,MAAAA,aAAAA,GAAgB,CAAC,EAC5BC,YAAe,GAAA;AAAC,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA,QAAA;AAAU,IAAA;AAAS,CAAA,EACtDC,MAAM,EACNC,WAAW,EACXC,aAAa,EACbC,cAAc,EACdC,IAAAA,GAAO,GAAG,EACVC,cAAc,EACdC,KAAAA,GAAQ,IAAI,EACO,GAAA;AACnB,IAAA,qBACEC,IAACC,CAAAA,iBAAAA,EAAAA;QAAkBC,OAAQ,EAAA,SAAA;;AACxBH,YAAAA,KAAAA,kBACCI,GAACC,CAAAA,GAAAA,EAAAA;gBAAIC,UAAY,EAAA,CAAA;gBAAGC,aAAe,EAAA,CAAA;AACjC,gBAAA,QAAA,gBAAAH,GAACI,CAAAA,UAAAA,EAAAA;oBAAWC,GAAI,EAAA,IAAA;oBAAKC,OAAQ,EAAA,OAAA;oBAAQC,UAAW,EAAA,UAAA;AAC7CX,oBAAAA,QAAAA,EAAAA;;;AAKP,0BAAAI,GAAA,CAACQ,KAAKC,IAAI,EAAA;gBAACC,GAAK,EAAA,CAAA;0BACbpB,MAAOqB,CAAAA,GAAG,CAAC,CAACC,KAAOC,EAAAA,KAAAA,GAAAA;AAClB,oBAAA,MAAMC,UAAa,GAAA,CAAC,CAACrB,cAAAA,CAAesB,IAAI,CAAC,CAACC,YAAAA,GAAiBA,YAAaC,CAAAA,EAAE,KAAKL,KAAAA,CAAMK,EAAE,CAAA;AAEvF,oBAAA,IAAItB,cAAgB,EAAA;wBAClB,qBACEK,GAAA,CAACQ,KAAKU,IAAI,EAAA;4BAAgBC,GAAK,EAAA,CAAA;4BAAGC,MAAO,EAAA,MAAA;AACvC,4BAAA,QAAA,gBAAApB,GAACqB,CAAAA,SAAAA,EAAAA;gCAAUR,KAAOA,EAAAA,KAAAA;gCAAOS,QAAU3B,EAAAA,cAAAA;AAAgBsB,gCAAAA,EAAAA,EAAIL,MAAMK,EAAE;AAC7D,gCAAA,QAAA,gBAAAjB,GAACuB,CAAAA,SAAAA,EAAAA;oCACClC,YAAcA,EAAAA,YAAAA;oCACduB,KAAOA,EAAAA,KAAAA;oCACPE,UAAYA,EAAAA,UAAAA;oCACZU,MAAQjC,EAAAA,WAAAA,GAAc,IAAMA,WAAAA,CAAYqB,KAASa,CAAAA,GAAAA,SAAAA;AACjDC,oCAAAA,QAAAA,EAAU,IAAMlC,aAAcoB,CAAAA,KAAAA,CAAAA;oCAC9BlB,IAAMA,EAAAA;;;AARIkB,yBAAAA,EAAAA,KAAAA,CAAMK,EAAE,CAAA;AAa5B;oBAEA,qBACEjB,GAAA,CAACQ,KAAKU,IAAI,EAAA;wBAACC,GAAK,EAAA,CAAA;wBAAkBC,MAAO,EAAA,MAAA;wBAAOO,SAAU,EAAA,QAAA;wBAASC,UAAW,EAAA,SAAA;AAC5E,wBAAA,QAAA,gBAAA5B,GAACuB,CAAAA,SAAAA,EAAAA;4BAEClC,YAAcA,EAAAA,YAAAA;4BACduB,KAAOA,EAAAA,KAAAA;4BACPE,UAAYA,EAAAA,UAAAA;4BACZU,MAAQjC,EAAAA,WAAAA,GAAc,IAAMA,WAAAA,CAAYqB,KAASa,CAAAA,GAAAA,SAAAA;AACjDC,4BAAAA,QAAAA,EAAU,IAAMlC,aAAcoB,CAAAA,KAAAA,CAAAA;4BAC9BlB,IAAMA,EAAAA;AANDkB,yBAAAA,EAAAA,KAAAA,CAAMK,EAAE;AAFOL,qBAAAA,EAAAA,KAAAA,CAAMK,EAAE,CAAA;AAYpC,iBAAA;;;;AAIR;;;;"}
1
+ {"version":3,"file":"AssetGridList.mjs","sources":["../../../../admin/src/components/AssetGridList/AssetGridList.tsx"],"sourcesContent":["// TODO: find a better naming convention for the file that was an index file before\nimport { Box, Grid, KeyboardNavigable, Typography } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\nimport { AssetCard } from '../AssetCard/AssetCard';\n\nimport { Draggable } from './Draggable';\n\nimport type { File } from '../../../../shared/contracts/files';\nimport type { AllowedTypes } from '../AssetCard/AssetCard';\n\nconst DraggableAssetCard = styled(AssetCard)`\n && {\n cursor: inherit;\n }\n`;\n\nexport interface AssetGridListProps {\n allowedTypes?: AllowedTypes[];\n assets: File[];\n onEditAsset?: (asset: File) => void;\n onSelectAsset: (asset: File) => void;\n selectedAssets: File[];\n size?: 'S' | 'M';\n onReorderAsset?: (fromIndex: number, toIndex: number) => void;\n title?: string | null;\n}\n\nexport const AssetGridList = ({\n allowedTypes = ['files', 'images', 'videos', 'audios'],\n assets,\n onEditAsset,\n onSelectAsset,\n selectedAssets,\n size = 'M',\n onReorderAsset,\n title = null,\n}: AssetGridListProps) => {\n return (\n <KeyboardNavigable tagName=\"article\">\n {title && (\n <Box paddingTop={2} paddingBottom={2}>\n <Typography tag=\"h2\" variant=\"delta\" fontWeight=\"semiBold\">\n {title}\n </Typography>\n </Box>\n )}\n\n <Grid.Root gap={4}>\n {assets.map((asset, index) => {\n const isSelected = !!selectedAssets.find((currentAsset) => currentAsset.id === asset.id);\n\n if (onReorderAsset) {\n return (\n <Grid.Item key={asset.id} col={3} height=\"100%\">\n <Draggable index={index} moveItem={onReorderAsset} id={asset.id}>\n <DraggableAssetCard\n allowedTypes={allowedTypes}\n asset={asset}\n isSelected={isSelected}\n onEdit={onEditAsset ? () => onEditAsset(asset) : undefined}\n onSelect={() => onSelectAsset(asset)}\n size={size}\n />\n </Draggable>\n </Grid.Item>\n );\n }\n\n return (\n <Grid.Item col={3} key={asset.id} height=\"100%\" direction=\"column\" alignItems=\"stretch\">\n <AssetCard\n key={asset.id}\n allowedTypes={allowedTypes}\n asset={asset}\n isSelected={isSelected}\n onEdit={onEditAsset ? () => onEditAsset(asset) : undefined}\n onSelect={() => onSelectAsset(asset)}\n size={size}\n />\n </Grid.Item>\n );\n })}\n </Grid.Root>\n </KeyboardNavigable>\n );\n};\n"],"names":["DraggableAssetCard","styled","AssetCard","AssetGridList","allowedTypes","assets","onEditAsset","onSelectAsset","selectedAssets","size","onReorderAsset","title","_jsxs","KeyboardNavigable","tagName","_jsx","Box","paddingTop","paddingBottom","Typography","tag","variant","fontWeight","Grid","Root","gap","map","asset","index","isSelected","find","currentAsset","id","Item","col","height","Draggable","moveItem","onEdit","undefined","onSelect","direction","alignItems"],"mappings":";;;;;;AAAA;AAWA,MAAMA,kBAAAA,GAAqBC,MAAOC,CAAAA,SAAAA,CAAU;;;;AAI5C,CAAC;AAaYC,MAAAA,aAAAA,GAAgB,CAAC,EAC5BC,YAAe,GAAA;AAAC,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA,QAAA;AAAU,IAAA;AAAS,CAAA,EACtDC,MAAM,EACNC,WAAW,EACXC,aAAa,EACbC,cAAc,EACdC,IAAAA,GAAO,GAAG,EACVC,cAAc,EACdC,KAAAA,GAAQ,IAAI,EACO,GAAA;AACnB,IAAA,qBACEC,IAACC,CAAAA,iBAAAA,EAAAA;QAAkBC,OAAQ,EAAA,SAAA;;AACxBH,YAAAA,KAAAA,kBACCI,GAACC,CAAAA,GAAAA,EAAAA;gBAAIC,UAAY,EAAA,CAAA;gBAAGC,aAAe,EAAA,CAAA;AACjC,gBAAA,QAAA,gBAAAH,GAACI,CAAAA,UAAAA,EAAAA;oBAAWC,GAAI,EAAA,IAAA;oBAAKC,OAAQ,EAAA,OAAA;oBAAQC,UAAW,EAAA,UAAA;AAC7CX,oBAAAA,QAAAA,EAAAA;;;AAKP,0BAAAI,GAAA,CAACQ,KAAKC,IAAI,EAAA;gBAACC,GAAK,EAAA,CAAA;0BACbpB,MAAOqB,CAAAA,GAAG,CAAC,CAACC,KAAOC,EAAAA,KAAAA,GAAAA;AAClB,oBAAA,MAAMC,UAAa,GAAA,CAAC,CAACrB,cAAAA,CAAesB,IAAI,CAAC,CAACC,YAAAA,GAAiBA,YAAaC,CAAAA,EAAE,KAAKL,KAAAA,CAAMK,EAAE,CAAA;AAEvF,oBAAA,IAAItB,cAAgB,EAAA;wBAClB,qBACEK,GAAA,CAACQ,KAAKU,IAAI,EAAA;4BAAgBC,GAAK,EAAA,CAAA;4BAAGC,MAAO,EAAA,MAAA;AACvC,4BAAA,QAAA,gBAAApB,GAACqB,CAAAA,SAAAA,EAAAA;gCAAUR,KAAOA,EAAAA,KAAAA;gCAAOS,QAAU3B,EAAAA,cAAAA;AAAgBsB,gCAAAA,EAAAA,EAAIL,MAAMK,EAAE;AAC7D,gCAAA,QAAA,gBAAAjB,GAACf,CAAAA,kBAAAA,EAAAA;oCACCI,YAAcA,EAAAA,YAAAA;oCACduB,KAAOA,EAAAA,KAAAA;oCACPE,UAAYA,EAAAA,UAAAA;oCACZS,MAAQhC,EAAAA,WAAAA,GAAc,IAAMA,WAAAA,CAAYqB,KAASY,CAAAA,GAAAA,SAAAA;AACjDC,oCAAAA,QAAAA,EAAU,IAAMjC,aAAcoB,CAAAA,KAAAA,CAAAA;oCAC9BlB,IAAMA,EAAAA;;;AARIkB,yBAAAA,EAAAA,KAAAA,CAAMK,EAAE,CAAA;AAa5B;oBAEA,qBACEjB,GAAA,CAACQ,KAAKU,IAAI,EAAA;wBAACC,GAAK,EAAA,CAAA;wBAAkBC,MAAO,EAAA,MAAA;wBAAOM,SAAU,EAAA,QAAA;wBAASC,UAAW,EAAA,SAAA;AAC5E,wBAAA,QAAA,gBAAA3B,GAACb,CAAAA,SAAAA,EAAAA;4BAECE,YAAcA,EAAAA,YAAAA;4BACduB,KAAOA,EAAAA,KAAAA;4BACPE,UAAYA,EAAAA,UAAAA;4BACZS,MAAQhC,EAAAA,WAAAA,GAAc,IAAMA,WAAAA,CAAYqB,KAASY,CAAAA,GAAAA,SAAAA;AACjDC,4BAAAA,QAAAA,EAAU,IAAMjC,aAAcoB,CAAAA,KAAAA,CAAAA;4BAC9BlB,IAAMA,EAAAA;AANDkB,yBAAAA,EAAAA,KAAAA,CAAMK,EAAE;AAFOL,qBAAAA,EAAAA,KAAAA,CAAMK,EAAE,CAAA;AAYpC,iBAAA;;;;AAIR;;;;"}
@@ -49,11 +49,15 @@ const CarouselAsset = ({ asset })=>{
49
49
  });
50
50
  }
51
51
  if (asset.mime?.includes(constants.AssetType.Image)) {
52
+ const assetUrl = createAssetUrl.createAssetUrl(asset, true);
53
+ if (!assetUrl) return null;
54
+ // Adding a param to the url to bust the cache and force the refresh of the image when replaced
55
+ const cacheBustedUrl = `${assetUrl}${assetUrl.includes('?') ? '&' : '?'}updatedAt=${asset.updatedAt}`;
52
56
  return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
53
57
  tag: "img",
54
58
  maxHeight: "100%",
55
59
  maxWidth: "100%",
56
- src: createAssetUrl.createAssetUrl(asset, true),
60
+ src: cacheBustedUrl,
57
61
  alt: asset.alternativeText || asset.name
58
62
  });
59
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CarouselAsset.js","sources":["../../../../../admin/src/components/MediaLibraryInput/Carousel/CarouselAsset.tsx"],"sourcesContent":["import { Box, Flex } from '@strapi/design-system';\nimport { File, FilePdf } from '@strapi/icons';\nimport { styled } from 'styled-components';\n\nimport { AssetType } from '../../../constants';\nimport { createAssetUrl } from '../../../utils';\nimport { AudioPreview } from '../../AssetCard/AudioPreview';\nimport { VideoPreview } from '../../AssetCard/VideoPreview';\n\nimport type { File as FileAsset } from '../../../../../shared/contracts/files';\n\nconst DocAsset = styled(Flex)`\n background: linear-gradient(180deg, #ffffff 0%, #f6f6f9 121.48%);\n`;\n\nconst VideoPreviewWrapper = styled(Box)`\n canvas,\n video {\n max-width: 100%;\n height: 124px;\n }\n`;\n\nconst AudioPreviewWrapper = styled(Box)`\n canvas,\n audio {\n max-width: 100%;\n }\n`;\n\nexport const CarouselAsset = ({ asset }: { asset: FileAsset }) => {\n if (asset.mime?.includes(AssetType.Video)) {\n return (\n <VideoPreviewWrapper height=\"100%\">\n <VideoPreview\n url={createAssetUrl(asset, true)!}\n mime={asset.mime}\n alt={asset.alternativeText || asset.name}\n />\n </VideoPreviewWrapper>\n );\n }\n\n if (asset.mime?.includes(AssetType.Audio)) {\n return (\n <AudioPreviewWrapper>\n <AudioPreview\n url={createAssetUrl(asset, true)!}\n alt={asset.alternativeText || asset.name}\n />\n </AudioPreviewWrapper>\n );\n }\n\n if (asset.mime?.includes(AssetType.Image)) {\n return (\n <Box\n tag=\"img\"\n maxHeight=\"100%\"\n maxWidth=\"100%\"\n src={createAssetUrl(asset, true)}\n alt={asset.alternativeText || asset.name}\n />\n );\n }\n\n return (\n <DocAsset width=\"100%\" height=\"100%\" justifyContent=\"center\" hasRadius>\n {asset.ext?.includes('pdf') ? (\n <FilePdf aria-label={asset.alternativeText || asset.name} width=\"24px\" height=\"32px\" />\n ) : (\n <File aria-label={asset.alternativeText || asset.name} width=\"24px\" height=\"32px\" />\n )}\n </DocAsset>\n );\n};\n"],"names":["DocAsset","styled","Flex","VideoPreviewWrapper","Box","AudioPreviewWrapper","CarouselAsset","asset","mime","includes","AssetType","Video","_jsx","height","VideoPreview","url","createAssetUrl","alt","alternativeText","name","Audio","AudioPreview","Image","tag","maxHeight","maxWidth","src","width","justifyContent","hasRadius","ext","FilePdf","aria-label","File"],"mappings":";;;;;;;;;;;;;;;AAWA,MAAMA,QAAAA,GAAWC,uBAAOC,CAAAA,iBAAAA,CAAK;;AAE7B,CAAC;AAED,MAAMC,mBAAAA,GAAsBF,uBAAOG,CAAAA,gBAAAA,CAAI;;;;;;AAMvC,CAAC;AAED,MAAMC,mBAAAA,GAAsBJ,uBAAOG,CAAAA,gBAAAA,CAAI;;;;;AAKvC,CAAC;AAEYE,MAAAA,aAAAA,GAAgB,CAAC,EAAEC,KAAK,EAAwB,GAAA;AAC3D,IAAA,IAAIA,MAAMC,IAAI,EAAEC,QAASC,CAAAA,mBAAAA,CAAUC,KAAK,CAAG,EAAA;AACzC,QAAA,qBACEC,cAACT,CAAAA,mBAAAA,EAAAA;YAAoBU,MAAO,EAAA,MAAA;AAC1B,YAAA,QAAA,gBAAAD,cAACE,CAAAA,yBAAAA,EAAAA;AACCC,gBAAAA,GAAAA,EAAKC,8BAAeT,KAAO,EAAA,IAAA,CAAA;AAC3BC,gBAAAA,IAAAA,EAAMD,MAAMC,IAAI;AAChBS,gBAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;;AAI5C;AAEA,IAAA,IAAIZ,MAAMC,IAAI,EAAEC,QAASC,CAAAA,mBAAAA,CAAUU,KAAK,CAAG,EAAA;AACzC,QAAA,qBACER,cAACP,CAAAA,mBAAAA,EAAAA;AACC,YAAA,QAAA,gBAAAO,cAACS,CAAAA,yBAAAA,EAAAA;AACCN,gBAAAA,GAAAA,EAAKC,8BAAeT,KAAO,EAAA,IAAA,CAAA;AAC3BU,gBAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;;AAI5C;AAEA,IAAA,IAAIZ,MAAMC,IAAI,EAAEC,QAASC,CAAAA,mBAAAA,CAAUY,KAAK,CAAG,EAAA;AACzC,QAAA,qBACEV,cAACR,CAAAA,gBAAAA,EAAAA;YACCmB,GAAI,EAAA,KAAA;YACJC,SAAU,EAAA,MAAA;YACVC,QAAS,EAAA,MAAA;AACTC,YAAAA,GAAAA,EAAKV,8BAAeT,KAAO,EAAA,IAAA,CAAA;AAC3BU,YAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;AAG1C;AAEA,IAAA,qBACEP,cAACZ,CAAAA,QAAAA,EAAAA;QAAS2B,KAAM,EAAA,MAAA;QAAOd,MAAO,EAAA,MAAA;QAAOe,cAAe,EAAA,QAAA;QAASC,SAAS,EAAA,IAAA;AACnEtB,QAAAA,QAAAA,EAAAA,KAAAA,CAAMuB,GAAG,EAAErB,QAAS,CAAA,KAAA,CAAA,iBACnBG,cAACmB,CAAAA,aAAAA,EAAAA;AAAQC,YAAAA,YAAAA,EAAYzB,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY,IAAI;YAAEQ,KAAM,EAAA,MAAA;YAAOd,MAAO,EAAA;2BAE9ED,cAACqB,CAAAA,UAAAA,EAAAA;AAAKD,YAAAA,YAAAA,EAAYzB,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY,IAAI;YAAEQ,KAAM,EAAA,MAAA;YAAOd,MAAO,EAAA;;;AAInF;;;;"}
1
+ {"version":3,"file":"CarouselAsset.js","sources":["../../../../../admin/src/components/MediaLibraryInput/Carousel/CarouselAsset.tsx"],"sourcesContent":["import { Box, Flex } from '@strapi/design-system';\nimport { File, FilePdf } from '@strapi/icons';\nimport { styled } from 'styled-components';\n\nimport { AssetType } from '../../../constants';\nimport { createAssetUrl } from '../../../utils';\nimport { AudioPreview } from '../../AssetCard/AudioPreview';\nimport { VideoPreview } from '../../AssetCard/VideoPreview';\n\nimport type { File as FileAsset } from '../../../../../shared/contracts/files';\n\nconst DocAsset = styled(Flex)`\n background: linear-gradient(180deg, #ffffff 0%, #f6f6f9 121.48%);\n`;\n\nconst VideoPreviewWrapper = styled(Box)`\n canvas,\n video {\n max-width: 100%;\n height: 124px;\n }\n`;\n\nconst AudioPreviewWrapper = styled(Box)`\n canvas,\n audio {\n max-width: 100%;\n }\n`;\n\nexport const CarouselAsset = ({ asset }: { asset: FileAsset }) => {\n if (asset.mime?.includes(AssetType.Video)) {\n return (\n <VideoPreviewWrapper height=\"100%\">\n <VideoPreview\n url={createAssetUrl(asset, true)!}\n mime={asset.mime}\n alt={asset.alternativeText || asset.name}\n />\n </VideoPreviewWrapper>\n );\n }\n\n if (asset.mime?.includes(AssetType.Audio)) {\n return (\n <AudioPreviewWrapper>\n <AudioPreview\n url={createAssetUrl(asset, true)!}\n alt={asset.alternativeText || asset.name}\n />\n </AudioPreviewWrapper>\n );\n }\n\n if (asset.mime?.includes(AssetType.Image)) {\n const assetUrl = createAssetUrl(asset, true);\n if (!assetUrl) return null;\n\n // Adding a param to the url to bust the cache and force the refresh of the image when replaced\n const cacheBustedUrl = `${assetUrl}${assetUrl.includes('?') ? '&' : '?'}updatedAt=${asset.updatedAt}`;\n\n return (\n <Box\n tag=\"img\"\n maxHeight=\"100%\"\n maxWidth=\"100%\"\n src={cacheBustedUrl}\n alt={asset.alternativeText || asset.name}\n />\n );\n }\n\n return (\n <DocAsset width=\"100%\" height=\"100%\" justifyContent=\"center\" hasRadius>\n {asset.ext?.includes('pdf') ? (\n <FilePdf aria-label={asset.alternativeText || asset.name} width=\"24px\" height=\"32px\" />\n ) : (\n <File aria-label={asset.alternativeText || asset.name} width=\"24px\" height=\"32px\" />\n )}\n </DocAsset>\n );\n};\n"],"names":["DocAsset","styled","Flex","VideoPreviewWrapper","Box","AudioPreviewWrapper","CarouselAsset","asset","mime","includes","AssetType","Video","_jsx","height","VideoPreview","url","createAssetUrl","alt","alternativeText","name","Audio","AudioPreview","Image","assetUrl","cacheBustedUrl","updatedAt","tag","maxHeight","maxWidth","src","width","justifyContent","hasRadius","ext","FilePdf","aria-label","File"],"mappings":";;;;;;;;;;;;;;;AAWA,MAAMA,QAAAA,GAAWC,uBAAOC,CAAAA,iBAAAA,CAAK;;AAE7B,CAAC;AAED,MAAMC,mBAAAA,GAAsBF,uBAAOG,CAAAA,gBAAAA,CAAI;;;;;;AAMvC,CAAC;AAED,MAAMC,mBAAAA,GAAsBJ,uBAAOG,CAAAA,gBAAAA,CAAI;;;;;AAKvC,CAAC;AAEYE,MAAAA,aAAAA,GAAgB,CAAC,EAAEC,KAAK,EAAwB,GAAA;AAC3D,IAAA,IAAIA,MAAMC,IAAI,EAAEC,QAASC,CAAAA,mBAAAA,CAAUC,KAAK,CAAG,EAAA;AACzC,QAAA,qBACEC,cAACT,CAAAA,mBAAAA,EAAAA;YAAoBU,MAAO,EAAA,MAAA;AAC1B,YAAA,QAAA,gBAAAD,cAACE,CAAAA,yBAAAA,EAAAA;AACCC,gBAAAA,GAAAA,EAAKC,8BAAeT,KAAO,EAAA,IAAA,CAAA;AAC3BC,gBAAAA,IAAAA,EAAMD,MAAMC,IAAI;AAChBS,gBAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;;AAI5C;AAEA,IAAA,IAAIZ,MAAMC,IAAI,EAAEC,QAASC,CAAAA,mBAAAA,CAAUU,KAAK,CAAG,EAAA;AACzC,QAAA,qBACER,cAACP,CAAAA,mBAAAA,EAAAA;AACC,YAAA,QAAA,gBAAAO,cAACS,CAAAA,yBAAAA,EAAAA;AACCN,gBAAAA,GAAAA,EAAKC,8BAAeT,KAAO,EAAA,IAAA,CAAA;AAC3BU,gBAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;;AAI5C;AAEA,IAAA,IAAIZ,MAAMC,IAAI,EAAEC,QAASC,CAAAA,mBAAAA,CAAUY,KAAK,CAAG,EAAA;QACzC,MAAMC,QAAAA,GAAWP,8BAAeT,KAAO,EAAA,IAAA,CAAA;QACvC,IAAI,CAACgB,UAAU,OAAO,IAAA;;AAGtB,QAAA,MAAMC,iBAAiB,CAAC,EAAED,QAAS,CAAA,EAAEA,SAASd,QAAQ,CAAC,GAAO,CAAA,GAAA,GAAA,GAAM,IAAI,UAAU,EAAEF,KAAMkB,CAAAA,SAAS,CAAC,CAAC;AAErG,QAAA,qBACEb,cAACR,CAAAA,gBAAAA,EAAAA;YACCsB,GAAI,EAAA,KAAA;YACJC,SAAU,EAAA,MAAA;YACVC,QAAS,EAAA,MAAA;YACTC,GAAKL,EAAAA,cAAAA;AACLP,YAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;AAG1C;AAEA,IAAA,qBACEP,cAACZ,CAAAA,QAAAA,EAAAA;QAAS8B,KAAM,EAAA,MAAA;QAAOjB,MAAO,EAAA,MAAA;QAAOkB,cAAe,EAAA,QAAA;QAASC,SAAS,EAAA,IAAA;AACnEzB,QAAAA,QAAAA,EAAAA,KAAAA,CAAM0B,GAAG,EAAExB,QAAS,CAAA,KAAA,CAAA,iBACnBG,cAACsB,CAAAA,aAAAA,EAAAA;AAAQC,YAAAA,YAAAA,EAAY5B,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY,IAAI;YAAEW,KAAM,EAAA,MAAA;YAAOjB,MAAO,EAAA;2BAE9ED,cAACwB,CAAAA,UAAAA,EAAAA;AAAKD,YAAAA,YAAAA,EAAY5B,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY,IAAI;YAAEW,KAAM,EAAA,MAAA;YAAOjB,MAAO,EAAA;;;AAInF;;;;"}
@@ -47,11 +47,15 @@ const CarouselAsset = ({ asset })=>{
47
47
  });
48
48
  }
49
49
  if (asset.mime?.includes(AssetType.Image)) {
50
+ const assetUrl = createAssetUrl(asset, true);
51
+ if (!assetUrl) return null;
52
+ // Adding a param to the url to bust the cache and force the refresh of the image when replaced
53
+ const cacheBustedUrl = `${assetUrl}${assetUrl.includes('?') ? '&' : '?'}updatedAt=${asset.updatedAt}`;
50
54
  return /*#__PURE__*/ jsx(Box, {
51
55
  tag: "img",
52
56
  maxHeight: "100%",
53
57
  maxWidth: "100%",
54
- src: createAssetUrl(asset, true),
58
+ src: cacheBustedUrl,
55
59
  alt: asset.alternativeText || asset.name
56
60
  });
57
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CarouselAsset.mjs","sources":["../../../../../admin/src/components/MediaLibraryInput/Carousel/CarouselAsset.tsx"],"sourcesContent":["import { Box, Flex } from '@strapi/design-system';\nimport { File, FilePdf } from '@strapi/icons';\nimport { styled } from 'styled-components';\n\nimport { AssetType } from '../../../constants';\nimport { createAssetUrl } from '../../../utils';\nimport { AudioPreview } from '../../AssetCard/AudioPreview';\nimport { VideoPreview } from '../../AssetCard/VideoPreview';\n\nimport type { File as FileAsset } from '../../../../../shared/contracts/files';\n\nconst DocAsset = styled(Flex)`\n background: linear-gradient(180deg, #ffffff 0%, #f6f6f9 121.48%);\n`;\n\nconst VideoPreviewWrapper = styled(Box)`\n canvas,\n video {\n max-width: 100%;\n height: 124px;\n }\n`;\n\nconst AudioPreviewWrapper = styled(Box)`\n canvas,\n audio {\n max-width: 100%;\n }\n`;\n\nexport const CarouselAsset = ({ asset }: { asset: FileAsset }) => {\n if (asset.mime?.includes(AssetType.Video)) {\n return (\n <VideoPreviewWrapper height=\"100%\">\n <VideoPreview\n url={createAssetUrl(asset, true)!}\n mime={asset.mime}\n alt={asset.alternativeText || asset.name}\n />\n </VideoPreviewWrapper>\n );\n }\n\n if (asset.mime?.includes(AssetType.Audio)) {\n return (\n <AudioPreviewWrapper>\n <AudioPreview\n url={createAssetUrl(asset, true)!}\n alt={asset.alternativeText || asset.name}\n />\n </AudioPreviewWrapper>\n );\n }\n\n if (asset.mime?.includes(AssetType.Image)) {\n return (\n <Box\n tag=\"img\"\n maxHeight=\"100%\"\n maxWidth=\"100%\"\n src={createAssetUrl(asset, true)}\n alt={asset.alternativeText || asset.name}\n />\n );\n }\n\n return (\n <DocAsset width=\"100%\" height=\"100%\" justifyContent=\"center\" hasRadius>\n {asset.ext?.includes('pdf') ? (\n <FilePdf aria-label={asset.alternativeText || asset.name} width=\"24px\" height=\"32px\" />\n ) : (\n <File aria-label={asset.alternativeText || asset.name} width=\"24px\" height=\"32px\" />\n )}\n </DocAsset>\n );\n};\n"],"names":["DocAsset","styled","Flex","VideoPreviewWrapper","Box","AudioPreviewWrapper","CarouselAsset","asset","mime","includes","AssetType","Video","_jsx","height","VideoPreview","url","createAssetUrl","alt","alternativeText","name","Audio","AudioPreview","Image","tag","maxHeight","maxWidth","src","width","justifyContent","hasRadius","ext","FilePdf","aria-label","File"],"mappings":";;;;;;;;;;;;;AAWA,MAAMA,QAAAA,GAAWC,MAAOC,CAAAA,IAAAA,CAAK;;AAE7B,CAAC;AAED,MAAMC,mBAAAA,GAAsBF,MAAOG,CAAAA,GAAAA,CAAI;;;;;;AAMvC,CAAC;AAED,MAAMC,mBAAAA,GAAsBJ,MAAOG,CAAAA,GAAAA,CAAI;;;;;AAKvC,CAAC;AAEYE,MAAAA,aAAAA,GAAgB,CAAC,EAAEC,KAAK,EAAwB,GAAA;AAC3D,IAAA,IAAIA,MAAMC,IAAI,EAAEC,QAASC,CAAAA,SAAAA,CAAUC,KAAK,CAAG,EAAA;AACzC,QAAA,qBACEC,GAACT,CAAAA,mBAAAA,EAAAA;YAAoBU,MAAO,EAAA,MAAA;AAC1B,YAAA,QAAA,gBAAAD,GAACE,CAAAA,YAAAA,EAAAA;AACCC,gBAAAA,GAAAA,EAAKC,eAAeT,KAAO,EAAA,IAAA,CAAA;AAC3BC,gBAAAA,IAAAA,EAAMD,MAAMC,IAAI;AAChBS,gBAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;;AAI5C;AAEA,IAAA,IAAIZ,MAAMC,IAAI,EAAEC,QAASC,CAAAA,SAAAA,CAAUU,KAAK,CAAG,EAAA;AACzC,QAAA,qBACER,GAACP,CAAAA,mBAAAA,EAAAA;AACC,YAAA,QAAA,gBAAAO,GAACS,CAAAA,YAAAA,EAAAA;AACCN,gBAAAA,GAAAA,EAAKC,eAAeT,KAAO,EAAA,IAAA,CAAA;AAC3BU,gBAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;;AAI5C;AAEA,IAAA,IAAIZ,MAAMC,IAAI,EAAEC,QAASC,CAAAA,SAAAA,CAAUY,KAAK,CAAG,EAAA;AACzC,QAAA,qBACEV,GAACR,CAAAA,GAAAA,EAAAA;YACCmB,GAAI,EAAA,KAAA;YACJC,SAAU,EAAA,MAAA;YACVC,QAAS,EAAA,MAAA;AACTC,YAAAA,GAAAA,EAAKV,eAAeT,KAAO,EAAA,IAAA,CAAA;AAC3BU,YAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;AAG1C;AAEA,IAAA,qBACEP,GAACZ,CAAAA,QAAAA,EAAAA;QAAS2B,KAAM,EAAA,MAAA;QAAOd,MAAO,EAAA,MAAA;QAAOe,cAAe,EAAA,QAAA;QAASC,SAAS,EAAA,IAAA;AACnEtB,QAAAA,QAAAA,EAAAA,KAAAA,CAAMuB,GAAG,EAAErB,QAAS,CAAA,KAAA,CAAA,iBACnBG,GAACmB,CAAAA,OAAAA,EAAAA;AAAQC,YAAAA,YAAAA,EAAYzB,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY,IAAI;YAAEQ,KAAM,EAAA,MAAA;YAAOd,MAAO,EAAA;2BAE9ED,GAACqB,CAAAA,IAAAA,EAAAA;AAAKD,YAAAA,YAAAA,EAAYzB,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY,IAAI;YAAEQ,KAAM,EAAA,MAAA;YAAOd,MAAO,EAAA;;;AAInF;;;;"}
1
+ {"version":3,"file":"CarouselAsset.mjs","sources":["../../../../../admin/src/components/MediaLibraryInput/Carousel/CarouselAsset.tsx"],"sourcesContent":["import { Box, Flex } from '@strapi/design-system';\nimport { File, FilePdf } from '@strapi/icons';\nimport { styled } from 'styled-components';\n\nimport { AssetType } from '../../../constants';\nimport { createAssetUrl } from '../../../utils';\nimport { AudioPreview } from '../../AssetCard/AudioPreview';\nimport { VideoPreview } from '../../AssetCard/VideoPreview';\n\nimport type { File as FileAsset } from '../../../../../shared/contracts/files';\n\nconst DocAsset = styled(Flex)`\n background: linear-gradient(180deg, #ffffff 0%, #f6f6f9 121.48%);\n`;\n\nconst VideoPreviewWrapper = styled(Box)`\n canvas,\n video {\n max-width: 100%;\n height: 124px;\n }\n`;\n\nconst AudioPreviewWrapper = styled(Box)`\n canvas,\n audio {\n max-width: 100%;\n }\n`;\n\nexport const CarouselAsset = ({ asset }: { asset: FileAsset }) => {\n if (asset.mime?.includes(AssetType.Video)) {\n return (\n <VideoPreviewWrapper height=\"100%\">\n <VideoPreview\n url={createAssetUrl(asset, true)!}\n mime={asset.mime}\n alt={asset.alternativeText || asset.name}\n />\n </VideoPreviewWrapper>\n );\n }\n\n if (asset.mime?.includes(AssetType.Audio)) {\n return (\n <AudioPreviewWrapper>\n <AudioPreview\n url={createAssetUrl(asset, true)!}\n alt={asset.alternativeText || asset.name}\n />\n </AudioPreviewWrapper>\n );\n }\n\n if (asset.mime?.includes(AssetType.Image)) {\n const assetUrl = createAssetUrl(asset, true);\n if (!assetUrl) return null;\n\n // Adding a param to the url to bust the cache and force the refresh of the image when replaced\n const cacheBustedUrl = `${assetUrl}${assetUrl.includes('?') ? '&' : '?'}updatedAt=${asset.updatedAt}`;\n\n return (\n <Box\n tag=\"img\"\n maxHeight=\"100%\"\n maxWidth=\"100%\"\n src={cacheBustedUrl}\n alt={asset.alternativeText || asset.name}\n />\n );\n }\n\n return (\n <DocAsset width=\"100%\" height=\"100%\" justifyContent=\"center\" hasRadius>\n {asset.ext?.includes('pdf') ? (\n <FilePdf aria-label={asset.alternativeText || asset.name} width=\"24px\" height=\"32px\" />\n ) : (\n <File aria-label={asset.alternativeText || asset.name} width=\"24px\" height=\"32px\" />\n )}\n </DocAsset>\n );\n};\n"],"names":["DocAsset","styled","Flex","VideoPreviewWrapper","Box","AudioPreviewWrapper","CarouselAsset","asset","mime","includes","AssetType","Video","_jsx","height","VideoPreview","url","createAssetUrl","alt","alternativeText","name","Audio","AudioPreview","Image","assetUrl","cacheBustedUrl","updatedAt","tag","maxHeight","maxWidth","src","width","justifyContent","hasRadius","ext","FilePdf","aria-label","File"],"mappings":";;;;;;;;;;;;;AAWA,MAAMA,QAAAA,GAAWC,MAAOC,CAAAA,IAAAA,CAAK;;AAE7B,CAAC;AAED,MAAMC,mBAAAA,GAAsBF,MAAOG,CAAAA,GAAAA,CAAI;;;;;;AAMvC,CAAC;AAED,MAAMC,mBAAAA,GAAsBJ,MAAOG,CAAAA,GAAAA,CAAI;;;;;AAKvC,CAAC;AAEYE,MAAAA,aAAAA,GAAgB,CAAC,EAAEC,KAAK,EAAwB,GAAA;AAC3D,IAAA,IAAIA,MAAMC,IAAI,EAAEC,QAASC,CAAAA,SAAAA,CAAUC,KAAK,CAAG,EAAA;AACzC,QAAA,qBACEC,GAACT,CAAAA,mBAAAA,EAAAA;YAAoBU,MAAO,EAAA,MAAA;AAC1B,YAAA,QAAA,gBAAAD,GAACE,CAAAA,YAAAA,EAAAA;AACCC,gBAAAA,GAAAA,EAAKC,eAAeT,KAAO,EAAA,IAAA,CAAA;AAC3BC,gBAAAA,IAAAA,EAAMD,MAAMC,IAAI;AAChBS,gBAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;;AAI5C;AAEA,IAAA,IAAIZ,MAAMC,IAAI,EAAEC,QAASC,CAAAA,SAAAA,CAAUU,KAAK,CAAG,EAAA;AACzC,QAAA,qBACER,GAACP,CAAAA,mBAAAA,EAAAA;AACC,YAAA,QAAA,gBAAAO,GAACS,CAAAA,YAAAA,EAAAA;AACCN,gBAAAA,GAAAA,EAAKC,eAAeT,KAAO,EAAA,IAAA,CAAA;AAC3BU,gBAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;;AAI5C;AAEA,IAAA,IAAIZ,MAAMC,IAAI,EAAEC,QAASC,CAAAA,SAAAA,CAAUY,KAAK,CAAG,EAAA;QACzC,MAAMC,QAAAA,GAAWP,eAAeT,KAAO,EAAA,IAAA,CAAA;QACvC,IAAI,CAACgB,UAAU,OAAO,IAAA;;AAGtB,QAAA,MAAMC,iBAAiB,CAAC,EAAED,QAAS,CAAA,EAAEA,SAASd,QAAQ,CAAC,GAAO,CAAA,GAAA,GAAA,GAAM,IAAI,UAAU,EAAEF,KAAMkB,CAAAA,SAAS,CAAC,CAAC;AAErG,QAAA,qBACEb,GAACR,CAAAA,GAAAA,EAAAA;YACCsB,GAAI,EAAA,KAAA;YACJC,SAAU,EAAA,MAAA;YACVC,QAAS,EAAA,MAAA;YACTC,GAAKL,EAAAA,cAAAA;AACLP,YAAAA,GAAAA,EAAKV,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY;;AAG1C;AAEA,IAAA,qBACEP,GAACZ,CAAAA,QAAAA,EAAAA;QAAS8B,KAAM,EAAA,MAAA;QAAOjB,MAAO,EAAA,MAAA;QAAOkB,cAAe,EAAA,QAAA;QAASC,SAAS,EAAA,IAAA;AACnEzB,QAAAA,QAAAA,EAAAA,KAAAA,CAAM0B,GAAG,EAAExB,QAAS,CAAA,KAAA,CAAA,iBACnBG,GAACsB,CAAAA,OAAAA,EAAAA;AAAQC,YAAAA,YAAAA,EAAY5B,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY,IAAI;YAAEW,KAAM,EAAA,MAAA;YAAOjB,MAAO,EAAA;2BAE9ED,GAACwB,CAAAA,IAAAA,EAAAA;AAAKD,YAAAA,YAAAA,EAAY5B,KAAMW,CAAAA,eAAe,IAAIX,KAAAA,CAAMY,IAAI;YAAEW,KAAM,EAAA,MAAA;YAAOjB,MAAO,EAAA;;;AAInF;;;;"}
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var name = "@strapi/upload";
6
- var version = "5.14.0";
6
+ var version = "5.15.1";
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.24",
68
- "@strapi/icons": "2.0.0-rc.24",
69
- "@strapi/provider-upload-local": "5.14.0",
70
- "@strapi/utils": "5.14.0",
67
+ "@strapi/design-system": "2.0.0-rc.26",
68
+ "@strapi/icons": "2.0.0-rc.26",
69
+ "@strapi/provider-upload-local": "5.15.1",
70
+ "@strapi/utils": "5.15.1",
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.14.0",
93
- "@strapi/types": "5.14.0",
92
+ "@strapi/admin": "5.15.1",
93
+ "@strapi/types": "5.15.1",
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",
@@ -99,7 +99,7 @@ var devDependencies = {
99
99
  "@types/koa": "2.13.4",
100
100
  "@types/koa-range": "0.3.5",
101
101
  "@types/koa-static": "4.0.2",
102
- formidable: "3.5.1",
102
+ formidable: "3.5.4",
103
103
  koa: "2.16.1",
104
104
  "koa-body": "6.0.1",
105
105
  msw: "1.3.0",
@@ -1,5 +1,5 @@
1
1
  var name = "@strapi/upload";
2
- var version = "5.14.0";
2
+ var version = "5.15.1";
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.24",
64
- "@strapi/icons": "2.0.0-rc.24",
65
- "@strapi/provider-upload-local": "5.14.0",
66
- "@strapi/utils": "5.14.0",
63
+ "@strapi/design-system": "2.0.0-rc.26",
64
+ "@strapi/icons": "2.0.0-rc.26",
65
+ "@strapi/provider-upload-local": "5.15.1",
66
+ "@strapi/utils": "5.15.1",
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.14.0",
89
- "@strapi/types": "5.14.0",
88
+ "@strapi/admin": "5.15.1",
89
+ "@strapi/types": "5.15.1",
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",
@@ -95,7 +95,7 @@ var devDependencies = {
95
95
  "@types/koa": "2.13.4",
96
96
  "@types/koa-range": "0.3.5",
97
97
  "@types/koa-static": "4.0.2",
98
- formidable: "3.5.1",
98
+ formidable: "3.5.4",
99
99
  koa: "2.16.1",
100
100
  "koa-body": "6.0.1",
101
101
  msw: "1.3.0",
@@ -13,6 +13,7 @@ interface AssetCardProps {
13
13
  size?: 'S' | 'M';
14
14
  allowedTypes?: AllowedTypes[];
15
15
  alt?: string;
16
+ className?: string;
16
17
  }
17
- export declare const AssetCard: ({ asset, isSelected, onSelect, onEdit, onRemove, size, local, }: AssetCardProps) => import("react/jsx-runtime").JSX.Element;
18
+ export declare const AssetCard: ({ asset, isSelected, onSelect, onEdit, onRemove, size, local, className, }: AssetCardProps) => import("react/jsx-runtime").JSX.Element;
18
19
  export {};
@@ -10,5 +10,6 @@ export interface AssetCardBaseProps {
10
10
  selected?: boolean;
11
11
  subtitle?: string;
12
12
  variant: 'Image' | 'Video' | 'Audio' | 'Doc';
13
+ className?: string;
13
14
  }
14
- export declare const AssetCardBase: ({ children, extension, isSelectable, name, onSelect, onRemove, onEdit, selected, subtitle, variant, }: AssetCardBaseProps) => import("react/jsx-runtime").JSX.Element;
15
+ export declare const AssetCardBase: ({ children, extension, isSelectable, name, onSelect, onRemove, onEdit, selected, subtitle, variant, className, }: AssetCardBaseProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
1
  import type { File as FileAsset } from '../../../../../shared/contracts/files';
2
2
  export declare const CarouselAsset: ({ asset }: {
3
3
  asset: FileAsset;
4
- }) => import("react/jsx-runtime").JSX.Element;
4
+ }) => import("react/jsx-runtime").JSX.Element | null;
@@ -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":"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"}
@@ -1,7 +1,8 @@
1
1
  import fs from 'fs';
2
2
  import { join } from 'path';
3
3
  import sharp from 'sharp';
4
- import { file } from '@strapi/utils';
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":";;;;;;;AAeA,MAAM,EAAEA,aAAa,EAAE,GAAGC,IAAAA;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,KAAKnB,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,UAAAA,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,KAAKnB,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,UAAW,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,OAAAA,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;;;;"}
@@ -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),