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.
Files changed (246) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +305 -0
  3. package/dist/cache/cacheManager.d.ts +42 -0
  4. package/dist/cache/cacheManager.js +138 -0
  5. package/dist/cache/cacheManager.js.map +1 -0
  6. package/dist/cache/cacheManager.test.d.ts +1 -0
  7. package/dist/cache/cacheManager.test.js +142 -0
  8. package/dist/cache/cacheManager.test.js.map +1 -0
  9. package/dist/cli.d.ts +32 -0
  10. package/dist/cli.js +137 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/cli.test.d.ts +1 -0
  13. package/dist/cli.test.js +184 -0
  14. package/dist/cli.test.js.map +1 -0
  15. package/dist/config/defaults.d.ts +5 -0
  16. package/dist/config/defaults.js +135 -0
  17. package/dist/config/defaults.js.map +1 -0
  18. package/dist/config/defineConfig.d.ts +28 -0
  19. package/dist/config/defineConfig.js +30 -0
  20. package/dist/config/defineConfig.js.map +1 -0
  21. package/dist/config/defineConfig.test.d.ts +1 -0
  22. package/dist/config/defineConfig.test.js +10 -0
  23. package/dist/config/defineConfig.test.js.map +1 -0
  24. package/dist/config/loader.d.ts +7 -0
  25. package/dist/config/loader.js +250 -0
  26. package/dist/config/loader.js.map +1 -0
  27. package/dist/config/loader.test.d.ts +1 -0
  28. package/dist/config/loader.test.js +276 -0
  29. package/dist/config/loader.test.js.map +1 -0
  30. package/dist/git/changeTracker.d.ts +44 -0
  31. package/dist/git/changeTracker.js +149 -0
  32. package/dist/git/changeTracker.js.map +1 -0
  33. package/dist/git/changeTracker.test.d.ts +1 -0
  34. package/dist/git/changeTracker.test.js +184 -0
  35. package/dist/git/changeTracker.test.js.map +1 -0
  36. package/dist/graph/codeDocGraph.d.ts +43 -0
  37. package/dist/graph/codeDocGraph.js +103 -0
  38. package/dist/graph/codeDocGraph.js.map +1 -0
  39. package/dist/graph/codeDocGraph.test.d.ts +1 -0
  40. package/dist/graph/codeDocGraph.test.js +78 -0
  41. package/dist/graph/codeDocGraph.test.js.map +1 -0
  42. package/dist/graph/graphBuilder.d.ts +17 -0
  43. package/dist/graph/graphBuilder.js +76 -0
  44. package/dist/graph/graphBuilder.js.map +1 -0
  45. package/dist/graph/graphBuilder.test.d.ts +1 -0
  46. package/dist/graph/graphBuilder.test.js +87 -0
  47. package/dist/graph/graphBuilder.test.js.map +1 -0
  48. package/dist/index.d.ts +37 -0
  49. package/dist/index.js +37 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/parsers/documentParser.d.ts +22 -0
  52. package/dist/parsers/documentParser.js +76 -0
  53. package/dist/parsers/documentParser.js.map +1 -0
  54. package/dist/parsers/documentParser.test.d.ts +1 -0
  55. package/dist/parsers/documentParser.test.js +116 -0
  56. package/dist/parsers/documentParser.test.js.map +1 -0
  57. package/dist/parsers/extractors/baseExtractor.d.ts +19 -0
  58. package/dist/parsers/extractors/baseExtractor.js +33 -0
  59. package/dist/parsers/extractors/baseExtractor.js.map +1 -0
  60. package/dist/parsers/extractors/baseExtractor.test.d.ts +1 -0
  61. package/dist/parsers/extractors/baseExtractor.test.js +43 -0
  62. package/dist/parsers/extractors/baseExtractor.test.js.map +1 -0
  63. package/dist/parsers/extractors/codePatternExtractor.d.ts +13 -0
  64. package/dist/parsers/extractors/codePatternExtractor.js +108 -0
  65. package/dist/parsers/extractors/codePatternExtractor.js.map +1 -0
  66. package/dist/parsers/extractors/codePatternExtractor.test.d.ts +1 -0
  67. package/dist/parsers/extractors/codePatternExtractor.test.js +49 -0
  68. package/dist/parsers/extractors/codePatternExtractor.test.js.map +1 -0
  69. package/dist/parsers/extractors/dependencyExtractor.d.ts +12 -0
  70. package/dist/parsers/extractors/dependencyExtractor.js +92 -0
  71. package/dist/parsers/extractors/dependencyExtractor.js.map +1 -0
  72. package/dist/parsers/extractors/dependencyExtractor.test.d.ts +1 -0
  73. package/dist/parsers/extractors/dependencyExtractor.test.js +48 -0
  74. package/dist/parsers/extractors/dependencyExtractor.test.js.map +1 -0
  75. package/dist/parsers/extractors/directoryStructureExtractor.d.ts +34 -0
  76. package/dist/parsers/extractors/directoryStructureExtractor.js +168 -0
  77. package/dist/parsers/extractors/directoryStructureExtractor.js.map +1 -0
  78. package/dist/parsers/extractors/directoryStructureExtractor.test.d.ts +1 -0
  79. package/dist/parsers/extractors/directoryStructureExtractor.test.js +121 -0
  80. package/dist/parsers/extractors/directoryStructureExtractor.test.js.map +1 -0
  81. package/dist/parsers/extractors/externalUrlExtractor.d.ts +14 -0
  82. package/dist/parsers/extractors/externalUrlExtractor.js +53 -0
  83. package/dist/parsers/extractors/externalUrlExtractor.js.map +1 -0
  84. package/dist/parsers/extractors/externalUrlExtractor.test.d.ts +1 -0
  85. package/dist/parsers/extractors/externalUrlExtractor.test.js +85 -0
  86. package/dist/parsers/extractors/externalUrlExtractor.test.js.map +1 -0
  87. package/dist/parsers/extractors/filePathExtractor.d.ts +18 -0
  88. package/dist/parsers/extractors/filePathExtractor.js +72 -0
  89. package/dist/parsers/extractors/filePathExtractor.js.map +1 -0
  90. package/dist/parsers/extractors/filePathExtractor.test.d.ts +1 -0
  91. package/dist/parsers/extractors/filePathExtractor.test.js +73 -0
  92. package/dist/parsers/extractors/filePathExtractor.test.js.map +1 -0
  93. package/dist/parsers/extractors/versionExtractor.d.ts +11 -0
  94. package/dist/parsers/extractors/versionExtractor.js +74 -0
  95. package/dist/parsers/extractors/versionExtractor.js.map +1 -0
  96. package/dist/parsers/extractors/versionExtractor.test.d.ts +1 -0
  97. package/dist/parsers/extractors/versionExtractor.test.js +55 -0
  98. package/dist/parsers/extractors/versionExtractor.test.js.map +1 -0
  99. package/dist/plugins/plugin.d.ts +32 -0
  100. package/dist/plugins/plugin.js +40 -0
  101. package/dist/plugins/plugin.js.map +1 -0
  102. package/dist/plugins/plugin.test.d.ts +1 -0
  103. package/dist/plugins/plugin.test.js +23 -0
  104. package/dist/plugins/plugin.test.js.map +1 -0
  105. package/dist/reporters/consoleReporter.d.ts +15 -0
  106. package/dist/reporters/consoleReporter.js +73 -0
  107. package/dist/reporters/consoleReporter.js.map +1 -0
  108. package/dist/reporters/consoleReporter.test.d.ts +1 -0
  109. package/dist/reporters/consoleReporter.test.js +155 -0
  110. package/dist/reporters/consoleReporter.test.js.map +1 -0
  111. package/dist/reporters/enhancedReporter.d.ts +12 -0
  112. package/dist/reporters/enhancedReporter.js +81 -0
  113. package/dist/reporters/enhancedReporter.js.map +1 -0
  114. package/dist/reporters/enhancedReporter.test.d.ts +1 -0
  115. package/dist/reporters/enhancedReporter.test.js +152 -0
  116. package/dist/reporters/enhancedReporter.test.js.map +1 -0
  117. package/dist/reporters/jsonReporter.d.ts +11 -0
  118. package/dist/reporters/jsonReporter.js +20 -0
  119. package/dist/reporters/jsonReporter.js.map +1 -0
  120. package/dist/reporters/jsonReporter.test.d.ts +1 -0
  121. package/dist/reporters/jsonReporter.test.js +31 -0
  122. package/dist/reporters/jsonReporter.test.js.map +1 -0
  123. package/dist/reporters/markdownReporter.d.ts +11 -0
  124. package/dist/reporters/markdownReporter.js +55 -0
  125. package/dist/reporters/markdownReporter.js.map +1 -0
  126. package/dist/reporters/markdownReporter.test.d.ts +1 -0
  127. package/dist/reporters/markdownReporter.test.js +136 -0
  128. package/dist/reporters/markdownReporter.test.js.map +1 -0
  129. package/dist/runner.d.ts +9 -0
  130. package/dist/runner.js +265 -0
  131. package/dist/runner.js.map +1 -0
  132. package/dist/runner.test.d.ts +1 -0
  133. package/dist/runner.test.js +353 -0
  134. package/dist/runner.test.js.map +1 -0
  135. package/dist/scoring/freshnessScorer.d.ts +40 -0
  136. package/dist/scoring/freshnessScorer.js +170 -0
  137. package/dist/scoring/freshnessScorer.js.map +1 -0
  138. package/dist/scoring/freshnessScorer.test.d.ts +1 -0
  139. package/dist/scoring/freshnessScorer.test.js +397 -0
  140. package/dist/scoring/freshnessScorer.test.js.map +1 -0
  141. package/dist/semantic/vectorSearch.d.ts +84 -0
  142. package/dist/semantic/vectorSearch.js +484 -0
  143. package/dist/semantic/vectorSearch.js.map +1 -0
  144. package/dist/semantic/vectorSearch.test.d.ts +1 -0
  145. package/dist/semantic/vectorSearch.test.js +660 -0
  146. package/dist/semantic/vectorSearch.test.js.map +1 -0
  147. package/dist/setupTests.d.ts +4 -0
  148. package/dist/setupTests.js +11 -0
  149. package/dist/setupTests.js.map +1 -0
  150. package/dist/test-utils/console.d.ts +2 -0
  151. package/dist/test-utils/console.js +3 -0
  152. package/dist/test-utils/console.js.map +1 -0
  153. package/dist/test-utils/factories.d.ts +3 -0
  154. package/dist/test-utils/factories.js +25 -0
  155. package/dist/test-utils/factories.js.map +1 -0
  156. package/dist/test-utils/tempFiles.d.ts +1 -0
  157. package/dist/test-utils/tempFiles.js +12 -0
  158. package/dist/test-utils/tempFiles.js.map +1 -0
  159. package/dist/types.d.ts +304 -0
  160. package/dist/types.js +5 -0
  161. package/dist/types.js.map +1 -0
  162. package/dist/utils/boundedMap.d.ts +8 -0
  163. package/dist/utils/boundedMap.js +22 -0
  164. package/dist/utils/boundedMap.js.map +1 -0
  165. package/dist/utils/boundedMap.test.d.ts +1 -0
  166. package/dist/utils/boundedMap.test.js +57 -0
  167. package/dist/utils/boundedMap.test.js.map +1 -0
  168. package/dist/utils/illustrativePatterns.d.ts +28 -0
  169. package/dist/utils/illustrativePatterns.js +80 -0
  170. package/dist/utils/illustrativePatterns.js.map +1 -0
  171. package/dist/utils/illustrativePatterns.test.d.ts +1 -0
  172. package/dist/utils/illustrativePatterns.test.js +48 -0
  173. package/dist/utils/illustrativePatterns.test.js.map +1 -0
  174. package/dist/utils/incremental.d.ts +36 -0
  175. package/dist/utils/incremental.js +87 -0
  176. package/dist/utils/incremental.js.map +1 -0
  177. package/dist/utils/incremental.test.d.ts +1 -0
  178. package/dist/utils/incremental.test.js +84 -0
  179. package/dist/utils/incremental.test.js.map +1 -0
  180. package/dist/utils/parallel.d.ts +14 -0
  181. package/dist/utils/parallel.js +43 -0
  182. package/dist/utils/parallel.js.map +1 -0
  183. package/dist/utils/parallel.test.d.ts +1 -0
  184. package/dist/utils/parallel.test.js +48 -0
  185. package/dist/utils/parallel.test.js.map +1 -0
  186. package/dist/utils/pathSecurity.d.ts +12 -0
  187. package/dist/utils/pathSecurity.js +22 -0
  188. package/dist/utils/pathSecurity.js.map +1 -0
  189. package/dist/utils/pathSecurity.test.d.ts +1 -0
  190. package/dist/utils/pathSecurity.test.js +34 -0
  191. package/dist/utils/pathSecurity.test.js.map +1 -0
  192. package/dist/utils/similarity.d.ts +12 -0
  193. package/dist/utils/similarity.js +64 -0
  194. package/dist/utils/similarity.js.map +1 -0
  195. package/dist/utils/similarity.test.d.ts +1 -0
  196. package/dist/utils/similarity.test.js +49 -0
  197. package/dist/utils/similarity.test.js.map +1 -0
  198. package/dist/utils/validation.d.ts +13 -0
  199. package/dist/utils/validation.js +24 -0
  200. package/dist/utils/validation.js.map +1 -0
  201. package/dist/utils/validation.test.d.ts +1 -0
  202. package/dist/utils/validation.test.js +28 -0
  203. package/dist/utils/validation.test.js.map +1 -0
  204. package/dist/validators/codePatternValidator.d.ts +28 -0
  205. package/dist/validators/codePatternValidator.js +200 -0
  206. package/dist/validators/codePatternValidator.js.map +1 -0
  207. package/dist/validators/codePatternValidator.test.d.ts +1 -0
  208. package/dist/validators/codePatternValidator.test.js +86 -0
  209. package/dist/validators/codePatternValidator.test.js.map +1 -0
  210. package/dist/validators/dependencyValidator.d.ts +12 -0
  211. package/dist/validators/dependencyValidator.js +102 -0
  212. package/dist/validators/dependencyValidator.js.map +1 -0
  213. package/dist/validators/dependencyValidator.test.d.ts +1 -0
  214. package/dist/validators/dependencyValidator.test.js +179 -0
  215. package/dist/validators/dependencyValidator.test.js.map +1 -0
  216. package/dist/validators/directoryValidator.d.ts +30 -0
  217. package/dist/validators/directoryValidator.js +192 -0
  218. package/dist/validators/directoryValidator.js.map +1 -0
  219. package/dist/validators/directoryValidator.test.d.ts +1 -0
  220. package/dist/validators/directoryValidator.test.js +193 -0
  221. package/dist/validators/directoryValidator.test.js.map +1 -0
  222. package/dist/validators/fileValidator.d.ts +16 -0
  223. package/dist/validators/fileValidator.js +114 -0
  224. package/dist/validators/fileValidator.js.map +1 -0
  225. package/dist/validators/fileValidator.test.d.ts +1 -0
  226. package/dist/validators/fileValidator.test.js +108 -0
  227. package/dist/validators/fileValidator.test.js.map +1 -0
  228. package/dist/validators/urlValidator.d.ts +25 -0
  229. package/dist/validators/urlValidator.js +320 -0
  230. package/dist/validators/urlValidator.js.map +1 -0
  231. package/dist/validators/urlValidator.test.d.ts +1 -0
  232. package/dist/validators/urlValidator.test.js +252 -0
  233. package/dist/validators/urlValidator.test.js.map +1 -0
  234. package/dist/validators/validationEngine.d.ts +23 -0
  235. package/dist/validators/validationEngine.js +117 -0
  236. package/dist/validators/validationEngine.js.map +1 -0
  237. package/dist/validators/validationEngine.test.d.ts +1 -0
  238. package/dist/validators/validationEngine.test.js +82 -0
  239. package/dist/validators/validationEngine.test.js.map +1 -0
  240. package/dist/validators/versionValidator.d.ts +18 -0
  241. package/dist/validators/versionValidator.js +211 -0
  242. package/dist/validators/versionValidator.js.map +1 -0
  243. package/dist/validators/versionValidator.test.d.ts +1 -0
  244. package/dist/validators/versionValidator.test.js +308 -0
  245. package/dist/validators/versionValidator.test.js.map +1 -0
  246. package/package.json +98 -0
@@ -0,0 +1,250 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import crypto from 'crypto';
4
+ import { pathToFileURL } from 'url';
5
+ import { createRequire } from 'module';
6
+ import { DEFAULT_CONFIG } from './defaults.js';
7
+ export { DEFAULT_CONFIG };
8
+ // Create a require function for loading CJS modules
9
+ const require = createRequire(import.meta.url);
10
+ const MANIFEST_CANDIDATES = ['package.json', 'requirements.txt', 'pyproject.toml', 'go.mod', 'Cargo.toml', 'pom.xml', 'build.gradle'];
11
+ const SOURCE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.py', '.go', '.rs', '.java'];
12
+ const SOURCE_GLOB = `**/*.{${SOURCE_EXTENSIONS.map((ext) => ext.slice(1)).join(',')}}`;
13
+ const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', 'coverage', '.next', '.nuxt', '__pycache__', 'vendor', 'target']);
14
+ /**
15
+ * Load and merge configuration
16
+ */
17
+ export async function loadConfig(configPath) {
18
+ const configFile = configPath || findConfigFile();
19
+ if (!configFile) {
20
+ // Note: We can't check verbose here as config isn't loaded yet
21
+ // This message will only show in verbose mode from the runner
22
+ return await autoDetectConfig({ ...DEFAULT_CONFIG, _noConfigFile: true });
23
+ }
24
+ const fullPath = path.resolve(process.cwd(), configFile);
25
+ const extension = path.extname(configFile).toLowerCase();
26
+ try {
27
+ let userConfig;
28
+ if (extension === '.json') {
29
+ const content = await fs.promises.readFile(fullPath, 'utf-8');
30
+ userConfig = JSON.parse(content);
31
+ }
32
+ else if (extension === '.cjs') {
33
+ userConfig = loadCjsConfig(fullPath);
34
+ }
35
+ else {
36
+ const content = await fs.promises.readFile(fullPath, 'utf-8');
37
+ userConfig = detectModuleType(content, fullPath) ? await loadESMConfig(content, fullPath) : loadCjsConfig(fullPath);
38
+ }
39
+ const merged = mergeConfig(DEFAULT_CONFIG, userConfig);
40
+ merged._configFile = configFile;
41
+ return await autoDetectConfig(merged);
42
+ }
43
+ catch (error) {
44
+ const err = error;
45
+ if (err.code === 'ENOENT' || err.code === 'ERR_MODULE_NOT_FOUND') {
46
+ console.log('Config file not found, using defaults');
47
+ return await autoDetectConfig({ ...DEFAULT_CONFIG, _noConfigFile: true });
48
+ }
49
+ throw error;
50
+ }
51
+ }
52
+ /**
53
+ * Load ESM config file via dynamic import with a temp .mjs file
54
+ * to avoid the Node.js MODULE_TYPELESS_PACKAGE_JSON warning.
55
+ */
56
+ async function loadESMConfig(content, filePath) {
57
+ const transformedContent = transformConfigContent(content);
58
+ const tempDir = path.join(path.dirname(filePath), '.doc-freshness-cache');
59
+ const tempFile = path.join(tempDir, `temp-config-${Date.now()}-${crypto.randomUUID()}.mjs`);
60
+ try {
61
+ await fs.promises.mkdir(tempDir, { recursive: true });
62
+ await fs.promises.writeFile(tempFile, transformedContent, 'utf-8');
63
+ const configUrl = pathToFileURL(tempFile).href;
64
+ const module = await import(configUrl);
65
+ return module.default || module;
66
+ }
67
+ finally {
68
+ await fs.promises.unlink(tempFile).catch(() => { });
69
+ }
70
+ }
71
+ /**
72
+ * Transform config content to handle doc-freshness-checker imports
73
+ * Replaces the import with a local defineConfig function
74
+ */
75
+ function transformConfigContent(content) {
76
+ // Replace import from doc-freshness-checker with local defineConfig
77
+ const importPattern = /import\s*\{\s*defineConfig\s*\}\s*from\s*['"]doc-freshness-checker['"]\s*;?/g;
78
+ return content.replace(importPattern, 'const defineConfig = (config) => config;');
79
+ }
80
+ /**
81
+ * Detect if file content is ESM or CommonJS
82
+ * Returns true for ESM, false for CommonJS
83
+ */
84
+ function detectModuleType(content, filePath) {
85
+ // Check file extension first
86
+ if (filePath.endsWith('.mjs'))
87
+ return true;
88
+ if (filePath.endsWith('.cjs'))
89
+ return false;
90
+ // Check for ESM syntax indicators
91
+ const esmPatterns = [
92
+ /^\s*export\s+default\s/m, // export default
93
+ /^\s*export\s+\{/m, // export { ... }
94
+ /^\s*export\s+(const|let|var|function|class)\s/m, // export const/let/var/function/class
95
+ /^\s*import\s+.*\s+from\s+['"].*['"]/m, // import ... from '...'
96
+ /^\s*import\s+['"].*['"]/m, // import '...'
97
+ ];
98
+ // Check for CommonJS syntax indicators
99
+ const cjsPatterns = [
100
+ /\bmodule\.exports\s*=/, // module.exports =
101
+ /\bexports\.\w+\s*=/, // exports.foo =
102
+ /\brequire\s*\(\s*['"].*['"]\s*\)/, // require('...')
103
+ ];
104
+ const hasESM = esmPatterns.some((pattern) => pattern.test(content));
105
+ const hasCJS = cjsPatterns.some((pattern) => pattern.test(content));
106
+ // If file has ESM syntax, treat as ESM
107
+ if (hasESM && !hasCJS)
108
+ return true;
109
+ // If file has CJS syntax, treat as CJS
110
+ if (hasCJS && !hasESM)
111
+ return false;
112
+ // If mixed or unclear, check project's package.json
113
+ try {
114
+ const projectRoot = process.cwd();
115
+ const pkgPath = path.join(projectRoot, 'package.json');
116
+ if (fs.existsSync(pkgPath)) {
117
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
118
+ if (pkg.type === 'module')
119
+ return true;
120
+ }
121
+ }
122
+ catch {
123
+ // Ignore package.json read errors
124
+ }
125
+ // Default to ESM if has ESM syntax, otherwise CJS
126
+ return hasESM;
127
+ }
128
+ /**
129
+ * Find configuration file in common locations
130
+ */
131
+ function findConfigFile() {
132
+ const candidates = ['.doc-freshness.config.js', '.doc-freshness.config.json', 'doc-freshness.config.js', 'doc-freshness.config.json'];
133
+ for (const candidate of candidates) {
134
+ if (fs.existsSync(path.resolve(process.cwd(), candidate))) {
135
+ return candidate;
136
+ }
137
+ }
138
+ return null;
139
+ }
140
+ /**
141
+ * Auto-detect project configuration based on files present
142
+ */
143
+ async function autoDetectConfig(config) {
144
+ config.rootDir = config.rootDir || process.cwd();
145
+ // Auto-detect manifest files if not specified
146
+ if (!config.manifestFiles) {
147
+ config.manifestFiles = detectManifestFiles(config.rootDir);
148
+ }
149
+ // Auto-detect source patterns if not specified
150
+ if (!config.sourcePatterns) {
151
+ config.sourcePatterns = detectSourcePatterns(config.rootDir);
152
+ }
153
+ return config;
154
+ }
155
+ /**
156
+ * Detect manifest files present in the project
157
+ */
158
+ function detectManifestFiles(rootDir) {
159
+ return MANIFEST_CANDIDATES.filter((f) => fs.existsSync(path.join(rootDir, f)));
160
+ }
161
+ /**
162
+ * Detect source code patterns based on project structure
163
+ * Dynamically scans the project to find directories containing source code
164
+ */
165
+ function detectSourcePatterns(rootDir) {
166
+ const patterns = [];
167
+ try {
168
+ const entries = fs.readdirSync(rootDir, { withFileTypes: true });
169
+ for (const entry of entries) {
170
+ if (!entry.isDirectory())
171
+ continue;
172
+ // Skip common non-source directories
173
+ if (SKIP_DIRS.has(entry.name) || entry.name.startsWith('.'))
174
+ continue;
175
+ const dirPath = path.join(rootDir, entry.name);
176
+ if (containsSourceFiles(dirPath, SOURCE_EXTENSIONS)) {
177
+ const srcPath = path.join(dirPath, 'src');
178
+ const pattern = fs.existsSync(srcPath) && containsSourceFiles(srcPath, SOURCE_EXTENSIONS)
179
+ ? `${entry.name}/src/${SOURCE_GLOB}`
180
+ : `${entry.name}/${SOURCE_GLOB}`;
181
+ patterns.push(pattern);
182
+ }
183
+ }
184
+ }
185
+ catch {
186
+ // Fallback if directory reading fails
187
+ }
188
+ // Fallback to broad pattern if nothing found
189
+ if (patterns.length === 0) {
190
+ patterns.push(SOURCE_GLOB);
191
+ }
192
+ return patterns;
193
+ }
194
+ /**
195
+ * Check if a directory contains source files (non-recursively, just top level or one level deep)
196
+ */
197
+ function containsSourceFiles(dirPath, extensions) {
198
+ const isSourceExt = (name) => extensions.includes(path.extname(name).toLowerCase());
199
+ try {
200
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
201
+ for (const entry of entries) {
202
+ if (entry.isFile() && isSourceExt(entry.name))
203
+ return true;
204
+ if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
205
+ // Check one level deep
206
+ const subPath = path.join(dirPath, entry.name);
207
+ try {
208
+ if (fs.readdirSync(subPath).some(isSourceExt))
209
+ return true;
210
+ }
211
+ catch {
212
+ // Skip unreadable subdirectory
213
+ }
214
+ }
215
+ }
216
+ }
217
+ catch {
218
+ // Directory not readable
219
+ }
220
+ return false;
221
+ }
222
+ /**
223
+ * Deep merge user config with defaults
224
+ */
225
+ function mergeConfig(defaults, user) {
226
+ const result = { ...defaults };
227
+ for (const key of Object.keys(user)) {
228
+ const userValue = user[key];
229
+ const defaultValue = defaults[key];
230
+ if (userValue === undefined)
231
+ continue;
232
+ if (typeof userValue === 'object' &&
233
+ userValue !== null &&
234
+ !Array.isArray(userValue) &&
235
+ typeof defaultValue === 'object' &&
236
+ defaultValue !== null) {
237
+ result[key] = mergeConfig(defaultValue, userValue);
238
+ }
239
+ else {
240
+ result[key] = userValue;
241
+ }
242
+ }
243
+ return result;
244
+ }
245
+ function loadCjsConfig(fullPath) {
246
+ const resolvedPath = require.resolve(fullPath);
247
+ delete require.cache[resolvedPath];
248
+ return require(resolvedPath);
249
+ }
250
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,oDAAoD;AACpD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,mBAAmB,GAAG,CAAC,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;AAEtI,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AACvF,MAAM,WAAW,GAAG,SAAS,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AACvF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEtI;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAmB;IAClD,MAAM,UAAU,GAAG,UAAU,IAAI,cAAc,EAAE,CAAC;IAElD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,+DAA+D;QAC/D,8DAA8D;QAC9D,OAAO,MAAM,gBAAgB,CAAC,EAAE,GAAG,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IAEzD,IAAI,CAAC;QACH,IAAI,UAA8B,CAAC;QAEnC,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9D,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YAChC,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9D,UAAU,GAAG,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACtH,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QACvD,MAAM,CAAC,WAAW,GAAG,UAAU,CAAC;QAChC,OAAO,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAA8B,CAAC;QAC3C,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;YACjE,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;YACrD,OAAO,MAAM,gBAAgB,CAAC,EAAE,GAAG,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,QAAgB;IAC5D,MAAM,kBAAkB,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAE3D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,sBAAsB,CAAC,CAAC;IAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,IAAI,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAE5F,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;QAEnE,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;QAC/C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAEvC,OAAO,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC;IAClC,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,sBAAsB,CAAC,OAAe;IAC7C,oEAAoE;IACpE,MAAM,aAAa,GAAG,8EAA8E,CAAC;IAErG,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,0CAA0C,CAAC,CAAC;AACpF,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,OAAe,EAAE,QAAgB;IACzD,6BAA6B;IAC7B,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5C,kCAAkC;IAClC,MAAM,WAAW,GAAG;QAClB,yBAAyB,EAAE,iBAAiB;QAC5C,kBAAkB,EAAE,iBAAiB;QACrC,gDAAgD,EAAE,sCAAsC;QACxF,sCAAsC,EAAE,wBAAwB;QAChE,0BAA0B,EAAE,eAAe;KAC5C,CAAC;IAEF,uCAAuC;IACvC,MAAM,WAAW,GAAG;QAClB,uBAAuB,EAAE,mBAAmB;QAC5C,oBAAoB,EAAE,gBAAgB;QACtC,kCAAkC,EAAE,iBAAiB;KACtD,CAAC;IAEF,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAEpE,uCAAuC;IACvC,IAAI,MAAM,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEnC,uCAAuC;IACvC,IAAI,MAAM,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAEpC,oDAAoD;IACpD,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QACvD,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YAC1D,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;QACzC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;IAED,kDAAkD;IAClD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc;IACrB,MAAM,UAAU,GAAG,CAAC,0BAA0B,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,2BAA2B,CAAC,CAAC;IAEtI,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;YAC1D,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAAC,MAA0B;IACxD,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAEjD,8CAA8C;IAC9C,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;QAC1B,MAAM,CAAC,aAAa,GAAG,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED,+CAA+C;IAC/C,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAC3B,MAAM,CAAC,cAAc,GAAG,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,OAAe;IAC1C,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACjF,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,OAAe;IAC3C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAEjE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBAAE,SAAS;YAEnC,qCAAqC;YACrC,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAEtE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAE/C,IAAI,mBAAmB,CAAC,OAAO,EAAE,iBAAiB,CAAC,EAAE,CAAC;gBACpD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAC1C,MAAM,OAAO,GACX,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,mBAAmB,CAAC,OAAO,EAAE,iBAAiB,CAAC;oBACvE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,QAAQ,WAAW,EAAE;oBACpC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC;gBACrC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sCAAsC;IACxC,CAAC;IAED,6CAA6C;IAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,OAAe,EAAE,UAAoB;IAChE,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAE5F,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAEjE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;YAE3D,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBACxF,uBAAuB;gBACvB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC/C,IAAI,CAAC;oBACH,IAAI,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;wBAAE,OAAO,IAAI,CAAC;gBAC7D,CAAC;gBAAC,MAAM,CAAC;oBACP,+BAA+B;gBACjC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;IAC3B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,QAA4B,EAAE,IAAwB;IACzE,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAA6B,CAAC;IAE1D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,SAAS,GAAI,IAAgC,CAAC,GAAG,CAAC,CAAC;QACzD,MAAM,YAAY,GAAI,QAAoC,CAAC,GAAG,CAAC,CAAC;QAEhE,IAAI,SAAS,KAAK,SAAS;YAAE,SAAS;QAEtC,IACE,OAAO,SAAS,KAAK,QAAQ;YAC7B,SAAS,KAAK,IAAI;YAClB,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;YACzB,OAAO,YAAY,KAAK,QAAQ;YAChC,YAAY,KAAK,IAAI,EACrB,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,YAAkC,EAAE,SAA+B,CAAC,CAAC;QACjG,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,MAA4B,CAAC;AACtC,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,OAAO,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACnC,OAAO,OAAO,CAAC,YAAY,CAAuB,CAAC;AACrD,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,276 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { loadConfig, DEFAULT_CONFIG } from './loader.js';
4
+ describe('DEFAULT_CONFIG', () => {
5
+ it('has sensible default values', () => {
6
+ expect(DEFAULT_CONFIG.include).toEqual(['docs/**/*.md', 'README.md']);
7
+ expect(DEFAULT_CONFIG.exclude).toContain('**/node_modules/**');
8
+ expect(DEFAULT_CONFIG.urlValidation?.enabled).toBe(true);
9
+ expect(DEFAULT_CONFIG.urlValidation?.timeout).toBe(10000);
10
+ expect(DEFAULT_CONFIG.rules?.['file-path']?.enabled).toBe(true);
11
+ expect(DEFAULT_CONFIG.reporters).toEqual(['console']);
12
+ expect(DEFAULT_CONFIG.verbose).toBe(false);
13
+ });
14
+ });
15
+ describe('loadConfig', () => {
16
+ const tmpDir = path.join(process.cwd(), '.doc-freshness-cache', 'config-test');
17
+ const unlinkIfExists = async (filePath) => {
18
+ await fs.promises.unlink(filePath).catch(() => { });
19
+ };
20
+ async function withTempConfig(fileName, content, assertConfig) {
21
+ const configPath = path.join(tmpDir, fileName);
22
+ const serialized = typeof content === 'string' ? content : JSON.stringify(content);
23
+ await fs.promises.writeFile(configPath, serialized);
24
+ try {
25
+ await assertConfig(configPath);
26
+ }
27
+ finally {
28
+ await unlinkIfExists(configPath);
29
+ }
30
+ }
31
+ beforeAll(async () => {
32
+ await fs.promises.mkdir(tmpDir, { recursive: true });
33
+ });
34
+ afterAll(async () => {
35
+ await fs.promises.rm(tmpDir, { recursive: true, force: true }).catch(() => { });
36
+ });
37
+ it('returns defaults with auto-detection when no config file exists', async () => {
38
+ const config = await loadConfig('/nonexistent/path.json');
39
+ expect(config.include).toEqual(DEFAULT_CONFIG.include);
40
+ expect(config._noConfigFile).toBe(true);
41
+ });
42
+ it('loads JSON config file and merges with defaults', async () => {
43
+ await withTempConfig('test-config.json', { verbose: true, include: ['**/*.md'] }, async (tmpConfig) => {
44
+ const config = await loadConfig(tmpConfig);
45
+ expect(config.verbose).toBe(true);
46
+ expect(config.include).toEqual(['**/*.md']);
47
+ expect(config.urlValidation?.enabled).toBe(true);
48
+ expect(config._configFile).toBeDefined();
49
+ });
50
+ });
51
+ it('deep-merges nested config objects', async () => {
52
+ await withTempConfig('merge-config.json', {
53
+ urlValidation: { timeout: 5000 },
54
+ }, async (tmpConfig) => {
55
+ const config = await loadConfig(tmpConfig);
56
+ expect(config.urlValidation?.timeout).toBe(5000);
57
+ expect(config.urlValidation?.enabled).toBe(true);
58
+ });
59
+ });
60
+ it('auto-detects manifest files', async () => {
61
+ const config = await loadConfig();
62
+ expect(config.manifestFiles).toBeDefined();
63
+ expect(Array.isArray(config.manifestFiles)).toBe(true);
64
+ if (fs.existsSync(path.join(process.cwd(), 'package.json'))) {
65
+ expect(config.manifestFiles).toContain('package.json');
66
+ }
67
+ });
68
+ it('auto-detects source patterns', async () => {
69
+ const config = await loadConfig();
70
+ expect(config.sourcePatterns).toBeDefined();
71
+ expect(Array.isArray(config.sourcePatterns)).toBe(true);
72
+ expect(config.sourcePatterns.length).toBeGreaterThan(0);
73
+ });
74
+ it('preserves user-provided manifestFiles and sourcePatterns', async () => {
75
+ await withTempConfig('custom-patterns.json', {
76
+ manifestFiles: ['custom-manifest.json'],
77
+ sourcePatterns: ['custom/**/*.ts'],
78
+ }, async (tmpConfig) => {
79
+ const config = await loadConfig(tmpConfig);
80
+ expect(config.manifestFiles).toEqual(['custom-manifest.json']);
81
+ expect(config.sourcePatterns).toEqual(['custom/**/*.ts']);
82
+ });
83
+ });
84
+ it('loads .cjs config file', async () => {
85
+ await withTempConfig('test-config.cjs', 'module.exports = { verbose: true, include: ["**/*.md"] };', async (tmpConfig) => {
86
+ const config = await loadConfig(tmpConfig);
87
+ expect(config.verbose).toBe(true);
88
+ });
89
+ });
90
+ it('handles config file with ESM syntax (export default)', async () => {
91
+ await withTempConfig('test-esm.js', 'export default { verbose: true, include: ["**/*.md"] };', async (tmpConfig) => {
92
+ const config = await loadConfig(tmpConfig);
93
+ expect(config.verbose).toBe(true);
94
+ });
95
+ });
96
+ it('handles config file importing defineConfig', async () => {
97
+ await withTempConfig('test-define.js', `import { defineConfig } from 'doc-freshness-checker';\nexport default defineConfig({ verbose: true });`, async (tmpConfig) => {
98
+ const config = await loadConfig(tmpConfig);
99
+ expect(config.verbose).toBe(true);
100
+ });
101
+ });
102
+ it('returns defaults when config file throws non-ENOENT error', async () => {
103
+ await withTempConfig('bad-config.json', 'not valid json!!!', async (tmpConfig) => {
104
+ await expect(loadConfig(tmpConfig)).rejects.toThrow();
105
+ });
106
+ });
107
+ it('loads .mjs config as ESM', async () => {
108
+ await withTempConfig('test.mjs', 'export default { verbose: true };', async (tmpConfig) => {
109
+ const config = await loadConfig(tmpConfig);
110
+ expect(config.verbose).toBe(true);
111
+ });
112
+ });
113
+ it('detects ESM from export const pattern', async () => {
114
+ await withTempConfig('esm-export-const.js', 'export const config = { verbose: true };\nexport default config;', async (tmpConfig) => {
115
+ const config = await loadConfig(tmpConfig);
116
+ expect(config.verbose).toBe(true);
117
+ });
118
+ });
119
+ it('detects ESM from import ... from pattern', async () => {
120
+ await withTempConfig('esm-import.js', 'import path from "path";\nexport default { verbose: true };', async (tmpConfig) => {
121
+ const config = await loadConfig(tmpConfig);
122
+ expect(config.verbose).toBe(true);
123
+ });
124
+ });
125
+ it('detects ESM from export { ... } pattern', async () => {
126
+ await withTempConfig('esm-export-named.js', 'const config = { verbose: true };\nexport { config };\nexport default config;', async (tmpConfig) => {
127
+ const config = await loadConfig(tmpConfig);
128
+ expect(config.verbose).toBe(true);
129
+ });
130
+ });
131
+ it('detects .cjs extension and loads CJS config directly', async () => {
132
+ await withTempConfig('direct-cjs.cjs', 'module.exports = { verbose: true, include: ["**/*.md"] };', async (tmpConfig) => {
133
+ const config = await loadConfig(tmpConfig);
134
+ expect(config.verbose).toBe(true);
135
+ });
136
+ });
137
+ it('merges arrays from user config (overrides, not deep merge)', async () => {
138
+ await withTempConfig('array-merge.json', {
139
+ include: ['custom/**/*.md'],
140
+ exclude: ['draft/**'],
141
+ }, async (tmpConfig) => {
142
+ const config = await loadConfig(tmpConfig);
143
+ expect(config.include).toEqual(['custom/**/*.md']);
144
+ expect(config.exclude).toEqual(['draft/**']);
145
+ });
146
+ });
147
+ it('skips undefined user config values during merge', async () => {
148
+ await withTempConfig('undefined-vals.json', { verbose: true }, async (tmpConfig) => {
149
+ const config = await loadConfig(tmpConfig);
150
+ expect(config.verbose).toBe(true);
151
+ expect(config.include).toEqual(DEFAULT_CONFIG.include);
152
+ });
153
+ });
154
+ it('handles ENOENT (module not found) error code', async () => {
155
+ const config = await loadConfig('/nonexistent/deep/path/config.json');
156
+ expect(config._noConfigFile).toBe(true);
157
+ });
158
+ it('loads config without explicit path, using auto-detection', async () => {
159
+ const config = await loadConfig();
160
+ expect(config).toBeDefined();
161
+ expect(config.rootDir).toBeDefined();
162
+ });
163
+ it('auto-detects source patterns with src subdirectory', async () => {
164
+ const config = await loadConfig();
165
+ expect(config.sourcePatterns).toBeDefined();
166
+ expect(config.sourcePatterns.some((p) => p.includes('src'))).toBe(true);
167
+ });
168
+ it('handles ESM config that exports module instead of default', async () => {
169
+ await withTempConfig('esm-module-export.mjs', 'const config = { verbose: true };\nexport default config;', async (tmpConfig) => {
170
+ const config = await loadConfig(tmpConfig);
171
+ expect(config.verbose).toBe(true);
172
+ });
173
+ });
174
+ it('sets rootDir to process.cwd when not specified', async () => {
175
+ await withTempConfig('no-root.json', { verbose: true }, async (tmpConfig) => {
176
+ const config = await loadConfig(tmpConfig);
177
+ expect(config.rootDir).toBe(process.cwd());
178
+ });
179
+ });
180
+ it('deep-merges nested objects but overwrites null with object values', async () => {
181
+ await withTempConfig('deep-null.json', {
182
+ rules: { 'file-path': { severity: 'error' } },
183
+ urlValidation: null,
184
+ }, async (tmpConfig) => {
185
+ const config = await loadConfig(tmpConfig);
186
+ expect(config.rules?.['file-path']?.severity).toBe('error');
187
+ });
188
+ });
189
+ it('falls back to broad source pattern when rootDir has no source dirs', async () => {
190
+ const emptyDir = path.join(tmpDir, 'empty-root');
191
+ await fs.promises.mkdir(emptyDir, { recursive: true });
192
+ await withTempConfig('empty-root-config.json', { rootDir: emptyDir }, async (tmpConfig) => {
193
+ const config = await loadConfig(tmpConfig);
194
+ expect(config.sourcePatterns).toBeDefined();
195
+ expect(config.sourcePatterns.length).toBeGreaterThan(0);
196
+ });
197
+ });
198
+ it('returns empty manifest list when rootDir has no manifests', async () => {
199
+ const emptyDir = path.join(tmpDir, 'no-manifests');
200
+ await fs.promises.mkdir(emptyDir, { recursive: true });
201
+ await withTempConfig('no-manifests-config.json', { rootDir: emptyDir }, async (tmpConfig) => {
202
+ const config = await loadConfig(tmpConfig);
203
+ expect(config.manifestFiles).toEqual([]);
204
+ });
205
+ });
206
+ it('detects source files in subdirectories', async () => {
207
+ const testDir = path.join(tmpDir, 'with-source');
208
+ const subDir = path.join(testDir, 'mylib');
209
+ await fs.promises.mkdir(subDir, { recursive: true });
210
+ await fs.promises.writeFile(path.join(subDir, 'index.ts'), 'export const x = 1;');
211
+ await withTempConfig('with-source-config.json', { rootDir: testDir }, async (tmpConfig) => {
212
+ const config = await loadConfig(tmpConfig);
213
+ expect(config.sourcePatterns.some((p) => p.includes('mylib'))).toBe(true);
214
+ });
215
+ });
216
+ it('detects source files in nested src subdirectory', async () => {
217
+ const testDir = path.join(tmpDir, 'with-nested-src');
218
+ const srcDir = path.join(testDir, 'app', 'src');
219
+ await fs.promises.mkdir(srcDir, { recursive: true });
220
+ await fs.promises.writeFile(path.join(srcDir, 'main.ts'), 'console.log("hi");');
221
+ await withTempConfig('nested-src-config.json', { rootDir: testDir }, async (tmpConfig) => {
222
+ const config = await loadConfig(tmpConfig);
223
+ expect(config.sourcePatterns.some((p) => p.includes('app/src/'))).toBe(true);
224
+ });
225
+ });
226
+ it('skips hidden and node_modules directories during source detection', async () => {
227
+ const testDir = path.join(tmpDir, 'skip-dirs');
228
+ await fs.promises.mkdir(path.join(testDir, '.hidden'), { recursive: true });
229
+ await fs.promises.mkdir(path.join(testDir, 'node_modules'), { recursive: true });
230
+ await fs.promises.writeFile(path.join(testDir, '.hidden', 'test.ts'), 'const x = 1;');
231
+ await fs.promises.writeFile(path.join(testDir, 'node_modules', 'test.ts'), 'const x = 1;');
232
+ await withTempConfig('skip-dirs-config.json', { rootDir: testDir }, async (tmpConfig) => {
233
+ const config = await loadConfig(tmpConfig);
234
+ expect(config.sourcePatterns.every((p) => !p.includes('.hidden') && !p.includes('node_modules'))).toBe(true);
235
+ });
236
+ });
237
+ it('skips dirs with only non-source files (containsSourceFiles returns false)', async () => {
238
+ const testDir = path.join(tmpDir, 'no-source-files');
239
+ const dataDir = path.join(testDir, 'data');
240
+ await fs.promises.mkdir(dataDir, { recursive: true });
241
+ await fs.promises.writeFile(path.join(dataDir, 'readme.txt'), 'not a source file');
242
+ await fs.promises.writeFile(path.join(dataDir, 'config.yml'), 'key: value');
243
+ await withTempConfig('no-source-config.json', { rootDir: testDir }, async (tmpConfig) => {
244
+ const config = await loadConfig(tmpConfig);
245
+ expect(config.sourcePatterns.every((p) => !p.includes('data/'))).toBe(true);
246
+ });
247
+ });
248
+ it('detects source files one level deep in subdirectory', async () => {
249
+ const testDir = path.join(tmpDir, 'deep-source');
250
+ const libDir = path.join(testDir, 'lib');
251
+ const innerDir = path.join(libDir, 'inner');
252
+ await fs.promises.mkdir(innerDir, { recursive: true });
253
+ await fs.promises.writeFile(path.join(innerDir, 'utils.js'), 'module.exports = {};');
254
+ await withTempConfig('deep-source-config.json', { rootDir: testDir }, async (tmpConfig) => {
255
+ const config = await loadConfig(tmpConfig);
256
+ expect(config.sourcePatterns.some((p) => p.includes('lib'))).toBe(true);
257
+ });
258
+ });
259
+ it('handles mixed ESM+CJS content by checking package.json type', async () => {
260
+ await withTempConfig('mixed-module.js', ['// Legacy: module.exports = config;', 'export default { verbose: true };'].join('\n'), async (tmpConfig) => {
261
+ const config = await loadConfig(tmpConfig);
262
+ expect(config.verbose).toBe(true);
263
+ });
264
+ });
265
+ it('skips non-directory entries during source detection', async () => {
266
+ const testDir = path.join(tmpDir, 'files-only');
267
+ await fs.promises.mkdir(testDir, { recursive: true });
268
+ await fs.promises.writeFile(path.join(testDir, 'standalone.ts'), 'const x = 1;');
269
+ await fs.promises.writeFile(path.join(testDir, 'other.txt'), 'text');
270
+ await withTempConfig('files-only-config.json', { rootDir: testDir }, async (tmpConfig) => {
271
+ const config = await loadConfig(tmpConfig);
272
+ expect(config.sourcePatterns).toBeDefined();
273
+ });
274
+ });
275
+ });
276
+ //# sourceMappingURL=loader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.test.js","sourceRoot":"","sources":["../../src/config/loader.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { ChangeSummaryItem, CommitInfo, DocFreshnessConfig } from '../types.js';
2
+ import type { CodeDocGraph } from '../graph/codeDocGraph.js';
3
+ /**
4
+ * Tracks git changes for incremental documentation checking
5
+ */
6
+ export declare class GitChangeTracker {
7
+ private rootDir;
8
+ private _isGitRepo;
9
+ constructor(config: DocFreshnessConfig);
10
+ private git;
11
+ /**
12
+ * Check if the project is a git repository
13
+ */
14
+ isGitRepo(): boolean;
15
+ /**
16
+ * Get the current git commit hash
17
+ */
18
+ getCurrentCommit(): string | null;
19
+ /**
20
+ * Get files changed between two commits
21
+ */
22
+ getChangedFiles(fromCommit: string, toCommit?: string): string[];
23
+ /**
24
+ * Get files changed since a timestamp
25
+ */
26
+ getChangedFilesSince(timestamp: number): string[];
27
+ /**
28
+ * Get the last modification time of a file from git
29
+ */
30
+ getFileLastModified(filePath: string): number | null;
31
+ /**
32
+ * Get commit info for a file.
33
+ * Uses NUL byte as separator to safely handle commit messages containing |
34
+ */
35
+ getFileCommitInfo(filePath: string): CommitInfo | null;
36
+ /**
37
+ * Determine which docs need re-checking based on code changes
38
+ */
39
+ getAffectedDocs(graph: CodeDocGraph, changedFiles: string[]): string[];
40
+ /**
41
+ * Get change summary for reporting
42
+ */
43
+ getChangeSummary(graph: CodeDocGraph, changedFiles: string[]): ChangeSummaryItem[];
44
+ }