Files
EpicNext-Cms/src/lib/services/furni-attachment.ts
T
Simo 13bd3695cb
CI / check (push) Successful in 2m5s
CI / deploy (push) Successful in 1m8s
CI / publish-container (push) Successful in 1m4s
feat(studio): recover matching Nitro sources and persist import phases
2026-09-11 10:22:06 +02:00

59 lines
1.8 KiB
TypeScript

import { randomUUID } from "node:crypto";
import { promises as fs } from "node:fs";
import path from "node:path";
import { parseNitroBundle } from "@/lib/services/swf/nitro-builder";
import { importRoot, validJobId } from "./furni-job-store";
export function validateFurnitureAttachment(buffer: Buffer, classname: string) {
if (buffer.length > 50 * 1024 * 1024)
throw Error("Maximum file size is 50 MB");
const parsed = parseNitroBundle(buffer, {
maxOutputLength: 50 * 1024 * 1024,
});
const base = classname.split("*")[0];
if (
parsed.jsonFileName !== `${base}.json` ||
(parsed.json.name && parsed.json.name !== base)
)
throw Error(`This bundle does not belong to ${classname}`);
if (
!parsed.png
.subarray(0, 8)
.equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))
)
throw Error("The bundle texture is not a PNG");
return buffer;
}
export async function stageFurnitureAttachment(
buffer: Buffer,
classname: string,
userId: number,
) {
validateFurnitureAttachment(buffer, classname);
const id = randomUUID(),
root = path.join(importRoot(), "attachments");
await fs.mkdir(root, { recursive: true });
await fs.writeFile(path.join(root, `${id}.nitro`), buffer);
await fs.writeFile(
path.join(root, `${id}.json`),
JSON.stringify({ classname, userId }),
);
return id;
}
export async function readFurnitureAttachment(
id: string,
classname: string,
userId: number,
) {
if (!validJobId(id)) throw Error("Invalid attachment");
const root = path.join(importRoot(), "attachments");
const meta = JSON.parse(
await fs.readFile(path.join(root, `${id}.json`), "utf8"),
);
if (meta.userId !== userId || meta.classname !== classname)
throw Error("Attachment does not belong to this furniture import");
return validateFurnitureAttachment(
await fs.readFile(path.join(root, `${id}.nitro`)),
classname,
);
}