@fabdeh/eslint-config 0.1.3 → 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/dist/index.cjs DELETED
@@ -1,1988 +0,0 @@
1
- 'use strict';
2
-
3
- const tseslint = require('typescript-eslint');
4
- const node_fs = require('node:fs');
5
- const promises = require('node:fs/promises');
6
- const node_path = require('node:path');
7
- const process = require('node:process');
8
- const node_url = require('node:url');
9
- const localPkg = require('local-pkg');
10
- const eslintComments = require('@eslint-community/eslint-plugin-eslint-comments');
11
- const importX = require('eslint-plugin-import-x');
12
- const eslint = require('@eslint/js');
13
- const preferArrowFunctions = require('eslint-plugin-prefer-arrow-functions');
14
- const unusedImports = require('eslint-plugin-unused-imports');
15
- const globals = require('globals');
16
- const jsdocPlugin = require('eslint-plugin-jsdoc');
17
- const eslintMergeProcessors = require('eslint-merge-processors');
18
- const perfectionistPlugin = require('eslint-plugin-perfectionist');
19
- const unicornPlugin = require('eslint-plugin-unicorn');
20
-
21
- var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
22
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
23
-
24
- function _interopNamespaceCompat(e) {
25
- if (e && typeof e === 'object' && 'default' in e) return e;
26
- const n = Object.create(null);
27
- if (e) {
28
- for (const k in e) {
29
- n[k] = e[k];
30
- }
31
- }
32
- n.default = e;
33
- return n;
34
- }
35
-
36
- const tseslint__default = /*#__PURE__*/_interopDefaultCompat(tseslint);
37
- const process__default = /*#__PURE__*/_interopDefaultCompat(process);
38
- const eslintComments__default = /*#__PURE__*/_interopDefaultCompat(eslintComments);
39
- const importX__namespace = /*#__PURE__*/_interopNamespaceCompat(importX);
40
- const eslint__default = /*#__PURE__*/_interopDefaultCompat(eslint);
41
- const preferArrowFunctions__default = /*#__PURE__*/_interopDefaultCompat(preferArrowFunctions);
42
- const unusedImports__default = /*#__PURE__*/_interopDefaultCompat(unusedImports);
43
- const globals__default = /*#__PURE__*/_interopDefaultCompat(globals);
44
- const jsdocPlugin__default = /*#__PURE__*/_interopDefaultCompat(jsdocPlugin);
45
- const perfectionistPlugin__default = /*#__PURE__*/_interopDefaultCompat(perfectionistPlugin);
46
- const unicornPlugin__default = /*#__PURE__*/_interopDefaultCompat(unicornPlugin);
47
-
48
- const GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
49
- const GLOB_SRC = `**/*.${GLOB_SRC_EXT}`;
50
- const GLOB_JS = "**/*.?([cm])js?(x)";
51
- const GLOB_TS_EXT = "?([cm])ts?(x)";
52
- const GLOB_TS = `**/*.${GLOB_TS_EXT}`;
53
- const GLOB_CSS = "**/*.css";
54
- const GLOB_POSTCSS = "**/*.{p,post}css";
55
- const GLOB_LESS = "**/*.less";
56
- const GLOB_SCSS = "**/*.scss";
57
- const GLOB_JSON = "**/*.json";
58
- const GLOB_JSON5 = "**/*.json5";
59
- const GLOB_JSONC = "**/*.jsonc";
60
- const GLOB_MARKDOWN = "**/*.md";
61
- const GLOB_MARKDOWN_IN_MARKDOWN = "**/*.md/*.md";
62
- const GLOB_MARKDOWN_CODE = `${GLOB_MARKDOWN}/${GLOB_SRC}`;
63
- const GLOB_YAML = "**/*.y?(a)ml";
64
- const GLOB_TOML = "**/*.toml";
65
- const GLOB_XML = "**/*.xml";
66
- const GLOB_SVG = "**/*.svg";
67
- const GLOB_GRAPHQL = "**/*.{g,graph}ql";
68
- const GLOB_HTML = "**/*.htm?(l)";
69
- const GLOB_TESTS = [`**/*.spec.${GLOB_SRC_EXT}`, `**/*.test.${GLOB_SRC_EXT}`, `**/test-setup.${GLOB_SRC_EXT}`];
70
- const GLOB_EXCLUDE = [
71
- "**/node_modules",
72
- "**/dist",
73
- "**/package-lock.json",
74
- "**/yarn.lock",
75
- "**/pnpm-lock.yaml",
76
- "**/bun.lockb",
77
- "**/output",
78
- "**/coverage",
79
- "**/temp",
80
- "**/.temp",
81
- "**/tmp",
82
- "**/.tmp",
83
- "**/.history",
84
- "**/.vitepress/cache",
85
- "**/.nuxt",
86
- "**/.next",
87
- "**/.svelte-kit",
88
- "**/.vercel",
89
- "**/.changeset",
90
- "**/.idea",
91
- "**/.cache",
92
- "**/.output",
93
- "**/.tsup",
94
- "**/.vite-inspect",
95
- "**/.yarn",
96
- "**/vite.config.*.timestamp-*",
97
- "**/CHANGELOG*.md",
98
- "**/*.min.*",
99
- "**/LICENSE*",
100
- "**/__snapshots__",
101
- "**/auto-import?(s).d.ts",
102
- "**/components.d.ts",
103
- "**/prettier-types.ts"
104
- ];
105
-
106
- const SCOPE_URL = node_url.fileURLToPath(new URL(".", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
107
- const IS_CWD_IN_SCOPE = localPkg.isPackageExists("@fabdeh/eslint-config");
108
- function isInEditorEnv() {
109
- if (process__default.env.CI) {
110
- return false;
111
- }
112
- const envKeys = Object.keys(process__default.env);
113
- if (envKeys.some((k) => /^GIT_/i.test(k))) {
114
- return false;
115
- }
116
- const isVsCode = envKeys.some((k) => /^VSCODE_/i.test(k));
117
- const isIntelliJ = envKeys.some((k) => /^INTELLIJ_/i.test(k));
118
- const isJetbrains = envKeys.some((k) => /^JETBRAINS_/i.test(k));
119
- const isVim = envKeys.some((k) => /^VIM$/i.test(k));
120
- const isNeoVim = envKeys.some((k) => /^NVIM$/i.test(k));
121
- return isVsCode || isIntelliJ || isJetbrains || isVim || isNeoVim;
122
- }
123
- function toArray(value) {
124
- return Array.isArray(value) ? value : [value];
125
- }
126
- async function interopDefault(m) {
127
- const resolved = await m;
128
- return resolved.default ?? resolved;
129
- }
130
- function fileExists(path) {
131
- try {
132
- return node_fs.statSync(path).isFile();
133
- } catch {
134
- return false;
135
- }
136
- }
137
- function getWorkspaceRoot(dir, candidateRoot) {
138
- if (process__default.env.NX_WORKSPACE_ROOT_PATH) {
139
- return process__default.env.NX_WORKSPACE_ROOT_PATH;
140
- }
141
- if (node_path.dirname(dir) === dir) {
142
- return candidateRoot;
143
- }
144
- const matches = [node_path.join(dir, "nx.json"), node_path.join(dir, "nx"), node_path.join(dir, "nx.bat")];
145
- if (matches.some((x) => fileExists(x))) {
146
- return dir;
147
- } else if (fileExists(node_path.join(dir, "node_modules", "nx", "package.json"))) {
148
- return getWorkspaceRoot(node_path.dirname(dir), dir);
149
- } else {
150
- return getWorkspaceRoot(node_path.dirname(dir), candidateRoot);
151
- }
152
- }
153
- function isPackageInScope(name) {
154
- return localPkg.isPackageExists(name, { paths: [SCOPE_URL] });
155
- }
156
- async function ensurePackages(packages) {
157
- if (process__default.env.CI || !process__default.stdout.isTTY || !IS_CWD_IN_SCOPE) {
158
- return;
159
- }
160
- const nonExistingPackages = packages.filter((i) => i && !isPackageInScope(i));
161
- if (nonExistingPackages.length === 0) {
162
- return;
163
- }
164
- const p = await import('@clack/prompts');
165
- const result = await p.confirm({
166
- message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?`
167
- });
168
- if (result) {
169
- await import('@antfu/install-pkg').then((i) => i.installPackage(nonExistingPackages, { dev: true }));
170
- }
171
- }
172
- async function findNearestPackageJsonName(directoryPath = node_path.resolve()) {
173
- try {
174
- const packageJsonPath = node_path.join(directoryPath, "package.json");
175
- const packageJsonData = JSON.parse(await promises.readFile(packageJsonPath, "utf8"));
176
- return packageJsonData.name;
177
- } catch {
178
- const parentDir = node_path.dirname(directoryPath);
179
- if (directoryPath === parentDir) {
180
- throw new Error("No package.json file found.");
181
- }
182
- return findNearestPackageJsonName(parentDir);
183
- }
184
- }
185
-
186
- async function angular(options = {}) {
187
- const angularEslint = await interopDefault(import('angular-eslint'));
188
- const { enableAccessibilityRules = true, tsOverrides = {}, htmlOverrides = {}, prefix = "app" } = options;
189
- return tseslint__default.config(
190
- {
191
- name: "fabdeh/angular/rules",
192
- plugins: {
193
- "@angular-eslint": angularEslint.tsPlugin
194
- },
195
- processor: angularEslint.processInlineTemplates,
196
- files: [GLOB_TS],
197
- extends: [angularEslint.configs.tsRecommended],
198
- rules: {
199
- "max-classes-per-file": ["error", 1],
200
- "max-lines": ["error", 400],
201
- "@angular-eslint/component-max-inline-declarations": "error",
202
- "@angular-eslint/component-selector": [
203
- "error",
204
- {
205
- type: "element",
206
- prefix,
207
- style: "kebab-case"
208
- }
209
- ],
210
- "@angular-eslint/contextual-decorator": "error",
211
- "@angular-eslint/directive-selector": [
212
- "error",
213
- {
214
- type: "attribute",
215
- prefix,
216
- style: "camelCase"
217
- }
218
- ],
219
- "@angular-eslint/no-async-lifecycle-method": "error",
220
- "@angular-eslint/no-attribute-decorator": "error",
221
- "@angular-eslint/no-conflicting-lifecycle": "error",
222
- "@angular-eslint/no-duplicates-in-metadata-arrays": "error",
223
- "@angular-eslint/no-forward-ref": "error",
224
- "@angular-eslint/no-lifecycle-call": "error",
225
- "@angular-eslint/no-pipe-impure": "error",
226
- "@angular-eslint/no-queries-metadata-property": "error",
227
- "@angular-eslint/prefer-output-readonly": "error",
228
- "@angular-eslint/prefer-signals": "error",
229
- "@angular-eslint/relative-url-prefix": "error",
230
- "@angular-eslint/sort-lifecycle-methods": "error",
231
- "@angular-eslint/use-component-selector": "error",
232
- "@angular-eslint/use-component-view-encapsulation": "error",
233
- "@angular-eslint/use-lifecycle-interface": "error",
234
- ...tsOverrides
235
- }
236
- },
237
- {
238
- name: "fabdeh/angular-template/rules",
239
- plugins: {
240
- "@angular-eslint": angularEslint.tsPlugin
241
- },
242
- files: [GLOB_HTML],
243
- extends: [
244
- ...angularEslint.configs.templateRecommended,
245
- ...enableAccessibilityRules ? angularEslint.configs.templateAccessibility : []
246
- ],
247
- rules: {
248
- "@angular-eslint/template/attributes-order": ["error", { alphabetical: true }],
249
- "@angular-eslint/template/button-has-type": "error",
250
- "@angular-eslint/template/conditional-complexity": "error",
251
- "@angular-eslint/template/eqeqeq": ["error", { allowNullOrUndefined: true }],
252
- "@angular-eslint/template/no-any": "error",
253
- "@angular-eslint/template/no-duplicate-attributes": "error",
254
- "@angular-eslint/template/no-interpolation-in-attributes": "error",
255
- "@angular-eslint/template/no-positive-tabindex": "error",
256
- "@angular-eslint/template/prefer-control-flow": "error",
257
- "@angular-eslint/template/prefer-ngsrc": "error",
258
- "@angular-eslint/template/prefer-self-closing-tags": "error",
259
- ...htmlOverrides
260
- }
261
- }
262
- );
263
- }
264
-
265
- function comments() {
266
- return tseslint__default.config({
267
- name: "fabdeh/comments/rules",
268
- files: [GLOB_SRC],
269
- plugins: {
270
- "@eslint-community/eslint-comments": eslintComments__default
271
- },
272
- rules: {
273
- "@eslint-community/eslint-comments/disable-enable-pair": ["error", { allowWholeFile: true }],
274
- "@eslint-community/eslint-comments/no-aggregating-enable": "error",
275
- "@eslint-community/eslint-comments/no-duplicate-disable": "error",
276
- "@eslint-community/eslint-comments/no-unlimited-disable": "error",
277
- "@eslint-community/eslint-comments/no-unused-disable": "error",
278
- "@eslint-community/eslint-comments/no-unused-enable": "error"
279
- }
280
- });
281
- }
282
-
283
- function ignores(userIgnores = []) {
284
- return tseslint__default.config({
285
- name: "fabdeh/ignores",
286
- ignores: [...GLOB_EXCLUDE, ...userIgnores]
287
- });
288
- }
289
-
290
- function imports(options = {}) {
291
- const { stylistic = true } = options;
292
- return tseslint__default.config(
293
- {
294
- name: "fabdeh/imports/common/rules",
295
- files: [GLOB_SRC],
296
- plugins: {
297
- "import-x": importX__namespace
298
- },
299
- rules: {
300
- "import-x/consistent-type-specifier-style": ["error", "prefer-top-level"],
301
- "import-x/default": "error",
302
- "import-x/export": "error",
303
- "import-x/first": "error",
304
- "import-x/no-absolute-path": "error",
305
- "import-x/no-duplicates": "error",
306
- "import-x/no-empty-named-blocks": "error",
307
- "import-x/no-extraneous-dependencies": "error",
308
- "import-x/no-mutable-exports": "error",
309
- "import-x/no-named-as-default": "warn",
310
- "import-x/no-named-as-default-member": "warn",
311
- "import-x/no-named-default": "error",
312
- "import-x/no-self-import": "error",
313
- "import-x/no-useless-path-segments": "error",
314
- "import-x/no-webpack-loader-syntax": "error",
315
- ...stylistic ? {
316
- "import-x/newline-after-import": ["error", { considerComments: true, count: 1 }]
317
- } : {}
318
- }
319
- },
320
- {
321
- name: "fabdeh/imports/js-only/rules",
322
- files: [GLOB_JS],
323
- rules: {
324
- "import-x/named": "error",
325
- "import-x/no-deprecated": "error"
326
- }
327
- },
328
- {
329
- name: "fabdeh/imports/ts-only/rules",
330
- files: [GLOB_TS],
331
- rules: {
332
- "import-x/named": "off",
333
- "import-x/no-deprecated": "off"
334
- }
335
- }
336
- );
337
- }
338
-
339
- function javascript(options = {}) {
340
- const { isInEditor = false, overrides = {}, allowAngularDecorator = false } = options;
341
- return tseslint__default.config(
342
- {
343
- name: "fabdeh/javascript/setup",
344
- languageOptions: {
345
- ecmaVersion: 2022,
346
- globals: {
347
- ...globals__default.browser,
348
- ...globals__default.es2021,
349
- ...globals__default.node,
350
- document: "readonly",
351
- navigator: "readonly",
352
- window: "readonly"
353
- },
354
- parser: tseslint__default.parser,
355
- parserOptions: {
356
- ecmaFeatures: {
357
- jsx: true
358
- },
359
- ecmaVersion: 2022,
360
- sourceType: "module"
361
- },
362
- sourceType: "module"
363
- },
364
- linterOptions: {
365
- reportUnusedDisableDirectives: "error"
366
- }
367
- },
368
- {
369
- name: "fabdeh/javascript/rules",
370
- files: [GLOB_SRC],
371
- plugins: {
372
- "@typescript-eslint": tseslint__default.plugin,
373
- "prefer-arrow-functions": preferArrowFunctions__default,
374
- "unused-imports": unusedImports__default
375
- },
376
- extends: [eslint__default.configs.recommended, ...tseslint__default.configs.recommended],
377
- rules: {
378
- "accessor-pairs": "error",
379
- "array-callback-return": "error",
380
- "block-scoped-var": "error",
381
- "default-case-last": "error",
382
- "dot-notation": "error",
383
- eqeqeq: "error",
384
- "id-denylist": [
385
- "error",
386
- "any",
387
- "Number",
388
- "number",
389
- "String",
390
- "string",
391
- "Boolean",
392
- "boolean",
393
- "Undefined",
394
- "undefined"
395
- ],
396
- "new-cap": allowAngularDecorator ? [
397
- "error",
398
- {
399
- capIsNewExceptions: [
400
- "Attribute",
401
- "Component",
402
- "ContentChild",
403
- "ContentChildren",
404
- "Directive",
405
- "Host",
406
- "HostBinding",
407
- "HostListener",
408
- "Inject",
409
- "Injectable",
410
- "Input",
411
- "NgModule",
412
- "Optional",
413
- "Output",
414
- "Pipe",
415
- "Self",
416
- "SkipSelf",
417
- "ViewChild",
418
- "ViewChildren"
419
- ]
420
- }
421
- ] : "error",
422
- "no-alert": "error",
423
- "no-caller": "error",
424
- "no-cond-assign": ["error", "always"],
425
- "no-console": ["error", { allow: ["warn", "error"] }],
426
- "no-empty": ["error", { allowEmptyCatch: true }],
427
- "no-eval": "error",
428
- "no-extend-native": "error",
429
- "no-extra-bind": "error",
430
- "no-implied-eval": "error",
431
- "no-iterator": "error",
432
- "no-labels": "error",
433
- "no-lone-blocks": "error",
434
- "no-lonely-if": "error",
435
- "no-multi-str": "error",
436
- "no-new": "error",
437
- "no-new-func": "error",
438
- "no-new-wrappers": "error",
439
- "no-octal-escape": "error",
440
- "no-plusplus": ["error", { allowForLoopAfterthoughts: true }],
441
- "no-proto": "error",
442
- "no-restricted-syntax": ["error", "TSEnumDeclaration[const=true]", "TSExportAssignment", "ForInStatement"],
443
- "no-self-compare": "error",
444
- "no-sequences": "error",
445
- "no-template-curly-in-string": "error",
446
- "no-throw-literal": "error",
447
- "no-undef-init": "error",
448
- "no-unmodified-loop-condition": "error",
449
- "no-unneeded-ternary": ["error", { defaultAssignment: false }],
450
- "no-unreachable-loop": "error",
451
- "no-unused-expressions": [
452
- "error",
453
- {
454
- allowShortCircuit: true,
455
- allowTaggedTemplates: true,
456
- allowTernary: true
457
- }
458
- ],
459
- "no-use-before-define": ["error", { classes: false, functions: false }],
460
- "no-useless-call": "error",
461
- "no-useless-computed-key": "error",
462
- "no-useless-constructor": "error",
463
- "no-useless-rename": "error",
464
- "no-useless-return": "error",
465
- "object-shorthand": [
466
- "error",
467
- "always",
468
- {
469
- avoidQuotes: true,
470
- ignoreConstructors: false
471
- }
472
- ],
473
- "prefer-arrow-callback": "error",
474
- "prefer-arrow-functions/prefer-arrow-functions": [
475
- "error",
476
- { singleReturnOnly: true, allowNamedFunctions: true }
477
- ],
478
- "prefer-exponentiation-operator": "error",
479
- "prefer-object-spread": "error",
480
- "prefer-promise-reject-errors": "error",
481
- "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
482
- "prefer-template": "error",
483
- "symbol-description": "error",
484
- "unicode-bom": ["error", "never"],
485
- "unused-imports/no-unused-imports": isInEditor ? "warn" : "error",
486
- "unused-imports/no-unused-vars": [
487
- "error",
488
- {
489
- args: "after-used",
490
- argsIgnorePattern: "^_",
491
- ignoreRestSiblings: true,
492
- vars: "all",
493
- varsIgnorePattern: "^_"
494
- }
495
- ],
496
- "use-isnan": ["error", { enforceForIndexOf: true }],
497
- "valid-typeof": ["error", { requireStringLiterals: true }],
498
- "vars-on-top": "error",
499
- yoda: ["error", "never", { exceptRange: true }],
500
- "@typescript-eslint/no-unused-vars": "off",
501
- // superseded by unused-imports/no-unused-vars
502
- // TODO: check if required to apply more nx javascript rules here
503
- ...overrides
504
- }
505
- }
506
- );
507
- }
508
-
509
- async function jest(options = {}) {
510
- const {
511
- overrides = {},
512
- useJestDom = localPkg.isPackageExists("@testing-library/jest-dom"),
513
- useTestingLibrary = localPkg.isPackageExists("@testing-library/angular"),
514
- stylistic = true
515
- } = options;
516
- const [jestPlugin, jestDomPlugin, testingLibraryPlugin] = await Promise.all([
517
- interopDefault(import('eslint-plugin-jest')),
518
- useJestDom ? interopDefault(import('eslint-plugin-jest-dom')) : Promise.resolve(undefined),
519
- useTestingLibrary ? interopDefault(import('eslint-plugin-testing-library')) : Promise.resolve(undefined)
520
- ]);
521
- return tseslint__default.config({
522
- name: "fabdeh/jest/rules",
523
- plugins: {
524
- jest: jestPlugin
525
- },
526
- languageOptions: {
527
- globals: {
528
- ...globals__default.node,
529
- ...globals__default.jest
530
- }
531
- },
532
- files: [...GLOB_TESTS, `** /jest.config.${GLOB_SRC_EXT}`],
533
- extends: [
534
- jestPlugin.configs["flat/recommended"],
535
- ...stylistic ? [jestPlugin.configs["flat/style"]] : [],
536
- ...jestDomPlugin ? [jestDomPlugin.configs["flat/recommended"]] : [],
537
- ...testingLibraryPlugin ? [testingLibraryPlugin.configs["flat/angular"]] : []
538
- ],
539
- rules: {
540
- "max-classes-per-file": "off",
541
- "max-lines": "off",
542
- "@typescript-eslint/consistent-type-assertions": "off",
543
- "@typescript-eslint/no-empty-function": "off",
544
- "@typescript-eslint/no-unsafe-assignment": "off",
545
- "@typescript-eslint/no-unsafe-call": "off",
546
- "@typescript-eslint/no-unsafe-member-access": "off",
547
- "@typescript-eslint/unbound-method": "off",
548
- "jest/consistent-test-it": ["error", { fn: "test" }],
549
- "jest/prefer-spy-on": "error",
550
- "jest/require-top-level-describe": "error",
551
- "jest/unbound-method": "error",
552
- "unicorn/no-null": "off",
553
- ...overrides
554
- }
555
- });
556
- }
557
-
558
- function jsdoc(options = {}) {
559
- const { stylistic = true } = options;
560
- return tseslint__default.config(
561
- {
562
- name: "fabdeh/jsdoc/rules",
563
- files: [GLOB_SRC],
564
- plugins: { jsdoc: jsdocPlugin__default },
565
- rules: {
566
- "jsdoc/check-access": "warn",
567
- "jsdoc/check-param-names": "warn",
568
- "jsdoc/check-property-names": "warn",
569
- "jsdoc/check-tag-names": "warn",
570
- "jsdoc/check-types": "warn",
571
- "jsdoc/check-values": "warn",
572
- "jsdoc/empty-tags": "warn",
573
- "jsdoc/implements-on-classes": "warn",
574
- "jsdoc/no-defaults": "warn",
575
- "jsdoc/no-multi-asterisks": "warn",
576
- "jsdoc/no-undefined-types": "warn",
577
- "jsdoc/require-jsdoc": "warn",
578
- "jsdoc/require-param": "warn",
579
- "jsdoc/require-param-description": "warn",
580
- "jsdoc/require-param-name": "warn",
581
- "jsdoc/require-param-type": "warn",
582
- "jsdoc/require-property": "warn",
583
- "jsdoc/require-property-description": "warn",
584
- "jsdoc/require-property-name": "warn",
585
- "jsdoc/require-property-type": "warn",
586
- "jsdoc/require-returns": "warn",
587
- "jsdoc/require-returns-check": "warn",
588
- "jsdoc/require-returns-description": "warn",
589
- "jsdoc/require-returns-type": "warn",
590
- "jsdoc/require-yields": "warn",
591
- "jsdoc/require-yields-check": "warn",
592
- "jsdoc/tag-lines": ["warn", "never", { startLines: 1 }],
593
- "jsdoc/valid-types": "warn",
594
- ...stylistic ? {
595
- "jsdoc/check-alignment": "warn",
596
- "jsdoc/multiline-blocks": "warn"
597
- } : {}
598
- }
599
- },
600
- {
601
- name: "fabdeh/jsdoc/ts-only/rules",
602
- files: [GLOB_TS],
603
- rules: {
604
- "jsdoc/check-tag-names": ["warn", { typed: true }],
605
- "jsdoc/no-types": "warn",
606
- "jsdoc/no-undefined-types": "off",
607
- "jsdoc/require-param-type": "off",
608
- "jsdoc/require-property-type": "off",
609
- "jsdoc/require-returns-type": "off"
610
- }
611
- }
612
- );
613
- }
614
-
615
- async function jsonc(options = {}) {
616
- const {
617
- files = [GLOB_JSON, GLOB_JSON5, GLOB_JSONC],
618
- overrides = {},
619
- stylistic = true
620
- } = options;
621
- const { indent = 2 } = typeof stylistic === "object" ? stylistic : {};
622
- const [jsoncPlugin, jsoncParser] = await Promise.all([
623
- interopDefault(import('eslint-plugin-jsonc')),
624
- interopDefault(import('jsonc-eslint-parser'))
625
- ]);
626
- return tseslint__default.config(
627
- {
628
- name: "fabdeh/jsonc/setup",
629
- plugins: {
630
- jsonc: jsoncPlugin
631
- }
632
- },
633
- {
634
- name: "fabdeh/jsonc/rules",
635
- languageOptions: {
636
- parser: jsoncParser
637
- },
638
- files,
639
- rules: {
640
- "jsonc/no-bigint-literals": "error",
641
- "jsonc/no-binary-expression": "error",
642
- "jsonc/no-binary-numeric-literals": "error",
643
- "jsonc/no-dupe-keys": "error",
644
- "jsonc/no-escape-sequence-in-identifier": "error",
645
- "jsonc/no-floating-decimal": "error",
646
- "jsonc/no-hexadecimal-numeric-literals": "error",
647
- "jsonc/no-infinity": "error",
648
- "jsonc/no-multi-str": "error",
649
- "jsonc/no-nan": "error",
650
- "jsonc/no-number-props": "error",
651
- "jsonc/no-numeric-separators": "error",
652
- "jsonc/no-octal": "error",
653
- "jsonc/no-octal-escape": "error",
654
- "jsonc/no-octal-numeric-literals": "error",
655
- "jsonc/no-parenthesized": "error",
656
- "jsonc/no-plus-sign": "error",
657
- "jsonc/no-regexp-literals": "error",
658
- "jsonc/no-sparse-arrays": "error",
659
- "jsonc/no-template-literals": "error",
660
- "jsonc/no-undefined-value": "error",
661
- "jsonc/no-unicode-codepoint-escapes": "error",
662
- "jsonc/no-useless-escape": "error",
663
- "jsonc/space-unary-ops": "error",
664
- "jsonc/valid-json-number": "error",
665
- "jsonc/vue-custom-block/no-parsing-error": "error",
666
- ...stylistic ? {
667
- "jsonc/array-bracket-spacing": ["error", "never"],
668
- "jsonc/comma-dangle": ["error", "never"],
669
- "jsonc/comma-style": ["error", "last"],
670
- "jsonc/indent": ["error", indent],
671
- "jsonc/key-spacing": ["error", { afterColon: true, beforeColon: false }],
672
- "jsonc/object-curly-newline": ["error", { consistent: true, multiline: true }],
673
- "jsonc/object-curly-spacing": ["error", "always"],
674
- "jsonc/object-property-newline": ["error", { allowMultiplePropertiesPerLine: true }],
675
- "jsonc/quote-props": "error",
676
- "jsonc/quotes": "error"
677
- } : {},
678
- ...overrides
679
- }
680
- }
681
- );
682
- }
683
-
684
- async function markdown(options = {}) {
685
- const {
686
- files = [GLOB_MARKDOWN],
687
- overrides = {}
688
- } = options;
689
- const markdownPlugin = await interopDefault(import('@eslint/markdown'));
690
- return tseslint__default.config(
691
- {
692
- name: "fabdeh/markdown/setup",
693
- plugins: {
694
- markdown: markdownPlugin
695
- }
696
- },
697
- {
698
- name: "fabdeh/markdown/processor",
699
- files,
700
- ignores: [GLOB_MARKDOWN_IN_MARKDOWN],
701
- processor: eslintMergeProcessors.mergeProcessors([
702
- markdownPlugin.processors.markdown,
703
- eslintMergeProcessors.processorPassThrough
704
- ])
705
- },
706
- {
707
- name: "fabdeh/markdown/disables",
708
- languageOptions: {
709
- parserOptions: {
710
- ecmaFeatures: {
711
- impliedStrict: true
712
- }
713
- }
714
- },
715
- files: [GLOB_MARKDOWN_CODE],
716
- extends: [tseslint__default.configs.disableTypeChecked],
717
- rules: {
718
- "import-x/newline-after-import": "off",
719
- "no-alert": "off",
720
- "no-console": "off",
721
- "no-labels": "off",
722
- "no-lone-blocks": "off",
723
- "no-restricted-syntax": "off",
724
- "no-undef": "off",
725
- "no-unused-expressions": "off",
726
- "no-unused-labels": "off",
727
- "no-unused-vars": "off",
728
- // 'node/prefer-global/process': 'off',
729
- "@stylistic/comma-dangle": "off",
730
- "@stylistic/eol-last": "off",
731
- "@typescript-eslint/consistent-type-imports": "off",
732
- "@typescript-eslint/explicit-function-return-type": "off",
733
- "@typescript-eslint/no-namespace": "off",
734
- "@typescript-eslint/no-redeclare": "off",
735
- "@typescript-eslint/no-require-imports": "off",
736
- "@typescript-eslint/no-unused-expressions": "off",
737
- "@typescript-eslint/no-unused-vars": "off",
738
- "@typescript-eslint/no-use-before-define": "off",
739
- "unicode-bom": "off",
740
- "unused-imports/no-unused-imports": "off",
741
- "unused-imports/no-unused-vars": "off",
742
- "unicorn/filename-case": "off",
743
- ...overrides
744
- }
745
- }
746
- );
747
- }
748
-
749
- const namingConvention = [
750
- { selector: "default", format: ["camelCase"], leadingUnderscore: "forbid", trailingUnderscore: "forbid" },
751
- { selector: ["variableLike", "memberLike"], format: ["camelCase"] },
752
- // eslint-disable-next-line unicorn/no-null
753
- { selector: "memberLike", modifiers: ["requiresQuotes"], format: null },
754
- { selector: "typeLike", format: ["PascalCase"] },
755
- { selector: "variable", modifiers: ["const", "global"], format: ["UPPER_CASE"] },
756
- { selector: "enumMember", format: ["UPPER_CASE"] },
757
- { selector: "parameter", modifiers: ["unused"], format: ["camelCase"], leadingUnderscore: "allow" },
758
- { selector: "import", modifiers: ["default"], format: ["camelCase", "PascalCase"] },
759
- { selector: "import", modifiers: ["namespace"], format: ["camelCase", "PascalCase"] }
760
- ];
761
-
762
- const DEFAULT_STORE_GLOB = [
763
- `**/*.actions.${GLOB_TS_EXT}`,
764
- `**/*.feature.${GLOB_TS_EXT}`,
765
- `**/*.reducer.${GLOB_TS_EXT}`,
766
- `**/*.state.${GLOB_TS_EXT}`
767
- ];
768
- const DEFAULT_EFFECTS_GLOB = [`**/*.effects.${GLOB_TS_EXT}`];
769
- const DEFAULT_SIGNALS_GLOB = [`**/*.store.${GLOB_TS_EXT}`];
770
- async function ngrx(options = {}) {
771
- const ngrxPlugin = await interopDefault(import('@ngrx/eslint-plugin/v9'));
772
- const {
773
- store = localPkg.isPackageExists("@ngrx/store"),
774
- effects = localPkg.isPackageExists("@ngrx/effects"),
775
- signals = localPkg.isPackageExists("@ngrx/signals")
776
- } = options;
777
- const configs = [];
778
- if (store) {
779
- const {
780
- files = DEFAULT_STORE_GLOB,
781
- enforceOperatorsRules = localPkg.isPackageExists("@ngrx/operators"),
782
- overrides = {}
783
- } = typeof store === "object" ? store : {};
784
- configs.push({
785
- name: "fabdeh/ngrx-store/rules",
786
- files,
787
- extends: [...ngrxPlugin.configs.store, ...enforceOperatorsRules ? ngrxPlugin.configs.operators : []],
788
- rules: {
789
- "@typescript-eslint/naming-convention": [
790
- "error",
791
- ...namingConvention,
792
- {
793
- selector: ["objectLiteralProperty"],
794
- // eslint-disable-next-line unicorn/no-null
795
- format: null,
796
- custom: {
797
- regex: String.raw`^(?:(?:[a-z]+(?:[A-Z][a-z]*)*)|[A-Z][a-z]*(?:\s[A-Z][a-z]*)*)$`,
798
- match: true
799
- }
800
- },
801
- {
802
- selector: "variable",
803
- modifiers: ["const", "global", "exported"],
804
- format: ["camelCase", "PascalCase"],
805
- leadingUnderscore: "forbid",
806
- trailingUnderscore: "forbid"
807
- }
808
- ],
809
- ...overrides
810
- }
811
- });
812
- }
813
- if (effects) {
814
- const {
815
- files = DEFAULT_EFFECTS_GLOB,
816
- enforceOperatorsRules = localPkg.isPackageExists("@ngrx/operators"),
817
- overrides = {}
818
- } = typeof effects === "object" ? effects : {};
819
- configs.push({
820
- name: "fabdeh/ngrx-effects/rules",
821
- files,
822
- extends: [...ngrxPlugin.configs.effects, ...enforceOperatorsRules ? ngrxPlugin.configs.operators : []],
823
- rules: {
824
- "@typescript-eslint/naming-convention": [
825
- "error",
826
- ...namingConvention,
827
- {
828
- selector: "variable",
829
- modifiers: ["const", "global", "exported"],
830
- format: ["camelCase"],
831
- leadingUnderscore: "forbid",
832
- trailingUnderscore: "forbid",
833
- suffix: ["$"]
834
- }
835
- ],
836
- ...overrides
837
- }
838
- });
839
- }
840
- if (signals) {
841
- const {
842
- files = DEFAULT_SIGNALS_GLOB,
843
- enforceOperatorsRules = localPkg.isPackageExists("@ngrx/operators"),
844
- overrides = {}
845
- } = typeof signals === "object" ? signals : {};
846
- const allowLeadingUnderscoreOnMemberLike = (conventions) => [
847
- ...conventions.filter((c) => !Array.isArray(c.selector)),
848
- { selector: "variableLike", format: ["camelCase"] },
849
- { selector: "memberLike", format: ["camelCase"], leadingUnderscore: "allow" }
850
- ];
851
- configs.push({
852
- name: "fabdeh/ngrx-signals/rules",
853
- files,
854
- extends: [...ngrxPlugin.configs.signals, ...enforceOperatorsRules ? ngrxPlugin.configs.operators : []],
855
- rules: {
856
- "@typescript-eslint/naming-convention": [
857
- "error",
858
- ...allowLeadingUnderscoreOnMemberLike(namingConvention),
859
- {
860
- selector: "variable",
861
- modifiers: ["const", "global", "exported"],
862
- format: ["PascalCase"],
863
- leadingUnderscore: "forbid",
864
- trailingUnderscore: "forbid"
865
- }
866
- ],
867
- ...overrides
868
- }
869
- });
870
- }
871
- return tseslint__default.config(configs);
872
- }
873
-
874
- const SORT_IMPORT_GROUPS = [
875
- "type",
876
- { newlinesBetween: "never" },
877
- "builtin-type",
878
- { newlinesBetween: "never" },
879
- "external-type",
880
- { newlinesBetween: "never" },
881
- "internal-type",
882
- { newlinesBetween: "never" },
883
- "parent-type",
884
- { newlinesBetween: "never" },
885
- "sibling-type",
886
- { newlinesBetween: "never" },
887
- "index-type",
888
- { newlinesBetween: "always" },
889
- "builtin",
890
- { newlinesBetween: "always" },
891
- "external",
892
- { newlinesBetween: "always" },
893
- "internal",
894
- { newlinesBetween: "always" },
895
- "parent",
896
- { newlinesBetween: "never" },
897
- "sibling",
898
- { newlinesBetween: "never" },
899
- "index",
900
- { newlinesBetween: "always" },
901
- "side-effect",
902
- { newlinesBetween: "always" },
903
- "object",
904
- { newlinesBetween: "always" },
905
- "unknown"
906
- ];
907
- const SORT_UNION_OR_INTERSECTION_GROUPS = [
908
- "named",
909
- "keyword",
910
- "operator",
911
- "literal",
912
- "function",
913
- "import",
914
- "conditional",
915
- "object",
916
- "tuple",
917
- "intersection",
918
- "union",
919
- "nullish",
920
- "unknown"
921
- ];
922
-
923
- async function perfectionist() {
924
- const tsconfigRootDir = await findNearestPackageJsonName() === "@fabdeh/eslint-config" ? undefined : getWorkspaceRoot(process__default.cwd(), process__default.cwd());
925
- return tseslint__default.config({
926
- name: "fabdeh/perfectionist/rules",
927
- plugins: {
928
- perfectionist: perfectionistPlugin__default
929
- },
930
- rules: {
931
- "perfectionist/sort-exports": ["error", { order: "asc", type: "natural" }],
932
- "perfectionist/sort-imports": [
933
- "error",
934
- {
935
- groups: SORT_IMPORT_GROUPS,
936
- tsconfigRootDir,
937
- order: "asc",
938
- type: "natural",
939
- newlinesBetween: "never"
940
- }
941
- ],
942
- "perfectionist/sort-intersection-types": [
943
- "error",
944
- {
945
- groups: SORT_UNION_OR_INTERSECTION_GROUPS,
946
- order: "asc",
947
- type: "natural"
948
- }
949
- ],
950
- "perfectionist/sort-named-exports": ["error", { order: "asc", type: "natural" }],
951
- "perfectionist/sort-named-imports": ["error", { order: "asc", type: "natural" }],
952
- "perfectionist/sort-switch-case": ["error", { order: "asc", type: "natural" }],
953
- "perfectionist/sort-union-types": [
954
- "error",
955
- {
956
- groups: SORT_UNION_OR_INTERSECTION_GROUPS,
957
- order: "asc",
958
- type: "natural"
959
- }
960
- ]
961
- }
962
- });
963
- }
964
-
965
- function sortPackageJson() {
966
- return tseslint__default.config({
967
- name: "fabdeh/sort/package-json",
968
- files: ["**/package.json"],
969
- rules: {
970
- "jsonc/sort-array-values": [
971
- "error",
972
- {
973
- order: { type: "asc" },
974
- pathPattern: "^files$"
975
- }
976
- ],
977
- "jsonc/sort-keys": [
978
- "error",
979
- {
980
- order: [
981
- "publisher",
982
- "name",
983
- "displayName",
984
- "type",
985
- "version",
986
- "private",
987
- "packageManager",
988
- "description",
989
- "author",
990
- "contributors",
991
- "license",
992
- "funding",
993
- "homepage",
994
- "repository",
995
- "bugs",
996
- "keywords",
997
- "categories",
998
- "sideEffects",
999
- "exports",
1000
- "main",
1001
- "module",
1002
- "unpkg",
1003
- "jsdelivr",
1004
- "types",
1005
- "typesVersions",
1006
- "bin",
1007
- "icon",
1008
- "files",
1009
- "engines",
1010
- "activationEvents",
1011
- "contributes",
1012
- "scripts",
1013
- "peerDependencies",
1014
- "peerDependenciesMeta",
1015
- "dependencies",
1016
- "optionalDependencies",
1017
- "devDependencies",
1018
- "pnpm",
1019
- "overrides",
1020
- "resolutions",
1021
- "husky",
1022
- "simple-git-hooks",
1023
- "lint-staged",
1024
- "nano-staged",
1025
- "eslintConfig",
1026
- "config"
1027
- ],
1028
- pathPattern: "^$"
1029
- },
1030
- {
1031
- order: { type: "asc" },
1032
- pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies(Meta)?$"
1033
- },
1034
- {
1035
- order: { type: "asc" },
1036
- pathPattern: "^(?:resolutions|overrides|pnpm.overrides)$"
1037
- },
1038
- {
1039
- order: [
1040
- "types",
1041
- "import",
1042
- "require",
1043
- "default"
1044
- ],
1045
- pathPattern: "^exports.*$"
1046
- },
1047
- {
1048
- order: [
1049
- // client hooks only
1050
- "pre-commit",
1051
- "prepare-commit-msg",
1052
- "commit-msg",
1053
- "post-commit",
1054
- "pre-rebase",
1055
- "post-rewrite",
1056
- "post-checkout",
1057
- "post-merge",
1058
- "pre-push",
1059
- "pre-auto-gc"
1060
- ],
1061
- pathPattern: "^(?:gitHooks|husky|simple-git-hooks)$"
1062
- }
1063
- ]
1064
- }
1065
- });
1066
- }
1067
- function sortTsConfig() {
1068
- return tseslint__default.config({
1069
- name: "fabdeh/sort/tsconfig-json",
1070
- files: ["**/tsconfig.json", "**/tsconfig.*.json"],
1071
- rules: {
1072
- "jsonc/sort-keys": [
1073
- "error",
1074
- {
1075
- order: [
1076
- "extends",
1077
- "compilerOptions",
1078
- "references",
1079
- "files",
1080
- "include",
1081
- "exclude"
1082
- ],
1083
- pathPattern: "^$"
1084
- },
1085
- {
1086
- order: [
1087
- /* Projects */
1088
- "incremental",
1089
- "composite",
1090
- "tsBuildInfoFile",
1091
- "disableSourceOfProjectReferenceRedirect",
1092
- "disableSolutionSearching",
1093
- "disableReferencedProjectLoad",
1094
- /* Language and Environment */
1095
- "target",
1096
- "jsx",
1097
- "jsxFactory",
1098
- "jsxFragmentFactory",
1099
- "jsxImportSource",
1100
- "lib",
1101
- "moduleDetection",
1102
- "noLib",
1103
- "reactNamespace",
1104
- "useDefineForClassFields",
1105
- "emitDecoratorMetadata",
1106
- "experimentalDecorators",
1107
- /* Modules */
1108
- "baseUrl",
1109
- "rootDir",
1110
- "rootDirs",
1111
- "customConditions",
1112
- "module",
1113
- "moduleResolution",
1114
- "moduleSuffixes",
1115
- "noResolve",
1116
- "paths",
1117
- "resolveJsonModule",
1118
- "resolvePackageJsonExports",
1119
- "resolvePackageJsonImports",
1120
- "typeRoots",
1121
- "types",
1122
- "allowArbitraryExtensions",
1123
- "allowImportingTsExtensions",
1124
- "allowUmdGlobalAccess",
1125
- /* JavaScript Support */
1126
- "allowJs",
1127
- "checkJs",
1128
- "maxNodeModuleJsDepth",
1129
- /* Type Checking */
1130
- "strict",
1131
- "strictBindCallApply",
1132
- "strictFunctionTypes",
1133
- "strictNullChecks",
1134
- "strictPropertyInitialization",
1135
- "allowUnreachableCode",
1136
- "allowUnusedLabels",
1137
- "alwaysStrict",
1138
- "exactOptionalPropertyTypes",
1139
- "noFallthroughCasesInSwitch",
1140
- "noImplicitAny",
1141
- "noImplicitOverride",
1142
- "noImplicitReturns",
1143
- "noImplicitThis",
1144
- "noPropertyAccessFromIndexSignature",
1145
- "noUncheckedIndexedAccess",
1146
- "noUnusedLocals",
1147
- "noUnusedParameters",
1148
- "useUnknownInCatchVariables",
1149
- /* Emit */
1150
- "declaration",
1151
- "declarationDir",
1152
- "declarationMap",
1153
- "downlevelIteration",
1154
- "emitBOM",
1155
- "emitDeclarationOnly",
1156
- "importHelpers",
1157
- "importsNotUsedAsValues",
1158
- "inlineSourceMap",
1159
- "inlineSources",
1160
- "mapRoot",
1161
- "newLine",
1162
- "noEmit",
1163
- "noEmitHelpers",
1164
- "noEmitOnError",
1165
- "outDir",
1166
- "outFile",
1167
- "preserveConstEnums",
1168
- "preserveValueImports",
1169
- "removeComments",
1170
- "sourceMap",
1171
- "sourceRoot",
1172
- "stripInternal",
1173
- /* Interop Constraints */
1174
- "allowSyntheticDefaultImports",
1175
- "esModuleInterop",
1176
- "forceConsistentCasingInFileNames",
1177
- "isolatedDeclarations",
1178
- "isolatedModules",
1179
- "preserveSymlinks",
1180
- "verbatimModuleSyntax",
1181
- /* Completeness */
1182
- "skipDefaultLibCheck",
1183
- "skipLibCheck"
1184
- ],
1185
- pathPattern: "^compilerOptions$"
1186
- }
1187
- ]
1188
- }
1189
- });
1190
- }
1191
-
1192
- const STYLISTIC_CONFIG_DEFAULT = {
1193
- semi: true,
1194
- arrowParens: true,
1195
- braceStyle: "1tbs",
1196
- quoteProps: "as-needed"
1197
- };
1198
- async function stylistic(options = {}) {
1199
- const stylisticOptions = { ...STYLISTIC_CONFIG_DEFAULT, ...options };
1200
- const stylisticPlugin = await interopDefault(import('@stylistic/eslint-plugin'));
1201
- const config = stylisticPlugin.configs.customize({ ...stylisticOptions, flat: true });
1202
- return tseslint__default.config({
1203
- name: "fabdeh/stylistic/rules",
1204
- files: [GLOB_SRC],
1205
- plugins: {
1206
- "@stylistic": stylisticPlugin
1207
- },
1208
- rules: {
1209
- ...config.rules,
1210
- "@stylistic/comma-dangle": ["error", { arrays: "always-multiline", objects: "always-multiline" }],
1211
- "@stylistic/no-extra-semi": "error",
1212
- "@stylistic/operator-linebreak": ["error", "after", { overrides: { "?": "before", ":": "before" } }]
1213
- }
1214
- });
1215
- }
1216
-
1217
- async function tailwindcss(options = {}) {
1218
- const tailwindcssPlugin = await interopDefault(import('eslint-plugin-tailwindcss'));
1219
- const { overrides } = options;
1220
- return tseslint__default.config({
1221
- name: "fabdeh/tailwindcss/rules",
1222
- plugins: { tailwindcss: tailwindcssPlugin },
1223
- files: [GLOB_SRC, GLOB_HTML],
1224
- rules: {
1225
- "tailwindcss/classnames-order": "error",
1226
- "tailwindcss/enforces-negative-arbitrary-values": "error",
1227
- "tailwindcss/enforces-shorthand": "error",
1228
- "tailwindcss/no-contradicting-classname": "error",
1229
- "tailwindcss/no-unnecessary-arbitrary-value": "error",
1230
- ...overrides
1231
- }
1232
- });
1233
- }
1234
-
1235
- async function toml(options = {}) {
1236
- const {
1237
- files = [GLOB_TOML],
1238
- overrides = {},
1239
- stylistic = true
1240
- } = options;
1241
- const { indent = 2 } = typeof stylistic === "object" ? stylistic : {};
1242
- const [tomlPlugin, tomlParser] = await Promise.all([
1243
- interopDefault(import('eslint-plugin-toml')),
1244
- interopDefault(import('toml-eslint-parser'))
1245
- ]);
1246
- return tseslint__default.config(
1247
- {
1248
- name: "fabdeh/toml/setup",
1249
- plugins: {
1250
- toml: tomlPlugin
1251
- }
1252
- },
1253
- {
1254
- name: "fabdeh/toml/rules",
1255
- languageOptions: {
1256
- parser: tomlParser
1257
- },
1258
- files,
1259
- rules: {
1260
- "@stylistic/spaced-comment": "off",
1261
- "toml/comma-style": "error",
1262
- "toml/keys-order": "error",
1263
- "toml/no-space-dots": "error",
1264
- "toml/no-unreadable-number-separator": "error",
1265
- "toml/precision-of-fractional-seconds": "error",
1266
- "toml/precision-of-integer": "error",
1267
- "toml/tables-order": "error",
1268
- "toml/vue-custom-block/no-parsing-error": "error",
1269
- ...stylistic ? {
1270
- "toml/array-bracket-newline": "error",
1271
- "toml/array-bracket-spacing": "error",
1272
- "toml/array-element-newline": "error",
1273
- "toml/indent": ["error", indent === "tab" ? 2 : indent],
1274
- "toml/inline-table-curly-spacing": "error",
1275
- "toml/key-spacing": "error",
1276
- "toml/padding-line-between-pairs": "error",
1277
- "toml/padding-line-between-tables": "error",
1278
- "toml/quoted-keys": "error",
1279
- "toml/spaced-comment": "error",
1280
- "toml/table-bracket-spacing": "error"
1281
- } : {},
1282
- ...overrides
1283
- }
1284
- }
1285
- );
1286
- }
1287
-
1288
- const memberOrdering = {
1289
- default: [
1290
- "signature",
1291
- "#private-field",
1292
- "private-field",
1293
- "protected-field",
1294
- "public-field",
1295
- ["#private-accessor", "#private-get", "#private-set"],
1296
- ["private-accessor", "private-get", "private-set"],
1297
- ["protected-accessor", "protected-get", "protected-set"],
1298
- ["public-accessor", "public-get", "public-set"],
1299
- "static-initialization",
1300
- "constructor",
1301
- "call-signature",
1302
- "public-method",
1303
- "protected-method",
1304
- "private-method",
1305
- "#private-method"
1306
- ]
1307
- };
1308
-
1309
- function typescript(options = {}) {
1310
- const { stylistic = true, parserOptions, overrides } = options;
1311
- return tseslint__default.config(
1312
- {
1313
- name: "fabdeh/typescript/setup",
1314
- languageOptions: {
1315
- parserOptions: parserOptions ?? {
1316
- projectService: true,
1317
- tsconfigRootDir: getWorkspaceRoot(process__default.cwd(), process__default.cwd())
1318
- }
1319
- }
1320
- },
1321
- {
1322
- name: "fabdeh/typescript/rules",
1323
- files: [GLOB_TS],
1324
- plugins: {
1325
- "@typescript-eslint": tseslint__default.plugin
1326
- },
1327
- extends: [
1328
- eslint__default.configs.recommended,
1329
- ...tseslint__default.configs.strictTypeChecked,
1330
- ...stylistic ? tseslint__default.configs.stylisticTypeChecked : []
1331
- ],
1332
- rules: {
1333
- "@typescript-eslint/array-type": ["error", { default: "array" }],
1334
- "@typescript-eslint/consistent-indexed-object-style": "error",
1335
- "@typescript-eslint/consistent-type-assertions": [
1336
- "error",
1337
- { assertionStyle: "as", objectLiteralTypeAssertions: "never" }
1338
- ],
1339
- "@typescript-eslint/consistent-type-definitions": ["error", "interface"],
1340
- "@typescript-eslint/dot-notation": "error",
1341
- "@typescript-eslint/explicit-function-return-type": [
1342
- "error",
1343
- {
1344
- allowExpressions: true,
1345
- allowTypedFunctionExpressions: true,
1346
- allowHigherOrderFunctions: true,
1347
- allowDirectConstAssertionInArrowFunctions: true,
1348
- allowConciseArrowFunctionExpressionsStartingWithVoid: true
1349
- }
1350
- ],
1351
- "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }],
1352
- "@typescript-eslint/member-ordering": ["error", memberOrdering],
1353
- "@typescript-eslint/method-signature-style": "error",
1354
- "@typescript-eslint/naming-convention": ["error", ...namingConvention],
1355
- "@typescript-eslint/no-base-to-string": "error",
1356
- "@typescript-eslint/no-confusing-non-null-assertion": "error",
1357
- "@typescript-eslint/no-confusing-void-expression": ["error", { ignoreArrowShorthand: true }],
1358
- "@typescript-eslint/no-empty-interface": "off",
1359
- // deprecated but included in nx
1360
- "@typescript-eslint/no-extra-non-null-assertion": "error",
1361
- "@typescript-eslint/no-extraneous-class": ["error", { allowStaticOnly: true, allowWithDecorator: true }],
1362
- "@typescript-eslint/no-invalid-void-type": "error",
1363
- "@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
1364
- "@typescript-eslint/no-require-imports": "error",
1365
- "@typescript-eslint/only-throw-error": "error",
1366
- "@typescript-eslint/no-unnecessary-condition": "error",
1367
- "@typescript-eslint/no-unnecessary-type-arguments": "error",
1368
- "@typescript-eslint/no-unsafe-unary-minus": "error",
1369
- "@typescript-eslint/parameter-properties": ["error", { prefer: "parameter-property" }],
1370
- "@typescript-eslint/prefer-enum-initializers": "error",
1371
- "@typescript-eslint/prefer-for-of": "error",
1372
- "@typescript-eslint/prefer-function-type": "error",
1373
- "@typescript-eslint/prefer-includes": "error",
1374
- "@typescript-eslint/prefer-literal-enum-member": "error",
1375
- "@typescript-eslint/prefer-nullish-coalescing": "error",
1376
- "@typescript-eslint/prefer-optional-chain": "error",
1377
- "@typescript-eslint/prefer-readonly": "error",
1378
- "@typescript-eslint/prefer-reduce-type-parameter": "error",
1379
- "@typescript-eslint/prefer-return-this-type": "error",
1380
- "@typescript-eslint/prefer-string-starts-ends-with": "error",
1381
- "@typescript-eslint/require-array-sort-compare": "error",
1382
- "@typescript-eslint/restrict-plus-operands": ["error", { skipCompoundAssignments: true }],
1383
- "@typescript-eslint/restrict-template-expressions": "off",
1384
- "@typescript-eslint/switch-exhaustiveness-check": "error",
1385
- "@typescript-eslint/unbound-method": ["error", { ignoreStatic: true }],
1386
- "@typescript-eslint/unified-signatures": "error",
1387
- ...overrides
1388
- }
1389
- }
1390
- );
1391
- }
1392
-
1393
- function unicorn(options = {}) {
1394
- return tseslint__default.config({
1395
- name: "fabdeh/unicorn/rules",
1396
- plugins: { unicorn: unicornPlugin__default },
1397
- files: [GLOB_SRC],
1398
- rules: {
1399
- ...options.allRecommended ? unicornPlugin__default.configs["flat/recommended"].rules : {
1400
- "unicorn/catch-error-name": "error",
1401
- "unicorn/consistent-empty-array-spread": "error",
1402
- "unicorn/consistent-existence-index-check": "error",
1403
- "unicorn/consistent-function-scoping": ["error", { checkArrowFunctions: false }],
1404
- "unicorn/custom-error-definition": "error",
1405
- "unicorn/error-message": "error",
1406
- "unicorn/escape-case": "error",
1407
- "unicorn/explicit-length-check": "error",
1408
- "unicorn/filename-case": ["error", { case: "kebabCase" }],
1409
- "unicorn/new-for-builtins": "error",
1410
- "unicorn/no-abusive-eslint-disable": "error",
1411
- "unicorn/no-anonymous-default-export": "error",
1412
- "unicorn/no-array-for-each": "error",
1413
- "unicorn/no-array-method-this-argument": "error",
1414
- "unicorn/no-array-push-push": "error",
1415
- "unicorn/no-array-reduce": "error",
1416
- "unicorn/no-await-expression-member": "error",
1417
- "unicorn/no-await-in-promise-methods": "error",
1418
- "unicorn/no-document-cookie": "error",
1419
- "unicorn/no-empty-file": "error",
1420
- "unicorn/no-for-loop": "error",
1421
- "unicorn/no-hex-escape": "error",
1422
- "unicorn/no-instanceof-array": "error",
1423
- "unicorn/no-invalid-fetch-options": "error",
1424
- "unicorn/no-invalid-remove-event-listener": "error",
1425
- "unicorn/no-length-as-slice-end": "error",
1426
- "unicorn/no-lonely-if": "error",
1427
- "unicorn/no-magic-array-flat-depth": "error",
1428
- "unicorn/no-negated-condition": "error",
1429
- "unicorn/no-negation-in-equality-check": "error",
1430
- "unicorn/no-new-array": "error",
1431
- "unicorn/no-new-buffer": "error",
1432
- "unicorn/no-null": "error",
1433
- "unicorn/no-process-exit": "error",
1434
- "unicorn/no-single-promise-in-promise-methods": "error",
1435
- "unicorn/no-thenable": "error",
1436
- "unicorn/no-this-assignment": "error",
1437
- "unicorn/no-typeof-undefined": "error",
1438
- "unicorn/no-unnecessary-await": "error",
1439
- "unicorn/no-unused-properties": "warn",
1440
- "unicorn/no-useless-fallback-in-spread": "error",
1441
- "unicorn/no-useless-length-check": "error",
1442
- "unicorn/no-useless-promise-resolve-reject": "error",
1443
- "unicorn/no-useless-spread": "error",
1444
- "unicorn/no-useless-switch-case": "error",
1445
- "unicorn/no-zero-fractions": "error",
1446
- "unicorn/number-literal-case": "error",
1447
- "unicorn/numeric-separators-style": "error",
1448
- "unicorn/prefer-array-find": "error",
1449
- "unicorn/prefer-array-flat": "error",
1450
- "unicorn/prefer-array-flat-map": "error",
1451
- "unicorn/prefer-array-index-of": "error",
1452
- "unicorn/prefer-array-some": "error",
1453
- "unicorn/prefer-at": "error",
1454
- "unicorn/prefer-blob-reading-methods": "error",
1455
- "unicorn/prefer-code-point": "error",
1456
- "unicorn/prefer-date-now": "error",
1457
- "unicorn/prefer-default-parameters": "error",
1458
- "unicorn/prefer-export-from": "error",
1459
- "unicorn/prefer-includes": "error",
1460
- "unicorn/prefer-keyboard-event-key": "error",
1461
- "unicorn/prefer-logical-operator-over-ternary": "error",
1462
- "unicorn/prefer-math-min-max": "error",
1463
- "unicorn/prefer-math-trunc": "error",
1464
- "unicorn/prefer-modern-math-apis": "error",
1465
- "unicorn/prefer-negative-index": "error",
1466
- "unicorn/prefer-node-protocol": "error",
1467
- "unicorn/prefer-number-properties": "error",
1468
- "unicorn/prefer-object-from-entries": "error",
1469
- "unicorn/prefer-optional-catch-binding": "error",
1470
- "unicorn/prefer-query-selector": "error",
1471
- "unicorn/prefer-regexp-test": "error",
1472
- "unicorn/prefer-set-has": "error",
1473
- "unicorn/prefer-set-size": "error",
1474
- "unicorn/prefer-spread": "error",
1475
- "unicorn/prefer-string-raw": "error",
1476
- "unicorn/prefer-string-replace-all": "error",
1477
- "unicorn/prefer-string-slice": "error",
1478
- "unicorn/prefer-string-starts-ends-with": "error",
1479
- "unicorn/prefer-string-trim-start-end": "error",
1480
- "unicorn/prefer-structured-clone": "error",
1481
- "unicorn/prefer-switch": "error",
1482
- "unicorn/prefer-ternary": "error",
1483
- "unicorn/prefer-type-error": "error",
1484
- "unicorn/require-array-join-separator": "error",
1485
- "unicorn/require-number-to-fixed-digits-argument": "error",
1486
- "unicorn/require-post-message-target-origin": "error",
1487
- "unicorn/throw-new-error": "error"
1488
- }
1489
- }
1490
- });
1491
- }
1492
-
1493
- async function vitest(options = {}) {
1494
- const {
1495
- overrides = {},
1496
- useJestDom = localPkg.isPackageExists("@testing-library/jest-dom"),
1497
- useTestingLibrary = localPkg.isPackageExists("@testing-library/angular")
1498
- } = options;
1499
- const [vitestPlugin, jestDomPlugin, testingLibraryPlugin] = await Promise.all([
1500
- interopDefault(import('@vitest/eslint-plugin')),
1501
- useJestDom ? interopDefault(import('eslint-plugin-jest-dom')) : Promise.resolve(undefined),
1502
- useTestingLibrary ? interopDefault(import('eslint-plugin-testing-library')) : Promise.resolve(undefined)
1503
- ]);
1504
- return tseslint__default.config({
1505
- name: "fabdeh/vitest/rules",
1506
- plugins: { vitest: vitestPlugin },
1507
- languageOptions: {
1508
- globals: {
1509
- ...globals__default.node,
1510
- ...globals__default.vitest,
1511
- ...vitestPlugin.environments.env.globals
1512
- }
1513
- },
1514
- settings: {
1515
- vitest: {
1516
- typecheck: true
1517
- }
1518
- },
1519
- files: [...GLOB_TESTS],
1520
- extends: [
1521
- vitestPlugin.configs.recommended,
1522
- ...jestDomPlugin ? [jestDomPlugin.configs["flat/recommended"]] : [],
1523
- ...testingLibraryPlugin ? [testingLibraryPlugin.configs["flat/angular"]] : []
1524
- ],
1525
- rules: {
1526
- "max-classes-per-file": "off",
1527
- "max-lines": "off",
1528
- "@typescript-eslint/consistent-type-assertions": "off",
1529
- "@typescript-eslint/no-empty-function": "off",
1530
- "@typescript-eslint/no-unsafe-assignment": "off",
1531
- "@typescript-eslint/no-unsafe-call": "off",
1532
- "@typescript-eslint/no-unsafe-member-access": "off",
1533
- "@typescript-eslint/unbound-method": "off",
1534
- "unicorn/no-null": "off",
1535
- "vitest/consistent-test-it": ["error", { fn: "test" }],
1536
- "vitest/no-standalone-expect": "error",
1537
- "vitest/no-test-return-statement": "error",
1538
- "vitest/prefer-hooks-in-order": "error",
1539
- "vitest/prefer-hooks-on-top": "error",
1540
- "vitest/prefer-lowercase-title": "error",
1541
- "vitest/prefer-spy-on": "error",
1542
- "vitest/prefer-to-be": "error",
1543
- "vitest/prefer-to-be-falsy": "error",
1544
- "vitest/prefer-to-be-object": "error",
1545
- "vitest/prefer-to-be-truthy": "error",
1546
- "vitest/prefer-to-contain": "error",
1547
- "vitest/prefer-to-have-length": "error",
1548
- "vitest/prefer-todo": "error",
1549
- "vitest/prefer-vi-mocked": "error",
1550
- "vitest/require-top-level-describe": "error",
1551
- ...overrides
1552
- }
1553
- });
1554
- }
1555
-
1556
- async function yaml(options = {}) {
1557
- const {
1558
- files = [GLOB_YAML],
1559
- overrides = {},
1560
- stylistic = true
1561
- } = options;
1562
- const {
1563
- indent = 2,
1564
- quotes = "single"
1565
- } = typeof stylistic === "object" ? stylistic : {};
1566
- const [yamlPlugin, yamlParser] = await Promise.all([
1567
- interopDefault(import('eslint-plugin-yml')),
1568
- interopDefault(import('yaml-eslint-parser'))
1569
- ]);
1570
- return tseslint__default.config(
1571
- {
1572
- name: "fabdeh/yaml/setup",
1573
- plugins: {
1574
- yaml: yamlPlugin
1575
- }
1576
- },
1577
- {
1578
- name: "fabdeh/yaml/rules",
1579
- languageOptions: {
1580
- parser: yamlParser
1581
- },
1582
- files,
1583
- rules: {
1584
- "@stylistic/spaced-comment": "off",
1585
- "yaml/block-mapping": "error",
1586
- "yaml/block-sequence": "error",
1587
- "yaml/no-empty-key": "error",
1588
- "yaml/no-empty-sequence-entry": "error",
1589
- "yaml/no-irregular-whitespace": "error",
1590
- "yaml/plain-scalar": "error",
1591
- "yaml/vue-custom-block/no-parsing-error": "error",
1592
- ...stylistic ? {
1593
- "yaml/block-mapping-question-indicator-newline": "error",
1594
- "yaml/block-sequence-hyphen-indicator-newline": "error",
1595
- "yaml/flow-mapping-curly-newline": "error",
1596
- "yaml/flow-mapping-curly-spacing": "error",
1597
- "yaml/flow-sequence-bracket-newline": "error",
1598
- "yaml/flow-sequence-bracket-spacing": "error",
1599
- "yaml/indent": ["error", indent === "tab" ? 2 : indent],
1600
- "yaml/key-spacing": "error",
1601
- "yaml/no-tab-indent": "error",
1602
- "yaml/quotes": ["error", { avoidEscape: true, prefer: quotes === "backtick" ? "single" : quotes }],
1603
- "yaml/spaced-comment": "error"
1604
- } : {},
1605
- ...overrides
1606
- }
1607
- }
1608
- );
1609
- }
1610
-
1611
- function mergePrettierOptions(options, overrides = {}) {
1612
- return {
1613
- ...options,
1614
- ...overrides,
1615
- plugins: [
1616
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1617
- ...overrides.plugins ?? [],
1618
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1619
- ...options.plugins ?? []
1620
- ]
1621
- };
1622
- }
1623
- async function formatters(options = {}, stylistic = {}) {
1624
- if (options === true) {
1625
- const isPrettierPluginXmlInScope = isPackageInScope("@prettier/plugin-xml");
1626
- options = {
1627
- css: true,
1628
- graphql: true,
1629
- html: true,
1630
- markdown: true,
1631
- slidev: localPkg.isPackageExists("@slidev/cli"),
1632
- svg: isPrettierPluginXmlInScope,
1633
- xml: isPrettierPluginXmlInScope
1634
- };
1635
- }
1636
- await ensurePackages([
1637
- "eslint-plugin-format",
1638
- options.markdown && options.slidev ? "prettier-plugin-slidev" : undefined,
1639
- options.xml || options.svg ? "@prettier/plugin-xml" : undefined
1640
- ]);
1641
- const {
1642
- indent,
1643
- quotes,
1644
- semi
1645
- } = {
1646
- ...STYLISTIC_CONFIG_DEFAULT,
1647
- ...stylistic
1648
- };
1649
- const prettierOptions = {
1650
- endOfLine: "auto",
1651
- printWidth: 120,
1652
- semi,
1653
- singleQuote: quotes === "single",
1654
- tabWidth: typeof indent === "number" ? indent : 2,
1655
- trailingComma: "all",
1656
- useTabs: indent === "tab",
1657
- ...options.options
1658
- };
1659
- const prettierXmlOptions = {
1660
- xmlQuoteAttributes: "double",
1661
- xmlSelfClosingSpace: true,
1662
- xmlSortAttributesByKey: false,
1663
- xmlWhitespaceSensitivity: "ignore"
1664
- };
1665
- const formatPlugin = await interopDefault(import('eslint-plugin-format'));
1666
- const configs = [
1667
- {
1668
- name: "fabdeh/formatter/setup",
1669
- plugins: {
1670
- format: formatPlugin
1671
- }
1672
- }
1673
- ];
1674
- if (options.css) {
1675
- configs.push(
1676
- {
1677
- name: "fabdeh/formatter/css",
1678
- languageOptions: {
1679
- parser: formatPlugin.parserPlain
1680
- },
1681
- files: [GLOB_CSS, GLOB_POSTCSS],
1682
- rules: {
1683
- "format/prettier": [
1684
- "error",
1685
- mergePrettierOptions(prettierOptions, { parser: "css" })
1686
- ]
1687
- }
1688
- },
1689
- {
1690
- name: "fabdeh/formatter/scss",
1691
- languageOptions: {
1692
- parser: formatPlugin.parserPlain
1693
- },
1694
- files: [GLOB_SCSS],
1695
- rules: {
1696
- "format/prettier": [
1697
- "error",
1698
- mergePrettierOptions(prettierOptions, { parser: "scss" })
1699
- ]
1700
- }
1701
- },
1702
- {
1703
- name: "fabdeh/formatter/less",
1704
- languageOptions: {
1705
- parser: formatPlugin.parserPlain
1706
- },
1707
- files: [GLOB_LESS],
1708
- rules: {
1709
- "format/prettier": [
1710
- "error",
1711
- mergePrettierOptions(prettierOptions, { parser: "less" })
1712
- ]
1713
- }
1714
- }
1715
- );
1716
- }
1717
- if (options.html) {
1718
- configs.push({
1719
- name: "fabdeh/formatter/html",
1720
- languageOptions: {
1721
- parser: formatPlugin.parserPlain
1722
- },
1723
- files: [GLOB_HTML],
1724
- rules: {
1725
- "format/prettier": [
1726
- "error",
1727
- mergePrettierOptions(prettierOptions, { parser: "html" })
1728
- ]
1729
- }
1730
- });
1731
- }
1732
- if (options.xml) {
1733
- configs.push({
1734
- name: "fabdeh/formatter/xml",
1735
- languageOptions: {
1736
- parser: formatPlugin.parserPlain
1737
- },
1738
- files: [GLOB_XML],
1739
- rules: {
1740
- "format/prettier": [
1741
- "error",
1742
- mergePrettierOptions({ ...prettierXmlOptions, ...prettierOptions }, {
1743
- parser: "xml",
1744
- plugins: ["@prettier/plugin-xml"]
1745
- })
1746
- ]
1747
- }
1748
- });
1749
- }
1750
- if (options.svg) {
1751
- configs.push({
1752
- name: "fabdeh/formatter/svg",
1753
- languageOptions: {
1754
- parser: formatPlugin.parserPlain
1755
- },
1756
- files: [GLOB_SVG],
1757
- rules: {
1758
- "format/prettier": [
1759
- "error",
1760
- mergePrettierOptions({ ...prettierXmlOptions, ...prettierOptions }, {
1761
- parser: "xml",
1762
- plugins: ["@prettier/plugin-xml"]
1763
- })
1764
- ]
1765
- }
1766
- });
1767
- }
1768
- if (options.markdown) {
1769
- const GLOB_SLIDEV = options.slidev ? options.slidev === true ? ["**/.slides.md"] : options.slidev.files : [];
1770
- configs.push({
1771
- name: "fabdeh/formatter/markdown",
1772
- languageOptions: {
1773
- parser: formatPlugin.parserPlain
1774
- },
1775
- files: [GLOB_MARKDOWN],
1776
- ignores: GLOB_SLIDEV,
1777
- rules: {
1778
- "format/prettier": [
1779
- "error",
1780
- mergePrettierOptions(prettierOptions, {
1781
- parser: "markdown",
1782
- embeddedLanguageFormatting: "off"
1783
- })
1784
- ]
1785
- }
1786
- });
1787
- if (options.slidev) {
1788
- configs.push({
1789
- name: "fabdeh/formatter/slidev",
1790
- languageOptions: {
1791
- parser: formatPlugin.parserPlain
1792
- },
1793
- files: GLOB_SLIDEV,
1794
- rules: {
1795
- "format/prettier": [
1796
- "error",
1797
- mergePrettierOptions(prettierOptions, {
1798
- embeddedLanguageFormatting: "off",
1799
- parser: "slidev",
1800
- plugins: ["prettier-plugin-slidev"]
1801
- })
1802
- ]
1803
- }
1804
- });
1805
- }
1806
- }
1807
- if (options.graphql) {
1808
- configs.push({
1809
- name: "fabdeh/formatter/graphql",
1810
- languageOptions: {
1811
- parser: formatPlugin.parserPlain
1812
- },
1813
- files: [GLOB_GRAPHQL],
1814
- rules: {
1815
- "format/prettier": [
1816
- "error",
1817
- mergePrettierOptions(prettierOptions, { parser: "graphql" })
1818
- ]
1819
- }
1820
- });
1821
- }
1822
- return tseslint__default.config(configs);
1823
- }
1824
-
1825
- const FLAT_CONFIG_PROPS = [
1826
- "name",
1827
- "languageOptions",
1828
- "linterOptions",
1829
- "processor",
1830
- "plugins",
1831
- "rules",
1832
- "settings",
1833
- "extends"
1834
- ];
1835
- const NGRX_PACKAGES = ["@ngrx/store", "@ngrx/effects", "@ngrx/signals", "@ngrx/operators"];
1836
- async function createConfig(options = {}, ...userConfigs) {
1837
- const {
1838
- angular: enableAngular = localPkg.isPackageExists("@angular/core"),
1839
- gitignore: enableGitignore = true,
1840
- isInEditor = isInEditorEnv(),
1841
- jest: enableJest = localPkg.isPackageExists("jest"),
1842
- ngrx: enableNgrx = NGRX_PACKAGES.some((p) => localPkg.isPackageExists(p)),
1843
- tailwindcss: enableTailwind = localPkg.isPackageExists("tailwindcss"),
1844
- unicorn: enableUnicorn = true,
1845
- vitest: enableVitest = localPkg.isPackageExists("vitest")
1846
- } = options;
1847
- if (isInEditor) {
1848
- console.log(
1849
- "[@fabdeh/eslint-config] Detected running in editor, some rules are configured as warn or completely turned off."
1850
- );
1851
- }
1852
- if (enableJest && enableVitest) {
1853
- throw new Error(
1854
- '[@fabdeh/eslint-config] Detected that both "jest" and "vitest" are enabled which is not supported. Manually disable or uninstall one of them.'
1855
- );
1856
- }
1857
- const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
1858
- const configs = [];
1859
- if (enableGitignore) {
1860
- if (typeof enableGitignore === "object") {
1861
- configs.push(
1862
- interopDefault(import('eslint-config-flat-gitignore')).then(
1863
- (r) => tseslint__default.config(r({ name: "fabdeh/gitignore", ...enableGitignore }))
1864
- )
1865
- );
1866
- } else {
1867
- configs.push(
1868
- interopDefault(import('eslint-config-flat-gitignore')).then(
1869
- (r) => tseslint__default.config(r({ name: "fabdeh/gitignore", strict: true }))
1870
- )
1871
- );
1872
- }
1873
- }
1874
- const allowAngularDecorator = options.angular !== false;
1875
- configs.push(
1876
- ignores(options.ignores),
1877
- javascript({ isInEditor, overrides: options.javascript?.overrides, allowAngularDecorator }),
1878
- typescript({
1879
- stylistic: stylisticOptions,
1880
- parserOptions: options.typescript?.parserOptions,
1881
- overrides: options.typescript?.overrides
1882
- }),
1883
- comments(),
1884
- imports({ stylistic: stylisticOptions }),
1885
- jsdoc({ stylistic: stylisticOptions }),
1886
- perfectionist()
1887
- );
1888
- if (enableUnicorn) {
1889
- configs.push(unicorn(typeof enableUnicorn === "object" ? enableUnicorn : {}));
1890
- }
1891
- if (stylisticOptions) {
1892
- configs.push(stylistic({ stylistic: stylisticOptions }));
1893
- }
1894
- if (enableAngular) {
1895
- configs.push(angular(typeof enableAngular === "object" ? enableAngular : {}));
1896
- }
1897
- if (enableNgrx) {
1898
- configs.push(ngrx(typeof enableNgrx === "object" ? enableNgrx : {}));
1899
- }
1900
- if (enableJest) {
1901
- configs.push(
1902
- jest(
1903
- typeof enableJest === "object" ? { ...enableJest, stylistic: stylisticOptions } : { stylistic: stylisticOptions }
1904
- )
1905
- );
1906
- }
1907
- if (enableVitest) {
1908
- configs.push(vitest(typeof enableVitest === "object" ? enableVitest : {}));
1909
- }
1910
- if (enableTailwind) {
1911
- configs.push(tailwindcss(typeof enableTailwind === "object" ? enableTailwind : {}));
1912
- }
1913
- if (options.jsonc ?? true) {
1914
- configs.push(
1915
- jsonc({
1916
- overrides: typeof options.jsonc === "object" ? options.jsonc.overrides : {},
1917
- stylistic: stylisticOptions
1918
- }),
1919
- sortPackageJson(),
1920
- sortTsConfig()
1921
- );
1922
- }
1923
- if (options.yaml ?? true) {
1924
- configs.push(yaml({
1925
- overrides: typeof options.yaml === "object" ? options.yaml.overrides : {},
1926
- stylistic: stylisticOptions
1927
- }));
1928
- }
1929
- if (options.toml ?? true) {
1930
- configs.push(toml({
1931
- overrides: typeof options.toml === "object" ? options.toml.overrides : {},
1932
- stylistic: stylisticOptions
1933
- }));
1934
- }
1935
- if (options.markdown ?? true) {
1936
- configs.push(markdown({
1937
- overrides: typeof options.markdown === "object" ? options.markdown.overrides : {}
1938
- }));
1939
- }
1940
- if (options.formatters) {
1941
- configs.push(formatters(options.formatters, typeof stylisticOptions === "boolean" ? {} : stylisticOptions));
1942
- }
1943
- if ("files" in options) {
1944
- throw new Error('[@fabdeh/eslint-config] The first argument should not contain the "files" property as the options are supposed to be global. Place it in the second or later config instead.');
1945
- }
1946
- const fusedConfig = Object.fromEntries(
1947
- Object.entries(options).filter(([k]) => FLAT_CONFIG_PROPS.includes(k))
1948
- );
1949
- if (Object.keys(fusedConfig).length > 0) {
1950
- configs.push([fusedConfig]);
1951
- }
1952
- return tseslint__default.config(...await Promise.all(configs), ...await Promise.all(userConfigs));
1953
- }
1954
-
1955
- exports.GLOB_HTML = GLOB_HTML;
1956
- exports.GLOB_JS = GLOB_JS;
1957
- exports.GLOB_SRC = GLOB_SRC;
1958
- exports.GLOB_TESTS = GLOB_TESTS;
1959
- exports.GLOB_TS = GLOB_TS;
1960
- exports.STYLISTIC_CONFIG_DEFAULT = STYLISTIC_CONFIG_DEFAULT;
1961
- exports.angular = angular;
1962
- exports.comments = comments;
1963
- exports.createConfig = createConfig;
1964
- exports.ensurePackages = ensurePackages;
1965
- exports.findNearestPackageJsonName = findNearestPackageJsonName;
1966
- exports.getWorkspaceRoot = getWorkspaceRoot;
1967
- exports.ignores = ignores;
1968
- exports.imports = imports;
1969
- exports.interopDefault = interopDefault;
1970
- exports.isInEditorEnv = isInEditorEnv;
1971
- exports.isPackageInScope = isPackageInScope;
1972
- exports.javascript = javascript;
1973
- exports.jest = jest;
1974
- exports.jsdoc = jsdoc;
1975
- exports.jsonc = jsonc;
1976
- exports.markdown = markdown;
1977
- exports.ngrx = ngrx;
1978
- exports.perfectionist = perfectionist;
1979
- exports.sortPackageJson = sortPackageJson;
1980
- exports.sortTsConfig = sortTsConfig;
1981
- exports.stylistic = stylistic;
1982
- exports.tailwindcss = tailwindcss;
1983
- exports.toArray = toArray;
1984
- exports.toml = toml;
1985
- exports.typescript = typescript;
1986
- exports.unicorn = unicorn;
1987
- exports.vitest = vitest;
1988
- exports.yaml = yaml;