import {Arguments} from 'yargs'; import {default as ExtLB} from '..' import * as Inquirer from 'inquirer' import {Answers} from "inquirer"; import * as path from 'path'; import * as _ from 'lodash'; import * as Joi from 'joi'; import * as pluralize from 'pluralize'; import * as shelljs from 'shelljs'; class Model { options: { name: string; camelName: string; snakeName: string; capitalName: string; dataSource: string; baseClass: string; public: boolean; pluralName: string; type: string; }; constructor() { this.options = { name: null, camelName: null, snakeName: null, capitalName: null, dataSource: null, baseClass: null, public: null, pluralName: null, type: null, }; } getName() { let me = this; let curDir = _.last(process.cwd().split(path.sep)); return Inquirer.prompt([{ type: 'input', name: 'name', message: 'Model Name:', default: me.options.name || curDir.toLowerCase(), validate: (name: string) => { if (_.isNull(Joi.validate(name, Joi.string().required(), {convert: false}).error)) { return true; } else { return 'Model Name is required!'; } }, }]).then((answers: Answers) => { me.options.name = answers.name; me.options.camelName = _.camelCase(answers.name); me.options.snakeName = _.snakeCase(answers.name); me.options.capitalName = me.options.camelName.charAt(0).toUpperCase() + me.options.camelName.substr(1); return me.options.name; }); } getDataSource() { let me = this; return Inquirer.prompt([{ type: 'list', name: 'dataSource', message: `Select the data-source to attach ${me.options.name} to?`, choices: [ { name: 'Persisted DataBase (db)', value: 'db' }, { name: 'Memory DataBase (memoryDb)', value: 'memoryDb' }, { name: 'Other', value: 'other' } ], default: 'db', }]).then((answers: Answers) => { if (answers.dataSource === 'other') { return Inquirer.prompt([{ type: 'input', name: 'dataSource', message: `Enter data-source to attach ${me.options.name} to:`, validate: (name: string) => { if (_.isNull(Joi.validate(name, Joi.string().required(), {convert: false}).error)) { return true; } else { return 'Data Source name is required!'; } } }]).then((answers: Answers) => { me.options.dataSource = answers.dataSource; return answers.dataSource; }); } else { me.options.dataSource = answers.dataSource; return answers.dataSource; } }); } getBaseClass() { let me = this; let choices = ExtLB.default.models; let localModels = null; if (shelljs.test('-e', `${process.cwd()}${path.sep}config${path.sep}server${path.sep}model-config.json`)) { localModels = require(`${process.cwd()}${path.sep}config${path.sep}server${path.sep}model-config.json`); } else if (shelljs.test('-e', `${process.cwd()}${path.sep}server${path.sep}model-config.json`)) { localModels = require(`${process.cwd()}${path.sep}server${path.sep}model-config.json`); } if (!_.isNull(localModels)) { _.each(_.keys(localModels), (localModel) => { if (_.findIndex(choices, {name: localModel}) === -1) { choices.push({ name: localModel, value: localModel, }); } }); } return Inquirer.prompt([{ type: 'list', name: 'baseClass', message: 'Select model\'s base class:', choices: ExtLB.default.models, default: 'PersistedModel', }]).then((answers: Answers) => { if (answers.baseClass === 'custom') { return Inquirer.prompt([{ type: 'input', name: 'baseClass', message: 'Select model\'s base class:', validate: (name: string) => { if (_.isNull(Joi.validate(name, Joi.string().required(), {convert: false}).error)) { return true; } else { return 'Base Class name is required!'; } } }]).then((answers: Answers) => { me.options.baseClass = answers.baseClass; return answers.baseClass; }); } else { me.options.baseClass = answers.baseClass; return answers.baseClass; } }); } getPublic() { let me = this; return Inquirer.prompt([{ type: 'confirm', name: 'public', message: `Expose ${me.options.name} via the REST API?`, default: true, }]).then((answers: Answers) => { me.options.public = answers.public; return answers.public; }); } getPlural() { let me = this; return Inquirer.prompt([{ type: 'input', name: 'plural', message: 'Custom plural form (used to build REST URL):', default: pluralize.plural(me.options.name), validate: (name: string) => { if (_.isNull(Joi.validate(name, Joi.string().required(), {convert: false}).error)) { return true; } else { return 'Plural form is required!'; } }, }]).then((answers: Answers) => { me.options.pluralName = answers.plural; return answers.plural; }); } getType() { let me = this; return Inquirer.prompt([{ type: 'list', name: 'type', message: 'Common model or server only?', choices: [ {name: 'common', value: 'common'}, {name: 'server', value: 'server'}, ], default: 'common', }]).then((answers: Answers) => { me.options.type = answers.type; return answers.type }); } } exports.command = 'model'; exports.describe = 'Create a new ExtLoop Model'; exports.builder = {}; exports.handler = (argv: Arguments) => { const app = new Model(); app.getName().then(() => { return app.getDataSource(); }).then(() => { return app.getBaseClass(); }).then(() => { return app.getPublic(); }).then(() => { return app.getPlural(); }).then(() => { return app.getType(); }).then(() => { ExtLB.default.createModel(app.options); }).catch((err) => { console.error(err); }); };