eslint-plugin-package-json 0.29.0 → 0.30.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.
Files changed (86) hide show
  1. package/README.md +43 -39
  2. package/lib/createRule.js +0 -1
  3. package/lib/createRule.mjs +0 -1
  4. package/lib/index.js +0 -1
  5. package/lib/index.mjs +0 -1
  6. package/lib/plugin.js +2 -1
  7. package/lib/plugin.mjs +2 -1
  8. package/lib/rules/no-empty-fields.js +0 -1
  9. package/lib/rules/no-empty-fields.mjs +0 -1
  10. package/lib/rules/no-redundant-files.js +0 -1
  11. package/lib/rules/no-redundant-files.mjs +0 -1
  12. package/lib/rules/order-properties.js +0 -1
  13. package/lib/rules/order-properties.mjs +0 -1
  14. package/lib/rules/repository-shorthand.js +0 -1
  15. package/lib/rules/repository-shorthand.mjs +0 -1
  16. package/lib/rules/require-properties.js +0 -1
  17. package/lib/rules/require-properties.mjs +0 -1
  18. package/lib/rules/restrict-dependency-ranges.d.mts +20 -0
  19. package/lib/rules/restrict-dependency-ranges.d.ts +20 -0
  20. package/lib/rules/restrict-dependency-ranges.js +239 -0
  21. package/lib/rules/restrict-dependency-ranges.mjs +205 -0
  22. package/lib/rules/sort-collections.js +0 -1
  23. package/lib/rules/sort-collections.mjs +0 -1
  24. package/lib/rules/unique-dependencies.js +0 -1
  25. package/lib/rules/unique-dependencies.mjs +0 -1
  26. package/lib/rules/valid-local-dependency.js +0 -1
  27. package/lib/rules/valid-local-dependency.mjs +0 -1
  28. package/lib/rules/valid-name.js +0 -1
  29. package/lib/rules/valid-name.mjs +0 -1
  30. package/lib/rules/valid-package-definition.js +0 -1
  31. package/lib/rules/valid-package-definition.mjs +0 -1
  32. package/lib/rules/valid-repository-directory.js +0 -1
  33. package/lib/rules/valid-repository-directory.mjs +0 -1
  34. package/lib/rules/valid-version.js +0 -1
  35. package/lib/rules/valid-version.mjs +0 -1
  36. package/lib/tests/rules/ruleTester.js +4 -1
  37. package/lib/tests/rules/ruleTester.mjs +4 -1
  38. package/lib/utils/createRequirePropertyRule.js +0 -1
  39. package/lib/utils/createRequirePropertyRule.mjs +0 -1
  40. package/lib/utils/findPropertyWithKeyValue.js +0 -1
  41. package/lib/utils/findPropertyWithKeyValue.mjs +0 -1
  42. package/lib/utils/isPackageJson.js +0 -1
  43. package/lib/utils/isPackageJson.mjs +0 -1
  44. package/lib/utils/predicates.js +0 -1
  45. package/lib/utils/predicates.mjs +0 -1
  46. package/package.json +56 -48
  47. package/lib/createRule.js.map +0 -1
  48. package/lib/createRule.mjs.map +0 -1
  49. package/lib/index.js.map +0 -1
  50. package/lib/index.mjs.map +0 -1
  51. package/lib/plugin.js.map +0 -1
  52. package/lib/plugin.mjs.map +0 -1
  53. package/lib/rules/no-empty-fields.js.map +0 -1
  54. package/lib/rules/no-empty-fields.mjs.map +0 -1
  55. package/lib/rules/no-redundant-files.js.map +0 -1
  56. package/lib/rules/no-redundant-files.mjs.map +0 -1
  57. package/lib/rules/order-properties.js.map +0 -1
  58. package/lib/rules/order-properties.mjs.map +0 -1
  59. package/lib/rules/repository-shorthand.js.map +0 -1
  60. package/lib/rules/repository-shorthand.mjs.map +0 -1
  61. package/lib/rules/require-properties.js.map +0 -1
  62. package/lib/rules/require-properties.mjs.map +0 -1
  63. package/lib/rules/sort-collections.js.map +0 -1
  64. package/lib/rules/sort-collections.mjs.map +0 -1
  65. package/lib/rules/unique-dependencies.js.map +0 -1
  66. package/lib/rules/unique-dependencies.mjs.map +0 -1
  67. package/lib/rules/valid-local-dependency.js.map +0 -1
  68. package/lib/rules/valid-local-dependency.mjs.map +0 -1
  69. package/lib/rules/valid-name.js.map +0 -1
  70. package/lib/rules/valid-name.mjs.map +0 -1
  71. package/lib/rules/valid-package-definition.js.map +0 -1
  72. package/lib/rules/valid-package-definition.mjs.map +0 -1
  73. package/lib/rules/valid-repository-directory.js.map +0 -1
  74. package/lib/rules/valid-repository-directory.mjs.map +0 -1
  75. package/lib/rules/valid-version.js.map +0 -1
  76. package/lib/rules/valid-version.mjs.map +0 -1
  77. package/lib/tests/rules/ruleTester.js.map +0 -1
  78. package/lib/tests/rules/ruleTester.mjs.map +0 -1
  79. package/lib/utils/createRequirePropertyRule.js.map +0 -1
  80. package/lib/utils/createRequirePropertyRule.mjs.map +0 -1
  81. package/lib/utils/findPropertyWithKeyValue.js.map +0 -1
  82. package/lib/utils/findPropertyWithKeyValue.mjs.map +0 -1
  83. package/lib/utils/isPackageJson.js.map +0 -1
  84. package/lib/utils/isPackageJson.mjs.map +0 -1
  85. package/lib/utils/predicates.js.map +0 -1
  86. package/lib/utils/predicates.mjs.map +0 -1
package/README.md CHANGED
@@ -1,20 +1,21 @@
1
1
  <h1 align="center">eslint-plugin-package-json</h1>
2
2
 
3
- <p align="center">Rules for consistent, readable, and valid package.json files. 🗂️</p>
3
+ <p align="center">
4
+ Rules for consistent, readable, and valid package.json files.
5
+ 🗂️
6
+ </p>
4
7
 
5
8
  <p align="center">
6
- <a href="#contributors" target="_blank">
7
- <!-- prettier-ignore-start -->
8
- <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
9
- <img alt="All Contributors: 23 👪" src="https://img.shields.io/badge/all_contributors-23_👪-21bb42.svg" />
9
+ <!-- prettier-ignore-start -->
10
+ <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
11
+ <a href="#contributors" target="_blank"><img alt="👪 All Contributors: 24" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-24-21bb42.svg" /></a>
10
12
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
11
- <!-- prettier-ignore-end -->
12
- </a>
13
- <a href="https://codecov.io/gh/JoshuaKGoldberg/eslint-plugin-package-json" target="_blank"><img alt="Codecov Test Coverage" src="https://codecov.io/gh/JoshuaKGoldberg/eslint-plugin-package-json/branch/main/graph/badge.svg"/></a>
14
- <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="Contributor Covenant" src="https://img.shields.io/badge/code_of_conduct-enforced-21bb42" /></a>
15
- <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/blob/main/LICENSE.md" target="_blank"><img alt="License: MIT" src="https://img.shields.io/github/license/JoshuaKGoldberg/eslint-plugin-package-json?color=21bb42"></a>
16
- <img alt="Style: Prettier" src="https://img.shields.io/badge/style-prettier-21bb42.svg" />
17
- <a href="https://www.npmjs.com/package/eslint-plugin-package-json"><img alt="npm package version" src="https://img.shields.io/npm/v/eslint-plugin-package-json?color=21bb42" /></a>
13
+ <!-- prettier-ignore-end -->
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>
15
+ <a href="https://codecov.io/gh/JoshuaKGoldberg/eslint-plugin-package-json" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/JoshuaKGoldberg/eslint-plugin-package-json?label=%F0%9F%A7%AA%20coverage" /></a>
16
+ <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg" /></a>
17
+ <a href="http://npmjs.com/package/eslint-plugin-package-json" target="_blank"><img alt="📦 npm version" src="https://img.shields.io/npm/v/eslint-plugin-package-json?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
18
+ <img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
18
19
  </p>
19
20
 
20
21
  ## Installation
@@ -70,7 +71,7 @@ npm install jsonc-eslint-parser --save-dev
70
71
 
71
72
  Add an override to your ESLint configuration file that specifies `jsonc-eslint-parser`, this plugin, and its recommended rules for your `package.json` file:
72
73
 
73
- ```js
74
+ ```ts
74
75
  module.exports = {
75
76
  overrides: [
76
77
  {
@@ -85,7 +86,7 @@ module.exports = {
85
86
  You may also want to individually configure rules.
86
87
  See [ESLint's _Configure Rules_ guide](https://eslint.org/docs/latest/use/configure/rules) for details on how to customize your rules.
87
88
 
88
- ```js
89
+ ```ts
89
90
  module.exports = {
90
91
  overrides: [
91
92
  {
@@ -112,32 +113,34 @@ The default settings don't conflict, and Prettier plugins can quickly fix up ord
112
113
  <!-- begin auto-generated rules list -->
113
114
 
114
115
  💼 Configurations enabled in.\
116
+ ✔️ Set in the `legacy-recommended` configuration.\
115
117
  ✅ Set in the `recommended` configuration.\
116
118
  🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
117
119
  💡 Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\
118
120
  ❌ Deprecated.
119
121
 
120
- | Name                       | Description | 💼 | 🔧 | 💡 | ❌ |
121
- | :--------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------ | :- | :- | :- | :- |
122
- | [no-empty-fields](docs/rules/no-empty-fields.md) | Reports on unnecessary empty arrays and objects. | ✅ | | 💡 | |
123
- | [no-redundant-files](docs/rules/no-redundant-files.md) | Prevents adding unnecessary / redundant files. | | | 💡 | |
124
- | [order-properties](docs/rules/order-properties.md) | Package properties must be declared in standard order | ✅ | 🔧 | | |
125
- | [repository-shorthand](docs/rules/repository-shorthand.md) | Enforce either object or shorthand declaration for repository. | ✅ | 🔧 | | |
126
- | [require-author](docs/rules/require-author.md) | Requires the `author` property to be present. | | | | |
127
- | [require-engines](docs/rules/require-engines.md) | Requires the `engines` property to be present. | | | | |
128
- | [require-files](docs/rules/require-files.md) | Requires the `files` property to be present. | | | | |
129
- | [require-keywords](docs/rules/require-keywords.md) | Requires the `keywords` property to be present. | | | | |
130
- | [require-name](docs/rules/require-name.md) | Requires the `name` property to be present. | ✅ | | | |
131
- | [require-types](docs/rules/require-types.md) | Requires the `types` property to be present. | | | | |
132
- | [require-version](docs/rules/require-version.md) | Requires the `version` property to be present. | ✅ | | | |
133
- | [sort-collections](docs/rules/sort-collections.md) | Dependencies, scripts, and configuration values must be declared in alphabetical order. || 🔧 | | |
134
- | [unique-dependencies](docs/rules/unique-dependencies.md) | Checks a dependency isn't specified more than once (i.e. in `dependencies` and `devDependencies`) | | | 💡 | |
135
- | [valid-local-dependency](docs/rules/valid-local-dependency.md) | Checks existence of local dependencies in the package.json | ✅ | | | |
136
- | [valid-name](docs/rules/valid-name.md) | Enforce that package names are valid npm package names | ✅ | | | |
137
- | [valid-package-def](docs/rules/valid-package-def.md) | Enforce that package.json has all properties required by the npm spec | | | | ❌ |
138
- | [valid-package-definition](docs/rules/valid-package-definition.md) | Enforce that package.json has all properties required by the npm spec || | | |
139
- | [valid-repository-directory](docs/rules/valid-repository-directory.md) | Enforce that if repository directory is specified, it matches the path to the package.json file || | 💡 | |
140
- | [valid-version](docs/rules/valid-version.md) | Enforce that package versions are valid semver specifiers | ✅ | | | |
122
+ | Name                       | Description | 💼 | 🔧 | 💡 | ❌ |
123
+ | :--------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------ | :--- | :- | :- | :- |
124
+ | [no-empty-fields](docs/rules/no-empty-fields.md) | Reports on unnecessary empty arrays and objects. | ✔️ | | 💡 | |
125
+ | [no-redundant-files](docs/rules/no-redundant-files.md) | Prevents adding unnecessary / redundant files. | | | 💡 | |
126
+ | [order-properties](docs/rules/order-properties.md) | Package properties must be declared in standard order | ✔️ | 🔧 | | |
127
+ | [repository-shorthand](docs/rules/repository-shorthand.md) | Enforce either object or shorthand declaration for repository. | ✔️ | 🔧 | | |
128
+ | [require-author](docs/rules/require-author.md) | Requires the `author` property to be present. | | | | |
129
+ | [require-engines](docs/rules/require-engines.md) | Requires the `engines` property to be present. | | | | |
130
+ | [require-files](docs/rules/require-files.md) | Requires the `files` property to be present. | | | | |
131
+ | [require-keywords](docs/rules/require-keywords.md) | Requires the `keywords` property to be present. | | | | |
132
+ | [require-name](docs/rules/require-name.md) | Requires the `name` property to be present. | ✔️ | | | |
133
+ | [require-types](docs/rules/require-types.md) | Requires the `types` property to be present. | | | | |
134
+ | [require-version](docs/rules/require-version.md) | Requires the `version` property to be present. | ✔️ | | | |
135
+ | [restrict-dependency-ranges](docs/rules/restrict-dependency-ranges.md) | Restricts the range of dependencies to allow or disallow specific types of ranges. | | | 💡 | |
136
+ | [sort-collections](docs/rules/sort-collections.md) | Dependencies, scripts, and configuration values must be declared in alphabetical order. | ✔️ | 🔧 | | |
137
+ | [unique-dependencies](docs/rules/unique-dependencies.md) | Checks a dependency isn't specified more than once (i.e. in `dependencies` and `devDependencies`) | ✔️ | | 💡 | |
138
+ | [valid-local-dependency](docs/rules/valid-local-dependency.md) | Checks existence of local dependencies in the package.json | ✔️ | | | |
139
+ | [valid-name](docs/rules/valid-name.md) | Enforce that package names are valid npm package names | ✔️ | | | |
140
+ | [valid-package-def](docs/rules/valid-package-def.md) | Enforce that package.json has all properties required by the npm spec | | | ||
141
+ | [valid-package-definition](docs/rules/valid-package-definition.md) | Enforce that package.json has all properties required by the npm spec | ✔️ | | | |
142
+ | [valid-repository-directory](docs/rules/valid-repository-directory.md) | Enforce that if repository directory is specified, it matches the path to the package.json file | ✔️ | | 💡 | |
143
+ | [valid-version](docs/rules/valid-version.md) | Enforce that package versions are valid semver specifiers | ✔️ ✅ | | | |
141
144
 
142
145
  <!-- end auto-generated rules list -->
143
146
  <!-- prettier-ignore-end -->
@@ -148,7 +151,7 @@ They can lint `package.json` files at project root and in any subfolder of the p
148
151
  ## Development
149
152
 
150
153
  See [`.github/CONTRIBUTING.md`](./.github/CONTRIBUTING.md), then [`.github/DEVELOPMENT.md`](./.github/DEVELOPMENT.md).
151
- Thanks! 💖
154
+ Thanks! 🗂
152
155
 
153
156
  ## Contributors
154
157
 
@@ -170,7 +173,7 @@ Thanks! 💖
170
173
  <tr>
171
174
  <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>
172
175
  <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>
173
- <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></td>
176
+ <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>
174
177
  <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>
175
178
  <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>
176
179
  <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>
@@ -187,7 +190,8 @@ Thanks! 💖
187
190
  </tr>
188
191
  <tr>
189
192
  <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>
190
- <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></td>
193
+ <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></td>
194
+ <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>
191
195
  </tr>
192
196
  </tbody>
193
197
  </table>
@@ -202,4 +206,4 @@ Thanks! 💖
202
206
 
203
207
  Many thanks to [@zetlen](https://github.com/zetlen) for creating the initial version and core infrastructure of this package! 💖
204
208
 
205
- > 💙 This package was templated with [create-typescript-app](https://github.com/JoshuaKGoldberg/create-typescript-app).
209
+ > 💝 This package was templated with [`create-typescript-app`](https://github.com/JoshuaKGoldberg/create-typescript-app) using the [Bingo engine](https://create.bingo).
package/lib/createRule.js CHANGED
@@ -37,4 +37,3 @@ function createRule(rule) {
37
37
  0 && (module.exports = {
38
38
  createRule
39
39
  });
40
- //# sourceMappingURL=createRule.js.map
@@ -13,4 +13,3 @@ function createRule(rule) {
13
13
  export {
14
14
  createRule
15
15
  };
16
- //# sourceMappingURL=createRule.mjs.map
package/lib/index.js CHANGED
@@ -32,4 +32,3 @@ var index_default = import_plugin.plugin;
32
32
  configs,
33
33
  rules
34
34
  });
35
- //# sourceMappingURL=index.js.map
package/lib/index.mjs CHANGED
@@ -7,4 +7,3 @@ export {
7
7
  index_default as default,
8
8
  rules
9
9
  };
10
- //# sourceMappingURL=index.mjs.map
package/lib/plugin.js CHANGED
@@ -38,6 +38,7 @@ var import_no_redundant_files = require("./rules/no-redundant-files.js");
38
38
  var import_order_properties = require("./rules/order-properties.js");
39
39
  var import_repository_shorthand = require("./rules/repository-shorthand.js");
40
40
  var import_require_properties = require("./rules/require-properties.js");
41
+ var import_restrict_dependency_ranges = require("./rules/restrict-dependency-ranges.js");
41
42
  var import_sort_collections = require("./rules/sort-collections.js");
42
43
  var import_unique_dependencies = require("./rules/unique-dependencies.js");
43
44
  var import_valid_local_dependency = require("./rules/valid-local-dependency.js");
@@ -54,6 +55,7 @@ const rules = {
54
55
  "order-properties": import_order_properties.rule,
55
56
  ...import_require_properties.rules,
56
57
  "repository-shorthand": import_repository_shorthand.rule,
58
+ "restrict-dependency-ranges": import_restrict_dependency_ranges.rule,
57
59
  "sort-collections": import_sort_collections.rule,
58
60
  "unique-dependencies": import_unique_dependencies.rule,
59
61
  "valid-local-dependency": import_valid_local_dependency.rule,
@@ -108,4 +110,3 @@ const plugin = {
108
110
  0 && (module.exports = {
109
111
  plugin
110
112
  });
111
- //# sourceMappingURL=plugin.js.map
package/lib/plugin.mjs CHANGED
@@ -5,6 +5,7 @@ import { rule as noRedundantFiles } from "./rules/no-redundant-files.js";
5
5
  import { rule as orderProperties } from "./rules/order-properties.js";
6
6
  import { rule as preferRepositoryShorthand } from "./rules/repository-shorthand.js";
7
7
  import { rules as requireRules } from "./rules/require-properties.js";
8
+ import { rule as restrictDependencyRanges } from "./rules/restrict-dependency-ranges.js";
8
9
  import { rule as sortCollections } from "./rules/sort-collections.js";
9
10
  import { rule as uniqueDependencies } from "./rules/unique-dependencies.js";
10
11
  import { rule as validLocalDependency } from "./rules/valid-local-dependency.js";
@@ -20,6 +21,7 @@ const rules = {
20
21
  "order-properties": orderProperties,
21
22
  ...requireRules,
22
23
  "repository-shorthand": preferRepositoryShorthand,
24
+ "restrict-dependency-ranges": restrictDependencyRanges,
23
25
  "sort-collections": sortCollections,
24
26
  "unique-dependencies": uniqueDependencies,
25
27
  "valid-local-dependency": validLocalDependency,
@@ -73,4 +75,3 @@ const plugin = {
73
75
  export {
74
76
  plugin
75
77
  };
76
- //# sourceMappingURL=plugin.mjs.map
@@ -107,4 +107,3 @@ const rule = (0, import_createRule.createRule)({
107
107
  0 && (module.exports = {
108
108
  rule
109
109
  });
110
- //# sourceMappingURL=no-empty-fields.js.map
@@ -86,4 +86,3 @@ const rule = createRule({
86
86
  export {
87
87
  rule
88
88
  };
89
- //# sourceMappingURL=no-empty-fields.mjs.map
@@ -164,4 +164,3 @@ const rule = (0, import_createRule.createRule)({
164
164
  0 && (module.exports = {
165
165
  rule
166
166
  });
167
- //# sourceMappingURL=no-redundant-files.js.map
@@ -140,4 +140,3 @@ const rule = createRule({
140
140
  export {
141
141
  rule
142
142
  };
143
- //# sourceMappingURL=no-redundant-files.mjs.map
@@ -155,4 +155,3 @@ const rule = (0, import_createRule.createRule)({
155
155
  0 && (module.exports = {
156
156
  rule
157
157
  });
158
- //# sourceMappingURL=order-properties.js.map
@@ -121,4 +121,3 @@ const rule = createRule({
121
121
  export {
122
122
  rule
123
123
  };
124
- //# sourceMappingURL=order-properties.mjs.map
@@ -140,4 +140,3 @@ const rule = (0, import_createRule.createRule)({
140
140
  0 && (module.exports = {
141
141
  rule
142
142
  });
143
- //# sourceMappingURL=repository-shorthand.js.map
@@ -116,4 +116,3 @@ const rule = createRule({
116
116
  export {
117
117
  rule
118
118
  };
119
- //# sourceMappingURL=repository-shorthand.mjs.map
@@ -46,4 +46,3 @@ const rules = properties.reduce(
46
46
  0 && (module.exports = {
47
47
  rules
48
48
  });
49
- //# sourceMappingURL=require-properties.js.map
@@ -22,4 +22,3 @@ const rules = properties.reduce(
22
22
  export {
23
23
  rules
24
24
  };
25
- //# sourceMappingURL=require-properties.mjs.map
@@ -0,0 +1,20 @@
1
+ import * as eslint from 'eslint';
2
+ import * as jsonc_eslint_parser from 'jsonc-eslint-parser';
3
+ import { PackageJsonRuleContext } from '../createRule.mjs';
4
+ import 'estree';
5
+
6
+ interface Option {
7
+ forDependencyTypes?: string[];
8
+ forPackages?: string[];
9
+ forVersions?: string;
10
+ rangeType: RangeType | RangeType[];
11
+ }
12
+ type Options = [Option | Option[] | undefined];
13
+ declare const RANGE_TYPES: readonly ["caret", "pin", "tilde"];
14
+ type RangeType = (typeof RANGE_TYPES)[number];
15
+ declare const rule: {
16
+ create(context: PackageJsonRuleContext<Options>): jsonc_eslint_parser.RuleListener;
17
+ meta: eslint.Rule.RuleMetaData;
18
+ };
19
+
20
+ export { rule };
@@ -0,0 +1,20 @@
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
+ interface Option {
7
+ forDependencyTypes?: string[];
8
+ forPackages?: string[];
9
+ forVersions?: string;
10
+ rangeType: RangeType | RangeType[];
11
+ }
12
+ type Options = [Option | Option[] | undefined];
13
+ declare const RANGE_TYPES: readonly ["caret", "pin", "tilde"];
14
+ type RangeType = (typeof RANGE_TYPES)[number];
15
+ declare const rule: {
16
+ create(context: PackageJsonRuleContext<Options>): jsonc_eslint_parser.RuleListener;
17
+ meta: eslint.Rule.RuleMetaData;
18
+ };
19
+
20
+ export { rule };
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var restrict_dependency_ranges_exports = {};
30
+ __export(restrict_dependency_ranges_exports, {
31
+ rule: () => rule
32
+ });
33
+ module.exports = __toCommonJS(restrict_dependency_ranges_exports);
34
+ var import_semver = __toESM(require("semver"));
35
+ var import_createRule = require("../createRule.js");
36
+ var import_predicates = require("../utils/predicates.js");
37
+ const DEPENDENCY_TYPES = [
38
+ "dependencies",
39
+ "devDependencies",
40
+ "optionalDependencies",
41
+ "peerDependencies"
42
+ ];
43
+ const RANGE_TYPES = ["caret", "pin", "tilde"];
44
+ const schemaOptions = {
45
+ additionalProperties: false,
46
+ properties: {
47
+ forDependencyTypes: {
48
+ items: {
49
+ enum: DEPENDENCY_TYPES
50
+ },
51
+ type: "array"
52
+ },
53
+ forPackages: {
54
+ items: {
55
+ type: "string"
56
+ },
57
+ type: "array"
58
+ },
59
+ forVersions: {
60
+ type: "string"
61
+ },
62
+ rangeType: {
63
+ oneOf: [
64
+ {
65
+ enum: RANGE_TYPES
66
+ },
67
+ {
68
+ items: {
69
+ enum: RANGE_TYPES
70
+ },
71
+ type: "array"
72
+ }
73
+ ]
74
+ }
75
+ },
76
+ required: ["rangeType"],
77
+ type: "object"
78
+ };
79
+ const SYMBOLS = {
80
+ caret: "^",
81
+ pin: "",
82
+ tilde: "~"
83
+ };
84
+ const changeVersionRange = (version, rangeType) => {
85
+ if (/^workspace:[~^*]$/.test(version)) {
86
+ switch (rangeType) {
87
+ case "caret":
88
+ return "workspace:^";
89
+ case "pin":
90
+ return "workspace:*";
91
+ case "tilde":
92
+ default:
93
+ return "workspace:~";
94
+ }
95
+ }
96
+ return version.replace(
97
+ /^(workspace:)?(\^|~|<=?|>=?)?/,
98
+ `$1${SYMBOLS[rangeType]}`
99
+ );
100
+ };
101
+ const isVersionSupported = (version) => {
102
+ if (/^workspace:[*^~]$/.test(version)) {
103
+ return true;
104
+ }
105
+ const rawVersion = version.replace(/^workspace:/, "");
106
+ return !!import_semver.default.validRange(rawVersion);
107
+ };
108
+ const capitalize = (str) => {
109
+ return str.charAt(0).toUpperCase() + str.slice(1);
110
+ };
111
+ const rule = (0, import_createRule.createRule)({
112
+ create(context) {
113
+ if (!context.options[0]) {
114
+ return {};
115
+ }
116
+ const optionsProvided = Array.isArray(context.options[0]) ? [...context.options[0]].reverse() : [context.options[0]];
117
+ const optionsArray = optionsProvided.map((option) => ({
118
+ ...option,
119
+ forPackages: option.forPackages?.map(
120
+ (pattern) => new RegExp(pattern)
121
+ ),
122
+ rangeTypes: Array.isArray(option.rangeType) ? option.rangeType : [option.rangeType]
123
+ }));
124
+ return {
125
+ "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.type=JSONLiteral][value.type=JSONObjectExpression]"(node) {
126
+ const dependencyType = node.key.value;
127
+ if (!DEPENDENCY_TYPES.includes(dependencyType)) {
128
+ return;
129
+ }
130
+ for (const property of node.value.properties) {
131
+ if (!(0, import_predicates.isJSONStringLiteral)(property.key) || !(0, import_predicates.isJSONStringLiteral)(property.value)) {
132
+ continue;
133
+ }
134
+ const name = property.key.value;
135
+ const version = property.value.value;
136
+ if (!isVersionSupported(version)) {
137
+ continue;
138
+ }
139
+ const isPinned = !!import_semver.default.parse(version) || version === "workspace:*";
140
+ const isTildeRange = !!import_semver.default.validRange(version) && version.startsWith("~") || version.startsWith("workspace:~");
141
+ const isCaretRange = !!import_semver.default.validRange(version) && version.startsWith("^") || version.startsWith("workspace:^");
142
+ for (const options of optionsArray) {
143
+ if (options.forDependencyTypes && !options.forDependencyTypes.includes(dependencyType)) {
144
+ continue;
145
+ }
146
+ if (options.forPackages) {
147
+ const isMatch = options.forPackages.some(
148
+ (packageNameRegex) => packageNameRegex.test(name)
149
+ );
150
+ if (!isMatch) {
151
+ continue;
152
+ }
153
+ }
154
+ if (options.forVersions && // We can't determine whether any workspace version without a numeric version to accompany it, matches this range
155
+ // so we'll just skip it.
156
+ (/^workspace:[^~*]?$/.test(version) || // * matches all
157
+ version !== "*" && !import_semver.default.satisfies(
158
+ version.replace(
159
+ /(?:workspace:)?[^~]?/,
160
+ ""
161
+ ),
162
+ options.forVersions
163
+ ))) {
164
+ continue;
165
+ }
166
+ const rangeTypes = options.rangeTypes;
167
+ if (version === "*") {
168
+ context.report({
169
+ data: {
170
+ rangeTypes: rangeTypes.join(", ")
171
+ },
172
+ messageId: "wrongRangeType",
173
+ node: property.value
174
+ });
175
+ break;
176
+ }
177
+ const rangeTypeMatch = rangeTypes.find((rangeType) => {
178
+ switch (rangeType) {
179
+ case "caret":
180
+ return isCaretRange;
181
+ case "pin":
182
+ return isPinned;
183
+ case "tilde":
184
+ return isTildeRange;
185
+ }
186
+ });
187
+ if (!rangeTypeMatch) {
188
+ context.report({
189
+ data: {
190
+ rangeTypes: rangeTypes.join(", ")
191
+ },
192
+ messageId: "wrongRangeType",
193
+ node: property.value,
194
+ suggest: rangeTypes.map((rangeType) => ({
195
+ fix(fixer) {
196
+ return fixer.replaceText(
197
+ property.value,
198
+ `"${changeVersionRange(version, rangeType)}"`
199
+ );
200
+ },
201
+ messageId: `changeTo${capitalize(rangeType)}`
202
+ }))
203
+ });
204
+ }
205
+ break;
206
+ }
207
+ }
208
+ }
209
+ };
210
+ },
211
+ meta: {
212
+ docs: {
213
+ description: "Restricts the range of dependencies to allow or disallow specific types of ranges."
214
+ },
215
+ hasSuggestions: true,
216
+ messages: {
217
+ changeToCaret: "Change to use a caret range.",
218
+ changeToPin: "Pin the version.",
219
+ changeToTilde: "Change to use a tilde range.",
220
+ wrongRangeType: "This dependency is using the wrong range type. Acceptable range type(s): {{rangeTypes}}"
221
+ },
222
+ schema: [
223
+ {
224
+ oneOf: [
225
+ schemaOptions,
226
+ {
227
+ items: schemaOptions,
228
+ type: "array"
229
+ }
230
+ ]
231
+ }
232
+ ],
233
+ type: "suggestion"
234
+ }
235
+ });
236
+ // Annotate the CommonJS export names for ESM import in node:
237
+ 0 && (module.exports = {
238
+ rule
239
+ });