feat: mockup types and template storage library
This commit is contained in:
@@ -0,0 +1,62 @@
|
|||||||
|
import { readFile, writeFile, mkdir, unlink } from 'fs/promises'
|
||||||
|
import { existsSync } from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
import { randomUUID } from 'crypto'
|
||||||
|
import type { MockupTemplate } from '@/types/mockup'
|
||||||
|
|
||||||
|
export const TEMPLATES_DIR = path.join(process.cwd(), 'data', 'mockup-templates')
|
||||||
|
const IMAGES_DIR = path.join(TEMPLATES_DIR, 'images')
|
||||||
|
const INDEX_PATH = path.join(TEMPLATES_DIR, 'index.json')
|
||||||
|
|
||||||
|
async function ensureDirs() {
|
||||||
|
await mkdir(IMAGES_DIR, { recursive: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readIndex(): Promise<MockupTemplate[]> {
|
||||||
|
if (!existsSync(INDEX_PATH)) return []
|
||||||
|
const raw = await readFile(INDEX_PATH, 'utf-8')
|
||||||
|
return JSON.parse(raw) as MockupTemplate[]
|
||||||
|
}
|
||||||
|
|
||||||
|
async function writeIndex(templates: MockupTemplate[]): Promise<void> {
|
||||||
|
await ensureDirs()
|
||||||
|
await writeFile(INDEX_PATH, JSON.stringify(templates, null, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listTemplates(): Promise<MockupTemplate[]> {
|
||||||
|
return readIndex()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listTemplatesByFamily(family: string): Promise<MockupTemplate[]> {
|
||||||
|
const all = await readIndex()
|
||||||
|
return all.filter(t => t.family === family)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveTemplate(
|
||||||
|
meta: Omit<MockupTemplate, 'id'>,
|
||||||
|
imageBuffer: Buffer,
|
||||||
|
ext: string,
|
||||||
|
): Promise<MockupTemplate> {
|
||||||
|
await ensureDirs()
|
||||||
|
const id = randomUUID()
|
||||||
|
const filename = `${id}.${ext}`
|
||||||
|
await writeFile(path.join(IMAGES_DIR, filename), imageBuffer)
|
||||||
|
const template: MockupTemplate = { ...meta, id, filename }
|
||||||
|
const all = await readIndex()
|
||||||
|
all.push(template)
|
||||||
|
await writeIndex(all)
|
||||||
|
return template
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteTemplate(id: string): Promise<void> {
|
||||||
|
const all = await readIndex()
|
||||||
|
const tpl = all.find(t => t.id === id)
|
||||||
|
if (!tpl) throw new Error('Template not found')
|
||||||
|
const filePath = path.join(IMAGES_DIR, tpl.filename)
|
||||||
|
if (existsSync(filePath)) await unlink(filePath)
|
||||||
|
await writeIndex(all.filter(t => t.id !== id))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTemplateImagePath(filename: string): string {
|
||||||
|
return path.join(IMAGES_DIR, filename)
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
export interface MockupTemplate {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
family: string
|
||||||
|
filename: string
|
||||||
|
description: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MockupGenerateRequest {
|
||||||
|
templateId: string
|
||||||
|
productImageBase64: string
|
||||||
|
productName: string
|
||||||
|
dimensions?: string
|
||||||
|
family: string
|
||||||
|
instruction?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MockupGenerateResult {
|
||||||
|
imageBase64: string
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user