@angular-eslint/eslint-plugin 19.5.1-alpha.1 → 19.5.1-alpha.10

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 CHANGED
@@ -65,6 +65,7 @@ Please see https://github.com/angular-eslint/angular-eslint for full usage instr
65
65
  | [`no-pipe-impure`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-pipe-impure.md) | Disallows the declaration of impure pipes | | | :bulb: |
66
66
  | [`no-queries-metadata-property`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/no-queries-metadata-property.md) | Disallows usage of the `queries` metadata property. See more at https://angular.dev/style-guide#style-05-12. | | | |
67
67
  | [`pipe-prefix`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/pipe-prefix.md) | Enforce consistent prefix for pipes. | | | |
68
+ | [`prefer-inject`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-inject.md) | Prefer using the inject() function over constructor parameter injection | :white_check_mark: | | |
68
69
  | [`prefer-on-push-component-change-detection`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-on-push-component-change-detection.md) | Ensures component's `changeDetection` is set to `ChangeDetectionStrategy.OnPush` | | | :bulb: |
69
70
  | [`prefer-output-emitter-ref`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-output-emitter-ref.md) | Use `OutputEmitterRef` instead of `@Output()` | | | |
70
71
  | [`prefer-output-readonly`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-output-readonly.md) | Prefer to declare `@Output`, `OutputEmitterRef` and `OutputRef` as `readonly` since they are not supposed to be reassigned | | | :bulb: |
@@ -27,6 +27,7 @@
27
27
  "@angular-eslint/no-pipe-impure": "error",
28
28
  "@angular-eslint/no-queries-metadata-property": "error",
29
29
  "@angular-eslint/pipe-prefix": "error",
30
+ "@angular-eslint/prefer-inject": "error",
30
31
  "@angular-eslint/prefer-on-push-component-change-detection": "error",
31
32
  "@angular-eslint/prefer-output-emitter-ref": "error",
32
33
  "@angular-eslint/prefer-output-readonly": "error",
@@ -12,6 +12,7 @@
12
12
  "@angular-eslint/no-output-on-prefix": "error",
13
13
  "@angular-eslint/no-output-rename": "error",
14
14
  "@angular-eslint/no-outputs-metadata-property": "error",
15
+ "@angular-eslint/prefer-inject": "error",
15
16
  "@angular-eslint/prefer-standalone": "error",
16
17
  "@angular-eslint/use-pipe-transform-interface": "error",
17
18
  "@angular-eslint/use-lifecycle-interface": "warn"
package/dist/index.d.ts CHANGED
@@ -29,6 +29,7 @@ declare const _default: {
29
29
  "@angular-eslint/no-pipe-impure": string;
30
30
  "@angular-eslint/no-queries-metadata-property": string;
31
31
  "@angular-eslint/pipe-prefix": string;
32
+ "@angular-eslint/prefer-inject": string;
32
33
  "@angular-eslint/prefer-on-push-component-change-detection": string;
33
34
  "@angular-eslint/prefer-output-emitter-ref": string;
34
35
  "@angular-eslint/prefer-output-readonly": string;
@@ -61,6 +62,7 @@ declare const _default: {
61
62
  "@angular-eslint/no-output-on-prefix": string;
62
63
  "@angular-eslint/no-output-rename": string;
63
64
  "@angular-eslint/no-outputs-metadata-property": string;
65
+ "@angular-eslint/prefer-inject": string;
64
66
  "@angular-eslint/prefer-standalone": string;
65
67
  "@angular-eslint/use-pipe-transform-interface": string;
66
68
  "@angular-eslint/use-lifecycle-interface": string;
@@ -102,6 +104,7 @@ declare const _default: {
102
104
  additionalSignalCreationFunctions: string[];
103
105
  }], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
104
106
  "prefer-standalone": import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferStandalone", [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
107
+ "prefer-inject": import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferInject", [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
105
108
  "prefer-output-emitter-ref": import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferOutputEmitterRef", [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
106
109
  "prefer-output-readonly": import("@typescript-eslint/utils/ts-eslint").RuleModule<import("./rules/prefer-output-readonly").MessageIds, [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
107
110
  "relative-url-prefix": import("@typescript-eslint/utils/ts-eslint").RuleModule<"relativeUrlPrefix", [], import("./utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+HA,kBAiDE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkIA,kBAkDE"}
package/dist/index.js CHANGED
@@ -65,6 +65,7 @@ const pipe_prefix_1 = __importStar(require("./rules/pipe-prefix"));
65
65
  const prefer_on_push_component_change_detection_1 = __importStar(require("./rules/prefer-on-push-component-change-detection"));
66
66
  const prefer_output_emitter_ref_1 = __importStar(require("./rules/prefer-output-emitter-ref"));
67
67
  const prefer_output_readonly_1 = __importStar(require("./rules/prefer-output-readonly"));
68
+ const prefer_inject_1 = __importStar(require("./rules/prefer-inject"));
68
69
  const prefer_signals_1 = __importStar(require("./rules/prefer-signals"));
69
70
  const prefer_standalone_1 = __importStar(require("./rules/prefer-standalone"));
70
71
  const relative_url_prefix_1 = __importStar(require("./rules/relative-url-prefix"));
@@ -112,6 +113,7 @@ module.exports = {
112
113
  [prefer_on_push_component_change_detection_1.RULE_NAME]: prefer_on_push_component_change_detection_1.default,
113
114
  [prefer_signals_1.RULE_NAME]: prefer_signals_1.default,
114
115
  [prefer_standalone_1.RULE_NAME]: prefer_standalone_1.default,
116
+ [prefer_inject_1.RULE_NAME]: prefer_inject_1.default,
115
117
  [prefer_output_emitter_ref_1.RULE_NAME]: prefer_output_emitter_ref_1.default,
116
118
  [prefer_output_readonly_1.RULE_NAME]: prefer_output_readonly_1.default,
117
119
  [relative_url_prefix_1.RULE_NAME]: relative_url_prefix_1.default,
@@ -0,0 +1,6 @@
1
+ export type Options = [];
2
+ export type MessageIds = 'preferInject';
3
+ export declare const RULE_NAME = "prefer-inject";
4
+ declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferInject", [], import("../utils/create-eslint-rule").RuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
5
+ export default _default;
6
+ //# sourceMappingURL=prefer-inject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefer-inject.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-inject.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AAEzB,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC;AACxC,eAAO,MAAM,SAAS,kBAAkB,CAAC;;AAEzC,wBA8GG"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RULE_NAME = void 0;
4
+ const utils_1 = require("@angular-eslint/utils");
5
+ const utils_2 = require("@typescript-eslint/utils");
6
+ const create_eslint_rule_1 = require("../utils/create-eslint-rule");
7
+ exports.RULE_NAME = 'prefer-inject';
8
+ exports.default = (0, create_eslint_rule_1.createESLintRule)({
9
+ name: exports.RULE_NAME,
10
+ meta: {
11
+ type: 'suggestion',
12
+ docs: {
13
+ description: 'Prefer using the inject() function over constructor parameter injection',
14
+ recommended: 'recommended',
15
+ },
16
+ schema: [],
17
+ messages: {
18
+ preferInject: "Prefer using the inject() function over constructor parameter injection. Use Angular's migration schematic to automatically refactor: ng generate @angular/core:inject",
19
+ },
20
+ },
21
+ defaultOptions: [],
22
+ create(context) {
23
+ const angularDecoratorsPattern = (0, utils_1.toPattern)([
24
+ 'Component',
25
+ 'Directive',
26
+ 'Injectable',
27
+ 'Pipe',
28
+ ]);
29
+ function shouldReportParameter(param) {
30
+ let actualParam = param;
31
+ let hasModifier = false;
32
+ if (param.type === utils_2.AST_NODE_TYPES.TSParameterProperty) {
33
+ actualParam = param.parameter;
34
+ hasModifier = true;
35
+ }
36
+ const decorators = (param.type === utils_2.AST_NODE_TYPES.TSParameterProperty
37
+ ? param.parameter
38
+ : param).decorators;
39
+ if (decorators?.some((d) => {
40
+ const name = utils_1.ASTUtils.getDecoratorName(d);
41
+ return (name === 'Inject' ||
42
+ name === 'Optional' ||
43
+ name === 'Self' ||
44
+ name === 'SkipSelf' ||
45
+ name === 'Host');
46
+ })) {
47
+ return true;
48
+ }
49
+ if (hasModifier) {
50
+ return true;
51
+ }
52
+ const typeAnnotation = actualParam.typeAnnotation;
53
+ if (typeAnnotation) {
54
+ switch (typeAnnotation.typeAnnotation.type) {
55
+ case utils_2.AST_NODE_TYPES.TSStringKeyword:
56
+ case utils_2.AST_NODE_TYPES.TSNumberKeyword:
57
+ case utils_2.AST_NODE_TYPES.TSBooleanKeyword:
58
+ case utils_2.AST_NODE_TYPES.TSBigIntKeyword:
59
+ case utils_2.AST_NODE_TYPES.TSSymbolKeyword:
60
+ case utils_2.AST_NODE_TYPES.TSAnyKeyword:
61
+ case utils_2.AST_NODE_TYPES.TSUnknownKeyword:
62
+ return false;
63
+ default:
64
+ return true;
65
+ }
66
+ }
67
+ return false;
68
+ }
69
+ return {
70
+ [`${utils_1.Selectors.decoratorDefinition(angularDecoratorsPattern)} > ClassBody > MethodDefinition[kind="constructor"]`](node) {
71
+ const params = node.value.params;
72
+ if (params.length === 0) {
73
+ return;
74
+ }
75
+ // ignore constructors that only call super() (no parameters to inject)
76
+ const body = node.value.body?.body ?? [];
77
+ const onlySuper = body.length === 1 &&
78
+ body[0].type === utils_2.AST_NODE_TYPES.ExpressionStatement &&
79
+ body[0].expression.type === utils_2.AST_NODE_TYPES.CallExpression &&
80
+ body[0].expression.callee.type === utils_2.AST_NODE_TYPES.Super;
81
+ if (onlySuper && params.length === 0) {
82
+ return;
83
+ }
84
+ for (const param of params) {
85
+ if (shouldReportParameter(param)) {
86
+ context.report({ node: param, messageId: 'preferInject' });
87
+ }
88
+ }
89
+ },
90
+ };
91
+ },
92
+ });
@@ -138,7 +138,9 @@ function reportAndFix(context, node, messageId, data, properties, expectedOrder,
138
138
  fix(fixer) {
139
139
  const indentation = utils_1.CommentUtils.getObjectIndentation(sourceCode, objectExpression);
140
140
  const propNames = properties.map((p) => p.key.name);
141
- const filteredOrder = expectedOrder.filter((name) => propNames.includes(name));
141
+ const configuredProps = expectedOrder.filter((name) => propNames.includes(name));
142
+ const unconfiguredProps = propNames.filter((name) => !expectedOrder.includes(name));
143
+ const filteredOrder = [...configuredProps, ...unconfiguredProps];
142
144
  const propInfoMap = utils_1.CommentUtils.extractPropertyComments(sourceCode, properties, objectExpression, indentation);
143
145
  const sortedText = utils_1.CommentUtils.buildSortedPropertiesWithComments(filteredOrder, propInfoMap, indentation);
144
146
  return fixer.replaceText(objectExpression, `{\n${sortedText}\n${indentation.slice(0, -2)}}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular-eslint/eslint-plugin",
3
- "version": "19.5.1-alpha.1",
3
+ "version": "19.5.1-alpha.10",
4
4
  "description": "ESLint plugin for Angular applications, following https://angular.dev/style-guide",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -18,11 +18,11 @@
18
18
  "LICENSE"
19
19
  ],
20
20
  "dependencies": {
21
- "@angular-eslint/bundled-angular-compiler": "19.5.1-alpha.1",
22
- "@angular-eslint/utils": "19.5.1-alpha.1"
21
+ "@angular-eslint/bundled-angular-compiler": "19.5.1-alpha.10",
22
+ "@angular-eslint/utils": "19.5.1-alpha.10"
23
23
  },
24
24
  "devDependencies": {
25
- "@angular-eslint/test-utils": "19.5.1-alpha.1"
25
+ "@angular-eslint/test-utils": "19.5.1-alpha.10"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@typescript-eslint/utils": "^7.11.0 || ^8.0.0",