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 { const child: Record = {}; 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'); });