const DEFAULT_UPDATE_SERVER = 'https://updates.actuatecms.com';
/**
 * Fetch the structured changelog from the update server's `/api/changelog`
 * endpoint. The server URL is overridable via `ACTUATE_UPDATE_SERVER_URL` (a
 * fixed, trusted host — never user input). Pass `fromVersion` to return only
 * releases newer than that version.
 */
export async function fetchChangelog(fromVersion) {
    const base = (process.env.ACTUATE_UPDATE_SERVER_URL ?? DEFAULT_UPDATE_SERVER).replace(/\/+$/, '');
    const url = new URL(`${base}/api/changelog`);
    if (fromVersion)
        url.searchParams.set('from', fromVersion);
    const response = await fetch(url.toString(), { signal: AbortSignal.timeout(10_000) });
    if (!response.ok) {
        throw new Error(`Changelog fetch failed: ${response.status}`);
    }
    return (await response.json());
}
/** Parse a CHANGELOG.md file into structured entries. */
export function parseChangelog(markdown) {
    const entries = [];
    const versionRegex = /^## \[?(\d+\.\d+\.\d+)\]?\s*[-–—]?\s*(\d{4}-\d{2}-\d{2})?/gm;
    let match;
    const positions = [];
    while ((match = versionRegex.exec(markdown)) !== null) {
        positions.push({
            version: match[1],
            date: match[2] ?? '',
            start: match.index + match[0].length,
        });
    }
    for (let i = 0; i < positions.length; i++) {
        const pos = positions[i];
        const end = positions[i + 1]?.start ?? markdown.length;
        const section = markdown.slice(pos.start, end);
        const changes = [];
        const lineRegex = /^[-*]\s+(.+)$/gm;
        let lineMatch;
        while ((lineMatch = lineRegex.exec(section)) !== null) {
            const text = lineMatch[1];
            const type = inferChangeType(text);
            changes.push({ type, description: text });
        }
        entries.push({ version: pos.version, date: pos.date, changes });
    }
    return entries;
}
function inferChangeType(text) {
    const lower = text.toLowerCase();
    if (lower.includes('breaking'))
        return 'breaking';
    if (lower.includes('security'))
        return 'security';
    if (lower.includes('deprecat'))
        return 'deprecation';
    if (lower.includes('fix') || lower.includes('bug'))
        return 'fix';
    return 'feature';
}
//# sourceMappingURL=changelog.js.map