Skip to content

Commit 8567799

Browse files
committed
feat: new restrict-dependency-ranges rule
This change adds a new rule that allows you to restrict usage of semver ranges on dependencies using any of the following matching options: - by dependency name or regex pattern - by version - by dependency type
1 parent e58f628 commit 8567799

File tree

5 files changed

+914
-0
lines changed

5 files changed

+914
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ The default settings don't conflict, and Prettier plugins can quickly fix up ord
130130
| [require-name](docs/rules/require-name.md) | Requires the `name` property to be present. || | | |
131131
| [require-types](docs/rules/require-types.md) | Requires the `types` property to be present. | | | | |
132132
| [require-version](docs/rules/require-version.md) | Requires the `version` property to be present. || | | |
133+
| [restrict-dependency-ranges](docs/rules/restrict-dependency-ranges.md) | Restricts the range of dependencies to allow or disallow specific types of ranges. | | | 💡 | |
133134
| [sort-collections](docs/rules/sort-collections.md) | Dependencies, scripts, and configuration values must be declared in alphabetical order. || 🔧 | | |
134135
| [unique-dependencies](docs/rules/unique-dependencies.md) | Checks a dependency isn't specified more than once (i.e. in `dependencies` and `devDependencies`) || | 💡 | |
135136
| [valid-local-dependency](docs/rules/valid-local-dependency.md) | Checks existence of local dependencies in the package.json || | | |
+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# restrict-dependency-ranges
2+
3+
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
4+
5+
<!-- end auto-generated rule header -->
6+
7+
This rule allows you to require that specific dependencies use a particular kind
8+
of semver range (e.g. `^`). There are several options for specifying which dependencies
9+
a range type restriction should be applied to, including dependency type,
10+
package name (or name regex pattern), and version range (e.g. '<1').
11+
12+
If you provide multiple options and a dependency matches more than one of the
13+
options, the last option that matches will take precedent for that dependency.
14+
This allows you to define more general rules that apply to all dependencies (or large
15+
groups of dependencies), and then define more granular options to apply exceptions
16+
or focus on some subset of dependencies.
17+
18+
## Options
19+
20+
`type DependencyType = 'dependencies' | 'devDependencies' | 'optionalDependencies' | 'peerDependencies';`\
21+
`type RangeType = 'caret' | 'pin' | 'tilde';`
22+
23+
| Name | Type | Required |
24+
| :------------------- | :----------------------- | :------- |
25+
| `forDependencyTypes` | DependencyType[] | |
26+
| `forPackages` | String[] | |
27+
| `forVersions` | String | |
28+
| `rangeType` | RangeType \| RangeType[] | Yes |
29+
30+
You can provide a single options object consisting of the above, or an array
31+
of such objects.
32+
33+
### `forDependencyTypes`
34+
35+
You can use this to apply a range type restriction for an entire group of dependencies
36+
by which type of dependencies they belong to.
37+
38+
Options are
39+
40+
- dependencies
41+
- devDependencies
42+
- optionalDependencies
43+
- peerDependencies
44+
45+
### `forPackages`
46+
47+
This can be the exact name of a package, or a regex pattern used to match a
48+
group of packages by name (e.g. `@typescript-eslint/*`).
49+
50+
### `forVersions`
51+
52+
You can use this to apply a restriction to a specific semver range. For example,
53+
a common use case is to pin "unstable" dependencies (packages that have
54+
a version in the `0.x.x` range). You can do this by setting `forVersions` to `'<1'`.
55+
56+
### `rangeType`
57+
58+
This is the only required option, and identifies which range type or types you
59+
want to apply to packages that match any of the other match options (or all
60+
dependencies if no other options are provided).
61+
62+
## Example
63+
64+
```ts
65+
export default [
66+
{
67+
"package-json/restrict-dependency-ranges": [
68+
"error",
69+
[
70+
// Apply base requirement that all deps should use ^
71+
{
72+
rangeType: "caret",
73+
},
74+
75+
// Restrict typescript to tilde ranges
76+
{
77+
forPackages: "typescript",
78+
rangeType: "tilde",
79+
},
80+
81+
// Require packages that have 0.x.x versions are pinned
82+
{
83+
forVersions: "<1",
84+
rangeType: "pin",
85+
},
86+
],
87+
],
88+
},
89+
];
90+
```
91+
92+
Example of **incorrect** code for the above configuration:
93+
94+
```json
95+
{
96+
"devDependencies": {
97+
"eslint": "^9.18.0",
98+
"markdownlint": "^0.37.4",
99+
"typescript": "^5.8.0"
100+
}
101+
}
102+
```
103+
104+
Example of **correct** code for the above configuration:
105+
106+
```json
107+
{
108+
"devDependencies": {
109+
"eslint": "^9.18.0",
110+
"markdownlint": "0.37.4",
111+
"typescript": "~5.8.0"
112+
}
113+
}
114+
```

src/plugin.ts

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { rule as noRedundantFiles } from "./rules/no-redundant-files.js";
88
import { rule as orderProperties } from "./rules/order-properties.js";
99
import { rule as preferRepositoryShorthand } from "./rules/repository-shorthand.js";
1010
import { rules as requireRules } from "./rules/require-properties.js";
11+
import { rule as restrictDependencyRanges } from "./rules/restrict-dependency-ranges.js";
1112
import { rule as sortCollections } from "./rules/sort-collections.js";
1213
import { rule as uniqueDependencies } from "./rules/unique-dependencies.js";
1314
import { rule as validLocalDependency } from "./rules/valid-local-dependency.js";
@@ -29,6 +30,7 @@ const rules: Record<string, PackageJsonRuleModule> = {
2930
"order-properties": orderProperties,
3031
...requireRules,
3132
"repository-shorthand": preferRepositoryShorthand,
33+
"restrict-dependency-ranges": restrictDependencyRanges,
3234
"sort-collections": sortCollections,
3335
"unique-dependencies": uniqueDependencies,
3436
"valid-local-dependency": validLocalDependency,

0 commit comments

Comments
 (0)