@angular-eslint/eslint-plugin-template 22.0.1-alpha.8 → 22.1.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.
- package/README.md +2 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/rules/button-has-type.d.ts.map +1 -1
- package/dist/rules/click-events-have-key-events.d.ts.map +1 -1
- package/dist/rules/conditional-complexity.d.ts.map +1 -1
- package/dist/rules/i18n.d.ts.map +1 -1
- package/dist/rules/no-any.d.ts.map +1 -1
- package/dist/rules/no-any.js +2 -2
- package/dist/rules/no-duplicate-attributes.d.ts.map +1 -1
- package/dist/rules/no-outerhtml.d.ts +11 -0
- package/dist/rules/no-outerhtml.d.ts.map +1 -0
- package/dist/rules/no-outerhtml.js +40 -0
- package/dist/rules/prefer-at-empty.d.ts.map +1 -1
- package/dist/rules/prefer-contextual-for-variables.d.ts.map +1 -1
- package/dist/rules/prefer-template-literal.d.ts.map +1 -1
- package/dist/rules/require-switch-default.d.ts +11 -0
- package/dist/rules/require-switch-default.d.ts.map +1 -0
- package/dist/rules/require-switch-default.js +41 -0
- package/dist/rules/valid-aria.d.ts.map +1 -1
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@ The premade flat configs that combine these rules are provided by the umbrella [
|
|
|
24
24
|
| --- | --- | --- | --- | --- | --- |
|
|
25
25
|
| [`no-duplicate-attributes`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-duplicate-attributes.md) | Ensures that there are no duplicate input properties or output event listeners | | | :bulb: | |
|
|
26
26
|
| [`no-nested-tags`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-nested-tags.md) | Denies nesting of `<p>` and `<a>` tags. | | | | |
|
|
27
|
+
| [`no-outerhtml`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-outerhtml.md) | Disallows using `outerHTML` on elements, which breaks change detection and detaches the element from the Angular view | | | | |
|
|
27
28
|
<!-- prettier-ignore-end -->
|
|
28
29
|
|
|
29
30
|
<!-- end problems rule list -->
|
|
@@ -72,6 +73,7 @@ The premade flat configs that combine these rules are provided by the umbrella [
|
|
|
72
73
|
| [`prefer-control-flow`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/prefer-control-flow.md) | Ensures that the built-in control flow is used. | :white_check_mark: | | | |
|
|
73
74
|
| [`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 | | | :bulb: | |
|
|
74
75
|
| [`prefer-template-literal`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/prefer-template-literal.md) | Ensure that template literals are used instead of concatenating strings or expressions. | | :wrench: | | |
|
|
76
|
+
| [`require-switch-default`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/require-switch-default.md) | Requires a `@default` block on every `@switch` to ensure all cases are handled. This is the template equivalent of the `@typescript-eslint/switch-exhaustiveness-check` rule. | | | | |
|
|
75
77
|
| [`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: |
|
|
76
78
|
| [`table-scope`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/table-scope.md) | [Accessibility] Ensures that the `scope` attribute is only used on the `<th>` element | | :wrench: | | :accessibility: |
|
|
77
79
|
| [`use-track-by-function`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/use-track-by-function.md) | Ensures trackBy function is used | | | | |
|
package/dist/index.d.ts
CHANGED
|
@@ -85,6 +85,9 @@ declare const _default: {
|
|
|
85
85
|
"no-non-null-assertion": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noNonNullAssertion", [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
86
86
|
name: string;
|
|
87
87
|
};
|
|
88
|
+
"no-outerhtml": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noOuterHtml", [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
89
|
+
name: string;
|
|
90
|
+
};
|
|
88
91
|
"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> & {
|
|
89
92
|
name: string;
|
|
90
93
|
};
|
|
@@ -115,6 +118,9 @@ declare const _default: {
|
|
|
115
118
|
"prefer-template-literal": import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferTemplateLiteral", [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
116
119
|
name: string;
|
|
117
120
|
};
|
|
121
|
+
"require-switch-default": import("@typescript-eslint/utils/ts-eslint").RuleModule<"requireSwitchDefault", [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
122
|
+
name: string;
|
|
123
|
+
};
|
|
118
124
|
"role-has-required-aria": import("@typescript-eslint/utils/ts-eslint").RuleModule<import("./rules/role-has-required-aria").MessageIds, [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
119
125
|
name: string;
|
|
120
126
|
};
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmHA,kBA6CE"}
|
package/dist/index.js
CHANGED
|
@@ -61,6 +61,7 @@ const no_interpolation_in_attributes_1 = __importStar(require("./rules/no-interp
|
|
|
61
61
|
const no_negated_async_1 = __importStar(require("./rules/no-negated-async"));
|
|
62
62
|
const no_nested_tags_1 = __importStar(require("./rules/no-nested-tags"));
|
|
63
63
|
const no_non_null_assertion_1 = __importStar(require("./rules/no-non-null-assertion"));
|
|
64
|
+
const no_outerhtml_1 = __importStar(require("./rules/no-outerhtml"));
|
|
64
65
|
const no_positive_tabindex_1 = __importStar(require("./rules/no-positive-tabindex"));
|
|
65
66
|
const prefer_ngsrc_1 = __importStar(require("./rules/prefer-ngsrc"));
|
|
66
67
|
const prefer_at_else_1 = __importStar(require("./rules/prefer-at-else"));
|
|
@@ -71,6 +72,7 @@ const prefer_control_flow_1 = __importStar(require("./rules/prefer-control-flow"
|
|
|
71
72
|
const prefer_self_closing_tags_1 = __importStar(require("./rules/prefer-self-closing-tags"));
|
|
72
73
|
const prefer_static_string_properties_1 = __importStar(require("./rules/prefer-static-string-properties"));
|
|
73
74
|
const prefer_template_literal_1 = __importStar(require("./rules/prefer-template-literal"));
|
|
75
|
+
const require_switch_default_1 = __importStar(require("./rules/require-switch-default"));
|
|
74
76
|
const role_has_required_aria_1 = __importStar(require("./rules/role-has-required-aria"));
|
|
75
77
|
const table_scope_1 = __importStar(require("./rules/table-scope"));
|
|
76
78
|
const use_track_by_function_1 = __importStar(require("./rules/use-track-by-function"));
|
|
@@ -103,6 +105,7 @@ module.exports = {
|
|
|
103
105
|
[no_negated_async_1.RULE_NAME]: no_negated_async_1.default,
|
|
104
106
|
[no_nested_tags_1.RULE_NAME]: no_nested_tags_1.default,
|
|
105
107
|
[no_non_null_assertion_1.RULE_NAME]: no_non_null_assertion_1.default,
|
|
108
|
+
[no_outerhtml_1.RULE_NAME]: no_outerhtml_1.default,
|
|
106
109
|
[no_positive_tabindex_1.RULE_NAME]: no_positive_tabindex_1.default,
|
|
107
110
|
[prefer_at_else_1.RULE_NAME]: prefer_at_else_1.default,
|
|
108
111
|
[prefer_at_empty_1.RULE_NAME]: prefer_at_empty_1.default,
|
|
@@ -113,6 +116,7 @@ module.exports = {
|
|
|
113
116
|
[prefer_self_closing_tags_1.RULE_NAME]: prefer_self_closing_tags_1.default,
|
|
114
117
|
[prefer_static_string_properties_1.RULE_NAME]: prefer_static_string_properties_1.default,
|
|
115
118
|
[prefer_template_literal_1.RULE_NAME]: prefer_template_literal_1.default,
|
|
119
|
+
[require_switch_default_1.RULE_NAME]: require_switch_default_1.default,
|
|
116
120
|
[role_has_required_aria_1.RULE_NAME]: role_has_required_aria_1.default,
|
|
117
121
|
[table_scope_1.RULE_NAME]: table_scope_1.default,
|
|
118
122
|
[use_track_by_function_1.RULE_NAME]: use_track_by_function_1.default,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button-has-type.d.ts","sourceRoot":"","sources":["../../src/rules/button-has-type.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC1C;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,aAAa,CAAC;AACvD,eAAO,MAAM,SAAS,oBAAoB,CAAC;AAI3C,eAAO,MAAM,qBAAqB,SAAS,CAAC;;;;AAW5C,
|
|
1
|
+
{"version":3,"file":"button-has-type.d.ts","sourceRoot":"","sources":["../../src/rules/button-has-type.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC1C;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,aAAa,CAAC;AACvD,eAAO,MAAM,SAAS,oBAAoB,CAAC;AAI3C,eAAO,MAAM,qBAAqB,SAAS,CAAC;;;;AAW5C,wBA2DG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"click-events-have-key-events.d.ts","sourceRoot":"","sources":["../../src/rules/click-events-have-key-events.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC1C;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,0BAA0B,CAAC;AACpD,eAAO,MAAM,SAAS,iCAAiC,CAAC;;;;AAKxD,
|
|
1
|
+
{"version":3,"file":"click-events-have-key-events.d.ts","sourceRoot":"","sources":["../../src/rules/click-events-have-key-events.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC1C;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,0BAA0B,CAAC;AACpD,eAAO,MAAM,SAAS,iCAAiC,CAAC;;;;AAKxD,wBA8EG;AAsBH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditional-complexity.d.ts","sourceRoot":"","sources":["../../src/rules/conditional-complexity.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,OAAO,GAAG,CAAC;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,uBAAuB,CAAC;AACjD,eAAO,MAAM,SAAS,2BAA2B,CAAC;;;;AAIlD,wBAsFG;
|
|
1
|
+
{"version":3,"file":"conditional-complexity.d.ts","sourceRoot":"","sources":["../../src/rules/conditional-complexity.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,OAAO,GAAG,CAAC;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,uBAAuB,CAAC;AACjD,eAAO,MAAM,SAAS,2BAA2B,CAAC;;;;AAIlD,wBAsFG;AA2DH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
package/dist/rules/i18n.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/rules/i18n.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AA6CnE,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;QACxC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;QAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;QACnC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;QACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAC7B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACxC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;QACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;KACnC;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAClB,eAAe,GACf,0BAA0B,GAC1B,yBAAyB,GACzB,uBAAuB,GACvB,uBAAuB,GACvB,yBAAyB,GACzB,wBAAwB,GACxB,oBAAoB,GACpB,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/rules/i18n.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AA6CnE,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;QACxC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;QAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;QACnC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;QACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAC7B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACxC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;QACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;KACnC;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAClB,eAAe,GACf,0BAA0B,GAC1B,yBAAyB,GACzB,uBAAuB,GACvB,uBAAuB,GACvB,yBAAyB,GACzB,wBAAwB,GACxB,oBAAoB,GACpB,qBAAqB,CAAC;AAmB1B,eAAO,MAAM,SAAS,SAAS,CAAC;;;;AAkBhC,wBAsUG;AAqJH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,wBAmFG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
package/dist/rules/no-any.js
CHANGED
|
@@ -33,8 +33,8 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
|
33
33
|
}
|
|
34
34
|
if (!(
|
|
35
35
|
// this.$any() is also valid usage of the native Angular $any()
|
|
36
|
-
|
|
37
|
-
node.receiver.receiver instanceof bundled_angular_compiler_1.ImplicitReceiver))
|
|
36
|
+
node.receiver.receiver instanceof bundled_angular_compiler_1.ThisReceiver ||
|
|
37
|
+
node.receiver.receiver instanceof bundled_angular_compiler_1.ImplicitReceiver)) {
|
|
38
38
|
return false;
|
|
39
39
|
}
|
|
40
40
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-duplicate-attributes.d.ts","sourceRoot":"","sources":["../../src/rules/no-duplicate-attributes.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;QAC1C,QAAQ,CAAC,8BAA8B,CAAC,EAAE,OAAO,CAAC;QAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;KACrC;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,uBAAuB,GAAG,wBAAwB,CAAC;AAC5E,eAAO,MAAM,SAAS,4BAA4B,CAAC;;;;AAOnD,wBA2IG;
|
|
1
|
+
{"version":3,"file":"no-duplicate-attributes.d.ts","sourceRoot":"","sources":["../../src/rules/no-duplicate-attributes.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;QAC1C,QAAQ,CAAC,8BAA8B,CAAC,EAAE,OAAO,CAAC;QAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;KACrC;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAAG,uBAAuB,GAAG,wBAAwB,CAAC;AAC5E,eAAO,MAAM,SAAS,4BAA4B,CAAC;;;;AAOnD,wBA2IG;AAgBH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type Options = [];
|
|
2
|
+
export type MessageIds = 'noOuterHtml';
|
|
3
|
+
export declare const RULE_NAME = "no-outerhtml";
|
|
4
|
+
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"noOuterHtml", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
5
|
+
name: string;
|
|
6
|
+
};
|
|
7
|
+
export default _default;
|
|
8
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
9
|
+
rationale: string;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=no-outerhtml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-outerhtml.d.ts","sourceRoot":"","sources":["../../src/rules/no-outerhtml.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,aAAa,CAAC;AACvC,eAAO,MAAM,SAAS,iBAAiB,CAAC;;;;AAExC,wBAoCG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
|
+
const utils_1 = require("@angular-eslint/utils");
|
|
5
|
+
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
6
|
+
const get_dom_elements_1 = require("../utils/get-dom-elements");
|
|
7
|
+
const to_pattern_1 = require("../utils/to-pattern");
|
|
8
|
+
exports.RULE_NAME = 'no-outerhtml';
|
|
9
|
+
exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
10
|
+
name: exports.RULE_NAME,
|
|
11
|
+
meta: {
|
|
12
|
+
type: 'problem',
|
|
13
|
+
docs: {
|
|
14
|
+
description: 'Disallows using `outerHTML` on elements, which breaks change detection and detaches the element from the Angular view',
|
|
15
|
+
},
|
|
16
|
+
schema: [],
|
|
17
|
+
messages: {
|
|
18
|
+
noOuterHtml: 'Do not use `outerHTML`. Binding to `[outerHTML]` throws on update because setting `outerHTML` replaces the host element itself, so Angular loses its reference to the node ("This element has no parent node"); a static `outerHTML` attribute is not a real DOM attribute and has no effect. Use `[innerHTML]` (being mindful of sanitization) or restructure the template instead.',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
defaultOptions: [],
|
|
22
|
+
create(context) {
|
|
23
|
+
const parserServices = (0, utils_1.getTemplateParserServices)(context);
|
|
24
|
+
const elementNamePattern = (0, to_pattern_1.toPattern)([...(0, get_dom_elements_1.getDomElements)()]);
|
|
25
|
+
return {
|
|
26
|
+
[`Element[name=${elementNamePattern}] > :matches(BoundAttribute, TextAttribute)`](node) {
|
|
27
|
+
if (node.name.toLowerCase() !== 'outerhtml') {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
context.report({
|
|
31
|
+
loc: parserServices.convertNodeSourceSpanToLoc(node.keySpan ?? node.sourceSpan),
|
|
32
|
+
messageId: 'noOuterHtml',
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
39
|
+
rationale: "Setting an element's `outerHTML` replaces the element itself in the DOM, including the very node Angular is bound to. Angular keeps an internal reference to that node in order to apply future updates during change detection. Once the node has been swapped out, it no longer has a parent in the document, so the next attempt to write to `outerHTML` fails with `NoModificationAllowedError: Failed to set the 'outerHTML' property on 'Element': This element has no parent node`. The initial render appears to work, which makes the problem easy to miss until the bound value changes at runtime or in a test that calls `detectChanges()`.\n\nBecause this is inherent to how `outerHTML` works — not a fixable framework bug (see angular/angular#41131 and angular/angular#41576, both closed) — there is effectively no correct way to use `outerHTML` in an Angular template. A static `outerHTML=\"...\"` attribute is not a real DOM attribute either and simply has no effect, so this rule disallows every form of `outerHTML` on native elements (`[outerHTML]`, `bind-outerHTML`, `[attr.outerHTML]` and the static attribute). Bindings to `outerHTML` on components are left alone, since there they are ordinary inputs rather than the DOM property.\n\nIn almost all cases the intent is to render dynamic markup inside the element, which is exactly what `[innerHTML]` does safely (it only replaces the element's content and preserves the host node). Note that `[innerHTML]` runs Angular's built-in sanitization; when rendering untrusted content, sanitization concerns still apply. If the goal was actually to replace the element (tag, attributes and all), the component should be restructured — for example by conditionally rendering different elements with `@if`/`@switch` — rather than reaching for `outerHTML`.",
|
|
40
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-at-empty.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-at-empty.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,eAAe,CAAC;AACzC,eAAO,MAAM,SAAS,oBAAoB,CAAC;;;;AAE3C,wBAwaG;
|
|
1
|
+
{"version":3,"file":"prefer-at-empty.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-at-empty.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,eAAe,CAAC;AACzC,eAAO,MAAM,SAAS,oBAAoB,CAAC;;;;AAE3C,wBAwaG;AAwLH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-contextual-for-variables.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-contextual-for-variables.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,cAAc,CAAC,EAAE;YACxB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC1B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;SAC1B,CAAC;KACH;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAClB,0BAA0B,GAC1B,aAAa,GACb,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,WAAW,CAAC;AAChB,eAAO,MAAM,SAAS,oCAAoC,CAAC;;;;AAc3D,wBAkaG;
|
|
1
|
+
{"version":3,"file":"prefer-contextual-for-variables.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-contextual-for-variables.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,OAAO,GAAG;IACpB;QACE,QAAQ,CAAC,cAAc,CAAC,EAAE;YACxB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC3B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC1B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;SAC1B,CAAC;KACH;CACF,CAAC;AACF,MAAM,MAAM,UAAU,GAClB,0BAA0B,GAC1B,aAAa,GACb,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,WAAW,CAAC;AAChB,eAAO,MAAM,SAAS,oCAAoC,CAAC;;;;AAc3D,wBAkaG;AAkRH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-template-literal.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-template-literal.ts"],"names":[],"mappings":"AAeA,QAAA,MAAM,SAAS,0BAA0B,CAAC;AAE1C,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,OAAO,SAAS,CAAC;AAC1C,eAAO,MAAM,SAAS,4BAA4B,CAAC;;;;
|
|
1
|
+
{"version":3,"file":"prefer-template-literal.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-template-literal.ts"],"names":[],"mappings":"AAeA,QAAA,MAAM,SAAS,0BAA0B,CAAC;AAE1C,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,OAAO,SAAS,CAAC;AAC1C,eAAO,MAAM,SAAS,4BAA4B,CAAC;;;;AA6FnD,wBAiKG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type Options = [];
|
|
2
|
+
export type MessageIds = 'requireSwitchDefault';
|
|
3
|
+
export declare const RULE_NAME = "require-switch-default";
|
|
4
|
+
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"requireSwitchDefault", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
5
|
+
name: string;
|
|
6
|
+
};
|
|
7
|
+
export default _default;
|
|
8
|
+
export declare const RULE_DOCS_EXTENSION: {
|
|
9
|
+
rationale: string;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=require-switch-default.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"require-switch-default.d.ts","sourceRoot":"","sources":["../../src/rules/require-switch-default.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAChD,eAAO,MAAM,SAAS,2BAA2B,CAAC;;;;AAElD,wBAuCG;AAEH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RULE_DOCS_EXTENSION = exports.RULE_NAME = void 0;
|
|
4
|
+
const utils_1 = require("@angular-eslint/utils");
|
|
5
|
+
const create_eslint_rule_1 = require("../utils/create-eslint-rule");
|
|
6
|
+
exports.RULE_NAME = 'require-switch-default';
|
|
7
|
+
exports.default = (0, create_eslint_rule_1.createESLintRule)({
|
|
8
|
+
name: exports.RULE_NAME,
|
|
9
|
+
meta: {
|
|
10
|
+
type: 'suggestion',
|
|
11
|
+
docs: {
|
|
12
|
+
description: 'Requires a `@default` block on every `@switch` to ensure all cases are handled. This is the template equivalent of the `@typescript-eslint/switch-exhaustiveness-check` rule.',
|
|
13
|
+
},
|
|
14
|
+
schema: [],
|
|
15
|
+
messages: {
|
|
16
|
+
requireSwitchDefault: 'Switch should have a default block. Add `@default { ... }`, or `@default never` to enforce a compile-time exhaustive switch.',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
defaultOptions: [],
|
|
20
|
+
create(context) {
|
|
21
|
+
const parserServices = (0, utils_1.getTemplateParserServices)(context);
|
|
22
|
+
return {
|
|
23
|
+
SwitchBlock({ exhaustiveCheck, groups, nameSpan }) {
|
|
24
|
+
if (exhaustiveCheck) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const hasDefaultCase = groups.some(({ cases }) => cases.some(({ expression }) => expression === null));
|
|
28
|
+
if (hasDefaultCase) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
context.report({
|
|
32
|
+
loc: parserServices.convertNodeSourceSpanToLoc(nameSpan),
|
|
33
|
+
messageId: 'requireSwitchDefault',
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
exports.RULE_DOCS_EXTENSION = {
|
|
40
|
+
rationale: "A `@switch` without a `@default` silently renders nothing when the value matches none of the `@case` branches, which is rarely intended and easy to miss. Because Angular templates are not type-checked the way TypeScript code is, the linter cannot determine whether the listed cases are exhaustive over a union or enum. Requiring an explicit `@default` block ensures unhandled values are always accounted for. For genuine compile-time exhaustiveness over a union or enum, use Angular's `@default never` form, which fails the template type-check if any case is missing.",
|
|
41
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"valid-aria.d.ts","sourceRoot":"","sources":["../../src/rules/valid-aria.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"valid-aria.d.ts","sourceRoot":"","sources":["../../src/rules/valid-aria.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GACpB,WAAW,GAAG,gBAAgB,GAAG,0BAA0B,CAAC;AAC9D,eAAO,MAAM,SAAS,eAAe,CAAC;;;;AAEtC,wBA8EG;AA0FH,eAAO,MAAM,mBAAmB;;CAG/B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-eslint/eslint-plugin-template",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.1.0",
|
|
4
4
|
"description": "ESLint plugin for Angular Templates",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"url": "https://github.com/angular-eslint/angular-eslint.git",
|
|
11
11
|
"directory": "packages/eslint-plugin-template"
|
|
12
12
|
},
|
|
13
|
+
"bugs": "https://github.com/angular-eslint/angular-eslint/issues",
|
|
13
14
|
"files": [
|
|
14
15
|
"dist",
|
|
15
16
|
"!**/*.tsbuildinfo",
|
|
@@ -20,19 +21,19 @@
|
|
|
20
21
|
"dependencies": {
|
|
21
22
|
"aria-query": "5.3.2",
|
|
22
23
|
"axobject-query": "4.1.0",
|
|
23
|
-
"@angular-eslint/bundled-angular-compiler": "22.
|
|
24
|
-
"@angular-eslint/utils": "22.
|
|
24
|
+
"@angular-eslint/bundled-angular-compiler": "22.1.0",
|
|
25
|
+
"@angular-eslint/utils": "22.1.0"
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
27
28
|
"@types/aria-query": "5.0.4",
|
|
28
|
-
"@angular-eslint/test-utils": "22.
|
|
29
|
+
"@angular-eslint/test-utils": "22.1.0"
|
|
29
30
|
},
|
|
30
31
|
"peerDependencies": {
|
|
31
32
|
"@typescript-eslint/types": "^8.0.0",
|
|
32
33
|
"@typescript-eslint/utils": "^8.0.0",
|
|
33
34
|
"eslint": "^9.0.0 || ^10.0.0",
|
|
34
35
|
"typescript": "*",
|
|
35
|
-
"@angular-eslint/template-parser": "22.
|
|
36
|
+
"@angular-eslint/template-parser": "22.1.0"
|
|
36
37
|
},
|
|
37
38
|
"gitHead": "e2006e5e9c99e5a943d1a999e0efa5247d29ec24"
|
|
38
39
|
}
|