eslint-plugin-package-json 0.45.2 → 0.47.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/CHANGELOG.md +14 -2
- package/README.md +2 -1
- package/lib/plugin.js +2 -0
- package/lib/rules/no-empty-fields.d.ts +5 -1
- package/lib/rules/no-empty-fields.js +30 -3
- package/lib/rules/valid-config.d.ts +11 -0
- package/lib/rules/valid-config.js +40 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# [0.47.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.46.0...v0.47.0) (2025-07-25)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **no-empty-fields:** Add `ignoreProperties` option ([#1186](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1186)) ([91e7156](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/91e7156d9f4569e8fee6f1124c4c1bb18ffdfbe0)), closes [#1182](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1182)
|
|
4
9
|
|
|
10
|
+
# [0.46.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.45.2...v0.46.0) (2025-07-24)
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- **valid-config:** add new rule for validating `config` ([#1179](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1179)) ([b71de96](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/b71de96a2a79a91d177ee0d734dc5f5d1d8e5b3b)), closes [#820](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/820)
|
|
15
|
+
|
|
16
|
+
## [0.45.2](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.45.1...v0.45.2) (2025-07-24)
|
|
5
17
|
|
|
6
18
|
### Bug Fixes
|
|
7
19
|
|
|
8
|
-
|
|
20
|
+
- **deps:** update dependency package-json-validator to ~0.23.0 ([#1183](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1183)) ([fbc5f29](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/fbc5f298a63a4ce58d1311502bbea9a0593173d1))
|
|
9
21
|
|
|
10
22
|
## [0.45.1](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.45.0...v0.45.1) (2025-07-18)
|
|
11
23
|
|
package/README.md
CHANGED
|
@@ -140,6 +140,7 @@ The default settings don't conflict, and Prettier plugins can quickly fix up ord
|
|
|
140
140
|
| [valid-author](docs/rules/valid-author.md) | Enforce that the author field is a valid npm author specification | ✔️ ✅ | | | |
|
|
141
141
|
| [valid-bin](docs/rules/valid-bin.md) | Enforce that the `bin` property is valid. | ✔️ ✅ | | 💡 | |
|
|
142
142
|
| [valid-bundleDependencies](docs/rules/valid-bundleDependencies.md) | Enforce that the `bundleDependencies` (or `bundledDependencies`) property is valid. | ✔️ ✅ | | | |
|
|
143
|
+
| [valid-config](docs/rules/valid-config.md) | Enforce that the `config` property is valid. | ✔️ ✅ | | | |
|
|
143
144
|
| [valid-license](docs/rules/valid-license.md) | Enforce that the `license` property is valid. | ✔️ ✅ | | | |
|
|
144
145
|
| [valid-local-dependency](docs/rules/valid-local-dependency.md) | Checks existence of local dependencies in the package.json | | | | ❌ |
|
|
145
146
|
| [valid-name](docs/rules/valid-name.md) | Enforce that package names are valid npm package names | ✔️ ✅ | | | |
|
|
@@ -193,7 +194,7 @@ Thanks! 🗂
|
|
|
193
194
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/andreww2012"><img src="https://avatars.githubusercontent.com/u/6554045?v=4?s=100" width="100px;" alt="Andrew Kazakov"/><br /><sub><b>Andrew Kazakov</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Aandreww2012" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=andreww2012" title="Code">💻</a> <a href="#ideas-andreww2012" title="Ideas, Planning, & Feedback">🤔</a></td>
|
|
194
195
|
<td align="center" valign="top" width="14.28%"><a href="http://technotes.khitrenovich.com/"><img src="https://avatars.githubusercontent.com/u/3424762?v=4?s=100" width="100px;" alt="Anton Khitrenovich"/><br /><sub><b>Anton Khitrenovich</b></sub></a><br /><a href="#ideas-khitrenovich" title="Ideas, Planning, & Feedback">🤔</a></td>
|
|
195
196
|
<td align="center" valign="top" width="14.28%"><a href="https://azat.io"><img src="https://avatars.githubusercontent.com/u/5698350?v=4?s=100" width="100px;" alt="Azat S."/><br /><sub><b>Azat S.</b></sub></a><br /><a href="#ideas-azat-io" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=azat-io" title="Code">💻</a></td>
|
|
196
|
-
<td align="center" valign="top" width="14.28%"><a href="https://github.com/anomiex"><img src="https://avatars.githubusercontent.com/u/1030580?v=4?s=100" width="100px;" alt="Brad Jorsch"/><br /><sub><b>Brad Jorsch</b></sub></a><br /><a href="#ideas-anomiex" title="Ideas, Planning, & Feedback">🤔</a></td>
|
|
197
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/anomiex"><img src="https://avatars.githubusercontent.com/u/1030580?v=4?s=100" width="100px;" alt="Brad Jorsch"/><br /><sub><b>Brad Jorsch</b></sub></a><br /><a href="#ideas-anomiex" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Aanomiex" title="Bug reports">🐛</a></td>
|
|
197
198
|
<td align="center" valign="top" width="14.28%"><a href="http://www.curtisjewell.dev/"><img src="https://avatars.githubusercontent.com/u/67483?v=4?s=100" width="100px;" alt="Curtis Jewell"/><br /><sub><b>Curtis Jewell</b></sub></a><br /><a href="#ideas-csjewell" title="Ideas, Planning, & Feedback">🤔</a></td>
|
|
198
199
|
</tr>
|
|
199
200
|
<tr>
|
package/lib/plugin.js
CHANGED
|
@@ -11,6 +11,7 @@ import { rule as uniqueDependencies } from "./rules/unique-dependencies.js";
|
|
|
11
11
|
import { rule as validAuthor } from "./rules/valid-author.js";
|
|
12
12
|
import { rule as validBin } from "./rules/valid-bin.js";
|
|
13
13
|
import { rule as validBundleDependencies } from "./rules/valid-bundleDependencies.js";
|
|
14
|
+
import { rule as validConfig } from "./rules/valid-config.js";
|
|
14
15
|
import { rule as validLicense } from "./rules/valid-license.js";
|
|
15
16
|
import { rule as validLocalDependency } from "./rules/valid-local-dependency.js";
|
|
16
17
|
import { rule as validName } from "./rules/valid-name.js";
|
|
@@ -33,6 +34,7 @@ const rules = {
|
|
|
33
34
|
"valid-author": validAuthor,
|
|
34
35
|
"valid-bin": validBin,
|
|
35
36
|
"valid-bundleDependencies": validBundleDependencies,
|
|
37
|
+
"valid-config": validConfig,
|
|
36
38
|
"valid-license": validLicense,
|
|
37
39
|
"valid-local-dependency": validLocalDependency,
|
|
38
40
|
"valid-name": validName,
|
|
@@ -3,8 +3,12 @@ import * as jsonc_eslint_parser from 'jsonc-eslint-parser';
|
|
|
3
3
|
import { PackageJsonRuleContext } from '../createRule.js';
|
|
4
4
|
import 'estree';
|
|
5
5
|
|
|
6
|
+
interface Option {
|
|
7
|
+
ignoreProperties?: string[];
|
|
8
|
+
}
|
|
9
|
+
type Options = [Option?];
|
|
6
10
|
declare const rule: {
|
|
7
|
-
create(context: PackageJsonRuleContext<
|
|
11
|
+
create(context: PackageJsonRuleContext<Options>): jsonc_eslint_parser.RuleListener;
|
|
8
12
|
meta: eslint.Rule.RuleMetaData;
|
|
9
13
|
};
|
|
10
14
|
|
|
@@ -52,17 +52,31 @@ const report = (context, node) => {
|
|
|
52
52
|
const getNode = (node) => {
|
|
53
53
|
return node.parent.type === "JSONProperty" ? node.parent : node;
|
|
54
54
|
};
|
|
55
|
+
const getTopLevelPropertyName = (node) => {
|
|
56
|
+
let n = node;
|
|
57
|
+
while (n.parent.parent?.parent?.type !== void 0 && n.parent.parent.parent.type !== "Program") {
|
|
58
|
+
n = n.parent;
|
|
59
|
+
}
|
|
60
|
+
return n.key.value;
|
|
61
|
+
};
|
|
55
62
|
const rule = createRule({
|
|
56
63
|
create(context) {
|
|
64
|
+
const ignoreProperties = context.options[0]?.ignoreProperties ?? [];
|
|
57
65
|
return {
|
|
58
66
|
JSONArrayExpression(node) {
|
|
59
67
|
if (!node.elements.length) {
|
|
60
|
-
|
|
68
|
+
const topLevelProperty = getTopLevelPropertyName(node);
|
|
69
|
+
if (!ignoreProperties.includes(topLevelProperty)) {
|
|
70
|
+
report(context, getNode(node));
|
|
71
|
+
}
|
|
61
72
|
}
|
|
62
73
|
},
|
|
63
74
|
JSONObjectExpression(node) {
|
|
64
75
|
if (!node.properties.length) {
|
|
65
|
-
|
|
76
|
+
const topLevelProperty = getTopLevelPropertyName(node);
|
|
77
|
+
if (!ignoreProperties.includes(topLevelProperty)) {
|
|
78
|
+
report(context, getNode(node));
|
|
79
|
+
}
|
|
66
80
|
}
|
|
67
81
|
}
|
|
68
82
|
};
|
|
@@ -79,7 +93,20 @@ const rule = createRule({
|
|
|
79
93
|
emptyFields: "The field '{{field}}' does nothing and can be removed.",
|
|
80
94
|
remove: "Remove this empty field."
|
|
81
95
|
},
|
|
82
|
-
schema: [
|
|
96
|
+
schema: [
|
|
97
|
+
{
|
|
98
|
+
additionalProperties: false,
|
|
99
|
+
properties: {
|
|
100
|
+
ignoreProperties: {
|
|
101
|
+
items: {
|
|
102
|
+
type: "string"
|
|
103
|
+
},
|
|
104
|
+
type: "array"
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
type: "object"
|
|
108
|
+
}
|
|
109
|
+
],
|
|
83
110
|
type: "suggestion"
|
|
84
111
|
}
|
|
85
112
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as eslint from 'eslint';
|
|
2
|
+
import * as jsonc_eslint_parser from 'jsonc-eslint-parser';
|
|
3
|
+
import { PackageJsonRuleContext } from '../createRule.js';
|
|
4
|
+
import 'estree';
|
|
5
|
+
|
|
6
|
+
declare const rule: {
|
|
7
|
+
create(context: PackageJsonRuleContext<unknown[]>): jsonc_eslint_parser.RuleListener;
|
|
8
|
+
meta: eslint.Rule.RuleMetaData;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { rule };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { validateConfig } from "package-json-validator";
|
|
2
|
+
import { createRule } from "../createRule.js";
|
|
3
|
+
import { formatErrors } from "../utils/formatErrors.js";
|
|
4
|
+
const rule = createRule({
|
|
5
|
+
create(context) {
|
|
6
|
+
return {
|
|
7
|
+
"Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=config]"(node) {
|
|
8
|
+
const valueNode = node.value;
|
|
9
|
+
const value = JSON.parse(
|
|
10
|
+
context.sourceCode.getText(valueNode)
|
|
11
|
+
);
|
|
12
|
+
const errors = validateConfig(value);
|
|
13
|
+
if (errors.length) {
|
|
14
|
+
context.report({
|
|
15
|
+
data: {
|
|
16
|
+
errors: formatErrors(errors)
|
|
17
|
+
},
|
|
18
|
+
messageId: "validationError",
|
|
19
|
+
node: valueNode
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
meta: {
|
|
26
|
+
docs: {
|
|
27
|
+
category: "Best Practices",
|
|
28
|
+
description: "Enforce that the `config` property is valid.",
|
|
29
|
+
recommended: true
|
|
30
|
+
},
|
|
31
|
+
messages: {
|
|
32
|
+
validationError: "Invalid config: {{ errors }}"
|
|
33
|
+
},
|
|
34
|
+
schema: [],
|
|
35
|
+
type: "problem"
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
export {
|
|
39
|
+
rule
|
|
40
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-package-json",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.47.0",
|
|
4
4
|
"description": "Rules for consistent, readable, and valid package.json files. 🗂️",
|
|
5
5
|
"homepage": "https://github.com/JoshuaKGoldberg/eslint-plugin-package-json#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"husky": "9.1.7",
|
|
83
83
|
"jiti": "2.4.2",
|
|
84
84
|
"jsonc-eslint-parser": "2.4.0",
|
|
85
|
-
"knip": "5.
|
|
85
|
+
"knip": "5.62.0",
|
|
86
86
|
"lint-staged": "16.1.0",
|
|
87
87
|
"markdownlint": "0.38.0",
|
|
88
88
|
"markdownlint-cli": "0.45.0",
|