@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 +1 @@
1
- {"version":3,"file":"uploadProgress.mjs","sources":["../../../admin/src/store/uploadProgress.ts"],"sourcesContent":["import { createSelector, createSlice, type PayloadAction } from '@reduxjs/toolkit';\n\nimport type { File } from '../../../shared/contracts/files';\n\nexport interface FileUploadError {\n name: string;\n message: string;\n}\n\nexport type FileProgressStatus = 'pending' | 'uploading' | 'complete' | 'error' | 'cancelled';\n\n/**\n * AI metadata generation phase for a single row, tracked independently from the\n * upload status: a metadata failure never turns a successful upload into an error.\n * `undefined` means the row has no metadata phase at all, i.e. AI metadata is\n * disabled — non-images do get a phase and come back `skipped` from the server.\n */\nexport type FileMetadataStatus = 'generating' | 'generated' | 'skipped' | 'failed';\n\nexport type FileMetadataResultStatus = Exclude<FileMetadataStatus, 'generating'>;\n\nexport interface FileProgress {\n name: string;\n index: number;\n status: FileProgressStatus;\n size: number;\n uploadedBytes: number;\n file?: File;\n /** When the server confirmed the upload. Set with the row's asset. */\n completedAt?: number;\n error?: string;\n metadataStatus?: FileMetadataStatus;\n}\n\nexport interface UploadProgressState {\n isVisible: boolean;\n isMinimized: boolean;\n totalFiles: number;\n files: FileProgress[];\n errors: FileUploadError[];\n uploadId: number;\n /**\n * Whether every row's size was known when the batch opened (the direct-file flow), so\n * the byte-weighted aggregate is meaningful. The URL flow learns sizes one row at a time.\n */\n reportsByteProgress: boolean;\n}\n\nexport interface RootState {\n uploadProgress: UploadProgressState;\n}\n\nconst initialState: UploadProgressState = {\n isVisible: false,\n isMinimized: false,\n totalFiles: 0,\n files: [],\n errors: [],\n uploadId: 0,\n reportsByteProgress: false,\n};\n\nconst uploadProgressSlice = createSlice({\n name: 'uploadProgress',\n initialState,\n reducers: {\n openUploadProgress(\n state,\n action: PayloadAction<{\n totalFiles: number;\n fileNames: string[];\n fileSizes?: number[];\n }>\n ) {\n state.isVisible = true;\n state.isMinimized = false;\n\n // Create pending files for upload\n const pendingFiles: FileProgress[] = action.payload.fileNames.map((name, index) => ({\n name,\n index,\n status: 'pending' as FileProgressStatus,\n size: action.payload.fileSizes?.[index] ?? 0,\n uploadedBytes: 0,\n }));\n\n state.files = pendingFiles;\n state.totalFiles = action.payload.totalFiles;\n state.errors = [];\n state.uploadId += 1;\n // Known sizes == the direct-file flow == the flow that streams bytes.\n state.reportsByteProgress = action.payload.fileSizes !== undefined;\n },\n /**\n * Rows for a second drop, joined to the batch already uploading. Indices\n * continue from the current length so the earlier drop's in-flight uploads\n * keep addressing their own rows.\n */\n appendUploadFiles(\n state,\n action: PayloadAction<{\n uploadId: number;\n fileNames: string[];\n fileSizes?: number[];\n }>\n ) {\n if (action.payload.uploadId !== state.uploadId) {\n return;\n }\n\n const offset = state.files.length;\n\n state.files.push(\n ...action.payload.fileNames.map((name, i) => ({\n name,\n index: offset + i,\n status: 'pending' as FileProgressStatus,\n size: action.payload.fileSizes?.[i] ?? 0,\n uploadedBytes: 0,\n }))\n );\n\n state.totalFiles += action.payload.fileNames.length;\n // The dialog may have been dismissed while the first drop was running.\n state.isVisible = true;\n state.isMinimized = false;\n },\n setFileUploading(\n state,\n action: PayloadAction<{ name: string; index: number; size: number; uploadId: number }>\n ) {\n const { index, size, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'uploading';\n state.files[index].size = size;\n }\n },\n /**\n * `size` is optional and only sent by the URL flow, which learns the size from the\n * same server event that carries the first byte count — the row was created with\n * `size: 0`, and bytes clamped against a zero size would all read as zero. The\n * direct-file flow already knows the size up front and omits it.\n */\n setFileProgress(\n state,\n action: PayloadAction<{ index: number; bytes: number; uploadId: number; size?: number }>\n ) {\n const { index, bytes, size, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n const file = state.files[index];\n if (file) {\n if (size !== undefined && file.size === 0) {\n file.size = size;\n }\n // Clamp to the known file size so the aggregate can never exceed 100%.\n file.uploadedBytes = Math.min(bytes, file.size);\n }\n },\n setFileComplete(\n state,\n action: PayloadAction<{ index: number; file: File; uploadId: number; completedAt: number }>\n ) {\n const { index, file, uploadId, completedAt } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'complete';\n state.files[index].file = file;\n state.files[index].completedAt = completedAt;\n // Reflect completion in the aggregate even if the final progress event was throttled.\n state.files[index].uploadedBytes = state.files[index].size;\n }\n },\n setFileError(\n state,\n action: PayloadAction<{ index: number; name: string; message: string; uploadId: number }>\n ) {\n const { index, name, message, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'error';\n state.files[index].error = message;\n }\n state.errors = [...state.errors, { name, message }];\n },\n /**\n * Metadata generation started for a row.\n *\n * Metadata requests are fired-and-forgotten, so their callbacks can land after\n * a new batch has replaced `files` and reused the same row indices. Every\n * metadata payload therefore carries the `uploadId` it was fired for, and stale\n * ones are dropped instead of writing onto another batch's row.\n */\n setFileMetadataGenerating(state, action: PayloadAction<{ index: number; uploadId: number }>) {\n const { index, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].metadataStatus = 'generating';\n }\n },\n /**\n * Terminal metadata outcome for a row. Never touches `status`/`error`/`errors`:\n * the upload itself already succeeded regardless of how generation went.\n */\n setFileMetadataResult(\n state,\n action: PayloadAction<{\n index: number;\n uploadId: number;\n status: FileMetadataResultStatus;\n }>\n ) {\n const { index, uploadId, status } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].metadataStatus = status;\n }\n },\n addUploadErrors(state, action: PayloadAction<FileUploadError[]>) {\n state.errors = [...state.errors, ...action.payload];\n },\n closeUploadProgress(state) {\n state.isVisible = false;\n state.isMinimized = false;\n state.totalFiles = 0;\n state.files = [];\n state.errors = [];\n state.reportsByteProgress = false;\n },\n toggleMinimize(state) {\n state.isMinimized = !state.isMinimized;\n },\n cancelUpload(state) {\n // Mark all pending and uploading files as cancelled\n state.files = state.files.map((file) => {\n if (file.status === 'pending' || file.status === 'uploading') {\n return { ...file, status: 'cancelled' as FileProgressStatus };\n }\n return file;\n });\n },\n setUploadFailed(state, action: PayloadAction<{ message: string }>) {\n // Mark all pending and uploading files as errored when a catastrophic failure occurs\n state.files = state.files.map((file) => {\n if (file.status === 'pending' || file.status === 'uploading') {\n return {\n ...file,\n status: 'error' as FileProgressStatus,\n error: action.payload.message,\n };\n }\n return file;\n });\n state.errors = [...state.errors, { name: 'Upload Error', message: action.payload.message }];\n },\n retryCancelledFiles(state) {\n // Reset all cancelled files back to pending for retry\n state.files = state.files.map((file) => {\n if (file.status === 'cancelled') {\n return {\n ...file,\n status: 'pending' as FileProgressStatus,\n uploadedBytes: 0,\n // A retried row goes through the metadata phase again from scratch.\n metadataStatus: undefined,\n };\n }\n return file;\n });\n },\n },\n});\n\n/**\n * Assets whose own upload has already finished, newest batch only.\n *\n * The list behind the upload dialog uses these to show each asset the moment it\n * lands, instead of waiting for the batch mutation to invalidate the cache. Rows\n * only carry a `file` once the server has created it, so every entry here is a\n * real, persisted asset.\n */\nconst NO_FILES: FileProgress[] = [];\n\n/** An uploaded asset, with the moment the server confirmed it. */\nexport interface CompletedUpload {\n asset: File;\n completedAt: number;\n}\n\nexport const selectCompletedUploads = createSelector(\n // The plugin registers this slice in `register()`, so a host that has not\n // reached that point has no upload state — and therefore nothing to place.\n (state: Partial<RootState>) => state.uploadProgress?.files ?? NO_FILES,\n (files): CompletedUpload[] =>\n files.reduce<CompletedUpload[]>((completed, row) => {\n if (row.status === 'complete' && row.file && row.completedAt !== undefined) {\n completed.push({ asset: row.file, completedAt: row.completedAt });\n }\n\n return completed;\n }, [])\n);\n\n/**\n * Byte-weighted aggregate progress across the whole batch: `sum(uploadedBytes) / sum(size)`.\n *\n * Falls back to count-based progress (settled files / total files) when all sizes are\n * zero — e.g. URL-flow rows where the file size is unknown up front.\n */\nexport const selectAggregateProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number => {\n if (files.length === 0) return 0;\n\n const totalSize = files.reduce((sum, f) => sum + f.size, 0);\n\n if (totalSize === 0) {\n const settled = files.filter(\n (f) => f.status === 'complete' || f.status === 'error' || f.status === 'cancelled'\n ).length;\n return Math.round((settled / files.length) * 100);\n }\n\n const uploadedBytes = files.reduce((sum, f) => sum + f.uploadedBytes, 0);\n return Math.round((uploadedBytes / totalSize) * 100);\n }\n);\n\n/**\n * Whether to show byte-weighted `selectAggregateProgress` rather than `selectCountBasedProgress`.\n *\n * Only the flag: byte-weighting needs every size up front. A URL batch learns sizes one row\n * at a time, so weighting over the sizes known so far makes the header jump backwards at\n * every file boundary.\n */\nexport const selectReportsByteProgress = createSelector(\n (state: RootState) => state.uploadProgress.reportsByteProgress,\n (reportsByteProgress): boolean => reportsByteProgress\n);\n\n/**\n * Row-weighted progress for a batch whose sizes are not known up front (the URL flow).\n * Each row is worth `1 / total`: settled rows count fully and an in-flight row contributes\n * `uploadedBytes / size` once it reports bytes, so a multi-URL batch climbs smoothly to\n * 33 → 67 → 100 and never moves backwards.\n *\n * Returns `null` until something has moved — 0% is the frozen signal this flow exists to\n * remove, so the header stays indeterminate until there's real progress.\n */\nexport const selectCountBasedProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number | null => {\n const done = files.reduce((sum, f) => {\n if (f.status === 'complete' || f.status === 'error' || f.status === 'cancelled') {\n return sum + 1;\n }\n return f.size > 0 ? sum + Math.min(f.uploadedBytes / f.size, 1) : sum;\n }, 0);\n\n if (done === 0) {\n return null;\n }\n\n return Math.round((done / files.length) * 100);\n }\n);\n\n/**\n * Count-based metadata progress across the whole batch: `settled / expected`.\n *\n * Count-based rather than byte-weighted because the generation endpoint answers in one\n * go — there is no intermediate progress to weight.\n *\n * The denominator is every row *expected* to enter the phase, not just those that\n * already have. Generation is fired per file as each upload finishes, so counting only\n * started rows made the denominator grow mid-batch and the percentage jump backwards\n * (1/1 = 100%, then a second row starts and it drops to 1/2 = 50%), which flickered the\n * header subtitle on and off once per file.\n *\n * \"Expected\" is derived from upload outcome rather than from the AI-metadata flag:\n * - a row still uploading may yet enter the phase, so it counts toward the total;\n * - an errored or cancelled row never will, so it must not — otherwise a batch with\n * one failure could never reach 100%.\n *\n * Returns `null` when nothing has entered the phase and nothing is pending — i.e. AI\n * metadata is off, or the batch is done — so the header can hide the subtitle.\n */\nexport const selectMetadataProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number | null => {\n const started = files.filter((f) => f.metadataStatus !== undefined);\n\n // Nothing has entered the phase yet: with no started row there is no evidence AI\n // metadata is even enabled, so stay silent rather than showing a premature 0%.\n if (started.length === 0) return null;\n\n // Rows whose upload is still in flight are counted in the denominator so the\n // percentage only ever climbs as the batch progresses.\n const pending = files.filter(\n (f) => f.metadataStatus === undefined && (f.status === 'pending' || f.status === 'uploading')\n ).length;\n\n const expected = started.length + pending;\n const settled = started.filter((f) => f.metadataStatus !== 'generating').length;\n\n return Math.round((settled / expected) * 100);\n }\n);\n\n/**\n * Whether the metadata phase is still ongoing for the batch as a whole.\n *\n * The header uses this — not `selectMetadataProgress === 100` — to decide when to drop\n * the subtitle. Two distinct reasons the phase can be unfinished:\n * - a row is generating right now;\n * - no row is generating this instant, but rows are still uploading and will enter the\n * phase when they finish.\n *\n * The second clause is what keeps the subtitle stable. Generation for file N typically\n * finishes before file N+1 finishes uploading, so a naive \"is anything generating?\"\n * check goes false between every pair of files and blinks the subtitle out and back in.\n */\nexport const selectIsGeneratingMetadata = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): boolean => {\n if (files.some((f) => f.metadataStatus === 'generating')) return true;\n\n // Only bridge the gap if some row has already entered the phase — otherwise a batch\n // with AI metadata disabled would report the phase as ongoing for its whole upload.\n const hasStarted = files.some((f) => f.metadataStatus !== undefined);\n\n return hasStarted && files.some((f) => f.status === 'pending' || f.status === 'uploading');\n }\n);\n\n/**\n * How many rows reached each terminal metadata outcome, for the header's completion\n * message. `null` while the phase is unfinished — or was never entered at all — so the\n * caller has a single check for \"there is no settled outcome to report yet\".\n *\n * Counts are reported separately rather than collapsed into one total because they are\n * not interchangeable: only `generated` rows actually had metadata written, so only that\n * count can be claimed as a success. A batch of non-images settles entirely on `skipped`,\n * where \"generated on 0 files\" would be worse than saying nothing.\n */\nexport const selectMetadataOutcome = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): { generated: number; skipped: number; failed: number } | null => {\n const started = files.filter((f) => f.metadataStatus !== undefined);\n\n if (started.length === 0) return null;\n\n // Mirrors `selectIsGeneratingMetadata`: the phase isn't over while a row is\n // generating, nor while a row is still uploading and has yet to enter it.\n const isOngoing =\n started.some((f) => f.metadataStatus === 'generating') ||\n files.some((f) => f.status === 'pending' || f.status === 'uploading');\n\n if (isOngoing) return null;\n\n return {\n generated: started.filter((f) => f.metadataStatus === 'generated').length,\n skipped: started.filter((f) => f.metadataStatus === 'skipped').length,\n failed: started.filter((f) => f.metadataStatus === 'failed').length,\n };\n }\n);\n\nexport const {\n openUploadProgress,\n appendUploadFiles,\n setFileUploading,\n setFileProgress,\n setFileComplete,\n setFileError,\n setFileMetadataGenerating,\n setFileMetadataResult,\n addUploadErrors,\n closeUploadProgress,\n toggleMinimize,\n cancelUpload,\n setUploadFailed,\n retryCancelledFiles,\n} = uploadProgressSlice.actions;\n\n/**\n * The merge/reset switch. Errored and cancelled rows count as settled, so a\n * batch that finished badly is still replaced by the next drop.\n */\nexport const isUploadInFlight = (files: ReadonlyArray<{ status: FileProgressStatus }>): boolean =>\n files.some((f) => f.status === 'pending' || f.status === 'uploading');\n\nexport const uploadProgressReducer = uploadProgressSlice.reducer;\n"],"names":["initialState","isVisible","isMinimized","totalFiles","files","errors","uploadId","reportsByteProgress","uploadProgressSlice","createSlice","name","reducers","openUploadProgress","state","action","pendingFiles","payload","fileNames","map","index","status","size","fileSizes","uploadedBytes","undefined","appendUploadFiles","offset","length","push","i","setFileUploading","setFileProgress","bytes","file","Math","min","setFileComplete","completedAt","setFileError","message","error","setFileMetadataGenerating","metadataStatus","setFileMetadataResult","addUploadErrors","closeUploadProgress","toggleMinimize","cancelUpload","setUploadFailed","retryCancelledFiles","NO_FILES","selectCompletedUploads","createSelector","uploadProgress","reduce","completed","row","asset","selectAggregateProgress","totalSize","sum","f","settled","filter","round","selectReportsByteProgress","selectCountBasedProgress","done","selectMetadataProgress","started","pending","expected","selectIsGeneratingMetadata","some","hasStarted","selectMetadataOutcome","isOngoing","generated","skipped","failed","actions","isUploadInFlight","uploadProgressReducer","reducer"],"mappings":"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"}
1
+ {"version":3,"file":"uploadProgress.mjs","sources":["../../../admin/src/store/uploadProgress.ts"],"sourcesContent":["import { createSelector, createSlice, type PayloadAction } from '@reduxjs/toolkit';\n\nimport type { File } from '../../../shared/contracts/files';\n\nexport interface FileUploadError {\n name: string;\n message: string;\n}\n\nexport type FileProgressStatus = 'pending' | 'uploading' | 'complete' | 'error' | 'cancelled';\n\n/**\n * AI metadata generation phase for a single row, tracked independently from the\n * upload status: a metadata failure never turns a successful upload into an error.\n * `undefined` means the row has no metadata phase at all, i.e. AI metadata is\n * disabled — non-images do get a phase and come back `skipped` from the server.\n */\nexport type FileMetadataStatus = 'generating' | 'generated' | 'skipped' | 'failed';\n\nexport type FileMetadataResultStatus = Exclude<FileMetadataStatus, 'generating'>;\n\nexport interface FileProgress {\n name: string;\n index: number;\n status: FileProgressStatus;\n size: number;\n uploadedBytes: number;\n file?: File;\n /** When the server confirmed the upload. Set with the row's asset. */\n completedAt?: number;\n error?: string;\n metadataStatus?: FileMetadataStatus;\n /**\n * Who started the row, when that is not the progress dialog alone. The Content\n * Manager field tags its own uploads so it can show their state in place.\n */\n owner?: string;\n}\n\nexport interface UploadProgressState {\n isVisible: boolean;\n isMinimized: boolean;\n totalFiles: number;\n files: FileProgress[];\n errors: FileUploadError[];\n uploadId: number;\n /**\n * Whether every row's size was known when the batch opened (the direct-file flow), so\n * the byte-weighted aggregate is meaningful. The URL flow learns sizes one row at a time.\n */\n reportsByteProgress: boolean;\n}\n\nexport interface RootState {\n uploadProgress: UploadProgressState;\n}\n\nconst initialState: UploadProgressState = {\n isVisible: false,\n isMinimized: false,\n totalFiles: 0,\n files: [],\n errors: [],\n uploadId: 0,\n reportsByteProgress: false,\n};\n\nconst uploadProgressSlice = createSlice({\n name: 'uploadProgress',\n initialState,\n reducers: {\n openUploadProgress(\n state,\n action: PayloadAction<{\n totalFiles: number;\n fileNames: string[];\n fileSizes?: number[];\n owner?: string;\n }>\n ) {\n state.isVisible = true;\n state.isMinimized = false;\n\n // Create pending files for upload\n const pendingFiles: FileProgress[] = action.payload.fileNames.map((name, index) => ({\n name,\n index,\n status: 'pending' as FileProgressStatus,\n size: action.payload.fileSizes?.[index] ?? 0,\n uploadedBytes: 0,\n owner: action.payload.owner,\n }));\n\n state.files = pendingFiles;\n state.totalFiles = action.payload.totalFiles;\n state.errors = [];\n state.uploadId += 1;\n // Known sizes == the direct-file flow == the flow that streams bytes.\n state.reportsByteProgress = action.payload.fileSizes !== undefined;\n },\n /**\n * Rows for a second drop, joined to the batch already uploading. Indices\n * continue from the current length so the earlier drop's in-flight uploads\n * keep addressing their own rows.\n */\n appendUploadFiles(\n state,\n action: PayloadAction<{\n uploadId: number;\n fileNames: string[];\n fileSizes?: number[];\n owner?: string;\n }>\n ) {\n if (action.payload.uploadId !== state.uploadId) {\n return;\n }\n\n const offset = state.files.length;\n\n state.files.push(\n ...action.payload.fileNames.map((name, i) => ({\n name,\n index: offset + i,\n status: 'pending' as FileProgressStatus,\n size: action.payload.fileSizes?.[i] ?? 0,\n uploadedBytes: 0,\n owner: action.payload.owner,\n }))\n );\n\n state.totalFiles += action.payload.fileNames.length;\n // The dialog may have been dismissed while the first drop was running.\n state.isVisible = true;\n state.isMinimized = false;\n },\n setFileUploading(\n state,\n action: PayloadAction<{ name: string; index: number; size: number; uploadId: number }>\n ) {\n const { index, size, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'uploading';\n state.files[index].size = size;\n }\n },\n /**\n * `size` is optional and only sent by the URL flow, which learns the size from the\n * same server event that carries the first byte count — the row was created with\n * `size: 0`, and bytes clamped against a zero size would all read as zero. The\n * direct-file flow already knows the size up front and omits it.\n */\n setFileProgress(\n state,\n action: PayloadAction<{ index: number; bytes: number; uploadId: number; size?: number }>\n ) {\n const { index, bytes, size, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n const file = state.files[index];\n if (file) {\n if (size !== undefined && file.size === 0) {\n file.size = size;\n }\n // Clamp to the known file size so the aggregate can never exceed 100%.\n file.uploadedBytes = Math.min(bytes, file.size);\n }\n },\n setFileComplete(\n state,\n action: PayloadAction<{ index: number; file: File; uploadId: number; completedAt: number }>\n ) {\n const { index, file, uploadId, completedAt } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'complete';\n state.files[index].file = file;\n state.files[index].completedAt = completedAt;\n // Reflect completion in the aggregate even if the final progress event was throttled.\n state.files[index].uploadedBytes = state.files[index].size;\n }\n },\n setFileError(\n state,\n action: PayloadAction<{ index: number; name: string; message: string; uploadId: number }>\n ) {\n const { index, name, message, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].status = 'error';\n state.files[index].error = message;\n }\n state.errors = [...state.errors, { name, message }];\n },\n /**\n * Metadata generation started for a row.\n *\n * Metadata requests are fired-and-forgotten, so their callbacks can land after\n * a new batch has replaced `files` and reused the same row indices. Every\n * metadata payload therefore carries the `uploadId` it was fired for, and stale\n * ones are dropped instead of writing onto another batch's row.\n */\n setFileMetadataGenerating(state, action: PayloadAction<{ index: number; uploadId: number }>) {\n const { index, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].metadataStatus = 'generating';\n }\n },\n /**\n * Terminal metadata outcome for a row. Never touches `status`/`error`/`errors`:\n * the upload itself already succeeded regardless of how generation went.\n */\n setFileMetadataResult(\n state,\n action: PayloadAction<{\n index: number;\n uploadId: number;\n status: FileMetadataResultStatus;\n }>\n ) {\n const { index, uploadId, status } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n if (state.files[index]) {\n state.files[index].metadataStatus = status;\n }\n },\n addUploadErrors(state, action: PayloadAction<FileUploadError[]>) {\n state.errors = [...state.errors, ...action.payload];\n },\n closeUploadProgress(state) {\n state.isVisible = false;\n state.isMinimized = false;\n state.totalFiles = 0;\n state.files = [];\n state.errors = [];\n state.reportsByteProgress = false;\n },\n toggleMinimize(state) {\n state.isMinimized = !state.isMinimized;\n },\n cancelUpload(state) {\n // Mark all pending and uploading files as cancelled\n state.files = state.files.map((file) => {\n if (file.status === 'pending' || file.status === 'uploading') {\n return { ...file, status: 'cancelled' as FileProgressStatus };\n }\n return file;\n });\n },\n setUploadFailed(state, action: PayloadAction<{ message: string }>) {\n // Mark all pending and uploading files as errored when a catastrophic failure occurs\n state.files = state.files.map((file) => {\n if (file.status === 'pending' || file.status === 'uploading') {\n return {\n ...file,\n status: 'error' as FileProgressStatus,\n error: action.payload.message,\n };\n }\n return file;\n });\n state.errors = [...state.errors, { name: 'Upload Error', message: action.payload.message }];\n },\n /** Cancels one row, leaving the rest of the batch running. */\n cancelFile(state, action: PayloadAction<{ index: number; uploadId: number }>) {\n const { index, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n const file = state.files[index];\n if (file && (file.status === 'pending' || file.status === 'uploading')) {\n file.status = 'cancelled';\n }\n },\n /** Puts one cancelled or failed row back in the queue. */\n retryFile(state, action: PayloadAction<{ index: number; uploadId: number }>) {\n const { index, uploadId } = action.payload;\n if (uploadId !== state.uploadId) {\n return;\n }\n const file = state.files[index];\n if (file && (file.status === 'cancelled' || file.status === 'error')) {\n file.status = 'pending';\n file.uploadedBytes = 0;\n file.error = undefined;\n file.metadataStatus = undefined;\n }\n },\n retryCancelledFiles(state) {\n // Reset all cancelled files back to pending for retry\n state.files = state.files.map((file) => {\n if (file.status === 'cancelled') {\n return {\n ...file,\n status: 'pending' as FileProgressStatus,\n uploadedBytes: 0,\n // A retried row goes through the metadata phase again from scratch.\n metadataStatus: undefined,\n };\n }\n return file;\n });\n },\n },\n});\n\n/**\n * Assets whose own upload has already finished, newest batch only.\n *\n * The list behind the upload dialog uses these to show each asset the moment it\n * lands, instead of waiting for the batch mutation to invalidate the cache. Rows\n * only carry a `file` once the server has created it, so every entry here is a\n * real, persisted asset.\n */\nconst NO_FILES: FileProgress[] = [];\n\n/** An uploaded asset, with the moment the server confirmed it. */\nexport interface CompletedUpload {\n asset: File;\n completedAt: number;\n}\n\nexport const selectCompletedUploads = createSelector(\n // The plugin registers this slice in `register()`, so a host that has not\n // reached that point has no upload state — and therefore nothing to place.\n (state: Partial<RootState>) => state.uploadProgress?.files ?? NO_FILES,\n (files): CompletedUpload[] =>\n files.reduce<CompletedUpload[]>((completed, row) => {\n if (row.status === 'complete' && row.file && row.completedAt !== undefined) {\n completed.push({ asset: row.file, completedAt: row.completedAt });\n }\n\n return completed;\n }, [])\n);\n\n/**\n * Byte-weighted aggregate progress across the whole batch: `sum(uploadedBytes) / sum(size)`.\n *\n * Falls back to count-based progress (settled files / total files) when all sizes are\n * zero — e.g. URL-flow rows where the file size is unknown up front.\n */\nexport const selectAggregateProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number => {\n if (files.length === 0) return 0;\n\n const totalSize = files.reduce((sum, f) => sum + f.size, 0);\n\n if (totalSize === 0) {\n const settled = files.filter(\n (f) => f.status === 'complete' || f.status === 'error' || f.status === 'cancelled'\n ).length;\n return Math.round((settled / files.length) * 100);\n }\n\n const uploadedBytes = files.reduce((sum, f) => sum + f.uploadedBytes, 0);\n return Math.round((uploadedBytes / totalSize) * 100);\n }\n);\n\n/**\n * Whether to show byte-weighted `selectAggregateProgress` rather than `selectCountBasedProgress`.\n *\n * Only the flag: byte-weighting needs every size up front. A URL batch learns sizes one row\n * at a time, so weighting over the sizes known so far makes the header jump backwards at\n * every file boundary.\n */\nexport const selectReportsByteProgress = createSelector(\n (state: RootState) => state.uploadProgress.reportsByteProgress,\n (reportsByteProgress): boolean => reportsByteProgress\n);\n\n/**\n * Row-weighted progress for a batch whose sizes are not known up front (the URL flow).\n * Each row is worth `1 / total`: settled rows count fully and an in-flight row contributes\n * `uploadedBytes / size` once it reports bytes, so a multi-URL batch climbs smoothly to\n * 33 → 67 → 100 and never moves backwards.\n *\n * Returns `null` until something has moved — 0% is the frozen signal this flow exists to\n * remove, so the header stays indeterminate until there's real progress.\n */\nexport const selectCountBasedProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number | null => {\n const done = files.reduce((sum, f) => {\n if (f.status === 'complete' || f.status === 'error' || f.status === 'cancelled') {\n return sum + 1;\n }\n return f.size > 0 ? sum + Math.min(f.uploadedBytes / f.size, 1) : sum;\n }, 0);\n\n if (done === 0) {\n return null;\n }\n\n return Math.round((done / files.length) * 100);\n }\n);\n\n/**\n * Count-based metadata progress across the whole batch: `settled / expected`.\n *\n * Count-based rather than byte-weighted because the generation endpoint answers in one\n * go — there is no intermediate progress to weight.\n *\n * The denominator is every row *expected* to enter the phase, not just those that\n * already have. Generation is fired per file as each upload finishes, so counting only\n * started rows made the denominator grow mid-batch and the percentage jump backwards\n * (1/1 = 100%, then a second row starts and it drops to 1/2 = 50%), which flickered the\n * header subtitle on and off once per file.\n *\n * \"Expected\" is derived from upload outcome rather than from the AI-metadata flag:\n * - a row still uploading may yet enter the phase, so it counts toward the total;\n * - an errored or cancelled row never will, so it must not — otherwise a batch with\n * one failure could never reach 100%.\n *\n * Returns `null` when nothing has entered the phase and nothing is pending — i.e. AI\n * metadata is off, or the batch is done — so the header can hide the subtitle.\n */\nexport const selectMetadataProgress = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): number | null => {\n const started = files.filter((f) => f.metadataStatus !== undefined);\n\n // Nothing has entered the phase yet: with no started row there is no evidence AI\n // metadata is even enabled, so stay silent rather than showing a premature 0%.\n if (started.length === 0) return null;\n\n // Rows whose upload is still in flight are counted in the denominator so the\n // percentage only ever climbs as the batch progresses.\n const pending = files.filter(\n (f) => f.metadataStatus === undefined && (f.status === 'pending' || f.status === 'uploading')\n ).length;\n\n const expected = started.length + pending;\n const settled = started.filter((f) => f.metadataStatus !== 'generating').length;\n\n return Math.round((settled / expected) * 100);\n }\n);\n\n/**\n * Whether the metadata phase is still ongoing for the batch as a whole.\n *\n * The header uses this — not `selectMetadataProgress === 100` — to decide when to drop\n * the subtitle. Two distinct reasons the phase can be unfinished:\n * - a row is generating right now;\n * - no row is generating this instant, but rows are still uploading and will enter the\n * phase when they finish.\n *\n * The second clause is what keeps the subtitle stable. Generation for file N typically\n * finishes before file N+1 finishes uploading, so a naive \"is anything generating?\"\n * check goes false between every pair of files and blinks the subtitle out and back in.\n */\nexport const selectIsGeneratingMetadata = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): boolean => {\n if (files.some((f) => f.metadataStatus === 'generating')) return true;\n\n // Only bridge the gap if some row has already entered the phase — otherwise a batch\n // with AI metadata disabled would report the phase as ongoing for its whole upload.\n const hasStarted = files.some((f) => f.metadataStatus !== undefined);\n\n return hasStarted && files.some((f) => f.status === 'pending' || f.status === 'uploading');\n }\n);\n\n/**\n * How many rows reached each terminal metadata outcome, for the header's completion\n * message. `null` while the phase is unfinished — or was never entered at all — so the\n * caller has a single check for \"there is no settled outcome to report yet\".\n *\n * Counts are reported separately rather than collapsed into one total because they are\n * not interchangeable: only `generated` rows actually had metadata written, so only that\n * count can be claimed as a success. A batch of non-images settles entirely on `skipped`,\n * where \"generated on 0 files\" would be worse than saying nothing.\n */\nexport const selectMetadataOutcome = createSelector(\n (state: RootState) => state.uploadProgress.files,\n (files): { generated: number; skipped: number; failed: number } | null => {\n const started = files.filter((f) => f.metadataStatus !== undefined);\n\n if (started.length === 0) return null;\n\n // Mirrors `selectIsGeneratingMetadata`: the phase isn't over while a row is\n // generating, nor while a row is still uploading and has yet to enter it.\n const isOngoing =\n started.some((f) => f.metadataStatus === 'generating') ||\n files.some((f) => f.status === 'pending' || f.status === 'uploading');\n\n if (isOngoing) return null;\n\n return {\n generated: started.filter((f) => f.metadataStatus === 'generated').length,\n skipped: started.filter((f) => f.metadataStatus === 'skipped').length,\n failed: started.filter((f) => f.metadataStatus === 'failed').length,\n };\n }\n);\n\nexport const {\n openUploadProgress,\n appendUploadFiles,\n setFileUploading,\n setFileProgress,\n setFileComplete,\n setFileError,\n setFileMetadataGenerating,\n setFileMetadataResult,\n addUploadErrors,\n closeUploadProgress,\n toggleMinimize,\n cancelUpload,\n setUploadFailed,\n cancelFile,\n retryFile,\n retryCancelledFiles,\n} = uploadProgressSlice.actions;\n\n/**\n * The merge/reset switch. Errored and cancelled rows count as settled, so a\n * batch that finished badly is still replaced by the next drop.\n */\nexport const isUploadInFlight = (files: ReadonlyArray<{ status: FileProgressStatus }>): boolean =>\n files.some((f) => f.status === 'pending' || f.status === 'uploading');\n\nexport const uploadProgressReducer = uploadProgressSlice.reducer;\n"],"names":["initialState","isVisible","isMinimized","totalFiles","files","errors","uploadId","reportsByteProgress","uploadProgressSlice","createSlice","name","reducers","openUploadProgress","state","action","pendingFiles","payload","fileNames","map","index","status","size","fileSizes","uploadedBytes","owner","undefined","appendUploadFiles","offset","length","push","i","setFileUploading","setFileProgress","bytes","file","Math","min","setFileComplete","completedAt","setFileError","message","error","setFileMetadataGenerating","metadataStatus","setFileMetadataResult","addUploadErrors","closeUploadProgress","toggleMinimize","cancelUpload","setUploadFailed","cancelFile","retryFile","retryCancelledFiles","NO_FILES","selectCompletedUploads","createSelector","uploadProgress","reduce","completed","row","asset","selectAggregateProgress","totalSize","sum","f","settled","filter","round","selectReportsByteProgress","selectCountBasedProgress","done","selectMetadataProgress","started","pending","expected","selectIsGeneratingMetadata","some","hasStarted","selectMetadataOutcome","isOngoing","generated","skipped","failed","actions","isUploadInFlight","uploadProgressReducer","reducer"],"mappings":"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"}
@@ -4,6 +4,17 @@ var en = {
4
4
  "apiError.FileTooBig": "The file is too large to be uploaded. It exceeds the maximum request size allowed by the server.",
5
5
  "apiError.FolderContainsUnauthorizedAssetsError": "The selected folders contain assets that you do not have permission to delete.",
6
6
  "assets.uploaded": "{number, plural, one {# asset} other {# assets}} uploaded successfully",
7
+ "asset-picker.breadcrumbs.label": "Folder navigation",
8
+ "asset-picker.breadcrumbs.more": "Show more folders",
9
+ "asset-picker.confirm": "Confirm",
10
+ "asset-picker.selected.empty": "No asset selected yet.",
11
+ "asset-picker.tabs.browse": "Browse assets",
12
+ "asset-picker.tabs.label": "Asset picker tabs",
13
+ "asset-picker.tabs.selected": "Selected assets",
14
+ "asset-picker.title": "Add asset for {fieldName}",
15
+ "asset-picker.title.insert": "Add assets",
16
+ "editor-drop-zone.accept": "Drop to upload and insert",
17
+ "editor-drop-zone.reject": "You don't have permission to upload files",
7
18
  "asset-details.title": "File details",
8
19
  "asset-details.description": "Displays file information and metadata",
9
20
  "asset-details.fileInfo": "File info",
@@ -26,6 +37,7 @@ var en = {
26
37
  "asset-details.field.empty": "{label} is currently empty.",
27
38
  "asset-details.location.root": "Media Library",
28
39
  "asset-details.saveChanges": "Save changes",
40
+ "asset-details.unsaved.confirm": "You have unsaved changes, are you sure you want to close this file's details? Your changes will be lost.",
29
41
  "asset-details.delete.trigger": "Delete this file",
30
42
  "asset-details.delete.title": "Delete this media file?",
31
43
  "asset-details.delete.description": "This file cannot be recovered once deleted. If it is currently in use, linked content will break and image containers will be empty.",
@@ -79,6 +91,12 @@ var en = {
79
91
  "content-manager.input.add-asset.browse": "Browse library",
80
92
  "content-manager.input.add-asset.device": "Upload from device",
81
93
  "content-manager.input.add-asset.url": "Upload from URL",
94
+ "content-manager.input.actions.cancel": "Cancel upload of {name}",
95
+ "content-manager.input.actions.more": "More actions for {name}",
96
+ "content-manager.input.actions.remove-failed": "Remove",
97
+ "content-manager.input.actions.retry": "Retry uploading {name}",
98
+ "content-manager.input.placeholder": "Drag & drop an asset here",
99
+ "content-manager.input.status.uploading": "Uploading",
82
100
  "upload.generic-error": "An error occurred while uploading the file.",
83
101
  "upload.progress": "Upload progress",
84
102
  "upload.progress.description": "Shows upload progress and status",
@@ -261,6 +279,11 @@ var en = {
261
279
  "list.folder.select": "Select {name} folder",
262
280
  "list.folder.subtitle": "{folderCount, plural, one {# folder} other {# folders}}, {filesCount, plural, one {# asset} other {# assets}}",
263
281
  "list.folders.title": "Folders ({count})",
282
+ "list.item.reorder": "Reorder {name}",
283
+ "list.reorder.cancelled": "Reordering cancelled. {name} is back at position {position} of {count}.",
284
+ "list.reorder.dropped": "{name} dropped at position {position} of {count}.",
285
+ "list.reorder.moved": "{name} moved to position {position} of {count}.",
286
+ "list.reorder.picked-up": "Picked up {name}. Position {position} of {count}.",
264
287
  "list.folders.link-label": "Access folder",
265
288
  "mediaLibraryInput.actions.nextSlide": "Next slide",
266
289
  "mediaLibraryInput.actions.previousSlide": "Previous slide",
@@ -406,6 +429,7 @@ var en = {
406
429
  "sidebar.tree.actions": "Actions for {name}",
407
430
  "sidebar.tree.empty": "No folders yet",
408
431
  "sidebar.tree.loading": "Loading folders...",
432
+ "sidebar.tree.hidden-ancestors": "{count, plural, one {# parent folder} other {# parent folders}}",
409
433
  "sidebar.tree.error": "Could not load folders."
410
434
  };
411
435
 
@@ -1 +1 @@
1
- {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,6 +2,17 @@ var en = {
2
2
  "apiError.FileTooBig": "The file is too large to be uploaded. It exceeds the maximum request size allowed by the server.",
3
3
  "apiError.FolderContainsUnauthorizedAssetsError": "The selected folders contain assets that you do not have permission to delete.",
4
4
  "assets.uploaded": "{number, plural, one {# asset} other {# assets}} uploaded successfully",
5
+ "asset-picker.breadcrumbs.label": "Folder navigation",
6
+ "asset-picker.breadcrumbs.more": "Show more folders",
7
+ "asset-picker.confirm": "Confirm",
8
+ "asset-picker.selected.empty": "No asset selected yet.",
9
+ "asset-picker.tabs.browse": "Browse assets",
10
+ "asset-picker.tabs.label": "Asset picker tabs",
11
+ "asset-picker.tabs.selected": "Selected assets",
12
+ "asset-picker.title": "Add asset for {fieldName}",
13
+ "asset-picker.title.insert": "Add assets",
14
+ "editor-drop-zone.accept": "Drop to upload and insert",
15
+ "editor-drop-zone.reject": "You don't have permission to upload files",
5
16
  "asset-details.title": "File details",
6
17
  "asset-details.description": "Displays file information and metadata",
7
18
  "asset-details.fileInfo": "File info",
@@ -24,6 +35,7 @@ var en = {
24
35
  "asset-details.field.empty": "{label} is currently empty.",
25
36
  "asset-details.location.root": "Media Library",
26
37
  "asset-details.saveChanges": "Save changes",
38
+ "asset-details.unsaved.confirm": "You have unsaved changes, are you sure you want to close this file's details? Your changes will be lost.",
27
39
  "asset-details.delete.trigger": "Delete this file",
28
40
  "asset-details.delete.title": "Delete this media file?",
29
41
  "asset-details.delete.description": "This file cannot be recovered once deleted. If it is currently in use, linked content will break and image containers will be empty.",
@@ -77,6 +89,12 @@ var en = {
77
89
  "content-manager.input.add-asset.browse": "Browse library",
78
90
  "content-manager.input.add-asset.device": "Upload from device",
79
91
  "content-manager.input.add-asset.url": "Upload from URL",
92
+ "content-manager.input.actions.cancel": "Cancel upload of {name}",
93
+ "content-manager.input.actions.more": "More actions for {name}",
94
+ "content-manager.input.actions.remove-failed": "Remove",
95
+ "content-manager.input.actions.retry": "Retry uploading {name}",
96
+ "content-manager.input.placeholder": "Drag & drop an asset here",
97
+ "content-manager.input.status.uploading": "Uploading",
80
98
  "upload.generic-error": "An error occurred while uploading the file.",
81
99
  "upload.progress": "Upload progress",
82
100
  "upload.progress.description": "Shows upload progress and status",
@@ -259,6 +277,11 @@ var en = {
259
277
  "list.folder.select": "Select {name} folder",
260
278
  "list.folder.subtitle": "{folderCount, plural, one {# folder} other {# folders}}, {filesCount, plural, one {# asset} other {# assets}}",
261
279
  "list.folders.title": "Folders ({count})",
280
+ "list.item.reorder": "Reorder {name}",
281
+ "list.reorder.cancelled": "Reordering cancelled. {name} is back at position {position} of {count}.",
282
+ "list.reorder.dropped": "{name} dropped at position {position} of {count}.",
283
+ "list.reorder.moved": "{name} moved to position {position} of {count}.",
284
+ "list.reorder.picked-up": "Picked up {name}. Position {position} of {count}.",
262
285
  "list.folders.link-label": "Access folder",
263
286
  "mediaLibraryInput.actions.nextSlide": "Next slide",
264
287
  "mediaLibraryInput.actions.previousSlide": "Previous slide",
@@ -404,6 +427,7 @@ var en = {
404
427
  "sidebar.tree.actions": "Actions for {name}",
405
428
  "sidebar.tree.empty": "No folders yet",
406
429
  "sidebar.tree.loading": "Loading folders...",
430
+ "sidebar.tree.hidden-ancestors": "{count, plural, one {# parent folder} other {# parent folders}}",
407
431
  "sidebar.tree.error": "Could not load folders."
408
432
  };
409
433
 
@@ -1 +1 @@
1
- {"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * The chain of folders from the library root down to `targetId`, inclusive, or
5
+ * `null` when the folder is not in the tree (deleted, or not loaded yet).
6
+ */ const findFolderPath = (nodes, targetId, trail = [])=>{
7
+ for (const node of nodes){
8
+ const nextTrail = node.id != null ? [
9
+ ...trail,
10
+ node
11
+ ] : trail;
12
+ if (node.id === targetId) {
13
+ return nextTrail;
14
+ }
15
+ if (node.children?.length) {
16
+ const found = findFolderPath(node.children, targetId, nextTrail);
17
+ if (found !== null) {
18
+ return found;
19
+ }
20
+ }
21
+ }
22
+ return null;
23
+ };
24
+
25
+ exports.findFolderPath = findFolderPath;
26
+ //# sourceMappingURL=findFolderPath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findFolderPath.js","sources":["../../../admin/src/utils/findFolderPath.ts"],"sourcesContent":["import type { FolderNode } from '../../../shared/contracts/folders';\n\n/**\n * The chain of folders from the library root down to `targetId`, inclusive, or\n * `null` when the folder is not in the tree (deleted, or not loaded yet).\n */\nexport const findFolderPath = (\n nodes: FolderNode[],\n targetId: number,\n trail: FolderNode[] = []\n): FolderNode[] | null => {\n for (const node of nodes) {\n const nextTrail = node.id != null ? [...trail, node] : trail;\n\n if (node.id === targetId) {\n return nextTrail;\n }\n\n if (node.children?.length) {\n const found = findFolderPath(node.children, targetId, nextTrail);\n\n if (found !== null) {\n return found;\n }\n }\n }\n\n return null;\n};\n"],"names":["findFolderPath","nodes","targetId","trail","node","nextTrail","id","children","length","found"],"mappings":";;AAEA;;;AAGC,IACM,MAAMA,cAAAA,GAAiB,CAC5BC,KAAAA,EACAC,QAAAA,EACAC,QAAsB,EAAE,GAAA;IAExB,KAAK,MAAMC,QAAQH,KAAAA,CAAO;AACxB,QAAA,MAAMI,SAAAA,GAAYD,IAAAA,CAAKE,EAAE,IAAI,IAAA,GAAO;AAAIH,YAAAA,GAAAA,KAAAA;AAAOC,YAAAA;SAAK,GAAGD,KAAAA;QAEvD,IAAIC,IAAAA,CAAKE,EAAE,KAAKJ,QAAAA,EAAU;YACxB,OAAOG,SAAAA;AACT,QAAA;QAEA,IAAID,IAAAA,CAAKG,QAAQ,EAAEC,MAAAA,EAAQ;AACzB,YAAA,MAAMC,KAAAA,GAAQT,cAAAA,CAAeI,IAAAA,CAAKG,QAAQ,EAAEL,QAAAA,EAAUG,SAAAA,CAAAA;AAEtD,YAAA,IAAII,UAAU,IAAA,EAAM;gBAClB,OAAOA,KAAAA;AACT,YAAA;AACF,QAAA;AACF,IAAA;IAEA,OAAO,IAAA;AACT;;;;"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The chain of folders from the library root down to `targetId`, inclusive, or
3
+ * `null` when the folder is not in the tree (deleted, or not loaded yet).
4
+ */ const findFolderPath = (nodes, targetId, trail = [])=>{
5
+ for (const node of nodes){
6
+ const nextTrail = node.id != null ? [
7
+ ...trail,
8
+ node
9
+ ] : trail;
10
+ if (node.id === targetId) {
11
+ return nextTrail;
12
+ }
13
+ if (node.children?.length) {
14
+ const found = findFolderPath(node.children, targetId, nextTrail);
15
+ if (found !== null) {
16
+ return found;
17
+ }
18
+ }
19
+ }
20
+ return null;
21
+ };
22
+
23
+ export { findFolderPath };
24
+ //# sourceMappingURL=findFolderPath.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findFolderPath.mjs","sources":["../../../admin/src/utils/findFolderPath.ts"],"sourcesContent":["import type { FolderNode } from '../../../shared/contracts/folders';\n\n/**\n * The chain of folders from the library root down to `targetId`, inclusive, or\n * `null` when the folder is not in the tree (deleted, or not loaded yet).\n */\nexport const findFolderPath = (\n nodes: FolderNode[],\n targetId: number,\n trail: FolderNode[] = []\n): FolderNode[] | null => {\n for (const node of nodes) {\n const nextTrail = node.id != null ? [...trail, node] : trail;\n\n if (node.id === targetId) {\n return nextTrail;\n }\n\n if (node.children?.length) {\n const found = findFolderPath(node.children, targetId, nextTrail);\n\n if (found !== null) {\n return found;\n }\n }\n }\n\n return null;\n};\n"],"names":["findFolderPath","nodes","targetId","trail","node","nextTrail","id","children","length","found"],"mappings":"AAEA;;;AAGC,IACM,MAAMA,cAAAA,GAAiB,CAC5BC,KAAAA,EACAC,QAAAA,EACAC,QAAsB,EAAE,GAAA;IAExB,KAAK,MAAMC,QAAQH,KAAAA,CAAO;AACxB,QAAA,MAAMI,SAAAA,GAAYD,IAAAA,CAAKE,EAAE,IAAI,IAAA,GAAO;AAAIH,YAAAA,GAAAA,KAAAA;AAAOC,YAAAA;SAAK,GAAGD,KAAAA;QAEvD,IAAIC,IAAAA,CAAKE,EAAE,KAAKJ,QAAAA,EAAU;YACxB,OAAOG,SAAAA;AACT,QAAA;QAEA,IAAID,IAAAA,CAAKG,QAAQ,EAAEC,MAAAA,EAAQ;AACzB,YAAA,MAAMC,KAAAA,GAAQT,cAAAA,CAAeI,IAAAA,CAAKG,QAAQ,EAAEL,QAAAA,EAAUG,SAAAA,CAAAA;AAEtD,YAAA,IAAII,UAAU,IAAA,EAAM;gBAClB,OAAOA,KAAAA;AACT,YAAA;AACF,QAAA;AACF,IAAA;IAEA,OAAO,IAAA;AACT;;;;"}
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+
3
+ var enums = require('../enums.js');
4
+
5
+ const MEDIA_KIND_BY_MIME_FAMILY = {
6
+ [enums.ASSET_TYPES.Image]: 'images',
7
+ [enums.ASSET_TYPES.Video]: 'videos',
8
+ [enums.ASSET_TYPES.Audio]: 'audios'
9
+ };
10
+ /**
11
+ * Whether an asset fits a media field's `allowedTypes`, by the same rule as the
12
+ * legacy picker: only the MIME family (before the `/`) counts, and `files`
13
+ * covers everything that is not an image, a video or an audio file.
14
+ *
15
+ * Not `typeFromMime`: it matches anywhere in the MIME type, so
16
+ * `application/x-iso9660-image` would count as an image.
17
+ *
18
+ * No restriction (missing or empty) allows everything.
19
+ */ const isAllowedAssetType = (allowedTypes, mime)=>{
20
+ const kinds = allowedTypes == null ? [] : [
21
+ allowedTypes
22
+ ].flat();
23
+ if (kinds.length === 0) {
24
+ return true;
25
+ }
26
+ if (!mime) {
27
+ return false;
28
+ }
29
+ return kinds.includes(MEDIA_KIND_BY_MIME_FAMILY[mime.split('/')[0]] ?? 'files');
30
+ };
31
+
32
+ exports.isAllowedAssetType = isAllowedAssetType;
33
+ //# sourceMappingURL=isAllowedAssetType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isAllowedAssetType.js","sources":["../../../admin/src/utils/isAllowedAssetType.ts"],"sourcesContent":["import { ASSET_TYPES } from '../enums';\n\nimport type { Schema } from '@strapi/types';\n\n/** A media field's `allowedTypes`, exactly as its schema can hold it. */\nexport type MediaAllowedTypes =\n Schema.Attribute.MediaProperties<Schema.Attribute.MediaKind>['allowedTypes'];\n\nconst MEDIA_KIND_BY_MIME_FAMILY: Record<string, Schema.Attribute.MediaKind> = {\n [ASSET_TYPES.Image]: 'images',\n [ASSET_TYPES.Video]: 'videos',\n [ASSET_TYPES.Audio]: 'audios',\n};\n\n/**\n * Whether an asset fits a media field's `allowedTypes`, by the same rule as the\n * legacy picker: only the MIME family (before the `/`) counts, and `files`\n * covers everything that is not an image, a video or an audio file.\n *\n * Not `typeFromMime`: it matches anywhere in the MIME type, so\n * `application/x-iso9660-image` would count as an image.\n *\n * No restriction (missing or empty) allows everything.\n */\nexport const isAllowedAssetType = (\n allowedTypes: MediaAllowedTypes | null,\n mime: string | null | undefined\n): boolean => {\n const kinds = allowedTypes == null ? [] : [allowedTypes].flat();\n\n if (kinds.length === 0) {\n return true;\n }\n\n if (!mime) {\n return false;\n }\n\n return kinds.includes(MEDIA_KIND_BY_MIME_FAMILY[mime.split('/')[0]] ?? 'files');\n};\n"],"names":["MEDIA_KIND_BY_MIME_FAMILY","ASSET_TYPES","Image","Video","Audio","isAllowedAssetType","allowedTypes","mime","kinds","flat","length","includes","split"],"mappings":";;;;AAQA,MAAMA,yBAAAA,GAAwE;IAC5E,CAACC,iBAAAA,CAAYC,KAAK,GAAG,QAAA;IACrB,CAACD,iBAAAA,CAAYE,KAAK,GAAG,QAAA;IACrB,CAACF,iBAAAA,CAAYG,KAAK,GAAG;AACvB,CAAA;AAEA;;;;;;;;;AASC,IACM,MAAMC,kBAAAA,GAAqB,CAChCC,YAAAA,EACAC,IAAAA,GAAAA;AAEA,IAAA,MAAMC,KAAAA,GAAQF,YAAAA,IAAgB,IAAA,GAAO,EAAE,GAAG;AAACA,QAAAA;AAAa,KAAA,CAACG,IAAI,EAAA;IAE7D,IAAID,KAAAA,CAAME,MAAM,KAAK,CAAA,EAAG;QACtB,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,IAAI,CAACH,IAAAA,EAAM;QACT,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,OAAOC,KAAAA,CAAMG,QAAQ,CAACX,yBAAyB,CAACO,IAAAA,CAAKK,KAAK,CAAC,GAAA,CAAI,CAAC,CAAA,CAAE,CAAC,IAAI,OAAA,CAAA;AACzE;;;;"}
@@ -0,0 +1,31 @@
1
+ import { ASSET_TYPES } from '../enums.mjs';
2
+
3
+ const MEDIA_KIND_BY_MIME_FAMILY = {
4
+ [ASSET_TYPES.Image]: 'images',
5
+ [ASSET_TYPES.Video]: 'videos',
6
+ [ASSET_TYPES.Audio]: 'audios'
7
+ };
8
+ /**
9
+ * Whether an asset fits a media field's `allowedTypes`, by the same rule as the
10
+ * legacy picker: only the MIME family (before the `/`) counts, and `files`
11
+ * covers everything that is not an image, a video or an audio file.
12
+ *
13
+ * Not `typeFromMime`: it matches anywhere in the MIME type, so
14
+ * `application/x-iso9660-image` would count as an image.
15
+ *
16
+ * No restriction (missing or empty) allows everything.
17
+ */ const isAllowedAssetType = (allowedTypes, mime)=>{
18
+ const kinds = allowedTypes == null ? [] : [
19
+ allowedTypes
20
+ ].flat();
21
+ if (kinds.length === 0) {
22
+ return true;
23
+ }
24
+ if (!mime) {
25
+ return false;
26
+ }
27
+ return kinds.includes(MEDIA_KIND_BY_MIME_FAMILY[mime.split('/')[0]] ?? 'files');
28
+ };
29
+
30
+ export { isAllowedAssetType };
31
+ //# sourceMappingURL=isAllowedAssetType.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isAllowedAssetType.mjs","sources":["../../../admin/src/utils/isAllowedAssetType.ts"],"sourcesContent":["import { ASSET_TYPES } from '../enums';\n\nimport type { Schema } from '@strapi/types';\n\n/** A media field's `allowedTypes`, exactly as its schema can hold it. */\nexport type MediaAllowedTypes =\n Schema.Attribute.MediaProperties<Schema.Attribute.MediaKind>['allowedTypes'];\n\nconst MEDIA_KIND_BY_MIME_FAMILY: Record<string, Schema.Attribute.MediaKind> = {\n [ASSET_TYPES.Image]: 'images',\n [ASSET_TYPES.Video]: 'videos',\n [ASSET_TYPES.Audio]: 'audios',\n};\n\n/**\n * Whether an asset fits a media field's `allowedTypes`, by the same rule as the\n * legacy picker: only the MIME family (before the `/`) counts, and `files`\n * covers everything that is not an image, a video or an audio file.\n *\n * Not `typeFromMime`: it matches anywhere in the MIME type, so\n * `application/x-iso9660-image` would count as an image.\n *\n * No restriction (missing or empty) allows everything.\n */\nexport const isAllowedAssetType = (\n allowedTypes: MediaAllowedTypes | null,\n mime: string | null | undefined\n): boolean => {\n const kinds = allowedTypes == null ? [] : [allowedTypes].flat();\n\n if (kinds.length === 0) {\n return true;\n }\n\n if (!mime) {\n return false;\n }\n\n return kinds.includes(MEDIA_KIND_BY_MIME_FAMILY[mime.split('/')[0]] ?? 'files');\n};\n"],"names":["MEDIA_KIND_BY_MIME_FAMILY","ASSET_TYPES","Image","Video","Audio","isAllowedAssetType","allowedTypes","mime","kinds","flat","length","includes","split"],"mappings":";;AAQA,MAAMA,yBAAAA,GAAwE;IAC5E,CAACC,WAAAA,CAAYC,KAAK,GAAG,QAAA;IACrB,CAACD,WAAAA,CAAYE,KAAK,GAAG,QAAA;IACrB,CAACF,WAAAA,CAAYG,KAAK,GAAG;AACvB,CAAA;AAEA;;;;;;;;;AASC,IACM,MAAMC,kBAAAA,GAAqB,CAChCC,YAAAA,EACAC,IAAAA,GAAAA;AAEA,IAAA,MAAMC,KAAAA,GAAQF,YAAAA,IAAgB,IAAA,GAAO,EAAE,GAAG;AAACA,QAAAA;AAAa,KAAA,CAACG,IAAI,EAAA;IAE7D,IAAID,KAAAA,CAAME,MAAM,KAAK,CAAA,EAAG;QACtB,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,IAAI,CAACH,IAAAA,EAAM;QACT,OAAO,KAAA;AACT,IAAA;AAEA,IAAA,OAAOC,KAAAA,CAAMG,QAAQ,CAACX,yBAAyB,CAACO,IAAAA,CAAKK,KAAK,CAAC,GAAA,CAAI,CAAC,CAAA,CAAE,CAAC,IAAI,OAAA,CAAA;AACzE;;;;"}