-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.js
executable file
·173 lines (138 loc) · 5.79 KB
/
cli.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
#!/usr/bin/env node
// @ts-check
/// <reference types="node" />
'use strict';
const path = require('path');
const chalk = require('chalk');
const { cosmiconfig } = require('cosmiconfig');
const meow = require('meow');
const VError = require('verror');
const { addAllIgnores } = require('.');
// *** CLI setup ***
const cli = meow(`
Usage
$ ts-ignore-import [...declaration files]
Adds @ts-ignore to imports/requires in TypeScript declaration files. By default it adds it to all imports/requires, but one can mark modules to be exempted from it by using the --allow flag.
Auto-discoveres tsconfig.json if none has been specified and uto-discoveres a top level index.d.ts declaration file if no specific declaration files has been specified.
Will traverse all local declaration files depended on by included declaration files and process them as well.
Core options
--allow, -a Marks a module as allowed. It will then not have a @ts-ignore added. (Already added ignores are kept though)
--skip, -s Skip a specific file. Follows .gitignore syntax. Matched against file paths relative to resolved path of ts-config.
--ts-config, -t Point to a tsconfig.json file to override any auto-discovered one
Additional options
--debug Activates some very verbose logging
--dry-run Runs everything like normal, but doesn't save any changes
--help When set, this help will be printed
--silent When set, no feedback will be printed
--verbose, -v When set, more verbose feedback will be printed
--version When set, this tools version will be printed
Examples
$ ts-ignore-import --allow=bunyan-adapter path/to/file.d.ts
`, {
flags: {
allow: { type: 'string', alias: 'a', isMultiple: true },
skip: { type: 'string', alias: 'i', isMultiple: true },
'ts-config': { type: 'string', alias: 't' },
debug: { type: 'boolean', 'default': false },
'dry-run': { type: 'boolean', 'default': false },
silent: { type: 'boolean', 'default': false },
verbose: { type: 'boolean', alias: 'v', 'default': false },
}
});
const declarationFilePaths = cli.input.length ? cli.input : undefined;
let {
tsConfig: tsConfigFilePath,
} = cli.flags;
const {
allow: allowedDependencies,
skip: ignoreFile,
debug,
dryRun,
silent,
verbose,
} = cli.flags;
// *** Logging setup ***
const LOG_TITLE_PAD = 30;
const LOG_MESSAGE_PAD = 25;
const LOG_TITLE_PAD_LONG = LOG_TITLE_PAD + LOG_MESSAGE_PAD + 1;
const LOG_MESSAGE_PAD_LONG = LOG_MESSAGE_PAD + 10;
/**
* @param {'log'|'error'} level
* @param {string} title
* @param {string} [message]
* @param {string} [extras]
* @param {boolean} [dimItAll]
* @returns {void}
*/
const log = (level, title, message, extras, dimItAll) => {
/** @type {string} */
let resolvedMessage = [
title && chalk.bold((message || extras) ? title.padEnd(title.length > LOG_TITLE_PAD ? LOG_TITLE_PAD_LONG : LOG_TITLE_PAD) : title),
extras ? (message || '').padEnd(message && message.length >= LOG_MESSAGE_PAD ? LOG_MESSAGE_PAD_LONG : LOG_MESSAGE_PAD) : message,
extras && chalk.dim(extras),
]
.filter(item => !!item)
.join(' ');
if (dimItAll) resolvedMessage = chalk.dim(resolvedMessage);
if (level === 'error') resolvedMessage = chalk.bgRed.whiteBright(resolvedMessage);
// eslint-disable-next-line no-console
console[level](resolvedMessage);
};
/** @type {import('.').VerboseLog} */
const verboseLog = (verbose || debug)
? (title, message, extras, dimItAll) => log('log', title, message, extras, dimItAll)
: () => {};
verboseLog('Time to ignore TypeScript imports!');
// *** Tool setup ***
if (dryRun) verboseLog('Doing a dry run:', 'Yes');
const explorer = cosmiconfig('tsignoreimport', {
packageProp: 'tsIgnoreImport',
});
explorer.search().then(async (result) => {
const config = (result && result.config) || {};
if (result && result.config) verboseLog('Uses configuration file:', result.filepath);
const mergedIgnoreFiles = [
...(Array.isArray(config.skipFiles) ? config.skipFiles : []),
...(ignoreFile || []),
];
const mergedAllowedDependencies = [
...(Array.isArray(config.allow) ? config.allow : []),
...(allowedDependencies || []),
];
const mergedDeclarationFilePaths = [
...(Array.isArray(config.files) ? config.files : []),
...(declarationFilePaths || []),
];
if (result && !tsConfigFilePath && config.tsConfigFilePath) {
tsConfigFilePath = path.resolve(result.filepath, config.tsConfigFilePath);
}
verboseLog(
'Allowed dependencies:',
mergedAllowedDependencies.length + ' dependencies',
mergedAllowedDependencies.length ? [...mergedAllowedDependencies].sort().join(', ') : ''
);
const { ignored, sourceFileCount } = await addAllIgnores({
declarationFilePaths: mergedDeclarationFilePaths,
// TODO [meow@>7.0.1]: Remove @ts-ignore if issue has been fixed
// @ts-ignore See https://github.com/sindresorhus/meow/issues/155
tsConfigFilePath,
}, {
allowedDependencies: mergedAllowedDependencies,
// TODO [meow@>7.0.1]: Remove @ts-ignore if issue has been fixed
// @ts-ignore See https://github.com/sindresorhus/meow/issues/155
dryRun,
ignoreFiles: mergedIgnoreFiles.length ? mergedIgnoreFiles : undefined,
debug,
verboseLog,
resolveWithCwd: true,
});
if (!silent) {
log('log', `Found and ignored ${ignored.size} ${ignored.size === 1 ? 'dependency' : 'dependencies'} across ${sourceFileCount} ${sourceFileCount === 1 ? 'file' : 'files'}:`, [...ignored].sort().join(', '));
}
})
.catch(err => {
log('error', err.name === 'VError' ? 'An error occured:' : 'An unexpected error occured:', err.message);
verboseLog('Stacktrace:');
verboseLog('', VError.fullStack(err));
process.exit(1);
});