@shayanthenerd/eslint-config 0.28.3 → 0.28.5

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
@@ -213,10 +213,7 @@ For editor integration, to avoid inconsistent diagnostics from the [Tailwind CS
213
213
  ```
214
214
 
215
215
  ### Nuxt
216
- Nuxt support is already included through the Vue integration, so you don’t need to install or configure [@nuxt/eslint][eslint-nuxt] manually. If you need additional rules tailored to Nuxt, refer to the plugin’s documentation for setup instructions.
217
-
218
- > [!TIP]
219
- > `configs.nuxt` only includes options for Nuxt Image, Nuxt UI, and the `<Icon>` component. Vue's rules and `overrides` can be configured via `configs.vue`.
216
+ The required Nuxt configurations and rules are already included, so there's no need to install or configure the [@nuxt/eslint][eslint-nuxt] module.
220
217
 
221
218
  ### Markdown
222
219
  Markdown linting is powered by [@eslint/markdown][plugin-md].
@@ -500,6 +497,7 @@ _.vscode/settings.json_:
500
497
  ui?: boolean | {
501
498
  prefix?: string,
502
499
  },
500
+ overrides?: Overrides,
503
501
  },
504
502
  packageJson?: boolean | {
505
503
  overrides?: Overrides,
@@ -12,7 +12,7 @@ function getBaseConfig(options) {
12
12
  name: "shayanthenerd/base",
13
13
  files: [
14
14
  globs.src,
15
- globs.jsxLike,
15
+ globs.jsxTsx,
16
16
  isEnabled(vue) ? globs.vue : "",
17
17
  isEnabled(astro) ? globs.astro : ""
18
18
  ].filter(isTruthy),
@@ -10,7 +10,7 @@ function getBaselineConfig(options) {
10
10
  name: "shayanthenerd/baseline",
11
11
  files: [
12
12
  globs.src,
13
- globs.jsxLike,
13
+ globs.jsxTsx,
14
14
  isEnabled(vue) ? globs.vue : "",
15
15
  isEnabled(astro) ? globs.astro : ""
16
16
  ].filter(isTruthy),
@@ -13,7 +13,7 @@ function getImportXConfig(options) {
13
13
  name: "shayanthenerd/import-x",
14
14
  files: [
15
15
  globs.src,
16
- globs.jsxLike,
16
+ globs.jsxTsx,
17
17
  isEnabled(vue) ? globs.vue : "",
18
18
  isEnabled(astro) ? globs.astro : ""
19
19
  ].filter(isTruthy),
@@ -10,7 +10,7 @@ function getNextConfig(options) {
10
10
  const { overrides } = isEnabled(next) ? next : defaultOptions.configs.next;
11
11
  return mergeConfigs({
12
12
  name: "shayanthenerd/next",
13
- files: [globs.src, globs.jsxLike],
13
+ files: [globs.src, globs.jsxTsx],
14
14
  plugins: { next: eslintPluginNext },
15
15
  settings: { next: { rootDir: packageDir } },
16
16
  rules: getNextRules()
@@ -15,7 +15,7 @@ function getNodeConfig(options) {
15
15
  name: "shayanthenerd/node",
16
16
  files: [
17
17
  globs.src,
18
- globs.jsxLike,
18
+ globs.jsxTsx,
19
19
  isEnabled(vue) ? globs.vue : "",
20
20
  isEnabled(astro) ? globs.astro : ""
21
21
  ].filter(isTruthy),
@@ -0,0 +1,64 @@
1
+ import { globs } from "../helpers/globs.mjs";
2
+ import { isEnabled } from "../utils/isEnabled.mjs";
3
+ import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
4
+ import { getNuxtRules } from "../rules/nuxt.mjs";
5
+ import { mergeConfigs } from "eslint-flat-config-utils";
6
+ import eslintPluginVue from "eslint-plugin-vue";
7
+ import { parser } from "typescript-eslint";
8
+ import eslintPluginNuxt from "@nuxt/eslint-plugin";
9
+ import eslintPluginNuxtLinkChecker from "nuxt-link-checker/eslint";
10
+ //#region src/configs/nuxt.ts
11
+ const baseVueConfig = eslintPluginVue.configs["flat/base"].find((config) => config.languageOptions?.parser);
12
+ const middlewaresConfig = {
13
+ name: "shayanthenerd/nuxt/middlewares",
14
+ files: [globs.nuxtMiddlewares],
15
+ rules: {
16
+ "consistent-return": "off",
17
+ "@typescript-eslint/consistent-return": "off"
18
+ }
19
+ };
20
+ const componentNamesConfig = {
21
+ name: "shayanthenerd/nuxt/component-names",
22
+ files: [globs.nuxtAppErrorLayoutsPages],
23
+ rules: {
24
+ "vue/match-component-file-name": "off",
25
+ "vue/multi-word-component-names": "off",
26
+ "vue/component-definition-name-casing": "off"
27
+ }
28
+ };
29
+ const serverComponentsConfig = {
30
+ name: "shayanthenerd/nuxt/server-components",
31
+ files: [globs.nuxtServerComponents],
32
+ plugins: { vue: eslintPluginVue },
33
+ rules: { "vue/no-multiple-template-root": "error" }
34
+ };
35
+ function getNuxtConfigs(options) {
36
+ const { nuxt } = options.configs;
37
+ const { overrides } = isEnabled(nuxt) ? nuxt : defaultOptions.configs.nuxt;
38
+ return [
39
+ mergeConfigs({
40
+ name: "shayanthenerd/nuxt",
41
+ files: [globs.vue],
42
+ plugins: {
43
+ "vue": eslintPluginVue,
44
+ "nuxt": eslintPluginNuxt,
45
+ "link-checker": eslintPluginNuxtLinkChecker
46
+ },
47
+ processor: "vue/vue",
48
+ languageOptions: {
49
+ parser: baseVueConfig?.languageOptions?.parser,
50
+ parserOptions: {
51
+ parser,
52
+ extraFileExtensions: [".vue"],
53
+ vueFeatures: { filter: false }
54
+ }
55
+ },
56
+ rules: getNuxtRules()
57
+ }, overrides),
58
+ middlewaresConfig,
59
+ componentNamesConfig,
60
+ serverComponentsConfig
61
+ ];
62
+ }
63
+ //#endregion
64
+ export { getNuxtConfigs };
@@ -13,7 +13,7 @@ function getPerfectionistConfig(options) {
13
13
  name: "shayanthenerd/perfectionist",
14
14
  files: [
15
15
  globs.src,
16
- globs.jsxLike,
16
+ globs.jsxTsx,
17
17
  isEnabled(vue) ? globs.vue : "",
18
18
  isEnabled(astro) ? globs.astro : ""
19
19
  ].filter(isTruthy),
@@ -13,7 +13,7 @@ function getPromiseConfig(options) {
13
13
  name: "shayanthenerd/promise",
14
14
  files: [
15
15
  globs.src,
16
- globs.jsxLike,
16
+ globs.jsxTsx,
17
17
  isEnabled(vue) ? globs.vue : "",
18
18
  isEnabled(astro) ? globs.astro : ""
19
19
  ].filter(isTruthy),
@@ -13,7 +13,7 @@ function getReactConfig(options) {
13
13
  const { overrides, accessibility } = isEnabled(react) ? react : defaultOptions.configs.react;
14
14
  return mergeConfigs({
15
15
  name: "shayanthenerd/react",
16
- files: [globs.src, globs.jsxLike],
16
+ files: [globs.src, globs.jsxTsx],
17
17
  plugins: {
18
18
  "@eslint-react": eslintPluginReact,
19
19
  "@html-eslint/react": eslintPluginHtmlReact,
@@ -13,7 +13,7 @@ function getStylisticConfig(options) {
13
13
  name: "shayanthenerd/stylistic",
14
14
  files: [
15
15
  globs.src,
16
- globs.jsxLike,
16
+ globs.jsxTsx,
17
17
  isEnabled(vue) ? globs.vue : "",
18
18
  isEnabled(astro) ? globs.astro : ""
19
19
  ].filter(isTruthy),
@@ -58,7 +58,7 @@ function getTailwindConfig(options) {
58
58
  name: "shayanthenerd/tailwind",
59
59
  files: [
60
60
  globs.src,
61
- globs.jsxLike,
61
+ globs.jsxTsx,
62
62
  isEnabled(vue) ? globs.vue : "",
63
63
  isEnabled(html) ? globs.html : "",
64
64
  isEnabled(astro) ? globs.astro : ""
@@ -15,7 +15,7 @@ function getTypeScriptConfig(options) {
15
15
  name: "shayanthenerd/typescript",
16
16
  files: [
17
17
  globs.src,
18
- globs.jsxLike,
18
+ globs.jsxTsx,
19
19
  isEnabled(vue) ? globs.vue : "",
20
20
  isEnabled(astro) ? globs.astro : ""
21
21
  ].filter(isTruthy),
@@ -13,7 +13,7 @@ function getUnicornConfig(options) {
13
13
  name: "shayanthenerd/unicorn",
14
14
  files: [
15
15
  globs.src,
16
- globs.jsxLike,
16
+ globs.jsxTsx,
17
17
  isEnabled(vue) ? globs.vue : "",
18
18
  isEnabled(astro) ? globs.astro : ""
19
19
  ].filter(isTruthy),
@@ -10,8 +10,8 @@ import eslintPluginVueAccessibility from "eslint-plugin-vuejs-accessibility";
10
10
  const baseVueConfig = eslintPluginVue.configs["flat/base"].find((config) => config.languageOptions?.parser);
11
11
  function getVueConfig(options) {
12
12
  const { vue } = options.configs;
13
- const isVueAccessibilityEnabled = isEnabled(vue) && isEnabled(vue.accessibility);
14
13
  const { overrides } = isEnabled(vue) ? vue : defaultOptions.configs.vue;
14
+ const isVueAccessibilityEnabled = isEnabled(vue) && isEnabled(vue.accessibility);
15
15
  return mergeConfigs({
16
16
  name: "shayanthenerd/vue",
17
17
  files: [globs.vue],
@@ -14,7 +14,7 @@ function getZodConfig(options) {
14
14
  name: `shayanthenerd/${mini ? "zod-mini" : "zod"}`,
15
15
  files: [
16
16
  globs.src,
17
- globs.jsxLike,
17
+ globs.jsxTsx,
18
18
  isEnabled(vue) ? globs.vue : "",
19
19
  isEnabled(astro) ? globs.astro : ""
20
20
  ].filter(isTruthy),
@@ -1,20 +1,20 @@
1
1
  //#region src/helpers/globs.ts
2
2
  const srcExtensions = "?([mc])[jt]s";
3
- const jsxLikeExtensions = "[jt]sx";
4
- const vueExtensions = `{vue,${srcExtensions},${jsxLikeExtensions}}`;
3
+ const jsxTsxExtensions = "[jt]sx";
4
+ const vueExtensions = `{vue,${srcExtensions},${jsxTsxExtensions}}`;
5
5
  const globs = {
6
6
  src: `**/*.${srcExtensions}`,
7
- jsxLike: `**/*.${jsxLikeExtensions}`,
7
+ jsxTsx: `**/*.${jsxTsxExtensions}`,
8
8
  packageJson: "**/package.json",
9
9
  markdown: "**/*.md",
10
10
  html: "**/*.html",
11
11
  css: "**/*.css",
12
12
  astro: "**/*.astro",
13
13
  vue: `**/*.${vueExtensions}`,
14
- vueMiddlewares: `**/middleware?(s)/**/*.${srcExtensions}`,
15
- vueServerComponents: `**/*.server.${vueExtensions}`,
16
- vueAppErrorLayoutsPages: `**/{{app,error},{layouts,pages}/**/*}.${vueExtensions}`,
17
- storybook: `**/*.(story|stories).{${srcExtensions},${jsxLikeExtensions}}`,
14
+ nuxtAppErrorLayoutsPages: `**/{{app,error},{layouts,pages}/**/*}.${vueExtensions}`,
15
+ nuxtServerComponents: `**/*.server.${vueExtensions}`,
16
+ nuxtMiddlewares: `**/middleware?(s)/**/*.${srcExtensions}`,
17
+ storybook: `**/*.(story|stories).{${srcExtensions},${jsxTsxExtensions}}`,
18
18
  test: `**/{__tests__/*,*.{test,spec,cy,bench?(mark)}.${srcExtensions}`,
19
19
  coverage: "**/coverage/**"
20
20
  };
@@ -9,16 +9,16 @@ const defaultIgnorePatterns = [
9
9
  "**/next-env.d.ts",
10
10
  "**/components.d.ts",
11
11
  "**/routeTree.gen.ts",
12
+ "**/eslint-typegen.d.ts",
12
13
  "**/auto-import?(s).d.ts",
13
14
  "**/out",
14
15
  "**/dist",
15
16
  "**/build",
16
17
  "**/.data",
18
+ "**/public",
17
19
  "**/output",
18
20
  "**/.output",
19
21
  "**/.serverless",
20
- "**/public/build",
21
- "**/public/static",
22
22
  "**/.eslint-config-inspector",
23
23
  "**/tmp",
24
24
  "**/.tmp",
@@ -58,7 +58,8 @@ const defaultOptions = {
58
58
  nuxt: {
59
59
  icon: { component: "Icon" },
60
60
  image: false,
61
- ui: { prefix: "U" }
61
+ ui: { prefix: "U" },
62
+ overrides: {}
62
63
  },
63
64
  packageJson: { overrides: {} },
64
65
  perfectionist: {
package/dist/index.mjs CHANGED
@@ -7,6 +7,7 @@ import { getBaseConfig } from "./configs/base.mjs";
7
7
  import { getHtmlConfig } from "./configs/html.mjs";
8
8
  import { getNextConfig } from "./configs/next.mjs";
9
9
  import { getNodeConfig } from "./configs/node.mjs";
10
+ import { getNuxtConfigs } from "./configs/nuxt.mjs";
10
11
  import { getAstroConfig } from "./configs/astro.mjs";
11
12
  import { getReactConfig } from "./configs/react.mjs";
12
13
  import { getVitestConfig } from "./configs/vitest.mjs";
@@ -23,11 +24,8 @@ import { getPlaywrightConfig } from "./configs/playwright.mjs";
23
24
  import { getTypeScriptConfig } from "./configs/typescript.mjs";
24
25
  import { getPackageJsonConfig } from "./configs/packageJson.mjs";
25
26
  import { getPerfectionistConfig } from "./configs/perfectionist.mjs";
26
- import { getVueMiddlewaresConfig } from "./configs/vueMiddlewares.mjs";
27
27
  import { getIgnorePatterns } from "./helpers/ignores/getIgnorePatterns.mjs";
28
28
  import { mergeWithDefaults } from "./helpers/options/mergeWithDefaults.mjs";
29
- import { getVueComponentNamesConfig } from "./configs/vueComponentNames.mjs";
30
- import { getVueServerComponentsConfig } from "./configs/vueServerComponents.mjs";
31
29
  import { defineConfig as defineConfig$1, globalIgnores } from "eslint/config";
32
30
  //#region src/index.ts
33
31
  /**
@@ -106,9 +104,7 @@ function defineConfig(...args) {
106
104
  isEnabled(react) && getReactConfig(mergedOptions),
107
105
  isEnabled(next) && getNextConfig(mergedOptions),
108
106
  isEnabled(vue) && getVueConfig(mergedOptions),
109
- isEnabled(vue) && getVueMiddlewaresConfig(),
110
- isEnabled(vue) && getVueComponentNamesConfig(),
111
- isEnabled(vue) && isEnabled(nuxt) && getVueServerComponentsConfig(),
107
+ ...isEnabled(nuxt) ? getNuxtConfigs(mergedOptions) : [],
112
108
  isEnabled(storybook) && getStorybookConfig(mergedOptions),
113
109
  isEnabled(vitest) && getVitestConfig(mergedOptions),
114
110
  isEnabled(cypress) && getCypressConfig(mergedOptions),
@@ -0,0 +1,12 @@
1
+ //#region src/rules/nuxt.ts
2
+ const nuxtRules = {
3
+ "link-checker/valid-route": "error",
4
+ "link-checker/valid-sitemap-link": "warn",
5
+ "nuxt/no-page-meta-runtime-values": "error",
6
+ "nuxt/prefer-import-meta": "warn"
7
+ };
8
+ function getNuxtRules() {
9
+ return nuxtRules;
10
+ }
11
+ //#endregion
12
+ export { getNuxtRules };
@@ -59,7 +59,15 @@ const typeConstituentSortOptions = {
59
59
  };
60
60
  const sortArrayIncludesOptions = {
61
61
  customGroups: literalCustomGroups,
62
- groups: sharedTypeLikeGroups
62
+ groups: [
63
+ "boolean-literal",
64
+ "number-literal",
65
+ "bigint-literal",
66
+ "string-literal",
67
+ "template-literal",
68
+ "literal",
69
+ "unknown"
70
+ ]
63
71
  };
64
72
  const sortImportsCustomGroups = [{
65
73
  groupName: "component",
@@ -22,6 +22,7 @@ function getPlaywrightRules(options) {
22
22
  "playwright/no-skipped-test": "error",
23
23
  "playwright/no-slowed-test": "warn",
24
24
  "playwright/no-standalone-expect": "error",
25
+ "playwright/no-unnecessary-assertions": "error",
25
26
  "playwright/no-unsafe-references": "error",
26
27
  "playwright/no-unused-locators": "warn",
27
28
  "playwright/no-useless-await": "warn",
@@ -55,7 +55,7 @@ function getVueRules(options) {
55
55
  "vuejs-accessibility/role-has-required-aria-props": "error",
56
56
  "vuejs-accessibility/tabindex-no-positive": "error"
57
57
  };
58
- const vueAndNuxtRules = {
58
+ const vueRules = {
59
59
  "@typescript-eslint/no-useless-default-assignment": "off",
60
60
  "vue/jsx-uses-vars": "error",
61
61
  "vue/comment-directive": ["error", { reportUnusedDisableDirectives: true }],
@@ -400,10 +400,10 @@ function getVueRules(options) {
400
400
  "vue/slot-name-casing": "warn",
401
401
  "vue/v-for-delimiter-style": ["warn", vForDelimiterStyle]
402
402
  };
403
- if (isEnabled(stylistic)) vueAndNuxtRules["@stylistic/max-len"] = "off";
403
+ if (isEnabled(stylistic)) vueRules["@stylistic/max-len"] = "off";
404
404
  const isVueAccessibilityEnabled = isEnabled(vue) && isEnabled(vue.accessibility);
405
405
  return {
406
- ...vueAndNuxtRules,
406
+ ...vueRules,
407
407
  ...isVueAccessibilityEnabled && vueAccessibilityRules
408
408
  };
409
409
  }
@@ -20,6 +20,7 @@ function getZodRules(options) {
20
20
  "zod-mini/no-unnecessary-readonly": "warn",
21
21
  "zod-mini/prefer-enum-over-literal-union": "warn",
22
22
  "zod-mini/prefer-meta": "warn",
23
+ "zod-mini/prefer-nullish": "warn",
23
24
  "zod-mini/prefer-tuple-over-array-length": "warn",
24
25
  "zod-mini/require-brand-type-parameter": "error",
25
26
  "zod-mini/require-error-message": "warn"
@@ -51,6 +52,7 @@ function getZodRules(options) {
51
52
  "zod/prefer-enum-over-literal-union": "warn",
52
53
  "zod/prefer-loose-object": "warn",
53
54
  "zod/prefer-meta": "warn",
55
+ "zod/prefer-nullish": "warn",
54
56
  "zod/prefer-meta-last": "warn",
55
57
  "zod/prefer-strict-object": "warn",
56
58
  "zod/prefer-top-level-string-formats": "warn",
@@ -3524,6 +3524,14 @@ interface ESLintSchema {
3524
3524
  * @deprecated
3525
3525
  */
3526
3526
  'lines-between-class-members'?: Linter.RuleEntry<LinesBetweenClassMembers>;
3527
+ /**
3528
+ * Validate that relative URLs match a known vue-router route pattern
3529
+ */
3530
+ 'link-checker/valid-route'?: Linter.RuleEntry<LinkCheckerValidRoute>;
3531
+ /**
3532
+ * Validate that relative URLs exist in the sitemap
3533
+ */
3534
+ 'link-checker/valid-sitemap-link'?: Linter.RuleEntry<LinkCheckerValidSitemapLink>;
3527
3535
  /**
3528
3536
  * Require or disallow logical assignment operator shorthand
3529
3537
  * @see https://eslint.org/docs/latest/rules/logical-assignment-operators
@@ -4855,6 +4863,26 @@ interface ESLintSchema {
4855
4863
  * @deprecated
4856
4864
  */
4857
4865
  'nonblock-statement-body-position'?: Linter.RuleEntry<NonblockStatementBodyPosition>;
4866
+ /**
4867
+ * Disallow setting `test` key in Nuxt config
4868
+ * @see https://eslint.nuxt.com/packages/plugin#nuxtno-nuxt-config-test-key
4869
+ */
4870
+ 'nuxt/no-nuxt-config-test-key'?: Linter.RuleEntry<[]>;
4871
+ /**
4872
+ * Disallow runtime context values inside `definePageMeta` at the eager level, which is extracted into a separate chunk at build time and runs before component setup
4873
+ * @see https://eslint.nuxt.com/packages/plugin#nuxtno-page-meta-runtime-values
4874
+ */
4875
+ 'nuxt/no-page-meta-runtime-values'?: Linter.RuleEntry<[]>;
4876
+ /**
4877
+ * Prefer recommended order of Nuxt config properties
4878
+ * @see https://eslint.nuxt.com/packages/plugin#nuxtnuxt-config-keys-order
4879
+ */
4880
+ 'nuxt/nuxt-config-keys-order'?: Linter.RuleEntry<[]>;
4881
+ /**
4882
+ * Prefer using `import.meta.*` over `process.*`
4883
+ * @see https://eslint.nuxt.com/packages/plugin#nuxtprefer-import-meta
4884
+ */
4885
+ 'nuxt/prefer-import-meta'?: Linter.RuleEntry<[]>;
4858
4886
  /**
4859
4887
  * Enforce consistent line breaks after opening and before closing braces
4860
4888
  * @see https://eslint.org/docs/latest/rules/object-curly-newline
@@ -5642,6 +5670,11 @@ interface ESLintSchema {
5642
5670
  * @see https://github.com/mskelton/eslint-plugin-playwright/tree/main/docs/rules/no-standalone-expect.md
5643
5671
  */
5644
5672
  'playwright/no-standalone-expect'?: Linter.RuleEntry<[]>;
5673
+ /**
5674
+ * Disallow assertions on a Locator that can never fail
5675
+ * @see https://github.com/mskelton/eslint-plugin-playwright/tree/main/docs/rules/no-unnecessary-assertions.md
5676
+ */
5677
+ 'playwright/no-unnecessary-assertions'?: Linter.RuleEntry<[]>;
5645
5678
  /**
5646
5679
  * Prevent unsafe variable references in page.evaluate() and page.addInitScript()
5647
5680
  * @see https://github.com/mskelton/eslint-plugin-playwright/tree/main/docs/rules/no-unsafe-references.md
@@ -9782,6 +9815,11 @@ interface ESLintSchema {
9782
9815
  * @see https://github.com/marcalexiei/eslint-zod/blob/HEAD/plugins/eslint-plugin-zod-mini/docs/rules/prefer-meta.md
9783
9816
  */
9784
9817
  'zod-mini/prefer-meta'?: Linter.RuleEntry<[]>;
9818
+ /**
9819
+ * Enforce `z.nullish()` instead of combining `z.optional()` and `z.nullable()`
9820
+ * @see https://github.com/marcalexiei/eslint-zod/blob/HEAD/plugins/eslint-plugin-zod-mini/docs/rules/prefer-nullish.md
9821
+ */
9822
+ 'zod-mini/prefer-nullish'?: Linter.RuleEntry<[]>;
9785
9823
  /**
9786
9824
  * Prefer `z.tuple()` over a length-constrained `z.array()` so the length is preserved in the inferred type.
9787
9825
  * @see https://github.com/marcalexiei/eslint-zod/blob/HEAD/plugins/eslint-plugin-zod-mini/docs/rules/prefer-tuple-over-array-length.md
@@ -9958,6 +9996,11 @@ interface ESLintSchema {
9958
9996
  * @see https://github.com/marcalexiei/eslint-zod/blob/HEAD/plugins/eslint-plugin-zod/docs/rules/prefer-meta-last.md
9959
9997
  */
9960
9998
  'zod/prefer-meta-last'?: Linter.RuleEntry<[]>;
9999
+ /**
10000
+ * Enforce `.nullish()` instead of combining `.optional()` and `.nullable()`
10001
+ * @see https://github.com/marcalexiei/eslint-zod/blob/HEAD/plugins/eslint-plugin-zod/docs/rules/prefer-nullish.md
10002
+ */
10003
+ 'zod/prefer-nullish'?: Linter.RuleEntry<[]>;
9961
10004
  /**
9962
10005
  * Prefer `z.strictObject()` over `z.object().strict()`
9963
10006
  * @see https://github.com/marcalexiei/eslint-zod/blob/HEAD/plugins/eslint-plugin-zod/docs/rules/prefer-strict-object.md
@@ -17196,6 +17239,16 @@ type LinesBetweenClassMembers = [] | [({
17196
17239
  } | ("always" | "never")), {
17197
17240
  exceptAfterSingleLine?: boolean;
17198
17241
  }];
17242
+ // ----- link-checker/valid-route -----
17243
+ type LinkCheckerValidRoute = [] | [{
17244
+ routesFile?: string;
17245
+ rootDir?: string;
17246
+ }];
17247
+ // ----- link-checker/valid-sitemap-link -----
17248
+ type LinkCheckerValidSitemapLink = [] | [{
17249
+ routesFile?: string;
17250
+ rootDir?: string;
17251
+ }];
17199
17252
  // ----- logical-assignment-operators -----
17200
17253
  type LogicalAssignmentOperators = (([] | ["always"] | ["always", {
17201
17254
  enforceForIfStatements?: boolean;
@@ -302,11 +302,9 @@ interface Options {
302
302
  */
303
303
  node?: boolean | ConfigWithOverrides<PluginRules<'n'>>;
304
304
  /**
305
- * Whether [Nuxt](https://nuxt.com) is used in the project.
305
+ * Use [@nuxt/eslint-plugin](https://eslint.nuxt.com/packages/plugin) and [nuxt-link-checker (ESLint plugin)](https://nuxtseo.com/docs/link-checker/guides/eslint) to enforce Nuxt best practices and catch broken links.
306
306
  *
307
- * Enforce best practices and the use of Nuxt-specific components over their standard counterparts. For example, `<NuxtLink>` must be used instead of `<a>`, and `<NuxtTime>` instead of `<time>`.
308
- *
309
- * **This configuration requires `configs.vue` to be enabled.**
307
+ * Enforce best practices and the use of Nuxt-specific components over their counterparts. For example, `<NuxtLink>` must be used instead of `<a>`, and `<NuxtTime>` instead of `<time>`.
310
308
  *
311
309
  * @default false // `true` if "nuxt" is detected in the dependencies when `autoDetectDeps` is enabled
312
310
  */
@@ -1,5 +1,8 @@
1
+ import { PluginRules } from "../eslintRules.mjs";
2
+ import { ConfigWithOverrides } from "../index.mjs";
1
3
  //#region src/types/options/nuxt.d.ts
2
- interface NuxtOptions {
4
+ type ConfigRules = PluginRules<'nuxt'> | PluginRules<'link-checker'>;
5
+ interface NuxtOptions extends ConfigWithOverrides<ConfigRules> {
3
6
  /**
4
7
  * Whether [@nuxt/icon](https://nuxt.com/modules/icon) is used in the project.
5
8
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shayanthenerd/eslint-config",
3
- "version": "0.28.3",
3
+ "version": "0.28.5",
4
4
  "description": "A modern, flexible ESLint configuration for enforcing best practices and maintaining a consistent coding style",
5
5
  "keywords": [
6
6
  "eslint",
@@ -49,14 +49,15 @@
49
49
  "{**/*.ts,package.json}": "pnpm lint"
50
50
  },
51
51
  "dependencies": {
52
- "@eslint-react/eslint-plugin": "5.17.3",
52
+ "@eslint-react/eslint-plugin": "5.18.0",
53
53
  "@eslint/css": "1.4.0",
54
54
  "@eslint/markdown": "8.0.3",
55
55
  "@html-eslint/eslint-plugin": "0.64.0",
56
56
  "@html-eslint/eslint-plugin-react": "0.64.0",
57
- "@next/eslint-plugin-next": "16.2.10",
57
+ "@next/eslint-plugin-next": "16.2.12",
58
+ "@nuxt/eslint-plugin": "1.16.0",
58
59
  "@stylistic/eslint-plugin": "5.10.0",
59
- "@vitest/eslint-plugin": "1.6.23",
60
+ "@vitest/eslint-plugin": "1.6.24",
60
61
  "astro-eslint-parser": "3.0.0",
61
62
  "defu": "6.1.7",
62
63
  "eslint-flat-config-utils": "3.2.0",
@@ -68,18 +69,19 @@
68
69
  "eslint-plugin-import-x": "4.17.1",
69
70
  "eslint-plugin-jsx-a11y": "6.10.2",
70
71
  "eslint-plugin-n": "18.2.2",
71
- "eslint-plugin-package-json": "1.6.0",
72
+ "eslint-plugin-package-json": "1.6.2",
72
73
  "eslint-plugin-perfectionist": "5.10.0",
73
- "eslint-plugin-playwright": "2.10.5",
74
+ "eslint-plugin-playwright": "2.11.0",
74
75
  "eslint-plugin-promise": "7.3.0",
75
- "eslint-plugin-storybook": "10.5.3",
76
+ "eslint-plugin-storybook": "10.5.5",
76
77
  "eslint-plugin-unicorn": "72.0.0",
77
78
  "eslint-plugin-vue": "10.10.0",
78
79
  "eslint-plugin-vuejs-accessibility": "2.5.0",
79
- "eslint-plugin-zod": "4.8.0",
80
- "eslint-plugin-zod-mini": "1.5.0",
81
- "globals": "17.7.0",
80
+ "eslint-plugin-zod": "4.9.0",
81
+ "eslint-plugin-zod-mini": "1.6.0",
82
+ "globals": "17.8.0",
82
83
  "local-pkg": "1.2.1",
84
+ "nuxt-link-checker": "5.1.3",
83
85
  "tailwind-csstree": "0.3.3",
84
86
  "typescript-eslint": "8.65.0"
85
87
  },
@@ -87,19 +89,19 @@
87
89
  "@arethetypeswrong/cli": "0.18.5",
88
90
  "@eslint/config-inspector": "3.1.0",
89
91
  "@types/eslint-plugin-jsx-a11y": "6.10.1",
90
- "@types/node": "26.1.1",
92
+ "@types/node": "26.1.2",
91
93
  "actions-up": "1.16.0",
92
- "eslint": "10.7.0",
94
+ "eslint": "10.8.0",
93
95
  "eslint-typegen": "2.3.1",
94
96
  "nano-staged": "1.0.2",
95
97
  "prettier": "3.9.6",
96
- "publint": "0.3.21",
98
+ "publint": "0.3.22",
97
99
  "serve": "14.2.6",
98
100
  "simple-git-hooks": "2.13.1",
99
101
  "ts-morph": "28.0.0",
100
- "tsdown": "0.22.12",
102
+ "tsdown": "0.22.14",
101
103
  "typescript": "6.0.3",
102
- "unplugin-unused": "0.5.7"
104
+ "unplugin-unused": "0.6.0"
103
105
  },
104
106
  "peerDependencies": {
105
107
  "eslint": "^10.6.0"
@@ -110,7 +112,7 @@
110
112
  "devEngines": {
111
113
  "packageManager": {
112
114
  "name": "pnpm",
113
- "version": "11.15.1",
115
+ "version": "11.16.0",
114
116
  "onFail": "warn"
115
117
  },
116
118
  "runtime": {
@@ -138,6 +140,6 @@
138
140
  "check:exports": "attw --pack --profile=esm-only",
139
141
  "format": "prettier --write '**/*.{json,yaml}' '!pnpm-lock.yaml' --cache",
140
142
  "lint": "eslint --fix --max-warnings=0 --cache --cache-location=./node_modules/.cache/.eslintcache",
141
- "ci:validate": "pnpm generate:types && pnpm format && pnpm build:package && pnpm lint && pnpm check:types && pnpm build:inspector && pnpm build:package && pnpm check:exports"
143
+ "ci:validate": "pnpm format && pnpm build:package && pnpm lint && pnpm check:types && pnpm build:inspector && pnpm build:package && pnpm check:exports"
142
144
  }
143
145
  }
@@ -1,15 +0,0 @@
1
- import { globs } from "../helpers/globs.mjs";
2
- //#region src/configs/vueComponentNames.ts
3
- function getVueComponentNamesConfig() {
4
- return {
5
- name: "shayanthenerd/vue/multi-word-component-names",
6
- files: [globs.vueAppErrorLayoutsPages],
7
- rules: {
8
- "vue/match-component-file-name": "off",
9
- "vue/multi-word-component-names": "off",
10
- "vue/component-definition-name-casing": "off"
11
- }
12
- };
13
- }
14
- //#endregion
15
- export { getVueComponentNamesConfig };
@@ -1,14 +0,0 @@
1
- import { globs } from "../helpers/globs.mjs";
2
- //#region src/configs/vueMiddlewares.ts
3
- function getVueMiddlewaresConfig() {
4
- return {
5
- name: "shayanthenerd/vue/middlewares",
6
- files: [globs.vueMiddlewares],
7
- rules: {
8
- "consistent-return": "off",
9
- "@typescript-eslint/consistent-return": "off"
10
- }
11
- };
12
- }
13
- //#endregion
14
- export { getVueMiddlewaresConfig };
@@ -1,11 +0,0 @@
1
- import { globs } from "../helpers/globs.mjs";
2
- //#region src/configs/vueServerComponents.ts
3
- function getVueServerComponentsConfig() {
4
- return {
5
- name: "shayanthenerd/vue/server-components",
6
- files: [globs.vueServerComponents],
7
- rules: { "vue/no-multiple-template-root": "error" }
8
- };
9
- }
10
- //#endregion
11
- export { getVueServerComponentsConfig };