-
Notifications
You must be signed in to change notification settings - Fork 327
Expand file tree
/
Copy patheslint.config.js
More file actions
105 lines (100 loc) · 3.3 KB
/
Copy patheslint.config.js
File metadata and controls
105 lines (100 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format
import storybook from 'eslint-plugin-storybook'
import js from '@eslint/js'
import typescript from '@typescript-eslint/eslint-plugin'
import typescriptParser from '@typescript-eslint/parser'
import prettier from 'eslint-config-prettier'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import globals from 'globals'
import { sharedParserOptions, sharedRules } from './shared/eslint/base.js'
export default [
// Global ignores (object with only `ignores` applies repo-wide). The generated
// wasm-bindgen glue is a build artifact — never lint it.
{ ignores: ['src/acp/iroh/pkg/**', 'crates/**'] },
js.configs.recommended,
prettier,
{
files: ['src/**/*.{ts,tsx}'],
ignores: ['node_modules', 'dist', 'dist-isolation', 'src-tauri', 'thunderbird-*', 'backend'],
languageOptions: {
parser: typescriptParser,
parserOptions: {
...sharedParserOptions,
ecmaFeatures: { jsx: true },
},
globals: {
...globals.browser,
...globals.node,
React: 'readonly',
Bun: 'readonly',
NodeJS: 'readonly',
RequestInfo: 'readonly',
RequestInit: 'readonly',
},
},
plugins: {
'@typescript-eslint': typescript,
react,
'react-hooks': reactHooks,
},
settings: {
react: { version: 'detect' },
},
rules: {
...sharedRules,
// React
'react/react-in-jsx-scope': 'off',
'react/prop-types': 'off',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
// Frontend-specific restrictions
'no-restricted-imports': [
'error',
{
name: 'react',
importNames: ['default'],
message: 'Do not import default React. Use named imports instead.',
},
],
'no-restricted-syntax': [
'error',
{
selector: "ExpressionStatement > Literal[value='use client']",
message: "'use client' is not needed in Vite — remove it.",
},
{
selector: "MemberExpression[object.name='React']",
message:
"React namespace access is not allowed. Use direct imports instead (e.g. import { type ReactNode } from 'react').",
},
{
selector: "TSQualifiedName[left.name='React']",
message:
"React namespace access in types is not allowed. Use direct imports instead (e.g. import { type ReactNode } from 'react').",
},
],
},
},
{
// Environment-agnostic code shared by frontend and backend. No React or
// browser assumptions here — just the shared TypeScript conventions.
files: ['shared/**/*.{ts,tsx}'],
languageOptions: {
parser: typescriptParser,
parserOptions: sharedParserOptions,
globals: {
...globals.node,
Bun: 'readonly',
},
},
plugins: {
'@typescript-eslint': typescript,
},
rules: sharedRules,
},
...storybook.configs['flat/recommended'],
]