cspell 9.1.2 → 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
package/dist/esm/app.mjs DELETED
@@ -1,34 +0,0 @@
1
- import { Option as CommanderOption, program } from 'commander';
2
- import { satisfies as semverSatisfies } from 'semver';
3
- import { commandCheck } from './commandCheck.js';
4
- import { commandDictionaries } from './commandDictionaries.js';
5
- import { commandInit } from './commandInit.js';
6
- import { commandLink } from './commandLink.js';
7
- import { commandLint } from './commandLint.js';
8
- import { commandSuggestion } from './commandSuggestion.js';
9
- import { commandTrace } from './commandTrace.js';
10
- import { npmPackage } from './pkgInfo.js';
11
- import { ApplicationError } from './util/errors.js';
12
- export { ApplicationError, CheckFailed } from './util/errors.js';
13
- export async function run(command, argv) {
14
- const prog = command || program;
15
- const args = argv || process.argv;
16
- prog.exitOverride();
17
- prog.version(npmPackage.version).description('Spelling Checker for Code').name('cspell');
18
- if (!semverSatisfies(process.versions.node, npmPackage.engines.node)) {
19
- throw new ApplicationError(`Unsupported NodeJS version (${process.versions.node}); ${npmPackage.engines.node} is required`);
20
- }
21
- const optionFlags = new CommanderOption('-f,--flag <flag:value>', 'Declare an execution flag value')
22
- .hideHelp()
23
- .argParser((value, prev) => prev?.concat(value) || [value]);
24
- commandLint(prog).addOption(optionFlags);
25
- commandTrace(prog).addOption(optionFlags);
26
- commandCheck(prog).addOption(optionFlags);
27
- commandSuggestion(prog).addOption(optionFlags);
28
- commandInit(prog).addOption(optionFlags);
29
- commandLink(prog);
30
- commandDictionaries(prog);
31
- prog.exitOverride();
32
- await prog.parseAsync(args);
33
- }
34
- //# sourceMappingURL=app.mjs.map
@@ -1,17 +0,0 @@
1
- import type { CSpellReporter, RunResult } from '@cspell/cspell-types';
2
- import type { CheckTextInfo, FeatureFlags, TraceWordResult } from 'cspell-lib';
3
- import { type InitOptions } from './config/index.js';
4
- import type { TimedSuggestionsForWordResult } from './emitters/suggestionsEmitter.js';
5
- import type { BaseOptions, LegacyOptions, LinterCliOptions, SuggestionOptions, TraceOptions } from './options.js';
6
- export { listDictionaries } from './dictionaries/index.js';
7
- export type { TraceResult } from 'cspell-lib';
8
- export { IncludeExcludeFlag } from 'cspell-lib';
9
- export type AppError = NodeJS.ErrnoException;
10
- export declare function lint(fileGlobs: string[], options: LinterCliOptions, reporter?: CSpellReporter): Promise<RunResult>;
11
- export declare function trace(words: string[], options: TraceOptions): AsyncIterableIterator<TraceWordResult>;
12
- export type CheckTextResult = CheckTextInfo;
13
- export declare function checkText(filename: string, options: BaseOptions & LegacyOptions): Promise<CheckTextResult>;
14
- export declare function suggestions(words: string[], options: SuggestionOptions): AsyncIterable<TimedSuggestionsForWordResult>;
15
- export declare function createInit(options: InitOptions): Promise<void>;
16
- export declare function parseApplicationFeatureFlags(flags: string[] | undefined): FeatureFlags;
17
- //# sourceMappingURL=application.d.mts.map
@@ -1,99 +0,0 @@
1
- import { opMap, opTap, pipeAsync, toAsyncIterable } from '@cspell/cspell-pipe';
2
- import { checkTextDocument, getDefaultSettings, getGlobalSettingsAsync, mergeSettings, SuggestionError, suggestionsForWords, traceWordsAsync, } from 'cspell-lib';
3
- import { getReporter } from './cli-reporter.js';
4
- import { configInit } from './config/index.js';
5
- import { console } from './console.js';
6
- import { getFeatureFlags, parseFeatureFlags } from './featureFlags/index.js';
7
- import { extractUnknownWordsConfig, LintRequest, runLint } from './lint/index.js';
8
- import { fixLegacy } from './options.js';
9
- import { simpleRepl } from './repl/index.js';
10
- import { readConfig } from './util/configFileHelper.js';
11
- import { fileInfoToDocument, readFileInfo } from './util/fileHelper.js';
12
- import { finalizeReporter } from './util/reporters.js';
13
- import { readStdin } from './util/stdin.js';
14
- import { getTimeMeasurer } from './util/timer.js';
15
- import * as util from './util/util.js';
16
- export { listDictionaries } from './dictionaries/index.js';
17
- export { IncludeExcludeFlag } from 'cspell-lib';
18
- export function lint(fileGlobs, options, reporter) {
19
- options = fixLegacy(options);
20
- const unknownWordsConfig = extractUnknownWordsConfig(options);
21
- const useOptions = { ...options, ...unknownWordsConfig };
22
- const reporterOptions = { ...useOptions, console };
23
- const cfg = new LintRequest(fileGlobs, useOptions, finalizeReporter(reporter) ?? getReporter({ ...useOptions, fileGlobs }, reporterOptions));
24
- return runLint(cfg);
25
- }
26
- export async function* trace(words, options) {
27
- options = fixLegacy(options);
28
- const iWords = options.stdin ? toAsyncIterable(words, readStdin()) : words;
29
- const { languageId, locale, allowCompoundWords, ignoreCase } = options;
30
- const configFile = await readConfig(options.config, undefined);
31
- const loadDefault = options.defaultConfiguration ?? configFile.config.loadDefaultConfiguration ?? true;
32
- const additionalSettings = {};
33
- if (options.dictionary) {
34
- additionalSettings.dictionaries = options.dictionary;
35
- }
36
- const config = mergeSettings(await getDefaultSettings(loadDefault), await getGlobalSettingsAsync(), configFile.config, additionalSettings);
37
- yield* traceWordsAsync(iWords, config, util.clean({ languageId, locale, ignoreCase, allowCompoundWords }));
38
- }
39
- export async function checkText(filename, options) {
40
- options = fixLegacy(options);
41
- const fileInfo = await readFileInfo(filename);
42
- const { locale, languageId, validateDirectives } = options;
43
- const doc = fileInfoToDocument(fileInfo, languageId, locale);
44
- const checkOptions = {
45
- configFile: options.config,
46
- validateDirectives,
47
- };
48
- const settingsFromCommandLine = util.clean({
49
- languageId,
50
- language: locale,
51
- loadDefaultConfiguration: options.defaultConfiguration,
52
- });
53
- return checkTextDocument(doc, util.clean({ ...checkOptions }), settingsFromCommandLine);
54
- }
55
- export async function* suggestions(words, options) {
56
- options = fixLegacy(options);
57
- const configFile = await readConfig(options.config, undefined);
58
- let timer;
59
- function tapStart() {
60
- timer = getTimeMeasurer();
61
- }
62
- function mapStart(v) {
63
- tapStart();
64
- return v;
65
- }
66
- function mapEnd(v) {
67
- const elapsedTimeMs = timer?.();
68
- return elapsedTimeMs ? { ...v, elapsedTimeMs } : v;
69
- }
70
- const iWords = options.repl
71
- ? pipeAsync(toAsyncIterable(words, simpleRepl()), opTap(tapStart))
72
- : options.useStdin
73
- ? pipeAsync(toAsyncIterable(words, readStdin()), opTap(tapStart))
74
- : words.map(mapStart);
75
- try {
76
- const results = pipeAsync(suggestionsForWords(iWords, util.clean({ ...options }), configFile.config), opMap(mapEnd));
77
- yield* results;
78
- }
79
- catch (e) {
80
- if (!(e instanceof SuggestionError))
81
- throw e;
82
- console.error(e.message);
83
- process.exitCode = 1;
84
- }
85
- }
86
- export function createInit(options) {
87
- return configInit(options);
88
- }
89
- function registerApplicationFeatureFlags() {
90
- const ff = getFeatureFlags();
91
- const flags = [{ name: 'timer', description: 'Display elapsed time for command.' }];
92
- flags.forEach((flag) => ff.register(flag));
93
- return ff;
94
- }
95
- export function parseApplicationFeatureFlags(flags) {
96
- const ff = registerApplicationFeatureFlags();
97
- return parseFeatureFlags(flags, ff);
98
- }
99
- //# sourceMappingURL=application.mjs.map
@@ -1,38 +0,0 @@
1
- import type { Issue } from '@cspell/cspell-types';
2
- import type { ChalkInstance } from 'chalk';
3
- import { CSpellReporterConfiguration } from './models.js';
4
- import type { LinterCliOptions } from './options.js';
5
- import type { FinalizedReporter } from './util/reporters.js';
6
- export interface TemplateSubstitutions extends Record<string, string> {
7
- $col: string;
8
- $contextFull: string;
9
- $contextLeft: string;
10
- $contextRight: string;
11
- $filename: string;
12
- $padContext: string;
13
- $padRowCol: string;
14
- $row: string;
15
- $suggestions: string;
16
- $text: string;
17
- $uri: string;
18
- $quickFix: string;
19
- $message: string;
20
- $messageColored: string;
21
- }
22
- export interface ReporterIssue extends Issue {
23
- filename: string;
24
- }
25
- interface IOChalk {
26
- readonly chalk: ChalkInstance;
27
- }
28
- export interface ReporterOptions extends Pick<LinterCliOptions, 'color' | 'debug' | 'issues' | 'issuesSummaryReport' | 'legacy' | 'progress' | 'relative' | 'root' | 'showContext' | 'showPerfSummary' | 'showSuggestions' | 'silent' | 'summary' | 'verbose' | 'wordsOnly'> {
29
- fileGlobs: string[];
30
- }
31
- export declare function getReporter(options: ReporterOptions, config?: CSpellReporterConfiguration): FinalizedReporter;
32
- declare function formatIssue(io: IOChalk, templateStr: string, issue: ReporterIssue, maxIssueTextWidth: number): string;
33
- export declare function checkTemplate(template: string): true | Error;
34
- export declare const __testing__: {
35
- formatIssue: typeof formatIssue;
36
- };
37
- export {};
38
- //# sourceMappingURL=cli-reporter.d.ts.map
@@ -1,386 +0,0 @@
1
- import assert from 'node:assert';
2
- import { formatWithOptions } from 'node:util';
3
- import { toFileDirURL, toFilePathOrHref, toFileURL, urlRelative } from '@cspell/url';
4
- import { Chalk } from 'chalk';
5
- import { makeTemplate } from 'chalk-template';
6
- import { isSpellingDictionaryLoadError } from 'cspell-lib';
7
- import { console as customConsole } from './console.js';
8
- import { ApplicationError } from './util/errors.js';
9
- import { uniqueFilterFnGenerator } from './util/util.js';
10
- const templateIssue = `{green $filename}:{yellow $row:$col} - $message ({red $text}) $quickFix`;
11
- const templateIssueNoFix = `{green $filename}:{yellow $row:$col} - $message ({red $text})`;
12
- const templateIssueWithSuggestions = `{green $filename}:{yellow $row:$col} - $message ({red $text}) Suggestions: {yellow [$suggestions]}`;
13
- const templateIssueWithContext = `{green $filename}:{yellow $row:$col} $padRowCol- $message ({red $text})$padContext -- {gray $contextLeft}{red {underline $text}}{gray $contextRight}`;
14
- const templateIssueWithContextWithSuggestions = `{green $filename}:{yellow $row:$col} $padRowCol- $message ({red $text})$padContext -- {gray $contextLeft}{red {underline $text}}{gray $contextRight}\n\t Suggestions: {yellow [$suggestions]}`;
15
- const templateIssueLegacy = `{green $filename}[$row, $col]: $message: {red $text}`;
16
- const templateIssueWordsOnly = '$text';
17
- const console = undefined;
18
- assert(!console);
19
- /**
20
- *
21
- * @param template - The template to use for the issue.
22
- * @param uniqueIssues - If true, only unique issues will be reported.
23
- * @param reportedIssuesCollection - optional collection to store reported issues.
24
- * @returns issueEmitter function
25
- */
26
- function genIssueEmitter(stdIO, errIO, template, uniqueIssues, reportedIssuesCollection) {
27
- const uniqueFilter = uniqueIssues ? uniqueFilterFnGenerator((issue) => issue.text) : () => true;
28
- const defaultWidth = 10;
29
- let maxWidth = defaultWidth;
30
- let uri;
31
- return function issueEmitter(issue) {
32
- if (!uniqueFilter(issue))
33
- return;
34
- if (uri !== issue.uri) {
35
- maxWidth = defaultWidth;
36
- uri = issue.uri;
37
- }
38
- maxWidth = Math.max(maxWidth * 0.999, issue.text.length, 10);
39
- const issueText = formatIssue(stdIO, template, issue, Math.ceil(maxWidth));
40
- reportedIssuesCollection?.push(formatIssue(errIO, template, issue, Math.ceil(maxWidth)));
41
- stdIO.writeLine(issueText);
42
- };
43
- }
44
- function nullEmitter() {
45
- /* empty */
46
- }
47
- function relativeUriFilename(uri, rootURL) {
48
- const url = toFileURL(uri);
49
- const rel = urlRelative(rootURL, url);
50
- if (rel.startsWith('..'))
51
- return toFilePathOrHref(url);
52
- return rel;
53
- }
54
- function reportProgress(io, p, cwdURL, options) {
55
- if (p.type === 'ProgressFileComplete') {
56
- return reportProgressFileComplete(io, p, cwdURL, options);
57
- }
58
- if (p.type === 'ProgressFileBegin') {
59
- return reportProgressFileBegin(io, p, cwdURL);
60
- }
61
- }
62
- function determineFilename(io, p, cwd) {
63
- const fc = '' + p.fileCount;
64
- const fn = (' '.repeat(fc.length) + p.fileNum).slice(-fc.length);
65
- const idx = fn + '/' + fc;
66
- const filename = io.chalk.gray(relativeUriFilename(p.filename, cwd));
67
- return { idx, filename };
68
- }
69
- function reportProgressFileBegin(io, p, cwdURL) {
70
- const { idx, filename } = determineFilename(io, p, cwdURL);
71
- if (io.getColorLevel() > 0) {
72
- io.clearLine?.(0);
73
- io.write(`${idx} ${filename}\r`);
74
- }
75
- }
76
- function reportProgressFileComplete(io, p, cwd, options) {
77
- const { idx, filename } = determineFilename(io, p, cwd);
78
- const { verbose, debug } = options;
79
- const time = reportTime(io, p.elapsedTimeMs, !!p.cached);
80
- const skipped = p.processed === false ? ' skipped' : '';
81
- const hasErrors = p.numErrors ? io.chalk.red ` X` : '';
82
- const newLine = (skipped && (verbose || debug)) || hasErrors || isSlow(p.elapsedTimeMs) || io.getColorLevel() < 1 ? '\n' : '';
83
- const msg = `${idx} ${filename} ${time}${skipped}${hasErrors}${newLine || '\r'}`;
84
- io.write(msg);
85
- }
86
- function reportTime(io, elapsedTimeMs, cached) {
87
- if (cached)
88
- return io.chalk.green('cached');
89
- if (elapsedTimeMs === undefined)
90
- return '-';
91
- const slow = isSlow(elapsedTimeMs);
92
- const color = !slow ? io.chalk.white : slow === 1 ? io.chalk.yellow : io.chalk.redBright;
93
- return color(elapsedTimeMs.toFixed(2) + 'ms');
94
- }
95
- function isSlow(elapsedTmeMs) {
96
- if (!elapsedTmeMs || elapsedTmeMs < 1000)
97
- return 0;
98
- if (elapsedTmeMs < 2000)
99
- return 1;
100
- return 2;
101
- }
102
- export function getReporter(options, config) {
103
- const perfStats = {
104
- filesProcessed: 0,
105
- filesSkipped: 0,
106
- filesCached: 0,
107
- elapsedTimeMs: 0,
108
- perf: Object.create(null),
109
- };
110
- const noColor = options.color === false;
111
- const forceColor = options.color === true;
112
- const uniqueIssues = config?.unique || false;
113
- const defaultIssueTemplate = options.wordsOnly
114
- ? templateIssueWordsOnly
115
- : options.legacy
116
- ? templateIssueLegacy
117
- : options.showContext
118
- ? options.showSuggestions
119
- ? templateIssueWithContextWithSuggestions
120
- : templateIssueWithContext
121
- : options.showSuggestions
122
- ? templateIssueWithSuggestions
123
- : options.showSuggestions === false
124
- ? templateIssueNoFix
125
- : templateIssue;
126
- const { fileGlobs, silent, summary, issues, progress: showProgress, verbose, debug } = options;
127
- const issueTemplate = config?.issueTemplate || defaultIssueTemplate;
128
- assertCheckTemplate(issueTemplate);
129
- const console = config?.console || customConsole;
130
- const colorLevel = noColor ? 0 : forceColor ? 2 : console.stdoutChannel.getColorLevel();
131
- const stdio = {
132
- ...console.stdoutChannel,
133
- chalk: new Chalk({ level: colorLevel }),
134
- };
135
- const stderr = {
136
- ...console.stderrChannel,
137
- chalk: new Chalk({ level: colorLevel }),
138
- };
139
- const consoleError = (msg) => stderr.writeLine(msg);
140
- function createInfoLog(wrap) {
141
- return (msg) => console.info(wrap(msg));
142
- }
143
- const emitters = {
144
- Debug: !silent && debug ? createInfoLog(stdio.chalk.cyan) : nullEmitter,
145
- Info: !silent && verbose ? createInfoLog(stdio.chalk.yellow) : nullEmitter,
146
- Warning: createInfoLog(stdio.chalk.yellow),
147
- };
148
- function infoEmitter(message, msgType) {
149
- emitters[msgType]?.(message);
150
- }
151
- const rootURL = toFileDirURL(options.root || process.cwd());
152
- function relativeIssue(fn) {
153
- const fnFilename = options.relative
154
- ? (uri) => relativeUriFilename(uri, rootURL)
155
- : (uri) => toFilePathOrHref(toFileURL(uri, rootURL));
156
- return (i) => {
157
- const fullFilename = i.uri ? toFilePathOrHref(toFileURL(i.uri, rootURL)) : '';
158
- const filename = i.uri ? fnFilename(i.uri) : '';
159
- const r = { ...i, filename, fullFilename };
160
- fn(r);
161
- };
162
- }
163
- /*
164
- * Turn off repeated issues see https://github.com/streetsidesoftware/cspell/pull/6058
165
- * We might want to add a CLI option later to turn this back on.
166
- */
167
- const repeatIssues = false;
168
- const issuesCollection = showProgress && repeatIssues ? [] : undefined;
169
- const errorCollection = [];
170
- function errorEmitter(message, error) {
171
- if (isSpellingDictionaryLoadError(error)) {
172
- error = error.cause;
173
- }
174
- const errorText = formatWithOptions({ colors: stderr.stream.hasColors?.() }, stderr.chalk.red(message), debug ? error : error.toString());
175
- errorCollection?.push(errorText);
176
- consoleError(errorText);
177
- }
178
- const resultEmitter = (result) => {
179
- if (!fileGlobs.length && !result.files) {
180
- return;
181
- }
182
- const { files, issues, cachedFiles, filesWithIssues, errors } = result;
183
- const numFilesWithIssues = filesWithIssues.size;
184
- if (stderr.getColorLevel() > 0) {
185
- stderr.write('\r');
186
- stderr.clearLine(0);
187
- }
188
- if (issuesCollection?.length || errorCollection?.length) {
189
- consoleError('-------------------------------------------');
190
- }
191
- if (issuesCollection?.length) {
192
- consoleError('Issues found:');
193
- issuesCollection.forEach((issue) => consoleError(issue));
194
- }
195
- const cachedFilesText = cachedFiles ? ` (${cachedFiles} from cache)` : '';
196
- const withErrorsText = errors ? ` with ${errors} error${errors === 1 ? '' : 's'}` : '';
197
- const numFilesWidthIssuesText = numFilesWithIssues === 1 ? '1 file' : `${numFilesWithIssues} files`;
198
- const summaryMessage = `CSpell\u003A Files checked: ${files}${cachedFilesText}, Issues found: ${issues} in ${numFilesWidthIssuesText}${withErrorsText}.`;
199
- consoleError(summaryMessage);
200
- if (errorCollection?.length && issues > 5) {
201
- consoleError('-------------------------------------------');
202
- consoleError('Errors:');
203
- errorCollection.forEach((error) => consoleError(error));
204
- }
205
- if (options.showPerfSummary) {
206
- consoleError('-------------------------------------------');
207
- consoleError('Performance Summary:');
208
- consoleError(` Files Processed: ${perfStats.filesProcessed.toString().padStart(6)}`);
209
- consoleError(` Files Skipped : ${perfStats.filesSkipped.toString().padStart(6)}`);
210
- consoleError(` Files Cached : ${perfStats.filesCached.toString().padStart(6)}`);
211
- consoleError(` Processing Time: ${perfStats.elapsedTimeMs.toFixed(2).padStart(9)}ms`);
212
- consoleError('Stats:');
213
- const stats = Object.entries(perfStats.perf)
214
- .filter((p) => !!p[1])
215
- .map(([key, value]) => [key, value.toFixed(2)]);
216
- const padName = Math.max(...stats.map((s) => s[0].length));
217
- const padValue = Math.max(...stats.map((s) => s[1].length));
218
- stats.sort((a, b) => a[0].localeCompare(b[0]));
219
- for (const [key, value] of stats) {
220
- value && consoleError(` ${key.padEnd(padName)}: ${value.padStart(padValue)}ms`);
221
- }
222
- }
223
- };
224
- function collectPerfStats(p) {
225
- if (p.cached) {
226
- perfStats.filesCached++;
227
- return;
228
- }
229
- perfStats.filesProcessed += p.processed ? 1 : 0;
230
- perfStats.filesSkipped += !p.processed ? 1 : 0;
231
- perfStats.elapsedTimeMs += p.elapsedTimeMs || 0;
232
- if (!p.perf)
233
- return;
234
- for (const [key, value] of Object.entries(p.perf)) {
235
- if (typeof value === 'number') {
236
- perfStats.perf[key] = (perfStats.perf[key] || 0) + value;
237
- }
238
- }
239
- }
240
- function progress(p) {
241
- if (!silent && showProgress) {
242
- reportProgress(stderr, p, rootURL, options);
243
- }
244
- if (p.type === 'ProgressFileComplete') {
245
- collectPerfStats(p);
246
- }
247
- }
248
- return {
249
- issue: relativeIssue(silent || !issues
250
- ? nullEmitter
251
- : genIssueEmitter(stdio, stderr, issueTemplate, uniqueIssues, issuesCollection)),
252
- error: silent ? nullEmitter : errorEmitter,
253
- info: infoEmitter,
254
- debug: emitters.Debug,
255
- progress,
256
- result: !silent && summary ? resultEmitter : nullEmitter,
257
- features: undefined,
258
- };
259
- }
260
- function formatIssue(io, templateStr, issue, maxIssueTextWidth) {
261
- function clean(t) {
262
- return t.replace(/\s+/, ' ');
263
- }
264
- const { uri = '', filename, row, col, text, context = issue.line, offset } = issue;
265
- const contextLeft = clean(context.text.slice(0, offset - context.offset));
266
- const contextRight = clean(context.text.slice(offset + text.length - context.offset));
267
- const contextFull = clean(context.text);
268
- const padContext = ' '.repeat(Math.max(maxIssueTextWidth - text.length, 0));
269
- const rowText = row.toString();
270
- const colText = col.toString();
271
- const padRowCol = ' '.repeat(Math.max(1, 8 - (rowText.length + colText.length)));
272
- const suggestions = formatSuggestions(io, issue);
273
- const msg = issue.message || (issue.isFlagged ? 'Forbidden word' : 'Unknown word');
274
- const messageColored = issue.isFlagged ? `{yellow ${msg}}` : msg;
275
- const substitutions = {
276
- $col: colText,
277
- $contextFull: contextFull,
278
- $contextLeft: contextLeft,
279
- $contextRight: contextRight,
280
- $filename: filename,
281
- $padContext: padContext,
282
- $padRowCol: padRowCol,
283
- $row: rowText,
284
- $suggestions: suggestions,
285
- $text: text,
286
- $uri: uri,
287
- $quickFix: formatQuickFix(io, issue),
288
- $message: msg,
289
- $messageColored: messageColored,
290
- };
291
- const t = templateStr.replaceAll('$messageColored', messageColored);
292
- const chalkTemplate = makeTemplate(io.chalk);
293
- return substitute(chalkTemplate(t), substitutions).trimEnd();
294
- }
295
- function formatSuggestions(io, issue) {
296
- if (issue.suggestionsEx) {
297
- return issue.suggestionsEx
298
- .map((sug) => sug.isPreferred
299
- ? io.chalk.italic(io.chalk.bold(sug.wordAdjustedToMatchCase || sug.word)) + '*'
300
- : sug.wordAdjustedToMatchCase || sug.word)
301
- .join(', ');
302
- }
303
- if (issue.suggestions) {
304
- return issue.suggestions.join(', ');
305
- }
306
- return '';
307
- }
308
- function formatQuickFix(io, issue) {
309
- if (!issue.suggestionsEx?.length)
310
- return '';
311
- const preferred = issue.suggestionsEx
312
- .filter((sug) => sug.isPreferred)
313
- .map((sug) => sug.wordAdjustedToMatchCase || sug.word);
314
- if (!preferred.length)
315
- return '';
316
- const fixes = preferred.map((w) => io.chalk.italic(io.chalk.yellow(w)));
317
- return `fix: (${fixes.join(', ')})`;
318
- }
319
- function substitute(text, substitutions) {
320
- const subs = [];
321
- for (const [match, replaceWith] of Object.entries(substitutions)) {
322
- const len = match.length;
323
- for (let i = text.indexOf(match); i >= 0; i = text.indexOf(match, i)) {
324
- const end = i + len;
325
- const reg = /\b/y;
326
- reg.lastIndex = end;
327
- if (reg.test(text)) {
328
- subs.push([i, end, replaceWith]);
329
- }
330
- i = end;
331
- }
332
- }
333
- subs.sort((a, b) => a[0] - b[0]);
334
- let i = 0;
335
- function sub(r) {
336
- const [a, b, t] = r;
337
- const prefix = text.slice(i, a);
338
- i = b;
339
- return prefix + t;
340
- }
341
- const parts = subs.map(sub);
342
- return parts.join('') + text.slice(i);
343
- }
344
- function assertCheckTemplate(template) {
345
- const r = checkTemplate(template);
346
- if (r instanceof Error) {
347
- throw r;
348
- }
349
- }
350
- export function checkTemplate(template) {
351
- const chalk = new Chalk();
352
- const chalkTemplate = makeTemplate(chalk);
353
- const substitutions = {
354
- $col: '<col>',
355
- $contextFull: '<contextFull>',
356
- $contextLeft: '<contextLeft>',
357
- $contextRight: '<contextRight>',
358
- $filename: '<filename>',
359
- $padContext: '<padContext>',
360
- $padRowCol: '<padRowCol>',
361
- $row: '<row>',
362
- $suggestions: '<suggestions>',
363
- $text: '<text>',
364
- $uri: '<uri>',
365
- $quickFix: '<quickFix>',
366
- $message: '<message>',
367
- $messageColored: '<messageColored>',
368
- };
369
- try {
370
- const t = chalkTemplate(template);
371
- const result = substitute(t, substitutions);
372
- const problems = [...result.matchAll(/\$[a-z]+/gi)].map((m) => m[0]);
373
- if (problems.length) {
374
- throw new Error(`Unresolved template variable${problems.length > 1 ? 's' : ''}: ${problems.map((v) => `'${v}'`).join(', ')}`);
375
- }
376
- return true;
377
- }
378
- catch (e) {
379
- const msg = e instanceof Error ? e.message : `${e}`;
380
- return new ApplicationError(msg);
381
- }
382
- }
383
- export const __testing__ = {
384
- formatIssue,
385
- };
386
- //# sourceMappingURL=cli-reporter.js.map
@@ -1,3 +0,0 @@
1
- import type { Command } from 'commander';
2
- export declare function commandCheck(prog: Command): Command;
3
- //# sourceMappingURL=commandCheck.d.ts.map
@@ -1,52 +0,0 @@
1
- import chalk from 'chalk';
2
- import { Option as CommanderOption } from 'commander';
3
- import * as App from './application.mjs';
4
- import { checkText } from './application.mjs';
5
- import { console } from './console.js';
6
- import { CheckFailed } from './util/errors.js';
7
- export function commandCheck(prog) {
8
- return prog
9
- .command('check <files...>')
10
- .description('Spell check file(s) and display the result. The full file is displayed in color.')
11
- .option('-c, --config <cspell.json>', 'Configuration file to use. By default cspell looks for cspell.json in the current directory.')
12
- .option('--validate-directives', 'Validate in-document CSpell directives.')
13
- .option('--no-validate-directives', 'Do not validate in-document CSpell directives.')
14
- .option('--no-color', 'Turn off color.')
15
- .option('--color', 'Force color')
16
- .option('--no-exit-code', 'Do not return an exit code if issues are found.')
17
- .addOption(new CommanderOption('--default-configuration', 'Load the default configuration and dictionaries.').hideHelp())
18
- .addOption(new CommanderOption('--no-default-configuration', 'Do not load the default configuration and dictionaries.'))
19
- .action(async (files, options) => {
20
- const useExitCode = options.exitCode ?? true;
21
- App.parseApplicationFeatureFlags(options.flag);
22
- let issueCount = 0;
23
- for (const filename of files) {
24
- console.log(chalk.yellowBright(`Check file: ${filename}`));
25
- console.log();
26
- try {
27
- const result = await checkText(filename, options);
28
- for (const item of result.items) {
29
- const fn = item.flagIE === App.IncludeExcludeFlag.EXCLUDE
30
- ? chalk.gray
31
- : item.isError
32
- ? chalk.red
33
- : chalk.whiteBright;
34
- const t = fn(item.text);
35
- process.stdout.write(t);
36
- issueCount += item.isError ? 1 : 0;
37
- }
38
- console.log();
39
- }
40
- catch {
41
- console.error(`File not found "${filename}"`);
42
- throw new CheckFailed('File not found', 1);
43
- }
44
- console.log();
45
- }
46
- if (issueCount) {
47
- const exitCode = (useExitCode ?? true) ? 1 : 0;
48
- throw new CheckFailed('Issues found', exitCode);
49
- }
50
- });
51
- }
52
- //# sourceMappingURL=commandCheck.js.map
@@ -1,3 +0,0 @@
1
- import type { Command } from 'commander';
2
- export declare function commandInit(prog: Command): Command;
3
- //# sourceMappingURL=commandConfig.d.ts.map
@@ -1,18 +0,0 @@
1
- import { collect, crOpt } from './commandHelpers.js';
2
- import { updateConfig } from './config/updateConfig.js';
3
- export function commandInit(prog) {
4
- const command = prog
5
- .command('config')
6
- .description('Update a CSpell configuration file.')
7
- .option('-c, --config <path>', 'Path to the CSpell configuration file.')
8
- .option('--import <path|package>', 'Import a configuration file or dictionary package.', collect)
9
- .option('--locale <locale>', 'Define the locale to use when spell checking (e.g., en, en-US, de).')
10
- .addOption(crOpt('--dictionary <dictionary>', 'Enable a dictionary.', collect).default(undefined))
11
- .addOption(crOpt('--comments', 'Add comments to the config file.').default(undefined).hideHelp())
12
- .option('--no-comments', 'Do not add comments to the config file.')
13
- .action((options) => {
14
- return updateConfig(options);
15
- });
16
- return command;
17
- }
18
- //# sourceMappingURL=commandConfig.js.map
@@ -1,3 +0,0 @@
1
- import type { Command } from 'commander';
2
- export declare function commandDictionaries(prog: Command): Command;
3
- //# sourceMappingURL=commandDictionaries.d.ts.map