@dineroregnskab/eslint-plugin-custom-rules 4.5.0 → 4.7.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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dineroregnskab/eslint-plugin-custom-rules",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.0",
|
|
4
4
|
"description": "ESLint plugin with custom rules for Dinero Regnskab",
|
|
5
5
|
"main": "eslint-plugin-custom-rules.js",
|
|
6
6
|
"scripts": {
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
"author": "",
|
|
11
11
|
"license": "ISC",
|
|
12
12
|
"devDependencies": {
|
|
13
|
-
"@typescript-eslint/parser": "^8.
|
|
14
|
-
"eslint": "^9.
|
|
15
|
-
"eslint-config-prettier": "^10.1.
|
|
16
|
-
"eslint-plugin-prettier": "^5.
|
|
17
|
-
"prettier": "^3.
|
|
18
|
-
"@angular-eslint/template-parser": "^
|
|
13
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
14
|
+
"eslint": "^9.39.2",
|
|
15
|
+
"eslint-config-prettier": "^10.1.8",
|
|
16
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
17
|
+
"prettier": "^3.8.1",
|
|
18
|
+
"@angular-eslint/template-parser": "^21.2.0"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"eslint": ">=8.0.0",
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
meta: {
|
|
3
|
-
type:
|
|
3
|
+
type: 'suggestion',
|
|
4
4
|
docs: {
|
|
5
|
-
description:
|
|
5
|
+
description:
|
|
6
|
+
'Reminder to convert backend data to lowercase when enum comparisons are made.',
|
|
6
7
|
},
|
|
7
8
|
schema: [],
|
|
8
9
|
messages: {
|
|
9
|
-
enumComparisonTip:
|
|
10
|
-
|
|
10
|
+
enumComparisonTip:
|
|
11
|
+
"Remember '{{property}}' should be converted to lowercase in the model class if the data is from a HTTP response, to ensure a valid comparison.",
|
|
12
|
+
},
|
|
11
13
|
},
|
|
12
14
|
create(context) {
|
|
13
15
|
// Handle TypeScript Files
|
|
14
16
|
function checkTsEnumComparisons(node) {
|
|
15
|
-
if (node.operator !==
|
|
17
|
+
if (node.operator !== '===' && node.operator !== '!==') {
|
|
16
18
|
return;
|
|
17
19
|
}
|
|
18
20
|
|
|
@@ -24,27 +26,39 @@ module.exports = {
|
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
function isPropertyAccess(node) {
|
|
27
|
-
return
|
|
29
|
+
return (
|
|
30
|
+
node.type === 'MemberExpression' &&
|
|
31
|
+
node.object &&
|
|
32
|
+
node.property
|
|
33
|
+
);
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
function isEnumReference(node) {
|
|
31
|
-
return
|
|
37
|
+
return (
|
|
38
|
+
isPropertyAccess(node) &&
|
|
39
|
+
node.object.type === 'Identifier' &&
|
|
40
|
+
isPascalCase(node.object.name)
|
|
41
|
+
);
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
if (
|
|
35
45
|
(isPropertyAccess(left) && isEnumReference(right)) ||
|
|
36
46
|
(isPropertyAccess(right) && isEnumReference(left))
|
|
37
47
|
) {
|
|
38
|
-
const property = isPropertyAccess(left)
|
|
39
|
-
|
|
48
|
+
const property = isPropertyAccess(left)
|
|
49
|
+
? context.getSourceCode().getText(left)
|
|
50
|
+
: context.getSourceCode().getText(right);
|
|
51
|
+
const enumValue = isEnumReference(left)
|
|
52
|
+
? context.getSourceCode().getText(left)
|
|
53
|
+
: context.getSourceCode().getText(right);
|
|
40
54
|
|
|
41
55
|
context.report({
|
|
42
56
|
node,
|
|
43
|
-
messageId:
|
|
57
|
+
messageId: 'enumComparisonTip',
|
|
44
58
|
data: {
|
|
45
59
|
property,
|
|
46
|
-
enumValue
|
|
47
|
-
}
|
|
60
|
+
enumValue,
|
|
61
|
+
},
|
|
48
62
|
});
|
|
49
63
|
}
|
|
50
64
|
}
|
|
@@ -52,15 +66,15 @@ module.exports = {
|
|
|
52
66
|
// Handle Angular Templates (`*.html`)
|
|
53
67
|
function checkHtmlEnumComparisons(node) {
|
|
54
68
|
if (
|
|
55
|
-
node.type !==
|
|
56
|
-
node.type !==
|
|
69
|
+
node.type !== 'Binary' &&
|
|
70
|
+
node.type !== 'Conditional' // Some AST parsers use ConditionalExpression
|
|
57
71
|
) {
|
|
58
72
|
return;
|
|
59
73
|
}
|
|
60
74
|
|
|
61
75
|
// Ensure we're checking the correct properties
|
|
62
76
|
const operator = node.operator || node.operation; // Adjust for Angular's AST
|
|
63
|
-
if (operator !==
|
|
77
|
+
if (operator !== '===' && operator !== '!==') {
|
|
64
78
|
return;
|
|
65
79
|
}
|
|
66
80
|
|
|
@@ -68,14 +82,17 @@ module.exports = {
|
|
|
68
82
|
const right = node.right;
|
|
69
83
|
|
|
70
84
|
function isPascalCase(value) {
|
|
71
|
-
return
|
|
85
|
+
return (
|
|
86
|
+
typeof value === 'string' &&
|
|
87
|
+
/^[A-Z][a-zA-Z0-9]*$/.test(value)
|
|
88
|
+
);
|
|
72
89
|
}
|
|
73
90
|
|
|
74
91
|
function extractNodeText(node) {
|
|
75
|
-
if (node && typeof node ===
|
|
92
|
+
if (node && typeof node === 'object' && node.name) {
|
|
76
93
|
return node.name;
|
|
77
94
|
}
|
|
78
|
-
return
|
|
95
|
+
return '';
|
|
79
96
|
}
|
|
80
97
|
|
|
81
98
|
const leftValue = extractNodeText(left);
|
|
@@ -84,11 +101,11 @@ module.exports = {
|
|
|
84
101
|
if (isPascalCase(leftValue) || isPascalCase(rightValue)) {
|
|
85
102
|
context.report({
|
|
86
103
|
node,
|
|
87
|
-
messageId:
|
|
104
|
+
messageId: 'enumComparisonTip',
|
|
88
105
|
data: {
|
|
89
106
|
property: leftValue || rightValue,
|
|
90
|
-
enumValue: rightValue || leftValue
|
|
91
|
-
}
|
|
107
|
+
enumValue: rightValue || leftValue,
|
|
108
|
+
},
|
|
92
109
|
});
|
|
93
110
|
}
|
|
94
111
|
}
|
|
@@ -96,8 +113,7 @@ module.exports = {
|
|
|
96
113
|
return {
|
|
97
114
|
BinaryExpression: checkTsEnumComparisons, // ✅ TypeScript file support
|
|
98
115
|
Binary: checkHtmlEnumComparisons, // ✅ Angular v18 template (`@if`) support
|
|
99
|
-
ConditionalExpression: checkHtmlEnumComparisons // Support variations
|
|
116
|
+
ConditionalExpression: checkHtmlEnumComparisons, // Support variations
|
|
100
117
|
};
|
|
101
|
-
}
|
|
118
|
+
},
|
|
102
119
|
};
|
|
103
|
-
|
package/rules/enum-lowercase.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
meta: {
|
|
3
|
-
type:
|
|
3
|
+
type: 'suggestion',
|
|
4
4
|
docs: {
|
|
5
|
-
description:
|
|
5
|
+
description:
|
|
6
|
+
'Warn when an enum string value is not in full lowercase.',
|
|
6
7
|
},
|
|
7
8
|
schema: [],
|
|
8
9
|
messages: {
|
|
9
10
|
enumLowercase:
|
|
10
|
-
"Enum value '{{enumKey}}' should be in full lowercase (e.g., '{{suggestedValue}}'). Avoid uppercase, spaces, dashes, or special characters."
|
|
11
|
-
}
|
|
11
|
+
"Enum value '{{enumKey}}' should be in full lowercase (e.g., '{{suggestedValue}}'). Avoid uppercase, spaces, dashes, or special characters.",
|
|
12
|
+
},
|
|
12
13
|
},
|
|
13
14
|
create(context) {
|
|
14
15
|
return {
|
|
@@ -16,8 +17,8 @@ module.exports = {
|
|
|
16
17
|
node.members.forEach((member) => {
|
|
17
18
|
if (
|
|
18
19
|
member.initializer &&
|
|
19
|
-
member.initializer.type ===
|
|
20
|
-
typeof member.initializer.value ===
|
|
20
|
+
member.initializer.type === 'Literal' &&
|
|
21
|
+
typeof member.initializer.value === 'string'
|
|
21
22
|
) {
|
|
22
23
|
const enumKey = member.id.name; // The enum key (e.g., "TaxTotal")
|
|
23
24
|
const enumValue = member.initializer.value; // The string value (e.g., "TaxTotal")
|
|
@@ -26,7 +27,7 @@ module.exports = {
|
|
|
26
27
|
if (!/^[a-z]+$/.test(enumValue)) {
|
|
27
28
|
context.report({
|
|
28
29
|
node: member.initializer,
|
|
29
|
-
messageId:
|
|
30
|
+
messageId: 'enumLowercase',
|
|
30
31
|
data: {
|
|
31
32
|
enumKey,
|
|
32
33
|
suggestedValue: enumValue.toLowerCase(),
|
|
@@ -35,7 +36,7 @@ module.exports = {
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
});
|
|
38
|
-
}
|
|
39
|
+
},
|
|
39
40
|
};
|
|
40
|
-
}
|
|
41
|
+
},
|
|
41
42
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
meta: {
|
|
3
|
-
type: '
|
|
3
|
+
type: 'problem',
|
|
4
4
|
docs: {
|
|
5
5
|
description:
|
|
6
|
-
'
|
|
6
|
+
'Error when an it() block is missing awaitFeatureReady while createUserWithOrganization uses featureToggles without awaiting',
|
|
7
7
|
category: 'Best Practices',
|
|
8
8
|
recommended: true,
|
|
9
9
|
},
|