Skip to content

Commit

Permalink
Merge pull request #4 from ezequielramos/main
Browse files Browse the repository at this point in the history
adding a beautiful cli
  • Loading branch information
ezequielramos authored Apr 22, 2024
2 parents 6a10fa0 + 65d81f2 commit 968a32d
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 52 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# Gina
# Gina

## Development

If you want to edit the cli and test it you can install it locally:

```bash
npm install -g .
```
88 changes: 57 additions & 31 deletions bin/index.js → bin/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
#! /usr/bin/env node
/* eslint-disable @typescript-eslint/no-var-requires */
#!/usr/bin/env ts-node

const yargs = require('yargs/yargs');
const { hideBin } = require('yargs/helpers');
const fs = require('fs/promises');
const moment = require('moment');
import yargs from 'yargs/yargs';
import { hideBin } from 'yargs/helpers';
import { readdir, mkdir, writeFile } from 'fs/promises';
import moment from 'moment';

async function createInitialFolder() {
const files = await fs.readdir('.');
const files = await readdir('.');
if (files.includes('gina')) {
console.info('There\'s already a folder/file named gina on your folder indicating that gina is already initialized.');
return;
}



await fs.mkdir('gina');
await fs.mkdir('gina/migrations');
await fs.writeFile(`gina/migrations/${moment().format('YYYYMMDDHHmmss') + '-add-version-control-table.ts'}`, `import { QueryInterface, DataTypes } from 'sequelize';
await mkdir('gina');
await mkdir('gina/migrations');
await writeFile(`gina/migrations/${moment().format('YYYYMMDDHHmmss') + '-add-version-control-table.ts'}`, `import { QueryInterface, DataTypes } from 'sequelize';
export const migration = {
async up(queryInterface: QueryInterface) {
Expand Down Expand Up @@ -55,7 +52,7 @@ export const migration = {
};
`);

await fs.writeFile('gina/initializeModels.ts', `import dotenv from 'dotenv';
await writeFile('gina/initializeModels.ts', `import dotenv from 'dotenv';
dotenv.config();
import { Sequelize, Transaction } from 'sequelize';
Expand Down Expand Up @@ -107,37 +104,66 @@ async function initializeModels() {
export { initializeModels };
`);

await fs.writeFile('gina/upgrade.ts', `
import { initializeModels } from './initializeModels';
import gina from 'gina-sequelize';
}

(async () => {
async function generateMigration(migrationName: string) {
try {
const sequelize = await initializeModels();
await gina.runMigrations(sequelize);
const pathName = process.cwd();
const initFile = await import(pathName + '/gina/initializeModels.ts');

console.log('loading models...');
const sequelize = await initFile.initializeModels();

console.log('loading gina lib...');
try {
const ginaLib = await import(pathName + '/node_modules/gina-sequelize/dist/gina.js');
await ginaLib.default.createMigration(sequelize, migrationName);
} catch (err) {
const ginaLib = await import(pathName + '/lib/gina.ts');
await ginaLib.default.createMigration(sequelize, migrationName);
}

process.exit();
} catch (err) {
console.error(err);
process.exit(1);
}
})();
`);

await fs.writeFile('gina/generate-migration.ts', `
import { initializeModels } from './initializeModels';
import gina from 'gina-sequelize';
}

(async () => {
async function upgrade() {
try {
const sequelize = await initializeModels();
await gina.createMigration(sequelize);
const pathName = process.cwd();
const initFile = await import(pathName + '/gina/initializeModels.ts');

console.log('loading models...');
const sequelize = await initFile.initializeModels();

console.log('loading migrations...');
const files = (await readdir(pathName + '/gina/migrations')).filter(file => !file.includes('.d.ts') && !file.includes('.js.map'));

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const migrations: { [file: string]: any; } = {};

for (const file of files) {
const filePath = await import(pathName + '/gina/migrations/' + file);
migrations[file.replace('.ts', '')] = filePath;
}

console.log('loading gina lib...');
try {
const ginaLib = await import(pathName + '/node_modules/gina-sequelize/dist/gina.js');
await ginaLib.default.runMigrations(sequelize, migrations);
} catch (err) {
const ginaLib = await import(pathName + '/lib/gina.ts');
await ginaLib.default.runMigrations(sequelize, migrations);
}

process.exit();
} catch (err) {
console.error(err);
process.exit(1);
}
})();
`);

}

Expand All @@ -151,9 +177,9 @@ yargs(hideBin(process.argv))
describe: 'Name of the migration to be added'
});
}, (argv) => {
console.info(`start server on :${argv['migration-name']}`);
generateMigration(argv['migration-name'] as string);
})
.command('upgrade', 'upgrade database to its last revision', () => {
console.log('upgrade');
upgrade();
})
.parse();
34 changes: 15 additions & 19 deletions lib/gina.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { DataTypes, ModelCtor, Model, Sequelize, ModelAttributeColumnOptions, QueryTypes } from 'sequelize';
import fs from 'fs/promises';
import moment from 'moment';
import path from 'path';
import { MigrationFile } from './typings/migration';

async function runMigrations(sequelize: Sequelize) {
const migrationsDir = './gina/migrations';
const files = (await fs.readdir(migrationsDir)).filter(file => !file.includes('.d.ts') && !file.includes('.js.map'));
interface MigrationFiles {
[version: string]: { migration: MigrationFile; };
}

async function runMigrations(sequelize: Sequelize, migrationFiles: MigrationFiles) {
const tables = await sequelize.getQueryInterface().showAllTables();

let version = '';
Expand All @@ -24,24 +24,20 @@ async function runMigrations(sequelize: Sequelize) {
version = versions.length == 1 ? versions[0].version : '';
}


console.info('current version:', version);

for (const file of files) {
const escapedFile = file.replace('.js', '').replace('.ts', '');
if (escapedFile > version) {
const filePath = path.join(migrationsDir, file);
const model: { migration: MigrationFile; } = await import(filePath.replace('.js', ''));
console.info('applying migration:', escapedFile);
await model.migration.up(sequelize.getQueryInterface());
for (const migrationFile of Object.keys(migrationFiles)) {
if (migrationFile > version) {
console.info('applying migration:', migrationFile);
await migrationFiles[migrationFile].migration.up(sequelize.getQueryInterface());
if (version) {
version = escapedFile;
version = migrationFile;
await sequelize.query(`UPDATE gina_version SET version = '${version}', updatedAt = NOW();`);
} else {
version = escapedFile;
version = migrationFile;
await sequelize.query(`INSERT INTO gina_version (updatedAt, version) VALUES (NOW(),'${version}');`);
}
console.info('applied version:', escapedFile);
console.info('applied version:', migrationFile);
}
}
}
Expand Down Expand Up @@ -280,7 +276,7 @@ class Migration {
}
}

async generateFile() {
async generateFile(migrationName: string) {
const migration = `import { ${this.imports.join(', ')} } from 'sequelize';
export const migration = {
Expand All @@ -295,11 +291,11 @@ ${this.downTables}
}
};`;

await fs.writeFile('./gina/migrations/' + moment().format('YYYYMMDDHHmmss') + '.ts', migration);
await fs.writeFile(`./gina/migrations/${moment().format('YYYYMMDDHHmmss')}-${migrationName.toLowerCase().replaceAll(' ', '-')}.ts`, migration);
}
}

async function createMigration(sequelize: Sequelize) {
async function createMigration(sequelize: Sequelize, migrationName: string) {

const migration = new Migration(sequelize);
await migration.loadDatabaseTables();
Expand All @@ -310,7 +306,7 @@ async function createMigration(sequelize: Sequelize) {
console.info('There\'s no changes between your models and the database.');
return;
}
await migration.generateFile();
await migration.generateFile(migrationName);

}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "gina-sequelize",
"main": "./dist/gina.js",
"bin": {
"gina-cli": "./bin/index.js"
"gina-cli": "./bin/index.ts"
},
"types": "./dist/gina.d.ts",
"version": "0.0.9",
Expand Down

0 comments on commit 968a32d

Please sign in to comment.