import fs from 'node:fs/promises'; import path from 'node:path'; import type { PackageFacts, RepoKind } from '../types.js'; export async function classifyRepository( repoPath: string, facts: PackageFacts ): Promise { const hasCdsDep = Boolean( facts.dependencies['@sap/cds'] ?? facts.dependencies.cds ?? facts.dependencies['cds-routing-handlers'] ); const cdsFiles = await findFiles(repoPath, '.cds'); const serverFiles = await Promise.all( ['srv/server.ts', 'srv/server.js', 'src/server.ts', 'src/server.js'].map( async (f) => fs .access(path.join(repoPath, f)) .then(() => true) .catch(() => false) ) ); const helper = Object.keys(facts.dependencies).includes('cds-routing-handlers') || facts.packageName?.includes('helper') === true; if (helper && cdsFiles.length > 0) return 'mixed'; if (helper) return 'helper-package'; if (hasCdsDep && (cdsFiles.length > 0 || serverFiles.some(Boolean))) return 'cap-service'; if (cdsFiles.length > 0) return serverFiles.some(Boolean) ? 'cap-service' : 'cap-db-model'; return 'unknown'; } async function findFiles(root: string, suffix: string): Promise { const out: string[] = []; async function walk(dir: string): Promise { const entries = await fs .readdir(dir, { withFileTypes: true }) .catch(() => []); for (const e of entries) { if (e.isDirectory()) { if (!['node_modules', 'dist', 'gen', '.git'].includes(e.name)) await walk(path.join(dir, e.name)); } else if (e.name.endsWith(suffix)) out.push(path.join(dir, e.name)); } } await walk(root); return out; }