feat: add stella-callgraph-node for JavaScript/TypeScript call graph extraction
- Implemented a new tool `stella-callgraph-node` that extracts call graphs from JavaScript/TypeScript projects using Babel AST. - Added command-line interface with options for JSON output and help. - Included functionality to analyze project structure, detect functions, and build call graphs. - Created a package.json file for dependency management. feat: introduce stella-callgraph-python for Python call graph extraction - Developed `stella-callgraph-python` to extract call graphs from Python projects using AST analysis. - Implemented command-line interface with options for JSON output and verbose logging. - Added framework detection to identify popular web frameworks and their entry points. - Created an AST analyzer to traverse Python code and extract function definitions and calls. - Included requirements.txt for project dependencies. chore: add framework detection for Python projects - Implemented framework detection logic to identify frameworks like Flask, FastAPI, Django, and others based on project files and import patterns. - Enhanced the AST analyzer to recognize entry points based on decorators and function definitions.
This commit is contained in:
178
tools/stella-callgraph-node/framework-detect.js
Normal file
178
tools/stella-callgraph-node/framework-detect.js
Normal file
@@ -0,0 +1,178 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// framework-detect.js
|
||||
// Framework detection patterns for JavaScript/TypeScript projects.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Framework detection patterns
|
||||
*/
|
||||
export const frameworkPatterns = {
|
||||
express: {
|
||||
packageNames: ['express'],
|
||||
patterns: [
|
||||
/const\s+\w+\s*=\s*require\(['"]express['"]\)/,
|
||||
/import\s+\w+\s+from\s+['"]express['"]/,
|
||||
/app\.(get|post|put|delete|patch)\s*\(/
|
||||
],
|
||||
entrypointType: 'http_handler'
|
||||
},
|
||||
|
||||
fastify: {
|
||||
packageNames: ['fastify'],
|
||||
patterns: [
|
||||
/require\(['"]fastify['"]\)/,
|
||||
/import\s+\w+\s+from\s+['"]fastify['"]/,
|
||||
/fastify\.(get|post|put|delete|patch)\s*\(/
|
||||
],
|
||||
entrypointType: 'http_handler'
|
||||
},
|
||||
|
||||
koa: {
|
||||
packageNames: ['koa', '@koa/router'],
|
||||
patterns: [
|
||||
/require\(['"]koa['"]\)/,
|
||||
/import\s+\w+\s+from\s+['"]koa['"]/,
|
||||
/router\.(get|post|put|delete|patch)\s*\(/
|
||||
],
|
||||
entrypointType: 'http_handler'
|
||||
},
|
||||
|
||||
hapi: {
|
||||
packageNames: ['@hapi/hapi'],
|
||||
patterns: [
|
||||
/require\(['"]@hapi\/hapi['"]\)/,
|
||||
/import\s+\w+\s+from\s+['"]@hapi\/hapi['"]/,
|
||||
/server\.route\s*\(/
|
||||
],
|
||||
entrypointType: 'http_handler'
|
||||
},
|
||||
|
||||
nestjs: {
|
||||
packageNames: ['@nestjs/core', '@nestjs/common'],
|
||||
patterns: [
|
||||
/@Controller\s*\(/,
|
||||
/@Get\s*\(/,
|
||||
/@Post\s*\(/,
|
||||
/@Put\s*\(/,
|
||||
/@Delete\s*\(/,
|
||||
/@Patch\s*\(/
|
||||
],
|
||||
entrypointType: 'http_handler'
|
||||
},
|
||||
|
||||
socketio: {
|
||||
packageNames: ['socket.io'],
|
||||
patterns: [
|
||||
/require\(['"]socket\.io['"]\)/,
|
||||
/import\s+\w+\s+from\s+['"]socket\.io['"]/,
|
||||
/io\.on\s*\(\s*['"]connection['"]/,
|
||||
/socket\.on\s*\(/
|
||||
],
|
||||
entrypointType: 'websocket_handler'
|
||||
},
|
||||
|
||||
awsLambda: {
|
||||
packageNames: ['aws-lambda', '@types/aws-lambda'],
|
||||
patterns: [
|
||||
/exports\.handler\s*=/,
|
||||
/export\s+(const|async function)\s+handler/,
|
||||
/module\.exports\.handler/,
|
||||
/APIGatewayProxyHandler/,
|
||||
/APIGatewayEvent/
|
||||
],
|
||||
entrypointType: 'lambda'
|
||||
},
|
||||
|
||||
azureFunctions: {
|
||||
packageNames: ['@azure/functions'],
|
||||
patterns: [
|
||||
/require\(['"]@azure\/functions['"]\)/,
|
||||
/import\s+\w+\s+from\s+['"]@azure\/functions['"]/,
|
||||
/app\.(http|timer|queue|blob)\s*\(/
|
||||
],
|
||||
entrypointType: 'cloud_function'
|
||||
},
|
||||
|
||||
gcpFunctions: {
|
||||
packageNames: ['@google-cloud/functions-framework'],
|
||||
patterns: [
|
||||
/require\(['"]@google-cloud\/functions-framework['"]\)/,
|
||||
/functions\.(http|cloudEvent)\s*\(/
|
||||
],
|
||||
entrypointType: 'cloud_function'
|
||||
},
|
||||
|
||||
electron: {
|
||||
packageNames: ['electron'],
|
||||
patterns: [
|
||||
/require\(['"]electron['"]\)/,
|
||||
/import\s+\{[^}]*\}\s+from\s+['"]electron['"]/,
|
||||
/ipcMain\.on\s*\(/,
|
||||
/ipcRenderer\.on\s*\(/
|
||||
],
|
||||
entrypointType: 'event_handler'
|
||||
},
|
||||
|
||||
grpc: {
|
||||
packageNames: ['@grpc/grpc-js', 'grpc'],
|
||||
patterns: [
|
||||
/require\(['"]@grpc\/grpc-js['"]\)/,
|
||||
/addService\s*\(/,
|
||||
/loadPackageDefinition\s*\(/
|
||||
],
|
||||
entrypointType: 'grpc_method'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Detect frameworks from package.json dependencies
|
||||
* @param {object} packageJson
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function detectFrameworks(packageJson) {
|
||||
const detected = [];
|
||||
const allDeps = {
|
||||
...packageJson.dependencies,
|
||||
...packageJson.devDependencies
|
||||
};
|
||||
|
||||
for (const [framework, config] of Object.entries(frameworkPatterns)) {
|
||||
for (const pkgName of config.packageNames) {
|
||||
if (allDeps[pkgName]) {
|
||||
detected.push(framework);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return detected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect frameworks from source code patterns
|
||||
* @param {string} content
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function detectFrameworksFromCode(content) {
|
||||
const detected = [];
|
||||
|
||||
for (const [framework, config] of Object.entries(frameworkPatterns)) {
|
||||
for (const pattern of config.patterns) {
|
||||
if (pattern.test(content)) {
|
||||
detected.push(framework);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return detected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entrypoint type for a detected framework
|
||||
* @param {string} framework
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getEntrypointType(framework) {
|
||||
return frameworkPatterns[framework]?.entrypointType || 'unknown';
|
||||
}
|
||||
Reference in New Issue
Block a user