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.
- package/index.js +225 -16
- 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)
|
|
586
|
-
//
|
|
587
|
-
//
|
|
588
|
-
//
|
|
589
|
-
//
|
|
590
|
-
//
|
|
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
|
-
|
|
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.
|
|
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.
|
|
37
|
+
"oxlint-plugin-react-doctor": "^0.9.6"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@changesets/cli": "^2.31.0",
|