eslint-plugin-traceability 1.1.9 → 1.1.10

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.
@@ -5,6 +5,8 @@
5
5
  * @req REQ-OPTIONS-SCOPE - Support configuring which function types to enforce via options
6
6
  * @req REQ-EXPORT-PRIORITY - Add exportPriority option to target exported or non-exported
7
7
  * @req REQ-UNIFIED-CHECK - Implement unified checkNode for all supported node types
8
+ * @req REQ-FUNCTION-DETECTION - Detect function declarations, expressions, arrow functions, and methods
9
+ * @req REQ-TYPESCRIPT-SUPPORT - Support TypeScript-specific function syntax
8
10
  */
9
11
  declare const _default: any;
10
12
  export default _default;
@@ -6,6 +6,8 @@
6
6
  * @req REQ-OPTIONS-SCOPE - Support configuring which function types to enforce via options
7
7
  * @req REQ-EXPORT-PRIORITY - Add exportPriority option to target exported or non-exported
8
8
  * @req REQ-UNIFIED-CHECK - Implement unified checkNode for all supported node types
9
+ * @req REQ-FUNCTION-DETECTION - Detect function declarations, expressions, arrow functions, and methods
10
+ * @req REQ-TYPESCRIPT-SUPPORT - Support TypeScript-specific function syntax
9
11
  */
10
12
  Object.defineProperty(exports, "__esModule", { value: true });
11
13
  /**
@@ -96,6 +98,12 @@ function resolveTargetNode(sourceCode, node) {
96
98
  }
97
99
  }
98
100
  }
101
+ else if (node.type === "TSMethodSignature") {
102
+ const exp = findAncestorNode(node, ["TSInterfaceDeclaration"]);
103
+ if (exp) {
104
+ target = exp;
105
+ }
106
+ }
99
107
  else if (node.type === "MethodDefinition") {
100
108
  target = node;
101
109
  }
@@ -124,6 +132,30 @@ function checkStoryAnnotation(sourceCode, context, node, scope, exportPriority)
124
132
  if (!shouldCheckNode(node, scope, exportPriority)) {
125
133
  return;
126
134
  }
135
+ // Special handling for TSMethodSignature: allow annotation on the method itself
136
+ if (node.type === "TSMethodSignature") {
137
+ // If annotated on the method signature, skip
138
+ if (hasStoryAnnotation(sourceCode, node)) {
139
+ return;
140
+ }
141
+ // Otherwise, check on interface declaration
142
+ const intf = resolveTargetNode(sourceCode, node);
143
+ if (hasStoryAnnotation(sourceCode, intf)) {
144
+ return;
145
+ }
146
+ // Missing annotation: report on the interface declaration
147
+ context.report({
148
+ node: intf,
149
+ messageId: "missingStory",
150
+ fix(fixer) {
151
+ const indentLevel = intf.loc.start.column;
152
+ const indent = " ".repeat(indentLevel);
153
+ const insertPos = intf.range[0] - indentLevel;
154
+ return fixer.insertTextBeforeRange([insertPos, insertPos], `${indent}/** @story <story-file>.story.md */\n`);
155
+ },
156
+ });
157
+ return;
158
+ }
127
159
  const target = resolveTargetNode(sourceCode, node);
128
160
  if (hasStoryAnnotation(sourceCode, target)) {
129
161
  return;
@@ -162,6 +194,8 @@ exports.default = {
162
194
  "FunctionExpression",
163
195
  "ArrowFunctionExpression",
164
196
  "MethodDefinition",
197
+ "TSDeclareFunction",
198
+ "TSMethodSignature",
165
199
  ],
166
200
  },
167
201
  uniqueItems: true,
@@ -182,6 +216,8 @@ exports.default = {
182
216
  "FunctionExpression",
183
217
  "ArrowFunctionExpression",
184
218
  "MethodDefinition",
219
+ "TSDeclareFunction",
220
+ "TSMethodSignature",
185
221
  ];
186
222
  const exportPriority = options.exportPriority || "all";
187
223
  return {
@@ -197,6 +233,16 @@ exports.default = {
197
233
  MethodDefinition(node) {
198
234
  checkStoryAnnotation(sourceCode, context, node, scope, exportPriority);
199
235
  },
236
+ // @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
237
+ // @req REQ-FUNCTION-DETECTION - Detect TS-specific function syntax
238
+ TSDeclareFunction(node) {
239
+ checkStoryAnnotation(sourceCode, context, node, scope, exportPriority);
240
+ },
241
+ // @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
242
+ // @req REQ-FUNCTION-DETECTION - Detect TS-specific function syntax
243
+ TSMethodSignature(node) {
244
+ checkStoryAnnotation(sourceCode, context, node, scope, exportPriority);
245
+ },
200
246
  };
201
247
  },
202
248
  };
@@ -40,6 +40,26 @@ const arrowFn = () => {};`,
40
40
  name: "[REQ-ANNOTATION-REQUIRED] valid on class method with annotation",
41
41
  code: `class A {\n /** @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md */\n method() {}\n}`,
42
42
  },
43
+ {
44
+ name: "[REQ-FUNCTION-DETECTION] valid with annotation on TS declare function",
45
+ code: `/** @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md */
46
+ declare function tsDecl(): void;`,
47
+ languageOptions: {
48
+ parser: require("@typescript-eslint/parser"),
49
+ parserOptions: { ecmaVersion: 2020, sourceType: "module" },
50
+ },
51
+ },
52
+ {
53
+ name: "[REQ-FUNCTION-DETECTION] valid with annotation on TS method signature",
54
+ code: `interface C {
55
+ /** @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md */
56
+ method(): void;
57
+ }`,
58
+ languageOptions: {
59
+ parser: require("@typescript-eslint/parser"),
60
+ parserOptions: { ecmaVersion: 2020, sourceType: "module" },
61
+ },
62
+ },
43
63
  ],
44
64
  invalid: [
45
65
  {
@@ -66,6 +86,32 @@ const arrowFn = () => {};`,
66
86
  output: `class C {\n /** @story <story-file>.story.md */\n method() {}\n}`,
67
87
  errors: [{ messageId: "missingStory" }],
68
88
  },
89
+ {
90
+ name: "[REQ-ANNOTATION-REQUIRED] missing @story on TS declare function",
91
+ code: `declare function tsDecl(): void;`,
92
+ output: `/** @story <story-file>.story.md */
93
+ declare function tsDecl(): void;`,
94
+ languageOptions: {
95
+ parser: require("@typescript-eslint/parser"),
96
+ parserOptions: { ecmaVersion: 2020, sourceType: "module" },
97
+ },
98
+ errors: [{ messageId: "missingStory" }],
99
+ },
100
+ {
101
+ name: "[REQ-ANNOTATION-REQUIRED] missing @story on TS method signature",
102
+ code: `interface D {
103
+ method(): void;
104
+ }`,
105
+ output: `/** @story <story-file>.story.md */
106
+ interface D {
107
+ method(): void;
108
+ }`,
109
+ languageOptions: {
110
+ parser: require("@typescript-eslint/parser"),
111
+ parserOptions: { ecmaVersion: 2020, sourceType: "module" },
112
+ },
113
+ errors: [{ messageId: "missingStory" }],
114
+ },
69
115
  ],
70
116
  });
71
117
  ruleTester.run("require-story-annotation with exportPriority option", require_story_annotation_1.default, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-traceability",
3
- "version": "1.1.9",
3
+ "version": "1.1.10",
4
4
  "description": "A customizable ESLint plugin that enforces traceability annotations in your code, ensuring each implementation is linked to its requirement or test case.",
5
5
  "main": "lib/src/index.js",
6
6
  "types": "lib/src/index.d.ts",
@@ -75,6 +75,11 @@
75
75
  "node": ">=14"
76
76
  },
77
77
  "overrides": {
78
- "glob": ">=11.0.4"
78
+ "glob": "12.0.0",
79
+ "http-cache-semantics": ">=4.1.1",
80
+ "ip": ">=2.0.2",
81
+ "semver": ">=7.5.2",
82
+ "socks": ">=2.7.2",
83
+ "tar": ">=6.1.12"
79
84
  }
80
85
  }