@shayanthenerd/eslint-config 0.13.0 → 0.14.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/README.md CHANGED
@@ -194,9 +194,10 @@ Install VS Code extensions for [ESLint](https://marketplace.visualstudio.com/ite
194
194
  "source.fixAll.oxc": "explicit",
195
195
  "source.fixAll.eslint": "explicit"
196
196
  },
197
- "eslint.run": "onSave",
198
- "oxc.lint.run": "onSave",
197
+ "oxc.lint.run": "onSave",
198
+ "eslint.run": "onSave",
199
199
  "editor.formatOnSave": true,
200
+ "eslint.format.enable": true,
200
201
 
201
202
  /* Format and lint JavaScript, TypeScript, HTML, and Vue files with ESLint, while everything else is formatted with Prettier. */
202
203
  "editor.defaultFormatter": "esbenp.prettier-vscode",
@@ -515,9 +516,8 @@ Under this policy, minor updates may introduce new linting errors, which could b
515
516
  You can find a list of all available versions and their changelogs on the [releases page](https://github.com/ShayanTheNerd/eslint-config/releases).
516
517
 
517
518
  ## Roadmap to v1.0.0
518
- - [ ] Integrate additional ESLint plugins, such as [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn), [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n), and [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc).
519
- - [ ] Add support for other frameworks and file types, including Astro, React, Next.js, MDX, Markdown, and JSON.
520
- - [ ] Reduce bundle size by dynamically (programmatically) installing dependencies as needed.
519
+ - [ ] Integrate additional ESLint plugins such as [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn), [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n), [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc), etc.
520
+ - [ ] Add support for other frameworks and file types, including Astro, React, Next.js, MDX, Markdown, JSON, etc.
521
521
  - [ ] Develop a starter wizard to automate the setup of OXLint, ESLint, Prettier, and other configurations.
522
522
 
523
523
  ## Contribution Guide
@@ -13,7 +13,14 @@ function getPerfectionistConfig(options) {
13
13
  name: "shayanthenerd/perfectionist",
14
14
  files: isEnabled(vue) ? [globs.src, globs.vue] : [globs.src],
15
15
  plugins: { perfectionist: eslintPluginPerfectionist },
16
- settings: { perfectionist: { type: sortType } },
16
+ settings: { perfectionist: {
17
+ type: sortType,
18
+ specialCharacters: "trim",
19
+ fallbackSort: {
20
+ order: "asc",
21
+ type: "natural"
22
+ }
23
+ } },
17
24
  rules: getPerfectionistRules(options)
18
25
  }, overrides);
19
26
  }
@@ -0,0 +1,21 @@
1
+ import { globs } from "../utils/globs.mjs";
2
+ import { isEnabled } from "../utils/isEnabled.mjs";
3
+ import { defaultOptions } from "../utils/options/defaultOptions.mjs";
4
+ import { getZodRules } from "../rules/zod.mjs";
5
+ import { mergeConfigs } from "eslint-flat-config-utils";
6
+ import eslintPluginZodX from "eslint-plugin-zod-x";
7
+
8
+ //#region src/configs/zod.ts
9
+ function getZodConfig(options) {
10
+ const { zod, vue } = options.configs;
11
+ const { overrides } = isEnabled(zod) ? zod : defaultOptions.configs.zod;
12
+ return mergeConfigs({
13
+ name: "shayanthenerd/zod",
14
+ files: isEnabled(vue) ? [globs.src, globs.vue] : [globs.src],
15
+ plugins: { "zod-x": eslintPluginZodX },
16
+ rules: getZodRules()
17
+ }, overrides);
18
+ }
19
+
20
+ //#endregion
21
+ export { getZodConfig };
package/dist/index.mjs CHANGED
@@ -2,6 +2,7 @@ import { isEnabled } from "./utils/isEnabled.mjs";
2
2
  import { defaultOptions } from "./utils/options/defaultOptions.mjs";
3
3
  import { getCSSConfig } from "./configs/css.mjs";
4
4
  import { getVueConfig } from "./configs/vue.mjs";
5
+ import { getZodConfig } from "./configs/zod.mjs";
5
6
  import { getBaseConfig } from "./configs/base.mjs";
6
7
  import { getHTMLConfig } from "./configs/html.mjs";
7
8
  import { getVitestConfig } from "./configs/vitest.mjs";
@@ -34,7 +35,7 @@ import path from "node:path";
34
35
  */
35
36
  function defineConfig(options = {}, ...configs) {
36
37
  const mergedOptions = mergeWithDefaults(options);
37
- const { gitignore, global: { rules, ignores, settings, linterOptions }, configs: { vue, css, nuxt, html, oxlint, importX, tailwind, stylistic, typescript, perfectionist, base: { preferNamedExports }, test: { vitest, cypress, storybook, playwright } } } = mergedOptions;
38
+ const { gitignore, global: { rules, ignores, settings, linterOptions }, configs: { css, zod, vue, html, nuxt, oxlint, importX, tailwind, stylistic, typescript, perfectionist, base: { preferNamedExports }, test: { vitest, cypress, storybook, playwright } } } = mergedOptions;
38
39
  const ignorePatterns = getIgnorePatterns({
39
40
  gitignore,
40
41
  patterns: ignores
@@ -57,6 +58,7 @@ function defineConfig(options = {}, ...configs) {
57
58
  preferNamedExports && getRestrictedExports(),
58
59
  isEnabled(stylistic) && getStylisticConfig(mergedOptions),
59
60
  isEnabled(perfectionist) && getPerfectionistConfig(mergedOptions),
61
+ isEnabled(zod) && getZodConfig(mergedOptions),
60
62
  isEnabled(tailwind) && getTailwindConfig(mergedOptions),
61
63
  isEnabled(vue) && getVueConfig(mergedOptions),
62
64
  isEnabled(vue) && getVueComponentNamesConfig(),
@@ -52,10 +52,14 @@
52
52
  "eslint/no-ternary": "off",
53
53
  "eslint/no-undefined": "off",
54
54
  "eslint/sort-imports": "off",
55
+ "eslint/max-statements": "off",
55
56
  "eslint/no-else-return": "off",
56
- "eslint/no-magic-numbers": "off",
57
57
  "eslint/arrow-body-style": "off",
58
+ "eslint/no-magic-numbers": "off",
59
+ "eslint/no-inline-comments": "off",
60
+ "eslint/capitalized-comments": "off",
58
61
  "eslint/func-names": ["error", "as-needed"],
62
+ "no-sequences": ["error", { "allowInParentheses": false }],
59
63
  "eslint/no-plusplus": ["warn", { "allowForLoopAfterthoughts": true }],
60
64
  "eslint/no-unused-vars": ["error", { "ignoreUsingDeclarations": true }],
61
65
  "eslint/no-duplicate-imports": ["error", { "allowSeparateTypeImports": true }],
@@ -95,6 +99,7 @@
95
99
  "unicorn/no-array-for-each": "off",
96
100
  "unicorn/prefer-global-this": "off",
97
101
  "unicorn/no-useless-undefined": "off",
102
+ "unicorn/no-immediate-mutation": "warn",
98
103
  "unicorn/prefer-prototype-methods": "off",
99
104
  "unicorn/no-await-expression-member": "off",
100
105
 
@@ -17,6 +17,7 @@ function getHTMLRules(options) {
17
17
  "@html-eslint/no-obsolete-tags": "error",
18
18
  "@html-eslint/no-script-style-type": "warn",
19
19
  "@html-eslint/no-target-blank": "warn",
20
+ "@html-eslint/no-whitespace-only-children": "error",
20
21
  "@html-eslint/prefer-https": "warn",
21
22
  "@html-eslint/require-button-type": "error",
22
23
  "@html-eslint/require-closing-tags": ["warn", {
@@ -12,8 +12,8 @@ function getPerfectionistRules(options) {
12
12
  "perfectionist/sort-union-types": "warn",
13
13
  "perfectionist/sort-array-includes": "warn",
14
14
  "perfectionist/sort-intersection-types": "warn",
15
- "perfectionist/sort-named-imports": ["warn", { groupKind: "types-first" }],
16
- "perfectionist/sort-named-exports": ["warn", { groupKind: "types-first" }],
15
+ "perfectionist/sort-named-imports": "warn",
16
+ "perfectionist/sort-named-exports": "warn",
17
17
  "perfectionist/sort-imports": ["warn", {
18
18
  environment: env,
19
19
  tsconfig: tsConfig || void 0,
@@ -29,7 +29,10 @@ function getStylisticRules(options) {
29
29
  "@stylistic/indent": [
30
30
  "warn",
31
31
  useTabs ? "tab" : indent,
32
- { tabLength: indent }
32
+ {
33
+ tabLength: indent,
34
+ SwitchCase: 1
35
+ }
33
36
  ],
34
37
  "@stylistic/indent-binary-ops": ["warn", useTabs ? "tab" : indent],
35
38
  "@stylistic/jsx-closing-bracket-location": "warn",
@@ -167,9 +170,10 @@ function getStylisticRules(options) {
167
170
  },
168
171
  {
169
172
  prev: [
170
- "const",
173
+ "var",
171
174
  "let",
172
- "var"
175
+ "const",
176
+ "using"
173
177
  ],
174
178
  next: "block-like",
175
179
  blankLine: "any"
@@ -178,6 +182,11 @@ function getStylisticRules(options) {
178
182
  prev: "block-like",
179
183
  next: "*",
180
184
  blankLine: "always"
185
+ },
186
+ {
187
+ prev: ["case", "default"],
188
+ next: ["case", "default"],
189
+ blankLine: "any"
181
190
  }
182
191
  ],
183
192
  "@stylistic/quote-props": ["warn", "consistent-as-needed"],
@@ -87,6 +87,7 @@ function getTypeScriptRules(options) {
87
87
  "@typescript-eslint/no-unused-expressions": "error",
88
88
  "@typescript-eslint/no-unused-vars": "error",
89
89
  "@typescript-eslint/no-useless-constructor": "error",
90
+ "@typescript-eslint/no-useless-default-assignment": "warn",
90
91
  "@typescript-eslint/no-wrapper-object-types": "error",
91
92
  "@typescript-eslint/only-throw-error": "error",
92
93
  "@typescript-eslint/prefer-as-const": "warn",
@@ -132,7 +133,10 @@ function getTypeScriptRules(options) {
132
133
  "@typescript-eslint/no-unsafe-type-assertion": "warn",
133
134
  "@typescript-eslint/prefer-enum-initializers": "error",
134
135
  "@typescript-eslint/no-unnecessary-qualifier": "warn",
135
- "@typescript-eslint/switch-exhaustiveness-check": "warn",
136
+ "@typescript-eslint/switch-exhaustiveness-check": ["warn", {
137
+ requireDefaultForNonUnion: true,
138
+ considerDefaultExhaustiveForUnions: true
139
+ }],
136
140
  "@typescript-eslint/explicit-module-boundary-types": "warn",
137
141
  "@typescript-eslint/no-unused-private-class-members": "error",
138
142
  "@typescript-eslint/no-unnecessary-parameter-property-assignment": "warn",
@@ -26,6 +26,7 @@ function getVitestRules(options) {
26
26
  "vitest/no-standalone-expect": "error",
27
27
  "vitest/no-test-prefixes": "error",
28
28
  "vitest/no-test-return-statement": "error",
29
+ "vitest/no-unneeded-async-expect-function": "warn",
29
30
  "vitest/padding-around-after-all-blocks": "warn",
30
31
  "vitest/padding-around-after-each-blocks": "warn",
31
32
  "vitest/padding-around-before-all-blocks": "warn",
@@ -33,6 +34,7 @@ function getVitestRules(options) {
33
34
  "vitest/padding-around-describe-blocks": "warn",
34
35
  "vitest/prefer-called-exactly-once-with": "warn",
35
36
  "vitest/prefer-called-once": "warn",
37
+ "vitest/prefer-called-times": "warn",
36
38
  "vitest/prefer-called-with": "warn",
37
39
  "vitest/prefer-comparison-matcher": "warn",
38
40
  "vitest/prefer-each": "warn",
@@ -45,6 +47,7 @@ function getVitestRules(options) {
45
47
  "vitest/prefer-importing-vitest-globals": "warn",
46
48
  "vitest/prefer-lowercase-title": "warn",
47
49
  "vitest/prefer-mock-promise-shorthand": "warn",
50
+ "vitest/prefer-mock-return-shorthand": "warn",
48
51
  "vitest/prefer-snapshot-hint": ["warn", "always"],
49
52
  "vitest/prefer-spy-on": "warn",
50
53
  "vitest/prefer-strict-boolean-matchers": "warn",
@@ -54,6 +57,7 @@ function getVitestRules(options) {
54
57
  "vitest/prefer-to-be-object": "warn",
55
58
  "vitest/prefer-to-be-truthy": "warn",
56
59
  "vitest/prefer-to-contain": "warn",
60
+ "vitest/prefer-to-have-been-called-times": "warn",
57
61
  "vitest/prefer-to-have-length": "warn",
58
62
  "vitest/prefer-todo": "warn",
59
63
  "vitest/prefer-vi-mocked": "warn",
@@ -0,0 +1,20 @@
1
+ //#region src/rules/zod.ts
2
+ function getZodRules() {
3
+ return {
4
+ "zod-x/array-style": "warn",
5
+ "zod-x/no-any-schema": "error",
6
+ "zod-x/no-empty-custom-schema": "error",
7
+ "zod-x/no-number-schema-with-int": "warn",
8
+ "zod-x/no-optional-and-default-together": ["warn", { preferredMethod: "default" }],
9
+ "zod-x/no-throw-in-refine": "error",
10
+ "zod-x/prefer-meta": "warn",
11
+ "zod-x/prefer-meta-last": "warn",
12
+ "zod-x/prefer-namespace-import": "error",
13
+ "zod-x/require-brand-type-parameter": "error",
14
+ "zod-x/require-error-message": "warn",
15
+ "zod-x/require-schema-suffix": "warn"
16
+ };
17
+ }
18
+
19
+ //#endregion
20
+ export { getZodRules };
@@ -2,6 +2,7 @@ import { RuleOptions } from "../eslintRules.mjs";
2
2
  import { ConfigWithOverrides } from "../index.mjs";
3
3
 
4
4
  //#region src/types/configOptions/perfectionist.d.ts
5
+ type SortTypeOptions = RuleOptions<'perfectionist/sort-imports'>['type'];
5
6
  interface PerfectionistOptions extends ConfigWithOverrides {
6
7
  /**
7
8
  * The type of sorting.
@@ -10,7 +11,7 @@ interface PerfectionistOptions extends ConfigWithOverrides {
10
11
  *
11
12
  * @see [Perfectionist Settings: `type` option](https://perfectionist.dev/guide/getting-started#settings)
12
13
  */
13
- sortType?: RuleOptions<'perfectionist/sort-imports'>['type'];
14
+ sortType?: Exclude<SortTypeOptions, 'type-import-first'>;
14
15
  }
15
16
  //#endregion
16
17
  export { type PerfectionistOptions };
@@ -7,7 +7,7 @@ interface BlockLang {
7
7
  style?: 'css' | 'scss' | 'postcss' | 'implicit';
8
8
  script?: 'js' | 'ts' | 'jsx' | 'tsx' | 'implicit';
9
9
  }
10
- type Macro = 'definePage' | 'defineModel' | 'defineProps' | 'defineEmits' | 'defineSlots' | 'defineCustom' | 'defineExpose' | 'defineOptions';
10
+ type Macro = 'definePage' | 'defineEmits' | 'defineModel' | 'defineProps' | 'defineSlots' | 'defineCustom' | 'defineExpose' | 'defineOptions';
11
11
  type SFCBlock = 'docs' | 'template' | 'script[setup]' | 'style[scoped]' | 'i18n[locale=en]' | 'script:not([setup])' | 'style:not([scoped])' | 'i18n:not([locale=en])';
12
12
  type VBindStyleSameNameShorthandOptions = RuleOptions<'vue/v-bind-style', 1>['sameNameShorthand'];
13
13
  interface VueOptions extends ConfigWithOverrides {