@angular-eslint/eslint-plugin-template 19.3.1-alpha.2 → 19.3.1-alpha.21
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/dist/index.d.ts +1 -1
- package/dist/index.js +17 -7
- package/dist/processors.d.ts.map +1 -1
- package/dist/processors.js +21 -4
- package/dist/rules/no-any.d.ts.map +1 -1
- package/dist/rules/no-any.js +53 -25
- package/dist/rules/no-interpolation-in-attributes.d.ts +4 -2
- package/dist/rules/no-interpolation-in-attributes.d.ts.map +1 -1
- package/dist/rules/no-interpolation-in-attributes.js +27 -3
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -103,7 +103,7 @@ declare const _default: {
|
|
|
103
103
|
"no-distracting-elements": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noDistractingElements", [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
104
104
|
"no-duplicate-attributes": import("@typescript-eslint/utils/ts-eslint").RuleModule<import("./rules/no-duplicate-attributes").MessageIds, import("./rules/no-duplicate-attributes").Options, import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
105
105
|
"no-inline-styles": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noInlineStyles", import("./rules/no-inline-styles").Options, import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
106
|
-
"no-interpolation-in-attributes": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noInterpolationInAttributes",
|
|
106
|
+
"no-interpolation-in-attributes": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noInterpolationInAttributes", import("./rules/no-interpolation-in-attributes").Options, import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
107
107
|
"no-negated-async": import("@typescript-eslint/utils/ts-eslint").RuleModule<import("./rules/no-negated-async").MessageIds, [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
108
108
|
"no-positive-tabindex": import("@typescript-eslint/utils/ts-eslint").RuleModule<import("./rules/no-positive-tabindex").MessageIds, [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
109
109
|
"prefer-contextual-for-variables": import("@typescript-eslint/utils/ts-eslint").RuleModule<import("./rules/prefer-contextual-for-variables").MessageIds, import("./rules/prefer-contextual-for-variables").Options, import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
package/dist/index.js
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
package/dist/processors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processors.d.ts","sourceRoot":"","sources":["../src/processors.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,wBAAgB,0CAA0C,CACxD,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CA2BT;AAED,KAAK,gBAAgB,GAAG,CAAC,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,CAAC;AAExE,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,gBAAgB,
|
|
1
|
+
{"version":3,"file":"processors.d.ts","sourceRoot":"","sources":["../src/processors.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,wBAAgB,0CAA0C,CACxD,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CA2BT;AAED,KAAK,gBAAgB,GAAG,CAAC,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,CAAC;AAExE,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,gBAAgB,CAqJlB;AAyDD,wBAAgB,wBAAwB,CACtC,wBAAwB,EAAE;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE;QACJ,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH,EAAE,EAAE,EACL,QAAQ,EAAE,MAAM,GACf,SAAS,OAAO,EAAE,CAmEpB;;;;;;;;;;;AAED,wBASE"}
|
package/dist/processors.js
CHANGED
|
@@ -110,7 +110,9 @@ function preprocessComponentFile(text, filename) {
|
|
|
110
110
|
templateText = templatePropertyInitializer.rawText;
|
|
111
111
|
}
|
|
112
112
|
if (typescript_1.default.isTemplateExpression(templatePropertyInitializer)) {
|
|
113
|
-
|
|
113
|
+
// The text includes the opening and closing
|
|
114
|
+
// backtick, so trim the first and last characters.
|
|
115
|
+
templateText = templatePropertyInitializer.getText().slice(1, -1);
|
|
114
116
|
}
|
|
115
117
|
if (typescript_1.default.isStringLiteral(templatePropertyInitializer)) {
|
|
116
118
|
templateText = templatePropertyInitializer.text;
|
|
@@ -222,10 +224,25 @@ function postprocessComponentFile(multiDimensionalMessages, filename) {
|
|
|
222
224
|
return [];
|
|
223
225
|
}
|
|
224
226
|
return messagesFromInlineTemplateHTML.map((message) => {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
227
|
+
// The first line of the inline template starts at the column after
|
|
228
|
+
// the opening quote in the TypeScript file, so we need to adjust
|
|
229
|
+
// the message's column by that amount when the message starts on
|
|
230
|
+
// the first line. The character we recorded was the quote's column,
|
|
231
|
+
// so add one to get the column where the actual string starts.
|
|
232
|
+
if (message.line === 1) {
|
|
233
|
+
message.column += rangeData.lineAndCharacter.start.character + 1;
|
|
234
|
+
}
|
|
235
|
+
// The same thing applies to the end column
|
|
236
|
+
// if it also ends on the first line.
|
|
237
|
+
if (message.endLine === 1) {
|
|
238
|
+
message.endColumn += rangeData.lineAndCharacter.start.character + 1;
|
|
239
|
+
}
|
|
240
|
+
message.line += rangeData.lineAndCharacter.start.line;
|
|
241
|
+
message.endLine += rangeData.lineAndCharacter.start.line;
|
|
228
242
|
if (message.fix) {
|
|
243
|
+
// The range defines the range of the value that initializes
|
|
244
|
+
// the `template` property, which includes the opening and
|
|
245
|
+
// closing quotes. Add one to move past the opening quote.
|
|
229
246
|
const startOffset = rangeData.range[0] + 1;
|
|
230
247
|
message.fix.range = [
|
|
231
248
|
startOffset + message.fix.range[0],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-any.d.ts","sourceRoot":"","sources":["../../src/rules/no-any.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-any.d.ts","sourceRoot":"","sources":["../../src/rules/no-any.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,kBAAkB,CAAC;AACtD,eAAO,MAAM,SAAS,WAAW,CAAC;;AAGlC,wBA0FG"}
|
package/dist/rules/no-any.js
CHANGED
|
@@ -24,34 +24,62 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
24
24
|
create(context) {
|
|
25
25
|
(0, utils_1.ensureTemplateParser)(context);
|
|
26
26
|
const sourceCode = context.sourceCode;
|
|
27
|
+
const isAnyCall = (node) => {
|
|
28
|
+
if (!(node.receiver instanceof bundled_angular_compiler_1.PropertyRead)) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
if (node.receiver.name !== ANY_TYPE_CAST_FUNCTION_NAME) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
if (!(
|
|
35
|
+
// this.$any() is also valid usage of the native Angular $any()
|
|
36
|
+
(node.receiver.receiver instanceof bundled_angular_compiler_1.ThisReceiver ||
|
|
37
|
+
node.receiver.receiver instanceof bundled_angular_compiler_1.ImplicitReceiver))) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return true;
|
|
41
|
+
};
|
|
42
|
+
const reportAnyCall = (node) => {
|
|
43
|
+
const { start, end } = node.sourceSpan;
|
|
44
|
+
const nameSpan = node.receiver.nameSpan;
|
|
45
|
+
context.report({
|
|
46
|
+
messageId: 'noAny',
|
|
47
|
+
loc: {
|
|
48
|
+
start: sourceCode.getLocFromIndex(start),
|
|
49
|
+
end: sourceCode.getLocFromIndex(end),
|
|
50
|
+
},
|
|
51
|
+
suggest: [
|
|
52
|
+
{
|
|
53
|
+
messageId: 'suggestRemoveAny',
|
|
54
|
+
fix: (fixer) => [
|
|
55
|
+
fixer.removeRange([nameSpan.start, nameSpan.end + 1]),
|
|
56
|
+
fixer.removeRange([end - 1, end]),
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Handles KeyedRead.KeyedRead cases like
|
|
64
|
+
* $any(attributeList)['NPSScore']['another']
|
|
65
|
+
*/
|
|
66
|
+
const findAndReportAnyCalls = (node) => {
|
|
67
|
+
if (node instanceof bundled_angular_compiler_1.Call && isAnyCall(node)) {
|
|
68
|
+
reportAnyCall(node);
|
|
69
|
+
}
|
|
70
|
+
else if (node instanceof bundled_angular_compiler_1.KeyedRead) {
|
|
71
|
+
findAndReportAnyCalls(node.receiver);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
27
74
|
return {
|
|
28
|
-
[`Call[receiver.name="${ANY_TYPE_CAST_FUNCTION_NAME}"]`](
|
|
29
|
-
if (!(
|
|
75
|
+
[`Call[receiver.name="${ANY_TYPE_CAST_FUNCTION_NAME}"]`](node) {
|
|
76
|
+
if (!isAnyCall(node)) {
|
|
30
77
|
return;
|
|
31
78
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const nameSpan = receiver.nameSpan;
|
|
39
|
-
context.report({
|
|
40
|
-
messageId: 'noAny',
|
|
41
|
-
loc: {
|
|
42
|
-
start: sourceCode.getLocFromIndex(start),
|
|
43
|
-
end: sourceCode.getLocFromIndex(end),
|
|
44
|
-
},
|
|
45
|
-
suggest: [
|
|
46
|
-
{
|
|
47
|
-
messageId: 'suggestRemoveAny',
|
|
48
|
-
fix: (fixer) => [
|
|
49
|
-
fixer.removeRange([nameSpan.start, nameSpan.end + 1]),
|
|
50
|
-
fixer.removeRange([end - 1, end]),
|
|
51
|
-
],
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
});
|
|
79
|
+
reportAnyCall(node);
|
|
80
|
+
},
|
|
81
|
+
KeyedRead(node) {
|
|
82
|
+
findAndReportAnyCalls(node);
|
|
55
83
|
},
|
|
56
84
|
};
|
|
57
85
|
},
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
export type Options = [
|
|
1
|
+
export type Options = [{
|
|
2
|
+
allowSubstringInterpolation: boolean;
|
|
3
|
+
}];
|
|
2
4
|
export type MessageIds = 'noInterpolationInAttributes';
|
|
3
5
|
export declare const RULE_NAME = "no-interpolation-in-attributes";
|
|
4
|
-
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"noInterpolationInAttributes",
|
|
6
|
+
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"noInterpolationInAttributes", Options, import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
7
|
export default _default;
|
|
6
8
|
//# sourceMappingURL=no-interpolation-in-attributes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-interpolation-in-attributes.d.ts","sourceRoot":"","sources":["../../src/rules/no-interpolation-in-attributes.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"no-interpolation-in-attributes.d.ts","sourceRoot":"","sources":["../../src/rules/no-interpolation-in-attributes.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,OAAO,GAAG,CAAC;IAAE,2BAA2B,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AACjE,MAAM,MAAM,UAAU,GAAG,6BAA6B,CAAC;AACvD,eAAO,MAAM,SAAS,mCAAmC,CAAC;;AAY1D,wBAmDG"}
|
|
@@ -3,6 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.RULE_NAME = void 0;
|
|
4
4
|
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
5
5
|
exports.RULE_NAME = 'no-interpolation-in-attributes';
|
|
6
|
+
const allowSubstringInterpolationDescription = `\
|
|
7
|
+
When \`true\`, only attribute values that are entirely interpolations will fail, whereas values with interpolations that form part of larger strings will be allowed.
|
|
8
|
+
|
|
9
|
+
For example, when set to \`true\` the following code will not fail for the \`alt\` attribute but will still fail for the \`src\` attribute:
|
|
10
|
+
|
|
11
|
+
\`\`\`html
|
|
12
|
+
<img alt="Poke user {{ username }}" src="{{ pokeSrc }}" />
|
|
13
|
+
\`\`\`
|
|
14
|
+
`;
|
|
6
15
|
exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
7
16
|
name: exports.RULE_NAME,
|
|
8
17
|
meta: {
|
|
@@ -10,16 +19,31 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
10
19
|
docs: {
|
|
11
20
|
description: 'Ensures that property-binding is used instead of interpolation in attributes.',
|
|
12
21
|
},
|
|
13
|
-
schema: [
|
|
22
|
+
schema: [
|
|
23
|
+
{
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
allowSubstringInterpolation: {
|
|
27
|
+
type: 'boolean',
|
|
28
|
+
description: allowSubstringInterpolationDescription,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
additionalProperties: false,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
14
34
|
messages: {
|
|
15
35
|
noInterpolationInAttributes: 'Use property binding [attribute]="value" instead of interpolation {{ value }} for an attribute.',
|
|
16
36
|
},
|
|
17
37
|
},
|
|
18
|
-
defaultOptions: [],
|
|
19
|
-
create(context) {
|
|
38
|
+
defaultOptions: [{ allowSubstringInterpolation: false }],
|
|
39
|
+
create(context, [{ allowSubstringInterpolation }]) {
|
|
20
40
|
const sourceCode = context.sourceCode;
|
|
21
41
|
return {
|
|
22
42
|
['BoundAttribute Interpolation'](interpolation) {
|
|
43
|
+
if (allowSubstringInterpolation &&
|
|
44
|
+
interpolation.strings.some((str) => str !== '')) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
23
47
|
const { sourceSpan: { start, end }, } = interpolation;
|
|
24
48
|
context.report({
|
|
25
49
|
loc: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-eslint/eslint-plugin-template",
|
|
3
|
-
"version": "19.3.1-alpha.
|
|
3
|
+
"version": "19.3.1-alpha.21",
|
|
4
4
|
"description": "ESLint plugin for Angular Templates",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"aria-query": "5.3.2",
|
|
22
22
|
"axobject-query": "4.1.0",
|
|
23
|
-
"@angular-eslint/bundled-angular-compiler": "19.3.1-alpha.
|
|
24
|
-
"@angular-eslint/utils": "19.3.1-alpha.
|
|
23
|
+
"@angular-eslint/bundled-angular-compiler": "19.3.1-alpha.21",
|
|
24
|
+
"@angular-eslint/utils": "19.3.1-alpha.21"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/aria-query": "5.0.4",
|
|
28
|
-
"@angular-eslint/template-parser": "19.3.1-alpha.
|
|
29
|
-
"@angular-eslint/test-utils": "19.3.1-alpha.
|
|
28
|
+
"@angular-eslint/template-parser": "19.3.1-alpha.21",
|
|
29
|
+
"@angular-eslint/test-utils": "19.3.1-alpha.21"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"@typescript-eslint/types": "^7.11.0 || ^8.0.0",
|