Files
git.stella-ops.org/tools/stella-callgraph-node/framework-detect.js
master 8779e9226f 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.
2025-12-19 18:11:59 +02:00

179 lines
4.8 KiB
JavaScript

// -----------------------------------------------------------------------------
// 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';
}