eslint-plugin-package-json 0.63.0 β†’ 0.65.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,28 @@
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.65.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.64.0...v0.65.0) (2025-11-08)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **valid-bin, valid-bundleDependencies:** improve report precision ([#1360](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1360)) ([3d0bd1e](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/3d0bd1e04b935d30e85823dcf8c8d682ea4ab8d2)), closes [#000](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/000)
9
+
10
+
11
+ ### Features
12
+
13
+ * **no-redundant-publishConfig:** add new rule ([#1366](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1366)) ([8d3680c](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/8d3680c5fb0df0af37744cf86201163aee372bab)), closes [#1365](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1365)
4
14
 
15
+ # [0.64.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.63.0...v0.64.0) (2025-11-04)
16
+
17
+ ### Features
18
+
19
+ - **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)
20
+
21
+ # [0.63.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.62.0...v0.63.0) (2025-11-04)
5
22
 
6
23
  ### Features
7
24
 
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)
25
+ - **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
26
 
10
27
  # [0.62.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.61.0...v0.62.0) (2025-11-03)
11
28
 
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  <p align="center">
9
9
  <!-- prettier-ignore-start -->
10
10
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
11
- <a href="#contributors" target="_blank"><img alt="πŸ‘ͺ All Contributors: 31" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-31-21bb42.svg" /></a>
11
+ <a href="#contributors" target="_blank"><img alt="πŸ‘ͺ All Contributors: 32" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-32-21bb42.svg" /></a>
12
12
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
13
13
  <!-- prettier-ignore-end -->
14
14
  <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🀝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
@@ -183,9 +183,11 @@ 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. | βœ”οΈ βœ… | | πŸ’‘ | |
190
+ | [no-redundant-publishConfig](docs/rules/no-redundant-publishConfig.md) | Warns when publishConfig.access is used in unscoped packages. | βœ”οΈ βœ… | | πŸ’‘ | |
189
191
  | [order-properties](docs/rules/order-properties.md) | Package properties must be declared in standard order | βœ”οΈ βœ… | πŸ”§ | | |
190
192
  | [repository-shorthand](docs/rules/repository-shorthand.md) | Enforce either object or shorthand declaration for repository. | βœ”οΈ βœ… | πŸ”§ | | |
191
193
  | [require-author](docs/rules/require-author.md) | Requires the `author` property to be present. | | | | |
@@ -210,7 +212,7 @@ The default settings don't conflict, and Prettier plugins can quickly fix up ord
210
212
  | [sort-collections](docs/rules/sort-collections.md) | Selected collections must be in a consistent order (lexicographical for most; lifecycle-aware for scripts). | βœ”οΈ βœ… | πŸ”§ | | |
211
213
  | [unique-dependencies](docs/rules/unique-dependencies.md) | Checks a dependency isn't specified more than once (i.e. in `dependencies` and `devDependencies`) | βœ”οΈ βœ… | | πŸ’‘ | |
212
214
  | [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. | βœ”οΈ βœ… | | πŸ’‘ | |
215
+ | [valid-bin](docs/rules/valid-bin.md) | Enforce that the `bin` property is valid. | βœ”οΈ βœ… | | | |
214
216
  | [valid-bundleDependencies](docs/rules/valid-bundleDependencies.md) | Enforce that the `bundleDependencies` (also: `bundledDependencies`) property is valid. | βœ”οΈ βœ… | | | |
215
217
  | [valid-config](docs/rules/valid-config.md) | Enforce that the `config` property is valid. | βœ”οΈ βœ… | | | |
216
218
  | [valid-cpu](docs/rules/valid-cpu.md) | Enforce that the `cpu` property is valid. | βœ”οΈ βœ… | | | |
@@ -275,36 +277,37 @@ Thanks! πŸ—‚
275
277
  <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>
276
278
  <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>
277
279
  <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> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=anomiex" title="Code">πŸ’»</a></td>
278
- <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>
280
+ <td align="center" valign="top" width="14.28%"><a href="https://christopher-buss.gitbook.io/portfolio"><img src="https://avatars.githubusercontent.com/u/32301681?v=4?s=100" width="100px;" alt="Christopher Buss"/><br /><sub><b>Christopher Buss</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Achristopher-buss" title="Bug reports">πŸ›</a></td>
279
281
  </tr>
280
282
  <tr>
283
+ <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>
281
284
  <td align="center" valign="top" width="14.28%"><a href="https://davidlj95.com"><img src="https://avatars.githubusercontent.com/u/8050648?v=4?s=100" width="100px;" alt="David LJ"/><br /><sub><b>David LJ</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=davidlj95" title="Documentation">πŸ“–</a></td>
282
285
  <td align="center" valign="top" width="14.28%"><a href="http://lishaduck.github.io"><img src="https://avatars.githubusercontent.com/u/88557639?v=4?s=100" width="100px;" alt="Eli"/><br /><sub><b>Eli</b></sub></a><br /><a href="#ideas-lishaduck" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Alishaduck" title="Bug reports">πŸ›</a></td>
283
286
  <td align="center" valign="top" width="14.28%"><a href="http://heggria.site"><img src="https://avatars.githubusercontent.com/u/34475327?v=4?s=100" width="100px;" alt="Heggria"/><br /><sub><b>Heggria</b></sub></a><br /><a href="#ideas-heggria" title="Ideas, Planning, & Feedback">πŸ€”</a></td>
284
287
  <td align="center" valign="top" width="14.28%"><a href="https://hirok.io"><img src="https://avatars.githubusercontent.com/u/1075694?v=4?s=100" width="100px;" alt="Hiroki Osame"/><br /><sub><b>Hiroki Osame</b></sub></a><br /><a href="#ideas-privatenumber" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=privatenumber" title="Code">πŸ’»</a></td>
285
288
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/Zamiell"><img src="https://avatars.githubusercontent.com/u/5511220?v=4?s=100" width="100px;" alt="James"/><br /><sub><b>James</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=Zamiell" title="Code">πŸ’»</a> <a href="#ideas-Zamiell" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3AZamiell" title="Bug reports">πŸ›</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=Zamiell" title="Documentation">πŸ“–</a></td>
286
289
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/zetlen"><img src="https://avatars.githubusercontent.com/u/1643758?v=4?s=100" width="100px;" alt="James Zetlen"/><br /><sub><b>James Zetlen</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=zetlen" title="Code">πŸ’»</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Azetlen" title="Bug reports">πŸ›</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=zetlen" title="Documentation">πŸ“–</a> <a href="#infra-zetlen" title="Infrastructure (Hosting, Build-Tools, etc)">πŸš‡</a> <a href="#maintenance-zetlen" title="Maintenance">🚧</a> <a href="#tool-zetlen" title="Tools">πŸ”§</a></td>
287
- <td align="center" valign="top" width="14.28%"><a href="https://piranna.github.io/"><img src="https://avatars.githubusercontent.com/u/532414?v=4?s=100" width="100px;" alt="JesΓΊs LeganΓ©s-Combarro"/><br /><sub><b>JesΓΊs LeganΓ©s-Combarro</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=piranna" title="Code">πŸ’»</a></td>
288
290
  </tr>
289
291
  <tr>
292
+ <td align="center" valign="top" width="14.28%"><a href="https://piranna.github.io/"><img src="https://avatars.githubusercontent.com/u/532414?v=4?s=100" width="100px;" alt="JesΓΊs LeganΓ©s-Combarro"/><br /><sub><b>JesΓΊs LeganΓ©s-Combarro</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=piranna" title="Code">πŸ’»</a></td>
290
293
  <td align="center" valign="top" width="14.28%"><a href="http://www.joshuakgoldberg.com/"><img src="https://avatars.githubusercontent.com/u/3335181?v=4?s=100" width="100px;" alt="Josh Goldberg ✨"/><br /><sub><b>Josh Goldberg ✨</b></sub></a><br /><a href="#tool-JoshuaKGoldberg" title="Tools">πŸ”§</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3AJoshuaKGoldberg" title="Bug reports">πŸ›</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=JoshuaKGoldberg" title="Code">πŸ’»</a> <a href="#infra-JoshuaKGoldberg" title="Infrastructure (Hosting, Build-Tools, etc)">πŸš‡</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=JoshuaKGoldberg" title="Documentation">πŸ“–</a> <a href="#maintenance-JoshuaKGoldberg" title="Maintenance">🚧</a> <a href="#ideas-JoshuaKGoldberg" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="#content-JoshuaKGoldberg" title="Content">πŸ–‹</a> <a href="#projectManagement-JoshuaKGoldberg" title="Project Management">πŸ“†</a></td>
291
294
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/kendallgassner"><img src="https://avatars.githubusercontent.com/u/15275462?v=4?s=100" width="100px;" alt="Kendall Gassner"/><br /><sub><b>Kendall Gassner</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=kendallgassner" title="Code">πŸ’»</a> <a href="#maintenance-kendallgassner" title="Maintenance">🚧</a></td>
292
295
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/KristjanESPERANTO"><img src="https://avatars.githubusercontent.com/u/35647502?v=4?s=100" width="100px;" alt="Kristjan ESPERANTO"/><br /><sub><b>Kristjan ESPERANTO</b></sub></a><br /><a href="#ideas-kristjanesperanto" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Akristjanesperanto" title="Bug reports">πŸ›</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=kristjanesperanto" title="Code">πŸ’»</a></td>
293
296
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/lo1tuma"><img src="https://avatars.githubusercontent.com/u/169170?v=4?s=100" width="100px;" alt="Mathias Schreck"/><br /><sub><b>Mathias Schreck</b></sub></a><br /><a href="#ideas-lo1tuma" title="Ideas, Planning, & Feedback">πŸ€”</a></td>
294
297
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/Cellule"><img src="https://avatars.githubusercontent.com/u/4157103?v=4?s=100" width="100px;" alt="Michael "Mike" Ferris"/><br /><sub><b>Michael "Mike" Ferris</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=cellule" title="Code">πŸ’»</a></td>
295
298
  <td align="center" valign="top" width="14.28%"><a href="https://morrisoncole.co.uk"><img src="https://avatars.githubusercontent.com/u/963368?v=4?s=100" width="100px;" alt="Morrison Cole"/><br /><sub><b>Morrison Cole</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3AMorrisonCole" title="Bug reports">πŸ›</a></td>
296
- <td align="center" valign="top" width="14.28%"><a href="https://github.com/nschonni"><img src="https://avatars.githubusercontent.com/u/1297909?v=4?s=100" width="100px;" alt="Nick Schonning"/><br /><sub><b>Nick Schonning</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=nschonni" title="Code">πŸ’»</a></td>
297
299
  </tr>
298
300
  <tr>
301
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/nschonni"><img src="https://avatars.githubusercontent.com/u/1297909?v=4?s=100" width="100px;" alt="Nick Schonning"/><br /><sub><b>Nick Schonning</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=nschonni" title="Code">πŸ’»</a></td>
299
302
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/rakleed"><img src="https://avatars.githubusercontent.com/u/19418601?v=4?s=100" width="100px;" alt="Pavel"/><br /><sub><b>Pavel</b></sub></a><br /><a href="#ideas-rakleed" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="#tool-rakleed" title="Tools">πŸ”§</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=rakleed" title="Documentation">πŸ“–</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=rakleed" title="Code">πŸ’»</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Arakleed" title="Bug reports">πŸ›</a></td>
300
303
  <td align="center" valign="top" width="14.28%"><a href="https://sasial.dev"><img src="https://avatars.githubusercontent.com/u/44125644?v=4?s=100" width="100px;" alt="Sasial"/><br /><sub><b>Sasial</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=sasial-dev" title="Code">πŸ’»</a></td>
301
304
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/sirugh"><img src="https://avatars.githubusercontent.com/u/1278869?v=4?s=100" width="100px;" alt="Stephen"/><br /><sub><b>Stephen</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=sirugh" title="Code">πŸ’»</a></td>
302
305
  <td align="center" valign="top" width="14.28%"><a href="https://hyoban.cc"><img src="https://avatars.githubusercontent.com/u/38493346?v=4?s=100" width="100px;" alt="Stephen Zhou"/><br /><sub><b>Stephen Zhou</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Ahyoban" title="Bug reports">πŸ›</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=hyoban" title="Code">πŸ’»</a> <a href="#ideas-hyoban" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=hyoban" title="Documentation">πŸ“–</a></td>
303
306
  <td align="center" valign="top" width="14.28%"><a href="https://ota-meshi.github.io/"><img src="https://avatars.githubusercontent.com/u/16508807?v=4?s=100" width="100px;" alt="Yosuke Ota"/><br /><sub><b>Yosuke Ota</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Aota-meshi" title="Bug reports">πŸ›</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=ota-meshi" title="Code">πŸ’»</a></td>
304
307
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/b3rnhard"><img src="https://avatars.githubusercontent.com/u/10774404?v=4?s=100" width="100px;" alt="b3rnhard"/><br /><sub><b>b3rnhard</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Ab3rnhard" title="Bug reports">πŸ›</a></td>
305
- <td align="center" valign="top" width="14.28%"><a href="https://github.com/chouchouji"><img src="https://avatars.githubusercontent.com/u/70570907?v=4?s=100" width="100px;" alt="chouchouji"/><br /><sub><b>chouchouji</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=chouchouji" title="Code">πŸ’»</a></td>
306
308
  </tr>
307
309
  <tr>
310
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/chouchouji"><img src="https://avatars.githubusercontent.com/u/70570907?v=4?s=100" width="100px;" alt="chouchouji"/><br /><sub><b>chouchouji</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=chouchouji" title="Code">πŸ’»</a></td>
308
311
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/michaelfaith"><img src="https://avatars.githubusercontent.com/u/8071845?v=4?s=100" width="100px;" alt="michael faith"/><br /><sub><b>michael faith</b></sub></a><br /><a href="#infra-michaelfaith" title="Infrastructure (Hosting, Build-Tools, etc)">πŸš‡</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=michaelfaith" title="Code">πŸ’»</a> <a href="#maintenance-michaelfaith" title="Maintenance">🚧</a> <a href="#ideas-michaelfaith" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Amichaelfaith" title="Bug reports">πŸ›</a> <a href="#tool-michaelfaith" title="Tools">πŸ”§</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=michaelfaith" title="Documentation">πŸ“–</a></td>
309
312
  <td align="center" valign="top" width="14.28%"><a href="https://roottool.vercel.app"><img src="https://avatars.githubusercontent.com/u/11808736?v=4?s=100" width="100px;" alt="roottool"/><br /><sub><b>roottool</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=roottool" title="Code">πŸ’»</a></td>
310
313
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/sunnytsang1998"><img src="https://avatars.githubusercontent.com/u/207208443?v=4?s=100" width="100px;" alt="sunnytsang1998"/><br /><sub><b>sunnytsang1998</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Asunnytsang1998" title="Bug reports">πŸ›</a></td>
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/no-redundant-publishConfig.js";
6
+ import { rule as rule$5 } from "./rules/order-properties.js";
7
+ import { rule as rule$6 } from "./rules/repository-shorthand.js";
6
8
  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";
9
+ import { rule as rule$7 } from "./rules/restrict-dependency-ranges.js";
10
+ import { rule as rule$8 } from "./rules/restrict-private-properties.js";
11
+ import { rule as rule$9 } from "./rules/scripts-name-casing.js";
12
+ import { rule as rule$10 } from "./rules/sort-collections.js";
13
+ import { rule as rule$11 } from "./rules/unique-dependencies.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
+ "no-redundant-publishConfig": rule$4,
31
+ "order-properties": rule$5,
30
32
  ...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,
33
+ "repository-shorthand": rule$6,
34
+ "restrict-dependency-ranges": rule$7,
35
+ "restrict-private-properties": rule$8,
36
+ "scripts-name-casing": rule$9,
37
+ "sort-collections": rule$10,
38
+ "unique-dependencies": rule$11,
37
39
  ...rules$1,
38
- "valid-author": rule$10,
39
- "valid-bin": rule$11,
40
40
  "valid-local-dependency": rule$12,
41
41
  "valid-name": rule$13,
42
42
  "valid-package-definition": rule$14,
@@ -1,6 +1,6 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
- //#region src/rules/valid-author.d.ts
3
+ //#region src/rules/bin-name-casing.d.ts
4
4
  declare const rule: PackageJsonRuleModule<[], []>;
5
5
  //#endregion
6
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 };
@@ -0,0 +1,6 @@
1
+ import { PackageJsonRuleModule } from "../createRule.js";
2
+
3
+ //#region src/rules/no-redundant-publishConfig.d.ts
4
+ declare const rule: PackageJsonRuleModule<[], []>;
5
+ //#endregion
6
+ export { rule };
@@ -0,0 +1,52 @@
1
+ import { createRule } from "../createRule.js";
2
+ import { isJSONStringLiteral } from "../utils/predicates.js";
3
+ import { fixRemoveObjectProperty } from "eslint-fix-utils";
4
+
5
+ //#region src/rules/no-redundant-publishConfig.ts
6
+ const rule = createRule({
7
+ create(context) {
8
+ let packageName;
9
+ let publishConfigAccessProperty;
10
+ return {
11
+ "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=name]"(node) {
12
+ if (isJSONStringLiteral(node.value)) packageName = node.value.value;
13
+ },
14
+ "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=publishConfig]"(node) {
15
+ if (node.value.type !== "JSONObjectExpression") return;
16
+ for (const property of node.value.properties) if (isJSONStringLiteral(property.key) && property.key.value === "access") {
17
+ publishConfigAccessProperty = property;
18
+ break;
19
+ }
20
+ },
21
+ "Program:exit"() {
22
+ if (!packageName || !publishConfigAccessProperty) return;
23
+ if (!packageName.startsWith("@")) context.report({
24
+ messageId: "redundantAccess",
25
+ node: publishConfigAccessProperty,
26
+ suggest: [{
27
+ fix: fixRemoveObjectProperty(context, publishConfigAccessProperty),
28
+ messageId: "removeAccess"
29
+ }]
30
+ });
31
+ }
32
+ };
33
+ },
34
+ meta: {
35
+ docs: {
36
+ category: "Best Practices",
37
+ description: "Warns when publishConfig.access is used in unscoped packages.",
38
+ recommended: true
39
+ },
40
+ hasSuggestions: true,
41
+ messages: {
42
+ redundantAccess: "'publishConfig.access' is redundant for unscoped packages - they are always public.",
43
+ removeAccess: "Remove the redundant 'access' field."
44
+ },
45
+ schema: [],
46
+ type: "suggestion"
47
+ },
48
+ name: "no-redundant-publishConfig"
49
+ });
50
+
51
+ //#endregion
52
+ export { rule };
@@ -3,7 +3,7 @@ import { PackageJsonRuleModule } from "../createRule.js";
3
3
  //#region src/rules/valid-properties.d.ts
4
4
  /** All basic valid- flavor rules */
5
5
  declare const rules: {
6
- [k: string]: PackageJsonRuleModule<[], []>;
6
+ [x: string]: PackageJsonRuleModule<[], []>;
7
7
  };
8
8
  //#endregion
9
9
  export { rules };
@@ -1,12 +1,8 @@
1
- import { createSimpleValidPropertyRule } from "../utils/createSimpleValidPropertyRule.js";
2
- import { validateBundleDependencies, validateConfig, validateCpu, validateDependencies, validateDescription, validateDirectories, validateExports, validateLicense, validateScripts, validateType } from "package-json-validator";
1
+ import { createLegacySimpleValidPropertyRule, createSimpleValidPropertyRule } from "../utils/createSimpleValidPropertyRule.js";
2
+ import { validateAuthor, 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
- const properties = [
6
- ["bundleDependencies", {
7
- aliases: ["bundledDependencies"],
8
- validator: validateBundleDependencies
9
- }],
5
+ const legacyProperties = [
10
6
  ["config", validateConfig],
11
7
  ["cpu", validateCpu],
12
8
  ["dependencies", validateDependencies],
@@ -20,17 +16,32 @@ const properties = [
20
16
  ["scripts", validateScripts],
21
17
  ["type", validateType]
22
18
  ];
23
- /** All basic valid- flavor rules */
24
- const rules = Object.fromEntries(properties.map(([propertyName, validationFunctionOrOptions]) => {
25
- let validationFunction;
26
- let aliases = [];
27
- if (typeof validationFunctionOrOptions === "object") {
28
- validationFunction = validationFunctionOrOptions.validator;
29
- aliases = validationFunctionOrOptions.aliases;
30
- } else validationFunction = validationFunctionOrOptions;
31
- const { rule, ruleName } = createSimpleValidPropertyRule(propertyName, validationFunction, aliases);
19
+ const legacyRules = Object.fromEntries(legacyProperties.map(([propertyName, validationFunction]) => {
20
+ const { rule, ruleName } = createLegacySimpleValidPropertyRule(propertyName, validationFunction);
32
21
  return [ruleName, rule];
33
22
  }));
23
+ const properties = [
24
+ ["author", validateAuthor],
25
+ ["bin", validateBin],
26
+ ["bundleDependencies", {
27
+ aliases: ["bundledDependencies"],
28
+ validator: validateBundleDependencies
29
+ }]
30
+ ];
31
+ /** All basic valid- flavor rules */
32
+ const rules = {
33
+ ...legacyRules,
34
+ ...Object.fromEntries(properties.map(([propertyName, validationFunctionOrOptions]) => {
35
+ let validationFunction;
36
+ let aliases = [];
37
+ if (typeof validationFunctionOrOptions === "object") {
38
+ validationFunction = validationFunctionOrOptions.validator;
39
+ aliases = validationFunctionOrOptions.aliases;
40
+ } else validationFunction = validationFunctionOrOptions;
41
+ const { rule, ruleName } = createSimpleValidPropertyRule(propertyName, validationFunction, aliases);
42
+ return [ruleName, rule];
43
+ }))
44
+ };
34
45
 
35
46
  //#endregion
36
47
  export { rules };
@@ -1,7 +1,9 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
+ import { Result } from "package-json-validator";
2
3
 
3
4
  //#region src/utils/createSimpleValidPropertyRule.d.ts
4
- type ValidationFunction = (value: unknown) => string[];
5
+ type LegacyValidationFunction = (value: unknown) => string[];
6
+ type ValidationFunction = (value: unknown) => Result;
5
7
  /**
6
8
  * Given a top-level property name, and a validation function, create a rule that validates the property using the validation function.
7
9
  * These rules will always be included in the recommended config.
@@ -12,5 +14,15 @@ declare const createSimpleValidPropertyRule: (propertyName: string, validationFu
12
14
  rule: PackageJsonRuleModule<[], []>;
13
15
  ruleName: string;
14
16
  };
17
+ /**
18
+ * Given a top-level property name, and a validation function, create a rule that validates the property using the validation function.
19
+ * These rules will always be included in the recommended config.
20
+ * Note: this will only create a basic validation rule, with no options. If you need
21
+ * to create a more complex rule, create it in its own file.
22
+ */
23
+ declare const createLegacySimpleValidPropertyRule: (propertyName: string, validationFunction: LegacyValidationFunction, aliases?: string[]) => {
24
+ rule: PackageJsonRuleModule<[], []>;
25
+ ruleName: string;
26
+ };
15
27
  //#endregion
16
- export { ValidationFunction, createSimpleValidPropertyRule };
28
+ export { LegacyValidationFunction, ValidationFunction, createLegacySimpleValidPropertyRule, createSimpleValidPropertyRule };
@@ -9,6 +9,58 @@ import { formatErrors } from "./formatErrors.js";
9
9
  * to create a more complex rule, create it in its own file.
10
10
  */
11
11
  const createSimpleValidPropertyRule = (propertyName, validationFunction, aliases = []) => {
12
+ const ruleName = `valid-${propertyName}`;
13
+ const propertyNames = [propertyName, ...aliases];
14
+ return {
15
+ rule: createRule({
16
+ create(context) {
17
+ const reportIssues = (result, node) => {
18
+ if (result.errorMessages.length === 0) return;
19
+ if (result.issues.length) for (const issue of result.issues) context.report({
20
+ data: { error: issue.message },
21
+ messageId: "validationError",
22
+ node
23
+ });
24
+ const childrenWithIssues = result.childResults.filter((childResult) => childResult.errorMessages.length);
25
+ if (node.type === "JSONObjectExpression" && childrenWithIssues.length) for (const childResult of childrenWithIssues) {
26
+ const childNode = node.properties[childResult.index];
27
+ reportIssues(childResult, childNode);
28
+ }
29
+ else if (node.type === "JSONArrayExpression" && childrenWithIssues.length) for (const childResult of childrenWithIssues) {
30
+ const childNode = node.elements[childResult.index];
31
+ if (childNode) reportIssues(childResult, childNode);
32
+ }
33
+ };
34
+ return propertyNames.reduce((acc, name) => {
35
+ acc[`Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=${name}]`] = (node) => {
36
+ const valueNode = node.value;
37
+ reportIssues(validationFunction(JSON.parse(context.sourceCode.getText(valueNode))), valueNode);
38
+ };
39
+ return acc;
40
+ }, {});
41
+ },
42
+ meta: {
43
+ docs: {
44
+ category: "Best Practices",
45
+ description: `Enforce that the \`${propertyName}\`${aliases.length ? ` (also: ${aliases.map((alias) => `\`${alias}\``).join(", ")})` : ""} property is valid.`,
46
+ recommended: true
47
+ },
48
+ messages: { validationError: `Invalid ${propertyName}: {{ error }}` },
49
+ schema: [],
50
+ type: "problem"
51
+ },
52
+ name: ruleName
53
+ }),
54
+ ruleName
55
+ };
56
+ };
57
+ /**
58
+ * Given a top-level property name, and a validation function, create a rule that validates the property using the validation function.
59
+ * These rules will always be included in the recommended config.
60
+ * Note: this will only create a basic validation rule, with no options. If you need
61
+ * to create a more complex rule, create it in its own file.
62
+ */
63
+ const createLegacySimpleValidPropertyRule = (propertyName, validationFunction, aliases = []) => {
12
64
  const ruleName = `valid-${propertyName}`;
13
65
  const propertyNames = [propertyName, ...aliases];
14
66
  return {
@@ -44,4 +96,4 @@ const createSimpleValidPropertyRule = (propertyName, validationFunction, aliases
44
96
  };
45
97
 
46
98
  //#endregion
47
- export { createSimpleValidPropertyRule };
99
+ export { createLegacySimpleValidPropertyRule, createSimpleValidPropertyRule };
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.65.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": {
@@ -48,7 +48,7 @@
48
48
  "detect-indent": "^7.0.2",
49
49
  "detect-newline": "^4.0.1",
50
50
  "eslint-fix-utils": "~0.4.0",
51
- "package-json-validator": "~0.32.1",
51
+ "package-json-validator": "~0.34.0",
52
52
  "semver": "^7.7.3",
53
53
  "sort-object-keys": "^2.0.0",
54
54
  "sort-package-json": "^3.4.0",
@@ -63,7 +63,7 @@
63
63
  "@types/semver": "7.7.0",
64
64
  "@types/validate-npm-package-name": "4.0.2",
65
65
  "@vitest/coverage-v8": "4.0.4",
66
- "@vitest/eslint-plugin": "1.3.3",
66
+ "@vitest/eslint-plugin": "1.4.0",
67
67
  "console-fail-test": "0.5.0",
68
68
  "eslint": "9.38.0",
69
69
  "eslint-doc-generator": "2.3.0",
@@ -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,39 +0,0 @@
1
- import { createRule } from "../createRule.js";
2
- import { validateAuthor } from "package-json-validator";
3
-
4
- //#region src/rules/valid-author.ts
5
- const rule = createRule({
6
- create(context) {
7
- const reportIssues = (result, node) => {
8
- if (result.errorMessages.length === 0) return;
9
- if (result.issues.length) for (const issue of result.issues) context.report({
10
- data: { error: issue.message },
11
- messageId: "validationError",
12
- node
13
- });
14
- const childrenWithIssues = result.childResults.filter((childResult) => childResult.errorMessages.length);
15
- if (node.type === "JSONObjectExpression" && childrenWithIssues.length) for (const childResult of childrenWithIssues) {
16
- const childNode = node.properties[childResult.index];
17
- reportIssues(childResult, childNode);
18
- }
19
- };
20
- return { "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=author]"(node) {
21
- const valueNode = node.value;
22
- reportIssues(validateAuthor(JSON.parse(context.sourceCode.getText(valueNode))), valueNode);
23
- } };
24
- },
25
- meta: {
26
- docs: {
27
- category: "Best Practices",
28
- description: "Enforce that the `author` property is valid.",
29
- recommended: true
30
- },
31
- messages: { validationError: `Invalid author: {{ error }}` },
32
- schema: [],
33
- type: "problem"
34
- },
35
- name: "valid-author"
36
- });
37
-
38
- //#endregion
39
- export { rule };
@@ -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 };