-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
177 lines (163 loc) · 6.89 KB
/
index.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
const fs = require('fs');
const prompts = require('prompts');
const ncp = require('ncp').ncp;
const changeCase = require('change-case');
const shell = require('shelljs');
const replaceInFile = require('replace-in-file');
ncp.limit = 16;
let destinationPath = "";
const REPLACEMENT_OPTIONS = ["FILE_NAME","FOLDER_NAME","FILE_VALUES"]
const CASE_TYPES = ["camelCase","snakeCase","paramCase","pascalCase","constantCase"]
// get list of available folders in a path
const getFolderList = (path) => {
return fs.readdirSync(path, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => ({title:dirent.name}));
}
// recursively pick the path to project package.json
const locationSelector = async (path)=>{
let cPath= path ? path:__dirname+"/../../";
let folderList = getFolderList(cPath);
folderList.push({title:"ADD_HERE"},{title:"GO_BACK"});
const response = await prompts({
type: 'autocomplete',
name: 'fileSelector',
message: 'Select the location you want your file in',
choices: folderList.reverse()
});
if (response.fileSelector == "ADD_HERE"){
destinationPath = cPath;
return cPath;
}
else if (response.fileSelector == "GO_BACK"){
await locationSelector();
}
else {
await locationSelector(cPath+"/"+response.fileSelector);
}
}
//prompt user to select tech stack and save it to a config file
const stackTypeSelector = async (path)=> {
path= path ? path:__dirname+"/../../developer-templates";
try {
return JSON.parse(fs.readFileSync(__dirname+"/../../developer-templates/config.json")).techStack;
}catch (e) {
let folderList = getFolderList(path);
const response = await prompts({
type: 'autocomplete',
name: 'techStack',
message: 'Select your Project stack',
choices: folderList
});
fs.writeFile (__dirname+"/../../developer-templates/config.json", JSON.stringify(response), function(err) {
if (err) throw err;
console.log('Response was saved to /developer-templates/config.json. Delete this file if you want to change it later.');
}
);
return response.techStack;
}
}
//prompt user to select template type and return the template path
const templateSelector = async (path)=> {
const techStack = await stackTypeSelector();
console.log ("Available templates for " +techStack);
path = path ? path:__dirname+"/../../developer-templates/"+techStack;
console.log("templateSelector",path)
let folderList = getFolderList(path);
const response = await prompts({
type: 'autocomplete',
name: 'templateType',
message: 'Select a template',
choices: folderList
});
const selectedPath = __dirname+"/../../developer-templates/"+techStack+"/"+response.templateType;
const templateName = getFolderList(selectedPath)[0].title;
return [selectedPath,selectedPath+"/"+templateName,templateName];
}
// Take user inputs
const replacePrompt = async (userInputRequests) =>{
//console.log(userInputRequest);
const promptList = userInputRequests.map((userInputRequest)=>{
return ({
type: 'text',
name: userInputRequest.label,
message: 'What should we rename '+userInputRequest.label+' to?',
})
})
const responses = await (async () => {
return await prompts(promptList);
})();
return responses;
}
//generate a list of tasks as an array to perform
const generateTaskList = (userInputRequests,responses) => {
const fullTaskList = userInputRequests.map((userInputRequest)=>{
const taskListPerRequest = userInputRequest.replacements.map((rv)=>{
const casedInput = changeCase[CASE_TYPES[rv.replacingCaseTypes-1]](responses[userInputRequest.label]);
return rv.replacingLocations.map((rl)=>{
return {
replacementOption : REPLACEMENT_OPTIONS[rl-1],
originalValue : rv.replacingText,
newValue: casedInput
}
});
});
return taskListPerRequest.reduce((a,b)=>{ return a.concat(b) }, []);
});
return fullTaskList.reduce((a,b)=>{ return a.concat(b) }, []);
}
const folderNameReplaceHandler = (originalValue,newValue,path) =>{
console.log("Folder Names => ",originalValue," to", newValue);
shell.exec('cd '+path+' &&'+__dirname+'/../../node_modules/.bin/renamer --find /'+originalValue+'/i --replace "'+newValue+'" "**/"');
}
const fileNameReplaceHandler = (originalValue,newValue,path) =>{
console.log("File Names => ",originalValue," to", newValue);
shell.exec('cd '+path+' &&'+__dirname+'/../../node_modules/.bin/renamer --find /'+originalValue+'/i --replace "'+newValue+'" "**"');
}
const fileContentReplaceHandler = async (originalValue,newValue,path) =>{
console.log("File Content => ",originalValue," to", newValue);
const data = replaceInFile({
files: path+'/**',
from: new RegExp(originalValue,"g"),
to: newValue,
});
return data;
}
// handle replacement process after analysing the user-input-map.json
const replaceHandler = async (templatePath,destinationRootPath,template) => {
try {
const userInputRequests = JSON.parse(fs.readFileSync(
templatePath.substring(0,templatePath.lastIndexOf("/"))+"/user-input-map.json"));
const taskList = generateTaskList(userInputRequests,await replacePrompt(userInputRequests));
let destinationFolderName = taskList.find((task)=>{
// Destination parent will take the first Name available for a FOLDER_NAME else template name
if (task.replacementOption === "FOLDER_NAME"){
return task;
}
});
destinationFolderName = destinationFolderName? destinationFolderName.newValue:template;
const destinationFolderPath = destinationRootPath+"/"+destinationFolderName
ncp(templatePath,destinationFolderPath,(err)=>{
taskList.map(async (task)=>{
if (task.replacementOption === "FILE_NAME"){
fileNameReplaceHandler(task.originalValue,task.newValue,destinationFolderPath)
}
else if (task.replacementOption === "FOLDER_NAME"){
folderNameReplaceHandler(task.originalValue,task.newValue,destinationFolderPath)
}
else if (task.replacementOption === "FILE_VALUES"){
await fileContentReplaceHandler(task.originalValue,task.newValue,destinationFolderPath)
}
})
}) // Copy the folder from template to the destination
}
catch (e){
console.log(e);
}
}
const run = async () =>{
let templateInfo = await templateSelector()
await locationSelector()
await replaceHandler(templateInfo[1],destinationPath,templateInfo[2]);
}
run();