cspell 9.6.0 → 9.6.1

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.
package/dist/esm/app.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as CheckFailed, S as ApplicationError, _ as padLeft, a as parseApplicationFeatureFlags, b as pruneAnsiTextStart, c as listDictionaries, d as validateUnitSize, f as unindent, g as tableToLines, i as lint, l as ReportChoicesAll, m as npmPackage, n as checkText, o as suggestions, p as DEFAULT_CACHE_LOCATION, r as createInit, s as trace, t as IncludeExcludeFlag, u as cvtLinterCliCommandOptionsToLinterCliOptions, v as padWidth, w as console, x as width, y as pruneAnsiTextEnd } from "./application-BJHh60xM.js";
1
+ import { C as CheckFailed, S as ApplicationError, _ as padLeft, a as parseApplicationFeatureFlags, b as pruneAnsiTextStart, c as listDictionaries, d as validateUnitSize, f as unindent, g as tableToLines, i as lint, l as ReportChoicesAll, m as npmPackage, n as checkText, o as suggestions, p as DEFAULT_CACHE_LOCATION, r as createInit, s as trace, t as IncludeExcludeFlag, u as cvtLinterCliCommandOptionsToLinterCliOptions, v as padWidth, w as console, x as width, y as pruneAnsiTextEnd } from "./application-DaQrXF9X.js";
2
2
  import { Link } from "cspell-lib";
3
3
  import chalk from "chalk";
4
4
  import * as iPath from "node:path";
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { isAsyncIterable, opFilter, opMap, opTap, operators, pipeAsync, pipeAsync as asyncPipe, toAsyncIterable, toAsyncIterable as mergeAsyncIterables } from "@cspell/cspell-pipe";
3
3
  import * as cspell from "cspell-lib";
4
- import { ENV_CSPELL_GLOB_ROOT, IncludeExcludeFlag, MessageTypes, SuggestionError, Text, checkTextDocument, combineTextAndLanguageSettings, createPerfTimer, extractDependencies, extractImportErrors, fileToDocument, getDefaultSettings, getDictionary, getGlobalSettingsAsync, getSystemFeatureFlags, isBinaryFile, isSpellingDictionaryLoadError, mergeSettings, setLogger, shouldCheckDocument, spellCheckDocument, suggestionsForWords, traceWordsAsync } from "cspell-lib";
4
+ import { ENV_CSPELL_GLOB_ROOT, IncludeExcludeFlag, MessageTypes, SuggestionError, Text, checkTextDocument, combineTextAndLanguageSettings, createPerfTimer, extractDependencies, extractImportErrors, fileToDocument, getDefaultSettings, getGlobalSettingsAsync, getSystemFeatureFlags, isBinaryFile, isSpellingDictionaryLoadError, mergeSettings, setLogger, shouldCheckDocument, spellCheckDocument, suggestionsForWords, traceWordsAsync } from "cspell-lib";
5
5
  import assert from "node:assert";
6
6
  import { format, formatWithOptions, stripVTControlCharacters } from "node:util";
7
7
  import { isUrlLike, toFileDirURL, toFilePathOrHref, toFileURL, urlRelative } from "@cspell/url";
@@ -14,6 +14,7 @@ import { promises } from "node:fs";
14
14
  import { fileURLToPath } from "node:url";
15
15
  import * as path$1 from "node:path";
16
16
  import path, { isAbsolute, posix, relative, resolve, sep } from "node:path";
17
+ import { enablePerformanceMeasurements, measurePerf } from "@cspell/cspell-performance-monitor";
17
18
  import { opMap as opMap$1, pipe } from "@cspell/cspell-pipe/sync";
18
19
  import { IssueType, MessageTypes as MessageTypes$1, unknownWordsChoices } from "@cspell/cspell-types";
19
20
  import { dictionaryCacheEnableLogging, dictionaryCacheGetLog } from "cspell-dictionary";
@@ -561,7 +562,8 @@ function getReporter(options, config) {
561
562
  filesProcessed: 0,
562
563
  filesSkipped: 0,
563
564
  filesCached: 0,
564
- elapsedTimeMs: 0,
565
+ accumulatedTimeMs: 0,
566
+ startTime: performance.now(),
565
567
  perf: Object.create(null)
566
568
  };
567
569
  const noColor = options.color === false;
@@ -639,12 +641,14 @@ function getReporter(options, config) {
639
641
  errorCollection.forEach((error) => consoleError(error));
640
642
  }
641
643
  if (options.showPerfSummary) {
644
+ const elapsedTotal = performance.now() - perfStats.startTime;
642
645
  consoleError("-------------------------------------------");
643
646
  consoleError("Performance Summary:");
644
- consoleError(` Files Processed: ${perfStats.filesProcessed.toString().padStart(6)}`);
645
- consoleError(` Files Skipped : ${perfStats.filesSkipped.toString().padStart(6)}`);
646
- consoleError(` Files Cached : ${perfStats.filesCached.toString().padStart(6)}`);
647
- consoleError(` Processing Time: ${perfStats.elapsedTimeMs.toFixed(2).padStart(9)}ms`);
647
+ consoleError(` Files Processed : ${perfStats.filesProcessed.toString().padStart(11)}`);
648
+ consoleError(` Files Skipped : ${perfStats.filesSkipped.toString().padStart(11)}`);
649
+ consoleError(` Files Cached : ${perfStats.filesCached.toString().padStart(11)}`);
650
+ consoleError(` Processing Time : ${perfStats.accumulatedTimeMs.toFixed(2).padStart(9)}ms`);
651
+ consoleError(` Total Time : ${elapsedTotal.toFixed(2).padStart(9)}ms`);
648
652
  const tableStats = {
649
653
  title: chalk$1.bold("Perf Stats:"),
650
654
  header: ["Name", "Time (ms)"],
@@ -726,7 +730,7 @@ function getReporter(options, config) {
726
730
  }
727
731
  perfStats.filesProcessed += p.processed ? 1 : 0;
728
732
  perfStats.filesSkipped += !p.processed ? 1 : 0;
729
- perfStats.elapsedTimeMs += p.elapsedTimeMs || 0;
733
+ perfStats.accumulatedTimeMs += p.elapsedTimeMs || 0;
730
734
  if (!p.perf) return;
731
735
  for (const [key, value] of Object.entries(p.perf)) if (typeof value === "number") perfStats.perf[key] = (perfStats.perf[key] || 0) + value;
732
736
  }
@@ -1197,8 +1201,8 @@ const pkgDir = _dirname;
1197
1201
  //#endregion
1198
1202
  //#region src/pkgInfo.ts
1199
1203
  const name = "cspell";
1200
- const version$1 = "9.6.0";
1201
- const engines = { node: ">=20" };
1204
+ const version$1 = "9.6.1";
1205
+ const engines = { node: ">=20.18" };
1202
1206
  const npmPackage = {
1203
1207
  name,
1204
1208
  version: version$1,
@@ -2074,22 +2078,6 @@ async function readConfigHandleError(filename) {
2074
2078
  }
2075
2079
  }
2076
2080
 
2077
- //#endregion
2078
- //#region src/util/prefetch.ts
2079
- function* prefetchIterable(iterable, size) {
2080
- assert(size >= 0);
2081
- const buffer = [];
2082
- for (const value of iterable) {
2083
- buffer.push(value);
2084
- if (buffer.length >= size - 1) {
2085
- const value$1 = buffer[0];
2086
- buffer.shift();
2087
- yield value$1;
2088
- }
2089
- }
2090
- yield* buffer;
2091
- }
2092
-
2093
2081
  //#endregion
2094
2082
  //#region src/util/reporters.ts
2095
2083
  function filterFeatureIssues(features, issue, reportOptions) {
@@ -2311,50 +2299,6 @@ function unindentString(str) {
2311
2299
  return lines.map((line) => line.slice(curPad)).join("\n");
2312
2300
  }
2313
2301
 
2314
- //#endregion
2315
- //#region src/util/unitNumbers.ts
2316
- const regexUnitNumber = /^((?:\d+(?:\.\d*)?)|(?:\.\d+))([a-z]*)$/i;
2317
- const unitSizes = {
2318
- "": 1,
2319
- b: 1,
2320
- k: 1024,
2321
- kb: 1024,
2322
- m: 1 << 20,
2323
- mb: 1 << 20,
2324
- g: 1 << 30,
2325
- gb: 1 << 30
2326
- };
2327
- function parseUnitSize(size) {
2328
- const match = size.match(regexUnitNumber);
2329
- const digits = match?.[1] || "";
2330
- const units = (match?.[2] || "").toLowerCase();
2331
- if (!match) return {
2332
- size,
2333
- digits,
2334
- units,
2335
- error: "Invalid size."
2336
- };
2337
- if (!units || units in unitSizes) return {
2338
- size,
2339
- digits,
2340
- units
2341
- };
2342
- return {
2343
- size,
2344
- digits,
2345
- units,
2346
- error: `Unknown units. Valid units are: ${Object.keys(unitSizes).filter(Boolean).join(", ").toUpperCase()}.`
2347
- };
2348
- }
2349
- function validateUnitSize(size) {
2350
- return parseUnitSize(size).error;
2351
- }
2352
- function sizeToNumber(size) {
2353
- const p = parseUnitSize(size);
2354
- if (p.error) return NaN;
2355
- return Number.parseFloat(p.digits) * (unitSizes[p.units] || 1);
2356
- }
2357
-
2358
2302
  //#endregion
2359
2303
  //#region src/util/wrap.ts
2360
2304
  const wrapSep = /\s+|(?<=,)|\.(?=\w)/g;
@@ -2483,11 +2427,11 @@ var LinterError = class extends Error {
2483
2427
 
2484
2428
  //#endregion
2485
2429
  //#region src/lint/processFile.ts
2486
- async function processFile(filename, cache, prefetch, processFileOptions) {
2487
- if (prefetch?.fileResult) return prefetch.fileResult;
2488
- const { reporter, cfg, configInfo } = processFileOptions;
2430
+ async function processFile(filename, cache, prefetch$1, processFileOptions) {
2431
+ if (prefetch$1?.fileResult) return prefetch$1.fileResult;
2432
+ const { reporter, cfg, configInfo, userSettings } = processFileOptions;
2489
2433
  const getElapsedTimeMs = getTimeMeasurer();
2490
- const reportIssueOptions = prefetch?.reportIssueOptions;
2434
+ const reportIssueOptions = prefetch$1?.reportIssueOptions;
2491
2435
  const cachedResult = await cache.getCachedLintResults(filename);
2492
2436
  if (cachedResult) {
2493
2437
  reporter.debug(`Filename: ${filename}, using cache`);
@@ -2509,7 +2453,7 @@ async function processFile(filename, cache, prefetch, processFileOptions) {
2509
2453
  elapsedTimeMs: 0,
2510
2454
  reportIssueOptions
2511
2455
  };
2512
- const fileInfo = prefetch?.fileInfo || await readFileInfo(filename, void 0, true);
2456
+ const fileInfo = prefetch$1?.fileInfo || await readFileInfo(filename, void 0, true);
2513
2457
  if (fileInfo.errorCode) {
2514
2458
  if (fileInfo.errorCode !== "EISDIR" && cfg.options.mustFindFiles) {
2515
2459
  const err = new LinterError(`File not found: "${filename}"`);
@@ -2530,7 +2474,7 @@ async function processFile(filename, cache, prefetch, processFileOptions) {
2530
2474
  numSuggestions,
2531
2475
  validateDirectives,
2532
2476
  skipValidation
2533
- }), configInfo.config);
2477
+ }), userSettings);
2534
2478
  spellResult = r;
2535
2479
  result.processed = r.checked;
2536
2480
  result.perf = r.perf ? { ...r.perf } : void 0;
@@ -2542,7 +2486,7 @@ async function processFile(filename, cache, prefetch, processFileOptions) {
2542
2486
  result.elapsedTimeMs = getElapsedTimeMs();
2543
2487
  const config = spellResult.settingsUsed ?? {};
2544
2488
  result.reportIssueOptions = mergeReportIssueOptions(spellResult.settingsUsed || configInfo.config, reportIssueOptions);
2545
- result.configErrors += await reportConfigurationErrors(config, processFileOptions);
2489
+ result.configErrors += reportSpellingResultConfigErrors(spellResult, processFileOptions);
2546
2490
  reportCheckResult(result, doc, spellResult, config, processFileOptions);
2547
2491
  const dep = calcDependencies(config);
2548
2492
  await cache.setCachedLintResults(result, dep.files);
@@ -2587,9 +2531,11 @@ function calcDependencies(config) {
2587
2531
  const { configFiles, dictionaryFiles } = extractDependencies(config);
2588
2532
  return { files: [...configFiles, ...dictionaryFiles] };
2589
2533
  }
2590
- async function reportConfigurationErrors(config, processFileOptions) {
2534
+ function reportConfigurationErrors(config, processFileOptions) {
2535
+ return reportImportErrors(extractImportErrors(config), processFileOptions);
2536
+ }
2537
+ function reportImportErrors(errors, processFileOptions) {
2591
2538
  const { reporter, configErrors } = processFileOptions;
2592
- const errors = extractImportErrors(config);
2593
2539
  let count = 0;
2594
2540
  errors.forEach((ref) => {
2595
2541
  const key = ref.error.toString();
@@ -2598,9 +2544,14 @@ async function reportConfigurationErrors(config, processFileOptions) {
2598
2544
  count += 1;
2599
2545
  reporter.error("Configuration", ref.error);
2600
2546
  });
2601
- (await getDictionary(config)).dictionaries.forEach((dict) => {
2602
- const dictErrors = dict.getErrors?.() || [];
2603
- const msg = `Dictionary Error with (${dict.name})`;
2547
+ return count;
2548
+ }
2549
+ function reportSpellingResultConfigErrors(spellResult, processFileOptions) {
2550
+ const { reporter, configErrors } = processFileOptions;
2551
+ let count = reportImportErrors(spellResult.configErrors || [], processFileOptions);
2552
+ const dictionaryErrors = [...spellResult.dictionaryErrors || []];
2553
+ for (const [dictName, dictErrors] of dictionaryErrors) {
2554
+ const msg = `Dictionary Error with (${dictName})`;
2604
2555
  dictErrors.forEach((error) => {
2605
2556
  const key = msg + error.toString();
2606
2557
  if (configErrors.has(key)) return;
@@ -2608,23 +2559,300 @@ async function reportConfigurationErrors(config, processFileOptions) {
2608
2559
  count += 1;
2609
2560
  reporter.error(msg, error);
2610
2561
  });
2611
- });
2562
+ }
2612
2563
  return count;
2613
2564
  }
2614
2565
  function countConfigErrors(configInfo, processFileOptions) {
2615
2566
  return reportConfigurationErrors(configInfo.config, processFileOptions);
2616
2567
  }
2617
2568
 
2569
+ //#endregion
2570
+ //#region src/util/prefetch.ts
2571
+ function* prefetchIterable(iterable, size) {
2572
+ assert(size >= 0);
2573
+ const buffer = [];
2574
+ for (const value of iterable) {
2575
+ buffer.push(value);
2576
+ if (buffer.length >= size - 1) {
2577
+ const value$1 = buffer[0];
2578
+ buffer.shift();
2579
+ yield value$1;
2580
+ }
2581
+ }
2582
+ yield* buffer;
2583
+ }
2584
+
2585
+ //#endregion
2586
+ //#region src/util/unitNumbers.ts
2587
+ const regexUnitNumber = /^((?:\d+(?:\.\d*)?)|(?:\.\d+))([a-z]*)$/i;
2588
+ const unitSizes = {
2589
+ "": 1,
2590
+ b: 1,
2591
+ k: 1024,
2592
+ kb: 1024,
2593
+ m: 1 << 20,
2594
+ mb: 1 << 20,
2595
+ g: 1 << 30,
2596
+ gb: 1 << 30
2597
+ };
2598
+ function parseUnitSize(size) {
2599
+ const match = size.match(regexUnitNumber);
2600
+ const digits = match?.[1] || "";
2601
+ const units = (match?.[2] || "").toLowerCase();
2602
+ if (!match) return {
2603
+ size,
2604
+ digits,
2605
+ units,
2606
+ error: "Invalid size."
2607
+ };
2608
+ if (!units || units in unitSizes) return {
2609
+ size,
2610
+ digits,
2611
+ units
2612
+ };
2613
+ return {
2614
+ size,
2615
+ digits,
2616
+ units,
2617
+ error: `Unknown units. Valid units are: ${Object.keys(unitSizes).filter(Boolean).join(", ").toUpperCase()}.`
2618
+ };
2619
+ }
2620
+ function validateUnitSize(size) {
2621
+ return parseUnitSize(size).error;
2622
+ }
2623
+ function sizeToNumber(size) {
2624
+ const p = parseUnitSize(size);
2625
+ if (p.error) return NaN;
2626
+ return Number.parseFloat(p.digits) * (unitSizes[p.units] || 1);
2627
+ }
2628
+
2629
+ //#endregion
2630
+ //#region src/lint/processFiles.ts
2631
+ const BATCH_FETCH_SIZE = 12;
2632
+ const BATCH_PROCESS_SIZE = 1;
2633
+ function prefetch(fileToProcess, cfg) {
2634
+ const { filename } = fileToProcess;
2635
+ if (isBinaryFile$1(filename, cfg.root)) return {
2636
+ ...fileToProcess,
2637
+ result: Promise.resolve({
2638
+ skip: true,
2639
+ skipReason: "Binary file."
2640
+ })
2641
+ };
2642
+ const reportIssueOptions = extractReporterIssueOptions(cfg.config);
2643
+ async function fetch$1() {
2644
+ const getElapsedTimeMs = getTimeMeasurer();
2645
+ const cachedResult = await cfg.cache.getCachedLintResults(filename);
2646
+ if (cachedResult) {
2647
+ cfg.reporter.debug(`Filename: ${filename}, using cache`);
2648
+ return { fileResult: {
2649
+ ...cachedResult,
2650
+ elapsedTimeMs: getElapsedTimeMs()
2651
+ } };
2652
+ }
2653
+ const uri = filenameToUri(filename, cfg.root).href;
2654
+ const checkResult = await shouldCheckDocument({ uri }, {}, cfg.config);
2655
+ if (!checkResult.shouldCheck) return {
2656
+ skip: true,
2657
+ skipReason: checkResult.reason || "Ignored by configuration."
2658
+ };
2659
+ const maxFileSize = processMaxFileSize(cfg.maxFileSize ?? checkResult.settings.maxFileSize);
2660
+ if (maxFileSize) {
2661
+ if (await getFileSize(filename) > maxFileSize) return {
2662
+ skip: true,
2663
+ skipReason: `File exceeded max file size of ${maxFileSize.toLocaleString()}`
2664
+ };
2665
+ }
2666
+ return {
2667
+ fileInfo: await readFileInfo(filename, void 0, true),
2668
+ reportIssueOptions
2669
+ };
2670
+ }
2671
+ const result = fetch$1().catch((e) => toApplicationError(e));
2672
+ return {
2673
+ ...fileToProcess,
2674
+ result
2675
+ };
2676
+ }
2677
+ async function processFiles(files, options) {
2678
+ const status = runResult();
2679
+ const cache = await createCache(options.cacheSettings);
2680
+ const failFast = options.cfg.options.failFast ?? options.configInfo.config.failFast ?? false;
2681
+ const reporter = options.lintReporter;
2682
+ const prefetchConfig = {
2683
+ reporter,
2684
+ root: options.cfg.root,
2685
+ maxFileSize: options.cfg.maxFileSize,
2686
+ config: options.configInfo.config,
2687
+ cache
2688
+ };
2689
+ const processFileOptionsGeneral = {
2690
+ reporter,
2691
+ chalk: options.chalk,
2692
+ configInfo: options.configInfo,
2693
+ cfg: options.cfg,
2694
+ verboseLevel: options.verboseLevel,
2695
+ useColor: options.useColor,
2696
+ configErrors: options.configErrors,
2697
+ userSettings: options.configInfo.config
2698
+ };
2699
+ function* prefetchFiles(files$1) {
2700
+ yield* prefetchIterable(pipe(files$1, opMap$1((file) => prefetch(file, prefetchConfig))), BATCH_FETCH_SIZE);
2701
+ }
2702
+ async function* prefetchFilesAsync(files$1) {
2703
+ for await (const file of files$1) yield prefetch(file, prefetchConfig);
2704
+ }
2705
+ const emptyResult = {
2706
+ fileInfo: { filename: "" },
2707
+ issues: [],
2708
+ processed: false,
2709
+ errors: 0,
2710
+ configErrors: 0,
2711
+ elapsedTimeMs: 1,
2712
+ reportIssueOptions: void 0
2713
+ };
2714
+ async function processPrefetchFileResult(pf) {
2715
+ const { filename, sequence, sequenceSize, result: pFetchResult } = pf;
2716
+ const getElapsedTimeMs = getTimeMeasurer();
2717
+ const fetchResult = await pFetchResult;
2718
+ if (fetchResult instanceof Error) throw fetchResult;
2719
+ const fileNum = sequence + 1;
2720
+ reporter.emitProgressBegin(filename, fileNum, pf.sequenceSize ?? sequence);
2721
+ if (fetchResult?.skip) return {
2722
+ filename,
2723
+ sequence,
2724
+ sequenceSize,
2725
+ result: {
2726
+ ...emptyResult,
2727
+ fileInfo: { filename },
2728
+ elapsedTimeMs: getElapsedTimeMs(),
2729
+ skippedReason: fetchResult.skipReason
2730
+ }
2731
+ };
2732
+ return {
2733
+ filename,
2734
+ sequence,
2735
+ sequenceSize,
2736
+ result: await processFile(filename, cache, fetchResult, processFileOptionsGeneral)
2737
+ };
2738
+ }
2739
+ async function* loadAndProcessFiles() {
2740
+ if (isAsyncIterable(files)) {
2741
+ for await (const pf of prefetchFilesAsync(files)) yield processPrefetchFileResult(pf);
2742
+ return;
2743
+ }
2744
+ if (BATCH_PROCESS_SIZE <= 1) {
2745
+ for (const pf of prefetchFiles(files)) {
2746
+ await pf.result;
2747
+ yield processPrefetchFileResult(pf);
2748
+ }
2749
+ return;
2750
+ }
2751
+ yield* pipe(prefetchIterable(pipe(prefetchFiles(files), opMap$1(async (pf) => processPrefetchFileResult(pf))), BATCH_PROCESS_SIZE));
2752
+ }
2753
+ for await (const fileP of loadAndProcessFiles()) {
2754
+ const { filename, sequence, sequenceSize, result } = fileP;
2755
+ status.files += 1;
2756
+ status.cachedFiles = (status.cachedFiles || 0) + (result.cached ? 1 : 0);
2757
+ status.skippedFiles = (status.skippedFiles || 0) + (result.processed ? 0 : 1);
2758
+ const fileNum = sequence + 1;
2759
+ const numIssues = reporter.emitProgressComplete(filename, fileNum, sequenceSize ?? fileNum, result);
2760
+ if (numIssues || result.errors) {
2761
+ status.filesWithIssues.add(relativeToCwd(filename, options.cfg.root));
2762
+ status.issues += numIssues;
2763
+ status.errors += result.errors;
2764
+ if (failFast) return status;
2765
+ }
2766
+ status.errors += result.configErrors;
2767
+ }
2768
+ await cache.reconcile();
2769
+ return status;
2770
+ }
2771
+ function processMaxFileSize(value) {
2772
+ if (!value) return void 0;
2773
+ if (typeof value === "number") return value;
2774
+ const num = sizeToNumber(value);
2775
+ if (Number.isNaN(num)) throw new ApplicationError(`Invalid max file size: "${value}"`);
2776
+ return num;
2777
+ }
2778
+ function runResult(init = {}) {
2779
+ const { files = 0, filesWithIssues = /* @__PURE__ */ new Set(), issues = 0, errors = 0, cachedFiles = 0 } = init;
2780
+ return {
2781
+ files,
2782
+ filesWithIssues,
2783
+ issues,
2784
+ errors,
2785
+ cachedFiles
2786
+ };
2787
+ }
2788
+
2789
+ //#endregion
2790
+ //#region \0@oxc-project+runtime@0.107.0/helpers/usingCtx.js
2791
+ function _usingCtx() {
2792
+ var r = "function" == typeof SuppressedError ? SuppressedError : function(r$1, e$1) {
2793
+ var n$1 = Error();
2794
+ return n$1.name = "SuppressedError", n$1.error = r$1, n$1.suppressed = e$1, n$1;
2795
+ }, e = {}, n = [];
2796
+ function using(r$1, e$1) {
2797
+ if (null != e$1) {
2798
+ if (Object(e$1) !== e$1) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
2799
+ if (r$1) var o = e$1[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
2800
+ if (void 0 === o && (o = e$1[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r$1)) var t = o;
2801
+ if ("function" != typeof o) throw new TypeError("Object is not disposable.");
2802
+ t && (o = function o$1() {
2803
+ try {
2804
+ t.call(e$1);
2805
+ } catch (r$2) {
2806
+ return Promise.reject(r$2);
2807
+ }
2808
+ }), n.push({
2809
+ v: e$1,
2810
+ d: o,
2811
+ a: r$1
2812
+ });
2813
+ } else r$1 && n.push({
2814
+ d: e$1,
2815
+ a: r$1
2816
+ });
2817
+ return e$1;
2818
+ }
2819
+ return {
2820
+ e,
2821
+ u: using.bind(null, !1),
2822
+ a: using.bind(null, !0),
2823
+ d: function d() {
2824
+ var o, t = this.e, s = 0;
2825
+ function next() {
2826
+ for (; o = n.pop();) try {
2827
+ if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
2828
+ if (o.d) {
2829
+ var r$1 = o.d.call(o.v);
2830
+ if (o.a) return s |= 2, Promise.resolve(r$1).then(next, err);
2831
+ } else s |= 1;
2832
+ } catch (r$2) {
2833
+ return err(r$2);
2834
+ }
2835
+ if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
2836
+ if (t !== e) throw t;
2837
+ }
2838
+ function err(n$1) {
2839
+ return t = t !== e ? new r(n$1, t) : n$1, next();
2840
+ }
2841
+ return next();
2842
+ }
2843
+ };
2844
+ }
2845
+
2618
2846
  //#endregion
2619
2847
  //#region src/lint/lint.ts
2620
2848
  const version = npmPackage.version;
2621
- const BATCH_SIZE = 8;
2622
2849
  const { opFilterAsync } = operators;
2623
2850
  async function runLint(cfg) {
2624
2851
  const reporter = new LintReporter(cfg.reporter, cfg.options);
2625
2852
  const configErrors = /* @__PURE__ */ new Set();
2626
2853
  const verboseLevel = calcVerboseLevel(cfg.options);
2627
2854
  const useColor = cfg.options.color ?? true;
2855
+ if (verboseLevel >= 1 && cfg.options.showPerfSummary) enablePerformanceMeasurements();
2628
2856
  const timer = getTimeMeasurer();
2629
2857
  const logDictRequests = truthy(getEnvironmentVariable("CSPELL_ENABLE_DICTIONARY_LOGGING"));
2630
2858
  if (logDictRequests) dictionaryCacheEnableLogging(true);
@@ -2632,157 +2860,65 @@ async function runLint(cfg) {
2632
2860
  if (logDictRequests) await writeDictionaryLog();
2633
2861
  await reporter.result(lintResult);
2634
2862
  const elapsed = timer();
2635
- if (getFeatureFlags().getFlag("timer")) console.log(`Elapsed Time: ${elapsed.toFixed(2)}ms`);
2863
+ if (getFeatureFlags().getFlag("timer") || verboseLevel >= 1 || cfg.options.showPerfSummary) console.error(`Elapsed Time: ${elapsed.toFixed(2)}ms`);
2636
2864
  return lintResult;
2637
- function prefetch(filename, configInfo, cache) {
2638
- if (isBinaryFile$1(filename, cfg.root)) return {
2639
- filename,
2640
- result: Promise.resolve({
2641
- skip: true,
2642
- skipReason: "Binary file."
2643
- })
2644
- };
2645
- const reportIssueOptions = extractReporterIssueOptions(configInfo.config);
2646
- async function fetch$1() {
2647
- const getElapsedTimeMs = getTimeMeasurer();
2648
- const cachedResult = await cache.getCachedLintResults(filename);
2649
- if (cachedResult) {
2650
- reporter.debug(`Filename: ${filename}, using cache`);
2651
- return { fileResult: {
2652
- ...cachedResult,
2653
- elapsedTimeMs: getElapsedTimeMs()
2654
- } };
2655
- }
2656
- const uri = filenameToUri(filename, cfg.root).href;
2657
- const checkResult = await shouldCheckDocument({ uri }, {}, configInfo.config);
2658
- if (!checkResult.shouldCheck) return {
2659
- skip: true,
2660
- skipReason: checkResult.reason || "Ignored by configuration."
2661
- };
2662
- const maxFileSize = processMaxFileSize(cfg.maxFileSize ?? checkResult.settings.maxFileSize);
2663
- if (maxFileSize) {
2664
- if (await getFileSize(filename) > maxFileSize) return {
2665
- skip: true,
2666
- skipReason: `File exceeded max file size of ${maxFileSize.toLocaleString()}`
2667
- };
2668
- }
2669
- return {
2670
- fileInfo: await readFileInfo(filename, void 0, true),
2671
- reportIssueOptions
2672
- };
2673
- }
2674
- return {
2675
- filename,
2676
- result: fetch$1().catch((e) => toApplicationError(e))
2677
- };
2678
- }
2679
- async function processFiles(files, configInfo, cacheSettings) {
2680
- const fileCount = Array.isArray(files) ? files.length : void 0;
2681
- const status = runResult();
2682
- const cache = await createCache(cacheSettings);
2683
- const failFast = cfg.options.failFast ?? configInfo.config.failFast ?? false;
2684
- function* prefetchFiles(files$1) {
2685
- const iter = prefetchIterable(pipe(files$1, opMap$1((filename) => prefetch(filename, configInfo, cache))), BATCH_SIZE);
2686
- for (const v of iter) yield v;
2687
- }
2688
- async function* prefetchFilesAsync(files$1) {
2689
- for await (const filename of files$1) yield prefetch(filename, configInfo, cache);
2690
- }
2691
- const emptyResult = {
2692
- fileInfo: { filename: "" },
2693
- issues: [],
2694
- processed: false,
2695
- errors: 0,
2696
- configErrors: 0,
2697
- elapsedTimeMs: 1,
2698
- reportIssueOptions: void 0
2699
- };
2700
- async function processPrefetchFileResult(pf, index) {
2701
- const { filename, result: pFetchResult } = pf;
2702
- const getElapsedTimeMs = getTimeMeasurer();
2703
- const fetchResult = await pFetchResult;
2704
- if (fetchResult instanceof Error) throw fetchResult;
2705
- reporter.emitProgressBegin(filename, index, fileCount ?? index);
2706
- if (fetchResult?.skip) return {
2707
- filename,
2708
- fileNum: index,
2709
- result: {
2710
- ...emptyResult,
2711
- fileInfo: { filename },
2712
- elapsedTimeMs: getElapsedTimeMs(),
2713
- skippedReason: fetchResult.skipReason
2714
- }
2715
- };
2716
- return {
2717
- filename,
2718
- fileNum: index,
2719
- result: await processFile(filename, cache, fetchResult, getProcessFileOptions(configInfo))
2720
- };
2721
- }
2722
- async function* loadAndProcessFiles() {
2723
- let i = 0;
2724
- if (isAsyncIterable(files)) for await (const pf of prefetchFilesAsync(files)) yield processPrefetchFileResult(pf, ++i);
2725
- else for (const pf of prefetchFiles(files)) {
2726
- await pf.result;
2727
- yield processPrefetchFileResult(pf, ++i);
2728
- }
2729
- }
2730
- for await (const fileP of loadAndProcessFiles()) {
2731
- const { filename, fileNum, result } = fileP;
2732
- status.files += 1;
2733
- status.cachedFiles = (status.cachedFiles || 0) + (result.cached ? 1 : 0);
2734
- status.skippedFiles = (status.skippedFiles || 0) + (result.processed ? 0 : 1);
2735
- const numIssues = reporter.emitProgressComplete(filename, fileNum, fileCount ?? fileNum, result);
2736
- if (numIssues || result.errors) {
2737
- status.filesWithIssues.add(relativeToCwd(filename, cfg.root));
2738
- status.issues += numIssues;
2739
- status.errors += result.errors;
2740
- if (failFast) return status;
2741
- }
2742
- status.errors += result.configErrors;
2743
- }
2744
- await cache.reconcile();
2745
- return status;
2746
- }
2747
2865
  async function run() {
2748
- if (cfg.options.root) setEnvironmentVariable(ENV_CSPELL_GLOB_ROOT, cfg.root);
2749
- const configInfo = await readConfig(cfg.configFile, cfg.root, cfg.options.stopConfigSearchAt);
2750
- const processFileOptions = getProcessFileOptions(configInfo);
2751
- if (cfg.options.defaultConfiguration !== void 0) configInfo.config.loadDefaultConfiguration = cfg.options.defaultConfiguration;
2752
- configInfo.config = mergeSettings(configInfo.config, cfg.cspellSettingsFromCliOptions);
2753
- const reporterConfig = clean({
2754
- maxNumberOfProblems: configInfo.config.maxNumberOfProblems,
2755
- maxDuplicateProblems: configInfo.config.maxDuplicateProblems,
2756
- minWordLength: configInfo.config.minWordLength,
2757
- ...cfg.options,
2758
- console
2759
- });
2760
- const reporters = cfg.options.reporter ?? configInfo.config.reporters;
2761
- reporter.config = reporterConfig;
2762
- await reporter.loadReportersAndFinalize(reporters);
2763
- setLogger(getLoggerFromReporter(reporter, useColor));
2764
- const globInfo = await determineGlobs(configInfo, cfg);
2765
- const { fileGlobs, excludeGlobs } = globInfo;
2766
- const hasFileLists = !!cfg.fileLists.length;
2767
- if (!fileGlobs.length && !hasFileLists && !cfg.files?.length) return runResult();
2768
- header(fileGlobs, excludeGlobs);
2769
- checkGlobs(fileGlobs, reporter);
2770
- if (verboseLevel > 1) reporter.info(`Config Files Found:\n ${relativeToCwd(configInfo.source)}\n`, MessageTypes$1.Info);
2771
- const configErrors$1 = await countConfigErrors(configInfo, processFileOptions);
2772
- if (configErrors$1 && cfg.options.exitCode !== false && !cfg.options.continueOnError) return runResult({ errors: configErrors$1 });
2773
- const { root } = cfg;
2774
2866
  try {
2775
- const cacheSettings = await calcCacheSettings(configInfo.config, {
2867
+ var _usingCtx$1 = _usingCtx();
2868
+ const _ = _usingCtx$1.u(measurePerf("runLint"));
2869
+ if (cfg.options.root) setEnvironmentVariable(ENV_CSPELL_GLOB_ROOT, cfg.root);
2870
+ const configInfo = await readConfig(cfg.configFile, cfg.root, cfg.options.stopConfigSearchAt);
2871
+ const processFileOptions = getProcessFileOptions(configInfo);
2872
+ if (cfg.options.defaultConfiguration !== void 0) configInfo.config.loadDefaultConfiguration = cfg.options.defaultConfiguration;
2873
+ configInfo.config = mergeSettings(configInfo.config, cfg.cspellSettingsFromCliOptions);
2874
+ const reporterConfig = clean({
2875
+ maxNumberOfProblems: configInfo.config.maxNumberOfProblems,
2876
+ maxDuplicateProblems: configInfo.config.maxDuplicateProblems,
2877
+ minWordLength: configInfo.config.minWordLength,
2776
2878
  ...cfg.options,
2777
- version
2778
- }, root);
2779
- const result = await processFiles(await determineFilesToCheck(configInfo, cfg, reporter, globInfo), configInfo, cacheSettings);
2780
- if (configErrors$1 && cfg.options.exitCode !== false) result.errors ||= configErrors$1;
2781
- return result;
2782
- } catch (e) {
2783
- const err = toApplicationError(e);
2784
- reporter.error("Linter", err);
2785
- return runResult({ errors: 1 });
2879
+ console
2880
+ });
2881
+ const reporters = cfg.options.reporter ?? configInfo.config.reporters;
2882
+ reporter.config = reporterConfig;
2883
+ await reporter.loadReportersAndFinalize(reporters);
2884
+ setLogger(getLoggerFromReporter(reporter, useColor));
2885
+ const globInfo = await determineGlobs(configInfo, cfg);
2886
+ const { fileGlobs, excludeGlobs } = globInfo;
2887
+ const hasFileLists = !!cfg.fileLists.length;
2888
+ if (!fileGlobs.length && !hasFileLists && !cfg.files?.length) return runResult();
2889
+ header(fileGlobs, excludeGlobs);
2890
+ checkGlobs(fileGlobs, reporter);
2891
+ if (verboseLevel > 1) reporter.info(`Config Files Found:\n ${relativeToCwd(configInfo.source)}\n`, MessageTypes$1.Info);
2892
+ const configErrorCount = countConfigErrors(configInfo, processFileOptions);
2893
+ if (configErrorCount && cfg.options.exitCode !== false && !cfg.options.continueOnError) return runResult({ errors: configErrorCount });
2894
+ const { root } = cfg;
2895
+ try {
2896
+ const cacheSettings = await calcCacheSettings(configInfo.config, {
2897
+ ...cfg.options,
2898
+ version
2899
+ }, root);
2900
+ const result = await processFiles(await determineFilesToCheck(configInfo, cfg, reporter, globInfo), {
2901
+ chalk,
2902
+ configInfo,
2903
+ cfg,
2904
+ verboseLevel,
2905
+ useColor,
2906
+ configErrors,
2907
+ userSettings: configInfo.config,
2908
+ lintReporter: reporter,
2909
+ cacheSettings
2910
+ });
2911
+ if (configErrorCount && cfg.options.exitCode !== false) result.errors ||= configErrorCount;
2912
+ return result;
2913
+ } catch (e) {
2914
+ const err = toApplicationError(e);
2915
+ reporter.error("Linter", err);
2916
+ return runResult({ errors: 1 });
2917
+ }
2918
+ } catch (_) {
2919
+ _usingCtx$1.e = _;
2920
+ } finally {
2921
+ _usingCtx$1.d();
2786
2922
  }
2787
2923
  }
2788
2924
  function header(files, cliExcludes) {
@@ -2808,7 +2944,8 @@ async function runLint(cfg) {
2808
2944
  cfg,
2809
2945
  verboseLevel,
2810
2946
  useColor,
2811
- configErrors
2947
+ configErrors,
2948
+ userSettings: configInfo.config
2812
2949
  };
2813
2950
  }
2814
2951
  }
@@ -2831,6 +2968,22 @@ async function determineGlobs(configInfo, cfg) {
2831
2968
  normalizedExcludes
2832
2969
  };
2833
2970
  }
2971
+ async function* filesToProcessAsync(filenames) {
2972
+ let sequence = 0;
2973
+ for await (const filename of filenames) yield {
2974
+ filename,
2975
+ sequence: sequence++
2976
+ };
2977
+ }
2978
+ function filesToProcess(files) {
2979
+ const filenames = [...files];
2980
+ const sequenceSize = filenames.length;
2981
+ return filenames.map((filename, sequence) => ({
2982
+ filename,
2983
+ sequence,
2984
+ sequenceSize
2985
+ }));
2986
+ }
2834
2987
  async function determineFilesToCheck(configInfo, cfg, reporter, globInfo) {
2835
2988
  async function _determineFilesToCheck() {
2836
2989
  const { fileLists } = cfg;
@@ -2858,7 +3011,7 @@ async function determineFilesToCheck(configInfo, cfg, reporter, globInfo) {
2858
3011
  const cliFiles = cfg.options.mustFindFiles ? rawCliFiles : rawCliFiles && pipeAsync(rawCliFiles, opFilterAsync(isFile));
2859
3012
  const foundFiles = hasFileLists ? concatAsyncIterables(cliFiles, await useFileLists(fileLists, includeFilter)) : cliFiles || await findFiles(fileGlobs, globOptions);
2860
3013
  const filtered = gitIgnore ? await gitIgnore.filterOutIgnored(foundFiles) : foundFiles;
2861
- return isAsyncIterable(filtered) ? pipeAsync(filtered, opFilterExcludedFiles) : [...pipe(filtered, opFilterExcludedFiles)];
3014
+ return isAsyncIterable(filtered) ? pipeAsync(filtered, opFilterExcludedFiles, filesToProcessAsync) : filesToProcess(pipe(filtered, opFilterExcludedFiles));
2862
3015
  }
2863
3016
  function isExcluded(filename, globMatcherExclude) {
2864
3017
  if (isBinaryFile(toFileURL(filename))) return true;
@@ -2885,16 +3038,6 @@ function extractGlobSource(g) {
2885
3038
  source
2886
3039
  };
2887
3040
  }
2888
- function runResult(init = {}) {
2889
- const { files = 0, filesWithIssues = /* @__PURE__ */ new Set(), issues = 0, errors = 0, cachedFiles = 0 } = init;
2890
- return {
2891
- files,
2892
- filesWithIssues,
2893
- issues,
2894
- errors,
2895
- cachedFiles
2896
- };
2897
- }
2898
3041
  function yesNo(value) {
2899
3042
  return value ? "Yes" : "No";
2900
3043
  }
@@ -2962,13 +3105,6 @@ function globPattern(g) {
2962
3105
  function calcVerboseLevel(options) {
2963
3106
  return options.verboseLevel ?? (options.verbose ? 1 : 0);
2964
3107
  }
2965
- function processMaxFileSize(value) {
2966
- if (!value) return void 0;
2967
- if (typeof value === "number") return value;
2968
- const num = sizeToNumber(value);
2969
- if (Number.isNaN(num)) throw new ApplicationError(`Invalid max file size: "${value}"`);
2970
- return num;
2971
- }
2972
3108
 
2973
3109
  //#endregion
2974
3110
  //#region src/lint/LintRequest.ts
@@ -3303,4 +3439,4 @@ function parseApplicationFeatureFlags(flags) {
3303
3439
 
3304
3440
  //#endregion
3305
3441
  export { CheckFailed as C, ApplicationError as S, padLeft as _, parseApplicationFeatureFlags as a, pruneAnsiTextStart as b, listDictionaries as c, validateUnitSize as d, unindent as f, tableToLines as g, getReporter as h, lint as i, ReportChoicesAll as l, npmPackage as m, checkText as n, suggestions as o, DEFAULT_CACHE_LOCATION as p, createInit as r, trace as s, IncludeExcludeFlag as t, cvtLinterCliCommandOptionsToLinterCliOptions as u, padWidth as v, console as w, width as x, pruneAnsiTextEnd as y };
3306
- //# sourceMappingURL=application-BJHh60xM.js.map
3442
+ //# sourceMappingURL=application-DaQrXF9X.js.map
@@ -1,3 +1,3 @@
1
- import { a as parseApplicationFeatureFlags, c as listDictionaries, i as lint, n as checkText, o as suggestions, r as createInit, s as trace, t as IncludeExcludeFlag } from "./application-BJHh60xM.js";
1
+ import { a as parseApplicationFeatureFlags, c as listDictionaries, i as lint, n as checkText, o as suggestions, r as createInit, s as trace, t as IncludeExcludeFlag } from "./application-DaQrXF9X.js";
2
2
 
3
3
  export { IncludeExcludeFlag, checkText, createInit, lint, listDictionaries, parseApplicationFeatureFlags, suggestions, trace };
package/dist/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as parseApplicationFeatureFlags, c as listDictionaries, h as getReporter, i as lint, n as checkText, o as suggestions, r as createInit, s as trace, t as IncludeExcludeFlag } from "./application-BJHh60xM.js";
1
+ import { a as parseApplicationFeatureFlags, c as listDictionaries, h as getReporter, i as lint, n as checkText, o as suggestions, r as createInit, s as trace, t as IncludeExcludeFlag } from "./application-DaQrXF9X.js";
2
2
 
3
3
  export * from "@cspell/cspell-types"
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cspell",
3
- "version": "9.6.0",
3
+ "version": "9.6.1",
4
4
  "description": "A Spelling Checker for Code!",
5
5
  "funding": "https://github.com/streetsidesoftware/cspell?sponsor=1",
6
6
  "bin": {
@@ -86,28 +86,30 @@
86
86
  },
87
87
  "homepage": "https://cspell.org/",
88
88
  "dependencies": {
89
- "@cspell/cspell-json-reporter": "9.6.0",
90
- "@cspell/cspell-pipe": "9.6.0",
91
- "@cspell/cspell-types": "9.6.0",
92
- "@cspell/dynamic-import": "9.6.0",
93
- "@cspell/url": "9.6.0",
89
+ "@cspell/cspell-json-reporter": "9.6.1",
90
+ "@cspell/cspell-performance-monitor": "9.6.1",
91
+ "@cspell/cspell-pipe": "9.6.1",
92
+ "@cspell/cspell-types": "9.6.1",
93
+ "@cspell/cspell-worker": "9.6.1",
94
+ "@cspell/dynamic-import": "9.6.1",
95
+ "@cspell/url": "9.6.1",
94
96
  "ansi-regex": "^6.2.2",
95
97
  "chalk": "^5.6.2",
96
98
  "chalk-template": "^1.1.2",
97
99
  "commander": "^14.0.2",
98
- "cspell-config-lib": "9.6.0",
99
- "cspell-dictionary": "9.6.0",
100
- "cspell-gitignore": "9.6.0",
101
- "cspell-glob": "9.6.0",
102
- "cspell-io": "9.6.0",
103
- "cspell-lib": "9.6.0",
100
+ "cspell-config-lib": "9.6.1",
101
+ "cspell-dictionary": "9.6.1",
102
+ "cspell-gitignore": "9.6.1",
103
+ "cspell-glob": "9.6.1",
104
+ "cspell-io": "9.6.1",
105
+ "cspell-lib": "9.6.1",
104
106
  "fast-json-stable-stringify": "^2.1.0",
105
107
  "flatted": "^3.3.3",
106
108
  "semver": "^7.7.3",
107
109
  "tinyglobby": "^0.2.15"
108
110
  },
109
111
  "engines": {
110
- "node": ">=20"
112
+ "node": ">=20.18"
111
113
  },
112
114
  "devDependencies": {
113
115
  "@types/micromatch": "^4.0.10",
@@ -115,5 +117,5 @@
115
117
  "micromatch": "^4.0.8",
116
118
  "minimatch": "^9.0.5"
117
119
  },
118
- "gitHead": "163793ddf2a0ad90bc7c90351698a106003297af"
120
+ "gitHead": "666fb79096d25c53af9519cad07030e7aca597e1"
119
121
  }