@dineroregnskab/eslint-plugin-custom-rules 3.0.0 → 3.0.2
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/.DS_Store +0 -0
- package/eslint-plugin-custom-rules.js +2 -0
- package/package.json +1 -1
- package/rules/enum-comparison-reminder.js +103 -0
- package/rules/enum-lowercase.js +41 -0
package/.DS_Store
ADDED
|
Binary file
|
|
@@ -9,6 +9,8 @@ const rules = {
|
|
|
9
9
|
'signal-naming-convention': require('./rules/signal-naming-convention'),
|
|
10
10
|
'filter-before-take': require('./rules/filter-before-take'),
|
|
11
11
|
'no-viewencapsulation-none': require('./rules/no-viewencapsulation-none'),
|
|
12
|
+
'enum-comparison-reminder': require('./rules/enum-comparison-reminder'),
|
|
13
|
+
'enum-lowercase': require('./rules/enum-lowercase'),
|
|
12
14
|
};
|
|
13
15
|
|
|
14
16
|
console.log('Custom ESLint rules loaded:', Object.keys(rules)); // Debug log
|
package/package.json
CHANGED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
meta: {
|
|
3
|
+
type: "suggestion",
|
|
4
|
+
docs: {
|
|
5
|
+
description: "Reminder to convert backend data to lower case when enum comparisons are made.",
|
|
6
|
+
},
|
|
7
|
+
schema: [],
|
|
8
|
+
messages: {
|
|
9
|
+
enumComparisonTip: "Remember '{{property}}' should be converted to lower case in the model class if the data is from a HTTP response, to ensure a valid comparison."
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
create(context) {
|
|
13
|
+
// Handle TypeScript Files
|
|
14
|
+
function checkTsEnumComparisons(node) {
|
|
15
|
+
if (node.operator !== "===" && node.operator !== "!==") {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const left = node.left;
|
|
20
|
+
const right = node.right;
|
|
21
|
+
|
|
22
|
+
function isPascalCase(value) {
|
|
23
|
+
return /^[A-Z][a-zA-Z0-9]*$/.test(value);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isPropertyAccess(node) {
|
|
27
|
+
return node.type === "MemberExpression" && node.object && node.property;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function isEnumReference(node) {
|
|
31
|
+
return isPropertyAccess(node) && node.object.type === "Identifier" && isPascalCase(node.object.name);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (
|
|
35
|
+
(isPropertyAccess(left) && isEnumReference(right)) ||
|
|
36
|
+
(isPropertyAccess(right) && isEnumReference(left))
|
|
37
|
+
) {
|
|
38
|
+
const property = isPropertyAccess(left) ? context.getSourceCode().getText(left) : context.getSourceCode().getText(right);
|
|
39
|
+
const enumValue = isEnumReference(left) ? context.getSourceCode().getText(left) : context.getSourceCode().getText(right);
|
|
40
|
+
|
|
41
|
+
context.report({
|
|
42
|
+
node,
|
|
43
|
+
messageId: "enumComparisonTip",
|
|
44
|
+
data: {
|
|
45
|
+
property,
|
|
46
|
+
enumValue
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Handle Angular Templates (`*.html`)
|
|
53
|
+
function checkHtmlEnumComparisons(node) {
|
|
54
|
+
if (
|
|
55
|
+
node.type !== "Binary" &&
|
|
56
|
+
node.type !== "Conditional" // Some AST parsers use ConditionalExpression
|
|
57
|
+
) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Ensure we're checking the correct properties
|
|
62
|
+
const operator = node.operator || node.operation; // Adjust for Angular's AST
|
|
63
|
+
if (operator !== "===" && operator !== "!==") {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const left = node.left;
|
|
68
|
+
const right = node.right;
|
|
69
|
+
|
|
70
|
+
function isPascalCase(value) {
|
|
71
|
+
return typeof value === "string" && /^[A-Z][a-zA-Z0-9]*$/.test(value);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function extractNodeText(node) {
|
|
75
|
+
if (node && typeof node === "object" && node.name) {
|
|
76
|
+
return node.name;
|
|
77
|
+
}
|
|
78
|
+
return "";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const leftValue = extractNodeText(left);
|
|
82
|
+
const rightValue = extractNodeText(right);
|
|
83
|
+
|
|
84
|
+
if (isPascalCase(leftValue) || isPascalCase(rightValue)) {
|
|
85
|
+
context.report({
|
|
86
|
+
node,
|
|
87
|
+
messageId: "enumComparisonTip",
|
|
88
|
+
data: {
|
|
89
|
+
property: leftValue || rightValue,
|
|
90
|
+
enumValue: rightValue || leftValue
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
BinaryExpression: checkTsEnumComparisons, // ✅ TypeScript file support
|
|
98
|
+
Binary: checkHtmlEnumComparisons, // ✅ Angular v18 template (`@if`) support
|
|
99
|
+
ConditionalExpression: checkHtmlEnumComparisons // Support variations
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
meta: {
|
|
3
|
+
type: "suggestion",
|
|
4
|
+
docs: {
|
|
5
|
+
description: "Warn when an enum string value is not in full lowercase.",
|
|
6
|
+
},
|
|
7
|
+
schema: [],
|
|
8
|
+
messages: {
|
|
9
|
+
enumLowercase:
|
|
10
|
+
"Enum value '{{enumKey}}' should be in full lowercase (e.g., '{{suggestedValue}}'). Avoid uppercase, spaces, dashes, or special characters."
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
create(context) {
|
|
14
|
+
return {
|
|
15
|
+
TSEnumDeclaration(node) {
|
|
16
|
+
node.members.forEach((member) => {
|
|
17
|
+
if (
|
|
18
|
+
member.initializer &&
|
|
19
|
+
member.initializer.type === "Literal" &&
|
|
20
|
+
typeof member.initializer.value === "string"
|
|
21
|
+
) {
|
|
22
|
+
const enumKey = member.id.name; // The enum key (e.g., "TaxTotal")
|
|
23
|
+
const enumValue = member.initializer.value; // The string value (e.g., "TaxTotal")
|
|
24
|
+
|
|
25
|
+
// Check if the value is not fully lowercase
|
|
26
|
+
if (!/^[a-z]+$/.test(enumValue)) {
|
|
27
|
+
context.report({
|
|
28
|
+
node: member.initializer,
|
|
29
|
+
messageId: "enumLowercase",
|
|
30
|
+
data: {
|
|
31
|
+
enumKey,
|
|
32
|
+
suggestedValue: enumValue.toLowerCase(),
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
};
|