-
Notifications
You must be signed in to change notification settings - Fork 1
/
csss.js
executable file
·239 lines (235 loc) · 7.97 KB
/
csss.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#! /usr/bin/env node
'use strict';
const fs = require('fs-extra');
const path = require('path');
const yargv = require('yargs');
const validateNPM = require('validate-npm-package-name');
const execFile = require('child_process').execFile;
const prompt = require('prompt');
const filepath = require('filepath');
const validatePath = require('./lib/helpers').validatePath;
const isRelativePath = require('is-relative');
const colors = require('colors/safe');
// configure prompt
prompt.message = '';
prompt.delimiter = colors.green(':');
// set default values
const defaultNPMName = 'my-staffbase-backend';
const scaffoldFolder = path.resolve(__dirname, './scaffoldTpl');
yargv
.usage('Usage: create-staffbase-sso-server <project-directory> [Options]')
.alias('name', 'N')
.string('name')
.describe('name', 'a sepcific package.json name of your app')
.version('0.0.1')
.help('help')
.epilogue(`for more information,\please see the README at:
https://github.com/Staffbase/create-staffbase-plugin-nodejs/blob/master/README.MD`);
// console.log('YARGS Parsed Data:\n', yargv.argv);
const packageJSON = fs.readJSONSync(path.join(scaffoldFolder, 'package.json'));
// Defaults package name to current folder name
const nameParam = yargv.argv.N || yargv.argv.name || defaultNPMName;
prompt.override = {
name: yargv.argv.N,
path: yargv.argv._[0],
};
/**
* Prompts user for just the npm name value.
* @param {String} name name of app in package.json
* @return {[type]} Promise resolved when correct name is entered. Resolved with prompt object
*/
function promptName(name) {
const namePromptSchema = {
properties: {
name: {
description: 'What is the npm name of your plugin?',
type: 'string',
default: name,
message: 'Name must be npm.js compatible',
required: true,
conform: function(value) {
return validateNPM(value).validForNewPackages;
},
},
},
};
return new Promise(function(resolve, reject) {
prompt.start()
.get(namePromptSchema, function(err, res) {
if (err) {
return reject(err);
}
return resolve(res);
});
});
}
/**
* Prompt path and ask to override folder if it exists
* @param {String} promtedName
* @return {[type]} [description]
*/
function promptPath(promtedName) {
const defPath = path.resolve(path.join(process.cwd(), promtedName));
const pathPromptSchema = {
properties: {
path: {
description: 'Please enter the folder path for the App',
type: 'string',
message:
'Entered path is invalid or an already present file on the File System. Please enter a correct filepath,',
default: defPath,
required: true,
conform: validatePath,
},
override: {
message:
colors.yellow('The directory you specified already exists. It directory will be overridden!') +
'\nDo you wish to proceed (y)es|(n)o?',
validator: /y[es]*|n[o]?/,
warning: 'Must respond yes or no',
default: 'yes',
ask: function() {
let chkPath = defPath;
if (prompt.history('path')) {
chkPath = prompt.history('path').value;
}
return filepath.create(chkPath).exists();
},
},
},
};
return new Promise(function(resolve, reject) {
prompt.get(pathPromptSchema, function(err, res) {
if (err) {
return reject(err);
}
return resolve(res);
});
});
}
/**
* Copy contants from the Scaffold Template to the specified folder
* @param {String} dstDir THe destination directory where files are to be copied
* @return {Promise} Promise resolved when the copy process is complete. Rejected
* if there is some error in copying files.
*/
function copyContents(dstDir) {
// console.log(colors.blue('Copying from:' + path.resolve(__dirname, './scaffoldTpl')));
const scaffoldFolder = path.resolve(__dirname, './scaffoldTpl');
return fs.copy(scaffoldFolder, dstDir);
}
/**
* Repace the package.json file from copied fromplate to the new generated one.
* @return {Promise} Promise resolved when the Package.json is successfully replaced.
* @param {String} dstPath The path of the folder where the package.json needs to be replaced
* @param {String} nameVal name value that should be replaced
* Rejected if there is some error in creating new Package.json file.
*/
function replacePackageJSON(dstPath, nameVal) {
// console.log("replacePackageJSON");
const newPackageJSON = Object.assign({}, packageJSON, {name: nameVal});
const curDir = path.resolve(dstPath);
const packagePath = path.resolve(path.join(curDir, 'package.json'));
return fs.remove(packagePath)
.then(function(data) {
// console.log(colors.yellow('Writing json...'));
return fs.writeJson(packagePath, newPackageJSON, {spaces: 2});
});
}
/**
* Installs the node modules in the folder where the template was created.
* The function runs "npm install" command.
* @param {String} dstPath Path of the folder where the packages need to be installed.
* @return {Promise} Promise resolved when the packages are successfulyl installed.
*/
function installDeps(dstPath) {
console.log(colors.italic('\nInstalling dependencies...'));
const opts = {
cwd: path.resolve(dstPath),
};
return new Promise( (resolve, reject) => {
execFile('npm', ['install'], opts, (err, stdout, stderr) => {
// console.log(colors.red('Inside Child result', stderr, stdout, err));
if (err) {
// console.log(colors.red(err));
return reject(err);
}
return resolve(stdout);
});
});
}
/**
* Removes the targer directory if it exists.
* @param {String} dstPath Path of target directory.
* @return {Promise} Promise resolved when the directory is removed or the directory doesn't exist,
* rejected when there is an errer in removing the directory.
*/
function removeExistingFolder(dstPath) {
const fp = filepath.create(dstPath);
if (fp.exists()) {
return fs.remove(fp.toString())
.then(function() {
console.log(colors.red('Removing existing folder and its contents...'));
return dstPath;
});
} else {
return Promise.resolve(dstPath);
}
}
// Run the promise chain for the whole process
const promptRes = {};
// promot package name
promptName(nameParam)
// prompt file path
.then(function(pathResp) {
const nameRecv = pathResp.name;
Object.assign(promptRes, pathResp);
return promptPath(nameRecv);
})
// remove the folder if it exists
.then(function(pathResp) {
if (pathResp.override === 'n' || pathResp.override === 'no') {
return Promise.reject(console.log(colors.green('Good Bye!')));
}
Object.assign(promptRes, pathResp);
let pathRecv = pathResp.path;
// if the entered path is relative, resolve to absolute
if (isRelativePath(pathRecv)) {
pathRecv = path.resolve(path.join(process.cwd(), pathRecv));
promptRes.path = pathRecv;
}
return removeExistingFolder(pathRecv);
})
// copy contents to folder
.then((pathRecv) => {
return (copyContents(pathRecv));
})
// replace package.json with new one
.then((res) => {
return replacePackageJSON(promptRes.path, promptRes.name);
})
// install npm dependencies
.then((res) => {
return installDeps(promptRes.path);
})
// output end results
.then(function(npmOutput) {
console.log(colors.yellow(npmOutput));
console.log(colors.green(`
Your application setup is complete!
Please see the generated README.MD file to get more details about next steps.
You can find your application template in: ${promptRes.path}.
`));
})
// handle errors if any
.catch(function(err) {
if (err.message === 'canceled') {
return console.log(colors.green('\nGood Bye!'));
}
if (err.message) {
console.log('An error occured.', err);
}
});
module.exports = {
validatePath: validatePath,
};