eslint-plugin-traceability 1.1.0 → 1.1.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/lib/src/index.d.ts +80 -0
- package/lib/src/index.js +58 -0
- package/lib/src/maintenance/batch.d.ts +16 -0
- package/lib/src/maintenance/batch.js +28 -0
- package/lib/src/maintenance/detect.d.ts +6 -0
- package/lib/src/maintenance/detect.js +69 -0
- package/lib/src/maintenance/index.js +22 -0
- package/lib/src/maintenance/report.d.ts +7 -0
- package/lib/src/maintenance/report.js +17 -0
- package/lib/src/maintenance/update.d.ts +6 -0
- package/lib/src/maintenance/update.js +67 -0
- package/lib/src/maintenance/utils.d.ts +6 -0
- package/lib/src/maintenance/utils.js +64 -0
- package/lib/src/rules/require-branch-annotation.d.ts +7 -0
- package/lib/src/rules/require-branch-annotation.js +111 -0
- package/lib/src/rules/require-req-annotation.d.ts +7 -0
- package/lib/src/rules/require-req-annotation.js +38 -0
- package/lib/src/rules/require-story-annotation.d.ts +7 -0
- package/lib/src/rules/require-story-annotation.js +50 -0
- package/lib/src/rules/valid-annotation-format.d.ts +10 -0
- package/lib/src/rules/valid-annotation-format.js +60 -0
- package/lib/src/rules/valid-req-reference.d.ts +3 -0
- package/lib/src/rules/valid-req-reference.js +104 -0
- package/lib/src/rules/valid-story-reference.d.ts +3 -0
- package/lib/src/rules/valid-story-reference.js +168 -0
- package/lib/tests/fixtures/stale/example.d.ts +0 -0
- package/{tests/fixtures/stale/example.ts → lib/tests/fixtures/stale/example.js} +1 -0
- package/lib/tests/fixtures/update/example.d.ts +0 -0
- package/{tests/fixtures/update/example.ts → lib/tests/fixtures/update/example.js} +1 -0
- package/lib/tests/fixtures/valid-annotations/example.d.ts +0 -0
- package/{tests/fixtures/valid-annotations/example.ts → lib/tests/fixtures/valid-annotations/example.js} +1 -0
- package/lib/tests/maintenance/batch.test.d.ts +1 -0
- package/lib/tests/maintenance/batch.test.js +79 -0
- package/lib/tests/maintenance/detect-isolated.test.d.ts +1 -0
- package/lib/tests/maintenance/detect-isolated.test.js +95 -0
- package/lib/tests/maintenance/detect.test.d.ts +1 -0
- package/lib/tests/maintenance/detect.test.js +23 -0
- package/lib/tests/maintenance/report.test.d.ts +1 -0
- package/lib/tests/maintenance/report.test.js +67 -0
- package/lib/tests/maintenance/update-isolated.test.d.ts +1 -0
- package/lib/tests/maintenance/update-isolated.test.js +66 -0
- package/lib/tests/maintenance/update.test.d.ts +1 -0
- package/lib/tests/maintenance/update.test.js +26 -0
- package/lib/tests/plugin-default-export-and-configs.test.d.ts +1 -0
- package/lib/tests/plugin-default-export-and-configs.test.js +72 -0
- package/lib/tests/plugin-setup.test.d.ts +1 -0
- package/lib/tests/plugin-setup.test.js +51 -0
- package/lib/tests/rules/require-branch-annotation.test.d.ts +1 -0
- package/lib/tests/rules/require-branch-annotation.test.js +253 -0
- package/lib/tests/rules/require-req-annotation.test.d.ts +1 -0
- package/lib/tests/rules/require-req-annotation.test.js +41 -0
- package/lib/tests/rules/require-story-annotation.test.d.ts +1 -0
- package/lib/tests/rules/require-story-annotation.test.js +36 -0
- package/lib/tests/rules/valid-annotation-format.test.d.ts +1 -0
- package/lib/tests/rules/valid-annotation-format.test.js +58 -0
- package/lib/tests/rules/valid-req-reference.test.d.ts +1 -0
- package/lib/tests/rules/valid-req-reference.test.js +87 -0
- package/lib/tests/rules/valid-story-reference.test.d.ts +1 -0
- package/lib/tests/rules/valid-story-reference.test.js +69 -0
- package/package.json +6 -1
- package/.env.example +0 -6
- package/.github/workflows/ci-cd.yml +0 -107
- package/.husky/pre-commit +0 -1
- package/.husky/pre-push +0 -1
- package/.prettierignore +0 -27
- package/.prettierrc +0 -4
- package/.releaserc.json +0 -15
- package/.voder/history.md +0 -162
- package/.voder/implementation-progress.md +0 -144
- package/.voder/last-action.md +0 -83
- package/.voder/plan.md +0 -12
- package/.voder/progress-chart.png +0 -0
- package/.voder/progress-log-areas.csv +0 -39
- package/.voder/progress-log.csv +0 -38
- package/.voder/traceability/docs-stories-001.0-DEV-PLUGIN-SETUP.story.xml +0 -17
- package/.voder/traceability/docs-stories-002.0-DEV-ESLINT-CONFIG.story.xml +0 -13
- package/.voder/traceability/docs-stories-003.0-DEV-FUNCTION-ANNOTATIONS.story.xml +0 -9
- package/.voder/traceability/docs-stories-004.0-DEV-BRANCH-ANNOTATIONS.story.xml +0 -9
- package/.voder/traceability/docs-stories-005.0-DEV-ANNOTATION-VALIDATION.story.xml +0 -9
- package/.voder/traceability/docs-stories-006.0-DEV-FILE-VALIDATION.story.xml +0 -9
- package/.voder/traceability/docs-stories-007.0-DEV-ERROR-REPORTING.story.xml +0 -9
- package/.voder/traceability/docs-stories-008.0-DEV-AUTO-FIX.story.xml +0 -9
- package/.voder/traceability/docs-stories-009.0-DEV-MAINTENANCE-TOOLS.story.xml +0 -16
- package/.voder/traceability/docs-stories-010.0-DEV-DEEP-VALIDATION.story.xml +0 -11
- package/CHANGELOG.md +0 -57
- package/CONTRIBUTING.md +0 -99
- package/cli-integration.js +0 -103
- package/docs/cli-integration.md +0 -105
- package/docs/config-presets.md +0 -38
- package/docs/conventional-commits-guide.md +0 -185
- package/docs/decisions/001-typescript-for-eslint-plugin.accepted.md +0 -111
- package/docs/decisions/002-jest-for-eslint-testing.accepted.md +0 -137
- package/docs/decisions/003-code-quality-ratcheting-plan.md +0 -48
- package/docs/decisions/004-automated-version-bumping-for-ci-cd.md +0 -196
- package/docs/decisions/005-github-actions-validation-tooling.accepted.md +0 -144
- package/docs/decisions/006-semantic-release-for-automated-publishing.accepted.md +0 -227
- package/docs/eslint-9-setup-guide.md +0 -517
- package/docs/eslint-plugin-development-guide.md +0 -483
- package/docs/jest-testing-guide.md +0 -100
- package/docs/rules/require-branch-annotation.md +0 -34
- package/docs/rules/require-req-annotation.md +0 -39
- package/docs/rules/require-story-annotation.md +0 -36
- package/docs/rules/valid-annotation-format.md +0 -52
- package/docs/rules/valid-req-reference.md +0 -58
- package/docs/rules/valid-story-reference.md +0 -47
- package/docs/security-incidents/unresolved-vulnerabilities.md +0 -11
- package/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md +0 -82
- package/docs/stories/002.0-DEV-ESLINT-CONFIG.story.md +0 -82
- package/docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md +0 -85
- package/docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md +0 -107
- package/docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md +0 -119
- package/docs/stories/006.0-DEV-FILE-VALIDATION.story.md +0 -127
- package/docs/stories/007.0-DEV-ERROR-REPORTING.story.md +0 -89
- package/docs/stories/008.0-DEV-AUTO-FIX.story.md +0 -104
- package/docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md +0 -104
- package/docs/stories/010.0-DEV-DEEP-VALIDATION.story.md +0 -110
- package/docs/stories/developer-story.map.md +0 -118
- package/eslint.config.js +0 -146
- package/jest.config.js +0 -21
- package/scripts/smoke-test.sh +0 -45
- package/src/index.ts +0 -56
- package/src/maintenance/batch.ts +0 -29
- package/src/maintenance/detect.ts +0 -42
- package/src/maintenance/report.ts +0 -15
- package/src/maintenance/update.ts +0 -40
- package/src/maintenance/utils.ts +0 -28
- package/src/rules/require-branch-annotation.ts +0 -114
- package/src/rules/require-req-annotation.ts +0 -36
- package/src/rules/require-story-annotation.ts +0 -52
- package/src/rules/valid-annotation-format.ts +0 -62
- package/src/rules/valid-req-reference.ts +0 -114
- package/src/rules/valid-story-reference.ts +0 -213
- package/tests/fixtures/story_bullet.md +0 -6
- package/tests/maintenance/batch.test.ts +0 -55
- package/tests/maintenance/detect-isolated.test.ts +0 -65
- package/tests/maintenance/detect.test.ts +0 -19
- package/tests/maintenance/report.test.ts +0 -37
- package/tests/maintenance/update-isolated.test.ts +0 -39
- package/tests/maintenance/update.test.ts +0 -21
- package/tests/plugin-default-export-and-configs.test.ts +0 -50
- package/tests/plugin-setup.test.ts +0 -17
- package/tests/rules/require-branch-annotation.test.ts +0 -250
- package/tests/rules/require-req-annotation.test.ts +0 -38
- package/tests/rules/require-story-annotation.test.ts +0 -33
- package/tests/rules/valid-annotation-format.test.ts +0 -55
- package/tests/rules/valid-req-reference.test.ts +0 -85
- package/tests/rules/valid-story-reference.test.ts +0 -66
- package/tsconfig.json +0 -15
- package/user-docs/api-reference.md +0 -135
- package/user-docs/examples.md +0 -73
- package/user-docs/migration-guide.md +0 -71
- /package/{src/maintenance/index.ts → lib/src/maintenance/index.d.ts} +0 -0
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for: docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
|
|
3
|
-
* @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
|
|
4
|
-
* @req REQ-PLUGIN-STRUCTURE - plugin exports rules and configs
|
|
5
|
-
*/
|
|
6
|
-
import plugin, { rules, configs } from "../src/index";
|
|
7
|
-
|
|
8
|
-
describe("Traceability ESLint Plugin (Story 001.0-DEV-PLUGIN-SETUP)", () => {
|
|
9
|
-
it("[REQ-PLUGIN-STRUCTURE] plugin exports rules and configs", () => {
|
|
10
|
-
expect(rules).toBeDefined();
|
|
11
|
-
expect(configs).toBeDefined();
|
|
12
|
-
expect(typeof rules).toBe("object");
|
|
13
|
-
expect(typeof configs).toBe("object");
|
|
14
|
-
expect(plugin.rules).toBe(rules);
|
|
15
|
-
expect(plugin.configs).toBe(configs);
|
|
16
|
-
});
|
|
17
|
-
});
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for: docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
|
|
3
|
-
* @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
|
|
4
|
-
* @req REQ-BRANCH-DETECTION - Verify require-branch-annotation rule enforces branch annotations
|
|
5
|
-
*/
|
|
6
|
-
import { RuleTester } from "eslint";
|
|
7
|
-
import rule from "../../src/rules/require-branch-annotation";
|
|
8
|
-
|
|
9
|
-
const ruleTester = new RuleTester({
|
|
10
|
-
languageOptions: { parserOptions: { ecmaVersion: 2020 } },
|
|
11
|
-
} as any);
|
|
12
|
-
|
|
13
|
-
describe("Require Branch Annotation Rule (Story 004.0-DEV-BRANCH-ANNOTATIONS)", () => {
|
|
14
|
-
ruleTester.run("require-branch-annotation", rule, {
|
|
15
|
-
valid: [
|
|
16
|
-
{
|
|
17
|
-
name: "[REQ-BRANCH-DETECTION] valid fallback scanning comment detection",
|
|
18
|
-
code: `switch (value) {
|
|
19
|
-
|
|
20
|
-
// @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
|
|
21
|
-
// @req REQ-BRANCH-DETECTION
|
|
22
|
-
case 'z':
|
|
23
|
-
break;
|
|
24
|
-
}`,
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
name: "[REQ-BRANCH-DETECTION] valid if-statement with annotations",
|
|
28
|
-
code: `// @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
|
|
29
|
-
// @req REQ-BRANCH-DETECTION
|
|
30
|
-
if (condition) {}`,
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
name: "[REQ-BRANCH-DETECTION] valid for loop with block comment annotations",
|
|
34
|
-
code: `/* @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md */
|
|
35
|
-
/* @req REQ-BRANCH-DETECTION */
|
|
36
|
-
for (let i = 0; i < 10; i++) {}`,
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
name: "[REQ-BRANCH-DETECTION] valid switch-case with annotations",
|
|
40
|
-
code: `switch (value) {
|
|
41
|
-
// @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
|
|
42
|
-
// @req REQ-BRANCH-DETECTION
|
|
43
|
-
case 'a':
|
|
44
|
-
break;
|
|
45
|
-
default:
|
|
46
|
-
break;
|
|
47
|
-
}`,
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
name: "[REQ-BRANCH-DETECTION] valid try-finally with annotations",
|
|
51
|
-
code: `/* @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md */
|
|
52
|
-
/* @req REQ-BRANCH-DETECTION */
|
|
53
|
-
try {
|
|
54
|
-
doSomething();
|
|
55
|
-
} finally {
|
|
56
|
-
cleanUp();
|
|
57
|
-
}`,
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name: "[REQ-BRANCH-DETECTION] valid catch with annotations",
|
|
61
|
-
code: `/* @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md */
|
|
62
|
-
/* @req REQ-BRANCH-DETECTION */
|
|
63
|
-
try {
|
|
64
|
-
doSomething();
|
|
65
|
-
}
|
|
66
|
-
/* @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md */
|
|
67
|
-
/* @req REQ-BRANCH-DETECTION */
|
|
68
|
-
catch (error) {
|
|
69
|
-
handleError(error);
|
|
70
|
-
}`,
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
name: "[REQ-BRANCH-DETECTION] valid do-while loop with annotations",
|
|
74
|
-
code: `/* @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md */
|
|
75
|
-
/* @req REQ-BRANCH-DETECTION */
|
|
76
|
-
do {
|
|
77
|
-
process();
|
|
78
|
-
} while (condition);`,
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
name: "[REQ-BRANCH-DETECTION] valid for-of loop with annotations",
|
|
82
|
-
code: `/* @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md */
|
|
83
|
-
/* @req REQ-BRANCH-DETECTION */
|
|
84
|
-
for (const item of items) {
|
|
85
|
-
process(item);
|
|
86
|
-
}`,
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
name: "[REQ-BRANCH-DETECTION] valid for-in loop with annotations",
|
|
90
|
-
code: `/* @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md */
|
|
91
|
-
/* @req REQ-BRANCH-DETECTION */
|
|
92
|
-
for (const key in object) {
|
|
93
|
-
console.log(key);
|
|
94
|
-
}`,
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
name: "[REQ-BRANCH-DETECTION] valid while loop with annotations",
|
|
98
|
-
code: `/* @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md */
|
|
99
|
-
/* @req REQ-BRANCH-DETECTION */
|
|
100
|
-
while (condition) {
|
|
101
|
-
iterate();
|
|
102
|
-
}`,
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
name: "[REQ-BRANCH-DETECTION] valid switch-case with inline annotation",
|
|
106
|
-
code: `switch (value) {
|
|
107
|
-
// @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
|
|
108
|
-
// @req REQ-BRANCH-DETECTION
|
|
109
|
-
case 'a':
|
|
110
|
-
break;
|
|
111
|
-
}`,
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
name: "[REQ-BRANCH-DETECTION] valid default case without annotations",
|
|
115
|
-
code: `switch (value) {
|
|
116
|
-
default:
|
|
117
|
-
doSomething();
|
|
118
|
-
}`,
|
|
119
|
-
},
|
|
120
|
-
],
|
|
121
|
-
invalid: [
|
|
122
|
-
{
|
|
123
|
-
name: "[REQ-BRANCH-DETECTION] missing annotations on if-statement",
|
|
124
|
-
code: `if (condition) {}`,
|
|
125
|
-
output: `// @story <story-file>.story.md
|
|
126
|
-
if (condition) {}`,
|
|
127
|
-
errors: [
|
|
128
|
-
{ messageId: "missingAnnotation", data: { missing: "@story" } },
|
|
129
|
-
{ messageId: "missingAnnotation", data: { missing: "@req" } },
|
|
130
|
-
],
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
name: "[REQ-BRANCH-DETECTION] missing @req on for loop when only story present",
|
|
134
|
-
code: `// @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
|
|
135
|
-
for (let i = 0; i < 5; i++) {}`,
|
|
136
|
-
output: `// @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
|
|
137
|
-
// @req <REQ-ID>
|
|
138
|
-
for (let i = 0; i < 5; i++) {}`,
|
|
139
|
-
errors: [{ messageId: "missingAnnotation", data: { missing: "@req" } }],
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
name: "[REQ-BRANCH-DETECTION] missing @story on while loop when only req present",
|
|
143
|
-
code: `// @req REQ-BRANCH-DETECTION
|
|
144
|
-
while (true) {}`,
|
|
145
|
-
output: `// @req REQ-BRANCH-DETECTION
|
|
146
|
-
// @story <story-file>.story.md
|
|
147
|
-
while (true) {}`,
|
|
148
|
-
errors: [
|
|
149
|
-
{ messageId: "missingAnnotation", data: { missing: "@story" } },
|
|
150
|
-
],
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
name: "[REQ-BRANCH-DETECTION] missing annotations on switch-case",
|
|
154
|
-
code: `switch (value) {
|
|
155
|
-
case 'a':
|
|
156
|
-
break;
|
|
157
|
-
}`,
|
|
158
|
-
output: `switch (value) {
|
|
159
|
-
// @story <story-file>.story.md
|
|
160
|
-
case 'a':
|
|
161
|
-
break;
|
|
162
|
-
}`,
|
|
163
|
-
errors: [
|
|
164
|
-
{ messageId: "missingAnnotation", data: { missing: "@story" } },
|
|
165
|
-
{ messageId: "missingAnnotation", data: { missing: "@req" } },
|
|
166
|
-
],
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
name: "[REQ-BRANCH-DETECTION] missing annotations on do-while loop",
|
|
170
|
-
code: `do {
|
|
171
|
-
action();
|
|
172
|
-
} while (condition);`,
|
|
173
|
-
output: `// @story <story-file>.story.md
|
|
174
|
-
do {
|
|
175
|
-
action();
|
|
176
|
-
} while (condition);`,
|
|
177
|
-
errors: [
|
|
178
|
-
{ messageId: "missingAnnotation", data: { missing: "@story" } },
|
|
179
|
-
{ messageId: "missingAnnotation", data: { missing: "@req" } },
|
|
180
|
-
],
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
name: "[REQ-BRANCH-DETECTION] missing annotations on for-of loop",
|
|
184
|
-
code: `for (const item of items) {
|
|
185
|
-
process(item);
|
|
186
|
-
}`,
|
|
187
|
-
output: `// @story <story-file>.story.md
|
|
188
|
-
for (const item of items) {
|
|
189
|
-
process(item);
|
|
190
|
-
}`,
|
|
191
|
-
errors: [
|
|
192
|
-
{ messageId: "missingAnnotation", data: { missing: "@story" } },
|
|
193
|
-
{ messageId: "missingAnnotation", data: { missing: "@req" } },
|
|
194
|
-
],
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
name: "[REQ-BRANCH-DETECTION] missing annotations on for-in loop",
|
|
198
|
-
code: `for (const key in object) {
|
|
199
|
-
console.log(key);
|
|
200
|
-
}`,
|
|
201
|
-
output: `// @story <story-file>.story.md
|
|
202
|
-
for (const key in object) {
|
|
203
|
-
console.log(key);
|
|
204
|
-
}`,
|
|
205
|
-
errors: [
|
|
206
|
-
{ messageId: "missingAnnotation", data: { missing: "@story" } },
|
|
207
|
-
{ messageId: "missingAnnotation", data: { missing: "@req" } },
|
|
208
|
-
],
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
name: "[REQ-BRANCH-DETECTION] missing annotations on try-catch blocks",
|
|
212
|
-
code: `try {
|
|
213
|
-
doSomething();
|
|
214
|
-
} catch (error) {
|
|
215
|
-
handleError(error);
|
|
216
|
-
}`,
|
|
217
|
-
output: `// @story <story-file>.story.md
|
|
218
|
-
try {
|
|
219
|
-
doSomething();
|
|
220
|
-
} catch (error) {
|
|
221
|
-
handleError(error);
|
|
222
|
-
}`,
|
|
223
|
-
errors: [
|
|
224
|
-
{ messageId: "missingAnnotation", data: { missing: "@story" } },
|
|
225
|
-
{ messageId: "missingAnnotation", data: { missing: "@req" } },
|
|
226
|
-
{ messageId: "missingAnnotation", data: { missing: "@story" } },
|
|
227
|
-
{ messageId: "missingAnnotation", data: { missing: "@req" } },
|
|
228
|
-
],
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
name: "[REQ-BRANCH-DETECTION] missing annotations on switch-case with blank line",
|
|
232
|
-
code: `switch (value) {
|
|
233
|
-
|
|
234
|
-
case 'a':
|
|
235
|
-
break;
|
|
236
|
-
}`,
|
|
237
|
-
output: `switch (value) {
|
|
238
|
-
|
|
239
|
-
// @story <story-file>.story.md
|
|
240
|
-
case 'a':
|
|
241
|
-
break;
|
|
242
|
-
}`,
|
|
243
|
-
errors: [
|
|
244
|
-
{ messageId: "missingAnnotation", data: { missing: "@story" } },
|
|
245
|
-
{ messageId: "missingAnnotation", data: { missing: "@req" } },
|
|
246
|
-
],
|
|
247
|
-
},
|
|
248
|
-
],
|
|
249
|
-
});
|
|
250
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for: docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
3
|
-
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
4
|
-
* @req REQ-ANNOTATION-REQUIRED - Verify require-req-annotation rule enforces @req on functions
|
|
5
|
-
*/
|
|
6
|
-
import { RuleTester } from "eslint";
|
|
7
|
-
import rule from "../../src/rules/require-req-annotation";
|
|
8
|
-
|
|
9
|
-
const ruleTester = new RuleTester();
|
|
10
|
-
|
|
11
|
-
describe("Require Req Annotation Rule (Story 003.0-DEV-FUNCTION-ANNOTATIONS)", () => {
|
|
12
|
-
ruleTester.run("require-req-annotation", rule, {
|
|
13
|
-
valid: [
|
|
14
|
-
{
|
|
15
|
-
name: "[REQ-ANNOTATION-REQUIRED] valid with only @req annotation",
|
|
16
|
-
code: `/**\n * @req REQ-EXAMPLE\n */\nfunction foo() {}`,
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
name: "[REQ-ANNOTATION-REQUIRED] valid with @story and @req annotations",
|
|
20
|
-
code: `/**\n * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md\n * @req REQ-EXAMPLE\n */\nfunction bar() {}`,
|
|
21
|
-
},
|
|
22
|
-
],
|
|
23
|
-
invalid: [
|
|
24
|
-
{
|
|
25
|
-
name: "[REQ-ANNOTATION-REQUIRED] missing @req on function without JSDoc",
|
|
26
|
-
code: `function baz() {}`,
|
|
27
|
-
output: `/** @req <REQ-ID> */\nfunction baz() {}`,
|
|
28
|
-
errors: [{ messageId: "missingReq" }],
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
name: "[REQ-ANNOTATION-REQUIRED] missing @req on function with only @story annotation",
|
|
32
|
-
code: `/**\n * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md\n */\nfunction qux() {}`,
|
|
33
|
-
output: `/**\n * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md\n */\n/** @req <REQ-ID> */\nfunction qux() {}`,
|
|
34
|
-
errors: [{ messageId: "missingReq" }],
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
});
|
|
38
|
-
});
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for: docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
3
|
-
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
4
|
-
* @req REQ-ANNOTATION-REQUIRED - Verify require-story-annotation rule enforces @story annotation on functions
|
|
5
|
-
*/
|
|
6
|
-
import { RuleTester } from "eslint";
|
|
7
|
-
import rule from "../../src/rules/require-story-annotation";
|
|
8
|
-
|
|
9
|
-
const ruleTester = new RuleTester();
|
|
10
|
-
|
|
11
|
-
describe("Require Story Annotation Rule (Story 003.0-DEV-FUNCTION-ANNOTATIONS)", () => {
|
|
12
|
-
ruleTester.run("require-story-annotation", rule, {
|
|
13
|
-
valid: [
|
|
14
|
-
{
|
|
15
|
-
name: "[REQ-ANNOTATION-REQUIRED] valid with JSDoc @story annotation",
|
|
16
|
-
code: `/**\n * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md\n */\nfunction foo() {}`,
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
name: "[REQ-ANNOTATION-REQUIRED] valid with line comment @story annotation",
|
|
20
|
-
code: `// @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
21
|
-
function foo() {}`,
|
|
22
|
-
},
|
|
23
|
-
],
|
|
24
|
-
invalid: [
|
|
25
|
-
{
|
|
26
|
-
name: "[REQ-ANNOTATION-REQUIRED] missing @story annotation on function",
|
|
27
|
-
code: `function bar() {}`,
|
|
28
|
-
output: `/** @story <story-file>.story.md */\nfunction bar() {}`,
|
|
29
|
-
errors: [{ messageId: "missingStory" }],
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
});
|
|
33
|
-
});
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for: docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
3
|
-
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
4
|
-
* @req REQ-FORMAT-SPECIFICATION - Verify valid-annotation-format rule enforces annotation format syntax
|
|
5
|
-
*/
|
|
6
|
-
import { RuleTester } from "eslint";
|
|
7
|
-
import rule from "../../src/rules/valid-annotation-format";
|
|
8
|
-
|
|
9
|
-
const ruleTester = new RuleTester({
|
|
10
|
-
languageOptions: { parserOptions: { ecmaVersion: 2020 } },
|
|
11
|
-
} as any);
|
|
12
|
-
|
|
13
|
-
describe("Valid Annotation Format Rule (Story 005.0-DEV-ANNOTATION-VALIDATION)", () => {
|
|
14
|
-
ruleTester.run("valid-annotation-format", rule, {
|
|
15
|
-
valid: [
|
|
16
|
-
{
|
|
17
|
-
name: "[REQ-PATH-FORMAT] valid story annotation format",
|
|
18
|
-
code: `// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md`,
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
name: "[REQ-REQ-FORMAT] valid req annotation format",
|
|
22
|
-
code: `// @req REQ-EXAMPLE`,
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
name: "[REQ-FORMAT-SPECIFICATION] valid block annotations",
|
|
26
|
-
code: `/**
|
|
27
|
-
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
28
|
-
* @req REQ-VALID-EXAMPLE
|
|
29
|
-
*/`,
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
invalid: [
|
|
33
|
-
{
|
|
34
|
-
name: "[REQ-PATH-FORMAT] missing story path",
|
|
35
|
-
code: `// @story`,
|
|
36
|
-
errors: [{ messageId: "invalidStoryFormat" }],
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
name: "[REQ-PATH-FORMAT] invalid story file extension",
|
|
40
|
-
code: `// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story`,
|
|
41
|
-
errors: [{ messageId: "invalidStoryFormat" }],
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
name: "[REQ-REQ-FORMAT] missing req id",
|
|
45
|
-
code: `// @req`,
|
|
46
|
-
errors: [{ messageId: "invalidReqFormat" }],
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
name: "[REQ-REQ-FORMAT] invalid req id format",
|
|
50
|
-
code: `// @req invalid-format`,
|
|
51
|
-
errors: [{ messageId: "invalidReqFormat" }],
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
});
|
|
55
|
-
});
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for: docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
|
|
3
|
-
* @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
|
|
4
|
-
* @req REQ-DEEP-PARSE - Verify valid-req-reference rule enforces existing requirement content
|
|
5
|
-
*/
|
|
6
|
-
import { RuleTester } from "eslint";
|
|
7
|
-
import rule from "../../src/rules/valid-req-reference";
|
|
8
|
-
|
|
9
|
-
const ruleTester = new RuleTester({
|
|
10
|
-
languageOptions: { parserOptions: { ecmaVersion: 2020 } },
|
|
11
|
-
} as any);
|
|
12
|
-
|
|
13
|
-
describe("Valid Req Reference Rule (Story 010.0-DEV-DEEP-VALIDATION)", () => {
|
|
14
|
-
ruleTester.run("valid-req-reference", rule, {
|
|
15
|
-
valid: [
|
|
16
|
-
{
|
|
17
|
-
name: "[REQ-DEEP-PARSE] valid requirement reference existing in story file",
|
|
18
|
-
code: `// @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
|
|
19
|
-
// @req REQ-PLUGIN-STRUCTURE`,
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
name: "[REQ-DEEP-BULLET] valid bullet list requirement existing in bullet story fixture",
|
|
23
|
-
code: `// @story tests/fixtures/story_bullet.md
|
|
24
|
-
// @req REQ-BULLET-LIST`,
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
invalid: [
|
|
28
|
-
{
|
|
29
|
-
name: "[REQ-DEEP-MATCH] missing requirement in story file",
|
|
30
|
-
code: `// @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
|
|
31
|
-
// @req REQ-NON-EXISTENT`,
|
|
32
|
-
errors: [
|
|
33
|
-
{
|
|
34
|
-
messageId: "reqMissing",
|
|
35
|
-
data: {
|
|
36
|
-
reqId: "REQ-NON-EXISTENT",
|
|
37
|
-
storyPath: "docs/stories/001.0-DEV-PLUGIN-SETUP.story.md",
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
name: "[REQ-DEEP-PARSE] disallow path traversal in story path",
|
|
44
|
-
code: `// @story ../docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
|
|
45
|
-
// @req REQ-PLUGIN-STRUCTURE`,
|
|
46
|
-
errors: [
|
|
47
|
-
{
|
|
48
|
-
messageId: "invalidPath",
|
|
49
|
-
data: {
|
|
50
|
-
storyPath: "../docs/stories/001.0-DEV-PLUGIN-SETUP.story.md",
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
name: "[REQ-DEEP-PARSE] disallow absolute path in story path",
|
|
57
|
-
code: `// @story /absolute/path/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
|
|
58
|
-
// @req REQ-PLUGIN-STRUCTURE`,
|
|
59
|
-
errors: [
|
|
60
|
-
{
|
|
61
|
-
messageId: "invalidPath",
|
|
62
|
-
data: {
|
|
63
|
-
storyPath:
|
|
64
|
-
"/absolute/path/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md",
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
],
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
name: "[REQ-DEEP-BULLET] missing bullet list requirement in bullet story fixture",
|
|
71
|
-
code: `// @story tests/fixtures/story_bullet.md
|
|
72
|
-
// @req REQ-MISSING-BULLET`,
|
|
73
|
-
errors: [
|
|
74
|
-
{
|
|
75
|
-
messageId: "reqMissing",
|
|
76
|
-
data: {
|
|
77
|
-
reqId: "REQ-MISSING-BULLET",
|
|
78
|
-
storyPath: "tests/fixtures/story_bullet.md",
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
});
|
|
85
|
-
});
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for: docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
3
|
-
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
4
|
-
* @req REQ-FILE-EXISTENCE - Verify valid-story-reference rule enforces existing .story.md files
|
|
5
|
-
*/
|
|
6
|
-
import { RuleTester } from "eslint";
|
|
7
|
-
import rule from "../../src/rules/valid-story-reference";
|
|
8
|
-
|
|
9
|
-
const ruleTester = new RuleTester({
|
|
10
|
-
languageOptions: { parserOptions: { ecmaVersion: 2020 } },
|
|
11
|
-
} as any);
|
|
12
|
-
|
|
13
|
-
describe("Valid Story Reference Rule (Story 006.0-DEV-FILE-VALIDATION)", () => {
|
|
14
|
-
ruleTester.run("valid-story-reference", rule, {
|
|
15
|
-
valid: [
|
|
16
|
-
{
|
|
17
|
-
name: "[REQ-FILE-EXISTENCE] valid story file reference",
|
|
18
|
-
code: `// @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md`,
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
name: "[REQ-EXTENSION] valid .story.md extension",
|
|
22
|
-
code: `// @story docs/stories/002.0-DEV-ESLINT-CONFIG.story.md`,
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
name: "[REQ-PATH-RESOLUTION] valid relative path with ./ prefix",
|
|
26
|
-
code: `// @story ./docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md`,
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
invalid: [
|
|
30
|
-
{
|
|
31
|
-
name: "[REQ-PATH-RESOLUTION] missing file",
|
|
32
|
-
code: `// @story docs/stories/missing-file.story.md`,
|
|
33
|
-
errors: [
|
|
34
|
-
{
|
|
35
|
-
messageId: "fileMissing",
|
|
36
|
-
data: { path: "docs/stories/missing-file.story.md" },
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
name: "[REQ-EXTENSION] invalid extension",
|
|
42
|
-
code: `// @story docs/stories/001.0-DEV-PLUGIN-SETUP.md`,
|
|
43
|
-
errors: [
|
|
44
|
-
{
|
|
45
|
-
messageId: "invalidExtension",
|
|
46
|
-
data: { path: "docs/stories/001.0-DEV-PLUGIN-SETUP.md" },
|
|
47
|
-
},
|
|
48
|
-
],
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
name: "[REQ-PATH-SECURITY] path traversal",
|
|
52
|
-
code: `// @story ../outside.story.md`,
|
|
53
|
-
errors: [
|
|
54
|
-
{ messageId: "invalidPath", data: { path: "../outside.story.md" } },
|
|
55
|
-
],
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
name: "[REQ-ABSOLUTE-PATH] absolute path not allowed",
|
|
59
|
-
code: `// @story /etc/passwd.story.md`,
|
|
60
|
-
errors: [
|
|
61
|
-
{ messageId: "invalidPath", data: { path: "/etc/passwd.story.md" } },
|
|
62
|
-
],
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
});
|
|
66
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "CommonJS",
|
|
5
|
-
"moduleResolution": "node",
|
|
6
|
-
"declaration": true,
|
|
7
|
-
"outDir": "lib",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"types": ["node", "jest", "eslint", "@typescript-eslint/utils"]
|
|
13
|
-
},
|
|
14
|
-
"include": ["src", "tests"]
|
|
15
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
# API Reference
|
|
2
|
-
|
|
3
|
-
Created autonomously by [voder.ai](https://voder.ai).
|
|
4
|
-
|
|
5
|
-
## Rules
|
|
6
|
-
|
|
7
|
-
Each rule enforces traceability conventions in your code. Below is a summary of each rule exposed by this plugin.
|
|
8
|
-
|
|
9
|
-
### traceability/require-story-annotation
|
|
10
|
-
|
|
11
|
-
Description: Ensures every function declaration has a JSDoc comment with an `@story` annotation referencing the related user story.
|
|
12
|
-
Options: None
|
|
13
|
-
Default Severity: `error`
|
|
14
|
-
Example:
|
|
15
|
-
|
|
16
|
-
```javascript
|
|
17
|
-
/**
|
|
18
|
-
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
19
|
-
* @req REQ-ANNOTATION-REQUIRED
|
|
20
|
-
*/
|
|
21
|
-
function initAuth() {
|
|
22
|
-
// authentication logic
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
### traceability/require-req-annotation
|
|
27
|
-
|
|
28
|
-
Description: Ensures every function declaration has an `@req` annotation in its JSDoc, linking to the specific requirement.
|
|
29
|
-
Options: None
|
|
30
|
-
Default Severity: `error`
|
|
31
|
-
Example:
|
|
32
|
-
|
|
33
|
-
```javascript
|
|
34
|
-
/**
|
|
35
|
-
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
36
|
-
* @req REQ-ANNOTATION-REQUIRED
|
|
37
|
-
*/
|
|
38
|
-
function initAuth() {
|
|
39
|
-
// authentication logic
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### traceability/require-branch-annotation
|
|
44
|
-
|
|
45
|
-
Description: Ensures significant code branches (if/else, loops, switch cases, try/catch) have both `@story` and `@req` annotations in preceding comments.
|
|
46
|
-
Options: None
|
|
47
|
-
Default Severity: `error`
|
|
48
|
-
Example:
|
|
49
|
-
|
|
50
|
-
```javascript
|
|
51
|
-
// @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
|
|
52
|
-
// @req REQ-BRANCH-DETECTION
|
|
53
|
-
if (error) {
|
|
54
|
-
handleError();
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### traceability/valid-annotation-format
|
|
59
|
-
|
|
60
|
-
Description: Validates that all traceability annotations (`@story`, `@req`) follow the correct JSDoc or inline comment format.
|
|
61
|
-
Options: None
|
|
62
|
-
Default Severity: `error`
|
|
63
|
-
Example:
|
|
64
|
-
|
|
65
|
-
```javascript
|
|
66
|
-
/**
|
|
67
|
-
* @story docs/stories/005.0-DEV-VALIDATION.story.md
|
|
68
|
-
* @req REQ-FORMAT-VALIDATION
|
|
69
|
-
*/
|
|
70
|
-
function example() {
|
|
71
|
-
// ...
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### traceability/valid-story-reference
|
|
76
|
-
|
|
77
|
-
Description: Checks that the file paths in `@story` annotations point to existing story markdown files.
|
|
78
|
-
Options: None
|
|
79
|
-
Default Severity: `error`
|
|
80
|
-
Example:
|
|
81
|
-
|
|
82
|
-
```javascript
|
|
83
|
-
/**
|
|
84
|
-
* @story docs/stories/006.0-DEV-STORY-EXISTS.story.md
|
|
85
|
-
* @req REQ-STORY-EXISTS
|
|
86
|
-
*/
|
|
87
|
-
function example() {
|
|
88
|
-
// ...
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### traceability/valid-req-reference
|
|
93
|
-
|
|
94
|
-
Description: Verifies that the IDs used in `@req` annotations match known requirement identifiers.
|
|
95
|
-
Options: None
|
|
96
|
-
Default Severity: `error`
|
|
97
|
-
Example:
|
|
98
|
-
|
|
99
|
-
```javascript
|
|
100
|
-
/**
|
|
101
|
-
* @story docs/stories/007.0-DEV-REQ-REFERENCE.story.md
|
|
102
|
-
* @req REQ-VALID-REFERENCE
|
|
103
|
-
*/
|
|
104
|
-
function example() {
|
|
105
|
-
// ...
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## Configuration Presets
|
|
110
|
-
|
|
111
|
-
The plugin provides two built-in presets for easy configuration:
|
|
112
|
-
|
|
113
|
-
### recommended
|
|
114
|
-
|
|
115
|
-
Enables the core traceability rules at the `error` level.
|
|
116
|
-
Usage:
|
|
117
|
-
|
|
118
|
-
```javascript
|
|
119
|
-
import js from "@eslint/js";
|
|
120
|
-
import traceability from "eslint-plugin-traceability";
|
|
121
|
-
|
|
122
|
-
export default [js.configs.recommended, traceability.configs.recommended];
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### strict
|
|
126
|
-
|
|
127
|
-
Currently mirrors the **recommended** preset, reserved for future stricter policies.
|
|
128
|
-
Usage:
|
|
129
|
-
|
|
130
|
-
```javascript
|
|
131
|
-
import js from "@eslint/js";
|
|
132
|
-
import traceability from "eslint-plugin-traceability";
|
|
133
|
-
|
|
134
|
-
export default [js.configs.recommended, traceability.configs.strict];
|
|
135
|
-
```
|