UNPKG

@npio/internals

Version:

A free visual website editor, powered with your own SolidJS components.

146 lines (131 loc) 3.45 kB
import { parseMultipartFormData } from "@npio/filesystem"; import { decode } from "decode-formdata"; import { FontFaceFile } from "../../../types"; import { getFontFormat } from "../../string"; import { useFilesystemDriver } from "../filesystem"; import { useDatabase } from "../prisma"; import { extractFontMeta, faceKey, fontPath } from "./util"; export const uploadFonts = async function () { const db = useDatabase(); const prepare = async function (id: string) { const font = await db.nitroFont.findUniqueOrThrow({ include: { faces: true, }, where: { id, }, }); return { font, }; }; let preparePromise: ReturnType<typeof prepare> = undefined!; type File = { filename: string; contentType: string; format: string; }; const result = decode<Record<string, any> & { files: (File | undefined)[] }>( await parseMultipartFormData<Promise<File | undefined>>({ async handleFile(info, fields) { const format = getFontFormat(info.contentType); if (!format) { return; } if (!preparePromise) { const id = fields.find(([name]: any) => name === "id")![1]; if (typeof id !== "string") throw new Error("Invalid font id"); preparePromise = prepare(id); } const { font } = await preparePromise; const driver = useFilesystemDriver(font.driver); try { await driver.put({ name: fontPath(font, info.filename), stream: info.body, contentType: info.contentType, }); const { body, name, ...rest } = info; return { ...rest, format }; } catch (err) { console.log("Error while uploading a font", err); } }, }), { arrays: ["files"], }, ); const files = result.files.filter((file) => file != null) as File[]; if (!files.length || !preparePromise) { return; } const { font } = await preparePromise; await db.nitroFont.update({ data: { cdn: null, }, where: { id: font.id, }, }); const faces: Record< string, { id?: string; weight: any; style: any; files: FontFaceFile[]; } > = {}; for (const face of font.faces) { const key = faceKey(face.weight!, face.style); faces[key] = { id: face.id, weight: face.weight, style: face.style, files: JSON.parse(face.files), }; } for (const file of files) { const meta = extractFontMeta(file.filename); const face = (faces[meta.key] = faces[meta.key] || { weight: meta.weight, style: meta.style, files: [], }); if (!face.files.find((f) => f.name == file.filename)) { face.files.push({ format: file.format, name: file.filename, mime: file.contentType, }); } } for (const face of Object.values(faces)) { if (!face.id) { await db.nitroFontFace.create({ data: { style: face.style, weight: face.weight, files: JSON.stringify(face.files), font: { connect: { id: font.id, }, }, }, }); } else { await db.nitroFontFace.update({ data: { files: JSON.stringify(face.files), }, where: { id: face.id, }, }); } } };