diff --git a/server/api/files/list.ts b/server/api/files/list.ts index 77b2d45..58397a0 100644 --- a/server/api/files/list.ts +++ b/server/api/files/list.ts @@ -2,17 +2,12 @@ import { listFiles } from '~/server/utils/minio'; export default defineEventHandler(async (event) => { try { - console.log('List files API called'); const query = getQuery(event); const prefix = (query.prefix as string) || ''; const recursive = query.recursive === 'true'; - console.log('Listing files with prefix:', prefix, 'recursive:', recursive); - const files = await listFiles(prefix, recursive); - console.log('Files retrieved:', files.length); - // Format file list with additional metadata const formattedFiles = (files as any[]).map(file => ({ ...file, diff --git a/server/utils/minio.ts b/server/utils/minio.ts index b46bf2d..5ae47ca 100644 --- a/server/utils/minio.ts +++ b/server/utils/minio.ts @@ -5,15 +5,6 @@ import type { BucketItem } from 'minio'; export const getMinioClient = () => { const config = useRuntimeConfig().minio; - console.log('MinIO Config:', { - endPoint: config.endPoint, - port: config.port, - useSSL: config.useSSL, - bucketName: config.bucketName, - hasAccessKey: !!config.accessKey, - hasSecretKey: !!config.secretKey, - }); - return new Client({ endPoint: config.endPoint, port: config.port, @@ -28,51 +19,59 @@ export const listFiles = async (prefix: string = '', recursive: boolean = false) const client = getMinioClient(); const bucketName = useRuntimeConfig().minio.bucketName; - console.log(`Listing files from bucket: ${bucketName}, prefix: ${prefix}, recursive: ${recursive}`); - const files: any[] = []; const folders = new Set(); return new Promise(async (resolve, reject) => { try { - // First check if bucket exists - const bucketExists = await client.bucketExists(bucketName); - console.log(`Bucket ${bucketName} exists:`, bucketExists); - - if (!bucketExists) { - console.error(`Bucket ${bucketName} does not exist`); - reject(new Error(`Bucket ${bucketName} does not exist`)); - return; - } - const stream = client.listObjectsV2(bucketName, prefix, recursive); - let objectCount = 0; stream.on('data', (obj) => { - objectCount++; - console.log('Object found:', obj.name); - if (!recursive && prefix) { - // Extract folder structure when not recursive - const relativePath = obj.name.substring(prefix.length); - const firstSlash = relativePath.indexOf('/'); - - if (firstSlash > -1) { - // This is a folder - const folderName = relativePath.substring(0, firstSlash); - folders.add(prefix + folderName + '/'); - } else if (relativePath) { - // This is a file in the current folder - files.push({ - name: obj.name, - size: obj.size, - lastModified: obj.lastModified, - etag: obj.etag, - isFolder: false, - }); + if (!recursive) { + if (prefix) { + // Extract folder structure when inside a folder + const relativePath = obj.name.substring(prefix.length); + const firstSlash = relativePath.indexOf('/'); + + if (firstSlash > -1) { + // This is a folder + const folderName = relativePath.substring(0, firstSlash); + folders.add(prefix + folderName + '/'); + } else if (relativePath && !obj.name.endsWith('/')) { + // This is a file in the current folder + files.push({ + name: obj.name, + size: obj.size, + lastModified: obj.lastModified, + etag: obj.etag, + isFolder: false, + }); + } + } else { + // At root level + const firstSlash = obj.name.indexOf('/'); + + if (obj.name.endsWith('/')) { + // This is a folder placeholder + folders.add(obj.name); + } else if (firstSlash > -1) { + // This is inside a folder, extract the folder + const folderName = obj.name.substring(0, firstSlash); + folders.add(folderName + '/'); + } else { + // This is a file at root + files.push({ + name: obj.name, + size: obj.size, + lastModified: obj.lastModified, + etag: obj.etag, + isFolder: false, + }); + } } } else { - // When recursive or at root, include all files + // When recursive, include all files if (!obj.name.endsWith('/')) { files.push({ name: obj.name, @@ -91,8 +90,6 @@ export const listFiles = async (prefix: string = '', recursive: boolean = false) }); stream.on('end', () => { - console.log(`Stream ended. Total objects processed: ${objectCount}`); - // Add folders to the result const folderItems = Array.from(folders).map(folder => ({ name: folder, @@ -102,7 +99,6 @@ export const listFiles = async (prefix: string = '', recursive: boolean = false) isFolder: true, })); - console.log(`Returning ${folderItems.length} folders and ${files.length} files`); resolve([...folderItems, ...files]); }); } catch (error) { @@ -127,7 +123,15 @@ export const getDownloadUrl = async (fileName: string, expiry: number = 60 * 60) const client = getMinioClient(); const bucketName = useRuntimeConfig().minio.bucketName; - return await client.presignedGetObject(bucketName, fileName, expiry); + // Extract just the filename from the full path + const filename = fileName.split('/').pop() || fileName; + + // Force download with Content-Disposition header + const responseHeaders = { + 'response-content-disposition': `attachment; filename="${filename}"`, + }; + + return await client.presignedGetObject(bucketName, fileName, expiry, responseHeaders); }; // Delete file