@boundaries/eslint-plugin 5.3.1 → 6.0.0-beta.1
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/README.md +9 -9
- package/dist/Config/Config.d.ts +6 -3
- package/dist/Config/Config.js +18 -7
- package/dist/Config/Recommended.d.ts +1 -1
- package/dist/Config/Recommended.js +3 -2
- package/dist/Config/Strict.d.ts +1 -1
- package/dist/Config/Strict.js +2 -2
- package/dist/Debug/Debug.d.ts +34 -0
- package/dist/Debug/Debug.js +285 -0
- package/dist/Debug/index.d.ts +1 -0
- package/dist/{Support → Debug}/index.js +0 -1
- package/dist/Elements/Elements.d.ts +11 -9
- package/dist/Elements/Elements.js +20 -34
- package/dist/Elements/Elements.types.d.ts +1 -0
- package/dist/Messages/CustomMessages.d.ts +44 -0
- package/dist/Messages/CustomMessages.js +156 -0
- package/dist/Messages/CustomMessages.types.d.ts +25 -0
- package/dist/Messages/CustomMessages.types.js +2 -0
- package/dist/Messages/Messages.d.ts +42 -13
- package/dist/Messages/Messages.js +400 -177
- package/dist/Messages/index.d.ts +2 -0
- package/dist/Messages/index.js +2 -0
- package/dist/Public/Config.types.d.ts +2 -2
- package/dist/Public/Config.types.js +2 -2
- package/dist/Public/Rules.types.d.ts +5 -4
- package/dist/Public/Rules.types.js +5 -6
- package/dist/Public/Settings.types.d.ts +3 -2
- package/dist/Public/Settings.types.js +4 -3
- package/dist/Public/index.d.ts +1 -0
- package/dist/Rules/Dependencies.d.ts +59 -0
- package/dist/Rules/Dependencies.js +439 -0
- package/dist/Rules/EntryPoint.js +44 -94
- package/dist/Rules/External.js +93 -68
- package/dist/Rules/NoIgnored.js +4 -4
- package/dist/Rules/NoPrivate.js +18 -5
- package/dist/Rules/NoUnknown.js +5 -5
- package/dist/Rules/NoUnknownFiles.js +4 -3
- package/dist/Rules/Support/DependencyRule.d.ts +9 -1
- package/dist/Rules/Support/DependencyRule.js +15 -15
- package/dist/Rules/Support/DependencyRule.types.d.ts +1 -1
- package/dist/Rules/Support/Helpers.d.ts +6 -2
- package/dist/Rules/Support/Helpers.js +7 -31
- package/dist/Settings/Helpers.d.ts +83 -1
- package/dist/Settings/Helpers.js +197 -7
- package/dist/Settings/Settings.d.ts +19 -2
- package/dist/Settings/Settings.js +20 -10
- package/dist/Settings/Validations.d.ts +11958 -45
- package/dist/Settings/Validations.js +797 -184
- package/dist/Settings/index.d.ts +0 -1
- package/dist/Settings/index.js +0 -1
- package/dist/{Settings → Shared}/Settings.types.d.ts +143 -37
- package/dist/{Settings → Shared}/Settings.types.js +32 -6
- package/dist/{Support/Common.d.ts → Shared/TypeHelpers.d.ts} +18 -0
- package/dist/{Support/Common.js → Shared/TypeHelpers.js} +28 -1
- package/dist/Shared/index.d.ts +2 -0
- package/dist/Shared/index.js +18 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +12 -10
- package/package.json +9 -8
- package/dist/Rules/ElementTypes.d.ts +0 -25
- package/dist/Rules/ElementTypes.js +0 -279
- package/dist/Support/Debug.d.ts +0 -5
- package/dist/Support/Debug.js +0 -54
- package/dist/Support/index.d.ts +0 -2
package/dist/Rules/EntryPoint.js
CHANGED
|
@@ -1,121 +1,71 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const elements_1 = require("@boundaries/elements");
|
|
4
|
-
const Messages_1 = require("../Messages");
|
|
5
4
|
const Settings_1 = require("../Settings");
|
|
6
|
-
const
|
|
5
|
+
const Shared_1 = require("../Shared");
|
|
6
|
+
const Dependencies_1 = require("./Dependencies");
|
|
7
7
|
const Support_1 = require("./Support");
|
|
8
|
-
const { RULE_ENTRY_POINT } =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
if (ruleReport.isDefault) {
|
|
18
|
-
return `No rule allows the entry point '${dependency.to.internalPath}' in dependencies ${(0, Messages_1.elementMessage)(dependency.to)}`;
|
|
19
|
-
}
|
|
20
|
-
return `The entry point '${dependency.to.internalPath}' is not allowed in ${(0, Messages_1.ruleElementMessage)(ruleReport.disallow, dependency.to.captured)}${(0, Messages_1.dependencyUsageKindMessage)(ruleReport.importKind, dependency, {
|
|
21
|
-
prefix: " when importing ",
|
|
22
|
-
suffix: "",
|
|
23
|
-
})}. Disallowed in rule ${ruleReport.index + 1}`;
|
|
24
|
-
}
|
|
25
|
-
function modifyTemplates(templates) {
|
|
26
|
-
if (!templates) {
|
|
27
|
-
return undefined;
|
|
28
|
-
}
|
|
8
|
+
const { RULE_ENTRY_POINT } = Shared_1.SETTINGS;
|
|
9
|
+
/**
|
|
10
|
+
* Adapts legacy template placeholders from `target` to `to` notation.
|
|
11
|
+
*
|
|
12
|
+
* @param templates - Legacy templates from rule options.
|
|
13
|
+
* @returns Normalized templates or `undefined` when not provided.
|
|
14
|
+
*/
|
|
15
|
+
function modifyLegacyTemplates(templates) {
|
|
29
16
|
const templatesArray = Array.isArray(templates) ? templates : [templates];
|
|
30
17
|
return templatesArray.map((template) => template.replaceAll("${target.", "${to."));
|
|
31
18
|
}
|
|
32
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Converts `entry-point` legacy rules to `dependencies` rule shape.
|
|
21
|
+
*
|
|
22
|
+
* @param rules - Entry-point rules as defined by user configuration.
|
|
23
|
+
* @returns Equivalent dependencies rules for shared evaluator.
|
|
24
|
+
*/
|
|
25
|
+
function transformToDependenciesRules(rules) {
|
|
33
26
|
const newRules = [];
|
|
34
|
-
for (
|
|
35
|
-
const rule = rules[i];
|
|
27
|
+
for (const rule of rules) {
|
|
36
28
|
const newTargets = (0, elements_1.normalizeElementsSelector)(rule.target);
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
internalPath: modifyTemplates(rule.allow),
|
|
50
|
-
};
|
|
51
|
-
}),
|
|
52
|
-
allow: ["*"],
|
|
53
|
-
importKind: rule.importKind,
|
|
54
|
-
message: rule.message,
|
|
55
|
-
originalRuleIndex: i,
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
to: newTargets.map((target) => {
|
|
59
|
-
return {
|
|
60
|
-
...target,
|
|
61
|
-
internalPath: modifyTemplates(rule.disallow),
|
|
62
|
-
};
|
|
63
|
-
}),
|
|
64
|
-
disallow: ["*"],
|
|
65
|
-
importKind: rule.importKind,
|
|
66
|
-
message: rule.message,
|
|
67
|
-
originalRuleIndex: i,
|
|
68
|
-
},
|
|
69
|
-
];
|
|
70
|
-
newRules.push(...toAdd);
|
|
71
|
-
}
|
|
72
|
-
if (ruleHasDisallow) {
|
|
73
|
-
internalPathPatterns = modifyTemplates(rule.disallow);
|
|
74
|
-
disallowPattern = ["*"];
|
|
75
|
-
}
|
|
76
|
-
else if (ruleHasAllow) {
|
|
77
|
-
internalPathPatterns = modifyTemplates(rule.allow);
|
|
78
|
-
allowPattern = ["*"];
|
|
29
|
+
for (const target of newTargets) {
|
|
30
|
+
newRules.push({
|
|
31
|
+
to: target,
|
|
32
|
+
allow: rule.allow
|
|
33
|
+
? { to: { internalPath: modifyLegacyTemplates(rule.allow) } }
|
|
34
|
+
: undefined,
|
|
35
|
+
disallow: rule.disallow
|
|
36
|
+
? { to: { internalPath: modifyLegacyTemplates(rule.disallow) } }
|
|
37
|
+
: undefined,
|
|
38
|
+
importKind: rule.importKind,
|
|
39
|
+
message: rule.message,
|
|
40
|
+
});
|
|
79
41
|
}
|
|
80
|
-
newRules.push({
|
|
81
|
-
to: newTargets.map((target) => {
|
|
82
|
-
return {
|
|
83
|
-
...target,
|
|
84
|
-
internalPath: internalPathPatterns,
|
|
85
|
-
};
|
|
86
|
-
}),
|
|
87
|
-
allow: allowPattern,
|
|
88
|
-
disallow: disallowPattern,
|
|
89
|
-
importKind: rule.importKind,
|
|
90
|
-
message: rule.message,
|
|
91
|
-
// @ts-expect-error Workaround to support both allow and disallow in the same entry point rule
|
|
92
|
-
originalRuleIndex: i,
|
|
93
|
-
});
|
|
94
42
|
}
|
|
95
43
|
return newRules;
|
|
96
44
|
}
|
|
97
45
|
exports.default = (0, Support_1.dependencyRule)({
|
|
98
46
|
ruleName: RULE_ENTRY_POINT,
|
|
99
|
-
description: `Check entry point
|
|
47
|
+
description: `Check elements entry point`,
|
|
100
48
|
schema: (0, Settings_1.rulesOptionsSchema)({
|
|
101
49
|
rulesMainKey: "target",
|
|
50
|
+
isLegacy: true,
|
|
102
51
|
}),
|
|
103
52
|
}, function ({ dependency, node, context, settings, options }) {
|
|
53
|
+
(0, Settings_1.warnMigrationToDependencies)(Shared_1.RULE_NAMES_MAP.ENTRY_POINT);
|
|
54
|
+
// Validate and warn about legacy selector syntax
|
|
55
|
+
(0, Settings_1.validateAndWarnRuleOptions)(options, Shared_1.RULE_NAMES_MAP.ENTRY_POINT, "target");
|
|
104
56
|
if (!dependency.to.isIgnored &&
|
|
105
57
|
dependency.to.type &&
|
|
106
58
|
dependency.dependency.relationship.to !==
|
|
107
59
|
elements_1.DEPENDENCY_RELATIONSHIPS_MAP.INTERNAL) {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
rules
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
});
|
|
118
|
-
}
|
|
60
|
+
const rules = transformToDependenciesRules(options?.rules ?? []);
|
|
61
|
+
(0, Dependencies_1.evaluateRulesAndReport)({
|
|
62
|
+
rules,
|
|
63
|
+
settings,
|
|
64
|
+
context,
|
|
65
|
+
node,
|
|
66
|
+
options,
|
|
67
|
+
dependency,
|
|
68
|
+
});
|
|
119
69
|
}
|
|
120
70
|
}, {
|
|
121
71
|
validateRules: { onlyMainKey: true, mainKey: "target" },
|
package/dist/Rules/External.js
CHANGED
|
@@ -1,72 +1,103 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const elements_1 = require("@boundaries/elements");
|
|
4
|
-
const Messages_1 = require("../Messages");
|
|
5
4
|
const Settings_1 = require("../Settings");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const { RULE_EXTERNAL } =
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
const Shared_1 = require("../Shared");
|
|
6
|
+
const Dependencies_1 = require("./Dependencies");
|
|
7
|
+
const Support_1 = require("./Support");
|
|
8
|
+
const { RULE_EXTERNAL } = Shared_1.SETTINGS;
|
|
9
|
+
/**
|
|
10
|
+
* Type guard for external selectors using tuple syntax with options.
|
|
11
|
+
*
|
|
12
|
+
* @param selector - External library selector from rule options.
|
|
13
|
+
* @returns `true` when selector is `[module, options]`.
|
|
14
|
+
*/
|
|
15
|
+
function isExternalLibrarySelectorWithOptions(selector) {
|
|
16
|
+
return ((0, Shared_1.isArray)(selector) &&
|
|
17
|
+
selector.length === 2 &&
|
|
18
|
+
(0, Shared_1.isString)(selector[0]) &&
|
|
19
|
+
(0, Shared_1.isObject)(selector[1]));
|
|
17
20
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
})}external module '${dependency.to.baseSource}' ${fileReport}`;
|
|
21
|
+
/**
|
|
22
|
+
* Builds a dependency selector from a legacy external selector using tuple syntax with options.
|
|
23
|
+
* @param selector The external library selector in legacy format with options.
|
|
24
|
+
* @returns The corresponding dependency selector compatible with `dependencies` rule evaluator.
|
|
25
|
+
*/
|
|
26
|
+
function buildSelectorFromLegacySelectorWithOptions(selector) {
|
|
27
|
+
const moduleSelector = selector[0];
|
|
28
|
+
const selectorOptions = selector[1];
|
|
29
|
+
const hasPathSelector = !(0, Shared_1.isNullish)(selectorOptions.path);
|
|
30
|
+
return {
|
|
31
|
+
to: {
|
|
32
|
+
origin: [elements_1.ELEMENT_ORIGINS_MAP.EXTERNAL, elements_1.ELEMENT_ORIGINS_MAP.CORE],
|
|
33
|
+
...(hasPathSelector ? { internalPath: selectorOptions.path } : {}),
|
|
34
|
+
},
|
|
35
|
+
dependency: {
|
|
36
|
+
module: moduleSelector,
|
|
37
|
+
...(selectorOptions.specifiers
|
|
38
|
+
? {
|
|
39
|
+
specifiers: selectorOptions.specifiers,
|
|
40
|
+
}
|
|
41
|
+
: {}),
|
|
42
|
+
},
|
|
43
|
+
};
|
|
42
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Transforms legacy external selectors into dependency selectors.
|
|
47
|
+
*
|
|
48
|
+
* @param selectors - External selector(s) from legacy rule format.
|
|
49
|
+
* @returns Dependency selector(s) compatible with `dependencies` rule evaluator.
|
|
50
|
+
*/
|
|
43
51
|
function modifySelectors(selectors) {
|
|
44
52
|
const originsToMatch = [
|
|
45
53
|
elements_1.ELEMENT_ORIGINS_MAP.EXTERNAL,
|
|
46
54
|
elements_1.ELEMENT_ORIGINS_MAP.CORE,
|
|
47
55
|
];
|
|
48
|
-
if ((
|
|
49
|
-
return
|
|
56
|
+
if (isExternalLibrarySelectorWithOptions(selectors)) {
|
|
57
|
+
return buildSelectorFromLegacySelectorWithOptions(selectors);
|
|
50
58
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
if ((0, Shared_1.isString)(selectors)) {
|
|
60
|
+
return {
|
|
61
|
+
to: {
|
|
54
62
|
origin: originsToMatch,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
63
|
+
},
|
|
64
|
+
dependency: {
|
|
65
|
+
module: selectors,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return selectors.map((selector) => {
|
|
70
|
+
if (isExternalLibrarySelectorWithOptions(selector)) {
|
|
71
|
+
return buildSelectorFromLegacySelectorWithOptions(selector);
|
|
59
72
|
}
|
|
60
73
|
return {
|
|
61
|
-
origin: originsToMatch,
|
|
62
|
-
|
|
74
|
+
to: { origin: originsToMatch },
|
|
75
|
+
dependency: {
|
|
76
|
+
module: selector,
|
|
77
|
+
},
|
|
63
78
|
};
|
|
64
79
|
});
|
|
65
80
|
}
|
|
66
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Converts `external` legacy rules to `dependencies` rule shape.
|
|
83
|
+
*
|
|
84
|
+
* @param rules - External rules as configured by the user.
|
|
85
|
+
* @returns Equivalent dependencies rules consumed by shared evaluator.
|
|
86
|
+
*/
|
|
87
|
+
function transformToDependenciesRules(rules) {
|
|
88
|
+
return rules.map((rule) => ({
|
|
89
|
+
from: rule.from,
|
|
90
|
+
allow: rule.allow ? modifySelectors(rule.allow) : undefined,
|
|
91
|
+
disallow: rule.disallow ? modifySelectors(rule.disallow) : undefined,
|
|
92
|
+
importKind: rule.importKind,
|
|
93
|
+
message: rule.message,
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
exports.default = (0, Support_1.dependencyRule)({
|
|
67
97
|
ruleName: RULE_EXTERNAL,
|
|
68
|
-
description: `Check
|
|
98
|
+
description: `Check dependencies to external and core libraries`,
|
|
69
99
|
schema: (0, Settings_1.rulesOptionsSchema)({
|
|
100
|
+
isLegacy: true,
|
|
70
101
|
targetMatcherOptions: {
|
|
71
102
|
type: "object",
|
|
72
103
|
properties: {
|
|
@@ -77,7 +108,7 @@ exports.default = (0, Support_2.dependencyRule)({
|
|
|
77
108
|
},
|
|
78
109
|
},
|
|
79
110
|
path: {
|
|
80
|
-
|
|
111
|
+
anyOf: [
|
|
81
112
|
{
|
|
82
113
|
type: "string",
|
|
83
114
|
},
|
|
@@ -94,26 +125,20 @@ exports.default = (0, Support_2.dependencyRule)({
|
|
|
94
125
|
},
|
|
95
126
|
}),
|
|
96
127
|
}, function ({ dependency, node, context, settings, options }) {
|
|
128
|
+
(0, Settings_1.warnMigrationToDependencies)(Shared_1.RULE_NAMES_MAP.EXTERNAL);
|
|
129
|
+
// Validate and warn about legacy selector syntax
|
|
130
|
+
(0, Settings_1.validateAndWarnRuleOptions)(options, Shared_1.RULE_NAMES_MAP.EXTERNAL, "from");
|
|
97
131
|
if ((0, elements_1.isExternalDependencyElement)(dependency.to) ||
|
|
98
132
|
(0, elements_1.isCoreDependencyElement)(dependency.to)) {
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
: [],
|
|
109
|
-
};
|
|
110
|
-
const ruleData = (0, ElementTypes_1.elementRulesAllowDependency)(dependency, settings, adaptedRuleOptions);
|
|
111
|
-
if (!ruleData.result) {
|
|
112
|
-
context.report({
|
|
113
|
-
message: errorMessage(ruleData, dependency),
|
|
114
|
-
node: node,
|
|
115
|
-
});
|
|
116
|
-
}
|
|
133
|
+
const rules = transformToDependenciesRules(options?.rules ?? []);
|
|
134
|
+
(0, Dependencies_1.evaluateRulesAndReport)({
|
|
135
|
+
rules,
|
|
136
|
+
settings,
|
|
137
|
+
context,
|
|
138
|
+
node,
|
|
139
|
+
options,
|
|
140
|
+
dependency,
|
|
141
|
+
});
|
|
117
142
|
}
|
|
118
143
|
}, {
|
|
119
144
|
validateRules: { onlyMainKey: true },
|
package/dist/Rules/NoIgnored.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const Shared_1 = require("../Shared");
|
|
4
4
|
const Support_1 = require("./Support");
|
|
5
|
-
const { RULE_NO_IGNORED } =
|
|
5
|
+
const { RULE_NO_IGNORED } = Shared_1.SETTINGS;
|
|
6
6
|
exports.default = (0, Support_1.dependencyRule)({
|
|
7
7
|
schema: [],
|
|
8
8
|
ruleName: RULE_NO_IGNORED,
|
|
9
|
-
description: `Prevent
|
|
9
|
+
description: `Prevent dependencies to ignored files from recognized elements`,
|
|
10
10
|
}, function ({ dependency, node, context }) {
|
|
11
11
|
if (dependency.to.isIgnored) {
|
|
12
12
|
context.report({
|
|
13
|
-
message: `
|
|
13
|
+
message: `Dependencies to ignored files are not allowed`,
|
|
14
14
|
node: node,
|
|
15
15
|
});
|
|
16
16
|
}
|
package/dist/Rules/NoPrivate.js
CHANGED
|
@@ -3,18 +3,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const elements_1 = require("@boundaries/elements");
|
|
4
4
|
const Messages_1 = require("../Messages");
|
|
5
5
|
const Settings_1 = require("../Settings");
|
|
6
|
+
const Shared_1 = require("../Shared");
|
|
6
7
|
const Support_1 = require("./Support");
|
|
7
|
-
const { RULE_NO_PRIVATE } =
|
|
8
|
+
const { RULE_NO_PRIVATE } = Shared_1.SETTINGS;
|
|
9
|
+
/**
|
|
10
|
+
* Builds the user-facing error message for private dependency violations.
|
|
11
|
+
*
|
|
12
|
+
* @param dependency - Described dependency that triggered the violation.
|
|
13
|
+
* @param options - Optional rule options with custom message template.
|
|
14
|
+
* @returns Final error message reported by ESLint.
|
|
15
|
+
*/
|
|
8
16
|
function errorMessage(dependency, options) {
|
|
9
17
|
if (options?.message) {
|
|
10
18
|
return (0, Messages_1.customErrorMessage)(options.message, dependency);
|
|
11
19
|
}
|
|
12
|
-
|
|
13
|
-
|
|
20
|
+
const privateParent = dependency.to.parents?.[0];
|
|
21
|
+
/* istanbul ignore next - Defensive: This should not happen */
|
|
22
|
+
if (!privateParent) {
|
|
23
|
+
return `Not able to create a message for this violation. Please report this at: ${Shared_1.PLUGIN_ISSUES_URL}`;
|
|
24
|
+
}
|
|
25
|
+
return `Dependency is private of ${(0, Messages_1.elementDescriptionMessage)(privateParent, ["type", "category", "captured"], { singleElement: true })}`;
|
|
14
26
|
}
|
|
15
27
|
exports.default = (0, Support_1.dependencyRule)({
|
|
16
28
|
ruleName: RULE_NO_PRIVATE,
|
|
17
|
-
description: `Prevent
|
|
29
|
+
description: `Prevent dependencies to private elements`,
|
|
18
30
|
schema: [
|
|
19
31
|
{
|
|
20
32
|
type: "object",
|
|
@@ -30,8 +42,9 @@ exports.default = (0, Support_1.dependencyRule)({
|
|
|
30
42
|
},
|
|
31
43
|
],
|
|
32
44
|
}, function ({ dependency, node, context, options }) {
|
|
45
|
+
(0, Settings_1.warnMigrationToDependencies)(Shared_1.RULE_NAMES_MAP.NO_PRIVATE);
|
|
33
46
|
if (!dependency.to.isIgnored &&
|
|
34
|
-
(0, elements_1.
|
|
47
|
+
(0, elements_1.isLocalElement)(dependency.to) &&
|
|
35
48
|
dependency.to.type &&
|
|
36
49
|
dependency.to.parents.length &&
|
|
37
50
|
dependency.dependency.relationship.to !==
|
package/dist/Rules/NoUnknown.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const elements_1 = require("@boundaries/elements");
|
|
4
|
-
const
|
|
4
|
+
const Shared_1 = require("../Shared");
|
|
5
5
|
const Support_1 = require("./Support");
|
|
6
|
-
const { RULE_NO_UNKNOWN } =
|
|
6
|
+
const { RULE_NO_UNKNOWN } = Shared_1.SETTINGS;
|
|
7
7
|
exports.default = (0, Support_1.dependencyRule)({
|
|
8
8
|
schema: [],
|
|
9
9
|
ruleName: RULE_NO_UNKNOWN,
|
|
10
|
-
description: `Prevent
|
|
10
|
+
description: `Prevent dependencies to unknown elements`,
|
|
11
11
|
}, function ({ dependency, node, context }) {
|
|
12
12
|
if (!dependency.to.isIgnored &&
|
|
13
|
-
(0, elements_1.
|
|
13
|
+
(0, elements_1.isLocalElement)(dependency.to) &&
|
|
14
14
|
dependency.to.isUnknown) {
|
|
15
15
|
context.report({
|
|
16
|
-
message: `
|
|
16
|
+
message: `Dependencies to unknown elements are not allowed`,
|
|
17
17
|
node: node,
|
|
18
18
|
});
|
|
19
19
|
}
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const Elements_1 = require("../Elements");
|
|
4
4
|
const Settings_1 = require("../Settings");
|
|
5
|
+
const Shared_1 = require("../Shared");
|
|
5
6
|
const Support_1 = require("./Support");
|
|
6
|
-
const { RULE_NO_UNKNOWN_FILES } =
|
|
7
|
+
const { RULE_NO_UNKNOWN_FILES } = Shared_1.SETTINGS;
|
|
7
8
|
const noUnknownFilesRule = {
|
|
8
9
|
...(0, Support_1.meta)({
|
|
9
10
|
ruleName: RULE_NO_UNKNOWN_FILES,
|
|
10
11
|
schema: [],
|
|
11
|
-
description: `Prevent creating files not recognized
|
|
12
|
+
description: `Prevent creating files not recognized by any element patterns`,
|
|
12
13
|
}),
|
|
13
14
|
create: function (context) {
|
|
14
15
|
const settings = (0, Settings_1.getSettings)(context);
|
|
@@ -19,7 +20,7 @@ const noUnknownFilesRule = {
|
|
|
19
20
|
return {
|
|
20
21
|
Program: (node) => {
|
|
21
22
|
context.report({
|
|
22
|
-
message: `File
|
|
23
|
+
message: `File does not match any element pattern`,
|
|
23
24
|
node: node,
|
|
24
25
|
});
|
|
25
26
|
},
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { Rule } from "eslint";
|
|
2
|
-
import type { RuleOptionsWithRules, RuleMetaDefinition } from "../../
|
|
2
|
+
import type { RuleOptionsWithRules, RuleMetaDefinition } from "../../Shared";
|
|
3
3
|
import type { DependencyRuleRunner, DependencyRuleOptions } from "./DependencyRule.types";
|
|
4
|
+
/**
|
|
5
|
+
* Creates a rule module that evaluates dependency nodes using shared matcher logic.
|
|
6
|
+
*
|
|
7
|
+
* @param ruleMeta - Metadata used to build ESLint rule `meta` information.
|
|
8
|
+
* @param rule - Rule runner invoked for each described dependency.
|
|
9
|
+
* @param ruleOptions - Optional behavior flags for validation and rule shape.
|
|
10
|
+
* @returns ESLint rule module ready to be exported by concrete rules.
|
|
11
|
+
*/
|
|
4
12
|
export declare function dependencyRule<Options extends RuleOptionsWithRules>(ruleMeta: RuleMetaDefinition, rule: DependencyRuleRunner<Options>, ruleOptions?: DependencyRuleOptions): Rule.RuleModule;
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.dependencyRule = dependencyRule;
|
|
4
|
+
const Debug_1 = require("../../Debug");
|
|
4
5
|
const Elements_1 = require("../../Elements");
|
|
5
6
|
const Settings_1 = require("../../Settings");
|
|
6
|
-
const
|
|
7
|
+
const Shared_1 = require("../../Shared");
|
|
7
8
|
const Helpers_1 = require("./Helpers");
|
|
8
|
-
const { ADDITIONAL_DEPENDENCY_NODES } =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
const { ADDITIONAL_DEPENDENCY_NODES } = Shared_1.SETTINGS;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a rule module that evaluates dependency nodes using shared matcher logic.
|
|
12
|
+
*
|
|
13
|
+
* @param ruleMeta - Metadata used to build ESLint rule `meta` information.
|
|
14
|
+
* @param rule - Rule runner invoked for each described dependency.
|
|
15
|
+
* @param ruleOptions - Optional behavior flags for validation and rule shape.
|
|
16
|
+
* @returns ESLint rule module ready to be exported by concrete rules.
|
|
17
|
+
*/
|
|
15
18
|
function dependencyRule(ruleMeta, rule, ruleOptions = {}) {
|
|
16
19
|
return {
|
|
17
20
|
...(0, Helpers_1.meta)(ruleMeta),
|
|
@@ -22,17 +25,14 @@ function dependencyRule(ruleMeta, rule, ruleOptions = {}) {
|
|
|
22
25
|
if (ruleOptions.validate !== false && !options) {
|
|
23
26
|
return {};
|
|
24
27
|
}
|
|
25
|
-
if (
|
|
26
|
-
(0, Settings_1.validateRules)(settings, options.rules, ruleOptions.validateRules);
|
|
27
|
-
}
|
|
28
|
-
// TODO: Remove this check when allowing to select by any other property
|
|
29
|
-
if (file.isIgnored || !file.type) {
|
|
28
|
+
if (file.isIgnored || file.isUnknown) {
|
|
30
29
|
return {};
|
|
31
30
|
}
|
|
32
31
|
return settings.dependencyNodes.reduce((visitors, { selector, kind, name }) => {
|
|
33
32
|
visitors[selector] = (node) => {
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
/* istanbul ignore next - Defensive check */
|
|
34
|
+
if (!(0, Shared_1.isString)(node.value)) {
|
|
35
|
+
(0, Debug_1.warnOnce)(`Dependency node value is not a string, skipping node.`, `Please check your ${ADDITIONAL_DEPENDENCY_NODES} setting. ${(0, Settings_1.moreInfoSettingsLink)()}`);
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
const dependency = (0, Elements_1.dependencyDescription)({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DependencyDescription } from "@boundaries/elements";
|
|
2
2
|
import type { Rule } from "eslint";
|
|
3
3
|
import type { EslintLiteralNode } from "../../Elements";
|
|
4
|
-
import type { ValidateRulesOptions, SettingsNormalized } from "../../
|
|
4
|
+
import type { ValidateRulesOptions, SettingsNormalized } from "../../Shared";
|
|
5
5
|
export type DependencyRuleRunner<Options> = (options: {
|
|
6
6
|
dependency: DependencyDescription;
|
|
7
7
|
options?: Options;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { Rule } from "eslint";
|
|
2
|
-
import type { RuleMetaDefinition } from "../../
|
|
2
|
+
import type { RuleMetaDefinition } from "../../Shared";
|
|
3
3
|
/**
|
|
4
4
|
* Returns the meta object for an ESLint rule.
|
|
5
|
-
* @param
|
|
5
|
+
* @param options The rule metadata definition.
|
|
6
|
+
* @param options.description The description of the rule.
|
|
7
|
+
* @param options.schema The JSON schema for rule options validation.
|
|
8
|
+
* @param options.ruleName The name of the rule.
|
|
9
|
+
* @param options.type The type of the rule (problem, suggestion, or layout).
|
|
6
10
|
* @returns The meta object for the ESLint rule.
|
|
7
11
|
*/
|
|
8
12
|
export declare function meta({ description, schema, ruleName, type, }: RuleMetaDefinition): Pick<Rule.RuleModule, "meta">;
|
|
@@ -2,46 +2,22 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.meta = meta;
|
|
4
4
|
const Settings_1 = require("../../Settings");
|
|
5
|
-
/**
|
|
6
|
-
* Removes the plugin namespace from a rule name.
|
|
7
|
-
* @param ruleName The name of the rule.
|
|
8
|
-
* @returns The rule name without the plugin namespace.
|
|
9
|
-
*/
|
|
10
|
-
function removePluginNamespace(ruleName) {
|
|
11
|
-
return ruleName.replace(`${Settings_1.PLUGIN_NAME}/`, "");
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Adapts the rule name to be used in a URL.
|
|
15
|
-
* @param ruleName The name of the rule.
|
|
16
|
-
* @returns The adapted rule name for URL usage.
|
|
17
|
-
*/
|
|
18
|
-
function adaptRuleNameToUrl(ruleName) {
|
|
19
|
-
// NOTE: Urls are already prepared for the next major release where "element-types" rule will be renamed to "dependencies", so no 301 redirect will be needed then.
|
|
20
|
-
if (ruleName === "element-types") {
|
|
21
|
-
return "dependencies";
|
|
22
|
-
}
|
|
23
|
-
return ruleName;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Returns the documentation URL for an ESLint rule.
|
|
27
|
-
* @param ruleName The name of the rule.
|
|
28
|
-
* @returns The documentation URL for the ESLint rule.
|
|
29
|
-
*/
|
|
30
|
-
function docsUrl(ruleName) {
|
|
31
|
-
return `${Settings_1.WEBSITE_URL}/docs/rules/${adaptRuleNameToUrl(removePluginNamespace(ruleName))}/`;
|
|
32
|
-
}
|
|
33
5
|
/**
|
|
34
6
|
* Returns the meta object for an ESLint rule.
|
|
35
|
-
* @param
|
|
7
|
+
* @param options The rule metadata definition.
|
|
8
|
+
* @param options.description The description of the rule.
|
|
9
|
+
* @param options.schema The JSON schema for rule options validation.
|
|
10
|
+
* @param options.ruleName The name of the rule.
|
|
11
|
+
* @param options.type The type of the rule (problem, suggestion, or layout).
|
|
36
12
|
* @returns The meta object for the ESLint rule.
|
|
37
13
|
*/
|
|
38
|
-
function meta({ description, schema
|
|
14
|
+
function meta({ description, schema, ruleName, type, }) {
|
|
39
15
|
return {
|
|
40
16
|
meta: {
|
|
41
17
|
// TODO: Consider changing default to "suggestion" in a future major release, because most rules are not fixing code issues, but only suggesting best practices.
|
|
42
18
|
type: type || "problem",
|
|
43
19
|
docs: {
|
|
44
|
-
url:
|
|
20
|
+
url: (0, Settings_1.ruleDocsUrl)(ruleName),
|
|
45
21
|
description,
|
|
46
22
|
category: "dependencies",
|
|
47
23
|
},
|