@strapi/upload 5.51.1 → 5.52.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 (369) hide show
  1. package/dist/admin/components/AssetCard/VideoPreview.js +1 -1
  2. package/dist/admin/components/AssetCard/VideoPreview.js.map +1 -1
  3. package/dist/admin/components/AssetCard/VideoPreview.mjs +1 -1
  4. package/dist/admin/components/AssetCard/VideoPreview.mjs.map +1 -1
  5. package/dist/admin/components/TableList/TableList.js +1 -1
  6. package/dist/admin/components/TableList/TableList.js.map +1 -1
  7. package/dist/admin/components/TableList/TableList.mjs +1 -1
  8. package/dist/admin/components/TableList/TableList.mjs.map +1 -1
  9. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +21 -4
  10. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
  11. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +21 -4
  12. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
  13. package/dist/admin/future/App.js +3 -3
  14. package/dist/admin/future/App.js.map +1 -1
  15. package/dist/admin/future/App.mjs +4 -4
  16. package/dist/admin/future/App.mjs.map +1 -1
  17. package/dist/admin/future/components/BetaNotice.js +72 -0
  18. package/dist/admin/future/components/BetaNotice.js.map +1 -0
  19. package/dist/admin/future/components/BetaNotice.mjs +70 -0
  20. package/dist/admin/future/components/BetaNotice.mjs.map +1 -0
  21. package/dist/admin/future/components/Drawer.js +18 -3
  22. package/dist/admin/future/components/Drawer.js.map +1 -1
  23. package/dist/admin/future/components/Drawer.mjs +18 -3
  24. package/dist/admin/future/components/Drawer.mjs.map +1 -1
  25. package/dist/admin/future/components/UploadProgressDialog.js +200 -27
  26. package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
  27. package/dist/admin/future/components/UploadProgressDialog.mjs +203 -30
  28. package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
  29. package/dist/admin/future/hooks/useAIMetadataEnabled.js +39 -0
  30. package/dist/admin/future/hooks/useAIMetadataEnabled.js.map +1 -0
  31. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs +37 -0
  32. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs.map +1 -0
  33. package/dist/admin/future/hooks/useMediaLibraryPermissions.js +35 -0
  34. package/dist/admin/future/hooks/useMediaLibraryPermissions.js.map +1 -0
  35. package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs +33 -0
  36. package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs.map +1 -0
  37. package/dist/admin/future/pages/Assets/AssetsPage.js +453 -170
  38. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/AssetsPage.mjs +454 -171
  40. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js +46 -0
  42. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js.map +1 -0
  43. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs +44 -0
  44. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs.map +1 -0
  45. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +325 -0
  46. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -0
  47. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +323 -0
  48. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -0
  49. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +110 -46
  50. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
  51. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +110 -46
  52. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
  53. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +95 -67
  54. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  55. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +95 -68
  56. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  57. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +94 -26
  58. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  59. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +96 -28
  60. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  61. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +112 -0
  62. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -0
  63. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +110 -0
  64. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -0
  65. package/dist/admin/future/pages/Assets/components/AssetsTable.js +172 -56
  66. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  67. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +175 -59
  68. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  69. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +188 -138
  70. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
  71. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +191 -141
  72. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
  73. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +123 -76
  74. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -1
  75. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +126 -79
  76. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -1
  77. package/dist/admin/future/pages/Assets/components/BusyOverlay.js +36 -0
  78. package/dist/admin/future/pages/Assets/components/BusyOverlay.js.map +1 -0
  79. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs +34 -0
  80. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs.map +1 -0
  81. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js +193 -0
  82. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js.map +1 -0
  83. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs +191 -0
  84. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs.map +1 -0
  85. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js +131 -0
  86. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js.map +1 -0
  87. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs +129 -0
  88. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs.map +1 -0
  89. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +45 -18
  90. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
  91. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +46 -19
  92. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
  93. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +28 -31
  94. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -1
  95. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +28 -31
  96. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -1
  97. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +10 -15
  98. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
  99. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +10 -15
  100. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
  101. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js +13 -3
  102. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
  103. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs +13 -3
  104. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
  105. package/dist/admin/future/pages/Assets/components/EmptyState.js +62 -3
  106. package/dist/admin/future/pages/Assets/components/EmptyState.js.map +1 -1
  107. package/dist/admin/future/pages/Assets/components/EmptyState.mjs +62 -4
  108. package/dist/admin/future/pages/Assets/components/EmptyState.mjs.map +1 -1
  109. package/dist/admin/future/pages/Assets/components/FilterBadges.js +417 -0
  110. package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -0
  111. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +415 -0
  112. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -0
  113. package/dist/admin/future/pages/Assets/components/FilterMenu.js +453 -0
  114. package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -0
  115. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +447 -0
  116. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -0
  117. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +144 -0
  118. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -0
  119. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +142 -0
  120. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -0
  121. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.js → FolderFormDialog.js} +50 -16
  122. package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -0
  123. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.mjs → FolderFormDialog.mjs} +52 -18
  124. package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -0
  125. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +125 -148
  126. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  127. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +127 -150
  128. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  129. package/dist/admin/future/pages/Assets/components/SortMenu.js +21 -32
  130. package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
  131. package/dist/admin/future/pages/Assets/components/SortMenu.mjs +22 -33
  132. package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
  133. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js +40 -0
  134. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js.map +1 -0
  135. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs +38 -0
  136. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs.map +1 -0
  137. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +21 -5
  138. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  139. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +21 -5
  140. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  141. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js +47 -0
  142. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js.map +1 -0
  143. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs +44 -0
  144. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs.map +1 -0
  145. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js +33 -12
  146. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  147. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs +33 -12
  148. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  149. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +222 -45
  150. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
  151. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +223 -46
  152. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
  153. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js +75 -0
  154. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js.map +1 -0
  155. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs +73 -0
  156. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs.map +1 -0
  157. package/dist/admin/future/pages/Assets/hooks/useListFilters.js +168 -0
  158. package/dist/admin/future/pages/Assets/hooks/useListFilters.js.map +1 -0
  159. package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs +162 -0
  160. package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs.map +1 -0
  161. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js +201 -0
  162. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js.map +1 -0
  163. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs +198 -0
  164. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs.map +1 -0
  165. package/dist/admin/future/pages/Assets/utils/listQueryKey.js +2 -2
  166. package/dist/admin/future/pages/Assets/utils/listQueryKey.js.map +1 -1
  167. package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs +2 -2
  168. package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs.map +1 -1
  169. package/dist/admin/future/services/api.js +187 -28
  170. package/dist/admin/future/services/api.js.map +1 -1
  171. package/dist/admin/future/services/api.mjs +187 -30
  172. package/dist/admin/future/services/api.mjs.map +1 -1
  173. package/dist/admin/future/services/assets.js +40 -17
  174. package/dist/admin/future/services/assets.js.map +1 -1
  175. package/dist/admin/future/services/assets.mjs +40 -17
  176. package/dist/admin/future/services/assets.mjs.map +1 -1
  177. package/dist/admin/future/services/folders.js +66 -19
  178. package/dist/admin/future/services/folders.js.map +1 -1
  179. package/dist/admin/future/services/folders.mjs +66 -20
  180. package/dist/admin/future/services/folders.mjs.map +1 -1
  181. package/dist/admin/future/services/settings.js +10 -3
  182. package/dist/admin/future/services/settings.js.map +1 -1
  183. package/dist/admin/future/services/settings.mjs +10 -3
  184. package/dist/admin/future/services/settings.mjs.map +1 -1
  185. package/dist/admin/future/store/uploadProgress.js +109 -2
  186. package/dist/admin/future/store/uploadProgress.js.map +1 -1
  187. package/dist/admin/future/store/uploadProgress.mjs +105 -3
  188. package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
  189. package/dist/admin/future/utils/buildDragSetFromSelection.js +7 -5
  190. package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -1
  191. package/dist/admin/future/utils/buildDragSetFromSelection.mjs +7 -5
  192. package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -1
  193. package/dist/admin/future/utils/formatMoveSuccessMessage.js +12 -1
  194. package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -1
  195. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +12 -1
  196. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -1
  197. package/dist/admin/future/utils/getRelationId.js +24 -0
  198. package/dist/admin/future/utils/getRelationId.js.map +1 -0
  199. package/dist/admin/future/utils/getRelationId.mjs +22 -0
  200. package/dist/admin/future/utils/getRelationId.mjs.map +1 -0
  201. package/dist/admin/future/utils/isEventFromWithin.js +14 -0
  202. package/dist/admin/future/utils/isEventFromWithin.js.map +1 -0
  203. package/dist/admin/future/utils/isEventFromWithin.mjs +12 -0
  204. package/dist/admin/future/utils/isEventFromWithin.mjs.map +1 -0
  205. package/dist/admin/future/utils/itemLocations.js +40 -0
  206. package/dist/admin/future/utils/itemLocations.js.map +1 -0
  207. package/dist/admin/future/utils/itemLocations.mjs +36 -0
  208. package/dist/admin/future/utils/itemLocations.mjs.map +1 -0
  209. package/dist/admin/future/utils/itemSource.js +36 -0
  210. package/dist/admin/future/utils/itemSource.js.map +1 -0
  211. package/dist/admin/future/utils/itemSource.mjs +32 -0
  212. package/dist/admin/future/utils/itemSource.mjs.map +1 -0
  213. package/dist/admin/future/utils/searchQueryParam.js +11 -0
  214. package/dist/admin/future/utils/searchQueryParam.js.map +1 -0
  215. package/dist/admin/future/utils/searchQueryParam.mjs +9 -0
  216. package/dist/admin/future/utils/searchQueryParam.mjs.map +1 -0
  217. package/dist/admin/hooks/useSelectionState.js +2 -4
  218. package/dist/admin/hooks/useSelectionState.js.map +1 -1
  219. package/dist/admin/hooks/useSelectionState.mjs +2 -4
  220. package/dist/admin/hooks/useSelectionState.mjs.map +1 -1
  221. package/dist/admin/index.js +11 -17
  222. package/dist/admin/index.js.map +1 -1
  223. package/dist/admin/index.mjs +12 -18
  224. package/dist/admin/index.mjs.map +1 -1
  225. package/dist/admin/shared/constants.js +43 -0
  226. package/dist/admin/shared/constants.js.map +1 -0
  227. package/dist/admin/shared/constants.mjs +38 -0
  228. package/dist/admin/shared/constants.mjs.map +1 -0
  229. package/dist/admin/src/future/App.d.ts +1 -1
  230. package/dist/admin/src/future/components/BetaNotice.d.ts +11 -0
  231. package/dist/admin/src/future/components/Drawer.d.ts +5 -1
  232. package/dist/admin/src/future/hooks/useAIMetadataEnabled.d.ts +26 -0
  233. package/dist/admin/src/future/hooks/useMediaLibraryPermissions.d.ts +21 -0
  234. package/dist/admin/src/future/pages/Assets/components/ActionsMenuContent.d.ts +33 -0
  235. package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +24 -0
  236. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.d.ts +7 -1
  237. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +16 -0
  238. package/dist/admin/src/future/pages/Assets/components/AssetsSearchInput.d.ts +5 -0
  239. package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +21 -1
  240. package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +17 -6
  241. package/dist/admin/src/future/pages/Assets/components/BusyOverlay.d.ts +9 -0
  242. package/dist/admin/src/future/pages/Assets/components/DateRangeCalendar.d.ts +8 -0
  243. package/dist/admin/src/future/pages/Assets/components/DeleteItemsDialog.d.ts +27 -0
  244. package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +8 -1
  245. package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +18 -3
  246. package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +2 -1
  247. package/dist/admin/src/future/pages/Assets/components/DropZone/UploadDropZoneContext.d.ts +8 -1
  248. package/dist/admin/src/future/pages/Assets/components/EmptyState.d.ts +18 -1
  249. package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +8 -0
  250. package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +26 -0
  251. package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +20 -0
  252. package/dist/admin/src/future/pages/Assets/components/FolderFormDialog.d.ts +16 -0
  253. package/dist/admin/src/future/pages/Assets/components/FolderTree/FolderTree.d.ts +13 -4
  254. package/dist/admin/src/future/pages/Assets/components/SortMenu.d.ts +6 -0
  255. package/dist/admin/src/future/pages/Assets/hooks/useAssetSearch.d.ts +12 -0
  256. package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +8 -1
  257. package/dist/admin/src/future/pages/Assets/hooks/useBusyAssets.d.ts +38 -0
  258. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +27 -3
  259. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteScrollSentinel.d.ts +41 -0
  260. package/dist/admin/src/future/pages/Assets/hooks/useListFilters.d.ts +69 -0
  261. package/dist/admin/src/future/pages/Assets/utils/buildAssetFilters.d.ts +46 -0
  262. package/dist/admin/src/future/pages/Assets/utils/listQueryKey.d.ts +3 -4
  263. package/dist/admin/src/future/services/api.d.ts +53 -5
  264. package/dist/admin/src/future/services/assets.d.ts +9 -1
  265. package/dist/admin/src/future/services/folders.d.ts +9 -1
  266. package/dist/admin/src/future/services/settings.d.ts +2 -2
  267. package/dist/admin/src/future/store/uploadProgress.d.ts +83 -1
  268. package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +4 -3
  269. package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +7 -1
  270. package/dist/admin/src/future/utils/getRelationId.d.ts +11 -0
  271. package/dist/admin/src/future/utils/isEventFromWithin.d.ts +11 -0
  272. package/dist/admin/src/future/utils/itemLocations.d.ts +31 -0
  273. package/dist/admin/src/future/utils/itemSource.d.ts +22 -0
  274. package/dist/admin/src/future/utils/searchQueryParam.d.ts +7 -0
  275. package/dist/admin/src/hooks/useAiAvailability.d.ts +1 -1
  276. package/dist/admin/src/hooks/useEditAsset.d.ts +4 -4
  277. package/dist/admin/src/hooks/useEditFolder.d.ts +4 -4
  278. package/dist/admin/src/hooks/useSettings.d.ts +1 -0
  279. package/dist/admin/src/hooks/useTracking.d.ts +1 -1
  280. package/dist/admin/src/hooks/useUpload.d.ts +1 -1
  281. package/dist/admin/translations/en.json.js +73 -2
  282. package/dist/admin/translations/en.json.js.map +1 -1
  283. package/dist/admin/translations/en.json.mjs +73 -2
  284. package/dist/admin/translations/en.json.mjs.map +1 -1
  285. package/dist/admin/utils/urlYupSchema.js +33 -9
  286. package/dist/admin/utils/urlYupSchema.js.map +1 -1
  287. package/dist/admin/utils/urlYupSchema.mjs +33 -9
  288. package/dist/admin/utils/urlYupSchema.mjs.map +1 -1
  289. package/dist/server/config.js +13 -5
  290. package/dist/server/config.js.map +1 -1
  291. package/dist/server/config.mjs +13 -5
  292. package/dist/server/config.mjs.map +1 -1
  293. package/dist/server/constants.js.map +1 -1
  294. package/dist/server/constants.mjs.map +1 -1
  295. package/dist/server/controllers/admin-file.js +30 -0
  296. package/dist/server/controllers/admin-file.js.map +1 -1
  297. package/dist/server/controllers/admin-file.mjs +30 -0
  298. package/dist/server/controllers/admin-file.mjs.map +1 -1
  299. package/dist/server/controllers/admin-settings.js +20 -2
  300. package/dist/server/controllers/admin-settings.js.map +1 -1
  301. package/dist/server/controllers/admin-settings.mjs +21 -3
  302. package/dist/server/controllers/admin-settings.mjs.map +1 -1
  303. package/dist/server/controllers/content-api.js +1 -2
  304. package/dist/server/controllers/content-api.js.map +1 -1
  305. package/dist/server/controllers/content-api.mjs +2 -2
  306. package/dist/server/controllers/content-api.mjs.map +1 -1
  307. package/dist/server/controllers/validation/admin/ai-metadata.js +12 -0
  308. package/dist/server/controllers/validation/admin/ai-metadata.js.map +1 -0
  309. package/dist/server/controllers/validation/admin/ai-metadata.mjs +10 -0
  310. package/dist/server/controllers/validation/admin/ai-metadata.mjs.map +1 -0
  311. package/dist/server/controllers/validation/admin/settings.js +4 -1
  312. package/dist/server/controllers/validation/admin/settings.js.map +1 -1
  313. package/dist/server/controllers/validation/admin/settings.mjs +1 -1
  314. package/dist/server/controllers/validation/admin/settings.mjs.map +1 -1
  315. package/dist/server/routes/admin.js +18 -0
  316. package/dist/server/routes/admin.js.map +1 -1
  317. package/dist/server/routes/admin.mjs +18 -0
  318. package/dist/server/routes/admin.mjs.map +1 -1
  319. package/dist/server/services/ai-metadata.js +108 -11
  320. package/dist/server/services/ai-metadata.js.map +1 -1
  321. package/dist/server/services/ai-metadata.mjs +108 -11
  322. package/dist/server/services/ai-metadata.mjs.map +1 -1
  323. package/dist/server/services/file.js +86 -13
  324. package/dist/server/services/file.js.map +1 -1
  325. package/dist/server/services/file.mjs +87 -14
  326. package/dist/server/services/file.mjs.map +1 -1
  327. package/dist/server/services/image-manipulation.js +4 -4
  328. package/dist/server/services/image-manipulation.js.map +1 -1
  329. package/dist/server/services/image-manipulation.mjs +4 -4
  330. package/dist/server/services/image-manipulation.mjs.map +1 -1
  331. package/dist/server/shared/constants.js +43 -0
  332. package/dist/server/shared/constants.js.map +1 -0
  333. package/dist/server/shared/constants.mjs +38 -0
  334. package/dist/server/shared/constants.mjs.map +1 -0
  335. package/dist/server/src/config.d.ts +2 -0
  336. package/dist/server/src/config.d.ts.map +1 -1
  337. package/dist/server/src/constants.d.ts +2 -1
  338. package/dist/server/src/constants.d.ts.map +1 -1
  339. package/dist/server/src/controllers/admin-file.d.ts +10 -0
  340. package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
  341. package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
  342. package/dist/server/src/controllers/index.d.ts +1 -0
  343. package/dist/server/src/controllers/index.d.ts.map +1 -1
  344. package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts +2 -0
  345. package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts.map +1 -0
  346. package/dist/server/src/controllers/validation/admin/settings.d.ts +1 -1
  347. package/dist/server/src/controllers/validation/admin/settings.d.ts.map +1 -1
  348. package/dist/server/src/index.d.ts +7 -1
  349. package/dist/server/src/index.d.ts.map +1 -1
  350. package/dist/server/src/routes/admin.d.ts.map +1 -1
  351. package/dist/server/src/services/ai-metadata.d.ts +19 -0
  352. package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
  353. package/dist/server/src/services/file.d.ts +12 -2
  354. package/dist/server/src/services/file.d.ts.map +1 -1
  355. package/dist/server/src/services/image-manipulation.d.ts +0 -5
  356. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  357. package/dist/server/src/services/index.d.ts +4 -1
  358. package/dist/server/src/services/index.d.ts.map +1 -1
  359. package/dist/server/src/types.d.ts +3 -0
  360. package/dist/server/src/types.d.ts.map +1 -1
  361. package/dist/shared/constants.d.ts +35 -0
  362. package/dist/shared/constants.d.ts.map +1 -0
  363. package/dist/shared/contracts/files.d.ts +25 -0
  364. package/dist/shared/contracts/files.d.ts.map +1 -1
  365. package/dist/shared/contracts/settings.d.ts +7 -0
  366. package/package.json +10 -10
  367. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js.map +0 -1
  368. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs.map +0 -1
  369. package/dist/admin/src/future/pages/Assets/components/CreateFolderDialog.d.ts +0 -8
@@ -0,0 +1,168 @@
1
+ 'use strict';
2
+
3
+ var strapiAdmin = require('@strapi/admin/strapi-admin');
4
+
5
+ /**
6
+ * Filter state for the assets list, backed by a single `?filters=` query param
7
+ * so the applied filters are shareable and survive Back/refresh.
8
+ *
9
+ * Serialized grammar — badges separated by `;`, one badge is
10
+ * `<field>:<condition>:<value>`:
11
+ *
12
+ * - `type:is:picture,audio` / `type:not:folder`
13
+ * - `created:within:1week` / `updated:notwithin:3months` / `created:exact:1day`
14
+ * - `created:rangeis:2024-01-01..2024-04-07` / `created:rangenot:...`
15
+ *
16
+ * Relative presets stay relative in the URL on purpose: the badge label
17
+ * ("1 week ago") remains truthful forever and a shared link means "within the
18
+ * last week from whenever it is opened". Resolution to absolute timestamps
19
+ * happens at query-build time (see utils/buildAssetFilters.ts).
20
+ *
21
+ * Several badges for the same field are allowed, even contradictory ones —
22
+ * everything is combined with AND; contradictions simply produce the filtered
23
+ * empty state.
24
+ */ const TYPE_VALUES = [
25
+ 'folder',
26
+ 'picture',
27
+ 'audio',
28
+ 'video',
29
+ 'document'
30
+ ];
31
+ const DATE_PRESETS = [
32
+ '1day',
33
+ '3days',
34
+ '1week',
35
+ '1month',
36
+ '3months',
37
+ '6months',
38
+ '1year'
39
+ ];
40
+ const FIELD_TOKENS = {
41
+ created: 'createdAt',
42
+ updated: 'updatedAt'
43
+ };
44
+ const FIELD_TOKEN_BY_FIELD = {
45
+ createdAt: 'created',
46
+ updatedAt: 'updated'
47
+ };
48
+ const PRESET_CONDITION_TOKENS = {
49
+ exact: 'isExactly',
50
+ within: 'withinLast',
51
+ notwithin: 'notWithinLast'
52
+ };
53
+ const PRESET_TOKEN_BY_CONDITION = {
54
+ isExactly: 'exact',
55
+ withinLast: 'within',
56
+ notWithinLast: 'notwithin'
57
+ };
58
+ const RANGE_CONDITION_TOKENS = {
59
+ rangeis: 'is',
60
+ rangenot: 'isNot'
61
+ };
62
+ const RANGE_TOKEN_BY_CONDITION = {
63
+ is: 'rangeis',
64
+ isNot: 'rangenot'
65
+ };
66
+ const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
67
+ const isTypeValue = (value)=>TYPE_VALUES.includes(value);
68
+ const isDatePreset = (value)=>DATE_PRESETS.includes(value);
69
+ const parseBadge = (raw)=>{
70
+ const [field, condition, value] = raw.split(':');
71
+ if (!field || !condition || !value) {
72
+ return null;
73
+ }
74
+ if (field === 'type') {
75
+ if (condition !== 'is' && condition !== 'not') {
76
+ return null;
77
+ }
78
+ const values = value.split(',').filter(isTypeValue);
79
+ return values.length > 0 ? {
80
+ kind: 'type',
81
+ condition: condition === 'is' ? 'is' : 'isNot',
82
+ values
83
+ } : null;
84
+ }
85
+ const dateField = FIELD_TOKENS[field];
86
+ if (!dateField) {
87
+ return null;
88
+ }
89
+ if (condition in PRESET_CONDITION_TOKENS) {
90
+ return isDatePreset(value) ? {
91
+ kind: 'date',
92
+ field: dateField,
93
+ mode: 'preset',
94
+ condition: PRESET_CONDITION_TOKENS[condition],
95
+ preset: value
96
+ } : null;
97
+ }
98
+ if (condition in RANGE_CONDITION_TOKENS) {
99
+ const [from, to] = value.split('..');
100
+ return DATE_RE.test(from ?? '') && DATE_RE.test(to ?? '') ? {
101
+ kind: 'date',
102
+ field: dateField,
103
+ mode: 'range',
104
+ condition: RANGE_CONDITION_TOKENS[condition],
105
+ from,
106
+ to
107
+ } : null;
108
+ }
109
+ return null;
110
+ };
111
+ /**
112
+ * `unknown` on purpose: the query string is user-editable, and qs parses
113
+ * shapes like `?filters[]=a&filters[]=b` into arrays — the guard is what
114
+ * makes the caller's `?filters=` type an assertion rather than a crash.
115
+ */ const parseFiltersParam = (raw)=>{
116
+ if (typeof raw !== 'string' || raw === '') {
117
+ return [];
118
+ }
119
+ return raw.split(';').map(parseBadge).filter((filter)=>filter !== null);
120
+ };
121
+ const serializeBadge = (filter)=>{
122
+ if (filter.kind === 'type') {
123
+ return `type:${filter.condition === 'is' ? 'is' : 'not'}:${filter.values.join(',')}`;
124
+ }
125
+ const field = FIELD_TOKEN_BY_FIELD[filter.field];
126
+ if (filter.mode === 'preset') {
127
+ return `${field}:${PRESET_TOKEN_BY_CONDITION[filter.condition]}:${filter.preset}`;
128
+ }
129
+ return `${field}:${RANGE_TOKEN_BY_CONDITION[filter.condition]}:${filter.from}..${filter.to}`;
130
+ };
131
+ const serializeFilters = (filters)=>filters.map(serializeBadge).join(';');
132
+ const useListFilters = ()=>{
133
+ const [{ query }, setQuery] = strapiAdmin.useQueryParams();
134
+ const filters = parseFiltersParam(query?.filters);
135
+ // `replace: true` on every write: filters are edited in rapid micro-steps
136
+ // (each checkbox of the keep-open Type submenu, each badge segment edit), so
137
+ // pushing would turn one logical change into a stack of Back entries. The
138
+ // URL stays shareable and refresh-safe either way.
139
+ const writeFilters = (next)=>{
140
+ if (next.length === 0) {
141
+ setQuery({
142
+ filters: ''
143
+ }, 'remove', true);
144
+ } else {
145
+ setQuery({
146
+ filters: serializeFilters(next)
147
+ }, 'push', true);
148
+ }
149
+ };
150
+ return {
151
+ filters,
152
+ serialized: serializeFilters(filters),
153
+ addFilter: (filter)=>writeFilters([
154
+ ...filters,
155
+ filter
156
+ ]),
157
+ updateFilter: (index, filter)=>writeFilters(filters.map((f, i)=>i === index ? filter : f)),
158
+ removeFilter: (index)=>writeFilters(filters.filter((_, i)=>i !== index)),
159
+ clearFilters: ()=>writeFilters([])
160
+ };
161
+ };
162
+
163
+ exports.DATE_PRESETS = DATE_PRESETS;
164
+ exports.TYPE_VALUES = TYPE_VALUES;
165
+ exports.parseFiltersParam = parseFiltersParam;
166
+ exports.serializeFilters = serializeFilters;
167
+ exports.useListFilters = useListFilters;
168
+ //# sourceMappingURL=useListFilters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useListFilters.js","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useListFilters.ts"],"sourcesContent":["import { useQueryParams } from '@strapi/admin/strapi-admin';\n\n/**\n * Filter state for the assets list, backed by a single `?filters=` query param\n * so the applied filters are shareable and survive Back/refresh.\n *\n * Serialized grammar — badges separated by `;`, one badge is\n * `<field>:<condition>:<value>`:\n *\n * - `type:is:picture,audio` / `type:not:folder`\n * - `created:within:1week` / `updated:notwithin:3months` / `created:exact:1day`\n * - `created:rangeis:2024-01-01..2024-04-07` / `created:rangenot:...`\n *\n * Relative presets stay relative in the URL on purpose: the badge label\n * (\"1 week ago\") remains truthful forever and a shared link means \"within the\n * last week from whenever it is opened\". Resolution to absolute timestamps\n * happens at query-build time (see utils/buildAssetFilters.ts).\n *\n * Several badges for the same field are allowed, even contradictory ones —\n * everything is combined with AND; contradictions simply produce the filtered\n * empty state.\n */\n\nexport const TYPE_VALUES = ['folder', 'picture', 'audio', 'video', 'document'] as const;\nexport type TypeValue = (typeof TYPE_VALUES)[number];\n\nexport const DATE_PRESETS = [\n '1day',\n '3days',\n '1week',\n '1month',\n '3months',\n '6months',\n '1year',\n] as const;\nexport type DatePreset = (typeof DATE_PRESETS)[number];\n\nexport type TypeCondition = 'is' | 'isNot';\nexport type PresetCondition = 'isExactly' | 'withinLast' | 'notWithinLast';\nexport type RangeCondition = 'is' | 'isNot';\n\nexport type DateField = 'createdAt' | 'updatedAt';\n\nexport interface TypeFilter {\n kind: 'type';\n condition: TypeCondition;\n values: TypeValue[];\n}\n\nexport interface DatePresetFilter {\n kind: 'date';\n field: DateField;\n mode: 'preset';\n condition: PresetCondition;\n preset: DatePreset;\n}\n\nexport interface DateRangeFilter {\n kind: 'date';\n field: DateField;\n mode: 'range';\n condition: RangeCondition;\n /** Calendar dates, `YYYY-MM-DD`, inclusive on both ends. */\n from: string;\n to: string;\n}\n\nexport type DateFilter = DatePresetFilter | DateRangeFilter;\nexport type ListFilter = TypeFilter | DateFilter;\n\nconst FIELD_TOKENS: Record<string, DateField> = {\n created: 'createdAt',\n updated: 'updatedAt',\n};\nconst FIELD_TOKEN_BY_FIELD: Record<DateField, string> = {\n createdAt: 'created',\n updatedAt: 'updated',\n};\n\nconst PRESET_CONDITION_TOKENS: Record<string, PresetCondition> = {\n exact: 'isExactly',\n within: 'withinLast',\n notwithin: 'notWithinLast',\n};\nconst PRESET_TOKEN_BY_CONDITION: Record<PresetCondition, string> = {\n isExactly: 'exact',\n withinLast: 'within',\n notWithinLast: 'notwithin',\n};\n\nconst RANGE_CONDITION_TOKENS: Record<string, RangeCondition> = {\n rangeis: 'is',\n rangenot: 'isNot',\n};\nconst RANGE_TOKEN_BY_CONDITION: Record<RangeCondition, string> = {\n is: 'rangeis',\n isNot: 'rangenot',\n};\n\nconst DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nconst isTypeValue = (value: string): value is TypeValue =>\n (TYPE_VALUES as readonly string[]).includes(value);\n\nconst isDatePreset = (value: string): value is DatePreset =>\n (DATE_PRESETS as readonly string[]).includes(value);\n\nconst parseBadge = (raw: string): ListFilter | null => {\n const [field, condition, value] = raw.split(':');\n\n if (!field || !condition || !value) {\n return null;\n }\n\n if (field === 'type') {\n if (condition !== 'is' && condition !== 'not') {\n return null;\n }\n const values = value.split(',').filter(isTypeValue);\n\n return values.length > 0\n ? { kind: 'type', condition: condition === 'is' ? 'is' : 'isNot', values }\n : null;\n }\n\n const dateField = FIELD_TOKENS[field];\n if (!dateField) {\n return null;\n }\n\n if (condition in PRESET_CONDITION_TOKENS) {\n return isDatePreset(value)\n ? {\n kind: 'date',\n field: dateField,\n mode: 'preset',\n condition: PRESET_CONDITION_TOKENS[condition],\n preset: value,\n }\n : null;\n }\n\n if (condition in RANGE_CONDITION_TOKENS) {\n const [from, to] = value.split('..');\n\n return DATE_RE.test(from ?? '') && DATE_RE.test(to ?? '')\n ? {\n kind: 'date',\n field: dateField,\n mode: 'range',\n condition: RANGE_CONDITION_TOKENS[condition],\n from,\n to,\n }\n : null;\n }\n\n return null;\n};\n\n/**\n * `unknown` on purpose: the query string is user-editable, and qs parses\n * shapes like `?filters[]=a&filters[]=b` into arrays — the guard is what\n * makes the caller's `?filters=` type an assertion rather than a crash.\n */\nexport const parseFiltersParam = (raw: unknown): ListFilter[] => {\n if (typeof raw !== 'string' || raw === '') {\n return [];\n }\n\n return raw\n .split(';')\n .map(parseBadge)\n .filter((filter): filter is ListFilter => filter !== null);\n};\n\nconst serializeBadge = (filter: ListFilter): string => {\n if (filter.kind === 'type') {\n return `type:${filter.condition === 'is' ? 'is' : 'not'}:${filter.values.join(',')}`;\n }\n\n const field = FIELD_TOKEN_BY_FIELD[filter.field];\n\n if (filter.mode === 'preset') {\n return `${field}:${PRESET_TOKEN_BY_CONDITION[filter.condition]}:${filter.preset}`;\n }\n\n return `${field}:${RANGE_TOKEN_BY_CONDITION[filter.condition]}:${filter.from}..${filter.to}`;\n};\n\nexport const serializeFilters = (filters: ListFilter[]): string =>\n filters.map(serializeBadge).join(';');\n\nexport interface ListFilters {\n filters: ListFilter[];\n /** Serialized form — stable fingerprint for list-identity (selection reset). */\n serialized: string;\n addFilter: (filter: ListFilter) => void;\n /** Replaces the badge at `index` (condition or value edited in place). */\n updateFilter: (index: number, filter: ListFilter) => void;\n removeFilter: (index: number) => void;\n clearFilters: () => void;\n}\n\nexport const useListFilters = (): ListFilters => {\n const [{ query }, setQuery] = useQueryParams<{ filters?: string }>();\n\n const filters = parseFiltersParam(query?.filters);\n\n // `replace: true` on every write: filters are edited in rapid micro-steps\n // (each checkbox of the keep-open Type submenu, each badge segment edit), so\n // pushing would turn one logical change into a stack of Back entries. The\n // URL stays shareable and refresh-safe either way.\n const writeFilters = (next: ListFilter[]) => {\n if (next.length === 0) {\n setQuery({ filters: '' }, 'remove', true);\n } else {\n setQuery({ filters: serializeFilters(next) }, 'push', true);\n }\n };\n\n return {\n filters,\n serialized: serializeFilters(filters),\n addFilter: (filter) => writeFilters([...filters, filter]),\n updateFilter: (index, filter) =>\n writeFilters(filters.map((f, i) => (i === index ? filter : f))),\n removeFilter: (index) => writeFilters(filters.filter((_, i) => i !== index)),\n clearFilters: () => writeFilters([]),\n };\n};\n"],"names":["TYPE_VALUES","DATE_PRESETS","FIELD_TOKENS","created","updated","FIELD_TOKEN_BY_FIELD","createdAt","updatedAt","PRESET_CONDITION_TOKENS","exact","within","notwithin","PRESET_TOKEN_BY_CONDITION","isExactly","withinLast","notWithinLast","RANGE_CONDITION_TOKENS","rangeis","rangenot","RANGE_TOKEN_BY_CONDITION","is","isNot","DATE_RE","isTypeValue","value","includes","isDatePreset","parseBadge","raw","field","condition","split","values","filter","length","kind","dateField","mode","preset","from","to","test","parseFiltersParam","map","serializeBadge","join","serializeFilters","filters","useListFilters","query","setQuery","useQueryParams","writeFilters","next","serialized","addFilter","updateFilter","index","f","i","removeFilter","_","clearFilters"],"mappings":"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"}
@@ -0,0 +1,162 @@
1
+ import { useQueryParams } from '@strapi/admin/strapi-admin';
2
+
3
+ /**
4
+ * Filter state for the assets list, backed by a single `?filters=` query param
5
+ * so the applied filters are shareable and survive Back/refresh.
6
+ *
7
+ * Serialized grammar — badges separated by `;`, one badge is
8
+ * `<field>:<condition>:<value>`:
9
+ *
10
+ * - `type:is:picture,audio` / `type:not:folder`
11
+ * - `created:within:1week` / `updated:notwithin:3months` / `created:exact:1day`
12
+ * - `created:rangeis:2024-01-01..2024-04-07` / `created:rangenot:...`
13
+ *
14
+ * Relative presets stay relative in the URL on purpose: the badge label
15
+ * ("1 week ago") remains truthful forever and a shared link means "within the
16
+ * last week from whenever it is opened". Resolution to absolute timestamps
17
+ * happens at query-build time (see utils/buildAssetFilters.ts).
18
+ *
19
+ * Several badges for the same field are allowed, even contradictory ones —
20
+ * everything is combined with AND; contradictions simply produce the filtered
21
+ * empty state.
22
+ */ const TYPE_VALUES = [
23
+ 'folder',
24
+ 'picture',
25
+ 'audio',
26
+ 'video',
27
+ 'document'
28
+ ];
29
+ const DATE_PRESETS = [
30
+ '1day',
31
+ '3days',
32
+ '1week',
33
+ '1month',
34
+ '3months',
35
+ '6months',
36
+ '1year'
37
+ ];
38
+ const FIELD_TOKENS = {
39
+ created: 'createdAt',
40
+ updated: 'updatedAt'
41
+ };
42
+ const FIELD_TOKEN_BY_FIELD = {
43
+ createdAt: 'created',
44
+ updatedAt: 'updated'
45
+ };
46
+ const PRESET_CONDITION_TOKENS = {
47
+ exact: 'isExactly',
48
+ within: 'withinLast',
49
+ notwithin: 'notWithinLast'
50
+ };
51
+ const PRESET_TOKEN_BY_CONDITION = {
52
+ isExactly: 'exact',
53
+ withinLast: 'within',
54
+ notWithinLast: 'notwithin'
55
+ };
56
+ const RANGE_CONDITION_TOKENS = {
57
+ rangeis: 'is',
58
+ rangenot: 'isNot'
59
+ };
60
+ const RANGE_TOKEN_BY_CONDITION = {
61
+ is: 'rangeis',
62
+ isNot: 'rangenot'
63
+ };
64
+ const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
65
+ const isTypeValue = (value)=>TYPE_VALUES.includes(value);
66
+ const isDatePreset = (value)=>DATE_PRESETS.includes(value);
67
+ const parseBadge = (raw)=>{
68
+ const [field, condition, value] = raw.split(':');
69
+ if (!field || !condition || !value) {
70
+ return null;
71
+ }
72
+ if (field === 'type') {
73
+ if (condition !== 'is' && condition !== 'not') {
74
+ return null;
75
+ }
76
+ const values = value.split(',').filter(isTypeValue);
77
+ return values.length > 0 ? {
78
+ kind: 'type',
79
+ condition: condition === 'is' ? 'is' : 'isNot',
80
+ values
81
+ } : null;
82
+ }
83
+ const dateField = FIELD_TOKENS[field];
84
+ if (!dateField) {
85
+ return null;
86
+ }
87
+ if (condition in PRESET_CONDITION_TOKENS) {
88
+ return isDatePreset(value) ? {
89
+ kind: 'date',
90
+ field: dateField,
91
+ mode: 'preset',
92
+ condition: PRESET_CONDITION_TOKENS[condition],
93
+ preset: value
94
+ } : null;
95
+ }
96
+ if (condition in RANGE_CONDITION_TOKENS) {
97
+ const [from, to] = value.split('..');
98
+ return DATE_RE.test(from ?? '') && DATE_RE.test(to ?? '') ? {
99
+ kind: 'date',
100
+ field: dateField,
101
+ mode: 'range',
102
+ condition: RANGE_CONDITION_TOKENS[condition],
103
+ from,
104
+ to
105
+ } : null;
106
+ }
107
+ return null;
108
+ };
109
+ /**
110
+ * `unknown` on purpose: the query string is user-editable, and qs parses
111
+ * shapes like `?filters[]=a&filters[]=b` into arrays — the guard is what
112
+ * makes the caller's `?filters=` type an assertion rather than a crash.
113
+ */ const parseFiltersParam = (raw)=>{
114
+ if (typeof raw !== 'string' || raw === '') {
115
+ return [];
116
+ }
117
+ return raw.split(';').map(parseBadge).filter((filter)=>filter !== null);
118
+ };
119
+ const serializeBadge = (filter)=>{
120
+ if (filter.kind === 'type') {
121
+ return `type:${filter.condition === 'is' ? 'is' : 'not'}:${filter.values.join(',')}`;
122
+ }
123
+ const field = FIELD_TOKEN_BY_FIELD[filter.field];
124
+ if (filter.mode === 'preset') {
125
+ return `${field}:${PRESET_TOKEN_BY_CONDITION[filter.condition]}:${filter.preset}`;
126
+ }
127
+ return `${field}:${RANGE_TOKEN_BY_CONDITION[filter.condition]}:${filter.from}..${filter.to}`;
128
+ };
129
+ const serializeFilters = (filters)=>filters.map(serializeBadge).join(';');
130
+ const useListFilters = ()=>{
131
+ const [{ query }, setQuery] = useQueryParams();
132
+ const filters = parseFiltersParam(query?.filters);
133
+ // `replace: true` on every write: filters are edited in rapid micro-steps
134
+ // (each checkbox of the keep-open Type submenu, each badge segment edit), so
135
+ // pushing would turn one logical change into a stack of Back entries. The
136
+ // URL stays shareable and refresh-safe either way.
137
+ const writeFilters = (next)=>{
138
+ if (next.length === 0) {
139
+ setQuery({
140
+ filters: ''
141
+ }, 'remove', true);
142
+ } else {
143
+ setQuery({
144
+ filters: serializeFilters(next)
145
+ }, 'push', true);
146
+ }
147
+ };
148
+ return {
149
+ filters,
150
+ serialized: serializeFilters(filters),
151
+ addFilter: (filter)=>writeFilters([
152
+ ...filters,
153
+ filter
154
+ ]),
155
+ updateFilter: (index, filter)=>writeFilters(filters.map((f, i)=>i === index ? filter : f)),
156
+ removeFilter: (index)=>writeFilters(filters.filter((_, i)=>i !== index)),
157
+ clearFilters: ()=>writeFilters([])
158
+ };
159
+ };
160
+
161
+ export { DATE_PRESETS, TYPE_VALUES, parseFiltersParam, serializeFilters, useListFilters };
162
+ //# sourceMappingURL=useListFilters.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useListFilters.mjs","sources":["../../../../../../admin/src/future/pages/Assets/hooks/useListFilters.ts"],"sourcesContent":["import { useQueryParams } from '@strapi/admin/strapi-admin';\n\n/**\n * Filter state for the assets list, backed by a single `?filters=` query param\n * so the applied filters are shareable and survive Back/refresh.\n *\n * Serialized grammar — badges separated by `;`, one badge is\n * `<field>:<condition>:<value>`:\n *\n * - `type:is:picture,audio` / `type:not:folder`\n * - `created:within:1week` / `updated:notwithin:3months` / `created:exact:1day`\n * - `created:rangeis:2024-01-01..2024-04-07` / `created:rangenot:...`\n *\n * Relative presets stay relative in the URL on purpose: the badge label\n * (\"1 week ago\") remains truthful forever and a shared link means \"within the\n * last week from whenever it is opened\". Resolution to absolute timestamps\n * happens at query-build time (see utils/buildAssetFilters.ts).\n *\n * Several badges for the same field are allowed, even contradictory ones —\n * everything is combined with AND; contradictions simply produce the filtered\n * empty state.\n */\n\nexport const TYPE_VALUES = ['folder', 'picture', 'audio', 'video', 'document'] as const;\nexport type TypeValue = (typeof TYPE_VALUES)[number];\n\nexport const DATE_PRESETS = [\n '1day',\n '3days',\n '1week',\n '1month',\n '3months',\n '6months',\n '1year',\n] as const;\nexport type DatePreset = (typeof DATE_PRESETS)[number];\n\nexport type TypeCondition = 'is' | 'isNot';\nexport type PresetCondition = 'isExactly' | 'withinLast' | 'notWithinLast';\nexport type RangeCondition = 'is' | 'isNot';\n\nexport type DateField = 'createdAt' | 'updatedAt';\n\nexport interface TypeFilter {\n kind: 'type';\n condition: TypeCondition;\n values: TypeValue[];\n}\n\nexport interface DatePresetFilter {\n kind: 'date';\n field: DateField;\n mode: 'preset';\n condition: PresetCondition;\n preset: DatePreset;\n}\n\nexport interface DateRangeFilter {\n kind: 'date';\n field: DateField;\n mode: 'range';\n condition: RangeCondition;\n /** Calendar dates, `YYYY-MM-DD`, inclusive on both ends. */\n from: string;\n to: string;\n}\n\nexport type DateFilter = DatePresetFilter | DateRangeFilter;\nexport type ListFilter = TypeFilter | DateFilter;\n\nconst FIELD_TOKENS: Record<string, DateField> = {\n created: 'createdAt',\n updated: 'updatedAt',\n};\nconst FIELD_TOKEN_BY_FIELD: Record<DateField, string> = {\n createdAt: 'created',\n updatedAt: 'updated',\n};\n\nconst PRESET_CONDITION_TOKENS: Record<string, PresetCondition> = {\n exact: 'isExactly',\n within: 'withinLast',\n notwithin: 'notWithinLast',\n};\nconst PRESET_TOKEN_BY_CONDITION: Record<PresetCondition, string> = {\n isExactly: 'exact',\n withinLast: 'within',\n notWithinLast: 'notwithin',\n};\n\nconst RANGE_CONDITION_TOKENS: Record<string, RangeCondition> = {\n rangeis: 'is',\n rangenot: 'isNot',\n};\nconst RANGE_TOKEN_BY_CONDITION: Record<RangeCondition, string> = {\n is: 'rangeis',\n isNot: 'rangenot',\n};\n\nconst DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nconst isTypeValue = (value: string): value is TypeValue =>\n (TYPE_VALUES as readonly string[]).includes(value);\n\nconst isDatePreset = (value: string): value is DatePreset =>\n (DATE_PRESETS as readonly string[]).includes(value);\n\nconst parseBadge = (raw: string): ListFilter | null => {\n const [field, condition, value] = raw.split(':');\n\n if (!field || !condition || !value) {\n return null;\n }\n\n if (field === 'type') {\n if (condition !== 'is' && condition !== 'not') {\n return null;\n }\n const values = value.split(',').filter(isTypeValue);\n\n return values.length > 0\n ? { kind: 'type', condition: condition === 'is' ? 'is' : 'isNot', values }\n : null;\n }\n\n const dateField = FIELD_TOKENS[field];\n if (!dateField) {\n return null;\n }\n\n if (condition in PRESET_CONDITION_TOKENS) {\n return isDatePreset(value)\n ? {\n kind: 'date',\n field: dateField,\n mode: 'preset',\n condition: PRESET_CONDITION_TOKENS[condition],\n preset: value,\n }\n : null;\n }\n\n if (condition in RANGE_CONDITION_TOKENS) {\n const [from, to] = value.split('..');\n\n return DATE_RE.test(from ?? '') && DATE_RE.test(to ?? '')\n ? {\n kind: 'date',\n field: dateField,\n mode: 'range',\n condition: RANGE_CONDITION_TOKENS[condition],\n from,\n to,\n }\n : null;\n }\n\n return null;\n};\n\n/**\n * `unknown` on purpose: the query string is user-editable, and qs parses\n * shapes like `?filters[]=a&filters[]=b` into arrays — the guard is what\n * makes the caller's `?filters=` type an assertion rather than a crash.\n */\nexport const parseFiltersParam = (raw: unknown): ListFilter[] => {\n if (typeof raw !== 'string' || raw === '') {\n return [];\n }\n\n return raw\n .split(';')\n .map(parseBadge)\n .filter((filter): filter is ListFilter => filter !== null);\n};\n\nconst serializeBadge = (filter: ListFilter): string => {\n if (filter.kind === 'type') {\n return `type:${filter.condition === 'is' ? 'is' : 'not'}:${filter.values.join(',')}`;\n }\n\n const field = FIELD_TOKEN_BY_FIELD[filter.field];\n\n if (filter.mode === 'preset') {\n return `${field}:${PRESET_TOKEN_BY_CONDITION[filter.condition]}:${filter.preset}`;\n }\n\n return `${field}:${RANGE_TOKEN_BY_CONDITION[filter.condition]}:${filter.from}..${filter.to}`;\n};\n\nexport const serializeFilters = (filters: ListFilter[]): string =>\n filters.map(serializeBadge).join(';');\n\nexport interface ListFilters {\n filters: ListFilter[];\n /** Serialized form — stable fingerprint for list-identity (selection reset). */\n serialized: string;\n addFilter: (filter: ListFilter) => void;\n /** Replaces the badge at `index` (condition or value edited in place). */\n updateFilter: (index: number, filter: ListFilter) => void;\n removeFilter: (index: number) => void;\n clearFilters: () => void;\n}\n\nexport const useListFilters = (): ListFilters => {\n const [{ query }, setQuery] = useQueryParams<{ filters?: string }>();\n\n const filters = parseFiltersParam(query?.filters);\n\n // `replace: true` on every write: filters are edited in rapid micro-steps\n // (each checkbox of the keep-open Type submenu, each badge segment edit), so\n // pushing would turn one logical change into a stack of Back entries. The\n // URL stays shareable and refresh-safe either way.\n const writeFilters = (next: ListFilter[]) => {\n if (next.length === 0) {\n setQuery({ filters: '' }, 'remove', true);\n } else {\n setQuery({ filters: serializeFilters(next) }, 'push', true);\n }\n };\n\n return {\n filters,\n serialized: serializeFilters(filters),\n addFilter: (filter) => writeFilters([...filters, filter]),\n updateFilter: (index, filter) =>\n writeFilters(filters.map((f, i) => (i === index ? filter : f))),\n removeFilter: (index) => writeFilters(filters.filter((_, i) => i !== index)),\n clearFilters: () => writeFilters([]),\n };\n};\n"],"names":["TYPE_VALUES","DATE_PRESETS","FIELD_TOKENS","created","updated","FIELD_TOKEN_BY_FIELD","createdAt","updatedAt","PRESET_CONDITION_TOKENS","exact","within","notwithin","PRESET_TOKEN_BY_CONDITION","isExactly","withinLast","notWithinLast","RANGE_CONDITION_TOKENS","rangeis","rangenot","RANGE_TOKEN_BY_CONDITION","is","isNot","DATE_RE","isTypeValue","value","includes","isDatePreset","parseBadge","raw","field","condition","split","values","filter","length","kind","dateField","mode","preset","from","to","test","parseFiltersParam","map","serializeBadge","join","serializeFilters","filters","useListFilters","query","setQuery","useQueryParams","writeFilters","next","serialized","addFilter","updateFilter","index","f","i","removeFilter","_","clearFilters"],"mappings":"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"}
@@ -0,0 +1,201 @@
1
+ 'use strict';
2
+
3
+ const MIME_BY_VALUE = {
4
+ picture: 'image',
5
+ audio: 'audio',
6
+ video: 'video'
7
+ };
8
+ const ALL_MIMES = Object.values(MIME_BY_VALUE);
9
+ const PRESET_DELTAS = {
10
+ '1day': {
11
+ days: 1
12
+ },
13
+ '3days': {
14
+ days: 3
15
+ },
16
+ '1week': {
17
+ days: 7
18
+ },
19
+ '1month': {
20
+ months: 1
21
+ },
22
+ '3months': {
23
+ months: 3
24
+ },
25
+ '6months': {
26
+ months: 6
27
+ },
28
+ '1year': {
29
+ years: 1
30
+ }
31
+ };
32
+ const subtractPreset = (now, preset)=>{
33
+ const { days = 0, months = 0, years = 0 } = PRESET_DELTAS[preset];
34
+ const result = new Date(now.getTime());
35
+ if (years || months) {
36
+ // JS date setters overflow at month ends (Mar 31 − 1 month → Feb 31 → Mar 3),
37
+ // so move to the 1st first and clamp the day to the target month's length.
38
+ const dayOfMonth = result.getDate();
39
+ result.setDate(1);
40
+ result.setFullYear(result.getFullYear() - years);
41
+ result.setMonth(result.getMonth() - months);
42
+ const daysInTargetMonth = new Date(result.getFullYear(), result.getMonth() + 1, 0).getDate();
43
+ result.setDate(Math.min(dayOfMonth, daysInTargetMonth));
44
+ }
45
+ result.setDate(result.getDate() - days);
46
+ return result;
47
+ };
48
+ const startOfDay = (date)=>{
49
+ const result = new Date(date.getTime());
50
+ result.setHours(0, 0, 0, 0);
51
+ return result;
52
+ };
53
+ const endOfDay = (date)=>{
54
+ const result = new Date(date.getTime());
55
+ result.setHours(23, 59, 59, 999);
56
+ return result;
57
+ };
58
+ /**
59
+ * Parses `YYYY-MM-DD` as a local calendar date — NOT `new Date(value)`, which
60
+ * treats date-only strings as UTC midnight and shifts the day in every
61
+ * timezone west of UTC. Shared by the query builder, the badge labels and the
62
+ * range calendar so all three agree on which day a range endpoint means.
63
+ */ const parseCalendarDate = (value)=>{
64
+ const [year, month, day] = value.split('-').map(Number);
65
+ return new Date(year, month - 1, day);
66
+ };
67
+ const buildDateClause = (filter, now)=>{
68
+ const { field } = filter;
69
+ if (filter.mode === 'preset') {
70
+ const pivot = subtractPreset(now, filter.preset);
71
+ switch(filter.condition){
72
+ case 'withinLast':
73
+ return {
74
+ [field]: {
75
+ $gte: pivot.toISOString()
76
+ }
77
+ };
78
+ case 'notWithinLast':
79
+ return {
80
+ [field]: {
81
+ $lt: pivot.toISOString()
82
+ }
83
+ };
84
+ case 'isExactly':
85
+ return {
86
+ [field]: {
87
+ $gte: startOfDay(pivot).toISOString(),
88
+ $lte: endOfDay(pivot).toISOString()
89
+ }
90
+ };
91
+ }
92
+ }
93
+ const from = startOfDay(parseCalendarDate(filter.from)).toISOString();
94
+ const to = endOfDay(parseCalendarDate(filter.to)).toISOString();
95
+ if (filter.condition === 'is') {
96
+ return {
97
+ [field]: {
98
+ $gte: from,
99
+ $lte: to
100
+ }
101
+ };
102
+ }
103
+ return {
104
+ $or: [
105
+ {
106
+ [field]: {
107
+ $lt: from
108
+ }
109
+ },
110
+ {
111
+ [field]: {
112
+ $gt: to
113
+ }
114
+ }
115
+ ]
116
+ };
117
+ };
118
+ const buildMimeClause = (filter)=>{
119
+ const fileValues = filter.values.filter((value)=>value !== 'folder');
120
+ if (fileValues.length === 0) {
121
+ return null;
122
+ }
123
+ const branches = fileValues.map((value)=>{
124
+ if (value === 'document') {
125
+ // Catch-all: none of the known mime families.
126
+ return {
127
+ $and: ALL_MIMES.map((mime)=>({
128
+ mime: {
129
+ $notContains: mime
130
+ }
131
+ }))
132
+ };
133
+ }
134
+ return {
135
+ mime: {
136
+ $contains: MIME_BY_VALUE[value]
137
+ }
138
+ };
139
+ });
140
+ if (filter.condition === 'is') {
141
+ return branches.length === 1 ? branches[0] : {
142
+ $or: branches
143
+ };
144
+ }
145
+ // "is not" = matches none of the selected values: negate each branch, AND them.
146
+ const negated = fileValues.map((value)=>{
147
+ if (value === 'document') {
148
+ // Not a document = is one of the known families.
149
+ return {
150
+ $or: ALL_MIMES.map((mime)=>({
151
+ mime: {
152
+ $contains: mime
153
+ }
154
+ }))
155
+ };
156
+ }
157
+ return {
158
+ mime: {
159
+ $notContains: MIME_BY_VALUE[value]
160
+ }
161
+ };
162
+ });
163
+ return negated.length === 1 ? negated[0] : {
164
+ $and: negated
165
+ };
166
+ };
167
+ const buildAssetFilters = (filters, now)=>{
168
+ const fileClauses = [];
169
+ const folderClauses = [];
170
+ let showFolders = true;
171
+ let showFiles = true;
172
+ for (const filter of filters){
173
+ if (filter.kind === 'date') {
174
+ const clause = buildDateClause(filter, now);
175
+ fileClauses.push(clause);
176
+ folderClauses.push(clause);
177
+ continue;
178
+ }
179
+ const includesFolder = filter.values.includes('folder');
180
+ if (filter.condition === 'is' ? !includesFolder : includesFolder) {
181
+ showFolders = false;
182
+ }
183
+ const mimeClause = buildMimeClause(filter);
184
+ if (mimeClause) {
185
+ fileClauses.push(mimeClause);
186
+ } else if (filter.condition === 'is') {
187
+ // `is [folder]` only — no file can match the badge.
188
+ showFiles = false;
189
+ }
190
+ }
191
+ return {
192
+ fileClauses,
193
+ folderClauses,
194
+ showFolders,
195
+ showFiles
196
+ };
197
+ };
198
+
199
+ exports.buildAssetFilters = buildAssetFilters;
200
+ exports.parseCalendarDate = parseCalendarDate;
201
+ //# sourceMappingURL=buildAssetFilters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildAssetFilters.js","sources":["../../../../../../admin/src/future/pages/Assets/utils/buildAssetFilters.ts"],"sourcesContent":["import {\n type DateFilter,\n type DatePreset,\n type ListFilter,\n type TypeFilter,\n type TypeValue,\n} from '../hooks/useListFilters';\n\n/**\n * Translates the URL filter model into Strapi `filters[$and]` entries for the\n * files and folders queries, and decides the structural visibility of both\n * sections.\n *\n * Relative presets resolve against `now` at build time — the URL stays\n * relative (\"within the last week\"), only the outgoing query is absolute.\n *\n * Semantics:\n * - Every badge is one `$and` entry (badges combine with AND, per ticket).\n * - Type: `folder` is not a mime — it acts structurally on the folders\n * section. The remaining values map to mime clauses; `document` is the\n * legacy catch-all (mime contains none of image/audio/video — audio\n * included in the exclusion, fixing the legacy quirk).\n * - Dates apply to files and folders alike (folders have both timestamps).\n * - \"is exactly <preset>\" means the calendar day of `now - delta`.\n * - Ranges are inclusive on both ends (start-of-day .. end-of-day).\n */\n\ntype QueryClause = Record<string, unknown>;\n\nconst MIME_BY_VALUE: Record<Exclude<TypeValue, 'folder' | 'document'>, string> = {\n picture: 'image',\n audio: 'audio',\n video: 'video',\n};\n\nconst ALL_MIMES = Object.values(MIME_BY_VALUE);\n\nconst PRESET_DELTAS: Record<DatePreset, { days?: number; months?: number; years?: number }> = {\n '1day': { days: 1 },\n '3days': { days: 3 },\n '1week': { days: 7 },\n '1month': { months: 1 },\n '3months': { months: 3 },\n '6months': { months: 6 },\n '1year': { years: 1 },\n};\n\nconst subtractPreset = (now: Date, preset: DatePreset): Date => {\n const { days = 0, months = 0, years = 0 } = PRESET_DELTAS[preset];\n const result = new Date(now.getTime());\n\n if (years || months) {\n // JS date setters overflow at month ends (Mar 31 − 1 month → Feb 31 → Mar 3),\n // so move to the 1st first and clamp the day to the target month's length.\n const dayOfMonth = result.getDate();\n result.setDate(1);\n result.setFullYear(result.getFullYear() - years);\n result.setMonth(result.getMonth() - months);\n\n const daysInTargetMonth = new Date(result.getFullYear(), result.getMonth() + 1, 0).getDate();\n result.setDate(Math.min(dayOfMonth, daysInTargetMonth));\n }\n\n result.setDate(result.getDate() - days);\n\n return result;\n};\n\nconst startOfDay = (date: Date): Date => {\n const result = new Date(date.getTime());\n result.setHours(0, 0, 0, 0);\n return result;\n};\n\nconst endOfDay = (date: Date): Date => {\n const result = new Date(date.getTime());\n result.setHours(23, 59, 59, 999);\n return result;\n};\n\n/**\n * Parses `YYYY-MM-DD` as a local calendar date — NOT `new Date(value)`, which\n * treats date-only strings as UTC midnight and shifts the day in every\n * timezone west of UTC. Shared by the query builder, the badge labels and the\n * range calendar so all three agree on which day a range endpoint means.\n */\nexport const parseCalendarDate = (value: string): Date => {\n const [year, month, day] = value.split('-').map(Number);\n return new Date(year, month - 1, day);\n};\n\nconst buildDateClause = (filter: DateFilter, now: Date): QueryClause => {\n const { field } = filter;\n\n if (filter.mode === 'preset') {\n const pivot = subtractPreset(now, filter.preset);\n\n switch (filter.condition) {\n case 'withinLast':\n return { [field]: { $gte: pivot.toISOString() } };\n case 'notWithinLast':\n return { [field]: { $lt: pivot.toISOString() } };\n case 'isExactly':\n return {\n [field]: {\n $gte: startOfDay(pivot).toISOString(),\n $lte: endOfDay(pivot).toISOString(),\n },\n };\n }\n }\n\n const from = startOfDay(parseCalendarDate(filter.from)).toISOString();\n const to = endOfDay(parseCalendarDate(filter.to)).toISOString();\n\n if (filter.condition === 'is') {\n return { [field]: { $gte: from, $lte: to } };\n }\n\n return { $or: [{ [field]: { $lt: from } }, { [field]: { $gt: to } }] };\n};\n\nconst buildMimeClause = (filter: TypeFilter): QueryClause | null => {\n const fileValues = filter.values.filter((value): value is TypeValue => value !== 'folder');\n\n if (fileValues.length === 0) {\n return null;\n }\n\n const branches: QueryClause[] = fileValues.map((value) => {\n if (value === 'document') {\n // Catch-all: none of the known mime families.\n return { $and: ALL_MIMES.map((mime) => ({ mime: { $notContains: mime } })) };\n }\n return { mime: { $contains: MIME_BY_VALUE[value as keyof typeof MIME_BY_VALUE] } };\n });\n\n if (filter.condition === 'is') {\n return branches.length === 1 ? branches[0] : { $or: branches };\n }\n\n // \"is not\" = matches none of the selected values: negate each branch, AND them.\n const negated: QueryClause[] = fileValues.map((value) => {\n if (value === 'document') {\n // Not a document = is one of the known families.\n return { $or: ALL_MIMES.map((mime) => ({ mime: { $contains: mime } })) };\n }\n return { mime: { $notContains: MIME_BY_VALUE[value as keyof typeof MIME_BY_VALUE] } };\n });\n\n return negated.length === 1 ? negated[0] : { $and: negated };\n};\n\nexport interface BuiltFilters {\n /** Extra `$and` entries for the files query. */\n fileClauses: QueryClause[];\n /** Extra `$and` entries for the folders query (dates only). */\n folderClauses: QueryClause[];\n /**\n * Whether the folders section can show at all. A type badge decides it by\n * evaluating \"folder\" like any other value: `is` shows folders only when\n * folder is selected; `is not` hides them only when folder is selected.\n */\n showFolders: boolean;\n /**\n * Whether the files list can show at all — false when an `is` type badge\n * selects only \"folder\" (no file can match).\n */\n showFiles: boolean;\n}\n\nexport const buildAssetFilters = (filters: ListFilter[], now: Date): BuiltFilters => {\n const fileClauses: QueryClause[] = [];\n const folderClauses: QueryClause[] = [];\n let showFolders = true;\n let showFiles = true;\n\n for (const filter of filters) {\n if (filter.kind === 'date') {\n const clause = buildDateClause(filter, now);\n fileClauses.push(clause);\n folderClauses.push(clause);\n continue;\n }\n\n const includesFolder = filter.values.includes('folder');\n if (filter.condition === 'is' ? !includesFolder : includesFolder) {\n showFolders = false;\n }\n\n const mimeClause = buildMimeClause(filter);\n if (mimeClause) {\n fileClauses.push(mimeClause);\n } else if (filter.condition === 'is') {\n // `is [folder]` only — no file can match the badge.\n showFiles = false;\n }\n }\n\n return { fileClauses, folderClauses, showFolders, showFiles };\n};\n"],"names":["MIME_BY_VALUE","picture","audio","video","ALL_MIMES","Object","values","PRESET_DELTAS","days","months","years","subtractPreset","now","preset","result","Date","getTime","dayOfMonth","getDate","setDate","setFullYear","getFullYear","setMonth","getMonth","daysInTargetMonth","Math","min","startOfDay","date","setHours","endOfDay","parseCalendarDate","value","year","month","day","split","map","Number","buildDateClause","filter","field","mode","pivot","condition","$gte","toISOString","$lt","$lte","from","to","$or","$gt","buildMimeClause","fileValues","length","branches","$and","mime","$notContains","$contains","negated","buildAssetFilters","filters","fileClauses","folderClauses","showFolders","showFiles","kind","clause","push","includesFolder","includes","mimeClause"],"mappings":"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"}