@strapi/upload 5.60.0 → 5.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js +29 -0
- package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.js.map +1 -0
- package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs +27 -0
- package/dist/admin/components/AssetPickerDialog/MediaLibraryPickerDialog.mjs.map +1 -0
- package/dist/admin/components/Drawer.js +12 -7
- package/dist/admin/components/Drawer.js.map +1 -1
- package/dist/admin/components/Drawer.mjs +12 -7
- package/dist/admin/components/Drawer.mjs.map +1 -1
- package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js +188 -0
- package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.js.map +1 -0
- package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs +186 -0
- package/dist/admin/components/EditorFileDropZone/EditorFileDropZone.mjs.map +1 -0
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js +5 -1
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs +5 -1
- package/dist/admin/components/MediaLibraryInput/AddAssetMenu.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +37 -27
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +37 -27
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/openAssetDetails.js +46 -0
- package/dist/admin/components/MediaLibraryInput/openAssetDetails.js.map +1 -0
- package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs +43 -0
- package/dist/admin/components/MediaLibraryInput/openAssetDetails.mjs.map +1 -0
- package/dist/admin/index.js +10 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +10 -1
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/pages/Assets/AssetsPage.js +1 -1
- package/dist/admin/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/pages/Assets/AssetsPage.mjs +2 -2
- package/dist/admin/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +2 -2
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +181 -65
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +184 -69
- package/dist/admin/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
- package/dist/admin/pages/Assets/components/AssetDetails/AssetPreview.mjs +1 -1
- package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js +2 -6
- package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.js.map +1 -1
- package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs +2 -6
- package/dist/admin/pages/Assets/hooks/useIsAssetDetailsOpen.mjs.map +1 -1
- package/dist/admin/src/components/AssetPickerDialog/MediaLibraryPickerDialog.d.ts +19 -0
- package/dist/admin/src/components/Drawer.d.ts +8 -0
- package/dist/admin/src/components/EditorFileDropZone/EditorFileDropZone.d.ts +21 -0
- package/dist/admin/src/components/MediaLibraryInput/AddAssetMenu.d.ts +7 -1
- package/dist/admin/src/components/MediaLibraryInput/openAssetDetails.d.ts +10 -0
- package/dist/admin/src/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +41 -5
- package/dist/admin/src/pages/Assets/hooks/useIsAssetDetailsOpen.d.ts +2 -6
- package/dist/admin/translations/en.json.js +4 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +4 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/server/audit-logs.js +264 -0
- package/dist/server/audit-logs.js.map +1 -0
- package/dist/server/audit-logs.mjs +255 -0
- package/dist/server/audit-logs.mjs.map +1 -0
- package/dist/server/bootstrap.js +4 -0
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/bootstrap.mjs +4 -0
- package/dist/server/bootstrap.mjs.map +1 -1
- package/dist/server/controllers/admin-folder-file.js +23 -1
- package/dist/server/controllers/admin-folder-file.js.map +1 -1
- package/dist/server/controllers/admin-folder-file.mjs +23 -1
- package/dist/server/controllers/admin-folder-file.mjs.map +1 -1
- package/dist/server/services/folder.js +48 -1
- package/dist/server/services/folder.js.map +1 -1
- package/dist/server/services/folder.mjs +48 -1
- package/dist/server/services/folder.mjs.map +1 -1
- package/dist/server/services/image-manipulation.js +12 -5
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs +12 -5
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/services/upload.js +100 -16
- package/dist/server/services/upload.js.map +1 -1
- package/dist/server/services/upload.mjs +102 -18
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/src/audit-logs.d.ts +142 -0
- package/dist/server/src/audit-logs.d.ts.map +1 -0
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-folder-file.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +3 -3
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/mcp/ambient-instance.d.ts.map +1 -1
- package/dist/server/src/services/folder.d.ts.map +1 -1
- package/dist/server/src/services/image-manipulation.d.ts +3 -3
- package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +3 -3
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/upload.d.ts.map +1 -1
- package/package.json +9 -16
|
@@ -3,6 +3,7 @@ import { getService } from '../utils/index.mjs';
|
|
|
3
3
|
import { FOLDER_MODEL_UID, FILE_MODEL_UID, ACTIONS } from '../constants.mjs';
|
|
4
4
|
import { FolderContainsUnauthorizedAssetsError } from '../errors.mjs';
|
|
5
5
|
import { validateMoveManyFoldersFiles, validateDeleteManyFoldersFiles } from './validation/admin/folder-file.mjs';
|
|
6
|
+
import { readMediaMoves, emitMediaMoves } from '../audit-logs.mjs';
|
|
6
7
|
|
|
7
8
|
var adminFolderFile = {
|
|
8
9
|
async deleteMany (ctx) {
|
|
@@ -101,11 +102,13 @@ var adminFolderFile = {
|
|
|
101
102
|
const { folderIds = [], fileIds = [], destinationFolderId } = body;
|
|
102
103
|
let totalFolderNumber = 0;
|
|
103
104
|
let totalFileNumber = 0;
|
|
105
|
+
let moves = [];
|
|
104
106
|
const trx = await strapi.db.transaction();
|
|
105
107
|
try {
|
|
106
108
|
// fetch folders
|
|
107
109
|
const existingFolders = await strapi.db.queryBuilder(FOLDER_MODEL_UID).select([
|
|
108
110
|
'id',
|
|
111
|
+
'name',
|
|
109
112
|
'pathId',
|
|
110
113
|
'path'
|
|
111
114
|
]).where({
|
|
@@ -115,7 +118,8 @@ var adminFolderFile = {
|
|
|
115
118
|
}).transacting(trx.get()).forUpdate().execute();
|
|
116
119
|
// fetch files
|
|
117
120
|
const existingFiles = await strapi.db.queryBuilder(FILE_MODEL_UID).select([
|
|
118
|
-
'id'
|
|
121
|
+
'id',
|
|
122
|
+
'name'
|
|
119
123
|
]).where({
|
|
120
124
|
id: {
|
|
121
125
|
$in: fileIds
|
|
@@ -135,6 +139,19 @@ var adminFolderFile = {
|
|
|
135
139
|
strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;
|
|
136
140
|
// @ts-expect-error - no dynamic typings for the models
|
|
137
141
|
const pathColName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;
|
|
142
|
+
// Read before the write: the audit log records where each item was.
|
|
143
|
+
const fileFolderAttribute = strapi.db.metadata.get(FILE_MODEL_UID).attributes.folder;
|
|
144
|
+
const folderParentAttribute = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;
|
|
145
|
+
moves = await readMediaMoves((table)=>strapi.db.getConnection(table).transacting(trx.get()), {
|
|
146
|
+
files: existingFiles,
|
|
147
|
+
folders: existingFolders,
|
|
148
|
+
destinationFolderId,
|
|
149
|
+
// @ts-expect-error - no dynamic typings for the models
|
|
150
|
+
fileFolderJoinTable: fileFolderAttribute.joinTable,
|
|
151
|
+
// @ts-expect-error - no dynamic typings for the models
|
|
152
|
+
folderParentJoinTable: folderParentAttribute.joinTable,
|
|
153
|
+
folderTable
|
|
154
|
+
});
|
|
138
155
|
if (existingFolders.length > 0) {
|
|
139
156
|
// update folders' parent relation
|
|
140
157
|
// @ts-expect-error - no dynamic typings for the models
|
|
@@ -199,6 +216,11 @@ var adminFolderFile = {
|
|
|
199
216
|
await trx.rollback();
|
|
200
217
|
throw e;
|
|
201
218
|
}
|
|
219
|
+
emitMediaMoves({
|
|
220
|
+
strapi
|
|
221
|
+
}, moves).catch((error)=>{
|
|
222
|
+
strapi.log.error(`Could not record media moves in audit logs: ${error?.message ?? error}`);
|
|
223
|
+
});
|
|
202
224
|
const updatedFolders = await strapi.db.query(FOLDER_MODEL_UID).findMany({
|
|
203
225
|
where: {
|
|
204
226
|
id: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-folder-file.mjs","sources":["../../../server/src/controllers/admin-folder-file.ts"],"sourcesContent":["import { errors, strings } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { FolderContainsUnauthorizedAssetsError } from '../errors';\nimport {\n validateDeleteManyFoldersFiles,\n validateMoveManyFoldersFiles,\n} from './validation/admin/folder-file';\n\nimport type { File, Folder } from '../types';\n\nexport default {\n async deleteMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.update,\n model: FILE_MODEL_UID,\n });\n\n await validateDeleteManyFoldersFiles(body);\n\n const fileService = getService('file');\n const folderService = getService('folder');\n\n const { fileIds = [], folderIds = [] } = body;\n\n const canDeleteFiles = async (files: File[]) => {\n const ids = [...new Set(files.map(({ id }) => id))];\n\n if (ids.length === 0) {\n return true;\n }\n\n const query = pmFile.addPermissionsQueryTo({ filters: { id: { $in: ids } } });\n const permittedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n select: ['id'],\n where: query.filters,\n });\n\n return permittedFiles.length === ids.length;\n };\n\n // https://github.com/strapi/strapi/issues/27649\n // Validate explicitly selected files before deleting a folder. Otherwise a mixed request\n // could delete permitted files first and only then discover a forbidden file in the folder.\n if (fileIds.length > 0) {\n const selectedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: { id: { $in: fileIds } },\n });\n\n if (!(await canDeleteFiles(selectedFiles))) {\n throw new errors.ForbiddenError();\n }\n }\n\n const {\n folders: deletedFolders,\n totalFolderNumber,\n totalFileNumber,\n } = await folderService.deleteByIds(folderIds, {\n async validateFiles(files) {\n if (!(await canDeleteFiles(files))) {\n throw new FolderContainsUnauthorizedAssetsError();\n }\n },\n });\n const deletedFiles = await fileService.deleteByIds(fileIds);\n\n if (deletedFiles.length + deletedFolders.length > 1) {\n await getService('metrics').trackUsage('didBulkDeleteMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: deletedFolders.length,\n rootAssetNumber: deletedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + deletedFiles.length,\n },\n });\n }\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(deletedFiles, { action: ACTIONS.read }),\n folders: await pmFolder.sanitizeOutput(deletedFolders),\n },\n };\n },\n async moveMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n await validateMoveManyFoldersFiles(body);\n const { folderIds = [], fileIds = [], destinationFolderId } = body;\n\n let totalFolderNumber = 0;\n let totalFileNumber = 0;\n\n const trx = await strapi.db.transaction();\n try {\n // fetch folders\n const existingFolders = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['id', 'pathId', 'path'])\n .where({ id: { $in: folderIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<Folder[]>();\n\n // fetch files\n const existingFiles = await strapi.db\n .queryBuilder(FILE_MODEL_UID)\n .select(['id'])\n .where({ id: { $in: fileIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<File[]>();\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (destinationFolderId !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: destinationFolderId })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const folderPathColName =\n // @ts-expect-error - no dynamic typings for the models\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic typings for the models\n const pathColName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n if (existingFolders.length > 0) {\n // update folders' parent relation\n // @ts-expect-error - no dynamic typings for the models\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: { $in: folderIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert(\n existingFolders.map((folder) => ({\n [joinTable.inverseJoinColumn.name]: destinationFolderId,\n [joinTable.joinColumn.name]: folder.id,\n }))\n )\n .execute();\n }\n\n for (const existingFolder of existingFolders) {\n let replaceQuery;\n switch (strapi.db.dialect.client) {\n case 'sqlite':\n replaceQuery = '? || SUBSTRING(??, ?)';\n break;\n case 'postgres':\n replaceQuery = 'CONCAT(?::TEXT, SUBSTRING(??, ?::INTEGER))';\n break;\n default:\n replaceQuery = 'CONCAT(?, SUBSTRING(??, ?))';\n }\n\n // update path for folders themselves & folders below\n totalFolderNumber = await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColName, existingFolder.path)\n .orWhere(pathColName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n pathColName,\n existingFolder.path.length + 1,\n ])\n );\n\n // update path of files below\n totalFileNumber = await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColName, existingFolder.path)\n .orWhere(folderPathColName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n folderPathColName,\n existingFolder.path.length + 1,\n ])\n );\n }\n }\n\n if (existingFiles.length > 0) {\n // update files' folder relation (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic typings for the models\n const fileJoinTable = strapi.db.metadata.get(FILE_MODEL_UID).attributes.folder.joinTable;\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [fileJoinTable.joinColumn.name]: { $in: fileIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .insert(\n existingFiles.map((file) => ({\n [fileJoinTable.inverseJoinColumn.name]: destinationFolderId,\n [fileJoinTable.joinColumn.name]: file.id,\n }))\n )\n .execute();\n }\n\n // update files main fields (path + updatedBy)\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .whereIn('id', fileIds)\n .update(folderPathColName, destinationFolderPath);\n }\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n const updatedFolders = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n where: { id: { $in: folderIds } },\n });\n\n const updatedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: { id: { $in: fileIds } },\n });\n\n await getService('metrics').trackUsage('didBulkMoveMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: updatedFolders.length,\n rootAssetNumber: updatedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + updatedFiles.length,\n },\n });\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(updatedFiles),\n folders: await pmFolder.sanitizeOutput(updatedFolders),\n },\n };\n },\n};\n"],"names":["deleteMany","ctx","body","request","state","userAbility","pmFolder","strapi","service","createPermissionsManager","ability","model","FOLDER_MODEL_UID","pmFile","action","ACTIONS","update","FILE_MODEL_UID","validateDeleteManyFoldersFiles","fileService","getService","folderService","fileIds","folderIds","canDeleteFiles","files","ids","Set","map","id","length","query","addPermissionsQueryTo","filters","$in","permittedFiles","db","findMany","select","where","selectedFiles","errors","ForbiddenError","folders","deletedFolders","totalFolderNumber","totalFileNumber","deleteByIds","validateFiles","FolderContainsUnauthorizedAssetsError","deletedFiles","trackUsage","eventProperties","rootFolderNumber","rootAssetNumber","totalAssetNumber","data","sanitizeOutput","read","moveMany","validateMoveManyFoldersFiles","destinationFolderId","trx","transaction","existingFolders","queryBuilder","transacting","get","forUpdate","execute","existingFiles","destinationFolderPath","destinationFolder","first","path","fileTable","getModel","collectionName","folderTable","folderPathColName","metadata","attributes","folderPath","columnName","pathColName","joinTable","parent","name","delete","joinColumn","insert","folder","inverseJoinColumn","existingFolder","replaceQuery","dialect","client","getConnection","orWhere","connection","raw","strings","joinBy","pathId","fileJoinTable","file","whereIn","commit","e","rollback","updatedFolders","updatedFiles"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"admin-folder-file.mjs","sources":["../../../server/src/controllers/admin-folder-file.ts"],"sourcesContent":["import { errors, strings } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { FolderContainsUnauthorizedAssetsError } from '../errors';\nimport {\n validateDeleteManyFoldersFiles,\n validateMoveManyFoldersFiles,\n} from './validation/admin/folder-file';\nimport { emitMediaMoves, readMediaMoves, type MediaMoveEvent } from '../audit-logs';\n\nimport type { File, Folder } from '../types';\n\nexport default {\n async deleteMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.update,\n model: FILE_MODEL_UID,\n });\n\n await validateDeleteManyFoldersFiles(body);\n\n const fileService = getService('file');\n const folderService = getService('folder');\n\n const { fileIds = [], folderIds = [] } = body;\n\n const canDeleteFiles = async (files: File[]) => {\n const ids = [...new Set(files.map(({ id }) => id))];\n\n if (ids.length === 0) {\n return true;\n }\n\n const query = pmFile.addPermissionsQueryTo({ filters: { id: { $in: ids } } });\n const permittedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n select: ['id'],\n where: query.filters,\n });\n\n return permittedFiles.length === ids.length;\n };\n\n // https://github.com/strapi/strapi/issues/27649\n // Validate explicitly selected files before deleting a folder. Otherwise a mixed request\n // could delete permitted files first and only then discover a forbidden file in the folder.\n if (fileIds.length > 0) {\n const selectedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: { id: { $in: fileIds } },\n });\n\n if (!(await canDeleteFiles(selectedFiles))) {\n throw new errors.ForbiddenError();\n }\n }\n\n const {\n folders: deletedFolders,\n totalFolderNumber,\n totalFileNumber,\n } = await folderService.deleteByIds(folderIds, {\n async validateFiles(files) {\n if (!(await canDeleteFiles(files))) {\n throw new FolderContainsUnauthorizedAssetsError();\n }\n },\n });\n const deletedFiles = await fileService.deleteByIds(fileIds);\n\n if (deletedFiles.length + deletedFolders.length > 1) {\n await getService('metrics').trackUsage('didBulkDeleteMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: deletedFolders.length,\n rootAssetNumber: deletedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + deletedFiles.length,\n },\n });\n }\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(deletedFiles, { action: ACTIONS.read }),\n folders: await pmFolder.sanitizeOutput(deletedFolders),\n },\n };\n },\n async moveMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n await validateMoveManyFoldersFiles(body);\n const { folderIds = [], fileIds = [], destinationFolderId } = body;\n\n let totalFolderNumber = 0;\n let totalFileNumber = 0;\n let moves: MediaMoveEvent[] = [];\n\n const trx = await strapi.db.transaction();\n try {\n // fetch folders\n const existingFolders = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['id', 'name', 'pathId', 'path'])\n .where({ id: { $in: folderIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<Folder[]>();\n\n // fetch files\n const existingFiles = await strapi.db\n .queryBuilder(FILE_MODEL_UID)\n .select(['id', 'name'])\n .where({ id: { $in: fileIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<File[]>();\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (destinationFolderId !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: destinationFolderId })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const folderPathColName =\n // @ts-expect-error - no dynamic typings for the models\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic typings for the models\n const pathColName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // Read before the write: the audit log records where each item was.\n const fileFolderAttribute = strapi.db.metadata.get(FILE_MODEL_UID).attributes.folder;\n const folderParentAttribute = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n moves = await readMediaMoves(\n (table) => strapi.db.getConnection(table).transacting(trx.get()),\n {\n files: existingFiles,\n folders: existingFolders,\n destinationFolderId,\n // @ts-expect-error - no dynamic typings for the models\n fileFolderJoinTable: fileFolderAttribute.joinTable,\n // @ts-expect-error - no dynamic typings for the models\n folderParentJoinTable: folderParentAttribute.joinTable,\n folderTable,\n }\n );\n\n if (existingFolders.length > 0) {\n // update folders' parent relation\n // @ts-expect-error - no dynamic typings for the models\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: { $in: folderIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert(\n existingFolders.map((folder) => ({\n [joinTable.inverseJoinColumn.name]: destinationFolderId,\n [joinTable.joinColumn.name]: folder.id,\n }))\n )\n .execute();\n }\n\n for (const existingFolder of existingFolders) {\n let replaceQuery;\n switch (strapi.db.dialect.client) {\n case 'sqlite':\n replaceQuery = '? || SUBSTRING(??, ?)';\n break;\n case 'postgres':\n replaceQuery = 'CONCAT(?::TEXT, SUBSTRING(??, ?::INTEGER))';\n break;\n default:\n replaceQuery = 'CONCAT(?, SUBSTRING(??, ?))';\n }\n\n // update path for folders themselves & folders below\n totalFolderNumber = await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColName, existingFolder.path)\n .orWhere(pathColName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n pathColName,\n existingFolder.path.length + 1,\n ])\n );\n\n // update path of files below\n totalFileNumber = await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColName, existingFolder.path)\n .orWhere(folderPathColName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n folderPathColName,\n existingFolder.path.length + 1,\n ])\n );\n }\n }\n\n if (existingFiles.length > 0) {\n // update files' folder relation (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic typings for the models\n const fileJoinTable = strapi.db.metadata.get(FILE_MODEL_UID).attributes.folder.joinTable;\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [fileJoinTable.joinColumn.name]: { $in: fileIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .insert(\n existingFiles.map((file) => ({\n [fileJoinTable.inverseJoinColumn.name]: destinationFolderId,\n [fileJoinTable.joinColumn.name]: file.id,\n }))\n )\n .execute();\n }\n\n // update files main fields (path + updatedBy)\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .whereIn('id', fileIds)\n .update(folderPathColName, destinationFolderPath);\n }\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n emitMediaMoves({ strapi }, moves).catch((error) => {\n strapi.log.error(`Could not record media moves in audit logs: ${error?.message ?? error}`);\n });\n\n const updatedFolders = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n where: { id: { $in: folderIds } },\n });\n\n const updatedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: { id: { $in: fileIds } },\n });\n\n await getService('metrics').trackUsage('didBulkMoveMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: updatedFolders.length,\n rootAssetNumber: updatedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + updatedFiles.length,\n },\n });\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(updatedFiles),\n folders: await pmFolder.sanitizeOutput(updatedFolders),\n },\n };\n },\n};\n"],"names":["deleteMany","ctx","body","request","state","userAbility","pmFolder","strapi","service","createPermissionsManager","ability","model","FOLDER_MODEL_UID","pmFile","action","ACTIONS","update","FILE_MODEL_UID","validateDeleteManyFoldersFiles","fileService","getService","folderService","fileIds","folderIds","canDeleteFiles","files","ids","Set","map","id","length","query","addPermissionsQueryTo","filters","$in","permittedFiles","db","findMany","select","where","selectedFiles","errors","ForbiddenError","folders","deletedFolders","totalFolderNumber","totalFileNumber","deleteByIds","validateFiles","FolderContainsUnauthorizedAssetsError","deletedFiles","trackUsage","eventProperties","rootFolderNumber","rootAssetNumber","totalAssetNumber","data","sanitizeOutput","read","moveMany","validateMoveManyFoldersFiles","destinationFolderId","moves","trx","transaction","existingFolders","queryBuilder","transacting","get","forUpdate","execute","existingFiles","destinationFolderPath","destinationFolder","first","path","fileTable","getModel","collectionName","folderTable","folderPathColName","metadata","attributes","folderPath","columnName","pathColName","fileFolderAttribute","folder","folderParentAttribute","parent","readMediaMoves","table","getConnection","fileFolderJoinTable","joinTable","folderParentJoinTable","name","delete","joinColumn","insert","inverseJoinColumn","existingFolder","replaceQuery","dialect","client","orWhere","connection","raw","strings","joinBy","pathId","fileJoinTable","file","whereIn","commit","e","rollback","emitMediaMoves","catch","error","log","message","updatedFolders","updatedFiles"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ var _ = require('lodash');
|
|
|
4
4
|
var utils = require('@strapi/utils');
|
|
5
5
|
var constants = require('../constants.js');
|
|
6
6
|
var index = require('../utils/index.js');
|
|
7
|
+
var auditLogs = require('../audit-logs.js');
|
|
7
8
|
|
|
8
9
|
const setPathIdAndPath = async (folder)=>{
|
|
9
10
|
const { max } = await strapi.db.queryBuilder(constants.FOLDER_MODEL_UID).max('pathId').first().execute();
|
|
@@ -100,6 +101,11 @@ const create = async (folderData, opts)=>{
|
|
|
100
101
|
strapi.eventHub.emit('media-folder.delete', {
|
|
101
102
|
folders
|
|
102
103
|
});
|
|
104
|
+
folders.forEach((folder)=>{
|
|
105
|
+
strapi.eventHub.emit(auditLogs.AUDITED_EVENTS.FOLDER_DELETE_AUDIT, {
|
|
106
|
+
folder
|
|
107
|
+
});
|
|
108
|
+
});
|
|
103
109
|
return {
|
|
104
110
|
folders,
|
|
105
111
|
totalFolderNumber,
|
|
@@ -114,6 +120,14 @@ const create = async (folderData, opts)=>{
|
|
|
114
120
|
const existingFolder = await strapi.db.query(constants.FOLDER_MODEL_UID).findOne({
|
|
115
121
|
where: {
|
|
116
122
|
id
|
|
123
|
+
},
|
|
124
|
+
populate: {
|
|
125
|
+
parent: {
|
|
126
|
+
select: [
|
|
127
|
+
'id',
|
|
128
|
+
'name'
|
|
129
|
+
]
|
|
130
|
+
}
|
|
117
131
|
}
|
|
118
132
|
});
|
|
119
133
|
if (!existingFolder) {
|
|
@@ -133,10 +147,30 @@ const create = async (folderData, opts)=>{
|
|
|
133
147
|
},
|
|
134
148
|
data: newFolder
|
|
135
149
|
});
|
|
150
|
+
strapi.eventHub.emit('media-folder.update', {
|
|
151
|
+
folder: {
|
|
152
|
+
...folder,
|
|
153
|
+
parent: existingFolder.parent ?? null
|
|
154
|
+
},
|
|
155
|
+
previous: existingFolder
|
|
156
|
+
});
|
|
136
157
|
return folder;
|
|
137
158
|
}
|
|
138
159
|
// location is updated => using transaction
|
|
139
160
|
} else {
|
|
161
|
+
const previous = await strapi.db.query(constants.FOLDER_MODEL_UID).findOne({
|
|
162
|
+
where: {
|
|
163
|
+
id
|
|
164
|
+
},
|
|
165
|
+
populate: {
|
|
166
|
+
parent: {
|
|
167
|
+
select: [
|
|
168
|
+
'id',
|
|
169
|
+
'name'
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
});
|
|
140
174
|
const trx = await strapi.db.transaction();
|
|
141
175
|
try {
|
|
142
176
|
// fetch existing folder
|
|
@@ -204,8 +238,21 @@ const create = async (folderData, opts)=>{
|
|
|
204
238
|
},
|
|
205
239
|
data: newFolder
|
|
206
240
|
});
|
|
241
|
+
const parentFolder = parent === null ? null : await strapi.db.query(constants.FOLDER_MODEL_UID).findOne({
|
|
242
|
+
where: {
|
|
243
|
+
id: parent
|
|
244
|
+
},
|
|
245
|
+
select: [
|
|
246
|
+
'id',
|
|
247
|
+
'name'
|
|
248
|
+
]
|
|
249
|
+
});
|
|
207
250
|
strapi.eventHub.emit('media-folder.update', {
|
|
208
|
-
folder
|
|
251
|
+
folder: {
|
|
252
|
+
...folder,
|
|
253
|
+
parent: parentFolder
|
|
254
|
+
},
|
|
255
|
+
previous
|
|
209
256
|
});
|
|
210
257
|
return folder;
|
|
211
258
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder.js","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { map, sortBy } from 'lodash';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\ntype DeleteByIdsOptions = {\n validateFiles?: (files: File[]) => Promise<void>;\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids: number[] = [], { validateFiles }: DeleteByIdsOptions = {}) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map(folders, 'path');\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n // A folder deletion cascades to every file in its subtree. Let callers enforce\n // request-scoped permissions against the complete set before the first destructive action.\n await validateFiles?.(filesToDelete);\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n /**\n * Omit to rename in place: the name-only branch skips the transaction that rewrites\n * descendant paths. Pass a number to re-parent, or null to move to the root.\n */\n parent?: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (parent === undefined) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (parent === undefined) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', { folder });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy(folderMap[parentId].children, 'name');\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","validateFiles","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","update","name","undefined","existingFolder","newFolder","isEdition","trx","transaction","select","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","forEach","f","parentId","push","sortBy"],"mappings":";;;;;;;AAqBA,MAAMA,mBAAmB,OAAOC,MAAAA,GAAAA;AAC9B,IAAA,MAAM,EAAEC,GAAG,EAAE,GAAG,MAAMC,OAAOC,EAAE,CAC5BC,YAAY,CAACC,4BACbJ,GAAG,CAAC,QAAA,CAAA,CACJK,KAAK,GACLC,OAAO,EAAA;AAEV,IAAA,MAAMC,SAASP,GAAAA,GAAM,CAAA;AACrB,IAAA,IAAIQ,UAAAA,GAAa,GAAA;IACjB,IAAIT,MAAAA,CAAOU,MAAM,EAAE;QACjB,MAAMC,YAAAA,GAAe,MAAMT,MAAAA,CAAOC,EAAE,CACjCS,KAAK,CAACP,0BAAAA,CAAAA,CACNQ,OAAO,CAAC;YAAEC,KAAAA,EAAO;AAAEC,gBAAAA,EAAAA,EAAIf,OAAOU;AAAO;AAAE,SAAA,CAAA;AAE1CD,QAAAA,UAAAA,GAAaE,aAAaK,IAAI;AAChC,IAAA;IAEA,OAAOC,MAAAA,CAAOC,MAAM,CAAClB,MAAAA,EAAQ;AAC3BQ,QAAAA,MAAAA;AACAQ,QAAAA,IAAAA,EAAMG,cAAQC,MAAM,CAAC,GAAA,EAAKX,UAAAA,EAAY,GAAGD,MAAAA,CAAAA,CAAQ;AACnD,KAAA,CAAA;AACF,CAAA;AAEA,MAAMa,MAAAA,GAAS,OACbC,UAAAA,EACAC,IAAAA,GAAAA;AAEA,IAAA,MAAMC,gBAAgBC,gBAAAA,CAAW,QAAA,CAAA;AAEjC,IAAA,MAAM,EAAEC,IAAI,EAAE,GAAGH,QAAQ,EAAC;AAE1B,IAAA,IAAII,cAAAA,GAAiB,MAAMH,aAAAA,CAAczB,gBAAgB,CAACuB,UAAAA,CAAAA;AAC1D,IAAA,IAAII,IAAAA,EAAM;AACRC,QAAAA,cAAAA,GAAiB,MAAMC,sBAAAA,CAAiB;AAAEF,YAAAA;SAAK,CAAA,CAAGC,cAAAA,CAAAA;AACpD,IAAA;IAEA,MAAM3B,MAAAA,GAAS,MAAME,MAAAA,CAAOC,EAAE,CAACS,KAAK,CAACP,0BAAAA,CAAAA,CAAkBgB,MAAM,CAAC;QAAEQ,IAAAA,EAAMF;AAAe,KAAA,CAAA;AAErFzB,IAAAA,MAAAA,CAAO4B,QAAQ,CAACC,IAAI,CAAC,qBAAA,EAAuB;AAAE/B,QAAAA;AAAO,KAAA,CAAA;IAErD,OAAOA,MAAAA;AACT,CAAA;AAEA;;;;IAKA,MAAMgC,WAAAA,GAAc,OAAOC,GAAAA,GAAgB,EAAE,EAAE,EAAEC,aAAa,EAAsB,GAAG,EAAE,GAAA;IACvF,MAAMC,OAAAA,GAAU,MAAMjC,MAAAA,CAAOC,EAAE,CAACS,KAAK,CAACP,0BAAAA,CAAAA,CAAkB+B,QAAQ,CAAC;QAAEtB,KAAAA,EAAO;YAAEC,EAAAA,EAAI;gBAAEsB,GAAAA,EAAKJ;AAAI;AAAE;AAAE,KAAA,CAAA;IAC/F,IAAIE,OAAAA,CAAQG,MAAM,KAAK,CAAA,EAAG;QACxB,OAAO;AACLH,YAAAA,OAAAA,EAAS,EAAE;YACXI,iBAAAA,EAAmB,CAAA;YACnBC,eAAAA,EAAiB;AACnB,SAAA;AACF,IAAA;IAEA,MAAMC,aAAAA,GAAgBC,MAAIP,OAAAA,EAAS,MAAA,CAAA;;IAGnC,MAAMQ,aAAAA,GAAgB,MAAMzC,MAAAA,CAAOC,EAAE,CAACS,KAAK,CAACgC,wBAAAA,CAAAA,CAAgBR,QAAQ,CAAC;QACnEtB,KAAAA,EAAO;AACL+B,YAAAA,GAAAA,EAAKJ,aAAAA,CAAcK,OAAO,CAAC,CAAC9B,IAAAA,GAAS;AACnC,oBAAA;wBAAE+B,UAAAA,EAAY;4BAAEC,GAAAA,EAAKhC;AAAK;AAAE,qBAAA;AAC5B,oBAAA;wBAAE+B,UAAAA,EAAY;4BAAEE,WAAAA,EAAa,CAAA,EAAGjC,IAAAA,CAAK,CAAC;AAAE;AAAE;AAC3C,iBAAA;AACH;AACF,KAAA,CAAA;;;AAIA,IAAA,MAAMkB,aAAAA,GAAgBS,aAAAA,CAAAA;IAEtB,MAAMO,OAAAA,CAAQC,GAAG,CAACR,aAAAA,CAAcD,GAAG,CAAC,CAACU,IAAAA,GAAe3B,gBAAAA,CAAW,QAAA,CAAA,CAAU4B,MAAM,CAACD,IAAAA,CAAAA,CAAAA,CAAAA;;AAGhF,IAAA,MAAM,EAAEE,KAAAA,EAAOf,iBAAiB,EAAE,GAAG,MAAMrC,MAAAA,CAAOC,EAAE,CAACS,KAAK,CAACP,0BAAAA,CAAAA,CAAkBkD,UAAU,CAAC;QACtFzC,KAAAA,EAAO;AACL+B,YAAAA,GAAAA,EAAKJ,aAAAA,CAAcK,OAAO,CAAC,CAAC9B,IAAAA,GAAS;AACnC,oBAAA;wBAAEA,IAAAA,EAAM;4BAAEgC,GAAAA,EAAKhC;AAAK;AAAE,qBAAA;AACtB,oBAAA;wBAAEA,IAAAA,EAAM;4BAAEiC,WAAAA,EAAa,CAAA,EAAGjC,IAAAA,CAAK,CAAC;AAAE;AAAE;AACrC,iBAAA;AACH;AACF,KAAA,CAAA;AAEAd,IAAAA,MAAAA,CAAO4B,QAAQ,CAACC,IAAI,CAAC,qBAAA,EAAuB;AAAEI,QAAAA;AAAQ,KAAA,CAAA;IAEtD,OAAO;AACLA,QAAAA,OAAAA;AACAI,QAAAA,iBAAAA;AACAC,QAAAA,eAAAA,EAAiBG,cAAcL;AACjC,KAAA;AACF,CAAA;AAEA;;AAEC,IACD,MAAMkB,MAAAA,GAAS,OACbzC,EAAAA,EACA,EACE0C,IAAI,EACJ/C,MAAM,EAQP,EACD,EAAEgB,IAAI,EAAqC,GAAA;;AAG3C,IAAA,IAAIhB,WAAWgD,SAAAA,EAAW;QACxB,MAAMC,cAAAA,GAAiB,MAAMzD,MAAAA,CAAOC,EAAE,CAACS,KAAK,CAACP,0BAAAA,CAAAA,CAAkBQ,OAAO,CAAC;YAAEC,KAAAA,EAAO;AAAEC,gBAAAA;AAAG;AAAE,SAAA,CAAA;AAEvF,QAAA,IAAI,CAAC4C,cAAAA,EAAgB;YACnB,OAAOD,SAAAA;AACT,QAAA;AAEA,QAAA,MAAME,YAAYhC,sBAAAA,CAAiB;AAAEF,YAAAA,IAAAA;YAAMmC,SAAAA,EAAW;SAAK,CAAA,CAAG;AAAEJ,YAAAA,IAAAA;AAAM/C,YAAAA;AAAO,SAAA,CAAA;AAE7E,QAAA,IAAIA,WAAWgD,SAAAA,EAAW;YACxB,MAAM1D,MAAAA,GAAS,MAAME,MAAAA,CAAOC,EAAE,CAC3BS,KAAK,CAACP,0BAAAA,CAAAA,CACNmD,MAAM,CAAC;gBAAE1C,KAAAA,EAAO;AAAEC,oBAAAA;AAAG,iBAAA;gBAAGc,IAAAA,EAAM+B;AAAU,aAAA,CAAA;YAE3C,OAAO5D,MAAAA;AACT,QAAA;;IAEF,CAAA,MAAO;AACL,QAAA,MAAM8D,GAAAA,GAAM,MAAM5D,MAAAA,CAAOC,EAAE,CAAC4D,WAAW,EAAA;QACvC,IAAI;;YAEF,MAAMJ,cAAAA,GAAiB,MAAMzD,MAAAA,CAAOC,EAAE,CACnCC,YAAY,CAACC,0BAAAA,CAAAA,CACb2D,MAAM,CAAC;AAAC,gBAAA,QAAA;AAAU,gBAAA;AAAO,aAAA,CAAA,CACzBlD,KAAK,CAAC;AAAEC,gBAAAA;aAAG,CAAA,CACXkD,WAAW,CAACH,GAAAA,CAAII,GAAG,IACnBC,SAAS,EAAA,CACT7D,KAAK,EAAA,CACLC,OAAO,EAAA;;;AAIV,YAAA,MAAM,EAAE6D,SAAS,EAAE,GAAGlE,OAAOC,EAAE,CAACkE,QAAQ,CAACH,GAAG,CAAC7D,0BAAAA,CAAAA,CAAkBiE,UAAU,CAAC5D,MAAM;AAChF,YAAA,MAAMR,OAAOC,EAAE,CACZC,YAAY,CAACgE,UAAUX,IAAI,CAAA,CAC3BQ,WAAW,CAACH,IAAII,GAAG,EAAA,CAAA,CACnBK,MAAM,EAAA,CACNzD,KAAK,CAAC;AAAE,gBAAA,CAACsD,SAAAA,CAAUI,UAAU,CAACf,IAAI,GAAG1C;AAAG,aAAA,CAAA,CACxCR,OAAO,EAAA;AAEV,YAAA,IAAIG,WAAW,IAAA,EAAM;AACnB,gBAAA,MAAMR,MAAAA,CAAOC,EAAE,CACZC,YAAY,CAACgE,SAAAA,CAAUX,IAAI,CAAA,CAC3BQ,WAAW,CAACH,GAAAA,CAAII,GAAG,EAAA,CAAA,CACnBO,MAAM,CAAC;AAAE,oBAAA,CAACL,SAAAA,CAAUM,iBAAiB,CAACjB,IAAI,GAAG/C,MAAAA;AAAQ,oBAAA,CAAC0D,SAAAA,CAAUI,UAAU,CAACf,IAAI,GAAG1C;AAAG,iBAAA,CAAA,CACrFD,KAAK,CAAC;AAAE,oBAAA,CAACsD,SAAAA,CAAUI,UAAU,CAACf,IAAI,GAAG1C;AAAG,iBAAA,CAAA,CACxCR,OAAO,EAAA;AACZ,YAAA;;AAGA,YAAA,IAAIoE,qBAAAA,GAAwB,GAAA;AAC5B,YAAA,IAAIjE,WAAW,IAAA,EAAM;AACnB,gBAAA,MAAMkE,iBAAAA,GAAoB,MAAM1E,MAAAA,CAAOC,EAAE,CACtCC,YAAY,CAACC,0BAAAA,CAAAA,CACb2D,MAAM,CAAC,MAAA,CAAA,CACPlD,KAAK,CAAC;oBAAEC,EAAAA,EAAIL;AAAO,iBAAA,CAAA,CACnBuD,WAAW,CAACH,GAAAA,CAAII,GAAG,EAAA,CAAA,CACnB5D,KAAK,GACLC,OAAO,EAAA;AACVoE,gBAAAA,qBAAAA,GAAwBC,kBAAkB5D,IAAI;AAChD,YAAA;AAEA,YAAA,MAAM6D,WAAAA,GAAc3E,MAAAA,CAAO4E,QAAQ,CAACzE,4BAAkB0E,cAAc;AACpE,YAAA,MAAMC,SAAAA,GAAY9E,MAAAA,CAAO4E,QAAQ,CAAClC,0BAAgBmC,cAAc;AAChE,YAAA,MAAME;YAEJ/E,MAAAA,CAAOC,EAAE,CAACkE,QAAQ,CAACH,GAAG,CAACtB,wBAAAA,CAAAA,CAAgB0B,UAAU,CAACvB,UAAU,CAACmC,UAAU;;AAEzE,YAAA,MAAMC,cAAAA,GAAiBjF,MAAAA,CAAOC,EAAE,CAACkE,QAAQ,CAACH,GAAG,CAAC7D,0BAAAA,CAAAA,CAAkBiE,UAAU,CAACtD,IAAI,CAACkE,UAAU;;AAG1F,YAAA,MAAMhF,OAAOC,EAAE,CACZiF,aAAa,CAACP,aACdZ,WAAW,CAACH,GAAAA,CAAII,GAAG,IACnBpD,KAAK,CAACqE,gBAAgBxB,cAAAA,CAAe3C,IAAI,EACzCqE,OAAO,CAACF,cAAAA,EAAgB,MAAA,EAAQ,GAAGxB,cAAAA,CAAe3C,IAAI,CAAC,EAAE,CAAC,CAAA,CAC1DwC,MAAM,CACL2B,cAAAA,EACAjF,OAAOC,EAAE,CAACmF,UAAU,CAACC,GAAG,CAAC,mBAAA,EAAqB;AAC5CJ,gBAAAA,cAAAA;AACAxB,gBAAAA,cAAAA,CAAe3C,IAAI;AACnBG,gBAAAA,aAAAA,CAAQC,MAAM,CAAC,GAAA,EAAKuD,uBAAuB,CAAA,EAAGhB,cAAAA,CAAenD,MAAM,CAAA,CAAE;AACtE,aAAA,CAAA,CAAA;;AAIL,YAAA,MAAMN,OAAOC,EAAE,CACZiF,aAAa,CAACJ,WACdf,WAAW,CAACH,GAAAA,CAAII,GAAG,IACnBpD,KAAK,CAACmE,sBAAsBtB,cAAAA,CAAe3C,IAAI,EAC/CqE,OAAO,CAACJ,oBAAAA,EAAsB,MAAA,EAAQ,GAAGtB,cAAAA,CAAe3C,IAAI,CAAC,EAAE,CAAC,CAAA,CAChEwC,MAAM,CACLyB,oBAAAA,EACA/E,OAAOC,EAAE,CAACmF,UAAU,CAACC,GAAG,CAAC,mBAAA,EAAqB;AAC5CN,gBAAAA,oBAAAA;AACAtB,gBAAAA,cAAAA,CAAe3C,IAAI;AACnBG,gBAAAA,aAAAA,CAAQC,MAAM,CAAC,GAAA,EAAKuD,uBAAuB,CAAA,EAAGhB,cAAAA,CAAenD,MAAM,CAAA,CAAE;AACtE,aAAA,CAAA,CAAA;AAGL,YAAA,MAAMsD,IAAI0B,MAAM,EAAA;AAClB,QAAA,CAAA,CAAE,OAAOC,CAAAA,EAAG;AACV,YAAA,MAAM3B,IAAI4B,QAAQ,EAAA;YAClB,MAAMD,CAAAA;AACR,QAAA;;AAGA,QAAA,MAAM7B,YAAYhC,sBAAAA,CAAiB;AAAEF,YAAAA,IAAAA;YAAMmC,SAAAA,EAAW;SAAK,CAAA,CAAG;AAAEJ,YAAAA;AAAK,SAAA,CAAA;QAErE,MAAMzD,MAAAA,GAAS,MAAME,MAAAA,CAAOC,EAAE,CAC3BS,KAAK,CAACP,0BAAAA,CAAAA,CACNmD,MAAM,CAAC;YAAE1C,KAAAA,EAAO;AAAEC,gBAAAA;AAAG,aAAA;YAAGc,IAAAA,EAAM+B;AAAU,SAAA,CAAA;AAE3C1D,QAAAA,MAAAA,CAAO4B,QAAQ,CAACC,IAAI,CAAC,qBAAA,EAAuB;AAAE/B,YAAAA;AAAO,SAAA,CAAA;QACrD,OAAOA,MAAAA;AACT,IAAA;AACF,CAAA;AAEA;;;;AAIC,IACD,MAAM2F,MAAAA,GAAS,OAAOC,MAAAA,GAAS,EAAE,GAAA;IAC/B,MAAMtC,KAAAA,GAAQ,MAAMpD,MAAAA,CAAOC,EAAE,CAACS,KAAK,CAACP,0BAAAA,CAAAA,CAAkBiD,KAAK,CAAC;QAAExC,KAAAA,EAAO8E;AAAO,KAAA,CAAA;AAC5E,IAAA,OAAOtC,KAAAA,GAAQ,CAAA;AACjB,CAAA;AAEA;;;AAGC,IACD,MAAMuC,YAAAA,GAAe,UAAA;;AAEnB,IAAA,MAAM,EAAEzB,SAAS,EAAE,GAAGlE,OAAOC,EAAE,CAACkE,QAAQ,CAACH,GAAG,CAAC7D,0BAAAA,CAAAA,CAAkBiE,UAAU,CAAC5D,MAAM;AAChF,IAAA,MAAMoF,EAAAA,GAAK5F,MAAAA,CAAOC,EAAE,CAACC,YAAY,CAACC,0BAAAA,CAAAA;IAClC,MAAM0F,KAAAA,GAAQD,GAAGE,QAAQ,EAAA;AACzB,IAAA,MAAM7D,OAAAA,GAAW,MAAM2D,EAAAA,CACpB9B,MAAM,CAAC;AAAC,QAAA,IAAA;AAAM,QAAA,MAAA;QAAQ,CAAA,EAAG+B,KAAAA,CAAM,CAAC,EAAE3B,SAAAA,CAAUM,iBAAiB,CAACjB,IAAI,CAAC,UAAU;AAAE,KAAA,CAAA,CAC/EwC,IAAI,CAAC;AACJF,QAAAA,KAAAA;AACAG,QAAAA,eAAAA,EAAiB9B,UAAUX,IAAI;QAC/B0C,gBAAAA,EAAkB/B,SAAAA,CAAUI,UAAU,CAACf,IAAI;QAC3C2C,UAAAA,EAAYhC,SAAAA,CAAUI,UAAU,CAAC2B,gBAAgB;AACjDE,QAAAA,SAAAA,EAAWP,GAAGC;AAChB,KAAA,CAAA,CACCxF,OAAO,CAAC;QAAE+F,UAAAA,EAAY;AAAM,KAAA,CAAA;AAE/B,IAAA,MAAMC,SAAAA,GAAuB;QAC3BC,IAAAA,EAAM;AAAEC,YAAAA,QAAAA,EAAU;AAAG;AACvB,KAAA;IAEAtE,OAAAA,CAAQuE,OAAO,CAAC,CAACC,CAAAA,GAAAA;AACfJ,QAAAA,SAAS,CAACI,CAAAA,CAAE5F,EAAE,CAAC,GAAG;AAAE,YAAA,GAAG4F,CAAC;AAAEF,YAAAA,QAAAA,EAAU;AAAG,SAAA;AACzC,IAAA,CAAA,CAAA;IAEAtE,OAAAA,CAAQuE,OAAO,CAAC,CAACC,CAAAA,GAAAA;QACf,MAAMC,QAAAA,GAAWD,CAAAA,CAAEjG,MAAM,IAAI,MAAA;AAE7B,QAAA,IAAI,CAAC6F,SAAS,CAACK,QAAAA,CAAS,EAAE;YACxBL,SAAS,CAACK,SAAS,GAAG;AAAEH,gBAAAA,QAAAA,EAAU;AAAG,aAAA;AACvC,QAAA;QAEAF,SAAS,CAACK,QAAAA,CAAS,CAACH,QAAQ,CAACI,IAAI,CAACN,SAAS,CAACI,CAAAA,CAAE5F,EAAE,CAAC,CAAA;QACjDwF,SAAS,CAACK,QAAAA,CAAS,CAACH,QAAQ,GAAGK,QAAAA,CAAOP,SAAS,CAACK,QAAAA,CAAS,CAACH,QAAQ,EAAE,MAAA,CAAA;AACpE,QAAA,OAAOF,SAAS,CAACI,CAAAA,CAAE5F,EAAE,CAAC,CAACL,MAAM;AAC/B,IAAA,CAAA,CAAA;IAEA,OAAO6F,SAAAA,CAAUC,IAAI,CAACC,QAAQ;AAChC,CAAA;AAEA,aAAe;AACbpF,IAAAA,MAAAA;AACAsE,IAAAA,MAAAA;AACA3D,IAAAA,WAAAA;AACAwB,IAAAA,MAAAA;AACAzD,IAAAA,gBAAAA;AACA8F,IAAAA;AACF,CAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"folder.js","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { map, sortBy } from 'lodash';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\nimport { AUDITED_EVENTS } from '../audit-logs';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\ntype DeleteByIdsOptions = {\n validateFiles?: (files: File[]) => Promise<void>;\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids: number[] = [], { validateFiles }: DeleteByIdsOptions = {}) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map(folders, 'path');\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n // A folder deletion cascades to every file in its subtree. Let callers enforce\n // request-scoped permissions against the complete set before the first destructive action.\n await validateFiles?.(filesToDelete);\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n folders.forEach((folder: Folder) => {\n strapi.eventHub.emit(AUDITED_EVENTS.FOLDER_DELETE_AUDIT, { folder });\n });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n /**\n * Omit to rename in place: the name-only branch skips the transaction that rewrites\n * descendant paths. Pass a number to re-parent, or null to move to the root.\n */\n parent?: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (parent === undefined) {\n const existingFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id }, populate: { parent: { select: ['id', 'name'] } } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (parent === undefined) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', {\n folder: { ...folder, parent: existingFolder.parent ?? null },\n previous: existingFolder,\n });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const previous = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id }, populate: { parent: { select: ['id', 'name'] } } });\n\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n const parentFolder =\n parent === null\n ? null\n : await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: parent }, select: ['id', 'name'] });\n\n strapi.eventHub.emit('media-folder.update', {\n folder: { ...folder, parent: parentFolder },\n previous,\n });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy(folderMap[parentId].children, 'name');\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","validateFiles","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","forEach","AUDITED_EVENTS","FOLDER_DELETE_AUDIT","update","name","undefined","existingFolder","populate","select","newFolder","isEdition","previous","trx","transaction","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","f","parentId","push","sortBy"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { sortBy, map } from 'lodash';
|
|
|
2
2
|
import { strings, setCreatorFields } from '@strapi/utils';
|
|
3
3
|
import { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants.mjs';
|
|
4
4
|
import { getService } from '../utils/index.mjs';
|
|
5
|
+
import { AUDITED_EVENTS } from '../audit-logs.mjs';
|
|
5
6
|
|
|
6
7
|
const setPathIdAndPath = async (folder)=>{
|
|
7
8
|
const { max } = await strapi.db.queryBuilder(FOLDER_MODEL_UID).max('pathId').first().execute();
|
|
@@ -98,6 +99,11 @@ const create = async (folderData, opts)=>{
|
|
|
98
99
|
strapi.eventHub.emit('media-folder.delete', {
|
|
99
100
|
folders
|
|
100
101
|
});
|
|
102
|
+
folders.forEach((folder)=>{
|
|
103
|
+
strapi.eventHub.emit(AUDITED_EVENTS.FOLDER_DELETE_AUDIT, {
|
|
104
|
+
folder
|
|
105
|
+
});
|
|
106
|
+
});
|
|
101
107
|
return {
|
|
102
108
|
folders,
|
|
103
109
|
totalFolderNumber,
|
|
@@ -112,6 +118,14 @@ const create = async (folderData, opts)=>{
|
|
|
112
118
|
const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({
|
|
113
119
|
where: {
|
|
114
120
|
id
|
|
121
|
+
},
|
|
122
|
+
populate: {
|
|
123
|
+
parent: {
|
|
124
|
+
select: [
|
|
125
|
+
'id',
|
|
126
|
+
'name'
|
|
127
|
+
]
|
|
128
|
+
}
|
|
115
129
|
}
|
|
116
130
|
});
|
|
117
131
|
if (!existingFolder) {
|
|
@@ -131,10 +145,30 @@ const create = async (folderData, opts)=>{
|
|
|
131
145
|
},
|
|
132
146
|
data: newFolder
|
|
133
147
|
});
|
|
148
|
+
strapi.eventHub.emit('media-folder.update', {
|
|
149
|
+
folder: {
|
|
150
|
+
...folder,
|
|
151
|
+
parent: existingFolder.parent ?? null
|
|
152
|
+
},
|
|
153
|
+
previous: existingFolder
|
|
154
|
+
});
|
|
134
155
|
return folder;
|
|
135
156
|
}
|
|
136
157
|
// location is updated => using transaction
|
|
137
158
|
} else {
|
|
159
|
+
const previous = await strapi.db.query(FOLDER_MODEL_UID).findOne({
|
|
160
|
+
where: {
|
|
161
|
+
id
|
|
162
|
+
},
|
|
163
|
+
populate: {
|
|
164
|
+
parent: {
|
|
165
|
+
select: [
|
|
166
|
+
'id',
|
|
167
|
+
'name'
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
});
|
|
138
172
|
const trx = await strapi.db.transaction();
|
|
139
173
|
try {
|
|
140
174
|
// fetch existing folder
|
|
@@ -202,8 +236,21 @@ const create = async (folderData, opts)=>{
|
|
|
202
236
|
},
|
|
203
237
|
data: newFolder
|
|
204
238
|
});
|
|
239
|
+
const parentFolder = parent === null ? null : await strapi.db.query(FOLDER_MODEL_UID).findOne({
|
|
240
|
+
where: {
|
|
241
|
+
id: parent
|
|
242
|
+
},
|
|
243
|
+
select: [
|
|
244
|
+
'id',
|
|
245
|
+
'name'
|
|
246
|
+
]
|
|
247
|
+
});
|
|
205
248
|
strapi.eventHub.emit('media-folder.update', {
|
|
206
|
-
folder
|
|
249
|
+
folder: {
|
|
250
|
+
...folder,
|
|
251
|
+
parent: parentFolder
|
|
252
|
+
},
|
|
253
|
+
previous
|
|
207
254
|
});
|
|
208
255
|
return folder;
|
|
209
256
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder.mjs","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { map, sortBy } from 'lodash';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\ntype DeleteByIdsOptions = {\n validateFiles?: (files: File[]) => Promise<void>;\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids: number[] = [], { validateFiles }: DeleteByIdsOptions = {}) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map(folders, 'path');\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n // A folder deletion cascades to every file in its subtree. Let callers enforce\n // request-scoped permissions against the complete set before the first destructive action.\n await validateFiles?.(filesToDelete);\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n /**\n * Omit to rename in place: the name-only branch skips the transaction that rewrites\n * descendant paths. Pass a number to re-parent, or null to move to the root.\n */\n parent?: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (parent === undefined) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (parent === undefined) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', { folder });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy(folderMap[parentId].children, 'name');\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","validateFiles","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","update","name","undefined","existingFolder","newFolder","isEdition","trx","transaction","select","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","forEach","f","parentId","push","sortBy"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"folder.mjs","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { map, sortBy } from 'lodash';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\nimport { AUDITED_EVENTS } from '../audit-logs';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\ntype DeleteByIdsOptions = {\n validateFiles?: (files: File[]) => Promise<void>;\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids: number[] = [], { validateFiles }: DeleteByIdsOptions = {}) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map(folders, 'path');\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n // A folder deletion cascades to every file in its subtree. Let callers enforce\n // request-scoped permissions against the complete set before the first destructive action.\n await validateFiles?.(filesToDelete);\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n folders.forEach((folder: Folder) => {\n strapi.eventHub.emit(AUDITED_EVENTS.FOLDER_DELETE_AUDIT, { folder });\n });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n /**\n * Omit to rename in place: the name-only branch skips the transaction that rewrites\n * descendant paths. Pass a number to re-parent, or null to move to the root.\n */\n parent?: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (parent === undefined) {\n const existingFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id }, populate: { parent: { select: ['id', 'name'] } } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (parent === undefined) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', {\n folder: { ...folder, parent: existingFolder.parent ?? null },\n previous: existingFolder,\n });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const previous = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id }, populate: { parent: { select: ['id', 'name'] } } });\n\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n const parentFolder =\n parent === null\n ? null\n : await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: parent }, select: ['id', 'name'] });\n\n strapi.eventHub.emit('media-folder.update', {\n folder: { ...folder, parent: parentFolder },\n previous,\n });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy(folderMap[parentId].children, 'name');\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","validateFiles","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","forEach","AUDITED_EVENTS","FOLDER_DELETE_AUDIT","update","name","undefined","existingFolder","populate","select","newFolder","isEdition","previous","trx","transaction","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","f","parentId","push","sortBy"],"mappings":"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"}
|
|
@@ -32,7 +32,8 @@ const FORMATS_TO_RESIZE = new Set([
|
|
|
32
32
|
'png',
|
|
33
33
|
'webp',
|
|
34
34
|
'tiff',
|
|
35
|
-
'gif'
|
|
35
|
+
'gif',
|
|
36
|
+
'avif'
|
|
36
37
|
]);
|
|
37
38
|
const FORMATS_TO_PROCESS = new Set([
|
|
38
39
|
'jpeg',
|
|
@@ -51,6 +52,10 @@ const FORMATS_TO_OPTIMIZE = new Set([
|
|
|
51
52
|
'avif'
|
|
52
53
|
]);
|
|
53
54
|
const isOptimizableFormat = (format)=>format !== undefined && FORMATS_TO_OPTIMIZE.has(format);
|
|
55
|
+
/**
|
|
56
|
+
* sharp reports AVIF files as `heif` with `av1` compression. Normalize them to `avif`;
|
|
57
|
+
* other HEIF files (e.g. HEIC, `hevc` compression) keep the `heif` format and stay unprocessed.
|
|
58
|
+
*/ const getFormat = ({ format, compression })=>format === 'heif' && compression === 'av1' ? 'avif' : format;
|
|
54
59
|
const writeStreamToFile = (stream, path)=>new Promise((resolve, reject)=>{
|
|
55
60
|
const writeStream = fs__default.default.createWriteStream(path);
|
|
56
61
|
// Reject promise if there is an error with the provided stream
|
|
@@ -133,7 +138,9 @@ const generateThumbnail = async (file)=>{
|
|
|
133
138
|
*
|
|
134
139
|
*/ const optimize = async (file)=>{
|
|
135
140
|
const { sizeOptimization = false, autoOrientation = false } = await index.getService('upload').getSettings() ?? {};
|
|
136
|
-
const
|
|
141
|
+
const metadata = await getMetadata(file);
|
|
142
|
+
const format = getFormat(metadata);
|
|
143
|
+
const { size } = metadata;
|
|
137
144
|
if ((sizeOptimization || autoOrientation) && isOptimizableFormat(format)) {
|
|
138
145
|
let transformer;
|
|
139
146
|
if (!file.filepath) {
|
|
@@ -246,7 +253,7 @@ const isOptimizableImage = async (file)=>{
|
|
|
246
253
|
let format;
|
|
247
254
|
try {
|
|
248
255
|
const metadata = await getMetadata(file);
|
|
249
|
-
format = metadata
|
|
256
|
+
format = getFormat(metadata);
|
|
250
257
|
} catch {
|
|
251
258
|
// throw when the file is not a supported image
|
|
252
259
|
return false;
|
|
@@ -257,7 +264,7 @@ const isResizableImage = async (file)=>{
|
|
|
257
264
|
let format;
|
|
258
265
|
try {
|
|
259
266
|
const metadata = await getMetadata(file);
|
|
260
|
-
format = metadata
|
|
267
|
+
format = getFormat(metadata);
|
|
261
268
|
} catch {
|
|
262
269
|
// throw when the file is not a supported image
|
|
263
270
|
return false;
|
|
@@ -268,7 +275,7 @@ const isImage = async (file)=>{
|
|
|
268
275
|
let format;
|
|
269
276
|
try {
|
|
270
277
|
const metadata = await getMetadata(file);
|
|
271
|
-
format = metadata
|
|
278
|
+
format = getFormat(metadata);
|
|
272
279
|
} catch {
|
|
273
280
|
// throw when the file is not a supported image
|
|
274
281
|
return false;
|