mirror of
https://gitlab.w-hs.de/an14051/backerup-website.git
synced 2026-07-27 17:35:29 +00:00
108 lines
3.2 KiB
TypeScript
108 lines
3.2 KiB
TypeScript
import path from 'path'
|
|
import fs from 'fs/promises'
|
|
import { getDb, ensureReady } from './db'
|
|
|
|
export type FileType = 'backerup' | 'config'
|
|
|
|
export interface FileRecord {
|
|
token: string
|
|
originalName: string
|
|
displayName?: string
|
|
size: number
|
|
type: FileType
|
|
uploadedAt: string
|
|
description?: string
|
|
group?: string
|
|
containerName?: string
|
|
image?: string
|
|
}
|
|
|
|
const DATA_DIR = path.join(process.cwd(), 'data')
|
|
const UPLOADS_DIR = path.join(DATA_DIR, 'uploads')
|
|
|
|
type DbRow = Record<string, unknown>
|
|
|
|
function rowToRecord(row: DbRow): FileRecord {
|
|
return {
|
|
token: row.token as string,
|
|
originalName: row.original_name as string,
|
|
displayName: (row.display_name as string | null) ?? undefined,
|
|
size: row.size as number,
|
|
type: row.type as FileType,
|
|
uploadedAt: row.uploaded_at as string,
|
|
description: (row.description as string | null) ?? undefined,
|
|
group: (row.group_name as string | null) ?? undefined,
|
|
containerName: (row.container_name as string | null) ?? undefined,
|
|
image: (row.image as string | null) ?? undefined,
|
|
}
|
|
}
|
|
|
|
export async function readMeta(): Promise<FileRecord[]> {
|
|
await ensureReady()
|
|
const { rows } = await getDb().execute(
|
|
'SELECT * FROM files ORDER BY uploaded_at DESC',
|
|
)
|
|
return rows.map(rowToRecord)
|
|
}
|
|
|
|
export async function listGroups(): Promise<string[]> {
|
|
await ensureReady()
|
|
const { rows } = await getDb().execute(
|
|
'SELECT DISTINCT group_name FROM files WHERE group_name IS NOT NULL ORDER BY group_name',
|
|
)
|
|
return rows.map((r) => r.group_name as string)
|
|
}
|
|
|
|
export async function addFile(record: FileRecord, buffer: Buffer): Promise<void> {
|
|
await ensureReady()
|
|
await fs.mkdir(UPLOADS_DIR, { recursive: true })
|
|
const dir = path.join(UPLOADS_DIR, record.token)
|
|
await fs.mkdir(dir, { recursive: true })
|
|
await fs.writeFile(path.join(dir, record.originalName), buffer)
|
|
|
|
await getDb().execute({
|
|
sql: `INSERT INTO files
|
|
(token,original_name,display_name,size,type,uploaded_at,description,group_name,container_name,image)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?)`,
|
|
args: [
|
|
record.token,
|
|
record.originalName,
|
|
record.displayName ?? null,
|
|
record.size,
|
|
record.type,
|
|
record.uploadedAt,
|
|
record.description ?? null,
|
|
record.group ?? null,
|
|
record.containerName ?? null,
|
|
record.image ?? null,
|
|
],
|
|
})
|
|
}
|
|
|
|
export async function getFile(token: string): Promise<FileRecord | undefined> {
|
|
await ensureReady()
|
|
const { rows } = await getDb().execute({
|
|
sql: 'SELECT * FROM files WHERE token = ?',
|
|
args: [token],
|
|
})
|
|
return rows[0] ? rowToRecord(rows[0]) : undefined
|
|
}
|
|
|
|
export function getUploadPath(token: string, originalName: string): string {
|
|
return path.join(UPLOADS_DIR, token, originalName)
|
|
}
|
|
|
|
export async function deleteFile(token: string): Promise<void> {
|
|
await ensureReady()
|
|
const record = await getFile(token)
|
|
if (!record) throw new Error('File not found')
|
|
|
|
// Remove from DB first
|
|
await getDb().execute({ sql: 'DELETE FROM files WHERE token = ?', args: [token] })
|
|
|
|
// Remove upload directory (best-effort — don't fail if already gone)
|
|
const dir = path.join(UPLOADS_DIR, token)
|
|
await fs.rm(dir, { recursive: true, force: true })
|
|
}
|
|
|