export interface SiteClientOptions {
    baseUrl?: string;
    apiPath?: string;
    apiKey?: string;
    fetch?: typeof fetch;
}
export interface LayoutVariant<T = Record<string, unknown>> {
    id: string;
    collection: string;
    data: T;
}
/** Resolved post author summary (derived server-side from the document creator). */
export interface ResolvePostAuthor {
    name?: string;
    avatarUrl?: string;
}
/** A related-post summary returned alongside post documents. */
export interface ResolveRelatedPost {
    title: string;
    url?: string;
    excerpt?: string;
}
/**
 * The post's featured image with intrinsic dimensions resolved from the media
 * library, so the post header can render a dimensioned, CLS-free LCP image.
 */
export interface ResolveFeaturedImage {
    url: string;
    width?: number | null;
    height?: number | null;
    alt?: string | null;
}
/**
 * Post-specific context the `/resolve` endpoint attaches for `type: 'post'`
 * collections so the public renderer can draw the author bio + related posts
 * without a second request.
 */
export interface ResolvePostContext {
    author?: ResolvePostAuthor | null;
    relatedPosts?: ResolveRelatedPost[];
    /** Featured image + intrinsic dimensions (CLS-safe LCP header). */
    featuredImage?: ResolveFeaturedImage;
}
/** Active-preview metadata when resolving with a valid preview token. */
export interface ResolvePreview {
    active: boolean;
    expiresAt?: string;
}
export interface ResolveResult<T = Record<string, unknown>> {
    data: {
        id: string;
        collection: string;
        data: T;
        status?: string;
        publishedAt?: string | null;
        structuredData?: unknown;
    };
    /** Composed SEO summary (title/description/canonical) from cms-core. */
    meta?: {
        title?: string;
        description?: string;
        canonical?: string;
    };
    /**
     * Next.js `generateMetadata()`-compatible object composed server-side so a
     * consumer can spread it directly into its `generateMetadata` return.
     */
    metadata?: Record<string, unknown>;
    /** Validated JSON-LD object to inject as `<script type="application/ld+json">`. */
    jsonLd?: Record<string, unknown> | null;
    /** Pre-escaped JSON-LD `<script>` body, ready to inject without re-stringifying. */
    jsonLdHtml?: string | null;
    /** Post-type template config (e.g. the design-driven header layout). */
    template?: {
        header?: unknown;
    };
    /** Author + related-post context for `type: 'post'` documents. */
    post?: ResolvePostContext;
    /** Present only when resolving with a valid preview token. */
    preview?: ResolvePreview;
    layout?: Record<string, LayoutVariant>;
}
export interface ResolvedMedia {
    id?: string;
    url: string;
    alt: string | null;
    title: string | null;
    width: number | null;
    height: number | null;
    storageKey: string | null;
}
export type MediaInput = string | {
    id?: unknown;
    url?: unknown;
    alt?: unknown;
    title?: unknown;
    width?: unknown;
    height?: unknown;
    storageKey?: unknown;
} | null | undefined;
export interface ResolveMediaOptions {
    resolveById?: (id: string) => Promise<MediaInput>;
}
/** A public navigation item — a label/url with optional target + children. */
export interface PublicNavItem {
    label: string;
    url: string;
    target?: '_blank' | '_self';
    children?: PublicNavItem[];
}
/** A resolved public navigation menu returned by `/public/navigations/:slug`. */
export interface PublicNavigation {
    name: string;
    slug: string;
    location: string | null;
    items: PublicNavItem[];
}
export interface ResolveDocumentOptions {
    /**
     * Signed preview token (from `POST /preview/token`). When present the
     * resolver drops the `PUBLISHED` filter for the one document the token is
     * bound to, so a consumer route can render drafts at their real URL —
     * forward `?preview=` from the page's search params.
     */
    previewToken?: string | null;
}
export interface SiteClient {
    getGlobal<T = Record<string, unknown>>(slug: string): Promise<T | null>;
    resolveDocument<T = Record<string, unknown>>(path: string, options?: ResolveDocumentOptions): Promise<ResolveResult<T> | null>;
    /**
     * Fetch a public navigation menu by slug. Returns `null` when no navigation
     * with that slug exists (or the navigation plugin isn't installed).
     */
    getNavigation(slug: string): Promise<PublicNavigation | null>;
}
/**
 * Coerce stored navigation `data.items` (open JSON) into a clean public tree.
 * Drops anything without a usable label, defends against deep recursion, and
 * strips fields a public consumer shouldn't need (e.g. internal ids). Shared by
 * the public REST handler and the DB-backed server client so both expose an
 * identical shape.
 */
export declare function coercePublicNavItems(value: unknown, depth?: number): PublicNavItem[];
export declare function createSiteClient(options?: SiteClientOptions): SiteClient;
export declare function normalizeMedia(value: MediaInput): ResolvedMedia | null;
export declare function resolveMedia(value: MediaInput, options?: ResolveMediaOptions): Promise<ResolvedMedia | null>;
//# sourceMappingURL=site.d.ts.map