-
Notifications
You must be signed in to change notification settings - Fork 75
Expand file tree
/
Copy patheslint.config.js
More file actions
136 lines (129 loc) · 4.74 KB
/
eslint.config.js
File metadata and controls
136 lines (129 loc) · 4.74 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
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
// @ts-check
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import reactPlugin from 'eslint-plugin-react';
import reactHooksPlugin from 'eslint-plugin-react-hooks';
import importPlugin from 'eslint-plugin-import';
// Domains with a public surface (`index.ts`). Other code must import via the
// domain root, never via internal sub-paths.
const DOMAINS = [
'Exercises',
'Routines',
'Weight',
'Nutrition',
'Measurements',
'Trophies',
'User',
];
const restrictAllDomains = {
"patterns": [{
"group": DOMAINS.map(d => `@/components/${d}/*`),
"message": "Import via the domain root (e.g. '@/components/Exercises'), not internal sub-paths.",
}]
};
// Per-domain override: files inside `components/<Domain>/` may import their
// OWN internals via absolute paths (though relative paths are preferred).
// Cross-domain absolute internals remain forbidden.
const domainOverrides = DOMAINS.map(domain => ({
files: [`src/components/${domain}/**/*.{ts,tsx}`],
rules: {
"no-restricted-imports": ["error", {
"patterns": [{
"group": DOMAINS
.filter(d => d !== domain)
.map(d => `@/components/${d}/*`),
"message": `Import other domains via their public surface (e.g. '@/components/${DOMAINS[0]}'), not internal sub-paths.`,
}]
}],
}
}));
export default tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommended,
{
files: ['**/*.{js,jsx,ts,tsx}'],
plugins: {
'react': reactPlugin,
'react-hooks': reactHooksPlugin,
'import': importPlugin,
},
rules: {
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
// React rules
'react/jsx-key': 'error',
'react/jsx-no-target-blank': 'error',
'react/no-unstable-nested-components': 'error',
'react/no-array-index-key': 'warn',
'react/jsx-no-duplicate-props': 'error',
'react/no-children-prop': 'error',
'react/void-dom-elements-no-children': 'error',
'react/no-unescaped-entities': 'error',
'react/self-closing-comp': 'error',
// Core JS hygiene.
'eqeqeq': ['error', 'smart'],
'no-var': 'error',
'prefer-const': 'error',
'no-console': ['warn', {allow: ['warn', 'error']}],
},
settings: {
react: {
version: 'detect'
}
}
},
{
files: ['**/*.ts', '**/*.tsx'],
rules: {
'semi': ['error', 'always'],
'camelcase': ['warn'],
"@typescript-eslint/no-unused-vars": ["warn"],
"@typescript-eslint/no-explicit-any": ["error"],
"@typescript-eslint/no-non-null-asserted-optional-chain": ["warn"],
"@typescript-eslint/no-unsafe-function-type": ["warn"],
"@typescript-eslint/ban-ts-comment": [
"warn", // changed to warning
{
"ts-ignore": "allow-with-description",
"ts-expect-error": "allow-with-description",
"minimumDescriptionLength": 10
}
],
// Auto-fixable: consolidates multiple imports from the same module.
"import/no-duplicates": ["error"],
// Domain boundary: consumers must import via the public surface
// (index.ts), not internal sub-paths.
"no-restricted-imports": ["error", restrictAllDomains],
}
},
// Per-domain overrides: relax the rule for same-domain imports.
...domainOverrides,
{
// The infrastructure layer (api/ files inside each domain, core/lib,
// tests/, types.ts) sits BELOW the consumer code. Importing from a
// domain barrel here would create circular dependencies (the barrel
// pulls in queries which depend on api). These files must use direct
// sub-paths.
//
// Test files are also exempted — they legitimately mock internal
// modules across domains (e.g. a Calendar test that asserts on
// multiple domains' api functions).
files: [
'src/components/*/api/**',
'src/core/api/**',
'src/core/lib/**',
'src/tests/**',
'src/types.ts',
'src/**/*.test.{ts,tsx}',
],
rules: {
"no-restricted-imports": "off",
"no-console": "off",
// API adapters and test fixtures mirror the backend's snake_case field names
"camelcase": "off",
}
},
{
ignores: ['build/**/*']
}
);