eslint-plugin-package-jsonc 1.0.4 → 1.1.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 +19 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -8
- package/dist/index.js.map +1 -1
- package/dist/rules/package-jsonc.d.ts.map +1 -1
- package/dist/rules/package-jsonc.js +20 -9
- package/dist/rules/package-jsonc.js.map +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -21,9 +21,9 @@ import packageJsonc from "eslint-plugin-package-jsonc";
|
|
|
21
21
|
export default [
|
|
22
22
|
// Use eslint-plugin-jsonc to parse JSONC files (handles comments, trailing commas)
|
|
23
23
|
...jsonc.configs["flat/recommended-with-jsonc"],
|
|
24
|
-
// Add package-jsonc/sync rule for package.jsonc files
|
|
24
|
+
// Add package-jsonc/sync rule for package.jsonc and package.json files
|
|
25
25
|
{
|
|
26
|
-
files: ["**/package.jsonc"],
|
|
26
|
+
files: ["**/package.jsonc", "**/package.json"],
|
|
27
27
|
plugins: {
|
|
28
28
|
"package-jsonc": packageJsonc,
|
|
29
29
|
},
|
|
@@ -36,30 +36,35 @@ export default [
|
|
|
36
36
|
|
|
37
37
|
## Rule: `package-jsonc/sync`
|
|
38
38
|
|
|
39
|
-
This rule ensures that `package.
|
|
39
|
+
This rule ensures that `package.jsonc` is the single source of truth for your package configuration.
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
- If `package.json` exists but has different content than what would be generated from `package.jsonc`, the rule reports an error and can update `package.json` when running with `--fix`.
|
|
41
|
+
It enforces the following:
|
|
43
42
|
|
|
44
|
-
|
|
43
|
+
1. **Missing `package.jsonc`**: If `package.json` exists but `package.jsonc` does not, the rule reports an error. This is not auto-fixable.
|
|
44
|
+
2. **Invalid `package.jsonc`**: If `package.jsonc` exists but contains invalid JSON (syntax errors), the rule reports an error. This is not auto-fixable.
|
|
45
|
+
3. **Inconsistent `package.json`**: If `package.jsonc` is valid, the rule compares it with `package.json`. If `package.json` is invalid, or inconsistent with `package.jsonc`, the rule reports an error. **This is auto-fixable.**
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
### Fix Mode
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
2. Update `package.json` if it's inconsistent with `package.jsonc`
|
|
49
|
+
When running ESLint with the `--fix` flag, the plugin will automatically generate or update `package.json` to match `package.jsonc`.
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
eslint package.jsonc --fix
|
|
52
|
+
eslint package.jsonc package.json --fix
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
## How It Works
|
|
56
56
|
|
|
57
|
-
1.
|
|
58
|
-
2.
|
|
59
|
-
3.
|
|
60
|
-
4.
|
|
57
|
+
1. When linting `package.json`, checks if `package.jsonc` exists.
|
|
58
|
+
2. When linting `package.jsonc`, it uses `jsonc-eslint-parser` to parse the content.
|
|
59
|
+
3. If `package.jsonc` is valid, it compares the parsed content with `package.json`.
|
|
60
|
+
4. If they differ, it reports an error.
|
|
61
|
+
5. In fix mode, it writes the normalized JSON from `package.jsonc` to `package.json`.
|
|
61
62
|
|
|
62
63
|
## Why Use This?
|
|
63
64
|
|
|
64
65
|
- **Comments in package.json**: JSONC allows you to add comments to your package configuration while maintaining a standard `package.json` for npm compatibility.
|
|
65
66
|
- **Single source of truth**: `package.jsonc` becomes the source of truth, and `package.json` is auto-generated.
|
|
67
|
+
|
|
68
|
+
## Hints
|
|
69
|
+
|
|
70
|
+
You can use eslint-plugin-package-json as you let AI fix related errors in package.jsonc rather than package.json.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAQrC,QAAA,MAAM,MAAM,EAAE,MAAM,CAAC,MAgBpB,CAAC;AAOF,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
1
|
import packageJsoncRule, { clearFixedFiles } from "./rules/package-jsonc.js";
|
|
3
|
-
//
|
|
4
|
-
// This ensures the plugin
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const { name, version } = require("../package.json");
|
|
2
|
+
// Plugin metadata - hardcoded to avoid dependency on package.json
|
|
3
|
+
// This ensures the plugin works even when the project's package.json is missing
|
|
4
|
+
const PLUGIN_NAME = "eslint-plugin-package-jsonc";
|
|
5
|
+
const PLUGIN_VERSION = "1.0.4";
|
|
8
6
|
const plugin = {
|
|
9
7
|
meta: {
|
|
10
|
-
name,
|
|
11
|
-
version,
|
|
8
|
+
name: PLUGIN_NAME,
|
|
9
|
+
version: PLUGIN_VERSION,
|
|
12
10
|
},
|
|
13
11
|
rules: {
|
|
14
12
|
sync: packageJsoncRule,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,gBAAgB,EAAE,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE7E,kEAAkE;AAClE,gFAAgF;AAChF,MAAM,WAAW,GAAG,6BAA6B,CAAC;AAClD,MAAM,cAAc,GAAG,OAAO,CAAC;AAE/B,MAAM,MAAM,GAAkB;IAC1B,IAAI,EAAE;QACF,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,cAAc;KAC1B;IACD,KAAK,EAAE;QACH,IAAI,EAAE,gBAAgB;KACzB;IACD,OAAO,EAAE;QACL,WAAW,EAAE;YACT,OAAO,EAAE,CAAC,eAAe,CAAC;YAC1B,KAAK,EAAE;gBACH,oBAAoB,EAAE,OAAO;aAChC;SACJ;KACJ;CACJ,CAAC;AAEF,kDAAkD;AAE9C,MACH,CAAC,eAAe,GAAG,eAAe,CAAC;AAEpC,eAAe,MAAM,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-jsonc.d.ts","sourceRoot":"","sources":["../../src/rules/package-jsonc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAiDnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"package-jsonc.d.ts","sourceRoot":"","sources":["../../src/rules/package-jsonc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAiDnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA4GhB,CAAC;AAGF,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,eAAe,IAAI,CAAC"}
|
|
@@ -52,21 +52,33 @@ const rule = {
|
|
|
52
52
|
fixable: "code",
|
|
53
53
|
schema: [],
|
|
54
54
|
messages: {
|
|
55
|
-
|
|
55
|
+
missingPackageJsonc: "package.jsonc does not exist.",
|
|
56
|
+
invalidPackageJsonc: "package.jsonc is invalid.",
|
|
56
57
|
inconsistentPackageJson: "package.json is inconsistent with package.jsonc. Run 'npx eslint package.jsonc --fix' to update it.",
|
|
57
58
|
},
|
|
58
59
|
},
|
|
59
60
|
create(context) {
|
|
60
61
|
const { filename } = context;
|
|
61
62
|
const basename = path.basename(filename);
|
|
62
|
-
|
|
63
|
-
if (basename !== "package.jsonc") {
|
|
63
|
+
if (basename !== "package.jsonc" && basename !== "package.json") {
|
|
64
64
|
return {};
|
|
65
65
|
}
|
|
66
66
|
const directory = path.dirname(filename);
|
|
67
|
+
const packageJsoncPath = path.join(directory, "package.jsonc");
|
|
67
68
|
const packageJsonPath = path.join(directory, "package.json");
|
|
68
69
|
return {
|
|
69
70
|
Program(node) {
|
|
71
|
+
// If we are on package.json, we only check if package.jsonc exists
|
|
72
|
+
if (basename === "package.json") {
|
|
73
|
+
if (!fs.existsSync(packageJsoncPath)) {
|
|
74
|
+
context.report({
|
|
75
|
+
node,
|
|
76
|
+
messageId: "missingPackageJsonc",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// If we are on package.jsonc, we perform the full check
|
|
70
82
|
const { sourceCode } = context;
|
|
71
83
|
const jsoncContent = sourceCode.getText();
|
|
72
84
|
let jsoncData;
|
|
@@ -74,7 +86,10 @@ const rule = {
|
|
|
74
86
|
jsoncData = parseJSONC(jsoncContent);
|
|
75
87
|
}
|
|
76
88
|
catch {
|
|
77
|
-
|
|
89
|
+
context.report({
|
|
90
|
+
node,
|
|
91
|
+
messageId: "invalidPackageJsonc",
|
|
92
|
+
});
|
|
78
93
|
return;
|
|
79
94
|
}
|
|
80
95
|
const normalizedJsonc = getNormalizedJson(jsoncData);
|
|
@@ -92,13 +107,9 @@ const rule = {
|
|
|
92
107
|
if (isConsistent) {
|
|
93
108
|
return;
|
|
94
109
|
}
|
|
95
|
-
// Report the error with a fixer
|
|
96
|
-
const messageId = fs.existsSync(packageJsonPath)
|
|
97
|
-
? "inconsistentPackageJson"
|
|
98
|
-
: "missingPackageJson";
|
|
99
110
|
context.report({
|
|
100
111
|
node,
|
|
101
|
-
messageId,
|
|
112
|
+
messageId: "inconsistentPackageJson",
|
|
102
113
|
fix(fixer) {
|
|
103
114
|
// Check if we've already fixed this file in this run
|
|
104
115
|
if (fixedFiles.has(filename)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-jsonc.js","sourceRoot":"","sources":["../../src/rules/package-jsonc.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,+EAA+E;AAC/E,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;AAErC;;GAEG;AACH,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB;;;;;GAKG;AACH,SAAS,UAAU,CAAC,OAAe;IAC/B,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO,kBAAkB,CAAC,GAAG,CAA4B,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,MAAe;IACtC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC;AAC5D,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,eAAuB,EAAE,eAAuB;IAC9D,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAA4B,CAAC;QACvE,OAAO,eAAe,KAAK,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACL,mCAAmC;QACnC,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAED,MAAM,IAAI,GAAoB;IAC1B,IAAI,EAAE;QACF,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACF,WAAW,EAAE,sDAAsD;YACnE,QAAQ,EAAE,iBAAiB;YAC3B,WAAW,EAAE,IAAI;SACpB;QACD,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACN,
|
|
1
|
+
{"version":3,"file":"package-jsonc.js","sourceRoot":"","sources":["../../src/rules/package-jsonc.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-package-jsonc",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "ESLint plugin to ensure package.json is consistent with package.jsonc",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -34,10 +34,12 @@
|
|
|
34
34
|
"@types/node": "^25.2.1",
|
|
35
35
|
"@vitest/eslint-plugin": "^1.6.6",
|
|
36
36
|
"eslint": "^9.39.1",
|
|
37
|
+
"eslint-plugin-jsonc": "^2.21.0",
|
|
37
38
|
"eslint-plugin-unicorn": "^62.0.0",
|
|
38
39
|
"espree": "^11.1.0",
|
|
39
40
|
"globals": "^17.3.0",
|
|
40
41
|
"jiti": "^2.6.1",
|
|
42
|
+
"jsonc-eslint-parser": "^2.4.2",
|
|
41
43
|
"prettier": "^3.6.2",
|
|
42
44
|
"prettier-plugin-organize-imports": "^4.2.0",
|
|
43
45
|
"typescript": "^5",
|