@mkrz/oxlint-config 0.1.0
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/CHANGELOG.md +27 -0
- package/LICENSE +21 -0
- package/LICENSE.anti-slop +21 -0
- package/LICENSE.stylistic +22 -0
- package/README.md +283 -0
- package/dist/index.d.ts +93 -0
- package/dist/index.js +624 -0
- package/dist/plugin/index.d.ts +4 -0
- package/dist/plugin/index.js +1957 -0
- package/docs/performance.md +29 -0
- package/docs/rules.md +190 -0
- package/package.json +85 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (2026-09-04)
|
|
4
|
+
|
|
5
|
+
First release.
|
|
6
|
+
|
|
7
|
+
- `mkrz(options?, config?)` builds the whole ruleset as one flat root config
|
|
8
|
+
and layers your own root config on top.
|
|
9
|
+
- `repositoryType: 'app' | 'library' | 'monorepo' | 'auto'` decides where the
|
|
10
|
+
disable-directive policy applies; `auto` reads the working directory.
|
|
11
|
+
- `typeAware` warns and runs without type-checked rules when
|
|
12
|
+
`oxlint-tsgolint` is not installed; an explicit `true` throws.
|
|
13
|
+
- `defineConfig` wrapper that folds `ignorePatterns`, `env`, `globals`, and
|
|
14
|
+
`settings` from extended configs into the root, since Oxlint drops them.
|
|
15
|
+
- Custom rules at `@mkrz/oxlint-config/plugin`, including a port of
|
|
16
|
+
`padding-line-between-statements` so the package has no ESLint dependency.
|
|
17
|
+
- Vendored anti-slop rules with local fixes; see
|
|
18
|
+
`src/plugin/rules/vendor/anti-slop/README.md`.
|
|
19
|
+
|
|
20
|
+
- Config inheritance preserves nested root settings and consumer ignore patterns.
|
|
21
|
+
- Hook rules resolve imports by binding, and type rules respect shadowed types.
|
|
22
|
+
- Monorepo restrictions cover static CommonJS application imports as well as ESM.
|
|
23
|
+
- Missing store selectors include explicit `undefined` and `void` arguments.
|
|
24
|
+
- Type-aware availability follows the consumer executable search path.
|
|
25
|
+
- Custom rule documentation, effective policy snapshots, and a repeatable consumer benchmark.
|
|
26
|
+
- Release publishing uses the exact tested tarball; pack tests support quoted paths.
|
|
27
|
+
- Padding autofixes preserve CRLF and keep directive comments attached to their code.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Michael Kreuzmayr
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dillon Mulroy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright OpenJS Foundation and other contributors, <www.openjsf.org>
|
|
4
|
+
Copyright (c) 2023-PRESENT ESLint Stylistic contributors
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# @mkrz/oxlint-config
|
|
2
|
+
|
|
3
|
+
`@mkrz/oxlint-config` is the Oxlint setup I use for TypeScript and React
|
|
4
|
+
projects. It is a set of guard-rails, not a starting point: every rule runs at
|
|
5
|
+
error severity, and the switches turn whole concerns off, never individual
|
|
6
|
+
rules.
|
|
7
|
+
|
|
8
|
+
## Read this first
|
|
9
|
+
|
|
10
|
+
The ruleset rejects code that most projects accept. Expect the first run on an
|
|
11
|
+
existing codebase to report a lot.
|
|
12
|
+
|
|
13
|
+
- `let` is an error, including `for (let i = 0; …)`. Use `const` and derive a
|
|
14
|
+
new value; use `for…of`.
|
|
15
|
+
- `../` imports are an error everywhere, inside packages too. Set up path
|
|
16
|
+
aliases or package imports first.
|
|
17
|
+
- `as T` is an error except `as const`. Parse the value with a runtime schema
|
|
18
|
+
library or narrow it with a type guard.
|
|
19
|
+
- `unknown` parameters and return types are errors.
|
|
20
|
+
- With `react` on: `useEffect`, `useLayoutEffect`, `useInsertionEffect`,
|
|
21
|
+
`useMemo`, `useCallback`, `useReducer`, and `useSyncExternalStore` are
|
|
22
|
+
errors.
|
|
23
|
+
- In test files, `vi.mock` and `jest.mock` are errors. The test override
|
|
24
|
+
relaxes assertions, not mocking.
|
|
25
|
+
- Disable comments are policed: none at all in applications, one named
|
|
26
|
+
`oxlint-disable-next-line <rule> -- reason` in libraries and packages.
|
|
27
|
+
- Test files are assumed to use vitest.
|
|
28
|
+
- Blank lines between multi-line statements, blocks, and before `return` are
|
|
29
|
+
enforced. This is a style rule with an autofix (`oxlint --fix`), not a
|
|
30
|
+
correctness check; it does not conflict with oxfmt or Prettier.
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
pnpm add -D oxlint @oxlint/plugins oxlint-tsgolint @mkrz/oxlint-config
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`@oxlint/plugins` is a peer dependency so its version always matches the
|
|
39
|
+
`oxlint` you run. `oxlint-tsgolint` powers the type-aware rules; without it
|
|
40
|
+
the default config warns and runs without them.
|
|
41
|
+
|
|
42
|
+
Oxlint cannot resolve npm package names from the `extends` array in
|
|
43
|
+
`.oxlintrc.json`. Use an `oxlint.config.ts` file and import from this package
|
|
44
|
+
instead. Node 22.18 or newer is required because Oxlint loads that file at
|
|
45
|
+
runtime. The package has no ESLint dependency; every custom rule, including the
|
|
46
|
+
blank-line rule, runs as an Oxlint JS plugin.
|
|
47
|
+
|
|
48
|
+
## Use
|
|
49
|
+
|
|
50
|
+
Add an `oxlint.config.ts` file at the root of your project:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { mkrz } from '@mkrz/oxlint-config';
|
|
54
|
+
|
|
55
|
+
export default mkrz();
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`mkrz(options?, config?)` returns one flat Oxlint root config. The plugin is
|
|
59
|
+
declared once, the `correctness` and `suspicious` categories are on at error
|
|
60
|
+
severity once, and there is no subset that fails to load or runs at warning
|
|
61
|
+
severity.
|
|
62
|
+
|
|
63
|
+
### Options
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
export default mkrz({
|
|
67
|
+
react: false,
|
|
68
|
+
typeAware: true,
|
|
69
|
+
repositoryType: 'monorepo',
|
|
70
|
+
appsPath: ['products/**'],
|
|
71
|
+
packagesPath: ['modules/**'],
|
|
72
|
+
appPackages: ['@acme/shop', '@acme/admin-*'],
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
- `react` (default `true`): accessibility, React Compiler, hooks, query, and
|
|
77
|
+
store rules. Turn off for Node services and libraries without JSX.
|
|
78
|
+
- `typeAware` (default `true`): type-checked TypeScript rules. Needs a
|
|
79
|
+
tsconfig and `oxlint-tsgolint`, and costs more lint time. When
|
|
80
|
+
`oxlint-tsgolint` is not installed, the default prints a warning and runs
|
|
81
|
+
without these rules; an explicit `typeAware: true` throws.
|
|
82
|
+
- `repositoryType` (default `'auto'`): where the disable-directive policy
|
|
83
|
+
applies. See below. `appsPath`, `packagesPath`, and `appPackages` are only
|
|
84
|
+
accepted together with `repositoryType: 'monorepo'`.
|
|
85
|
+
|
|
86
|
+
### Your own settings
|
|
87
|
+
|
|
88
|
+
Pass your root config as the second argument. Its `rules` replace this
|
|
89
|
+
package's root rules, its `overrides` run after this package's, and its
|
|
90
|
+
`ignorePatterns`, `env`,
|
|
91
|
+
`globals`, `settings`, and `plugins` are merged with the ruleset's:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { mkrz } from '@mkrz/oxlint-config';
|
|
95
|
+
|
|
96
|
+
export default mkrz(
|
|
97
|
+
{ react: false },
|
|
98
|
+
{
|
|
99
|
+
ignorePatterns: ['**/generated/**'],
|
|
100
|
+
rules: {
|
|
101
|
+
'mkrz/no-let': 'off',
|
|
102
|
+
},
|
|
103
|
+
overrides: [
|
|
104
|
+
{
|
|
105
|
+
files: ['scripts/**'],
|
|
106
|
+
rules: { 'no-alert': 'off' },
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
File overrides take precedence over root rules. To change a rule supplied by
|
|
114
|
+
one of this package's overrides, add a matching override of your own. For
|
|
115
|
+
example, to relax the application directive policy:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
export default mkrz(
|
|
119
|
+
{ repositoryType: 'app' },
|
|
120
|
+
{
|
|
121
|
+
overrides: [
|
|
122
|
+
{ files: ['**/*'], rules: { 'mkrz/no-oxlint-disable': 'off' } },
|
|
123
|
+
],
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
If you compose with Oxlint's `extends` instead, use the `defineConfig` export
|
|
129
|
+
of this package. Oxlint only honors `ignorePatterns`, `env`, `globals`, and
|
|
130
|
+
`settings` on the root config and drops them from extended configs; the
|
|
131
|
+
wrapper folds them back in. The ignore list is also exported as
|
|
132
|
+
`ignorePatterns`.
|
|
133
|
+
|
|
134
|
+
## Repository types
|
|
135
|
+
|
|
136
|
+
- `app`: no Oxlint or ESLint disable comment anywhere.
|
|
137
|
+
- `library`: a single named `oxlint-disable-next-line <rule> -- reason`
|
|
138
|
+
comment is allowed.
|
|
139
|
+
- `monorepo`: the `app` policy under `appsPath` (default `apps/**`), the
|
|
140
|
+
`library` policy under `packagesPath` (default `packages/**`). Files outside
|
|
141
|
+
both, such as root configs, get neither. Packages may not import the
|
|
142
|
+
workspace package names listed in `appPackages` (gitignore-style globs).
|
|
143
|
+
Relative paths that climb out of a package are already rejected by
|
|
144
|
+
`import/no-relative-parent-imports`.
|
|
145
|
+
- `auto` (the default) reads the directory Oxlint runs in: a
|
|
146
|
+
`pnpm-workspace.yaml` with `packages`, a `workspaces` field, or an `apps/`
|
|
147
|
+
or `packages/` directory means `monorepo`. Otherwise `"private": true` in
|
|
148
|
+
`package.json` means `app` and anything else `library`. Without a
|
|
149
|
+
`package.json` it falls back to `app` and says so. A workspace without
|
|
150
|
+
`apps/` or `packages/` is still `monorepo`, but the policy overrides would
|
|
151
|
+
then match nothing, so it warns and asks for explicit `appsPath` and
|
|
152
|
+
`packagesPath`. It is the working
|
|
153
|
+
directory, not the directory of `oxlint.config.ts`, because a config file
|
|
154
|
+
cannot learn its own location from Oxlint; run Oxlint from the repository
|
|
155
|
+
root or set the type explicitly.
|
|
156
|
+
|
|
157
|
+
Unused disable directives are always reported. One bypass the directive rules
|
|
158
|
+
cannot close themselves: a file-level
|
|
159
|
+
`/* oxlint-disable mkrz/no-oxlint-disable */` comment suppresses the very rule
|
|
160
|
+
that reports it and counts as a used directive. The bare `/* oxlint-disable */`
|
|
161
|
+
form is still caught by `unicorn/no-abusive-eslint-disable`. Catching the
|
|
162
|
+
named form needs an out-of-band check, such as a CI grep for
|
|
163
|
+
`oxlint-disable mkrz/`.
|
|
164
|
+
|
|
165
|
+
## React policy
|
|
166
|
+
|
|
167
|
+
`react` rejects `useEffect`, `useLayoutEffect`, `useInsertionEffect`,
|
|
168
|
+
`useReducer`, `useSyncExternalStore`, `useMemo`, and `useCallback`. There is
|
|
169
|
+
deliberately no sanctioned way to subscribe to something outside React by
|
|
170
|
+
hand; that is what the query and store libraries are for. Oxlint's native
|
|
171
|
+
ports of the React Compiler and rules-of-hooks checks run as errors, so no
|
|
172
|
+
ESLint plugin is loaded for React. The rule sees hooks imported from `react`
|
|
173
|
+
and called as `React.useEffect`; a local re-export of React is not followed.
|
|
174
|
+
|
|
175
|
+
With `react` on, both the `browser` and `node` environments are enabled for
|
|
176
|
+
every file. Universal code (server components, loaders) needs both, and file
|
|
177
|
+
location cannot tell them apart. Use separate tsconfigs with appropriate
|
|
178
|
+
`lib` and `types` settings to check environment-specific globals.
|
|
179
|
+
|
|
180
|
+
Side-effect imports are rejected by `import/no-unassigned-import`, except
|
|
181
|
+
stylesheets (`.css`, `.scss`, `.sass`, `.less`). Add other side-effect modules
|
|
182
|
+
such as `server-only` through your root config's `rules`.
|
|
183
|
+
|
|
184
|
+
Query and store hooks are matched by name, on direct calls only: anything of
|
|
185
|
+
the form `use*Query`, `use*Queries`, or `use*Mutation` counts as a query hook,
|
|
186
|
+
and a bound zustand hook named after its store, `use<Name>Store`, counts as a
|
|
187
|
+
store hook, so wrapper hooks such as `useUserQuery` follow the same policy.
|
|
188
|
+
Aliases such as `const query = useQuery` are not followed. Query results
|
|
189
|
+
cannot be object-destructured, and a cast or parentheses do not hide the call.
|
|
190
|
+
Keeping the result together is a project convention: it makes the source of
|
|
191
|
+
each field visible and keeps checks and reads on the same object. TypeScript
|
|
192
|
+
can preserve narrowing for `const { data, isSuccess } = useQuery()` when both
|
|
193
|
+
bindings come from the same destructuring declaration. This rule deliberately
|
|
194
|
+
rejects that valid form too. For mutations, write
|
|
195
|
+
`const mutation = useMutation(...)` and call `mutation.mutate`. Store
|
|
196
|
+
hooks must receive a selector, and the selector may not return the whole
|
|
197
|
+
state. The store rule is written for zustand: the
|
|
198
|
+
bare `useStore(store, selector)` is checked when it is imported from `zustand`
|
|
199
|
+
or `zustand/react`, and a `useStore` from any other module (react-redux,
|
|
200
|
+
MobX) is left alone. Name bound stores by domain; a local
|
|
201
|
+
`const useStore = create(...)` is not recognised. `useSyncExternalStore` is
|
|
202
|
+
not treated as a store hook (it is rejected by the hook policy above
|
|
203
|
+
instead).
|
|
204
|
+
|
|
205
|
+
## Base policy
|
|
206
|
+
|
|
207
|
+
`base` is always on. It turns the `correctness` and `suspicious` categories on
|
|
208
|
+
at error severity for every enabled plugin and lists only the rules outside
|
|
209
|
+
those categories. Three of the listed rules (`no-unreachable-loop`,
|
|
210
|
+
`typescript/prefer-optional-chain`, `react/require-render-return`) are in
|
|
211
|
+
Oxlint's nursery and may be renamed between Oxlint minors.
|
|
212
|
+
|
|
213
|
+
Test files (`**/*.{test,spec}.*`, `**/*.test-d.*`, `**/__tests__/**`) get the
|
|
214
|
+
vitest plugin and may use type assertions and non-null assertions.
|
|
215
|
+
|
|
216
|
+
## Custom rules
|
|
217
|
+
|
|
218
|
+
The custom rules ship from the same package at `@mkrz/oxlint-config/plugin`.
|
|
219
|
+
`mkrz()` loads that subpath itself, so consumers do not configure it
|
|
220
|
+
separately.
|
|
221
|
+
|
|
222
|
+
Rules written for this package:
|
|
223
|
+
|
|
224
|
+
- `mkrz/no-app-requires`: the CommonJS counterpart to monorepo import restrictions.
|
|
225
|
+
- `mkrz/no-let`
|
|
226
|
+
- `mkrz/no-oxlint-disable` and `mkrz/package-disable-policy`
|
|
227
|
+
- `mkrz/no-query-result-destructuring`
|
|
228
|
+
- `mkrz/no-restricted-react-hooks`
|
|
229
|
+
- `mkrz/require-store-selector`
|
|
230
|
+
- `mkrz/no-type-assertion`
|
|
231
|
+
- `mkrz/padding-line-between-statements`: a port of the `@stylistic` rule of
|
|
232
|
+
the same name, with the same options and messages. Oxlint has no esquery,
|
|
233
|
+
so the `selector` option accepts `*` or an exact AST node type instead of a
|
|
234
|
+
full selector.
|
|
235
|
+
|
|
236
|
+
Rules vendored from Dillon Mulroy's anti-slop project, enabled as errors by
|
|
237
|
+
default. The assertion and widening checks are relaxed in test files:
|
|
238
|
+
|
|
239
|
+
- `mkrz/no-chained-type-assertions`
|
|
240
|
+
- `mkrz/no-known-value-widening`
|
|
241
|
+
- `mkrz/no-module-mocking`
|
|
242
|
+
- `mkrz/no-reflect-apply`
|
|
243
|
+
- `mkrz/no-reflect-get`
|
|
244
|
+
- `mkrz/no-unknown-parameters`
|
|
245
|
+
- `mkrz/no-unknown-returns`
|
|
246
|
+
- `mkrz/no-unknown-type-aliases`
|
|
247
|
+
- `mkrz/no-unsafe-dictionary-type`
|
|
248
|
+
- `mkrz/no-widen-then-assert`
|
|
249
|
+
|
|
250
|
+
Examples and migration guidance for every custom rule are in
|
|
251
|
+
[the rule reference](docs/rules.md). Each diagnostic links to its rule there.
|
|
252
|
+
The CommonJS boundary rule uses `ignore` to match the same gitignore-style
|
|
253
|
+
patterns as the native ESM restriction. Dynamic CommonJS module names cannot
|
|
254
|
+
be checked statically; literal `require` and `module.require` calls are checked.
|
|
255
|
+
|
|
256
|
+
The local changes made to the vendored rules are listed in
|
|
257
|
+
`src/plugin/rules/vendor/anti-slop/README.md`.
|
|
258
|
+
|
|
259
|
+
## Versions
|
|
260
|
+
|
|
261
|
+
The peer ranges on `oxlint`, `@oxlint/plugins`, and `oxlint-tsgolint` use `~`
|
|
262
|
+
because Oxlint's JS plugin API is not covered by semver yet; expect a release
|
|
263
|
+
of this package per Oxlint minor. This has a consequence for npm users: npm
|
|
264
|
+
treats an unmet peer range as an install error, so you cannot move to a new
|
|
265
|
+
Oxlint minor until this package has followed (pnpm only warns). Renovate opens
|
|
266
|
+
one grouped PR per Oxlint release, and the tarball is installed and linted in
|
|
267
|
+
CI before every release.
|
|
268
|
+
|
|
269
|
+
## Maintaining the policy
|
|
270
|
+
|
|
271
|
+
`pnpm test` compares the effective native rules, severities, options, and
|
|
272
|
+
custom overrides against `src/__snapshots__/policy.json`. After an intentional
|
|
273
|
+
policy or Oxlint update, run `pnpm run test:update-policy` and review the diff.
|
|
274
|
+
|
|
275
|
+
`pnpm run benchmark` measures cold-process linting of a generated TypeScript
|
|
276
|
+
consumer with type awareness on and off. See [the benchmark notes](docs/performance.md)
|
|
277
|
+
for the fixture, measured results, and limits.
|
|
278
|
+
|
|
279
|
+
## License
|
|
280
|
+
|
|
281
|
+
MIT. The vendored anti-slop code keeps Dillon Mulroy's MIT license and the
|
|
282
|
+
blank-line rule keeps the ESLint Stylistic license. The package includes
|
|
283
|
+
copies at `LICENSE.anti-slop` and `LICENSE.stylistic`.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { OxlintConfig } from "oxlint";
|
|
2
|
+
//#region src/configs/ignore-patterns.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Build output, caches, and lockfiles that should never be linted.
|
|
5
|
+
*
|
|
6
|
+
* Oxlint only honors `ignorePatterns` on the root config; patterns inside an
|
|
7
|
+
* extended config are dropped. Spread this list into the root config.
|
|
8
|
+
*/
|
|
9
|
+
declare const ignorePatterns: string[];
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/configs/monorepo.d.ts
|
|
12
|
+
type MonorepoOptions = {
|
|
13
|
+
/** Globs for application source. Defaults to `['apps/**']`. */
|
|
14
|
+
appsPath?: string[];
|
|
15
|
+
/** Globs for shared package source. Defaults to `['packages/**']`. */
|
|
16
|
+
packagesPath?: string[];
|
|
17
|
+
/**
|
|
18
|
+
* Workspace package names of applications, as gitignore-style globs such as
|
|
19
|
+
* `['@acme/web', '@acme/admin-*']`. Packages may not import them.
|
|
20
|
+
*/
|
|
21
|
+
appPackages?: string[];
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/configs/repository.d.ts
|
|
25
|
+
/**
|
|
26
|
+
* What kind of repository the ruleset runs in. It decides where the
|
|
27
|
+
* disable-directive policies apply:
|
|
28
|
+
*
|
|
29
|
+
* - `app`: no disable comments anywhere.
|
|
30
|
+
* - `library`: a single named `oxlint-disable-next-line <rule> -- reason`
|
|
31
|
+
* comment is allowed anywhere.
|
|
32
|
+
* - `monorepo`: the app policy under `appsPath`, the library policy under
|
|
33
|
+
* `packagesPath`, and packages may not import applications.
|
|
34
|
+
*/
|
|
35
|
+
type RepositoryType = 'app' | 'library' | 'monorepo';
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/mkrz.d.ts
|
|
38
|
+
type Switches = {
|
|
39
|
+
/**
|
|
40
|
+
* React, accessibility, React Compiler, query, and store rules. Turn off
|
|
41
|
+
* for Node services and libraries without JSX. Defaults to `true`.
|
|
42
|
+
*/
|
|
43
|
+
react?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Type-checked rules. These need a tsconfig and `oxlint-tsgolint`, and cost
|
|
46
|
+
* more lint time. Defaults to `true`; when `oxlint-tsgolint` is not
|
|
47
|
+
* installed the default warns and runs without them, while an explicit
|
|
48
|
+
* `true` throws.
|
|
49
|
+
*/
|
|
50
|
+
typeAware?: boolean;
|
|
51
|
+
};
|
|
52
|
+
type MkrzOptions = (Switches & {
|
|
53
|
+
/**
|
|
54
|
+
* Where the disable-directive policies apply. `auto` (the default) reads
|
|
55
|
+
* the working directory: a `pnpm-workspace.yaml` with `packages`, a
|
|
56
|
+
* `workspaces` field, or an `apps/` or `packages/` directory means
|
|
57
|
+
* `monorepo`; otherwise `"private": true` in `package.json` means `app`
|
|
58
|
+
* and anything else `library`. Without a `package.json` it falls back
|
|
59
|
+
* to `app` with a warning.
|
|
60
|
+
*
|
|
61
|
+
* The working directory is used because a config file cannot learn its
|
|
62
|
+
* own location from Oxlint; run Oxlint from the repository root or set
|
|
63
|
+
* the type explicitly. Set `monorepo` explicitly to change the layout
|
|
64
|
+
* globs.
|
|
65
|
+
*/
|
|
66
|
+
repositoryType?: 'auto' | 'app' | 'library';
|
|
67
|
+
}) | (Switches & MonorepoOptions & {
|
|
68
|
+
repositoryType: 'monorepo';
|
|
69
|
+
});
|
|
70
|
+
/**
|
|
71
|
+
* `defineConfig` from Oxlint for consumers who compose with `extends`.
|
|
72
|
+
*
|
|
73
|
+
* Oxlint only honors `ignorePatterns`, `env`, `globals`, and `settings` on
|
|
74
|
+
* the root config and drops them from extended configs. This wrapper folds
|
|
75
|
+
* those fields from every entry of `extends` into the root, and adds this
|
|
76
|
+
* package's ignore list. Prefer the second argument of `mkrz` when you only
|
|
77
|
+
* need to layer settings on this ruleset.
|
|
78
|
+
*/
|
|
79
|
+
declare function defineConfig(config: OxlintConfig): OxlintConfig;
|
|
80
|
+
/**
|
|
81
|
+
* The complete ruleset as one flat root config.
|
|
82
|
+
*
|
|
83
|
+
* Everything is built as a single object rather than a chain of `extends`
|
|
84
|
+
* pieces: the plugin is declared once, the rule categories are declared once,
|
|
85
|
+
* and no subset can be handed to Oxlint that fails to load or runs at the
|
|
86
|
+
* wrong severity. `config` is the consumer's own root config and is layered
|
|
87
|
+
* on top: its root `rules` win over our root rules, its `overrides` run last,
|
|
88
|
+
* and its `ignorePatterns` are added to this package's list. Matching file
|
|
89
|
+
* overrides still take precedence over root rules.
|
|
90
|
+
*/
|
|
91
|
+
declare function mkrz(options?: MkrzOptions, config?: OxlintConfig): OxlintConfig;
|
|
92
|
+
//#endregion
|
|
93
|
+
export { type MkrzOptions, type MonorepoOptions, type RepositoryType, defineConfig, ignorePatterns, mkrz };
|