@strapi/upload 5.48.0 → 5.49.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 (187) hide show
  1. package/dist/admin/ai/components/AIAssetCard.js +3 -2
  2. package/dist/admin/ai/components/AIAssetCard.js.map +1 -1
  3. package/dist/admin/ai/components/AIUploadModal.js +3 -2
  4. package/dist/admin/ai/components/AIUploadModal.js.map +1 -1
  5. package/dist/admin/components/AssetCard/UploadingAssetCard.js +3 -2
  6. package/dist/admin/components/AssetCard/UploadingAssetCard.js.map +1 -1
  7. package/dist/admin/components/AssetCard/VideoAssetCard.js +3 -2
  8. package/dist/admin/components/AssetCard/VideoAssetCard.js.map +1 -1
  9. package/dist/admin/components/AssetDialog/AssetDialog.js +3 -2
  10. package/dist/admin/components/AssetDialog/AssetDialog.js.map +1 -1
  11. package/dist/admin/components/AssetDialog/BrowseStep/Filters.js +3 -2
  12. package/dist/admin/components/AssetDialog/BrowseStep/Filters.js.map +1 -1
  13. package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/Pagination.js +3 -2
  14. package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/Pagination.js.map +1 -1
  15. package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.js +3 -2
  16. package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.js.map +1 -1
  17. package/dist/admin/components/AssetGridList/Draggable.js +3 -2
  18. package/dist/admin/components/AssetGridList/Draggable.js.map +1 -1
  19. package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.js +3 -2
  20. package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.js.map +1 -1
  21. package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.js +5 -1
  22. package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.js.map +1 -1
  23. package/dist/admin/components/EditAssetDialog/EditAssetContent.js +8 -4
  24. package/dist/admin/components/EditAssetDialog/EditAssetContent.js.map +1 -1
  25. package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js +7 -3
  26. package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js.map +1 -1
  27. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js +7 -3
  28. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js.map +1 -1
  29. package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.js +3 -2
  30. package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.js.map +1 -1
  31. package/dist/admin/components/EditFolderDialog/EditFolderDialog.js +8 -4
  32. package/dist/admin/components/EditFolderDialog/EditFolderDialog.js.map +1 -1
  33. package/dist/admin/components/FilterPopover/FilterPopover.js +3 -2
  34. package/dist/admin/components/FilterPopover/FilterPopover.js.map +1 -1
  35. package/dist/admin/components/FolderCard/FolderCard/FolderCard.js +3 -2
  36. package/dist/admin/components/FolderCard/FolderCard/FolderCard.js.map +1 -1
  37. package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.js +5 -3
  38. package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.js.map +1 -1
  39. package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.mjs +2 -1
  40. package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.mjs.map +1 -1
  41. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.js +3 -2
  42. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.js.map +1 -1
  43. package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js +3 -2
  44. package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js.map +1 -1
  45. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +3 -2
  46. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
  47. package/dist/admin/components/SelectTree/SelectTree.js +7 -3
  48. package/dist/admin/components/SelectTree/SelectTree.js.map +1 -1
  49. package/dist/admin/components/TableList/CellContent.js +5 -1
  50. package/dist/admin/components/TableList/CellContent.js.map +1 -1
  51. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js +3 -2
  52. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js.map +1 -1
  53. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +3 -2
  54. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
  55. package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js +3 -2
  56. package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js.map +1 -1
  57. package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.js +3 -2
  58. package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.js.map +1 -1
  59. package/dist/admin/future/components/Drawer.js +4 -3
  60. package/dist/admin/future/components/Drawer.js.map +1 -1
  61. package/dist/admin/future/pages/Assets/AssetsPage.js +29 -4
  62. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  63. package/dist/admin/future/pages/Assets/AssetsPage.mjs +28 -4
  64. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  65. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +3 -2
  66. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  67. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js +3 -2
  68. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js.map +1 -1
  69. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.js +3 -2
  70. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.js.map +1 -1
  71. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +389 -0
  72. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -0
  73. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +387 -0
  74. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -0
  75. package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.js +3 -2
  76. package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.js.map +1 -1
  77. package/dist/admin/future/pages/Assets/hooks/useFolderInfo.js +4 -4
  78. package/dist/admin/future/pages/Assets/hooks/useFolderInfo.js.map +1 -1
  79. package/dist/admin/future/pages/Assets/hooks/useFolderInfo.mjs +4 -4
  80. package/dist/admin/future/pages/Assets/hooks/useFolderInfo.mjs.map +1 -1
  81. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js +48 -2
  82. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  83. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs +48 -2
  84. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  85. package/dist/admin/future/services/folders.js +28 -1
  86. package/dist/admin/future/services/folders.js.map +1 -1
  87. package/dist/admin/future/services/folders.mjs +28 -2
  88. package/dist/admin/future/services/folders.mjs.map +1 -1
  89. package/dist/admin/future/utils/files.js +5 -1
  90. package/dist/admin/future/utils/files.js.map +1 -1
  91. package/dist/admin/hooks/useAIMetadataJob.js +3 -2
  92. package/dist/admin/hooks/useAIMetadataJob.js.map +1 -1
  93. package/dist/admin/hooks/useAssets.js +3 -2
  94. package/dist/admin/hooks/useAssets.js.map +1 -1
  95. package/dist/admin/hooks/useCropImg.js +7 -3
  96. package/dist/admin/hooks/useCropImg.js.map +1 -1
  97. package/dist/admin/hooks/useEditAsset.js +3 -2
  98. package/dist/admin/hooks/useEditAsset.js.map +1 -1
  99. package/dist/admin/hooks/useFolders.js +3 -2
  100. package/dist/admin/hooks/useFolders.js.map +1 -1
  101. package/dist/admin/hooks/useModalQueryParams.js +3 -2
  102. package/dist/admin/hooks/useModalQueryParams.js.map +1 -1
  103. package/dist/admin/hooks/useSelectionState.js +3 -2
  104. package/dist/admin/hooks/useSelectionState.js.map +1 -1
  105. package/dist/admin/hooks/useUpload.js +3 -2
  106. package/dist/admin/hooks/useUpload.js.map +1 -1
  107. package/dist/admin/pages/App/App.js +3 -2
  108. package/dist/admin/pages/App/App.js.map +1 -1
  109. package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js +7 -3
  110. package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
  111. package/dist/admin/pages/App/ConfigureTheView/state/reducer.js +7 -2
  112. package/dist/admin/pages/App/ConfigureTheView/state/reducer.js.map +1 -1
  113. package/dist/admin/pages/App/MediaLibrary.js +3 -2
  114. package/dist/admin/pages/App/MediaLibrary.js.map +1 -1
  115. package/dist/admin/pages/App/components/BulkMoveButton.js +3 -2
  116. package/dist/admin/pages/App/components/BulkMoveButton.js.map +1 -1
  117. package/dist/admin/pages/App/components/Filters.js +3 -2
  118. package/dist/admin/pages/App/components/Filters.js.map +1 -1
  119. package/dist/admin/pages/SettingsPage/SettingsPage.js +7 -3
  120. package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
  121. package/dist/admin/pages/SettingsPage/reducer.js +5 -1
  122. package/dist/admin/pages/SettingsPage/reducer.js.map +1 -1
  123. package/dist/admin/src/components/MediaLibraryDialog/MediaLibraryDialog.d.ts +2 -1
  124. package/dist/admin/src/future/pages/Assets/components/FolderTree/FolderTree.d.ts +19 -0
  125. package/dist/admin/src/future/pages/Assets/hooks/useFolderNavigation.d.ts +2 -0
  126. package/dist/admin/src/future/services/folders.d.ts +2 -2
  127. package/dist/admin/translations/en.json.js +10 -1
  128. package/dist/admin/translations/en.json.js.map +1 -1
  129. package/dist/admin/translations/en.json.mjs +10 -1
  130. package/dist/admin/translations/en.json.mjs.map +1 -1
  131. package/dist/admin/utils/formatBytes.js +5 -1
  132. package/dist/admin/utils/formatBytes.js.map +1 -1
  133. package/dist/admin/utils/urlYupSchema.js +3 -2
  134. package/dist/admin/utils/urlYupSchema.js.map +1 -1
  135. package/dist/server/controllers/admin-upload.js +11 -4
  136. package/dist/server/controllers/admin-upload.js.map +1 -1
  137. package/dist/server/controllers/content-api.js +19 -2
  138. package/dist/server/controllers/content-api.js.map +1 -1
  139. package/dist/server/controllers/content-api.mjs +12 -0
  140. package/dist/server/controllers/content-api.mjs.map +1 -1
  141. package/dist/server/controllers/utils/find-entity-and-check-permissions.js +7 -3
  142. package/dist/server/controllers/utils/find-entity-and-check-permissions.js.map +1 -1
  143. package/dist/server/middlewares/upload.js +7 -2
  144. package/dist/server/middlewares/upload.js.map +1 -1
  145. package/dist/server/register.js +9 -4
  146. package/dist/server/register.js.map +1 -1
  147. package/dist/server/routes/content-api.js +18 -2
  148. package/dist/server/routes/content-api.js.map +1 -1
  149. package/dist/server/routes/content-api.mjs +15 -0
  150. package/dist/server/routes/content-api.mjs.map +1 -1
  151. package/dist/server/routes/validation/upload.js +31 -2
  152. package/dist/server/routes/validation/upload.js.map +1 -1
  153. package/dist/server/routes/validation/upload.mjs +28 -0
  154. package/dist/server/routes/validation/upload.mjs.map +1 -1
  155. package/dist/server/services/file.js +13 -6
  156. package/dist/server/services/file.js.map +1 -1
  157. package/dist/server/services/image-manipulation.js +18 -12
  158. package/dist/server/services/image-manipulation.js.map +1 -1
  159. package/dist/server/services/provider.js +24 -0
  160. package/dist/server/services/provider.js.map +1 -1
  161. package/dist/server/services/provider.mjs +24 -0
  162. package/dist/server/services/provider.mjs.map +1 -1
  163. package/dist/server/services/upload.js +187 -31
  164. package/dist/server/services/upload.js.map +1 -1
  165. package/dist/server/services/upload.mjs +159 -11
  166. package/dist/server/services/upload.mjs.map +1 -1
  167. package/dist/server/src/controllers/content-api.d.ts +1 -0
  168. package/dist/server/src/controllers/content-api.d.ts.map +1 -1
  169. package/dist/server/src/controllers/index.d.ts +1 -0
  170. package/dist/server/src/controllers/index.d.ts.map +1 -1
  171. package/dist/server/src/index.d.ts +6 -0
  172. package/dist/server/src/index.d.ts.map +1 -1
  173. package/dist/server/src/routes/content-api.d.ts.map +1 -1
  174. package/dist/server/src/routes/validation/upload.d.ts +45 -0
  175. package/dist/server/src/routes/validation/upload.d.ts.map +1 -1
  176. package/dist/server/src/services/index.d.ts +5 -0
  177. package/dist/server/src/services/index.d.ts.map +1 -1
  178. package/dist/server/src/services/provider.d.ts +2 -1
  179. package/dist/server/src/services/provider.d.ts.map +1 -1
  180. package/dist/server/src/services/upload.d.ts +5 -0
  181. package/dist/server/src/services/upload.d.ts.map +1 -1
  182. package/dist/server/src/utils/mime-validation.d.ts.map +1 -1
  183. package/dist/server/utils/mime-validation.js +8 -2
  184. package/dist/server/utils/mime-validation.js.map +1 -1
  185. package/dist/server/utils/mime-validation.mjs +9 -3
  186. package/dist/server/utils/mime-validation.mjs.map +1 -1
  187. package/package.json +7 -7
@@ -24,6 +24,30 @@ var provider = (({ strapi })=>({
24
24
  delete file$1.filepath;
25
25
  }
26
26
  }
27
+ },
28
+ async replace (newFile, oldFile) {
29
+ const provider = strapi.plugin('upload').provider;
30
+ if (isFunction(provider.replaceStream)) {
31
+ newFile.stream = newFile.getStream();
32
+ await provider.replaceStream(newFile, oldFile);
33
+ delete newFile.stream;
34
+ if ('filepath' in newFile) {
35
+ delete newFile.filepath;
36
+ }
37
+ return;
38
+ }
39
+ if (isFunction(provider.replace)) {
40
+ newFile.buffer = await file.streamToBuffer(newFile.getStream());
41
+ await provider.replace(newFile, oldFile);
42
+ delete newFile.buffer;
43
+ if ('filepath' in newFile) {
44
+ delete newFile.filepath;
45
+ }
46
+ return;
47
+ }
48
+ // Fallback: delete old then upload new — preserves current behavior for the file.
49
+ await provider.delete(oldFile);
50
+ await this.upload(newFile);
27
51
  }
28
52
  }));
29
53
 
@@ -1 +1 @@
1
- {"version":3,"file":"provider.mjs","sources":["../../../server/src/services/provider.ts"],"sourcesContent":["import { isFunction } from 'lodash/fp';\nimport { file as fileUtils } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\n\nimport { Config, UploadableFile } from '../types';\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n async checkFileSize(file: UploadableFile) {\n const { sizeLimit } = strapi.config.get<Config>('plugin::upload');\n await strapi.plugin('upload').provider.checkFileSize(file, { sizeLimit });\n },\n\n async upload(file: UploadableFile) {\n if (isFunction(strapi.plugin('upload').provider.uploadStream)) {\n file.stream = file.getStream();\n await strapi.plugin('upload').provider.uploadStream(file);\n\n delete file.stream;\n\n if ('filepath' in file) {\n delete file.filepath;\n }\n } else {\n file.buffer = await fileUtils.streamToBuffer(file.getStream());\n await strapi.plugin('upload').provider.upload(file);\n\n delete file.buffer;\n\n if ('filepath' in file) {\n delete file.filepath;\n }\n }\n },\n});\n"],"names":["strapi","checkFileSize","file","sizeLimit","config","get","plugin","provider","upload","isFunction","uploadStream","stream","getStream","filepath","buffer","fileUtils","streamToBuffer"],"mappings":";;;AAMA,eAAe,CAAA,CAAC,EAAEA,MAAM,EAA2B,IAAM;AACvD,QAAA,MAAMC,eAAcC,IAAoB,EAAA;YACtC,MAAM,EAAEC,SAAS,EAAE,GAAGH,OAAOI,MAAM,CAACC,GAAG,CAAS,gBAAA,CAAA;YAChD,MAAML,MAAAA,CAAOM,MAAM,CAAC,QAAA,CAAA,CAAUC,QAAQ,CAACN,aAAa,CAACC,IAAAA,EAAM;AAAEC,gBAAAA;AAAU,aAAA,CAAA;AACzE,QAAA,CAAA;AAEA,QAAA,MAAMK,QAAON,MAAoB,EAAA;YAC/B,IAAIO,UAAAA,CAAWT,OAAOM,MAAM,CAAC,UAAUC,QAAQ,CAACG,YAAY,CAAA,EAAG;gBAC7DR,MAAAA,CAAKS,MAAM,GAAGT,MAAAA,CAAKU,SAAS,EAAA;AAC5B,gBAAA,MAAMZ,OAAOM,MAAM,CAAC,UAAUC,QAAQ,CAACG,YAAY,CAACR,MAAAA,CAAAA;AAEpD,gBAAA,OAAOA,OAAKS,MAAM;AAElB,gBAAA,IAAI,cAAcT,MAAAA,EAAM;AACtB,oBAAA,OAAOA,OAAKW,QAAQ;AACtB,gBAAA;YACF,CAAA,MAAO;AACLX,gBAAAA,MAAAA,CAAKY,MAAM,GAAG,MAAMC,KAAUC,cAAc,CAACd,OAAKU,SAAS,EAAA,CAAA;AAC3D,gBAAA,MAAMZ,OAAOM,MAAM,CAAC,UAAUC,QAAQ,CAACC,MAAM,CAACN,MAAAA,CAAAA;AAE9C,gBAAA,OAAOA,OAAKY,MAAM;AAElB,gBAAA,IAAI,cAAcZ,MAAAA,EAAM;AACtB,oBAAA,OAAOA,OAAKW,QAAQ;AACtB,gBAAA;AACF,YAAA;AACF,QAAA;AACF,KAAA,CAAC;;;;"}
1
+ {"version":3,"file":"provider.mjs","sources":["../../../server/src/services/provider.ts"],"sourcesContent":["import { isFunction } from 'lodash/fp';\nimport { file as fileUtils } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\n\nimport { Config, File, UploadableFile } from '../types';\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n async checkFileSize(file: UploadableFile) {\n const { sizeLimit } = strapi.config.get<Config>('plugin::upload');\n await strapi.plugin('upload').provider.checkFileSize(file, { sizeLimit });\n },\n\n async upload(file: UploadableFile) {\n if (isFunction(strapi.plugin('upload').provider.uploadStream)) {\n file.stream = file.getStream();\n await strapi.plugin('upload').provider.uploadStream(file);\n\n delete file.stream;\n\n if ('filepath' in file) {\n delete file.filepath;\n }\n } else {\n file.buffer = await fileUtils.streamToBuffer(file.getStream());\n await strapi.plugin('upload').provider.upload(file);\n\n delete file.buffer;\n\n if ('filepath' in file) {\n delete file.filepath;\n }\n }\n },\n\n async replace(newFile: UploadableFile, oldFile: File) {\n const provider = strapi.plugin('upload').provider;\n\n if (isFunction(provider.replaceStream)) {\n newFile.stream = newFile.getStream();\n await provider.replaceStream(newFile, oldFile);\n\n delete newFile.stream;\n\n if ('filepath' in newFile) {\n delete newFile.filepath;\n }\n return;\n }\n\n if (isFunction(provider.replace)) {\n newFile.buffer = await fileUtils.streamToBuffer(newFile.getStream());\n await provider.replace(newFile, oldFile);\n\n delete newFile.buffer;\n\n if ('filepath' in newFile) {\n delete newFile.filepath;\n }\n return;\n }\n\n // Fallback: delete old then upload new — preserves current behavior for the file.\n await provider.delete(oldFile);\n await this.upload(newFile);\n },\n});\n"],"names":["strapi","checkFileSize","file","sizeLimit","config","get","plugin","provider","upload","isFunction","uploadStream","stream","getStream","filepath","buffer","fileUtils","streamToBuffer","replace","newFile","oldFile","replaceStream","delete"],"mappings":";;;AAMA,eAAe,CAAA,CAAC,EAAEA,MAAM,EAA2B,IAAM;AACvD,QAAA,MAAMC,eAAcC,IAAoB,EAAA;YACtC,MAAM,EAAEC,SAAS,EAAE,GAAGH,OAAOI,MAAM,CAACC,GAAG,CAAS,gBAAA,CAAA;YAChD,MAAML,MAAAA,CAAOM,MAAM,CAAC,QAAA,CAAA,CAAUC,QAAQ,CAACN,aAAa,CAACC,IAAAA,EAAM;AAAEC,gBAAAA;AAAU,aAAA,CAAA;AACzE,QAAA,CAAA;AAEA,QAAA,MAAMK,QAAON,MAAoB,EAAA;YAC/B,IAAIO,UAAAA,CAAWT,OAAOM,MAAM,CAAC,UAAUC,QAAQ,CAACG,YAAY,CAAA,EAAG;gBAC7DR,MAAAA,CAAKS,MAAM,GAAGT,MAAAA,CAAKU,SAAS,EAAA;AAC5B,gBAAA,MAAMZ,OAAOM,MAAM,CAAC,UAAUC,QAAQ,CAACG,YAAY,CAACR,MAAAA,CAAAA;AAEpD,gBAAA,OAAOA,OAAKS,MAAM;AAElB,gBAAA,IAAI,cAAcT,MAAAA,EAAM;AACtB,oBAAA,OAAOA,OAAKW,QAAQ;AACtB,gBAAA;YACF,CAAA,MAAO;AACLX,gBAAAA,MAAAA,CAAKY,MAAM,GAAG,MAAMC,KAAUC,cAAc,CAACd,OAAKU,SAAS,EAAA,CAAA;AAC3D,gBAAA,MAAMZ,OAAOM,MAAM,CAAC,UAAUC,QAAQ,CAACC,MAAM,CAACN,MAAAA,CAAAA;AAE9C,gBAAA,OAAOA,OAAKY,MAAM;AAElB,gBAAA,IAAI,cAAcZ,MAAAA,EAAM;AACtB,oBAAA,OAAOA,OAAKW,QAAQ;AACtB,gBAAA;AACF,YAAA;AACF,QAAA,CAAA;QAEA,MAAMI,OAAAA,CAAAA,CAAQC,OAAuB,EAAEC,OAAa,EAAA;AAClD,YAAA,MAAMZ,QAAAA,GAAWP,MAAAA,CAAOM,MAAM,CAAC,UAAUC,QAAQ;YAEjD,IAAIE,UAAAA,CAAWF,QAAAA,CAASa,aAAa,CAAA,EAAG;gBACtCF,OAAAA,CAAQP,MAAM,GAAGO,OAAAA,CAAQN,SAAS,EAAA;gBAClC,MAAML,QAAAA,CAASa,aAAa,CAACF,OAAAA,EAASC,OAAAA,CAAAA;AAEtC,gBAAA,OAAOD,QAAQP,MAAM;AAErB,gBAAA,IAAI,cAAcO,OAAAA,EAAS;AACzB,oBAAA,OAAOA,QAAQL,QAAQ;AACzB,gBAAA;AACA,gBAAA;AACF,YAAA;YAEA,IAAIJ,UAAAA,CAAWF,QAAAA,CAASU,OAAO,CAAA,EAAG;AAChCC,gBAAAA,OAAAA,CAAQJ,MAAM,GAAG,MAAMC,KAAUC,cAAc,CAACE,QAAQN,SAAS,EAAA,CAAA;gBACjE,MAAML,QAAAA,CAASU,OAAO,CAACC,OAAAA,EAASC,OAAAA,CAAAA;AAEhC,gBAAA,OAAOD,QAAQJ,MAAM;AAErB,gBAAA,IAAI,cAAcI,OAAAA,EAAS;AACzB,oBAAA,OAAOA,QAAQL,QAAQ;AACzB,gBAAA;AACA,gBAAA;AACF,YAAA;;YAGA,MAAMN,QAAAA,CAASc,MAAM,CAACF,OAAAA,CAAAA;YACtB,MAAM,IAAI,CAACX,MAAM,CAACU,OAAAA,CAAAA;AACpB,QAAA;AACF,KAAA,CAAC;;;;"}
@@ -7,9 +7,18 @@ var fse = require('fs-extra');
7
7
  var _ = require('lodash');
8
8
  var mimeTypes = require('mime-types');
9
9
  var utils = require('@strapi/utils');
10
+ var fp = require('lodash/fp');
10
11
  var constants = require('../constants.js');
11
12
  var index = require('../utils/index.js');
12
13
 
14
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
+
16
+ var os__default = /*#__PURE__*/_interopDefault(os);
17
+ var path__default = /*#__PURE__*/_interopDefault(path);
18
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
19
+ var fse__default = /*#__PURE__*/_interopDefault(fse);
20
+ var ___default = /*#__PURE__*/_interopDefault(_);
21
+
13
22
  const { UPDATED_BY_ATTRIBUTE, CREATED_BY_ATTRIBUTE } = utils.contentTypes.constants;
14
23
  const { MEDIA_CREATE, MEDIA_UPDATE, MEDIA_DELETE } = constants.ALLOWED_WEBHOOK_EVENTS;
15
24
  const { ApplicationError, NotFoundError } = utils.errors;
@@ -17,15 +26,15 @@ const { bytesToKbytes } = utils.file;
17
26
  var upload = (({ strapi })=>{
18
27
  const fileService = index.getService('file');
19
28
  const sendMediaMetrics = async (data)=>{
20
- if (_.has(data, 'caption') && !_.isEmpty(data.caption)) {
29
+ if (___default.default.has(data, 'caption') && !___default.default.isEmpty(data.caption)) {
21
30
  await index.getService('metrics').trackUsage('didSaveMediaWithCaption');
22
31
  }
23
- if (_.has(data, 'alternativeText') && !_.isEmpty(data.alternativeText)) {
32
+ if (___default.default.has(data, 'alternativeText') && !___default.default.isEmpty(data.alternativeText)) {
24
33
  await index.getService('metrics').trackUsage('didSaveMediaWithAlternativeText');
25
34
  }
26
35
  };
27
36
  const createAndAssignTmpWorkingDirectoryToFiles = async (files)=>{
28
- const tmpWorkingDirectory = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-upload-'));
37
+ const tmpWorkingDirectory = await fse__default.default.mkdtemp(path__default.default.join(os__default.default.tmpdir(), 'strapi-upload-'));
29
38
  if (Array.isArray(files)) {
30
39
  files.forEach((file)=>{
31
40
  file.tmpWorkingDirectory = tmpWorkingDirectory;
@@ -74,12 +83,12 @@ var upload = (({ strapi })=>{
74
83
  if (!isValidFilename(filename)) {
75
84
  throw new ApplicationError('File name contains invalid characters');
76
85
  }
77
- let ext = path.extname(filename);
86
+ let ext = path__default.default.extname(filename);
78
87
  if (!ext) {
79
88
  ext = `.${mimeTypes.extension(type)}`;
80
89
  }
81
90
  const usedName = (fileInfo.name || filename).normalize();
82
- const basename = path.basename(usedName, ext);
91
+ const basename = path__default.default.basename(usedName, ext);
83
92
  // Prevent null characters in file name
84
93
  if (!isValidFilename(filename)) {
85
94
  throw new ApplicationError('File name contains invalid characters');
@@ -132,7 +141,7 @@ var upload = (({ strapi })=>{
132
141
  tmpWorkingDirectory: file.tmpWorkingDirectory
133
142
  });
134
143
  currentFile.filepath = file.filepath;
135
- currentFile.getStream = ()=>fs.createReadStream(file.filepath);
144
+ currentFile.getStream = ()=>fs__default.default.createReadStream(file.filepath);
136
145
  const { optimize, isImage, isFaultyImage, isOptimizableImage } = strapi.plugin('upload').service('image-manipulation');
137
146
  if (await isImage(currentFile)) {
138
147
  if (await isFaultyImage(currentFile)) {
@@ -164,7 +173,7 @@ var upload = (({ strapi })=>{
164
173
  });
165
174
  };
166
175
  const concurrentUploadSize = Math.max(1, strapi.config.get('plugin::upload').concurrentUploadSize ?? 1);
167
- const fileBatches = _.chunk(fileArray.map((file, idx)=>({
176
+ const fileBatches = ___default.default.chunk(fileArray.map((file, idx)=>({
168
177
  file,
169
178
  fileInfo: fileInfoArray[idx] || {}
170
179
  })), concurrentUploadSize);
@@ -174,7 +183,7 @@ var upload = (({ strapi })=>{
174
183
  }
175
184
  } finally{
176
185
  // delete temporary folder
177
- await fse.remove(tmpWorkingDirectory);
186
+ await fse__default.default.remove(tmpWorkingDirectory);
178
187
  }
179
188
  return uploadedFiles;
180
189
  }
@@ -189,20 +198,20 @@ var upload = (({ strapi })=>{
189
198
  const { width, height } = await getDimensions(fileData);
190
199
  // Make sure this is assigned before calling any upload
191
200
  // That way it can mutate the width and height
192
- _.assign(fileData, {
201
+ ___default.default.assign(fileData, {
193
202
  width,
194
203
  height
195
204
  });
196
205
  // For performance reasons, all uploads are wrapped in a single Promise.all
197
206
  const uploadThumbnail = async (thumbnailFile)=>{
198
207
  await index.getService('provider').upload(thumbnailFile);
199
- _.set(fileData, 'formats.thumbnail', thumbnailFile);
208
+ ___default.default.set(fileData, 'formats.thumbnail', thumbnailFile);
200
209
  };
201
210
  // Generate thumbnail and responsive formats
202
211
  const uploadResponsiveFormat = async (format)=>{
203
212
  const { key, file } = format;
204
213
  await index.getService('provider').upload(file);
205
- _.set(fileData, [
214
+ ___default.default.set(fileData, [
206
215
  'formats',
207
216
  key
208
217
  ], file);
@@ -229,6 +238,61 @@ var upload = (({ strapi })=>{
229
238
  await Promise.all(uploadPromises);
230
239
  }
231
240
  /**
241
+ * Like uploadImage, but pairs the main file and each format with its old
242
+ * counterpart and routes through provider.replace so providers that implement
243
+ * an atomic replace can use it. Formats that no longer exist on the new image
244
+ * are deleted; formats that didn't exist on the old image are uploaded fresh.
245
+ */ async function replaceImage(fileData, oldFile) {
246
+ const { getDimensions, generateThumbnail, generateResponsiveFormats, isResizableImage } = index.getService('image-manipulation');
247
+ const { width, height } = await getDimensions(fileData);
248
+ ___default.default.assign(fileData, {
249
+ width,
250
+ height
251
+ });
252
+ const replaceFormat = async (key, newFormat)=>{
253
+ const oldFormat = oldFile.formats?.[key];
254
+ if (oldFormat) {
255
+ await index.getService('provider').replace(newFormat, oldFormat);
256
+ } else {
257
+ await index.getService('provider').upload(newFormat);
258
+ }
259
+ ___default.default.set(fileData, [
260
+ 'formats',
261
+ key
262
+ ], newFormat);
263
+ };
264
+ const promises = [];
265
+ // Replace the main file
266
+ promises.push(index.getService('provider').replace(fileData, oldFile));
267
+ const newFormatKeys = new Set();
268
+ if (await isResizableImage(fileData)) {
269
+ const thumbnailFile = await generateThumbnail(fileData);
270
+ if (thumbnailFile) {
271
+ newFormatKeys.add('thumbnail');
272
+ promises.push(replaceFormat('thumbnail', thumbnailFile));
273
+ }
274
+ const formats = await generateResponsiveFormats(fileData);
275
+ if (Array.isArray(formats) && formats.length > 0) {
276
+ for (const format of formats){
277
+ // eslint-disable-next-line no-continue
278
+ if (!format) continue;
279
+ newFormatKeys.add(format.key);
280
+ promises.push(replaceFormat(format.key, format.file));
281
+ }
282
+ }
283
+ }
284
+ // Delete any formats that existed on the old file but are not present on the new one
285
+ if (oldFile.formats && oldFile.provider === strapi.config.get('plugin::upload').provider) {
286
+ for (const oldKey of Object.keys(oldFile.formats)){
287
+ if (!newFormatKeys.has(oldKey)) {
288
+ const oldFormat = oldFile.formats[oldKey];
289
+ promises.push(strapi.plugin('upload').provider.delete(oldFormat));
290
+ }
291
+ }
292
+ }
293
+ await Promise.all(promises);
294
+ }
295
+ /**
232
296
  * Upload a file. If it is an image it will generate a thumbnail
233
297
  * and responsive formats (if enabled).
234
298
  */ async function uploadFileAndPersist(fileData, opts) {
@@ -241,7 +305,7 @@ var upload = (({ strapi })=>{
241
305
  } else {
242
306
  await index.getService('provider').upload(fileData);
243
307
  }
244
- _.set(fileData, 'provider', config.provider);
308
+ ___default.default.set(fileData, 'provider', config.provider);
245
309
  // Persist file(s)
246
310
  return add(fileData, {
247
311
  user
@@ -254,14 +318,14 @@ var upload = (({ strapi })=>{
254
318
  throw new NotFoundError();
255
319
  }
256
320
  const fileService = index.getService('file');
257
- const newName = _.isNil(name) ? dbFile.name : name;
321
+ const newName = ___default.default.isNil(name) ? dbFile.name : name;
258
322
  const newInfos = {
259
323
  name: newName,
260
- alternativeText: _.isNil(alternativeText) ? dbFile.alternativeText : alternativeText,
261
- caption: _.isNil(caption) ? dbFile.caption : caption,
262
- focalPoint: _.isNil(focalPoint) ? dbFile.focalPoint : focalPoint,
263
- folder: _.isUndefined(folder) ? dbFile.folder : folder,
264
- folderPath: _.isUndefined(folder) ? dbFile.folderPath : await fileService.getFolderPath(folder)
324
+ alternativeText: ___default.default.isNil(alternativeText) ? dbFile.alternativeText : alternativeText,
325
+ caption: ___default.default.isNil(caption) ? dbFile.caption : caption,
326
+ focalPoint: ___default.default.isNil(focalPoint) ? dbFile.focalPoint : focalPoint,
327
+ folder: ___default.default.isUndefined(folder) ? dbFile.folder : folder,
328
+ folderPath: ___default.default.isUndefined(folder) ? dbFile.folderPath : await fileService.getFolderPath(folder)
265
329
  };
266
330
  return update(id, newInfos, {
267
331
  user
@@ -282,30 +346,34 @@ var upload = (({ strapi })=>{
282
346
  const { fileInfo } = data;
283
347
  fileData = await enhanceAndValidateFile(file, fileInfo);
284
348
  // keep a constant hash and extension so the file url doesn't change when the file is replaced
285
- _.assign(fileData, {
349
+ ___default.default.assign(fileData, {
286
350
  hash: dbFile.hash,
287
351
  ext: dbFile.ext
288
352
  });
289
- // execute delete function of the provider
353
+ // clear old formats replaceImage / replace will set new ones
354
+ ___default.default.set(fileData, 'formats', {});
290
355
  if (dbFile.provider === config.provider) {
291
- await strapi.plugin('upload').provider.delete(dbFile);
292
- if (dbFile.formats) {
293
- await Promise.all(Object.keys(dbFile.formats).map((key)=>{
294
- return strapi.plugin('upload').provider.delete(dbFile.formats[key]);
295
- }));
356
+ if (await isImage(fileData)) {
357
+ await replaceImage(fileData, dbFile);
358
+ } else {
359
+ // The new file is not an image, so it has no formats. Replace the main
360
+ // file, then delete any formats the old image left behind — otherwise
361
+ // they're orphaned in storage since the DB record no longer tracks them.
362
+ await index.getService('provider').replace(fileData, dbFile);
363
+ if (dbFile.formats) {
364
+ await Promise.all(Object.keys(dbFile.formats).map((key)=>strapi.plugin('upload').provider.delete(dbFile.formats[key])));
365
+ }
296
366
  }
297
- }
298
- // clear old formats
299
- _.set(fileData, 'formats', {});
300
- if (await isImage(fileData)) {
367
+ } else if (await isImage(fileData)) {
368
+ // Cross-provider replacement: no delete on the old provider, upload to the new one.
301
369
  await uploadImage(fileData);
302
370
  } else {
303
371
  await index.getService('provider').upload(fileData);
304
372
  }
305
- _.set(fileData, 'provider', config.provider);
373
+ ___default.default.set(fileData, 'provider', config.provider);
306
374
  } finally{
307
375
  // delete temporary folder
308
- await fse.remove(tmpWorkingDirectory);
376
+ await fse__default.default.remove(tmpWorkingDirectory);
309
377
  }
310
378
  return update(id, fileData, {
311
379
  user
@@ -377,6 +445,93 @@ var upload = (({ strapi })=>{
377
445
  results: signedResults
378
446
  };
379
447
  }
448
+ /**
449
+ * Resolve whether the count query should run, mirroring core-api's `shouldCount`.
450
+ * Defaults to the `api.rest.withCount` config (true) when not specified on the request.
451
+ */ function resolveWithCount(pagination) {
452
+ if (fp.has('withCount', pagination)) {
453
+ const withCount = pagination.withCount;
454
+ if (typeof withCount === 'boolean') {
455
+ return withCount;
456
+ }
457
+ if (typeof withCount === 'undefined') {
458
+ return false;
459
+ }
460
+ if ([
461
+ 'true',
462
+ 't',
463
+ '1',
464
+ 1
465
+ ].includes(withCount)) {
466
+ return true;
467
+ }
468
+ if ([
469
+ 'false',
470
+ 'f',
471
+ '0',
472
+ 0
473
+ ].includes(withCount)) {
474
+ return false;
475
+ }
476
+ throw new utils.errors.ValidationError('Invalid withCount parameter. Expected "t","1","true","false","0","f"');
477
+ }
478
+ return Boolean(strapi.config.get('api.rest.withCount', true));
479
+ }
480
+ /**
481
+ * REST-aware paginated find for the content API.
482
+ *
483
+ * Unlike `findPage` (used by the admin API), this honors the standard nested
484
+ * `pagination` query object (`pagination[page]`, `pagination[pageSize]`,
485
+ * `pagination[start]`, `pagination[limit]`, `pagination[withCount]`) and the
486
+ * `api.rest.defaultLimit` / `api.rest.maxLimit` / `api.rest.withCount` config,
487
+ * exactly like every other Strapi REST collection-type endpoint.
488
+ */ async function findAndCountPage(query = {}) {
489
+ const { pagination = {} } = query;
490
+ const defaultLimit = fp.toNumber(strapi.config.get('api.rest.defaultLimit', 25));
491
+ const maxLimit = fp.toNumber(strapi.config.get('api.rest.maxLimit')) || null;
492
+ // Whether the consumer used page-based pagination (default) vs offset-based.
493
+ const isOffset = fp.has('start', pagination) || fp.has('limit', pagination);
494
+ const isPaged = !isOffset;
495
+ // Resolve start/limit applying defaults and the maxLimit cap.
496
+ const { start, limit } = utils.pagination.withDefaultPagination(pagination, {
497
+ defaults: {
498
+ offset: {
499
+ limit: defaultLimit
500
+ },
501
+ page: {
502
+ pageSize: defaultLimit
503
+ }
504
+ },
505
+ maxLimit: maxLimit || -1
506
+ });
507
+ // Feed the transform the resolved offset/limit so it ignores the nested
508
+ // `pagination` object (which it cannot read) and applies real bounds.
509
+ const transformed = strapi.get('query-params').transform(constants.FILE_MODEL_UID, {
510
+ ...query,
511
+ pagination: undefined,
512
+ start,
513
+ limit
514
+ });
515
+ const shouldCount = resolveWithCount(pagination);
516
+ const [results, total] = await Promise.all([
517
+ strapi.db.query(constants.FILE_MODEL_UID).findMany(transformed),
518
+ shouldCount ? strapi.db.query(constants.FILE_MODEL_UID).count(transformed) : Promise.resolve(undefined)
519
+ ]);
520
+ const signedResults = await utils.async.map(results, (file)=>fileService.signFileUrls(file));
521
+ const transform = isPaged ? utils.pagination.transformPagedPaginationInfo : utils.pagination.transformOffsetPaginationInfo;
522
+ const paginationInfo = transform({
523
+ start,
524
+ limit
525
+ }, total);
526
+ return {
527
+ results: signedResults,
528
+ // Omit total & pageCount when counting is disabled (withCount=false).
529
+ pagination: fp.isNil(total) ? ___default.default.omit(paginationInfo, [
530
+ 'total',
531
+ 'pageCount'
532
+ ]) : paginationInfo
533
+ };
534
+ }
380
535
  async function remove(file) {
381
536
  const config = strapi.config.get('plugin::upload');
382
537
  // execute delete function of the provider
@@ -448,6 +603,7 @@ var upload = (({ strapi })=>{
448
603
  findOne,
449
604
  findMany,
450
605
  findPage,
606
+ findAndCountPage,
451
607
  remove,
452
608
  getSettings,
453
609
  setSettings,
@@ -1 +1 @@
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 async,\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 fileService = getService('file');\n\n const sendMediaMetrics = async (data: Pick<File, 'caption' | 'alternativeText'>) => {\n if (_.has(data, 'caption') && !_.isEmpty(data.caption)) {\n await getService('metrics').trackUsage('didSaveMediaWithCaption');\n }\n\n if (_.has(data, 'alternativeText') && !_.isEmpty(data.alternativeText)) {\n await getService('metrics').trackUsage('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 focalPoint: fileInfo.focalPoint,\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 // Prefer detected MIME type from security validation. Treat application/octet-stream as\n // undeclared so we use detected type when the client sends no real Content-Type.\n const detected = (file as any).detectedMimeType;\n const declared = file.mimetype || '';\n const mimeType =\n detected ||\n (declared && declared !== 'application/octet-stream' ? declared : undefined) ||\n 'application/octet-stream';\n\n const currentFile = (await formatFileInfo(\n {\n filename: file.originalFilename ?? 'unamed',\n type: mimeType,\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[];\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 const uploadedFiles = [];\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 const concurrentUploadSize = Math.max(\n 1,\n strapi.config.get<Config>('plugin::upload').concurrentUploadSize ?? 1\n );\n\n const fileBatches = _.chunk(\n fileArray.map((file, idx) => ({ file, fileInfo: fileInfoArray[idx] || {} })),\n concurrentUploadSize\n );\n\n for (const batch of fileBatches) {\n const results = await Promise.all(\n batch.map(({ file, fileInfo }) => doUpload(file, fileInfo))\n );\n uploadedFiles.push(...results);\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, focalPoint, 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 focalPoint: _.isNil(focalPoint) ? dbFile.focalPoint : focalPoint,\n folder: _.isUndefined(folder) ? dbFile.folder : folder,\n folderPath: _.isUndefined(folder)\n ? dbFile.folderPath\n : 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 await 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 await 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 async function findOne(id: ID, populate = {}) {\n const query = strapi.get('query-params').transform(FILE_MODEL_UID, {\n populate,\n });\n\n const file = await strapi.db.query(FILE_MODEL_UID).findOne({\n where: { id },\n ...query,\n });\n\n if (!file) return file;\n\n // Sign file URLs if using private provider\n return fileService.signFileUrls(file);\n }\n\n async function findMany(query: any = {}): Promise<File[]> {\n const files = await strapi.db\n .query(FILE_MODEL_UID)\n .findMany(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n\n // Sign file URLs if using private provider\n return async.map(files, (file: File) => fileService.signFileUrls(file));\n }\n\n async function findPage(query: any = {}) {\n const result = await strapi.db\n .query(FILE_MODEL_UID)\n .findPage(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n\n // Sign file URLs if using private provider\n const signedResults = await async.map(result.results, (file: File) =>\n fileService.signFileUrls(file)\n );\n\n return {\n ...result,\n results: signedResults,\n };\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 async function setSettings(value: Settings) {\n if (value.responsiveDimensions === true) {\n await getService('metrics').trackUsage('didEnableResponsiveDimensions');\n } else {\n await getService('metrics').trackUsage('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","fileService","getService","sendMediaMetrics","data","_","has","isEmpty","caption","trackUsage","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","imageManipulationService","ext","extname","extension","usedName","name","normalize","basename","entity","focalPoint","folder","folderPath","getFolderPath","hash","generateFileName","mime","sizeInBytes","refId","ref","field","related","id","__type","__pivot","enhanceAndValidateFile","detected","detectedMimeType","declared","mimetype","mimeType","undefined","currentFile","originalFilename","filepath","getStream","fs","createReadStream","optimize","isImage","isFaultyImage","isOptimizableImage","plugin","service","upload","opts","user","uploadedFiles","fileArray","fileInfoArray","doUpload","fileData","uploadFileAndPersist","concurrentUploadSize","Math","max","config","get","fileBatches","chunk","map","idx","batch","results","Promise","all","push","remove","uploadImage","getDimensions","generateThumbnail","generateResponsiveFormats","isResizableImage","width","height","assign","uploadThumbnail","thumbnailFile","set","uploadResponsiveFormat","format","key","uploadPromises","formats","checkFileSize","provider","add","updateFileInfo","dbFile","findOne","newName","isNil","newInfos","isUndefined","update","replace","delete","Object","keys","values","fileValues","res","db","query","where","create","populate","transform","signFileUrls","findMany","async","findPage","result","signedResults","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 async,\n sanitize,\n contentTypes as contentTypesUtils,\n errors,\n file as fileUtils,\n pagination as paginationUtils,\n} from '@strapi/utils';\nimport { has, toNumber, isNil } from 'lodash/fp';\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 fileService = getService('file');\n\n const sendMediaMetrics = async (data: Pick<File, 'caption' | 'alternativeText'>) => {\n if (_.has(data, 'caption') && !_.isEmpty(data.caption)) {\n await getService('metrics').trackUsage('didSaveMediaWithCaption');\n }\n\n if (_.has(data, 'alternativeText') && !_.isEmpty(data.alternativeText)) {\n await getService('metrics').trackUsage('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 focalPoint: fileInfo.focalPoint,\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 // Prefer detected MIME type from security validation. Treat application/octet-stream as\n // undeclared so we use detected type when the client sends no real Content-Type.\n const detected = (file as any).detectedMimeType;\n const declared = file.mimetype || '';\n const mimeType =\n detected ||\n (declared && declared !== 'application/octet-stream' ? declared : undefined) ||\n 'application/octet-stream';\n\n const currentFile = (await formatFileInfo(\n {\n filename: file.originalFilename ?? 'unamed',\n type: mimeType,\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[];\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 const uploadedFiles = [];\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 const concurrentUploadSize = Math.max(\n 1,\n strapi.config.get<Config>('plugin::upload').concurrentUploadSize ?? 1\n );\n\n const fileBatches = _.chunk(\n fileArray.map((file, idx) => ({ file, fileInfo: fileInfoArray[idx] || {} })),\n concurrentUploadSize\n );\n\n for (const batch of fileBatches) {\n const results = await Promise.all(\n batch.map(({ file, fileInfo }) => doUpload(file, fileInfo))\n );\n uploadedFiles.push(...results);\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 * Like uploadImage, but pairs the main file and each format with its old\n * counterpart and routes through provider.replace so providers that implement\n * an atomic replace can use it. Formats that no longer exist on the new image\n * are deleted; formats that didn't exist on the old image are uploaded fresh.\n */\n async function replaceImage(fileData: UploadableFile, oldFile: File) {\n const { getDimensions, generateThumbnail, generateResponsiveFormats, isResizableImage } =\n getService('image-manipulation');\n\n const { width, height } = await getDimensions(fileData);\n\n _.assign(fileData, {\n width,\n height,\n });\n\n const replaceFormat = async (key: string, newFormat: UploadableFile) => {\n const oldFormat = oldFile.formats?.[key] as File | undefined;\n if (oldFormat) {\n await getService('provider').replace(newFormat, oldFormat);\n } else {\n await getService('provider').upload(newFormat);\n }\n _.set(fileData, ['formats', key], newFormat);\n };\n\n const promises: Promise<unknown>[] = [];\n\n // Replace the main file\n promises.push(getService('provider').replace(fileData, oldFile));\n\n const newFormatKeys = new Set<string>();\n\n if (await isResizableImage(fileData)) {\n const thumbnailFile = await generateThumbnail(fileData);\n if (thumbnailFile) {\n newFormatKeys.add('thumbnail');\n promises.push(replaceFormat('thumbnail', 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 newFormatKeys.add(format.key);\n promises.push(replaceFormat(format.key, format.file));\n }\n }\n }\n\n // Delete any formats that existed on the old file but are not present on the new one\n if (\n oldFile.formats &&\n oldFile.provider === strapi.config.get<Config>('plugin::upload').provider\n ) {\n for (const oldKey of Object.keys(oldFile.formats)) {\n if (!newFormatKeys.has(oldKey)) {\n const oldFormat = oldFile.formats[oldKey] as File;\n promises.push(strapi.plugin('upload').provider.delete(oldFormat));\n }\n }\n }\n\n await Promise.all(promises);\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, focalPoint, 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 focalPoint: _.isNil(focalPoint) ? dbFile.focalPoint : focalPoint,\n folder: _.isUndefined(folder) ? dbFile.folder : folder,\n folderPath: _.isUndefined(folder)\n ? dbFile.folderPath\n : 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 // clear old formats — replaceImage / replace will set new ones\n _.set(fileData, 'formats', {});\n\n if (dbFile.provider === config.provider) {\n if (await isImage(fileData)) {\n await replaceImage(fileData, dbFile);\n } else {\n // The new file is not an image, so it has no formats. Replace the main\n // file, then delete any formats the old image left behind — otherwise\n // they're orphaned in storage since the DB record no longer tracks them.\n await getService('provider').replace(fileData, dbFile);\n if (dbFile.formats) {\n await Promise.all(\n Object.keys(dbFile.formats).map((key) =>\n strapi.plugin('upload').provider.delete(dbFile.formats![key] as File)\n )\n );\n }\n }\n } else if (await isImage(fileData)) {\n // Cross-provider replacement: no delete on the old provider, upload to the new one.\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 await 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 await 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 async function findOne(id: ID, populate = {}) {\n const query = strapi.get('query-params').transform(FILE_MODEL_UID, {\n populate,\n });\n\n const file = await strapi.db.query(FILE_MODEL_UID).findOne({\n where: { id },\n ...query,\n });\n\n if (!file) return file;\n\n // Sign file URLs if using private provider\n return fileService.signFileUrls(file);\n }\n\n async function findMany(query: any = {}): Promise<File[]> {\n const files = await strapi.db\n .query(FILE_MODEL_UID)\n .findMany(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n\n // Sign file URLs if using private provider\n return async.map(files, (file: File) => fileService.signFileUrls(file));\n }\n\n async function findPage(query: any = {}) {\n const result = await strapi.db\n .query(FILE_MODEL_UID)\n .findPage(strapi.get('query-params').transform(FILE_MODEL_UID, query));\n\n // Sign file URLs if using private provider\n const signedResults = await async.map(result.results, (file: File) =>\n fileService.signFileUrls(file)\n );\n\n return {\n ...result,\n results: signedResults,\n };\n }\n\n /**\n * Resolve whether the count query should run, mirroring core-api's `shouldCount`.\n * Defaults to the `api.rest.withCount` config (true) when not specified on the request.\n */\n function resolveWithCount(pagination: Record<string, unknown>): boolean {\n if (has('withCount', pagination)) {\n const withCount = pagination.withCount;\n\n if (typeof withCount === 'boolean') {\n return withCount;\n }\n\n if (typeof withCount === 'undefined') {\n return false;\n }\n\n if (['true', 't', '1', 1].includes(withCount as string | number)) {\n return true;\n }\n\n if (['false', 'f', '0', 0].includes(withCount as string | number)) {\n return false;\n }\n\n throw new errors.ValidationError(\n 'Invalid withCount parameter. Expected \"t\",\"1\",\"true\",\"false\",\"0\",\"f\"'\n );\n }\n\n return Boolean(strapi.config.get('api.rest.withCount', true));\n }\n\n /**\n * REST-aware paginated find for the content API.\n *\n * Unlike `findPage` (used by the admin API), this honors the standard nested\n * `pagination` query object (`pagination[page]`, `pagination[pageSize]`,\n * `pagination[start]`, `pagination[limit]`, `pagination[withCount]`) and the\n * `api.rest.defaultLimit` / `api.rest.maxLimit` / `api.rest.withCount` config,\n * exactly like every other Strapi REST collection-type endpoint.\n */\n async function findAndCountPage(query: any = {}) {\n const { pagination = {} } = query;\n\n const defaultLimit = toNumber(strapi.config.get('api.rest.defaultLimit', 25));\n const maxLimit = toNumber(strapi.config.get('api.rest.maxLimit')) || null;\n\n // Whether the consumer used page-based pagination (default) vs offset-based.\n const isOffset = has('start', pagination) || has('limit', pagination);\n const isPaged = !isOffset;\n\n // Resolve start/limit applying defaults and the maxLimit cap.\n const { start, limit } = paginationUtils.withDefaultPagination(pagination, {\n defaults: { offset: { limit: defaultLimit }, page: { pageSize: defaultLimit } },\n maxLimit: maxLimit || -1,\n });\n\n // Feed the transform the resolved offset/limit so it ignores the nested\n // `pagination` object (which it cannot read) and applies real bounds.\n const transformed = strapi\n .get('query-params')\n .transform(FILE_MODEL_UID, { ...query, pagination: undefined, start, limit });\n\n const shouldCount = resolveWithCount(pagination);\n\n const [results, total] = await Promise.all([\n strapi.db.query(FILE_MODEL_UID).findMany(transformed),\n shouldCount ? strapi.db.query(FILE_MODEL_UID).count(transformed) : Promise.resolve(undefined),\n ]);\n\n const signedResults = await async.map(results, (file: File) => fileService.signFileUrls(file));\n\n const transform = isPaged\n ? paginationUtils.transformPagedPaginationInfo\n : paginationUtils.transformOffsetPaginationInfo;\n\n const paginationInfo = transform({ start, limit }, total as number);\n\n return {\n results: signedResults,\n // Omit total & pageCount when counting is disabled (withCount=false).\n pagination: isNil(total) ? _.omit(paginationInfo, ['total', 'pageCount']) : paginationInfo,\n };\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 async function setSettings(value: Settings) {\n if (value.responsiveDimensions === true) {\n await getService('metrics').trackUsage('didEnableResponsiveDimensions');\n } else {\n await getService('metrics').trackUsage('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 findAndCountPage,\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","fileService","getService","sendMediaMetrics","data","_","has","isEmpty","caption","trackUsage","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","imageManipulationService","ext","extname","extension","usedName","name","normalize","basename","entity","focalPoint","folder","folderPath","getFolderPath","hash","generateFileName","mime","sizeInBytes","refId","ref","field","related","id","__type","__pivot","enhanceAndValidateFile","detected","detectedMimeType","declared","mimetype","mimeType","undefined","currentFile","originalFilename","filepath","getStream","fs","createReadStream","optimize","isImage","isFaultyImage","isOptimizableImage","plugin","service","upload","opts","user","uploadedFiles","fileArray","fileInfoArray","doUpload","fileData","uploadFileAndPersist","concurrentUploadSize","Math","max","config","get","fileBatches","chunk","map","idx","batch","results","Promise","all","push","remove","uploadImage","getDimensions","generateThumbnail","generateResponsiveFormats","isResizableImage","width","height","assign","uploadThumbnail","thumbnailFile","set","uploadResponsiveFormat","format","key","uploadPromises","formats","replaceImage","oldFile","replaceFormat","newFormat","oldFormat","replace","promises","newFormatKeys","Set","add","provider","oldKey","Object","keys","delete","checkFileSize","updateFileInfo","dbFile","findOne","newName","isNil","newInfos","isUndefined","update","values","fileValues","res","db","query","where","create","populate","transform","signFileUrls","findMany","async","findPage","result","signedResults","resolveWithCount","pagination","withCount","includes","ValidationError","Boolean","findAndCountPage","defaultLimit","toNumber","maxLimit","isOffset","isPaged","start","limit","paginationUtils","withDefaultPagination","defaults","offset","page","pageSize","transformed","shouldCount","total","count","resolve","transformPagedPaginationInfo","transformOffsetPaginationInfo","paginationInfo","omit","getSettings","store","setSettings","value","responsiveDimensions","getConfiguration","setConfiguration","_uploadImage"],"mappings":"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"}