{"version":3,"file":"admin-file.mjs","sources":["../../../server/src/controllers/admin-file.ts"],"sourcesContent":["import { merge } from 'lodash/fp';\nimport { async } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions';\n\nexport default {\n  async find(ctx: Context) {\n    const {\n      state: { userAbility },\n    } = ctx;\n\n    const defaultQuery = { populate: { folder: true } };\n\n    const pm = strapi.service('admin::permission').createPermissionsManager({\n      ability: userAbility,\n      action: ACTIONS.read,\n      model: FILE_MODEL_UID,\n    });\n\n    if (!pm.isAllowed) {\n      return ctx.forbidden();\n    }\n\n    // validate the incoming user query params\n    await pm.validateQuery(ctx.query);\n\n    const query = await async.pipe(\n      // Start by sanitizing the incoming query\n      (q) => pm.sanitizeQuery(q),\n      // Add the default query which should not be validated or sanitized\n      (q) => merge(defaultQuery, q),\n      // Add the dynamic filters based on permissions' conditions\n      (q) => pm.addPermissionsQueryTo(q)\n    )(ctx.query);\n\n    const { results: files, pagination } = await getService('upload').findPage(query);\n\n    // Sign file urls for private providers\n    const signedFiles = await async.map(files, getService('file').signFileUrls);\n\n    const sanitizedFiles = await pm.sanitizeOutput(signedFiles);\n\n    return { results: sanitizedFiles, pagination };\n  },\n\n  async findOne(ctx: Context) {\n    const {\n      state: { userAbility },\n      params: { id },\n    } = ctx;\n\n    const { pm, file } = await findEntityAndCheckPermissions(\n      userAbility,\n      ACTIONS.read,\n      FILE_MODEL_UID,\n      id\n    );\n\n    const signedFile = await getService('file').signFileUrls(file);\n    ctx.body = await pm.sanitizeOutput(signedFile);\n  },\n\n  async destroy(ctx: Context) {\n    const { id } = ctx.params;\n    const { userAbility } = ctx.state;\n\n    const { pm, file } = await findEntityAndCheckPermissions(\n      userAbility,\n      ACTIONS.update,\n      FILE_MODEL_UID,\n      id\n    );\n\n    const [body] = await Promise.all([\n      pm.sanitizeOutput(file, { action: ACTIONS.read }),\n      getService('upload').remove(file),\n    ]);\n\n    ctx.body = body;\n  },\n\n  async getAIMetadataCount(ctx: Context) {\n    const { userAbility } = ctx.state;\n\n    const pm = strapi.service('admin::permission').createPermissionsManager({\n      ability: userAbility,\n      action: ACTIONS.read,\n      model: FILE_MODEL_UID,\n    });\n\n    if (!pm.isAllowed) {\n      return ctx.forbidden();\n    }\n\n    const aiMetadataService = getService('aiMetadata');\n\n    // Check if AI service is enabled\n    if (!(await aiMetadataService.isEnabled())) {\n      return ctx.badRequest('AI Metadata service is not enabled');\n    }\n\n    try {\n      const { imagesWithoutMetadataCount, totalImages } =\n        await aiMetadataService.countImagesWithoutMetadata();\n\n      ctx.body = {\n        imagesWithoutMetadataCount,\n        totalImages,\n      };\n    } catch (error) {\n      const message = error instanceof Error ? error.message : 'Failed to get AI metadata count';\n\n      strapi.log.error('Failed to get AI metadata count', {\n        message,\n        error,\n      });\n\n      ctx.badRequest(message);\n    }\n  },\n\n  async generateAIMetadata(ctx: Context) {\n    const { userAbility } = ctx.state;\n\n    const pm = strapi.service('admin::permission').createPermissionsManager({\n      ability: userAbility,\n      action: ACTIONS.update,\n      model: FILE_MODEL_UID,\n    });\n\n    if (!pm.isAllowed) {\n      return ctx.forbidden();\n    }\n\n    const aiMetadataService = getService('aiMetadata');\n\n    // Check if AI service is enabled\n    if (!(await aiMetadataService.isEnabled())) {\n      return ctx.badRequest('AI Metadata service is not enabled');\n    }\n\n    try {\n      // Get count first to check if there are images to process\n      const result = await aiMetadataService.countImagesWithoutMetadata();\n\n      if (result.imagesWithoutMetadataCount === 0) {\n        ctx.body = {\n          count: 0,\n          message: 'No images without metadata found',\n        };\n        return;\n      }\n\n      // Create job\n      const jobService = getService('aiMetadataJobs');\n      const jobId = await jobService.createJob();\n\n      // Start async processing (fire and forget)\n      aiMetadataService.processExistingFiles(jobId, ctx.state.user).catch((err: Error) => {\n        strapi.log.error('AI metadata job failed:', err);\n      });\n\n      // Return immediately with job ID\n      ctx.body = {\n        jobId,\n        status: 'pending',\n      };\n    } catch (error) {\n      const message = error instanceof Error ? error.message : 'Failed to generate AI metadata';\n      const cause = error instanceof Error && error.cause ? String(error.cause) : undefined;\n\n      strapi.log.error('AI metadata generation failed in controller', {\n        message,\n        cause,\n        error,\n      });\n\n      ctx.badRequest(cause ? `${message}: ${cause}` : message);\n    }\n  },\n\n  async getLatestAIMetadataJob(ctx: Context) {\n    if ((await getService('aiMetadata').isEnabled()) === false) {\n      return ctx.notFound();\n    }\n\n    const jobService = getService('aiMetadataJobs');\n    const job = await jobService.getLatestActiveJob();\n\n    if (!job) {\n      return ctx.notFound('No active job found');\n    }\n\n    ctx.body = job;\n  },\n};\n"],"names":["find","ctx","state","userAbility","defaultQuery","populate","folder","pm","strapi","service","createPermissionsManager","ability","action","ACTIONS","read","model","FILE_MODEL_UID","isAllowed","forbidden","validateQuery","query","async","pipe","q","sanitizeQuery","merge","addPermissionsQueryTo","results","files","pagination","getService","findPage","signedFiles","map","signFileUrls","sanitizedFiles","sanitizeOutput","findOne","params","id","file","findEntityAndCheckPermissions","signedFile","body","destroy","update","Promise","all","remove","getAIMetadataCount","aiMetadataService","isEnabled","badRequest","imagesWithoutMetadataCount","totalImages","countImagesWithoutMetadata","error","message","Error","log","generateAIMetadata","result","count","jobService","jobId","createJob","processExistingFiles","user","catch","err","status","cause","String","undefined","getLatestAIMetadataJob","notFound","job","getLatestActiveJob"],"mappings":"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"}