@angular-eslint/eslint-plugin 19.0.0-alpha.3 → 19.0.0-alpha.5

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
@@ -66,7 +66,7 @@ Please see https://github.com/angular-eslint/angular-eslint for full usage instr
66
66
  | [`pipe-prefix`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/pipe-prefix.md) | Enforce consistent prefix for pipes. | | | |
67
67
  | [`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: |
68
68
  | [`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: |
69
- | [`prefer-standalone`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-standalone.md) | Ensures component, directive and pipe `standalone` property is set to `true` in the component decorator | | :wrench: | |
69
+ | [`prefer-standalone`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-standalone.md) | Ensures component, directive and pipe `standalone` property is set to `true` in the component decorator | :white_check_mark: | :wrench: | |
70
70
  | [`relative-url-prefix`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/relative-url-prefix.md) | The ./ and ../ prefix is standard syntax for relative URLs; don't depend on Angular's current ability to do without that prefix. See more at https://angular.dev/style-guide#style-05-04 | | | |
71
71
  | [`require-localize-metadata`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/require-localize-metadata.md) | Ensures that $localize tagged messages contain helpful metadata to aid with translations. | | | |
72
72
  | [`runtime-localize`](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/runtime-localize.md) | Ensures that $localize tagged messages can use runtime-loaded translations. | | | |
@@ -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-standalone": "error",
15
16
  "@angular-eslint/use-pipe-transform-interface": "error",
16
17
  "@angular-eslint/use-lifecycle-interface": "warn"
17
18
  }
package/dist/index.d.ts CHANGED
@@ -57,6 +57,7 @@ declare const _default: {
57
57
  "@angular-eslint/no-output-on-prefix": string;
58
58
  "@angular-eslint/no-output-rename": string;
59
59
  "@angular-eslint/no-outputs-metadata-property": string;
60
+ "@angular-eslint/prefer-standalone": string;
60
61
  "@angular-eslint/use-pipe-transform-interface": string;
61
62
  "@angular-eslint/use-lifecycle-interface": string;
62
63
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmHA,kBA6CE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmHA,kBA6CE"}
@@ -1 +1 @@
1
- {"version":3,"file":"no-input-rename.d.ts","sourceRoot":"","sources":["../../src/rules/no-input-rename.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,OAAO,GAAG,CAAC;IAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AACtE,MAAM,MAAM,UAAU,GAClB,eAAe,GACf,wBAAwB,GACxB,yCAAyC,CAAC;AAC9C,eAAO,MAAM,SAAS,oBAAoB,CAAC;;AAG3C,wBAkPG"}
1
+ {"version":3,"file":"no-input-rename.d.ts","sourceRoot":"","sources":["../../src/rules/no-input-rename.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,OAAO,GAAG,CAAC;IAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AACtE,MAAM,MAAM,UAAU,GAClB,eAAe,GACf,wBAAwB,GACxB,yCAAyC,CAAC;AAC9C,eAAO,MAAM,SAAS,oBAAoB,CAAC;;AAG3C,wBAgQG"}
@@ -58,14 +58,6 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
58
58
  !utils_2.ASTUtils.isIdentifier(propertyOrMethodDefinition.key)) {
59
59
  return;
60
60
  }
61
- let isAliasMetadataProperty = false;
62
- if (node.parent && utils_1.ASTUtils.isProperty(node.parent)) {
63
- if (utils_1.ASTUtils.getRawText(node.parent.key) !== 'alias') {
64
- // We're within an Input decorator metadata object, but it is not the alias property
65
- return;
66
- }
67
- isAliasMetadataProperty = true;
68
- }
69
61
  const aliasName = utils_1.ASTUtils.getRawText(node);
70
62
  const propertyName = utils_1.ASTUtils.getRawText(propertyOrMethodDefinition.key);
71
63
  if (allowedNames.includes(aliasName) ||
@@ -73,28 +65,65 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
73
65
  propertyName === (0, utils_1.kebabToCamelCase)(aliasName))) {
74
66
  return;
75
67
  }
76
- const inputCallExpression = utils_1.ASTUtils.getNearestNodeFrom(node, utils_1.ASTUtils.isCallExpression);
77
- if (inputCallExpression &&
78
- utils_2.ASTUtils.isIdentifier(inputCallExpression.callee) &&
79
- inputCallExpression.callee.name === 'Input' &&
80
- utils_1.ASTUtils.isObjectExpression(inputCallExpression.arguments?.[0])) {
81
- const [firstArg] = inputCallExpression.arguments;
82
- const aliasProperty = firstArg.properties.find((property) => utils_1.ASTUtils.isProperty(property) &&
83
- utils_1.ASTUtils.getRawText(property.key) === 'alias');
84
- if (!aliasProperty) {
85
- return;
68
+ // The alias is either a string in the `@Input()` decorator function,
69
+ // or a string on an `alias` property that is in an object expression
70
+ // that is in the `@Input()` decorator or the `input()` function or the
71
+ // `input.required()` function. If it's on the `alias` property, then we
72
+ // want to remove that whole property rather than just the string literal.
73
+ const stringToRemove = utils_1.ASTUtils.isTemplateElement(node)
74
+ ? node.parent
75
+ : node;
76
+ let rangeToRemove = stringToRemove.range;
77
+ if (utils_1.ASTUtils.isProperty(stringToRemove.parent)) {
78
+ const property = stringToRemove.parent;
79
+ rangeToRemove = property.range;
80
+ if (utils_1.ASTUtils.isObjectExpression(property.parent)) {
81
+ const objectExpression = property.parent;
82
+ if (objectExpression.properties.length === 1) {
83
+ // The property is the only property in the
84
+ // object, so we can remove the whole object.
85
+ rangeToRemove = objectExpression.range;
86
+ // If the object is in an `input()` function, then
87
+ // the object will be the second argument. The first
88
+ // argument will be the default value. We need to
89
+ // remove the comma after the default value.
90
+ const tokenBefore = context.sourceCode.getTokenBefore(objectExpression);
91
+ if (tokenBefore && utils_2.ASTUtils.isCommaToken(tokenBefore)) {
92
+ rangeToRemove = [tokenBefore.range[0], rangeToRemove[1]];
93
+ }
94
+ }
95
+ else {
96
+ // There are other properties in the object, so we
97
+ // can only remove the property. How we remove it
98
+ // will depend on where the property is in the object.
99
+ const propertyIndex = objectExpression.properties.indexOf(property);
100
+ if (propertyIndex < objectExpression.properties.length - 1) {
101
+ // The property is not the last one, so we can
102
+ // remove everything up to the next property
103
+ // which will remove the comma after it.
104
+ rangeToRemove = [
105
+ property.range[0],
106
+ objectExpression.properties[propertyIndex + 1].range[0],
107
+ ];
108
+ }
109
+ else {
110
+ // The property is the last one. If the object has a
111
+ // trailing comma, then we want to keep the trailing comma.
112
+ // The simplest way to do that is to remove the property
113
+ // and the comma that precedes it.
114
+ const tokenBefore = context.sourceCode.getTokenBefore(property);
115
+ if (tokenBefore && utils_2.ASTUtils.isCommaToken(tokenBefore)) {
116
+ rangeToRemove = [tokenBefore.range[0], rangeToRemove[1]];
117
+ }
118
+ }
119
+ }
86
120
  }
87
121
  }
88
122
  if (aliasName === propertyName) {
89
123
  context.report({
90
124
  node,
91
125
  messageId: 'noInputRename',
92
- fix: (fixer) => {
93
- if (node.parent && isAliasMetadataProperty) {
94
- return fixer.remove(node.parent);
95
- }
96
- return fixer.remove(node);
97
- },
126
+ fix: (fixer) => fixer.removeRange(rangeToRemove),
98
127
  });
99
128
  }
100
129
  else if (!isAliasNameAllowed(selectors, propertyName, aliasName, selectorDirectiveName)) {
@@ -104,17 +133,12 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
104
133
  suggest: [
105
134
  {
106
135
  messageId: 'suggestRemoveAliasName',
107
- fix: (fixer) => {
108
- if (node.parent && isAliasMetadataProperty) {
109
- return fixer.remove(node.parent);
110
- }
111
- return fixer.remove(node);
112
- },
136
+ fix: (fixer) => fixer.removeRange(rangeToRemove),
113
137
  },
114
138
  {
115
139
  messageId: 'suggestReplaceOriginalNameWithAliasName',
116
140
  fix: (fixer) => [
117
- fixer.remove(node),
141
+ fixer.removeRange(rangeToRemove),
118
142
  fixer.replaceText(propertyOrMethodDefinition.key, aliasName.includes('-') ? `'${aliasName}'` : aliasName),
119
143
  ],
120
144
  },
@@ -1 +1 @@
1
- {"version":3,"file":"no-output-rename.d.ts","sourceRoot":"","sources":["../../src/rules/no-output-rename.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAClB,gBAAgB,GAChB,wBAAwB,GACxB,yCAAyC,CAAC;AAC9C,eAAO,MAAM,SAAS,qBAAqB,CAAC;;AAG5C,wBAkJG"}
1
+ {"version":3,"file":"no-output-rename.d.ts","sourceRoot":"","sources":["../../src/rules/no-output-rename.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAClB,gBAAgB,GAChB,wBAAwB,GACxB,yCAAyC,CAAC;AAC9C,eAAO,MAAM,SAAS,qBAAqB,CAAC;;AAG5C,wBAgMG"}
@@ -38,11 +38,56 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
38
38
  }
39
39
  const aliasName = utils_1.ASTUtils.getRawText(node);
40
40
  const propertyName = utils_1.ASTUtils.getRawText(propertyOrMethodDefinition.key);
41
+ // The alias is either a string in the `@Output()` decorator function,
42
+ // or a string on an `alias` property that is in an object expression
43
+ // that is in the `output()` function. If it's the latter, then we want
44
+ // to remove that whole property rather than just the string literal.
45
+ const stringToRemove = utils_1.ASTUtils.isTemplateElement(node)
46
+ ? node.parent
47
+ : node;
48
+ let rangeToRemove = stringToRemove.range;
49
+ if (utils_1.ASTUtils.isProperty(stringToRemove.parent)) {
50
+ const property = stringToRemove.parent;
51
+ rangeToRemove = property.range;
52
+ if (utils_1.ASTUtils.isObjectExpression(property.parent)) {
53
+ const objectExpression = property.parent;
54
+ if (objectExpression.properties.length === 1) {
55
+ // The property is the only property in the
56
+ // object, so we can remove the whole object.
57
+ rangeToRemove = objectExpression.range;
58
+ }
59
+ else {
60
+ // There are other properties in the object, so we
61
+ // can only remove the property. How we remove it
62
+ // will depend on where the property is in the object.
63
+ const propertyIndex = objectExpression.properties.indexOf(property);
64
+ if (propertyIndex < objectExpression.properties.length - 1) {
65
+ // The property is not the last one, so we can
66
+ // remove everything up to the next property
67
+ // which will remove the comma after it.
68
+ rangeToRemove = [
69
+ property.range[0],
70
+ objectExpression.properties[propertyIndex + 1].range[0],
71
+ ];
72
+ }
73
+ else {
74
+ // The property is the last one. If the object has a
75
+ // trailing comma, then we want to keep the trailing comma.
76
+ // The simplest way to do that is to remove the property
77
+ // and the comma that precedes it.
78
+ const tokenBefore = context.sourceCode.getTokenBefore(property);
79
+ if (tokenBefore && utils_2.ASTUtils.isCommaToken(tokenBefore)) {
80
+ rangeToRemove = [tokenBefore.range[0], rangeToRemove[1]];
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
41
86
  if (aliasName === propertyName) {
42
87
  context.report({
43
88
  node,
44
89
  messageId: 'noOutputRename',
45
- fix: (fixer) => fixer.remove(node),
90
+ fix: (fixer) => fixer.removeRange(rangeToRemove),
46
91
  });
47
92
  }
48
93
  else if (!isAliasNameAllowed(selectors, propertyName, aliasName)) {
@@ -52,12 +97,12 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
52
97
  suggest: [
53
98
  {
54
99
  messageId: 'suggestRemoveAliasName',
55
- fix: (fixer) => fixer.remove(node),
100
+ fix: (fixer) => fixer.removeRange(rangeToRemove),
56
101
  },
57
102
  {
58
103
  messageId: 'suggestReplaceOriginalNameWithAliasName',
59
104
  fix: (fixer) => [
60
- fixer.remove(node),
105
+ fixer.removeRange(rangeToRemove),
61
106
  fixer.replaceText(propertyOrMethodDefinition.key, aliasName.includes('-') ? `'${aliasName}'` : aliasName),
62
107
  ],
63
108
  },
@@ -0,0 +1,15 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ type Options = [
3
+ {
4
+ preferReadonlySignalProperties: boolean;
5
+ preferInputSignals: boolean;
6
+ preferQuerySignals: boolean;
7
+ useTypeChecking: boolean;
8
+ additionalSignalCreationFunctions: string[];
9
+ }
10
+ ];
11
+ export type MessageIds = 'preferInputSignals' | 'preferQuerySignals' | 'preferReadonlySignalProperties' | 'suggestAddReadonlyModifier';
12
+ export declare const RULE_NAME = "prefer-signals";
13
+ declare const _default: ESLintUtils.RuleModule<MessageIds, Options, import("../utils/create-eslint-rule").RuleDocs, ESLintUtils.RuleListener>;
14
+ export default _default;
15
+ //# sourceMappingURL=prefer-signals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefer-signals.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-signals.ts"],"names":[],"mappings":"AAKA,OAAO,EAAkB,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvE,KAAK,OAAO,GAAG;IACb;QACE,8BAA8B,EAAE,OAAO,CAAC;QACxC,kBAAkB,EAAE,OAAO,CAAC;QAC5B,kBAAkB,EAAE,OAAO,CAAC;QAC5B,eAAe,EAAE,OAAO,CAAC;QACzB,iCAAiC,EAAE,MAAM,EAAE,CAAC;KAC7C;CACF,CAAC;AA4BF,MAAM,MAAM,UAAU,GAClB,oBAAoB,GACpB,oBAAoB,GACpB,gCAAgC,GAChC,4BAA4B,CAAC;AACjC,eAAO,MAAM,SAAS,mBAAmB,CAAC;;AAE1C,wBA6KG"}
@@ -0,0 +1,168 @@
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
+ const DEFAULT_OPTIONS = {
8
+ preferReadonlySignalProperties: true,
9
+ preferInputSignals: true,
10
+ preferQuerySignals: true,
11
+ useTypeChecking: false,
12
+ additionalSignalCreationFunctions: [],
13
+ };
14
+ const KNOWN_SIGNAL_TYPES = new Set([
15
+ 'InputSignal',
16
+ 'ModelSignal',
17
+ 'Signal',
18
+ 'WritableSignal',
19
+ ]);
20
+ const KNOWN_SIGNAL_CREATION_FUNCTIONS = new Set([
21
+ 'computed',
22
+ 'contentChild',
23
+ 'contentChildren',
24
+ 'input',
25
+ 'model',
26
+ 'signal',
27
+ 'toSignal',
28
+ 'viewChild',
29
+ 'viewChildren',
30
+ ]);
31
+ exports.RULE_NAME = 'prefer-signals';
32
+ exports.default = (0, create_eslint_rule_1.createESLintRule)({
33
+ name: exports.RULE_NAME,
34
+ meta: {
35
+ type: 'suggestion',
36
+ docs: {
37
+ description: 'Use readonly signals instead of `@Input()`, `@ViewChild()` and other legacy decorators',
38
+ recommended: 'recommended',
39
+ },
40
+ hasSuggestions: true,
41
+ schema: [
42
+ {
43
+ type: 'object',
44
+ properties: {
45
+ preferReadonlySignalProperties: {
46
+ type: 'boolean',
47
+ default: DEFAULT_OPTIONS.preferReadonlySignalProperties,
48
+ },
49
+ preferInputSignals: {
50
+ type: 'boolean',
51
+ default: DEFAULT_OPTIONS.preferInputSignals,
52
+ },
53
+ preferQuerySignals: {
54
+ type: 'boolean',
55
+ default: DEFAULT_OPTIONS.preferQuerySignals,
56
+ },
57
+ useTypeChecking: {
58
+ type: 'boolean',
59
+ default: DEFAULT_OPTIONS.useTypeChecking,
60
+ },
61
+ additionalSignalCreationFunctions: {
62
+ type: 'array',
63
+ items: { type: 'string' },
64
+ default: DEFAULT_OPTIONS.additionalSignalCreationFunctions,
65
+ },
66
+ },
67
+ additionalProperties: false,
68
+ },
69
+ ],
70
+ messages: {
71
+ preferInputSignals: 'Use `InputSignal`s (e.g. via `input()`) for Component input properties rather than the legacy `@Input()` decorator',
72
+ preferQuerySignals: 'Use the `{{function}}` function instead of the `{{decorator}}` decorator',
73
+ preferReadonlySignalProperties: 'Properties declared using signals should be marked as `readonly` since they should not be reassigned',
74
+ suggestAddReadonlyModifier: 'Add `readonly` modifier',
75
+ },
76
+ },
77
+ defaultOptions: [{ ...DEFAULT_OPTIONS }],
78
+ create(context, [{ preferReadonlySignalProperties = DEFAULT_OPTIONS.preferReadonlySignalProperties, preferInputSignals = DEFAULT_OPTIONS.preferInputSignals, preferQuerySignals = DEFAULT_OPTIONS.preferQuerySignals, additionalSignalCreationFunctions = DEFAULT_OPTIONS.additionalSignalCreationFunctions, useTypeChecking = DEFAULT_OPTIONS.useTypeChecking, },]) {
79
+ let services;
80
+ const listener = {};
81
+ if (preferReadonlySignalProperties) {
82
+ listener[`PropertyDefinition:not([readonly=true])`] = (node) => {
83
+ let shouldBeReadonly = false;
84
+ if (node.typeAnnotation) {
85
+ // Use the type annotation to determine
86
+ // whether the property is a signal.
87
+ if (node.typeAnnotation.typeAnnotation.type ===
88
+ utils_2.AST_NODE_TYPES.TSTypeReference) {
89
+ const type = node.typeAnnotation.typeAnnotation;
90
+ if (type.typeArguments &&
91
+ type.typeName.type === utils_2.AST_NODE_TYPES.Identifier &&
92
+ KNOWN_SIGNAL_TYPES.has(type.typeName.name)) {
93
+ shouldBeReadonly = true;
94
+ }
95
+ }
96
+ }
97
+ else {
98
+ // There is no type annotation, so try to
99
+ // use the value assigned to the property
100
+ // to determine whether it would be a signal.
101
+ if (node.value?.type === utils_2.AST_NODE_TYPES.CallExpression) {
102
+ let callee = node.value.callee;
103
+ // Some signal-creating functions have a `.required`
104
+ // member. For example, `input.required()`.
105
+ if (callee.type === utils_2.AST_NODE_TYPES.MemberExpression) {
106
+ if (callee.property.type === utils_2.AST_NODE_TYPES.Identifier &&
107
+ callee.property.name !== 'required') {
108
+ return;
109
+ }
110
+ callee = callee.object;
111
+ }
112
+ if (callee.type === utils_2.AST_NODE_TYPES.Identifier &&
113
+ (KNOWN_SIGNAL_CREATION_FUNCTIONS.has(callee.name) ||
114
+ additionalSignalCreationFunctions.includes(callee.name))) {
115
+ shouldBeReadonly = true;
116
+ }
117
+ }
118
+ if (!shouldBeReadonly && useTypeChecking && node.value) {
119
+ services ??= utils_2.ESLintUtils.getParserServices(context);
120
+ const name = services
121
+ .getTypeAtLocation(node.value)
122
+ .getSymbol()?.name;
123
+ shouldBeReadonly =
124
+ name !== undefined && KNOWN_SIGNAL_TYPES.has(name);
125
+ }
126
+ }
127
+ if (shouldBeReadonly) {
128
+ context.report({
129
+ node: node.key,
130
+ messageId: 'preferReadonlySignalProperties',
131
+ suggest: [
132
+ {
133
+ messageId: 'suggestAddReadonlyModifier',
134
+ fix: (fixer) => fixer.insertTextBefore(node.key, 'readonly '),
135
+ },
136
+ ],
137
+ });
138
+ }
139
+ };
140
+ }
141
+ if (preferInputSignals) {
142
+ listener[utils_1.Selectors.INPUT_DECORATOR] = (node) => {
143
+ context.report({
144
+ node,
145
+ messageId: 'preferInputSignals',
146
+ });
147
+ };
148
+ }
149
+ if (preferQuerySignals) {
150
+ listener['Decorator[expression.callee.name=/^(ContentChild|ContentChildren|ViewChild|ViewChildren)$/]'] = (node) => {
151
+ if (node.expression.type === utils_2.AST_NODE_TYPES.CallExpression &&
152
+ node.expression.callee.type === utils_2.AST_NODE_TYPES.Identifier) {
153
+ const decoratorName = node.expression.callee.name;
154
+ context.report({
155
+ node,
156
+ messageId: 'preferQuerySignals',
157
+ data: {
158
+ function: decoratorName.slice(0, 1).toLowerCase() +
159
+ decoratorName.slice(1),
160
+ decorator: decoratorName,
161
+ },
162
+ });
163
+ }
164
+ };
165
+ }
166
+ return listener;
167
+ },
168
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-standalone.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-standalone.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AAEzB,MAAM,MAAM,UAAU,GAAG,kBAAkB,CAAC;AAC5C,eAAO,MAAM,SAAS,sBAAsB,CAAC;;AAI7C,wBAiEG"}
1
+ {"version":3,"file":"prefer-standalone.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-standalone.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AAEzB,MAAM,MAAM,UAAU,GAAG,kBAAkB,CAAC;AAC5C,eAAO,MAAM,SAAS,sBAAsB,CAAC;;AAI7C,wBAkEG"}
@@ -12,6 +12,7 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
12
12
  type: 'suggestion',
13
13
  docs: {
14
14
  description: `Ensures component, directive and pipe \`${METADATA_PROPERTY_NAME}\` property is set to \`${IS_STANDALONE}\` in the component decorator`,
15
+ recommended: 'recommended',
15
16
  },
16
17
  fixable: 'code',
17
18
  schema: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular-eslint/eslint-plugin",
3
- "version": "19.0.0-alpha.3",
3
+ "version": "19.0.0-alpha.5",
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.0.0-alpha.3",
22
- "@angular-eslint/utils": "19.0.0-alpha.3"
21
+ "@angular-eslint/bundled-angular-compiler": "19.0.0-alpha.5",
22
+ "@angular-eslint/utils": "19.0.0-alpha.5"
23
23
  },
24
24
  "devDependencies": {
25
- "@angular-eslint/test-utils": "19.0.0-alpha.3"
25
+ "@angular-eslint/test-utils": "19.0.0-alpha.5"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@typescript-eslint/utils": "^7.11.0 || ^8.0.0",