From bf5ffbf90fd4e63cf1b17e3fe7e6ee01a6815b42 Mon Sep 17 00:00:00 2001 From: No767 <73260931+No767@users.noreply.github.com> Date: Wed, 15 Jul 2026 23:02:02 -0700 Subject: [PATCH] add react doctor rules --- .oxlintrc.json | 65 ++++++++++++++++++++++++++++++++- package.json | 1 + pnpm-lock.yaml | 27 ++++++++------ src/routes/dashboard/events.tsx | 2 +- 4 files changed, 81 insertions(+), 14 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 145fa63a..f40466c0 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -748,6 +748,68 @@ "sonarjs/hooks-before-test-cases": "error", "sonarjs/no-forced-browser-interaction": "error", "sonarjs/super-linear-regex": "error", + "react-doctor/no-fetch-in-effect": "error", + "react-doctor/no-async-effect-callback": "error", + "react-doctor/effect-needs-cleanup": "error", + "react-doctor/effect-listener-cleanup-mismatch": "error", + "react-doctor/no-effect-chain": "error", + "react-doctor/no-self-updating-effect": "error", + "react-doctor/no-effect-with-fresh-deps": "error", + "react-doctor/no-effect-event-in-deps": "error", + "react-doctor/no-stale-timer-ref": "error", + "react-doctor/no-mirror-prop-effect": "error", + "react-doctor/hooks-no-nan-in-deps": "error", + "react-doctor/no-mutable-in-deps": "error", + "react-doctor/no-impure-state-updater": "error", + "react-doctor/no-derived-state": "error", + "react-doctor/no-derived-state-effect": "error", + "react-doctor/no-chain-state-updates": "error", + "react-doctor/no-event-handler": "error", + "react-doctor/no-adjust-state-on-prop-change": "error", + "react-doctor/no-reset-all-state-on-prop-change": "error", + "react-doctor/no-pass-live-state-to-parent": "error", + "react-doctor/no-pass-data-to-parent": "error", + "react-doctor/no-initialize-state": "error", + "react-doctor/no-create-context-in-render": "error", + "react-doctor/no-create-store-in-render": "error", + "react-doctor/no-render-in-render": "error", + "react-doctor/no-ref-current-in-render": "error", + "react-doctor/no-json-parse-stringify-clone": "error", + "react-doctor/no-call-component-as-function": "error", + "react-doctor/no-full-lodash-import": "error", + "react-doctor/no-moment": "error", + "react-doctor/no-barrel-import": "error", + "react-doctor/prefer-dynamic-import": "error", + "react-doctor/no-dynamic-import-path": "error", + "react-doctor/no-layout-property-animation": "error", + "react-doctor/no-transition-all": "error", + "react-doctor/no-permanent-will-change": "error", + "react-doctor/no-large-animated-blur": "error", + "react-doctor/no-long-transition-duration": "error", + "react-doctor/no-global-css-variable-animation": "error", + "react-doctor/no-inline-bounce-easing": "error", + "react-doctor/no-scale-from-zero": "error", + "react-doctor/no-layout-transition-inline": "error", + "react-doctor/client-passive-event-listeners": "error", + "react-doctor/no-img-lazy-with-high-fetchpriority": "error", + "react-doctor/no-undeferred-third-party": "error", + "react-doctor/rendering-script-defer-async": "error", + "react-doctor/activity-wraps-effect-heavy-subtree": "error", + "react-doctor/no-eval": "error", + "react-doctor/no-sync-xhr": "error", + "react-doctor/no-document-write": "error", + "react-doctor/auth-token-in-web-storage": "error", + "react-doctor/zod-v4-no-deprecated-schema-apis": "error", + "react-doctor/zod-v4-no-deprecated-error-apis": "error", + "react-doctor/zod-v4-no-deprecated-error-customization": "error", + "react-doctor/zod-v4-prefer-top-level-string-formats": "error", + "react-doctor/no-react19-deprecated-apis": "error", + "react-doctor/no-react-dom-deprecated-apis": "error", + "react-doctor/dialog-has-accessible-name": "error", + "react-doctor/html-no-invalid-table-nesting": "error", + "react-doctor/html-no-nested-interactive": "error", + "react-doctor/html-no-invalid-paragraph-child": "error", + "react-doctor/no-aria-hidden-on-focusable": "error", "perfectionist/sort-variable-declarations": [ "error", { @@ -867,7 +929,8 @@ "eslint-plugin-sonarjs", "eslint-plugin-perfectionist", "@tanstack/eslint-plugin-query", - "@tanstack/eslint-plugin-router" + "@tanstack/eslint-plugin-router", + { "name": "react-doctor", "specifier": "oxlint-plugin-react-doctor" } ], "env": { "es2026": true, diff --git a/package.json b/package.json index 5ac0d651..9f4ac38f 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "globals": "^17.7.0", "oxfmt": "^0.58.0", "oxlint": "^1.73.0", + "oxlint-plugin-react-doctor": "^0.7.8", "oxlint-tsgolint": "^0.24.0", "react-scan": "^0.5.7", "shadcn": "^4.13.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7744869d..36490005 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -171,6 +171,9 @@ importers: oxlint: specifier: ^1.73.0 version: 1.73.0(oxlint-tsgolint@0.24.0) + oxlint-plugin-react-doctor: + specifier: ^0.7.8 + version: 0.7.8 oxlint-tsgolint: specifier: ^0.24.0 version: 0.24.0 @@ -2148,8 +2151,8 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} - deslop-js@0.7.7: - resolution: {integrity: sha512-mUr2B3FZM+vJZK4w6ZRwuHm6cXVWM5kS4xGRjRLC0yyen/zD+/ZI7QtH/UqUN0LaEIQZL2+P8PMcsDOIB5xgPQ==} + deslop-js@0.7.8: + resolution: {integrity: sha512-QMmb3Z/ARvYZmZneudb8cnY/4mVvZTdhUyA9TC2skwOcm7KvY9zyOdn0TApQc4rL0VM2TffFkmo3ky/lJZX7qw==} detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} @@ -3074,8 +3077,8 @@ packages: vite-plus: optional: true - oxlint-plugin-react-doctor@0.7.7: - resolution: {integrity: sha512-OMl/8k3rcxTSyMJWUL/pdq/ZZKFtv1F4kyM+AWYsj/YYaL/nftL/idrJOxyd2CuFa5Nrbz2DlK3QFRej1uwQ/Q==} + oxlint-plugin-react-doctor@0.7.8: + resolution: {integrity: sha512-3f9/jFLIC/KRLPYqxiXSk20cq47luGy9Oz5Ru7nK7w0EI9B9zuMvAU92bK9jFiwFE7Lc9PA8ER6Y+naYaGFQGw==} engines: {node: ^20.19.0 || >=22.13.0} oxlint-tsgolint@0.24.0: @@ -3265,8 +3268,8 @@ packages: '@types/react': optional: true - react-doctor@0.7.7: - resolution: {integrity: sha512-kHlzPDZNRKlQbXsXgnFh1I4mL0ybt0xJca3/uRMZafaXR4AG5zf7iFMqtdRUiFWHeefE4vGf4YQmkYkXzE1rlg==} + react-doctor@0.7.8: + resolution: {integrity: sha512-G3spmtZJE/gWWPRJ3rpgUWTPRDJpEmdRja7iNZ7RAXlfpEO+NWVzPTca/cPI9hLwPo2Aq5/BZggo5JDBrwGrlA==} engines: {node: ^20.19.0 || >=22.13.0} hasBin: true @@ -5588,7 +5591,7 @@ snapshots: depd@2.0.0: {} - deslop-js@0.7.7: + deslop-js@0.7.8: dependencies: '@oxc-project/types': 0.138.0 fast-glob: 3.3.3 @@ -6569,7 +6572,7 @@ snapshots: '@oxfmt/binding-win32-ia32-msvc': 0.58.0 '@oxfmt/binding-win32-x64-msvc': 0.58.0 - oxlint-plugin-react-doctor@0.7.7: + oxlint-plugin-react-doctor@0.7.8: dependencies: '@typescript-eslint/types': 8.63.0 eslint-scope: 9.1.2 @@ -6759,19 +6762,19 @@ snapshots: optionalDependencies: '@types/react': 19.2.17 - react-doctor@0.7.7(@opentelemetry/core@2.9.0(@opentelemetry/api@1.9.1))(eslint@10.7.0(jiti@2.7.0))(oxlint-tsgolint@0.24.0): + react-doctor@0.7.8(@opentelemetry/core@2.9.0(@opentelemetry/api@1.9.1))(eslint@10.7.0(jiti@2.7.0))(oxlint-tsgolint@0.24.0): dependencies: '@babel/code-frame': 7.29.7 '@sentry/node': 10.65.0(@opentelemetry/core@2.9.0(@opentelemetry/api@1.9.1)) agent-install: 0.0.5 conf: 15.1.0 confbox: 0.2.4 - deslop-js: 0.7.7 + deslop-js: 0.7.8 eslint-plugin-react-hooks: 7.1.1(eslint@10.7.0(jiti@2.7.0)) jiti: 2.7.0 magicast: 0.5.3 oxlint: 1.66.0(oxlint-tsgolint@0.24.0) - oxlint-plugin-react-doctor: 0.7.7 + oxlint-plugin-react-doctor: 0.7.8 prompts: 2.4.2 typescript: 5.9.3 vscode-languageserver: 9.0.1 @@ -6818,7 +6821,7 @@ snapshots: preact: 10.29.7 prompts: 2.4.2 react: 19.2.7 - react-doctor: 0.7.7(@opentelemetry/core@2.9.0(@opentelemetry/api@1.9.1))(eslint@10.7.0(jiti@2.7.0))(oxlint-tsgolint@0.24.0) + react-doctor: 0.7.8(@opentelemetry/core@2.9.0(@opentelemetry/api@1.9.1))(eslint@10.7.0(jiti@2.7.0))(oxlint-tsgolint@0.24.0) react-dom: 19.2.7(react@19.2.7) react-grab: 0.1.48(react@19.2.7) optionalDependencies: diff --git a/src/routes/dashboard/events.tsx b/src/routes/dashboard/events.tsx index f0364cea..b8b53ce3 100644 --- a/src/routes/dashboard/events.tsx +++ b/src/routes/dashboard/events.tsx @@ -274,7 +274,7 @@ function EventsCalendar({ ); } -export function getRosterStatus(member: AttendanceMember): RosterStatus { +function getRosterStatus(member: AttendanceMember): RosterStatus { if (member.attended) return member.planned ? "checked_in" : "walk_in"; return member.planned ? "expected" : "no_show"; }