/**
 * Content File Reader
 *
 * Reads content from the file system for push operations.
 * Mirrors the structure created by writer.ts.
 */
import type { NavigationLinkInput } from '@riverbankcms/api';
import type { Theme } from '../../contracts';
export interface LocalEntry {
    identifier: string;
    data: Record<string, unknown>;
    status?: 'draft' | 'published';
    hasUnpublishedChanges?: boolean;
    slug?: string;
}
export declare class LegacyEntryTitleError extends Error {
    readonly filePath: string;
    constructor(filePath: string);
}
export interface LocalEntriesFile {
    contentType: string;
    entries: LocalEntry[];
}
export interface LocalBlock {
    identifier: string;
    kind: string;
    position?: number;
    data: Record<string, unknown>;
}
export interface LocalPage {
    identifier: string;
    title: string;
    path: string;
    status?: 'draft' | 'published';
    hasUnpublishedChanges?: boolean;
    blocks?: LocalBlock[];
    seoTitle?: string;
    seoDescription?: string;
    updatedAt?: string;
}
/**
 * Navigation link types for local navigation files.
 *
 * These types are aligned with the API NavigationLinkInput contract
 * to keep SDK file formats and management validation in sync.
 */
export type LocalNavigationLinkType = NavigationLinkInput;
export interface LocalNavigationItem {
    label: string;
    /** Link configuration. Required for non-dropdown items. */
    link?: LocalNavigationLinkType;
    /** Whether this item should render as a CTA-style navigation action. */
    isCta?: boolean;
    children?: LocalNavigationItem[];
}
export interface LocalNavigationMenu {
    identifier?: string | null;
    name: string;
    isPrimary?: boolean;
    isFooter?: boolean;
    items: LocalNavigationItem[];
}
export interface LocalNavigation {
    menus: LocalNavigationMenu[];
}
export interface LocalSettings {
    homepageId?: string | null;
    seoDefaults?: {
        title?: string;
        description?: string;
        ogImage?: string;
        allowIndexingInProduction?: boolean;
    } | null;
    logoIdentifier?: string | null;
    faviconIdentifier?: string | null;
}
export interface LocalFormField {
    id: string;
    label: string;
    type: string;
    required?: boolean;
    placeholder?: string;
    helpText?: string;
    options?: Array<{
        value: string;
        label: string;
    }>;
    multiple?: boolean;
    minLength?: number;
    maxLength?: number;
    pattern?: string;
    min?: number;
    max?: number;
}
export interface LocalFormSchema {
    version?: string;
    fields: LocalFormField[];
}
export type LocalFormSettings = Record<string, unknown>;
export interface LocalForm {
    slug: string;
    name: string;
    schema: LocalFormSchema;
    settings: LocalFormSettings;
}
export interface LocalTheme {
    /** Filename without .json extension */
    name: string;
    /** Full theme object matching themeSchema */
    theme: Theme;
}
/**
 * Local footer content structure.
 * Stored in content/footer.json.
 *
 * Footer links are managed via navigation (footer menu), not this file.
 */
export interface LocalFooterContent {
    /** Rich text content in ProseMirror JSON format. Set to null to clear. */
    bottomText?: Record<string, unknown> | null;
}
export interface LocalVenueAddress {
    line1?: string | null;
    line2?: string | null;
    city?: string | null;
    region?: string | null;
    postcode?: string | null;
    country?: string | null;
}
export interface LocalVenueLocation {
    lat?: number;
    lng?: number;
}
export interface LocalVenue {
    slug: string;
    title: string;
    description?: string | null;
    timezone?: string | null;
    capacity?: number | null;
    address?: LocalVenueAddress;
    location?: LocalVenueLocation | null;
    mapEmbed?: string | null;
}
export interface LocalEventCategory {
    identifier: string;
    name: string;
    description?: string | null;
    color?: string | null;
    sortOrder?: number;
}
export interface LocalEventSchedule {
    recurrenceRule?: string | null;
    startDate?: string | null;
    defaultStartTime?: string | null;
    durationMinutes?: number | null;
}
export interface LocalEventPricing {
    requiresPayment?: boolean;
    priceAmount?: number | null;
    priceCurrency?: string;
    priceDisplay?: string | null;
    acceptsPasses?: boolean;
    acceptsMemberships?: boolean;
}
export interface LocalEventContent {
    summary?: string | null;
    body?: string | Record<string, unknown> | null;
    image?: string | Record<string, unknown> | null;
}
export interface LocalEvent {
    identifier: string;
    title: string;
    slug: string;
    status?: 'draft' | 'active' | 'archived' | 'cancelled' | 'completed';
    visibility?: 'private' | 'public' | 'unlisted';
    schedule?: LocalEventSchedule;
    capacity?: number | null;
    pricing?: LocalEventPricing;
    venueRef?: string | null;
    categoryRef?: string | null;
    content?: LocalEventContent;
    formRef?: string | null;
    settings?: Record<string, unknown>;
    presentation?: Record<string, unknown> | null;
    tags?: string[];
}
export interface LocalCourseSession {
    startsAt: string;
    endsAt: string;
}
export interface LocalCourseProgram {
    identifier?: string | null;
    data: Record<string, unknown>;
}
export interface LocalCourse {
    identifier: string;
    title: string;
    slug: string;
    status?: 'draft' | 'active' | 'cancelled' | 'completed';
    visibility?: 'private' | 'public' | 'unlisted';
    venueRef?: string | null;
    categoryRef?: string | null;
    formRef?: string | null;
    capacity?: number | null;
    enrollmentCapacity?: number | null;
    acceptsMemberships?: boolean;
    priceCents?: number | null;
    currency?: string;
    sessions: LocalCourseSession[];
    programRef?: string | null;
    program?: LocalCourseProgram | null;
}
/**
 * Check if old format entry files exist (for migration warning)
 *
 * @param contentDir - Base content directory
 * @returns Array of old format file paths found
 */
export declare function findLegacyEntryFiles(contentDir: string): Promise<string[]>;
/**
 * Read entries from content directory
 *
 * Format: content/entries/{contentType}/{identifier}.json (one file per entry)
 *
 * This is the new directory format. Old format (one file per content type)
 * is no longer supported. Run `riverbankcms migrate entries` (recommended) or `riverbankcms pull entries` to migrate.
 *
 * @param contentDir - Base content directory
 * @param contentType - Optional specific content type to read
 * @returns Map of content type to entries
 */
export declare function readEntries(contentDir: string, contentType?: string): Promise<Map<string, LocalEntry[]>>;
/**
 * Read pages from content directory
 *
 * Format: content/pages/{identifier}.json
 *
 * @param contentDir - Base content directory
 * @returns Array of local pages
 */
export declare function readPages(contentDir: string): Promise<LocalPage[]>;
/**
 * Read navigation from content directory
 *
 * Format: content/navigation.json
 *
 * @param contentDir - Base content directory
 * @returns Navigation menus or null if not found
 */
export declare function readNavigation(contentDir: string): Promise<LocalNavigation | null>;
/**
 * Read settings from content directory
 *
 * Format: content/settings.json
 *
 * @param contentDir - Base content directory
 * @returns Settings or null if not found
 */
export declare function readSettings(contentDir: string): Promise<LocalSettings | null>;
/**
 * Read forms from content directory
 *
 * Format: content/forms/{slug}.json
 *
 * @param contentDir - Base content directory
 * @returns Array of local forms
 */
export declare function readForms(contentDir: string): Promise<LocalForm[]>;
/**
 * Read venues from content directory
 *
 * Format: content/venues/{slug}.json
 *
 * @param contentDir - Base content directory
 * @returns Array of local venues
 */
export declare function readVenues(contentDir: string): Promise<LocalVenue[]>;
/**
 * Read event categories from content directory
 *
 * Format: content/event-categories/{identifier}.json
 *
 * @param contentDir - Base content directory
 * @returns Array of local event categories
 */
export declare function readEventCategories(contentDir: string): Promise<LocalEventCategory[]>;
/**
 * Read events from content directory
 *
 * Format: content/events/{identifier}.json
 *
 * @param contentDir - Base content directory
 * @returns Array of local events
 */
export declare function readEvents(contentDir: string): Promise<LocalEvent[]>;
/**
 * Read courses from content directory
 *
 * Format: content/courses/{identifier}.json
 *
 * @param contentDir - Base content directory
 * @returns Array of local courses
 */
export declare function readCourses(contentDir: string): Promise<LocalCourse[]>;
/**
 * Read a single theme by name from content directory
 *
 * Format: content/themes/{name}.json
 *
 * @param contentDir - Base content directory
 * @param themeName - Theme name (filename without .json)
 * @returns Local theme or null if not found
 */
export declare function readTheme(contentDir: string, themeName: string): Promise<LocalTheme | null>;
/**
 * Read all themes from content directory
 *
 * Format: content/themes/*.json
 *
 * @param contentDir - Base content directory
 * @returns Array of local themes
 */
export declare function readThemes(contentDir: string): Promise<LocalTheme[]>;
/**
 * Read footer content from content directory
 *
 * Format: content/footer.json
 *
 * @param contentDir - Base content directory
 * @returns Footer content or null if not found
 */
export declare function readFooter(contentDir: string): Promise<LocalFooterContent | null>;
/**
 * Read all content from content directory
 */
export interface LocalContent {
    entries: Map<string, LocalEntry[]>;
    pages: LocalPage[];
    navigation: LocalNavigation | null;
    settings: LocalSettings | null;
    forms: LocalForm[];
    footer: LocalFooterContent | null;
    venues: LocalVenue[];
    eventCategories: LocalEventCategory[];
    events: LocalEvent[];
    courses: LocalCourse[];
}
export declare function readAllContent(contentDir: string): Promise<LocalContent>;
/**
 * Check if content directory exists and has content
 */
export declare function contentDirExists(contentDir: string): Promise<boolean>;
/**
 * Get summary of content in directory
 */
export interface ContentSummary {
    hasEntries: boolean;
    entryTypes: string[];
    totalEntries: number;
    hasPages: boolean;
    pageCount: number;
    hasNavigation: boolean;
    menuCount: number;
    hasSettings: boolean;
    hasForms: boolean;
    formCount: number;
    hasVenues: boolean;
    venueCount: number;
    hasEventCategories: boolean;
    eventCategoryCount: number;
    hasEvents: boolean;
    eventCount: number;
    hasCourses: boolean;
    courseCount: number;
}
export declare function getContentSummary(contentDir: string): Promise<ContentSummary>;
export interface EntryMetadata {
    pulledAt: string;
    entries: Record<string, {
        id?: string;
        createdAt?: string;
        updatedAt?: string;
        publishedAt?: string;
    }>;
}
export interface PagesMetadata {
    pulledAt: string;
    pages: Record<string, {
        createdAt?: string;
        updatedAt?: string;
    }>;
}
export interface NavigationMetadata {
    pulledAt: string;
    menus: Record<string, {
        createdAt?: string;
        updatedAt?: string;
    }>;
}
/**
 * Read metadata for a content type from .meta/ directory
 *
 * @param contentDir - Base content directory
 * @param contentType - Content type to read metadata for
 * @returns Metadata or null if not found
 */
export declare function readEntriesMeta(contentDir: string, contentType: string): Promise<EntryMetadata | null>;
/**
 * Read all entry metadata files from .meta/ directory
 *
 * @param contentDir - Base content directory
 * @returns Map of content type to metadata
 */
export declare function readAllMeta(contentDir: string): Promise<Map<string, EntryMetadata>>;
/**
 * Read pages metadata from .meta/pages.json
 *
 * @param contentDir - Base content directory
 * @returns Pages metadata or null if not found
 */
export declare function readPagesMeta(contentDir: string): Promise<PagesMetadata | null>;
/**
 * Read navigation metadata from .meta/navigation.json
 *
 * @param contentDir - Base content directory
 * @returns Navigation metadata or null if not found
 */
export declare function readNavigationMeta(contentDir: string): Promise<NavigationMetadata | null>;
export interface FormsMetadata {
    pulledAt: string;
    forms: Record<string, {
        createdAt?: string;
        updatedAt?: string;
    }>;
}
/**
 * Read forms metadata from .meta/forms.json
 *
 * @param contentDir - Base content directory
 * @returns Forms metadata or null if not found
 */
export declare function readFormsMeta(contentDir: string): Promise<FormsMetadata | null>;
export interface ThemesMetadata {
    pulledAt: string;
    themes: Record<string, {
        themeId: string;
        selectionId: string;
        updatedAt: string;
    }>;
}
/**
 * Read themes metadata from .meta/themes.json
 *
 * @param contentDir - Base content directory
 * @returns Themes metadata or null if not found
 */
export declare function readThemesMeta(contentDir: string): Promise<ThemesMetadata | null>;
export interface VenuesMetadata {
    pulledAt: string;
    venues: Record<string, {
        createdAt?: string;
        updatedAt?: string;
    }>;
}
/**
 * Read venues metadata from .meta/venues.json
 *
 * @param contentDir - Base content directory
 * @returns Venues metadata or null if not found
 */
export declare function readVenuesMeta(contentDir: string): Promise<VenuesMetadata | null>;
export interface EventCategoriesMetadata {
    pulledAt: string;
    eventCategories: Record<string, {
        createdAt?: string;
        updatedAt?: string;
    }>;
}
/**
 * Read event categories metadata from .meta/event-categories.json
 *
 * @param contentDir - Base content directory
 * @returns Event categories metadata or null if not found
 */
export declare function readEventCategoriesMeta(contentDir: string): Promise<EventCategoriesMetadata | null>;
export interface EventsMetadata {
    pulledAt: string;
    events: Record<string, {
        createdAt?: string;
        updatedAt?: string;
    }>;
}
export interface CoursesMetadata {
    pulledAt: string;
    courses: Record<string, {
        createdAt?: string;
        updatedAt?: string;
    }>;
}
/**
 * Read events metadata from .meta/events.json
 *
 * @param contentDir - Base content directory
 * @returns Events metadata or null if not found
 */
export declare function readEventsMeta(contentDir: string): Promise<EventsMetadata | null>;
/**
 * Read courses metadata from .meta/courses.json
 *
 * @param contentDir - Base content directory
 * @returns Courses metadata or null if not found
 */
export declare function readCoursesMeta(contentDir: string): Promise<CoursesMetadata | null>;
export interface FooterMetadata {
    pulledAt: string;
    updatedAt?: string;
}
/**
 * Read footer metadata from .meta/footer.json
 *
 * @param contentDir - Base content directory
 * @returns Footer metadata or null if not found
 */
export declare function readFooterMeta(contentDir: string): Promise<FooterMetadata | null>;
