@strapi/upload 5.37.1 → 5.38.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 (526) hide show
  1. package/dist/admin/ai/components/AIAssetCard.js.map +1 -1
  2. package/dist/admin/ai/components/AIAssetCard.mjs +1 -1
  3. package/dist/admin/ai/components/AIAssetCard.mjs.map +1 -1
  4. package/dist/admin/ai/components/AIUploadModal.js.map +1 -1
  5. package/dist/admin/ai/components/AIUploadModal.mjs +1 -1
  6. package/dist/admin/ai/components/AIUploadModal.mjs.map +1 -1
  7. package/dist/admin/components/AssetCard/AssetCard.js.map +1 -1
  8. package/dist/admin/components/AssetCard/AssetCard.mjs.map +1 -1
  9. package/dist/admin/components/AssetCard/AssetCardBase.js.map +1 -1
  10. package/dist/admin/components/AssetCard/AssetCardBase.mjs.map +1 -1
  11. package/dist/admin/components/AssetCard/AudioAssetCard.js.map +1 -1
  12. package/dist/admin/components/AssetCard/AudioAssetCard.mjs.map +1 -1
  13. package/dist/admin/components/AssetCard/AudioPreview.js.map +1 -1
  14. package/dist/admin/components/AssetCard/AudioPreview.mjs.map +1 -1
  15. package/dist/admin/components/AssetCard/DocAssetCard.js.map +1 -1
  16. package/dist/admin/components/AssetCard/DocAssetCard.mjs.map +1 -1
  17. package/dist/admin/components/AssetCard/ImageAssetCard.js.map +1 -1
  18. package/dist/admin/components/AssetCard/ImageAssetCard.mjs.map +1 -1
  19. package/dist/admin/components/AssetCard/UploadingAssetCard.js.map +1 -1
  20. package/dist/admin/components/AssetCard/UploadingAssetCard.mjs.map +1 -1
  21. package/dist/admin/components/AssetCard/VideoAssetCard.js.map +1 -1
  22. package/dist/admin/components/AssetCard/VideoAssetCard.mjs.map +1 -1
  23. package/dist/admin/components/AssetCard/VideoPreview.js.map +1 -1
  24. package/dist/admin/components/AssetCard/VideoPreview.mjs.map +1 -1
  25. package/dist/admin/components/AssetDialog/AssetDialog.js.map +1 -1
  26. package/dist/admin/components/AssetDialog/AssetDialog.mjs.map +1 -1
  27. package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js +1 -1
  28. package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js.map +1 -1
  29. package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs +1 -1
  30. package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs.map +1 -1
  31. package/dist/admin/components/AssetDialog/BrowseStep/Filters.js.map +1 -1
  32. package/dist/admin/components/AssetDialog/BrowseStep/Filters.mjs.map +1 -1
  33. package/dist/admin/components/AssetDialog/BrowseStep/PageSize.js.map +1 -1
  34. package/dist/admin/components/AssetDialog/BrowseStep/PageSize.mjs.map +1 -1
  35. package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/Pagination.js.map +1 -1
  36. package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/Pagination.mjs.map +1 -1
  37. package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/PaginationFooter.js.map +1 -1
  38. package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/PaginationFooter.mjs.map +1 -1
  39. package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.js.map +1 -1
  40. package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.mjs.map +1 -1
  41. package/dist/admin/components/AssetDialog/BrowseStep/utils/isSelectable.js.map +1 -1
  42. package/dist/admin/components/AssetDialog/BrowseStep/utils/isSelectable.mjs.map +1 -1
  43. package/dist/admin/components/AssetDialog/DialogFooter.js.map +1 -1
  44. package/dist/admin/components/AssetDialog/DialogFooter.mjs.map +1 -1
  45. package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.js.map +1 -1
  46. package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.mjs.map +1 -1
  47. package/dist/admin/components/AssetGridList/AssetGridList.js.map +1 -1
  48. package/dist/admin/components/AssetGridList/AssetGridList.mjs.map +1 -1
  49. package/dist/admin/components/AssetGridList/Draggable.js.map +1 -1
  50. package/dist/admin/components/AssetGridList/Draggable.mjs.map +1 -1
  51. package/dist/admin/components/Breadcrumbs/Breadcrumbs.js.map +1 -1
  52. package/dist/admin/components/Breadcrumbs/Breadcrumbs.mjs.map +1 -1
  53. package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.js.map +1 -1
  54. package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs.map +1 -1
  55. package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.js.map +1 -1
  56. package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.mjs.map +1 -1
  57. package/dist/admin/components/ContextInfo/ContextInfo.js.map +1 -1
  58. package/dist/admin/components/ContextInfo/ContextInfo.mjs.map +1 -1
  59. package/dist/admin/components/CopyLinkButton/CopyLinkButton.js.map +1 -1
  60. package/dist/admin/components/CopyLinkButton/CopyLinkButton.mjs.map +1 -1
  61. package/dist/admin/components/EditAssetDialog/DialogHeader.js.map +1 -1
  62. package/dist/admin/components/EditAssetDialog/DialogHeader.mjs.map +1 -1
  63. package/dist/admin/components/EditAssetDialog/EditAssetContent.js.map +1 -1
  64. package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs.map +1 -1
  65. package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js.map +1 -1
  66. package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.mjs.map +1 -1
  67. package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.js.map +1 -1
  68. package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.mjs.map +1 -1
  69. package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.js.map +1 -1
  70. package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.mjs.map +1 -1
  71. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js +1 -4
  72. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js.map +1 -1
  73. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs +1 -4
  74. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs.map +1 -1
  75. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewComponents.js.map +1 -1
  76. package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewComponents.mjs.map +1 -1
  77. package/dist/admin/components/EditAssetDialog/RemoveAssetDialog.js.map +1 -1
  78. package/dist/admin/components/EditAssetDialog/RemoveAssetDialog.mjs.map +1 -1
  79. package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.js.map +1 -1
  80. package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.mjs.map +1 -1
  81. package/dist/admin/components/EditFolderDialog/EditFolderDialog.js.map +1 -1
  82. package/dist/admin/components/EditFolderDialog/EditFolderDialog.mjs.map +1 -1
  83. package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.js.map +1 -1
  84. package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.mjs.map +1 -1
  85. package/dist/admin/components/EditFolderDialog/RemoveFolderDialog.js.map +1 -1
  86. package/dist/admin/components/EditFolderDialog/RemoveFolderDialog.mjs.map +1 -1
  87. package/dist/admin/components/EmptyAssets/EmptyAssetGrid.js.map +1 -1
  88. package/dist/admin/components/EmptyAssets/EmptyAssetGrid.mjs.map +1 -1
  89. package/dist/admin/components/EmptyAssets/EmptyAssets.js.map +1 -1
  90. package/dist/admin/components/EmptyAssets/EmptyAssets.mjs.map +1 -1
  91. package/dist/admin/components/FilterList/FilterList.js.map +1 -1
  92. package/dist/admin/components/FilterList/FilterList.mjs.map +1 -1
  93. package/dist/admin/components/FilterList/FilterTag.js.map +1 -1
  94. package/dist/admin/components/FilterList/FilterTag.mjs.map +1 -1
  95. package/dist/admin/components/FilterPopover/FilterPopover.js.map +1 -1
  96. package/dist/admin/components/FilterPopover/FilterPopover.mjs.map +1 -1
  97. package/dist/admin/components/FilterPopover/FilterValueInput.js.map +1 -1
  98. package/dist/admin/components/FilterPopover/FilterValueInput.mjs.map +1 -1
  99. package/dist/admin/components/FilterPopover/utils/getFilterList.js.map +1 -1
  100. package/dist/admin/components/FilterPopover/utils/getFilterList.mjs.map +1 -1
  101. package/dist/admin/components/FolderCard/FolderCard/FolderCard.js.map +1 -1
  102. package/dist/admin/components/FolderCard/FolderCard/FolderCard.mjs.map +1 -1
  103. package/dist/admin/components/FolderCard/FolderCardBody/FolderCardBody.js.map +1 -1
  104. package/dist/admin/components/FolderCard/FolderCardBody/FolderCardBody.mjs.map +1 -1
  105. package/dist/admin/components/FolderCard/FolderCardBodyAction/FolderCardBodyAction.js.map +1 -1
  106. package/dist/admin/components/FolderCard/FolderCardBodyAction/FolderCardBodyAction.mjs.map +1 -1
  107. package/dist/admin/components/FolderCard/FolderCardCheckbox/FolderCardCheckbox.js.map +1 -1
  108. package/dist/admin/components/FolderCard/FolderCardCheckbox/FolderCardCheckbox.mjs.map +1 -1
  109. package/dist/admin/components/FolderCard/contexts/FolderCard.js.map +1 -1
  110. package/dist/admin/components/FolderCard/contexts/FolderCard.mjs.map +1 -1
  111. package/dist/admin/components/FolderGridList/FolderGridList.js.map +1 -1
  112. package/dist/admin/components/FolderGridList/FolderGridList.mjs.map +1 -1
  113. package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.js.map +1 -1
  114. package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.mjs.map +1 -1
  115. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.js.map +1 -1
  116. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs.map +1 -1
  117. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.js.map +1 -1
  118. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.mjs.map +1 -1
  119. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.js.map +1 -1
  120. package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.mjs.map +1 -1
  121. package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js.map +1 -1
  122. package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.mjs.map +1 -1
  123. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
  124. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
  125. package/dist/admin/components/SelectTree/Option.js.map +1 -1
  126. package/dist/admin/components/SelectTree/Option.mjs.map +1 -1
  127. package/dist/admin/components/SelectTree/SelectTree.js.map +1 -1
  128. package/dist/admin/components/SelectTree/SelectTree.mjs +1 -1
  129. package/dist/admin/components/SelectTree/SelectTree.mjs.map +1 -1
  130. package/dist/admin/components/SelectTree/utils/flattenTree.js.map +1 -1
  131. package/dist/admin/components/SelectTree/utils/flattenTree.mjs.map +1 -1
  132. package/dist/admin/components/SelectTree/utils/getOpenValues.js.map +1 -1
  133. package/dist/admin/components/SelectTree/utils/getOpenValues.mjs.map +1 -1
  134. package/dist/admin/components/SelectTree/utils/getValuesToClose.js.map +1 -1
  135. package/dist/admin/components/SelectTree/utils/getValuesToClose.mjs.map +1 -1
  136. package/dist/admin/components/SortPicker/SortPicker.js.map +1 -1
  137. package/dist/admin/components/SortPicker/SortPicker.mjs.map +1 -1
  138. package/dist/admin/components/TableList/CellContent.js.map +1 -1
  139. package/dist/admin/components/TableList/CellContent.mjs.map +1 -1
  140. package/dist/admin/components/TableList/PreviewCell.js.map +1 -1
  141. package/dist/admin/components/TableList/PreviewCell.mjs +1 -1
  142. package/dist/admin/components/TableList/PreviewCell.mjs.map +1 -1
  143. package/dist/admin/components/TableList/TableList.js.map +1 -1
  144. package/dist/admin/components/TableList/TableList.mjs +1 -1
  145. package/dist/admin/components/TableList/TableList.mjs.map +1 -1
  146. package/dist/admin/components/TableList/TableRows.js.map +1 -1
  147. package/dist/admin/components/TableList/TableRows.mjs.map +1 -1
  148. package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.js.map +1 -1
  149. package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.mjs.map +1 -1
  150. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js.map +1 -1
  151. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.mjs.map +1 -1
  152. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
  153. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
  154. package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js.map +1 -1
  155. package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.mjs.map +1 -1
  156. package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.js.map +1 -1
  157. package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.mjs.map +1 -1
  158. package/dist/admin/components/UploadProgress/UploadProgress.js.map +1 -1
  159. package/dist/admin/components/UploadProgress/UploadProgress.mjs.map +1 -1
  160. package/dist/admin/constants.js.map +1 -1
  161. package/dist/admin/constants.mjs.map +1 -1
  162. package/dist/admin/future/App.js.map +1 -1
  163. package/dist/admin/future/App.mjs.map +1 -1
  164. package/dist/admin/future/components/Drawer.js +189 -0
  165. package/dist/admin/future/components/Drawer.js.map +1 -0
  166. package/dist/admin/future/components/Drawer.mjs +166 -0
  167. package/dist/admin/future/components/Drawer.mjs.map +1 -0
  168. package/dist/admin/future/components/UploadProgressDialog.js +60 -101
  169. package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
  170. package/dist/admin/future/components/UploadProgressDialog.mjs +62 -84
  171. package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
  172. package/dist/admin/future/pages/Assets/AssetsPage.js +155 -100
  173. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  174. package/dist/admin/future/pages/Assets/AssetsPage.mjs +160 -105
  175. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  176. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +406 -0
  177. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -0
  178. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +384 -0
  179. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -0
  180. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js +215 -0
  181. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js.map +1 -0
  182. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs +194 -0
  183. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs.map +1 -0
  184. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +37 -8
  185. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  186. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +38 -9
  187. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  188. package/dist/admin/future/pages/Assets/components/AssetsTable.js +35 -5
  189. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  190. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +37 -7
  191. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  192. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js +143 -0
  193. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js.map +1 -0
  194. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs +141 -0
  195. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs.map +1 -0
  196. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.js.map +1 -1
  197. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.mjs.map +1 -1
  198. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
  199. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
  200. package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.js +127 -0
  201. package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.js.map +1 -0
  202. package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.mjs +106 -0
  203. package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.mjs.map +1 -0
  204. package/dist/admin/future/pages/Assets/constants.js.map +1 -1
  205. package/dist/admin/future/pages/Assets/constants.mjs.map +1 -1
  206. package/dist/admin/future/pages/Assets/hooks/useFolderInfo.js.map +1 -1
  207. package/dist/admin/future/pages/Assets/hooks/useFolderInfo.mjs.map +1 -1
  208. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  209. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  210. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
  211. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
  212. package/dist/admin/future/services/api.js +181 -97
  213. package/dist/admin/future/services/api.js.map +1 -1
  214. package/dist/admin/future/services/api.mjs +181 -98
  215. package/dist/admin/future/services/api.mjs.map +1 -1
  216. package/dist/admin/future/services/assets.js +14 -1
  217. package/dist/admin/future/services/assets.js.map +1 -1
  218. package/dist/admin/future/services/assets.mjs +14 -2
  219. package/dist/admin/future/services/assets.mjs.map +1 -1
  220. package/dist/admin/future/services/folders.js +16 -1
  221. package/dist/admin/future/services/folders.js.map +1 -1
  222. package/dist/admin/future/services/folders.mjs +16 -2
  223. package/dist/admin/future/services/folders.mjs.map +1 -1
  224. package/dist/admin/future/store/hooks.js.map +1 -1
  225. package/dist/admin/future/store/hooks.mjs.map +1 -1
  226. package/dist/admin/future/store/uploadProgress.js +7 -4
  227. package/dist/admin/future/store/uploadProgress.js.map +1 -1
  228. package/dist/admin/future/store/uploadProgress.mjs +7 -4
  229. package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
  230. package/dist/admin/future/utils/files.js +105 -3
  231. package/dist/admin/future/utils/files.js.map +1 -1
  232. package/dist/admin/future/utils/files.mjs +104 -4
  233. package/dist/admin/future/utils/files.mjs.map +1 -1
  234. package/dist/admin/future/utils/getAssetIcon.js +3 -3
  235. package/dist/admin/future/utils/getAssetIcon.js.map +1 -1
  236. package/dist/admin/future/utils/getAssetIcon.mjs +4 -4
  237. package/dist/admin/future/utils/getAssetIcon.mjs.map +1 -1
  238. package/dist/admin/future/utils/translations.js.map +1 -1
  239. package/dist/admin/future/utils/translations.mjs.map +1 -1
  240. package/dist/admin/hooks/useAIMetadataJob.js.map +1 -1
  241. package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -1
  242. package/dist/admin/hooks/useAiAvailability.js.map +1 -1
  243. package/dist/admin/hooks/useAiAvailability.mjs.map +1 -1
  244. package/dist/admin/hooks/useAssets.js.map +1 -1
  245. package/dist/admin/hooks/useAssets.mjs.map +1 -1
  246. package/dist/admin/hooks/useBulkEdit.js.map +1 -1
  247. package/dist/admin/hooks/useBulkEdit.mjs.map +1 -1
  248. package/dist/admin/hooks/useBulkMove.js.map +1 -1
  249. package/dist/admin/hooks/useBulkMove.mjs.map +1 -1
  250. package/dist/admin/hooks/useBulkRemove.js.map +1 -1
  251. package/dist/admin/hooks/useBulkRemove.mjs.map +1 -1
  252. package/dist/admin/hooks/useConfig.js.map +1 -1
  253. package/dist/admin/hooks/useConfig.mjs.map +1 -1
  254. package/dist/admin/hooks/useCropImg.js.map +1 -1
  255. package/dist/admin/hooks/useCropImg.mjs.map +1 -1
  256. package/dist/admin/hooks/useEditAsset.js.map +1 -1
  257. package/dist/admin/hooks/useEditAsset.mjs.map +1 -1
  258. package/dist/admin/hooks/useEditFolder.js.map +1 -1
  259. package/dist/admin/hooks/useEditFolder.mjs.map +1 -1
  260. package/dist/admin/hooks/useFolder.js.map +1 -1
  261. package/dist/admin/hooks/useFolder.mjs.map +1 -1
  262. package/dist/admin/hooks/useFolderStructure.js.map +1 -1
  263. package/dist/admin/hooks/useFolderStructure.mjs.map +1 -1
  264. package/dist/admin/hooks/useFolders.js.map +1 -1
  265. package/dist/admin/hooks/useFolders.mjs.map +1 -1
  266. package/dist/admin/hooks/useMediaLibraryPermissions.js.map +1 -1
  267. package/dist/admin/hooks/useMediaLibraryPermissions.mjs.map +1 -1
  268. package/dist/admin/hooks/useModalQueryParams.js.map +1 -1
  269. package/dist/admin/hooks/useModalQueryParams.mjs.map +1 -1
  270. package/dist/admin/hooks/usePersistentState.js.map +1 -1
  271. package/dist/admin/hooks/usePersistentState.mjs.map +1 -1
  272. package/dist/admin/hooks/useRemoveAsset.js.map +1 -1
  273. package/dist/admin/hooks/useRemoveAsset.mjs.map +1 -1
  274. package/dist/admin/hooks/useSelectionState.js.map +1 -1
  275. package/dist/admin/hooks/useSelectionState.mjs.map +1 -1
  276. package/dist/admin/hooks/useSettings.js.map +1 -1
  277. package/dist/admin/hooks/useSettings.mjs.map +1 -1
  278. package/dist/admin/hooks/useTracking.js.map +1 -1
  279. package/dist/admin/hooks/useTracking.mjs.map +1 -1
  280. package/dist/admin/hooks/useUpload.js.map +1 -1
  281. package/dist/admin/hooks/useUpload.mjs.map +1 -1
  282. package/dist/admin/hooks/utils/renameKeys.js.map +1 -1
  283. package/dist/admin/hooks/utils/renameKeys.mjs.map +1 -1
  284. package/dist/admin/index.js.map +1 -1
  285. package/dist/admin/index.mjs.map +1 -1
  286. package/dist/admin/package.json.js +1 -152
  287. package/dist/admin/package.json.js.map +1 -1
  288. package/dist/admin/package.json.mjs +2 -141
  289. package/dist/admin/package.json.mjs.map +1 -1
  290. package/dist/admin/pages/App/App.js.map +1 -1
  291. package/dist/admin/pages/App/App.mjs.map +1 -1
  292. package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
  293. package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs +3 -3
  294. package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
  295. package/dist/admin/pages/App/ConfigureTheView/components/Settings.js.map +1 -1
  296. package/dist/admin/pages/App/ConfigureTheView/components/Settings.mjs.map +1 -1
  297. package/dist/admin/pages/App/ConfigureTheView/state/actionTypes.js.map +1 -1
  298. package/dist/admin/pages/App/ConfigureTheView/state/actionTypes.mjs.map +1 -1
  299. package/dist/admin/pages/App/ConfigureTheView/state/actions.js.map +1 -1
  300. package/dist/admin/pages/App/ConfigureTheView/state/actions.mjs.map +1 -1
  301. package/dist/admin/pages/App/ConfigureTheView/state/init.js.map +1 -1
  302. package/dist/admin/pages/App/ConfigureTheView/state/init.mjs.map +1 -1
  303. package/dist/admin/pages/App/ConfigureTheView/state/reducer.js.map +1 -1
  304. package/dist/admin/pages/App/ConfigureTheView/state/reducer.mjs +1 -1
  305. package/dist/admin/pages/App/ConfigureTheView/state/reducer.mjs.map +1 -1
  306. package/dist/admin/pages/App/MediaLibrary.js +1 -1
  307. package/dist/admin/pages/App/MediaLibrary.js.map +1 -1
  308. package/dist/admin/pages/App/MediaLibrary.mjs +2 -2
  309. package/dist/admin/pages/App/MediaLibrary.mjs.map +1 -1
  310. package/dist/admin/pages/App/components/BulkActions.js.map +1 -1
  311. package/dist/admin/pages/App/components/BulkActions.mjs.map +1 -1
  312. package/dist/admin/pages/App/components/BulkDeleteButton.js.map +1 -1
  313. package/dist/admin/pages/App/components/BulkDeleteButton.mjs.map +1 -1
  314. package/dist/admin/pages/App/components/BulkMoveButton.js.map +1 -1
  315. package/dist/admin/pages/App/components/BulkMoveButton.mjs.map +1 -1
  316. package/dist/admin/pages/App/components/EmptyOrNoPermissions.js.map +1 -1
  317. package/dist/admin/pages/App/components/EmptyOrNoPermissions.mjs.map +1 -1
  318. package/dist/admin/pages/App/components/Filters.js.map +1 -1
  319. package/dist/admin/pages/App/components/Filters.mjs.map +1 -1
  320. package/dist/admin/pages/App/components/Header.js.map +1 -1
  321. package/dist/admin/pages/App/components/Header.mjs +2 -2
  322. package/dist/admin/pages/App/components/Header.mjs.map +1 -1
  323. package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
  324. package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
  325. package/dist/admin/pages/SettingsPage/reducer.js.map +1 -1
  326. package/dist/admin/pages/SettingsPage/reducer.mjs.map +1 -1
  327. package/dist/admin/pluginId.js.map +1 -1
  328. package/dist/admin/pluginId.mjs.map +1 -1
  329. package/dist/admin/src/future/components/Drawer.d.ts +32 -0
  330. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +8 -0
  331. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetPreview.d.ts +6 -0
  332. package/dist/admin/src/future/pages/Assets/components/AssetsGrid.d.ts +2 -1
  333. package/dist/admin/src/future/pages/Assets/components/AssetsTable.d.ts +2 -1
  334. package/dist/admin/src/future/pages/Assets/components/CreateFolderDialog.d.ts +8 -0
  335. package/dist/admin/src/future/pages/Assets/components/ImportFromUrlDialog.d.ts +7 -0
  336. package/dist/admin/src/future/services/api.d.ts +10 -1
  337. package/dist/admin/src/future/services/assets.d.ts +2 -2
  338. package/dist/admin/src/future/services/folders.d.ts +1 -1
  339. package/dist/admin/src/future/store/uploadProgress.d.ts +1 -1
  340. package/dist/admin/src/future/utils/files.d.ts +70 -0
  341. package/dist/admin/translations/en.json.js +35 -3
  342. package/dist/admin/translations/en.json.js.map +1 -1
  343. package/dist/admin/translations/en.json.mjs +35 -3
  344. package/dist/admin/translations/en.json.mjs.map +1 -1
  345. package/dist/admin/translations/es.json.js +1 -1
  346. package/dist/admin/translations/es.json.mjs +1 -1
  347. package/dist/admin/utils/appendSearchParamsToUrl.js.map +1 -1
  348. package/dist/admin/utils/appendSearchParamsToUrl.mjs.map +1 -1
  349. package/dist/admin/utils/containsAssetFilter.js.map +1 -1
  350. package/dist/admin/utils/containsAssetFilter.mjs.map +1 -1
  351. package/dist/admin/utils/createAssetUrl.js.map +1 -1
  352. package/dist/admin/utils/createAssetUrl.mjs.map +1 -1
  353. package/dist/admin/utils/displayedFilters.js.map +1 -1
  354. package/dist/admin/utils/displayedFilters.mjs.map +1 -1
  355. package/dist/admin/utils/downloadFile.js.map +1 -1
  356. package/dist/admin/utils/downloadFile.mjs.map +1 -1
  357. package/dist/admin/utils/findRecursiveFolderByValue.js.map +1 -1
  358. package/dist/admin/utils/findRecursiveFolderByValue.mjs.map +1 -1
  359. package/dist/admin/utils/formatBytes.js.map +1 -1
  360. package/dist/admin/utils/formatBytes.mjs.map +1 -1
  361. package/dist/admin/utils/formatDuration.js.map +1 -1
  362. package/dist/admin/utils/formatDuration.mjs.map +1 -1
  363. package/dist/admin/utils/getAPIInnerErrors.js.map +1 -1
  364. package/dist/admin/utils/getAPIInnerErrors.mjs.map +1 -1
  365. package/dist/admin/utils/getAllowedFiles.js.map +1 -1
  366. package/dist/admin/utils/getAllowedFiles.mjs.map +1 -1
  367. package/dist/admin/utils/getBreadcrumbDataCM.js.map +1 -1
  368. package/dist/admin/utils/getBreadcrumbDataCM.mjs.map +1 -1
  369. package/dist/admin/utils/getBreadcrumbDataML.js.map +1 -1
  370. package/dist/admin/utils/getBreadcrumbDataML.mjs.map +1 -1
  371. package/dist/admin/utils/getFileExtension.js.map +1 -1
  372. package/dist/admin/utils/getFileExtension.mjs.map +1 -1
  373. package/dist/admin/utils/getFolderParents.js.map +1 -1
  374. package/dist/admin/utils/getFolderParents.mjs.map +1 -1
  375. package/dist/admin/utils/getFolderURL.js.map +1 -1
  376. package/dist/admin/utils/getFolderURL.mjs.map +1 -1
  377. package/dist/admin/utils/getTrad.js.map +1 -1
  378. package/dist/admin/utils/getTrad.mjs.map +1 -1
  379. package/dist/admin/utils/icons.js.map +1 -1
  380. package/dist/admin/utils/icons.mjs +1 -1
  381. package/dist/admin/utils/icons.mjs.map +1 -1
  382. package/dist/admin/utils/moveElement.js.map +1 -1
  383. package/dist/admin/utils/moveElement.mjs.map +1 -1
  384. package/dist/admin/utils/normalizeAPIError.js.map +1 -1
  385. package/dist/admin/utils/normalizeAPIError.mjs.map +1 -1
  386. package/dist/admin/utils/prefixFileUrlWithBackendUrl.js.map +1 -1
  387. package/dist/admin/utils/prefixFileUrlWithBackendUrl.mjs.map +1 -1
  388. package/dist/admin/utils/prefixPluginTranslations.js.map +1 -1
  389. package/dist/admin/utils/prefixPluginTranslations.mjs.map +1 -1
  390. package/dist/admin/utils/rawFileToAsset.js.map +1 -1
  391. package/dist/admin/utils/rawFileToAsset.mjs.map +1 -1
  392. package/dist/admin/utils/toSingularTypes.js.map +1 -1
  393. package/dist/admin/utils/toSingularTypes.mjs.map +1 -1
  394. package/dist/admin/utils/typeFromMime.js.map +1 -1
  395. package/dist/admin/utils/typeFromMime.mjs.map +1 -1
  396. package/dist/admin/utils/urlYupSchema.js.map +1 -1
  397. package/dist/admin/utils/urlYupSchema.mjs.map +1 -1
  398. package/dist/admin/utils/urlsToAssets.js.map +1 -1
  399. package/dist/admin/utils/urlsToAssets.mjs.map +1 -1
  400. package/dist/server/bootstrap.js.map +1 -1
  401. package/dist/server/bootstrap.mjs.map +1 -1
  402. package/dist/server/config.js.map +1 -1
  403. package/dist/server/config.mjs.map +1 -1
  404. package/dist/server/constants.js.map +1 -1
  405. package/dist/server/constants.mjs.map +1 -1
  406. package/dist/server/content-types/file.js.map +1 -1
  407. package/dist/server/content-types/file.mjs.map +1 -1
  408. package/dist/server/content-types/folder.js.map +1 -1
  409. package/dist/server/content-types/folder.mjs +1 -1
  410. package/dist/server/content-types/folder.mjs.map +1 -1
  411. package/dist/server/content-types/index.js.map +1 -1
  412. package/dist/server/content-types/index.mjs.map +1 -1
  413. package/dist/server/controllers/admin-file.js.map +1 -1
  414. package/dist/server/controllers/admin-file.mjs +1 -1
  415. package/dist/server/controllers/admin-file.mjs.map +1 -1
  416. package/dist/server/controllers/admin-folder-file.js.map +1 -1
  417. package/dist/server/controllers/admin-folder-file.mjs +2 -2
  418. package/dist/server/controllers/admin-folder-file.mjs.map +1 -1
  419. package/dist/server/controllers/admin-folder.js.map +1 -1
  420. package/dist/server/controllers/admin-folder.mjs +1 -1
  421. package/dist/server/controllers/admin-folder.mjs.map +1 -1
  422. package/dist/server/controllers/admin-settings.js.map +1 -1
  423. package/dist/server/controllers/admin-settings.mjs.map +1 -1
  424. package/dist/server/controllers/admin-upload.js +144 -0
  425. package/dist/server/controllers/admin-upload.js.map +1 -1
  426. package/dist/server/controllers/admin-upload.mjs +147 -3
  427. package/dist/server/controllers/admin-upload.mjs.map +1 -1
  428. package/dist/server/controllers/content-api.js.map +1 -1
  429. package/dist/server/controllers/content-api.mjs.map +1 -1
  430. package/dist/server/controllers/index.js.map +1 -1
  431. package/dist/server/controllers/index.mjs.map +1 -1
  432. package/dist/server/controllers/utils/find-entity-and-check-permissions.js.map +1 -1
  433. package/dist/server/controllers/utils/find-entity-and-check-permissions.mjs.map +1 -1
  434. package/dist/server/controllers/utils/folders.js.map +1 -1
  435. package/dist/server/controllers/utils/folders.mjs.map +1 -1
  436. package/dist/server/controllers/validation/admin/configureView.js.map +1 -1
  437. package/dist/server/controllers/validation/admin/configureView.mjs.map +1 -1
  438. package/dist/server/controllers/validation/admin/folder-file.js.map +1 -1
  439. package/dist/server/controllers/validation/admin/folder-file.mjs.map +1 -1
  440. package/dist/server/controllers/validation/admin/folder.js.map +1 -1
  441. package/dist/server/controllers/validation/admin/folder.mjs.map +1 -1
  442. package/dist/server/controllers/validation/admin/settings.js.map +1 -1
  443. package/dist/server/controllers/validation/admin/settings.mjs.map +1 -1
  444. package/dist/server/controllers/validation/admin/upload.js.map +1 -1
  445. package/dist/server/controllers/validation/admin/upload.mjs.map +1 -1
  446. package/dist/server/controllers/validation/admin/utils.js.map +1 -1
  447. package/dist/server/controllers/validation/admin/utils.mjs.map +1 -1
  448. package/dist/server/controllers/validation/content-api/upload.js.map +1 -1
  449. package/dist/server/controllers/validation/content-api/upload.mjs.map +1 -1
  450. package/dist/server/controllers/view-configuration.js.map +1 -1
  451. package/dist/server/controllers/view-configuration.mjs.map +1 -1
  452. package/dist/server/graphql.js.map +1 -1
  453. package/dist/server/graphql.mjs.map +1 -1
  454. package/dist/server/index.js +8 -8
  455. package/dist/server/middlewares/upload.js.map +1 -1
  456. package/dist/server/middlewares/upload.mjs.map +1 -1
  457. package/dist/server/models/ai-metadata-job.js.map +1 -1
  458. package/dist/server/models/ai-metadata-job.mjs.map +1 -1
  459. package/dist/server/register.js.map +1 -1
  460. package/dist/server/register.mjs.map +1 -1
  461. package/dist/server/routes/admin.js +10 -0
  462. package/dist/server/routes/admin.js.map +1 -1
  463. package/dist/server/routes/admin.mjs +10 -0
  464. package/dist/server/routes/admin.mjs.map +1 -1
  465. package/dist/server/routes/content-api.js.map +1 -1
  466. package/dist/server/routes/content-api.mjs.map +1 -1
  467. package/dist/server/routes/index.js.map +1 -1
  468. package/dist/server/routes/index.mjs +4 -4
  469. package/dist/server/routes/index.mjs.map +1 -1
  470. package/dist/server/routes/validation/upload.js.map +1 -1
  471. package/dist/server/routes/validation/upload.mjs.map +1 -1
  472. package/dist/server/routes/view-configuration.js.map +1 -1
  473. package/dist/server/routes/view-configuration.mjs.map +1 -1
  474. package/dist/server/services/ai-metadata-jobs.js.map +1 -1
  475. package/dist/server/services/ai-metadata-jobs.mjs.map +1 -1
  476. package/dist/server/services/ai-metadata.js.map +1 -1
  477. package/dist/server/services/ai-metadata.mjs.map +1 -1
  478. package/dist/server/services/api-upload-folder.js.map +1 -1
  479. package/dist/server/services/api-upload-folder.mjs.map +1 -1
  480. package/dist/server/services/extensions/index.js.map +1 -1
  481. package/dist/server/services/extensions/index.mjs.map +1 -1
  482. package/dist/server/services/extensions/utils.js.map +1 -1
  483. package/dist/server/services/extensions/utils.mjs.map +1 -1
  484. package/dist/server/services/file.js +120 -1
  485. package/dist/server/services/file.js.map +1 -1
  486. package/dist/server/services/file.mjs +122 -3
  487. package/dist/server/services/file.mjs.map +1 -1
  488. package/dist/server/services/folder.js.map +1 -1
  489. package/dist/server/services/folder.mjs +1 -1
  490. package/dist/server/services/folder.mjs.map +1 -1
  491. package/dist/server/services/image-manipulation.js.map +1 -1
  492. package/dist/server/services/image-manipulation.mjs +1 -1
  493. package/dist/server/services/image-manipulation.mjs.map +1 -1
  494. package/dist/server/services/index.js.map +1 -1
  495. package/dist/server/services/index.mjs.map +1 -1
  496. package/dist/server/services/metrics.js.map +1 -1
  497. package/dist/server/services/metrics.mjs.map +1 -1
  498. package/dist/server/services/provider.js.map +1 -1
  499. package/dist/server/services/provider.mjs.map +1 -1
  500. package/dist/server/services/upload.js.map +1 -1
  501. package/dist/server/services/upload.mjs +1 -1
  502. package/dist/server/services/upload.mjs.map +1 -1
  503. package/dist/server/services/weekly-metrics.js.map +1 -1
  504. package/dist/server/services/weekly-metrics.mjs.map +1 -1
  505. package/dist/server/src/controllers/admin-upload.d.ts +13 -0
  506. package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
  507. package/dist/server/src/controllers/index.d.ts +1 -0
  508. package/dist/server/src/controllers/index.d.ts.map +1 -1
  509. package/dist/server/src/index.d.ts +2 -0
  510. package/dist/server/src/index.d.ts.map +1 -1
  511. package/dist/server/src/routes/admin.d.ts.map +1 -1
  512. package/dist/server/src/services/file.d.ts +15 -0
  513. package/dist/server/src/services/file.d.ts.map +1 -1
  514. package/dist/server/src/services/index.d.ts +1 -0
  515. package/dist/server/src/services/index.d.ts.map +1 -1
  516. package/dist/server/utils/cron.js.map +1 -1
  517. package/dist/server/utils/cron.mjs.map +1 -1
  518. package/dist/server/utils/images.js.map +1 -1
  519. package/dist/server/utils/images.mjs.map +1 -1
  520. package/dist/server/utils/index.js.map +1 -1
  521. package/dist/server/utils/index.mjs.map +1 -1
  522. package/dist/server/utils/mime-validation.js.map +1 -1
  523. package/dist/server/utils/mime-validation.mjs.map +1 -1
  524. package/dist/shared/contracts/files.d.ts +11 -0
  525. package/dist/shared/contracts/files.d.ts.map +1 -1
  526. package/package.json +8 -8
@@ -1,8 +1,11 @@
1
+ import os from 'os';
2
+ import path from 'path';
3
+ import fse from 'fs-extra';
1
4
  import _ from 'lodash';
2
- import { async, errors } from '@strapi/utils';
5
+ import { errors, async } from '@strapi/utils';
3
6
  import { getService } from '../utils/index.mjs';
4
- import { ACTIONS, FILE_MODEL_UID } from '../constants.mjs';
5
- import { validateBulkUpdateBody, validateUploadBody } from './validation/admin/upload.mjs';
7
+ import { FILE_MODEL_UID, ACTIONS } from '../constants.mjs';
8
+ import { validateUploadBody, validateBulkUpdateBody } from './validation/admin/upload.mjs';
6
9
  import { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions.mjs';
7
10
  import { prepareUploadRequest } from '../utils/mime-validation.mjs';
8
11
 
@@ -262,6 +265,147 @@ var adminUpload = {
262
265
  });
263
266
  res.end();
264
267
  },
268
+ /**
269
+ * @experimental
270
+ * Upload files from URLs with SSE streaming for per-file progress
271
+ *
272
+ * Accepts JSON body with URLs and fetches them server-side.
273
+ * Streams Server-Sent Events as each URL is fetched and uploaded:
274
+ * - file:fetching — when starting to fetch a URL
275
+ * - file:uploading — when upload starts for a fetched file
276
+ * - file:complete — when a file is successfully uploaded
277
+ * - file:error — when a URL fetch or upload fails
278
+ * - stream:complete — final summary with all results
279
+ */ async unstable_uploadFromUrls (ctx) {
280
+ const { state: { userAbility, user }, request: { body } } = ctx;
281
+ const uploadService = getService('upload');
282
+ const fileService = getService('file');
283
+ const pm = strapi.service('admin::permission').createPermissionsManager({
284
+ ability: userAbility,
285
+ action: ACTIONS.create,
286
+ model: FILE_MODEL_UID
287
+ });
288
+ if (!pm.isAllowed) {
289
+ return ctx.forbidden();
290
+ }
291
+ // Parse and validate request body
292
+ const { urls, folderId } = body;
293
+ if (!urls || !Array.isArray(urls) || urls.length === 0) {
294
+ throw new errors.ApplicationError('URLs are required');
295
+ }
296
+ if (urls.length > 20) {
297
+ throw new errors.ApplicationError('Maximum 20 URLs allowed per request');
298
+ }
299
+ // Take manual control of the response for SSE streaming
300
+ ctx.respond = false;
301
+ const res = ctx.res;
302
+ res.writeHead(200, {
303
+ 'Content-Type': 'text/event-stream',
304
+ 'Cache-Control': 'no-cache',
305
+ Connection: 'keep-alive'
306
+ });
307
+ const writeSSE = (event, data)=>{
308
+ res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
309
+ };
310
+ const total = urls.length;
311
+ const uploadErrors = [];
312
+ const successfulFiles = [];
313
+ // Create temp directory for fetched files
314
+ const tmpWorkingDirectory = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-url-upload-'));
315
+ const { sizeLimit } = strapi.config.get('plugin::upload');
316
+ try {
317
+ // Process each URL sequentially
318
+ for(let i = 0; i < urls.length; i += 1){
319
+ const url = urls[i];
320
+ writeSSE('file:fetching', {
321
+ url,
322
+ index: i,
323
+ total
324
+ });
325
+ try {
326
+ // Fetch URL to temp file
327
+ const { file } = await fileService.fetchUrlToInputFile(url, tmpWorkingDirectory, sizeLimit);
328
+ const fileName = file.originalFilename;
329
+ writeSSE('file:uploading', {
330
+ name: fileName,
331
+ index: i,
332
+ total,
333
+ size: file.size
334
+ });
335
+ // Validate using security checks
336
+ const fileInfo = {
337
+ name: fileName,
338
+ caption: null,
339
+ alternativeText: null,
340
+ folder: folderId ?? null
341
+ };
342
+ const { validFiles, errors: validationErrors } = await prepareUploadRequest(file, {
343
+ fileInfo: JSON.stringify(fileInfo)
344
+ }, strapi);
345
+ if (validFiles.length === 0) {
346
+ const errorMessage = validationErrors[0]?.message || 'Validation failed';
347
+ uploadErrors.push({
348
+ name: fileName,
349
+ message: errorMessage
350
+ });
351
+ writeSSE('file:error', {
352
+ name: fileName,
353
+ url,
354
+ index: i,
355
+ message: errorMessage
356
+ });
357
+ } else {
358
+ // Upload the file
359
+ const data = await validateUploadBody({
360
+ fileInfo
361
+ }, false);
362
+ const [uploadedFile] = await uploadService.upload({
363
+ data,
364
+ files: [
365
+ validFiles[0]
366
+ ]
367
+ }, {
368
+ user
369
+ });
370
+ // Sign file url
371
+ const signedFile = await fileService.signFileUrls(uploadedFile);
372
+ successfulFiles.push(signedFile);
373
+ writeSSE('file:complete', {
374
+ name: fileName,
375
+ index: i,
376
+ file: signedFile
377
+ });
378
+ }
379
+ } catch (error) {
380
+ const errorMessage = error instanceof Error ? error.message : String(error);
381
+ uploadErrors.push({
382
+ name: url,
383
+ message: errorMessage
384
+ });
385
+ writeSSE('file:error', {
386
+ url,
387
+ index: i,
388
+ message: errorMessage
389
+ });
390
+ }
391
+ }
392
+ // Track image upload metric once if any images were uploaded
393
+ if (successfulFiles.some((file)=>file.mime?.startsWith('image/'))) {
394
+ await getService('metrics').trackUsage('didUploadImage');
395
+ }
396
+ // Send final stream summary
397
+ writeSSE('stream:complete', {
398
+ data: await pm.sanitizeOutput(successfulFiles, {
399
+ action: ACTIONS.read
400
+ }),
401
+ errors: uploadErrors
402
+ });
403
+ } finally{
404
+ // Clean up temp directory
405
+ await fse.remove(tmpWorkingDirectory);
406
+ }
407
+ res.end();
408
+ },
265
409
  // TODO: split into multiple endpoints
266
410
  async upload (ctx) {
267
411
  const { query: { id }, request: { files: { files } = {} } } = ctx;
@@ -1 +1 @@
1
- {"version":3,"file":"admin-upload.mjs","sources":["../../../server/src/controllers/admin-upload.ts"],"sourcesContent":["import _ from 'lodash';\nimport { errors, async } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport { validateBulkUpdateBody, validateUploadBody } from './validation/admin/upload';\nimport { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions';\nimport { FileInfo } from '../types';\nimport { prepareUploadRequest, type FileUploadError } from '../utils/mime-validation';\nimport type { UploadFileInfo } from '../../../shared/contracts/files';\n\nexport default {\n async bulkUpdateFileInfo(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body },\n } = ctx;\n\n const { updates } = await validateBulkUpdateBody(body);\n const uploadService = getService('upload');\n\n const results = await async.map(\n updates,\n async ({ id, fileInfo }: { id: number; fileInfo: FileInfo }) => {\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const updated = await uploadService.updateFileInfo(id, fileInfo as any, { user });\n return pm.sanitizeOutput(updated, { action: ACTIONS.read });\n }\n );\n\n ctx.body = results;\n },\n\n async updateFileInfo(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const data = await validateUploadBody(body);\n\n const file = await uploadService.updateFileInfo(id, data.fileInfo as any, { user });\n\n ctx.body = await pm.sanitizeOutput(file, { action: ACTIONS.read });\n },\n\n async replaceFile(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body, files: { files } = {} },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n if (Array.isArray(files)) {\n throw new errors.ApplicationError('Cannot replace a file with multiple ones');\n }\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(files, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const data = (await validateUploadBody(filteredBody)) as { fileInfo: FileInfo };\n const replacedFile = await uploadService.replace(id, { data, file: validFiles[0] }, { user });\n\n // Sign file urls for private providers\n const signedFile = await getService('file').signFileUrls(replacedFile);\n\n ctx.body = await pm.sanitizeOutput(signedFile, { action: ACTIONS.read });\n },\n\n async uploadFiles(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body, files: { files } = {} },\n } = ctx;\n\n const uploadService = getService('upload');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(files, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const isMultipleFiles = validFiles.length > 1;\n const data = await validateUploadBody(filteredBody, isMultipleFiles);\n\n let filesArray = validFiles;\n\n if (\n data.fileInfo &&\n Array.isArray(data.fileInfo) &&\n filesArray.length === data.fileInfo.length\n ) {\n // Reorder filesArray to match data.fileInfo order\n const alignedFilesArray = data.fileInfo\n .map((info) => {\n return filesArray.find((file) => file.originalFilename === info.name);\n })\n .filter(Boolean) as any[];\n\n filesArray = alignedFilesArray;\n }\n\n // Upload files first to get thumbnails\n const uploadedFiles = await uploadService.upload({ data, files: filesArray }, { user });\n if (uploadedFiles.some((file) => file.mime?.startsWith('image/'))) {\n await getService('metrics').trackUsage('didUploadImage');\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // AFTER upload - generate AI metadata for images\n if (await aiMetadataService.isEnabled()) {\n try {\n const metadataResults = await aiMetadataService.processFiles(uploadedFiles);\n // Update the uploaded files with AI metadata\n await aiMetadataService.updateFilesWithAIMetadata(uploadedFiles, metadataResults, user);\n } catch (error) {\n strapi.log.warn('AI metadata generation failed, proceeding without AI enhancements', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Sign file urls for private providers\n const signedFiles = await async.map(uploadedFiles, getService('file').signFileUrls);\n\n ctx.body = await pm.sanitizeOutput(signedFiles, { action: ACTIONS.read });\n ctx.status = 201;\n },\n\n /**\n * @experimental\n * Stream upload files with SSE streaming for per-file progress\n *\n * Streams Server-Sent Events as each file is validated and uploaded:\n * - file:uploading — when processing starts for a file\n * - file:complete — when a file is successfully uploaded\n * - file:error — when a file fails validation or upload\n * - stream:complete — final summary with all results\n *\n */\n async unstable_uploadFilesStream(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body, files: { files } = {} },\n } = ctx;\n\n const uploadService = getService('upload');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n throw new errors.ApplicationError('Files are empty');\n }\n\n // Take manual control of the response for SSE streaming\n ctx.respond = false;\n const res = ctx.res;\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n });\n\n const writeSSE = (event: string, data: Record<string, unknown>) => {\n res.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n };\n\n // Normalize files to an array\n const filesArray = Array.isArray(files) ? files : [files];\n const total = filesArray.length;\n\n // Parse fileInfo from body\n // Multipart forms send fileInfo as either:\n // - An array of JSON strings (one per file)\n // - A single JSON string (one file, or a JSON-encoded array)\n let parsedFileInfo: UploadFileInfo[] = [];\n if (body?.fileInfo) {\n const raw = body.fileInfo;\n if (Array.isArray(raw)) {\n parsedFileInfo = raw.map((fi: unknown) =>\n typeof fi === 'string' ? JSON.parse(fi) : fi\n ) as UploadFileInfo[];\n } else if (typeof raw === 'string') {\n const parsed = JSON.parse(raw);\n // Handle case where a single string contains a JSON array\n parsedFileInfo = (Array.isArray(parsed) ? parsed : [parsed]) as UploadFileInfo[];\n } else {\n parsedFileInfo = [raw as UploadFileInfo];\n }\n }\n\n const uploadErrors: FileUploadError[] = [];\n const successfulFiles: any[] = [];\n\n // Process each file sequentially with inline validation\n for (let i = 0; i < filesArray.length; i += 1) {\n const file = filesArray[i];\n const fileName = file.originalFilename || 'unknown';\n const fileInfo: UploadFileInfo = parsedFileInfo[i] || {\n name: fileName,\n caption: null,\n alternativeText: null,\n folder: null,\n };\n\n writeSSE('file:uploading', { name: fileName, index: i, total, size: file.size || 0 });\n\n try {\n // Validate this single file using security checks\n const { validFiles, errors: validationErrors } = await prepareUploadRequest(\n file,\n { fileInfo: JSON.stringify(fileInfo) },\n strapi\n );\n\n if (validFiles.length === 0) {\n const errorMessage = validationErrors[0]?.message || 'Validation failed';\n uploadErrors.push({ name: fileName, message: errorMessage });\n writeSSE('file:error', { name: fileName, index: i, message: errorMessage });\n } else {\n // Validate using the already-parsed single fileInfo object directly\n const data = await validateUploadBody({ fileInfo }, false);\n const [uploadedFile] = await uploadService.upload(\n { data, files: [validFiles[0]] },\n { user }\n );\n\n // Sign file url\n const signedFile = await getService('file').signFileUrls(uploadedFile);\n successfulFiles.push(signedFile);\n\n writeSSE('file:complete', { name: fileName, index: i, file: signedFile });\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n uploadErrors.push({ name: fileName, message: errorMessage });\n writeSSE('file:error', { name: fileName, index: i, message: errorMessage });\n }\n }\n\n // Track image upload metric once if any images were uploaded\n if (successfulFiles.some((file) => file.mime?.startsWith('image/'))) {\n await getService('metrics').trackUsage('didUploadImage');\n }\n\n // Send final stream summary\n writeSSE('stream:complete', {\n data: await pm.sanitizeOutput(successfulFiles, { action: ACTIONS.read }),\n errors: uploadErrors,\n });\n\n res.end();\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new errors.ApplicationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n};\n"],"names":["bulkUpdateFileInfo","ctx","state","userAbility","user","request","body","updates","validateBulkUpdateBody","uploadService","getService","results","async","map","id","fileInfo","pm","findEntityAndCheckPermissions","ACTIONS","update","FILE_MODEL_UID","updated","updateFileInfo","sanitizeOutput","action","read","query","errors","ValidationError","data","validateUploadBody","file","replaceFile","files","Array","isArray","ApplicationError","validFiles","filteredBody","validationErrors","prepareUploadRequest","strapi","length","message","replacedFile","replace","signedFile","signFileUrls","uploadFiles","service","createPermissionsManager","ability","create","model","isAllowed","forbidden","isMultipleFiles","filesArray","alignedFilesArray","info","find","originalFilename","name","filter","Boolean","uploadedFiles","upload","some","mime","startsWith","trackUsage","aiMetadataService","isEnabled","metadataResults","processFiles","updateFilesWithAIMetadata","error","log","warn","Error","String","signedFiles","status","unstable_uploadFilesStream","_","isEmpty","size","respond","res","writeHead","Connection","writeSSE","event","write","JSON","stringify","total","parsedFileInfo","raw","fi","parse","parsed","uploadErrors","successfulFiles","i","fileName","caption","alternativeText","folder","index","errorMessage","push","uploadedFile","end"],"mappings":"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"}
1
+ {"version":3,"file":"admin-upload.mjs","sources":["../../../server/src/controllers/admin-upload.ts"],"sourcesContent":["import os from 'os';\nimport path from 'path';\nimport fse from 'fs-extra';\nimport _ from 'lodash';\nimport { errors, async } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport { validateBulkUpdateBody, validateUploadBody } from './validation/admin/upload';\nimport { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions';\nimport { Config, FileInfo } from '../types';\nimport { prepareUploadRequest, type FileUploadError } from '../utils/mime-validation';\nimport type { UploadFileInfo } from '../../../shared/contracts/files';\n\nexport default {\n async bulkUpdateFileInfo(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body },\n } = ctx;\n\n const { updates } = await validateBulkUpdateBody(body);\n const uploadService = getService('upload');\n\n const results = await async.map(\n updates,\n async ({ id, fileInfo }: { id: number; fileInfo: FileInfo }) => {\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const updated = await uploadService.updateFileInfo(id, fileInfo as any, { user });\n return pm.sanitizeOutput(updated, { action: ACTIONS.read });\n }\n );\n\n ctx.body = results;\n },\n\n async updateFileInfo(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const data = await validateUploadBody(body);\n\n const file = await uploadService.updateFileInfo(id, data.fileInfo as any, { user });\n\n ctx.body = await pm.sanitizeOutput(file, { action: ACTIONS.read });\n },\n\n async replaceFile(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body, files: { files } = {} },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n if (Array.isArray(files)) {\n throw new errors.ApplicationError('Cannot replace a file with multiple ones');\n }\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(files, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const data = (await validateUploadBody(filteredBody)) as { fileInfo: FileInfo };\n const replacedFile = await uploadService.replace(id, { data, file: validFiles[0] }, { user });\n\n // Sign file urls for private providers\n const signedFile = await getService('file').signFileUrls(replacedFile);\n\n ctx.body = await pm.sanitizeOutput(signedFile, { action: ACTIONS.read });\n },\n\n async uploadFiles(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body, files: { files } = {} },\n } = ctx;\n\n const uploadService = getService('upload');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(files, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const isMultipleFiles = validFiles.length > 1;\n const data = await validateUploadBody(filteredBody, isMultipleFiles);\n\n let filesArray = validFiles;\n\n if (\n data.fileInfo &&\n Array.isArray(data.fileInfo) &&\n filesArray.length === data.fileInfo.length\n ) {\n // Reorder filesArray to match data.fileInfo order\n const alignedFilesArray = data.fileInfo\n .map((info) => {\n return filesArray.find((file) => file.originalFilename === info.name);\n })\n .filter(Boolean) as any[];\n\n filesArray = alignedFilesArray;\n }\n\n // Upload files first to get thumbnails\n const uploadedFiles = await uploadService.upload({ data, files: filesArray }, { user });\n if (uploadedFiles.some((file) => file.mime?.startsWith('image/'))) {\n await getService('metrics').trackUsage('didUploadImage');\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // AFTER upload - generate AI metadata for images\n if (await aiMetadataService.isEnabled()) {\n try {\n const metadataResults = await aiMetadataService.processFiles(uploadedFiles);\n // Update the uploaded files with AI metadata\n await aiMetadataService.updateFilesWithAIMetadata(uploadedFiles, metadataResults, user);\n } catch (error) {\n strapi.log.warn('AI metadata generation failed, proceeding without AI enhancements', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Sign file urls for private providers\n const signedFiles = await async.map(uploadedFiles, getService('file').signFileUrls);\n\n ctx.body = await pm.sanitizeOutput(signedFiles, { action: ACTIONS.read });\n ctx.status = 201;\n },\n\n /**\n * @experimental\n * Stream upload files with SSE streaming for per-file progress\n *\n * Streams Server-Sent Events as each file is validated and uploaded:\n * - file:uploading — when processing starts for a file\n * - file:complete — when a file is successfully uploaded\n * - file:error — when a file fails validation or upload\n * - stream:complete — final summary with all results\n *\n */\n async unstable_uploadFilesStream(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body, files: { files } = {} },\n } = ctx;\n\n const uploadService = getService('upload');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n throw new errors.ApplicationError('Files are empty');\n }\n\n // Take manual control of the response for SSE streaming\n ctx.respond = false;\n const res = ctx.res;\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n });\n\n const writeSSE = (event: string, data: Record<string, unknown>) => {\n res.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n };\n\n // Normalize files to an array\n const filesArray = Array.isArray(files) ? files : [files];\n const total = filesArray.length;\n\n // Parse fileInfo from body\n // Multipart forms send fileInfo as either:\n // - An array of JSON strings (one per file)\n // - A single JSON string (one file, or a JSON-encoded array)\n let parsedFileInfo: UploadFileInfo[] = [];\n if (body?.fileInfo) {\n const raw = body.fileInfo;\n if (Array.isArray(raw)) {\n parsedFileInfo = raw.map((fi: unknown) =>\n typeof fi === 'string' ? JSON.parse(fi) : fi\n ) as UploadFileInfo[];\n } else if (typeof raw === 'string') {\n const parsed = JSON.parse(raw);\n // Handle case where a single string contains a JSON array\n parsedFileInfo = (Array.isArray(parsed) ? parsed : [parsed]) as UploadFileInfo[];\n } else {\n parsedFileInfo = [raw as UploadFileInfo];\n }\n }\n\n const uploadErrors: FileUploadError[] = [];\n const successfulFiles: any[] = [];\n\n // Process each file sequentially with inline validation\n for (let i = 0; i < filesArray.length; i += 1) {\n const file = filesArray[i];\n const fileName = file.originalFilename || 'unknown';\n const fileInfo: UploadFileInfo = parsedFileInfo[i] || {\n name: fileName,\n caption: null,\n alternativeText: null,\n folder: null,\n };\n\n writeSSE('file:uploading', { name: fileName, index: i, total, size: file.size || 0 });\n\n try {\n // Validate this single file using security checks\n const { validFiles, errors: validationErrors } = await prepareUploadRequest(\n file,\n { fileInfo: JSON.stringify(fileInfo) },\n strapi\n );\n\n if (validFiles.length === 0) {\n const errorMessage = validationErrors[0]?.message || 'Validation failed';\n uploadErrors.push({ name: fileName, message: errorMessage });\n writeSSE('file:error', { name: fileName, index: i, message: errorMessage });\n } else {\n // Validate using the already-parsed single fileInfo object directly\n const data = await validateUploadBody({ fileInfo }, false);\n const [uploadedFile] = await uploadService.upload(\n { data, files: [validFiles[0]] },\n { user }\n );\n\n // Sign file url\n const signedFile = await getService('file').signFileUrls(uploadedFile);\n successfulFiles.push(signedFile);\n\n writeSSE('file:complete', { name: fileName, index: i, file: signedFile });\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n uploadErrors.push({ name: fileName, message: errorMessage });\n writeSSE('file:error', { name: fileName, index: i, message: errorMessage });\n }\n }\n\n // Track image upload metric once if any images were uploaded\n if (successfulFiles.some((file) => file.mime?.startsWith('image/'))) {\n await getService('metrics').trackUsage('didUploadImage');\n }\n\n // Send final stream summary\n writeSSE('stream:complete', {\n data: await pm.sanitizeOutput(successfulFiles, { action: ACTIONS.read }),\n errors: uploadErrors,\n });\n\n res.end();\n },\n\n /**\n * @experimental\n * Upload files from URLs with SSE streaming for per-file progress\n *\n * Accepts JSON body with URLs and fetches them server-side.\n * Streams Server-Sent Events as each URL is fetched and uploaded:\n * - file:fetching — when starting to fetch a URL\n * - file:uploading — when upload starts for a fetched file\n * - file:complete — when a file is successfully uploaded\n * - file:error — when a URL fetch or upload fails\n * - stream:complete — final summary with all results\n */\n async unstable_uploadFromUrls(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body },\n } = ctx;\n\n const uploadService = getService('upload');\n const fileService = getService('file');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n // Parse and validate request body\n const { urls, folderId } = body as { urls?: string[]; folderId?: number | null };\n\n if (!urls || !Array.isArray(urls) || urls.length === 0) {\n throw new errors.ApplicationError('URLs are required');\n }\n\n if (urls.length > 20) {\n throw new errors.ApplicationError('Maximum 20 URLs allowed per request');\n }\n\n // Take manual control of the response for SSE streaming\n ctx.respond = false;\n const res = ctx.res;\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n });\n\n const writeSSE = (event: string, data: Record<string, unknown>) => {\n res.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n };\n\n const total = urls.length;\n const uploadErrors: FileUploadError[] = [];\n const successfulFiles: any[] = [];\n\n // Create temp directory for fetched files\n const tmpWorkingDirectory = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-url-upload-'));\n const { sizeLimit } = strapi.config.get<Config>('plugin::upload');\n\n try {\n // Process each URL sequentially\n for (let i = 0; i < urls.length; i += 1) {\n const url = urls[i];\n\n writeSSE('file:fetching', { url, index: i, total });\n\n try {\n // Fetch URL to temp file\n const { file } = await fileService.fetchUrlToInputFile(\n url,\n tmpWorkingDirectory,\n sizeLimit\n );\n const fileName = file.originalFilename;\n\n writeSSE('file:uploading', {\n name: fileName,\n index: i,\n total,\n size: file.size,\n });\n\n // Validate using security checks\n const fileInfo: UploadFileInfo = {\n name: fileName,\n caption: null,\n alternativeText: null,\n folder: folderId ?? null,\n };\n\n const { validFiles, errors: validationErrors } = await prepareUploadRequest(\n file,\n { fileInfo: JSON.stringify(fileInfo) },\n strapi\n );\n\n if (validFiles.length === 0) {\n const errorMessage = validationErrors[0]?.message || 'Validation failed';\n uploadErrors.push({ name: fileName, message: errorMessage });\n writeSSE('file:error', { name: fileName, url, index: i, message: errorMessage });\n } else {\n // Upload the file\n const data = await validateUploadBody({ fileInfo }, false);\n const [uploadedFile] = await uploadService.upload(\n { data, files: [validFiles[0]] },\n { user }\n );\n\n // Sign file url\n const signedFile = await fileService.signFileUrls(uploadedFile);\n successfulFiles.push(signedFile);\n\n writeSSE('file:complete', { name: fileName, index: i, file: signedFile });\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n uploadErrors.push({ name: url, message: errorMessage });\n writeSSE('file:error', { url, index: i, message: errorMessage });\n }\n }\n\n // Track image upload metric once if any images were uploaded\n if (successfulFiles.some((file) => file.mime?.startsWith('image/'))) {\n await getService('metrics').trackUsage('didUploadImage');\n }\n\n // Send final stream summary\n writeSSE('stream:complete', {\n data: await pm.sanitizeOutput(successfulFiles, { action: ACTIONS.read }),\n errors: uploadErrors,\n });\n } finally {\n // Clean up temp directory\n await fse.remove(tmpWorkingDirectory);\n }\n\n res.end();\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new errors.ApplicationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n};\n"],"names":["bulkUpdateFileInfo","ctx","state","userAbility","user","request","body","updates","validateBulkUpdateBody","uploadService","getService","results","async","map","id","fileInfo","pm","findEntityAndCheckPermissions","ACTIONS","update","FILE_MODEL_UID","updated","updateFileInfo","sanitizeOutput","action","read","query","errors","ValidationError","data","validateUploadBody","file","replaceFile","files","Array","isArray","ApplicationError","validFiles","filteredBody","validationErrors","prepareUploadRequest","strapi","length","message","replacedFile","replace","signedFile","signFileUrls","uploadFiles","service","createPermissionsManager","ability","create","model","isAllowed","forbidden","isMultipleFiles","filesArray","alignedFilesArray","info","find","originalFilename","name","filter","Boolean","uploadedFiles","upload","some","mime","startsWith","trackUsage","aiMetadataService","isEnabled","metadataResults","processFiles","updateFilesWithAIMetadata","error","log","warn","Error","String","signedFiles","status","unstable_uploadFilesStream","_","isEmpty","size","respond","res","writeHead","Connection","writeSSE","event","write","JSON","stringify","total","parsedFileInfo","raw","fi","parse","parsed","uploadErrors","successfulFiles","i","fileName","caption","alternativeText","folder","index","errorMessage","push","uploadedFile","end","unstable_uploadFromUrls","fileService","urls","folderId","tmpWorkingDirectory","fse","mkdtemp","path","join","os","tmpdir","sizeLimit","config","get","url","fetchUrlToInputFile","remove"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"content-api.js","sources":["../../../server/src/controllers/content-api.ts"],"sourcesContent":["import _ from 'lodash';\nimport utils, { errors } from '@strapi/utils';\n\nimport type { Context } from 'koa';\nimport type { Core } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { FILE_MODEL_UID } from '../constants';\nimport { validateUploadBody } from './validation/content-api/upload';\nimport { FileInfo } from '../types';\nimport { prepareUploadRequest } from '../utils/mime-validation';\n\nconst { ValidationError } = utils.errors;\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => {\n const sanitizeOutput = async (data: unknown | unknown[], ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth } = ctx.state;\n\n return strapi.contentAPI.sanitize.output(data, schema, { auth });\n };\n\n const validateQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.validate.query(data, schema, { auth, route });\n };\n\n const sanitizeQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.sanitize.query(data, schema, { auth, route });\n };\n\n return {\n async find(ctx: Context) {\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const files = await getService('upload').findMany(sanitizedQuery);\n\n ctx.body = await sanitizeOutput(files, ctx);\n },\n\n async findOne(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const file = await getService('upload').findOne(id, sanitizedQuery.populate!);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n ctx.body = await sanitizeOutput(file, ctx);\n },\n\n async destroy(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n const file = await getService('upload').findOne(id);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n await getService('upload').remove(file);\n\n ctx.body = await sanitizeOutput(file, ctx);\n },\n\n async updateFileInfo(ctx: Context) {\n const {\n query: { id },\n request: { body },\n } = ctx;\n const data = await validateUploadBody(body);\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const result = await getService('upload').updateFileInfo(id, data.fileInfo as any);\n\n ctx.body = await sanitizeOutput(result, ctx);\n },\n\n async replaceFile(ctx: Context) {\n const {\n query: { id },\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n // cannot replace with more than one file\n if (Array.isArray(filesInput)) {\n throw new ValidationError('Cannot replace a file with multiple ones');\n }\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const data = (await validateUploadBody(filteredBody)) as { fileInfo: FileInfo };\n\n const replacedFiles = await getService('upload').replace(id, { data, file: validFiles[0] });\n\n ctx.body = await sanitizeOutput(replacedFiles, ctx);\n },\n\n async uploadFiles(ctx: Context) {\n const {\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const isMultipleFiles = validFiles.length > 1;\n const data: any = await validateUploadBody(filteredBody, isMultipleFiles);\n\n const apiUploadFolderService = getService('api-upload-folder');\n\n const apiUploadFolder = await apiUploadFolderService.getAPIUploadFolder();\n\n if (isMultipleFiles) {\n data.fileInfo = data.fileInfo || [];\n data.fileInfo = validFiles.map((_f, i) => ({\n ...data.fileInfo[i],\n folder: apiUploadFolder.id,\n }));\n } else {\n data.fileInfo = { ...data.fileInfo, folder: apiUploadFolder.id };\n }\n\n const uploadedFiles = await getService('upload').upload({\n data,\n files: validFiles,\n });\n\n ctx.body = await sanitizeOutput(uploadedFiles as any, ctx);\n ctx.status = 201;\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new ValidationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n };\n};\n"],"names":["ValidationError","utils","errors","strapi","sanitizeOutput","data","ctx","schema","getModel","FILE_MODEL_UID","auth","state","contentAPI","sanitize","output","validateQuery","route","validate","query","sanitizeQuery","find","sanitizedQuery","files","getService","findMany","body","findOne","params","id","file","populate","notFound","destroy","remove","updateFileInfo","request","validateUploadBody","result","fileInfo","replaceFile","filesInput","validFiles","filteredBody","validationErrors","prepareUploadRequest","length","message","Array","isArray","replacedFiles","replace","uploadFiles","isMultipleFiles","apiUploadFolderService","apiUploadFolder","getAPIUploadFolder","map","_f","i","folder","uploadedFiles","upload","status","_","isEmpty","size"],"mappings":";;;;;;;;;AAYA,MAAM,EAAEA,eAAe,EAAE,GAAGC,MAAMC,MAAM;AAExC,iBAAe,CAAA,CAAC,EAAEC,MAAM,EAA2B,GAAA;IACjD,MAAMC,cAAAA,GAAiB,OAAOC,IAA2BC,EAAAA,GAAAA,GAAAA;QACvD,MAAMC,MAAAA,GAASJ,MAAOK,CAAAA,QAAQ,CAACC,wBAAAA,CAAAA;AAC/B,QAAA,MAAM,EAAEC,IAAI,EAAE,GAAGJ,IAAIK,KAAK;QAE1B,OAAOR,MAAAA,CAAOS,UAAU,CAACC,QAAQ,CAACC,MAAM,CAACT,MAAME,MAAQ,EAAA;AAAEG,YAAAA;AAAK,SAAA,CAAA;AAChE,KAAA;IAEA,MAAMK,aAAAA,GAAgB,OAAOV,IAA+BC,EAAAA,GAAAA,GAAAA;QAC1D,MAAMC,MAAAA,GAASJ,MAAOK,CAAAA,QAAQ,CAACC,wBAAAA,CAAAA;AAC/B,QAAA,MAAM,EAAEC,IAAI,EAAEM,KAAK,EAAE,GAAGV,IAAIK,KAAK;QAEjC,OAAOR,MAAAA,CAAOS,UAAU,CAACK,QAAQ,CAACC,KAAK,CAACb,MAAME,MAAQ,EAAA;AAAEG,YAAAA,IAAAA;AAAMM,YAAAA;AAAM,SAAA,CAAA;AACtE,KAAA;IAEA,MAAMG,aAAAA,GAAgB,OAAOd,IAA+BC,EAAAA,GAAAA,GAAAA;QAC1D,MAAMC,MAAAA,GAASJ,MAAOK,CAAAA,QAAQ,CAACC,wBAAAA,CAAAA;AAC/B,QAAA,MAAM,EAAEC,IAAI,EAAEM,KAAK,EAAE,GAAGV,IAAIK,KAAK;QAEjC,OAAOR,MAAAA,CAAOS,UAAU,CAACC,QAAQ,CAACK,KAAK,CAACb,MAAME,MAAQ,EAAA;AAAEG,YAAAA,IAAAA;AAAMM,YAAAA;AAAM,SAAA,CAAA;AACtE,KAAA;IAEA,OAAO;AACL,QAAA,MAAMI,MAAKd,GAAY,EAAA;YACrB,MAAMS,aAAAA,CAAcT,GAAIY,CAAAA,KAAK,EAAEZ,GAAAA,CAAAA;AAC/B,YAAA,MAAMe,cAAiB,GAAA,MAAMF,aAAcb,CAAAA,GAAAA,CAAIY,KAAK,EAAEZ,GAAAA,CAAAA;AAEtD,YAAA,MAAMgB,KAAQ,GAAA,MAAMC,gBAAW,CAAA,QAAA,CAAA,CAAUC,QAAQ,CAACH,cAAAA,CAAAA;AAElDf,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAekB,KAAOhB,EAAAA,GAAAA,CAAAA;AACzC,SAAA;AAEA,QAAA,MAAMoB,SAAQpB,GAAY,EAAA;AACxB,YAAA,MAAM,EACJqB,MAAQ,EAAA,EAAEC,EAAE,EAAE,EACf,GAAGtB,GAAAA;YAEJ,MAAMS,aAAAA,CAAcT,GAAIY,CAAAA,KAAK,EAAEZ,GAAAA,CAAAA;AAC/B,YAAA,MAAMe,cAAiB,GAAA,MAAMF,aAAcb,CAAAA,GAAAA,CAAIY,KAAK,EAAEZ,GAAAA,CAAAA;YAEtD,MAAMuB,IAAAA,GAAO,MAAMN,gBAAW,CAAA,QAAA,CAAA,CAAUG,OAAO,CAACE,EAAAA,EAAIP,eAAeS,QAAQ,CAAA;AAE3E,YAAA,IAAI,CAACD,IAAM,EAAA;gBACT,OAAOvB,GAAAA,CAAIyB,QAAQ,CAAC,eAAA,CAAA;AACtB;AAEAzB,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAeyB,IAAMvB,EAAAA,GAAAA,CAAAA;AACxC,SAAA;AAEA,QAAA,MAAM0B,SAAQ1B,GAAY,EAAA;AACxB,YAAA,MAAM,EACJqB,MAAQ,EAAA,EAAEC,EAAE,EAAE,EACf,GAAGtB,GAAAA;AAEJ,YAAA,MAAMuB,IAAO,GAAA,MAAMN,gBAAW,CAAA,QAAA,CAAA,CAAUG,OAAO,CAACE,EAAAA,CAAAA;AAEhD,YAAA,IAAI,CAACC,IAAM,EAAA;gBACT,OAAOvB,GAAAA,CAAIyB,QAAQ,CAAC,eAAA,CAAA;AACtB;YAEA,MAAMR,gBAAAA,CAAW,QAAUU,CAAAA,CAAAA,MAAM,CAACJ,IAAAA,CAAAA;AAElCvB,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAeyB,IAAMvB,EAAAA,GAAAA,CAAAA;AACxC,SAAA;AAEA,QAAA,MAAM4B,gBAAe5B,GAAY,EAAA;YAC/B,MAAM,EACJY,KAAO,EAAA,EAAEU,EAAE,EAAE,EACbO,OAAAA,EAAS,EAAEV,IAAI,EAAE,EAClB,GAAGnB,GAAAA;YACJ,MAAMD,IAAAA,GAAO,MAAM+B,yBAAmBX,CAAAA,IAAAA,CAAAA;AAEtC,YAAA,IAAI,CAACG,EAAO,IAAA,OAAOA,OAAO,QAAY,IAAA,OAAOA,OAAO,QAAW,EAAA;AAC7D,gBAAA,MAAM,IAAI5B,eAAgB,CAAA,gDAAA,CAAA;AAC5B;YAEA,MAAMqC,MAAAA,GAAS,MAAMd,gBAAW,CAAA,QAAA,CAAA,CAAUW,cAAc,CAACN,EAAAA,EAAIvB,KAAKiC,QAAQ,CAAA;AAE1EhC,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAeiC,MAAQ/B,EAAAA,GAAAA,CAAAA;AAC1C,SAAA;AAEA,QAAA,MAAMiC,aAAYjC,GAAY,EAAA;YAC5B,MAAM,EACJY,OAAO,EAAEU,EAAE,EAAE,EACbO,OAAAA,EAAS,EAAEV,IAAI,EAAEH,OAAO,EAAEA,KAAAA,EAAOkB,UAAU,EAAE,GAAG,EAAE,EAAE,EACrD,GAAGlC,GAAAA;AAEJ,YAAA,MAAM,EACJmC,UAAU,EACVC,YAAY,EACZxC,MAAAA,EAAQyC,gBAAgB,EACzB,GAAG,MAAMC,mCAAqBJ,CAAAA,UAAAA,EAAYf,IAAMtB,EAAAA,MAAAA,CAAAA;YACjD,IAAIsC,UAAAA,CAAWI,MAAM,KAAK,CAAG,EAAA;gBAC3B,MAAM,IAAI3C,aAAOF,eAAe,CAAC2C,gBAAgB,CAAC,CAAA,CAAE,CAACG,OAAO,CAAA;AAC9D;;YAGA,IAAIC,KAAAA,CAAMC,OAAO,CAACR,UAAa,CAAA,EAAA;AAC7B,gBAAA,MAAM,IAAIxC,eAAgB,CAAA,0CAAA,CAAA;AAC5B;AAEA,YAAA,IAAI,CAAC4B,EAAO,IAAA,OAAOA,OAAO,QAAY,IAAA,OAAOA,OAAO,QAAW,EAAA;AAC7D,gBAAA,MAAM,IAAI5B,eAAgB,CAAA,gDAAA,CAAA;AAC5B;YAEA,MAAMK,IAAAA,GAAQ,MAAM+B,yBAAmBM,CAAAA,YAAAA,CAAAA;AAEvC,YAAA,MAAMO,gBAAgB,MAAM1B,gBAAAA,CAAW,QAAU2B,CAAAA,CAAAA,OAAO,CAACtB,EAAI,EAAA;AAAEvB,gBAAAA,IAAAA;gBAAMwB,IAAMY,EAAAA,UAAU,CAAC,CAAE;AAAC,aAAA,CAAA;AAEzFnC,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAe6C,aAAe3C,EAAAA,GAAAA,CAAAA;AACjD,SAAA;AAEA,QAAA,MAAM6C,aAAY7C,GAAY,EAAA;AAC5B,YAAA,MAAM,EACJ6B,OAAAA,EAAS,EAAEV,IAAI,EAAEH,KAAO,EAAA,EAAEA,KAAOkB,EAAAA,UAAU,EAAE,GAAG,EAAE,EAAE,EACrD,GAAGlC,GAAAA;AAEJ,YAAA,MAAM,EACJmC,UAAU,EACVC,YAAY,EACZxC,MAAAA,EAAQyC,gBAAgB,EACzB,GAAG,MAAMC,mCAAqBJ,CAAAA,UAAAA,EAAYf,IAAMtB,EAAAA,MAAAA,CAAAA;YACjD,IAAIsC,UAAAA,CAAWI,MAAM,KAAK,CAAG,EAAA;gBAC3B,MAAM,IAAI3C,aAAOF,eAAe,CAAC2C,gBAAgB,CAAC,CAAA,CAAE,CAACG,OAAO,CAAA;AAC9D;YAEA,MAAMM,eAAAA,GAAkBX,UAAWI,CAAAA,MAAM,GAAG,CAAA;YAC5C,MAAMxC,IAAAA,GAAY,MAAM+B,yBAAAA,CAAmBM,YAAcU,EAAAA,eAAAA,CAAAA;AAEzD,YAAA,MAAMC,yBAAyB9B,gBAAW,CAAA,mBAAA,CAAA;YAE1C,MAAM+B,eAAAA,GAAkB,MAAMD,sBAAAA,CAAuBE,kBAAkB,EAAA;AAEvE,YAAA,IAAIH,eAAiB,EAAA;AACnB/C,gBAAAA,IAAAA,CAAKiC,QAAQ,GAAGjC,IAAKiC,CAAAA,QAAQ,IAAI,EAAE;gBACnCjC,IAAKiC,CAAAA,QAAQ,GAAGG,UAAWe,CAAAA,GAAG,CAAC,CAACC,EAAAA,EAAIC,KAAO;wBACzC,GAAGrD,IAAAA,CAAKiC,QAAQ,CAACoB,CAAE,CAAA;AACnBC,wBAAAA,MAAAA,EAAQL,gBAAgB1B;qBAC1B,CAAA,CAAA;aACK,MAAA;AACLvB,gBAAAA,IAAAA,CAAKiC,QAAQ,GAAG;AAAE,oBAAA,GAAGjC,KAAKiC,QAAQ;AAAEqB,oBAAAA,MAAAA,EAAQL,gBAAgB1B;AAAG,iBAAA;AACjE;AAEA,YAAA,MAAMgC,aAAgB,GAAA,MAAMrC,gBAAW,CAAA,QAAA,CAAA,CAAUsC,MAAM,CAAC;AACtDxD,gBAAAA,IAAAA;gBACAiB,KAAOmB,EAAAA;AACT,aAAA,CAAA;AAEAnC,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAewD,aAAsBtD,EAAAA,GAAAA,CAAAA;AACtDA,YAAAA,GAAAA,CAAIwD,MAAM,GAAG,GAAA;AACf,SAAA;;AAGA,QAAA,MAAMD,QAAOvD,GAAY,EAAA;AACvB,YAAA,MAAM,EACJY,KAAO,EAAA,EAAEU,EAAE,EAAE,EACbO,OAAS,EAAA,EAAEb,KAAO,EAAA,EAAEA,KAAK,EAAE,GAAG,EAAE,EAAE,EACnC,GAAGhB,GAAAA;AAEJ,YAAA,IAAIyD,CAAEC,CAAAA,OAAO,CAAC1C,KAAAA,CAAAA,IAAW,CAACyB,KAAAA,CAAMC,OAAO,CAAC1B,KAAUA,CAAAA,IAAAA,KAAAA,CAAM2C,IAAI,KAAK,CAAI,EAAA;AACnE,gBAAA,IAAIrC,EAAI,EAAA;oBACN,OAAO,IAAI,CAACM,cAAc,CAAC5B,GAAAA,CAAAA;AAC7B;AAEA,gBAAA,MAAM,IAAIN,eAAgB,CAAA,iBAAA,CAAA;AAC5B;YAEA,MAAO4B,CAAAA,EAAAA,GAAK,IAAI,CAACW,WAAW,GAAG,IAAI,CAACY,WAAU,EAAG7C,GAAAA,CAAAA;AACnD;AACF,KAAA;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"content-api.js","sources":["../../../server/src/controllers/content-api.ts"],"sourcesContent":["import _ from 'lodash';\nimport utils, { errors } from '@strapi/utils';\n\nimport type { Context } from 'koa';\nimport type { Core } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { FILE_MODEL_UID } from '../constants';\nimport { validateUploadBody } from './validation/content-api/upload';\nimport { FileInfo } from '../types';\nimport { prepareUploadRequest } from '../utils/mime-validation';\n\nconst { ValidationError } = utils.errors;\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => {\n const sanitizeOutput = async (data: unknown | unknown[], ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth } = ctx.state;\n\n return strapi.contentAPI.sanitize.output(data, schema, { auth });\n };\n\n const validateQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.validate.query(data, schema, { auth, route });\n };\n\n const sanitizeQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.sanitize.query(data, schema, { auth, route });\n };\n\n return {\n async find(ctx: Context) {\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const files = await getService('upload').findMany(sanitizedQuery);\n\n ctx.body = await sanitizeOutput(files, ctx);\n },\n\n async findOne(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const file = await getService('upload').findOne(id, sanitizedQuery.populate!);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n ctx.body = await sanitizeOutput(file, ctx);\n },\n\n async destroy(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n const file = await getService('upload').findOne(id);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n await getService('upload').remove(file);\n\n ctx.body = await sanitizeOutput(file, ctx);\n },\n\n async updateFileInfo(ctx: Context) {\n const {\n query: { id },\n request: { body },\n } = ctx;\n const data = await validateUploadBody(body);\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const result = await getService('upload').updateFileInfo(id, data.fileInfo as any);\n\n ctx.body = await sanitizeOutput(result, ctx);\n },\n\n async replaceFile(ctx: Context) {\n const {\n query: { id },\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n // cannot replace with more than one file\n if (Array.isArray(filesInput)) {\n throw new ValidationError('Cannot replace a file with multiple ones');\n }\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const data = (await validateUploadBody(filteredBody)) as { fileInfo: FileInfo };\n\n const replacedFiles = await getService('upload').replace(id, { data, file: validFiles[0] });\n\n ctx.body = await sanitizeOutput(replacedFiles, ctx);\n },\n\n async uploadFiles(ctx: Context) {\n const {\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const isMultipleFiles = validFiles.length > 1;\n const data: any = await validateUploadBody(filteredBody, isMultipleFiles);\n\n const apiUploadFolderService = getService('api-upload-folder');\n\n const apiUploadFolder = await apiUploadFolderService.getAPIUploadFolder();\n\n if (isMultipleFiles) {\n data.fileInfo = data.fileInfo || [];\n data.fileInfo = validFiles.map((_f, i) => ({\n ...data.fileInfo[i],\n folder: apiUploadFolder.id,\n }));\n } else {\n data.fileInfo = { ...data.fileInfo, folder: apiUploadFolder.id };\n }\n\n const uploadedFiles = await getService('upload').upload({\n data,\n files: validFiles,\n });\n\n ctx.body = await sanitizeOutput(uploadedFiles as any, ctx);\n ctx.status = 201;\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new ValidationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n };\n};\n"],"names":["ValidationError","utils","errors","strapi","sanitizeOutput","data","ctx","schema","getModel","FILE_MODEL_UID","auth","state","contentAPI","sanitize","output","validateQuery","route","validate","query","sanitizeQuery","find","sanitizedQuery","files","getService","findMany","body","findOne","params","id","file","populate","notFound","destroy","remove","updateFileInfo","request","validateUploadBody","result","fileInfo","replaceFile","filesInput","validFiles","filteredBody","validationErrors","prepareUploadRequest","length","message","Array","isArray","replacedFiles","replace","uploadFiles","isMultipleFiles","apiUploadFolderService","apiUploadFolder","getAPIUploadFolder","map","_f","i","folder","uploadedFiles","upload","status","_","isEmpty","size"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"content-api.mjs","sources":["../../../server/src/controllers/content-api.ts"],"sourcesContent":["import _ from 'lodash';\nimport utils, { errors } from '@strapi/utils';\n\nimport type { Context } from 'koa';\nimport type { Core } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { FILE_MODEL_UID } from '../constants';\nimport { validateUploadBody } from './validation/content-api/upload';\nimport { FileInfo } from '../types';\nimport { prepareUploadRequest } from '../utils/mime-validation';\n\nconst { ValidationError } = utils.errors;\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => {\n const sanitizeOutput = async (data: unknown | unknown[], ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth } = ctx.state;\n\n return strapi.contentAPI.sanitize.output(data, schema, { auth });\n };\n\n const validateQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.validate.query(data, schema, { auth, route });\n };\n\n const sanitizeQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.sanitize.query(data, schema, { auth, route });\n };\n\n return {\n async find(ctx: Context) {\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const files = await getService('upload').findMany(sanitizedQuery);\n\n ctx.body = await sanitizeOutput(files, ctx);\n },\n\n async findOne(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const file = await getService('upload').findOne(id, sanitizedQuery.populate!);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n ctx.body = await sanitizeOutput(file, ctx);\n },\n\n async destroy(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n const file = await getService('upload').findOne(id);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n await getService('upload').remove(file);\n\n ctx.body = await sanitizeOutput(file, ctx);\n },\n\n async updateFileInfo(ctx: Context) {\n const {\n query: { id },\n request: { body },\n } = ctx;\n const data = await validateUploadBody(body);\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const result = await getService('upload').updateFileInfo(id, data.fileInfo as any);\n\n ctx.body = await sanitizeOutput(result, ctx);\n },\n\n async replaceFile(ctx: Context) {\n const {\n query: { id },\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n // cannot replace with more than one file\n if (Array.isArray(filesInput)) {\n throw new ValidationError('Cannot replace a file with multiple ones');\n }\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const data = (await validateUploadBody(filteredBody)) as { fileInfo: FileInfo };\n\n const replacedFiles = await getService('upload').replace(id, { data, file: validFiles[0] });\n\n ctx.body = await sanitizeOutput(replacedFiles, ctx);\n },\n\n async uploadFiles(ctx: Context) {\n const {\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const isMultipleFiles = validFiles.length > 1;\n const data: any = await validateUploadBody(filteredBody, isMultipleFiles);\n\n const apiUploadFolderService = getService('api-upload-folder');\n\n const apiUploadFolder = await apiUploadFolderService.getAPIUploadFolder();\n\n if (isMultipleFiles) {\n data.fileInfo = data.fileInfo || [];\n data.fileInfo = validFiles.map((_f, i) => ({\n ...data.fileInfo[i],\n folder: apiUploadFolder.id,\n }));\n } else {\n data.fileInfo = { ...data.fileInfo, folder: apiUploadFolder.id };\n }\n\n const uploadedFiles = await getService('upload').upload({\n data,\n files: validFiles,\n });\n\n ctx.body = await sanitizeOutput(uploadedFiles as any, ctx);\n ctx.status = 201;\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new ValidationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n };\n};\n"],"names":["ValidationError","utils","errors","strapi","sanitizeOutput","data","ctx","schema","getModel","FILE_MODEL_UID","auth","state","contentAPI","sanitize","output","validateQuery","route","validate","query","sanitizeQuery","find","sanitizedQuery","files","getService","findMany","body","findOne","params","id","file","populate","notFound","destroy","remove","updateFileInfo","request","validateUploadBody","result","fileInfo","replaceFile","filesInput","validFiles","filteredBody","validationErrors","prepareUploadRequest","length","message","Array","isArray","replacedFiles","replace","uploadFiles","isMultipleFiles","apiUploadFolderService","apiUploadFolder","getAPIUploadFolder","map","_f","i","folder","uploadedFiles","upload","status","_","isEmpty","size"],"mappings":"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"}
1
+ {"version":3,"file":"content-api.mjs","sources":["../../../server/src/controllers/content-api.ts"],"sourcesContent":["import _ from 'lodash';\nimport utils, { errors } from '@strapi/utils';\n\nimport type { Context } from 'koa';\nimport type { Core } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { FILE_MODEL_UID } from '../constants';\nimport { validateUploadBody } from './validation/content-api/upload';\nimport { FileInfo } from '../types';\nimport { prepareUploadRequest } from '../utils/mime-validation';\n\nconst { ValidationError } = utils.errors;\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => {\n const sanitizeOutput = async (data: unknown | unknown[], ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth } = ctx.state;\n\n return strapi.contentAPI.sanitize.output(data, schema, { auth });\n };\n\n const validateQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.validate.query(data, schema, { auth, route });\n };\n\n const sanitizeQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.sanitize.query(data, schema, { auth, route });\n };\n\n return {\n async find(ctx: Context) {\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const files = await getService('upload').findMany(sanitizedQuery);\n\n ctx.body = await sanitizeOutput(files, ctx);\n },\n\n async findOne(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const file = await getService('upload').findOne(id, sanitizedQuery.populate!);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n ctx.body = await sanitizeOutput(file, ctx);\n },\n\n async destroy(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n const file = await getService('upload').findOne(id);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n await getService('upload').remove(file);\n\n ctx.body = await sanitizeOutput(file, ctx);\n },\n\n async updateFileInfo(ctx: Context) {\n const {\n query: { id },\n request: { body },\n } = ctx;\n const data = await validateUploadBody(body);\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const result = await getService('upload').updateFileInfo(id, data.fileInfo as any);\n\n ctx.body = await sanitizeOutput(result, ctx);\n },\n\n async replaceFile(ctx: Context) {\n const {\n query: { id },\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n // cannot replace with more than one file\n if (Array.isArray(filesInput)) {\n throw new ValidationError('Cannot replace a file with multiple ones');\n }\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const data = (await validateUploadBody(filteredBody)) as { fileInfo: FileInfo };\n\n const replacedFiles = await getService('upload').replace(id, { data, file: validFiles[0] });\n\n ctx.body = await sanitizeOutput(replacedFiles, ctx);\n },\n\n async uploadFiles(ctx: Context) {\n const {\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const isMultipleFiles = validFiles.length > 1;\n const data: any = await validateUploadBody(filteredBody, isMultipleFiles);\n\n const apiUploadFolderService = getService('api-upload-folder');\n\n const apiUploadFolder = await apiUploadFolderService.getAPIUploadFolder();\n\n if (isMultipleFiles) {\n data.fileInfo = data.fileInfo || [];\n data.fileInfo = validFiles.map((_f, i) => ({\n ...data.fileInfo[i],\n folder: apiUploadFolder.id,\n }));\n } else {\n data.fileInfo = { ...data.fileInfo, folder: apiUploadFolder.id };\n }\n\n const uploadedFiles = await getService('upload').upload({\n data,\n files: validFiles,\n });\n\n ctx.body = await sanitizeOutput(uploadedFiles as any, ctx);\n ctx.status = 201;\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new ValidationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n };\n};\n"],"names":["ValidationError","utils","errors","strapi","sanitizeOutput","data","ctx","schema","getModel","FILE_MODEL_UID","auth","state","contentAPI","sanitize","output","validateQuery","route","validate","query","sanitizeQuery","find","sanitizedQuery","files","getService","findMany","body","findOne","params","id","file","populate","notFound","destroy","remove","updateFileInfo","request","validateUploadBody","result","fileInfo","replaceFile","filesInput","validFiles","filteredBody","validationErrors","prepareUploadRequest","length","message","Array","isArray","replacedFiles","replace","uploadFiles","isMultipleFiles","apiUploadFolderService","apiUploadFolder","getAPIUploadFolder","map","_f","i","folder","uploadedFiles","upload","status","_","isEmpty","size"],"mappings":";;;;;;;AAYA,MAAM,EAAEA,eAAe,EAAE,GAAGC,MAAMC,MAAM;AAExC,iBAAe,CAAA,CAAC,EAAEC,MAAM,EAA2B,GAAA;IACjD,MAAMC,cAAAA,GAAiB,OAAOC,IAAAA,EAA2BC,GAAAA,GAAAA;QACvD,MAAMC,MAAAA,GAASJ,MAAAA,CAAOK,QAAQ,CAACC,cAAAA,CAAAA;AAC/B,QAAA,MAAM,EAAEC,IAAI,EAAE,GAAGJ,IAAIK,KAAK;QAE1B,OAAOR,MAAAA,CAAOS,UAAU,CAACC,QAAQ,CAACC,MAAM,CAACT,MAAME,MAAAA,EAAQ;AAAEG,YAAAA;AAAK,SAAA,CAAA;AAChE,IAAA,CAAA;IAEA,MAAMK,aAAAA,GAAgB,OAAOV,IAAAA,EAA+BC,GAAAA,GAAAA;QAC1D,MAAMC,MAAAA,GAASJ,MAAAA,CAAOK,QAAQ,CAACC,cAAAA,CAAAA;AAC/B,QAAA,MAAM,EAAEC,IAAI,EAAEM,KAAK,EAAE,GAAGV,IAAIK,KAAK;QAEjC,OAAOR,MAAAA,CAAOS,UAAU,CAACK,QAAQ,CAACC,KAAK,CAACb,MAAME,MAAAA,EAAQ;AAAEG,YAAAA,IAAAA;AAAMM,YAAAA;AAAM,SAAA,CAAA;AACtE,IAAA,CAAA;IAEA,MAAMG,aAAAA,GAAgB,OAAOd,IAAAA,EAA+BC,GAAAA,GAAAA;QAC1D,MAAMC,MAAAA,GAASJ,MAAAA,CAAOK,QAAQ,CAACC,cAAAA,CAAAA;AAC/B,QAAA,MAAM,EAAEC,IAAI,EAAEM,KAAK,EAAE,GAAGV,IAAIK,KAAK;QAEjC,OAAOR,MAAAA,CAAOS,UAAU,CAACC,QAAQ,CAACK,KAAK,CAACb,MAAME,MAAAA,EAAQ;AAAEG,YAAAA,IAAAA;AAAMM,YAAAA;AAAM,SAAA,CAAA;AACtE,IAAA,CAAA;IAEA,OAAO;AACL,QAAA,MAAMI,MAAKd,GAAY,EAAA;YACrB,MAAMS,aAAAA,CAAcT,GAAAA,CAAIY,KAAK,EAAEZ,GAAAA,CAAAA;AAC/B,YAAA,MAAMe,cAAAA,GAAiB,MAAMF,aAAAA,CAAcb,GAAAA,CAAIY,KAAK,EAAEZ,GAAAA,CAAAA;AAEtD,YAAA,MAAMgB,KAAAA,GAAQ,MAAMC,UAAAA,CAAW,QAAA,CAAA,CAAUC,QAAQ,CAACH,cAAAA,CAAAA;AAElDf,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAekB,KAAAA,EAAOhB,GAAAA,CAAAA;AACzC,QAAA,CAAA;AAEA,QAAA,MAAMoB,SAAQpB,GAAY,EAAA;AACxB,YAAA,MAAM,EACJqB,MAAAA,EAAQ,EAAEC,EAAE,EAAE,EACf,GAAGtB,GAAAA;YAEJ,MAAMS,aAAAA,CAAcT,GAAAA,CAAIY,KAAK,EAAEZ,GAAAA,CAAAA;AAC/B,YAAA,MAAMe,cAAAA,GAAiB,MAAMF,aAAAA,CAAcb,GAAAA,CAAIY,KAAK,EAAEZ,GAAAA,CAAAA;YAEtD,MAAMuB,IAAAA,GAAO,MAAMN,UAAAA,CAAW,QAAA,CAAA,CAAUG,OAAO,CAACE,EAAAA,EAAIP,eAAeS,QAAQ,CAAA;AAE3E,YAAA,IAAI,CAACD,IAAAA,EAAM;gBACT,OAAOvB,GAAAA,CAAIyB,QAAQ,CAAC,eAAA,CAAA;AACtB,YAAA;AAEAzB,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAeyB,IAAAA,EAAMvB,GAAAA,CAAAA;AACxC,QAAA,CAAA;AAEA,QAAA,MAAM0B,SAAQ1B,GAAY,EAAA;AACxB,YAAA,MAAM,EACJqB,MAAAA,EAAQ,EAAEC,EAAE,EAAE,EACf,GAAGtB,GAAAA;AAEJ,YAAA,MAAMuB,IAAAA,GAAO,MAAMN,UAAAA,CAAW,QAAA,CAAA,CAAUG,OAAO,CAACE,EAAAA,CAAAA;AAEhD,YAAA,IAAI,CAACC,IAAAA,EAAM;gBACT,OAAOvB,GAAAA,CAAIyB,QAAQ,CAAC,eAAA,CAAA;AACtB,YAAA;YAEA,MAAMR,UAAAA,CAAW,QAAA,CAAA,CAAUU,MAAM,CAACJ,IAAAA,CAAAA;AAElCvB,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAeyB,IAAAA,EAAMvB,GAAAA,CAAAA;AACxC,QAAA,CAAA;AAEA,QAAA,MAAM4B,gBAAe5B,GAAY,EAAA;YAC/B,MAAM,EACJY,KAAAA,EAAO,EAAEU,EAAE,EAAE,EACbO,OAAAA,EAAS,EAAEV,IAAI,EAAE,EAClB,GAAGnB,GAAAA;YACJ,MAAMD,IAAAA,GAAO,MAAM+B,kBAAAA,CAAmBX,IAAAA,CAAAA;AAEtC,YAAA,IAAI,CAACG,EAAAA,IAAO,OAAOA,OAAO,QAAA,IAAY,OAAOA,OAAO,QAAA,EAAW;AAC7D,gBAAA,MAAM,IAAI5B,eAAAA,CAAgB,gDAAA,CAAA;AAC5B,YAAA;YAEA,MAAMqC,MAAAA,GAAS,MAAMd,UAAAA,CAAW,QAAA,CAAA,CAAUW,cAAc,CAACN,EAAAA,EAAIvB,KAAKiC,QAAQ,CAAA;AAE1EhC,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAeiC,MAAAA,EAAQ/B,GAAAA,CAAAA;AAC1C,QAAA,CAAA;AAEA,QAAA,MAAMiC,aAAYjC,GAAY,EAAA;YAC5B,MAAM,EACJY,OAAO,EAAEU,EAAE,EAAE,EACbO,OAAAA,EAAS,EAAEV,IAAI,EAAEH,OAAO,EAAEA,KAAAA,EAAOkB,UAAU,EAAE,GAAG,EAAE,EAAE,EACrD,GAAGlC,GAAAA;AAEJ,YAAA,MAAM,EACJmC,UAAU,EACVC,YAAY,EACZxC,MAAAA,EAAQyC,gBAAgB,EACzB,GAAG,MAAMC,oBAAAA,CAAqBJ,UAAAA,EAAYf,IAAAA,EAAMtB,MAAAA,CAAAA;YACjD,IAAIsC,UAAAA,CAAWI,MAAM,KAAK,CAAA,EAAG;gBAC3B,MAAM,IAAI3C,OAAOF,eAAe,CAAC2C,gBAAgB,CAAC,CAAA,CAAE,CAACG,OAAO,CAAA;AAC9D,YAAA;;YAGA,IAAIC,KAAAA,CAAMC,OAAO,CAACR,UAAAA,CAAAA,EAAa;AAC7B,gBAAA,MAAM,IAAIxC,eAAAA,CAAgB,0CAAA,CAAA;AAC5B,YAAA;AAEA,YAAA,IAAI,CAAC4B,EAAAA,IAAO,OAAOA,OAAO,QAAA,IAAY,OAAOA,OAAO,QAAA,EAAW;AAC7D,gBAAA,MAAM,IAAI5B,eAAAA,CAAgB,gDAAA,CAAA;AAC5B,YAAA;YAEA,MAAMK,IAAAA,GAAQ,MAAM+B,kBAAAA,CAAmBM,YAAAA,CAAAA;AAEvC,YAAA,MAAMO,gBAAgB,MAAM1B,UAAAA,CAAW,QAAA,CAAA,CAAU2B,OAAO,CAACtB,EAAAA,EAAI;AAAEvB,gBAAAA,IAAAA;gBAAMwB,IAAAA,EAAMY,UAAU,CAAC,CAAA;AAAG,aAAA,CAAA;AAEzFnC,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAe6C,aAAAA,EAAe3C,GAAAA,CAAAA;AACjD,QAAA,CAAA;AAEA,QAAA,MAAM6C,aAAY7C,GAAY,EAAA;AAC5B,YAAA,MAAM,EACJ6B,OAAAA,EAAS,EAAEV,IAAI,EAAEH,KAAAA,EAAO,EAAEA,KAAAA,EAAOkB,UAAU,EAAE,GAAG,EAAE,EAAE,EACrD,GAAGlC,GAAAA;AAEJ,YAAA,MAAM,EACJmC,UAAU,EACVC,YAAY,EACZxC,MAAAA,EAAQyC,gBAAgB,EACzB,GAAG,MAAMC,oBAAAA,CAAqBJ,UAAAA,EAAYf,IAAAA,EAAMtB,MAAAA,CAAAA;YACjD,IAAIsC,UAAAA,CAAWI,MAAM,KAAK,CAAA,EAAG;gBAC3B,MAAM,IAAI3C,OAAOF,eAAe,CAAC2C,gBAAgB,CAAC,CAAA,CAAE,CAACG,OAAO,CAAA;AAC9D,YAAA;YAEA,MAAMM,eAAAA,GAAkBX,UAAAA,CAAWI,MAAM,GAAG,CAAA;YAC5C,MAAMxC,IAAAA,GAAY,MAAM+B,kBAAAA,CAAmBM,YAAAA,EAAcU,eAAAA,CAAAA;AAEzD,YAAA,MAAMC,yBAAyB9B,UAAAA,CAAW,mBAAA,CAAA;YAE1C,MAAM+B,eAAAA,GAAkB,MAAMD,sBAAAA,CAAuBE,kBAAkB,EAAA;AAEvE,YAAA,IAAIH,eAAAA,EAAiB;AACnB/C,gBAAAA,IAAAA,CAAKiC,QAAQ,GAAGjC,IAAAA,CAAKiC,QAAQ,IAAI,EAAE;gBACnCjC,IAAAA,CAAKiC,QAAQ,GAAGG,UAAAA,CAAWe,GAAG,CAAC,CAACC,EAAAA,EAAIC,KAAO;wBACzC,GAAGrD,IAAAA,CAAKiC,QAAQ,CAACoB,CAAAA,CAAE;AACnBC,wBAAAA,MAAAA,EAAQL,gBAAgB1B;qBAC1B,CAAA,CAAA;YACF,CAAA,MAAO;AACLvB,gBAAAA,IAAAA,CAAKiC,QAAQ,GAAG;AAAE,oBAAA,GAAGjC,KAAKiC,QAAQ;AAAEqB,oBAAAA,MAAAA,EAAQL,gBAAgB1B;AAAG,iBAAA;AACjE,YAAA;AAEA,YAAA,MAAMgC,aAAAA,GAAgB,MAAMrC,UAAAA,CAAW,QAAA,CAAA,CAAUsC,MAAM,CAAC;AACtDxD,gBAAAA,IAAAA;gBACAiB,KAAAA,EAAOmB;AACT,aAAA,CAAA;AAEAnC,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAewD,aAAAA,EAAsBtD,GAAAA,CAAAA;AACtDA,YAAAA,GAAAA,CAAIwD,MAAM,GAAG,GAAA;AACf,QAAA,CAAA;;AAGA,QAAA,MAAMD,QAAOvD,GAAY,EAAA;AACvB,YAAA,MAAM,EACJY,KAAAA,EAAO,EAAEU,EAAE,EAAE,EACbO,OAAAA,EAAS,EAAEb,KAAAA,EAAO,EAAEA,KAAK,EAAE,GAAG,EAAE,EAAE,EACnC,GAAGhB,GAAAA;AAEJ,YAAA,IAAIyD,CAAAA,CAAEC,OAAO,CAAC1C,KAAAA,CAAAA,IAAW,CAACyB,KAAAA,CAAMC,OAAO,CAAC1B,KAAAA,CAAAA,IAAUA,KAAAA,CAAM2C,IAAI,KAAK,CAAA,EAAI;AACnE,gBAAA,IAAIrC,EAAAA,EAAI;oBACN,OAAO,IAAI,CAACM,cAAc,CAAC5B,GAAAA,CAAAA;AAC7B,gBAAA;AAEA,gBAAA,MAAM,IAAIN,eAAAA,CAAgB,iBAAA,CAAA;AAC5B,YAAA;YAEA,MAAO4B,CAAAA,EAAAA,GAAK,IAAI,CAACW,WAAW,GAAG,IAAI,CAACY,WAAU,EAAG7C,GAAAA,CAAAA;AACnD,QAAA;AACF,KAAA;AACF,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../server/src/controllers/index.ts"],"sourcesContent":["import adminFile from './admin-file';\nimport adminFolder from './admin-folder';\nimport adminFolderFile from './admin-folder-file';\nimport adminSettings from './admin-settings';\nimport adminUpload from './admin-upload';\nimport contentApi from './content-api';\nimport viewConfiguration from './view-configuration';\n\nexport const controllers = {\n 'admin-file': adminFile,\n 'admin-folder': adminFolder,\n 'admin-folder-file': adminFolderFile,\n 'admin-settings': adminSettings,\n 'admin-upload': adminUpload,\n 'content-api': contentApi,\n 'view-configuration': viewConfiguration,\n};\n"],"names":["controllers","adminFile","adminFolder","adminFolderFile","adminSettings","adminUpload","contentApi","viewConfiguration"],"mappings":";;;;;;;;;;MAQaA,WAAc,GAAA;IACzB,YAAcC,EAAAA,SAAAA;IACd,cAAgBC,EAAAA,WAAAA;IAChB,mBAAqBC,EAAAA,eAAAA;IACrB,gBAAkBC,EAAAA,aAAAA;IAClB,cAAgBC,EAAAA,WAAAA;IAChB,aAAeC,EAAAA,UAAAA;IACf,oBAAsBC,EAAAA;AACxB;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../server/src/controllers/index.ts"],"sourcesContent":["import adminFile from './admin-file';\nimport adminFolder from './admin-folder';\nimport adminFolderFile from './admin-folder-file';\nimport adminSettings from './admin-settings';\nimport adminUpload from './admin-upload';\nimport contentApi from './content-api';\nimport viewConfiguration from './view-configuration';\n\nexport const controllers = {\n 'admin-file': adminFile,\n 'admin-folder': adminFolder,\n 'admin-folder-file': adminFolderFile,\n 'admin-settings': adminSettings,\n 'admin-upload': adminUpload,\n 'content-api': contentApi,\n 'view-configuration': viewConfiguration,\n};\n"],"names":["controllers","adminFile","adminFolder","adminFolderFile","adminSettings","adminUpload","contentApi","viewConfiguration"],"mappings":";;;;;;;;;;MAQaA,WAAAA,GAAc;IACzB,YAAA,EAAcC,SAAAA;IACd,cAAA,EAAgBC,WAAAA;IAChB,mBAAA,EAAqBC,eAAAA;IACrB,gBAAA,EAAkBC,aAAAA;IAClB,cAAA,EAAgBC,WAAAA;IAChB,aAAA,EAAeC,UAAAA;IACf,oBAAA,EAAsBC;AACxB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../server/src/controllers/index.ts"],"sourcesContent":["import adminFile from './admin-file';\nimport adminFolder from './admin-folder';\nimport adminFolderFile from './admin-folder-file';\nimport adminSettings from './admin-settings';\nimport adminUpload from './admin-upload';\nimport contentApi from './content-api';\nimport viewConfiguration from './view-configuration';\n\nexport const controllers = {\n 'admin-file': adminFile,\n 'admin-folder': adminFolder,\n 'admin-folder-file': adminFolderFile,\n 'admin-settings': adminSettings,\n 'admin-upload': adminUpload,\n 'content-api': contentApi,\n 'view-configuration': viewConfiguration,\n};\n"],"names":["controllers","adminFile","adminFolder","adminFolderFile","adminSettings","adminUpload","contentApi","viewConfiguration"],"mappings":";;;;;;;;MAQaA,WAAc,GAAA;IACzB,YAAcC,EAAAA,SAAAA;IACd,cAAgBC,EAAAA,WAAAA;IAChB,mBAAqBC,EAAAA,eAAAA;IACrB,gBAAkBC,EAAAA,aAAAA;IAClB,cAAgBC,EAAAA,WAAAA;IAChB,aAAeC,EAAAA,UAAAA;IACf,oBAAsBC,EAAAA;AACxB;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../server/src/controllers/index.ts"],"sourcesContent":["import adminFile from './admin-file';\nimport adminFolder from './admin-folder';\nimport adminFolderFile from './admin-folder-file';\nimport adminSettings from './admin-settings';\nimport adminUpload from './admin-upload';\nimport contentApi from './content-api';\nimport viewConfiguration from './view-configuration';\n\nexport const controllers = {\n 'admin-file': adminFile,\n 'admin-folder': adminFolder,\n 'admin-folder-file': adminFolderFile,\n 'admin-settings': adminSettings,\n 'admin-upload': adminUpload,\n 'content-api': contentApi,\n 'view-configuration': viewConfiguration,\n};\n"],"names":["controllers","adminFile","adminFolder","adminFolderFile","adminSettings","adminUpload","contentApi","viewConfiguration"],"mappings":";;;;;;;;MAQaA,WAAAA,GAAc;IACzB,YAAA,EAAcC,SAAAA;IACd,cAAA,EAAgBC,WAAAA;IAChB,mBAAA,EAAqBC,eAAAA;IACrB,gBAAA,EAAkBC,aAAAA;IAClB,cAAA,EAAgBC,WAAAA;IAChB,aAAA,EAAeC,UAAAA;IACf,oBAAA,EAAsBC;AACxB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"find-entity-and-check-permissions.js","sources":["../../../../server/src/controllers/utils/find-entity-and-check-permissions.ts"],"sourcesContent":["import _ from 'lodash';\nimport { errors, contentTypes as contentTypesUtils } from '@strapi/utils';\nimport { getService } from '../../utils';\n\nconst findEntityAndCheckPermissions = async (\n ability: unknown,\n action: string,\n model: string,\n id: string | number\n) => {\n const file = await getService('upload').findOne(id, [\n contentTypesUtils.constants.CREATED_BY_ATTRIBUTE,\n 'folder',\n ]);\n\n if (_.isNil(file)) {\n throw new errors.NotFoundError();\n }\n\n const pm = strapi\n .service('admin::permission')\n .createPermissionsManager({ ability, action, model });\n\n const creatorId = _.get(file, [contentTypesUtils.constants.CREATED_BY_ATTRIBUTE, 'id']);\n const author = creatorId\n ? await strapi.service('admin::user').findOne(creatorId, ['roles'])\n : null;\n\n const fileWithRoles = _.set(_.cloneDeep(file), 'createdBy', author);\n\n if (pm.ability.cannot(pm.action, pm.toSubject(fileWithRoles))) {\n throw new errors.ForbiddenError();\n }\n\n return { pm, file };\n};\n\nexport { findEntityAndCheckPermissions };\n"],"names":["findEntityAndCheckPermissions","ability","action","model","id","file","getService","findOne","contentTypesUtils","constants","CREATED_BY_ATTRIBUTE","_","isNil","errors","NotFoundError","pm","strapi","service","createPermissionsManager","creatorId","get","author","fileWithRoles","set","cloneDeep","cannot","toSubject","ForbiddenError"],"mappings":";;;;;;AAIA,MAAMA,6BAAgC,GAAA,OACpCC,OACAC,EAAAA,MAAAA,EACAC,KACAC,EAAAA,EAAAA,GAAAA;AAEA,IAAA,MAAMC,OAAO,MAAMC,gBAAAA,CAAW,QAAUC,CAAAA,CAAAA,OAAO,CAACH,EAAI,EAAA;QAClDI,kBAAkBC,CAAAA,SAAS,CAACC,oBAAoB;AAChD,QAAA;AACD,KAAA,CAAA;IAED,IAAIC,CAAAA,CAAEC,KAAK,CAACP,IAAO,CAAA,EAAA;QACjB,MAAM,IAAIQ,aAAOC,aAAa,EAAA;AAChC;AAEA,IAAA,MAAMC,KAAKC,MACRC,CAAAA,OAAO,CAAC,mBAAA,CAAA,CACRC,wBAAwB,CAAC;AAAEjB,QAAAA,OAAAA;AAASC,QAAAA,MAAAA;AAAQC,QAAAA;AAAM,KAAA,CAAA;AAErD,IAAA,MAAMgB,SAAYR,GAAAA,CAAAA,CAAES,GAAG,CAACf,IAAM,EAAA;QAACG,kBAAkBC,CAAAA,SAAS,CAACC,oBAAoB;AAAE,QAAA;AAAK,KAAA,CAAA;IACtF,MAAMW,MAAAA,GAASF,YACX,MAAMH,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeV,OAAO,CAACY,SAAW,EAAA;AAAC,QAAA;KAAQ,CAChE,GAAA,IAAA;IAEJ,MAAMG,aAAAA,GAAgBX,EAAEY,GAAG,CAACZ,EAAEa,SAAS,CAACnB,OAAO,WAAagB,EAAAA,MAAAA,CAAAA;IAE5D,IAAIN,EAAAA,CAAGd,OAAO,CAACwB,MAAM,CAACV,EAAGb,CAAAA,MAAM,EAAEa,EAAAA,CAAGW,SAAS,CAACJ,aAAiB,CAAA,CAAA,EAAA;QAC7D,MAAM,IAAIT,aAAOc,cAAc,EAAA;AACjC;IAEA,OAAO;AAAEZ,QAAAA,EAAAA;AAAIV,QAAAA;AAAK,KAAA;AACpB;;;;"}
1
+ {"version":3,"file":"find-entity-and-check-permissions.js","sources":["../../../../server/src/controllers/utils/find-entity-and-check-permissions.ts"],"sourcesContent":["import _ from 'lodash';\nimport { errors, contentTypes as contentTypesUtils } from '@strapi/utils';\nimport { getService } from '../../utils';\n\nconst findEntityAndCheckPermissions = async (\n ability: unknown,\n action: string,\n model: string,\n id: string | number\n) => {\n const file = await getService('upload').findOne(id, [\n contentTypesUtils.constants.CREATED_BY_ATTRIBUTE,\n 'folder',\n ]);\n\n if (_.isNil(file)) {\n throw new errors.NotFoundError();\n }\n\n const pm = strapi\n .service('admin::permission')\n .createPermissionsManager({ ability, action, model });\n\n const creatorId = _.get(file, [contentTypesUtils.constants.CREATED_BY_ATTRIBUTE, 'id']);\n const author = creatorId\n ? await strapi.service('admin::user').findOne(creatorId, ['roles'])\n : null;\n\n const fileWithRoles = _.set(_.cloneDeep(file), 'createdBy', author);\n\n if (pm.ability.cannot(pm.action, pm.toSubject(fileWithRoles))) {\n throw new errors.ForbiddenError();\n }\n\n return { pm, file };\n};\n\nexport { findEntityAndCheckPermissions };\n"],"names":["findEntityAndCheckPermissions","ability","action","model","id","file","getService","findOne","contentTypesUtils","constants","CREATED_BY_ATTRIBUTE","_","isNil","errors","NotFoundError","pm","strapi","service","createPermissionsManager","creatorId","get","author","fileWithRoles","set","cloneDeep","cannot","toSubject","ForbiddenError"],"mappings":";;;;;;AAIA,MAAMA,6BAAAA,GAAgC,OACpCC,OAAAA,EACAC,MAAAA,EACAC,KAAAA,EACAC,EAAAA,GAAAA;AAEA,IAAA,MAAMC,OAAO,MAAMC,gBAAAA,CAAW,QAAA,CAAA,CAAUC,OAAO,CAACH,EAAAA,EAAI;QAClDI,kBAAAA,CAAkBC,SAAS,CAACC,oBAAoB;AAChD,QAAA;AACD,KAAA,CAAA;IAED,IAAIC,CAAAA,CAAEC,KAAK,CAACP,IAAAA,CAAAA,EAAO;QACjB,MAAM,IAAIQ,aAAOC,aAAa,EAAA;AAChC,IAAA;AAEA,IAAA,MAAMC,KAAKC,MAAAA,CACRC,OAAO,CAAC,mBAAA,CAAA,CACRC,wBAAwB,CAAC;AAAEjB,QAAAA,OAAAA;AAASC,QAAAA,MAAAA;AAAQC,QAAAA;AAAM,KAAA,CAAA;AAErD,IAAA,MAAMgB,SAAAA,GAAYR,CAAAA,CAAES,GAAG,CAACf,IAAAA,EAAM;QAACG,kBAAAA,CAAkBC,SAAS,CAACC,oBAAoB;AAAE,QAAA;AAAK,KAAA,CAAA;IACtF,MAAMW,MAAAA,GAASF,YACX,MAAMH,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeV,OAAO,CAACY,SAAAA,EAAW;AAAC,QAAA;KAAQ,CAAA,GAChE,IAAA;IAEJ,MAAMG,aAAAA,GAAgBX,EAAEY,GAAG,CAACZ,EAAEa,SAAS,CAACnB,OAAO,WAAA,EAAagB,MAAAA,CAAAA;IAE5D,IAAIN,EAAAA,CAAGd,OAAO,CAACwB,MAAM,CAACV,EAAAA,CAAGb,MAAM,EAAEa,EAAAA,CAAGW,SAAS,CAACJ,aAAAA,CAAAA,CAAAA,EAAiB;QAC7D,MAAM,IAAIT,aAAOc,cAAc,EAAA;AACjC,IAAA;IAEA,OAAO;AAAEZ,QAAAA,EAAAA;AAAIV,QAAAA;AAAK,KAAA;AACpB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"find-entity-and-check-permissions.mjs","sources":["../../../../server/src/controllers/utils/find-entity-and-check-permissions.ts"],"sourcesContent":["import _ from 'lodash';\nimport { errors, contentTypes as contentTypesUtils } from '@strapi/utils';\nimport { getService } from '../../utils';\n\nconst findEntityAndCheckPermissions = async (\n ability: unknown,\n action: string,\n model: string,\n id: string | number\n) => {\n const file = await getService('upload').findOne(id, [\n contentTypesUtils.constants.CREATED_BY_ATTRIBUTE,\n 'folder',\n ]);\n\n if (_.isNil(file)) {\n throw new errors.NotFoundError();\n }\n\n const pm = strapi\n .service('admin::permission')\n .createPermissionsManager({ ability, action, model });\n\n const creatorId = _.get(file, [contentTypesUtils.constants.CREATED_BY_ATTRIBUTE, 'id']);\n const author = creatorId\n ? await strapi.service('admin::user').findOne(creatorId, ['roles'])\n : null;\n\n const fileWithRoles = _.set(_.cloneDeep(file), 'createdBy', author);\n\n if (pm.ability.cannot(pm.action, pm.toSubject(fileWithRoles))) {\n throw new errors.ForbiddenError();\n }\n\n return { pm, file };\n};\n\nexport { findEntityAndCheckPermissions };\n"],"names":["findEntityAndCheckPermissions","ability","action","model","id","file","getService","findOne","contentTypesUtils","constants","CREATED_BY_ATTRIBUTE","_","isNil","errors","NotFoundError","pm","strapi","service","createPermissionsManager","creatorId","get","author","fileWithRoles","set","cloneDeep","cannot","toSubject","ForbiddenError"],"mappings":";;;;AAIA,MAAMA,6BAAgC,GAAA,OACpCC,OACAC,EAAAA,MAAAA,EACAC,KACAC,EAAAA,EAAAA,GAAAA;AAEA,IAAA,MAAMC,OAAO,MAAMC,UAAAA,CAAW,QAAUC,CAAAA,CAAAA,OAAO,CAACH,EAAI,EAAA;QAClDI,YAAkBC,CAAAA,SAAS,CAACC,oBAAoB;AAChD,QAAA;AACD,KAAA,CAAA;IAED,IAAIC,CAAAA,CAAEC,KAAK,CAACP,IAAO,CAAA,EAAA;QACjB,MAAM,IAAIQ,OAAOC,aAAa,EAAA;AAChC;AAEA,IAAA,MAAMC,KAAKC,MACRC,CAAAA,OAAO,CAAC,mBAAA,CAAA,CACRC,wBAAwB,CAAC;AAAEjB,QAAAA,OAAAA;AAASC,QAAAA,MAAAA;AAAQC,QAAAA;AAAM,KAAA,CAAA;AAErD,IAAA,MAAMgB,SAAYR,GAAAA,CAAAA,CAAES,GAAG,CAACf,IAAM,EAAA;QAACG,YAAkBC,CAAAA,SAAS,CAACC,oBAAoB;AAAE,QAAA;AAAK,KAAA,CAAA;IACtF,MAAMW,MAAAA,GAASF,YACX,MAAMH,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeV,OAAO,CAACY,SAAW,EAAA;AAAC,QAAA;KAAQ,CAChE,GAAA,IAAA;IAEJ,MAAMG,aAAAA,GAAgBX,EAAEY,GAAG,CAACZ,EAAEa,SAAS,CAACnB,OAAO,WAAagB,EAAAA,MAAAA,CAAAA;IAE5D,IAAIN,EAAAA,CAAGd,OAAO,CAACwB,MAAM,CAACV,EAAGb,CAAAA,MAAM,EAAEa,EAAAA,CAAGW,SAAS,CAACJ,aAAiB,CAAA,CAAA,EAAA;QAC7D,MAAM,IAAIT,OAAOc,cAAc,EAAA;AACjC;IAEA,OAAO;AAAEZ,QAAAA,EAAAA;AAAIV,QAAAA;AAAK,KAAA;AACpB;;;;"}
1
+ {"version":3,"file":"find-entity-and-check-permissions.mjs","sources":["../../../../server/src/controllers/utils/find-entity-and-check-permissions.ts"],"sourcesContent":["import _ from 'lodash';\nimport { errors, contentTypes as contentTypesUtils } from '@strapi/utils';\nimport { getService } from '../../utils';\n\nconst findEntityAndCheckPermissions = async (\n ability: unknown,\n action: string,\n model: string,\n id: string | number\n) => {\n const file = await getService('upload').findOne(id, [\n contentTypesUtils.constants.CREATED_BY_ATTRIBUTE,\n 'folder',\n ]);\n\n if (_.isNil(file)) {\n throw new errors.NotFoundError();\n }\n\n const pm = strapi\n .service('admin::permission')\n .createPermissionsManager({ ability, action, model });\n\n const creatorId = _.get(file, [contentTypesUtils.constants.CREATED_BY_ATTRIBUTE, 'id']);\n const author = creatorId\n ? await strapi.service('admin::user').findOne(creatorId, ['roles'])\n : null;\n\n const fileWithRoles = _.set(_.cloneDeep(file), 'createdBy', author);\n\n if (pm.ability.cannot(pm.action, pm.toSubject(fileWithRoles))) {\n throw new errors.ForbiddenError();\n }\n\n return { pm, file };\n};\n\nexport { findEntityAndCheckPermissions };\n"],"names":["findEntityAndCheckPermissions","ability","action","model","id","file","getService","findOne","contentTypesUtils","constants","CREATED_BY_ATTRIBUTE","_","isNil","errors","NotFoundError","pm","strapi","service","createPermissionsManager","creatorId","get","author","fileWithRoles","set","cloneDeep","cannot","toSubject","ForbiddenError"],"mappings":";;;;AAIA,MAAMA,6BAAAA,GAAgC,OACpCC,OAAAA,EACAC,MAAAA,EACAC,KAAAA,EACAC,EAAAA,GAAAA;AAEA,IAAA,MAAMC,OAAO,MAAMC,UAAAA,CAAW,QAAA,CAAA,CAAUC,OAAO,CAACH,EAAAA,EAAI;QAClDI,YAAAA,CAAkBC,SAAS,CAACC,oBAAoB;AAChD,QAAA;AACD,KAAA,CAAA;IAED,IAAIC,CAAAA,CAAEC,KAAK,CAACP,IAAAA,CAAAA,EAAO;QACjB,MAAM,IAAIQ,OAAOC,aAAa,EAAA;AAChC,IAAA;AAEA,IAAA,MAAMC,KAAKC,MAAAA,CACRC,OAAO,CAAC,mBAAA,CAAA,CACRC,wBAAwB,CAAC;AAAEjB,QAAAA,OAAAA;AAASC,QAAAA,MAAAA;AAAQC,QAAAA;AAAM,KAAA,CAAA;AAErD,IAAA,MAAMgB,SAAAA,GAAYR,CAAAA,CAAES,GAAG,CAACf,IAAAA,EAAM;QAACG,YAAAA,CAAkBC,SAAS,CAACC,oBAAoB;AAAE,QAAA;AAAK,KAAA,CAAA;IACtF,MAAMW,MAAAA,GAASF,YACX,MAAMH,MAAAA,CAAOC,OAAO,CAAC,aAAA,CAAA,CAAeV,OAAO,CAACY,SAAAA,EAAW;AAAC,QAAA;KAAQ,CAAA,GAChE,IAAA;IAEJ,MAAMG,aAAAA,GAAgBX,EAAEY,GAAG,CAACZ,EAAEa,SAAS,CAACnB,OAAO,WAAA,EAAagB,MAAAA,CAAAA;IAE5D,IAAIN,EAAAA,CAAGd,OAAO,CAACwB,MAAM,CAACV,EAAAA,CAAGb,MAAM,EAAEa,EAAAA,CAAGW,SAAS,CAACJ,aAAAA,CAAAA,CAAAA,EAAiB;QAC7D,MAAM,IAAIT,OAAOc,cAAc,EAAA;AACjC,IAAA;IAEA,OAAO;AAAEZ,QAAAA,EAAAA;AAAIV,QAAAA;AAAK,KAAA;AACpB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"folders.js","sources":["../../../../server/src/controllers/utils/folders.ts"],"sourcesContent":["import { Folder } from '../../types';\n\nconst isFolderOrChild = (folderOrChild: Folder, folder: Folder) =>\n folderOrChild.path === folder.path || folderOrChild.path.startsWith(`${folder.path}/`);\n\nexport { isFolderOrChild };\n"],"names":["isFolderOrChild","folderOrChild","folder","path","startsWith"],"mappings":";;AAEMA,MAAAA,eAAAA,GAAkB,CAACC,aAAuBC,EAAAA,MAAAA,GAC9CD,cAAcE,IAAI,KAAKD,OAAOC,IAAI,IAAIF,cAAcE,IAAI,CAACC,UAAU,CAAC,CAAA,EAAGF,OAAOC,IAAI,CAAC,CAAC,CAAC;;;;"}
1
+ {"version":3,"file":"folders.js","sources":["../../../../server/src/controllers/utils/folders.ts"],"sourcesContent":["import { Folder } from '../../types';\n\nconst isFolderOrChild = (folderOrChild: Folder, folder: Folder) =>\n folderOrChild.path === folder.path || folderOrChild.path.startsWith(`${folder.path}/`);\n\nexport { isFolderOrChild };\n"],"names":["isFolderOrChild","folderOrChild","folder","path","startsWith"],"mappings":";;AAEA,MAAMA,eAAAA,GAAkB,CAACC,aAAAA,EAAuBC,MAAAA,GAC9CD,cAAcE,IAAI,KAAKD,OAAOC,IAAI,IAAIF,cAAcE,IAAI,CAACC,UAAU,CAAC,CAAA,EAAGF,OAAOC,IAAI,CAAC,CAAC,CAAC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"folders.mjs","sources":["../../../../server/src/controllers/utils/folders.ts"],"sourcesContent":["import { Folder } from '../../types';\n\nconst isFolderOrChild = (folderOrChild: Folder, folder: Folder) =>\n folderOrChild.path === folder.path || folderOrChild.path.startsWith(`${folder.path}/`);\n\nexport { isFolderOrChild };\n"],"names":["isFolderOrChild","folderOrChild","folder","path","startsWith"],"mappings":"AAEMA,MAAAA,eAAAA,GAAkB,CAACC,aAAuBC,EAAAA,MAAAA,GAC9CD,cAAcE,IAAI,KAAKD,OAAOC,IAAI,IAAIF,cAAcE,IAAI,CAACC,UAAU,CAAC,CAAA,EAAGF,OAAOC,IAAI,CAAC,CAAC,CAAC;;;;"}
1
+ {"version":3,"file":"folders.mjs","sources":["../../../../server/src/controllers/utils/folders.ts"],"sourcesContent":["import { Folder } from '../../types';\n\nconst isFolderOrChild = (folderOrChild: Folder, folder: Folder) =>\n folderOrChild.path === folder.path || folderOrChild.path.startsWith(`${folder.path}/`);\n\nexport { isFolderOrChild };\n"],"names":["isFolderOrChild","folderOrChild","folder","path","startsWith"],"mappings":"AAEA,MAAMA,eAAAA,GAAkB,CAACC,aAAAA,EAAuBC,MAAAA,GAC9CD,cAAcE,IAAI,KAAKD,OAAOC,IAAI,IAAIF,cAAcE,IAAI,CAACC,UAAU,CAAC,CAAA,EAAGF,OAAOC,IAAI,CAAC,CAAC,CAAC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"configureView.js","sources":["../../../../../server/src/controllers/validation/admin/configureView.ts"],"sourcesContent":["import { yup, validateYupSchema } from '@strapi/utils';\nimport { ALLOWED_SORT_STRINGS } from '../../../constants';\n\nconst configSchema = yup.object({\n pageSize: yup.number().required(),\n sort: yup.mixed().oneOf(ALLOWED_SORT_STRINGS),\n});\n\nexport const validateViewConfiguration = validateYupSchema(configSchema);\n\nexport type ViewConfiguration = yup.InferType<typeof configSchema>;\n"],"names":["configSchema","yup","object","pageSize","number","required","sort","mixed","oneOf","ALLOWED_SORT_STRINGS","validateViewConfiguration","validateYupSchema"],"mappings":";;;;;AAGA,MAAMA,YAAAA,GAAeC,SAAIC,CAAAA,MAAM,CAAC;IAC9BC,QAAUF,EAAAA,SAAAA,CAAIG,MAAM,EAAA,CAAGC,QAAQ,EAAA;AAC/BC,IAAAA,IAAAA,EAAML,SAAIM,CAAAA,KAAK,EAAGC,CAAAA,KAAK,CAACC,8BAAAA;AAC1B,CAAA,CAAA;AAEO,MAAMC,yBAA4BC,GAAAA,uBAAAA,CAAkBX,YAAc;;;;"}
1
+ {"version":3,"file":"configureView.js","sources":["../../../../../server/src/controllers/validation/admin/configureView.ts"],"sourcesContent":["import { yup, validateYupSchema } from '@strapi/utils';\nimport { ALLOWED_SORT_STRINGS } from '../../../constants';\n\nconst configSchema = yup.object({\n pageSize: yup.number().required(),\n sort: yup.mixed().oneOf(ALLOWED_SORT_STRINGS),\n});\n\nexport const validateViewConfiguration = validateYupSchema(configSchema);\n\nexport type ViewConfiguration = yup.InferType<typeof configSchema>;\n"],"names":["configSchema","yup","object","pageSize","number","required","sort","mixed","oneOf","ALLOWED_SORT_STRINGS","validateViewConfiguration","validateYupSchema"],"mappings":";;;;;AAGA,MAAMA,YAAAA,GAAeC,SAAAA,CAAIC,MAAM,CAAC;IAC9BC,QAAAA,EAAUF,SAAAA,CAAIG,MAAM,EAAA,CAAGC,QAAQ,EAAA;AAC/BC,IAAAA,IAAAA,EAAML,SAAAA,CAAIM,KAAK,EAAA,CAAGC,KAAK,CAACC,8BAAAA;AAC1B,CAAA,CAAA;AAEO,MAAMC,yBAAAA,GAA4BC,uBAAAA,CAAkBX,YAAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"configureView.mjs","sources":["../../../../../server/src/controllers/validation/admin/configureView.ts"],"sourcesContent":["import { yup, validateYupSchema } from '@strapi/utils';\nimport { ALLOWED_SORT_STRINGS } from '../../../constants';\n\nconst configSchema = yup.object({\n pageSize: yup.number().required(),\n sort: yup.mixed().oneOf(ALLOWED_SORT_STRINGS),\n});\n\nexport const validateViewConfiguration = validateYupSchema(configSchema);\n\nexport type ViewConfiguration = yup.InferType<typeof configSchema>;\n"],"names":["configSchema","yup","object","pageSize","number","required","sort","mixed","oneOf","ALLOWED_SORT_STRINGS","validateViewConfiguration","validateYupSchema"],"mappings":";;;AAGA,MAAMA,YAAAA,GAAeC,GAAIC,CAAAA,MAAM,CAAC;IAC9BC,QAAUF,EAAAA,GAAAA,CAAIG,MAAM,EAAA,CAAGC,QAAQ,EAAA;AAC/BC,IAAAA,IAAAA,EAAML,GAAIM,CAAAA,KAAK,EAAGC,CAAAA,KAAK,CAACC,oBAAAA;AAC1B,CAAA,CAAA;AAEO,MAAMC,yBAA4BC,GAAAA,iBAAAA,CAAkBX,YAAc;;;;"}
1
+ {"version":3,"file":"configureView.mjs","sources":["../../../../../server/src/controllers/validation/admin/configureView.ts"],"sourcesContent":["import { yup, validateYupSchema } from '@strapi/utils';\nimport { ALLOWED_SORT_STRINGS } from '../../../constants';\n\nconst configSchema = yup.object({\n pageSize: yup.number().required(),\n sort: yup.mixed().oneOf(ALLOWED_SORT_STRINGS),\n});\n\nexport const validateViewConfiguration = validateYupSchema(configSchema);\n\nexport type ViewConfiguration = yup.InferType<typeof configSchema>;\n"],"names":["configSchema","yup","object","pageSize","number","required","sort","mixed","oneOf","ALLOWED_SORT_STRINGS","validateViewConfiguration","validateYupSchema"],"mappings":";;;AAGA,MAAMA,YAAAA,GAAeC,GAAAA,CAAIC,MAAM,CAAC;IAC9BC,QAAAA,EAAUF,GAAAA,CAAIG,MAAM,EAAA,CAAGC,QAAQ,EAAA;AAC/BC,IAAAA,IAAAA,EAAML,GAAAA,CAAIM,KAAK,EAAA,CAAGC,KAAK,CAACC,oBAAAA;AAC1B,CAAA,CAAA;AAEO,MAAMC,yBAAAA,GAA4BC,iBAAAA,CAAkBX,YAAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"folder-file.js","sources":["../../../../../server/src/controllers/validation/admin/folder-file.ts"],"sourcesContent":["import { intersection, map, isEmpty } from 'lodash/fp';\nimport { yup, validateYupSchema } from '@strapi/utils';\nimport { FOLDER_MODEL_UID } from '../../../constants';\nimport { folderExists } from './utils';\nimport { isFolderOrChild } from '../../utils/folders';\n\nimport type { Folder } from '../../../types';\n\nconst validateDeleteManyFoldersFilesSchema = yup\n .object()\n .shape({\n fileIds: yup.array().of(yup.strapiID().required()),\n folderIds: yup.array().of(yup.strapiID().required()),\n })\n .noUnknown()\n .required();\n\nconst validateStructureMoveManyFoldersFilesSchema = yup\n .object()\n .shape({\n destinationFolderId: yup\n .strapiID()\n .nullable()\n .defined()\n .test('folder-exists', 'destination folder does not exist', folderExists),\n fileIds: yup.array().of(yup.strapiID().required()),\n folderIds: yup.array().of(yup.strapiID().required()),\n })\n .noUnknown()\n .required();\n\nconst validateDuplicatesMoveManyFoldersFilesSchema = yup\n .object()\n .test('are-folders-unique', 'some folders already exist', async function areFoldersUnique(value) {\n const { folderIds, destinationFolderId } = value;\n if (isEmpty(folderIds)) return true;\n\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n select: ['name'],\n where: { id: { $in: folderIds } },\n });\n\n const existingFolders = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n select: ['name'],\n where: { parent: { id: destinationFolderId } },\n });\n\n const duplicatedNames = intersection(map('name', folders), map('name', existingFolders));\n if (duplicatedNames.length > 0) {\n return this.createError({\n message: `some folders already exists: ${duplicatedNames.join(', ')}`,\n });\n }\n\n return true;\n });\n\nconst validateMoveFoldersNotInsideThemselvesSchema = yup\n .object()\n .test(\n 'dont-move-inside-self',\n 'folders cannot be moved inside themselves or one of its children',\n async function validateMoveFoldersNotInsideThemselves(value) {\n const { folderIds, destinationFolderId } = value;\n if (destinationFolderId === null || isEmpty(folderIds)) return true;\n\n const destinationFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({\n select: ['path'],\n where: { id: destinationFolderId },\n });\n\n const folders: Folder[] = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n select: ['name', 'path'],\n where: { id: { $in: folderIds } },\n });\n\n const unmovableFoldersNames = folders\n .filter((folder) => isFolderOrChild(destinationFolder, folder))\n .map((f) => f.name);\n\n if (unmovableFoldersNames.length > 0) {\n return this.createError({\n message: `folders cannot be moved inside themselves or one of its children: ${unmovableFoldersNames.join(\n ', '\n )}`,\n });\n }\n\n return true;\n }\n );\n\nexport const validateDeleteManyFoldersFiles = validateYupSchema(\n validateDeleteManyFoldersFilesSchema\n);\n\nexport async function validateMoveManyFoldersFiles(body: unknown) {\n await validateYupSchema(validateStructureMoveManyFoldersFilesSchema)(body);\n await validateYupSchema(validateDuplicatesMoveManyFoldersFilesSchema)(body);\n await validateYupSchema(validateMoveFoldersNotInsideThemselvesSchema)(body);\n}\n"],"names":["validateDeleteManyFoldersFilesSchema","yup","object","shape","fileIds","array","of","strapiID","required","folderIds","noUnknown","validateStructureMoveManyFoldersFilesSchema","destinationFolderId","nullable","defined","test","folderExists","validateDuplicatesMoveManyFoldersFilesSchema","areFoldersUnique","value","isEmpty","folders","strapi","db","query","FOLDER_MODEL_UID","findMany","select","where","id","$in","existingFolders","parent","duplicatedNames","intersection","map","length","createError","message","join","validateMoveFoldersNotInsideThemselvesSchema","validateMoveFoldersNotInsideThemselves","destinationFolder","findOne","unmovableFoldersNames","filter","folder","isFolderOrChild","f","name","validateDeleteManyFoldersFiles","validateYupSchema","validateMoveManyFoldersFiles","body"],"mappings":"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"}
1
+ {"version":3,"file":"folder-file.js","sources":["../../../../../server/src/controllers/validation/admin/folder-file.ts"],"sourcesContent":["import { intersection, map, isEmpty } from 'lodash/fp';\nimport { yup, validateYupSchema } from '@strapi/utils';\nimport { FOLDER_MODEL_UID } from '../../../constants';\nimport { folderExists } from './utils';\nimport { isFolderOrChild } from '../../utils/folders';\n\nimport type { Folder } from '../../../types';\n\nconst validateDeleteManyFoldersFilesSchema = yup\n .object()\n .shape({\n fileIds: yup.array().of(yup.strapiID().required()),\n folderIds: yup.array().of(yup.strapiID().required()),\n })\n .noUnknown()\n .required();\n\nconst validateStructureMoveManyFoldersFilesSchema = yup\n .object()\n .shape({\n destinationFolderId: yup\n .strapiID()\n .nullable()\n .defined()\n .test('folder-exists', 'destination folder does not exist', folderExists),\n fileIds: yup.array().of(yup.strapiID().required()),\n folderIds: yup.array().of(yup.strapiID().required()),\n })\n .noUnknown()\n .required();\n\nconst validateDuplicatesMoveManyFoldersFilesSchema = yup\n .object()\n .test('are-folders-unique', 'some folders already exist', async function areFoldersUnique(value) {\n const { folderIds, destinationFolderId } = value;\n if (isEmpty(folderIds)) return true;\n\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n select: ['name'],\n where: { id: { $in: folderIds } },\n });\n\n const existingFolders = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n select: ['name'],\n where: { parent: { id: destinationFolderId } },\n });\n\n const duplicatedNames = intersection(map('name', folders), map('name', existingFolders));\n if (duplicatedNames.length > 0) {\n return this.createError({\n message: `some folders already exists: ${duplicatedNames.join(', ')}`,\n });\n }\n\n return true;\n });\n\nconst validateMoveFoldersNotInsideThemselvesSchema = yup\n .object()\n .test(\n 'dont-move-inside-self',\n 'folders cannot be moved inside themselves or one of its children',\n async function validateMoveFoldersNotInsideThemselves(value) {\n const { folderIds, destinationFolderId } = value;\n if (destinationFolderId === null || isEmpty(folderIds)) return true;\n\n const destinationFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({\n select: ['path'],\n where: { id: destinationFolderId },\n });\n\n const folders: Folder[] = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n select: ['name', 'path'],\n where: { id: { $in: folderIds } },\n });\n\n const unmovableFoldersNames = folders\n .filter((folder) => isFolderOrChild(destinationFolder, folder))\n .map((f) => f.name);\n\n if (unmovableFoldersNames.length > 0) {\n return this.createError({\n message: `folders cannot be moved inside themselves or one of its children: ${unmovableFoldersNames.join(\n ', '\n )}`,\n });\n }\n\n return true;\n }\n );\n\nexport const validateDeleteManyFoldersFiles = validateYupSchema(\n validateDeleteManyFoldersFilesSchema\n);\n\nexport async function validateMoveManyFoldersFiles(body: unknown) {\n await validateYupSchema(validateStructureMoveManyFoldersFilesSchema)(body);\n await validateYupSchema(validateDuplicatesMoveManyFoldersFilesSchema)(body);\n await validateYupSchema(validateMoveFoldersNotInsideThemselvesSchema)(body);\n}\n"],"names":["validateDeleteManyFoldersFilesSchema","yup","object","shape","fileIds","array","of","strapiID","required","folderIds","noUnknown","validateStructureMoveManyFoldersFilesSchema","destinationFolderId","nullable","defined","test","folderExists","validateDuplicatesMoveManyFoldersFilesSchema","areFoldersUnique","value","isEmpty","folders","strapi","db","query","FOLDER_MODEL_UID","findMany","select","where","id","$in","existingFolders","parent","duplicatedNames","intersection","map","length","createError","message","join","validateMoveFoldersNotInsideThemselvesSchema","validateMoveFoldersNotInsideThemselves","destinationFolder","findOne","unmovableFoldersNames","filter","folder","isFolderOrChild","f","name","validateDeleteManyFoldersFiles","validateYupSchema","validateMoveManyFoldersFiles","body"],"mappings":";;;;;;;;AAQA,MAAMA,oCAAAA,GAAuCC,SAAAA,CAC1CC,MAAM,EAAA,CACNC,KAAK,CAAC;IACLC,OAAAA,EAASH,SAAAA,CAAII,KAAK,EAAA,CAAGC,EAAE,CAACL,SAAAA,CAAIM,QAAQ,GAAGC,QAAQ,EAAA,CAAA;IAC/CC,SAAAA,EAAWR,SAAAA,CAAII,KAAK,EAAA,CAAGC,EAAE,CAACL,SAAAA,CAAIM,QAAQ,GAAGC,QAAQ,EAAA;AACnD,CAAA,CAAA,CACCE,SAAS,GACTF,QAAQ,EAAA;AAEX,MAAMG,2CAAAA,GAA8CV,SAAAA,CACjDC,MAAM,EAAA,CACNC,KAAK,CAAC;IACLS,mBAAAA,EAAqBX,SAAAA,CAClBM,QAAQ,EAAA,CACRM,QAAQ,EAAA,CACRC,OAAO,EAAA,CACPC,IAAI,CAAC,eAAA,EAAiB,mCAAA,EAAqCC,oBAAAA,CAAAA;IAC9DZ,OAAAA,EAASH,SAAAA,CAAII,KAAK,EAAA,CAAGC,EAAE,CAACL,SAAAA,CAAIM,QAAQ,GAAGC,QAAQ,EAAA,CAAA;IAC/CC,SAAAA,EAAWR,SAAAA,CAAII,KAAK,EAAA,CAAGC,EAAE,CAACL,SAAAA,CAAIM,QAAQ,GAAGC,QAAQ,EAAA;AACnD,CAAA,CAAA,CACCE,SAAS,GACTF,QAAQ,EAAA;AAEX,MAAMS,4CAAAA,GAA+ChB,SAAAA,CAClDC,MAAM,EAAA,CACNa,IAAI,CAAC,oBAAA,EAAsB,4BAAA,EAA8B,eAAeG,gBAAAA,CAAiBC,KAAK,EAAA;AAC7F,IAAA,MAAM,EAAEV,SAAS,EAAEG,mBAAmB,EAAE,GAAGO,KAAAA;IAC3C,IAAIC,UAAAA,CAAQX,YAAY,OAAO,IAAA;IAE/B,MAAMY,OAAAA,GAAU,MAAMC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAACC,0BAAAA,CAAAA,CAAkBC,QAAQ,CAAC;QAC/DC,MAAAA,EAAQ;AAAC,YAAA;AAAO,SAAA;QAChBC,KAAAA,EAAO;YAAEC,EAAAA,EAAI;gBAAEC,GAAAA,EAAKrB;AAAU;AAAE;AAClC,KAAA,CAAA;IAEA,MAAMsB,eAAAA,GAAkB,MAAMT,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAACC,0BAAAA,CAAAA,CAAkBC,QAAQ,CAAC;QACvEC,MAAAA,EAAQ;AAAC,YAAA;AAAO,SAAA;QAChBC,KAAAA,EAAO;YAAEI,MAAAA,EAAQ;gBAAEH,EAAAA,EAAIjB;AAAoB;AAAE;AAC/C,KAAA,CAAA;AAEA,IAAA,MAAMqB,kBAAkBC,eAAAA,CAAaC,MAAAA,CAAI,MAAA,EAAQd,OAAAA,CAAAA,EAAUc,OAAI,MAAA,EAAQJ,eAAAA,CAAAA,CAAAA;IACvE,IAAIE,eAAAA,CAAgBG,MAAM,GAAG,CAAA,EAAG;QAC9B,OAAO,IAAI,CAACC,WAAW,CAAC;AACtBC,YAAAA,OAAAA,EAAS,CAAC,6BAA6B,EAAEL,eAAAA,CAAgBM,IAAI,CAAC,IAAA,CAAA,CAAA;AAChE,SAAA,CAAA;AACF,IAAA;IAEA,OAAO,IAAA;AACT,CAAA,CAAA;AAEF,MAAMC,4CAAAA,GAA+CvC,SAAAA,CAClDC,MAAM,EAAA,CACNa,IAAI,CACH,uBAAA,EACA,kEAAA,EACA,eAAe0B,sCAAAA,CAAuCtB,KAAK,EAAA;AACzD,IAAA,MAAM,EAAEV,SAAS,EAAEG,mBAAmB,EAAE,GAAGO,KAAAA;AAC3C,IAAA,IAAIP,mBAAAA,KAAwB,IAAA,IAAQQ,UAAAA,CAAQX,SAAAA,CAAAA,EAAY,OAAO,IAAA;IAE/D,MAAMiC,iBAAAA,GAAoB,MAAMpB,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAACC,0BAAAA,CAAAA,CAAkBkB,OAAO,CAAC;QACxEhB,MAAAA,EAAQ;AAAC,YAAA;AAAO,SAAA;QAChBC,KAAAA,EAAO;YAAEC,EAAAA,EAAIjB;AAAoB;AACnC,KAAA,CAAA;IAEA,MAAMS,SAAAA,GAAoB,MAAMC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAACC,0BAAAA,CAAAA,CAAkBC,QAAQ,CAAC;QACzEC,MAAAA,EAAQ;AAAC,YAAA,MAAA;AAAQ,YAAA;AAAO,SAAA;QACxBC,KAAAA,EAAO;YAAEC,EAAAA,EAAI;gBAAEC,GAAAA,EAAKrB;AAAU;AAAE;AAClC,KAAA,CAAA;AAEA,IAAA,MAAMmC,qBAAAA,GAAwBvB,SAAAA,CAC3BwB,MAAM,CAAC,CAACC,MAAAA,GAAWC,uBAAAA,CAAgBL,iBAAAA,EAAmBI,MAAAA,CAAAA,CAAAA,CACtDX,GAAG,CAAC,CAACa,CAAAA,GAAMA,EAAEC,IAAI,CAAA;IAEpB,IAAIL,qBAAAA,CAAsBR,MAAM,GAAG,CAAA,EAAG;QACpC,OAAO,IAAI,CAACC,WAAW,CAAC;AACtBC,YAAAA,OAAAA,EAAS,CAAC,kEAAkE,EAAEM,qBAAAA,CAAsBL,IAAI,CACtG,IAAA,CAAA,CAAA;AAEJ,SAAA,CAAA;AACF,IAAA;IAEA,OAAO,IAAA;AACT,CAAA,CAAA;AAGG,MAAMW,8BAAAA,GAAiCC,uBAAAA,CAC5CnD,oCAAAA;AAGK,eAAeoD,6BAA6BC,IAAa,EAAA;AAC9D,IAAA,MAAMF,wBAAkBxC,2CAAAA,CAAAA,CAA6C0C,IAAAA,CAAAA;AACrE,IAAA,MAAMF,wBAAkBlC,4CAAAA,CAAAA,CAA8CoC,IAAAA,CAAAA;AACtE,IAAA,MAAMF,wBAAkBX,4CAAAA,CAAAA,CAA8Ca,IAAAA,CAAAA;AACxE;;;;;"}