UNPKG

@riddance/env

Version:

Too much code slows you down, creates risks, increases maintainability burdens, confuses AI. So let's commit less of it.

91 lines 12.7 kB
import { spellCheckFile } from 'cspell-lib'; import { readFile, writeFile } from 'node:fs/promises'; import { join, resolve } from 'node:path'; export function isSpellingDictionaryFile(files) { return files.length === 1 && files[0] === 'dictionary.txt'; } export async function spelling(reporter, path, files, abort) { const dictionaryWords = await readWords(path); const words = [...commonInducedWords, ...dictionaryWords]; const checkFiles = ['package.json', 'example/package.json', ...files]; const [, ...results] = await Promise.all([ syncConfigFile(path, dictionaryWords), ...checkFiles.map(file => spellCheckFile(resolve(path, file), { generateSuggestions: false }, { noConfigSearch: true, words })), ]); if (abort.aborted) { return false; } const errors = results.flatMap((r, ix) => (r.errors ?? []) .filter(e => !isFileNotFound(e)) .map(error => ({ file: checkFiles[ix], error }))); if (errors.length !== 0) { for (const e of errors) { reporter.fatal('Unexpected error checking spelling.', e.error, e.file); } return false; } const issues = results.flatMap((r, ix) => r.issues.map((issue) => ({ file: checkFiles[ix], issue, }))); if (issues.length !== 0) { for (const i of issues) { reporter.error(i.issue.message ?? 'Unknown word: ' + i.issue.text, i.file, i.issue.line.position && i.issue.line.position.line + 1); } return false; } return true; } const commonInducedWords = ['camelcase', 'postpublish']; async function readWords(dir) { try { const dictionary = await readFile(join(dir, 'dictionary.txt')); return dictionary .toString('utf-8') .split('\n') .filter(l => !!l) .map(l => l.trim()); } catch (e) { if (isFileNotFound(e)) { return []; } throw e; } } export async function setupSpelling(dir) { await syncConfigFile(dir, await readWords(dir)); } async function syncConfigFile(dir, words) { const config = JSON.stringify({ version: '0.2', files: ['**/*.ts', '**/*.md', 'package.json', 'example/package.json'], words: commonInducedWords, ...(words.length !== 0 && { dictionaries: ['project'], dictionaryDefinitions: [ { name: 'project', path: './dictionary.txt', }, ], }), }, undefined, ' '); try { const existing = await readFile(join(dir, 'cspell.json'), 'utf-8'); if (existing !== config) { await writeFile(join(dir, 'cspell.json'), config); } } catch (e) { if (isFileNotFound(e)) { await writeFile(join(dir, 'cspell.json'), config); return; } throw e; } } function isFileNotFound(e) { return e.code === 'ENOENT'; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlbGxpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzcGVsbGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQW1CLGNBQWMsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUM1RCxPQUFPLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFBO0FBQ3RELE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBR3pDLE1BQU0sVUFBVSx3QkFBd0IsQ0FBQyxLQUFlO0lBQ3BELE9BQU8sS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLGdCQUFnQixDQUFBO0FBQzlELENBQUM7QUFFRCxNQUFNLENBQUMsS0FBSyxVQUFVLFFBQVEsQ0FDMUIsUUFBa0IsRUFDbEIsSUFBWSxFQUNaLEtBQWUsRUFDZixLQUFrQjtJQUVsQixNQUFNLGVBQWUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUM3QyxNQUFNLEtBQUssR0FBRyxDQUFDLEdBQUcsa0JBQWtCLEVBQUUsR0FBRyxlQUFlLENBQUMsQ0FBQTtJQUN6RCxNQUFNLFVBQVUsR0FBRyxDQUFDLGNBQWMsRUFBRSxzQkFBc0IsRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFBO0lBQ3JFLE1BQU0sQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDO1FBQ3JDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsZUFBZSxDQUFDO1FBQ3JDLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUNyQixjQUFjLENBQ1YsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsRUFDbkIsRUFBRSxtQkFBbUIsRUFBRSxLQUFLLEVBQUUsRUFDOUIsRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUNsQyxDQUNK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Y2VzQ29udGVudCI6WyJpbXBvcnQgeyBWYWxpZGF0aW9uSXNzdWUsIHNwZWxsQ2hlY2tGaWxlIH0gZnJvbSAnY3NwZWxsLWxpYidcbmltcG9ydCB7IHJlYWRGaWxlLCB3cml0ZUZpbGUgfSBmcm9tICdub2RlOmZzL3Byb21pc2VzJ1xuaW1wb3J0IHsgam9pbiwgcmVzb2x2ZSB9IGZyb20gJ25vZGU6cGF0aCdcbmltcG9ydCB7IFJlcG9ydGVyIH0gZnJvbSAnLi9yZXBvcnRlci5qcydcblxuZXhwb3J0IGZ1bmN0aW9uIGlzU3BlbGxpbmdEaWN0aW9uYXJ5RmlsZShmaWxlczogc3RyaW5nW10pIHtcbiAgICByZXR1cm4gZmlsZXMubGVuZ3RoID09PSAxICYmIGZpbGVzWzBdID09PSAnZGljdGlvbmFyeS50eHQnXG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzcGVsbGluZyhcbiAgICByZXBvcnRlcjogUmVwb3J0ZXIsXG4gICAgcGF0aDogc3RyaW5nLFxuICAgIGZpbGVzOiBzdHJpbmdbXSxcbiAgICBhYm9ydDogQWJvcnRTaWduYWwsXG4pIHtcbiAgICBjb25zdCBkaWN0aW9uYXJ5V29yZHMgPSBhd2FpdCByZWFkV29yZHMocGF0aClcbiAgICBjb25zdCB3b3JkcyA9IFsuLi5jb21tb25JbmR1Y2VkV29yZHMsIC4uLmRpY3Rpb25hcnlXb3Jkc11cbiAgICBjb25zdCBjaGVja0ZpbGVzID0gWydwYWNrYWdlLmpzb24nLCAnZXhhbXBsZS9wYWNrYWdlLmpzb24nLCAuLi5maWxlc11cbiAgICBjb25zdCBbLCAuLi5yZXN1bHRzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgc3luY0NvbmZpZ0ZpbGUocGF0aCwgZGljdGlvbmFyeVdvcmRzKSxcbiAgICAgICAgLi4uY2hlY2tGaWxlcy5tYXAoZmlsZSA9PlxuICAgICAgICAgICAgc3BlbGxDaGVja0ZpbGUoXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShwYXRoLCBmaWxlKSxcbiAgICAgICAgICAgICAgICB7IGdlbmVyYXRlU3VnZ2VzdGlvbnM6IGZhbHNlIH0sXG4gICAgICAgICAgICAgICAgeyBub0NvbmZpZ1NlYXJjaDogdHJ1ZSwgd29yZHMgfSxcbiAgICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgXSlcbiAgICBpZiAoYWJvcnQuYWJvcnRlZCkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgY29uc3QgZXJyb3JzID0gcmVzdWx0cy5mbGF0TWFwKChyLCBpeCkgPT5cbiAgICAgICAgKHIuZXJyb3JzID8/IFtdKVxuICAgICAgICAgICAgLmZpbHRlcihlID0+ICFpc0ZpbGVOb3RGb3VuZChlKSlcbiAgICAgICAgICAgIC5tYXAoZXJyb3IgPT4gKHsgZmlsZTogY2hlY2tGaWxlc1tpeF0sIGVycm9yIH0pKSxcbiAgICApXG4gICAgaWYgKGVycm9ycy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgZm9yIChjb25zdCBlIG9mIGVycm9ycykge1xuICAgICAgICAgICAgcmVwb3J0ZXIuZmF0YWwoJ1VuZXhwZWN0ZWQgZXJyb3IgY2hlY2tpbmcgc3BlbGxpbmcuJywgZS5lcnJvciwgZS5maWxlKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBjb25zdCBpc3N1ZXMgPSByZXN1bHRzLmZsYXRNYXAoKHIsIGl4KSA9PlxuICAgICAgICByLmlzc3Vlcy5tYXAoKGlzc3VlOiBWYWxpZGF0aW9uSXNzdWUgJiB7IGxpbmU6IHsgcG9zaXRpb24/OiB7IGxpbmU6IG51bWJlciB9IH0gfSkgPT4gKHtcbiAgICAgICAgICAgIGZpbGU6IGNoZWNrRmlsZXNbaXhdLFxuICAgICAgICAgICAgaXNzdWUsXG4gICAgICAgIH0pKSxcbiAgICApXG4gICAgaWYgKGlzc3Vlcy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgZm9yIChjb25zdCBpIG9mIGlzc3Vlcykge1xuICAgICAgICAgICAgcmVwb3J0ZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgaS5pc3N1ZS5tZXNzYWdlID8/ICdVbmtub3duIHdvcmQ6ICcgKyBpLmlzc3VlLnRleHQsXG4gICAgICAgICAgICAgICAgaS5maWxlLFxuICAgICAgICAgICAgICAgIGkuaXNzdWUubGluZS5wb3NpdGlvbiAmJiBpLmlzc3VlLmxpbmUucG9zaXRpb24ubGluZSArIDEsXG4gICAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHJldHVybiB0cnVlXG59XG5cbmNvbnN0IGNvbW1vbkluZHVjZWRXb3JkcyA9IFsnY2FtZWxjYXNlJywgJ3Bvc3RwdWJsaXNoJ11cblxuYXN5bmMgZnVuY3Rpb24gcmVhZFdvcmRzKGRpcjogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGljdGlvbmFyeSA9IGF3YWl0IHJlYWRGaWxlKGpvaW4oZGlyLCAnZGljdGlvbmFyeS50eHQnKSlcbiAgICAgICAgcmV0dXJuIGRpY3Rpb25hcnlcbiAgICAgICAgICAgIC50b1N0cmluZygndXRmLTgnKVxuICAgICAgICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgICAgICAgLmZpbHRlcihsID0+ICEhbClcbiAgICAgICAgICAgIC5tYXAobCA9PiBsLnRyaW0oKSlcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChpc0ZpbGVOb3RGb3VuZChlKSkge1xuICAgICAgICAgICAgcmV0dXJuIFtdXG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZVxuICAgIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNldHVwU3BlbGxpbmcoZGlyOiBzdHJpbmcpIHtcbiAgICBhd2FpdCBzeW5jQ29uZmlnRmlsZShkaXIsIGF3YWl0IHJlYWRXb3JkcyhkaXIpKVxufVxuXG5hc3luYyBmdW5jdGlvbiBzeW5jQ29uZmlnRmlsZShkaXI6IHN0cmluZywgd29yZHM6IHN0cmluZ1tdKSB7XG4gICAgY29uc3QgY29uZmlnID0gSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIHtcbiAgICAgICAgICAgIHZlcnNpb246ICcwLjInLFxuICAgICAgICAgICAgZmlsZXM6IFsnKiovKi50cycsICcqKi8qLm1kJywgJ3BhY2thZ2UuanNvbicsICdleGFtcGxlL3BhY2thZ2UuanNvbiddLFxuICAgICAgICAgICAgd29yZHM6IGNvbW1vbkluZHVjZWRXb3JkcyxcbiAgICAgICAgICAgIC4uLih3b3Jkcy5sZW5ndGggIT09IDAgJiYge1xuICAgICAgICAgICAgICAgIGRpY3Rpb25hcmllczogWydwcm9qZWN0J10sXG4gICAgICAgICAgICAgICAgZGljdGlvbmFyeURlZmluaXRpb25zOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdwcm9qZWN0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6ICcuL2RpY3Rpb25hcnkudHh0JyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSksXG4gICAgICAgIH0sXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgJyAgJyxcbiAgICApXG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCByZWFkRmlsZShqb2luKGRpciwgJ2NzcGVsbC5qc29uJyksICd1dGYtOCcpXG4gICAgICAgIGlmIChleGlzdGluZyAhPT0gY29uZmlnKSB7XG4gICAgICAgICAgICBhd2FpdCB3cml0ZUZpbGUoam9pbihkaXIsICdjc3BlbGwuanNvbicpLCBjb25maWcpXG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChpc0ZpbGVOb3RGb3VuZChlKSkge1xuICAgICAgICAgICAgYXdhaXQgd3JpdGVGaWxlKGpvaW4oZGlyLCAnY3NwZWxsLmpzb24nKSwgY29uZmlnKVxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZVxuICAgIH1cbn1cblxuZnVuY3Rpb24gaXNGaWxlTm90Rm91bmQoZTogdW5rbm93bikge1xuICAgIHJldHVybiAoZSBhcyB7IGNvZGU6IHVua25vd24gfSkuY29kZSA9PT0gJ0VOT0VOVCdcbn1cbiJdfQ==