@luxass/eslint-config 4.3.7 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -51,6 +51,7 @@ __export(src_exports, {
51
51
  GLOB_SRC: () => GLOB_SRC,
52
52
  GLOB_SRC_EXT: () => GLOB_SRC_EXT,
53
53
  GLOB_STYLE: () => GLOB_STYLE,
54
+ GLOB_SVELTE: () => GLOB_SVELTE,
54
55
  GLOB_TESTS: () => GLOB_TESTS,
55
56
  GLOB_TOML: () => GLOB_TOML,
56
57
  GLOB_TS: () => GLOB_TS,
@@ -70,6 +71,7 @@ __export(src_exports, {
70
71
  javascript: () => javascript,
71
72
  jsdoc: () => jsdoc,
72
73
  jsonc: () => jsonc,
74
+ luxass: () => luxass,
73
75
  markdown: () => markdown,
74
76
  nextjs: () => nextjs,
75
77
  node: () => node,
@@ -81,6 +83,7 @@ __export(src_exports, {
81
83
  sortPackageJson: () => sortPackageJson,
82
84
  sortTsconfig: () => sortTsconfig,
83
85
  stylistic: () => stylistic,
86
+ svelte: () => svelte,
84
87
  tailwindcss: () => tailwindcss,
85
88
  test: () => test,
86
89
  toArray: () => toArray,
@@ -194,6 +197,7 @@ var GLOB_JSON5 = "**/*.json5";
194
197
  var GLOB_JSONC = "**/*.jsonc";
195
198
  var GLOB_MARKDOWN = "**/*.md";
196
199
  var GLOB_MARKDOWN_IN_MARKDOWN = "**/*.md/*.md";
200
+ var GLOB_SVELTE = "**/*.svelte";
197
201
  var GLOB_VUE = "**/*.vue";
198
202
  var GLOB_YAML = "**/*.y?(a)ml";
199
203
  var GLOB_TOML = "**/*.toml";
@@ -518,6 +522,172 @@ function sortTsconfig() {
518
522
  ];
519
523
  }
520
524
 
525
+ // src/utils.ts
526
+ var import_node_process = __toESM(require("process"), 1);
527
+ var import_local_pkg = require("local-pkg");
528
+ var parserPlain = {
529
+ meta: {
530
+ name: "parser-plain"
531
+ },
532
+ parseForESLint: (code) => ({
533
+ ast: {
534
+ body: [],
535
+ comments: [],
536
+ loc: { end: code.length, start: 0 },
537
+ range: [0, code.length],
538
+ tokens: [],
539
+ type: "Program"
540
+ },
541
+ scopeManager: null,
542
+ services: { isPlain: true },
543
+ visitorKeys: {
544
+ Program: []
545
+ }
546
+ })
547
+ };
548
+ async function combine(...configs) {
549
+ const resolved = await Promise.all(configs);
550
+ return resolved.flat();
551
+ }
552
+ function renameRules(rules, from, to) {
553
+ return Object.fromEntries(
554
+ Object.entries(rules).map(([key, value]) => {
555
+ if (key.startsWith(from)) {
556
+ return [to + key.slice(from.length), value];
557
+ }
558
+ return [key, value];
559
+ })
560
+ );
561
+ }
562
+ function toArray(value) {
563
+ return Array.isArray(value) ? value : [value];
564
+ }
565
+ async function interop(m) {
566
+ const resolved = await m;
567
+ return resolved.default || resolved;
568
+ }
569
+ async function ensure(packages) {
570
+ if (import_node_process.default.env.CI || import_node_process.default.stdout.isTTY === false) {
571
+ return;
572
+ }
573
+ ;
574
+ const nonExistingPackages = packages.filter((i) => i && !(0, import_local_pkg.isPackageExists)(i));
575
+ if (nonExistingPackages.length === 0) {
576
+ return;
577
+ }
578
+ const p = await import("@clack/prompts");
579
+ const result = await p.confirm({
580
+ message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?`
581
+ });
582
+ if (result) {
583
+ await import("@antfu/install-pkg").then((i) => i.installPackage(nonExistingPackages, { dev: true }));
584
+ }
585
+ }
586
+ function resolveSubOptions(options, key) {
587
+ return typeof options[key] === "boolean" ? {} : options[key] || {};
588
+ }
589
+ function getOverrides(options, key) {
590
+ const sub = resolveSubOptions(options, key);
591
+ return {
592
+ ..."overrides" in sub ? sub.overrides : {}
593
+ };
594
+ }
595
+
596
+ // src/configs/svelte.ts
597
+ async function svelte(options = {}) {
598
+ const {
599
+ files = [GLOB_SVELTE],
600
+ overrides = {},
601
+ stylistic: stylistic2 = true
602
+ } = options;
603
+ const {
604
+ indent = 2,
605
+ quotes = "single"
606
+ } = typeof stylistic2 === "boolean" ? {} : stylistic2;
607
+ await ensure([
608
+ "eslint-plugin-svelte"
609
+ ]);
610
+ const [
611
+ pluginSvelte,
612
+ parserSvelte
613
+ ] = await Promise.all([
614
+ interop(import("eslint-plugin-svelte")),
615
+ interop(import("svelte-eslint-parser"))
616
+ ]);
617
+ return [
618
+ {
619
+ name: "antfu/svelte/setup",
620
+ plugins: {
621
+ svelte: pluginSvelte
622
+ }
623
+ },
624
+ {
625
+ files,
626
+ languageOptions: {
627
+ parser: parserSvelte,
628
+ parserOptions: {
629
+ extraFileExtensions: [".svelte"],
630
+ parser: options.typescript ? await interop(import("@typescript-eslint/parser")) : null
631
+ }
632
+ },
633
+ name: "antfu/svelte/rules",
634
+ processor: pluginSvelte.processors[".svelte"],
635
+ rules: {
636
+ "import/no-mutable-exports": "off",
637
+ "no-undef": "off",
638
+ // incompatible with most recent (attribute-form) generic types RFC
639
+ "no-unused-vars": ["error", {
640
+ args: "none",
641
+ caughtErrors: "none",
642
+ ignoreRestSiblings: true,
643
+ vars: "all",
644
+ varsIgnorePattern: "^(\\$\\$Props$|\\$\\$Events$|\\$\\$Slots$)"
645
+ }],
646
+ "svelte/comment-directive": "error",
647
+ "svelte/no-at-debug-tags": "warn",
648
+ "svelte/no-at-html-tags": "error",
649
+ "svelte/no-dupe-else-if-blocks": "error",
650
+ "svelte/no-dupe-style-properties": "error",
651
+ "svelte/no-dupe-use-directives": "error",
652
+ "svelte/no-dynamic-slot-name": "error",
653
+ "svelte/no-export-load-in-svelte-module-in-kit-pages": "error",
654
+ "svelte/no-inner-declarations": "error",
655
+ "svelte/no-not-function-handler": "error",
656
+ "svelte/no-object-in-text-mustaches": "error",
657
+ "svelte/no-reactive-functions": "error",
658
+ "svelte/no-reactive-literals": "error",
659
+ "svelte/no-shorthand-style-property-overrides": "error",
660
+ "svelte/no-unknown-style-directive-property": "error",
661
+ "svelte/no-unused-svelte-ignore": "error",
662
+ "svelte/no-useless-mustaches": "error",
663
+ "svelte/require-store-callbacks-use-set-param": "error",
664
+ "svelte/system": "error",
665
+ "svelte/valid-compile": "error",
666
+ "svelte/valid-each-key": "error",
667
+ "unused-imports/no-unused-vars": [
668
+ "error",
669
+ { args: "after-used", argsIgnorePattern: "^_", vars: "all", varsIgnorePattern: "^(_|\\$\\$Props$|\\$\\$Events$|\\$\\$Slots$)" }
670
+ ],
671
+ ...stylistic2 ? {
672
+ "style/indent": "off",
673
+ // superseded by svelte/indent
674
+ "style/no-trailing-spaces": "off",
675
+ // superseded by svelte/no-trailing-spaces
676
+ "svelte/derived-has-same-inputs-outputs": "error",
677
+ "svelte/html-closing-bracket-spacing": "error",
678
+ "svelte/html-quotes": ["error", { prefer: quotes }],
679
+ "svelte/indent": ["error", { alignAttributesVertically: true, indent }],
680
+ "svelte/mustache-spacing": "error",
681
+ "svelte/no-spaces-around-equal-signs-in-attribute": "error",
682
+ "svelte/no-trailing-spaces": "error",
683
+ "svelte/spaced-html-comment": "error"
684
+ } : {},
685
+ ...overrides
686
+ }
687
+ }
688
+ ];
689
+ }
690
+
521
691
  // src/configs/imports.ts
522
692
  var import_eslint_plugin_import_x = __toESM(require("eslint-plugin-import-x"), 1);
523
693
  var import_eslint_plugin_antfu = __toESM(require("eslint-plugin-antfu"), 1);
@@ -817,77 +987,6 @@ async function javascript(options = {}) {
817
987
  ];
818
988
  }
819
989
 
820
- // src/utils.ts
821
- var import_node_process = __toESM(require("process"), 1);
822
- var import_local_pkg = require("local-pkg");
823
- var parserPlain = {
824
- meta: {
825
- name: "parser-plain"
826
- },
827
- parseForESLint: (code) => ({
828
- ast: {
829
- body: [],
830
- comments: [],
831
- loc: { end: code.length, start: 0 },
832
- range: [0, code.length],
833
- tokens: [],
834
- type: "Program"
835
- },
836
- scopeManager: null,
837
- services: { isPlain: true },
838
- visitorKeys: {
839
- Program: []
840
- }
841
- })
842
- };
843
- async function combine(...configs) {
844
- const resolved = await Promise.all(configs);
845
- return resolved.flat();
846
- }
847
- function renameRules(rules, from, to) {
848
- return Object.fromEntries(
849
- Object.entries(rules).map(([key, value]) => {
850
- if (key.startsWith(from)) {
851
- return [to + key.slice(from.length), value];
852
- }
853
- return [key, value];
854
- })
855
- );
856
- }
857
- function toArray(value) {
858
- return Array.isArray(value) ? value : [value];
859
- }
860
- async function interop(m) {
861
- const resolved = await m;
862
- return resolved.default || resolved;
863
- }
864
- async function ensure(packages) {
865
- if (import_node_process.default.env.CI || import_node_process.default.stdout.isTTY === false) {
866
- return;
867
- }
868
- ;
869
- const nonExistingPackages = packages.filter((i) => i && !(0, import_local_pkg.isPackageExists)(i));
870
- if (nonExistingPackages.length === 0) {
871
- return;
872
- }
873
- const p = await import("@clack/prompts");
874
- const result = await p.confirm({
875
- message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?`
876
- });
877
- if (result) {
878
- await import("@antfu/install-pkg").then((i) => i.installPackage(nonExistingPackages, { dev: true }));
879
- }
880
- }
881
- function resolveSubOptions(options, key) {
882
- return typeof options[key] === "boolean" ? {} : options[key] || {};
883
- }
884
- function getOverrides(options, key) {
885
- const sub = resolveSubOptions(options, key);
886
- return {
887
- ..."overrides" in sub ? sub.overrides : {}
888
- };
889
- }
890
-
891
990
  // src/configs/jsdoc.ts
892
991
  async function jsdoc(options = {}) {
893
992
  const {
@@ -1024,7 +1123,7 @@ async function markdown(options = {}) {
1024
1123
  }
1025
1124
  },
1026
1125
  {
1027
- name: "luxass/markdown:processor",
1126
+ name: "luxass/markdown/processor",
1028
1127
  files,
1029
1128
  ignores: [GLOB_MARKDOWN_IN_MARKDOWN],
1030
1129
  // `eslint-plugin-markdown` only creates virtual files for code blocks,
@@ -1613,6 +1712,7 @@ async function yaml(options = {}) {
1613
1712
  }
1614
1713
 
1615
1714
  // src/configs/test.ts
1715
+ var _pluginTest;
1616
1716
  async function test(options = {}) {
1617
1717
  const {
1618
1718
  editor = false,
@@ -1624,16 +1724,12 @@ async function test(options = {}) {
1624
1724
  ] = await Promise.all([
1625
1725
  interop(import("eslint-plugin-vitest"))
1626
1726
  ]);
1727
+ _pluginTest = _pluginTest || pluginVitest;
1627
1728
  return [
1628
1729
  {
1629
1730
  name: "luxass/test/setup",
1630
1731
  plugins: {
1631
- test: {
1632
- ...pluginVitest,
1633
- rules: {
1634
- ...pluginVitest.rules
1635
- }
1636
- }
1732
+ test: _pluginTest
1637
1733
  }
1638
1734
  },
1639
1735
  {
@@ -1709,35 +1805,42 @@ async function nextjs(options = {}) {
1709
1805
  {
1710
1806
  name: "luxass/nextjs/setup",
1711
1807
  plugins: {
1712
- "@next/next": pluginNextjs
1808
+ nextjs: pluginNextjs
1713
1809
  }
1714
1810
  },
1715
1811
  {
1716
1812
  name: "luxass/nextjs/rules",
1717
1813
  files,
1718
1814
  rules: {
1719
- ...pluginNextjs.configs.recommended.rules,
1720
- ...pluginNextjs.configs["core-web-vitals"].rules,
1721
- "@next/next/google-font-display": ["error"],
1722
- "@next/next/google-font-preconnect": ["error"],
1723
- "@next/next/inline-script-id": ["error"],
1724
- "@next/next/next-script-for-ga": ["warn"],
1725
- "@next/next/no-assign-module-variable": ["error"],
1726
- "@next/next/no-css-tags": ["warn"],
1727
- "@next/next/no-document-import-in-page": ["error"],
1728
- "@next/next/no-duplicate-head": ["error"],
1729
- "@next/next/no-head-element": ["warn"],
1730
- "@next/next/no-head-import-in-document": ["error"],
1731
- "@next/next/no-html-link-for-pages": ["off"],
1732
- "@next/next/no-img-element": ["warn"],
1733
- "@next/next/no-page-custom-font": ["warn"],
1734
- "@next/next/no-script-component-in-head": ["error"],
1735
- "@next/next/no-styled-jsx-in-document": ["warn"],
1736
- "@next/next/no-sync-scripts": ["warn"],
1737
- "@next/next/no-title-in-document-head": ["warn"],
1738
- "@next/next/no-typos": ["warn"],
1739
- "@next/next/no-unwanted-polyfillio": ["warn"],
1740
- // "jsx-a11y/anchor-is-valid": ["off"],
1815
+ ...renameRules(
1816
+ pluginNextjs.configs.recommended.rules,
1817
+ "@next/next/",
1818
+ "nextjs/"
1819
+ ),
1820
+ ...renameRules(
1821
+ pluginNextjs.configs["core-web-vitals"].rules,
1822
+ "@next/next/",
1823
+ "nextjs/"
1824
+ ),
1825
+ "nextjs/google-font-display": ["error"],
1826
+ "nextjs/google-font-preconnect": ["error"],
1827
+ "nextjs/inline-script-id": ["error"],
1828
+ "nextjs/next-script-for-ga": ["warn"],
1829
+ "nextjs/no-assign-module-variable": ["error"],
1830
+ "nextjs/no-css-tags": ["warn"],
1831
+ "nextjs/no-document-import-in-page": ["error"],
1832
+ "nextjs/no-duplicate-head": ["error"],
1833
+ "nextjs/no-head-element": ["warn"],
1834
+ "nextjs/no-head-import-in-document": ["error"],
1835
+ "nextjs/no-html-link-for-pages": ["off"],
1836
+ "nextjs/no-img-element": ["warn"],
1837
+ "nextjs/no-page-custom-font": ["warn"],
1838
+ "nextjs/no-script-component-in-head": ["error"],
1839
+ "nextjs/no-styled-jsx-in-document": ["warn"],
1840
+ "nextjs/no-sync-scripts": ["warn"],
1841
+ "nextjs/no-title-in-document-head": ["warn"],
1842
+ "nextjs/no-typos": ["warn"],
1843
+ "nextjs/no-unwanted-polyfillio": ["warn"],
1741
1844
  // This rule creates errors with webpack parsing on edge runtime
1742
1845
  "unicorn/prefer-node-protocol": ["off"],
1743
1846
  ...overrides
@@ -1763,7 +1866,7 @@ async function nextjs(options = {}) {
1763
1866
  name: "luxass/nextjs/og-override",
1764
1867
  files: GLOB_NEXTJS_OG,
1765
1868
  rules: {
1766
- "@next/next/no-img-element": "off",
1869
+ "nextjs/no-img-element": "off",
1767
1870
  "react/no-unknown-property": ["error", {
1768
1871
  ignore: ["tw"]
1769
1872
  }]
@@ -1774,281 +1877,148 @@ async function nextjs(options = {}) {
1774
1877
 
1775
1878
  // src/configs/react.ts
1776
1879
  var import_local_pkg2 = require("local-pkg");
1880
+ var ReactRefreshAllowConstantExportPackages = [
1881
+ "vite"
1882
+ ];
1883
+ var RemixPackages = [
1884
+ "@remix-run/node",
1885
+ "@remix-run/react",
1886
+ "@remix-run/serve",
1887
+ "@remix-run/dev"
1888
+ ];
1777
1889
  async function react(options = {}) {
1778
1890
  const {
1779
- a11y = false,
1780
- files = [GLOB_JSX, GLOB_TSX],
1781
- overrides = {},
1782
- refresh = true,
1783
- typescript: typescript2 = true
1891
+ files = [GLOB_TS, GLOB_TSX],
1892
+ overrides = {}
1784
1893
  } = options;
1785
1894
  await ensure([
1786
- "eslint-plugin-react",
1895
+ "@eslint-react/eslint-plugin",
1787
1896
  "eslint-plugin-react-hooks",
1788
- ...refresh ? ["eslint-plugin-react-refresh"] : [],
1789
- ...a11y ? ["eslint-plugin-jsx-a11y"] : []
1897
+ "eslint-plugin-react-refresh"
1790
1898
  ]);
1899
+ const tsconfigPath = options?.tsconfigPath ? toArray(options.tsconfigPath) : void 0;
1900
+ const isTypeAware = !!tsconfigPath;
1791
1901
  const [
1792
1902
  pluginReact,
1793
1903
  pluginReactHooks,
1794
1904
  pluginReactRefresh,
1795
- pluginA11y
1905
+ parserTs
1796
1906
  ] = await Promise.all([
1797
- interop(import("eslint-plugin-react")),
1907
+ interop(import("@eslint-react/eslint-plugin")),
1798
1908
  interop(import("eslint-plugin-react-hooks")),
1799
- ...refresh ? [interop(import("eslint-plugin-react-refresh"))] : [],
1800
- ...a11y ? [interop(import("eslint-plugin-jsx-a11y"))] : []
1909
+ interop(import("eslint-plugin-react-refresh")),
1910
+ interop(import("@typescript-eslint/parser"))
1801
1911
  ]);
1802
- const isAllowConstantExport = (0, import_local_pkg2.isPackageExists)("vite");
1912
+ const isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some(
1913
+ (i) => (0, import_local_pkg2.isPackageExists)(i)
1914
+ );
1915
+ const isUsingRemix = RemixPackages.some((i) => (0, import_local_pkg2.isPackageExists)(i));
1916
+ const isUsingNext = (0, import_local_pkg2.isPackageExists)("next");
1917
+ const plugins = pluginReact.configs.all.plugins;
1803
1918
  return [
1804
1919
  {
1805
1920
  name: "luxass/react/setup",
1806
1921
  plugins: {
1807
- "react": pluginReact,
1922
+ "react": plugins["@eslint-react"],
1923
+ "react-dom": plugins["@eslint-react/dom"],
1808
1924
  "react-hooks": pluginReactHooks,
1809
- ...refresh ? { "react-refresh": pluginReactRefresh } : {},
1810
- ...a11y ? { "jsx-a11y": pluginA11y } : {}
1925
+ "react-hooks-extra": plugins["@eslint-react/hooks-extra"],
1926
+ "react-naming-convention": plugins["@eslint-react/naming-convention"],
1927
+ "react-refresh": pluginReactRefresh
1811
1928
  }
1812
1929
  },
1813
1930
  {
1814
1931
  name: "luxass/react/rules",
1815
1932
  files,
1816
1933
  languageOptions: {
1934
+ parser: parserTs,
1817
1935
  parserOptions: {
1818
1936
  ecmaFeatures: {
1819
1937
  jsx: true
1820
- }
1821
- }
1938
+ },
1939
+ ...isTypeAware ? { project: tsconfigPath } : {}
1940
+ },
1941
+ sourceType: "module"
1822
1942
  },
1823
1943
  rules: {
1824
- ...a11y ? {
1825
- // recommended rules for jsx-a11y
1826
- "jsx-a11y/alt-text": "error",
1827
- "jsx-a11y/anchor-ambiguous-text": "off",
1828
- "jsx-a11y/anchor-has-content": "error",
1829
- "jsx-a11y/anchor-is-valid": "error",
1830
- "jsx-a11y/aria-activedescendant-has-tabindex": "error",
1831
- "jsx-a11y/aria-props": "error",
1832
- "jsx-a11y/aria-proptypes": "error",
1833
- "jsx-a11y/aria-role": "error",
1834
- "jsx-a11y/aria-unsupported-elements": "error",
1835
- "jsx-a11y/autocomplete-valid": "error",
1836
- "jsx-a11y/click-events-have-key-events": "error",
1837
- "jsx-a11y/control-has-associated-label": [
1838
- "off",
1839
- {
1840
- ignoreElements: [
1841
- "audio",
1842
- "canvas",
1843
- "embed",
1844
- "input",
1845
- "textarea",
1846
- "tr",
1847
- "video"
1848
- ],
1849
- ignoreRoles: [
1850
- "grid",
1851
- "listbox",
1852
- "menu",
1853
- "menubar",
1854
- "radiogroup",
1855
- "row",
1856
- "tablist",
1857
- "toolbar",
1858
- "tree",
1859
- "treegrid"
1860
- ],
1861
- includeRoles: [
1862
- "alert",
1863
- "dialog"
1864
- ]
1865
- }
1866
- ],
1867
- "jsx-a11y/heading-has-content": "error",
1868
- "jsx-a11y/html-has-lang": "error",
1869
- "jsx-a11y/iframe-has-title": "error",
1870
- "jsx-a11y/img-redundant-alt": "error",
1871
- "jsx-a11y/interactive-supports-focus": [
1872
- "error",
1873
- {
1874
- tabbable: [
1875
- "button",
1876
- "checkbox",
1877
- "link",
1878
- "searchbox",
1879
- "spinbutton",
1880
- "switch",
1881
- "textbox"
1882
- ]
1883
- }
1884
- ],
1885
- "jsx-a11y/label-has-associated-control": "error",
1886
- "jsx-a11y/label-has-for": "off",
1887
- "jsx-a11y/media-has-caption": "error",
1888
- "jsx-a11y/mouse-events-have-key-events": "error",
1889
- "jsx-a11y/no-access-key": "error",
1890
- "jsx-a11y/no-autofocus": "error",
1891
- "jsx-a11y/no-distracting-elements": "error",
1892
- "jsx-a11y/no-interactive-element-to-noninteractive-role": [
1893
- "error",
1894
- {
1895
- canvas: [
1896
- "img"
1897
- ],
1898
- tr: [
1899
- "none",
1900
- "presentation"
1901
- ]
1902
- }
1903
- ],
1904
- "jsx-a11y/no-noninteractive-element-interactions": [
1905
- "error",
1906
- {
1907
- alert: [
1908
- "onKeyUp",
1909
- "onKeyDown",
1910
- "onKeyPress"
1911
- ],
1912
- body: [
1913
- "onError",
1914
- "onLoad"
1915
- ],
1916
- dialog: [
1917
- "onKeyUp",
1918
- "onKeyDown",
1919
- "onKeyPress"
1920
- ],
1921
- handlers: [
1922
- "onClick",
1923
- "onError",
1924
- "onLoad",
1925
- "onMouseDown",
1926
- "onMouseUp",
1927
- "onKeyPress",
1928
- "onKeyDown",
1929
- "onKeyUp"
1930
- ],
1931
- iframe: [
1932
- "onError",
1933
- "onLoad"
1934
- ],
1935
- img: [
1936
- "onError",
1937
- "onLoad"
1938
- ]
1939
- }
1940
- ],
1941
- "jsx-a11y/no-noninteractive-element-to-interactive-role": [
1942
- "error",
1943
- {
1944
- fieldset: [
1945
- "radiogroup",
1946
- "presentation"
1947
- ],
1948
- li: [
1949
- "menuitem",
1950
- "option",
1951
- "row",
1952
- "tab",
1953
- "treeitem"
1954
- ],
1955
- ol: [
1956
- "listbox",
1957
- "menu",
1958
- "menubar",
1959
- "radiogroup",
1960
- "tablist",
1961
- "tree",
1962
- "treegrid"
1963
- ],
1964
- table: [
1965
- "grid"
1966
- ],
1967
- td: [
1968
- "gridcell"
1969
- ],
1970
- ul: [
1971
- "listbox",
1972
- "menu",
1973
- "menubar",
1974
- "radiogroup",
1975
- "tablist",
1976
- "tree",
1977
- "treegrid"
1978
- ]
1979
- }
1980
- ],
1981
- "jsx-a11y/no-noninteractive-tabindex": [
1982
- "error",
1983
- {
1984
- allowExpressionValues: true,
1985
- roles: [
1986
- "tabpanel"
1987
- ],
1988
- tags: []
1989
- }
1990
- ],
1991
- "jsx-a11y/no-redundant-roles": "error",
1992
- "jsx-a11y/no-static-element-interactions": [
1993
- "error",
1994
- {
1995
- allowExpressionValues: true,
1996
- handlers: [
1997
- "onClick",
1998
- "onMouseDown",
1999
- "onMouseUp",
2000
- "onKeyPress",
2001
- "onKeyDown",
2002
- "onKeyUp"
2003
- ]
2004
- }
2005
- ],
2006
- "jsx-a11y/role-has-required-aria-props": "error",
2007
- "jsx-a11y/role-supports-aria-props": "error",
2008
- "jsx-a11y/scope": "error",
2009
- "jsx-a11y/tabindex-no-positive": "error"
2010
- } : {},
2011
- // recommended rules react
2012
- "react/display-name": "error",
2013
- "react/jsx-key": "error",
2014
- "react/jsx-no-comment-textnodes": "error",
2015
- "react/jsx-no-duplicate-props": "error",
2016
- "react/jsx-no-target-blank": "error",
2017
- "react/jsx-no-undef": "error",
2018
- "react/jsx-uses-react": "error",
2019
- "react/jsx-uses-vars": "error",
2020
- "react/no-children-prop": "error",
2021
- "react/no-danger-with-children": "error",
2022
- "react/no-deprecated": "error",
2023
- "react/no-direct-mutation-state": "error",
2024
- "react/no-find-dom-node": "error",
2025
- "react/no-is-mounted": "error",
2026
- "react/no-render-return-value": "error",
2027
- "react/no-string-refs": "error",
2028
- "react/no-unescaped-entities": "error",
2029
- "react/no-unknown-property": "error",
2030
- "react/no-unsafe": "off",
2031
- "react/prop-types": "error",
2032
- "react/react-in-jsx-scope": "off",
2033
- "react/require-render-return": "error",
1944
+ // recommended rules from @eslint-react/dom
1945
+ "react-dom/no-children-in-void-dom-elements": "warn",
1946
+ "react-dom/no-dangerously-set-innerhtml": "warn",
1947
+ "react-dom/no-dangerously-set-innerhtml-with-children": "error",
1948
+ "react-dom/no-find-dom-node": "error",
1949
+ "react-dom/no-missing-button-type": "warn",
1950
+ "react-dom/no-missing-iframe-sandbox": "warn",
1951
+ "react-dom/no-namespace": "error",
1952
+ "react-dom/no-render-return-value": "error",
1953
+ "react-dom/no-script-url": "warn",
1954
+ "react-dom/no-unsafe-iframe-sandbox": "warn",
1955
+ "react-dom/no-unsafe-target-blank": "warn",
2034
1956
  // recommended rules react-hooks
2035
1957
  "react-hooks/exhaustive-deps": "warn",
2036
1958
  "react-hooks/rules-of-hooks": "error",
2037
1959
  // react refresh
2038
- ...refresh ? {
2039
- "react-refresh/only-export-components": ["warn", { allowConstantExport: isAllowConstantExport }]
2040
- } : {},
2041
- ...typescript2 ? {
2042
- "react/jsx-no-undef": "off",
2043
- "react/prop-type": "off"
1960
+ "react-refresh/only-export-components": [
1961
+ "warn",
1962
+ {
1963
+ allowConstantExport: isAllowConstantExport,
1964
+ allowExportNames: isUsingNext ? [
1965
+ "config",
1966
+ "generateStaticParams",
1967
+ "metadata",
1968
+ "generateMetadata",
1969
+ "viewport",
1970
+ "generateViewport"
1971
+ ] : isUsingRemix ? [
1972
+ "meta",
1973
+ "links",
1974
+ "headers",
1975
+ "loader",
1976
+ "action"
1977
+ ] : void 0
1978
+ }
1979
+ ],
1980
+ // recommended rules from @eslint-react
1981
+ "react/ensure-forward-ref-using-ref": "warn",
1982
+ "react/no-access-state-in-setstate": "error",
1983
+ "react/no-array-index-key": "warn",
1984
+ "react/no-children-count": "warn",
1985
+ "react/no-children-for-each": "warn",
1986
+ "react/no-children-map": "warn",
1987
+ "react/no-children-only": "warn",
1988
+ "react/no-children-prop": "warn",
1989
+ "react/no-children-to-array": "warn",
1990
+ "react/no-clone-element": "warn",
1991
+ "react/no-comment-textnodes": "warn",
1992
+ "react/no-component-will-mount": "error",
1993
+ "react/no-component-will-receive-props": "error",
1994
+ "react/no-component-will-update": "error",
1995
+ "react/no-create-ref": "error",
1996
+ "react/no-direct-mutation-state": "error",
1997
+ "react/no-duplicate-key": "error",
1998
+ "react/no-implicit-key": "error",
1999
+ "react/no-missing-key": "error",
2000
+ "react/no-nested-components": "warn",
2001
+ "react/no-redundant-should-component-update": "error",
2002
+ "react/no-set-state-in-component-did-mount": "warn",
2003
+ "react/no-set-state-in-component-did-update": "warn",
2004
+ "react/no-set-state-in-component-will-update": "warn",
2005
+ "react/no-string-refs": "error",
2006
+ "react/no-unsafe-component-will-mount": "warn",
2007
+ "react/no-unsafe-component-will-receive-props": "warn",
2008
+ "react/no-unsafe-component-will-update": "warn",
2009
+ "react/no-unstable-context-value": "error",
2010
+ "react/no-unstable-default-props": "error",
2011
+ "react/no-unused-class-component-members": "warn",
2012
+ "react/no-unused-state": "warn",
2013
+ "react/no-useless-fragment": "warn",
2014
+ "react/prefer-destructuring-assignment": "warn",
2015
+ "react/prefer-shorthand-boolean": "warn",
2016
+ "react/prefer-shorthand-fragment": "warn",
2017
+ ...isTypeAware ? {
2018
+ "react/no-leaked-conditional-rendering": "warn"
2044
2019
  } : {},
2045
2020
  // overrides
2046
2021
  ...overrides
2047
- },
2048
- settings: {
2049
- react: {
2050
- version: "detect"
2051
- }
2052
2022
  }
2053
2023
  }
2054
2024
  ];
@@ -2306,7 +2276,7 @@ async function formatters(options = {}, stylistic2 = {}) {
2306
2276
  if (options.html) {
2307
2277
  configs.push({
2308
2278
  name: "luxass/formatter/html",
2309
- files: ["**/*.html"],
2279
+ files: [GLOB_HTML],
2310
2280
  languageOptions: {
2311
2281
  parser: parserPlain
2312
2282
  },
@@ -2456,10 +2426,14 @@ async function solid(options = {}) {
2456
2426
  await ensure([
2457
2427
  "eslint-plugin-solid"
2458
2428
  ]);
2429
+ const tsconfigPath = options?.tsconfigPath ? toArray(options.tsconfigPath) : void 0;
2430
+ const isTypeAware = !!tsconfigPath;
2459
2431
  const [
2460
- pluginSolid
2432
+ pluginSolid,
2433
+ parserTs
2461
2434
  ] = await Promise.all([
2462
- interop(import("eslint-plugin-solid"))
2435
+ interop(import("eslint-plugin-solid")),
2436
+ interop(import("@typescript-eslint/parser"))
2463
2437
  ]);
2464
2438
  return [
2465
2439
  {
@@ -2472,42 +2446,41 @@ async function solid(options = {}) {
2472
2446
  name: "luxass/solid/rules",
2473
2447
  files,
2474
2448
  languageOptions: {
2449
+ parser: parserTs,
2475
2450
  parserOptions: {
2476
2451
  ecmaFeatures: {
2477
2452
  jsx: true
2478
- }
2453
+ },
2454
+ ...isTypeAware ? { project: tsconfigPath } : {}
2479
2455
  },
2480
2456
  sourceType: "module"
2481
2457
  },
2482
2458
  rules: {
2483
- // solid recommended rules
2484
2459
  // reactivity
2485
2460
  "solid/components-return-once": "warn",
2486
- "solid/event-handlers": "warn",
2461
+ "solid/event-handlers": ["error", {
2462
+ // if true, don't warn on ambiguously named event handlers like `onclick` or `onchange`
2463
+ ignoreCase: false,
2464
+ // if true, warn when spreading event handlers onto JSX. Enable for Solid < v1.6.
2465
+ warnOnSpread: false
2466
+ }],
2487
2467
  // these rules are mostly style suggestions
2488
- "solid/imports": "warn",
2468
+ "solid/imports": "error",
2489
2469
  // identifier usage is important
2490
2470
  "solid/jsx-no-duplicate-props": "error",
2491
2471
  "solid/jsx-no-script-url": "error",
2492
2472
  "solid/jsx-no-undef": "error",
2493
2473
  "solid/jsx-uses-vars": "error",
2494
- "solid/no-array-handlers": "off",
2495
2474
  "solid/no-destructure": "error",
2496
2475
  // security problems
2497
- "solid/no-innerhtml": "error",
2498
- // only necessary for resource-constrained environments
2499
- "solid/no-proxy-apis": "off",
2500
- "solid/no-react-deps": "warn",
2501
- "solid/no-react-specific-props": "warn",
2476
+ "solid/no-innerhtml": ["error", { allowStatic: true }],
2477
+ "solid/no-react-deps": "error",
2478
+ "solid/no-react-specific-props": "error",
2502
2479
  "solid/no-unknown-namespaces": "error",
2503
- // deprecated
2504
- "solid/prefer-classlist": "off",
2505
2480
  "solid/prefer-for": "error",
2506
- // handled by Solid compiler, opt-in style suggestion
2507
- "solid/prefer-show": "off",
2508
2481
  "solid/reactivity": "warn",
2509
- "solid/self-closing-comp": "warn",
2510
- "solid/style-prop": "warn",
2482
+ "solid/self-closing-comp": "error",
2483
+ "solid/style-prop": ["error", { styleProps: ["style", "css"] }],
2511
2484
  ...typescript2 ? {
2512
2485
  "solid/jsx-no-undef": ["error", { typescriptEnabled: true }],
2513
2486
  // namespaces taken care of by TS
@@ -2544,7 +2517,12 @@ var defaultPluginRenaming = {
2544
2517
  "import-x": "import",
2545
2518
  "n": "node",
2546
2519
  "vitest": "test",
2547
- "yml": "yaml"
2520
+ "yml": "yaml",
2521
+ "@eslint-react": "react",
2522
+ "@eslint-react/dom": "react-dom",
2523
+ "@eslint-react/hooks-extra": "react-hooks-extra",
2524
+ "@eslint-react/naming-convention": "react-naming-convention",
2525
+ "@next/next": "nextjs"
2548
2526
  };
2549
2527
  function luxass(options = {}, ...userConfigs) {
2550
2528
  const {
@@ -2556,6 +2534,7 @@ function luxass(options = {}, ...userConfigs) {
2556
2534
  nextjs: enableNextJS = false,
2557
2535
  react: enableReact = false,
2558
2536
  tailwindcss: enableTailwindCSS = false,
2537
+ svelte: enableSvelte = false,
2559
2538
  solid: enableSolid = false,
2560
2539
  typescript: enableTypeScript = (0, import_local_pkg4.isPackageExists)("typescript"),
2561
2540
  unocss: enableUnoCSS = false,
@@ -2617,8 +2596,7 @@ function luxass(options = {}, ...userConfigs) {
2617
2596
  configs.push(react({
2618
2597
  ...resolveSubOptions(options, "react"),
2619
2598
  overrides: getOverrides(options, "react"),
2620
- typescript: !!enableTypeScript,
2621
- refresh: !enableNextJS
2599
+ tsconfigPath: getOverrides(options, "typescript").tsconfigPath
2622
2600
  }));
2623
2601
  }
2624
2602
  if (enableNextJS) {
@@ -2638,6 +2616,16 @@ function luxass(options = {}, ...userConfigs) {
2638
2616
  })
2639
2617
  );
2640
2618
  }
2619
+ if (enableSvelte) {
2620
+ configs.push(
2621
+ svelte({
2622
+ ...resolveSubOptions(options, "svelte"),
2623
+ overrides: getOverrides(options, "svelte"),
2624
+ stylistic: stylisticOptions,
2625
+ typescript: !!enableTypeScript
2626
+ })
2627
+ );
2628
+ }
2641
2629
  if (enableVue) {
2642
2630
  configs.push(
2643
2631
  vue({
@@ -2714,15 +2702,15 @@ function luxass(options = {}, ...userConfigs) {
2714
2702
  if (Object.keys(fusedConfig).length) {
2715
2703
  configs.push([fusedConfig]);
2716
2704
  }
2717
- let pipeline = new import_eslint_flat_config_utils.FlatConfigComposer();
2718
- pipeline = pipeline.append(
2705
+ let composer = new import_eslint_flat_config_utils.FlatConfigComposer();
2706
+ composer = composer.append(
2719
2707
  ...configs,
2720
2708
  ...userConfigs
2721
2709
  );
2722
2710
  if (autoRenamePlugins) {
2723
- pipeline = pipeline.renamePlugins(defaultPluginRenaming);
2711
+ composer = composer.renamePlugins(defaultPluginRenaming);
2724
2712
  }
2725
- return pipeline;
2713
+ return composer;
2726
2714
  }
2727
2715
 
2728
2716
  // src/index.ts
@@ -2750,6 +2738,7 @@ var src_default = luxass;
2750
2738
  GLOB_SRC,
2751
2739
  GLOB_SRC_EXT,
2752
2740
  GLOB_STYLE,
2741
+ GLOB_SVELTE,
2753
2742
  GLOB_TESTS,
2754
2743
  GLOB_TOML,
2755
2744
  GLOB_TS,
@@ -2768,6 +2757,7 @@ var src_default = luxass;
2768
2757
  javascript,
2769
2758
  jsdoc,
2770
2759
  jsonc,
2760
+ luxass,
2771
2761
  markdown,
2772
2762
  nextjs,
2773
2763
  node,
@@ -2779,6 +2769,7 @@ var src_default = luxass;
2779
2769
  sortPackageJson,
2780
2770
  sortTsconfig,
2781
2771
  stylistic,
2772
+ svelte,
2782
2773
  tailwindcss,
2783
2774
  test,
2784
2775
  toArray,