eslint-plugin-boundaries 3.1.0 → 3.2.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/package.json +8 -8
- package/src/core/elementsInfo.js +8 -6
- package/src/rules/external.js +64 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-boundaries",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Eslint plugin checking architecture boundaries between elements",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -32,21 +32,21 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"chalk": "4.1.2",
|
|
35
|
-
"eslint-import-resolver-node": "0.3.
|
|
35
|
+
"eslint-import-resolver-node": "0.3.7",
|
|
36
36
|
"eslint-module-utils": "2.7.4",
|
|
37
37
|
"is-core-module": "2.11.0",
|
|
38
38
|
"micromatch": "4.0.5"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"cross-env": "7.0.3",
|
|
42
|
-
"eslint": "8.
|
|
43
|
-
"eslint-config-prettier": "8.
|
|
42
|
+
"eslint": "8.37.0",
|
|
43
|
+
"eslint-config-prettier": "8.8.0",
|
|
44
44
|
"eslint-plugin-prettier": "4.2.1",
|
|
45
|
-
"husky": "8.0.
|
|
45
|
+
"husky": "8.0.3",
|
|
46
46
|
"is-ci": "3.0.1",
|
|
47
|
-
"jest": "29.
|
|
48
|
-
"lint-staged": "13.0
|
|
49
|
-
"prettier": "2.8.
|
|
47
|
+
"jest": "29.5.0",
|
|
48
|
+
"lint-staged": "13.2.0",
|
|
49
|
+
"prettier": "2.8.7"
|
|
50
50
|
},
|
|
51
51
|
"lint-staged": {
|
|
52
52
|
"test/**/*.js": "eslint",
|
package/src/core/elementsInfo.js
CHANGED
|
@@ -9,10 +9,7 @@ const { isArray } = require("../helpers/utils");
|
|
|
9
9
|
|
|
10
10
|
const { filesCache, importsCache, elementsCache } = require("./cache");
|
|
11
11
|
|
|
12
|
-
function baseModule(name
|
|
13
|
-
if (path) {
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
12
|
+
function baseModule(name) {
|
|
16
13
|
if (isScoped(name)) {
|
|
17
14
|
const [scope, packageName] = name.split("/");
|
|
18
15
|
return `${scope}/${packageName}`;
|
|
@@ -193,6 +190,10 @@ function projectPath(absolutePath) {
|
|
|
193
190
|
}
|
|
194
191
|
}
|
|
195
192
|
|
|
193
|
+
function externalModulePath(source, baseModuleValue) {
|
|
194
|
+
return source.replace(baseModuleValue, "");
|
|
195
|
+
}
|
|
196
|
+
|
|
196
197
|
function importInfo(source, context) {
|
|
197
198
|
const path = projectPath(resolve(source, context));
|
|
198
199
|
const isExternalModule = isExternal(source, path);
|
|
@@ -205,8 +206,9 @@ function importInfo(source, context) {
|
|
|
205
206
|
result = resultCache;
|
|
206
207
|
} else {
|
|
207
208
|
elementCache = elementsCache.load(path, context.settings);
|
|
209
|
+
const baseModuleValue = isExternalModule ? baseModule(source) : null;
|
|
208
210
|
const isBuiltInModule = isBuiltIn(source, path);
|
|
209
|
-
const pathToUse = isExternalModule ?
|
|
211
|
+
const pathToUse = isExternalModule ? externalModulePath(source, baseModuleValue) : path;
|
|
210
212
|
if (elementCache) {
|
|
211
213
|
elementResult = elementCache;
|
|
212
214
|
} else {
|
|
@@ -221,7 +223,7 @@ function importInfo(source, context) {
|
|
|
221
223
|
isLocal: !isExternalModule && !isBuiltInModule,
|
|
222
224
|
isBuiltIn: isBuiltInModule,
|
|
223
225
|
isExternal: isExternalModule,
|
|
224
|
-
baseModule:
|
|
226
|
+
baseModule: baseModuleValue,
|
|
225
227
|
...elementResult,
|
|
226
228
|
};
|
|
227
229
|
|
package/src/rules/external.js
CHANGED
|
@@ -11,14 +11,15 @@ const {
|
|
|
11
11
|
micromatchPatternReplacingObjectsValues,
|
|
12
12
|
} = require("../helpers/rules");
|
|
13
13
|
const { customErrorMessage, ruleElementMessage, elementMessage } = require("../helpers/messages");
|
|
14
|
+
const { isArray } = require("../helpers/utils");
|
|
14
15
|
|
|
15
|
-
function specifiersMatch(specifiers,
|
|
16
|
+
function specifiersMatch(specifiers, specifierOptions, elementsCapturedValues) {
|
|
16
17
|
const importedSpecifiersNames = specifiers
|
|
17
18
|
.filter((specifier) => {
|
|
18
19
|
return specifier.type === "ImportSpecifier" && specifier.imported.name;
|
|
19
20
|
})
|
|
20
21
|
.map((specifier) => specifier.imported.name);
|
|
21
|
-
return
|
|
22
|
+
return specifierOptions.reduce((found, option) => {
|
|
22
23
|
const matcherWithTemplateReplaced = micromatchPatternReplacingObjectsValues(
|
|
23
24
|
option,
|
|
24
25
|
elementsCapturedValues
|
|
@@ -30,6 +31,23 @@ function specifiersMatch(specifiers, options, elementsCapturedValues) {
|
|
|
30
31
|
}, []);
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
function pathMatch(path, pathOptions, elementsCapturedValues) {
|
|
35
|
+
const pathMatchers = isArray(pathOptions) ? pathOptions : [pathOptions];
|
|
36
|
+
return pathMatchers.reduce((isMatch, option) => {
|
|
37
|
+
if (isMatch) {
|
|
38
|
+
return isMatch;
|
|
39
|
+
}
|
|
40
|
+
const matcherWithTemplateReplaced = micromatchPatternReplacingObjectsValues(
|
|
41
|
+
option,
|
|
42
|
+
elementsCapturedValues
|
|
43
|
+
);
|
|
44
|
+
if (micromatch.some(path, matcherWithTemplateReplaced)) {
|
|
45
|
+
isMatch = true;
|
|
46
|
+
}
|
|
47
|
+
return isMatch;
|
|
48
|
+
}, false);
|
|
49
|
+
}
|
|
50
|
+
|
|
33
51
|
function isMatchExternalDependency(dependency, matcher, options, elementsCapturedValues) {
|
|
34
52
|
const matcherWithTemplatesReplaced = micromatchPatternReplacingObjectsValues(
|
|
35
53
|
matcher,
|
|
@@ -37,14 +55,27 @@ function isMatchExternalDependency(dependency, matcher, options, elementsCapture
|
|
|
37
55
|
);
|
|
38
56
|
const isMatch = micromatch.isMatch(dependency.baseModule, matcherWithTemplatesReplaced);
|
|
39
57
|
if (isMatch && options && Object.keys(options).length) {
|
|
40
|
-
const
|
|
41
|
-
dependency.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
58
|
+
const isPathMatch = options.path
|
|
59
|
+
? pathMatch(dependency.path, options.path, elementsCapturedValues)
|
|
60
|
+
: true;
|
|
61
|
+
if (isPathMatch && options.specifiers) {
|
|
62
|
+
const specifiersResult = specifiersMatch(
|
|
63
|
+
dependency.specifiers,
|
|
64
|
+
options.specifiers,
|
|
65
|
+
elementsCapturedValues
|
|
66
|
+
);
|
|
67
|
+
return {
|
|
68
|
+
result: specifiersResult.length > 0,
|
|
69
|
+
report: {
|
|
70
|
+
specifiers: specifiersResult,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
45
74
|
return {
|
|
46
|
-
result:
|
|
47
|
-
report:
|
|
75
|
+
result: isPathMatch,
|
|
76
|
+
report: {
|
|
77
|
+
path: dependency.path,
|
|
78
|
+
},
|
|
48
79
|
};
|
|
49
80
|
}
|
|
50
81
|
return {
|
|
@@ -61,11 +92,20 @@ function elementRulesAllowExternalDependency(element, dependency, options) {
|
|
|
61
92
|
});
|
|
62
93
|
}
|
|
63
94
|
|
|
95
|
+
function getErrorReportMessage(report) {
|
|
96
|
+
if (report.path) {
|
|
97
|
+
return report.path;
|
|
98
|
+
}
|
|
99
|
+
return report.specifiers.join(", ");
|
|
100
|
+
}
|
|
101
|
+
|
|
64
102
|
function errorMessage(ruleData, file, dependency) {
|
|
65
103
|
const ruleReport = ruleData.ruleReport;
|
|
66
104
|
if (ruleReport.message) {
|
|
67
105
|
return customErrorMessage(ruleReport.message, file, dependency, {
|
|
68
|
-
specifiers:
|
|
106
|
+
specifiers:
|
|
107
|
+
ruleData.report && ruleData.report.specifiers && ruleData.report.specifiers.join(", "),
|
|
108
|
+
path: ruleData.report && ruleData.report.path,
|
|
69
109
|
});
|
|
70
110
|
}
|
|
71
111
|
if (ruleReport.isDefault) {
|
|
@@ -80,7 +120,7 @@ function errorMessage(ruleData, file, dependency) {
|
|
|
80
120
|
)}. Disallowed in rule ${ruleReport.index + 1}`;
|
|
81
121
|
|
|
82
122
|
if (ruleData.report) {
|
|
83
|
-
return `Usage of '${ruleData.report
|
|
123
|
+
return `Usage of '${getErrorReportMessage(ruleData.report)}' from external module '${
|
|
84
124
|
dependency.baseModule
|
|
85
125
|
}' ${fileReport}`;
|
|
86
126
|
}
|
|
@@ -101,6 +141,19 @@ module.exports = dependencyRule(
|
|
|
101
141
|
type: "string",
|
|
102
142
|
},
|
|
103
143
|
},
|
|
144
|
+
path: {
|
|
145
|
+
oneOf: [
|
|
146
|
+
{
|
|
147
|
+
type: "string",
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: "array",
|
|
151
|
+
items: {
|
|
152
|
+
type: "string",
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
},
|
|
104
157
|
},
|
|
105
158
|
additionalProperties: false,
|
|
106
159
|
},
|