UNPKG

datacops-cms

Version:

A modern, extensible CMS built with Next.js and Prisma.

78 lines (66 loc) 2.58 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ import fs from "fs" import { NextRequest, NextResponse } from "next/server" import path from "path" import { z } from "zod" import { ensurePermissionForType } from "../../permissions/route" const RelationSchema = z.object({ target: z.string(), relationType: z.enum(["one-one", "one-many", "many-many"]), }) const FieldSchema = z.object({ name: z.string(), label: z.string(), type: z.string(), required: z.boolean(), options: z.array(z.object({ label: z.string(), value: z.string(), })).optional(), description: z.string().optional(), relation: RelationSchema.optional(), slugSource: z.string().optional(), // <--- Add if you support slug fields }) const ContentTypeSchema = z.object({ name: z.string().min(1), label: z.string().min(1), fields: z.array(FieldSchema), }) function safeFieldName(name: string) { return name.trim().replace(/\s+/g, '_').replace(/[^a-zA-Z0-9_]/g, '').toLowerCase() } export async function POST(req: NextRequest) { try { const data = await req.json() const parsed = ContentTypeSchema.parse(data) // Sanitize type name (no spaces, lowercase, etc.) const safeName = safeFieldName(parsed.name) const safeFields = parsed.fields.map(f => ({ ...f, name: safeFieldName(f.name), })); const folder = path.resolve(process.cwd(), "content-types") if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true }) const filePath = path.join(folder, `${safeName}.json`) if (fs.existsSync(filePath)) { return NextResponse.json({ error: "Content type already exists" }, { status: 400 }) } // Save the parsed schema (with safe field names) try { fs.writeFileSync( filePath, JSON.stringify({ ...parsed, name: safeName, fields: safeFields }, null, 2), "utf-8" ) // ⬇️ Add this line right after file creation ensurePermissionForType(safeName); } catch (err: any) { return NextResponse.json({ error: "Failed to write schema file. " + err.message }, { status: 500 }); } return NextResponse.json({ success: true, message: "Content type schema saved.", name: safeName }) } catch (e: any) { return NextResponse.json({ error: e.message }, { status: 400 }) } }