#!/usr/bin/env ts-node import { exec } from 'child_process'; import fs from 'fs'; import path from 'path'; import { config as setupEnv } from 'dotenv-flow'; import yargs from 'yargs'; import logger from '@/logger'; import connect from '../src/config/db'; setupEnv(); const scriptName = 'Regenerate last migration'; const args = yargs(process.argv.slice(2)) .options({ n: { type: 'string', alias: 'name', demand: true, description: 'The name of the migration', }, }) .parse(); const main = async () => { const { n: name } = args; const isDevelopmentLike = ['development', 'dev'].includes( process.env.NODE_ENV ?? '' ); if (!isDevelopmentLike) { throw new Error('Cannot regenerate last migration in non-dev environment.'); } // @TODO: probably want to check for the connection host isn't foreign (e.g. // localhost and docker are ok) const db = await connect(); // down the last migration logger.info(`Reverting last migration...`); await db.undoLastMigration(); const migrationDir = path.join(__dirname, '../src/migration'); const migrationFileNames = await fs.promises.readdir(migrationDir); const lastMigration = migrationFileNames.find((fn) => fn.startsWith( migrationFileNames .map((fn) => { const parts = fn.split('-'); const timeStamp = parts[0]; return parseInt(timeStamp); }) .sort((a, b) => { return b - a; })[0] .toString() ) ); if (!lastMigration) { logger.error(`Failed to find last migration`); return; } logger.info(`Removing build and source files...`); // remove source file await fs.promises.rm(path.join(migrationDir, `${lastMigration}`)); // remove dist file await fs.promises.rm( path.join( __dirname, '../dist/migration', `${lastMigration.replace('.ts', '.js')}` ) ); await new Promise((resolve, reject) => { exec(`yarn migration:generate -n ${name}`, (error, stdout, stderr) => { if (error) { reject(error); logger.error(stderr); return; } logger.info(stdout); resolve(); }); }); // NOTE: have to close the connection since seed script opens it's own // connection. await db.close(); }; console.time(scriptName); main() .then(() => { console.timeEnd(scriptName); }) .catch((error) => { logger.error(error); process.exit(1); });