devbonzai 2.2.0 → 2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devbonzai",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Quickly set up a local file server in any repository for browser-based file access",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -26,6 +26,8 @@
26
26
  "cors": "^2.8.5",
27
27
  "body-parser": "^1.20.2",
28
28
  "raw-body": "^2.5.2",
29
- "glob": "^10.0.0"
29
+ "glob": "^10.0.0",
30
+ "eslint": "^8.57.0",
31
+ "madge": "^6.1.0"
30
32
  }
31
33
  }
@@ -1,19 +1,26 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const glob = require('glob');
4
+ const { ESLint } = require('eslint');
5
+ const madge = require('madge');
4
6
  const { getIgnorePatterns, shouldIgnore } = require('../utils/ignore');
5
7
 
6
8
  module.exports = async function scanCodeQuality(req, res) {
7
9
  try {
8
- const { projectPath, maxFileLines = 500, maxFolderFiles = 20 } = req.body;
10
+ const {
11
+ projectPath,
12
+ maxFileLines = 500,
13
+ maxFolderFiles = 20,
14
+ checkUnusedImports = true,
15
+ checkDeadCode = true,
16
+ checkCircularDeps = false
17
+ } = req.body;
9
18
 
10
19
  if (!projectPath) {
11
20
  return res.status(400).json({ error: 'projectPath required' });
12
21
  }
13
22
 
14
- // Get ignore patterns from .ignore file (same blacklist used throughout the codebase)
15
23
  const ignorePatterns = getIgnorePatterns();
16
-
17
24
  const issues = [];
18
25
 
19
26
  // 1. Check file sizes
@@ -22,7 +29,6 @@ module.exports = async function scanCodeQuality(req, res) {
22
29
  nodir: true
23
30
  });
24
31
 
25
- // Filter out files that match ignore patterns
26
32
  const files = allFiles.filter(file => !shouldIgnore(file, ignorePatterns));
27
33
 
28
34
  files.forEach(file => {
@@ -45,7 +51,6 @@ module.exports = async function scanCodeQuality(req, res) {
45
51
  cwd: projectPath
46
52
  });
47
53
 
48
- // Filter out folders that match ignore patterns
49
54
  const folders = allFolders.filter(folder => !shouldIgnore(folder, ignorePatterns));
50
55
 
51
56
  folders.forEach(folder => {
@@ -66,6 +71,79 @@ module.exports = async function scanCodeQuality(req, res) {
66
71
  }
67
72
  });
68
73
 
74
+ // 3. Check unused imports and dead code with ESLint
75
+ if (checkUnusedImports || checkDeadCode) {
76
+ try {
77
+ const eslint = new ESLint({
78
+ cwd: projectPath,
79
+ useEslintrc: false,
80
+ overrideConfig: {
81
+ env: {
82
+ browser: true,
83
+ node: true,
84
+ es6: true
85
+ },
86
+ parserOptions: {
87
+ ecmaVersion: 2021,
88
+ sourceType: 'module',
89
+ ecmaFeatures: { jsx: true }
90
+ },
91
+ rules: {
92
+ 'no-unused-vars': checkDeadCode ? 'error' : 'off',
93
+ '@typescript-eslint/no-unused-vars': checkDeadCode ? 'error' : 'off'
94
+ }
95
+ }
96
+ });
97
+
98
+ const jsFiles = files.filter(f => /\.(js|jsx|ts|tsx)$/.test(f));
99
+ const results = await eslint.lintFiles(jsFiles.map(f => path.join(projectPath, f)));
100
+
101
+ results.forEach(result => {
102
+ const relativePath = path.relative(projectPath, result.filePath);
103
+
104
+ result.messages.forEach(msg => {
105
+ if (msg.ruleId === 'no-unused-vars' || msg.ruleId === '@typescript-eslint/no-unused-vars') {
106
+ issues.push({
107
+ type: 'unused_variable',
108
+ file: relativePath,
109
+ line: msg.line,
110
+ variable: msg.message.match(/'(.+?)'/)?.[1] || 'unknown',
111
+ message: msg.message
112
+ });
113
+ }
114
+ });
115
+ });
116
+ } catch (eslintError) {
117
+ console.error('ESLint scan error:', eslintError);
118
+ // Don't fail entire scan if ESLint fails
119
+ }
120
+ }
121
+
122
+ // 4. Check circular dependencies
123
+ if (checkCircularDeps) {
124
+ try {
125
+ const result = await madge(projectPath, {
126
+ fileExtensions: ['js', 'jsx', 'ts', 'tsx'],
127
+ excludeRegExp: ignorePatterns.map(p => new RegExp(p))
128
+ });
129
+
130
+ const circular = result.circular();
131
+
132
+ if (circular.length > 0) {
133
+ circular.forEach(cycle => {
134
+ issues.push({
135
+ type: 'circular_dependency',
136
+ files: cycle,
137
+ message: `Circular dependency: ${cycle.join(' → ')}`
138
+ });
139
+ });
140
+ }
141
+ } catch (madgeError) {
142
+ console.error('Madge scan error:', madgeError);
143
+ // Don't fail entire scan if madge fails
144
+ }
145
+ }
146
+
69
147
  res.json({ issues });
70
148
 
71
149
  } catch (error) {
@@ -73,4 +151,3 @@ module.exports = async function scanCodeQuality(req, res) {
73
151
  res.status(500).json({ error: error.message });
74
152
  }
75
153
  };
76
-