doc-freshness-checker 1.0.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/LICENSE +21 -0
- package/README.md +305 -0
- package/dist/cache/cacheManager.d.ts +42 -0
- package/dist/cache/cacheManager.js +138 -0
- package/dist/cache/cacheManager.js.map +1 -0
- package/dist/cache/cacheManager.test.d.ts +1 -0
- package/dist/cache/cacheManager.test.js +142 -0
- package/dist/cache/cacheManager.test.js.map +1 -0
- package/dist/cli.d.ts +32 -0
- package/dist/cli.js +137 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.test.d.ts +1 -0
- package/dist/cli.test.js +184 -0
- package/dist/cli.test.js.map +1 -0
- package/dist/config/defaults.d.ts +5 -0
- package/dist/config/defaults.js +135 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/defineConfig.d.ts +28 -0
- package/dist/config/defineConfig.js +30 -0
- package/dist/config/defineConfig.js.map +1 -0
- package/dist/config/defineConfig.test.d.ts +1 -0
- package/dist/config/defineConfig.test.js +10 -0
- package/dist/config/defineConfig.test.js.map +1 -0
- package/dist/config/loader.d.ts +7 -0
- package/dist/config/loader.js +250 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/loader.test.d.ts +1 -0
- package/dist/config/loader.test.js +276 -0
- package/dist/config/loader.test.js.map +1 -0
- package/dist/git/changeTracker.d.ts +44 -0
- package/dist/git/changeTracker.js +149 -0
- package/dist/git/changeTracker.js.map +1 -0
- package/dist/git/changeTracker.test.d.ts +1 -0
- package/dist/git/changeTracker.test.js +184 -0
- package/dist/git/changeTracker.test.js.map +1 -0
- package/dist/graph/codeDocGraph.d.ts +43 -0
- package/dist/graph/codeDocGraph.js +103 -0
- package/dist/graph/codeDocGraph.js.map +1 -0
- package/dist/graph/codeDocGraph.test.d.ts +1 -0
- package/dist/graph/codeDocGraph.test.js +78 -0
- package/dist/graph/codeDocGraph.test.js.map +1 -0
- package/dist/graph/graphBuilder.d.ts +17 -0
- package/dist/graph/graphBuilder.js +76 -0
- package/dist/graph/graphBuilder.js.map +1 -0
- package/dist/graph/graphBuilder.test.d.ts +1 -0
- package/dist/graph/graphBuilder.test.js +87 -0
- package/dist/graph/graphBuilder.test.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/documentParser.d.ts +22 -0
- package/dist/parsers/documentParser.js +76 -0
- package/dist/parsers/documentParser.js.map +1 -0
- package/dist/parsers/documentParser.test.d.ts +1 -0
- package/dist/parsers/documentParser.test.js +116 -0
- package/dist/parsers/documentParser.test.js.map +1 -0
- package/dist/parsers/extractors/baseExtractor.d.ts +19 -0
- package/dist/parsers/extractors/baseExtractor.js +33 -0
- package/dist/parsers/extractors/baseExtractor.js.map +1 -0
- package/dist/parsers/extractors/baseExtractor.test.d.ts +1 -0
- package/dist/parsers/extractors/baseExtractor.test.js +43 -0
- package/dist/parsers/extractors/baseExtractor.test.js.map +1 -0
- package/dist/parsers/extractors/codePatternExtractor.d.ts +13 -0
- package/dist/parsers/extractors/codePatternExtractor.js +108 -0
- package/dist/parsers/extractors/codePatternExtractor.js.map +1 -0
- package/dist/parsers/extractors/codePatternExtractor.test.d.ts +1 -0
- package/dist/parsers/extractors/codePatternExtractor.test.js +49 -0
- package/dist/parsers/extractors/codePatternExtractor.test.js.map +1 -0
- package/dist/parsers/extractors/dependencyExtractor.d.ts +12 -0
- package/dist/parsers/extractors/dependencyExtractor.js +92 -0
- package/dist/parsers/extractors/dependencyExtractor.js.map +1 -0
- package/dist/parsers/extractors/dependencyExtractor.test.d.ts +1 -0
- package/dist/parsers/extractors/dependencyExtractor.test.js +48 -0
- package/dist/parsers/extractors/dependencyExtractor.test.js.map +1 -0
- package/dist/parsers/extractors/directoryStructureExtractor.d.ts +34 -0
- package/dist/parsers/extractors/directoryStructureExtractor.js +168 -0
- package/dist/parsers/extractors/directoryStructureExtractor.js.map +1 -0
- package/dist/parsers/extractors/directoryStructureExtractor.test.d.ts +1 -0
- package/dist/parsers/extractors/directoryStructureExtractor.test.js +121 -0
- package/dist/parsers/extractors/directoryStructureExtractor.test.js.map +1 -0
- package/dist/parsers/extractors/externalUrlExtractor.d.ts +14 -0
- package/dist/parsers/extractors/externalUrlExtractor.js +53 -0
- package/dist/parsers/extractors/externalUrlExtractor.js.map +1 -0
- package/dist/parsers/extractors/externalUrlExtractor.test.d.ts +1 -0
- package/dist/parsers/extractors/externalUrlExtractor.test.js +85 -0
- package/dist/parsers/extractors/externalUrlExtractor.test.js.map +1 -0
- package/dist/parsers/extractors/filePathExtractor.d.ts +18 -0
- package/dist/parsers/extractors/filePathExtractor.js +72 -0
- package/dist/parsers/extractors/filePathExtractor.js.map +1 -0
- package/dist/parsers/extractors/filePathExtractor.test.d.ts +1 -0
- package/dist/parsers/extractors/filePathExtractor.test.js +73 -0
- package/dist/parsers/extractors/filePathExtractor.test.js.map +1 -0
- package/dist/parsers/extractors/versionExtractor.d.ts +11 -0
- package/dist/parsers/extractors/versionExtractor.js +74 -0
- package/dist/parsers/extractors/versionExtractor.js.map +1 -0
- package/dist/parsers/extractors/versionExtractor.test.d.ts +1 -0
- package/dist/parsers/extractors/versionExtractor.test.js +55 -0
- package/dist/parsers/extractors/versionExtractor.test.js.map +1 -0
- package/dist/plugins/plugin.d.ts +32 -0
- package/dist/plugins/plugin.js +40 -0
- package/dist/plugins/plugin.js.map +1 -0
- package/dist/plugins/plugin.test.d.ts +1 -0
- package/dist/plugins/plugin.test.js +23 -0
- package/dist/plugins/plugin.test.js.map +1 -0
- package/dist/reporters/consoleReporter.d.ts +15 -0
- package/dist/reporters/consoleReporter.js +73 -0
- package/dist/reporters/consoleReporter.js.map +1 -0
- package/dist/reporters/consoleReporter.test.d.ts +1 -0
- package/dist/reporters/consoleReporter.test.js +155 -0
- package/dist/reporters/consoleReporter.test.js.map +1 -0
- package/dist/reporters/enhancedReporter.d.ts +12 -0
- package/dist/reporters/enhancedReporter.js +81 -0
- package/dist/reporters/enhancedReporter.js.map +1 -0
- package/dist/reporters/enhancedReporter.test.d.ts +1 -0
- package/dist/reporters/enhancedReporter.test.js +152 -0
- package/dist/reporters/enhancedReporter.test.js.map +1 -0
- package/dist/reporters/jsonReporter.d.ts +11 -0
- package/dist/reporters/jsonReporter.js +20 -0
- package/dist/reporters/jsonReporter.js.map +1 -0
- package/dist/reporters/jsonReporter.test.d.ts +1 -0
- package/dist/reporters/jsonReporter.test.js +31 -0
- package/dist/reporters/jsonReporter.test.js.map +1 -0
- package/dist/reporters/markdownReporter.d.ts +11 -0
- package/dist/reporters/markdownReporter.js +55 -0
- package/dist/reporters/markdownReporter.js.map +1 -0
- package/dist/reporters/markdownReporter.test.d.ts +1 -0
- package/dist/reporters/markdownReporter.test.js +136 -0
- package/dist/reporters/markdownReporter.test.js.map +1 -0
- package/dist/runner.d.ts +9 -0
- package/dist/runner.js +265 -0
- package/dist/runner.js.map +1 -0
- package/dist/runner.test.d.ts +1 -0
- package/dist/runner.test.js +353 -0
- package/dist/runner.test.js.map +1 -0
- package/dist/scoring/freshnessScorer.d.ts +40 -0
- package/dist/scoring/freshnessScorer.js +170 -0
- package/dist/scoring/freshnessScorer.js.map +1 -0
- package/dist/scoring/freshnessScorer.test.d.ts +1 -0
- package/dist/scoring/freshnessScorer.test.js +397 -0
- package/dist/scoring/freshnessScorer.test.js.map +1 -0
- package/dist/semantic/vectorSearch.d.ts +84 -0
- package/dist/semantic/vectorSearch.js +484 -0
- package/dist/semantic/vectorSearch.js.map +1 -0
- package/dist/semantic/vectorSearch.test.d.ts +1 -0
- package/dist/semantic/vectorSearch.test.js +660 -0
- package/dist/semantic/vectorSearch.test.js.map +1 -0
- package/dist/setupTests.d.ts +4 -0
- package/dist/setupTests.js +11 -0
- package/dist/setupTests.js.map +1 -0
- package/dist/test-utils/console.d.ts +2 -0
- package/dist/test-utils/console.js +3 -0
- package/dist/test-utils/console.js.map +1 -0
- package/dist/test-utils/factories.d.ts +3 -0
- package/dist/test-utils/factories.js +25 -0
- package/dist/test-utils/factories.js.map +1 -0
- package/dist/test-utils/tempFiles.d.ts +1 -0
- package/dist/test-utils/tempFiles.js +12 -0
- package/dist/test-utils/tempFiles.js.map +1 -0
- package/dist/types.d.ts +304 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/boundedMap.d.ts +8 -0
- package/dist/utils/boundedMap.js +22 -0
- package/dist/utils/boundedMap.js.map +1 -0
- package/dist/utils/boundedMap.test.d.ts +1 -0
- package/dist/utils/boundedMap.test.js +57 -0
- package/dist/utils/boundedMap.test.js.map +1 -0
- package/dist/utils/illustrativePatterns.d.ts +28 -0
- package/dist/utils/illustrativePatterns.js +80 -0
- package/dist/utils/illustrativePatterns.js.map +1 -0
- package/dist/utils/illustrativePatterns.test.d.ts +1 -0
- package/dist/utils/illustrativePatterns.test.js +48 -0
- package/dist/utils/illustrativePatterns.test.js.map +1 -0
- package/dist/utils/incremental.d.ts +36 -0
- package/dist/utils/incremental.js +87 -0
- package/dist/utils/incremental.js.map +1 -0
- package/dist/utils/incremental.test.d.ts +1 -0
- package/dist/utils/incremental.test.js +84 -0
- package/dist/utils/incremental.test.js.map +1 -0
- package/dist/utils/parallel.d.ts +14 -0
- package/dist/utils/parallel.js +43 -0
- package/dist/utils/parallel.js.map +1 -0
- package/dist/utils/parallel.test.d.ts +1 -0
- package/dist/utils/parallel.test.js +48 -0
- package/dist/utils/parallel.test.js.map +1 -0
- package/dist/utils/pathSecurity.d.ts +12 -0
- package/dist/utils/pathSecurity.js +22 -0
- package/dist/utils/pathSecurity.js.map +1 -0
- package/dist/utils/pathSecurity.test.d.ts +1 -0
- package/dist/utils/pathSecurity.test.js +34 -0
- package/dist/utils/pathSecurity.test.js.map +1 -0
- package/dist/utils/similarity.d.ts +12 -0
- package/dist/utils/similarity.js +64 -0
- package/dist/utils/similarity.js.map +1 -0
- package/dist/utils/similarity.test.d.ts +1 -0
- package/dist/utils/similarity.test.js +49 -0
- package/dist/utils/similarity.test.js.map +1 -0
- package/dist/utils/validation.d.ts +13 -0
- package/dist/utils/validation.js +24 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils/validation.test.d.ts +1 -0
- package/dist/utils/validation.test.js +28 -0
- package/dist/utils/validation.test.js.map +1 -0
- package/dist/validators/codePatternValidator.d.ts +28 -0
- package/dist/validators/codePatternValidator.js +200 -0
- package/dist/validators/codePatternValidator.js.map +1 -0
- package/dist/validators/codePatternValidator.test.d.ts +1 -0
- package/dist/validators/codePatternValidator.test.js +86 -0
- package/dist/validators/codePatternValidator.test.js.map +1 -0
- package/dist/validators/dependencyValidator.d.ts +12 -0
- package/dist/validators/dependencyValidator.js +102 -0
- package/dist/validators/dependencyValidator.js.map +1 -0
- package/dist/validators/dependencyValidator.test.d.ts +1 -0
- package/dist/validators/dependencyValidator.test.js +179 -0
- package/dist/validators/dependencyValidator.test.js.map +1 -0
- package/dist/validators/directoryValidator.d.ts +30 -0
- package/dist/validators/directoryValidator.js +192 -0
- package/dist/validators/directoryValidator.js.map +1 -0
- package/dist/validators/directoryValidator.test.d.ts +1 -0
- package/dist/validators/directoryValidator.test.js +193 -0
- package/dist/validators/directoryValidator.test.js.map +1 -0
- package/dist/validators/fileValidator.d.ts +16 -0
- package/dist/validators/fileValidator.js +114 -0
- package/dist/validators/fileValidator.js.map +1 -0
- package/dist/validators/fileValidator.test.d.ts +1 -0
- package/dist/validators/fileValidator.test.js +108 -0
- package/dist/validators/fileValidator.test.js.map +1 -0
- package/dist/validators/urlValidator.d.ts +25 -0
- package/dist/validators/urlValidator.js +320 -0
- package/dist/validators/urlValidator.js.map +1 -0
- package/dist/validators/urlValidator.test.d.ts +1 -0
- package/dist/validators/urlValidator.test.js +252 -0
- package/dist/validators/urlValidator.test.js.map +1 -0
- package/dist/validators/validationEngine.d.ts +23 -0
- package/dist/validators/validationEngine.js +117 -0
- package/dist/validators/validationEngine.js.map +1 -0
- package/dist/validators/validationEngine.test.d.ts +1 -0
- package/dist/validators/validationEngine.test.js +82 -0
- package/dist/validators/validationEngine.test.js.map +1 -0
- package/dist/validators/versionValidator.d.ts +18 -0
- package/dist/validators/versionValidator.js +211 -0
- package/dist/validators/versionValidator.js.map +1 -0
- package/dist/validators/versionValidator.test.d.ts +1 -0
- package/dist/validators/versionValidator.test.js +308 -0
- package/dist/validators/versionValidator.test.js.map +1 -0
- package/package.json +98 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find the most similar string from a list using Levenshtein distance
|
|
3
|
+
*/
|
|
4
|
+
export function findSimilar(target, candidates, maxDistance = 3) {
|
|
5
|
+
if (!candidates || candidates.length === 0)
|
|
6
|
+
return null;
|
|
7
|
+
let bestMatch = null;
|
|
8
|
+
let bestDistance = Infinity;
|
|
9
|
+
const targetLower = target.toLowerCase();
|
|
10
|
+
for (const candidate of candidates) {
|
|
11
|
+
const candidateLower = candidate.toLowerCase();
|
|
12
|
+
// Exact case-insensitive match
|
|
13
|
+
if (targetLower === candidateLower && target !== candidate) {
|
|
14
|
+
return candidate;
|
|
15
|
+
}
|
|
16
|
+
const distance = levenshteinDistance(targetLower, candidateLower);
|
|
17
|
+
if (distance < bestDistance && distance <= maxDistance) {
|
|
18
|
+
bestDistance = distance;
|
|
19
|
+
bestMatch = candidate;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return bestMatch;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Calculate Levenshtein distance between two strings
|
|
26
|
+
*/
|
|
27
|
+
export function levenshteinDistance(a, b) {
|
|
28
|
+
if (a.length === 0)
|
|
29
|
+
return b.length;
|
|
30
|
+
if (b.length === 0)
|
|
31
|
+
return a.length;
|
|
32
|
+
const matrix = [];
|
|
33
|
+
// Initialize matrix
|
|
34
|
+
for (let i = 0; i <= b.length; i++) {
|
|
35
|
+
matrix[i] = [i];
|
|
36
|
+
}
|
|
37
|
+
for (let j = 0; j <= a.length; j++) {
|
|
38
|
+
matrix[0][j] = j;
|
|
39
|
+
}
|
|
40
|
+
// Fill matrix
|
|
41
|
+
for (let i = 1; i <= b.length; i++) {
|
|
42
|
+
for (let j = 1; j <= a.length; j++) {
|
|
43
|
+
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
|
44
|
+
matrix[i][j] = matrix[i - 1][j - 1];
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
|
|
48
|
+
matrix[i][j - 1] + 1, // insertion
|
|
49
|
+
matrix[i - 1][j] + 1 // deletion
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return matrix[b.length][a.length];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Calculate similarity ratio (0-1) between two strings
|
|
58
|
+
*/
|
|
59
|
+
export function similarityRatio(a, b) {
|
|
60
|
+
const distance = levenshteinDistance(a.toLowerCase(), b.toLowerCase());
|
|
61
|
+
const maxLength = Math.max(a.length, b.length);
|
|
62
|
+
return maxLength === 0 ? 1 : 1 - distance / maxLength;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=similarity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"similarity.js","sourceRoot":"","sources":["../../src/utils/similarity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { levenshteinDistance, findSimilar, similarityRatio } from './similarity.js';
|
|
2
|
+
describe('levenshteinDistance', () => {
|
|
3
|
+
it.each([
|
|
4
|
+
['', '', 0],
|
|
5
|
+
['abc', '', 3],
|
|
6
|
+
['', 'xyz', 3],
|
|
7
|
+
['kitten', 'sitting', 3],
|
|
8
|
+
['same', 'same', 0],
|
|
9
|
+
['abc', 'abd', 1],
|
|
10
|
+
])('levenshteinDistance(%s, %s) => %d', (a, b, expected) => {
|
|
11
|
+
expect(levenshteinDistance(a, b)).toBe(expected);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
describe('similarityRatio', () => {
|
|
15
|
+
it('returns 1 for identical strings', () => {
|
|
16
|
+
expect(similarityRatio('hello', 'hello')).toBe(1);
|
|
17
|
+
});
|
|
18
|
+
it('returns 1 for two empty strings', () => {
|
|
19
|
+
expect(similarityRatio('', '')).toBe(1);
|
|
20
|
+
});
|
|
21
|
+
it('is case-insensitive', () => {
|
|
22
|
+
expect(similarityRatio('Hello', 'hello')).toBe(1);
|
|
23
|
+
});
|
|
24
|
+
it('returns a value between 0 and 1 for different strings', () => {
|
|
25
|
+
const ratio = similarityRatio('kitten', 'sitting');
|
|
26
|
+
expect(ratio).toBeGreaterThan(0);
|
|
27
|
+
expect(ratio).toBeLessThan(1);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe('findSimilar', () => {
|
|
31
|
+
it('returns null for empty candidates', () => {
|
|
32
|
+
expect(findSimilar('test', [])).toBeNull();
|
|
33
|
+
expect(findSimilar('test', null)).toBeNull();
|
|
34
|
+
});
|
|
35
|
+
it('returns exact case-insensitive match preferentially', () => {
|
|
36
|
+
expect(findSimilar('README', ['readme', 'other'])).toBe('readme');
|
|
37
|
+
});
|
|
38
|
+
it('returns closest match within maxDistance', () => {
|
|
39
|
+
expect(findSimilar('fle', ['file', 'folder', 'xyz'])).toBe('file');
|
|
40
|
+
});
|
|
41
|
+
it('returns null when no match within default maxDistance', () => {
|
|
42
|
+
expect(findSimilar('abc', ['xyzxyz', 'mnopqr'])).toBeNull();
|
|
43
|
+
});
|
|
44
|
+
it('respects custom maxDistance', () => {
|
|
45
|
+
expect(findSimilar('abc', ['abd'], 1)).toBe('abd');
|
|
46
|
+
expect(findSimilar('abc', ['xyz'], 1)).toBeNull();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=similarity.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"similarity.test.js","sourceRoot":"","sources":["../../src/utils/similarity.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DocFreshnessConfig, Reference, Severity, ValidationResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get a rule severity with fallback.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getRuleSeverity(config: DocFreshnessConfig, ruleType: string, fallback: Severity): Severity;
|
|
6
|
+
/**
|
|
7
|
+
* Downgrade severity for illustrative references.
|
|
8
|
+
*/
|
|
9
|
+
export declare function severityForIllustrative(isIllustrative: boolean, baseSeverity: Severity): Severity;
|
|
10
|
+
/**
|
|
11
|
+
* Standard skipped result for illustrative references.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createIllustrativeSkippedResult(reference: Reference, message: string): ValidationResult;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get a rule severity with fallback.
|
|
3
|
+
*/
|
|
4
|
+
export function getRuleSeverity(config, ruleType, fallback) {
|
|
5
|
+
return config.rules?.[ruleType]?.severity || fallback;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Downgrade severity for illustrative references.
|
|
9
|
+
*/
|
|
10
|
+
export function severityForIllustrative(isIllustrative, baseSeverity) {
|
|
11
|
+
return isIllustrative ? 'info' : baseSeverity;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Standard skipped result for illustrative references.
|
|
15
|
+
*/
|
|
16
|
+
export function createIllustrativeSkippedResult(reference, message) {
|
|
17
|
+
return {
|
|
18
|
+
reference,
|
|
19
|
+
valid: true,
|
|
20
|
+
skipped: true,
|
|
21
|
+
message,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,MAA0B,EAAE,QAAgB,EAAE,QAAkB;IAC9F,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,QAAQ,IAAI,QAAQ,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,cAAuB,EAAE,YAAsB;IACrF,OAAO,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,+BAA+B,CAAC,SAAoB,EAAE,OAAe;IACnF,OAAO;QACL,SAAS;QACT,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,IAAI;QACb,OAAO;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getRuleSeverity, severityForIllustrative, createIllustrativeSkippedResult } from './validation.js';
|
|
2
|
+
describe('getRuleSeverity', () => {
|
|
3
|
+
it('returns configured severity when present', () => {
|
|
4
|
+
const config = { rules: { 'file-path': { severity: 'warning' } } };
|
|
5
|
+
expect(getRuleSeverity(config, 'file-path', 'error')).toBe('warning');
|
|
6
|
+
});
|
|
7
|
+
it('returns fallback when rule is not configured', () => {
|
|
8
|
+
expect(getRuleSeverity({}, 'file-path', 'error')).toBe('error');
|
|
9
|
+
expect(getRuleSeverity({ rules: {} }, 'missing', 'info')).toBe('info');
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
describe('severityForIllustrative', () => {
|
|
13
|
+
it('downgrades to info for illustrative references', () => {
|
|
14
|
+
expect(severityForIllustrative(true, 'error')).toBe('info');
|
|
15
|
+
});
|
|
16
|
+
it('keeps base severity for non-illustrative references', () => {
|
|
17
|
+
expect(severityForIllustrative(false, 'error')).toBe('error');
|
|
18
|
+
expect(severityForIllustrative(false, 'warning')).toBe('warning');
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
describe('createIllustrativeSkippedResult', () => {
|
|
22
|
+
it('creates a valid skipped result', () => {
|
|
23
|
+
const ref = { type: 'file-path', value: 'foo.ts', lineNumber: 1, raw: 'foo.ts', sourceFile: 'doc.md' };
|
|
24
|
+
const result = createIllustrativeSkippedResult(ref, 'Skipped');
|
|
25
|
+
expect(result).toEqual({ reference: ref, valid: true, skipped: true, message: 'Skipped' });
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=validation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.test.js","sourceRoot":"","sources":["../../src/utils/validation.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAC;AAG5G,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,MAAM,GAAuB,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QACvF,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,eAAe,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChE,MAAM,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,uBAAuB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC9D,MAAM,CAAC,uBAAuB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,GAAG,GAAc,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;QAClH,MAAM,MAAM,GAAG,+BAA+B,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC/D,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { DocFreshnessConfig, Document, LanguageConfig, Reference, SourceFileData, SymbolLocation, ValidationResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Language-specific source file patterns and code symbol extractors
|
|
4
|
+
*/
|
|
5
|
+
declare const languageConfigs: Record<string, LanguageConfig>;
|
|
6
|
+
/**
|
|
7
|
+
* Validates code patterns exist in source files
|
|
8
|
+
*/
|
|
9
|
+
export declare class CodePatternValidator {
|
|
10
|
+
private sourceIndex;
|
|
11
|
+
private sourceFiles;
|
|
12
|
+
constructor();
|
|
13
|
+
buildSourceIndex(config: DocFreshnessConfig): Promise<void>;
|
|
14
|
+
private detectSourcePatterns;
|
|
15
|
+
private detectLanguage;
|
|
16
|
+
private indexContent;
|
|
17
|
+
validateBatch(references: Reference[], _document: Document, config: DocFreshnessConfig): Promise<ValidationResult[]>;
|
|
18
|
+
private findSimilarSymbol;
|
|
19
|
+
/**
|
|
20
|
+
* Get the source index for graph building
|
|
21
|
+
*/
|
|
22
|
+
getSourceIndex(): Map<string, SymbolLocation[]> | null;
|
|
23
|
+
/**
|
|
24
|
+
* Get source files with content for vector search
|
|
25
|
+
*/
|
|
26
|
+
getSourceFiles(): Map<string, SourceFileData> | null;
|
|
27
|
+
}
|
|
28
|
+
export { languageConfigs };
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { glob } from 'glob';
|
|
4
|
+
import { findSimilar } from '../utils/similarity.js';
|
|
5
|
+
/**
|
|
6
|
+
* Language-specific source file patterns and code symbol extractors
|
|
7
|
+
*/
|
|
8
|
+
const languageConfigs = {
|
|
9
|
+
javascript: {
|
|
10
|
+
extensions: ['js', 'jsx', 'mjs', 'cjs'],
|
|
11
|
+
patterns: [
|
|
12
|
+
{ regex: /\bclass\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'class' },
|
|
13
|
+
{ regex: /\bexport\s+(?:async\s+)?function\s+([a-zA-Z][a-zA-Z0-9]+)/g, kind: 'function' },
|
|
14
|
+
{ regex: /\bexport\s+const\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'const' },
|
|
15
|
+
{ regex: /\bfunction\s+([a-zA-Z][a-zA-Z0-9]+)/g, kind: 'function' },
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
typescript: {
|
|
19
|
+
extensions: ['ts', 'tsx'],
|
|
20
|
+
patterns: [
|
|
21
|
+
{ regex: /\bclass\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'class' },
|
|
22
|
+
{ regex: /\binterface\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'interface' },
|
|
23
|
+
{ regex: /\btype\s+([A-Z][a-zA-Z0-9]+)\s*=/g, kind: 'type' },
|
|
24
|
+
{ regex: /\bexport\s+(?:async\s+)?function\s+([a-zA-Z][a-zA-Z0-9]+)/g, kind: 'function' },
|
|
25
|
+
{ regex: /\bexport\s+const\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'const' },
|
|
26
|
+
{ regex: /\bfunction\s+([a-zA-Z][a-zA-Z0-9]+)/g, kind: 'function' },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
python: {
|
|
30
|
+
extensions: ['py'],
|
|
31
|
+
patterns: [
|
|
32
|
+
{ regex: /\bclass\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'class' },
|
|
33
|
+
{ regex: /\bdef\s+([a-z_][a-zA-Z0-9_]*)/g, kind: 'function' },
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
go: {
|
|
37
|
+
extensions: ['go'],
|
|
38
|
+
patterns: [
|
|
39
|
+
{ regex: /\btype\s+([A-Z][a-zA-Z0-9]+)\s+struct/g, kind: 'struct' },
|
|
40
|
+
{ regex: /\btype\s+([A-Z][a-zA-Z0-9]+)\s+interface/g, kind: 'interface' },
|
|
41
|
+
{ regex: /\bfunc\s+(?:\([^)]+\)\s+)?([A-Z][a-zA-Z0-9]+)/g, kind: 'function' },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
rust: {
|
|
45
|
+
extensions: ['rs'],
|
|
46
|
+
patterns: [
|
|
47
|
+
{ regex: /\bstruct\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'struct' },
|
|
48
|
+
{ regex: /\benum\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'enum' },
|
|
49
|
+
{ regex: /\btrait\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'trait' },
|
|
50
|
+
{ regex: /\bpub\s+fn\s+([a-z_][a-zA-Z0-9_]*)/g, kind: 'function' },
|
|
51
|
+
{ regex: /\bfn\s+([a-z_][a-zA-Z0-9_]*)/g, kind: 'function' },
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
java: {
|
|
55
|
+
extensions: ['java'],
|
|
56
|
+
patterns: [
|
|
57
|
+
{ regex: /\bclass\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'class' },
|
|
58
|
+
{ regex: /\binterface\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'interface' },
|
|
59
|
+
{ regex: /\benum\s+([A-Z][a-zA-Z0-9]+)/g, kind: 'enum' },
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
import { isIllustrativeSymbol } from '../utils/illustrativePatterns.js';
|
|
64
|
+
import { createIllustrativeSkippedResult, getRuleSeverity, severityForIllustrative } from '../utils/validation.js';
|
|
65
|
+
/**
|
|
66
|
+
* Validates code patterns exist in source files
|
|
67
|
+
*/
|
|
68
|
+
export class CodePatternValidator {
|
|
69
|
+
sourceIndex;
|
|
70
|
+
sourceFiles; // Stores file content for vector search
|
|
71
|
+
constructor() {
|
|
72
|
+
this.sourceIndex = null;
|
|
73
|
+
this.sourceFiles = null;
|
|
74
|
+
}
|
|
75
|
+
async buildSourceIndex(config) {
|
|
76
|
+
if (this.sourceIndex)
|
|
77
|
+
return;
|
|
78
|
+
this.sourceIndex = new Map();
|
|
79
|
+
this.sourceFiles = new Map();
|
|
80
|
+
// Use configured source patterns or detect automatically
|
|
81
|
+
const sourcePatterns = config.sourcePatterns || this.detectSourcePatterns();
|
|
82
|
+
for (const pattern of sourcePatterns) {
|
|
83
|
+
try {
|
|
84
|
+
const files = await glob(pattern, {
|
|
85
|
+
cwd: config.rootDir,
|
|
86
|
+
absolute: true,
|
|
87
|
+
ignore: ['**/*.test.*', '**/*.spec.*', '**/*.d.ts', '**/node_modules/**', '**/vendor/**'],
|
|
88
|
+
});
|
|
89
|
+
for (const file of files) {
|
|
90
|
+
try {
|
|
91
|
+
const content = await fs.promises.readFile(file, 'utf-8');
|
|
92
|
+
const relativePath = path.relative(config.rootDir || process.cwd(), file);
|
|
93
|
+
const lang = this.detectLanguage(file);
|
|
94
|
+
this.indexContent(content, relativePath, lang);
|
|
95
|
+
// Store file content for vector search
|
|
96
|
+
this.sourceFiles.set(relativePath, { content, language: lang });
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Skip unreadable files
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Skip invalid patterns
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
detectSourcePatterns() {
|
|
109
|
+
// Auto-detect based on what files exist
|
|
110
|
+
const patterns = [];
|
|
111
|
+
for (const conf of Object.values(languageConfigs)) {
|
|
112
|
+
for (const ext of conf.extensions) {
|
|
113
|
+
patterns.push(`**/*.${ext}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return patterns;
|
|
117
|
+
}
|
|
118
|
+
detectLanguage(filePath) {
|
|
119
|
+
const ext = path.extname(filePath).slice(1).toLowerCase();
|
|
120
|
+
for (const [lang, conf] of Object.entries(languageConfigs)) {
|
|
121
|
+
if (conf.extensions.includes(ext)) {
|
|
122
|
+
return lang;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return 'javascript';
|
|
126
|
+
}
|
|
127
|
+
indexContent(content, filePath, language) {
|
|
128
|
+
const langConfig = languageConfigs[language];
|
|
129
|
+
if (!langConfig)
|
|
130
|
+
return;
|
|
131
|
+
for (const { regex, kind } of langConfig.patterns) {
|
|
132
|
+
let match;
|
|
133
|
+
// Clone regex to avoid state issues
|
|
134
|
+
const re = new RegExp(regex.source, regex.flags);
|
|
135
|
+
while ((match = re.exec(content)) !== null) {
|
|
136
|
+
const name = match[1];
|
|
137
|
+
if (!this.sourceIndex.has(name)) {
|
|
138
|
+
this.sourceIndex.set(name, []);
|
|
139
|
+
}
|
|
140
|
+
this.sourceIndex.get(name).push({ filePath, kind, language });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async validateBatch(references, _document, config) {
|
|
145
|
+
await this.buildSourceIndex(config);
|
|
146
|
+
const results = [];
|
|
147
|
+
// For code-pattern, we skip illustrative symbols by default
|
|
148
|
+
const skipIllustrative = true;
|
|
149
|
+
for (const ref of references) {
|
|
150
|
+
const name = ref.value;
|
|
151
|
+
// Check if this is an illustrative symbol (marked by extractor or detected here)
|
|
152
|
+
const illustrative = ref.isIllustrative || isIllustrativeSymbol(name);
|
|
153
|
+
if (illustrative && skipIllustrative) {
|
|
154
|
+
results.push(createIllustrativeSkippedResult(ref, 'Skipped: illustrative/example code pattern'));
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const found = this.sourceIndex.get(name);
|
|
158
|
+
if (found && found.length > 0) {
|
|
159
|
+
results.push({
|
|
160
|
+
reference: ref,
|
|
161
|
+
valid: true,
|
|
162
|
+
foundIn: found.map((f) => f.filePath),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
const similar = this.findSimilarSymbol(name);
|
|
167
|
+
// Reduce severity for illustrative patterns that weren't skipped
|
|
168
|
+
const baseSeverity = getRuleSeverity(config, 'code-pattern', 'warning');
|
|
169
|
+
results.push({
|
|
170
|
+
reference: ref,
|
|
171
|
+
valid: false,
|
|
172
|
+
severity: severityForIllustrative(illustrative, baseSeverity),
|
|
173
|
+
message: illustrative
|
|
174
|
+
? `Code pattern not found (illustrative): ${ref.kind} ${name}`
|
|
175
|
+
: `Code pattern not found: ${ref.kind} ${name}`,
|
|
176
|
+
suggestion: similar ? `Did you mean: ${similar}?` : null,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return results;
|
|
181
|
+
}
|
|
182
|
+
findSimilarSymbol(name) {
|
|
183
|
+
const symbols = Array.from(this.sourceIndex.keys());
|
|
184
|
+
return findSimilar(name, symbols);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Get the source index for graph building
|
|
188
|
+
*/
|
|
189
|
+
getSourceIndex() {
|
|
190
|
+
return this.sourceIndex;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Get source files with content for vector search
|
|
194
|
+
*/
|
|
195
|
+
getSourceFiles() {
|
|
196
|
+
return this.sourceFiles;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
export { languageConfigs };
|
|
200
|
+
//# sourceMappingURL=codePatternValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codePatternValidator.js","sourceRoot":"","sources":["../../src/validators/codePatternValidator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { CodePatternValidator } from './codePatternValidator.js';
|
|
2
|
+
function makeRef(value, overrides = {}) {
|
|
3
|
+
return {
|
|
4
|
+
type: 'code-pattern',
|
|
5
|
+
value,
|
|
6
|
+
lineNumber: 1,
|
|
7
|
+
raw: value,
|
|
8
|
+
sourceFile: 'doc.md',
|
|
9
|
+
kind: 'class',
|
|
10
|
+
language: 'typescript',
|
|
11
|
+
...overrides,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const doc = { path: 'doc.md', absolutePath: '/project/doc.md', content: '', format: 'markdown', lines: [], references: [] };
|
|
15
|
+
describe('CodePatternValidator', () => {
|
|
16
|
+
const config = {
|
|
17
|
+
rootDir: process.cwd(),
|
|
18
|
+
sourcePatterns: ['src/**/*.ts'],
|
|
19
|
+
rules: { 'code-pattern': { enabled: true, severity: 'warning' } },
|
|
20
|
+
};
|
|
21
|
+
it('finds symbols that exist in source code', async () => {
|
|
22
|
+
const validator = new CodePatternValidator();
|
|
23
|
+
const results = await validator.validateBatch([makeRef('CodePatternValidator')], doc, config);
|
|
24
|
+
expect(results[0].valid).toBe(true);
|
|
25
|
+
expect(results[0].foundIn).toBeDefined();
|
|
26
|
+
});
|
|
27
|
+
it('reports missing symbols with suggestions', async () => {
|
|
28
|
+
const validator = new CodePatternValidator();
|
|
29
|
+
const results = await validator.validateBatch([makeRef('CodePatternValidato')], doc, config);
|
|
30
|
+
expect(results[0].valid).toBe(false);
|
|
31
|
+
expect(results[0].suggestion).toContain('CodePatternValidator');
|
|
32
|
+
});
|
|
33
|
+
it('skips illustrative symbols', async () => {
|
|
34
|
+
const validator = new CodePatternValidator();
|
|
35
|
+
const results = await validator.validateBatch([makeRef('YourComponent'), makeRef('FooBar')], doc, config);
|
|
36
|
+
expect(results.every((r) => r.skipped)).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it('skips pre-marked illustrative references', async () => {
|
|
39
|
+
const validator = new CodePatternValidator();
|
|
40
|
+
const results = await validator.validateBatch([makeRef('SomeRealName', { isIllustrative: true })], doc, config);
|
|
41
|
+
expect(results[0].skipped).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
it('exposes source index and source files after building', async () => {
|
|
44
|
+
const validator = new CodePatternValidator();
|
|
45
|
+
await validator.buildSourceIndex(config);
|
|
46
|
+
expect(validator.getSourceIndex()).toBeInstanceOf(Map);
|
|
47
|
+
expect(validator.getSourceFiles()).toBeInstanceOf(Map);
|
|
48
|
+
expect(validator.getSourceIndex().size).toBeGreaterThan(0);
|
|
49
|
+
});
|
|
50
|
+
it('returns immediately when source index is already built', async () => {
|
|
51
|
+
const validator = new CodePatternValidator();
|
|
52
|
+
await validator.buildSourceIndex(config);
|
|
53
|
+
const indexBefore = validator.getSourceIndex();
|
|
54
|
+
await validator.buildSourceIndex(config);
|
|
55
|
+
expect(validator.getSourceIndex()).toBe(indexBefore);
|
|
56
|
+
});
|
|
57
|
+
it('defaults to javascript when language is unknown', async () => {
|
|
58
|
+
const validator = new CodePatternValidator();
|
|
59
|
+
await validator.buildSourceIndex({
|
|
60
|
+
rootDir: process.cwd(),
|
|
61
|
+
sourcePatterns: ['src/**/*.ts'],
|
|
62
|
+
});
|
|
63
|
+
expect(validator.getSourceIndex()).toBeInstanceOf(Map);
|
|
64
|
+
});
|
|
65
|
+
it('reports not-found symbol without suggestion when no similar exists', async () => {
|
|
66
|
+
const validator = new CodePatternValidator();
|
|
67
|
+
const results = await validator.validateBatch([makeRef('ZzzVeryUniqueName12345')], doc, config);
|
|
68
|
+
expect(results[0].valid).toBe(false);
|
|
69
|
+
expect(results[0].suggestion).toBeNull();
|
|
70
|
+
expect(results[0].message).toContain('Code pattern not found');
|
|
71
|
+
});
|
|
72
|
+
it('handles source patterns that match no files', async () => {
|
|
73
|
+
const validator = new CodePatternValidator();
|
|
74
|
+
await validator.buildSourceIndex({
|
|
75
|
+
rootDir: process.cwd(),
|
|
76
|
+
sourcePatterns: ['nonexistent-dir/**/*.zzz'],
|
|
77
|
+
});
|
|
78
|
+
expect(validator.getSourceIndex().size).toBe(0);
|
|
79
|
+
});
|
|
80
|
+
it('auto-detects source patterns when none configured', async () => {
|
|
81
|
+
const validator = new CodePatternValidator();
|
|
82
|
+
await validator.buildSourceIndex({ rootDir: process.cwd() });
|
|
83
|
+
expect(validator.getSourceIndex()).toBeInstanceOf(Map);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=codePatternValidator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codePatternValidator.test.js","sourceRoot":"","sources":["../../src/validators/codePatternValidator.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DocFreshnessConfig, Document, Reference, ValidationResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validates that mentioned dependencies exist in manifest files
|
|
4
|
+
*/
|
|
5
|
+
export declare class DependencyValidator {
|
|
6
|
+
private dependencies;
|
|
7
|
+
private loadedFromKey;
|
|
8
|
+
constructor();
|
|
9
|
+
private loadDependencies;
|
|
10
|
+
private parseManifest;
|
|
11
|
+
validateBatch(references: Reference[], _document: Document, config: DocFreshnessConfig): Promise<ValidationResult[]>;
|
|
12
|
+
}
|