cspell 9.1.3 → 9.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/README.md +29 -21
  2. package/bin.mjs +1 -1
  3. package/dist/esm/app.d.ts +19 -0
  4. package/dist/esm/app.js +1033 -0
  5. package/dist/esm/application-D-NwS6qb.js +2573 -0
  6. package/dist/esm/application-DbOQYm56.d.ts +116 -0
  7. package/dist/esm/application.d.ts +3 -0
  8. package/dist/esm/application.js +3 -0
  9. package/dist/esm/index.d.ts +55 -0
  10. package/dist/esm/index.js +5 -0
  11. package/dist/esm/options-ChaXtdFn.d.ts +387 -0
  12. package/package.json +27 -25
  13. package/dist/esm/app.d.mts +0 -5
  14. package/dist/esm/app.mjs +0 -34
  15. package/dist/esm/application.d.mts +0 -17
  16. package/dist/esm/application.mjs +0 -99
  17. package/dist/esm/cli-reporter.d.ts +0 -38
  18. package/dist/esm/cli-reporter.js +0 -386
  19. package/dist/esm/commandCheck.d.ts +0 -3
  20. package/dist/esm/commandCheck.js +0 -52
  21. package/dist/esm/commandConfig.d.ts +0 -3
  22. package/dist/esm/commandConfig.js +0 -18
  23. package/dist/esm/commandDictionaries.d.ts +0 -3
  24. package/dist/esm/commandDictionaries.js +0 -40
  25. package/dist/esm/commandHelpers.d.ts +0 -18
  26. package/dist/esm/commandHelpers.js +0 -30
  27. package/dist/esm/commandInit.d.ts +0 -3
  28. package/dist/esm/commandInit.js +0 -25
  29. package/dist/esm/commandLink.d.ts +0 -3
  30. package/dist/esm/commandLink.js +0 -48
  31. package/dist/esm/commandLint.d.ts +0 -3
  32. package/dist/esm/commandLint.js +0 -226
  33. package/dist/esm/commandSuggestion.d.ts +0 -3
  34. package/dist/esm/commandSuggestion.js +0 -61
  35. package/dist/esm/commandTrace.d.ts +0 -3
  36. package/dist/esm/commandTrace.js +0 -91
  37. package/dist/esm/config/adjustConfig.d.ts +0 -7
  38. package/dist/esm/config/adjustConfig.js +0 -137
  39. package/dist/esm/config/config.d.ts +0 -5
  40. package/dist/esm/config/config.js +0 -18
  41. package/dist/esm/config/configInit.d.ts +0 -3
  42. package/dist/esm/config/configInit.js +0 -104
  43. package/dist/esm/config/constants.d.ts +0 -17
  44. package/dist/esm/config/constants.js +0 -23
  45. package/dist/esm/config/index.d.ts +0 -3
  46. package/dist/esm/config/index.js +0 -2
  47. package/dist/esm/config/options.d.ts +0 -62
  48. package/dist/esm/config/options.js +0 -2
  49. package/dist/esm/config/updateConfig.d.ts +0 -3
  50. package/dist/esm/config/updateConfig.js +0 -2
  51. package/dist/esm/console.d.ts +0 -25
  52. package/dist/esm/console.js +0 -53
  53. package/dist/esm/dictionaries/index.d.ts +0 -3
  54. package/dist/esm/dictionaries/index.js +0 -2
  55. package/dist/esm/dictionaries/listDictionaries.d.ts +0 -33
  56. package/dist/esm/dictionaries/listDictionaries.js +0 -131
  57. package/dist/esm/dirname.d.ts +0 -2
  58. package/dist/esm/dirname.js +0 -13
  59. package/dist/esm/emitters/DictionaryPathFormat.d.ts +0 -3
  60. package/dist/esm/emitters/DictionaryPathFormat.js +0 -12
  61. package/dist/esm/emitters/dictionaryListEmitter.d.ts +0 -19
  62. package/dist/esm/emitters/dictionaryListEmitter.js +0 -82
  63. package/dist/esm/emitters/helpers.d.ts +0 -14
  64. package/dist/esm/emitters/helpers.js +0 -67
  65. package/dist/esm/emitters/suggestionsEmitter.d.ts +0 -13
  66. package/dist/esm/emitters/suggestionsEmitter.js +0 -79
  67. package/dist/esm/emitters/traceEmitter.d.ts +0 -19
  68. package/dist/esm/emitters/traceEmitter.js +0 -87
  69. package/dist/esm/environment.d.ts +0 -39
  70. package/dist/esm/environment.js +0 -30
  71. package/dist/esm/featureFlags/featureFlags.d.ts +0 -4
  72. package/dist/esm/featureFlags/featureFlags.js +0 -21
  73. package/dist/esm/featureFlags/index.d.ts +0 -2
  74. package/dist/esm/featureFlags/index.js +0 -2
  75. package/dist/esm/index.d.mts +0 -6
  76. package/dist/esm/index.mjs +0 -4
  77. package/dist/esm/link.d.ts +0 -8
  78. package/dist/esm/link.js +0 -39
  79. package/dist/esm/lint/LintRequest.d.ts +0 -26
  80. package/dist/esm/lint/LintRequest.js +0 -83
  81. package/dist/esm/lint/index.d.ts +0 -3
  82. package/dist/esm/lint/index.js +0 -3
  83. package/dist/esm/lint/lint.d.ts +0 -8
  84. package/dist/esm/lint/lint.js +0 -515
  85. package/dist/esm/models.d.ts +0 -15
  86. package/dist/esm/models.js +0 -2
  87. package/dist/esm/options.d.ts +0 -353
  88. package/dist/esm/options.js +0 -9
  89. package/dist/esm/pkgInfo.d.ts +0 -14
  90. package/dist/esm/pkgInfo.js +0 -7
  91. package/dist/esm/repl/index.d.ts +0 -18
  92. package/dist/esm/repl/index.js +0 -52
  93. package/dist/esm/util/InMemoryReporter.d.ts +0 -31
  94. package/dist/esm/util/InMemoryReporter.js +0 -49
  95. package/dist/esm/util/LintFileResult.d.ts +0 -14
  96. package/dist/esm/util/LintFileResult.js +0 -2
  97. package/dist/esm/util/async.d.ts +0 -3
  98. package/dist/esm/util/async.js +0 -4
  99. package/dist/esm/util/cache/CSpellLintResultCache.d.ts +0 -20
  100. package/dist/esm/util/cache/CSpellLintResultCache.js +0 -2
  101. package/dist/esm/util/cache/CacheOptions.d.ts +0 -34
  102. package/dist/esm/util/cache/CacheOptions.js +0 -2
  103. package/dist/esm/util/cache/DiskCache.d.ts +0 -63
  104. package/dist/esm/util/cache/DiskCache.js +0 -214
  105. package/dist/esm/util/cache/DummyCache.d.ts +0 -11
  106. package/dist/esm/util/cache/DummyCache.js +0 -18
  107. package/dist/esm/util/cache/ObjectCollection.d.ts +0 -17
  108. package/dist/esm/util/cache/ObjectCollection.js +0 -127
  109. package/dist/esm/util/cache/createCache.d.ts +0 -31
  110. package/dist/esm/util/cache/createCache.js +0 -69
  111. package/dist/esm/util/cache/file-entry-cache.d.mts +0 -4
  112. package/dist/esm/util/cache/file-entry-cache.mjs +0 -5
  113. package/dist/esm/util/cache/fileEntryCache.d.ts +0 -9
  114. package/dist/esm/util/cache/fileEntryCache.js +0 -79
  115. package/dist/esm/util/cache/index.d.ts +0 -4
  116. package/dist/esm/util/cache/index.js +0 -2
  117. package/dist/esm/util/canUseColor.d.ts +0 -2
  118. package/dist/esm/util/canUseColor.js +0 -10
  119. package/dist/esm/util/configFileHelper.d.ts +0 -15
  120. package/dist/esm/util/configFileHelper.js +0 -43
  121. package/dist/esm/util/constants.d.ts +0 -6
  122. package/dist/esm/util/constants.js +0 -6
  123. package/dist/esm/util/errors.d.ts +0 -24
  124. package/dist/esm/util/errors.js +0 -60
  125. package/dist/esm/util/extractContext.d.ts +0 -5
  126. package/dist/esm/util/extractContext.js +0 -75
  127. package/dist/esm/util/fileHelper.d.ts +0 -44
  128. package/dist/esm/util/fileHelper.js +0 -165
  129. package/dist/esm/util/glob.d.ts +0 -45
  130. package/dist/esm/util/glob.js +0 -147
  131. package/dist/esm/util/pad.d.ts +0 -45
  132. package/dist/esm/util/pad.js +0 -191
  133. package/dist/esm/util/prefetch.d.ts +0 -2
  134. package/dist/esm/util/prefetch.js +0 -15
  135. package/dist/esm/util/reporters.d.ts +0 -30
  136. package/dist/esm/util/reporters.js +0 -209
  137. package/dist/esm/util/stdin.d.ts +0 -2
  138. package/dist/esm/util/stdin.js +0 -5
  139. package/dist/esm/util/stdinUrl.d.ts +0 -9
  140. package/dist/esm/util/stdinUrl.js +0 -26
  141. package/dist/esm/util/table.d.ts +0 -41
  142. package/dist/esm/util/table.js +0 -115
  143. package/dist/esm/util/timer.d.ts +0 -4
  144. package/dist/esm/util/timer.js +0 -9
  145. package/dist/esm/util/types.d.ts +0 -7
  146. package/dist/esm/util/types.js +0 -5
  147. package/dist/esm/util/unindent.d.ts +0 -14
  148. package/dist/esm/util/unindent.js +0 -55
  149. package/dist/esm/util/util.d.ts +0 -14
  150. package/dist/esm/util/util.js +0 -30
  151. package/dist/esm/util/writeFile.d.ts +0 -3
  152. package/dist/esm/util/writeFile.js +0 -30
@@ -1,83 +0,0 @@
1
- import * as path from 'node:path';
2
- import { unknownWordsChoices } from '@cspell/cspell-types';
3
- import { calcExcludeGlobInfo } from '../util/glob.js';
4
- const defaultContextRange = 20;
5
- export class LintRequest {
6
- fileGlobs;
7
- options;
8
- reporter;
9
- locale;
10
- configFile;
11
- excludes;
12
- root;
13
- showContext;
14
- enableGlobDot;
15
- fileLists;
16
- files;
17
- cspellSettingsFromCliOptions;
18
- constructor(fileGlobs, options, reporter) {
19
- this.fileGlobs = fileGlobs;
20
- this.options = options;
21
- this.reporter = reporter;
22
- this.root = path.resolve(options.root || process.cwd());
23
- this.configFile = options.config;
24
- this.excludes = calcExcludeGlobInfo(this.root, options.exclude);
25
- this.locale = options.locale ?? options.local ?? '';
26
- this.enableGlobDot = options.dot;
27
- this.showContext = Math.max(options.showContext === true ? defaultContextRange : options.showContext ? options.showContext : 0, 0);
28
- this.fileLists = (options.fileList ?? options.fileLists) || [];
29
- this.files = mergeFiles(options.file, options.files);
30
- const noConfigSearch = options.configSearch === false ? true : options.configSearch === true ? false : undefined;
31
- const dictionaries = [
32
- ...(options.disableDictionary ?? []).map((d) => `!${d}`), // first disable dictionaries
33
- ...(options.dictionary ?? []).map((d) => `!!${d}`), // Use `!!` to ensure dictionaries are enabled
34
- ];
35
- const languageSettings = [
36
- // Use `*` to match all languages and locales
37
- { languageId: '*', locale: '*', dictionaries },
38
- ];
39
- this.cspellSettingsFromCliOptions = {
40
- ...(noConfigSearch !== undefined ? { noConfigSearch } : {}),
41
- ...extractUnknownWordsConfig(options),
42
- languageSettings,
43
- };
44
- }
45
- }
46
- function mergeFiles(a, b) {
47
- const files = merge(a, b);
48
- if (!files)
49
- return undefined;
50
- return [...new Set(files.flatMap((a) => a.split('\n').map((a) => a.trim())).filter((a) => !!a))];
51
- }
52
- function merge(a, b) {
53
- if (!a)
54
- return b;
55
- if (!b)
56
- return a;
57
- return [...a, ...b];
58
- }
59
- export function extractUnknownWordsConfig(options) {
60
- const config = {};
61
- if (!options.report)
62
- return config;
63
- switch (options.report) {
64
- case 'all': {
65
- config.unknownWords = unknownWordsChoices.ReportAll;
66
- break;
67
- }
68
- case 'simple': {
69
- config.unknownWords = unknownWordsChoices.ReportSimple;
70
- break;
71
- }
72
- case 'typos': {
73
- config.unknownWords = unknownWordsChoices.ReportCommonTypos;
74
- break;
75
- }
76
- case 'flagged': {
77
- config.unknownWords = unknownWordsChoices.ReportFlagged;
78
- break;
79
- }
80
- }
81
- return config;
82
- }
83
- //# sourceMappingURL=LintRequest.js.map
@@ -1,3 +0,0 @@
1
- export { runLint } from './lint.js';
2
- export { extractUnknownWordsConfig, LintRequest } from './LintRequest.js';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1,3 +0,0 @@
1
- export { runLint } from './lint.js';
2
- export { extractUnknownWordsConfig, LintRequest } from './LintRequest.js';
3
- //# sourceMappingURL=index.js.map
@@ -1,8 +0,0 @@
1
- import type { RunResult } from '@cspell/cspell-types';
2
- import type { LintRequest } from './LintRequest.js';
3
- export declare function runLint(cfg: LintRequest): Promise<RunResult>;
4
- export declare class LinterError extends Error {
5
- constructor(message: string);
6
- toString(): string;
7
- }
8
- //# sourceMappingURL=lint.d.ts.map
@@ -1,515 +0,0 @@
1
- import * as path from 'node:path';
2
- import { format } from 'node:util';
3
- import { isAsyncIterable, operators, opFilter, pipeAsync } from '@cspell/cspell-pipe';
4
- import { opMap, pipe } from '@cspell/cspell-pipe/sync';
5
- import { MessageTypes } from '@cspell/cspell-types';
6
- import { toFileURL } from '@cspell/url';
7
- import chalk from 'chalk';
8
- import { _debug as cspellDictionaryDebug } from 'cspell-dictionary';
9
- import { findRepoRoot, GitIgnore } from 'cspell-gitignore';
10
- import { GlobMatcher } from 'cspell-glob';
11
- import { ENV_CSPELL_GLOB_ROOT, extractDependencies, extractImportErrors, getDefaultConfigLoader, getDictionary, isBinaryFile as cspellIsBinaryFile, mergeSettings, setLogger, shouldCheckDocument, spellCheckDocument, Text as cspellText, } from 'cspell-lib';
12
- import { console } from '../console.js';
13
- import { getEnvironmentVariable, setEnvironmentVariable, truthy } from '../environment.js';
14
- import { getFeatureFlags } from '../featureFlags/index.js';
15
- import { npmPackage } from '../pkgInfo.js';
16
- import { calcCacheSettings, createCache } from '../util/cache/index.js';
17
- import { readConfig } from '../util/configFileHelper.js';
18
- import { CheckFailed, toApplicationError, toError } from '../util/errors.js';
19
- import { extractContext } from '../util/extractContext.js';
20
- import { fileInfoToDocument, filenameToUri, findFiles, isBinaryFile, isFile, isNotDir, readFileInfo, readFileListFiles, relativeToCwd, resolveFilename, } from '../util/fileHelper.js';
21
- import { buildGlobMatcher, extractGlobsFromMatcher, extractPatterns, normalizeFileOrGlobsToRoot, normalizeGlobsToRoot, } from '../util/glob.js';
22
- import { prefetchIterable } from '../util/prefetch.js';
23
- import { extractReporterIssueOptions, LintReporter, mergeReportIssueOptions } from '../util/reporters.js';
24
- import { getTimeMeasurer } from '../util/timer.js';
25
- import * as util from '../util/util.js';
26
- import { writeFileOrStream } from '../util/writeFile.js';
27
- const version = npmPackage.version;
28
- const BATCH_SIZE = 8;
29
- const debugStats = false;
30
- const { opFilterAsync } = operators;
31
- export async function runLint(cfg) {
32
- const reporter = new LintReporter(cfg.reporter, cfg.options);
33
- const configErrors = new Set();
34
- const timer = getTimeMeasurer();
35
- const logDictRequests = truthy(getEnvironmentVariable('CSPELL_ENABLE_DICTIONARY_LOGGING'));
36
- if (logDictRequests) {
37
- cspellDictionaryDebug.cacheDictionaryEnableLogging(true);
38
- }
39
- const lintResult = await run();
40
- if (logDictRequests) {
41
- await writeDictionaryLog();
42
- }
43
- await reporter.result(lintResult);
44
- const elapsed = timer();
45
- if (getFeatureFlags().getFlag('timer')) {
46
- console.log(`Elapsed Time: ${elapsed.toFixed(2)}ms`);
47
- }
48
- return lintResult;
49
- function prefetch(filename, configInfo, cache) {
50
- if (isBinaryFile(filename, cfg.root))
51
- return { filename, result: Promise.resolve({ skip: true }) };
52
- const reportIssueOptions = extractReporterIssueOptions(configInfo.config);
53
- async function fetch() {
54
- const getElapsedTimeMs = getTimeMeasurer();
55
- const cachedResult = await cache.getCachedLintResults(filename);
56
- if (cachedResult) {
57
- reporter.debug(`Filename: ${filename}, using cache`);
58
- const fileResult = { ...cachedResult, elapsedTimeMs: getElapsedTimeMs() };
59
- return { fileResult };
60
- }
61
- const uri = filenameToUri(filename, cfg.root).href;
62
- const checkResult = await shouldCheckDocument({ uri }, {}, configInfo.config);
63
- if (!checkResult.shouldCheck)
64
- return { skip: true };
65
- const fileInfo = await readFileInfo(filename, undefined, true);
66
- return { fileInfo, reportIssueOptions };
67
- }
68
- const result = fetch();
69
- return { filename, result };
70
- }
71
- async function processFile(filename, configInfo, cache, prefetch) {
72
- if (prefetch?.fileResult)
73
- return prefetch.fileResult;
74
- const getElapsedTimeMs = getTimeMeasurer();
75
- const reportIssueOptions = prefetch?.reportIssueOptions;
76
- const cachedResult = await cache.getCachedLintResults(filename);
77
- if (cachedResult) {
78
- reporter.debug(`Filename: ${filename}, using cache`);
79
- return { ...cachedResult, elapsedTimeMs: getElapsedTimeMs(), reportIssueOptions };
80
- }
81
- const result = {
82
- fileInfo: {
83
- filename,
84
- },
85
- issues: [],
86
- processed: false,
87
- errors: 0,
88
- configErrors: 0,
89
- elapsedTimeMs: 0,
90
- reportIssueOptions,
91
- };
92
- const fileInfo = prefetch?.fileInfo || (await readFileInfo(filename, undefined, true));
93
- if (fileInfo.errorCode) {
94
- if (fileInfo.errorCode !== 'EISDIR' && cfg.options.mustFindFiles) {
95
- const err = new LinterError(`File not found: "${filename}"`);
96
- reporter.error('Linter:', err);
97
- result.errors += 1;
98
- }
99
- return result;
100
- }
101
- const doc = fileInfoToDocument(fileInfo, cfg.options.languageId, cfg.locale);
102
- const { text } = fileInfo;
103
- result.fileInfo = fileInfo;
104
- let spellResult = {};
105
- reporter.info(`Checking: ${filename}, File type: ${doc.languageId ?? 'auto'}, Language: ${doc.locale ?? 'default'}`, MessageTypes.Info);
106
- try {
107
- const { showSuggestions: generateSuggestions, validateDirectives, skipValidation } = cfg.options;
108
- const numSuggestions = configInfo.config.numSuggestions ?? 5;
109
- const validateOptions = util.clean({
110
- generateSuggestions,
111
- numSuggestions,
112
- validateDirectives,
113
- skipValidation,
114
- });
115
- const r = await spellCheckDocument(doc, validateOptions, configInfo.config);
116
- // console.warn('filename: %o %o', path.relative(process.cwd(), filename), r.perf);
117
- spellResult = r;
118
- result.processed = r.checked;
119
- result.perf = r.perf ? { ...r.perf } : undefined;
120
- result.issues = cspellText.calculateTextDocumentOffsets(doc.uri, text, r.issues).map(mapIssue);
121
- }
122
- catch (e) {
123
- reporter.error(`Failed to process "${filename}"`, toError(e));
124
- result.errors += 1;
125
- }
126
- result.elapsedTimeMs = getElapsedTimeMs();
127
- const config = spellResult.settingsUsed ?? {};
128
- result.reportIssueOptions = mergeReportIssueOptions(spellResult.settingsUsed || configInfo.config, reportIssueOptions);
129
- result.configErrors += await reportConfigurationErrors(config);
130
- const elapsed = result.elapsedTimeMs;
131
- const dictionaries = config.dictionaries || [];
132
- reporter.info(`Checked: ${filename}, File type: ${config.languageId}, Language: ${config.language} ... Issues: ${result.issues.length} ${elapsed.toFixed(2)}ms`, MessageTypes.Info);
133
- reporter.info(`Config file Used: ${spellResult.localConfigFilepath || configInfo.source}`, MessageTypes.Info);
134
- reporter.info(`Dictionaries Used: ${dictionaries.join(', ')}`, MessageTypes.Info);
135
- if (cfg.options.debug) {
136
- const { id: _id, name: _name, __imports, __importRef, ...cfg } = config;
137
- const debugCfg = {
138
- filename,
139
- languageId: doc.languageId ?? cfg.languageId ?? 'default',
140
- // eslint-disable-next-line unicorn/no-null
141
- config: { ...cfg, source: null },
142
- source: spellResult.localConfigFilepath,
143
- };
144
- reporter.debug(JSON.stringify(debugCfg, undefined, 2));
145
- }
146
- const dep = calcDependencies(config);
147
- cache.setCachedLintResults(result, dep.files);
148
- return result;
149
- }
150
- function mapIssue({ doc: _, ...tdo }) {
151
- const context = cfg.showContext ? extractContext(tdo, cfg.showContext) : undefined;
152
- return util.clean({ ...tdo, context });
153
- }
154
- async function processFiles(files, configInfo, cacheSettings) {
155
- const fileCount = Array.isArray(files) ? files.length : undefined;
156
- const status = runResult();
157
- const cache = createCache(cacheSettings);
158
- const failFast = cfg.options.failFast ?? configInfo.config.failFast ?? false;
159
- function* prefetchFiles(files) {
160
- const iter = prefetchIterable(pipe(files, opMap((filename) => prefetch(filename, configInfo, cache))), BATCH_SIZE);
161
- for (const v of iter) {
162
- yield v;
163
- }
164
- }
165
- async function* prefetchFilesAsync(files) {
166
- for await (const filename of files) {
167
- yield prefetch(filename, configInfo, cache);
168
- }
169
- }
170
- const emptyResult = {
171
- fileInfo: { filename: '' },
172
- issues: [],
173
- processed: false,
174
- errors: 0,
175
- configErrors: 0,
176
- elapsedTimeMs: 1,
177
- reportIssueOptions: undefined,
178
- };
179
- async function processPrefetchFileResult(pf, index) {
180
- const { filename, result: pFetchResult } = pf;
181
- const getElapsedTimeMs = getTimeMeasurer();
182
- const fetchResult = await pFetchResult;
183
- reporter.emitProgressBegin(filename, index, fileCount ?? index);
184
- if (fetchResult?.skip) {
185
- return {
186
- filename,
187
- fileNum: index,
188
- result: { ...emptyResult, fileInfo: { filename }, elapsedTimeMs: getElapsedTimeMs() },
189
- };
190
- }
191
- const result = await processFile(filename, configInfo, cache, fetchResult);
192
- return { filename, fileNum: index, result };
193
- }
194
- async function* loadAndProcessFiles() {
195
- let i = 0;
196
- if (isAsyncIterable(files)) {
197
- for await (const pf of prefetchFilesAsync(files)) {
198
- yield processPrefetchFileResult(pf, ++i);
199
- }
200
- }
201
- else {
202
- for (const pf of prefetchFiles(files)) {
203
- await pf.result;
204
- yield processPrefetchFileResult(pf, ++i);
205
- }
206
- // const iter = prefetchIterable(
207
- // pipe(
208
- // prefetchFiles(files),
209
- // opMap(async (pf) => {
210
- // return processPrefetchFileResult(pf, ++i);
211
- // }),
212
- // ),
213
- // BATCH_SIZE,
214
- // );
215
- // yield* iter;
216
- }
217
- }
218
- for await (const fileP of loadAndProcessFiles()) {
219
- const { filename, fileNum, result } = fileP;
220
- status.files += 1;
221
- status.cachedFiles = (status.cachedFiles || 0) + (result.cached ? 1 : 0);
222
- const numIssues = reporter.emitProgressComplete(filename, fileNum, fileCount ?? fileNum, result);
223
- if (numIssues || result.errors) {
224
- status.filesWithIssues.add(relativeToCwd(filename, cfg.root));
225
- status.issues += numIssues;
226
- status.errors += result.errors;
227
- if (failFast) {
228
- return status;
229
- }
230
- }
231
- status.errors += result.configErrors;
232
- }
233
- cache.reconcile();
234
- return status;
235
- }
236
- function calcDependencies(config) {
237
- const { configFiles, dictionaryFiles } = extractDependencies(config);
238
- return { files: [...configFiles, ...dictionaryFiles] };
239
- }
240
- async function reportConfigurationErrors(config) {
241
- const errors = extractImportErrors(config);
242
- let count = 0;
243
- errors.forEach((ref) => {
244
- const key = ref.error.toString();
245
- if (configErrors.has(key))
246
- return;
247
- configErrors.add(key);
248
- count += 1;
249
- reporter.error('Configuration', ref.error);
250
- });
251
- const dictCollection = await getDictionary(config);
252
- dictCollection.dictionaries.forEach((dict) => {
253
- const dictErrors = dict.getErrors?.() || [];
254
- const msg = `Dictionary Error with (${dict.name})`;
255
- dictErrors.forEach((error) => {
256
- const key = msg + error.toString();
257
- if (configErrors.has(key))
258
- return;
259
- configErrors.add(key);
260
- count += 1;
261
- reporter.error(msg, error);
262
- });
263
- });
264
- return count;
265
- }
266
- function countConfigErrors(configInfo) {
267
- return reportConfigurationErrors(configInfo.config);
268
- }
269
- async function run() {
270
- if (cfg.options.root) {
271
- setEnvironmentVariable(ENV_CSPELL_GLOB_ROOT, cfg.root);
272
- }
273
- const configInfo = await readConfig(cfg.configFile, cfg.root, cfg.options.stopConfigSearchAt);
274
- if (cfg.options.defaultConfiguration !== undefined) {
275
- configInfo.config.loadDefaultConfiguration = cfg.options.defaultConfiguration;
276
- }
277
- configInfo.config = mergeSettings(configInfo.config, cfg.cspellSettingsFromCliOptions);
278
- const reporterConfig = util.clean({
279
- maxNumberOfProblems: configInfo.config.maxNumberOfProblems,
280
- maxDuplicateProblems: configInfo.config.maxDuplicateProblems,
281
- minWordLength: configInfo.config.minWordLength,
282
- ...cfg.options,
283
- console,
284
- });
285
- const reporters = cfg.options.reporter ?? configInfo.config.reporters;
286
- reporter.config = reporterConfig;
287
- await reporter.loadReportersAndFinalize(reporters);
288
- setLogger(getLoggerFromReporter(reporter));
289
- const globInfo = await determineGlobs(configInfo, cfg);
290
- const { fileGlobs, excludeGlobs } = globInfo;
291
- const hasFileLists = !!cfg.fileLists.length;
292
- if (!fileGlobs.length && !hasFileLists && !cfg.files?.length) {
293
- // Nothing to do.
294
- return runResult();
295
- }
296
- header(fileGlobs, excludeGlobs);
297
- checkGlobs(fileGlobs, reporter);
298
- reporter.info(`Config Files Found:\n ${configInfo.source}\n`, MessageTypes.Info);
299
- const configErrors = await countConfigErrors(configInfo);
300
- if (configErrors && cfg.options.exitCode !== false && !cfg.options.continueOnError) {
301
- return runResult({ errors: configErrors });
302
- }
303
- // Get Exclusions from the config files.
304
- const { root } = cfg;
305
- try {
306
- const cacheSettings = await calcCacheSettings(configInfo.config, { ...cfg.options, version }, root);
307
- const files = await determineFilesToCheck(configInfo, cfg, reporter, globInfo);
308
- const result = await processFiles(files, configInfo, cacheSettings);
309
- if (configErrors && cfg.options.exitCode !== false) {
310
- result.errors ||= configErrors;
311
- }
312
- debugStats && console.error('stats: %o', getDefaultConfigLoader().getStats());
313
- return result;
314
- }
315
- catch (e) {
316
- const err = toApplicationError(e);
317
- reporter.error('Linter', err);
318
- return runResult({ errors: 1 });
319
- }
320
- }
321
- function header(files, cliExcludes) {
322
- const formattedFiles = files.length > 100 ? [...files.slice(0, 100), '...'] : files;
323
- reporter.info(`
324
- cspell;
325
- Date: ${new Date().toUTCString()}
326
- Options:
327
- verbose: ${yesNo(!!cfg.options.verbose)}
328
- config: ${cfg.configFile || 'default'}
329
- exclude: ${cliExcludes.join('\n ')}
330
- files: ${formattedFiles}
331
- wordsOnly: ${yesNo(!!cfg.options.wordsOnly)}
332
- unique: ${yesNo(!!cfg.options.unique)}
333
- `, MessageTypes.Info);
334
- }
335
- }
336
- function checkGlobs(globs, reporter) {
337
- globs
338
- .filter((g) => g.startsWith("'") || g.endsWith("'"))
339
- .map((glob) => chalk.yellow(glob))
340
- .forEach((glob) => reporter.error('Linter', new CheckFailed(`Glob starting or ending with ' (single quote) is not likely to match any files: ${glob}.`)));
341
- }
342
- async function determineGlobs(configInfo, cfg) {
343
- const useGitignore = cfg.options.gitignore ?? configInfo.config.useGitignore ?? false;
344
- const gitignoreRoots = cfg.options.gitignoreRoot ?? configInfo.config.gitignoreRoot;
345
- const gitIgnore = useGitignore ? await generateGitIgnore(gitignoreRoots) : undefined;
346
- const cliGlobs = cfg.fileGlobs;
347
- const allGlobs = (cliGlobs.length && cliGlobs) || (cfg.options.filterFiles !== false && configInfo.config.files) || [];
348
- const combinedGlobs = await normalizeFileOrGlobsToRoot(allGlobs, cfg.root);
349
- const cliExcludeGlobs = extractPatterns(cfg.excludes).map((p) => p.glob);
350
- const normalizedExcludes = normalizeGlobsToRoot(cliExcludeGlobs, cfg.root, true);
351
- const includeGlobs = combinedGlobs.filter((g) => !g.startsWith('!'));
352
- const excludeGlobs = [
353
- ...combinedGlobs.filter((g) => g.startsWith('!')).map((g) => g.slice(1)),
354
- ...normalizedExcludes,
355
- ];
356
- const fileGlobs = includeGlobs;
357
- const appGlobs = { allGlobs, gitIgnore, fileGlobs, excludeGlobs, normalizedExcludes };
358
- return appGlobs;
359
- }
360
- async function determineFilesToCheck(configInfo, cfg, reporter, globInfo) {
361
- async function _determineFilesToCheck() {
362
- const { fileLists } = cfg;
363
- const hasFileLists = !!fileLists.length;
364
- const { allGlobs, gitIgnore, fileGlobs, excludeGlobs, normalizedExcludes } = globInfo;
365
- // Get Exclusions from the config files.
366
- const { root } = cfg;
367
- const globsToExcludeRaw = [...(configInfo.config.ignorePaths || []), ...excludeGlobs];
368
- const globsToExclude = globsToExcludeRaw.filter((g) => !globPattern(g).startsWith('!'));
369
- if (globsToExclude.length !== globsToExcludeRaw.length) {
370
- const globs = globsToExcludeRaw.map((g) => globPattern(g)).filter((g) => g.startsWith('!'));
371
- const msg = `Negative glob exclusions are not supported: ${globs.join(', ')}`;
372
- reporter.info(msg, MessageTypes.Warning);
373
- }
374
- const globMatcher = buildGlobMatcher(globsToExclude, root, true);
375
- const ignoreGlobs = extractGlobsFromMatcher(globMatcher);
376
- // cspell:word nodir
377
- const globOptions = {
378
- root,
379
- cwd: root,
380
- ignore: [...ignoreGlobs, ...normalizedExcludes],
381
- nodir: true,
382
- };
383
- const enableGlobDot = cfg.enableGlobDot ?? configInfo.config.enableGlobDot;
384
- if (enableGlobDot !== undefined) {
385
- globOptions.dot = enableGlobDot;
386
- }
387
- const opFilterExcludedFiles = opFilter(filterOutExcludedFilesFn(globMatcher));
388
- const includeFilter = createIncludeFileFilterFn(allGlobs, root, enableGlobDot);
389
- const rawCliFiles = cfg.files?.map((file) => resolveFilename(file, root)).filter(includeFilter);
390
- const cliFiles = cfg.options.mustFindFiles
391
- ? rawCliFiles
392
- : rawCliFiles && pipeAsync(rawCliFiles, opFilterAsync(isFile));
393
- const foundFiles = hasFileLists
394
- ? concatAsyncIterables(cliFiles, await useFileLists(fileLists, includeFilter))
395
- : cliFiles || (await findFiles(fileGlobs, globOptions));
396
- const filtered = gitIgnore ? await gitIgnore.filterOutIgnored(foundFiles) : foundFiles;
397
- const files = isAsyncIterable(filtered)
398
- ? pipeAsync(filtered, opFilterExcludedFiles)
399
- : [...pipe(filtered, opFilterExcludedFiles)];
400
- return files;
401
- }
402
- function isExcluded(filename, globMatcherExclude) {
403
- if (cspellIsBinaryFile(toFileURL(filename))) {
404
- return true;
405
- }
406
- const { root } = cfg;
407
- const absFilename = path.resolve(root, filename);
408
- const r = globMatcherExclude.matchEx(absFilename);
409
- if (r.matched) {
410
- const { glob, source } = extractGlobSource(r.pattern);
411
- reporter.info(`Excluded File: ${path.relative(root, absFilename)}; Excluded by ${glob} from ${source}`, MessageTypes.Info);
412
- }
413
- return r.matched;
414
- }
415
- function filterOutExcludedFilesFn(globMatcherExclude) {
416
- const patterns = globMatcherExclude.patterns;
417
- const excludeInfo = patterns
418
- .map(extractGlobSource)
419
- .map(({ glob, source }) => `Glob: ${glob} from ${source}`)
420
- .filter(util.uniqueFn());
421
- reporter.info(`Exclusion Globs: \n ${excludeInfo.join('\n ')}\n`, MessageTypes.Info);
422
- return (filename) => !isExcluded(filename, globMatcherExclude);
423
- }
424
- return _determineFilesToCheck();
425
- }
426
- function extractGlobSource(g) {
427
- const { glob, rawGlob, source } = g;
428
- return {
429
- glob: rawGlob || glob,
430
- source,
431
- };
432
- }
433
- function runResult(init = {}) {
434
- const { files = 0, filesWithIssues = new Set(), issues = 0, errors = 0, cachedFiles = 0 } = init;
435
- return { files, filesWithIssues, issues, errors, cachedFiles };
436
- }
437
- function yesNo(value) {
438
- return value ? 'Yes' : 'No';
439
- }
440
- function getLoggerFromReporter(reporter) {
441
- const log = (...params) => {
442
- const msg = format(...params);
443
- reporter.info(msg, 'Info');
444
- };
445
- const error = (...params) => {
446
- const msg = format(...params);
447
- const err = { message: '', name: 'error', toString: () => '' };
448
- reporter.error(msg, err);
449
- };
450
- const warn = (...params) => {
451
- const msg = format(...params);
452
- reporter.info(msg, 'Warning');
453
- };
454
- return {
455
- log,
456
- warn,
457
- error,
458
- };
459
- }
460
- async function generateGitIgnore(roots) {
461
- const root = (typeof roots === 'string' ? [roots].filter((r) => !!r) : roots) || [];
462
- if (!root?.length) {
463
- const cwd = process.cwd();
464
- const repo = (await findRepoRoot(cwd)) || cwd;
465
- root.push(repo);
466
- }
467
- return new GitIgnore(root?.map((p) => path.resolve(p)));
468
- }
469
- async function useFileLists(fileListFiles, filterFiles) {
470
- const files = readFileListFiles(fileListFiles);
471
- return pipeAsync(files, opFilter(filterFiles), opFilterAsync(isNotDir));
472
- }
473
- function createIncludeFileFilterFn(includeGlobPatterns, root, dot) {
474
- if (!includeGlobPatterns?.length) {
475
- return () => true;
476
- }
477
- const patterns = includeGlobPatterns.map((g) => (g === '.' ? '/**' : g));
478
- const options = { root, mode: 'include' };
479
- if (dot !== undefined) {
480
- options.dot = dot;
481
- }
482
- const globMatcher = new GlobMatcher(patterns, options);
483
- return (file) => globMatcher.match(file);
484
- }
485
- async function* concatAsyncIterables(...iterables) {
486
- for (const iter of iterables) {
487
- if (!iter)
488
- continue;
489
- yield* iter;
490
- }
491
- }
492
- async function writeDictionaryLog() {
493
- const fieldsCsv = getEnvironmentVariable('CSPELL_ENABLE_DICTIONARY_LOG_FIELDS') || 'time, word, value';
494
- const fields = fieldsCsv.split(',').map((f) => f.trim());
495
- const header = fields.join(', ') + '\n';
496
- const lines = cspellDictionaryDebug
497
- .cacheDictionaryGetLog()
498
- .filter((d) => d.method === 'has')
499
- .map((d) => fields.map((f) => (f in d ? `${d[f]}` : '')).join(', '));
500
- const data = header + lines.join('\n') + '\n';
501
- const filename = getEnvironmentVariable('CSPELL_ENABLE_DICTIONARY_LOG_FILE') || 'cspell-dictionary-log.csv';
502
- await writeFileOrStream(filename, data);
503
- }
504
- function globPattern(g) {
505
- return typeof g === 'string' ? g : g.glob;
506
- }
507
- export class LinterError extends Error {
508
- constructor(message) {
509
- super(message);
510
- }
511
- toString() {
512
- return this.message;
513
- }
514
- }
515
- //# sourceMappingURL=lint.js.map
@@ -1,15 +0,0 @@
1
- import type { CSpellReporter, ReporterConfiguration } from '@cspell/cspell-types';
2
- import type { IConsole } from './console.js';
3
- import type { LinterCliOptions } from './options.js';
4
- export type ReporterConsole = IConsole;
5
- export interface CSpellReporterConfiguration extends Readonly<ReporterConfiguration>, Readonly<LinterCliOptions> {
6
- /**
7
- * The console to use for reporting.
8
- * @since 8.11.1
9
- */
10
- readonly console?: ReporterConsole;
11
- }
12
- export interface CSpellReporterModule {
13
- getReporter: <T>(settings: T, config: CSpellReporterConfiguration) => CSpellReporter;
14
- }
15
- //# sourceMappingURL=models.d.ts.map
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=models.js.map