@miskamyasa/eslint-config 1.0.1 → 1.0.3
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 +67 -1
- package/dist/index.d.ts +48 -8
- package/dist/index.js +471 -49
- package/package.json +15 -7
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ Opinionated ESLint config for React + TypeScript projects.
|
|
|
4
4
|
|
|
5
5
|
## What's included
|
|
6
6
|
|
|
7
|
+
### JS/TS
|
|
8
|
+
|
|
7
9
|
- ESLint recommended rules
|
|
8
10
|
- TypeScript strict type checking (`typescript-eslint` recommended + strictTypeChecked + stylisticTypeChecked)
|
|
9
11
|
- React rules (`@eslint-react/eslint-plugin` recommended-typescript + `react-hooks`)
|
|
@@ -11,6 +13,21 @@ Opinionated ESLint config for React + TypeScript projects.
|
|
|
11
13
|
- Stylistic formatting (`@stylistic/eslint-plugin` with double quotes, no semicolons, 2-space indent, stroustrup brace style)
|
|
12
14
|
- CommonJS overrides for `.js`/`.cjs` files
|
|
13
15
|
|
|
16
|
+
### Data files (enabled by default)
|
|
17
|
+
|
|
18
|
+
- JSON/JSONC/JSON5 linting (`eslint-plugin-jsonc`)
|
|
19
|
+
- YAML linting (`eslint-plugin-yml`)
|
|
20
|
+
- TOML linting (`eslint-plugin-toml`)
|
|
21
|
+
- Markdown linting (`@eslint/markdown` with GFM support)
|
|
22
|
+
|
|
23
|
+
### Formatters (opt-in)
|
|
24
|
+
|
|
25
|
+
- CSS/SCSS/Less formatting via Prettier
|
|
26
|
+
- HTML formatting via Prettier
|
|
27
|
+
- Markdown formatting via Prettier
|
|
28
|
+
- GraphQL formatting via Prettier
|
|
29
|
+
- XML/SVG formatting via Prettier (requires `@prettier/plugin-xml`)
|
|
30
|
+
|
|
14
31
|
## Requirements
|
|
15
32
|
|
|
16
33
|
- Node.js >= 22
|
|
@@ -43,6 +60,44 @@ export default createConfig({
|
|
|
43
60
|
|---|---|---|---|
|
|
44
61
|
| `tsconfigRootDir` | `string` | `process.cwd()` | Root directory for TypeScript project service |
|
|
45
62
|
| `ignores` | `string[]` | `[]` | Additional glob patterns to ignore |
|
|
63
|
+
| `jsonc` | `boolean` | `true` | Enable JSON/JSONC/JSON5 linting |
|
|
64
|
+
| `yaml` | `boolean` | `true` | Enable YAML linting |
|
|
65
|
+
| `toml` | `boolean` | `true` | Enable TOML linting |
|
|
66
|
+
| `markdown` | `boolean` | `true` | Enable Markdown linting |
|
|
67
|
+
| `formatters` | `boolean \| OptionsFormatters` | `false` | Enable Prettier formatting for CSS, HTML, etc. |
|
|
68
|
+
|
|
69
|
+
### Formatters options
|
|
70
|
+
|
|
71
|
+
When `formatters` is set to `true`, CSS, HTML, Markdown, and GraphQL formatting are enabled. XML/SVG are disabled by default because they require `@prettier/plugin-xml` to be installed separately.
|
|
72
|
+
|
|
73
|
+
For fine-grained control, pass an `OptionsFormatters` object:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
export default createConfig({
|
|
77
|
+
tsconfigRootDir: import.meta.dirname,
|
|
78
|
+
formatters: {
|
|
79
|
+
css: true,
|
|
80
|
+
html: true,
|
|
81
|
+
markdown: true,
|
|
82
|
+
graphql: true,
|
|
83
|
+
xml: true, // requires: pnpm add -D @prettier/plugin-xml
|
|
84
|
+
svg: true, // requires: pnpm add -D @prettier/plugin-xml
|
|
85
|
+
prettierOptions: {
|
|
86
|
+
// override default Prettier options
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Disabling configs
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
export default createConfig({
|
|
96
|
+
tsconfigRootDir: import.meta.dirname,
|
|
97
|
+
yaml: false,
|
|
98
|
+
toml: false,
|
|
99
|
+
})
|
|
100
|
+
```
|
|
46
101
|
|
|
47
102
|
## Overrides
|
|
48
103
|
|
|
@@ -66,7 +121,18 @@ export default createConfig(
|
|
|
66
121
|
Individual config functions are available for advanced composition:
|
|
67
122
|
|
|
68
123
|
```ts
|
|
69
|
-
import {
|
|
124
|
+
import {
|
|
125
|
+
typescript,
|
|
126
|
+
stylistic,
|
|
127
|
+
imports,
|
|
128
|
+
react,
|
|
129
|
+
javascript,
|
|
130
|
+
jsonc,
|
|
131
|
+
yaml,
|
|
132
|
+
toml,
|
|
133
|
+
markdown,
|
|
134
|
+
formatters,
|
|
135
|
+
} from "@miskamyasa/eslint-config"
|
|
70
136
|
```
|
|
71
137
|
|
|
72
138
|
## Key style decisions
|
package/dist/index.d.ts
CHANGED
|
@@ -1,22 +1,47 @@
|
|
|
1
1
|
import { Linter } from 'eslint';
|
|
2
|
+
export { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript';
|
|
3
|
+
|
|
4
|
+
type ConfigItem = Linter.Config;
|
|
5
|
+
type OptionsFormatters = {
|
|
6
|
+
css?: boolean;
|
|
7
|
+
html?: boolean;
|
|
8
|
+
xml?: boolean;
|
|
9
|
+
svg?: boolean;
|
|
10
|
+
markdown?: boolean;
|
|
11
|
+
graphql?: boolean;
|
|
12
|
+
prettierOptions?: Record<string, unknown>;
|
|
13
|
+
};
|
|
14
|
+
type OptionsConfig = {
|
|
15
|
+
tsconfigRootDir?: string;
|
|
16
|
+
ignores?: string[];
|
|
17
|
+
yaml?: boolean;
|
|
18
|
+
toml?: boolean;
|
|
19
|
+
jsonc?: boolean;
|
|
20
|
+
markdown?: boolean;
|
|
21
|
+
formatters?: boolean | OptionsFormatters;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
declare function formatters(options?: OptionsFormatters | true): Linter.Config[];
|
|
2
25
|
|
|
3
26
|
declare function createImportsConfig(): Linter.Config[];
|
|
4
27
|
|
|
5
28
|
declare function javascript(): Linter.Config[];
|
|
6
29
|
|
|
30
|
+
declare function jsonc(): Linter.Config[];
|
|
31
|
+
|
|
32
|
+
declare function markdown(): Linter.Config[];
|
|
33
|
+
|
|
7
34
|
declare function react(): Linter.Config[];
|
|
8
35
|
|
|
9
36
|
declare function stylistic(): Linter.Config[];
|
|
10
37
|
|
|
38
|
+
declare function toml(): Linter.Config[];
|
|
39
|
+
|
|
11
40
|
declare function typescript(options: {
|
|
12
41
|
tsconfigRootDir: string;
|
|
13
42
|
}): Linter.Config[];
|
|
14
43
|
|
|
15
|
-
|
|
16
|
-
type OptionsConfig = {
|
|
17
|
-
tsconfigRootDir?: string;
|
|
18
|
-
ignores?: string[];
|
|
19
|
-
};
|
|
44
|
+
declare function yaml(): Linter.Config[];
|
|
20
45
|
|
|
21
46
|
/**
|
|
22
47
|
* Construct an array of ESLint flat config items.
|
|
@@ -37,11 +62,26 @@ type OptionsConfig = {
|
|
|
37
62
|
*/
|
|
38
63
|
declare function createConfig(options?: OptionsConfig, ...userConfigs: Linter.Config[]): Linter.Config[];
|
|
39
64
|
|
|
40
|
-
declare const GLOB_JS = "
|
|
65
|
+
declare const GLOB_JS = "**/*.?([cm])js";
|
|
66
|
+
declare const GLOB_JSX = "**/*.jsx";
|
|
41
67
|
declare const GLOB_CJS = "**/*.cjs";
|
|
42
|
-
declare const GLOB_TS = "
|
|
68
|
+
declare const GLOB_TS = "**/*.?([cm])ts";
|
|
43
69
|
declare const GLOB_TSX = "**/*.tsx";
|
|
44
70
|
declare const GLOB_SRC: string[];
|
|
71
|
+
declare const GLOB_YAML = "**/*.y?(a)ml";
|
|
72
|
+
declare const GLOB_TOML = "**/*.toml";
|
|
73
|
+
declare const GLOB_JSON = "**/*.json";
|
|
74
|
+
declare const GLOB_JSONC = "**/*.jsonc";
|
|
75
|
+
declare const GLOB_JSON5 = "**/*.json5";
|
|
76
|
+
declare const GLOB_MARKDOWN = "**/*.md";
|
|
77
|
+
declare const GLOB_CSS = "**/*.css";
|
|
78
|
+
declare const GLOB_POSTCSS = "**/*.{p,post}css";
|
|
79
|
+
declare const GLOB_SCSS = "**/*.scss";
|
|
80
|
+
declare const GLOB_LESS = "**/*.less";
|
|
81
|
+
declare const GLOB_HTML = "**/*.htm?(l)";
|
|
82
|
+
declare const GLOB_XML = "**/*.xml";
|
|
83
|
+
declare const GLOB_SVG = "**/*.svg";
|
|
84
|
+
declare const GLOB_GRAPHQL = "**/*.{g,graph}ql";
|
|
45
85
|
declare const GLOB_EXCLUDE: string[];
|
|
46
86
|
|
|
47
|
-
export { type ConfigItem, GLOB_CJS, GLOB_EXCLUDE, GLOB_JS, GLOB_SRC, GLOB_TS, GLOB_TSX, type OptionsConfig, createConfig, createConfig as default, createImportsConfig as imports, javascript, react, stylistic, typescript };
|
|
87
|
+
export { type ConfigItem, GLOB_CJS, GLOB_CSS, GLOB_EXCLUDE, GLOB_GRAPHQL, GLOB_HTML, GLOB_JS, GLOB_JSON, GLOB_JSON5, GLOB_JSONC, GLOB_JSX, GLOB_LESS, GLOB_MARKDOWN, GLOB_POSTCSS, GLOB_SCSS, GLOB_SRC, GLOB_SVG, GLOB_TOML, GLOB_TS, GLOB_TSX, GLOB_XML, GLOB_YAML, type OptionsConfig, type OptionsFormatters, createConfig, createConfig as default, formatters, createImportsConfig as imports, javascript, jsonc, markdown, react, stylistic, toml, typescript, yaml };
|
package/dist/index.js
CHANGED
|
@@ -1,30 +1,215 @@
|
|
|
1
|
+
// src/configs/formatters.ts
|
|
2
|
+
import formatPlugin from "eslint-plugin-format";
|
|
3
|
+
|
|
4
|
+
// src/globs.ts
|
|
5
|
+
var GLOB_JS = "**/*.?([cm])js";
|
|
6
|
+
var GLOB_JSX = "**/*.jsx";
|
|
7
|
+
var GLOB_CJS = "**/*.cjs";
|
|
8
|
+
var GLOB_TS = "**/*.?([cm])ts";
|
|
9
|
+
var GLOB_TSX = "**/*.tsx";
|
|
10
|
+
var GLOB_SRC = [
|
|
11
|
+
GLOB_JS,
|
|
12
|
+
GLOB_JSX,
|
|
13
|
+
GLOB_TS,
|
|
14
|
+
GLOB_TSX
|
|
15
|
+
];
|
|
16
|
+
var GLOB_YAML = "**/*.y?(a)ml";
|
|
17
|
+
var GLOB_TOML = "**/*.toml";
|
|
18
|
+
var GLOB_JSON = "**/*.json";
|
|
19
|
+
var GLOB_JSONC = "**/*.jsonc";
|
|
20
|
+
var GLOB_JSON5 = "**/*.json5";
|
|
21
|
+
var GLOB_MARKDOWN = "**/*.md";
|
|
22
|
+
var GLOB_CSS = "**/*.css";
|
|
23
|
+
var GLOB_POSTCSS = "**/*.{p,post}css";
|
|
24
|
+
var GLOB_SCSS = "**/*.scss";
|
|
25
|
+
var GLOB_LESS = "**/*.less";
|
|
26
|
+
var GLOB_HTML = "**/*.htm?(l)";
|
|
27
|
+
var GLOB_XML = "**/*.xml";
|
|
28
|
+
var GLOB_SVG = "**/*.svg";
|
|
29
|
+
var GLOB_GRAPHQL = "**/*.{g,graph}ql";
|
|
30
|
+
var GLOB_EXCLUDE = [
|
|
31
|
+
"**/node_modules",
|
|
32
|
+
"**/dist",
|
|
33
|
+
"**/package-lock.json",
|
|
34
|
+
"**/yarn.lock",
|
|
35
|
+
"**/pnpm-lock.yaml",
|
|
36
|
+
"**/bun.lockb"
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
// src/configs/formatters.ts
|
|
40
|
+
var parserPlain = {
|
|
41
|
+
meta: {
|
|
42
|
+
name: "parser-plain"
|
|
43
|
+
},
|
|
44
|
+
parseForESLint: (code) => ({
|
|
45
|
+
ast: {
|
|
46
|
+
body: [],
|
|
47
|
+
comments: [],
|
|
48
|
+
loc: { end: code.length, start: 0 },
|
|
49
|
+
range: [0, code.length],
|
|
50
|
+
tokens: [],
|
|
51
|
+
type: "Program"
|
|
52
|
+
},
|
|
53
|
+
scopeManager: null,
|
|
54
|
+
services: { isPlain: true },
|
|
55
|
+
visitorKeys: {
|
|
56
|
+
Program: []
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
};
|
|
60
|
+
var defaultPrettierOptions = {
|
|
61
|
+
endOfLine: "auto",
|
|
62
|
+
printWidth: 120,
|
|
63
|
+
semi: false,
|
|
64
|
+
singleQuote: false,
|
|
65
|
+
tabWidth: 2,
|
|
66
|
+
trailingComma: "all",
|
|
67
|
+
useTabs: false
|
|
68
|
+
};
|
|
69
|
+
function formatters(options = {}) {
|
|
70
|
+
const resolvedOptions = options === true ? {
|
|
71
|
+
css: true,
|
|
72
|
+
graphql: true,
|
|
73
|
+
html: true,
|
|
74
|
+
markdown: true,
|
|
75
|
+
// XML/SVG require @prettier/plugin-xml to be installed separately
|
|
76
|
+
svg: false,
|
|
77
|
+
xml: false
|
|
78
|
+
} : options;
|
|
79
|
+
const prettierOptions = {
|
|
80
|
+
...defaultPrettierOptions,
|
|
81
|
+
...resolvedOptions.prettierOptions ?? {}
|
|
82
|
+
};
|
|
83
|
+
const configs2 = [
|
|
84
|
+
{
|
|
85
|
+
name: "miskamyasa/formatters/setup",
|
|
86
|
+
plugins: {
|
|
87
|
+
format: formatPlugin
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
];
|
|
91
|
+
if (resolvedOptions.css) {
|
|
92
|
+
configs2.push(
|
|
93
|
+
{
|
|
94
|
+
name: "miskamyasa/formatters/css",
|
|
95
|
+
files: [GLOB_CSS, GLOB_POSTCSS],
|
|
96
|
+
languageOptions: { parser: parserPlain },
|
|
97
|
+
rules: {
|
|
98
|
+
"format/prettier": ["error", { ...prettierOptions, parser: "css" }]
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "miskamyasa/formatters/scss",
|
|
103
|
+
files: [GLOB_SCSS],
|
|
104
|
+
languageOptions: { parser: parserPlain },
|
|
105
|
+
rules: {
|
|
106
|
+
"format/prettier": ["error", { ...prettierOptions, parser: "scss" }]
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: "miskamyasa/formatters/less",
|
|
111
|
+
files: [GLOB_LESS],
|
|
112
|
+
languageOptions: { parser: parserPlain },
|
|
113
|
+
rules: {
|
|
114
|
+
"format/prettier": ["error", { ...prettierOptions, parser: "less" }]
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
if (resolvedOptions.html) {
|
|
120
|
+
configs2.push({
|
|
121
|
+
name: "miskamyasa/formatters/html",
|
|
122
|
+
files: [GLOB_HTML],
|
|
123
|
+
languageOptions: { parser: parserPlain },
|
|
124
|
+
rules: {
|
|
125
|
+
"format/prettier": ["error", { ...prettierOptions, parser: "html" }]
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
if (resolvedOptions.xml) {
|
|
130
|
+
configs2.push({
|
|
131
|
+
name: "miskamyasa/formatters/xml",
|
|
132
|
+
files: [GLOB_XML],
|
|
133
|
+
languageOptions: { parser: parserPlain },
|
|
134
|
+
rules: {
|
|
135
|
+
"format/prettier": ["error", { ...prettierOptions, parser: "xml", plugins: ["@prettier/plugin-xml"] }]
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
if (resolvedOptions.svg) {
|
|
140
|
+
configs2.push({
|
|
141
|
+
name: "miskamyasa/formatters/svg",
|
|
142
|
+
files: [GLOB_SVG],
|
|
143
|
+
languageOptions: { parser: parserPlain },
|
|
144
|
+
rules: {
|
|
145
|
+
"format/prettier": ["error", { ...prettierOptions, parser: "xml", plugins: ["@prettier/plugin-xml"] }]
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
if (resolvedOptions.markdown) {
|
|
150
|
+
configs2.push({
|
|
151
|
+
name: "miskamyasa/formatters/markdown",
|
|
152
|
+
files: [GLOB_MARKDOWN],
|
|
153
|
+
languageOptions: { parser: parserPlain },
|
|
154
|
+
rules: {
|
|
155
|
+
"format/prettier": ["error", { ...prettierOptions, embeddedLanguageFormatting: "off", parser: "markdown" }]
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (resolvedOptions.graphql) {
|
|
160
|
+
configs2.push({
|
|
161
|
+
name: "miskamyasa/formatters/graphql",
|
|
162
|
+
files: [GLOB_GRAPHQL],
|
|
163
|
+
languageOptions: { parser: parserPlain },
|
|
164
|
+
rules: {
|
|
165
|
+
"format/prettier": ["error", { ...prettierOptions, parser: "graphql" }]
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return configs2;
|
|
170
|
+
}
|
|
171
|
+
|
|
1
172
|
// src/configs/imports.ts
|
|
2
173
|
import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";
|
|
3
|
-
import { flatConfigs as
|
|
174
|
+
import { flatConfigs as importConfigs } from "eslint-plugin-import-x";
|
|
4
175
|
import unusedImports from "eslint-plugin-unused-imports";
|
|
5
176
|
function createImportsConfig() {
|
|
6
177
|
return [
|
|
178
|
+
// Plugin setup (global - registers import-x and unused-imports plugins)
|
|
179
|
+
{
|
|
180
|
+
name: "miskamyasa/imports/setup",
|
|
181
|
+
plugins: {
|
|
182
|
+
...importConfigs.recommended.plugins,
|
|
183
|
+
"unused-imports": unusedImports
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
// Recommended rules - scoped to source files
|
|
7
187
|
{
|
|
8
|
-
|
|
9
|
-
|
|
188
|
+
name: "miskamyasa/imports/recommended-rules",
|
|
189
|
+
files: GLOB_SRC,
|
|
190
|
+
rules: importConfigs.recommended.rules
|
|
10
191
|
},
|
|
192
|
+
// React settings - scoped to source files
|
|
11
193
|
{
|
|
12
|
-
|
|
13
|
-
|
|
194
|
+
name: "miskamyasa/imports/react",
|
|
195
|
+
files: GLOB_SRC,
|
|
196
|
+
settings: importConfigs.react.settings,
|
|
197
|
+
languageOptions: importConfigs.react.languageOptions
|
|
14
198
|
},
|
|
199
|
+
// TypeScript resolver
|
|
15
200
|
{
|
|
16
201
|
name: "miskamyasa/imports/typescript",
|
|
202
|
+
files: GLOB_SRC,
|
|
17
203
|
settings: {
|
|
18
204
|
"import-x/resolver-next": [
|
|
19
205
|
createTypeScriptImportResolver()
|
|
20
206
|
]
|
|
21
207
|
}
|
|
22
208
|
},
|
|
209
|
+
// Custom rules - scoped to source files
|
|
23
210
|
{
|
|
24
211
|
name: "miskamyasa/imports/rules",
|
|
25
|
-
|
|
26
|
-
"unused-imports": unusedImports
|
|
27
|
-
},
|
|
212
|
+
files: GLOB_SRC,
|
|
28
213
|
rules: {
|
|
29
214
|
"import-x/namespace": "off",
|
|
30
215
|
"import-x/newline-after-import": [
|
|
@@ -61,32 +246,12 @@ function createImportsConfig() {
|
|
|
61
246
|
];
|
|
62
247
|
}
|
|
63
248
|
|
|
64
|
-
// src/globs.ts
|
|
65
|
-
var GLOB_JS = "**/*.js";
|
|
66
|
-
var GLOB_CJS = "**/*.cjs";
|
|
67
|
-
var GLOB_TS = "**/*.ts";
|
|
68
|
-
var GLOB_TSX = "**/*.tsx";
|
|
69
|
-
var GLOB_SRC = [
|
|
70
|
-
GLOB_JS,
|
|
71
|
-
GLOB_CJS,
|
|
72
|
-
GLOB_TS,
|
|
73
|
-
GLOB_TSX
|
|
74
|
-
];
|
|
75
|
-
var GLOB_EXCLUDE = [
|
|
76
|
-
"**/node_modules",
|
|
77
|
-
"**/dist",
|
|
78
|
-
"**/package-lock.json",
|
|
79
|
-
"**/yarn.lock",
|
|
80
|
-
"**/pnpm-lock.yaml",
|
|
81
|
-
"**/bun.lockb"
|
|
82
|
-
];
|
|
83
|
-
|
|
84
249
|
// src/configs/javascript.ts
|
|
85
250
|
function javascript() {
|
|
86
251
|
return [
|
|
87
252
|
{
|
|
88
253
|
name: "miskamyasa/javascript/overrides",
|
|
89
|
-
files: [
|
|
254
|
+
files: ["**/*.js", GLOB_CJS],
|
|
90
255
|
languageOptions: {
|
|
91
256
|
globals: {
|
|
92
257
|
require: "readonly",
|
|
@@ -103,20 +268,113 @@ function javascript() {
|
|
|
103
268
|
];
|
|
104
269
|
}
|
|
105
270
|
|
|
271
|
+
// src/configs/jsonc.ts
|
|
272
|
+
import jsoncPlugin from "eslint-plugin-jsonc";
|
|
273
|
+
import * as jsoncParser from "jsonc-eslint-parser";
|
|
274
|
+
var JSON_FILES = [GLOB_JSON, GLOB_JSONC, GLOB_JSON5];
|
|
275
|
+
function jsonc() {
|
|
276
|
+
const preset = jsoncPlugin.configs["flat/recommended-with-jsonc"];
|
|
277
|
+
return [
|
|
278
|
+
// Plugin setup (global - registers the jsonc plugin)
|
|
279
|
+
{
|
|
280
|
+
name: "miskamyasa/jsonc/setup",
|
|
281
|
+
plugins: preset[0].plugins
|
|
282
|
+
},
|
|
283
|
+
// Parser and basic overrides from preset (already scoped to JSON files)
|
|
284
|
+
{
|
|
285
|
+
...preset[1],
|
|
286
|
+
name: "miskamyasa/jsonc/parser-overrides"
|
|
287
|
+
},
|
|
288
|
+
// Recommended rules - scoped to JSON files
|
|
289
|
+
{
|
|
290
|
+
name: "miskamyasa/jsonc/recommended-rules",
|
|
291
|
+
files: JSON_FILES,
|
|
292
|
+
rules: preset[2].rules
|
|
293
|
+
},
|
|
294
|
+
// Stylistic rules
|
|
295
|
+
{
|
|
296
|
+
name: "miskamyasa/jsonc/stylistic-rules",
|
|
297
|
+
files: JSON_FILES,
|
|
298
|
+
languageOptions: {
|
|
299
|
+
parser: jsoncParser
|
|
300
|
+
},
|
|
301
|
+
rules: {
|
|
302
|
+
"jsonc/indent": ["error", 2],
|
|
303
|
+
"jsonc/key-spacing": "error",
|
|
304
|
+
"jsonc/array-bracket-spacing": ["error", "never"],
|
|
305
|
+
"jsonc/sort-keys": "off"
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
// JSON-specific rules (strict JSON doesn't allow trailing commas)
|
|
309
|
+
{
|
|
310
|
+
name: "miskamyasa/jsonc/json-rules",
|
|
311
|
+
files: [GLOB_JSON],
|
|
312
|
+
languageOptions: {
|
|
313
|
+
parser: jsoncParser
|
|
314
|
+
},
|
|
315
|
+
rules: {
|
|
316
|
+
"jsonc/comma-dangle": ["error", "never"]
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
];
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// src/configs/markdown.ts
|
|
323
|
+
import markdownPlugin from "@eslint/markdown";
|
|
324
|
+
function markdown() {
|
|
325
|
+
return [
|
|
326
|
+
{
|
|
327
|
+
name: "miskamyasa/markdown/setup",
|
|
328
|
+
plugins: {
|
|
329
|
+
markdown: markdownPlugin
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
name: "miskamyasa/markdown/parser",
|
|
334
|
+
files: [GLOB_MARKDOWN],
|
|
335
|
+
language: "markdown/gfm"
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
name: "miskamyasa/markdown/rules",
|
|
339
|
+
files: [GLOB_MARKDOWN],
|
|
340
|
+
rules: {
|
|
341
|
+
"markdown/fenced-code-language": "warn",
|
|
342
|
+
"markdown/heading-increment": "error",
|
|
343
|
+
"markdown/no-duplicate-headings": "off",
|
|
344
|
+
"markdown/no-empty-links": "error",
|
|
345
|
+
"markdown/no-html": "off",
|
|
346
|
+
"markdown/no-invalid-label-refs": "off",
|
|
347
|
+
"markdown/no-missing-label-refs": "off"
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
];
|
|
351
|
+
}
|
|
352
|
+
|
|
106
353
|
// src/configs/react.ts
|
|
107
354
|
import reactPlugin from "@eslint-react/eslint-plugin";
|
|
108
355
|
import reactHooksPlugin from "eslint-plugin-react-hooks";
|
|
109
356
|
function react() {
|
|
357
|
+
const preset = reactPlugin.configs["recommended-typescript"];
|
|
110
358
|
return [
|
|
359
|
+
// Plugin setup (global - registers all react plugins)
|
|
111
360
|
{
|
|
112
|
-
|
|
113
|
-
name: "miskamyasa/react/recommended-typescript"
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
name: "miskamyasa/react/rules",
|
|
361
|
+
name: "miskamyasa/react/setup",
|
|
117
362
|
plugins: {
|
|
363
|
+
...preset.plugins,
|
|
118
364
|
"react-hooks": reactHooksPlugin
|
|
119
365
|
},
|
|
366
|
+
settings: preset.settings
|
|
367
|
+
},
|
|
368
|
+
// React rules - scoped to source files only
|
|
369
|
+
{
|
|
370
|
+
name: "miskamyasa/react/rules",
|
|
371
|
+
files: GLOB_SRC,
|
|
372
|
+
rules: preset.rules
|
|
373
|
+
},
|
|
374
|
+
// React hooks rules - scoped to source files only
|
|
375
|
+
{
|
|
376
|
+
name: "miskamyasa/react/hooks-rules",
|
|
377
|
+
files: GLOB_SRC,
|
|
120
378
|
rules: {
|
|
121
379
|
"react-hooks/rules-of-hooks": "error",
|
|
122
380
|
"react-hooks/exhaustive-deps": "error"
|
|
@@ -128,17 +386,24 @@ function react() {
|
|
|
128
386
|
// src/configs/stylistic.ts
|
|
129
387
|
import stylisticPlugin from "@stylistic/eslint-plugin";
|
|
130
388
|
function stylistic() {
|
|
131
|
-
const stylistic2 = stylisticPlugin;
|
|
132
389
|
return [
|
|
390
|
+
// Plugin setup (global - registers the @stylistic plugin)
|
|
391
|
+
{
|
|
392
|
+
name: "miskamyasa/stylistic/setup",
|
|
393
|
+
plugins: {
|
|
394
|
+
"@stylistic": stylisticPlugin
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
// Disable legacy ESLint formatting rules - scoped to source files
|
|
133
398
|
{
|
|
134
|
-
|
|
135
|
-
|
|
399
|
+
name: "miskamyasa/stylistic/disable-legacy",
|
|
400
|
+
files: GLOB_SRC,
|
|
401
|
+
rules: stylisticPlugin.configs["disable-legacy"].rules
|
|
136
402
|
},
|
|
403
|
+
// Stylistic rules - scoped to source files
|
|
137
404
|
{
|
|
138
405
|
name: "miskamyasa/stylistic/rules",
|
|
139
|
-
|
|
140
|
-
"@stylistic": stylistic2
|
|
141
|
-
},
|
|
406
|
+
files: GLOB_SRC,
|
|
142
407
|
rules: {
|
|
143
408
|
"@stylistic/block-spacing": ["error", "never"],
|
|
144
409
|
"@stylistic/comma-dangle": ["error", "always-multiline"],
|
|
@@ -296,15 +561,89 @@ function stylistic() {
|
|
|
296
561
|
];
|
|
297
562
|
}
|
|
298
563
|
|
|
564
|
+
// src/configs/toml.ts
|
|
565
|
+
import tomlPlugin from "eslint-plugin-toml";
|
|
566
|
+
import * as tomlParser from "toml-eslint-parser";
|
|
567
|
+
function toml() {
|
|
568
|
+
return [
|
|
569
|
+
{
|
|
570
|
+
name: "miskamyasa/toml/setup",
|
|
571
|
+
plugins: {
|
|
572
|
+
toml: tomlPlugin
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
name: "miskamyasa/toml/rules",
|
|
577
|
+
files: [GLOB_TOML],
|
|
578
|
+
languageOptions: {
|
|
579
|
+
parser: tomlParser
|
|
580
|
+
},
|
|
581
|
+
rules: {
|
|
582
|
+
"toml/comma-style": "error",
|
|
583
|
+
"toml/keys-order": "error",
|
|
584
|
+
"toml/no-space-dots": "error",
|
|
585
|
+
"toml/no-unreadable-number-separator": "error",
|
|
586
|
+
"toml/precision-of-fractional-seconds": "error",
|
|
587
|
+
"toml/precision-of-integer": "error",
|
|
588
|
+
"toml/tables-order": "error",
|
|
589
|
+
"toml/array-bracket-newline": "error",
|
|
590
|
+
"toml/array-bracket-spacing": "error",
|
|
591
|
+
"toml/array-element-newline": "error",
|
|
592
|
+
"toml/indent": ["error", 2],
|
|
593
|
+
"toml/inline-table-curly-spacing": "error",
|
|
594
|
+
"toml/key-spacing": "error",
|
|
595
|
+
"toml/padding-line-between-pairs": "error",
|
|
596
|
+
"toml/padding-line-between-tables": "error",
|
|
597
|
+
"toml/quoted-keys": "error",
|
|
598
|
+
"toml/spaced-comment": "error",
|
|
599
|
+
"toml/table-bracket-spacing": "error"
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
];
|
|
603
|
+
}
|
|
604
|
+
|
|
299
605
|
// src/configs/typescript.ts
|
|
300
|
-
import { configs } from "typescript-eslint";
|
|
606
|
+
import { configs, parser } from "typescript-eslint";
|
|
301
607
|
function typescript(options) {
|
|
608
|
+
const recommended = configs.recommended;
|
|
609
|
+
const strictTypeChecked = configs.strictTypeChecked;
|
|
610
|
+
const stylisticTypeChecked = configs.stylisticTypeChecked;
|
|
302
611
|
return [
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
612
|
+
// Plugin + parser setup (shared across all presets, only need it once)
|
|
613
|
+
{
|
|
614
|
+
name: "miskamyasa/typescript/setup",
|
|
615
|
+
plugins: recommended[0].plugins,
|
|
616
|
+
languageOptions: {
|
|
617
|
+
parser
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
// ESLint-recommended overrides for TS files (already scoped by preset)
|
|
621
|
+
{
|
|
622
|
+
...recommended[1],
|
|
623
|
+
name: "miskamyasa/typescript/eslint-recommended"
|
|
624
|
+
},
|
|
625
|
+
// Recommended rules - scoped to source files
|
|
626
|
+
{
|
|
627
|
+
name: "miskamyasa/typescript/recommended-rules",
|
|
628
|
+
files: GLOB_SRC,
|
|
629
|
+
rules: recommended[2].rules
|
|
630
|
+
},
|
|
631
|
+
// Strict type-checked rules - scoped to source files
|
|
632
|
+
{
|
|
633
|
+
name: "miskamyasa/typescript/strict-type-checked-rules",
|
|
634
|
+
files: GLOB_SRC,
|
|
635
|
+
rules: strictTypeChecked[2].rules
|
|
636
|
+
},
|
|
637
|
+
// Stylistic type-checked rules - scoped to source files
|
|
638
|
+
{
|
|
639
|
+
name: "miskamyasa/typescript/stylistic-type-checked-rules",
|
|
640
|
+
files: GLOB_SRC,
|
|
641
|
+
rules: stylisticTypeChecked[2].rules
|
|
642
|
+
},
|
|
643
|
+
// Parser options with type information
|
|
306
644
|
{
|
|
307
645
|
name: "miskamyasa/typescript/language-options",
|
|
646
|
+
files: GLOB_SRC,
|
|
308
647
|
languageOptions: {
|
|
309
648
|
parserOptions: {
|
|
310
649
|
projectService: true,
|
|
@@ -312,8 +651,10 @@ function typescript(options) {
|
|
|
312
651
|
}
|
|
313
652
|
}
|
|
314
653
|
},
|
|
654
|
+
// Project-specific rule overrides
|
|
315
655
|
{
|
|
316
656
|
name: "miskamyasa/typescript/rules",
|
|
657
|
+
files: GLOB_SRC,
|
|
317
658
|
rules: {
|
|
318
659
|
"@typescript-eslint/consistent-type-definitions": ["error", "type"],
|
|
319
660
|
"@typescript-eslint/no-unused-vars": "off",
|
|
@@ -336,12 +677,57 @@ function typescript(options) {
|
|
|
336
677
|
];
|
|
337
678
|
}
|
|
338
679
|
|
|
680
|
+
// src/configs/yaml.ts
|
|
681
|
+
import yamlPlugin from "eslint-plugin-yml";
|
|
682
|
+
import * as yamlParser from "yaml-eslint-parser";
|
|
683
|
+
function yaml() {
|
|
684
|
+
return [
|
|
685
|
+
{
|
|
686
|
+
name: "miskamyasa/yaml/setup",
|
|
687
|
+
plugins: {
|
|
688
|
+
yaml: yamlPlugin
|
|
689
|
+
}
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
name: "miskamyasa/yaml/rules",
|
|
693
|
+
files: [GLOB_YAML],
|
|
694
|
+
languageOptions: {
|
|
695
|
+
parser: yamlParser
|
|
696
|
+
},
|
|
697
|
+
rules: {
|
|
698
|
+
"yaml/block-mapping": "error",
|
|
699
|
+
"yaml/block-sequence": "error",
|
|
700
|
+
"yaml/no-empty-key": "error",
|
|
701
|
+
"yaml/no-empty-sequence-entry": "error",
|
|
702
|
+
"yaml/no-irregular-whitespace": "error",
|
|
703
|
+
"yaml/plain-scalar": "error",
|
|
704
|
+
"yaml/block-mapping-question-indicator-newline": "error",
|
|
705
|
+
"yaml/block-sequence-hyphen-indicator-newline": "error",
|
|
706
|
+
"yaml/flow-mapping-curly-newline": "error",
|
|
707
|
+
"yaml/flow-mapping-curly-spacing": "error",
|
|
708
|
+
"yaml/flow-sequence-bracket-newline": "error",
|
|
709
|
+
"yaml/flow-sequence-bracket-spacing": "error",
|
|
710
|
+
"yaml/indent": ["error", 2],
|
|
711
|
+
"yaml/key-spacing": "error",
|
|
712
|
+
"yaml/no-tab-indent": "error",
|
|
713
|
+
"yaml/quotes": ["error", { "avoidEscape": true, "prefer": "double" }],
|
|
714
|
+
"yaml/spaced-comment": "error"
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
];
|
|
718
|
+
}
|
|
719
|
+
|
|
339
720
|
// src/factory.ts
|
|
340
721
|
import eslint from "@eslint/js";
|
|
341
722
|
function createConfig(options = {}, ...userConfigs) {
|
|
342
723
|
const {
|
|
343
724
|
tsconfigRootDir = process.cwd(),
|
|
344
|
-
ignores = []
|
|
725
|
+
ignores = [],
|
|
726
|
+
jsonc: enableJsonc = true,
|
|
727
|
+
yaml: enableYaml = true,
|
|
728
|
+
toml: enableToml = true,
|
|
729
|
+
markdown: enableMarkdown = true,
|
|
730
|
+
formatters: enableFormatters = false
|
|
345
731
|
} = options;
|
|
346
732
|
return [
|
|
347
733
|
// Global ignores
|
|
@@ -352,10 +738,12 @@ function createConfig(options = {}, ...userConfigs) {
|
|
|
352
738
|
...ignores
|
|
353
739
|
]
|
|
354
740
|
},
|
|
355
|
-
// ESLint recommended
|
|
741
|
+
// ESLint recommended rules (scoped to source files -
|
|
742
|
+
// core rules use JS-specific sourceCode APIs incompatible with other languages)
|
|
356
743
|
{
|
|
357
|
-
|
|
358
|
-
|
|
744
|
+
name: "miskamyasa/eslint/recommended",
|
|
745
|
+
files: GLOB_SRC,
|
|
746
|
+
rules: eslint.configs.recommended.rules
|
|
359
747
|
},
|
|
360
748
|
// TypeScript
|
|
361
749
|
...typescript({ tsconfigRootDir }),
|
|
@@ -365,24 +753,58 @@ function createConfig(options = {}, ...userConfigs) {
|
|
|
365
753
|
...react(),
|
|
366
754
|
// Stylistic
|
|
367
755
|
...stylistic(),
|
|
756
|
+
// JSONC/JSON
|
|
757
|
+
...enableJsonc ? jsonc() : [],
|
|
758
|
+
// YAML
|
|
759
|
+
...enableYaml ? yaml() : [],
|
|
760
|
+
// TOML
|
|
761
|
+
...enableToml ? toml() : [],
|
|
762
|
+
// Markdown
|
|
763
|
+
...enableMarkdown ? markdown() : [],
|
|
764
|
+
// Formatters (Prettier via ESLint for CSS, HTML, XML, etc.)
|
|
765
|
+
...enableFormatters ? formatters(enableFormatters) : [],
|
|
368
766
|
// JavaScript/CJS overrides (must come after TypeScript rules)
|
|
369
767
|
...javascript(),
|
|
370
768
|
// User configs (appended last for maximum override power)
|
|
371
769
|
...userConfigs
|
|
372
770
|
];
|
|
373
771
|
}
|
|
772
|
+
|
|
773
|
+
// src/index.ts
|
|
774
|
+
import { createTypeScriptImportResolver as createTypeScriptImportResolver2 } from "eslint-import-resolver-typescript";
|
|
374
775
|
export {
|
|
375
776
|
GLOB_CJS,
|
|
777
|
+
GLOB_CSS,
|
|
376
778
|
GLOB_EXCLUDE,
|
|
779
|
+
GLOB_GRAPHQL,
|
|
780
|
+
GLOB_HTML,
|
|
377
781
|
GLOB_JS,
|
|
782
|
+
GLOB_JSON,
|
|
783
|
+
GLOB_JSON5,
|
|
784
|
+
GLOB_JSONC,
|
|
785
|
+
GLOB_JSX,
|
|
786
|
+
GLOB_LESS,
|
|
787
|
+
GLOB_MARKDOWN,
|
|
788
|
+
GLOB_POSTCSS,
|
|
789
|
+
GLOB_SCSS,
|
|
378
790
|
GLOB_SRC,
|
|
791
|
+
GLOB_SVG,
|
|
792
|
+
GLOB_TOML,
|
|
379
793
|
GLOB_TS,
|
|
380
794
|
GLOB_TSX,
|
|
795
|
+
GLOB_XML,
|
|
796
|
+
GLOB_YAML,
|
|
381
797
|
createConfig,
|
|
798
|
+
createTypeScriptImportResolver2 as createTypeScriptImportResolver,
|
|
382
799
|
createConfig as default,
|
|
800
|
+
formatters,
|
|
383
801
|
createImportsConfig as imports,
|
|
384
802
|
javascript,
|
|
803
|
+
jsonc,
|
|
804
|
+
markdown,
|
|
385
805
|
react,
|
|
386
806
|
stylistic,
|
|
387
|
-
|
|
807
|
+
toml,
|
|
808
|
+
typescript,
|
|
809
|
+
yaml
|
|
388
810
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miskamyasa/eslint-config",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.3",
|
|
5
5
|
"description": "Opinionated ESLint config for React + TypeScript projects",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -24,26 +24,34 @@
|
|
|
24
24
|
"author": "Denis <MiskaMyasa> Zaitsev",
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"engines": {
|
|
27
|
-
"node": ">=
|
|
27
|
+
"node": ">=24.0.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@eslint-react/eslint-plugin": "2.13.0",
|
|
31
31
|
"@eslint/js": "10.0.1",
|
|
32
|
+
"@eslint/markdown": "7.5.1",
|
|
32
33
|
"@stylistic/eslint-plugin": "5.10.0",
|
|
33
34
|
"eslint-import-resolver-typescript": "4.4.4",
|
|
35
|
+
"eslint-plugin-format": "2.0.1",
|
|
34
36
|
"eslint-plugin-import-x": "4.16.2",
|
|
35
|
-
"eslint-plugin-
|
|
37
|
+
"eslint-plugin-jsonc": "3.1.2",
|
|
38
|
+
"eslint-plugin-react-hooks": "7.1.1",
|
|
39
|
+
"eslint-plugin-toml": "1.3.1",
|
|
36
40
|
"eslint-plugin-unused-imports": "4.4.1",
|
|
37
|
-
"
|
|
41
|
+
"eslint-plugin-yml": "3.3.2",
|
|
42
|
+
"jsonc-eslint-parser": "3.1.0",
|
|
43
|
+
"toml-eslint-parser": "1.0.3",
|
|
44
|
+
"typescript-eslint": "8.59.4",
|
|
45
|
+
"yaml-eslint-parser": "2.0.0"
|
|
38
46
|
},
|
|
39
47
|
"peerDependencies": {
|
|
40
48
|
"eslint": ">=9.0.0",
|
|
41
49
|
"typescript": ">=5.0.0"
|
|
42
50
|
},
|
|
43
51
|
"devDependencies": {
|
|
44
|
-
"@types/node": "
|
|
45
|
-
"eslint": "10.0
|
|
46
|
-
"jiti": "2.
|
|
52
|
+
"@types/node": "24.12.4",
|
|
53
|
+
"eslint": "10.4.0",
|
|
54
|
+
"jiti": "2.7.0",
|
|
47
55
|
"tsup": "8.5.1",
|
|
48
56
|
"typescript": "5.9.3"
|
|
49
57
|
},
|