@doubleloop-io/oxlint-plugin-effect 0.1.0-rc.0 → 0.1.0-rc.2
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/README.md +106 -82
- package/RULES.md +527 -382
- package/dist/index.d.ts +3 -0
- package/dist/index.js +13 -8
- package/dist/presets/all.json +5 -4
- package/dist/rules/adapter-import-boundary.js +5 -12
- package/dist/rules/all-errors-handled-at-boundary.d.ts +1 -0
- package/dist/rules/all-errors-handled-at-boundary.js +105 -0
- package/dist/rules/anti-slop-no-service-constructor-imports.js +1 -8
- package/dist/rules/exported-schema-identifier.js +15 -10
- package/dist/rules/no-effect-promise.js +1 -8
- package/dist/rules/no-manual-discriminant-comparison.js +36 -19
- package/dist/rules/no-manual-discriminant-construction.js +50 -14
- package/dist/rules/no-provide-on-definition.js +31 -9
- package/dist/rules/no-throw-or-primitive-failure.d.ts +1 -0
- package/dist/rules/{no-bare-error-in-effect.js → no-throw-or-primitive-failure.js} +11 -3
- package/dist/rules/no-yielded-match.js +9 -2
- package/dist/rules/prefer-effect-vitest.d.ts +1 -0
- package/dist/rules/prefer-effect-vitest.js +45 -0
- package/dist/rules/provide-named-layer.js +1 -8
- package/dist/rules/redacted-secret-names.js +18 -7
- package/dist/rules/run-only-in-runner.d.ts +1 -0
- package/dist/rules/run-only-in-runner.js +33 -0
- package/dist/rules/service-key-matches-name.js +15 -6
- package/dist/rules/service-port-shape-only.js +10 -18
- package/dist/rules/single-style-per-function.js +82 -21
- package/dist/rules/split-success-path-from-error-handling.d.ts +1 -0
- package/dist/rules/split-success-path-from-error-handling.js +137 -0
- package/dist/shared/effect-ast.d.ts +1 -0
- package/dist/shared/effect-ast.js +15 -4
- package/dist/shared/effect-runners.d.ts +2 -0
- package/dist/shared/effect-runners.js +14 -0
- package/dist/shared/entry-files.d.ts +2 -2
- package/dist/shared/file-globs.d.ts +3 -9
- package/dist/shared/file-globs.js +3 -12
- package/dist/shared/settings.d.ts +5 -0
- package/dist/shared/settings.js +26 -0
- package/dist/shared/tagged-values.d.ts +2 -8
- package/dist/shared/tagged-values.js +3 -14
- package/dist/shared/test-files.d.ts +2 -2
- package/package.json +61 -54
- package/dist/rules/boundary-entrypoint-shape.d.ts +0 -1
- package/dist/rules/boundary-entrypoint-shape.js +0 -52
- package/dist/rules/error-handling-in-effect-fn-handler.d.ts +0 -1
- package/dist/rules/error-handling-in-effect-fn-handler.js +0 -66
- package/dist/rules/no-bare-error-in-effect.d.ts +0 -1
- package/dist/rules/run-only-at-entry.d.ts +0 -1
- package/dist/rules/run-only-at-entry.js +0 -50
package/README.md
CHANGED
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
An oxlint plugin that enforces a catalog of patterns for Effect 4 code.
|
|
4
4
|
|
|
5
|
-
The rules are written and tested against Effect 4.
|
|
5
|
+
The rules are written and tested against Effect 4. Where an Effect 3 API has the same intent, the rules recognize its v3 name too: each rule's Trigger in [`RULES.md`](RULES.md) names them.
|
|
6
6
|
|
|
7
|
-
|
|
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.
|
|
7
|
+
It complements the type-aware rules of [`@effect/tsgo`](#alongside-effecttsgo): it does not need them, and it checks what they do not.
|
|
10
8
|
|
|
11
9
|
## Installation
|
|
12
10
|
|
|
@@ -18,9 +16,16 @@ Requires Node `^22.20.0 || >=24.8.0` and oxlint `^1.82.0`.
|
|
|
18
16
|
|
|
19
17
|
## Configuration
|
|
20
18
|
|
|
21
|
-
Extend the `all` preset.
|
|
19
|
+
Extend the `all` preset. Prefer `oxlint.config.ts`, where `extends` takes config objects and the preset is imported by package name:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import dlEffectAll from "@doubleloop-io/oxlint-plugin-effect/presets/all"
|
|
23
|
+
import { defineConfig } from "oxlint"
|
|
24
|
+
|
|
25
|
+
export default defineConfig({ extends: [dlEffectAll] })
|
|
26
|
+
```
|
|
22
27
|
|
|
23
|
-
With `.oxlintrc.json`,
|
|
28
|
+
With `.oxlintrc.json`, `extends` takes file paths only, so the preset is reached through `node_modules`:
|
|
24
29
|
|
|
25
30
|
```json
|
|
26
31
|
{
|
|
@@ -28,55 +33,69 @@ With `.oxlintrc.json`, where `extends` takes file paths:
|
|
|
28
33
|
}
|
|
29
34
|
```
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
`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.
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
import dlEffectAll from "@doubleloop-io/oxlint-plugin-effect/presets/all"
|
|
35
|
-
import { defineConfig } from "oxlint"
|
|
38
|
+
To pick rules without the preset, load the plugin by package name and list the rules:
|
|
36
39
|
|
|
37
|
-
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"jsPlugins": ["@doubleloop-io/oxlint-plugin-effect"],
|
|
43
|
+
"rules": {
|
|
44
|
+
"dl-effect/no-effect-promise": "error",
|
|
45
|
+
"dl-effect/try-object-form": "error"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
38
48
|
```
|
|
39
49
|
|
|
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
50
|
### Configuration options
|
|
43
51
|
|
|
44
|
-
|
|
52
|
+
Three settings describe your project, not a rule, so they are declared once under `settings["dl-effect"]` and every rule that uses them reads them from there. Their defaults fit a Node CLI; on another layout (Next.js, a monorepo) set them before reading the warnings.
|
|
45
53
|
|
|
46
|
-
- `entryFiles`: the files allowed to run Effects and import adapters. Default `**/main.ts`, `**/cli.ts`, `**/bin/**`.
|
|
47
|
-
- `testFiles`: the files exempt from the rules that tests legitimately break. Default `**/*.test.*`, `**/*.spec.*`, `**/__tests__/**`, `**/test/**`, `**/tests/**`.
|
|
54
|
+
- `entryFiles`: the files allowed to run Effects and import adapters. Default `**/main.ts`, `**/cli.ts`, `**/bin/**`.
|
|
55
|
+
- `testFiles`: the test files, exempt from the rules that tests legitimately break and the only files `prefer-effect-vitest` checks. Default `**/*.test.*`, `**/*.spec.*`, `**/__tests__/**`, `**/test/**`, `**/tests/**`.
|
|
56
|
+
- `discriminants`: the fields that discriminate a closed union. Default `_tag`; add the ones your unions use, such as `type` or `kind`.
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
The rules that use each one are listed in [Shared settings](RULES.md#shared-settings). Set one only where its default does not fit: it **replaces** the default instead of extending it. An unknown key or a value that is not an array of strings stops the lint with an error, so a typo is never silently ignored.
|
|
50
59
|
|
|
51
60
|
```ts
|
|
52
61
|
import dlEffectAll from "@doubleloop-io/oxlint-plugin-effect/presets/all"
|
|
53
62
|
import { defineConfig } from "oxlint"
|
|
54
63
|
|
|
55
|
-
const entryFiles = ["apps/web/src/app/**/route.ts", "apps/web/src/runtime.ts"]
|
|
56
|
-
const testFiles = ["**/*.test.ts", "e2e/**"]
|
|
57
|
-
|
|
58
64
|
export default defineConfig({
|
|
59
65
|
extends: [dlEffectAll],
|
|
60
|
-
|
|
61
|
-
"dl-effect
|
|
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 }],
|
|
66
|
+
settings: {
|
|
67
|
+
"dl-effect": { entryFiles: ["apps/web/src/app/**/route.ts", "apps/web/src/runtime.ts"] },
|
|
68
68
|
},
|
|
69
69
|
})
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"extends": ["./node_modules/@doubleloop-io/oxlint-plugin-effect/dist/presets/all.json"],
|
|
75
|
+
"settings": {
|
|
76
|
+
"dl-effect": { "entryFiles": ["apps/web/src/app/**/route.ts", "apps/web/src/runtime.ts"] }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The package exports the defaults as `defaultEntryFiles`, `defaultTestFiles` and `defaultDiscriminants`: spread them to extend a default (`testFiles: [...defaultTestFiles, "e2e/**"]`).
|
|
82
|
+
|
|
83
|
+
Settings belong to the config that lints: oxlint does not inherit them from a preset in `extends`, and rejects them in `overrides`. For a value that differs by group of files, use `overrides` on the rules instead.
|
|
73
84
|
|
|
74
85
|
The other options and every default are in [Default configuration](#default-configuration).
|
|
75
86
|
|
|
76
|
-
### Alongside `@effect/tsgo`
|
|
87
|
+
### Alongside `@effect/tsgo`
|
|
77
88
|
|
|
78
89
|
[`@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
90
|
|
|
91
|
+
```ts
|
|
92
|
+
import dlEffectAll from "@doubleloop-io/oxlint-plugin-effect/presets/all"
|
|
93
|
+
import { recommended as effectTsgoRecommended } from "@effect/tsgo/oxlint-presets"
|
|
94
|
+
import { defineConfig } from "oxlint"
|
|
95
|
+
|
|
96
|
+
export default defineConfig({ extends: [effectTsgoRecommended, dlEffectAll] })
|
|
97
|
+
```
|
|
98
|
+
|
|
80
99
|
```json
|
|
81
100
|
{
|
|
82
101
|
"extends": [
|
|
@@ -86,89 +105,92 @@ The other options and every default are in [Default configuration](#default-conf
|
|
|
86
105
|
}
|
|
87
106
|
```
|
|
88
107
|
|
|
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
108
|
## Rules
|
|
98
109
|
|
|
99
110
|
What each rule reports and why is in [`RULES.md`](RULES.md).
|
|
100
111
|
|
|
101
|
-
| Topic | Rules
|
|
102
|
-
| -------------------- |
|
|
103
|
-
| Error channel | [`no-
|
|
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-
|
|
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
|
+
| Topic | Rules |
|
|
113
|
+
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
114
|
+
| Error channel | [`no-throw-or-primitive-failure`](RULES.md#no-throw-or-primitive-failure), [`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), [`split-success-path-from-error-handling`](RULES.md#split-success-path-from-error-handling), [`anti-slop-no-manual-effect-error-tag`](RULES.md#anti-slop-no-manual-effect-error-tag) |
|
|
115
|
+
| Tagged values | [`no-manual-discriminant-comparison`](RULES.md#no-manual-discriminant-comparison), [`no-manual-discriminant-construction`](RULES.md#no-manual-discriminant-construction) |
|
|
116
|
+
| 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) |
|
|
117
|
+
| Runtime & entrypoint | [`run-only-in-runner`](RULES.md#run-only-in-runner), [`prefer-effect-vitest`](RULES.md#prefer-effect-vitest), [`all-errors-handled-at-boundary`](RULES.md#all-errors-handled-at-boundary) |
|
|
118
|
+
| Design & boundaries | [`adapter-import-boundary`](RULES.md#adapter-import-boundary), [`no-transport-types-in-generator`](RULES.md#no-transport-types-in-generator) |
|
|
119
|
+
| 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) |
|
|
120
|
+
| 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) |
|
|
121
|
+
| Schema | [`exported-schema-identifier`](RULES.md#exported-schema-identifier), [`no-inline-schema-codec`](RULES.md#no-inline-schema-codec) |
|
|
122
|
+
| Config & secrets | [`redacted-secret-names`](RULES.md#redacted-secret-names) |
|
|
112
123
|
|
|
113
124
|
### Absorbed from anti-slop
|
|
114
125
|
|
|
115
|
-
|
|
126
|
+
Some rules come from the Effect rules of [`dmmulroy/anti-slop`](https://github.com/dmmulroy/anti-slop), MIT-licensed: see [`LICENSE.anti-slop`](LICENSE.anti-slop).
|
|
127
|
+
|
|
128
|
+
- Imported: [`anti-slop-no-manual-effect-error-tag`](RULES.md#anti-slop-no-manual-effect-error-tag), [`anti-slop-no-service-constructor-imports`](RULES.md#anti-slop-no-service-constructor-imports), [`anti-slop-prefer-effect-match`](RULES.md#anti-slop-prefer-effect-match).
|
|
129
|
+
- Superseded: `no-manual-tag-comparison` by [`no-manual-discriminant-comparison`](RULES.md#no-manual-discriminant-comparison), `no-manual-tagged-construction` by [`no-manual-discriminant-construction`](RULES.md#no-manual-discriminant-construction).
|
|
116
130
|
|
|
117
131
|
## Default configuration
|
|
118
132
|
|
|
119
|
-
`all` is equivalent to the config below, with every option spelled out at its default.
|
|
133
|
+
`all` is equivalent to the config below, with every setting and option spelled out at its default. Both **replace** the defaults instead of extending them: see [Shared settings](RULES.md#shared-settings).
|
|
120
134
|
|
|
121
135
|
```ts
|
|
122
136
|
import { defineConfig } from "oxlint"
|
|
123
137
|
|
|
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
138
|
// Constructors that must not appear inside an Effect generator: the conversion to the
|
|
134
139
|
// transport belongs in the second argument of Effect.fn. Add your own transport DTOs.
|
|
135
140
|
const transportTypes = ["Response", "NextResponse"]
|
|
136
141
|
|
|
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
142
|
// Schema fields holding a secret: a field matches an entry or ends with it capitalized
|
|
142
143
|
// (`password` matches `dbPassword`). No generic `token`: `nextPageToken` is not a secret.
|
|
143
144
|
const secretFields = ["password", "secret", "apiKey", "accessToken", "refreshToken", "idToken"]
|
|
144
145
|
|
|
145
146
|
export default defineConfig({
|
|
146
|
-
|
|
147
|
-
|
|
147
|
+
jsPlugins: ["@doubleloop-io/oxlint-plugin-effect"],
|
|
148
|
+
settings: {
|
|
149
|
+
"dl-effect": {
|
|
150
|
+
// Files allowed to run Effects (Effect.run*, runMain, ManagedRuntime.make) and to
|
|
151
|
+
// import adapters. `index.ts` is left out on purpose: as a barrel it would let
|
|
152
|
+
// adapters leak through re-exports.
|
|
153
|
+
entryFiles: ["**/main.ts", "**/cli.ts", "**/bin/**"],
|
|
154
|
+
// Files exempt from the rules that tests legitimately break. Helper directories such
|
|
155
|
+
// as `src/testing/` are support code, not tests, so they are not matched.
|
|
156
|
+
testFiles: [
|
|
157
|
+
"**/*.test.*",
|
|
158
|
+
"**/*.spec.*",
|
|
159
|
+
"**/__tests__/**",
|
|
160
|
+
"**/test/**",
|
|
161
|
+
"**/tests/**",
|
|
162
|
+
],
|
|
163
|
+
// Fields that discriminate a closed union, compared or switched on only through an
|
|
164
|
+
// exhaustive match and set only by a constructor. Add the ones your unions use, such
|
|
165
|
+
// as `type` or `kind`.
|
|
166
|
+
discriminants: ["_tag"],
|
|
167
|
+
},
|
|
168
|
+
},
|
|
148
169
|
// Every rule at `warn`, to measure noise without blocking.
|
|
149
170
|
rules: {
|
|
150
171
|
// Error channel
|
|
151
|
-
"dl-effect/no-
|
|
172
|
+
"dl-effect/no-throw-or-primitive-failure": "warn",
|
|
152
173
|
"dl-effect/try-object-form": "warn",
|
|
153
|
-
"dl-effect/no-effect-promise":
|
|
174
|
+
"dl-effect/no-effect-promise": "warn",
|
|
154
175
|
"dl-effect/no-parameterless-catch-all": "warn",
|
|
155
|
-
"dl-effect/
|
|
176
|
+
"dl-effect/split-success-path-from-error-handling": "warn",
|
|
156
177
|
"dl-effect/anti-slop-no-manual-effect-error-tag": "warn",
|
|
157
178
|
// Tagged values
|
|
158
|
-
"dl-effect/no-manual-discriminant-comparison":
|
|
159
|
-
"dl-effect/no-manual-discriminant-construction":
|
|
179
|
+
"dl-effect/no-manual-discriminant-comparison": "warn",
|
|
180
|
+
"dl-effect/no-manual-discriminant-construction": "warn",
|
|
160
181
|
// Services & Layers
|
|
161
182
|
"dl-effect/service-port-shape-only": "warn",
|
|
162
183
|
"dl-effect/service-key-matches-name": "warn",
|
|
163
184
|
"dl-effect/service-built-with-of": "warn",
|
|
164
|
-
"dl-effect/provide-named-layer":
|
|
165
|
-
"dl-effect/no-provide-on-definition":
|
|
166
|
-
"dl-effect/anti-slop-no-service-constructor-imports":
|
|
185
|
+
"dl-effect/provide-named-layer": "warn",
|
|
186
|
+
"dl-effect/no-provide-on-definition": "warn",
|
|
187
|
+
"dl-effect/anti-slop-no-service-constructor-imports": "warn",
|
|
167
188
|
// Runtime & entrypoint
|
|
168
|
-
"dl-effect/run-only-
|
|
169
|
-
"dl-effect/
|
|
189
|
+
"dl-effect/run-only-in-runner": "warn",
|
|
190
|
+
"dl-effect/prefer-effect-vitest": "warn",
|
|
191
|
+
"dl-effect/all-errors-handled-at-boundary": "warn",
|
|
170
192
|
// Design & boundaries
|
|
171
|
-
"dl-effect/adapter-import-boundary":
|
|
193
|
+
"dl-effect/adapter-import-boundary": "warn",
|
|
172
194
|
"dl-effect/no-transport-types-in-generator": ["warn", { transportTypes }],
|
|
173
195
|
// Effectful functions
|
|
174
196
|
"dl-effect/prefer-effect-fn": "warn",
|
|
@@ -190,11 +212,11 @@ export default defineConfig({
|
|
|
190
212
|
})
|
|
191
213
|
```
|
|
192
214
|
|
|
193
|
-
To change
|
|
215
|
+
To change a setting, declare it in `settings`; to change a rule option, extend `all` and override only that rule.
|
|
194
216
|
|
|
195
217
|
## Versioning
|
|
196
218
|
|
|
197
|
-
Versions are `0.x`: any minor release may add, remove or change rules, options and messages.
|
|
219
|
+
Versions are `0.x`: any minor release may add, remove or change rules, options, settings and messages.
|
|
198
220
|
|
|
199
221
|
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
222
|
|
|
@@ -203,9 +225,11 @@ Supported oxlint is the `peerDependencies` range, `^1.82.0`; CI tests the tarbal
|
|
|
203
225
|
- `pnpm format`: formats with oxfmt; the only script that rewrites sources.
|
|
204
226
|
- `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
227
|
- `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
|
|
207
|
-
- `pnpm smoke-test`: installs the tarball in `smoke-fixture/` with pnpm and checks the diagnostics of oxlint with
|
|
228
|
+
- `pnpm pack:check`: checks the built preset, then the tarball `npm pack` would publish: only the files in `files`, no local absolute paths, `publint --strict`.
|
|
229
|
+
- `pnpm smoke-test`: installs the tarball in `smoke-fixture/` with pnpm and checks the diagnostics of oxlint with each config form: `oxlint.config.ts` and `.oxlintrc.json` with the preset, `.oxlintrc.json` with the plugin by package name.
|
|
208
230
|
- `pnpm build-and-pack`: `check`, `build`, `pack:check` and `smoke-test`; run it after every change.
|
|
209
|
-
- `
|
|
231
|
+
- `pnpm release <bump>`: from a clean `main` equal to `origin/main`, runs `build-and-pack`, bumps with `npm version <bump> --preid rc` (`prerelease` for the next rc, `x.y.z` for a stable), publishes, then pushes the commit and the tag. A prerelease is `next`, and also `latest` until the first stable version; a stable version is `latest`. A failed publish undoes the bump. Without `<bump>`, prints the version in `package.json` and the npm dist-tags.
|
|
232
|
+
- `pnpm build:w`: reruns `pnpm build`, preset included, on every change to `index.ts`, `rules/`, `presets/`, `shared/` or `tsconfig.build.json`; a failed build waits for the next change.
|
|
233
|
+
- `pnpm consumer:link <consumer>`: after `pnpm build`, replaces the pnpm symlinks of the plugin in every workspace package of `<consumer>` with links to the checkout, so the consumer's own lint runs the checkout's rules; no tracked file of the consumer changes. `pnpm consumer:unlink <consumer>` restores them with `pnpm install --frozen-lockfile`, as does any `pnpm install` in the consumer.
|
|
210
234
|
|
|
211
235
|
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.
|