@strapi/upload 5.59.0 → 5.61.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 (295) hide show
  1. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.js +434 -0
  2. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.js.map +1 -0
  3. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.mjs +432 -0
  4. package/dist/admin/components/AssetPickerDialog/AssetPickerDialog.mjs.map +1 -0
  5. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.js +91 -0
  6. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.js.map +1 -0
  7. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.mjs +89 -0
  8. package/dist/admin/components/AssetPickerDialog/FolderBreadcrumbs.mjs.map +1 -0
  9. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js +29 -0
  10. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js.map +1 -0
  11. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs +27 -0
  12. package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs.map +1 -0
  13. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.js +178 -0
  14. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.js.map +1 -0
  15. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs +175 -0
  16. package/dist/admin/components/AssetPickerDialog/PickerSelectionProvider.mjs.map +1 -0
  17. package/dist/admin/components/AssetPickerDialog/SortableSelection.js +143 -0
  18. package/dist/admin/components/AssetPickerDialog/SortableSelection.js.map +1 -0
  19. package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs +141 -0
  20. package/dist/admin/components/AssetPickerDialog/SortableSelection.mjs.map +1 -0
  21. package/dist/admin/components/AssetPickerDialog/pickerSelection.js +49 -0
  22. package/dist/admin/components/AssetPickerDialog/pickerSelection.js.map +1 -0
  23. package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs +41 -0
  24. package/dist/admin/components/AssetPickerDialog/pickerSelection.mjs.map +1 -0
  25. package/dist/admin/components/Drawer.js +12 -7
  26. package/dist/admin/components/Drawer.js.map +1 -1
  27. package/dist/admin/components/Drawer.mjs +12 -7
  28. package/dist/admin/components/Drawer.mjs.map +1 -1
  29. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js +188 -0
  30. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js.map +1 -0
  31. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs +186 -0
  32. package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs.map +1 -0
  33. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js +9 -4
  34. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js.map +1 -1
  35. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs +9 -4
  36. package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs.map +1 -1
  37. package/dist/admin/components/MediaLibraryInput/AssetCard.js +240 -0
  38. package/dist/admin/components/MediaLibraryInput/AssetCard.js.map +1 -0
  39. package/dist/admin/components/MediaLibraryInput/AssetCard.mjs +237 -0
  40. package/dist/admin/components/MediaLibraryInput/AssetCard.mjs.map +1 -0
  41. package/dist/admin/components/MediaLibraryInput/AssetCarousel.js +161 -0
  42. package/dist/admin/components/MediaLibraryInput/AssetCarousel.js.map +1 -0
  43. package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs +159 -0
  44. package/dist/admin/components/MediaLibraryInput/AssetCarousel.mjs.map +1 -0
  45. package/dist/admin/components/MediaLibraryInput/AssetDropZone.js +76 -49
  46. package/dist/admin/components/MediaLibraryInput/AssetDropZone.js.map +1 -1
  47. package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs +77 -50
  48. package/dist/admin/components/MediaLibraryInput/AssetDropZone.mjs.map +1 -1
  49. package/dist/admin/components/MediaLibraryInput/AssetPreview.js +109 -0
  50. package/dist/admin/components/MediaLibraryInput/AssetPreview.js.map +1 -0
  51. package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs +106 -0
  52. package/dist/admin/components/MediaLibraryInput/AssetPreview.mjs.map +1 -0
  53. package/dist/admin/components/MediaLibraryInput/AssetRow.js +146 -79
  54. package/dist/admin/components/MediaLibraryInput/AssetRow.js.map +1 -1
  55. package/dist/admin/components/MediaLibraryInput/AssetRow.mjs +148 -82
  56. package/dist/admin/components/MediaLibraryInput/AssetRow.mjs.map +1 -1
  57. package/dist/admin/components/MediaLibraryInput/FieldControls.js +32 -0
  58. package/dist/admin/components/MediaLibraryInput/FieldControls.js.map +1 -0
  59. package/dist/admin/components/MediaLibraryInput/FieldControls.mjs +29 -0
  60. package/dist/admin/components/MediaLibraryInput/FieldControls.mjs.map +1 -0
  61. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +163 -111
  62. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
  63. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +162 -114
  64. package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
  65. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js +42 -0
  66. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.js.map +1 -0
  67. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs +40 -0
  68. package/dist/admin/components/MediaLibraryInput/UploadProgressBar.mjs.map +1 -0
  69. package/dist/admin/components/MediaLibraryInput/openAssetDetails.js +46 -0
  70. package/dist/admin/components/MediaLibraryInput/openAssetDetails.js.map +1 -0
  71. package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs +43 -0
  72. package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs.map +1 -0
  73. package/dist/admin/components/MediaLibraryInput/useFieldUploads.js +122 -0
  74. package/dist/admin/components/MediaLibraryInput/useFieldUploads.js.map +1 -0
  75. package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs +120 -0
  76. package/dist/admin/components/MediaLibraryInput/useFieldUploads.mjs.map +1 -0
  77. package/dist/admin/components/UploadProgressDialog.js +2 -1
  78. package/dist/admin/components/UploadProgressDialog.js.map +1 -1
  79. package/dist/admin/components/UploadProgressDialog.mjs +2 -1
  80. package/dist/admin/components/UploadProgressDialog.mjs.map +1 -1
  81. package/dist/admin/hooks/useMediaLibraryPermissions.js +12 -2
  82. package/dist/admin/hooks/useMediaLibraryPermissions.js.map +1 -1
  83. package/dist/admin/hooks/useMediaLibraryPermissions.mjs +12 -2
  84. package/dist/admin/hooks/useMediaLibraryPermissions.mjs.map +1 -1
  85. package/dist/admin/index.js +10 -1
  86. package/dist/admin/index.js.map +1 -1
  87. package/dist/admin/index.mjs +10 -1
  88. package/dist/admin/index.mjs.map +1 -1
  89. package/dist/admin/pages/Assets/AssetsPage.js +14 -303
  90. package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
  91. package/dist/admin/pages/Assets/AssetsPage.mjs +13 -282
  92. package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
  93. package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +2 -2
  94. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +181 -65
  95. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  96. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +184 -69
  97. package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  98. package/dist/admin/pages/Assets/components/AssetDetails/AssetPreview.mjs +1 -1
  99. package/dist/admin/pages/Assets/components/AssetsGrid.js +142 -31
  100. package/dist/admin/pages/Assets/components/AssetsGrid.js.map +1 -1
  101. package/dist/admin/pages/Assets/components/AssetsGrid.mjs +145 -34
  102. package/dist/admin/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  103. package/dist/admin/pages/Assets/components/AssetsSearchInput.js +43 -2
  104. package/dist/admin/pages/Assets/components/AssetsSearchInput.js.map +1 -1
  105. package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs +45 -4
  106. package/dist/admin/pages/Assets/components/AssetsSearchInput.mjs.map +1 -1
  107. package/dist/admin/pages/Assets/components/AssetsTable.js +58 -34
  108. package/dist/admin/pages/Assets/components/AssetsTable.js.map +1 -1
  109. package/dist/admin/pages/Assets/components/AssetsTable.mjs +60 -36
  110. package/dist/admin/pages/Assets/components/AssetsTable.mjs.map +1 -1
  111. package/dist/admin/pages/Assets/components/AssetsView.js +145 -0
  112. package/dist/admin/pages/Assets/components/AssetsView.js.map +1 -0
  113. package/dist/admin/pages/Assets/components/AssetsView.mjs +143 -0
  114. package/dist/admin/pages/Assets/components/AssetsView.mjs.map +1 -0
  115. package/dist/admin/pages/Assets/components/BulkActionsBar.mjs +1 -1
  116. package/dist/admin/pages/Assets/components/BusyOverlay.mjs +1 -1
  117. package/dist/admin/pages/Assets/components/Dnd/DragOverlayChip.mjs +1 -1
  118. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js +40 -0
  119. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.js.map +1 -0
  120. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs +38 -0
  121. package/dist/admin/pages/Assets/components/Dnd/ReorderHandle.mjs.map +1 -0
  122. package/dist/admin/pages/Assets/components/Dnd/assetSortable.js +29 -0
  123. package/dist/admin/pages/Assets/components/Dnd/assetSortable.js.map +1 -0
  124. package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs +24 -0
  125. package/dist/admin/pages/Assets/components/Dnd/assetSortable.mjs.map +1 -0
  126. package/dist/admin/pages/Assets/components/Dnd/dndIds.js +5 -0
  127. package/dist/admin/pages/Assets/components/Dnd/dndIds.js.map +1 -1
  128. package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs +5 -1
  129. package/dist/admin/pages/Assets/components/Dnd/dndIds.mjs.map +1 -1
  130. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js +41 -13
  131. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
  132. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs +41 -13
  133. package/dist/admin/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
  134. package/dist/admin/pages/Assets/components/FilterBadges.mjs +2 -2
  135. package/dist/admin/pages/Assets/components/FilterMenu.mjs +2 -2
  136. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js +274 -55
  137. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  138. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs +277 -59
  139. package/dist/admin/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  140. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js +32 -0
  141. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.js.map +1 -0
  142. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs +29 -0
  143. package/dist/admin/pages/Assets/components/FolderTree/collapsedBranch.mjs.map +1 -0
  144. package/dist/admin/pages/Assets/components/ViewToggle.js +126 -0
  145. package/dist/admin/pages/Assets/components/ViewToggle.js.map +1 -0
  146. package/dist/admin/pages/Assets/components/ViewToggle.mjs +104 -0
  147. package/dist/admin/pages/Assets/components/ViewToggle.mjs.map +1 -0
  148. package/dist/admin/pages/Assets/hooks/useAssetSearch.js +2 -2
  149. package/dist/admin/pages/Assets/hooks/useAssetSearch.js.map +1 -1
  150. package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs +2 -2
  151. package/dist/admin/pages/Assets/hooks/useAssetSearch.mjs.map +1 -1
  152. package/dist/admin/pages/Assets/hooks/useAssetSelection.js +19 -1
  153. package/dist/admin/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  154. package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs +20 -3
  155. package/dist/admin/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  156. package/dist/admin/pages/Assets/hooks/useAssetsList.js +87 -0
  157. package/dist/admin/pages/Assets/hooks/useAssetsList.js.map +1 -0
  158. package/dist/admin/pages/Assets/hooks/useAssetsList.mjs +85 -0
  159. package/dist/admin/pages/Assets/hooks/useAssetsList.mjs.map +1 -0
  160. package/dist/admin/pages/Assets/hooks/useBusyAssets.mjs +1 -1
  161. package/dist/admin/pages/Assets/hooks/useFolderNavigation.js +2 -1
  162. package/dist/admin/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  163. package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs +3 -2
  164. package/dist/admin/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  165. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js +2 -6
  166. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js.map +1 -1
  167. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs +2 -6
  168. package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs.map +1 -1
  169. package/dist/admin/pages/Assets/hooks/useListFilters.js +2 -1
  170. package/dist/admin/pages/Assets/hooks/useListFilters.js.map +1 -1
  171. package/dist/admin/pages/Assets/hooks/useListFilters.mjs +3 -2
  172. package/dist/admin/pages/Assets/hooks/useListFilters.mjs.map +1 -1
  173. package/dist/admin/pages/Assets/hooks/useListQueryParams.js +80 -0
  174. package/dist/admin/pages/Assets/hooks/useListQueryParams.js.map +1 -0
  175. package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs +77 -0
  176. package/dist/admin/pages/Assets/hooks/useListQueryParams.mjs.map +1 -0
  177. package/dist/admin/pages/Assets/hooks/useListSettings.js +32 -0
  178. package/dist/admin/pages/Assets/hooks/useListSettings.js.map +1 -0
  179. package/dist/admin/pages/Assets/hooks/useListSettings.mjs +29 -0
  180. package/dist/admin/pages/Assets/hooks/useListSettings.mjs.map +1 -0
  181. package/dist/admin/pages/Assets/hooks/useListSort.js +2 -1
  182. package/dist/admin/pages/Assets/hooks/useListSort.js.map +1 -1
  183. package/dist/admin/pages/Assets/hooks/useListSort.mjs +3 -2
  184. package/dist/admin/pages/Assets/hooks/useListSort.mjs.map +1 -1
  185. package/dist/admin/services/api.js +92 -7
  186. package/dist/admin/services/api.js.map +1 -1
  187. package/dist/admin/services/api.mjs +91 -9
  188. package/dist/admin/services/api.mjs.map +1 -1
  189. package/dist/admin/src/components/AssetPickerDialog/AssetPickerDialog.d.ts +19 -0
  190. package/dist/admin/src/components/AssetPickerDialog/FolderBreadcrumbs.d.ts +10 -0
  191. package/dist/admin/src/components/AssetPickerDialog/MediaLibraryPickerDialog.d.ts +19 -0
  192. package/dist/admin/src/components/AssetPickerDialog/PickerSelectionProvider.d.ts +28 -0
  193. package/dist/admin/src/components/AssetPickerDialog/SortableSelection.d.ts +12 -0
  194. package/dist/admin/src/components/AssetPickerDialog/pickerSelection.d.ts +26 -0
  195. package/dist/admin/src/components/Drawer.d.ts +8 -0
  196. package/dist/admin/src/components/EditorFileDropZone/EditorFileDropZone.d.ts +21 -0
  197. package/dist/admin/src/components/MediaLibraryInput/AddAssetMenu.d.ts +7 -1
  198. package/dist/admin/src/components/MediaLibraryInput/AssetCard.d.ts +25 -0
  199. package/dist/admin/src/components/MediaLibraryInput/AssetCarousel.d.ts +16 -0
  200. package/dist/admin/src/components/MediaLibraryInput/AssetDropZone.d.ts +11 -3
  201. package/dist/admin/src/components/MediaLibraryInput/AssetPreview.d.ts +17 -0
  202. package/dist/admin/src/components/MediaLibraryInput/AssetRow.d.ts +13 -3
  203. package/dist/admin/src/components/MediaLibraryInput/FieldControls.d.ts +19 -0
  204. package/dist/admin/src/components/MediaLibraryInput/MediaLibraryInput.d.ts +3 -1
  205. package/dist/admin/src/components/MediaLibraryInput/UploadProgressBar.d.ts +7 -0
  206. package/dist/admin/src/components/MediaLibraryInput/openAssetDetails.d.ts +10 -0
  207. package/dist/admin/src/components/MediaLibraryInput/useFieldUploads.d.ts +31 -0
  208. package/dist/admin/src/hooks/useMediaLibraryPermissions.d.ts +2 -0
  209. package/dist/admin/src/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +41 -5
  210. package/dist/admin/src/pages/Assets/components/AssetsGrid.d.ts +3 -1
  211. package/dist/admin/src/pages/Assets/components/AssetsSearchInput.d.ts +11 -1
  212. package/dist/admin/src/pages/Assets/components/AssetsView.d.ts +29 -0
  213. package/dist/admin/src/pages/Assets/components/Dnd/ReorderHandle.d.ts +12 -0
  214. package/dist/admin/src/pages/Assets/components/Dnd/assetSortable.d.ts +37 -0
  215. package/dist/admin/src/pages/Assets/components/Dnd/dndIds.d.ts +5 -0
  216. package/dist/admin/src/pages/Assets/components/Dnd/useAssetDnd.d.ts +23 -2
  217. package/dist/admin/src/pages/Assets/components/FolderTree/FolderTree.d.ts +1 -0
  218. package/dist/admin/src/pages/Assets/components/FolderTree/collapsedBranch.d.ts +21 -0
  219. package/dist/admin/src/pages/Assets/components/ViewToggle.d.ts +8 -0
  220. package/dist/admin/src/pages/Assets/hooks/useAssetSelection.d.ts +26 -0
  221. package/dist/admin/src/pages/Assets/hooks/useAssetsList.d.ts +30 -0
  222. package/dist/admin/src/pages/Assets/hooks/useIsAssetDetailsOpen.d.ts +2 -6
  223. package/dist/admin/src/pages/Assets/hooks/useListQueryParams.d.ts +27 -0
  224. package/dist/admin/src/pages/Assets/hooks/useListSettings.d.ts +29 -0
  225. package/dist/admin/src/services/api.d.ts +24 -1
  226. package/dist/admin/src/store/uploadProgress.d.ts +14 -1
  227. package/dist/admin/src/utils/findFolderPath.d.ts +6 -0
  228. package/dist/admin/src/utils/isAllowedAssetType.d.ts +14 -0
  229. package/dist/admin/store/uploadProgress.js +30 -3
  230. package/dist/admin/store/uploadProgress.js.map +1 -1
  231. package/dist/admin/store/uploadProgress.mjs +29 -4
  232. package/dist/admin/store/uploadProgress.mjs.map +1 -1
  233. package/dist/admin/translations/en.json.js +24 -0
  234. package/dist/admin/translations/en.json.js.map +1 -1
  235. package/dist/admin/translations/en.json.mjs +24 -0
  236. package/dist/admin/translations/en.json.mjs.map +1 -1
  237. package/dist/admin/utils/findFolderPath.js +26 -0
  238. package/dist/admin/utils/findFolderPath.js.map +1 -0
  239. package/dist/admin/utils/findFolderPath.mjs +24 -0
  240. package/dist/admin/utils/findFolderPath.mjs.map +1 -0
  241. package/dist/admin/utils/isAllowedAssetType.js +33 -0
  242. package/dist/admin/utils/isAllowedAssetType.js.map +1 -0
  243. package/dist/admin/utils/isAllowedAssetType.mjs +31 -0
  244. package/dist/admin/utils/isAllowedAssetType.mjs.map +1 -0
  245. package/dist/server/audit-logs.js +264 -0
  246. package/dist/server/audit-logs.js.map +1 -0
  247. package/dist/server/audit-logs.mjs +255 -0
  248. package/dist/server/audit-logs.mjs.map +1 -0
  249. package/dist/server/bootstrap.js +4 -0
  250. package/dist/server/bootstrap.js.map +1 -1
  251. package/dist/server/bootstrap.mjs +4 -0
  252. package/dist/server/bootstrap.mjs.map +1 -1
  253. package/dist/server/controllers/admin-folder-file.js +23 -1
  254. package/dist/server/controllers/admin-folder-file.js.map +1 -1
  255. package/dist/server/controllers/admin-folder-file.mjs +23 -1
  256. package/dist/server/controllers/admin-folder-file.mjs.map +1 -1
  257. package/dist/server/controllers/admin-settings.js +5 -1
  258. package/dist/server/controllers/admin-settings.js.map +1 -1
  259. package/dist/server/controllers/admin-settings.mjs +5 -1
  260. package/dist/server/controllers/admin-settings.mjs.map +1 -1
  261. package/dist/server/services/folder.js +48 -1
  262. package/dist/server/services/folder.js.map +1 -1
  263. package/dist/server/services/folder.mjs +48 -1
  264. package/dist/server/services/folder.mjs.map +1 -1
  265. package/dist/server/services/image-manipulation.js +14 -7
  266. package/dist/server/services/image-manipulation.js.map +1 -1
  267. package/dist/server/services/image-manipulation.mjs +14 -7
  268. package/dist/server/services/image-manipulation.mjs.map +1 -1
  269. package/dist/server/services/upload.js +100 -16
  270. package/dist/server/services/upload.js.map +1 -1
  271. package/dist/server/services/upload.mjs +102 -18
  272. package/dist/server/services/upload.mjs.map +1 -1
  273. package/dist/server/src/audit-logs.d.ts +142 -0
  274. package/dist/server/src/audit-logs.d.ts.map +1 -0
  275. package/dist/server/src/bootstrap.d.ts.map +1 -1
  276. package/dist/server/src/controllers/admin-folder-file.d.ts.map +1 -1
  277. package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
  278. package/dist/server/src/index.d.ts +4 -4
  279. package/dist/server/src/index.d.ts.map +1 -1
  280. package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -1
  281. package/dist/server/src/services/extensions/utils.d.ts +11 -11
  282. package/dist/server/src/services/folder.d.ts.map +1 -1
  283. package/dist/server/src/services/image-manipulation.d.ts +4 -4
  284. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  285. package/dist/server/src/services/index.d.ts +4 -4
  286. package/dist/server/src/services/index.d.ts.map +1 -1
  287. package/dist/server/src/services/upload.d.ts.map +1 -1
  288. package/dist/server/src/types.d.ts +63 -12
  289. package/dist/server/src/types.d.ts.map +1 -1
  290. package/package.json +11 -16
  291. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js +0 -45
  292. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.js.map +0 -1
  293. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs +0 -43
  294. package/dist/admin/components/MediaLibraryInput/NoLibraryAccessDialog.mjs.map +0 -1
  295. package/dist/admin/src/components/MediaLibraryInput/NoLibraryAccessDialog.d.ts +0 -10
@@ -1,5 +1,5 @@
1
1
  import { adminApi } from '@strapi/admin/strapi-admin';
2
- import { openUploadProgress, setUploadFailed, retryCancelledFiles, isUploadInFlight, appendUploadFiles, setFileError, setFileComplete, setFileUploading, setFileProgress, setFileMetadataGenerating, setFileMetadataResult } from '../store/uploadProgress.mjs';
2
+ import { openUploadProgress, setUploadFailed, retryFile, retryCancelledFiles, isUploadInFlight, appendUploadFiles, setFileError, setFileComplete, setFileUploading, setFileProgress, setFileMetadataGenerating, setFileMetadataResult } from '../store/uploadProgress.mjs';
3
3
  import { createRafBatcher } from '../utils/createRafBatcher.mjs';
4
4
  import { getFilenameFromUrl } from '../utils/files.mjs';
5
5
  import { uploadFileViaXHR, UploadFileError, UploadAbortedError } from './uploadFileViaXHR.mjs';
@@ -41,6 +41,31 @@ const unregisterAbortController = (uploadId)=>{
41
41
  unregisterAbortController(uploadId);
42
42
  }
43
43
  };
44
+ /**
45
+ * One controller per file in flight, keyed by `uploadId:index`, so a single row
46
+ * can be cancelled without stopping the rest of its batch. Files still queued
47
+ * have no request to abort yet; they are remembered in `skippedFiles` instead
48
+ * and dropped when a worker reaches them.
49
+ */ const fileAbortControllers = new Map();
50
+ const skippedFiles = new Set();
51
+ const getFileKey = (uploadId, index)=>`${uploadId}:${index}`;
52
+ /**
53
+ * Aborts one file of a batch. Pair it with `cancelFile` to mark the row, the
54
+ * same way `abortUpload` pairs with `cancelUpload`.
55
+ */ const abortUploadFile = (uploadId, index)=>{
56
+ const key = getFileKey(uploadId, index);
57
+ const controller = fileAbortControllers.get(key);
58
+ if (controller) {
59
+ controller.abort();
60
+ fileAbortControllers.delete(key);
61
+ return;
62
+ }
63
+ skippedFiles.add(key);
64
+ };
65
+ /**
66
+ * The file the user picked for a row, kept so it can be previewed while it
67
+ * uploads and replayed on retry.
68
+ */ const getUploadSourceFile = (uploadId, index)=>getUploadEntries(uploadId)?.entries[index]?.file;
44
69
  /**
45
70
  * Runs are chained per batch rather than started in parallel: a second pool
46
71
  * alongside the first would double the files in flight and make `concurrency`
@@ -136,6 +161,10 @@ const trackPoolRun = (uploadId, run)=>{
136
161
  if (!entry) {
137
162
  return;
138
163
  }
164
+ const fileKey = getFileKey(uploadId, index);
165
+ if (skippedFiles.delete(fileKey)) {
166
+ return;
167
+ }
139
168
  const fileName = entry.fileInfo?.name ?? entry.file.name;
140
169
  dispatch(setFileUploading({
141
170
  name: fileName,
@@ -143,6 +172,11 @@ const trackPoolRun = (uploadId, run)=>{
143
172
  size: entry.file.size,
144
173
  uploadId
145
174
  }));
175
+ // Aborted by either a per-file cancel or the batch's own Cancel all.
176
+ const fileAbortController = new AbortController();
177
+ const abortFile = ()=>fileAbortController.abort();
178
+ abortController.signal.addEventListener('abort', abortFile);
179
+ fileAbortControllers.set(fileKey, fileAbortController);
146
180
  const formData = new FormData();
147
181
  formData.append('files', entry.file);
148
182
  formData.append('fileInfo', JSON.stringify(entry.fileInfo));
@@ -155,7 +189,7 @@ const trackPoolRun = (uploadId, run)=>{
155
189
  }));
156
190
  });
157
191
  try {
158
- const file = await uploadFileViaXHR(url, token, formData, abortController.signal, (bytes)=>batcher.schedule(bytes));
192
+ const file = await uploadFileViaXHR(url, token, formData, fileAbortController.signal, (bytes)=>batcher.schedule(bytes));
159
193
  batcher.cancel();
160
194
  uploaded.push(file);
161
195
  dispatch(setFileComplete({
@@ -176,8 +210,8 @@ const trackPoolRun = (uploadId, run)=>{
176
210
  } catch (err) {
177
211
  batcher.cancel();
178
212
  if (err instanceof UploadAbortedError) {
179
- // Batch was cancelled — the worker loop checks the signal and stops.
180
- // cancelUpload (dispatched from the dialog) marks the remaining rows.
213
+ // Batch or file was cancelled. Whoever cancelled marks the rows
214
+ // (`cancelUpload` / `cancelFile`); a batch abort also stops the workers.
181
215
  return;
182
216
  }
183
217
  const message = err instanceof Error ? err.message : 'Upload failed';
@@ -187,6 +221,9 @@ const trackPoolRun = (uploadId, run)=>{
187
221
  message,
188
222
  uploadId
189
223
  }));
224
+ } finally{
225
+ abortController.signal.removeEventListener('abort', abortFile);
226
+ fileAbortControllers.delete(fileKey);
190
227
  }
191
228
  };
192
229
  // Guard non-finite/invalid values (NaN, Infinity, <1): `Math.floor(NaN)`
@@ -438,7 +475,7 @@ const uploadApi = adminApi.enhanceEndpoints({
438
475
  * pool of `concurrency` parallel requests (default 1 = sequential). Real
439
476
  * per-file byte progress comes from `XHR.upload.onprogress`.
440
477
  */ uploadFiles: builder.mutation({
441
- queryFn: async ({ formData, totalFiles, concurrency = 1, generateAiMetadata, onFileUploaded }, { dispatch, getState })=>{
478
+ queryFn: async ({ formData, totalFiles, concurrency = 1, generateAiMetadata, onFileUploaded, owner }, { dispatch, getState })=>{
442
479
  const token = getState().admin_app?.token;
443
480
  // Extract the original files and their per-file fileInfo from the combined FormData.
444
481
  const files = formData.getAll('files');
@@ -469,7 +506,8 @@ const uploadApi = adminApi.enhanceEndpoints({
469
506
  dispatch(appendUploadFiles({
470
507
  uploadId,
471
508
  fileNames,
472
- fileSizes
509
+ fileSizes,
510
+ owner
473
511
  }));
474
512
  const mergedEntries = [
475
513
  ...batch.entries,
@@ -492,7 +530,8 @@ const uploadApi = adminApi.enhanceEndpoints({
492
530
  dispatch(openUploadProgress({
493
531
  totalFiles,
494
532
  fileNames,
495
- fileSizes
533
+ fileSizes,
534
+ owner
496
535
  }));
497
536
  // Get the uploadId from state after dispatching
498
537
  const uploadId = getState().uploadProgress.uploadId;
@@ -634,6 +673,49 @@ const uploadApi = adminApi.enhanceEndpoints({
634
673
  ]
635
674
  }),
636
675
  /**
676
+ * Retry one cancelled or failed file of the current batch. Queued behind
677
+ * whatever the batch still has in flight, so `concurrency` keeps holding.
678
+ */ retryUploadFile: builder.mutation({
679
+ queryFn: async ({ uploadId, index }, { dispatch, getState })=>{
680
+ const { uploadProgress, admin_app } = getState();
681
+ const batch = getUploadEntries(uploadId);
682
+ if (uploadId !== uploadProgress.uploadId || !batch || !batch.entries[index]) {
683
+ return {
684
+ error: {
685
+ name: 'UnknownError',
686
+ message: 'Original file not found'
687
+ }
688
+ };
689
+ }
690
+ skippedFiles.delete(getFileKey(uploadId, index));
691
+ dispatch(retryFile({
692
+ uploadId,
693
+ index
694
+ }));
695
+ return runMergedUploadPool({
696
+ entries: batch.entries,
697
+ indices: [
698
+ index
699
+ ],
700
+ token: admin_app?.token,
701
+ uploadId,
702
+ dispatch,
703
+ concurrency: batch.concurrency,
704
+ generateAiMetadata: batch.generateAiMetadata
705
+ });
706
+ },
707
+ invalidatesTags: [
708
+ {
709
+ type: 'Asset',
710
+ id: 'LIST'
711
+ },
712
+ {
713
+ type: 'Folder',
714
+ id: 'LIST'
715
+ }
716
+ ]
717
+ }),
718
+ /**
637
719
  * Upload files from URLs.
638
720
  * Sends URLs to the server which fetches and uploads them (SSE flow, unchanged).
639
721
  */ uploadFromUrls: builder.mutation({
@@ -770,7 +852,7 @@ const uploadApi = adminApi.enhanceEndpoints({
770
852
  })
771
853
  })
772
854
  });
773
- const { useUploadFilesMutation, useUploadFileSilentlyMutation, useRetryCancelledFilesMutation, useUploadFromUrlsMutation, useGenerateAiMetadataMutation } = uploadApi;
855
+ const { useUploadFilesMutation, useUploadFileSilentlyMutation, useRetryCancelledFilesMutation, useRetryUploadFileMutation, useUploadFromUrlsMutation, useGenerateAiMetadataMutation } = uploadApi;
774
856
 
775
- export { abortUpload, maybeGenerateMetadata, uploadApi, useGenerateAiMetadataMutation, useRetryCancelledFilesMutation, useUploadFileSilentlyMutation, useUploadFilesMutation, useUploadFromUrlsMutation };
857
+ export { abortUpload, abortUploadFile, getUploadSourceFile, maybeGenerateMetadata, uploadApi, useGenerateAiMetadataMutation, useRetryCancelledFilesMutation, useRetryUploadFileMutation, useUploadFileSilentlyMutation, useUploadFilesMutation, useUploadFromUrlsMutation };
776
858
  //# sourceMappingURL=api.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.mjs","sources":["../../../admin/src/services/api.ts"],"sourcesContent":["import { Dispatch } from '@reduxjs/toolkit';\nimport { adminApi } from '@strapi/admin/strapi-admin';\n\nimport {\n openUploadProgress,\n appendUploadFiles,\n isUploadInFlight,\n setFileUploading,\n setFileProgress,\n setFileComplete,\n setFileError,\n setFileMetadataGenerating,\n setFileMetadataResult,\n setUploadFailed,\n retryCancelledFiles,\n} from '../store/uploadProgress';\nimport { createRafBatcher } from '../utils/createRafBatcher';\nimport { getFilenameFromUrl } from '../utils/files';\n\nimport { uploadFileViaXHR, UploadAbortedError, UploadFileError } from './uploadFileViaXHR';\n\nimport type {\n CreateFilesStream,\n CreateFilesStreamEvents,\n File as UploadedFile,\n GenerateAIMetadata,\n UploadFileInfo,\n} from '../../../shared/contracts/files';\nimport type { FileMetadataResultStatus } from '../store/uploadProgress';\n\ninterface UploadFilesArgs {\n formData: FormData;\n totalFiles: number;\n /**\n * How many files to upload in parallel — the `concurrentUploadRequests`\n * settings value. Defaults to 1 (sequential).\n */\n concurrency?: number;\n /** Whether AI metadata generation is enabled (EE AI available + `settings.aiMetadata`). */\n generateAiMetadata: boolean;\n /**\n * Called for each file of this call as it finishes uploading, including files\n * a later retry uploads after the call itself has resolved.\n */\n onFileUploaded?: (file: UploadedFile) => void;\n}\n\ninterface UploadFromUrlsArgs {\n urls: string[];\n folderId: number | null;\n generateAiMetadata: boolean;\n}\n\ninterface RootState {\n admin_app: {\n token?: string | null;\n };\n uploadProgress: {\n uploadId: number;\n files: Array<{\n index: number;\n name: string;\n size: number;\n status: 'pending' | 'uploading' | 'complete' | 'error' | 'cancelled';\n }>;\n };\n}\n\n/**\n * A single file plus the `fileInfo` it was queued with.\n * Retained in {@link uploadRegistry} so cancelled files can be retried without\n * the user re-selecting them. `File`/`AbortController` are non-serializable, so\n * they live here rather than in Redux.\n */\ninterface UploadEntry {\n file: File;\n fileInfo: UploadFileInfo;\n onUploaded?: (file: UploadedFile) => void;\n}\n\n/**\n * Everything a batch needs to be replayed on retry: the original entries plus the\n * flags it was started with (AI-metadata and upload concurrency). These live here\n * rather than in Redux because `retryCancelledFiles` takes no args and the page\n * that owns the settings value is not involved in the retry.\n */\ninterface UploadBatch {\n entries: UploadEntry[];\n generateAiMetadata: boolean;\n concurrency: number;\n}\n\n/**\n * Stores the original upload batch (keyed by uploadId) to enable retry.\n */\nconst uploadRegistry = new Map<number, UploadBatch>();\n\nconst registerUploadEntries = (\n uploadId: number,\n entries: UploadEntry[],\n generateAiMetadata: boolean,\n concurrency: number\n) => {\n uploadRegistry.set(uploadId, { entries, generateAiMetadata, concurrency });\n};\n\nconst getUploadEntries = (uploadId: number): UploadBatch | undefined => {\n return uploadRegistry.get(uploadId);\n};\n\n/**\n * Manages abort controllers for in-flight uploads.\n *\n * Design decision: Uses a Map to track uploads by their unique uploadId.\n * Redux state cannot store function references (abort controllers), RTK Query's\n * signal is only accessible within the queryFn, and the upload is triggered in\n * AssetsPage but cancelled from UploadProgressDialog.\n */\nconst abortControllers = new Map<number, AbortController>();\n\nconst registerAbortController = (uploadId: number, controller: AbortController) => {\n abortControllers.set(uploadId, controller);\n};\n\nconst unregisterAbortController = (uploadId: number) => {\n abortControllers.delete(uploadId);\n};\n\n/**\n * Aborts an upload by its uploadId.\n * Called from the UploadProgressDialog when the user clicks cancel or close.\n */\nexport const abortUpload = (uploadId: number) => {\n const controller = abortControllers.get(uploadId);\n if (controller) {\n controller.abort();\n unregisterAbortController(uploadId);\n }\n};\n\n/**\n * Runs are chained per batch rather than started in parallel: a second pool\n * alongside the first would double the files in flight and make `concurrency`\n * stop meaning anything.\n */\nconst poolTails = new Map<number, Promise<UploadPoolResult | undefined>>();\n\nconst trackPoolRun = (uploadId: number, run: Promise<UploadPoolResult>) => {\n // Not swallowed: the caller still gets the real result from `run`.\n const tail = run.catch(() => undefined);\n\n poolTails.set(uploadId, tail);\n\n tail.then(() => {\n // Leave the entry alone if another run has queued behind us in the meantime.\n if (poolTails.get(uploadId) === tail) {\n poolTails.delete(uploadId);\n }\n });\n};\n\n/**\n * Error shape returned by upload operations.\n * Matches RTK Query's expected return type for queryFn.\n */\ninterface UploadError {\n name: 'UnknownError';\n message: string;\n status?: number;\n}\n\n/**\n * The store's dispatch also accepts thunks, which is what RTK Query's\n * `endpoint.initiate(...)` returns — the plain `Dispatch` action type can't express that.\n */\ntype AppDispatch = Dispatch &\n (<T>(thunk: T) => T extends (...args: never[]) => infer R ? R : never);\n\ntype UploadPoolResult =\n /**\n * `own` is set only by a merged leg: `data` is the whole batch so far, for the\n * next leg to chain from, while `own` is what this call uploaded.\n */\n | { data: UploadedFile[]; own?: UploadedFile[]; error?: undefined }\n | { error: UploadError; data?: undefined; own?: undefined };\n\n/** Maps a server per-file outcome onto the row's terminal metadata status. */\nconst METADATA_STATUS_BY_RESULT: Record<GenerateAIMetadata.FileStatus, FileMetadataResultStatus> = {\n success: 'generated',\n skipped: 'skipped',\n error: 'failed',\n};\n\n/**\n * Re-attaches the folder an upload targeted.\n *\n * The create response is built from `db.query().create()` with no populate, so\n * it comes back without the folder relation it was just given. The list needs\n * it to tell whether a freshly uploaded asset belongs to the folder on screen.\n */\nconst withTargetFolder = (\n file: UploadedFile,\n folder: number | string | null | undefined\n): UploadedFile => (file.folder != null ? file : { ...file, folder: folder ?? null });\n\n/**\n * Kicks off AI metadata generation for a freshly uploaded file.\n *\n * Deliberately fire-and-forget — the caller must NOT await it:\n * - generation for file N overlaps the upload of file N+1;\n * - a generation failure can never affect the upload result (the upload already\n * succeeded), which is why the promise is fully swallowed here.\n *\n * Every uploaded file is sent, including non-images: the server already classifies\n * them (`ai-metadata.generateForFiles` returns `skipped` for anything whose mime\n * isn't `image/*`) and duplicating that rule here would let the two drift apart.\n * The upshot is that a non-image now reports \"Metadata generation skipped\" rather\n * than silently showing no metadata state at all.\n */\nexport const maybeGenerateMetadata = ({\n file,\n index,\n uploadId,\n enabled,\n dispatch,\n}: {\n file: UploadedFile;\n index: number;\n uploadId: number;\n enabled: boolean;\n dispatch: Dispatch;\n}): void => {\n if (!enabled || typeof file.id !== 'number') {\n return;\n }\n\n dispatch(setFileMetadataGenerating({ index, uploadId }));\n\n // `uploadApi` is declared below but only read at call time, long after the module\n // has finished evaluating.\n const promise = (dispatch as AppDispatch)(\n uploadApi.endpoints.generateAiMetadata.initiate({ fileIds: [file.id] })\n );\n\n promise\n .unwrap()\n .then((results) => {\n const result = results?.find((r) => r.id === file.id) ?? results?.[0];\n dispatch(\n setFileMetadataResult({\n index,\n uploadId,\n status: result ? METADATA_STATUS_BY_RESULT[result.status] : 'failed',\n })\n );\n })\n .catch(() => {\n dispatch(setFileMetadataResult({ index, uploadId, status: 'failed' }));\n });\n};\n\n/**\n * Uploads the given entry indices one at a time through the single-file endpoint.\n *\n * For each file: dispatches \"uploading\", wires `XHR.upload.onprogress` through a\n * per-frame batcher to `setFileProgress`, awaits the XHR, then dispatches\n * \"complete\" or \"error\". Each file is wrapped in its own try/catch so one failure\n * does not stop the batch. An abort stops the loop without starting further files.\n */\nconst runUploadPool = async ({\n entries,\n indices,\n token,\n uploadId,\n abortController,\n dispatch,\n concurrency = 1,\n generateAiMetadata,\n}: {\n entries: UploadEntry[];\n indices: number[];\n token: string | null | undefined;\n uploadId: number;\n abortController: AbortController;\n dispatch: Dispatch;\n /** Parallel workers pulling from the queue. 1 (the default) = sequential. */\n concurrency?: number;\n generateAiMetadata: boolean;\n}): Promise<UploadPoolResult> => {\n const url = `${window.strapi.backendURL}/upload/files`;\n const uploaded: UploadedFile[] = [];\n\n // Shared queue: each worker shifts the next index when it frees up, so N\n // files are in flight at any moment (not N-sized waves). With concurrency 1\n // this degenerates to the original strictly sequential loop.\n const queue = [...indices];\n\n const uploadOne = async (index: number) => {\n const entry = entries[index];\n if (!entry) {\n return;\n }\n\n const fileName = entry.fileInfo?.name ?? entry.file.name;\n\n dispatch(setFileUploading({ name: fileName, index, size: entry.file.size, uploadId }));\n\n const formData = new FormData();\n formData.append('files', entry.file);\n formData.append('fileInfo', JSON.stringify(entry.fileInfo));\n\n // Coalesce high-frequency progress events into one dispatch per frame.\n const batcher = createRafBatcher<number>((bytes) => {\n dispatch(setFileProgress({ index, bytes, uploadId }));\n });\n\n try {\n const file = await uploadFileViaXHR(url, token, formData, abortController.signal, (bytes) =>\n batcher.schedule(bytes)\n );\n batcher.cancel();\n uploaded.push(file);\n dispatch(\n setFileComplete({\n index,\n file: withTargetFolder(file, entry.fileInfo?.folder),\n uploadId,\n completedAt: Date.now(),\n })\n );\n entry.onUploaded?.(file);\n\n // Not awaited: overlaps with the next file's upload and can't fail the batch.\n maybeGenerateMetadata({\n file,\n index,\n uploadId,\n enabled: generateAiMetadata,\n dispatch,\n });\n } catch (err) {\n batcher.cancel();\n\n if (err instanceof UploadAbortedError) {\n // Batch was cancelled — the worker loop checks the signal and stops.\n // cancelUpload (dispatched from the dialog) marks the remaining rows.\n return;\n }\n\n const message = err instanceof Error ? err.message : 'Upload failed';\n dispatch(setFileError({ index, name: fileName, message, uploadId }));\n }\n };\n\n // Guard non-finite/invalid values (NaN, Infinity, <1): `Math.floor(NaN)`\n // would propagate through Math.max to `Array.from({ length: NaN })` = zero\n // workers, silently uploading nothing. Anything invalid falls back to 1.\n const requested = Number.isFinite(concurrency) ? Math.floor(concurrency) : 1;\n const workerCount = Math.min(Math.max(1, requested), queue.length);\n\n const worker = async () => {\n while (queue.length > 0) {\n if (abortController.signal.aborted) {\n break;\n }\n\n const index = queue.shift();\n if (index === undefined) {\n break;\n }\n\n // eslint-disable-next-line no-await-in-loop\n await uploadOne(index);\n }\n };\n\n await Promise.all(Array.from({ length: workerCount }, () => worker()));\n\n unregisterAbortController(uploadId);\n\n return { data: uploaded };\n};\n\n/**\n * Reuses the batch's AbortController so one Cancel stops both drops.\n * `runUploadPool` unregisters it on finish, hence the re-register below.\n *\n * Resolves with the whole batch's files, not just this leg's: the mutation\n * models one drop, and after a merge the drop is the batch. The earlier leg's\n * files come from the tail this run queued behind.\n */\nconst runMergedUploadPool = async ({\n entries,\n indices,\n token,\n uploadId,\n dispatch,\n concurrency,\n generateAiMetadata,\n}: {\n entries: UploadEntry[];\n indices: number[];\n token: string | null | undefined;\n uploadId: number;\n dispatch: Dispatch;\n concurrency: number;\n generateAiMetadata: boolean;\n}): Promise<UploadPoolResult> => {\n const abortController = abortControllers.get(uploadId) ?? new AbortController();\n\n const run = (poolTails.get(uploadId) ?? Promise.resolve(undefined)).then(\n (previous): UploadPoolResult | Promise<UploadPoolResult> => {\n // A failed earlier leg contributes no files; its error already reached the\n // store, and this leg still has files of its own to upload.\n const earlier = previous?.data ?? [];\n\n if (abortController.signal.aborted) {\n return { data: earlier, own: [] };\n }\n\n registerAbortController(uploadId, abortController);\n\n return runUploadPool({\n entries,\n indices,\n token,\n uploadId,\n abortController,\n dispatch,\n concurrency,\n generateAiMetadata,\n }).then((result) =>\n result.error\n ? result\n : { data: [...earlier, ...(result.data ?? [])], own: result.data ?? [] }\n );\n }\n );\n\n trackPoolRun(uploadId, run);\n\n // The chained value keeps every file in the batch, because the next merged leg\n // reads it as its own `earlier`. The caller gets only what it handed in: a\n // consumer that attaches the result — the Content Manager field — would\n // otherwise re-attach the files the earlier drop already added.\n return run.then((result) => (result.error ? result : { data: result.own ?? result.data }));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * URL upload flow (SSE) — kept as-is for this iteration\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Parses a raw SSE text chunk into event/data pairs.\n *\n * SSE format:\n * event: <eventName>\\n\n * data: <json>\\n\n * \\n\n */\nconst parseSSEEvents = (chunk: string): Array<{ event: string; data: string }> => {\n const events: Array<{ event: string; data: string }> = [];\n const blocks = chunk.split('\\n\\n').filter(Boolean);\n\n for (const block of blocks) {\n let event = '';\n let data = '';\n\n for (const line of block.split('\\n')) {\n if (line.startsWith('event: ')) {\n event = line.slice(7);\n } else if (line.startsWith('data: ')) {\n data = line.slice(6);\n }\n }\n\n if (event && data) {\n events.push({ event, data });\n }\n }\n\n return events;\n};\n\n/**\n * Makes a streaming upload-from-URLs request to the server.\n * Sends URLs as JSON body instead of FormData.\n */\nconst fetchUrlUploadStream = async ({\n token,\n urls,\n folderId,\n signal,\n}: {\n token: string | null | undefined;\n urls: string[];\n folderId: number | null;\n signal: AbortSignal;\n}): Promise<Response> => {\n const backendURL = window.strapi.backendURL;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n }\n\n return fetch(`${backendURL}/upload/actions/upload-from-urls`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ urls, folderId }),\n signal,\n });\n};\n\n/**\n * Processes an SSE stream from the URL upload endpoint.\n * Dispatches Redux actions for each file event and returns the final result.\n */\nconst processSSEStream = async ({\n response,\n dispatch,\n uploadId,\n generateAiMetadata,\n folderId,\n}: {\n response: Response;\n dispatch: Dispatch;\n uploadId: number;\n generateAiMetadata: boolean;\n folderId?: number | null;\n}): Promise<CreateFilesStream.Response | null> => {\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let streamResult: CreateFilesStream.Response | null = null;\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete SSE events from the buffer\n const lastDoubleNewline = buffer.lastIndexOf('\\n\\n');\n if (lastDoubleNewline === -1) {\n // No complete events yet, keep buffering\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const completePart = buffer.slice(0, lastDoubleNewline + 2);\n buffer = buffer.slice(lastDoubleNewline + 2);\n\n const events = parseSSEEvents(completePart);\n\n for (const { event, data } of events) {\n const parsed = JSON.parse(data);\n const index = parsed.index as number;\n\n switch (event) {\n case 'file:fetching': {\n // URL is being fetched server-side - mark as uploading (processing)\n dispatch(setFileUploading({ name: parsed.url as string, index, size: 0, uploadId }));\n break;\n }\n case 'file:progress': {\n const payload = parsed as CreateFilesStreamEvents.FileProgressEvent;\n\n // No usable Content-Length on the remote: leave the row indeterminate\n if (payload.totalBytes === null) {\n break;\n }\n\n // Already throttled server-side (~5 frames a second per file), so no batching\n // here. `size` rides along because the row is still at 0 — see `setFileProgress`.\n dispatch(\n setFileProgress({\n index,\n bytes: payload.loadedBytes,\n size: payload.totalBytes,\n uploadId,\n })\n );\n break;\n }\n case 'file:uploading': {\n const payload = parsed as CreateFilesStreamEvents.FileUploadingEvent;\n dispatch(setFileUploading({ name: payload.name, index, size: payload.size, uploadId }));\n break;\n }\n case 'file:complete': {\n const payload = parsed as CreateFilesStreamEvents.FileCompleteEvent;\n dispatch(\n setFileComplete({\n index,\n file: withTargetFolder(payload.file, folderId),\n uploadId,\n completedAt: Date.now(),\n })\n );\n\n // Same fire-and-forget semantics as the file flow.\n maybeGenerateMetadata({\n file: payload.file,\n index,\n uploadId,\n enabled: generateAiMetadata,\n dispatch,\n });\n break;\n }\n case 'file:error': {\n const payload = parsed as CreateFilesStreamEvents.FileErrorEvent;\n dispatch(setFileError({ index, name: payload.name, message: payload.message, uploadId }));\n break;\n }\n case 'stream:complete': {\n const payload = parsed as CreateFilesStreamEvents.StreamCompleteEvent;\n streamResult = {\n data: payload.data,\n errors: payload.errors,\n };\n break;\n }\n default:\n console.error(`[SSE Upload] unknown event: ${event}`, parsed);\n }\n }\n }\n\n return streamResult;\n};\n\nconst uploadApi = adminApi\n .enhanceEndpoints({\n addTagTypes: ['Asset', 'Folder'],\n })\n .injectEndpoints({\n endpoints: (builder) => ({\n /**\n * Upload files to `/upload/files`, one request per file, through a worker\n * pool of `concurrency` parallel requests (default 1 = sequential). Real\n * per-file byte progress comes from `XHR.upload.onprogress`.\n */\n uploadFiles: builder.mutation<UploadedFile[], UploadFilesArgs>({\n queryFn: async (\n { formData, totalFiles, concurrency = 1, generateAiMetadata, onFileUploaded },\n { dispatch, getState }\n ) => {\n const token = (getState() as RootState).admin_app?.token;\n\n // Extract the original files and their per-file fileInfo from the combined FormData.\n const files = formData.getAll('files') as File[];\n const fileInfoJson = formData.get('fileInfo') as string;\n const fileInfoArray = JSON.parse(fileInfoJson) as UploadFileInfo[];\n\n const entries: UploadEntry[] = files.map((file, index) => ({\n file,\n fileInfo: fileInfoArray[index] ?? {\n name: file.name,\n caption: null,\n alternativeText: null,\n folder: null,\n },\n onUploaded: onFileUploaded,\n }));\n\n const fileNames = entries.map((entry) => entry.fileInfo.name ?? entry.file.name);\n const fileSizes = entries.map((entry) => entry.file.size);\n\n // `uploadFromUrls` also leaves rows `pending`, but registers no batch —\n // so an unregistered batch is not ours to merge into, and appending would\n // land on top of its rows.\n const progress = (getState() as RootState).uploadProgress;\n const batch = getUploadEntries(progress.uploadId);\n const isMerge = batch !== undefined && isUploadInFlight(progress.files);\n\n if (isMerge) {\n const { uploadId } = progress;\n const offset = batch.entries.length;\n\n // No `totalFiles`: the reducer derives it from the rows it appends.\n dispatch(appendUploadFiles({ uploadId, fileNames, fileSizes }));\n\n const mergedEntries = [...batch.entries, ...entries];\n\n // Merged files adopt the batch's flags: a new concurrency would raise\n // the ceiling it exists to impose.\n registerUploadEntries(\n uploadId,\n mergedEntries,\n batch.generateAiMetadata,\n batch.concurrency\n );\n\n return runMergedUploadPool({\n entries: mergedEntries,\n indices: entries.map((_, index) => offset + index),\n token,\n uploadId,\n dispatch,\n concurrency: batch.concurrency,\n generateAiMetadata: batch.generateAiMetadata,\n });\n }\n\n // Open the progress dialog\n dispatch(openUploadProgress({ totalFiles, fileNames, fileSizes }));\n\n // Get the uploadId from state after dispatching\n const uploadId = (getState() as RootState).uploadProgress.uploadId;\n\n // Store original entries for retry functionality\n registerUploadEntries(uploadId, entries, generateAiMetadata, concurrency);\n\n // One AbortController per batch\n const abortController = new AbortController();\n registerAbortController(uploadId, abortController);\n\n const run = runUploadPool({\n entries,\n indices: entries.map((_, index) => index),\n token,\n uploadId,\n abortController,\n dispatch,\n concurrency,\n generateAiMetadata,\n });\n\n trackPoolRun(uploadId, run);\n\n return run;\n },\n // `Folder, LIST` refreshes the folder header count, which changes when\n // files are added to it.\n invalidatesTags: [\n { type: 'Asset', id: 'LIST' },\n { type: 'Folder', id: 'LIST' },\n ],\n }),\n\n /**\n * Upload a single, already-prepared file WITHOUT opening the global\n * upload-progress dialog. For flows that create one asset programmatically\n * (e.g. crop → \"Save as copy\"), where the bulk-upload progress UI is\n * inappropriate. Same endpoint as `uploadFiles`, minus the progress/retry\n * machinery.\n */\n uploadFileSilently: builder.mutation<UploadedFile, UploadEntry>({\n queryFn: async ({ file, fileInfo }, { getState }) => {\n const token = (getState() as RootState).admin_app?.token;\n const url = `${window.strapi.backendURL}/upload/files`;\n\n const formData = new FormData();\n formData.append('files', file);\n formData.append('fileInfo', JSON.stringify(fileInfo));\n\n try {\n const uploaded = await uploadFileViaXHR(\n url,\n token,\n formData,\n new AbortController().signal,\n () => {}\n );\n return { data: uploaded };\n } catch (err) {\n // Only pass on text the server actually sent. The XHR layer's own\n // fallbacks are hardcoded English, and callers here (crop → \"Save\n // as copy\") have a localized message of their own; an empty string\n // reads as \"nothing usable\" and lets theirs win.\n const message =\n err instanceof UploadFileError && err.isServerMessage ? err.message : '';\n return { error: { name: 'UnknownError', message } };\n }\n },\n // `Folder, LIST` refreshes the folder header count, which changes when\n // files are added to it.\n invalidatesTags: [\n { type: 'Asset', id: 'LIST' },\n { type: 'Folder', id: 'LIST' },\n ],\n }),\n\n /**\n * Retry uploading cancelled files.\n * Maps cancelled rows back to their original entries and re-runs only those\n * through the same upload pool with a fresh AbortController.\n */\n retryCancelledFiles: builder.mutation<UploadedFile[], void>({\n queryFn: async (_arg, { dispatch, getState }) => {\n const { uploadId, files: stateFiles } = (getState() as RootState).uploadProgress;\n const token = (getState() as RootState).admin_app?.token;\n\n const cancelledIndices = stateFiles\n .filter((f) => f.status === 'cancelled')\n .map((f) => f.index);\n\n if (cancelledIndices.length === 0) {\n return { error: { name: 'UnknownError', message: 'No cancelled files to retry' } };\n }\n\n const batch = getUploadEntries(uploadId);\n if (!batch) {\n return { error: { name: 'UnknownError', message: 'Original files not found' } };\n }\n\n // Reset cancelled files back to pending\n dispatch(retryCancelledFiles());\n\n // Fresh AbortController for the retry run\n const abortController = new AbortController();\n registerAbortController(uploadId, abortController);\n\n const run = runUploadPool({\n entries: batch.entries,\n indices: cancelledIndices,\n token,\n uploadId,\n abortController,\n dispatch,\n // Replay the retried rows with the flags the batch was started with.\n concurrency: batch.concurrency,\n generateAiMetadata: batch.generateAiMetadata,\n });\n\n // Retried rows are `pending` again, so a drop lands on the merge branch.\n // Untracked, that merge would find no tail to queue behind and run its\n // pool beside this one — two pools of `concurrency` each.\n trackPoolRun(uploadId, run);\n\n return run;\n },\n // `Folder, LIST` refreshes the folder header count, which changes when\n // files are added to it.\n invalidatesTags: [\n { type: 'Asset', id: 'LIST' },\n { type: 'Folder', id: 'LIST' },\n ],\n }),\n\n /**\n * Upload files from URLs.\n * Sends URLs to the server which fetches and uploads them (SSE flow, unchanged).\n */\n uploadFromUrls: builder.mutation<CreateFilesStream.Response, UploadFromUrlsArgs>({\n queryFn: async ({ urls, folderId, generateAiMetadata }, { dispatch, getState }) => {\n const token = (getState() as RootState).admin_app?.token;\n\n // Extract filenames from URLs for the progress dialog\n const fileNames = urls.map((url) => getFilenameFromUrl(url));\n\n // Open progress dialog with all URLs as pending files\n dispatch(\n openUploadProgress({\n totalFiles: urls.length,\n fileNames,\n })\n );\n\n // Get the uploadId from state after dispatching\n const uploadId = (getState() as RootState).uploadProgress.uploadId;\n\n // Create abort controller for this upload\n const abortController = new AbortController();\n registerAbortController(uploadId, abortController);\n\n try {\n // Send URLs to server for fetching and uploading\n const response = await fetchUrlUploadStream({\n token,\n urls,\n folderId,\n signal: abortController.signal,\n });\n\n if (!response.ok || !response.body) {\n unregisterAbortController(uploadId);\n\n let errorMessage = 'Upload request failed';\n try {\n const errorData = await response.json();\n if (errorData.error?.message) {\n errorMessage = errorData.error.message;\n } else if (errorData.message) {\n errorMessage = errorData.message;\n }\n } catch {\n errorMessage = `Upload failed with status ${response.status}`;\n }\n\n dispatch(setUploadFailed({ message: errorMessage }));\n\n return {\n error: {\n name: 'UnknownError' as const,\n message: errorMessage,\n status: response.status,\n },\n };\n }\n\n // Process SSE stream from server\n const streamResult = await processSSEStream({\n response,\n dispatch,\n uploadId,\n generateAiMetadata,\n folderId,\n });\n\n unregisterAbortController(uploadId);\n\n if (streamResult && streamResult.data.length > 0) {\n return { data: streamResult };\n }\n\n return { data: { data: [], errors: [] } };\n } catch (err) {\n unregisterAbortController(uploadId);\n\n if (err instanceof DOMException && err.name === 'AbortError') {\n return { error: { name: 'UnknownError' as const, message: 'Upload cancelled' } };\n }\n\n const errorMessage = err instanceof Error ? err.message : 'Network error occurred';\n dispatch(setUploadFailed({ message: errorMessage }));\n\n return {\n error: {\n name: 'UnknownError' as const,\n message: errorMessage,\n },\n };\n }\n },\n // `Folder, LIST` refreshes the folder header count, which changes when\n // files are added to it.\n invalidatesTags: [\n { type: 'Asset', id: 'LIST' },\n { type: 'Folder', id: 'LIST' },\n ],\n }),\n\n /**\n * Generate AI metadata (alt text + caption) for the given assets.\n * Synchronous: resolves once every file has been processed and reports the\n * outcome per file, so non-images and individual failures don't fail the\n * whole batch. Existing alt text and captions are never overwritten.\n *\n * Lives here rather than in `assets.ts` because the upload flows dispatch it\n * directly via `initiate()` after each file completes, and `assets.ts` already\n * imports from this module — defining it there would be a circular import.\n * Re-exported from `assets.ts` for the components that consume the hook.\n */\n generateAiMetadata: builder.mutation<\n GenerateAIMetadata.Response['data'],\n { fileIds: number[] }\n >({\n query: ({ fileIds }) => ({\n url: '/upload/actions/generate-ai-metadata',\n method: 'POST',\n data: { fileIds },\n }),\n transformResponse: (response: { data: GenerateAIMetadata.Response['data'] }) =>\n response.data,\n invalidatesTags: (_result, _error, { fileIds }) => [\n ...fileIds.map((id) => ({ type: 'Asset' as const, id })),\n { type: 'Asset' as const, id: 'LIST' },\n ],\n }),\n }),\n });\n\nexport const {\n useUploadFilesMutation,\n useUploadFileSilentlyMutation,\n useRetryCancelledFilesMutation,\n useUploadFromUrlsMutation,\n useGenerateAiMetadataMutation,\n} = uploadApi;\nexport { uploadApi };\n"],"names":["uploadRegistry","Map","registerUploadEntries","uploadId","entries","generateAiMetadata","concurrency","set","getUploadEntries","get","abortControllers","registerAbortController","controller","unregisterAbortController","delete","abortUpload","abort","poolTails","trackPoolRun","run","tail","catch","undefined","then","METADATA_STATUS_BY_RESULT","success","skipped","error","withTargetFolder","file","folder","maybeGenerateMetadata","index","enabled","dispatch","id","setFileMetadataGenerating","promise","uploadApi","endpoints","initiate","fileIds","unwrap","results","result","find","r","setFileMetadataResult","status","runUploadPool","indices","token","abortController","url","window","strapi","backendURL","uploaded","queue","uploadOne","entry","fileName","fileInfo","name","setFileUploading","size","formData","FormData","append","JSON","stringify","batcher","createRafBatcher","bytes","setFileProgress","uploadFileViaXHR","signal","schedule","cancel","push","setFileComplete","completedAt","Date","now","onUploaded","err","UploadAbortedError","message","Error","setFileError","requested","Number","isFinite","Math","floor","workerCount","min","max","length","worker","aborted","shift","Promise","all","Array","from","data","runMergedUploadPool","AbortController","resolve","previous","earlier","own","parseSSEEvents","chunk","events","blocks","split","filter","Boolean","block","event","line","startsWith","slice","fetchUrlUploadStream","urls","folderId","headers","Authorization","fetch","method","body","processSSEStream","response","reader","getReader","decoder","TextDecoder","streamResult","buffer","done","value","read","decode","stream","lastDoubleNewline","lastIndexOf","completePart","parsed","parse","payload","totalBytes","loadedBytes","errors","console","adminApi","enhanceEndpoints","addTagTypes","injectEndpoints","builder","uploadFiles","mutation","queryFn","totalFiles","onFileUploaded","getState","admin_app","files","getAll","fileInfoJson","fileInfoArray","map","caption","alternativeText","fileNames","fileSizes","progress","uploadProgress","batch","isMerge","isUploadInFlight","offset","appendUploadFiles","mergedEntries","_","openUploadProgress","invalidatesTags","type","uploadFileSilently","UploadFileError","isServerMessage","retryCancelledFiles","_arg","stateFiles","cancelledIndices","f","uploadFromUrls","getFilenameFromUrl","ok","errorMessage","errorData","json","setUploadFailed","DOMException","query","transformResponse","_result","_error","useUploadFilesMutation","useUploadFileSilentlyMutation","useRetryCancelledFilesMutation","useUploadFromUrlsMutation","useGenerateAiMetadataMutation"],"mappings":"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"}
1
+ {"version":3,"file":"api.mjs","sources":["../../../admin/src/services/api.ts"],"sourcesContent":["import { Dispatch } from '@reduxjs/toolkit';\nimport { adminApi } from '@strapi/admin/strapi-admin';\n\nimport {\n openUploadProgress,\n appendUploadFiles,\n isUploadInFlight,\n setFileUploading,\n setFileProgress,\n setFileComplete,\n setFileError,\n setFileMetadataGenerating,\n setFileMetadataResult,\n setUploadFailed,\n retryCancelledFiles,\n retryFile,\n} from '../store/uploadProgress';\nimport { createRafBatcher } from '../utils/createRafBatcher';\nimport { getFilenameFromUrl } from '../utils/files';\n\nimport { uploadFileViaXHR, UploadAbortedError, UploadFileError } from './uploadFileViaXHR';\n\nimport type {\n CreateFilesStream,\n CreateFilesStreamEvents,\n File as UploadedFile,\n GenerateAIMetadata,\n UploadFileInfo,\n} from '../../../shared/contracts/files';\nimport type { FileMetadataResultStatus } from '../store/uploadProgress';\n\ninterface UploadFilesArgs {\n formData: FormData;\n totalFiles: number;\n /**\n * How many files to upload in parallel — the `concurrentUploadRequests`\n * settings value. Defaults to 1 (sequential).\n */\n concurrency?: number;\n /** Whether AI metadata generation is enabled (EE AI available + `settings.aiMetadata`). */\n generateAiMetadata: boolean;\n /**\n * Called for each file of this call as it finishes uploading, including files\n * a later retry uploads after the call itself has resolved.\n */\n onFileUploaded?: (file: UploadedFile) => void;\n /** Tags the batch's rows in the progress store, see `FileProgress.owner`. */\n owner?: string;\n}\n\ninterface UploadFromUrlsArgs {\n urls: string[];\n folderId: number | null;\n generateAiMetadata: boolean;\n}\n\ninterface RootState {\n admin_app: {\n token?: string | null;\n };\n uploadProgress: {\n uploadId: number;\n files: Array<{\n index: number;\n name: string;\n size: number;\n status: 'pending' | 'uploading' | 'complete' | 'error' | 'cancelled';\n }>;\n };\n}\n\n/**\n * A single file plus the `fileInfo` it was queued with.\n * Retained in {@link uploadRegistry} so cancelled files can be retried without\n * the user re-selecting them. `File`/`AbortController` are non-serializable, so\n * they live here rather than in Redux.\n */\ninterface UploadEntry {\n file: File;\n fileInfo: UploadFileInfo;\n onUploaded?: (file: UploadedFile) => void;\n}\n\n/**\n * Everything a batch needs to be replayed on retry: the original entries plus the\n * flags it was started with (AI-metadata and upload concurrency). These live here\n * rather than in Redux because `retryCancelledFiles` takes no args and the page\n * that owns the settings value is not involved in the retry.\n */\ninterface UploadBatch {\n entries: UploadEntry[];\n generateAiMetadata: boolean;\n concurrency: number;\n}\n\n/**\n * Stores the original upload batch (keyed by uploadId) to enable retry.\n */\nconst uploadRegistry = new Map<number, UploadBatch>();\n\nconst registerUploadEntries = (\n uploadId: number,\n entries: UploadEntry[],\n generateAiMetadata: boolean,\n concurrency: number\n) => {\n uploadRegistry.set(uploadId, { entries, generateAiMetadata, concurrency });\n};\n\nconst getUploadEntries = (uploadId: number): UploadBatch | undefined => {\n return uploadRegistry.get(uploadId);\n};\n\n/**\n * Manages abort controllers for in-flight uploads.\n *\n * Design decision: Uses a Map to track uploads by their unique uploadId.\n * Redux state cannot store function references (abort controllers), RTK Query's\n * signal is only accessible within the queryFn, and the upload is triggered in\n * AssetsPage but cancelled from UploadProgressDialog.\n */\nconst abortControllers = new Map<number, AbortController>();\n\nconst registerAbortController = (uploadId: number, controller: AbortController) => {\n abortControllers.set(uploadId, controller);\n};\n\nconst unregisterAbortController = (uploadId: number) => {\n abortControllers.delete(uploadId);\n};\n\n/**\n * Aborts an upload by its uploadId.\n * Called from the UploadProgressDialog when the user clicks cancel or close.\n */\nexport const abortUpload = (uploadId: number) => {\n const controller = abortControllers.get(uploadId);\n if (controller) {\n controller.abort();\n unregisterAbortController(uploadId);\n }\n};\n\n/**\n * One controller per file in flight, keyed by `uploadId:index`, so a single row\n * can be cancelled without stopping the rest of its batch. Files still queued\n * have no request to abort yet; they are remembered in `skippedFiles` instead\n * and dropped when a worker reaches them.\n */\nconst fileAbortControllers = new Map<string, AbortController>();\nconst skippedFiles = new Set<string>();\n\nconst getFileKey = (uploadId: number, index: number) => `${uploadId}:${index}`;\n\n/**\n * Aborts one file of a batch. Pair it with `cancelFile` to mark the row, the\n * same way `abortUpload` pairs with `cancelUpload`.\n */\nexport const abortUploadFile = (uploadId: number, index: number) => {\n const key = getFileKey(uploadId, index);\n const controller = fileAbortControllers.get(key);\n\n if (controller) {\n controller.abort();\n fileAbortControllers.delete(key);\n return;\n }\n\n skippedFiles.add(key);\n};\n\n/**\n * The file the user picked for a row, kept so it can be previewed while it\n * uploads and replayed on retry.\n */\nexport const getUploadSourceFile = (uploadId: number, index: number): File | undefined =>\n getUploadEntries(uploadId)?.entries[index]?.file;\n\n/**\n * Runs are chained per batch rather than started in parallel: a second pool\n * alongside the first would double the files in flight and make `concurrency`\n * stop meaning anything.\n */\nconst poolTails = new Map<number, Promise<UploadPoolResult | undefined>>();\n\nconst trackPoolRun = (uploadId: number, run: Promise<UploadPoolResult>) => {\n // Not swallowed: the caller still gets the real result from `run`.\n const tail = run.catch(() => undefined);\n\n poolTails.set(uploadId, tail);\n\n tail.then(() => {\n // Leave the entry alone if another run has queued behind us in the meantime.\n if (poolTails.get(uploadId) === tail) {\n poolTails.delete(uploadId);\n }\n });\n};\n\n/**\n * Error shape returned by upload operations.\n * Matches RTK Query's expected return type for queryFn.\n */\ninterface UploadError {\n name: 'UnknownError';\n message: string;\n status?: number;\n}\n\n/**\n * The store's dispatch also accepts thunks, which is what RTK Query's\n * `endpoint.initiate(...)` returns — the plain `Dispatch` action type can't express that.\n */\ntype AppDispatch = Dispatch &\n (<T>(thunk: T) => T extends (...args: never[]) => infer R ? R : never);\n\ntype UploadPoolResult =\n /**\n * `own` is set only by a merged leg: `data` is the whole batch so far, for the\n * next leg to chain from, while `own` is what this call uploaded.\n */\n | { data: UploadedFile[]; own?: UploadedFile[]; error?: undefined }\n | { error: UploadError; data?: undefined; own?: undefined };\n\n/** Maps a server per-file outcome onto the row's terminal metadata status. */\nconst METADATA_STATUS_BY_RESULT: Record<GenerateAIMetadata.FileStatus, FileMetadataResultStatus> = {\n success: 'generated',\n skipped: 'skipped',\n error: 'failed',\n};\n\n/**\n * Re-attaches the folder an upload targeted.\n *\n * The create response is built from `db.query().create()` with no populate, so\n * it comes back without the folder relation it was just given. The list needs\n * it to tell whether a freshly uploaded asset belongs to the folder on screen.\n */\nconst withTargetFolder = (\n file: UploadedFile,\n folder: number | string | null | undefined\n): UploadedFile => (file.folder != null ? file : { ...file, folder: folder ?? null });\n\n/**\n * Kicks off AI metadata generation for a freshly uploaded file.\n *\n * Deliberately fire-and-forget — the caller must NOT await it:\n * - generation for file N overlaps the upload of file N+1;\n * - a generation failure can never affect the upload result (the upload already\n * succeeded), which is why the promise is fully swallowed here.\n *\n * Every uploaded file is sent, including non-images: the server already classifies\n * them (`ai-metadata.generateForFiles` returns `skipped` for anything whose mime\n * isn't `image/*`) and duplicating that rule here would let the two drift apart.\n * The upshot is that a non-image now reports \"Metadata generation skipped\" rather\n * than silently showing no metadata state at all.\n */\nexport const maybeGenerateMetadata = ({\n file,\n index,\n uploadId,\n enabled,\n dispatch,\n}: {\n file: UploadedFile;\n index: number;\n uploadId: number;\n enabled: boolean;\n dispatch: Dispatch;\n}): void => {\n if (!enabled || typeof file.id !== 'number') {\n return;\n }\n\n dispatch(setFileMetadataGenerating({ index, uploadId }));\n\n // `uploadApi` is declared below but only read at call time, long after the module\n // has finished evaluating.\n const promise = (dispatch as AppDispatch)(\n uploadApi.endpoints.generateAiMetadata.initiate({ fileIds: [file.id] })\n );\n\n promise\n .unwrap()\n .then((results) => {\n const result = results?.find((r) => r.id === file.id) ?? results?.[0];\n dispatch(\n setFileMetadataResult({\n index,\n uploadId,\n status: result ? METADATA_STATUS_BY_RESULT[result.status] : 'failed',\n })\n );\n })\n .catch(() => {\n dispatch(setFileMetadataResult({ index, uploadId, status: 'failed' }));\n });\n};\n\n/**\n * Uploads the given entry indices one at a time through the single-file endpoint.\n *\n * For each file: dispatches \"uploading\", wires `XHR.upload.onprogress` through a\n * per-frame batcher to `setFileProgress`, awaits the XHR, then dispatches\n * \"complete\" or \"error\". Each file is wrapped in its own try/catch so one failure\n * does not stop the batch. An abort stops the loop without starting further files.\n */\nconst runUploadPool = async ({\n entries,\n indices,\n token,\n uploadId,\n abortController,\n dispatch,\n concurrency = 1,\n generateAiMetadata,\n}: {\n entries: UploadEntry[];\n indices: number[];\n token: string | null | undefined;\n uploadId: number;\n abortController: AbortController;\n dispatch: Dispatch;\n /** Parallel workers pulling from the queue. 1 (the default) = sequential. */\n concurrency?: number;\n generateAiMetadata: boolean;\n}): Promise<UploadPoolResult> => {\n const url = `${window.strapi.backendURL}/upload/files`;\n const uploaded: UploadedFile[] = [];\n\n // Shared queue: each worker shifts the next index when it frees up, so N\n // files are in flight at any moment (not N-sized waves). With concurrency 1\n // this degenerates to the original strictly sequential loop.\n const queue = [...indices];\n\n const uploadOne = async (index: number) => {\n const entry = entries[index];\n if (!entry) {\n return;\n }\n\n const fileKey = getFileKey(uploadId, index);\n\n if (skippedFiles.delete(fileKey)) {\n return;\n }\n\n const fileName = entry.fileInfo?.name ?? entry.file.name;\n\n dispatch(setFileUploading({ name: fileName, index, size: entry.file.size, uploadId }));\n\n // Aborted by either a per-file cancel or the batch's own Cancel all.\n const fileAbortController = new AbortController();\n const abortFile = () => fileAbortController.abort();\n abortController.signal.addEventListener('abort', abortFile);\n fileAbortControllers.set(fileKey, fileAbortController);\n\n const formData = new FormData();\n formData.append('files', entry.file);\n formData.append('fileInfo', JSON.stringify(entry.fileInfo));\n\n // Coalesce high-frequency progress events into one dispatch per frame.\n const batcher = createRafBatcher<number>((bytes) => {\n dispatch(setFileProgress({ index, bytes, uploadId }));\n });\n\n try {\n const file = await uploadFileViaXHR(\n url,\n token,\n formData,\n fileAbortController.signal,\n (bytes) => batcher.schedule(bytes)\n );\n batcher.cancel();\n uploaded.push(file);\n dispatch(\n setFileComplete({\n index,\n file: withTargetFolder(file, entry.fileInfo?.folder),\n uploadId,\n completedAt: Date.now(),\n })\n );\n entry.onUploaded?.(file);\n\n // Not awaited: overlaps with the next file's upload and can't fail the batch.\n maybeGenerateMetadata({\n file,\n index,\n uploadId,\n enabled: generateAiMetadata,\n dispatch,\n });\n } catch (err) {\n batcher.cancel();\n\n if (err instanceof UploadAbortedError) {\n // Batch or file was cancelled. Whoever cancelled marks the rows\n // (`cancelUpload` / `cancelFile`); a batch abort also stops the workers.\n return;\n }\n\n const message = err instanceof Error ? err.message : 'Upload failed';\n dispatch(setFileError({ index, name: fileName, message, uploadId }));\n } finally {\n abortController.signal.removeEventListener('abort', abortFile);\n fileAbortControllers.delete(fileKey);\n }\n };\n\n // Guard non-finite/invalid values (NaN, Infinity, <1): `Math.floor(NaN)`\n // would propagate through Math.max to `Array.from({ length: NaN })` = zero\n // workers, silently uploading nothing. Anything invalid falls back to 1.\n const requested = Number.isFinite(concurrency) ? Math.floor(concurrency) : 1;\n const workerCount = Math.min(Math.max(1, requested), queue.length);\n\n const worker = async () => {\n while (queue.length > 0) {\n if (abortController.signal.aborted) {\n break;\n }\n\n const index = queue.shift();\n if (index === undefined) {\n break;\n }\n\n // eslint-disable-next-line no-await-in-loop\n await uploadOne(index);\n }\n };\n\n await Promise.all(Array.from({ length: workerCount }, () => worker()));\n\n unregisterAbortController(uploadId);\n\n return { data: uploaded };\n};\n\n/**\n * Reuses the batch's AbortController so one Cancel stops both drops.\n * `runUploadPool` unregisters it on finish, hence the re-register below.\n *\n * Resolves with the whole batch's files, not just this leg's: the mutation\n * models one drop, and after a merge the drop is the batch. The earlier leg's\n * files come from the tail this run queued behind.\n */\nconst runMergedUploadPool = async ({\n entries,\n indices,\n token,\n uploadId,\n dispatch,\n concurrency,\n generateAiMetadata,\n}: {\n entries: UploadEntry[];\n indices: number[];\n token: string | null | undefined;\n uploadId: number;\n dispatch: Dispatch;\n concurrency: number;\n generateAiMetadata: boolean;\n}): Promise<UploadPoolResult> => {\n const abortController = abortControllers.get(uploadId) ?? new AbortController();\n\n const run = (poolTails.get(uploadId) ?? Promise.resolve(undefined)).then(\n (previous): UploadPoolResult | Promise<UploadPoolResult> => {\n // A failed earlier leg contributes no files; its error already reached the\n // store, and this leg still has files of its own to upload.\n const earlier = previous?.data ?? [];\n\n if (abortController.signal.aborted) {\n return { data: earlier, own: [] };\n }\n\n registerAbortController(uploadId, abortController);\n\n return runUploadPool({\n entries,\n indices,\n token,\n uploadId,\n abortController,\n dispatch,\n concurrency,\n generateAiMetadata,\n }).then((result) =>\n result.error\n ? result\n : { data: [...earlier, ...(result.data ?? [])], own: result.data ?? [] }\n );\n }\n );\n\n trackPoolRun(uploadId, run);\n\n // The chained value keeps every file in the batch, because the next merged leg\n // reads it as its own `earlier`. The caller gets only what it handed in: a\n // consumer that attaches the result — the Content Manager field — would\n // otherwise re-attach the files the earlier drop already added.\n return run.then((result) => (result.error ? result : { data: result.own ?? result.data }));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * URL upload flow (SSE) — kept as-is for this iteration\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * Parses a raw SSE text chunk into event/data pairs.\n *\n * SSE format:\n * event: <eventName>\\n\n * data: <json>\\n\n * \\n\n */\nconst parseSSEEvents = (chunk: string): Array<{ event: string; data: string }> => {\n const events: Array<{ event: string; data: string }> = [];\n const blocks = chunk.split('\\n\\n').filter(Boolean);\n\n for (const block of blocks) {\n let event = '';\n let data = '';\n\n for (const line of block.split('\\n')) {\n if (line.startsWith('event: ')) {\n event = line.slice(7);\n } else if (line.startsWith('data: ')) {\n data = line.slice(6);\n }\n }\n\n if (event && data) {\n events.push({ event, data });\n }\n }\n\n return events;\n};\n\n/**\n * Makes a streaming upload-from-URLs request to the server.\n * Sends URLs as JSON body instead of FormData.\n */\nconst fetchUrlUploadStream = async ({\n token,\n urls,\n folderId,\n signal,\n}: {\n token: string | null | undefined;\n urls: string[];\n folderId: number | null;\n signal: AbortSignal;\n}): Promise<Response> => {\n const backendURL = window.strapi.backendURL;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n }\n\n return fetch(`${backendURL}/upload/actions/upload-from-urls`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ urls, folderId }),\n signal,\n });\n};\n\n/**\n * Processes an SSE stream from the URL upload endpoint.\n * Dispatches Redux actions for each file event and returns the final result.\n */\nconst processSSEStream = async ({\n response,\n dispatch,\n uploadId,\n generateAiMetadata,\n folderId,\n}: {\n response: Response;\n dispatch: Dispatch;\n uploadId: number;\n generateAiMetadata: boolean;\n folderId?: number | null;\n}): Promise<CreateFilesStream.Response | null> => {\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let streamResult: CreateFilesStream.Response | null = null;\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete SSE events from the buffer\n const lastDoubleNewline = buffer.lastIndexOf('\\n\\n');\n if (lastDoubleNewline === -1) {\n // No complete events yet, keep buffering\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const completePart = buffer.slice(0, lastDoubleNewline + 2);\n buffer = buffer.slice(lastDoubleNewline + 2);\n\n const events = parseSSEEvents(completePart);\n\n for (const { event, data } of events) {\n const parsed = JSON.parse(data);\n const index = parsed.index as number;\n\n switch (event) {\n case 'file:fetching': {\n // URL is being fetched server-side - mark as uploading (processing)\n dispatch(setFileUploading({ name: parsed.url as string, index, size: 0, uploadId }));\n break;\n }\n case 'file:progress': {\n const payload = parsed as CreateFilesStreamEvents.FileProgressEvent;\n\n // No usable Content-Length on the remote: leave the row indeterminate\n if (payload.totalBytes === null) {\n break;\n }\n\n // Already throttled server-side (~5 frames a second per file), so no batching\n // here. `size` rides along because the row is still at 0 — see `setFileProgress`.\n dispatch(\n setFileProgress({\n index,\n bytes: payload.loadedBytes,\n size: payload.totalBytes,\n uploadId,\n })\n );\n break;\n }\n case 'file:uploading': {\n const payload = parsed as CreateFilesStreamEvents.FileUploadingEvent;\n dispatch(setFileUploading({ name: payload.name, index, size: payload.size, uploadId }));\n break;\n }\n case 'file:complete': {\n const payload = parsed as CreateFilesStreamEvents.FileCompleteEvent;\n dispatch(\n setFileComplete({\n index,\n file: withTargetFolder(payload.file, folderId),\n uploadId,\n completedAt: Date.now(),\n })\n );\n\n // Same fire-and-forget semantics as the file flow.\n maybeGenerateMetadata({\n file: payload.file,\n index,\n uploadId,\n enabled: generateAiMetadata,\n dispatch,\n });\n break;\n }\n case 'file:error': {\n const payload = parsed as CreateFilesStreamEvents.FileErrorEvent;\n dispatch(setFileError({ index, name: payload.name, message: payload.message, uploadId }));\n break;\n }\n case 'stream:complete': {\n const payload = parsed as CreateFilesStreamEvents.StreamCompleteEvent;\n streamResult = {\n data: payload.data,\n errors: payload.errors,\n };\n break;\n }\n default:\n console.error(`[SSE Upload] unknown event: ${event}`, parsed);\n }\n }\n }\n\n return streamResult;\n};\n\nconst uploadApi = adminApi\n .enhanceEndpoints({\n addTagTypes: ['Asset', 'Folder'],\n })\n .injectEndpoints({\n endpoints: (builder) => ({\n /**\n * Upload files to `/upload/files`, one request per file, through a worker\n * pool of `concurrency` parallel requests (default 1 = sequential). Real\n * per-file byte progress comes from `XHR.upload.onprogress`.\n */\n uploadFiles: builder.mutation<UploadedFile[], UploadFilesArgs>({\n queryFn: async (\n { formData, totalFiles, concurrency = 1, generateAiMetadata, onFileUploaded, owner },\n { dispatch, getState }\n ) => {\n const token = (getState() as RootState).admin_app?.token;\n\n // Extract the original files and their per-file fileInfo from the combined FormData.\n const files = formData.getAll('files') as File[];\n const fileInfoJson = formData.get('fileInfo') as string;\n const fileInfoArray = JSON.parse(fileInfoJson) as UploadFileInfo[];\n\n const entries: UploadEntry[] = files.map((file, index) => ({\n file,\n fileInfo: fileInfoArray[index] ?? {\n name: file.name,\n caption: null,\n alternativeText: null,\n folder: null,\n },\n onUploaded: onFileUploaded,\n }));\n\n const fileNames = entries.map((entry) => entry.fileInfo.name ?? entry.file.name);\n const fileSizes = entries.map((entry) => entry.file.size);\n\n // `uploadFromUrls` also leaves rows `pending`, but registers no batch —\n // so an unregistered batch is not ours to merge into, and appending would\n // land on top of its rows.\n const progress = (getState() as RootState).uploadProgress;\n const batch = getUploadEntries(progress.uploadId);\n const isMerge = batch !== undefined && isUploadInFlight(progress.files);\n\n if (isMerge) {\n const { uploadId } = progress;\n const offset = batch.entries.length;\n\n // No `totalFiles`: the reducer derives it from the rows it appends.\n dispatch(appendUploadFiles({ uploadId, fileNames, fileSizes, owner }));\n\n const mergedEntries = [...batch.entries, ...entries];\n\n // Merged files adopt the batch's flags: a new concurrency would raise\n // the ceiling it exists to impose.\n registerUploadEntries(\n uploadId,\n mergedEntries,\n batch.generateAiMetadata,\n batch.concurrency\n );\n\n return runMergedUploadPool({\n entries: mergedEntries,\n indices: entries.map((_, index) => offset + index),\n token,\n uploadId,\n dispatch,\n concurrency: batch.concurrency,\n generateAiMetadata: batch.generateAiMetadata,\n });\n }\n\n // Open the progress dialog\n dispatch(openUploadProgress({ totalFiles, fileNames, fileSizes, owner }));\n\n // Get the uploadId from state after dispatching\n const uploadId = (getState() as RootState).uploadProgress.uploadId;\n\n // Store original entries for retry functionality\n registerUploadEntries(uploadId, entries, generateAiMetadata, concurrency);\n\n // One AbortController per batch\n const abortController = new AbortController();\n registerAbortController(uploadId, abortController);\n\n const run = runUploadPool({\n entries,\n indices: entries.map((_, index) => index),\n token,\n uploadId,\n abortController,\n dispatch,\n concurrency,\n generateAiMetadata,\n });\n\n trackPoolRun(uploadId, run);\n\n return run;\n },\n // `Folder, LIST` refreshes the folder header count, which changes when\n // files are added to it.\n invalidatesTags: [\n { type: 'Asset', id: 'LIST' },\n { type: 'Folder', id: 'LIST' },\n ],\n }),\n\n /**\n * Upload a single, already-prepared file WITHOUT opening the global\n * upload-progress dialog. For flows that create one asset programmatically\n * (e.g. crop → \"Save as copy\"), where the bulk-upload progress UI is\n * inappropriate. Same endpoint as `uploadFiles`, minus the progress/retry\n * machinery.\n */\n uploadFileSilently: builder.mutation<UploadedFile, UploadEntry>({\n queryFn: async ({ file, fileInfo }, { getState }) => {\n const token = (getState() as RootState).admin_app?.token;\n const url = `${window.strapi.backendURL}/upload/files`;\n\n const formData = new FormData();\n formData.append('files', file);\n formData.append('fileInfo', JSON.stringify(fileInfo));\n\n try {\n const uploaded = await uploadFileViaXHR(\n url,\n token,\n formData,\n new AbortController().signal,\n () => {}\n );\n return { data: uploaded };\n } catch (err) {\n // Only pass on text the server actually sent. The XHR layer's own\n // fallbacks are hardcoded English, and callers here (crop → \"Save\n // as copy\") have a localized message of their own; an empty string\n // reads as \"nothing usable\" and lets theirs win.\n const message =\n err instanceof UploadFileError && err.isServerMessage ? err.message : '';\n return { error: { name: 'UnknownError', message } };\n }\n },\n // `Folder, LIST` refreshes the folder header count, which changes when\n // files are added to it.\n invalidatesTags: [\n { type: 'Asset', id: 'LIST' },\n { type: 'Folder', id: 'LIST' },\n ],\n }),\n\n /**\n * Retry uploading cancelled files.\n * Maps cancelled rows back to their original entries and re-runs only those\n * through the same upload pool with a fresh AbortController.\n */\n retryCancelledFiles: builder.mutation<UploadedFile[], void>({\n queryFn: async (_arg, { dispatch, getState }) => {\n const { uploadId, files: stateFiles } = (getState() as RootState).uploadProgress;\n const token = (getState() as RootState).admin_app?.token;\n\n const cancelledIndices = stateFiles\n .filter((f) => f.status === 'cancelled')\n .map((f) => f.index);\n\n if (cancelledIndices.length === 0) {\n return { error: { name: 'UnknownError', message: 'No cancelled files to retry' } };\n }\n\n const batch = getUploadEntries(uploadId);\n if (!batch) {\n return { error: { name: 'UnknownError', message: 'Original files not found' } };\n }\n\n // Reset cancelled files back to pending\n dispatch(retryCancelledFiles());\n\n // Fresh AbortController for the retry run\n const abortController = new AbortController();\n registerAbortController(uploadId, abortController);\n\n const run = runUploadPool({\n entries: batch.entries,\n indices: cancelledIndices,\n token,\n uploadId,\n abortController,\n dispatch,\n // Replay the retried rows with the flags the batch was started with.\n concurrency: batch.concurrency,\n generateAiMetadata: batch.generateAiMetadata,\n });\n\n // Retried rows are `pending` again, so a drop lands on the merge branch.\n // Untracked, that merge would find no tail to queue behind and run its\n // pool beside this one — two pools of `concurrency` each.\n trackPoolRun(uploadId, run);\n\n return run;\n },\n // `Folder, LIST` refreshes the folder header count, which changes when\n // files are added to it.\n invalidatesTags: [\n { type: 'Asset', id: 'LIST' },\n { type: 'Folder', id: 'LIST' },\n ],\n }),\n\n /**\n * Retry one cancelled or failed file of the current batch. Queued behind\n * whatever the batch still has in flight, so `concurrency` keeps holding.\n */\n retryUploadFile: builder.mutation<UploadedFile[], { uploadId: number; index: number }>({\n queryFn: async ({ uploadId, index }, { dispatch, getState }) => {\n const { uploadProgress, admin_app } = getState() as RootState;\n const batch = getUploadEntries(uploadId);\n\n if (uploadId !== uploadProgress.uploadId || !batch || !batch.entries[index]) {\n return { error: { name: 'UnknownError', message: 'Original file not found' } };\n }\n\n skippedFiles.delete(getFileKey(uploadId, index));\n dispatch(retryFile({ uploadId, index }));\n\n return runMergedUploadPool({\n entries: batch.entries,\n indices: [index],\n token: admin_app?.token,\n uploadId,\n dispatch,\n concurrency: batch.concurrency,\n generateAiMetadata: batch.generateAiMetadata,\n });\n },\n invalidatesTags: [\n { type: 'Asset', id: 'LIST' },\n { type: 'Folder', id: 'LIST' },\n ],\n }),\n\n /**\n * Upload files from URLs.\n * Sends URLs to the server which fetches and uploads them (SSE flow, unchanged).\n */\n uploadFromUrls: builder.mutation<CreateFilesStream.Response, UploadFromUrlsArgs>({\n queryFn: async ({ urls, folderId, generateAiMetadata }, { dispatch, getState }) => {\n const token = (getState() as RootState).admin_app?.token;\n\n // Extract filenames from URLs for the progress dialog\n const fileNames = urls.map((url) => getFilenameFromUrl(url));\n\n // Open progress dialog with all URLs as pending files\n dispatch(\n openUploadProgress({\n totalFiles: urls.length,\n fileNames,\n })\n );\n\n // Get the uploadId from state after dispatching\n const uploadId = (getState() as RootState).uploadProgress.uploadId;\n\n // Create abort controller for this upload\n const abortController = new AbortController();\n registerAbortController(uploadId, abortController);\n\n try {\n // Send URLs to server for fetching and uploading\n const response = await fetchUrlUploadStream({\n token,\n urls,\n folderId,\n signal: abortController.signal,\n });\n\n if (!response.ok || !response.body) {\n unregisterAbortController(uploadId);\n\n let errorMessage = 'Upload request failed';\n try {\n const errorData = await response.json();\n if (errorData.error?.message) {\n errorMessage = errorData.error.message;\n } else if (errorData.message) {\n errorMessage = errorData.message;\n }\n } catch {\n errorMessage = `Upload failed with status ${response.status}`;\n }\n\n dispatch(setUploadFailed({ message: errorMessage }));\n\n return {\n error: {\n name: 'UnknownError' as const,\n message: errorMessage,\n status: response.status,\n },\n };\n }\n\n // Process SSE stream from server\n const streamResult = await processSSEStream({\n response,\n dispatch,\n uploadId,\n generateAiMetadata,\n folderId,\n });\n\n unregisterAbortController(uploadId);\n\n if (streamResult && streamResult.data.length > 0) {\n return { data: streamResult };\n }\n\n return { data: { data: [], errors: [] } };\n } catch (err) {\n unregisterAbortController(uploadId);\n\n if (err instanceof DOMException && err.name === 'AbortError') {\n return { error: { name: 'UnknownError' as const, message: 'Upload cancelled' } };\n }\n\n const errorMessage = err instanceof Error ? err.message : 'Network error occurred';\n dispatch(setUploadFailed({ message: errorMessage }));\n\n return {\n error: {\n name: 'UnknownError' as const,\n message: errorMessage,\n },\n };\n }\n },\n // `Folder, LIST` refreshes the folder header count, which changes when\n // files are added to it.\n invalidatesTags: [\n { type: 'Asset', id: 'LIST' },\n { type: 'Folder', id: 'LIST' },\n ],\n }),\n\n /**\n * Generate AI metadata (alt text + caption) for the given assets.\n * Synchronous: resolves once every file has been processed and reports the\n * outcome per file, so non-images and individual failures don't fail the\n * whole batch. Existing alt text and captions are never overwritten.\n *\n * Lives here rather than in `assets.ts` because the upload flows dispatch it\n * directly via `initiate()` after each file completes, and `assets.ts` already\n * imports from this module — defining it there would be a circular import.\n * Re-exported from `assets.ts` for the components that consume the hook.\n */\n generateAiMetadata: builder.mutation<\n GenerateAIMetadata.Response['data'],\n { fileIds: number[] }\n >({\n query: ({ fileIds }) => ({\n url: '/upload/actions/generate-ai-metadata',\n method: 'POST',\n data: { fileIds },\n }),\n transformResponse: (response: { data: GenerateAIMetadata.Response['data'] }) =>\n response.data,\n invalidatesTags: (_result, _error, { fileIds }) => [\n ...fileIds.map((id) => ({ type: 'Asset' as const, id })),\n { type: 'Asset' as const, id: 'LIST' },\n ],\n }),\n }),\n });\n\nexport const {\n useUploadFilesMutation,\n useUploadFileSilentlyMutation,\n useRetryCancelledFilesMutation,\n useRetryUploadFileMutation,\n useUploadFromUrlsMutation,\n useGenerateAiMetadataMutation,\n} = uploadApi;\nexport { uploadApi };\n"],"names":["uploadRegistry","Map","registerUploadEntries","uploadId","entries","generateAiMetadata","concurrency","set","getUploadEntries","get","abortControllers","registerAbortController","controller","unregisterAbortController","delete","abortUpload","abort","fileAbortControllers","skippedFiles","Set","getFileKey","index","abortUploadFile","key","add","getUploadSourceFile","file","poolTails","trackPoolRun","run","tail","catch","undefined","then","METADATA_STATUS_BY_RESULT","success","skipped","error","withTargetFolder","folder","maybeGenerateMetadata","enabled","dispatch","id","setFileMetadataGenerating","promise","uploadApi","endpoints","initiate","fileIds","unwrap","results","result","find","r","setFileMetadataResult","status","runUploadPool","indices","token","abortController","url","window","strapi","backendURL","uploaded","queue","uploadOne","entry","fileKey","fileName","fileInfo","name","setFileUploading","size","fileAbortController","AbortController","abortFile","signal","addEventListener","formData","FormData","append","JSON","stringify","batcher","createRafBatcher","bytes","setFileProgress","uploadFileViaXHR","schedule","cancel","push","setFileComplete","completedAt","Date","now","onUploaded","err","UploadAbortedError","message","Error","setFileError","removeEventListener","requested","Number","isFinite","Math","floor","workerCount","min","max","length","worker","aborted","shift","Promise","all","Array","from","data","runMergedUploadPool","resolve","previous","earlier","own","parseSSEEvents","chunk","events","blocks","split","filter","Boolean","block","event","line","startsWith","slice","fetchUrlUploadStream","urls","folderId","headers","Authorization","fetch","method","body","processSSEStream","response","reader","getReader","decoder","TextDecoder","streamResult","buffer","done","value","read","decode","stream","lastDoubleNewline","lastIndexOf","completePart","parsed","parse","payload","totalBytes","loadedBytes","errors","console","adminApi","enhanceEndpoints","addTagTypes","injectEndpoints","builder","uploadFiles","mutation","queryFn","totalFiles","onFileUploaded","owner","getState","admin_app","files","getAll","fileInfoJson","fileInfoArray","map","caption","alternativeText","fileNames","fileSizes","progress","uploadProgress","batch","isMerge","isUploadInFlight","offset","appendUploadFiles","mergedEntries","_","openUploadProgress","invalidatesTags","type","uploadFileSilently","UploadFileError","isServerMessage","retryCancelledFiles","_arg","stateFiles","cancelledIndices","f","retryUploadFile","retryFile","uploadFromUrls","getFilenameFromUrl","ok","errorMessage","errorData","json","setUploadFailed","DOMException","query","transformResponse","_result","_error","useUploadFilesMutation","useUploadFileSilentlyMutation","useRetryCancelledFilesMutation","useRetryUploadFileMutation","useUploadFromUrlsMutation","useGenerateAiMetadataMutation"],"mappings":";;;;;;AA+FA;;IAGA,MAAMA,iBAAiB,IAAIC,GAAAA,EAAAA;AAE3B,MAAMC,qBAAAA,GAAwB,CAC5BC,QAAAA,EACAC,OAAAA,EACAC,kBAAAA,EACAC,WAAAA,GAAAA;IAEAN,cAAAA,CAAeO,GAAG,CAACJ,QAAAA,EAAU;AAAEC,QAAAA,OAAAA;AAASC,QAAAA,kBAAAA;AAAoBC,QAAAA;AAAY,KAAA,CAAA;AAC1E,CAAA;AAEA,MAAME,mBAAmB,CAACL,QAAAA,GAAAA;IACxB,OAAOH,cAAAA,CAAeS,GAAG,CAACN,QAAAA,CAAAA;AAC5B,CAAA;AAEA;;;;;;;IAQA,MAAMO,mBAAmB,IAAIT,GAAAA,EAAAA;AAE7B,MAAMU,uBAAAA,GAA0B,CAACR,QAAAA,EAAkBS,UAAAA,GAAAA;IACjDF,gBAAAA,CAAiBH,GAAG,CAACJ,QAAAA,EAAUS,UAAAA,CAAAA;AACjC,CAAA;AAEA,MAAMC,4BAA4B,CAACV,QAAAA,GAAAA;AACjCO,IAAAA,gBAAAA,CAAiBI,MAAM,CAACX,QAAAA,CAAAA;AAC1B,CAAA;AAEA;;;IAIO,MAAMY,WAAAA,GAAc,CAACZ,QAAAA,GAAAA;IAC1B,MAAMS,UAAAA,GAAaF,gBAAAA,CAAiBD,GAAG,CAACN,QAAAA,CAAAA;AACxC,IAAA,IAAIS,UAAAA,EAAY;AACdA,QAAAA,UAAAA,CAAWI,KAAK,EAAA;QAChBH,yBAAAA,CAA0BV,QAAAA,CAAAA;AAC5B,IAAA;AACF;AAEA;;;;;IAMA,MAAMc,uBAAuB,IAAIhB,GAAAA,EAAAA;AACjC,MAAMiB,eAAe,IAAIC,GAAAA,EAAAA;AAEzB,MAAMC,UAAAA,GAAa,CAACjB,QAAAA,EAAkBkB,KAAAA,GAAkB,GAAGlB,QAAAA,CAAS,CAAC,EAAEkB,KAAAA,CAAAA,CAAO;AAE9E;;;AAGC,IACM,MAAMC,eAAAA,GAAkB,CAACnB,QAAAA,EAAkBkB,KAAAA,GAAAA;IAChD,MAAME,GAAAA,GAAMH,WAAWjB,QAAAA,EAAUkB,KAAAA,CAAAA;IACjC,MAAMT,UAAAA,GAAaK,oBAAAA,CAAqBR,GAAG,CAACc,GAAAA,CAAAA;AAE5C,IAAA,IAAIX,UAAAA,EAAY;AACdA,QAAAA,UAAAA,CAAWI,KAAK,EAAA;AAChBC,QAAAA,oBAAAA,CAAqBH,MAAM,CAACS,GAAAA,CAAAA;AAC5B,QAAA;AACF,IAAA;AAEAL,IAAAA,YAAAA,CAAaM,GAAG,CAACD,GAAAA,CAAAA;AACnB;AAEA;;;AAGC,IACM,MAAME,mBAAAA,GAAsB,CAACtB,QAAAA,EAAkBkB,KAAAA,GACpDb,gBAAAA,CAAiBL,QAAAA,CAAAA,EAAWC,OAAO,CAACiB,KAAAA,CAAM,EAAEK;AAE9C;;;;IAKA,MAAMC,YAAY,IAAI1B,GAAAA,EAAAA;AAEtB,MAAM2B,YAAAA,GAAe,CAACzB,QAAAA,EAAkB0B,GAAAA,GAAAA;;AAEtC,IAAA,MAAMC,IAAAA,GAAOD,GAAAA,CAAIE,KAAK,CAAC,IAAMC,SAAAA,CAAAA;IAE7BL,SAAAA,CAAUpB,GAAG,CAACJ,QAAAA,EAAU2B,IAAAA,CAAAA;AAExBA,IAAAA,IAAAA,CAAKG,IAAI,CAAC,IAAA;;AAER,QAAA,IAAIN,SAAAA,CAAUlB,GAAG,CAACN,QAAAA,CAAAA,KAAc2B,IAAAA,EAAM;AACpCH,YAAAA,SAAAA,CAAUb,MAAM,CAACX,QAAAA,CAAAA;AACnB,QAAA;AACF,IAAA,CAAA,CAAA;AACF,CAAA;AA2BA,+EACA,MAAM+B,yBAAAA,GAA6F;IACjGC,OAAAA,EAAS,WAAA;IACTC,OAAAA,EAAS,SAAA;IACTC,KAAAA,EAAO;AACT,CAAA;AAEA;;;;;;IAOA,MAAMC,mBAAmB,CACvBZ,IAAAA,EACAa,SACkBb,IAAAA,CAAKa,MAAM,IAAI,IAAA,GAAOb,IAAAA,GAAO;AAAE,QAAA,GAAGA,IAAI;AAAEa,QAAAA,MAAAA,EAAQA,MAAAA,IAAU;AAAK,KAAA;AAEnF;;;;;;;;;;;;;AAaC,IACM,MAAMC,qBAAAA,GAAwB,CAAC,EACpCd,IAAI,EACJL,KAAK,EACLlB,QAAQ,EACRsC,OAAO,EACPC,QAAQ,EAOT,GAAA;AACC,IAAA,IAAI,CAACD,OAAAA,IAAW,OAAOf,IAAAA,CAAKiB,EAAE,KAAK,QAAA,EAAU;AAC3C,QAAA;AACF,IAAA;AAEAD,IAAAA,QAAAA,CAASE,yBAAAA,CAA0B;AAAEvB,QAAAA,KAAAA;AAAOlB,QAAAA;AAAS,KAAA,CAAA,CAAA;;;IAIrD,MAAM0C,OAAAA,GAAU,QAACH,CACfI,SAAAA,CAAUC,SAAS,CAAC1C,kBAAkB,CAAC2C,QAAQ,CAAC;QAAEC,OAAAA,EAAS;AAACvB,YAAAA,IAAAA,CAAKiB;AAAG;AAAC,KAAA,CAAA,CAAA;AAGvEE,IAAAA,OAAAA,CACGK,MAAM,EAAA,CACNjB,IAAI,CAAC,CAACkB,OAAAA,GAAAA;AACL,QAAA,MAAMC,MAAAA,GAASD,OAAAA,EAASE,IAAAA,CAAK,CAACC,CAAAA,GAAMA,CAAAA,CAAEX,EAAE,KAAKjB,IAAAA,CAAKiB,EAAE,CAAA,IAAKQ,OAAAA,GAAU,CAAA,CAAE;AACrET,QAAAA,QAAAA,CACEa,qBAAAA,CAAsB;AACpBlC,YAAAA,KAAAA;AACAlB,YAAAA,QAAAA;AACAqD,YAAAA,MAAAA,EAAQJ,SAASlB,yBAAyB,CAACkB,MAAAA,CAAOI,MAAM,CAAC,GAAG;AAC9D,SAAA,CAAA,CAAA;AAEJ,IAAA,CAAA,CAAA,CACCzB,KAAK,CAAC,IAAA;AACLW,QAAAA,QAAAA,CAASa,qBAAAA,CAAsB;AAAElC,YAAAA,KAAAA;AAAOlB,YAAAA,QAAAA;YAAUqD,MAAAA,EAAQ;AAAS,SAAA,CAAA,CAAA;AACrE,IAAA,CAAA,CAAA;AACJ;AAEA;;;;;;;IAQA,MAAMC,gBAAgB,OAAO,EAC3BrD,OAAO,EACPsD,OAAO,EACPC,KAAK,EACLxD,QAAQ,EACRyD,eAAe,EACflB,QAAQ,EACRpC,cAAc,CAAC,EACfD,kBAAkB,EAWnB,GAAA;IACC,MAAMwD,GAAAA,GAAM,GAAGC,MAAAA,CAAOC,MAAM,CAACC,UAAU,CAAC,aAAa,CAAC;AACtD,IAAA,MAAMC,WAA2B,EAAE;;;;AAKnC,IAAA,MAAMC,KAAAA,GAAQ;AAAIR,QAAAA,GAAAA;AAAQ,KAAA;AAE1B,IAAA,MAAMS,YAAY,OAAO9C,KAAAA,GAAAA;QACvB,MAAM+C,KAAAA,GAAQhE,OAAO,CAACiB,KAAAA,CAAM;AAC5B,QAAA,IAAI,CAAC+C,KAAAA,EAAO;AACV,YAAA;AACF,QAAA;QAEA,MAAMC,OAAAA,GAAUjD,WAAWjB,QAAAA,EAAUkB,KAAAA,CAAAA;QAErC,IAAIH,YAAAA,CAAaJ,MAAM,CAACuD,OAAAA,CAAAA,EAAU;AAChC,YAAA;AACF,QAAA;QAEA,MAAMC,QAAAA,GAAWF,MAAMG,QAAQ,EAAEC,QAAQJ,KAAAA,CAAM1C,IAAI,CAAC8C,IAAI;AAExD9B,QAAAA,QAAAA,CAAS+B,gBAAAA,CAAiB;YAAED,IAAAA,EAAMF,QAAAA;AAAUjD,YAAAA,KAAAA;YAAOqD,IAAAA,EAAMN,KAAAA,CAAM1C,IAAI,CAACgD,IAAI;AAAEvE,YAAAA;AAAS,SAAA,CAAA,CAAA;;AAGnF,QAAA,MAAMwE,sBAAsB,IAAIC,eAAAA,EAAAA;QAChC,MAAMC,SAAAA,GAAY,IAAMF,mBAAAA,CAAoB3D,KAAK,EAAA;AACjD4C,QAAAA,eAAAA,CAAgBkB,MAAM,CAACC,gBAAgB,CAAC,OAAA,EAASF,SAAAA,CAAAA;QACjD5D,oBAAAA,CAAqBV,GAAG,CAAC8D,OAAAA,EAASM,mBAAAA,CAAAA;AAElC,QAAA,MAAMK,WAAW,IAAIC,QAAAA,EAAAA;AACrBD,QAAAA,QAAAA,CAASE,MAAM,CAAC,OAAA,EAASd,KAAAA,CAAM1C,IAAI,CAAA;AACnCsD,QAAAA,QAAAA,CAASE,MAAM,CAAC,UAAA,EAAYC,KAAKC,SAAS,CAAChB,MAAMG,QAAQ,CAAA,CAAA;;QAGzD,MAAMc,OAAAA,GAAUC,iBAAyB,CAACC,KAAAA,GAAAA;AACxC7C,YAAAA,QAAAA,CAAS8C,eAAAA,CAAgB;AAAEnE,gBAAAA,KAAAA;AAAOkE,gBAAAA,KAAAA;AAAOpF,gBAAAA;AAAS,aAAA,CAAA,CAAA;AACpD,QAAA,CAAA,CAAA;QAEA,IAAI;AACF,YAAA,MAAMuB,IAAAA,GAAO,MAAM+D,gBAAAA,CACjB5B,GAAAA,EACAF,KAAAA,EACAqB,QAAAA,EACAL,mBAAAA,CAAoBG,MAAM,EAC1B,CAACS,KAAAA,GAAUF,OAAAA,CAAQK,QAAQ,CAACH,KAAAA,CAAAA,CAAAA;AAE9BF,YAAAA,OAAAA,CAAQM,MAAM,EAAA;AACd1B,YAAAA,QAAAA,CAAS2B,IAAI,CAAClE,IAAAA,CAAAA;AACdgB,YAAAA,QAAAA,CACEmD,eAAAA,CAAgB;AACdxE,gBAAAA,KAAAA;AACAK,gBAAAA,IAAAA,EAAMY,gBAAAA,CAAiBZ,IAAAA,EAAM0C,KAAAA,CAAMG,QAAQ,EAAEhC,MAAAA,CAAAA;AAC7CpC,gBAAAA,QAAAA;AACA2F,gBAAAA,WAAAA,EAAaC,KAAKC,GAAG;AACvB,aAAA,CAAA,CAAA;AAEF5B,YAAAA,KAAAA,CAAM6B,UAAU,GAAGvE,IAAAA,CAAAA;;YAGnBc,qBAAAA,CAAsB;AACpBd,gBAAAA,IAAAA;AACAL,gBAAAA,KAAAA;AACAlB,gBAAAA,QAAAA;gBACAsC,OAAAA,EAASpC,kBAAAA;AACTqC,gBAAAA;AACF,aAAA,CAAA;AACF,QAAA,CAAA,CAAE,OAAOwD,GAAAA,EAAK;AACZb,YAAAA,OAAAA,CAAQM,MAAM,EAAA;AAEd,YAAA,IAAIO,eAAeC,kBAAAA,EAAoB;;;AAGrC,gBAAA;AACF,YAAA;AAEA,YAAA,MAAMC,OAAAA,GAAUF,GAAAA,YAAeG,KAAAA,GAAQH,GAAAA,CAAIE,OAAO,GAAG,eAAA;AACrD1D,YAAAA,QAAAA,CAAS4D,YAAAA,CAAa;AAAEjF,gBAAAA,KAAAA;gBAAOmD,IAAAA,EAAMF,QAAAA;AAAU8B,gBAAAA,OAAAA;AAASjG,gBAAAA;AAAS,aAAA,CAAA,CAAA;QACnE,CAAA,QAAU;AACRyD,YAAAA,eAAAA,CAAgBkB,MAAM,CAACyB,mBAAmB,CAAC,OAAA,EAAS1B,SAAAA,CAAAA;AACpD5D,YAAAA,oBAAAA,CAAqBH,MAAM,CAACuD,OAAAA,CAAAA;AAC9B,QAAA;AACF,IAAA,CAAA;;;;IAKA,MAAMmC,SAAAA,GAAYC,OAAOC,QAAQ,CAACpG,eAAeqG,IAAAA,CAAKC,KAAK,CAACtG,WAAAA,CAAAA,GAAe,CAAA;IAC3E,MAAMuG,WAAAA,GAAcF,IAAAA,CAAKG,GAAG,CAACH,IAAAA,CAAKI,GAAG,CAAC,CAAA,EAAGP,SAAAA,CAAAA,EAAYtC,KAAAA,CAAM8C,MAAM,CAAA;AAEjE,IAAA,MAAMC,MAAAA,GAAS,UAAA;QACb,MAAO/C,KAAAA,CAAM8C,MAAM,GAAG,CAAA,CAAG;AACvB,YAAA,IAAIpD,eAAAA,CAAgBkB,MAAM,CAACoC,OAAO,EAAE;AAClC,gBAAA;AACF,YAAA;YAEA,MAAM7F,KAAAA,GAAQ6C,MAAMiD,KAAK,EAAA;AACzB,YAAA,IAAI9F,UAAUW,SAAAA,EAAW;AACvB,gBAAA;AACF,YAAA;;AAGA,YAAA,MAAMmC,SAAAA,CAAU9C,KAAAA,CAAAA;AAClB,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAM+F,OAAAA,CAAQC,GAAG,CAACC,KAAAA,CAAMC,IAAI,CAAC;QAAEP,MAAAA,EAAQH;AAAY,KAAA,EAAG,IAAMI,MAAAA,EAAAA,CAAAA,CAAAA;IAE5DpG,yBAAAA,CAA0BV,QAAAA,CAAAA;IAE1B,OAAO;QAAEqH,IAAAA,EAAMvD;AAAS,KAAA;AAC1B,CAAA;AAEA;;;;;;;AAOC,IACD,MAAMwD,mBAAAA,GAAsB,OAAO,EACjCrH,OAAO,EACPsD,OAAO,EACPC,KAAK,EACLxD,QAAQ,EACRuC,QAAQ,EACRpC,WAAW,EACXD,kBAAkB,EASnB,GAAA;AACC,IAAA,MAAMuD,eAAAA,GAAkBlD,gBAAAA,CAAiBD,GAAG,CAACN,aAAa,IAAIyE,eAAAA,EAAAA;AAE9D,IAAA,MAAM/C,GAAAA,GAAOF,CAAAA,SAAAA,CAAUlB,GAAG,CAACN,QAAAA,CAAAA,IAAaiH,OAAAA,CAAQM,OAAO,CAAC1F,SAAAA,CAAS,EAAGC,IAAI,CACtE,CAAC0F,QAAAA,GAAAA;;;QAGC,MAAMC,OAAAA,GAAUD,QAAAA,EAAUH,IAAAA,IAAQ,EAAE;AAEpC,QAAA,IAAI5D,eAAAA,CAAgBkB,MAAM,CAACoC,OAAO,EAAE;YAClC,OAAO;gBAAEM,IAAAA,EAAMI,OAAAA;AAASC,gBAAAA,GAAAA,EAAK;AAAG,aAAA;AAClC,QAAA;AAEAlH,QAAAA,uBAAAA,CAAwBR,QAAAA,EAAUyD,eAAAA,CAAAA;AAElC,QAAA,OAAOH,aAAAA,CAAc;AACnBrD,YAAAA,OAAAA;AACAsD,YAAAA,OAAAA;AACAC,YAAAA,KAAAA;AACAxD,YAAAA,QAAAA;AACAyD,YAAAA,eAAAA;AACAlB,YAAAA,QAAAA;AACApC,YAAAA,WAAAA;AACAD,YAAAA;AACF,SAAA,CAAA,CAAG4B,IAAI,CAAC,CAACmB,SACPA,MAAAA,CAAOf,KAAK,GACRe,MAAAA,GACA;gBAAEoE,IAAAA,EAAM;AAAII,oBAAAA,GAAAA,OAAAA;uBAAaxE,MAAAA,CAAOoE,IAAI,IAAI;AAAI,iBAAA;gBAAEK,GAAAA,EAAKzE,MAAAA,CAAOoE,IAAI,IAAI;AAAG,aAAA,CAAA;AAE7E,IAAA,CAAA,CAAA;AAGF5F,IAAAA,YAAAA,CAAazB,QAAAA,EAAU0B,GAAAA,CAAAA;;;;;IAMvB,OAAOA,GAAAA,CAAII,IAAI,CAAC,CAACmB,SAAYA,MAAAA,CAAOf,KAAK,GAAGe,MAAAA,GAAS;AAAEoE,YAAAA,IAAAA,EAAMpE,MAAAA,CAAOyE,GAAG,IAAIzE,MAAAA,CAAOoE;AAAK,SAAA,CAAA;AACzF,CAAA;AAEA;;;;;;;;;IAYA,MAAMM,iBAAiB,CAACC,KAAAA,GAAAA;AACtB,IAAA,MAAMC,SAAiD,EAAE;AACzD,IAAA,MAAMC,SAASF,KAAAA,CAAMG,KAAK,CAAC,MAAA,CAAA,CAAQC,MAAM,CAACC,OAAAA,CAAAA;IAE1C,KAAK,MAAMC,SAASJ,MAAAA,CAAQ;AAC1B,QAAA,IAAIK,KAAAA,GAAQ,EAAA;AACZ,QAAA,IAAId,IAAAA,GAAO,EAAA;AAEX,QAAA,KAAK,MAAMe,IAAAA,IAAQF,KAAAA,CAAMH,KAAK,CAAC,IAAA,CAAA,CAAO;YACpC,IAAIK,IAAAA,CAAKC,UAAU,CAAC,SAAA,CAAA,EAAY;gBAC9BF,KAAAA,GAAQC,IAAAA,CAAKE,KAAK,CAAC,CAAA,CAAA;AACrB,YAAA,CAAA,MAAO,IAAIF,IAAAA,CAAKC,UAAU,CAAC,QAAA,CAAA,EAAW;gBACpChB,IAAAA,GAAOe,IAAAA,CAAKE,KAAK,CAAC,CAAA,CAAA;AACpB,YAAA;AACF,QAAA;AAEA,QAAA,IAAIH,SAASd,IAAAA,EAAM;AACjBQ,YAAAA,MAAAA,CAAOpC,IAAI,CAAC;AAAE0C,gBAAAA,KAAAA;AAAOd,gBAAAA;AAAK,aAAA,CAAA;AAC5B,QAAA;AACF,IAAA;IAEA,OAAOQ,MAAAA;AACT,CAAA;AAEA;;;IAIA,MAAMU,oBAAAA,GAAuB,OAAO,EAClC/E,KAAK,EACLgF,IAAI,EACJC,QAAQ,EACR9D,MAAM,EAMP,GAAA;AACC,IAAA,MAAMd,UAAAA,GAAaF,MAAAA,CAAOC,MAAM,CAACC,UAAU;AAC3C,IAAA,MAAM6E,OAAAA,GAAkC;QACtC,cAAA,EAAgB;AAClB,KAAA;AACA,IAAA,IAAIlF,KAAAA,EAAO;AACTkF,QAAAA,OAAAA,CAAQC,aAAa,GAAG,CAAC,OAAO,EAAEnF,KAAAA,CAAAA,CAAO;AAC3C,IAAA;AAEA,IAAA,OAAOoF,KAAAA,CAAM,CAAA,EAAG/E,UAAAA,CAAW,gCAAgC,CAAC,EAAE;QAC5DgF,MAAAA,EAAQ,MAAA;AACRH,QAAAA,OAAAA;QACAI,IAAAA,EAAM9D,IAAAA,CAAKC,SAAS,CAAC;AAAEuD,YAAAA,IAAAA;AAAMC,YAAAA;AAAS,SAAA,CAAA;AACtC9D,QAAAA;AACF,KAAA,CAAA;AACF,CAAA;AAEA;;;AAGC,IACD,MAAMoE,gBAAAA,GAAmB,OAAO,EAC9BC,QAAQ,EACRzG,QAAQ,EACRvC,QAAQ,EACRE,kBAAkB,EAClBuI,QAAQ,EAOT,GAAA;AACC,IAAA,MAAMQ,MAAAA,GAASD,QAAAA,CAASF,IAAI,CAAEI,SAAS,EAAA;AACvC,IAAA,MAAMC,UAAU,IAAIC,WAAAA,EAAAA;AACpB,IAAA,IAAIC,YAAAA,GAAkD,IAAA;AACtD,IAAA,IAAIC,MAAAA,GAAS,EAAA;AAEb,IAAA,MAAO,IAAA,CAAM;QACX,MAAM,EAAEC,IAAI,EAAEC,KAAK,EAAE,GAAG,MAAMP,OAAOQ,IAAI,EAAA;AAEzC,QAAA,IAAIF,IAAAA,EAAM;AACR,YAAA;AACF,QAAA;QAEAD,MAAAA,IAAUH,OAAAA,CAAQO,MAAM,CAACF,KAAAA,EAAO;YAAEG,MAAAA,EAAQ;AAAK,SAAA,CAAA;;QAG/C,MAAMC,iBAAAA,GAAoBN,MAAAA,CAAOO,WAAW,CAAC,MAAA,CAAA;QAC7C,IAAID,iBAAAA,KAAsB,EAAC,EAAG;AAG5B,YAAA;AACF,QAAA;AAEA,QAAA,MAAME,YAAAA,GAAeR,MAAAA,CAAOhB,KAAK,CAAC,GAAGsB,iBAAAA,GAAoB,CAAA,CAAA;QACzDN,MAAAA,GAASA,MAAAA,CAAOhB,KAAK,CAACsB,iBAAAA,GAAoB,CAAA,CAAA;AAE1C,QAAA,MAAM/B,SAASF,cAAAA,CAAemC,YAAAA,CAAAA;AAE9B,QAAA,KAAK,MAAM,EAAE3B,KAAK,EAAEd,IAAI,EAAE,IAAIQ,MAAAA,CAAQ;YACpC,MAAMkC,MAAAA,GAAS/E,IAAAA,CAAKgF,KAAK,CAAC3C,IAAAA,CAAAA;YAC1B,MAAMnG,KAAAA,GAAQ6I,OAAO7I,KAAK;YAE1B,OAAQiH,KAAAA;gBACN,KAAK,eAAA;AAAiB,oBAAA;;AAEpB5F,wBAAAA,QAAAA,CAAS+B,gBAAAA,CAAiB;AAAED,4BAAAA,IAAAA,EAAM0F,OAAOrG,GAAG;AAAYxC,4BAAAA,KAAAA;4BAAOqD,IAAAA,EAAM,CAAA;AAAGvE,4BAAAA;AAAS,yBAAA,CAAA,CAAA;AACjF,wBAAA;AACF,oBAAA;gBACA,KAAK,eAAA;AAAiB,oBAAA;AACpB,wBAAA,MAAMiK,OAAAA,GAAUF,MAAAA;;wBAGhB,IAAIE,OAAAA,CAAQC,UAAU,KAAK,IAAA,EAAM;AAC/B,4BAAA;AACF,wBAAA;;;AAIA3H,wBAAAA,QAAAA,CACE8C,eAAAA,CAAgB;AACdnE,4BAAAA,KAAAA;AACAkE,4BAAAA,KAAAA,EAAO6E,QAAQE,WAAW;AAC1B5F,4BAAAA,IAAAA,EAAM0F,QAAQC,UAAU;AACxBlK,4BAAAA;AACF,yBAAA,CAAA,CAAA;AAEF,wBAAA;AACF,oBAAA;gBACA,KAAK,gBAAA;AAAkB,oBAAA;AACrB,wBAAA,MAAMiK,OAAAA,GAAUF,MAAAA;AAChBxH,wBAAAA,QAAAA,CAAS+B,gBAAAA,CAAiB;AAAED,4BAAAA,IAAAA,EAAM4F,QAAQ5F,IAAI;AAAEnD,4BAAAA,KAAAA;AAAOqD,4BAAAA,IAAAA,EAAM0F,QAAQ1F,IAAI;AAAEvE,4BAAAA;AAAS,yBAAA,CAAA,CAAA;AACpF,wBAAA;AACF,oBAAA;gBACA,KAAK,eAAA;AAAiB,oBAAA;AACpB,wBAAA,MAAMiK,OAAAA,GAAUF,MAAAA;AAChBxH,wBAAAA,QAAAA,CACEmD,eAAAA,CAAgB;AACdxE,4BAAAA,KAAAA;4BACAK,IAAAA,EAAMY,gBAAAA,CAAiB8H,OAAAA,CAAQ1I,IAAI,EAAEkH,QAAAA,CAAAA;AACrCzI,4BAAAA,QAAAA;AACA2F,4BAAAA,WAAAA,EAAaC,KAAKC,GAAG;AACvB,yBAAA,CAAA,CAAA;;wBAIFxD,qBAAAA,CAAsB;AACpBd,4BAAAA,IAAAA,EAAM0I,QAAQ1I,IAAI;AAClBL,4BAAAA,KAAAA;AACAlB,4BAAAA,QAAAA;4BACAsC,OAAAA,EAASpC,kBAAAA;AACTqC,4BAAAA;AACF,yBAAA,CAAA;AACA,wBAAA;AACF,oBAAA;gBACA,KAAK,YAAA;AAAc,oBAAA;AACjB,wBAAA,MAAM0H,OAAAA,GAAUF,MAAAA;AAChBxH,wBAAAA,QAAAA,CAAS4D,YAAAA,CAAa;AAAEjF,4BAAAA,KAAAA;AAAOmD,4BAAAA,IAAAA,EAAM4F,QAAQ5F,IAAI;AAAE4B,4BAAAA,OAAAA,EAASgE,QAAQhE,OAAO;AAAEjG,4BAAAA;AAAS,yBAAA,CAAA,CAAA;AACtF,wBAAA;AACF,oBAAA;gBACA,KAAK,iBAAA;AAAmB,oBAAA;AACtB,wBAAA,MAAMiK,OAAAA,GAAUF,MAAAA;wBAChBV,YAAAA,GAAe;AACbhC,4BAAAA,IAAAA,EAAM4C,QAAQ5C,IAAI;AAClB+C,4BAAAA,MAAAA,EAAQH,QAAQG;AAClB,yBAAA;AACA,wBAAA;AACF,oBAAA;AACA,gBAAA;AACEC,oBAAAA,OAAAA,CAAQnI,KAAK,CAAC,CAAC,4BAA4B,EAAEiG,OAAO,EAAE4B,MAAAA,CAAAA;AAC1D;AACF,QAAA;AACF,IAAA;IAEA,OAAOV,YAAAA;AACT,CAAA;AAEA,MAAM1G,SAAAA,GAAY2H,QAAAA,CACfC,gBAAgB,CAAC;IAChBC,WAAAA,EAAa;AAAC,QAAA,OAAA;AAAS,QAAA;AAAS;AAClC,CAAA,CAAA,CACCC,eAAe,CAAC;IACf7H,SAAAA,EAAW,CAAC8H,WAAa;AACvB;;;;UAKAC,WAAAA,EAAaD,OAAAA,CAAQE,QAAQ,CAAkC;gBAC7DC,OAAAA,EAAS,OACP,EAAEhG,QAAQ,EAAEiG,UAAU,EAAE3K,WAAAA,GAAc,CAAC,EAAED,kBAAkB,EAAE6K,cAAc,EAAEC,KAAK,EAAE,EACpF,EAAEzI,QAAQ,EAAE0I,QAAQ,EAAE,GAAA;AAEtB,oBAAA,MAAMzH,KAAAA,GAASyH,QAAAA,EAAAA,CAAyBC,SAAS,EAAE1H,KAAAA;;oBAGnD,MAAM2H,KAAAA,GAAQtG,QAAAA,CAASuG,MAAM,CAAC,OAAA,CAAA;oBAC9B,MAAMC,YAAAA,GAAexG,QAAAA,CAASvE,GAAG,CAAC,UAAA,CAAA;oBAClC,MAAMgL,aAAAA,GAAgBtG,IAAAA,CAAKgF,KAAK,CAACqB,YAAAA,CAAAA;AAEjC,oBAAA,MAAMpL,UAAyBkL,KAAAA,CAAMI,GAAG,CAAC,CAAChK,IAAAA,EAAML,SAAW;AACzDK,4BAAAA,IAAAA;4BACA6C,QAAAA,EAAUkH,aAAa,CAACpK,KAAAA,CAAM,IAAI;AAChCmD,gCAAAA,IAAAA,EAAM9C,KAAK8C,IAAI;gCACfmH,OAAAA,EAAS,IAAA;gCACTC,eAAAA,EAAiB,IAAA;gCACjBrJ,MAAAA,EAAQ;AACV,6BAAA;4BACA0D,UAAAA,EAAYiF;yBACd,CAAA,CAAA;AAEA,oBAAA,MAAMW,SAAAA,GAAYzL,OAAAA,CAAQsL,GAAG,CAAC,CAACtH,KAAAA,GAAUA,KAAAA,CAAMG,QAAQ,CAACC,IAAI,IAAIJ,KAAAA,CAAM1C,IAAI,CAAC8C,IAAI,CAAA;oBAC/E,MAAMsH,SAAAA,GAAY1L,QAAQsL,GAAG,CAAC,CAACtH,KAAAA,GAAUA,KAAAA,CAAM1C,IAAI,CAACgD,IAAI,CAAA;;;;oBAKxD,MAAMqH,QAAAA,GAAW,QAACX,EAAAA,CAAyBY,cAAc;oBACzD,MAAMC,KAAAA,GAAQzL,gBAAAA,CAAiBuL,QAAAA,CAAS5L,QAAQ,CAAA;AAChD,oBAAA,MAAM+L,OAAAA,GAAUD,KAAAA,KAAUjK,SAAAA,IAAamK,gBAAAA,CAAiBJ,SAAST,KAAK,CAAA;AAEtE,oBAAA,IAAIY,OAAAA,EAAS;wBACX,MAAM,EAAE/L,QAAQ,EAAE,GAAG4L,QAAAA;AACrB,wBAAA,MAAMK,MAAAA,GAASH,KAAAA,CAAM7L,OAAO,CAAC4G,MAAM;;AAGnCtE,wBAAAA,QAAAA,CAAS2J,iBAAAA,CAAkB;AAAElM,4BAAAA,QAAAA;AAAU0L,4BAAAA,SAAAA;AAAWC,4BAAAA,SAAAA;AAAWX,4BAAAA;AAAM,yBAAA,CAAA,CAAA;AAEnE,wBAAA,MAAMmB,aAAAA,GAAgB;AAAIL,4BAAAA,GAAAA,KAAAA,CAAM7L,OAAO;AAAKA,4BAAAA,GAAAA;AAAQ,yBAAA;;;AAIpDF,wBAAAA,qBAAAA,CACEC,UACAmM,aAAAA,EACAL,KAAAA,CAAM5L,kBAAkB,EACxB4L,MAAM3L,WAAW,CAAA;AAGnB,wBAAA,OAAOmH,mBAAAA,CAAoB;4BACzBrH,OAAAA,EAASkM,aAAAA;AACT5I,4BAAAA,OAAAA,EAAStD,QAAQsL,GAAG,CAAC,CAACa,CAAAA,EAAGlL,QAAU+K,MAAAA,GAAS/K,KAAAA,CAAAA;AAC5CsC,4BAAAA,KAAAA;AACAxD,4BAAAA,QAAAA;AACAuC,4BAAAA,QAAAA;AACApC,4BAAAA,WAAAA,EAAa2L,MAAM3L,WAAW;AAC9BD,4BAAAA,kBAAAA,EAAoB4L,MAAM5L;AAC5B,yBAAA,CAAA;AACF,oBAAA;;AAGAqC,oBAAAA,QAAAA,CAAS8J,kBAAAA,CAAmB;AAAEvB,wBAAAA,UAAAA;AAAYY,wBAAAA,SAAAA;AAAWC,wBAAAA,SAAAA;AAAWX,wBAAAA;AAAM,qBAAA,CAAA,CAAA;;AAGtE,oBAAA,MAAMhL,QAAAA,GAAYiL,QAAAA,EAAAA,CAAyBY,cAAc,CAAC7L,QAAQ;;oBAGlED,qBAAAA,CAAsBC,QAAAA,EAAUC,SAASC,kBAAAA,EAAoBC,WAAAA,CAAAA;;AAG7D,oBAAA,MAAMsD,kBAAkB,IAAIgB,eAAAA,EAAAA;AAC5BjE,oBAAAA,uBAAAA,CAAwBR,QAAAA,EAAUyD,eAAAA,CAAAA;AAElC,oBAAA,MAAM/B,MAAM4B,aAAAA,CAAc;AACxBrD,wBAAAA,OAAAA;AACAsD,wBAAAA,OAAAA,EAAStD,OAAAA,CAAQsL,GAAG,CAAC,CAACa,GAAGlL,KAAAA,GAAUA,KAAAA,CAAAA;AACnCsC,wBAAAA,KAAAA;AACAxD,wBAAAA,QAAAA;AACAyD,wBAAAA,eAAAA;AACAlB,wBAAAA,QAAAA;AACApC,wBAAAA,WAAAA;AACAD,wBAAAA;AACF,qBAAA,CAAA;AAEAuB,oBAAAA,YAAAA,CAAazB,QAAAA,EAAU0B,GAAAA,CAAAA;oBAEvB,OAAOA,GAAAA;AACT,gBAAA,CAAA;;;gBAGA4K,eAAAA,EAAiB;AACf,oBAAA;wBAAEC,IAAAA,EAAM,OAAA;wBAAS/J,EAAAA,EAAI;AAAO,qBAAA;AAC5B,oBAAA;wBAAE+J,IAAAA,EAAM,QAAA;wBAAU/J,EAAAA,EAAI;AAAO;AAC9B;AACH,aAAA,CAAA;AAEA;;;;;;UAOAgK,kBAAAA,EAAoB9B,OAAAA,CAAQE,QAAQ,CAA4B;gBAC9DC,OAAAA,EAAS,OAAO,EAAEtJ,IAAI,EAAE6C,QAAQ,EAAE,EAAE,EAAE6G,QAAQ,EAAE,GAAA;AAC9C,oBAAA,MAAMzH,KAAAA,GAASyH,QAAAA,EAAAA,CAAyBC,SAAS,EAAE1H,KAAAA;oBACnD,MAAME,GAAAA,GAAM,GAAGC,MAAAA,CAAOC,MAAM,CAACC,UAAU,CAAC,aAAa,CAAC;AAEtD,oBAAA,MAAMgB,WAAW,IAAIC,QAAAA,EAAAA;oBACrBD,QAAAA,CAASE,MAAM,CAAC,OAAA,EAASxD,IAAAA,CAAAA;AACzBsD,oBAAAA,QAAAA,CAASE,MAAM,CAAC,UAAA,EAAYC,IAAAA,CAAKC,SAAS,CAACb,QAAAA,CAAAA,CAAAA;oBAE3C,IAAI;wBACF,MAAMN,QAAAA,GAAW,MAAMwB,gBAAAA,CACrB5B,GAAAA,EACAF,KAAAA,EACAqB,UACA,IAAIJ,eAAAA,EAAAA,CAAkBE,MAAM,EAC5B,IAAA,CAAO,CAAA,CAAA;wBAET,OAAO;4BAAE0C,IAAAA,EAAMvD;AAAS,yBAAA;AAC1B,oBAAA,CAAA,CAAE,OAAOiC,GAAAA,EAAK;;;;;wBAKZ,MAAME,OAAAA,GACJF,eAAe0G,eAAAA,IAAmB1G,GAAAA,CAAI2G,eAAe,GAAG3G,GAAAA,CAAIE,OAAO,GAAG,EAAA;wBACxE,OAAO;4BAAE/D,KAAAA,EAAO;gCAAEmC,IAAAA,EAAM,cAAA;AAAgB4B,gCAAAA;AAAQ;AAAE,yBAAA;AACpD,oBAAA;AACF,gBAAA,CAAA;;;gBAGAqG,eAAAA,EAAiB;AACf,oBAAA;wBAAEC,IAAAA,EAAM,OAAA;wBAAS/J,EAAAA,EAAI;AAAO,qBAAA;AAC5B,oBAAA;wBAAE+J,IAAAA,EAAM,QAAA;wBAAU/J,EAAAA,EAAI;AAAO;AAC9B;AACH,aAAA,CAAA;AAEA;;;;UAKAmK,mBAAAA,EAAqBjC,OAAAA,CAAQE,QAAQ,CAAuB;AAC1DC,gBAAAA,OAAAA,EAAS,OAAO+B,IAAAA,EAAM,EAAErK,QAAQ,EAAE0I,QAAQ,EAAE,GAAA;oBAC1C,MAAM,EAAEjL,QAAQ,EAAEmL,KAAAA,EAAO0B,UAAU,EAAE,GAAG,QAAC5B,EAAAA,CAAyBY,cAAc;AAChF,oBAAA,MAAMrI,KAAAA,GAASyH,QAAAA,EAAAA,CAAyBC,SAAS,EAAE1H,KAAAA;AAEnD,oBAAA,MAAMsJ,gBAAAA,GAAmBD,UAAAA,CACtB7E,MAAM,CAAC,CAAC+E,CAAAA,GAAMA,CAAAA,CAAE1J,MAAM,KAAK,aAC3BkI,GAAG,CAAC,CAACwB,CAAAA,GAAMA,EAAE7L,KAAK,CAAA;oBAErB,IAAI4L,gBAAAA,CAAiBjG,MAAM,KAAK,CAAA,EAAG;wBACjC,OAAO;4BAAE3E,KAAAA,EAAO;gCAAEmC,IAAAA,EAAM,cAAA;gCAAgB4B,OAAAA,EAAS;AAA8B;AAAE,yBAAA;AACnF,oBAAA;AAEA,oBAAA,MAAM6F,QAAQzL,gBAAAA,CAAiBL,QAAAA,CAAAA;AAC/B,oBAAA,IAAI,CAAC8L,KAAAA,EAAO;wBACV,OAAO;4BAAE5J,KAAAA,EAAO;gCAAEmC,IAAAA,EAAM,cAAA;gCAAgB4B,OAAAA,EAAS;AAA2B;AAAE,yBAAA;AAChF,oBAAA;;oBAGA1D,QAAAA,CAASoK,mBAAAA,EAAAA,CAAAA;;AAGT,oBAAA,MAAMlJ,kBAAkB,IAAIgB,eAAAA,EAAAA;AAC5BjE,oBAAAA,uBAAAA,CAAwBR,QAAAA,EAAUyD,eAAAA,CAAAA;AAElC,oBAAA,MAAM/B,MAAM4B,aAAAA,CAAc;AACxBrD,wBAAAA,OAAAA,EAAS6L,MAAM7L,OAAO;wBACtBsD,OAAAA,EAASuJ,gBAAAA;AACTtJ,wBAAAA,KAAAA;AACAxD,wBAAAA,QAAAA;AACAyD,wBAAAA,eAAAA;AACAlB,wBAAAA,QAAAA;;AAEApC,wBAAAA,WAAAA,EAAa2L,MAAM3L,WAAW;AAC9BD,wBAAAA,kBAAAA,EAAoB4L,MAAM5L;AAC5B,qBAAA,CAAA;;;;AAKAuB,oBAAAA,YAAAA,CAAazB,QAAAA,EAAU0B,GAAAA,CAAAA;oBAEvB,OAAOA,GAAAA;AACT,gBAAA,CAAA;;;gBAGA4K,eAAAA,EAAiB;AACf,oBAAA;wBAAEC,IAAAA,EAAM,OAAA;wBAAS/J,EAAAA,EAAI;AAAO,qBAAA;AAC5B,oBAAA;wBAAE+J,IAAAA,EAAM,QAAA;wBAAU/J,EAAAA,EAAI;AAAO;AAC9B;AACH,aAAA,CAAA;AAEA;;;UAIAwK,eAAAA,EAAiBtC,OAAAA,CAAQE,QAAQ,CAAsD;gBACrFC,OAAAA,EAAS,OAAO,EAAE7K,QAAQ,EAAEkB,KAAK,EAAE,EAAE,EAAEqB,QAAQ,EAAE0I,QAAQ,EAAE,GAAA;AACzD,oBAAA,MAAM,EAAEY,cAAc,EAAEX,SAAS,EAAE,GAAGD,QAAAA,EAAAA;AACtC,oBAAA,MAAMa,QAAQzL,gBAAAA,CAAiBL,QAAAA,CAAAA;oBAE/B,IAAIA,QAAAA,KAAa6L,cAAAA,CAAe7L,QAAQ,IAAI,CAAC8L,KAAAA,IAAS,CAACA,KAAAA,CAAM7L,OAAO,CAACiB,KAAAA,CAAM,EAAE;wBAC3E,OAAO;4BAAEgB,KAAAA,EAAO;gCAAEmC,IAAAA,EAAM,cAAA;gCAAgB4B,OAAAA,EAAS;AAA0B;AAAE,yBAAA;AAC/E,oBAAA;oBAEAlF,YAAAA,CAAaJ,MAAM,CAACM,UAAAA,CAAWjB,QAAAA,EAAUkB,KAAAA,CAAAA,CAAAA;AACzCqB,oBAAAA,QAAAA,CAAS0K,SAAAA,CAAU;AAAEjN,wBAAAA,QAAAA;AAAUkB,wBAAAA;AAAM,qBAAA,CAAA,CAAA;AAErC,oBAAA,OAAOoG,mBAAAA,CAAoB;AACzBrH,wBAAAA,OAAAA,EAAS6L,MAAM7L,OAAO;wBACtBsD,OAAAA,EAAS;AAACrC,4BAAAA;AAAM,yBAAA;AAChBsC,wBAAAA,KAAAA,EAAO0H,SAAAA,EAAW1H,KAAAA;AAClBxD,wBAAAA,QAAAA;AACAuC,wBAAAA,QAAAA;AACApC,wBAAAA,WAAAA,EAAa2L,MAAM3L,WAAW;AAC9BD,wBAAAA,kBAAAA,EAAoB4L,MAAM5L;AAC5B,qBAAA,CAAA;AACF,gBAAA,CAAA;gBACAoM,eAAAA,EAAiB;AACf,oBAAA;wBAAEC,IAAAA,EAAM,OAAA;wBAAS/J,EAAAA,EAAI;AAAO,qBAAA;AAC5B,oBAAA;wBAAE+J,IAAAA,EAAM,QAAA;wBAAU/J,EAAAA,EAAI;AAAO;AAC9B;AACH,aAAA,CAAA;AAEA;;;UAIA0K,cAAAA,EAAgBxC,OAAAA,CAAQE,QAAQ,CAAiD;AAC/EC,gBAAAA,OAAAA,EAAS,OAAO,EAAErC,IAAI,EAAEC,QAAQ,EAAEvI,kBAAkB,EAAE,EAAE,EAAEqC,QAAQ,EAAE0I,QAAQ,EAAE,GAAA;AAC5E,oBAAA,MAAMzH,KAAAA,GAASyH,QAAAA,EAAAA,CAAyBC,SAAS,EAAE1H,KAAAA;;AAGnD,oBAAA,MAAMkI,YAAYlD,IAAAA,CAAK+C,GAAG,CAAC,CAAC7H,MAAQyJ,kBAAAA,CAAmBzJ,GAAAA,CAAAA,CAAAA;;AAGvDnB,oBAAAA,QAAAA,CACE8J,kBAAAA,CAAmB;AACjBvB,wBAAAA,UAAAA,EAAYtC,KAAK3B,MAAM;AACvB6E,wBAAAA;AACF,qBAAA,CAAA,CAAA;;AAIF,oBAAA,MAAM1L,QAAAA,GAAYiL,QAAAA,EAAAA,CAAyBY,cAAc,CAAC7L,QAAQ;;AAGlE,oBAAA,MAAMyD,kBAAkB,IAAIgB,eAAAA,EAAAA;AAC5BjE,oBAAAA,uBAAAA,CAAwBR,QAAAA,EAAUyD,eAAAA,CAAAA;oBAElC,IAAI;;wBAEF,MAAMuF,QAAAA,GAAW,MAAMT,oBAAAA,CAAqB;AAC1C/E,4BAAAA,KAAAA;AACAgF,4BAAAA,IAAAA;AACAC,4BAAAA,QAAAA;AACA9D,4BAAAA,MAAAA,EAAQlB,gBAAgBkB;AAC1B,yBAAA,CAAA;AAEA,wBAAA,IAAI,CAACqE,QAAAA,CAASoE,EAAE,IAAI,CAACpE,QAAAA,CAASF,IAAI,EAAE;4BAClCpI,yBAAAA,CAA0BV,QAAAA,CAAAA;AAE1B,4BAAA,IAAIqN,YAAAA,GAAe,uBAAA;4BACnB,IAAI;gCACF,MAAMC,SAAAA,GAAY,MAAMtE,QAAAA,CAASuE,IAAI,EAAA;gCACrC,IAAID,SAAAA,CAAUpL,KAAK,EAAE+D,OAAAA,EAAS;oCAC5BoH,YAAAA,GAAeC,SAAAA,CAAUpL,KAAK,CAAC+D,OAAO;gCACxC,CAAA,MAAO,IAAIqH,SAAAA,CAAUrH,OAAO,EAAE;AAC5BoH,oCAAAA,YAAAA,GAAeC,UAAUrH,OAAO;AAClC,gCAAA;AACF,4BAAA,CAAA,CAAE,OAAM;AACNoH,gCAAAA,YAAAA,GAAe,CAAC,0BAA0B,EAAErE,QAAAA,CAAS3F,MAAM,CAAA,CAAE;AAC/D,4BAAA;AAEAd,4BAAAA,QAAAA,CAASiL,eAAAA,CAAgB;gCAAEvH,OAAAA,EAASoH;AAAa,6BAAA,CAAA,CAAA;4BAEjD,OAAO;gCACLnL,KAAAA,EAAO;oCACLmC,IAAAA,EAAM,cAAA;oCACN4B,OAAAA,EAASoH,YAAAA;AACThK,oCAAAA,MAAAA,EAAQ2F,SAAS3F;AACnB;AACF,6BAAA;AACF,wBAAA;;wBAGA,MAAMgG,YAAAA,GAAe,MAAMN,gBAAAA,CAAiB;AAC1CC,4BAAAA,QAAAA;AACAzG,4BAAAA,QAAAA;AACAvC,4BAAAA,QAAAA;AACAE,4BAAAA,kBAAAA;AACAuI,4BAAAA;AACF,yBAAA,CAAA;wBAEA/H,yBAAAA,CAA0BV,QAAAA,CAAAA;AAE1B,wBAAA,IAAIqJ,gBAAgBA,YAAAA,CAAahC,IAAI,CAACR,MAAM,GAAG,CAAA,EAAG;4BAChD,OAAO;gCAAEQ,IAAAA,EAAMgC;AAAa,6BAAA;AAC9B,wBAAA;wBAEA,OAAO;4BAAEhC,IAAAA,EAAM;AAAEA,gCAAAA,IAAAA,EAAM,EAAE;AAAE+C,gCAAAA,MAAAA,EAAQ;AAAG;AAAE,yBAAA;AAC1C,oBAAA,CAAA,CAAE,OAAOrE,GAAAA,EAAK;wBACZrF,yBAAAA,CAA0BV,QAAAA,CAAAA;AAE1B,wBAAA,IAAI+F,GAAAA,YAAe0H,YAAAA,IAAgB1H,GAAAA,CAAI1B,IAAI,KAAK,YAAA,EAAc;4BAC5D,OAAO;gCAAEnC,KAAAA,EAAO;oCAAEmC,IAAAA,EAAM,cAAA;oCAAyB4B,OAAAA,EAAS;AAAmB;AAAE,6BAAA;AACjF,wBAAA;AAEA,wBAAA,MAAMoH,YAAAA,GAAetH,GAAAA,YAAeG,KAAAA,GAAQH,GAAAA,CAAIE,OAAO,GAAG,wBAAA;AAC1D1D,wBAAAA,QAAAA,CAASiL,eAAAA,CAAgB;4BAAEvH,OAAAA,EAASoH;AAAa,yBAAA,CAAA,CAAA;wBAEjD,OAAO;4BACLnL,KAAAA,EAAO;gCACLmC,IAAAA,EAAM,cAAA;gCACN4B,OAAAA,EAASoH;AACX;AACF,yBAAA;AACF,oBAAA;AACF,gBAAA,CAAA;;;gBAGAf,eAAAA,EAAiB;AACf,oBAAA;wBAAEC,IAAAA,EAAM,OAAA;wBAAS/J,EAAAA,EAAI;AAAO,qBAAA;AAC5B,oBAAA;wBAAE+J,IAAAA,EAAM,QAAA;wBAAU/J,EAAAA,EAAI;AAAO;AAC9B;AACH,aAAA,CAAA;AAEA;;;;;;;;;;UAWAtC,kBAAAA,EAAoBwK,OAAAA,CAAQE,QAAQ,CAGlC;AACA8C,gBAAAA,KAAAA,EAAO,CAAC,EAAE5K,OAAO,EAAE,IAAM;wBACvBY,GAAAA,EAAK,sCAAA;wBACLmF,MAAAA,EAAQ,MAAA;wBACRxB,IAAAA,EAAM;AAAEvE,4BAAAA;AAAQ;qBAClB,CAAA;gBACA6K,iBAAAA,EAAmB,CAAC3E,QAAAA,GAClBA,QAAAA,CAAS3B,IAAI;AACfiF,gBAAAA,eAAAA,EAAiB,CAACsB,OAAAA,EAASC,MAAAA,EAAQ,EAAE/K,OAAO,EAAE,GAAK;AAC9CA,wBAAAA,GAAAA,OAAAA,CAAQyI,GAAG,CAAC,CAAC/I,EAAAA,IAAQ;gCAAE+J,IAAAA,EAAM,OAAA;AAAkB/J,gCAAAA;6BAAG,CAAA,CAAA;AACrD,wBAAA;4BAAE+J,IAAAA,EAAM,OAAA;4BAAkB/J,EAAAA,EAAI;AAAO;AACtC;AACH,aAAA;SACF;AACF,CAAA;AAEK,MAAM,EACXsL,sBAAsB,EACtBC,6BAA6B,EAC7BC,8BAA8B,EAC9BC,0BAA0B,EAC1BC,yBAAyB,EACzBC,6BAA6B,EAC9B,GAAGxL;;;;"}
@@ -0,0 +1,19 @@
1
+ import { type MediaAllowedTypes } from '../../utils/isAllowedAssetType';
2
+ import type { File } from '../../../../shared/contracts/files';
3
+ export interface AssetPickerDialogProps {
4
+ open: boolean;
5
+ onClose: () => void;
6
+ title: string;
7
+ /** What the field holds now; the picker starts with it selected. */
8
+ initialSelection?: File[];
9
+ multiple?: boolean;
10
+ allowedTypes?: MediaAllowedTypes | null;
11
+ /** The confirmed selection, in order. Always an array, even for a single field. */
12
+ onConfirm: (files: File[]) => void;
13
+ }
14
+ /**
15
+ * Content Manager asset picker, built on the current Media Library list. Its
16
+ * folder, search, filter and sort state lives in memory, so browsing never
17
+ * touches the URL of the entry it is opened from.
18
+ */
19
+ export declare const AssetPickerDialog: ({ open, onClose, title, initialSelection, multiple, allowedTypes, onConfirm, }: AssetPickerDialogProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,10 @@
1
+ interface FolderBreadcrumbsProps {
2
+ currentFolderId: number;
3
+ onSelectFolder: (folderId: number | null) => void;
4
+ }
5
+ /**
6
+ * Home › … › parent › current. Every crumb but the current folder navigates,
7
+ * so a user deep in the tree can climb back without a sidebar.
8
+ */
9
+ export declare const FolderBreadcrumbs: ({ currentFolderId, onSelectFolder }: FolderBreadcrumbsProps) => import("react/jsx-runtime").JSX.Element | null;
10
+ export {};
@@ -0,0 +1,19 @@
1
+ import type { File } from '../../../../shared/contracts/files';
2
+ import type { MediaAllowedTypes } from '../../utils/isAllowedAssetType';
3
+ /**
4
+ * The `media-library` component contract, which the Wysiwyg and Blocks editors
5
+ * render to insert images. Kept identical to the legacy `MediaLibraryDialog`.
6
+ */
7
+ export interface MediaLibraryPickerDialogProps {
8
+ allowedTypes?: MediaAllowedTypes;
9
+ multiple?: boolean;
10
+ initiallySelectedAssets?: File[];
11
+ onClose: () => void;
12
+ onSelectAssets: (selectedAssets: File[]) => void;
13
+ }
14
+ /**
15
+ * The current asset picker behind the `media-library` component. The editors
16
+ * insert assets rather than hold a value, and don't pass a field label, so the
17
+ * title is generic.
18
+ */
19
+ export declare const MediaLibraryPickerDialog: ({ allowedTypes, multiple, initiallySelectedAssets, onClose, onSelectAssets, }: MediaLibraryPickerDialogProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,28 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type MediaAllowedTypes } from '../../utils/isAllowedAssetType';
3
+ import { type PickerSelection } from './pickerSelection';
4
+ import type { File } from '../../../../shared/contracts/files';
5
+ interface PickerSelectionContextValue {
6
+ selection: PickerSelection;
7
+ moveFile: (activeId: number, overId: number) => void;
8
+ }
9
+ export declare const usePickerSelection: () => PickerSelectionContextValue;
10
+ interface PickerSelectionProviderProps {
11
+ children: ReactNode;
12
+ initialSelection: File[];
13
+ multiple: boolean;
14
+ allowedTypes?: MediaAllowedTypes | null;
15
+ /**
16
+ * The assets on screen. Views select by key, but the selection keeps whole
17
+ * files, so a newly picked key is resolved against these.
18
+ */
19
+ knownFiles: File[];
20
+ }
21
+ /**
22
+ * The Content Manager picker's selection, behind the same `AssetSelection`
23
+ * interface the Media Library views read: only assets are selectable, assets
24
+ * outside `allowedTypes` are shown but cannot be picked, and the selection
25
+ * survives folder changes, search, filters and sort.
26
+ */
27
+ export declare const PickerSelectionProvider: ({ children, initialSelection, multiple, allowedTypes, knownFiles, }: PickerSelectionProviderProps) => import("react/jsx-runtime").JSX.Element;
28
+ export {};
@@ -0,0 +1,12 @@
1
+ import { type ReactNode } from 'react';
2
+ interface SortableSelectionProps {
3
+ children: ReactNode;
4
+ /**
5
+ * Called with `true` when a drag starts and `false` when it ends or is
6
+ * cancelled, so the dialog can keep Escape for cancelling the drag.
7
+ */
8
+ onReorderingChange?: (reordering: boolean) => void;
9
+ }
10
+ /** Makes the picker's selected assets reorderable (the Selected tab is always a grid). */
11
+ export declare const SortableSelection: ({ children, onReorderingChange }: SortableSelectionProps) => import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,26 @@
1
+ import type { File } from '../../../../shared/contracts/files';
2
+ /**
3
+ * The picker's selection is the value the field will hold once confirmed:
4
+ * whole `File` objects, in order. Assets already in the field come first, new
5
+ * picks are appended in the order they are clicked.
6
+ */
7
+ export type PickerSelection = File[];
8
+ export declare const hasFile: (selection: PickerSelection, id: number) => boolean;
9
+ /**
10
+ * Adds the file, or removes it if it is already there. On a single-value field
11
+ * a new pick replaces whatever was selected.
12
+ */
13
+ export declare const toggleFile: (selection: PickerSelection, file: File, { multiple }: {
14
+ multiple: boolean;
15
+ }) => PickerSelection;
16
+ /** Appends every file not already selected, keeping their order (select-all). */
17
+ export declare const addFiles: (selection: PickerSelection, files: File[]) => PickerSelection;
18
+ export declare const removeFile: (selection: PickerSelection, id: number) => PickerSelection;
19
+ export declare const removeFiles: (selection: PickerSelection, ids: Set<number>) => PickerSelection;
20
+ /**
21
+ * Moves one file to where another one is, the others shifting to make room.
22
+ * Unknown ids leave the selection as it is.
23
+ */
24
+ export declare const moveFile: (selection: PickerSelection, activeId: number, overId: number) => PickerSelection;
25
+ /** Same files in the same order: confirming would change nothing. */
26
+ export declare const isSameSelection: (a: PickerSelection, b: PickerSelection) => boolean;
@@ -4,6 +4,7 @@ import { FlexProps } from '@strapi/design-system';
4
4
  /** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */
5
5
  export declare const DRAWER_CLOSE_ANIMATION_MS = 300;
6
6
  type PointerDownOutsideHandler = NonNullable<Dialog.DialogContentProps['onPointerDownOutside']>;
7
+ type AutoFocusHandler = NonNullable<Dialog.DialogContentProps['onOpenAutoFocus']>;
7
8
  interface DrawerBodyProps extends Omit<FlexProps, 'width' | 'maxHeight'> {
8
9
  animationDirection?: 'up' | 'left';
9
10
  /** Width of the panel from the medium breakpoint up. Mobile is always full-bleed. */
@@ -19,6 +20,13 @@ interface DrawerBodyProps extends Omit<FlexProps, 'width' | 'maxHeight'> {
19
20
  * never counts as outside — Radix reads the React tree, not the DOM.
20
21
  */
21
22
  onPointerDownOutside?: PointerDownOutsideHandler;
23
+ /** Radix's hook as focus moves into the panel on open. */
24
+ onOpenAutoFocus?: AutoFocusHandler;
25
+ /**
26
+ * Radix's hook as the panel gives focus back on close. Opened from state
27
+ * rather than a `Dialog.Trigger`, it has nowhere to send it unless this does.
28
+ */
29
+ onCloseAutoFocus?: AutoFocusHandler;
22
30
  children: React.ReactNode;
23
31
  }
24
32
  interface DrawerRootProps {