#!/usr/bin/env node import { spawn, spawnSync } from "node:child_process"; import { existsSync, writeFileSync } from "node:fs"; import path from "node:path"; const cwd = process.cwd(); const pascalDir = path.resolve( cwd, process.env.PASCAL_EDITOR_DIR || "services/pascal-editor" ); const port = process.env.PASCAL_EDITOR_PORT || "3002"; function run(command, args, options = {}) { const result = spawnSync(command, args, { cwd, stdio: "inherit", ...options, }); if (result.status !== 0) { process.exit(result.status ?? 1); } } function commandExists(command) { const result = spawnSync(command, ["--version"], { stdio: "ignore" }); return result.status === 0; } function runPackageScript(packageManager, packageDir, scriptName) { if (packageManager === "bun") { run("bun", ["--cwd", packageDir, "run", scriptName], { cwd: pascalDir }); return; } run("npm", ["--prefix", packageDir, "run", scriptName], { cwd: pascalDir }); } function ensureBuiltWorkspacePackages(packageManager) { const requiredBuilds = [ ["packages/core", "dist/index.js"], ["packages/viewer", "dist/index.js"], ["packages/nodes", "dist/index.js"], ["packages/mcp", "dist/index.js"], ]; for (const [packageDir, distFile] of requiredBuilds) { if (existsSync(path.join(pascalDir, packageDir, distFile))) { continue; } runPackageScript(packageManager, packageDir, "build"); } } if (!existsSync(path.join(pascalDir, "apps/editor/package.json"))) { console.error( `Vendored Pascal Editor source was not found at ${pascalDir}. Set PASCAL_EDITOR_DIR to override it.` ); process.exit(1); } const envLocalPath = path.join(pascalDir, ".env.local"); if (!existsSync(envLocalPath)) { writeFileSync(envLocalPath, `PORT=${port}\n`, "utf8"); } const hasBun = commandExists("bun"); const hasNpm = commandExists("npm"); const hasNodeModules = existsSync(path.join(pascalDir, "node_modules")); if (!hasBun && !hasNpm) { console.error("Pascal Editor needs Bun or npm to install dependencies."); process.exit(1); } if (!hasNodeModules) { if (hasBun) { run("bun", ["install"], { cwd: pascalDir }); } else { run("npm", ["install"], { cwd: pascalDir }); } } const packageManager = hasBun ? "bun" : "npm"; ensureBuiltWorkspacePackages(packageManager); const command = hasBun ? "bun" : "npm"; const args = hasBun ? ["--cwd", "apps/editor", "run", "dev"] : ["--prefix", "apps/editor", "run", "dev"]; console.log(`Starting self-hosted Pascal Editor on http://localhost:${port}`); const child = spawn(command, args, { cwd: pascalDir, stdio: "inherit", env: { ...process.env, PORT: port, }, }); child.on("exit", (code, signal) => { if (signal) { process.kill(process.pid, signal); return; } process.exit(code ?? 0); });