Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 23 additions & 34 deletions eslint.config.js
Comment thread
Pixel998 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,43 +1,40 @@
import eslintConfigESLint from "eslint-config-eslint";
import { defineConfig, includeIgnoreFile } from "@eslint/config-helpers";
import globals from "globals";
import {
defineConfig,
globalIgnores,
includeIgnoreFile,
} from "@eslint/config-helpers";
import tseslint from "typescript-eslint";
import { fileURLToPath } from "node:url";
import path from "node:path";

const eslintPluginJSDoc = eslintConfigESLint.find(
config => config.plugins?.jsdoc,
).plugins.jsdoc;

const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);

export default defineConfig([
includeIgnoreFile(path.join(dirname, ".gitignore"), {
gitignoreResolution: true,
}),

{
ignores: ["**/tests/fixtures/"],
},

globalIgnores(["**/tests/fixtures/"], "rewrite/global-ignores"),
{
name: "rewrite/js",
files: ["**/*.js"],
extends: [eslintConfigESLint],
settings: {
jsdoc: {
preferredTypes: {
object: "object",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
object: "object",
Object: "object",

This seems to be a typo (we want to disallow Object and prefer object).

},
},
},
rules: {
// disable rules we don't want to use from eslint-config-eslint
"no-undefined": "off",

// TODO: re-enable eslint-plugin-jsdoc rules
...Object.fromEntries(
Object.keys(eslintPluginJSDoc.rules).map(name => [
`jsdoc/${name}`,
"off",
]),
),
},
},

// Tools and CLI
{
name: "rewrite/tools",
files: [
"scripts/**",
"tools/**",
Expand All @@ -48,30 +45,22 @@ export default defineConfig([
"n/no-process-exit": "off",
},
},

{
name: "rewrite/tests",
files: ["**/tests/**"],
languageOptions: {
globals: {
describe: "readonly",
xdescribe: "readonly",
it: "readonly",
xit: "readonly",
beforeEach: "readonly",
afterEach: "readonly",
before: "readonly",
after: "readonly",
...globals.mocha,
},
},
},

// TypeScript
...tseslint.config({
{
name: "rewrite/ts",
files: ["**/*.ts"],
ignores: ["**/tests/**/*.ts"],
extends: [...tseslint.configs.strict, ...tseslint.configs.stylistic],
extends: [tseslint.configs.strict, tseslint.configs.stylistic],
rules: {
"no-use-before-define": "off",
},
}),
},
]);
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"c8": "^11.0.0",
"eslint": "^10.0.3",
"eslint-config-eslint": "^14.0.0",
"globals": "^17.7.0",
"knip": "^6.0.0",
"lint-staged": "^16.0.0",
"mocha": "^11.5.0",
Expand Down
5 changes: 5 additions & 0 deletions packages/compat/src/fixup-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ export function fixupRule(ruleDefinition) {
? ruleDefinition
: ruleDefinition.create.bind(ruleDefinition);

/**
* Compatibility rule creator that adds missing methods to context and sourceCode objects.
* @param {object} context The rule context.
* @returns {object} The rule visitor.
*/
function ruleCreate(context) {
const sourceCode = context.sourceCode;

Expand Down
2 changes: 0 additions & 2 deletions packages/compat/src/ignore-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import path from "node:path";
* Converts an ESLint ignore pattern to a minimatch pattern.
* @param {string} pattern The .eslintignore or .gitignore pattern to convert.
* @returns {string} The converted pattern.
*
* @deprecated Use the `convertIgnorePatternToMinimatch()` function exported by
* `@eslint/config-helpers` instead.
*/
Expand Down Expand Up @@ -75,7 +74,6 @@ export function convertIgnorePatternToMinimatch(pattern) {
* @param {string} [name] The name of the ignore file config.
* @returns {FlatConfig} An object with an `ignores` property that is an array of ignore patterns.
* @throws {Error} If the ignore file path is not an absolute path.
*
* @deprecated Use the `includeIgnoreFile()` function exported by
* `@eslint/config-helpers` instead (also available at `eslint/config`).
*/
Expand Down
14 changes: 14 additions & 0 deletions packages/compat/tests/fixup-rules.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import {
} from "../src/fixup-rules.js";
import { Linter } from "eslint";

//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------

/** @typedef {import("@eslint/core").RuleDefinition["create"]} LegacyRuleDefinition */

//-----------------------------------------------------------------------------
// Data
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -170,6 +176,10 @@ describe("@eslint/compat", () => {
});

it("should return a rule object when a function-style rule is passed to fixupRule", () => {
/**
* Legacy function-style rule fixture without metadata.
* @type {LegacyRuleDefinition}
*/
function rule(context) {
return {
Identifier(node) {
Expand Down Expand Up @@ -208,6 +218,10 @@ describe("@eslint/compat", () => {
});

it("should return a rule object with `meta.schema` when a function-style rule with schema is passed to fixupRule", () => {
/**
* Legacy function-style rule fixture with a top-level schema.
* @type {LegacyRuleDefinition}
*/
function rule(context) {
return {
Identifier(node) {
Expand Down
7 changes: 7 additions & 0 deletions packages/config-array/fix-std__path-imports.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@

import { readFile, writeFile } from "node:fs/promises";

/**
* Replaces matches of a pattern in a file with a replacement string.
* @param {string} file The file path to modify.
* @param {RegExp} search The regular expression to match.
* @param {string} replacement The replacement string.
* @returns {Promise<void>} Resolves when the file has been written.
*/
async function replaceInFile(file, search, replacement) {
let text = await readFile(file, "utf-8");
text = text.replace(search, replacement);
Expand Down
24 changes: 19 additions & 5 deletions packages/config-array/src/config-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ function getConfigName(config) {
* @param {ConfigObject} config The config object to get the name of.
* @param {number} index The index of the config object in the array.
* @param {Error} error The error to rethrow.
* @returns {void}
* @throws {ConfigError} When the error is rethrown for a config.
*/
function rethrowConfigError(config, index, error) {
Expand Down Expand Up @@ -270,7 +271,6 @@ function normalizePattern(pattern) {
* Checks if a given pattern requires normalization.
* @param {any} pattern The pattern to check.
* @returns {boolean} True if the pattern needs normalization, false otherwise.
*
*/
function needsPatternNormalization(pattern) {
return (
Expand Down Expand Up @@ -367,6 +367,12 @@ async function normalize(
const allowFunctions = extraConfigTypes.includes("function");
const allowArrays = extraConfigTypes.includes("array");

/**
* Recursively flattens items and resolves config functions into config objects.
* @param {Array} array The array to traverse.
* @returns {AsyncGenerator<Object, void, void>} Async generator yielding config objects.
* @throws {TypeError} If functions or arrays are not allowed, or if a config function returns another function.
*/
async function* flatTraverse(array) {
for (let item of array) {
if (typeof item === "function") {
Expand Down Expand Up @@ -431,6 +437,12 @@ function normalizeSync(
const allowFunctions = extraConfigTypes.includes("function");
const allowArrays = extraConfigTypes.includes("array");

/**
* Recursively flattens items and resolves config functions into config objects.
* @param {Array} array The array to traverse.
* @returns {Generator<Object, void, void>} Generator yielding config objects.
* @throws {TypeError} If functions or arrays are not allowed, if a config function returns another function, or if it returns a promise.
*/
function* flatTraverse(array) {
for (let item of array) {
if (typeof item === "function") {
Expand Down Expand Up @@ -569,6 +581,12 @@ function shouldIgnorePath(
*/
function pathMatches(filePath, relativeFilePath, config) {
// match both strings and functions
/**
* Matches a file matcher against the provided file path.
* @param {FileMatcher} pattern The matcher pattern or function.
* @returns {boolean} True if the string pattern matches `relativeFilePath` or the matcher function returns true for `filePath`, false otherwise.
* @throws {TypeError} If the matcher is not a string or function.
*/
function match(pattern) {
if (isString(pattern)) {
return doMatch(relativeFilePath, pattern);
Expand Down Expand Up @@ -731,15 +749,13 @@ export class ConfigArray extends Array {

/**
* Tracks if the array has been normalized.
* @property isNormalized
* @type {boolean}
* @private
*/
this[ConfigArraySymbol.isNormalized] = normalized;

/**
* The schema used for validating and merging configs.
* @property schema
* @type {ObjectSchemaInstance}
* @private
*/
Expand All @@ -754,7 +770,6 @@ export class ConfigArray extends Array {
/**
* The path of the config file that this array was loaded from.
* This is used to calculate filename matches.
* @property basePath
* @type {string}
*/
this.basePath = basePath;
Expand All @@ -770,7 +785,6 @@ export class ConfigArray extends Array {

/**
* A cache to store calculated configs for faster repeat lookup.
* @property configCache
* @type {Map<string, Object>}
* @private
*/
Expand Down
13 changes: 7 additions & 6 deletions packages/config-array/src/files-and-ignores-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@

/** @typedef {import("@eslint/object-schema").PropertyDefinition} PropertyDefinition */
/** @typedef {import("@eslint/object-schema").ObjectDefinition} ObjectDefinition */
/** @typedef {import("./types.ts").FileMatcher} FileMatcher */

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

/**
* Asserts that a given value is an array.
* @param {*} value The value to check.
* @returns {void}
* @param {unknown} value The value to check.
* @returns {asserts value is unknown[]} Asserts that the value is an array.
* @throws {TypeError} When the value is not an array.
*/
function assertIsArray(value) {
Expand All @@ -28,8 +29,8 @@ function assertIsArray(value) {

/**
* Asserts that a given value is an array containing only strings and functions.
* @param {*} value The value to check.
* @returns {void}
* @param {unknown} value The value to check.
* @returns {asserts value is FileMatcher[]} Asserts that the value is an array of file matchers.
* @throws {TypeError} When the value is not an array of strings and functions.
*/
function assertIsArrayOfStringsAndFunctions(value) {
Expand All @@ -48,8 +49,8 @@ function assertIsArrayOfStringsAndFunctions(value) {

/**
* Asserts that a given value is a non-empty array.
* @param {*} value The value to check.
* @returns {void}
* @param {unknown} value The value to check.
* @returns {asserts value is unknown[]} Asserts that the value is a non-empty array.
* @throws {TypeError} When the value is not an array or an empty array.
*/
function assertIsNonEmptyArray(value) {
Expand Down
14 changes: 14 additions & 0 deletions packages/config-array/tests/config-array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ const CSSLanguage = class {};
const MarkdownLanguage = class {};
const JSONLanguage = class {};

/**
* Creates a `ConfigArray` pre-populated with test fixtures.
* @param {Object} [options] Options to merge with the default `ConfigArray` constructor options.
* @returns {ConfigArray} The created instance.
*/
function createConfigArray(options) {
return new ConfigArray(
[
Expand Down Expand Up @@ -298,6 +303,15 @@ describe("ConfigArray", () => {
});

describe("Validation", () => {
/**
* Defines tests that assert validation errors in both async and sync normalize flows.
* @param {Object} options Test options.
* @param {boolean} [options.only=false] If true, run these tests exclusively.
* @param {string} options.title Test title prefix.
* @param {Iterable|Function|Object} options.configs Configs to pass to the `ConfigArray` constructor.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param {Iterable|Function|Object} options.configs Configs to pass to the `ConfigArray` constructor.
* @param {Iterable<Function|Object>|Function|Object} options.configs Configs to pass to the `ConfigArray` constructor.

The Iterable type should have type arguments.

* @param {assert.AssertPredicate} options.expectedError Expected error matcher for `assert.rejects()` and `assert.throws()`.
* @returns {void}
*/
function testValidationError({
only = false,
title,
Expand Down
Loading
Loading