eslint-plugin-package-json 0.63.0 → 0.64.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 CHANGED
@@ -1,11 +1,17 @@
1
1
  # Changelog
2
2
 
3
- # [0.63.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.62.0...v0.63.0) (2025-11-04)
3
+ # [0.64.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.63.0...v0.64.0) (2025-11-04)
4
+
5
+
6
+ ### Features
7
+
8
+ * **bin-name-casing:** add new rule ([#1343](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1343)) ([0e10e87](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/0e10e875eb4cc5f680e154e6ea2333e5902d4c4c)), closes [#1346](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1346)
4
9
 
10
+ # [0.63.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.62.0...v0.63.0) (2025-11-04)
5
11
 
6
12
  ### Features
7
13
 
8
- * **restrict-private-properties:** add new rule ([#1336](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1336)) ([e1225cf](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/e1225cf991be2f3829cdddcae8b06cef8196f070)), closes [#1323](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1323)
14
+ - **restrict-private-properties:** add new rule ([#1336](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1336)) ([e1225cf](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/e1225cf991be2f3829cdddcae8b06cef8196f070)), closes [#1323](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1323)
9
15
 
10
16
  # [0.62.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.61.0...v0.62.0) (2025-11-03)
11
17
 
package/README.md CHANGED
@@ -183,6 +183,7 @@ The default settings don't conflict, and Prettier plugins can quickly fix up ord
183
183
 
184
184
  | Name                         | Description | 💼 | 🔧 | 💡 | ❌ |
185
185
  | :------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------- | :--- | :- | :- | :- |
186
+ | [bin-name-casing](docs/rules/bin-name-casing.md) | Enforce that names for bin properties are in kebab case. | 🎨 | | 💡 | |
186
187
  | [exports-subpaths-style](docs/rules/exports-subpaths-style.md) | Enforce consistent format for the exports field (implicit or explicit subpaths). | 🎨 | 🔧 | | |
187
188
  | [no-empty-fields](docs/rules/no-empty-fields.md) | Reports on unnecessary empty arrays and objects. | ✔️ ✅ | | 💡 | |
188
189
  | [no-redundant-files](docs/rules/no-redundant-files.md) | Prevents adding unnecessary / redundant files. | ✔️ ✅ | | 💡 | |
@@ -210,7 +211,7 @@ The default settings don't conflict, and Prettier plugins can quickly fix up ord
210
211
  | [sort-collections](docs/rules/sort-collections.md) | Selected collections must be in a consistent order (lexicographical for most; lifecycle-aware for scripts). | ✔️ ✅ | 🔧 | | |
211
212
  | [unique-dependencies](docs/rules/unique-dependencies.md) | Checks a dependency isn't specified more than once (i.e. in `dependencies` and `devDependencies`) | ✔️ ✅ | | 💡 | |
212
213
  | [valid-author](docs/rules/valid-author.md) | Enforce that the `author` property is valid. | ✔️ ✅ | | | |
213
- | [valid-bin](docs/rules/valid-bin.md) | Enforce that the `bin` property is valid. | ✔️ ✅ | | 💡 | |
214
+ | [valid-bin](docs/rules/valid-bin.md) | Enforce that the `bin` property is valid. | ✔️ ✅ | | | |
214
215
  | [valid-bundleDependencies](docs/rules/valid-bundleDependencies.md) | Enforce that the `bundleDependencies` (also: `bundledDependencies`) property is valid. | ✔️ ✅ | | | |
215
216
  | [valid-config](docs/rules/valid-config.md) | Enforce that the `config` property is valid. | ✔️ ✅ | | | |
216
217
  | [valid-cpu](docs/rules/valid-cpu.md) | Enforce that the `cpu` property is valid. | ✔️ ✅ | | | |
package/lib/plugin.js CHANGED
@@ -1,16 +1,16 @@
1
- import { rule } from "./rules/exports-subpaths-style.js";
2
- import { rule as rule$1 } from "./rules/no-empty-fields.js";
3
- import { rule as rule$2 } from "./rules/no-redundant-files.js";
4
- import { rule as rule$3 } from "./rules/order-properties.js";
5
- import { rule as rule$4 } from "./rules/repository-shorthand.js";
1
+ import { rule } from "./rules/bin-name-casing.js";
2
+ import { rule as rule$1 } from "./rules/exports-subpaths-style.js";
3
+ import { rule as rule$2 } from "./rules/no-empty-fields.js";
4
+ import { rule as rule$3 } from "./rules/no-redundant-files.js";
5
+ import { rule as rule$4 } from "./rules/order-properties.js";
6
+ import { rule as rule$5 } from "./rules/repository-shorthand.js";
6
7
  import { rules } from "./rules/require-properties.js";
7
- import { rule as rule$5 } from "./rules/restrict-dependency-ranges.js";
8
- import { rule as rule$6 } from "./rules/restrict-private-properties.js";
9
- import { rule as rule$7 } from "./rules/scripts-name-casing.js";
10
- import { rule as rule$8 } from "./rules/sort-collections.js";
11
- import { rule as rule$9 } from "./rules/unique-dependencies.js";
12
- import { rule as rule$10 } from "./rules/valid-author.js";
13
- import { rule as rule$11 } from "./rules/valid-bin.js";
8
+ import { rule as rule$6 } from "./rules/restrict-dependency-ranges.js";
9
+ import { rule as rule$7 } from "./rules/restrict-private-properties.js";
10
+ import { rule as rule$8 } from "./rules/scripts-name-casing.js";
11
+ import { rule as rule$9 } from "./rules/sort-collections.js";
12
+ import { rule as rule$10 } from "./rules/unique-dependencies.js";
13
+ import { rule as rule$11 } from "./rules/valid-author.js";
14
14
  import { rule as rule$12 } from "./rules/valid-local-dependency.js";
15
15
  import { rule as rule$13 } from "./rules/valid-name.js";
16
16
  import { rule as rule$14 } from "./rules/valid-package-definition.js";
@@ -23,20 +23,20 @@ import * as parserJsonc from "jsonc-eslint-parser";
23
23
  //#region src/plugin.ts
24
24
  const { name, version } = createRequire(import.meta.url)("../package.json");
25
25
  const rules$2 = {
26
- "exports-subpaths-style": rule,
27
- "no-empty-fields": rule$1,
28
- "no-redundant-files": rule$2,
29
- "order-properties": rule$3,
26
+ "bin-name-casing": rule,
27
+ "exports-subpaths-style": rule$1,
28
+ "no-empty-fields": rule$2,
29
+ "no-redundant-files": rule$3,
30
+ "order-properties": rule$4,
30
31
  ...rules,
31
- "repository-shorthand": rule$4,
32
- "restrict-dependency-ranges": rule$5,
33
- "restrict-private-properties": rule$6,
34
- "scripts-name-casing": rule$7,
35
- "sort-collections": rule$8,
36
- "unique-dependencies": rule$9,
32
+ "repository-shorthand": rule$5,
33
+ "restrict-dependency-ranges": rule$6,
34
+ "restrict-private-properties": rule$7,
35
+ "scripts-name-casing": rule$8,
36
+ "sort-collections": rule$9,
37
+ "unique-dependencies": rule$10,
37
38
  ...rules$1,
38
- "valid-author": rule$10,
39
- "valid-bin": rule$11,
39
+ "valid-author": rule$11,
40
40
  "valid-local-dependency": rule$12,
41
41
  "valid-name": rule$13,
42
42
  "valid-package-definition": rule$14,
@@ -0,0 +1,6 @@
1
+ import { PackageJsonRuleModule } from "../createRule.js";
2
+
3
+ //#region src/rules/bin-name-casing.d.ts
4
+ declare const rule: PackageJsonRuleModule<[], []>;
5
+ //#endregion
6
+ export { rule };
@@ -0,0 +1,43 @@
1
+ import { createRule } from "../createRule.js";
2
+ import { kebabCase } from "change-case";
3
+
4
+ //#region src/rules/bin-name-casing.ts
5
+ const rule = createRule({
6
+ create(context) {
7
+ return { "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=bin]"(node) {
8
+ if (node.value.type === "JSONObjectExpression") for (const property of node.value.properties) {
9
+ const key = property.key;
10
+ const kebabCaseKey = kebabCase(key.value);
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 bin properties are in kebab case."
30
+ },
31
+ hasSuggestions: true,
32
+ messages: {
33
+ convertToKebabCase: "Convert {{ property }} to kebab case.",
34
+ invalidCase: "Command name {{ property }} should be in kebab case."
35
+ },
36
+ schema: [],
37
+ type: "suggestion"
38
+ },
39
+ name: "bin-name-casing"
40
+ });
41
+
42
+ //#endregion
43
+ export { rule };
@@ -1,8 +1,9 @@
1
1
  import { createSimpleValidPropertyRule } from "../utils/createSimpleValidPropertyRule.js";
2
- import { validateBundleDependencies, validateConfig, validateCpu, validateDependencies, validateDescription, validateDirectories, validateExports, validateLicense, validateScripts, validateType } from "package-json-validator";
2
+ import { validateBin, validateBundleDependencies, validateConfig, validateCpu, validateDependencies, validateDescription, validateDirectories, validateExports, validateLicense, validateScripts, validateType } from "package-json-validator";
3
3
 
4
4
  //#region src/rules/valid-properties.ts
5
5
  const properties = [
6
+ ["bin", validateBin],
6
7
  ["bundleDependencies", {
7
8
  aliases: ["bundledDependencies"],
8
9
  validator: validateBundleDependencies
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-package-json",
3
- "version": "0.63.0",
3
+ "version": "0.64.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": {
@@ -97,7 +97,7 @@
97
97
  "eslint": ">=8.0.0",
98
98
  "jsonc-eslint-parser": "^2.0.0"
99
99
  },
100
- "packageManager": "pnpm@10.19.0",
100
+ "packageManager": "pnpm@10.20.0",
101
101
  "engines": {
102
102
  "node": "^20.19.0 || >=22.12.0"
103
103
  },
@@ -1,17 +0,0 @@
1
- import { PackageJsonRuleModule } from "../createRule.js";
2
-
3
- //#region src/rules/valid-bin.d.ts
4
- declare const rule: PackageJsonRuleModule<[({
5
- enforceCase?: boolean | undefined;
6
- } | undefined)?], [{
7
- readonly additionalProperties: false;
8
- readonly properties: {
9
- readonly enforceCase: {
10
- readonly description: "Enforce that the bin's keys should be in kebab case.";
11
- readonly type: "boolean";
12
- };
13
- };
14
- readonly type: "object";
15
- }]>;
16
- //#endregion
17
- export { rule };
@@ -1,62 +0,0 @@
1
- import { createRule } from "../createRule.js";
2
- import { formatErrors } from "../utils/formatErrors.js";
3
- import { kebabCase } from "change-case";
4
- import { validateBin } from "package-json-validator";
5
-
6
- //#region src/rules/valid-bin.ts
7
- const rule = createRule({
8
- create(context) {
9
- const shouldEnforceCase = !!context.options[0]?.enforceCase;
10
- return { "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=bin]"(node) {
11
- const binValueNode = node.value;
12
- const errors = validateBin(JSON.parse(context.sourceCode.getText(binValueNode)));
13
- if (errors.length) context.report({
14
- data: { errors: formatErrors(errors) },
15
- messageId: "validationError",
16
- node: binValueNode
17
- });
18
- if (shouldEnforceCase && node.value.type === "JSONObjectExpression") for (const property of node.value.properties) {
19
- const key = property.key;
20
- const kebabCaseKey = kebabCase(key.value);
21
- if (kebabCaseKey !== key.value) context.report({
22
- data: { property: key.value },
23
- messageId: "invalidCase",
24
- node: key,
25
- suggest: [{
26
- fix: (fixer) => {
27
- return fixer.replaceText(key, JSON.stringify(kebabCaseKey));
28
- },
29
- messageId: "convertToKebabCase"
30
- }]
31
- });
32
- }
33
- } };
34
- },
35
- meta: {
36
- defaultOptions: [{ enforceCase: false }],
37
- docs: {
38
- category: "Best Practices",
39
- description: "Enforce that the `bin` property is valid.",
40
- recommended: true
41
- },
42
- hasSuggestions: true,
43
- messages: {
44
- convertToKebabCase: "Convert command name to kebab case.",
45
- invalidCase: "Command name {{ property }} should be in kebab case.",
46
- validationError: "Invalid bin: {{ errors }}"
47
- },
48
- schema: [{
49
- additionalProperties: false,
50
- properties: { enforceCase: {
51
- description: "Enforce that the bin's keys should be in kebab case.",
52
- type: "boolean"
53
- } },
54
- type: "object"
55
- }],
56
- type: "problem"
57
- },
58
- name: "valid-bin"
59
- });
60
-
61
- //#endregion
62
- export { rule };