- Render `u32::MAX` defaults as `Infinity` in generated markdown docs.
- Keeps the `require-top-level-describe` docs stable on 32-bit targets, where `u32::MAX` also equals `usize::MAX`.
This should fix the faiking 32 bit tests
> This PR enhances Oxlint configuration schema fidelity by expanding `DummyRuleMap` to explicitly list all built-in rules as schema properties (improving editor autocomplete), while adding markdown-renderer filtering to avoid generating massive documentation sections for `rules`.
<img width="632" height="391" alt="grafik" src="https://github.com/user-attachments/assets/732bf81b-b090-429a-8bcd-20f0a6a54aa6" />
When a property references a type via `$ref` and both have doc comments, the markdown renderer was dropping the property-level description.
```rs
/// A set of glob patterns. // ← type-level
pub struct GlobSet(Vec<String>);
```
```rs
pub struct OxfmtOverrideConfig {
/// Glob patterns to match files for this override. // ← property-level
pub files: GlobSet,
}
```
Before:
```
#### overrides[n].files
A set of glob patterns.
```
After:
```
#### overrides[n].files
Glob patterns to match files for this override.
A set of glob patterns.
```
At present, some definitions may seem redundant, but since unifying them at the prop-level seemed inconvenient for linter use cases, I decided to provide both.
The intended convention is generic invariants on the type-level, contextual purpose on the property-level.
> ## Pull request overview
> This PR adds automated generation of website documentation for oxlint’s LSP linting options by exposing the LSP options schema, rendering it to markdown, and snapshot-testing the output.
An PR on `oxc-project/website` is needed. Will wait for the next release to improve the LSP & Editor docs too :)
When you have a json schema with a type of `Option<Enum>`, it seemed to not generate the docs correctly. Now, it will properly render all of the possible variants in this case.
Currently, fields defined as `key: Option<T>` are represented in TS as `key?: T | null`.
However, passing `null` actually just treats it as `None`, which only creates noise.
Claude's summary:
- Enhanced `schema_markdown.rs` to properly handle `allOf` schemas
created by the `RemoveRefSiblings` visitor
- When a `$ref` has sibling properties (like `description`), schemars'
draft-07 visitor wraps it in an `allOf`
- The renderer now resolves through `allOf` structures to find the
actual referenced schema
----
This fixes the problem discovered in
https://github.com/oxc-project/oxc/pull/19387#issuecomment-3999084412.
This actually improves the generated docs for a few rules:
- `typescript/no-deprecated`
- `no-floating-promises`
- `react/forbid-dom-props`
- `typescript/no-misused-spread`
- `typescript/only-throw-error`
- `typescript/prefer-readonly-parameter-types`
- `typescript/prefer-nullish-coalescing`
- `typescript/restrict-template-expressions`
Basically, any rule that has a struct nested inside an array has better
docs now, as the docs generator actually handles their schema correctly
now.
AI Disclosure: Generated by Claude Code.
Examples:
no-deprecated
````md
## Configuration
This rule accepts a configuration object with the following properties:
### allow
type: `array`
default: `[]`
An array of type or value specifiers that are allowed to be used even if deprecated.
Use this to allow specific deprecated APIs that you intentionally want to continue using.
#### allow[n]
type: `object | string`
Type or value specifier for matching specific declarations
Supports four types of specifiers:
1. **String specifier** (deprecated): Universal match by name
```json
"Promise"
```
2. **File specifier**: Match types/values declared in local files
```json
{ "from": "file", "name": "MyType" }
{ "from": "file", "name": ["Type1", "Type2"] }
{ "from": "file", "name": "MyType", "path": "./types.ts" }
```
3. **Lib specifier**: Match TypeScript built-in lib types
```json
{ "from": "lib", "name": "Promise" }
{ "from": "lib", "name": ["Promise", "PromiseLike"] }
```
4. **Package specifier**: Match types/values from npm packages
```json
{ "from": "package", "name": "Observable", "package": "rxjs" }
{ "from": "package", "name": ["Observable", "Subject"], "package":
"rxjs" }
```
##### allow[n].from
type: `"file"`
##### allow[n].name
type: `array | string`
Name specifier that can be a single string or array of strings
###### allow[n].name[n]
type: `string`
##### allow[n].path
type: `string`
Optional file path to specify where the types or values must be declared.
If omitted, all files will be matched.
````
react/forbid-dom-props
````md
## Configuration
Configuration for the `forbid-dom-props` rule.
This rule accepts a configuration object with the following properties:
### forbid
type: `array`
An array of prop names or objects that are forbidden on DOM elements.
Each array element can be a string with the property name, or an object
with `propName`, an optional `disallowedFor` array of DOM node names,
and an optional custom `message`.
Examples:
- `["error", { "forbid": ["id", "style"] }]`
- `["error", { "forbid": [{ "propName": "className", "message": "Use class instead" }] }]`
- `["error", { "forbid": [{ "propName": "style", "disallowedFor": ["div", "span"] }] }]`
#### forbid[n]
type: `object | string`
A forbidden prop, either as a plain prop name string or with options.
##### forbid[n].disallowedFor
type: `string[]`
A list of DOM element names (e.g. `["div", "span"]`) on which this
prop is forbidden. If empty or omitted, the prop is forbidden on all
DOM elements.
##### forbid[n].message
type: `string`
A custom message to display when this prop is used.
##### forbid[n].propName
type: `string`
The name of the prop to forbid.
````
---------
Co-authored-by: Claude <noreply@anthropic.com>
Fixes#17191. Previously, the docs were incorrect and a bit confusing for the user to understand. Now it's possible to actually configure the linter rule based on the docs.
AI Disclosure: Change was made with help from Claude Code and also based on the changes originally made with https://github.com/oxc-project/oxc/pull/17208.
Generated docs:
```md
## Configuration
Configuration for the capitalized-comments rule.
The first element specifies whether comments should `"always"` or `"never"`
begin with a capital letter. The second element is an optional object
containing additional options.
### The 1st option
type: `"always" | "never"`
### The 2nd option
This option is an object with the following properties:
#### block
type: `object`
Configuration options specific to block comments.
##### block.ignoreConsecutiveComments
type: `boolean`
If true, consecutive comments will be ignored after the first comment.
##### block.ignoreInlineComments
type: `boolean`
If true, inline comments (comments in the middle of code) will be ignored.
##### block.ignorePattern
type: `string`
A regex pattern. Comments that match the pattern will not cause violations.
#### ignoreConsecutiveComments
type: `boolean`
If true, consecutive comments will be ignored after the first comment.
#### ignoreInlineComments
type: `boolean`
If true, inline comments (comments in the middle of code) will be ignored.
#### ignorePattern
type: `string`
A regex pattern. Comments that match the pattern will not cause violations.
#### line
type: `object`
Configuration options specific to line comments.
##### line.ignoreConsecutiveComments
type: `boolean`
If true, consecutive comments will be ignored after the first comment.
##### line.ignoreInlineComments
type: `boolean`
If true, inline comments (comments in the middle of code) will be ignored.
##### line.ignorePattern
type: `string`
A regex pattern. Comments that match the pattern will not cause violations.
```
The initial goal was to extract the schema generation utility from `oxfmtrc.rs`.
However, I found that `oxc_linter` also defines a similar function, so I unified them into `website_common`.
- Added `generate_schema_json<T>()` to `website_common`
- Removed duplicated implementations from `oxfmtrc.rs` and `oxlintrc.rs`
- Moved `test_schema_json` from `oxc_linter` to `website_linter` too
NOTE: When running `cargo t -p oxc_linter`, it previously generated `npm/oxlint/configuration_schema.json`. Now use `just linter-schema-json` instead.
## Summary
- Filter out `| null` from type annotations in website documentation markdown
- Keeps JSON schema files unchanged (they still have proper null types for validation)
- Makes documentation cleaner since users typically omit optional fields rather than setting them to null
**Before:** `type: boolean | null`
**After:** `type: boolean`
## Test plan
- [x] `cargo test -p website_formatter test_schema_markdown`
- [x] `cargo test -p website_linter test_schema_markdown`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Enum config options were rendering as `string | null` in the generated documentation, hiding valid values from users.
## Changes
- **`schema_markdown.rs`**: Enhanced `anyOf` schema processing to detect and extract enum values from referenced types, rendering them as quoted string literals instead of generic type names
- **Snapshot update**: Regenerated test snapshot reflecting new enum value display
## Before/After
```markdown
# Before
type: `string | null`
# After
type: `"always" | "avoid" | null`
```
Affected fields: `arrowParens`, `endOfLine`, `trailingComma`, `quoteProps`, `objectWrap`, `embeddedLanguageFormatting`, and nested enums like `experimentalSortImports.order`.
Values are extracted programmatically from the JSON schema rather than hardcoded in doc comments.
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>docs(formatter): Improve config file reference docs to show possible enum values</issue_title>
> <issue_description>Improve the formatter's config file reference by rendering the possible enum values for the top-level config file attributes.
>
> <img width="500" height="161" alt="Image" src="https://github.com/user-attachments/assets/fd0a43ef-d1c8-4d0d-9c1c-32d9a303b563" />
>
> https://oxc.rs/docs/guide/usage/formatter/config-file-reference.html
>
> Right now, there's no way to tell what the allowed values are for `arrowParens`, `endOfLine`, `trailingComma`, etc. They all render as `string | null`.
>
> We can temporarily/easily fix this by updating the doc comments to list all available options, but ideally we would fix this via the `schema_markdown.rs` file in `website_common/`.
>
> I tried fixing this by updating the oxfmtrc.rs file with a `schemars with` to remove the Option<> wrapping, like so:
>
> ```rs
> /// Include parentheses around a sole arrow function parameter. (Default: `"always"`)
> #[serde(skip_serializing_if = "Option::is_none")]
> #[schemars(with = "ArrowParensConfig")]
> pub arrow_parens: Option<ArrowParensConfig>,
> ```
>
> Which fixes the `type` rendering, but for some reason that stops printing the code comments, so... that's annoying.</issue_description>
>
> <agent_instructions>Display possible values of enum config options in the oxfmt config file docs. You can see the generated config file page by running `cargo run -p website_formatter schema-markdown` to print the generated docs page.
>
> Do not hardcode the possible values into the doc comments in oxfmtrc.rs. You should update tasks/website_common/src/schema_markdown.rs (and any other relevant files) to generate them from the json schema we have defined.</agent_instructions>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixesoxc-project/oxc#16589
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
## Summary
- Disable `test = false` and `doctest = false` for crates that have no tests
- Reduces CI noise from "0 passed; 0 failed" output
- Saves compilation time for empty test targets
**Affected crates:**
- `oxc_ast_macros` - lib test
- `oxc_language_server` - bin test, lib doctest
- `oxc_napi` - lib test
- `oxc_syntax` - lib doctest
- `oxc_compat_data` - bin test
- `oxc_coverage` - lib test
- `oxc_linter_codegen` - bin test
- `oxc_prettier_conformance` - lib test
- `oxc_transform_conformance` - lib test
- `vscode_docs` - bin test
- `website_common` - lib test, lib doctest
## Test plan
- [x] `cargo test` passes with no empty test suites
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Include configuration examples for clarity, and ensure the severity level is included in the examples to make it easier to understand for the end-user.
I also used Claude Opus to fix a bug in the `sanitize` method, where it crashed when you had a json code block on a non-indented doc comment, which was hilarious.
Generated docs:
```md
## Configuration
This rule accepts three types of configuration:
1. **Global rule** (string): `"always"`, `"never"`, or `"ignorePackages"`
\```json
{
"rules": {
// this would require extensions for all imports
"import/extensions": ["error", "always"]
}
}
\```
2. **Per-extension rules** (object): `{ "js": "always", "jsx": "never", ... }`
\```json
{
"rules": {
"import/extensions": [
"error",
// per-extension rules:
// require extensions for .js imports and disallow them for .ts imports
{ "js": "always", "ts": "never" }
]
}
}
\```
3. **Combined** (array): `["error", "always", { "js": "never" }]` or `["error", { "js": "always" }]`
\```json
{
"rules": {
"import/extensions": [
"error",
"always", // by default, require extensions for all imports
{ "ts": "never" } // override the global value and disallow extensions on imports for specific file types
]
}
}
\```
**Default behavior (no configuration)**: All imports pass.
Unconfigured file extensions are ignored, to avoid false positives.
This rule accepts a configuration object with the following properties:
### checkTypeImports
type: `boolean`
default: `false`
Whether to check type imports when enforcing extension rules.
### extensions
type: `Record<string, string>`
default: `{}`
Map from file extension (without dot) to its configured rule.
### ignorePackages
type: `boolean`
default: `false`
Whether to ignore package imports when enforcing extension rules.
A boolean option (not per-extension) that exempts package imports from the "always" rule.
Can be set in the config object: `["error", "always", { "ignorePackages": true }]`
Legacy shorthand: `["error", "ignorePackages"]` is equivalent to `["error", "always", { "ignorePackages": true }]`
- **With "always"**: When `true`, package imports (e.g., `lodash`, `@babel/core`) don't require extensions
- **With "never"**: This option has no effect; extensions are still forbidden on package imports
Example: `["error", "always", { "ignorePackages": true }]` allows `import foo from "lodash"` but requires `import bar from "./bar.js"`
### pathGroupOverrides
type: `array`
default: `[]`
Path group overrides for bespoke import specifiers.
Array of pattern-action pairs for custom import protocols (monorepo tools, custom resolvers).
Each override has: `{ "pattern": "<glob-pattern>", "action": "enforce" | "ignore" }`
**Pattern matching**: Uses glob patterns (`*`, `**`, `{a,b}`) to match import specifiers.
**Actions**:
- `"enforce"`: Apply normal extension validation (respect global/per-extension rules)
- `"ignore"`: Skip all extension validation for matching imports
**Precedence**: First matching pattern wins.
Example: `["error", "always", { "pathGroupOverrides": [{ "pattern": "rootverse{*,*/**}", "action": "ignore" }] }]`
- Allows `import { x } from 'rootverse+debug:src'` without extension
- Still requires extensions for standard imports
#### pathGroupOverrides[n]
type: `object`
Path group override configuration for bespoke import specifiers.
Allows fine-grained control over extension validation for custom import protocols
(e.g., monorepo tools, custom resolvers, framework-specific imports).
**Pattern matching:**
Uses fast-glob patterns to match import specifiers:
- `*`: Match any characters except `/`
- `**`: Match any characters including `/` (recursive)
- `{a,b}`: Match alternatives
**Examples:**
\```json
{
"pattern": "rootverse{*,*/**}",
"action": "enforce"
}
\```
Matches: `rootverse+debug:src`, `rootverse+bfe:src/symbols`
##### pathGroupOverrides[n].action
type: `"enforce" | "ignore"`
Action to take for path group overrides.
Determines how import extensions are validated for matching bespoke import specifiers.
###### `"enforce"`
Enforce extension validation for matching imports (require extensions based on config)
###### `"ignore"`
Ignore matching imports entirely (skip all extension validation)
##### pathGroupOverrides[n].pattern
type: `string`
Glob pattern to match import specifiers
```
Somehow raptor mini managed to figure out the needle in the haystack here after I wrote a sufficient prompt for it, neat. This retains the fix for the formatter markdown headers while also fixing the problem with the linter markdown :)
Prompt was:
```
How can we update the depth numbers in schema_markdown.rs in order to fix the header for `categories` in the snapshot? The `categories` header should be an `h2` (so `## categories`, but currently renders as 3).
We need to fix this somehow while ensuring that `arrowParens`, `bracketSameLine`, `useTabs`, etc. in `tasks/website_formatter/src/snapshots/schema_markdown.snap` are kept as `h2`s. You can regenerate these two snapshots by running `cargo test -p website_formatter -- test_schema_markdown && cargo test -p website_linter -- test_schema_markdown`
```
- Extract Renderer and schema rendering logic from website_linter to website_common
- Add schema-json and schema-markdown commands to website_formatter
🤖 Generated with [Claude Code](https://claude.com/claude-code)