@angular-eslint/eslint-plugin-template 17.0.2-alpha.0 → 17.0.2-alpha.2
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.
- package/README.md +1 -1
- package/dist/rules/attributes-order.js +27 -14
- package/dist/rules/no-negated-async.js +23 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
| [`no-distracting-elements`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-distracting-elements.md) | [Accessibility] Enforces that no distracting elements are used | | :wrench: | | :accessibility: |
|
|
58
58
|
| [`no-inline-styles`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-inline-styles.md) | Disallows the use of inline styles in HTML templates | | | | |
|
|
59
59
|
| [`no-interpolation-in-attributes`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-interpolation-in-attributes.md) | Ensures that property-binding is used instead of interpolation in attributes. | | | | |
|
|
60
|
-
| [`no-negated-async`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-negated-async.md) | Ensures that async pipe results are not negated | :white_check_mark: | | :bulb: | |
|
|
60
|
+
| [`no-negated-async`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-negated-async.md) | Ensures that async pipe results, as well as values used with the async pipe, are not negated | :white_check_mark: | | :bulb: | |
|
|
61
61
|
| [`no-positive-tabindex`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-positive-tabindex.md) | Ensures that the `tabindex` attribute is not positive | | | :bulb: | |
|
|
62
62
|
| [`prefer-ngsrc`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/prefer-ngsrc.md) | Ensures ngSrc is used instead of src for img elements | | | | |
|
|
63
63
|
| [`role-has-required-aria`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/role-has-required-aria.md) | [Accessibility] Ensures elements with ARIA roles have all required properties for that role. | | | :bulb: | :accessibility: |
|
|
@@ -152,10 +152,14 @@ function byOrder(order, alphabetical) {
|
|
|
152
152
|
var _a, _b, _c, _d;
|
|
153
153
|
const orderComparison = getOrderIndex(one, order) - getOrderIndex(other, order);
|
|
154
154
|
if (alphabetical && orderComparison === 0) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
155
|
+
const oneName = (_b = (_a = one.keySpan) === null || _a === void 0 ? void 0 : _a.details) !== null && _b !== void 0 ? _b : one.name;
|
|
156
|
+
const oneNormalised = oneName.replace(/^i18n-/, '');
|
|
157
|
+
const otherName = (_d = (_c = other.keySpan) === null || _c === void 0 ? void 0 : _c.details) !== null && _d !== void 0 ? _d : other.name;
|
|
158
|
+
const otherNormalised = otherName.replace(/^i18n-/, '');
|
|
159
|
+
if (oneNormalised === otherNormalised) {
|
|
160
|
+
return /^i18n-/.test(oneName) ? 1 : -1;
|
|
161
|
+
}
|
|
162
|
+
return oneNormalised > otherNormalised ? 1 : -1;
|
|
159
163
|
}
|
|
160
164
|
return orderComparison;
|
|
161
165
|
};
|
|
@@ -185,6 +189,7 @@ function isImplicitTemplate(node) {
|
|
|
185
189
|
return isTmplAstTemplate(node) && node.tagName !== 'ng-template';
|
|
186
190
|
}
|
|
187
191
|
function extractTemplateAttrs(node) {
|
|
192
|
+
var _a, _b, _c, _d, _e, _f;
|
|
188
193
|
if (isTmplAstTemplate(node)) {
|
|
189
194
|
return node.templateAttrs.map(toStructuralDirectiveOrderType).concat(node.variables.map((x) => {
|
|
190
195
|
return Object.assign(Object.assign({}, toAttributeBindingOrderType(x)), {
|
|
@@ -202,17 +207,25 @@ function extractTemplateAttrs(node) {
|
|
|
202
207
|
* will parsed as two attributes (`ngFor` and `ngForOf`)
|
|
203
208
|
*/
|
|
204
209
|
const attrs = node.parent.templateAttrs.map(toStructuralDirectiveOrderType);
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
210
|
+
let keyEnd = (_a = attrs[0].keySpan) === null || _a === void 0 ? void 0 : _a.end;
|
|
211
|
+
if (((_b = keyEnd === null || keyEnd === void 0 ? void 0 : keyEnd.getContext(0, 0)) === null || _b === void 0 ? void 0 : _b.after) === '=') {
|
|
212
|
+
keyEnd = keyEnd.moveBy(1);
|
|
213
|
+
const apos = (_c = keyEnd.getContext(0, 0)) === null || _c === void 0 ? void 0 : _c.after;
|
|
214
|
+
if (apos === "'" || apos === '"') {
|
|
215
|
+
do {
|
|
216
|
+
keyEnd = keyEnd.moveBy(1);
|
|
217
|
+
} while (((_d = keyEnd.getContext(0, 0)) === null || _d === void 0 ? void 0 : _d.after) !== apos);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
while (!/[\s>]/.test((_f = (_e = keyEnd.getContext(0, 0)) === null || _e === void 0 ? void 0 : _e.after) !== null && _f !== void 0 ? _f : '')) {
|
|
221
|
+
keyEnd = keyEnd.moveBy(1);
|
|
222
|
+
}
|
|
211
223
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
224
|
+
return [
|
|
225
|
+
Object.assign(Object.assign({}, attrs[0]), { sourceSpan: new bundled_angular_compiler_1.ParseSourceSpan(attrs[0].sourceSpan.start, keyEnd) }),
|
|
226
|
+
];
|
|
227
|
+
}
|
|
228
|
+
return [attrs[0]];
|
|
216
229
|
}
|
|
217
230
|
function normalizeInputsOutputs(inputs, outputs) {
|
|
218
231
|
const extractedInputs = inputs
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
|
+
const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
|
|
4
5
|
const utils_1 = require("@angular-eslint/utils");
|
|
5
6
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
6
7
|
exports.RULE_NAME = 'no-negated-async';
|
|
@@ -9,16 +10,18 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
9
10
|
meta: {
|
|
10
11
|
type: 'suggestion',
|
|
11
12
|
docs: {
|
|
12
|
-
description: 'Ensures that async pipe results are not negated',
|
|
13
|
+
description: 'Ensures that async pipe results, as well as values used with the async pipe, are not negated',
|
|
13
14
|
recommended: 'recommended',
|
|
14
15
|
},
|
|
15
16
|
hasSuggestions: true,
|
|
16
17
|
schema: [],
|
|
17
18
|
messages: {
|
|
18
19
|
noNegatedAsync: 'Async pipe results should not be negated. Use `(observable | async) === false`, `(observable | async) === null`, or `(observable | async) === undefined` to check its value instead',
|
|
20
|
+
noNegatedValueForAsync: 'Values used with the async pipe should not be negated.',
|
|
19
21
|
suggestFalseComparison: 'Compare with `false`',
|
|
20
22
|
suggestNullComparison: 'Compare with `null`',
|
|
21
23
|
suggestUndefinedComparison: 'Compare with `undefined`',
|
|
24
|
+
suggestUsingNonNegatedValue: 'Use non-negated value',
|
|
22
25
|
},
|
|
23
26
|
},
|
|
24
27
|
defaultOptions: [],
|
|
@@ -26,6 +29,25 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
26
29
|
(0, utils_1.ensureTemplateParser)(context);
|
|
27
30
|
const sourceCode = context.getSourceCode();
|
|
28
31
|
return {
|
|
32
|
+
'BindingPipe[name="async"]'(bindingPipe) {
|
|
33
|
+
if (bindingPipe.exp instanceof bundled_angular_compiler_1.PrefixNot) {
|
|
34
|
+
const sourceSpanStart = bindingPipe.sourceSpan.start;
|
|
35
|
+
const sourceSpanEnd = bindingPipe.sourceSpan.end;
|
|
36
|
+
context.report({
|
|
37
|
+
messageId: 'noNegatedValueForAsync',
|
|
38
|
+
loc: {
|
|
39
|
+
start: sourceCode.getLocFromIndex(sourceSpanStart),
|
|
40
|
+
end: sourceCode.getLocFromIndex(sourceSpanEnd),
|
|
41
|
+
},
|
|
42
|
+
suggest: [
|
|
43
|
+
{
|
|
44
|
+
messageId: 'suggestUsingNonNegatedValue',
|
|
45
|
+
fix: (fixer) => fixer.removeRange([sourceSpanStart, sourceSpanStart + 1]),
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
},
|
|
29
51
|
':not(PrefixNot) > PrefixNot > BindingPipe[name="async"]'({ parent: { sourceSpan: { end, start }, }, }) {
|
|
30
52
|
context.report({
|
|
31
53
|
messageId: 'noNegatedAsync',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-eslint/eslint-plugin-template",
|
|
3
|
-
"version": "17.0.2-alpha.
|
|
3
|
+
"version": "17.0.2-alpha.2",
|
|
4
4
|
"description": "ESLint plugin for Angular Templates",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"LICENSE"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@angular-eslint/bundled-angular-compiler": "17.0.2-alpha.
|
|
21
|
-
"@angular-eslint/utils": "17.0.2-alpha.
|
|
20
|
+
"@angular-eslint/bundled-angular-compiler": "17.0.2-alpha.2",
|
|
21
|
+
"@angular-eslint/utils": "17.0.2-alpha.2",
|
|
22
22
|
"@typescript-eslint/type-utils": "6.10.0",
|
|
23
23
|
"@typescript-eslint/utils": "6.10.0",
|
|
24
24
|
"aria-query": "5.3.0",
|