@angular-eslint/eslint-plugin-template 19.8.1-alpha.1 → 19.8.1

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.
@@ -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,wBAkFG"}
1
+ {"version":3,"file":"conditional-complexity.d.ts","sourceRoot":"","sources":["../../src/rules/conditional-complexity.ts"],"names":[],"mappings":"AAgBA,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,wBAkFG"}
@@ -4,7 +4,6 @@ exports.RULE_NAME = void 0;
4
4
  const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
5
5
  const utils_1 = require("@angular-eslint/utils");
6
6
  const create_eslint_rule_1 = require("../utils/create-eslint-rule");
7
- const unwrap_parenthesized_expression_1 = require("../utils/unwrap-parenthesized-expression");
8
7
  exports.RULE_NAME = 'conditional-complexity';
9
8
  const DEFAULT_MAX_COMPLEXITY = 5;
10
9
  exports.default = (0, create_eslint_rule_1.createESLintRule)({
@@ -75,8 +74,7 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
75
74
  },
76
75
  });
77
76
  function extractPossibleBinaryOrConditionalFrom(node) {
78
- const unwrapped = (0, unwrap_parenthesized_expression_1.unwrapParenthesizedExpression)(node);
79
- return unwrapped instanceof bundled_angular_compiler_1.BindingPipe ? unwrapped.exp : unwrapped;
77
+ return node instanceof bundled_angular_compiler_1.BindingPipe ? node.exp : node;
80
78
  }
81
79
  let parser = null;
82
80
  // Instantiate the `Parser` class lazily only when this rule is applied.
@@ -91,14 +89,10 @@ function getTotalComplexity(ast) {
91
89
  }
92
90
  let total = 1;
93
91
  if (possibleBinaryOrConditional instanceof bundled_angular_compiler_1.Binary) {
94
- const leftUnwrapped = (0, unwrap_parenthesized_expression_1.unwrapParenthesizedExpression)(possibleBinaryOrConditional.left);
95
- const rightUnwrapped = (0, unwrap_parenthesized_expression_1.unwrapParenthesizedExpression)(possibleBinaryOrConditional.right);
96
- if (leftUnwrapped instanceof bundled_angular_compiler_1.Binary ||
97
- leftUnwrapped instanceof bundled_angular_compiler_1.Conditional) {
92
+ if (possibleBinaryOrConditional.left instanceof bundled_angular_compiler_1.Binary) {
98
93
  total += getTotalComplexity(possibleBinaryOrConditional.left);
99
94
  }
100
- if (rightUnwrapped instanceof bundled_angular_compiler_1.Binary ||
101
- rightUnwrapped instanceof bundled_angular_compiler_1.Conditional) {
95
+ if (possibleBinaryOrConditional.right instanceof bundled_angular_compiler_1.Binary) {
102
96
  total += getTotalComplexity(possibleBinaryOrConditional.right);
103
97
  }
104
98
  }
@@ -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,CAAC;IAAE,2BAA2B,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AACjE,MAAM,MAAM,UAAU,GAAG,6BAA6B,CAAC;AACvD,eAAO,MAAM,SAAS,mCAAmC,CAAC;;AAY1D,wBA+EG"}
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,wBAmFG"}
@@ -59,16 +59,20 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
59
59
  messageId: 'noInterpolationInAttributes',
60
60
  fix: isFullInterpolation
61
61
  ? (fixer) => {
62
- const attributeName = boundAttribute.name.trim();
62
+ const attrStart = boundAttribute.keySpan.start.offset;
63
+ const attrEnd = boundAttribute.keySpan.end.offset;
64
+ const attributeName = sourceCode.text
65
+ .slice(attrStart, attrEnd)
66
+ .trim();
63
67
  const exprStart = boundAttribute.valueSpan.start.offset + 2; // +2 to remove '{{'
64
68
  const exprEnd = boundAttribute.valueSpan.end.offset - 2; // -2 to remove '}}'
65
69
  const expression = sourceCode.text
66
70
  .slice(exprStart, exprEnd)
67
71
  .trim();
68
- return fixer.replaceTextRange([
69
- boundAttribute.keySpan.start.offset,
70
- boundAttribute.valueSpan.end.offset,
71
- ], `[${attributeName}]="${expression}`);
72
+ const rangeStart = boundAttribute.sourceSpan.start.offset;
73
+ const rangeEnd = boundAttribute.sourceSpan.end.offset;
74
+ const replacement = `[${attributeName}]="${expression}"`;
75
+ return fixer.replaceTextRange([rangeStart, rangeEnd], replacement);
72
76
  }
73
77
  : null,
74
78
  });
@@ -1 +1 @@
1
- {"version":3,"file":"no-negated-async.d.ts","sourceRoot":"","sources":["../../src/rules/no-negated-async.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAClB,gBAAgB,GAChB,wBAAwB,GACxB,wBAAwB,GACxB,uBAAuB,GACvB,4BAA4B,GAC5B,6BAA6B,CAAC;AAClC,eAAO,MAAM,SAAS,qBAAqB,CAAC;;AAE5C,wBAmFG;AAEH,eAAO,MAAM,mBAAmB;;CAE/B,CAAC"}
1
+ {"version":3,"file":"no-negated-async.d.ts","sourceRoot":"","sources":["../../src/rules/no-negated-async.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,UAAU,GAClB,gBAAgB,GAChB,wBAAwB,GACxB,wBAAwB,GACxB,uBAAuB,GACvB,4BAA4B,GAC5B,6BAA6B,CAAC;AAClC,eAAO,MAAM,SAAS,qBAAqB,CAAC;;AAE5C,wBA2EG;AAEH,eAAO,MAAM,mBAAmB;;CAE/B,CAAC"}
@@ -28,23 +28,6 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
28
28
  create(context) {
29
29
  (0, utils_1.ensureTemplateParser)(context);
30
30
  const sourceCode = context.sourceCode;
31
- function reportNegatedAsync(prefixNotNode) {
32
- const { start, end } = prefixNotNode.sourceSpan;
33
- context.report({
34
- messageId: 'noNegatedAsync',
35
- loc: {
36
- start: sourceCode.getLocFromIndex(start),
37
- end: sourceCode.getLocFromIndex(end),
38
- },
39
- suggest: getSuggestionsSchema().map(({ messageId, textToInsert }) => ({
40
- messageId,
41
- fix: (fixer) => [
42
- fixer.removeRange([start, start + 1]),
43
- fixer.insertTextAfterRange([end, end], textToInsert),
44
- ],
45
- })),
46
- });
47
- }
48
31
  return {
49
32
  'BindingPipe[name="async"]'(bindingPipe) {
50
33
  if (bindingPipe.exp instanceof bundled_angular_compiler_1.PrefixNot) {
@@ -65,11 +48,21 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
65
48
  });
66
49
  }
67
50
  },
68
- ':not(PrefixNot) > PrefixNot > BindingPipe[name="async"]'({ parent, }) {
69
- reportNegatedAsync(parent);
70
- },
71
- ':not(PrefixNot) > PrefixNot > ParenthesizedExpression > BindingPipe[name="async"]'({ parent: { parent }, }) {
72
- reportNegatedAsync(parent);
51
+ ':not(PrefixNot) > PrefixNot > BindingPipe[name="async"]'({ parent: { sourceSpan: { end, start }, }, }) {
52
+ context.report({
53
+ messageId: 'noNegatedAsync',
54
+ loc: {
55
+ start: sourceCode.getLocFromIndex(start),
56
+ end: sourceCode.getLocFromIndex(end),
57
+ },
58
+ suggest: getSuggestionsSchema().map(({ messageId, textToInsert }) => ({
59
+ messageId,
60
+ fix: (fixer) => [
61
+ fixer.removeRange([start, start + 1]),
62
+ fixer.insertTextAfterRange([end, end], textToInsert),
63
+ ],
64
+ })),
65
+ });
73
66
  },
74
67
  };
75
68
  },
@@ -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,wBAiaG"}
1
+ {"version":3,"file":"prefer-contextual-for-variables.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-contextual-for-variables.ts"],"names":[],"mappings":"AAmBA,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,wBAiaG"}
@@ -3,9 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RULE_NAME = void 0;
4
4
  const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
5
5
  const utils_1 = require("@angular-eslint/utils");
6
- const are_equivalent_asts_1 = require("../utils/are-equivalent-asts");
7
6
  const create_eslint_rule_1 = require("../utils/create-eslint-rule");
8
- const unwrap_parenthesized_expression_1 = require("../utils/unwrap-parenthesized-expression");
7
+ const are_equivalent_asts_1 = require("../utils/are-equivalent-asts");
9
8
  exports.RULE_NAME = 'prefer-contextual-for-variables';
10
9
  const DEFAULT_OPTIONS = {
11
10
  allowedAliases: {
@@ -483,38 +482,35 @@ function isIndex(node) {
483
482
  return isContextualVariable(node, '$index');
484
483
  }
485
484
  function isIndexPlusOne(node) {
486
- const unwrapped = (0, unwrap_parenthesized_expression_1.unwrapParenthesizedExpression)(node);
487
- if (unwrapped instanceof bundled_angular_compiler_1.Binary) {
488
- if (unwrapped.operation === '+') {
489
- if (isIndex(unwrapped.left)) {
490
- return isOne(unwrapped.right);
485
+ if (node instanceof bundled_angular_compiler_1.Binary) {
486
+ if (node.operation === '+') {
487
+ if (isIndex(node.left)) {
488
+ return isOne(node.right);
491
489
  }
492
490
  else {
493
- return isIndex(unwrapped.right) && isOne(unwrapped.left);
491
+ return isIndex(node.right) && isOne(node.left);
494
492
  }
495
493
  }
496
494
  }
497
495
  return false;
498
496
  }
499
497
  function isIndexModTwo(node) {
500
- const unwrapped = (0, unwrap_parenthesized_expression_1.unwrapParenthesizedExpression)(node);
501
- return (unwrapped instanceof bundled_angular_compiler_1.Binary &&
502
- unwrapped.operation === '%' &&
503
- isIndex(unwrapped.left) &&
504
- isTwo(unwrapped.right));
498
+ return (node instanceof bundled_angular_compiler_1.Binary &&
499
+ node.operation === '%' &&
500
+ isIndex(node.left) &&
501
+ isTwo(node.right));
505
502
  }
506
503
  function isCount(node) {
507
504
  return isContextualVariable(node, '$count');
508
505
  }
509
506
  function isCountMinusOne(node) {
510
- const unwrapped = (0, unwrap_parenthesized_expression_1.unwrapParenthesizedExpression)(node);
511
- if (unwrapped instanceof bundled_angular_compiler_1.Binary) {
512
- if (unwrapped.operation === '-') {
513
- if (isCount(unwrapped.left)) {
514
- return isOne(unwrapped.right);
507
+ if (node instanceof bundled_angular_compiler_1.Binary) {
508
+ if (node.operation === '-') {
509
+ if (isCount(node.left)) {
510
+ return isOne(node.right);
515
511
  }
516
512
  else {
517
- return isCount(unwrapped.right) && isOne(unwrapped.left);
513
+ return isCount(node.right) && isOne(node.left);
518
514
  }
519
515
  }
520
516
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-template-literal.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-template-literal.ts"],"names":[],"mappings":"AAkBA,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;;AAEnD,wBAsKG"}
1
+ {"version":3,"file":"prefer-template-literal.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-template-literal.ts"],"names":[],"mappings":"AAgBA,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;;AAEnD,wBA+PG"}
@@ -5,7 +5,6 @@ const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-comp
5
5
  const utils_1 = require("@angular-eslint/utils");
6
6
  const create_eslint_rule_1 = require("../utils/create-eslint-rule");
7
7
  const literal_primitive_1 = require("../utils/literal-primitive");
8
- const unwrap_parenthesized_expression_1 = require("../utils/unwrap-parenthesized-expression");
9
8
  const messageId = 'preferTemplateLiteral';
10
9
  exports.RULE_NAME = 'prefer-template-literal';
11
10
  exports.default = (0, create_eslint_rule_1.createESLintRule)({
@@ -27,10 +26,7 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
27
26
  const { sourceCode } = context;
28
27
  return {
29
28
  'Binary[operation="+"]'(node) {
30
- const originalLeft = node.left;
31
- const originalRight = node.right;
32
- const left = (0, unwrap_parenthesized_expression_1.unwrapParenthesizedExpression)(originalLeft);
33
- const right = (0, unwrap_parenthesized_expression_1.unwrapParenthesizedExpression)(originalRight);
29
+ const { left, right } = node;
34
30
  const isLeftString = (0, literal_primitive_1.isStringLiteralPrimitive)(left) || left instanceof bundled_angular_compiler_1.TemplateLiteral;
35
31
  const isRightString = (0, literal_primitive_1.isStringLiteralPrimitive)(right) || right instanceof bundled_angular_compiler_1.TemplateLiteral;
36
32
  // If both sides are not strings, we don't report anything
@@ -43,10 +39,6 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
43
39
  if (parentIsTemplateLiteral) {
44
40
  return '';
45
41
  }
46
- // If either side is not a literal primitive, we need to use backticks for interpolation
47
- if (!(0, literal_primitive_1.isLiteralPrimitive)(left) || !(0, literal_primitive_1.isLiteralPrimitive)(right)) {
48
- return '`';
49
- }
50
42
  if (left instanceof bundled_angular_compiler_1.LiteralPrimitive &&
51
43
  right instanceof bundled_angular_compiler_1.LiteralPrimitive) {
52
44
  const leftValue = sourceCode.text.at(left.sourceSpan.start);
@@ -60,6 +52,57 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
60
52
  }
61
53
  return '`';
62
54
  }
55
+ function getLeftSideFixes(fixer, quote) {
56
+ const { start, end } = left.sourceSpan;
57
+ if (left instanceof bundled_angular_compiler_1.TemplateLiteral) {
58
+ // Remove the end ` sign from the left side
59
+ return [
60
+ fixer.replaceTextRange([start, start + 1], quote),
61
+ fixer.removeRange([end - 1, end]),
62
+ ];
63
+ }
64
+ if ((0, literal_primitive_1.isLiteralPrimitive)(left)) {
65
+ // Transform left side to template literal
66
+ return [
67
+ fixer.replaceTextRange([start, end], parentIsTemplateLiteral
68
+ ? `${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(left, '`')}`
69
+ : `${quote}${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(left, quote)}`),
70
+ ];
71
+ }
72
+ // Transform left side to template literal
73
+ return [
74
+ fixer.insertTextBeforeRange([start, end], `${quote}\${`),
75
+ fixer.insertTextAfterRange([start, end], '}'),
76
+ ];
77
+ }
78
+ function getRightSideFixes(fixer, quote) {
79
+ const { start, end } = right.sourceSpan;
80
+ if (right instanceof bundled_angular_compiler_1.TemplateLiteral) {
81
+ // Remove the start ` sign from the right side
82
+ return [
83
+ fixer.removeRange([start, start + 1]),
84
+ fixer.replaceTextRange([end - 1, end], quote),
85
+ ];
86
+ }
87
+ if ((0, literal_primitive_1.isLiteralPrimitive)(right)) {
88
+ // Transform right side to template literal if it's a string
89
+ return [
90
+ fixer.replaceTextRange([start, end], parentIsTemplateLiteral
91
+ ? `${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(right, '`')}`
92
+ : `${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(right, quote)}${quote}`),
93
+ ];
94
+ }
95
+ // Transform right side to template literal
96
+ return [
97
+ fixer.insertTextBeforeRange([start, end], '${'),
98
+ fixer.insertTextAfterRange([start, end], `}${quote}`),
99
+ ];
100
+ }
101
+ function hasParentheses(node) {
102
+ const { start, end } = node.sourceSpan;
103
+ const text = sourceCode.text.slice(start - 1, end + 1);
104
+ return text.startsWith('(') && text.endsWith(')');
105
+ }
63
106
  context.report({
64
107
  loc: {
65
108
  start: sourceCode.getLocFromIndex(start),
@@ -85,25 +128,48 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
85
128
  : `${quote}${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(left, quote)}${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(right, quote)}${quote}`));
86
129
  }
87
130
  else {
88
- // Fix the left side - handle parenthesized expressions specially
89
- if (originalLeft instanceof bundled_angular_compiler_1.ParenthesizedExpression) {
90
- fixes.push(...getLeftSideFixesForParenthesized(fixer, left, originalLeft, quote));
131
+ const leftHasParentheses = hasParentheses(left);
132
+ const rightHasParentheses = hasParentheses(right);
133
+ // Remove the left first parenthesis if it exists
134
+ if (leftHasParentheses) {
135
+ fixes.push(fixer.removeRange([
136
+ left.sourceSpan.start - 1,
137
+ left.sourceSpan.start,
138
+ ]));
91
139
  }
92
- else {
93
- fixes.push(...getLeftSideFixes(fixer, left, quote));
140
+ // Fix the left side
141
+ fixes.push(...getLeftSideFixes(fixer, quote));
142
+ // Remove the left last parenthesis if it exists
143
+ if (leftHasParentheses) {
144
+ fixes.push(fixer.removeRange([
145
+ left.sourceSpan.end,
146
+ left.sourceSpan.end + 1,
147
+ ]));
94
148
  }
95
- // Remove the `+` sign (including surrounding whitespace)
149
+ // Remove the `+` sign
96
150
  fixes.push(fixer.removeRange([
97
- originalLeft.sourceSpan.end,
98
- originalRight.sourceSpan.start,
151
+ leftHasParentheses
152
+ ? left.sourceSpan.end + 1
153
+ : left.sourceSpan.end,
154
+ rightHasParentheses
155
+ ? right.sourceSpan.start - 1
156
+ : right.sourceSpan.start,
99
157
  ]));
100
- // Fix the right side - handle parenthesized expressions specially
101
- if (originalRight instanceof bundled_angular_compiler_1.ParenthesizedExpression) {
102
- // For parenthesized expressions, we want to replace the whole thing including parens
103
- fixes.push(...getRightSideFixesForParenthesized(fixer, right, originalRight, quote));
158
+ // Remove the right first parenthesis if it exists
159
+ if (rightHasParentheses) {
160
+ fixes.push(fixer.removeRange([
161
+ right.sourceSpan.start - 1,
162
+ right.sourceSpan.start,
163
+ ]));
104
164
  }
105
- else {
106
- fixes.push(...getRightSideFixes(fixer, right, quote));
165
+ // Fix the right side
166
+ fixes.push(...getRightSideFixes(fixer, quote));
167
+ // Remove the right last parenthesis if it exists
168
+ if (rightHasParentheses) {
169
+ fixes.push(fixer.removeRange([
170
+ right.sourceSpan.end,
171
+ right.sourceSpan.end + 1,
172
+ ]));
107
173
  }
108
174
  }
109
175
  // If the parent is a template literal, remove the `}` sign
@@ -121,101 +187,3 @@ exports.default = (0, create_eslint_rule_1.createESLintRule)({
121
187
  };
122
188
  },
123
189
  });
124
- function getLeftSideFixes(fixer, left, quote) {
125
- const { start, end } = left.sourceSpan;
126
- if (left instanceof bundled_angular_compiler_1.TemplateLiteral) {
127
- // Remove the end ` sign from the left side
128
- return [
129
- fixer.replaceTextRange([start, start + 1], quote),
130
- fixer.removeRange([end - 1, end]),
131
- ];
132
- }
133
- if ((0, literal_primitive_1.isLiteralPrimitive)(left)) {
134
- // Transform left side to template literal
135
- return [
136
- fixer.replaceTextRange([start, end], quote === ''
137
- ? `${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(left, '`')}`
138
- : `${quote}${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(left, quote)}`),
139
- ];
140
- }
141
- // Transform left side to template literal
142
- return [
143
- fixer.insertTextBeforeRange([start, end], `${quote}\${`),
144
- fixer.insertTextAfterRange([start, end], '}'),
145
- ];
146
- }
147
- function getLeftSideFixesForParenthesized(fixer, innerExpression, parenthesizedExpression, quote) {
148
- const parenthesizedStart = parenthesizedExpression.sourceSpan.start;
149
- const parenthesizedEnd = parenthesizedExpression.sourceSpan.end;
150
- const innerStart = innerExpression.sourceSpan.start;
151
- const innerEnd = innerExpression.sourceSpan.end;
152
- if (innerExpression instanceof bundled_angular_compiler_1.TemplateLiteral) {
153
- // Remove the end ` sign from the inner expression and remove the parentheses
154
- return [
155
- fixer.replaceTextRange([parenthesizedStart, innerStart + 1], quote), // Replace opening paren and backtick with quote
156
- fixer.removeRange([innerEnd - 1, parenthesizedEnd]), // Remove closing backtick and paren
157
- ];
158
- }
159
- if ((0, literal_primitive_1.isLiteralPrimitive)(innerExpression)) {
160
- // Transform to template literal and remove parentheses
161
- return [
162
- fixer.replaceTextRange([parenthesizedStart, parenthesizedEnd], quote === ''
163
- ? `${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(innerExpression, '`')}`
164
- : `${quote}${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(innerExpression, quote)}`),
165
- ];
166
- }
167
- // Transform parenthesized expression to template literal by removing parens and wrapping in ${}
168
- return [
169
- fixer.replaceTextRange([parenthesizedStart, innerStart], `${quote}\${`), // Replace opening paren with quote${
170
- fixer.replaceTextRange([innerEnd, parenthesizedEnd], '}'), // Replace closing paren with }
171
- ];
172
- }
173
- function getRightSideFixes(fixer, right, quote) {
174
- const { start, end } = right.sourceSpan;
175
- if (right instanceof bundled_angular_compiler_1.TemplateLiteral) {
176
- // Remove the start ` sign from the right side
177
- return [
178
- fixer.removeRange([start, start + 1]),
179
- fixer.replaceTextRange([end - 1, end], quote),
180
- ];
181
- }
182
- if ((0, literal_primitive_1.isLiteralPrimitive)(right)) {
183
- // Transform right side to template literal if it's a string
184
- return [
185
- fixer.replaceTextRange([start, end], quote === ''
186
- ? `${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(right, '`')}`
187
- : `${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(right, quote)}${quote}`),
188
- ];
189
- }
190
- // Transform right side to template literal
191
- return [
192
- fixer.insertTextBeforeRange([start, end], '${'),
193
- fixer.insertTextAfterRange([start, end], `}${quote}`),
194
- ];
195
- }
196
- function getRightSideFixesForParenthesized(fixer, innerExpression, parenthesizedExpression, quote) {
197
- const parenthesizedStart = parenthesizedExpression.sourceSpan.start;
198
- const parenthesizedEnd = parenthesizedExpression.sourceSpan.end;
199
- const innerStart = innerExpression.sourceSpan.start;
200
- const innerEnd = innerExpression.sourceSpan.end;
201
- if (innerExpression instanceof bundled_angular_compiler_1.TemplateLiteral) {
202
- // Remove the start ` sign from the inner expression and remove the parentheses
203
- return [
204
- fixer.removeRange([parenthesizedStart, innerStart + 1]), // Remove opening paren and backtick
205
- fixer.replaceTextRange([innerEnd - 1, parenthesizedEnd], quote), // Replace closing backtick and paren with quote
206
- ];
207
- }
208
- if ((0, literal_primitive_1.isLiteralPrimitive)(innerExpression)) {
209
- // Transform to template literal and remove parentheses
210
- return [
211
- fixer.replaceTextRange([parenthesizedStart, parenthesizedEnd], quote === ''
212
- ? `${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(innerExpression, '`')}`
213
- : `${(0, literal_primitive_1.getLiteralPrimitiveStringValue)(innerExpression, quote)}${quote}`),
214
- ];
215
- }
216
- // Transform parenthesized expression to template literal by removing parens and wrapping in ${}
217
- return [
218
- fixer.replaceTextRange([parenthesizedStart, innerStart], '${'), // Replace opening paren with ${
219
- fixer.replaceTextRange([innerEnd, parenthesizedEnd], `}${quote}`), // Replace closing paren with }quote
220
- ];
221
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular-eslint/eslint-plugin-template",
3
- "version": "19.8.1-alpha.1",
3
+ "version": "19.8.1",
4
4
  "description": "ESLint plugin for Angular Templates",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -20,19 +20,19 @@
20
20
  "dependencies": {
21
21
  "aria-query": "5.3.2",
22
22
  "axobject-query": "4.1.0",
23
- "@angular-eslint/bundled-angular-compiler": "19.8.1-alpha.1",
24
- "@angular-eslint/utils": "19.8.1-alpha.1"
23
+ "@angular-eslint/bundled-angular-compiler": "19.8.1",
24
+ "@angular-eslint/utils": "19.8.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/aria-query": "5.0.4",
28
- "@angular-eslint/test-utils": "19.8.1-alpha.1"
28
+ "@angular-eslint/test-utils": "19.8.1"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@typescript-eslint/types": "^7.11.0 || ^8.0.0",
32
32
  "@typescript-eslint/utils": "^7.11.0 || ^8.0.0",
33
33
  "eslint": "^8.57.0 || ^9.0.0",
34
34
  "typescript": "*",
35
- "@angular-eslint/template-parser": "19.8.1-alpha.1"
35
+ "@angular-eslint/template-parser": "19.8.1"
36
36
  },
37
37
  "gitHead": "e2006e5e9c99e5a943d1a999e0efa5247d29ec24"
38
38
  }
@@ -1,3 +0,0 @@
1
- import { type AST } from '@angular-eslint/bundled-angular-compiler';
2
- export declare function unwrapParenthesizedExpression(node: AST): AST;
3
- //# sourceMappingURL=unwrap-parenthesized-expression.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"unwrap-parenthesized-expression.d.ts","sourceRoot":"","sources":["../../src/utils/unwrap-parenthesized-expression.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,GAAG,EAET,MAAM,0CAA0C,CAAC;AAElD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,CAE5D"}
@@ -1,7 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.unwrapParenthesizedExpression = unwrapParenthesizedExpression;
4
- const bundled_angular_compiler_1 = require("@angular-eslint/bundled-angular-compiler");
5
- function unwrapParenthesizedExpression(node) {
6
- return node instanceof bundled_angular_compiler_1.ParenthesizedExpression ? node.expression : node;
7
- }