react-doctor 0.0.45 → 0.0.47

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/cli.js +63 -30
  2. package/dist/index.js +62 -29
  3. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -1760,16 +1760,45 @@ const REACT_COMPILER_RULES = {
1760
1760
  "react-hooks-js/incompatible-library": "warn",
1761
1761
  "react-hooks-js/todo": "warn"
1762
1762
  };
1763
+ const readPluginRuleNames = (pluginSpecifier) => {
1764
+ try {
1765
+ const pluginModule = esmRequire$1(pluginSpecifier);
1766
+ const rules = pluginModule.rules ?? pluginModule.default?.rules;
1767
+ if (rules === void 0) return /* @__PURE__ */ new Set();
1768
+ return new Set(Object.keys(rules));
1769
+ } catch {
1770
+ return /* @__PURE__ */ new Set();
1771
+ }
1772
+ };
1763
1773
  const resolveReactHooksJsPlugin = (hasReactCompiler, customRulesOnly) => {
1764
- if (!hasReactCompiler || customRulesOnly) return [];
1774
+ if (!hasReactCompiler || customRulesOnly) return null;
1775
+ let pluginSpecifier;
1765
1776
  try {
1766
- return [{
1767
- name: "react-hooks-js",
1768
- specifier: esmRequire$1.resolve("eslint-plugin-react-hooks")
1769
- }];
1777
+ pluginSpecifier = esmRequire$1.resolve("eslint-plugin-react-hooks");
1770
1778
  } catch {
1771
- return [];
1779
+ return null;
1772
1780
  }
1781
+ return {
1782
+ entry: {
1783
+ name: "react-hooks-js",
1784
+ specifier: pluginSpecifier
1785
+ },
1786
+ availableRuleNames: readPluginRuleNames(pluginSpecifier)
1787
+ };
1788
+ };
1789
+ const filterRulesToAvailable = (rules, pluginNamespace, availableRuleNames) => {
1790
+ if (availableRuleNames.size === 0) return rules;
1791
+ const ruleKeyPrefix = `${pluginNamespace}/`;
1792
+ const filtered = {};
1793
+ for (const [ruleKey, severity] of Object.entries(rules)) {
1794
+ if (!ruleKey.startsWith(ruleKeyPrefix)) {
1795
+ filtered[ruleKey] = severity;
1796
+ continue;
1797
+ }
1798
+ const ruleName = ruleKey.slice(ruleKeyPrefix.length);
1799
+ if (availableRuleNames.has(ruleName)) filtered[ruleKey] = severity;
1800
+ }
1801
+ return filtered;
1773
1802
  };
1774
1803
  const TANSTACK_QUERY_RULES = {
1775
1804
  "react-doctor/query-stable-query-client": "warn",
@@ -1915,29 +1944,33 @@ const ALL_REACT_DOCTOR_RULE_KEYS = new Set([
1915
1944
  ...Object.keys(TANSTACK_START_RULES),
1916
1945
  ...Object.keys(TANSTACK_QUERY_RULES)
1917
1946
  ]);
1918
- const createOxlintConfig = ({ pluginPath, framework, hasReactCompiler, hasTanStackQuery, customRulesOnly = false }) => ({
1919
- categories: {
1920
- correctness: "off",
1921
- suspicious: "off",
1922
- pedantic: "off",
1923
- perf: "off",
1924
- restriction: "off",
1925
- style: "off",
1926
- nursery: "off"
1927
- },
1928
- plugins: customRulesOnly ? [] : ["react", "jsx-a11y"],
1929
- jsPlugins: [...resolveReactHooksJsPlugin(hasReactCompiler, customRulesOnly), pluginPath],
1930
- rules: {
1931
- ...customRulesOnly ? {} : BUILTIN_REACT_RULES,
1932
- ...customRulesOnly ? {} : BUILTIN_A11Y_RULES,
1933
- ...hasReactCompiler && !customRulesOnly ? REACT_COMPILER_RULES : {},
1934
- ...GLOBAL_REACT_DOCTOR_RULES,
1935
- ...framework === "nextjs" ? NEXTJS_RULES : {},
1936
- ...framework === "expo" || framework === "react-native" ? REACT_NATIVE_RULES : {},
1937
- ...framework === "tanstack-start" ? TANSTACK_START_RULES : {},
1938
- ...hasTanStackQuery ? TANSTACK_QUERY_RULES : {}
1939
- }
1940
- });
1947
+ const createOxlintConfig = ({ pluginPath, framework, hasReactCompiler, hasTanStackQuery, customRulesOnly = false }) => {
1948
+ const reactHooksJsPlugin = resolveReactHooksJsPlugin(hasReactCompiler, customRulesOnly);
1949
+ const reactCompilerRules = reactHooksJsPlugin ? filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames) : {};
1950
+ return {
1951
+ categories: {
1952
+ correctness: "off",
1953
+ suspicious: "off",
1954
+ pedantic: "off",
1955
+ perf: "off",
1956
+ restriction: "off",
1957
+ style: "off",
1958
+ nursery: "off"
1959
+ },
1960
+ plugins: customRulesOnly ? [] : ["react", "jsx-a11y"],
1961
+ jsPlugins: reactHooksJsPlugin ? [reactHooksJsPlugin.entry, pluginPath] : [pluginPath],
1962
+ rules: {
1963
+ ...customRulesOnly ? {} : BUILTIN_REACT_RULES,
1964
+ ...customRulesOnly ? {} : BUILTIN_A11Y_RULES,
1965
+ ...reactCompilerRules,
1966
+ ...GLOBAL_REACT_DOCTOR_RULES,
1967
+ ...framework === "nextjs" ? NEXTJS_RULES : {},
1968
+ ...framework === "expo" || framework === "react-native" ? REACT_NATIVE_RULES : {},
1969
+ ...framework === "tanstack-start" ? TANSTACK_START_RULES : {},
1970
+ ...hasTanStackQuery ? TANSTACK_QUERY_RULES : {}
1971
+ }
1972
+ };
1973
+ };
1941
1974
  //#endregion
1942
1975
  //#region src/utils/neutralize-disable-directives.ts
1943
1976
  const DISABLE_DIRECTIVE_PATTERN = /(eslint|oxlint)-disable/;
@@ -3330,7 +3363,7 @@ const promptProjectSelection = async (workspacePackages, rootDirectory) => {
3330
3363
  };
3331
3364
  //#endregion
3332
3365
  //#region src/cli.ts
3333
- const VERSION = "0.0.45";
3366
+ const VERSION = "0.0.47";
3334
3367
  const VALID_FAIL_ON_LEVELS = new Set([
3335
3368
  "error",
3336
3369
  "warning",
package/dist/index.js CHANGED
@@ -1512,16 +1512,45 @@ const REACT_COMPILER_RULES = {
1512
1512
  "react-hooks-js/incompatible-library": "warn",
1513
1513
  "react-hooks-js/todo": "warn"
1514
1514
  };
1515
+ const readPluginRuleNames = (pluginSpecifier) => {
1516
+ try {
1517
+ const pluginModule = esmRequire$1(pluginSpecifier);
1518
+ const rules = pluginModule.rules ?? pluginModule.default?.rules;
1519
+ if (rules === void 0) return /* @__PURE__ */ new Set();
1520
+ return new Set(Object.keys(rules));
1521
+ } catch {
1522
+ return /* @__PURE__ */ new Set();
1523
+ }
1524
+ };
1515
1525
  const resolveReactHooksJsPlugin = (hasReactCompiler, customRulesOnly) => {
1516
- if (!hasReactCompiler || customRulesOnly) return [];
1526
+ if (!hasReactCompiler || customRulesOnly) return null;
1527
+ let pluginSpecifier;
1517
1528
  try {
1518
- return [{
1519
- name: "react-hooks-js",
1520
- specifier: esmRequire$1.resolve("eslint-plugin-react-hooks")
1521
- }];
1529
+ pluginSpecifier = esmRequire$1.resolve("eslint-plugin-react-hooks");
1522
1530
  } catch {
1523
- return [];
1531
+ return null;
1524
1532
  }
1533
+ return {
1534
+ entry: {
1535
+ name: "react-hooks-js",
1536
+ specifier: pluginSpecifier
1537
+ },
1538
+ availableRuleNames: readPluginRuleNames(pluginSpecifier)
1539
+ };
1540
+ };
1541
+ const filterRulesToAvailable = (rules, pluginNamespace, availableRuleNames) => {
1542
+ if (availableRuleNames.size === 0) return rules;
1543
+ const ruleKeyPrefix = `${pluginNamespace}/`;
1544
+ const filtered = {};
1545
+ for (const [ruleKey, severity] of Object.entries(rules)) {
1546
+ if (!ruleKey.startsWith(ruleKeyPrefix)) {
1547
+ filtered[ruleKey] = severity;
1548
+ continue;
1549
+ }
1550
+ const ruleName = ruleKey.slice(ruleKeyPrefix.length);
1551
+ if (availableRuleNames.has(ruleName)) filtered[ruleKey] = severity;
1552
+ }
1553
+ return filtered;
1525
1554
  };
1526
1555
  const TANSTACK_QUERY_RULES = {
1527
1556
  "react-doctor/query-stable-query-client": "warn",
@@ -1667,29 +1696,33 @@ const ALL_REACT_DOCTOR_RULE_KEYS = new Set([
1667
1696
  ...Object.keys(TANSTACK_START_RULES),
1668
1697
  ...Object.keys(TANSTACK_QUERY_RULES)
1669
1698
  ]);
1670
- const createOxlintConfig = ({ pluginPath, framework, hasReactCompiler, hasTanStackQuery, customRulesOnly = false }) => ({
1671
- categories: {
1672
- correctness: "off",
1673
- suspicious: "off",
1674
- pedantic: "off",
1675
- perf: "off",
1676
- restriction: "off",
1677
- style: "off",
1678
- nursery: "off"
1679
- },
1680
- plugins: customRulesOnly ? [] : ["react", "jsx-a11y"],
1681
- jsPlugins: [...resolveReactHooksJsPlugin(hasReactCompiler, customRulesOnly), pluginPath],
1682
- rules: {
1683
- ...customRulesOnly ? {} : BUILTIN_REACT_RULES,
1684
- ...customRulesOnly ? {} : BUILTIN_A11Y_RULES,
1685
- ...hasReactCompiler && !customRulesOnly ? REACT_COMPILER_RULES : {},
1686
- ...GLOBAL_REACT_DOCTOR_RULES,
1687
- ...framework === "nextjs" ? NEXTJS_RULES : {},
1688
- ...framework === "expo" || framework === "react-native" ? REACT_NATIVE_RULES : {},
1689
- ...framework === "tanstack-start" ? TANSTACK_START_RULES : {},
1690
- ...hasTanStackQuery ? TANSTACK_QUERY_RULES : {}
1691
- }
1692
- });
1699
+ const createOxlintConfig = ({ pluginPath, framework, hasReactCompiler, hasTanStackQuery, customRulesOnly = false }) => {
1700
+ const reactHooksJsPlugin = resolveReactHooksJsPlugin(hasReactCompiler, customRulesOnly);
1701
+ const reactCompilerRules = reactHooksJsPlugin ? filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames) : {};
1702
+ return {
1703
+ categories: {
1704
+ correctness: "off",
1705
+ suspicious: "off",
1706
+ pedantic: "off",
1707
+ perf: "off",
1708
+ restriction: "off",
1709
+ style: "off",
1710
+ nursery: "off"
1711
+ },
1712
+ plugins: customRulesOnly ? [] : ["react", "jsx-a11y"],
1713
+ jsPlugins: reactHooksJsPlugin ? [reactHooksJsPlugin.entry, pluginPath] : [pluginPath],
1714
+ rules: {
1715
+ ...customRulesOnly ? {} : BUILTIN_REACT_RULES,
1716
+ ...customRulesOnly ? {} : BUILTIN_A11Y_RULES,
1717
+ ...reactCompilerRules,
1718
+ ...GLOBAL_REACT_DOCTOR_RULES,
1719
+ ...framework === "nextjs" ? NEXTJS_RULES : {},
1720
+ ...framework === "expo" || framework === "react-native" ? REACT_NATIVE_RULES : {},
1721
+ ...framework === "tanstack-start" ? TANSTACK_START_RULES : {},
1722
+ ...hasTanStackQuery ? TANSTACK_QUERY_RULES : {}
1723
+ }
1724
+ };
1725
+ };
1693
1726
  //#endregion
1694
1727
  //#region src/utils/neutralize-disable-directives.ts
1695
1728
  const DISABLE_DIRECTIVE_PATTERN = /(eslint|oxlint)-disable/;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-doctor",
3
- "version": "0.0.45",
3
+ "version": "0.0.47",
4
4
  "description": "Diagnose and fix React codebases for security, performance, correctness, accessibility, bundle-size, and architecture issues",
5
5
  "keywords": [
6
6
  "accessibility",
@@ -66,7 +66,7 @@
66
66
  "commander": "^14.0.3",
67
67
  "knip": "^6.3.1",
68
68
  "ora": "^9.3.0",
69
- "oxlint": "^1.60.0",
69
+ "oxlint": "^1.62.0",
70
70
  "picocolors": "^1.1.1",
71
71
  "prompts": "^2.4.2",
72
72
  "typescript": ">=5.0.4 <7"