This repository has been archived by the owner on Aug 23, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
extension.js
114 lines (100 loc) · 3.62 KB
/
extension.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
const vscode = require('vscode');
const path = require('path');
const fs = require('fs-plus');
const replacePlaceholders = (templateString, componentName) => (
templateString.replace(/__ComponentName__/g, componentName)
);
const computeConditionals = (templateString, options) => (
Object.keys(options).reduce((prev, curr) => (
options[curr]
? prev.replace(new RegExp('\\/\\* ?IF ?!'+curr+'[\\s\\S]*?ENDIF ?\\*\\/', 'g'), '')
: prev.replace(new RegExp(`\\/\\* ?IF ?`+curr+'[\\s\\S]*?ENDIF ?\\*\\/', 'g'), '')
), templateString).replace(/\/\* ?(END)?IF.*?\*\/\n?/g, '')
);
const validateName = (value, basePath) => {
if (value === undefined || value.trim() === '') {
return 'Invalid name';
}
if (fs.existsSync(path.join(basePath, value.trim()))) {
return 'Path already exists';
}
return null;
}
const validateYN = (value) => {
if (value !== undefined && value.toLowerCase() !== 'y' && value.toLowerCase() !== 'n') {
return 'Type "y" or "n"';
}
return null;
}
const generate = (componentName, inputPath, mode, enabledOptions) => {
const basePath = fs.isDirectorySync(inputPath)
? inputPath
: path.join(inputPath, '..');
const newPath = path.join(basePath, componentName);
console.log(`Generating ${newPath}`);
fs.mkdir(newPath, err => {
if (err) throw err;
// use included templates if user-defined path is empty
const templatePath =
vscode.workspace.getConfiguration('generate-react-component').get(`${mode}TemplatePath`).trim()
|| path.resolve(__dirname, `${mode}_template`);
fs.readdir(templatePath, (err, files) => {
if (err) throw err;
files.map(filename => {
const newFilename = replacePlaceholders(filename, componentName);
const filePath = path.resolve(templatePath, filename);
fs.readFile(filePath, (err, data) => {
if (err) throw err;
const newFilePath = path.join(newPath, newFilename);
fs.appendFile(newFilePath, replacePlaceholders(
computeConditionals(data.toString(), enabledOptions),
componentName
));
});
});
});
});
}
const createDisposable = (type) => (
vscode.commands.registerCommand(`extension.gen_${type}`, (target) => {
// Display input box prompting for component name
vscode.window.showInputBox({
prompt: `Enter ${type} name`,
validateInput: name => validateName(name, target.path),
}).then((name) => {
if (name === undefined) return undefined;
const options = vscode.workspace
.getConfiguration('generate-react-component')
.get('conditionals');
// Display a new input box for every conditional, resolve all in series
let p = Promise.resolve({ name, enabledOptions: {} });
return options.reduce((pc, opt) => {
return pc = pc.then((prev) => (vscode.window.showInputBox({
prompt: `Enable ${opt}? y/N`,
validateInput: value => validateYN(value),
}).then(value => {
if (value === undefined || prev === undefined) return undefined;
return {
name,
enabledOptions: Object.assign(
{},
prev.enabledOptions,
{ [opt]: (value.toLowerCase() === 'y') }
),
};
})));
}, p);
}).then((params) => {
if (params === undefined) return;
const { name, enabledOptions } = params;
generate(name.trim(), target.fsPath, type, enabledOptions);
});
})
)
const activate = (context) => {
context.subscriptions.push(
createDisposable('component'),
createDisposable('container')
);
}
exports.activate = activate;