UNPKG

lorehub

Version:

Capture and surface the collective wisdom of your codebase

176 lines 5.79 kB
import { readFile } from 'fs/promises'; import { join, basename } from 'path'; import { execSync } from 'child_process'; export async function getRealmInfo(realmPath) { const name = await detectProjectName(realmPath); const gitRemote = detectGitRemote(realmPath); const { isMonorepo, provinces } = await detectMonorepoInfo(realmPath); return { name, path: realmPath, gitRemote, isMonorepo, provinces, }; } async function detectProjectName(realmPath) { // Try package.json first try { const packageJsonPath = join(realmPath, 'package.json'); const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf-8')); if (packageJson.name) { return packageJson.name; } } catch { // Ignore error, try other methods } // Try Cargo.toml for Rust realms try { const cargoTomlPath = join(realmPath, 'Cargo.toml'); const cargoToml = await readFile(cargoTomlPath, 'utf-8'); const match = cargoToml.match(/name\s*=\s*"([^"]+)"/); if (match?.[1]) { return match[1]; } } catch { // Ignore error } // Default to directory name return basename(realmPath); } function detectGitRemote(realmPath) { try { const remote = execSync('git remote get-url origin', { cwd: realmPath, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'], }).trim(); return remote || undefined; } catch { return undefined; } } async function detectMonorepoInfo(realmPath) { // Check for common monorepo indicators try { const packageJsonPath = join(realmPath, 'package.json'); const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf-8')); // Check for workspace configuration (npm/yarn/pnpm) if (packageJson.workspaces) { const provinces = await detectWorkspaceProvinces(realmPath, packageJson.workspaces); return { isMonorepo: true, provinces }; } // Check for lerna try { const lernaPath = join(realmPath, 'lerna.json'); await readFile(lernaPath, 'utf-8'); const provinces = await detectLernaServices(realmPath); return { isMonorepo: true, provinces }; } catch { // Not a lerna monorepo } // Check for nx if (packageJson.nx || await fileExists(join(realmPath, 'nx.json'))) { const provinces = await detectNxServices(realmPath); return { isMonorepo: true, provinces }; } } catch { // Not a JS/TS realm or no package.json } // Check for Cargo workspace (Rust) try { const cargoTomlPath = join(realmPath, 'Cargo.toml'); const cargoToml = await readFile(cargoTomlPath, 'utf-8'); if (cargoToml.includes('[workspace]')) { const provinces = await detectCargoWorkspaceMembers(realmPath, cargoToml); return { isMonorepo: true, provinces }; } } catch { // Not a Rust realm } return { isMonorepo: false, provinces: [] }; } async function detectWorkspaceProvinces(realmPath, workspaces) { const patterns = Array.isArray(workspaces) ? workspaces : workspaces.packages || []; const services = []; // This is a simplified version - in production you'd use glob patterns for (const pattern of patterns) { if (pattern.includes('*')) { // Handle glob patterns - simplified for now const baseDir = pattern.replace('/*', '').replace('/**', ''); try { const { readdirSync } = await import('fs'); const dirs = readdirSync(join(realmPath, baseDir), { withFileTypes: true }) .filter(dirent => dirent.isDirectory()) .map(dirent => dirent.name); services.push(...dirs); } catch { // Ignore errors } } else { services.push(basename(pattern)); } } return services; } async function detectLernaServices(realmPath) { try { const { readdirSync } = await import('fs'); const packages = readdirSync(join(realmPath, 'packages'), { withFileTypes: true }) .filter(dirent => dirent.isDirectory()) .map(dirent => dirent.name); return packages; } catch { return []; } } async function detectNxServices(realmPath) { // Simplified - in production you'd parse nx.json or workspace.json const services = []; for (const dir of ['apps', 'libs', 'packages']) { try { const { readdirSync } = await import('fs'); const dirs = readdirSync(join(realmPath, dir), { withFileTypes: true }) .filter(dirent => dirent.isDirectory()) .map(dirent => dirent.name); services.push(...dirs); } catch { // Directory doesn't exist } } return services; } async function detectCargoWorkspaceMembers(_projectPath, cargoToml) { const match = cargoToml.match(/members\s*=\s*\[([\s\S]*?)\]/); if (!match) return []; const membersString = match[1]; if (!membersString) return []; const members = membersString .split(',') .map(m => m.trim().replace(/["']/g, '')) .filter(m => m); return members.map(m => basename(m)); } async function fileExists(path) { try { const { access } = await import('fs/promises'); await access(path); return true; } catch { return false; } } //# sourceMappingURL=realm.js.map