@nicollasfrazao/liguelead-log-service 2.0.0 → 2.1.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/README.md +63 -0
- package/dist/.mcp/analyzers/best-practices.d.ts +3 -0
- package/dist/.mcp/analyzers/best-practices.d.ts.map +1 -0
- package/dist/.mcp/analyzers/best-practices.js +61 -0
- package/dist/.mcp/analyzers/best-practices.js.map +1 -0
- package/dist/.mcp/analyzers/express-detector.d.ts +3 -0
- package/dist/.mcp/analyzers/express-detector.d.ts.map +1 -0
- package/dist/.mcp/analyzers/express-detector.js +150 -0
- package/dist/.mcp/analyzers/express-detector.js.map +1 -0
- package/dist/.mcp/analyzers/logging-detector.d.ts +5 -0
- package/dist/.mcp/analyzers/logging-detector.d.ts.map +1 -0
- package/dist/.mcp/analyzers/logging-detector.js +196 -0
- package/dist/.mcp/analyzers/logging-detector.js.map +1 -0
- package/dist/.mcp/analyzers/pattern-matcher.d.ts +3 -0
- package/dist/.mcp/analyzers/pattern-matcher.d.ts.map +1 -0
- package/dist/.mcp/analyzers/pattern-matcher.js +187 -0
- package/dist/.mcp/analyzers/pattern-matcher.js.map +1 -0
- package/dist/.mcp/bin/mcp-server.d.ts +3 -0
- package/dist/.mcp/bin/mcp-server.d.ts.map +1 -0
- package/dist/.mcp/bin/mcp-server.js +9 -0
- package/dist/.mcp/bin/mcp-server.js.map +1 -0
- package/dist/.mcp/knowledge/best-practices.d.ts +33 -0
- package/dist/.mcp/knowledge/best-practices.d.ts.map +1 -0
- package/dist/.mcp/knowledge/best-practices.js +95 -0
- package/dist/.mcp/knowledge/best-practices.js.map +1 -0
- package/dist/.mcp/knowledge/documentation.d.ts +10 -0
- package/dist/.mcp/knowledge/documentation.d.ts.map +1 -0
- package/dist/.mcp/knowledge/documentation.js +362 -0
- package/dist/.mcp/knowledge/documentation.js.map +1 -0
- package/dist/.mcp/knowledge/snippets.d.ts +11 -0
- package/dist/.mcp/knowledge/snippets.d.ts.map +1 -0
- package/dist/.mcp/knowledge/snippets.js +140 -0
- package/dist/.mcp/knowledge/snippets.js.map +1 -0
- package/dist/.mcp/resources/index.d.ts +9 -0
- package/dist/.mcp/resources/index.d.ts.map +1 -0
- package/dist/.mcp/resources/index.js +49 -0
- package/dist/.mcp/resources/index.js.map +1 -0
- package/dist/.mcp/server.d.ts +2 -0
- package/dist/.mcp/server.d.ts.map +1 -0
- package/dist/.mcp/server.js +170 -0
- package/dist/.mcp/server.js.map +1 -0
- package/dist/.mcp/tools/analyze-project.tool.d.ts +2 -0
- package/dist/.mcp/tools/analyze-project.tool.d.ts.map +1 -0
- package/dist/.mcp/tools/analyze-project.tool.js +91 -0
- package/dist/.mcp/tools/analyze-project.tool.js.map +1 -0
- package/dist/.mcp/tools/fix-logging.tool.d.ts +2 -0
- package/dist/.mcp/tools/fix-logging.tool.d.ts.map +1 -0
- package/dist/.mcp/tools/fix-logging.tool.js +119 -0
- package/dist/.mcp/tools/fix-logging.tool.js.map +1 -0
- package/dist/.mcp/tools/generate-snippet.tool.d.ts +2 -0
- package/dist/.mcp/tools/generate-snippet.tool.d.ts.map +1 -0
- package/dist/.mcp/tools/generate-snippet.tool.js +27 -0
- package/dist/.mcp/tools/generate-snippet.tool.js.map +1 -0
- package/dist/.mcp/tools/implement-logging.tool.d.ts +7 -0
- package/dist/.mcp/tools/implement-logging.tool.d.ts.map +1 -0
- package/dist/.mcp/tools/implement-logging.tool.js +149 -0
- package/dist/.mcp/tools/implement-logging.tool.js.map +1 -0
- package/dist/.mcp/tools/index.d.ts +7 -0
- package/dist/.mcp/tools/index.d.ts.map +1 -0
- package/dist/.mcp/tools/index.js +16 -0
- package/dist/.mcp/tools/index.js.map +1 -0
- package/dist/.mcp/tools/suggest-logging.tool.d.ts +2 -0
- package/dist/.mcp/tools/suggest-logging.tool.d.ts.map +1 -0
- package/dist/.mcp/tools/suggest-logging.tool.js +68 -0
- package/dist/.mcp/tools/suggest-logging.tool.js.map +1 -0
- package/dist/.mcp/tools/validate-logging.tool.d.ts +2 -0
- package/dist/.mcp/tools/validate-logging.tool.d.ts.map +1 -0
- package/dist/.mcp/tools/validate-logging.tool.js +70 -0
- package/dist/.mcp/tools/validate-logging.tool.js.map +1 -0
- package/dist/.mcp/types/index.d.ts +150 -0
- package/dist/.mcp/types/index.d.ts.map +1 -0
- package/dist/.mcp/types/index.js +6 -0
- package/dist/.mcp/types/index.js.map +1 -0
- package/dist/.mcp/writers/code-writer.d.ts +6 -0
- package/dist/.mcp/writers/code-writer.d.ts.map +1 -0
- package/dist/.mcp/writers/code-writer.js +110 -0
- package/dist/.mcp/writers/code-writer.js.map +1 -0
- package/dist/.mcp/writers/import-manager.d.ts +9 -0
- package/dist/.mcp/writers/import-manager.d.ts.map +1 -0
- package/dist/.mcp/writers/import-manager.js +58 -0
- package/dist/.mcp/writers/import-manager.js.map +1 -0
- package/dist/.mcp/writers/log-fixer.d.ts +6 -0
- package/dist/.mcp/writers/log-fixer.d.ts.map +1 -0
- package/dist/.mcp/writers/log-fixer.js +64 -0
- package/dist/.mcp/writers/log-fixer.js.map +1 -0
- package/dist/.mcp/writers/log-inserter.d.ts +6 -0
- package/dist/.mcp/writers/log-inserter.d.ts.map +1 -0
- package/dist/.mcp/writers/log-inserter.js +72 -0
- package/dist/.mcp/writers/log-inserter.js.map +1 -0
- package/dist/helpers/log.sanitization.helper.d.ts.map +1 -1
- package/dist/helpers/log.sanitization.helper.js +9 -1
- package/dist/helpers/log.sanitization.helper.js.map +1 -1
- package/dist/mcp-server.d.ts +9 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +27 -0
- package/dist/mcp-server.js.map +1 -0
- package/package.json +18 -3
package/README.md
CHANGED
|
@@ -515,6 +515,69 @@ npm run prepublishOnly # Clean + build para publicação
|
|
|
515
515
|
- `test:` Testes
|
|
516
516
|
- `chore:` Manutenção
|
|
517
517
|
|
|
518
|
+
## 🤖 MCP Server (AI Integration)
|
|
519
|
+
|
|
520
|
+
An MCP (Model Context Protocol) server is included for AI-assisted logging integration. It allows AI agents like Claude Desktop, VS Code Copilot, Cursor, and Windsurf to analyze, validate, fix, and implement logging in your Express projects.
|
|
521
|
+
|
|
522
|
+
**Use it with:**
|
|
523
|
+
```bash
|
|
524
|
+
npx @nicollasfrazao/liguelead-log-service
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
**Or import programmatically:**
|
|
528
|
+
```typescript
|
|
529
|
+
import { startServer } from '@nicollasfrazao/liguelead-log-service/mcp';
|
|
530
|
+
await startServer();
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
**Available tools:** `analyze_project`, `validate_logging`, `suggest_logging`, `fix_logging`, `implement_logging`, `generate_snippet`
|
|
534
|
+
|
|
535
|
+
See [MCP Configuration Guide](#mcp-configuration) below and [src/.mcp/README.md](src/.mcp/README.md) for full documentation and agent setup.
|
|
536
|
+
|
|
537
|
+
### MCP Configuration
|
|
538
|
+
|
|
539
|
+
#### Claude Desktop
|
|
540
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
541
|
+
|
|
542
|
+
```json
|
|
543
|
+
{
|
|
544
|
+
"mcpServers": {
|
|
545
|
+
"liguelead-log-service": {
|
|
546
|
+
"command": "npx",
|
|
547
|
+
"args": ["@nicollasfrazao/liguelead-log-service"]
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
#### VS Code (Copilot)
|
|
554
|
+
Add to `.vscode/mcp.json` in your project:
|
|
555
|
+
|
|
556
|
+
```json
|
|
557
|
+
{
|
|
558
|
+
"servers": {
|
|
559
|
+
"liguelead-log-service": {
|
|
560
|
+
"command": "npx",
|
|
561
|
+
"args": ["@nicollasfrazao/liguelead-log-service"]
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
#### Cursor
|
|
568
|
+
Add to `.cursor/mcp.json`:
|
|
569
|
+
|
|
570
|
+
```json
|
|
571
|
+
{
|
|
572
|
+
"mcpServers": {
|
|
573
|
+
"liguelead-log-service": {
|
|
574
|
+
"command": "npx",
|
|
575
|
+
"args": ["@nicollasfrazao/liguelead-log-service"]
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
518
581
|
## 📄 Licença
|
|
519
582
|
|
|
520
583
|
ISC © [Ligue Lead Tech](https://github.com/ligue-lead-tech)
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { BestPracticesResult, ExpressDetectorResult, LoggingDetectorResult } from '../types';
|
|
2
|
+
export declare function validateBestPractices(targetPath: string, expressResult?: ExpressDetectorResult, loggingResult?: LoggingDetectorResult): Promise<BestPracticesResult>;
|
|
3
|
+
//# sourceMappingURL=best-practices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"best-practices.d.ts","sourceRoot":"","sources":["../../../src/.mcp/analyzers/best-practices.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACtB,MAAM,UAAU,CAAC;AAElB,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,qBAAqB,EACrC,aAAa,CAAC,EAAE,qBAAqB,GACpC,OAAO,CAAC,mBAAmB,CAAC,CA+D9B"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateBestPractices = validateBestPractices;
|
|
4
|
+
const logging_detector_1 = require("./logging-detector");
|
|
5
|
+
const express_detector_1 = require("./express-detector");
|
|
6
|
+
async function validateBestPractices(targetPath, expressResult, loggingResult) {
|
|
7
|
+
const express = expressResult ?? await (0, express_detector_1.detectExpress)(targetPath);
|
|
8
|
+
const logging = loggingResult ?? await (0, logging_detector_1.detectLogging)(targetPath);
|
|
9
|
+
const violations = [];
|
|
10
|
+
const warnings = [];
|
|
11
|
+
const passed = [];
|
|
12
|
+
// Collect issues from logging detector
|
|
13
|
+
for (const issue of logging.issues) {
|
|
14
|
+
if (issue.severity === 'error') {
|
|
15
|
+
violations.push(issue);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
warnings.push(issue);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Check LogMiddleware order
|
|
22
|
+
if (express.hasLogMiddleware) {
|
|
23
|
+
const middlewareIndex = express.middlewares.findIndex((m) => m.isLogMiddleware);
|
|
24
|
+
const firstRouteMiddleware = express.middlewares.findIndex((m) => !m.isLogMiddleware);
|
|
25
|
+
if (middlewareIndex > -1
|
|
26
|
+
&& firstRouteMiddleware > -1
|
|
27
|
+
&& middlewareIndex > firstRouteMiddleware) {
|
|
28
|
+
violations.push({
|
|
29
|
+
id: 'middleware-order',
|
|
30
|
+
filePath: express.middlewares[middlewareIndex].filePath,
|
|
31
|
+
line: express.middlewares[middlewareIndex].line,
|
|
32
|
+
severity: 'error',
|
|
33
|
+
rule: 'middleware-before-routes',
|
|
34
|
+
message: 'LogMiddleware.handler is registered AFTER other middlewares/routes',
|
|
35
|
+
suggestion: 'Move app.use(LogMiddleware.handler) before route definitions',
|
|
36
|
+
fixable: false,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
passed.push('LogMiddleware.handler is correctly placed before routes');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (express.hasLogServiceImport) {
|
|
44
|
+
passed.push('Log service import detected');
|
|
45
|
+
}
|
|
46
|
+
// Check for fire-and-forget
|
|
47
|
+
const noAwaitCalls = logging.logCalls.filter((c) => !c.hasAwait);
|
|
48
|
+
if (noAwaitCalls.length === 0 && logging.logCalls.length > 0) {
|
|
49
|
+
passed.push('All LogService calls use await');
|
|
50
|
+
}
|
|
51
|
+
// Check catch blocks use error level
|
|
52
|
+
const catchCalls = logging.logCalls.filter((c) => c.isInCatchBlock);
|
|
53
|
+
const wrongLevelInCatch = catchCalls.filter((c) => c.level !== 'error');
|
|
54
|
+
if (wrongLevelInCatch.length === 0 && catchCalls.length > 0) {
|
|
55
|
+
passed.push('All catch block logs use error level');
|
|
56
|
+
}
|
|
57
|
+
const totalChecks = violations.length + warnings.length + passed.length;
|
|
58
|
+
const score = totalChecks > 0 ? Math.round((passed.length / totalChecks) * 100) : 100;
|
|
59
|
+
return { violations, warnings, passed, score };
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=best-practices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"best-practices.js","sourceRoot":"","sources":["../../../src/.mcp/analyzers/best-practices.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express-detector.d.ts","sourceRoot":"","sources":["../../../src/.mcp/analyzers/express-detector.ts"],"names":[],"mappings":"AAGA,OAAO,EAKL,qBAAqB,EACtB,MAAM,UAAU,CAAC;AAQlB,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAgBvF"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.detectExpress = detectExpress;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const glob_1 = require("glob");
|
|
40
|
+
const EXPRESS_IMPORT_PATTERN = /(?:require\s*\(\s*['"]express['"]\s*\)|import\s+.*?\s+from\s+['"]express['"])/;
|
|
41
|
+
const LOG_SERVICE_IMPORT_PATTERN = /(?:require\s*\(\s*['"]@nicollasfrazao\/liguelead-log-service['"]\s*\)|import\s+.*?\s+from\s+['"]@nicollasfrazao\/liguelead-log-service['"])/;
|
|
42
|
+
const LOG_MIDDLEWARE_PATTERN = /LogMiddleware\.handler/;
|
|
43
|
+
const ROUTE_PATTERN = /\b(app|router)\s*\.\s*(get|post|put|patch|delete|all|use)\s*\(\s*['"\/]/;
|
|
44
|
+
const EXPRESS_VAR_PATTERN = /(?:const|let|var)\s+(\w+)\s*=\s*(?:express\s*\(\)|require\s*\(\s*['"]express['"]\s*\)\s*\(\))/;
|
|
45
|
+
async function detectExpress(projectPath) {
|
|
46
|
+
const result = {
|
|
47
|
+
entryPoints: [],
|
|
48
|
+
routes: [],
|
|
49
|
+
middlewares: [],
|
|
50
|
+
hasLogMiddleware: false,
|
|
51
|
+
hasLogServiceImport: false,
|
|
52
|
+
};
|
|
53
|
+
const files = await getProjectFiles(projectPath);
|
|
54
|
+
for (const fileInfo of files) {
|
|
55
|
+
analyzeFile(fileInfo, result);
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
async function getProjectFiles(projectPath) {
|
|
60
|
+
const resolvedPath = path.resolve(projectPath);
|
|
61
|
+
const pattern = '**/*.{ts,js}';
|
|
62
|
+
const ignore = ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**', '**/*.d.ts', '**/*.spec.ts', '**/*.test.ts'];
|
|
63
|
+
const filePaths = await (0, glob_1.glob)(pattern, { cwd: resolvedPath, ignore, absolute: true });
|
|
64
|
+
const files = [];
|
|
65
|
+
for (const filePath of filePaths) {
|
|
66
|
+
try {
|
|
67
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
68
|
+
files.push({
|
|
69
|
+
filePath,
|
|
70
|
+
content,
|
|
71
|
+
lines: content.split('\n'),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Skip files that can't be read
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return files;
|
|
79
|
+
}
|
|
80
|
+
function analyzeFile(fileInfo, result) {
|
|
81
|
+
const { filePath, content, lines } = fileInfo;
|
|
82
|
+
if (EXPRESS_IMPORT_PATTERN.test(content)) {
|
|
83
|
+
const expressVarMatch = content.match(EXPRESS_VAR_PATTERN);
|
|
84
|
+
if (expressVarMatch) {
|
|
85
|
+
result.entryPoints.push({
|
|
86
|
+
filePath,
|
|
87
|
+
line: findLineNumber(lines, EXPRESS_VAR_PATTERN),
|
|
88
|
+
expressVariable: expressVarMatch[1],
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (LOG_SERVICE_IMPORT_PATTERN.test(content)) {
|
|
93
|
+
result.hasLogServiceImport = true;
|
|
94
|
+
}
|
|
95
|
+
if (LOG_MIDDLEWARE_PATTERN.test(content)) {
|
|
96
|
+
result.hasLogMiddleware = true;
|
|
97
|
+
}
|
|
98
|
+
for (let i = 0; i < lines.length; i++) {
|
|
99
|
+
const line = lines[i];
|
|
100
|
+
detectRoute(filePath, line, i + 1, result);
|
|
101
|
+
detectMiddleware(filePath, line, i + 1, result);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function detectRoute(filePath, line, lineNum, result) {
|
|
105
|
+
const match = line.match(ROUTE_PATTERN);
|
|
106
|
+
if (!match)
|
|
107
|
+
return;
|
|
108
|
+
const method = match[2].toUpperCase();
|
|
109
|
+
if (method === 'USE')
|
|
110
|
+
return; // handled by detectMiddleware
|
|
111
|
+
const pathMatch = line.match(/\.\s*(?:get|post|put|patch|delete|all)\s*\(\s*['"]([^'"]*)['"]/);
|
|
112
|
+
const routePath = pathMatch ? pathMatch[1] : 'unknown';
|
|
113
|
+
const handlerMatch = line.match(/,\s*(\w+)\s*[,)]/);
|
|
114
|
+
const handlerName = handlerMatch ? handlerMatch[1] : undefined;
|
|
115
|
+
const hasLogging = checkRouteHasLogging(filePath, lineNum, result);
|
|
116
|
+
result.routes.push({
|
|
117
|
+
filePath,
|
|
118
|
+
line: lineNum,
|
|
119
|
+
method,
|
|
120
|
+
path: routePath,
|
|
121
|
+
handlerName,
|
|
122
|
+
hasLogging,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function checkRouteHasLogging(_filePath, _lineNum, _result) {
|
|
126
|
+
// Determined later by logging-detector; default false
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
function detectMiddleware(filePath, line, lineNum, result) {
|
|
130
|
+
const useMatch = line.match(/\b(?:app|router)\s*\.\s*use\s*\(/);
|
|
131
|
+
if (!useMatch)
|
|
132
|
+
return;
|
|
133
|
+
const isLogMiddleware = LOG_MIDDLEWARE_PATTERN.test(line);
|
|
134
|
+
const nameMatch = line.match(/\.use\s*\(\s*(\w+)/);
|
|
135
|
+
const name = nameMatch ? nameMatch[1] : 'anonymous';
|
|
136
|
+
result.middlewares.push({
|
|
137
|
+
filePath,
|
|
138
|
+
line: lineNum,
|
|
139
|
+
name: isLogMiddleware ? 'LogMiddleware.handler' : name,
|
|
140
|
+
isLogMiddleware,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
function findLineNumber(lines, pattern) {
|
|
144
|
+
for (let i = 0; i < lines.length; i++) {
|
|
145
|
+
if (pattern.test(lines[i]))
|
|
146
|
+
return i + 1;
|
|
147
|
+
}
|
|
148
|
+
return 1;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=express-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express-detector.js","sourceRoot":"","sources":["../../../src/.mcp/analyzers/express-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { LoggingDetectorResult } from '../types';
|
|
2
|
+
declare const EXECUTE_REQUEST_PATTERN: RegExp;
|
|
3
|
+
export declare function detectLogging(targetPath: string): Promise<LoggingDetectorResult>;
|
|
4
|
+
export { EXECUTE_REQUEST_PATTERN };
|
|
5
|
+
//# sourceMappingURL=logging-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging-detector.d.ts","sourceRoot":"","sources":["../../../src/.mcp/analyzers/logging-detector.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,qBAAqB,EACtB,MAAM,UAAU,CAAC;AAIlB,QAAA,MAAM,uBAAuB,QAAsC,CAAC;AAEpE,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAuBtF;AAkJD,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.EXECUTE_REQUEST_PATTERN = void 0;
|
|
37
|
+
exports.detectLogging = detectLogging;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const glob_1 = require("glob");
|
|
41
|
+
const LOG_CALL_PATTERN = /LogService\.(info|warn|error|debug)\s*\(/g;
|
|
42
|
+
const AWAIT_LOG_CALL_PATTERN = /await\s+LogService\.(info|warn|error|debug)\s*\(/;
|
|
43
|
+
const EXECUTE_REQUEST_PATTERN = /LogService\.executeRequest\s*[<(]/;
|
|
44
|
+
exports.EXECUTE_REQUEST_PATTERN = EXECUTE_REQUEST_PATTERN;
|
|
45
|
+
async function detectLogging(targetPath) {
|
|
46
|
+
const files = await getFiles(targetPath);
|
|
47
|
+
const logCalls = [];
|
|
48
|
+
const issues = [];
|
|
49
|
+
let filesWithLogging = 0;
|
|
50
|
+
for (const fileInfo of files) {
|
|
51
|
+
const fileCalls = analyzeFileLogging(fileInfo);
|
|
52
|
+
if (fileCalls.length > 0)
|
|
53
|
+
filesWithLogging++;
|
|
54
|
+
logCalls.push(...fileCalls);
|
|
55
|
+
issues.push(...detectIssues(fileInfo, fileCalls));
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
logCalls,
|
|
59
|
+
issues,
|
|
60
|
+
coverage: {
|
|
61
|
+
filesWithLogging,
|
|
62
|
+
totalFiles: files.length,
|
|
63
|
+
percentage: files.length > 0 ? Math.round((filesWithLogging / files.length) * 100) : 0,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async function getFiles(targetPath) {
|
|
68
|
+
const resolvedPath = path.resolve(targetPath);
|
|
69
|
+
const stat = fs.statSync(resolvedPath);
|
|
70
|
+
if (stat.isFile()) {
|
|
71
|
+
const content = fs.readFileSync(resolvedPath, 'utf-8');
|
|
72
|
+
return [{ filePath: resolvedPath, content, lines: content.split('\n') }];
|
|
73
|
+
}
|
|
74
|
+
const pattern = '**/*.{ts,js}';
|
|
75
|
+
const ignore = ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**', '**/*.d.ts'];
|
|
76
|
+
const filePaths = await (0, glob_1.glob)(pattern, { cwd: resolvedPath, ignore, absolute: true });
|
|
77
|
+
const files = [];
|
|
78
|
+
for (const filePath of filePaths) {
|
|
79
|
+
try {
|
|
80
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
81
|
+
files.push({ filePath, content, lines: content.split('\n') });
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Skip unreadable files
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return files;
|
|
88
|
+
}
|
|
89
|
+
function analyzeFileLogging(fileInfo) {
|
|
90
|
+
const calls = [];
|
|
91
|
+
const { filePath, lines } = fileInfo;
|
|
92
|
+
for (let i = 0; i < lines.length; i++) {
|
|
93
|
+
const line = lines[i];
|
|
94
|
+
const lineNum = i + 1;
|
|
95
|
+
LOG_CALL_PATTERN.lastIndex = 0;
|
|
96
|
+
const match = LOG_CALL_PATTERN.exec(line);
|
|
97
|
+
if (!match)
|
|
98
|
+
continue;
|
|
99
|
+
const level = match[1];
|
|
100
|
+
const hasAwait = AWAIT_LOG_CALL_PATTERN.test(line);
|
|
101
|
+
const isInCatchBlock = isInsideCatch(lines, i);
|
|
102
|
+
const isInTryCatch = isInsideTryCatch(lines, i);
|
|
103
|
+
calls.push({
|
|
104
|
+
filePath,
|
|
105
|
+
line: lineNum,
|
|
106
|
+
level,
|
|
107
|
+
hasAwait,
|
|
108
|
+
isInTryCatch,
|
|
109
|
+
isInCatchBlock,
|
|
110
|
+
rawLine: line.trim(),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return calls;
|
|
114
|
+
}
|
|
115
|
+
function isInsideCatch(lines, lineIndex) {
|
|
116
|
+
let braceDepth = 0;
|
|
117
|
+
for (let i = lineIndex; i >= 0; i--) {
|
|
118
|
+
const line = lines[i];
|
|
119
|
+
for (let j = line.length - 1; j >= 0; j--) {
|
|
120
|
+
if (line[j] === '}')
|
|
121
|
+
braceDepth++;
|
|
122
|
+
if (line[j] === '{')
|
|
123
|
+
braceDepth--;
|
|
124
|
+
}
|
|
125
|
+
if (braceDepth < 0 && /\bcatch\s*\(/.test(lines[i])) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
function isInsideTryCatch(lines, lineIndex) {
|
|
132
|
+
for (let i = lineIndex; i >= 0; i--) {
|
|
133
|
+
if (/\btry\s*\{/.test(lines[i]) || /\bcatch\s*\(/.test(lines[i])) {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
function detectIssues(fileInfo, calls) {
|
|
140
|
+
const issues = [];
|
|
141
|
+
for (const call of calls) {
|
|
142
|
+
if (!call.hasAwait) {
|
|
143
|
+
issues.push({
|
|
144
|
+
id: `no-await-${call.filePath}-${call.line}`,
|
|
145
|
+
filePath: call.filePath,
|
|
146
|
+
line: call.line,
|
|
147
|
+
severity: 'error',
|
|
148
|
+
rule: 'no-fire-and-forget',
|
|
149
|
+
message: `LogService.${call.level}() called without await — logs may be lost`,
|
|
150
|
+
suggestion: `Add "await" before LogService.${call.level}()`,
|
|
151
|
+
fixable: true,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
if (call.isInCatchBlock && call.level !== 'error') {
|
|
155
|
+
issues.push({
|
|
156
|
+
id: `wrong-level-catch-${call.filePath}-${call.line}`,
|
|
157
|
+
filePath: call.filePath,
|
|
158
|
+
line: call.line,
|
|
159
|
+
severity: 'warning',
|
|
160
|
+
rule: 'error-in-catch',
|
|
161
|
+
message: `LogService.${call.level}() used in catch block — should be LogService.error()`,
|
|
162
|
+
suggestion: `Change to LogService.error()`,
|
|
163
|
+
fixable: true,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Check for new LogService()
|
|
168
|
+
for (let i = 0; i < fileInfo.lines.length; i++) {
|
|
169
|
+
if (/new\s+LogService\s*\(/.test(fileInfo.lines[i])) {
|
|
170
|
+
issues.push({
|
|
171
|
+
id: `no-instantiation-${fileInfo.filePath}-${i + 1}`,
|
|
172
|
+
filePath: fileInfo.filePath,
|
|
173
|
+
line: i + 1,
|
|
174
|
+
severity: 'error',
|
|
175
|
+
rule: 'no-instantiation',
|
|
176
|
+
message: 'LogService is static — do not instantiate with "new"',
|
|
177
|
+
suggestion: 'Use LogService.info() directly instead of new LogService()',
|
|
178
|
+
fixable: true,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (/context\.request\b/.test(fileInfo.lines[i])) {
|
|
182
|
+
issues.push({
|
|
183
|
+
id: `no-context-request-${fileInfo.filePath}-${i + 1}`,
|
|
184
|
+
filePath: fileInfo.filePath,
|
|
185
|
+
line: i + 1,
|
|
186
|
+
severity: 'warning',
|
|
187
|
+
rule: 'no-context-request',
|
|
188
|
+
message: 'Use context.payload instead of context.request',
|
|
189
|
+
suggestion: 'Replace context.request with context.payload',
|
|
190
|
+
fixable: true,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return issues;
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=logging-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging-detector.js","sourceRoot":"","sources":["../../../src/.mcp/analyzers/logging-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-matcher.d.ts","sourceRoot":"","sources":["../../../src/.mcp/analyzers/pattern-matcher.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,UAAU,CAAC;AASlB,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,qBAAqB,GACpC,OAAO,CAAC,oBAAoB,CAAC,CAkB/B"}
|