import { spawn } from "node:child_process"; import { createLogger } from "../logger/logger.controller.js"; import { emitToRoom } from "../socket.io/roomEmitter.socket.js"; import { updateAppStats } from "./updateAppStats.utils.js"; import { zipBuild } from "./zipper.utils.js"; export const emitBuildLog = (message: string, level = "info") => { const payload = { type: "build", level, message, timestamp: new Date().toISOString(), }; //console.log(`[BUILD][${level.toUpperCase()}] ${message}`); emitToRoom("admin:build", payload as any); if (payload.level === "info") { log.info({ stack: payload }, payload.message); } // if (log) { // log(payload); // } }; export let building = false; const log = createLogger({ module: "utils", subModule: "builds" }); export const build = async () => { const appDir = process.env.DEV_DIR ?? ""; return new Promise((resolve) => { building = true; updateAppStats({ lastUpdated: new Date(), building: true, }); emitBuildLog(`Starting build in: ${appDir}`); const child = spawn("npm", ["run", "build"], { cwd: appDir, shell: true, }); child.stdout.on("data", (data) => { const lines = data.toString().split(/\r?\n/); for (const line of lines) { if (line.trim() !== "") { emitBuildLog(line, "info"); } } }); child.stderr.on("data", (data) => { const lines = data.toString().split(/\r?\n/); for (const line of lines) { if (line.trim() !== "") { emitBuildLog(line, "error"); } } }); child.on("close", (code) => { if (code === 0) { emitBuildLog("Build completed successfully.", "info"); building = false; zipBuild(); resolve(true); } else { building = false; updateAppStats({ lastUpdated: new Date(), building: false, }); emitBuildLog(`Build failed with code ${code}`, "error"); //reject(new Error(`Build failed with code ${code}`)); } }); child.on("error", (err) => { building = false; updateAppStats({ lastUpdated: new Date(), building: false, }); emitBuildLog(`Process error: ${err.message}`, "error"); // reject(err); }); }); };