@duro-app/eslint-config 2.0.0 → 3.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/README.md +28 -0
- package/package.json +2 -2
- package/src/index.js +23 -3
package/README.md
CHANGED
|
@@ -54,6 +54,34 @@ Severity is the one gating line: `error` gates at commit and CI, `warn`
|
|
|
54
54
|
informs everywhere. Don't add `--max-warnings=0` — promote a rule to
|
|
55
55
|
`error` here instead if it earns gating.
|
|
56
56
|
|
|
57
|
+
### Adopting 3.0 with existing debt
|
|
58
|
+
|
|
59
|
+
3.0 promotes `duro/no-raw-design-values` to `error` and adds
|
|
60
|
+
`duro/no-raw-breakpoint-query`. A repo that already carries raw values keeps
|
|
61
|
+
the gate for every **new** file and ratchets the old ones down with an
|
|
62
|
+
explicit file list — never a glob, never `--max-warnings`:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
// eslint.duro-baseline.js — delete a line when its file is migrated. Never add one.
|
|
66
|
+
export const RAW_VALUES_BASELINE = [
|
|
67
|
+
'app/routes/legacy-dashboard.tsx',
|
|
68
|
+
'app/components/OldChart/OldChart.tsx',
|
|
69
|
+
]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
// eslint.config.js — after the presets, so last-wins downgrades only these
|
|
74
|
+
import {RAW_VALUES_BASELINE} from './eslint.duro-baseline.js'
|
|
75
|
+
export default [
|
|
76
|
+
...react,
|
|
77
|
+
{files: RAW_VALUES_BASELINE, rules: {'duro/no-raw-design-values': 'warn'}},
|
|
78
|
+
]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Most findings carry a suggestion; the ESLint API can apply them in bulk
|
|
82
|
+
(`message.suggestions[0].fix`). What is left is the handful that need a
|
|
83
|
+
human choice — an off-palette color, an off-scale spacing.
|
|
84
|
+
|
|
57
85
|
## Escape hatches
|
|
58
86
|
|
|
59
87
|
Flat config is last-wins — scope an override after the preset:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@duro-app/eslint-config",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Shareable ESLint flat config for the Duro stack: base TS conventions, the design-system rules and UI-library policy for React apps, Effect server conventions, and accessibility-first test selectors.",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"eslint-config-prettier": "^10.1.8",
|
|
50
50
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
51
51
|
"typescript-eslint": "^8.56.0",
|
|
52
|
-
"@duro-app/eslint-plugin": "^
|
|
52
|
+
"@duro-app/eslint-plugin": "^3.0.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"eslint": "^9.20.0",
|
package/src/index.js
CHANGED
|
@@ -68,11 +68,19 @@ export const react = tseslint.config(
|
|
|
68
68
|
{
|
|
69
69
|
name: 'duro-config/react-policy',
|
|
70
70
|
rules: {
|
|
71
|
-
|
|
71
|
+
// The typescript-eslint version, not the core rule, for `allowTypeImports`.
|
|
72
|
+
// Banning a module by name also catches `import type {X} from 'lexical'`,
|
|
73
|
+
// and a type import erases at compile time: it reaches no runtime module,
|
|
74
|
+
// so it bypasses nothing these bans protect. kb-vision hit exactly that —
|
|
75
|
+
// it uses the wrapper correctly and needed one type the wrapper does not
|
|
76
|
+
// re-export — and had to carry a local override to say so.
|
|
77
|
+
'no-restricted-imports': 'off',
|
|
78
|
+
'@typescript-eslint/no-restricted-imports': [
|
|
72
79
|
'error',
|
|
73
80
|
{
|
|
74
81
|
patterns: [
|
|
75
82
|
{
|
|
83
|
+
allowTypeImports: true,
|
|
76
84
|
group: [
|
|
77
85
|
'react-aria',
|
|
78
86
|
'react-aria-components',
|
|
@@ -92,6 +100,7 @@ export const react = tseslint.config(
|
|
|
92
100
|
message: FOREIGN_UI_MESSAGE,
|
|
93
101
|
},
|
|
94
102
|
{
|
|
103
|
+
allowTypeImports: true,
|
|
95
104
|
group: ['lexical', '@lexical/*'],
|
|
96
105
|
message: LEXICAL_MESSAGE,
|
|
97
106
|
},
|
|
@@ -113,12 +122,23 @@ export const effect = tseslint.config(...base, {
|
|
|
113
122
|
plugins: {'@effect': effectPlugin},
|
|
114
123
|
rules: {
|
|
115
124
|
'@effect/no-import-from-barrel-package': 'warn',
|
|
116
|
-
|
|
125
|
+
// See the react preset: type imports erase, so they bypass nothing here.
|
|
126
|
+
// The OTel barrel ban exists because WebSdk's transitive imports crash a
|
|
127
|
+
// Node service *at module load* — which a type import never triggers.
|
|
128
|
+
'no-restricted-imports': 'off',
|
|
129
|
+
'@typescript-eslint/no-restricted-imports': [
|
|
117
130
|
'error',
|
|
118
131
|
{
|
|
119
|
-
paths: [
|
|
132
|
+
paths: [
|
|
133
|
+
{
|
|
134
|
+
allowTypeImports: true,
|
|
135
|
+
name: '@effect/opentelemetry',
|
|
136
|
+
message: OTEL_BARREL_MESSAGE,
|
|
137
|
+
},
|
|
138
|
+
],
|
|
120
139
|
patterns: [
|
|
121
140
|
{
|
|
141
|
+
allowTypeImports: true,
|
|
122
142
|
group: ['kysely', 'kysely-*', '@kysely/*'],
|
|
123
143
|
message: KYSELY_MESSAGE,
|
|
124
144
|
},
|