import { validateSlug } from '../content/slug.js';
/**
 * Resolve the configured gate mode. Defaults to `block` — a published page that
 * fails a hard invariant is a defect, and the whole point of the gate is to
 * stop it server-side. Operators can relax to `warn` (log only) or `off`.
 */
export function resolvePublishValidationMode(config) {
    const mode = config?.seo?.publishValidation;
    return mode === 'warn' || mode === 'off' ? mode : 'block';
}
/**
 * Only publicly-routed content is gated. A collection qualifies when it is
 * explicitly typed `page` or `post`; everything else (internal singletons,
 * untyped/utility collections, forms with their own lifecycle) is skipped.
 */
export function isGatedContentCollection(collectionDef) {
    const type = collectionDef?.type;
    return type === 'page' || type === 'post';
}
function firstNonEmptyString(...candidates) {
    for (const c of candidates) {
        if (typeof c === 'string' && c.trim().length > 0)
            return c.trim();
    }
    return undefined;
}
/**
 * Validate a document that is about to be (or remain) published. `data` is the
 * full, merged document data as it will be stored.
 */
export function validatePublishableDocument(params) {
    const errors = [];
    const warnings = [];
    const data = params.data ?? {};
    const page = data.pageSettings ?? {};
    const title = firstNonEmptyString(data.metaTitle, page.metaTitle, data.title, page.title);
    if (!title) {
        errors.push('A published page needs a title.');
    }
    const slug = firstNonEmptyString(data.slug);
    const path = firstNonEmptyString(data.path);
    if (!slug && !path) {
        errors.push('A published page needs a slug or path so it has a public URL.');
    }
    const slugError = validateSlug(slug);
    if (slugError) {
        errors.push(slugError);
    }
    const description = firstNonEmptyString(data.metaDescription, page.metaDescription, data.excerpt, data.description);
    if (!description) {
        warnings.push('No meta description — search engines will generate a snippet for you.');
    }
    return { errors, warnings };
}
/**
 * Run the gate for a publish and apply the configured mode. Throws a single
 * combined error in `block` mode when there are hard errors; logs (non-test)
 * in `warn` mode; no-ops in `off` mode. Returns the raw result so callers can
 * surface warnings.
 */
export function enforcePublishValidation(params) {
    const empty = { errors: [], warnings: [] };
    const mode = resolvePublishValidationMode(params.config);
    if (mode === 'off' || !isGatedContentCollection(params.collectionDef))
        return empty;
    const result = validatePublishableDocument({ data: params.data });
    if (result.errors.length > 0 && mode === 'block') {
        throw new Error(`Cannot publish — ${result.errors.join(' ')}`);
    }
    if (result.errors.length > 0 && mode === 'warn' && process.env.NODE_ENV !== 'test') {
        console.warn('[actuate] publish validation (warn mode):', result.errors.join(' '));
    }
    return result;
}
//# sourceMappingURL=publish.js.map