@doubleloop-io/oxlint-plugin-effect 0.0.0-stage → 0.1.0-rc.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/LICENSE.anti-slop +21 -0
- package/README.md +210 -2
- package/RULES.md +911 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +71 -0
- package/dist/presets/all.d.ts +7 -0
- package/dist/presets/all.js +9 -0
- package/dist/presets/all.json +37 -0
- package/dist/rules/adapter-import-boundary.d.ts +7 -0
- package/dist/rules/adapter-import-boundary.js +103 -0
- package/dist/rules/anti-slop-no-manual-effect-error-tag.d.ts +1 -0
- package/dist/rules/anti-slop-no-manual-effect-error-tag.js +32 -0
- package/dist/rules/anti-slop-no-service-constructor-imports.d.ts +1 -0
- package/dist/rules/anti-slop-no-service-constructor-imports.js +49 -0
- package/dist/rules/anti-slop-prefer-effect-match.d.ts +1 -0
- package/dist/rules/anti-slop-prefer-effect-match.js +45 -0
- package/dist/rules/boundary-entrypoint-shape.d.ts +1 -0
- package/dist/rules/boundary-entrypoint-shape.js +52 -0
- package/dist/rules/error-handling-in-effect-fn-handler.d.ts +1 -0
- package/dist/rules/error-handling-in-effect-fn-handler.js +66 -0
- package/dist/rules/exported-schema-identifier.d.ts +1 -0
- package/dist/rules/exported-schema-identifier.js +117 -0
- package/dist/rules/no-asymmetric-match-handlers.d.ts +1 -0
- package/dist/rules/no-asymmetric-match-handlers.js +74 -0
- package/dist/rules/no-bare-error-in-effect.d.ts +1 -0
- package/dist/rules/no-bare-error-in-effect.js +34 -0
- package/dist/rules/no-effect-promise.d.ts +1 -0
- package/dist/rules/no-effect-promise.js +57 -0
- package/dist/rules/no-effect-return-type.d.ts +1 -0
- package/dist/rules/no-effect-return-type.js +130 -0
- package/dist/rules/no-inline-schema-codec.d.ts +1 -0
- package/dist/rules/no-inline-schema-codec.js +46 -0
- package/dist/rules/no-inline-yield-star.d.ts +1 -0
- package/dist/rules/no-inline-yield-star.js +230 -0
- package/dist/rules/no-manual-discriminant-comparison.d.ts +2 -0
- package/dist/rules/no-manual-discriminant-comparison.js +58 -0
- package/dist/rules/no-manual-discriminant-construction.d.ts +2 -0
- package/dist/rules/no-manual-discriminant-construction.js +90 -0
- package/dist/rules/no-nested-match.d.ts +1 -0
- package/dist/rules/no-nested-match.js +24 -0
- package/dist/rules/no-parameterless-catch-all.d.ts +1 -0
- package/dist/rules/no-parameterless-catch-all.js +29 -0
- package/dist/rules/no-provide-on-definition.d.ts +1 -0
- package/dist/rules/no-provide-on-definition.js +94 -0
- package/dist/rules/no-transport-types-in-generator.d.ts +1 -0
- package/dist/rules/no-transport-types-in-generator.js +63 -0
- package/dist/rules/no-yielded-match.d.ts +1 -0
- package/dist/rules/no-yielded-match.js +91 -0
- package/dist/rules/prefer-effect-fn.d.ts +1 -0
- package/dist/rules/prefer-effect-fn.js +102 -0
- package/dist/rules/provide-named-layer.d.ts +1 -0
- package/dist/rules/provide-named-layer.js +55 -0
- package/dist/rules/redacted-secret-names.d.ts +1 -0
- package/dist/rules/redacted-secret-names.js +127 -0
- package/dist/rules/run-only-at-entry.d.ts +1 -0
- package/dist/rules/run-only-at-entry.js +50 -0
- package/dist/rules/service-built-with-of.d.ts +1 -0
- package/dist/rules/service-built-with-of.js +74 -0
- package/dist/rules/service-key-matches-name.d.ts +1 -0
- package/dist/rules/service-key-matches-name.js +69 -0
- package/dist/rules/service-port-shape-only.d.ts +1 -0
- package/dist/rules/service-port-shape-only.js +65 -0
- package/dist/rules/single-style-per-function.d.ts +1 -0
- package/dist/rules/single-style-per-function.js +77 -0
- package/dist/rules/try-object-form.d.ts +1 -0
- package/dist/rules/try-object-form.js +26 -0
- package/dist/rules/untraced-recursion.d.ts +1 -0
- package/dist/rules/untraced-recursion.js +48 -0
- package/dist/shared/effect-ast.d.ts +9 -0
- package/dist/shared/effect-ast.js +52 -0
- package/dist/shared/entry-files.d.ts +6 -0
- package/dist/shared/entry-files.js +5 -0
- package/dist/shared/file-globs.d.ts +14 -0
- package/dist/shared/file-globs.js +17 -0
- package/dist/shared/match-ast.d.ts +5 -0
- package/dist/shared/match-ast.js +52 -0
- package/dist/shared/tagged-values.d.ts +17 -0
- package/dist/shared/tagged-values.js +67 -0
- package/dist/shared/test-files.d.ts +6 -0
- package/dist/shared/test-files.js +10 -0
- package/package.json +56 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 doubleloop.io
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,3 +1,211 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @doubleloop-io/oxlint-plugin-effect
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An oxlint plugin that enforces a catalog of patterns for Effect 4 code.
|
|
4
|
+
|
|
5
|
+
The rules are written and tested against Effect 4. On an Effect 3 codebase most of them do not recognize the APIs and stay silent: silence there is not compliance.
|
|
6
|
+
|
|
7
|
+
## Install `@effect/tsgo` first
|
|
8
|
+
|
|
9
|
+
[`@effect/tsgo`](https://github.com/Effect-TS/tsgo) is the official Effect language service on top of the TypeScript Go compiler; its `effecttsgo` oxlint presets ship more than 100 type-aware rules. This plugin is meant to be used alongside them: its rules target what those presets do not check. Set it up with its [Oxlint Setup guide](https://github.com/Effect-TS/tsgo/blob/main/docs/README.md) and put its `extends` **before** this plugin's preset, which does not include it.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add -D @doubleloop-io/oxlint-plugin-effect oxlint
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Requires Node `^22.20.0 || >=24.8.0` and oxlint `^1.82.0`.
|
|
18
|
+
|
|
19
|
+
## Configuration
|
|
20
|
+
|
|
21
|
+
Extend the `all` preset.
|
|
22
|
+
|
|
23
|
+
With `.oxlintrc.json`, where `extends` takes file paths:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"extends": ["./node_modules/@doubleloop-io/oxlint-plugin-effect/dist/presets/all.json"]
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
With `oxlint.config.ts`, where `extends` takes config objects:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import dlEffectAll from "@doubleloop-io/oxlint-plugin-effect/presets/all"
|
|
35
|
+
import { defineConfig } from "oxlint"
|
|
36
|
+
|
|
37
|
+
export default defineConfig({ extends: [dlEffectAll] })
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`all` enables every rule at `warn`, so adopting it never breaks a build: look at the warnings first, then raise to `error` the rules you want to enforce. A `recommended` preset with reasoned severities will come from measurements on real codebases.
|
|
41
|
+
|
|
42
|
+
### Configuration options
|
|
43
|
+
|
|
44
|
+
Two options tell the rules where your files are. Their defaults fit a Node CLI; on another layout (Next.js, a monorepo) set them before reading the warnings.
|
|
45
|
+
|
|
46
|
+
- `entryFiles`: the files allowed to run Effects and import adapters. Default `**/main.ts`, `**/cli.ts`, `**/bin/**`. Used by `run-only-at-entry` and `adapter-import-boundary`.
|
|
47
|
+
- `testFiles`: the files exempt from the rules that tests legitimately break. Default `**/*.test.*`, `**/*.spec.*`, `**/__tests__/**`, `**/test/**`, `**/tests/**`. Used by `adapter-import-boundary`, `no-effect-promise`, `provide-named-layer`, `no-provide-on-definition`, `error-handling-in-effect-fn-handler` and `anti-slop-no-service-constructor-imports`.
|
|
48
|
+
|
|
49
|
+
An option **replaces** its default instead of extending it, and every rule that uses it must get the same value. With `oxlint.config.ts`, declare each option once and override the rules that use it after `extends`:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import dlEffectAll from "@doubleloop-io/oxlint-plugin-effect/presets/all"
|
|
53
|
+
import { defineConfig } from "oxlint"
|
|
54
|
+
|
|
55
|
+
const entryFiles = ["apps/web/src/app/**/route.ts", "apps/web/src/runtime.ts"]
|
|
56
|
+
const testFiles = ["**/*.test.ts", "e2e/**"]
|
|
57
|
+
|
|
58
|
+
export default defineConfig({
|
|
59
|
+
extends: [dlEffectAll],
|
|
60
|
+
rules: {
|
|
61
|
+
"dl-effect/run-only-at-entry": ["warn", { entryFiles }],
|
|
62
|
+
"dl-effect/adapter-import-boundary": ["warn", { entryFiles, testFiles }],
|
|
63
|
+
"dl-effect/no-effect-promise": ["warn", { testFiles }],
|
|
64
|
+
"dl-effect/provide-named-layer": ["warn", { testFiles }],
|
|
65
|
+
"dl-effect/no-provide-on-definition": ["warn", { testFiles }],
|
|
66
|
+
"dl-effect/error-handling-in-effect-fn-handler": ["warn", { testFiles }],
|
|
67
|
+
"dl-effect/anti-slop-no-service-constructor-imports": ["warn", { testFiles }],
|
|
68
|
+
},
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
With `.oxlintrc.json` the same overrides go under `rules`, repeating each list in every rule.
|
|
73
|
+
|
|
74
|
+
The other options and every default are in [Default configuration](#default-configuration).
|
|
75
|
+
|
|
76
|
+
### Alongside `@effect/tsgo` (optional)
|
|
77
|
+
|
|
78
|
+
[`@effect/tsgo`](https://github.com/Effect-TS/tsgo) is the official Effect language service on top of the TypeScript Go compiler; its `effecttsgo` oxlint presets add more than 100 type-aware rules. This plugin does not need it, and its rules target what those presets do not check, so the two complement each other. To use both, follow its [Oxlint Setup guide](https://github.com/Effect-TS/tsgo/blob/main/docs/README.md) and put its preset in `extends` **before** `all`:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"extends": [
|
|
83
|
+
"./node_modules/@effect/tsgo/oxlint-presets/recommended.json",
|
|
84
|
+
"./node_modules/@doubleloop-io/oxlint-plugin-effect/dist/presets/all.json"
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import dlEffectAll from "@doubleloop-io/oxlint-plugin-effect/presets/all"
|
|
91
|
+
import { recommended as effectTsgoRecommended } from "@effect/tsgo/oxlint-presets"
|
|
92
|
+
import { defineConfig } from "oxlint"
|
|
93
|
+
|
|
94
|
+
export default defineConfig({ extends: [effectTsgoRecommended, dlEffectAll] })
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Rules
|
|
98
|
+
|
|
99
|
+
What each rule reports and why is in [`RULES.md`](RULES.md).
|
|
100
|
+
|
|
101
|
+
| Topic | Rules |
|
|
102
|
+
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
103
|
+
| Error channel | [`no-bare-error-in-effect`](RULES.md#no-bare-error-in-effect), [`try-object-form`](RULES.md#try-object-form), [`no-effect-promise`](RULES.md#no-effect-promise), [`no-parameterless-catch-all`](RULES.md#no-parameterless-catch-all), [`error-handling-in-effect-fn-handler`](RULES.md#error-handling-in-effect-fn-handler), [`anti-slop-no-manual-effect-error-tag`](RULES.md#anti-slop-no-manual-effect-error-tag) |
|
|
104
|
+
| Tagged values | [`no-manual-discriminant-comparison`](RULES.md#no-manual-discriminant-comparison), [`no-manual-discriminant-construction`](RULES.md#no-manual-discriminant-construction) |
|
|
105
|
+
| Services & Layers | [`service-port-shape-only`](RULES.md#service-port-shape-only), [`service-key-matches-name`](RULES.md#service-key-matches-name), [`service-built-with-of`](RULES.md#service-built-with-of), [`provide-named-layer`](RULES.md#provide-named-layer), [`no-provide-on-definition`](RULES.md#no-provide-on-definition), [`anti-slop-no-service-constructor-imports`](RULES.md#anti-slop-no-service-constructor-imports) |
|
|
106
|
+
| Runtime & entrypoint | [`run-only-at-entry`](RULES.md#run-only-at-entry), [`boundary-entrypoint-shape`](RULES.md#boundary-entrypoint-shape) |
|
|
107
|
+
| Design & boundaries | [`adapter-import-boundary`](RULES.md#adapter-import-boundary), [`no-transport-types-in-generator`](RULES.md#no-transport-types-in-generator) |
|
|
108
|
+
| Effectful functions | [`prefer-effect-fn`](RULES.md#prefer-effect-fn), [`untraced-recursion`](RULES.md#untraced-recursion), [`single-style-per-function`](RULES.md#single-style-per-function) |
|
|
109
|
+
| Code shape | [`no-nested-match`](RULES.md#no-nested-match), [`no-yielded-match`](RULES.md#no-yielded-match), [`no-inline-yield-star`](RULES.md#no-inline-yield-star), [`no-effect-return-type`](RULES.md#no-effect-return-type), [`no-asymmetric-match-handlers`](RULES.md#no-asymmetric-match-handlers), [`anti-slop-prefer-effect-match`](RULES.md#anti-slop-prefer-effect-match) |
|
|
110
|
+
| Schema | [`exported-schema-identifier`](RULES.md#exported-schema-identifier), [`no-inline-schema-codec`](RULES.md#no-inline-schema-codec) |
|
|
111
|
+
| Config & secrets | [`redacted-secret-names`](RULES.md#redacted-secret-names) |
|
|
112
|
+
|
|
113
|
+
### Absorbed from anti-slop
|
|
114
|
+
|
|
115
|
+
The `anti-slop-*` rules come from the five Effect rules of [`dmmulroy/anti-slop`](https://github.com/dmmulroy/anti-slop) (plugin `anti-slop-effect`, commit [`c44ef22`](https://github.com/dmmulroy/anti-slop/tree/c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b/src/effect)), ported into this plugin; its generic TypeScript rules stay out. `no-manual-tag-comparison` and `no-manual-tagged-construction` are retired: [`no-manual-discriminant-comparison`](RULES.md#no-manual-discriminant-comparison) and [`no-manual-discriminant-construction`](RULES.md#no-manual-discriminant-construction) cover them with their default. In the others, detection logic and messages are unchanged; [`anti-slop-no-service-constructor-imports`](RULES.md#anti-slop-no-service-constructor-imports) recognizes test files through the shared [`testFiles`](RULES.md#file-options) option instead of its own `*.test.*`/`*.spec.*` check. Do not enable the `anti-slop-effect` plugin alongside this one: every finding would be reported twice. The original code is MIT-licensed: see [`LICENSE.anti-slop`](LICENSE.anti-slop).
|
|
116
|
+
|
|
117
|
+
## Default configuration
|
|
118
|
+
|
|
119
|
+
`all` is equivalent to the config below, with every option spelled out at its default. File options **replace** the defaults instead of extending them, and every rule sharing an option must get the same value: see [File options](RULES.md#file-options).
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { defineConfig } from "oxlint"
|
|
123
|
+
|
|
124
|
+
// Files allowed to run Effects (Effect.run*, runMain, ManagedRuntime.make) and to import
|
|
125
|
+
// adapters. `index.ts` is left out on purpose: as a barrel it would let adapters leak
|
|
126
|
+
// through re-exports.
|
|
127
|
+
const entryFiles = ["**/main.ts", "**/cli.ts", "**/bin/**"]
|
|
128
|
+
|
|
129
|
+
// Files exempt from the rules that tests legitimately break. Helper directories such as
|
|
130
|
+
// `src/testing/` are support code, not tests, so they are not matched.
|
|
131
|
+
const testFiles = ["**/*.test.*", "**/*.spec.*", "**/__tests__/**", "**/test/**", "**/tests/**"]
|
|
132
|
+
|
|
133
|
+
// Constructors that must not appear inside an Effect generator: the conversion to the
|
|
134
|
+
// transport belongs in the second argument of Effect.fn. Add your own transport DTOs.
|
|
135
|
+
const transportTypes = ["Response", "NextResponse"]
|
|
136
|
+
|
|
137
|
+
// Fields that discriminate a closed union, compared or switched on only through an exhaustive
|
|
138
|
+
// match and set only by a constructor. Add the ones your unions use, such as `type` or `kind`.
|
|
139
|
+
const discriminants = ["_tag"]
|
|
140
|
+
|
|
141
|
+
// Schema fields holding a secret: a field matches an entry or ends with it capitalized
|
|
142
|
+
// (`password` matches `dbPassword`). No generic `token`: `nextPageToken` is not a secret.
|
|
143
|
+
const secretFields = ["password", "secret", "apiKey", "accessToken", "refreshToken", "idToken"]
|
|
144
|
+
|
|
145
|
+
export default defineConfig({
|
|
146
|
+
// The package exports no entry point: point at the plugin file.
|
|
147
|
+
jsPlugins: ["./node_modules/@doubleloop-io/oxlint-plugin-effect/dist/index.js"],
|
|
148
|
+
// Every rule at `warn`, to measure noise without blocking.
|
|
149
|
+
rules: {
|
|
150
|
+
// Error channel
|
|
151
|
+
"dl-effect/no-bare-error-in-effect": "warn",
|
|
152
|
+
"dl-effect/try-object-form": "warn",
|
|
153
|
+
"dl-effect/no-effect-promise": ["warn", { testFiles }],
|
|
154
|
+
"dl-effect/no-parameterless-catch-all": "warn",
|
|
155
|
+
"dl-effect/error-handling-in-effect-fn-handler": ["warn", { testFiles }],
|
|
156
|
+
"dl-effect/anti-slop-no-manual-effect-error-tag": "warn",
|
|
157
|
+
// Tagged values
|
|
158
|
+
"dl-effect/no-manual-discriminant-comparison": ["warn", { discriminants }],
|
|
159
|
+
"dl-effect/no-manual-discriminant-construction": ["warn", { discriminants }],
|
|
160
|
+
// Services & Layers
|
|
161
|
+
"dl-effect/service-port-shape-only": "warn",
|
|
162
|
+
"dl-effect/service-key-matches-name": "warn",
|
|
163
|
+
"dl-effect/service-built-with-of": "warn",
|
|
164
|
+
"dl-effect/provide-named-layer": ["warn", { testFiles }],
|
|
165
|
+
"dl-effect/no-provide-on-definition": ["warn", { testFiles }],
|
|
166
|
+
"dl-effect/anti-slop-no-service-constructor-imports": ["warn", { testFiles }],
|
|
167
|
+
// Runtime & entrypoint
|
|
168
|
+
"dl-effect/run-only-at-entry": ["warn", { entryFiles }],
|
|
169
|
+
"dl-effect/boundary-entrypoint-shape": "warn",
|
|
170
|
+
// Design & boundaries
|
|
171
|
+
"dl-effect/adapter-import-boundary": ["warn", { entryFiles, testFiles }],
|
|
172
|
+
"dl-effect/no-transport-types-in-generator": ["warn", { transportTypes }],
|
|
173
|
+
// Effectful functions
|
|
174
|
+
"dl-effect/prefer-effect-fn": "warn",
|
|
175
|
+
"dl-effect/untraced-recursion": "warn",
|
|
176
|
+
"dl-effect/single-style-per-function": "warn",
|
|
177
|
+
// Code shape
|
|
178
|
+
"dl-effect/no-nested-match": "warn",
|
|
179
|
+
"dl-effect/no-yielded-match": "warn",
|
|
180
|
+
"dl-effect/no-inline-yield-star": "warn",
|
|
181
|
+
"dl-effect/no-effect-return-type": ["warn", { checkExported: false }],
|
|
182
|
+
"dl-effect/no-asymmetric-match-handlers": "warn",
|
|
183
|
+
"dl-effect/anti-slop-prefer-effect-match": "warn",
|
|
184
|
+
// Schema
|
|
185
|
+
"dl-effect/exported-schema-identifier": "warn",
|
|
186
|
+
"dl-effect/no-inline-schema-codec": "warn",
|
|
187
|
+
// Config & secrets
|
|
188
|
+
"dl-effect/redacted-secret-names": ["warn", { secretFields }],
|
|
189
|
+
},
|
|
190
|
+
})
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
To change one option, extend `all` and override only the rules that use it.
|
|
194
|
+
|
|
195
|
+
## Versioning
|
|
196
|
+
|
|
197
|
+
Versions are `0.x`: any minor release may add, remove or change rules, options and messages.
|
|
198
|
+
|
|
199
|
+
Supported oxlint is the `peerDependencies` range, `^1.82.0`; CI tests the tarball against `1.82.0`. oxlint's JS plugin API is still experimental, so a newer oxlint minor may break the plugin before the range is narrowed.
|
|
200
|
+
|
|
201
|
+
## Development
|
|
202
|
+
|
|
203
|
+
- `pnpm format`: formats with oxfmt; the only script that rewrites sources.
|
|
204
|
+
- `pnpm check`: format check, typecheck, lint and tests, writing nothing. The tests are the `RuleTester`s from `oxlint/plugins-dev` with `node --test`, plus an alignment check of `RULES.md` with one section per rule.
|
|
205
|
+
- `pnpm build`: compiles to `dist/` and generates `dist/presets/all.json` from `presets/all.ts` (the rule list comes from the plugin).
|
|
206
|
+
- `pnpm pack:check`: checks the built preset, then the tarball `npm pack` would publish: only the files in `files`, no internal names, `publint --strict`.
|
|
207
|
+
- `pnpm smoke-test`: installs the tarball in `smoke-fixture/` with pnpm and checks the diagnostics of oxlint with both config forms.
|
|
208
|
+
- `pnpm build-and-pack`: `check`, `build`, `pack:check` and `smoke-test`; run it after every change.
|
|
209
|
+
- `docs/consumer-loop.md`: how to run a consumer's checks against the checkout, without a release.
|
|
210
|
+
|
|
211
|
+
A new rule must be registered in `index.ts` and documented in `RULES.md` under a `` ### `rule-name` `` heading; `pnpm build` adds it to the preset.
|