oxlint-plugin-effector 0.0.1
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 +24 -0
- package/README.md +121 -0
- package/dist/index.js +2031 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Marsel Abazbekov
|
|
4
|
+
|
|
5
|
+
Rules ported from eslint-plugin-effector (https://github.com/effector/eslint-plugin),
|
|
6
|
+
Copyright (c) Igor Kamyshev, also MIT licensed.
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
in the Software without restriction, including without limitation the rights
|
|
11
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
furnished to do so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# oxlint-plugin-effector
|
|
2
|
+
|
|
3
|
+
Enforce [Effector](https://effector.dev) best practices with [oxlint](https://oxc.rs).
|
|
4
|
+
|
|
5
|
+
A **full, type-aware** port of [`eslint-plugin-effector`](https://github.com/effector/eslint-plugin) to oxlint's
|
|
6
|
+
[custom JS plugin API](https://oxc.rs/docs/guide/usage/linter/js-plugins). All **22 rules** are the original rules,
|
|
7
|
+
unchanged — this package runs the upstream plugin's entire test suite (349 cases) against the real TypeScript type
|
|
8
|
+
checker and passes it.
|
|
9
|
+
|
|
10
|
+
## How it stays type-aware on oxlint
|
|
11
|
+
|
|
12
|
+
The Effector rules need TypeScript types (to tell a `Store` from an `Event`, follow units across files, etc.).
|
|
13
|
+
oxlint does not hand type information to JS plugins. So instead of relying on it, **the plugin builds its own
|
|
14
|
+
`ts.Program`** using the `typescript` package directly and calls `getTypeAtLocation` itself, mapping oxlint's AST
|
|
15
|
+
nodes to TS nodes by source range. Under ESLint / the test runner it transparently uses the parser's existing
|
|
16
|
+
services; under oxlint it constructs its own. Same rule code, real types, either way. There is **no
|
|
17
|
+
`@typescript-eslint` in the runtime** — the only runtime dependencies are `typescript` (peer) and `esquery`.
|
|
18
|
+
|
|
19
|
+
Program discovery (`src/shared/services.ts`) is on plain `typescript` and handles the awkward setups:
|
|
20
|
+
|
|
21
|
+
- the nearest `tsconfig.json` is used; **project references are followed**, so a solution-style root tsconfig
|
|
22
|
+
(only `references`, no `files`) resolves the project that actually owns the file;
|
|
23
|
+
- if no tsconfig is found, a node-resolution fallback is used so `effector`/`react` types still resolve;
|
|
24
|
+
- set **`OXLINT_EFFECTOR_TSCONFIG`** to point at a specific tsconfig (custom names, monorepo roots).
|
|
25
|
+
|
|
26
|
+
Trade-off: building a TypeScript program means these rules are not "native oxlint" fast — the first lint of a
|
|
27
|
+
project pays for program creation. Functionally there are **no limitations** versus `eslint-plugin-effector`
|
|
28
|
+
(the full upstream test suite — 349 cases — passes against the real type checker).
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
npm install -D oxlint oxlint-plugin-effector typescript
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
oxlint JS plugins require an oxlint version that supports `jsPlugins`. `typescript` is a peer dependency (the
|
|
37
|
+
plugin uses it for type analysis).
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
Register the plugin under `jsPlugins`; rules are namespaced `effector/<rule>`.
|
|
42
|
+
|
|
43
|
+
```jsonc
|
|
44
|
+
// .oxlintrc.json
|
|
45
|
+
{
|
|
46
|
+
"jsPlugins": ["oxlint-plugin-effector"],
|
|
47
|
+
"rules": {
|
|
48
|
+
"effector/enforce-store-naming-convention": ["error", { "mode": "prefix" }],
|
|
49
|
+
"effector/no-watch": "warn",
|
|
50
|
+
"effector/no-getState": "error"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Severity presets are exported on `effector.configs` (`recommended`, `react`, `scope`, `future`, `patronum`) for use
|
|
56
|
+
from a JS/TS config:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
// oxlint.config.js
|
|
60
|
+
import effector from "oxlint-plugin-effector"
|
|
61
|
+
|
|
62
|
+
export default {
|
|
63
|
+
jsPlugins: ["oxlint-plugin-effector"],
|
|
64
|
+
rules: { ...effector.configs.recommended, ...effector.configs.react },
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Rules
|
|
69
|
+
|
|
70
|
+
### `recommended`
|
|
71
|
+
|
|
72
|
+
| Rule | Description |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| `enforce-effect-naming-convention` | Enforce `Fx` suffix for Effects |
|
|
75
|
+
| `enforce-store-naming-convention` | Enforce `$` prefix/postfix for Stores |
|
|
76
|
+
| `keep-options-order` | Enforce options order for Effector methods |
|
|
77
|
+
| `no-ambiguity-target` | Forbid ambiguous `target` in `sample`/`guard` |
|
|
78
|
+
| `no-duplicate-on` | Forbid duplicate `.on` calls on Stores |
|
|
79
|
+
| `no-forward` | Prefer `sample` over `forward` |
|
|
80
|
+
| `no-getState` | Forbid `.getState` on Stores |
|
|
81
|
+
| `no-guard` | Prefer `sample` over `guard` |
|
|
82
|
+
| `no-unnecessary-combination` | Forbid unnecessary `combine`/`merge` in `clock`/`source` |
|
|
83
|
+
| `no-unnecessary-duplication` | Forbid duplicate `source` and `clock` |
|
|
84
|
+
| `no-useless-methods` | Forbid useless `sample`/`guard` calls |
|
|
85
|
+
| `no-watch` | Restrict `.watch` on units |
|
|
86
|
+
|
|
87
|
+
### `react`
|
|
88
|
+
|
|
89
|
+
| Rule | Description |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
| `enforce-gate-naming-convention` | Enforce capitalized Gate names |
|
|
92
|
+
| `enforce-exhaustive-useUnit-destructuring` | Ensure units passed to `useUnit` are destructured |
|
|
93
|
+
| `mandatory-scope-binding` | Forbid Event/Effect usage without `useUnit` |
|
|
94
|
+
| `no-units-spawn-in-render` | Forbid creating units / calling operators in render |
|
|
95
|
+
| `prefer-useUnit` | Prefer `useUnit` over `useStore`/`useEvent` |
|
|
96
|
+
|
|
97
|
+
### `scope`
|
|
98
|
+
|
|
99
|
+
| Rule | Description |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| `require-pickup-in-persist` | Require `pickup` in `effector-storage` `persist` |
|
|
102
|
+
| `strict-effect-handlers` | Forbid mixing regular async fns and Effects |
|
|
103
|
+
|
|
104
|
+
### `future`
|
|
105
|
+
|
|
106
|
+
| Rule | Description |
|
|
107
|
+
| --- | --- |
|
|
108
|
+
| `no-domain-unit-creators` | Disallow Domain methods to create units |
|
|
109
|
+
|
|
110
|
+
### `patronum`
|
|
111
|
+
|
|
112
|
+
| Rule | Description |
|
|
113
|
+
| --- | --- |
|
|
114
|
+
| `no-patronum-debug` | Disallow `patronum`'s `debug` |
|
|
115
|
+
|
|
116
|
+
See [`examples/vite-comparison`](./examples/vite-comparison) for a project linted by both this plugin and
|
|
117
|
+
`eslint-plugin-effector`, producing identical results.
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
MIT. Rules ported from [`eslint-plugin-effector`](https://github.com/effector/eslint-plugin) (MIT).
|