eslint-plugin-traceability 1.21.1 → 1.22.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +7 -2
  2. package/README.md +3 -4
  3. package/lib/src/maintenance/batch.js +0 -2
  4. package/lib/src/maintenance/cli.js +8 -11
  5. package/lib/src/maintenance/commands.d.ts +2 -2
  6. package/lib/src/maintenance/commands.js +2 -3
  7. package/lib/src/maintenance/detect.js +7 -8
  8. package/lib/src/maintenance/report.js +2 -3
  9. package/lib/src/maintenance/storyParser.d.ts +16 -0
  10. package/lib/src/maintenance/storyParser.js +167 -0
  11. package/lib/src/maintenance/update.js +0 -1
  12. package/lib/src/rules/helpers/pattern-validators.d.ts +42 -0
  13. package/lib/src/rules/helpers/pattern-validators.js +65 -0
  14. package/lib/src/rules/helpers/prefer-implements-inline.d.ts +16 -0
  15. package/lib/src/rules/helpers/prefer-implements-inline.js +146 -0
  16. package/lib/src/rules/helpers/require-story-comment-detection.d.ts +47 -0
  17. package/lib/src/rules/helpers/require-story-comment-detection.js +141 -0
  18. package/lib/src/rules/helpers/require-story-core.d.ts +6 -6
  19. package/lib/src/rules/helpers/require-story-core.js +10 -11
  20. package/lib/src/rules/helpers/require-story-helpers.d.ts +5 -63
  21. package/lib/src/rules/helpers/require-story-helpers.js +29 -337
  22. package/lib/src/rules/helpers/require-story-name-extraction.d.ts +35 -0
  23. package/lib/src/rules/helpers/require-story-name-extraction.js +107 -0
  24. package/lib/src/rules/helpers/require-story-node-utils.d.ts +43 -0
  25. package/lib/src/rules/helpers/require-story-node-utils.js +115 -0
  26. package/lib/src/rules/helpers/valid-annotation-format-internal.js +11 -3
  27. package/lib/src/rules/helpers/valid-annotation-options.d.ts +0 -10
  28. package/lib/src/rules/helpers/valid-annotation-options.js +22 -92
  29. package/lib/src/rules/helpers/valid-req-reference-helpers.js +0 -1
  30. package/lib/src/rules/no-redundant-annotation.js +4 -238
  31. package/lib/src/rules/prefer-implements-annotation.d.ts +12 -0
  32. package/lib/src/rules/prefer-implements-annotation.js +9 -164
  33. package/lib/src/rules/require-traceability.d.ts +8 -0
  34. package/lib/src/rules/require-traceability.js +8 -0
  35. package/lib/src/utils/annotation-checker.d.ts +3 -2
  36. package/lib/src/utils/annotation-checker.js +3 -2
  37. package/lib/src/utils/branch-annotation-catch-helpers.d.ts +22 -0
  38. package/lib/src/utils/branch-annotation-catch-helpers.js +70 -0
  39. package/lib/src/utils/branch-annotation-helpers.js +11 -187
  40. package/lib/src/utils/branch-annotation-if-helpers.d.ts +1 -0
  41. package/lib/src/utils/branch-annotation-if-helpers.js +59 -0
  42. package/lib/src/utils/branch-annotation-indent-helpers.d.ts +1 -1
  43. package/lib/src/utils/branch-annotation-switch-helpers.d.ts +8 -2
  44. package/lib/src/utils/branch-annotation-switch-helpers.js +10 -4
  45. package/lib/src/utils/branch-validation.d.ts +9 -0
  46. package/lib/src/utils/branch-validation.js +58 -0
  47. package/lib/src/utils/comment-text-helpers.d.ts +31 -0
  48. package/lib/src/utils/comment-text-helpers.js +54 -0
  49. package/lib/src/utils/redundancy-detector.d.ts +85 -0
  50. package/lib/src/utils/redundancy-detector.js +235 -0
  51. package/lib/tests/maintenance/storyParser.test.d.ts +8 -0
  52. package/lib/tests/maintenance/storyParser.test.js +505 -0
  53. package/lib/tests/rules/no-redundant-annotation.test.js +1 -0
  54. package/lib/tests/rules/require-story-helpers.test.js +3 -2
  55. package/lib/tests/rules/valid-req-reference.test.js +2 -0
  56. package/package.json +18 -10
  57. package/user-docs/api-reference.md +2 -2
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processInlineComments = processInlineComments;
4
+ const valid_annotation_format_internal_1 = require("../helpers/valid-annotation-format-internal");
5
+ const MIN_STORY_TOKENS = 2;
6
+ const MIN_REQ_TOKENS = 2;
7
+ /**
8
+ * Extract the leading whitespace and `//` prefix from a line comment's full
9
+ * source text so that new inline annotations can be inserted with matching
10
+ * indentation and formatting.
11
+ *
12
+ * @story docs/stories/010.3-DEV-MIGRATE-TO-SUPPORTS.story.md
13
+ * @req REQ-MIGRATE-INLINE
14
+ */
15
+ function getLinePrefixFromText(fullText) {
16
+ const match = fullText.match(/^(\s*\/\/\s*)/);
17
+ return match ? match[1] : "";
18
+ }
19
+ /**
20
+ * Attempt to construct an inline auto-fix that replaces a contiguous
21
+ * sequence of `@story` and `@req` line comments with a single `@supports`
22
+ * annotation while preserving the original comment prefix.
23
+ *
24
+ * @story docs/stories/010.3-DEV-MIGRATE-TO-SUPPORTS.story.md
25
+ * @req REQ-MIGRATE-INLINE
26
+ */
27
+ function tryBuildInlineAutoFix(context, comments, storyIndex, reqIndices) {
28
+ const sourceCode = context.getSourceCode();
29
+ const storyComment = comments[storyIndex];
30
+ const storyNormalized = (0, valid_annotation_format_internal_1.normalizeCommentLine)(storyComment.value || "");
31
+ if (!storyNormalized || !/^@story\b/.test(storyNormalized)) {
32
+ return null;
33
+ }
34
+ const storyParts = storyNormalized.split(/\s+/);
35
+ if (storyParts.length !== MIN_STORY_TOKENS) {
36
+ return null;
37
+ }
38
+ const storyPath = storyParts[1];
39
+ const reqIds = [];
40
+ for (const idx of reqIndices) {
41
+ const reqComment = comments[idx];
42
+ const reqNormalized = (0, valid_annotation_format_internal_1.normalizeCommentLine)(reqComment.value || "");
43
+ if (!reqNormalized || !/^@req\b/.test(reqNormalized)) {
44
+ return null;
45
+ }
46
+ const reqParts = reqNormalized.split(/\s+/);
47
+ if (reqParts.length !== MIN_REQ_TOKENS) {
48
+ return null;
49
+ }
50
+ reqIds.push(reqParts[1]);
51
+ }
52
+ if (!reqIds.length) {
53
+ return null;
54
+ }
55
+ const fullText = sourceCode.text.slice(storyComment.range[0], storyComment.range[1]);
56
+ const linePrefix = getLinePrefixFromText(fullText);
57
+ const implAnnotation = `@supports ${storyPath} ${reqIds.join(" ")}`;
58
+ const implLine = `${linePrefix}${implAnnotation}`;
59
+ const start = storyComment.range[0];
60
+ const end = comments[reqIndices[reqIndices.length - 1]].range[1];
61
+ return (fixer) => fixer.replaceTextRange([start, end], implLine);
62
+ }
63
+ /**
64
+ * Coordinate detection and optional migration of a single inline `@story`
65
+ * comment and its following `@req` comments, reporting diagnostics and
66
+ * scheduling auto-fixes where safe.
67
+ *
68
+ * @story docs/stories/010.3-DEV-MIGRATE-TO-SUPPORTS.story.md
69
+ * @req REQ-MIGRATE-INLINE
70
+ */
71
+ function collectReqIndicesAfterStory(group, startIndex) {
72
+ const n = group.length;
73
+ const reqIndices = [];
74
+ let j = startIndex + 1;
75
+ while (j < n) {
76
+ const next = group[j];
77
+ const nextNormalized = (0, valid_annotation_format_internal_1.normalizeCommentLine)(next.value || "");
78
+ if (!nextNormalized || /^@supports\b/.test(nextNormalized)) {
79
+ break;
80
+ }
81
+ if (/^@req\b/.test(nextNormalized)) {
82
+ reqIndices.push(j);
83
+ j += 1;
84
+ continue;
85
+ }
86
+ break;
87
+ }
88
+ return { reqIndices, nextIndex: j };
89
+ }
90
+ function handleInlineStorySequence(context, group, startIndex) {
91
+ const current = group[startIndex];
92
+ const normalized = (0, valid_annotation_format_internal_1.normalizeCommentLine)(current.value || "");
93
+ if (!normalized || !/^@story\b/.test(normalized)) {
94
+ return startIndex + 1;
95
+ }
96
+ const { reqIndices, nextIndex } = collectReqIndicesAfterStory(group, startIndex);
97
+ if (reqIndices.length === 0) {
98
+ return startIndex + 1;
99
+ }
100
+ const fix = tryBuildInlineAutoFix(context, group, startIndex, reqIndices);
101
+ context.report({
102
+ node: current,
103
+ messageId: "preferImplements",
104
+ fix: fix || undefined,
105
+ });
106
+ return nextIndex;
107
+ }
108
+ function advanceInlineGroupIndex(context, group, i) {
109
+ if (i >= group.length) {
110
+ return i;
111
+ }
112
+ return handleInlineStorySequence(context, group, i);
113
+ }
114
+ function processInlineGroup(context, group) {
115
+ let i = 0;
116
+ while (i < group.length) {
117
+ i = advanceInlineGroupIndex(context, group, i);
118
+ }
119
+ }
120
+ /**
121
+ * Scan sequences of Line comments for inline legacy story and requirement patterns
122
+ * and report diagnostics with optional auto-fixes.
123
+ */
124
+ function processInlineComments(context, lineComments) {
125
+ if (!lineComments.length)
126
+ return;
127
+ // Group by contiguous line numbers
128
+ let group = [lineComments[0]];
129
+ const flushGroup = () => {
130
+ processInlineGroup(context, group);
131
+ group = [];
132
+ };
133
+ for (let idx = 1; idx < lineComments.length; idx++) {
134
+ const prev = lineComments[idx - 1];
135
+ const curr = lineComments[idx];
136
+ if (curr.loc.start.line === prev.loc.start.line + 1 &&
137
+ curr.loc.start.column === prev.loc.start.column) {
138
+ group.push(curr);
139
+ }
140
+ else {
141
+ flushGroup();
142
+ group.push(curr);
143
+ }
144
+ }
145
+ flushGroup();
146
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Check whether the JSDoc associated with node contains `@story`
3
+ *
4
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
5
+ * @req REQ-ANNOTATION-REQUIRED - Extract JSDoc based detection into helper
6
+ */
7
+ export declare function jsdocHasStory(sourceCode: any, node: any): boolean;
8
+ /**
9
+ * Check whether comments returned by sourceCode.getCommentsBefore contain `@story`
10
+ *
11
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
12
+ * @req REQ-ANNOTATION-REQUIRED - Extract comment-before detection into helper
13
+ */
14
+ export declare function commentsBeforeHasStory(sourceCode: any, node: any): boolean;
15
+ /**
16
+ * Check whether leadingComments attached to the node contain `@story`
17
+ *
18
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
19
+ * @req REQ-ANNOTATION-REQUIRED - Extract leadingComments detection into helper
20
+ */
21
+ export declare function leadingCommentsHasStory(node: any): boolean;
22
+ /**
23
+ * Check if `@story` annotation already present in JSDoc or preceding comments.
24
+ * Consolidates a variety of heuristics through smaller helpers.
25
+ *
26
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
27
+ * @req REQ-ANNOTATION-REQUIRED - Detect existing story annotations in JSDoc or comments
28
+ */
29
+ export declare function hasStoryAnnotation(sourceCode: any, node: any): boolean;
30
+ /**
31
+ * Placement-aware story detection helper used by core reporting.
32
+ *
33
+ * When annotationPlacement is "inside" and the node supports inside-brace
34
+ * semantics, this helper only treats annotations found on the first
35
+ * comment-only lines inside the function or method body as satisfying the
36
+ * requirement. JSDoc and before-function comments are intentionally ignored so
37
+ * that misplaced annotations are reported as violations under the inside
38
+ * standard.
39
+ *
40
+ * For nodes that do not support inside placement (such as TS declarations,
41
+ * signature-only nodes, or functions without block bodies), this helper
42
+ * delegates to the existing hasStoryAnnotation heuristics so that they
43
+ * continue to rely on before-function placement.
44
+ *
45
+ * @supports docs/stories/028.0-DEV-ANNOTATION-PLACEMENT-STANDARDIZATION.story.md REQ-ALL-BLOCK-TYPES REQ-INSIDE-BRACE-PLACEMENT REQ-PLACEMENT-CONFIG
46
+ */
47
+ export declare function hasStoryAnnotationWithPlacement(sourceCode: any, node: any, annotationPlacement: "before" | "inside"): boolean;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.jsdocHasStory = jsdocHasStory;
4
+ exports.commentsBeforeHasStory = commentsBeforeHasStory;
5
+ exports.leadingCommentsHasStory = leadingCommentsHasStory;
6
+ exports.hasStoryAnnotation = hasStoryAnnotation;
7
+ exports.hasStoryAnnotationWithPlacement = hasStoryAnnotationWithPlacement;
8
+ /**
9
+ * Comment detection utilities for require-story rule
10
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
11
+ * @req REQ-ANNOTATION-REQUIRED - File-level header for comment detection utilities
12
+ */
13
+ const require_story_io_1 = require("./require-story-io");
14
+ const function_annotation_helpers_1 = require("../../utils/function-annotation-helpers");
15
+ const require_story_node_utils_1 = require("./require-story-node-utils");
16
+ /**
17
+ * Check whether the JSDoc associated with node contains `@story`
18
+ *
19
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
20
+ * @req REQ-ANNOTATION-REQUIRED - Extract JSDoc based detection into helper
21
+ */
22
+ function jsdocHasStory(sourceCode, node) {
23
+ if (typeof sourceCode?.getJSDocComment !== "function") {
24
+ return false;
25
+ }
26
+ const jsdoc = sourceCode.getJSDocComment(node);
27
+ return !!(jsdoc &&
28
+ typeof jsdoc.value === "string" &&
29
+ jsdoc.value.includes("@story"));
30
+ }
31
+ /**
32
+ * Check whether comments returned by sourceCode.getCommentsBefore contain `@story`
33
+ *
34
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
35
+ * @req REQ-ANNOTATION-REQUIRED - Extract comment-before detection into helper
36
+ */
37
+ function commentsBeforeHasStory(sourceCode, node) {
38
+ if (typeof sourceCode?.getCommentsBefore !== "function") {
39
+ return false;
40
+ }
41
+ const commentsBefore = sourceCode.getCommentsBefore(node) || [];
42
+ return (Array.isArray(commentsBefore) &&
43
+ commentsBefore.some((c) => typeof c.value === "string" && c.value.includes("@story")));
44
+ }
45
+ /**
46
+ * Check whether leadingComments attached to the node contain `@story`
47
+ *
48
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
49
+ * @req REQ-ANNOTATION-REQUIRED - Extract leadingComments detection into helper
50
+ */
51
+ function leadingCommentsHasStory(node) {
52
+ const leadingComments = (node && node.leadingComments) || [];
53
+ return (Array.isArray(leadingComments) &&
54
+ leadingComments.some((c) => typeof c.value === "string" && c.value.includes("@story")));
55
+ }
56
+ /**
57
+ * Check if `@story` annotation already present in JSDoc or preceding comments.
58
+ * Consolidates a variety of heuristics through smaller helpers.
59
+ *
60
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
61
+ * @req REQ-ANNOTATION-REQUIRED - Detect existing story annotations in JSDoc or comments
62
+ */
63
+ function hasStoryAnnotation(sourceCode, node) {
64
+ try {
65
+ // Direct, node-local checks always apply first.
66
+ if (jsdocHasStory(sourceCode, node)) {
67
+ return true;
68
+ }
69
+ if (commentsBeforeHasStory(sourceCode, node)) {
70
+ return true;
71
+ }
72
+ if (leadingCommentsHasStory(node)) {
73
+ return true;
74
+ }
75
+ if (!(0, require_story_node_utils_1.isNestedFunction)(node) && (0, require_story_io_1.linesBeforeHasStory)(sourceCode, node)) {
76
+ return true;
77
+ }
78
+ const canInherit = (0, require_story_node_utils_1.isNestedFunction)(node) && (0, require_story_node_utils_1.isEffectivelyAnonymousFunction)(node);
79
+ // Only nodes that are allowed to inherit annotations (e.g., nested anonymous
80
+ // callbacks) may treat parent-chain comments or broad fallback text as
81
+ // satisfying the annotation requirement.
82
+ if (canInherit && (0, require_story_io_1.parentChainHasStory)(sourceCode, node)) {
83
+ return true;
84
+ }
85
+ if (canInherit && (0, require_story_io_1.fallbackTextBeforeHasStory)(sourceCode, node)) {
86
+ return true;
87
+ }
88
+ if (canInherit) {
89
+ return true;
90
+ }
91
+ }
92
+ catch (error) {
93
+ if (process.env.TRACEABILITY_DEBUG === "1") {
94
+ console.error("[traceability] hasStoryAnnotation failed for node", error?.message ?? error);
95
+ }
96
+ }
97
+ return false;
98
+ }
99
+ /**
100
+ * Placement-aware story detection helper used by core reporting.
101
+ *
102
+ * When annotationPlacement is "inside" and the node supports inside-brace
103
+ * semantics, this helper only treats annotations found on the first
104
+ * comment-only lines inside the function or method body as satisfying the
105
+ * requirement. JSDoc and before-function comments are intentionally ignored so
106
+ * that misplaced annotations are reported as violations under the inside
107
+ * standard.
108
+ *
109
+ * For nodes that do not support inside placement (such as TS declarations,
110
+ * signature-only nodes, or functions without block bodies), this helper
111
+ * delegates to the existing hasStoryAnnotation heuristics so that they
112
+ * continue to rely on before-function placement.
113
+ *
114
+ * @supports docs/stories/028.0-DEV-ANNOTATION-PLACEMENT-STANDARDIZATION.story.md REQ-ALL-BLOCK-TYPES REQ-INSIDE-BRACE-PLACEMENT REQ-PLACEMENT-CONFIG
115
+ */
116
+ function hasStoryAnnotationWithPlacement(sourceCode, node, annotationPlacement) {
117
+ // Backward-compatible default: use existing heuristics when placement is
118
+ // "before" or when the function does not support inside-brace semantics.
119
+ if (annotationPlacement !== "inside" ||
120
+ !(0, function_annotation_helpers_1.supportsInsidePlacementForFunction)(node)) {
121
+ return hasStoryAnnotation(sourceCode, node);
122
+ }
123
+ try {
124
+ const insideText = (0, function_annotation_helpers_1.getFunctionInsideBodyCommentText)(sourceCode, node);
125
+ if (typeof insideText === "string" &&
126
+ (insideText.includes("@story") || insideText.includes("@supports"))) {
127
+ return true;
128
+ }
129
+ }
130
+ catch (error) {
131
+ if (process.env.TRACEABILITY_DEBUG === "1") {
132
+ // Debug logging only when explicitly enabled for troubleshooting helper failures.
133
+ console.error("[traceability] hasStoryAnnotationWithPlacement failed for node", error?.message ?? error);
134
+ }
135
+ }
136
+ // In inside-placement mode for block-bodied functions and methods we
137
+ // intentionally do not fall back to before-function heuristics; callers
138
+ // should treat this as a missing annotation so that misplaced comments are
139
+ // reported as violations.
140
+ return false;
141
+ }
@@ -1,21 +1,21 @@
1
1
  /**
2
- * Create a fixer function that inserts a @story annotation before the target node.
2
+ * Create a fixer function that inserts a `@story` annotation before the target node.
3
3
  * This fixer is responsible for placing the annotation immediately before the
4
4
  * resolved target node in the source code.
5
5
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
6
- * @req REQ-AUTOFIX - Provide automatic fix function for missing @story annotations
6
+ * @req REQ-AUTOFIX - Provide automatic fix function for missing `@story` annotations
7
7
  */
8
8
  export declare function createAddStoryFix(target: any, annotationTemplate: string): (fixer: any) => any;
9
9
  /**
10
10
  * Create a fixer function for class method annotations.
11
- * This helper ensures that the @story annotation is inserted with appropriate
11
+ * This helper ensures that the `@story` annotation is inserted with appropriate
12
12
  * indentation and placement before a class method declaration.
13
13
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
14
14
  * @req REQ-AUTOFIX - Provide automatic fix for class method annotations
15
15
  */
16
16
  export declare function createMethodFix(node: any, annotationTemplate: string): (fixer: any) => any;
17
17
  /**
18
- * Default set of node types to check for missing @story annotations.
18
+ * Default set of node types to check for missing `@story` annotations.
19
19
  * This default scope covers common function-like declarations used in typical
20
20
  * TypeScript and JavaScript codebases.
21
21
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
@@ -57,7 +57,7 @@ type ReportDeps = {
57
57
  hasStoryAnnotationWithPlacement?: (_sourceCode: any, _node: any, _placement: "before" | "inside") => boolean;
58
58
  };
59
59
  /**
60
- * Core helper to report a missing @story annotation for a function-like node.
60
+ * Core helper to report a missing `@story` annotation for a function-like node.
61
61
  * This reporting utility delegates behavior to injected dependencies so that
62
62
  * higher-level helpers can stay small while sharing error-reporting logic.
63
63
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
@@ -73,7 +73,7 @@ export declare function coreReportMissing(deps: ReportDeps, context: Rule.RuleCo
73
73
  options?: CoreReportOptions;
74
74
  }): void;
75
75
  /**
76
- * Core helper to report a missing @story annotation for a method-like node.
76
+ * Core helper to report a missing `@story` annotation for a method-like node.
77
77
  * This method-focused reporting utility uses injected dependencies while
78
78
  * keeping this module centered on core error-reporting behavior.
79
79
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
@@ -5,7 +5,6 @@ exports.createAddStoryFix = createAddStoryFix;
5
5
  exports.createMethodFix = createMethodFix;
6
6
  exports.coreReportMissing = coreReportMissing;
7
7
  exports.coreReportMethod = coreReportMethod;
8
- /* eslint-disable traceability/valid-annotation-format */
9
8
  /**
10
9
  * Compute the insertion start offset for inserting annotations before a node.
11
10
  * This helper ensures we insert before any export wrapper when present, while
@@ -33,18 +32,18 @@ function getInsertionStart(candidate) {
33
32
  return 0;
34
33
  }
35
34
  /**
36
- * Create a fixer function that inserts a @story annotation before the target node.
35
+ * Create a fixer function that inserts a `@story` annotation before the target node.
37
36
  * This fixer is responsible for placing the annotation immediately before the
38
37
  * resolved target node in the source code.
39
38
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
40
- * @req REQ-AUTOFIX - Provide automatic fix function for missing @story annotations
39
+ * @req REQ-AUTOFIX - Provide automatic fix function for missing `@story` annotations
41
40
  */
42
41
  function createAddStoryFix(target, annotationTemplate) {
43
42
  /**
44
- * Fixer that inserts a @story annotation before the target node.
43
+ * Fixer that inserts a `@story` annotation before the target node.
45
44
  * This inner fixer is used by ESLint to apply the actual code modification.
46
45
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
47
- * @req REQ-AUTOFIX - Provide automatic fix function for missing @story annotations
46
+ * @req REQ-AUTOFIX - Provide automatic fix function for missing `@story` annotations
48
47
  */
49
48
  function addStoryFixer(fixer) {
50
49
  const start = getInsertionStart(target);
@@ -54,14 +53,14 @@ function createAddStoryFix(target, annotationTemplate) {
54
53
  }
55
54
  /**
56
55
  * Create a fixer function for class method annotations.
57
- * This helper ensures that the @story annotation is inserted with appropriate
56
+ * This helper ensures that the `@story` annotation is inserted with appropriate
58
57
  * indentation and placement before a class method declaration.
59
58
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
60
59
  * @req REQ-AUTOFIX - Provide automatic fix for class method annotations
61
60
  */
62
61
  function createMethodFix(node, annotationTemplate) {
63
62
  /**
64
- * Fixer that inserts a @story annotation before a method node.
63
+ * Fixer that inserts a `@story` annotation before a method node.
65
64
  * This inner fixer handles inserting the annotation with method-friendly
66
65
  * formatting and spacing.
67
66
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
@@ -74,7 +73,7 @@ function createMethodFix(node, annotationTemplate) {
74
73
  return methodFixer;
75
74
  }
76
75
  /**
77
- * Default set of node types to check for missing @story annotations.
76
+ * Default set of node types to check for missing `@story` annotations.
78
77
  * This default scope covers common function-like declarations used in typical
79
78
  * TypeScript and JavaScript codebases.
80
79
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
@@ -118,7 +117,7 @@ function withSafeReporting(label, fn) {
118
117
  }
119
118
  }
120
119
  /**
121
- * Build the shared ESLint report descriptor for a missing @story annotation.
120
+ * Build the shared ESLint report descriptor for a missing story annotation.
122
121
  * This keeps the core helpers focused on computing names, targets, and
123
122
  * templates while centralizing the diagnostic wiring.
124
123
  * @supports docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md REQ-ERROR-SPECIFIC
@@ -145,7 +144,7 @@ function resolveAnnotationPlacement(options) {
145
144
  return raw === "inside" || raw === "before" ? raw : "before";
146
145
  }
147
146
  /**
148
- * Core helper to report a missing @story annotation for a function-like node.
147
+ * Core helper to report a missing `@story` annotation for a function-like node.
149
148
  * This reporting utility delegates behavior to injected dependencies so that
150
149
  * higher-level helpers can stay small while sharing error-reporting logic.
151
150
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
@@ -184,7 +183,7 @@ function coreReportMissing(deps, context, sourceCode, config) {
184
183
  });
185
184
  }
186
185
  /**
187
- * Core helper to report a missing @story annotation for a method-like node.
186
+ * Core helper to report a missing `@story` annotation for a method-like node.
188
187
  * This method-focused reporting utility uses injected dependencies while
189
188
  * keeping this module centered on core error-reporting behavior.
190
189
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
@@ -9,9 +9,11 @@
9
9
  */
10
10
  import type { Rule } from "eslint";
11
11
  import { linesBeforeHasStory, parentChainHasStory, fallbackTextBeforeHasStory } from "./require-story-io";
12
- import { getNodeName } from "./require-story-utils";
13
12
  import { DEFAULT_SCOPE, EXPORT_PRIORITY_VALUES, STORY_PATH } from "./require-story-core";
14
13
  import { type CallbackExclusionOptions } from "./test-callback-exclusion";
14
+ import { extractName } from "./require-story-name-extraction";
15
+ import { isExportedNode, resolveTargetNode } from "./require-story-node-utils";
16
+ import { jsdocHasStory, commentsBeforeHasStory, leadingCommentsHasStory, hasStoryAnnotation, hasStoryAnnotationWithPlacement } from "./require-story-comment-detection";
15
17
  /**
16
18
  * Shared configuration helpers
17
19
  */
@@ -23,67 +25,6 @@ interface ReportOptions extends CallbackExclusionOptions {
23
25
  /** @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md */
24
26
  declare function getAnnotationTemplate(override?: string, _options?: CallbackExclusionOptions): string;
25
27
  declare function shouldApplyAutoFix(autoFix: boolean | undefined, _options?: CallbackExclusionOptions): boolean;
26
- /**
27
- * Determine if a node is in an export declaration
28
- * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
29
- * @req REQ-ANNOTATION-REQUIRED - Check node ancestry to find export declarations
30
- */
31
- declare function isExportedNode(node: any): boolean;
32
- /**
33
- * Check whether the JSDoc associated with node contains @story
34
- * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
35
- * @req REQ-ANNOTATION-REQUIRED - Extract JSDoc based detection into helper
36
- */
37
- declare function jsdocHasStory(sourceCode: any, node: any): boolean;
38
- /**
39
- * Check whether comments returned by sourceCode.getCommentsBefore contain @story
40
- * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
41
- * @req REQ-ANNOTATION-REQUIRED - Extract comment-before detection into helper
42
- */
43
- declare function commentsBeforeHasStory(sourceCode: any, node: any): boolean;
44
- /**
45
- * Check whether leadingComments attached to the node contain @story
46
- * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
47
- * @req REQ-ANNOTATION-REQUIRED - Extract leadingComments detection into helper
48
- */
49
- declare function leadingCommentsHasStory(node: any): boolean;
50
- /**
51
- * Check if @story annotation already present in JSDoc or preceding comments
52
- * Consolidates a variety of heuristics through smaller helpers.
53
- * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
54
- * @req REQ-ANNOTATION-REQUIRED - Detect existing story annotations in JSDoc or comments
55
- */
56
- declare function hasStoryAnnotation(sourceCode: any, node: any): boolean;
57
- /**
58
- * Placement-aware story detection helper used by core reporting.
59
- *
60
- * When annotationPlacement is "inside" and the node supports inside-brace
61
- * semantics, this helper only treats annotations found on the first
62
- * comment-only lines inside the function or method body as satisfying the
63
- * requirement. JSDoc and before-function comments are intentionally ignored so
64
- * that misplaced annotations are reported as violations under the inside
65
- * standard.
66
- *
67
- * For nodes that do not support inside placement (such as TS declarations,
68
- * signature-only nodes, or functions without block bodies), this helper
69
- * delegates to the existing hasStoryAnnotation heuristics so that they
70
- * continue to rely on before-function placement.
71
- *
72
- * @supports docs/stories/028.0-DEV-ANNOTATION-PLACEMENT-STANDARDIZATION.story.md REQ-ALL-BLOCK-TYPES REQ-INSIDE-BRACE-PLACEMENT REQ-PLACEMENT-CONFIG
73
- */
74
- declare function hasStoryAnnotationWithPlacement(sourceCode: any, node: any, annotationPlacement: "before" | "inside"): boolean;
75
- /**
76
- * Determine AST node where annotation should be inserted
77
- * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
78
- * @req REQ-ANNOTATION-REQUIRED - Determine correct insertion target for annotation
79
- */
80
- declare function resolveTargetNode(sourceCode: any, node: any): any;
81
- /**
82
- * Small utility to walk the node and its parents to extract an Identifier or key name.
83
- * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
84
- * @req REQ-ANNOTATION-REQUIRED - Walk node and parents to find Identifier/Key name
85
- */
86
- declare function extractName(node: any): string;
87
28
  /** @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md */
88
29
  declare function shouldProcessNode(node: any, scope: string[], exportPriority?: string, options?: CallbackExclusionOptions): boolean;
89
30
  /** @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md */
@@ -100,7 +41,8 @@ declare function reportMethod(context: Rule.RuleContext, sourceCode: any, config
100
41
  }): void;
101
42
  /**
102
43
  * Explicit exports for require-story-annotation helpers.
44
+ *
103
45
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
104
46
  * @req REQ-ANNOTATION-REQUIRED
105
47
  */
106
- export { STORY_PATH, getAnnotationTemplate, shouldApplyAutoFix, isExportedNode, jsdocHasStory, commentsBeforeHasStory, leadingCommentsHasStory, hasStoryAnnotation, hasStoryAnnotationWithPlacement, getNodeName, extractName, resolveTargetNode, shouldProcessNode, DEFAULT_SCOPE, EXPORT_PRIORITY_VALUES, linesBeforeHasStory, parentChainHasStory, fallbackTextBeforeHasStory, reportMissing, reportMethod, };
48
+ export { STORY_PATH, getAnnotationTemplate, shouldApplyAutoFix, isExportedNode, jsdocHasStory, commentsBeforeHasStory, leadingCommentsHasStory, hasStoryAnnotation, hasStoryAnnotationWithPlacement, extractName, resolveTargetNode, shouldProcessNode, DEFAULT_SCOPE, EXPORT_PRIORITY_VALUES, linesBeforeHasStory, parentChainHasStory, fallbackTextBeforeHasStory, reportMissing, reportMethod, };