@dineroregnskab/eslint-plugin-custom-rules 3.0.1 → 4.0.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/README.md +2 -2
- package/eslint-plugin-custom-rules.js +0 -2
- package/package.json +10 -11
- package/.DS_Store +0 -0
- package/rules/enum-comparison-reminder.js +0 -103
- package/rules/enum-lowercase.js +0 -50
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ Run `npm i` in root and in `/example`.
|
|
|
22
22
|
|
|
23
23
|
- Add the new rule to this file `./eslint-plugin-custom-rules.js`.
|
|
24
24
|
|
|
25
|
-
- Add the new rule to `./example
|
|
25
|
+
- Add the new rule to `./example/eslint.config.mjs`
|
|
26
26
|
|
|
27
27
|
- Test the rule by adding some HTML/TS code here `./example/test.html` or `./example/test.ts` and restart the ESLint server in vs code by pressing F1 -> ESLint: Restart ESLint Server.
|
|
28
28
|
|
|
@@ -71,7 +71,7 @@ npm version {version_type} && npm publish
|
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
- In dinero.Frontend and/or dinero.Admin, update the root `package.json` file with the newly published version number.
|
|
74
|
-
- Locate the `eslintrc` file and add the new rule in the rules property (under `"files": ["*.html"]`, `"files": ["*.ts"]` etc. respectively).
|
|
74
|
+
- Locate the `eslintrc` or the newer `eslint.config.mjs` file and add the new rule in the rules property (under `"files": ["*.html"]`, `"files": ["*.ts"]` etc. respectively).
|
|
75
75
|
|
|
76
76
|
> **Note: The reference here must be in the format of the package name without "eslint-plugin" + rule name**
|
|
77
77
|
|
|
@@ -9,8 +9,6 @@ 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'),
|
|
14
12
|
};
|
|
15
13
|
|
|
16
14
|
console.log('Custom ESLint rules loaded:', Object.keys(rules)); // Debug log
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dineroregnskab/eslint-plugin-custom-rules",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "ESLint plugin with custom rules for Dinero Regnskab",
|
|
5
5
|
"main": "eslint-plugin-custom-rules.js",
|
|
6
6
|
"scripts": {
|
|
@@ -10,21 +10,20 @@
|
|
|
10
10
|
"author": "",
|
|
11
11
|
"license": "ISC",
|
|
12
12
|
"devDependencies": {
|
|
13
|
-
"@typescript-eslint/parser": "^
|
|
14
|
-
"eslint": "
|
|
15
|
-
"eslint-config-prettier": "^
|
|
16
|
-
"eslint-plugin-prettier": "^5.2.
|
|
17
|
-
"prettier": "^3.
|
|
13
|
+
"@typescript-eslint/parser": "^8.26.1",
|
|
14
|
+
"eslint": "^9.22.0",
|
|
15
|
+
"eslint-config-prettier": "^10.1.1",
|
|
16
|
+
"eslint-plugin-prettier": "^5.2.3",
|
|
17
|
+
"prettier": "^3.5.3",
|
|
18
|
+
"@angular-eslint/template-parser": "^19.2.1"
|
|
18
19
|
},
|
|
19
20
|
"peerDependencies": {
|
|
20
21
|
"eslint": ">=8.0.0",
|
|
21
|
-
"@typescript-eslint/parser": ">=7"
|
|
22
|
+
"@typescript-eslint/parser": ">=7",
|
|
23
|
+
"@angular-eslint/template-parser": ">=17"
|
|
22
24
|
},
|
|
23
25
|
"files": [
|
|
24
26
|
"**/*",
|
|
25
27
|
"!example/**/*"
|
|
26
|
-
]
|
|
27
|
-
"dependencies": {
|
|
28
|
-
"@angular-eslint/template-parser": "17.5.3"
|
|
29
|
-
}
|
|
28
|
+
]
|
|
30
29
|
}
|
package/.DS_Store
DELETED
|
Binary file
|
|
@@ -1,103 +0,0 @@
|
|
|
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
|
-
|
package/rules/enum-lowercase.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
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
|
-
VariableDeclarator(node) {
|
|
16
|
-
// Check if it's an Enum declaration
|
|
17
|
-
if (
|
|
18
|
-
node.init &&
|
|
19
|
-
node.init.type === "ObjectExpression" &&
|
|
20
|
-
node.id.type === "Identifier"
|
|
21
|
-
) {
|
|
22
|
-
node.init.properties.forEach((prop) => {
|
|
23
|
-
if (
|
|
24
|
-
prop.key &&
|
|
25
|
-
prop.key.type === "Identifier" &&
|
|
26
|
-
prop.value &&
|
|
27
|
-
prop.value.type === "Literal" &&
|
|
28
|
-
typeof prop.value.value === "string"
|
|
29
|
-
) {
|
|
30
|
-
const enumKey = prop.key.name;
|
|
31
|
-
const enumValue = prop.value.value;
|
|
32
|
-
|
|
33
|
-
// Check if the value is not fully lowercase
|
|
34
|
-
if (!/^[a-z]+$/.test(enumValue)) {
|
|
35
|
-
context.report({
|
|
36
|
-
node: prop.value,
|
|
37
|
-
messageId: "enumLowercase",
|
|
38
|
-
data: {
|
|
39
|
-
enumKey,
|
|
40
|
-
suggestedValue: enumValue.toLowerCase(),
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
};
|