File size: 4,190 Bytes
6b825ee |
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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
// @ts-check
import fs from "fs";
import path from "path";
import { Request, Response } from 'express';
interface SkillResult {
name: string;
skill: string;
extension: string;
}
interface Config {
project: string;
}
const languageMap: { [key: string]: string } = {
"js": "JavaScript",
"ts": "TypeScript",
"html": "HTML",
"css": "CSS",
"json": "JSON",
"md": "Markdown",
"py": "Python",
"java": "Java",
"c": "C",
"cpp": "C++",
"cs": "C#",
"go": "Go",
"rb": "Ruby",
"php": "PHP",
"swift": "Swift",
"kt": "Kotlin",
"sh": "Shell Script",
"xml": "XML",
"yaml": "YAML",
"yml": "YAML",
"sql": "SQL",
"jsx": "React (JavaScript)",
"tsx": "React (TypeScript)",
};
function walkDir(dirPath: string, counts: Map<string, number>): number {
let totalFiles = 0;
if (!fs.existsSync(dirPath) || !fs.statSync(dirPath).isDirectory()) {
console.warn(`[Skills Analyzer] Directory not found or not a directory: ${dirPath}`);
return 0;
}
const files = fs.readdirSync(dirPath);
for (const file of files) {
const fullPath = path.join(dirPath, file);
try {
const stats = fs.statSync(fullPath);
if (stats.isDirectory()) {
totalFiles += walkDir(fullPath, counts);
} else if (stats.isFile()) {
let ext = path.extname(file);
if (ext) {
ext = ext.substring(1).toLowerCase();
counts.set(ext, (counts.get(ext) || 0) + 1);
totalFiles++;
}
}
} catch (error: any) {
console.error(`[Skills Analyzer] Error processing file ${fullPath}:`, error.message);
}
}
return totalFiles;
}
async function analyzeProjectSkills(): Promise<{ project: string; skills: SkillResult[] }> {
const configPath = path.resolve(__dirname, '..', 'config.json');
console.log(`[Skills Analyzer] Attempting to read config from: ${configPath}`);
let projectRoot: string;
try {
const configContent = fs.readFileSync(configPath, 'utf8');
const config: Config = JSON.parse(configContent);
if (!config.project) {
throw new Error("Missing 'project' key in config.json. Please ensure it's defined.");
}
projectRoot = path.resolve(path.dirname(configPath), config.project);
console.log(`[Skills Analyzer] Project path from config: ${projectRoot}`);
} catch (error: any) {
console.error(`[Skills Analyzer] Failed to read or parse config.json:`, error.message);
return { project: "Unknown Project (config error)", skills: [] };
}
const languageCounts = new Map<string, number>();
const totalFiles = walkDir(projectRoot, languageCounts);
if (totalFiles === 0) {
console.warn(`[Skills Analyzer] No files with recognized extensions found in project directory: ${projectRoot}`);
return { project: projectRoot, skills: [] };
}
const skills: SkillResult[] = [];
for (const [ext, count] of languageCounts.entries()) {
const percentage = ((count / totalFiles) * 100).toFixed(2);
const name = languageMap[ext] || ext.toUpperCase();
skills.push({
name: name.toLowerCase(),
skill: `${percentage}%`,
extension: ext,
});
}
skills.sort((a, b) => parseFloat(b.skill) - parseFloat(a.skill));
console.log(`[Skills Analyzer] Analysis complete for project: ${projectRoot}. Found ${totalFiles} files.`);
return { project: projectRoot, skills: skills };
}
interface LoginRouteParams {
req: Request<any, any, unknown>;
res: Response;
}
interface LoginExpressRouteModule {
method: "get" | "post" | "put" | "delete" | "patch" | "options" | "head" | "all";
path: string;
install: (params: LoginRouteParams) => Promise<void> | void;
}
export const modules: LoginExpressRouteModule[] = [
{
method: "post",
path: "/skills",
install: async ({ req, res }: { req: Request; res: Response }) => {
try {
const { project, skills } = await analyzeProjectSkills();
res.json([{ project: project, skills: skills }]);
} catch (error: any) {
console.error("[Skills Route] Error serving skills:", error.message);
res.status(500).json({ error: "Failed to analyze project skills. Check server logs." });
}
},
},
]; |