@noyrax/documentation-system-plugin 1.0.4-beta.12 → 1.0.4-beta.14

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@noyrax/documentation-system-plugin",
3
3
  "displayName": "Noyrax",
4
4
  "description": "Documentation that never drifts. Automatic documentation generation with validation and drift detection. Generates 5-dimensional documentation structure (modules, symbols, dependencies, ADRs, changes) for codebases.",
5
- "version": "1.0.4-beta.12",
5
+ "version": "1.0.4-beta.14",
6
6
  "publisher": "noyrax",
7
7
  "repository": {
8
8
  "type": "git",
@@ -154,56 +154,162 @@ function extractClaimsFromAdr(adrPath) {
154
154
  return claims;
155
155
  }
156
156
 
157
+ /**
158
+ * Lädt die Path-Alias-Map aus .database-plugin/path-aliases.json
159
+ */
160
+ function loadAliasMap(workspaceRoot) {
161
+ const aliasMapPath = path.join(workspaceRoot, '.database-plugin', 'path-aliases.json');
162
+ if (fs.existsSync(aliasMapPath)) {
163
+ try {
164
+ const content = fs.readFileSync(aliasMapPath, 'utf-8');
165
+ return JSON.parse(content);
166
+ } catch (error) {
167
+ // Ignore errors loading alias map
168
+ return {};
169
+ }
170
+ }
171
+ return {};
172
+ }
173
+
174
+ /**
175
+ * Resolved einen Pfad mit Hilfe der Alias-Map
176
+ */
177
+ function resolvePathWithAlias(filePath, workspaceRoot, aliasMap) {
178
+ // Normalisiere den Pfad (forward slashes)
179
+ const normalized = filePath.replace(/\\/g, '/');
180
+
181
+ // Prüfe ob es einen Alias gibt
182
+ if (aliasMap[normalized]) {
183
+ return path.join(workspaceRoot, aliasMap[normalized]);
184
+ }
185
+
186
+ // Fallback: Original-Pfad
187
+ return path.join(workspaceRoot, filePath);
188
+ }
189
+
190
+ /**
191
+ * Findet alle src/ Verzeichnisse (und app/ für Next.js) mit Hilfe der Alias-Map
192
+ */
193
+ function findAllSourceDirectories(workspaceRoot, aliasMap) {
194
+ const sourceDirs = [];
195
+
196
+ // Standard: src/ im Workspace-Root
197
+ const standardSrc = path.join(workspaceRoot, 'src');
198
+ if (fs.existsSync(standardSrc)) {
199
+ sourceDirs.push(standardSrc);
200
+ }
201
+
202
+ // Suche in Alias-Map nach src/ Pfaden
203
+ for (const [alias, target] of Object.entries(aliasMap)) {
204
+ if (alias.startsWith('src/') || alias.includes('/src/')) {
205
+ // Extrahiere das Plugin-Root aus dem Target
206
+ const targetParts = target.split('/');
207
+ const srcIndex = targetParts.indexOf('src');
208
+ if (srcIndex > 0) {
209
+ const pluginRoot = targetParts.slice(0, srcIndex).join('/');
210
+ const srcDir = path.join(workspaceRoot, pluginRoot, 'src');
211
+ if (fs.existsSync(srcDir) && !sourceDirs.includes(srcDir)) {
212
+ sourceDirs.push(srcDir);
213
+ }
214
+ }
215
+ }
216
+ }
217
+
218
+ // Suche rekursiv nach src/ Verzeichnissen (max. 2 Ebenen tief)
219
+ try {
220
+ const searchDirs = [
221
+ workspaceRoot,
222
+ ...fs.readdirSync(workspaceRoot, { withFileTypes: true })
223
+ .filter(dirent => dirent.isDirectory() && !dirent.name.startsWith('.') && dirent.name !== 'node_modules')
224
+ .map(dirent => path.join(workspaceRoot, dirent.name))
225
+ ];
226
+
227
+ for (const searchDir of searchDirs) {
228
+ // src/ Verzeichnisse
229
+ const srcDir = path.join(searchDir, 'src');
230
+ if (fs.existsSync(srcDir) && !sourceDirs.includes(srcDir)) {
231
+ sourceDirs.push(srcDir);
232
+ }
233
+
234
+ // app/ Verzeichnisse (Next.js)
235
+ const appDir = path.join(searchDir, 'app');
236
+ if (fs.existsSync(appDir) && !sourceDirs.includes(appDir)) {
237
+ sourceDirs.push(appDir);
238
+ }
239
+ }
240
+ } catch (error) {
241
+ // Ignore errors
242
+ }
243
+
244
+ return sourceDirs.length > 0 ? sourceDirs : null;
245
+ }
246
+
157
247
  /**
158
248
  * Verifiziert einen Claim
159
249
  */
160
250
  function verifyClaim(claim, workspaceRoot) {
251
+ // Lade Alias-Map
252
+ const aliasMap = loadAliasMap(workspaceRoot);
253
+
161
254
  if (claim.type === 'file-exists') {
162
- const fullPath = path.join(workspaceRoot, claim.file);
163
- const exists = fs.existsSync(fullPath);
255
+ // Versuche zuerst mit Alias-Map
256
+ const resolvedPath = resolvePathWithAlias(claim.file, workspaceRoot, aliasMap);
257
+ const exists = fs.existsSync(resolvedPath);
164
258
 
165
259
  if (!exists) {
166
- // Prüfe ob es als .js in out/ existiert (kompilierte Version)
167
- const jsPath = fullPath.replace(/^src\//, 'out/').replace(/\.ts$/, '.js');
168
- const jsExists = fs.existsSync(path.join(workspaceRoot, jsPath));
260
+ // Fallback: Original-Pfad
261
+ const fullPath = path.join(workspaceRoot, claim.file);
262
+ const existsOriginal = fs.existsSync(fullPath);
169
263
 
170
- if (jsExists) {
171
- warnings.push({
264
+ if (!existsOriginal) {
265
+ // Prüfe ob es als .js in out/ existiert (kompilierte Version)
266
+ const jsPath = fullPath.replace(/^src\//, 'out/').replace(/\.ts$/, '.js');
267
+ const jsExists = fs.existsSync(path.join(workspaceRoot, jsPath));
268
+
269
+ if (jsExists) {
270
+ warnings.push({
271
+ adr: claim.adr,
272
+ line: claim.line,
273
+ claim: `File ${claim.file} exists as compiled ${jsPath}, but source not found`,
274
+ type: 'file-exists'
275
+ });
276
+ return true; // Akzeptabel
277
+ }
278
+
279
+ errors.push({
172
280
  adr: claim.adr,
173
281
  line: claim.line,
174
- claim: `File ${claim.file} exists as compiled ${jsPath}, but source not found`,
282
+ claim: `File ${claim.file} does not exist`,
175
283
  type: 'file-exists'
176
284
  });
177
- return true; // Akzeptabel
285
+ return false;
178
286
  }
179
-
180
- errors.push({
181
- adr: claim.adr,
182
- line: claim.line,
183
- claim: `File ${claim.file} does not exist`,
184
- type: 'file-exists'
185
- });
186
- return false;
187
287
  }
188
288
  return true;
189
289
  }
190
290
 
191
291
  if (claim.type === 'function-exists') {
192
292
  try {
193
- // Windows-optimierte Suche mit PowerShell
194
- const srcDir = path.join(workspaceRoot, 'src');
195
- if (!fs.existsSync(srcDir)) {
293
+ // Finde alle src/ und app/ Verzeichnisse mit Hilfe der Alias-Map
294
+ const sourceDirs = findAllSourceDirectories(workspaceRoot, aliasMap);
295
+ if (!sourceDirs || sourceDirs.length === 0) {
196
296
  warnings.push({
197
297
  adr: claim.adr,
198
298
  line: claim.line,
199
- claim: `Could not verify function ${claim.name} (src/ directory not found)`,
299
+ claim: `Could not verify function ${claim.name} (src/ or app/ directory not found)`,
200
300
  type: 'function-exists'
201
301
  });
202
302
  return true;
203
303
  }
204
304
 
205
- // Rekursive Suche in TypeScript-Dateien
206
- const found = searchInDirectory(srcDir, claim.name);
305
+ // Rekursive Suche in allen TypeScript-Dateien (src/ und app/)
306
+ let found = false;
307
+ for (const srcDir of sourceDirs) {
308
+ if (searchInDirectory(srcDir, claim.name)) {
309
+ found = true;
310
+ break;
311
+ }
312
+ }
207
313
 
208
314
  if (!found) {
209
315
  if (claim.explicit || claim.autoGenerated) {
@@ -16,6 +16,39 @@ const { execSync } = require('child_process');
16
16
  const errors = [];
17
17
  const warnings = [];
18
18
 
19
+ /**
20
+ * Lädt die Path-Alias-Map aus .database-plugin/path-aliases.json
21
+ */
22
+ function loadAliasMap(workspaceRoot) {
23
+ const aliasMapPath = path.join(workspaceRoot, '.database-plugin', 'path-aliases.json');
24
+ if (fs.existsSync(aliasMapPath)) {
25
+ try {
26
+ const content = fs.readFileSync(aliasMapPath, 'utf-8');
27
+ return JSON.parse(content);
28
+ } catch (error) {
29
+ // Ignore errors loading alias map
30
+ return {};
31
+ }
32
+ }
33
+ return {};
34
+ }
35
+
36
+ /**
37
+ * Resolved einen Pfad mit Hilfe der Alias-Map
38
+ */
39
+ function resolvePathWithAlias(filePath, workspaceRoot, aliasMap) {
40
+ // Normalisiere den Pfad (forward slashes)
41
+ const normalized = filePath.replace(/\\/g, '/');
42
+
43
+ // Prüfe ob es einen Alias gibt
44
+ if (aliasMap[normalized]) {
45
+ return path.join(workspaceRoot, aliasMap[normalized]);
46
+ }
47
+
48
+ // Fallback: Original-Pfad
49
+ return path.join(workspaceRoot, filePath);
50
+ }
51
+
19
52
  /**
20
53
  * Findet ein Verzeichnis durch intelligente Suche.
21
54
  * Sucht im gegebenen Verzeichnis und in Parent-Verzeichnissen (max. 5 Ebenen).
@@ -55,8 +88,25 @@ function findDirectoryOrFile(startDir, targetPath, maxDepth = 5) {
55
88
  function checkMcpToSrcImports(workspaceRoot) {
56
89
  console.log('🔍 Checking for invalid imports from mcp/ to src/...');
57
90
 
91
+ // Lade Alias-Map
92
+ const aliasMap = loadAliasMap(workspaceRoot);
93
+
58
94
  // Suche mcp/src relativ zu workspaceRoot
59
95
  let mcpSrcDir = findDirectoryOrFile(workspaceRoot, 'mcp/src');
96
+ if (!mcpSrcDir) {
97
+ // Versuche mit Alias-Map
98
+ const aliasKeys = Object.keys(aliasMap);
99
+ for (const alias of aliasKeys) {
100
+ if (alias.includes('mcp/src') || alias.includes('/mcp/src')) {
101
+ const resolved = resolvePathWithAlias(alias, workspaceRoot, aliasMap);
102
+ if (fs.existsSync(resolved)) {
103
+ mcpSrcDir = resolved;
104
+ break;
105
+ }
106
+ }
107
+ }
108
+ }
109
+
60
110
  if (!mcpSrcDir) {
61
111
  // Fallback: Versuche __dirname + '/..' (Plugin-interne Suche)
62
112
  const fallbackRoot = path.join(__dirname, '..');
@@ -15,6 +15,69 @@ const { execSync } = require('child_process');
15
15
  const errors = [];
16
16
  const warnings = [];
17
17
 
18
+ /**
19
+ * Lädt die Path-Alias-Map aus .database-plugin/path-aliases.json
20
+ */
21
+ function loadAliasMap(workspaceRoot) {
22
+ const aliasMapPath = path.join(workspaceRoot, '.database-plugin', 'path-aliases.json');
23
+ if (fs.existsSync(aliasMapPath)) {
24
+ try {
25
+ const content = fs.readFileSync(aliasMapPath, 'utf-8');
26
+ return JSON.parse(content);
27
+ } catch (error) {
28
+ // Ignore errors loading alias map
29
+ return {};
30
+ }
31
+ }
32
+ return {};
33
+ }
34
+
35
+ /**
36
+ * Resolved einen Pfad mit Hilfe der Alias-Map
37
+ */
38
+ function resolvePathWithAlias(filePath, workspaceRoot, aliasMap) {
39
+ // Normalisiere den Pfad (forward slashes)
40
+ const normalized = filePath.replace(/\\/g, '/');
41
+
42
+ // Prüfe ob es einen Alias gibt
43
+ if (aliasMap[normalized]) {
44
+ return path.join(workspaceRoot, aliasMap[normalized]);
45
+ }
46
+
47
+ // Fallback: Original-Pfad
48
+ return path.join(workspaceRoot, filePath);
49
+ }
50
+
51
+ /**
52
+ * Findet src/ Verzeichnis mit Hilfe der Alias-Map
53
+ */
54
+ function findSrcDirectoryWithAlias(startDir, workspaceRoot, aliasMap, maxDepth = 5) {
55
+ // Standard: src/ im Workspace-Root
56
+ const standardSrc = path.join(workspaceRoot, 'src');
57
+ if (fs.existsSync(standardSrc)) {
58
+ return standardSrc;
59
+ }
60
+
61
+ // Suche in Alias-Map nach src/ Pfaden
62
+ for (const [alias, target] of Object.entries(aliasMap)) {
63
+ if (alias.startsWith('src/') || alias.includes('/src/')) {
64
+ // Extrahiere das Plugin-Root aus dem Target
65
+ const targetParts = target.split('/');
66
+ const srcIndex = targetParts.indexOf('src');
67
+ if (srcIndex > 0) {
68
+ const pluginRoot = targetParts.slice(0, srcIndex).join('/');
69
+ const srcDir = path.join(workspaceRoot, pluginRoot, 'src');
70
+ if (fs.existsSync(srcDir)) {
71
+ return srcDir;
72
+ }
73
+ }
74
+ }
75
+ }
76
+
77
+ // Fallback: Original findSrcDirectory
78
+ return findSrcDirectory(startDir, maxDepth);
79
+ }
80
+
18
81
  /**
19
82
  * Sammelt alle TypeScript-Dateien rekursiv
20
83
  */
@@ -126,7 +189,7 @@ function findSrcDirectory(startDir, maxDepth = 5) {
126
189
  /**
127
190
  * Prüft ob ein Import verfügbar ist
128
191
  */
129
- function checkImport(importPath, importedName, fromFile, workspaceRoot) {
192
+ function checkImport(importPath, importedName, fromFile, workspaceRoot, aliasMap) {
130
193
 
131
194
  // Resolve import path
132
195
  let targetFile;
@@ -148,6 +211,14 @@ function checkImport(importPath, importedName, fromFile, workspaceRoot) {
148
211
  targetFile = path.join(targetFile, 'index.js');
149
212
  }
150
213
  }
214
+
215
+ // Versuche mit Alias-Map, wenn Datei nicht gefunden wurde
216
+ if (!fs.existsSync(targetFile) && aliasMap) {
217
+ const relativePath = path.relative(workspaceRoot, targetFile).replace(/\\/g, '/');
218
+ if (aliasMap[relativePath]) {
219
+ targetFile = path.join(workspaceRoot, aliasMap[relativePath]);
220
+ }
221
+ }
151
222
  } else {
152
223
  // Node module import - skip for now
153
224
  return true;
@@ -187,7 +258,7 @@ function checkImport(importPath, importedName, fromFile, workspaceRoot) {
187
258
  /**
188
259
  * Prüft alle Imports in einer Datei
189
260
  */
190
- function checkFileImports(filePath, workspaceRoot) {
261
+ function checkFileImports(filePath, workspaceRoot, aliasMap) {
191
262
  const content = fs.readFileSync(filePath, 'utf8');
192
263
  const lines = content.split('\n');
193
264
 
@@ -230,7 +301,7 @@ function checkFileImports(filePath, workspaceRoot) {
230
301
 
231
302
  // Check each imported name
232
303
  importedNames.forEach(name => {
233
- checkImport(importPath, name, filePath, workspaceRoot);
304
+ checkImport(importPath, name, filePath, workspaceRoot, aliasMap);
234
305
  });
235
306
  }
236
307
  }
@@ -267,14 +338,17 @@ function main() {
267
338
  }
268
339
  }
269
340
 
270
- // src/ Verzeichnis finden (intelligente Suche)
271
- const srcDir = findSrcDirectory(workspaceRoot);
341
+ // Lade Alias-Map
342
+ const aliasMap = loadAliasMap(workspaceRoot);
343
+
344
+ // src/ Verzeichnis finden (intelligente Suche mit Alias-Map)
345
+ const srcDir = findSrcDirectoryWithAlias(workspaceRoot, workspaceRoot, aliasMap);
272
346
  if (!srcDir) {
273
347
  console.log('⚠️ src/ directory not found, skipping verification');
274
348
  console.log(` Searched from: ${workspaceRoot}`);
275
349
  process.exit(0);
276
350
  }
277
-
351
+
278
352
  // workspaceRoot auf Basis des gefundenen src/ korrigieren
279
353
  workspaceRoot = path.dirname(srcDir);
280
354
 
@@ -285,7 +359,7 @@ function main() {
285
359
 
286
360
  let checkedFiles = 0;
287
361
  for (const file of files) {
288
- checkFileImports(file, workspaceRoot);
362
+ checkFileImports(file, workspaceRoot, aliasMap);
289
363
  checkedFiles++;
290
364
 
291
365
  if (checkedFiles % 10 === 0) {