109 lines
2.6 KiB
TypeScript
109 lines
2.6 KiB
TypeScript
import chokidar from 'chokidar';
|
|
import { exec } from 'node:child_process';
|
|
import type { ExecException } from 'node:child_process';
|
|
import nodemon from 'nodemon';
|
|
|
|
import { logger } from './src/utils/logger.ts';
|
|
|
|
const nodeEnv = process.env.NODE_ENV || 'dev_stage';
|
|
const childEnv = buildChildEnv(process.env, nodeEnv);
|
|
const log = logger.child({ module: 'watcher' });
|
|
|
|
function buildChildEnv(
|
|
env: NodeJS.ProcessEnv,
|
|
fallbackNodeEnv: string,
|
|
): Record<string, string> {
|
|
const child: Record<string, string> = {};
|
|
|
|
for (const [key, value] of Object.entries(env)) {
|
|
if (value !== undefined) {
|
|
child[key] = value;
|
|
}
|
|
}
|
|
|
|
child.NODE_ENV = fallbackNodeEnv;
|
|
return child;
|
|
}
|
|
|
|
function logCommandResult(
|
|
error: ExecException | null,
|
|
stdout: string,
|
|
stderr: string,
|
|
successMessage: string,
|
|
): void {
|
|
const output = stdout.trim();
|
|
const errorOutput = stderr.trim();
|
|
|
|
if (output) {
|
|
log.info({ output }, successMessage);
|
|
}
|
|
|
|
if (error) {
|
|
log.error(
|
|
{ err: error, stderr: errorOutput },
|
|
'Watched database command failed',
|
|
);
|
|
} else if (errorOutput) {
|
|
log.warn({ stderr: errorOutput }, 'Watched database command wrote stderr');
|
|
}
|
|
}
|
|
|
|
const migrationsWatcher = chokidar.watch('./src/db/migrations', {
|
|
persistent: true,
|
|
ignoreInitial: true,
|
|
usePolling: true,
|
|
interval: 1000,
|
|
});
|
|
migrationsWatcher.on('error', (error) => {
|
|
log.error({ err: error }, 'Migrations watcher failed');
|
|
});
|
|
migrationsWatcher.on('add', (filePath) => {
|
|
log.info({ filePath }, 'New migration file detected');
|
|
exec('npm run db:migrate', { env: childEnv }, (error, stdout, stderr) => {
|
|
logCommandResult(error, stdout, stderr, 'Migration command completed');
|
|
});
|
|
});
|
|
|
|
const seedersWatcher = chokidar.watch('./src/db/seeders', {
|
|
persistent: true,
|
|
ignoreInitial: true,
|
|
usePolling: true,
|
|
interval: 1000,
|
|
});
|
|
seedersWatcher.on('error', (error) => {
|
|
log.error({ err: error }, 'Seeders watcher failed');
|
|
});
|
|
seedersWatcher.on('add', (filePath) => {
|
|
log.info({ filePath }, 'New seed file detected');
|
|
exec('npm run db:seed', { env: childEnv }, (error, stdout, stderr) => {
|
|
logCommandResult(error, stdout, stderr, 'Seeder command completed');
|
|
});
|
|
});
|
|
|
|
nodemon({
|
|
script: './src/index.ts',
|
|
exec: 'node',
|
|
env: childEnv,
|
|
watch: ['./src'],
|
|
ext: 'js,ts,json',
|
|
ignore: [
|
|
'./src/db/migrations',
|
|
'./src/db/seeders',
|
|
'./dist',
|
|
'./node_modules',
|
|
],
|
|
delay: 500,
|
|
});
|
|
|
|
nodemon.on('start', () => {
|
|
log.info({ nodeEnv }, 'Nodemon started');
|
|
});
|
|
|
|
nodemon.on('restart', (files) => {
|
|
log.info({ files }, 'Nodemon restarted due to file changes');
|
|
});
|
|
|
|
nodemon.on('crash', () => {
|
|
log.error('Nodemon app crashed');
|
|
});
|