From 58063a101ec38d40789a0a59b7cfa521b170a0e7 Mon Sep 17 00:00:00 2001 From: Jason Dent Date: Fri, 19 Apr 2024 07:35:16 +0200 Subject: [PATCH] chore: Add lint rules (#5502) --- cspell-dict.txt | 1 + eslint.config.mjs | 106 ++++- integration-tests/src/check.ts | 13 +- integration-tests/src/config.ts | 4 +- integration-tests/src/reporter/index.ts | 2 +- integration-tests/src/run.ts | 6 +- integration-tests/src/snapshots.ts | 4 +- packages/cspell-bundled-dicts/tsconfig.json | 3 +- .../CSpellConfigFile/CSpellConfigFileJson.ts | 2 +- .../CSpellConfigFilePackageJson.ts | 4 +- .../src/CSpellConfigFileReaderWriter.ts | 2 +- packages/cspell-config-lib/src/defaultIO.ts | 2 +- packages/cspell-config-lib/src/index.test.ts | 2 +- .../src/loaders/loaderJavaScript.ts | 3 +- .../SpellingDictionaryCollection.test.ts | 2 +- .../SpellingDictionaryFromTrie.ts | 6 +- .../src/util/braceExpansion.ts | 19 +- .../cspell-dictionary/src/util/clean.test.ts | 2 +- packages/cspell-dictionary/src/util/repMap.ts | 4 +- packages/cspell-dictionary/src/util/text.ts | 10 +- .../src/plugin/cspell-eslint-plugin.cts | 1 + .../cspell-eslint-plugin/src/plugin/index.cts | 4 +- .../src/test/index.test.mts | 2 +- .../src/worker/spellCheck.mts | 2 +- .../cspell-gitignore/src/GitIgnoreFile.ts | 2 +- packages/cspell-glob/src/GlobMatcher.test.ts | 2 +- packages/cspell-grammar/src/app.ts | 4 +- .../src/mappers/typescript.test.ts | 3 +- .../cspell-grammar/src/mappers/typescript.ts | 35 +- .../src/parsers/typescript/index.test.ts | 2 +- .../src/viewer/escapeMarkdown.ts | 6 +- .../src/viewer/visualizeAsMD.ts | 3 +- packages/cspell-io/src/CSpellIONode.test.ts | 2 +- packages/cspell-io/src/VirtualFS.ts | 4 +- .../src/common/CFileResource.test.ts | 8 +- .../cspell-io/src/common/arrayBuffers.test.ts | 4 +- .../src/common/encode-decode.test.ts | 1 + .../cspell-io/src/common/encode-decode.ts | 29 +- packages/cspell-io/src/errors/assert.test.ts | 12 +- packages/cspell-io/src/handlers/node/file.ts | 3 +- .../cspell-io/src/models/BufferEncoding.ts | 1 + packages/cspell-io/src/node/dataUrl.test.ts | 1 + packages/cspell-io/src/node/dataUrl.ts | 5 +- .../cspell-io/src/node/file/fileWriter.ts | 2 +- packages/cspell-io/src/node/file/url.ts | 4 +- packages/cspell-lib/api/api.d.ts | 435 +++++++++--------- .../configLoader/configLoader.test.ts | 2 +- .../Controller/configLoader/configLoader.ts | 12 +- .../configLoader/configSearch.test.ts | 2 +- .../lib/Settings/Controller/pnpLoader.test.ts | 2 +- .../src/lib/Settings/Controller/pnpLoader.ts | 2 +- .../src/lib/Settings/InDocSettings.test.ts | 118 ++--- .../src/lib/Settings/InDocSettings.ts | 6 +- .../src/lib/Settings/RegExpPatterns.test.ts | 4 +- .../lib/Settings/checkFilenameMatchesGlob.ts | 5 +- packages/cspell-lib/src/lib/Settings/link.ts | 2 +- .../SuggestExperimental/helpers.ts | 4 +- .../cspell-lib/src/lib/clearCachedFiles.ts | 2 +- packages/cspell-lib/src/lib/index.ts | 21 +- .../cspell-lib/src/lib/spellCheckFile.test.ts | 20 +- packages/cspell-lib/src/lib/test/bugs.spec.ts | 2 +- .../src/lib/textValidation/checkText.ts | 26 +- .../src/lib/textValidation/docValidator.ts | 4 +- .../src/lib/textValidation/traceWord.ts | 2 +- .../cspell-lib/src/lib/util/MinHeapQueue.ts | 6 +- packages/cspell-lib/src/lib/util/Uri.ts | 2 +- .../src/lib/util/fileReader.test.ts | 2 +- .../cspell-lib/src/lib/util/fileReader.ts | 10 +- .../src/lib/util/memorizerWeak.test.ts | 3 +- packages/cspell-lib/src/lib/util/repMap.ts | 2 +- .../src/lib/util/resolveFile.test.ts | 14 +- .../cspell-lib/src/lib/util/resolveFile.ts | 8 +- packages/cspell-lib/src/lib/util/text.test.ts | 2 + packages/cspell-lib/src/lib/util/text.ts | 10 +- packages/cspell-lib/src/lib/util/util.test.ts | 2 +- packages/cspell-lib/src/lib/wordListHelper.ts | 2 +- .../src/test-util/test.matchers.mts | 2 +- .../cspell-resolver/src/requireResolve.ts | 2 +- packages/cspell-tools/src/compile.ts | 4 +- .../src/compiler/createCompileRequest.ts | 4 +- .../src/compiler/legacyLineToWords.ts | 2 +- .../src/compiler/wordListParser.test.ts | 4 +- .../src/compiler/wordListParser.ts | 27 +- .../src/compiler/writeTextToFile.ts | 2 +- packages/cspell-tools/src/shasum/shasum.ts | 8 +- packages/cspell-tools/src/test/TestHelper.ts | 2 +- packages/cspell-tools/src/util/errors.test.ts | 8 +- .../src/lib/Builder/cursor-util.ts | 1 + .../cspell-trie-lib/src/lib/ITrieNode/find.ts | 17 +- .../src/lib/ITrieNode/walker/hintedWalker.ts | 4 +- .../src/lib/SimpleDictionaryParser.ts | 19 +- .../src/lib/TrieBlob/FastTrieBlob.test.ts | 4 +- .../src/lib/TrieBlob/FastTrieBlob.ts | 5 +- .../lib/TrieBlob/FastTrieBlobBuilder.test.ts | 2 +- .../src/lib/TrieBlob/FastTrieBlobBuilder.ts | 1 + .../NumberSequenceByteDecoderAccumulator.ts | 25 +- .../src/lib/TrieBlob/TrieBlob.test.ts | 2 +- .../src/lib/TrieBlob/TrieBlob.ts | 6 +- .../cspell-trie-lib/src/lib/TrieBuilder.ts | 2 +- .../cspell-trie-lib/src/lib/TrieNode/find.ts | 17 +- .../src/lib/convertToTrieRefNodes.ts | 4 +- .../distance/distanceAStarWeighted.test.ts | 4 +- .../src/lib/distance/formatResultEx.ts | 2 +- packages/cspell-trie-lib/src/lib/io/decode.ts | 2 +- .../src/lib/io/importExport.ts | 2 +- .../src/lib/io/importExportV2.ts | 9 +- .../src/lib/io/importExportV3.test.ts | 2 +- .../src/lib/io/importExportV3.ts | 19 +- .../src/lib/io/importExportV4.test.ts | 2 +- .../src/lib/io/importExportV4.ts | 44 +- .../src/lib/io/importV3.test.ts | 2 +- .../cspell-trie-lib/src/lib/io/importV3.ts | 4 +- .../src/lib/io/importV3FastBlob.test.ts | 2 +- .../src/lib/suggestions/suggest-en.test.ts | 9 +- .../src/lib/suggestions/suggest.ts | 8 +- .../src/lib/suggestions/suggestAStar.ts | 12 +- .../cspell-trie-lib/src/lib/utils/text.ts | 11 +- .../src/lib/walker/hintedWalker.ts | 4 +- .../cspell-trie-lib/src/perf/perfSuite.ts | 26 +- packages/cspell-trie-lib/src/perf/run.ts | 36 +- .../src/test/dictionaries.test.helper.ts | 2 +- .../src/test/reader.test.helper.ts | 3 +- packages/cspell-trie/src/app.test.ts | 6 +- packages/cspell-trie/src/app.ts | 8 +- packages/cspell/src/app/app.test.ts | 30 +- packages/cspell/src/app/cli-reporter.ts | 2 +- packages/cspell/src/app/commandSuggestion.ts | 2 +- packages/cspell/src/app/lint/lint.ts | 1 + .../dynamic-import/src/esm/dynamicImport.mts | 2 +- .../src/IterableHunspellReaderLegacy.test.ts | 2 +- .../src/IterableHunspellReaderLegacy.ts | 2 + packages/hunspell-reader/src/aff.test.ts | 3 +- packages/hunspell-reader/src/aff.ts | 29 +- .../hunspell-reader/src/affLegacy.test.ts | 3 +- packages/hunspell-reader/src/affLegacy.ts | 26 +- packages/hunspell-reader/src/affReader.ts | 9 +- .../hunspell-reader/src/commandDictInfo.ts | 2 +- packages/hunspell-reader/src/commandWords.ts | 4 +- .../hunspell-reader/src/iterableToStream.ts | 10 +- .../hunspell-reader/src/textUtils.test.ts | 1 + packages/hunspell-reader/src/textUtils.ts | 21 +- .../src/config-definitions.ts | 1 + scripts/build-cspell-schema.mjs | 2 +- scripts/update-package-json.mjs | 4 +- scripts/update-release-please.mjs | 2 +- .../test-cspell-esbuild-cjs/package.json | 3 +- .../src/rollup-plugin-inject-dirname.mts | 10 +- .../test-cspell-lib-rollup/rollup.config.mjs | 2 +- .../test-cspell-pipe-rollup/rollup.config.mjs | 2 +- .../rollup.config.mjs | 2 +- .../rollup.config.mjs | 2 +- .../test-cspell-trie-lib/rollup.config.mjs | 2 +- .../rollup.config.mjs | 2 +- .../rollup.config.mjs | 2 +- tools/perf-chart/lib/app.cjs | 2 +- tools/perf-chart/src/perfChart.ts | 2 +- tsconfig.json | 3 +- 157 files changed, 898 insertions(+), 760 deletions(-) diff --git a/cspell-dict.txt b/cspell-dict.txt index 06ddc0571c70..d948493e90cb 100644 --- a/cspell-dict.txt +++ b/cspell-dict.txt @@ -23,6 +23,7 @@ globby globstar gzipped Harakat +iife jamstack lcov licia diff --git a/eslint.config.mjs b/eslint.config.mjs index f74ea52f1d10..5631a26d3a85 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,5 +1,3 @@ -// @ts-check - import eslint from '@eslint/js'; import nodePlugin from 'eslint-plugin-n'; import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; @@ -12,6 +10,8 @@ import tsEslint from 'typescript-eslint'; // const __dirname = fileURLToPath(new URL('.', import.meta.url)); // const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: eslint.configs.recommended}); +// @ts-check + export default tsEslint.config( eslint.configs.recommended, nodePlugin.configs['flat/recommended'], @@ -26,24 +26,36 @@ export default tsEslint.config( // Disable these rules 'unicorn/catch-error-name': 'off', 'unicorn/consistent-function-scoping': 'off', + 'unicorn/explicit-length-check': 'off', 'unicorn/filename-case': 'off', 'unicorn/import-style': 'off', 'unicorn/no-array-callback-reference': 'off', - 'unicorn/prevent-abbreviations': 'off', 'unicorn/no-array-reduce': 'off', - 'unicorn/explicit-length-check': 'off', - 'unicorn/no-nested-ternary': 'off', 'unicorn/no-await-expression-member': 'off', + 'unicorn/no-nested-ternary': 'off', + 'unicorn/no-new-array': 'off', // new Array(size) is 10x faster than Array.from({length: size}) + 'unicorn/no-useless-spread': 'off', // makes dangerous fixes + 'unicorn/no-useless-undefined': 'off', // Breaks return types and other things + 'unicorn/no-zero-fractions': 'off', + 'unicorn/number-literal-case': 'off', // doesn't fix anything, might conflict with other rules. + 'unicorn/prefer-event-target': 'off', // It is broken + 'unicorn/prefer-logical-operator-over-ternary': 'off', // single line ternary is fine + 'unicorn/prefer-math-trunc': 'off', // incorrectly sets Enums. + 'unicorn/prefer-native-coercion-functions': 'off', // Makes some strange choices + 'unicorn/prefer-string-slice': 'off', // substring is used where it make the most sense. + 'unicorn/prefer-top-level-await': 'off', // it will be possible to require a module that does not use top level await. + 'unicorn/prevent-abbreviations': 'off', // Maybe later + 'unicorn/better-regex': 'off', // Not sure if it is an improvement. + 'unicorn/new-for-builtins': 'off', 'unicorn/no-array-for-each': 'off', - 'unicorn/prefer-at': 'off', + 'unicorn/no-array-method-this-argument': 'off', // Too many false positives 'unicorn/no-for-loop': 'off', - 'unicorn/new-for-builtins': 'off', - 'unicorn/better-regex': 'off', // Not sure if it is an improvement. + 'unicorn/no-negated-condition': 'off', // Too picky - works against implying the most common branch. + 'unicorn/prefer-at': 'off', // Enable these rules to help with on boarding eslint. - 'unicorn/no-instanceof-array': 'error', 'unicorn/numeric-separators-style': [ 'error', { @@ -53,11 +65,85 @@ export default tsEslint.config( }, }, ], + 'unicorn/empty-brace-spaces': 'error', + 'unicorn/error-message': 'error', + 'unicorn/escape-case': 'error', + 'unicorn/expiring-todo-comments': 'error', + 'unicorn/no-abusive-eslint-disable': 'error', + 'unicorn/no-anonymous-default-export': 'error', + 'unicorn/no-array-push-push': 'error', // This isn't really a problem + 'unicorn/no-await-in-promise-methods': 'error', + 'unicorn/no-console-spaces': 'error', + 'unicorn/no-document-cookie': 'error', + 'unicorn/no-empty-file': 'error', + 'unicorn/no-hex-escape': 'error', + 'unicorn/no-instanceof-array': 'error', + 'unicorn/no-invalid-remove-event-listener': 'error', + 'unicorn/no-lonely-if': 'error', + 'unicorn/no-new-buffer': 'error', + 'unicorn/no-null': 'error', + 'unicorn/no-object-as-default-parameter': 'error', + 'unicorn/no-process-exit': 'error', + 'unicorn/no-single-promise-in-promise-methods': 'error', + 'unicorn/no-static-only-class': 'error', + 'unicorn/no-thenable': 'error', + 'unicorn/no-this-assignment': 'error', + 'unicorn/no-typeof-undefined': 'error', + 'unicorn/no-unnecessary-await': 'error', + 'unicorn/no-unnecessary-polyfills': 'error', + 'unicorn/no-unreadable-array-destructuring': 'error', + 'unicorn/no-unreadable-iife': 'error', + 'unicorn/no-useless-fallback-in-spread': 'error', + 'unicorn/no-useless-length-check': 'error', + 'unicorn/no-useless-promise-resolve-reject': 'error', + 'unicorn/no-useless-switch-case': 'error', + 'unicorn/prefer-add-event-listener': 'error', + 'unicorn/prefer-array-find': 'error', + 'unicorn/prefer-array-flat-map': 'error', 'unicorn/prefer-array-flat': 'error', + 'unicorn/prefer-array-index-of': 'error', + 'unicorn/prefer-array-some': 'error', + 'unicorn/prefer-blob-reading-methods': 'error', + 'unicorn/prefer-code-point': 'error', + 'unicorn/prefer-date-now': 'error', + 'unicorn/prefer-default-parameters': 'error', + 'unicorn/prefer-dom-node-append': 'error', + 'unicorn/prefer-dom-node-dataset': 'error', + 'unicorn/prefer-dom-node-remove': 'error', + 'unicorn/prefer-dom-node-text-content': 'error', + 'unicorn/prefer-export-from': 'error', + 'unicorn/prefer-includes': 'error', + 'unicorn/prefer-keyboard-event-key': 'error', + 'unicorn/prefer-modern-dom-apis': 'error', + 'unicorn/prefer-modern-math-apis': 'error', 'unicorn/prefer-module': 'error', + 'unicorn/prefer-negative-index': 'error', 'unicorn/prefer-node-protocol': 'error', + 'unicorn/prefer-number-properties': 'error', + 'unicorn/prefer-object-from-entries': 'error', + 'unicorn/prefer-optional-catch-binding': 'error', + 'unicorn/prefer-prototype-methods': 'error', + 'unicorn/prefer-query-selector': 'error', + 'unicorn/prefer-reflect-apply': 'error', + 'unicorn/prefer-regexp-test': 'error', + 'unicorn/prefer-set-has': 'error', + 'unicorn/prefer-set-size': 'error', 'unicorn/prefer-spread': 'error', 'unicorn/prefer-string-replace-all': 'error', + 'unicorn/prefer-string-starts-ends-with': 'error', + 'unicorn/prefer-string-trim-start-end': 'error', + 'unicorn/prefer-switch': 'error', + 'unicorn/prefer-ternary': 'error', + 'unicorn/prefer-type-error': 'error', + 'unicorn/relative-url-style': 'error', + 'unicorn/require-array-join-separator': 'error', + 'unicorn/require-number-to-fixed-digits-argument': 'error', + 'unicorn/switch-case-braces': 'error', + 'unicorn/template-indent': 'error', + 'unicorn/text-encoding-identifier-case': 'error', + 'unicorn/throw-new-error': 'error', + + // To be evaluated }, }, { @@ -162,6 +248,8 @@ export default tsEslint.config( '@typescript-eslint/no-explicit-any': 'off', // any is allowed in tests 'unicorn/no-null': 'off', // null is allowed in tests 'unicorn/prefer-module': 'off', // require.resolve is allowed in tests + 'unicorn/error-message': 'off', + 'unicorn/no-useless-undefined': 'off', // undefined is allowed in tests }, }, { diff --git a/integration-tests/src/check.ts b/integration-tests/src/check.ts index f2f602910898..6365f60682db 100644 --- a/integration-tests/src/check.ts +++ b/integration-tests/src/check.ts @@ -73,9 +73,9 @@ async function execCheckAndUpdate(rep: Repository, options: CheckAndUpdateOption try { const updatedRep = mustBeDefined(await addRepository(logger, rep.url, rep.branch)); rep = resolveRepArgs(updatedRep); - } catch (_) { + } catch { log(color`******** fail ********`); - return Promise.resolve({ success: false, rep, elapsedTime: 0 }); + return { success: false, rep, elapsedTime: 0 }; } log(color`******** Updating Repo Complete ********`); if (rep.commit !== oldCommit) { @@ -111,12 +111,12 @@ async function execCheck(context: CheckContext, update: boolean): Promise [r.rep, r])); const w = Math.max(...reposChecked.map((r) => r.path.length)); const r = sorted.map((r) => { - const { success = undefined, elapsedTime = 0 } = resultsByRep.get(r) || {}; + const { success, elapsedTime = 0 } = resultsByRep.get(r) || {}; const mark = success === undefined ? '🛑' : success === false ? '❌' : '✅'; const time = chalk.gray(rightJustify(elapsedTime ? `${(elapsedTime / 1000).toFixed(3)}s` : '', 9)); const padding = ' '.repeat(w - r.path.length); @@ -363,8 +363,7 @@ function tfn(colorFn: ChalkInstance): (strings: string | TemplateStringsArray, . const parts: string[] = []; let i = 0; for (; i < strings.length - 1; ++i) { - parts.push(strings[i]); - parts.push(rest[i] as string); + parts.push(strings[i], rest[i] as string); } if (i < strings.length) { parts.push(strings[i]); diff --git a/integration-tests/src/config.ts b/integration-tests/src/config.ts index 4ca6d03649e5..c311e8089473 100644 --- a/integration-tests/src/config.ts +++ b/integration-tests/src/config.ts @@ -23,10 +23,10 @@ const defaultConfig: Config = { export function readConfig(): Config { try { - const file = fs.readFileSync(configFile, 'utf-8'); + const file = fs.readFileSync(configFile, 'utf8'); const cfg = JSON.parse(file); return cfg; - } catch (_) { + } catch { return JSON.parse(JSON.stringify(defaultConfig)); } } diff --git a/integration-tests/src/reporter/index.ts b/integration-tests/src/reporter/index.ts index 81730494c0c2..37e31b4974d0 100644 --- a/integration-tests/src/reporter/index.ts +++ b/integration-tests/src/reporter/index.ts @@ -164,7 +164,7 @@ function getPerfCsvFileUrl(root: vscodeUri.URI): URL { */ async function createCsvFile(csvUrl: URL): Promise { if (!reformatCsv) return; - const csvFile = await fs.readFile(csvUrl, 'utf-8').catch(() => undefined); + const csvFile = await fs.readFile(csvUrl, 'utf8').catch(() => undefined); if (!csvFile) { return fs.writeFile(csvUrl, stringifyCsv([csvHeaders])); } diff --git a/integration-tests/src/run.ts b/integration-tests/src/run.ts index b0625dcfc8ef..90888a3adbe2 100644 --- a/integration-tests/src/run.ts +++ b/integration-tests/src/run.ts @@ -11,14 +11,14 @@ import { addRepository, listRepositories } from './repositoryHelper.js'; const defaultParallel = Math.max(os.cpus().length / 2, 1); function processParallelArg(value: string): number { - const v = parseInt(value, 10); + const v = Number.parseInt(value, 10); return v < 1 ? defaultParallel : v; } function validateParallelArg(value: string) { // parseInt takes a string and a radix - const parsedValue = parseInt(value, 10); - if (isNaN(parsedValue) || parsedValue < 1) { + const parsedValue = Number.parseInt(value, 10); + if (Number.isNaN(parsedValue) || parsedValue < 1) { throw new InvalidArgumentError('Must be a number >= 1'); } return value; diff --git a/integration-tests/src/snapshots.ts b/integration-tests/src/snapshots.ts index 337ac2f33303..b33a0e47c1a0 100644 --- a/integration-tests/src/snapshots.ts +++ b/integration-tests/src/snapshots.ts @@ -66,8 +66,8 @@ export function readSnapshot(rep: Repository): string { const dir = Path.join(snapshotDir, rep.path); const filename = Path.join(dir, snapshotFileName); try { - return fs.readFileSync(filename, 'utf-8'); - } catch (_) { + return fs.readFileSync(filename, 'utf8'); + } catch { return ''; } } diff --git a/packages/cspell-bundled-dicts/tsconfig.json b/packages/cspell-bundled-dicts/tsconfig.json index 21f87d81541b..8e3dc2e8de8c 100644 --- a/packages/cspell-bundled-dicts/tsconfig.json +++ b/packages/cspell-bundled-dicts/tsconfig.json @@ -4,5 +4,6 @@ "declaration": false, "declarationMap": false, "sourceMap": false - } + }, + "files": ["cspell-default.config.ts"] } diff --git a/packages/cspell-config-lib/src/CSpellConfigFile/CSpellConfigFileJson.ts b/packages/cspell-config-lib/src/CSpellConfigFile/CSpellConfigFileJson.ts index 10ca2e17808d..f2f46e018c8a 100644 --- a/packages/cspell-config-lib/src/CSpellConfigFile/CSpellConfigFileJson.ts +++ b/packages/cspell-config-lib/src/CSpellConfigFile/CSpellConfigFileJson.ts @@ -16,7 +16,7 @@ export class CSpellConfigFileJson extends ImplCSpellConfigFile { } serialize() { - return stringify(this.settings, null, this.indent) + '\n'; + return stringify(this.settings, undefined, this.indent) + '\n'; } public static parse(file: TextFile): CSpellConfigFileJson { diff --git a/packages/cspell-config-lib/src/CSpellConfigFile/CSpellConfigFilePackageJson.ts b/packages/cspell-config-lib/src/CSpellConfigFile/CSpellConfigFilePackageJson.ts index d14aa1c4ce68..ea5e05ce7314 100644 --- a/packages/cspell-config-lib/src/CSpellConfigFile/CSpellConfigFilePackageJson.ts +++ b/packages/cspell-config-lib/src/CSpellConfigFile/CSpellConfigFilePackageJson.ts @@ -28,14 +28,14 @@ export function parseCSpellConfigFilePackageJson(file: TextFile): CSpellConfigFi packageJson['cspell'] = packageJson['cspell'] || {}; const cspell = packageJson['cspell']; if (typeof cspell !== 'object' || Array.isArray(cspell)) { - throw new Error(`Unable to parse ${url}`); + throw new TypeError(`Unable to parse ${url}`); } const indent = detectIndent(content); function serialize(settings: CSpellSettings) { packageJson['cspell'] = settings; - return JSON.stringify(packageJson, null, indent) + '\n'; + return JSON.stringify(packageJson, undefined, indent) + '\n'; } return new CSpellConfigFilePackageJson(url, cspell, serialize); diff --git a/packages/cspell-config-lib/src/CSpellConfigFileReaderWriter.ts b/packages/cspell-config-lib/src/CSpellConfigFileReaderWriter.ts index aa7a71ca6e5a..f7a0402dd904 100644 --- a/packages/cspell-config-lib/src/CSpellConfigFileReaderWriter.ts +++ b/packages/cspell-config-lib/src/CSpellConfigFileReaderWriter.ts @@ -91,7 +91,7 @@ export class CSpellConfigFileReaderWriterImpl implements CSpellConfigFileReaderW } setTrustedUrls(urls: readonly (URL | string)[]): this { - this._trustedUrls = [...new Set([...urls.map((url) => new URL(url).href)])].sort(); + this._trustedUrls = [...new Set(urls.map((url) => new URL(url).href))].sort(); return this; } diff --git a/packages/cspell-config-lib/src/defaultIO.ts b/packages/cspell-config-lib/src/defaultIO.ts index 012c6af67c5e..7911399b7ed4 100644 --- a/packages/cspell-config-lib/src/defaultIO.ts +++ b/packages/cspell-config-lib/src/defaultIO.ts @@ -9,7 +9,7 @@ export const defaultIO: IO = { }; async function readFile(url: URL): Promise { - const content = await fs.readFile(url, 'utf-8'); + const content = await fs.readFile(url, 'utf8'); return { url, content }; } diff --git a/packages/cspell-config-lib/src/index.test.ts b/packages/cspell-config-lib/src/index.test.ts index c9fc16483dc1..b8c1307f054d 100644 --- a/packages/cspell-config-lib/src/index.test.ts +++ b/packages/cspell-config-lib/src/index.test.ts @@ -39,6 +39,6 @@ describe('cspell-config', () => { assert(cfg instanceof CSpellConfigFile); cfg.addWords(addWords); await rw.writeConfig(cfg); - expect(await fs.readFile(tempFile, 'utf-8')).toMatchSnapshot(); + expect(await fs.readFile(tempFile, 'utf8')).toMatchSnapshot(); }); }); diff --git a/packages/cspell-config-lib/src/loaders/loaderJavaScript.ts b/packages/cspell-config-lib/src/loaders/loaderJavaScript.ts index 3976922615a0..64cacf8d56e1 100644 --- a/packages/cspell-config-lib/src/loaders/loaderJavaScript.ts +++ b/packages/cspell-config-lib/src/loaders/loaderJavaScript.ts @@ -36,8 +36,9 @@ export class LoaderJavaScript implements FileLoaderMiddleware { switch (ext) { case '.js': case '.cjs': - case '.mjs': + case '.mjs': { return importJavaScript(url, this.hashSuffix); + } } return next(req); } diff --git a/packages/cspell-dictionary/src/SpellingDictionary/SpellingDictionaryCollection.test.ts b/packages/cspell-dictionary/src/SpellingDictionary/SpellingDictionaryCollection.test.ts index c84641227694..365ec821db1f 100644 --- a/packages/cspell-dictionary/src/SpellingDictionary/SpellingDictionaryCollection.test.ts +++ b/packages/cspell-dictionary/src/SpellingDictionary/SpellingDictionaryCollection.test.ts @@ -125,7 +125,7 @@ describe('Verify using multiple dictionaries', () => { }); test('checks mapWord is identity', async () => { - const dicts = await Promise.all([createSpellingDictionary(wordsA, 'wordsA', 'test', opts())]); + const dicts = [createSpellingDictionary(wordsA, 'wordsA', 'test', opts())]; const dictCollection = createCollection(dicts, 'test'); expect(dictCollection.mapWord('Hello')).toBe('Hello'); diff --git a/packages/cspell-dictionary/src/SpellingDictionary/SpellingDictionaryFromTrie.ts b/packages/cspell-dictionary/src/SpellingDictionary/SpellingDictionaryFromTrie.ts index a722ac498f4e..c179eb744bdf 100644 --- a/packages/cspell-dictionary/src/SpellingDictionary/SpellingDictionaryFromTrie.ts +++ b/packages/cspell-dictionary/src/SpellingDictionary/SpellingDictionaryFromTrie.ts @@ -236,10 +236,8 @@ function findCache(fn: FindFunction, size = 2000): FindFunction { ignoreCase: boolean, ): FindAnyFormResult | undefined { const r = cache.get(word); - if (r !== undefined) { - if (r.useCompounds === useCompounds && r.ignoreCase === ignoreCase) { - return r.findResult; - } + if (r !== undefined && r.useCompounds === useCompounds && r.ignoreCase === ignoreCase) { + return r.findResult; } const findResult = fn(word, useCompounds, ignoreCase); cache.set(word, { useCompounds, ignoreCase, findResult }); diff --git a/packages/cspell-dictionary/src/util/braceExpansion.ts b/packages/cspell-dictionary/src/util/braceExpansion.ts index 3570b8dbd59b..af7b96f8684c 100644 --- a/packages/cspell-dictionary/src/util/braceExpansion.ts +++ b/packages/cspell-dictionary/src/util/braceExpansion.ts @@ -4,11 +4,8 @@ export interface Options { sep: string; } -function expand( - pattern: string, - options: Options = { begin: '(', end: ')', sep: '|' }, - start = 0, -): { parts: string[]; idx: number } { +function expand(pattern: string, options?: Options, start = 0): { parts: string[]; idx: number } { + const _options = options ?? { begin: '(', end: ')', sep: '|' }; const len = pattern.length; const parts: string[] = []; function push(word: string | string[]) { @@ -22,16 +19,16 @@ function expand( let curWord: string | string[] = ''; while (i < len) { const ch = pattern[i++]; - if (ch === options.end) { + if (ch === _options.end) { break; } - if (ch === options.begin) { - const nested = expand(pattern, options, i); + if (ch === _options.begin) { + const nested = expand(pattern, _options, i); i = nested.idx; curWord = nested.parts.flatMap((p) => (Array.isArray(curWord) ? curWord.map((w) => w + p) : [curWord + p])); continue; } - if (ch === options.sep) { + if (ch === _options.sep) { push(curWord); curWord = ''; continue; @@ -42,6 +39,6 @@ function expand( return { parts, idx: i }; } -export function expandBraces(pattern: string, options: Options = { begin: '(', end: ')', sep: '|' }): string[] { - return expand(pattern, options).parts; +export function expandBraces(pattern: string, options?: Options): string[] { + return expand(pattern, options ?? { begin: '(', end: ')', sep: '|' }).parts; } diff --git a/packages/cspell-dictionary/src/util/clean.test.ts b/packages/cspell-dictionary/src/util/clean.test.ts index c40f383eedd5..83eaf8caee14 100644 --- a/packages/cspell-dictionary/src/util/clean.test.ts +++ b/packages/cspell-dictionary/src/util/clean.test.ts @@ -12,6 +12,6 @@ describe('Validate util', () => { e: 'str', }; const cleanObj = clean(obj); - expect([...Object.keys(cleanObj)]).toEqual(['b', 'c', 'e']); + expect(Object.keys(cleanObj)).toEqual(['b', 'c', 'e']); }); }); diff --git a/packages/cspell-dictionary/src/util/repMap.ts b/packages/cspell-dictionary/src/util/repMap.ts index 2f9e58d4100e..991af3379790 100644 --- a/packages/cspell-dictionary/src/util/repMap.ts +++ b/packages/cspell-dictionary/src/util/repMap.ts @@ -67,10 +67,10 @@ function createMapperRegExp(repMap: ReplaceMap): RegExp { .map((s) => { try { // fix up any nested () - const r = s.match(/\(/) ? s.replaceAll(/\((?=.*\))/g, '(?:').replaceAll('(?:?', '(?') : s; + const r = /\(/.test(s) ? s.replaceAll(/\((?=.*\))/g, '(?:').replaceAll('(?:?', '(?') : s; new RegExp(r); s = r; - } catch (_err) { + } catch { return escapeRegEx(s); } return s; diff --git a/packages/cspell-dictionary/src/util/text.ts b/packages/cspell-dictionary/src/util/text.ts index e40356619635..3859e38b9f86 100644 --- a/packages/cspell-dictionary/src/util/text.ts +++ b/packages/cspell-dictionary/src/util/text.ts @@ -4,11 +4,11 @@ const regExAllLower = /^(?:\p{Ll}\p{M}?)+$/u; const regExAccents = /\p{M}/gu; export function isUpperCase(word: string): boolean { - return !!word.match(regExAllUpper); + return !!regExAllUpper.test(word); } export function isLowerCase(word: string): boolean { - return !!word.match(regExAllLower); + return !!regExAllLower.test(word); } export function isFirstCharacterUpper(word: string): boolean { @@ -28,13 +28,13 @@ export function lcFirst(word: string): string { } export function matchCase(example: string, word: string): string { - if (example.match(regExFirstUpper)) { + if (regExFirstUpper.test(example)) { return word.slice(0, 1).toUpperCase() + word.slice(1).toLowerCase(); } - if (example.match(regExAllLower)) { + if (regExAllLower.test(example)) { return word.toLowerCase(); } - if (example.match(regExAllUpper)) { + if (regExAllUpper.test(example)) { return word.toUpperCase(); } diff --git a/packages/cspell-eslint-plugin/src/plugin/cspell-eslint-plugin.cts b/packages/cspell-eslint-plugin/src/plugin/cspell-eslint-plugin.cts index b5f012d99136..84cf977124ea 100644 --- a/packages/cspell-eslint-plugin/src/plugin/cspell-eslint-plugin.cts +++ b/packages/cspell-eslint-plugin/src/plugin/cspell-eslint-plugin.cts @@ -56,6 +56,7 @@ const ruleMeta: Rule.RuleMetaData = { let isDebugMode = false; function nullFix(): null { + // eslint-disable-next-line unicorn/no-null return null; } diff --git a/packages/cspell-eslint-plugin/src/plugin/index.cts b/packages/cspell-eslint-plugin/src/plugin/index.cts index c18d49d83ba5..f4d0db85bf3a 100644 --- a/packages/cspell-eslint-plugin/src/plugin/index.cts +++ b/packages/cspell-eslint-plugin/src/plugin/index.cts @@ -1,4 +1,2 @@ export type { Options } from '../common/options.cjs'; -import { plugin } from './cspell-eslint-plugin.cjs'; -export { configs, meta, rules } from './cspell-eslint-plugin.cjs'; -export default plugin; +export { configs, plugin as default, meta, rules } from './cspell-eslint-plugin.cjs'; diff --git a/packages/cspell-eslint-plugin/src/test/index.test.mts b/packages/cspell-eslint-plugin/src/test/index.test.mts index d1f8f6936038..1a14e612c036 100644 --- a/packages/cspell-eslint-plugin/src/test/index.test.mts +++ b/packages/cspell-eslint-plugin/src/test/index.test.mts @@ -234,7 +234,7 @@ interface ValidTestCaseEsLint9 extends ValidTestCase { function readFix(filename: string, options?: Options): ValidTestCase { const __filename = resolveFix(filename); - const code = fs.readFileSync(__filename, 'utf-8'); + const code = fs.readFileSync(__filename, 'utf8'); const sample: ValidTestCaseEsLint9 = { code, diff --git a/packages/cspell-eslint-plugin/src/worker/spellCheck.mts b/packages/cspell-eslint-plugin/src/worker/spellCheck.mts index 773413175b20..229a623570ba 100644 --- a/packages/cspell-eslint-plugin/src/worker/spellCheck.mts +++ b/packages/cspell-eslint-plugin/src/worker/spellCheck.mts @@ -446,7 +446,7 @@ function deepEqual(a: unknown, b: unknown): boolean { try { assert.deepStrictEqual(a, b); return true; - } catch (_) { + } catch { return false; } } diff --git a/packages/cspell-gitignore/src/GitIgnoreFile.ts b/packages/cspell-gitignore/src/GitIgnoreFile.ts index 5495f0a06bc7..2b3b4f8189a2 100644 --- a/packages/cspell-gitignore/src/GitIgnoreFile.ts +++ b/packages/cspell-gitignore/src/GitIgnoreFile.ts @@ -116,7 +116,7 @@ export async function loadGitIgnore(dir: string): Promise { const filename = path.join(root, file); const patterns = pattern.split('|'); const _options = options ?? root; - if (typeof _options !== 'string' && typeof _options !== 'undefined') { + if (typeof _options !== 'string' && _options !== undefined) { _options.root = _options.root ?? root; } expected = typeof expected === 'boolean' ? { matched: expected } : expected; diff --git a/packages/cspell-grammar/src/app.ts b/packages/cspell-grammar/src/app.ts index 709cb3c75e78..603c1f5e8c44 100644 --- a/packages/cspell-grammar/src/app.ts +++ b/packages/cspell-grammar/src/app.ts @@ -21,7 +21,7 @@ export async function run(args: string[]): Promise { return; } - const filename = args.slice(2).filter((p) => !p.startsWith('-'))[0]; + const filename = args.slice(2).find((p) => !p.startsWith('-')); if (!filename) { console.log('filename missing'); return; @@ -35,7 +35,7 @@ export async function run(args: string[]): Promise { } console.log(`File: ${path.basename(filename)} Parser: ${parser.name}`); - const content = await fs.readFile(filename, 'utf-8'); + const content = await fs.readFile(filename, 'utf8'); const result = parser.parse(content, filename); for (const pt of result.parsedTexts) { diff --git a/packages/cspell-grammar/src/mappers/typescript.test.ts b/packages/cspell-grammar/src/mappers/typescript.test.ts index d153a084a813..c1db829e01de 100644 --- a/packages/cspell-grammar/src/mappers/typescript.test.ts +++ b/packages/cspell-grammar/src/mappers/typescript.test.ts @@ -30,7 +30,7 @@ describe('mappers typescript', () => { ${'hello'} | ${'hello'} ${'caf\\xe9'} | ${'café'} ${'caf\\u00e9'} | ${'café'} - ${'hello\\x20there'} | ${'hello\x20there'} + ${'hello\\x20there'} | ${'hello\u0020there'} ${'hello\\u0020there'} | ${'hello\u0020there'} ${'hello\\u{020}there'} | ${'hello\u{020}there'} ${'a\\tb'} | ${'a\tb'} @@ -80,6 +80,7 @@ function toCharCodes(s: string): string { function toCharCodesNumber(s: string): number[] { const codes: number[] = []; for (let i = 0; i < s.length; ++i) { + // eslint-disable-next-line unicorn/prefer-code-point codes.push(s.charCodeAt(i)); } return codes; diff --git a/packages/cspell-grammar/src/mappers/typescript.ts b/packages/cspell-grammar/src/mappers/typescript.ts index d6ebdfd0b57c..1eaef5d45e1f 100644 --- a/packages/cspell-grammar/src/mappers/typescript.ts +++ b/packages/cspell-grammar/src/mappers/typescript.ts @@ -60,14 +60,14 @@ export function mapRawString(text: string): MappedText { continue; } switch (tc) { - case 'u': + case 'u': { { let char: string; let end: number; if (text[i + 1] !== '{') { const digits = text.slice(i + 1, i + 5); - parsed = isHex.test(digits) ? parseInt(digits, 16) : NaN; - char = isNaN(parsed) ? '' : String.fromCharCode(parsed); + parsed = isHex.test(digits) ? Number.parseInt(digits, 16) : Number.NaN; + char = Number.isNaN(parsed) ? '' : String.fromCodePoint(parsed); end = i + 4; } else { for (end = i + 2; text[end] in hexChars; ++end) { @@ -77,8 +77,8 @@ export function mapRawString(text: string): MappedText { char = ''; } else { const digits = text.slice(i + 2, end); - parsed = isHex.test(digits) ? parseInt(digits, 16) : NaN; - char = isNaN(parsed) ? '' : String.fromCodePoint(parsed); + parsed = isHex.test(digits) ? Number.parseInt(digits, 16) : Number.NaN; + char = Number.isNaN(parsed) ? '' : String.fromCodePoint(parsed); } } if (!char) { @@ -91,37 +91,44 @@ export function mapRawString(text: string): MappedText { } } break; - case 'x': + } + case 'x': { { const digits = text.slice(i + 1, i + 3); - parsed = isHex.test(digits) ? parseInt(digits, 16) : NaN; - if (isNaN(parsed)) { + parsed = isHex.test(digits) ? Number.parseInt(digits, 16) : Number.NaN; + if (Number.isNaN(parsed)) { // give up, it is not valid t += tc; j += 1; } else { - t += String.fromCharCode(parsed); + t += String.fromCodePoint(parsed); i += 2; ++j; } } break; - case '0': + } + case '0': { // Deprecated in ES5 t += '0'; j += 1; break; - case '\r': + } + case '\r': { i += text[i + 1] === '\n' ? 1 : 0; break; - case '\n': + } + case '\n': { break; - case undefined: + } + case undefined: { break; - default: + } + default: { t += tc; ++j; break; + } } map.push(i + 1, j); continue; diff --git a/packages/cspell-grammar/src/parsers/typescript/index.test.ts b/packages/cspell-grammar/src/parsers/typescript/index.test.ts index 241a2b1fca88..a81e63e534e6 100644 --- a/packages/cspell-grammar/src/parsers/typescript/index.test.ts +++ b/packages/cspell-grammar/src/parsers/typescript/index.test.ts @@ -25,7 +25,7 @@ describe('TypeScript Parser', () => { }); function readSample(filename: string): Promise { - return fs.readFile(path.resolve(fixtures, filename), 'utf-8'); + return fs.readFile(path.resolve(fixtures, filename), 'utf8'); } function stringifyResult(result: ParseResult): string { diff --git a/packages/cspell-grammar/src/viewer/escapeMarkdown.ts b/packages/cspell-grammar/src/viewer/escapeMarkdown.ts index b3382c614a40..0daa1702138d 100644 --- a/packages/cspell-grammar/src/viewer/escapeMarkdown.ts +++ b/packages/cspell-grammar/src/viewer/escapeMarkdown.ts @@ -29,7 +29,7 @@ function _escape(str: string, r: RegExp): string { while (r.test(str)) { const i = r.lastIndex - 1; - html += str.substring(lastIndex, i) + cvt[str.charCodeAt(i)]; + html += str.substring(lastIndex, i) + (cvt[str.codePointAt(i) || 0] || ''); lastIndex = r.lastIndex; } return html + str.substring(lastIndex); @@ -44,7 +44,9 @@ function compileEntities(entityMap: Record): string[] { } for (const [char, entity] of Object.entries(entityMap)) { - result[char.charCodeAt(0)] = entity; + const index = char.codePointAt(0); + if (!index) continue; + result[index] = entity; } return result; } diff --git a/packages/cspell-grammar/src/viewer/visualizeAsMD.ts b/packages/cspell-grammar/src/viewer/visualizeAsMD.ts index 80f55f2a8d5c..16742a3c8c49 100644 --- a/packages/cspell-grammar/src/viewer/visualizeAsMD.ts +++ b/packages/cspell-grammar/src/viewer/visualizeAsMD.ts @@ -9,8 +9,7 @@ export function _tokenizedLineToMarkdown(line: TokenizedLine, indentation = ''): | text | scope | | --------- | -------------------------------------------------------- |`; - markdownLines.push(...header.split('\n')); - markdownLines.push(...line.tokens.map((t) => ` | ${toInlineCode(t.text)} | ${t.scope} |`)); + markdownLines.push(...header.split('\n'), ...line.tokens.map((t) => ` | ${toInlineCode(t.text)} | ${t.scope} |`)); return markdownLines.map((line) => indentation + line).join('\n') + '\n\n'; } diff --git a/packages/cspell-io/src/CSpellIONode.test.ts b/packages/cspell-io/src/CSpellIONode.test.ts index 356e18d46a87..0a827ba119c0 100644 --- a/packages/cspell-io/src/CSpellIONode.test.ts +++ b/packages/cspell-io/src/CSpellIONode.test.ts @@ -173,7 +173,7 @@ describe('CSpellIONode', () => { ${pathToTemp('cities.txt')} ${pathToTemp('cities.txt.gz')} `('writeFile $filename', async ({ filename }) => { - const content = await fs.readFile(ps('cities.txt'), 'utf-8'); + const content = await fs.readFile(ps('cities.txt'), 'utf8'); const cspellIo = new CSpellIONode(); await makePathToFile(filename); await cspellIo.writeFile(filename, content); diff --git a/packages/cspell-io/src/VirtualFS.ts b/packages/cspell-io/src/VirtualFS.ts index 87963e1ba631..48a3f02f3a34 100644 --- a/packages/cspell-io/src/VirtualFS.ts +++ b/packages/cspell-io/src/VirtualFS.ts @@ -229,7 +229,7 @@ class CVirtualFS implements VirtualFS { for (const [key, fs] of [...this.cachedFs].reverse()) { try { WrappedProviderFs.disposeOf(fs); - } catch (_) { + } catch { // continue - we are cleaning up. } this.cachedFs.delete(key); @@ -243,7 +243,7 @@ class CVirtualFS implements VirtualFS { for (const provider of providers) { try { provider.dispose?.(); - } catch (_) { + } catch { // continue - we are cleaning up. } } diff --git a/packages/cspell-io/src/common/CFileResource.test.ts b/packages/cspell-io/src/common/CFileResource.test.ts index 886cd0925db6..fb672d26dc1e 100644 --- a/packages/cspell-io/src/common/CFileResource.test.ts +++ b/packages/cspell-io/src/common/CFileResource.test.ts @@ -9,7 +9,7 @@ describe('CFileResource', () => { const fileResource = { url: new URL('https://example.com/file.txt'), content: 'Hello, world!', - encoding: 'utf-8', + encoding: 'utf8', } as const; // Act @@ -28,7 +28,7 @@ describe('CFileResource', () => { const fileResource = { url: new URL('https://example.com/file.txt'), content: 'Hello, world!', - encoding: 'utf-8', + encoding: 'utf8', } as const; const content = 'Welcome to a new day!'; @@ -70,7 +70,7 @@ describe('CFileResource', () => { // Arrange const url = new URL('https://example.com/file.txt'); const content = 'Hello, world!'; - const encoding = 'utf-8'; + const encoding = 'utf8'; const baseFilename = 'file.txt'; const gz = true; @@ -95,7 +95,7 @@ describe('CFileResource', () => { const fileResource = { url: new URL('https://example.com/file.txt'), content: Buffer.from(content), - encoding: 'utf-8', + encoding: 'utf8', } as const; // Act diff --git a/packages/cspell-io/src/common/arrayBuffers.test.ts b/packages/cspell-io/src/common/arrayBuffers.test.ts index b5661782d1c6..9cfbcbf424fc 100644 --- a/packages/cspell-io/src/common/arrayBuffers.test.ts +++ b/packages/cspell-io/src/common/arrayBuffers.test.ts @@ -15,8 +15,8 @@ describe('arrayBuffers', () => { test('asUint8Array', () => { const buf = Buffer.from(sampleText); const u8 = asUint8Array(buf); - expect(u8[0]).toBe(sampleText.charCodeAt(0)); - expect(buf[0]).toBe(sampleText.charCodeAt(0)); + expect(u8[0]).toBe(sampleText.codePointAt(0)); + expect(buf[0]).toBe(sampleText.codePointAt(0)); u8[0] = 32; expect(u8[0]).toBe(32); expect(u8[0]).toBe(buf[0]); diff --git a/packages/cspell-io/src/common/encode-decode.test.ts b/packages/cspell-io/src/common/encode-decode.test.ts index 8a945bf297f0..198010d689dd 100644 --- a/packages/cspell-io/src/common/encode-decode.test.ts +++ b/packages/cspell-io/src/common/encode-decode.test.ts @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/text-encoding-identifier-case */ import { describe, expect, test } from 'vitest'; import { arrayBufferViewToBuffer, swap16 as swapBytesInPlace, swapBytes } from './arrayBuffers.js'; diff --git a/packages/cspell-io/src/common/encode-decode.ts b/packages/cspell-io/src/common/encode-decode.ts index 75399b8265de..05cc5d7316a7 100644 --- a/packages/cspell-io/src/common/encode-decode.ts +++ b/packages/cspell-io/src/common/encode-decode.ts @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/text-encoding-identifier-case */ import { gunzipSync } from 'node:zlib'; import { arrayBufferViewToBuffer, asUint8Array, swap16, swapBytes } from './arrayBuffers.js'; @@ -6,7 +7,7 @@ import type { BufferEncodingExt, TextEncodingExt } from './BufferEncoding.js'; const BOM_BE = 0xfeff; const BOM_LE = 0xfffe; -const decoderUTF8 = new TextDecoder('utf-8'); +const decoderUTF8 = new TextDecoder('utf8'); const decoderUTF16LE = new TextDecoder('utf-16le'); const decoderUTF16BE = createTextDecoderUtf16BE(); @@ -38,14 +39,17 @@ export function decodeToString(data: ArrayBufferView, encoding?: TextEncodingExt switch (encoding) { case 'utf-16be': - case 'utf16be': + case 'utf16be': { return decodeUtf16BE(buf); + } case 'utf-16le': - case 'utf16le': + case 'utf16le': { return decodeUtf16LE(buf); + } case 'utf-8': - case 'utf8': + case 'utf8': { return decoderUTF8.decode(buf); + } } throw new UnsupportedEncodingError(encoding); @@ -55,8 +59,9 @@ export function decode(data: ArrayBufferView, encoding?: BufferEncodingExt): str switch (encoding) { case 'base64': case 'base64url': - case 'hex': + case 'hex': { return arrayBufferViewToBuffer(data).toString(encoding); + } } const result = decodeToString(data, encoding); @@ -67,11 +72,13 @@ export function decode(data: ArrayBufferView, encoding?: BufferEncodingExt): str export function encodeString(str: string, encoding?: BufferEncodingExt, bom?: boolean): ArrayBufferView { switch (encoding) { case 'utf-16be': - case 'utf16be': + case 'utf16be': { return encodeUtf16BE(str, bom); + } case 'utf-16le': - case 'utf16le': + case 'utf16le': { return encodeUtf16LE(str, bom); + } } return Buffer.from(str, encoding); } @@ -96,10 +103,12 @@ export function calcEncodingFromBom(data: ArrayBufferView): 'utf16be' | 'utf16le const buf = asUint8Array(data); if (buf.length < 2) return undefined; switch ((buf[0] << 8) | buf[1]) { - case BOM_BE: + case BOM_BE: { return 'utf16be'; - case BOM_LE: + } + case BOM_LE: { return 'utf16le'; + } } return undefined; } @@ -108,7 +117,7 @@ function createTextDecoderUtf16BE() { try { const decoder = new TextDecoder('utf-16be'); return decoder; - } catch (_) { + } catch { return { encoding: 'utf-16be', fatal: false, diff --git a/packages/cspell-io/src/errors/assert.test.ts b/packages/cspell-io/src/errors/assert.test.ts index 3e044ebd8aaa..44aeb73ddb0c 100644 --- a/packages/cspell-io/src/errors/assert.test.ts +++ b/packages/cspell-io/src/errors/assert.test.ts @@ -14,12 +14,12 @@ describe('assert', () => { }); test.each` - value | message | expected - ${false} | ${'test'} | ${new AssertionError('test')} - ${0} | ${undefined} | ${new AssertionError('Assertion failed')} - ${undefined} | ${null} | ${new AssertionError('Assertion failed')} - ${null} | ${''} | ${new AssertionError('')} - ${NaN} | ${'NaN'} | ${new AssertionError('NaN')} + value | message | expected + ${false} | ${'test'} | ${new AssertionError('test')} + ${0} | ${undefined} | ${new AssertionError('Assertion failed')} + ${undefined} | ${null} | ${new AssertionError('Assertion failed')} + ${null} | ${''} | ${new AssertionError('')} + ${Number.NaN} | ${'NaN'} | ${new AssertionError('NaN')} `('failed assert $value', ({ value, message, expected }) => { expect(() => assert(value, message)).toThrow(expected); }); diff --git a/packages/cspell-io/src/handlers/node/file.ts b/packages/cspell-io/src/handlers/node/file.ts index 5f7903381bb6..fddbab89e5e7 100644 --- a/packages/cspell-io/src/handlers/node/file.ts +++ b/packages/cspell-io/src/handlers/node/file.ts @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/text-encoding-identifier-case */ import type { Dirent, Stats as FsStats } from 'node:fs'; import { promises as fs, readFileSync, statSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; @@ -283,7 +284,7 @@ export function registerHandlers(serviceBus: ServiceBus) { function encodeContent(ref: FileReference, content: string | ArrayBufferView): string | Buffer { if (typeof content === 'string') { - if (!ref.encoding || ref.encoding === 'utf-8') return content; + if ([undefined, 'utf8', 'utf-8'].includes(ref.encoding)) return content; return arrayBufferViewToBuffer(encodeString(content, ref.encoding)); } return arrayBufferViewToBuffer(content); diff --git a/packages/cspell-io/src/models/BufferEncoding.ts b/packages/cspell-io/src/models/BufferEncoding.ts index f1abedd1779e..d0a75ff5cca2 100644 --- a/packages/cspell-io/src/models/BufferEncoding.ts +++ b/packages/cspell-io/src/models/BufferEncoding.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line unicorn/text-encoding-identifier-case export type TextEncoding = 'utf-8' | 'utf8' | 'utf16le' | 'utf16be' | 'utf-16le' | 'utf-16be'; export type BufferEncoding = 'base64' | 'base64url' | 'hex' | TextEncoding; diff --git a/packages/cspell-io/src/node/dataUrl.test.ts b/packages/cspell-io/src/node/dataUrl.test.ts index dc3b3ac3fc8f..2555246dcf73 100644 --- a/packages/cspell-io/src/node/dataUrl.test.ts +++ b/packages/cspell-io/src/node/dataUrl.test.ts @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/text-encoding-identifier-case */ import { describe, expect, test } from 'vitest'; import { pathToSample } from '../test/test.helper.js'; diff --git a/packages/cspell-io/src/node/dataUrl.ts b/packages/cspell-io/src/node/dataUrl.ts index 78b269fd327e..9684e07f4963 100644 --- a/packages/cspell-io/src/node/dataUrl.ts +++ b/packages/cspell-io/src/node/dataUrl.ts @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/text-encoding-identifier-case */ import { promises as fs } from 'node:fs'; import * as fsPath from 'node:path'; @@ -67,9 +68,9 @@ const dataUrlRegExHead = /^data:(?[^;,]*)(?(?:;[^=]+=[^;, export function decodeDataUrl(url: string | URL): DecodedDataUrl { url = url.toString(); const [head, encodedData] = url.split(',', 2); - if (!head || encodedData === undefined) throw Error('Not a data url'); + if (!head || encodedData === undefined) throw new Error('Not a data url'); const match = head.match(dataUrlRegExHead); - if (!match || !match.groups) throw Error('Not a data url'); + if (!match || !match.groups) throw new Error('Not a data url'); const mediaType = match.groups['mediaType'] || ''; const rawAttributes = (match.groups['attributes'] || '') .split(';') diff --git a/packages/cspell-io/src/node/file/fileWriter.ts b/packages/cspell-io/src/node/file/fileWriter.ts index 51652ea2faf0..8eafe0d688d5 100644 --- a/packages/cspell-io/src/node/file/fileWriter.ts +++ b/packages/cspell-io/src/node/file/fileWriter.ts @@ -22,6 +22,6 @@ export function writeToFileIterable( encoding?: BufferEncodingExt, ): Promise { const stream = Stream.Readable.from(encoderTransformer(data, encoding)); - const zip = filename.match(/\.gz$/) ? zlib.createGzip() : new Stream.PassThrough(); + const zip = /\.gz$/.test(filename) ? zlib.createGzip() : new Stream.PassThrough(); return pipeline(stream, zip, fs.createWriteStream(filename)); } diff --git a/packages/cspell-io/src/node/file/url.ts b/packages/cspell-io/src/node/file/url.ts index c3b16320e94a..4c92ad8d93ad 100644 --- a/packages/cspell-io/src/node/file/url.ts +++ b/packages/cspell-io/src/node/file/url.ts @@ -88,7 +88,7 @@ export function urlDirname(url: string | URL): URL { try { return new URL(url.pathname.endsWith('/') ? '..' : '.', url); - } catch (_) { + } catch { return url; } } @@ -99,7 +99,7 @@ export function urlDirname(url: string | URL): URL { * @returns */ export function basename(path: string): string { - path = path.endsWith('/') ? path.slice(0, path.length - 1) : path; + path = path.endsWith('/') ? path.slice(0, -1) : path; const idx = path.lastIndexOf('/'); return idx >= 0 ? path.slice(idx + 1) : path; } diff --git a/packages/cspell-lib/api/api.d.ts b/packages/cspell-lib/api/api.d.ts index 923fee47ca97..8661ee26934d 100644 --- a/packages/cspell-lib/api/api.d.ts +++ b/packages/cspell-lib/api/api.d.ts @@ -1,104 +1,30 @@ /// -import { Glob, CSpellSettingsWithSourceTrace, TextOffset, TextDocumentOffset, AdvancedCSpellSettingsWithSourceTrace, Parser, DictionaryDefinitionInline, DictionaryDefinitionPreferred, DictionaryDefinitionAugmented, DictionaryDefinitionCustom, ImportFileRef, PnPSettings, CSpellUserSettings, Issue, LocaleId, CSpellSettings, MappedText, ParsedText } from '@cspell/cspell-types'; +import { Glob, AdvancedCSpellSettingsWithSourceTrace, Parser, DictionaryDefinitionInline, DictionaryDefinitionPreferred, DictionaryDefinitionAugmented, DictionaryDefinitionCustom, CSpellUserSettings, ImportFileRef, PnPSettings, CSpellSettingsWithSourceTrace, TextOffset, Issue, LocaleId, CSpellSettings, MappedText, ParsedText, TextDocumentOffset } from '@cspell/cspell-types'; export * from '@cspell/cspell-types'; -import { WeightMap } from 'cspell-trie-lib'; -export { CompoundWordsMethod } from 'cspell-trie-lib'; -import { CSpellConfigFile } from 'cspell-config-lib'; import * as cspell_io from 'cspell-io'; import { VFileSystem } from 'cspell-io'; export { FSCapabilityFlags, VFileSystemProvider, VirtualFS, asyncIterableToArray, readFileText as readFile, readFileTextSync as readFileSync, writeToFile, writeToFileIterable, writeToFileIterableP } from 'cspell-io'; -import { SuggestOptions, SuggestionResult, CachingDictionary, SpellingDictionaryCollection } from 'cspell-dictionary'; +import { SpellingDictionaryCollection, SuggestOptions, SuggestionResult, CachingDictionary } from 'cspell-dictionary'; export { SpellingDictionary, SpellingDictionaryCollection, SuggestOptions, SuggestionCollector, SuggestionResult, createSpellingDictionary, createCollection as createSpellingDictionaryCollection } from 'cspell-dictionary'; +import { WeightMap } from 'cspell-trie-lib'; +export { CompoundWordsMethod } from 'cspell-trie-lib'; +import { CSpellConfigFile } from 'cspell-config-lib'; -type ExclusionFunction = (fileUri: string) => boolean; -type FileExclusionFunction = (file: string) => boolean; -/** The structure of the VS Code search.exclude settings */ -interface ExcludeFilesGlobMap { - [glob: string]: boolean; -} -declare function extractGlobsFromExcludeFilesGlobMap(globMap: ExcludeFilesGlobMap): string[]; /** - * @todo Support multi root globs. - * @param globs - glob patterns - * @param root - root directory - * @param allowedSchemes - allowed schemas - */ -declare function generateExclusionFunctionForUri(globs: Glob[], root: string, allowedSchemes?: Set): ExclusionFunction; -/** - * @todo Support multi root globs. - * @param globs - glob patterns - * @param root - root directory - * @param allowedSchemes - allowed schemas + * Clear the cached files and other cached data. + * Calling this function will cause the next spell check to take longer because it will need to reload configuration files and dictionaries. + * Call this function if configuration files have changed. + * + * It is safe to replace {@link clearCachedFiles} with {@link clearCaches} */ -declare function generateExclusionFunctionForFiles(globs: Glob[], root: string): FileExclusionFunction; - -type exclusionHelper_d_ExcludeFilesGlobMap = ExcludeFilesGlobMap; -type exclusionHelper_d_ExclusionFunction = ExclusionFunction; -type exclusionHelper_d_FileExclusionFunction = FileExclusionFunction; -declare const exclusionHelper_d_extractGlobsFromExcludeFilesGlobMap: typeof extractGlobsFromExcludeFilesGlobMap; -declare const exclusionHelper_d_generateExclusionFunctionForFiles: typeof generateExclusionFunctionForFiles; -declare const exclusionHelper_d_generateExclusionFunctionForUri: typeof generateExclusionFunctionForUri; -declare namespace exclusionHelper_d { - export { type exclusionHelper_d_ExcludeFilesGlobMap as ExcludeFilesGlobMap, type exclusionHelper_d_ExclusionFunction as ExclusionFunction, type exclusionHelper_d_FileExclusionFunction as FileExclusionFunction, exclusionHelper_d_extractGlobsFromExcludeFilesGlobMap as extractGlobsFromExcludeFilesGlobMap, exclusionHelper_d_generateExclusionFunctionForFiles as generateExclusionFunctionForFiles, exclusionHelper_d_generateExclusionFunctionForUri as generateExclusionFunctionForUri }; -} - -interface ListGlobalImportsResult { - filename: string; - name: string | undefined; - id: string | undefined; - error: string | undefined; - dictionaryDefinitions: CSpellSettingsWithSourceTrace['dictionaryDefinitions']; - languageSettings: CSpellSettingsWithSourceTrace['languageSettings']; - package: NodePackage | undefined; -} -interface ListGlobalImportsResults { - list: ListGlobalImportsResult[]; - globalSettings: CSpellSettingsWithSourceTrace; -} -interface NodePackage { - name: string | undefined; - filename: string; -} -declare function listGlobalImports(): Promise; -interface AddPathsToGlobalImportsResults { - success: boolean; - resolvedSettings: ResolveSettingsResult[]; - error: string | undefined; -} -declare function addPathsToGlobalImports(paths: string[]): Promise; -interface RemovePathsFromGlobalImportsResult { - success: boolean; - error: string | undefined; - removed: string[]; -} +declare function clearCachedFiles(): Promise; /** - * Remove files from the global setting. - * @param paths match against the partial file path, or package name, or id. - * To match against a partial file path, it must match against the subdirectory and filename. - * Note: for Idempotent reasons, asking to remove a path that is not in the global settings is considered a success. - * It is possible to check for this by looking at the returned list of removed paths. + * Sends and event to clear the caches. + * It resets the configuration files and dictionaries. + * + * It is safe to replace {@link clearCaches} with {@link clearCachedFiles} */ -declare function removePathsFromGlobalImports(paths: string[]): Promise; -interface ResolveSettingsResult { - filename: string; - resolvedToFilename: string | undefined; - error?: string; - settings: CSpellSettingsWithSourceTrace; -} - -//# sourceMappingURL=index.link.d.ts.map - -type index_link_d_AddPathsToGlobalImportsResults = AddPathsToGlobalImportsResults; -type index_link_d_ListGlobalImportsResult = ListGlobalImportsResult; -type index_link_d_ListGlobalImportsResults = ListGlobalImportsResults; -type index_link_d_RemovePathsFromGlobalImportsResult = RemovePathsFromGlobalImportsResult; -type index_link_d_ResolveSettingsResult = ResolveSettingsResult; -declare const index_link_d_addPathsToGlobalImports: typeof addPathsToGlobalImports; -declare const index_link_d_listGlobalImports: typeof listGlobalImports; -declare const index_link_d_removePathsFromGlobalImports: typeof removePathsFromGlobalImports; -declare namespace index_link_d { - export { type index_link_d_AddPathsToGlobalImportsResults as AddPathsToGlobalImportsResults, type index_link_d_ListGlobalImportsResult as ListGlobalImportsResult, type index_link_d_ListGlobalImportsResults as ListGlobalImportsResults, type index_link_d_RemovePathsFromGlobalImportsResult as RemovePathsFromGlobalImportsResult, type index_link_d_ResolveSettingsResult as ResolveSettingsResult, index_link_d_addPathsToGlobalImports as addPathsToGlobalImports, index_link_d_listGlobalImports as listGlobalImports, index_link_d_removePathsFromGlobalImports as removePathsFromGlobalImports }; -} +declare function clearCaches(): void; interface Uri { readonly scheme: string; @@ -108,86 +34,6 @@ interface Uri { readonly query?: string; } -declare function stringToRegExp(pattern: string | RegExp, defaultFlags?: string, forceFlags?: string): RegExp | undefined; - -declare function splitCamelCaseWordWithOffset(wo: TextOffset): Array; -/** - * Split camelCase words into an array of strings. - */ -declare function splitCamelCaseWord(word: string): string[]; -/** - * This function lets you iterate over regular expression matches. - */ -declare function match(reg: RegExp, text: string): Iterable; -declare function matchStringToTextOffset(reg: RegExp, text: string): Iterable; -declare function matchToTextOffset(reg: RegExp, text: TextOffset): Iterable; -declare function extractLinesOfText(text: string): Iterable; -/** - * Extract out whole words from a string of text. - */ -declare function extractWordsFromText(text: string): Iterable; -/** - * Extract out whole words from a string of text. - */ -declare function extractWordsFromTextOffset(text: TextOffset): Iterable; -declare function cleanText(text: string): string; -declare function cleanTextOffset(text: TextOffset): TextOffset; -/** - * Extract out whole words and words containing numbers from a string of text. - */ -declare function extractPossibleWordsFromTextOffset(text: TextOffset): Iterable; -declare function extractWordsFromCode(text: string): Iterable; -declare function extractWordsFromCodeTextOffset(textOffset: TextOffset): Iterable; -declare function isUpperCase(word: string): boolean; -declare function isLowerCase(word: string): boolean; -declare function isFirstCharacterUpper(word: string): boolean; -declare function isFirstCharacterLower(word: string): boolean; -declare function ucFirst(word: string): string; -declare function lcFirst(word: string): string; -declare function snakeToCamel(word: string): string; -declare function camelToSnake(word: string): string; -declare function matchCase(example: string, word: string): string; -declare function textOffset(text: string, offset?: number): TextOffset; -declare function extractText(textOffset: TextOffset, startPos: number, endPos: number): string; -declare function calculateTextDocumentOffsets(uri: string | Uri | URL, doc: string, wordOffsets: T[]): (TextDocumentOffset & T)[]; -declare function removeAccents(text: string): string; -declare const __testing__: { - regExWords: RegExp; - regExWordsAndDigits: RegExp; -}; - -declare const text_d___testing__: typeof __testing__; -declare const text_d_calculateTextDocumentOffsets: typeof calculateTextDocumentOffsets; -declare const text_d_camelToSnake: typeof camelToSnake; -declare const text_d_cleanText: typeof cleanText; -declare const text_d_cleanTextOffset: typeof cleanTextOffset; -declare const text_d_extractLinesOfText: typeof extractLinesOfText; -declare const text_d_extractPossibleWordsFromTextOffset: typeof extractPossibleWordsFromTextOffset; -declare const text_d_extractText: typeof extractText; -declare const text_d_extractWordsFromCode: typeof extractWordsFromCode; -declare const text_d_extractWordsFromCodeTextOffset: typeof extractWordsFromCodeTextOffset; -declare const text_d_extractWordsFromText: typeof extractWordsFromText; -declare const text_d_extractWordsFromTextOffset: typeof extractWordsFromTextOffset; -declare const text_d_isFirstCharacterLower: typeof isFirstCharacterLower; -declare const text_d_isFirstCharacterUpper: typeof isFirstCharacterUpper; -declare const text_d_isLowerCase: typeof isLowerCase; -declare const text_d_isUpperCase: typeof isUpperCase; -declare const text_d_lcFirst: typeof lcFirst; -declare const text_d_match: typeof match; -declare const text_d_matchCase: typeof matchCase; -declare const text_d_matchStringToTextOffset: typeof matchStringToTextOffset; -declare const text_d_matchToTextOffset: typeof matchToTextOffset; -declare const text_d_removeAccents: typeof removeAccents; -declare const text_d_snakeToCamel: typeof snakeToCamel; -declare const text_d_splitCamelCaseWord: typeof splitCamelCaseWord; -declare const text_d_splitCamelCaseWordWithOffset: typeof splitCamelCaseWordWithOffset; -declare const text_d_stringToRegExp: typeof stringToRegExp; -declare const text_d_textOffset: typeof textOffset; -declare const text_d_ucFirst: typeof ucFirst; -declare namespace text_d { - export { text_d___testing__ as __testing__, text_d_calculateTextDocumentOffsets as calculateTextDocumentOffsets, text_d_camelToSnake as camelToSnake, text_d_cleanText as cleanText, text_d_cleanTextOffset as cleanTextOffset, text_d_extractLinesOfText as extractLinesOfText, text_d_extractPossibleWordsFromTextOffset as extractPossibleWordsFromTextOffset, text_d_extractText as extractText, text_d_extractWordsFromCode as extractWordsFromCode, text_d_extractWordsFromCodeTextOffset as extractWordsFromCodeTextOffset, text_d_extractWordsFromText as extractWordsFromText, text_d_extractWordsFromTextOffset as extractWordsFromTextOffset, text_d_isFirstCharacterLower as isFirstCharacterLower, text_d_isFirstCharacterUpper as isFirstCharacterUpper, text_d_isLowerCase as isLowerCase, text_d_isUpperCase as isUpperCase, text_d_lcFirst as lcFirst, text_d_match as match, text_d_matchCase as matchCase, text_d_matchStringToTextOffset as matchStringToTextOffset, text_d_matchToTextOffset as matchToTextOffset, text_d_removeAccents as removeAccents, text_d_snakeToCamel as snakeToCamel, text_d_splitCamelCaseWord as splitCamelCaseWord, text_d_splitCamelCaseWordWithOffset as splitCamelCaseWordWithOffset, text_d_stringToRegExp as stringToRegExp, text_d_textOffset as textOffset, text_d_ucFirst as ucFirst }; -} - interface Document { uri: UriString; text?: string; @@ -288,6 +134,38 @@ declare function fileToDocument(file: string, text: string, languageId?: string, declare function fileToDocument(file: string, text?: string, languageId?: string, locale?: string): Document | DocumentWithText; declare function fileToTextDocument(file: string): Promise; +type ExclusionFunction = (fileUri: string) => boolean; +type FileExclusionFunction = (file: string) => boolean; +/** The structure of the VS Code search.exclude settings */ +interface ExcludeFilesGlobMap { + [glob: string]: boolean; +} +declare function extractGlobsFromExcludeFilesGlobMap(globMap: ExcludeFilesGlobMap): string[]; +/** + * @todo Support multi root globs. + * @param globs - glob patterns + * @param root - root directory + * @param allowedSchemes - allowed schemas + */ +declare function generateExclusionFunctionForUri(globs: Glob[], root: string, allowedSchemes?: Set): ExclusionFunction; +/** + * @todo Support multi root globs. + * @param globs - glob patterns + * @param root - root directory + * @param allowedSchemes - allowed schemas + */ +declare function generateExclusionFunctionForFiles(globs: Glob[], root: string): FileExclusionFunction; + +type exclusionHelper_d_ExcludeFilesGlobMap = ExcludeFilesGlobMap; +type exclusionHelper_d_ExclusionFunction = ExclusionFunction; +type exclusionHelper_d_FileExclusionFunction = FileExclusionFunction; +declare const exclusionHelper_d_extractGlobsFromExcludeFilesGlobMap: typeof extractGlobsFromExcludeFilesGlobMap; +declare const exclusionHelper_d_generateExclusionFunctionForFiles: typeof generateExclusionFunctionForFiles; +declare const exclusionHelper_d_generateExclusionFunctionForUri: typeof generateExclusionFunctionForUri; +declare namespace exclusionHelper_d { + export { type exclusionHelper_d_ExcludeFilesGlobMap as ExcludeFilesGlobMap, type exclusionHelper_d_ExclusionFunction as ExclusionFunction, type exclusionHelper_d_FileExclusionFunction as FileExclusionFunction, exclusionHelper_d_extractGlobsFromExcludeFilesGlobMap as extractGlobsFromExcludeFilesGlobMap, exclusionHelper_d_generateExclusionFunctionForFiles as generateExclusionFunctionForFiles, exclusionHelper_d_generateExclusionFunctionForUri as generateExclusionFunctionForUri }; +} + interface FeatureFlag { name: string; description: string; @@ -317,9 +195,7 @@ declare class UnknownFeatureFlagError extends Error { } declare function getSystemFeatureFlags(): FeatureFlags; -type LanguageId = string; -declare function getLanguagesForExt(ext: string): string[]; -declare function getLanguagesForBasename(basename: string): string[]; +declare function getVirtualFS(): cspell_io.VirtualFS; /** * The keys of an object where the values cannot be undefined. @@ -360,6 +236,40 @@ interface DictionaryFileDefinitionInternal extends Readonly; + +type LoadOptions = DictionaryDefinitionInternal; + +declare class SpellingDictionaryLoadError extends Error { + readonly uri: string; + readonly options: LoadOptions; + readonly cause: Error; + readonly name: string; + constructor(uri: string, options: LoadOptions, cause: Error, message: string); +} +declare function isSpellingDictionaryLoadError(e: Error): e is SpellingDictionaryLoadError; + +/** + * Load a dictionary collection defined by the settings. + * @param settings - that defines the dictionaries and the ones to load. + * @returns a dictionary collection that represents all the enabled dictionaries. + */ +declare function getDictionary(settings: CSpellUserSettings): Promise; + +type LanguageId = string; +declare function getLanguagesForExt(ext: string): string[]; +declare function getLanguagesForBasename(basename: string): string[]; + +interface PerfTimer { + readonly name: string; + readonly startTime: number; + readonly elapsed: number; + start(): void; + end(): void; +} +type TimeNowFn = () => number; +declare function createPerfTimer(name: string, onEnd?: (elapsed: number, name: string) => void, timeNowFn?: TimeNowFn): PerfTimer; + type CSpellSettingsWST$1 = AdvancedCSpellSettingsWithSourceTrace; type CSpellSettingsWSTO = OptionalOrUndefined; type CSpellSettingsI$1 = CSpellSettingsInternal; @@ -395,20 +305,9 @@ declare function calcOverrideSettings(settings: CSpellSettingsWSTO, filename: st */ declare function checkFilenameMatchesExcludeGlob(filename: string, globs: Glob | Glob[]): boolean; -/** - * @param filename - filename - * @param globs - globs - * @returns true if it matches - * @deprecated true - * @deprecationMessage No longer actively supported. Use package: `cspell-glob`. - */ -declare const checkFilenameMatchesGlob: typeof checkFilenameMatchesExcludeGlob; - declare const currentSettingsFileVersion = "0.2"; declare const ENV_CSPELL_GLOB_ROOT = "CSPELL_GLOB_ROOT"; -declare function getVirtualFS(): cspell_io.VirtualFS; - interface ResolveFileResult { /** * Absolute path or URL to the file. @@ -555,6 +454,64 @@ declare class ImportError extends Error { declare function getDefaultSettings(useDefaultDictionaries?: boolean): Promise; declare function getDefaultBundledSettingsAsync(): Promise; +interface ListGlobalImportsResult { + filename: string; + name: string | undefined; + id: string | undefined; + error: string | undefined; + dictionaryDefinitions: CSpellSettingsWithSourceTrace['dictionaryDefinitions']; + languageSettings: CSpellSettingsWithSourceTrace['languageSettings']; + package: NodePackage | undefined; +} +interface ListGlobalImportsResults { + list: ListGlobalImportsResult[]; + globalSettings: CSpellSettingsWithSourceTrace; +} +interface NodePackage { + name: string | undefined; + filename: string; +} +declare function listGlobalImports(): Promise; +interface AddPathsToGlobalImportsResults { + success: boolean; + resolvedSettings: ResolveSettingsResult[]; + error: string | undefined; +} +declare function addPathsToGlobalImports(paths: string[]): Promise; +interface RemovePathsFromGlobalImportsResult { + success: boolean; + error: string | undefined; + removed: string[]; +} +/** + * Remove files from the global setting. + * @param paths match against the partial file path, or package name, or id. + * To match against a partial file path, it must match against the subdirectory and filename. + * Note: for Idempotent reasons, asking to remove a path that is not in the global settings is considered a success. + * It is possible to check for this by looking at the returned list of removed paths. + */ +declare function removePathsFromGlobalImports(paths: string[]): Promise; +interface ResolveSettingsResult { + filename: string; + resolvedToFilename: string | undefined; + error?: string; + settings: CSpellSettingsWithSourceTrace; +} + +//# sourceMappingURL=index.link.d.ts.map + +type index_link_d_AddPathsToGlobalImportsResults = AddPathsToGlobalImportsResults; +type index_link_d_ListGlobalImportsResult = ListGlobalImportsResult; +type index_link_d_ListGlobalImportsResults = ListGlobalImportsResults; +type index_link_d_RemovePathsFromGlobalImportsResult = RemovePathsFromGlobalImportsResult; +type index_link_d_ResolveSettingsResult = ResolveSettingsResult; +declare const index_link_d_addPathsToGlobalImports: typeof addPathsToGlobalImports; +declare const index_link_d_listGlobalImports: typeof listGlobalImports; +declare const index_link_d_removePathsFromGlobalImports: typeof removePathsFromGlobalImports; +declare namespace index_link_d { + export { type index_link_d_AddPathsToGlobalImportsResults as AddPathsToGlobalImportsResults, type index_link_d_ListGlobalImportsResult as ListGlobalImportsResult, type index_link_d_ListGlobalImportsResults as ListGlobalImportsResults, type index_link_d_RemovePathsFromGlobalImportsResult as RemovePathsFromGlobalImportsResult, type index_link_d_ResolveSettingsResult as ResolveSettingsResult, index_link_d_addPathsToGlobalImports as addPathsToGlobalImports, index_link_d_listGlobalImports as listGlobalImports, index_link_d_removePathsFromGlobalImports as removePathsFromGlobalImports }; +} + declare function combineTextAndLanguageSettings(settings: CSpellUserSettings, text: string | undefined, languageId: string | string[]): CSpellSettingsInternal; interface ExtendedSuggestion { @@ -583,19 +540,6 @@ interface ValidationIssue extends ValidationResult { suggestionsEx?: ExtendedSuggestion[] | undefined; } -declare function refreshDictionaryCache(maxAge?: number): Promise; - -type LoadOptions = DictionaryDefinitionInternal; - -declare class SpellingDictionaryLoadError extends Error { - readonly uri: string; - readonly options: LoadOptions; - readonly cause: Error; - readonly name: string; - constructor(uri: string, options: LoadOptions, cause: Error, message: string); -} -declare function isSpellingDictionaryLoadError(e: Error): e is SpellingDictionaryLoadError; - type Href = string; interface DictionaryTraceResult { word: string; @@ -1013,37 +957,84 @@ declare function setLogger(logger: Logger): Logger; */ declare function getLogger(): Logger; +declare function stringToRegExp(pattern: string | RegExp, defaultFlags?: string, forceFlags?: string): RegExp | undefined; + +declare function splitCamelCaseWordWithOffset(wo: TextOffset): Array; /** - * Clear the cached files and other cached data. - * Calling this function will cause the next spell check to take longer because it will need to reload configuration files and dictionaries. - * Call this function if configuration files have changed. - * - * It is safe to replace {@link clearCachedFiles} with {@link clearCaches} + * Split camelCase words into an array of strings. */ -declare function clearCachedFiles(): Promise; +declare function splitCamelCaseWord(word: string): string[]; /** - * Sends and event to clear the caches. - * It resets the configuration files and dictionaries. - * - * It is safe to replace {@link clearCaches} with {@link clearCachedFiles} + * This function lets you iterate over regular expression matches. */ -declare function clearCaches(): void; - +declare function match(reg: RegExp, text: string): Iterable; +declare function matchStringToTextOffset(reg: RegExp, text: string): Iterable; +declare function matchToTextOffset(reg: RegExp, text: TextOffset): Iterable; +declare function extractLinesOfText(text: string): Iterable; /** - * Load a dictionary collection defined by the settings. - * @param settings - that defines the dictionaries and the ones to load. - * @returns a dictionary collection that represents all the enabled dictionaries. + * Extract out whole words from a string of text. */ -declare function getDictionary(settings: CSpellUserSettings): Promise; +declare function extractWordsFromText(text: string): Iterable; +/** + * Extract out whole words from a string of text. + */ +declare function extractWordsFromTextOffset(text: TextOffset): Iterable; +declare function cleanText(text: string): string; +declare function cleanTextOffset(text: TextOffset): TextOffset; +/** + * Extract out whole words and words containing numbers from a string of text. + */ +declare function extractPossibleWordsFromTextOffset(text: TextOffset): Iterable; +declare function extractWordsFromCode(text: string): Iterable; +declare function extractWordsFromCodeTextOffset(textOffset: TextOffset): Iterable; +declare function isUpperCase(word: string): boolean; +declare function isLowerCase(word: string): boolean; +declare function isFirstCharacterUpper(word: string): boolean; +declare function isFirstCharacterLower(word: string): boolean; +declare function ucFirst(word: string): string; +declare function lcFirst(word: string): string; +declare function snakeToCamel(word: string): string; +declare function camelToSnake(word: string): string; +declare function matchCase(example: string, word: string): string; +declare function textOffset(text: string, offset?: number): TextOffset; +declare function extractText(textOffset: TextOffset, startPos: number, endPos: number): string; +declare function calculateTextDocumentOffsets(uri: string | Uri | URL, doc: string, wordOffsets: T[]): (TextDocumentOffset & T)[]; +declare function removeAccents(text: string): string; +declare const __testing__: { + regExWords: RegExp; + regExWordsAndDigits: RegExp; +}; -interface PerfTimer { - readonly name: string; - readonly startTime: number; - readonly elapsed: number; - start(): void; - end(): void; +declare const text_d___testing__: typeof __testing__; +declare const text_d_calculateTextDocumentOffsets: typeof calculateTextDocumentOffsets; +declare const text_d_camelToSnake: typeof camelToSnake; +declare const text_d_cleanText: typeof cleanText; +declare const text_d_cleanTextOffset: typeof cleanTextOffset; +declare const text_d_extractLinesOfText: typeof extractLinesOfText; +declare const text_d_extractPossibleWordsFromTextOffset: typeof extractPossibleWordsFromTextOffset; +declare const text_d_extractText: typeof extractText; +declare const text_d_extractWordsFromCode: typeof extractWordsFromCode; +declare const text_d_extractWordsFromCodeTextOffset: typeof extractWordsFromCodeTextOffset; +declare const text_d_extractWordsFromText: typeof extractWordsFromText; +declare const text_d_extractWordsFromTextOffset: typeof extractWordsFromTextOffset; +declare const text_d_isFirstCharacterLower: typeof isFirstCharacterLower; +declare const text_d_isFirstCharacterUpper: typeof isFirstCharacterUpper; +declare const text_d_isLowerCase: typeof isLowerCase; +declare const text_d_isUpperCase: typeof isUpperCase; +declare const text_d_lcFirst: typeof lcFirst; +declare const text_d_match: typeof match; +declare const text_d_matchCase: typeof matchCase; +declare const text_d_matchStringToTextOffset: typeof matchStringToTextOffset; +declare const text_d_matchToTextOffset: typeof matchToTextOffset; +declare const text_d_removeAccents: typeof removeAccents; +declare const text_d_snakeToCamel: typeof snakeToCamel; +declare const text_d_splitCamelCaseWord: typeof splitCamelCaseWord; +declare const text_d_splitCamelCaseWordWithOffset: typeof splitCamelCaseWordWithOffset; +declare const text_d_stringToRegExp: typeof stringToRegExp; +declare const text_d_textOffset: typeof textOffset; +declare const text_d_ucFirst: typeof ucFirst; +declare namespace text_d { + export { text_d___testing__ as __testing__, text_d_calculateTextDocumentOffsets as calculateTextDocumentOffsets, text_d_camelToSnake as camelToSnake, text_d_cleanText as cleanText, text_d_cleanTextOffset as cleanTextOffset, text_d_extractLinesOfText as extractLinesOfText, text_d_extractPossibleWordsFromTextOffset as extractPossibleWordsFromTextOffset, text_d_extractText as extractText, text_d_extractWordsFromCode as extractWordsFromCode, text_d_extractWordsFromCodeTextOffset as extractWordsFromCodeTextOffset, text_d_extractWordsFromText as extractWordsFromText, text_d_extractWordsFromTextOffset as extractWordsFromTextOffset, text_d_isFirstCharacterLower as isFirstCharacterLower, text_d_isFirstCharacterUpper as isFirstCharacterUpper, text_d_isLowerCase as isLowerCase, text_d_isUpperCase as isUpperCase, text_d_lcFirst as lcFirst, text_d_match as match, text_d_matchCase as matchCase, text_d_matchStringToTextOffset as matchStringToTextOffset, text_d_matchToTextOffset as matchToTextOffset, text_d_removeAccents as removeAccents, text_d_snakeToCamel as snakeToCamel, text_d_splitCamelCaseWord as splitCamelCaseWord, text_d_splitCamelCaseWordWithOffset as splitCamelCaseWordWithOffset, text_d_stringToRegExp as stringToRegExp, text_d_textOffset as textOffset, text_d_ucFirst as ucFirst }; } -type TimeNowFn = () => number; -declare function createPerfTimer(name: string, onEnd?: (elapsed: number, name: string) => void, timeNowFn?: TimeNowFn): PerfTimer; -export { type CheckTextInfo, type ConfigurationDependencies, type CreateTextDocumentParams, type DetermineFinalDocumentSettingsResult, type Document, DocumentValidator, type DocumentValidatorOptions, ENV_CSPELL_GLOB_ROOT, type ExcludeFilesGlobMap, type ExclusionFunction, exclusionHelper_d as ExclusionHelper, type FeatureFlag, FeatureFlags, ImportError, type ImportFileRefWithError$1 as ImportFileRefWithError, IncludeExcludeFlag, type IncludeExcludeOptions, index_link_d as Link, type Logger, type PerfTimer, type SpellCheckFileOptions, type SpellCheckFileResult, SpellingDictionaryLoadError, type SuggestedWord, SuggestionError, type SuggestionOptions, type SuggestionsForWordResult, text_d as Text, type TextDocument, type TextDocumentLine, type TextDocumentRef, type TextInfoItem, type TraceOptions, type TraceResult, type TraceWordResult, UnknownFeatureFlagError, type ValidationIssue, calcOverrideSettings, checkFilenameMatchesGlob, checkText, checkTextDocument, clearCachedFiles, clearCaches, combineTextAndLanguageSettings, combineTextAndLanguageSettings as constructSettingsForText, createConfigLoader, createPerfTimer, createTextDocument, currentSettingsFileVersion, defaultConfigFilenames, defaultFileName, defaultFileName as defaultSettingsFilename, determineFinalDocumentSettings, extractDependencies, extractImportErrors, fileToDocument, fileToTextDocument, finalizeSettings, getCachedFileSize, getDefaultBundledSettingsAsync, getDefaultConfigLoader, getDefaultSettings, getDictionary, getGlobalSettings, getGlobalSettingsAsync, getLanguagesForBasename as getLanguageIdsForBaseFilename, getLanguagesForExt, getLogger, getSources, getSystemFeatureFlags, getVirtualFS, isBinaryFile, isSpellingDictionaryLoadError, loadConfig, loadPnP, mergeInDocSettings, mergeSettings, readRawSettings, readSettings, readSettingsFiles, refreshDictionaryCache, resolveFile, searchForConfig, sectionCSpell, setLogger, shouldCheckDocument, spellCheckDocument, spellCheckFile, suggestionsForWord, suggestionsForWords, traceWords, traceWordsAsync, updateTextDocument, validateText }; +export { type CheckTextInfo, type ConfigurationDependencies, type CreateTextDocumentParams, type DetermineFinalDocumentSettingsResult, type Document, DocumentValidator, type DocumentValidatorOptions, ENV_CSPELL_GLOB_ROOT, type ExcludeFilesGlobMap, type ExclusionFunction, exclusionHelper_d as ExclusionHelper, type FeatureFlag, FeatureFlags, ImportError, type ImportFileRefWithError$1 as ImportFileRefWithError, IncludeExcludeFlag, type IncludeExcludeOptions, index_link_d as Link, type Logger, type PerfTimer, type SpellCheckFileOptions, type SpellCheckFileResult, SpellingDictionaryLoadError, type SuggestedWord, SuggestionError, type SuggestionOptions, type SuggestionsForWordResult, text_d as Text, type TextDocument, type TextDocumentLine, type TextDocumentRef, type TextInfoItem, type TraceOptions, type TraceResult, type TraceWordResult, UnknownFeatureFlagError, type ValidationIssue, calcOverrideSettings, checkFilenameMatchesExcludeGlob as checkFilenameMatchesGlob, checkText, checkTextDocument, clearCachedFiles, clearCaches, combineTextAndLanguageSettings, combineTextAndLanguageSettings as constructSettingsForText, createConfigLoader, createPerfTimer, createTextDocument, currentSettingsFileVersion, defaultConfigFilenames, defaultFileName, defaultFileName as defaultSettingsFilename, determineFinalDocumentSettings, extractDependencies, extractImportErrors, fileToDocument, fileToTextDocument, finalizeSettings, getCachedFileSize, getDefaultBundledSettingsAsync, getDefaultConfigLoader, getDefaultSettings, getDictionary, getGlobalSettings, getGlobalSettingsAsync, getLanguagesForBasename as getLanguageIdsForBaseFilename, getLanguagesForExt, getLogger, getSources, getSystemFeatureFlags, getVirtualFS, isBinaryFile, isSpellingDictionaryLoadError, loadConfig, loadPnP, mergeInDocSettings, mergeSettings, readRawSettings, readSettings, readSettingsFiles, refreshDictionaryCache, resolveFile, searchForConfig, sectionCSpell, setLogger, shouldCheckDocument, spellCheckDocument, spellCheckFile, suggestionsForWord, suggestionsForWords, traceWords, traceWordsAsync, updateTextDocument, validateText }; diff --git a/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configLoader.test.ts b/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configLoader.test.ts index 76708f25c4df..27a78193933f 100644 --- a/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configLoader.test.ts +++ b/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configLoader.test.ts @@ -52,7 +52,7 @@ const samplesDir = pathPackageSamples; const samplesSrc = path.join(samplesDir, 'src'); const testFixtures = pathRepoTestFixtures; -const urlIssues = new URL('./issues/', pathRepoTestFixturesURL); +const urlIssues = new URL('issues/', pathRepoTestFixturesURL); const oc = expect.objectContaining; const sm = expect.stringMatching; diff --git a/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configLoader.ts b/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configLoader.ts index 856cd3fd1e0e..6fb573b09a1b 100644 --- a/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configLoader.ts +++ b/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configLoader.ts @@ -240,11 +240,13 @@ export class ConfigLoader implements IConfigLoader { async searchForConfigFileLocation(searchFrom: URL | string | undefined): Promise { const url = toFileURL(searchFrom || cwdURL(), cwdURL()); - if (typeof searchFrom === 'string' && !isUrlLike(searchFrom) && url.protocol === 'file:') { - // check to see if it is a directory - if (await isDirectory(this.fs, url)) { - return this.configSearch.searchForConfig(addTrailingSlash(url)); - } + if ( + typeof searchFrom === 'string' && + !isUrlLike(searchFrom) && + url.protocol === 'file:' && // check to see if it is a directory + (await isDirectory(this.fs, url)) + ) { + return this.configSearch.searchForConfig(addTrailingSlash(url)); } return this.configSearch.searchForConfig(url); } diff --git a/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configSearch.test.ts b/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configSearch.test.ts index 023871dffed7..5956b9937581 100644 --- a/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configSearch.test.ts +++ b/packages/cspell-lib/src/lib/Settings/Controller/configLoader/configSearch.test.ts @@ -113,7 +113,7 @@ describe('ConfigSearch', () => { const result = await configSearch.searchForConfig(searchFrom); expect(result).toEqual(expectedConfigUrl); - const result2 = await configSearch.searchForConfig(new URL('./text.txt', searchFrom)); + const result2 = await configSearch.searchForConfig(new URL('text.txt', searchFrom)); expect(result2).toBe(result); configSearch.clearCache(); diff --git a/packages/cspell-lib/src/lib/Settings/Controller/pnpLoader.test.ts b/packages/cspell-lib/src/lib/Settings/Controller/pnpLoader.test.ts index 5db396134965..708947591735 100644 --- a/packages/cspell-lib/src/lib/Settings/Controller/pnpLoader.test.ts +++ b/packages/cspell-lib/src/lib/Settings/Controller/pnpLoader.test.ts @@ -14,7 +14,7 @@ const uriSamples = pathPackageSamplesURL; const uriDirectory = uriSamples; const uriYarn2TestMed = new URL('yarn2/test-yarn3-med/', uriTestPackages); const uriYarn2TestSci = new URL('yarn2/test-yarn3-sci/', uriTestPackages); -const uriBadPnp = new URL('./bad-pnp/', uriSamples); +const uriBadPnp = new URL('bad-pnp/', uriSamples); const uriYarn2TestMedPnp = new URL('.pnp.cjs', uriYarn2TestMed); const uriYarn2TestSciPnp = new URL('.pnp.cjs', uriYarn2TestSci); diff --git a/packages/cspell-lib/src/lib/Settings/Controller/pnpLoader.ts b/packages/cspell-lib/src/lib/Settings/Controller/pnpLoader.ts index 1600e01b1c4d..6de2999459a2 100644 --- a/packages/cspell-lib/src/lib/Settings/Controller/pnpLoader.ts +++ b/packages/cspell-lib/src/lib/Settings/Controller/pnpLoader.ts @@ -24,7 +24,7 @@ const cachedRequestsSync = new Map(); export class PnpLoader { private cacheKeySuffix: string; constructor(readonly pnpFiles: string[] = defaultPnpFiles) { - this.cacheKeySuffix = ':' + pnpFiles.join(); + this.cacheKeySuffix = ':' + pnpFiles.join(','); } /** diff --git a/packages/cspell-lib/src/lib/Settings/InDocSettings.test.ts b/packages/cspell-lib/src/lib/Settings/InDocSettings.test.ts index 2d50ebcd58fc..b47faa9087e1 100644 --- a/packages/cspell-lib/src/lib/Settings/InDocSettings.test.ts +++ b/packages/cspell-lib/src/lib/Settings/InDocSettings.test.ts @@ -17,30 +17,30 @@ const nac = expect.not.arrayContaining; // cSpell:ignoreRegExp /\/\/\/.*/ // cSpell:ignoreRegExp weird const sampleCode = ` - // cSpell\x3aenableCompoundWords - // cSpell\x3adisableCompoundWords - // cSpell\x3a enableCOMPOUNDWords + // cSpell\u003AenableCompoundWords + // cSpell\u003AdisableCompoundWords + // cSpell\u003A enableCOMPOUNDWords // cSpell:words whiteberry, redberry, lightbrown - // cSpell\x3a ignoreRegExp /\\/\\/\\/.*/ - // cSpell\x3aignoreRegexp w\\w+berry - // cSpell\x3a:ignoreRegExp / - /* cSpell\x3aignoreRegExp \\w+s{4}\\w+ */ - /* cSpell\x3aignoreRegExp /faullts[/]?/ */ + // cSpell\u003A ignoreRegExp /\\/\\/\\/.*/ + // cSpell\u003AignoreRegexp w\\w+berry + // cSpell\u003A:ignoreRegExp / + /* cSpell\u003AignoreRegExp \\w+s{4}\\w+ */ + /* cSpell\u003AignoreRegExp /faullts[/]?/ */ const berries = ['whiteberry', 'redberry', 'blueberry']; - /* cSpell\x3aignore tripe, comment */ - // cSpell\x3a: ignoreWords tooo faullts + /* cSpell\u003Aignore tripe, comment */ + // cSpell\u003A: ignoreWords tooo faullts /// ignore triple comment, with misssspellings and faullts /// mooree prooobleems onn thisss line tooo with wordberry // misssspellings faullts // weirdberry can be straange. - // cSpell\x3alanguage en-US - // cspell\x3alocal - // cspell\x3alocale es-ES - // cspell\x3alocal en, nl + // cSpell\u003Alanguage en-US + // cspell\u003Alocal + // cspell\u003Alocale es-ES + // cspell\u003Alocal en, nl - // cspell\x3adictionaries lorem-ipsum + // cspell\u003Adictionaries lorem-ipsum // LocalWords: one two three // LocalWords:four five six // localwords: seven eight nine @@ -48,19 +48,19 @@ const sampleCode = ` // cspell:ignore againxx const sampleText = ` -# cSpell\x3adisableCompoundWords -# cSpell\x3aenableCOMPOUNDWords +# cSpell\u003AdisableCompoundWords +# cSpell\u003AenableCOMPOUNDWords # happydays arehere againxx `; // cspell:ignore popoutlist const sampleTextWithIncompleteInDocSetting = ` -// spell\x3adictionaries php -// spell\x3awords const -// cspell\x3a -// cspell\x3aignore popoutlist +// spell\u003Adictionaries php +// spell\u003Awords const +// cspell\u003A +// cspell\u003Aignore popoutlist const x = imp.popoutlist; -// cspell\x3aignore again +// cspell\u003Aignore again `; const sampleInDocDict: DictionaryDefinitionInline = { @@ -71,7 +71,7 @@ const sampleInDocDict: DictionaryDefinitionInline = { // cspell:disable const sampleTextWithBadRegexp = ` -# cspell\x3AignoreRegExp "(foobar|foo_baz)"'); +# cspell\u003AignoreRegExp "(foobar|foo_baz)"'); `; // cspell:enable @@ -106,34 +106,34 @@ describe('Validate InDocSettings', () => { const USE_TEST = undefined; test.each` - test | text | expected - ${'Empty Doc'} | ${''} | ${{ id: 'in-doc-settings' }} - ${'cSpell\x3aenableCompoundWords'} | ${'cSpell\x3aenableCompoundWords'} | ${oc({ allowCompoundWords: true })} - ${'cSpell\x3aENABLECompoundWords'} | ${'cSpell\x3aENABLECompoundWords'} | ${oc({ allowCompoundWords: true })} - ${'cSpell\x3adisableCompoundWords'} | ${'cSpell\x3adisableCompoundWords'} | ${oc({ allowCompoundWords: false })} - ${'cSpell\x3adisableCompoundWORDS'} | ${'cSpell\x3adisableCompoundWORDS'} | ${oc({ allowCompoundWords: false })} - ${'cSpell\x3aENABLECompoundWords\ncSpell\x3adisableCompoundWords'} | ${'cSpell\x3aENABLECompoundWords\ncSpell\x3adisableCompoundWords'} | ${oc({ allowCompoundWords: false })} - ${'cSpell\x3adisableCompoundWords\ncSpell\x3aenableCompoundWords'} | ${'cSpell\x3adisableCompoundWords\ncSpell\x3aenableCompoundWords'} | ${oc({ allowCompoundWords: true })} - ${'sampleText'} | ${sampleText} | ${oc({ allowCompoundWords: true })} - ${'sampleCode'} | ${sampleCode} | ${oc({ allowCompoundWords: true })} - ${'cSpell\x3aword apple'} | ${USE_TEST} | ${oc(inDocDict({ words: ['apple'] }))} - ${'/*cSpell\x3aword apple*/'} | ${USE_TEST} | ${oc(inDocDict({ words: ['apple*/'] }))} - ${''} | ${USE_TEST} | ${oc(inDocDict({ words: ['apple', '-->'] }))} - ${''} | ${USE_TEST} | ${oc(inDocDict({ ignoreWords: ['apple', '-->'] }))} - ${''} | ${USE_TEST} | ${oc(inDocDict({ flagWords: ['apple', '-->'] }))} - ${''} | ${USE_TEST} | ${oc(inDocDict({ flagWords: ['apple', '-->'] }))} - ${'# cspell\x3aignore auto* *labeler'} | ${USE_TEST} | ${oc(inDocDict({ ignoreWords: ['auto*', '*labeler'] }))} + test | text | expected + ${'Empty Doc'} | ${''} | ${{ id: 'in-doc-settings' }} + ${'cSpell\u003AenableCompoundWords'} | ${'cSpell\u003AenableCompoundWords'} | ${oc({ allowCompoundWords: true })} + ${'cSpell\u003AENABLECompoundWords'} | ${'cSpell\u003AENABLECompoundWords'} | ${oc({ allowCompoundWords: true })} + ${'cSpell\u003AdisableCompoundWords'} | ${'cSpell\u003AdisableCompoundWords'} | ${oc({ allowCompoundWords: false })} + ${'cSpell\u003AdisableCompoundWORDS'} | ${'cSpell\u003AdisableCompoundWORDS'} | ${oc({ allowCompoundWords: false })} + ${'cSpell\u003AENABLECompoundWords\ncSpell\u003AdisableCompoundWords'} | ${'cSpell\u003AENABLECompoundWords\ncSpell\u003AdisableCompoundWords'} | ${oc({ allowCompoundWords: false })} + ${'cSpell\u003AdisableCompoundWords\ncSpell\u003AenableCompoundWords'} | ${'cSpell\u003AdisableCompoundWords\ncSpell\u003AenableCompoundWords'} | ${oc({ allowCompoundWords: true })} + ${'sampleText'} | ${sampleText} | ${oc({ allowCompoundWords: true })} + ${'sampleCode'} | ${sampleCode} | ${oc({ allowCompoundWords: true })} + ${'cSpell\u003Aword apple'} | ${USE_TEST} | ${oc(inDocDict({ words: ['apple'] }))} + ${'/*cSpell\u003Aword apple*/'} | ${USE_TEST} | ${oc(inDocDict({ words: ['apple*/'] }))} + ${''} | ${USE_TEST} | ${oc(inDocDict({ words: ['apple', '-->'] }))} + ${''} | ${USE_TEST} | ${oc(inDocDict({ ignoreWords: ['apple', '-->'] }))} + ${''} | ${USE_TEST} | ${oc(inDocDict({ flagWords: ['apple', '-->'] }))} + ${''} | ${USE_TEST} | ${oc(inDocDict({ flagWords: ['apple', '-->'] }))} + ${'# cspell\u003Aignore auto* *labeler'} | ${USE_TEST} | ${oc(inDocDict({ ignoreWords: ['auto*', '*labeler'] }))} `('detect compound words setting: $test', ({ test, text, expected }) => { expect(InDoc.getInDocumentSettings(text == USE_TEST ? test : text)).toEqual(expected); expect([...InDoc.validateInDocumentSettings(text, {})]).toEqual([]); }); test.each` - test | text | expected - ${'Empty Doc'} | ${''} | ${{ id: 'in-doc-settings' }} - ${'sampleTextWithIncompleteInDocSetting'} | ${sampleTextWithIncompleteInDocSetting} | ${oc(inDocDict(sampleInDocDict, ['php']))} - ${'enableCaseSensitive'} | ${'// cspell\x3aenableCaseSensitive'} | ${oc({ caseSensitive: true })} - ${'disableCaseSensitive'} | ${'// cspell\x3adisableCaseSensitive'} | ${oc({ caseSensitive: false })} + test | text | expected + ${'Empty Doc'} | ${''} | ${{ id: 'in-doc-settings' }} + ${'sampleTextWithIncompleteInDocSetting'} | ${sampleTextWithIncompleteInDocSetting} | ${oc(inDocDict(sampleInDocDict, ['php']))} + ${'enableCaseSensitive'} | ${'// cspell\u003AenableCaseSensitive'} | ${oc({ caseSensitive: true })} + ${'disableCaseSensitive'} | ${'// cspell\u003AdisableCaseSensitive'} | ${oc({ caseSensitive: false })} `('extract setting: $test', ({ text, expected }) => { expect(InDoc.getInDocumentSettings(text)).toEqual(expected); }); @@ -183,20 +183,20 @@ describe('Validate InDocSettings', () => { // cspell:ignore dictionar lokal test.each` - text | settings | expected - ${''} | ${{}} | ${[]} - ${'cspell\x3a */'} | ${{}} | ${[]} - ${'cspell\x3a ignore x */'} | ${{}} | ${[]} - ${'cspell\x3a word*/'} | ${{}} | ${[]} - ${'cspell\x3a word-*/'} | ${{}} | ${[oc({ message: 'Unknown CSpell directive', text: 'word-' })]} - ${'spell-checker\x3a word-*/'} | ${{}} | ${[oc({ message: 'Unknown CSpell directive', text: 'word-' })]} - ${'spellchecker\x3a word-*/'} | ${{}} | ${[oc({ message: 'Unknown CSpell directive', text: 'word-' })]} - ${'spell\x3a ignore-next-occurrence */'} | ${{}} | ${[oc({ message: 'Unknown CSpell directive', text: 'ignore-next-occurrence' })]} - ${'cspell\x3adictionar dutch'} | ${{}} | ${[oc({ range: [7, 16], suggestions: ac(['dictionary', 'dictionaries']), text: 'dictionar' })]} - ${'cspell\x3a:dictionar dutch'} | ${{}} | ${[oc({ range: [8, 17], suggestions: ac(['dictionary', 'dictionaries']), text: 'dictionar' })]} - ${'cspell\x3a ignored */'} | ${{}} | ${[oc({ range: [8, 15], suggestions: ac(['ignore', 'ignoreWord']), text: 'ignored' })]} - ${'cspell\x3alokal en'} | ${{}} | ${[oc({ suggestions: ac(['locale']) })]} - ${'cspell\x3alokal en'} | ${{}} | ${[oc({ suggestions: nac(['local']) })]} + text | settings | expected + ${''} | ${{}} | ${[]} + ${'cspell\u003A */'} | ${{}} | ${[]} + ${'cspell\u003A ignore x */'} | ${{}} | ${[]} + ${'cspell\u003A word*/'} | ${{}} | ${[]} + ${'cspell\u003A word-*/'} | ${{}} | ${[oc({ message: 'Unknown CSpell directive', text: 'word-' })]} + ${'spell-checker\u003A word-*/'} | ${{}} | ${[oc({ message: 'Unknown CSpell directive', text: 'word-' })]} + ${'spellchecker\u003A word-*/'} | ${{}} | ${[oc({ message: 'Unknown CSpell directive', text: 'word-' })]} + ${'spell\u003A ignore-next-occurrence */'} | ${{}} | ${[oc({ message: 'Unknown CSpell directive', text: 'ignore-next-occurrence' })]} + ${'cspell\u003Adictionar dutch'} | ${{}} | ${[oc({ range: [7, 16], suggestions: ac(['dictionary', 'dictionaries']), text: 'dictionar' })]} + ${'cspell\u003A:dictionar dutch'} | ${{}} | ${[oc({ range: [8, 17], suggestions: ac(['dictionary', 'dictionaries']), text: 'dictionar' })]} + ${'cspell\u003A ignored */'} | ${{}} | ${[oc({ range: [8, 15], suggestions: ac(['ignore', 'ignoreWord']), text: 'ignored' })]} + ${'cspell\u003Alokal en'} | ${{}} | ${[oc({ suggestions: ac(['locale']) })]} + ${'cspell\u003Alokal en'} | ${{}} | ${[oc({ suggestions: nac(['local']) })]} `('validateInDocumentSettings', ({ text, settings, expected }) => { const result = [...InDoc.validateInDocumentSettings(text, settings)]; expect(result).toEqual(expected); diff --git a/packages/cspell-lib/src/lib/Settings/InDocSettings.ts b/packages/cspell-lib/src/lib/Settings/InDocSettings.ts index 0b3385e6e80a..a1db99b82556 100644 --- a/packages/cspell-lib/src/lib/Settings/InDocSettings.ts +++ b/packages/cspell-lib/src/lib/Settings/InDocSettings.ts @@ -220,10 +220,8 @@ function* filterUniqueSuggestions(sugs: Iterable): Iterable< for (const sug of sugs) { const existing = map.get(sug.word); - if (existing) { - if (sug.isPreferred) { - existing.isPreferred = true; - } + if (existing && sug.isPreferred) { + existing.isPreferred = true; } yield sug; } diff --git a/packages/cspell-lib/src/lib/Settings/RegExpPatterns.test.ts b/packages/cspell-lib/src/lib/Settings/RegExpPatterns.test.ts index 3148bdfaa807..58a8c7b80f33 100644 --- a/packages/cspell-lib/src/lib/Settings/RegExpPatterns.test.ts +++ b/packages/cspell-lib/src/lib/Settings/RegExpPatterns.test.ts @@ -457,7 +457,7 @@ describe('Validate InDocSettings', () => { test('regExIgnoreSpellingDirectives', () => { const match = sampleBug345.match(RegPat.regExIgnoreSpellingDirectives); - expect(match?.[0]).toBe('cspell\x3AignoreRegExp "(foobar|foobaz)"'); + expect(match?.[0]).toBe('cspell\u003AignoreRegExp "(foobar|foobaz)"'); }); }); @@ -591,4 +591,4 @@ pAqEAuV4DNoxQKKWmhVv+J0ptMWD25Pnpxeq5sXzghfJnslJlQND const sampleCode2LF = sampleCodeSrc.replaceAll(/\r?\n/g, '\n'); const sampleCode2CRLF = sampleCode2LF.replaceAll('\n', '\r\n'); -const sampleBug345 = fs.readFileSync(Path.join(pathPackageSamples, './bug-fixes/bug345.ts'), 'utf-8'); +const sampleBug345 = fs.readFileSync(Path.join(pathPackageSamples, './bug-fixes/bug345.ts'), 'utf8'); diff --git a/packages/cspell-lib/src/lib/Settings/checkFilenameMatchesGlob.ts b/packages/cspell-lib/src/lib/Settings/checkFilenameMatchesGlob.ts index f179810cf903..c187277ed7d4 100644 --- a/packages/cspell-lib/src/lib/Settings/checkFilenameMatchesGlob.ts +++ b/packages/cspell-lib/src/lib/Settings/checkFilenameMatchesGlob.ts @@ -1,5 +1,3 @@ -import { checkFilenameMatchesExcludeGlob } from '../globs/checkFilenameMatchesGlob.js'; - /** * @param filename - filename * @param globs - globs @@ -7,4 +5,5 @@ import { checkFilenameMatchesExcludeGlob } from '../globs/checkFilenameMatchesGl * @deprecated true * @deprecationMessage No longer actively supported. Use package: `cspell-glob`. */ -export const checkFilenameMatchesGlob = checkFilenameMatchesExcludeGlob; + +export { checkFilenameMatchesExcludeGlob as checkFilenameMatchesGlob } from '../globs/checkFilenameMatchesGlob.js'; diff --git a/packages/cspell-lib/src/lib/Settings/link.ts b/packages/cspell-lib/src/lib/Settings/link.ts index 3c70c8119cf0..07d330e40f38 100644 --- a/packages/cspell-lib/src/lib/Settings/link.ts +++ b/packages/cspell-lib/src/lib/Settings/link.ts @@ -58,7 +58,7 @@ function isString(s: string | undefined): s is string { export async function addPathsToGlobalImports(paths: string[]): Promise { const resolvedSettings = await Promise.all(paths.map(resolveSettings)); - const hasError = resolvedSettings.filter((r) => !!r.error).length > 0; + const hasError = resolvedSettings.some((r) => !!r.error); if (hasError) { return { success: false, diff --git a/packages/cspell-lib/src/lib/SpellingDictionary/SuggestExperimental/helpers.ts b/packages/cspell-lib/src/lib/SpellingDictionary/SuggestExperimental/helpers.ts index c755de0cc051..b69306ac8c7c 100644 --- a/packages/cspell-lib/src/lib/SpellingDictionary/SuggestExperimental/helpers.ts +++ b/packages/cspell-lib/src/lib/SpellingDictionary/SuggestExperimental/helpers.ts @@ -30,9 +30,9 @@ export function wordToTwoLetterFeatures(word: string): Feature[] { export function segmentString(s: string, segLen: number): string[] { const count = Math.max(0, s.length - segLen + 1); - const result: string[] = new Array(count); + const result: string[] = []; for (let i = 0; i < count; ++i) { - result[i] = s.substr(i, segLen); + result[i] = s.slice(i, i + segLen); } return result; } diff --git a/packages/cspell-lib/src/lib/clearCachedFiles.ts b/packages/cspell-lib/src/lib/clearCachedFiles.ts index a13f955f530c..fefa6be68a50 100644 --- a/packages/cspell-lib/src/lib/clearCachedFiles.ts +++ b/packages/cspell-lib/src/lib/clearCachedFiles.ts @@ -20,7 +20,7 @@ export function clearCachedFiles(): Promise { function _clearCachedFiles(): Promise { // We want to dispatch immediately. dispatchClearCache(); - return Promise.all([refreshDictionaryCache(0)]).then(() => undefined); + return refreshDictionaryCache(0).then(() => undefined); } /** diff --git a/packages/cspell-lib/src/lib/index.ts b/packages/cspell-lib/src/lib/index.ts index a403d480b8c7..15d715874f21 100644 --- a/packages/cspell-lib/src/lib/index.ts +++ b/packages/cspell-lib/src/lib/index.ts @@ -1,11 +1,12 @@ -import * as ExclusionHelper from './exclusionHelper.js'; -import * as Link from './Settings/index.link.js'; -import * as Text from './util/text.js'; - +export { clearCachedFiles, clearCaches } from './clearCachedFiles.js'; export type { Document } from './Document/index.js'; export { fileToDocument, fileToTextDocument, isBinaryFile } from './Document/index.js'; export { ExcludeFilesGlobMap, ExclusionFunction } from './exclusionHelper.js'; +export * as ExclusionHelper from './exclusionHelper.js'; export { FeatureFlag, FeatureFlags, getSystemFeatureFlags, UnknownFeatureFlagError } from './FeatureFlags/index.js'; +export type { VFileSystemProvider, VirtualFS } from './fileSystem.js'; +export { FSCapabilityFlags, getVirtualFS } from './fileSystem.js'; +export { getDictionary } from './getDictionary.js'; export { getLanguagesForBasename as getLanguageIdsForBaseFilename, getLanguagesForExt } from './LanguageIds.js'; export type { CreateTextDocumentParams, @@ -14,6 +15,8 @@ export type { TextDocumentRef, } from './Models/TextDocument.js'; export { createTextDocument, updateTextDocument } from './Models/TextDocument.js'; +export type { PerfTimer } from './perf/index.js'; +export { createPerfTimer } from './perf/index.js'; export { calcOverrideSettings, checkFilenameMatchesGlob, @@ -46,6 +49,7 @@ export { sectionCSpell, } from './Settings/index.js'; export { defaultFileName as defaultSettingsFilename } from './Settings/index.js'; +export * as Link from './Settings/index.link.js'; export { combineTextAndLanguageSettings, combineTextAndLanguageSettings as constructSettingsForText, @@ -78,6 +82,7 @@ export type { TraceOptions, TraceResult, TraceWordResult } from './trace.js'; export { traceWords, traceWordsAsync } from './trace.js'; export { getLogger, Logger, setLogger } from './util/logger.js'; export { resolveFile } from './util/resolveFile.js'; +export * as Text from './util/text.js'; export { checkText, checkTextDocument, @@ -97,11 +102,3 @@ export { writeToFileIterable, writeToFileIterableP, } from 'cspell-io'; -export { Link, Text }; -export { ExclusionHelper }; -export { clearCachedFiles, clearCaches } from './clearCachedFiles.js'; -export type { VFileSystemProvider, VirtualFS } from './fileSystem.js'; -export { FSCapabilityFlags, getVirtualFS } from './fileSystem.js'; -export { getDictionary } from './getDictionary.js'; -export type { PerfTimer } from './perf/index.js'; -export { createPerfTimer } from './perf/index.js'; diff --git a/packages/cspell-lib/src/lib/spellCheckFile.test.ts b/packages/cspell-lib/src/lib/spellCheckFile.test.ts index 72f6962d14f3..a4a8dc5c529a 100644 --- a/packages/cspell-lib/src/lib/spellCheckFile.test.ts +++ b/packages/cspell-lib/src/lib/spellCheckFile.test.ts @@ -67,16 +67,16 @@ describe('Validate Determine settings', () => { const doc = fileToDocument; test.each` - document | settings | expected | comment - ${doc(u('README.md'), '# README\n')} | ${{}} | ${{ languageId: 'markdown', language: 'en' }} | ${'from uri'} - ${doc(u('README.md'), '# README\n \x63spell:locale fr')} | ${{}} | ${{ languageId: 'markdown', language: 'fr' }} | ${'In doc locale'} - ${doc('stdin:///', '# README\n', 'markdown')} | ${{}} | ${{ languageId: 'markdown', language: 'en' }} | ${'passed with doc'} - ${doc('stdin:///README.txt', '# README\n')} | ${{}} | ${{ languageId: 'plaintext', language: 'en' }} | ${'from stdin uri'} - ${doc(u('README.md'), '# README\n', 'plaintext')} | ${{}} | ${{ languageId: 'plaintext', language: 'en' }} | ${'override with doc'} - ${doc(u('README.md'), '# README\n', undefined, 'fr')} | ${{}} | ${{ languageId: 'markdown', language: 'fr' }} | ${'passed with doc'} - ${doc(u('README.md'), '# README\n \x63spell:locale fr', undefined, 'en')} | ${{}} | ${{ languageId: 'markdown', language: 'fr' }} | ${'In doc locale wins'} - ${doc(u('README.md'), '# README\n')} | ${{ language: 'fr' }} | ${{ languageId: 'markdown', language: 'fr' }} | ${'Language from settings'} - ${doc(u('README.md'), '# README\n', undefined, 'en')} | ${{ language: 'fr' }} | ${{ languageId: 'markdown', language: 'en' }} | ${'passed with doc'} + document | settings | expected | comment + ${doc(u('README.md'), '# README\n')} | ${{}} | ${{ languageId: 'markdown', language: 'en' }} | ${'from uri'} + ${doc(u('README.md'), '# README\n \u0063spell:locale fr')} | ${{}} | ${{ languageId: 'markdown', language: 'fr' }} | ${'In doc locale'} + ${doc('stdin:///', '# README\n', 'markdown')} | ${{}} | ${{ languageId: 'markdown', language: 'en' }} | ${'passed with doc'} + ${doc('stdin:///README.txt', '# README\n')} | ${{}} | ${{ languageId: 'plaintext', language: 'en' }} | ${'from stdin uri'} + ${doc(u('README.md'), '# README\n', 'plaintext')} | ${{}} | ${{ languageId: 'plaintext', language: 'en' }} | ${'override with doc'} + ${doc(u('README.md'), '# README\n', undefined, 'fr')} | ${{}} | ${{ languageId: 'markdown', language: 'fr' }} | ${'passed with doc'} + ${doc(u('README.md'), '# README\n \u0063spell:locale fr', undefined, 'en')} | ${{}} | ${{ languageId: 'markdown', language: 'fr' }} | ${'In doc locale wins'} + ${doc(u('README.md'), '# README\n')} | ${{ language: 'fr' }} | ${{ languageId: 'markdown', language: 'fr' }} | ${'Language from settings'} + ${doc(u('README.md'), '# README\n', undefined, 'en')} | ${{ language: 'fr' }} | ${{ languageId: 'markdown', language: 'en' }} | ${'passed with doc'} `( 'determineFinalDocumentSettings($document, $settings) $expected $comment', async ({ document, settings, expected }) => { diff --git a/packages/cspell-lib/src/lib/test/bugs.spec.ts b/packages/cspell-lib/src/lib/test/bugs.spec.ts index 4edc9681a8bb..e2723a99317d 100644 --- a/packages/cspell-lib/src/lib/test/bugs.spec.ts +++ b/packages/cspell-lib/src/lib/test/bugs.spec.ts @@ -20,7 +20,7 @@ describe('Validate Against Bug Fixes', () => { async () => { const fullFilename = path.resolve(samples, filename); const ext = path.extname(filename); - const text = await fsp.readFile(fullFilename, 'utf-8'); + const text = await fsp.readFile(fullFilename, 'utf8'); const languageIds = cspell.getLanguagesForExt(ext); const settings = cspell.mergeSettings( await cspell.getDefaultBundledSettingsAsync(), diff --git a/packages/cspell-lib/src/lib/textValidation/checkText.ts b/packages/cspell-lib/src/lib/textValidation/checkText.ts index 82f7b76286d3..7c4016cd4520 100644 --- a/packages/cspell-lib/src/lib/textValidation/checkText.ts +++ b/packages/cspell-lib/src/lib/textValidation/checkText.ts @@ -99,18 +99,20 @@ function genResult(text: string, issues: ValidationIssue[], includeRanges: Match const result: TextInfoItem[] = []; let lastPos = 0; for (const { startPos, endPos } of includeRanges) { - result.push({ - text: text.slice(lastPos, startPos), - startPos: lastPos, - endPos: startPos, - flagIE: IncludeExcludeFlag.EXCLUDE, - }); - result.push({ - text: text.slice(startPos, endPos), - startPos, - endPos, - flagIE: IncludeExcludeFlag.INCLUDE, - }); + result.push( + { + text: text.slice(lastPos, startPos), + startPos: lastPos, + endPos: startPos, + flagIE: IncludeExcludeFlag.EXCLUDE, + }, + { + text: text.slice(startPos, endPos), + startPos, + endPos, + flagIE: IncludeExcludeFlag.INCLUDE, + }, + ); lastPos = endPos; } result.push({ diff --git a/packages/cspell-lib/src/lib/textValidation/docValidator.ts b/packages/cspell-lib/src/lib/textValidation/docValidator.ts index 64271407a2cb..3810e9376c8f 100644 --- a/packages/cspell-lib/src/lib/textValidation/docValidator.ts +++ b/packages/cspell-lib/src/lib/textValidation/docValidator.ts @@ -140,6 +140,7 @@ export class DocumentValidator { recGlobMatcherTime(); const recShouldCheckTime = recordPerfTime(this.perfTiming, '_shouldCheck'); + // eslint-disable-next-line unicorn/prefer-regexp-test const shouldCheck = !matcher.match(uriToFilePath(uri)) && (docSettings.enabled ?? true); recShouldCheckTime(); @@ -476,7 +477,7 @@ async function searchForDocumentConfig( pnpSettings: PnPSettings, ): Promise { const { uri } = document; - if (uri.scheme !== 'file') return Promise.resolve(defaultConfig); + if (uri.scheme !== 'file') return defaultConfig; return searchForConfig(uri.toString(), pnpSettings).then((s) => s || defaultConfig); } @@ -519,6 +520,7 @@ export async function shouldCheckDocument( const matcher = getGlobMatcherForExcluding(localConfig?.ignorePaths); const docSettings = await determineTextDocumentSettings(doc, config); const uri = doc.uri; + // eslint-disable-next-line unicorn/prefer-regexp-test return !matcher.match(uriToFilePath(uri)) && (docSettings.enabled ?? true); } diff --git a/packages/cspell-lib/src/lib/textValidation/traceWord.ts b/packages/cspell-lib/src/lib/textValidation/traceWord.ts index d23dd70fdf53..ea095a8a26be 100644 --- a/packages/cspell-lib/src/lib/textValidation/traceWord.ts +++ b/packages/cspell-lib/src/lib/textValidation/traceWord.ts @@ -60,7 +60,7 @@ export function traceWord( const unique = uniqueFn((w: WordSplits) => w.word + '|' + w.found); const wsFound = { word, found: dictCollection.has(word, opts) }; - const wordSplits = wfSplits.find((s) => s.word === word) ? wfSplits : [wsFound, ...wfSplits]; + const wordSplits = wfSplits.some((s) => s.word === word) ? wfSplits : [wsFound, ...wfSplits]; const traces = wordSplits .filter(unique) diff --git a/packages/cspell-lib/src/lib/util/MinHeapQueue.ts b/packages/cspell-lib/src/lib/util/MinHeapQueue.ts index 7eacd9d9d6ed..beee48845bd8 100644 --- a/packages/cspell-lib/src/lib/util/MinHeapQueue.ts +++ b/packages/cspell-lib/src/lib/util/MinHeapQueue.ts @@ -38,10 +38,8 @@ function takeFromHeap(t: T[], compare: (a: T, b: T) => number): T | undefined i = k; j = i * 2 + 1; } - if (j === m) { - if (compare(t[i], t[j]) > 0) { - swap(t, i, j); - } + if (j === m && compare(t[i], t[j]) > 0) { + swap(t, i, j); } return result; } diff --git a/packages/cspell-lib/src/lib/util/Uri.ts b/packages/cspell-lib/src/lib/util/Uri.ts index 14b28e65dcd1..d2b55ae00270 100644 --- a/packages/cspell-lib/src/lib/util/Uri.ts +++ b/packages/cspell-lib/src/lib/util/Uri.ts @@ -108,7 +108,7 @@ class UriImpl extends URI implements UriInstance { toString(): string { // if (this.scheme !== 'stdin') return super.toString(true); - const path = encodeURI(this.path || '').replaceAll(/[#?]/g, (c) => `%${c.charCodeAt(0).toString(16)}`); + const path = encodeURI(this.path || '').replaceAll(/[#?]/g, (c) => `%${(c.codePointAt(0) || 0).toString(16)}`); const base = `${this.scheme}://${this.authority || ''}${path}`; const query = (this.query && `?${this.query}`) || ''; const fragment = (this.fragment && `#${this.fragment}`) || ''; diff --git a/packages/cspell-lib/src/lib/util/fileReader.test.ts b/packages/cspell-lib/src/lib/util/fileReader.test.ts index 0b6d88b6336b..ab3ebc53c0eb 100644 --- a/packages/cspell-lib/src/lib/util/fileReader.test.ts +++ b/packages/cspell-lib/src/lib/util/fileReader.test.ts @@ -18,7 +18,7 @@ describe('Validate file reader', () => { file ${__filename} `('reading files "$file"', async ({ file: filename }) => { - const expected = (await fs.readFile(filename, 'utf-8')).split(/\r?\n/g); + const expected = (await fs.readFile(filename, 'utf8')).split(/\r?\n/g); const content = [...(await fileReader.readLines(filename))]; expect(content).toEqual(expected); }); diff --git a/packages/cspell-lib/src/lib/util/fileReader.ts b/packages/cspell-lib/src/lib/util/fileReader.ts index 93be1a6b7d69..2fa470d1e905 100644 --- a/packages/cspell-lib/src/lib/util/fileReader.ts +++ b/packages/cspell-lib/src/lib/util/fileReader.ts @@ -4,11 +4,7 @@ import { readTextFile } from '../fileSystem.js'; import { toIterableIterator } from './iterableIteratorLib.js'; export async function readLines(url: URL | string, encoding: TextEncoding = 'utf8'): Promise> { - try { - url = toFileURL(url); - const content = await readTextFile(url, encoding); - return toIterableIterator(content.split(/\r?\n/g)); - } catch (e) { - return Promise.reject(e); - } + url = toFileURL(url); + const content = await readTextFile(url, encoding); + return toIterableIterator(content.split(/\r?\n/g)); } diff --git a/packages/cspell-lib/src/lib/util/memorizerWeak.test.ts b/packages/cspell-lib/src/lib/util/memorizerWeak.test.ts index b2d9011c5874..32ab0634d3d5 100644 --- a/packages/cspell-lib/src/lib/util/memorizerWeak.test.ts +++ b/packages/cspell-lib/src/lib/util/memorizerWeak.test.ts @@ -16,8 +16,7 @@ describe('memorizer Weak', () => { const aa = [...a] as [string]; const requests: (readonly [string])[][] = []; - requests.push([a], [a, b, c], [a], [a, b, c]); - requests.push([aa, b, c], [a, b, c], [aa], [a], [a, b, c]); + requests.push([a], [a, b, c], [a], [a, b, c], [aa, b, c], [a, b, c], [aa], [a], [a, b, c]); const expected = [[a], [a, b, c], [aa, b, c], [aa]]; diff --git a/packages/cspell-lib/src/lib/util/repMap.ts b/packages/cspell-lib/src/lib/util/repMap.ts index 27db33ef5357..690a81237884 100644 --- a/packages/cspell-lib/src/lib/util/repMap.ts +++ b/packages/cspell-lib/src/lib/util/repMap.ts @@ -15,7 +15,7 @@ export function createMapper(repMap: ReplaceMap): ReplaceMapper { .map((s) => { try { // fix up any nested () - const r = s.match(/\(/) ? s.replaceAll(/\((?=.*\))/g, '(?:').replaceAll('(?:?', '(?') : s; + const r = /\(/.test(s) ? s.replaceAll(/\((?=.*\))/g, '(?:').replaceAll('(?:?', '(?') : s; new RegExp(r); s = r; } catch { diff --git a/packages/cspell-lib/src/lib/util/resolveFile.test.ts b/packages/cspell-lib/src/lib/util/resolveFile.test.ts index fc80ee9834d1..b038b49908d5 100644 --- a/packages/cspell-lib/src/lib/util/resolveFile.test.ts +++ b/packages/cspell-lib/src/lib/util/resolveFile.test.ts @@ -30,8 +30,8 @@ interface Config { import: string[]; } -const issuesFolderURL = new URL('./issues/', pathRepoTestFixturesURL); -const notFoundURL = new URL('./not-found/', pathRepoTestFixturesURL); +const issuesFolderURL = new URL('issues/', pathRepoTestFixturesURL); +const notFoundURL = new URL('not-found/', pathRepoTestFixturesURL); const defaultConfigFile = require.resolve('@cspell/cspell-bundled-dicts/cspell-default.json'); const defaultConfigLocation = path.dirname(defaultConfigFile); @@ -55,8 +55,8 @@ const sm = expect.stringMatching; setTimeout( () => { debugOut('Failed to quit in 1 minute: %o', getActiveResourcesInfo()); - // eslint-disable-next-line n/no-process-exit - process.exit(1); + process.exitCode = 1; + throw new Error('Failed to quit in 1 minute'); }, 1000 * 60 * 1, ); @@ -135,9 +135,7 @@ describe('Validate resolveFile', () => { }); // Due to a circular reference it is not possible to make a dependency upon the issue. - const frExtFound = fs.existsSync( - new URL('./frontend/node_modules/@cspell/dict-fr-fr/cspell-ext.json', urlIssue5034), - ); + const frExtFound = fs.existsSync(new URL('frontend/node_modules/@cspell/dict-fr-fr/cspell-ext.json', urlIssue5034)); test.each` filename | relativeTo | expected | found @@ -250,7 +248,7 @@ describe('resolveRelativeTo', () => { }); function readConfig(filename: string): Config { - const parsed = parse(fs.readFileSync(filename, 'utf-8')); + const parsed = parse(fs.readFileSync(filename, 'utf8')); if (!parsed || typeof parsed !== 'object') throw new Error(`Unable to parse "${filename}"`); return parsed as unknown as Config; } diff --git a/packages/cspell-lib/src/lib/util/resolveFile.ts b/packages/cspell-lib/src/lib/util/resolveFile.ts index 1ec4e8d4c896..57f02675b0fe 100644 --- a/packages/cspell-lib/src/lib/util/resolveFile.ts +++ b/packages/cspell-lib/src/lib/util/resolveFile.ts @@ -179,7 +179,7 @@ export class FileResolver { try { const r = require.resolve(filename); return { filename: r, relativeTo: rel.toString(), found: true, method: 'tryCreateRequire' }; - } catch (_) { + } catch { return undefined; } }; @@ -189,7 +189,7 @@ export class FileResolver { // eslint-disable-next-line unicorn/prefer-module const r = require.resolve(filename); return { filename: r, relativeTo: undefined, found: true, method: 'tryNodeResolveDefaultPaths' }; - } catch (_) { + } catch { return undefined; } }; @@ -216,7 +216,7 @@ export class FileResolver { // eslint-disable-next-line unicorn/prefer-module const r = require.resolve(filename, { paths }); return { filename: r, relativeTo: relativeToPath, found: true, method: 'tryNodeRequireResolve' }; - } catch (_) { + } catch { return undefined; } }; @@ -226,7 +226,7 @@ export class FileResolver { const paths = isRelative(filename) ? [relativeTo] : [relativeTo, srcDirectory]; const resolved = fileURLToPath(importResolveModuleName(filename, paths)); return { filename: resolved, relativeTo: relativeTo.toString(), found: true, method: 'tryImportResolve' }; - } catch (_) { + } catch { return undefined; } }; diff --git a/packages/cspell-lib/src/lib/util/text.test.ts b/packages/cspell-lib/src/lib/util/text.test.ts index 8a570b20e1b0..041d02d0a054 100644 --- a/packages/cspell-lib/src/lib/util/text.test.ts +++ b/packages/cspell-lib/src/lib/util/text.test.ts @@ -1,3 +1,5 @@ +/* eslint-disable unicorn/text-encoding-identifier-case */ + import { opConcatMap, pipe, toArray } from '@cspell/cspell-pipe/sync'; import type { TextOffset } from '@cspell/cspell-types'; import { describe, expect, test } from 'vitest'; diff --git a/packages/cspell-lib/src/lib/util/text.ts b/packages/cspell-lib/src/lib/util/text.ts index 52ea4f90da1e..e2c3cad48a8e 100644 --- a/packages/cspell-lib/src/lib/util/text.ts +++ b/packages/cspell-lib/src/lib/util/text.ts @@ -118,11 +118,11 @@ export function extractWordsFromCodeTextOffset(textOffset: TextOffset): Iterable } export function isUpperCase(word: string): boolean { - return !!word.match(regExAllUpper); + return regExAllUpper.test(word); } export function isLowerCase(word: string): boolean { - return !!word.match(regExAllLower); + return regExAllLower.test(word); } export function isFirstCharacterUpper(word: string): boolean { @@ -150,13 +150,13 @@ export function camelToSnake(word: string): string { } export function matchCase(example: string, word: string): string { - if (example.match(regExFirstUpper)) { + if (regExFirstUpper.test(example)) { return word.slice(0, 1).toUpperCase() + word.slice(1).toLowerCase(); } - if (example.match(regExAllLower)) { + if (regExAllLower.test(example)) { return word.toLowerCase(); } - if (example.match(regExAllUpper)) { + if (regExAllUpper.test(example)) { return word.toUpperCase(); } diff --git a/packages/cspell-lib/src/lib/util/util.test.ts b/packages/cspell-lib/src/lib/util/util.test.ts index 38154816c45b..d70c4a0c01c6 100644 --- a/packages/cspell-lib/src/lib/util/util.test.ts +++ b/packages/cspell-lib/src/lib/util/util.test.ts @@ -33,7 +33,7 @@ describe('Validate util', () => { e: 'str', }; const cleanObj = util.clean(obj); - expect([...Object.keys(cleanObj)]).toEqual(['b', 'c', 'e']); + expect(Object.keys(cleanObj)).toEqual(['b', 'c', 'e']); }); test('scan map with no init', () => { diff --git a/packages/cspell-lib/src/lib/wordListHelper.ts b/packages/cspell-lib/src/lib/wordListHelper.ts index 6213e6d122ea..d50f3db35d84 100644 --- a/packages/cspell-lib/src/lib/wordListHelper.ts +++ b/packages/cspell-lib/src/lib/wordListHelper.ts @@ -27,7 +27,7 @@ export function splitLine(line: string): string[] { } export function splitCodeWords(words: string[]): string[] { - return words.map(Text.splitCamelCaseWord).flat(); + return words.flatMap(Text.splitCamelCaseWord); } export function splitLineIntoCodeWords(line: string): IterableIterator { diff --git a/packages/cspell-lib/src/test-util/test.matchers.mts b/packages/cspell-lib/src/test-util/test.matchers.mts index 6d674e264d57..5ae9eb811ace 100644 --- a/packages/cspell-lib/src/test-util/test.matchers.mts +++ b/packages/cspell-lib/src/test-util/test.matchers.mts @@ -8,7 +8,7 @@ export function extendExpect(e: typeof expect): AsymmetricMatchers { e.extend({ toEqualCaseInsensitive(actual, expected) { if (typeof actual !== 'string' || typeof expected !== 'string') { - throw new Error('These must be of type number!'); + throw new TypeError('These must be of type number!'); } const pass = actual.toLowerCase() === expected.toLowerCase(); diff --git a/packages/cspell-resolver/src/requireResolve.ts b/packages/cspell-resolver/src/requireResolve.ts index 95471e8fa3ab..447520b6500c 100644 --- a/packages/cspell-resolver/src/requireResolve.ts +++ b/packages/cspell-resolver/src/requireResolve.ts @@ -2,7 +2,7 @@ export function requireResolve(filename: string, paths?: string[]): string | und try { // eslint-disable-next-line unicorn/prefer-module return require.resolve(filename, paths ? { paths } : undefined); - } catch (_) { + } catch { return undefined; } } diff --git a/packages/cspell-tools/src/compile.ts b/packages/cspell-tools/src/compile.ts index 8b175730c1c4..dce22ca4d820 100644 --- a/packages/cspell-tools/src/compile.ts +++ b/packages/cspell-tools/src/compile.ts @@ -29,7 +29,7 @@ export async function processCompileAction( async function useCompile(src: string[], options: CompileCommonAppOptions): Promise { console.log( - 'Compile:\n output: %s\n compress: %s\n files:\n %s ', + 'Compile:\n output: %s\n compress: %s\n files:\n %s', options.output || 'default', options.compress ? 'true' : 'false', src.join('\n '), @@ -54,7 +54,7 @@ async function useCompile(src: string[], options: CompileCommonAppOptions): Prom async function initConfig(runConfig: RunConfig): Promise { const { $schema = configFileSchemaURL, ...cfg } = runConfig; const config = { $schema, ...cfg }; - const content = configFileHeader + YAML.stringify(config, null, 2); + const content = configFileHeader + YAML.stringify(config, undefined, 2); console.log('Writing config file: %s', defaultConfigFile); await writeFile(defaultConfigFile, content); diff --git a/packages/cspell-tools/src/compiler/createCompileRequest.ts b/packages/cspell-tools/src/compiler/createCompileRequest.ts index b6740a5a076a..dc568a451032 100644 --- a/packages/cspell-tools/src/compiler/createCompileRequest.ts +++ b/packages/cspell-tools/src/compiler/createCompileRequest.ts @@ -77,8 +77,8 @@ function toTargetName(sourceFile: string) { } function parseNumber(s: string | undefined): number | undefined { - const n = parseInt(s ?? ''); - return isNaN(n) ? undefined : n; + const n = Number.parseInt(s ?? ''); + return Number.isNaN(n) ? undefined : n; } function baseNameOfSource(source: DictionarySource): string { diff --git a/packages/cspell-tools/src/compiler/legacyLineToWords.ts b/packages/cspell-tools/src/compiler/legacyLineToWords.ts index 34cdf185f8ba..348633a8cdbd 100644 --- a/packages/cspell-tools/src/compiler/legacyLineToWords.ts +++ b/packages/cspell-tools/src/compiler/legacyLineToWords.ts @@ -17,7 +17,7 @@ export function legacyLineToWords( const words = pipe( wordGroups, - opConcatMap((a) => [...a.split(regExpSpaceOrDash)]), + opConcatMap((a) => a.split(regExpSpaceOrDash)), opConcatMap((a) => splitCamelCaseIfAllowed(a, allowedSplitWords, keepCase)), opMap((a) => a.trim()), opFilter((a) => !!a), diff --git a/packages/cspell-tools/src/compiler/wordListParser.test.ts b/packages/cspell-tools/src/compiler/wordListParser.test.ts index ae5945a0d9af..d9c15f04046f 100644 --- a/packages/cspell-tools/src/compiler/wordListParser.test.ts +++ b/packages/cspell-tools/src/compiler/wordListParser.test.ts @@ -49,8 +49,8 @@ describe('Validate the wordListCompiler', () => { ${s('Apple|~apple|Apple')} | ${pf({ legacy: true })} | ${['apple']} ${'ArrayObject::getFlags\nArrayObject::getIterator\nArrayObject::getIteratorClass\n'} | ${pf({ legacy: true })} | ${s('array|object|get|flags|iterator|class')} ${sampleContent} | ${pf()} | ${s('Tower of London|New|York')} - ${'apple\u200cbanana'} | ${pf({ split: true })} | ${['apple', 'banana']} - ${'apple\u200cbanana'} | ${pf({})} | ${['apple\u200cbanana']} + ${'apple\u200Cbanana'} | ${pf({ split: true })} | ${['apple', 'banana']} + ${'apple\u200Cbanana'} | ${pf({})} | ${['apple\u200Cbanana']} ${'apple\\u200cbanana'} | ${pf({ split: true })} | ${s('apple|banana')} ${s('apple|xfc|banana|x|u|a')} | ${pf({ split: true })} | ${s('apple|xfc|banana|x|u|a')} `('createSortAndFilterOperation $content $options', ({ content, options, expectedResult }) => { diff --git a/packages/cspell-tools/src/compiler/wordListParser.ts b/packages/cspell-tools/src/compiler/wordListParser.ts index 170ef197913c..a431cca1623b 100644 --- a/packages/cspell-tools/src/compiler/wordListParser.ts +++ b/packages/cspell-tools/src/compiler/wordListParser.ts @@ -134,23 +134,28 @@ export function createParseFileLineMapper(options?: Partial): .filter((a) => !!a); for (const flag of flags) { switch (flag) { - case 'split': + case 'split': { split = true; break; - case 'no-split': + } + case 'no-split': { split = false; break; - case 'keep-case': + } + case 'keep-case': { keepCase = true; legacy = false; break; - case 'no-keep-case': + } + case 'no-keep-case': { keepCase = false; break; - case 'legacy': + } + case 'legacy': { keepCase = false; legacy = true; break; + } } } } @@ -182,8 +187,8 @@ export function createParseFileLineMapper(options?: Partial): .split('|') .map((a) => a.trim()) .filter((a) => !!a) - .filter((a) => !a.match(/^[0-9_-]+$/)) // pure numbers and symbols - .filter((a) => !a.match(/^0[xo][0-9A-F]+$/i)); // c-style hex/octal digits + .filter((a) => !/^[0-9_-]+$/.test(a)) // pure numbers and symbols + .filter((a) => !/^0[xo][0-9A-F]+$/i.test(a)); // c-style hex/octal digits return lines; } @@ -196,11 +201,9 @@ export function createParseFileLineMapper(options?: Partial): } if (split) { const words = splitLine(line); - if (!allowedSplitWords.size) { - yield* words; - } else { - yield* words.flatMap((word) => splitCamelCaseIfAllowed(word, allowedSplitWords, keepCase)); - } + yield* !allowedSplitWords.size + ? words + : words.flatMap((word) => splitCamelCaseIfAllowed(word, allowedSplitWords, keepCase)); if (!splitKeepBoth) continue; } yield line.replaceAll(/["]/g, ''); diff --git a/packages/cspell-tools/src/compiler/writeTextToFile.ts b/packages/cspell-tools/src/compiler/writeTextToFile.ts index 52ce73cee693..aa4f475d9a05 100644 --- a/packages/cspell-tools/src/compiler/writeTextToFile.ts +++ b/packages/cspell-tools/src/compiler/writeTextToFile.ts @@ -6,7 +6,7 @@ const isGzFile = /\.gz$/; export async function writeTextToFile(filename: string, data: string): Promise { const useGz = isGzFile.test(filename); - const buf = Buffer.from(data, 'utf-8'); + const buf = Buffer.from(data, 'utf8'); const buffer = useGz ? await compress(buf) : buf; await fs.writeFile(filename, buffer); } diff --git a/packages/cspell-tools/src/shasum/shasum.ts b/packages/cspell-tools/src/shasum/shasum.ts index c8a2bc179b3c..d89ba399ac82 100644 --- a/packages/cspell-tools/src/shasum/shasum.ts +++ b/packages/cspell-tools/src/shasum/shasum.ts @@ -21,8 +21,10 @@ export async function shasumFile(filename: string, root: string | undefined): Pr const file = resolve(root || '.', filename); const checksum = await calcFileChecksum(file); return `${checksum} ${filename}`; - } catch (_) { + } catch { // const err = toError(error); + // Reject with a string. + // eslint-disable-next-line unicorn/no-useless-promise-resolve-reject return Promise.reject(`shasum: ${filename}: Unable to read file.`); } } @@ -50,7 +52,7 @@ export async function checkShasumFile( }), ); - const passed = !results.find((v) => !v.passed); + const passed = !results.some((v) => !v.passed); return { passed, results }; } @@ -64,7 +66,7 @@ async function tryToCheckFile(filename: string, root: string, checksum: string | try { const passed = await checkFile(checksum, file); return { filename, passed }; - } catch (_) { + } catch { return { filename, passed: false, error: Error('Failed to read file.') }; } } diff --git a/packages/cspell-tools/src/test/TestHelper.ts b/packages/cspell-tools/src/test/TestHelper.ts index f8eb925994dc..1a99f698cc4c 100644 --- a/packages/cspell-tools/src/test/TestHelper.ts +++ b/packages/cspell-tools/src/test/TestHelper.ts @@ -174,7 +174,7 @@ class TestHelperImpl implements TestHelper { try { await fs.stat(path); return true; - } catch (_) { + } catch { return false; } } diff --git a/packages/cspell-tools/src/util/errors.test.ts b/packages/cspell-tools/src/util/errors.test.ts index 06e68cb0c0df..9609ae06d6de 100644 --- a/packages/cspell-tools/src/util/errors.test.ts +++ b/packages/cspell-tools/src/util/errors.test.ts @@ -4,10 +4,10 @@ import { isError, toError } from './errors.js'; describe('errors', () => { test.each` - err | expected - ${1} | ${false} - ${undefined} | ${false} - ${new Error()} | ${true} + err | expected + ${1} | ${false} + ${undefined} | ${false} + ${new Error('msg')} | ${true} `('isError', ({ err, expected }) => { expect(isError(err)).toBe(expected); }); diff --git a/packages/cspell-trie-lib/src/lib/Builder/cursor-util.ts b/packages/cspell-trie-lib/src/lib/Builder/cursor-util.ts index daa726f50ce1..9708b24882cf 100644 --- a/packages/cspell-trie-lib/src/lib/Builder/cursor-util.ts +++ b/packages/cspell-trie-lib/src/lib/Builder/cursor-util.ts @@ -23,6 +23,7 @@ export function commonStringPrefixLen(a: string, b: string): number { } if (i) { // detect second half of a surrogate pair and backup. + // eslint-disable-next-line unicorn/prefer-code-point const c = a.charCodeAt(i) & 0xffff; if (c >= 0xdc00 && c <= 0xdfff) { --i; diff --git a/packages/cspell-trie-lib/src/lib/ITrieNode/find.ts b/packages/cspell-trie-lib/src/lib/ITrieNode/find.ts index 68bc83f794a4..b96be0375f26 100644 --- a/packages/cspell-trie-lib/src/lib/ITrieNode/find.ts +++ b/packages/cspell-trie-lib/src/lib/ITrieNode/find.ts @@ -114,12 +114,15 @@ function _findWordNode(root: Root, word: string, options: FindOptions): FindFull } switch (compoundMode) { - case 'none': + case 'none': { return options.matchCase ? __findExact() : __findCompound(); - case 'compound': + } + case 'compound': { return __findCompound(); - case 'legacy': + } + case 'legacy': { return findLegacyCompound(root, word, options); + } } } @@ -200,11 +203,9 @@ export function findCompoundNode( if (!r.cr) { break; } - if (!i && !r.caseMatched) { - if (w !== w.toLowerCase()) { - // It is not going to be found. - break; - } + if (!i && !r.caseMatched && w !== w.toLowerCase()) { + // It is not going to be found. + break; } } else { break; diff --git a/packages/cspell-trie-lib/src/lib/ITrieNode/walker/hintedWalker.ts b/packages/cspell-trie-lib/src/lib/ITrieNode/walker/hintedWalker.ts index 09ed32c9d8bc..23660c9ed9ba 100644 --- a/packages/cspell-trie-lib/src/lib/ITrieNode/walker/hintedWalker.ts +++ b/packages/cspell-trie-lib/src/lib/ITrieNode/walker/hintedWalker.ts @@ -53,8 +53,8 @@ function* hintedWalkerNext( const compoundMethodRoots: { [index: number]: readonly (readonly [string, ITrieNode])[] } = { [CompoundWordsMethod.NONE]: [], - [CompoundWordsMethod.JOIN_WORDS]: [...rootsForCompoundMethods.map((r) => [JOIN_SEPARATOR, r] as const)], - [CompoundWordsMethod.SEPARATE_WORDS]: [...rootsForCompoundMethods.map((r) => [WORD_SEPARATOR, r] as const)], + [CompoundWordsMethod.JOIN_WORDS]: rootsForCompoundMethods.map((r) => [JOIN_SEPARATOR, r] as const), + [CompoundWordsMethod.SEPARATE_WORDS]: rootsForCompoundMethods.map((r) => [WORD_SEPARATOR, r] as const), }; interface StackItemEntry { diff --git a/packages/cspell-trie-lib/src/lib/SimpleDictionaryParser.ts b/packages/cspell-trie-lib/src/lib/SimpleDictionaryParser.ts index aab4e16ab8a8..9e62a71874c7 100644 --- a/packages/cspell-trie-lib/src/lib/SimpleDictionaryParser.ts +++ b/packages/cspell-trie-lib/src/lib/SimpleDictionaryParser.ts @@ -137,18 +137,22 @@ export function createDictionaryLineParserMapper(options?: Partial !!a); for (const flag of flags) { switch (flag) { - case 'split': + case 'split': { split = true; break; - case 'no-split': + } + case 'no-split': { split = false; break; - case 'no-generate-alternatives': + } + case 'no-generate-alternatives': { stripCaseAndAccents = false; break; - case 'generate-alternatives': + } + case 'generate-alternatives': { stripCaseAndAccents = true; break; + } } } } @@ -214,10 +218,9 @@ export function createDictionaryLineParserMapper(options?: Partial): Iterable { for (const line of lines) { if (split) { - const lineEscaped = - line.indexOf('"') >= 0 - ? line.replaceAll(/".*?"/g, (quoted) => ' ' + quoted.replaceAll(/(\s)/g, '\\$1') + ' ') - : line; + const lineEscaped = line.includes('"') + ? line.replaceAll(/".*?"/g, (quoted) => ' ' + quoted.replaceAll(/(\s)/g, '\\$1') + ' ') + : line; const words = splitLine(lineEscaped, splitSeparator); yield* words.map((escaped) => escaped.replaceAll('\\', '')); diff --git a/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlob.test.ts b/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlob.test.ts index 8c46af8e5038..db9548b5632c 100644 --- a/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlob.test.ts +++ b/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlob.test.ts @@ -26,13 +26,13 @@ describe('FastTrieBlob', () => { test('expected', () => { const ft = FastTrieBlobBuilder.fromWordList(words); expect(ft.has('walk')).toBe(true); - expect(ft.charIndex.length).toBe(new Set([...words.join('')]).size + 1); + expect(ft.charIndex.length).toBe(new Set(words.join('')).size + 1); }); test('createTriFromList', () => { const root = createTrieRootFromList(words); const ft = FastTrieBlobBuilder.fromTrieRoot(root); - expect(ft.charIndex.length).toBe(new Set([...words.join('')]).size + 1); + expect(ft.charIndex.length).toBe(new Set(words.join('')).size + 1); expect(ft.has('walk')).toBe(true); expect(words.findIndex((word) => !ft.has(word))).toBe(-1); expect(ft.has('hello')).toBe(false); diff --git a/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlob.ts b/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlob.ts index 29dd5e6dda20..aacb5bc5fe6b 100644 --- a/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlob.ts +++ b/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlob.ts @@ -265,13 +265,14 @@ export class FastTrieBlob implements TrieData { nodeOffsets.push(offset); } const offsetToNodeIndex = new Map(nodeOffsets.map((offset, i) => [offset, i])); - const nodes: FastTrieBlobNode[] = new Array(nodeOffsets.length); + const nodes: FastTrieBlobNode[] = Array.from({ length: nodeOffsets.length }); for (let i = 0; i < nodes.length; ++i) { const offset = nodeOffsets[i]; const n = trieNodesBin[offset]; const eow = n & TrieBlob.NodeMaskEOW; const count = n & TrieBlob.NodeMaskNumChildren; - const node = new Array(count + 1); + // Preallocate the array to the correct size. + const node = Array.from({ length: count + 1 }); node[0] = eow; nodes[i] = node; for (let j = 1; j <= count; ++j) { diff --git a/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlobBuilder.test.ts b/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlobBuilder.test.ts index e161e0472622..742e2760d555 100644 --- a/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlobBuilder.test.ts +++ b/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlobBuilder.test.ts @@ -136,7 +136,7 @@ function sampleWords() { 🙄😯😦😧😮😲🥱😴🤤😪😮‍💨😵😵‍💫🤐🥴🤢 🤮🤧😷🤒🤕🤑🤠😈 ` + // cspell:enable genWords(8, 'A', 'z').join(' ') + - genWords(8, '\u1f00', '\u1fff').join(' ') + + genWords(8, '\u1F00', '\u1FFF').join(' ') + ' ' ) .normalize('NFC') diff --git a/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlobBuilder.ts b/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlobBuilder.ts index 32ea330e2e5b..684c25b49c2d 100644 --- a/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlobBuilder.ts +++ b/packages/cspell-trie-lib/src/lib/TrieBlob/FastTrieBlobBuilder.ts @@ -127,6 +127,7 @@ export class FastTrieBlobBuilder implements TrieBuilder { let depth = 0; const insertChar = (char: string) => { + // eslint-disable-next-line unicorn/prefer-code-point const cc = char.charCodeAt(0) & 0xfc00; // Work with partial surrogate pairs. if (cc === 0xd800 && char.length == 1) { diff --git a/packages/cspell-trie-lib/src/lib/TrieBlob/NumberSequenceByteDecoderAccumulator.ts b/packages/cspell-trie-lib/src/lib/TrieBlob/NumberSequenceByteDecoderAccumulator.ts index 29e8254dab0e..66b35fe9e00f 100644 --- a/packages/cspell-trie-lib/src/lib/TrieBlob/NumberSequenceByteDecoderAccumulator.ts +++ b/packages/cspell-trie-lib/src/lib/TrieBlob/NumberSequenceByteDecoderAccumulator.ts @@ -14,6 +14,7 @@ export type EncodedSequence = | [SpecialCharIndex.Index14bit, number, number] | [SpecialCharIndex.Index21bit, number, number, number]; +// eslint-disable-next-line unicorn/no-static-only-class export class NumberSequenceByteEncoderDecoder { static encode(n: number): EncodedSequence { if (n < this.SpecialCharIndexMask) return [n]; @@ -28,18 +29,22 @@ export class NumberSequenceByteEncoderDecoder { static decode(encodedSequence: EncodedSequence): number { const [a, b, c, d] = encodedSequence; switch (a) { - case SpecialCharIndex.Index8bit: + case SpecialCharIndex.Index8bit: { // assert(encodedSequence.length === 2); return (b || 0) + this.SpecialCharIndexMask; - case SpecialCharIndex.Index14bit: + } + case SpecialCharIndex.Index14bit: { // assert(encodedSequence.length === 3); return ((b || 0) << 7) + (c || 0); - case SpecialCharIndex.Index21bit: + } + case SpecialCharIndex.Index21bit: { // assert(encodedSequence.length === 4); return ((b || 0) << 14) + ((c || 0) << 7) + (d || 0); - default: + } + default: { // assert(a <= SpecialCharIndex.MaxCharIndex); return a; + } } } @@ -89,17 +94,21 @@ export class NumberSequenceByteDecoderAccumulator { return v; } switch (idx) { - case NumberSequenceByteEncoderDecoder.SpecialCharIndex8bit: + case NumberSequenceByteEncoderDecoder.SpecialCharIndex8bit: { this.accumulation += NumberSequenceByteEncoderDecoder.SpecialCharIndexMask; break; - case NumberSequenceByteEncoderDecoder.SpecialCharIndex16bit: + } + case NumberSequenceByteEncoderDecoder.SpecialCharIndex16bit: { this.byteMode = 2; break; - case NumberSequenceByteEncoderDecoder.SpecialCharIndex24bit: + } + case NumberSequenceByteEncoderDecoder.SpecialCharIndex24bit: { this.byteMode = 3; break; - default: + } + default: { throw new Error('Invalid SpecialCharIndex'); + } } return undefined; } diff --git a/packages/cspell-trie-lib/src/lib/TrieBlob/TrieBlob.test.ts b/packages/cspell-trie-lib/src/lib/TrieBlob/TrieBlob.test.ts index 71907cc24419..dd756ff39874 100644 --- a/packages/cspell-trie-lib/src/lib/TrieBlob/TrieBlob.test.ts +++ b/packages/cspell-trie-lib/src/lib/TrieBlob/TrieBlob.test.ts @@ -83,7 +83,7 @@ describe('TrieBlob special character indexes', () => { test('mapping characters', () => { const characters = 'this is a test of a few characters and accents: é ♘😀😎🥳'; const map = Object.fromEntries( - [...new Set([...characters]).values()].map((c) => [c, c.codePointAt(0)] as [string, number]), + [...new Set(characters).values()].map((c) => [c, c.codePointAt(0)] as [string, number]), ); const charIndex = Object.fromEntries(Object.entries(map).map(([c, i]) => [i, c])) as Record; const seq = TrieBlob.charactersToCharIndexSequence([...characters], map); diff --git a/packages/cspell-trie-lib/src/lib/TrieBlob/TrieBlob.ts b/packages/cspell-trie-lib/src/lib/TrieBlob/TrieBlob.ts index 01dca1fdd270..92189d5fae63 100644 --- a/packages/cspell-trie-lib/src/lib/TrieBlob/TrieBlob.ts +++ b/packages/cspell-trie-lib/src/lib/TrieBlob/TrieBlob.ts @@ -269,11 +269,7 @@ export class TrieBlob implements TrieData { const header = new DataView(blob.buffer); const useLittle = isLittleEndian(); if (header.getUint32(HEADER.endian, useLittle) !== endianSig) { - // swap the bytes - // blob.swap32(); - if (header.getUint32(HEADER.endian, useLittle) !== endianSig) { - throw new ErrorDecodeTrieBlob('Invalid TrieBlob Header'); - } + throw new ErrorDecodeTrieBlob('Invalid TrieBlob Header'); } const offsetNodes = header.getUint32(HEADER.nodes, useLittle); const lenNodes = header.getUint32(HEADER.nodesLen, useLittle); diff --git a/packages/cspell-trie-lib/src/lib/TrieBuilder.ts b/packages/cspell-trie-lib/src/lib/TrieBuilder.ts index deb335cbe888..908d2bd61537 100644 --- a/packages/cspell-trie-lib/src/lib/TrieBuilder.ts +++ b/packages/cspell-trie-lib/src/lib/TrieBuilder.ts @@ -343,5 +343,5 @@ function assertFrozen(n: TrieNodeEx): asserts n is TrieNodeExFrozen { if (!('id' in n)) { console.warn('%o', n); } - if (!Object.isFrozen(n) || !('id' in n)) throw Error('Must be TrieNodeExFrozen'); + if (!Object.isFrozen(n) || !('id' in n)) throw new Error('Must be TrieNodeExFrozen'); } diff --git a/packages/cspell-trie-lib/src/lib/TrieNode/find.ts b/packages/cspell-trie-lib/src/lib/TrieNode/find.ts index 83e5248b6c67..135b1be8605a 100644 --- a/packages/cspell-trie-lib/src/lib/TrieNode/find.ts +++ b/packages/cspell-trie-lib/src/lib/TrieNode/find.ts @@ -139,12 +139,15 @@ function _findWordNode(root: Root, word: string, options: FindOptions): FindFull } switch (compoundMode) { - case 'none': + case 'none': { return options.matchCase ? __findExact() : __findCompound(); - case 'compound': + } + case 'compound': { return __findCompound(); - case 'legacy': + } + case 'legacy': { return findLegacyCompound(root, word, options); + } } } @@ -225,11 +228,9 @@ export function findCompoundNode( if (!r.cr) { break; } - if (!i && !r.caseMatched) { - if (w !== w.toLowerCase()) { - // It is not going to be found. - break; - } + if (!i && !r.caseMatched && w !== w.toLowerCase()) { + // It is not going to be found. + break; } } else { break; diff --git a/packages/cspell-trie-lib/src/lib/convertToTrieRefNodes.ts b/packages/cspell-trie-lib/src/lib/convertToTrieRefNodes.ts index ea013c23b9d9..8ffeaff54640 100644 --- a/packages/cspell-trie-lib/src/lib/convertToTrieRefNodes.ts +++ b/packages/cspell-trie-lib/src/lib/convertToTrieRefNodes.ts @@ -49,8 +49,8 @@ export function convertToTrieRefNodes(root: TrieNode): IterableIterator): IterableIterator { - const nodes = [...genSequence(tallies).filter((a) => a[1] >= MinReferenceCount)].sort((a, b) => b[1] - a[1]); - for (const [n] of nodes) { + const nodes = genSequence(tallies).filter((a) => a[1] >= MinReferenceCount); + for (const [n] of [...nodes].sort((a, b) => b[1] - a[1])) { yield* walkByRollup(n); } } diff --git a/packages/cspell-trie-lib/src/lib/distance/distanceAStarWeighted.test.ts b/packages/cspell-trie-lib/src/lib/distance/distanceAStarWeighted.test.ts index a7c70316ce50..7808e4f0ce7e 100644 --- a/packages/cspell-trie-lib/src/lib/distance/distanceAStarWeighted.test.ts +++ b/packages/cspell-trie-lib/src/lib/distance/distanceAStarWeighted.test.ts @@ -179,9 +179,9 @@ describe('distanceAStar', () => { ); }); -function mapLetters(cost = 50): SuggestionCostMapDef { - const letters = [...'a'.repeat(27)].map((s, i) => String.fromCharCode(s.charCodeAt(0) + i)).join(''); +const letters = 'abcdefghijklmnopqrstuvwxyz'; +function mapLetters(cost = 50): SuggestionCostMapDef { return { map: letters + letters.toUpperCase(), insDel: cost, diff --git a/packages/cspell-trie-lib/src/lib/distance/formatResultEx.ts b/packages/cspell-trie-lib/src/lib/distance/formatResultEx.ts index 58c320ed38cf..d21458b15623 100644 --- a/packages/cspell-trie-lib/src/lib/distance/formatResultEx.ts +++ b/packages/cspell-trie-lib/src/lib/distance/formatResultEx.ts @@ -15,7 +15,7 @@ function pR(s: string, w: number) { } function vizWidth(s: string) { - const r = s.replaceAll(/[\u0300-\u036F\u007f-\u009f]/gu, ''); + const r = s.replaceAll(/[\u0300-\u036F\u007F-\u009F]/gu, ''); let i = 0; for (const c of r) { i += c.length; diff --git a/packages/cspell-trie-lib/src/lib/io/decode.ts b/packages/cspell-trie-lib/src/lib/io/decode.ts index 253e013be77e..7e1af3e3e628 100644 --- a/packages/cspell-trie-lib/src/lib/io/decode.ts +++ b/packages/cspell-trie-lib/src/lib/io/decode.ts @@ -32,7 +32,7 @@ function importTrie(input: Iterable | IterableIterator | string[ for (let i = 0; i < headerRows.length; ++i) { const match = headerRows[i].match(headerReg); if (match) { - return parseInt(match[1], 10); + return Number.parseInt(match[1], 10); } } throw new Error('Unknown file format'); diff --git a/packages/cspell-trie-lib/src/lib/io/importExport.ts b/packages/cspell-trie-lib/src/lib/io/importExport.ts index 290536891037..dea42cc7755c 100644 --- a/packages/cspell-trie-lib/src/lib/io/importExport.ts +++ b/packages/cspell-trie-lib/src/lib/io/importExport.ts @@ -56,7 +56,7 @@ export function importTrie(input: Iterable | IterableIterator | for (let i = 0; i < headerRows.length; ++i) { const match = headerRows[i].match(headerReg); if (match) { - return parseInt(match[1], 10); + return Number.parseInt(match[1], 10); } } throw new Error('Unknown file format'); diff --git a/packages/cspell-trie-lib/src/lib/io/importExportV2.ts b/packages/cspell-trie-lib/src/lib/io/importExportV2.ts index f46f8051e2de..b60460347c8d 100644 --- a/packages/cspell-trie-lib/src/lib/io/importExportV2.ts +++ b/packages/cspell-trie-lib/src/lib/io/importExportV2.ts @@ -105,9 +105,12 @@ function toLine(node: TrieRefNode, base: number): string { function generateHeader(base: number, comment: string): Sequence { const header = [ - ...['#!/usr/bin/env cspell-trie reader', 'TrieXv2', 'base=' + base], + '#!/usr/bin/env cspell-trie reader', + 'TrieXv2', + 'base=' + base, ...(comment ? comment.split('\n').map((a) => '# ' + a) : []), - ...['# Data:', DATA], + '# Data:', + DATA, ]; return genSequence(header); } @@ -187,7 +190,7 @@ export function importTrie(linesX: Iterable | IterableIterator): .slice(refOffset) .split(',') .filter((a) => !!a) - .map((r) => parseInt(r, base)); + .map((r) => Number.parseInt(r, base)); return { letter: line[0], isWord, diff --git a/packages/cspell-trie-lib/src/lib/io/importExportV3.test.ts b/packages/cspell-trie-lib/src/lib/io/importExportV3.test.ts index 051cdba49995..df17f6048f8d 100644 --- a/packages/cspell-trie-lib/src/lib/io/importExportV3.test.ts +++ b/packages/cspell-trie-lib/src/lib/io/importExportV3.test.ts @@ -74,7 +74,7 @@ describe('Import/Export', () => { ${'sample2.txt'} | ${{}} `('Read sample and ensure results match $sampleWordList $options', async ({ sampleWordList, options }) => { const path = resolveSamplePath(sampleWordList); - const content = await readFile(path, 'utf-8'); + const content = await readFile(path, 'utf8'); const wordList = content .split('\n') .map((a) => a.trim()) diff --git a/packages/cspell-trie-lib/src/lib/io/importExportV3.ts b/packages/cspell-trie-lib/src/lib/io/importExportV3.ts index 2c89a1ac0735..b6faf7126697 100644 --- a/packages/cspell-trie-lib/src/lib/io/importExportV3.ts +++ b/packages/cspell-trie-lib/src/lib/io/importExportV3.ts @@ -23,9 +23,12 @@ export const DATA = '__DATA__'; function generateHeader(base: number, comment: string): Iterable { const header = [ - ...['#!/usr/bin/env cspell-trie reader', 'TrieXv3', 'base=' + base], + '#!/usr/bin/env cspell-trie reader', + 'TrieXv3', + 'base=' + base, ...(comment ? comment.split('\n').map((a) => '# ' + a) : []), - ...['# Data:', DATA], + '# Data:', + DATA, ]; return header.map((a) => a + '\n'); } @@ -83,19 +86,22 @@ export function serializeTrie(root: TrieRoot, options: ExportOptions | number = function* emit(s: string): Generator { switch (s) { - case EOW: + case EOW: { yield* flush(); backBuffer.last = EOW; backBuffer.count = 0; backBuffer.words++; break; - case BACK: + } + case BACK: { backBuffer.count++; break; - case EOL: + } + case EOL: { backBuffer.eol = true; break; - default: + } + default: { if (backBuffer.words >= WORDS_PER_LINE) { backBuffer.eol = true; } @@ -104,6 +110,7 @@ export function serializeTrie(root: TrieRoot, options: ExportOptions | number = backBuffer.words++; } yield s; + } } } diff --git a/packages/cspell-trie-lib/src/lib/io/importExportV4.test.ts b/packages/cspell-trie-lib/src/lib/io/importExportV4.test.ts index 15e7d4c153e7..d20830786d3f 100644 --- a/packages/cspell-trie-lib/src/lib/io/importExportV4.test.ts +++ b/packages/cspell-trie-lib/src/lib/io/importExportV4.test.ts @@ -94,7 +94,7 @@ describe('Import/Export', () => { ${'sample2.txt'} | ${{}} `('Read sample and ensure results match $sampleWordList $options', async ({ sampleWordList, options }) => { const path = resolveSamplePath(sampleWordList); - const content = await readFile(path, 'utf-8'); + const content = await readFile(path, 'utf8'); const wordList = content .split('\n') .map((a) => a.trim()) diff --git a/packages/cspell-trie-lib/src/lib/io/importExportV4.ts b/packages/cspell-trie-lib/src/lib/io/importExportV4.ts index 62164f280d6e..462048103375 100644 --- a/packages/cspell-trie-lib/src/lib/io/importExportV4.ts +++ b/packages/cspell-trie-lib/src/lib/io/importExportV4.ts @@ -35,20 +35,18 @@ const INLINE_DATA_COMMENT_LINE = '/'; const specialCharacters = stringToCharSet( [ - ...[ - EOW, - BACK, - EOL, - REF, - REF_REL, - EOR, - ESCAPE, - LF, - REF_INDEX_BEGIN, - REF_INDEX_END, - INLINE_DATA_COMMENT_LINE, - ...'0123456789', - ], + EOW, + BACK, + EOL, + REF, + REF_REL, + EOR, + ESCAPE, + LF, + REF_INDEX_BEGIN, + REF_INDEX_END, + INLINE_DATA_COMMENT_LINE, + ...'0123456789', ...'`~!@#$%^&*()_-+=[]{};:\'"<>,./?\\|', ].join(''), ); @@ -133,19 +131,22 @@ export function serializeTrie(root: TrieRoot, options: ExportOptions | number = function* emit(s: string): Generator { switch (s) { - case EOW: + case EOW: { yield* flush(); backBuffer.last = EOW; backBuffer.count = 0; backBuffer.words++; break; - case BACK: + } + case BACK: { backBuffer.count++; break; - case EOL: + } + case EOL: { backBuffer.eol = true; break; - default: + } + default: { if (backBuffer.words >= WORDS_PER_LINE) { backBuffer.eol = true; } @@ -154,6 +155,7 @@ export function serializeTrie(root: TrieRoot, options: ExportOptions | number = backBuffer.words++; } yield s; + } } } @@ -334,7 +336,7 @@ function parseStream(radix: number, iter: Iterable): TrieRoot { function parser(acc: ReduceResults, s: string): ReduceResults { if (s === EOR || (radix === 10 && !(s in numbersSet))) { const { root, nodes, stack } = acc; - const r = parseInt(ref, radix); + const r = Number.parseInt(ref, radix); const top = stack[stack.length - 1]; const p = stack[stack.length - 2].node; const n = isIndexRef ? refIndex[r] : r; @@ -423,7 +425,7 @@ function parseStream(radix: number, iter: Iterable): TrieRoot { if (!(s in charactersBack)) { return parserMain({ ...acc, parser: undefined }, s); } - let n = s === BACK ? 1 : parseInt(s, 10) - 1; + let n = s === BACK ? 1 : Number.parseInt(s, 10) - 1; const { stack } = acc; while (n-- > 0) { stack.pop(); @@ -474,7 +476,7 @@ function parseStream(radix: number, iter: Iterable): TrieRoot { refIndex = json .replaceAll(/[\s[\]]/g, '') .split(',') - .map((n) => parseInt(n, radix)); + .map((n) => Number.parseInt(n, radix)); return { ...acc, parser: undefined }; } return acc; diff --git a/packages/cspell-trie-lib/src/lib/io/importV3.test.ts b/packages/cspell-trie-lib/src/lib/io/importV3.test.ts index 154938507d2e..2e4e0f9ff8c8 100644 --- a/packages/cspell-trie-lib/src/lib/io/importV3.test.ts +++ b/packages/cspell-trie-lib/src/lib/io/importV3.test.ts @@ -98,7 +98,7 @@ describe('Import/Export', () => { ${'sample2.txt'} | ${{}} `('Read sample and ensure results match $sampleWordList $options', async ({ sampleWordList, options }) => { const path = resolveSamplePath(sampleWordList); - const content = await readFile(path, 'utf-8'); + const content = await readFile(path, 'utf8'); const wordList = content .split('\n') .map((a) => a.trim()) diff --git a/packages/cspell-trie-lib/src/lib/io/importV3.ts b/packages/cspell-trie-lib/src/lib/io/importV3.ts index 43534bd8ac6f..d2c9f1b0ca2d 100644 --- a/packages/cspell-trie-lib/src/lib/io/importV3.ts +++ b/packages/cspell-trie-lib/src/lib/io/importV3.ts @@ -108,7 +108,7 @@ function parseStream(radix: number): Reducer { function parser(acc: ReduceResults, s: string): ReduceResults { if (s === EOR) { const { cursor } = acc; - const r = parseInt(ref, radix); + const r = Number.parseInt(ref, radix); // +1 is used because EOW node was added but not counted. cursor.reference(r + 1); acc.parser = undefined; @@ -161,7 +161,7 @@ function parseStream(radix: number): Reducer { acc.parser = undefined; return parserMain(acc, s); } - const n = s === BACK ? 1 : parseInt(s, 10) - 1; + const n = s === BACK ? 1 : Number.parseInt(s, 10) - 1; acc.cursor.backStep(n); acc.parser = parseBack; return acc; diff --git a/packages/cspell-trie-lib/src/lib/io/importV3FastBlob.test.ts b/packages/cspell-trie-lib/src/lib/io/importV3FastBlob.test.ts index 6afefe968c82..74685cebd6cc 100644 --- a/packages/cspell-trie-lib/src/lib/io/importV3FastBlob.test.ts +++ b/packages/cspell-trie-lib/src/lib/io/importV3FastBlob.test.ts @@ -76,7 +76,7 @@ describe('Import/Export', () => { ${'sample2.txt'} | ${{}} `('Read sample and ensure results match $sampleWordList $options', async ({ sampleWordList, options }) => { const path = resolveSamplePath(sampleWordList); - const content = await readFile(path, 'utf-8'); + const content = await readFile(path, 'utf8'); const wordList = content .split('\n') .map((a) => a.trim()) diff --git a/packages/cspell-trie-lib/src/lib/suggestions/suggest-en.test.ts b/packages/cspell-trie-lib/src/lib/suggestions/suggest-en.test.ts index 7fa02b68003f..375e420d7259 100644 --- a/packages/cspell-trie-lib/src/lib/suggestions/suggest-en.test.ts +++ b/packages/cspell-trie-lib/src/lib/suggestions/suggest-en.test.ts @@ -31,9 +31,12 @@ const pAffContent = readRawDictionaryFile('hunspell/en_US.aff'); let affContent: string | undefined; -const pReady = Promise.all([pAffContent.then((aff) => (affContent = aff))]).then(() => { - return undefined; -}); +const pReady = pAffContent + .then((aff) => (affContent = aff)) + .then(() => { + return undefined; + }) + .catch(() => undefined); describe('Validate English Suggestions', () => { interface WordSuggestionsTest { diff --git a/packages/cspell-trie-lib/src/lib/suggestions/suggest.ts b/packages/cspell-trie-lib/src/lib/suggestions/suggest.ts index 996f4a48f046..2d45dc26f13e 100644 --- a/packages/cspell-trie-lib/src/lib/suggestions/suggest.ts +++ b/packages/cspell-trie-lib/src/lib/suggestions/suggest.ts @@ -85,12 +85,14 @@ export function* genCompoundableSuggestions( function updateCostLimit(maxCost: number | symbol | undefined) { switch (typeof maxCost) { - case 'number': + case 'number': { costLimit = maxCost; break; - case 'symbol': + } + case 'symbol': { stopNow = true; break; + } } } @@ -116,7 +118,7 @@ export function* genCompoundableSuggestions( if (setOfSeparators.has(w)) { const mxRange = matrix[depth].slice(a, b + 1); const mxMin = Math.min(...mxRange); - const tag = [a, ...mxRange.map((c) => c - mxMin)].join(); + const tag = [a, ...mxRange.map((c) => c - mxMin)].join(','); const ht = historyTags.get(tag); if (ht && ht.m <= mxMin) { goDeeper = false; diff --git a/packages/cspell-trie-lib/src/lib/suggestions/suggestAStar.ts b/packages/cspell-trie-lib/src/lib/suggestions/suggestAStar.ts index 548e03b90565..3b73b06da963 100644 --- a/packages/cspell-trie-lib/src/lib/suggestions/suggestAStar.ts +++ b/packages/cspell-trie-lib/src/lib/suggestions/suggestAStar.ts @@ -138,7 +138,9 @@ export function* getSuggestionsAStar( return ( pb - pa || a.cost - b.cost || + // eslint-disable-next-line unicorn/prefer-code-point Math.abs(a.word.charCodeAt(0) - srcWord.charCodeAt(0)) - + // eslint-disable-next-line unicorn/prefer-code-point Math.abs(b.word.charCodeAt(0) - srcWord.charCodeAt(0)) ); } @@ -194,11 +196,9 @@ export function* getSuggestionsAStar( storePath(t, n.child(j), i + 1, c, ss, p, 'r', ss); } - if (n.eow && i) { + if (n.eow && i && compoundMethod) { // legacy word compound - if (compoundMethod) { - storePath(t, root, i, costLegacyCompound, wordSeparator, p, 'L', wordSeparator); - } + storePath(t, root, i, costLegacyCompound, wordSeparator, p, 'L', wordSeparator); } // swap @@ -333,7 +333,7 @@ function getCostTrie(t: CostTrie, s: string) { return t; } let tt = t; - for (const c of [...s]) { + for (const c of s) { tt = tt.t[c] ??= createCostTrie(); } return tt; @@ -411,7 +411,7 @@ function serializeCostTrie(p: PNode): string { function _serializeCostTrie(t: CostTrie): string { const lines: string[] = []; - lines.push(`:: [${t.c.join()}]`); + lines.push(`:: [${t.c.join(',')}]`); for (const [letter, child] of Object.entries(t.t)) { lines.push(letter + ':'); if (!child) continue; diff --git a/packages/cspell-trie-lib/src/lib/utils/text.ts b/packages/cspell-trie-lib/src/lib/utils/text.ts index 68cd4d1ad8e6..29ad8d4d8fa0 100644 --- a/packages/cspell-trie-lib/src/lib/utils/text.ts +++ b/packages/cspell-trie-lib/src/lib/utils/text.ts @@ -21,12 +21,10 @@ export function expandCharacterSet(line: string, rangeChar = '-'): Set { expandRange(prev, char).forEach((a) => charSet.add(a)); mode = 0; } - if (char === rangeChar) { + if (char === rangeChar && prev) { // store the `-` if there isn't a previous value. - if (prev) { - mode = 1; - continue; - } + mode = 1; + continue; } charSet.add(char); prev = char; @@ -115,9 +113,11 @@ export function stripNonAccents(characters: string): string { export function isValidUtf16Character(char: string): boolean { const len = char.length; + // eslint-disable-next-line unicorn/prefer-code-point const code = char.charCodeAt(0) & 0xfc00; const valid = (len === 1 && (code & 0xf800) !== 0xd800) || + // eslint-disable-next-line unicorn/prefer-code-point (len === 2 && (code & 0xfc00) === 0xd800 && (char.charCodeAt(1) & 0xfc00) === 0xdc00); return valid; } @@ -141,6 +141,7 @@ export function assertValidUtf16Character(char: string): void { function toCharCodes(s: string): number[] { const values: number[] = []; for (let i = 0; i < s.length; ++i) { + // eslint-disable-next-line unicorn/prefer-code-point values.push(s.charCodeAt(i)); } return values; diff --git a/packages/cspell-trie-lib/src/lib/walker/hintedWalker.ts b/packages/cspell-trie-lib/src/lib/walker/hintedWalker.ts index b06eebb923f4..88ceea5e3d23 100644 --- a/packages/cspell-trie-lib/src/lib/walker/hintedWalker.ts +++ b/packages/cspell-trie-lib/src/lib/walker/hintedWalker.ts @@ -56,8 +56,8 @@ function* hintedWalkerNext( const compoundMethodRoots: { [index: number]: readonly (readonly [string, TrieNode])[] } = { [CompoundWordsMethod.NONE]: [], - [CompoundWordsMethod.JOIN_WORDS]: [...rootsForCompoundMethods.map((r) => [JOIN_SEPARATOR, r] as const)], - [CompoundWordsMethod.SEPARATE_WORDS]: [...rootsForCompoundMethods.map((r) => [WORD_SEPARATOR, r] as const)], + [CompoundWordsMethod.JOIN_WORDS]: rootsForCompoundMethods.map((r) => [JOIN_SEPARATOR, r] as const), + [CompoundWordsMethod.SEPARATE_WORDS]: rootsForCompoundMethods.map((r) => [WORD_SEPARATOR, r] as const), }; interface StackItemEntry { diff --git a/packages/cspell-trie-lib/src/perf/perfSuite.ts b/packages/cspell-trie-lib/src/perf/perfSuite.ts index 7c072876ff0d..bb27697a416c 100644 --- a/packages/cspell-trie-lib/src/perf/perfSuite.ts +++ b/packages/cspell-trie-lib/src/perf/perfSuite.ts @@ -164,11 +164,12 @@ export async function measurePerf(which: string | undefined, method: string | un ); switch (method) { - case 'has': + case 'has': { timer.measureFn('blob.TrieBlob.has', () => trieHasWords(trieBlob, words)); timer.measureFn('blob.TrieBlob.has', () => trieHasWords(trieBlob, words)); break; - case 'words': + } + case 'words': { timer.start('blob.words'); [...trieBlob.words()]; timer.stop('blob.words'); @@ -177,16 +178,18 @@ export async function measurePerf(which: string | undefined, method: string | un [...walkerWordsITrie(trieBlob.getRoot())]; timer.stop('blob.walkerWordsITrie'); break; - case 'dump': + } + case 'dump': { timer.start('blob.write.TrieBlob.en.json'); - writeFileSync('./TrieBlob.en.json', JSON.stringify(trieBlob, null, 2), 'utf8'); + writeFileSync('./TrieBlob.en.json', JSON.stringify(trieBlob, undefined, 2), 'utf8'); timer.stop('blob.write.TrieBlob.en.json'); timer.start('blob.write.TrieBlob.en.trieb'); writeFileSync('./TrieBlob.en.trieb', trieBlob.encodeBin()); timer.stop('blob.write.TrieBlob.en.trieb'); break; - case 'decode': + } + case 'decode': { { const tb = timer.measureFn('blob.TrieBlob.decodeBin \t', () => { return TrieBlob.decodeBin(readFileSync('./TrieBlob.en.trieb')); @@ -195,6 +198,7 @@ export async function measurePerf(which: string | undefined, method: string | un timer.measureFn('blob.TrieBlob.has \t\t', () => hasWords(words, (word) => tb.has(word))); } break; + } } } @@ -208,11 +212,12 @@ export async function measurePerf(which: string | undefined, method: string | un ); switch (method) { - case 'has': + case 'has': { timer.measureFn('fast.FastTrieBlob.has', () => hasWords(words, (word) => ft.has(word))); timer.measureFn('fast.FastTrieBlob.has', () => hasWords(words, (word) => ft.has(word))); break; - case 'words': + } + case 'words': { timer.start('fast.words.fromWordList'); [...ftWordList.words()]; timer.stop('fast.words.fromWordList'); @@ -220,6 +225,7 @@ export async function measurePerf(which: string | undefined, method: string | un [...ft.words()]; timer.stop('fast.words'); break; + } } } @@ -233,15 +239,17 @@ export async function measurePerf(which: string | undefined, method: string | un timer.measureFn('trie.buildTrieNodeTrieFromWords', () => buildTrieNodeTrieFromWords(words)); switch (method) { - case 'has': + case 'has': { timer.measureFn('trie.Trie.has', () => hasWords(words, (word) => trie.hasWord(word, true))); timer.measureFn('trie.Trie.has', () => hasWords(words, (word) => trie.hasWord(word, true))); break; - case 'words': + } + case 'words': { timer.start('trie.words'); [...trie.words()]; timer.stop('trie.words'); break; + } } } diff --git a/packages/cspell-trie-lib/src/perf/run.ts b/packages/cspell-trie-lib/src/perf/run.ts index e44df51021d8..b4a5341b072f 100644 --- a/packages/cspell-trie-lib/src/perf/run.ts +++ b/packages/cspell-trie-lib/src/perf/run.ts @@ -1,26 +1,30 @@ import { measurePerf, PerfConfig } from './perfSuite.js'; -const args = process.argv.slice(2); +function run() { + const args = process.argv.slice(2); -if (args.includes('--help')) { - console.log(`\ -Measure trie perf tool used only for testing. -Usage: + if (args.includes('--help')) { + console.log(`\ + Measure trie perf tool used only for testing. + Usage: -- node run.js [type] -- node run.js [method] + - node run.js [type] + - node run.js [method] -type: -${Object.entries(PerfConfig) - .map(([name, opt]) => `- ${name} - ${opt.desc}`) - .join('\n')} + type: + ${Object.entries(PerfConfig) + .map(([name, opt]) => `- ${name} - ${opt.desc}`) + .join('\n')} -method - words, has + method - words, has -`); + `); - // eslint-disable-next-line n/no-process-exit - process.exit(1); + process.exitCode = 1; + return; + } + + measurePerf(args[0], args[1]); } -measurePerf(args[0], args[1]); +run(); diff --git a/packages/cspell-trie-lib/src/test/dictionaries.test.helper.ts b/packages/cspell-trie-lib/src/test/dictionaries.test.helper.ts index f0ceedd4365a..20231f1592fe 100644 --- a/packages/cspell-trie-lib/src/test/dictionaries.test.helper.ts +++ b/packages/cspell-trie-lib/src/test/dictionaries.test.helper.ts @@ -55,7 +55,7 @@ function memorize(key: string, map: Map, resolve: (key: string) => return r; } -export function readRawDictionaryFile(name: string, encoding: BufferEncoding = 'utf-8'): Promise { +export function readRawDictionaryFile(name: string, encoding: BufferEncoding = 'utf8'): Promise { return fs.readFile(resolveGlobalDict(name), encoding); } diff --git a/packages/cspell-trie-lib/src/test/reader.test.helper.ts b/packages/cspell-trie-lib/src/test/reader.test.helper.ts index bb4a872e9dd4..c16154a5cd08 100644 --- a/packages/cspell-trie-lib/src/test/reader.test.helper.ts +++ b/packages/cspell-trie-lib/src/test/reader.test.helper.ts @@ -20,7 +20,7 @@ export interface Config { } export async function readConfig(configLocation: string): Promise { - const json = await readFile(configLocation, 'utf-8'); + const json = await readFile(configLocation, 'utf8'); return JSON.parse(json.replaceAll(/\/\/.*/g, '')); } @@ -42,6 +42,7 @@ export async function readTrieFileFromConfig(configLocation: string, name?: stri return new Trie(trieNode); } +// eslint-disable-next-line unicorn/text-encoding-identifier-case type BufferEncoding = 'utf8' | 'utf-8'; /** diff --git a/packages/cspell-trie/src/app.test.ts b/packages/cspell-trie/src/app.test.ts index 110848c370dc..a17463913bca 100644 --- a/packages/cspell-trie/src/app.test.ts +++ b/packages/cspell-trie/src/app.test.ts @@ -53,11 +53,7 @@ describe('Validate App', () => { vi.spyOn(console, 'warn').mockImplementation(out.warn); const result = app.run(commander, argv(...args)); - if (errorResult) { - await expect(result).rejects.toThrow(errorResult); - } else { - await expect(result).resolves.not.toThrow(); - } + await (errorResult ? expect(result).rejects.toThrow(errorResult) : expect(result).resolves.not.toThrow()); expect(out.getText()).toMatchSnapshot(); }); }); diff --git a/packages/cspell-trie/src/app.ts b/packages/cspell-trie/src/app.ts index ecdbc084d8bb..504eb2329df7 100644 --- a/packages/cspell-trie/src/app.ts +++ b/packages/cspell-trie/src/app.ts @@ -84,16 +84,12 @@ export async function run(program: Command, argv: string[]): Promise { }); }); - try { - return program.parseAsync(argv); - } catch (e) { - return Promise.reject(e); - } + return program.parseAsync(argv); } async function fileToLines(filename: string): Promise> { const buffer = await fsp.readFile(filename); - const file = (filename.match(/\.gz$/) ? zlib.gunzipSync(buffer) : buffer).toString(UTF8); + const file = (/\.gz$/.test(filename) ? zlib.gunzipSync(buffer) : buffer).toString(UTF8); return genSequence(file.split(/\r?\n/)); } diff --git a/packages/cspell/src/app/app.test.ts b/packages/cspell/src/app/app.test.ts index 4eb605e775ba..216b2d566130 100644 --- a/packages/cspell/src/app/app.test.ts +++ b/packages/cspell/src/app/app.test.ts @@ -198,11 +198,7 @@ describe('Validate cli', () => { const commander = getCommander(); const args = argv(...testArgs); const result = app.run(commander, args); - if (!errorCheck) { - await expect(result).resolves.toBeUndefined(); - } else { - await expect(result).rejects.toThrow(errorCheck); - } + await (!errorCheck ? expect(result).resolves.toBeUndefined() : expect(result).rejects.toThrow(errorCheck)); eError ? expect(error).toHaveBeenCalled() : expect(error).not.toHaveBeenCalled(); @@ -223,11 +219,7 @@ describe('Validate cli', () => { const commander = getCommander(); const args = argv(...testArgs); const result = app.run(commander, args); - if (!errorCheck) { - await expect(result).resolves.toBeUndefined(); - } else { - await expect(result).rejects.toThrow(errorCheck); - } + await (!errorCheck ? expect(result).resolves.toBeUndefined() : expect(result).rejects.toThrow(errorCheck)); eError ? expect(error).toHaveBeenCalled() : expect(error).not.toHaveBeenCalled(); @@ -255,11 +247,7 @@ describe('Validate cli', () => { const commander = getCommander(); const args = argv(...testArgs); const result = app.run(commander, args); - if (!errorCheck) { - await expect(result).resolves.toBeUndefined(); - } else { - await expect(result).rejects.toThrow(errorCheck); - } + await (!errorCheck ? expect(result).resolves.toBeUndefined() : expect(result).rejects.toThrow(errorCheck)); eError ? expect(error).toHaveBeenCalled() : expect(error).not.toHaveBeenCalled(); @@ -300,11 +288,7 @@ describe('Validate cli', () => { const commander = getCommander(); const args = argv(...testArgs); const result = app.run(commander, args); - if (!errorCheck) { - await expect(result).resolves.toBeUndefined(); - } else { - await expect(result).rejects.toThrow(errorCheck); - } + await (!errorCheck ? expect(result).resolves.toBeUndefined() : expect(result).rejects.toThrow(errorCheck)); eError ? expect(error).toHaveBeenCalled() : expect(error).not.toHaveBeenCalled(); @@ -339,11 +323,7 @@ describe('Validate cli', () => { const commander = getCommander(); const args = argv(...testArgs); const result = app.run(commander, args); - if (!errorCheck) { - await expect(result).resolves.toBeUndefined(); - } else { - await expect(result).rejects.toThrow(errorCheck); - } + await (!errorCheck ? expect(result).resolves.toBeUndefined() : expect(result).rejects.toThrow(errorCheck)); expect(captureStdout.text).toMatchSnapshot(); expect(log.mock.calls.join('\n')).toMatchSnapshot(); expect(error.mock.calls.join('\n')).toMatchSnapshot(); diff --git a/packages/cspell/src/app/cli-reporter.ts b/packages/cspell/src/app/cli-reporter.ts index 620c9aa65df9..f0b7dcccf132 100644 --- a/packages/cspell/src/app/cli-reporter.ts +++ b/packages/cspell/src/app/cli-reporter.ts @@ -200,7 +200,7 @@ export function getReporter(options: ReporterOptions, config?: ReporterConfigura const withErrorsText = errors ? ` with ${errors} error${errors === 1 ? '' : 's'}` : ''; const numFilesWidthIssuesText = numFilesWithIssues === 1 ? '1 file' : `${numFilesWithIssues} files`; - const summaryMessage = `CSpell\x3a Files checked: ${files}${cachedFilesText}, Issues found: ${issues} in ${numFilesWidthIssuesText}${withErrorsText}.`; + const summaryMessage = `CSpell\u003A Files checked: ${files}${cachedFilesText}, Issues found: ${issues} in ${numFilesWidthIssuesText}${withErrorsText}.`; console.error(summaryMessage); diff --git a/packages/cspell/src/app/commandSuggestion.ts b/packages/cspell/src/app/commandSuggestion.ts index 81e699448b1d..cd4c5a6358e9 100644 --- a/packages/cspell/src/app/commandSuggestion.ts +++ b/packages/cspell/src/app/commandSuggestion.ts @@ -29,7 +29,7 @@ function count(_: string, previous: number | undefined): number { } function asNumber(value: string, prev: number | undefined): number { - return parseInt(value, 10) ?? prev; + return Number.parseInt(value, 10) ?? prev; } export function commandSuggestion(prog: Command): Command { diff --git a/packages/cspell/src/app/lint/lint.ts b/packages/cspell/src/app/lint/lint.ts index a59ae81b410e..37fd48b1ef4c 100644 --- a/packages/cspell/src/app/lint/lint.ts +++ b/packages/cspell/src/app/lint/lint.ts @@ -224,6 +224,7 @@ export async function runLint(cfg: LintRequest): Promise { const debugCfg = { filename, languageId: doc.languageId ?? cfg.languageId ?? 'default', + // eslint-disable-next-line unicorn/no-null config: { ...cfg, source: null }, source: spellResult.localConfigFilepath, }; diff --git a/packages/dynamic-import/src/esm/dynamicImport.mts b/packages/dynamic-import/src/esm/dynamicImport.mts index 76af19a9cef5..50ec7529d4cc 100644 --- a/packages/dynamic-import/src/esm/dynamicImport.mts +++ b/packages/dynamic-import/src/esm/dynamicImport.mts @@ -63,7 +63,7 @@ export function importResolveModuleName(moduleName: string | URL, paths: (string if (s.isFile()) { return resolvedURL; } - } catch (_) { + } catch { const error: ErrorWithCode = new Error(`Cannot find module ${moduleName}`); error.code = 'ERR_MODULE_NOT_FOUND'; lastError = error; diff --git a/packages/hunspell-reader/src/IterableHunspellReaderLegacy.test.ts b/packages/hunspell-reader/src/IterableHunspellReaderLegacy.test.ts index e86029406c85..67f2aa235d84 100644 --- a/packages/hunspell-reader/src/IterableHunspellReaderLegacy.test.ts +++ b/packages/hunspell-reader/src/IterableHunspellReaderLegacy.test.ts @@ -154,7 +154,7 @@ describe('HunspellReader read dictionaries', function () { describe('Validated loading all dictionaries in the `dictionaries` directory.', () => { const dictionaries = readdirSync(DICTIONARY_LOCATIONS) - .filter((dic) => !!dic.match(/\.aff$/)) + .filter((dic) => !!/\.aff$/.test(dic)) .map((base) => path.join(DICTIONARY_LOCATIONS, base)); it('Make sure we found some sample dictionaries', () => { expect(dictionaries.length).toBeGreaterThan(4); diff --git a/packages/hunspell-reader/src/IterableHunspellReaderLegacy.ts b/packages/hunspell-reader/src/IterableHunspellReaderLegacy.ts index 95067ab8e031..1e46faec5a9d 100644 --- a/packages/hunspell-reader/src/IterableHunspellReaderLegacy.ts +++ b/packages/hunspell-reader/src/IterableHunspellReaderLegacy.ts @@ -11,6 +11,8 @@ import type { WordInfo } from './types.js'; import { filterOrderedList } from './util.js'; const { decode } = pkgIconvLite; + +// eslint-disable-next-line unicorn/text-encoding-identifier-case const defaultEncoding = 'UTF-8'; export { WordInfo } from './types.js'; diff --git a/packages/hunspell-reader/src/aff.test.ts b/packages/hunspell-reader/src/aff.test.ts index 650fde013ff6..6e1a79e8ca52 100644 --- a/packages/hunspell-reader/src/aff.test.ts +++ b/packages/hunspell-reader/src/aff.test.ts @@ -23,6 +23,7 @@ describe('Basic Aff Validation', () => { const pAff = parseAff(getSimpleAff()); it('Reads Simple Aff', () => { const aff = pAff; + // eslint-disable-next-line unicorn/text-encoding-identifier-case expect(aff.SET).toBe('UTF-8'); expect(aff.PFX).toBeInstanceOf(Map); expect(aff.SFX).toBeInstanceOf(Map); @@ -169,7 +170,7 @@ describe('Test Aff', () => { describe('Validated loading all dictionaries in the `dictionaries` directory.', () => { function getDictionaries() { return readdirSync(DICTIONARY_LOCATIONS) - .filter((dic) => !!dic.match(/\.aff$/)) + .filter((dic) => !!/\.aff$/.test(dic)) .map((base) => path.join(DICTIONARY_LOCATIONS, base)); } const dictionaries = getDictionaries(); diff --git a/packages/hunspell-reader/src/aff.ts b/packages/hunspell-reader/src/aff.ts index 89892b68d55a..c782de7d3bd1 100644 --- a/packages/hunspell-reader/src/aff.ts +++ b/packages/hunspell-reader/src/aff.ts @@ -105,12 +105,7 @@ export class Aff { const { flags } = affWord; const subRules = this.affData.getRulesForAffSubstitution(sub); const rules = joinRules(affWord.rules, subRules); - let word: string; - if (sub.type === 'S') { - word = stripped + sub.attach; - } else { - word = sub.attach + stripped; - } + const word = sub.type === 'S' ? stripped + sub.attach : sub.attach + stripped; return this.affData.toAffixWord(affWord, word, flags, rules); } @@ -419,12 +414,14 @@ class AffData { #splitRules(rules: string): string[] { switch (this.affFlagType) { - case 'long': + case 'long': { return [...new Set(rules.replaceAll(/(..)/g, '$1//').split('//').slice(0, -1))]; - case 'num': + } + case 'num': { return [...new Set(rules.split(','))]; + } } - return [...new Set([...rules])]; + return [...new Set(rules)]; } #processAffInfo(affInfo: AffInfo) { @@ -467,11 +464,9 @@ class AffData { const fx = sfx || pfx; if (fx) { const affFx = this.#mapFx(fx); - if (affFx.type === 'P') { - return { id, idx: index, type: 'P', flags: 0, fx: affFx }; - } else { - return { id, idx: index, type: 'S', flags: 0, fx: affFx }; - } + return affFx.type === 'P' + ? { id, idx: index, type: 'P', flags: 0, fx: affFx } + : { id, idx: index, type: 'S', flags: 0, fx: affFx }; } return { id, idx: index, type: 'F', flags: flags || 0 }; } @@ -586,9 +581,11 @@ export function toAffFlagType(FLAG: string | undefined): AffFlagType { if (!FLAG) return 'char'; switch (FLAG) { case 'long': - case 'num': + case 'num': { return FLAG; - default: + } + default: { throw new Error(`Unexpected FLAG value: ${FLAG}`); + } } } diff --git a/packages/hunspell-reader/src/affLegacy.test.ts b/packages/hunspell-reader/src/affLegacy.test.ts index 3bbc37ffd6e5..f6fe916a0276 100644 --- a/packages/hunspell-reader/src/affLegacy.test.ts +++ b/packages/hunspell-reader/src/affLegacy.test.ts @@ -24,6 +24,7 @@ describe('Basic Aff Validation', () => { const pAff = AffReader.parseAff(getSimpleAff()); it('Reads Simple Aff', async () => { const aff = await pAff; + // eslint-disable-next-line unicorn/text-encoding-identifier-case expect(aff.SET).toBe('UTF-8'); expect(aff.PFX).toBeInstanceOf(Map); expect(aff.SFX).toBeInstanceOf(Map); @@ -201,7 +202,7 @@ describe('Test Aff', () => { describe('Validated loading all dictionaries in the `dictionaries` directory.', () => { function getDictionaries() { return readdirSync(DICTIONARY_LOCATIONS) - .filter((dic) => !!dic.match(/\.aff$/)) + .filter((dic) => !!/\.aff$/.test(dic)) .map((base) => path.join(DICTIONARY_LOCATIONS, base)); } const dictionaries = getDictionaries(); diff --git a/packages/hunspell-reader/src/affLegacy.ts b/packages/hunspell-reader/src/affLegacy.ts index 0f8931fc8e2e..b1f5a9a85a6e 100644 --- a/packages/hunspell-reader/src/affLegacy.ts +++ b/packages/hunspell-reader/src/affLegacy.ts @@ -161,7 +161,7 @@ export class Aff { getMatchingRules(rules: string): Rule[] { const { AF = [] } = this.affInfo; - const idx = regExpIsNumber.test(rules) ? parseInt(rules, 10) : -1; + const idx = regExpIsNumber.test(rules) ? Number.parseInt(rules, 10) : -1; const rulesToSplit = AF[idx] || rules; return this.separateRules(rulesToSplit) .map((key) => this.rules.get(key)) @@ -170,10 +170,12 @@ export class Aff { joinRules(rules: string[]): string { switch (this.affInfo.FLAG) { - case 'long': + case 'long': { return rules.join(''); - case 'num': + } + case 'num': { return rules.join(','); + } } return rules.join(''); } @@ -188,12 +190,14 @@ export class Aff { #separateRules(rules: string): string[] { switch (this.affInfo.FLAG) { - case 'long': + case 'long': { return [...new Set(rules.replaceAll(/(..)/g, '$1//').split('//').slice(0, -1))]; - case 'num': + } + case 'num': { return [...new Set(rules.split(','))]; + } } - return [...new Set([...rules])]; + return [...new Set(rules)]; } get iConv() { @@ -222,12 +226,10 @@ export function processRules(affInfo: AffInfo): Map { const pfxRules: PfxRule[] = [...(affInfo.PFX || [])] .map(([, pfx]) => pfx) .map((pfx) => ({ id: pfx.id, type: 'pfx', pfx })); - const flagRules: FlagRule[] = [ - ...GS.sequenceFromObject(affInfo as AffTransformFlags) - .filter(([key, value]) => !!affFlag[key] && !!value) - .map(([key, value]) => ({ id: value!, type: 'flag', flags: affFlag[key] })), - ]; - + const flagRules: FlagRule[] = GS.sequenceFromObject(affInfo as AffTransformFlags) + .filter(([key, value]) => !!affFlag[key] && !!value) + .map(([key, value]) => ({ id: value!, type: 'flag', flags: affFlag[key] })) + .toArray(); const rules = [...sfxRules, ...pfxRules, ...flagRules].reduce((acc, rule) => { acc.set(rule.id, rule); return acc; diff --git a/packages/hunspell-reader/src/affReader.ts b/packages/hunspell-reader/src/affReader.ts index 99556403bd63..6322fad46161 100644 --- a/packages/hunspell-reader/src/affReader.ts +++ b/packages/hunspell-reader/src/affReader.ts @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/text-encoding-identifier-case */ import assert from 'node:assert'; import { readFile } from 'node:fs/promises'; @@ -165,7 +166,7 @@ function parseAffixCreation(line: AffLine): Fx { const fx: Fx = { id: flag, type: line.option === 'SFX' ? 'SFX' : 'PFX', - combinable: !!combinable.match(yesRegex), + combinable: !!yesRegex.test(combinable), count, extra, substitutionSets: new Map(), @@ -252,8 +253,8 @@ const asPfx = collectFx; const asSfx = collectFx; const asString = () => collectPrimitive((v) => v, ''); -const asBoolean = () => collectPrimitive((v) => !!parseInt(v), '1'); -const asNumber = () => collectPrimitive(parseInt, '0'); +const asBoolean = () => collectPrimitive((v) => !!Number.parseInt(v), '1'); +const asNumber = () => collectPrimitive(Number.parseInt, '0'); function collectPrimitive(map: (line: string) => T, defaultValue = ''): Collector { let primitive: T | undefined; @@ -405,7 +406,7 @@ export async function parseAffFile(filename: string, encoding: string = UTF8) { } function convertHtmlEntities(line: string, index: number): string { - if (line.indexOf('&') < 0) return line; + if (!line.includes('&')) return line; const fixed = decodeHtmlEntities(line); if (fixed !== line) { if (htmlEntitiesFound < 10) { diff --git a/packages/hunspell-reader/src/commandDictInfo.ts b/packages/hunspell-reader/src/commandDictInfo.ts index c437bb380c91..ee9b886f72d7 100644 --- a/packages/hunspell-reader/src/commandDictInfo.ts +++ b/packages/hunspell-reader/src/commandDictInfo.ts @@ -24,6 +24,6 @@ async function action(hunspellFile: string, locale: string): Promise { const info = affToDicInfo(aff, locale); - const rawJson = JSON.stringify(info, null, 2); + const rawJson = JSON.stringify(info, undefined, 2); console.log(escapeUnicodeCode(rawJson)); } diff --git a/packages/hunspell-reader/src/commandWords.ts b/packages/hunspell-reader/src/commandWords.ts index ca901707be40..51b81755ffff 100644 --- a/packages/hunspell-reader/src/commandWords.ts +++ b/packages/hunspell-reader/src/commandWords.ts @@ -41,7 +41,7 @@ export function getCommand(): Command { function notify(message: string, newLine = true) { message = message + (newLine ? '\n' : ''); - logStream.write(message, 'utf-8'); + logStream.write(message, 'utf8'); } function yesNo(value: boolean) { @@ -189,7 +189,7 @@ async function actionPrime(hunspellDicFilename: string, options: Options) { const callback = showProgress ? () => { current++; - !(current % reportProgressRate) && process.stderr.write(calcProgress(), 'utf-8'); + !(current % reportProgressRate) && process.stderr.write(calcProgress(), 'utf8'); } : () => { /* void */ diff --git a/packages/hunspell-reader/src/iterableToStream.ts b/packages/hunspell-reader/src/iterableToStream.ts index 5d06f457094b..a27ee2c0a8da 100644 --- a/packages/hunspell-reader/src/iterableToStream.ts +++ b/packages/hunspell-reader/src/iterableToStream.ts @@ -11,9 +11,9 @@ export type IterableLike = Iterable | IterableIterator; */ export function iterableToStream( src: IterableLike, - options: stream.ReadableOptions = { encoding: 'utf8' }, + options?: stream.ReadableOptions, ): stream.Readable { - return new ReadableObservableStream(src, options); + return new ReadableObservableStream(src, options ?? { encoding: 'utf8' }); } class ReadableObservableStream extends stream.Readable { @@ -32,6 +32,9 @@ class ReadableObservableStream extends stream.Readable { this.iter = this._source[Symbol.iterator](); } if (this.done) { + // See: https://nodejs.org/api/stream.html#readablepushchunk-encoding + // Pushing null means the stream is done. + // eslint-disable-next-line unicorn/no-null this.push(null); return; } @@ -46,6 +49,9 @@ class ReadableObservableStream extends stream.Readable { if (r.value !== null && r.value !== undefined) { this.push(r.value); } + // See: https://nodejs.org/api/stream.html#readablepushchunk-encoding + // Pushing null means the stream is done. + // eslint-disable-next-line unicorn/no-null this.push(null); } } diff --git a/packages/hunspell-reader/src/textUtils.test.ts b/packages/hunspell-reader/src/textUtils.test.ts index 510272cc8f87..0e3c31693c6d 100644 --- a/packages/hunspell-reader/src/textUtils.test.ts +++ b/packages/hunspell-reader/src/textUtils.test.ts @@ -11,6 +11,7 @@ describe('textUtils', () => { ${'café'.normalize('NFD')} | ${undefined} | ${'"cafe\\u0301"'} ${'à la mode café résumé'.normalize('NFD')} | ${undefined} | ${'"a\\u0300 la mode cafe\\u0301 re\\u0301sume\\u0301"'} ${'abc\nabc'} | ${undefined} | ${'"abc\\nabc"'} + ${'😀😃\n😎😬'} | ${/\P{L}/gu} | ${'"\\uD83D\\uDE00\\uD83D\\uDE03\\n\\uD83D\\uDE0E\\uD83D\\uDE2C"'} `('escapeUnicodeCode $text', ({ text, regexp, expected }) => { const result = escapeUnicodeCode(JSON.stringify(text), regexp); expect(result).toBe(expected); diff --git a/packages/hunspell-reader/src/textUtils.ts b/packages/hunspell-reader/src/textUtils.ts index 95ba4294fee4..0bec02521357 100644 --- a/packages/hunspell-reader/src/textUtils.ts +++ b/packages/hunspell-reader/src/textUtils.ts @@ -12,15 +12,19 @@ function replaceWithUnicode(substring: string): string { const start = 0x20; const end = 0x7a; let val = ''; - for (let i = 0; i < substring.length; ++i) { - const char = substring[i]; - const code = char.charCodeAt(0); + for (const char of substring) { + const code = char.codePointAt(0) || 0; if (code >= start && code <= end) { val += char; continue; } - const hex = '0000' + code.toString(16); - val += code < 256 ? '\\x' + hex.slice(-2) : '\\u' + hex.slice(-4); + for (let i = 0; i < char.length; i += 1) { + // Use charCodeAt to get the value because JSON does not handle \u{10000} correctly. + // eslint-disable-next-line unicorn/prefer-code-point + const code = char.charCodeAt(i); + const hex = code.toString(16).toUpperCase().padStart(4, '0'); + val += code < 256 ? '\\x' + hex.slice(-2) : hex.length === 4 ? '\\u' + hex : '\\u{' + hex + '}'; + } } return val; } @@ -47,7 +51,7 @@ export function toRange(letters: string, minLength = 4): string { return; } for (let code = begin + 1; code < end; code += 1) { - chars.push(String.fromCharCode(code)); + chars.push(String.fromCodePoint(code)); } } @@ -57,9 +61,8 @@ export function toRange(letters: string, minLength = 4): string { endChar = ''; } - for (let i = 0; i < letters.length; ++i) { - const letter = letters[i]; - const code = letter.charCodeAt(0); + for (const letter of letters) { + const code = letter.codePointAt(0) || 0; if (code - end === 1) { end = code; endChar = letter; diff --git a/rfc/rfc-0001 suggestions/src/config-definitions.ts b/rfc/rfc-0001 suggestions/src/config-definitions.ts index 967a69e4d801..c49872b7a9f2 100644 --- a/rfc/rfc-0001 suggestions/src/config-definitions.ts +++ b/rfc/rfc-0001 suggestions/src/config-definitions.ts @@ -47,6 +47,7 @@ type TermTypo = string[] | string; const TermForbid: TermForbid = false; const TermWord: TermWord = true; +// eslint-disable-next-line unicorn/no-null const TermIgnore: TermIgnore = null; type Term = TermWord | TermForbid | TermIgnore | TermTypo; diff --git a/scripts/build-cspell-schema.mjs b/scripts/build-cspell-schema.mjs index 2c66ceb74b03..63ccb32539f8 100755 --- a/scripts/build-cspell-schema.mjs +++ b/scripts/build-cspell-schema.mjs @@ -57,7 +57,7 @@ async function run() { const schema = tsj.createGenerator(config).createSchema(config.type); schema.allowTrailingCommas = true; const stringify = config.sortProps ? safeStableStringify : JSON.stringify; - const schemaString = stringify(schema, null, 2); + const schemaString = stringify(schema, undefined, 2); await writeFile(path.join(typesDir, outFile), schemaString); await writeFile(new URL(outFile, rootUrl), schemaString); diff --git a/scripts/update-package-json.mjs b/scripts/update-package-json.mjs index ac902b93870b..a0cc711c7e8c 100755 --- a/scripts/update-package-json.mjs +++ b/scripts/update-package-json.mjs @@ -10,7 +10,7 @@ async function updatePackageJson(pkgFile) { const directory = pkgFile.split(/[/\\]/g).slice(-3, -1).join('/'); console.log(directory); - const pkg = JSON.parse(await fs.readFile(pkgFile, 'utf-8')); + const pkg = JSON.parse(await fs.readFile(pkgFile, 'utf8')); const repository = { type: 'git', @@ -20,7 +20,7 @@ async function updatePackageJson(pkgFile) { pkg.repository = repository; - await fs.writeFile(pkgFile, JSON.stringify(pkg, null, 2) + '\n'); + await fs.writeFile(pkgFile, JSON.stringify(pkg, undefined, 2) + '\n'); } async function run() { diff --git a/scripts/update-release-please.mjs b/scripts/update-release-please.mjs index 4427a50344f4..db83003aea3d 100755 --- a/scripts/update-release-please.mjs +++ b/scripts/update-release-please.mjs @@ -69,7 +69,7 @@ async function readJson(filename) { } async function writeJson(filename, data) { - const content = JSON.stringify(data, null, 4) + '\n'; + const content = JSON.stringify(data, undefined, 4) + '\n'; await writeFile(filename, content, { encoding: 'utf8' }); } diff --git a/test-packages/cspell-lib/test-cspell-esbuild-cjs/package.json b/test-packages/cspell-lib/test-cspell-esbuild-cjs/package.json index 3824e03101f2..c0c68c4b4394 100644 --- a/test-packages/cspell-lib/test-cspell-esbuild-cjs/package.json +++ b/test-packages/cspell-lib/test-cspell-esbuild-cjs/package.json @@ -10,7 +10,8 @@ "type": "module", "private": true, "scripts": { - "#build": "node build.mjs", + "#build": "cd source && pnpm build", + "clean": "shx rm -rf bin/dist", "test": "pnpm test:esm && pnpm test:cjs", "test:esm": "node bin.mjs README.md", "test:cjs": "node bin.cjs" diff --git a/test-packages/cspell-lib/test-cspell-lib-rollup/plugin/src/rollup-plugin-inject-dirname.mts b/test-packages/cspell-lib/test-cspell-lib-rollup/plugin/src/rollup-plugin-inject-dirname.mts index 9caaa248dfce..c49417b2420a 100644 --- a/test-packages/cspell-lib/test-cspell-lib-rollup/plugin/src/rollup-plugin-inject-dirname.mts +++ b/test-packages/cspell-lib/test-cspell-lib-rollup/plugin/src/rollup-plugin-inject-dirname.mts @@ -54,8 +54,16 @@ function calcPosition(code: string): number | undefined { if (!code.includes('__dirname')) return undefined; const beforePos = code.indexOf('commonjsGlobal'); + const lastImportPos = code.lastIndexOf('import ', beforePos); + + // const context = { + // after: code.slice(0, lastImportPos).split('\n').slice(-3), + // before: code.slice(lastImportPos, beforePos).split('\n').slice(0, 3), + // }; + + // console.error('calcPosition %o', { includes: true, beforePos, lastImportPos, ...context }); + if (beforePos < 0) return logError('`commonjsGlobal` Not found, cannot inject.'); - const lastImportPos = code.lastIndexOf('import', beforePos); if (lastImportPos < 0) return logError('`import` not found, cannot inject.'); const betweenCode = code.slice(lastImportPos, beforePos); diff --git a/test-packages/cspell-lib/test-cspell-lib-rollup/rollup.config.mjs b/test-packages/cspell-lib/test-cspell-lib-rollup/rollup.config.mjs index 52313b32f2ae..c3a00840e100 100644 --- a/test-packages/cspell-lib/test-cspell-lib-rollup/rollup.config.mjs +++ b/test-packages/cspell-lib/test-cspell-lib-rollup/rollup.config.mjs @@ -8,7 +8,7 @@ import rollupPluginTypescript from '@rollup/plugin-typescript'; import { injectDirname } from './plugin/index.mjs'; -const pkg = JSON.parse(readFileSync('./package.json', 'utf-8')); +const pkg = JSON.parse(readFileSync('./package.json', 'utf8')); /** @type {import('rollup').RollupOptions} */ const common = { diff --git a/test-packages/cspell-pipe/test-cspell-pipe-rollup/rollup.config.mjs b/test-packages/cspell-pipe/test-cspell-pipe-rollup/rollup.config.mjs index 63fa51a1493a..c8548c2a1254 100644 --- a/test-packages/cspell-pipe/test-cspell-pipe-rollup/rollup.config.mjs +++ b/test-packages/cspell-pipe/test-cspell-pipe-rollup/rollup.config.mjs @@ -5,7 +5,7 @@ import rollupPluginJson from '@rollup/plugin-json'; import rollupPluginNodeResolve from '@rollup/plugin-node-resolve'; import rollupPluginTypescript from '@rollup/plugin-typescript'; -const pkg = JSON.parse(readFileSync('./package.json', 'utf-8')); +const pkg = JSON.parse(readFileSync('./package.json', 'utf8')); /** @type {import('rollup').RollupOptions} */ const common = { diff --git a/test-packages/cspell-service-bus/test-cspell-service-bus-rollup/rollup.config.mjs b/test-packages/cspell-service-bus/test-cspell-service-bus-rollup/rollup.config.mjs index 2f0dd39f7c9f..e346765a1ea9 100644 --- a/test-packages/cspell-service-bus/test-cspell-service-bus-rollup/rollup.config.mjs +++ b/test-packages/cspell-service-bus/test-cspell-service-bus-rollup/rollup.config.mjs @@ -4,7 +4,7 @@ import rollupPluginJson from '@rollup/plugin-json'; import rollupPluginNodeResolve from '@rollup/plugin-node-resolve'; import rollupPluginTypescript from '@rollup/plugin-typescript'; -const pkg = JSON.parse(readFileSync('./package.json', 'utf-8')); +const pkg = JSON.parse(readFileSync('./package.json', 'utf8')); /** @type {import('rollup').RollupOptions} */ const common = { diff --git a/test-packages/cspell-strong-weak-map/test-cspell-strong-weak-map/rollup.config.mjs b/test-packages/cspell-strong-weak-map/test-cspell-strong-weak-map/rollup.config.mjs index 3fb567a0a3be..891d9644de20 100644 --- a/test-packages/cspell-strong-weak-map/test-cspell-strong-weak-map/rollup.config.mjs +++ b/test-packages/cspell-strong-weak-map/test-cspell-strong-weak-map/rollup.config.mjs @@ -5,7 +5,7 @@ import rollupPluginJson from '@rollup/plugin-json'; import rollupPluginNodeResolve from '@rollup/plugin-node-resolve'; import rollupPluginTypescript from '@rollup/plugin-typescript'; -const pkg = JSON.parse(readFileSync('./package.json', 'utf-8')); +const pkg = JSON.parse(readFileSync('./package.json', 'utf8')); /** @type {import('rollup').RollupOptions} */ const common = { diff --git a/test-packages/cspell-trie-lib/test-cspell-trie-lib/rollup.config.mjs b/test-packages/cspell-trie-lib/test-cspell-trie-lib/rollup.config.mjs index 3fb567a0a3be..891d9644de20 100644 --- a/test-packages/cspell-trie-lib/test-cspell-trie-lib/rollup.config.mjs +++ b/test-packages/cspell-trie-lib/test-cspell-trie-lib/rollup.config.mjs @@ -5,7 +5,7 @@ import rollupPluginJson from '@rollup/plugin-json'; import rollupPluginNodeResolve from '@rollup/plugin-node-resolve'; import rollupPluginTypescript from '@rollup/plugin-typescript'; -const pkg = JSON.parse(readFileSync('./package.json', 'utf-8')); +const pkg = JSON.parse(readFileSync('./package.json', 'utf8')); /** @type {import('rollup').RollupOptions} */ const common = { diff --git a/test-packages/cspell-types/test-cspell-types-rollup/rollup.config.mjs b/test-packages/cspell-types/test-cspell-types-rollup/rollup.config.mjs index e9289addafc1..037634c35d8b 100644 --- a/test-packages/cspell-types/test-cspell-types-rollup/rollup.config.mjs +++ b/test-packages/cspell-types/test-cspell-types-rollup/rollup.config.mjs @@ -5,7 +5,7 @@ import rollupPluginJson from '@rollup/plugin-json'; import rollupPluginNodeResolve from '@rollup/plugin-node-resolve'; import rollupPluginTypescript from '@rollup/plugin-typescript'; -const pkg = JSON.parse(readFileSync('./package.json', 'utf-8')); +const pkg = JSON.parse(readFileSync('./package.json', 'utf8')); /** @type {import('rollup').RollupOptions} */ const common = { diff --git a/test-packages/dynamic-import/test-dynamic-import-rollup/rollup.config.mjs b/test-packages/dynamic-import/test-dynamic-import-rollup/rollup.config.mjs index f5ea07f9bfe5..7fd4905ace58 100644 --- a/test-packages/dynamic-import/test-dynamic-import-rollup/rollup.config.mjs +++ b/test-packages/dynamic-import/test-dynamic-import-rollup/rollup.config.mjs @@ -5,7 +5,7 @@ import rollupPluginJson from '@rollup/plugin-json'; import rollupPluginNodeResolve from '@rollup/plugin-node-resolve'; import rollupPluginTypescript from '@rollup/plugin-typescript'; -const pkg = JSON.parse(readFileSync('./package.json', 'utf-8')); +const pkg = JSON.parse(readFileSync('./package.json', 'utf8')); /** @type {import('rollup').RollupOptions} */ const common = { diff --git a/tools/perf-chart/lib/app.cjs b/tools/perf-chart/lib/app.cjs index 40d17406dd1d..b8e0f90cb20f 100644 --- a/tools/perf-chart/lib/app.cjs +++ b/tools/perf-chart/lib/app.cjs @@ -4315,7 +4315,7 @@ ${createPerfTable2(data)} return markdown; } async function readCsvData(csvFile) { - const csv = await import_node_fs.promises.readFile(csvFile, "utf-8"); + const csv = await import_node_fs.promises.readFile(csvFile, "utf8"); const records = parse(csv, { columns: true, cast: true }); return records; } diff --git a/tools/perf-chart/src/perfChart.ts b/tools/perf-chart/src/perfChart.ts index c907419abe37..88f358d34f65 100644 --- a/tools/perf-chart/src/perfChart.ts +++ b/tools/perf-chart/src/perfChart.ts @@ -32,7 +32,7 @@ ${createPerfTable2(data)} } async function readCsvData(csvFile: string | URL): Promise { - const csv = await fs.readFile(csvFile, 'utf-8'); + const csv = await fs.readFile(csvFile, 'utf8'); const records = parseCsv(csv, { columns: true, cast: true }) as CsvRecord[]; return records; } diff --git a/tsconfig.json b/tsconfig.json index c80c2f057201..031d0511676c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,5 +4,6 @@ "extends": "./tsconfig.base.json", "compilerOptions": { "skipLibCheck": false - } + }, + "include": [] }