vivid-cdn/src/lib/file-service.ts
2025-06-11 22:05:20 +02:00

88 lines
3 KiB
TypeScript

"use server";
import type { FileItem } from '@/types';
import { v4 as uuidv4 } from 'uuid';
import fs from 'node:fs';
import path from 'node:path';
const CDN_DIR = path.join(process.cwd(), 'CDN');
const METADATA_FILE_PATH = path.join(CDN_DIR, 'cdn_metadata.json');
// Internal function to load files from disk.
function _loadFilesFromDisk(): FileItem[] {
try {
if (!fs.existsSync(CDN_DIR)) {
fs.mkdirSync(CDN_DIR, { recursive: true });
}
if (fs.existsSync(METADATA_FILE_PATH)) {
const fileContent = fs.readFileSync(METADATA_FILE_PATH, 'utf-8');
// Handle case where file might be empty or just whitespace
if (!fileContent || fileContent.trim() === '') {
return [];
}
const parsedData = JSON.parse(fileContent);
// Ensure uploadDate is a string (ISO format) as expected by FileItem type
return parsedData.map((file: any) => ({
...file,
uploadDate: typeof file.uploadDate === 'string' ? file.uploadDate : new Date(file.uploadDate).toISOString(),
})) as FileItem[];
}
} catch (error) {
console.error("Error loading file metadata:", error);
// In case of error (e.g., corrupted file), return an empty list
}
return [];
}
// Internal function to save the provided files array to disk.
async function _saveFilesToDisk(filesToSave: FileItem[]): Promise<void> {
try {
if (!fs.existsSync(CDN_DIR)) {
fs.mkdirSync(CDN_DIR, { recursive: true });
}
const dataToSave = filesToSave || []; // Ensure it's an array
const data = JSON.stringify(dataToSave, null, 2); // Pretty print JSON
fs.writeFileSync(METADATA_FILE_PATH, data, 'utf-8');
} catch (error) {
console.error("Error saving file metadata:", error);
}
}
export async function getFiles(): Promise<FileItem[]> {
const currentFiles = _loadFilesFromDisk(); // Always load fresh from disk
return JSON.parse(JSON.stringify(currentFiles)).sort((a:FileItem, b:FileItem) => new Date(b.uploadDate).getTime() - new Date(a.uploadDate).getTime());
}
export async function getFileById(id: string): Promise<FileItem | null> {
const currentFiles = _loadFilesFromDisk(); // Always load fresh from disk
const file = currentFiles.find(f => f.id === id);
return file ? JSON.parse(JSON.stringify(file)) : null;
}
interface AddFilePayload {
name: string;
type: string;
size: number;
}
export async function addFile(payload: AddFilePayload): Promise<FileItem> {
const currentFiles = _loadFilesFromDisk(); // Load the current state from disk
const extension = payload.name.split('.').pop()?.toLowerCase() || 'unknown';
const newFile: FileItem = {
id: uuidv4(),
name: payload.name,
type: payload.type || 'application/octet-stream',
extension,
size: payload.size,
uploadDate: new Date().toISOString(),
url: '',
};
newFile.url = `/files/${newFile.id}`;
const updatedFiles = [newFile, ...currentFiles];
await _saveFilesToDisk(updatedFiles); // Save the updated list to disk
return JSON.parse(JSON.stringify(newFile));
}