@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
JavaScript
;
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;