@strapi/upload 5.42.1 → 5.43.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 (46) hide show
  1. package/dist/admin/hooks/useTracking.js +1 -1
  2. package/dist/admin/hooks/useTracking.js.map +1 -1
  3. package/dist/admin/hooks/useTracking.mjs +1 -1
  4. package/dist/admin/hooks/useTracking.mjs.map +1 -1
  5. package/dist/admin/hooks/useUpload.js +1 -1
  6. package/dist/admin/hooks/useUpload.js.map +1 -1
  7. package/dist/admin/hooks/useUpload.mjs +1 -1
  8. package/dist/admin/hooks/useUpload.mjs.map +1 -1
  9. package/dist/admin/index.js +1 -0
  10. package/dist/admin/index.js.map +1 -1
  11. package/dist/admin/index.mjs +1 -0
  12. package/dist/admin/index.mjs.map +1 -1
  13. package/dist/admin/src/future/services/api.d.ts +6 -6
  14. package/dist/admin/src/future/services/assets.d.ts +1 -1
  15. package/dist/admin/src/future/services/folders.d.ts +2 -2
  16. package/dist/admin/src/future/services/settings.d.ts +1 -1
  17. package/dist/admin/translations/nl.json.js +227 -0
  18. package/dist/admin/translations/nl.json.js.map +1 -0
  19. package/dist/admin/translations/nl.json.mjs +225 -0
  20. package/dist/admin/translations/nl.json.mjs.map +1 -0
  21. package/dist/server/bootstrap.js +3 -1
  22. package/dist/server/bootstrap.js.map +1 -1
  23. package/dist/server/bootstrap.mjs +3 -1
  24. package/dist/server/bootstrap.mjs.map +1 -1
  25. package/dist/server/controllers/admin-file.js +3 -0
  26. package/dist/server/controllers/admin-file.js.map +1 -1
  27. package/dist/server/controllers/admin-file.mjs +3 -0
  28. package/dist/server/controllers/admin-file.mjs.map +1 -1
  29. package/dist/server/controllers/content-api.js +12 -6
  30. package/dist/server/controllers/content-api.js.map +1 -1
  31. package/dist/server/controllers/content-api.mjs +13 -7
  32. package/dist/server/controllers/content-api.mjs.map +1 -1
  33. package/dist/server/services/ai-metadata.js +3 -12
  34. package/dist/server/services/ai-metadata.js.map +1 -1
  35. package/dist/server/services/ai-metadata.mjs +3 -12
  36. package/dist/server/services/ai-metadata.mjs.map +1 -1
  37. package/dist/server/services/metrics.js +3 -3
  38. package/dist/server/services/metrics.js.map +1 -1
  39. package/dist/server/services/metrics.mjs +3 -3
  40. package/dist/server/services/metrics.mjs.map +1 -1
  41. package/dist/server/src/bootstrap.d.ts.map +1 -1
  42. package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
  43. package/dist/server/src/controllers/content-api.d.ts.map +1 -1
  44. package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
  45. package/dist/server/src/services/metrics.d.ts.map +1 -1
  46. package/package.json +6 -6
@@ -0,0 +1,225 @@
1
+ var nl = {
2
+ "ai.modal.error": "Kon geen AI-metadata genereren voor de geüploade bestanden.",
3
+ "ai.modal.title": "{count, plural, one {# bestand geüpload} other {# bestanden geüpload}}, beoordeel door AI gegenereerde metadata",
4
+ "ai.modal.uploading.title": "Uploaden en verwerken met AI...",
5
+ "apiError.FileTooBig": "Het geüploade bestand overschrijdt de maximaal toegestane bestandsgrootte.",
6
+ "asset-details.alternativeText": "Alternatieve tekst",
7
+ "asset-details.assetId": "Bestands-ID",
8
+ "asset-details.caption": "Onderschrift",
9
+ "asset-details.createdBy": "Aangemaakt door",
10
+ "asset-details.creationDate": "Aanmaakdatum",
11
+ "asset-details.description": "Toont bestandsinformatie en metadata",
12
+ "asset-details.dimensions": "Afmetingen",
13
+ "asset-details.duration": "Duur",
14
+ "asset-details.error": "Bestandsdetails konden niet worden geladen.",
15
+ "asset-details.extension": "Extensie",
16
+ "asset-details.fileInfo": "Bestandsinformatie",
17
+ "asset-details.fileName": "Bestandsnaam",
18
+ "asset-details.lastUpdated": "Laatst bijgewerkt",
19
+ "asset-details.noPreview": "Geen voorbeeld beschikbaar",
20
+ "asset-details.size": "Grootte",
21
+ "asset-details.title": "Bestandsdetails",
22
+ "asset-details.videoNotSupported": "Je browser ondersteunt het video-element niet.",
23
+ "assets.uploaded": "{number, plural, one {# bestand} other {# bestanden}} succesvol geüpload",
24
+ "bulk.select.label": "Alle bestanden selecteren",
25
+ "button.next": "Volgende",
26
+ "checkControl.crop-duplicate": "Dupliceren en bijsnijden",
27
+ "checkControl.crop-original": "Origineel bijsnijden",
28
+ "config.back": "Terug",
29
+ "config.entries.note": "Aantal bestanden dat standaard wordt weergegeven in de Mediabibliotheek",
30
+ "config.entries.title": "Items per pagina",
31
+ "config.note": "Opmerking: Je kunt deze waarde aanpassen in de mediabibliotheek.",
32
+ "config.popUpWarning.warning.updateAllSettings": "Dit wijzigt al je instellingen",
33
+ "config.sort.title": "Standaard sorteervolgorde",
34
+ "config.subtitle": "Configureer de weergave-instellingen van de mediabibliotheek.",
35
+ "content.isLoading": "Inhoud wordt geladen.",
36
+ "control-card.add": "Toevoegen",
37
+ "control-card.cancel": "Annuleren",
38
+ "control-card.copy-link": "Link kopiëren",
39
+ "control-card.crop": "Bijsnijden",
40
+ "control-card.download": "Downloaden",
41
+ "control-card.edit": "Bewerken",
42
+ "control-card.remove-selection": "Verwijderen uit selectie",
43
+ "control-card.replace-media": "Media vervangen",
44
+ "control-card.reset-focal-point": "Terugzetten naar midden",
45
+ "control-card.save": "Opslaan",
46
+ "control-card.save-focal-point": "Brandpunt opslaan",
47
+ "control-card.set-focal-point": "Brandpunt instellen",
48
+ "control-card.stop-crop": "Bijsnijden stoppen",
49
+ "control-card.stop-focal-point": "Brandpuntselectie annuleren",
50
+ "dropzone.upload.message": "Sleep hier naartoe om te uploaden naar",
51
+ "filter.add": "Filter toevoegen",
52
+ "folder.create.form.error.name-required": "Naam is verplicht",
53
+ "folder.create.form.error.unknown": "Er is een fout opgetreden bij het aanmaken van de map",
54
+ "folder.create.submit": "Map aanmaken",
55
+ "folder.create.success": "Map is aangemaakt",
56
+ "folder.create.title": "Nieuwe map",
57
+ "folder.form.name.label": "Mapnaam",
58
+ "form.button.replace-media": "Media vervangen",
59
+ "form.input.description.file-alt": "Deze tekst wordt weergegeven als het bestand niet kan worden getoond.",
60
+ "form.input.label.file-alt": "Alternatieve tekst",
61
+ "form.input.label.file-caption": "Onderschrift",
62
+ "form.input.label.file-name": "Bestandsnaam",
63
+ "form.input.placeholder.file-caption": "Voer onderschrift in",
64
+ "form.upload-url.error.url.invalid": "Eén URL is ongeldig",
65
+ "form.upload-url.error.url.invalids": "{number} URL's zijn ongeldig",
66
+ "header.actions.add-assets": "Nieuwe bestanden toevoegen",
67
+ "header.actions.add-assets.folder": "map",
68
+ "header.actions.add-folder": "Nieuwe map toevoegen",
69
+ "header.actions.upload-assets": "Bestanden uploaden",
70
+ "header.actions.upload-new-asset": "Nieuw bestand uploaden",
71
+ "header.content.assets": "{numberFolders, plural, one {1 map} other {# mappen}} - {numberAssets, plural, one {1 bestand} other {# bestanden}}",
72
+ "header.content.assets-empty": "Geen bestanden",
73
+ "header.content.item-count": "{count, plural, =1 {# item} other {# items}}",
74
+ "import-files": "Bestand uploaden",
75
+ "import-from-url": "Bestand uploaden via URL",
76
+ "input.button.label": "Bestanden zoeken",
77
+ "input.label": "Sleep en laat los of",
78
+ "input.label-bold": "Sleep en laat los",
79
+ "input.label-normal": "om te uploaden of",
80
+ "input.notification.not-supported": "Je kunt dit type bestand niet uploaden, alleen de volgende typen worden geaccepteerd – {fileTypes}",
81
+ "input.placeholder": "Klik om een bestand toe te voegen of sleep een bestand naar dit gebied",
82
+ "input.placeholder.icon": "Laat het bestand los in deze zone",
83
+ "input.url.description": "Scheid je URL-links met een nieuwe regel.",
84
+ "input.url.label": "URL('s)",
85
+ "input.url.placeholder": "Leeg",
86
+ "list-assets-select": "Selecteer bestand {name}",
87
+ "list.asset.at.finished": "De bestanden zijn geladen.",
88
+ "list.assets-empty.search": "Geen resultaten gevonden",
89
+ "list.assets-empty.subtitle": "Voeg er een toe aan de lijst.",
90
+ "list.assets-empty.title": "Er zijn nog geen bestanden",
91
+ "list.assets-empty.title-withSearch": "Er zijn geen elementen met de toegepaste filters",
92
+ "list.assets.empty": "Mediabibliotheek is leeg",
93
+ "list.assets.empty-upload": "Upload je eerste bestanden...",
94
+ "list.assets.empty.no-permissions": "Geen rechten om te bekijken",
95
+ "list.assets.error": "Er is een fout opgetreden bij het ophalen van bestanden.",
96
+ "list.assets.loading-asset": "Voorbeeld laden voor het mediabestand: {path}",
97
+ "list.assets.loading-more": "Meer bestanden laden...",
98
+ "list.assets.not-supported-content": "Geen voorbeeld beschikbaar",
99
+ "list.assets.preview-asset": "Voorbeeld voor de video op pad {path}",
100
+ "list.assets.selected": "{numberFolders, plural, one {1 map} other {# mappen}} - {numberAssets, plural, one {1 bestand} other {# bestanden}}",
101
+ "list.assets.title": "Bestanden ({count})",
102
+ "list.assets.to-upload": "{number, plural, =0 {Geen bestanden} one {1 bestand} other {# bestanden}} klaar om te uploaden",
103
+ "list.assets.type-not-allowed": "Dit type bestand is niet toegestaan.",
104
+ "list.folder.edit": "Map bewerken",
105
+ "list.folder.select": "Selecteer map {name}",
106
+ "list.folder.subtitle": "{folderCount, plural, one {# map} other {# mappen}}, {filesCount, plural, one {# bestand} other {# bestanden}}",
107
+ "list.folders.link-label": "Naar map",
108
+ "list.folders.title": "Mappen ({count})",
109
+ "list.table.content.empty-label": "Dit veld is leeg",
110
+ "list.table.header.actions": "acties",
111
+ "list.table.header.createdAt": "aangemaakt",
112
+ "list.table.header.creationDate": "Aanmaakdatum",
113
+ "list.table.header.ext": "extensie",
114
+ "list.table.header.lastModified": "Laatst gewijzigd",
115
+ "list.table.header.name": "naam",
116
+ "list.table.header.preview": "voorbeeld",
117
+ "list.table.header.size": "grootte",
118
+ "list.table.header.sort": "Sorteren op {label}",
119
+ "list.table.header.updatedAt": "laatst bijgewerkt",
120
+ "mediaLibraryInput.actions.nextSlide": "Volgende slide",
121
+ "mediaLibraryInput.actions.previousSlide": "Vorige slide",
122
+ "mediaLibraryInput.placeholder": "Klik om een bestand toe te voegen of sleep er een naar dit gebied",
123
+ "mediaLibraryInput.slideCount": "{n} van {m} slides",
124
+ "modal.file-details.date": "Datum",
125
+ "modal.file-details.dimensions": "Afmetingen",
126
+ "modal.file-details.extension": "Extensie",
127
+ "modal.file-details.focal-point": "Brandpunt",
128
+ "modal.file-details.id": "Bestands-ID",
129
+ "modal.file-details.size": "Grootte",
130
+ "modal.folder.elements.count": "{folderCount} mappen, {assetCount} bestanden",
131
+ "modal.folder.move.title": "Elementen verplaatsen naar",
132
+ "modal.header.browse": "Bestanden uploaden",
133
+ "modal.header.file-detail": "Details",
134
+ "modal.header.go-back": "Terug",
135
+ "modal.header.pending-assets": "Wachtende bestanden",
136
+ "modal.header.select-files": "Geselecteerde bestanden",
137
+ "modal.move.success-label": "Elementen zijn succesvol verplaatst",
138
+ "modal.nav.browse": "bladeren",
139
+ "modal.nav.computer": "Vanaf computer",
140
+ "modal.nav.selected": "geselecteerd",
141
+ "modal.nav.url": "Via URL",
142
+ "modal.remove.success-label": "Elementen zijn succesvol verwijderd.",
143
+ "modal.selected-list.sub-header-subtitle": "Sleep om de bestanden in het veld te herschikken",
144
+ "modal.upload-list.footer.button": "{number, plural, one {# bestand} other {# bestanden}} uploaden naar de bibliotheek",
145
+ "modal.upload-list.sub-header-subtitle": "Beheer de bestanden voordat je ze toevoegt aan de Mediabibliotheek",
146
+ "modal.upload-list.sub-header.button": "Meer bestanden toevoegen",
147
+ "modal.upload.cancelled": "Upload handmatig afgebroken.",
148
+ "new": "Nieuw",
149
+ "page.title": "Instellingen - Mediabibliotheek",
150
+ "permissions.not-allowed.update": "Je hebt geen rechten om dit bestand te bewerken.",
151
+ "plugin.description.long": "Beheer van mediabestanden.",
152
+ "plugin.description.short": "Beheer van mediabestanden.",
153
+ "plugin.home": "Home",
154
+ "plugin.name": "Mediabibliotheek",
155
+ "search.clear.label": "Zoekopdracht wissen",
156
+ "search.label": "Zoek naar een bestand",
157
+ "search.placeholder": "bijv.: de eerste hond op de maan",
158
+ "settings.blockTitle": "Bestandsbeheer",
159
+ "settings.form.aiMetadata.allAssetsHaveMetadata": "Alle bestanden hebben een onderschrift en alternatieve tekst",
160
+ "settings.form.aiMetadata.confirmDialog.message": "Dit start een achtergrondproces om onderschriften en alternatieve tekst te genereren voor {count, plural, one {# afbeelding} other {# afbeeldingen}}. AI kan fouten maken; controleer de gegenereerde inhoud.",
161
+ "settings.form.aiMetadata.confirmDialog.title": "AI-metadata genereren",
162
+ "settings.form.aiMetadata.description": "Schakel deze functie in om tijd te besparen, je SEO te optimaliseren en de toegankelijkheid te vergroten door onze AI onderschriften en alternatieve teksten voor je te laten genereren.",
163
+ "settings.form.aiMetadata.generateButton": "Metadata genereren",
164
+ "settings.form.aiMetadata.generatingMetadata": "AI genereert je metadata",
165
+ "settings.form.aiMetadata.imagesWithoutMetadata": "{count, plural, one {# afbeelding mist onderschrift of alternatieve tekst} other {# afbeeldingen missen onderschrift of alternatieve tekst}}",
166
+ "settings.form.aiMetadata.label": "Genereer automatisch AI-onderschriften en alternatieve teksten bij het uploaden!",
167
+ "settings.form.aiMetadata.metadataGenerated": "Je metadata is gegenereerd",
168
+ "settings.form.autoOrientation.description": "Door deze optie in te schakelen wordt de afbeelding automatisch geroteerd op basis van de EXIF-oriëntatie-tag.",
169
+ "settings.form.autoOrientation.label": "Automatische oriëntatie",
170
+ "settings.form.responsiveDimensions.description": "Door deze optie in te schakelen worden meerdere formaten (klein, medium en groot) van het geüploade bestand gegenereerd.",
171
+ "settings.form.responsiveDimensions.label": "Responsief uploaden",
172
+ "settings.form.sizeOptimization.description": "Door deze optie in te schakelen wordt de afbeeldingsgrootte verkleind en de kwaliteit enigszins verminderd.",
173
+ "settings.form.sizeOptimization.label": "Grootte-optimalisatie",
174
+ "settings.form.videoPreview.description": "Er wordt een voorbeeld van zes seconden van de video gegenereerd (GIF)",
175
+ "settings.form.videoPreview.label": "Voorbeeld",
176
+ "settings.header.label": "Mediabibliotheek",
177
+ "settings.section.audio.label": "Audio",
178
+ "settings.section.doc.label": "Document",
179
+ "settings.section.image.label": "Afbeelding",
180
+ "settings.section.video.label": "Video",
181
+ "settings.sub-header.label": "Configureer de instellingen voor de Mediabibliotheek",
182
+ "sort.created_at_asc": "Oudste uploads",
183
+ "sort.created_at_desc": "Nieuwste uploads",
184
+ "sort.label": "Sorteren op",
185
+ "sort.name_asc": "Alfabetische volgorde (A tot Z)",
186
+ "sort.name_desc": "Omgekeerd alfabetisch (Z tot A)",
187
+ "sort.updated_at_asc": "Oudste wijzigingen",
188
+ "sort.updated_at_desc": "Nieuwste wijzigingen",
189
+ "tabs.title": "Hoe wil je je bestanden uploaden?",
190
+ "upload.generic-error": "Er is een fout opgetreden bij het uploaden van het bestand.",
191
+ "upload.progress": "Uploadvoortgang",
192
+ "upload.progress.cancel": "Annuleren",
193
+ "upload.progress.canceled": "Uploads geannuleerd",
194
+ "upload.progress.canceled.subtitle": "Sommige bestanden zijn niet geüpload",
195
+ "upload.progress.canceled.subtitle.all": "Alle uploads zijn geannuleerd",
196
+ "upload.progress.close": "Sluiten",
197
+ "upload.progress.description": "Toont uploadvoortgang en status",
198
+ "upload.progress.errors.title": "Upload mislukt voor:",
199
+ "upload.progress.failed": "Upload mislukt",
200
+ "upload.progress.failed.subtitle": "Probeer de bestanden opnieuw te uploaden",
201
+ "upload.progress.file.canceled": "Geannuleerd",
202
+ "upload.progress.file.uploaded": "Geüpload",
203
+ "upload.progress.file.uploading": "Uploaden...",
204
+ "upload.progress.indicator.complete": "Upload voltooid-indicator",
205
+ "upload.progress.indicator.in-progress": "Upload bezig-indicator",
206
+ "upload.progress.label": "Uploaden",
207
+ "upload.progress.maximize": "Maximaliseren",
208
+ "upload.progress.minimize": "Minimaliseren",
209
+ "upload.progress.retry": "Opnieuw proberen",
210
+ "upload.progress.success": "Upload succesvol!",
211
+ "upload.progress.success.subtitle": "{count, plural, one {# bestand succesvol geüpload} other {# bestanden succesvol geüpload}}",
212
+ "upload.progress.success.subtitle.withErrors": "{successCount} geüpload, {errorCount} mislukt",
213
+ "upload.progress.uploading-files": "{count, plural, one {# bestand} other {# bestanden}} uploaden",
214
+ "upload.progress.uploading.withCount": "{total} items uploaden ({percentage}%)",
215
+ "view-switch.grid": "Rasterweergave",
216
+ "view-switch.list": "Lijstweergave",
217
+ "view.grid": "Rasterweergave",
218
+ "view.switch.label": "Weergaveopties",
219
+ "view.table": "Tabelweergave",
220
+ "window.confirm.close-modal.file": "Weet je het zeker? Je wijzigingen gaan verloren.",
221
+ "window.confirm.close-modal.files": "Weet je het zeker? Er zijn bestanden die nog niet zijn geüpload."
222
+ };
223
+
224
+ export { nl as default };
225
+ //# sourceMappingURL=nl.json.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nl.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -36,7 +36,9 @@ async function bootstrap({ strapi: strapi1 }) {
36
36
  await registerPermissionActions();
37
37
  await registerWebhookEvents();
38
38
  await index.getService('weeklyMetrics').registerCron();
39
- await index.getService('aiMetadataJobs').registerCron();
39
+ if (strapi1.ai.admin.isEnabled() === true) {
40
+ await index.getService('aiMetadataJobs').registerCron();
41
+ }
40
42
  index.getService('metrics').sendUploadPluginMetrics();
41
43
  index.getService('extensions').signFileUrlsOnDocumentService();
42
44
  }
@@ -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 await getService('aiMetadataJobs').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":";;;;;AAKO,eAAeA,SAAAA,CAAU,EAAEC,MAAAA,EAAAA,OAAM,EAA2B,EAAA;AACjE,IAAA,MAAMC,aAAAA,GAAgB;QACpBC,QAAAA,EAAU;YACRC,gBAAAA,EAAkB,IAAA;YAClBC,oBAAAA,EAAsB,IAAA;YACtBC,eAAAA,EAAiB,KAAA;YACjBC,UAAAA,EAAY;AACd,SAAA;QACAC,kBAAAA,EAAoB;YAClBC,QAAAA,EAAU,EAAA;YACVC,IAAAA,EAAMC,8BAAoB,CAAC,CAAA;AAC7B;AACF,KAAA;IAEA,KAAK,MAAM,CAACC,GAAAA,EAAKC,YAAAA,CAAa,IAAIC,MAAAA,CAAOC,OAAO,CAACb,aAAAA,CAAAA,CAAgB;;QAE/D,MAAMc,YAAAA,GAAef,OAAAA,CAAOgB,KAAK,CAAE;YAAEC,IAAAA,EAAM,QAAA;YAAUC,IAAAA,EAAM,QAAA;AAAUP,YAAAA;AAAI,SAAA,CAAA;AAEzE,QAAA,MAAMQ,MAAAA,GAAS,MAAMJ,YAAAA,CAAaK,GAAG,CAAC,EAAC,CAAA;AACvC,QAAA,IACED,UACAN,MAAAA,CAAOQ,IAAI,CAACT,YAAAA,CAAAA,CAAcU,KAAK,CAAC,CAACX,GAAAA,GAAQE,MAAAA,CAAOU,SAAS,CAACC,cAAc,CAACC,IAAI,CAACN,QAAQR,GAAAA,CAAAA,CAAAA,EACtF;AAEA,YAAA;AACF,QAAA;;;QAIA,MAAMI,YAAAA,CAAaW,GAAG,CAAC;AACrBC,YAAAA,KAAAA,EAAOd,MAAAA,CAAOe,MAAM,CAAChB,YAAAA,EAAcO,UAAU,EAAC;AAChD,SAAA,CAAA;AACF,IAAA;IAEA,MAAMU,yBAAAA,EAAAA;IACN,MAAMC,qBAAAA,EAAAA;IAEN,MAAMC,gBAAAA,CAAW,iBAAiBC,YAAY,EAAA;IAC9C,MAAMD,gBAAAA,CAAW,kBAAkBC,YAAY,EAAA;AAE/CD,IAAAA,gBAAAA,CAAW,WAAWE,uBAAuB,EAAA;AAE7CF,IAAAA,gBAAAA,CAAW,cAAcG,6BAA6B,EAAA;AACxD;AAEA,MAAMJ,qBAAAA,GAAwB,UAC5BjB,MAAAA,CAAOC,OAAO,CAACqB,gCAAAA,CAAAA,CAAwBC,OAAO,CAAC,CAAC,CAACzB,GAAAA,EAAKgB,KAAAA,CAAM,GAAA;AAC1D3B,QAAAA,MAAAA,CAAOoB,GAAG,CAAC,cAAA,CAAA,CAAgBiB,eAAe,CAAC1B,GAAAA,EAAKgB,KAAAA,CAAAA;AAClD,IAAA,CAAA,CAAA;AAEF,MAAME,yBAAAA,GAA4B,UAAA;AAChC,IAAA,MAAMS,OAAAA,GAAU;AACd,QAAA;YACEC,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,0BAAA;YACbC,GAAAA,EAAK,MAAA;YACLC,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,iBAAA;YACbC,GAAAA,EAAK,eAAA;YACLE,WAAAA,EAAa,QAAA;YACbD,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,0CAAA;YACbC,GAAAA,EAAK,eAAA;YACLE,WAAAA,EAAa,QAAA;YACbD,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,UAAA;YACbC,GAAAA,EAAK,iBAAA;YACLE,WAAAA,EAAa,QAAA;YACbD,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,WAAA;YACbC,GAAAA,EAAK,kBAAA;YACLE,WAAAA,EAAa,QAAA;YACbD,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,gBAAA;YACbC,GAAAA,EAAK,gBAAA;YACLC,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,UAAA;YACTC,WAAAA,EAAa,wCAAA;YACbC,GAAAA,EAAK,eAAA;YACLG,QAAAA,EAAU,eAAA;YACVF,UAAAA,EAAY;AACd;AACD,KAAA;AAED,IAAA,MAAM1C,OAAO6C,OAAO,CAAC,qBAAqBC,cAAc,CAACC,YAAY,CAACT,OAAAA,CAAAA;AACxE,CAAA;;;;"}
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 if (strapi.ai.admin.isEnabled() === true) {\n await getService('aiMetadataJobs').registerCron();\n }\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","ai","admin","isEnabled","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":";;;;;AAKO,eAAeA,SAAAA,CAAU,EAAEC,MAAAA,EAAAA,OAAM,EAA2B,EAAA;AACjE,IAAA,MAAMC,aAAAA,GAAgB;QACpBC,QAAAA,EAAU;YACRC,gBAAAA,EAAkB,IAAA;YAClBC,oBAAAA,EAAsB,IAAA;YACtBC,eAAAA,EAAiB,KAAA;YACjBC,UAAAA,EAAY;AACd,SAAA;QACAC,kBAAAA,EAAoB;YAClBC,QAAAA,EAAU,EAAA;YACVC,IAAAA,EAAMC,8BAAoB,CAAC,CAAA;AAC7B;AACF,KAAA;IAEA,KAAK,MAAM,CAACC,GAAAA,EAAKC,YAAAA,CAAa,IAAIC,MAAAA,CAAOC,OAAO,CAACb,aAAAA,CAAAA,CAAgB;;QAE/D,MAAMc,YAAAA,GAAef,OAAAA,CAAOgB,KAAK,CAAE;YAAEC,IAAAA,EAAM,QAAA;YAAUC,IAAAA,EAAM,QAAA;AAAUP,YAAAA;AAAI,SAAA,CAAA;AAEzE,QAAA,MAAMQ,MAAAA,GAAS,MAAMJ,YAAAA,CAAaK,GAAG,CAAC,EAAC,CAAA;AACvC,QAAA,IACED,UACAN,MAAAA,CAAOQ,IAAI,CAACT,YAAAA,CAAAA,CAAcU,KAAK,CAAC,CAACX,GAAAA,GAAQE,MAAAA,CAAOU,SAAS,CAACC,cAAc,CAACC,IAAI,CAACN,QAAQR,GAAAA,CAAAA,CAAAA,EACtF;AAEA,YAAA;AACF,QAAA;;;QAIA,MAAMI,YAAAA,CAAaW,GAAG,CAAC;AACrBC,YAAAA,KAAAA,EAAOd,MAAAA,CAAOe,MAAM,CAAChB,YAAAA,EAAcO,UAAU,EAAC;AAChD,SAAA,CAAA;AACF,IAAA;IAEA,MAAMU,yBAAAA,EAAAA;IACN,MAAMC,qBAAAA,EAAAA;IAEN,MAAMC,gBAAAA,CAAW,iBAAiBC,YAAY,EAAA;AAC9C,IAAA,IAAIhC,QAAOiC,EAAE,CAACC,KAAK,CAACC,SAAS,OAAO,IAAA,EAAM;QACxC,MAAMJ,gBAAAA,CAAW,kBAAkBC,YAAY,EAAA;AACjD,IAAA;AAEAD,IAAAA,gBAAAA,CAAW,WAAWK,uBAAuB,EAAA;AAE7CL,IAAAA,gBAAAA,CAAW,cAAcM,6BAA6B,EAAA;AACxD;AAEA,MAAMP,qBAAAA,GAAwB,UAC5BjB,MAAAA,CAAOC,OAAO,CAACwB,gCAAAA,CAAAA,CAAwBC,OAAO,CAAC,CAAC,CAAC5B,GAAAA,EAAKgB,KAAAA,CAAM,GAAA;AAC1D3B,QAAAA,MAAAA,CAAOoB,GAAG,CAAC,cAAA,CAAA,CAAgBoB,eAAe,CAAC7B,GAAAA,EAAKgB,KAAAA,CAAAA;AAClD,IAAA,CAAA,CAAA;AAEF,MAAME,yBAAAA,GAA4B,UAAA;AAChC,IAAA,MAAMY,OAAAA,GAAU;AACd,QAAA;YACEC,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,0BAAA;YACbC,GAAAA,EAAK,MAAA;YACLC,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,iBAAA;YACbC,GAAAA,EAAK,eAAA;YACLE,WAAAA,EAAa,QAAA;YACbD,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,0CAAA;YACbC,GAAAA,EAAK,eAAA;YACLE,WAAAA,EAAa,QAAA;YACbD,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,UAAA;YACbC,GAAAA,EAAK,iBAAA;YACLE,WAAAA,EAAa,QAAA;YACbD,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,WAAA;YACbC,GAAAA,EAAK,kBAAA;YACLE,WAAAA,EAAa,QAAA;YACbD,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,SAAA;YACTC,WAAAA,EAAa,gBAAA;YACbC,GAAAA,EAAK,gBAAA;YACLC,UAAAA,EAAY;AACd,SAAA;AACA,QAAA;YACEH,OAAAA,EAAS,UAAA;YACTC,WAAAA,EAAa,wCAAA;YACbC,GAAAA,EAAK,eAAA;YACLG,QAAAA,EAAU,eAAA;YACVF,UAAAA,EAAY;AACd;AACD,KAAA;AAED,IAAA,MAAM7C,OAAOgD,OAAO,CAAC,qBAAqBC,cAAc,CAACC,YAAY,CAACT,OAAAA,CAAAA;AACxE,CAAA;;;;"}
@@ -34,7 +34,9 @@ async function bootstrap({ strapi: strapi1 }) {
34
34
  await registerPermissionActions();
35
35
  await registerWebhookEvents();
36
36
  await getService('weeklyMetrics').registerCron();
37
- await getService('aiMetadataJobs').registerCron();
37
+ if (strapi1.ai.admin.isEnabled() === true) {
38
+ await getService('aiMetadataJobs').registerCron();
39
+ }
38
40
  getService('metrics').sendUploadPluginMetrics();
39
41
  getService('extensions').signFileUrlsOnDocumentService();
40
42
  }
@@ -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 await getService('aiMetadataJobs').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';\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 if (strapi.ai.admin.isEnabled() === true) {\n await getService('aiMetadataJobs').registerCron();\n }\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","ai","admin","isEnabled","sendUploadPluginMetrics","signFileUrlsOnDocumentService","ALLOWED_WEBHOOK_EVENTS","forEach","addAllowedEvent","actions","section","displayName","uid","pluginName","subCategory","category","service","actionProvider","registerMany"],"mappings":"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"}
@@ -134,6 +134,9 @@ var adminFile = {
134
134
  }
135
135
  },
136
136
  async getLatestAIMetadataJob (ctx) {
137
+ if (await index.getService('aiMetadata').isEnabled() === false) {
138
+ return ctx.notFound();
139
+ }
137
140
  const jobService = index.getService('aiMetadataJobs');
138
141
  const job = await jobService.getLatestActiveJob();
139
142
  if (!job) {
@@ -1 +1 @@
1
- {"version":3,"file":"admin-file.js","sources":["../../../server/src/controllers/admin-file.ts"],"sourcesContent":["import { merge } from 'lodash/fp';\nimport { async } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions';\n\nexport default {\n async find(ctx: Context) {\n const {\n state: { userAbility },\n } = ctx;\n\n const defaultQuery = { populate: { folder: true } };\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n // validate the incoming user query params\n await pm.validateQuery(ctx.query);\n\n const query = await async.pipe(\n // Start by sanitizing the incoming query\n (q) => pm.sanitizeQuery(q),\n // Add the default query which should not be validated or sanitized\n (q) => merge(defaultQuery, q),\n // Add the dynamic filters based on permissions' conditions\n (q) => pm.addPermissionsQueryTo(q)\n )(ctx.query);\n\n const { results: files, pagination } = await getService('upload').findPage(query);\n\n // Sign file urls for private providers\n const signedFiles = await async.map(files, getService('file').signFileUrls);\n\n const sanitizedFiles = await pm.sanitizeOutput(signedFiles);\n\n return { results: sanitizedFiles, pagination };\n },\n\n async findOne(ctx: Context) {\n const {\n state: { userAbility },\n params: { id },\n } = ctx;\n\n const { pm, file } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.read,\n FILE_MODEL_UID,\n id\n );\n\n const signedFile = await getService('file').signFileUrls(file);\n ctx.body = await pm.sanitizeOutput(signedFile);\n },\n\n async destroy(ctx: Context) {\n const { id } = ctx.params;\n const { userAbility } = ctx.state;\n\n const { pm, file } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const [body] = await Promise.all([\n pm.sanitizeOutput(file, { action: ACTIONS.read }),\n getService('upload').remove(file),\n ]);\n\n ctx.body = body;\n },\n\n async getAIMetadataCount(ctx: Context) {\n const { userAbility } = ctx.state;\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // Check if AI service is enabled\n if (!(await aiMetadataService.isEnabled())) {\n return ctx.badRequest('AI Metadata service is not enabled');\n }\n\n try {\n const { imagesWithoutMetadataCount, totalImages } =\n await aiMetadataService.countImagesWithoutMetadata();\n\n ctx.body = {\n imagesWithoutMetadataCount,\n totalImages,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to get AI metadata count';\n\n strapi.log.error('Failed to get AI metadata count', {\n message,\n error,\n });\n\n ctx.badRequest(message);\n }\n },\n\n async generateAIMetadata(ctx: Context) {\n const { userAbility } = ctx.state;\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.update,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // Check if AI service is enabled\n if (!(await aiMetadataService.isEnabled())) {\n return ctx.badRequest('AI Metadata service is not enabled');\n }\n\n try {\n // Get count first to check if there are images to process\n const result = await aiMetadataService.countImagesWithoutMetadata();\n\n if (result.imagesWithoutMetadataCount === 0) {\n ctx.body = {\n count: 0,\n message: 'No images without metadata found',\n };\n return;\n }\n\n // Create job\n const jobService = getService('aiMetadataJobs');\n const jobId = await jobService.createJob();\n\n // Start async processing (fire and forget)\n aiMetadataService.processExistingFiles(jobId, ctx.state.user).catch((err: Error) => {\n strapi.log.error('AI metadata job failed:', err);\n });\n\n // Return immediately with job ID\n ctx.body = {\n jobId,\n status: 'pending',\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to generate AI metadata';\n const cause = error instanceof Error && error.cause ? String(error.cause) : undefined;\n\n strapi.log.error('AI metadata generation failed in controller', {\n message,\n cause,\n error,\n });\n\n ctx.badRequest(cause ? `${message}: ${cause}` : message);\n }\n },\n\n async getLatestAIMetadataJob(ctx: Context) {\n const jobService = getService('aiMetadataJobs');\n const job = await jobService.getLatestActiveJob();\n\n if (!job) {\n return ctx.notFound('No active job found');\n }\n\n ctx.body = job;\n },\n};\n"],"names":["find","ctx","state","userAbility","defaultQuery","populate","folder","pm","strapi","service","createPermissionsManager","ability","action","ACTIONS","read","model","FILE_MODEL_UID","isAllowed","forbidden","validateQuery","query","async","pipe","q","sanitizeQuery","merge","addPermissionsQueryTo","results","files","pagination","getService","findPage","signedFiles","map","signFileUrls","sanitizedFiles","sanitizeOutput","findOne","params","id","file","findEntityAndCheckPermissions","signedFile","body","destroy","update","Promise","all","remove","getAIMetadataCount","aiMetadataService","isEnabled","badRequest","imagesWithoutMetadataCount","totalImages","countImagesWithoutMetadata","error","message","Error","log","generateAIMetadata","result","count","jobService","jobId","createJob","processExistingFiles","user","catch","err","status","cause","String","undefined","getLatestAIMetadataJob","job","getLatestActiveJob","notFound"],"mappings":";;;;;;;;AASA,gBAAe;AACb,IAAA,MAAMA,MAAKC,GAAY,EAAA;AACrB,QAAA,MAAM,EACJC,KAAAA,EAAO,EAAEC,WAAW,EAAE,EACvB,GAAGF,GAAAA;AAEJ,QAAA,MAAMG,YAAAA,GAAe;YAAEC,QAAAA,EAAU;gBAAEC,MAAAA,EAAQ;AAAK;AAAE,SAAA;AAElD,QAAA,MAAMC,KAAKC,MAAAA,CAAOC,OAAO,CAAC,mBAAA,CAAA,CAAqBC,wBAAwB,CAAC;YACtEC,OAAAA,EAASR,WAAAA;AACTS,YAAAA,MAAAA,EAAQC,kBAAQC,IAAI;YACpBC,KAAAA,EAAOC;AACT,SAAA,CAAA;QAEA,IAAI,CAACT,EAAAA,CAAGU,SAAS,EAAE;AACjB,YAAA,OAAOhB,IAAIiB,SAAS,EAAA;AACtB,QAAA;;AAGA,QAAA,MAAMX,EAAAA,CAAGY,aAAa,CAAClB,GAAAA,CAAImB,KAAK,CAAA;AAEhC,QAAA,MAAMA,KAAAA,GAAQ,MAAMC,WAAAA,CAAMC,IAAI;AAE5B,QAAA,CAACC,CAAAA,GAAMhB,EAAAA,CAAGiB,aAAa,CAACD;AAExB,QAAA,CAACA,CAAAA,GAAME,QAAAA,CAAMrB,YAAAA,EAAcmB,CAAAA,CAAAA;AAE3B,QAAA,CAACA,IAAMhB,EAAAA,CAAGmB,qBAAqB,CAACH,CAAAA,CAAAA,CAAAA,CAChCtB,IAAImB,KAAK,CAAA;QAEX,MAAM,EAAEO,OAAAA,EAASC,KAAK,EAAEC,UAAU,EAAE,GAAG,MAAMC,gBAAAA,CAAW,QAAA,CAAA,CAAUC,QAAQ,CAACX,KAAAA,CAAAA;;QAG3E,MAAMY,WAAAA,GAAc,MAAMX,WAAAA,CAAMY,GAAG,CAACL,KAAAA,EAAOE,gBAAAA,CAAW,QAAQI,YAAY,CAAA;AAE1E,QAAA,MAAMC,cAAAA,GAAiB,MAAM5B,EAAAA,CAAG6B,cAAc,CAACJ,WAAAA,CAAAA;QAE/C,OAAO;YAAEL,OAAAA,EAASQ,cAAAA;AAAgBN,YAAAA;AAAW,SAAA;AAC/C,IAAA,CAAA;AAEA,IAAA,MAAMQ,SAAQpC,GAAY,EAAA;QACxB,MAAM,EACJC,KAAAA,EAAO,EAAEC,WAAW,EAAE,EACtBmC,MAAAA,EAAQ,EAAEC,EAAE,EAAE,EACf,GAAGtC,GAAAA;AAEJ,QAAA,MAAM,EAAEM,EAAE,EAAEiC,IAAI,EAAE,GAAG,MAAMC,2DAAAA,CACzBtC,WAAAA,EACAU,iBAAAA,CAAQC,IAAI,EACZE,wBAAAA,EACAuB,EAAAA,CAAAA;AAGF,QAAA,MAAMG,UAAAA,GAAa,MAAMZ,gBAAAA,CAAW,MAAA,CAAA,CAAQI,YAAY,CAACM,IAAAA,CAAAA;AACzDvC,QAAAA,GAAAA,CAAI0C,IAAI,GAAG,MAAMpC,EAAAA,CAAG6B,cAAc,CAACM,UAAAA,CAAAA;AACrC,IAAA,CAAA;AAEA,IAAA,MAAME,SAAQ3C,GAAY,EAAA;AACxB,QAAA,MAAM,EAAEsC,EAAE,EAAE,GAAGtC,IAAIqC,MAAM;AACzB,QAAA,MAAM,EAAEnC,WAAW,EAAE,GAAGF,IAAIC,KAAK;AAEjC,QAAA,MAAM,EAAEK,EAAE,EAAEiC,IAAI,EAAE,GAAG,MAAMC,2DAAAA,CACzBtC,WAAAA,EACAU,iBAAAA,CAAQgC,MAAM,EACd7B,wBAAAA,EACAuB,EAAAA,CAAAA;AAGF,QAAA,MAAM,CAACI,IAAAA,CAAK,GAAG,MAAMG,OAAAA,CAAQC,GAAG,CAAC;YAC/BxC,EAAAA,CAAG6B,cAAc,CAACI,IAAAA,EAAM;AAAE5B,gBAAAA,MAAAA,EAAQC,kBAAQC;AAAK,aAAA,CAAA;YAC/CgB,gBAAAA,CAAW,QAAA,CAAA,CAAUkB,MAAM,CAACR,IAAAA;AAC7B,SAAA,CAAA;AAEDvC,QAAAA,GAAAA,CAAI0C,IAAI,GAAGA,IAAAA;AACb,IAAA,CAAA;AAEA,IAAA,MAAMM,oBAAmBhD,GAAY,EAAA;AACnC,QAAA,MAAM,EAAEE,WAAW,EAAE,GAAGF,IAAIC,KAAK;AAEjC,QAAA,MAAMK,KAAKC,MAAAA,CAAOC,OAAO,CAAC,mBAAA,CAAA,CAAqBC,wBAAwB,CAAC;YACtEC,OAAAA,EAASR,WAAAA;AACTS,YAAAA,MAAAA,EAAQC,kBAAQC,IAAI;YACpBC,KAAAA,EAAOC;AACT,SAAA,CAAA;QAEA,IAAI,CAACT,EAAAA,CAAGU,SAAS,EAAE;AACjB,YAAA,OAAOhB,IAAIiB,SAAS,EAAA;AACtB,QAAA;AAEA,QAAA,MAAMgC,oBAAoBpB,gBAAAA,CAAW,YAAA,CAAA;;AAGrC,QAAA,IAAI,CAAE,MAAMoB,iBAAAA,CAAkBC,SAAS,EAAA,EAAK;YAC1C,OAAOlD,GAAAA,CAAImD,UAAU,CAAC,oCAAA,CAAA;AACxB,QAAA;QAEA,IAAI;YACF,MAAM,EAAEC,0BAA0B,EAAEC,WAAW,EAAE,GAC/C,MAAMJ,kBAAkBK,0BAA0B,EAAA;AAEpDtD,YAAAA,GAAAA,CAAI0C,IAAI,GAAG;AACTU,gBAAAA,0BAAAA;AACAC,gBAAAA;AACF,aAAA;AACF,QAAA,CAAA,CAAE,OAAOE,KAAAA,EAAO;AACd,YAAA,MAAMC,OAAAA,GAAUD,KAAAA,YAAiBE,KAAAA,GAAQF,KAAAA,CAAMC,OAAO,GAAG,iCAAA;AAEzDjD,YAAAA,MAAAA,CAAOmD,GAAG,CAACH,KAAK,CAAC,iCAAA,EAAmC;AAClDC,gBAAAA,OAAAA;AACAD,gBAAAA;AACF,aAAA,CAAA;AAEAvD,YAAAA,GAAAA,CAAImD,UAAU,CAACK,OAAAA,CAAAA;AACjB,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAMG,oBAAmB3D,GAAY,EAAA;AACnC,QAAA,MAAM,EAAEE,WAAW,EAAE,GAAGF,IAAIC,KAAK;AAEjC,QAAA,MAAMK,KAAKC,MAAAA,CAAOC,OAAO,CAAC,mBAAA,CAAA,CAAqBC,wBAAwB,CAAC;YACtEC,OAAAA,EAASR,WAAAA;AACTS,YAAAA,MAAAA,EAAQC,kBAAQgC,MAAM;YACtB9B,KAAAA,EAAOC;AACT,SAAA,CAAA;QAEA,IAAI,CAACT,EAAAA,CAAGU,SAAS,EAAE;AACjB,YAAA,OAAOhB,IAAIiB,SAAS,EAAA;AACtB,QAAA;AAEA,QAAA,MAAMgC,oBAAoBpB,gBAAAA,CAAW,YAAA,CAAA;;AAGrC,QAAA,IAAI,CAAE,MAAMoB,iBAAAA,CAAkBC,SAAS,EAAA,EAAK;YAC1C,OAAOlD,GAAAA,CAAImD,UAAU,CAAC,oCAAA,CAAA;AACxB,QAAA;QAEA,IAAI;;YAEF,MAAMS,MAAAA,GAAS,MAAMX,iBAAAA,CAAkBK,0BAA0B,EAAA;YAEjE,IAAIM,MAAAA,CAAOR,0BAA0B,KAAK,CAAA,EAAG;AAC3CpD,gBAAAA,GAAAA,CAAI0C,IAAI,GAAG;oBACTmB,KAAAA,EAAO,CAAA;oBACPL,OAAAA,EAAS;AACX,iBAAA;AACA,gBAAA;AACF,YAAA;;AAGA,YAAA,MAAMM,aAAajC,gBAAAA,CAAW,gBAAA,CAAA;YAC9B,MAAMkC,KAAAA,GAAQ,MAAMD,UAAAA,CAAWE,SAAS,EAAA;;YAGxCf,iBAAAA,CAAkBgB,oBAAoB,CAACF,KAAAA,EAAO/D,GAAAA,CAAIC,KAAK,CAACiE,IAAI,CAAA,CAAEC,KAAK,CAAC,CAACC,GAAAA,GAAAA;AACnE7D,gBAAAA,MAAAA,CAAOmD,GAAG,CAACH,KAAK,CAAC,yBAAA,EAA2Ba,GAAAA,CAAAA;AAC9C,YAAA,CAAA,CAAA;;AAGApE,YAAAA,GAAAA,CAAI0C,IAAI,GAAG;AACTqB,gBAAAA,KAAAA;gBACAM,MAAAA,EAAQ;AACV,aAAA;AACF,QAAA,CAAA,CAAE,OAAOd,KAAAA,EAAO;AACd,YAAA,MAAMC,OAAAA,GAAUD,KAAAA,YAAiBE,KAAAA,GAAQF,KAAAA,CAAMC,OAAO,GAAG,gCAAA;YACzD,MAAMc,KAAAA,GAAQf,iBAAiBE,KAAAA,IAASF,KAAAA,CAAMe,KAAK,GAAGC,MAAAA,CAAOhB,KAAAA,CAAMe,KAAK,CAAA,GAAIE,SAAAA;AAE5EjE,YAAAA,MAAAA,CAAOmD,GAAG,CAACH,KAAK,CAAC,6CAAA,EAA+C;AAC9DC,gBAAAA,OAAAA;AACAc,gBAAAA,KAAAA;AACAf,gBAAAA;AACF,aAAA,CAAA;YAEAvD,GAAAA,CAAImD,UAAU,CAACmB,KAAAA,GAAQ,CAAA,EAAGd,QAAQ,EAAE,EAAEc,OAAO,GAAGd,OAAAA,CAAAA;AAClD,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAMiB,wBAAuBzE,GAAY,EAAA;AACvC,QAAA,MAAM8D,aAAajC,gBAAAA,CAAW,gBAAA,CAAA;QAC9B,MAAM6C,GAAAA,GAAM,MAAMZ,UAAAA,CAAWa,kBAAkB,EAAA;AAE/C,QAAA,IAAI,CAACD,GAAAA,EAAK;YACR,OAAO1E,GAAAA,CAAI4E,QAAQ,CAAC,qBAAA,CAAA;AACtB,QAAA;AAEA5E,QAAAA,GAAAA,CAAI0C,IAAI,GAAGgC,GAAAA;AACb,IAAA;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"admin-file.js","sources":["../../../server/src/controllers/admin-file.ts"],"sourcesContent":["import { merge } from 'lodash/fp';\nimport { async } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions';\n\nexport default {\n async find(ctx: Context) {\n const {\n state: { userAbility },\n } = ctx;\n\n const defaultQuery = { populate: { folder: true } };\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n // validate the incoming user query params\n await pm.validateQuery(ctx.query);\n\n const query = await async.pipe(\n // Start by sanitizing the incoming query\n (q) => pm.sanitizeQuery(q),\n // Add the default query which should not be validated or sanitized\n (q) => merge(defaultQuery, q),\n // Add the dynamic filters based on permissions' conditions\n (q) => pm.addPermissionsQueryTo(q)\n )(ctx.query);\n\n const { results: files, pagination } = await getService('upload').findPage(query);\n\n // Sign file urls for private providers\n const signedFiles = await async.map(files, getService('file').signFileUrls);\n\n const sanitizedFiles = await pm.sanitizeOutput(signedFiles);\n\n return { results: sanitizedFiles, pagination };\n },\n\n async findOne(ctx: Context) {\n const {\n state: { userAbility },\n params: { id },\n } = ctx;\n\n const { pm, file } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.read,\n FILE_MODEL_UID,\n id\n );\n\n const signedFile = await getService('file').signFileUrls(file);\n ctx.body = await pm.sanitizeOutput(signedFile);\n },\n\n async destroy(ctx: Context) {\n const { id } = ctx.params;\n const { userAbility } = ctx.state;\n\n const { pm, file } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const [body] = await Promise.all([\n pm.sanitizeOutput(file, { action: ACTIONS.read }),\n getService('upload').remove(file),\n ]);\n\n ctx.body = body;\n },\n\n async getAIMetadataCount(ctx: Context) {\n const { userAbility } = ctx.state;\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // Check if AI service is enabled\n if (!(await aiMetadataService.isEnabled())) {\n return ctx.badRequest('AI Metadata service is not enabled');\n }\n\n try {\n const { imagesWithoutMetadataCount, totalImages } =\n await aiMetadataService.countImagesWithoutMetadata();\n\n ctx.body = {\n imagesWithoutMetadataCount,\n totalImages,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to get AI metadata count';\n\n strapi.log.error('Failed to get AI metadata count', {\n message,\n error,\n });\n\n ctx.badRequest(message);\n }\n },\n\n async generateAIMetadata(ctx: Context) {\n const { userAbility } = ctx.state;\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.update,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // Check if AI service is enabled\n if (!(await aiMetadataService.isEnabled())) {\n return ctx.badRequest('AI Metadata service is not enabled');\n }\n\n try {\n // Get count first to check if there are images to process\n const result = await aiMetadataService.countImagesWithoutMetadata();\n\n if (result.imagesWithoutMetadataCount === 0) {\n ctx.body = {\n count: 0,\n message: 'No images without metadata found',\n };\n return;\n }\n\n // Create job\n const jobService = getService('aiMetadataJobs');\n const jobId = await jobService.createJob();\n\n // Start async processing (fire and forget)\n aiMetadataService.processExistingFiles(jobId, ctx.state.user).catch((err: Error) => {\n strapi.log.error('AI metadata job failed:', err);\n });\n\n // Return immediately with job ID\n ctx.body = {\n jobId,\n status: 'pending',\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to generate AI metadata';\n const cause = error instanceof Error && error.cause ? String(error.cause) : undefined;\n\n strapi.log.error('AI metadata generation failed in controller', {\n message,\n cause,\n error,\n });\n\n ctx.badRequest(cause ? `${message}: ${cause}` : message);\n }\n },\n\n async getLatestAIMetadataJob(ctx: Context) {\n if ((await getService('aiMetadata').isEnabled()) === false) {\n return ctx.notFound();\n }\n\n const jobService = getService('aiMetadataJobs');\n const job = await jobService.getLatestActiveJob();\n\n if (!job) {\n return ctx.notFound('No active job found');\n }\n\n ctx.body = job;\n },\n};\n"],"names":["find","ctx","state","userAbility","defaultQuery","populate","folder","pm","strapi","service","createPermissionsManager","ability","action","ACTIONS","read","model","FILE_MODEL_UID","isAllowed","forbidden","validateQuery","query","async","pipe","q","sanitizeQuery","merge","addPermissionsQueryTo","results","files","pagination","getService","findPage","signedFiles","map","signFileUrls","sanitizedFiles","sanitizeOutput","findOne","params","id","file","findEntityAndCheckPermissions","signedFile","body","destroy","update","Promise","all","remove","getAIMetadataCount","aiMetadataService","isEnabled","badRequest","imagesWithoutMetadataCount","totalImages","countImagesWithoutMetadata","error","message","Error","log","generateAIMetadata","result","count","jobService","jobId","createJob","processExistingFiles","user","catch","err","status","cause","String","undefined","getLatestAIMetadataJob","notFound","job","getLatestActiveJob"],"mappings":";;;;;;;;AASA,gBAAe;AACb,IAAA,MAAMA,MAAKC,GAAY,EAAA;AACrB,QAAA,MAAM,EACJC,KAAAA,EAAO,EAAEC,WAAW,EAAE,EACvB,GAAGF,GAAAA;AAEJ,QAAA,MAAMG,YAAAA,GAAe;YAAEC,QAAAA,EAAU;gBAAEC,MAAAA,EAAQ;AAAK;AAAE,SAAA;AAElD,QAAA,MAAMC,KAAKC,MAAAA,CAAOC,OAAO,CAAC,mBAAA,CAAA,CAAqBC,wBAAwB,CAAC;YACtEC,OAAAA,EAASR,WAAAA;AACTS,YAAAA,MAAAA,EAAQC,kBAAQC,IAAI;YACpBC,KAAAA,EAAOC;AACT,SAAA,CAAA;QAEA,IAAI,CAACT,EAAAA,CAAGU,SAAS,EAAE;AACjB,YAAA,OAAOhB,IAAIiB,SAAS,EAAA;AACtB,QAAA;;AAGA,QAAA,MAAMX,EAAAA,CAAGY,aAAa,CAAClB,GAAAA,CAAImB,KAAK,CAAA;AAEhC,QAAA,MAAMA,KAAAA,GAAQ,MAAMC,WAAAA,CAAMC,IAAI;AAE5B,QAAA,CAACC,CAAAA,GAAMhB,EAAAA,CAAGiB,aAAa,CAACD;AAExB,QAAA,CAACA,CAAAA,GAAME,QAAAA,CAAMrB,YAAAA,EAAcmB,CAAAA,CAAAA;AAE3B,QAAA,CAACA,IAAMhB,EAAAA,CAAGmB,qBAAqB,CAACH,CAAAA,CAAAA,CAAAA,CAChCtB,IAAImB,KAAK,CAAA;QAEX,MAAM,EAAEO,OAAAA,EAASC,KAAK,EAAEC,UAAU,EAAE,GAAG,MAAMC,gBAAAA,CAAW,QAAA,CAAA,CAAUC,QAAQ,CAACX,KAAAA,CAAAA;;QAG3E,MAAMY,WAAAA,GAAc,MAAMX,WAAAA,CAAMY,GAAG,CAACL,KAAAA,EAAOE,gBAAAA,CAAW,QAAQI,YAAY,CAAA;AAE1E,QAAA,MAAMC,cAAAA,GAAiB,MAAM5B,EAAAA,CAAG6B,cAAc,CAACJ,WAAAA,CAAAA;QAE/C,OAAO;YAAEL,OAAAA,EAASQ,cAAAA;AAAgBN,YAAAA;AAAW,SAAA;AAC/C,IAAA,CAAA;AAEA,IAAA,MAAMQ,SAAQpC,GAAY,EAAA;QACxB,MAAM,EACJC,KAAAA,EAAO,EAAEC,WAAW,EAAE,EACtBmC,MAAAA,EAAQ,EAAEC,EAAE,EAAE,EACf,GAAGtC,GAAAA;AAEJ,QAAA,MAAM,EAAEM,EAAE,EAAEiC,IAAI,EAAE,GAAG,MAAMC,2DAAAA,CACzBtC,WAAAA,EACAU,iBAAAA,CAAQC,IAAI,EACZE,wBAAAA,EACAuB,EAAAA,CAAAA;AAGF,QAAA,MAAMG,UAAAA,GAAa,MAAMZ,gBAAAA,CAAW,MAAA,CAAA,CAAQI,YAAY,CAACM,IAAAA,CAAAA;AACzDvC,QAAAA,GAAAA,CAAI0C,IAAI,GAAG,MAAMpC,EAAAA,CAAG6B,cAAc,CAACM,UAAAA,CAAAA;AACrC,IAAA,CAAA;AAEA,IAAA,MAAME,SAAQ3C,GAAY,EAAA;AACxB,QAAA,MAAM,EAAEsC,EAAE,EAAE,GAAGtC,IAAIqC,MAAM;AACzB,QAAA,MAAM,EAAEnC,WAAW,EAAE,GAAGF,IAAIC,KAAK;AAEjC,QAAA,MAAM,EAAEK,EAAE,EAAEiC,IAAI,EAAE,GAAG,MAAMC,2DAAAA,CACzBtC,WAAAA,EACAU,iBAAAA,CAAQgC,MAAM,EACd7B,wBAAAA,EACAuB,EAAAA,CAAAA;AAGF,QAAA,MAAM,CAACI,IAAAA,CAAK,GAAG,MAAMG,OAAAA,CAAQC,GAAG,CAAC;YAC/BxC,EAAAA,CAAG6B,cAAc,CAACI,IAAAA,EAAM;AAAE5B,gBAAAA,MAAAA,EAAQC,kBAAQC;AAAK,aAAA,CAAA;YAC/CgB,gBAAAA,CAAW,QAAA,CAAA,CAAUkB,MAAM,CAACR,IAAAA;AAC7B,SAAA,CAAA;AAEDvC,QAAAA,GAAAA,CAAI0C,IAAI,GAAGA,IAAAA;AACb,IAAA,CAAA;AAEA,IAAA,MAAMM,oBAAmBhD,GAAY,EAAA;AACnC,QAAA,MAAM,EAAEE,WAAW,EAAE,GAAGF,IAAIC,KAAK;AAEjC,QAAA,MAAMK,KAAKC,MAAAA,CAAOC,OAAO,CAAC,mBAAA,CAAA,CAAqBC,wBAAwB,CAAC;YACtEC,OAAAA,EAASR,WAAAA;AACTS,YAAAA,MAAAA,EAAQC,kBAAQC,IAAI;YACpBC,KAAAA,EAAOC;AACT,SAAA,CAAA;QAEA,IAAI,CAACT,EAAAA,CAAGU,SAAS,EAAE;AACjB,YAAA,OAAOhB,IAAIiB,SAAS,EAAA;AACtB,QAAA;AAEA,QAAA,MAAMgC,oBAAoBpB,gBAAAA,CAAW,YAAA,CAAA;;AAGrC,QAAA,IAAI,CAAE,MAAMoB,iBAAAA,CAAkBC,SAAS,EAAA,EAAK;YAC1C,OAAOlD,GAAAA,CAAImD,UAAU,CAAC,oCAAA,CAAA;AACxB,QAAA;QAEA,IAAI;YACF,MAAM,EAAEC,0BAA0B,EAAEC,WAAW,EAAE,GAC/C,MAAMJ,kBAAkBK,0BAA0B,EAAA;AAEpDtD,YAAAA,GAAAA,CAAI0C,IAAI,GAAG;AACTU,gBAAAA,0BAAAA;AACAC,gBAAAA;AACF,aAAA;AACF,QAAA,CAAA,CAAE,OAAOE,KAAAA,EAAO;AACd,YAAA,MAAMC,OAAAA,GAAUD,KAAAA,YAAiBE,KAAAA,GAAQF,KAAAA,CAAMC,OAAO,GAAG,iCAAA;AAEzDjD,YAAAA,MAAAA,CAAOmD,GAAG,CAACH,KAAK,CAAC,iCAAA,EAAmC;AAClDC,gBAAAA,OAAAA;AACAD,gBAAAA;AACF,aAAA,CAAA;AAEAvD,YAAAA,GAAAA,CAAImD,UAAU,CAACK,OAAAA,CAAAA;AACjB,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAMG,oBAAmB3D,GAAY,EAAA;AACnC,QAAA,MAAM,EAAEE,WAAW,EAAE,GAAGF,IAAIC,KAAK;AAEjC,QAAA,MAAMK,KAAKC,MAAAA,CAAOC,OAAO,CAAC,mBAAA,CAAA,CAAqBC,wBAAwB,CAAC;YACtEC,OAAAA,EAASR,WAAAA;AACTS,YAAAA,MAAAA,EAAQC,kBAAQgC,MAAM;YACtB9B,KAAAA,EAAOC;AACT,SAAA,CAAA;QAEA,IAAI,CAACT,EAAAA,CAAGU,SAAS,EAAE;AACjB,YAAA,OAAOhB,IAAIiB,SAAS,EAAA;AACtB,QAAA;AAEA,QAAA,MAAMgC,oBAAoBpB,gBAAAA,CAAW,YAAA,CAAA;;AAGrC,QAAA,IAAI,CAAE,MAAMoB,iBAAAA,CAAkBC,SAAS,EAAA,EAAK;YAC1C,OAAOlD,GAAAA,CAAImD,UAAU,CAAC,oCAAA,CAAA;AACxB,QAAA;QAEA,IAAI;;YAEF,MAAMS,MAAAA,GAAS,MAAMX,iBAAAA,CAAkBK,0BAA0B,EAAA;YAEjE,IAAIM,MAAAA,CAAOR,0BAA0B,KAAK,CAAA,EAAG;AAC3CpD,gBAAAA,GAAAA,CAAI0C,IAAI,GAAG;oBACTmB,KAAAA,EAAO,CAAA;oBACPL,OAAAA,EAAS;AACX,iBAAA;AACA,gBAAA;AACF,YAAA;;AAGA,YAAA,MAAMM,aAAajC,gBAAAA,CAAW,gBAAA,CAAA;YAC9B,MAAMkC,KAAAA,GAAQ,MAAMD,UAAAA,CAAWE,SAAS,EAAA;;YAGxCf,iBAAAA,CAAkBgB,oBAAoB,CAACF,KAAAA,EAAO/D,GAAAA,CAAIC,KAAK,CAACiE,IAAI,CAAA,CAAEC,KAAK,CAAC,CAACC,GAAAA,GAAAA;AACnE7D,gBAAAA,MAAAA,CAAOmD,GAAG,CAACH,KAAK,CAAC,yBAAA,EAA2Ba,GAAAA,CAAAA;AAC9C,YAAA,CAAA,CAAA;;AAGApE,YAAAA,GAAAA,CAAI0C,IAAI,GAAG;AACTqB,gBAAAA,KAAAA;gBACAM,MAAAA,EAAQ;AACV,aAAA;AACF,QAAA,CAAA,CAAE,OAAOd,KAAAA,EAAO;AACd,YAAA,MAAMC,OAAAA,GAAUD,KAAAA,YAAiBE,KAAAA,GAAQF,KAAAA,CAAMC,OAAO,GAAG,gCAAA;YACzD,MAAMc,KAAAA,GAAQf,iBAAiBE,KAAAA,IAASF,KAAAA,CAAMe,KAAK,GAAGC,MAAAA,CAAOhB,KAAAA,CAAMe,KAAK,CAAA,GAAIE,SAAAA;AAE5EjE,YAAAA,MAAAA,CAAOmD,GAAG,CAACH,KAAK,CAAC,6CAAA,EAA+C;AAC9DC,gBAAAA,OAAAA;AACAc,gBAAAA,KAAAA;AACAf,gBAAAA;AACF,aAAA,CAAA;YAEAvD,GAAAA,CAAImD,UAAU,CAACmB,KAAAA,GAAQ,CAAA,EAAGd,QAAQ,EAAE,EAAEc,OAAO,GAAGd,OAAAA,CAAAA;AAClD,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAMiB,wBAAuBzE,GAAY,EAAA;AACvC,QAAA,IAAI,MAAO6B,gBAAAA,CAAW,YAAA,CAAA,CAAcqB,SAAS,OAAQ,KAAA,EAAO;AAC1D,YAAA,OAAOlD,IAAI0E,QAAQ,EAAA;AACrB,QAAA;AAEA,QAAA,MAAMZ,aAAajC,gBAAAA,CAAW,gBAAA,CAAA;QAC9B,MAAM8C,GAAAA,GAAM,MAAMb,UAAAA,CAAWc,kBAAkB,EAAA;AAE/C,QAAA,IAAI,CAACD,GAAAA,EAAK;YACR,OAAO3E,GAAAA,CAAI0E,QAAQ,CAAC,qBAAA,CAAA;AACtB,QAAA;AAEA1E,QAAAA,GAAAA,CAAI0C,IAAI,GAAGiC,GAAAA;AACb,IAAA;AACF,CAAA;;;;"}
@@ -132,6 +132,9 @@ var adminFile = {
132
132
  }
133
133
  },
134
134
  async getLatestAIMetadataJob (ctx) {
135
+ if (await getService('aiMetadata').isEnabled() === false) {
136
+ return ctx.notFound();
137
+ }
135
138
  const jobService = getService('aiMetadataJobs');
136
139
  const job = await jobService.getLatestActiveJob();
137
140
  if (!job) {
@@ -1 +1 @@
1
- {"version":3,"file":"admin-file.mjs","sources":["../../../server/src/controllers/admin-file.ts"],"sourcesContent":["import { merge } from 'lodash/fp';\nimport { async } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions';\n\nexport default {\n async find(ctx: Context) {\n const {\n state: { userAbility },\n } = ctx;\n\n const defaultQuery = { populate: { folder: true } };\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n // validate the incoming user query params\n await pm.validateQuery(ctx.query);\n\n const query = await async.pipe(\n // Start by sanitizing the incoming query\n (q) => pm.sanitizeQuery(q),\n // Add the default query which should not be validated or sanitized\n (q) => merge(defaultQuery, q),\n // Add the dynamic filters based on permissions' conditions\n (q) => pm.addPermissionsQueryTo(q)\n )(ctx.query);\n\n const { results: files, pagination } = await getService('upload').findPage(query);\n\n // Sign file urls for private providers\n const signedFiles = await async.map(files, getService('file').signFileUrls);\n\n const sanitizedFiles = await pm.sanitizeOutput(signedFiles);\n\n return { results: sanitizedFiles, pagination };\n },\n\n async findOne(ctx: Context) {\n const {\n state: { userAbility },\n params: { id },\n } = ctx;\n\n const { pm, file } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.read,\n FILE_MODEL_UID,\n id\n );\n\n const signedFile = await getService('file').signFileUrls(file);\n ctx.body = await pm.sanitizeOutput(signedFile);\n },\n\n async destroy(ctx: Context) {\n const { id } = ctx.params;\n const { userAbility } = ctx.state;\n\n const { pm, file } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const [body] = await Promise.all([\n pm.sanitizeOutput(file, { action: ACTIONS.read }),\n getService('upload').remove(file),\n ]);\n\n ctx.body = body;\n },\n\n async getAIMetadataCount(ctx: Context) {\n const { userAbility } = ctx.state;\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // Check if AI service is enabled\n if (!(await aiMetadataService.isEnabled())) {\n return ctx.badRequest('AI Metadata service is not enabled');\n }\n\n try {\n const { imagesWithoutMetadataCount, totalImages } =\n await aiMetadataService.countImagesWithoutMetadata();\n\n ctx.body = {\n imagesWithoutMetadataCount,\n totalImages,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to get AI metadata count';\n\n strapi.log.error('Failed to get AI metadata count', {\n message,\n error,\n });\n\n ctx.badRequest(message);\n }\n },\n\n async generateAIMetadata(ctx: Context) {\n const { userAbility } = ctx.state;\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.update,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // Check if AI service is enabled\n if (!(await aiMetadataService.isEnabled())) {\n return ctx.badRequest('AI Metadata service is not enabled');\n }\n\n try {\n // Get count first to check if there are images to process\n const result = await aiMetadataService.countImagesWithoutMetadata();\n\n if (result.imagesWithoutMetadataCount === 0) {\n ctx.body = {\n count: 0,\n message: 'No images without metadata found',\n };\n return;\n }\n\n // Create job\n const jobService = getService('aiMetadataJobs');\n const jobId = await jobService.createJob();\n\n // Start async processing (fire and forget)\n aiMetadataService.processExistingFiles(jobId, ctx.state.user).catch((err: Error) => {\n strapi.log.error('AI metadata job failed:', err);\n });\n\n // Return immediately with job ID\n ctx.body = {\n jobId,\n status: 'pending',\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to generate AI metadata';\n const cause = error instanceof Error && error.cause ? String(error.cause) : undefined;\n\n strapi.log.error('AI metadata generation failed in controller', {\n message,\n cause,\n error,\n });\n\n ctx.badRequest(cause ? `${message}: ${cause}` : message);\n }\n },\n\n async getLatestAIMetadataJob(ctx: Context) {\n const jobService = getService('aiMetadataJobs');\n const job = await jobService.getLatestActiveJob();\n\n if (!job) {\n return ctx.notFound('No active job found');\n }\n\n ctx.body = job;\n },\n};\n"],"names":["find","ctx","state","userAbility","defaultQuery","populate","folder","pm","strapi","service","createPermissionsManager","ability","action","ACTIONS","read","model","FILE_MODEL_UID","isAllowed","forbidden","validateQuery","query","async","pipe","q","sanitizeQuery","merge","addPermissionsQueryTo","results","files","pagination","getService","findPage","signedFiles","map","signFileUrls","sanitizedFiles","sanitizeOutput","findOne","params","id","file","findEntityAndCheckPermissions","signedFile","body","destroy","update","Promise","all","remove","getAIMetadataCount","aiMetadataService","isEnabled","badRequest","imagesWithoutMetadataCount","totalImages","countImagesWithoutMetadata","error","message","Error","log","generateAIMetadata","result","count","jobService","jobId","createJob","processExistingFiles","user","catch","err","status","cause","String","undefined","getLatestAIMetadataJob","job","getLatestActiveJob","notFound"],"mappings":"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"}
1
+ {"version":3,"file":"admin-file.mjs","sources":["../../../server/src/controllers/admin-file.ts"],"sourcesContent":["import { merge } from 'lodash/fp';\nimport { async } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions';\n\nexport default {\n async find(ctx: Context) {\n const {\n state: { userAbility },\n } = ctx;\n\n const defaultQuery = { populate: { folder: true } };\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n // validate the incoming user query params\n await pm.validateQuery(ctx.query);\n\n const query = await async.pipe(\n // Start by sanitizing the incoming query\n (q) => pm.sanitizeQuery(q),\n // Add the default query which should not be validated or sanitized\n (q) => merge(defaultQuery, q),\n // Add the dynamic filters based on permissions' conditions\n (q) => pm.addPermissionsQueryTo(q)\n )(ctx.query);\n\n const { results: files, pagination } = await getService('upload').findPage(query);\n\n // Sign file urls for private providers\n const signedFiles = await async.map(files, getService('file').signFileUrls);\n\n const sanitizedFiles = await pm.sanitizeOutput(signedFiles);\n\n return { results: sanitizedFiles, pagination };\n },\n\n async findOne(ctx: Context) {\n const {\n state: { userAbility },\n params: { id },\n } = ctx;\n\n const { pm, file } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.read,\n FILE_MODEL_UID,\n id\n );\n\n const signedFile = await getService('file').signFileUrls(file);\n ctx.body = await pm.sanitizeOutput(signedFile);\n },\n\n async destroy(ctx: Context) {\n const { id } = ctx.params;\n const { userAbility } = ctx.state;\n\n const { pm, file } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const [body] = await Promise.all([\n pm.sanitizeOutput(file, { action: ACTIONS.read }),\n getService('upload').remove(file),\n ]);\n\n ctx.body = body;\n },\n\n async getAIMetadataCount(ctx: Context) {\n const { userAbility } = ctx.state;\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // Check if AI service is enabled\n if (!(await aiMetadataService.isEnabled())) {\n return ctx.badRequest('AI Metadata service is not enabled');\n }\n\n try {\n const { imagesWithoutMetadataCount, totalImages } =\n await aiMetadataService.countImagesWithoutMetadata();\n\n ctx.body = {\n imagesWithoutMetadataCount,\n totalImages,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to get AI metadata count';\n\n strapi.log.error('Failed to get AI metadata count', {\n message,\n error,\n });\n\n ctx.badRequest(message);\n }\n },\n\n async generateAIMetadata(ctx: Context) {\n const { userAbility } = ctx.state;\n\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.update,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // Check if AI service is enabled\n if (!(await aiMetadataService.isEnabled())) {\n return ctx.badRequest('AI Metadata service is not enabled');\n }\n\n try {\n // Get count first to check if there are images to process\n const result = await aiMetadataService.countImagesWithoutMetadata();\n\n if (result.imagesWithoutMetadataCount === 0) {\n ctx.body = {\n count: 0,\n message: 'No images without metadata found',\n };\n return;\n }\n\n // Create job\n const jobService = getService('aiMetadataJobs');\n const jobId = await jobService.createJob();\n\n // Start async processing (fire and forget)\n aiMetadataService.processExistingFiles(jobId, ctx.state.user).catch((err: Error) => {\n strapi.log.error('AI metadata job failed:', err);\n });\n\n // Return immediately with job ID\n ctx.body = {\n jobId,\n status: 'pending',\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to generate AI metadata';\n const cause = error instanceof Error && error.cause ? String(error.cause) : undefined;\n\n strapi.log.error('AI metadata generation failed in controller', {\n message,\n cause,\n error,\n });\n\n ctx.badRequest(cause ? `${message}: ${cause}` : message);\n }\n },\n\n async getLatestAIMetadataJob(ctx: Context) {\n if ((await getService('aiMetadata').isEnabled()) === false) {\n return ctx.notFound();\n }\n\n const jobService = getService('aiMetadataJobs');\n const job = await jobService.getLatestActiveJob();\n\n if (!job) {\n return ctx.notFound('No active job found');\n }\n\n ctx.body = job;\n },\n};\n"],"names":["find","ctx","state","userAbility","defaultQuery","populate","folder","pm","strapi","service","createPermissionsManager","ability","action","ACTIONS","read","model","FILE_MODEL_UID","isAllowed","forbidden","validateQuery","query","async","pipe","q","sanitizeQuery","merge","addPermissionsQueryTo","results","files","pagination","getService","findPage","signedFiles","map","signFileUrls","sanitizedFiles","sanitizeOutput","findOne","params","id","file","findEntityAndCheckPermissions","signedFile","body","destroy","update","Promise","all","remove","getAIMetadataCount","aiMetadataService","isEnabled","badRequest","imagesWithoutMetadataCount","totalImages","countImagesWithoutMetadata","error","message","Error","log","generateAIMetadata","result","count","jobService","jobId","createJob","processExistingFiles","user","catch","err","status","cause","String","undefined","getLatestAIMetadataJob","notFound","job","getLatestActiveJob"],"mappings":"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"}
@@ -37,7 +37,8 @@ var contentApi = (({ strapi })=>{
37
37
  await validateQuery(ctx.query, ctx);
38
38
  const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);
39
39
  const files = await index.getService('upload').findMany(sanitizedQuery);
40
- ctx.body = await sanitizeOutput(files, ctx);
40
+ const signedFiles = await utils.async.map(files, index.getService('file').signFileUrls);
41
+ ctx.body = await sanitizeOutput(signedFiles, ctx);
41
42
  },
42
43
  async findOne (ctx) {
43
44
  const { params: { id } } = ctx;
@@ -47,7 +48,8 @@ var contentApi = (({ strapi })=>{
47
48
  if (!file) {
48
49
  return ctx.notFound('file.notFound');
49
50
  }
50
- ctx.body = await sanitizeOutput(file, ctx);
51
+ const signedFile = await index.getService('file').signFileUrls(file);
52
+ ctx.body = await sanitizeOutput(signedFile, ctx);
51
53
  },
52
54
  async destroy (ctx) {
53
55
  const { params: { id } } = ctx;
@@ -56,7 +58,8 @@ var contentApi = (({ strapi })=>{
56
58
  return ctx.notFound('file.notFound');
57
59
  }
58
60
  await index.getService('upload').remove(file);
59
- ctx.body = await sanitizeOutput(file, ctx);
61
+ const signedFile = await index.getService('file').signFileUrls(file);
62
+ ctx.body = await sanitizeOutput(signedFile, ctx);
60
63
  },
61
64
  async updateFileInfo (ctx) {
62
65
  const { query: { id }, request: { body } } = ctx;
@@ -65,7 +68,8 @@ var contentApi = (({ strapi })=>{
65
68
  throw new ValidationError('File id is required and must be a single value');
66
69
  }
67
70
  const result = await index.getService('upload').updateFileInfo(id, data.fileInfo);
68
- ctx.body = await sanitizeOutput(result, ctx);
71
+ const signedResult = await index.getService('file').signFileUrls(result);
72
+ ctx.body = await sanitizeOutput(signedResult, ctx);
69
73
  },
70
74
  async replaceFile (ctx) {
71
75
  const { query: { id }, request: { body, files: { files: filesInput } = {} } } = ctx;
@@ -85,7 +89,8 @@ var contentApi = (({ strapi })=>{
85
89
  data,
86
90
  file: validFiles[0]
87
91
  });
88
- ctx.body = await sanitizeOutput(replacedFiles, ctx);
92
+ const signedFiles = await index.getService('file').signFileUrls(replacedFiles);
93
+ ctx.body = await sanitizeOutput(signedFiles, ctx);
89
94
  },
90
95
  async uploadFiles (ctx) {
91
96
  const { request: { body, files: { files: filesInput } = {} } } = ctx;
@@ -113,7 +118,8 @@ var contentApi = (({ strapi })=>{
113
118
  data,
114
119
  files: validFiles
115
120
  });
116
- ctx.body = await sanitizeOutput(uploadedFiles, ctx);
121
+ const signedFiles = await utils.async.map(uploadedFiles, index.getService('file').signFileUrls);
122
+ ctx.body = await sanitizeOutput(signedFiles, ctx);
117
123
  ctx.status = 201;
118
124
  },
119
125
  // TODO: split into multiple endpoints
@@ -1 +1 @@
1
- {"version":3,"file":"content-api.js","sources":["../../../server/src/controllers/content-api.ts"],"sourcesContent":["import _ from 'lodash';\nimport utils, { errors } from '@strapi/utils';\n\nimport type { Context } from 'koa';\nimport type { Core } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { FILE_MODEL_UID } from '../constants';\nimport { validateUploadBody } from './validation/content-api/upload';\nimport { FileInfo } from '../types';\nimport { prepareUploadRequest } from '../utils/mime-validation';\n\nconst { ValidationError } = utils.errors;\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => {\n const sanitizeOutput = async (data: unknown | unknown[], ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth } = ctx.state;\n\n return strapi.contentAPI.sanitize.output(data, schema, { auth });\n };\n\n const validateQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.validate.query(data, schema, { auth, route });\n };\n\n const sanitizeQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.sanitize.query(data, schema, { auth, route });\n };\n\n return {\n async find(ctx: Context) {\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const files = await getService('upload').findMany(sanitizedQuery);\n\n ctx.body = await sanitizeOutput(files, ctx);\n },\n\n async findOne(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const file = await getService('upload').findOne(id, sanitizedQuery.populate!);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n ctx.body = await sanitizeOutput(file, ctx);\n },\n\n async destroy(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n const file = await getService('upload').findOne(id);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n await getService('upload').remove(file);\n\n ctx.body = await sanitizeOutput(file, ctx);\n },\n\n async updateFileInfo(ctx: Context) {\n const {\n query: { id },\n request: { body },\n } = ctx;\n const data = await validateUploadBody(body);\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const result = await getService('upload').updateFileInfo(id, data.fileInfo as any);\n\n ctx.body = await sanitizeOutput(result, ctx);\n },\n\n async replaceFile(ctx: Context) {\n const {\n query: { id },\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n // cannot replace with more than one file\n if (Array.isArray(filesInput)) {\n throw new ValidationError('Cannot replace a file with multiple ones');\n }\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const data = (await validateUploadBody(filteredBody)) as { fileInfo: FileInfo };\n\n const replacedFiles = await getService('upload').replace(id, { data, file: validFiles[0] });\n\n ctx.body = await sanitizeOutput(replacedFiles, ctx);\n },\n\n async uploadFiles(ctx: Context) {\n const {\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const isMultipleFiles = validFiles.length > 1;\n const data: any = await validateUploadBody(filteredBody, isMultipleFiles);\n\n const apiUploadFolderService = getService('api-upload-folder');\n\n const apiUploadFolder = await apiUploadFolderService.getAPIUploadFolder();\n\n if (isMultipleFiles) {\n data.fileInfo = data.fileInfo || [];\n data.fileInfo = validFiles.map((_f, i) => ({\n ...data.fileInfo[i],\n folder: apiUploadFolder.id,\n }));\n } else {\n data.fileInfo = { ...data.fileInfo, folder: apiUploadFolder.id };\n }\n\n const uploadedFiles = await getService('upload').upload({\n data,\n files: validFiles,\n });\n\n ctx.body = await sanitizeOutput(uploadedFiles as any, ctx);\n ctx.status = 201;\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new ValidationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n };\n};\n"],"names":["ValidationError","utils","errors","strapi","sanitizeOutput","data","ctx","schema","getModel","FILE_MODEL_UID","auth","state","contentAPI","sanitize","output","validateQuery","route","validate","query","sanitizeQuery","find","sanitizedQuery","files","getService","findMany","body","findOne","params","id","file","populate","notFound","destroy","remove","updateFileInfo","request","validateUploadBody","result","fileInfo","replaceFile","filesInput","validFiles","filteredBody","validationErrors","prepareUploadRequest","length","message","Array","isArray","replacedFiles","replace","uploadFiles","isMultipleFiles","apiUploadFolderService","apiUploadFolder","getAPIUploadFolder","map","_f","i","folder","uploadedFiles","upload","status","_","isEmpty","size"],"mappings":";;;;;;;;;AAYA,MAAM,EAAEA,eAAe,EAAE,GAAGC,MAAMC,MAAM;AAExC,iBAAe,CAAA,CAAC,EAAEC,MAAM,EAA2B,GAAA;IACjD,MAAMC,cAAAA,GAAiB,OAAOC,IAAAA,EAA2BC,GAAAA,GAAAA;QACvD,MAAMC,MAAAA,GAASJ,MAAAA,CAAOK,QAAQ,CAACC,wBAAAA,CAAAA;AAC/B,QAAA,MAAM,EAAEC,IAAI,EAAE,GAAGJ,IAAIK,KAAK;QAE1B,OAAOR,MAAAA,CAAOS,UAAU,CAACC,QAAQ,CAACC,MAAM,CAACT,MAAME,MAAAA,EAAQ;AAAEG,YAAAA;AAAK,SAAA,CAAA;AAChE,IAAA,CAAA;IAEA,MAAMK,aAAAA,GAAgB,OAAOV,IAAAA,EAA+BC,GAAAA,GAAAA;QAC1D,MAAMC,MAAAA,GAASJ,MAAAA,CAAOK,QAAQ,CAACC,wBAAAA,CAAAA;AAC/B,QAAA,MAAM,EAAEC,IAAI,EAAEM,KAAK,EAAE,GAAGV,IAAIK,KAAK;QAEjC,OAAOR,MAAAA,CAAOS,UAAU,CAACK,QAAQ,CAACC,KAAK,CAACb,MAAME,MAAAA,EAAQ;AAAEG,YAAAA,IAAAA;AAAMM,YAAAA;AAAM,SAAA,CAAA;AACtE,IAAA,CAAA;IAEA,MAAMG,aAAAA,GAAgB,OAAOd,IAAAA,EAA+BC,GAAAA,GAAAA;QAC1D,MAAMC,MAAAA,GAASJ,MAAAA,CAAOK,QAAQ,CAACC,wBAAAA,CAAAA;AAC/B,QAAA,MAAM,EAAEC,IAAI,EAAEM,KAAK,EAAE,GAAGV,IAAIK,KAAK;QAEjC,OAAOR,MAAAA,CAAOS,UAAU,CAACC,QAAQ,CAACK,KAAK,CAACb,MAAME,MAAAA,EAAQ;AAAEG,YAAAA,IAAAA;AAAMM,YAAAA;AAAM,SAAA,CAAA;AACtE,IAAA,CAAA;IAEA,OAAO;AACL,QAAA,MAAMI,MAAKd,GAAY,EAAA;YACrB,MAAMS,aAAAA,CAAcT,GAAAA,CAAIY,KAAK,EAAEZ,GAAAA,CAAAA;AAC/B,YAAA,MAAMe,cAAAA,GAAiB,MAAMF,aAAAA,CAAcb,GAAAA,CAAIY,KAAK,EAAEZ,GAAAA,CAAAA;AAEtD,YAAA,MAAMgB,KAAAA,GAAQ,MAAMC,gBAAAA,CAAW,QAAA,CAAA,CAAUC,QAAQ,CAACH,cAAAA,CAAAA;AAElDf,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAekB,KAAAA,EAAOhB,GAAAA,CAAAA;AACzC,QAAA,CAAA;AAEA,QAAA,MAAMoB,SAAQpB,GAAY,EAAA;AACxB,YAAA,MAAM,EACJqB,MAAAA,EAAQ,EAAEC,EAAE,EAAE,EACf,GAAGtB,GAAAA;YAEJ,MAAMS,aAAAA,CAAcT,GAAAA,CAAIY,KAAK,EAAEZ,GAAAA,CAAAA;AAC/B,YAAA,MAAMe,cAAAA,GAAiB,MAAMF,aAAAA,CAAcb,GAAAA,CAAIY,KAAK,EAAEZ,GAAAA,CAAAA;YAEtD,MAAMuB,IAAAA,GAAO,MAAMN,gBAAAA,CAAW,QAAA,CAAA,CAAUG,OAAO,CAACE,EAAAA,EAAIP,eAAeS,QAAQ,CAAA;AAE3E,YAAA,IAAI,CAACD,IAAAA,EAAM;gBACT,OAAOvB,GAAAA,CAAIyB,QAAQ,CAAC,eAAA,CAAA;AACtB,YAAA;AAEAzB,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAeyB,IAAAA,EAAMvB,GAAAA,CAAAA;AACxC,QAAA,CAAA;AAEA,QAAA,MAAM0B,SAAQ1B,GAAY,EAAA;AACxB,YAAA,MAAM,EACJqB,MAAAA,EAAQ,EAAEC,EAAE,EAAE,EACf,GAAGtB,GAAAA;AAEJ,YAAA,MAAMuB,IAAAA,GAAO,MAAMN,gBAAAA,CAAW,QAAA,CAAA,CAAUG,OAAO,CAACE,EAAAA,CAAAA;AAEhD,YAAA,IAAI,CAACC,IAAAA,EAAM;gBACT,OAAOvB,GAAAA,CAAIyB,QAAQ,CAAC,eAAA,CAAA;AACtB,YAAA;YAEA,MAAMR,gBAAAA,CAAW,QAAA,CAAA,CAAUU,MAAM,CAACJ,IAAAA,CAAAA;AAElCvB,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAeyB,IAAAA,EAAMvB,GAAAA,CAAAA;AACxC,QAAA,CAAA;AAEA,QAAA,MAAM4B,gBAAe5B,GAAY,EAAA;YAC/B,MAAM,EACJY,KAAAA,EAAO,EAAEU,EAAE,EAAE,EACbO,OAAAA,EAAS,EAAEV,IAAI,EAAE,EAClB,GAAGnB,GAAAA;YACJ,MAAMD,IAAAA,GAAO,MAAM+B,yBAAAA,CAAmBX,IAAAA,CAAAA;AAEtC,YAAA,IAAI,CAACG,EAAAA,IAAO,OAAOA,OAAO,QAAA,IAAY,OAAOA,OAAO,QAAA,EAAW;AAC7D,gBAAA,MAAM,IAAI5B,eAAAA,CAAgB,gDAAA,CAAA;AAC5B,YAAA;YAEA,MAAMqC,MAAAA,GAAS,MAAMd,gBAAAA,CAAW,QAAA,CAAA,CAAUW,cAAc,CAACN,EAAAA,EAAIvB,KAAKiC,QAAQ,CAAA;AAE1EhC,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAeiC,MAAAA,EAAQ/B,GAAAA,CAAAA;AAC1C,QAAA,CAAA;AAEA,QAAA,MAAMiC,aAAYjC,GAAY,EAAA;YAC5B,MAAM,EACJY,OAAO,EAAEU,EAAE,EAAE,EACbO,OAAAA,EAAS,EAAEV,IAAI,EAAEH,OAAO,EAAEA,KAAAA,EAAOkB,UAAU,EAAE,GAAG,EAAE,EAAE,EACrD,GAAGlC,GAAAA;AAEJ,YAAA,MAAM,EACJmC,UAAU,EACVC,YAAY,EACZxC,MAAAA,EAAQyC,gBAAgB,EACzB,GAAG,MAAMC,mCAAAA,CAAqBJ,UAAAA,EAAYf,IAAAA,EAAMtB,MAAAA,CAAAA;YACjD,IAAIsC,UAAAA,CAAWI,MAAM,KAAK,CAAA,EAAG;gBAC3B,MAAM,IAAI3C,aAAOF,eAAe,CAAC2C,gBAAgB,CAAC,CAAA,CAAE,CAACG,OAAO,CAAA;AAC9D,YAAA;;YAGA,IAAIC,KAAAA,CAAMC,OAAO,CAACR,UAAAA,CAAAA,EAAa;AAC7B,gBAAA,MAAM,IAAIxC,eAAAA,CAAgB,0CAAA,CAAA;AAC5B,YAAA;AAEA,YAAA,IAAI,CAAC4B,EAAAA,IAAO,OAAOA,OAAO,QAAA,IAAY,OAAOA,OAAO,QAAA,EAAW;AAC7D,gBAAA,MAAM,IAAI5B,eAAAA,CAAgB,gDAAA,CAAA;AAC5B,YAAA;YAEA,MAAMK,IAAAA,GAAQ,MAAM+B,yBAAAA,CAAmBM,YAAAA,CAAAA;AAEvC,YAAA,MAAMO,gBAAgB,MAAM1B,gBAAAA,CAAW,QAAA,CAAA,CAAU2B,OAAO,CAACtB,EAAAA,EAAI;AAAEvB,gBAAAA,IAAAA;gBAAMwB,IAAAA,EAAMY,UAAU,CAAC,CAAA;AAAG,aAAA,CAAA;AAEzFnC,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAe6C,aAAAA,EAAe3C,GAAAA,CAAAA;AACjD,QAAA,CAAA;AAEA,QAAA,MAAM6C,aAAY7C,GAAY,EAAA;AAC5B,YAAA,MAAM,EACJ6B,OAAAA,EAAS,EAAEV,IAAI,EAAEH,KAAAA,EAAO,EAAEA,KAAAA,EAAOkB,UAAU,EAAE,GAAG,EAAE,EAAE,EACrD,GAAGlC,GAAAA;AAEJ,YAAA,MAAM,EACJmC,UAAU,EACVC,YAAY,EACZxC,MAAAA,EAAQyC,gBAAgB,EACzB,GAAG,MAAMC,mCAAAA,CAAqBJ,UAAAA,EAAYf,IAAAA,EAAMtB,MAAAA,CAAAA;YACjD,IAAIsC,UAAAA,CAAWI,MAAM,KAAK,CAAA,EAAG;gBAC3B,MAAM,IAAI3C,aAAOF,eAAe,CAAC2C,gBAAgB,CAAC,CAAA,CAAE,CAACG,OAAO,CAAA;AAC9D,YAAA;YAEA,MAAMM,eAAAA,GAAkBX,UAAAA,CAAWI,MAAM,GAAG,CAAA;YAC5C,MAAMxC,IAAAA,GAAY,MAAM+B,yBAAAA,CAAmBM,YAAAA,EAAcU,eAAAA,CAAAA;AAEzD,YAAA,MAAMC,yBAAyB9B,gBAAAA,CAAW,mBAAA,CAAA;YAE1C,MAAM+B,eAAAA,GAAkB,MAAMD,sBAAAA,CAAuBE,kBAAkB,EAAA;AAEvE,YAAA,IAAIH,eAAAA,EAAiB;AACnB/C,gBAAAA,IAAAA,CAAKiC,QAAQ,GAAGjC,IAAAA,CAAKiC,QAAQ,IAAI,EAAE;gBACnCjC,IAAAA,CAAKiC,QAAQ,GAAGG,UAAAA,CAAWe,GAAG,CAAC,CAACC,EAAAA,EAAIC,KAAO;wBACzC,GAAGrD,IAAAA,CAAKiC,QAAQ,CAACoB,CAAAA,CAAE;AACnBC,wBAAAA,MAAAA,EAAQL,gBAAgB1B;qBAC1B,CAAA,CAAA;YACF,CAAA,MAAO;AACLvB,gBAAAA,IAAAA,CAAKiC,QAAQ,GAAG;AAAE,oBAAA,GAAGjC,KAAKiC,QAAQ;AAAEqB,oBAAAA,MAAAA,EAAQL,gBAAgB1B;AAAG,iBAAA;AACjE,YAAA;AAEA,YAAA,MAAMgC,aAAAA,GAAgB,MAAMrC,gBAAAA,CAAW,QAAA,CAAA,CAAUsC,MAAM,CAAC;AACtDxD,gBAAAA,IAAAA;gBACAiB,KAAAA,EAAOmB;AACT,aAAA,CAAA;AAEAnC,YAAAA,GAAAA,CAAImB,IAAI,GAAG,MAAMrB,cAAAA,CAAewD,aAAAA,EAAsBtD,GAAAA,CAAAA;AACtDA,YAAAA,GAAAA,CAAIwD,MAAM,GAAG,GAAA;AACf,QAAA,CAAA;;AAGA,QAAA,MAAMD,QAAOvD,GAAY,EAAA;AACvB,YAAA,MAAM,EACJY,KAAAA,EAAO,EAAEU,EAAE,EAAE,EACbO,OAAAA,EAAS,EAAEb,KAAAA,EAAO,EAAEA,KAAK,EAAE,GAAG,EAAE,EAAE,EACnC,GAAGhB,GAAAA;AAEJ,YAAA,IAAIyD,CAAAA,CAAEC,OAAO,CAAC1C,KAAAA,CAAAA,IAAW,CAACyB,KAAAA,CAAMC,OAAO,CAAC1B,KAAAA,CAAAA,IAAUA,KAAAA,CAAM2C,IAAI,KAAK,CAAA,EAAI;AACnE,gBAAA,IAAIrC,EAAAA,EAAI;oBACN,OAAO,IAAI,CAACM,cAAc,CAAC5B,GAAAA,CAAAA;AAC7B,gBAAA;AAEA,gBAAA,MAAM,IAAIN,eAAAA,CAAgB,iBAAA,CAAA;AAC5B,YAAA;YAEA,MAAO4B,CAAAA,EAAAA,GAAK,IAAI,CAACW,WAAW,GAAG,IAAI,CAACY,WAAU,EAAG7C,GAAAA,CAAAA;AACnD,QAAA;AACF,KAAA;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"content-api.js","sources":["../../../server/src/controllers/content-api.ts"],"sourcesContent":["import _ from 'lodash';\nimport utils, { async, errors } from '@strapi/utils';\n\nimport type { Context } from 'koa';\nimport type { Core } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { FILE_MODEL_UID } from '../constants';\nimport { validateUploadBody } from './validation/content-api/upload';\nimport { FileInfo } from '../types';\nimport { prepareUploadRequest } from '../utils/mime-validation';\n\nconst { ValidationError } = utils.errors;\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => {\n const sanitizeOutput = async (data: unknown | unknown[], ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth } = ctx.state;\n\n return strapi.contentAPI.sanitize.output(data, schema, { auth });\n };\n\n const validateQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.validate.query(data, schema, { auth, route });\n };\n\n const sanitizeQuery = async (data: Record<string, unknown>, ctx: Context) => {\n const schema = strapi.getModel(FILE_MODEL_UID);\n const { auth, route } = ctx.state;\n\n return strapi.contentAPI.sanitize.query(data, schema, { auth, route });\n };\n\n return {\n async find(ctx: Context) {\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const files = await getService('upload').findMany(sanitizedQuery);\n\n const signedFiles = await async.map(files, getService('file').signFileUrls);\n\n ctx.body = await sanitizeOutput(signedFiles, ctx);\n },\n\n async findOne(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n await validateQuery(ctx.query, ctx);\n const sanitizedQuery = await sanitizeQuery(ctx.query, ctx);\n\n const file = await getService('upload').findOne(id, sanitizedQuery.populate!);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n const signedFile = await getService('file').signFileUrls(file);\n\n ctx.body = await sanitizeOutput(signedFile, ctx);\n },\n\n async destroy(ctx: Context) {\n const {\n params: { id },\n } = ctx;\n\n const file = await getService('upload').findOne(id);\n\n if (!file) {\n return ctx.notFound('file.notFound');\n }\n\n await getService('upload').remove(file);\n\n const signedFile = await getService('file').signFileUrls(file);\n\n ctx.body = await sanitizeOutput(signedFile, ctx);\n },\n\n async updateFileInfo(ctx: Context) {\n const {\n query: { id },\n request: { body },\n } = ctx;\n const data = await validateUploadBody(body);\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const result = await getService('upload').updateFileInfo(id, data.fileInfo as any);\n\n const signedResult = await getService('file').signFileUrls(result);\n\n ctx.body = await sanitizeOutput(signedResult, ctx);\n },\n\n async replaceFile(ctx: Context) {\n const {\n query: { id },\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n // cannot replace with more than one file\n if (Array.isArray(filesInput)) {\n throw new ValidationError('Cannot replace a file with multiple ones');\n }\n\n if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n throw new ValidationError('File id is required and must be a single value');\n }\n\n const data = (await validateUploadBody(filteredBody)) as { fileInfo: FileInfo };\n\n const replacedFiles = await getService('upload').replace(id, { data, file: validFiles[0] });\n\n const signedFiles = await getService('file').signFileUrls(replacedFiles);\n\n ctx.body = await sanitizeOutput(signedFiles, ctx);\n },\n\n async uploadFiles(ctx: Context) {\n const {\n request: { body, files: { files: filesInput } = {} },\n } = ctx;\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(filesInput, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const isMultipleFiles = validFiles.length > 1;\n const data: any = await validateUploadBody(filteredBody, isMultipleFiles);\n\n const apiUploadFolderService = getService('api-upload-folder');\n\n const apiUploadFolder = await apiUploadFolderService.getAPIUploadFolder();\n\n if (isMultipleFiles) {\n data.fileInfo = data.fileInfo || [];\n data.fileInfo = validFiles.map((_f, i) => ({\n ...data.fileInfo[i],\n folder: apiUploadFolder.id,\n }));\n } else {\n data.fileInfo = { ...data.fileInfo, folder: apiUploadFolder.id };\n }\n\n const uploadedFiles = await getService('upload').upload({\n data,\n files: validFiles,\n });\n\n const signedFiles = await async.map(uploadedFiles as any[], getService('file').signFileUrls);\n\n ctx.body = await sanitizeOutput(signedFiles, ctx);\n ctx.status = 201;\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new ValidationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n };\n};\n"],"names":["ValidationError","utils","errors","strapi","sanitizeOutput","data","ctx","schema","getModel","FILE_MODEL_UID","auth","state","contentAPI","sanitize","output","validateQuery","route","validate","query","sanitizeQuery","find","sanitizedQuery","files","getService","findMany","signedFiles","async","map","signFileUrls","body","findOne","params","id","file","populate","notFound","signedFile","destroy","remove","updateFileInfo","request","validateUploadBody","result","fileInfo","signedResult","replaceFile","filesInput","validFiles","filteredBody","validationErrors","prepareUploadRequest","length","message","Array","isArray","replacedFiles","replace","uploadFiles","isMultipleFiles","apiUploadFolderService","apiUploadFolder","getAPIUploadFolder","_f","i","folder","uploadedFiles","upload","status","_","isEmpty","size"],"mappings":"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"}