Files
Aislo/resources/tester/print_frame/print_quantity_seam.mjs
T

111 lines
3.3 KiB
JavaScript

// 302-1 수량산출 이음매 — 영역 모으기 → 인쇄 페이지 서버 몸(pdfBody · xlsxBody) 을 node 로.
// node print_quantity_seam.mjs <저장소 뿌리>
// 표준입력 = { project, responses: {"/quantity/…": 응답}, image_b64 } (302-3 시험 자료 꼴)
// 표준출력 끝 줄 = { pdf: {title, sheets}, xlsx: {title, sheets} }
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { pathToFileURL } from "node:url";
const root = path.resolve(process.argv[2] ?? ".");
const { build } = await import(
pathToFileURL(path.join(root, "config/node_modules/vite/dist/node/index.js")).href
);
const input = JSON.parse(fs.readFileSync(0, "utf-8"));
// 화면 · 세션만 흉내 — 이 길은 DOM 을 안 그림
class Node {
constructor() {
this.children = [];
this.classList = { toggle() {}, add() {}, remove() {}, contains: () => false };
this.style = {};
this.dataset = {};
}
append(...kids) {
this.children.push(...kids);
}
appendChild(kid) {
this.children.push(kid);
return kid;
}
addEventListener() {}
setAttribute() {}
}
const session = new Map();
const storage = {
getItem: (k) => (session.has(k) ? session.get(k) : null),
setItem: (k, v) => session.set(k, String(v)),
removeItem: (k) => session.delete(k),
};
globalThis.document = {
createElement: () => new Node(),
createElementNS: () => new Node(),
createTextNode: () => new Node(),
head: new Node(),
body: new Node(),
addEventListener() {},
documentElement: new Node(),
};
globalThis.window = {
sessionStorage: storage,
localStorage: storage,
location: { origin: "http://localhost", hash: "" },
addEventListener() {},
setTimeout: (...a) => setTimeout(...a),
clearTimeout: (id) => clearTimeout(id),
};
globalThis.sessionStorage = storage;
globalThis.localStorage = storage;
const png = Buffer.from(input.image_b64, "base64");
globalThis.fetch = async (url) => {
const at = String(url)
.replace(/^.*\/projects\/[^/]+/, "")
.split("?")[0];
if (at === "/quantity/milestone/image")
return new Response(png, { status: 200, headers: { "Content-Type": "image/png" } });
const body = input.responses[at];
return body
? new Response(JSON.stringify(body), {
status: 200,
headers: { "Content-Type": "application/json" },
})
: new Response(JSON.stringify({ detail: `없음 ${at}` }), { status: 404 });
};
const outDir = fs.mkdtempSync(path.join(os.tmpdir(), "aislo-302-1-"));
try {
await build({
configFile: false,
logLevel: "silent",
root,
resolve: {
alias: {
"@ui": path.join(root, "ui_template"),
"@config": path.join(root, "config"),
"@util": path.join(root, "common_util"),
},
},
build: {
outDir,
minify: false,
target: "es2022",
lib: {
entry: path.join(root, "resources/tester/print_frame/print_quantity_entry.ts"),
formats: ["es"],
fileName: "entry",
},
},
});
const mod = await import(pathToFileURL(path.join(outDir, "entry.js")).href);
const sheets = await mod.collectQuantitySheets(input.project);
console.log(
JSON.stringify({
pdf: mod.pdfBody("수량산출", sheets),
xlsx: mod.xlsxBody("수량산출", sheets),
}),
);
} finally {
fs.rmSync(outDir, { recursive: true, force: true });
}