From e94b59a35c914d868f89dd300b8d6b8090054976 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Mon, 17 Mar 2025 17:49:50 +0900 Subject: [PATCH 01/14] fix: resolve false positives on nested objects in `no-unused-props` rule (#1128) --- .changeset/fuzzy-ads-join.md | 5 +++++ .../src/rules/no-unused-props.ts | 2 +- .../no-unused-props/valid/ts-basic-input.svelte | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 .changeset/fuzzy-ads-join.md create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ts-basic-input.svelte diff --git a/.changeset/fuzzy-ads-join.md b/.changeset/fuzzy-ads-join.md new file mode 100644 index 000000000..5af5eb134 --- /dev/null +++ b/.changeset/fuzzy-ads-join.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-svelte': patch +--- + +fix: resolve false positives on nested objects in `no-unused-props` rule diff --git a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts index 1588f3b32..0d057b3f0 100644 --- a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts +++ b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts @@ -319,7 +319,7 @@ export default createRule('no-unused-props', { .filter((v): v is TSESTree.Identifier => v.type === 'Identifier'); for (const identifier of identifiers) { const paths = getUsedNestedPropertyNames(identifier); - usedPaths.push(...paths); + usedPaths.push(...paths.map((path) => [identifier.name, ...path])); } } else if (node.id.type === 'Identifier') { usedPaths = getUsedNestedPropertyNames(node.id); diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ts-basic-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ts-basic-input.svelte new file mode 100644 index 000000000..d2c509f6a --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ts-basic-input.svelte @@ -0,0 +1,15 @@ + + +

{myObjectProp.value} {myObjectProp.value2}

From ae6e3e7b55ca2fb588568d6bff5f547bcacb90bd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 17:50:53 +0900 Subject: [PATCH 02/14] chore: release eslint-plugin-svelte (#1129) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/fuzzy-ads-join.md | 5 ----- packages/eslint-plugin-svelte/CHANGELOG.md | 6 ++++++ packages/eslint-plugin-svelte/package.json | 2 +- packages/eslint-plugin-svelte/src/meta.ts | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 .changeset/fuzzy-ads-join.md diff --git a/.changeset/fuzzy-ads-join.md b/.changeset/fuzzy-ads-join.md deleted file mode 100644 index 5af5eb134..000000000 --- a/.changeset/fuzzy-ads-join.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-svelte': patch ---- - -fix: resolve false positives on nested objects in `no-unused-props` rule diff --git a/packages/eslint-plugin-svelte/CHANGELOG.md b/packages/eslint-plugin-svelte/CHANGELOG.md index 9aa040e0a..618399569 100644 --- a/packages/eslint-plugin-svelte/CHANGELOG.md +++ b/packages/eslint-plugin-svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # eslint-plugin-svelte +## 3.2.1 + +### Patch Changes + +- [#1128](https://github.com/sveltejs/eslint-plugin-svelte/pull/1128) [`e94b59a`](https://github.com/sveltejs/eslint-plugin-svelte/commit/e94b59a35c914d868f89dd300b8d6b8090054976) Thanks [@baseballyama](https://github.com/baseballyama)! - fix: resolve false positives on nested objects in `no-unused-props` rule + ## 3.2.0 ### Minor Changes diff --git a/packages/eslint-plugin-svelte/package.json b/packages/eslint-plugin-svelte/package.json index 06a83ab12..47cc6824e 100644 --- a/packages/eslint-plugin-svelte/package.json +++ b/packages/eslint-plugin-svelte/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-svelte", - "version": "3.2.0", + "version": "3.2.1", "description": "ESLint plugin for Svelte using AST", "repository": "git+https://github.com/sveltejs/eslint-plugin-svelte.git", "homepage": "https://sveltejs.github.io/eslint-plugin-svelte", diff --git a/packages/eslint-plugin-svelte/src/meta.ts b/packages/eslint-plugin-svelte/src/meta.ts index 9de65a2c7..86678047c 100644 --- a/packages/eslint-plugin-svelte/src/meta.ts +++ b/packages/eslint-plugin-svelte/src/meta.ts @@ -2,4 +2,4 @@ // This file has been automatically generated, // in order to update its content execute "pnpm run update" export const name = 'eslint-plugin-svelte'; -export const version = '3.2.0'; +export const version = '3.2.1'; From bea4945bff71d381a9832be96a13c0a70aa69358 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Mon, 17 Mar 2025 17:59:28 +0900 Subject: [PATCH 03/14] chore: update required Node.js version in README (#1130) --- README.md | 2 +- docs/user-guide.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3315bd3ba..db731dd26 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ npm install --save-dev svelte eslint eslint-plugin-svelte globals > **Requirements:** > > - ESLint v8.57.1, v9.0.0, and above -> - Node.js v18.20.4, v20.18.0, v22.10.0, and above +> - Node.js v18.18.0, v20.9.0, v21.1.0 and above ## Usage diff --git a/docs/user-guide.md b/docs/user-guide.md index 0eba2e2bd..babec87fa 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -13,7 +13,7 @@ npm install --save-dev svelte eslint eslint-plugin-svelte globals > **Requirements:** > > - ESLint v8.57.1, v9.0.0, and above -> - Node.js v18.20.4, v20.18.0, v22.10.0, and above +> - Node.js v18.18.0, v20.9.0, v21.1.0 and above ## Usage From 1ff148a0bb24954aef59ce93b05a35913d83f2ee Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Mon, 17 Mar 2025 23:04:56 +0900 Subject: [PATCH 04/14] fix: correct detection of externally defined types in `no-unused-props` rule (#1135) --- .changeset/plain-chairs-tie.md | 5 +++++ .../eslint-plugin-svelte/src/rules/no-unused-props.ts | 10 +++------- .../invalid/ignore-external-type-errors.yaml | 4 ++++ .../invalid/ignore-external-type-input.svelte | 10 ++++++++++ .../invalid/imported-type-check-errors.yaml | 2 -- .../rules/no-unused-props/invalid/shared-types.ts | 11 +++++++++++ .../valid/ignore-external-type-input.svelte | 10 ++++++++++ .../rules/no-unused-props/valid/shared-types.ts | 11 +++++++++++ 8 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 .changeset/plain-chairs-tie.md create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-external-type-errors.yaml create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-external-type-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-external-type-input.svelte diff --git a/.changeset/plain-chairs-tie.md b/.changeset/plain-chairs-tie.md new file mode 100644 index 000000000..5b5c46d5d --- /dev/null +++ b/.changeset/plain-chairs-tie.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-svelte': patch +--- + +fix: correct detection of externally defined types in `no-unused-props` rule diff --git a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts index 0d057b3f0..d425026f2 100644 --- a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts +++ b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts @@ -80,15 +80,11 @@ export default createRule('no-unused-props', { return shouldIgnore(typeStr) || (symbolName ? shouldIgnore(symbolName) : false); } - function isExternalType(type: ts.Type): boolean { - const symbol = type.getSymbol(); - if (!symbol) return false; - + function isInternalProperty(symbol: ts.Symbol): boolean { const declarations = symbol.getDeclarations(); if (!declarations || declarations.length === 0) return false; - const sourceFile = declarations[0].getSourceFile(); - return sourceFile.fileName !== fileName; + return declarations.every((decl) => decl.getSourceFile().fileName === fileName); } /** @@ -200,7 +196,6 @@ export default createRule('no-unused-props', { if (checkedTypes.has(typeStr)) return; checkedTypes.add(typeStr); if (shouldIgnoreType(type)) return; - if (!checkImportedTypes && isExternalType(type)) return; const properties = typeChecker.getPropertiesOfType(type); const baseTypes = type.getBaseTypes(); @@ -225,6 +220,7 @@ export default createRule('no-unused-props', { for (const prop of properties) { if (isBuiltInProperty(prop)) continue; + if (!checkImportedTypes && !isInternalProperty(prop)) continue; const propName = prop.getName(); const currentPath = [...parentPath, propName]; diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-external-type-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-external-type-errors.yaml new file mode 100644 index 000000000..502c15458 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-external-type-errors.yaml @@ -0,0 +1,4 @@ +- message: "'child2' is an unused Props property." + line: 9 + column: 6 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-external-type-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-external-type-input.svelte new file mode 100644 index 000000000..2d26bd2d9 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-external-type-input.svelte @@ -0,0 +1,10 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/imported-type-check-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/imported-type-check-errors.yaml index 2f341476f..278805b2d 100644 --- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/imported-type-check-errors.yaml +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/imported-type-check-errors.yaml @@ -1,6 +1,4 @@ - message: "'name' is an unused Props property." line: 6 column: 6 - endLine: 6 - endColumn: 20 suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/shared-types.ts b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/shared-types.ts index a60e61ef1..e33a3a24e 100644 --- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/shared-types.ts +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/shared-types.ts @@ -1,3 +1,14 @@ export interface BaseProps { name: string; } + +export interface FooDTO { + foo: string; + bar: number; + baz: BazDTO; +} + +interface BazDTO { + qux: string; + quux: number; +} diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-external-type-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-external-type-input.svelte new file mode 100644 index 000000000..920dece77 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-external-type-input.svelte @@ -0,0 +1,10 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/shared-types.ts b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/shared-types.ts index a60e61ef1..e33a3a24e 100644 --- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/shared-types.ts +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/shared-types.ts @@ -1,3 +1,14 @@ export interface BaseProps { name: string; } + +export interface FooDTO { + foo: string; + bar: number; + baz: BazDTO; +} + +interface BazDTO { + qux: string; + quux: number; +} From 0e2e84844a95555324b9cae167c5a1f684a1174b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 23:06:28 +0900 Subject: [PATCH 05/14] chore: release eslint-plugin-svelte (#1137) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/plain-chairs-tie.md | 5 ----- packages/eslint-plugin-svelte/CHANGELOG.md | 6 ++++++ packages/eslint-plugin-svelte/package.json | 2 +- packages/eslint-plugin-svelte/src/meta.ts | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 .changeset/plain-chairs-tie.md diff --git a/.changeset/plain-chairs-tie.md b/.changeset/plain-chairs-tie.md deleted file mode 100644 index 5b5c46d5d..000000000 --- a/.changeset/plain-chairs-tie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-svelte': patch ---- - -fix: correct detection of externally defined types in `no-unused-props` rule diff --git a/packages/eslint-plugin-svelte/CHANGELOG.md b/packages/eslint-plugin-svelte/CHANGELOG.md index 618399569..d7d42835a 100644 --- a/packages/eslint-plugin-svelte/CHANGELOG.md +++ b/packages/eslint-plugin-svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # eslint-plugin-svelte +## 3.2.2 + +### Patch Changes + +- [#1135](https://github.com/sveltejs/eslint-plugin-svelte/pull/1135) [`1ff148a`](https://github.com/sveltejs/eslint-plugin-svelte/commit/1ff148a0bb24954aef59ce93b05a35913d83f2ee) Thanks [@baseballyama](https://github.com/baseballyama)! - fix: correct detection of externally defined types in `no-unused-props` rule + ## 3.2.1 ### Patch Changes diff --git a/packages/eslint-plugin-svelte/package.json b/packages/eslint-plugin-svelte/package.json index 47cc6824e..d227077dc 100644 --- a/packages/eslint-plugin-svelte/package.json +++ b/packages/eslint-plugin-svelte/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-svelte", - "version": "3.2.1", + "version": "3.2.2", "description": "ESLint plugin for Svelte using AST", "repository": "git+https://github.com/sveltejs/eslint-plugin-svelte.git", "homepage": "https://sveltejs.github.io/eslint-plugin-svelte", diff --git a/packages/eslint-plugin-svelte/src/meta.ts b/packages/eslint-plugin-svelte/src/meta.ts index 86678047c..4fbc02f6a 100644 --- a/packages/eslint-plugin-svelte/src/meta.ts +++ b/packages/eslint-plugin-svelte/src/meta.ts @@ -2,4 +2,4 @@ // This file has been automatically generated, // in order to update its content execute "pnpm run update" export const name = 'eslint-plugin-svelte'; -export const version = '3.2.1'; +export const version = '3.2.2'; From 30c1e5fc6517cec7171ca42327699c3ad9ab6580 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Mon, 17 Mar 2025 23:38:36 +0900 Subject: [PATCH 06/14] feat: add `ignorePropertyPatterns` property and rename `ignorePatterns` to `ignoreTypePatterns` in `no-unused-props` rule (#1132) --- .changeset/crazy-peas-laugh.md | 5 ++ docs/rules/no-unused-props.md | 31 +++++++++++-- .../eslint-plugin-svelte/src/rule-types.ts | 3 +- .../src/rules/no-unused-props.ts | 46 +++++++++++++++++-- .../custom-config-combination-config.json | 9 ++++ .../custom-config-combination-errors.yaml | 12 +++++ .../custom-config-combination-input.svelte | 12 +++++ ...gnore-property-patterns-custom-config.json | 7 +++ ...gnore-property-patterns-custom-errors.yaml | 8 ++++ ...nore-property-patterns-custom-input.svelte | 9 ++++ .../ignored-pattern-partial-config.json | 7 --- .../ignored-type-patterns-custom-config.json | 7 +++ ... ignored-type-patterns-custom-errors.yaml} | 0 ...ignored-type-patterns-custom-input.svelte} | 0 .../custom-config-combination-config.json | 9 ++++ .../custom-config-combination-input.svelte | 11 +++++ ...gnore-property-patterns-custom-config.json | 7 +++ ...nore-property-patterns-custom-input.svelte | 13 ++++++ ...ore-property-patterns-default-input.svelte | 8 ++++ .../ignored-conditional-type-config.json | 7 --- .../ignored-type-patterns-custom-config.json | 7 +++ ...ignored-type-patterns-custom-input.svelte} | 0 .../ignored-type-patterns-custom2-config.json | 7 +++ ...ignored-type-patterns-custom2-input.svelte | 12 +++++ .../no-unused-props/valid/shared-types.ts | 1 + 25 files changed, 213 insertions(+), 25 deletions(-) create mode 100644 .changeset/crazy-peas-laugh.md create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/custom-config-combination-config.json create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/custom-config-combination-errors.yaml create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/custom-config-combination-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-config.json create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-errors.yaml create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-input.svelte delete mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-pattern-partial-config.json create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-type-patterns-custom-config.json rename packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/{ignored-pattern-partial-errors.yaml => ignored-type-patterns-custom-errors.yaml} (100%) rename packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/{ignored-pattern-partial-input.svelte => ignored-type-patterns-custom-input.svelte} (100%) create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/custom-config-combination-config.json create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/custom-config-combination-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-custom-config.json create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-custom-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-default-input.svelte delete mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-conditional-type-config.json create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom-config.json rename packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/{ignored-conditional-type-input.svelte => ignored-type-patterns-custom-input.svelte} (100%) create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom2-config.json create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom2-input.svelte diff --git a/.changeset/crazy-peas-laugh.md b/.changeset/crazy-peas-laugh.md new file mode 100644 index 000000000..c3bbeeafd --- /dev/null +++ b/.changeset/crazy-peas-laugh.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-svelte': minor +--- + +feat: add `ignorePropertyPatterns` property and rename `ignorePatterns` to `ignoreTypePatterns` in `no-unused-props` rule. The `ignorePatterns` option existed only for a few hours and is removed by this PR. Technically, this is a breaking change, but we’ll handle it as a minor release since very few users are likely affected. diff --git a/docs/rules/no-unused-props.md b/docs/rules/no-unused-props.md index c375aa430..fffe3864f 100644 --- a/docs/rules/no-unused-props.md +++ b/docs/rules/no-unused-props.md @@ -159,14 +159,17 @@ Note: Properties of class types are not checked for usage, as they might be used "svelte/no-unused-props": ["error", { // Whether to check properties from imported types "checkImportedTypes": false, + // Patterns to ignore when checking property types + "ignoreTypePatterns": [], // Patterns to ignore when checking for unused props - "ignorePatterns": [] + "ignorePropertyPatterns": [], }] } ``` -- `checkImportedTypes` ... Controls whether to check properties from imported types. Default is `false`. -- `ignorePatterns` ... Patterns to ignore when checking for unused props. Default is an empty array. +- `checkImportedTypes` ... Controls whether to check properties from types defined in external files. Default is `false`, meaning the rule only checks types defined within the component file itself. When set to `true`, the rule will also check properties from imported and extended types. +- `ignoreTypePatterns` ... Regular expression patterns for type names to exclude from checks. Default is `[]` (no exclusions). Most useful when `checkImportedTypes` is `true`, allowing you to exclude specific imported types (like utility types or third-party types) from being checked. +- `ignorePropertyPatterns` ... Regular expression patterns for property names to exclude from unused checks. Default is `[]` (no exclusions). Most useful when `checkImportedTypes` is `true`, allowing you to ignore specific properties from external types that shouldn't trigger warnings. Examples: @@ -187,8 +190,26 @@ Examples: ```svelte +``` + +```svelte + + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-config.json new file mode 100644 index 000000000..65233c1d9 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-config.json @@ -0,0 +1,7 @@ +{ + "options": [ + { + "ignorePropertyPatterns": ["^foo$"] + } + ] +} diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-errors.yaml new file mode 100644 index 000000000..32c659188 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-errors.yaml @@ -0,0 +1,8 @@ +- message: "'foo' is an unused Props property." + line: 8 + column: 8 + suggestions: null +- message: "'_foo' is an unused Props property." + line: 8 + column: 8 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-input.svelte new file mode 100644 index 000000000..7bee93044 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignore-property-patterns-custom-input.svelte @@ -0,0 +1,9 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-pattern-partial-config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-pattern-partial-config.json deleted file mode 100644 index c049eb81c..000000000 --- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-pattern-partial-config.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "options": [ - { - "ignorePatterns": [".*DTO$"] - } - ] -} diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-type-patterns-custom-config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-type-patterns-custom-config.json new file mode 100644 index 000000000..ee109aa43 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-type-patterns-custom-config.json @@ -0,0 +1,7 @@ +{ + "options": [ + { + "ignoreTypePatterns": [".*DTO$"] + } + ] +} diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-pattern-partial-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-type-patterns-custom-errors.yaml similarity index 100% rename from packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-pattern-partial-errors.yaml rename to packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-type-patterns-custom-errors.yaml diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-pattern-partial-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-type-patterns-custom-input.svelte similarity index 100% rename from packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-pattern-partial-input.svelte rename to packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/invalid/ignored-type-patterns-custom-input.svelte diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/custom-config-combination-config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/custom-config-combination-config.json new file mode 100644 index 000000000..57ebeb292 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/custom-config-combination-config.json @@ -0,0 +1,9 @@ +{ + "options": [ + { + "checkImportedTypes": true, + "ignoreTypePatterns": ["BaseProps"], + "ignorePropertyPatterns": ["/^(_|baz)/"] + } + ] +} diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/custom-config-combination-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/custom-config-combination-input.svelte new file mode 100644 index 000000000..c34bc850e --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/custom-config-combination-input.svelte @@ -0,0 +1,11 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-custom-config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-custom-config.json new file mode 100644 index 000000000..c22dc1654 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-custom-config.json @@ -0,0 +1,7 @@ +{ + "options": [ + { + "ignorePropertyPatterns": ["/^[#$@_~]/"] + } + ] +} diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-custom-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-custom-input.svelte new file mode 100644 index 000000000..1dc0ca14d --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-custom-input.svelte @@ -0,0 +1,13 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-default-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-default-input.svelte new file mode 100644 index 000000000..5694cb2d7 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignore-property-patterns-default-input.svelte @@ -0,0 +1,8 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-conditional-type-config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-conditional-type-config.json deleted file mode 100644 index 73df77c94..000000000 --- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-conditional-type-config.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "options": [ - { - "ignorePatterns": ["^Conditional"] - } - ] -} diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom-config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom-config.json new file mode 100644 index 000000000..3a5c1de84 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom-config.json @@ -0,0 +1,7 @@ +{ + "options": [ + { + "ignoreTypePatterns": ["/^Conditional/"] + } + ] +} diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-conditional-type-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom-input.svelte similarity index 100% rename from packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-conditional-type-input.svelte rename to packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom-input.svelte diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom2-config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom2-config.json new file mode 100644 index 000000000..347ef2b85 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom2-config.json @@ -0,0 +1,7 @@ +{ + "options": [ + { + "ignoreTypePatterns": ["/^Internal/"] + } + ] +} diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom2-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom2-input.svelte new file mode 100644 index 000000000..0f465ea7d --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/ignored-type-patterns-custom2-input.svelte @@ -0,0 +1,12 @@ + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/shared-types.ts b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/shared-types.ts index e33a3a24e..76d6b33c5 100644 --- a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/shared-types.ts +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/shared-types.ts @@ -1,5 +1,6 @@ export interface BaseProps { name: string; + age: number; } export interface FooDTO { From 65c4f797c1563f5166ebc56a3096967d9c2f134c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 23:40:22 +0900 Subject: [PATCH 07/14] chore: release eslint-plugin-svelte (#1138) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/crazy-peas-laugh.md | 5 ----- packages/eslint-plugin-svelte/CHANGELOG.md | 6 ++++++ packages/eslint-plugin-svelte/package.json | 2 +- packages/eslint-plugin-svelte/src/meta.ts | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 .changeset/crazy-peas-laugh.md diff --git a/.changeset/crazy-peas-laugh.md b/.changeset/crazy-peas-laugh.md deleted file mode 100644 index c3bbeeafd..000000000 --- a/.changeset/crazy-peas-laugh.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-svelte': minor ---- - -feat: add `ignorePropertyPatterns` property and rename `ignorePatterns` to `ignoreTypePatterns` in `no-unused-props` rule. The `ignorePatterns` option existed only for a few hours and is removed by this PR. Technically, this is a breaking change, but we’ll handle it as a minor release since very few users are likely affected. diff --git a/packages/eslint-plugin-svelte/CHANGELOG.md b/packages/eslint-plugin-svelte/CHANGELOG.md index d7d42835a..ba2a18aaf 100644 --- a/packages/eslint-plugin-svelte/CHANGELOG.md +++ b/packages/eslint-plugin-svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # eslint-plugin-svelte +## 3.3.0 + +### Minor Changes + +- [#1132](https://github.com/sveltejs/eslint-plugin-svelte/pull/1132) [`30c1e5f`](https://github.com/sveltejs/eslint-plugin-svelte/commit/30c1e5fc6517cec7171ca42327699c3ad9ab6580) Thanks [@baseballyama](https://github.com/baseballyama)! - feat: add `ignorePropertyPatterns` property and rename `ignorePatterns` to `ignoreTypePatterns` in `no-unused-props` rule. The `ignorePatterns` option existed only for a few hours and is removed by this PR. Technically, this is a breaking change, but we’ll handle it as a minor release since very few users are likely affected. + ## 3.2.2 ### Patch Changes diff --git a/packages/eslint-plugin-svelte/package.json b/packages/eslint-plugin-svelte/package.json index d227077dc..ad3b13143 100644 --- a/packages/eslint-plugin-svelte/package.json +++ b/packages/eslint-plugin-svelte/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-svelte", - "version": "3.2.2", + "version": "3.3.0", "description": "ESLint plugin for Svelte using AST", "repository": "git+https://github.com/sveltejs/eslint-plugin-svelte.git", "homepage": "https://sveltejs.github.io/eslint-plugin-svelte", diff --git a/packages/eslint-plugin-svelte/src/meta.ts b/packages/eslint-plugin-svelte/src/meta.ts index 4fbc02f6a..9e182e182 100644 --- a/packages/eslint-plugin-svelte/src/meta.ts +++ b/packages/eslint-plugin-svelte/src/meta.ts @@ -2,4 +2,4 @@ // This file has been automatically generated, // in order to update its content execute "pnpm run update" export const name = 'eslint-plugin-svelte'; -export const version = '3.2.2'; +export const version = '3.3.0'; From 40806a4b6342a7f2d1bd40d65df8dec5af666e1a Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Tue, 18 Mar 2025 10:47:59 +0900 Subject: [PATCH 08/14] fix(no-useless-mustaches): Wrong auto-fix for quoted mustaches (#1140) --- .changeset/wise-fireants-obey.md | 5 +++++ .../src/rules/no-useless-mustaches.ts | 11 +++++++++-- .../invalid/quote-test02-errors.yaml | 16 ++++++++++++++++ .../invalid/quote-test02-input.svelte | 8 ++++++++ .../invalid/quote-test02-output.svelte | 8 ++++++++ 5 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 .changeset/wise-fireants-obey.md create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-errors.yaml create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-output.svelte diff --git a/.changeset/wise-fireants-obey.md b/.changeset/wise-fireants-obey.md new file mode 100644 index 000000000..8f37980cb --- /dev/null +++ b/.changeset/wise-fireants-obey.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-svelte": patch +--- + +fix(no-useless-mustaches): Wrong auto-fix for quoted mustaches diff --git a/packages/eslint-plugin-svelte/src/rules/no-useless-mustaches.ts b/packages/eslint-plugin-svelte/src/rules/no-useless-mustaches.ts index 05d3af28e..d8da0cc11 100644 --- a/packages/eslint-plugin-svelte/src/rules/no-useless-mustaches.ts +++ b/packages/eslint-plugin-svelte/src/rules/no-useless-mustaches.ts @@ -142,14 +142,21 @@ export default createRule('no-useless-mustaches', { node.parent.key.range[1], node.parent.value[0].range[0] ); - if (!div.endsWith('"') && !div.endsWith("'")) { + const quote = div.endsWith('"') ? 'quot' : div.endsWith("'") ? 'apos' : null; + if (!quote) { return [ fixer.insertTextBefore(node.parent.value[0], '"'), fixer.replaceText(node, unescaped.replace(/"/gu, '"')), fixer.insertTextAfter(node.parent.value[node.parent.value.length - 1], '"') ]; } - return fixer.replaceText(node, unescaped); + + return fixer.replaceText( + node, + quote === 'quot' + ? unescaped.replace(/"/gu, '"') + : unescaped.replace(/'/gu, ''') + ); } return fixer.replaceText(node, unescaped.replace(//gu, '>')); } diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-errors.yaml b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-errors.yaml new file mode 100644 index 000000000..ee6ce5e3e --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-errors.yaml @@ -0,0 +1,16 @@ +- message: Unexpected mustache interpolation with a string literal value. + line: 2 + column: 17 + suggestions: null +- message: Unexpected mustache interpolation with a string literal value. + line: 4 + column: 17 + suggestions: null +- message: Unexpected mustache interpolation with a string literal value. + line: 6 + column: 17 + suggestions: null +- message: Unexpected mustache interpolation with a string literal value. + line: 8 + column: 17 + suggestions: null diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-input.svelte new file mode 100644 index 000000000..43dbb27d9 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-input.svelte @@ -0,0 +1,8 @@ + +
+ +
+ +
+ +
diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-output.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-output.svelte new file mode 100644 index 000000000..fd9b14743 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-useless-mustaches/invalid/quote-test02-output.svelte @@ -0,0 +1,8 @@ + +
+ +
+ +
+ +
From 43f0ac316584d18ecdd4e14e6db9060f92515a64 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 11:00:15 +0900 Subject: [PATCH 09/14] chore: release eslint-plugin-svelte (#1141) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/wise-fireants-obey.md | 5 ----- packages/eslint-plugin-svelte/CHANGELOG.md | 6 ++++++ packages/eslint-plugin-svelte/package.json | 2 +- packages/eslint-plugin-svelte/src/meta.ts | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 .changeset/wise-fireants-obey.md diff --git a/.changeset/wise-fireants-obey.md b/.changeset/wise-fireants-obey.md deleted file mode 100644 index 8f37980cb..000000000 --- a/.changeset/wise-fireants-obey.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"eslint-plugin-svelte": patch ---- - -fix(no-useless-mustaches): Wrong auto-fix for quoted mustaches diff --git a/packages/eslint-plugin-svelte/CHANGELOG.md b/packages/eslint-plugin-svelte/CHANGELOG.md index ba2a18aaf..526195187 100644 --- a/packages/eslint-plugin-svelte/CHANGELOG.md +++ b/packages/eslint-plugin-svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # eslint-plugin-svelte +## 3.3.1 + +### Patch Changes + +- [#1140](https://github.com/sveltejs/eslint-plugin-svelte/pull/1140) [`40806a4`](https://github.com/sveltejs/eslint-plugin-svelte/commit/40806a4b6342a7f2d1bd40d65df8dec5af666e1a) Thanks [@ota-meshi](https://github.com/ota-meshi)! - fix(no-useless-mustaches): Wrong auto-fix for quoted mustaches + ## 3.3.0 ### Minor Changes diff --git a/packages/eslint-plugin-svelte/package.json b/packages/eslint-plugin-svelte/package.json index ad3b13143..ceb8c95ea 100644 --- a/packages/eslint-plugin-svelte/package.json +++ b/packages/eslint-plugin-svelte/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-svelte", - "version": "3.3.0", + "version": "3.3.1", "description": "ESLint plugin for Svelte using AST", "repository": "git+https://github.com/sveltejs/eslint-plugin-svelte.git", "homepage": "https://sveltejs.github.io/eslint-plugin-svelte", diff --git a/packages/eslint-plugin-svelte/src/meta.ts b/packages/eslint-plugin-svelte/src/meta.ts index 9e182e182..1402e15c7 100644 --- a/packages/eslint-plugin-svelte/src/meta.ts +++ b/packages/eslint-plugin-svelte/src/meta.ts @@ -2,4 +2,4 @@ // This file has been automatically generated, // in order to update its content execute "pnpm run update" export const name = 'eslint-plugin-svelte'; -export const version = '3.3.0'; +export const version = '3.3.1'; From 138380deeec2ccd0189b70abf7d9a2cd6b608338 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Tue, 18 Mar 2025 21:34:26 +0900 Subject: [PATCH 10/14] fix: stop reporting child properties in `no-unused-props` when the parent object itself is used (#1143) --- .changeset/floppy-symbols-sing.md | 5 +++ .../src/rules/no-unused-props.ts | 38 +++++++++++++++---- .../valid/nested-props2-input.svelte | 14 +++++++ .../valid/nested-props3-input.svelte | 16 ++++++++ .../valid/nested-props4-input.svelte | 17 +++++++++ 5 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 .changeset/floppy-symbols-sing.md create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props2-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props3-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props4-input.svelte diff --git a/.changeset/floppy-symbols-sing.md b/.changeset/floppy-symbols-sing.md new file mode 100644 index 000000000..11aa7c646 --- /dev/null +++ b/.changeset/floppy-symbols-sing.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-svelte': patch +--- + +fix: stop reporting child properties in `no-unused-props` when the parent object itself is used diff --git a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts index 84faa365e..5de3133c0 100644 --- a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts +++ b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts @@ -156,7 +156,12 @@ export default createRule('no-unused-props', { const paths: PropertyPath[] = []; for (const reference of variable.references) { - if ('identifier' in reference && reference.identifier.type === 'Identifier') { + if ( + 'identifier' in reference && + reference.identifier.type === 'Identifier' && + (reference.identifier.range[0] !== node.range[0] || + reference.identifier.range[1] !== node.range[1]) + ) { const referencePath = getPropertyPath(reference.identifier); paths.push(referencePath); } @@ -265,11 +270,17 @@ export default createRule('no-unused-props', { if (reportedProps.has(currentPathStr)) continue; const propType = typeChecker.getTypeOfSymbol(prop); - const isUsedInPath = usedPaths.some((path) => { - const usedPath = path.join('.'); - return usedPath === currentPathStr || usedPath.startsWith(`${currentPathStr}.`); + + const joinedUsedPaths = usedPaths.map((path) => path.join('.')); + const isUsedThisInPath = joinedUsedPaths.includes(currentPathStr); + const isUsedInPath = joinedUsedPaths.some((path) => { + return path.startsWith(`${currentPathStr}.`); }); + if (isUsedThisInPath && !isUsedInPath) { + continue; + } + const isUsedInProps = usedProps.has(propName); if (!isUsedInPath && !isUsedInProps) { @@ -282,10 +293,11 @@ export default createRule('no-unused-props', { parent: parentPath.join('.') } }); + continue; } - const isUsedNested = usedPaths.some((path) => { - return path.join('.').startsWith(`${currentPathStr}.`); + const isUsedNested = joinedUsedPaths.some((path) => { + return path.startsWith(`${currentPathStr}.`); }); if (isUsedNested || isUsedInProps) { @@ -324,6 +336,18 @@ export default createRule('no-unused-props', { return usedProps.size === 0; } + function normalizeUsedPaths(paths: PropertyPath[]): PropertyPath[] { + const normalized: PropertyPath[] = []; + for (const path of paths.sort((a, b) => a.length - b.length)) { + if (path.length === 0) continue; + if (normalized.some((p) => p.every((part, idx) => part === path[idx]))) { + continue; + } + normalized.push(path); + } + return normalized; + } + return { 'VariableDeclaration > VariableDeclarator': (node: TSESTree.VariableDeclarator) => { // Only check $props declarations @@ -359,7 +383,7 @@ export default createRule('no-unused-props', { checkUnusedProperties( propType, - usedPaths, + normalizeUsedPaths(usedPaths), usedProps, node.id, [], diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props2-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props2-input.svelte new file mode 100644 index 000000000..3fb8790fd --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props2-input.svelte @@ -0,0 +1,14 @@ + + +Test diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props3-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props3-input.svelte new file mode 100644 index 000000000..7090054f8 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props3-input.svelte @@ -0,0 +1,16 @@ + + +Test diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props4-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props4-input.svelte new file mode 100644 index 000000000..15bdb1277 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props4-input.svelte @@ -0,0 +1,17 @@ + + +Test +Test From 423fe5ef1d36344f7b1a70568339a545d2f4e695 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 21:36:58 +0900 Subject: [PATCH 11/14] chore: release eslint-plugin-svelte (#1144) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/floppy-symbols-sing.md | 5 ----- packages/eslint-plugin-svelte/CHANGELOG.md | 6 ++++++ packages/eslint-plugin-svelte/package.json | 2 +- packages/eslint-plugin-svelte/src/meta.ts | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 .changeset/floppy-symbols-sing.md diff --git a/.changeset/floppy-symbols-sing.md b/.changeset/floppy-symbols-sing.md deleted file mode 100644 index 11aa7c646..000000000 --- a/.changeset/floppy-symbols-sing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-svelte': patch ---- - -fix: stop reporting child properties in `no-unused-props` when the parent object itself is used diff --git a/packages/eslint-plugin-svelte/CHANGELOG.md b/packages/eslint-plugin-svelte/CHANGELOG.md index 526195187..d9dc6f750 100644 --- a/packages/eslint-plugin-svelte/CHANGELOG.md +++ b/packages/eslint-plugin-svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # eslint-plugin-svelte +## 3.3.2 + +### Patch Changes + +- [#1143](https://github.com/sveltejs/eslint-plugin-svelte/pull/1143) [`138380d`](https://github.com/sveltejs/eslint-plugin-svelte/commit/138380deeec2ccd0189b70abf7d9a2cd6b608338) Thanks [@baseballyama](https://github.com/baseballyama)! - fix: stop reporting child properties in `no-unused-props` when the parent object itself is used + ## 3.3.1 ### Patch Changes diff --git a/packages/eslint-plugin-svelte/package.json b/packages/eslint-plugin-svelte/package.json index ceb8c95ea..46ae8a490 100644 --- a/packages/eslint-plugin-svelte/package.json +++ b/packages/eslint-plugin-svelte/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-svelte", - "version": "3.3.1", + "version": "3.3.2", "description": "ESLint plugin for Svelte using AST", "repository": "git+https://github.com/sveltejs/eslint-plugin-svelte.git", "homepage": "https://sveltejs.github.io/eslint-plugin-svelte", diff --git a/packages/eslint-plugin-svelte/src/meta.ts b/packages/eslint-plugin-svelte/src/meta.ts index 1402e15c7..e340ae364 100644 --- a/packages/eslint-plugin-svelte/src/meta.ts +++ b/packages/eslint-plugin-svelte/src/meta.ts @@ -2,4 +2,4 @@ // This file has been automatically generated, // in order to update its content execute "pnpm run update" export const name = 'eslint-plugin-svelte'; -export const version = '3.3.1'; +export const version = '3.3.2'; From 1233e46413132c1e81dc69981be1533c5e6c6a4d Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Thu, 20 Mar 2025 09:21:55 +0900 Subject: [PATCH 12/14] fix(no-unused-props): resolve false positives on props with default values or $bindable usage (#1146) --- .changeset/few-singers-marry.md | 5 +++++ .../src/rules/no-unused-props.ts | 15 +++++++++++---- .../no-unused-props/valid/bindable-input.svelte | 9 +++++++++ .../valid/default-value-input.svelte | 14 ++++++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 .changeset/few-singers-marry.md create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/bindable-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/default-value-input.svelte diff --git a/.changeset/few-singers-marry.md b/.changeset/few-singers-marry.md new file mode 100644 index 000000000..4e924dfd1 --- /dev/null +++ b/.changeset/few-singers-marry.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-svelte': patch +--- + +fix(no-unused-props): resolve false positives on props with default values or $bindable usage diff --git a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts index 5de3133c0..2ea58fd87 100644 --- a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts +++ b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts @@ -369,10 +369,17 @@ export default createRule('no-unused-props', { if (node.id.type === 'ObjectPattern') { usedProps = getUsedPropertiesFromPattern(node.id); if (usedProps.size === 0) return; - const identifiers = node.id.properties - .filter((p): p is TSESTree.Property => p.type === 'Property') - .map((p) => p.value) - .filter((v): v is TSESTree.Identifier => v.type === 'Identifier'); + const identifiers: TSESTree.Identifier[] = []; + for (const p of node.id.properties) { + if (p.type !== 'Property') { + continue; + } + if (p.value.type === 'Identifier') { + identifiers.push(p.value); + } else if (p.value.type === 'AssignmentPattern' && p.value.left.type === 'Identifier') { + identifiers.push(p.value.left); + } + } for (const identifier of identifiers) { const paths = getUsedNestedPropertyNames(identifier); usedPaths.push(...paths.map((path) => [identifier.name, ...path])); diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/bindable-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/bindable-input.svelte new file mode 100644 index 000000000..ef2c5e990 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/bindable-input.svelte @@ -0,0 +1,9 @@ + + + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/default-value-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/default-value-input.svelte new file mode 100644 index 000000000..48d6887f4 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/default-value-input.svelte @@ -0,0 +1,14 @@ + + +
+
+ {newTaskAttributes.attribute} + {newTaskAttributes.attribute2} +
+
From 6ed9870053beb05350b893a1ce0285c483a655ec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 09:22:56 +0900 Subject: [PATCH 13/14] chore: release eslint-plugin-svelte (#1147) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/few-singers-marry.md | 5 ----- packages/eslint-plugin-svelte/CHANGELOG.md | 6 ++++++ packages/eslint-plugin-svelte/package.json | 2 +- packages/eslint-plugin-svelte/src/meta.ts | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 .changeset/few-singers-marry.md diff --git a/.changeset/few-singers-marry.md b/.changeset/few-singers-marry.md deleted file mode 100644 index 4e924dfd1..000000000 --- a/.changeset/few-singers-marry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-svelte': patch ---- - -fix(no-unused-props): resolve false positives on props with default values or $bindable usage diff --git a/packages/eslint-plugin-svelte/CHANGELOG.md b/packages/eslint-plugin-svelte/CHANGELOG.md index d9dc6f750..23a4fba9e 100644 --- a/packages/eslint-plugin-svelte/CHANGELOG.md +++ b/packages/eslint-plugin-svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # eslint-plugin-svelte +## 3.3.3 + +### Patch Changes + +- [#1146](https://github.com/sveltejs/eslint-plugin-svelte/pull/1146) [`1233e46`](https://github.com/sveltejs/eslint-plugin-svelte/commit/1233e46413132c1e81dc69981be1533c5e6c6a4d) Thanks [@baseballyama](https://github.com/baseballyama)! - fix(no-unused-props): resolve false positives on props with default values or $bindable usage + ## 3.3.2 ### Patch Changes diff --git a/packages/eslint-plugin-svelte/package.json b/packages/eslint-plugin-svelte/package.json index 46ae8a490..236ec8e09 100644 --- a/packages/eslint-plugin-svelte/package.json +++ b/packages/eslint-plugin-svelte/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-svelte", - "version": "3.3.2", + "version": "3.3.3", "description": "ESLint plugin for Svelte using AST", "repository": "git+https://github.com/sveltejs/eslint-plugin-svelte.git", "homepage": "https://sveltejs.github.io/eslint-plugin-svelte", diff --git a/packages/eslint-plugin-svelte/src/meta.ts b/packages/eslint-plugin-svelte/src/meta.ts index e340ae364..f3f181d74 100644 --- a/packages/eslint-plugin-svelte/src/meta.ts +++ b/packages/eslint-plugin-svelte/src/meta.ts @@ -2,4 +2,4 @@ // This file has been automatically generated, // in order to update its content execute "pnpm run update" export const name = 'eslint-plugin-svelte'; -export const version = '3.3.2'; +export const version = '3.3.3'; From a62ef2fd57e0af3b218776ecb744514c2e296d61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Mar 2025 02:43:14 +0000 Subject: [PATCH 14/14] chore(deps): update dependency eslint to ~9.23.0 (#1149) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4c02f05d2..254352fc5 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@typescript-eslint/parser": "^8.16.0", "c8": "^10.1.2", "env-cmd": "^10.1.0", - "eslint": "~9.22.0", + "eslint": "~9.23.0", "eslint-config-prettier": "^10.0.0", "eslint-formatter-friendly": "^7.0.0", "eslint-plugin-eslint-plugin": "^6.3.2",