// src/app/api/files/route.ts import { NextResponse } from 'next/server'; import fs from 'fs'; import path from 'path'; // Define types directly in this file as they are specific to this API route. export interface File { id: string; type: 'file'; name: string; path: string; fileType: 'pdf' | 'docx' | 'pptx' | 'other'; contentSnippet: string; } export interface Folder { id:string; type: 'folder'; name: string; path: string; children: (Folder | File)[]; } export type FileSystemNode = Folder | File; // Helper function to recursively scan directories function getFileStructure(dirPath: string, relativeTo: string): FileSystemNode[] { // Ensure the base directory exists if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } const children: FileSystemNode[] = fs.readdirSync(dirPath, { withFileTypes: true }).map((dirent) => { const childAbsolutePath = path.join(dirPath, dirent.name); // This relative path will be like 'folder/file.pdf' const fileRelativePath = path.relative(relativeTo, childAbsolutePath).replace(/\\/g, '/'); const id = fileRelativePath.replace(/[\/\.]/g, '-') || 'root'; if (dirent.isDirectory()) { const subChildren = getFileStructure(childAbsolutePath, relativeTo); return { id, type: 'folder', name: dirent.name, // The browser path should start with a leading slash path: `/${fileRelativePath}`, children: subChildren } as Folder; } else { const extension = path.extname(dirent.name).toLowerCase(); let fileType: File['fileType'] = 'other'; let contentSnippet = 'A document file.'; if (extension === '.pdf') { fileType = 'pdf'; contentSnippet = 'A PDF document.'; } else if (extension === '.docx') { fileType = 'docx'; contentSnippet = 'A Word document.'; } else if (extension === '.pptx') { fileType = 'pptx'; contentSnippet = 'A PowerPoint presentation.'; } // We only want to return specific file types for this app. // You could remove this if you want to show all files. if (fileType !== 'other') { return { id, type: 'file', name: dirent.name, // The path for the browser needs to be a root-relative URL path: `/${fileRelativePath}`, fileType: fileType, contentSnippet: contentSnippet, } as File; } return null; } }).filter((node): node is FileSystemNode => node !== null); return children; } export async function GET() { try { const publicDir = path.join(process.cwd(), 'public'); const children = getFileStructure(publicDir, publicDir); // The root is now the list of files/folders in the public directory return NextResponse.json(children); } catch (error) { console.error('Failed to read file system:', error); // If 'public' directory doesn't exist or another error occurs, return an empty array. return NextResponse.json([]); } }