chore: synchronize local fixes to gitea
This commit is contained in:
85
src/server/services/FileStorageService.ts
Normal file
85
src/server/services/FileStorageService.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
const DATA_DIR = path.join(process.cwd(), 'data');
|
||||
|
||||
// Ensure data directory exists
|
||||
const initDataDir = async () => {
|
||||
try {
|
||||
await fs.access(DATA_DIR);
|
||||
} catch {
|
||||
await fs.mkdir(DATA_DIR, { recursive: true });
|
||||
}
|
||||
};
|
||||
|
||||
initDataDir();
|
||||
|
||||
export class FileStorageService<T extends { id: string }> {
|
||||
private filePath: string;
|
||||
|
||||
constructor(filename: string) {
|
||||
this.filePath = path.join(DATA_DIR, filename);
|
||||
}
|
||||
|
||||
private async readFile(): Promise<T[]> {
|
||||
try {
|
||||
await initDataDir();
|
||||
const data = await fs.readFile(this.filePath, 'utf-8');
|
||||
return JSON.parse(data);
|
||||
} catch (error: unknown) {
|
||||
const err = error as { code?: string };
|
||||
if (err.code === 'ENOENT') {
|
||||
return []; // File doesn't exist yet, return empty array
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private async writeFile(data: T[]): Promise<void> {
|
||||
await initDataDir();
|
||||
await fs.writeFile(this.filePath, JSON.stringify(data, null, 2), 'utf-8');
|
||||
}
|
||||
|
||||
async getAll(): Promise<T[]> {
|
||||
return this.readFile();
|
||||
}
|
||||
|
||||
async getById(id: string): Promise<T | null> {
|
||||
const items = await this.readFile();
|
||||
return items.find(item => item.id === id) || null;
|
||||
}
|
||||
|
||||
async create(data: Omit<T, 'id'>): Promise<T> {
|
||||
const items = await this.readFile();
|
||||
const newItem = { ...data, id: uuidv4() } as T;
|
||||
items.push(newItem);
|
||||
await this.writeFile(items);
|
||||
return newItem;
|
||||
}
|
||||
|
||||
async update(id: string, data: Partial<T>): Promise<T | null> {
|
||||
const items = await this.readFile();
|
||||
const index = items.findIndex(item => item.id === id);
|
||||
if (index === -1) return null;
|
||||
|
||||
items[index] = { ...items[index], ...data };
|
||||
await this.writeFile(items);
|
||||
return items[index];
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<boolean> {
|
||||
const items = await this.readFile();
|
||||
const filtered = items.filter(item => item.id !== id);
|
||||
if (filtered.length === items.length) return false;
|
||||
|
||||
await this.writeFile(filtered);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper for filtering by foreign keys (e.g., get parts by projectId)
|
||||
async getByField(field: keyof T, value: T[keyof T]): Promise<T[]> {
|
||||
const items = await this.readFile();
|
||||
return items.filter(item => item[field] === value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user