feat(health): service registry loader + seed config (fresh titles)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
30
lib/health/registry.js
Normal file
30
lib/health/registry.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const CONFIG = path.join(__dirname, '../../config/services.json');
|
||||
export const CATEGORY_ORDER = ['agents', 'infrastructure', 'media', 'other'];
|
||||
|
||||
let cache = null;
|
||||
export function load() {
|
||||
if (!cache) cache = JSON.parse(readFileSync(CONFIG, 'utf8'));
|
||||
return cache;
|
||||
}
|
||||
export function _reset() { cache = null; } // tests
|
||||
|
||||
export function iconSlug(svc) {
|
||||
return (svc.icon || svc.name).toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
|
||||
}
|
||||
|
||||
export function grouped(services) {
|
||||
const map = new Map();
|
||||
for (const s of services) {
|
||||
const cat = CATEGORY_ORDER.includes(s.category) ? s.category : 'other';
|
||||
if (!map.has(cat)) map.set(cat, []);
|
||||
map.get(cat).push(s);
|
||||
}
|
||||
return [...CATEGORY_ORDER, ...[...map.keys()].filter(c => !CATEGORY_ORDER.includes(c))]
|
||||
.filter(c => map.has(c))
|
||||
.map(category => ({ category, services: map.get(category) }));
|
||||
}
|
||||
Reference in New Issue
Block a user