Commit Graph

246 Commits

Author SHA1 Message Date
camc314 beb724dce2 fix(linter/eslint/no-unused-vars): report bare underscore parameters (#25663)
## Summary

- report a bare underscore parameter when no args ignore pattern is configured
- preserve the optimized underscore-prefix behavior for explicit argsIgnorePattern configuration
- update focused rule coverage and generated documentation

Closes #25626
2026-08-14 13:16:16 +00:00
Faris Tristan Fabian 2b027111db fix(oxlint): correct --warn flag help text (#25059)
The `-W, --warn` help text says "Deny the rule or category (emit a
warning)", copied from the `-D, --deny` entry.

With that wording, `--warn` and `--deny` look like they do the same
thing in `--help`, but `-W` reports a warning and `-D` reports an error.

Evidence why I think this is not intentional, and instead a typo:

- The other two entries start with their own flag's verb ("Allow the
rule...", "Deny the rule..."). Only the `-W` entry starts with its
sibling's verb, in a sentence identical to the `-D` one except the
parenthetical.
- These flags mirror rustc and clippy's `-A`/`-W`/`-D`, where warn and
deny are two different levels and deny specifically means "make it an
error".
- In this same file, `-W` maps to `AllowWarnDeny::Warn` and `-D` maps to
`AllowWarnDeny::Deny` (`into_tuple`). The internal name for what `-W`
does is warn, not deny.

What changed:

- The `-W` help text is now "Warn on the rule or category (emit a
warning)"
- Updated the two website_linter snapshots, so the generated CLI docs
page picks up the fix

I used Claude Code to help find and fix this.

Co-authored-by: Cameron <cameron.clark@hey.com>
2026-07-29 11:05:18 +01:00
Boshen 3ff2e0e6fa docs(linter): clarify config extends types (#24936)
The generated config reference only described the JSON schema's `string[]` form. Clarify that `oxlint.config.ts` accepts imported `OxlintConfig[]`, add an example and public JSDoc, and regenerate the derived artifacts.

Closes #20238.

Validated with the website generator suite, targeted TypeScript checks, and the relevant Oxlint tests. The full `just ready` run reached an unrelated parallel suppression-fixture cleanup race; the failing test passes in isolation.

AI-assisted.
2026-07-27 01:51:16 +00:00
Mikhail Baev 678bbb5f34 feat(linter/typescript-eslint): implement suggestion for class-literal-property-style rule (#24766)
this PR implements suggestion for
`typescript-eslint/class-literal-property-style` rule. Passes all (19)
[upstream test
cases](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts)

issue #2180
2026-07-22 11:52:59 +01:00
camc314 92f154a07c feat(oxlint,oxfmt): auto-discover .mts config files (#24357)
## Summary

- auto-discover `oxfmt.config.mts` and `oxlint.config.mts`
- watch `.mts` configs in the language server and reject `.ts`/`.mts` conflicts
- add focused CLI and LSP coverage
2026-07-10 11:38:35 +00:00
leaysgur 83378351e4 fix(linter): error on ignorePatterns that cannot match files aoutside the config directory (#24341)
Follow up on #24339

- Added the same guard as Oxfmt
- Since they are identical, I moved them into `oxc_config` so they can be shared
2026-07-10 09:05:48 +00:00
leaysgur 2ce5a33ecc fix(linter): resolve ignorePatterns relative to the config dir (#24339)
Fixes #24310

Root config's `ignorePatterns` are now resolved relative to the directory containing the config file, instead of CWD.

Also fixes a latent issue: a `--config <path>` containing `..` silently disabled all `ignorePatterns` (the unnormalized parent dir never prefix-matches lint target paths). Explicit config paths are now lexically normalized, same as Oxfmt.

### Behavior change

The new anchoring applies in all cases, including `--config` / LSP `configPath`. This intentionally differs from ESLint, which resolves alternate-config ignore patterns relative to CWD:

- `extends`, `overrides[].files`, and JS plugin specifiers are already config-file-relative, including via `--config`
  - rooting only `ignorePatterns` at CWD would give one file two coordinate systems
- Wrappers like Vite+ pass `--config <workspace-root config>` as an implementation detail while CWD stays at the invocation directory, so "`--config` means CWD-relative" does not hold in practice
  - #24276

Impact should be small: bare names (`dist`, `*.min.js`) and `**/`-prefixed patterns are unaffected by the anchor.

The updated `config_ignore_patterns/with_oxlintrc` snapshot shows the `--config` case.
2026-07-10 08:39:56 +00:00
ColemanDunn 002ab355ec fix(linter/unicorn): avoid prefer-array-find rest destructuring false positive (#23654)
## Summary

This PR fixes two issues in `unicorn/prefer-array-find`:

- Oxlint reports a false positive for rest destructuring from
`filter()`, where `find()` is not an equivalent replacement.
- The rule docs are missing supported cases that the implementation
already detects, including array destructuring and `findLast()`-style
patterns. The upstream [eslint-plugin-unicorn
docs](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-find.md)
cover these cases, so this brings Oxlint's docs closer to the equivalent
rule.

## False positive

On this line, Oxlint currently reports a false positive diagnostic from
`unicorn/prefer-array-find`:

```js
const [element, ...restElements] = myArray.filter(isEven);
```

That diagnostic is incorrect because the code keeps both the first
matching element and the remaining matching elements. Replacing it with
`find()` would drop `restElements`, so it is not an equivalent
transformation.

The fix is to only report array destructuring when there is no rest
element. This still reports valid cases like:

```js
const [element] = myArray.filter(isEven);
```

## Docs mismatch

Oxlint already detects more than the docs describe. In addition to
`filter(...)[0]` and `.shift()`, the implementation handles simple array
destructuring and last-match cases using `.at(-1)` or `.pop()`.

This PR updates the docs to include those supported patterns and their
`find()` / `findLast()` replacements, matching the upstream
[eslint-plugin-unicorn
docs](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-find.md)
more closely for the cases Oxlint currently implements.

## Upstream parity mismatch still exists


[`eslint-plugin-unicorn`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-find.md)
also documents and detects `.filter(fn).slice(-1)[0]`-style last-element
patterns. Oxlint does not currently detect that pattern, so this PR does
not document it. That can be handled as a separate parity follow-up.

## Tests

- `cargo fmt -p oxc_linter`
- `cargo test -p oxc_linter prefer_array_find -- --nocapture`
- Manual local repro with `oxlint -D unicorn/prefer-array-find`

## AI assistance

AI assistance was used to prepare this change. I have reviewed the code
and remain responsible for the submission.

Co-authored-by: Cameron <cameron.clark@hey.com>
2026-07-02 17:36:49 +01:00
Mikhail Baev 743e22293b feat(linter/react): add disallowedValues option for forbid-dom-props rule (#23970)
fixes #23049. Tests regenerated from upstream
2026-06-30 09:06:52 +01:00
Connor Shea 9fff263920 docs(linter): Add short descriptions to more rules that lacked them (#23389)
This adds more short descriptions to rules that lacked them, completes
all the rules in the following plugins:

- Oxc
- JSDoc
- Vue
- Nextjs
- Promise
- jsx-a11y

About 200 rules still lack short descriptions, so I'll do those in
subsequent PRs to avoid needing review on any massive sets.

---------

Co-authored-by: Cameron <cameron.clark@hey.com>
2026-06-14 13:56:51 +01:00
Sysix b0d39d7942 test(website): fix tests for win32 (#23398)
fixes the tests on main:
https://github.com/oxc-project/oxc/actions/runs/27479376607/job/81224340552

introduced in https://github.com/oxc-project/oxc/pull/23387
2026-06-14 11:59:06 +00:00
Sysix 49e5649653 test(website): don't snapshot on schema validation (#23387)
It sounds stupid to create a snapshot from an already existing file.
Works on https://github.com/oxc-project/oxc/issues/22955 showed they will always match.

The PR changes the tests so it just checks if the existing file matches the output, without snapshots.
2026-06-13 21:14:05 +00:00
WaterWhisperer f4250d0d08 feat(linter): add schema for unicorn/import-style (#23386)
Adds verified config schema generation for `unicorn/import-style`.

Refs #22955.

Signed-off-by: Alexander S. <sysix@sysix-coding.de>
Co-authored-by: Alexander S. <sysix@sysix-coding.de>
2026-06-13 20:15:53 +02:00
Sysix 26ddac621e fix(linter): avoid config schema generation for jsx_a11y/no-noninteractive-element-interactions (#23385)
Fixes #23299 for now.
We can look later how and where we need to make changes.
2026-06-13 17:57:00 +00:00
Sysix 30c74ce6bf feat(linter): add schema for jsx_a11y/no-noninteractive-element-to-interactive-role (#23384)
+ little refactoring on the other rule, we want to know the defaults from the `Config` and not from the `Rule`.
2026-06-13 17:31:56 +00:00
WaterWhisperer cfbe8dc639 feat(linter): add schema for jsx_a11y/no-interactive-element-to-noninteractive-role (#23382)
Adds verified config schema generation for
`jsx_a11y/no-interactive-element-to-noninteractive-role`.

Refs #22955.
2026-06-13 19:21:13 +02:00
WaterWhisperer d15b7ff197 feat(linter): add schema for typescript/no-restricted-types (#23381)
Adds verified config schema generation for
`typescript/no-restricted-types`.

Refs #22955.

Signed-off-by: Alexander S. <sysix@sysix-coding.de>
Co-authored-by: Alexander S. <sysix@sysix-coding.de>
2026-06-13 18:59:08 +02:00
Sysix 028a8117d3 feat(linter): add schema for jsx-a11y/media-has-caption (#23377) 2026-06-13 16:22:32 +00:00
Sysix b3b1038f38 feat(linter): add schema for jsx-a11y/label-has-associated-control (#23376) 2026-06-13 16:22:32 +00:00
WaterWhisperer 7ada6b2446 feat(linter): add schema for jsx_a11y/no-distracting-elements (#23379)
Adds verified config schema generation for
`jsx_a11y/no-distracting-elements`.

Refs #22955.
2026-06-13 18:15:21 +02:00
Sysix ee3dd49e8b feat(linter): add schema for jsx-a11y/img-redundant-alt (#23374) 2026-06-13 15:54:30 +00:00
Connor Shea df5f8dd5f4 feat(linter): Add short descriptions to most lint rules. (#23365)
This adds short description fields using a codemod script and then
reviewing the result (by myself and with Claude to find any
possibly-weird ones and flag them for me) and then cleaning up some
overly-long or weirdly-formatted rule short descriptions (by myself).

This _does not_ cover all rules, as the codemod was not built to handle
the shared jest/vitest rules or "What it does" sections that were any
more complex than a single sentence. But it handles >75% of them. I'll
work on the remainder in the next few days after we get this part
merged.

I've also made modifications/edits to various rule descriptions and
short descriptions when I noticed as part of this work that they were
overly verbose, inconsistent with the description format of most other
rules, or grammatically incorrect.

<details>
<summary>Codemod script for reference</summary>

```js
#!/usr/bin/env node
// Insert a `short_description = "..."` argument into the
// `declare_oxc_lint!` macro for every rule whose inline-doc "What it does"
// section is a single sentence.
//
// Notes:
//   - Only handles rules with INLINE `///` doc comments. Shared-docs rules
//     (vitest/jest rules pulling from rules/shared) are intentionally skipped.
//   - Markdown links `[text](url)` are flattened to `text`.
//   - The insertion goes right after `version = "...",` so `short_description`
//     sits at the end of the macro arguments. Indentation mirrors `version`.
//   - `declare_oxc_lint!` must accept the `short_description = "..."` argument
//     (see crates/oxc_macros/src/declare_oxc_lint.rs); otherwise the generated
//     code will not compile.
//
// Usage: node insert_short_descriptions.mjs            # dry-run, prints stats + sample diffs
//        node insert_short_descriptions.mjs --write    # actually modify files
//        node insert_short_descriptions.mjs --show <substring>   # preview generated insertions

import { readFileSync, writeFileSync, readdirSync, statSync } from "node:fs";
import { join, relative } from "node:path";

const RULES_DIR = "~/code/oxc/crates/oxc_linter/src/rules";
const SHARED_DIR = join(RULES_DIR, "shared");

function walk(dir) {
  const out = [];
  for (const entry of readdirSync(dir)) {
    const p = join(dir, entry);
    const s = statSync(p);
    if (s.isDirectory()) out.push(...walk(p));
    else if (entry.endsWith(".rs")) out.push(p);
  }
  return out;
}

// --- extraction (inline-only) --------------------------------------------

function ruleDocLines(source) {
  const out = [];
  for (const line of source.split("\n")) {
    const m = line.match(/^\s*\/\/\/ ?(.*)$/);
    if (m) out.push(m[1]);
  }
  return out;
}

function extractWhatItDoesFromMarkdown(lines) {
  let start = -1;
  for (let i = 0; i < lines.length; i++) {
    if (/^\s*###\s+What it does\s*$/i.test(lines[i])) {
      start = i + 1;
      break;
    }
  }
  if (start === -1) return null;
  const body = [];
  for (let i = start; i < lines.length; i++) {
    if (/^\s*###\s+/.test(lines[i])) break;
    body.push(lines[i]);
  }
  while (body.length && body[0].trim() === "") body.shift();
  while (body.length && body[body.length - 1].trim() === "") body.pop();
  return body;
}

// A "What it does" body that contains a markdown list or a URL can't be
// faithfully reduced to a one-line sentence — flattening it produces a run-on
// string (the whole list inlined) or a description that leads with a raw URL.
// Skip these rather than emit garbage.
function hasListOrUrl(bodyLines) {
  let inFence = false;
  for (const line of bodyLines) {
    if (/^\s*```/.test(line)) { inFence = !inFence; continue; }
    if (inFence) continue;
    if (/^\s*([-*+]|\d+\.)\s+/.test(line)) return true; // markdown list item
    if (/https?:\/\//.test(line)) return true;          // bare/inline URL
  }
  return false;
}

function countSentences(bodyLines) {
  const kept = [];
  let inFence = false;
  for (const line of bodyLines) {
    if (/^\s*```/.test(line)) { inFence = !inFence; continue; }
    if (!inFence) kept.push(line);
  }
  let text = kept.join(" ").trim();
  if (!text) return 0;
  text = text.replace(/`[^`]*`/g, "X");
  text = text.replace(/\b(e\.g|i\.e|etc|vs|cf|approx|Mr|Mrs|Ms|Dr|Jr|Sr)\./gi, "$1");
  text = text.replace(/(\d)\.(\d)/g, "$1$2");
  const matches = text.match(/[.!?]+(?=\s|$)/g);
  return matches ? matches.length : 0;
}

// --- build short_description ---------------------------------------------

function bodyToShortDescription(bodyLines) {
  const kept = [];
  let inFence = false;
  for (const line of bodyLines) {
    if (/^\s*```/.test(line)) { inFence = !inFence; continue; }
    if (!inFence) kept.push(line);
  }
  let text = kept.join(" ").replace(/\s+/g, " ").trim();
  let prev;
  do {
    prev = text;
    text = text.replace(/\[([^\]]*)\]\(([^)]*)\)/g, "$1");
  } while (text !== prev);
  return text;
}

function escapeForRustString(s) {
  return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
}

// --- macro surgery -------------------------------------------------------

function findMacroSpan(source) {
  const idx = source.indexOf("declare_oxc_lint!");
  if (idx === -1) return null;
  let i = idx + "declare_oxc_lint!".length;
  while (i < source.length && /\s/.test(source[i])) i++;
  if (source[i] !== "(") return null;
  const open = i;
  let depth = 1;
  i++;
  while (i < source.length && depth > 0) {
    const c = source[i];
    if (c === '"') {
      i++;
      while (i < source.length && source[i] !== '"') {
        if (source[i] === "\\") i++;
        i++;
      }
    } else if (c === "/" && source[i + 1] === "/") {
      while (i < source.length && source[i] !== "\n") i++;
    } else if (c === "(") {
      depth++;
    } else if (c === ")") {
      depth--;
      if (depth === 0) return { open, close: i };
    }
    i++;
  }
  return null;
}

function insertShortDescription(source, sentence) {
  const span = findMacroSpan(source);
  if (!span) return null;
  const inner = source.slice(span.open + 1, span.close);

  // Don't touch rules that already have the field.
  if (/\bshort_description\s*=/.test(inner)) return source;

  // Match the last `version = "..."` assignment. Last-match wins so we skip
  // any stray mentions in doc comments. The trailing comma (if any) is
  // detected separately below — folding `\s*,?` into this regex would let
  // `\s*` swallow the following newline when there is no comma, misplacing the
  // insertion point.
  const versionRe = /\bversion\s*=\s*"(?:[^"\\]|\\.)*"/g;
  let lastMatch = null;
  let vm;
  while ((vm = versionRe.exec(inner)) !== null) lastMatch = vm;
  if (!lastMatch) return null;

  const matchStartAbs = span.open + 1 + lastMatch.index;
  let matchEndAbs = matchStartAbs + lastMatch[0].length;

  // Consume an optional trailing comma that sits on the same line (after only
  // horizontal whitespace), leaving any newline untouched.
  let j = matchEndAbs;
  while (source[j] === " " || source[j] === "\t") j++;
  const hasTrailingComma = source[j] === ",";
  if (hasTrailingComma) matchEndAbs = j + 1;

  let lineStart = matchStartAbs;
  while (lineStart > 0 && source[lineStart - 1] !== "\n") lineStart--;
  const indent = source.slice(lineStart, matchStartAbs);
  const isOnOwnLine = /^\s*$/.test(indent);

  const escaped = escapeForRustString(sentence);

  let insertion;
  if (isOnOwnLine) {
    const prefix = hasTrailingComma ? "" : ",";
    insertion = `${prefix}\n${indent}short_description = "${escaped}",`;
  } else {
    const prefix = hasTrailingComma ? " " : ", ";
    insertion = `${prefix}short_description = "${escaped}",`;
  }

  return source.slice(0, matchEndAbs) + insertion + source.slice(matchEndAbs);
}

// --- main ----------------------------------------------------------------

const args = process.argv.slice(2);
const flag = (n) => args.includes(n);
const showIdx = args.indexOf("--show");
const showNeedle = showIdx >= 0 ? args[showIdx + 1] : null;
const writeMode = flag("--write");

const files = walk(RULES_DIR).sort();

let processed = 0;
let skippedShared = 0;
let skippedMulti = 0;
let skippedListOrUrl = 0;
let skippedMissing = 0;
let skippedAlreadyHas = 0;
let skippedNoVersion = 0;
let changed = 0;
const samples = [];

for (const file of files) {
  if (file.startsWith(SHARED_DIR + "/")) continue;
  const src = readFileSync(file, "utf8");
  if (!/declare_oxc_lint!/.test(src)) continue;
  processed++;

  const docLines = ruleDocLines(src);
  const body = extractWhatItDoesFromMarkdown(docLines);
  if (body === null) { skippedShared++; continue; }
  if (body.length === 0) { skippedMissing++; continue; }
  if (hasListOrUrl(body)) { skippedListOrUrl++; continue; }
  const n = countSentences(body);
  if (n !== 1) { skippedMulti++; continue; }

  const sentence = bodyToShortDescription(body);
  if (!sentence) { skippedMissing++; continue; }

  if (/\bshort_description\s*=/.test(src)) { skippedAlreadyHas++; continue; }

  const updated = insertShortDescription(src, sentence);
  if (updated === null) { skippedNoVersion++; continue; }
  if (updated === src) { skippedAlreadyHas++; continue; }

  if (showNeedle && file.includes(showNeedle)) {
    samples.push({ file, sentence, updated });
  } else if (samples.length < 3 && !showNeedle) {
    samples.push({ file, sentence, updated });
  }

  if (writeMode) writeFileSync(file, updated);
  changed++;
}

console.log(`Rule files scanned:                ${processed}`);
console.log(`Would insert short_description:    ${changed}`);
console.log(`Skipped (shared-docs / no inline): ${skippedShared}`);
console.log(`Skipped (multi-sentence / none):   ${skippedMulti}`);
console.log(`Skipped (list or URL body):        ${skippedListOrUrl}`);
console.log(`Skipped (empty/missing body):      ${skippedMissing}`);
console.log(`Skipped (already has field):       ${skippedAlreadyHas}`);
console.log(`Skipped (no version= found):       ${skippedNoVersion}`);
console.log(writeMode ? `\nWROTE ${changed} files.` : `\nDry run. Pass --write to apply.`);

if (samples.length) {
  console.log("\nSamples:\n");
  for (const s of samples) {
    console.log(`--- ${relative(RULES_DIR, s.file)} ---`);
    console.log(`  short_description = "${escapeForRustString(s.sentence)}"`);
    const span = findMacroSpan(s.updated);
    if (span) {
      const chunk = s.updated.slice(span.open - 20, span.close + 2);
      console.log("");
      for (const line of chunk.split("\n")) console.log("    " + line);
    }
    console.log("");
  }
}
```
</details>

---------

Co-authored-by: Cameron Clark <cameron.clark@hey.com>
2026-06-13 16:54:21 +01:00
Sysix 40556ad8b5 fix(linter): parse jsx-a11y/control-has-associated-label config with DefaultRuleConfig (#23373)
- Used `DefaultRuleConfig` to parse the `serde_json` value
- Moved the 25 cap, to the `Deserializer`
- added schema validation + deny unknown fields
- removed test cases where the upstream rule auto-generated options for every rule
2026-06-13 15:30:37 +00:00
Sysix e3fd735e59 feat(linter): add schema for jsx_a11y/alt-text (#23369)
upstream docs: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/alt-text.md
2026-06-13 15:08:23 +00:00
Mikhail Baev 0f2fff48d2 feat(linter): add schema for react/exhaustive-deps (#23372)
part of #22955
2026-06-13 15:51:43 +01:00
Mikhail Baev e3e4e105bc feat(linter): add schema for react_perf/jsx-no-new-object-as-prop (#23368)
issue #22955

---------

Signed-off-by: Alexander S. <sysix@sysix-coding.de>
Co-authored-by: Alexander S. <sysix@sysix-coding.de>
2026-06-13 15:38:33 +02:00
WaterWhisperer 9366d44cc2 feat(linter): add schema for unicorn/prefer-at (#23366)
Adds verified config schema generation for `unicorn/prefer-at`.

Refs #22955.
2026-06-13 15:29:35 +02:00
Sysix f57b55db11 feat(linter): add schema for typescript/array-type (#23355) 2026-06-12 17:37:36 +00:00
Sysix 0dcf912b16 feat(linter): add schema for typescript/ban-ts-comment (#23354)
Requesting a little review, because the types are little bit complex.
Should be aligned with our tests and the upstream TS type:
https://typescript-eslint.io/rules/ban-ts-comment/#options
2026-06-12 17:26:26 +00:00
Mikhail Baev 51fa83ef5f feat(linter): add schema for react/no-did-update-set-state (#23357)
issue #22955

There are three rules that use the same config and default value:
- `react/no-did-mount-set-state`
- `react/no-did-update-set-state`
- `react/no-will-update-set-state`

this PR also moves that config into a shared `SetStateInFunctionConfig`
type to avoid duplication, similar to the `AlwaysNever` enum
2026-06-12 19:20:41 +02:00
Sysix 59db0bd215 feat(linter): add schema for consistent-generic-constructors (#23353) 2026-06-12 15:07:59 +00:00
Sysix c4775c01b5 feat(linter): add schema for typescript/consistent-type-assertions (#23349)
`assertionStyle` can only be `never` without any other options. This is currently not reflected within the schema.
Upstream docs:
https://typescript-eslint.io/rules/consistent-type-assertions/
2026-06-12 14:05:40 +00:00
Sysix 6e516f75b6 feat(linter): add schema for typescript/consistent-type-imports (#23348) 2026-06-12 14:05:40 +00:00
WaterWhisperer 012134d6cb feat(linter): add schema for react/jsx-no-target-blank (#23345)
Adds verified config schema generation for `react/jsx-no-target-blank`.

Refs #22955.

---------

Signed-off-by: Cameron <cameron.clark@hey.com>
Co-authored-by: Cameron <cameron.clark@hey.com>
2026-06-12 14:44:22 +01:00
Mikhail Baev 0806aae474 feat(linter): add schema for jsx_a11y/no-noninteractive-tabindex (#23337)
issue #22955

also replaced manual config parsing with `DefaultRuleConfig`
2026-06-12 13:39:39 +02:00
Mikhail Baev 0708b5a233 feat(linter): add schema for react/jsx-filename-extension (#23315)
issue #22955

---------

Co-authored-by: Cameron <cameron.clark@hey.com>
2026-06-12 10:05:03 +01:00
Sysix 150bce13e4 feat(linter): add schema for typescript/no-empty-object-type (#23309) 2026-06-12 00:45:31 +00:00
Sysix f9e36f1738 feat(linter): add schema for typescript/no-duplicate-type-constituents (#23308) 2026-06-12 00:45:30 +00:00
Sysix 937accf58f feat(linter): add schema for typescript/no-invalid-void-type (#23307) 2026-06-11 23:58:30 +00:00
Sysix 3e042b9dbd feat(linter): add schema for typescript/no-misused-promises (#23306) 2026-06-11 23:58:30 +00:00
Sysix da212d1d1d feat(linter): add schema for typescript/no-unnecessary-condition (#23305)
The upstream rule has an option we do not to support:
```
    /** Whether to not error when running with a tsconfig that has strictNullChecks turned. */
    allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing?: boolean;
```
https://typescript-eslint.io/rules/no-unnecessary-condition/
2026-06-11 23:45:58 +00:00
Sysix f8f0d38eb3 feat(linter): add schema for typescript/parameter-properties (#23304) 2026-06-11 22:41:24 +00:00
Sysix 2275fc7ec1 feat(linter): add schema for typescript/prefer-nullish-coalescing (#23302)
The upstream rules does support one more option, but I guess we do not want this:

```
    /** Unless this is set to `true`, the rule will error on every file whose `tsconfig.json` does _not_ have the `strictNullChecks` compiler option (or `strict`) set to `true`. */
    allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing?: boolean;
```

https://typescript-eslint.io/rules/prefer-nullish-coalescing

Another little difference: The upstream rule marks as `true | IgnorePrimitivesOptions`, we support the `false` value too.
2026-06-11 22:20:24 +00:00
Sysix d353858d1c feat(linter): add schema for typescript/prefer-string-starts-ends-with (#23301)
Should we deprecate/remove the unicorn version of it?
https://oxc.rs/docs/guide/usage/linter/rules/unicorn/prefer-string-starts-ends-with

We marked some rules as unsupported because they should use the type-aware version. 🤔
2026-06-11 21:47:41 +00:00
Sysix 03060f5f06 feat(linter): add schema for typescript/triple-slash-reference (#23300)
Little review please because of the enum removal  🙇
#23301 has a question too.
2026-06-11 21:29:40 +00:00
Sysix 6619ceeffa feat(linter): add schema for promise/param-names (#23298) 2026-06-11 20:54:38 +00:00
Sysix 8bf108e2a1 feat(linter): add schema for promise/catch-or-return (#23297) 2026-06-11 20:40:14 +00:00
Sysix 48158d00b7 feat(linter): add schema for vitest/consistent-each-for (#23294) 2026-06-11 20:27:30 +00:00
Sysix 7e74c98794 feat(linter): add schema for vitest/consistent-test-filename (#23293) 2026-06-11 22:03:48 +02:00
camc314 71e9648564 fix(linter): expose no-noninteractive-element-interactions schema (#23283)
## Summary

- Remove only `jsx_a11y/no-noninteractive-element-interactions` from the unverified schema skip list.
- Regenerate the oxlint JSON schema, website schema snapshot, and generated TypeScript config types.
- Leave `jsx_a11y/no-interactive-element-to-noninteractive-role` on the skip list for a separate fix.
2026-06-11 19:57:47 +00:00