import { HttpContext } from '@adonisjs/core/http' import listValidator from '#base_modules/FileManager/validator/list_validator' import uploadFileValidator from '#base_modules/FileManager/validator/upload_file_validator' import createDirectoryValidator from '#base_modules/FileManager/validator/create_directory_validator' import renameEntryValidator from '#base_modules/FileManager/validator/rename_entry_validator' import duplicateEntriesValidator from '#base_modules/FileManager/validator/duplicate_entries_validator' import FileMangerPolicy from '#base_modules/FileManager/policy/file_manager_policy' import { Entry, FileEntry, FolderEntry } from '#base_modules/FileManager/types/entries' import getValidatedPathFromRequest from '#base_modules/FileManager/helpers/get_validated_path_from_request' import FileManagerService from '#base_modules/FileManager/services/file_manager_service' export default class FileManagerController { private fileManagerService = new FileManagerService() async index({ request, response, bouncer }: HttpContext) { await bouncer.with(FileMangerPolicy).authorize('viewList') const path = await getValidatedPathFromRequest(request) const query = request.all() const params = await listValidator.validate({ filterBy: query?.filterBy ?? 'all', sortBy: query?.sortBy ?? 'name', sortOrder: query?.sortOrder ?? 'asc', maxResults: query?.maxResults, paginationToken: query?.paginationToken, }) const entries = await this.fileManagerService.listDirectory(path, params) const payload: { data: Entry[] meta: { nextPaginationToken: string | null } } = { data: entries.data, meta: entries.meta, } return response.ok(payload) } async show({ request, response, bouncer }: HttpContext) { await bouncer.with(FileMangerPolicy).authorize('view') const path = await getValidatedPathFromRequest(request) const result = await this.fileManagerService.getFileEntryWithPreview(path) const payload: { data: FileEntry & { content?: string } } = { data: result, } return response.ok(payload) } public async raw({ request, response, bouncer }: HttpContext) { await bouncer.with(FileMangerPolicy).authorize('view') const path = await getValidatedPathFromRequest(request) const { stream, contentType, size, name } = await this.fileManagerService.getFileStream(path) if (contentType) response.header('Content-Type', contentType) if (size !== undefined) response.header('Content-Length', String(size)) response.header('Content-Disposition', `inline; filename="${encodeURIComponent(name)}"`) return response.stream(stream) } async createFolder({ request, response, bouncer }: HttpContext) { await bouncer.with(FileMangerPolicy).authorize('create') const { name, path } = await createDirectoryValidator.validate(request.all()) const result = await this.fileManagerService.createDirectory(path, name) const payload: { data: FolderEntry } = { data: result, } return response.created(payload) } async destroy({ request, response, bouncer }: HttpContext) { await bouncer.with(FileMangerPolicy).authorize('delete') const path = await getValidatedPathFromRequest(request) await this.fileManagerService.deleteEntry(path) return response.noContent() } async rename({ request, response, bouncer }: HttpContext) { await bouncer.with(FileMangerPolicy).authorize('update') const { name, path } = await renameEntryValidator.validate(request.all()) const entry = await this.fileManagerService.moveEntry(path, name) const payload: { data: Entry } = { data: entry } return response.ok(payload) } async upload({ request, response, bouncer }: HttpContext) { await bouncer.with(FileMangerPolicy).authorize('create') const { file, path } = await uploadFileValidator.validate(request.all()) const entry = await this.fileManagerService.writeFile(path, file) const payload: { data: Entry } = { data: entry } return response.created(payload) } async duplicate({ request, response, bouncer }: HttpContext) { await bouncer.with(FileMangerPolicy).authorize('create') const { paths } = await duplicateEntriesValidator.validate(request.all()) const results = await this.fileManagerService.copyEntries(paths) const payload: { data: Entry[] } = { data: results } return response.created(payload) } async search({ request, response, bouncer }: HttpContext) { await bouncer.with(FileMangerPolicy).authorize('viewList') const query = request.input('q', '') if (!query.trim()) { return response.badRequest({ message: 'Search query is required' }) } const abortController = new AbortController() request.request.on('close', () => abortController.abort()) const results = await this.fileManagerService.search('/', query, abortController.signal) const payload: { data: Entry[] } = { data: results } return response.ok(payload) } }