@pyreon/lint 0.11.4 → 0.11.6
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 +91 -91
- package/lib/analysis/cli.js.html +5406 -0
- package/lib/analysis/index.js.html +1 -1
- package/lib/cli.js +3290 -0
- package/lib/cli.js.map +1 -0
- package/lib/index.js +220 -29
- package/lib/index.js.map +1 -1
- package/lib/types/index.d.ts +30 -5
- package/lib/types/index.d.ts.map +1 -1
- package/package.json +19 -19
- package/src/cache.ts +1 -1
- package/src/cli.ts +39 -28
- package/src/config/ignore.ts +23 -23
- package/src/config/loader.ts +8 -8
- package/src/config/presets.ts +11 -11
- package/src/index.ts +14 -12
- package/src/lint.ts +19 -25
- package/src/lsp/index.ts +225 -0
- package/src/reporter.ts +17 -17
- package/src/rules/accessibility/dialog-a11y.ts +10 -10
- package/src/rules/accessibility/overlay-a11y.ts +11 -11
- package/src/rules/accessibility/toast-a11y.ts +11 -11
- package/src/rules/architecture/dev-guard-warnings.ts +19 -19
- package/src/rules/architecture/no-circular-import.ts +16 -16
- package/src/rules/architecture/no-cross-layer-import.ts +35 -35
- package/src/rules/architecture/no-deep-import.ts +7 -7
- package/src/rules/architecture/no-error-without-prefix.ts +20 -20
- package/src/rules/form/no-submit-without-validation.ts +13 -13
- package/src/rules/form/no-unregistered-field.ts +12 -12
- package/src/rules/form/prefer-field-array.ts +11 -11
- package/src/rules/hooks/no-raw-addeventlistener.ts +9 -9
- package/src/rules/hooks/no-raw-localstorage.ts +11 -11
- package/src/rules/hooks/no-raw-setinterval.ts +11 -11
- package/src/rules/index.ts +60 -57
- package/src/rules/jsx/no-and-conditional.ts +8 -8
- package/src/rules/jsx/no-children-access.ts +12 -12
- package/src/rules/jsx/no-classname.ts +10 -10
- package/src/rules/jsx/no-htmlfor.ts +10 -10
- package/src/rules/jsx/no-index-as-by.ts +17 -17
- package/src/rules/jsx/no-map-in-jsx.ts +9 -9
- package/src/rules/jsx/no-missing-for-by.ts +9 -9
- package/src/rules/jsx/no-onchange.ts +12 -12
- package/src/rules/jsx/no-props-destructure.ts +11 -11
- package/src/rules/jsx/no-ternary-conditional.ts +8 -8
- package/src/rules/jsx/use-by-not-key.ts +12 -12
- package/src/rules/lifecycle/no-dom-in-setup.ts +18 -18
- package/src/rules/lifecycle/no-effect-in-mount.ts +11 -11
- package/src/rules/lifecycle/no-missing-cleanup.ts +19 -19
- package/src/rules/lifecycle/no-mount-in-effect.ts +11 -11
- package/src/rules/performance/no-eager-import.ts +7 -7
- package/src/rules/performance/no-effect-in-for.ts +10 -10
- package/src/rules/performance/no-large-for-without-by.ts +9 -9
- package/src/rules/performance/prefer-show-over-display.ts +16 -16
- package/src/rules/reactivity/no-bare-signal-in-jsx.ts +10 -10
- package/src/rules/reactivity/no-context-destructure.ts +45 -0
- package/src/rules/reactivity/no-effect-assignment.ts +16 -16
- package/src/rules/reactivity/no-nested-effect.ts +10 -10
- package/src/rules/reactivity/no-peek-in-tracked.ts +10 -10
- package/src/rules/reactivity/no-signal-in-loop.ts +13 -13
- package/src/rules/reactivity/no-signal-leak.ts +9 -9
- package/src/rules/reactivity/no-unbatched-updates.ts +12 -12
- package/src/rules/reactivity/prefer-computed.ts +13 -13
- package/src/rules/router/index.ts +4 -4
- package/src/rules/router/no-href-navigation.ts +14 -14
- package/src/rules/router/no-imperative-navigate-in-render.ts +19 -19
- package/src/rules/router/no-missing-fallback.ts +16 -16
- package/src/rules/router/prefer-use-is-active.ts +11 -11
- package/src/rules/ssr/no-mismatch-risk.ts +11 -11
- package/src/rules/ssr/no-window-in-ssr.ts +22 -22
- package/src/rules/ssr/prefer-request-context.ts +14 -14
- package/src/rules/store/no-duplicate-store-id.ts +9 -9
- package/src/rules/store/no-mutate-store-state.ts +11 -11
- package/src/rules/store/no-store-outside-provider.ts +15 -15
- package/src/rules/styling/no-dynamic-styled.ts +13 -13
- package/src/rules/styling/no-inline-style-object.ts +10 -10
- package/src/rules/styling/no-theme-outside-provider.ts +11 -11
- package/src/rules/styling/prefer-cx.ts +12 -12
- package/src/runner.ts +13 -14
- package/src/tests/lsp.test.ts +88 -0
- package/src/tests/runner.test.ts +325 -325
- package/src/types.ts +15 -15
- package/src/utils/ast.ts +50 -50
- package/src/utils/imports.ts +53 -53
- package/src/utils/index.ts +12 -3
- package/src/utils/source.ts +2 -2
- package/src/watcher.ts +19 -25
package/README.md
CHANGED
|
@@ -41,12 +41,12 @@ pyreon-lint --list
|
|
|
41
41
|
### Programmatic API
|
|
42
42
|
|
|
43
43
|
```ts
|
|
44
|
-
import { lint, listRules, lintFile, applyFixes } from
|
|
44
|
+
import { lint, listRules, lintFile, applyFixes } from '@pyreon/lint'
|
|
45
45
|
|
|
46
46
|
// Lint files
|
|
47
47
|
const result = lint({
|
|
48
|
-
paths: [
|
|
49
|
-
preset:
|
|
48
|
+
paths: ['src/'],
|
|
49
|
+
preset: 'recommended',
|
|
50
50
|
fix: false,
|
|
51
51
|
quiet: false,
|
|
52
52
|
})
|
|
@@ -59,140 +59,140 @@ for (const rule of listRules()) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// Lint a single source string
|
|
62
|
-
import { getPreset } from
|
|
63
|
-
import { allRules } from
|
|
62
|
+
import { getPreset } from '@pyreon/lint'
|
|
63
|
+
import { allRules } from '@pyreon/lint/rules'
|
|
64
64
|
|
|
65
|
-
const fileResult = lintFile(
|
|
65
|
+
const fileResult = lintFile('app.tsx', source, allRules, getPreset('recommended'))
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
## Rules (51)
|
|
69
69
|
|
|
70
70
|
### Reactivity (8)
|
|
71
71
|
|
|
72
|
-
| Rule
|
|
73
|
-
|
|
74
|
-
| `pyreon/no-bare-signal-in-jsx` | error
|
|
75
|
-
| `pyreon/no-signal-in-loop`
|
|
76
|
-
| `pyreon/no-nested-effect`
|
|
77
|
-
| `pyreon/no-peek-in-tracked`
|
|
78
|
-
| `pyreon/no-unbatched-updates`
|
|
79
|
-
| `pyreon/prefer-computed`
|
|
80
|
-
| `pyreon/no-effect-assignment`
|
|
81
|
-
| `pyreon/no-signal-leak`
|
|
72
|
+
| Rule | Severity | Fixable | Description |
|
|
73
|
+
| ------------------------------ | -------- | ------- | ------------------------------------------------- |
|
|
74
|
+
| `pyreon/no-bare-signal-in-jsx` | error | Yes | Flags `{count()}` in JSX text — wrap in `() =>` |
|
|
75
|
+
| `pyreon/no-signal-in-loop` | error | No | Flags signal()/computed() inside loops |
|
|
76
|
+
| `pyreon/no-nested-effect` | warn | No | Flags effect() inside effect() |
|
|
77
|
+
| `pyreon/no-peek-in-tracked` | error | No | Flags .peek() inside effect/computed |
|
|
78
|
+
| `pyreon/no-unbatched-updates` | warn | No | Flags 3+ .set() calls without batch() |
|
|
79
|
+
| `pyreon/prefer-computed` | warn | No | Suggests computed() for effect with single .set() |
|
|
80
|
+
| `pyreon/no-effect-assignment` | warn | No | Flags effect with single .update() |
|
|
81
|
+
| `pyreon/no-signal-leak` | warn | No | Reports unused signal declarations |
|
|
82
82
|
|
|
83
83
|
### JSX (11)
|
|
84
84
|
|
|
85
|
-
| Rule
|
|
86
|
-
|
|
87
|
-
| `pyreon/no-map-in-jsx`
|
|
88
|
-
| `pyreon/use-by-not-key`
|
|
89
|
-
| `pyreon/no-classname`
|
|
90
|
-
| `pyreon/no-htmlfor`
|
|
91
|
-
| `pyreon/no-onchange`
|
|
92
|
-
| `pyreon/no-ternary-conditional` | warn
|
|
93
|
-
| `pyreon/no-and-conditional`
|
|
94
|
-
| `pyreon/no-index-as-by`
|
|
95
|
-
| `pyreon/no-missing-for-by`
|
|
96
|
-
| `pyreon/no-props-destructure`
|
|
97
|
-
| `pyreon/no-children-access`
|
|
85
|
+
| Rule | Severity | Fixable | Description |
|
|
86
|
+
| ------------------------------- | -------- | ------- | ------------------------------------------ |
|
|
87
|
+
| `pyreon/no-map-in-jsx` | warn | No | Prefer `<For>` over .map() in JSX |
|
|
88
|
+
| `pyreon/use-by-not-key` | error | Yes | Use `by` not `key` on `<For>` |
|
|
89
|
+
| `pyreon/no-classname` | error | Yes | Use `class` not `className` |
|
|
90
|
+
| `pyreon/no-htmlfor` | error | Yes | Use `for` not `htmlFor` |
|
|
91
|
+
| `pyreon/no-onchange` | warn | Yes | Prefer `onInput` over `onChange` on inputs |
|
|
92
|
+
| `pyreon/no-ternary-conditional` | warn | No | Prefer `<Show>` over ternary with JSX |
|
|
93
|
+
| `pyreon/no-and-conditional` | warn | No | Prefer `<Show>` over `&&` with JSX |
|
|
94
|
+
| `pyreon/no-index-as-by` | warn | No | Don't use index as `by` prop |
|
|
95
|
+
| `pyreon/no-missing-for-by` | warn | No | `<For>` should have `by` prop |
|
|
96
|
+
| `pyreon/no-props-destructure` | error | No | Don't destructure component props |
|
|
97
|
+
| `pyreon/no-children-access` | info | No | Direct props.children access in renderers |
|
|
98
98
|
|
|
99
99
|
### Lifecycle (4)
|
|
100
100
|
|
|
101
|
-
| Rule
|
|
102
|
-
|
|
103
|
-
| `pyreon/no-missing-cleanup` | warn
|
|
104
|
-
| `pyreon/no-mount-in-effect` | warn
|
|
105
|
-
| `pyreon/no-effect-in-mount` | info
|
|
106
|
-
| `pyreon/no-dom-in-setup`
|
|
101
|
+
| Rule | Severity | Fixable | Description |
|
|
102
|
+
| --------------------------- | -------- | ------- | ---------------------------------------- |
|
|
103
|
+
| `pyreon/no-missing-cleanup` | warn | No | onMount with timers needs cleanup return |
|
|
104
|
+
| `pyreon/no-mount-in-effect` | warn | No | Don't call onMount inside effect |
|
|
105
|
+
| `pyreon/no-effect-in-mount` | info | No | effect() inside onMount is unusual |
|
|
106
|
+
| `pyreon/no-dom-in-setup` | warn | No | DOM queries outside onMount/effect |
|
|
107
107
|
|
|
108
108
|
### Performance (4)
|
|
109
109
|
|
|
110
|
-
| Rule
|
|
111
|
-
|
|
112
|
-
| `pyreon/no-large-for-without-by`
|
|
113
|
-
| `pyreon/no-effect-in-for`
|
|
114
|
-
| `pyreon/no-eager-import`
|
|
115
|
-
| `pyreon/prefer-show-over-display` | info
|
|
110
|
+
| Rule | Severity | Fixable | Description |
|
|
111
|
+
| --------------------------------- | -------- | ------- | ------------------------------------------ |
|
|
112
|
+
| `pyreon/no-large-for-without-by` | error | No | `<For>` must have `by` for reconciliation |
|
|
113
|
+
| `pyreon/no-effect-in-for` | warn | No | Don't create effects inside `<For>` |
|
|
114
|
+
| `pyreon/no-eager-import` | info | No | Lazy-load heavy packages |
|
|
115
|
+
| `pyreon/prefer-show-over-display` | info | No | Use `<Show>` instead of CSS display toggle |
|
|
116
116
|
|
|
117
117
|
### SSR (3)
|
|
118
118
|
|
|
119
|
-
| Rule
|
|
120
|
-
|
|
121
|
-
| `pyreon/no-window-in-ssr`
|
|
122
|
-
| `pyreon/no-mismatch-risk`
|
|
123
|
-
| `pyreon/prefer-request-context` | warn
|
|
119
|
+
| Rule | Severity | Fixable | Description |
|
|
120
|
+
| ------------------------------- | -------- | ------- | ----------------------------------- |
|
|
121
|
+
| `pyreon/no-window-in-ssr` | error | No | Browser globals outside safe scopes |
|
|
122
|
+
| `pyreon/no-mismatch-risk` | warn | No | Non-deterministic calls in JSX |
|
|
123
|
+
| `pyreon/prefer-request-context` | warn | No | Module-level state in server files |
|
|
124
124
|
|
|
125
125
|
### Architecture (5)
|
|
126
126
|
|
|
127
|
-
| Rule
|
|
128
|
-
|
|
129
|
-
| `pyreon/no-circular-import`
|
|
130
|
-
| `pyreon/no-deep-import`
|
|
131
|
-
| `pyreon/no-cross-layer-import`
|
|
132
|
-
| `pyreon/dev-guard-warnings`
|
|
133
|
-
| `pyreon/no-error-without-prefix` | warn
|
|
127
|
+
| Rule | Severity | Fixable | Description |
|
|
128
|
+
| -------------------------------- | -------- | ------- | ---------------------------------- |
|
|
129
|
+
| `pyreon/no-circular-import` | error | No | Enforce package layer order |
|
|
130
|
+
| `pyreon/no-deep-import` | warn | No | No @pyreon/\*/src/ imports |
|
|
131
|
+
| `pyreon/no-cross-layer-import` | error | No | Core can't import ui-system |
|
|
132
|
+
| `pyreon/dev-guard-warnings` | error | No | console.warn/error needs `__DEV__` |
|
|
133
|
+
| `pyreon/no-error-without-prefix` | warn | Yes | Errors need [Pyreon] prefix |
|
|
134
134
|
|
|
135
135
|
### Store (3)
|
|
136
136
|
|
|
137
|
-
| Rule
|
|
138
|
-
|
|
139
|
-
| `pyreon/no-store-outside-provider` | warn
|
|
140
|
-
| `pyreon/no-mutate-store-state`
|
|
141
|
-
| `pyreon/no-duplicate-store-id`
|
|
137
|
+
| Rule | Severity | Fixable | Description |
|
|
138
|
+
| ---------------------------------- | -------- | ------- | -------------------------------- |
|
|
139
|
+
| `pyreon/no-store-outside-provider` | warn | No | Store hooks need provider in SSR |
|
|
140
|
+
| `pyreon/no-mutate-store-state` | warn | No | Use actions, not direct .set() |
|
|
141
|
+
| `pyreon/no-duplicate-store-id` | error | No | Unique defineStore() IDs |
|
|
142
142
|
|
|
143
143
|
### Form (3)
|
|
144
144
|
|
|
145
|
-
| Rule
|
|
146
|
-
|
|
147
|
-
| `pyreon/no-unregistered-field`
|
|
148
|
-
| `pyreon/no-submit-without-validation` | warn
|
|
149
|
-
| `pyreon/prefer-field-array`
|
|
145
|
+
| Rule | Severity | Fixable | Description |
|
|
146
|
+
| ------------------------------------- | -------- | ------- | ----------------------------------- |
|
|
147
|
+
| `pyreon/no-unregistered-field` | warn | No | useField() without register() |
|
|
148
|
+
| `pyreon/no-submit-without-validation` | warn | No | useForm onSubmit without validators |
|
|
149
|
+
| `pyreon/prefer-field-array` | info | No | signal([]) in form files |
|
|
150
150
|
|
|
151
151
|
### Styling (4)
|
|
152
152
|
|
|
153
|
-
| Rule
|
|
154
|
-
|
|
155
|
-
| `pyreon/no-inline-style-object`
|
|
156
|
-
| `pyreon/no-dynamic-styled`
|
|
157
|
-
| `pyreon/prefer-cx`
|
|
158
|
-
| `pyreon/no-theme-outside-provider` | warn
|
|
153
|
+
| Rule | Severity | Fixable | Description |
|
|
154
|
+
| ---------------------------------- | -------- | ------- | ------------------------------ |
|
|
155
|
+
| `pyreon/no-inline-style-object` | warn | No | Inline style objects in JSX |
|
|
156
|
+
| `pyreon/no-dynamic-styled` | warn | No | styled() inside functions |
|
|
157
|
+
| `pyreon/prefer-cx` | info | No | Use cx() for class composition |
|
|
158
|
+
| `pyreon/no-theme-outside-provider` | warn | No | useTheme() without provider |
|
|
159
159
|
|
|
160
160
|
### Hooks (3)
|
|
161
161
|
|
|
162
|
-
| Rule
|
|
163
|
-
|
|
164
|
-
| `pyreon/no-raw-addeventlistener` | info
|
|
165
|
-
| `pyreon/no-raw-setinterval`
|
|
166
|
-
| `pyreon/no-raw-localstorage`
|
|
162
|
+
| Rule | Severity | Fixable | Description |
|
|
163
|
+
| -------------------------------- | -------- | ------- | ---------------------- |
|
|
164
|
+
| `pyreon/no-raw-addeventlistener` | info | No | Use useEventListener() |
|
|
165
|
+
| `pyreon/no-raw-setinterval` | info | No | Wrap timers in onMount |
|
|
166
|
+
| `pyreon/no-raw-localstorage` | info | No | Use useStorage() |
|
|
167
167
|
|
|
168
168
|
### Accessibility (3)
|
|
169
169
|
|
|
170
|
-
| Rule
|
|
171
|
-
|
|
172
|
-
| `pyreon/toast-a11y`
|
|
173
|
-
| `pyreon/dialog-a11y`
|
|
174
|
-
| `pyreon/overlay-a11y` | warn
|
|
170
|
+
| Rule | Severity | Fixable | Description |
|
|
171
|
+
| --------------------- | -------- | ------- | ------------------------------------ |
|
|
172
|
+
| `pyreon/toast-a11y` | warn | No | Toast components need role/aria-live |
|
|
173
|
+
| `pyreon/dialog-a11y` | warn | No | `<dialog>` needs aria-label |
|
|
174
|
+
| `pyreon/overlay-a11y` | warn | No | `<Overlay>` needs role/aria-label |
|
|
175
175
|
|
|
176
176
|
## Presets
|
|
177
177
|
|
|
178
|
-
| Preset
|
|
179
|
-
|
|
180
|
-
| `recommended` | All rules at default severity
|
|
181
|
-
| `strict`
|
|
182
|
-
| `app`
|
|
183
|
-
| `lib`
|
|
178
|
+
| Preset | Description |
|
|
179
|
+
| ------------- | ------------------------------------ |
|
|
180
|
+
| `recommended` | All rules at default severity |
|
|
181
|
+
| `strict` | All warnings promoted to errors |
|
|
182
|
+
| `app` | Recommended minus library-only rules |
|
|
183
|
+
| `lib` | Strict plus architecture checks |
|
|
184
184
|
|
|
185
185
|
## Custom Rules
|
|
186
186
|
|
|
187
187
|
```ts
|
|
188
|
-
import type { Rule } from
|
|
188
|
+
import type { Rule } from '@pyreon/lint'
|
|
189
189
|
|
|
190
190
|
const myRule: Rule = {
|
|
191
191
|
meta: {
|
|
192
|
-
id:
|
|
193
|
-
category:
|
|
194
|
-
description:
|
|
195
|
-
severity:
|
|
192
|
+
id: 'custom/my-rule',
|
|
193
|
+
category: 'reactivity',
|
|
194
|
+
description: 'My custom rule',
|
|
195
|
+
severity: 'warn',
|
|
196
196
|
fixable: false,
|
|
197
197
|
},
|
|
198
198
|
create(context) {
|
|
@@ -200,7 +200,7 @@ const myRule: Rule = {
|
|
|
200
200
|
CallExpression(node, parent) {
|
|
201
201
|
// Your rule logic
|
|
202
202
|
context.report({
|
|
203
|
-
message:
|
|
203
|
+
message: 'Something is wrong',
|
|
204
204
|
span: { start: node.start, end: node.end },
|
|
205
205
|
})
|
|
206
206
|
},
|