@dvukovic/style-guide 0.3.119 → 0.3.120

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dvukovic/style-guide",
3
- "version": "0.3.119",
3
+ "version": "0.3.120",
4
4
  "description": "My own style guide",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,17 +24,18 @@ export const packageJson = {
24
24
  "dvukovic/no-restricted-dependencies": [
25
25
  "error",
26
26
  {
27
- packages: [
27
+ dependencies: [
28
28
  "@types/*",
29
29
  "cspell",
30
30
  "eslint",
31
+ "lambda",
31
32
  "lodash",
32
- "npm-package-json-lint",
33
33
  "prettier",
34
34
  "ramda",
35
35
  "stylelint",
36
36
  "typeorm",
37
37
  ],
38
+ peerDependencies: ["@types/*"],
38
39
  },
39
40
  ],
40
41
  "dvukovic/require-properties": ["error", { properties: ["volta.node"] }],
@@ -1,9 +1,11 @@
1
- const DEPENDENCY_TYPES = new Set([
1
+ const DEPENDENCY_TYPES = [
2
2
  "dependencies",
3
3
  "devDependencies",
4
4
  "optionalDependencies",
5
5
  "peerDependencies",
6
- ])
6
+ ]
7
+
8
+ const DEPENDENCY_TYPES_SET = new Set(DEPENDENCY_TYPES)
7
9
 
8
10
  /**
9
11
  * Checks if a package name matches a restriction pattern. Supports exact matches and glob-like
@@ -28,11 +30,6 @@ function matchesPattern(packageName, pattern) {
28
30
  export const noRestrictedDependencies = {
29
31
  create(context) {
30
32
  const options = context.options[0] || {}
31
- const restricted = options.packages || []
32
-
33
- if (restricted.length === 0) {
34
- return {}
35
- }
36
33
 
37
34
  return {
38
35
  JSONProperty(node) {
@@ -42,7 +39,7 @@ export const noRestrictedDependencies = {
42
39
 
43
40
  const propertyName = node.key.value
44
41
 
45
- if (!DEPENDENCY_TYPES.has(propertyName)) {
42
+ if (!DEPENDENCY_TYPES_SET.has(propertyName)) {
46
43
  return
47
44
  }
48
45
 
@@ -50,6 +47,12 @@ export const noRestrictedDependencies = {
50
47
  return
51
48
  }
52
49
 
50
+ const patterns = options[propertyName] || []
51
+
52
+ if (patterns.length === 0) {
53
+ return
54
+ }
55
+
53
56
  for (const dep of node.value.properties) {
54
57
  if (dep.key.type !== "JSONLiteral" || typeof dep.key.value !== "string") {
55
58
  continue
@@ -57,7 +60,7 @@ export const noRestrictedDependencies = {
57
60
 
58
61
  const packageName = dep.key.value
59
62
 
60
- for (const pattern of restricted) {
63
+ for (const pattern of patterns) {
61
64
  if (matchesPattern(packageName, pattern)) {
62
65
  context.report({
63
66
  data: {
@@ -86,9 +89,23 @@ export const noRestrictedDependencies = {
86
89
  {
87
90
  additionalProperties: false,
88
91
  properties: {
89
- packages: {
90
- description:
91
- "List of restricted package names or patterns (supports * wildcard)",
92
+ dependencies: {
93
+ description: "Restricted patterns in dependencies",
94
+ items: { type: "string" },
95
+ type: "array",
96
+ },
97
+ devDependencies: {
98
+ description: "Restricted patterns in devDependencies",
99
+ items: { type: "string" },
100
+ type: "array",
101
+ },
102
+ optionalDependencies: {
103
+ description: "Restricted patterns in optionalDependencies",
104
+ items: { type: "string" },
105
+ type: "array",
106
+ },
107
+ peerDependencies: {
108
+ description: "Restricted patterns in peerDependencies",
92
109
  items: { type: "string" },
93
110
  type: "array",
94
111
  },
@@ -3,7 +3,7 @@ import jsoncParser from "jsonc-eslint-parser"
3
3
 
4
4
  import { noRestrictedDependencies } from "./no-restricted-dependencies.js"
5
5
 
6
- const createEslint = (packages) => {
6
+ const createEslint = (options) => {
7
7
  return new ESLint({
8
8
  overrideConfig: [
9
9
  {
@@ -19,7 +19,7 @@ const createEslint = (packages) => {
19
19
  },
20
20
  },
21
21
  rules: {
22
- "custom/no-restricted-dependencies": ["error", { packages }],
22
+ "custom/no-restricted-dependencies": ["error", options],
23
23
  },
24
24
  },
25
25
  ],
@@ -27,9 +27,19 @@ const createEslint = (packages) => {
27
27
  })
28
28
  }
29
29
 
30
+ const getErrors = async (eslint, packageJson) => {
31
+ const results = await eslint.lintText(packageJson, { filePath: "package.json" })
32
+
33
+ return (
34
+ results[0]?.messages.filter((message) => {
35
+ return message.ruleId === "custom/no-restricted-dependencies"
36
+ }) ?? []
37
+ )
38
+ }
39
+
30
40
  describe("no-restricted-dependencies", () => {
31
41
  test("detects restricted package in dependencies", async () => {
32
- const eslint = createEslint(["lodash"])
42
+ const eslint = createEslint({ dependencies: ["lodash"] })
33
43
  const packageJson = JSON.stringify(
34
44
  {
35
45
  dependencies: {
@@ -41,17 +51,14 @@ describe("no-restricted-dependencies", () => {
41
51
  4,
42
52
  )
43
53
 
44
- const results = await eslint.lintText(packageJson, { filePath: "package.json" })
45
- const errors = results[0]?.messages.filter((message) => {
46
- return message.ruleId === "custom/no-restricted-dependencies"
47
- })
54
+ const errors = await getErrors(eslint, packageJson)
48
55
 
49
- expect(errors?.length).toBe(1)
50
- expect(errors?.[0]?.message).toContain("lodash")
56
+ expect(errors.length).toBe(1)
57
+ expect(errors[0]?.message).toContain("lodash")
51
58
  })
52
59
 
53
60
  test("detects restricted package in devDependencies", async () => {
54
- const eslint = createEslint(["jest"])
61
+ const eslint = createEslint({ devDependencies: ["jest"] })
55
62
  const packageJson = JSON.stringify(
56
63
  {
57
64
  devDependencies: {
@@ -63,16 +70,13 @@ describe("no-restricted-dependencies", () => {
63
70
  4,
64
71
  )
65
72
 
66
- const results = await eslint.lintText(packageJson, { filePath: "package.json" })
67
- const errors = results[0]?.messages.filter((message) => {
68
- return message.ruleId === "custom/no-restricted-dependencies"
69
- })
73
+ const errors = await getErrors(eslint, packageJson)
70
74
 
71
- expect(errors?.length).toBe(1)
75
+ expect(errors.length).toBe(1)
72
76
  })
73
77
 
74
78
  test("detects pattern with wildcard", async () => {
75
- const eslint = createEslint(["@types/*"])
79
+ const eslint = createEslint({ devDependencies: ["@types/*"] })
76
80
  const packageJson = JSON.stringify(
77
81
  {
78
82
  devDependencies: {
@@ -85,16 +89,13 @@ describe("no-restricted-dependencies", () => {
85
89
  4,
86
90
  )
87
91
 
88
- const results = await eslint.lintText(packageJson, { filePath: "package.json" })
89
- const errors = results[0]?.messages.filter((message) => {
90
- return message.ruleId === "custom/no-restricted-dependencies"
91
- })
92
+ const errors = await getErrors(eslint, packageJson)
92
93
 
93
- expect(errors?.length).toBe(2)
94
+ expect(errors.length).toBe(2)
94
95
  })
95
96
 
96
97
  test("allows non-restricted packages", async () => {
97
- const eslint = createEslint(["lodash"])
98
+ const eslint = createEslint({ dependencies: ["lodash"] })
98
99
  const packageJson = JSON.stringify(
99
100
  {
100
101
  dependencies: {
@@ -106,16 +107,13 @@ describe("no-restricted-dependencies", () => {
106
107
  4,
107
108
  )
108
109
 
109
- const results = await eslint.lintText(packageJson, { filePath: "package.json" })
110
- const errors = results[0]?.messages.filter((message) => {
111
- return message.ruleId === "custom/no-restricted-dependencies"
112
- })
110
+ const errors = await getErrors(eslint, packageJson)
113
111
 
114
- expect(errors?.length).toBe(0)
112
+ expect(errors.length).toBe(0)
115
113
  })
116
114
 
117
115
  test("detects multiple restricted packages", async () => {
118
- const eslint = createEslint(["lodash", "ramda", "underscore"])
116
+ const eslint = createEslint({ dependencies: ["lodash", "ramda", "underscore"] })
119
117
  const packageJson = JSON.stringify(
120
118
  {
121
119
  dependencies: {
@@ -129,16 +127,13 @@ describe("no-restricted-dependencies", () => {
129
127
  4,
130
128
  )
131
129
 
132
- const results = await eslint.lintText(packageJson, { filePath: "package.json" })
133
- const errors = results[0]?.messages.filter((message) => {
134
- return message.ruleId === "custom/no-restricted-dependencies"
135
- })
130
+ const errors = await getErrors(eslint, packageJson)
136
131
 
137
- expect(errors?.length).toBe(2)
132
+ expect(errors.length).toBe(2)
138
133
  })
139
134
 
140
- test("handles empty packages list", async () => {
141
- const eslint = createEslint([])
135
+ test("handles empty options", async () => {
136
+ const eslint = createEslint({})
142
137
  const packageJson = JSON.stringify(
143
138
  {
144
139
  dependencies: {
@@ -150,11 +145,93 @@ describe("no-restricted-dependencies", () => {
150
145
  4,
151
146
  )
152
147
 
153
- const results = await eslint.lintText(packageJson, { filePath: "package.json" })
154
- const errors = results[0]?.messages.filter((message) => {
155
- return message.ruleId === "custom/no-restricted-dependencies"
148
+ const errors = await getErrors(eslint, packageJson)
149
+
150
+ expect(errors.length).toBe(0)
151
+ })
152
+
153
+ test("restricts @types/* in dependencies but allows in devDependencies", async () => {
154
+ const eslint = createEslint({ dependencies: ["@types/*"] })
155
+ const packageJson = JSON.stringify(
156
+ {
157
+ dependencies: {
158
+ "@types/node": "^20.0.0",
159
+ },
160
+ devDependencies: {
161
+ "@types/react": "^18.0.0",
162
+ },
163
+ name: "test",
164
+ },
165
+ null,
166
+ 4,
167
+ )
168
+
169
+ const errors = await getErrors(eslint, packageJson)
170
+
171
+ expect(errors.length).toBe(1)
172
+ expect(errors[0]?.message).toContain("@types/node")
173
+ expect(errors[0]?.message).toContain("dependencies")
174
+ })
175
+
176
+ test("restricts different patterns in different dependency types", async () => {
177
+ const eslint = createEslint({
178
+ dependencies: ["@types/*", "lodash"],
179
+ devDependencies: ["jest"],
156
180
  })
181
+ const packageJson = JSON.stringify(
182
+ {
183
+ dependencies: {
184
+ "@types/node": "^20.0.0",
185
+ lodash: "^4.0.0",
186
+ },
187
+ devDependencies: {
188
+ "@types/react": "^18.0.0",
189
+ jest: "^29.0.0",
190
+ },
191
+ name: "test",
192
+ },
193
+ null,
194
+ 4,
195
+ )
196
+
197
+ const errors = await getErrors(eslint, packageJson)
198
+
199
+ expect(errors.length).toBe(3)
200
+ })
201
+
202
+ test("restricts in peerDependencies", async () => {
203
+ const eslint = createEslint({ peerDependencies: ["react"] })
204
+ const packageJson = JSON.stringify(
205
+ {
206
+ name: "test",
207
+ peerDependencies: {
208
+ react: "^18.0.0",
209
+ },
210
+ },
211
+ null,
212
+ 4,
213
+ )
214
+
215
+ const errors = await getErrors(eslint, packageJson)
216
+
217
+ expect(errors.length).toBe(1)
218
+ })
219
+
220
+ test("restricts in optionalDependencies", async () => {
221
+ const eslint = createEslint({ optionalDependencies: ["fsevents"] })
222
+ const packageJson = JSON.stringify(
223
+ {
224
+ name: "test",
225
+ optionalDependencies: {
226
+ fsevents: "^2.0.0",
227
+ },
228
+ },
229
+ null,
230
+ 4,
231
+ )
232
+
233
+ const errors = await getErrors(eslint, packageJson)
157
234
 
158
- expect(errors?.length).toBe(0)
235
+ expect(errors.length).toBe(1)
159
236
  })
160
237
  })