From 8c3aa8a525fec1a15dc72502605ddbaf3d12ba73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJamesHenry=E2=80=9D?= Date: Thu, 24 Nov 2022 14:34:23 +0400 Subject: [PATCH] fix(eslint-plugin): [no-input-rename] do not report on directive composition API --- .../docs/rules/no-input-rename.md | 99 +++++++++++++++++++ .../src/rules/no-input-rename.ts | 22 +++++ .../tests/rules/no-input-rename/cases.ts | 35 +++++++ 3 files changed, 156 insertions(+) diff --git a/packages/eslint-plugin/docs/rules/no-input-rename.md b/packages/eslint-plugin/docs/rules/no-input-rename.md index 4bae04702..e14441ee7 100644 --- a/packages/eslint-plugin/docs/rules/no-input-rename.md +++ b/packages/eslint-plugin/docs/rules/no-input-rename.md @@ -655,6 +655,105 @@ class Test {} #### ✅ Valid Code +```ts +@Component({ + selector: 'qx-menuitem', + hostDirectives: [{ + directive: CdkMenuItem, + inputs: ['cdkMenuItemDisabled: disabled'], + }] +}) +class Test {} +``` + +
+ +--- + +
+ +#### Default Config + +```json +{ + "rules": { + "@angular-eslint/no-input-rename": [ + "error" + ] + } +} +``` + +
+ +#### ✅ Valid Code + +```ts +@Component({ + selector: 'qx-menuitem', + 'hostDirectives': [{ + directive: CdkMenuItem, + inputs: ['cdkMenuItemDisabled: disabled'], + }] +}) +class Test {} +``` + +
+ +--- + +
+ +#### Default Config + +```json +{ + "rules": { + "@angular-eslint/no-input-rename": [ + "error" + ] + } +} +``` + +
+ +#### ✅ Valid Code + +```ts +@Component({ + selector: 'qx-menuitem', + ['hostDirectives']: [{ + directive: CdkMenuItem, + inputs: ['cdkMenuItemDisabled: disabled'], + }] +}) +class Test {} +``` + +
+ +--- + +
+ +#### Default Config + +```json +{ + "rules": { + "@angular-eslint/no-input-rename": [ + "error" + ] + } +} +``` + +
+ +#### ✅ Valid Code + ```ts @Component({}) class Test { diff --git a/packages/eslint-plugin/src/rules/no-input-rename.ts b/packages/eslint-plugin/src/rules/no-input-rename.ts index aa81e9a55..9431af5a5 100644 --- a/packages/eslint-plugin/src/rules/no-input-rename.ts +++ b/packages/eslint-plugin/src/rules/no-input-rename.ts @@ -139,6 +139,28 @@ export default createESLintRule({ [Selectors.INPUTS_METADATA_PROPERTY_LITERAL]( node: TSESTree.Literal | TSESTree.TemplateElement, ) { + const ancestorMaybeHostDirectiveAPI = + node.parent?.parent?.parent?.parent?.parent; + if ( + ancestorMaybeHostDirectiveAPI && + ASTUtils.isProperty(ancestorMaybeHostDirectiveAPI) + ) { + /** + * Angular v15 introduced the directive composition API: https://angular.io/guide/directive-composition-api + * Renaming host directive inputs using this API is not a bad practice and should not be reported + */ + const hostDirectiveAPIPropertyName = 'hostDirectives'; + if ( + (ASTUtils.isLiteral(ancestorMaybeHostDirectiveAPI.key) && + ancestorMaybeHostDirectiveAPI.key.value === + hostDirectiveAPIPropertyName) || + (TSESLintASTUtils.isIdentifier(ancestorMaybeHostDirectiveAPI.key) && + ancestorMaybeHostDirectiveAPI.key.name === + hostDirectiveAPIPropertyName) + ) { + return; + } + } const [propertyName, aliasName] = withoutBracketsAndWhitespaces( ASTUtils.getRawText(node), ).split(':'); diff --git a/packages/eslint-plugin/tests/rules/no-input-rename/cases.ts b/packages/eslint-plugin/tests/rules/no-input-rename/cases.ts index 9cfbd6e53..05ac84021 100644 --- a/packages/eslint-plugin/tests/rules/no-input-rename/cases.ts +++ b/packages/eslint-plugin/tests/rules/no-input-rename/cases.ts @@ -50,6 +50,41 @@ export const valid = [ }) class Test {} `, + /** + * Renaming inputs when using the directive composition API is not a bad practice + * https://angular.io/guide/directive-composition-api + * https://www.youtube.com/watch?v=EJJwyyjsRGs + */ + ` + @Component({ + selector: 'qx-menuitem', + hostDirectives: [{ + directive: CdkMenuItem, + inputs: ['cdkMenuItemDisabled: disabled'], + }] + }) + class Test {} + `, + ` + @Component({ + selector: 'qx-menuitem', + 'hostDirectives': [{ + directive: CdkMenuItem, + inputs: ['cdkMenuItemDisabled: disabled'], + }] + }) + class Test {} + `, + ` + @Component({ + selector: 'qx-menuitem', + ['hostDirectives']: [{ + directive: CdkMenuItem, + inputs: ['cdkMenuItemDisabled: disabled'], + }] + }) + class Test {} + `, ` @Component({}) class Test {