From 8df4bf4948ebef417e723d7e678573b6eaeb01a2 Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Mon, 25 Nov 2024 14:17:38 -0500 Subject: [PATCH 1/5] fix: Update RuleVisitor type fixes #134 --- packages/core/src/types.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 3fc3e19..38663b0 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -92,20 +92,19 @@ export type RuleType = "problem" | "suggestion" | "layout"; */ export type RuleFixType = "code" | "whitespace"; -/* eslint-disable @typescript-eslint/consistent-indexed-object-style -- Needs to be interface so people can extend it. */ /* eslint-disable @typescript-eslint/no-explicit-any -- Necessary to allow subclasses to work correctly */ /** * An object containing visitor information for a rule. Each method is either the * name of a node type or a selector, or is a method that will be called at specific * times during the traversal. */ -export interface RuleVisitor { +export type RuleVisitor = { /** * Called for each node in the AST or at specific times during the traversal. */ - [key: string]: (...args: any[]) => void; -} -/* eslint-enable @typescript-eslint/consistent-indexed-object-style -- Needs to be interface so people can extend it. */ + [key in string]?: (...args: any[]) => void; +}; + /* eslint-enable @typescript-eslint/no-explicit-any -- Necessary to allow subclasses to work correctly */ /** From be98ba55274731629a7f2d311696107e2005c67d Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Mon, 25 Nov 2024 16:26:12 -0500 Subject: [PATCH 2/5] Switch to record --- packages/core/src/types.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 38663b0..112844f 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -98,12 +98,7 @@ export type RuleFixType = "code" | "whitespace"; * name of a node type or a selector, or is a method that will be called at specific * times during the traversal. */ -export type RuleVisitor = { - /** - * Called for each node in the AST or at specific times during the traversal. - */ - [key in string]?: (...args: any[]) => void; -}; +export type RuleVisitor = Record void>; /* eslint-enable @typescript-eslint/no-explicit-any -- Necessary to allow subclasses to work correctly */ From 2d6fd9c3321ce49b30442508ca2f14a6aed048a9 Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Tue, 26 Nov 2024 10:36:32 -0500 Subject: [PATCH 3/5] Update packages/core/src/types.ts Co-authored-by: Francesco Trotta --- packages/core/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 112844f..fef7437 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -98,7 +98,7 @@ export type RuleFixType = "code" | "whitespace"; * name of a node type or a selector, or is a method that will be called at specific * times during the traversal. */ -export type RuleVisitor = Record void>; +export type RuleVisitor = Record void) | undefined>; /* eslint-enable @typescript-eslint/no-explicit-any -- Necessary to allow subclasses to work correctly */ From d49741fbb3712f73ce026c59f9fc922db53c736a Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Tue, 26 Nov 2024 16:51:03 -0500 Subject: [PATCH 4/5] Update packages/core/src/types.ts Co-authored-by: Francesco Trotta --- packages/core/src/types.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index fef7437..93b66f9 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -98,7 +98,10 @@ export type RuleFixType = "code" | "whitespace"; * name of a node type or a selector, or is a method that will be called at specific * times during the traversal. */ -export type RuleVisitor = Record void) | undefined>; +export type RuleVisitor = Record< + string, + ((...args: any[]) => void) | undefined +>; /* eslint-enable @typescript-eslint/no-explicit-any -- Necessary to allow subclasses to work correctly */ From 3554ecc84f5baed36f7b00360a29a8bd9511a6cd Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Wed, 27 Nov 2024 10:44:07 -0500 Subject: [PATCH 5/5] Formatting fix --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- README.md | 10 ++++----- decisions/001-rewrite-core.md | 2 +- decisions/004-types.md | 10 ++++----- package.json | 2 +- packages/compat/README.md | 8 ++++---- packages/config-array/README.md | 34 +++++++++++++++---------------- packages/migrate-config/README.md | 6 +++--- packages/object-schema/README.md | 20 +++++++++--------- packages/plugin-kit/README.md | 28 ++++++++++++------------- 10 files changed, 61 insertions(+), 61 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1f44735..533ec11 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,7 +6,7 @@ #### Prerequisites checklist -- [ ] I have read the [contributing guidelines](https://github.com/eslint/eslint/blob/HEAD/CONTRIBUTING.md). +- [ ] I have read the [contributing guidelines](https://github.com/eslint/eslint/blob/HEAD/CONTRIBUTING.md). diff --git a/decisions/001-rewrite-core.md b/decisions/001-rewrite-core.md index e41a48a..64a0541 100644 --- a/decisions/001-rewrite-core.md +++ b/decisions/001-rewrite-core.md @@ -25,4 +25,4 @@ When the new core is ready, we will need to be careful about the migration plan ## See Also -- +- diff --git a/decisions/004-types.md b/decisions/004-types.md index effaf1f..e8dcac2 100644 --- a/decisions/004-types.md +++ b/decisions/004-types.md @@ -26,13 +26,13 @@ We do not intend to take over full maintenance of `@types/eslint`. Instead, we w For the ESLint team, this decision will: -- Ensure we have control over our type definitions. -- Allow us to design a more coherent and well-integrated type system in the new `@eslint/core`. -- Provide a clear path for integrating these types with `@types/eslint`, improving consistency across the ecosystem. +- Ensure we have control over our type definitions. +- Allow us to design a more coherent and well-integrated type system in the new `@eslint/core`. +- Provide a clear path for integrating these types with `@types/eslint`, improving consistency across the ecosystem. For the community, this decision may: -- Require adjustments to adapt to the new type definitions in `@eslint/core`. -- Improve the accuracy and reliability of type definitions used in ESLint-related projects. +- Require adjustments to adapt to the new type definitions in `@eslint/core`. +- Improve the accuracy and reliability of type definitions used in ESLint-related projects. We recognize that this may frustrate or anger some contributors, but we believe that this approach balances the need for accurate type definitions with the practicalities of maintaining a complex project like ESLint. diff --git a/package.json b/package.json index 3b17f7e..687926a 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "eslint-config-eslint": "^11.0.0", "got": "^14.4.1", "lint-staged": "^15.2.0", - "prettier": "^3.1.1", + "prettier": "^3.4.1", "typescript": "^5.5.3", "typescript-eslint": "^8.0.0", "yorkie": "^2.0.0" diff --git a/packages/compat/README.md b/packages/compat/README.md index 870e961..cb1c3d8 100644 --- a/packages/compat/README.md +++ b/packages/compat/README.md @@ -30,10 +30,10 @@ deno add @eslint/compat This package exports the following functions in both ESM and CommonJS format: -- `fixupRule(rule)` - wraps the given rule in a compatibility layer and returns the result -- `fixupPluginRules(plugin)` - wraps each rule in the given plugin using `fixupRule()` and returns a new object that represents the plugin with the fixed-up rules -- `fixupConfigRules(configs)` - wraps all plugins found in an array of config objects using `fixupPluginRules()` -- `includeIgnoreFile(path)` - reads an ignore file (like `.gitignore`) and converts the patterns into the correct format for the config file +- `fixupRule(rule)` - wraps the given rule in a compatibility layer and returns the result +- `fixupPluginRules(plugin)` - wraps each rule in the given plugin using `fixupRule()` and returns a new object that represents the plugin with the fixed-up rules +- `fixupConfigRules(configs)` - wraps all plugins found in an array of config objects using `fixupPluginRules()` +- `includeIgnoreFile(path)` - reads an ignore file (like `.gitignore`) and converts the patterns into the correct format for the config file ### Fixing Rules diff --git a/packages/config-array/README.md b/packages/config-array/README.md index eb2c121..31e4a37 100644 --- a/packages/config-array/README.md +++ b/packages/config-array/README.md @@ -283,10 +283,10 @@ The config array always returns an object, even if there are no configs matching A few things to keep in mind: -- If a filename is not an absolute path, it will be resolved relative to the base path directory. -- The returned config object never has `files`, `ignores`, or `name` properties; the only properties on the object will be the other configuration options specified. -- The config array caches configs, so subsequent calls to `getConfig()` with the same filename will return in a fast lookup rather than another calculation. -- A config will only be generated if the filename matches an entry in a `files` key. A config will not be generated without matching a `files` key (configs without a `files` key are only applied when another config with a `files` key is applied; configs without `files` are never applied on their own). Any config with a `files` key entry that is `*` or ends with `/**` or `/*` will only be applied if another entry in the same `files` key matches or another config matches. +- If a filename is not an absolute path, it will be resolved relative to the base path directory. +- The returned config object never has `files`, `ignores`, or `name` properties; the only properties on the object will be the other configuration options specified. +- The config array caches configs, so subsequent calls to `getConfig()` with the same filename will return in a fast lookup rather than another calculation. +- A config will only be generated if the filename matches an entry in a `files` key. A config will not be generated without matching a `files` key (configs without a `files` key are only applied when another config with a `files` key is applied; configs without `files` are never applied on their own). Any config with a `files` key entry that is `*` or ends with `/**` or `/*` will only be applied if another entry in the same `files` key matches or another config matches. ## Determining Ignored Paths @@ -298,11 +298,11 @@ const ignored = configs.isFileIgnored("/foo/bar/baz.txt"); A file is considered ignored if any of the following is true: -- **It's parent directory is ignored.** For example, if `foo` is in `ignores`, then `foo/a.js` is considered ignored. -- **It has an ancestor directory that is ignored.** For example, if `foo` is in `ignores`, then `foo/baz/a.js` is considered ignored. -- **It matches an ignored file pattern.** For example, if `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored. -- **If it matches an entry in `files` and also in `ignores`.** For example, if `**/*.js` is in `files` and `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored. -- **The file is outside the `basePath`.** If the `basePath` is `/usr/me`, then `/foo/a.js` is considered ignored. +- **It's parent directory is ignored.** For example, if `foo` is in `ignores`, then `foo/a.js` is considered ignored. +- **It has an ancestor directory that is ignored.** For example, if `foo` is in `ignores`, then `foo/baz/a.js` is considered ignored. +- **It matches an ignored file pattern.** For example, if `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored. +- **If it matches an entry in `files` and also in `ignores`.** For example, if `**/*.js` is in `files` and `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored. +- **The file is outside the `basePath`.** If the `basePath` is `/usr/me`, then `/foo/a.js` is considered ignored. For directories, use the `isDirectoryIgnored()` method and pass in the path of any directory, as in this example: @@ -312,11 +312,11 @@ const ignored = configs.isDirectoryIgnored("/foo/bar/"); A directory is considered ignored if any of the following is true: -- **It's parent directory is ignored.** For example, if `foo` is in `ignores`, then `foo/baz` is considered ignored. -- **It has an ancestor directory that is ignored.** For example, if `foo` is in `ignores`, then `foo/bar/baz/a.js` is considered ignored. -- **It matches and ignored file pattern.** For example, if `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored. -- **If it matches an entry in `files` and also in `ignores`.** For example, if `**/*.js` is in `files` and `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored. -- **The file is outside the `basePath`.** If the `basePath` is `/usr/me`, then `/foo/a.js` is considered ignored. +- **It's parent directory is ignored.** For example, if `foo` is in `ignores`, then `foo/baz` is considered ignored. +- **It has an ancestor directory that is ignored.** For example, if `foo` is in `ignores`, then `foo/bar/baz/a.js` is considered ignored. +- **It matches and ignored file pattern.** For example, if `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored. +- **If it matches an entry in `files` and also in `ignores`.** For example, if `**/*.js` is in `files` and `**/a.js` is in `ignores`, then `foo/a.js` and `foo/baz/a.js` are considered ignored. +- **The file is outside the `basePath`.** If the `basePath` is `/usr/me`, then `/foo/a.js` is considered ignored. **Important:** A pattern such as `foo/**` means that `foo` and `foo/` are _not_ ignored whereas `foo/bar` is ignored. If you want to ignore `foo` and all of its subdirectories, use the pattern `foo` or `foo/` in `ignores`. @@ -331,9 +331,9 @@ Each `ConfigArray` aggressively caches configuration objects to avoid unnecessar The design of this project was influenced by feedback on the ESLint RFC, and incorporates ideas from: -- Teddy Katz (@not-an-aardvark) -- Toru Nagashima (@mysticatea) -- Kai Cataldo (@kaicataldo) +- Teddy Katz (@not-an-aardvark) +- Toru Nagashima (@mysticatea) +- Kai Cataldo (@kaicataldo) ## License diff --git a/packages/migrate-config/README.md b/packages/migrate-config/README.md index 94a3855..d9b230e 100644 --- a/packages/migrate-config/README.md +++ b/packages/migrate-config/README.md @@ -10,9 +10,9 @@ This package aids in the migration of the legacy ESLint configuration file forma This tool currently works well for the following config file formats: -- `.eslintrc` -- `.eslintrc.json` -- `.eslintrc.yml` +- `.eslintrc` +- `.eslintrc.json` +- `.eslintrc.yml` If you are using a JavaScript configuration file (`.eslintrc.js`, `.eslintrc.cjs`, `.eslintrc.mjs`), this tool currently is only capable of migrating the _evaluated_ configuration. That means any logic you may have inside of the file will be lost. If your configuration file is mostly static, then you'll get a good result; if your configuration file is more complex (using functions, calculating paths, etc.) then this tool will not provide an equivalent configuration file. diff --git a/packages/object-schema/README.md b/packages/object-schema/README.md index d8e3295..b8f2d03 100644 --- a/packages/object-schema/README.md +++ b/packages/object-schema/README.md @@ -94,9 +94,9 @@ const result = { Instead of specifying a `merge()` method, you can specify one of the following strings to use a default merge strategy: -- `"assign"` - use `Object.assign()` to merge the two values into one object. -- `"overwrite"` - the second value always replaces the first. -- `"replace"` - the second value replaces the first if the second is not `undefined`. +- `"assign"` - use `Object.assign()` to merge the two values into one object. +- `"overwrite"` - the second value always replaces the first. +- `"replace"` - the second value replaces the first if the second is not `undefined`. For example: @@ -113,13 +113,13 @@ const schema = new ObjectSchema({ Instead of specifying a `validate()` method, you can specify one of the following strings to use a default validation strategy: -- `"array"` - value must be an array. -- `"boolean"` - value must be a boolean. -- `"number"` - value must be a number. -- `"object"` - value must be an object. -- `"object?"` - value must be an object or null. -- `"string"` - value must be a string. -- `"string!"` - value must be a non-empty string. +- `"array"` - value must be an array. +- `"boolean"` - value must be a boolean. +- `"number"` - value must be a number. +- `"object"` - value must be an object. +- `"object?"` - value must be an object or null. +- `"string"` - value must be a string. +- `"string!"` - value must be a non-empty string. For example: diff --git a/packages/plugin-kit/README.md b/packages/plugin-kit/README.md index bd77edc..4a57637 100644 --- a/packages/plugin-kit/README.md +++ b/packages/plugin-kit/README.md @@ -28,10 +28,10 @@ deno add @eslint/plugin-kit This package exports the following utilities: -- `ConfigCommentParser` - used to parse ESLint configuration comments (i.e., `/* eslint-disable rule */`) -- `VisitNodeStep` and `CallMethodStep` - used to help implement `SourceCode#traverse()` -- `Directive` - used to help implement `SourceCode#getDisableDirectives()` -- `TextSourceCodeBase` - base class to help implement the `SourceCode` interface +- `ConfigCommentParser` - used to parse ESLint configuration comments (i.e., `/* eslint-disable rule */`) +- `VisitNodeStep` and `CallMethodStep` - used to help implement `SourceCode#traverse()` +- `Directive` - used to help implement `SourceCode#getDisableDirectives()` +- `TextSourceCodeBase` - base class to help implement the `SourceCode` interface ### `ConfigCommentParser` @@ -85,9 +85,9 @@ The `VisitNodeStep` and `CallMethodStep` classes represent steps in the traversa The `VisitNodeStep` class is the more common of the two, where you are describing a visit to a particular node during the traversal. The constructor accepts three arguments: -- `target` - the node being visited. This is used to determine the method to call inside of a rule. For instance, if the node's type is `Literal` then ESLint will call a method named `Literal()` on the rule (if present). -- `phase` - either 1 for enter or 2 for exit. -- `args` - an array of arguments to pass into the visitor method of a rule. +- `target` - the node being visited. This is used to determine the method to call inside of a rule. For instance, if the node's type is `Literal` then ESLint will call a method named `Literal()` on the rule (if present). +- `phase` - either 1 for enter or 2 for exit. +- `args` - an array of arguments to pass into the visitor method of a rule. For example: @@ -115,8 +115,8 @@ class MySourceCode { The `CallMethodStep` class is less common and is used to tell ESLint to call a specific method on the rule. The constructor accepts two arguments: -- `target` - the name of the method to call, frequently beginning with `"on"` such as `"onCodePathStart"`. -- `args` - an array of arguments to pass to the method. +- `target` - the name of the method to call, frequently beginning with `"on"` such as `"onCodePathStart"`. +- `args` - an array of arguments to pass to the method. For example: @@ -205,11 +205,11 @@ class MySourceCode { The `TextSourceCodeBase` class is intended to be a base class that has several of the common members found in `SourceCode` objects already implemented. Those members are: -- `lines` - an array of text lines that is created automatically when the constructor is called. -- `getLoc(node)` - gets the location of a node. Works for nodes that have the ESLint-style `loc` property and nodes that have the Unist-style [`position` property](https://github.com/syntax-tree/unist?tab=readme-ov-file#position). If you're using an AST with a different location format, you'll still need to implement this method yourself. -- `getRange(node)` - gets the range of a node within the source text. Works for nodes that have the ESLint-style `range` property and nodes that have the Unist-style [`position` property](https://github.com/syntax-tree/unist?tab=readme-ov-file#position). If you're using an AST with a different range format, you'll still need to implement this method yourself. -- `getText(nodeOrToken, charsBefore, charsAfter)` - gets the source text for the given node or token that has range information attached. Optionally, can return additional characters before and after the given node or token. As long as `getRange()` is properly implemented, this method will just work. -- `getAncestors(node)` - returns the ancestry of the node. In order for this to work, you must implement the `getParent()` method yourself. +- `lines` - an array of text lines that is created automatically when the constructor is called. +- `getLoc(node)` - gets the location of a node. Works for nodes that have the ESLint-style `loc` property and nodes that have the Unist-style [`position` property](https://github.com/syntax-tree/unist?tab=readme-ov-file#position). If you're using an AST with a different location format, you'll still need to implement this method yourself. +- `getRange(node)` - gets the range of a node within the source text. Works for nodes that have the ESLint-style `range` property and nodes that have the Unist-style [`position` property](https://github.com/syntax-tree/unist?tab=readme-ov-file#position). If you're using an AST with a different range format, you'll still need to implement this method yourself. +- `getText(nodeOrToken, charsBefore, charsAfter)` - gets the source text for the given node or token that has range information attached. Optionally, can return additional characters before and after the given node or token. As long as `getRange()` is properly implemented, this method will just work. +- `getAncestors(node)` - returns the ancestry of the node. In order for this to work, you must implement the `getParent()` method yourself. Here's an example: