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