@fabdeh/eslint-config 0.0.4 → 0.1.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 CHANGED
@@ -1,74 +1,72 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ 'use strict';
29
2
 
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- GLOB_EXCLUDE: () => GLOB_EXCLUDE,
34
- GLOB_HTML: () => GLOB_HTML,
35
- GLOB_JS: () => GLOB_JS,
36
- GLOB_SRC: () => GLOB_SRC,
37
- GLOB_SRC_EXT: () => GLOB_SRC_EXT,
38
- GLOB_TESTS: () => GLOB_TESTS,
39
- GLOB_TS: () => GLOB_TS,
40
- GLOB_TS_EXT: () => GLOB_TS_EXT,
41
- dedupeTsBaseConfig: () => dedupeTsBaseConfig,
42
- default: () => index_default,
43
- ensureCorrectFiles: () => ensureCorrectFiles,
44
- isInEditorEnv: () => isInEditorEnv
45
- });
46
- module.exports = __toCommonJS(index_exports);
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');
47
19
 
48
- // src/configs/index.ts
49
- var configs_exports = {};
50
- __export(configs_exports, {
51
- angular: () => angular_default,
52
- base: () => base_default,
53
- jest: () => jest_default,
54
- ngrx: () => ngrx_exports,
55
- tailwindcss: () => tailwindcss_default,
56
- vitest: () => vitest_default
57
- });
20
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
21
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
58
22
 
59
- // src/configs/angular.ts
60
- var import_eslint_plugin = __toESM(require("@nx/eslint-plugin"), 1);
61
- var import_typescript_eslint = __toESM(require("typescript-eslint"), 1);
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
+ }
62
34
 
63
- // src/globs.ts
64
- var GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
65
- var GLOB_SRC = `**/*.${GLOB_SRC_EXT}`;
66
- var GLOB_JS = "**/*.?([cm])js?(x)";
67
- var GLOB_TS_EXT = "?([cm])ts?(x)";
68
- var GLOB_TS = `**/*.${GLOB_TS_EXT}`;
69
- var GLOB_HTML = "**/*.htm?(l)";
70
- var GLOB_TESTS = [`**/*.spec.${GLOB_SRC_EXT}`, `**/*.test.${GLOB_SRC_EXT}`, `**/test-setup.${GLOB_SRC_EXT}`];
71
- var GLOB_EXCLUDE = [
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 = [
72
70
  "**/node_modules",
73
71
  "**/dist",
74
72
  "**/package-lock.json",
@@ -100,88 +98,17 @@ var GLOB_EXCLUDE = [
100
98
  "**/LICENSE*",
101
99
  "**/__snapshots__",
102
100
  "**/auto-import?(s).d.ts",
103
- "**/components.d.ts"
101
+ "**/components.d.ts",
102
+ "**/prettier-types.ts"
104
103
  ];
105
104
 
106
- // src/configs/angular.ts
107
- var angular_default = import_typescript_eslint.default.config(
108
- import_eslint_plugin.default.configs["flat/angular"],
109
- import_eslint_plugin.default.configs["flat/angular-template"],
110
- {
111
- name: "fabdeh/angular/rules",
112
- files: [GLOB_TS],
113
- rules: {
114
- "max-classes-per-file": ["error", 1],
115
- "max-lines": ["error", 400],
116
- "@angular-eslint/component-max-inline-declarations": "error",
117
- "@angular-eslint/contextual-decorator": "error",
118
- "@angular-eslint/no-async-lifecycle-method": "error",
119
- "@angular-eslint/no-attribute-decorator": "error",
120
- "@angular-eslint/no-conflicting-lifecycle": "error",
121
- "@angular-eslint/no-duplicates-in-metadata-arrays": "error",
122
- "@angular-eslint/no-forward-ref": "error",
123
- "@angular-eslint/no-lifecycle-call": "error",
124
- "@angular-eslint/no-pipe-impure": "error",
125
- "@angular-eslint/no-queries-metadata-property": "error",
126
- "@angular-eslint/prefer-output-readonly": "error",
127
- "@angular-eslint/prefer-signals": "error",
128
- "@angular-eslint/relative-url-prefix": "error",
129
- "@angular-eslint/sort-lifecycle-methods": "error",
130
- "@angular-eslint/use-component-selector": "error",
131
- "@angular-eslint/use-component-view-encapsulation": "error",
132
- "@angular-eslint/use-lifecycle-interface": "error"
133
- }
134
- },
135
- {
136
- name: "fabdeh/angular-template/rules",
137
- files: [GLOB_HTML],
138
- rules: {
139
- "@angular-eslint/template/attributes-order": ["error", { alphabetical: true }],
140
- "@angular-eslint/template/button-has-type": "error",
141
- "@angular-eslint/template/conditional-complexity": "error",
142
- "@angular-eslint/template/eqeqeq": ["error", { allowNullOrUndefined: true }],
143
- "@angular-eslint/template/no-any": "error",
144
- "@angular-eslint/template/no-duplicate-attributes": "error",
145
- "@angular-eslint/template/no-interpolation-in-attributes": "error",
146
- "@angular-eslint/template/no-positive-tabindex": "error",
147
- "@angular-eslint/template/prefer-control-flow": "error",
148
- "@angular-eslint/template/prefer-ngsrc": "error",
149
- "@angular-eslint/template/prefer-self-closing-tags": "error",
150
- // accessibility
151
- "@angular-eslint/template/alt-text": "error",
152
- "@angular-eslint/template/click-events-have-key-events": "warn",
153
- "@angular-eslint/template/elements-content": "error",
154
- "@angular-eslint/template/interactive-supports-focus": "warn",
155
- "@angular-eslint/template/label-has-associated-control": "error",
156
- "@angular-eslint/template/mouse-events-have-key-events": "warn",
157
- "@angular-eslint/template/no-autofocus": "error",
158
- "@angular-eslint/template/no-distracting-elements": "error",
159
- "@angular-eslint/template/role-has-required-aria": "error",
160
- "@angular-eslint/template/table-scope": "error",
161
- "@angular-eslint/template/valid-aria": "error"
162
- }
163
- }
164
- );
165
-
166
- // src/configs/base.ts
167
- var import_eslint_plugin_eslint_comments = __toESM(require("@eslint-community/eslint-plugin-eslint-comments"), 1);
168
- var import_eslint_plugin2 = __toESM(require("@nx/eslint-plugin"), 1);
169
- var import_eslint_plugin3 = __toESM(require("@stylistic/eslint-plugin"), 1);
170
- var importX = __toESM(require("eslint-plugin-import-x"), 1);
171
- var import_eslint_plugin_jsdoc = __toESM(require("eslint-plugin-jsdoc"), 1);
172
- var import_eslint_plugin_perfectionist = __toESM(require("eslint-plugin-perfectionist"), 1);
173
- var import_eslint_plugin_prefer_arrow_functions = __toESM(require("eslint-plugin-prefer-arrow-functions"), 1);
174
- var import_eslint_plugin_unicorn = __toESM(require("eslint-plugin-unicorn"), 1);
175
- var import_eslint_plugin_unused_imports = __toESM(require("eslint-plugin-unused-imports"), 1);
176
- var import_globals = __toESM(require("globals"), 1);
177
- var import_typescript_eslint2 = __toESM(require("typescript-eslint"), 1);
178
-
179
- // src/utils.ts
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("@antfu/eslint-config");
180
107
  function isInEditorEnv() {
181
- if (process.env.CI) {
108
+ if (process__default.env.CI) {
182
109
  return false;
183
110
  }
184
- const envKeys = Object.keys(process.env);
111
+ const envKeys = Object.keys(process__default.env);
185
112
  if (envKeys.some((k) => /^GIT_/i.test(k))) {
186
113
  return false;
187
114
  }
@@ -192,45 +119,650 @@ function isInEditorEnv() {
192
119
  const isNeoVim = envKeys.some((k) => /^NVIM$/i.test(k));
193
120
  return isVsCode || isIntelliJ || isJetbrains || isVim || isNeoVim;
194
121
  }
195
- function dedupeTsBaseConfig(...configs) {
196
- return configs.filter((c) => !c.name || c.name !== "typescript-eslint/base");
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
+ }
197
170
  }
198
- function ensureCorrectFiles(files) {
199
- return (config) => {
200
- if ("rules" in config && !("files" in config)) {
201
- return {
202
- ...config,
203
- files
204
- };
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
+ }
205
247
  }
206
- return config;
207
- };
248
+ );
208
249
  }
209
250
 
210
- // src/configs/rules-configs/member-ordering.ts
211
- var member_ordering_default = {
212
- default: [
213
- "signature",
214
- "#private-field",
215
- "private-field",
216
- "protected-field",
217
- "public-field",
218
- ["#private-accessor", "#private-get", "#private-set"],
219
- ["private-accessor", "private-get", "private-set"],
220
- ["protected-accessor", "protected-get", "protected-set"],
221
- ["public-accessor", "public-get", "public-set"],
222
- "static-initialization",
223
- "constructor",
224
- "call-signature",
225
- "public-method",
226
- "protected-method",
227
- "private-method",
228
- "#private-method"
229
- ]
230
- };
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
+ }
231
494
 
232
- // src/configs/rules-configs/naming-convention.ts
233
- var naming_convention_default = [
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 = [
234
766
  { selector: "default", format: ["camelCase"], leadingUnderscore: "forbid", trailingUnderscore: "forbid" },
235
767
  { selector: ["variableLike", "memberLike"], format: ["camelCase"] },
236
768
  // eslint-disable-next-line unicorn/no-null
@@ -243,34 +775,152 @@ var naming_convention_default = [
243
775
  { selector: "import", modifiers: ["namespace"], format: ["camelCase", "PascalCase"] }
244
776
  ];
245
777
 
246
- // src/configs/rules-configs/perfectionist-groups.ts
247
- var SORT_IMPORT_GROUPS = [
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 = [
248
891
  "type",
892
+ { newlinesBetween: "never" },
249
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" },
250
905
  "builtin",
251
906
  { newlinesBetween: "always" },
252
- "external-type",
253
907
  "external",
254
908
  { newlinesBetween: "always" },
255
- "internal-type",
256
909
  "internal",
257
910
  { newlinesBetween: "always" },
258
- "parent-type",
259
911
  "parent",
260
- { newlinesBetween: "always" },
261
- "sibling-type",
912
+ { newlinesBetween: "never" },
262
913
  "sibling",
263
- { newlinesBetween: "always" },
264
- "index-type",
914
+ { newlinesBetween: "never" },
265
915
  "index",
266
916
  { newlinesBetween: "always" },
267
- "object",
268
- { newlinesBetween: "always" },
269
917
  "side-effect",
270
918
  { newlinesBetween: "always" },
919
+ "object",
920
+ { newlinesBetween: "always" },
271
921
  "unknown"
272
922
  ];
273
- var SORT_UNION_OR_INTERSECTION_GROUPS = [
923
+ const SORT_UNION_OR_INTERSECTION_GROUPS = [
274
924
  "named",
275
925
  "keyword",
276
926
  "operator",
@@ -286,220 +936,22 @@ var SORT_UNION_OR_INTERSECTION_GROUPS = [
286
936
  "unknown"
287
937
  ];
288
938
 
289
- // src/configs/base.ts
290
- var IS_IN_EDITOR = isInEditorEnv();
291
- var base_default = import_typescript_eslint2.default.config(
292
- {
293
- name: "fabdeh/base/ignores",
294
- ignores: GLOB_EXCLUDE
295
- },
296
- {
297
- name: "fabdeh/base/setup",
298
- files: [GLOB_SRC],
939
+ function perfectionist() {
940
+ return tseslint__default.config({
941
+ name: "fabdeh/perfectionist/rules",
299
942
  plugins: {
300
- "@eslint-community/eslint-comments": import_eslint_plugin_eslint_comments.default,
301
- "@typescript-eslint": import_typescript_eslint2.default.plugin,
302
- "import-x": importX,
303
- jsdoc: import_eslint_plugin_jsdoc.default,
304
- perfectionist: import_eslint_plugin_perfectionist.default,
305
- "prefer-arrow-functions": import_eslint_plugin_prefer_arrow_functions.default,
306
- "@stylistic": import_eslint_plugin3.default,
307
- unicorn: import_eslint_plugin_unicorn.default,
308
- "unused-imports": import_eslint_plugin_unused_imports.default
943
+ perfectionist: perfectionistPlugin__default
309
944
  },
310
- languageOptions: {
311
- ecmaVersion: 2022,
312
- globals: {
313
- ...import_globals.default.browser,
314
- ...import_globals.default.es2021,
315
- ...import_globals.default.node,
316
- document: "readonly",
317
- navigator: "readonly",
318
- window: "readonly"
319
- },
320
- parser: import_typescript_eslint2.default.parser,
321
- parserOptions: {
322
- ecmaFeatures: {
323
- jsx: true
324
- },
325
- ecmaVersion: 2022,
326
- sourceType: "module"
327
- },
328
- sourceType: "module"
329
- },
330
- linterOptions: {
331
- reportUnusedDisableDirectives: "error"
332
- }
333
- },
334
- {
335
- name: "fabdeh/base/common-rules",
336
- files: [GLOB_SRC],
337
- extends: [import_eslint_plugin3.default.configs["recommended-flat"]],
338
945
  rules: {
339
- "@eslint-community/eslint-comments/disable-enable-pair": ["error", { allowWholeFile: true }],
340
- "@eslint-community/eslint-comments/no-aggregating-enable": "error",
341
- "@eslint-community/eslint-comments/no-duplicate-disable": "error",
342
- "@eslint-community/eslint-comments/no-unlimited-disable": "error",
343
- "@eslint-community/eslint-comments/no-unused-disable": "error",
344
- "@eslint-community/eslint-comments/no-unused-enable": "error",
345
- "@stylistic/no-extra-semi": "error",
346
- "@typescript-eslint/no-empty-function": "error",
347
- "@typescript-eslint/no-invalid-this": "error",
348
- "@typescript-eslint/no-redeclare": "error",
349
- "@typescript-eslint/no-restricted-imports": ["error", "rxjs/Rx"],
350
- "@typescript-eslint/no-shadow": ["error", { hoist: "all" }],
351
- "@typescript-eslint/no-unused-expressions": "error",
352
- "@typescript-eslint/no-use-before-define": "error",
353
- "@typescript-eslint/no-useless-constructor": "error",
354
- "accessor-pairs": "error",
355
- "array-callback-return": "error",
356
- "block-scoped-var": "error",
357
- "default-case-last": "error",
358
- "dot-notation": "error",
359
- eqeqeq: "error",
360
- "id-denylist": [
361
- "error",
362
- "any",
363
- "Number",
364
- "number",
365
- "String",
366
- "string",
367
- "Boolean",
368
- "boolean",
369
- "Undefined",
370
- "undefined"
371
- ],
372
- "new-cap": [
373
- "error",
374
- {
375
- capIsNewExceptions: [
376
- "Attribute",
377
- "Component",
378
- "ContentChild",
379
- "ContentChildren",
380
- "Directive",
381
- "Host",
382
- "HostBinding",
383
- "HostListener",
384
- "Inject",
385
- "Injectable",
386
- "Input",
387
- "NgModule",
388
- "Optional",
389
- "Output",
390
- "Pipe",
391
- "Self",
392
- "SkipSelf",
393
- "ViewChild",
394
- "ViewChildren"
395
- ]
396
- }
397
- ],
398
- "no-alert": "error",
399
- "no-array-constructor": "error",
400
- "no-caller": "error",
401
- "no-cond-assign": ["error", "always"],
402
- "no-console": ["error", { allow: ["warn", "error"] }],
403
- "no-empty": ["error", { allowEmptyCatch: true }],
404
- "no-eval": "error",
405
- "no-extend-native": "error",
406
- "no-extra-bind": "error",
407
- "no-implied-eval": "error",
408
- "no-iterator": "error",
409
- "no-labels": "error",
410
- "no-lone-blocks": "error",
411
- "no-lonely-if": "error",
412
- "no-multi-str": "error",
413
- "no-new": "error",
414
- "no-new-func": "error",
415
- "no-new-wrappers": "error",
416
- "no-octal-escape": "error",
417
- "no-plusplus": ["error", { allowForLoopAfterthoughts: true }],
418
- "no-proto": "error",
419
- "no-restricted-syntax": ["error", "TSEnumDeclaration[const=true]", "TSExportAssignment", "ForInStatement"],
420
- "no-self-compare": "error",
421
- "no-sequences": "error",
422
- "no-template-curly-in-string": "error",
423
- "no-throw-literal": "error",
424
- "no-undef": "error",
425
- "no-undef-init": "error",
426
- "no-unmodified-loop-condition": "error",
427
- "no-unneeded-ternary": ["error", { defaultAssignment: false }],
428
- "no-unreachable-loop": "error",
429
- "no-unused-expressions": [
430
- "error",
431
- {
432
- allowShortCircuit: true,
433
- allowTaggedTemplates: true,
434
- allowTernary: true
435
- }
436
- ],
437
- "no-unused-vars": "off",
438
- "no-use-before-define": ["error", { classes: false, functions: false }],
439
- "no-useless-call": "error",
440
- "no-useless-computed-key": "error",
441
- "no-useless-constructor": "error",
442
- "no-useless-rename": "error",
443
- "no-useless-return": "error",
444
- "no-var": "error",
445
- "object-shorthand": [
446
- "error",
447
- "always",
448
- {
449
- avoidQuotes: true,
450
- ignoreConstructors: false
451
- }
452
- ],
453
- "prefer-arrow-callback": "error",
454
- "prefer-arrow-functions/prefer-arrow-functions": ["error", { singleReturnOnly: true, allowNamedFunctions: true }],
455
- "prefer-exponentiation-operator": "error",
456
- "prefer-object-spread": "error",
457
- "prefer-promise-reject-errors": "error",
458
- "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
459
- "prefer-rest-params": "error",
460
- "prefer-spread": "error",
461
- "prefer-template": "error",
462
- "symbol-description": "error",
463
- "unicode-bom": ["error", "never"],
464
- "unused-imports/no-unused-imports": IS_IN_EDITOR ? "off" : "error",
465
- "unused-imports/no-unused-vars": [
466
- "error",
467
- {
468
- args: "after-used",
469
- argsIgnorePattern: "^_",
470
- ignoreRestSiblings: true,
471
- vars: "all",
472
- varsIgnorePattern: "^_"
473
- }
474
- ],
475
- "use-isnan": ["error", { enforceForIndexOf: true }],
476
- "valid-typeof": ["error", { requireStringLiterals: true }],
477
- "vars-on-top": "error",
478
- yoda: ["error", "never", { exceptRange: true }],
479
- "import-x/consistent-type-specifier-style": ["error", "prefer-top-level"],
480
- "import-x/default": "error",
481
- "import-x/export": "error",
482
- "import-x/first": "error",
483
- "import-x/newline-after-import": ["error", { considerComments: true }],
484
- "import-x/no-absolute-path": "error",
485
- "import-x/no-duplicates": "error",
486
- "import-x/no-empty-named-blocks": "error",
487
- "import-x/no-extraneous-dependencies": "error",
488
- "import-x/no-mutable-exports": "error",
489
- "import-x/no-named-as-default": "warn",
490
- "import-x/no-named-as-default-member": "warn",
491
- "import-x/no-named-default": "error",
492
- "import-x/no-self-import": "error",
493
- "import-x/no-useless-path-segments": "error",
494
- "import-x/no-webpack-loader-syntax": "error",
495
946
  "perfectionist/sort-exports": ["error", { order: "asc", type: "natural" }],
496
947
  "perfectionist/sort-imports": [
497
948
  "error",
498
949
  {
499
950
  groups: SORT_IMPORT_GROUPS,
500
- tsconfigRootDir: process.cwd(),
951
+ tsconfigRootDir: getWorkspaceRoot(process__default.cwd(), process__default.cwd()),
501
952
  order: "asc",
502
- type: "natural"
953
+ type: "natural",
954
+ newlinesBetween: "never"
503
955
  }
504
956
  ],
505
957
  "perfectionist/sort-intersection-types": [
@@ -520,402 +972,1025 @@ var base_default = import_typescript_eslint2.default.config(
520
972
  order: "asc",
521
973
  type: "natural"
522
974
  }
523
- ],
524
- "unicorn/catch-error-name": "error",
525
- "unicorn/consistent-empty-array-spread": "error",
526
- "unicorn/consistent-existence-index-check": "error",
527
- "unicorn/consistent-function-scoping": ["error", { checkArrowFunctions: false }],
528
- "unicorn/custom-error-definition": "error",
529
- "unicorn/error-message": "error",
530
- "unicorn/escape-case": "error",
531
- "unicorn/explicit-length-check": "error",
532
- "unicorn/filename-case": ["error", { case: "kebabCase" }],
533
- "unicorn/new-for-builtins": "error",
534
- "unicorn/no-abusive-eslint-disable": "error",
535
- "unicorn/no-anonymous-default-export": "error",
536
- "unicorn/no-array-for-each": "error",
537
- "unicorn/no-array-method-this-argument": "error",
538
- "unicorn/no-array-push-push": "error",
539
- "unicorn/no-array-reduce": "error",
540
- "unicorn/no-await-expression-member": "error",
541
- "unicorn/no-await-in-promise-methods": "error",
542
- "unicorn/no-document-cookie": "error",
543
- "unicorn/no-empty-file": "error",
544
- "unicorn/no-for-loop": "error",
545
- "unicorn/no-hex-escape": "error",
546
- "unicorn/no-instanceof-array": "error",
547
- "unicorn/no-invalid-fetch-options": "error",
548
- "unicorn/no-invalid-remove-event-listener": "error",
549
- "unicorn/no-length-as-slice-end": "error",
550
- "unicorn/no-lonely-if": "error",
551
- "unicorn/no-magic-array-flat-depth": "error",
552
- "unicorn/no-negated-condition": "error",
553
- "unicorn/no-negation-in-equality-check": "error",
554
- "unicorn/no-new-array": "error",
555
- "unicorn/no-new-buffer": "error",
556
- "unicorn/no-null": "error",
557
- "unicorn/no-process-exit": "error",
558
- "unicorn/no-single-promise-in-promise-methods": "error",
559
- "unicorn/no-thenable": "error",
560
- "unicorn/no-this-assignment": "error",
561
- "unicorn/no-typeof-undefined": "error",
562
- "unicorn/no-unnecessary-await": "error",
563
- "unicorn/no-unused-properties": "warn",
564
- "unicorn/no-useless-fallback-in-spread": "error",
565
- "unicorn/no-useless-length-check": "error",
566
- "unicorn/no-useless-promise-resolve-reject": "error",
567
- "unicorn/no-useless-spread": "error",
568
- "unicorn/no-useless-switch-case": "error",
569
- "unicorn/no-zero-fractions": "error",
570
- "unicorn/number-literal-case": "error",
571
- "unicorn/numeric-separators-style": "error",
572
- "unicorn/prefer-array-find": "error",
573
- "unicorn/prefer-array-flat": "error",
574
- "unicorn/prefer-array-flat-map": "error",
575
- "unicorn/prefer-array-index-of": "error",
576
- "unicorn/prefer-array-some": "error",
577
- "unicorn/prefer-at": "error",
578
- "unicorn/prefer-blob-reading-methods": "error",
579
- "unicorn/prefer-code-point": "error",
580
- "unicorn/prefer-date-now": "error",
581
- "unicorn/prefer-default-parameters": "error",
582
- "unicorn/prefer-export-from": "error",
583
- "unicorn/prefer-includes": "error",
584
- "unicorn/prefer-keyboard-event-key": "error",
585
- "unicorn/prefer-logical-operator-over-ternary": "error",
586
- "unicorn/prefer-math-min-max": "error",
587
- "unicorn/prefer-math-trunc": "error",
588
- "unicorn/prefer-modern-math-apis": "error",
589
- "unicorn/prefer-negative-index": "error",
590
- "unicorn/prefer-node-protocol": "error",
591
- "unicorn/prefer-number-properties": "error",
592
- "unicorn/prefer-object-from-entries": "error",
593
- "unicorn/prefer-optional-catch-binding": "error",
594
- "unicorn/prefer-query-selector": "error",
595
- "unicorn/prefer-regexp-test": "error",
596
- "unicorn/prefer-set-has": "error",
597
- "unicorn/prefer-set-size": "error",
598
- "unicorn/prefer-spread": "error",
599
- "unicorn/prefer-string-raw": "error",
600
- "unicorn/prefer-string-replace-all": "error",
601
- "unicorn/prefer-string-slice": "error",
602
- "unicorn/prefer-string-starts-ends-with": "error",
603
- "unicorn/prefer-string-trim-start-end": "error",
604
- "unicorn/prefer-structured-clone": "error",
605
- "unicorn/prefer-switch": "error",
606
- "unicorn/prefer-ternary": "error",
607
- "unicorn/prefer-type-error": "error",
608
- "unicorn/require-array-join-separator": "error",
609
- "unicorn/require-number-to-fixed-digits-argument": "error",
610
- "unicorn/require-post-message-target-origin": "error",
611
- "unicorn/throw-new-error": "error"
975
+ ]
612
976
  }
613
- },
614
- {
615
- name: "fabdeh/base/javascript-rules",
616
- files: [GLOB_JS],
617
- extends: [import_eslint_plugin2.default.configs["flat/javascript"], import_eslint_plugin_jsdoc.default.configs["flat/recommended"]],
618
- rules: {
619
- "@typescript-eslint/no-empty-interface": "off",
620
- // deprecated but included in nx
621
- "import-x/named": "error",
622
- "import-x/no-deprecated": "error"
623
- }
624
- },
625
- {
626
- name: "fabdeh/base/typescript-rules",
627
- files: [GLOB_TS],
628
- extends: [
629
- import_typescript_eslint2.default.configs.strictTypeChecked,
630
- import_typescript_eslint2.default.configs.stylisticTypeChecked,
631
- import_eslint_plugin2.default.configs["flat/typescript"],
632
- import_eslint_plugin_jsdoc.default.configs["flat/recommended-typescript"]
633
- ],
977
+ });
978
+ }
979
+
980
+ function sortPackageJson() {
981
+ return tseslint__default.config({
982
+ name: "fabdeh/sort/package-json",
983
+ files: ["**/package.json"],
634
984
  rules: {
635
- "@typescript-eslint/array-type": ["error", { default: "array" }],
636
- "@typescript-eslint/consistent-indexed-object-style": "error",
637
- "@typescript-eslint/consistent-type-assertions": [
985
+ "jsonc/sort-array-values": [
638
986
  "error",
639
- { assertionStyle: "as", objectLiteralTypeAssertions: "never" }
987
+ {
988
+ order: { type: "asc" },
989
+ pathPattern: "^files$"
990
+ }
640
991
  ],
641
- "@typescript-eslint/consistent-type-definitions": ["error", "interface"],
642
- "@typescript-eslint/dot-notation": "error",
643
- "@typescript-eslint/explicit-function-return-type": [
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": [
644
1088
  "error",
645
1089
  {
646
- allowExpressions: true,
647
- allowTypedFunctionExpressions: true,
648
- allowHigherOrderFunctions: true,
649
- allowDirectConstAssertionInArrowFunctions: true,
650
- allowConciseArrowFunctionExpressionsStartingWithVoid: true
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$"
651
1201
  }
652
- ],
653
- "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }],
654
- "@typescript-eslint/member-ordering": ["error", member_ordering_default],
655
- "@typescript-eslint/method-signature-style": "error",
656
- "@typescript-eslint/naming-convention": ["error", ...naming_convention_default],
657
- "@typescript-eslint/no-base-to-string": "error",
658
- "@typescript-eslint/no-confusing-non-null-assertion": "error",
659
- "@typescript-eslint/no-confusing-void-expression": ["error", { ignoreArrowShorthand: true }],
660
- "@typescript-eslint/no-empty-interface": "off",
661
- // deprecated but included in nx
662
- "@typescript-eslint/no-extra-non-null-assertion": "error",
663
- "@typescript-eslint/no-extraneous-class": ["error", { allowStaticOnly: true, allowWithDecorator: true }],
664
- "@typescript-eslint/no-invalid-void-type": "error",
665
- "@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
666
- "@typescript-eslint/no-require-imports": "error",
667
- "@typescript-eslint/only-throw-error": "error",
668
- "@typescript-eslint/no-unnecessary-condition": "error",
669
- "@typescript-eslint/no-unnecessary-type-arguments": "error",
670
- "@typescript-eslint/no-unsafe-unary-minus": "error",
671
- "@typescript-eslint/parameter-properties": ["error", { prefer: "parameter-property" }],
672
- "@typescript-eslint/prefer-enum-initializers": "error",
673
- "@typescript-eslint/prefer-for-of": "error",
674
- "@typescript-eslint/prefer-function-type": "error",
675
- "@typescript-eslint/prefer-includes": "error",
676
- "@typescript-eslint/prefer-literal-enum-member": "error",
677
- "@typescript-eslint/prefer-nullish-coalescing": "error",
678
- "@typescript-eslint/prefer-optional-chain": "error",
679
- "@typescript-eslint/prefer-readonly": "error",
680
- "@typescript-eslint/prefer-reduce-type-parameter": "error",
681
- "@typescript-eslint/prefer-return-this-type": "error",
682
- "@typescript-eslint/prefer-string-starts-ends-with": "error",
683
- "@typescript-eslint/require-array-sort-compare": "error",
684
- "@typescript-eslint/restrict-plus-operands": ["error", { skipCompoundAssignments: true }],
685
- "@typescript-eslint/restrict-template-expressions": "off",
686
- "@typescript-eslint/switch-exhaustiveness-check": "error",
687
- "@typescript-eslint/unbound-method": ["error", { ignoreStatic: true }],
688
- "@typescript-eslint/unified-signatures": "error",
689
- "import-x/named": "off",
690
- "import-x/no-deprecated": "off"
1202
+ ]
691
1203
  }
692
- }
693
- );
1204
+ });
1205
+ }
694
1206
 
695
- // src/configs/jest.ts
696
- var import_eslint_plugin_jest = __toESM(require("eslint-plugin-jest"), 1);
697
- var import_eslint_plugin_jest_dom = __toESM(require("eslint-plugin-jest-dom"), 1);
698
- var import_eslint_plugin_testing_library = __toESM(require("eslint-plugin-testing-library"), 1);
699
- var import_globals2 = __toESM(require("globals"), 1);
700
- var import_typescript_eslint3 = __toESM(require("typescript-eslint"), 1);
701
- var jest_default = import_typescript_eslint3.default.config({
702
- name: "fabdeh/jest/rules",
703
- plugins: {
704
- jest: import_eslint_plugin_jest.default
705
- },
706
- languageOptions: {
707
- globals: {
708
- ...import_globals2.default.node,
709
- ...import_globals2.default.jest
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" } }]
710
1228
  }
711
- },
712
- files: [...GLOB_TESTS, `**/jest.config.${GLOB_SRC_EXT}`],
713
- extends: [
714
- import_eslint_plugin_jest.default.configs["flat/recommended"],
715
- import_eslint_plugin_jest.default.configs["flat/style"],
716
- import_eslint_plugin_jest_dom.default.configs["flat/recommended"],
717
- import_eslint_plugin_testing_library.default.configs["flat/angular"]
718
- ],
719
- rules: {
720
- "max-classes-per-file": "off",
721
- "max-lines": "off",
722
- "@typescript-eslint/consistent-type-assertions": "off",
723
- "@typescript-eslint/no-empty-function": "off",
724
- "@typescript-eslint/no-unsafe-assignment": "off",
725
- "@typescript-eslint/no-unsafe-call": "off",
726
- "@typescript-eslint/no-unsafe-member-access": "off",
727
- "@typescript-eslint/unbound-method": "off",
728
- "jest/consistent-test-it": ["error", { fn: "test" }],
729
- "jest/prefer-spy-on": "error",
730
- "jest/require-top-level-describe": "error",
731
- "jest/unbound-method": "error",
732
- "unicorn/no-null": "off"
733
- }
734
- });
1229
+ });
1230
+ }
735
1231
 
736
- // src/configs/ngrx/index.ts
737
- var ngrx_exports = {};
738
- __export(ngrx_exports, {
739
- effects: () => effects_default,
740
- signals: () => signals_default,
741
- store: () => store_default
742
- });
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
+ }
743
1249
 
744
- // src/configs/ngrx/effects.ts
745
- var import_v9 = __toESM(require("@ngrx/eslint-plugin/v9"), 1);
746
- var import_typescript_eslint4 = __toESM(require("typescript-eslint"), 1);
747
- var effects_default = import_typescript_eslint4.default.config({
748
- name: "fabdeh/ngrx-effects/rules",
749
- files: [`**/*.effects.${GLOB_TS_EXT}`],
750
- extends: [import_v9.default.configs.effects, import_v9.default.configs.operators],
751
- rules: {
752
- "@typescript-eslint/naming-convention": [
753
- "error",
754
- ...naming_convention_default,
755
- {
756
- selector: "variable",
757
- modifiers: ["const", "global", "exported"],
758
- format: ["camelCase"],
759
- leadingUnderscore: "forbid",
760
- trailingUnderscore: "forbid",
761
- suffix: ["$"]
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
762
1266
  }
763
- ]
764
- }
765
- });
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
+ }
766
1302
 
767
- // src/configs/ngrx/signals.ts
768
- var import_v92 = __toESM(require("@ngrx/eslint-plugin/v9"), 1);
769
- var import_typescript_eslint5 = __toESM(require("typescript-eslint"), 1);
770
- function allowLeadingUnderscoreOnMemberLike(conventions) {
771
- return [
772
- ...conventions.filter((c) => !Array.isArray(c.selector)),
773
- { selector: "variableLike", format: ["camelCase"] },
774
- { selector: "memberLike", format: ["camelCase"], leadingUnderscore: "allow" }
775
- ];
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
+ );
776
1406
  }
777
- var signals_default = import_typescript_eslint5.default.config({
778
- name: "fabdeh/ngrx-signals/rules",
779
- files: [`**/*.store.${GLOB_TS_EXT}`],
780
- extends: [import_v92.default.configs.signals, import_v92.default.configs.operators],
781
- rules: {
782
- "@typescript-eslint/naming-convention": [
783
- "error",
784
- ...allowLeadingUnderscoreOnMemberLike(naming_convention_default),
785
- {
786
- selector: "variable",
787
- modifiers: ["const", "global", "exported"],
788
- format: ["PascalCase"],
789
- leadingUnderscore: "forbid",
790
- trailingUnderscore: "forbid"
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
791
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 ?? []
792
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
+ };
793
1649
  }
794
- });
795
-
796
- // src/configs/ngrx/store.ts
797
- var import_v93 = __toESM(require("@ngrx/eslint-plugin/v9"), 1);
798
- var import_typescript_eslint6 = __toESM(require("typescript-eslint"), 1);
799
- var store_default = import_typescript_eslint6.default.config({
800
- name: "fabdeh/ngrx-store/rules",
801
- files: [
802
- `**/*.actions.${GLOB_TS_EXT}`,
803
- `**/*.feature.${GLOB_TS_EXT}`,
804
- `**/*.reducer.${GLOB_TS_EXT}`,
805
- `**/*.state.${GLOB_TS_EXT}`
806
- ],
807
- extends: [import_v93.default.configs.store, import_v93.default.configs.operators],
808
- rules: {
809
- "@typescript-eslint/naming-convention": [
810
- "error",
811
- ...naming_convention_default,
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(
812
1690
  {
813
- selector: ["objectLiteralProperty"],
814
- // eslint-disable-next-line unicorn/no-null
815
- format: null,
816
- custom: {
817
- regex: String.raw`^(?:(?:[a-z]+(?:[A-Z][a-z]*)*)|[A-Z][a-z]*(?:\s[A-Z][a-z]*)*)$`,
818
- match: true
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
+ ]
819
1701
  }
820
1702
  },
821
1703
  {
822
- selector: "variable",
823
- modifiers: ["const", "global", "exported"],
824
- format: ["camelCase", "PascalCase"],
825
- leadingUnderscore: "forbid",
826
- trailingUnderscore: "forbid"
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
+ }
827
1728
  }
828
- ]
1729
+ );
829
1730
  }
830
- });
831
-
832
- // src/configs/tailwindcss.ts
833
- var import_eslint_plugin_tailwindcss = __toESM(require("eslint-plugin-tailwindcss"), 1);
834
- var import_typescript_eslint7 = __toESM(require("typescript-eslint"), 1);
835
- var tailwindcss_default = import_typescript_eslint7.default.config({
836
- name: "fabdeh/tailwindcss/rules",
837
- plugins: {
838
- tailwindcss: import_eslint_plugin_tailwindcss.default
839
- },
840
- files: [GLOB_SRC, GLOB_HTML],
841
- rules: {
842
- "tailwindcss/classnames-order": "error",
843
- // replace by prettier plugin ???
844
- "tailwindcss/enforces-negative-arbitrary-values": "error",
845
- "tailwindcss/enforces-shorthand": "error",
846
- "tailwindcss/no-contradicting-classname": "error",
847
- "tailwindcss/no-unnecessary-arbitrary-value": "error"
848
- }
849
- });
850
-
851
- // src/configs/vitest.ts
852
- var import_eslint_plugin4 = __toESM(require("@vitest/eslint-plugin"), 1);
853
- var import_eslint_plugin_jest_dom2 = __toESM(require("eslint-plugin-jest-dom"), 1);
854
- var import_eslint_plugin_testing_library2 = __toESM(require("eslint-plugin-testing-library"), 1);
855
- var import_globals3 = __toESM(require("globals"), 1);
856
- var import_typescript_eslint8 = __toESM(require("typescript-eslint"), 1);
857
- var vitest_default = import_typescript_eslint8.default.config({
858
- name: "fabdeh/vitest/rules",
859
- plugins: {
860
- vitest: import_eslint_plugin4.default
861
- },
862
- languageOptions: {
863
- globals: {
864
- ...import_globals3.default.node,
865
- ...import_globals3.default.vitest,
866
- ...import_eslint_plugin4.default.environments.env.globals
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
+ });
867
1819
  }
868
- },
869
- settings: {
870
- vitest: {
871
- typecheck: true
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
+ );
872
1886
  }
873
- },
874
- files: [...GLOB_TESTS],
875
- extends: [import_eslint_plugin4.default.configs.recommended, import_eslint_plugin_jest_dom2.default.configs["flat/recommended"], import_eslint_plugin_testing_library2.default.configs["flat/angular"]],
876
- rules: {
877
- "max-classes-per-file": "off",
878
- "max-lines": "off",
879
- "@typescript-eslint/consistent-type-assertions": "off",
880
- "@typescript-eslint/no-empty-function": "off",
881
- "@typescript-eslint/no-unsafe-assignment": "off",
882
- "@typescript-eslint/no-unsafe-call": "off",
883
- "@typescript-eslint/no-unsafe-member-access": "off",
884
- "@typescript-eslint/unbound-method": "off",
885
- "unicorn/no-null": "off",
886
- "vitest/consistent-test-it": ["error", { fn: "test" }],
887
- "vitest/no-standalone-expect": "error",
888
- "vitest/no-test-return-statement": "error",
889
- "vitest/prefer-hooks-in-order": "error",
890
- "vitest/prefer-hooks-on-top": "error",
891
- "vitest/prefer-lowercase-title": "error",
892
- "vitest/prefer-spy-on": "error",
893
- "vitest/prefer-to-be": "error",
894
- "vitest/prefer-to-be-falsy": "error",
895
- "vitest/prefer-to-be-object": "error",
896
- "vitest/prefer-to-be-truthy": "error",
897
- "vitest/prefer-to-contain": "error",
898
- "vitest/prefer-to-have-length": "error",
899
- "vitest/prefer-todo": "error",
900
- "vitest/prefer-vi-mocked": "error",
901
- "vitest/require-top-level-describe": "error"
902
- }
903
- });
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.formatters) {
1950
+ configs.push(formatters(options.formatters, typeof stylisticOptions === "boolean" ? {} : stylisticOptions));
1951
+ }
1952
+ if ("files" in options) {
1953
+ 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.');
1954
+ }
1955
+ const fusedConfig = Object.fromEntries(
1956
+ Object.entries(options).filter(([k]) => FLAT_CONFIG_PROPS.includes(k))
1957
+ );
1958
+ if (Object.keys(fusedConfig).length > 0) {
1959
+ configs.push([fusedConfig]);
1960
+ }
1961
+ return tseslint__default.config(...await Promise.all(configs), ...await Promise.all(userConfigs));
1962
+ }
904
1963
 
905
- // src/index.ts
906
- var DEFAULT = { configs: configs_exports };
907
- var index_default = DEFAULT;
908
- // Annotate the CommonJS export names for ESM import in node:
909
- 0 && (module.exports = {
910
- GLOB_EXCLUDE,
911
- GLOB_HTML,
912
- GLOB_JS,
913
- GLOB_SRC,
914
- GLOB_SRC_EXT,
915
- GLOB_TESTS,
916
- GLOB_TS,
917
- GLOB_TS_EXT,
918
- dedupeTsBaseConfig,
919
- ensureCorrectFiles,
920
- isInEditorEnv
921
- });
1964
+ exports.GLOB_HTML = GLOB_HTML;
1965
+ exports.GLOB_JS = GLOB_JS;
1966
+ exports.GLOB_SRC = GLOB_SRC;
1967
+ exports.GLOB_TESTS = GLOB_TESTS;
1968
+ exports.GLOB_TS = GLOB_TS;
1969
+ exports.STYLISTIC_CONFIG_DEFAULT = STYLISTIC_CONFIG_DEFAULT;
1970
+ exports.angular = angular;
1971
+ exports.comments = comments;
1972
+ exports.createConfig = createConfig;
1973
+ exports.ensurePackages = ensurePackages;
1974
+ exports.getWorkspaceRoot = getWorkspaceRoot;
1975
+ exports.ignores = ignores;
1976
+ exports.imports = imports;
1977
+ exports.interopDefault = interopDefault;
1978
+ exports.isInEditorEnv = isInEditorEnv;
1979
+ exports.isPackageInScope = isPackageInScope;
1980
+ exports.javascript = javascript;
1981
+ exports.jest = jest;
1982
+ exports.jsdoc = jsdoc;
1983
+ exports.jsonc = jsonc;
1984
+ exports.markdown = markdown;
1985
+ exports.ngrx = ngrx;
1986
+ exports.perfectionist = perfectionist;
1987
+ exports.sortPackageJson = sortPackageJson;
1988
+ exports.sortTsConfig = sortTsConfig;
1989
+ exports.stylistic = stylistic;
1990
+ exports.tailwindcss = tailwindcss;
1991
+ exports.toArray = toArray;
1992
+ exports.toml = toml;
1993
+ exports.typescript = typescript;
1994
+ exports.unicorn = unicorn;
1995
+ exports.vitest = vitest;
1996
+ exports.yaml = yaml;