@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
@@ -0,0 +1,12 @@
1
+ /** Wraps a plain object into the dual-representation MCP tool return value (text + structuredContent). */ const ok = (structuredContent)=>({
2
+ content: [
3
+ {
4
+ type: 'text',
5
+ text: JSON.stringify(structuredContent)
6
+ }
7
+ ],
8
+ structuredContent
9
+ });
10
+
11
+ export { ok };
12
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","sources":["../../../server/src/mcp/utils.ts"],"sourcesContent":["import type { Modules } from '@strapi/types';\n\n/** Wraps a plain object into the dual-representation MCP tool return value (text + structuredContent). */\nexport const ok = (\n structuredContent: Record<string, unknown>\n): Modules.MCP.McpToolHandlerReturn => ({\n content: [{ type: 'text', text: JSON.stringify(structuredContent) }],\n structuredContent,\n});\n"],"names":["ok","structuredContent","content","type","text","JSON","stringify"],"mappings":"AAEA,2GACO,MAAMA,EAAAA,GAAK,CAChBC,qBACsC;QACtCC,OAAAA,EAAS;AAAC,YAAA;gBAAEC,IAAAA,EAAM,MAAA;gBAAQC,IAAAA,EAAMC,IAAAA,CAAKC,SAAS,CAACL,iBAAAA;AAAmB;AAAE,SAAA;AACpEA,QAAAA;AACF,KAAA;;;;"}
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ const NOTICE_STORE_KEY = 'media_library_default_notice';
4
+ const NOTICE = [
5
+ 'The Media Library has been redesigned and is now the default.',
6
+ 'To keep the previous one, set `useLegacyMediaLibrary: true` in config/features.'
7
+ ].join(' ');
8
+ /**
9
+ * Tells an upgrading app, once, that its Media Library changed.
10
+ *
11
+ * At GA every existing app changes behaviour with nothing in its config to hint at it,
12
+ * because nobody has a flag set. Three conditions keep this from becoming noise:
13
+ *
14
+ * - only when the flag is absent — setting it either way is a deliberate choice, and
15
+ * `false` is how an app says "I know, I want the new one"
16
+ * - only for an app that has booted this plugin before, so a fresh install (which has
17
+ * no previous Media Library to lose) stays quiet
18
+ * - only once, tracked in the plugin store rather than in memory, so restarts and
19
+ * multi-instance deployments do not repeat it
20
+ */ const notifyMediaLibraryDefault = async ({ strapi, isExistingApp })=>{
21
+ const optOut = strapi.config.get('features.useLegacyMediaLibrary');
22
+ if (optOut !== undefined || !isExistingApp) {
23
+ return;
24
+ }
25
+ const store = strapi.store({
26
+ type: 'plugin',
27
+ name: 'upload',
28
+ key: NOTICE_STORE_KEY
29
+ });
30
+ if (await store.get({}) !== null) {
31
+ return;
32
+ }
33
+ strapi.log.info(NOTICE);
34
+ await store.set({
35
+ value: {
36
+ shown: true
37
+ }
38
+ });
39
+ };
40
+
41
+ exports.notifyMediaLibraryDefault = notifyMediaLibraryDefault;
42
+ //# sourceMappingURL=media-library-default-notice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-library-default-notice.js","sources":["../../server/src/media-library-default-notice.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nconst NOTICE_STORE_KEY = 'media_library_default_notice';\n\nconst NOTICE = [\n 'The Media Library has been redesigned and is now the default.',\n 'To keep the previous one, set `useLegacyMediaLibrary: true` in config/features.',\n].join(' ');\n\n/**\n * Tells an upgrading app, once, that its Media Library changed.\n *\n * At GA every existing app changes behaviour with nothing in its config to hint at it,\n * because nobody has a flag set. Three conditions keep this from becoming noise:\n *\n * - only when the flag is absent — setting it either way is a deliberate choice, and\n * `false` is how an app says \"I know, I want the new one\"\n * - only for an app that has booted this plugin before, so a fresh install (which has\n * no previous Media Library to lose) stays quiet\n * - only once, tracked in the plugin store rather than in memory, so restarts and\n * multi-instance deployments do not repeat it\n */\nexport const notifyMediaLibraryDefault = async ({\n strapi,\n isExistingApp,\n}: {\n strapi: Core.Strapi;\n isExistingApp: boolean;\n}) => {\n const optOut = strapi.config.get('features.useLegacyMediaLibrary');\n\n if (optOut !== undefined || !isExistingApp) {\n return;\n }\n\n const store = strapi.store!({ type: 'plugin', name: 'upload', key: NOTICE_STORE_KEY });\n\n if ((await store.get({})) !== null) {\n return;\n }\n\n strapi.log.info(NOTICE);\n await store.set({ value: { shown: true } });\n};\n"],"names":["NOTICE_STORE_KEY","NOTICE","join","notifyMediaLibraryDefault","strapi","isExistingApp","optOut","config","get","undefined","store","type","name","key","log","info","set","value","shown"],"mappings":";;AAEA,MAAMA,gBAAAA,GAAmB,8BAAA;AAEzB,MAAMC,MAAAA,GAAS;AACb,IAAA,+DAAA;AACA,IAAA;AACD,CAAA,CAACC,IAAI,CAAC,GAAA,CAAA;AAEP;;;;;;;;;;;;UAaaC,yBAAAA,GAA4B,OAAO,EAC9CC,MAAM,EACNC,aAAa,EAId,GAAA;AACC,IAAA,MAAMC,MAAAA,GAASF,MAAAA,CAAOG,MAAM,CAACC,GAAG,CAAC,gCAAA,CAAA;IAEjC,IAAIF,MAAAA,KAAWG,SAAAA,IAAa,CAACJ,aAAAA,EAAe;AAC1C,QAAA;AACF,IAAA;IAEA,MAAMK,KAAAA,GAAQN,MAAAA,CAAOM,KAAK,CAAE;QAAEC,IAAAA,EAAM,QAAA;QAAUC,IAAAA,EAAM,QAAA;QAAUC,GAAAA,EAAKb;AAAiB,KAAA,CAAA;AAEpF,IAAA,IAAI,MAAOU,KAAAA,CAAMF,GAAG,CAAC,QAAS,IAAA,EAAM;AAClC,QAAA;AACF,IAAA;IAEAJ,MAAAA,CAAOU,GAAG,CAACC,IAAI,CAACd,MAAAA,CAAAA;IAChB,MAAMS,KAAAA,CAAMM,GAAG,CAAC;QAAEC,KAAAA,EAAO;YAAEC,KAAAA,EAAO;AAAK;AAAE,KAAA,CAAA;AAC3C;;;;"}
@@ -0,0 +1,40 @@
1
+ const NOTICE_STORE_KEY = 'media_library_default_notice';
2
+ const NOTICE = [
3
+ 'The Media Library has been redesigned and is now the default.',
4
+ 'To keep the previous one, set `useLegacyMediaLibrary: true` in config/features.'
5
+ ].join(' ');
6
+ /**
7
+ * Tells an upgrading app, once, that its Media Library changed.
8
+ *
9
+ * At GA every existing app changes behaviour with nothing in its config to hint at it,
10
+ * because nobody has a flag set. Three conditions keep this from becoming noise:
11
+ *
12
+ * - only when the flag is absent — setting it either way is a deliberate choice, and
13
+ * `false` is how an app says "I know, I want the new one"
14
+ * - only for an app that has booted this plugin before, so a fresh install (which has
15
+ * no previous Media Library to lose) stays quiet
16
+ * - only once, tracked in the plugin store rather than in memory, so restarts and
17
+ * multi-instance deployments do not repeat it
18
+ */ const notifyMediaLibraryDefault = async ({ strapi, isExistingApp })=>{
19
+ const optOut = strapi.config.get('features.useLegacyMediaLibrary');
20
+ if (optOut !== undefined || !isExistingApp) {
21
+ return;
22
+ }
23
+ const store = strapi.store({
24
+ type: 'plugin',
25
+ name: 'upload',
26
+ key: NOTICE_STORE_KEY
27
+ });
28
+ if (await store.get({}) !== null) {
29
+ return;
30
+ }
31
+ strapi.log.info(NOTICE);
32
+ await store.set({
33
+ value: {
34
+ shown: true
35
+ }
36
+ });
37
+ };
38
+
39
+ export { notifyMediaLibraryDefault };
40
+ //# sourceMappingURL=media-library-default-notice.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-library-default-notice.mjs","sources":["../../server/src/media-library-default-notice.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nconst NOTICE_STORE_KEY = 'media_library_default_notice';\n\nconst NOTICE = [\n 'The Media Library has been redesigned and is now the default.',\n 'To keep the previous one, set `useLegacyMediaLibrary: true` in config/features.',\n].join(' ');\n\n/**\n * Tells an upgrading app, once, that its Media Library changed.\n *\n * At GA every existing app changes behaviour with nothing in its config to hint at it,\n * because nobody has a flag set. Three conditions keep this from becoming noise:\n *\n * - only when the flag is absent — setting it either way is a deliberate choice, and\n * `false` is how an app says \"I know, I want the new one\"\n * - only for an app that has booted this plugin before, so a fresh install (which has\n * no previous Media Library to lose) stays quiet\n * - only once, tracked in the plugin store rather than in memory, so restarts and\n * multi-instance deployments do not repeat it\n */\nexport const notifyMediaLibraryDefault = async ({\n strapi,\n isExistingApp,\n}: {\n strapi: Core.Strapi;\n isExistingApp: boolean;\n}) => {\n const optOut = strapi.config.get('features.useLegacyMediaLibrary');\n\n if (optOut !== undefined || !isExistingApp) {\n return;\n }\n\n const store = strapi.store!({ type: 'plugin', name: 'upload', key: NOTICE_STORE_KEY });\n\n if ((await store.get({})) !== null) {\n return;\n }\n\n strapi.log.info(NOTICE);\n await store.set({ value: { shown: true } });\n};\n"],"names":["NOTICE_STORE_KEY","NOTICE","join","notifyMediaLibraryDefault","strapi","isExistingApp","optOut","config","get","undefined","store","type","name","key","log","info","set","value","shown"],"mappings":"AAEA,MAAMA,gBAAAA,GAAmB,8BAAA;AAEzB,MAAMC,MAAAA,GAAS;AACb,IAAA,+DAAA;AACA,IAAA;AACD,CAAA,CAACC,IAAI,CAAC,GAAA,CAAA;AAEP;;;;;;;;;;;;UAaaC,yBAAAA,GAA4B,OAAO,EAC9CC,MAAM,EACNC,aAAa,EAId,GAAA;AACC,IAAA,MAAMC,MAAAA,GAASF,MAAAA,CAAOG,MAAM,CAACC,GAAG,CAAC,gCAAA,CAAA;IAEjC,IAAIF,MAAAA,KAAWG,SAAAA,IAAa,CAACJ,aAAAA,EAAe;AAC1C,QAAA;AACF,IAAA;IAEA,MAAMK,KAAAA,GAAQN,MAAAA,CAAOM,KAAK,CAAE;QAAEC,IAAAA,EAAM,QAAA;QAAUC,IAAAA,EAAM,QAAA;QAAUC,GAAAA,EAAKb;AAAiB,KAAA,CAAA;AAEpF,IAAA,IAAI,MAAOU,KAAAA,CAAMF,GAAG,CAAC,QAAS,IAAA,EAAM;AAClC,QAAA;AACF,IAAA;IAEAJ,MAAAA,CAAOU,GAAG,CAACC,IAAI,CAACd,MAAAA,CAAAA;IAChB,MAAMS,KAAAA,CAAMM,GAAG,CAAC;QAAEC,KAAAA,EAAO;YAAEC,KAAAA,EAAO;AAAK;AAAE,KAAA,CAAA;AAC3C;;;;"}
@@ -6,6 +6,7 @@ var utils = require('@strapi/utils');
6
6
  var upload = require('./middlewares/upload.js');
7
7
  var contentApi = require('./documentation/content-api.json.js');
8
8
  var aiMetadataJob = require('./models/ai-metadata-job.js');
9
+ var registerUploadMcpTools = require('./mcp/register-upload-mcp-tools.js');
9
10
 
10
11
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
12
 
@@ -35,6 +36,10 @@ const { bytesToHumanReadable, kbytesToBytes } = utils.file;
35
36
  await upload({
36
37
  strapi
37
38
  });
39
+ // Register phase, before the MCP HTTP server starts during bootstrap.
40
+ registerUploadMcpTools.registerUploadMcpTools({
41
+ strapi
42
+ });
38
43
  if (strapi.plugin('graphql')) {
39
44
  const { installGraphqlExtension } = await Promise.resolve().then(function () { return require('./graphql.js'); });
40
45
  installGraphqlExtension({
@@ -1 +1 @@
1
- {"version":3,"file":"register.js","sources":["../../server/src/register.ts"],"sourcesContent":["import _ from 'lodash';\nimport sharp from 'sharp';\n\nimport { errors, file } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\n\nimport registerUploadMiddleware from './middlewares/upload';\nimport spec from '../../documentation/content-api.json';\nimport type { Config, File, InputFile } from './types';\nimport { aiMetadataJob } from './models/ai-metadata-job';\n\nconst { PayloadTooLargeError } = errors;\nconst { bytesToHumanReadable, kbytesToBytes } = file;\n\n/**\n * Register upload plugin\n */\nexport async function register({ strapi }: { strapi: Core.Strapi }) {\n // Register AI metadata job model\n strapi.get('models').add(aiMetadataJob);\n\n const raw = strapi.config.get<Partial<Config> | null | undefined>('plugin::upload') ?? {};\n // createProvider needs a provider; empty get() (e.g. in tests) still has defaults.\n const uploadConfig = {\n provider: 'local' as const,\n providerOptions: {} as Config['providerOptions'],\n actionOptions: {} as Config['actionOptions'],\n ...raw,\n } as Config;\n\n // Configure sharp memory management\n const { cache = false, concurrency = 1 } = uploadConfig.sharp ?? {};\n sharp.cache(cache);\n sharp.concurrency(concurrency);\n\n strapi.plugin('upload').provider = createProvider(uploadConfig);\n\n await registerUploadMiddleware({ strapi });\n\n if (strapi.plugin('graphql')) {\n const { installGraphqlExtension } = await import('./graphql.js');\n installGraphqlExtension({ strapi });\n }\n\n if (strapi.plugin('documentation')) {\n strapi\n .plugin('documentation')\n .service('override')\n .registerOverride(spec, {\n pluginOrigin: 'upload',\n excludeFromGeneration: ['upload'],\n });\n }\n}\n\nconst createProvider = (config: Config) => {\n const { providerOptions, actionOptions = {} } = config;\n\n const providerName = _.toLower(config.provider);\n let provider;\n\n let modulePath;\n try {\n modulePath = require.resolve(`@strapi/provider-upload-${providerName}`);\n } catch (error) {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'MODULE_NOT_FOUND'\n ) {\n modulePath = providerName;\n } else {\n throw error;\n }\n }\n\n try {\n provider = require(modulePath);\n } catch (err) {\n const newError = new Error(`Could not load upload provider \"${providerName}\".`);\n\n if (err instanceof Error) {\n newError.stack = err.stack;\n }\n\n throw newError;\n }\n\n const providerInstance = provider.init(providerOptions);\n\n if (!providerInstance.delete) {\n throw new Error(`The upload provider \"${providerName}\" doesn't implement the delete method.`);\n }\n\n if (!providerInstance.upload && !providerInstance.uploadStream) {\n throw new Error(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream nor the upload method.`\n );\n }\n\n if (!providerInstance.uploadStream) {\n process.emitWarning(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream function. Strapi will fallback on the upload method. Some performance issues may occur.`\n );\n }\n\n const wrappedProvider = _.mapValues(providerInstance, (method, methodName) => {\n return async (file: File, options = actionOptions[methodName]) =>\n providerInstance[methodName](file, options);\n });\n\n return Object.assign(Object.create(baseProvider), wrappedProvider);\n};\n\nconst baseProvider = {\n extend(obj: unknown) {\n Object.assign(this, obj);\n },\n checkFileSize(file: InputFile, { sizeLimit }: { sizeLimit: number }) {\n if (sizeLimit && kbytesToBytes(file.size) > sizeLimit) {\n throw new PayloadTooLargeError(\n `${file.originalFilename} exceeds size limit of ${bytesToHumanReadable(sizeLimit)}.`\n );\n }\n },\n getSignedUrl(file: File) {\n return file;\n },\n isPrivate() {\n return false;\n },\n};\n"],"names":["PayloadTooLargeError","errors","bytesToHumanReadable","kbytesToBytes","file","register","strapi","get","add","aiMetadataJob","raw","config","uploadConfig","provider","providerOptions","actionOptions","cache","concurrency","sharp","plugin","createProvider","registerUploadMiddleware","installGraphqlExtension","service","registerOverride","spec","pluginOrigin","excludeFromGeneration","providerName","_","toLower","modulePath","require","resolve","error","code","err","newError","Error","stack","providerInstance","init","delete","upload","uploadStream","process","emitWarning","wrappedProvider","mapValues","method","methodName","options","Object","assign","create","baseProvider","extend","obj","checkFileSize","sizeLimit","size","originalFilename","getSignedUrl","isPrivate"],"mappings":"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"}
1
+ {"version":3,"file":"register.js","sources":["../../server/src/register.ts"],"sourcesContent":["import _ from 'lodash';\nimport sharp from 'sharp';\n\nimport { errors, file } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\n\nimport registerUploadMiddleware from './middlewares/upload';\nimport spec from '../../documentation/content-api.json';\nimport type { Config, File, InputFile } from './types';\nimport { aiMetadataJob } from './models/ai-metadata-job';\nimport { registerUploadMcpTools } from './mcp';\n\nconst { PayloadTooLargeError } = errors;\nconst { bytesToHumanReadable, kbytesToBytes } = file;\n\n/**\n * Register upload plugin\n */\nexport async function register({ strapi }: { strapi: Core.Strapi }) {\n // Register AI metadata job model\n strapi.get('models').add(aiMetadataJob);\n\n const raw = strapi.config.get<Partial<Config> | null | undefined>('plugin::upload') ?? {};\n // createProvider needs a provider; empty get() (e.g. in tests) still has defaults.\n const uploadConfig = {\n provider: 'local' as const,\n providerOptions: {} as Config['providerOptions'],\n actionOptions: {} as Config['actionOptions'],\n ...raw,\n } as Config;\n\n // Configure sharp memory management\n const { cache = false, concurrency = 1 } = uploadConfig.sharp ?? {};\n sharp.cache(cache);\n sharp.concurrency(concurrency);\n\n strapi.plugin('upload').provider = createProvider(uploadConfig);\n\n await registerUploadMiddleware({ strapi });\n\n // Register phase, before the MCP HTTP server starts during bootstrap.\n registerUploadMcpTools({ strapi });\n\n if (strapi.plugin('graphql')) {\n const { installGraphqlExtension } = await import('./graphql.js');\n installGraphqlExtension({ strapi });\n }\n\n if (strapi.plugin('documentation')) {\n strapi\n .plugin('documentation')\n .service('override')\n .registerOverride(spec, {\n pluginOrigin: 'upload',\n excludeFromGeneration: ['upload'],\n });\n }\n}\n\nconst createProvider = (config: Config) => {\n const { providerOptions, actionOptions = {} } = config;\n\n const providerName = _.toLower(config.provider);\n let provider;\n\n let modulePath;\n try {\n modulePath = require.resolve(`@strapi/provider-upload-${providerName}`);\n } catch (error) {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'MODULE_NOT_FOUND'\n ) {\n modulePath = providerName;\n } else {\n throw error;\n }\n }\n\n try {\n provider = require(modulePath);\n } catch (err) {\n const newError = new Error(`Could not load upload provider \"${providerName}\".`);\n\n if (err instanceof Error) {\n newError.stack = err.stack;\n }\n\n throw newError;\n }\n\n const providerInstance = provider.init(providerOptions);\n\n if (!providerInstance.delete) {\n throw new Error(`The upload provider \"${providerName}\" doesn't implement the delete method.`);\n }\n\n if (!providerInstance.upload && !providerInstance.uploadStream) {\n throw new Error(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream nor the upload method.`\n );\n }\n\n if (!providerInstance.uploadStream) {\n process.emitWarning(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream function. Strapi will fallback on the upload method. Some performance issues may occur.`\n );\n }\n\n const wrappedProvider = _.mapValues(providerInstance, (method, methodName) => {\n return async (file: File, options = actionOptions[methodName]) =>\n providerInstance[methodName](file, options);\n });\n\n return Object.assign(Object.create(baseProvider), wrappedProvider);\n};\n\nconst baseProvider = {\n extend(obj: unknown) {\n Object.assign(this, obj);\n },\n checkFileSize(file: InputFile, { sizeLimit }: { sizeLimit: number }) {\n if (sizeLimit && kbytesToBytes(file.size) > sizeLimit) {\n throw new PayloadTooLargeError(\n `${file.originalFilename} exceeds size limit of ${bytesToHumanReadable(sizeLimit)}.`\n );\n }\n },\n getSignedUrl(file: File) {\n return file;\n },\n isPrivate() {\n return false;\n },\n};\n"],"names":["PayloadTooLargeError","errors","bytesToHumanReadable","kbytesToBytes","file","register","strapi","get","add","aiMetadataJob","raw","config","uploadConfig","provider","providerOptions","actionOptions","cache","concurrency","sharp","plugin","createProvider","registerUploadMiddleware","registerUploadMcpTools","installGraphqlExtension","service","registerOverride","spec","pluginOrigin","excludeFromGeneration","providerName","_","toLower","modulePath","require","resolve","error","code","err","newError","Error","stack","providerInstance","init","delete","upload","uploadStream","process","emitWarning","wrappedProvider","mapValues","method","methodName","options","Object","assign","create","baseProvider","extend","obj","checkFileSize","sizeLimit","size","originalFilename","getSignedUrl","isPrivate"],"mappings":"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"}
@@ -4,6 +4,7 @@ import { errors, file } from '@strapi/utils';
4
4
  import registerUploadMiddleware from './middlewares/upload.mjs';
5
5
  import spec from './documentation/content-api.json.mjs';
6
6
  import { aiMetadataJob } from './models/ai-metadata-job.mjs';
7
+ import { registerUploadMcpTools } from './mcp/register-upload-mcp-tools.mjs';
7
8
 
8
9
  const { PayloadTooLargeError } = errors;
9
10
  const { bytesToHumanReadable, kbytesToBytes } = file;
@@ -28,6 +29,10 @@ const { bytesToHumanReadable, kbytesToBytes } = file;
28
29
  await registerUploadMiddleware({
29
30
  strapi
30
31
  });
32
+ // Register phase, before the MCP HTTP server starts during bootstrap.
33
+ registerUploadMcpTools({
34
+ strapi
35
+ });
31
36
  if (strapi.plugin('graphql')) {
32
37
  const { installGraphqlExtension } = await import('./graphql.mjs');
33
38
  installGraphqlExtension({
@@ -1 +1 @@
1
- {"version":3,"file":"register.mjs","sources":["../../server/src/register.ts"],"sourcesContent":["import _ from 'lodash';\nimport sharp from 'sharp';\n\nimport { errors, file } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\n\nimport registerUploadMiddleware from './middlewares/upload';\nimport spec from '../../documentation/content-api.json';\nimport type { Config, File, InputFile } from './types';\nimport { aiMetadataJob } from './models/ai-metadata-job';\n\nconst { PayloadTooLargeError } = errors;\nconst { bytesToHumanReadable, kbytesToBytes } = file;\n\n/**\n * Register upload plugin\n */\nexport async function register({ strapi }: { strapi: Core.Strapi }) {\n // Register AI metadata job model\n strapi.get('models').add(aiMetadataJob);\n\n const raw = strapi.config.get<Partial<Config> | null | undefined>('plugin::upload') ?? {};\n // createProvider needs a provider; empty get() (e.g. in tests) still has defaults.\n const uploadConfig = {\n provider: 'local' as const,\n providerOptions: {} as Config['providerOptions'],\n actionOptions: {} as Config['actionOptions'],\n ...raw,\n } as Config;\n\n // Configure sharp memory management\n const { cache = false, concurrency = 1 } = uploadConfig.sharp ?? {};\n sharp.cache(cache);\n sharp.concurrency(concurrency);\n\n strapi.plugin('upload').provider = createProvider(uploadConfig);\n\n await registerUploadMiddleware({ strapi });\n\n if (strapi.plugin('graphql')) {\n const { installGraphqlExtension } = await import('./graphql.js');\n installGraphqlExtension({ strapi });\n }\n\n if (strapi.plugin('documentation')) {\n strapi\n .plugin('documentation')\n .service('override')\n .registerOverride(spec, {\n pluginOrigin: 'upload',\n excludeFromGeneration: ['upload'],\n });\n }\n}\n\nconst createProvider = (config: Config) => {\n const { providerOptions, actionOptions = {} } = config;\n\n const providerName = _.toLower(config.provider);\n let provider;\n\n let modulePath;\n try {\n modulePath = require.resolve(`@strapi/provider-upload-${providerName}`);\n } catch (error) {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'MODULE_NOT_FOUND'\n ) {\n modulePath = providerName;\n } else {\n throw error;\n }\n }\n\n try {\n provider = require(modulePath);\n } catch (err) {\n const newError = new Error(`Could not load upload provider \"${providerName}\".`);\n\n if (err instanceof Error) {\n newError.stack = err.stack;\n }\n\n throw newError;\n }\n\n const providerInstance = provider.init(providerOptions);\n\n if (!providerInstance.delete) {\n throw new Error(`The upload provider \"${providerName}\" doesn't implement the delete method.`);\n }\n\n if (!providerInstance.upload && !providerInstance.uploadStream) {\n throw new Error(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream nor the upload method.`\n );\n }\n\n if (!providerInstance.uploadStream) {\n process.emitWarning(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream function. Strapi will fallback on the upload method. Some performance issues may occur.`\n );\n }\n\n const wrappedProvider = _.mapValues(providerInstance, (method, methodName) => {\n return async (file: File, options = actionOptions[methodName]) =>\n providerInstance[methodName](file, options);\n });\n\n return Object.assign(Object.create(baseProvider), wrappedProvider);\n};\n\nconst baseProvider = {\n extend(obj: unknown) {\n Object.assign(this, obj);\n },\n checkFileSize(file: InputFile, { sizeLimit }: { sizeLimit: number }) {\n if (sizeLimit && kbytesToBytes(file.size) > sizeLimit) {\n throw new PayloadTooLargeError(\n `${file.originalFilename} exceeds size limit of ${bytesToHumanReadable(sizeLimit)}.`\n );\n }\n },\n getSignedUrl(file: File) {\n return file;\n },\n isPrivate() {\n return false;\n },\n};\n"],"names":["PayloadTooLargeError","errors","bytesToHumanReadable","kbytesToBytes","file","register","strapi","get","add","aiMetadataJob","raw","config","uploadConfig","provider","providerOptions","actionOptions","cache","concurrency","sharp","plugin","createProvider","registerUploadMiddleware","installGraphqlExtension","service","registerOverride","spec","pluginOrigin","excludeFromGeneration","providerName","_","toLower","modulePath","require","resolve","error","code","err","newError","Error","stack","providerInstance","init","delete","upload","uploadStream","process","emitWarning","wrappedProvider","mapValues","method","methodName","options","Object","assign","create","baseProvider","extend","obj","checkFileSize","sizeLimit","size","originalFilename","getSignedUrl","isPrivate"],"mappings":"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"}
1
+ {"version":3,"file":"register.mjs","sources":["../../server/src/register.ts"],"sourcesContent":["import _ from 'lodash';\nimport sharp from 'sharp';\n\nimport { errors, file } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\n\nimport registerUploadMiddleware from './middlewares/upload';\nimport spec from '../../documentation/content-api.json';\nimport type { Config, File, InputFile } from './types';\nimport { aiMetadataJob } from './models/ai-metadata-job';\nimport { registerUploadMcpTools } from './mcp';\n\nconst { PayloadTooLargeError } = errors;\nconst { bytesToHumanReadable, kbytesToBytes } = file;\n\n/**\n * Register upload plugin\n */\nexport async function register({ strapi }: { strapi: Core.Strapi }) {\n // Register AI metadata job model\n strapi.get('models').add(aiMetadataJob);\n\n const raw = strapi.config.get<Partial<Config> | null | undefined>('plugin::upload') ?? {};\n // createProvider needs a provider; empty get() (e.g. in tests) still has defaults.\n const uploadConfig = {\n provider: 'local' as const,\n providerOptions: {} as Config['providerOptions'],\n actionOptions: {} as Config['actionOptions'],\n ...raw,\n } as Config;\n\n // Configure sharp memory management\n const { cache = false, concurrency = 1 } = uploadConfig.sharp ?? {};\n sharp.cache(cache);\n sharp.concurrency(concurrency);\n\n strapi.plugin('upload').provider = createProvider(uploadConfig);\n\n await registerUploadMiddleware({ strapi });\n\n // Register phase, before the MCP HTTP server starts during bootstrap.\n registerUploadMcpTools({ strapi });\n\n if (strapi.plugin('graphql')) {\n const { installGraphqlExtension } = await import('./graphql.js');\n installGraphqlExtension({ strapi });\n }\n\n if (strapi.plugin('documentation')) {\n strapi\n .plugin('documentation')\n .service('override')\n .registerOverride(spec, {\n pluginOrigin: 'upload',\n excludeFromGeneration: ['upload'],\n });\n }\n}\n\nconst createProvider = (config: Config) => {\n const { providerOptions, actionOptions = {} } = config;\n\n const providerName = _.toLower(config.provider);\n let provider;\n\n let modulePath;\n try {\n modulePath = require.resolve(`@strapi/provider-upload-${providerName}`);\n } catch (error) {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'MODULE_NOT_FOUND'\n ) {\n modulePath = providerName;\n } else {\n throw error;\n }\n }\n\n try {\n provider = require(modulePath);\n } catch (err) {\n const newError = new Error(`Could not load upload provider \"${providerName}\".`);\n\n if (err instanceof Error) {\n newError.stack = err.stack;\n }\n\n throw newError;\n }\n\n const providerInstance = provider.init(providerOptions);\n\n if (!providerInstance.delete) {\n throw new Error(`The upload provider \"${providerName}\" doesn't implement the delete method.`);\n }\n\n if (!providerInstance.upload && !providerInstance.uploadStream) {\n throw new Error(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream nor the upload method.`\n );\n }\n\n if (!providerInstance.uploadStream) {\n process.emitWarning(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream function. Strapi will fallback on the upload method. Some performance issues may occur.`\n );\n }\n\n const wrappedProvider = _.mapValues(providerInstance, (method, methodName) => {\n return async (file: File, options = actionOptions[methodName]) =>\n providerInstance[methodName](file, options);\n });\n\n return Object.assign(Object.create(baseProvider), wrappedProvider);\n};\n\nconst baseProvider = {\n extend(obj: unknown) {\n Object.assign(this, obj);\n },\n checkFileSize(file: InputFile, { sizeLimit }: { sizeLimit: number }) {\n if (sizeLimit && kbytesToBytes(file.size) > sizeLimit) {\n throw new PayloadTooLargeError(\n `${file.originalFilename} exceeds size limit of ${bytesToHumanReadable(sizeLimit)}.`\n );\n }\n },\n getSignedUrl(file: File) {\n return file;\n },\n isPrivate() {\n return false;\n },\n};\n"],"names":["PayloadTooLargeError","errors","bytesToHumanReadable","kbytesToBytes","file","register","strapi","get","add","aiMetadataJob","raw","config","uploadConfig","provider","providerOptions","actionOptions","cache","concurrency","sharp","plugin","createProvider","registerUploadMiddleware","registerUploadMcpTools","installGraphqlExtension","service","registerOverride","spec","pluginOrigin","excludeFromGeneration","providerName","_","toLower","modulePath","require","resolve","error","code","err","newError","Error","stack","providerInstance","init","delete","upload","uploadStream","process","emitWarning","wrappedProvider","mapValues","method","methodName","options","Object","assign","create","baseProvider","extend","obj","checkFileSize","sizeLimit","size","originalFilename","getSignedUrl","isPrivate"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"folder.js","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { sortBy, map, isUndefined } from 'lodash/fp';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids = []) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map('path', folders);\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n parent: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (isUndefined(parent)) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (isUndefined(parent)) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', { folder });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy('name', folderMap[parentId].children);\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","update","name","isUndefined","existingFolder","undefined","newFolder","isEdition","trx","transaction","select","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","forEach","f","parentId","push","sortBy"],"mappings":"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"}
1
+ {"version":3,"file":"folder.js","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { sortBy, map, isUndefined } from 'lodash/fp';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids: number[] = []) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map('path', folders);\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n /**\n * Omit to rename in place: the name-only branch skips the transaction that rewrites\n * descendant paths. Pass a number to re-parent, or null to move to the root.\n */\n parent?: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (isUndefined(parent)) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (isUndefined(parent)) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', { folder });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy('name', folderMap[parentId].children);\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","update","name","isUndefined","existingFolder","undefined","newFolder","isEdition","trx","transaction","select","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","forEach","f","parentId","push","sortBy"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"folder.mjs","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { sortBy, map, isUndefined } from 'lodash/fp';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids = []) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map('path', folders);\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n parent: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (isUndefined(parent)) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (isUndefined(parent)) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', { folder });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy('name', folderMap[parentId].children);\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","update","name","isUndefined","existingFolder","undefined","newFolder","isEdition","trx","transaction","select","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","forEach","f","parentId","push","sortBy"],"mappings":"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"}
1
+ {"version":3,"file":"folder.mjs","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { sortBy, map, isUndefined } from 'lodash/fp';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids: number[] = []) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map('path', folders);\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n /**\n * Omit to rename in place: the name-only branch skips the transaction that rewrites\n * descendant paths. Pass a number to re-parent, or null to move to the root.\n */\n parent?: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (isUndefined(parent)) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (isUndefined(parent)) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', { folder });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy('name', folderMap[parentId].children);\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","update","name","isUndefined","existingFolder","undefined","newFolder","isEdition","trx","transaction","select","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","forEach","f","parentId","push","sortBy"],"mappings":"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"}
@@ -23,6 +23,16 @@ const { UPDATED_BY_ATTRIBUTE, CREATED_BY_ATTRIBUTE } = utils.contentTypes.consta
23
23
  const { MEDIA_CREATE, MEDIA_UPDATE, MEDIA_DELETE } = constants.ALLOWED_WEBHOOK_EVENTS;
24
24
  const { ApplicationError, NotFoundError } = utils.errors;
25
25
  const { bytesToKbytes } = utils.file;
26
+ /**
27
+ * Queue a provider operation for a later `Promise.all`, with a rejection handler
28
+ * attached in the same turn so a fast failure is never an unhandled rejection.
29
+ *
30
+ * `Promise.resolve` first — a provider may hand back a plain value, which
31
+ * `Promise.all` accepts but `.catch` would throw on.
32
+ */ const queueConcurrentOperation = (queue, operation)=>{
33
+ Promise.resolve(operation).catch(()=>undefined);
34
+ queue.push(operation);
35
+ };
26
36
  var upload = (({ strapi })=>{
27
37
  const fileService = index.getService('file');
28
38
  const sendMediaMetrics = async (data)=>{
@@ -218,19 +228,19 @@ var upload = (({ strapi })=>{
218
228
  };
219
229
  const uploadPromises = [];
220
230
  // Upload image
221
- uploadPromises.push(index.getService('provider').upload(fileData));
231
+ queueConcurrentOperation(uploadPromises, index.getService('provider').upload(fileData));
222
232
  // Generate & Upload thumbnail and responsive formats
223
233
  if (await isResizableImage(fileData)) {
224
234
  const thumbnailFile = await generateThumbnail(fileData);
225
235
  if (thumbnailFile) {
226
- uploadPromises.push(uploadThumbnail(thumbnailFile));
236
+ queueConcurrentOperation(uploadPromises, uploadThumbnail(thumbnailFile));
227
237
  }
228
238
  const formats = await generateResponsiveFormats(fileData);
229
239
  if (Array.isArray(formats) && formats.length > 0) {
230
240
  for (const format of formats){
231
241
  // eslint-disable-next-line no-continue
232
242
  if (!format) continue;
233
- uploadPromises.push(uploadResponsiveFormat(format));
243
+ queueConcurrentOperation(uploadPromises, uploadResponsiveFormat(format));
234
244
  }
235
245
  }
236
246
  }
@@ -263,13 +273,13 @@ var upload = (({ strapi })=>{
263
273
  };
264
274
  const promises = [];
265
275
  // Replace the main file
266
- promises.push(index.getService('provider').replace(fileData, oldFile));
276
+ queueConcurrentOperation(promises, index.getService('provider').replace(fileData, oldFile));
267
277
  const newFormatKeys = new Set();
268
278
  if (await isResizableImage(fileData)) {
269
279
  const thumbnailFile = await generateThumbnail(fileData);
270
280
  if (thumbnailFile) {
271
281
  newFormatKeys.add('thumbnail');
272
- promises.push(replaceFormat('thumbnail', thumbnailFile));
282
+ queueConcurrentOperation(promises, replaceFormat('thumbnail', thumbnailFile));
273
283
  }
274
284
  const formats = await generateResponsiveFormats(fileData);
275
285
  if (Array.isArray(formats) && formats.length > 0) {
@@ -277,7 +287,7 @@ var upload = (({ strapi })=>{
277
287
  // eslint-disable-next-line no-continue
278
288
  if (!format) continue;
279
289
  newFormatKeys.add(format.key);
280
- promises.push(replaceFormat(format.key, format.file));
290
+ queueConcurrentOperation(promises, replaceFormat(format.key, format.file));
281
291
  }
282
292
  }
283
293
  }
@@ -286,7 +296,7 @@ var upload = (({ strapi })=>{
286
296
  for (const oldKey of Object.keys(oldFile.formats)){
287
297
  if (!newFormatKeys.has(oldKey)) {
288
298
  const oldFormat = oldFile.formats[oldKey];
289
- promises.push(strapi.plugin('upload').provider.delete(oldFormat));
299
+ queueConcurrentOperation(promises, strapi.plugin('upload').provider.delete(oldFormat));
290
300
  }
291
301
  }
292
302
  }
@@ -343,8 +353,12 @@ var upload = (({ strapi })=>{
343
353
  const tmpWorkingDirectory = await createAndAssignTmpWorkingDirectoryToFiles(file);
344
354
  let fileData;
345
355
  try {
346
- const { fileInfo } = data;
347
- fileData = await enhanceAndValidateFile(file, fileInfo);
356
+ // `refId` / `ref` / `field` are dropped rather than forwarded: `formatFileInfo` turns
357
+ // them into a one-element `related` array, and a bare array reaches the morph join as
358
+ // `set` — which deletes every row for this file, detaching it from every other entry
359
+ // that uses it. Attaching an existing file to an entry is the content API's job.
360
+ const { fileInfo, refId: _refId, ref: _ref, field: _field, ...metas } = data;
361
+ fileData = await enhanceAndValidateFile(file, fileInfo, metas);
348
362
  // Replacing a file writes new bytes just like creating one, so it has to
349
363
  // respect sizeLimit too. Checked before any provider write, and measured on
350
364
  // the same post-optimization file as the create path (uploadFileAndPersist).
@@ -354,6 +368,14 @@ var upload = (({ strapi })=>{
354
368
  hash: dbFile.hash,
355
369
  ext: dbFile.ext
356
370
  });
371
+ // A plain replace sends no folder, so `formatFileInfo` resolved folderPath to
372
+ // '/' while the relation survived — and folder deletion selects by folderPath,
373
+ // which orphaned the file. An explicitly sent folder still moves it.
374
+ if (fileInfo?.folder === undefined) {
375
+ ___default.default.assign(fileData, {
376
+ folderPath: dbFile.folderPath
377
+ });
378
+ }
357
379
  // clear old formats — replaceImage / replace will set new ones
358
380
  ___default.default.set(fileData, 'formats', {});
359
381
  if (dbFile.provider === config.provider) {
@@ -616,7 +638,9 @@ var upload = (({ strapi })=>{
616
638
  /**
617
639
  * exposed for testing only
618
640
  * @internal
619
- */ _uploadImage: uploadImage
641
+ */ _uploadImage: uploadImage,
642
+ _replaceImage: replaceImage,
643
+ _queueConcurrentOperation: queueConcurrentOperation
620
644
  };
621
645
  });
622
646