@fabdeh/eslint-config 0.12.1 → 0.13.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.
Files changed (3) hide show
  1. package/dist/index.d.mts +2618 -1476
  2. package/dist/index.mjs +72 -25
  3. package/package.json +55 -53
package/dist/index.mjs CHANGED
@@ -14,7 +14,7 @@ import { mergeProcessors, processorPassThrough } from "eslint-merge-processors";
14
14
  import nodePlugin from "eslint-plugin-n";
15
15
  import perfectionistPlugin from "eslint-plugin-perfectionist";
16
16
  import { readFile } from "node:fs/promises";
17
- import { findUp, findUpSync } from "find-up-simple";
17
+ import { up } from "empathic/find";
18
18
  import { configs } from "eslint-plugin-regexp";
19
19
  import unicornPlugin from "eslint-plugin-unicorn";
20
20
  import { FlatConfigComposer } from "eslint-flat-config-utils";
@@ -349,7 +349,8 @@ function getPlaywrightDirectory() {
349
349
  const match = /testDir:\s*["'](.+)["'],?/.exec(configContent);
350
350
  if (match) {
351
351
  const testDir = match[1];
352
- const resolvedTestDir = resolve(dirname(config), testDir);
352
+ const configDir = dirname(config);
353
+ const resolvedTestDir = resolve(configDir, testDir);
353
354
  if (isDirectory(resolvedTestDir)) return resolvedTestDir;
354
355
  }
355
356
  } catch {}
@@ -396,6 +397,7 @@ async function angular(options = {}) {
396
397
  "Output",
397
398
  "Pipe",
398
399
  "Self",
400
+ "Service",
399
401
  "SkipSelf",
400
402
  "ViewChild",
401
403
  "ViewChildren"
@@ -1519,7 +1521,7 @@ async function playwright(options = {}) {
1519
1521
  * @returns `true` when catalog configuration is present; otherwise `false`.
1520
1522
  */
1521
1523
  async function detectCatalogUsage() {
1522
- const workspaceFile = await findUp("pnpm-workspace.yaml");
1524
+ const workspaceFile = up("pnpm-workspace.yaml");
1523
1525
  if (!workspaceFile) return false;
1524
1526
  const yaml = await readFile(workspaceFile, "utf-8");
1525
1527
  return yaml.includes("catalog:") || yaml.includes("catalogs:");
@@ -2094,7 +2096,7 @@ const MEMBER_ORDERING_OPTIONS = { default: [
2094
2096
  * @returns A TypedConfig[] containing the TypeScript ESLint configuration.
2095
2097
  */
2096
2098
  async function typescript(options = {}, isWorkspaceProject = false) {
2097
- const { enableErasableSyntaxOnly = false, overrides = {}, parserOptions = {}, stylistic = true, type = "app", useRelaxedNamingConventionForCamelAndPascalCases = false } = options;
2099
+ const { enableErasableSyntaxOnly = false, overrides = {}, parserOptions = {}, stylistic = true, type = "app", useRelaxedNamingConventionForCamelAndPascalCases = false, allowJsx = false } = options;
2098
2100
  let erasableSyntaxOnlyPlugin;
2099
2101
  let erasableSyntaxOnlyRules;
2100
2102
  if (enableErasableSyntaxOnly) {
@@ -2160,7 +2162,7 @@ async function typescript(options = {}, isWorkspaceProject = false) {
2160
2162
  fixStyle: "separate-type-imports",
2161
2163
  prefer: "type-imports"
2162
2164
  }],
2163
- "@typescript-eslint/dot-notation": "error",
2165
+ "@typescript-eslint/dot-notation": ["error", { allowIndexSignaturePropertyAccess: true }],
2164
2166
  ...type === "lib" ? { "@typescript-eslint/explicit-function-return-type": ["error", {
2165
2167
  allowExpressions: true,
2166
2168
  allowIIFEs: true
@@ -2169,7 +2171,7 @@ async function typescript(options = {}, isWorkspaceProject = false) {
2169
2171
  ...type === "workspace" ? {} : { "@typescript-eslint/explicit-module-boundary-types": "error" },
2170
2172
  "@typescript-eslint/member-ordering": ["error", MEMBER_ORDERING_OPTIONS],
2171
2173
  "@typescript-eslint/method-signature-style": "error",
2172
- "@typescript-eslint/naming-convention": ["error", ...namingConvention(!useRelaxedNamingConventionForCamelAndPascalCases)],
2174
+ "@typescript-eslint/naming-convention": ["error", ...namingConvention(!useRelaxedNamingConventionForCamelAndPascalCases, allowJsx)],
2173
2175
  "@typescript-eslint/no-base-to-string": "error",
2174
2176
  "@typescript-eslint/no-confusing-non-null-assertion": "error",
2175
2177
  "@typescript-eslint/no-confusing-void-expression": ["error", { ignoreArrowShorthand: true }],
@@ -2462,6 +2464,47 @@ const NGRX_PACKAGES = [
2462
2464
  const PLAYWRIGHT_PACKAGES = ["@playwright/test", "playwright"];
2463
2465
  const OPTIONS_SYMBOL = Symbol("options");
2464
2466
  //#endregion
2467
+ //#region src/factories/playwright-config.ts
2468
+ /**
2469
+ * Creates an ESLint configuration array for Playwright projects based on the provided base configuration,
2470
+ * options and user configurations.
2471
+ * This function is designed for use in an end-to-end project of a workspace environment and extends a base configuration
2472
+ * that is already defined in the root of the workspace.
2473
+ *
2474
+ * @param baseConfig - The base configuration to extend from.
2475
+ * @param options - Playwright-specific configuration options.
2476
+ * @param userConfigs - Additional user configurations that can be awaited.
2477
+ * @returns The merged ESLint configurations.
2478
+ * @example
2479
+ * ```typescript
2480
+ * import { definePlaywrightConfig } from '@fabdeh/eslint-config';
2481
+ *
2482
+ * import baseConfig from '../../eslint.base.js';
2483
+ *
2484
+ * export default definePlaywrightConfig(baseConfig, { ignores: ['playwright-report/**'] });
2485
+ */
2486
+ function definePlaywrightConfig(baseConfig, options = {}, ...userConfigs) {
2487
+ if (PLAYWRIGHT_PACKAGES.every((p) => !isPackageExists(p))) throw new Error("Playwright rules require the \"playwright\" package to be installed.");
2488
+ let isInEditor = options.isInEditor;
2489
+ if (isInEditor === void 0) {
2490
+ isInEditor = isInEditorEnv();
2491
+ if (isInEditor) console.log("[@fabdeh/eslint-config] Detected running in editor, some rules are disabled.");
2492
+ }
2493
+ const workspaceOptions = baseConfig[OPTIONS_SYMBOL];
2494
+ const configs = [];
2495
+ if (options.ignores && options.ignores.length > 0) configs.push(ignores(options.ignores, "project"));
2496
+ if (workspaceOptions.typescript) configs.push(typescript({
2497
+ overrides: {},
2498
+ parserOptions: {},
2499
+ type: "app"
2500
+ }, true));
2501
+ configs.push(playwright(options));
2502
+ let composer = new FlatConfigComposer();
2503
+ composer = composer.append(baseConfig, ...configs, ...userConfigs);
2504
+ if (isInEditor) composer = composer.disableRulesFix(["prefer-const", "unused-imports/no-unused-imports"], { builtinRules: () => import("eslint/use-at-your-own-risk").then((m) => m.builtinRules) });
2505
+ return composer;
2506
+ }
2507
+ //#endregion
2465
2508
  //#region src/factories/project-config.ts
2466
2509
  /**
2467
2510
  * Creates an ESLint configuration array based on the provided base configuration, options and user configurations.
@@ -2546,7 +2589,7 @@ function defineProjectConfig(baseConfig, options = {}, ...userConfigs) {
2546
2589
  * ```
2547
2590
  */
2548
2591
  function defineConfig(options = {}, ...userConfigs) {
2549
- const { angular: enableAngular = isPackageExists("@angular/core"), gitignore: enableGitignore = true, jsdoc: enableJsdoc = options.type === "lib", ngrx: enableNgrx = NGRX_PACKAGES.some((p) => isPackageExists(p)), playwright: enablePlaywright = PLAYWRIGHT_PACKAGES.some((p) => isPackageExists(p)), pnpm: enableCatalogs = !!findUpSync("pnpm-workspace.yaml"), regexp: enableRegexp = true, tailwindcss: enableTailwind = false, typescript: enableTypescript = isPackageExists("typescript"), unicorn: enableUnicorn = true, vitest: enableVitest = isPackageExists("vitest") } = options;
2592
+ const { angular: enableAngular = isPackageExists("@angular/core"), gitignore: enableGitignore = true, jsdoc: enableJsdoc = options.type === "lib", ngrx: enableNgrx = NGRX_PACKAGES.some((p) => isPackageExists(p)), playwright: enablePlaywright = PLAYWRIGHT_PACKAGES.some((p) => isPackageExists(p)), pnpm: enableCatalogs = !!up("pnpm-workspace.yaml"), regexp: enableRegexp = true, tailwindcss: enableTailwind = false, typescript: enableTypescript = isPackageExists("typescript"), unicorn: enableUnicorn = true, vitest: enableVitest = isPackageExists("vitest") } = options;
2550
2593
  let isInEditor = options.isInEditor;
2551
2594
  if (isInEditor === void 0) {
2552
2595
  isInEditor = isInEditorEnv();
@@ -2555,14 +2598,16 @@ function defineConfig(options = {}, ...userConfigs) {
2555
2598
  if (enableNgrx && !enableAngular) throw new Error("NgRx rules can only be enabled if Angular rules are also enabled.");
2556
2599
  const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
2557
2600
  const configs = [];
2558
- if (enableGitignore) if (typeof enableGitignore === "object") configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2559
- name: "fabdeh/gitignore",
2560
- ...enableGitignore
2561
- })]));
2562
- else configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2563
- name: "fabdeh/gitignore",
2564
- strict: true
2565
- })]));
2601
+ if (enableGitignore) {
2602
+ if (typeof enableGitignore === "object") configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2603
+ name: "fabdeh/gitignore",
2604
+ ...enableGitignore
2605
+ })]));
2606
+ else configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2607
+ name: "fabdeh/gitignore",
2608
+ strict: true
2609
+ })]));
2610
+ }
2566
2611
  configs.push(ignores(options.ignores), javascript({
2567
2612
  isInEditor,
2568
2613
  overrides: options.javascript?.overrides
@@ -2677,7 +2722,7 @@ function defineConfig(options = {}, ...userConfigs) {
2677
2722
  * ```
2678
2723
  */
2679
2724
  function defineWorkspaceConfig(options = {}, ...userConfigs) {
2680
- const { gitignore: enableGitignore = true, pnpm: enableCatalogs = !!findUpSync("pnpm-workspace.yaml"), regexp: enableRegexp = true, typescript: enableTypescript = isPackageExists("typescript"), unicorn: enableUnicorn = true } = options;
2725
+ const { gitignore: enableGitignore = true, pnpm: enableCatalogs = !!up("pnpm-workspace.yaml"), regexp: enableRegexp = true, typescript: enableTypescript = isPackageExists("typescript"), unicorn: enableUnicorn = true } = options;
2681
2726
  let isInEditor = options.isInEditor;
2682
2727
  if (isInEditor === void 0) {
2683
2728
  isInEditor = isInEditorEnv();
@@ -2685,14 +2730,16 @@ function defineWorkspaceConfig(options = {}, ...userConfigs) {
2685
2730
  }
2686
2731
  const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
2687
2732
  const configs = [];
2688
- if (enableGitignore) if (typeof enableGitignore === "object") configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2689
- name: "fabdeh/gitignore",
2690
- ...enableGitignore
2691
- })]));
2692
- else configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2693
- name: "fabdeh/gitignore",
2694
- strict: true
2695
- })]));
2733
+ if (enableGitignore) {
2734
+ if (typeof enableGitignore === "object") configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2735
+ name: "fabdeh/gitignore",
2736
+ ...enableGitignore
2737
+ })]));
2738
+ else configs.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => [r({
2739
+ name: "fabdeh/gitignore",
2740
+ strict: true
2741
+ })]));
2742
+ }
2696
2743
  configs.push(ignores(options.ignores, "workspace"), javascript({
2697
2744
  isInEditor,
2698
2745
  overrides: options.javascript?.overrides
@@ -2756,4 +2803,4 @@ function defineWorkspaceConfig(options = {}, ...userConfigs) {
2756
2803
  return composerWithOptions;
2757
2804
  }
2758
2805
  //#endregion
2759
- export { CONFIG_PRESET_FULL_OFF, CONFIG_PRESET_FULL_ON, GLOB_HTML, GLOB_JS, GLOB_SRC, GLOB_TESTS, GLOB_TS, STYLISTIC_CONFIG_DEFAULT, angular, comments, convertPathToPosix, defineConfig, defineProjectConfig, defineWorkspaceConfig, ensurePackages, getPlaywrightDirectory, getTsConfigFileName, getWorkspaceRoot, ignores, imports, interopDefault, isDirectory, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsdoc, jsonc, markdown, ngrx, node, pathToGlobPattern, perfectionist, playwright, pnpm, regexp, resolveSubOptions, sortPackageJson, sortTsConfig, stylistic, tailwindcss, toml, typescript, unicorn, vitest, yaml };
2806
+ export { CONFIG_PRESET_FULL_OFF, CONFIG_PRESET_FULL_ON, GLOB_HTML, GLOB_JS, GLOB_SRC, GLOB_TESTS, GLOB_TS, STYLISTIC_CONFIG_DEFAULT, angular, comments, convertPathToPosix, defineConfig, definePlaywrightConfig, defineProjectConfig, defineWorkspaceConfig, ensurePackages, getPlaywrightDirectory, getTsConfigFileName, getWorkspaceRoot, ignores, imports, interopDefault, isDirectory, isInEditorEnv, isInGitHooksOrLintStaged, isPackageInScope, javascript, jsdoc, jsonc, markdown, ngrx, node, pathToGlobPattern, perfectionist, playwright, pnpm, regexp, resolveSubOptions, sortPackageJson, sortTsConfig, stylistic, tailwindcss, toml, typescript, unicorn, vitest, yaml };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fabdeh/eslint-config",
3
3
  "type": "module",
4
- "version": "0.12.1",
4
+ "version": "0.13.0",
5
5
  "description": "My personal eslint config preset",
6
6
  "author": {
7
7
  "name": "Fabien Dehopré",
@@ -37,8 +37,8 @@
37
37
  ],
38
38
  "peerDependencies": {
39
39
  "eslint": "^9.38.0 || ^10.0.0",
40
- "eslint-plugin-better-tailwindcss": "^4.5.0",
41
- "eslint-plugin-erasable-syntax-only": "^0.4.1"
40
+ "eslint-plugin-better-tailwindcss": "^4.7.0",
41
+ "eslint-plugin-erasable-syntax-only": "^0.4.2"
42
42
  },
43
43
  "peerDependenciesMeta": {
44
44
  "eslint-plugin-better-tailwindcss": {
@@ -49,82 +49,84 @@
49
49
  }
50
50
  },
51
51
  "dependencies": {
52
- "@antfu/install-pkg": "^1.1.0",
53
- "@clack/prompts": "^1.5.1",
52
+ "@antfu/install-pkg": "^2.0.1",
53
+ "@clack/prompts": "^1.7.0",
54
54
  "@eslint-community/eslint-plugin-eslint-comments": "^4.7.2",
55
- "@eslint/markdown": "^8.0.2",
55
+ "@eslint/markdown": "^8.0.3",
56
56
  "@ngrx/eslint-plugin": "^21.1.1",
57
57
  "@stylistic/eslint-plugin": "^5.10.0",
58
- "@typescript-eslint/eslint-plugin": "^8.61.0",
59
- "@typescript-eslint/parser": "^8.61.0",
60
- "@typescript-eslint/utils": "^8.61.0",
61
- "@vitest/eslint-plugin": "^1.6.19",
62
- "angular-eslint": "^22.0.0",
58
+ "@typescript-eslint/eslint-plugin": "^8.66.0",
59
+ "@typescript-eslint/parser": "^8.66.0",
60
+ "@typescript-eslint/utils": "^8.66.0",
61
+ "@vitest/eslint-plugin": "^1.6.27",
62
+ "angular-eslint": "^22.1.0",
63
+ "empathic": "^2.0.1",
63
64
  "eslint-config-flat-gitignore": "^2.3.0",
64
65
  "eslint-flat-config-utils": "^3.2.0",
65
66
  "eslint-merge-processors": "^2.0.0",
66
- "eslint-plugin-import-x": "^4.16.2",
67
+ "eslint-plugin-import-x": "^4.17.1",
67
68
  "eslint-plugin-jest-dom-ya": "^1.0.1",
68
- "eslint-plugin-jsdoc": "^63.0.2",
69
- "eslint-plugin-jsonc": "^3.2.0",
70
- "eslint-plugin-n": "^18.1.0",
71
- "eslint-plugin-perfectionist": "^5.9.0",
72
- "eslint-plugin-playwright": "^2.10.4",
73
- "eslint-plugin-pnpm": "^1.6.1",
74
- "eslint-plugin-prefer-arrow-functions": "^3.9.1",
75
- "eslint-plugin-regexp": "^3.1.0",
69
+ "eslint-plugin-jsdoc": "^63.3.3",
70
+ "eslint-plugin-jsonc": "^3.4.1",
71
+ "eslint-plugin-n": "^18.3.0",
72
+ "eslint-plugin-perfectionist": "^5.10.1",
73
+ "eslint-plugin-playwright": "^2.11.0",
74
+ "eslint-plugin-pnpm": "^1.7.0",
75
+ "eslint-plugin-prefer-arrow-functions": "^3.10.2",
76
+ "eslint-plugin-regexp": "^3.1.1",
76
77
  "eslint-plugin-testing-library": "^7.16.2",
77
- "eslint-plugin-toml": "^1.4.0",
78
+ "eslint-plugin-toml": "^1.5.0",
78
79
  "eslint-plugin-unicorn": "^65.0.1",
79
80
  "eslint-plugin-unused-imports": "^4.4.1",
80
- "eslint-plugin-yml": "^3.4.0",
81
- "find-up-simple": "^1.0.1",
81
+ "eslint-plugin-yml": "^3.8.1",
82
82
  "glob": "^13.0.6",
83
- "globals": "^17.6.0",
84
- "jsonc-eslint-parser": "^3.1.0",
83
+ "globals": "^17.9.0",
84
+ "jsonc-eslint-parser": "^3.3.0",
85
85
  "local-pkg": "^1.2.1",
86
- "typescript-eslint": "^8.61.0"
86
+ "typescript-eslint": "^8.66.0"
87
87
  },
88
88
  "devDependencies": {
89
- "@angular/core": "^22.0.0",
90
- "@arethetypeswrong/cli": "^0.18.3",
91
- "@commitlint/cli": "^21.0.2",
92
- "@commitlint/config-conventional": "^21.0.2",
93
- "@commitlint/cz-commitlint": "^21.0.2",
94
- "@commitlint/lint": "^21.0.2",
95
- "@commitlint/load": "^21.0.2",
89
+ "@angular/cli": "^22.1.3",
90
+ "@angular/core": "^22.1.1",
91
+ "@arethetypeswrong/cli": "^0.18.5",
92
+ "@commitlint/cli": "^21.2.1",
93
+ "@commitlint/config-conventional": "^21.2.0",
94
+ "@commitlint/cz-commitlint": "^21.2.0",
95
+ "@commitlint/lint": "^21.2.0",
96
+ "@commitlint/load": "^21.2.0",
96
97
  "@ngrx/effects": "^21.1.1",
97
98
  "@ngrx/operators": "^21.1.1",
98
99
  "@ngrx/signals": "^21.1.1",
99
100
  "@ngrx/store": "^21.1.1",
100
- "@testing-library/angular": "^19.4.1",
101
- "@testing-library/jest-dom": "^6.9.1",
101
+ "@testing-library/angular": "^19.4.2",
102
+ "@testing-library/dom": "^10.4.1",
103
+ "@testing-library/jest-dom": "^7.0.1",
102
104
  "@types/fs-extra": "^11.0.4",
103
- "@types/node": "^24.13.1",
104
- "@vitest/coverage-v8": "^4.1.8",
105
- "@vitest/ui": "^4.1.8",
106
- "bumpp": "^11.1.0",
105
+ "@types/node": "^24.13.3",
106
+ "@vitest/coverage-v8": "^4.1.10",
107
+ "@vitest/ui": "^4.1.10",
108
+ "bumpp": "^12.2.0",
107
109
  "change-case": "^5.4.4",
108
- "changelogithub": "^14.0.0",
109
- "commitizen": "^4.3.1",
110
- "eslint": "^10.4.1",
111
- "eslint-plugin-better-tailwindcss": "^4.5.0",
112
- "eslint-plugin-erasable-syntax-only": "^0.4.1",
110
+ "changelogithub": "^15.0.4",
111
+ "commitizen": "^4.3.2",
112
+ "eslint": "^10.8.1",
113
+ "eslint-plugin-better-tailwindcss": "^4.7.0",
114
+ "eslint-plugin-erasable-syntax-only": "^0.4.2",
113
115
  "eslint-typegen": "^2.3.1",
114
- "execa": "^9.6.1",
115
- "fs-extra": "^11.3.5",
116
+ "execa": "^10.0.1",
117
+ "fs-extra": "^11.4.0",
116
118
  "is-ci": "^4.1.0",
117
119
  "jiti": "^2.7.0",
118
120
  "nano-staged": "^1.0.2",
119
- "playwright": "^1.60.0",
120
- "semver": "^7.8.3",
121
+ "playwright": "^1.62.1",
122
+ "semver": "^7.8.5",
121
123
  "simple-git-hooks": "^2.13.1",
122
- "tailwindcss": "^4.3.0",
123
- "tsdown": "^0.22.2",
124
- "tsx": "^4.22.4",
124
+ "tailwindcss": "^4.3.3",
125
+ "tsdown": "^0.22.14",
126
+ "tsx": "^4.23.12",
125
127
  "typescript": "^6.0.3",
126
- "vitest": "^4.1.8",
127
- "@fabdeh/eslint-config": "0.12.1"
128
+ "vitest": "^4.1.10",
129
+ "@fabdeh/eslint-config": "0.13.0"
128
130
  },
129
131
  "simple-git-hooks": {
130
132
  "pre-commit": "pnpm nano-staged",