entkapp 5.1.0 → 5.2.1

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.
@@ -0,0 +1,80 @@
1
+ import path from 'path';
2
+
3
+ /**
4
+ * ============================================================================
5
+ * Dead Code & Zombie Export Hunter v5.1.0
6
+ * ============================================================================
7
+ * Identifies unused files and exported symbols that are never imported.
8
+ */
9
+ export class GraphAnalyzer {
10
+ constructor(context) {
11
+ this.context = context;
12
+ this.cwd = context.cwd;
13
+ }
14
+
15
+ /**
16
+ * Performs a full reachability analysis from entry points.
17
+ */
18
+ async findDeadCode() {
19
+ const graph = this.context.projectGraph;
20
+ const reachable = new Set();
21
+ const entries = [];
22
+
23
+ // 1. Identify all confirmed entry points
24
+ for (const [filePath, node] of graph.entries()) {
25
+ if (node.isEntry) {
26
+ entries.push(filePath);
27
+ this._walk(filePath, reachable);
28
+ }
29
+ }
30
+
31
+ const deadFiles = [];
32
+ const zombieExports = [];
33
+
34
+ // 2. Find unreachable files
35
+ for (const filePath of graph.keys()) {
36
+ if (!reachable.has(filePath)) {
37
+ deadFiles.push(path.relative(this.cwd, filePath).replace(/\\/g, '/'));
38
+ } else {
39
+ // 3. Find Zombie Exports in reachable files
40
+ const node = graph.get(filePath);
41
+ if (node.isEntry) continue; // Skip entries as their exports are intended for external use
42
+
43
+ for (const [symbol, meta] of node.internalExports.entries()) {
44
+ if (symbol === 'default' || symbol === '*') continue;
45
+
46
+ let isUsed = false;
47
+ // Check if any other node imports this symbol
48
+ for (const [otherPath, otherNode] of graph.entries()) {
49
+ if (otherNode.importedSymbols && otherNode.importedSymbols.has(symbol)) {
50
+ // This is a simplified check; in reality, we'd check if it's imported FROM this file
51
+ isUsed = true;
52
+ break;
53
+ }
54
+ }
55
+
56
+ if (!isUsed) {
57
+ zombieExports.push({
58
+ file: path.relative(this.cwd, filePath).replace(/\\/g, '/'),
59
+ symbol: symbol
60
+ });
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ return { deadFiles, zombieExports };
67
+ }
68
+
69
+ _walk(filePath, reachable) {
70
+ if (reachable.has(filePath)) return;
71
+ reachable.add(filePath);
72
+
73
+ const node = this.context.projectGraph.get(filePath);
74
+ if (!node) return;
75
+
76
+ for (const impPath of node.explicitImports) {
77
+ this._walk(impPath, reachable);
78
+ }
79
+ }
80
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * ============================================================================
3
+ * Migration Path Analyzer v5.1.0
4
+ * ============================================================================
5
+ * Suggests modern alternatives for legacy tools and frameworks.
6
+ */
7
+ export class MigrationAnalyzer {
8
+ constructor(context) {
9
+ this.context = context;
10
+ this.migrations = [
11
+ {
12
+ legacy: 'webpack',
13
+ modern: 'vite',
14
+ reason: 'Vite offers significantly faster HMR and build times using ES modules during development.'
15
+ },
16
+ {
17
+ legacy: 'jest',
18
+ modern: 'vitest',
19
+ reason: 'Vitest is faster, has native ESM support, and shares configuration with Vite.'
20
+ },
21
+ {
22
+ legacy: 'moment',
23
+ modern: 'dayjs',
24
+ reason: 'Day.js is a 2KB alternative to Moment.js with the same modern API.'
25
+ },
26
+ {
27
+ legacy: 'axios',
28
+ modern: 'fetch',
29
+ reason: 'Native fetch is now widely supported and requires no external dependency for simple use cases.'
30
+ },
31
+ {
32
+ legacy: 'ts-node',
33
+ modern: 'tsx',
34
+ reason: 'tsx is faster and has better ESM support for running TypeScript files.'
35
+ },
36
+ {
37
+ legacy: 'eslint-plugin-prettier',
38
+ modern: 'eslint-config-prettier',
39
+ reason: 'Running Prettier as an ESLint rule is slow. It is recommended to run them separately or use a config that turns off conflicting rules.'
40
+ }
41
+ ];
42
+ }
43
+
44
+ async analyze(activePlugins) {
45
+ const suggestions = [];
46
+ const activeNames = activePlugins.map(p => p.name);
47
+
48
+ for (const m of this.migrations) {
49
+ if (activeNames.includes(m.legacy)) {
50
+ suggestions.push({
51
+ from: m.legacy,
52
+ to: m.modern,
53
+ message: `Migration Suggestion: Consider moving from "${m.legacy}" to "${m.modern}". ${m.reason}`
54
+ });
55
+ }
56
+ }
57
+
58
+ return suggestions;
59
+ }
60
+ }
@@ -7,7 +7,7 @@ export class PathMapper {
7
7
  }
8
8
 
9
9
  async loadMappings() {
10
- // Hier können später tsconfig-Pfade geladen werden
10
+ // Tsconfig paths can be loaded here later
11
11
  }
12
12
 
13
13
  /**
@@ -18,19 +18,19 @@ export class PathMapper {
18
18
  resolvePath(p) {
19
19
  if (!p || typeof p !== 'string') return p;
20
20
 
21
- // FIX 1: Wenn der Import auf .js endet, übersetze ihn für die Suche auf .ts
21
+ // FIX 1: If the import ends with .js, translate it to .ts for the search
22
22
  if (p.endsWith('.js')) {
23
23
  const tsPath = p.slice(0, -3) + '.ts';
24
24
  if (fs.existsSync(tsPath)) return tsPath;
25
25
  }
26
26
 
27
- // FIX 2: Wenn der Import auf .jsx endet, übersetze ihn für die Suche auf .tsx
27
+ // FIX 2: If the import ends with .jsx, translate it to .tsx for the search
28
28
  if (p.endsWith('.jsx')) {
29
29
  const tsxPath = p.slice(0, -4) + '.tsx';
30
30
  if (fs.existsSync(tsxPath)) return tsxPath;
31
31
  }
32
32
 
33
- // FIX 3: Unterstützung für Verzeichnis-Imports (z.B. ./adapters -> ./adapters/index.ts)
33
+ // FIX 3: Support for directory imports (z.B. ./adapters -> ./adapters/index.ts)
34
34
  try {
35
35
  const stat = fs.statSync(p);
36
36
  if (stat.isDirectory()) {
@@ -41,7 +41,7 @@ export class PathMapper {
41
41
  }
42
42
  }
43
43
  } catch {
44
- // Datei existiert nicht oder ist kein Verzeichnis, fahre mit Standard fort
44
+ // File does not exist or is not a directory, continue with default
45
45
  }
46
46
 
47
47
  return p;