@fabdeh/eslint-config 0.7.0 → 0.8.0-beta.1

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.ts +209 -109
  2. package/dist/index.js +196 -48
  3. package/package.json +7 -4
package/dist/index.d.ts CHANGED
@@ -297,6 +297,11 @@ interface RuleOptions {
297
297
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-duplicate-attributes.md
298
298
  */
299
299
  '@angular-eslint/template/no-duplicate-attributes'?: Linter.RuleEntry<AngularEslintTemplateNoDuplicateAttributes>;
300
+ /**
301
+ * Ensures that control flow blocks are not empty. Empty control flow blocks usually occur due to refactoring that wasn't completed. They can cause confusion when reading code.
302
+ * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-empty-control-flow.md
303
+ */
304
+ '@angular-eslint/template/no-empty-control-flow'?: Linter.RuleEntry<[]>;
300
305
  /**
301
306
  * Disallows the use of inline styles in HTML templates
302
307
  * @see https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/docs/rules/no-inline-styles.md
@@ -629,8 +634,9 @@ interface RuleOptions {
629
634
  */
630
635
  '@stylistic/jsx-pascal-case'?: Linter.RuleEntry<StylisticJsxPascalCase>;
631
636
  /**
632
- * Disallow multiple spaces between inline JSX props
637
+ * Disallow multiple spaces between inline JSX props. Deprecated, use `no-multi-spaces` rule instead.
633
638
  * @see https://eslint.style/rules/jsx-props-no-multi-spaces
639
+ * @deprecated
634
640
  */
635
641
  '@stylistic/jsx-props-no-multi-spaces'?: Linter.RuleEntry<[]>;
636
642
  /**
@@ -2802,7 +2808,7 @@ interface RuleOptions {
2802
2808
  * Enforce heading levels increment by one
2803
2809
  * @see https://github.com/eslint/markdown/blob/main/docs/rules/heading-increment.md
2804
2810
  */
2805
- 'markdown/heading-increment'?: Linter.RuleEntry<[]>;
2811
+ 'markdown/heading-increment'?: Linter.RuleEntry<MarkdownHeadingIncrement>;
2806
2812
  /**
2807
2813
  * Disallow bare URLs
2808
2814
  * @see https://github.com/eslint/markdown/blob/main/docs/rules/no-bare-urls.md
@@ -2847,7 +2853,7 @@ interface RuleOptions {
2847
2853
  * Disallow headings without a space after the hash characters
2848
2854
  * @see https://github.com/eslint/markdown/blob/main/docs/rules/no-missing-atx-heading-space.md
2849
2855
  */
2850
- 'markdown/no-missing-atx-heading-space'?: Linter.RuleEntry<[]>;
2856
+ 'markdown/no-missing-atx-heading-space'?: Linter.RuleEntry<MarkdownNoMissingAtxHeadingSpace>;
2851
2857
  /**
2852
2858
  * Disallow missing label references
2853
2859
  * @see https://github.com/eslint/markdown/blob/main/docs/rules/no-missing-label-refs.md
@@ -2868,6 +2874,11 @@ interface RuleOptions {
2868
2874
  * @see https://github.com/eslint/markdown/blob/main/docs/rules/no-reversed-media-syntax.md
2869
2875
  */
2870
2876
  'markdown/no-reversed-media-syntax'?: Linter.RuleEntry<[]>;
2877
+ /**
2878
+ * Disallow spaces around emphasis markers
2879
+ * @see https://github.com/eslint/markdown/blob/main/docs/rules/no-space-in-emphasis.md
2880
+ */
2881
+ 'markdown/no-space-in-emphasis'?: Linter.RuleEntry<MarkdownNoSpaceInEmphasis>;
2871
2882
  /**
2872
2883
  * Disallow unused definitions
2873
2884
  * @see https://github.com/eslint/markdown/blob/main/docs/rules/no-unused-definitions.md
@@ -5963,6 +5974,11 @@ interface RuleOptions {
5963
5974
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-expect-resolves.md
5964
5975
  */
5965
5976
  'vitest/prefer-expect-resolves'?: Linter.RuleEntry<[]>;
5977
+ /**
5978
+ * enforce using `expectTypeOf` instead of `expect(typeof ...)`
5979
+ * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-expect-type-of.md
5980
+ */
5981
+ 'vitest/prefer-expect-type-of'?: Linter.RuleEntry<[]>;
5966
5982
  /**
5967
5983
  * enforce having hooks in consistent order
5968
5984
  * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-in-order.md
@@ -6410,7 +6426,6 @@ type AngularEslintTemplatePreferContextualForVariables = [] | [{
6410
6426
  $last?: string[];
6411
6427
  $even?: string[];
6412
6428
  $odd?: string[];
6413
- [k: string]: unknown | undefined;
6414
6429
  };
6415
6430
  }];
6416
6431
  // ----- @angular-eslint/template/use-track-by-function -----
@@ -6658,6 +6673,7 @@ type StylisticIndent = [] | [("tab" | number)] | [("tab" | number), {
6658
6673
  const?: (number | ("first" | "off"));
6659
6674
  using?: (number | ("first" | "off"));
6660
6675
  });
6676
+ assignmentOperator?: (number | "off");
6661
6677
  outerIIFEBody?: (number | "off");
6662
6678
  MemberExpression?: (number | "off");
6663
6679
  FunctionDeclaration?: {
@@ -6890,6 +6906,22 @@ type StylisticKeywordSpacing = [] | [{
6890
6906
  before?: boolean;
6891
6907
  after?: boolean;
6892
6908
  };
6909
+ arguments?: {
6910
+ before?: boolean;
6911
+ after?: boolean;
6912
+ };
6913
+ as?: {
6914
+ before?: boolean;
6915
+ after?: boolean;
6916
+ };
6917
+ async?: {
6918
+ before?: boolean;
6919
+ after?: boolean;
6920
+ };
6921
+ await?: {
6922
+ before?: boolean;
6923
+ after?: boolean;
6924
+ };
6893
6925
  boolean?: {
6894
6926
  before?: boolean;
6895
6927
  after?: boolean;
@@ -6954,6 +6986,10 @@ type StylisticKeywordSpacing = [] | [{
6954
6986
  before?: boolean;
6955
6987
  after?: boolean;
6956
6988
  };
6989
+ eval?: {
6990
+ before?: boolean;
6991
+ after?: boolean;
6992
+ };
6957
6993
  export?: {
6958
6994
  before?: boolean;
6959
6995
  after?: boolean;
@@ -6982,10 +7018,18 @@ type StylisticKeywordSpacing = [] | [{
6982
7018
  before?: boolean;
6983
7019
  after?: boolean;
6984
7020
  };
7021
+ from?: {
7022
+ before?: boolean;
7023
+ after?: boolean;
7024
+ };
6985
7025
  function?: {
6986
7026
  before?: boolean;
6987
7027
  after?: boolean;
6988
7028
  };
7029
+ get?: {
7030
+ before?: boolean;
7031
+ after?: boolean;
7032
+ };
6989
7033
  goto?: {
6990
7034
  before?: boolean;
6991
7035
  after?: boolean;
@@ -7018,6 +7062,10 @@ type StylisticKeywordSpacing = [] | [{
7018
7062
  before?: boolean;
7019
7063
  after?: boolean;
7020
7064
  };
7065
+ let?: {
7066
+ before?: boolean;
7067
+ after?: boolean;
7068
+ };
7021
7069
  long?: {
7022
7070
  before?: boolean;
7023
7071
  after?: boolean;
@@ -7034,6 +7082,10 @@ type StylisticKeywordSpacing = [] | [{
7034
7082
  before?: boolean;
7035
7083
  after?: boolean;
7036
7084
  };
7085
+ of?: {
7086
+ before?: boolean;
7087
+ after?: boolean;
7088
+ };
7037
7089
  package?: {
7038
7090
  before?: boolean;
7039
7091
  after?: boolean;
@@ -7054,6 +7106,10 @@ type StylisticKeywordSpacing = [] | [{
7054
7106
  before?: boolean;
7055
7107
  after?: boolean;
7056
7108
  };
7109
+ set?: {
7110
+ before?: boolean;
7111
+ after?: boolean;
7112
+ };
7057
7113
  short?: {
7058
7114
  before?: boolean;
7059
7115
  after?: boolean;
@@ -7098,59 +7154,43 @@ type StylisticKeywordSpacing = [] | [{
7098
7154
  before?: boolean;
7099
7155
  after?: boolean;
7100
7156
  };
7101
- typeof?: {
7102
- before?: boolean;
7103
- after?: boolean;
7104
- };
7105
- var?: {
7106
- before?: boolean;
7107
- after?: boolean;
7108
- };
7109
- void?: {
7110
- before?: boolean;
7111
- after?: boolean;
7112
- };
7113
- volatile?: {
7114
- before?: boolean;
7115
- after?: boolean;
7116
- };
7117
- while?: {
7157
+ type?: {
7118
7158
  before?: boolean;
7119
7159
  after?: boolean;
7120
7160
  };
7121
- with?: {
7161
+ typeof?: {
7122
7162
  before?: boolean;
7123
7163
  after?: boolean;
7124
7164
  };
7125
- accessor?: {
7165
+ using?: {
7126
7166
  before?: boolean;
7127
7167
  after?: boolean;
7128
7168
  };
7129
- as?: {
7169
+ var?: {
7130
7170
  before?: boolean;
7131
7171
  after?: boolean;
7132
7172
  };
7133
- async?: {
7173
+ void?: {
7134
7174
  before?: boolean;
7135
7175
  after?: boolean;
7136
7176
  };
7137
- await?: {
7177
+ volatile?: {
7138
7178
  before?: boolean;
7139
7179
  after?: boolean;
7140
7180
  };
7141
- from?: {
7181
+ while?: {
7142
7182
  before?: boolean;
7143
7183
  after?: boolean;
7144
7184
  };
7145
- get?: {
7185
+ with?: {
7146
7186
  before?: boolean;
7147
7187
  after?: boolean;
7148
7188
  };
7149
- let?: {
7189
+ yield?: {
7150
7190
  before?: boolean;
7151
7191
  after?: boolean;
7152
7192
  };
7153
- of?: {
7193
+ accessor?: {
7154
7194
  before?: boolean;
7155
7195
  after?: boolean;
7156
7196
  };
@@ -7158,22 +7198,6 @@ type StylisticKeywordSpacing = [] | [{
7158
7198
  before?: boolean;
7159
7199
  after?: boolean;
7160
7200
  };
7161
- set?: {
7162
- before?: boolean;
7163
- after?: boolean;
7164
- };
7165
- using?: {
7166
- before?: boolean;
7167
- after?: boolean;
7168
- };
7169
- yield?: {
7170
- before?: boolean;
7171
- after?: boolean;
7172
- };
7173
- type?: {
7174
- before?: boolean;
7175
- after?: boolean;
7176
- };
7177
7201
  };
7178
7202
  }];
7179
7203
  // ----- @stylistic/line-comment-position -----
@@ -7373,6 +7397,7 @@ type StylisticNoExtraParens = ([] | ["functions"] | [] | ["all"] | ["all", {
7373
7397
  LogicalExpression?: boolean;
7374
7398
  AwaitExpression?: boolean;
7375
7399
  };
7400
+ ignoredNodes?: string[];
7376
7401
  }]);
7377
7402
  // ----- @stylistic/no-mixed-operators -----
7378
7403
  type StylisticNoMixedOperators = [] | [{
@@ -7488,7 +7513,7 @@ type StylisticPaddedBlocks = [] | [(("always" | "never" | "start" | "end") | {
7488
7513
  // ----- @stylistic/padding-line-between-statements -----
7489
7514
  type _StylisticPaddingLineBetweenStatementsPaddingType = ("any" | "never" | "always");
7490
7515
  type _StylisticPaddingLineBetweenStatementsStatementOption = (_StylisticPaddingLineBetweenStatementsStatementType | [_StylisticPaddingLineBetweenStatementsStatementType, ...(_StylisticPaddingLineBetweenStatementsStatementType)[]]);
7491
- type _StylisticPaddingLineBetweenStatementsStatementType = ("*" | "exports" | "require" | "directive" | "iife" | "block" | "empty" | "function" | "ts-method" | "break" | "case" | "class" | "continue" | "debugger" | "default" | "do" | "for" | "if" | "import" | "return" | "switch" | "throw" | "try" | "while" | "with" | "cjs-export" | "cjs-import" | "enum" | "interface" | "type" | "function-overload" | "block-like" | "singleline-block-like" | "multiline-block-like" | "expression" | "singleline-expression" | "multiline-expression" | "export" | "singleline-export" | "multiline-export" | "var" | "singleline-var" | "multiline-var" | "let" | "singleline-let" | "multiline-let" | "const" | "singleline-const" | "multiline-const" | "using" | "singleline-using" | "multiline-using");
7516
+ type _StylisticPaddingLineBetweenStatementsStatementType = ("*" | "exports" | "require" | "directive" | "iife" | "block" | "empty" | "function" | "ts-method" | "break" | "case" | "class" | "continue" | "debugger" | "default" | "do" | "for" | "if" | "import" | "switch" | "throw" | "try" | "while" | "with" | "cjs-export" | "cjs-import" | "enum" | "interface" | "function-overload" | "block-like" | "singleline-block-like" | "multiline-block-like" | "expression" | "singleline-expression" | "multiline-expression" | "return" | "singleline-return" | "multiline-return" | "export" | "singleline-export" | "multiline-export" | "var" | "singleline-var" | "multiline-var" | "let" | "singleline-let" | "multiline-let" | "const" | "singleline-const" | "multiline-const" | "using" | "singleline-using" | "multiline-using" | "type" | "singleline-type" | "multiline-type");
7492
7517
  type StylisticPaddingLineBetweenStatements = {
7493
7518
  blankLine: _StylisticPaddingLineBetweenStatementsPaddingType;
7494
7519
  prev: _StylisticPaddingLineBetweenStatementsStatementOption;
@@ -10042,6 +10067,7 @@ type JsdocRequireReturnsType = [] | [{
10042
10067
  }];
10043
10068
  // ----- jsdoc/require-template -----
10044
10069
  type JsdocRequireTemplate = [] | [{
10070
+ exemptedBy?: string[];
10045
10071
  requireSeparateTemplates?: boolean;
10046
10072
  }];
10047
10073
  // ----- jsdoc/require-throws -----
@@ -10763,6 +10789,10 @@ type LogicalAssignmentOperators = (([] | ["always"] | ["always", {
10763
10789
  type MarkdownFencedCodeLanguage = [] | [{
10764
10790
  required?: string[];
10765
10791
  }];
10792
+ // ----- markdown/heading-increment -----
10793
+ type MarkdownHeadingIncrement = [] | [{
10794
+ frontmatterTitle?: string;
10795
+ }];
10766
10796
  // ----- markdown/no-duplicate-definitions -----
10767
10797
  type MarkdownNoDuplicateDefinitions = [] | [{
10768
10798
  allowDefinitions?: string[];
@@ -10781,6 +10811,11 @@ type MarkdownNoEmptyDefinitions = [] | [{
10781
10811
  // ----- markdown/no-html -----
10782
10812
  type MarkdownNoHtml = [] | [{
10783
10813
  allowed?: string[];
10814
+ allowedIgnoreCase?: boolean;
10815
+ }];
10816
+ // ----- markdown/no-missing-atx-heading-space -----
10817
+ type MarkdownNoMissingAtxHeadingSpace = [] | [{
10818
+ checkClosedHeadings?: boolean;
10784
10819
  }];
10785
10820
  // ----- markdown/no-missing-link-fragments -----
10786
10821
  type MarkdownNoMissingLinkFragments = [] | [{
@@ -10791,6 +10826,10 @@ type MarkdownNoMissingLinkFragments = [] | [{
10791
10826
  type MarkdownNoMultipleH1 = [] | [{
10792
10827
  frontmatterTitle?: string;
10793
10828
  }];
10829
+ // ----- markdown/no-space-in-emphasis -----
10830
+ type MarkdownNoSpaceInEmphasis = [] | [{
10831
+ checkStrikethrough?: boolean;
10832
+ }];
10794
10833
  // ----- markdown/no-unused-definitions -----
10795
10834
  type MarkdownNoUnusedDefinitions = [] | [{
10796
10835
  allowDefinitions?: string[];
@@ -14446,7 +14485,7 @@ type Yoda = [] | [("always" | "never")] | [("always" | "never"), {
14446
14485
  onlyEquality?: boolean;
14447
14486
  }];
14448
14487
  // Names of all the configs
14449
- type ConfigNames = 'fabdeh/angular/rules' | 'fabdeh/angular-template/rules' | 'fabdeh/comments/rules' | 'fabdeh/formatter/setup' | 'fabdeh/imports/rules' | 'fabdeh/imports/ts-disables' | 'fabdeh/javascript/setup' | 'fabdeh/javascript/rules' | 'fabdeh/jsdoc/rules' | 'fabdeh/jsdoc/ts-only/rules' | 'fabdeh/jsonc/setup' | 'fabdeh/jsonc/rules' | 'fabdeh/markdown/setup' | 'fabdeh/markdown/processor' | 'fabdeh/markdown/parser' | 'fabdeh/markdown/disables' | 'fabdeh/markdown/rules' | 'fabdeh/ngrx-store/rules' | 'fabdeh/ngrx-effects/rules' | 'fabdeh/ngrx-signals/rules' | 'fabdeh/ngrx-operators/rules' | 'fabdeh/node/rules' | 'fabdeh/perfectionist/rules' | 'fabdeh/regexp/rules' | 'fabdeh/sort/package-json' | 'fabdeh/stylistic/rules' | '@fabdeh/tailwindcss/rules' | 'fabdeh/toml/setup' | 'fabdeh/toml/rules' | 'fabdeh/typescript/setup' | 'fabdeh/typescript/rules' | 'fabdeh/unicorn/rules' | 'fabdeh/vitest/rules' | 'fabdeh/yaml/setup' | 'fabdeh/yaml/rules';
14488
+ type ConfigNames = 'fabdeh/angular/rules' | 'fabdeh/angular-template/rules' | 'fabdeh/comments/rules' | 'fabdeh/formatter/setup' | 'fabdeh/imports/rules' | 'fabdeh/imports/ts-disables' | 'fabdeh/javascript/setup' | 'fabdeh/javascript/rules' | 'fabdeh/jsdoc/rules' | 'fabdeh/jsdoc/ts-only/rules' | 'fabdeh/jsonc/setup' | 'fabdeh/jsonc/rules' | 'fabdeh/markdown/setup' | 'fabdeh/markdown/processor' | 'fabdeh/markdown/parser' | 'fabdeh/markdown/disables' | 'fabdeh/markdown/rules' | 'fabdeh/ngrx-store/rules' | 'fabdeh/ngrx-effects/rules' | 'fabdeh/ngrx-signals/rules' | 'fabdeh/ngrx-operators/rules' | 'fabdeh/node/rules' | 'fabdeh/perfectionist/rules' | 'fabdeh/regexp/rules' | 'fabdeh/sort/package-json' | 'fabdeh/stylistic/rules' | '@fabdeh/tailwindcss/rules' | 'fabdeh/toml/setup' | 'fabdeh/toml/rules' | 'fabdeh/app/typescript/setup' | 'fabdeh/app/typescript/rules' | 'fabdeh/unicorn/rules' | 'fabdeh/vitest/rules' | 'fabdeh/yaml/setup' | 'fabdeh/yaml/rules';
14450
14489
  //#endregion
14451
14490
  //#region src/vendor/prettier-types.d.ts
14452
14491
  /**
@@ -14582,7 +14621,10 @@ interface VendoredPrettierOptionsRequired {
14582
14621
  xmlWhitespaceSensitivity: "ignore" | "preserve" | "strict";
14583
14622
  }
14584
14623
  //#endregion
14585
- //#region src/types.d.ts
14624
+ //#region src/shared/constants.d.ts
14625
+ declare const OPTIONS_SYMBOL: unique symbol;
14626
+ //#endregion
14627
+ //#region src/shared/types.d.ts
14586
14628
  /**
14587
14629
  * A type that can be awaited. Promise<T> or T.
14588
14630
  */
@@ -14892,20 +14934,30 @@ interface TailwindCssOptions {
14892
14934
  */
14893
14935
  tags?: Tags;
14894
14936
  }
14895
- interface ProjectTypeOptions {
14937
+ type ProjectType = "app" | "lib";
14938
+ type WorkspaceProjectType = ProjectType | "workspace";
14939
+ interface ProjectTypeOptions<T = ProjectType> {
14896
14940
  /**
14897
14941
  * Type of the project. `lib` will enable more strict rules for libraries.
14898
14942
  *
14899
14943
  * @default 'app'
14900
14944
  */
14901
- type?: "app" | "lib";
14945
+ type?: T;
14902
14946
  }
14903
14947
  /**
14904
- * Options for creating an ESLint configuration.
14905
- *
14906
- * @see createConfig function
14948
+ * Options for project-specific TypeScript configuration.
14949
+ */
14950
+ interface ProjectTypeScriptOptions {
14951
+ /**
14952
+ * Additional parser options for TypeScript.
14953
+ */
14954
+ parserOptions: TSESLint.FlatConfig.ParserOptions;
14955
+ }
14956
+ /**
14957
+ * Options for creating workspace-level ESLint configuration.
14958
+ * These options define foundational, consistency-focused configurations.
14907
14959
  */
14908
- interface CreateConfigOptions extends ProjectTypeOptions {
14960
+ interface CreateWorkspaceConfigOptions {
14909
14961
  /**
14910
14962
  * An array of glob patterns indicating the files that the configuration object should not apply to.
14911
14963
  * If not specified, the configuration object applies to all files matched by files.
@@ -14925,9 +14977,9 @@ interface CreateConfigOptions extends ProjectTypeOptions {
14925
14977
  */
14926
14978
  javascript?: OverridesOptions;
14927
14979
  /**
14928
- * TypeScript rules overrides and parser configuration.
14980
+ * TypeScript rules overrides and basic configuration.
14929
14981
  *
14930
- * @default auto-detected
14982
+ * @default false
14931
14983
  */
14932
14984
  typescript?: boolean | (NamingConventionOptions & OverridesOptions & TypeScriptOptions);
14933
14985
  /**
@@ -14938,12 +14990,6 @@ interface CreateConfigOptions extends ProjectTypeOptions {
14938
14990
  */
14939
14991
  stylistic?: boolean | (OverridesOptions & StylisticConfig);
14940
14992
  /**
14941
- * Enable or disable JSDoc rules.
14942
- *
14943
- * @default true
14944
- */
14945
- jsdoc?: boolean;
14946
- /**
14947
14993
  * Enable regexp rules.
14948
14994
  *
14949
14995
  * @see https://ota-meshi.github.io/eslint-plugin-regexp/
@@ -14957,30 +15003,6 @@ interface CreateConfigOptions extends ProjectTypeOptions {
14957
15003
  */
14958
15004
  unicorn?: UnicornOptions | boolean;
14959
15005
  /**
14960
- * Options for the angular linting rules
14961
- *
14962
- * @default auto-detect based on the dependencies.
14963
- */
14964
- angular?: AngularOptions | boolean;
14965
- /**
14966
- * Options for the ngrx linting rules.
14967
- *
14968
- * @default auto-detect based on dependencies.
14969
- */
14970
- ngrx?: NgrxOptions | boolean;
14971
- /**
14972
- * Options for the vitest linting rules
14973
- *
14974
- * @default auto-detect based on dependencies.
14975
- */
14976
- vitest?: boolean | (OverridesOptions & UnitTestingOptions);
14977
- /**
14978
- * Options for the TailwindCSS linting rules.
14979
- *
14980
- * @default false
14981
- */
14982
- tailwindcss?: boolean | (FilesOptions & OverridesOptions & TailwindCssOptions);
14983
- /**
14984
15006
  * Enable JSONC support.
14985
15007
  *
14986
15008
  * @default true
@@ -15024,14 +15046,64 @@ interface CreateConfigOptions extends ProjectTypeOptions {
15024
15046
  * In the future it will be smartly enabled based on the project usage.
15025
15047
  *
15026
15048
  * @see https://github.com/antfu/pnpm-workspace-utils
15027
- * @experimental
15028
15049
  * @default false
15050
+ * @experimental
15029
15051
  */
15030
15052
  pnpm?: boolean;
15031
15053
  }
15032
- declare const OPTIONS_SYMBOL: unique symbol;
15033
- type ConfigArrayWithOptions = TypedConfigArray & {
15034
- [OPTIONS_SYMBOL]?: CreateConfigOptions;
15054
+ /**
15055
+ * Options for creating project-level ESLint configuration.
15056
+ * These options define feature-specific, implementation-focused configurations.
15057
+ */
15058
+ interface CreateProjectConfigOptions extends ProjectTypeOptions {
15059
+ /**
15060
+ * Enable or disable JSDoc rules.
15061
+ *
15062
+ * @default true
15063
+ */
15064
+ jsdoc?: boolean;
15065
+ /**
15066
+ * Options for the angular linting rules
15067
+ *
15068
+ * @default auto-detect based on the dependencies.
15069
+ */
15070
+ angular?: AngularOptions | boolean;
15071
+ /**
15072
+ * Options for the ngrx linting rules.
15073
+ *
15074
+ * @default auto-detect based on dependencies.
15075
+ */
15076
+ ngrx?: NgrxOptions | boolean;
15077
+ /**
15078
+ * Options for the vitest linting rules
15079
+ *
15080
+ * @default auto-detect based on dependencies.
15081
+ */
15082
+ vitest?: boolean | (OverridesOptions & UnitTestingOptions);
15083
+ /**
15084
+ * Options for the TailwindCSS linting rules.
15085
+ *
15086
+ * @default false
15087
+ */
15088
+ tailwindcss?: boolean | (FilesOptions & OverridesOptions & TailwindCssOptions);
15089
+ /**
15090
+ * Project-specific TypeScript configuration.
15091
+ * Allows overriding parser options and adding project-specific rule overrides.
15092
+ */
15093
+ typescript?: OverridesOptions & ProjectTypeScriptOptions;
15094
+ }
15095
+ /**
15096
+ * Options for creating an ESLint configuration.
15097
+ * Combines workspace and project options for standalone usage.
15098
+ *
15099
+ * @see defineConfig function
15100
+ */
15101
+ type CreateConfigOptions = CreateWorkspaceConfigOptions & Omit<CreateProjectConfigOptions, "typescript">;
15102
+ /**
15103
+ * Return-type of the `defineWorkspaceConfig` function.
15104
+ */
15105
+ type TypedConfigArrayWithOptions = TypedConfigArray & {
15106
+ [OPTIONS_SYMBOL]: CreateWorkspaceConfigOptions;
15035
15107
  };
15036
15108
  //#endregion
15037
15109
  //#region src/configs/angular.d.ts
@@ -15292,16 +15364,8 @@ declare function tailwindcss(options?: (FilesOptions & OverridesOptions & Tailwi
15292
15364
  declare function toml(options?: FilesOptions & OverridesOptions & StylisticOptions): Promise<TypedConfigArray>;
15293
15365
  //#endregion
15294
15366
  //#region src/configs/typescript.d.ts
15295
- /**
15296
- * Generates a TypeScript ESLint configuration.
15297
- *
15298
- * @param options - Configuration options that include overrides, stylistic preferences, and parser options.
15299
- * @param options.stylistic - A boolean indicating whether stylistic rules should be included. Defaults to true.
15300
- * @param options.parserOptions - Options for the TypeScript parser.
15301
- * @param options.overrides - Additional rule overrides.
15302
- * @returns A TypedConfigArray containing the TypeScript ESLint configuration.
15303
- */
15304
- declare function typescript(options?: NamingConventionOptions & OverridesOptions & ProjectTypeOptions & StylisticOptions & TypeScriptOptions): Promise<TypedConfigArray>;
15367
+ declare function typescript(options?: NamingConventionOptions & OverridesOptions & ProjectTypeOptions<WorkspaceProjectType> & StylisticOptions & TypeScriptOptions): Promise<TypedConfigArray>;
15368
+ declare function typescript(options: OverridesOptions & ProjectTypeOptions & ProjectTypeScriptOptions, isWorkspaceProject: true): Promise<TypedConfigArray>;
15305
15369
  //#endregion
15306
15370
  //#region src/configs/unicorn.d.ts
15307
15371
  /**
@@ -15346,21 +15410,57 @@ declare function vitest(options?: OverridesOptions & UnitTestingOptions): Promis
15346
15410
  */
15347
15411
  declare function yaml(options?: FilesOptions & OverridesOptions & StylisticOptions): Promise<TypedConfigArray>;
15348
15412
  //#endregion
15349
- //#region src/factory.d.ts
15413
+ //#region src/factories/project-config.d.ts
15414
+ /**
15415
+ * Creates an ESLint configuration array based on the provided base configuration, options and user configurations.
15416
+ * This function is similar to `defineConfig`, but it is designed for use in a project of a workspace environment.
15417
+ * It requires a base configuration that is already defined in the root of the workspace via the `defineWorkspaceConfig` function.
15418
+ *
15419
+ * @param baseConfig - The base configuration to extend from.
15420
+ * @param options - Configuration options.
15421
+ * @param userConfigs - Additional user configurations that can be awaited.
15422
+ * @returns A promise that resolves to a `TypedConfigArray`.
15423
+ * @example
15424
+ * ```typescript
15425
+ * import baseConfig from '../../eslint.base.js';
15426
+ *
15427
+ * const config = await defineProjectConfig(baseConfig, { vitest: true, typescript: { parserOptions: { project: './tsconfig.json' } } });
15428
+ * ```
15429
+ */
15430
+ declare function defineProjectConfig(baseConfig: Awaitable<TypedConfigArrayWithOptions>, options?: CreateProjectConfigOptions, ...userConfigs: Awaitable<TypedConfigWithExtends | TypedConfigWithExtends[]>[]): Promise<TypedConfigArray>;
15431
+ //#endregion
15432
+ //#region src/factories/standard-config.d.ts
15433
+ /**
15434
+ * Creates an ESLint configuration array based on the provided options and user configurations.
15435
+ * Additionally, it will automatically detect the presence of certain packages and enable corresponding rules.
15436
+ *
15437
+ * @param options - Configuration options.
15438
+ * @param userConfigs - Additional user configurations that can be awaited.
15439
+ * @returns A promise that resolves to a `ConfigArrayWithOptions`.
15440
+ * @example
15441
+ * ```typescript
15442
+ * const config = await defineConfig({ vitest: true, typescript: { parserOptions: { project: './tsconfig.json' } } });
15443
+ * ```
15444
+ */
15445
+ declare function defineConfig(options?: CreateConfigOptions, ...userConfigs: Awaitable<TypedConfigWithExtends | TypedConfigWithExtends[]>[]): Promise<TypedConfigArray>;
15446
+ //#endregion
15447
+ //#region src/factories/workspace-config.d.ts
15350
15448
  /**
15351
15449
  * Creates an ESLint configuration array based on the provided options and user configurations.
15450
+ * This function is similar to `defineConfig`, but it is designed for use in the root of a workspace environment.
15451
+ * Contrary to `defineConfig`, it will not automatically detect the presence of certain packages and will not enable corresponding rules.
15352
15452
  *
15353
- * @param options - Configuration options that extend `ConfigWithExtends` and `CreateConfigOptions`.
15453
+ * @param options - Configuration options.
15354
15454
  * @param userConfigs - Additional user configurations that can be awaited.
15355
- * @returns A promise that resolves to a `ConfigArray`.
15455
+ * @returns A promise that resolves to a `ConfigArrayWithOptions`.
15356
15456
  * @example
15357
15457
  * ```typescript
15358
- * const config = await createConfig({ vitest: true, typescript: { parserOptions: { project: './tsconfig.json' } } });
15458
+ * const config = await defineWorkspaceConfig({ vitest: true, typescript: { parserOptions: { project: './tsconfig.json' } } });
15359
15459
  * ```
15360
15460
  */
15361
- declare function defineConfig(options?: CreateConfigOptions, ...userConfigs: Awaitable<TypedConfigWithExtends | TypedConfigWithExtends[]>[]): Promise<ConfigArrayWithOptions>;
15461
+ declare function defineWorkspaceConfig(options?: CreateWorkspaceConfigOptions, ...userConfigs: Awaitable<TypedConfigWithExtends | TypedConfigWithExtends[]>[]): Promise<TypedConfigArrayWithOptions>;
15362
15462
  //#endregion
15363
- //#region src/globs.d.ts
15463
+ //#region src/shared/globs.d.ts
15364
15464
  /**
15365
15465
  * A glob pattern that matches JavaScript and TypeScript source files (including JSX/TSX).
15366
15466
  */
@@ -15393,7 +15493,7 @@ declare const GLOB_TESTS: string[];
15393
15493
  * A glob pattern that matches all source files.
15394
15494
  */
15395
15495
  //#endregion
15396
- //#region src/utils.d.ts
15496
+ //#region src/shared/utils.d.ts
15397
15497
  /**
15398
15498
  * A utility function to handle the default export of a module.
15399
15499
  *
@@ -15464,4 +15564,4 @@ type ResolvedOptions<T> = T extends boolean ? never : NonNullable<T>;
15464
15564
  */
15465
15565
  declare function resolveSubOptions<K extends keyof CreateConfigOptions>(options: CreateConfigOptions, key: K): ResolvedOptions<CreateConfigOptions[K]>;
15466
15566
  //#endregion
15467
- export { AngularOptions, ArrayItemType, Awaitable, ConfigArrayWithOptions, type ConfigNames, CreateConfigOptions, ExtractRuleOptionsType, FilesOptions, FormattersOptions, GLOB_HTML, GLOB_JS, GLOB_SRC, GLOB_TESTS, GLOB_TS, InfiniteDepthConfigWithExtends, NamingConventionOptions, NgrxOperatorsOptions, NgrxOptions, OPTIONS_SYMBOL, OverridesOptions, ProjectTypeOptions, RegExpOptions, ResolvedOptions, Rules, STYLISTIC_CONFIG_DEFAULT, StylisticConfig, StylisticOptions, TailwindCssOptions, TypeScriptOptions, TypedConfig, TypedConfigArray, TypedConfigWithExtends, UnicornOptions, UnitTestingOptions, angular, comments, defineConfig, ensurePackages, findNearestPackageJsonName, formatters, getTsConfigFileName, getWorkspaceRoot, ignores, imports, interopDefault, isPackageInScope, javascript, jsdoc, jsonc, markdown, ngrx, node, perfectionist, pnpm, regexp, resolveSubOptions, sortPackageJson, sortTsConfig, stylistic, tailwindcss, toml, typescript, unicorn, vitest, yaml };
15567
+ export { AngularOptions, ArrayItemType, Awaitable, type ConfigNames, CreateConfigOptions, CreateProjectConfigOptions, CreateWorkspaceConfigOptions, ExtractRuleOptionsType, FilesOptions, FormattersOptions, GLOB_HTML, GLOB_JS, GLOB_SRC, GLOB_TESTS, GLOB_TS, InfiniteDepthConfigWithExtends, NamingConventionOptions, NgrxOperatorsOptions, NgrxOptions, OverridesOptions, ProjectType, ProjectTypeOptions, ProjectTypeScriptOptions, RegExpOptions, ResolvedOptions, Rules, STYLISTIC_CONFIG_DEFAULT, StylisticConfig, StylisticOptions, TailwindCssOptions, TypeScriptOptions, TypedConfig, TypedConfigArray, TypedConfigArrayWithOptions, TypedConfigWithExtends, UnicornOptions, UnitTestingOptions, WorkspaceProjectType, angular, comments, defineConfig, defineProjectConfig, defineWorkspaceConfig, ensurePackages, findNearestPackageJsonName, formatters, getTsConfigFileName, getWorkspaceRoot, ignores, imports, interopDefault, isPackageInScope, javascript, jsdoc, jsonc, markdown, ngrx, node, perfectionist, pnpm, regexp, resolveSubOptions, sortPackageJson, sortTsConfig, stylistic, tailwindcss, toml, typescript, unicorn, vitest, yaml };
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import perfectionistPlugin from "eslint-plugin-perfectionist";
17
17
  import { configs } from "eslint-plugin-regexp";
18
18
  import unicornPlugin from "eslint-plugin-unicorn";
19
19
 
20
- //#region src/globs.ts
20
+ //#region src/shared/globs.ts
21
21
  /**
22
22
  * A glob pattern that matches the extension of JavaScript and TypeScript source files.
23
23
  */
@@ -150,7 +150,7 @@ const GLOB_EXCLUDE = [
150
150
  ];
151
151
 
152
152
  //#endregion
153
- //#region src/utils.ts
153
+ //#region src/shared/utils.ts
154
154
  const SCOPE_URL = import.meta.dirname;
155
155
  const IS_CWD_IN_SCOPE = isPackageExists("@fabdeh/eslint-config");
156
156
  /**
@@ -195,12 +195,11 @@ function fileExists(path) {
195
195
  function getWorkspaceRoot(dir, candidateRoot) {
196
196
  if (process.env.NX_WORKSPACE_ROOT) return process.env.NX_WORKSPACE_ROOT;
197
197
  if (dirname(dir) === dir) return candidateRoot;
198
- const matches = [
198
+ if ([
199
199
  join(dir, "nx.json"),
200
200
  join(dir, "nx"),
201
201
  join(dir, "nx.bat")
202
- ];
203
- if (matches.some((x) => fileExists(x))) return dir;
202
+ ].some((x) => fileExists(x))) return dir;
204
203
  else if (fileExists(join(dir, "node_modules", "nx", "package.json"))) return getWorkspaceRoot(dirname(dir), dir);
205
204
  else return getWorkspaceRoot(dirname(dir), candidateRoot);
206
205
  }
@@ -241,9 +240,7 @@ async function ensurePackages(packages) {
241
240
  if (process.env.CI || !process.stdout.isTTY || !IS_CWD_IN_SCOPE) return;
242
241
  const nonExistingPackages = packages.filter((i) => i && !isPackageInScope(i));
243
242
  if (nonExistingPackages.length === 0) return;
244
- const p = await import("@clack/prompts");
245
- const result = await p.confirm({ message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?` });
246
- if (result) await import("@antfu/install-pkg").then((i) => i.installPackage(nonExistingPackages, { dev: true }));
243
+ if (await (await import("@clack/prompts")).confirm({ message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?` })) await import("@antfu/install-pkg").then((i) => i.installPackage(nonExistingPackages, { dev: true }));
247
244
  }
248
245
  /**
249
246
  * Search for the nearest package.json file and return the `name` property value.
@@ -254,8 +251,7 @@ async function ensurePackages(packages) {
254
251
  async function findNearestPackageJsonName(directoryPath = resolve()) {
255
252
  try {
256
253
  const packageJsonPath = join(directoryPath, "package.json");
257
- const packageJsonData = JSON.parse(await readFile(packageJsonPath, "utf8"));
258
- return packageJsonData.name;
254
+ return JSON.parse(await readFile(packageJsonPath, "utf8")).name;
259
255
  } catch {
260
256
  const parentDir = dirname(directoryPath);
261
257
  if (directoryPath === parentDir) throw new Error("No package.json file found.");
@@ -1019,25 +1015,6 @@ async function jsonc(options = {}) {
1019
1015
  async function markdown(options = {}) {
1020
1016
  const { files = [GLOB_MARKDOWN], overrides = {} } = options;
1021
1017
  const markdownPlugin = await interopDefault(import("@eslint/markdown"));
1022
- const parserPlain = {
1023
- meta: { name: "parser-plain" },
1024
- parseForESLint: (code) => ({
1025
- ast: {
1026
- body: [],
1027
- comments: [],
1028
- loc: {
1029
- end: code.length,
1030
- start: 0
1031
- },
1032
- range: [0, code.length],
1033
- tokens: [],
1034
- type: "Program"
1035
- },
1036
- scopeManager: null,
1037
- services: { isPlain: true },
1038
- visitorKeys: { Program: [] }
1039
- })
1040
- };
1041
1018
  return tseslint.config({
1042
1019
  name: "fabdeh/markdown/setup",
1043
1020
  plugins: { markdown: markdownPlugin }
@@ -1049,7 +1026,25 @@ async function markdown(options = {}) {
1049
1026
  }, {
1050
1027
  name: "fabdeh/markdown/parser",
1051
1028
  files,
1052
- languageOptions: { parser: parserPlain }
1029
+ languageOptions: { parser: {
1030
+ meta: { name: "parser-plain" },
1031
+ parseForESLint: (code) => ({
1032
+ ast: {
1033
+ body: [],
1034
+ comments: [],
1035
+ loc: {
1036
+ end: code.length,
1037
+ start: 0
1038
+ },
1039
+ range: [0, code.length],
1040
+ tokens: [],
1041
+ type: "Program"
1042
+ },
1043
+ scopeManager: null,
1044
+ services: { isPlain: true },
1045
+ visitorKeys: { Program: [] }
1046
+ })
1047
+ } }
1053
1048
  }, {
1054
1049
  name: "fabdeh/markdown/disables",
1055
1050
  languageOptions: { parserOptions: { ecmaFeatures: { impliedStrict: true } } },
@@ -1893,10 +1888,11 @@ const MEMBER_ORDERING_OPTIONS = { default: [
1893
1888
  * @param options.stylistic - A boolean indicating whether stylistic rules should be included. Defaults to true.
1894
1889
  * @param options.parserOptions - Options for the TypeScript parser.
1895
1890
  * @param options.overrides - Additional rule overrides.
1891
+ * @param isWorkspaceProject - A boolean indicating whether the project is a workspace project. Defaults to false.
1896
1892
  * @returns A TypedConfigArray containing the TypeScript ESLint configuration.
1897
1893
  */
1898
- async function typescript(options = {}) {
1899
- const { stylistic: stylistic$1 = true, parserOptions = {}, overrides = {}, enableErasableSyntaxOnly = false, useRelaxedNamingConventionForCamelAndPascalCases = false, type = "app" } = options;
1894
+ async function typescript(options = {}, isWorkspaceProject = false) {
1895
+ const { enableErasableSyntaxOnly = false, overrides = {}, parserOptions = {}, stylistic: stylistic$1 = true, type = "app", useRelaxedNamingConventionForCamelAndPascalCases = false } = options;
1900
1896
  let erasableSyntaxOnlyPlugin;
1901
1897
  let erasableSyntaxOnlyRules;
1902
1898
  if (enableErasableSyntaxOnly) {
@@ -1908,7 +1904,7 @@ async function typescript(options = {}) {
1908
1904
  const tsconfigRootDir = getWorkspaceRoot(process.cwd(), process.cwd());
1909
1905
  const defaultProject = getTsConfigFileName(tsconfigRootDir);
1910
1906
  return tseslint.config({
1911
- name: "fabdeh/typescript/setup",
1907
+ name: `fabdeh/${type}/typescript/setup`,
1912
1908
  files: [GLOB_TS],
1913
1909
  ignores: [`${GLOB_MARKDOWN}/**`],
1914
1910
  languageOptions: {
@@ -1923,8 +1919,21 @@ async function typescript(options = {}) {
1923
1919
  ...parserOptions
1924
1920
  }
1925
1921
  }
1926
- }, {
1927
- name: "fabdeh/typescript/rules",
1922
+ }, isWorkspaceProject ? {
1923
+ name: `fabdeh/${type}/typescript/rules`,
1924
+ files: [GLOB_TS],
1925
+ ignores: [`${GLOB_MARKDOWN}/**`],
1926
+ plugins: { "@typescript-eslint": tseslint.plugin },
1927
+ rules: {
1928
+ ...type === "lib" ? { "@typescript-eslint/explicit-function-return-type": ["error", {
1929
+ allowExpressions: true,
1930
+ allowIIFEs: true
1931
+ }] } : {},
1932
+ "@typescript-eslint/explicit-module-boundary-types": "error",
1933
+ ...overrides
1934
+ }
1935
+ } : {
1936
+ name: `fabdeh/${type}/typescript/rules`,
1928
1937
  files: [GLOB_TS],
1929
1938
  ignores: [`${GLOB_MARKDOWN}/**`],
1930
1939
  plugins: {
@@ -1953,8 +1962,9 @@ async function typescript(options = {}) {
1953
1962
  ...type === "lib" ? { "@typescript-eslint/explicit-function-return-type": ["error", {
1954
1963
  allowExpressions: true,
1955
1964
  allowIIFEs: true
1956
- }] } : { "@typescript-eslint/explicit-module-boundary-types": "error" },
1965
+ }] } : {},
1957
1966
  "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }],
1967
+ ...type === "workspace" ? {} : { "@typescript-eslint/explicit-module-boundary-types": "error" },
1958
1968
  "@typescript-eslint/member-ordering": ["error", MEMBER_ORDERING_OPTIONS],
1959
1969
  "@typescript-eslint/method-signature-style": "error",
1960
1970
  "@typescript-eslint/naming-convention": ["error", ...namingConvention(!useRelaxedNamingConventionForCamelAndPascalCases)],
@@ -2241,26 +2251,89 @@ async function yaml(options = {}) {
2241
2251
  }
2242
2252
 
2243
2253
  //#endregion
2244
- //#region src/types.ts
2245
- const OPTIONS_SYMBOL = Symbol("options");
2246
-
2247
- //#endregion
2248
- //#region src/factory.ts
2254
+ //#region src/shared/constants.ts
2249
2255
  const NGRX_PACKAGES = [
2250
2256
  "@ngrx/store",
2251
2257
  "@ngrx/effects",
2252
2258
  "@ngrx/signals",
2253
2259
  "@ngrx/operators"
2254
2260
  ];
2261
+ const OPTIONS_SYMBOL = Symbol("options");
2262
+
2263
+ //#endregion
2264
+ //#region src/factories/project-config.ts
2265
+ /**
2266
+ * Creates an ESLint configuration array based on the provided base configuration, options and user configurations.
2267
+ * This function is similar to `defineConfig`, but it is designed for use in a project of a workspace environment.
2268
+ * It requires a base configuration that is already defined in the root of the workspace via the `defineWorkspaceConfig` function.
2269
+ *
2270
+ * @param baseConfig - The base configuration to extend from.
2271
+ * @param options - Configuration options.
2272
+ * @param userConfigs - Additional user configurations that can be awaited.
2273
+ * @returns A promise that resolves to a `TypedConfigArray`.
2274
+ * @example
2275
+ * ```typescript
2276
+ * import baseConfig from '../../eslint.base.js';
2277
+ *
2278
+ * const config = await defineProjectConfig(baseConfig, { vitest: true, typescript: { parserOptions: { project: './tsconfig.json' } } });
2279
+ * ```
2280
+ */
2281
+ async function defineProjectConfig(baseConfig, options = {}, ...userConfigs) {
2282
+ const resolvedBaseConfig = await baseConfig;
2283
+ const workspaceOptions = resolvedBaseConfig[OPTIONS_SYMBOL];
2284
+ const { angular: enableAngular = isPackageExists("@angular/core"), jsdoc: enableJsdoc = true, ngrx: enableNgrx = NGRX_PACKAGES.some((p) => isPackageExists(p)), tailwindcss: enableTailwind = false, typescript: typescriptOptions, vitest: enableVitest = isPackageExists("vitest") } = options;
2285
+ if (enableNgrx && !enableAngular) throw new Error("NgRx rules can only be enabled if Angular rules are also enabled.");
2286
+ const configs$1 = [];
2287
+ if (enableJsdoc) {
2288
+ const stylisticOptions = workspaceOptions.stylistic === false ? false : typeof workspaceOptions.stylistic === "object" ? workspaceOptions.stylistic : {};
2289
+ configs$1.push(jsdoc({ stylistic: stylisticOptions }));
2290
+ }
2291
+ if (typescriptOptions) {
2292
+ if (!workspaceOptions.typescript) throw new Error("Project-specific TypeScript configuration requires a base configuration with TypeScript support.");
2293
+ configs$1.push(typescript({
2294
+ ...typescriptOptions,
2295
+ type: options.type
2296
+ }, true));
2297
+ }
2298
+ if (enableAngular) {
2299
+ const angularOptions = resolveSubOptions(options, "angular");
2300
+ configs$1.push(angular(angularOptions));
2301
+ if (workspaceOptions.formatters) {
2302
+ const htmlFormatters = resolvedBaseConfig.find((c) => c.name === "fabdeh/formatter/html");
2303
+ if (htmlFormatters) delete htmlFormatters.languageOptions;
2304
+ }
2305
+ }
2306
+ if (enableNgrx) {
2307
+ const ngrxOptions = resolveSubOptions(options, "ngrx");
2308
+ const typescriptOptions$1 = resolveSubOptions(workspaceOptions, "typescript");
2309
+ configs$1.push(ngrx({
2310
+ ...ngrxOptions,
2311
+ useRelaxedNamingConventionForCamelAndPascalCases: typescriptOptions$1.useRelaxedNamingConventionForCamelAndPascalCases
2312
+ }));
2313
+ }
2314
+ if (enableVitest) {
2315
+ const vitestOptions = resolveSubOptions(options, "vitest");
2316
+ configs$1.push(vitest(vitestOptions));
2317
+ }
2318
+ if (enableTailwind) {
2319
+ const tailwindcssOptions = resolveSubOptions(options, "tailwindcss");
2320
+ configs$1.push(tailwindcss(tailwindcssOptions));
2321
+ }
2322
+ return tseslint.config(...resolvedBaseConfig, ...await Promise.all(configs$1), ...await Promise.all(userConfigs));
2323
+ }
2324
+
2325
+ //#endregion
2326
+ //#region src/factories/standard-config.ts
2255
2327
  /**
2256
2328
  * Creates an ESLint configuration array based on the provided options and user configurations.
2329
+ * Additionally, it will automatically detect the presence of certain packages and enable corresponding rules.
2257
2330
  *
2258
- * @param options - Configuration options that extend `ConfigWithExtends` and `CreateConfigOptions`.
2331
+ * @param options - Configuration options.
2259
2332
  * @param userConfigs - Additional user configurations that can be awaited.
2260
- * @returns A promise that resolves to a `ConfigArray`.
2333
+ * @returns A promise that resolves to a `ConfigArrayWithOptions`.
2261
2334
  * @example
2262
2335
  * ```typescript
2263
- * const config = await createConfig({ vitest: true, typescript: { parserOptions: { project: './tsconfig.json' } } });
2336
+ * const config = await defineConfig({ vitest: true, typescript: { parserOptions: { project: './tsconfig.json' } } });
2264
2337
  * ```
2265
2338
  */
2266
2339
  async function defineConfig(options = {}, ...userConfigs) {
@@ -2342,10 +2415,85 @@ async function defineConfig(options = {}, ...userConfigs) {
2342
2415
  configs$1.push(markdown(markdownOptions));
2343
2416
  }
2344
2417
  if (options.formatters) configs$1.push(formatters(options.formatters, typeof stylisticOptions === "boolean" ? {} : stylisticOptions, Boolean(enableAngular)));
2345
- const config = tseslint.config(...await Promise.all(configs$1), ...await Promise.all(userConfigs));
2346
- config[OPTIONS_SYMBOL] = options;
2347
- return config;
2418
+ return tseslint.config(...await Promise.all(configs$1), ...await Promise.all(userConfigs));
2419
+ }
2420
+
2421
+ //#endregion
2422
+ //#region src/factories/workspace-config.ts
2423
+ /**
2424
+ * Creates an ESLint configuration array based on the provided options and user configurations.
2425
+ * This function is similar to `defineConfig`, but it is designed for use in the root of a workspace environment.
2426
+ * Contrary to `defineConfig`, it will not automatically detect the presence of certain packages and will not enable corresponding rules.
2427
+ *
2428
+ * @param options - Configuration options.
2429
+ * @param userConfigs - Additional user configurations that can be awaited.
2430
+ * @returns A promise that resolves to a `ConfigArrayWithOptions`.
2431
+ * @example
2432
+ * ```typescript
2433
+ * const config = await defineWorkspaceConfig({ vitest: true, typescript: { parserOptions: { project: './tsconfig.json' } } });
2434
+ * ```
2435
+ */
2436
+ async function defineWorkspaceConfig(options = {}, ...userConfigs) {
2437
+ const { gitignore: enableGitignore = true, pnpm: enableCatalogs = false, regexp: enableRegexp = true, typescript: enableTypescript = isPackageExists("typescript"), unicorn: enableUnicorn = true } = options;
2438
+ const stylisticOptions = options.stylistic === false ? false : typeof options.stylistic === "object" ? options.stylistic : {};
2439
+ const configs$1 = [];
2440
+ if (enableGitignore) if (typeof enableGitignore === "object") configs$1.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => tseslint.config(r({
2441
+ name: "fabdeh/gitignore",
2442
+ ...enableGitignore
2443
+ }))));
2444
+ else configs$1.push(interopDefault(import("eslint-config-flat-gitignore")).then((r) => tseslint.config(r({
2445
+ name: "fabdeh/gitignore",
2446
+ strict: true
2447
+ }))));
2448
+ configs$1.push(ignores(options.ignores), javascript({ overrides: options.javascript?.overrides }), comments(), node(), imports({ stylistic: stylisticOptions }), perfectionist());
2449
+ if (enableUnicorn) {
2450
+ const unicornOptions = resolveSubOptions(options, "unicorn");
2451
+ configs$1.push(unicorn(unicornOptions));
2452
+ }
2453
+ if (enableTypescript) {
2454
+ const typescriptOptions = resolveSubOptions(options, "typescript");
2455
+ configs$1.push(typescript({
2456
+ ...typescriptOptions,
2457
+ stylistic: stylisticOptions,
2458
+ type: "workspace"
2459
+ }));
2460
+ }
2461
+ if (stylisticOptions) configs$1.push(stylistic({ stylistic: stylisticOptions }));
2462
+ if (enableRegexp) {
2463
+ const regexpOptions = resolveSubOptions(options, "regexp");
2464
+ configs$1.push(regexp(regexpOptions));
2465
+ }
2466
+ if (options.jsonc ?? true) {
2467
+ const jsoncOptions = resolveSubOptions(options, "jsonc");
2468
+ configs$1.push(jsonc({
2469
+ ...jsoncOptions,
2470
+ stylistic: stylisticOptions
2471
+ }), sortPackageJson(), sortTsConfig());
2472
+ }
2473
+ if (enableCatalogs) configs$1.push(pnpm());
2474
+ if (options.yaml ?? true) {
2475
+ const yamlOptions = resolveSubOptions(options, "yaml");
2476
+ configs$1.push(yaml({
2477
+ ...yamlOptions,
2478
+ stylistic: stylisticOptions
2479
+ }));
2480
+ }
2481
+ if (options.toml ?? true) {
2482
+ const tomlOptions = resolveSubOptions(options, "toml");
2483
+ configs$1.push(toml({
2484
+ ...tomlOptions,
2485
+ stylistic: stylisticOptions
2486
+ }));
2487
+ }
2488
+ if (options.markdown ?? true) {
2489
+ const markdownOptions = resolveSubOptions(options, "markdown");
2490
+ configs$1.push(markdown(markdownOptions));
2491
+ }
2492
+ if (options.formatters) configs$1.push(formatters(options.formatters, typeof stylisticOptions === "boolean" ? {} : stylisticOptions, false));
2493
+ const eslintConfigWithOptions = tseslint.config(...await Promise.all(configs$1), ...await Promise.all(userConfigs));
2494
+ eslintConfigWithOptions[OPTIONS_SYMBOL] = options;
2495
+ return eslintConfigWithOptions;
2348
2496
  }
2349
2497
 
2350
2498
  //#endregion
2351
- export { GLOB_HTML, GLOB_JS, GLOB_SRC, GLOB_TESTS, GLOB_TS, STYLISTIC_CONFIG_DEFAULT, angular, comments, defineConfig, ensurePackages, findNearestPackageJsonName, formatters, getTsConfigFileName, getWorkspaceRoot, ignores, imports, interopDefault, isPackageInScope, javascript, jsdoc, jsonc, markdown, ngrx, node, perfectionist, pnpm, regexp, resolveSubOptions, sortPackageJson, sortTsConfig, stylistic, tailwindcss, toml, typescript, unicorn, vitest, yaml };
2499
+ export { GLOB_HTML, GLOB_JS, GLOB_SRC, GLOB_TESTS, GLOB_TS, STYLISTIC_CONFIG_DEFAULT, angular, comments, defineConfig, defineProjectConfig, defineWorkspaceConfig, ensurePackages, findNearestPackageJsonName, formatters, getTsConfigFileName, getWorkspaceRoot, ignores, imports, interopDefault, isPackageInScope, javascript, jsdoc, jsonc, markdown, ngrx, node, perfectionist, pnpm, regexp, resolveSubOptions, sortPackageJson, sortTsConfig, stylistic, tailwindcss, toml, typescript, unicorn, vitest, yaml };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@fabdeh/eslint-config",
3
3
  "type": "module",
4
- "version": "0.7.0",
5
- "packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748",
4
+ "version": "0.8.0-beta.1",
5
+ "packageManager": "pnpm@10.16.1+sha512.0e155aa2629db8672b49e8475da6226aa4bdea85fdcdfdc15350874946d4f3c91faaf64cbdc4a5d1ab8002f473d5c3fcedcd197989cf0390f9badd3c04678706",
6
6
  "description": "My personal eslint config preset",
7
7
  "author": {
8
8
  "name": "Fabien Dehopré",
@@ -51,9 +51,10 @@
51
51
  "lint": "pnpm build && eslint . --fix",
52
52
  "lint:ci": "eslint . --quiet",
53
53
  "prepack": "pnpm build",
54
- "release": "bumpp && npm publish",
54
+ "release": "bumpp",
55
55
  "typecheck": "tsc --noEmit",
56
- "gen": "tsx scripts/typegen.ts"
56
+ "gen": "tsx scripts/typegen.ts",
57
+ "validate-pr-title": "tsx scripts/validate-pr-title.ts"
57
58
  },
58
59
  "peerDependencies": {
59
60
  "@prettier/plugin-xml": "catalog:peer",
@@ -123,6 +124,8 @@
123
124
  "@commitlint/cli": "catalog:dev",
124
125
  "@commitlint/config-conventional": "catalog:dev",
125
126
  "@commitlint/cz-commitlint": "catalog:dev",
127
+ "@commitlint/lint": "catalog:dev",
128
+ "@commitlint/load": "catalog:dev",
126
129
  "@fabdeh/eslint-config": "workspace:*",
127
130
  "@ngrx/effects": "catalog:dev",
128
131
  "@ngrx/operators": "catalog:dev",