| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- import { promises as fs } from 'fs';
- import path from 'path';
- import type { NextRequest } from 'next/server';
- import type { Scene, Stage } from '@/lib/types/stage';
- export const CLASSROOMS_DIR = path.join(process.cwd(), 'data', 'classrooms');
- export const CLASSROOM_JOBS_DIR = path.join(process.cwd(), 'data', 'classroom-jobs');
- async function ensureDir(dir: string) {
- await fs.mkdir(dir, { recursive: true });
- }
- export async function ensureClassroomsDir() {
- await ensureDir(CLASSROOMS_DIR);
- }
- export async function ensureClassroomJobsDir() {
- await ensureDir(CLASSROOM_JOBS_DIR);
- }
- export async function writeJsonFileAtomic(filePath: string, data: unknown) {
- const dir = path.dirname(filePath);
- await ensureDir(dir);
- const tempFilePath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
- const content = JSON.stringify(data, null, 2);
- await fs.writeFile(tempFilePath, content, 'utf-8');
- await fs.rename(tempFilePath, filePath);
- }
- export function buildRequestOrigin(req: NextRequest): string {
- return req.headers.get('x-forwarded-host')
- ? `${req.headers.get('x-forwarded-proto') || 'http'}://${req.headers.get('x-forwarded-host')}`
- : req.nextUrl.origin;
- }
- export interface PersistedClassroomData {
- id: string;
- stage: Stage;
- scenes: Scene[];
- createdAt: string;
- }
- export function isValidClassroomId(id: string): boolean {
- return /^[a-zA-Z0-9_-]+$/.test(id);
- }
- export async function readClassroom(id: string): Promise<PersistedClassroomData | null> {
- const filePath = path.join(CLASSROOMS_DIR, `${id}.json`);
- try {
- const content = await fs.readFile(filePath, 'utf-8');
- return JSON.parse(content) as PersistedClassroomData;
- } catch (error) {
- if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
- return null;
- }
- throw error;
- }
- }
- export async function persistClassroom(
- data: {
- id: string;
- stage: Stage;
- scenes: Scene[];
- },
- baseUrl: string,
- ): Promise<PersistedClassroomData & { url: string }> {
- const classroomData: PersistedClassroomData = {
- id: data.id,
- stage: data.stage,
- scenes: data.scenes,
- createdAt: new Date().toISOString(),
- };
- await ensureClassroomsDir();
- const filePath = path.join(CLASSROOMS_DIR, `${data.id}.json`);
- await writeJsonFileAtomic(filePath, classroomData);
- return {
- ...classroomData,
- url: `${baseUrl}/classroom/${data.id}`,
- };
- }
|