UNPKG

@bodheesh/create-bodhi-node-app

Version:

Create a production-ready Node.js REST API with zero configuration

115 lines (97 loc) 3.43 kB
import { Umzug, SequelizeStorage } from 'umzug'; import { Sequelize } from 'sequelize'; import fs from 'fs'; import path from 'path'; export const generateMigrations = async (schema: any, outputDir: string, dbConfig: any) => { const migrationDir = path.join(outputDir, 'migrations'); if (!fs.existsSync(migrationDir)) { fs.mkdirSync(migrationDir, { recursive: true }); } const timestamp = new Date().toISOString().replace(/[^0-9]/g, '').slice(0, -3); const migrationPath = path.join(migrationDir, `${timestamp}-create-tables.js`); const migrationContent = generateMigrationContent(schema); fs.writeFileSync(migrationPath, migrationContent); // Generate sequelize configuration const configPath = path.join(outputDir, 'config'); if (!fs.existsSync(configPath)) { fs.mkdirSync(configPath, { recursive: true }); } const dbConfigContent = generateDBConfig(dbConfig); fs.writeFileSync(path.join(configPath, 'database.js'), dbConfigContent); }; const generateMigrationContent = (schema: any) => { let upQueries = []; let downQueries = []; for (const [modelName, properties] of Object.entries(schema)) { const tableName = modelName.toLowerCase() + 's'; const columns = Object.entries(properties).map(([field, rules]: [string, any]) => { return generateColumnDefinition(field, rules); }).join(',\n '); upQueries.push(` await queryInterface.createTable('${tableName}', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, ${columns}, createdAt: { type: Sequelize.DATE, allowNull: false }, updatedAt: { type: Sequelize.DATE, allowNull: false } });`); downQueries.push(`await queryInterface.dropTable('${tableName}');`); } return `'use strict'; module.exports = { up: async (queryInterface, Sequelize) => { ${upQueries.join('\n')} }, down: async (queryInterface, Sequelize) => { ${downQueries.join('\n')} } };`; }; const generateColumnDefinition = (field: string, rules: any) => { const type = rules.type === 'string' ? 'STRING' : rules.type === 'number' ? 'INTEGER' : rules.type === 'boolean' ? 'BOOLEAN' : rules.type === 'date' ? 'DATE' : 'STRING'; return `${field}: { type: Sequelize.${type}, allowNull: ${!rules.required}, ${rules.unique ? 'unique: true,' : ''} ${rules.defaultValue ? `defaultValue: ${JSON.stringify(rules.defaultValue)},` : ''} }`; }; const generateDBConfig = (config: any) => { return `module.exports = { development: { username: process.env.DB_USERNAME || '${config.username}', password: process.env.DB_PASSWORD || '${config.password}', database: process.env.DB_NAME || '${config.database}', host: process.env.DB_HOST || '${config.host}', dialect: '${config.dialect}', logging: false }, test: { username: process.env.TEST_DB_USERNAME, password: process.env.TEST_DB_PASSWORD, database: process.env.TEST_DB_NAME, host: process.env.TEST_DB_HOST, dialect: '${config.dialect}', logging: false }, production: { username: process.env.PROD_DB_USERNAME, password: process.env.PROD_DB_PASSWORD, database: process.env.PROD_DB_NAME, host: process.env.PROD_DB_HOST, dialect: '${config.dialect}', logging: false } };`;