@jameswyse/oxc-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/LICENSE +21 -0
- package/README.md +213 -0
- package/REFERENCE.md +134 -0
- package/dist/format.d.ts +5 -0
- package/dist/format.js +47 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +97 -0
- package/dist/lint.d.ts +33 -0
- package/dist/lint.js +493 -0
- package/dist/rules/companion-has-owner.d.ts +1 -0
- package/dist/rules/companion-has-owner.js +74 -0
- package/dist/rules/electron-no-raw-ipc-renderer-exposure.d.ts +1 -0
- package/dist/rules/electron-no-raw-ipc-renderer-exposure.js +127 -0
- package/dist/rules/electron-no-remote-module.d.ts +1 -0
- package/dist/rules/electron-no-remote-module.js +112 -0
- package/dist/rules/electron-secure-web-preferences.d.ts +1 -0
- package/dist/rules/electron-secure-web-preferences.js +108 -0
- package/dist/rules/explicit-api-states.d.ts +1 -0
- package/dist/rules/explicit-api-states.js +143 -0
- package/dist/rules/import-boundaries.d.ts +1 -0
- package/dist/rules/import-boundaries.js +99 -0
- package/dist/rules/no-ambient-clock.d.ts +1 -0
- package/dist/rules/no-ambient-clock.js +35 -0
- package/dist/rules/no-ambient-random.d.ts +1 -0
- package/dist/rules/no-ambient-random.js +71 -0
- package/dist/rules/no-comments.d.ts +1 -0
- package/dist/rules/no-comments.js +64 -0
- package/dist/rules/no-deep-ternary.d.ts +1 -0
- package/dist/rules/no-deep-ternary.js +32 -0
- package/dist/rules/no-edit-proof-assertions.d.ts +1 -0
- package/dist/rules/no-edit-proof-assertions.js +120 -0
- package/dist/rules/no-env-access.d.ts +1 -0
- package/dist/rules/no-env-access.js +35 -0
- package/dist/rules/no-fixed-test-delay.d.ts +1 -0
- package/dist/rules/no-fixed-test-delay.js +130 -0
- package/dist/rules/no-forwarding-module.d.ts +1 -0
- package/dist/rules/no-forwarding-module.js +158 -0
- package/dist/rules/no-generic-file-suffix.d.ts +1 -0
- package/dist/rules/no-generic-file-suffix.js +74 -0
- package/dist/rules/no-pass-through-function.d.ts +1 -0
- package/dist/rules/no-pass-through-function.js +106 -0
- package/dist/rules/no-swallowed-errors.d.ts +1 -0
- package/dist/rules/no-swallowed-errors.js +168 -0
- package/dist/rules/no-test-timeout-overrides.d.ts +1 -0
- package/dist/rules/no-test-timeout-overrides.js +105 -0
- package/dist/rules/no-vacuous-test-assertions.d.ts +1 -0
- package/dist/rules/no-vacuous-test-assertions.js +71 -0
- package/dist/rules/server-action-guard.d.ts +1 -0
- package/dist/rules/server-action-guard.js +109 -0
- package/dist/rules/statement-spacing.d.ts +1 -0
- package/dist/rules/statement-spacing.js +29 -0
- package/dist/rules/type-guard-name.d.ts +1 -0
- package/dist/rules/type-guard-name.js +59 -0
- package/dist/shared/index.d.ts +26 -0
- package/dist/shared/index.js +260 -0
- package/dist/shared/rule-options.d.ts +2 -0
- package/dist/shared/rule-options.js +8 -0
- package/dist/vendor/anti-slop/effect/rules/no-manual-effect-error-tag.d.ts +1 -0
- package/dist/vendor/anti-slop/effect/rules/no-manual-effect-error-tag.js +35 -0
- package/dist/vendor/anti-slop/effect/rules/no-service-constructor-imports.d.ts +1 -0
- package/dist/vendor/anti-slop/effect/rules/no-service-constructor-imports.js +48 -0
- package/dist/vendor/anti-slop/effect/shared/tagged-values.d.ts +9 -0
- package/dist/vendor/anti-slop/effect/shared/tagged-values.js +65 -0
- package/dist/vendor/anti-slop/rules/no-array-filter-map.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-array-filter-map.js +40 -0
- package/dist/vendor/anti-slop/rules/no-chained-type-assertions.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-chained-type-assertions.js +58 -0
- package/dist/vendor/anti-slop/rules/no-conditional-empty-object-spread.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-conditional-empty-object-spread.js +41 -0
- package/dist/vendor/anti-slop/rules/no-known-value-widening.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-known-value-widening.js +333 -0
- package/dist/vendor/anti-slop/rules/no-module-mocking.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-module-mocking.js +74 -0
- package/dist/vendor/anti-slop/rules/no-object-parameters.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-object-parameters.js +59 -0
- package/dist/vendor/anti-slop/rules/no-reduce-accumulator-copy.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-reduce-accumulator-copy.js +124 -0
- package/dist/vendor/anti-slop/rules/no-reflect-apply.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-reflect-apply.js +26 -0
- package/dist/vendor/anti-slop/rules/no-reflect-get.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-reflect-get.js +26 -0
- package/dist/vendor/anti-slop/rules/no-runtime-typeof.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-runtime-typeof.js +63 -0
- package/dist/vendor/anti-slop/rules/no-shape-in-symbol-names.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-shape-in-symbol-names.js +37 -0
- package/dist/vendor/anti-slop/rules/no-unknown-returns.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-unknown-returns.js +61 -0
- package/dist/vendor/anti-slop/rules/no-unknown-type-aliases.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-unknown-type-aliases.js +38 -0
- package/dist/vendor/anti-slop/rules/no-unsafe-dictionary-type.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-unsafe-dictionary-type.js +143 -0
- package/dist/vendor/anti-slop/rules/no-widen-then-assert.d.ts +1 -0
- package/dist/vendor/anti-slop/rules/no-widen-then-assert.js +288 -0
- package/dist/vendor/anti-slop/shared/array-method.d.ts +10 -0
- package/dist/vendor/anti-slop/shared/array-method.js +95 -0
- package/dist/vendor/anti-slop/shared/dictionary-types.d.ts +23 -0
- package/dist/vendor/anti-slop/shared/dictionary-types.js +408 -0
- package/dist/vendor/anti-slop/shared/function-parameters.d.ts +6 -0
- package/dist/vendor/anti-slop/shared/function-parameters.js +41 -0
- package/dist/vendor/anti-slop/shared/lexical-type-parameters.d.ts +4 -0
- package/dist/vendor/anti-slop/shared/lexical-type-parameters.js +32 -0
- package/dist/vendor/anti-slop/shared/reflect-method.d.ts +3 -0
- package/dist/vendor/anti-slop/shared/reflect-method.js +24 -0
- package/dist/vendor/anti-slop/shared/scope.d.ts +3 -0
- package/dist/vendor/anti-slop/shared/scope.js +12 -0
- package/dist/vendor/anti-slop/shared/type-alias-resolution.d.ts +21 -0
- package/dist/vendor/anti-slop/shared/type-alias-resolution.js +147 -0
- package/dist/vendor/eslint-stylistic/padding-line-ast.d.ts +14 -0
- package/dist/vendor/eslint-stylistic/padding-line-ast.js +19 -0
- package/dist/vendor/eslint-stylistic/padding-line-between-statements.d.ts +91 -0
- package/dist/vendor/eslint-stylistic/padding-line-between-statements.js +493 -0
- package/package.json +89 -0
- package/src/vendor/anti-slop/LICENSE +21 -0
- package/src/vendor/eslint-stylistic/LICENSE +22 -0
- package/tsconfig.base.json +10 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 James Wyse
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# @jameswyse/oxc-config
|
|
2
|
+
|
|
3
|
+
Opinionated [Oxlint](https://oxc.rs/docs/guide/usage/linter.html) and [Oxfmt](https://oxc.rs/docs/guide/usage/formatter.html) configs for TypeScript and JavaScript projects. They combine Oxlint's native rules with custom rules for type and data safety, comment-free code, configuration ownership, import boundaries, server-action guards, test reliability and statement spacing.
|
|
4
|
+
|
|
5
|
+
The rules aim to keep both people and coding agents on the same standards: parse external data at the seam, use named exports, never ship console logging, and let names, types and tests carry intent instead of comments. [The reference](REFERENCE.md) maps each standard to its rules and states what lint cannot check.
|
|
6
|
+
|
|
7
|
+
Requires Node.js 22.23 or later. Supports Oxlint 1.86 or later, Oxfmt 0.71 or later and oxlint-tsgolint 7.0.2003 or later, within their current major versions.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
pnpm add -D @jameswyse/oxc-config oxlint oxfmt oxlint-tsgolint
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The React profile uses `eslint-plugin-react-you-might-not-need-an-effect`, which declares an ESLint peer even though it runs under Oxlint. To skip installing ESLint with pnpm, add this to the project's `pnpm-workspace.yaml` before installing:
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
autoInstallPeers: false
|
|
19
|
+
peerDependencyRules:
|
|
20
|
+
ignoreMissing:
|
|
21
|
+
- eslint
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`autoInstallPeers` affects every dependency in the workspace. No ESLint configuration is needed either way.
|
|
25
|
+
|
|
26
|
+
## Configure
|
|
27
|
+
|
|
28
|
+
Create `oxlint.config.ts` in the project root:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { createLintConfig } from "@jameswyse/oxc-config/oxlint";
|
|
32
|
+
|
|
33
|
+
export default createLintConfig();
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Type-aware checking is on by default. It needs the project's `tsconfig.json` and `oxlint-tsgolint`, which uses TypeScript 7. Configurations that rely on removed options such as `baseUrl` need migrating first. For plain JavaScript or a TypeScript project that is not yet compatible, pass `typeAware: false`. Syntax and scope rules still run, and explicit `any` is still rejected.
|
|
37
|
+
|
|
38
|
+
Create `oxfmt.config.ts` beside it:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { formatConfig } from "@jameswyse/oxc-config/oxfmt";
|
|
42
|
+
|
|
43
|
+
export default formatConfig;
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Add the scripts:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"scripts": {
|
|
51
|
+
"lint": "oxlint .",
|
|
52
|
+
"lint:fix": "oxlint --fix . && oxfmt . && oxlint .",
|
|
53
|
+
"format": "oxfmt .",
|
|
54
|
+
"format:check": "oxfmt --check ."
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Errors fail the run. Warnings mark patterns worth reviewing that have legitimate uses, so they report without blocking: dependency cycles, barrel and forwarding modules, `typeof` outside type guards, swallowed errors, boolean parameters on exported functions, pass-through functions, tests without a matching owner file and test timeout overrides. `lint:fix` formats after applying lint fixes, then lints again to confirm the result.
|
|
60
|
+
|
|
61
|
+
## Select framework and runtime profiles
|
|
62
|
+
|
|
63
|
+
Enable only the tools the project uses. Each profile accepts `true` for its default scope or an array of project-relative globs. `nextjs` takes application root directories instead of globs.
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { createLintConfig } from "@jameswyse/oxc-config/oxlint";
|
|
67
|
+
|
|
68
|
+
export default createLintConfig({ react: true, vitest: true });
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
For a monorepo with separate server and browser packages:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { createLintConfig } from "@jameswyse/oxc-config/oxlint";
|
|
75
|
+
|
|
76
|
+
export default createLintConfig({
|
|
77
|
+
nextjs: ["apps/web"],
|
|
78
|
+
react: ["packages/ui/**/*.{ts,tsx}"],
|
|
79
|
+
node: ["packages/server/**/*.ts"],
|
|
80
|
+
vitest: ["**/*.{test,spec}.{ts,tsx}"],
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
| Option | Adds |
|
|
85
|
+
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| `react` | React and React Compiler rules, accessibility rules, effect-misuse rules, and e18e performance rules outside tests |
|
|
87
|
+
| `nextjs` | The React profile plus Next.js rules, with default exports allowed for `app` and `pages` entrypoints under each root |
|
|
88
|
+
| `node` | Node.js environment and rules |
|
|
89
|
+
| `vitest` | Vitest rules; its globs join the shared test scope |
|
|
90
|
+
| `jest` | Jest rules; keep its scope separate from Vitest when both exist |
|
|
91
|
+
| `effect` | Effect error-tag and service-import rules, for modules that use [Effect](https://effect.website) |
|
|
92
|
+
| `tests` | Extra test globs, such as Playwright or Node tests, for the custom test rules |
|
|
93
|
+
| `electron` | Electron security rules everywhere, and an import boundary keeping `electron` and `node:*` out of the renderer (`src/renderer/**` by default, or `{ renderer: [...] }`) |
|
|
94
|
+
|
|
95
|
+
Default exports are also accepted where a tool loads them: config files, Storybook stories and `.storybook`, `sanity.cli`, GraphQL Codegen entrypoints and declaration files.
|
|
96
|
+
|
|
97
|
+
In a monorepo, run Oxlint from each package with a `tsconfig.json`, or pass an existing lint tsconfig with `--tsconfig`.
|
|
98
|
+
|
|
99
|
+
## Enforce project boundaries
|
|
100
|
+
|
|
101
|
+
These options need the project to name its owners, so each is off until configured. Globs are relative to the directory Oxlint runs from.
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { createLintConfig } from "@jameswyse/oxc-config/oxlint";
|
|
105
|
+
|
|
106
|
+
export default createLintConfig({
|
|
107
|
+
react: ["src/renderer/**"],
|
|
108
|
+
env: ["src/main/config.ts", "src/renderer/env.ts"],
|
|
109
|
+
boundaries: [
|
|
110
|
+
{
|
|
111
|
+
files: ["src/renderer/**"],
|
|
112
|
+
deny: ["electron", "node:*", "@main/**", "src/main/**"],
|
|
113
|
+
message: "Use the typed contextBridge API exposed by the preload process.",
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
serverActionGuards: ["requireStaffPermission", "requireMember"],
|
|
117
|
+
clock: ["src/platform/clock.ts"],
|
|
118
|
+
random: ["src/platform/ids.ts"],
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
- `env` lists the modules that may read `process.env` or `import.meta.env`. Other source files must receive parsed configuration. Config files and scripts are entrypoints and remain allowed.
|
|
123
|
+
- `boundaries` rejects imports from `files` that match a `deny` glob. Bare specifiers match as written. Relative specifiers resolve to a project path first, so `../main/ipc` matches `src/main/**`. Type-only imports are allowed because they are erased. Use `ignore` to exclude files from a boundary's scope.
|
|
124
|
+
- `serverActionGuards` requires every exported function in a `"use server"` module, and every inline `"use server"` function, to start by awaiting one of the named guards. Server-action modules must export each action where it is declared. A guard's name cannot prove it authorises the operation, so review the guard itself.
|
|
125
|
+
- `clock` and `random` list the modules that may read the current time (`Date.now()`, argument-less `new Date()`) or generate random values and IDs (`Math.random()`, `crypto.randomUUID()`, `randomUUID`/`randomInt` from `node:crypto`). Other production code must receive them, so tests can control them without faking globals. Test files, parameter defaults such as `now = new Date()` and passing `Date.now` uncalled are allowed. Durations from `performance.now()` and secret generation are out of scope.
|
|
126
|
+
|
|
127
|
+
## Share strict compiler settings
|
|
128
|
+
|
|
129
|
+
The package exports `strict`, `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`, `noImplicitOverride` and `noFallthroughCasesInSwitch` as a base config. Extend it from the project's `tsconfig.json` and keep target, module and path settings local:
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"extends": "@jameswyse/oxc-config/tsconfig"
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
In an existing project, `noUncheckedIndexedAccess` and `exactOptionalPropertyTypes` usually surface many type errors, so adopt them as a separate migration.
|
|
138
|
+
|
|
139
|
+
## Add project-specific exceptions
|
|
140
|
+
|
|
141
|
+
Append overrides to the returned config so its framework and test overrides stay active. Oxlint applies file overrides after top-level `rules`, so type-aware and framework rules can only be changed by a later override.
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
import { createLintConfig } from "@jameswyse/oxc-config/oxlint";
|
|
145
|
+
|
|
146
|
+
const base = createLintConfig({ react: true, vitest: true });
|
|
147
|
+
|
|
148
|
+
export default {
|
|
149
|
+
...base,
|
|
150
|
+
ignorePatterns: [...base.ignorePatterns, "src/routeTree.gen.ts"],
|
|
151
|
+
overrides: [
|
|
152
|
+
...base.overrides,
|
|
153
|
+
{
|
|
154
|
+
files: ["src/validation/**/*.ts"],
|
|
155
|
+
rules: {
|
|
156
|
+
"wyse/no-runtime-typeof": "off",
|
|
157
|
+
"wyse/no-unsafe-dictionary-type": "off",
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Use this for validated input seams, real timer tests, external module mocks, framework-required default exports and generated files. Keep each exception to the smallest scope. Suppression comments that no longer suppress anything are errors.
|
|
165
|
+
|
|
166
|
+
## Adjust the formatter
|
|
167
|
+
|
|
168
|
+
The formatter uses 100 columns, two spaces, double quotes, semicolons and trailing commas. It sorts imports into value and type groups and sorts `package.json` scripts. To use single quotes or add a workspace import prefix:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
import { formatConfig } from "@jameswyse/oxc-config/oxfmt";
|
|
172
|
+
|
|
173
|
+
export default {
|
|
174
|
+
...formatConfig,
|
|
175
|
+
singleQuote: true,
|
|
176
|
+
sortImports: {
|
|
177
|
+
...formatConfig.sortImports,
|
|
178
|
+
internalPattern: ["@/", "#", "@my-workspace/"],
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Tailwind class sorting depends on the project's Tailwind version and stylesheet, so configure Oxfmt's `sortTailwindcss` option in the project.
|
|
184
|
+
|
|
185
|
+
## Develop
|
|
186
|
+
|
|
187
|
+
```sh
|
|
188
|
+
pnpm install --frozen-lockfile
|
|
189
|
+
pnpm check
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`pnpm check` runs the rule tests, lints real consumer configs in temporary projects, checks type-aware diagnostics and formatter convergence, then lints, typechecks, checks formatting and builds `dist`.
|
|
193
|
+
|
|
194
|
+
## Release
|
|
195
|
+
|
|
196
|
+
Add a changeset to any pull request that should ship:
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
pnpm changeset
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
On `main`, the release workflow keeps a "chore(release): version packages" pull request up to date with the pending changesets. Merging it publishes the new version to npm with provenance, tags it and creates a GitHub release.
|
|
203
|
+
|
|
204
|
+
## Vendored code
|
|
205
|
+
|
|
206
|
+
Some code is adapted from other MIT-licensed projects. Each project's licence sits beside its code in `src/vendor`.
|
|
207
|
+
|
|
208
|
+
- [anti-slop](https://github.com/dmmulroy/anti-slop): 17 rules and their shared helpers, in `src/vendor/anti-slop`.
|
|
209
|
+
- [ESLint Stylistic](https://github.com/eslint-stylistic/eslint-stylistic): the `padding-line-between-statements` engine behind `statement-spacing`, in `src/vendor/eslint-stylistic`.
|
|
210
|
+
|
|
211
|
+
## Licence
|
|
212
|
+
|
|
213
|
+
[MIT](LICENSE).
|
package/REFERENCE.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Rule reference
|
|
2
|
+
|
|
3
|
+
## Defaults
|
|
4
|
+
|
|
5
|
+
The base config enables Oxlint's correctness and suspicious categories as errors. It also enables strict equality, mandatory braces, `prefer-const`, no parameter reassignment, unused-variable checks that ignore `_`-prefixed bindings, import ordering and duplicate checks, the accumulating-spread check, named exports and no console logging. Unused suppression comments are errors. `no-underscore-dangle` is off so schema-owned fields such as `_id` and `__typename` remain valid.
|
|
6
|
+
|
|
7
|
+
Warnings do not fail the run. The warning-level rules mark patterns that are usually worth changing but have legitimate uses that no syntax separates; each was measured on real codebases before it was added.
|
|
8
|
+
|
|
9
|
+
## Standards and rules
|
|
10
|
+
|
|
11
|
+
| Standard | Implemented automation | Limit |
|
|
12
|
+
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| No `any`; keep unknown external values at a seam | `typescript/no-explicit-any`; type-aware `no-unsafe-*`; `no-unsafe-dictionary-type`, `no-known-value-widening`, `no-unknown-returns` and `no-unknown-type-aliases` | Legitimate parsers may need narrow exceptions; imported domain types require type-aware analysis |
|
|
14
|
+
| Parse external data at a seam instead of probing it | `wyse/no-runtime-typeof` warns about `typeof` outside type guards; `typeof x === "undefined"` probes are allowed | Narrowing a known primitive union with `typeof` is legitimate; the warning prompts a schema without blocking |
|
|
15
|
+
| Prefer validated narrowing and `satisfies` | Native `no-non-null-assertion`; type-aware `no-unsafe-type-assertion`, `no-unnecessary-type-assertion`; `no-chained-type-assertions` and `no-widen-then-assert` | No syntactic rule proves a runtime schema or invariant correct |
|
|
16
|
+
| Guards have truthful, recognisable names | Custom `wyse/type-guard-name` | Names do not prove predicate correctness |
|
|
17
|
+
| Handle every union case | Type-aware `typescript/switch-exhaustiveness-check` | The compiler still owns `never` assignments and valid-state modelling |
|
|
18
|
+
| Remove redundant guards and dead code | Correctness/suspicious categories; unused variables/private members; type-aware `no-unnecessary-condition` | Whether validation belongs at another seam needs review |
|
|
19
|
+
| Keep branches readable | Custom `wyse/no-deep-ternary`; native `curly` | Complexity, line count and parameter count are not used as design proxies |
|
|
20
|
+
| Handle asynchronous work and errors | Native correctness/promise checks, `no-empty`, `no-useless-catch`; typed floating/misused promises, `await-thenable`, `return-await`, `only-throw-error` | Meaningful recovery, domain results, retry policy and error context need review |
|
|
21
|
+
| Represent expected failures instead of silencing them | Custom `wyse/no-swallowed-errors` (warning) | Parser, filesystem-probe and existing-promise catches are allowed; other expected failures need a suppression with a reason |
|
|
22
|
+
| Avoid boolean control parameters | Custom `wyse/explicit-api-states` (warning) | Final boolean parameters of `set*`/`update*` functions are allowed; a boolean that is domain data still warns |
|
|
23
|
+
| Named exports and imports from an owner | `import/no-default-export`, `first`, `no-duplicates`, `no-self-import`, `no-unassigned-import`; warnings from `import/no-cycle` and `oxc/no-barrel-file` | Internal barrel ownership and public package entrypoints need architectural context; the barrel rule counts only `export *` fan-out above its default threshold |
|
|
24
|
+
| Name files after their concept | Custom `wyse/no-generic-file-suffix` | Files named after a domain export, such as `agentPolicy.ts` exporting `AgentPolicy`, and standard header policies are allowed |
|
|
25
|
+
| Import from the authoritative module | Custom `wyse/no-forwarding-module` (warning) | Package entrypoints and framework route files are allowed; other frameworks' mandated re-export files may need an exception |
|
|
26
|
+
| Remove middle men | Custom `wyse/no-pass-through-function` (warning) | Only identifier callees are checked, because method facades usually hide an instance |
|
|
27
|
+
| No shipped console logging | `eslint/no-console`; narrow config/script exceptions | Redaction, sensitive fields and sufficient structured context need review |
|
|
28
|
+
| Never add code comments | Custom `wyse/no-comments`; tool directives and JavaScript type JSDoc remain allowed | Projects can allow further directive patterns; the rule cannot tell whether the removed intent reached a name, type, test or commit |
|
|
29
|
+
| Parse configuration at startup | Custom `wyse/no-env-access` with the project's `env` owners | Owners must be named by the project; the rule does not check that the owner validates what it reads |
|
|
30
|
+
| Keep privileged modules out of other runtimes | Custom `wyse/import-boundaries` from the project's `boundaries` | Only static, dynamic-literal and re-export specifiers are checked; `require` and computed imports are not |
|
|
31
|
+
| Enforce authorisation at the protected operation | Custom `wyse/server-action-guard` with the project's `serverActionGuards` | A guard's name cannot prove it authorises the operation or checks the right resource |
|
|
32
|
+
| Control time and randomness | Custom `wyse/no-ambient-clock` and `wyse/no-ambient-random` with the project's `clock` and `random` owners | Production code only; owners must be named by the project |
|
|
33
|
+
| Harden Electron apps | Custom `wyse/electron-*` rules and a renderer import boundary in the `electron` profile | Checks literal `webPreferences`, `remote` usage and raw `ipcRenderer` exposure through `contextBridge` |
|
|
34
|
+
| Prefer local state and avoid accidental mutation | `prefer-const`, `no-param-reassign`; React immutability checks; typed `prefer-readonly` | Local accumulator mutation is allowed; ownership is not inferred from a variable name |
|
|
35
|
+
| Avoid repeated growing copies | Native `oxc/no-accumulating-spread`; `no-array-filter-map` and `no-reduce-accumulator-copy`; optional e18e profile | No performance improvement is claimed without measurement |
|
|
36
|
+
| Avoid duplicate React state and effect chains | React and React Compiler native rules; `react-you-might-not-need-an-effect` rules | Product interactions still need runtime verification |
|
|
37
|
+
| Basic accessible JSX | Native `jsx-a11y` correctness/suspicious rules in the React profile | Keyboard behaviour, accessible names through custom components and visual contrast require application evidence |
|
|
38
|
+
| Tests execute assertions and are not silently skipped | Native Jest/Vitest focused/disabled/conditional/standalone/valid expectation checks | Valid helper-based assertions are allowed; assertion-count rules are not enabled blindly |
|
|
39
|
+
| Tests wait for observable outcomes | Custom `wyse/no-fixed-test-delay` | Genuine timer tests need a scoped exception; unknown wait helpers are not guessed |
|
|
40
|
+
| Tests have a non-vacuous oracle | Custom `wyse/no-vacuous-test-assertions` | Independent expected results and meaningful behavioural coverage still need review |
|
|
41
|
+
| Tests protect behaviour, not edits | Custom `wyse/no-edit-proof-assertions` | Only existence checks of imports and `typeof … "function"` checks are recognised |
|
|
42
|
+
| Tests do not hide slow or flaky work | Custom `wyse/no-test-timeout-overrides` (warning, unit tests only) | End-to-end suites legitimately need longer timeouts and are excluded |
|
|
43
|
+
| Tests sit beside the module they cover | Custom `wyse/companion-has-owner` (warning) | Cross-module tests should be named `<behaviour>.integration.test` or live under `tests/` |
|
|
44
|
+
| Avoid module mocking of runnable dependencies | `wyse/no-module-mocking` | External systems can justify a file-scoped exception |
|
|
45
|
+
| Consistent layout and imports | Oxfmt; custom `wyse/statement-spacing` | Blank lines are only required around imports, multiline blocks, multiline declarations and returns, so deliberate groups of one-line statements stay together |
|
|
46
|
+
|
|
47
|
+
`no-unnecessary-condition` is a nursery rule in Oxlint 1.86.0. It is enabled only with `typeAware`. The usual native nested-ternary rule conflicts with Oxfmt 0.71.0 because one tool adds parentheses and the other removes them. The custom depth rule allows one nested level and reports the third ternary level, without prescribing parentheses.
|
|
48
|
+
|
|
49
|
+
## Custom rules
|
|
50
|
+
|
|
51
|
+
All rules use Oxlint's supported AST and lexical scopes and their tests sit beside their source, in `src/rules` or, for rules adapted from anti-slop, `src/vendor/anti-slop`. Only `statement-spacing` has an autofix, which inserts blank lines; its engine is adapted from ESLint Stylistic's `padding-line-between-statements`. `companion-has-owner` and `no-forwarding-module` read sibling files and the nearest `package.json`. The others are dependency-free.
|
|
52
|
+
|
|
53
|
+
| Rule | Rejected pattern | Allowed or outside scope |
|
|
54
|
+
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
55
|
+
| `type-guard-name` | A named predicate such as `checkUser(value): value is User` | `isUser`, `hasId`, assertion functions, anonymous callbacks and computed method names |
|
|
56
|
+
| `no-deep-ternary` | A conditional expression nested inside two conditional expressions | One nested level; a separate function's expressions start a new depth |
|
|
57
|
+
| `no-fixed-test-delay` | Awaited literal timer delays and known Playwright fixture `waitForTimeout` calls in recognised tests | Local functions that shadow timer/test names, nonliteral delays, and unknown custom helpers |
|
|
58
|
+
| `no-vacuous-test-assertions` | Literal-to-literal equality expectations or the same identifier on both sides of `toBe`, `toEqual`, `toStrictEqual` | Computed values, property getters, reversed meaningful expectations and promise resolution matchers |
|
|
59
|
+
| `no-comments` | Line, block and JSDoc comments, including JSDoc in TypeScript files | Shebangs, JSDoc with type tags in JavaScript files, and tool directives: lint suppressions, `@ts-expect-error`, triple-slash references, `#__PURE__`, formatter and coverage ignores, bundler magic comments, test-environment and JSX pragmas; extra patterns through the `allow` option |
|
|
60
|
+
| `no-env-access` | `process.env`, `import.meta.env` and destructuring `env` from either, outside `env` owners, config files and scripts | Local bindings named `process` and unrelated `env` properties |
|
|
61
|
+
| `import-boundaries` | A value import, re-export or literal dynamic import from a configured scope whose specifier or resolved relative path matches a `deny` glob | Type-only imports and files outside the boundary's scope |
|
|
62
|
+
| `server-action-guard` | An exported action in a `"use server"` module, or an inline `"use server"` function, whose first statement does not await a configured guard; indirect or default exports from server-action modules | Non-exported helpers in server-action modules and test files |
|
|
63
|
+
| `statement-spacing` | A missing blank line after the imports, around a multiline block or a multiline declaration, including exported ones, or before `return` | Consecutive imports, consecutive one-line statements, and a type alias directly after the multiline declaration it derives from |
|
|
64
|
+
| `no-edit-proof-assertions` | `toBeDefined`, `toBeTruthy` and similar on an imported binding or namespace member; `typeof X` or `toBeTypeOf` against a string on imports; `toBeTypeOf("function")` on anything; `toHaveProperty` on a namespace | Assertions on values produced by running code |
|
|
65
|
+
| `no-test-timeout-overrides` | Per-test or per-suite timeout and retry options, `test.setTimeout`, `test.slow()`, `describe.configure`, `vi.setConfig` and `jest.setTimeout` in unit tests | End-to-end files under `e2e/` or named `*.e2e.*` |
|
|
66
|
+
| `companion-has-owner` | A `.test`, `.spec` or `.bench` file whose name prefix matches no sibling module or directory, nor its own directory | Files with an `integration` or `e2e` segment and files under `tests/`, `test/`, `__tests__/` or `e2e/` |
|
|
67
|
+
| `no-generic-file-suffix` | A file named `*Contract`, `*Policy`, `policy` or `contract` in camel, kebab, snake or dot form | Test and story files, standard header policies such as content security policy, and files exporting a binding with the file's name |
|
|
68
|
+
| `no-forwarding-module` | A module made only of re-exports, or imports re-exported unchanged | Package entrypoints in the nearest `package.json`, Next.js `app` special files and `pages`, root `middleware`/`proxy`/`instrumentation`, modules with directives or side-effect imports |
|
|
69
|
+
| `no-pass-through-function` | A named function whose body only calls an identifier with exactly its own parameters, in order | Zero-parameter functions, method callees, type predicates and `useEffectEvent` callees |
|
|
70
|
+
| `explicit-api-states` | A `boolean`, optional `boolean`, or boolean-defaulted parameter on an exported function, exported class constructor or public method | Destructured parameters, accessors, private members, overloads and the final boolean of a `set*`/`update*` function |
|
|
71
|
+
| `no-swallowed-errors` | A `catch` whose body only returns a fallback literal, and a `.catch` callback that is empty or returns one | Built-in parser and filesystem-probe try blocks, `response.json()`, and `.catch` on a promise another caller also receives |
|
|
72
|
+
| `no-ambient-clock` | `Date.now()` and argument-less `new Date()`, including through `globalThis`/`window` | Parameter defaults, uncalled `Date.now` and provider functions that only return the read |
|
|
73
|
+
| `no-ambient-random` | `Math.random()`, `crypto.randomUUID()`, and `randomUUID`/`randomInt` from `node:crypto` | The same injection seams; `randomBytes` and `getRandomValues`, which generate secrets |
|
|
74
|
+
| `electron-no-remote-module` | `remote` from `electron`, and `@electron/remote` by import, `require`, dynamic import or re-export | Other Electron APIs |
|
|
75
|
+
| `electron-secure-web-preferences` | `webPreferences` without literal `contextIsolation: true`, `sandbox: true` and `nodeIntegration: false`, or with insecure web security, insecure content, experimental or Blink features; overrides through later keys, spreads or computed keys | Preferences passed from a variable the rule cannot resolve |
|
|
76
|
+
| `electron-no-raw-ipc-renderer-exposure` | Exposing `ipcRenderer` or its methods through `contextBridge`, forwarding renderer-chosen channels or arguments, or passing renderer callbacks straight to `on`/`once` | Narrow, named preload functions with fixed channels |
|
|
77
|
+
|
|
78
|
+
Test-specific custom rules run on the default test globs, `tests` paths and any explicit Jest or Vitest profile scopes. Their import and binding recognition is deliberately narrower than unrestricted text matching. The tests are the executable reference for supported aliases, shadowing and callback forms.
|
|
79
|
+
|
|
80
|
+
## Type, data and test-double rules
|
|
81
|
+
|
|
82
|
+
The base config also enables these rules as errors:
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
no-array-filter-map
|
|
86
|
+
no-reduce-accumulator-copy
|
|
87
|
+
no-chained-type-assertions
|
|
88
|
+
no-conditional-empty-object-spread
|
|
89
|
+
no-known-value-widening
|
|
90
|
+
no-module-mocking
|
|
91
|
+
no-object-parameters
|
|
92
|
+
no-reflect-apply
|
|
93
|
+
no-reflect-get
|
|
94
|
+
no-shape-in-symbol-names
|
|
95
|
+
no-unknown-returns
|
|
96
|
+
no-unknown-type-aliases
|
|
97
|
+
no-unsafe-dictionary-type
|
|
98
|
+
no-widen-then-assert
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`no-runtime-typeof` is a warning with `allowInTypeGuards` enabled. Banning `typeof` outright blocks legitimate narrowing of known unions, while the warning still points towards parsing external data with a schema. Projects can turn it off at a validated input seam.
|
|
102
|
+
|
|
103
|
+
The optional `effect` profile enables `no-manual-effect-error-tag` and `no-service-constructor-imports`.
|
|
104
|
+
|
|
105
|
+
These rules do not have cross-file type knowledge. Their [source files](src/vendor/anti-slop/rules) and tests define the supported same-file alias, scope and inference cases. There is no blanket ban on legitimate `unknown` values or invariant-preserving `as const` expressions.
|
|
106
|
+
|
|
107
|
+
## Project-specific automation
|
|
108
|
+
|
|
109
|
+
These policies are enforced once a project names the actual owners. They are intentionally not universal defaults:
|
|
110
|
+
|
|
111
|
+
| Policy | Mechanism | Required project information |
|
|
112
|
+
| --------------------------------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
|
113
|
+
| Parse configuration at startup | `env` option | Modules that own configuration parsing |
|
|
114
|
+
| Keep privileged modules out of other runtimes | `boundaries` option | Each runtime's file scope, and the packages, aliases and paths it must not import |
|
|
115
|
+
| Require access checks before server actions | `serverActionGuards` option | The guard functions that perform authorisation |
|
|
116
|
+
| Control time and randomness | `clock` and `random` options | Modules that own the clock and ID or random generation |
|
|
117
|
+
| Harden Electron apps | `electron` option | Renderer globs when they are not `src/renderer/**` |
|
|
118
|
+
| Generated assets and style imports | Shared ignores plus local patterns; Oxfmt Tailwind configuration | Actual generators, CSS preprocessors, Tailwind config or stylesheet |
|
|
119
|
+
|
|
120
|
+
## Compiler settings and review work
|
|
121
|
+
|
|
122
|
+
For new TypeScript projects, use `strict`, `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`, `noImplicitOverride` and `noFallthroughCasesInSwitch`. The package exports them as `@jameswyse/oxc-config/tsconfig` for a project's `tsconfig.json` to extend. Lint configuration never applies them, because changing them in an existing project is a deliberate migration.
|
|
123
|
+
|
|
124
|
+
Lint cannot establish correct authorisation, tenant isolation, schema validation, secret redaction, transaction boundaries, idempotency, crash recovery, concurrency ownership, dependency justification, useful module depth, constructive domain modelling or independent test oracles. These remain review and verification work. File naming, positional parameters, boolean inputs, `Partial<T>`, wrappers and abstraction counts have legitimate domain/framework exceptions and are not rejected through universal heuristics.
|
|
125
|
+
|
|
126
|
+
## Oxc API references
|
|
127
|
+
|
|
128
|
+
The implementation follows the current [Oxlint configuration API](https://oxc.rs/docs/guide/usage/linter/config.html), [JS plugin API](https://oxc.rs/docs/guide/usage/linter/writing-js-plugins.html), [type-aware setup](https://oxc.rs/docs/guide/usage/linter/type-aware.html), and [Oxfmt options](https://oxc.rs/docs/guide/usage/formatter/config-file-reference.html). Absolute plugin specifiers keep imported configs independent of the consumer's working directory. Side-effect import sorting is explicitly disabled.
|
|
129
|
+
|
|
130
|
+
## Rules considered and dropped
|
|
131
|
+
|
|
132
|
+
`no-call-count-assertions` would have rejected `toHaveBeenCalledTimes`, `toHaveBeenNthCalledWith` and `mock.calls` counting. On three codebases, 36 of 40 sampled findings were legitimate: the count was the behaviour under test, such as caching, retry, deduplication or firing once. No syntax separated them from incidental counts, so it was dropped.
|
|
133
|
+
|
|
134
|
+
Rules for safety comments on type assertions, a blank line between every top-level statement, and rejecting `unknown` parameters are not included. The first conflicts with `no-comments`, the second split deliberate groups of related declarations, and the third rejected legitimate unparsed input seams. Effect rules that reject `_tag` comparisons, prefer `Match` or reject literal tagged construction are not included either, because discriminant checks are the preferred way to narrow a union and TypeScript already checks literal variants.
|
package/dist/format.d.ts
ADDED
package/dist/format.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { defaultIgnores } from "./lint.js";
|
|
2
|
+
export const formatConfig = {
|
|
3
|
+
printWidth: 100,
|
|
4
|
+
tabWidth: 2,
|
|
5
|
+
useTabs: false,
|
|
6
|
+
semi: true,
|
|
7
|
+
singleQuote: false,
|
|
8
|
+
jsxSingleQuote: false,
|
|
9
|
+
trailingComma: "all",
|
|
10
|
+
bracketSpacing: true,
|
|
11
|
+
arrowParens: "always",
|
|
12
|
+
endOfLine: "lf",
|
|
13
|
+
ignorePatterns: defaultIgnores,
|
|
14
|
+
sortImports: {
|
|
15
|
+
internalPattern: ["@/", "~/", "#"],
|
|
16
|
+
sortSideEffects: false,
|
|
17
|
+
groups: [
|
|
18
|
+
"value-builtin",
|
|
19
|
+
"next-libs",
|
|
20
|
+
"react-libs",
|
|
21
|
+
"value-external",
|
|
22
|
+
"value-internal",
|
|
23
|
+
["value-parent", "value-sibling", "value-index"],
|
|
24
|
+
"type-builtin",
|
|
25
|
+
"type-external",
|
|
26
|
+
"type-internal",
|
|
27
|
+
["type-parent", "type-sibling", "type-index"],
|
|
28
|
+
"unknown",
|
|
29
|
+
"style",
|
|
30
|
+
],
|
|
31
|
+
customGroups: [
|
|
32
|
+
{
|
|
33
|
+
groupName: "next-libs",
|
|
34
|
+
elementNamePattern: ["next", "next/*"],
|
|
35
|
+
modifiers: ["value"],
|
|
36
|
+
selector: "external",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
groupName: "react-libs",
|
|
40
|
+
elementNamePattern: ["react", "react-dom", "react-dom/*"],
|
|
41
|
+
modifiers: ["value"],
|
|
42
|
+
selector: "external",
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
sortPackageJson: { sortScripts: true },
|
|
47
|
+
};
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { definePlugin } from "@oxlint/plugins";
|
|
3
|
+
import { companionHasOwner } from "./rules/companion-has-owner.js";
|
|
4
|
+
import { electronNoRawIpcRendererExposure } from "./rules/electron-no-raw-ipc-renderer-exposure.js";
|
|
5
|
+
import { electronNoRemoteModule } from "./rules/electron-no-remote-module.js";
|
|
6
|
+
import { electronSecureWebPreferences } from "./rules/electron-secure-web-preferences.js";
|
|
7
|
+
import { explicitApiStates } from "./rules/explicit-api-states.js";
|
|
8
|
+
import { importBoundaries } from "./rules/import-boundaries.js";
|
|
9
|
+
import { noAmbientClock } from "./rules/no-ambient-clock.js";
|
|
10
|
+
import { noAmbientRandom } from "./rules/no-ambient-random.js";
|
|
11
|
+
import { noComments } from "./rules/no-comments.js";
|
|
12
|
+
import { noDeepTernary } from "./rules/no-deep-ternary.js";
|
|
13
|
+
import { noEditProofAssertions } from "./rules/no-edit-proof-assertions.js";
|
|
14
|
+
import { noEnvAccess } from "./rules/no-env-access.js";
|
|
15
|
+
import { noFixedTestDelay } from "./rules/no-fixed-test-delay.js";
|
|
16
|
+
import { noForwardingModule } from "./rules/no-forwarding-module.js";
|
|
17
|
+
import { noGenericFileSuffix } from "./rules/no-generic-file-suffix.js";
|
|
18
|
+
import { noPassThroughFunction } from "./rules/no-pass-through-function.js";
|
|
19
|
+
import { noSwallowedErrors } from "./rules/no-swallowed-errors.js";
|
|
20
|
+
import { noTestTimeoutOverrides } from "./rules/no-test-timeout-overrides.js";
|
|
21
|
+
import { noVacuousTestAssertions } from "./rules/no-vacuous-test-assertions.js";
|
|
22
|
+
import { serverActionGuard } from "./rules/server-action-guard.js";
|
|
23
|
+
import { statementSpacing } from "./rules/statement-spacing.js";
|
|
24
|
+
import { typeGuardName } from "./rules/type-guard-name.js";
|
|
25
|
+
import { noManualEffectErrorTag } from "./vendor/anti-slop/effect/rules/no-manual-effect-error-tag.js";
|
|
26
|
+
import { noServiceConstructorImports } from "./vendor/anti-slop/effect/rules/no-service-constructor-imports.js";
|
|
27
|
+
import { noArrayFilterMap } from "./vendor/anti-slop/rules/no-array-filter-map.js";
|
|
28
|
+
import { noChainedTypeAssertions } from "./vendor/anti-slop/rules/no-chained-type-assertions.js";
|
|
29
|
+
import { noConditionalEmptyObjectSpread } from "./vendor/anti-slop/rules/no-conditional-empty-object-spread.js";
|
|
30
|
+
import { noKnownValueWidening } from "./vendor/anti-slop/rules/no-known-value-widening.js";
|
|
31
|
+
import { noModuleMocking } from "./vendor/anti-slop/rules/no-module-mocking.js";
|
|
32
|
+
import { noObjectParameters } from "./vendor/anti-slop/rules/no-object-parameters.js";
|
|
33
|
+
import { noReduceAccumulatorCopy } from "./vendor/anti-slop/rules/no-reduce-accumulator-copy.js";
|
|
34
|
+
import { noReflectApply } from "./vendor/anti-slop/rules/no-reflect-apply.js";
|
|
35
|
+
import { noReflectGet } from "./vendor/anti-slop/rules/no-reflect-get.js";
|
|
36
|
+
import { noRuntimeTypeof } from "./vendor/anti-slop/rules/no-runtime-typeof.js";
|
|
37
|
+
import { noForbiddenTermInSymbolNames } from "./vendor/anti-slop/rules/no-shape-in-symbol-names.js";
|
|
38
|
+
import { noUnknownReturns } from "./vendor/anti-slop/rules/no-unknown-returns.js";
|
|
39
|
+
import { noUnknownTypeAliases } from "./vendor/anti-slop/rules/no-unknown-type-aliases.js";
|
|
40
|
+
import { noUnsafeDictionaryType } from "./vendor/anti-slop/rules/no-unsafe-dictionary-type.js";
|
|
41
|
+
import { noWidenThenAssert } from "./vendor/anti-slop/rules/no-widen-then-assert.js";
|
|
42
|
+
function packageVersion() {
|
|
43
|
+
const manifest = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
44
|
+
if (typeof manifest === "object" &&
|
|
45
|
+
manifest !== null &&
|
|
46
|
+
"version" in manifest &&
|
|
47
|
+
typeof manifest.version === "string") {
|
|
48
|
+
return manifest.version;
|
|
49
|
+
}
|
|
50
|
+
throw new TypeError("The package manifest has no version.");
|
|
51
|
+
}
|
|
52
|
+
const meta = { name: "wyse", version: packageVersion() };
|
|
53
|
+
const wyse = definePlugin({
|
|
54
|
+
meta,
|
|
55
|
+
rules: {
|
|
56
|
+
"companion-has-owner": companionHasOwner,
|
|
57
|
+
"electron-no-raw-ipc-renderer-exposure": electronNoRawIpcRendererExposure,
|
|
58
|
+
"electron-no-remote-module": electronNoRemoteModule,
|
|
59
|
+
"electron-secure-web-preferences": electronSecureWebPreferences,
|
|
60
|
+
"explicit-api-states": explicitApiStates,
|
|
61
|
+
"import-boundaries": importBoundaries,
|
|
62
|
+
"no-ambient-clock": noAmbientClock,
|
|
63
|
+
"no-ambient-random": noAmbientRandom,
|
|
64
|
+
"no-array-filter-map": noArrayFilterMap,
|
|
65
|
+
"no-chained-type-assertions": noChainedTypeAssertions,
|
|
66
|
+
"no-comments": noComments,
|
|
67
|
+
"no-conditional-empty-object-spread": noConditionalEmptyObjectSpread,
|
|
68
|
+
"no-deep-ternary": noDeepTernary,
|
|
69
|
+
"no-edit-proof-assertions": noEditProofAssertions,
|
|
70
|
+
"no-env-access": noEnvAccess,
|
|
71
|
+
"no-fixed-test-delay": noFixedTestDelay,
|
|
72
|
+
"no-forwarding-module": noForwardingModule,
|
|
73
|
+
"no-generic-file-suffix": noGenericFileSuffix,
|
|
74
|
+
"no-known-value-widening": noKnownValueWidening,
|
|
75
|
+
"no-manual-effect-error-tag": noManualEffectErrorTag,
|
|
76
|
+
"no-module-mocking": noModuleMocking,
|
|
77
|
+
"no-object-parameters": noObjectParameters,
|
|
78
|
+
"no-pass-through-function": noPassThroughFunction,
|
|
79
|
+
"no-reduce-accumulator-copy": noReduceAccumulatorCopy,
|
|
80
|
+
"no-reflect-apply": noReflectApply,
|
|
81
|
+
"no-reflect-get": noReflectGet,
|
|
82
|
+
"no-runtime-typeof": noRuntimeTypeof,
|
|
83
|
+
"no-service-constructor-imports": noServiceConstructorImports,
|
|
84
|
+
"no-shape-in-symbol-names": noForbiddenTermInSymbolNames,
|
|
85
|
+
"no-swallowed-errors": noSwallowedErrors,
|
|
86
|
+
"no-test-timeout-overrides": noTestTimeoutOverrides,
|
|
87
|
+
"no-unknown-returns": noUnknownReturns,
|
|
88
|
+
"no-unknown-type-aliases": noUnknownTypeAliases,
|
|
89
|
+
"no-unsafe-dictionary-type": noUnsafeDictionaryType,
|
|
90
|
+
"no-vacuous-test-assertions": noVacuousTestAssertions,
|
|
91
|
+
"no-widen-then-assert": noWidenThenAssert,
|
|
92
|
+
"server-action-guard": serverActionGuard,
|
|
93
|
+
"statement-spacing": statementSpacing,
|
|
94
|
+
"type-guard-name": typeGuardName,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
export default wyse;
|
package/dist/lint.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { DummyRuleMap, OxlintConfig, OxlintOverride } from "oxlint";
|
|
2
|
+
export type FileScope = boolean | string[];
|
|
3
|
+
export interface LintOptions {
|
|
4
|
+
typeAware?: boolean;
|
|
5
|
+
node?: FileScope;
|
|
6
|
+
react?: FileScope;
|
|
7
|
+
nextjs?: FileScope;
|
|
8
|
+
vitest?: FileScope;
|
|
9
|
+
jest?: FileScope;
|
|
10
|
+
effect?: FileScope;
|
|
11
|
+
tests?: string[];
|
|
12
|
+
env?: [string, ...string[]];
|
|
13
|
+
boundaries?: ImportBoundary[];
|
|
14
|
+
serverActionGuards?: [string, ...string[]];
|
|
15
|
+
clock?: [string, ...string[]];
|
|
16
|
+
random?: [string, ...string[]];
|
|
17
|
+
electron?: boolean | {
|
|
18
|
+
renderer?: string[];
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface ImportBoundary {
|
|
22
|
+
files: string[];
|
|
23
|
+
ignore?: string[];
|
|
24
|
+
deny: string[];
|
|
25
|
+
message: string;
|
|
26
|
+
}
|
|
27
|
+
export type SharedLintConfig = OxlintConfig & {
|
|
28
|
+
ignorePatterns: string[];
|
|
29
|
+
overrides: OxlintOverride[];
|
|
30
|
+
rules: DummyRuleMap;
|
|
31
|
+
};
|
|
32
|
+
export declare const defaultIgnores: string[];
|
|
33
|
+
export declare function createLintConfig({ typeAware, node, react, nextjs, vitest, jest, effect, tests, env, boundaries, serverActionGuards, clock, random, electron, }?: LintOptions): SharedLintConfig;
|