Skip to content

Commit f5464cc

Browse files
authored
feat: add support for flat config (#301)
* feat: add support for flat config * fix * Create rare-coats-report.md * fix test
1 parent 81b901e commit f5464cc

File tree

14 files changed

+218
-9
lines changed

14 files changed

+218
-9
lines changed

.changeset/rare-coats-report.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-json-schema-validator": minor
3+
---
4+
5+
feat: add support for flat config

.eslintrc.js

+12
Original file line numberDiff line numberDiff line change
@@ -188,5 +188,17 @@ module.exports = {
188188
"eslint-plugin/require-meta-schema": "off",
189189
},
190190
},
191+
{
192+
files: ["*.mjs"],
193+
parserOptions: {
194+
sourceType: "module",
195+
},
196+
},
197+
{
198+
files: ["*.md/**", "**/*.md/**"],
199+
rules: {
200+
"n/no-missing-import": "off",
201+
},
202+
},
191203
],
192204
};

README.md

+29-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,35 @@ npm install --save-dev eslint eslint-plugin-jsonc eslint-plugin-json-schema-vali
4343

4444
### Configuration
4545

46-
Use `.eslintrc.*` file to configure rules. See also: [https://eslint.org/docs/user-guide/configuring](https://eslint.org/docs/user-guide/configuring).
46+
#### New (ESLint>=v9) Config (Flat Config)
47+
48+
Use `eslint.config.js` file to configure rules. See also: <https://eslint.org/docs/latest/use/configure/configuration-files-new>.
49+
50+
Example **eslint.config.js**:
51+
52+
```mjs
53+
import eslintPluginJsonSchemaValidator from 'eslint-plugin-json-schema-validator';
54+
export default [
55+
// add more generic rule sets here, such as:
56+
// js.configs.recommended,
57+
...eslintPluginJsonSchemaValidator.configs['flat/recommended'],
58+
{
59+
rules: {
60+
// override/add rules settings here, such as:
61+
// 'json-schema-validator/no-invalid': 'warn'
62+
}
63+
}
64+
];
65+
```
66+
67+
This plugin provides configs:
68+
69+
- `*.configs['flat/base']` ... Configuration to enable correct JSON, YAML and TOML parsing.
70+
- `*.configs['flat/recommended']` ... Above, plus rule to validate with JSON Schema.
71+
72+
#### Legacy Config (ESLint<v9)
73+
74+
Use `.eslintrc.*` file to configure rules. See also: <https://eslint.org/docs/latest/use/configure/>.
4775

4876
Example **.eslintrc.js**:
4977

docs/user-guide/README.md

+29-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,35 @@ npm install --save-dev eslint eslint-plugin-json-schema-validator
1818

1919
### Configuration
2020

21-
Use `.eslintrc.*` file to configure rules. See also: [https://eslint.org/docs/user-guide/configuring](https://eslint.org/docs/user-guide/configuring).
21+
#### New (ESLint>=v9) Config (Flat Config)
22+
23+
Use `eslint.config.js` file to configure rules. See also: <https://eslint.org/docs/latest/use/configure/configuration-files-new>.
24+
25+
Example **eslint.config.js**:
26+
27+
```mjs
28+
import eslintPluginJsonSchemaValidator from 'eslint-plugin-json-schema-validator';
29+
export default [
30+
// add more generic rule sets here, such as:
31+
// js.configs.recommended,
32+
...eslintPluginJsonSchemaValidator.configs['flat/recommended'],
33+
{
34+
rules: {
35+
// override/add rules settings here, such as:
36+
// 'json-schema-validator/no-invalid': 'warn'
37+
}
38+
}
39+
];
40+
```
41+
42+
This plugin provides configs:
43+
44+
- `*.configs['flat/base']` ... Configuration to enable correct JSON, YAML and TOML parsing.
45+
- `*.configs['flat/recommended']` ... Above, plus rule to validate with JSON Schema.
46+
47+
#### Legacy Config (ESLint<v9)
48+
49+
Use `.eslintrc.*` file to configure rules. See also: <https://eslint.org/docs/latest/use/configure/>.
2250

2351
Example **.eslintrc.js**:
2452

src/configs/flat/base.ts

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import type { ESLint } from "eslint";
2+
import * as jsoncParser from "jsonc-eslint-parser";
3+
import * as yamlParser from "yaml-eslint-parser";
4+
import * as tomlParser from "toml-eslint-parser";
5+
export default [
6+
{
7+
plugins: {
8+
// eslint-disable-next-line @typescript-eslint/naming-convention -- plugin name
9+
get "json-schema-validator"(): ESLint.Plugin {
10+
// eslint-disable-next-line @typescript-eslint/no-require-imports -- ignore
11+
return require("../../index");
12+
},
13+
},
14+
},
15+
{
16+
files: [
17+
"*.json",
18+
"**/*.json",
19+
"*.json5",
20+
"**/*.json5",
21+
"*.jsonc",
22+
"**/*.jsonc",
23+
],
24+
languageOptions: {
25+
parser: jsoncParser,
26+
},
27+
rules: {
28+
// ESLint core rules known to cause problems with JSON.
29+
strict: "off",
30+
"no-unused-expressions": "off",
31+
"no-unused-vars": "off",
32+
},
33+
},
34+
{
35+
files: ["*.yaml", "**/*.yaml", "*.yml", "**/*.yml"],
36+
languageOptions: {
37+
parser: yamlParser,
38+
},
39+
rules: {
40+
// ESLint core rules known to cause problems with YAML.
41+
"no-irregular-whitespace": "off",
42+
"no-unused-vars": "off",
43+
"spaced-comment": "off",
44+
},
45+
},
46+
{
47+
files: ["*.toml", "**/*.toml"],
48+
languageOptions: {
49+
parser: tomlParser,
50+
},
51+
rules: {
52+
// ESLint core rules known to cause problems with TOML.
53+
"no-irregular-whitespace": "off",
54+
"spaced-comment": "off",
55+
},
56+
},
57+
];

src/configs/flat/recommended.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import base from "./base";
2+
export default [
3+
...base,
4+
{
5+
rules: {
6+
// eslint-plugin-json-schema-validator rules
7+
"json-schema-validator/no-invalid": "warn",
8+
},
9+
},
10+
];

src/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@ import type { RuleModule } from "./types";
22
import { rules as ruleList } from "./utils/rules";
33
import base from "./configs/base";
44
import recommended from "./configs/recommended";
5+
import flatBase from "./configs/flat/base";
6+
import flatRecommended from "./configs/flat/recommended";
57
import * as meta from "./meta";
68

79
const configs = {
810
base,
911
recommended,
12+
"flat/base": flatBase,
13+
"flat/recommended": flatRecommended,
1014
};
1115

1216
const rules = ruleList.reduce(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
var a = {foo: 'bar'}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"foo": "bar"}

tests/src/eslint-plugin.ts

+29-7
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,46 @@
11
import path from "path";
22
import assert from "assert";
33
import plugin from "../../src/index";
4-
import { getLegacyESLint } from "eslint-compat-utils/eslint";
4+
import semver from "semver";
5+
import { getLegacyESLint, getESLint } from "eslint-compat-utils/eslint";
56

6-
// eslint-disable-next-line @typescript-eslint/naming-convention -- Class name
7-
const ESLint = getLegacyESLint();
87
// -----------------------------------------------------------------------------
98
// Tests
109
// -----------------------------------------------------------------------------
1110

12-
const TEST_CWD = path.join(__dirname, "../fixtures/integrations/eslint-plugin");
11+
const TEST_FIXTURES_ROOT = path.join(
12+
__dirname,
13+
"../fixtures/integrations/eslint-plugin",
14+
);
1315

1416
describe("Integration with eslint-plugin-json-schema-validator", () => {
15-
it("should lint without errors", async () => {
17+
it("should lint without errors with legacy-config", async () => {
18+
// eslint-disable-next-line @typescript-eslint/naming-convention -- Class name
19+
const ESLint = getLegacyESLint();
1620
const engine = new ESLint({
17-
cwd: TEST_CWD,
21+
cwd: path.join(TEST_FIXTURES_ROOT, "legacy-config-test01"),
1822
extensions: [".js", ".json"],
1923
plugins: { "json-schema-validator": plugin as any },
2024
});
21-
const results = await engine.lintFiles(["test01/src"]);
25+
const results = await engine.lintFiles(["src"]);
26+
assert.strictEqual(results.length, 2);
27+
assert.strictEqual(
28+
results.reduce((s, r) => s + r.errorCount, 0),
29+
0,
30+
);
31+
});
32+
it("should lint without errors with flat-config", async () => {
33+
// eslint-disable-next-line @typescript-eslint/naming-convention -- Class name
34+
const ESLint = getESLint();
35+
if (semver.satisfies(ESLint.version, "<7.0.0")) return;
36+
const engine = new ESLint({
37+
cwd: path.join(TEST_FIXTURES_ROOT, "flat-config-test01"),
38+
// @ts-expect-error -- typing bug
39+
overrideConfigFile: true,
40+
// @ts-expect-error -- typing bug
41+
overrideConfig: plugin.configs["flat/recommended"],
42+
});
43+
const results = await engine.lintFiles(["src"]);
2244
assert.strictEqual(results.length, 2);
2345
assert.strictEqual(
2446
results.reduce((s, r) => s + r.errorCount, 0),

tools/update-rulesets.ts

+41
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import os from "os";
55
import { rules } from "./lib/load-rules";
66
const isWin = os.platform().startsWith("win");
77

8+
const FLAT_RULESET_NAME = {
9+
recommended: "../src/configs/flat/recommended.ts",
10+
};
811
const RULESET_NAME = {
912
recommended: "../src/configs/recommended.ts",
1013
// standard: "../src/configs/standard.ts",
@@ -50,3 +53,41 @@ export = {
5053
// Update file.
5154
fs.writeFileSync(filePath, content);
5255
}
56+
57+
for (const rec of ["recommended"] as const) {
58+
let content = `
59+
import base from './base';
60+
export default [
61+
...base,
62+
{
63+
rules: {
64+
// eslint-plugin-json-schema-validator rules
65+
${rules
66+
.filter(
67+
(rule) =>
68+
rule.meta.docs.categories &&
69+
!rule.meta.deprecated &&
70+
rule.meta.docs.categories.includes(rec),
71+
)
72+
.map((rule) => {
73+
const conf = rule.meta.docs.default || "error";
74+
return `"${rule.meta.docs.ruleId}": "${conf}"`;
75+
})
76+
.join(",\n")}
77+
},
78+
}
79+
]
80+
`;
81+
82+
const filePath = path.resolve(__dirname, FLAT_RULESET_NAME[rec]);
83+
84+
if (isWin) {
85+
content = content
86+
.replace(/\r?\n/gu, "\n")
87+
.replace(/\r/gu, "\n")
88+
.replace(/\n/gu, "\r\n");
89+
}
90+
91+
// Update file.
92+
fs.writeFileSync(filePath, content);
93+
}

0 commit comments

Comments
 (0)