eslint-plugin-package-json 0.60.0 β 0.62.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 +23 -5
- package/lib/index.d.ts +13 -0
- package/lib/plugin.d.ts +13 -0
- package/lib/plugin.js +31 -19
- package/lib/rules/exports-subpaths-style.js +1 -1
- package/lib/rules/scripts-name-casing.d.ts +6 -0
- package/lib/rules/scripts-name-casing.js +43 -0
- package/lib/rules/valid-bin.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
# [0.
|
|
3
|
+
# [0.62.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.61.0...v0.62.0) (2025-11-03)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **scripts-name-casing:** add new rule ([#1344](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1344)) ([e735595](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/e735595537e6857c771eac12a1efcd55cb2d3564)), closes [#61](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/61)
|
|
4
9
|
|
|
10
|
+
# [0.61.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.60.0...v0.61.0) (2025-11-03)
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- add new stylistic config ([#1342](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1342)) ([3d01cce](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/3d01cce99a1718a7485669c7b8cf6143a255b094)), closes [#1341](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1341)
|
|
15
|
+
|
|
16
|
+
# [0.60.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.59.1...v0.60.0) (2025-11-03)
|
|
5
17
|
|
|
6
18
|
### Features
|
|
7
19
|
|
|
8
|
-
|
|
20
|
+
- **valid-author:** create more precise reports ([#1337](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1337)) ([e79ff9a](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/e79ff9ac602d85bf999686b018de6ace3a7bee36)), closes [#000](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/000)
|
|
9
21
|
|
|
10
22
|
## [0.59.1](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.59.0...v0.59.1) (2025-10-30)
|
|
11
23
|
|
package/README.md
CHANGED
|
@@ -28,13 +28,12 @@ npm install eslint eslint-plugin-package-json --save-dev
|
|
|
28
28
|
|
|
29
29
|
## Usage
|
|
30
30
|
|
|
31
|
-
### Config
|
|
31
|
+
### Recommended Config
|
|
32
32
|
|
|
33
33
|
This plugin's recommended configuration enables its rules on `**/package.json` files, parsing them with [`jsonc-eslint-parser`](https://github.com/ota-meshi/jsonc-eslint-parser).
|
|
34
34
|
|
|
35
|
-
In your ESLint configuration file:
|
|
36
|
-
|
|
37
35
|
```ts
|
|
36
|
+
// eslint.config.ts
|
|
38
37
|
import packageJson from "eslint-plugin-package-json";
|
|
39
38
|
|
|
40
39
|
export default [
|
|
@@ -46,6 +45,7 @@ export default [
|
|
|
46
45
|
If you want to override the recommended rules:
|
|
47
46
|
|
|
48
47
|
```ts
|
|
48
|
+
// eslint.config.ts
|
|
49
49
|
import packageJson from "eslint-plugin-package-json";
|
|
50
50
|
|
|
51
51
|
export default [
|
|
@@ -61,7 +61,23 @@ export default [
|
|
|
61
61
|
|
|
62
62
|
See [ESLint's _Configuration Files_ guide](https://eslint.org/docs/latest/use/configure/configuration-files-new) for details on how to customize your rules and other config settings.
|
|
63
63
|
|
|
64
|
-
###
|
|
64
|
+
### Stylistic Config
|
|
65
|
+
|
|
66
|
+
The stylistic configuration enables sets up the parser and files similar to the recommended config, but includes rules that are more opinionated about the style of a package.json.
|
|
67
|
+
This can be used in addition to the recommended config, or on its own.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
// eslint.config.ts
|
|
71
|
+
import packageJson from "eslint-plugin-package-json";
|
|
72
|
+
|
|
73
|
+
export default [
|
|
74
|
+
// your other ESLint configurations
|
|
75
|
+
packageJson.configs.recommended,
|
|
76
|
+
packageJson.configs.stylistic,
|
|
77
|
+
];
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Legacy Recommended Config (deprecated)
|
|
65
81
|
|
|
66
82
|
Usage with ESLint's legacy ("eslintrc") format requires also installing [`jsonc-eslint-parser`](https://github.com/ota-meshi/jsonc-eslint-parser):
|
|
67
83
|
|
|
@@ -160,13 +176,14 @@ The default settings don't conflict, and Prettier plugins can quickly fix up ord
|
|
|
160
176
|
πΌ Configurations enabled in.\
|
|
161
177
|
βοΈ Set in the `legacy-recommended` configuration.\
|
|
162
178
|
β
Set in the `recommended` configuration.\
|
|
179
|
+
π¨ Set in the `stylistic` configuration.\
|
|
163
180
|
π§ Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
|
|
164
181
|
π‘ Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\
|
|
165
182
|
β Deprecated.
|
|
166
183
|
|
|
167
184
|
| NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β | Description | πΌ | π§ | π‘ | β |
|
|
168
185
|
| :------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------- | :--- | :- | :- | :- |
|
|
169
|
-
| [exports-subpaths-style](docs/rules/exports-subpaths-style.md) | Enforce consistent format for the exports field (implicit or explicit subpaths). |
|
|
186
|
+
| [exports-subpaths-style](docs/rules/exports-subpaths-style.md) | Enforce consistent format for the exports field (implicit or explicit subpaths). | π¨ | π§ | | |
|
|
170
187
|
| [no-empty-fields](docs/rules/no-empty-fields.md) | Reports on unnecessary empty arrays and objects. | βοΈ β
| | π‘ | |
|
|
171
188
|
| [no-redundant-files](docs/rules/no-redundant-files.md) | Prevents adding unnecessary / redundant files. | βοΈ β
| | π‘ | |
|
|
172
189
|
| [order-properties](docs/rules/order-properties.md) | Package properties must be declared in standard order | βοΈ β
| π§ | | |
|
|
@@ -188,6 +205,7 @@ The default settings don't conflict, and Prettier plugins can quickly fix up ord
|
|
|
188
205
|
| [require-types](docs/rules/require-types.md) | Requires the `types` property to be present. | | | | |
|
|
189
206
|
| [require-version](docs/rules/require-version.md) | Requires the `version` property to be present. | βοΈ β
| | | |
|
|
190
207
|
| [restrict-dependency-ranges](docs/rules/restrict-dependency-ranges.md) | Restricts the range of dependencies to allow or disallow specific types of ranges. | | | π‘ | |
|
|
208
|
+
| [scripts-name-casing](docs/rules/scripts-name-casing.md) | Enforce that names for `scripts` are in kebab case (optionally separated by colons). | π¨ | | π‘ | |
|
|
191
209
|
| [sort-collections](docs/rules/sort-collections.md) | Selected collections must be in a consistent order (lexicographical for most; lifecycle-aware for scripts). | βοΈ β
| π§ | | |
|
|
192
210
|
| [unique-dependencies](docs/rules/unique-dependencies.md) | Checks a dependency isn't specified more than once (i.e. in `dependencies` and `devDependencies`) | βοΈ β
| | π‘ | |
|
|
193
211
|
| [valid-author](docs/rules/valid-author.md) | Enforce that the `author` property is valid. | βοΈ β
| | | |
|
package/lib/index.d.ts
CHANGED
|
@@ -30,6 +30,19 @@ declare const configs: {
|
|
|
30
30
|
}];
|
|
31
31
|
};
|
|
32
32
|
};
|
|
33
|
+
stylistic: {
|
|
34
|
+
files: string[];
|
|
35
|
+
languageOptions: {
|
|
36
|
+
parser: typeof jsonc_eslint_parser0;
|
|
37
|
+
};
|
|
38
|
+
name: string;
|
|
39
|
+
plugins: {
|
|
40
|
+
readonly "package-json": eslint0.ESLint.Plugin;
|
|
41
|
+
};
|
|
42
|
+
rules: {
|
|
43
|
+
[k: string]: "error";
|
|
44
|
+
};
|
|
45
|
+
};
|
|
33
46
|
};
|
|
34
47
|
//#endregion
|
|
35
48
|
export { type PackageJsonPluginSettings, configs, plugin as default, rules };
|
package/lib/plugin.d.ts
CHANGED
|
@@ -30,6 +30,19 @@ declare const plugin: {
|
|
|
30
30
|
}];
|
|
31
31
|
};
|
|
32
32
|
};
|
|
33
|
+
stylistic: {
|
|
34
|
+
files: string[];
|
|
35
|
+
languageOptions: {
|
|
36
|
+
parser: typeof parserJsonc;
|
|
37
|
+
};
|
|
38
|
+
name: string;
|
|
39
|
+
plugins: {
|
|
40
|
+
readonly "package-json": ESLint.Plugin;
|
|
41
|
+
};
|
|
42
|
+
rules: {
|
|
43
|
+
[k: string]: "error";
|
|
44
|
+
};
|
|
45
|
+
};
|
|
33
46
|
};
|
|
34
47
|
meta: {
|
|
35
48
|
name: string;
|
package/lib/plugin.js
CHANGED
|
@@ -5,16 +5,17 @@ import { rule as rule$3 } from "./rules/order-properties.js";
|
|
|
5
5
|
import { rule as rule$4 } from "./rules/repository-shorthand.js";
|
|
6
6
|
import { rules } from "./rules/require-properties.js";
|
|
7
7
|
import { rule as rule$5 } from "./rules/restrict-dependency-ranges.js";
|
|
8
|
-
import { rule as rule$6 } from "./rules/
|
|
9
|
-
import { rule as rule$7 } from "./rules/
|
|
10
|
-
import { rule as rule$8 } from "./rules/
|
|
11
|
-
import { rule as rule$9 } from "./rules/valid-
|
|
12
|
-
import { rule as rule$10 } from "./rules/valid-
|
|
13
|
-
import { rule as rule$11 } from "./rules/valid-
|
|
14
|
-
import { rule as rule$12 } from "./rules/valid-
|
|
8
|
+
import { rule as rule$6 } from "./rules/scripts-name-casing.js";
|
|
9
|
+
import { rule as rule$7 } from "./rules/sort-collections.js";
|
|
10
|
+
import { rule as rule$8 } from "./rules/unique-dependencies.js";
|
|
11
|
+
import { rule as rule$9 } from "./rules/valid-author.js";
|
|
12
|
+
import { rule as rule$10 } from "./rules/valid-bin.js";
|
|
13
|
+
import { rule as rule$11 } from "./rules/valid-local-dependency.js";
|
|
14
|
+
import { rule as rule$12 } from "./rules/valid-name.js";
|
|
15
|
+
import { rule as rule$13 } from "./rules/valid-package-definition.js";
|
|
15
16
|
import { rules as rules$1 } from "./rules/valid-properties.js";
|
|
16
|
-
import { rule as rule$
|
|
17
|
-
import { rule as rule$
|
|
17
|
+
import { rule as rule$14 } from "./rules/valid-repository-directory.js";
|
|
18
|
+
import { rule as rule$15 } from "./rules/valid-version.js";
|
|
18
19
|
import { createRequire } from "node:module";
|
|
19
20
|
import * as parserJsonc from "jsonc-eslint-parser";
|
|
20
21
|
|
|
@@ -28,22 +29,24 @@ const rules$2 = {
|
|
|
28
29
|
...rules,
|
|
29
30
|
"repository-shorthand": rule$4,
|
|
30
31
|
"restrict-dependency-ranges": rule$5,
|
|
31
|
-
"
|
|
32
|
-
"
|
|
32
|
+
"scripts-name-casing": rule$6,
|
|
33
|
+
"sort-collections": rule$7,
|
|
34
|
+
"unique-dependencies": rule$8,
|
|
33
35
|
...rules$1,
|
|
34
|
-
"valid-author": rule$
|
|
35
|
-
"valid-bin": rule$
|
|
36
|
-
"valid-local-dependency": rule$
|
|
37
|
-
"valid-name": rule$
|
|
38
|
-
"valid-package-definition": rule$
|
|
39
|
-
"valid-repository-directory": rule$
|
|
40
|
-
"valid-version": rule$
|
|
36
|
+
"valid-author": rule$9,
|
|
37
|
+
"valid-bin": rule$10,
|
|
38
|
+
"valid-local-dependency": rule$11,
|
|
39
|
+
"valid-name": rule$12,
|
|
40
|
+
"valid-package-definition": rule$13,
|
|
41
|
+
"valid-repository-directory": rule$14,
|
|
42
|
+
"valid-version": rule$15
|
|
41
43
|
};
|
|
42
|
-
const baseRecommendedRules = { ...Object.fromEntries(Object.entries(rules$2).filter(([, rule$
|
|
44
|
+
const baseRecommendedRules = { ...Object.fromEntries(Object.entries(rules$2).filter(([, rule$16]) => rule$16.meta.docs?.recommended).map(([name$1]) => ["package-json/" + name$1, "error"])) };
|
|
43
45
|
const recommendedRules = {
|
|
44
46
|
...baseRecommendedRules,
|
|
45
47
|
"package-json/valid-package-definition": ["error", { ignoreProperties: Object.entries(baseRecommendedRules).filter(([name$1]) => name$1.startsWith("package-json/valid-") && name$1 !== "package-json/valid-package-definition").map(([name$1]) => name$1.replace("package-json/valid-", "")) }]
|
|
46
48
|
};
|
|
49
|
+
const stylisticRules = { ...Object.fromEntries(Object.entries(rules$2).filter(([, rule$16]) => rule$16.meta.docs?.category === "Stylistic").map(([name$1]) => ["package-json/" + name$1, "error"])) };
|
|
47
50
|
const plugin = {
|
|
48
51
|
configs: {
|
|
49
52
|
"legacy-recommended": {
|
|
@@ -58,6 +61,15 @@ const plugin = {
|
|
|
58
61
|
return plugin;
|
|
59
62
|
} },
|
|
60
63
|
rules: recommendedRules
|
|
64
|
+
},
|
|
65
|
+
stylistic: {
|
|
66
|
+
files: ["**/package.json"],
|
|
67
|
+
languageOptions: { parser: parserJsonc },
|
|
68
|
+
name: "package-json/stylistic",
|
|
69
|
+
plugins: { get "package-json"() {
|
|
70
|
+
return plugin;
|
|
71
|
+
} },
|
|
72
|
+
rules: stylisticRules
|
|
61
73
|
}
|
|
62
74
|
},
|
|
63
75
|
meta: {
|
|
@@ -46,7 +46,7 @@ const rule = createRule({
|
|
|
46
46
|
meta: {
|
|
47
47
|
defaultOptions: [{ prefer: "explicit" }],
|
|
48
48
|
docs: {
|
|
49
|
-
category: "
|
|
49
|
+
category: "Stylistic",
|
|
50
50
|
description: "Enforce consistent format for the exports field (implicit or explicit subpaths).",
|
|
51
51
|
recommended: false
|
|
52
52
|
},
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createRule } from "../createRule.js";
|
|
2
|
+
import { kebabCase } from "change-case";
|
|
3
|
+
|
|
4
|
+
//#region src/rules/scripts-name-casing.ts
|
|
5
|
+
const rule = createRule({
|
|
6
|
+
create(context) {
|
|
7
|
+
return { "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=scripts]"(node) {
|
|
8
|
+
if (node.value.type === "JSONObjectExpression") for (const property of node.value.properties) {
|
|
9
|
+
const key = property.key;
|
|
10
|
+
const kebabCaseKey = key.value.split(":").map((segment) => kebabCase(segment)).join(":");
|
|
11
|
+
if (kebabCaseKey !== key.value) context.report({
|
|
12
|
+
data: { property: key.value },
|
|
13
|
+
messageId: "invalidCase",
|
|
14
|
+
node: key,
|
|
15
|
+
suggest: [{
|
|
16
|
+
data: { property: key.value },
|
|
17
|
+
fix: (fixer) => {
|
|
18
|
+
return fixer.replaceText(key, JSON.stringify(kebabCaseKey));
|
|
19
|
+
},
|
|
20
|
+
messageId: "convertToKebabCase"
|
|
21
|
+
}]
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
} };
|
|
25
|
+
},
|
|
26
|
+
meta: {
|
|
27
|
+
docs: {
|
|
28
|
+
category: "Stylistic",
|
|
29
|
+
description: "Enforce that names for `scripts` are in kebab case (optionally separated by colons)."
|
|
30
|
+
},
|
|
31
|
+
hasSuggestions: true,
|
|
32
|
+
messages: {
|
|
33
|
+
convertToKebabCase: "Convert {{ property }} to kebab case.",
|
|
34
|
+
invalidCase: "Script name {{ property }} should be in kebab case."
|
|
35
|
+
},
|
|
36
|
+
schema: [],
|
|
37
|
+
type: "suggestion"
|
|
38
|
+
},
|
|
39
|
+
name: "scripts-name-casing"
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
export { rule };
|
package/lib/rules/valid-bin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRule } from "../createRule.js";
|
|
2
2
|
import { formatErrors } from "../utils/formatErrors.js";
|
|
3
|
-
import { validateBin } from "package-json-validator";
|
|
4
3
|
import { kebabCase } from "change-case";
|
|
4
|
+
import { validateBin } from "package-json-validator";
|
|
5
5
|
|
|
6
6
|
//#region src/rules/valid-bin.ts
|
|
7
7
|
const rule = createRule({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-package-json",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.62.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": {
|