canina/scripts/start-dev.js
parsa aghaei cd17a532d9 fix: resolve backend TS compilation errors, startup order, and add clipboard paste upload
- Fix products.service.ts: ingredients -> ingredientList (Prisma relation name)
- Fix seed-blogs.ts: template literal refactor (array join) to avoid esbuild parse error
- Fix seed-custom.ts: category string -> connectOrCreate relation
- Add start-dev.js: sequential startup (backend first, then frontends)
- Add Ctrl+V paste upload to admin MediaSelector component
- Create missing images/vets/ and images/slider/ directories
2026-07-11 13:51:12 +03:30

44 lines
1.3 KiB
JavaScript

const { spawn } = require('child_process');
const http = require('http');
const BACKEND_PORT = 4001;
const MAX_WAIT = 60000;
function waitForBackend(port, timeout) {
return new Promise((resolve, reject) => {
const start = Date.now();
function check() {
const req = http.get(`http://127.0.0.1:${port}/api/docs`, (res) => {
resolve();
});
req.on('error', () => {
if (Date.now() - start > timeout) {
reject(new Error(`Backend did not start within ${timeout/1000}s`));
} else {
setTimeout(check, 1000);
}
});
req.setTimeout(3000, () => { req.destroy(); });
}
setTimeout(check, 3000);
});
}
const backend = spawn('npm', ['run', 'dev:backend'], { stdio: 'inherit', shell: true });
waitForBackend(BACKEND_PORT, MAX_WAIT).then(() => {
const store = spawn('npm', ['run', 'dev:frontend'], { stdio: 'inherit', shell: true });
const admin = spawn('npm', ['run', 'dev:admin'], { stdio: 'inherit', shell: true });
const openBrowsers = spawn('node', ['scripts/open-browsers.js'], { stdio: 'inherit', shell: true });
process.on('SIGINT', () => {
backend.kill(); store.kill(); admin.kill(); openBrowsers.kill();
process.exit();
});
}).catch((err) => {
console.error(err.message);
backend.kill();
process.exit(1);
});