UNPKG

3.52 kBJavaScriptView Raw
1import { parse } from 'path';
2import { constants, filter, fs, inquirer, listr, loadSettings, log, value as valueUtil, } from '../common';
3export const name = 'tsconfig';
4export const alias = 'ts';
5export const description = `Common transformations across typescript configuration files.`;
6export const args = {
7 '-i': 'Include ignored modules.',
8};
9export async function cmd(args) {
10 const options = (args && args.options) || {};
11 const includeIgnored = options.i || false;
12 const settings = await loadSettings();
13 if (!settings) {
14 log.warn.yellow(constants.CONFIG_NOT_FOUND_ERROR);
15 return;
16 }
17 const response = (await inquirer.prompt([
18 {
19 type: 'list',
20 name: 'type',
21 message: 'Change?',
22 choices: ['noUnusedLocals: true', 'noUnusedLocals: false'],
23 },
24 ]));
25 log.info();
26 const paths = await getTsconfigPaths(settings, { includeIgnored });
27 const parts = toChoiceParts(response.type);
28 switch (response.type) {
29 case 'noUnusedLocals: true':
30 case 'noUnusedLocals: false':
31 await saveChangesWithPrompt(paths, { noUnusedLocals: parts.value });
32 break;
33 default:
34 log.error(`'${response.type}' not supported.`);
35 break;
36 }
37 log.info();
38}
39async function getTsconfigPaths(settings, options) {
40 const { includeIgnored = false } = options;
41 const paths = settings.modules
42 .filter((pkg) => filter.includeIgnored(pkg, includeIgnored))
43 .map((m) => m.dir)
44 .map((dir) => fs.join(dir, 'tsconfig.json'));
45 return filter.fileExists(paths);
46}
47async function saveChangesWithPrompt(paths, changes) {
48 if (paths.length === 0) {
49 log.info.gray('No files to change.');
50 return false;
51 }
52 log.info.cyan(`\nChange files:`);
53 paths.forEach((path) => {
54 log.info(` ${toDisplayPath(path)}`);
55 });
56 log.info();
57 const response = (await inquirer.prompt([
58 {
59 type: 'list',
60 name: 'confirm',
61 message: 'Are you sure?',
62 choices: ['No', 'Yes'],
63 },
64 ]));
65 switch (response.confirm) {
66 case 'No':
67 log.info.gray(`Nothing changed.`);
68 return false;
69 case 'Yes':
70 await saveChanges(paths, changes);
71 return true;
72 default:
73 return false;
74 }
75}
76function toDisplayPath(path) {
77 const root = parse(path);
78 const dir = parse(root.dir);
79 return log.gray(`${dir.dir}/${log.magenta(dir.base)}/${log.cyan(root.base)}`);
80}
81async function saveChanges(paths, changes) {
82 const saveChange = async (path) => {
83 const json = await fs.readJson(path);
84 const compilerOptions = Object.assign(Object.assign({}, json.compilerOptions), changes);
85 const tsConfig = Object.assign(Object.assign({}, json), { compilerOptions });
86 const text = `${JSON.stringify(tsConfig, null, ' ')}\n`;
87 await fs.writeFile(path, text);
88 };
89 const tasks = paths.map((path) => {
90 return {
91 title: `${log.cyan('Updated')} ${toDisplayPath(path)}`,
92 task: async () => saveChange(path),
93 };
94 });
95 try {
96 await listr(tasks, { concurrent: true, exitOnError: false }).run();
97 }
98 catch (error) {
99 }
100}
101function toChoiceParts(choice) {
102 const parts = choice.split(':');
103 const key = parts[0].trim();
104 const value = valueUtil.toType(parts[1].trim());
105 return { key, value };
106}