-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathengine.js
More file actions
104 lines (87 loc) · 3.25 KB
/
Copy pathengine.js
File metadata and controls
104 lines (87 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import Parser from 'web-tree-sitter';
import path from 'path';
import fs from 'fs';
/**
* Blocc Code Parser Engine
* Uses Tree-sitter to analyze codebase and extract API metadata.
*/
class CodeParserEngine {
constructor() {
this.parser = null;
this.initialized = false;
}
async init() {
if (this.initialized) return;
await Parser.init();
this.parser = new Parser();
this.initialized = true;
}
async loadLanguage(lang) {
const wasmPath = path.resolve(`api/parser/wasm/tree-sitter-${lang}.wasm`);
// Ensure WASM file physically exists and isn't corrupted (e.g. 0 bytes)
if (!fs.existsSync(wasmPath)) {
console.warn(`[Parser Warning] Missing WASM binary for language: ${lang}`);
return false;
}
const stats = fs.statSync(wasmPath);
if (stats.size === 0) {
console.warn(`[Parser Warning] Corrupted WASM binary (0 bytes) for language: ${lang}`);
return false;
}
try {
const Lang = await Parser.Language.load(wasmPath);
this.parser.setLanguage(Lang);
return true;
} catch (e) {
console.error(`Failed to load language ${lang}:`, e);
return false;
}
}
/**
* Scans source code for endpoint patterns
*/
async scan(content, language) {
await this.init();
const success = await this.loadLanguage(language);
if (!success) return [];
const tree = this.parser.parse(content);
const endpoints = [];
// Example Query for Express/JS routes
// This is a simplified version of AST querying
if (language === 'javascript' || language === 'typescript') {
const query = this.parser.getLanguage().query(`
(call_expression
function: (member_expression
object: (identifier) @app
property: (identifier) @method (#match? @method "^(get|post|put|delete|patch)$")
)
arguments: (arguments
(string) @path
)
) @route
`);
const captures = query.captures(tree.rootNode);
let currentRoute = {};
captures.forEach(cap => {
if (cap.name === 'method') currentRoute.method = cap.node.text.toUpperCase();
if (cap.name === 'path') currentRoute.path = cap.node.text.replace(/['"]/g, '');
if (currentRoute.method && currentRoute.path) {
endpoints.push({ ...currentRoute });
currentRoute = {};
}
});
}
// Similar queries would be implemented for Python (FastAPI/Flask) and Go
return endpoints;
}
}
// Example CLI usage: node engine.js <file_content> <language>
if (process.argv[2] && process.argv[3]) {
const engine = new CodeParserEngine();
const content = process.argv[2];
const lang = process.argv[3];
engine.scan(content, lang).then(results => {
console.log(JSON.stringify(results));
});
}
export default CodeParserEngine;