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
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
## [1.11.2](https://github.com/voder-ai/eslint-plugin-traceability/compare/v1.11.1...v1.11.2) (2025-12-06)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
###
|
|
4
|
+
### Bug Fixes
|
|
5
5
|
|
|
6
|
-
*
|
|
7
|
-
* add configurable auto-fix templates and toggles ([21c3a79](https://github.com/voder-ai/eslint-plugin-traceability/commit/21c3a79ce2e2e7fd95a422a963735d67940c8bd8))
|
|
6
|
+
* ignore inline-code annotation references in comment normalization ([118d743](https://github.com/voder-ai/eslint-plugin-traceability/commit/118d743ff8c8bf1dcb0854b898480c641cc727c8))
|
|
8
7
|
|
|
9
8
|
# Changelog
|
|
10
9
|
|
package/README.md
CHANGED
|
@@ -83,7 +83,7 @@ export default [
|
|
|
83
83
|
|
|
84
84
|
```js
|
|
85
85
|
/**
|
|
86
|
-
* @story stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
86
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
87
87
|
* // Point this to your own project's story/requirements file, not to this plugin's internal docs.
|
|
88
88
|
* @req REQ-ANNOTATION-REQUIRED
|
|
89
89
|
*/
|
package/lib/src/index.d.ts
CHANGED
|
@@ -11,16 +11,27 @@ import type { Rule } from "eslint";
|
|
|
11
11
|
*/
|
|
12
12
|
import { detectStaleAnnotations, updateAnnotationReferences, batchUpdateAnnotations, verifyAnnotations, generateMaintenanceReport } from "./maintenance";
|
|
13
13
|
/**
|
|
14
|
-
* @story docs/stories/002.0-
|
|
14
|
+
* @story docs/stories/002.0-DEV-ESLINT-CONFIG.story.md
|
|
15
15
|
* @req REQ-RULE-LIST - Enumerate supported rule file names for plugin discovery
|
|
16
16
|
*/
|
|
17
17
|
declare const RULE_NAMES: readonly ["require-story-annotation", "require-req-annotation", "require-branch-annotation", "valid-annotation-format", "valid-story-reference", "valid-req-reference", "prefer-implements-annotation", "require-test-traceability"];
|
|
18
18
|
type RuleName = (typeof RULE_NAMES)[number];
|
|
19
19
|
declare const rules: Record<RuleName, Rule.RuleModule>;
|
|
20
|
+
/**
|
|
21
|
+
* Plugin metadata used by ESLint for debugging and caching.
|
|
22
|
+
*
|
|
23
|
+
* @supports docs/stories/001.0-DEV-PLUGIN-SETUP.story.md REQ-PLUGIN-STRUCTURE REQ-NPM-PACKAGE
|
|
24
|
+
*/
|
|
25
|
+
declare const pluginMeta: {
|
|
26
|
+
readonly name: string;
|
|
27
|
+
readonly version: string;
|
|
28
|
+
readonly namespace: "traceability";
|
|
29
|
+
};
|
|
20
30
|
declare const plugin: {
|
|
21
31
|
rules: typeof rules;
|
|
22
32
|
configs?: unknown;
|
|
23
33
|
maintenance?: unknown;
|
|
34
|
+
meta?: typeof pluginMeta;
|
|
24
35
|
};
|
|
25
36
|
/**
|
|
26
37
|
* @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
|
package/lib/src/index.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.maintenance = exports.configs = exports.rules = void 0;
|
|
|
7
7
|
*/
|
|
8
8
|
const maintenance_1 = require("./maintenance");
|
|
9
9
|
/**
|
|
10
|
-
* @story docs/stories/002.0-
|
|
10
|
+
* @story docs/stories/002.0-DEV-ESLINT-CONFIG.story.md
|
|
11
11
|
* @req REQ-RULE-LIST - Enumerate supported rule file names for plugin discovery
|
|
12
12
|
*/
|
|
13
13
|
const RULE_NAMES = [
|
|
@@ -24,18 +24,18 @@ const rules = {};
|
|
|
24
24
|
exports.rules = rules;
|
|
25
25
|
RULE_NAMES.forEach(
|
|
26
26
|
/**
|
|
27
|
-
* @story docs/stories/002.0-
|
|
27
|
+
* @story docs/stories/002.0-DEV-ESLINT-CONFIG.story.md
|
|
28
28
|
* @req REQ-DYNAMIC-LOADING - Support dynamic rule loading by name at runtime
|
|
29
29
|
* @param {RuleName} name - Rule file base name used to discover and load rule module
|
|
30
30
|
*/
|
|
31
31
|
(name) => {
|
|
32
32
|
/**
|
|
33
|
-
* @story docs/stories/002.0-
|
|
33
|
+
* @story docs/stories/002.0-DEV-ESLINT-CONFIG.story.md
|
|
34
34
|
* @req REQ-DYNAMIC-LOADING - Support dynamic rule loading by name at runtime
|
|
35
35
|
*/
|
|
36
36
|
try {
|
|
37
37
|
/**
|
|
38
|
-
* @story docs/stories/002.0-
|
|
38
|
+
* @story docs/stories/002.0-DEV-ESLINT-CONFIG.story.md
|
|
39
39
|
* @req REQ-DYNAMIC-LOADING - Support dynamic rule loading by name at runtime
|
|
40
40
|
*/
|
|
41
41
|
// Dynamically require rule module
|
|
@@ -45,11 +45,11 @@ RULE_NAMES.forEach(
|
|
|
45
45
|
}
|
|
46
46
|
catch (error) {
|
|
47
47
|
/**
|
|
48
|
-
* @story docs/stories/
|
|
48
|
+
* @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
|
|
49
49
|
* @req REQ-ERROR-HANDLING - Provide fallback rule module and surface errors when rule loading fails
|
|
50
50
|
*/
|
|
51
51
|
/**
|
|
52
|
-
* @story docs/stories/
|
|
52
|
+
* @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
|
|
53
53
|
* @req REQ-ERROR-HANDLING - Provide fallback rule module and surface errors when rule loading fails
|
|
54
54
|
*/
|
|
55
55
|
console.error(`[eslint-plugin-traceability] Failed to load rule "${name}": ${error.message}`);
|
|
@@ -74,8 +74,45 @@ RULE_NAMES.forEach(
|
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
76
|
});
|
|
77
|
+
/**
|
|
78
|
+
* Plugin metadata used by ESLint for debugging and caching.
|
|
79
|
+
*
|
|
80
|
+
* @supports docs/stories/001.0-DEV-PLUGIN-SETUP.story.md REQ-PLUGIN-STRUCTURE REQ-NPM-PACKAGE
|
|
81
|
+
*/
|
|
82
|
+
const pluginMeta = (() => {
|
|
83
|
+
let pkg = {};
|
|
84
|
+
try {
|
|
85
|
+
// When running from built output (lib/src/index.js)
|
|
86
|
+
// this resolves to the package.json at the project root.
|
|
87
|
+
// @supports docs/stories/001.0-DEV-PLUGIN-SETUP.story.md REQ-NPM-PACKAGE
|
|
88
|
+
pkg = require("../../package.json");
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
try {
|
|
92
|
+
// When running via the TypeScript sources (src/index.ts) in this repo,
|
|
93
|
+
// fall back to resolving package.json one level up from src/.
|
|
94
|
+
// @supports docs/stories/001.0-DEV-PLUGIN-SETUP.story.md REQ-NPM-PACKAGE
|
|
95
|
+
pkg = require("../package.json");
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// As a last resort (tests, unusual environments), provide sensible
|
|
99
|
+
// defaults so that plugin loading never fails just for metadata.
|
|
100
|
+
// @supports docs/stories/001.0-DEV-PLUGIN-SETUP.story.md REQ-PLUGIN-STRUCTURE
|
|
101
|
+
pkg = {
|
|
102
|
+
name: "eslint-plugin-traceability",
|
|
103
|
+
version: "0.0.0-development",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
name: pkg.name ?? "eslint-plugin-traceability",
|
|
109
|
+
version: pkg.version ?? "0.0.0-development",
|
|
110
|
+
namespace: "traceability",
|
|
111
|
+
};
|
|
112
|
+
})();
|
|
77
113
|
const plugin = {
|
|
78
114
|
rules,
|
|
115
|
+
meta: pluginMeta,
|
|
79
116
|
};
|
|
80
117
|
/**
|
|
81
118
|
* @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
|
|
@@ -9,7 +9,7 @@ exports.handleUpdate = handleUpdate;
|
|
|
9
9
|
* Subcommand handlers for the traceability-maint CLI.
|
|
10
10
|
*
|
|
11
11
|
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
12
|
-
* @req REQ-MAINT-DETECT - CLI support for detection of stale annotations
|
|
12
|
+
* @req REQ-MAINT-DETECT - CLI support for detection of stale annotations.
|
|
13
13
|
* @req REQ-MAINT-VERIFY - CLI support for verification of annotations
|
|
14
14
|
* @req REQ-MAINT-REPORT - CLI support for human-readable reports
|
|
15
15
|
* @req REQ-MAINT-UPDATE - CLI support for updating annotation references
|
|
@@ -34,8 +34,7 @@ function handleDetect(normalized) {
|
|
|
34
34
|
const root = flags.root;
|
|
35
35
|
const stale = (0, detect_1.detectStaleAnnotations)(root);
|
|
36
36
|
if (flags.json) {
|
|
37
|
-
//
|
|
38
|
-
// @req REQ-MAINT-REPORT - JSON-friendly output for tooling integration
|
|
37
|
+
// Emit JSON output to support consumption by external tools and scripts.
|
|
39
38
|
console.log(JSON.stringify({ root, stale }));
|
|
40
39
|
}
|
|
41
40
|
else if (stale.length === 0) {
|
|
@@ -60,43 +60,129 @@ function createDefaultFlags() {
|
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
63
|
+
* Safely check if the next argument value exists and is a string.
|
|
64
64
|
*
|
|
65
65
|
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
66
66
|
* @req REQ-MAINT-SAFE - Provide predictable, minimal argument parsing
|
|
67
67
|
*/
|
|
68
|
-
function
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
function isNextValueString(args, index) {
|
|
69
|
+
return typeof args[index + 1] === "string";
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Handle the --root flag, updating the root path if present.
|
|
73
|
+
*
|
|
74
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
75
|
+
* @req REQ-MAINT-SAFE - Provide predictable, minimal argument parsing
|
|
76
|
+
*/
|
|
77
|
+
function handleRootFlag(flags, args, index) {
|
|
78
|
+
if (args[index] !== "--root" || !isNextValueString(args, index)) {
|
|
79
|
+
return index;
|
|
80
|
+
}
|
|
81
|
+
flags.root = path_1.default.resolve(args[index + 1]);
|
|
82
|
+
return index + 1;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Handle the --json flag, toggling JSON output when present.
|
|
86
|
+
*
|
|
87
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
88
|
+
* @req REQ-MAINT-SAFE - Provide predictable, minimal argument parsing
|
|
89
|
+
*/
|
|
90
|
+
function handleJsonFlag(flags, args, index) {
|
|
91
|
+
if (args[index] !== "--json") {
|
|
92
|
+
return index;
|
|
73
93
|
}
|
|
74
|
-
|
|
75
|
-
|
|
94
|
+
flags.json = true;
|
|
95
|
+
return index;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Handle the --format flag, validating and setting the output format.
|
|
99
|
+
*
|
|
100
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
101
|
+
* @req REQ-MAINT-SAFE - Provide predictable, minimal argument parsing
|
|
102
|
+
*/
|
|
103
|
+
function handleFormatFlag(flags, args, index) {
|
|
104
|
+
if (args[index] !== "--format" || !isNextValueString(args, index)) {
|
|
76
105
|
return index;
|
|
77
106
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
throw new Error(`Invalid format: ${value}. Expected 'text' or 'json'.`);
|
|
85
|
-
}
|
|
86
|
-
return index + 1;
|
|
107
|
+
const value = args[index + 1];
|
|
108
|
+
if (value === "text" || value === "json") {
|
|
109
|
+
flags.format = value;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
throw new Error(`Invalid format: ${value}. Expected 'text' or 'json'.`);
|
|
87
113
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
114
|
+
return index + 1;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Handle the --from flag, capturing the starting reference if present.
|
|
118
|
+
*
|
|
119
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
120
|
+
* @req REQ-MAINT-SAFE - Provide predictable, minimal argument parsing
|
|
121
|
+
*/
|
|
122
|
+
function handleFromFlag(flags, args, index) {
|
|
123
|
+
if (args[index] !== "--from" || !isNextValueString(args, index)) {
|
|
124
|
+
return index;
|
|
91
125
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
126
|
+
flags.from = args[index + 1];
|
|
127
|
+
return index + 1;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Handle the --to flag, capturing the ending reference if present.
|
|
131
|
+
*
|
|
132
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
133
|
+
* @req REQ-MAINT-SAFE - Provide predictable, minimal argument parsing
|
|
134
|
+
*/
|
|
135
|
+
function handleToFlag(flags, args, index) {
|
|
136
|
+
if (args[index] !== "--to" || !isNextValueString(args, index)) {
|
|
137
|
+
return index;
|
|
95
138
|
}
|
|
96
|
-
|
|
97
|
-
|
|
139
|
+
flags.to = args[index + 1];
|
|
140
|
+
return index + 1;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Handle the --dry-run flag, enabling dry-run mode when present.
|
|
144
|
+
*
|
|
145
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
146
|
+
* @req REQ-MAINT-SAFE - Provide predictable, minimal argument parsing
|
|
147
|
+
*/
|
|
148
|
+
function handleDryRunFlag(flags, args, index) {
|
|
149
|
+
if (args[index] !== "--dry-run") {
|
|
98
150
|
return index;
|
|
99
151
|
}
|
|
152
|
+
flags.dryRun = true;
|
|
153
|
+
return index;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Handle a single CLI argument and update the flags accordingly.
|
|
157
|
+
*
|
|
158
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
159
|
+
* @req REQ-MAINT-SAFE - Provide predictable, minimal argument parsing
|
|
160
|
+
*/
|
|
161
|
+
function applyFlag(flags, args, index) {
|
|
162
|
+
const afterRoot = handleRootFlag(flags, args, index);
|
|
163
|
+
if (afterRoot !== index) {
|
|
164
|
+
return afterRoot;
|
|
165
|
+
}
|
|
166
|
+
const afterJson = handleJsonFlag(flags, args, index);
|
|
167
|
+
if (afterJson !== index) {
|
|
168
|
+
return afterJson;
|
|
169
|
+
}
|
|
170
|
+
const afterFormat = handleFormatFlag(flags, args, index);
|
|
171
|
+
if (afterFormat !== index) {
|
|
172
|
+
return afterFormat;
|
|
173
|
+
}
|
|
174
|
+
const afterFrom = handleFromFlag(flags, args, index);
|
|
175
|
+
if (afterFrom !== index) {
|
|
176
|
+
return afterFrom;
|
|
177
|
+
}
|
|
178
|
+
const afterTo = handleToFlag(flags, args, index);
|
|
179
|
+
if (afterTo !== index) {
|
|
180
|
+
return afterTo;
|
|
181
|
+
}
|
|
182
|
+
const afterDryRun = handleDryRunFlag(flags, args, index);
|
|
183
|
+
if (afterDryRun !== index) {
|
|
184
|
+
return afterDryRun;
|
|
185
|
+
}
|
|
100
186
|
return index;
|
|
101
187
|
}
|
|
102
188
|
/**
|
|
@@ -42,20 +42,7 @@ const utils_1 = require("./utils");
|
|
|
42
42
|
* @req REQ-MAINT-UPDATE
|
|
43
43
|
*/
|
|
44
44
|
function processFileForAnnotationUpdates(fullPath, regex, newPath, replacementCountRef) {
|
|
45
|
-
const
|
|
46
|
-
/**
|
|
47
|
-
* Skip non-files in iteration
|
|
48
|
-
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
49
|
-
* @req REQ-MAINT-UPDATE
|
|
50
|
-
*/
|
|
51
|
-
/**
|
|
52
|
-
* Skip entries that are not regular files (e.g., directories)
|
|
53
|
-
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
54
|
-
* @req REQ-MAINT-UPDATE
|
|
55
|
-
*/
|
|
56
|
-
if (!stat.isFile())
|
|
57
|
-
return;
|
|
58
|
-
const content = fs.readFileSync(fullPath, "utf8");
|
|
45
|
+
const content = fs.readFileSync(fullPath, "utf8"); // getAllFiles already returns regular files
|
|
59
46
|
const newContent = content.replace(regex,
|
|
60
47
|
/**
|
|
61
48
|
* Replacement callback to update annotation references
|
|
@@ -1,22 +1,89 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Create a fixer function that inserts a @story annotation before the target node.
|
|
3
|
+
* This fixer is responsible for placing the annotation immediately before the
|
|
4
|
+
* resolved target node in the source code.
|
|
3
5
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
4
6
|
* @req REQ-AUTOFIX - Provide automatic fix function for missing @story annotations
|
|
5
7
|
*/
|
|
6
8
|
export declare function createAddStoryFix(target: any, annotationTemplate: string): (fixer: any) => any;
|
|
7
9
|
/**
|
|
8
10
|
* Create a fixer function for class method annotations.
|
|
11
|
+
* This helper ensures that the @story annotation is inserted with appropriate
|
|
12
|
+
* indentation and placement before a class method declaration.
|
|
9
13
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
10
14
|
* @req REQ-AUTOFIX - Provide automatic fix for class method annotations
|
|
11
15
|
*/
|
|
12
16
|
export declare function createMethodFix(node: any, annotationTemplate: string): (fixer: any) => any;
|
|
13
17
|
/**
|
|
14
18
|
* Default set of node types to check for missing @story annotations.
|
|
19
|
+
* This default scope covers common function-like declarations used in typical
|
|
20
|
+
* TypeScript and JavaScript codebases.
|
|
15
21
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
16
22
|
* @req REQ-ANNOTATION-REQUIRED - Provide sensible default scope for rule checks
|
|
17
23
|
*/
|
|
18
24
|
export declare const DEFAULT_SCOPE: string[];
|
|
25
|
+
/**
|
|
26
|
+
* Path to the story file for function-annotation helpers.
|
|
27
|
+
* This constant centralizes the reference to the canonical documentation story
|
|
28
|
+
* used by these helpers.
|
|
29
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
30
|
+
* @req REQ-ANNOTATION-REQUIRED - Provide a single source of truth for the canonical story path used by helper modules
|
|
31
|
+
*/
|
|
32
|
+
export declare const STORY_PATH = "docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md";
|
|
19
33
|
/**
|
|
20
34
|
* Allowed values for export priority option.
|
|
21
35
|
*/
|
|
22
36
|
export declare const EXPORT_PRIORITY_VALUES: string[];
|
|
37
|
+
import type { Rule } from "eslint";
|
|
38
|
+
type CoreReportOptions = {
|
|
39
|
+
annotationTemplateOverride?: string;
|
|
40
|
+
autoFixToggle?: boolean;
|
|
41
|
+
};
|
|
42
|
+
type ReportDeps = {
|
|
43
|
+
hasStoryAnnotation: (_sourceCode: any, _node: any) => boolean;
|
|
44
|
+
getReportedFunctionName: (_node: any) => string;
|
|
45
|
+
resolveAnnotationTargetNode: (_sourceCode: any, _node: any, _passedTarget: any) => any;
|
|
46
|
+
getNameNodeForReport: (_node: any) => any;
|
|
47
|
+
buildTemplateConfig: (_options?: CoreReportOptions) => {
|
|
48
|
+
effectiveTemplate: string;
|
|
49
|
+
allowFix: boolean;
|
|
50
|
+
};
|
|
51
|
+
extractName: (_node: any) => string;
|
|
52
|
+
getAnnotationTemplate: (_override?: string) => string;
|
|
53
|
+
shouldApplyAutoFix: (_autoFix: boolean | undefined) => boolean;
|
|
54
|
+
createAddStoryFix: (_target: any, _annotationTemplate: string) => any;
|
|
55
|
+
createMethodFix: (_node: any, _annotationTemplate: string) => any;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Core helper to report a missing @story annotation for a function-like node.
|
|
59
|
+
* This reporting utility delegates behavior to injected dependencies so that
|
|
60
|
+
* higher-level helpers can stay small while sharing error-reporting logic.
|
|
61
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
62
|
+
* @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
|
|
63
|
+
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
64
|
+
* @req REQ-ANNOTATION-REQUIRED
|
|
65
|
+
* @req REQ-AUTOFIX-MISSING
|
|
66
|
+
* @req REQ-ERROR-SPECIFIC
|
|
67
|
+
*/
|
|
68
|
+
export declare function coreReportMissing(deps: ReportDeps, context: Rule.RuleContext, sourceCode: any, config: {
|
|
69
|
+
node: any;
|
|
70
|
+
target?: any;
|
|
71
|
+
options?: CoreReportOptions;
|
|
72
|
+
}): void;
|
|
73
|
+
/**
|
|
74
|
+
* Core helper to report a missing @story annotation for a method-like node.
|
|
75
|
+
* This method-focused reporting utility uses injected dependencies while
|
|
76
|
+
* keeping this module centered on core error-reporting behavior.
|
|
77
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
78
|
+
* @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
|
|
79
|
+
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
80
|
+
* @req REQ-ANNOTATION-REQUIRED
|
|
81
|
+
* @req REQ-AUTOFIX-MISSING
|
|
82
|
+
* @req REQ-ERROR-SPECIFIC
|
|
83
|
+
*/
|
|
84
|
+
export declare function coreReportMethod(deps: ReportDeps, context: Rule.RuleContext, sourceCode: any, config: {
|
|
85
|
+
node: any;
|
|
86
|
+
target?: any;
|
|
87
|
+
options?: CoreReportOptions;
|
|
88
|
+
}): void;
|
|
89
|
+
export {};
|
|
@@ -1,64 +1,81 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EXPORT_PRIORITY_VALUES = exports.DEFAULT_SCOPE = void 0;
|
|
3
|
+
exports.EXPORT_PRIORITY_VALUES = exports.STORY_PATH = exports.DEFAULT_SCOPE = void 0;
|
|
4
4
|
exports.createAddStoryFix = createAddStoryFix;
|
|
5
5
|
exports.createMethodFix = createMethodFix;
|
|
6
|
+
exports.coreReportMissing = coreReportMissing;
|
|
7
|
+
exports.coreReportMethod = coreReportMethod;
|
|
8
|
+
/**
|
|
9
|
+
* Compute the insertion start offset for inserting annotations before a node.
|
|
10
|
+
* This helper ensures we insert before any export wrapper when present, while
|
|
11
|
+
* remaining resilient to malformed or unexpected AST structures.
|
|
12
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
13
|
+
* @req REQ-AUTOFIX
|
|
14
|
+
* @req REQ-AUTOFIX-SAFE
|
|
15
|
+
*/
|
|
16
|
+
function getInsertionStart(candidate) {
|
|
17
|
+
if (!candidate || typeof candidate !== "object") {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
const parent = candidate.parent;
|
|
21
|
+
if (parent &&
|
|
22
|
+
(parent.type === "ExportNamedDeclaration" ||
|
|
23
|
+
parent.type === "ExportDefaultDeclaration") &&
|
|
24
|
+
Array.isArray(parent.range) &&
|
|
25
|
+
typeof parent.range[0] === "number") {
|
|
26
|
+
return parent.range[0];
|
|
27
|
+
}
|
|
28
|
+
if (Array.isArray(candidate.range) &&
|
|
29
|
+
typeof candidate.range[0] === "number") {
|
|
30
|
+
return candidate.range[0];
|
|
31
|
+
}
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
6
34
|
/**
|
|
7
35
|
* Create a fixer function that inserts a @story annotation before the target node.
|
|
36
|
+
* This fixer is responsible for placing the annotation immediately before the
|
|
37
|
+
* resolved target node in the source code.
|
|
8
38
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
9
39
|
* @req REQ-AUTOFIX - Provide automatic fix function for missing @story annotations
|
|
10
40
|
*/
|
|
11
41
|
function createAddStoryFix(target, annotationTemplate) {
|
|
12
42
|
/**
|
|
13
43
|
* Fixer that inserts a @story annotation before the target node.
|
|
44
|
+
* This inner fixer is used by ESLint to apply the actual code modification.
|
|
14
45
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
15
46
|
* @req REQ-AUTOFIX - Provide automatic fix function for missing @story annotations
|
|
16
47
|
*/
|
|
17
48
|
function addStoryFixer(fixer) {
|
|
18
|
-
const start = target
|
|
19
|
-
? target.parent &&
|
|
20
|
-
(target.parent.type === "ExportNamedDeclaration" ||
|
|
21
|
-
target.parent.type === "ExportDefaultDeclaration") &&
|
|
22
|
-
Array.isArray(target.parent.range) &&
|
|
23
|
-
typeof target.parent.range[0] === "number"
|
|
24
|
-
? target.parent.range[0]
|
|
25
|
-
: Array.isArray(target.range) && typeof target.range[0] === "number"
|
|
26
|
-
? target.range[0]
|
|
27
|
-
: 0
|
|
28
|
-
: 0;
|
|
49
|
+
const start = getInsertionStart(target);
|
|
29
50
|
return fixer.insertTextBeforeRange([start, start], `${annotationTemplate}\n`);
|
|
30
51
|
}
|
|
31
52
|
return addStoryFixer;
|
|
32
53
|
}
|
|
33
54
|
/**
|
|
34
55
|
* Create a fixer function for class method annotations.
|
|
56
|
+
* This helper ensures that the @story annotation is inserted with appropriate
|
|
57
|
+
* indentation and placement before a class method declaration.
|
|
35
58
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
36
59
|
* @req REQ-AUTOFIX - Provide automatic fix for class method annotations
|
|
37
60
|
*/
|
|
38
61
|
function createMethodFix(node, annotationTemplate) {
|
|
39
62
|
/**
|
|
40
63
|
* Fixer that inserts a @story annotation before a method node.
|
|
64
|
+
* This inner fixer handles inserting the annotation with method-friendly
|
|
65
|
+
* formatting and spacing.
|
|
41
66
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
42
67
|
* @req REQ-AUTOFIX - Provide automatic fix for class method annotations
|
|
43
68
|
*/
|
|
44
69
|
function methodFixer(fixer) {
|
|
45
|
-
const start = node
|
|
46
|
-
? node.parent &&
|
|
47
|
-
(node.parent.type === "ExportNamedDeclaration" ||
|
|
48
|
-
node.parent.type === "ExportDefaultDeclaration") &&
|
|
49
|
-
Array.isArray(node.parent.range) &&
|
|
50
|
-
typeof node.parent.range[0] === "number"
|
|
51
|
-
? node.parent.range[0]
|
|
52
|
-
: Array.isArray(node.range) && typeof node.range[0] === "number"
|
|
53
|
-
? node.range[0]
|
|
54
|
-
: 0
|
|
55
|
-
: 0;
|
|
70
|
+
const start = getInsertionStart(node);
|
|
56
71
|
return fixer.insertTextBeforeRange([start, start], `${annotationTemplate}\n `);
|
|
57
72
|
}
|
|
58
73
|
return methodFixer;
|
|
59
74
|
}
|
|
60
75
|
/**
|
|
61
76
|
* Default set of node types to check for missing @story annotations.
|
|
77
|
+
* This default scope covers common function-like declarations used in typical
|
|
78
|
+
* TypeScript and JavaScript codebases.
|
|
62
79
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
63
80
|
* @req REQ-ANNOTATION-REQUIRED - Provide sensible default scope for rule checks
|
|
64
81
|
*/
|
|
@@ -69,7 +86,109 @@ exports.DEFAULT_SCOPE = [
|
|
|
69
86
|
"TSMethodSignature",
|
|
70
87
|
"TSDeclareFunction",
|
|
71
88
|
];
|
|
89
|
+
/**
|
|
90
|
+
* Path to the story file for function-annotation helpers.
|
|
91
|
+
* This constant centralizes the reference to the canonical documentation story
|
|
92
|
+
* used by these helpers.
|
|
93
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
94
|
+
* @req REQ-ANNOTATION-REQUIRED - Provide a single source of truth for the canonical story path used by helper modules
|
|
95
|
+
*/
|
|
96
|
+
exports.STORY_PATH = "docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md";
|
|
72
97
|
/**
|
|
73
98
|
* Allowed values for export priority option.
|
|
74
99
|
*/
|
|
75
100
|
exports.EXPORT_PRIORITY_VALUES = ["all", "exported", "non-exported"];
|
|
101
|
+
/**
|
|
102
|
+
* Core helper to report a missing @story annotation for a function-like node.
|
|
103
|
+
* This reporting utility delegates behavior to injected dependencies so that
|
|
104
|
+
* higher-level helpers can stay small while sharing error-reporting logic.
|
|
105
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
106
|
+
* @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
|
|
107
|
+
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
108
|
+
* @req REQ-ANNOTATION-REQUIRED
|
|
109
|
+
* @req REQ-AUTOFIX-MISSING
|
|
110
|
+
* @req REQ-ERROR-SPECIFIC
|
|
111
|
+
*/
|
|
112
|
+
function coreReportMissing(deps, context, sourceCode, config) {
|
|
113
|
+
const { node, target: passedTarget, options = {} } = config;
|
|
114
|
+
try {
|
|
115
|
+
if (deps.hasStoryAnnotation(sourceCode, node)) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const functionName = deps.getReportedFunctionName(node);
|
|
119
|
+
const resolvedTarget = deps.resolveAnnotationTargetNode(sourceCode, node, passedTarget);
|
|
120
|
+
const nameNode = deps.getNameNodeForReport(node);
|
|
121
|
+
const { effectiveTemplate, allowFix } = deps.buildTemplateConfig(options);
|
|
122
|
+
const name = functionName;
|
|
123
|
+
context.report({
|
|
124
|
+
node: nameNode,
|
|
125
|
+
messageId: "missingStory",
|
|
126
|
+
data: { name, functionName: name },
|
|
127
|
+
fix: allowFix
|
|
128
|
+
? deps.createAddStoryFix(resolvedTarget, effectiveTemplate)
|
|
129
|
+
: undefined,
|
|
130
|
+
suggest: [
|
|
131
|
+
{
|
|
132
|
+
desc: `Add JSDoc @story annotation for function '${name}', e.g., ${effectiveTemplate}`,
|
|
133
|
+
fix: deps.createAddStoryFix(resolvedTarget, effectiveTemplate),
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
// Intentionally swallow unexpected helper errors so traceability checks never
|
|
140
|
+
// break lint runs. When TRACEABILITY_DEBUG=1 is set, log a debug message to
|
|
141
|
+
// help diagnose misbehaving helpers in local development without affecting
|
|
142
|
+
// normal CI or production usage.
|
|
143
|
+
if (process.env.TRACEABILITY_DEBUG === "1") {
|
|
144
|
+
console.error("[traceability] coreReportMissing failed for node", error?.message ?? error);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Core helper to report a missing @story annotation for a method-like node.
|
|
150
|
+
* This method-focused reporting utility uses injected dependencies while
|
|
151
|
+
* keeping this module centered on core error-reporting behavior.
|
|
152
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
153
|
+
* @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
|
|
154
|
+
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
155
|
+
* @req REQ-ANNOTATION-REQUIRED
|
|
156
|
+
* @req REQ-AUTOFIX-MISSING
|
|
157
|
+
* @req REQ-ERROR-SPECIFIC
|
|
158
|
+
*/
|
|
159
|
+
function coreReportMethod(deps, context, sourceCode, config) {
|
|
160
|
+
const { node, target: passedTarget, options = {} } = config;
|
|
161
|
+
try {
|
|
162
|
+
if (deps.hasStoryAnnotation(sourceCode, node)) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const resolvedTarget = passedTarget ?? deps.resolveAnnotationTargetNode(sourceCode, node, null);
|
|
166
|
+
const name = deps.extractName(node);
|
|
167
|
+
const nameNode = (node.key && node.key.type === "Identifier" && node.key) || node;
|
|
168
|
+
const effectiveTemplate = deps.getAnnotationTemplate(options.annotationTemplateOverride);
|
|
169
|
+
const allowFix = deps.shouldApplyAutoFix(options.autoFixToggle);
|
|
170
|
+
context.report({
|
|
171
|
+
node: nameNode,
|
|
172
|
+
messageId: "missingStory",
|
|
173
|
+
data: { name, functionName: name },
|
|
174
|
+
fix: allowFix
|
|
175
|
+
? deps.createMethodFix(resolvedTarget, effectiveTemplate)
|
|
176
|
+
: undefined,
|
|
177
|
+
suggest: [
|
|
178
|
+
{
|
|
179
|
+
desc: `Add JSDoc @story annotation for function '${name}', e.g., ${effectiveTemplate}`,
|
|
180
|
+
fix: deps.createMethodFix(resolvedTarget, effectiveTemplate),
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
// Intentionally swallow unexpected helper errors so traceability checks never
|
|
187
|
+
// break lint runs. When TRACEABILITY_DEBUG=1 is set, log a debug message to
|
|
188
|
+
// help diagnose misbehaving helpers in local development without affecting
|
|
189
|
+
// normal CI or production usage.
|
|
190
|
+
if (process.env.TRACEABILITY_DEBUG === "1") {
|
|
191
|
+
console.error("[traceability] coreReportMethod failed for node", error?.message ?? error);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|