UNPKG

@shagital/adonisjs-crud-generator

Version:

Adonisjs Admin Panel Generator is a package that helps you quickly scaffold your typical CRUD admin interfaces. It generates the admin panel code based on the existing (migrated) table in the database

202 lines (201 loc) 9.6 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const standalone_1 = require("@adonisjs/core/build/standalone"); const helpers_1 = require("../common/helpers"); const fs_1 = __importDefault(require("fs")); const pluralize_1 = __importDefault(require("pluralize")); class ModelGenerator extends standalone_1.BaseCommand { async run() { const dbInstance = this.application.container.use('Adonis/Lucid/Database'); if (this.connection) { (0, helpers_1.validateConnection)(dbInstance, this.application.config, this.connection); } const tableColumns = (0, helpers_1.getTableColumnsAndTypes)(dbInstance, this.application.config); let tableName = this.table.toLowerCase(); let columnTypes = await tableColumns(tableName, this.connection); let singular = pluralize_1.default.singular(tableName); let modelFile = `${__dirname}/../templates/model.txt`; let pascalName = (0, helpers_1.pascalCase)(singular); let data = String(fs_1.default.readFileSync(modelFile)); data = await this.generateString(data, { columnTypes, tableName, pascalName }); fs_1.default.writeFileSync(`${this.application.appRoot}/app/Models/${pascalName}.ts`, data); process.exit(); } isDateTime(type) { return ['timestamp', 'datetime', 'date'].includes(type); } isDate(type) { return type === 'date'; } async generateString(data, { columnTypes, tableName, pascalName }) { this.logger.info('Generate model data'); let columnDefinitions = ''; let primary; let relationships = ''; let varImport = ''; let updateHook = ''; let createHook = ''; let relationshipArray = []; let imported = {}; let methods = ''; let otherImports = ''; Object.keys(columnTypes).forEach((columnName) => { let column = columnTypes[columnName]; if (this.isDateTime(column.type)) { if (!imported['datetime']) { varImport += `\nimport { DateTime } from 'luxon' import moment from 'moment'`; methods += ` private static formatDateTime(datetime) { let value = new Date(datetime) return datetime ? value.getFullYear() + "-" + (value.getMonth() + 1) + "-" + value.getDate() + " " + value.getHours() + ":" + value.getMinutes() + ":" + value.getSeconds() : datetime }`; imported['datetime'] = true; } if (this.isDate(column.type) && !imported['date']) { methods += ` private static formatDate(datetime) { let value = new Date(datetime) return datetime ? value.getFullYear() + "-" + (value.getMonth() + 1) + "-" + value.getDate() : datetime }`; imported['date'] = true; } if (!imported[columnName]) { updateHook += `${['datetime', 'timestamp'].includes(column.type) ? `\nif (_modelInstance.$dirty.${columnName}) { _modelInstance.${columnName} = this.formatDateTime(_modelInstance.${columnName}) }` : ''}`; createHook += `${['datetime', 'timestamp'].includes(column.type) ? `\nif (_modelInstance.$dirty.${columnName}) { _modelInstance.${columnName} = this.formatDateTime(_modelInstance.${columnName}) }` : ''}`; createHook += `${column.type === 'date' ? `\nif (_modelInstance.$dirty.${columnName}) { _modelInstance.${columnName} = this.formatDate(_modelInstance.${columnName}) }` : ''}`; } imported[columnName] = true; } if (column.original_type === 'json') { createHook += `${column.original_type === 'json' ? `\nif (_modelInstance.$dirty.${columnName}) { _modelInstance.${columnName} = JSON.stringify(_modelInstance.${columnName} || {}) }` : ''}`; updateHook += `${column.original_type === 'json' ? `\nif (_modelInstance.$dirty.${columnName}) { _modelInstance.${columnName} = JSON.stringify(_modelInstance.${columnName} || {}) }` : ''}`; } columnDefinitions += ` @column${column.type === 'date' ? '.date' : ''}({`; columnDefinitions += `${column.primary ? ` isPrimary: true,` : ''}`; columnDefinitions += `${columnName === 'password' ? 'serializeAs: null,' : ''}`; columnDefinitions += ` ${['timestamp', 'datetime'].includes(column.type) ? ` serialize: (value: DateTime | null) => { return value ? moment(value).format('lll') : value }` : ''}`; columnDefinitions += ` ${this.isDate(column.type) ? ` serialize: (value: DateTime | null) => { return value ? moment(value).format('ll') : value }` : ''}`; columnDefinitions += ` }) public ${columnName}: ${this.isDateTime(column.type) ? 'DateTime' : column.type === 'others' ? 'string' : column.type}\n`; if (column.primary) { primary = { name: null, ...column }; primary.name = columnName; } else if (columnName === 'password') { varImport += `\nimport Hash from '@ioc:Adonis/Core/Hash'`; createHook += `\n_modelInstance.password = await Hash.make(_modelInstance.password)`; } else if (column.primary_table && column.primary_column && column.relation_name && fs_1.default.existsSync(`${this.application.appRoot}/app/Models/${(0, helpers_1.pascalCase)(pluralize_1.default.singular(column.primary_table))}.ts`)) { let pascal = (0, helpers_1.pascalCase)(pluralize_1.default.singular(column.primary_table)); let camel = (0, helpers_1.camelCase)(pluralize_1.default.singular(column.relation_name)); relationshipArray.push(camel); if (!imported['belongsTo']) { otherImports += `, belongsTo, BelongsTo`; imported['belongsTo'] = true; } varImport += `\nimport ${pascal} from 'App/Models/${pascal}'`; relationships += `\n@belongsTo(() => ${pascal}) public ${camel}: BelongsTo<typeof ${pascal}>\n`; } }); data = data .replace(new RegExp('{{pascalName}}', 'g'), pascalName) .replace(new RegExp('{{tableName}}', 'g'), tableName) .replace('{{primaryColumn}}', `${primary ? primary.name : 'null'}`) .replace('{{autoIncrement}}', `${primary && primary.autoincrement ? 'false' : 'true'}`) .replace('{{relationships}}', relationships) .replace('{{columnDefinitions}}', columnDefinitions) .replace('{{createHook}}', createHook) .replace('{{updateHook}}', updateHook) .replace('{{otherImports}}', `${otherImports} `) .replace('{{relationshipArray}}', relationshipArray.length ? `['${relationshipArray.join("', '")}']` : '[]') .replace('{{varImport}}', varImport) .replace('{{methods}}', methods); return data; } } /** * Command name is used to run the command */ ModelGenerator.commandName = 'crud:model'; /** * Command description is displayed in the "help" output */ ModelGenerator.description = 'Generate model and relationships for a table'; ModelGenerator.settings = { /** * Set the following value to true, if you want to load the application * before running the command */ loadApp: true, /** * Set the following value to true, if you want this command to keep running until * you manually decide to exit the process */ stayAlive: false, }; __decorate([ standalone_1.args.string({ description: 'Table to generate model and relationships for' }), __metadata("design:type", String) ], ModelGenerator.prototype, "table", void 0); __decorate([ standalone_1.flags.boolean({ description: 'Specify custom DB connection to use' }), __metadata("design:type", String) ], ModelGenerator.prototype, "connection", void 0); exports.default = ModelGenerator;