react-doctor 0.2.0-beta.4 → 0.2.0-beta.6

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.d.ts CHANGED
@@ -11,6 +11,70 @@ interface ReactDoctorIgnoreConfig {
11
11
  overrides?: ReactDoctorIgnoreOverride[];
12
12
  tags?: string[];
13
13
  }
14
+ /**
15
+ * Discrete output channels a diagnostic can flow through after a scan.
16
+ * Each surface is filtered independently so a rule can be visible
17
+ * locally but excluded from PR comments, the score, or the CI gate:
18
+ *
19
+ * - `cli` — local terminal output from `react-doctor` (`printDiagnostics`).
20
+ * - `prComment` — output captured by the GitHub Action for the sticky
21
+ * PR comment. Enabled when the CLI is run with `--pr-comment` (the
22
+ * action sets this automatically when `github-token` is provided).
23
+ * - `score` — diagnostics shipped to the React Doctor score API
24
+ * (or counted toward local score calculations).
25
+ * - `ciFailure` — diagnostics that count toward the `--fail-on` exit
26
+ * code gate. A diagnostic excluded from this surface never fails the
27
+ * build, regardless of severity.
28
+ *
29
+ * Defaults: design rules (tag `"design"`) are excluded from `prComment`,
30
+ * `score`, and `ciFailure` so style cleanup doesn't dilute meaningful
31
+ * React findings. They remain in `cli` so locally-running developers
32
+ * still see the suggestion when they touch the file.
33
+ */
34
+ type DiagnosticSurface = "cli" | "prComment" | "score" | "ciFailure";
35
+ /**
36
+ * Severity value accepted by the top-level `rules` and `categories`
37
+ * config fields. Exactly the same form ESLint and oxlint accept:
38
+ * `"off"` skips registration entirely (the rule never runs and
39
+ * never enters any surface); `"error"` / `"warn"` change the rule's
40
+ * registered severity.
41
+ *
42
+ * For visibility-only adjustments (silence on PR comments but keep
43
+ * on CLI / score), prefer `surfaces` instead — severity applies
44
+ * before lint runs and is the most aggressive control.
45
+ */
46
+ type RuleSeverityOverride = "error" | "warn" | "off";
47
+ /**
48
+ * Internal shape consumed by `resolveRuleSeverityOverride` and
49
+ * `applySeverityControls`. Assembled at runtime from the top-level
50
+ * `rules` and `categories` fields on `ReactDoctorConfig`. Per-rule
51
+ * wins over per-category when both match the same diagnostic.
52
+ */
53
+ interface SurfaceControls {
54
+ /**
55
+ * Tag names whose diagnostics should be force-included on the surface,
56
+ * even if a default or category-level exclusion would otherwise drop
57
+ * them. Include wins over exclude when both apply to the same rule.
58
+ */
59
+ includeTags?: string[];
60
+ /**
61
+ * Tag names whose diagnostics should be excluded from the surface.
62
+ * Use this to silence whole rule families (e.g. `["design"]`,
63
+ * `["test-noise"]`) for a single channel without touching others.
64
+ */
65
+ excludeTags?: string[];
66
+ /** Category names (e.g. `"Architecture"`) to force-include. */
67
+ includeCategories?: string[];
68
+ /** Category names (e.g. `"Architecture"`) to exclude. */
69
+ excludeCategories?: string[];
70
+ /**
71
+ * Fully-qualified rule keys (`"<plugin>/<rule>"`, e.g.
72
+ * `"react-doctor/design-no-redundant-size-axes"`) to force-include.
73
+ */
74
+ includeRules?: string[];
75
+ /** Fully-qualified rule keys to exclude from this surface. */
76
+ excludeRules?: string[];
77
+ }
14
78
  interface ReactDoctorConfig {
15
79
  ignore?: ReactDoctorIgnoreConfig;
16
80
  lint?: boolean;
@@ -56,6 +120,20 @@ interface ReactDoctorConfig {
56
120
  * suppresses regardless of sibling content.
57
121
  */
58
122
  rawTextWrapperComponents?: string[];
123
+ /**
124
+ * Project-level allowlist of function names that the
125
+ * `server-auth-actions` rule treats as an auth check at the top of
126
+ * a server action. Names are accepted whether called as a bare
127
+ * identifier (`myAuthGuard()`) or as the final property of a
128
+ * member call (`ctx.myAuthGuard()`); unlike the built-in default
129
+ * list, user-provided names are treated as distinctive and never
130
+ * subject to receiver-object disambiguation.
131
+ *
132
+ * Use this to teach react-doctor about custom auth guards in
133
+ * codebases that wrap their auth library — e.g. a project-local
134
+ * `requireWorkspaceMember` or `ensureSignedIn`.
135
+ */
136
+ serverAuthFunctionNames?: string[];
59
137
  /**
60
138
  * Whether to respect inline `// eslint-disable*`, `// oxlint-disable*`,
61
139
  * and `// react-doctor-disable*` comments in source files. Default: `true`.
@@ -96,6 +174,63 @@ interface ReactDoctorConfig {
96
174
  * Set to `false` to scan only react-doctor's curated rule set.
97
175
  */
98
176
  adoptExistingLintConfig?: boolean;
177
+ /**
178
+ * Per-surface include/exclude controls. Each `DiagnosticSurface` is
179
+ * resolved independently against rule tags, category, and id so a
180
+ * single rule can be visible locally yet hidden from PR comments,
181
+ * neutralized from the score, and excluded from `--fail-on` — all
182
+ * without touching the rule's severity or activation.
183
+ *
184
+ * Defaults (applied before user overrides):
185
+ *
186
+ * - `prComment` excludes tag `"design"`
187
+ * - `score` excludes tag `"design"`
188
+ * - `ciFailure` excludes tag `"design"`
189
+ *
190
+ * Pass any controls block (even an empty `{}`) to keep the default
191
+ * exclusions; the user's include/exclude entries layer on top.
192
+ * Include entries always win over exclude entries — handy for
193
+ * promoting a single high-signal `design-*` rule back into the
194
+ * score or PR-comment surface.
195
+ */
196
+ surfaces?: Partial<Record<DiagnosticSurface, SurfaceControls>>;
197
+ /**
198
+ * Per-rule severity map — the exact ESLint / oxlint top-level
199
+ * `rules` field. Keys are fully-qualified rule keys
200
+ * (`"<plugin>/<rule>"`, e.g. `"react-doctor/no-array-index-as-key"`),
201
+ * values are `"error" | "warn" | "off"`.
202
+ *
203
+ * `"off"` skips registration in the generated lint config so the
204
+ * rule never runs; `"error"` / `"warn"` re-stamp the registered
205
+ * severity and the post-lint diagnostic, so downstream consumers
206
+ * (`--fail-on`, the score, the printed list) all see the
207
+ * user-chosen severity.
208
+ *
209
+ * For visibility-only changes (silence on PR comments but keep on
210
+ * CLI / score), prefer `surfaces` instead. Most specific control
211
+ * wins: `rules` > `categories` > `tags`.
212
+ *
213
+ * ```json
214
+ * { "rules": { "react-doctor/no-array-index-as-key": "error" } }
215
+ * ```
216
+ */
217
+ rules?: Record<string, RuleSeverityOverride>;
218
+ /**
219
+ * Per-category severity map. Mirrors oxlint's top-level
220
+ * `categories` field, but keyed by React Doctor's display
221
+ * categories (`"Server"`, `"React Native"`, `"Architecture"`,
222
+ * `"Bundle Size"`, `"State & Effects"`, `"Security"`,
223
+ * `"Accessibility"`, `"Performance"`, `"Correctness"`, …).
224
+ *
225
+ * ```json
226
+ * { "categories": { "React Native": "warn", "Server": "off" } }
227
+ * ```
228
+ *
229
+ * To silence a whole tag-defined rule family (e.g. `"design"`,
230
+ * `"test-noise"`, `"migration-hint"`) that doesn't align with a
231
+ * single category, use `ignore.tags` instead.
232
+ */
233
+ categories?: Record<string, RuleSeverityOverride>;
99
234
  } //#endregion
100
235
  //#region src/diagnostic.d.ts
101
236
  interface Diagnostic {
@@ -124,6 +259,20 @@ interface ProjectInfo {
124
259
  hasTypeScript: boolean;
125
260
  hasReactCompiler: boolean;
126
261
  hasTanStackQuery: boolean;
262
+ /**
263
+ * `true` when the project (or any of its workspace packages) declares
264
+ * React Native or Expo as a dependency. Enables the `react-native`
265
+ * capability — and therefore every `rn-*` rule — even on web-rooted
266
+ * monorepos where the entry-point `package.json` is Next / Vite /
267
+ * Remix but a sibling workspace (`apps/mobile`, `packages/native-ui`)
268
+ * targets React Native. The file-level package-boundary check in
269
+ * `oxlint-plugin-react-doctor` still keeps the rules silent on the
270
+ * web workspaces.
271
+ *
272
+ * `false` collapses the gate to the legacy "framework is RN" behavior
273
+ * — no `rn-*` rules load for the project at all.
274
+ */
275
+ hasReactNativeWorkspace: boolean;
127
276
  sourceFileCount: number;
128
277
  }
129
278
  //#endregion