mirror of
https://github.com/vega-org/vega-providers.git
synced 2026-04-17 15:41:45 +00:00
216 lines
5.6 KiB
JavaScript
216 lines
5.6 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
const { spawn } = require("child_process");
|
||
const path = require("path");
|
||
const fs = require("fs");
|
||
|
||
// Colors for console output
|
||
const colors = {
|
||
reset: "\x1b[0m",
|
||
bright: "\x1b[1m",
|
||
green: "\x1b[32m",
|
||
red: "\x1b[31m",
|
||
yellow: "\x1b[33m",
|
||
blue: "\x1b[34m",
|
||
magenta: "\x1b[35m",
|
||
cyan: "\x1b[36m",
|
||
};
|
||
|
||
const log = {
|
||
info: (msg) => console.log(`${colors.blue}ℹ${colors.reset} ${msg}`),
|
||
success: (msg) => console.log(`${colors.green}✅${colors.reset} ${msg}`),
|
||
error: (msg) => console.log(`${colors.red}❌${colors.reset} ${msg}`),
|
||
warning: (msg) => console.log(`${colors.yellow}⚠️${colors.reset} ${msg}`),
|
||
server: (msg) => console.log(`${colors.cyan}🌐${colors.reset} ${msg}`),
|
||
watch: (msg) => console.log(`${colors.magenta}👀${colors.reset} ${msg}`),
|
||
};
|
||
|
||
class AutoDev {
|
||
constructor() {
|
||
this.processes = new Map();
|
||
this.isShuttingDown = false;
|
||
}
|
||
|
||
async checkDependencies() {
|
||
log.info("Checking dependencies...");
|
||
|
||
const requiredPackages = ["nodemon", "concurrently", "express", "cors"];
|
||
const packageJson = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
||
|
||
const missing = requiredPackages.filter(
|
||
(pkg) =>
|
||
!packageJson.dependencies?.[pkg] && !packageJson.devDependencies?.[pkg]
|
||
);
|
||
|
||
if (missing.length > 0) {
|
||
log.error(`Missing packages: ${missing.join(", ")}`);
|
||
log.info("Installing missing packages...");
|
||
await this.runCommand("npm", ["install", ...missing, "--save-dev"]);
|
||
}
|
||
|
||
log.success("All dependencies are installed");
|
||
}
|
||
|
||
async runCommand(command, args, options = {}) {
|
||
return new Promise((resolve, reject) => {
|
||
const child = spawn(command, args, {
|
||
stdio: "inherit",
|
||
shell: true,
|
||
...options,
|
||
});
|
||
|
||
child.on("close", (code) => {
|
||
if (code === 0) {
|
||
resolve();
|
||
} else {
|
||
reject(new Error(`Command failed with code ${code}`));
|
||
}
|
||
});
|
||
|
||
child.on("error", reject);
|
||
});
|
||
}
|
||
async initialBuild() {
|
||
log.info("Running initial build...");
|
||
try {
|
||
await this.runCommand("node", ["build-simple.js"]);
|
||
log.success("Initial build completed");
|
||
} catch (error) {
|
||
log.error("Initial build failed:", error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
startWatcher() {
|
||
log.watch("Starting file watcher...");
|
||
|
||
const watcher = spawn("npx", ["nodemon"], {
|
||
stdio: ["inherit", "pipe", "pipe"],
|
||
shell: true,
|
||
env: { ...process.env, NODE_ENV: "development" },
|
||
});
|
||
|
||
watcher.stdout.on("data", (data) => {
|
||
const output = data.toString().trim();
|
||
if (output) {
|
||
console.log(`${colors.magenta}[WATCH]${colors.reset} ${output}`);
|
||
}
|
||
});
|
||
|
||
watcher.stderr.on("data", (data) => {
|
||
const output = data.toString().trim();
|
||
if (output) {
|
||
console.log(`${colors.yellow}[WATCH]${colors.reset} ${output}`);
|
||
}
|
||
});
|
||
|
||
watcher.on("close", (code) => {
|
||
if (!this.isShuttingDown) {
|
||
log.error(`Watcher exited with code ${code}`);
|
||
}
|
||
});
|
||
|
||
this.processes.set("watcher", watcher);
|
||
return watcher;
|
||
}
|
||
|
||
startDevServer() {
|
||
log.server("Starting development server...");
|
||
|
||
const server = spawn("node", ["dev-server.js"], {
|
||
stdio: ["inherit", "pipe", "pipe"],
|
||
shell: true,
|
||
});
|
||
|
||
server.stdout.on("data", (data) => {
|
||
const output = data.toString().trim();
|
||
if (output) {
|
||
console.log(`${colors.cyan}[SERVER]${colors.reset} ${output}`);
|
||
}
|
||
});
|
||
|
||
server.stderr.on("data", (data) => {
|
||
const output = data.toString().trim();
|
||
if (output) {
|
||
console.log(`${colors.red}[SERVER]${colors.reset} ${output}`);
|
||
}
|
||
});
|
||
|
||
server.on("close", (code) => {
|
||
if (!this.isShuttingDown) {
|
||
log.error(`Server exited with code ${code}`);
|
||
}
|
||
});
|
||
|
||
this.processes.set("server", server);
|
||
return server;
|
||
}
|
||
|
||
setupSignalHandlers() {
|
||
const cleanup = () => {
|
||
if (this.isShuttingDown) return;
|
||
this.isShuttingDown = true;
|
||
|
||
console.log("\n");
|
||
log.info("Shutting down auto-dev environment...");
|
||
|
||
for (const [name, process] of this.processes) {
|
||
log.info(`Stopping ${name}...`);
|
||
process.kill("SIGTERM");
|
||
}
|
||
|
||
setTimeout(() => {
|
||
log.success("Auto-dev environment stopped");
|
||
process.exit(0);
|
||
}, 1000);
|
||
};
|
||
|
||
process.on("SIGINT", cleanup);
|
||
process.on("SIGTERM", cleanup);
|
||
}
|
||
|
||
async start() {
|
||
console.log(`
|
||
${colors.bright}🚀 Vega Providers Auto-Development Environment${colors.reset}
|
||
|
||
|
||
${colors.yellow}Press Ctrl+C to stop${colors.reset}
|
||
`);
|
||
|
||
try {
|
||
// Setup signal handlers
|
||
this.setupSignalHandlers();
|
||
|
||
// Check dependencies
|
||
await this.checkDependencies();
|
||
|
||
// Initial build
|
||
await this.initialBuild();
|
||
|
||
// Start watcher and server
|
||
this.startWatcher();
|
||
|
||
// Wait a bit before starting server
|
||
setTimeout(() => {
|
||
this.startDevServer();
|
||
}, 2000);
|
||
|
||
log.success("Auto-development environment is running!");
|
||
log.info(
|
||
"Make changes to your providers and watch them rebuild automatically"
|
||
);
|
||
} catch (error) {
|
||
log.error("Failed to start auto-dev environment:", error.message);
|
||
process.exit(1);
|
||
}
|
||
}
|
||
}
|
||
|
||
// CLI interface
|
||
if (require.main === module) {
|
||
const autoDev = new AutoDev();
|
||
autoDev.start();
|
||
}
|
||
|
||
module.exports = AutoDev;
|