import type { HydrantEvent, HydrantRecordValue, UrlEntry } from './types'; import { sanitizeLastmod } from './xml'; export interface ExtractedAction { type: 'upsert' | 'delete'; url: string; entry?: UrlEntry; } interface CollectionSpec { buildPath: (owner: string, rkey: string, record?: HydrantRecordValue) => string; changefreq: UrlEntry['changefreq']; priority: number; } export const COLLECTION_SPECS: Record = { 'sh.tangled.repo': { buildPath: (owner, rkey, record) => `${owner}/${(record?.name as string) || rkey}`, changefreq: 'daily', priority: 0.8, }, 'sh.tangled.actor.profile': { buildPath: (owner) => owner, changefreq: 'daily', priority: 0.8, }, 'sh.tangled.string': { buildPath: (owner, rkey) => `${owner}/strings/${rkey}`, changefreq: 'weekly', priority: 0.6, }, }; export function resolveIdentity( did: string, explicitHandle?: string, identityMap?: Map, ): string { if (explicitHandle && explicitHandle.trim().length > 0) { if (identityMap) identityMap.set(did, explicitHandle); return explicitHandle; } return identityMap?.get(did) || did; } export function extractUrlAction( event: HydrantEvent, baseUrl: string, identityMap: Map, now = new Date(), ): ExtractedAction | null { if (event.type === 'identity' && event.identity) { if (event.identity.handle) { identityMap.set(event.identity.did, event.identity.handle); } return null; } if (event.type !== 'record' || !event.record) { return null; } const { collection, rkey, action, did, handle, record } = event.record; const spec = COLLECTION_SPECS[collection]; if (!spec) { return null; } const owner = resolveIdentity(did, handle, identityMap); const normalizedBase = baseUrl.replace(/\/+$/, ''); const path = spec.buildPath(owner, rkey, record); const url = `${normalizedBase}/${path}`; if (action === 'delete') { return { type: 'delete', url }; } const lastmod = sanitizeLastmod(record?.createdAt as string | undefined, now); return { type: 'upsert', url, entry: { loc: url, lastmod, changefreq: spec.changefreq, priority: spec.priority, }, }; }