eslint-plugin-traceability 1.11.0 → 1.11.2
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/CHANGELOG.md +3 -4
- package/README.md +1 -1
- package/lib/src/index.d.ts +12 -1
- package/lib/src/index.js +43 -6
- package/lib/src/maintenance/commands.js +2 -3
- package/lib/src/maintenance/flags.js +111 -25
- package/lib/src/maintenance/update.js +1 -14
- package/lib/src/rules/helpers/require-story-core.d.ts +67 -0
- package/lib/src/rules/helpers/require-story-core.js +142 -23
- package/lib/src/rules/helpers/require-story-helpers.d.ts +9 -88
- package/lib/src/rules/helpers/require-story-helpers.js +118 -166
- package/lib/src/rules/helpers/require-story-io.js +51 -31
- package/lib/src/rules/helpers/valid-annotation-format-internal.d.ts +12 -13
- package/lib/src/rules/helpers/valid-annotation-format-internal.js +21 -16
- package/lib/src/rules/helpers/valid-annotation-format-validators.d.ts +29 -3
- package/lib/src/rules/helpers/valid-annotation-format-validators.js +29 -3
- package/lib/src/rules/helpers/valid-annotation-options.d.ts +3 -0
- package/lib/src/rules/helpers/valid-annotation-options.js +64 -21
- package/lib/src/rules/helpers/valid-annotation-utils.d.ts +3 -3
- package/lib/src/rules/helpers/valid-annotation-utils.js +10 -10
- package/lib/src/rules/helpers/valid-req-reference-helpers.d.ts +11 -0
- package/lib/src/rules/helpers/valid-req-reference-helpers.js +362 -0
- package/lib/src/rules/prefer-implements-annotation.js +7 -7
- package/lib/src/rules/require-story-annotation.d.ts +2 -0
- package/lib/src/rules/require-story-annotation.js +1 -1
- package/lib/src/rules/valid-req-reference.d.ts +4 -0
- package/lib/src/rules/valid-req-reference.js +5 -349
- package/lib/src/rules/valid-story-reference.d.ts +1 -1
- package/lib/src/rules/valid-story-reference.js +17 -10
- package/lib/src/utils/annotation-checker.js +31 -7
- package/lib/src/utils/branch-annotation-helpers.d.ts +2 -2
- package/lib/src/utils/branch-annotation-helpers.js +4 -4
- package/lib/src/utils/reqAnnotationDetection.js +36 -22
- package/lib/tests/cli-error-handling.test.js +2 -1
- package/lib/tests/config/eslint-config-validation.test.d.ts +8 -0
- package/lib/tests/config/eslint-config-validation.test.js +81 -0
- package/lib/tests/config/flat-config-presets-integration.test.js +1 -3
- package/lib/tests/config/require-story-annotation-config.test.d.ts +9 -0
- package/lib/tests/config/require-story-annotation-config.test.js +9 -0
- package/lib/tests/fixtures/stale/example.js +1 -1
- package/lib/tests/fixtures/update/example.js +1 -1
- package/lib/tests/integration/cli-integration.test.js +9 -1
- package/lib/tests/integration/dogfooding-validation.test.d.ts +1 -0
- package/lib/tests/integration/dogfooding-validation.test.js +94 -0
- package/lib/tests/maintenance/batch.test.js +1 -0
- package/lib/tests/maintenance/cli.test.js +38 -0
- package/lib/tests/maintenance/detect-isolated.test.js +6 -5
- package/lib/tests/maintenance/detect.test.js +1 -0
- package/lib/tests/maintenance/index.test.js +1 -0
- package/lib/tests/maintenance/report.test.js +1 -0
- package/lib/tests/maintenance/update-isolated.test.js +1 -0
- package/lib/tests/maintenance/update.test.js +1 -0
- package/lib/tests/perf/maintenance-cli-large-workspace.test.js +18 -0
- package/lib/tests/perf/require-branch-annotation-large-file.test.d.ts +1 -0
- package/lib/tests/perf/require-branch-annotation-large-file.test.js +67 -0
- package/lib/tests/plugin-default-export-and-configs.test.js +2 -0
- package/lib/tests/plugin-setup-error.test.d.ts +1 -0
- package/lib/tests/plugin-setup-error.test.js +1 -0
- package/lib/tests/plugin-setup.test.js +12 -1
- package/lib/tests/rules/auto-fix-behavior-008.test.js +16 -0
- package/lib/tests/rules/error-reporting.test.js +1 -0
- package/lib/tests/rules/prefer-implements-annotation.test.js +8 -0
- package/lib/tests/rules/require-branch-annotation.test.js +34 -0
- package/lib/tests/rules/require-story-core-edgecases.test.js +1 -0
- package/lib/tests/rules/require-story-core.autofix.test.js +1 -0
- package/lib/tests/rules/require-story-core.test.js +1 -0
- package/lib/tests/rules/require-story-helpers-edgecases.test.d.ts +1 -0
- package/lib/tests/rules/require-story-helpers-edgecases.test.js +1 -0
- package/lib/tests/rules/require-story-helpers.test.js +4 -3
- package/lib/tests/rules/require-story-io-behavior.test.d.ts +1 -0
- package/lib/tests/rules/require-story-io-behavior.test.js +1 -0
- package/lib/tests/rules/require-story-io.edgecases.test.d.ts +1 -0
- package/lib/tests/rules/require-story-io.edgecases.test.js +1 -0
- package/lib/tests/rules/require-story-visitors-edgecases.test.d.ts +1 -0
- package/lib/tests/rules/require-story-visitors-edgecases.test.js +1 -0
- package/lib/tests/rules/valid-annotation-format-internal.test.d.ts +8 -0
- package/lib/tests/rules/valid-annotation-format-internal.test.js +47 -0
- package/lib/tests/rules/valid-story-reference.test.js +2 -0
- package/lib/tests/utils/annotation-checker.test.js +2 -1
- package/lib/tests/utils/branch-annotation-helpers.test.js +2 -1
- package/package.json +2 -2
- package/user-docs/api-reference.md +115 -8
- package/user-docs/examples.md +1 -1
- package/user-docs/migration-guide.md +35 -2
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Internal helpers and types for the valid-annotation-format rule.
|
|
3
3
|
*
|
|
4
|
-
* @
|
|
5
|
-
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
6
|
-
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
7
|
-
* @req REQ-MULTILINE-SUPPORT - Handle annotations split across multiple lines
|
|
8
|
-
* @req REQ-FLEXIBLE-PARSING - Support reasonable variations in whitespace and formatting
|
|
9
|
-
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
10
|
-
* @req REQ-SUPPORTS-PARSE - Parse @supports annotations without affecting @story/@req
|
|
11
|
-
* @req REQ-MIXED-SUPPORT - Support mixed @story/@req/@implements usage in comments
|
|
4
|
+
* @supports docs/stories/024.0-DEV-IGNORE-INLINE-CODE-REFS.story.md REQ-IGNORE-INLINE-CODE REQ-PRESERVE-BOUNDARIES REQ-CENTRALIZED-FILTER
|
|
12
5
|
*/
|
|
13
6
|
/**
|
|
14
7
|
* Pending annotation state tracked while iterating through comment lines.
|
|
@@ -21,8 +14,10 @@ export interface PendingAnnotation {
|
|
|
21
14
|
/**
|
|
22
15
|
* Normalize a raw comment line to make annotation parsing more robust.
|
|
23
16
|
*
|
|
24
|
-
* This function trims whitespace,
|
|
25
|
-
*
|
|
17
|
+
* This function trims whitespace, strips any inline code spans wrapped in
|
|
18
|
+
* backticks (replacing them with spaces of equal length to preserve character
|
|
19
|
+
* boundaries), keeps any annotation tags that appear later in the line, and
|
|
20
|
+
* supports common JSDoc styles such as leading "*".
|
|
26
21
|
*
|
|
27
22
|
* It detects @story, @req, and @supports tags while preserving the rest
|
|
28
23
|
* of the line for downstream logic.
|
|
@@ -34,8 +29,12 @@ export declare function normalizeCommentLine(rawLine: string): string;
|
|
|
34
29
|
* This is used to distinguish regular JSDoc tags (e.g. @param, @returns) from
|
|
35
30
|
* traceability-related annotations such as @story, @req, and @supports.
|
|
36
31
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
32
|
+
* Supports coexistence with JSDoc by:
|
|
33
|
+
* - Detecting boundaries between traceability tags and other tags
|
|
34
|
+
* - Allowing regular JSDoc tags to live alongside traceability annotations
|
|
35
|
+
*
|
|
36
|
+
* Related requirements:
|
|
37
|
+
* - REQ-JSDOC-BOUNDARY-DETECTION
|
|
38
|
+
* - REQ-JSDOC-TAG-COEXISTENCE
|
|
40
39
|
*/
|
|
41
40
|
export declare function isNonTraceabilityJSDocTagLine(normalized: string): boolean;
|
|
@@ -2,14 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Internal helpers and types for the valid-annotation-format rule.
|
|
4
4
|
*
|
|
5
|
-
* @
|
|
6
|
-
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
7
|
-
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
8
|
-
* @req REQ-MULTILINE-SUPPORT - Handle annotations split across multiple lines
|
|
9
|
-
* @req REQ-FLEXIBLE-PARSING - Support reasonable variations in whitespace and formatting
|
|
10
|
-
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
11
|
-
* @req REQ-SUPPORTS-PARSE - Parse @supports annotations without affecting @story/@req
|
|
12
|
-
* @req REQ-MIXED-SUPPORT - Support mixed @story/@req/@implements usage in comments
|
|
5
|
+
* @supports docs/stories/024.0-DEV-IGNORE-INLINE-CODE-REFS.story.md REQ-IGNORE-INLINE-CODE REQ-PRESERVE-BOUNDARIES REQ-CENTRALIZED-FILTER
|
|
13
6
|
*/
|
|
14
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
8
|
exports.normalizeCommentLine = normalizeCommentLine;
|
|
@@ -17,8 +10,10 @@ exports.isNonTraceabilityJSDocTagLine = isNonTraceabilityJSDocTagLine;
|
|
|
17
10
|
/**
|
|
18
11
|
* Normalize a raw comment line to make annotation parsing more robust.
|
|
19
12
|
*
|
|
20
|
-
* This function trims whitespace,
|
|
21
|
-
*
|
|
13
|
+
* This function trims whitespace, strips any inline code spans wrapped in
|
|
14
|
+
* backticks (replacing them with spaces of equal length to preserve character
|
|
15
|
+
* boundaries), keeps any annotation tags that appear later in the line, and
|
|
16
|
+
* supports common JSDoc styles such as leading "*".
|
|
22
17
|
*
|
|
23
18
|
* It detects @story, @req, and @supports tags while preserving the rest
|
|
24
19
|
* of the line for downstream logic.
|
|
@@ -28,12 +23,18 @@ function normalizeCommentLine(rawLine) {
|
|
|
28
23
|
if (!trimmed) {
|
|
29
24
|
return "";
|
|
30
25
|
}
|
|
31
|
-
|
|
26
|
+
// @supports docs/stories/024.0-DEV-IGNORE-INLINE-CODE-REFS.story.md REQ-IGNORE-INLINE-CODE REQ-PRESERVE-BOUNDARIES REQ-CENTRALIZED-FILTER
|
|
27
|
+
// Strip backtick-wrapped content while preserving character positions by
|
|
28
|
+
// replacing each matched segment with spaces of the same length.
|
|
29
|
+
// This ensures annotations that appear outside code spans are still
|
|
30
|
+
// detected at their original indices.
|
|
31
|
+
const filtered = trimmed.replace(/`[^`]*`/g, (match) => " ".repeat(match.length));
|
|
32
|
+
const annotationMatch = filtered.match(/@story\b|@req\b|@supports\b/);
|
|
32
33
|
if (!annotationMatch || annotationMatch.index === undefined) {
|
|
33
|
-
const withoutLeadingStar =
|
|
34
|
+
const withoutLeadingStar = filtered.replace(/^\*\s?/, "");
|
|
34
35
|
return withoutLeadingStar;
|
|
35
36
|
}
|
|
36
|
-
return
|
|
37
|
+
return filtered.slice(annotationMatch.index);
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
40
|
* Detect whether a normalized comment line starts with a non-traceability JSDoc tag.
|
|
@@ -41,9 +42,13 @@ function normalizeCommentLine(rawLine) {
|
|
|
41
42
|
* This is used to distinguish regular JSDoc tags (e.g. @param, @returns) from
|
|
42
43
|
* traceability-related annotations such as @story, @req, and @supports.
|
|
43
44
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
45
|
+
* Supports coexistence with JSDoc by:
|
|
46
|
+
* - Detecting boundaries between traceability tags and other tags
|
|
47
|
+
* - Allowing regular JSDoc tags to live alongside traceability annotations
|
|
48
|
+
*
|
|
49
|
+
* Related requirements:
|
|
50
|
+
* - REQ-JSDOC-BOUNDARY-DETECTION
|
|
51
|
+
* - REQ-JSDOC-TAG-COEXISTENCE
|
|
47
52
|
*/
|
|
48
53
|
function isNonTraceabilityJSDocTagLine(normalized) {
|
|
49
54
|
const trimmed = normalized.trimStart();
|
|
@@ -2,9 +2,15 @@
|
|
|
2
2
|
* Validators and helper functions for the valid-annotation-format rule.
|
|
3
3
|
*
|
|
4
4
|
* This module contains the core validation logic that was originally
|
|
5
|
-
* embedded in src/rules/valid-annotation-format.ts.
|
|
6
|
-
*
|
|
7
|
-
* preserving existing behavior.
|
|
5
|
+
* embedded in src/rules/valid-annotation-format.ts. The logic is extracted
|
|
6
|
+
* into this helper to keep the main rule implementation smaller and easier
|
|
7
|
+
* to read while still preserving all existing behavior.
|
|
8
|
+
*
|
|
9
|
+
* The implementation in this module supports:
|
|
10
|
+
* - validation of @story annotations
|
|
11
|
+
* - validation of @req annotations
|
|
12
|
+
* - validation of @implements/@supports-style annotations
|
|
13
|
+
* - safe, minimal auto-fixes for certain invalid formats
|
|
8
14
|
*
|
|
9
15
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
10
16
|
* @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
|
|
@@ -29,6 +35,8 @@ import type { PendingAnnotation } from "./valid-annotation-format-internal";
|
|
|
29
35
|
/**
|
|
30
36
|
* Report an invalid @story annotation without applying a fix.
|
|
31
37
|
*
|
|
38
|
+
* The invalid @story annotation is detected and reported but left unchanged.
|
|
39
|
+
*
|
|
32
40
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
33
41
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
34
42
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
@@ -55,6 +63,9 @@ export declare function createStoryFix(context: any, comment: any, fixed: string
|
|
|
55
63
|
* for common path suffix issues by locating and replacing the path text
|
|
56
64
|
* within the original comment.
|
|
57
65
|
*
|
|
66
|
+
* Reporting includes both the original invalid value and, where applicable,
|
|
67
|
+
* a suggested corrected story path that only adjusts the suffix.
|
|
68
|
+
*
|
|
58
69
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
59
70
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
60
71
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
@@ -68,6 +79,12 @@ export declare function reportInvalidStoryFormatWithFix(context: any, comment: a
|
|
|
68
79
|
* Validate a @story annotation value and report detailed errors when needed.
|
|
69
80
|
* Where safe and unambiguous, apply an automatic fix for missing suffixes.
|
|
70
81
|
*
|
|
82
|
+
* Processing of @story values includes:
|
|
83
|
+
* - trimming whitespace,
|
|
84
|
+
* - collapsing multi-line text,
|
|
85
|
+
* - matching against the configured story regex,
|
|
86
|
+
* - and attempting a conservative suffix-only correction when possible.
|
|
87
|
+
*
|
|
71
88
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
72
89
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
73
90
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
@@ -82,6 +99,11 @@ export declare function validateStoryAnnotation(context: any, comment: any, rawV
|
|
|
82
99
|
/**
|
|
83
100
|
* Validate a @req annotation value and report detailed errors when needed.
|
|
84
101
|
*
|
|
102
|
+
* This behavior covers:
|
|
103
|
+
* - detecting missing identifiers,
|
|
104
|
+
* - collapsing multi-line requirement identifiers,
|
|
105
|
+
* - and validating the final identifier against the configured regex.
|
|
106
|
+
*
|
|
85
107
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
86
108
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
87
109
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
@@ -115,6 +137,10 @@ export declare function validateImplementsAnnotation(context: any, comment: any,
|
|
|
115
137
|
/**
|
|
116
138
|
* Finalize and validate the currently pending annotation, if any.
|
|
117
139
|
*
|
|
140
|
+
* Pending annotation state is produced by earlier parsing of multi-line
|
|
141
|
+
* comments. This function dispatches that accumulated value to the
|
|
142
|
+
* appropriate validator and then clears the pending state.
|
|
143
|
+
*
|
|
118
144
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
119
145
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
120
146
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
@@ -3,9 +3,15 @@
|
|
|
3
3
|
* Validators and helper functions for the valid-annotation-format rule.
|
|
4
4
|
*
|
|
5
5
|
* This module contains the core validation logic that was originally
|
|
6
|
-
* embedded in src/rules/valid-annotation-format.ts.
|
|
7
|
-
*
|
|
8
|
-
* preserving existing behavior.
|
|
6
|
+
* embedded in src/rules/valid-annotation-format.ts. The logic is extracted
|
|
7
|
+
* into this helper to keep the main rule implementation smaller and easier
|
|
8
|
+
* to read while still preserving all existing behavior.
|
|
9
|
+
*
|
|
10
|
+
* The implementation in this module supports:
|
|
11
|
+
* - validation of @story annotations
|
|
12
|
+
* - validation of @req annotations
|
|
13
|
+
* - validation of @implements/@supports-style annotations
|
|
14
|
+
* - safe, minimal auto-fixes for certain invalid formats
|
|
9
15
|
*
|
|
10
16
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
11
17
|
* @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
|
|
@@ -39,6 +45,8 @@ const valid_annotation_options_1 = require("./valid-annotation-options");
|
|
|
39
45
|
/**
|
|
40
46
|
* Report an invalid @story annotation without applying a fix.
|
|
41
47
|
*
|
|
48
|
+
* The invalid @story annotation is detected and reported but left unchanged.
|
|
49
|
+
*
|
|
42
50
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
43
51
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
44
52
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
@@ -99,6 +107,9 @@ function createStoryFix(context, comment, fixed) {
|
|
|
99
107
|
* for common path suffix issues by locating and replacing the path text
|
|
100
108
|
* within the original comment.
|
|
101
109
|
*
|
|
110
|
+
* Reporting includes both the original invalid value and, where applicable,
|
|
111
|
+
* a suggested corrected story path that only adjusts the suffix.
|
|
112
|
+
*
|
|
102
113
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
103
114
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
104
115
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
@@ -128,6 +139,12 @@ function reportInvalidStoryFormatWithFix(context, comment, collapsed, fixed) {
|
|
|
128
139
|
* Validate a @story annotation value and report detailed errors when needed.
|
|
129
140
|
* Where safe and unambiguous, apply an automatic fix for missing suffixes.
|
|
130
141
|
*
|
|
142
|
+
* Processing of @story values includes:
|
|
143
|
+
* - trimming whitespace,
|
|
144
|
+
* - collapsing multi-line text,
|
|
145
|
+
* - matching against the configured story regex,
|
|
146
|
+
* - and attempting a conservative suffix-only correction when possible.
|
|
147
|
+
*
|
|
131
148
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
132
149
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
133
150
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
@@ -179,6 +196,11 @@ function validateStoryAnnotation(context, comment, rawValue, options) {
|
|
|
179
196
|
/**
|
|
180
197
|
* Validate a @req annotation value and report detailed errors when needed.
|
|
181
198
|
*
|
|
199
|
+
* This behavior covers:
|
|
200
|
+
* - detecting missing identifiers,
|
|
201
|
+
* - collapsing multi-line requirement identifiers,
|
|
202
|
+
* - and validating the final identifier against the configured regex.
|
|
203
|
+
*
|
|
182
204
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
183
205
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
184
206
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
@@ -247,6 +269,10 @@ function validateImplementsAnnotation(context, comment, rawValue, options) {
|
|
|
247
269
|
/**
|
|
248
270
|
* Finalize and validate the currently pending annotation, if any.
|
|
249
271
|
*
|
|
272
|
+
* Pending annotation state is produced by earlier parsing of multi-line
|
|
273
|
+
* comments. This function dispatches that accumulated value to the
|
|
274
|
+
* appropriate validator and then clears the pending state.
|
|
275
|
+
*
|
|
250
276
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
251
277
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
252
278
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
@@ -105,46 +105,88 @@ function resolveExample(nestedExample, flatExample, defaultExample) {
|
|
|
105
105
|
}
|
|
106
106
|
return defaultExample;
|
|
107
107
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
function resolveOptions(rawOptions) {
|
|
113
|
-
optionErrors = [];
|
|
114
|
-
const user = normalizeUserOptions(rawOptions);
|
|
115
|
-
const nestedStoryPattern = user?.story?.pattern;
|
|
116
|
-
const flatStoryPattern = user?.storyPathPattern;
|
|
117
|
-
const nestedStoryExample = user?.story?.example;
|
|
118
|
-
const flatStoryExample = user?.storyPathExample;
|
|
119
|
-
const nestedReqPattern = user?.req?.pattern;
|
|
120
|
-
const flatReqPattern = user?.requirementIdPattern;
|
|
121
|
-
const nestedReqExample = user?.req?.example;
|
|
122
|
-
const flatReqExample = user?.requirementIdExample;
|
|
108
|
+
function getUserOptions(rawOptions) {
|
|
109
|
+
return normalizeUserOptions(rawOptions);
|
|
110
|
+
}
|
|
111
|
+
function resolveAutoFixFlag(user) {
|
|
123
112
|
const autoFixFlag = user?.autoFix;
|
|
124
|
-
|
|
125
|
-
|
|
113
|
+
return typeof autoFixFlag === "boolean" ? autoFixFlag : true;
|
|
114
|
+
}
|
|
115
|
+
function resolveStoryPattern(nestedStoryPattern, flatStoryPattern) {
|
|
116
|
+
return resolvePattern({
|
|
126
117
|
nestedPattern: nestedStoryPattern,
|
|
127
118
|
nestedFieldName: "story.pattern",
|
|
128
119
|
flatPattern: flatStoryPattern,
|
|
129
120
|
flatFieldName: "storyPathPattern",
|
|
130
121
|
defaultPattern: getDefaultStoryPattern(),
|
|
131
122
|
});
|
|
132
|
-
|
|
123
|
+
}
|
|
124
|
+
function resolveReqPattern(nestedReqPattern, flatReqPattern) {
|
|
125
|
+
return resolvePattern({
|
|
133
126
|
nestedPattern: nestedReqPattern,
|
|
134
127
|
nestedFieldName: "req.pattern",
|
|
135
128
|
flatPattern: flatReqPattern,
|
|
136
129
|
flatFieldName: "requirementIdPattern",
|
|
137
130
|
defaultPattern: getDefaultReqPattern(),
|
|
138
131
|
});
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
132
|
+
}
|
|
133
|
+
function resolveStoryExample(nestedStoryExample, flatStoryExample) {
|
|
134
|
+
return resolveExample(nestedStoryExample, flatStoryExample, getDefaultStoryExample());
|
|
135
|
+
}
|
|
136
|
+
function resolveReqExample(nestedReqExample, flatReqExample) {
|
|
137
|
+
return resolveExample(nestedReqExample, flatReqExample, getDefaultReqExample());
|
|
138
|
+
}
|
|
139
|
+
function getStoryPatternInputs(user) {
|
|
140
|
+
return {
|
|
141
|
+
nestedStoryPattern: user?.story?.pattern,
|
|
142
|
+
flatStoryPattern: user?.storyPathPattern,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function getStoryExampleInputs(user) {
|
|
146
|
+
return {
|
|
147
|
+
nestedStoryExample: user?.story?.example,
|
|
148
|
+
flatStoryExample: user?.storyPathExample,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function getReqPatternInputs(user) {
|
|
152
|
+
return {
|
|
153
|
+
nestedReqPattern: user?.req?.pattern,
|
|
154
|
+
flatReqPattern: user?.requirementIdPattern,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function getReqExampleInputs(user) {
|
|
158
|
+
return {
|
|
159
|
+
nestedReqExample: user?.req?.example,
|
|
160
|
+
flatReqExample: user?.requirementIdExample,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function resolveOptionsInternal(user) {
|
|
164
|
+
const { nestedStoryPattern, flatStoryPattern } = getStoryPatternInputs(user);
|
|
165
|
+
const { nestedStoryExample, flatStoryExample } = getStoryExampleInputs(user);
|
|
166
|
+
const { nestedReqPattern, flatReqPattern } = getReqPatternInputs(user);
|
|
167
|
+
const { nestedReqExample, flatReqExample } = getReqExampleInputs(user);
|
|
168
|
+
const autoFix = resolveAutoFixFlag(user);
|
|
169
|
+
const storyPattern = resolveStoryPattern(nestedStoryPattern, flatStoryPattern);
|
|
170
|
+
const reqPattern = resolveReqPattern(nestedReqPattern, flatReqPattern);
|
|
171
|
+
const storyExample = resolveStoryExample(nestedStoryExample, flatStoryExample);
|
|
172
|
+
const reqExample = resolveReqExample(nestedReqExample, flatReqExample);
|
|
173
|
+
return {
|
|
142
174
|
storyPattern,
|
|
143
175
|
storyExample,
|
|
144
176
|
reqPattern,
|
|
145
177
|
reqExample,
|
|
146
178
|
autoFix,
|
|
147
179
|
};
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Resolve user options into concrete, validated configuration.
|
|
183
|
+
* Falls back to existing defaults when options are not provided or invalid.
|
|
184
|
+
*/
|
|
185
|
+
function resolveOptions(rawOptions) {
|
|
186
|
+
optionErrors = [];
|
|
187
|
+
const user = getUserOptions(rawOptions);
|
|
188
|
+
const resolved = resolveOptionsInternal(user);
|
|
189
|
+
resolvedDefaults = resolved;
|
|
148
190
|
return resolvedDefaults;
|
|
149
191
|
}
|
|
150
192
|
/**
|
|
@@ -175,6 +217,7 @@ function getRuleSchema() {
|
|
|
175
217
|
storyPathExample: { type: "string" },
|
|
176
218
|
requirementIdPattern: { type: "string" },
|
|
177
219
|
requirementIdExample: { type: "string" },
|
|
220
|
+
autoFix: { type: "boolean" },
|
|
178
221
|
},
|
|
179
222
|
additionalProperties: false,
|
|
180
223
|
},
|
|
@@ -44,7 +44,7 @@ export declare function collapseAnnotationValue(value: string): string;
|
|
|
44
44
|
*
|
|
45
45
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
46
46
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
47
|
-
* @story docs/stories/010.1-
|
|
47
|
+
* @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
|
|
48
48
|
* @story docs/stories/010.2-REQ-STORY-PATH-AUTOFIX.story.md
|
|
49
49
|
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
50
50
|
* @req REQ-AUTOFIX-SAFE - Auto-fix must be conservative and never broaden the referenced path
|
|
@@ -56,7 +56,7 @@ export declare function getFixedStoryPath(original: string): string | null;
|
|
|
56
56
|
*
|
|
57
57
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
58
58
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
59
|
-
* @story docs/stories/010.1-
|
|
59
|
+
* @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
|
|
60
60
|
* @req REQ-ERROR-SPECIFICITY - Provide specific error messages for different format violations
|
|
61
61
|
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
62
62
|
*/
|
|
@@ -66,7 +66,7 @@ export declare function buildStoryErrorMessage(kind: "missing" | "invalid", valu
|
|
|
66
66
|
*
|
|
67
67
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
68
68
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
69
|
-
* @story docs/stories/010.1-
|
|
69
|
+
* @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
|
|
70
70
|
* @req REQ-ERROR-SPECIFICITY - Provide specific error messages for different format violations
|
|
71
71
|
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
72
72
|
*/
|
|
@@ -54,19 +54,19 @@ function collapseAnnotationValue(value) {
|
|
|
54
54
|
*
|
|
55
55
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
56
56
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
57
|
-
* @story docs/stories/010.1-
|
|
57
|
+
* @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
|
|
58
58
|
* @story docs/stories/010.2-REQ-STORY-PATH-AUTOFIX.story.md
|
|
59
59
|
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
60
60
|
* @req REQ-AUTOFIX-SAFE - Auto-fix must be conservative and never broaden the referenced path
|
|
61
61
|
* @req REQ-AUTOFIX-PRESERVE - Preserve surrounding formatting when normalizing story path suffixes
|
|
62
62
|
*/
|
|
63
63
|
function getFixedStoryPath(original) {
|
|
64
|
-
// @story docs/stories/010.1-
|
|
64
|
+
// @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md | REQ-AUTOFIX-SAFE - Reject auto-fix when the path contains ".." traversal segments to avoid broadening the reference.
|
|
65
65
|
// @supports docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md REQ-REQ-FORMAT REQ-ERROR-SPECIFICITY - Enforces correctness of the story identifier by rejecting paths that use unsafe traversal segments.
|
|
66
66
|
if (original.includes("..")) {
|
|
67
67
|
// @supports docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md REQ-REQ-FORMAT
|
|
68
68
|
// @supports docs/stories/008.0-DEV-AUTO-FIX.story.md REQ-AUTOFIX-SAFE
|
|
69
|
-
// @supports docs/stories/010.1-
|
|
69
|
+
// @supports docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md REQ-AUTOFIX-SAFE
|
|
70
70
|
return null;
|
|
71
71
|
}
|
|
72
72
|
// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md | REQ-AUTOFIX-FORMAT - Leave correctly formatted ".story.md" paths unchanged so diagnostics are not hidden by redundant fixes.
|
|
@@ -74,7 +74,7 @@ function getFixedStoryPath(original) {
|
|
|
74
74
|
if (/\.story\.md$/.test(original)) {
|
|
75
75
|
// @supports docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md REQ-REQ-FORMAT
|
|
76
76
|
// @supports docs/stories/008.0-DEV-AUTO-FIX.story.md REQ-AUTOFIX-FORMAT
|
|
77
|
-
// @supports docs/stories/010.1-
|
|
77
|
+
// @supports docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md REQ-AUTOFIX-FORMAT
|
|
78
78
|
return null;
|
|
79
79
|
}
|
|
80
80
|
// @story docs/stories/008.0-DEV-AUTO-FIX.story.md | REQ-AUTOFIX-FORMAT REQ-AUTOFIX-PRESERVE - When ".story" is present but ".md" is missing, append only the extension without altering the base path.
|
|
@@ -105,7 +105,7 @@ function getFixedStoryPath(original) {
|
|
|
105
105
|
*
|
|
106
106
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
107
107
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
108
|
-
* @story docs/stories/010.1-
|
|
108
|
+
* @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
|
|
109
109
|
* @req REQ-ERROR-SPECIFICITY - Provide specific error messages for different format violations
|
|
110
110
|
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
111
111
|
*/
|
|
@@ -115,11 +115,11 @@ function buildStoryErrorMessage(kind, value, options) {
|
|
|
115
115
|
// @supports docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md REQ-REQ-FORMAT REQ-ERROR-SPECIFICITY - Enforces presence of the story identifier by emitting a targeted message when the @story value is absent.
|
|
116
116
|
if (kind === "missing") {
|
|
117
117
|
// @supports docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md REQ-ERROR-SPECIFICITY
|
|
118
|
-
// @supports docs/stories/010.1-
|
|
118
|
+
// @supports docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md REQ-ERROR-SPECIFICITY
|
|
119
119
|
return `Missing story path for @story annotation. Expected a path like "${example}".`;
|
|
120
120
|
}
|
|
121
121
|
// @supports docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md REQ-ERROR-SPECIFICITY
|
|
122
|
-
// @supports docs/stories/010.1-
|
|
122
|
+
// @supports docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md REQ-ERROR-SPECIFICITY
|
|
123
123
|
return `Invalid story path "${value ?? ""}" for @story annotation. Expected a path like "${example}".`;
|
|
124
124
|
}
|
|
125
125
|
/**
|
|
@@ -127,7 +127,7 @@ function buildStoryErrorMessage(kind, value, options) {
|
|
|
127
127
|
*
|
|
128
128
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
129
129
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
130
|
-
* @story docs/stories/010.1-
|
|
130
|
+
* @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
|
|
131
131
|
* @req REQ-ERROR-SPECIFICITY - Provide specific error messages for different format violations
|
|
132
132
|
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
133
133
|
*/
|
|
@@ -137,10 +137,10 @@ function buildReqErrorMessage(kind, value, options) {
|
|
|
137
137
|
// @supports docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md REQ-REQ-FORMAT REQ-ERROR-SPECIFICITY - Enforces presence of the requirement identifier by emitting a specific message when the @req value is missing.
|
|
138
138
|
if (kind === "missing") {
|
|
139
139
|
// @supports docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md REQ-ERROR-SPECIFICITY
|
|
140
|
-
// @supports docs/stories/010.1-
|
|
140
|
+
// @supports docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md REQ-ERROR-SPECIFICITY
|
|
141
141
|
return `Missing requirement ID for @req annotation. Expected an identifier like "${example}".`;
|
|
142
142
|
}
|
|
143
143
|
// @supports docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md REQ-ERROR-SPECIFICITY
|
|
144
|
-
// @supports docs/stories/010.1-
|
|
144
|
+
// @supports docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md REQ-ERROR-SPECIFICITY
|
|
145
145
|
return `Invalid requirement ID "${value ?? ""}" for @req annotation. Expected an identifier like "${example}" (uppercase letters, numbers, and dashes only).`;
|
|
146
146
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Rule } from "eslint";
|
|
2
|
+
/**
|
|
3
|
+
* Factory used by the valid-req-reference rule to construct its Program
|
|
4
|
+
* visitor. Keeping this in a helper module allows the rule entrypoint
|
|
5
|
+
* itself to remain small and focused on meta configuration while the
|
|
6
|
+
* heavier deep-validation logic is encapsulated here.
|
|
7
|
+
*
|
|
8
|
+
* @supports docs/stories/010.0-DEV-DEEP-VALIDATION.story.md REQ-DEEP-PARSE REQ-DEEP-MATCH REQ-DEEP-CACHE
|
|
9
|
+
* @supports docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md REQ-SUPPORTS-VALIDATE REQ-MIXED-SUPPORT REQ-SCOPED-IDS
|
|
10
|
+
*/
|
|
11
|
+
export declare function createValidReqReferenceProgramVisitor(context: Rule.RuleContext): () => void;
|