eslint-plugin-crisp 1.4.4 → 1.4.7

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": "eslint-plugin-crisp",
3
- "version": "1.4.4",
3
+ "version": "1.4.7",
4
4
  "description": "Custom ESLint Rules for Crisp",
5
5
  "author": "Crisp IM SAS",
6
6
  "main": "index.js",
@@ -1,3 +1,51 @@
1
+ function isTypeComment(comment) {
2
+ return (
3
+ comment.type === "Block" &&
4
+ comment.value.startsWith("*") &&
5
+ (comment.value.includes("@import") || comment.value.includes("@typedef"))
6
+ );
7
+ }
8
+
9
+ function isTypesGroupComment(comment) {
10
+ return comment.type === "Line" && comment.value.trim() === "TYPES";
11
+ }
12
+
13
+ function isGroupComment(comment) {
14
+ return (
15
+ comment.type === "Line" &&
16
+ (
17
+ comment.value.trim().startsWith("PROJECT:") ||
18
+ comment.value.trim().startsWith("NPM") ||
19
+ comment.value.trim().startsWith("TYPES")
20
+ )
21
+ );
22
+ }
23
+
24
+ function isIgnoreComment(comment) {
25
+ return (
26
+ comment.type === "Line" &&
27
+ comment.value.trim().startsWith("@ts-ignore")
28
+ );
29
+ }
30
+
31
+ function getDirectoryName(filePath) {
32
+ const pathParts = filePath.split("/");
33
+
34
+ return pathParts[pathParts.length - 2].toUpperCase();
35
+ }
36
+
37
+ function generateExpectedComment(group) {
38
+ if (group === "NPM") {
39
+ return group;
40
+ }
41
+
42
+ if (group === "SRC") {
43
+ group = "MAIN";
44
+ }
45
+
46
+ return `PROJECT: ${group}`;
47
+ }
48
+
1
49
  export default {
2
50
  meta: {
3
51
  type: "suggestion",
@@ -21,18 +69,12 @@ export default {
21
69
  const customGroups = context.options[0] || {}; // Get custom groups from options
22
70
 
23
71
  // Pre-compile custom regexes once instead of on every import
24
- const compiledCustomGroups = Object.entries(customGroups).map(
25
- ([regexStr, group]) => [new RegExp(regexStr), group]
26
- );
72
+ const compiledCustomGroups = Object.entries(customGroups).map(([regexStr, group]) => {
73
+ return [new RegExp(regexStr), group];
74
+ });
27
75
 
28
76
  let currentGroupComment = null;
29
77
 
30
- // Extract the directory name from the file path
31
- function getDirectoryName(filePath) {
32
- const pathParts = filePath.split("/");
33
- return pathParts[pathParts.length - 2].toUpperCase(); // Directory name
34
- }
35
-
36
78
  function extractGroupFromPath(path, filePath) {
37
79
  // Check custom regexes first (using pre-compiled patterns)
38
80
  for (const [regex, group] of compiledCustomGroups) {
@@ -60,36 +102,6 @@ export default {
60
102
  return "NPM";
61
103
  }
62
104
 
63
- function generateExpectedComment(group) {
64
- if (group === "NPM") {
65
- return group;
66
- }
67
-
68
- if (group === "SRC") {
69
- group = "MAIN";
70
- }
71
-
72
- return `PROJECT: ${group}`;
73
- }
74
-
75
- function isGroupComment(comment) {
76
- return (
77
- comment.type === "Line" &&
78
- (
79
- comment.value.trim().startsWith("PROJECT:") ||
80
- comment.value.trim().startsWith("NPM")
81
- )
82
- );
83
- }
84
-
85
- function isIgnoreComment(comment) {
86
- // Skip some comments
87
- return (
88
- comment.type === "Line" &&
89
- comment.value.trim().startsWith("@ts-ignore")
90
- );
91
- }
92
-
93
105
  function updateCurrentGroupComment(node) {
94
106
  const comments = context.getSourceCode().getCommentsBefore(node);
95
107
 
@@ -119,7 +131,7 @@ export default {
119
131
  // Get comment for current group
120
132
  updateCurrentGroupComment(node);
121
133
 
122
- if (!currentGroupComment || !currentGroupComment.value.toUpperCase().includes(expectedComment.toUpperCase())) {
134
+ if (!currentGroupComment || !currentGroupComment.value.includes(expectedComment)) {
123
135
  context.report({
124
136
  node,
125
137
  message: `Import "${importPath}" should be in the "${expectedComment}" group.`,
@@ -127,8 +139,49 @@ export default {
127
139
  }
128
140
  }
129
141
 
142
+ const sourceCode = context.sourceCode || context.getSourceCode();
143
+ const allComments = sourceCode.getAllComments();
144
+ const typeComments = allComments.filter(c => isTypeComment(c));
145
+
146
+ function checkTypeCommentsGroup() {
147
+ const filename = context.getFilename();
148
+
149
+ // Only check for // TYPES in .vue files (block header is checked by header-comments-check rule for .js/.ts)
150
+ if (!filename.endsWith(".vue")) {
151
+ return;
152
+ }
153
+
154
+ if (typeComments.length === 0) {
155
+ return;
156
+ }
157
+
158
+ const firstTypeComment = typeComments[0];
159
+ const typeCommentStart = firstTypeComment.range[0];
160
+
161
+ let comment = null;
162
+
163
+ for (let i = allComments.length - 1; i >= 0; i--) {
164
+ if (allComments[i].range[1] < typeCommentStart) {
165
+ comment = allComments[i];
166
+
167
+ break;
168
+ }
169
+ }
170
+
171
+ if (!comment || !isTypesGroupComment(comment)) {
172
+ context.report({
173
+ loc: firstTypeComment.loc,
174
+ message: "Type comments group must be preceded by a '// TYPES' comment",
175
+ });
176
+ }
177
+ }
178
+
130
179
  return {
131
180
  ImportDeclaration: checkImportGroup,
181
+
182
+ "Program:exit": () => {
183
+ checkTypeCommentsGroup();
184
+ }
132
185
  };
133
186
  }
134
187
  };