@taiga-ui/eslint-plugin-experience-next 0.526.0 → 0.528.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 +1 -0
- package/index.d.ts +3 -0
- package/index.esm.js +331 -159
- package/package.json +3 -3
- package/rules/recommended/class-accessibility-spacing.d.ts +4 -0
- package/rules/recommended/injection-token-description.d.ts +2 -1
- package/rules/recommended/no-implicit-public.d.ts +2 -1
- package/rules/utils/angular/import-fix-helpers.d.ts +1 -1
- package/rules/utils/ast/class-members.d.ts +8 -0
- package/rules/utils/ast/spacing.d.ts +6 -0
package/README.md
CHANGED
|
@@ -75,6 +75,7 @@ from third-party plugins. The exact severities and file globs live in
|
|
|
75
75
|
| [array-as-const](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/array-as-const.md) | Exported array of class references should be marked with `as const` | | 🔧 | |
|
|
76
76
|
| [at-compat](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/at-compat.md) | Keep built-in `.at()` and indexed access aligned with the TypeScript target | ✅ | 🔧 | |
|
|
77
77
|
| [attrs-newline](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/attrs-newline.md) | Enforce one attribute per line when a start tag spans multiple lines | ✅ | 🔧 | |
|
|
78
|
+
| [class-accessibility-spacing](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/class-accessibility-spacing.md) | Separate adjacent class members with a blank line when their accessibility group changes | ✅ | 🔧 | |
|
|
78
79
|
| [class-property-naming](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/class-property-naming.md) | Enforce custom naming for class properties based on their type | | 🔧 | |
|
|
79
80
|
| [decorator-key-sort](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/decorator-key-sort.md) | Sorts the keys of the object passed to the `@Component/@Injectable/@NgModule/@Pipe` decorator | ✅ | 🔧 | |
|
|
80
81
|
| [element-newline](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/element-newline.md) | Require line breaks around block-level child nodes in HTML templates | ✅ | 🔧 | |
|
package/index.d.ts
CHANGED
|
@@ -18,6 +18,9 @@ declare const plugin: {
|
|
|
18
18
|
'attrs-newline': import("eslint").Rule.RuleModule & {
|
|
19
19
|
name: string;
|
|
20
20
|
};
|
|
21
|
+
'class-accessibility-spacing': import("@typescript-eslint/utils/ts-eslint").RuleModule<"classAccessibilitySpacing", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
22
|
+
name: string;
|
|
23
|
+
};
|
|
21
24
|
'class-property-naming': import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidName", [import("./rules/taiga-specific/class-property-naming").RuleConfig[]], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
22
25
|
name: string;
|
|
23
26
|
};
|
package/index.esm.js
CHANGED
|
@@ -465,8 +465,111 @@ const TUI_MEMBER_ORDERING_CONVENTION = [
|
|
|
465
465
|
'#private-instance-method',
|
|
466
466
|
];
|
|
467
467
|
|
|
468
|
+
function isSingleLineNode(node) {
|
|
469
|
+
return node.loc.start.line === node.loc.end.line;
|
|
470
|
+
}
|
|
471
|
+
function isLineBreakCharacter(char) {
|
|
472
|
+
return char === '\n' || char === '\r';
|
|
473
|
+
}
|
|
474
|
+
function hasCommentLikeText(text) {
|
|
475
|
+
return text.includes('//') || text.includes('/*');
|
|
476
|
+
}
|
|
477
|
+
function hasBlankLine(text) {
|
|
478
|
+
let lineBreaks = 0;
|
|
479
|
+
for (let index = 0; index < text.length; index++) {
|
|
480
|
+
const char = text[index];
|
|
481
|
+
if (char === '\n') {
|
|
482
|
+
lineBreaks++;
|
|
483
|
+
}
|
|
484
|
+
else if (char === '\r') {
|
|
485
|
+
lineBreaks++;
|
|
486
|
+
if (text[index + 1] === '\n') {
|
|
487
|
+
index++;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (lineBreaks > 1) {
|
|
491
|
+
return true;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
function hasBlankLineBetweenNodes(text) {
|
|
497
|
+
const lines = splitLines(text);
|
|
498
|
+
const linesBetweenNodes = lines.slice(1, -1);
|
|
499
|
+
return linesBetweenNodes.some((line) => line.trim() === '');
|
|
500
|
+
}
|
|
501
|
+
function getLineBreak(text) {
|
|
502
|
+
if (text.includes('\r\n')) {
|
|
503
|
+
return '\r\n';
|
|
504
|
+
}
|
|
505
|
+
return text.includes('\r') ? '\r' : '\n';
|
|
506
|
+
}
|
|
507
|
+
function hasLineBreak(text) {
|
|
508
|
+
for (const char of text) {
|
|
509
|
+
if (isLineBreakCharacter(char)) {
|
|
510
|
+
return true;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return false;
|
|
514
|
+
}
|
|
515
|
+
function getLeadingIndentation(text) {
|
|
516
|
+
let index = 0;
|
|
517
|
+
while (index < text.length && (text[index] === ' ' || text[index] === '\t')) {
|
|
518
|
+
index++;
|
|
519
|
+
}
|
|
520
|
+
return text.slice(0, index);
|
|
521
|
+
}
|
|
522
|
+
function getLineStartOffset(text, offset) {
|
|
523
|
+
let index = offset - 1;
|
|
524
|
+
while (index >= 0) {
|
|
525
|
+
const char = text[index];
|
|
526
|
+
if (isLineBreakCharacter(char)) {
|
|
527
|
+
return index + 1;
|
|
528
|
+
}
|
|
529
|
+
index--;
|
|
530
|
+
}
|
|
531
|
+
return 0;
|
|
532
|
+
}
|
|
533
|
+
function getLineEndOffset(text, lineStartOffset) {
|
|
534
|
+
let index = lineStartOffset;
|
|
535
|
+
while (index < text.length) {
|
|
536
|
+
const char = text[index];
|
|
537
|
+
if (isLineBreakCharacter(char)) {
|
|
538
|
+
return index;
|
|
539
|
+
}
|
|
540
|
+
index++;
|
|
541
|
+
}
|
|
542
|
+
return text.length;
|
|
543
|
+
}
|
|
544
|
+
function getNextLineStartOffset(text, offset) {
|
|
545
|
+
let index = offset;
|
|
546
|
+
while (index < text.length) {
|
|
547
|
+
const char = text[index];
|
|
548
|
+
if (char === '\r') {
|
|
549
|
+
return text[index + 1] === '\n' ? index + 2 : index + 1;
|
|
550
|
+
}
|
|
551
|
+
if (char === '\n') {
|
|
552
|
+
return index + 1;
|
|
553
|
+
}
|
|
554
|
+
index++;
|
|
555
|
+
}
|
|
556
|
+
return offset;
|
|
557
|
+
}
|
|
558
|
+
function splitLines(text) {
|
|
559
|
+
return text.split(/\r\n|\n|\r/);
|
|
560
|
+
}
|
|
561
|
+
function getIndentAtOffset(text, offset) {
|
|
562
|
+
const lineStart = getLineStartOffset(text, offset);
|
|
563
|
+
const indent = text.slice(lineStart, offset);
|
|
564
|
+
return indent.trim() === '' ? indent : '';
|
|
565
|
+
}
|
|
566
|
+
function getSpacingReplacement(sourceCode, betweenText, nextLine, blankLineCount) {
|
|
567
|
+
const indentation = getLeadingIndentation(sourceCode.lines[nextLine - 1] ?? '');
|
|
568
|
+
return `${getLineBreak(betweenText).repeat(blankLineCount + 1)}${indentation}`;
|
|
569
|
+
}
|
|
570
|
+
|
|
468
571
|
function buildAST(text) {
|
|
469
|
-
const lines = text
|
|
572
|
+
const lines = splitLines(text);
|
|
470
573
|
const lastLine = lines[lines.length - 1] ?? '';
|
|
471
574
|
return {
|
|
472
575
|
body: [],
|
|
@@ -1149,6 +1252,7 @@ var recommended = defineConfig([
|
|
|
1149
1252
|
'@angular-eslint/use-lifecycle-interface': 'error',
|
|
1150
1253
|
'@angular-eslint/use-pipe-transform-interface': 'error',
|
|
1151
1254
|
'@taiga-ui/experience-next/at-compat': 'error',
|
|
1255
|
+
'@taiga-ui/experience-next/class-accessibility-spacing': 'error',
|
|
1152
1256
|
'@taiga-ui/experience-next/decorator-key-sort': [
|
|
1153
1257
|
'error',
|
|
1154
1258
|
{
|
|
@@ -14876,6 +14980,40 @@ function getParenthesizedExpression(expression) {
|
|
|
14876
14980
|
: null;
|
|
14877
14981
|
}
|
|
14878
14982
|
|
|
14983
|
+
function isFieldLikeMember(member) {
|
|
14984
|
+
return (member.type === dist$4.AST_NODE_TYPES.PropertyDefinition ||
|
|
14985
|
+
member.type === dist$4.AST_NODE_TYPES.TSAbstractPropertyDefinition);
|
|
14986
|
+
}
|
|
14987
|
+
function isAccessorMember(member) {
|
|
14988
|
+
return (member.type === dist$4.AST_NODE_TYPES.MethodDefinition &&
|
|
14989
|
+
(member.kind === 'get' || member.kind === 'set'));
|
|
14990
|
+
}
|
|
14991
|
+
function isRelevantSpacingClassMember(member) {
|
|
14992
|
+
return isFieldLikeMember(member) || isAccessorMember(member);
|
|
14993
|
+
}
|
|
14994
|
+
function isAccessibilityClassMember(member) {
|
|
14995
|
+
switch (member.type) {
|
|
14996
|
+
case dist$4.AST_NODE_TYPES.AccessorProperty:
|
|
14997
|
+
case dist$4.AST_NODE_TYPES.MethodDefinition:
|
|
14998
|
+
case dist$4.AST_NODE_TYPES.PropertyDefinition:
|
|
14999
|
+
case dist$4.AST_NODE_TYPES.TSAbstractAccessorProperty:
|
|
15000
|
+
case dist$4.AST_NODE_TYPES.TSAbstractMethodDefinition:
|
|
15001
|
+
case dist$4.AST_NODE_TYPES.TSAbstractPropertyDefinition:
|
|
15002
|
+
case dist$4.AST_NODE_TYPES.TSIndexSignature:
|
|
15003
|
+
return true;
|
|
15004
|
+
default:
|
|
15005
|
+
return false;
|
|
15006
|
+
}
|
|
15007
|
+
}
|
|
15008
|
+
function isEcmascriptPrivateClassMember(member) {
|
|
15009
|
+
return 'key' in member && member.key.type === dist$4.AST_NODE_TYPES.PrivateIdentifier;
|
|
15010
|
+
}
|
|
15011
|
+
function getAccessibilityGroup(member) {
|
|
15012
|
+
return isEcmascriptPrivateClassMember(member)
|
|
15013
|
+
? 'private'
|
|
15014
|
+
: (member.accessibility ?? 'public');
|
|
15015
|
+
}
|
|
15016
|
+
|
|
14879
15017
|
const EQUALITY_OPERATORS = new Set(['!=', '!==', '==', '===']);
|
|
14880
15018
|
function getChainExpressionRoot(node) {
|
|
14881
15019
|
const parent = getParentNode(node);
|
|
@@ -15091,62 +15229,11 @@ function getMemberExpressionPropertyName(node) {
|
|
|
15091
15229
|
return node.computed ? getStaticStringValue(node.property) : null;
|
|
15092
15230
|
}
|
|
15093
15231
|
function getClassMemberName(member) {
|
|
15094
|
-
return member
|
|
15232
|
+
return isEcmascriptPrivateClassMember(member)
|
|
15095
15233
|
? null
|
|
15096
15234
|
: getStaticPropertyName(member.key);
|
|
15097
15235
|
}
|
|
15098
15236
|
|
|
15099
|
-
function isSingleLineNode(node) {
|
|
15100
|
-
return node.loc.start.line === node.loc.end.line;
|
|
15101
|
-
}
|
|
15102
|
-
function hasCommentLikeText(text) {
|
|
15103
|
-
return text.includes('//') || text.includes('/*');
|
|
15104
|
-
}
|
|
15105
|
-
function hasBlankLine(text) {
|
|
15106
|
-
let lineBreaks = 0;
|
|
15107
|
-
for (let index = 0; index < text.length; index++) {
|
|
15108
|
-
const char = text[index];
|
|
15109
|
-
if (char === '\n') {
|
|
15110
|
-
lineBreaks++;
|
|
15111
|
-
}
|
|
15112
|
-
else if (char === '\r') {
|
|
15113
|
-
lineBreaks++;
|
|
15114
|
-
if (text[index + 1] === '\n') {
|
|
15115
|
-
index++;
|
|
15116
|
-
}
|
|
15117
|
-
}
|
|
15118
|
-
if (lineBreaks > 1) {
|
|
15119
|
-
return true;
|
|
15120
|
-
}
|
|
15121
|
-
}
|
|
15122
|
-
return false;
|
|
15123
|
-
}
|
|
15124
|
-
function getLineBreak(text) {
|
|
15125
|
-
if (text.includes('\r\n')) {
|
|
15126
|
-
return '\r\n';
|
|
15127
|
-
}
|
|
15128
|
-
return text.includes('\r') ? '\r' : '\n';
|
|
15129
|
-
}
|
|
15130
|
-
function getLeadingIndentation(text) {
|
|
15131
|
-
let index = 0;
|
|
15132
|
-
while (index < text.length && (text[index] === ' ' || text[index] === '\t')) {
|
|
15133
|
-
index++;
|
|
15134
|
-
}
|
|
15135
|
-
return text.slice(0, index);
|
|
15136
|
-
}
|
|
15137
|
-
function getLineStartOffset(text, offset) {
|
|
15138
|
-
return text.lastIndexOf('\n', offset - 1) + 1;
|
|
15139
|
-
}
|
|
15140
|
-
function getIndentAtOffset(text, offset) {
|
|
15141
|
-
const lineStart = getLineStartOffset(text, offset);
|
|
15142
|
-
const indent = text.slice(lineStart, offset);
|
|
15143
|
-
return indent.trim() === '' ? indent : '';
|
|
15144
|
-
}
|
|
15145
|
-
function getSpacingReplacement(sourceCode, betweenText, nextLine, blankLineCount) {
|
|
15146
|
-
const indentation = getLeadingIndentation(sourceCode.lines[nextLine - 1] ?? '');
|
|
15147
|
-
return `${getLineBreak(betweenText).repeat(blankLineCount + 1)}${indentation}`;
|
|
15148
|
-
}
|
|
15149
|
-
|
|
15150
15237
|
const RULE_DOCS_BASE_URL = 'https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs';
|
|
15151
15238
|
const ruleCreator = dist$4.ESLintUtils.RuleCreator((name) => `${RULE_DOCS_BASE_URL}/${name}.md`);
|
|
15152
15239
|
function createRule(options) {
|
|
@@ -216065,12 +216152,10 @@ function getPreferredTemporaryNames(node) {
|
|
|
216065
216152
|
];
|
|
216066
216153
|
}
|
|
216067
216154
|
function getClassElementName(member) {
|
|
216068
|
-
if (
|
|
216069
|
-
return
|
|
216155
|
+
if (isEcmascriptPrivateClassMember(member)) {
|
|
216156
|
+
return member.key.name;
|
|
216070
216157
|
}
|
|
216071
|
-
return member.key
|
|
216072
|
-
? member.key.name
|
|
216073
|
-
: getStaticPropertyName(member.key);
|
|
216158
|
+
return 'key' in member ? getStaticPropertyName(member.key) : null;
|
|
216074
216159
|
}
|
|
216075
216160
|
function hasClassElementName(classBody, name) {
|
|
216076
216161
|
return classBody.body.some((member) => getClassElementName(member) === name);
|
|
@@ -216220,7 +216305,7 @@ function getLastIndexFix(fixer, sourceCode, node, call) {
|
|
|
216220
216305
|
}
|
|
216221
216306
|
return null;
|
|
216222
216307
|
}
|
|
216223
|
-
const rule$
|
|
216308
|
+
const rule$Y = createRule({
|
|
216224
216309
|
create(context) {
|
|
216225
216310
|
const typeAwareContext = getTypeAwareRuleContext(context);
|
|
216226
216311
|
const compilerOptions = typeAwareContext.tsProgram.getCompilerOptions();
|
|
@@ -248017,15 +248102,16 @@ function buildMultilineStartTag(node, sourceText) {
|
|
|
248017
248102
|
const closing = sourceText
|
|
248018
248103
|
.slice(lastAttr ? lastAttr.sourceSpan.end.offset : startTag.end.offset, startTag.end.offset)
|
|
248019
248104
|
.trimStart();
|
|
248105
|
+
const lineBreak = getLineBreak(sourceText);
|
|
248020
248106
|
return [
|
|
248021
248107
|
tagStart.trimEnd(),
|
|
248022
248108
|
...attrs.map((attr) => sourceText
|
|
248023
248109
|
.slice(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset)
|
|
248024
248110
|
.trim()),
|
|
248025
248111
|
closing,
|
|
248026
|
-
].join(
|
|
248112
|
+
].join(lineBreak);
|
|
248027
248113
|
}
|
|
248028
|
-
const rule$
|
|
248114
|
+
const rule$X = createRule({
|
|
248029
248115
|
name: 'attrs-newline',
|
|
248030
248116
|
rule: {
|
|
248031
248117
|
create(context) {
|
|
@@ -248111,6 +248197,59 @@ const rule$W = createRule({
|
|
|
248111
248197
|
},
|
|
248112
248198
|
});
|
|
248113
248199
|
|
|
248200
|
+
const rule$W = createRule({
|
|
248201
|
+
create(context) {
|
|
248202
|
+
const sourceCode = context.sourceCode;
|
|
248203
|
+
return {
|
|
248204
|
+
ClassBody(node) {
|
|
248205
|
+
for (let index = 0; index < node.body.length - 1; index++) {
|
|
248206
|
+
const current = node.body[index];
|
|
248207
|
+
const next = node.body[index + 1];
|
|
248208
|
+
if (!current ||
|
|
248209
|
+
!next ||
|
|
248210
|
+
!isAccessibilityClassMember(current) ||
|
|
248211
|
+
!isAccessibilityClassMember(next)) {
|
|
248212
|
+
continue;
|
|
248213
|
+
}
|
|
248214
|
+
const accessibilityGroupChanged = getAccessibilityGroup(current) !== getAccessibilityGroup(next);
|
|
248215
|
+
if (!accessibilityGroupChanged) {
|
|
248216
|
+
continue;
|
|
248217
|
+
}
|
|
248218
|
+
const betweenText = sourceCode.text.slice(current.range[1], next.range[0]);
|
|
248219
|
+
const missingBlankLine = !hasBlankLineBetweenNodes(betweenText);
|
|
248220
|
+
if (!missingBlankLine) {
|
|
248221
|
+
continue;
|
|
248222
|
+
}
|
|
248223
|
+
const reportTarget = {
|
|
248224
|
+
messageId: 'classAccessibilitySpacing',
|
|
248225
|
+
node: next,
|
|
248226
|
+
};
|
|
248227
|
+
if (hasCommentLikeText(betweenText)) {
|
|
248228
|
+
context.report(reportTarget);
|
|
248229
|
+
continue;
|
|
248230
|
+
}
|
|
248231
|
+
context.report({
|
|
248232
|
+
...reportTarget,
|
|
248233
|
+
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 1)),
|
|
248234
|
+
});
|
|
248235
|
+
}
|
|
248236
|
+
},
|
|
248237
|
+
};
|
|
248238
|
+
},
|
|
248239
|
+
meta: {
|
|
248240
|
+
docs: {
|
|
248241
|
+
description: 'Require a blank line between adjacent class members when their accessibility group changes',
|
|
248242
|
+
},
|
|
248243
|
+
fixable: 'code',
|
|
248244
|
+
messages: {
|
|
248245
|
+
classAccessibilitySpacing: 'Class members with different accessibility groups should be separated by a blank line',
|
|
248246
|
+
},
|
|
248247
|
+
schema: [],
|
|
248248
|
+
type: 'layout',
|
|
248249
|
+
},
|
|
248250
|
+
name: 'class-accessibility-spacing',
|
|
248251
|
+
});
|
|
248252
|
+
|
|
248114
248253
|
function isObject(node) {
|
|
248115
248254
|
return node?.type === dist$3.AST_NODE_TYPES.ObjectExpression;
|
|
248116
248255
|
}
|
|
@@ -248301,6 +248440,7 @@ const rule$U = createRule({
|
|
|
248301
248440
|
name: 'element-newline',
|
|
248302
248441
|
rule: {
|
|
248303
248442
|
create(context) {
|
|
248443
|
+
const lineBreak = getLineBreak(context.sourceCode.getText());
|
|
248304
248444
|
return {
|
|
248305
248445
|
Element(rawNode) {
|
|
248306
248446
|
const node = rawNode;
|
|
@@ -248321,7 +248461,7 @@ const rule$U = createRule({
|
|
|
248321
248461
|
fix: (fixer) => fixer.insertTextBeforeRange([
|
|
248322
248462
|
firstChild.sourceSpan.start.offset,
|
|
248323
248463
|
firstChild.sourceSpan.start.offset,
|
|
248324
|
-
],
|
|
248464
|
+
], lineBreak),
|
|
248325
248465
|
loc: sourceSpanToLoc(firstChild.sourceSpan),
|
|
248326
248466
|
messageId: MESSAGE_ID$i,
|
|
248327
248467
|
});
|
|
@@ -248339,7 +248479,7 @@ const rule$U = createRule({
|
|
|
248339
248479
|
fix: (fixer) => fixer.insertTextAfterRange([
|
|
248340
248480
|
child.sourceSpan.end.offset,
|
|
248341
248481
|
child.sourceSpan.end.offset,
|
|
248342
|
-
],
|
|
248482
|
+
], lineBreak),
|
|
248343
248483
|
loc: sourceSpanToLoc(next.sourceSpan),
|
|
248344
248484
|
messageId: MESSAGE_ID$i,
|
|
248345
248485
|
});
|
|
@@ -248353,7 +248493,7 @@ const rule$U = createRule({
|
|
|
248353
248493
|
fix: (fixer) => fixer.insertTextAfterRange([
|
|
248354
248494
|
lastChild.sourceSpan.end.offset,
|
|
248355
248495
|
lastChild.sourceSpan.end.offset,
|
|
248356
|
-
],
|
|
248496
|
+
], lineBreak),
|
|
248357
248497
|
loc: sourceSpanToLoc(lastChild.sourceSpan),
|
|
248358
248498
|
messageId: MESSAGE_ID$i,
|
|
248359
248499
|
});
|
|
@@ -248644,19 +248784,21 @@ function getAttachedComments(hostObject, properties, sourceCode, comments) {
|
|
|
248644
248784
|
return usedComments.size === comments.length ? attached : null;
|
|
248645
248785
|
}
|
|
248646
248786
|
function renderFixWithComments(hostObject, sortedProperties, sourceCode, attachedComments) {
|
|
248787
|
+
const lineBreak = getLineBreak(sourceCode.text);
|
|
248647
248788
|
const objectIndentation = getLineIndentation(sourceCode.text, hostObject.range[0]);
|
|
248648
248789
|
const propertyIndentation = getPropertyIndentation(hostObject, sortedProperties, sourceCode.text, attachedComments);
|
|
248649
|
-
return `{
|
|
248790
|
+
return `{${lineBreak}${sortedProperties
|
|
248650
248791
|
.map(({ node }, index) => renderPropertyWithComments(node, attachedComments.get(node), sourceCode, propertyIndentation, index === sortedProperties.length - 1))
|
|
248651
|
-
.join(
|
|
248792
|
+
.join(lineBreak)}${lineBreak}${objectIndentation}}`;
|
|
248652
248793
|
}
|
|
248653
248794
|
function renderPropertyWithComments(property, attachedComments, sourceCode, propertyIndentation, isLast) {
|
|
248795
|
+
const lineBreak = getLineBreak(sourceCode.text);
|
|
248654
248796
|
const lines = attachedComments?.leading.map((comment) => `${propertyIndentation}${sourceCode.text.slice(...comment.range)}`) ?? [];
|
|
248655
248797
|
const trailingComment = attachedComments?.trailing
|
|
248656
248798
|
? ` ${sourceCode.text.slice(...attachedComments.trailing.range)}`
|
|
248657
248799
|
: '';
|
|
248658
248800
|
lines.push(`${propertyIndentation}${sourceCode.getText(property)}${isLast ? '' : ','}${trailingComment}`);
|
|
248659
|
-
return lines.join(
|
|
248801
|
+
return lines.join(lineBreak);
|
|
248660
248802
|
}
|
|
248661
248803
|
function getPropertyIndentation(hostObject, properties, sourceText, attachedComments) {
|
|
248662
248804
|
for (const { node } of properties) {
|
|
@@ -248670,9 +248812,7 @@ function getPropertyIndentation(hostObject, properties, sourceText, attachedComm
|
|
|
248670
248812
|
}
|
|
248671
248813
|
function getLineIndentation(sourceText, offset) {
|
|
248672
248814
|
let lineStart = offset;
|
|
248673
|
-
while (lineStart > 0 &&
|
|
248674
|
-
sourceText[lineStart - 1] !== '\n' &&
|
|
248675
|
-
sourceText[lineStart - 1] !== '\r') {
|
|
248815
|
+
while (lineStart > 0 && !isLineBreakCharacter(sourceText[lineStart - 1])) {
|
|
248676
248816
|
lineStart--;
|
|
248677
248817
|
}
|
|
248678
248818
|
let indentationEnd = lineStart;
|
|
@@ -249382,11 +249522,15 @@ const rule$R = createRule({
|
|
|
249382
249522
|
}
|
|
249383
249523
|
function buildImportRemovalFix(fixer, node) {
|
|
249384
249524
|
const [start, end] = node.range;
|
|
249385
|
-
const lineStart = sourceCode.text
|
|
249525
|
+
const lineStart = getLineStartOffset(sourceCode.text, start);
|
|
249386
249526
|
const removeStart = /^\s*$/.test(sourceCode.text.slice(lineStart, start))
|
|
249387
249527
|
? lineStart
|
|
249388
249528
|
: start;
|
|
249389
|
-
const
|
|
249529
|
+
const lineEnd = getLineEndOffset(sourceCode.text, end);
|
|
249530
|
+
const isImportLastStatementOnLine = sourceCode.text.slice(end, lineEnd).trim() === '';
|
|
249531
|
+
const removeEnd = isImportLastStatementOnLine
|
|
249532
|
+
? getNextLineStartOffset(sourceCode.text, end)
|
|
249533
|
+
: end;
|
|
249390
249534
|
return [fixer.removeRange([removeStart, removeEnd])];
|
|
249391
249535
|
}
|
|
249392
249536
|
function buildDuplicateImportFix(fixer, first, rest) {
|
|
@@ -249700,7 +249844,7 @@ const rule$R = createRule({
|
|
|
249700
249844
|
const relPath = computeRelativeImportPath(context.filename, sourceFilePath);
|
|
249701
249845
|
newImports.push(`${importPrefix} {${names.join(', ')}} from ${quote}${relPath}${quote}${semi}`);
|
|
249702
249846
|
}
|
|
249703
|
-
return newImports.join(
|
|
249847
|
+
return newImports.join(getLineBreak(sourceCode.text));
|
|
249704
249848
|
}
|
|
249705
249849
|
function checkDefaultImport(node) {
|
|
249706
249850
|
if ((!checkDefaultImports &&
|
|
@@ -250050,17 +250194,18 @@ function getDescriptionNode(node) {
|
|
|
250050
250194
|
function prependTokenName(text, name) {
|
|
250051
250195
|
return `${text.slice(0, 1)}[${name}]: ${text.slice(1)}`;
|
|
250052
250196
|
}
|
|
250053
|
-
function getNgDevModeDeclarationFix(program, fixer) {
|
|
250197
|
+
function getNgDevModeDeclarationFix(program, fixer, sourceCode) {
|
|
250054
250198
|
const lastImport = [...program.body]
|
|
250055
250199
|
.reverse()
|
|
250056
250200
|
.find((statement) => statement.type === dist$3.AST_NODE_TYPES.ImportDeclaration);
|
|
250201
|
+
const lineBreak = getLineBreak(sourceCode.text);
|
|
250057
250202
|
if (lastImport) {
|
|
250058
|
-
return fixer.insertTextAfter(lastImport,
|
|
250203
|
+
return fixer.insertTextAfter(lastImport, `${lineBreak}${lineBreak}declare const ngDevMode: boolean;`);
|
|
250059
250204
|
}
|
|
250060
250205
|
const [firstStatement] = program.body;
|
|
250061
250206
|
return firstStatement
|
|
250062
|
-
? fixer.insertTextBefore(firstStatement,
|
|
250063
|
-
: fixer.insertTextBeforeRange([0, 0],
|
|
250207
|
+
? fixer.insertTextBefore(firstStatement, `declare const ngDevMode: boolean;${lineBreak}${lineBreak}`)
|
|
250208
|
+
: fixer.insertTextBeforeRange([0, 0], `declare const ngDevMode: boolean;${lineBreak}`);
|
|
250064
250209
|
}
|
|
250065
250210
|
const rule$Q = createRule({
|
|
250066
250211
|
create(context) {
|
|
@@ -250090,7 +250235,7 @@ const rule$Q = createRule({
|
|
|
250090
250235
|
shouldAddNgDevModeDeclaration &&
|
|
250091
250236
|
!hasVariableInScope(sourceCode, description, NG_DEV_MODE)) {
|
|
250092
250237
|
shouldAddNgDevModeDeclaration = false;
|
|
250093
|
-
fixes.unshift(getNgDevModeDeclarationFix(program, fixer));
|
|
250238
|
+
fixes.unshift(getNgDevModeDeclarationFix(program, fixer, sourceCode));
|
|
250094
250239
|
}
|
|
250095
250240
|
return fixes;
|
|
250096
250241
|
},
|
|
@@ -250708,11 +250853,10 @@ function getSinglePropertyRange(text, property) {
|
|
|
250708
250853
|
: [property.range[0], property.range[1]];
|
|
250709
250854
|
}
|
|
250710
250855
|
function getLineStart(text, index) {
|
|
250711
|
-
return text
|
|
250856
|
+
return getLineStartOffset(text, index);
|
|
250712
250857
|
}
|
|
250713
250858
|
function getNextLineStart(text, index) {
|
|
250714
|
-
|
|
250715
|
-
return lineEnd === -1 ? index : lineEnd + 1;
|
|
250859
|
+
return getNextLineStartOffset(text, index);
|
|
250716
250860
|
}
|
|
250717
250861
|
function hasCommentsInRange(sourceCode, [start, end]) {
|
|
250718
250862
|
return sourceCode
|
|
@@ -251170,40 +251314,78 @@ const rule$H = createRule({
|
|
|
251170
251314
|
rule: config$3,
|
|
251171
251315
|
});
|
|
251172
251316
|
|
|
251317
|
+
function isClassMemberCandidate(node) {
|
|
251318
|
+
return (node.type === dist$4.AST_NODE_TYPES.MethodDefinition ||
|
|
251319
|
+
node.type === dist$4.AST_NODE_TYPES.PropertyDefinition);
|
|
251320
|
+
}
|
|
251321
|
+
function isConstructorMember(node) {
|
|
251322
|
+
return node.type === dist$4.AST_NODE_TYPES.MethodDefinition && node.kind === 'constructor';
|
|
251323
|
+
}
|
|
251324
|
+
function getParameterPropertyName(node) {
|
|
251325
|
+
const { parameter } = node;
|
|
251326
|
+
return parameter.type === dist$4.AST_NODE_TYPES.Identifier
|
|
251327
|
+
? parameter.name
|
|
251328
|
+
: parameter.left.name;
|
|
251329
|
+
}
|
|
251330
|
+
function getCandidateName(node) {
|
|
251331
|
+
return node.type === dist$4.AST_NODE_TYPES.TSParameterProperty
|
|
251332
|
+
? (getParameterPropertyName(node) ?? 'member')
|
|
251333
|
+
: (getStaticPropertyName(node.key) ?? 'member');
|
|
251334
|
+
}
|
|
251335
|
+
function getCandidateKind(node) {
|
|
251336
|
+
return node.type === dist$4.AST_NODE_TYPES.MethodDefinition ? node.kind : 'property';
|
|
251337
|
+
}
|
|
251338
|
+
function getFirstNonWhitespaceOffset(text, offset) {
|
|
251339
|
+
let index = offset;
|
|
251340
|
+
while (index < text.length && text[index]?.trim() === '') {
|
|
251341
|
+
index++;
|
|
251342
|
+
}
|
|
251343
|
+
return index;
|
|
251344
|
+
}
|
|
251345
|
+
function getPublicModifierInsertion(options) {
|
|
251346
|
+
const { node, sourceCode } = options;
|
|
251347
|
+
const lastDecoratorIndex = node.decorators.length - 1;
|
|
251348
|
+
const lastDecorator = node.decorators[lastDecoratorIndex];
|
|
251349
|
+
if (lastDecorator) {
|
|
251350
|
+
const [, end] = lastDecorator.range;
|
|
251351
|
+
const memberStart = getFirstNonWhitespaceOffset(sourceCode.text, end);
|
|
251352
|
+
const hasWhitespaceAfterDecorator = memberStart > end;
|
|
251353
|
+
return {
|
|
251354
|
+
range: [memberStart, memberStart],
|
|
251355
|
+
text: hasWhitespaceAfterDecorator ? 'public ' : ' public ',
|
|
251356
|
+
};
|
|
251357
|
+
}
|
|
251358
|
+
return {
|
|
251359
|
+
range: [node.range[0], node.range[0]],
|
|
251360
|
+
text: 'public ',
|
|
251361
|
+
};
|
|
251362
|
+
}
|
|
251173
251363
|
const rule$G = createRule({
|
|
251174
251364
|
create(context) {
|
|
251365
|
+
const sourceCode = context.sourceCode;
|
|
251175
251366
|
const checkImplicitPublic = (node) => {
|
|
251176
251367
|
const classRef = getEnclosingClass(node);
|
|
251177
|
-
if (!classRef
|
|
251178
|
-
node.kind === 'constructor' ||
|
|
251179
|
-
!!node?.accessibility ||
|
|
251180
|
-
node.key?.type === dist$4.AST_NODE_TYPES.PrivateIdentifier) {
|
|
251368
|
+
if (!classRef) {
|
|
251181
251369
|
return;
|
|
251182
251370
|
}
|
|
251183
|
-
const
|
|
251184
|
-
|
|
251185
|
-
(node
|
|
251186
|
-
|
|
251187
|
-
|
|
251188
|
-
node?.range ?? [0, 0];
|
|
251189
|
-
if (node.kind === 'set' || node.kind === 'get') {
|
|
251190
|
-
const [start, end] = node.key.range;
|
|
251191
|
-
range = [start - node.kind.length - 1, end - node.kind.length - 1];
|
|
251192
|
-
}
|
|
251193
|
-
else if (node.kind === 'method' && node.key?.object?.name === 'Symbol') {
|
|
251194
|
-
const [start, end] = range;
|
|
251195
|
-
range = [start - 1, end - 1];
|
|
251196
|
-
}
|
|
251197
|
-
if (node.type === 'PropertyDefinition' && node.decorators?.length > 0) {
|
|
251198
|
-
const [, end] = node.decorators[node.decorators.length - 1].range ?? [];
|
|
251199
|
-
range = [end + 1, end + 2];
|
|
251371
|
+
const privateNameCannotBePublic = isClassMemberCandidate(node) && isEcmascriptPrivateClassMember(node);
|
|
251372
|
+
if (isConstructorMember(node) ||
|
|
251373
|
+
Boolean(node.accessibility) ||
|
|
251374
|
+
privateNameCannotBePublic) {
|
|
251375
|
+
return;
|
|
251200
251376
|
}
|
|
251201
251377
|
context.report({
|
|
251202
251378
|
data: {
|
|
251203
|
-
kind: node
|
|
251204
|
-
name,
|
|
251379
|
+
kind: getCandidateKind(node),
|
|
251380
|
+
name: getCandidateName(node),
|
|
251381
|
+
},
|
|
251382
|
+
fix: (fixer) => {
|
|
251383
|
+
const { range, text } = getPublicModifierInsertion({
|
|
251384
|
+
node,
|
|
251385
|
+
sourceCode,
|
|
251386
|
+
});
|
|
251387
|
+
return fixer.insertTextBeforeRange(range, text);
|
|
251205
251388
|
},
|
|
251206
|
-
fix: (fixer) => fixer.insertTextBeforeRange(range, ' public '),
|
|
251207
251389
|
messageId: 'implicitPublic',
|
|
251208
251390
|
node,
|
|
251209
251391
|
});
|
|
@@ -251322,7 +251504,7 @@ const rule$D = createRule({
|
|
|
251322
251504
|
return {
|
|
251323
251505
|
Program(node) {
|
|
251324
251506
|
const text = context.sourceCode.getText(node);
|
|
251325
|
-
const lines = text
|
|
251507
|
+
const lines = splitLines(text);
|
|
251326
251508
|
for (const [index, line] of lines.entries()) {
|
|
251327
251509
|
const trimmed = line.trim();
|
|
251328
251510
|
if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith(';')) {
|
|
@@ -251664,11 +251846,12 @@ const rule$B = createRule({
|
|
|
251664
251846
|
return null;
|
|
251665
251847
|
}
|
|
251666
251848
|
const indent = getIndentAtOffset(sourceCode.text, insertOffset);
|
|
251849
|
+
const lineBreak = getLineBreak(sourceCode.text);
|
|
251667
251850
|
const declarations = result.lets
|
|
251668
251851
|
.map(({ expression, name }, index) => `${index === 0 ? '' : indent}@let ${name} = ${expression};`)
|
|
251669
|
-
.join(
|
|
251852
|
+
.join(lineBreak);
|
|
251670
251853
|
return [
|
|
251671
|
-
fixer.insertTextBeforeRange([insertOffset, insertOffset], `${declarations}
|
|
251854
|
+
fixer.insertTextBeforeRange([insertOffset, insertOffset], `${declarations}${lineBreak}${indent}`),
|
|
251672
251855
|
fixer.replaceTextRange([node.sourceSpan.start, node.sourceSpan.end], result.reference),
|
|
251673
251856
|
];
|
|
251674
251857
|
},
|
|
@@ -252664,10 +252847,11 @@ const rule$v = createRule({
|
|
|
252664
252847
|
fix(fixer) {
|
|
252665
252848
|
const varName = getCalleeName(firstCall);
|
|
252666
252849
|
const parentStatement = findParentStatement(node);
|
|
252850
|
+
const lineBreak = getLineBreak(sourceCode.text);
|
|
252667
252851
|
if (parentStatement) {
|
|
252668
252852
|
const indent = getStatementIndent$1(parentStatement, sourceCode.text);
|
|
252669
252853
|
const fixes = [
|
|
252670
|
-
fixer.insertTextBefore(parentStatement, `const ${varName} = ${callText}
|
|
252854
|
+
fixer.insertTextBefore(parentStatement, `const ${varName} = ${callText};${lineBreak}${lineBreak}${indent}`),
|
|
252671
252855
|
];
|
|
252672
252856
|
for (const call of calls) {
|
|
252673
252857
|
fixes.push(fixer.replaceText(getTargetNode(call), varName));
|
|
@@ -252694,7 +252878,7 @@ const rule$v = createRule({
|
|
|
252694
252878
|
lastIndex = end;
|
|
252695
252879
|
}
|
|
252696
252880
|
replacedBody += bodyText.slice(lastIndex);
|
|
252697
|
-
const newBody = `{
|
|
252881
|
+
const newBody = `{${lineBreak}${innerIndent}const ${varName} = ${callText};${lineBreak}${lineBreak}${innerIndent}return ${replacedBody};${lineBreak}${outerIndent}}`;
|
|
252698
252882
|
const bodyRangeStart = arrowBody.range[0];
|
|
252699
252883
|
const textBeforeBody = sourceCode.text.slice(0, bodyRangeStart);
|
|
252700
252884
|
const whitespaceBeforeBody = /\s*$/.exec(textBeforeBody)?.[0] ?? '';
|
|
@@ -253146,6 +253330,10 @@ const rule$s = createUntrackedRule({
|
|
|
253146
253330
|
name: 'no-signal-reads-after-await-in-reactive-context',
|
|
253147
253331
|
});
|
|
253148
253332
|
|
|
253333
|
+
const CARRIAGE_RETURN = String.fromCharCode(13);
|
|
253334
|
+
const LINE_FEED = String.fromCharCode(10);
|
|
253335
|
+
const ESCAPED_CARRIAGE_RETURN = String.fromCharCode(92, 114);
|
|
253336
|
+
const ESCAPED_LINE_FEED = String.fromCharCode(92, 110);
|
|
253149
253337
|
function collectParts(node) {
|
|
253150
253338
|
return node.type === dist$4.AST_NODE_TYPES.BinaryExpression && node.operator === '+'
|
|
253151
253339
|
? [...collectParts(node.left), ...collectParts(node.right)]
|
|
@@ -253165,8 +253353,8 @@ function buildMergedString(parts) {
|
|
|
253165
253353
|
const quote = combined.includes("'") && !combined.includes('"') ? '"' : "'";
|
|
253166
253354
|
const escaped = combined
|
|
253167
253355
|
.replaceAll('\\', '\\\\')
|
|
253168
|
-
.replaceAll(
|
|
253169
|
-
.replaceAll(
|
|
253356
|
+
.replaceAll(CARRIAGE_RETURN, ESCAPED_CARRIAGE_RETURN)
|
|
253357
|
+
.replaceAll(LINE_FEED, ESCAPED_LINE_FEED)
|
|
253170
253358
|
.replaceAll('\t', String.raw `\t`)
|
|
253171
253359
|
.replaceAll(new RegExp(quote, 'g'), `\\${quote}`);
|
|
253172
253360
|
return `${quote}${escaped}${quote}`;
|
|
@@ -253300,13 +253488,14 @@ function findUntrackedAlias(program) {
|
|
|
253300
253488
|
* Builds fixer actions that add `untracked` to an existing `@angular/core` import,
|
|
253301
253489
|
* or insert a new import declaration when none exists.
|
|
253302
253490
|
*/
|
|
253303
|
-
function buildUntrackedImportFixes(program, fixer) {
|
|
253491
|
+
function buildUntrackedImportFixes(program, fixer, sourceCode) {
|
|
253304
253492
|
const coreImport = findRuntimeAngularCoreImport(program);
|
|
253493
|
+
const lineBreak = getLineBreak(sourceCode.text);
|
|
253305
253494
|
if (!coreImport) {
|
|
253306
253495
|
const firstStatement = program.body[0];
|
|
253307
253496
|
return firstStatement
|
|
253308
253497
|
? [
|
|
253309
|
-
fixer.insertTextBefore(firstStatement,
|
|
253498
|
+
fixer.insertTextBefore(firstStatement, `import { untracked } from '@angular/core';${lineBreak}`),
|
|
253310
253499
|
]
|
|
253311
253500
|
: [];
|
|
253312
253501
|
}
|
|
@@ -253321,7 +253510,7 @@ function buildUntrackedImportFixes(program, fixer) {
|
|
|
253321
253510
|
return defaultImport
|
|
253322
253511
|
? [fixer.insertTextAfter(defaultImport, ', { untracked }')]
|
|
253323
253512
|
: [
|
|
253324
|
-
fixer.insertTextAfter(coreImport,
|
|
253513
|
+
fixer.insertTextAfter(coreImport, `${lineBreak}import { untracked } from '@angular/core';`),
|
|
253325
253514
|
];
|
|
253326
253515
|
}
|
|
253327
253516
|
/**
|
|
@@ -253411,10 +253600,9 @@ function dedent(text, extraSpaces) {
|
|
|
253411
253600
|
return text;
|
|
253412
253601
|
}
|
|
253413
253602
|
const prefix = ' '.repeat(extraSpaces);
|
|
253414
|
-
return text
|
|
253415
|
-
.split('\n')
|
|
253603
|
+
return splitLines(text)
|
|
253416
253604
|
.map((line) => (line.startsWith(prefix) ? line.slice(extraSpaces) : line))
|
|
253417
|
-
.join(
|
|
253605
|
+
.join(getLineBreak(text));
|
|
253418
253606
|
}
|
|
253419
253607
|
|
|
253420
253608
|
function isDirectCallOrNewArgument(node) {
|
|
@@ -253617,7 +253805,8 @@ function buildReplacement(untrackedCall, parentStatement, sourceCode) {
|
|
|
253617
253805
|
const firstStmtColumn = firstStmt.loc.start.column;
|
|
253618
253806
|
const extra = firstStmtColumn - parentColumn;
|
|
253619
253807
|
const indented = stmts.map((s) => dedent(sourceCode.getText(s), extra));
|
|
253620
|
-
|
|
253808
|
+
const lineBreak = getLineBreak(sourceCode.text);
|
|
253809
|
+
return indented.join(`${lineBreak}${''.padStart(parentColumn)}`);
|
|
253621
253810
|
}
|
|
253622
253811
|
// Expression body: arrow `() => expr` — just emit `expr;`
|
|
253623
253812
|
return `${sourceCode.getText(body)};`;
|
|
@@ -253728,14 +253917,7 @@ const rule$p = createUntrackedRule({
|
|
|
253728
253917
|
const rule$o = createRule({
|
|
253729
253918
|
create(context, [{ printWidth }]) {
|
|
253730
253919
|
const sourceCode = context.sourceCode;
|
|
253731
|
-
const getLineEndIndex = (lineStartIndex) =>
|
|
253732
|
-
const text = sourceCode.text;
|
|
253733
|
-
const newLineIndex = text.indexOf('\n', lineStartIndex);
|
|
253734
|
-
const rawEndIndex = newLineIndex === -1 ? text.length : newLineIndex;
|
|
253735
|
-
return rawEndIndex > lineStartIndex && text[rawEndIndex - 1] === '\r'
|
|
253736
|
-
? rawEndIndex - 1
|
|
253737
|
-
: rawEndIndex;
|
|
253738
|
-
};
|
|
253920
|
+
const getLineEndIndex = (lineStartIndex) => getLineEndOffset(sourceCode.text, lineStartIndex);
|
|
253739
253921
|
const hasAnyCommentsInside = (node) => sourceCode.getCommentsInside(node).length > 0;
|
|
253740
253922
|
const isTemplateLikeExpression = (expression) => expression.type === dist$3.AST_NODE_TYPES.TemplateLiteral ||
|
|
253741
253923
|
expression.type === dist$3.AST_NODE_TYPES.TaggedTemplateExpression;
|
|
@@ -253847,7 +254029,7 @@ const rule$o = createRule({
|
|
|
253847
254029
|
if (inner.type === dist$3.AST_NODE_TYPES.ObjectExpression &&
|
|
253848
254030
|
canInlineObjectExpression(inner)) {
|
|
253849
254031
|
const innerText = sourceCode.getText(inner);
|
|
253850
|
-
return innerText
|
|
254032
|
+
return hasLineBreak(innerText);
|
|
253851
254033
|
}
|
|
253852
254034
|
}
|
|
253853
254035
|
if (value.type === dist$3.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
@@ -253859,7 +254041,7 @@ const rule$o = createRule({
|
|
|
253859
254041
|
if (inner.type === dist$3.AST_NODE_TYPES.ObjectExpression &&
|
|
253860
254042
|
canInlineObjectExpression(inner)) {
|
|
253861
254043
|
const innerText = sourceCode.getText(inner);
|
|
253862
|
-
return innerText
|
|
254044
|
+
return hasLineBreak(innerText);
|
|
253863
254045
|
}
|
|
253864
254046
|
}
|
|
253865
254047
|
}
|
|
@@ -253868,7 +254050,7 @@ const rule$o = createRule({
|
|
|
253868
254050
|
if (bodyExpr.type === dist$3.AST_NODE_TYPES.ObjectExpression &&
|
|
253869
254051
|
canInlineObjectExpression(bodyExpr)) {
|
|
253870
254052
|
const innerText = sourceCode.getText(bodyExpr);
|
|
253871
|
-
return innerText
|
|
254053
|
+
return hasLineBreak(innerText);
|
|
253872
254054
|
}
|
|
253873
254055
|
}
|
|
253874
254056
|
}
|
|
@@ -253932,7 +254114,7 @@ const rule$o = createRule({
|
|
|
253932
254114
|
ObjectExpression(node) {
|
|
253933
254115
|
const originalText = sourceCode.getText(node);
|
|
253934
254116
|
if (!canInlineObjectExpression(node) ||
|
|
253935
|
-
!originalText
|
|
254117
|
+
!hasLineBreak(originalText) ||
|
|
253936
254118
|
hasPendingInnerInlineCandidate(node) ||
|
|
253937
254119
|
hasArrowReturningMultiPropObject(node)) {
|
|
253938
254120
|
return;
|
|
@@ -254306,35 +254488,37 @@ function renderConditionalReturn(ifStatement, consequentExpression, alternateExp
|
|
|
254306
254488
|
return inlineReturn;
|
|
254307
254489
|
}
|
|
254308
254490
|
const branchIndent = `${indent} `;
|
|
254309
|
-
|
|
254491
|
+
const lineBreak = getLineBreak(sourceCode.text);
|
|
254492
|
+
return `return ${test}${lineBreak}${branchIndent}? ${consequent}${lineBreak}${branchIndent}: ${alternate};`;
|
|
254310
254493
|
}
|
|
254311
254494
|
function renderBooleanTestReturn(ifStatement, sourceCode, strategy) {
|
|
254312
254495
|
const test = sourceCode.getText(ifStatement.test);
|
|
254496
|
+
const lineBreak = getLineBreak(sourceCode.text);
|
|
254313
254497
|
if (strategy === 'negate') {
|
|
254314
|
-
if (!test
|
|
254498
|
+
if (!hasLineBreak(test)) {
|
|
254315
254499
|
const renderedTest = needsParenthesesInBooleanCoercion(ifStatement.test)
|
|
254316
254500
|
? `(${test})`
|
|
254317
254501
|
: test;
|
|
254318
254502
|
return `return !${renderedTest};`;
|
|
254319
254503
|
}
|
|
254320
254504
|
const indent = getStatementIndent(ifStatement, sourceCode);
|
|
254321
|
-
return `return !(
|
|
254505
|
+
return `return !(${lineBreak}${indent} ${test}${lineBreak}${indent});`;
|
|
254322
254506
|
}
|
|
254323
254507
|
if (strategy === 'coerce') {
|
|
254324
|
-
if (!test
|
|
254508
|
+
if (!hasLineBreak(test)) {
|
|
254325
254509
|
const renderedTest = needsParenthesesInBooleanCoercion(ifStatement.test)
|
|
254326
254510
|
? `(${test})`
|
|
254327
254511
|
: test;
|
|
254328
254512
|
return `return !!${renderedTest};`;
|
|
254329
254513
|
}
|
|
254330
254514
|
const indent = getStatementIndent(ifStatement, sourceCode);
|
|
254331
|
-
return `return !!(
|
|
254515
|
+
return `return !!(${lineBreak}${indent} ${test}${lineBreak}${indent});`;
|
|
254332
254516
|
}
|
|
254333
|
-
if (!test
|
|
254517
|
+
if (!hasLineBreak(test)) {
|
|
254334
254518
|
return `return ${test};`;
|
|
254335
254519
|
}
|
|
254336
254520
|
const indent = getStatementIndent(ifStatement, sourceCode);
|
|
254337
|
-
return `return (
|
|
254521
|
+
return `return (${lineBreak}${indent} ${test}${lineBreak}${indent});`;
|
|
254338
254522
|
}
|
|
254339
254523
|
const rule$m = createRule({
|
|
254340
254524
|
create(context) {
|
|
@@ -254912,7 +255096,7 @@ const rule$i = createUntrackedRule({
|
|
|
254912
255096
|
? (fixer) => [fixer.replaceText(read, wrapped)]
|
|
254913
255097
|
: (fixer) => [
|
|
254914
255098
|
fixer.replaceText(read, wrapped),
|
|
254915
|
-
...buildUntrackedImportFixes(program, fixer),
|
|
255099
|
+
...buildUntrackedImportFixes(program, fixer, sourceCode),
|
|
254916
255100
|
];
|
|
254917
255101
|
}
|
|
254918
255102
|
return {
|
|
@@ -255051,8 +255235,7 @@ const rule$g = createRule({
|
|
|
255051
255235
|
let openQuoteOffset = valueSpan.start.offset - 1;
|
|
255052
255236
|
while (openQuoteOffset >= 0 &&
|
|
255053
255237
|
(sourceText[openQuoteOffset] === ' ' ||
|
|
255054
|
-
sourceText[openQuoteOffset]
|
|
255055
|
-
sourceText[openQuoteOffset] === '\r' ||
|
|
255238
|
+
isLineBreakCharacter(sourceText[openQuoteOffset]) ||
|
|
255056
255239
|
sourceText[openQuoteOffset] === '\t')) {
|
|
255057
255240
|
openQuoteOffset--;
|
|
255058
255241
|
}
|
|
@@ -255063,8 +255246,7 @@ const rule$g = createRule({
|
|
|
255063
255246
|
if (isQuotedAttribute) {
|
|
255064
255247
|
while (closeQuoteOffset < sourceText.length &&
|
|
255065
255248
|
(sourceText[closeQuoteOffset] === ' ' ||
|
|
255066
|
-
sourceText[closeQuoteOffset]
|
|
255067
|
-
sourceText[closeQuoteOffset] === '\r' ||
|
|
255249
|
+
isLineBreakCharacter(sourceText[closeQuoteOffset]) ||
|
|
255068
255250
|
sourceText[closeQuoteOffset] === '\t')) {
|
|
255069
255251
|
closeQuoteOffset++;
|
|
255070
255252
|
}
|
|
@@ -255121,6 +255303,7 @@ const rule$f = createRule({
|
|
|
255121
255303
|
rule: {
|
|
255122
255304
|
create(context) {
|
|
255123
255305
|
const sourceText = context.sourceCode.getText();
|
|
255306
|
+
const lineBreak = getLineBreak(sourceText);
|
|
255124
255307
|
let reported = false;
|
|
255125
255308
|
return {
|
|
255126
255309
|
Element(rawNode) {
|
|
@@ -255132,7 +255315,7 @@ const rule$f = createRule({
|
|
|
255132
255315
|
}
|
|
255133
255316
|
reported = true;
|
|
255134
255317
|
context.report({
|
|
255135
|
-
fix: (fixer) => fixer.insertTextBeforeRange([0, 0],
|
|
255318
|
+
fix: (fixer) => fixer.insertTextBeforeRange([0, 0], `<!DOCTYPE html>${lineBreak}`),
|
|
255136
255319
|
loc: sourceSpanToLoc(node.startSourceSpan),
|
|
255137
255320
|
messageId: MESSAGE_ID$6,
|
|
255138
255321
|
});
|
|
@@ -255526,18 +255709,6 @@ const rule$a = createRule({
|
|
|
255526
255709
|
name: 'short-tui-imports',
|
|
255527
255710
|
});
|
|
255528
255711
|
|
|
255529
|
-
function isFieldLikeMember(member) {
|
|
255530
|
-
return (member.type === dist$4.AST_NODE_TYPES.PropertyDefinition ||
|
|
255531
|
-
member.type === dist$4.AST_NODE_TYPES.TSAbstractPropertyDefinition);
|
|
255532
|
-
}
|
|
255533
|
-
function isAccessorMember(member) {
|
|
255534
|
-
return (member.type === dist$4.AST_NODE_TYPES.MethodDefinition &&
|
|
255535
|
-
(member.kind === 'get' || member.kind === 'set'));
|
|
255536
|
-
}
|
|
255537
|
-
function isRelevantSpacingClassMember(member) {
|
|
255538
|
-
return isFieldLikeMember(member) || isAccessorMember(member);
|
|
255539
|
-
}
|
|
255540
|
-
|
|
255541
255712
|
const rule$9 = createRule({
|
|
255542
255713
|
create(context) {
|
|
255543
255714
|
const sourceCode = context.sourceCode;
|
|
@@ -256766,7 +256937,7 @@ function buildRewrittenImports({ baseImportPath, node, state, symbolToEntryPoint
|
|
|
256766
256937
|
if (remainingImportStatement) {
|
|
256767
256938
|
importStatements.push(remainingImportStatement);
|
|
256768
256939
|
}
|
|
256769
|
-
return importStatements.join(
|
|
256940
|
+
return importStatements.join(getLineBreak(state.sourceCode.text));
|
|
256770
256941
|
}
|
|
256771
256942
|
function buildNamedImportStatement({ importKind, importPath, specifiers, state, }) {
|
|
256772
256943
|
const importKeyword = importKind === 'type' ? 'import type' : 'import';
|
|
@@ -256904,8 +257075,9 @@ const plugin = {
|
|
|
256904
257075
|
},
|
|
256905
257076
|
rules: {
|
|
256906
257077
|
'array-as-const': rule$5,
|
|
256907
|
-
'at-compat': rule$
|
|
256908
|
-
'attrs-newline': rule$
|
|
257078
|
+
'at-compat': rule$Y,
|
|
257079
|
+
'attrs-newline': rule$X,
|
|
257080
|
+
'class-accessibility-spacing': rule$W,
|
|
256909
257081
|
'class-property-naming': rule$4,
|
|
256910
257082
|
'decorator-key-sort': rule$V,
|
|
256911
257083
|
'element-newline': rule$U,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taiga-ui/eslint-plugin-experience-next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.528.0",
|
|
4
4
|
"description": "An ESLint plugin to enforce a consistent code styles across taiga-ui projects",
|
|
5
5
|
"homepage": "https://github.com/taiga-family/toolkit#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"eslint-plugin-unicorn": "64.0.0",
|
|
55
55
|
"eslint-plugin-unused-imports": "4.4.1",
|
|
56
56
|
"globals": "17.6.0",
|
|
57
|
-
"typescript-eslint": "8.59.
|
|
57
|
+
"typescript-eslint": "8.59.2"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@typescript-eslint/rule-tester": "8.59.
|
|
60
|
+
"@typescript-eslint/rule-tester": "8.59.2"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
63
|
"eslint": "^9.39.4"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { type TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
export declare const rule: TSESLint.RuleModule<"invalid-injection-token-description", readonly unknown[], unknown, TSESLint.RuleListener> & {
|
|
2
3
|
name: string;
|
|
3
4
|
};
|
|
4
5
|
export default rule;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { type TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
export declare const rule: TSESLint.RuleModule<"implicitPublic", readonly unknown[], unknown, TSESLint.RuleListener> & {
|
|
2
3
|
name: string;
|
|
3
4
|
};
|
|
4
5
|
export default rule;
|
|
@@ -6,7 +6,7 @@ export declare function findUntrackedAlias(program: TSESTree.Program): string |
|
|
|
6
6
|
* Builds fixer actions that add `untracked` to an existing `@angular/core` import,
|
|
7
7
|
* or insert a new import declaration when none exists.
|
|
8
8
|
*/
|
|
9
|
-
export declare function buildUntrackedImportFixes(program: TSESTree.Program, fixer: RuleFixer): Array<ReturnType<RuleFixer['insertTextBefore']>>;
|
|
9
|
+
export declare function buildUntrackedImportFixes(program: TSESTree.Program, fixer: RuleFixer, sourceCode: SourceCode): Array<ReturnType<RuleFixer['insertTextBefore']>>;
|
|
10
10
|
/**
|
|
11
11
|
* Removes the `untracked` import specifier from `@angular/core`.
|
|
12
12
|
* When it is the last specifier, removes the entire declaration.
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { type TSESTree } from '@typescript-eslint/utils';
|
|
2
2
|
export { getLeadingIndentation, getLineBreak, getLineStartOffset, hasBlankLine, hasCommentLikeText, isSingleLineNode, } from './spacing';
|
|
3
3
|
export type FieldLikeMember = TSESTree.PropertyDefinition | TSESTree.TSAbstractPropertyDefinition;
|
|
4
|
+
export type AccessibilityGroup = 'private' | 'protected' | 'public';
|
|
5
|
+
export type AccessibilityClassMember = TSESTree.AccessorProperty | TSESTree.MethodDefinition | TSESTree.PropertyDefinition | TSESTree.TSAbstractAccessorProperty | TSESTree.TSAbstractMethodDefinition | TSESTree.TSAbstractPropertyDefinition | TSESTree.TSIndexSignature;
|
|
6
|
+
export type EcmascriptPrivateClassMember = Exclude<AccessibilityClassMember, TSESTree.TSIndexSignature> & {
|
|
7
|
+
readonly key: TSESTree.PrivateIdentifier;
|
|
8
|
+
};
|
|
4
9
|
export declare function isFieldLikeMember(member: TSESTree.ClassElement): member is FieldLikeMember;
|
|
5
10
|
export declare function isAccessorMember(member: TSESTree.ClassElement): member is TSESTree.MethodDefinition;
|
|
6
11
|
export declare function isRelevantSpacingClassMember(member: TSESTree.ClassElement): member is FieldLikeMember | TSESTree.MethodDefinition;
|
|
12
|
+
export declare function isAccessibilityClassMember(member: TSESTree.ClassElement): member is AccessibilityClassMember;
|
|
13
|
+
export declare function isEcmascriptPrivateClassMember(member: TSESTree.ClassElement): member is EcmascriptPrivateClassMember;
|
|
14
|
+
export declare function getAccessibilityGroup(member: AccessibilityClassMember): AccessibilityGroup;
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { type TSESLint, type TSESTree } from '@typescript-eslint/utils';
|
|
2
2
|
export declare function isSingleLineNode(node: TSESTree.Node): boolean;
|
|
3
|
+
export declare function isLineBreakCharacter(char: string | undefined): boolean;
|
|
3
4
|
export declare function hasCommentLikeText(text: string): boolean;
|
|
4
5
|
export declare function hasBlankLine(text: string): boolean;
|
|
6
|
+
export declare function hasBlankLineBetweenNodes(text: string): boolean;
|
|
5
7
|
export declare function getLineBreak(text: string): string;
|
|
8
|
+
export declare function hasLineBreak(text: string): boolean;
|
|
6
9
|
export declare function getLeadingIndentation(text: string): string;
|
|
7
10
|
export declare function getLineStartOffset(text: string, offset: number): number;
|
|
11
|
+
export declare function getLineEndOffset(text: string, lineStartOffset: number): number;
|
|
12
|
+
export declare function getNextLineStartOffset(text: string, offset: number): number;
|
|
13
|
+
export declare function splitLines(text: string): string[];
|
|
8
14
|
export declare function getIndentAtOffset(text: string, offset: number): string;
|
|
9
15
|
export declare function getSpacingReplacement(sourceCode: Readonly<TSESLint.SourceCode>, betweenText: string, nextLine: number, blankLineCount: number): string;
|