eslint-plugin-crisp 1.0.69 → 1.0.70

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 CHANGED
@@ -98,6 +98,7 @@ Each item has emojis denoting:
98
98
  - [crisp/enforce-optional](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/enforce-optional.js) (🟠🟢): Enforces use of optional chaining
99
99
  - [crisp/header-check](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/header-check.js) (🟠🟢): Enforces files to start with Crisp header
100
100
  - [crisp/header-comments-check](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/header-comments-check.js) (🟠🟢): Enforces different comment blocks before different groups (imports, constants, instances and exports)
101
+ - [crisp/import-group-comment](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/import-group-comment.js) (🟢): Ensures `import` statements are preceded by a comment stating their type
101
102
  - [crisp/methods-naming](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/methods-naming.js) (🟠🟢): Ensures methods are named according to their access (`public`, `private`, `protected`)
102
103
  - [crisp/methods-ordering](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/methods-ordering.js) (🟠🟢): Ensures methods order according to their access: `public` then `protected` then `private`
103
104
  - [crisp/multiline-comment-end-backslash](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/multiline-comment-end-backslash.js) (🟠🟢): Enforces multiline comments to end with a backslash
package/index.js CHANGED
@@ -11,6 +11,7 @@ module.exports = {
11
11
  "enforce-optional": require("./rules/enforce-optional"),
12
12
  "header-check": require("./rules/header-check"),
13
13
  "header-comments-check": require("./rules/header-comments-check"),
14
+ "import-group-comment": require("./rules/import-group-comment"),
14
15
  "jsdoc-align-params": require("./rules/jsdoc-align-params"),
15
16
  "jsdoc-check-indentation": require("./rules/jsdoc-check-indentation"),
16
17
  "jsdoc-check-optional-params": require("./rules/jsdoc-check-optional-params"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-crisp",
3
- "version": "1.0.69",
3
+ "version": "1.0.70",
4
4
  "description": "Custom ESLint Rules for Crisp",
5
5
  "author": "Crisp IM SAS",
6
6
  "main": "index.js",
@@ -140,6 +140,7 @@ module.exports = {
140
140
  "crisp/enforce-optional": "error",
141
141
  "crisp/header-check": "error",
142
142
  "crisp/header-comments-check": "error",
143
+ "crisp/import-group-comment": "error",
143
144
  "crisp/methods-naming": "error",
144
145
  "crisp/methods-ordering": "error",
145
146
  "crisp/multiline-comment-end-backslash": "error",
@@ -0,0 +1,108 @@
1
+ module.exports = {
2
+ meta: {
3
+ type: "suggestion",
4
+ docs: {
5
+ description: "Enforce import statements to be grouped and preceded by a comment",
6
+ category: "Best Practices",
7
+ recommended: false,
8
+ },
9
+ fixable: null, // This rule is not auto-fixable
10
+ },
11
+
12
+ create(context) {
13
+ let currentGroupComment = null;
14
+
15
+ // Extract the directory name from the file path
16
+ function getDirectoryName(filePath) {
17
+ const pathParts = filePath.split('/');
18
+ return pathParts[pathParts.length - 2].toUpperCase(); // Directory name
19
+ }
20
+
21
+ function extractGroupFromPath(path, filePath) {
22
+ // Relative path import?
23
+ if (path.startsWith("./")) {
24
+ return getDirectoryName(filePath);
25
+ }
26
+
27
+ // Alias path import?
28
+ if (path.startsWith("@/")) {
29
+ const parts = path.split("/");
30
+
31
+ if (parts.length === 2) {
32
+ return "MAIN";
33
+ }
34
+
35
+ return parts[1].toUpperCase();
36
+ }
37
+
38
+ return "NPM";
39
+ }
40
+
41
+ function generateExpectedComment(group) {
42
+ if (group === "NPM") {
43
+ return group;
44
+ }
45
+
46
+ return `PROJECT: ${group}`;
47
+ }
48
+
49
+ function isGroupComment(comment) {
50
+ return (
51
+ comment.type === "Line" &&
52
+ (
53
+ comment.value.trim().startsWith("PROJECT:") ||
54
+ comment.value.trim().startsWith("NPM")
55
+ )
56
+ );
57
+ }
58
+
59
+ function isIgnoreComment(comment) {
60
+ // Skip some comments
61
+ return (
62
+ comment.type === "Line" &&
63
+ comment.value.trim().startsWith("@ts-ignore")
64
+ );
65
+ }
66
+
67
+ function updateCurrentGroupComment(node) {
68
+ const comments = context.getSourceCode().getCommentsBefore(node);
69
+
70
+ if (comments.length > 0) {
71
+ for (let i = comments.length - 1; i >= 0; i--) {
72
+ if (isIgnoreComment(comments[i])) {
73
+ continue;
74
+ }
75
+
76
+ if (isGroupComment(comments[i])) {
77
+ currentGroupComment = comments[i];
78
+
79
+ break;
80
+ }
81
+ }
82
+ }
83
+ }
84
+
85
+ function checkImportGroup(node) {
86
+ const importPath = node.source.value;
87
+ const filePath = context.getFilename();
88
+
89
+ // Get group from import path
90
+ const expectedGroup = extractGroupFromPath(importPath, filePath);
91
+ const expectedComment = generateExpectedComment(expectedGroup);
92
+
93
+ // Get comment for current group
94
+ updateCurrentGroupComment(node);
95
+
96
+ if (!currentGroupComment || !currentGroupComment.value.toUpperCase().includes(expectedComment.toUpperCase())) {
97
+ context.report({
98
+ node,
99
+ message: `Import "${importPath}" should be in the "${expectedComment}" group.`,
100
+ });
101
+ }
102
+ }
103
+
104
+ return {
105
+ ImportDeclaration: checkImportGroup,
106
+ };
107
+ }
108
+ };