@yoo-digital/eslint-plugin-angular 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,37 +1,25 @@
|
|
|
1
1
|
import type { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
-
|
|
3
|
-
allowFalseLiteral?: boolean;
|
|
4
|
-
}
|
|
5
|
-
type MessageIds = 'preferTrue' | 'preferFalse' | 'suggestTrue' | 'suggestRemove';
|
|
2
|
+
type MessageIds = 'preferTrue' | 'suggestTrue';
|
|
6
3
|
export declare const RULE_NAME = "prefer-boolean-attribute-shorthand";
|
|
7
4
|
/**
|
|
8
|
-
*
|
|
5
|
+
* This rule enforces shorthand syntax for boolean inputs bound to true.
|
|
9
6
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* 3. Complex AST traversal and decorator/signal input analysis
|
|
7
|
+
* BEHAVIOR:
|
|
8
|
+
* - [attr]="true" → Warns and suggests: attr
|
|
9
|
+
* - [attr]="false" → No warning (ignored)
|
|
10
|
+
* - attr → OK (already shorthand)
|
|
15
11
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
12
|
+
* ASSUMPTIONS:
|
|
13
|
+
* This rule assumes that boolean inputs use Angular's booleanAttribute transform,
|
|
14
|
+
* which allows the shorthand syntax to work correctly. The presence of the attribute
|
|
15
|
+
* alone (without a binding) will be interpreted as true.
|
|
20
16
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
17
|
+
* LIMITATIONS:
|
|
18
|
+
* Cannot verify at lint-time whether:
|
|
19
|
+
* - The input actually has `transform: booleanAttribute`
|
|
20
|
+
* - The input's default value
|
|
25
21
|
*
|
|
26
|
-
*
|
|
27
|
-
* To implement the full feature set requested would require creating a SEPARATE
|
|
28
|
-
* TypeScript ESLint rule that:
|
|
29
|
-
* - Runs on .ts component files (not templates)
|
|
30
|
-
* - Analyzes @Component decorators to find template references
|
|
31
|
-
* - Parses templates and cross-references with component inputs
|
|
32
|
-
* - Reports errors in both .ts and template files
|
|
33
|
-
*
|
|
34
|
-
* This would be a significantly more complex multi-file analysis rule.
|
|
22
|
+
* Use this rule in projects where boolean inputs consistently use booleanAttribute.
|
|
35
23
|
*/
|
|
36
|
-
export declare const preferBooleanAttributeShorthandRule: TSESLint.RuleModule<MessageIds,
|
|
24
|
+
export declare const preferBooleanAttributeShorthandRule: TSESLint.RuleModule<MessageIds, []>;
|
|
37
25
|
export {};
|
|
@@ -4,67 +4,40 @@ exports.preferBooleanAttributeShorthandRule = exports.RULE_NAME = void 0;
|
|
|
4
4
|
const utils_1 = require("@angular-eslint/utils");
|
|
5
5
|
exports.RULE_NAME = 'prefer-boolean-attribute-shorthand';
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* This rule enforces shorthand syntax for boolean inputs bound to true.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* 3. Complex AST traversal and decorator/signal input analysis
|
|
9
|
+
* BEHAVIOR:
|
|
10
|
+
* - [attr]="true" → Warns and suggests: attr
|
|
11
|
+
* - [attr]="false" → No warning (ignored)
|
|
12
|
+
* - attr → OK (already shorthand)
|
|
14
13
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* ASSUMPTIONS:
|
|
15
|
+
* This rule assumes that boolean inputs use Angular's booleanAttribute transform,
|
|
16
|
+
* which allows the shorthand syntax to work correctly. The presence of the attribute
|
|
17
|
+
* alone (without a binding) will be interpreted as true.
|
|
19
18
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
19
|
+
* LIMITATIONS:
|
|
20
|
+
* Cannot verify at lint-time whether:
|
|
21
|
+
* - The input actually has `transform: booleanAttribute`
|
|
22
|
+
* - The input's default value
|
|
24
23
|
*
|
|
25
|
-
*
|
|
26
|
-
* To implement the full feature set requested would require creating a SEPARATE
|
|
27
|
-
* TypeScript ESLint rule that:
|
|
28
|
-
* - Runs on .ts component files (not templates)
|
|
29
|
-
* - Analyzes @Component decorators to find template references
|
|
30
|
-
* - Parses templates and cross-references with component inputs
|
|
31
|
-
* - Reports errors in both .ts and template files
|
|
32
|
-
*
|
|
33
|
-
* This would be a significantly more complex multi-file analysis rule.
|
|
24
|
+
* Use this rule in projects where boolean inputs consistently use booleanAttribute.
|
|
34
25
|
*/
|
|
35
26
|
exports.preferBooleanAttributeShorthandRule = {
|
|
36
27
|
meta: {
|
|
37
28
|
type: 'suggestion',
|
|
38
29
|
docs: {
|
|
39
|
-
description: 'Prefer boolean input attribute shorthand
|
|
30
|
+
description: 'Prefer boolean input attribute shorthand when binding to true (e.g., use "disabled" instead of [disabled]="true").',
|
|
40
31
|
},
|
|
41
32
|
hasSuggestions: true,
|
|
42
|
-
schema: [
|
|
43
|
-
{
|
|
44
|
-
type: 'object',
|
|
45
|
-
properties: {
|
|
46
|
-
allowFalseLiteral: { type: 'boolean' },
|
|
47
|
-
},
|
|
48
|
-
additionalProperties: false,
|
|
49
|
-
},
|
|
50
|
-
],
|
|
33
|
+
schema: [],
|
|
51
34
|
messages: {
|
|
52
|
-
preferTrue: 'Use attribute shorthand "{{attr}}" instead of [{{attr}}]="true".
|
|
53
|
-
preferFalse: 'Avoid binding [{{attr}}]="false"; remove the binding if default is false.',
|
|
35
|
+
preferTrue: 'Use attribute shorthand "{{attr}}" instead of [{{attr}}]="true".',
|
|
54
36
|
suggestTrue: 'Replace with attribute shorthand {{attr}}',
|
|
55
|
-
suggestRemove: 'Remove the false binding',
|
|
56
37
|
},
|
|
57
38
|
},
|
|
58
|
-
defaultOptions: [
|
|
59
|
-
{
|
|
60
|
-
allowFalseLiteral: true, // Changed default to true for safety
|
|
61
|
-
},
|
|
62
|
-
],
|
|
39
|
+
defaultOptions: [],
|
|
63
40
|
create(context) {
|
|
64
|
-
// Robust to missing options: default to [{}] if undefined
|
|
65
|
-
const optionsArr = context.options ?? [{}];
|
|
66
|
-
const options = optionsArr[0] ?? {};
|
|
67
|
-
const allowFalseLiteral = options.allowFalseLiteral ?? true; // Default to true for safety
|
|
68
41
|
const parserServices = (0, utils_1.getTemplateParserServices)(context);
|
|
69
42
|
return {
|
|
70
43
|
BoundAttribute(node) {
|
|
@@ -72,14 +45,14 @@ exports.preferBooleanAttributeShorthandRule = {
|
|
|
72
45
|
if (!value || !value.ast)
|
|
73
46
|
return;
|
|
74
47
|
const ast = value.ast;
|
|
48
|
+
// Only check for boolean literals
|
|
75
49
|
if (ast?.constructor?.name === 'LiteralPrimitive' && typeof ast.value === 'boolean') {
|
|
76
|
-
|
|
77
|
-
const loc = parserServices.convertNodeSourceSpanToLoc(node.sourceSpan);
|
|
78
|
-
const start = node.sourceSpan.start.offset;
|
|
79
|
-
const end = node.sourceSpan.end.offset;
|
|
50
|
+
// Only warn for [attr]="true", ignore [attr]="false"
|
|
80
51
|
if (ast.value === true) {
|
|
81
|
-
|
|
82
|
-
|
|
52
|
+
const attrName = node.name;
|
|
53
|
+
const loc = parserServices.convertNodeSourceSpanToLoc(node.sourceSpan);
|
|
54
|
+
const start = node.sourceSpan.start.offset;
|
|
55
|
+
const end = node.sourceSpan.end.offset;
|
|
83
56
|
context.report({
|
|
84
57
|
loc,
|
|
85
58
|
messageId: 'preferTrue',
|
|
@@ -93,21 +66,7 @@ exports.preferBooleanAttributeShorthandRule = {
|
|
|
93
66
|
],
|
|
94
67
|
});
|
|
95
68
|
}
|
|
96
|
-
|
|
97
|
-
// Only flag false bindings if explicitly configured
|
|
98
|
-
context.report({
|
|
99
|
-
loc,
|
|
100
|
-
messageId: 'preferFalse',
|
|
101
|
-
data: { attr: attrName },
|
|
102
|
-
suggest: [
|
|
103
|
-
{
|
|
104
|
-
messageId: 'suggestRemove',
|
|
105
|
-
data: { attr: attrName },
|
|
106
|
-
fix: (fixer) => fixer.replaceTextRange([start, end], ''),
|
|
107
|
-
},
|
|
108
|
-
],
|
|
109
|
-
});
|
|
110
|
-
}
|
|
69
|
+
// [attr]="false" is explicitly ignored - no warning
|
|
111
70
|
}
|
|
112
71
|
},
|
|
113
72
|
};
|
package/package.json
CHANGED