import path from 'path' import { pathToFileURL } from 'url' export interface TemplateFieldRow { label: string value: string } export interface ParsedSoonTemplate { frontImageUrl: string backImageUrl: string fields: TemplateFieldRow[] } function pickArray(obj: Record, key: string): Record[] { const entry = Object.entries(obj).find(([k]) => k.toLowerCase() === key.toLowerCase()) if (!Array.isArray(entry?.[1])) return [] return (entry[1] as unknown[]).filter((x) => x && typeof x === 'object') as Record[] } function pickStr(item: Record, keys: string[]): string { for (const k of keys) { const hit = Object.entries(item).find(([name]) => name.toLowerCase() === k.toLowerCase()) if (hit && hit[1] != null && String(hit[1]).trim()) return String(hit[1]).trim() } return '' } function sideOf(item: Record): 'front' | 'back' | '' { const raw = pickStr(item, ['side', 'face', 'surface', 'cardface']).toLowerCase() if (!raw) return '' if (['front', '0', 'f', '正面', '正'].includes(raw)) return 'front' if (['back', '1', 'b', '背面', '背'].includes(raw)) return 'back' return '' } function sideLabel(side: 'front' | 'back'): string { return side === 'front' ? '正面' : '背面' } function resolveAssetPath(soonPath: string, ref: string): string { if (!ref) return '' const clean = ref.replace(/^file:\/\//i, '') const abs = path.isAbsolute(clean) ? clean : path.join(path.dirname(soonPath), clean) return pathToFileURL(abs).href } function toFieldLabel(name: string, side: 'front' | 'back'): string { return `${name} [${sideLabel(side)}]` } export function parseSoonTemplate(soonPath: string, raw: Record): ParsedSoonTemplate { const imgs = pickArray(raw, 'Img') const texts = pickArray(raw, 'Text') let frontImageUrl = '' let backImageUrl = '' const fields: TemplateFieldRow[] = [] imgs.forEach((item, idx) => { const fileRef = pickStr(item, ['file', 'path', 'img', 'image', 'src', 'filename']) if (!fileRef) return let side = sideOf(item) if (!side) side = idx === 0 ? 'front' : idx === 1 ? 'back' : 'front' const url = resolveAssetPath(soonPath, fileRef) if (side === 'front') { if (!frontImageUrl) frontImageUrl = url const name = pickStr(item, ['name', 'field', 'key']) || 'IMAGE' fields.push({ label: toFieldLabel(name, 'front'), value: fileRef }) } else if (!backImageUrl) { backImageUrl = url } }) texts.forEach((item) => { const name = pickStr(item, ['name', 'field', 'key', 'id']) if (!name) return const value = pickStr(item, ['value', 'text', 'default', 'content', 'data']) let side = sideOf(item) if (!side) side = /image|img|front/i.test(name) ? 'front' : 'back' fields.push({ label: toFieldLabel(name, side), value }) }) return { frontImageUrl, backImageUrl, fields } }