@strapi/upload 5.52.3 → 5.54.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 (220) hide show
  1. package/dist/admin/future/components/Drawer.js +6 -3
  2. package/dist/admin/future/components/Drawer.js.map +1 -1
  3. package/dist/admin/future/components/Drawer.mjs +6 -3
  4. package/dist/admin/future/components/Drawer.mjs.map +1 -1
  5. package/dist/admin/future/components/UploadProgressDialog.js +9 -8
  6. package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
  7. package/dist/admin/future/components/UploadProgressDialog.mjs +9 -8
  8. package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
  9. package/dist/admin/future/pages/Assets/AssetsPage.js +16 -4
  10. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  11. package/dist/admin/future/pages/Assets/AssetsPage.mjs +16 -4
  12. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  13. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +5 -0
  14. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -1
  15. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +5 -0
  16. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -1
  17. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +19 -4
  18. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
  19. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +19 -4
  20. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
  21. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +35 -1
  22. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  23. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +35 -1
  24. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  25. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +10 -0
  26. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  27. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +10 -0
  28. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  29. package/dist/admin/future/pages/Assets/components/AssetsTable.js +9 -0
  30. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  31. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +10 -1
  32. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  33. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +132 -88
  34. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
  35. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +135 -91
  36. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
  37. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +7 -0
  38. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +7 -0
  40. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js +4 -1
  42. package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.js.map +1 -1
  43. package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs +4 -1
  44. package/dist/admin/future/pages/Assets/components/Dnd/DragOverlayChip.mjs.map +1 -1
  45. package/dist/admin/future/pages/Assets/components/MainAreaContextMenu.js +181 -0
  46. package/dist/admin/future/pages/Assets/components/MainAreaContextMenu.js.map +1 -0
  47. package/dist/admin/future/pages/Assets/components/MainAreaContextMenu.mjs +179 -0
  48. package/dist/admin/future/pages/Assets/components/MainAreaContextMenu.mjs.map +1 -0
  49. package/dist/admin/future/pages/Assets/constants.js +22 -0
  50. package/dist/admin/future/pages/Assets/constants.js.map +1 -1
  51. package/dist/admin/future/pages/Assets/constants.mjs +19 -1
  52. package/dist/admin/future/pages/Assets/constants.mjs.map +1 -1
  53. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +65 -10
  54. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
  55. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +66 -11
  56. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
  57. package/dist/admin/future/pages/Assets/hooks/useListScrollRestoration.js +111 -0
  58. package/dist/admin/future/pages/Assets/hooks/useListScrollRestoration.js.map +1 -0
  59. package/dist/admin/future/pages/Assets/hooks/useListScrollRestoration.mjs +109 -0
  60. package/dist/admin/future/pages/Assets/hooks/useListScrollRestoration.mjs.map +1 -0
  61. package/dist/admin/future/services/api.js +17 -0
  62. package/dist/admin/future/services/api.js.map +1 -1
  63. package/dist/admin/future/services/api.mjs +18 -1
  64. package/dist/admin/future/services/api.mjs.map +1 -1
  65. package/dist/admin/future/store/uploadProgress.js +31 -22
  66. package/dist/admin/future/store/uploadProgress.js.map +1 -1
  67. package/dist/admin/future/store/uploadProgress.mjs +31 -22
  68. package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
  69. package/dist/admin/index.js +11 -10
  70. package/dist/admin/index.js.map +1 -1
  71. package/dist/admin/index.mjs +11 -10
  72. package/dist/admin/index.mjs.map +1 -1
  73. package/dist/admin/src/future/components/Drawer.d.ts +10 -0
  74. package/dist/admin/src/future/pages/Assets/components/MainAreaContextMenu.d.ts +28 -0
  75. package/dist/admin/src/future/pages/Assets/constants.d.ts +20 -0
  76. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +4 -0
  77. package/dist/admin/src/future/pages/Assets/hooks/useListScrollRestoration.d.ts +15 -0
  78. package/dist/admin/src/future/store/uploadProgress.d.ts +14 -20
  79. package/dist/admin/translations/en.json.js +1 -3
  80. package/dist/admin/translations/en.json.js.map +1 -1
  81. package/dist/admin/translations/en.json.mjs +1 -3
  82. package/dist/admin/translations/en.json.mjs.map +1 -1
  83. package/dist/server/bootstrap.js +11 -0
  84. package/dist/server/bootstrap.js.map +1 -1
  85. package/dist/server/bootstrap.mjs +11 -0
  86. package/dist/server/bootstrap.mjs.map +1 -1
  87. package/dist/server/controllers/admin-upload.js +31 -1
  88. package/dist/server/controllers/admin-upload.js.map +1 -1
  89. package/dist/server/controllers/admin-upload.mjs +31 -1
  90. package/dist/server/controllers/admin-upload.mjs.map +1 -1
  91. package/dist/server/controllers/utils/find-entity-and-check-permissions.js +15 -4
  92. package/dist/server/controllers/utils/find-entity-and-check-permissions.js.map +1 -1
  93. package/dist/server/controllers/utils/find-entity-and-check-permissions.mjs +15 -4
  94. package/dist/server/controllers/utils/find-entity-and-check-permissions.mjs.map +1 -1
  95. package/dist/server/controllers/utils/folders.js +1 -1
  96. package/dist/server/controllers/utils/folders.js.map +1 -1
  97. package/dist/server/controllers/utils/folders.mjs +1 -1
  98. package/dist/server/controllers/utils/folders.mjs.map +1 -1
  99. package/dist/server/mcp/ambient-instance.js +46 -0
  100. package/dist/server/mcp/ambient-instance.js.map +1 -0
  101. package/dist/server/mcp/ambient-instance.mjs +43 -0
  102. package/dist/server/mcp/ambient-instance.mjs.map +1 -0
  103. package/dist/server/mcp/handlers/constants.js +60 -0
  104. package/dist/server/mcp/handlers/constants.js.map +1 -0
  105. package/dist/server/mcp/handlers/constants.mjs +45 -0
  106. package/dist/server/mcp/handlers/constants.mjs.map +1 -0
  107. package/dist/server/mcp/handlers/folder-handlers.js +308 -0
  108. package/dist/server/mcp/handlers/folder-handlers.js.map +1 -0
  109. package/dist/server/mcp/handlers/folder-handlers.mjs +303 -0
  110. package/dist/server/mcp/handlers/folder-handlers.mjs.map +1 -0
  111. package/dist/server/mcp/handlers/read-handlers.js +134 -0
  112. package/dist/server/mcp/handlers/read-handlers.js.map +1 -0
  113. package/dist/server/mcp/handlers/read-handlers.mjs +130 -0
  114. package/dist/server/mcp/handlers/read-handlers.mjs.map +1 -0
  115. package/dist/server/mcp/handlers/write-handlers.js +315 -0
  116. package/dist/server/mcp/handlers/write-handlers.js.map +1 -0
  117. package/dist/server/mcp/handlers/write-handlers.mjs +311 -0
  118. package/dist/server/mcp/handlers/write-handlers.mjs.map +1 -0
  119. package/dist/server/mcp/permissions.js +36 -0
  120. package/dist/server/mcp/permissions.js.map +1 -0
  121. package/dist/server/mcp/permissions.mjs +33 -0
  122. package/dist/server/mcp/permissions.mjs.map +1 -0
  123. package/dist/server/mcp/register-upload-mcp-tools.js +235 -0
  124. package/dist/server/mcp/register-upload-mcp-tools.js.map +1 -0
  125. package/dist/server/mcp/register-upload-mcp-tools.mjs +232 -0
  126. package/dist/server/mcp/register-upload-mcp-tools.mjs.map +1 -0
  127. package/dist/server/mcp/sanitizers/sanitize-media.js +97 -0
  128. package/dist/server/mcp/sanitizers/sanitize-media.js.map +1 -0
  129. package/dist/server/mcp/sanitizers/sanitize-media.mjs +93 -0
  130. package/dist/server/mcp/sanitizers/sanitize-media.mjs.map +1 -0
  131. package/dist/server/mcp/schemas/input-schemas.js +206 -0
  132. package/dist/server/mcp/schemas/input-schemas.js.map +1 -0
  133. package/dist/server/mcp/schemas/input-schemas.mjs +190 -0
  134. package/dist/server/mcp/schemas/input-schemas.mjs.map +1 -0
  135. package/dist/server/mcp/schemas/output-schemas.js +158 -0
  136. package/dist/server/mcp/schemas/output-schemas.js.map +1 -0
  137. package/dist/server/mcp/schemas/output-schemas.mjs +142 -0
  138. package/dist/server/mcp/schemas/output-schemas.mjs.map +1 -0
  139. package/dist/server/mcp/utils.js +14 -0
  140. package/dist/server/mcp/utils.js.map +1 -0
  141. package/dist/server/mcp/utils.mjs +12 -0
  142. package/dist/server/mcp/utils.mjs.map +1 -0
  143. package/dist/server/media-library-default-notice.js +42 -0
  144. package/dist/server/media-library-default-notice.js.map +1 -0
  145. package/dist/server/media-library-default-notice.mjs +40 -0
  146. package/dist/server/media-library-default-notice.mjs.map +1 -0
  147. package/dist/server/register.js +5 -0
  148. package/dist/server/register.js.map +1 -1
  149. package/dist/server/register.mjs +5 -0
  150. package/dist/server/register.mjs.map +1 -1
  151. package/dist/server/services/folder.js.map +1 -1
  152. package/dist/server/services/folder.mjs.map +1 -1
  153. package/dist/server/services/upload.js +34 -10
  154. package/dist/server/services/upload.js.map +1 -1
  155. package/dist/server/services/upload.mjs +34 -10
  156. package/dist/server/services/upload.mjs.map +1 -1
  157. package/dist/server/src/bootstrap.d.ts.map +1 -1
  158. package/dist/server/src/controllers/admin-upload.d.ts +1 -0
  159. package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
  160. package/dist/server/src/controllers/utils/find-entity-and-check-permissions.d.ts +14 -1
  161. package/dist/server/src/controllers/utils/find-entity-and-check-permissions.d.ts.map +1 -1
  162. package/dist/server/src/controllers/utils/folders.d.ts +2 -1
  163. package/dist/server/src/controllers/utils/folders.d.ts.map +1 -1
  164. package/dist/server/src/index.d.ts +10 -2
  165. package/dist/server/src/index.d.ts.map +1 -1
  166. package/dist/server/src/mcp/ambient-instance.d.ts +65 -0
  167. package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -0
  168. package/dist/server/src/mcp/handlers/constants.d.ts +48 -0
  169. package/dist/server/src/mcp/handlers/constants.d.ts.map +1 -0
  170. package/dist/server/src/mcp/handlers/folder-handlers.d.ts +49 -0
  171. package/dist/server/src/mcp/handlers/folder-handlers.d.ts.map +1 -0
  172. package/dist/server/src/mcp/handlers/index.d.ts +5 -0
  173. package/dist/server/src/mcp/handlers/index.d.ts.map +1 -0
  174. package/dist/server/src/mcp/handlers/read-handlers.d.ts +35 -0
  175. package/dist/server/src/mcp/handlers/read-handlers.d.ts.map +1 -0
  176. package/dist/server/src/mcp/handlers/write-handlers.d.ts +66 -0
  177. package/dist/server/src/mcp/handlers/write-handlers.d.ts.map +1 -0
  178. package/dist/server/src/mcp/index.d.ts +3 -0
  179. package/dist/server/src/mcp/index.d.ts.map +1 -0
  180. package/dist/server/src/mcp/permissions.d.ts +22 -0
  181. package/dist/server/src/mcp/permissions.d.ts.map +1 -0
  182. package/dist/server/src/mcp/register-upload-mcp-tools.d.ts +29 -0
  183. package/dist/server/src/mcp/register-upload-mcp-tools.d.ts.map +1 -0
  184. package/dist/server/src/mcp/sanitizers/sanitize-media.d.ts +63 -0
  185. package/dist/server/src/mcp/sanitizers/sanitize-media.d.ts.map +1 -0
  186. package/dist/server/src/mcp/schemas/index.d.ts +3 -0
  187. package/dist/server/src/mcp/schemas/index.d.ts.map +1 -0
  188. package/dist/server/src/mcp/schemas/input-schemas.d.ts +148 -0
  189. package/dist/server/src/mcp/schemas/input-schemas.d.ts.map +1 -0
  190. package/dist/server/src/mcp/schemas/output-schemas.d.ts +276 -0
  191. package/dist/server/src/mcp/schemas/output-schemas.d.ts.map +1 -0
  192. package/dist/server/src/mcp/types.d.ts +19 -0
  193. package/dist/server/src/mcp/types.d.ts.map +1 -0
  194. package/dist/server/src/mcp/utils.d.ts +4 -0
  195. package/dist/server/src/mcp/utils.d.ts.map +1 -0
  196. package/dist/server/src/media-library-default-notice.d.ts +19 -0
  197. package/dist/server/src/media-library-default-notice.d.ts.map +1 -0
  198. package/dist/server/src/register.d.ts.map +1 -1
  199. package/dist/server/src/services/folder.d.ts +6 -2
  200. package/dist/server/src/services/folder.d.ts.map +1 -1
  201. package/dist/server/src/services/index.d.ts +10 -2
  202. package/dist/server/src/services/index.d.ts.map +1 -1
  203. package/dist/server/src/services/upload.d.ts +10 -1
  204. package/dist/server/src/services/upload.d.ts.map +1 -1
  205. package/dist/server/src/types.d.ts +2 -2
  206. package/dist/server/src/types.d.ts.map +1 -1
  207. package/dist/server/src/utils/index.d.ts +2 -1
  208. package/dist/server/src/utils/index.d.ts.map +1 -1
  209. package/dist/server/utils/index.js +2 -2
  210. package/dist/server/utils/index.js.map +1 -1
  211. package/dist/server/utils/index.mjs +2 -2
  212. package/dist/server/utils/index.mjs.map +1 -1
  213. package/dist/shared/contracts/files.d.ts +22 -0
  214. package/dist/shared/contracts/files.d.ts.map +1 -1
  215. package/package.json +7 -6
  216. package/dist/admin/future/components/BetaNotice.js +0 -72
  217. package/dist/admin/future/components/BetaNotice.js.map +0 -1
  218. package/dist/admin/future/components/BetaNotice.mjs +0 -70
  219. package/dist/admin/future/components/BetaNotice.mjs.map +0 -1
  220. package/dist/admin/src/future/components/BetaNotice.d.ts +0 -11
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../admin/src/index.ts"],"sourcesContent":["import { Images } from '@strapi/icons';\n\nimport pluginPkg from '../../package.json';\n\nimport { MediaLibraryDialog } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport { MediaLibraryInput } from './components/MediaLibraryInput/MediaLibraryInput';\nimport { PERMISSIONS } from './constants';\nimport { UploadProgressDialog } from './future/components/UploadProgressDialog';\nimport { uploadProgressReducer } from './future/store/uploadProgress';\nimport { pluginId } from './pluginId';\nimport { getTrad, prefixPluginTranslations } from './utils';\n\nimport type { MediaLibraryDialogProps } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport type { MediaLibraryInputProps } from './components/MediaLibraryInput/MediaLibraryInput';\nimport type { StrapiApp } from '@strapi/admin/strapi-admin';\nimport type { Plugin } from '@strapi/types';\n\nconst name = pluginPkg.strapi.name;\n\nconst admin: Plugin.Config.AdminInput = {\n register(app: StrapiApp) {\n /**\n * The beta Media Library owns `plugins/upload` outright when the flag is on:\n * the legacy app is not registered at all, so there is exactly one Media\n * Library entry in the menu and no route to rename at GA.\n */\n const isBetaMediaLibrary = window.strapi.future.isEnabled('betaMediaLibrary');\n\n app.addMenuLink({\n to: `plugins/${pluginId}`,\n icon: Images,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Media Library',\n },\n permissions: PERMISSIONS.main,\n Component: isBetaMediaLibrary\n ? () => {\n return import('./future/App').then((mod) => ({\n default: mod.BetaMediaLibrary,\n }));\n }\n : () => {\n return import('./pages/App/App').then((mod) => ({ default: mod.Upload }));\n },\n position: 4,\n });\n\n if (isBetaMediaLibrary) {\n app.addReducers({ uploadProgress: uploadProgressReducer });\n\n app.addComponents([\n {\n name: 'future-global::upload-progress',\n Component: UploadProgressDialog,\n },\n ]);\n }\n\n app.addSettingsLink('global', {\n id: 'media-library-settings',\n to: 'media-library',\n intlLabel: {\n id: getTrad('plugin.name'),\n defaultMessage: 'Media Library',\n },\n Component() {\n return import('./pages/SettingsPage/SettingsPage').then((mod) => ({\n default: mod.ProtectedSettingsPage,\n }));\n },\n permissions: PERMISSIONS.settings,\n });\n\n app.addFields({\n type: 'media',\n Component: MediaLibraryInput as React.FC<Partial<MediaLibraryInputProps>>,\n });\n app.addComponents([\n {\n name: 'media-library',\n Component: MediaLibraryDialog as React.FC<Partial<MediaLibraryDialogProps>>,\n },\n ]);\n\n app.registerPlugin({\n id: pluginId,\n name,\n });\n },\n async registerTrads({ locales }: { locales: string[] }) {\n const importedTrads = await Promise.all(\n locales.map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: prefixPluginTranslations(data, pluginId),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return Promise.resolve(importedTrads);\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default admin;\n"],"names":["name","pluginPkg","strapi","admin","register","app","isBetaMediaLibrary","window","future","isEnabled","addMenuLink","to","pluginId","icon","Images","intlLabel","id","defaultMessage","permissions","PERMISSIONS","main","Component","then","mod","default","BetaMediaLibrary","Upload","position","addReducers","uploadProgress","uploadProgressReducer","addComponents","UploadProgressDialog","addSettingsLink","getTrad","ProtectedSettingsPage","settings","addFields","type","MediaLibraryInput","MediaLibraryDialog","registerPlugin","registerTrads","locales","importedTrads","Promise","all","map","locale","data","prefixPluginTranslations","catch","resolve"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../admin/src/index.ts"],"sourcesContent":["import { Images } from '@strapi/icons';\n\nimport pluginPkg from '../../package.json';\n\nimport { MediaLibraryDialog } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport { MediaLibraryInput } from './components/MediaLibraryInput/MediaLibraryInput';\nimport { PERMISSIONS } from './constants';\nimport { UploadProgressDialog } from './future/components/UploadProgressDialog';\nimport { uploadProgressReducer } from './future/store/uploadProgress';\nimport { pluginId } from './pluginId';\nimport { getTrad, prefixPluginTranslations } from './utils';\n\nimport type { MediaLibraryDialogProps } from './components/MediaLibraryDialog/MediaLibraryDialog';\nimport type { MediaLibraryInputProps } from './components/MediaLibraryInput/MediaLibraryInput';\nimport type { StrapiApp } from '@strapi/admin/strapi-admin';\nimport type { Plugin } from '@strapi/types';\n\nconst name = pluginPkg.strapi.name;\n\nconst admin: Plugin.Config.AdminInput = {\n register(app: StrapiApp) {\n /**\n * Whichever Media Library is selected owns `plugins/upload` outright: the other is\n * not registered at all, so there is exactly one Media Library entry in the menu.\n *\n * The new one is the default; `useLegacyMediaLibrary` opts back out.\n */\n const isLegacyMediaLibrary = window.strapi.featureFlags.isEnabled('useLegacyMediaLibrary');\n\n app.addMenuLink({\n to: `plugins/${pluginId}`,\n icon: Images,\n intlLabel: {\n id: `${pluginId}.plugin.name`,\n defaultMessage: 'Media Library',\n },\n permissions: PERMISSIONS.main,\n Component: isLegacyMediaLibrary\n ? () => {\n return import('./pages/App/App').then((mod) => ({ default: mod.Upload }));\n }\n : () => {\n return import('./future/App').then((mod) => ({\n default: mod.BetaMediaLibrary,\n }));\n },\n position: 4,\n });\n\n if (!isLegacyMediaLibrary) {\n app.addReducers({ uploadProgress: uploadProgressReducer });\n\n app.addComponents([\n {\n name: 'future-global::upload-progress',\n Component: UploadProgressDialog,\n },\n ]);\n }\n\n app.addSettingsLink('global', {\n id: 'media-library-settings',\n to: 'media-library',\n intlLabel: {\n id: getTrad('plugin.name'),\n defaultMessage: 'Media Library',\n },\n Component() {\n return import('./pages/SettingsPage/SettingsPage').then((mod) => ({\n default: mod.ProtectedSettingsPage,\n }));\n },\n permissions: PERMISSIONS.settings,\n });\n\n app.addFields({\n type: 'media',\n Component: MediaLibraryInput as React.FC<Partial<MediaLibraryInputProps>>,\n });\n app.addComponents([\n {\n name: 'media-library',\n Component: MediaLibraryDialog as React.FC<Partial<MediaLibraryDialogProps>>,\n },\n ]);\n\n app.registerPlugin({\n id: pluginId,\n name,\n });\n },\n async registerTrads({ locales }: { locales: string[] }) {\n const importedTrads = await Promise.all(\n locales.map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: prefixPluginTranslations(data, pluginId),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return Promise.resolve(importedTrads);\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default admin;\n"],"names":["name","pluginPkg","strapi","admin","register","app","isLegacyMediaLibrary","window","featureFlags","isEnabled","addMenuLink","to","pluginId","icon","Images","intlLabel","id","defaultMessage","permissions","PERMISSIONS","main","Component","then","mod","default","Upload","BetaMediaLibrary","position","addReducers","uploadProgress","uploadProgressReducer","addComponents","UploadProgressDialog","addSettingsLink","getTrad","ProtectedSettingsPage","settings","addFields","type","MediaLibraryInput","MediaLibraryDialog","registerPlugin","registerTrads","locales","importedTrads","Promise","all","map","locale","data","prefixPluginTranslations","catch","resolve"],"mappings":"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"}
@@ -3,12 +3,22 @@ import * as Dialog from '@radix-ui/react-dialog';
3
3
  import { FlexProps } from '@strapi/design-system';
4
4
  /** Duration of the close animation in ms. Use for timing cleanup (e.g. removing URL params). */
5
5
  export declare const DRAWER_CLOSE_ANIMATION_MS = 300;
6
+ type PointerDownOutsideHandler = NonNullable<Dialog.DialogContentProps['onPointerDownOutside']>;
6
7
  interface DrawerBodyProps extends Omit<FlexProps, 'width' | 'maxHeight'> {
7
8
  animationDirection?: 'up' | 'left';
8
9
  /** Width of the panel from the medium breakpoint up. Mobile is always full-bleed. */
9
10
  width?: string;
10
11
  /** Cap on the panel height. Defaults to the dynamic viewport height. */
11
12
  maxHeight?: string;
13
+ /**
14
+ * Opt in to dismiss-on-outside-click. Omitted, an outside pointer press never
15
+ * closes the drawer — it must be closed explicitly, as long-running panels
16
+ * like the upload progress dialog need. Passed, the handler can still veto
17
+ * individual presses via `event.preventDefault()`. Content rendered from
18
+ * inside the panel but portaled elsewhere (DS dialogs, popovers, tooltips)
19
+ * never counts as outside — Radix reads the React tree, not the DOM.
20
+ */
21
+ onPointerDownOutside?: PointerDownOutsideHandler;
12
22
  children: React.ReactNode;
13
23
  }
14
24
  interface DrawerRootProps {
@@ -0,0 +1,28 @@
1
+ interface MainAreaContextMenuProps {
2
+ /** Opens the "new folder" dialog in the folder currently on screen. */
3
+ onCreateFolder: () => void;
4
+ /** Opens the native file picker — same entry point as the header "New" menu. */
5
+ onImportFiles: () => void;
6
+ /** Opens the "import from URL" dialog. */
7
+ onImportFromUrl: () => void;
8
+ /**
9
+ * RBAC gate — without `assets.create` there is nothing to offer, so the
10
+ * right-click falls through to the browser. Required (not defaulted) so a
11
+ * permission gate can't silently regress to permissive.
12
+ */
13
+ disabled: boolean;
14
+ }
15
+ /**
16
+ * Drive/Dropbox-style right-click on the empty parts of the assets area: the
17
+ * same creation actions the header "New" menu offers, acting on the folder
18
+ * currently open.
19
+ *
20
+ * Renders no wrapper — it finds the scrolling column and listens there, so the
21
+ * hit area is the whole column including the padding below the list.
22
+ *
23
+ * Deliberately background-only. Right-clicking an asset, a folder or a table
24
+ * row is left alone — those carry `data-native-context-menu` and keep the
25
+ * browser's menu (which is what you want over a thumbnail or a filename).
26
+ */
27
+ export declare const MainAreaContextMenu: ({ onCreateFolder, onImportFiles, onImportFromUrl, disabled, }: MainAreaContextMenuProps) => import("react/jsx-runtime").JSX.Element;
28
+ export {};
@@ -5,6 +5,26 @@ export declare const viewOptions: {
5
5
  GRID: number;
6
6
  TABLE: number;
7
7
  };
8
+ /**
9
+ * Spread onto grid cards and table rows, whose click opens or switches the
10
+ * asset details drawer. The drawer's outside-click dismissal skips presses
11
+ * landing on one of these, so switching assets doesn't close-then-reopen it.
12
+ */
13
+ export declare const ASSET_DETAILS_TRIGGER_PROPS: {
14
+ "data-asset-details-trigger": string;
15
+ };
16
+ /**
17
+ * Spread onto the controls inside an asset card or row that act on the item
18
+ * rather than opening it — its selection checkbox and its actions menu. They
19
+ * stop the card's own click, so no details switch follows them.
20
+ */
21
+ export declare const ASSET_ITEM_CONTROL_PROPS: {
22
+ "data-asset-item-control": string;
23
+ };
24
+ /** Matches an element carrying {@link ASSET_ITEM_CONTROL_PROPS}. */
25
+ export declare const ASSET_ITEM_CONTROL_SELECTOR = "[data-asset-item-control]";
26
+ /** Matches an element carrying {@link ASSET_DETAILS_TRIGGER_PROPS}. */
27
+ export declare const ASSET_DETAILS_TRIGGER_SELECTOR = "[data-asset-details-trigger]";
8
28
  interface TableHeader {
9
29
  name: string;
10
30
  label: {
@@ -15,6 +15,10 @@ interface UseInfiniteAssetsOptions {
15
15
  * The caller MUST render the returned `subscribers` node — that is what keeps
16
16
  * every loaded page subscribed, so `{Asset, LIST}` invalidations keep the whole
17
17
  * list consistent rather than only the current page.
18
+ *
19
+ * Loaded pages survive navigating away and back: each list's accumulator is
20
+ * remembered (LRU, `MAX_REMEMBERED_LISTS`) and restored when its key returns, so
21
+ * stepping into a subfolder and back out keeps the rows the user scrolled for.
18
22
  */
19
23
  declare const useInfiniteAssets: ({ folder, sort, search, filters, enabled, }?: UseInfiniteAssetsOptions) => {
20
24
  assets: File[];
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Remembers where each list was scrolled to and puts it back on return.
3
+ *
4
+ * `key` fingerprints the list on screen (folder, search, sort, filters). While
5
+ * it holds steady the current offset is recorded; when it changes the incoming
6
+ * key's saved offset is restored, or the list is sent to the top if it has none
7
+ * — a first visit, or one whose entry has been dropped.
8
+ *
9
+ * Returns a callback ref to place on any element inside the scrolling column;
10
+ * it only locates that column, it is never scrolled itself.
11
+ *
12
+ * Restoring a *position* only helps if the rows that filled it come back too —
13
+ * that is `useInfiniteAssets`' job.
14
+ */
15
+ export declare const useListScrollRestoration: (key: string) => (node: HTMLElement | null) => void;
@@ -32,9 +32,8 @@ export interface UploadProgressState {
32
32
  errors: FileUploadError[];
33
33
  uploadId: number;
34
34
  /**
35
- * Whether this batch reports transferred bytes at all. The direct-file flow streams
36
- * byte counts from XHR; the URL flow leaves the fetch to the server and gets none back
37
- * so its byte-weighted aggregate is stuck at 0%.
35
+ * Whether every row's size was known when the batch opened (the direct-file flow), so
36
+ * the byte-weighted aggregate is meaningful. The URL flow learns sizes one row at a time.
38
37
  */
39
38
  reportsByteProgress: boolean;
40
39
  }
@@ -63,31 +62,25 @@ export declare const selectAggregateProgress: ((state: RootState) => number) & i
63
62
  clearCache: () => void;
64
63
  };
65
64
  /**
66
- * Whether to show byte-weighted `selectAggregateProgress` rather than count-based progress.
67
- * A batch that never reports bytes stays pinned at 0%, so the header falls back to
68
- * `selectCountBasedProgress`.
65
+ * Whether to show byte-weighted `selectAggregateProgress` rather than `selectCountBasedProgress`.
69
66
  *
70
- * Checks the rows too, not just the flag: an in-flight row reporting bytes proves the batch
71
- * can, so byte-weighting takes over once the URL flow starts emitting progress. Only
72
- * `uploading` rows count — completion backfills `uploadedBytes` to the file size, so letting
73
- * settled rows qualify would switch a multi-URL batch to byte-weighting mid-upload over only
74
- * the sizes known so far (transiently 100% after the first file).
67
+ * Only the flag: byte-weighting needs every size up front. A URL batch learns sizes one row
68
+ * at a time, so weighting over the sizes known so far makes the header jump backwards at
69
+ * every file boundary.
75
70
  */
76
- export declare const selectReportsByteProgress: ((state: RootState) => boolean) & import("reselect").OutputSelectorFields<(args_0: boolean, args_1: FileProgress[]) => boolean, {
71
+ export declare const selectReportsByteProgress: ((state: RootState) => boolean) & import("reselect").OutputSelectorFields<(args_0: boolean) => boolean, {
77
72
  clearCache: () => void;
78
73
  }> & {
79
74
  clearCache: () => void;
80
75
  };
81
76
  /**
82
- * Count-based progress (settled / total rows) for a batch that reports no transferred bytes
83
- * (the URL flow). Used by the header whenever `selectReportsByteProgress` is false.
77
+ * Row-weighted progress for a batch whose sizes are not known up front (the URL flow).
78
+ * Each row is worth `1 / total`: settled rows count fully and an in-flight row contributes
79
+ * `uploadedBytes / size` once it reports bytes, so a multi-URL batch climbs smoothly to
80
+ * 33 → 67 → 100 and never moves backwards.
84
81
  *
85
- * Never byte-weights, so a multi-URL batch climbs 33 67 100 as each file lands instead
86
- * of jumping to a transient 100% after the first.
87
- *
88
- * Returns `null` until a row settles — 0% is the frozen signal this flow exists to remove
89
- * (a lone URL upload would otherwise read "Uploading 1 item (0%)" throughout), so the header
90
- * stays indeterminate until there's real progress.
82
+ * Returns `null` until something has moved 0% is the frozen signal this flow exists to
83
+ * remove, so the header stays indeterminate until there's real progress.
91
84
  */
92
85
  export declare const selectCountBasedProgress: ((state: RootState) => number | null) & import("reselect").OutputSelectorFields<(args_0: FileProgress[]) => number | null, {
93
86
  clearCache: () => void;
@@ -177,6 +170,7 @@ export declare const openUploadProgress: import("@reduxjs/toolkit").ActionCreato
177
170
  index: number;
178
171
  bytes: number;
179
172
  uploadId: number;
173
+ size?: number;
180
174
  }, "uploadProgress/setFileProgress">, setFileComplete: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
181
175
  index: number;
182
176
  file: File;
@@ -102,9 +102,6 @@ var en = {
102
102
  "upload.progress.maximize": "Maximize",
103
103
  "upload.progress.minimize": "Minimize",
104
104
  "upload.progress.close": "Close",
105
- "beta.badge": "Beta",
106
- "beta.notice.close": "Close",
107
- "beta.notice.content": "This is a beta version of the Media Library. Some features are still in progress — please report any issue you run into.",
108
105
  "bulk.select.label": "Select all assets",
109
106
  "button.next": "Next",
110
107
  "new": "New",
@@ -341,6 +338,7 @@ var en = {
341
338
  "list.table.row.select": "Select {name}",
342
339
  "list.table.row.metadata-missing": "This asset is missing metadata (caption or alternative text).",
343
340
  "list.table.content.empty-label": "This field is empty",
341
+ "list.context-menu.label": "Media library actions",
344
342
  "list.bulk-actions.label": "Bulk actions",
345
343
  "list.bulk-actions.selected-count": "{count, plural, =1 {# item selected} other {# items selected}}",
346
344
  "list.bulk-actions.select-all": "Select all",
@@ -1 +1 @@
1
- {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -100,9 +100,6 @@ var en = {
100
100
  "upload.progress.maximize": "Maximize",
101
101
  "upload.progress.minimize": "Minimize",
102
102
  "upload.progress.close": "Close",
103
- "beta.badge": "Beta",
104
- "beta.notice.close": "Close",
105
- "beta.notice.content": "This is a beta version of the Media Library. Some features are still in progress — please report any issue you run into.",
106
103
  "bulk.select.label": "Select all assets",
107
104
  "button.next": "Next",
108
105
  "new": "New",
@@ -339,6 +336,7 @@ var en = {
339
336
  "list.table.row.select": "Select {name}",
340
337
  "list.table.row.metadata-missing": "This asset is missing metadata (caption or alternative text).",
341
338
  "list.table.content.empty-label": "This field is empty",
339
+ "list.context-menu.label": "Media library actions",
342
340
  "list.bulk-actions.label": "Bulk actions",
343
341
  "list.bulk-actions.selected-count": "{count, plural, =1 {# item selected} other {# items selected}}",
344
342
  "list.bulk-actions.select-all": "Select all",
@@ -1 +1 @@
1
- {"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,6 +2,7 @@
2
2
 
3
3
  var index = require('./utils/index.js');
4
4
  var constants = require('./constants.js');
5
+ var mediaLibraryDefaultNotice = require('./media-library-default-notice.js');
5
6
 
6
7
  async function bootstrap({ strapi: strapi1 }) {
7
8
  const defaultConfig = {
@@ -16,6 +17,9 @@ async function bootstrap({ strapi: strapi1 }) {
16
17
  sort: constants.ALLOWED_SORT_STRINGS[0]
17
18
  }
18
19
  };
20
+ // Whether this plugin has stored settings from an earlier boot, which is what separates
21
+ // an upgrading app from a fresh install for the Media Library default notice below.
22
+ let isExistingApp = false;
19
23
  for (const [key, defaultValue] of Object.entries(defaultConfig)){
20
24
  // set plugin store
21
25
  const configurator = strapi1.store({
@@ -24,6 +28,9 @@ async function bootstrap({ strapi: strapi1 }) {
24
28
  key
25
29
  });
26
30
  const config = await configurator.get({});
31
+ if (config) {
32
+ isExistingApp = true;
33
+ }
27
34
  if (config && Object.keys(defaultValue).every((key)=>Object.prototype.hasOwnProperty.call(config, key))) {
28
35
  continue;
29
36
  }
@@ -33,6 +40,10 @@ async function bootstrap({ strapi: strapi1 }) {
33
40
  value: Object.assign(defaultValue, config || {})
34
41
  });
35
42
  }
43
+ await mediaLibraryDefaultNotice.notifyMediaLibraryDefault({
44
+ strapi: strapi1,
45
+ isExistingApp
46
+ });
36
47
  await registerPermissionActions();
37
48
  await registerWebhookEvents();
38
49
  await index.getService('weeklyMetrics').registerCron();
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap.js","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { notifyMediaLibraryDefault } from './media-library-default-notice';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n // Whether this plugin has stored settings from an earlier boot, which is what separates\n // an upgrading app from a fresh install for the Media Library default notice below.\n let isExistingApp = false;\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n\n if (config) {\n isExistingApp = true;\n }\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await notifyMediaLibraryDefault({ strapi, isExistingApp });\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","isExistingApp","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","notifyMediaLibraryDefault","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { getService } from './utils/index.mjs';
2
2
  import { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants.mjs';
3
+ import { notifyMediaLibraryDefault } from './media-library-default-notice.mjs';
3
4
 
4
5
  async function bootstrap({ strapi: strapi1 }) {
5
6
  const defaultConfig = {
@@ -14,6 +15,9 @@ async function bootstrap({ strapi: strapi1 }) {
14
15
  sort: ALLOWED_SORT_STRINGS[0]
15
16
  }
16
17
  };
18
+ // Whether this plugin has stored settings from an earlier boot, which is what separates
19
+ // an upgrading app from a fresh install for the Media Library default notice below.
20
+ let isExistingApp = false;
17
21
  for (const [key, defaultValue] of Object.entries(defaultConfig)){
18
22
  // set plugin store
19
23
  const configurator = strapi1.store({
@@ -22,6 +26,9 @@ async function bootstrap({ strapi: strapi1 }) {
22
26
  key
23
27
  });
24
28
  const config = await configurator.get({});
29
+ if (config) {
30
+ isExistingApp = true;
31
+ }
25
32
  if (config && Object.keys(defaultValue).every((key)=>Object.prototype.hasOwnProperty.call(config, key))) {
26
33
  continue;
27
34
  }
@@ -31,6 +38,10 @@ async function bootstrap({ strapi: strapi1 }) {
31
38
  value: Object.assign(defaultValue, config || {})
32
39
  });
33
40
  }
41
+ await notifyMediaLibraryDefault({
42
+ strapi: strapi1,
43
+ isExistingApp
44
+ });
34
45
  await registerPermissionActions();
35
46
  await registerWebhookEvents();
36
47
  await getService('weeklyMetrics').registerCron();
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { getService } from './utils';\nimport { ALLOWED_SORT_STRINGS, ALLOWED_WEBHOOK_EVENTS } from './constants';\nimport { notifyMediaLibraryDefault } from './media-library-default-notice';\n\nexport async function bootstrap({ strapi }: { strapi: Core.Strapi }) {\n const defaultConfig = {\n settings: {\n sizeOptimization: true,\n responsiveDimensions: true,\n autoOrientation: false,\n aiMetadata: true,\n },\n view_configuration: {\n pageSize: 10,\n sort: ALLOWED_SORT_STRINGS[0],\n },\n };\n\n // Whether this plugin has stored settings from an earlier boot, which is what separates\n // an upgrading app from a fresh install for the Media Library default notice below.\n let isExistingApp = false;\n\n for (const [key, defaultValue] of Object.entries(defaultConfig)) {\n // set plugin store\n const configurator = strapi.store!({ type: 'plugin', name: 'upload', key });\n\n const config = await configurator.get({});\n\n if (config) {\n isExistingApp = true;\n }\n if (\n config &&\n Object.keys(defaultValue).every((key) => Object.prototype.hasOwnProperty.call(config, key))\n ) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n // if the config does not exist or does not have all the required keys\n // set from the defaultValue ensuring all required settings are present\n await configurator.set({\n value: Object.assign(defaultValue, config || {}),\n });\n }\n\n await notifyMediaLibraryDefault({ strapi, isExistingApp });\n\n await registerPermissionActions();\n await registerWebhookEvents();\n\n await getService('weeklyMetrics').registerCron();\n\n getService('metrics').sendUploadPluginMetrics();\n\n getService('extensions').signFileUrlsOnDocumentService();\n}\n\nconst registerWebhookEvents = async () =>\n Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {\n strapi.get('webhookStore').addAllowedEvent(key, value);\n });\n\nconst registerPermissionActions = async () => {\n const actions = [\n {\n section: 'plugins',\n displayName: 'Access the Media Library',\n uid: 'read',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Create (upload)',\n uid: 'assets.create',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Update (crop, details, replace) + delete',\n uid: 'assets.update',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Download',\n uid: 'assets.download',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Copy link',\n uid: 'assets.copy-link',\n subCategory: 'assets',\n pluginName: 'upload',\n },\n {\n section: 'plugins',\n displayName: 'Configure view',\n uid: 'configure-view',\n pluginName: 'upload',\n },\n {\n section: 'settings',\n displayName: 'Access the Media Library settings page',\n uid: 'settings.read',\n category: 'media library',\n pluginName: 'upload',\n },\n ];\n\n await strapi.service('admin::permission').actionProvider.registerMany(actions);\n};\n"],"names":["bootstrap","strapi","defaultConfig","settings","sizeOptimization","responsiveDimensions","autoOrientation","aiMetadata","view_configuration","pageSize","sort","ALLOWED_SORT_STRINGS","isExistingApp","key","defaultValue","Object","entries","configurator","store","type","name","config","get","keys","every","prototype","hasOwnProperty","call","set","value","assign","notifyMediaLibraryDefault","registerPermissionActions","registerWebhookEvents","getService","registerCron","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
@@ -18,6 +18,13 @@ var path__default = /*#__PURE__*/_interopDefault(path);
18
18
  var fse__default = /*#__PURE__*/_interopDefault(fse);
19
19
  var ___default = /*#__PURE__*/_interopDefault(_);
20
20
 
21
+ /**
22
+ * Minimum delay between two `file:progress` frames for the same URL.
23
+ *
24
+ * `fetchUrlToInputFile` reports once per streamed chunk (~8000 calls for a 512MB file at
25
+ * 64KB chunks); at ~5 frames a second a 10s transfer costs ~50 frames, which is plenty for
26
+ * a bar the user watches.
27
+ */ const URL_FETCH_PROGRESS_INTERVAL_MS = 200;
21
28
  var adminUpload = {
22
29
  async bulkUpdateFileInfo (ctx) {
23
30
  const { state: { userAbility, user }, request: { body } } = ctx;
@@ -249,6 +256,7 @@ var adminUpload = {
249
256
  * Accepts JSON body with URLs and fetches them server-side.
250
257
  * Streams Server-Sent Events as each URL is fetched and uploaded:
251
258
  * - file:fetching — when starting to fetch a URL
259
+ * - file:progress — throttled byte progress of the remote → server temp file transfer
252
260
  * - file:uploading — when upload starts for a fetched file
253
261
  * - file:complete — when a file is successfully uploaded
254
262
  * - file:error — when a URL fetch or upload fails
@@ -300,8 +308,30 @@ var adminUpload = {
300
308
  total
301
309
  });
302
310
  try {
311
+ // `fetchUrlToInputFile` reports raw, unthrottled progress — coalescing it into a
312
+ // sane frame rate is the caller's job. State is per URL: the loop is sequential.
313
+ let lastProgressAt = 0;
314
+ let hasAnnouncedSize = false;
315
+ let hasReachedTotal = false;
316
+ const onFetchProgress = ({ bytesWritten, totalBytes })=>{
317
+ // The frame that reaches the total always goes out, or a throttled last chunk
318
+ // leaves the row short of 100% until `file:complete`.
319
+ const isFinal = !hasReachedTotal && totalBytes !== null && bytesWritten >= totalBytes;
320
+ if (hasAnnouncedSize && !isFinal && Date.now() - lastProgressAt < URL_FETCH_PROGRESS_INTERVAL_MS) {
321
+ return;
322
+ }
323
+ hasAnnouncedSize = true;
324
+ hasReachedTotal = hasReachedTotal || isFinal;
325
+ lastProgressAt = Date.now();
326
+ writeSSE('file:progress', {
327
+ index: i,
328
+ loadedBytes: bytesWritten,
329
+ totalBytes,
330
+ phase: 'fetch'
331
+ });
332
+ };
303
333
  // Fetch URL to temp file
304
- const { file } = await fileService.fetchUrlToInputFile(url, tmpWorkingDirectory, sizeLimit);
334
+ const { file } = await fileService.fetchUrlToInputFile(url, tmpWorkingDirectory, sizeLimit, onFetchProgress);
305
335
  const fileName = file.originalFilename;
306
336
  writeSSE('file:uploading', {
307
337
  name: fileName,