@taiga-ui/eslint-plugin-experience-next 0.538.0 → 0.540.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
CHANGED
|
@@ -104,6 +104,7 @@ from third-party plugins. The exact severities and file globs live in
|
|
|
104
104
|
| [no-playwright-empty-fill](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/no-playwright-empty-fill.md) | Enforce `clear()` over `fill('')` in Playwright tests | ✅ | 🔧 | |
|
|
105
105
|
| [no-project-as-in-ng-template](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/no-project-as-in-ng-template.md) | `ngProjectAs` has no effect inside `<ng-template>` or dynamic outlets | ✅ | | |
|
|
106
106
|
| [no-restricted-attr-values](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/no-restricted-attr-values.md) | Disallow configured attribute values in Angular templates | | | |
|
|
107
|
+
| [no-redundant-fs-encoding](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/no-redundant-fs-encoding.md) | Remove redundant default utf8 encoding from Node.js file write calls | ✅ | 🔧 | |
|
|
107
108
|
| [no-redundant-type-annotation](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/no-redundant-type-annotation.md) | Disallow redundant type annotations when the type is already inferred from the initializer | ✅ | 🔧 | |
|
|
108
109
|
| [no-repeated-signal-in-conditional](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/no-repeated-signal-in-conditional.md) | Disallow reading the same nullable Angular signal more than once in a conditional expression | ✅ | 🔧 | |
|
|
109
110
|
| [no-side-effects-in-computed](https://github.com/taiga-family/toolkit/tree/main/projects/eslint-plugin-experience-next/docs/no-side-effects-in-computed.md) | Disallow side effects and effectful helper calls inside Angular `computed()` callbacks | ✅ | | |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getDefaultParserOptions(): Record<string, unknown>;
|
package/index.d.ts
CHANGED
|
@@ -123,6 +123,9 @@ declare const plugin: {
|
|
|
123
123
|
'no-project-as-in-ng-template': import("eslint").Rule.RuleModule & {
|
|
124
124
|
name: string;
|
|
125
125
|
};
|
|
126
|
+
'no-redundant-fs-encoding': import("@typescript-eslint/utils/ts-eslint").RuleModule<"noRedundantFsEncoding", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
127
|
+
name: string;
|
|
128
|
+
};
|
|
126
129
|
'no-redundant-type-annotation': import("@typescript-eslint/utils/ts-eslint").RuleModule<"redundantTypeAnnotation", [({
|
|
127
130
|
ignoreTupleContextualTyping?: boolean;
|
|
128
131
|
} | undefined)?], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
package/index.esm.js
CHANGED
|
@@ -599,9 +599,33 @@ var npmrcParser = /*#__PURE__*/Object.freeze({
|
|
|
599
599
|
});
|
|
600
600
|
|
|
601
601
|
const require$2 = createRequire(import.meta.url);
|
|
602
|
+
function projectJsonExist(filename) {
|
|
603
|
+
try {
|
|
604
|
+
const path = require$2('node:path').resolve(filename);
|
|
605
|
+
return require$2('node:fs').existsSync(path) ? path : '';
|
|
606
|
+
}
|
|
607
|
+
catch {
|
|
608
|
+
return '';
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
function getDefaultParserOptions() {
|
|
613
|
+
const tsconfig = projectJsonExist('tsconfig.eslint.json');
|
|
614
|
+
if (tsconfig) {
|
|
615
|
+
return { project: [tsconfig] };
|
|
616
|
+
}
|
|
617
|
+
return projectJsonExist('tsconfig.json')
|
|
618
|
+
? {
|
|
619
|
+
projectService: true,
|
|
620
|
+
tsconfigRootDir: process.cwd(),
|
|
621
|
+
}
|
|
622
|
+
: { projectService: false };
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
const require$1 = createRequire(import.meta.url);
|
|
602
626
|
function getAngularVersion() {
|
|
603
627
|
try {
|
|
604
|
-
const { major } = require$
|
|
628
|
+
const { major } = require$1('@angular/cli').VERSION;
|
|
605
629
|
return Number.parseInt(major, 10);
|
|
606
630
|
}
|
|
607
631
|
catch {
|
|
@@ -618,25 +642,7 @@ const modernAngularRules = {
|
|
|
618
642
|
templateLiteral: 19,
|
|
619
643
|
};
|
|
620
644
|
|
|
621
|
-
const require$1 = createRequire(import.meta.url);
|
|
622
|
-
function projectJsonExist(filename) {
|
|
623
|
-
try {
|
|
624
|
-
const path = require$1('node:path').resolve(filename);
|
|
625
|
-
return require$1('node:fs').existsSync(path) ? path : '';
|
|
626
|
-
}
|
|
627
|
-
catch {
|
|
628
|
-
return '';
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
|
|
632
645
|
const ALL_TS_JS_FILES = ['**/*.{js,mjs,ts,cjs,tsx,jsx}'];
|
|
633
|
-
const tsconfig = projectJsonExist('tsconfig.eslint.json');
|
|
634
|
-
const parserOptions$1 = tsconfig
|
|
635
|
-
? { project: [tsconfig] }
|
|
636
|
-
: {
|
|
637
|
-
projectService: true,
|
|
638
|
-
tsconfigRootDir: process.cwd(),
|
|
639
|
-
};
|
|
640
646
|
var recommended = defineConfig([
|
|
641
647
|
progress.configs['recommended-ci'],
|
|
642
648
|
{
|
|
@@ -698,7 +704,7 @@ var recommended = defineConfig([
|
|
|
698
704
|
errorOnUnknownASTType: true,
|
|
699
705
|
sourceType: 'module',
|
|
700
706
|
warnOnUnsupportedTypeScriptVersion: false,
|
|
701
|
-
...
|
|
707
|
+
...getDefaultParserOptions(),
|
|
702
708
|
},
|
|
703
709
|
},
|
|
704
710
|
settings: {
|
|
@@ -931,6 +937,7 @@ var recommended = defineConfig([
|
|
|
931
937
|
'@typescript-eslint/prefer-destructuring': 'off',
|
|
932
938
|
'@typescript-eslint/prefer-find': 'error',
|
|
933
939
|
'@typescript-eslint/prefer-for-of': 'error',
|
|
940
|
+
'@typescript-eslint/prefer-function-type': 'off',
|
|
934
941
|
'@typescript-eslint/prefer-includes': 'error',
|
|
935
942
|
'@typescript-eslint/prefer-nullish-coalescing': 'off', // TODO: ['error', {ignorePrimitives: {boolean: true, number: true, string: true}}]
|
|
936
943
|
'@typescript-eslint/prefer-optional-chain': 'error',
|
|
@@ -1319,6 +1326,7 @@ var recommended = defineConfig([
|
|
|
1319
1326
|
'@taiga-ui/experience-next/no-implicit-public': 'error',
|
|
1320
1327
|
'@taiga-ui/experience-next/no-import-assertions': 'error',
|
|
1321
1328
|
'@taiga-ui/experience-next/no-infinite-loop': 'error',
|
|
1329
|
+
'@taiga-ui/experience-next/no-redundant-fs-encoding': 'error',
|
|
1322
1330
|
'@taiga-ui/experience-next/no-redundant-type-annotation': 'error',
|
|
1323
1331
|
'@taiga-ui/experience-next/no-repeated-signal-in-conditional': 'error',
|
|
1324
1332
|
'@taiga-ui/experience-next/no-side-effects-in-computed': 'error',
|
|
@@ -15661,7 +15669,7 @@ function getLastIndexFix(fixer, sourceCode, node, call) {
|
|
|
15661
15669
|
}
|
|
15662
15670
|
return null;
|
|
15663
15671
|
}
|
|
15664
|
-
const rule$
|
|
15672
|
+
const rule$Z = createRule({
|
|
15665
15673
|
create(context) {
|
|
15666
15674
|
const typeAwareContext = getTypeAwareRuleContext(context);
|
|
15667
15675
|
const compilerOptions = typeAwareContext.tsProgram.getCompilerOptions();
|
|
@@ -47467,7 +47475,7 @@ function buildMultilineStartTag(node, sourceText) {
|
|
|
47467
47475
|
closing,
|
|
47468
47476
|
].join(lineBreak);
|
|
47469
47477
|
}
|
|
47470
|
-
const rule$
|
|
47478
|
+
const rule$Y = createRule({
|
|
47471
47479
|
name: 'attrs-newline',
|
|
47472
47480
|
rule: {
|
|
47473
47481
|
create(context) {
|
|
@@ -47553,7 +47561,7 @@ const rule$X = createRule({
|
|
|
47553
47561
|
},
|
|
47554
47562
|
});
|
|
47555
47563
|
|
|
47556
|
-
const rule$
|
|
47564
|
+
const rule$X = createRule({
|
|
47557
47565
|
create(context) {
|
|
47558
47566
|
const sourceCode = context.sourceCode;
|
|
47559
47567
|
return {
|
|
@@ -47656,7 +47664,7 @@ function sameOrder(a, b) {
|
|
|
47656
47664
|
return a.length === b.length && a.every((value, index) => value === b[index]);
|
|
47657
47665
|
}
|
|
47658
47666
|
|
|
47659
|
-
const rule$
|
|
47667
|
+
const rule$W = createRule({
|
|
47660
47668
|
create(context, [order]) {
|
|
47661
47669
|
const decorators = new Set(Object.keys(order));
|
|
47662
47670
|
return {
|
|
@@ -47792,7 +47800,7 @@ function getNodeLabel(node) {
|
|
|
47792
47800
|
}
|
|
47793
47801
|
return node instanceof dist.TmplAstBoundText ? 'binding' : 'text';
|
|
47794
47802
|
}
|
|
47795
|
-
const rule$
|
|
47803
|
+
const rule$V = createRule({
|
|
47796
47804
|
name: 'element-newline',
|
|
47797
47805
|
rule: {
|
|
47798
47806
|
create(context) {
|
|
@@ -47932,7 +47940,7 @@ const PRESETS = {
|
|
|
47932
47940
|
$VUE: ['$CLASS', '$ID', '$VUE_ATTRIBUTE'],
|
|
47933
47941
|
$VUE_ATTRIBUTE: /^v-/,
|
|
47934
47942
|
};
|
|
47935
|
-
const rule$
|
|
47943
|
+
const rule$U = createRule({
|
|
47936
47944
|
create(context, [options]) {
|
|
47937
47945
|
const sourceCode = context.sourceCode;
|
|
47938
47946
|
const settings = {
|
|
@@ -48263,7 +48271,7 @@ const config$4 = {
|
|
|
48263
48271
|
type: 'suggestion',
|
|
48264
48272
|
},
|
|
48265
48273
|
};
|
|
48266
|
-
const rule$
|
|
48274
|
+
const rule$T = createRule({
|
|
48267
48275
|
name: 'html-logical-properties',
|
|
48268
48276
|
rule: config$4,
|
|
48269
48277
|
});
|
|
@@ -48841,7 +48849,7 @@ function isImportUsedOnlyAsAngularDiFirstArg(node, sourceCode) {
|
|
|
48841
48849
|
}
|
|
48842
48850
|
return hasSafeRuntimeUsage;
|
|
48843
48851
|
}
|
|
48844
|
-
const rule$
|
|
48852
|
+
const rule$S = createRule({
|
|
48845
48853
|
create(context) {
|
|
48846
48854
|
const { checker, esTreeNodeToTSNodeMap, sourceCode, tsProgram } = getTypeAwareRuleContext(context);
|
|
48847
48855
|
const checkCycles = context.options[0]?.checkCycles ?? true;
|
|
@@ -49563,7 +49571,7 @@ function getNgDevModeDeclarationFix(program, fixer, sourceCode) {
|
|
|
49563
49571
|
? fixer.insertTextBefore(firstStatement, `declare const ngDevMode: boolean;${lineBreak}${lineBreak}`)
|
|
49564
49572
|
: fixer.insertTextBeforeRange([0, 0], `declare const ngDevMode: boolean;${lineBreak}`);
|
|
49565
49573
|
}
|
|
49566
|
-
const rule$
|
|
49574
|
+
const rule$R = createRule({
|
|
49567
49575
|
create(context) {
|
|
49568
49576
|
const { sourceCode } = context;
|
|
49569
49577
|
const program = sourceCode.ast;
|
|
@@ -49612,7 +49620,7 @@ const rule$Q = createRule({
|
|
|
49612
49620
|
name: 'injection-token-description',
|
|
49613
49621
|
});
|
|
49614
49622
|
|
|
49615
|
-
const rule$
|
|
49623
|
+
const rule$Q = createRule({
|
|
49616
49624
|
create(context) {
|
|
49617
49625
|
const { sourceCode } = context;
|
|
49618
49626
|
const namespaceImports = new Map();
|
|
@@ -49707,7 +49715,7 @@ const DEFAULT_OPTIONS = {
|
|
|
49707
49715
|
importDeclaration: '^@taiga-ui*',
|
|
49708
49716
|
projectName: String.raw `(?<=^@taiga-ui/)([-\w]+)`,
|
|
49709
49717
|
};
|
|
49710
|
-
const rule$
|
|
49718
|
+
const rule$P = createRule({
|
|
49711
49719
|
create(context) {
|
|
49712
49720
|
const { currentProject, deepImport, ignoreImports, importDeclaration, projectName, } = { ...DEFAULT_OPTIONS, ...context.options[0] };
|
|
49713
49721
|
const hasNonCodeExtension = (source) => {
|
|
@@ -49799,7 +49807,7 @@ const nearestFileUpCache = new Map();
|
|
|
49799
49807
|
const markerCache = new Map();
|
|
49800
49808
|
const indexFileCache = new Map();
|
|
49801
49809
|
const indexExportsCache = new Map();
|
|
49802
|
-
const rule$
|
|
49810
|
+
const rule$O = createRule({
|
|
49803
49811
|
create(context) {
|
|
49804
49812
|
const parserServices = dist$4.ESLintUtils.getParserServices(context);
|
|
49805
49813
|
const program = parserServices.program;
|
|
@@ -49993,13 +50001,13 @@ const noDuplicateAttributesRule = angular.templatePlugin.rules?.['no-duplicate-a
|
|
|
49993
50001
|
if (!noDuplicateAttributesRule) {
|
|
49994
50002
|
throw new Error('angular-eslint template rule "no-duplicate-attributes" is not available');
|
|
49995
50003
|
}
|
|
49996
|
-
const rule$
|
|
50004
|
+
const rule$N = createRule({
|
|
49997
50005
|
name: 'no-duplicate-attrs',
|
|
49998
50006
|
rule: noDuplicateAttributesRule,
|
|
49999
50007
|
});
|
|
50000
50008
|
|
|
50001
50009
|
const MESSAGE_ID$e = 'duplicateId';
|
|
50002
|
-
const rule$
|
|
50010
|
+
const rule$M = createRule({
|
|
50003
50011
|
name: 'no-duplicate-id',
|
|
50004
50012
|
rule: {
|
|
50005
50013
|
create(context) {
|
|
@@ -50057,7 +50065,7 @@ function getTrackingKey(node) {
|
|
|
50057
50065
|
? 'link[rel=canonical]'
|
|
50058
50066
|
: null;
|
|
50059
50067
|
}
|
|
50060
|
-
const rule$
|
|
50068
|
+
const rule$L = createRule({
|
|
50061
50069
|
name: 'no-duplicate-in-head',
|
|
50062
50070
|
rule: {
|
|
50063
50071
|
create(context) {
|
|
@@ -50113,7 +50121,7 @@ const rule$K = createRule({
|
|
|
50113
50121
|
});
|
|
50114
50122
|
|
|
50115
50123
|
const COMPONENT_DECORATORS = new Set(['Component']);
|
|
50116
|
-
const rule$
|
|
50124
|
+
const rule$K = createRule({
|
|
50117
50125
|
create(context) {
|
|
50118
50126
|
const { sourceCode } = context;
|
|
50119
50127
|
return {
|
|
@@ -50592,7 +50600,7 @@ const ANGULAR_SIGNALS_UNTRACKED_GUIDE_URL = 'https://angular.dev/guide/signals#r
|
|
|
50592
50600
|
const ANGULAR_SIGNALS_ASYNC_GUIDE_URL = 'https://angular.dev/guide/signals#reactive-context-and-async-operations';
|
|
50593
50601
|
const createUntrackedRule = createRule;
|
|
50594
50602
|
|
|
50595
|
-
const rule$
|
|
50603
|
+
const rule$J = createUntrackedRule({
|
|
50596
50604
|
create(context) {
|
|
50597
50605
|
const { checker, esTreeNodeToTSNodeMap, program } = getTypeAwareRuleContext(context);
|
|
50598
50606
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -50665,7 +50673,7 @@ const config$3 = {
|
|
|
50665
50673
|
type: 'problem',
|
|
50666
50674
|
},
|
|
50667
50675
|
};
|
|
50668
|
-
const rule$
|
|
50676
|
+
const rule$I = createRule({
|
|
50669
50677
|
name: 'no-href-with-router-link',
|
|
50670
50678
|
rule: config$3,
|
|
50671
50679
|
});
|
|
@@ -50716,7 +50724,7 @@ function getPublicModifierInsertion(options) {
|
|
|
50716
50724
|
text: 'public ',
|
|
50717
50725
|
};
|
|
50718
50726
|
}
|
|
50719
|
-
const rule$
|
|
50727
|
+
const rule$H = createRule({
|
|
50720
50728
|
create(context) {
|
|
50721
50729
|
const sourceCode = context.sourceCode;
|
|
50722
50730
|
const checkImplicitPublic = (node) => {
|
|
@@ -50770,7 +50778,7 @@ const rule$G = createRule({
|
|
|
50770
50778
|
name: 'no-implicit-public',
|
|
50771
50779
|
});
|
|
50772
50780
|
|
|
50773
|
-
const rule$
|
|
50781
|
+
const rule$G = createRule({
|
|
50774
50782
|
create(context) {
|
|
50775
50783
|
const { sourceCode } = context;
|
|
50776
50784
|
return {
|
|
@@ -50810,7 +50818,7 @@ function isInfiniteLoopLiteral(node) {
|
|
|
50810
50818
|
function isInfiniteLoopTest(test) {
|
|
50811
50819
|
return test == null || isInfiniteLoopLiteral(test);
|
|
50812
50820
|
}
|
|
50813
|
-
const rule$
|
|
50821
|
+
const rule$F = createRule({
|
|
50814
50822
|
create(context) {
|
|
50815
50823
|
return {
|
|
50816
50824
|
DoWhileStatement(node) {
|
|
@@ -50855,7 +50863,7 @@ const rule$E = createRule({
|
|
|
50855
50863
|
});
|
|
50856
50864
|
|
|
50857
50865
|
const LEGACY_PEER_DEPS_PATTERN = /^legacy-peer-deps\s*=\s*true$/i;
|
|
50858
|
-
const rule$
|
|
50866
|
+
const rule$E = createRule({
|
|
50859
50867
|
create(context) {
|
|
50860
50868
|
return {
|
|
50861
50869
|
Program(node) {
|
|
@@ -50947,7 +50955,7 @@ function getAvailableLabelParent(stack, node, labelsWithControl) {
|
|
|
50947
50955
|
? parent
|
|
50948
50956
|
: null;
|
|
50949
50957
|
}
|
|
50950
|
-
const rule$
|
|
50958
|
+
const rule$D = createRule({
|
|
50951
50959
|
name: 'no-nested-interactive',
|
|
50952
50960
|
rule: {
|
|
50953
50961
|
create(context) {
|
|
@@ -51168,7 +51176,7 @@ function createLetFixes(node, baseName, unavailableNames, text) {
|
|
|
51168
51176
|
reference: name,
|
|
51169
51177
|
};
|
|
51170
51178
|
}
|
|
51171
|
-
const rule$
|
|
51179
|
+
const rule$C = createRule({
|
|
51172
51180
|
name: 'no-nested-ternary-in-template',
|
|
51173
51181
|
rule: {
|
|
51174
51182
|
create(context) {
|
|
@@ -51706,7 +51714,7 @@ const OBSOLETE_HTML_ATTRS = {
|
|
|
51706
51714
|
};
|
|
51707
51715
|
|
|
51708
51716
|
const MESSAGE_ID$9 = 'obsolete';
|
|
51709
|
-
const rule$
|
|
51717
|
+
const rule$B = createRule({
|
|
51710
51718
|
name: 'no-obsolete-attrs',
|
|
51711
51719
|
rule: {
|
|
51712
51720
|
create(context) {
|
|
@@ -51784,7 +51792,7 @@ const OBSOLETE_HTML_TAGS = new Set([
|
|
|
51784
51792
|
]);
|
|
51785
51793
|
|
|
51786
51794
|
const MESSAGE_ID$8 = 'unexpected';
|
|
51787
|
-
const rule$
|
|
51795
|
+
const rule$A = createRule({
|
|
51788
51796
|
name: 'no-obsolete-tags',
|
|
51789
51797
|
rule: {
|
|
51790
51798
|
create(context) {
|
|
@@ -51811,7 +51819,7 @@ const rule$z = createRule({
|
|
|
51811
51819
|
},
|
|
51812
51820
|
});
|
|
51813
51821
|
|
|
51814
|
-
const rule$
|
|
51822
|
+
const rule$z = createRule({
|
|
51815
51823
|
create(context) {
|
|
51816
51824
|
const { checker, esTreeNodeToTSNodeMap, sourceCode } = getTypeAwareRuleContext(context);
|
|
51817
51825
|
return {
|
|
@@ -51955,11 +51963,175 @@ const config$2 = {
|
|
|
51955
51963
|
type: 'problem',
|
|
51956
51964
|
},
|
|
51957
51965
|
};
|
|
51958
|
-
const rule$
|
|
51966
|
+
const rule$y = createRule({
|
|
51959
51967
|
name: 'no-project-as-in-ng-template',
|
|
51960
51968
|
rule: config$2,
|
|
51961
51969
|
});
|
|
51962
51970
|
|
|
51971
|
+
function getCommaAfter(sourceCode, node) {
|
|
51972
|
+
const token = sourceCode.getTokenAfter(node);
|
|
51973
|
+
return token?.value === ',' ? token : null;
|
|
51974
|
+
}
|
|
51975
|
+
function getCommaBefore(sourceCode, node) {
|
|
51976
|
+
const token = sourceCode.getTokenBefore(node);
|
|
51977
|
+
return token?.value === ',' ? token : null;
|
|
51978
|
+
}
|
|
51979
|
+
function removeStandaloneLine(sourceCode, fixer, node) {
|
|
51980
|
+
const lineStart = getLineStartOffset(sourceCode.text, node.range[0]);
|
|
51981
|
+
const nextLineStart = getNextLineStartOffset(sourceCode.text, node.range[1]);
|
|
51982
|
+
return fixer.removeRange([lineStart, nextLineStart]);
|
|
51983
|
+
}
|
|
51984
|
+
function isStandaloneListItem(node, previousNode, nextNode) {
|
|
51985
|
+
const startsOwnLine = previousNode === null || previousNode.loc.end.line < node.loc.start.line;
|
|
51986
|
+
const endsOwnLine = nextNode === null || nextNode.loc.start.line > node.loc.end.line;
|
|
51987
|
+
return startsOwnLine && endsOwnLine;
|
|
51988
|
+
}
|
|
51989
|
+
function removeCommaSeparatedNode(sourceCode, fixer, node, previousNode, nextNode) {
|
|
51990
|
+
if (isStandaloneListItem(node, previousNode, nextNode)) {
|
|
51991
|
+
return removeStandaloneLine(sourceCode, fixer, node);
|
|
51992
|
+
}
|
|
51993
|
+
const commaAfter = getCommaAfter(sourceCode, node);
|
|
51994
|
+
if (nextNode && commaAfter) {
|
|
51995
|
+
return fixer.removeRange([node.range[0], nextNode.range[0]]);
|
|
51996
|
+
}
|
|
51997
|
+
const commaBefore = getCommaBefore(sourceCode, node);
|
|
51998
|
+
if (commaBefore) {
|
|
51999
|
+
return fixer.removeRange([
|
|
52000
|
+
commaBefore.range[0],
|
|
52001
|
+
commaAfter?.range[1] ?? node.range[1],
|
|
52002
|
+
]);
|
|
52003
|
+
}
|
|
52004
|
+
return commaAfter ? fixer.removeRange([node.range[0], commaAfter.range[1]]) : null;
|
|
52005
|
+
}
|
|
52006
|
+
|
|
52007
|
+
const WRITE_METHODS = new Set([
|
|
52008
|
+
'appendFile',
|
|
52009
|
+
'appendFileSync',
|
|
52010
|
+
'writeFile',
|
|
52011
|
+
'writeFileSync',
|
|
52012
|
+
]);
|
|
52013
|
+
const FS_NAMESPACE_NAMES = new Set(['fs', 'fsPromises']);
|
|
52014
|
+
function isWriteMethod(name) {
|
|
52015
|
+
return name !== null && WRITE_METHODS.has(name);
|
|
52016
|
+
}
|
|
52017
|
+
function isFsNamespaceObject(node) {
|
|
52018
|
+
if (node.type === dist$4.AST_NODE_TYPES.Identifier) {
|
|
52019
|
+
return FS_NAMESPACE_NAMES.has(node.name);
|
|
52020
|
+
}
|
|
52021
|
+
if (node.type !== dist$4.AST_NODE_TYPES.MemberExpression) {
|
|
52022
|
+
return false;
|
|
52023
|
+
}
|
|
52024
|
+
const isFsPromisesNamespace = node.object.type === dist$4.AST_NODE_TYPES.Identifier &&
|
|
52025
|
+
node.object.name === 'fs' &&
|
|
52026
|
+
getMemberExpressionPropertyName(node) === 'promises';
|
|
52027
|
+
return isFsPromisesNamespace;
|
|
52028
|
+
}
|
|
52029
|
+
function getWriteMethodName(callee) {
|
|
52030
|
+
if (callee.type === dist$4.AST_NODE_TYPES.Identifier) {
|
|
52031
|
+
return callee.name;
|
|
52032
|
+
}
|
|
52033
|
+
return callee.type === dist$4.AST_NODE_TYPES.MemberExpression &&
|
|
52034
|
+
isFsNamespaceObject(callee.object)
|
|
52035
|
+
? getMemberExpressionPropertyName(callee)
|
|
52036
|
+
: null;
|
|
52037
|
+
}
|
|
52038
|
+
function isRedundantUtf8Encoding(node) {
|
|
52039
|
+
const value = getStaticStringValue(node);
|
|
52040
|
+
if (value === null) {
|
|
52041
|
+
return false;
|
|
52042
|
+
}
|
|
52043
|
+
const normalizedValue = value.toLowerCase();
|
|
52044
|
+
return normalizedValue === 'utf8' || normalizedValue === 'utf-8';
|
|
52045
|
+
}
|
|
52046
|
+
function hasSpreadProperty(node) {
|
|
52047
|
+
return node.properties.some((property) => property.type === dist$4.AST_NODE_TYPES.SpreadElement);
|
|
52048
|
+
}
|
|
52049
|
+
function findRedundantEncodingProperty(node) {
|
|
52050
|
+
if (hasSpreadProperty(node)) {
|
|
52051
|
+
return null;
|
|
52052
|
+
}
|
|
52053
|
+
const encodingProperties = node.properties.filter((property) => property.type === dist$4.AST_NODE_TYPES.Property &&
|
|
52054
|
+
getObjectPropertyName(property) === 'encoding');
|
|
52055
|
+
if (encodingProperties.length !== 1) {
|
|
52056
|
+
return null;
|
|
52057
|
+
}
|
|
52058
|
+
const encodingProperty = encodingProperties[0];
|
|
52059
|
+
return encodingProperty && isRedundantUtf8Encoding(encodingProperty.value)
|
|
52060
|
+
? encodingProperty
|
|
52061
|
+
: null;
|
|
52062
|
+
}
|
|
52063
|
+
function getObjectPropertyFix(sourceCode, fixer, objectExpression, property) {
|
|
52064
|
+
const propertyIndex = objectExpression.properties.indexOf(property);
|
|
52065
|
+
const previousProperty = objectExpression.properties[propertyIndex - 1] ?? null;
|
|
52066
|
+
const nextProperty = objectExpression.properties[propertyIndex + 1] ?? null;
|
|
52067
|
+
return removeCommaSeparatedNode(sourceCode, fixer, property, previousProperty, nextProperty);
|
|
52068
|
+
}
|
|
52069
|
+
function getOptionsArgumentFix(sourceCode, fixer, callExpression, options) {
|
|
52070
|
+
const argumentIndex = callExpression.arguments.indexOf(options);
|
|
52071
|
+
const previousArgument = callExpression.arguments[argumentIndex - 1] ?? null;
|
|
52072
|
+
const nextArgument = callExpression.arguments[argumentIndex + 1] ?? null;
|
|
52073
|
+
return removeCommaSeparatedNode(sourceCode, fixer, options, previousArgument, nextArgument);
|
|
52074
|
+
}
|
|
52075
|
+
const rule$x = createRule({
|
|
52076
|
+
create(context) {
|
|
52077
|
+
const { sourceCode } = context;
|
|
52078
|
+
function reportRedundantEncodingArgument(callExpression, encodingArgument) {
|
|
52079
|
+
context.report({
|
|
52080
|
+
fix(fixer) {
|
|
52081
|
+
return getOptionsArgumentFix(sourceCode, fixer, callExpression, encodingArgument);
|
|
52082
|
+
},
|
|
52083
|
+
messageId: 'noRedundantFsEncoding',
|
|
52084
|
+
node: encodingArgument,
|
|
52085
|
+
});
|
|
52086
|
+
}
|
|
52087
|
+
function reportRedundantEncodingProperty(callExpression, options, encodingProperty) {
|
|
52088
|
+
context.report({
|
|
52089
|
+
fix(fixer) {
|
|
52090
|
+
const hasOnlyEncodingProperty = options.properties.length === 1;
|
|
52091
|
+
return hasOnlyEncodingProperty
|
|
52092
|
+
? getOptionsArgumentFix(sourceCode, fixer, callExpression, options)
|
|
52093
|
+
: getObjectPropertyFix(sourceCode, fixer, options, encodingProperty);
|
|
52094
|
+
},
|
|
52095
|
+
messageId: 'noRedundantFsEncoding',
|
|
52096
|
+
node: encodingProperty,
|
|
52097
|
+
});
|
|
52098
|
+
}
|
|
52099
|
+
return {
|
|
52100
|
+
CallExpression(node) {
|
|
52101
|
+
if (!isWriteMethod(getWriteMethodName(node.callee))) {
|
|
52102
|
+
return;
|
|
52103
|
+
}
|
|
52104
|
+
const options = node.arguments[2];
|
|
52105
|
+
if (!options || options.type === dist$4.AST_NODE_TYPES.SpreadElement) {
|
|
52106
|
+
return;
|
|
52107
|
+
}
|
|
52108
|
+
if (options.type !== dist$4.AST_NODE_TYPES.ObjectExpression) {
|
|
52109
|
+
if (isRedundantUtf8Encoding(options)) {
|
|
52110
|
+
reportRedundantEncodingArgument(node, options);
|
|
52111
|
+
}
|
|
52112
|
+
return;
|
|
52113
|
+
}
|
|
52114
|
+
const encodingProperty = findRedundantEncodingProperty(options);
|
|
52115
|
+
if (encodingProperty) {
|
|
52116
|
+
reportRedundantEncodingProperty(node, options, encodingProperty);
|
|
52117
|
+
}
|
|
52118
|
+
},
|
|
52119
|
+
};
|
|
52120
|
+
},
|
|
52121
|
+
meta: {
|
|
52122
|
+
docs: {
|
|
52123
|
+
description: 'Disallow redundant default utf8 encoding in Node.js file write calls.',
|
|
52124
|
+
},
|
|
52125
|
+
fixable: 'code',
|
|
52126
|
+
messages: {
|
|
52127
|
+
noRedundantFsEncoding: 'Remove redundant utf8 encoding. Node.js file write methods use utf8 by default for string data.',
|
|
52128
|
+
},
|
|
52129
|
+
schema: [],
|
|
52130
|
+
type: 'suggestion',
|
|
52131
|
+
},
|
|
52132
|
+
name: 'no-redundant-fs-encoding',
|
|
52133
|
+
});
|
|
52134
|
+
|
|
51963
52135
|
function collectArrayExpressions(node) {
|
|
51964
52136
|
const result = [];
|
|
51965
52137
|
if (node.type === dist$4.AST_NODE_TYPES.ArrayExpression) {
|
|
@@ -56434,36 +56606,37 @@ const plugin = {
|
|
|
56434
56606
|
},
|
|
56435
56607
|
rules: {
|
|
56436
56608
|
'array-as-const': rule$5,
|
|
56437
|
-
'at-compat': rule$
|
|
56438
|
-
'attrs-newline': rule$
|
|
56439
|
-
'class-accessibility-spacing': rule$
|
|
56609
|
+
'at-compat': rule$Z,
|
|
56610
|
+
'attrs-newline': rule$Y,
|
|
56611
|
+
'class-accessibility-spacing': rule$X,
|
|
56440
56612
|
'class-property-naming': rule$4,
|
|
56441
|
-
'decorator-key-sort': rule$
|
|
56442
|
-
'element-newline': rule$
|
|
56613
|
+
'decorator-key-sort': rule$W,
|
|
56614
|
+
'element-newline': rule$V,
|
|
56443
56615
|
'flat-exports': rule$3,
|
|
56444
|
-
'host-attributes-sort': rule$
|
|
56445
|
-
'html-logical-properties': rule$
|
|
56446
|
-
'import-integrity': rule$
|
|
56447
|
-
'injection-token-description': rule$
|
|
56448
|
-
'no-commonjs-import-patterns': rule$
|
|
56449
|
-
'no-deep-imports': rule$
|
|
56450
|
-
'no-deep-imports-to-indexed-packages': rule$
|
|
56451
|
-
'no-duplicate-attrs': rule$
|
|
56452
|
-
'no-duplicate-id': rule$
|
|
56453
|
-
'no-duplicate-in-head': rule$
|
|
56454
|
-
'no-empty-style-metadata': rule$
|
|
56455
|
-
'no-fully-untracked-effect': rule$
|
|
56456
|
-
'no-href-with-router-link': rule$
|
|
56457
|
-
'no-implicit-public': rule$
|
|
56458
|
-
'no-import-assertions': rule$
|
|
56459
|
-
'no-infinite-loop': rule$
|
|
56460
|
-
'no-legacy-peer-deps': rule$
|
|
56461
|
-
'no-nested-interactive': rule$
|
|
56462
|
-
'no-nested-ternary-in-template': rule$
|
|
56463
|
-
'no-obsolete-attrs': rule$
|
|
56464
|
-
'no-obsolete-tags': rule$
|
|
56465
|
-
'no-playwright-empty-fill': rule$
|
|
56466
|
-
'no-project-as-in-ng-template': rule$
|
|
56616
|
+
'host-attributes-sort': rule$U,
|
|
56617
|
+
'html-logical-properties': rule$T,
|
|
56618
|
+
'import-integrity': rule$S,
|
|
56619
|
+
'injection-token-description': rule$R,
|
|
56620
|
+
'no-commonjs-import-patterns': rule$Q,
|
|
56621
|
+
'no-deep-imports': rule$P,
|
|
56622
|
+
'no-deep-imports-to-indexed-packages': rule$O,
|
|
56623
|
+
'no-duplicate-attrs': rule$N,
|
|
56624
|
+
'no-duplicate-id': rule$M,
|
|
56625
|
+
'no-duplicate-in-head': rule$L,
|
|
56626
|
+
'no-empty-style-metadata': rule$K,
|
|
56627
|
+
'no-fully-untracked-effect': rule$J,
|
|
56628
|
+
'no-href-with-router-link': rule$I,
|
|
56629
|
+
'no-implicit-public': rule$H,
|
|
56630
|
+
'no-import-assertions': rule$G,
|
|
56631
|
+
'no-infinite-loop': rule$F,
|
|
56632
|
+
'no-legacy-peer-deps': rule$E,
|
|
56633
|
+
'no-nested-interactive': rule$D,
|
|
56634
|
+
'no-nested-ternary-in-template': rule$C,
|
|
56635
|
+
'no-obsolete-attrs': rule$B,
|
|
56636
|
+
'no-obsolete-tags': rule$A,
|
|
56637
|
+
'no-playwright-empty-fill': rule$z,
|
|
56638
|
+
'no-project-as-in-ng-template': rule$y,
|
|
56639
|
+
'no-redundant-fs-encoding': rule$x,
|
|
56467
56640
|
'no-redundant-type-annotation': rule$w,
|
|
56468
56641
|
'no-repeated-signal-in-conditional': rule$v,
|
|
56469
56642
|
'no-restricted-attr-values': rule$2,
|
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.540.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": {
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type TSESLint, type TSESTree } from '@typescript-eslint/utils';
|
|
2
|
+
export type CommaSeparatedNode = TSESTree.Expression | TSESTree.Property | TSESTree.SpreadElement;
|
|
3
|
+
export declare function removeCommaSeparatedNode(sourceCode: Readonly<TSESLint.SourceCode>, fixer: TSESLint.RuleFixer, node: CommaSeparatedNode, previousNode: CommaSeparatedNode | null, nextNode: CommaSeparatedNode | null): TSESLint.RuleFix | null;
|