Files
XIP/scripts/dev-stack.ts
arussac 12afb71a67 feat: initialize project with Docker, PostgreSQL, Redis, and Vue.js frontend
- Added docker-compose.yml for PostgreSQL and Redis services with health checks.
- Created frontend directory with initial Vue.js setup including package.json, vite.config.ts, and TypeScript configuration.
- Implemented main application structure with App.vue and HomePage.vue components.
- Added message fetching and posting functionality in HomePage.vue.
- Included necessary styles and scripts for Ionic framework integration.
- Developed a dev-stack script to manage Docker containers and run backend/frontend servers.
2026-05-29 11:47:52 +02:00

89 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bun
import { spawn } from "bun";
import { resolve } from "path";
const ROOT = resolve(import.meta.dir, "..");
const BACKEND = resolve(ROOT, "backend");
const FRONTEND = resolve(ROOT, "frontend");
function run(cmd: string[], cwd = ROOT): Promise<void> {
console.log(`${cmd.join(" ")}`);
const proc = spawn(cmd, { cwd, stdout: "inherit", stderr: "inherit" });
return proc.exited.then((code) => {
if (code !== 0) throw new Error(`Command failed (exit ${code}): ${cmd.join(" ")}`);
});
}
async function waitForService(
label: string,
check: string[],
retries = 30,
delayMs = 2000
): Promise<void> {
for (let i = 1; i <= retries; i++) {
const proc = spawn(check, { cwd: ROOT, stdout: "pipe", stderr: "pipe" });
if ((await proc.exited) === 0) {
console.log(`${label} is ready`);
return;
}
console.log(`⏳ Waiting for ${label}... (${i}/${retries})`);
await Bun.sleep(delayMs);
}
throw new Error(`${label} did not become ready in time`);
}
async function main() {
console.log("\n🐳 Starting Docker containers...");
await run(["docker", "compose", "up", "-d"]);
console.log("\n⏳ Waiting for services...");
await waitForService("PostgreSQL", [
"docker", "compose", "exec", "postgres", "pg_isready", "-U", "xip",
]);
await waitForService("Redis", [
"docker", "compose", "exec", "redis", "redis-cli", "ping",
]);
console.log("\n🔧 Generating Prisma client...");
await run(["bunx", "prisma", "generate"], BACKEND);
console.log("\n🗄 Applying database migrations...");
await run(
["bunx", "prisma", "migrate", "dev", "--name", "init", "--skip-seed"],
BACKEND
);
console.log("\n🌱 Seeding database...");
await run(["bun", "run", "prisma/seed.ts"], BACKEND);
console.log("\n✅ Stack ready! Starting dev servers...\n");
console.log(" Backend → http://localhost:3000");
console.log(" Frontend → http://localhost:5173\n");
const backend = spawn(["bun", "run", "dev"], {
cwd: BACKEND,
stdout: "inherit",
stderr: "inherit",
});
const frontend = spawn(["bun", "run", "dev"], {
cwd: FRONTEND,
stdout: "inherit",
stderr: "inherit",
});
const cleanup = () => {
backend.kill();
frontend.kill();
process.exit(0);
};
process.on("SIGINT", cleanup);
process.on("SIGTERM", cleanup);
await Promise.all([backend.exited, frontend.exited]);
}
main().catch((err: Error) => {
console.error("\n❌ ", err.message);
process.exit(1);
});