@hypersolid-dev/eslint-config 5.0.0 → 6.0.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/CHANGELOG.md +15 -0
- package/README.md +17 -1
- package/dist/base.js +14 -1
- package/dist/jest.d.ts +3 -0
- package/dist/jest.js +56 -0
- package/dist/plugins/props-destructuring.js +12 -12
- package/dist/plugins/react-native-a11y/rules/accessibility-actions-need-handler.js +2 -2
- package/dist/plugins/react-native-a11y/rules/accessibility-hint.js +2 -2
- package/dist/plugins/react-native-a11y/rules/accessibility-label.js +2 -2
- package/dist/plugins/react-native-a11y/rules/accessibility-role.js +2 -2
- package/dist/plugins/react-native-a11y/rules/accessibility-value-needs-range.js +25 -27
- package/dist/plugins/react-native-a11y/rules/adjustable-needs-value.js +16 -18
- package/dist/plugins/react-native-a11y/rules/gate-announce-for-accessibility.js +4 -4
- package/dist/plugins/react-native-a11y/rules/input-purpose.js +2 -2
- package/dist/plugins/react-native-a11y/rules/no-aria-legacy-mix.js +20 -22
- package/dist/plugins/react-native-a11y/rules/no-deprecated-accessibility-focus.js +12 -14
- package/dist/plugins/react-native-a11y/rules/no-dropped-aria-on-text.js +2 -2
- package/dist/plugins/react-native-a11y/rules/no-font-scaling-disabled.js +24 -26
- package/dist/plugins/react-native-a11y/rules/no-ineffective-accessibility-props.js +34 -36
- package/dist/plugins/react-native-a11y/rules/no-invalid-accessibility-state.js +31 -33
- package/dist/plugins/react-native-a11y/rules/no-nested-focus-stops.js +2 -2
- package/dist/plugins/react-native-a11y/rules/no-press-in-activation.js +2 -2
- package/dist/plugins/react-native-a11y/rules/no-unnamed-interactive.js +2 -2
- package/dist/plugins/react-native-a11y/rules/require-invert-colors-opt-out.js +2 -2
- package/dist/plugins/react-native-a11y/rules/require-modal-a11y-on-sheets.js +2 -2
- package/dist/plugins/react-native-a11y/utils/get-amount-of-text-children.js +15 -13
- package/dist/plugins/rules/boolean-guard.js +3 -3
- package/dist/plugins/rules/comment-style.js +43 -34
- package/dist/plugins/rules/effect-takes-callback.js +1 -1
- package/dist/plugins/rules/jsdoc-for-props.js +1 -1
- package/dist/plugins/rules/no-callback-payload.js +18 -15
- package/dist/plugins/rules/no-markup-variable.js +41 -35
- package/dist/plugins/rules/no-unnecessary-use-callback.js +2 -2
- package/dist/plugins/rules/regex-pattern-const.js +1 -1
- package/dist/plugins/rules/test-id-default.js +23 -27
- package/dist/plugins/rules/test-id-format.js +14 -18
- package/dist/plugins/rules/test-id-from-props.js +23 -27
- package/dist/plugins/rules/undefined-check.js +2 -2
- package/dist/plugins/rules/webview-allow-list.js +22 -26
- package/dist/plugins/utils/expressions.d.ts +3 -3
- package/dist/plugins/utils/expressions.js +94 -78
- package/dist/plugins/utils/types.js +14 -12
- package/dist/react-native.js +28 -0
- package/dist/shared.d.ts +3 -3
- package/dist/shared.js +168 -112
- package/package.json +12 -2
package/dist/shared.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import eslintReact from '@eslint-react/eslint-plugin';
|
|
2
|
+
import reactDoctor from 'eslint-plugin-react-doctor';
|
|
2
3
|
import reactHooks from 'eslint-plugin-react-hooks';
|
|
3
4
|
import unicorn from 'eslint-plugin-unicorn';
|
|
4
5
|
import hypersolid from './plugins/hypersolid.js';
|
|
@@ -52,119 +53,174 @@ export const NAMING_CONVENTION = [
|
|
|
52
53
|
{ selector: 'typeLike', format: ['PascalCase'] },
|
|
53
54
|
];
|
|
54
55
|
// Every enabled rule is an error: a warning is either worth fixing or not worth reporting.
|
|
55
|
-
export
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
export const raiseWarnings = (configs) => configs.map((config) => {
|
|
57
|
+
if (!config.rules) {
|
|
58
|
+
return config;
|
|
59
|
+
}
|
|
60
|
+
const rules = {};
|
|
61
|
+
for (const [name, entry] of Object.entries(config.rules)) {
|
|
62
|
+
if (entry === undefined) {
|
|
63
|
+
continue;
|
|
59
64
|
}
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
rules[name] = severity === 'warn' || severity === 1 ? ['error', ...ruleOptions] : entry;
|
|
67
|
-
}
|
|
68
|
-
return { ...config, rules };
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
export function scopeToCode(configs) {
|
|
72
|
-
return configs.map((config) => ({ files: CODE_FILES, ...config }));
|
|
73
|
-
}
|
|
65
|
+
const [severity, ...ruleOptions] = Array.isArray(entry) ? entry : [entry];
|
|
66
|
+
rules[name] = severity === 'warn' || severity === 1 ? ['error', ...ruleOptions] : entry;
|
|
67
|
+
}
|
|
68
|
+
return { ...config, rules };
|
|
69
|
+
});
|
|
70
|
+
export const scopeToCode = (configs) => configs.map((config) => ({ files: CODE_FILES, ...config }));
|
|
74
71
|
// The React block shared by `react` and `react-native`.
|
|
75
|
-
export
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
'
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
'@hypersolid-dev/jsdoc-for-props': 'error',
|
|
153
|
-
},
|
|
72
|
+
export const reactConfigs = () => [
|
|
73
|
+
...scopeToCode([
|
|
74
|
+
// React correctness for TypeScript projects. Bad: `this.state.count = 1`, `<li>` in a `.map()` without `key`.
|
|
75
|
+
eslintReact.configs['recommended-typescript'],
|
|
76
|
+
// The official hooks rules plus the React Compiler checks. Bad: `if (isOpen) useEffect(…)`, a missing effect dependency.
|
|
77
|
+
reactHooks.configs.flat['recommended-latest'],
|
|
78
|
+
]),
|
|
79
|
+
{
|
|
80
|
+
name: '@hypersolid-dev/react',
|
|
81
|
+
files: CODE_FILES,
|
|
82
|
+
plugins: { '@hypersolid-dev': hypersolid, unicorn },
|
|
83
|
+
languageOptions: { parserOptions: { ecmaFeatures: { jsx: true } } },
|
|
84
|
+
rules: {
|
|
85
|
+
// Off: react-hooks/exhaustive-deps reports it. Bad: `useEffect(() => log(id), [])` reported twice.
|
|
86
|
+
'@eslint-react/exhaustive-deps': 'off',
|
|
87
|
+
// Off: react-hooks/rules-of-hooks reports it. Bad: `if (isOpen) useEffect(…)` reported twice.
|
|
88
|
+
'@eslint-react/rules-of-hooks': 'off',
|
|
89
|
+
// Off: react-hooks/error-boundaries reports it. Bad: `try { return <Child /> } catch {…}` reported twice.
|
|
90
|
+
'@eslint-react/error-boundaries': 'off',
|
|
91
|
+
// Off: react-hooks/purity reports it. Bad: `const id = Math.random()` in render reported twice.
|
|
92
|
+
'@eslint-react/purity': 'off',
|
|
93
|
+
// Off: react-hooks/set-state-in-effect reports it. Bad: `useEffect(() => setCount(1))` reported twice.
|
|
94
|
+
'@eslint-react/set-state-in-effect': 'off',
|
|
95
|
+
// Off: react-hooks/set-state-in-render reports it. Bad: `setCount(1)` in the component body reported twice.
|
|
96
|
+
'@eslint-react/set-state-in-render': 'off',
|
|
97
|
+
// Off: react-hooks/static-components reports it. Bad: a component created during render reported twice.
|
|
98
|
+
'@eslint-react/static-components': 'off',
|
|
99
|
+
// Off: react-hooks/unsupported-syntax reports it. Bad: `eval(code)` in a component reported twice.
|
|
100
|
+
'@eslint-react/unsupported-syntax': 'off',
|
|
101
|
+
// Off: react-hooks/use-memo reports it. Bad: `useMemo(async () => …)` reported twice.
|
|
102
|
+
'@eslint-react/use-memo': 'off',
|
|
103
|
+
// A component defined inside another remounts on every render. Bad: `function List() { function Row() {…} return <Row />; }`.
|
|
104
|
+
'@eslint-react/no-nested-component-definitions': 'error',
|
|
105
|
+
// List items need a `key`. Bad: `items.map((item) => <Row item={item} />)`.
|
|
106
|
+
'@eslint-react/no-missing-key': 'error',
|
|
107
|
+
// Sibling keys are unique. Bad: `<Row key="a" /><Row key="a" />`.
|
|
108
|
+
'@eslint-react/no-duplicate-key': 'error',
|
|
109
|
+
// An index key breaks state when the list reorders. Bad: `items.map((item, index) => <Row key={index} />)`.
|
|
110
|
+
'@eslint-react/no-array-index-key': 'error',
|
|
111
|
+
// A new context value each render re-renders every consumer. Bad: `<Context value={{ user }}>`.
|
|
112
|
+
'@eslint-react/no-unstable-context-value': 'error',
|
|
113
|
+
// Props are readable from the component's signature; a union props type may keep `props`. Bad: `const Card = (props: Props) => <h1>{props.title}</h1>`.
|
|
114
|
+
'@hypersolid-dev/props-destructuring': 'error',
|
|
115
|
+
// A boolean reads as a claim; hook and mock names are exempt. Bad: `const visible = true` (use `isVisible`).
|
|
116
|
+
'unicorn/consistent-boolean-name': ['error', REACT_BOOLEAN_NAME_OPTIONS],
|
|
117
|
+
// Base's empty catch and default specifiers, plus compiler opt-outs, hooks inside JSX and `React.useX`. Bad: `style={useAnimatedStyle(…)}`, `React.useState(0)`.
|
|
118
|
+
'no-restricted-syntax': ['error', ...REACT_RESTRICTED_SYNTAX],
|
|
119
|
+
// Base's naming, plus: a boolean prop is a state, not a command. Bad: `type Props = { showBadge: boolean }` (use `hasBadge`).
|
|
120
|
+
'@typescript-eslint/naming-convention': [
|
|
121
|
+
'error',
|
|
122
|
+
...NAMING_CONVENTION,
|
|
123
|
+
{ selector: 'typeProperty', types: ['boolean'], format: null, custom: { regex: '^(show|display|hide)[A-Z]', match: false } },
|
|
124
|
+
],
|
|
125
|
+
// A fragment around one child renders nothing extra. Bad: `<><Row /></>`.
|
|
126
|
+
'@eslint-react/jsx-no-useless-fragment': 'error',
|
|
127
|
+
// A literal default prop is a new object each render and breaks memoization. Bad: `({ items = [] }: Props)`.
|
|
128
|
+
'@eslint-react/no-unstable-default-props': 'error',
|
|
129
|
+
// State synced from props in an effect renders one frame stale. Bad: `useEffect(() => setFullName(first + last), [first, last])`.
|
|
130
|
+
'react-hooks/no-deriving-state-in-effects': 'error',
|
|
131
|
+
// Off: memo-dependencies and exhaustive-effect-dependencies check the same arrays with the compiler's analysis, so one missing dependency would be reported twice.
|
|
132
|
+
'react-hooks/exhaustive-deps': 'off',
|
|
133
|
+
// The compiler's dependency check for memos: missing and unused deps. Bad: `useMemo(() => a + b, [a])`.
|
|
134
|
+
'react-hooks/memo-dependencies': 'error',
|
|
135
|
+
// The same check for effects; plugin 7.1.1 ships it inert, so `environment` turns it on. Bad: `useEffect(() => log(id), [])`.
|
|
136
|
+
'react-hooks/exhaustive-effect-dependencies': ['error', { environment: { validateExhaustiveEffectDependencies: 'all' } }],
|
|
137
|
+
// `{count && <Badge />}` renders `0`, which crashes React Native outside `<Text>`. Bad: `{items.length && <List />}`.
|
|
138
|
+
'@hypersolid-dev/boolean-guard': 'error',
|
|
139
|
+
// Styled JSX built in a component body is a component without a name. Bad: `const header = <View style={s.header}>…</View>`.
|
|
140
|
+
'@hypersolid-dev/no-markup-variable': 'error',
|
|
141
|
+
// A `use*Effect` hook takes its callback first, like `useEffect`. Bad: `useFocusEffect(deps, () => …)`.
|
|
142
|
+
'@hypersolid-dev/effect-takes-callback': 'error',
|
|
143
|
+
// A `useCallback` with empty deps that captures nothing is a module-level function. Bad: `useCallback(() => track('open'), [])`.
|
|
144
|
+
'@hypersolid-dev/no-unnecessary-use-callback': 'error',
|
|
145
|
+
// A component forwards the event; the caller builds the payload. Bad: `onPress={() => onSelect(item.id)}` inside `Row`.
|
|
146
|
+
'@hypersolid-dev/no-callback-payload': 'error',
|
|
147
|
+
// A comment on a type member is JSDoc, the form editors show. Bad: `// The title\ntitle: string` in a props type.
|
|
148
|
+
'@hypersolid-dev/jsdoc-for-props': 'error',
|
|
154
149
|
},
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
/**
|
|
153
|
+
* React Doctor's bug catchers, as used in the ESPN Goal pilot; test doubles break them by design.
|
|
154
|
+
* Left out as duplicates: `no-create-ref-in-function-component` (@eslint-react/no-create-ref), and
|
|
155
|
+
* `effect-listener-cleanup-mismatch` and `effect-remove-listener-inline-handler` (@eslint-react/web-api-no-leaked-event-listener).
|
|
156
|
+
*/
|
|
157
|
+
name: '@hypersolid-dev/react/react-doctor',
|
|
158
|
+
files: CODE_FILES,
|
|
159
|
+
ignores: TEST_FILES,
|
|
160
|
+
plugins: { 'react-doctor': reactDoctor },
|
|
161
|
+
rules: {
|
|
162
|
+
// A value computed from props or state is read where used, not copied into state. Bad: `const [full, setFull] = useState(first + last)` kept in sync by an effect.
|
|
163
|
+
'react-doctor/no-derived-state': 'error',
|
|
164
|
+
// A refetch from an effect double-fetches and races the cache; key the query instead. Bad: `useEffect(() => { refetch(); }, [id])`.
|
|
165
|
+
'react-doctor/query-no-query-in-effect': 'error',
|
|
166
|
+
// A write behind `useQuery` posts again on focus and mount; writes are mutations. Bad: `useQuery({ queryFn: () => api.post(…) })`.
|
|
167
|
+
'react-doctor/query-no-usequery-for-mutation': 'error',
|
|
168
|
+
// A `requestAnimationFrame` loop without a cancel keeps running after unmount. Bad: an effect that schedules `tick` with no `cancelAnimationFrame` cleanup.
|
|
169
|
+
'react-doctor/effect-raf-loop-needs-cancel': 'error',
|
|
170
|
+
// A timer ref holding a cleared id still reads as pending. Bad: `clearTimeout(timer.current)` without `timer.current = undefined`.
|
|
171
|
+
'react-doctor/no-stale-timer-ref': 'error',
|
|
172
|
+
// An effect wrapper must return the callback's cleanup. Bad: `useEffect(() => { callback(); }, deps)` in a `useMountEffect(callback)`.
|
|
173
|
+
'react-doctor/no-effect-wrapper-discards-callback-cleanup-return': 'error',
|
|
174
|
+
// A fetch in an effect races on re-run and is neither cached nor deduplicated. Bad: `useEffect(() => { fetch(url).then(setData); }, [url])`.
|
|
175
|
+
'react-doctor/no-fetch-in-effect': 'error',
|
|
176
|
+
// A toggle from a deferred callback reads a stale value; use the updater. Bad: `setTimeout(() => setOpen(!open))`.
|
|
177
|
+
'react-doctor/no-boolean-toggle-without-functional-update': 'error',
|
|
178
|
+
// Mutating state and setting it hands React the same reference, so nothing re-renders. Bad: `items.push(item); setItems(items)`.
|
|
179
|
+
'react-doctor/no-direct-state-mutation': 'error',
|
|
180
|
+
// The same mutation through an alias. Bad: `const next = state; next.done = true; setState(next)`.
|
|
181
|
+
'react-doctor/no-mutate-then-set-or-return-same-reference': 'error',
|
|
182
|
+
// `sort`, `reverse` and `splice` reorder a prop in place; use `toSorted` and friends. Bad: `props.items.sort(byName)`.
|
|
183
|
+
'react-doctor/no-mutating-array-method-on-prop-or-hook-result': 'error',
|
|
184
|
+
// React may call an updater twice, so a side effect in one runs twice. Bad: `setCount((count) => { track(count); return count + 1; })`.
|
|
185
|
+
'react-doctor/no-side-effect-in-state-updater-function': 'error',
|
|
186
|
+
// After `.fill(x)` every element is x, so every key is the same. Bad: `Array(3).fill(0).map((value) => <Dot key={value} />)`.
|
|
187
|
+
'react-doctor/no-fill-map-element-as-key': 'error',
|
|
188
|
+
// Calling a component runs its hooks as the caller's. Bad: `{Row(props)}` instead of `<Row {...props} />`.
|
|
189
|
+
'react-doctor/no-call-component-as-function': 'error',
|
|
190
|
+
// A context created in render is new each time, so consumers lose their provider. Bad: `const Theme = createContext(light)` inside a component.
|
|
191
|
+
'react-doctor/no-create-context-in-render': 'error',
|
|
192
|
+
// Render can be discarded, so calling a prop callback from it reports UI that never committed. Bad: `onReady()` in the component body.
|
|
193
|
+
'react-doctor/no-prop-callback-in-render': 'error',
|
|
194
|
+
// State plus a subscribing effect tears under concurrent rendering. Bad: `useEffect(() => store.subscribe(() => setValue(store.get())))`.
|
|
195
|
+
'react-doctor/prefer-use-sync-external-store': 'error',
|
|
196
|
+
// A hook renamed on import hides from the hooks rules, which match on the name. Bad: `import { useQuery as query } from '…'`.
|
|
197
|
+
'react-doctor/hook-import-rename-loses-use-prefix': 'error',
|
|
198
|
+
// An index read is typed `T` but is `undefined` on a short array. Bad: `items[0].title` without a length check.
|
|
199
|
+
'react-doctor/no-array-index-deref-without-bounds-or-empty-guard': 'error',
|
|
200
|
+
// Arithmetic binds tighter than `??`. Bad: `count ?? 0 + 1` (means `count ?? (0 + 1)`).
|
|
201
|
+
'react-doctor/no-nullish-coalescing-arithmetic-precedence': 'error',
|
|
202
|
+
// A whole-object parameter default is dropped as soon as any object is passed. Bad: `({ size, color } = { size: 1, color: 'red' })`.
|
|
203
|
+
'react-doctor/no-whole-object-default-losing-per-key-defaults': 'error',
|
|
204
|
+
// An explicit `undefined` prop erases the default it is spread over. Bad: `{ ...DEFAULTS, ...props }`.
|
|
205
|
+
'react-doctor/no-spread-props-over-defaults-clobbers-with-undefined': 'error',
|
|
206
|
+
// fetch resolves on a 4xx or 5xx, so parsing without checking `ok` reads the error body as data. Bad: `(await fetch(url)).json()`.
|
|
207
|
+
'react-doctor/no-fetch-response-used-without-status-check': 'error',
|
|
208
|
+
// An unescaped search term turns `.` and `(` into pattern syntax. Bad: `new RegExp(query)`.
|
|
209
|
+
'react-doctor/no-unescaped-dynamic-string-in-regexp': 'error',
|
|
168
210
|
},
|
|
169
|
-
|
|
170
|
-
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: '@hypersolid-dev/react/tests',
|
|
214
|
+
files: TEST_FILES,
|
|
215
|
+
rules: {
|
|
216
|
+
// Off: tests build markup and callbacks inline by design. Bad: `const tree = <Row />` in a test reported.
|
|
217
|
+
'@hypersolid-dev/boolean-guard': 'off',
|
|
218
|
+
'@hypersolid-dev/no-markup-variable': 'off',
|
|
219
|
+
'@hypersolid-dev/effect-takes-callback': 'off',
|
|
220
|
+
'@hypersolid-dev/no-unnecessary-use-callback': 'off',
|
|
221
|
+
'@hypersolid-dev/no-callback-payload': 'off',
|
|
222
|
+
// Off: a mocked hook keeps the `use` name of the hook it replaces. Bad: `const useUser = () => fakeUser` in a mock.
|
|
223
|
+
'@eslint-react/no-unnecessary-use-prefix': 'off',
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypersolid-dev/eslint-config",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "Shared ESLint flat config for Hypersolid TypeScript projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"react",
|
|
13
13
|
"react-native",
|
|
14
14
|
"next",
|
|
15
|
-
"node"
|
|
15
|
+
"node",
|
|
16
|
+
"jest"
|
|
16
17
|
],
|
|
17
18
|
"type": "module",
|
|
18
19
|
"exports": {
|
|
@@ -35,6 +36,10 @@
|
|
|
35
36
|
"./next": {
|
|
36
37
|
"types": "./dist/next.d.ts",
|
|
37
38
|
"default": "./dist/next.js"
|
|
39
|
+
},
|
|
40
|
+
"./jest": {
|
|
41
|
+
"types": "./dist/jest.d.ts",
|
|
42
|
+
"default": "./dist/jest.js"
|
|
38
43
|
}
|
|
39
44
|
},
|
|
40
45
|
"files": [
|
|
@@ -75,9 +80,14 @@
|
|
|
75
80
|
"eslint-import-resolver-typescript": "^4.4.5",
|
|
76
81
|
"eslint-plugin-expo": "^1.2.1",
|
|
77
82
|
"eslint-plugin-import-x": "^4.17.1",
|
|
83
|
+
"eslint-plugin-jest": "^29.17.0",
|
|
78
84
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
79
85
|
"eslint-plugin-no-secrets": "^2.3.3",
|
|
86
|
+
"eslint-plugin-prefer-arrow-functions": "^3.10.2",
|
|
87
|
+
"eslint-plugin-react-doctor": "0.9.22",
|
|
80
88
|
"eslint-plugin-react-hooks": "7.1.1",
|
|
89
|
+
"eslint-plugin-sonarjs": "^4.2.2",
|
|
90
|
+
"eslint-plugin-testing-library": "^7.16.2",
|
|
81
91
|
"eslint-plugin-unicorn": "^79.0.0",
|
|
82
92
|
"globals": "^17.13.0",
|
|
83
93
|
"typescript-eslint": "^8.72.1"
|