99 lines
3.9 KiB
Plaintext
99 lines
3.9 KiB
Plaintext
|
import { createRequire } from 'node:module';
|
||
|
import path from 'node:path';
|
||
|
import { AstroCheck } from '@astrojs/language-server';
|
||
|
import { watch } from 'chokidar';
|
||
|
import { bold, dim, red, yellow } from 'kleur/colors';
|
||
|
import yargs from 'yargs';
|
||
|
import { hideBin } from 'yargs/helpers';
|
||
|
import { options } from './options.js';
|
||
|
/**
|
||
|
* Given a list of arguments from the command line (such as `process.argv`), return parsed and processed options
|
||
|
*/
|
||
|
export function parseArgsAsCheckConfig(args) {
|
||
|
return yargs(hideBin(args)).options(options).parseSync();
|
||
|
}
|
||
|
/**
|
||
|
* Print diagnostics according to the given flags, and return whether or not the program should exit with an error code.
|
||
|
*/
|
||
|
export async function check(flags) {
|
||
|
const workspaceRoot = path.resolve(flags.root ?? process.cwd());
|
||
|
const require = createRequire(import.meta.url);
|
||
|
const checker = new AstroCheck(workspaceRoot, require.resolve('typescript'), flags.tsconfig);
|
||
|
let req = 0;
|
||
|
if (flags.watch) {
|
||
|
function createWatcher(rootPath, extensions) {
|
||
|
return watch(`${rootPath}/**/*{${extensions.join(',')}}`, {
|
||
|
ignored: (ignoredPath) => ignoredPath.includes('node_modules'),
|
||
|
ignoreInitial: true,
|
||
|
});
|
||
|
}
|
||
|
// Dynamically get the list of extensions to watch from the files already included in the project
|
||
|
const checkedExtensions = Array.from(new Set(checker.linter.languageHost.getScriptFileNames().map((fileName) => path.extname(fileName))));
|
||
|
createWatcher(workspaceRoot, checkedExtensions)
|
||
|
.on('add', (fileName) => {
|
||
|
checker.linter.fileCreated(fileName);
|
||
|
update();
|
||
|
})
|
||
|
.on('unlink', (fileName) => {
|
||
|
checker.linter.fileDeleted(fileName);
|
||
|
update();
|
||
|
})
|
||
|
.on('change', (fileName) => {
|
||
|
checker.linter.fileUpdated(fileName);
|
||
|
update();
|
||
|
});
|
||
|
}
|
||
|
async function update() {
|
||
|
if (!flags.preserveWatchOutput)
|
||
|
process.stdout.write('\x1Bc');
|
||
|
await lint();
|
||
|
}
|
||
|
async function lint() {
|
||
|
const currentReq = ++req;
|
||
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
||
|
const isCanceled = () => currentReq !== req;
|
||
|
if (isCanceled())
|
||
|
return;
|
||
|
const minimumSeverity = flags.minimumSeverity || 'hint';
|
||
|
const result = await checker.lint({
|
||
|
logErrors: {
|
||
|
level: minimumSeverity,
|
||
|
},
|
||
|
cancel: isCanceled,
|
||
|
});
|
||
|
console.info([
|
||
|
bold(`Result (${result.fileChecked} file${result.fileChecked === 1 ? '' : 's'}): `),
|
||
|
['error', 'warning', 'hint'].includes(minimumSeverity)
|
||
|
? bold(red(`${result.errors} ${result.errors === 1 ? 'error' : 'errors'}`))
|
||
|
: undefined,
|
||
|
['warning', 'hint'].includes(minimumSeverity)
|
||
|
? bold(yellow(`${result.warnings} ${result.warnings === 1 ? 'warning' : 'warnings'}`))
|
||
|
: undefined,
|
||
|
['hint'].includes(minimumSeverity)
|
||
|
? dim(`${result.hints} ${result.hints === 1 ? 'hint' : 'hints'}\n`)
|
||
|
: undefined,
|
||
|
]
|
||
|
.filter(Boolean)
|
||
|
.join(`\n${dim('-')} `));
|
||
|
if (flags.watch) {
|
||
|
console.info('Watching for changes...');
|
||
|
}
|
||
|
else {
|
||
|
switch (flags.minimumFailingSeverity) {
|
||
|
case 'error':
|
||
|
return result.errors > 0;
|
||
|
case 'warning':
|
||
|
return result.errors + result.warnings > 0;
|
||
|
case 'hint':
|
||
|
return result.errors + result.warnings + result.hints > 0;
|
||
|
default:
|
||
|
return result.errors > 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// Always lint on first run, even in watch mode.
|
||
|
const lintResult = await lint();
|
||
|
if (!flags.watch)
|
||
|
return lintResult;
|
||
|
}
|
||
|
//# sourceMappingURL=index.js.map
|