eslint-plugin-package-json 0.52.1 → 0.53.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 (55) hide show
  1. package/CHANGELOG.md +8 -2
  2. package/lib/createRule.d.ts +28 -28
  3. package/lib/createRule.js +18 -12
  4. package/lib/index.d.ts +33 -35
  5. package/lib/index.js +6 -6
  6. package/lib/plugin.d.ts +33 -34
  7. package/lib/plugin.js +62 -80
  8. package/lib/rules/no-empty-fields.d.ts +6 -11
  9. package/lib/rules/no-empty-fields.js +80 -114
  10. package/lib/rules/no-redundant-files.d.ts +5 -10
  11. package/lib/rules/no-redundant-files.js +93 -136
  12. package/lib/rules/order-properties.d.ts +6 -11
  13. package/lib/rules/order-properties.js +92 -118
  14. package/lib/rules/repository-shorthand.d.ts +6 -11
  15. package/lib/rules/repository-shorthand.js +79 -114
  16. package/lib/rules/require-properties.d.ts +7 -12
  17. package/lib/rules/require-properties.js +31 -27
  18. package/lib/rules/restrict-dependency-ranges.d.ts +9 -14
  19. package/lib/rules/restrict-dependency-ranges.js +137 -195
  20. package/lib/rules/sort-collections.d.ts +5 -10
  21. package/lib/rules/sort-collections.js +71 -116
  22. package/lib/rules/unique-dependencies.d.ts +5 -10
  23. package/lib/rules/unique-dependencies.js +58 -82
  24. package/lib/rules/valid-bin.d.ts +6 -11
  25. package/lib/rules/valid-bin.js +59 -79
  26. package/lib/rules/valid-local-dependency.d.ts +5 -10
  27. package/lib/rules/valid-local-dependency.js +49 -57
  28. package/lib/rules/valid-name.d.ts +5 -10
  29. package/lib/rules/valid-name.js +41 -48
  30. package/lib/rules/valid-package-definition.d.ts +6 -11
  31. package/lib/rules/valid-package-definition.js +41 -52
  32. package/lib/rules/valid-properties.d.ts +7 -7
  33. package/lib/rules/valid-properties.js +33 -55
  34. package/lib/rules/valid-repository-directory.d.ts +5 -10
  35. package/lib/rules/valid-repository-directory.js +65 -80
  36. package/lib/rules/valid-version.d.ts +5 -10
  37. package/lib/rules/valid-version.js +35 -36
  38. package/lib/types/estree.d.ts +8 -0
  39. package/lib/utils/createSimpleRequirePropertyRule.d.ts +19 -18
  40. package/lib/utils/createSimpleRequirePropertyRule.js +48 -53
  41. package/lib/utils/createSimpleValidPropertyRule.d.ts +6 -8
  42. package/lib/utils/createSimpleValidPropertyRule.js +45 -39
  43. package/lib/utils/findPropertyWithKeyValue.d.ts +6 -5
  44. package/lib/utils/findPropertyWithKeyValue.js +5 -6
  45. package/lib/utils/formatErrors.d.ts +3 -2
  46. package/lib/utils/formatErrors.js +11 -7
  47. package/lib/utils/isPackageJson.d.ts +3 -2
  48. package/lib/utils/isPackageJson.js +4 -3
  49. package/lib/utils/predicates.d.ts +4 -3
  50. package/lib/utils/predicates.js +6 -6
  51. package/package.json +4 -4
  52. package/lib/tests/rules/ruleTester.d.ts +0 -15
  53. package/lib/tests/rules/ruleTester.js +0 -25
  54. package/lib/types/estree.d.d.ts +0 -7
  55. package/lib/types/estree.d.js +0 -0
@@ -1,211 +1,153 @@
1
- import semver from "semver";
2
1
  import { createRule } from "../createRule.js";
3
2
  import { isJSONStringLiteral } from "../utils/predicates.js";
3
+ import semver from "semver";
4
+
5
+ //#region src/rules/restrict-dependency-ranges.ts
4
6
  const DEPENDENCY_TYPES = [
5
- "dependencies",
6
- "devDependencies",
7
- "optionalDependencies",
8
- "peerDependencies"
7
+ "dependencies",
8
+ "devDependencies",
9
+ "optionalDependencies",
10
+ "peerDependencies"
11
+ ];
12
+ const RANGE_TYPES = [
13
+ "caret",
14
+ "pin",
15
+ "tilde"
9
16
  ];
10
- const RANGE_TYPES = ["caret", "pin", "tilde"];
11
17
  const schemaOptions = {
12
- additionalProperties: false,
13
- properties: {
14
- forDependencyTypes: {
15
- description: "Apply a range type restriction for an entire group of dependencies by which type of dependencies they belong to.",
16
- items: {
17
- enum: DEPENDENCY_TYPES
18
- },
19
- type: "array"
20
- },
21
- forPackages: {
22
- description: "The exact name of a package, or a regex pattern used to match a group of packages by name.",
23
- items: {
24
- type: "string"
25
- },
26
- type: "array"
27
- },
28
- forVersions: {
29
- description: "Apply a restriction to a specific semver range.",
30
- type: "string"
31
- },
32
- rangeType: {
33
- description: "Identifies which range type or types you want to apply to packages that match any of the other match options (or all dependencies if no other options are provided).",
34
- oneOf: [
35
- {
36
- enum: RANGE_TYPES
37
- },
38
- {
39
- items: {
40
- enum: RANGE_TYPES
41
- },
42
- type: "array"
43
- }
44
- ]
45
- }
46
- },
47
- required: ["rangeType"],
48
- type: "object"
18
+ additionalProperties: false,
19
+ properties: {
20
+ forDependencyTypes: {
21
+ description: "Apply a range type restriction for an entire group of dependencies by which type of dependencies they belong to.",
22
+ items: { enum: DEPENDENCY_TYPES },
23
+ type: "array"
24
+ },
25
+ forPackages: {
26
+ description: "The exact name of a package, or a regex pattern used to match a group of packages by name.",
27
+ items: { type: "string" },
28
+ type: "array"
29
+ },
30
+ forVersions: {
31
+ description: "Apply a restriction to a specific semver range.",
32
+ type: "string"
33
+ },
34
+ rangeType: {
35
+ description: "Identifies which range type or types you want to apply to packages that match any of the other match options (or all dependencies if no other options are provided).",
36
+ oneOf: [{ enum: RANGE_TYPES }, {
37
+ items: { enum: RANGE_TYPES },
38
+ type: "array"
39
+ }]
40
+ }
41
+ },
42
+ required: ["rangeType"],
43
+ type: "object"
49
44
  };
50
45
  const SYMBOLS = {
51
- caret: "^",
52
- pin: "",
53
- tilde: "~"
46
+ caret: "^",
47
+ pin: "",
48
+ tilde: "~"
54
49
  };
50
+ /**
51
+ * Given the original version, update it to use the correct range type.
52
+ */
55
53
  const changeVersionRange = (version, rangeType) => {
56
- if (/^workspace:[~^*]$/.test(version)) {
57
- switch (rangeType) {
58
- case "caret":
59
- return "workspace:^";
60
- case "pin":
61
- return "workspace:*";
62
- case "tilde":
63
- default:
64
- return "workspace:~";
65
- }
66
- }
67
- return version.replace(
68
- /^(workspace:)?(\^|~|<=?|>=?)?/,
69
- `$1${SYMBOLS[rangeType]}`
70
- );
54
+ if (/^workspace:[~^*]$/.test(version)) switch (rangeType) {
55
+ case "caret": return "workspace:^";
56
+ case "pin": return "workspace:*";
57
+ case "tilde":
58
+ default: return "workspace:~";
59
+ }
60
+ return version.replace(/^(workspace:)?(\^|~|<=?|>=?)?/, `$1${SYMBOLS[rangeType]}`);
71
61
  };
62
+ /**
63
+ * Check if the version is in a form that this rule supports.
64
+ */
72
65
  const isVersionSupported = (version) => {
73
- if (/^workspace:[*^~]$/.test(version)) {
74
- return true;
75
- }
76
- const rawVersion = version.replace(/^workspace:/, "");
77
- return !!semver.validRange(rawVersion);
66
+ if (/^workspace:[*^~]$/.test(version)) return true;
67
+ const rawVersion = version.replace(/^workspace:/, "");
68
+ return !!semver.validRange(rawVersion);
78
69
  };
79
70
  const capitalize = (str) => {
80
- return str.charAt(0).toUpperCase() + str.slice(1);
71
+ return str.charAt(0).toUpperCase() + str.slice(1);
81
72
  };
82
73
  const rule = createRule({
83
- create(context) {
84
- if (!context.options[0]) {
85
- return {};
86
- }
87
- const optionsProvided = Array.isArray(context.options[0]) ? [...context.options[0]].reverse() : [context.options[0]];
88
- const optionsArray = optionsProvided.map((option) => ({
89
- ...option,
90
- forPackages: option.forPackages?.map(
91
- (pattern) => new RegExp(pattern)
92
- ),
93
- rangeTypes: Array.isArray(option.rangeType) ? option.rangeType : [option.rangeType]
94
- }));
95
- return {
96
- "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.type=JSONLiteral][value.type=JSONObjectExpression]"(node) {
97
- const dependencyType = node.key.value;
98
- if (!DEPENDENCY_TYPES.includes(dependencyType)) {
99
- return;
100
- }
101
- for (const property of node.value.properties) {
102
- if (!isJSONStringLiteral(property.key) || !isJSONStringLiteral(property.value)) {
103
- continue;
104
- }
105
- const name = property.key.value;
106
- const version = property.value.value;
107
- if (!isVersionSupported(version)) {
108
- continue;
109
- }
110
- const isPinned = !!semver.parse(version) || version === "workspace:*";
111
- const isTildeRange = !!semver.validRange(version) && version.startsWith("~") || version.startsWith("workspace:~");
112
- const isCaretRange = !!semver.validRange(version) && version.startsWith("^") || version.startsWith("workspace:^");
113
- for (const options of optionsArray) {
114
- if (options.forDependencyTypes && !options.forDependencyTypes.includes(dependencyType)) {
115
- continue;
116
- }
117
- if (options.forPackages) {
118
- const isMatch = options.forPackages.some(
119
- (packageNameRegex) => packageNameRegex.test(name)
120
- );
121
- if (!isMatch) {
122
- continue;
123
- }
124
- }
125
- if (options.forVersions && // We can't determine whether any workspace version without a numeric version to accompany it, matches this range
126
- // so we'll just skip it.
127
- (/^workspace:[^~*]?$/.test(version) || // * matches all
128
- version !== "*" && !semver.satisfies(
129
- version.replace(
130
- /(?:workspace:)?[^~]?/,
131
- ""
132
- ),
133
- options.forVersions
134
- ))) {
135
- continue;
136
- }
137
- const rangeTypes = options.rangeTypes;
138
- if (version === "*") {
139
- context.report({
140
- data: {
141
- rangeTypes: rangeTypes.join(", ")
142
- },
143
- messageId: "wrongRangeType",
144
- node: property.value
145
- });
146
- break;
147
- }
148
- const rangeTypeMatch = rangeTypes.find((rangeType) => {
149
- switch (rangeType) {
150
- case "caret":
151
- return isCaretRange;
152
- case "pin":
153
- return isPinned;
154
- case "tilde":
155
- return isTildeRange;
156
- }
157
- });
158
- if (!rangeTypeMatch) {
159
- context.report({
160
- data: {
161
- rangeTypes: rangeTypes.join(", ")
162
- },
163
- messageId: "wrongRangeType",
164
- node: property.value,
165
- suggest: rangeTypes.map((rangeType) => ({
166
- fix(fixer) {
167
- return fixer.replaceText(
168
- property.value,
169
- `"${changeVersionRange(version, rangeType)}"`
170
- );
171
- },
172
- messageId: `changeTo${capitalize(rangeType)}`
173
- }))
174
- });
175
- }
176
- break;
177
- }
178
- }
179
- }
180
- };
181
- },
182
- meta: {
183
- defaultOptions: [[]],
184
- docs: {
185
- description: "Restricts the range of dependencies to allow or disallow specific types of ranges."
186
- },
187
- hasSuggestions: true,
188
- messages: {
189
- changeToCaret: "Change to use a caret range.",
190
- changeToPin: "Pin the version.",
191
- changeToTilde: "Change to use a tilde range.",
192
- wrongRangeType: "This dependency is using the wrong range type. Acceptable range type(s): {{rangeTypes}}"
193
- },
194
- schema: [
195
- {
196
- oneOf: [
197
- schemaOptions,
198
- {
199
- description: "Array of configuration options, specifying range requirements.",
200
- items: schemaOptions,
201
- type: "array"
202
- }
203
- ]
204
- }
205
- ],
206
- type: "suggestion"
207
- }
74
+ create(context) {
75
+ if (!context.options[0]) return {};
76
+ const optionsProvided = Array.isArray(context.options[0]) ? [...context.options[0]].reverse() : [context.options[0]];
77
+ const optionsArray = optionsProvided.map((option) => ({
78
+ ...option,
79
+ forPackages: option.forPackages?.map((pattern) => new RegExp(pattern)),
80
+ rangeTypes: Array.isArray(option.rangeType) ? option.rangeType : [option.rangeType]
81
+ }));
82
+ return { "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.type=JSONLiteral][value.type=JSONObjectExpression]"(node) {
83
+ const dependencyType = node.key.value;
84
+ if (!DEPENDENCY_TYPES.includes(dependencyType)) return;
85
+ for (const property of node.value.properties) {
86
+ if (!isJSONStringLiteral(property.key) || !isJSONStringLiteral(property.value)) continue;
87
+ const name = property.key.value;
88
+ const version = property.value.value;
89
+ if (!isVersionSupported(version)) continue;
90
+ const isPinned = !!semver.parse(version) || version === "workspace:*";
91
+ const isTildeRange = !!semver.validRange(version) && version.startsWith("~") || version.startsWith("workspace:~");
92
+ const isCaretRange = !!semver.validRange(version) && version.startsWith("^") || version.startsWith("workspace:^");
93
+ for (const options of optionsArray) {
94
+ if (options.forDependencyTypes && !options.forDependencyTypes.includes(dependencyType)) continue;
95
+ if (options.forPackages) {
96
+ const isMatch = options.forPackages.some((packageNameRegex) => packageNameRegex.test(name));
97
+ if (!isMatch) continue;
98
+ }
99
+ if (options.forVersions && (/^workspace:[^~*]?$/.test(version) || version !== "*" && !semver.satisfies(version.replace(/(?:workspace:)?[^~]?/, ""), options.forVersions))) continue;
100
+ const rangeTypes = options.rangeTypes;
101
+ if (version === "*") {
102
+ context.report({
103
+ data: { rangeTypes: rangeTypes.join(", ") },
104
+ messageId: "wrongRangeType",
105
+ node: property.value
106
+ });
107
+ break;
108
+ }
109
+ const rangeTypeMatch = rangeTypes.find((rangeType) => {
110
+ switch (rangeType) {
111
+ case "caret": return isCaretRange;
112
+ case "pin": return isPinned;
113
+ case "tilde": return isTildeRange;
114
+ }
115
+ });
116
+ if (!rangeTypeMatch) context.report({
117
+ data: { rangeTypes: rangeTypes.join(", ") },
118
+ messageId: "wrongRangeType",
119
+ node: property.value,
120
+ suggest: rangeTypes.map((rangeType) => ({
121
+ fix(fixer) {
122
+ return fixer.replaceText(property.value, `"${changeVersionRange(version, rangeType)}"`);
123
+ },
124
+ messageId: `changeTo${capitalize(rangeType)}`
125
+ }))
126
+ });
127
+ break;
128
+ }
129
+ }
130
+ } };
131
+ },
132
+ meta: {
133
+ defaultOptions: [[]],
134
+ docs: { description: "Restricts the range of dependencies to allow or disallow specific types of ranges." },
135
+ hasSuggestions: true,
136
+ messages: {
137
+ changeToCaret: "Change to use a caret range.",
138
+ changeToPin: "Pin the version.",
139
+ changeToTilde: "Change to use a tilde range.",
140
+ wrongRangeType: "This dependency is using the wrong range type. Acceptable range type(s): {{rangeTypes}}"
141
+ },
142
+ schema: [{ oneOf: [schemaOptions, {
143
+ description: "Array of configuration options, specifying range requirements.",
144
+ items: schemaOptions,
145
+ type: "array"
146
+ }] }],
147
+ type: "suggestion"
148
+ },
149
+ name: "restrict-dependency-ranges"
208
150
  });
209
- export {
210
- rule
211
- };
151
+
152
+ //#endregion
153
+ export { rule };
@@ -1,12 +1,7 @@
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';
1
+ import { PackageJsonRuleModule } from "../createRule.js";
5
2
 
3
+ //#region src/rules/sort-collections.d.ts
6
4
  type Options = string[];
7
- declare const rule: {
8
- create(context: PackageJsonRuleContext<Options>): jsonc_eslint_parser.RuleListener;
9
- meta: eslint.Rule.RuleMetaData;
10
- };
11
-
12
- export { rule };
5
+ declare const rule: PackageJsonRuleModule<Options>;
6
+ //#endregion
7
+ export { rule };
@@ -1,120 +1,75 @@
1
- import sortPackageJson from "sort-package-json";
2
1
  import { createRule } from "../createRule.js";
3
- const defaultCollections = /* @__PURE__ */ new Set([
4
- "config",
5
- "dependencies",
6
- "devDependencies",
7
- "exports",
8
- "optionalDependencies",
9
- "overrides",
10
- "peerDependencies",
11
- "peerDependenciesMeta",
12
- "scripts"
2
+ import sortPackageJson from "sort-package-json";
3
+
4
+ //#region src/rules/sort-collections.ts
5
+ const defaultCollections = new Set([
6
+ "config",
7
+ "dependencies",
8
+ "devDependencies",
9
+ "exports",
10
+ "optionalDependencies",
11
+ "overrides",
12
+ "peerDependencies",
13
+ "peerDependenciesMeta",
14
+ "scripts"
13
15
  ]);
14
16
  const rule = createRule({
15
- create(context) {
16
- const toSort = context.options[0] ? new Set(context.options[0]) : defaultCollections;
17
- return {
18
- "JSONProperty:exit"(node) {
19
- const { key: nodeKey, value: collection } = node;
20
- if (nodeKey.type !== "JSONLiteral" || collection.type !== "JSONObjectExpression") {
21
- return;
22
- }
23
- const keyPartsReversed = [nodeKey.value];
24
- for (
25
- let currNode = node.parent;
26
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
27
- currNode;
28
- currNode = currNode.parent
29
- ) {
30
- if (currNode.type === "JSONProperty" && currNode.key.type === "JSONLiteral") {
31
- keyPartsReversed.push(currNode.key.value);
32
- } else if (currNode.type === "JSONArrayExpression") {
33
- return;
34
- }
35
- }
36
- const key = keyPartsReversed.reverse().join(".");
37
- if (!toSort.has(key)) {
38
- return;
39
- }
40
- const currentOrder = collection.properties;
41
- let desiredOrder;
42
- if (keyPartsReversed.at(-1) !== "scripts") {
43
- desiredOrder = currentOrder.slice().sort((a, b) => {
44
- const aKey = a.key.value;
45
- const bKey = b.key.value;
46
- return aKey > bKey ? 1 : -1;
47
- });
48
- } else {
49
- const scriptsSource = context.sourceCode.getText(node);
50
- const minimalJson = JSON.parse(`{${scriptsSource}}`);
51
- const { scripts: sortedScripts } = sortPackageJson(minimalJson);
52
- const propertyNodeMap = Object.fromEntries(
53
- collection.properties.map((prop) => [
54
- prop.key.value,
55
- prop
56
- ])
57
- );
58
- desiredOrder = Object.keys(sortedScripts).map(
59
- (prop) => propertyNodeMap[prop]
60
- );
61
- }
62
- if (currentOrder.some(
63
- (property, i) => desiredOrder[i] !== property
64
- )) {
65
- context.report({
66
- data: {
67
- key
68
- },
69
- fix(fixer) {
70
- return fixer.replaceText(
71
- collection,
72
- JSON.stringify(
73
- desiredOrder.reduce((out, property) => {
74
- out[property.key.value] = JSON.parse(
75
- context.sourceCode.getText(
76
- property.value
77
- )
78
- );
79
- return out;
80
- }, {}),
81
- null,
82
- 2
83
- ).split("\n").join("\n ")
84
- // nest indents
85
- );
86
- },
87
- loc: collection.loc,
88
- messageId: "notAlphabetized",
89
- node
90
- });
91
- }
92
- }
93
- };
94
- },
95
- meta: {
96
- defaultOptions: [Array.from(defaultCollections)],
97
- docs: {
98
- category: "Best Practices",
99
- description: "Dependencies, scripts, and configuration values must be declared in alphabetical order.",
100
- recommended: true
101
- },
102
- fixable: "code",
103
- messages: {
104
- notAlphabetized: "Package {{ key }} are not alphabetized"
105
- },
106
- schema: [
107
- {
108
- description: "Array of package properties to require sorting.",
109
- items: {
110
- type: "string"
111
- },
112
- type: "array"
113
- }
114
- ],
115
- type: "layout"
116
- }
17
+ create(context) {
18
+ const toSort = context.options[0] ? new Set(context.options[0]) : defaultCollections;
19
+ return { "JSONProperty:exit"(node) {
20
+ const { key: nodeKey, value: collection } = node;
21
+ if (nodeKey.type !== "JSONLiteral" || collection.type !== "JSONObjectExpression") return;
22
+ const keyPartsReversed = [nodeKey.value];
23
+ for (let currNode = node.parent; currNode; currNode = currNode.parent) if (currNode.type === "JSONProperty" && currNode.key.type === "JSONLiteral") keyPartsReversed.push(currNode.key.value);
24
+ else if (currNode.type === "JSONArrayExpression") return;
25
+ const key = keyPartsReversed.reverse().join(".");
26
+ if (!toSort.has(key)) return;
27
+ const currentOrder = collection.properties;
28
+ let desiredOrder;
29
+ if (keyPartsReversed.at(-1) !== "scripts") desiredOrder = currentOrder.slice().sort((a, b) => {
30
+ const aKey = a.key.value;
31
+ const bKey = b.key.value;
32
+ return aKey > bKey ? 1 : -1;
33
+ });
34
+ else {
35
+ const scriptsSource = context.sourceCode.getText(node);
36
+ const minimalJson = JSON.parse(`{${scriptsSource}}`);
37
+ const { scripts: sortedScripts } = sortPackageJson(minimalJson);
38
+ const propertyNodeMap = Object.fromEntries(collection.properties.map((prop) => [prop.key.value, prop]));
39
+ desiredOrder = Object.keys(sortedScripts).map((prop) => propertyNodeMap[prop]);
40
+ }
41
+ if (currentOrder.some((property, i) => desiredOrder[i] !== property)) context.report({
42
+ data: { key },
43
+ fix(fixer) {
44
+ return fixer.replaceText(collection, JSON.stringify(desiredOrder.reduce((out, property) => {
45
+ out[property.key.value] = JSON.parse(context.sourceCode.getText(property.value));
46
+ return out;
47
+ }, {}), null, 2).split("\n").join("\n "));
48
+ },
49
+ loc: collection.loc,
50
+ messageId: "notAlphabetized",
51
+ node
52
+ });
53
+ } };
54
+ },
55
+ meta: {
56
+ defaultOptions: [Array.from(defaultCollections)],
57
+ docs: {
58
+ category: "Best Practices",
59
+ description: "Dependencies, scripts, and configuration values must be declared in alphabetical order.",
60
+ recommended: true
61
+ },
62
+ fixable: "code",
63
+ messages: { notAlphabetized: "Package {{ key }} are not alphabetized" },
64
+ schema: [{
65
+ description: "Array of package properties to require sorting.",
66
+ items: { type: "string" },
67
+ type: "array"
68
+ }],
69
+ type: "layout"
70
+ },
71
+ name: "sort-collections"
117
72
  });
118
- export {
119
- rule
120
- };
73
+
74
+ //#endregion
75
+ export { rule };
@@ -1,11 +1,6 @@
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';
1
+ import { PackageJsonRuleModule } from "../createRule.js";
5
2
 
6
- declare const rule: {
7
- create(context: PackageJsonRuleContext<unknown[]>): jsonc_eslint_parser.RuleListener;
8
- meta: eslint.Rule.RuleMetaData;
9
- };
10
-
11
- export { rule };
3
+ //#region src/rules/unique-dependencies.d.ts
4
+ declare const rule: PackageJsonRuleModule<unknown[]>;
5
+ //#endregion
6
+ export { rule };