From 39ddebe259d637275d406ea93a57f05ee2cb7344 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 4 Jun 2025 16:56:42 +0200 Subject: [PATCH] Remove debug logs and improve file listing logic Cleaned up console.log statements from MinIO client initialization and file listing operations. Refactored folder detection logic to better handle root level files and nested folder structures in non-recursive mode. --- server/api/files/list.ts | 5 -- server/utils/minio.ts | 98 +++++++++++++++++++++------------------- 2 files changed, 51 insertions(+), 52 deletions(-) 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