{"version":3,"file":"content-api.mjs","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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"}