veza/apps/web/scripts/validate-storybook.cjs

100 lines
2.4 KiB
JavaScript

#!/usr/bin/env node
/**
* validate-storybook: build Storybook, serve on 6007, run audit, then stop server.
* Single command for CI/local: npm run validate:storybook
*/
const { spawn, execSync } = require('child_process');
const http = require('http');
const path = require('path');
const PORT = 6007;
const INDEX_URL = `http://localhost:${PORT}/index.json`;
const POLL_MS = 500;
const POLL_TIMEOUT_MS = 60000;
function waitForUrl(url, timeoutMs) {
const start = Date.now();
return new Promise((resolve, reject) => {
const tryOnce = () => {
const req = http.get(url, (res) => {
if (res.statusCode === 200) {
resolve();
return;
}
res.resume();
schedule();
});
req.on('error', () => schedule());
req.setTimeout(5000, () => {
req.destroy();
schedule();
});
};
const schedule = () => {
if (Date.now() - start > timeoutMs) {
reject(new Error(`Timeout waiting for ${url}`));
return;
}
setTimeout(tryOnce, POLL_MS);
};
tryOnce();
});
}
function runBuild() {
console.log('[validate-storybook] Running build-storybook...');
execSync('npm run build-storybook', {
stdio: 'inherit',
cwd: path.resolve(__dirname, '..'),
});
}
function main() {
const cwd = path.resolve(__dirname, '..');
runBuild();
const serve = spawn('npx', ['serve', 'storybook-static', '-l', String(PORT)], {
stdio: 'pipe',
shell: true,
cwd,
});
let auditExitCode = 1;
serve.on('error', (err) => {
console.error('[validate-storybook] Failed to start serve:', err);
process.exit(1);
});
waitForUrl(INDEX_URL, POLL_TIMEOUT_MS)
.then(() => {
console.log('[validate-storybook] Server ready, running audit...');
const audit = spawn('node', ['scripts/audit-storybook.js'], {
stdio: 'inherit',
shell: true,
cwd,
});
return new Promise((res) => {
audit.on('exit', (code) => {
auditExitCode = code ?? 1;
res();
});
});
})
.catch((err) => {
console.error('[validate-storybook]', err.message);
auditExitCode = 1;
})
.finally(() => {
serve.kill('SIGTERM');
serve.on('exit', () => {
process.exit(auditExitCode);
});
setTimeout(() => {
serve.kill('SIGKILL');
process.exit(auditExitCode);
}, 5000);
});
}
main();