From 18d22b7c58546e0eafce78ceb9961271c7d0d4c7 Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Fri, 14 Feb 2025 02:28:40 -0700 Subject: [PATCH] refactor: Upgrade ESLint (#178) * chore: Upgrade ESLint * Add back eslintignore * Skip tests relying on project files * Update eslint.config.js Co-authored-by: Milos Djermanovic * Update eslint.config.js Co-authored-by: Milos Djermanovic * Update eslint.config.js Co-authored-by: Milos Djermanovic * Update package.json Co-authored-by: Milos Djermanovic * Add formatting config --------- Co-authored-by: Milos Djermanovic --- .eslintrc.cjs | 42 ---------------- conf/environments.js | 2 +- eslint.config.js | 52 ++++++++++++++++++++ lib/cascading-config-array-factory.js | 10 ++-- lib/config-array-factory.js | 19 ++++--- lib/config-array/config-array.js | 2 + lib/config-array/config-dependency.js | 10 ++-- lib/config-array/extracted-config.js | 4 +- lib/config-array/ignore-pattern.js | 11 +++-- lib/config-array/override-tester.js | 12 +++-- lib/flat-compat.js | 7 +-- lib/shared/ajv.js | 2 +- lib/shared/config-ops.js | 4 +- lib/shared/config-validator.js | 25 +++++++--- lib/shared/deprecation-warnings.js | 2 +- lib/shared/relative-module-resolver.js | 3 +- package.json | 9 ++-- tests/lib/cascading-config-array-factory.js | 21 ++++---- tests/lib/commonjs.cjs | 4 +- tests/lib/config-array-factory.js | 20 ++++---- tests/lib/config-array/config-array.js | 10 ++-- tests/lib/config-array/config-dependency.js | 8 +-- tests/lib/config-array/extracted-config.js | 2 +- tests/lib/config-array/ignore-pattern.js | 4 +- tests/lib/config-array/override-tester.js | 8 +-- tests/lib/flat-compat.js | 6 +-- tests/lib/shared/config-ops.js | 2 +- tests/lib/shared/config-validator.js | 2 +- tests/lib/shared/relative-module-resolver.js | 2 +- universal.js | 3 +- 30 files changed, 172 insertions(+), 136 deletions(-) delete mode 100644 .eslintrc.cjs create mode 100644 eslint.config.js diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index de2207d9..00000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,42 +0,0 @@ -"use strict"; - -module.exports = { - root: true, - extends: [ - "eslint" - ], - parserOptions: { - ecmaVersion: 2020 - }, - - /* - * it fixes eslint-plugin-jsdoc's reports: "Invalid JSDoc tag name "template" jsdoc/check-tag-names" - * refs: https://github.com/gajus/eslint-plugin-jsdoc#check-tag-names - */ - settings: { - jsdoc: { - mode: "typescript" - } - }, - - overrides: [ - { - files: ["tests/**/*"], - env: { mocha: true }, - rules: { - "no-restricted-syntax": ["error", { - selector: "CallExpression[callee.object.name='assert'][callee.property.name='doesNotThrow']", - message: "`assert.doesNotThrow()` should be replaced with a comment next to the code." - }], - - // Overcome https://github.com/mysticatea/eslint-plugin-node/issues/250 - "node/no-unsupported-features/es-syntax": ["error", { - ignores: [ - "modules", - "dynamicImport" - ] - }] - } - } - ] -}; diff --git a/conf/environments.js b/conf/environments.js index 50d1b1d1..e296fae7 100644 --- a/conf/environments.js +++ b/conf/environments.js @@ -23,7 +23,7 @@ function getDiff(current, prev) { const retv = {}; for (const [key, value] of Object.entries(current)) { - if (!Object.hasOwnProperty.call(prev, key)) { + if (!Object.hasOwn(prev, key)) { retv[key] = value; } } diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..0981a822 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,52 @@ +/** + * @fileoverview ESLint configuration file + * @author Nicholas C. Zakas + */ + +//----------------------------------------------------------------------------- +// Imports +//----------------------------------------------------------------------------- + +import eslintConfigESLint from "eslint-config-eslint"; +import eslintConfigESLintFormatting from "eslint-config-eslint/formatting"; + +//----------------------------------------------------------------------------- +// Config +//----------------------------------------------------------------------------- + +export default [ + + { + ignores: [ + "tests/fixtures", + "coverage", + "docs", + "jsdoc", + "dist" + ] + }, + + ...eslintConfigESLint, + eslintConfigESLintFormatting, + { + files: ["tests/**/*"], + languageOptions: { + globals: { + describe: "readonly", + xdescribe: "readonly", + it: "readonly", + xit: "readonly", + beforeEach: "readonly", + afterEach: "readonly", + before: "readonly", + after: "readonly" + } + }, + rules: { + "no-restricted-syntax": ["error", { + selector: "CallExpression[callee.object.name='assert'][callee.property.name='doesNotThrow']", + message: "`assert.doesNotThrow()` should be replaced with a comment next to the code." + }] + } + } +]; diff --git a/lib/cascading-config-array-factory.js b/lib/cascading-config-array-factory.js index 597352e4..71549107 100644 --- a/lib/cascading-config-array-factory.js +++ b/lib/cascading-config-array-factory.js @@ -23,8 +23,8 @@ //------------------------------------------------------------------------------ import debugOrig from "debug"; -import os from "os"; -import path from "path"; +import os from "node:os"; +import path from "node:path"; import { ConfigArrayFactory } from "./config-array-factory.js"; import { @@ -193,7 +193,7 @@ function createCLIConfigArray({ */ class ConfigurationNotFoundError extends Error { - // eslint-disable-next-line jsdoc/require-description + /** * @param {string} directoryPath The directory path. */ @@ -345,6 +345,7 @@ class CascadingConfigArrayFactory { * @param {string} directoryPath The path to a leaf directory. * @param {boolean} configsExistInSubdirs `true` if configurations exist in subdirectories. * @returns {ConfigArray} The loaded config. + * @throws {Error} If a config file is invalid. * @private */ _loadConfigInAncestors(directoryPath, configsExistInSubdirs = false) { @@ -446,6 +447,7 @@ class CascadingConfigArrayFactory { * @param {string} directoryPath The path to the leaf directory to find config files. * @param {boolean} ignoreNotFoundError If `true` then it doesn't throw `ConfigurationNotFoundError`. * @returns {ConfigArray} The loaded config. + * @throws {Error} If a config file is invalid. * @private */ _finalizeConfigArray(configArray, directoryPath, ignoreNotFoundError) { @@ -482,7 +484,7 @@ class CascadingConfigArrayFactory { !directoryPath.startsWith(homePath) ) { const lastElement = - personalConfigArray[personalConfigArray.length - 1]; + personalConfigArray.at(-1); emitDeprecationWarning( lastElement.filePath, diff --git a/lib/config-array-factory.js b/lib/config-array-factory.js index e4b18ebd..5c7c3ef0 100644 --- a/lib/config-array-factory.js +++ b/lib/config-array-factory.js @@ -39,10 +39,10 @@ //------------------------------------------------------------------------------ import debugOrig from "debug"; -import fs from "fs"; +import fs from "node:fs"; import importFresh from "import-fresh"; -import { createRequire } from "module"; -import path from "path"; +import { createRequire } from "node:module"; +import path from "node:path"; import stripComments from "strip-json-comments"; import { @@ -254,7 +254,7 @@ function loadPackageJSONConfigFile(filePath) { try { const packageData = loadJSONConfigFile(filePath); - if (!Object.hasOwnProperty.call(packageData, "eslintConfig")) { + if (!Object.hasOwn(packageData, "eslintConfig")) { throw Object.assign( new Error("package.json file doesn't have 'eslintConfig' field."), { code: "ESLINT_CONFIG_FIELD_NOT_FOUND" } @@ -273,6 +273,7 @@ function loadPackageJSONConfigFile(filePath) { * Loads a `.eslintignore` from a file. * @param {string} filePath The filename to load. * @returns {string[]} The ignore patterns from the file. + * @throws {Error} If the file cannot be read. * @private */ function loadESLintIgnoreFile(filePath) { @@ -345,7 +346,7 @@ function loadConfigFile(filePath) { function writeDebugLogForLoading(request, relativeTo, filePath) { /* istanbul ignore next */ if (debug.enabled) { - let nameAndVersion = null; + let nameAndVersion = null; // eslint-disable-line no-useless-assignment -- known bug in the rule try { const packageJsonPath = ModuleResolver.resolve( @@ -510,6 +511,7 @@ class ConfigArrayFactory { * @param {Object} [options] The options. * @param {string} [options.basePath] The base path to resolve relative paths in `overrides[].files`, `overrides[].excludedFiles`, and `ignorePatterns`. * @param {string} [options.name] The config name. + * @throws {Error} If the config file is invalid. * @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist. */ loadInDirectory(directoryPath, { basePath, name } = {}) { @@ -595,6 +597,7 @@ class ConfigArrayFactory { /** * Load `.eslintignore` file in the current working directory. * @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist. + * @throws {Error} If the ignore file is invalid. */ loadDefaultESLintIgnore() { const slots = internalSlotsMap.get(this); @@ -607,7 +610,7 @@ class ConfigArrayFactory { if (fs.existsSync(packageJsonPath)) { const data = loadJSONConfigFile(packageJsonPath); - if (Object.hasOwnProperty.call(data, "eslintIgnore")) { + if (Object.hasOwn(data, "eslintIgnore")) { if (!Array.isArray(data.eslintIgnore)) { throw new Error("Package.json eslintIgnore property requires an array of paths"); } @@ -796,6 +799,7 @@ class ConfigArrayFactory { * @param {string} extendName The name of a base config. * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. * @returns {IterableIterator} The normalized config. + * @throws {Error} If the extended config file can't be loaded. * @private */ _loadExtends(extendName, ctx) { @@ -819,6 +823,7 @@ class ConfigArrayFactory { * @param {string} extendName The name of a base config. * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. * @returns {IterableIterator} The normalized config. + * @throws {Error} If the extended config file can't be loaded. * @private */ _loadExtendedBuiltInConfig(extendName, ctx) { @@ -868,6 +873,7 @@ class ConfigArrayFactory { * @param {string} extendName The name of a base config. * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. * @returns {IterableIterator} The normalized config. + * @throws {Error} If the extended config file can't be loaded. * @private */ _loadExtendedPluginConfig(extendName, ctx) { @@ -905,6 +911,7 @@ class ConfigArrayFactory { * @param {string} extendName The name of a base config. * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. * @returns {IterableIterator} The normalized config. + * @throws {Error} If the extended config file can't be loaded. * @private */ _loadExtendedShareableConfig(extendName, ctx) { diff --git a/lib/config-array/config-array.js b/lib/config-array/config-array.js index 5766fc46..8b3ec28c 100644 --- a/lib/config-array/config-array.js +++ b/lib/config-array/config-array.js @@ -178,6 +178,7 @@ class PluginConflictError extends Error { * @param {Record} target The destination to merge * @param {Record|undefined} source The source to merge. * @returns {void} + * @throws {PluginConflictError} When a plugin was conflicted. */ function mergePlugins(target, source) { if (!isNonNullObject(source)) { @@ -258,6 +259,7 @@ function mergeRuleConfigs(target, source) { * @param {ConfigArray} instance The config elements. * @param {number[]} indices The indices to use. * @returns {ExtractedConfig} The extracted config. + * @throws {Error} When a plugin is conflicted. */ function createConfig(instance, indices) { const config = new ExtractedConfig(); diff --git a/lib/config-array/config-dependency.js b/lib/config-array/config-dependency.js index 080e6405..80968950 100644 --- a/lib/config-array/config-dependency.js +++ b/lib/config-array/config-dependency.js @@ -15,7 +15,7 @@ * @author Toru Nagashima */ -import util from "util"; +import util from "node:util"; /** * The class is to store parsers or plugins. @@ -88,8 +88,8 @@ class ConfigDependency { this.importerPath = importerPath; } - // eslint-disable-next-line jsdoc/require-description /** + * Converts this instance to a JSON compatible object. * @returns {Object} a JSON compatible object. */ toJSON() { @@ -103,14 +103,14 @@ class ConfigDependency { return obj; } - // eslint-disable-next-line jsdoc/require-description /** + * Custom inspect method for Node.js `console.log()`. * @returns {Object} an object to display by `console.log()`. */ [util.inspect.custom]() { const { - definition: _ignore1, // eslint-disable-line no-unused-vars - original: _ignore2, // eslint-disable-line no-unused-vars + definition: _ignore1, // eslint-disable-line no-unused-vars -- needed to make `obj` correct + original: _ignore2, // eslint-disable-line no-unused-vars -- needed to make `obj` correct ...obj } = this; diff --git a/lib/config-array/extracted-config.js b/lib/config-array/extracted-config.js index e93b0b67..65206f27 100644 --- a/lib/config-array/extracted-config.js +++ b/lib/config-array/extracted-config.js @@ -120,10 +120,10 @@ class ExtractedConfig { */ toCompatibleObjectAsConfigFileContent() { const { - /* eslint-disable no-unused-vars */ + /* eslint-disable no-unused-vars -- needed to make `config` correct */ configNameOfNoInlineConfig: _ignore1, processor: _ignore2, - /* eslint-enable no-unused-vars */ + /* eslint-enable no-unused-vars -- needed to make `config` correct */ ignores, ...config } = this; diff --git a/lib/config-array/ignore-pattern.js b/lib/config-array/ignore-pattern.js index 3022ba9f..21e8f9e9 100644 --- a/lib/config-array/ignore-pattern.js +++ b/lib/config-array/ignore-pattern.js @@ -32,8 +32,8 @@ // Requirements //------------------------------------------------------------------------------ -import assert from "assert"; -import path from "path"; +import assert from "node:assert"; +import path from "node:path"; import ignore from "ignore"; import debugOrig from "debug"; @@ -117,6 +117,9 @@ const DotPatterns = Object.freeze([".*", "!.eslintrc.*", "!../"]); // Public //------------------------------------------------------------------------------ +/** + * + */ class IgnorePattern { /** @@ -153,9 +156,7 @@ class IgnorePattern { debug("Create with: %o", ignorePatterns); const basePath = getCommonAncestorPath(ignorePatterns.map(p => p.basePath)); - const patterns = [].concat( - ...ignorePatterns.map(p => p.getPatternsRelativeTo(basePath)) - ); + const patterns = ignorePatterns.flatMap(p => p.getPatternsRelativeTo(basePath)); const ig = ignore({ allowRelativePaths: true }).add([...DotPatterns, ...patterns]); const dotIg = ignore({ allowRelativePaths: true }).add(patterns); diff --git a/lib/config-array/override-tester.js b/lib/config-array/override-tester.js index 460aafcf..3a445b1a 100644 --- a/lib/config-array/override-tester.js +++ b/lib/config-array/override-tester.js @@ -17,9 +17,9 @@ * @author Toru Nagashima */ -import assert from "assert"; -import path from "path"; -import util from "util"; +import assert from "node:assert"; +import path from "node:path"; +import util from "node:util"; import minimatch from "minimatch"; const { Minimatch } = minimatch; @@ -94,6 +94,7 @@ class OverrideTester { * @param {string|string[]} excludedFiles The glob patterns for excluded files. * @param {string} basePath The path to the base directory to test paths. * @returns {OverrideTester|null} The created instance or `null`. + * @throws {Error} When invalid patterns are given. */ static create(files, excludedFiles, basePath) { const includePatterns = normalizePatterns(files); @@ -183,6 +184,7 @@ class OverrideTester { * Test if a given path is matched or not. * @param {string} filePath The absolute path to the target file. * @returns {boolean} `true` if the path was matched. + * @throws {Error} When invalid `filePath` is given. */ test(filePath) { if (typeof filePath !== "string" || !path.isAbsolute(filePath)) { @@ -196,8 +198,8 @@ class OverrideTester { )); } - // eslint-disable-next-line jsdoc/require-description /** + * Converts this instance to a JSON compatible object. * @returns {Object} a JSON compatible object. */ toJSON() { @@ -213,8 +215,8 @@ class OverrideTester { }; } - // eslint-disable-next-line jsdoc/require-description /** + * Custom inspect method for Node.js `console.log()`. * @returns {Object} an object to display by `console.log()`. */ [util.inspect.custom]() { diff --git a/lib/flat-compat.js b/lib/flat-compat.js index 6c307a99..caaca204 100644 --- a/lib/flat-compat.js +++ b/lib/flat-compat.js @@ -8,7 +8,7 @@ //----------------------------------------------------------------------------- import createDebug from "debug"; -import path from "path"; +import path from "node:path"; import environments from "../conf/environments.js"; import { ConfigArrayFactory } from "./config-array-factory.js"; @@ -37,6 +37,7 @@ const cafactory = Symbol("cafactory"); * @param {ReadOnlyMap} options.pluginProcessors A map of plugin processor * names to objects. * @returns {Object} A flag-config-style config object. + * @throws {Error} If a plugin or environment cannot be resolved. */ function translateESLintRC(eslintrcConfig, { resolveConfigRelativeTo, @@ -219,7 +220,7 @@ class FlatCompat { this[cafactory] = new ConfigArrayFactory({ cwd: baseDirectory, resolvePluginsRelativeTo, - getEslintAllConfig: () => { + getEslintAllConfig() { if (!allConfig) { throw new TypeError("Missing parameter 'allConfig' in FlatCompat constructor."); @@ -227,7 +228,7 @@ class FlatCompat { return allConfig; }, - getEslintRecommendedConfig: () => { + getEslintRecommendedConfig() { if (!recommendedConfig) { throw new TypeError("Missing parameter 'recommendedConfig' in FlatCompat constructor."); diff --git a/lib/shared/ajv.js b/lib/shared/ajv.js index b79ad36c..7e53d12a 100644 --- a/lib/shared/ajv.js +++ b/lib/shared/ajv.js @@ -184,7 +184,7 @@ export default (additionalOptions = {}) => { }); ajv.addMetaSchema(metaSchema); - // eslint-disable-next-line no-underscore-dangle + // eslint-disable-next-line no-underscore-dangle -- part of the API ajv._opts.defaultMeta = metaSchema.id; return ajv; diff --git a/lib/shared/config-ops.js b/lib/shared/config-ops.js index d203be0e..465d9b86 100644 --- a/lib/shared/config-ops.js +++ b/lib/shared/config-ops.js @@ -13,7 +13,7 @@ const RULE_SEVERITY_STRINGS = ["off", "warn", "error"], map[value] = index; return map; }, {}), - VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"]; + VALID_SEVERITIES = new Set([0, 1, 2, "off", "warn", "error"]); //------------------------------------------------------------------------------ // Public Interface @@ -83,7 +83,7 @@ function isValidSeverity(ruleConfig) { if (typeof severity === "string") { severity = severity.toLowerCase(); } - return VALID_SEVERITIES.indexOf(severity) !== -1; + return VALID_SEVERITIES.has(severity); } /** diff --git a/lib/shared/config-validator.js b/lib/shared/config-validator.js index 0829bf9d..fb96842f 100644 --- a/lib/shared/config-validator.js +++ b/lib/shared/config-validator.js @@ -3,7 +3,7 @@ * @author Brandon Mills */ -/* eslint class-methods-use-this: "off" */ +/* eslint class-methods-use-this: "off" -- not needed in this file */ //------------------------------------------------------------------------------ // Typedefs @@ -15,7 +15,7 @@ // Requirements //------------------------------------------------------------------------------ -import util from "util"; +import util from "node:util"; import * as ConfigOps from "./config-ops.js"; import { emitDeprecationWarning } from "./deprecation-warnings.js"; import ajvOrig from "./ajv.js"; @@ -51,6 +51,9 @@ const noOptionsSchema = Object.freeze({ // Exports //----------------------------------------------------------------------------- +/** + * + */ export default class ConfigValidator { constructor({ builtInRules = new Map() } = {}) { this.builtInRules = builtInRules; @@ -110,6 +113,7 @@ export default class ConfigValidator { * Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid. * @param {options} options The given options for the rule. * @returns {number|string} The rule's severity value + * @throws {Error} If the severity is invalid. */ validateRuleSeverity(options) { const severity = Array.isArray(options) ? options[0] : options; @@ -128,6 +132,7 @@ export default class ConfigValidator { * @param {{create: Function}} rule The rule to validate * @param {Array} localOptions The options for the rule, excluding severity * @returns {void} + * @throws {Error} If the options are invalid. */ validateRuleSchema(rule, localOptions) { if (!ruleValidators.has(rule)) { @@ -169,6 +174,7 @@ export default class ConfigValidator { * @param {string|null} source The name of the configuration source to report in any errors. If null or undefined, * no source is prepended to the message. * @returns {void} + * @throws {Error} If the options are invalid. */ validateRuleOptions(rule, ruleId, options, source = null) { try { @@ -200,8 +206,9 @@ export default class ConfigValidator { * Validates an environment object * @param {Object} environment The environment config object to validate. * @param {string} source The name of the configuration source to report in any errors. - * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded environments. + * @param {(envId:string) => Object} [getAdditionalEnv] A map from strings to loaded environments. * @returns {void} + * @throws {Error} If the environment is invalid. */ validateEnvironment( environment, @@ -229,7 +236,7 @@ export default class ConfigValidator { * Validates a rules config object * @param {Object} rulesConfig The rules config object to validate. * @param {string} source The name of the configuration source to report in any errors. - * @param {function(ruleId:string): Object} getAdditionalRule A map from strings to loaded rules + * @param {(ruleId:string) => Object} getAdditionalRule A map from strings to loaded rules * @returns {void} */ validateRules( @@ -273,8 +280,9 @@ export default class ConfigValidator { * Validate `processor` configuration. * @param {string|undefined} processorName The processor name. * @param {string} source The name of config file. - * @param {function(id:string): Processor} getProcessor The getter of defined processors. + * @param {(id:string) => Processor} getProcessor The getter of defined processors. * @returns {void} + * @throws {Error} If the processor is invalid. */ validateProcessor(processorName, source, getProcessor) { if (processorName && !getProcessor(processorName)) { @@ -313,6 +321,7 @@ export default class ConfigValidator { * @param {Object} config The config object to validate. * @param {string} source The name of the configuration source to report in any errors. * @returns {void} + * @throws {Error} If the config is invalid. */ validateConfigSchema(config, source = null) { validateSchema = validateSchema || ajv.compile(configSchema); @@ -321,7 +330,7 @@ export default class ConfigValidator { throw new Error(`ESLint configuration in ${source} is invalid:\n${this.formatErrors(validateSchema.errors)}`); } - if (Object.hasOwnProperty.call(config, "ecmaFeatures")) { + if (Object.hasOwn(config, "ecmaFeatures")) { emitDeprecationWarning(source, "ESLINT_LEGACY_ECMAFEATURES"); } } @@ -330,8 +339,8 @@ export default class ConfigValidator { * Validates an entire config object. * @param {Object} config The config object to validate. * @param {string} source The name of the configuration source to report in any errors. - * @param {function(ruleId:string): Object} [getAdditionalRule] A map from strings to loaded rules. - * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded envs. + * @param {(ruleId:string) => Object} [getAdditionalRule] A map from strings to loaded rules. + * @param {(envId:string) => Object} [getAdditionalEnv] A map from strings to loaded envs. * @returns {void} */ validate(config, source, getAdditionalRule, getAdditionalEnv) { diff --git a/lib/shared/deprecation-warnings.js b/lib/shared/deprecation-warnings.js index 91907b13..39cfe2c6 100644 --- a/lib/shared/deprecation-warnings.js +++ b/lib/shared/deprecation-warnings.js @@ -7,7 +7,7 @@ // Requirements //------------------------------------------------------------------------------ -import path from "path"; +import path from "node:path"; //------------------------------------------------------------------------------ // Private diff --git a/lib/shared/relative-module-resolver.js b/lib/shared/relative-module-resolver.js index 1df0ca80..81415b42 100644 --- a/lib/shared/relative-module-resolver.js +++ b/lib/shared/relative-module-resolver.js @@ -3,7 +3,7 @@ * @author Teddy Katz */ -import Module from "module"; +import Module from "node:module"; /* * `Module.createRequire` is added in v12.2.0. It supports URL as well. @@ -17,6 +17,7 @@ const createRequire = Module.createRequire; * @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be * a file rather than a directory, but the file need not actually exist. * @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath` + * @throws {Error} When the module cannot be resolved. */ function resolve(moduleName, relativeToPath) { try { diff --git a/package.json b/package.json index dac77b45..69d57830 100644 --- a/package.json +++ b/package.json @@ -53,17 +53,16 @@ "devDependencies": { "c8": "^7.7.3", "chai": "^4.3.4", - "eslint": "^7.31.0", - "eslint-config-eslint": "^7.0.0", - "eslint-plugin-jsdoc": "^35.4.1", - "eslint-plugin-node": "^11.1.0", + "eslint": "^9.20.1", + "eslint-config-eslint": "^11.0.0", "eslint-release": "^3.2.0", "fs-teardown": "^0.1.3", "mocha": "^9.0.3", "rollup": "^2.70.1", "shelljs": "^0.8.5", "sinon": "^11.1.2", - "temp-dir": "^2.0.0" + "temp-dir": "^2.0.0", + "typescript": "^5.7.3" }, "dependencies": { "ajv": "^6.12.4", diff --git a/tests/lib/cascading-config-array-factory.js b/tests/lib/cascading-config-array-factory.js index 7250f9a8..7567e423 100644 --- a/tests/lib/cascading-config-array-factory.js +++ b/tests/lib/cascading-config-array-factory.js @@ -8,14 +8,14 @@ //----------------------------------------------------------------------------- import { assert } from "chai"; -import fs from "fs"; -import { createRequire } from "module"; -import os from "os"; -import path from "path"; +import fs from "node:fs"; +import { createRequire } from "node:module"; +import os from "node:os"; +import path from "node:path"; import sh from "shelljs"; import sinon from "sinon"; import systemTempDir from "temp-dir"; -import { fileURLToPath } from "url"; +import { fileURLToPath } from "node:url"; import { Legacy } from "../../lib/index.js"; import { createCustomTeardown } from "../_utils/index.js"; @@ -557,7 +557,8 @@ describe("CascadingConfigArrayFactory", () => { // key is path, value is file content (string) const flattened = {}; - /** Recursively joins path segments and populates `flattened` object + /** + * Recursively joins path segments and populates `flattened` object * @param {Object} object key is path segment, value is file content (string) or another object of the same kind * @param {string} prefix parent directory * @returns {void} @@ -654,7 +655,7 @@ describe("CascadingConfigArrayFactory", () => { * exceeds the default test timeout, so raise it just for this hook. * Mocha uses `this` to set timeouts on an individual hook level. */ - this.timeout(60 * 1000); // eslint-disable-line no-invalid-this + this.timeout(60 * 1000); // eslint-disable-line no-invalid-this -- needed for test fixtureDir = `${systemTempDir}/eslint/fixtures`; sh.mkdir("-p", fixtureDir); @@ -696,7 +697,7 @@ describe("CascadingConfigArrayFactory", () => { }); // TODO: Tests should not rely on project files!!! - it("should return the project config when called in current working directory", () => { + it.skip("should return the project config when called in current working directory", () => { const factory = new CascadingConfigArrayFactory({ eslintAllPath, eslintRecommendedPath @@ -1882,7 +1883,7 @@ describe("CascadingConfigArrayFactory", () => { * exceeds the default test timeout, so raise it just for this hook. * Mocha uses `this` to set timeouts on an individual hook level. */ - this.timeout(60 * 1000); // eslint-disable-line no-invalid-this + this.timeout(60 * 1000); // eslint-disable-line no-invalid-this -- needed for test fixtureDir = `${systemTempDir}/eslint/fixtures`; sh.mkdir("-p", fixtureDir); @@ -1924,7 +1925,7 @@ describe("CascadingConfigArrayFactory", () => { }); // TODO: Tests should not rely on project files!!! - it("should return the project config when called in current working directory", () => { + it.skip("should return the project config when called in current working directory", () => { const factory = new CascadingConfigArrayFactory({ getEslintAllConfig, getEslintRecommendedConfig diff --git a/tests/lib/commonjs.cjs b/tests/lib/commonjs.cjs index a6840cde..3d17a017 100644 --- a/tests/lib/commonjs.cjs +++ b/tests/lib/commonjs.cjs @@ -9,10 +9,10 @@ // Requirements //------------------------------------------------------------------------------ -const assert = require("assert"); +const assert = require("node:assert"); const eslintrc = require("../../dist/eslintrc.cjs"); const universal = require("../../dist/eslintrc-universal.cjs"); -const path = require("path"); +const path = require("node:path"); const sh = require("shelljs"); //------------------------------------------------------------------------------ diff --git a/tests/lib/config-array-factory.js b/tests/lib/config-array-factory.js index a92443f6..4951770e 100644 --- a/tests/lib/config-array-factory.js +++ b/tests/lib/config-array-factory.js @@ -8,12 +8,12 @@ //----------------------------------------------------------------------------- import { assert } from "chai"; -import fs from "fs"; -import { createRequire } from "module"; -import path from "path"; +import fs from "node:fs"; +import { createRequire } from "node:module"; +import path from "node:path"; import sinon from "sinon"; import systemTempDir from "temp-dir"; -import { fileURLToPath } from "url"; +import { fileURLToPath } from "node:url"; import { Legacy } from "../../lib/index.js"; import { createCustomTeardown } from "../_utils/index.js"; @@ -173,7 +173,7 @@ describe("ConfigArrayFactory", () => { it("should return a config array that contains the yielded elements from '_normalizeConfigData(configData, ctx)'.", () => { const elements = [{}, {}]; - factory._normalizeConfigData = () => elements; // eslint-disable-line no-underscore-dangle + factory._normalizeConfigData = () => elements; // eslint-disable-line no-underscore-dangle -- needed for test const configArray = factory.create({}); @@ -237,7 +237,7 @@ describe("ConfigArrayFactory", () => { }); for (const filePath of Object.keys(basicFiles)) { - it(`should load '${filePath}' then return a config array what contains that file content.`, () => { // eslint-disable-line no-loop-func + it(`should load '${filePath}' then return a config array what contains that file content.`, () => { // eslint-disable-line no-loop-func -- needed for test const configArray = factory.loadFile(filePath); assert.strictEqual(configArray.length, 1); @@ -267,7 +267,7 @@ describe("ConfigArrayFactory", () => { it("should return a config array that contains the yielded elements from '_normalizeConfigData(configData, ctx)'.", () => { const elements = [{}, {}]; - factory._normalizeConfigData = () => elements; // eslint-disable-line no-underscore-dangle + factory._normalizeConfigData = () => elements; // eslint-disable-line no-underscore-dangle -- needed for test const configArray = factory.loadFile("js/.eslintrc.js"); @@ -335,7 +335,7 @@ describe("ConfigArrayFactory", () => { for (const filePath of Object.keys(basicFiles)) { const directoryPath = filePath.split("/")[0]; - it(`should load '${directoryPath}' then return a config array what contains the config file of that directory.`, () => { // eslint-disable-line no-loop-func + it(`should load '${directoryPath}' then return a config array what contains the config file of that directory.`, () => { // eslint-disable-line no-loop-func -- needed for test const configArray = factory.loadInDirectory(directoryPath); assert.strictEqual(configArray.length, 1); @@ -365,7 +365,7 @@ describe("ConfigArrayFactory", () => { it("should return a config array that contains the yielded elements from '_normalizeConfigData(configData, ctx)'.", () => { const elements = [{}, {}]; - factory._normalizeConfigData = () => elements; // eslint-disable-line no-underscore-dangle + factory._normalizeConfigData = () => elements; // eslint-disable-line no-underscore-dangle -- needed for test const configArray = factory.loadInDirectory("js"); @@ -395,7 +395,7 @@ describe("ConfigArrayFactory", () => { function create(configData, { filePath, name } = {}) { const ctx = createContext({ cwd: tempDir }, void 0, name, filePath, void 0); - return new ConfigArray(...factory._normalizeConfigData(configData, ctx)); // eslint-disable-line no-underscore-dangle + return new ConfigArray(...factory._normalizeConfigData(configData, ctx)); // eslint-disable-line no-underscore-dangle -- needed for test } describe("misc", () => { diff --git a/tests/lib/config-array/config-array.js b/tests/lib/config-array/config-array.js index d0808ee8..2883671e 100644 --- a/tests/lib/config-array/config-array.js +++ b/tests/lib/config-array/config-array.js @@ -3,8 +3,8 @@ * @author Toru Nagashima */ -import path from "path"; -import { fileURLToPath } from "url"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; import { assert } from "chai"; import { ConfigArray, OverrideTester, getUsedExtractedConfigs } from "../../../lib/config-array/index.js"; @@ -37,7 +37,7 @@ describe("ConfigArray", () => { }); for (let i = 0; i < elements.length; ++i) { - it(`should have ${JSON.stringify(elements[i])} at configArray[${i}].`, () => { // eslint-disable-line no-loop-func + it(`should have ${JSON.stringify(elements[i])} at configArray[${i}].`, () => { // eslint-disable-line no-loop-func -- needed for test assert.strictEqual(configArray[i], elements[i]); }); } @@ -702,7 +702,7 @@ describe("ConfigArray", () => { { filePaths: [filename, `${filename}.ts`] }, { filePaths: [filename, `${filename}.ts`, path.join(dirname, "foo.js")] } ]) { - describe(`after it called 'extractConfig(filePath)' ${filePaths.length} time(s) with ${JSON.stringify(filePaths, null, 4)}, the returned array`, () => { // eslint-disable-line no-loop-func + describe(`after it called 'extractConfig(filePath)' ${filePaths.length} time(s) with ${JSON.stringify(filePaths, null, 4)}, the returned array`, () => { // eslint-disable-line no-loop-func -- needed for test let configs; let usedConfigs; @@ -716,7 +716,7 @@ describe("ConfigArray", () => { }); for (let i = 0; i < filePaths.length; ++i) { - it(`should contain 'configs[${i}]'.`, () => { // eslint-disable-line no-loop-func + it(`should contain 'configs[${i}]'.`, () => { // eslint-disable-line no-loop-func -- needed for test assert(usedConfigs.includes(configs[i])); }); } diff --git a/tests/lib/config-array/config-dependency.js b/tests/lib/config-array/config-dependency.js index 3087b8ca..ddb04b88 100644 --- a/tests/lib/config-array/config-dependency.js +++ b/tests/lib/config-array/config-dependency.js @@ -3,9 +3,9 @@ * @author Toru Nagashima */ -import assert from "assert"; -import { Console } from "console"; -import { Writable } from "stream"; +import assert from "node:assert"; +import { Console } from "node:console"; +import { Writable } from "node:stream"; import { ConfigDependency } from "../../../lib/config-array/config-dependency.js"; describe("ConfigDependency", () => { @@ -80,7 +80,7 @@ describe("ConfigDependency", () => { let output = ""; const localConsole = new Console( new class extends Writable { - write(chunk) { // eslint-disable-line class-methods-use-this + write(chunk) { // eslint-disable-line class-methods-use-this -- needed for test output += chunk; } }() diff --git a/tests/lib/config-array/extracted-config.js b/tests/lib/config-array/extracted-config.js index cf2a8c71..52d8c4a9 100644 --- a/tests/lib/config-array/extracted-config.js +++ b/tests/lib/config-array/extracted-config.js @@ -3,7 +3,7 @@ * @author Toru Nagashima */ -import assert from "assert"; +import assert from "node:assert"; import { ExtractedConfig } from "../../../lib/config-array/extracted-config.js"; describe("'ExtractedConfig' class", () => { diff --git a/tests/lib/config-array/ignore-pattern.js b/tests/lib/config-array/ignore-pattern.js index 9be97452..10030199 100644 --- a/tests/lib/config-array/ignore-pattern.js +++ b/tests/lib/config-array/ignore-pattern.js @@ -3,8 +3,8 @@ * @author Toru Nagashima */ -import assert from "assert"; -import path from "path"; +import assert from "node:assert"; +import path from "node:path"; import sinon from "sinon"; import { IgnorePattern } from "../../../lib/config-array/ignore-pattern.js"; diff --git a/tests/lib/config-array/override-tester.js b/tests/lib/config-array/override-tester.js index ba54cfe5..a9837800 100644 --- a/tests/lib/config-array/override-tester.js +++ b/tests/lib/config-array/override-tester.js @@ -3,10 +3,10 @@ * @author Toru Nagashima */ -import assert from "assert"; -import { Console } from "console"; -import path from "path"; -import { Writable } from "stream"; +import assert from "node:assert"; +import { Console } from "node:console"; +import path from "node:path"; +import { Writable } from "node:stream"; import { OverrideTester } from "../../../lib/config-array/override-tester.js"; describe("OverrideTester", () => { diff --git a/tests/lib/flat-compat.js b/tests/lib/flat-compat.js index 6bba95a0..36e7288e 100644 --- a/tests/lib/flat-compat.js +++ b/tests/lib/flat-compat.js @@ -7,12 +7,12 @@ // Requirements //----------------------------------------------------------------------------- -import path from "path"; -import { fileURLToPath, pathToFileURL } from "url"; +import path from "node:path"; +import { fileURLToPath, pathToFileURL } from "node:url"; import { assert } from "chai"; import { FlatCompat } from "../../lib/index.js"; import environments from "../../conf/environments.js"; -import { createRequire } from "module"; +import { createRequire } from "node:module"; const dirname = path.dirname(fileURLToPath(import.meta.url)); const require = createRequire(import.meta.url); diff --git a/tests/lib/shared/config-ops.js b/tests/lib/shared/config-ops.js index 574918e3..cb1a92c4 100644 --- a/tests/lib/shared/config-ops.js +++ b/tests/lib/shared/config-ops.js @@ -9,7 +9,7 @@ import { assert } from "chai"; -import util from "util"; +import util from "node:util"; import * as ConfigOps from "../../../lib/shared/config-ops.js"; diff --git a/tests/lib/shared/config-validator.js b/tests/lib/shared/config-validator.js index fbd92d94..dd2bdcea 100644 --- a/tests/lib/shared/config-validator.js +++ b/tests/lib/shared/config-validator.js @@ -7,7 +7,7 @@ //------------------------------------------------------------------------------ import { assert } from "chai"; -import nodeAssert from "assert"; +import nodeAssert from "node:assert"; import ConfigValidator from "../../../lib/shared/config-validator.js"; diff --git a/tests/lib/shared/relative-module-resolver.js b/tests/lib/shared/relative-module-resolver.js index 92eaa6ed..33c18361 100644 --- a/tests/lib/shared/relative-module-resolver.js +++ b/tests/lib/shared/relative-module-resolver.js @@ -3,7 +3,7 @@ */ import { assert } from "chai"; -import path from "path"; +import path from "node:path"; import { Legacy } from "../../../lib/index.js"; diff --git a/universal.js b/universal.js index 4e1846ee..2257383e 100644 --- a/universal.js +++ b/universal.js @@ -1,3 +1,5 @@ +/* global module, require -- required for CJS file */ + // Jest (and probably some other runtimes with custom implementations of // `require`) doesn't support `exports` in `package.json`, so this file is here // to help them load this module. Note that it is also `.js` and not `.cjs` for @@ -5,5 +7,4 @@ // since Jest doesn't respect `module` outside of ESM mode it still works in // this case (and the `require` in _this_ file does specify the extension). -// eslint-disable-next-line no-undef module.exports = require("./dist/eslintrc-universal.cjs");