eslint-plugin-traceability 1.8.0 → 1.8.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.
Files changed (110) hide show
  1. package/CHANGELOG.md +5 -5
  2. package/README.md +28 -29
  3. package/SECURITY.md +135 -0
  4. package/lib/src/index.d.ts +6 -35
  5. package/lib/src/index.js +8 -5
  6. package/lib/src/maintenance/cli.js +12 -16
  7. package/lib/src/maintenance/detect.js +28 -1
  8. package/lib/src/rules/helpers/require-story-io.d.ts +2 -2
  9. package/lib/src/rules/helpers/require-story-io.js +13 -13
  10. package/lib/src/rules/helpers/valid-annotation-format-internal.d.ts +2 -2
  11. package/lib/src/rules/helpers/valid-annotation-format-internal.js +3 -3
  12. package/lib/src/rules/helpers/valid-annotation-utils.d.ts +5 -0
  13. package/lib/src/rules/helpers/valid-annotation-utils.js +43 -5
  14. package/lib/src/rules/helpers/valid-implements-utils.d.ts +11 -11
  15. package/lib/src/rules/helpers/valid-implements-utils.js +11 -11
  16. package/lib/src/rules/helpers/valid-story-reference-helpers.js +19 -0
  17. package/lib/src/rules/prefer-implements-annotation.d.ts +7 -7
  18. package/lib/src/rules/prefer-implements-annotation.js +21 -21
  19. package/lib/src/rules/valid-annotation-format.js +50 -24
  20. package/lib/src/rules/valid-req-reference.js +9 -9
  21. package/lib/src/utils/annotation-checker.js +3 -1
  22. package/lib/src/utils/reqAnnotationDetection.d.ts +2 -2
  23. package/lib/src/utils/reqAnnotationDetection.js +28 -28
  24. package/lib/tests/config/flat-config-presets-integration.test.d.ts +1 -0
  25. package/lib/tests/config/flat-config-presets-integration.test.js +75 -0
  26. package/lib/tests/maintenance/batch.test.js +11 -11
  27. package/lib/tests/maintenance/cli.test.js +34 -27
  28. package/lib/tests/maintenance/report.test.js +7 -7
  29. package/lib/tests/plugin-default-export-and-configs.test.js +0 -2
  30. package/lib/tests/rules/prefer-implements-annotation.test.js +48 -15
  31. package/lib/tests/rules/require-branch-annotation.test.js +15 -36
  32. package/lib/tests/rules/require-req-annotation.test.js +31 -104
  33. package/lib/tests/rules/require-story-annotation.test.js +3 -3
  34. package/lib/tests/rules/require-story-io-behavior.test.js +2 -7
  35. package/lib/tests/rules/require-story-io.edgecases.test.js +2 -7
  36. package/lib/tests/rules/require-story-visitors-edgecases.test.js +8 -8
  37. package/lib/tests/rules/valid-annotation-format.test.js +23 -23
  38. package/lib/tests/rules/valid-req-reference.test.js +9 -9
  39. package/lib/tests/rules/valid-story-reference.test.js +4 -43
  40. package/lib/tests/utils/annotation-checker.test.js +2 -6
  41. package/lib/tests/utils/fsTestHelpers.d.ts +7 -0
  42. package/lib/tests/utils/fsTestHelpers.js +26 -0
  43. package/lib/tests/utils/ioTestHelpers.d.ts +7 -0
  44. package/lib/tests/utils/ioTestHelpers.js +24 -0
  45. package/lib/tests/utils/temp-dir-helpers.d.ts +14 -0
  46. package/lib/tests/utils/temp-dir-helpers.js +61 -0
  47. package/package.json +8 -7
  48. package/user-docs/api-reference.md +37 -20
  49. package/user-docs/eslint-9-setup-guide.md +89 -6
  50. package/user-docs/migration-guide.md +37 -21
  51. package/docs/ci-cd-pipeline.md +0 -224
  52. package/docs/cli-integration.md +0 -22
  53. package/docs/code-quality-refactor-opportunities-2025-12-03.md +0 -78
  54. package/docs/config-presets.md +0 -38
  55. package/docs/conventional-commits-guide.md +0 -185
  56. package/docs/custom-rules-development-guide.md +0 -659
  57. package/docs/decisions/0001-allow-dynamic-require-for-built-plugins.md +0 -26
  58. package/docs/decisions/001-typescript-for-eslint-plugin.accepted.md +0 -111
  59. package/docs/decisions/002-jest-for-eslint-testing.accepted.md +0 -137
  60. package/docs/decisions/003-code-quality-ratcheting-plan.md +0 -48
  61. package/docs/decisions/004-automated-version-bumping-for-ci-cd.md +0 -196
  62. package/docs/decisions/005-github-actions-validation-tooling.accepted.md +0 -144
  63. package/docs/decisions/006-semantic-release-for-automated-publishing.accepted.md +0 -227
  64. package/docs/decisions/007-github-releases-over-changelog.accepted.md +0 -216
  65. package/docs/decisions/008-ci-audit-flags.accepted.md +0 -60
  66. package/docs/decisions/009-security-focused-lint-rules.accepted.md +0 -64
  67. package/docs/decisions/010-implements-annotation-for-multi-story-requirements.proposed.md +0 -184
  68. package/docs/decisions/adr-0001-console-usage-for-cli-guards.md +0 -190
  69. package/docs/decisions/adr-accept-dev-dep-risk-glob.md +0 -40
  70. package/docs/decisions/adr-commit-branch-tests.md +0 -54
  71. package/docs/decisions/adr-maintenance-cli-interface.md +0 -140
  72. package/docs/decisions/adr-pre-push-parity.md +0 -112
  73. package/docs/decisions/code-quality-ratcheting-plan.md +0 -53
  74. package/docs/dependency-health.md +0 -238
  75. package/docs/eslint-9-setup-guide.md +0 -517
  76. package/docs/eslint-plugin-development-guide.md +0 -487
  77. package/docs/functionality-coverage-2025-12-03.md +0 -250
  78. package/docs/jest-testing-guide.md +0 -100
  79. package/docs/rules/prefer-implements-annotation.md +0 -219
  80. package/docs/rules/require-branch-annotation.md +0 -71
  81. package/docs/rules/require-req-annotation.md +0 -203
  82. package/docs/rules/require-story-annotation.md +0 -159
  83. package/docs/rules/valid-annotation-format.md +0 -418
  84. package/docs/rules/valid-req-reference.md +0 -153
  85. package/docs/rules/valid-story-reference.md +0 -120
  86. package/docs/security-incidents/2025-11-17-glob-cli-incident.md +0 -45
  87. package/docs/security-incidents/2025-11-18-brace-expansion-redos.md +0 -45
  88. package/docs/security-incidents/2025-11-18-bundled-dev-deps-accepted-risk.md +0 -93
  89. package/docs/security-incidents/2025-11-18-tar-race-condition.md +0 -43
  90. package/docs/security-incidents/2025-12-03-dependency-health-review.md +0 -58
  91. package/docs/security-incidents/SECURITY-INCIDENT-2025-11-18-semantic-release-bundled-npm.known-error.md +0 -104
  92. package/docs/security-incidents/SECURITY-INCIDENT-TEMPLATE.md +0 -37
  93. package/docs/security-incidents/dependency-override-rationale.md +0 -57
  94. package/docs/security-incidents/dev-deps-high.json +0 -116
  95. package/docs/security-incidents/handling-procedure.md +0 -54
  96. package/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md +0 -92
  97. package/docs/stories/002.0-DEV-ESLINT-CONFIG.story.md +0 -82
  98. package/docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md +0 -112
  99. package/docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md +0 -153
  100. package/docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md +0 -138
  101. package/docs/stories/006.0-DEV-FILE-VALIDATION.story.md +0 -144
  102. package/docs/stories/007.0-DEV-ERROR-REPORTING.story.md +0 -163
  103. package/docs/stories/008.0-DEV-AUTO-FIX.story.md +0 -150
  104. package/docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md +0 -117
  105. package/docs/stories/010.0-DEV-DEEP-VALIDATION.story.md +0 -124
  106. package/docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md +0 -149
  107. package/docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md +0 -216
  108. package/docs/stories/010.3-DEV-MIGRATE-TO-IMPLEMENTS.story.md +0 -236
  109. package/docs/stories/developer-story.map.md +0 -120
  110. package/docs/ts-jest-presets-guide.md +0 -548
@@ -1,487 +0,0 @@
1
- # ESLint Plugin Development Guidance
2
-
3
- This document provides comprehensive guidance for developing ESLint plugins, specifically tailored for the eslint-plugin-traceability project. It's based on the official [ESLint plugin documentation](https://eslint.org/docs/latest/extend/plugins) and includes project-specific considerations.
4
-
5
- ## Plugin Structure Overview
6
-
7
- An ESLint plugin is a JavaScript object that exposes specific properties to ESLint:
8
-
9
- - `meta` - information about the plugin
10
- - `configs` - an object containing named configurations
11
- - `rules` - an object containing custom rule definitions
12
- - `processors` - an object containing named processors
13
-
14
- ## Basic Plugin Template
15
-
16
- ```typescript
17
- // src/index.ts
18
- const plugin = {
19
- meta: {
20
- name: "eslint-plugin-traceability",
21
- version: "1.0.0",
22
- namespace: "traceability",
23
- },
24
- configs: {},
25
- rules: {},
26
- processors: {},
27
- };
28
-
29
- // for ESM source (compiled to CommonJS)
30
- export default plugin;
31
- ```
32
-
33
- ## Meta Data Requirements
34
-
35
- ### Essential Meta Properties
36
-
37
- Every plugin should include meta information for debugging and caching:
38
-
39
- ```typescript
40
- const plugin = {
41
- meta: {
42
- name: "eslint-plugin-traceability", // npm package name
43
- version: "1.0.0", // npm package version
44
- namespace: "traceability", // prefix for rules/configs
45
- },
46
- // ... other properties
47
- };
48
- ```
49
-
50
- ### Reading from package.json
51
-
52
- For maintainability, read name and version from package.json:
53
-
54
- ```typescript
55
- import fs from "fs";
56
- import { fileURLToPath } from "url";
57
- import { dirname, join } from "path";
58
-
59
- const __filename = fileURLToPath(import.meta.url);
60
- const __dirname = dirname(__filename);
61
-
62
- const pkg = JSON.parse(
63
- fs.readFileSync(join(__dirname, "../package.json"), "utf8"),
64
- );
65
-
66
- const plugin = {
67
- meta: {
68
- name: pkg.name,
69
- version: pkg.version,
70
- namespace: "traceability",
71
- },
72
- // ... other properties
73
- };
74
- ```
75
-
76
- ## Rule Development
77
-
78
- ### Rule Structure
79
-
80
- Rules are the core functionality of an ESLint plugin:
81
-
82
- ```typescript
83
- const plugin = {
84
- meta: {
85
- name: "eslint-plugin-traceability",
86
- version: "1.0.0",
87
- namespace: "traceability",
88
- },
89
- rules: {
90
- "require-story-annotation": {
91
- meta: {
92
- type: "problem",
93
- docs: {
94
- description: "require @story annotations on functions",
95
- category: "Traceability",
96
- recommended: true,
97
- },
98
- schema: [
99
- {
100
- type: "object",
101
- properties: {
102
- // rule options
103
- },
104
- additionalProperties: false,
105
- },
106
- ],
107
- messages: {
108
- missingStory: "Function '{{name}}' is missing @story annotation",
109
- invalidStoryFormat: "@story annotation format is invalid: {{format}}",
110
- },
111
- },
112
- create(context) {
113
- return {
114
- FunctionDeclaration(node) {
115
- // rule implementation
116
- },
117
- };
118
- },
119
- },
120
- },
121
- };
122
- ```
123
-
124
- ### Rule Implementation Guidelines
125
-
126
- 1. **Use TypeScript for type safety**: Leverage @typescript-eslint/utils for AST manipulation
127
- 2. **Clear error messages**: Provide helpful, actionable error messages
128
- 3. **Configurable options**: Allow users to customize rule behavior
129
- 4. **Performance**: Avoid expensive operations in visitors
130
- 5. **Testing**: Use ESLint's RuleTester for comprehensive testing
131
-
132
- ### AST Node Handling
133
-
134
- When working with AST nodes, use TypeScript for safety:
135
-
136
- ```typescript
137
- import { TSESTree } from "@typescript-eslint/utils";
138
-
139
- function checkFunctionAnnotation(node: TSESTree.FunctionDeclaration) {
140
- // Type-safe AST manipulation
141
- if (node.id?.name) {
142
- // Check for @story annotation in comments
143
- }
144
- }
145
- ```
146
-
147
- ## Configuration Presets
148
-
149
- ### Recommended Configuration
150
-
151
- Provide a recommended configuration for common use cases:
152
-
153
- ```typescript
154
- const plugin = {
155
- // ... meta and rules
156
- configs: {},
157
- };
158
-
159
- // Assign configs after plugin definition to reference plugin
160
- Object.assign(plugin.configs, {
161
- recommended: [
162
- {
163
- plugins: {
164
- traceability: plugin,
165
- },
166
- rules: {
167
- "traceability/require-story-annotation": "error",
168
- "traceability/require-req-annotation": "error",
169
- "traceability/valid-story-reference": "error",
170
- "traceability/valid-req-reference": "error",
171
- },
172
- },
173
- ],
174
- strict: [
175
- {
176
- plugins: {
177
- traceability: plugin,
178
- },
179
- rules: {
180
- "traceability/require-story-annotation": "error",
181
- "traceability/require-req-annotation": "error",
182
- "traceability/valid-story-reference": "error",
183
- "traceability/valid-req-reference": "error",
184
- "traceability/require-branch-annotation": "error",
185
- },
186
- },
187
- ],
188
- });
189
- ```
190
-
191
- ### Configuration Usage
192
-
193
- Users can extend configurations in their eslint.config.js:
194
-
195
- ```javascript
196
- // eslint.config.js
197
- import { defineConfig } from "eslint/config";
198
- import traceability from "eslint-plugin-traceability";
199
-
200
- export default defineConfig([
201
- {
202
- files: ["src/**/*.{js,ts}"],
203
- plugins: {
204
- traceability,
205
- },
206
- extends: ["traceability/recommended"],
207
- },
208
- ]);
209
- ```
210
-
211
- ## Testing Strategy
212
-
213
- ### Using ESLint's RuleTester
214
-
215
- ```typescript
216
- // tests/rules/require-story-annotation.test.ts
217
- import { RuleTester } from "eslint";
218
- import rule from "../../src/rules/require-story-annotation";
219
-
220
- const ruleTester = new RuleTester({
221
- parser: require.resolve("@typescript-eslint/parser"),
222
- parserOptions: {
223
- ecmaVersion: 2020,
224
- sourceType: "module",
225
- },
226
- });
227
-
228
- ruleTester.run("require-story-annotation", rule, {
229
- valid: [
230
- {
231
- code: `
232
- /**
233
- * @story docs/stories/001.0-DEV-EXAMPLE.story.md
234
- * @req REQ-EXAMPLE
235
- */
236
- function validFunction() {}
237
- `,
238
- },
239
- ],
240
- invalid: [
241
- {
242
- code: `function invalidFunction() {}`,
243
- errors: [
244
- {
245
- messageId: "missingStory",
246
- data: { name: "invalidFunction" },
247
- },
248
- ],
249
- },
250
- ],
251
- });
252
- ```
253
-
254
- ### Test Organization
255
-
256
- - **Unit tests**: Test individual rules in isolation
257
- - **Integration tests**: Test plugin loading and configuration
258
- - **File system tests**: Test file reference validation (use temporary directories)
259
-
260
- ## Project-Specific Considerations
261
-
262
- ### File System Integration
263
-
264
- For validating @story references to actual files:
265
-
266
- ```typescript
267
- import fs from "fs/promises";
268
- import path from "path";
269
-
270
- async function validateStoryFile(
271
- storyPath: string,
272
- context: any,
273
- ): Promise<boolean> {
274
- try {
275
- const fullPath = path.resolve(context.getCwd(), storyPath);
276
-
277
- // Check file exists
278
- await fs.access(fullPath);
279
-
280
- // Check file extension
281
- if (!fullPath.endsWith(".story.md")) {
282
- return false;
283
- }
284
-
285
- return true;
286
- } catch {
287
- return false;
288
- }
289
- }
290
- ```
291
-
292
- ### Requirement Reference Validation
293
-
294
- For validating @req references within story files:
295
-
296
- ```typescript
297
- async function validateRequirement(
298
- storyPath: string,
299
- reqId: string,
300
- ): Promise<boolean> {
301
- try {
302
- const content = await fs.readFile(storyPath, "utf8");
303
-
304
- // Look for requirement ID in story content
305
- const reqPattern = new RegExp(`\\*\\*${reqId}\\*\\*:`, "g");
306
- return reqPattern.test(content);
307
- } catch {
308
- return false;
309
- }
310
- }
311
- ```
312
-
313
- ### Configuration Options
314
-
315
- Allow users to customize behavior:
316
-
317
- ```typescript
318
- interface RuleOptions {
319
- storyFilePattern?: string; // Default: "**/*.story.md"
320
- requirementPattern?: string; // Default: "REQ-*"
321
- excludePatterns?: string[]; // Files to exclude
322
- includePrivateFunctions?: boolean; // Default: false
323
- }
324
- ```
325
-
326
- ## Build and Distribution
327
-
328
- ### TypeScript Configuration
329
-
330
- Configure TypeScript to output CommonJS for ESLint compatibility:
331
-
332
- ```json
333
- // tsconfig.json
334
- {
335
- "compilerOptions": {
336
- "target": "ES2020",
337
- "module": "commonjs",
338
- "moduleResolution": "node",
339
- "declaration": true,
340
- "outDir": "./lib",
341
- "strict": true
342
- },
343
- "include": ["src/**/*"],
344
- "exclude": ["node_modules", "lib", "tests"]
345
- }
346
- ```
347
-
348
- ### Package.json Configuration
349
-
350
- Essential package.json settings for ESLint plugins:
351
-
352
- ```json
353
- {
354
- "name": "eslint-plugin-traceability",
355
- "version": "1.0.0",
356
- "description": "ESLint plugin for enforcing code traceability annotations",
357
- "main": "lib/index.js",
358
- "types": "lib/index.d.ts",
359
- "keywords": ["eslint", "eslintplugin", "eslint-plugin", "traceability"],
360
- "peerDependencies": {
361
- "eslint": ">=9.0.0"
362
- },
363
- "engines": {
364
- "node": ">=18.0.0"
365
- }
366
- }
367
- ```
368
-
369
- ## Development Workflow
370
-
371
- ### Local Testing
372
-
373
- 1. **Link locally**: Use `npm link` for local development
374
- 2. **Test project**: Create a test project to verify plugin behavior
375
- 3. **Rule tester**: Use ESLint's RuleTester for individual rule testing
376
- 4. **Integration testing**: Test complete plugin configuration
377
-
378
- ### Quality Checks
379
-
380
- Recommended linting for the plugin itself:
381
-
382
- ```javascript
383
- // eslint.config.js (for the plugin project)
384
- import js from "@eslint/js";
385
- import typescript from "@typescript-eslint/eslint-plugin";
386
- import eslintPlugin from "eslint-plugin-eslint-plugin";
387
-
388
- export default [
389
- js.configs.recommended,
390
- {
391
- plugins: {
392
- "@typescript-eslint": typescript,
393
- "eslint-plugin": eslintPlugin,
394
- },
395
- rules: {
396
- // Plugin-specific linting rules
397
- },
398
- },
399
- ];
400
- ```
401
-
402
- ## Performance Considerations
403
-
404
- ### Efficient AST Traversal
405
-
406
- - **Minimal visitors**: Only register for needed node types
407
- - **Early returns**: Exit early when conditions aren't met
408
- - **Caching**: Cache expensive operations (file reads, regex compilation)
409
- - **Async handling**: Use proper async patterns for file operations
410
-
411
- ### Memory Management
412
-
413
- - **Avoid global state**: Keep rule instances isolated
414
- - **Clean up resources**: Properly handle file handles and timers
415
- - **Limit recursion**: Avoid deep recursive operations
416
-
417
- ## Documentation Requirements
418
-
419
- ### Rule Documentation
420
-
421
- Each rule should have comprehensive documentation:
422
-
423
- ```typescript
424
- const rule = {
425
- meta: {
426
- docs: {
427
- description: "require @story annotations on functions",
428
- category: "Traceability",
429
- recommended: true,
430
- url: "https://github.com/voder-ai/eslint-plugin-traceability#require-story-annotation",
431
- },
432
- // ... other meta properties
433
- },
434
- // ... rule implementation
435
- };
436
- ```
437
-
438
- ### README Structure
439
-
440
- Include in the plugin README:
441
-
442
- 1. **Installation instructions**
443
- 2. **Configuration examples**
444
- 3. **Rule documentation**
445
- 4. **Usage examples**
446
- 5. **Troubleshooting guide**
447
-
448
- ## Security Considerations
449
-
450
- ### File System Access
451
-
452
- - **Validate paths**: Prevent directory traversal attacks
453
- - **Sanitize input**: Validate user-provided file patterns
454
- - **Limit scope**: Restrict file access to project directory
455
-
456
- ### Input Validation
457
-
458
- - **Schema validation**: Use JSON Schema for rule options
459
- - **Type checking**: Leverage TypeScript for compile-time safety
460
- - **Runtime checks**: Validate configuration at runtime
461
-
462
- ## Maintenance Guidelines
463
-
464
- ### Version Management
465
-
466
- - **Semantic versioning**: Follow semver for releases
467
- - **Breaking changes**: Document breaking changes clearly
468
- - **Migration guides**: Provide upgrade instructions
469
-
470
- ### Community Support
471
-
472
- - **Issue templates**: Provide clear bug report templates
473
- - **Contributing guide**: Document contribution process
474
- - **Code of conduct**: Establish community guidelines
475
-
476
- ---
477
-
478
- ### Security and Dependency Tooling
479
-
480
- Plugin development in this repo is protected by the same security and dependency checks described in the main README. `npm run ci-verify:full` runs `npm audit --omit=dev --audit-level=high`, `npm run safety:deps`, and `npm run audit:dev-high`. These commands are executed both locally via Husky pre-push hooks and in CI, so contributors working on rules or plugin internals automatically benefit from the same security and dependency guarantees promised to end users.
481
-
482
- ## Related Resources
483
-
484
- - [ESLint Plugin Development Guide](https://eslint.org/docs/latest/extend/plugins)
485
- - [ESLint Custom Rules](https://eslint.org/docs/latest/extend/custom-rules)
486
- - [@typescript-eslint/utils](https://typescript-eslint.io/packages/utils/)
487
- - [ESLint RuleTester](https://eslint.org/docs/latest/integrate/nodejs-api#ruletester)