Skip to content

feat!: write lint directives into generated files (13.0.0) - #24

Merged
maxholman merged 7 commits into
masterfrom
feat/lint-directives
Sep 23, 2026
Merged

maxholman merged 7 commits into
masterfrom
feat/lint-directives

Conversation

@maxholman

@maxholman maxholman Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Breaking: the ./oxlint export is removed

@block65/openapi-codegen/oxlint pointed at a .ts file, and node refuses to strip types under node_modules, so importing it into a lint config broke that consumer's lint. The export, defineOverrides and generatedFiles are gone. Delete the override from your lint config and regenerate.

Lint directives in generated files

After writing, the generator runs the project's own oxlint over the files it wrote, with the project's config. Each file gets one line naming only the exempt rules that fired in it:

// oxlint-disable block65/prefer-exact-optional

Naming only rules that fired keeps reportUnusedDisableDirectives satisfied. Rules outside the exempt list still reach the consumer's lint, as generator bugs to report. Every run relints every file, so the directives follow the current lint config, including after an upgrade from 12. A file that lands on its recorded revision gets its bytes on disk back. With no oxlint in the project the files get no directive. If the config fails to load, the generator warns and writes none.

The exempt list covers the comment rules (the prose is transcribed from the document), no-single-character-declaration, unicorn/max-nested-calls and prefer-exact-optional.

prefer-strict-object is never exempt

looseObject passes a peer's unnamed keys through. An object the document leaves open is now a lint error at the consumer until the document sets additionalProperties: false. The one exception is a header schema, which is v.object() on purpose because a request carries headers the document does not name. Where the rule fires on one, the generator brackets that declaration with // oxlint-disable block65/prefer-strict-object -- <reason> and a matching enable. This repo turns the rule off for the valibot modules of its three third-party fixture documents, and test1 closes its own objects.

in: cookie stops generation

No command or validator reads a cookie, so the parameter used to be dropped without a word. Generation now throws naming the operation and the parameter, as in: querystring already does.

Dependencies

oxlint plugin 0.11.0 and shared-config 0.5.0. The plugin deletes snake-case-wire-keys, so the exempt list drops it and a test holds the fixture directives free of it.

just check: 59 tests, 0 warnings.

maxholman Bot and others added 7 commits September 23, 2026 15:30
The package exported `./oxlint` for consumers to spread into their lint
config, but the export pointed at a .ts file, and node refuses to strip
types under node_modules, so importing it broke the consumer's lint.

The generator now runs the consumer's own oxlint over the files it writes
and prefixes each with an `oxlint-disable` naming the exempt rules that
fired in it. Naming only rules that fired keeps `reportUnusedDisableDirectives`
satisfied. The exemption list and its reasons stay here; the export,
`defineOverrides` and `generatedFiles` go.

BREAKING CHANGE: `@block65/openapi-codegen/oxlint` is removed. Delete the
override from your lint config and regenerate.

Co-Authored-By: LLM <noreply@block65.dev>
No command or validator reads a cookie, so the parameter was dropped
without a word. It now throws naming the operation and the parameter, as
`in: querystring` already does.

BREAKING CHANGE: a document with a cookie parameter no longer generates.

Co-Authored-By: LLM <noreply@block65.dev>
Each module gains the lint directive for the exempt rules that fire in it,
and the `#generator` stamp moves in every manifest.

Co-Authored-By: LLM <noreply@block65.dev>
`looseObject` passes a peer's unnamed keys through, which is how a secret
leaked from fifo. The generator no longer exempts `prefer-strict-object`,
so a document that leaves an object open fails the consumer's lint until
it sets `additionalProperties: false`. The fixtures are third-party
documents, so this repo turns the rule off for them.

Co-Authored-By: LLM <noreply@block65.dev>
Plugin 0.11.0 deletes `snake-case-wire-keys`, so the exempt list drops it
and the fixtures regenerate without it. A test holds every fixture
directive free of the rule, and the manifest test loses its now-unused
directive.

Co-Authored-By: LLM <noreply@block65.dev>
Only rewritten files were linted, so a file the manifest recorded as
current kept whatever directives it had. After an upgrade from 12, or a
change to the consumer's lint config, that left lint red. Every run now
writes and lints every file, the directives count toward the recorded
revision, and a file that lands on its recorded revision gets its bytes
back.

A header schema is `v.object()` on purpose: a request carries headers the
document does not name. Where `prefer-strict-object` fires on one, the
declaration is bracketed by a disable and enable naming that reason. An
open body object stays an error.

Co-Authored-By: LLM <noreply@block65.dev>
test1 is our own document, so its four open schemas now set
`additionalProperties: false`. Three were `allOf` merges, which the
generator closes only when the merged schema says so. The
`prefer-strict-object` override now names only the valibot modules of the
three third-party documents.

Co-Authored-By: LLM <noreply@block65.dev>
@maxholman
maxholman merged commit b4acf6b into master Sep 23, 2026
4 checks passed
@maxholman
maxholman Bot deleted the feat/lint-directives branch September 27, 2026 13:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant