UNPKG

6.41 kBPlain TextView Raw
1import {Arguments} from 'yargs';
2import {default as ExtLB} from '..'
3import * as Inquirer from 'inquirer'
4import {Answers} from "inquirer";
5import * as path from 'path';
6import * as _ from 'lodash';
7import * as Joi from 'joi';
8import * as pluralize from 'pluralize';
9import * as shelljs from 'shelljs';
10
11class Model {
12 options: {
13 name: string;
14 camelName: string;
15 snakeName: string;
16 capitalName: string;
17 dataSource: string;
18 baseClass: string;
19 public: boolean;
20 pluralName: string;
21 type: string;
22 };
23 constructor() {
24 this.options = {
25 name: null,
26 camelName: null,
27 snakeName: null,
28 capitalName: null,
29 dataSource: null,
30 baseClass: null,
31 public: null,
32 pluralName: null,
33 type: null,
34 };
35 }
36 getName() {
37 let me = this;
38 let curDir = _.last(process.cwd().split(path.sep));
39 return Inquirer.prompt([{
40 type: 'input',
41 name: 'name',
42 message: 'Model Name:',
43 default: me.options.name || curDir.toLowerCase(),
44 validate: (name: string) => {
45 if (_.isNull(Joi.validate(name, Joi.string().required(), {convert: false}).error)) {
46 return true;
47 } else {
48 return 'Model Name is required!';
49 }
50 },
51 }]).then((answers: Answers) => {
52 me.options.name = answers.name;
53 me.options.camelName = _.camelCase(answers.name);
54 me.options.snakeName = _.snakeCase(answers.name);
55 me.options.capitalName = me.options.camelName.charAt(0).toUpperCase() + me.options.camelName.substr(1);
56 return me.options.name;
57 });
58 }
59 getDataSource() {
60 let me = this;
61 return Inquirer.prompt([{
62 type: 'list',
63 name: 'dataSource',
64 message: `Select the data-source to attach ${me.options.name} to?`,
65 choices: [
66 {
67 name: 'Persisted DataBase (db)',
68 value: 'db'
69 }, {
70 name: 'Memory DataBase (memoryDb)',
71 value: 'memoryDb'
72 }, {
73 name: 'Other',
74 value: 'other'
75 }
76 ],
77 default: 'db',
78 }]).then((answers: Answers) => {
79 if (answers.dataSource === 'other') {
80 return Inquirer.prompt([{
81 type: 'input',
82 name: 'dataSource',
83 message: `Enter data-source to attach ${me.options.name} to:`,
84 validate: (name: string) => {
85 if (_.isNull(Joi.validate(name, Joi.string().required(), {convert: false}).error)) {
86 return true;
87 } else {
88 return 'Data Source name is required!';
89 }
90 }
91 }]).then((answers: Answers) => {
92 me.options.dataSource = answers.dataSource;
93 return answers.dataSource;
94 });
95 } else {
96 me.options.dataSource = answers.dataSource;
97 return answers.dataSource;
98 }
99 });
100 }
101 getBaseClass() {
102 let me = this;
103 let choices = ExtLB.default.models;
104 let localModels = null;
105 if (shelljs.test('-e', `${process.cwd()}${path.sep}config${path.sep}server${path.sep}model-config.json`)) {
106 localModels = require(`${process.cwd()}${path.sep}config${path.sep}server${path.sep}model-config.json`);
107 } else if (shelljs.test('-e', `${process.cwd()}${path.sep}server${path.sep}model-config.json`)) {
108 localModels = require(`${process.cwd()}${path.sep}server${path.sep}model-config.json`);
109 }
110 if (!_.isNull(localModels)) {
111 _.each(_.keys(localModels), (localModel) => {
112 if (_.findIndex(choices, {name: localModel}) === -1) {
113 choices.push({
114 name: localModel,
115 value: localModel,
116 });
117 }
118 });
119 }
120 return Inquirer.prompt([{
121 type: 'list',
122 name: 'baseClass',
123 message: 'Select model\'s base class:',
124 choices: ExtLB.default.models,
125 default: 'PersistedModel',
126 }]).then((answers: Answers) => {
127 if (answers.baseClass === 'custom') {
128 return Inquirer.prompt([{
129 type: 'input',
130 name: 'baseClass',
131 message: 'Select model\'s base class:',
132 validate: (name: string) => {
133 if (_.isNull(Joi.validate(name, Joi.string().required(), {convert: false}).error)) {
134 return true;
135 } else {
136 return 'Base Class name is required!';
137 }
138 }
139 }]).then((answers: Answers) => {
140 me.options.baseClass = answers.baseClass;
141 return answers.baseClass;
142 });
143 } else {
144 me.options.baseClass = answers.baseClass;
145 return answers.baseClass;
146 }
147 });
148 }
149 getPublic() {
150 let me = this;
151 return Inquirer.prompt([{
152 type: 'confirm',
153 name: 'public',
154 message: `Expose ${me.options.name} via the REST API?`,
155 default: true,
156 }]).then((answers: Answers) => {
157 me.options.public = answers.public;
158 return answers.public;
159 });
160 }
161 getPlural() {
162 let me = this;
163 return Inquirer.prompt([{
164 type: 'input',
165 name: 'plural',
166 message: 'Custom plural form (used to build REST URL):',
167 default: pluralize.plural(me.options.name),
168 validate: (name: string) => {
169 if (_.isNull(Joi.validate(name, Joi.string().required(), {convert: false}).error)) {
170 return true;
171 } else {
172 return 'Plural form is required!';
173 }
174 },
175 }]).then((answers: Answers) => {
176 me.options.pluralName = answers.plural;
177 return answers.plural;
178 });
179 }
180 getType() {
181 let me = this;
182 return Inquirer.prompt([{
183 type: 'list',
184 name: 'type',
185 message: 'Common model or server only?',
186 choices: [
187 {name: 'common', value: 'common'},
188 {name: 'server', value: 'server'},
189 ],
190 default: 'common',
191 }]).then((answers: Answers) => {
192 me.options.type = answers.type;
193 return answers.type
194 });
195 }
196}
197
198exports.command = 'model';
199exports.describe = 'Create a new ExtLoop Model';
200exports.builder = {};
201exports.handler = (argv: Arguments) => {
202 const app = new Model();
203 app.getName().then(() => {
204 return app.getDataSource();
205 }).then(() => {
206 return app.getBaseClass();
207 }).then(() => {
208 return app.getPublic();
209 }).then(() => {
210 return app.getPlural();
211 }).then(() => {
212 return app.getType();
213 }).then(() => {
214 ExtLB.default.createModel(app.options);
215 }).catch((err) => {
216 console.error(err);
217 });
218};