94 lines
3.0 KiB
TypeScript
94 lines
3.0 KiB
TypeScript
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,
|
|
sizeFormatted: file.isFolder ? '-' : formatFileSize(file.size),
|
|
extension: file.isFolder ? 'folder' : getFileExtension(file.name),
|
|
icon: file.isFolder ? 'mdi-folder' : getFileIcon(file.name),
|
|
displayName: getDisplayName(file.name),
|
|
}));
|
|
|
|
// Sort folders first, then files
|
|
formattedFiles.sort((a, b) => {
|
|
if (a.isFolder && !b.isFolder) return -1;
|
|
if (!a.isFolder && b.isFolder) return 1;
|
|
return a.displayName.localeCompare(b.displayName);
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
files: formattedFiles,
|
|
count: formattedFiles.length,
|
|
currentPath: prefix,
|
|
};
|
|
} catch (error: any) {
|
|
console.error('Failed to list files - Full error:', error);
|
|
console.error('Error message:', error.message);
|
|
console.error('Error stack:', error.stack);
|
|
throw createError({
|
|
statusCode: 500,
|
|
statusMessage: error.message || 'Failed to list files',
|
|
});
|
|
}
|
|
});
|
|
|
|
// Helper functions
|
|
function formatFileSize(bytes: number): string {
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
if (bytes === 0) return '0 Bytes';
|
|
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
|
|
}
|
|
|
|
function getFileExtension(filename: string): string {
|
|
const parts = filename.split('.');
|
|
return parts.length > 1 ? parts.pop()?.toLowerCase() || '' : '';
|
|
}
|
|
|
|
function getFileIcon(filename: string): string {
|
|
const ext = getFileExtension(filename);
|
|
const iconMap: Record<string, string> = {
|
|
pdf: 'mdi-file-pdf-box',
|
|
doc: 'mdi-file-document',
|
|
docx: 'mdi-file-document',
|
|
xls: 'mdi-file-excel',
|
|
xlsx: 'mdi-file-excel',
|
|
jpg: 'mdi-file-image',
|
|
jpeg: 'mdi-file-image',
|
|
png: 'mdi-file-image',
|
|
gif: 'mdi-file-image',
|
|
svg: 'mdi-file-image',
|
|
zip: 'mdi-folder-zip',
|
|
rar: 'mdi-folder-zip',
|
|
txt: 'mdi-file-document-outline',
|
|
csv: 'mdi-file-delimited',
|
|
mp4: 'mdi-file-video',
|
|
mp3: 'mdi-file-music',
|
|
};
|
|
return iconMap[ext] || 'mdi-file';
|
|
}
|
|
|
|
function getDisplayName(filepath: string): string {
|
|
// Get just the filename from the full path
|
|
const parts = filepath.split('/');
|
|
const filename = parts[parts.length - 1];
|
|
|
|
// Remove timestamp prefix if present (e.g., "1234567890-filename.pdf" -> "filename.pdf")
|
|
const match = filename.match(/^\d{10,}-(.+)$/);
|
|
return match ? match[1] : filename;
|
|
}
|