@zayne-labs/eslint-config 0.4.2 → 0.5.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.js CHANGED
@@ -1,11 +1,12 @@
1
- import './chunk-VUNV25KB.js';
2
1
  import { fileURLToPath } from 'node:url';
3
2
  import { isPackageExists } from 'local-pkg';
4
3
  import globals from 'globals';
5
4
  import { fixupPluginRules } from '@eslint/compat';
6
5
  import { mergeProcessors } from 'eslint-merge-processors';
6
+ import { assert } from '@zayne-labs/toolkit-type-helpers';
7
7
  import { FlatConfigComposer } from 'eslint-flat-config-utils';
8
8
 
9
+ // src/utils.ts
9
10
  var isObject = (value) => {
10
11
  return typeof value === "object" && value !== null && !Array.isArray(value);
11
12
  };
@@ -64,6 +65,7 @@ var ensurePackages = async (packages) => {
64
65
  await antfuPkg.installPackage(nonExistingPackages, { dev: true });
65
66
  }
66
67
  };
68
+ var resolveOptions = (option) => isObject(option) ? option : {};
67
69
 
68
70
  // src/globs.ts
69
71
  var GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
@@ -177,9 +179,6 @@ var javascript = async (options = {}) => {
177
179
  window: "readonly"
178
180
  },
179
181
  parserOptions: {
180
- ecmaFeatures: {
181
- jsx: true
182
- },
183
182
  ecmaVersion: "latest",
184
183
  sourceType: "module"
185
184
  },
@@ -516,7 +515,7 @@ var typescript = async (options = {}) => {
516
515
  allowDefaultProjects,
517
516
  componentExts = [],
518
517
  files = [GLOB_TS, GLOB_TSX, ...componentExts.map((ext) => `**/*.${ext}`)],
519
- filesTypeAware = [GLOB_TS, GLOB_TSX],
518
+ filesTypeAware = [GLOB_TS, GLOB_TSX, ...componentExts.map((ext) => `**/*.${ext}`)],
520
519
  ignoresTypeAware = [`${GLOB_MARKDOWN}/**`, GLOB_ASTRO_TS],
521
520
  overrides,
522
521
  parserOptions,
@@ -653,11 +652,11 @@ var imports = async (options = {}) => {
653
652
  const eslintPluginImportX = await interopDefault(import('eslint-plugin-import-x'));
654
653
  return [
655
654
  {
655
+ name: "zayne/import/setup",
656
656
  plugins: {
657
657
  import: eslintPluginImportX
658
658
  },
659
- ...typescript2 && { settings: eslintPluginImportX.flatConfigs.typescript.settings },
660
- name: "zayne/import/setup"
659
+ ...typescript2 && { settings: eslintPluginImportX.flatConfigs.typescript.settings }
661
660
  },
662
661
  {
663
662
  name: "zayne/import/recommended",
@@ -866,16 +865,10 @@ var stylistic = async (options = {}) => {
866
865
  }
867
866
  ],
868
867
  ...jsx2 && {
869
- "stylistic/jsx-self-closing-comp": "error"
868
+ "stylistic/jsx-self-closing-comp": "warn"
870
869
  },
871
870
  ...overrides
872
871
  }
873
- },
874
- {
875
- files: [GLOB_YAML],
876
- rules: {
877
- "stylistic/spaced-comment": "off"
878
- }
879
872
  }
880
873
  ];
881
874
  };
@@ -1006,19 +999,28 @@ var isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some((i) =>
1006
999
  var isUsingRemix = RemixPackages.some((i) => isPackageExists(i));
1007
1000
  var isUsingNext = NextJsPackages.some((i) => isPackageExists(i));
1008
1001
  var react = async (options = {}) => {
1009
- const { files = [GLOB_SRC], nextjs = isUsingNext, overrides, typescript: typescript2 = true } = options;
1002
+ const {
1003
+ compiler = false,
1004
+ files = [GLOB_SRC],
1005
+ nextjs = isUsingNext,
1006
+ overrides,
1007
+ refresh = true,
1008
+ typescript: typescript2 = true
1009
+ } = options;
1010
1010
  await ensurePackages([
1011
1011
  "@eslint-react/eslint-plugin",
1012
1012
  "eslint-plugin-react-hooks",
1013
- "eslint-plugin-react-refresh",
1013
+ ...refresh ? ["eslint-plugin-react-refresh"] : [],
1014
+ ...compiler ? ["eslint-plugin-react-compiler"] : [],
1014
1015
  ...nextjs ? ["@next/eslint-plugin-next"] : []
1015
1016
  ]);
1016
- const [eslintPluginReact, eslintReactHooks, eslintPluginReactRefresh, eslintPluginNextjs] = await Promise.all([
1017
+ const [eslintPluginReact, eslintReactHooks, eslintPluginReactRefresh] = await Promise.all([
1017
1018
  interopDefault(import('@eslint-react/eslint-plugin')),
1018
1019
  interopDefault(import('eslint-plugin-react-hooks')),
1019
- interopDefault(import('eslint-plugin-react-refresh')),
1020
- ...nextjs ? [interopDefault(import('@next/eslint-plugin-next'))] : []
1020
+ ...refresh ? [interopDefault(import('eslint-plugin-react-refresh'))] : []
1021
1021
  ]);
1022
+ const eslintPluginReactCompiler = compiler && await interopDefault(import('eslint-plugin-react-compiler'));
1023
+ const eslintPluginNextjs = nextjs && await interopDefault(import('@next/eslint-plugin-next'));
1022
1024
  const recommendedReactConfig = eslintPluginReact.configs[typescript2 ? "recommended-type-checked" : "recommended"];
1023
1025
  const config = [
1024
1026
  {
@@ -1039,11 +1041,12 @@ var react = async (options = {}) => {
1039
1041
  files,
1040
1042
  name: "zayne/react/rules",
1041
1043
  rules: {
1042
- // Hook rules
1044
+ // Hook Extra rules
1043
1045
  "react-hooks-extra/ensure-custom-hooks-using-other-hooks": "error",
1044
1046
  "react-hooks-extra/no-unnecessary-use-callback": "warn",
1045
1047
  "react-hooks-extra/no-unnecessary-use-memo": "warn",
1046
1048
  "react-hooks-extra/prefer-use-state-lazy-initialization": "error",
1049
+ // Hook rules
1047
1050
  "react-hooks/exhaustive-deps": "warn",
1048
1051
  "react-hooks/rules-of-hooks": "error",
1049
1052
  // Naming convention rules
@@ -1092,10 +1095,22 @@ var react = async (options = {}) => {
1092
1095
  }
1093
1096
  }
1094
1097
  ];
1098
+ if (compiler && eslintPluginReactCompiler) {
1099
+ config.push({
1100
+ files,
1101
+ name: "zayne/react/compiler",
1102
+ plugins: {
1103
+ "react-compiler": eslintPluginReactCompiler
1104
+ },
1105
+ rules: {
1106
+ "react-compiler/react-compiler": "error"
1107
+ }
1108
+ });
1109
+ }
1095
1110
  if (nextjs && eslintPluginNextjs) {
1096
1111
  config.push({
1097
1112
  files,
1098
- name: "zayne/react/next",
1113
+ name: "zayne/react/nextjs",
1099
1114
  plugins: {
1100
1115
  "nextjs-next": fixupPluginRules(eslintPluginNextjs)
1101
1116
  },
@@ -1506,7 +1521,7 @@ var yaml = async (options = {}) => {
1506
1521
  "yaml/no-irregular-whitespace": "error",
1507
1522
  "yaml/plain-scalar": "error",
1508
1523
  "yaml/vue-custom-block/no-parsing-error": "error",
1509
- ...stylistic2 ? {
1524
+ ...stylistic2 && {
1510
1525
  "yaml/block-mapping-question-indicator-newline": "error",
1511
1526
  "yaml/block-sequence-hyphen-indicator-newline": "error",
1512
1527
  "yaml/flow-mapping-curly-newline": "error",
@@ -1521,7 +1536,8 @@ var yaml = async (options = {}) => {
1521
1536
  // { avoidEscape: true, prefer: quotes === "backtick" ? "double" : quotes },
1522
1537
  // ],
1523
1538
  "yaml/spaced-comment": "error"
1524
- } : {},
1539
+ },
1540
+ "stylistic/spaced-comment": "off",
1525
1541
  ...overrides
1526
1542
  }
1527
1543
  }
@@ -1530,13 +1546,12 @@ var yaml = async (options = {}) => {
1530
1546
  async function vue(options = {}) {
1531
1547
  const {
1532
1548
  files = [GLOB_VUE],
1533
- indent = 3,
1534
1549
  overrides,
1550
+ sfcBlocks = true,
1535
1551
  stylistic: stylistic2 = true,
1536
1552
  typescript: typescript2 = true,
1537
1553
  vueVersion = 3
1538
1554
  } = options;
1539
- const sfcBlocks = options.sfcBlocks === true ? {} : options.sfcBlocks ?? {};
1540
1555
  await ensurePackages([
1541
1556
  "eslint-plugin-vue",
1542
1557
  "vue-eslint-parser",
@@ -1545,7 +1560,7 @@ async function vue(options = {}) {
1545
1560
  const [pluginVue, parserVue, processorVueBlocks] = await Promise.all([
1546
1561
  interopDefault(import('eslint-plugin-vue')),
1547
1562
  interopDefault(import('vue-eslint-parser')),
1548
- interopDefault(import('eslint-processor-vue-blocks'))
1563
+ ...sfcBlocks ? [interopDefault(import('eslint-processor-vue-blocks'))] : []
1549
1564
  ]);
1550
1565
  return [
1551
1566
  {
@@ -1583,21 +1598,20 @@ async function vue(options = {}) {
1583
1598
  jsx: true
1584
1599
  },
1585
1600
  extraFileExtensions: [".vue"],
1586
- // eslint-disable-next-line import/no-extraneous-dependencies -- allow this for now, might change later
1587
- parser: typescript2 ? await interopDefault(import('./dist-RQW5ZYTC.js')) : void 0,
1588
- sourceType: "module"
1601
+ sourceType: "module",
1602
+ ...typescript2 && { parser: await interopDefault(import('@typescript-eslint/parser')) }
1589
1603
  }
1590
1604
  },
1591
1605
  name: "zayne/vue/rules",
1592
1606
  processor: sfcBlocks === false ? pluginVue.processors[".vue"] : mergeProcessors([
1593
1607
  pluginVue.processors[".vue"],
1594
- processorVueBlocks({
1595
- ...sfcBlocks,
1608
+ processorVueBlocks?.({
1609
+ ...resolveOptions(sfcBlocks),
1596
1610
  blocks: {
1597
1611
  styles: true,
1598
- ...sfcBlocks.blocks
1612
+ ...resolveOptions(sfcBlocks).blocks
1599
1613
  }
1600
- })
1614
+ }) ?? pluginVue.processors[".vue"]
1601
1615
  ]),
1602
1616
  rules: {
1603
1617
  ...pluginVue.configs.base.rules,
@@ -1631,7 +1645,7 @@ async function vue(options = {}) {
1631
1645
  "vue/dot-location": ["error", "property"],
1632
1646
  "vue/dot-notation": ["error", { allowKeywords: true }],
1633
1647
  "vue/eqeqeq": ["error", "smart"],
1634
- "vue/html-indent": ["error", indent],
1648
+ "vue/html-indent": "off",
1635
1649
  "vue/html-quotes": ["error", "double"],
1636
1650
  "vue/max-attributes-per-line": "off",
1637
1651
  "vue/multi-word-component-names": "off",
@@ -1664,6 +1678,7 @@ async function vue(options = {}) {
1664
1678
  "vue/prop-name-casing": ["error", "camelCase"],
1665
1679
  "vue/require-default-prop": "off",
1666
1680
  "vue/require-prop-types": "off",
1681
+ "vue/singleline-html-element-content-newline": "off",
1667
1682
  "vue/space-infix-ops": "error",
1668
1683
  "vue/space-unary-ops": ["error", { nonwords: false, words: true }],
1669
1684
  ...stylistic2 && {
@@ -1699,12 +1714,42 @@ async function vue(options = {}) {
1699
1714
  "vue/space-in-parens": ["error", "never"],
1700
1715
  "vue/template-curly-spacing": "error"
1701
1716
  },
1717
+ "ts-eslint/no-unused-vars": "off",
1702
1718
  ...overrides
1703
1719
  }
1704
1720
  }
1705
1721
  ];
1706
1722
  }
1707
1723
 
1724
+ // src/configs/solid.ts
1725
+ var solid = async (options = {}) => {
1726
+ const { files = [GLOB_SRC], overrides, typescript: typescript2 = true } = options;
1727
+ await ensurePackages(["eslint-plugin-solid"]);
1728
+ const eslintPluginSolid = await interopDefault(import('eslint-plugin-solid'));
1729
+ const recommendedSolidConfig = eslintPluginSolid.configs[typescript2 ? "flat/typescript" : "flat/recommended"];
1730
+ return [
1731
+ {
1732
+ name: "zayne/solid/setup",
1733
+ plugins: {
1734
+ solid: eslintPluginSolid
1735
+ }
1736
+ },
1737
+ {
1738
+ files,
1739
+ name: "zayne/solid/recommended",
1740
+ rules: recommendedSolidConfig.rules
1741
+ },
1742
+ {
1743
+ name: "zayne/solid/rules",
1744
+ rules: {
1745
+ "solid/no-innerhtml": ["error", { allowStatic: true }],
1746
+ "solid/style-prop": ["error", { styleProps: ["style", "css"] }],
1747
+ ...overrides
1748
+ }
1749
+ }
1750
+ ];
1751
+ };
1752
+
1708
1753
  // src/configs/jsx.ts
1709
1754
  var jsx = () => {
1710
1755
  return [
@@ -1724,8 +1769,6 @@ var jsx = () => {
1724
1769
 
1725
1770
  // src/factory.ts
1726
1771
  var ReactPackages = ["react", "react-dom"];
1727
- var VuePackages = ["vue", "nuxt", "vitepress", "@slidev/cli"];
1728
- var resolveOptions = (option) => isObject(option) ? option : {};
1729
1772
  var zayne = (options = {}, userConfigs = []) => {
1730
1773
  const {
1731
1774
  type = "app",
@@ -1734,6 +1777,7 @@ var zayne = (options = {}, userConfigs = []) => {
1734
1777
  /* eslint-enable perfectionist/sort-objects -- I just want to put `type` at the beginning */
1735
1778
  comments: enableComments = true,
1736
1779
  componentExts = [],
1780
+ componentExtsTypeAware = [],
1737
1781
  gitignore: enableGitignore = true,
1738
1782
  imports: enableImports = true,
1739
1783
  jsdoc: enableJsdoc = true,
@@ -1746,7 +1790,6 @@ var zayne = (options = {}, userConfigs = []) => {
1746
1790
  toml: enableToml = true,
1747
1791
  typescript: enableTypeScript = isPackageExists("typescript"),
1748
1792
  unicorn: enableUnicorn = true,
1749
- vue: enableVue = VuePackages.some((pkg) => isPackageExists(pkg)),
1750
1793
  yaml: enableYaml = true,
1751
1794
  ...restOfOptions
1752
1795
  } = options;
@@ -1791,9 +1834,18 @@ var zayne = (options = {}, userConfigs = []) => {
1791
1834
  sortTsconfig()
1792
1835
  );
1793
1836
  }
1837
+ if (restOfOptions.vue) {
1838
+ componentExts.push("vue");
1839
+ componentExtsTypeAware.push("vue");
1840
+ }
1794
1841
  if (enableTypeScript) {
1795
1842
  configs.push(
1796
- typescript({ componentExts, stylistic: isStylistic, ...resolveOptions(enableTypeScript) })
1843
+ typescript({
1844
+ componentExts,
1845
+ componentExtsTypeAware,
1846
+ stylistic: isStylistic,
1847
+ ...resolveOptions(enableTypeScript)
1848
+ })
1797
1849
  );
1798
1850
  }
1799
1851
  if (restOfOptions.tailwindcss) {
@@ -1821,14 +1873,18 @@ var zayne = (options = {}, userConfigs = []) => {
1821
1873
  if (enableReact) {
1822
1874
  configs.push(react({ typescript: isTypeAware, ...resolveOptions(enableReact) }));
1823
1875
  }
1824
- if (enableVue) {
1825
- configs.push(vue({ typescript: isTypeAware, ...resolveOptions(enableVue) }));
1826
- }
1827
- if ("files" in restOfOptions) {
1828
- throw new Error(
1829
- `[@zayne-labs/eslint-config] The first argument should not contain the "files" property as the options are supposed to be global. Place it in the second config array instead.`
1876
+ if (restOfOptions.vue) {
1877
+ configs.push(
1878
+ vue({ stylistic: isStylistic, typescript: isTypeAware, ...resolveOptions(restOfOptions.vue) })
1830
1879
  );
1831
1880
  }
1881
+ if (restOfOptions.solid) {
1882
+ configs.push(solid({ typescript: isTypeAware, ...resolveOptions(restOfOptions.solid) }));
1883
+ }
1884
+ assert(
1885
+ !("files" in restOfOptions),
1886
+ `[@zayne-labs/eslint-config] The first argument should not contain the "files" property as the options are supposed to be global. Place it in the second config array instead.`
1887
+ );
1832
1888
  let composer = new FlatConfigComposer();
1833
1889
  composer = composer.append(...configs, ...userConfigs);
1834
1890
  if (autoRenamePlugins) {
@@ -1837,6 +1893,6 @@ var zayne = (options = {}, userConfigs = []) => {
1837
1893
  return composer;
1838
1894
  };
1839
1895
 
1840
- export { GLOB_ALL_SRC, GLOB_ASTRO, GLOB_ASTRO_TS, GLOB_CSS, GLOB_EXCLUDE, GLOB_GRAPHQL, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLES, GLOB_SVELTE, GLOB_SVG, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, combine, comments, ensurePackages, gitIgnores, ignores, imports, interopDefault, isObject, isPackageInScope, javascript, jsdoc, jsonc, node, perfectionist, react, renamePluginInConfigs, renamePlugins, renameRules, sortPackageJson, sortTsconfig, stylistic, tailwindcss, tanstack, toml, typescript, unicorn, vue, yaml, zayne };
1896
+ export { GLOB_ALL_SRC, GLOB_ASTRO, GLOB_ASTRO_TS, GLOB_CSS, GLOB_EXCLUDE, GLOB_GRAPHQL, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_MARKDOWN_CODE, GLOB_MARKDOWN_IN_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SRC_EXT, GLOB_STYLES, GLOB_SVELTE, GLOB_SVG, GLOB_TESTS, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_VUE, GLOB_XML, GLOB_YAML, combine, comments, ensurePackages, gitIgnores, ignores, imports, interopDefault, isObject, isPackageInScope, javascript, jsdoc, jsonc, node, perfectionist, react, renamePluginInConfigs, renamePlugins, renameRules, resolveOptions, solid, sortPackageJson, sortTsconfig, stylistic, tailwindcss, tanstack, toml, typescript, unicorn, vue, yaml, zayne };
1841
1897
  //# sourceMappingURL=index.js.map
1842
1898
  //# sourceMappingURL=index.js.map