@fabdeh/eslint-config 0.1.2 → 0.2.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 +2 -3
- package/dist/index.d.mts +15 -64
- package/dist/index.mjs +135 -191
- package/package.json +70 -38
- package/dist/index.cjs +0 -2001
- package/dist/index.d.cts +0 -782
- package/dist/index.d.ts +0 -782
package/dist/index.mjs
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
+
import { isPackageExists } from 'local-pkg';
|
|
1
2
|
import tseslint from 'typescript-eslint';
|
|
2
3
|
import { statSync } from 'node:fs';
|
|
3
|
-
import {
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
5
|
+
import { resolve, dirname, join } from 'node:path';
|
|
4
6
|
import process from 'node:process';
|
|
5
7
|
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { isPackageExists } from 'local-pkg';
|
|
7
|
-
import eslintComments from '@eslint-community/eslint-plugin-eslint-comments';
|
|
8
|
-
import * as importX from 'eslint-plugin-import-x';
|
|
9
8
|
import eslint from '@eslint/js';
|
|
10
9
|
import preferArrowFunctions from 'eslint-plugin-prefer-arrow-functions';
|
|
11
10
|
import unusedImports from 'eslint-plugin-unused-imports';
|
|
12
11
|
import globals from 'globals';
|
|
12
|
+
import eslintComments from '@eslint-community/eslint-plugin-eslint-comments';
|
|
13
|
+
import * as importX from 'eslint-plugin-import-x';
|
|
13
14
|
import jsdocPlugin from 'eslint-plugin-jsdoc';
|
|
14
|
-
import { mergeProcessors, processorPassThrough } from 'eslint-merge-processors';
|
|
15
15
|
import perfectionistPlugin from 'eslint-plugin-perfectionist';
|
|
16
16
|
import unicornPlugin from 'eslint-plugin-unicorn';
|
|
17
|
+
import { mergeProcessors, processorPassThrough } from 'eslint-merge-processors';
|
|
17
18
|
|
|
18
19
|
const GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
|
|
19
20
|
const GLOB_SRC = `**/*.${GLOB_SRC_EXT}`;
|
|
@@ -75,24 +76,6 @@ const GLOB_EXCLUDE = [
|
|
|
75
76
|
|
|
76
77
|
const SCOPE_URL = fileURLToPath(new URL(".", import.meta.url));
|
|
77
78
|
const IS_CWD_IN_SCOPE = isPackageExists("@fabdeh/eslint-config");
|
|
78
|
-
function isInEditorEnv() {
|
|
79
|
-
if (process.env.CI) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
const envKeys = Object.keys(process.env);
|
|
83
|
-
if (envKeys.some((k) => /^GIT_/i.test(k))) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
const isVsCode = envKeys.some((k) => /^VSCODE_/i.test(k));
|
|
87
|
-
const isIntelliJ = envKeys.some((k) => /^INTELLIJ_/i.test(k));
|
|
88
|
-
const isJetbrains = envKeys.some((k) => /^JETBRAINS_/i.test(k));
|
|
89
|
-
const isVim = envKeys.some((k) => /^VIM$/i.test(k));
|
|
90
|
-
const isNeoVim = envKeys.some((k) => /^NVIM$/i.test(k));
|
|
91
|
-
return isVsCode || isIntelliJ || isJetbrains || isVim || isNeoVim;
|
|
92
|
-
}
|
|
93
|
-
function toArray(value) {
|
|
94
|
-
return Array.isArray(value) ? value : [value];
|
|
95
|
-
}
|
|
96
79
|
async function interopDefault(m) {
|
|
97
80
|
const resolved = await m;
|
|
98
81
|
return resolved.default ?? resolved;
|
|
@@ -139,6 +122,19 @@ async function ensurePackages(packages) {
|
|
|
139
122
|
await import('@antfu/install-pkg').then((i) => i.installPackage(nonExistingPackages, { dev: true }));
|
|
140
123
|
}
|
|
141
124
|
}
|
|
125
|
+
async function findNearestPackageJsonName(directoryPath = resolve()) {
|
|
126
|
+
try {
|
|
127
|
+
const packageJsonPath = join(directoryPath, "package.json");
|
|
128
|
+
const packageJsonData = JSON.parse(await readFile(packageJsonPath, "utf8"));
|
|
129
|
+
return packageJsonData.name;
|
|
130
|
+
} catch {
|
|
131
|
+
const parentDir = dirname(directoryPath);
|
|
132
|
+
if (directoryPath === parentDir) {
|
|
133
|
+
throw new Error("No package.json file found.");
|
|
134
|
+
}
|
|
135
|
+
return findNearestPackageJsonName(parentDir);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
142
138
|
|
|
143
139
|
async function angular(options = {}) {
|
|
144
140
|
const angularEslint = await interopDefault(import('angular-eslint'));
|
|
@@ -151,10 +147,36 @@ async function angular(options = {}) {
|
|
|
151
147
|
},
|
|
152
148
|
processor: angularEslint.processInlineTemplates,
|
|
153
149
|
files: [GLOB_TS],
|
|
154
|
-
extends: [angularEslint.configs.tsRecommended],
|
|
155
150
|
rules: {
|
|
156
151
|
"max-classes-per-file": ["error", 1],
|
|
157
152
|
"max-lines": ["error", 400],
|
|
153
|
+
"new-cap": [
|
|
154
|
+
"error",
|
|
155
|
+
{
|
|
156
|
+
capIsNewExceptions: [
|
|
157
|
+
"Attribute",
|
|
158
|
+
"Component",
|
|
159
|
+
"ContentChild",
|
|
160
|
+
"ContentChildren",
|
|
161
|
+
"Directive",
|
|
162
|
+
"Host",
|
|
163
|
+
"HostBinding",
|
|
164
|
+
"HostListener",
|
|
165
|
+
"Inject",
|
|
166
|
+
"Injectable",
|
|
167
|
+
"Input",
|
|
168
|
+
"NgModule",
|
|
169
|
+
"Optional",
|
|
170
|
+
"Output",
|
|
171
|
+
"Pipe",
|
|
172
|
+
"Self",
|
|
173
|
+
"SkipSelf",
|
|
174
|
+
"ViewChild",
|
|
175
|
+
"ViewChildren"
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
...angularEslint.configs.tsRecommended.find((c) => c.name === "angular-eslint/ts-recommended")?.rules,
|
|
158
180
|
"@angular-eslint/component-max-inline-declarations": "error",
|
|
159
181
|
"@angular-eslint/component-selector": [
|
|
160
182
|
"error",
|
|
@@ -194,14 +216,14 @@ async function angular(options = {}) {
|
|
|
194
216
|
{
|
|
195
217
|
name: "fabdeh/angular-template/rules",
|
|
196
218
|
plugins: {
|
|
197
|
-
"@angular-eslint": angularEslint.
|
|
219
|
+
"@angular-eslint/template": angularEslint.templatePlugin
|
|
220
|
+
},
|
|
221
|
+
languageOptions: {
|
|
222
|
+
parser: angularEslint.templateParser
|
|
198
223
|
},
|
|
199
224
|
files: [GLOB_HTML],
|
|
200
|
-
extends: [
|
|
201
|
-
...angularEslint.configs.templateRecommended,
|
|
202
|
-
...enableAccessibilityRules ? angularEslint.configs.templateAccessibility : []
|
|
203
|
-
],
|
|
204
225
|
rules: {
|
|
226
|
+
...angularEslint.configs.templateRecommended.find((c) => c.name === "angular-eslint/template-recommended")?.rules,
|
|
205
227
|
"@angular-eslint/template/attributes-order": ["error", { alphabetical: true }],
|
|
206
228
|
"@angular-eslint/template/button-has-type": "error",
|
|
207
229
|
"@angular-eslint/template/conditional-complexity": "error",
|
|
@@ -213,6 +235,8 @@ async function angular(options = {}) {
|
|
|
213
235
|
"@angular-eslint/template/prefer-control-flow": "error",
|
|
214
236
|
"@angular-eslint/template/prefer-ngsrc": "error",
|
|
215
237
|
"@angular-eslint/template/prefer-self-closing-tags": "error",
|
|
238
|
+
"@angular-eslint/template/prefer-static-string-properties": "error",
|
|
239
|
+
...enableAccessibilityRules ? angularEslint.configs.templateAccessibility.find((c) => c.name === "angular-eslint/template-accessibility")?.rules : {},
|
|
216
240
|
...htmlOverrides
|
|
217
241
|
}
|
|
218
242
|
}
|
|
@@ -294,7 +318,7 @@ function imports(options = {}) {
|
|
|
294
318
|
}
|
|
295
319
|
|
|
296
320
|
function javascript(options = {}) {
|
|
297
|
-
const {
|
|
321
|
+
const { overrides = {} } = options;
|
|
298
322
|
return tseslint.config(
|
|
299
323
|
{
|
|
300
324
|
name: "fabdeh/javascript/setup",
|
|
@@ -330,8 +354,8 @@ function javascript(options = {}) {
|
|
|
330
354
|
"prefer-arrow-functions": preferArrowFunctions,
|
|
331
355
|
"unused-imports": unusedImports
|
|
332
356
|
},
|
|
333
|
-
extends: [eslint.configs.recommended, ...tseslint.configs.recommended],
|
|
334
357
|
rules: {
|
|
358
|
+
...eslint.configs.recommended.rules,
|
|
335
359
|
"accessor-pairs": "error",
|
|
336
360
|
"array-callback-return": "error",
|
|
337
361
|
"block-scoped-var": "error",
|
|
@@ -350,32 +374,7 @@ function javascript(options = {}) {
|
|
|
350
374
|
"Undefined",
|
|
351
375
|
"undefined"
|
|
352
376
|
],
|
|
353
|
-
"new-cap":
|
|
354
|
-
"error",
|
|
355
|
-
{
|
|
356
|
-
capIsNewExceptions: [
|
|
357
|
-
"Attribute",
|
|
358
|
-
"Component",
|
|
359
|
-
"ContentChild",
|
|
360
|
-
"ContentChildren",
|
|
361
|
-
"Directive",
|
|
362
|
-
"Host",
|
|
363
|
-
"HostBinding",
|
|
364
|
-
"HostListener",
|
|
365
|
-
"Inject",
|
|
366
|
-
"Injectable",
|
|
367
|
-
"Input",
|
|
368
|
-
"NgModule",
|
|
369
|
-
"Optional",
|
|
370
|
-
"Output",
|
|
371
|
-
"Pipe",
|
|
372
|
-
"Self",
|
|
373
|
-
"SkipSelf",
|
|
374
|
-
"ViewChild",
|
|
375
|
-
"ViewChildren"
|
|
376
|
-
]
|
|
377
|
-
}
|
|
378
|
-
] : "error",
|
|
377
|
+
"new-cap": "error",
|
|
379
378
|
"no-alert": "error",
|
|
380
379
|
"no-caller": "error",
|
|
381
380
|
"no-cond-assign": ["error", "always"],
|
|
@@ -419,6 +418,7 @@ function javascript(options = {}) {
|
|
|
419
418
|
"no-useless-constructor": "error",
|
|
420
419
|
"no-useless-rename": "error",
|
|
421
420
|
"no-useless-return": "error",
|
|
421
|
+
"no-var": "error",
|
|
422
422
|
"object-shorthand": [
|
|
423
423
|
"error",
|
|
424
424
|
"always",
|
|
@@ -432,14 +432,18 @@ function javascript(options = {}) {
|
|
|
432
432
|
"error",
|
|
433
433
|
{ singleReturnOnly: true, allowNamedFunctions: true }
|
|
434
434
|
],
|
|
435
|
+
"prefer-const": "error",
|
|
435
436
|
"prefer-exponentiation-operator": "error",
|
|
436
437
|
"prefer-object-spread": "error",
|
|
437
438
|
"prefer-promise-reject-errors": "error",
|
|
438
439
|
"prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
|
|
440
|
+
"prefer-rest-params": "error",
|
|
441
|
+
"prefer-spread": "error",
|
|
439
442
|
"prefer-template": "error",
|
|
440
443
|
"symbol-description": "error",
|
|
441
444
|
"unicode-bom": ["error", "never"],
|
|
442
|
-
"unused-imports/no-unused-imports":
|
|
445
|
+
"unused-imports/no-unused-imports": "error",
|
|
446
|
+
"no-unused-vars": "off",
|
|
443
447
|
"unused-imports/no-unused-vars": [
|
|
444
448
|
"error",
|
|
445
449
|
{
|
|
@@ -454,64 +458,18 @@ function javascript(options = {}) {
|
|
|
454
458
|
"valid-typeof": ["error", { requireStringLiterals: true }],
|
|
455
459
|
"vars-on-top": "error",
|
|
456
460
|
yoda: ["error", "never", { exceptRange: true }],
|
|
457
|
-
"@typescript-eslint/
|
|
458
|
-
|
|
459
|
-
|
|
461
|
+
"@typescript-eslint/ban-ts-comment": "error",
|
|
462
|
+
"@typescript-eslint/no-extra-non-null-assertion": "error",
|
|
463
|
+
"@typescript-eslint/no-misused-new": "error",
|
|
464
|
+
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
|
|
465
|
+
"@typescript-eslint/no-require-imports": ["error", { allowAsImport: true }],
|
|
466
|
+
"@typescript-eslint/no-this-alias": "error",
|
|
460
467
|
...overrides
|
|
461
468
|
}
|
|
462
469
|
}
|
|
463
470
|
);
|
|
464
471
|
}
|
|
465
472
|
|
|
466
|
-
async function jest(options = {}) {
|
|
467
|
-
const {
|
|
468
|
-
overrides = {},
|
|
469
|
-
useJestDom = isPackageExists("@testing-library/jest-dom"),
|
|
470
|
-
useTestingLibrary = isPackageExists("@testing-library/angular"),
|
|
471
|
-
stylistic = true
|
|
472
|
-
} = options;
|
|
473
|
-
const [jestPlugin, jestDomPlugin, testingLibraryPlugin] = await Promise.all([
|
|
474
|
-
interopDefault(import('eslint-plugin-jest')),
|
|
475
|
-
useJestDom ? interopDefault(import('eslint-plugin-jest-dom')) : Promise.resolve(undefined),
|
|
476
|
-
useTestingLibrary ? interopDefault(import('eslint-plugin-testing-library')) : Promise.resolve(undefined)
|
|
477
|
-
]);
|
|
478
|
-
return tseslint.config({
|
|
479
|
-
name: "fabdeh/jest/rules",
|
|
480
|
-
plugins: {
|
|
481
|
-
jest: jestPlugin
|
|
482
|
-
},
|
|
483
|
-
languageOptions: {
|
|
484
|
-
globals: {
|
|
485
|
-
...globals.node,
|
|
486
|
-
...globals.jest
|
|
487
|
-
}
|
|
488
|
-
},
|
|
489
|
-
files: [...GLOB_TESTS, `** /jest.config.${GLOB_SRC_EXT}`],
|
|
490
|
-
extends: [
|
|
491
|
-
jestPlugin.configs["flat/recommended"],
|
|
492
|
-
...stylistic ? [jestPlugin.configs["flat/style"]] : [],
|
|
493
|
-
...jestDomPlugin ? [jestDomPlugin.configs["flat/recommended"]] : [],
|
|
494
|
-
...testingLibraryPlugin ? [testingLibraryPlugin.configs["flat/angular"]] : []
|
|
495
|
-
],
|
|
496
|
-
rules: {
|
|
497
|
-
"max-classes-per-file": "off",
|
|
498
|
-
"max-lines": "off",
|
|
499
|
-
"@typescript-eslint/consistent-type-assertions": "off",
|
|
500
|
-
"@typescript-eslint/no-empty-function": "off",
|
|
501
|
-
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
502
|
-
"@typescript-eslint/no-unsafe-call": "off",
|
|
503
|
-
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
504
|
-
"@typescript-eslint/unbound-method": "off",
|
|
505
|
-
"jest/consistent-test-it": ["error", { fn: "test" }],
|
|
506
|
-
"jest/prefer-spy-on": "error",
|
|
507
|
-
"jest/require-top-level-describe": "error",
|
|
508
|
-
"jest/unbound-method": "error",
|
|
509
|
-
"unicorn/no-null": "off",
|
|
510
|
-
...overrides
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
|
-
|
|
515
473
|
function jsdoc(options = {}) {
|
|
516
474
|
const { stylistic = true } = options;
|
|
517
475
|
return tseslint.config(
|
|
@@ -643,28 +601,6 @@ async function markdown(options = {}) {
|
|
|
643
601
|
files = [GLOB_MARKDOWN],
|
|
644
602
|
overrides = {}
|
|
645
603
|
} = options;
|
|
646
|
-
const parserPlain = {
|
|
647
|
-
meta: {
|
|
648
|
-
name: "parser-plain"
|
|
649
|
-
},
|
|
650
|
-
parseForESLint: (code) => ({
|
|
651
|
-
ast: {
|
|
652
|
-
body: [],
|
|
653
|
-
comments: [],
|
|
654
|
-
loc: { end: code.length, start: 0 },
|
|
655
|
-
range: [0, code.length],
|
|
656
|
-
tokens: [],
|
|
657
|
-
type: "Program"
|
|
658
|
-
},
|
|
659
|
-
// eslint-disable-next-line unicorn/no-null
|
|
660
|
-
scopeManager: null,
|
|
661
|
-
services: { isPlain: true },
|
|
662
|
-
visitorKeys: {
|
|
663
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
664
|
-
Program: []
|
|
665
|
-
}
|
|
666
|
-
})
|
|
667
|
-
};
|
|
668
604
|
const markdownPlugin = await interopDefault(import('@eslint/markdown'));
|
|
669
605
|
return tseslint.config(
|
|
670
606
|
{
|
|
@@ -680,19 +616,16 @@ async function markdown(options = {}) {
|
|
|
680
616
|
processor: mergeProcessors([
|
|
681
617
|
markdownPlugin.processors.markdown,
|
|
682
618
|
processorPassThrough
|
|
683
|
-
])
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
languageOptions: {
|
|
689
|
-
parser: parserPlain
|
|
690
|
-
},
|
|
691
|
-
files
|
|
619
|
+
]),
|
|
620
|
+
rules: {
|
|
621
|
+
...markdownPlugin.configs.recommended.at(0)?.rules,
|
|
622
|
+
"markdown/no-duplicate-headings": "error"
|
|
623
|
+
}
|
|
692
624
|
},
|
|
693
625
|
{
|
|
694
626
|
name: "fabdeh/markdown/disables",
|
|
695
627
|
languageOptions: {
|
|
628
|
+
parser: tseslint.parser,
|
|
696
629
|
parserOptions: {
|
|
697
630
|
ecmaFeatures: {
|
|
698
631
|
impliedStrict: true
|
|
@@ -700,8 +633,8 @@ async function markdown(options = {}) {
|
|
|
700
633
|
}
|
|
701
634
|
},
|
|
702
635
|
files: [GLOB_MARKDOWN_CODE],
|
|
703
|
-
extends: [tseslint.configs.disableTypeChecked],
|
|
704
636
|
rules: {
|
|
637
|
+
...tseslint.configs.disableTypeChecked.rules,
|
|
705
638
|
"import-x/newline-after-import": "off",
|
|
706
639
|
"no-alert": "off",
|
|
707
640
|
"no-console": "off",
|
|
@@ -762,17 +695,22 @@ async function ngrx(options = {}) {
|
|
|
762
695
|
signals = isPackageExists("@ngrx/signals")
|
|
763
696
|
} = options;
|
|
764
697
|
const configs = [];
|
|
698
|
+
let addOperatorsRules = false;
|
|
699
|
+
const ngrxOperatorsFiles = [];
|
|
765
700
|
if (store) {
|
|
766
701
|
const {
|
|
767
702
|
files = DEFAULT_STORE_GLOB,
|
|
768
703
|
enforceOperatorsRules = isPackageExists("@ngrx/operators"),
|
|
769
704
|
overrides = {}
|
|
770
705
|
} = typeof store === "object" ? store : {};
|
|
706
|
+
addOperatorsRules ||= enforceOperatorsRules;
|
|
707
|
+
ngrxOperatorsFiles.push(files);
|
|
771
708
|
configs.push({
|
|
772
709
|
name: "fabdeh/ngrx-store/rules",
|
|
773
710
|
files,
|
|
774
|
-
|
|
711
|
+
plugins: { "@ngrx": ngrxPlugin },
|
|
775
712
|
rules: {
|
|
713
|
+
...ngrxPlugin.configs.store.find((c) => c.name === "ngrx/store")?.rules,
|
|
776
714
|
"@typescript-eslint/naming-convention": [
|
|
777
715
|
"error",
|
|
778
716
|
...namingConvention,
|
|
@@ -803,11 +741,14 @@ async function ngrx(options = {}) {
|
|
|
803
741
|
enforceOperatorsRules = isPackageExists("@ngrx/operators"),
|
|
804
742
|
overrides = {}
|
|
805
743
|
} = typeof effects === "object" ? effects : {};
|
|
744
|
+
addOperatorsRules ||= enforceOperatorsRules;
|
|
745
|
+
ngrxOperatorsFiles.push(files);
|
|
806
746
|
configs.push({
|
|
807
747
|
name: "fabdeh/ngrx-effects/rules",
|
|
808
748
|
files,
|
|
809
|
-
|
|
749
|
+
plugins: { "@ngrx": ngrxPlugin },
|
|
810
750
|
rules: {
|
|
751
|
+
...ngrxPlugin.configs.effects.find((c) => c.name === "ngrx/effects")?.rules,
|
|
811
752
|
"@typescript-eslint/naming-convention": [
|
|
812
753
|
"error",
|
|
813
754
|
...namingConvention,
|
|
@@ -835,11 +776,14 @@ async function ngrx(options = {}) {
|
|
|
835
776
|
{ selector: "variableLike", format: ["camelCase"] },
|
|
836
777
|
{ selector: "memberLike", format: ["camelCase"], leadingUnderscore: "allow" }
|
|
837
778
|
];
|
|
779
|
+
addOperatorsRules ||= enforceOperatorsRules;
|
|
780
|
+
ngrxOperatorsFiles.push(files);
|
|
838
781
|
configs.push({
|
|
839
782
|
name: "fabdeh/ngrx-signals/rules",
|
|
840
783
|
files,
|
|
841
|
-
|
|
784
|
+
plugins: { "@ngrx": ngrxPlugin },
|
|
842
785
|
rules: {
|
|
786
|
+
...ngrxPlugin.configs.signals.find((c) => c.name === "ngrx/signals")?.rules,
|
|
843
787
|
"@typescript-eslint/naming-convention": [
|
|
844
788
|
"error",
|
|
845
789
|
...allowLeadingUnderscoreOnMemberLike(namingConvention),
|
|
@@ -855,6 +799,16 @@ async function ngrx(options = {}) {
|
|
|
855
799
|
}
|
|
856
800
|
});
|
|
857
801
|
}
|
|
802
|
+
if (addOperatorsRules) {
|
|
803
|
+
configs.push({
|
|
804
|
+
name: "fabdeh/ngrx-operators/rules",
|
|
805
|
+
files: [...ngrxOperatorsFiles],
|
|
806
|
+
plugins: { "@ngrx": ngrxPlugin },
|
|
807
|
+
rules: {
|
|
808
|
+
...ngrxPlugin.configs.operators.find((c) => c.name === "ngrx/operators")?.rules
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
}
|
|
858
812
|
return tseslint.config(configs);
|
|
859
813
|
}
|
|
860
814
|
|
|
@@ -907,9 +861,11 @@ const SORT_UNION_OR_INTERSECTION_GROUPS = [
|
|
|
907
861
|
"unknown"
|
|
908
862
|
];
|
|
909
863
|
|
|
910
|
-
function perfectionist() {
|
|
864
|
+
async function perfectionist() {
|
|
865
|
+
const tsconfigRootDir = await findNearestPackageJsonName() === "@fabdeh/eslint-config" ? void 0 : getWorkspaceRoot(process.cwd(), process.cwd());
|
|
911
866
|
return tseslint.config({
|
|
912
867
|
name: "fabdeh/perfectionist/rules",
|
|
868
|
+
files: [GLOB_SRC],
|
|
913
869
|
plugins: {
|
|
914
870
|
perfectionist: perfectionistPlugin
|
|
915
871
|
},
|
|
@@ -919,7 +875,7 @@ function perfectionist() {
|
|
|
919
875
|
"error",
|
|
920
876
|
{
|
|
921
877
|
groups: SORT_IMPORT_GROUPS,
|
|
922
|
-
tsconfigRootDir
|
|
878
|
+
tsconfigRootDir,
|
|
923
879
|
order: "asc",
|
|
924
880
|
type: "natural",
|
|
925
881
|
newlinesBetween: "never"
|
|
@@ -1308,14 +1264,13 @@ function typescript(options = {}) {
|
|
|
1308
1264
|
name: "fabdeh/typescript/rules",
|
|
1309
1265
|
files: [GLOB_TS],
|
|
1310
1266
|
plugins: {
|
|
1311
|
-
"@typescript-eslint": tseslint.plugin
|
|
1267
|
+
"@typescript-eslint": tseslint.plugin,
|
|
1268
|
+
"unused-imports": unusedImports
|
|
1312
1269
|
},
|
|
1313
|
-
extends: [
|
|
1314
|
-
eslint.configs.recommended,
|
|
1315
|
-
...tseslint.configs.strictTypeChecked,
|
|
1316
|
-
...stylistic ? tseslint.configs.stylisticTypeChecked : []
|
|
1317
|
-
],
|
|
1318
1270
|
rules: {
|
|
1271
|
+
...tseslint.configs.stylisticTypeChecked.find((c) => c.name === "typescript-eslint/eslint-recommended")?.rules,
|
|
1272
|
+
...tseslint.configs.stylisticTypeChecked.find((c) => c.name === "typescript-eslint/strict-type-checked")?.rules,
|
|
1273
|
+
...stylistic ? tseslint.configs.stylisticTypeChecked.find((c) => c.name === "typescript-eslint/stylistic-type-checked")?.rules : {},
|
|
1319
1274
|
"@typescript-eslint/array-type": ["error", { default: "array" }],
|
|
1320
1275
|
"@typescript-eslint/consistent-indexed-object-style": "error",
|
|
1321
1276
|
"@typescript-eslint/consistent-type-assertions": [
|
|
@@ -1323,7 +1278,14 @@ function typescript(options = {}) {
|
|
|
1323
1278
|
{ assertionStyle: "as", objectLiteralTypeAssertions: "never" }
|
|
1324
1279
|
],
|
|
1325
1280
|
"@typescript-eslint/consistent-type-definitions": ["error", "interface"],
|
|
1281
|
+
"@typescript-eslint/consistent-type-exports": "error",
|
|
1282
|
+
"@typescript-eslint/consistent-type-imports": ["error", {
|
|
1283
|
+
disallowTypeAnnotations: false,
|
|
1284
|
+
fixStyle: "separate-type-imports",
|
|
1285
|
+
prefer: "type-imports"
|
|
1286
|
+
}],
|
|
1326
1287
|
"@typescript-eslint/dot-notation": "error",
|
|
1288
|
+
"@typescript-eslint/explicit-module-boundary-types": "error",
|
|
1327
1289
|
"@typescript-eslint/explicit-function-return-type": [
|
|
1328
1290
|
"error",
|
|
1329
1291
|
{
|
|
@@ -1347,12 +1309,11 @@ function typescript(options = {}) {
|
|
|
1347
1309
|
"@typescript-eslint/no-extraneous-class": ["error", { allowStaticOnly: true, allowWithDecorator: true }],
|
|
1348
1310
|
"@typescript-eslint/no-invalid-void-type": "error",
|
|
1349
1311
|
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
|
|
1350
|
-
"@typescript-eslint/no-require-imports": "error",
|
|
1351
1312
|
"@typescript-eslint/only-throw-error": "error",
|
|
1352
1313
|
"@typescript-eslint/no-unnecessary-condition": "error",
|
|
1353
1314
|
"@typescript-eslint/no-unnecessary-type-arguments": "error",
|
|
1354
1315
|
"@typescript-eslint/no-unsafe-unary-minus": "error",
|
|
1355
|
-
"@typescript-eslint/parameter-properties":
|
|
1316
|
+
"@typescript-eslint/parameter-properties": "error",
|
|
1356
1317
|
"@typescript-eslint/prefer-enum-initializers": "error",
|
|
1357
1318
|
"@typescript-eslint/prefer-for-of": "error",
|
|
1358
1319
|
"@typescript-eslint/prefer-function-type": "error",
|
|
@@ -1370,6 +1331,7 @@ function typescript(options = {}) {
|
|
|
1370
1331
|
"@typescript-eslint/switch-exhaustiveness-check": "error",
|
|
1371
1332
|
"@typescript-eslint/unbound-method": ["error", { ignoreStatic: true }],
|
|
1372
1333
|
"@typescript-eslint/unified-signatures": "error",
|
|
1334
|
+
"@typescript-eslint/no-unused-vars": "off",
|
|
1373
1335
|
...overrides
|
|
1374
1336
|
}
|
|
1375
1337
|
}
|
|
@@ -1380,9 +1342,11 @@ function unicorn(options = {}) {
|
|
|
1380
1342
|
return tseslint.config({
|
|
1381
1343
|
name: "fabdeh/unicorn/rules",
|
|
1382
1344
|
plugins: { unicorn: unicornPlugin },
|
|
1345
|
+
files: [GLOB_SRC],
|
|
1383
1346
|
rules: {
|
|
1384
|
-
...options.allRecommended ? unicornPlugin.configs
|
|
1347
|
+
...options.allRecommended ? unicornPlugin.configs.recommended.rules : {
|
|
1385
1348
|
"unicorn/catch-error-name": "error",
|
|
1349
|
+
"unicorn/consistent-date-clone": "error",
|
|
1386
1350
|
"unicorn/consistent-empty-array-spread": "error",
|
|
1387
1351
|
"unicorn/consistent-existence-index-check": "error",
|
|
1388
1352
|
"unicorn/consistent-function-scoping": ["error", { checkArrowFunctions: false }],
|
|
@@ -1404,7 +1368,7 @@ function unicorn(options = {}) {
|
|
|
1404
1368
|
"unicorn/no-empty-file": "error",
|
|
1405
1369
|
"unicorn/no-for-loop": "error",
|
|
1406
1370
|
"unicorn/no-hex-escape": "error",
|
|
1407
|
-
"unicorn/no-instanceof-
|
|
1371
|
+
"unicorn/no-instanceof-builtins": "error",
|
|
1408
1372
|
"unicorn/no-invalid-fetch-options": "error",
|
|
1409
1373
|
"unicorn/no-invalid-remove-event-listener": "error",
|
|
1410
1374
|
"unicorn/no-length-as-slice-end": "error",
|
|
@@ -1483,12 +1447,16 @@ async function vitest(options = {}) {
|
|
|
1483
1447
|
} = options;
|
|
1484
1448
|
const [vitestPlugin, jestDomPlugin, testingLibraryPlugin] = await Promise.all([
|
|
1485
1449
|
interopDefault(import('@vitest/eslint-plugin')),
|
|
1486
|
-
useJestDom ? interopDefault(import('eslint-plugin-jest-dom')) : Promise.resolve(
|
|
1487
|
-
useTestingLibrary ? interopDefault(import('eslint-plugin-testing-library')) : Promise.resolve(
|
|
1450
|
+
useJestDom ? interopDefault(import('eslint-plugin-jest-dom')) : Promise.resolve(void 0),
|
|
1451
|
+
useTestingLibrary ? interopDefault(import('eslint-plugin-testing-library')) : Promise.resolve(void 0)
|
|
1488
1452
|
]);
|
|
1489
1453
|
return tseslint.config({
|
|
1490
1454
|
name: "fabdeh/vitest/rules",
|
|
1491
|
-
plugins: {
|
|
1455
|
+
plugins: {
|
|
1456
|
+
vitest: vitestPlugin,
|
|
1457
|
+
...jestDomPlugin ? { "jest-dom": jestDomPlugin } : {},
|
|
1458
|
+
...testingLibraryPlugin ? { "testing-library": testingLibraryPlugin } : {}
|
|
1459
|
+
},
|
|
1492
1460
|
languageOptions: {
|
|
1493
1461
|
globals: {
|
|
1494
1462
|
...globals.node,
|
|
@@ -1502,12 +1470,10 @@ async function vitest(options = {}) {
|
|
|
1502
1470
|
}
|
|
1503
1471
|
},
|
|
1504
1472
|
files: [...GLOB_TESTS],
|
|
1505
|
-
extends: [
|
|
1506
|
-
vitestPlugin.configs.recommended,
|
|
1507
|
-
...jestDomPlugin ? [jestDomPlugin.configs["flat/recommended"]] : [],
|
|
1508
|
-
...testingLibraryPlugin ? [testingLibraryPlugin.configs["flat/angular"]] : []
|
|
1509
|
-
],
|
|
1510
1473
|
rules: {
|
|
1474
|
+
...vitestPlugin.configs.recommended.rules,
|
|
1475
|
+
...jestDomPlugin?.configs["flat/recommended"].rules,
|
|
1476
|
+
...testingLibraryPlugin?.configs["flat/angular"].rules,
|
|
1511
1477
|
"max-classes-per-file": "off",
|
|
1512
1478
|
"max-lines": "off",
|
|
1513
1479
|
"@typescript-eslint/consistent-type-assertions": "off",
|
|
@@ -1598,9 +1564,7 @@ function mergePrettierOptions(options, overrides = {}) {
|
|
|
1598
1564
|
...options,
|
|
1599
1565
|
...overrides,
|
|
1600
1566
|
plugins: [
|
|
1601
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1602
1567
|
...overrides.plugins ?? [],
|
|
1603
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1604
1568
|
...options.plugins ?? []
|
|
1605
1569
|
]
|
|
1606
1570
|
};
|
|
@@ -1620,8 +1584,8 @@ async function formatters(options = {}, stylistic = {}) {
|
|
|
1620
1584
|
}
|
|
1621
1585
|
await ensurePackages([
|
|
1622
1586
|
"eslint-plugin-format",
|
|
1623
|
-
options.markdown && options.slidev ? "prettier-plugin-slidev" :
|
|
1624
|
-
options.xml || options.svg ? "@prettier/plugin-xml" :
|
|
1587
|
+
options.markdown && options.slidev ? "prettier-plugin-slidev" : void 0,
|
|
1588
|
+
options.xml || options.svg ? "@prettier/plugin-xml" : void 0
|
|
1625
1589
|
]);
|
|
1626
1590
|
const {
|
|
1627
1591
|
indent,
|
|
@@ -1822,23 +1786,11 @@ async function createConfig(options = {}, ...userConfigs) {
|
|
|
1822
1786
|
const {
|
|
1823
1787
|
angular: enableAngular = isPackageExists("@angular/core"),
|
|
1824
1788
|
gitignore: enableGitignore = true,
|
|
1825
|
-
isInEditor = isInEditorEnv(),
|
|
1826
|
-
jest: enableJest = isPackageExists("jest"),
|
|
1827
1789
|
ngrx: enableNgrx = NGRX_PACKAGES.some((p) => isPackageExists(p)),
|
|
1828
1790
|
tailwindcss: enableTailwind = isPackageExists("tailwindcss"),
|
|
1829
1791
|
unicorn: enableUnicorn = true,
|
|
1830
1792
|
vitest: enableVitest = isPackageExists("vitest")
|
|
1831
1793
|
} = options;
|
|
1832
|
-
if (isInEditor) {
|
|
1833
|
-
console.log(
|
|
1834
|
-
"[@fabdeh/eslint-config] Detected running in editor, some rules are configured as warn or completely turned off."
|
|
1835
|
-
);
|
|
1836
|
-
}
|
|
1837
|
-
if (enableJest && enableVitest) {
|
|
1838
|
-
throw new Error(
|
|
1839
|
-
'[@fabdeh/eslint-config] Detected that both "jest" and "vitest" are enabled which is not supported. Manually disable or uninstall one of them.'
|
|
1840
|
-
);
|
|
1841
|
-
}
|
|
1842
1794
|
const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
|
|
1843
1795
|
const configs = [];
|
|
1844
1796
|
if (enableGitignore) {
|
|
@@ -1856,10 +1808,9 @@ async function createConfig(options = {}, ...userConfigs) {
|
|
|
1856
1808
|
);
|
|
1857
1809
|
}
|
|
1858
1810
|
}
|
|
1859
|
-
const allowAngularDecorator = options.angular !== false;
|
|
1860
1811
|
configs.push(
|
|
1861
1812
|
ignores(options.ignores),
|
|
1862
|
-
javascript({
|
|
1813
|
+
javascript({ overrides: options.javascript?.overrides }),
|
|
1863
1814
|
typescript({
|
|
1864
1815
|
stylistic: stylisticOptions,
|
|
1865
1816
|
parserOptions: options.typescript?.parserOptions,
|
|
@@ -1882,13 +1833,6 @@ async function createConfig(options = {}, ...userConfigs) {
|
|
|
1882
1833
|
if (enableNgrx) {
|
|
1883
1834
|
configs.push(ngrx(typeof enableNgrx === "object" ? enableNgrx : {}));
|
|
1884
1835
|
}
|
|
1885
|
-
if (enableJest) {
|
|
1886
|
-
configs.push(
|
|
1887
|
-
jest(
|
|
1888
|
-
typeof enableJest === "object" ? { ...enableJest, stylistic: stylisticOptions } : { stylistic: stylisticOptions }
|
|
1889
|
-
)
|
|
1890
|
-
);
|
|
1891
|
-
}
|
|
1892
1836
|
if (enableVitest) {
|
|
1893
1837
|
configs.push(vitest(typeof enableVitest === "object" ? enableVitest : {}));
|
|
1894
1838
|
}
|
|
@@ -1937,4 +1881,4 @@ async function createConfig(options = {}, ...userConfigs) {
|
|
|
1937
1881
|
return tseslint.config(...await Promise.all(configs), ...await Promise.all(userConfigs));
|
|
1938
1882
|
}
|
|
1939
1883
|
|
|
1940
|
-
export { GLOB_HTML, GLOB_JS, GLOB_SRC, GLOB_TESTS, GLOB_TS, STYLISTIC_CONFIG_DEFAULT, angular, comments, createConfig, ensurePackages, getWorkspaceRoot, ignores, imports, interopDefault,
|
|
1884
|
+
export { GLOB_HTML, GLOB_JS, GLOB_SRC, GLOB_TESTS, GLOB_TS, STYLISTIC_CONFIG_DEFAULT, angular, comments, createConfig, ensurePackages, findNearestPackageJsonName, getWorkspaceRoot, ignores, imports, interopDefault, isPackageInScope, javascript, jsdoc, jsonc, markdown, ngrx, perfectionist, sortPackageJson, sortTsConfig, stylistic, tailwindcss, toml, typescript, unicorn, vitest, yaml };
|