diff --git a/.changeset/angry-lions-learn.md b/.changeset/angry-lions-learn.md new file mode 100644 index 00000000..843dbc15 --- /dev/null +++ b/.changeset/angry-lions-learn.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-import-x": patch +--- + +fix(extensions): always calculate `fix` option diff --git a/docs/rules/extensions.md b/docs/rules/extensions.md index e8386799..414d5e5a 100644 --- a/docs/rules/extensions.md +++ b/docs/rules/extensions.md @@ -4,6 +4,18 @@ +> [!NOTE] +> +> This rule is only fixable when the `fix` option is set to `true` for compatibility, otherwise `suggestions` will be provided instead. +> +> Example: +> +> ```json +> "import-x/extensions": ["error", "never", { "fix": true }] +> ``` +> +> It will change to be automatically fixable in the next major version. + Some file resolve algorithms allow you to omit the file extension within the import source path. For example the `node` resolver (which does not yet support ESM/`import`) can resolve `./foo/bar` to the absolute path `/User/someone/foo/bar.js` because the `.js` extension is resolved automatically by default in CJS. Depending on the resolver you can configure more extensions to get resolved automatically. In order to provide a consistent use of file extensions across your code base, this rule can enforce or disallow the use of certain file extensions. diff --git a/src/rules/extensions.ts b/src/rules/extensions.ts index 73bb6a75..7f8c5f82 100644 --- a/src/rules/extensions.ts +++ b/src/rules/extensions.ts @@ -132,6 +132,10 @@ function buildProperties(context: RuleContext) { continue } + if (obj.fix != null) { + result.fix = Boolean(obj.fix) + } + // If this is not the new structure, transfer all props to result.pattern if ( (!('pattern' in obj) || obj.pattern == null) && @@ -156,10 +160,6 @@ function buildProperties(context: RuleContext) { result.checkTypeImports = obj.checkTypeImports } - if (obj.fix != null) { - result.fix = Boolean(obj.fix) - } - if (Array.isArray(obj.pathGroupOverrides)) { result.pathGroupOverrides = obj.pathGroupOverrides } diff --git a/test/rules/extensions.spec.ts b/test/rules/extensions.spec.ts index 01b97b3e..f7824036 100644 --- a/test/rules/extensions.spec.ts +++ b/test/rules/extensions.spec.ts @@ -173,6 +173,83 @@ ruleTester.run('extensions', rule, { ], invalid: [ + tInvalid({ + name: 'extensions should provide suggestions by default', + code: 'import a from "./foo.js"', + options: ['never'], + errors: [ + { + messageId: 'unexpected', + data: { extension: 'js', importPath: './foo.js' }, + line: 1, + column: 15, + suggestions: [ + { + messageId: 'removeUnexpected', + data: { + extension: 'js', + importPath: './foo.js', + fixedImportPath: './foo', + }, + output: 'import a from "./foo"', + }, + ], + }, + ], + }), + tInvalid({ + name: 'extensions should autofix when fix is set to true', + code: 'import a from "./foo.js"', + options: ['never', { fix: true }], + errors: [ + { + messageId: 'unexpected', + data: { extension: 'js', importPath: './foo.js' }, + line: 1, + column: 15, + }, + ], + output: 'import a from "./foo"', + }), + tInvalid({ + name: 'extensions should autofix when fix is set to true and a pattern object is provided', + code: 'import a from "./foo.js"', + options: ['never', { fix: true, pattern: {} }], + errors: [ + { + messageId: 'unexpected', + data: { extension: 'js', importPath: './foo.js' }, + line: 1, + column: 15, + }, + ], + output: 'import a from "./foo"', + }), + tInvalid({ + name: 'extensions should not autofix when fix is set to false', + code: 'import a from "./foo.js"', + options: ['never', { fix: false }], + errors: [ + { + messageId: 'unexpected', + data: { extension: 'js', importPath: './foo.js' }, + line: 1, + column: 15, + suggestions: [ + { + messageId: 'removeUnexpected', + data: { + extension: 'js', + importPath: './foo.js', + fixedImportPath: './foo', + }, + output: 'import a from "./foo"', + }, + ], + }, + ], + output: null, + }), tInvalid({ code: 'import a from "a/index.js"', errors: [