eslint-plugin-traceability 1.26.0 → 1.27.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.
package/CHANGELOG.md CHANGED
@@ -1,14 +1,10 @@
1
- # [1.26.0](https://github.com/voder-ai/eslint-plugin-traceability/compare/v1.25.0...v1.26.0) (2026-01-11)
2
-
3
-
4
- ### Bug Fixes
5
-
6
- * **tests:** update performance test for new return types ([6db924f](https://github.com/voder-ai/eslint-plugin-traceability/commit/6db924f7af3c4feadf9528b557a3948a2e89bb19))
1
+ # [1.27.0](https://github.com/voder-ai/eslint-plugin-traceability/compare/v1.26.0...v1.27.0) (2026-01-12)
7
2
 
8
3
 
9
4
  ### Features
10
5
 
11
- * **maintenance:** add [@supports](https://github.com/supports) reference updates and malformed annotation detection ([845a8cf](https://github.com/voder-ai/eslint-plugin-traceability/commit/845a8cf55e5f0444cead557fdea2f9d1b10b588b)), closes [REQ-MAINT-UPDATE#1](https://github.com/REQ-MAINT-UPDATE/issues/1)
6
+ * **rules:** add storyDirectories support to valid-annotation-format ([50ac131](https://github.com/voder-ai/eslint-plugin-traceability/commit/50ac131f24accf3009899939ababc91c0f1c83ad)), closes [#now-1](https://github.com/voder-ai/eslint-plugin-traceability/issues/now-1)
7
+ * **rules:** complete storyDirectories example derivation ([ac0ed9c](https://github.com/voder-ai/eslint-plugin-traceability/commit/ac0ed9c48c5312c502ae07d18b1ab0ca36e6e2c0))
12
8
 
13
9
  # Changelog
14
10
 
@@ -43,6 +43,13 @@ export interface AnnotationRuleOptions {
43
43
  * Human-readable example requirement ID used in error messages.
44
44
  */
45
45
  requirementIdExample?: string;
46
+ /**
47
+ * Story directories to validate against. When provided, derives storyPathPattern
48
+ * to match files within these directories if no explicit pattern is configured.
49
+ * Aligns with valid-story-reference configuration.
50
+ * Default: ["docs/stories", "stories"]
51
+ */
52
+ storyDirectories?: string[];
46
53
  /**
47
54
  * Global toggle for auto-fix behavior in valid-annotation-format.
48
55
  * When false, no automatic suffix-normalization fixes are applied.
@@ -140,6 +147,12 @@ export declare function getRuleSchema(): {
140
147
  requirementIdExample: {
141
148
  type: string;
142
149
  };
150
+ storyDirectories: {
151
+ type: string;
152
+ items: {
153
+ type: string;
154
+ };
155
+ };
143
156
  autoFix: {
144
157
  type: string;
145
158
  };
@@ -16,6 +16,29 @@ exports.getRuleSchema = getRuleSchema;
16
16
  * @req REQ-SCHEMA-VALIDATION - Use JSON Schema to validate configuration options
17
17
  */
18
18
  const pattern_validators_1 = require("./pattern-validators");
19
+ /**
20
+ * Derive a story path pattern from configured story directories.
21
+ * Creates a pattern that matches files within any of the provided directories.
22
+ *
23
+ * @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
24
+ */
25
+ function deriveStoryPatternFromDirectories(dirs) {
26
+ // Escape special regex characters in directory paths
27
+ const escapedDirs = dirs.map((dir) => dir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
28
+ // Create alternation pattern: (dir1|dir2|...)/filename.story.md
29
+ const dirsPattern = escapedDirs.length === 1 ? escapedDirs[0] : `(${escapedDirs.join("|")})`;
30
+ return new RegExp(String.raw `^${dirsPattern}/[0-9]+\.[0-9]+-DEV-[\w-]+\.story\.md$`);
31
+ }
32
+ /**
33
+ * Derive a story path example from configured story directories.
34
+ * Uses the first directory in the list to create an example path.
35
+ *
36
+ * @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
37
+ */
38
+ function deriveStoryExampleFromDirectories(dirs) {
39
+ const firstDir = dirs[0] || "docs/stories";
40
+ return `${firstDir}/005.0-DEV-EXAMPLE.story.md`;
41
+ }
19
42
  /**
20
43
  * Get the default regular expression used to validate story paths.
21
44
  *
@@ -98,21 +121,31 @@ function getOptionErrors() {
98
121
  /**
99
122
  * Resolve the story path pattern from nested or flat configuration
100
123
  * fields, validating and falling back to the default as needed.
124
+ * If storyDirectories is provided but no explicit pattern, derives pattern from directories.
101
125
  *
102
126
  * @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
103
127
  * @req REQ-PATTERN-CONFIG - Allow configurable story path patterns
104
128
  * @req REQ-REGEX-VALIDATION - Validate story path regex options
105
129
  * @req REQ-BACKWARD-COMPAT - Use a default when no pattern is provided
106
130
  */
107
- function resolveStoryPattern(nestedStoryPattern, flatStoryPattern) {
108
- return (0, pattern_validators_1.resolvePattern)({
109
- nestedPattern: nestedStoryPattern,
110
- nestedFieldName: "story.pattern",
111
- flatPattern: flatStoryPattern,
112
- flatFieldName: "storyPathPattern",
113
- defaultPattern: getDefaultStoryPattern(),
114
- errors: optionErrors,
115
- });
131
+ function resolveStoryPattern(nestedStoryPattern, flatStoryPattern, storyDirectories) {
132
+ // If an explicit pattern is provided (nested or flat), use it
133
+ if (nestedStoryPattern || flatStoryPattern) {
134
+ return (0, pattern_validators_1.resolvePattern)({
135
+ nestedPattern: nestedStoryPattern,
136
+ nestedFieldName: "story.pattern",
137
+ flatPattern: flatStoryPattern,
138
+ flatFieldName: "storyPathPattern",
139
+ defaultPattern: getDefaultStoryPattern(),
140
+ errors: optionErrors,
141
+ });
142
+ }
143
+ // If storyDirectories is provided, derive pattern from it
144
+ if (storyDirectories && storyDirectories.length > 0) {
145
+ return deriveStoryPatternFromDirectories(storyDirectories);
146
+ }
147
+ // Otherwise, use the default pattern
148
+ return getDefaultStoryPattern();
116
149
  }
117
150
  /**
118
151
  * Resolve the requirement ID pattern from nested or flat configuration
@@ -141,8 +174,17 @@ function resolveReqPattern(nestedReqPattern, flatReqPattern) {
141
174
  * @req REQ-EXAMPLE-MESSAGES - Allow custom story examples in messages
142
175
  * @req REQ-BACKWARD-COMPAT - Use a default story example when omitted
143
176
  */
144
- function resolveStoryExample(nestedStoryExample, flatStoryExample) {
145
- return (0, pattern_validators_1.resolveExample)(nestedStoryExample, flatStoryExample, getDefaultStoryExample());
177
+ function resolveStoryExample(nestedStoryExample, flatStoryExample, storyDirectories) {
178
+ // If an explicit example is provided, use it
179
+ if (nestedStoryExample || flatStoryExample) {
180
+ return (0, pattern_validators_1.resolveExample)(nestedStoryExample, flatStoryExample, getDefaultStoryExample());
181
+ }
182
+ // If storyDirectories is provided, derive example from it
183
+ if (storyDirectories && storyDirectories.length > 0) {
184
+ return deriveStoryExampleFromDirectories(storyDirectories);
185
+ }
186
+ // Otherwise, use the default example
187
+ return getDefaultStoryExample();
146
188
  }
147
189
  /**
148
190
  * Resolve the requirement ID example string from nested or flat configuration
@@ -227,9 +269,9 @@ function resolveOptionsInternal(user) {
227
269
  const { nestedReqExample, flatReqExample } = getReqExampleInputs(user);
228
270
  const autoFixFlag = user?.autoFix;
229
271
  const autoFix = typeof autoFixFlag === "boolean" ? autoFixFlag : true;
230
- const storyPattern = resolveStoryPattern(nestedStoryPattern, flatStoryPattern);
272
+ const storyPattern = resolveStoryPattern(nestedStoryPattern, flatStoryPattern, user?.storyDirectories);
231
273
  const reqPattern = resolveReqPattern(nestedReqPattern, flatReqPattern);
232
- const storyExample = resolveStoryExample(nestedStoryExample, flatStoryExample);
274
+ const storyExample = resolveStoryExample(nestedStoryExample, flatStoryExample, user?.storyDirectories);
233
275
  const reqExample = resolveReqExample(nestedReqExample, flatReqExample);
234
276
  return {
235
277
  storyPattern,
@@ -290,6 +332,7 @@ function getRuleSchema() {
290
332
  storyPathExample: { type: "string" },
291
333
  requirementIdPattern: { type: "string" },
292
334
  requirementIdExample: { type: "string" },
335
+ storyDirectories: { type: "array", items: { type: "string" } },
293
336
  autoFix: { type: "boolean" },
294
337
  },
295
338
  additionalProperties: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-traceability",
3
- "version": "1.26.0",
3
+ "version": "1.27.0",
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/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -28,8 +28,9 @@
28
28
  "lint:require-built-plugin": "npm run lint-plugin-guard",
29
29
  "lint": "eslint --config eslint.config.js \"src/**/*.{js,ts}\" \"tests/**/*.{js,ts}\" --max-warnings=0",
30
30
  "test": "jest --ci --bail",
31
- "test:unit": "jest --ci --bail --testPathPatterns='tests/(rules|maintenance|utils|unit)' --testPathIgnorePatterns='integration'",
31
+ "test:unit": "jest --ci --bail --testPathPatterns='tests/(rules|maintenance|utils|unit)' --testPathIgnorePatterns='integration|e2e'",
32
32
  "test:integration": "jest --ci --bail --testPathPatterns='tests/integration'",
33
+ "test:e2e": "jest --ci --bail --testPathPatterns='tests/e2e'",
33
34
  "ci-verify": "npm run type-check && npm run lint && npm run format:check && npm run duplication && npm run check:traceability && npm test && npm run audit:ci && npm run safety:deps",
34
35
  "ci-verify:full": "npm run check:traceability && npm run safety:deps && npm run audit:ci && npm run build && npm run smoke:runtime && npm run type-check && npm run lint-plugin-check && npm run lint -- --max-warnings=0 && npm run duplication && npm run test -- --coverage && npm run format:check && npm audit --omit=dev --audit-level=high && npm run audit:dev-high && npm run check:ci-artifacts",
35
36
  "ci-verify:fast": "npm run type-check && npm run check:traceability && npm run duplication && jest --ci --bail --passWithNoTests --testPathPatterns 'tests/(rules|maintenance)'",
@@ -766,7 +766,7 @@ Generates a plain-text or JSON report of stale story references.
766
766
  # Human-readable text report (default)
767
767
  traceability-maint report --root .
768
768
 
769
- # JSON report suitable for CI
769
+ # Machine-readable JSON output for further analysis
770
770
  traceability-maint report --root . --format json
771
771
  ```
772
772
 
@@ -847,7 +847,7 @@ If `--from` or `--to` is missing, the CLI prints an error, shows the help text,
847
847
  }
848
848
  ```
849
849
 
850
- In CI:
850
+ Manual verification:
851
851
 
852
852
  ```bash
853
853
  npm run traceability:verify