forked from DouglasNeuroInformatics/OpenDataCapture
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheslint.config.js
More file actions
169 lines (160 loc) · 4.89 KB
/
Copy patheslint.config.js
File metadata and controls
169 lines (160 loc) · 4.89 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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import { config } from '@douglasneuroinformatics/eslint-config';
// Restricted imports and syntax are declared as constants because flat config *replaces* a rule's
// options when a later block matches the same file rather than merging them. Any narrower block
// must therefore restate everything a broader block set for that rule.
const NO_BARE_ZOD = {
message:
"Import from 'zod/v4'. Bare 'zod' resolves to the v3 API, which is a separate schema registry — v3 and v4 schemas, error maps and issue formats do not interoperate.",
name: 'zod'
};
const NO_CLSX = {
message: "Use `cn` from '@douglasneuroinformatics/libui/utils', which also merges conflicting Tailwind classes.",
name: 'clsx'
};
const NO_TAILWIND_MERGE = {
message: "Use `cn` from '@douglasneuroinformatics/libui/utils'.",
name: 'tailwind-merge'
};
const NO_TESTS_IN_ROUTES = {
group: ['vitest', '@testing-library/*'],
message:
'The TanStack route generator scans every file under src/routes and warns on any that does not export a Route. Put tests in src/hooks/__tests__/, src/utils/__tests__/ or src/__tests__/.'
};
const NO_AXIOS_INSTANCE = {
message:
'apps/web uses the default axios instance; the retry, offline and error-notification interceptors in src/services/axios.ts are installed on it. A separate instance silently bypasses all of them.',
selector: "CallExpression[callee.object.name='axios'][callee.property.name='create']"
};
const NO_PROCESS_ENV = {
message:
'Read configuration through ConfigService, typed by $Env in src/core/schemas/env.schema.ts, so an absent variable fails at startup rather than at first use.',
selector: "MemberExpression[object.name='process'][property.name='env']"
};
const REQUIRE_ROUTE_ACCESS = {
message:
'Every controller handler needs @RouteAccess. Without it JwtAuthGuard throws InternalServerErrorException at request time. Note that @RouteAccess([]) grants access to any authenticated user.',
selector:
'MethodDefinition:has(Decorator > CallExpression > Identifier.callee[name=/^(Delete|Get|Patch|Post|Put)$/]):not(:has(Decorator > CallExpression > Identifier.callee[name="RouteAccess"]))'
};
export default config(
{
astro: {
enabled: true
},
env: {
browser: true,
es2021: true,
node: true
},
react: {
enabled: true,
version: '18'
},
typescript: {
enabled: true
}
},
{
ignores: [
'apps/playground/src/instruments/examples/interactive/Interactive-With-Legacy-Script/legacy.js',
'runtime/v1/src/**/*.d.ts',
'vendor/**/*',
'knip.ts',
'vitest.config.ts'
]
},
{
files: ['**/*.tsx'],
rules: {
'@typescript-eslint/only-throw-error': 'off',
'jsx-a11y/media-has-caption': 'off'
}
},
{
files: ['packages/instrument-library/**/*'],
rules: {
'perfectionist/sort-objects': 'off'
}
},
{
rules: {
'no-restricted-imports': ['error', { paths: [NO_BARE_ZOD] }]
}
},
{
files: ['packages/schemas/src/**/*.ts'],
rules: {
'import/extensions': ['error', 'always', { ignorePackages: true }]
}
},
{
files: ['apps/api/src/**/*.ts'],
rules: {
'no-restricted-syntax': ['error', NO_PROCESS_ENV]
}
},
{
files: ['apps/api/src/**/*.controller.ts'],
rules: {
'no-restricted-syntax': ['error', NO_PROCESS_ENV, REQUIRE_ROUTE_ACCESS]
}
},
{
files: ['apps/web/src/**/*', 'packages/react-core/src/**/*'],
rules: {
'no-restricted-imports': ['error', { paths: [NO_BARE_ZOD, NO_CLSX, NO_TAILWIND_MERGE] }],
'no-restricted-syntax': ['error', NO_AXIOS_INSTANCE]
}
},
{
files: ['apps/web/src/routes/**/*'],
rules: {
'no-restricted-imports': [
'error',
{ paths: [NO_BARE_ZOD, NO_CLSX, NO_TAILWIND_MERGE], patterns: [NO_TESTS_IN_ROUTES] }
]
}
},
{
files: ['apps/web/src/components/**/*', 'packages/react-core/src/components/**/*'],
ignores: ['**/*.stories.tsx'],
rules: {
'import/no-default-export': 'error'
}
},
{
files: ['apps/web/src/**/*.tsx', 'packages/react-core/src/**/*.tsx'],
// Story fixtures are authored for developers and never reach a user.
ignores: ['**/*.stories.tsx'],
rules: {
'react/jsx-no-literals': [
'error',
{
// Punctuation and separators carry no meaning to translate, and proper nouns must survive
// translation unchanged.
allowedStrings: [
'%',
'©',
'(',
')',
'-',
'/',
':',
'Douglas Neuroinformatics',
'Douglas Neuroinformatics Platform',
'EN',
'FR',
'Open Data Capture',
'SSL/TLS',
'STARTTLS',
'×',
'·',
'—'
],
ignoreProps: true,
noStrings: true
}
]
}
}
);