UNPKG

18.5 kBPlain TextView Raw
1import inquirer = require('inquirer');
2import * as path from 'path';
3import * as jsonfile from 'jsonfile';
4import * as _ from 'lodash';
5import * as async from 'async';
6import * as fs from 'fs';
7import * as shelljs from 'shelljs';
8import * as ejs from 'ejs';
9import {default as chalk} from 'chalk';
10let simpleGit = require('simple-git/promise');
11
12export class ExtLB {
13 logo: string = chalk.green(` (
14 ) )\\ ) (
15 ( ) ( /((()/( ( )\\
16 )\\ ( /( )\\())/(_)))((_)
17((_) )\\())(_))/(_)) ((_)_
18| __|((_)\\ | |_ | | | _ )
19| _| \\ \\ / | _|| |__ | _ \\
20|___|/_\\_\\ \\__||____||___/ `);
21 versions: string[] = ['v1'];
22 authentication: object[] = [{name: 'User', value: 'users'},{name: 'Accounts', value: 'accounts'}];
23 platforms: object[] = [{name:'desktop', checked: true}, {name:'phone'}];
24 features: object[] = [
25 new inquirer.Separator('ExtLoop Features'), {
26 name: 'Browserify',
27 value: 'browserify',
28 checked: true
29 }, {
30 name: 'Socket.IO',
31 value: 'socketio',
32 checked: true
33 }, {
34 name: 'Authentication',
35 value: 'auth',
36 checked: true
37 }, {
38 name: 'Queues',
39 value: 'queues'
40 }, new inquirer.Separator('ExtLoop Perspectives'), {
41 name: 'Admin',
42 value: 'perspective-admin',
43 checked: true
44 }, {
45 name: 'Auth',
46 value: 'perspective-auth',
47 checked: true
48 }, {
49 name: 'Error',
50 value: 'perspective-error',
51 checked: true
52 }, {
53 name: 'Main',
54 value: 'perspective-main',
55 checked: true
56 }
57 ];
58 models: object[] = [
59 {name: 'Model', value: 'Model'},
60 {name: 'PersistedModel', value: 'PersistedModel'},
61 {name: 'ACL', value: 'ACL'},
62 {name: 'AccessToken', value: 'AccessToken'},
63 {name: 'Application', value: 'Application'},
64 {name: 'Change', value: 'Change'},
65 {name: 'Checkpoint', value: 'Checkpoint'},
66 {name: 'Email', value: 'Email'},
67 {name: 'KeyValueModel', value: 'KeyValueModel'},
68 {name: 'Role', value: 'Role'},
69 {name: 'RoleMapping', value: 'RoleMapping'},
70 {name: 'Scope', value: 'Scope'},
71 {name: 'User', value: 'User'},
72 {name: '(custom)', value: 'custom'}
73 ];
74 constructor() {
75 }
76 static checkAvailable(dir: string): boolean {
77 return !shelljs.test('-e', path.join(dir, 'package.json'));
78 }
79 createApp(options: { name: string, camelName: string, snakeName: string, capitalName: string, description: string, version: string, authType: string, platforms: [string], features: [string]}) {
80 console.log('Creating Application', options);
81 if (ExtLB.checkAvailable(process.cwd())) {
82 process.stdout.write(chalk.keyword('limegreen')('Retrieving application template '));
83 simpleGit().clone('https://gitlab.com/ExtLB/app-template.git', '.').then(() => {
84 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
85 shelljs.rm('-fr', '.git');
86 if (!_.includes(options.platforms, 'desktop')) {
87 shelljs.rm('-fr', ['config/client/desktop.json', 'resources/moderndesktop', 'app/desktop']);
88 }
89 if (!_.includes(options.platforms, 'phone')) {
90 shelljs.rm('-fr', ['config/client/phone.json', 'resources/modernphone', 'app/phone']);
91 }
92 let modifications: any = {};
93 _.filter(shelljs.ls(`${__dirname}${path.sep}app${path.sep}*.ts`), (file) => {
94 return !_.endsWith(file, '.d.ts');
95 }).map((file) => {
96 return file.substr(0, file.length - 3);
97 }).forEach((changer) => {
98 modifications[changer] = require(`${changer}`).default;
99 });
100 let modifiers: any = {};
101 _.each(modifications, (files) => {
102 _.each(files, (changes, file) => {
103 if (_.isUndefined(modifiers[file])) {
104 modifiers[file] = [];
105 }
106 modifiers[file].push(changes);
107 });
108 });
109 process.stdout.write(chalk.keyword('limegreen')(`Modifying ${_.keys(modifiers).length} files `));
110 let files = _.keys(modifiers);
111 _.each(files, (file) => {
112 let content: any = null;
113 if (_.endsWith(file, '.json')) {
114 content = jsonfile.readFileSync(file);
115 } else {
116 content = fs.readFileSync(file, {encoding: 'utf8'});
117 }
118 modifiers[file].forEach((modifier: (options: object, content: any) => object) => {
119 content = modifier(options, content);
120 });
121 process.stdout.write('.');
122 if (_.isNull(content)) {
123 shelljs.rm(file);
124 } else {
125 if (_.endsWith(file, '.json')) {
126 jsonfile.writeFileSync(file, content, {spaces: 2});
127 } else {
128 fs.writeFileSync(file, content, {encoding: 'utf8'});
129 }
130 }
131 });
132 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
133 console.log(chalk.keyword('limegreen')('Installing/Building Modules (npm install)'));
134 shelljs.exec('npm install', {silent:false}, () => {
135 console.log(chalk.keyword('limegreen')('Modules Installed!'));
136 if (
137 _.includes(options.features, 'perspective-admin') ||
138 _.includes(options.features, 'perspective-auth') ||
139 _.includes(options.features, 'perspective-error') ||
140 _.includes(options.features, 'perspective-main') ||
141 _.includes(options.features, 'auth')
142 ) {
143 let perspectives = _.filter(options.features, (feature) => {
144 return _.startsWith(feature, 'perspective-');
145 }).map((feature) => {
146 return `@extlb/${feature}`;
147 });
148 let installs: async.Dictionary<async.AsyncFunction<{},{}>> = {};
149 // let installs: {perspectives?: Function, authentication?: Function} = {};
150 if (perspectives.length !== 0) {
151 installs.perspectives = (cb: (err?: {}, result?: {}) => void) => {
152 process.stdout.write(chalk.keyword('limegreen')(`Installing ${perspectives.length} Perspectives `));
153 shelljs.exec(`npm install ${perspectives.join(' ')} -S`, {silent:true}, (err) => {
154 if (err) {
155 console.error(err);
156 cb(err);
157 } else {
158 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
159 cb();
160 }
161 });
162 };
163 }
164 if (_.includes(options.features, 'auth')) {
165 if (options.authType === 'users') {
166 installs.authentication = (cb: (err?: {}, result?: {}) => void) => {
167 process.stdout.write(chalk.keyword('limegreen')('Installing Authentication Module '));
168 shelljs.exec('npm install @extlb/auth -S', {silent: true}, (err) => {
169 if (err) {
170 console.error(err);
171 cb(err);
172 } else {
173 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
174 cb();
175 }
176 });
177 };
178 } else if (options.authType === 'accounts') {
179 installs.authentication = (cb: (err?: {}, result?: {}) => void) => {
180 process.stdout.write(chalk.keyword('limegreen')('Installing Accounts Module '));
181 shelljs.exec('npm install @extlb/module-admin-accounts -S', {silent: true}, (err) => {
182 if (err) {
183 console.error(err);
184 cb(err);
185 } else {
186 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
187 cb();
188 }
189 });
190 };
191 }
192 }
193 installs.grunt = (cb: (err?: {}, result?: {}) => void) => {
194 process.stdout.write(chalk.keyword('limegreen')('Building application '));
195 shelljs.exec('grunt "Build Testing Desktop"', {silent:true}, (err) => {
196 if (err) {
197 console.error(err);
198 cb(err);
199 } else {
200 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
201 cb();
202 }
203 });
204 };
205 async.series(installs, (err) => {
206 if (err) {
207 console.log(err);
208 } else {
209 console.log(chalk.keyword('limegreen')('Install Completed!'));
210 }
211 });
212 }
213 });
214 }).catch((err: any) => {
215 console.error(err);
216 });
217 } else {
218 console.log(chalk.red('package.json already exists!\n'));
219 }
220 // console.log(modifiers);
221 }
222 createModule(options: { name: string, camelName: string, snakeName: string, capitalName: string, server: boolean, client: boolean}) {
223 console.log('Creating Module', options);
224 if (ExtLB.checkAvailable(process.cwd())) {
225 process.stdout.write(chalk.keyword('limegreen')('Retrieving module template '));
226 simpleGit().clone('https://gitlab.com/ExtLB/module-template.git', '.').then(() => {
227 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
228 shelljs.rm('-fr', '.git');
229 let modifications: any = {};
230 _.filter(shelljs.ls(`${__dirname}${path.sep}module${path.sep}*.ts`), (file) => {
231 return !_.endsWith(file, '.d.ts');
232 }).map((file) => {
233 return file.substr(0, file.length - 3);
234 }).forEach((changer) => {
235 modifications[changer] = require(`${changer}`).default;
236 });
237 let modifiers: any = {};
238 _.each(modifications, (files) => {
239 _.each(files, (changes, file) => {
240 if (_.isUndefined(modifiers[file])) {
241 modifiers[file] = [];
242 }
243 modifiers[file].push(changes);
244 });
245 });
246 process.stdout.write(chalk.keyword('limegreen')(`Modifying ${_.keys(modifiers).length} files `));
247 let files = _.keys(modifiers);
248 _.each(files, (file) => {
249 let content: any = null;
250 if (_.endsWith(file, '.json')) {
251 content = jsonfile.readFileSync(file);
252 } else {
253 content = fs.readFileSync(file, {encoding: 'utf8'});
254 }
255 modifiers[file].forEach((modifier: (options: object, content: any) => object) => {
256 content = modifier(options, content);
257 });
258 process.stdout.write('.');
259 if (_.isNull(content)) {
260 shelljs.rm(file);
261 } else {
262 if (_.endsWith(file, '.json')) {
263 jsonfile.writeFileSync(file, content, {spaces: 2});
264 } else {
265 fs.writeFileSync(file, content, {encoding: 'utf8'});
266 }
267 }
268 });
269 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
270 process.stdout.write(chalk.keyword('limegreen')('Relocating 2 paths '));
271 shelljs.mv(`app${path.sep}desktop${path.sep}src${path.sep}view${path.sep}template`, `app${path.sep}desktop${path.sep}src${path.sep}view${path.sep}${options.name}`);
272 process.stdout.write('.');
273 shelljs.mv(`locales${path.sep}en-US${path.sep}mod-template.json`, `locales${path.sep}en-US${path.sep}mod-${options.name}.json`);
274 process.stdout.write('.');
275 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
276 console.log(chalk.keyword('limegreen')('Installing/Building Modules (npm install)'));
277 shelljs.exec('npm install', {silent:false}, () => {
278 console.log(chalk.keyword('limegreen')('Modules Installed!'));
279 });
280 }).catch((err: any) => {
281 console.error(err);
282 });
283 } else {
284 console.log(chalk.red('package.json already exists!\n'));
285 }
286 }
287 createPerspective(options: { name: string, camelName: string, snakeName: string, capitalName: string, server: boolean, client: boolean}) {
288 console.log('Creating Perspective', options);
289 if (ExtLB.checkAvailable(process.cwd())) {
290 process.stdout.write(chalk.keyword('limegreen')('Retrieving perspective template '));
291 simpleGit().clone('https://gitlab.com/ExtLB/perspective-template.git', '.').then(() => {
292 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
293 shelljs.rm('-fr', '.git');
294 let modifications: any = {};
295 _.filter(shelljs.ls(`${__dirname}${path.sep}perspective${path.sep}*.ts`), (file) => {
296 return !_.endsWith(file, '.d.ts');
297 }).map((file) => {
298 return file.substr(0, file.length - 3);
299 }).forEach((changer) => {
300 modifications[changer] = require(`${changer}`).default;
301 });
302 let modifiers: any = {};
303 _.each(modifications, (files) => {
304 _.each(files, (changes, file) => {
305 if (_.isUndefined(modifiers[file])) {
306 modifiers[file] = [];
307 }
308 modifiers[file].push(changes);
309 });
310 });
311 process.stdout.write(chalk.keyword('limegreen')(`Modifying ${_.keys(modifiers).length} files `));
312 let files = _.keys(modifiers);
313 _.each(files, (file) => {
314 let content: any = null;
315 if (_.endsWith(file, '.json')) {
316 content = jsonfile.readFileSync(file);
317 } else {
318 content = fs.readFileSync(file, {encoding: 'utf8'});
319 }
320 modifiers[file].forEach((modifier: (options: object, content: any) => object) => {
321 content = modifier(options, content);
322 });
323 process.stdout.write('.');
324 if (_.isNull(content)) {
325 shelljs.rm(file);
326 } else {
327 if (_.endsWith(file, '.json')) {
328 jsonfile.writeFileSync(file, content, {spaces: 2});
329 } else {
330 fs.writeFileSync(file, content, {encoding: 'utf8'});
331 }
332 }
333 });
334 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
335 process.stdout.write(chalk.keyword('limegreen')('Relocating 7 paths '));
336 shelljs.mv(`app${path.sep}desktop${path.sep}src${path.sep}model${path.sep}perspective${path.sep}template`, `app${path.sep}desktop${path.sep}src${path.sep}model${path.sep}perspective${path.sep}${options.name}`);
337 process.stdout.write('.');
338 shelljs.mv(`app${path.sep}desktop${path.sep}src${path.sep}view${path.sep}perspective${path.sep}template`, `app${path.sep}desktop${path.sep}src${path.sep}view${path.sep}perspective${path.sep}${options.name}`);
339 process.stdout.write('.');
340 shelljs.mv(`locales${path.sep}en-US${path.sep}per-template.json`, `locales${path.sep}en-US${path.sep}per-${options.name}.json`);
341 process.stdout.write('.');
342 shelljs.mv(`server${path.sep}models${path.sep}template-navigation.js`, `server${path.sep}models${path.sep}${options.name}-navigation.js`);
343 process.stdout.write('.');
344 shelljs.mv(`server${path.sep}models${path.sep}template-navigation.json`, `server${path.sep}models${path.sep}${options.name}-navigation.json`);
345 process.stdout.write('.');
346 shelljs.mv(`server${path.sep}models${path.sep}template-notification.ts`, `server${path.sep}models${path.sep}${options.name}-notification.ts`);
347 process.stdout.write('.');
348 shelljs.mv(`server${path.sep}models${path.sep}template-notification.json`, `server${path.sep}models${path.sep}${options.name}-notification.json`);
349 process.stdout.write(chalk.keyword('limegreen')(' done!\n'));
350 console.log(chalk.keyword('limegreen')('Installing/Building Modules (npm install)'));
351 shelljs.exec('npm install', {silent:false}, () => {
352 console.log(chalk.keyword('limegreen')('Modules Installed!'));
353 });
354 }).catch((err: any) => {
355 console.error(err);
356 });
357 } else {
358 console.log(chalk.red('package.json already exists!\n'));
359 }
360 }
361 createModel(options: { name: string, camelName: string, snakeName: string, capitalName: string, pluralName: string, dataSource: string, baseClass: string, public: boolean, type: string}) {
362 console.log('Creating Model', options);
363 if (!ExtLB.checkAvailable(process.cwd())) {
364 let modelDir = `${process.cwd()}${path.sep}${options.type}${path.sep}models${path.sep}`;
365 if (!shelljs.test('-d', modelDir)) {
366 shelljs.mkdir('-p', modelDir);
367 }
368 let modelConfigFile = `${modelDir}${options.snakeName}.json`;
369 let modelConfig = jsonfile.readFileSync(`${__dirname}${path.sep}model${path.sep}config.json`);
370 modelConfig.name = options.name;
371 modelConfig.plural = options.pluralName;
372 modelConfig.base = options.baseClass;
373 jsonfile.writeFileSync(modelConfigFile, modelConfig, {spaces: 2});
374 let modelCodeFile = `${modelDir}${options.snakeName}.ts`;
375 let modelCode = fs.readFileSync(`${__dirname}${path.sep}model${path.sep}code.ejs`, {encoding: 'utf8'});
376 modelCode = ejs.render(modelCode, {options: options});
377 fs.writeFileSync(modelCodeFile, modelCode);
378 if (shelljs.test('-e', `${process.cwd()}${path.sep}config${path.sep}server${path.sep}model-config.json`)) {
379 let modelsFile = `${process.cwd()}${path.sep}config${path.sep}server${path.sep}model-config.json`;
380 let modelsContent = jsonfile.readFileSync(modelsFile);
381 modelsContent[options.name] = {dataSource: options.dataSource, public: options.public};
382 jsonfile.writeFileSync(modelsFile, modelsContent, {spaces: 2});
383 } else if (shelljs.test('-e', `${process.cwd()}${path.sep}server${path.sep}model-config.json`)) {
384 let modelsFile = `${process.cwd()}${path.sep}server${path.sep}model-config.json`;
385 let models = jsonfile.readFileSync(modelsFile);
386 if (!_.isObject(models)) {
387 models.models = {};
388 }
389 models.models[options.name] = {dataSource: options.dataSource, public: options.public};
390 jsonfile.writeFileSync(modelsFile, models, {spaces: 2});
391 } else {
392 console.log(chalk.red('model-config.json missing'));
393 }
394 } else {
395 console.log(chalk.red('package.json missing!\n'));
396 }
397 }
398 createView(options: { name: string, camelName: string, snakeName: string, capitalName: string}) {
399 console.log('Creating View', options);
400 }
401}
402let extLoop = new ExtLB();
403export default extLoop;