oxlint-config-awesomeness 3.2.1 → 3.3.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.
Files changed (2) hide show
  1. package/index.js +225 -16
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -582,14 +582,74 @@ export default defineConfig({
582
582
  // Dead imports bloat bundles and mislead readers — remove them.
583
583
  "unused-imports/no-unused-imports": "error",
584
584
 
585
- // React Doctor (react-doctor) — original diagnostic rules from the upstream
586
- // recommended + next + tanstack-query presets, at upstream severities (warn =
587
- // advisory, error = definite bug). Excluded on purpose: the a11y/react-builtins
588
- // buckets (1:1 ports of oxlint-native react/jsx-a11y/react-hooks rules already
589
- // enabled above — or deliberately disabled, like no-array-index-key), the six
590
- // rules the native nextjs plugin already covers, no-eval (core eslint rule is
591
- // on), and react-compiler-no-manual-memoization (contradicts
585
+ // React Doctor (react-doctor): original diagnostic rules at upstream severities
586
+ // (warn = advisory, error = definite bug). Excluded on purpose: the ports of
587
+ // oxlint-native react/jsx-a11y/react-hooks rules already enabled above (or
588
+ // deliberately disabled, like no-array-index-key), the six rules the native
589
+ // nextjs plugin already covers, no-eval (core eslint rule is on), and
590
+ // react-compiler-no-manual-memoization (contradicts
592
591
  // react-hooks-js/preserve-manual-memoization).
592
+ //
593
+ // The plugin grew 337 -> 787 rules between 0.5 and 0.9 with nothing removed or
594
+ // renamed. Of the 450 additions, the ones enabled below are those whose
595
+ // `requires` stack tokens the fleet actually ships (react, tailwind 4, next 15,
596
+ // ssr, i18n). Left off: rules gated on libraries no repo uses (ink, motion,
597
+ // three/r3f, firebase, supabase, react-router), and the visual-taste bucket
598
+ // described at the Maintainability group.
599
+
600
+ // Accessibility: original checks, not the ports excluded above. These cover
601
+ // ground the native jsx-a11y rules do not (Tailwind animation gating, control
602
+ // sizing, landmark and heading structure, focus visibility).
603
+ "react-doctor/anchor-target-exists": "warn",
604
+ "react-doctor/aria-braille-equivalent": "warn",
605
+ "react-doctor/data-table-requires-accessible-name": "warn",
606
+ "react-doctor/details-requires-summary": "warn",
607
+ "react-doctor/dialog-has-accessible-name": "warn",
608
+ "react-doctor/empty-table-header": "warn",
609
+ "react-doctor/fieldset-requires-legend": "warn",
610
+ "react-doctor/html-xml-lang-mismatch": "warn",
611
+ "react-doctor/iframe-title-unique": "warn",
612
+ "react-doctor/loading-action-preserves-trigger": "warn",
613
+ "react-doctor/no-all-caps-body-text": "warn",
614
+ "react-doctor/no-arbitrary-px-font-size": "warn",
615
+ "react-doctor/no-aria-hidden-on-body": "error",
616
+ "react-doctor/no-aria-invalid-without-description": "warn",
617
+ "react-doctor/no-assertive-status": "warn",
618
+ "react-doctor/no-autoplay-without-muted": "warn",
619
+ "react-doctor/no-blocked-paste": "error",
620
+ "react-doctor/no-controlled-selection-focus-effect": "warn",
621
+ "react-doctor/no-cramped-container-padding": "warn",
622
+ "react-doctor/no-crushed-letter-spacing": "warn",
623
+ "react-doctor/no-duplicate-static-id-reference": "error",
624
+ "react-doctor/no-focus-in-animation-completion-handler": "warn",
625
+ "react-doctor/no-focusable-content-in-aria-hidden": "warn",
626
+ "react-doctor/no-focusable-content-in-role-text": "warn",
627
+ "react-doctor/no-hover-only-reveal": "warn",
628
+ "react-doctor/no-inert-pointer-affordance": "warn",
629
+ "react-doctor/no-invalid-progress-range": "error",
630
+ "react-doctor/no-invisible-focus-control": "warn",
631
+ "react-doctor/no-low-contrast-inline-style": "warn",
632
+ "react-doctor/no-multiple-main-landmarks": "warn",
633
+ "react-doctor/no-multiple-unlabeled-navigation-landmarks": "warn",
634
+ "react-doctor/no-nonresizable-textarea": "warn",
635
+ "react-doctor/no-overwide-text-measure": "warn",
636
+ "react-doctor/no-placeholder-only-field": "warn",
637
+ "react-doctor/no-pointer-disabled-enabled-control": "warn",
638
+ "react-doctor/no-presentation-role-conflict": "warn",
639
+ "react-doctor/no-reduced-motion-content-removal": "warn",
640
+ "react-doctor/no-responsive-hidden-accessible-name": "warn",
641
+ "react-doctor/no-server-side-image-map": "warn",
642
+ "react-doctor/no-skipped-heading-level": "warn",
643
+ "react-doctor/no-small-form-control-text": "warn",
644
+ "react-doctor/no-smooth-scroll-without-reduced-motion": "warn",
645
+ "react-doctor/no-tight-body-leading": "warn",
646
+ "react-doctor/no-transitioned-composite-widget-state": "warn",
647
+ "react-doctor/no-transitioned-focus-ring": "warn",
648
+ "react-doctor/no-undersized-icon-button": "warn",
649
+ "react-doctor/no-ungated-tailwind-animation": "warn",
650
+ "react-doctor/no-uninformative-aria-label": "warn",
651
+ "react-doctor/radio-input-missing-name": "warn",
652
+ "react-doctor/role-button-requires-complete-keyboard-activation": "warn",
593
653
 
594
654
  // Architecture — component structure, module boundaries, export hygiene.
595
655
  "react-doctor/no-giant-component": "warn",
@@ -605,6 +665,89 @@ export default defineConfig({
605
665
  "react-doctor/prefer-module-scope-pure-function": "warn",
606
666
  "react-doctor/prefer-module-scope-static-value": "warn",
607
667
 
668
+ // Bugs: runtime defects with a concrete failure mode (hydration mismatches,
669
+ // unguarded parses, effect and listener lifecycle, DOM structure).
670
+ "react-doctor/class-component-missing-component-will-unmount-teardown": "warn",
671
+ "react-doctor/debounce-no-cleanup": "warn",
672
+ "react-doctor/effect-listener-cleanup-mismatch": "error",
673
+ "react-doctor/effect-listener-cleanup-reference-mismatch": "error",
674
+ "react-doctor/effect-observer-needs-disconnect": "error",
675
+ "react-doctor/effect-raf-loop-needs-cancel": "warn",
676
+ "react-doctor/effect-remove-listener-inline-handler": "error",
677
+ "react-doctor/form-control-requires-name": "warn",
678
+ "react-doctor/hook-import-rename-loses-use-prefix": "warn",
679
+ "react-doctor/html-label-has-single-control": "warn",
680
+ "react-doctor/html-no-nested-form": "warn",
681
+ "react-doctor/jsx-numeric-and-leaked-render": "warn",
682
+ "react-doctor/nextjs-async-dynamic-api-not-awaited": "error",
683
+ "react-doctor/nextjs-metadata-url-consistency": "warn",
684
+ "react-doctor/no-arithmetic-on-optional-chained-operand": "warn",
685
+ "react-doctor/no-array-find-result-member-access-without-guard": "warn",
686
+ "react-doctor/no-array-index-deref-without-bounds-or-empty-guard": "warn",
687
+ "react-doctor/no-async-effect-callback": "warn",
688
+ "react-doctor/no-async-event-handler-without-reentry-guard": "warn",
689
+ "react-doctor/no-boolean-toggle-without-functional-update": "warn",
690
+ "react-doctor/no-broken-image-source": "warn",
691
+ "react-doctor/no-call-component-as-function": "warn",
692
+ "react-doctor/no-clipped-overlay": "warn",
693
+ "react-doctor/no-collapse-request-error-to-empty-state": "warn",
694
+ "react-doctor/no-collapsed-literal-or-chain-as-value": "warn",
695
+ "react-doctor/no-controlled-input-value-without-state-update": "warn",
696
+ "react-doctor/no-create-object-url-in-render": "warn",
697
+ "react-doctor/no-create-ref-in-function-component": "warn",
698
+ "react-doctor/no-deprecated-keyboard-event-keycode-which": "warn",
699
+ "react-doctor/no-effect-wrapper-discards-callback-cleanup-return": "warn",
700
+ "react-doctor/no-enter-submit-without-ime-composition-guard": "warn",
701
+ "react-doctor/no-fetch-response-used-without-status-check": "warn",
702
+ "react-doctor/no-fill-map-element-as-key": "warn",
703
+ "react-doctor/no-fixed-inside-transformed-ancestor": "warn",
704
+ "react-doctor/no-floating-then-in-jsx-handler": "warn",
705
+ "react-doctor/no-hydration-branch-on-browser-global": "error",
706
+ "react-doctor/no-impure-call-at-module-scope": "warn",
707
+ "react-doctor/no-impure-state-updater": "error",
708
+ "react-doctor/no-indeterminate-attribute": "warn",
709
+ "react-doctor/no-inert-sticky-position": "warn",
710
+ "react-doctor/no-loading-flag-reset-outside-finally": "warn",
711
+ "react-doctor/no-locale-format-in-render": "warn",
712
+ "react-doctor/no-match-media-in-state-initializer": "warn",
713
+ "react-doctor/no-mixed-srcset-descriptors": "warn",
714
+ "react-doctor/no-mutate-queried-dom-node-in-component": "warn",
715
+ "react-doctor/no-mutate-then-set-or-return-same-reference": "warn",
716
+ "react-doctor/no-mutating-array-method-on-prop-or-hook-result": "warn",
717
+ "react-doctor/no-non-literal-selector-query-without-try-catch": "warn",
718
+ "react-doctor/no-non-null-assertion-on-maybe-undefined-result": "warn",
719
+ "react-doctor/no-nondeterministic-id-value-in-render-body": "warn",
720
+ "react-doctor/no-nullish-coalescing-arithmetic-precedence": "warn",
721
+ "react-doctor/no-object-keys-values-entries-on-maybe-undefined": "warn",
722
+ "react-doctor/no-object-or-array-coerced-to-string-in-template-literal": "warn",
723
+ "react-doctor/no-passive-request-owner-ref": "warn",
724
+ "react-doctor/no-predicate-function-reference-in-boolean-position": "warn",
725
+ "react-doctor/no-promise-then-side-effect-in-effect-without-catch": "warn",
726
+ "react-doctor/no-prop-callback-in-render": "error",
727
+ "react-doctor/no-ref-current-in-render": "error",
728
+ "react-doctor/no-set-state-after-await-in-effect": "warn",
729
+ "react-doctor/no-side-effect-in-state-updater-function": "warn",
730
+ "react-doctor/no-spread-props-over-defaults-clobbers-with-undefined": "warn",
731
+ "react-doctor/no-stale-timer-ref": "warn",
732
+ "react-doctor/no-string-false-on-boolean-attribute": "warn",
733
+ "react-doctor/no-unescaped-dynamic-string-in-regexp": "warn",
734
+ "react-doctor/no-unguarded-browser-global-at-module-scope": "warn",
735
+ // Downgraded from its upstream "error". The rule reports any browser-global
736
+ // read on a render path, but a component behind `dynamic(…, { ssr: false })`
737
+ // and an app with no server render at all are both correct as written, and
738
+ // neither is visible from the file the rule inspects.
739
+ "react-doctor/no-unguarded-browser-global-in-render-or-hook-init": "warn",
740
+ "react-doctor/no-unguarded-numeric-input-parse": "warn",
741
+ "react-doctor/no-unguarded-throwing-parse-call": "warn",
742
+ "react-doctor/no-unowned-async-error-clear": "warn",
743
+ "react-doctor/no-unsafe-json-parse": "warn",
744
+ "react-doctor/no-whole-object-default-losing-per-key-defaults": "warn",
745
+ "react-doctor/no-whole-object-dep-with-member-reads": "warn",
746
+ "react-doctor/pointer-capture-needs-cancel-handler": "warn",
747
+ "react-doctor/shadcn-tabs-trigger-requires-list": "warn",
748
+ "react-doctor/waapi-animation-in-render": "error",
749
+ "react-doctor/web-animation-offsets-valid": "error",
750
+
608
751
  // Bundle size — heavy imports that bloat client bundles.
609
752
  "react-doctor/no-barrel-import": "warn",
610
753
  "react-doctor/no-dynamic-import-path": "warn",
@@ -663,6 +806,40 @@ export default defineConfig({
663
806
  "react-doctor/js-set-map-lookups": "warn",
664
807
  "react-doctor/js-tosorted-immutable": "warn",
665
808
 
809
+ // Maintainability: the mechanically-checkable subset. The rest of this bucket
810
+ // upstream is visual-taste detection (decorative orbs, hero eyebrow chips,
811
+ // uniform feature-card grids); those are design calls, not lint findings.
812
+ "react-doctor/no-auto-scrolling-content": "warn",
813
+ "react-doctor/no-deprecated-tailwind-class": "warn",
814
+ "react-doctor/no-dynamic-tailwind-class-fragment": "warn",
815
+ "react-doctor/no-excessive-font-families": "warn",
816
+ "react-doctor/no-inline-hoc-on-component": "warn",
817
+ "react-doctor/no-layout-shifting-interaction-state": "warn",
818
+ "react-doctor/no-mixed-icon-libraries": "warn",
819
+ "react-doctor/no-redundant-display-class": "warn",
820
+ "react-doctor/no-redundant-title-tooltip": "warn",
821
+ "react-doctor/no-svg-currentcolor-with-fill-class": "warn",
822
+ "react-doctor/prefer-tabular-numeric-data": "warn",
823
+ "react-doctor/prefer-truncate-shorthand": "warn",
824
+ "react-doctor/require-autoplay-video-poster": "warn",
825
+
826
+ // Runtime performance: DOM, media and animation cost.
827
+ "react-doctor/context-provider-value-from-unmemoized-local-literal": "warn",
828
+ "react-doctor/no-create-object-url-without-revoke": "warn",
829
+ "react-doctor/no-document-write": "warn",
830
+ "react-doctor/no-eager-new-in-use-state-initializer": "warn",
831
+ "react-doctor/no-ease-in-motion": "warn",
832
+ "react-doctor/no-img-lazy-with-high-fetchpriority": "warn",
833
+ "react-doctor/no-img-without-dimensions": "warn",
834
+ "react-doctor/no-json-parse-stringify-clone": "warn",
835
+ "react-doctor/no-spread-accumulator-in-reduce": "warn",
836
+ "react-doctor/no-srcset-without-sizes": "warn",
837
+ "react-doctor/no-sync-xhr": "warn",
838
+ "react-doctor/no-tailwind-layout-transition": "warn",
839
+ "react-doctor/no-unbounded-animation-frame-loop": "warn",
840
+ "react-doctor/no-unthrottled-scroll-mutation": "warn",
841
+ "react-doctor/prefer-motion-transform-property": "warn",
842
+
666
843
  // Next.js App Router — RSC/route-handler/metadata pitfalls beyond the native nextjs plugin.
667
844
  "react-doctor/nextjs-error-boundary-missing-use-client": "error",
668
845
  "react-doctor/nextjs-global-error-missing-html-body": "error",
@@ -705,7 +882,47 @@ export default defineConfig({
705
882
  "react-doctor/rerender-transitions-scroll": "warn",
706
883
 
707
884
  // Security.
885
+ "react-doctor/active-static-asset": "warn",
886
+ "react-doctor/agent-tool-capability-risk": "warn",
887
+ "react-doctor/artifact-baas-authority-surface": "warn",
888
+ "react-doctor/artifact-env-leak": "error",
889
+ "react-doctor/artifact-secret-leak": "error",
890
+ "react-doctor/auth-token-in-web-storage": "warn",
891
+ "react-doctor/build-pipeline-secret-boundary": "warn",
892
+ "react-doctor/clickjacking-redirect-risk": "warn",
893
+ "react-doctor/command-execution-input-risk": "error",
894
+ "react-doctor/cors-cookie-trust-risk": "warn",
895
+ "react-doctor/dangerous-html-sink": "warn",
896
+ "react-doctor/git-provider-url-injection-risk": "warn",
897
+ "react-doctor/import-metadata-execution-risk": "error",
898
+ "react-doctor/insecure-crypto-risk": "warn",
899
+ "react-doctor/insecure-session-cookie": "warn",
900
+ "react-doctor/jwt-insecure-verification": "error",
901
+ "react-doctor/key-lifecycle-risk": "error",
902
+ "react-doctor/local-rpc-native-bridge-risk": "warn",
903
+ "react-doctor/mcp-tool-capability-risk": "warn",
904
+ "react-doctor/mdx-ssr-execution-risk": "warn",
905
+ "react-doctor/no-path-prefix-containment": "warn",
708
906
  "react-doctor/no-secrets-in-client-code": "warn",
907
+ "react-doctor/nosql-injection-risk": "warn",
908
+ "react-doctor/package-metadata-secret": "warn",
909
+ "react-doctor/path-traversal-risk": "warn",
910
+ "react-doctor/plugin-update-trust-risk": "warn",
911
+ "react-doctor/postmessage-origin-risk": "warn",
912
+ "react-doctor/public-debug-artifact": "warn",
913
+ "react-doctor/public-env-secret-name": "warn",
914
+ "react-doctor/raw-sql-injection-risk": "warn",
915
+ "react-doctor/react-markdown-unsanitized-raw-html": "warn",
916
+ "react-doctor/repository-secret-file": "error",
917
+ "react-doctor/request-body-mass-assignment": "warn",
918
+ "react-doctor/secret-in-fallback": "error",
919
+ "react-doctor/svg-filter-clickjacking-risk": "warn",
920
+ "react-doctor/tenant-static-proxy-risk": "warn",
921
+ "react-doctor/unsafe-json-in-html": "warn",
922
+ "react-doctor/untrusted-redirect-following": "warn",
923
+ "react-doctor/url-prefilled-privileged-action": "warn",
924
+ "react-doctor/webhook-signature-risk": "warn",
925
+ "react-doctor/window-open-without-noopener": "warn",
709
926
 
710
927
  // Server Components / server code.
711
928
  "react-doctor/server-after-nonblocking": "warn",
@@ -762,15 +979,7 @@ export default defineConfig({
762
979
 
763
980
  // TanStack Query.
764
981
  "react-doctor/query-destructure-result": "error",
765
- // Off: the plugin's 0.5.x check only scans the `useMutation` options object
766
- // literal for a `queryClient.invalidateQueries`-style call, so extracting the
767
- // invalidation into a named hook (`onSuccess: invalidateWallets`) reports as
768
- // missing even though the cache is invalidated. That extraction is the
769
- // idiomatic React Query pattern, and the rule cannot follow any indirection,
770
- // so it fires on correct code and stays silent on the real bug (a mismatched
771
- // queryKey). oxlint-plugin-react-doctor 0.9.x resolves the callback through
772
- // scope; re-enable when this config moves off 0.5.x.
773
- "react-doctor/query-mutation-missing-invalidation": "off",
982
+ "react-doctor/query-mutation-missing-invalidation": "warn",
774
983
  "react-doctor/query-no-query-in-effect": "warn",
775
984
  "react-doctor/query-no-rest-destructuring": "warn",
776
985
  "react-doctor/query-no-usequery-for-mutation": "warn",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oxlint-config-awesomeness",
3
- "version": "3.2.1",
3
+ "version": "3.3.0",
4
4
  "description": "Oxlint config with sensible defaults.",
5
5
  "keywords": [
6
6
  "autofix",
@@ -34,7 +34,7 @@
34
34
  "eslint-plugin-perfectionist": "^5.9.0",
35
35
  "eslint-plugin-react-hooks": "^7.1.1",
36
36
  "eslint-plugin-unused-imports": "~4.4.1",
37
- "oxlint-plugin-react-doctor": "^0.5.1"
37
+ "oxlint-plugin-react-doctor": "^0.9.6"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@changesets/cli": "^2.31.0",