· 6 years ago · Mar 23, 2019, 04:12 PM
1'use strict';
2
3const fs = require('fs');
4const chalk = require('chalk');
5const shell = require('shelljs');
6const inquirer = require('inquirer');
7const elegantSpinner = require('elegant-spinner');
8const logUpdate = require('log-update');
9const Table = require('cli-table3');
10const validate = require('validate-npm-package-name');
11const { showBanner } = require('../../external/banner');
12const boilerplate = require('../../../config.json');
13
14let availableCommands = new Table();
15let frame = elegantSpinner();
16
17let projectName;
18let projectConfig;
19
20let showTables = () => {
21 console.log(chalk.yellow('\n Available commands:-'));
22
23 availableCommands.push({
24 'mevn version': 'Current CLI version'
25 }, {
26 'mevn serve': 'To launch client/server'
27 }, {
28 'mevn add:package': 'Add additional packages'
29 },{
30 'mevn generate': 'To generate config files'
31 }, {
32 'mevn create:component <name>': 'Create new components'
33 }, {
34 'mevn codesplit <name>': 'Lazy load components'
35 }, {
36 'mevn create:git-repo': 'Create a GitHub Repo'
37 }, {
38 'mevn dockerize': 'Launch within docker containers'
39 }, {
40 'mevn deploy': 'Deploy the app to Heroku'
41 });
42 console.log(availableCommands.toString());
43
44 console.log(chalk.cyanBright(`\n\n Make sure that you've done ${chalk.greenBright(`cd ${projectName}`)}`));
45 console.log(chalk.redBright('\n warning:'));
46 console.log(' Do not delete mevn.json file');
47};
48
49let fetchTemplate = (template) => {
50 let templateDir = 'mevn-boilerplate';
51 if (template !== 'basic') {
52 templateDir = `mevn-${template}-boilerplate`;
53 }
54 shell.exec(`${boilerplate[template]} ${projectName}`, {silent: true}, {async: true});
55
56 let fetchSpinner = setInterval(() => {
57 logUpdate('Fetching the boilerplate ' + chalk.cyan.bold.dim(frame()));
58 }, 50);
59
60 setTimeout(() =>{
61 console.log('\n');
62 clearInterval(fetchSpinner);
63 logUpdate.clear();
64 showTables();
65
66 }, 5000);
67
68 fs.writeFileSync(`./${projectName}/mevn.json`, projectConfig.join('\n').toString());
69
70 if (template === 'nuxt') {
71 setTimeout(() => {
72 console.log('\n');
73 //add pwa support
74 inquirer.prompt([{
75 name: 'pwa',
76 type: 'confirm',
77 message: 'Do you want to have pwa support?'
78 }])
79 .then(async (answers) => {
80 if (answers.pwa) {
81 try{
82 //add pwa support
83 await shell.cd(`${projectName}`);
84 await shell.echo('Installing @nuxtjs/pwa package...');
85 //install pwa module
86 await shell.exec('npm i --save @nuxtjs/pwa', {silent: true});
87 //create nuxt.config.js
88 await shell.echo('Create nuxt.config.js file...');
89 await shell.exec('touch nuxt.config.js');
90 //config for pwa module
91 let data = `{ modules: [ '@nuxtjs/pwa']}`;
92 fs.writeFileSync('./nuxt.config.js', data);
93 //create sw.* and place it in gitignore
94 await shell.echo('Creating sw.*');
95 await shell.exec('touch sw.*');
96 } catch (err) {
97 throw err;
98 }
99 }
100 else{
101 await shell.echo('Okay, proceeding further..');
102 }
103 })
104 .then(() => {
105 //prompt user for Universal/SPA choices
106 inquirer.prompt([{
107 name: 'mode',
108 type: 'list',
109 message: 'Choose your preferred mode',
110 choices: ['Universal', 'SPA']
111 }]).then((choice) => {
112 if (choice.mode === 'Universal') {
113 let configFile = fs.readFileSync(`./${projectName}/nuxt.config.js`, 'utf8').toString().split('\n');
114 let index = configFile.indexOf(configFile.find(line => line.includes('mode')));
115 configFile[index] = ` mode: 'universal',`;
116
117 fs.writeFileSync(`./${projectName}/nuxt.config.js`, configFile.join('\n'));
118 }
119 showTables();
120 });
121 });
122 }, 5000);
123 }
124};
125
126exports.initializeProject = (appName) => {
127 showBanner();
128 console.log('\n');
129
130 let initialSpinner = setInterval(() => {
131 logUpdate('Initializing ' + chalk.cyan.bold.dim(frame()));
132 }, 50);
133
134 setTimeout(() => {
135 const hasMultipleProjectNameArgs = process.argv[4] && !process.argv[4].startsWith('-');
136 // Validation for multiple directory names
137 if (hasMultipleProjectNameArgs){
138 console.log(chalk.red.bold('\n Kindly provide only one argument as the directory name!!'));
139 process.exit(1);
140 }
141
142 const validationResult = validate(appName);
143 if (!validationResult.validForNewPackages) {
144 console.error(
145 `Could not create a project called ${chalk.red(
146 `"${appName}"`
147 )} because of npm naming restrictions:`
148 );
149 process.exit(1);
150 }
151
152 if (fs.existsSync(appName)) {
153 console.error(chalk.red.bold(`\n Directory ${appName} already exists in path!`));
154 process.exit(1);
155 }
156
157 clearInterval(initialSpinner);
158 logUpdate.clear();
159 projectName = appName;
160
161 inquirer.prompt([{
162 name: 'template',
163 type: 'list',
164 message: 'Please select one',
165 choices: ['basic', 'pwa', 'graphql', 'Nuxt-js']
166
167 }])
168 .then((choice) => {
169 projectConfig = [
170 '{',
171 `"name": "${appName}",`,
172 `"template": "${choice.template}"`,
173 '}'
174 ];
175
176 if (choice.template === 'Nuxt-js') {
177 choice.template = 'nuxt';
178 }
179 fetchTemplate(choice.template);
180 });
181 }, 1000);
182
183};