| import fs from "fs/promises"; |
| import path from "path"; |
| import type { Project } from "@/types"; |
|
|
| export const STORAGE_ROOT = path.join(process.cwd(), "storage"); |
| export const UPLOADS_DIR = path.join(STORAGE_ROOT, "uploads"); |
| export const EXPORTS_DIR = path.join(STORAGE_ROOT, "exports"); |
| export const RENDERS_DIR = path.join(STORAGE_ROOT, "renders"); |
| export const PROJECTS_DIR = path.join(STORAGE_ROOT, "projects"); |
|
|
| export async function ensureStorageDirs() { |
| await Promise.all([ |
| fs.mkdir(UPLOADS_DIR, { recursive: true }), |
| fs.mkdir(EXPORTS_DIR, { recursive: true }), |
| fs.mkdir(RENDERS_DIR, { recursive: true }), |
| fs.mkdir(PROJECTS_DIR, { recursive: true }), |
| ]); |
| } |
|
|
| export function projectPath(id: string) { |
| return path.join(PROJECTS_DIR, `${id}.json`); |
| } |
|
|
| export function uploadDir(id: string) { |
| return path.join(UPLOADS_DIR, id); |
| } |
|
|
| export function videoPath(id: string) { |
| return path.join(uploadDir(id), "video.mp4"); |
| } |
|
|
| export function audioPath(id: string) { |
| return path.join(uploadDir(id), "voiceover.mp3"); |
| } |
|
|
| export function renderDir(id: string) { |
| return path.join(RENDERS_DIR, id); |
| } |
|
|
| export function exportPath(id: string) { |
| return path.join(EXPORTS_DIR, `${id}_captioned.mp4`); |
| } |
|
|
| export async function saveProject(project: Project) { |
| await ensureStorageDirs(); |
| |
| const target = projectPath(project.id); |
| const tmp = `${target}.${process.pid}.tmp`; |
| await fs.writeFile(tmp, JSON.stringify(project, null, 2)); |
| await fs.rename(tmp, target); |
| } |
|
|
| export async function loadProject(id: string): Promise<Project | null> { |
| try { |
| const raw = await fs.readFile(projectPath(id), "utf-8"); |
| return JSON.parse(raw) as Project; |
| } catch { |
| return null; |
| } |
| } |
|
|