import * as _btst_stack_plugins_client from '@btst/stack/plugins/client';
import * as react from 'react';
import { ComponentType } from 'react';
import * as _btst_yar from '@btst/yar';
import { QueryClient } from '@tanstack/react-query';
import { P as Post, S as SerializedPost } from '../../../shared/stack.BWp0hcm9.js';
export { UsePostsOptions, UsePostsResult } from './hooks/index.js';
import 'zod';

/**
 * Context passed to route hooks
 */
interface RouteContext$1 {
    /** Current route path */
    path: string;
    /** Route parameters (e.g., { slug: "my-post" }) */
    params?: Record<string, string>;
    /** Whether rendering on server (true) or client (false) */
    isSSR: boolean;
    /** Additional context properties */
    [key: string]: any;
}
/**
 * Context passed to loader hooks
 */
interface LoaderContext {
    /** Current route path */
    path: string;
    /** Route parameters (e.g., { slug: "my-post" }) */
    params?: Record<string, string>;
    /** Whether rendering on server (true) or client (false) */
    isSSR: boolean;
    /** Base URL for API calls */
    apiBaseURL: string;
    /** Path where the API is mounted */
    apiBasePath: string;
    /** Optional headers for the request */
    headers?: Headers;
    /** Additional context properties */
    [key: string]: any;
}
/**
 * Configuration for blog client plugin
 * Note: queryClient is passed at runtime to both loader and meta (for SSR isolation)
 */
interface BlogClientConfig {
    /** Base URL for API calls (e.g., "http://localhost:3000") */
    apiBaseURL: string;
    /** Path where the API is mounted (e.g., "/api/data") */
    apiBasePath: string;
    /** Base URL of your site for SEO meta tags */
    siteBaseURL: string;
    /** Path where pages are mounted (e.g., "/pages") */
    siteBasePath: string;
    /** React Query client instance for caching */
    queryClient: QueryClient;
    /** Optional SEO configuration for meta tags */
    seo?: {
        /** Site name for Open Graph tags */
        siteName?: string;
        /** Default author name */
        author?: string;
        /** Twitter handle (e.g., "@yourhandle") */
        twitterHandle?: string;
        /** Locale for Open Graph (e.g., "en_US") */
        locale?: string;
        /** Default image URL for social sharing */
        defaultImage?: string;
    };
    /** Optional hooks for customizing behavior */
    hooks?: BlogClientHooks;
    /** Optional headers for SSR (e.g., forwarding cookies) */
    headers?: Headers;
}
/**
 * Hooks for blog client plugin
 * All hooks are optional and allow consumers to customize behavior
 */
interface BlogClientHooks {
    /**
     * Called before loading posts list. Throw an error to cancel loading.
     * @param filter - Filter parameters including published status
     * @param context - Loader context with path, params, etc.
     */
    beforeLoadPosts?: (filter: {
        published: boolean;
    }, context: LoaderContext) => Promise<void> | void;
    /**
     * Called after posts are loaded. Throw an error to cancel further processing.
     * @param posts - Array of loaded posts or null
     * @param filter - Filter parameters used
     * @param context - Loader context
     */
    afterLoadPosts?: (posts: Post[] | null, filter: {
        published: boolean;
    }, context: LoaderContext) => Promise<void> | void;
    /**
     * Called before loading a single post. Throw an error to cancel loading.
     * @param slug - Post slug being loaded
     * @param context - Loader context
     */
    beforeLoadPost?: (slug: string, context: LoaderContext) => Promise<void> | void;
    /**
     * Called after a post is loaded. Throw an error to cancel further processing.
     * @param post - Loaded post or null if not found
     * @param slug - Post slug that was requested
     * @param context - Loader context
     */
    afterLoadPost?: (post: Post | null, slug: string, context: LoaderContext) => Promise<void> | void;
    /**
     * Called before loading the new post page. Throw an error to cancel.
     * @param context - Loader context
     */
    beforeLoadNewPost?: (context: LoaderContext) => Promise<void> | void;
    /**
     * Called after the new post page is loaded. Throw an error to cancel.
     * @param context - Loader context
     */
    afterLoadNewPost?: (context: LoaderContext) => Promise<void> | void;
    /**
     * Called when a loading error occurs
     * @param error - The error that occurred
     * @param context - Loader context
     */
    onLoadError?: (error: Error, context: LoaderContext) => Promise<void> | void;
}
/**
 * Blog client plugin
 * Provides routes, components, and React Query hooks for blog posts
 *
 * @param config - Configuration including queryClient, baseURL, and optional hooks
 */
declare const blogClientPlugin: (config: BlogClientConfig) => _btst_stack_plugins_client.ClientPlugin<Record<string, never>, {
    posts: {
        (inputCtx_0?: _btst_yar.InputContext<"/blog", _btst_yar.RouteOptions> | undefined): {
            PageComponent?: react.ComponentType<unknown> | undefined;
            LoadingComponent?: react.ComponentType<unknown> | undefined;
            ErrorComponent?: react.ComponentType<unknown> | undefined;
            loader?: (() => Promise<void>) | undefined;
            meta?: (() => ({
                title: string;
                name?: undefined;
                content?: undefined;
                property?: undefined;
            } | {
                name: string;
                content: string;
                title?: undefined;
                property?: undefined;
            } | {
                property: string;
                content: string;
                title?: undefined;
                name?: undefined;
            })[]) | undefined;
            extra?: (() => any) | undefined;
        };
        options: _btst_yar.RouteOptions | undefined;
        path: "/blog";
        meta: _btst_yar.RouteMeta | undefined;
    };
    drafts: {
        (inputCtx_0?: _btst_yar.InputContext<"/blog/drafts", _btst_yar.RouteOptions> | undefined): {
            PageComponent?: react.ComponentType<unknown> | undefined;
            LoadingComponent?: react.ComponentType<unknown> | undefined;
            ErrorComponent?: react.ComponentType<unknown> | undefined;
            loader?: (() => Promise<void>) | undefined;
            meta?: (() => ({
                title: string;
                name?: undefined;
                content?: undefined;
                property?: undefined;
            } | {
                name: string;
                content: string;
                title?: undefined;
                property?: undefined;
            } | {
                property: string;
                content: string;
                title?: undefined;
                name?: undefined;
            })[]) | undefined;
            extra?: (() => any) | undefined;
        };
        options: _btst_yar.RouteOptions | undefined;
        path: "/blog/drafts";
        meta: _btst_yar.RouteMeta | undefined;
    };
    newPost: {
        (inputCtx_0?: _btst_yar.InputContext<"/blog/new", _btst_yar.RouteOptions> | undefined): {
            PageComponent?: react.ComponentType<unknown> | undefined;
            LoadingComponent?: react.ComponentType<unknown> | undefined;
            ErrorComponent?: react.ComponentType<unknown> | undefined;
            loader?: (() => Promise<void>) | undefined;
            meta?: (() => ({
                title: string;
                name?: undefined;
                content?: undefined;
                property?: undefined;
            } | {
                name: string;
                content: string;
                title?: undefined;
                property?: undefined;
            } | {
                property: string;
                content: string;
                title?: undefined;
                name?: undefined;
            })[]) | undefined;
            extra?: (() => any) | undefined;
        };
        options: _btst_yar.RouteOptions | undefined;
        path: "/blog/new";
        meta: _btst_yar.RouteMeta | undefined;
    };
    editPost: {
        (inputCtx_0: _btst_yar.InputContext<"/blog/:slug/edit", _btst_yar.RouteOptions>): {
            PageComponent?: react.ComponentType<unknown> | undefined;
            LoadingComponent?: react.ComponentType<unknown> | undefined;
            ErrorComponent?: react.ComponentType<unknown> | undefined;
            loader?: (() => Promise<void>) | undefined;
            meta?: (() => ({
                title: string;
                name?: undefined;
                content?: undefined;
                property?: undefined;
            } | {
                name: string;
                content: string;
                title?: undefined;
                property?: undefined;
            } | {
                property: string;
                content: string;
                title?: undefined;
                name?: undefined;
            })[]) | undefined;
            extra?: (() => any) | undefined;
        };
        options: _btst_yar.RouteOptions | undefined;
        path: "/blog/:slug/edit";
        meta: _btst_yar.RouteMeta | undefined;
    };
    tag: {
        (inputCtx_0: _btst_yar.InputContext<"/blog/tag/:tagSlug", _btst_yar.RouteOptions>): {
            PageComponent?: react.ComponentType<unknown> | undefined;
            LoadingComponent?: react.ComponentType<unknown> | undefined;
            ErrorComponent?: react.ComponentType<unknown> | undefined;
            loader?: (() => Promise<void>) | undefined;
            meta?: (() => ({
                title: string;
                name?: undefined;
                content?: undefined;
                property?: undefined;
            } | {
                name: string;
                content: string;
                title?: undefined;
                property?: undefined;
            } | {
                property: string;
                content: string;
                title?: undefined;
                name?: undefined;
            })[]) | undefined;
            extra?: (() => any) | undefined;
        };
        options: _btst_yar.RouteOptions | undefined;
        path: "/blog/tag/:tagSlug";
        meta: _btst_yar.RouteMeta | undefined;
    };
    post: {
        (inputCtx_0: _btst_yar.InputContext<"/blog/:slug", _btst_yar.RouteOptions>): {
            PageComponent?: react.ComponentType<unknown> | undefined;
            LoadingComponent?: react.ComponentType<unknown> | undefined;
            ErrorComponent?: react.ComponentType<unknown> | undefined;
            loader?: (() => Promise<void>) | undefined;
            meta?: (() => ({
                title: string;
                name?: undefined;
                content?: undefined;
                property?: undefined;
            } | {
                name: string;
                content: string | undefined;
                title?: undefined;
                property?: undefined;
            } | {
                property: string;
                content: string;
                title?: undefined;
                name?: undefined;
            })[]) | undefined;
            extra?: (() => any) | undefined;
        };
        options: _btst_yar.RouteOptions | undefined;
        path: "/blog/:slug";
        meta: _btst_yar.RouteMeta | undefined;
    };
}>;

declare const BLOG_LOCALIZATION: {
    BLOG_FORMS_TITLE_LABEL: string;
    BLOG_FORMS_REQUIRED_ASTERISK: string;
    BLOG_FORMS_TITLE_PLACEHOLDER: string;
    BLOG_FORMS_SLUG_LABEL: string;
    BLOG_FORMS_SLUG_PLACEHOLDER: string;
    BLOG_FORMS_EXCERPT_LABEL: string;
    BLOG_FORMS_EXCERPT_PLACEHOLDER: string;
    BLOG_FORMS_TAGS_LABEL: string;
    BLOG_FORMS_TAGS_PLACEHOLDER: string;
    BLOG_FORMS_CONTENT_LABEL: string;
    BLOG_FORMS_PUBLISHED_LABEL: string;
    BLOG_FORMS_PUBLISHED_DESCRIPTION: string;
    BLOG_FORMS_SUBMIT_CREATE_IDLE: string;
    BLOG_FORMS_SUBMIT_CREATE_PENDING: string;
    BLOG_FORMS_SUBMIT_UPDATE_IDLE: string;
    BLOG_FORMS_SUBMIT_UPDATE_PENDING: string;
    BLOG_FORMS_CANCEL_BUTTON: string;
    BLOG_FORMS_TOAST_CREATE_SUCCESS: string;
    BLOG_FORMS_TOAST_UPDATE_SUCCESS: string;
    BLOG_FORMS_TOAST_DELETE_SUCCESS: string;
    BLOG_FORMS_LOADING_POST: string;
    BLOG_FORMS_DELETE_BUTTON: string;
    BLOG_FORMS_DELETE_DIALOG_TITLE: string;
    BLOG_FORMS_DELETE_DIALOG_DESCRIPTION: string;
    BLOG_FORMS_DELETE_DIALOG_CANCEL: string;
    BLOG_FORMS_DELETE_DIALOG_CONFIRM: string;
    BLOG_FORMS_DELETE_PENDING: string;
    BLOG_FORMS_EDITOR_PLACEHOLDER: string;
    BLOG_FORMS_FEATURED_IMAGE_LABEL: string;
    BLOG_FORMS_FEATURED_IMAGE_REQUIRED_ASTERISK: string;
    BLOG_FORMS_FEATURED_IMAGE_INPUT_PLACEHOLDER: string;
    BLOG_FORMS_FEATURED_IMAGE_UPLOAD_BUTTON: string;
    BLOG_FORMS_FEATURED_IMAGE_UPLOADING_BUTTON: string;
    BLOG_FORMS_FEATURED_IMAGE_UPLOADING_TEXT: string;
    BLOG_FORMS_FEATURED_IMAGE_PREVIEW_ALT: string;
    BLOG_FORMS_FEATURED_IMAGE_ERROR_NOT_IMAGE: string;
    BLOG_FORMS_FEATURED_IMAGE_ERROR_TOO_LARGE: string;
    BLOG_FORMS_FEATURED_IMAGE_TOAST_SUCCESS: string;
    BLOG_FORMS_FEATURED_IMAGE_TOAST_FAILURE: string;
    BLOG_POST_ADD_TITLE: string;
    BLOG_POST_ADD_DESCRIPTION: string;
    BLOG_POST_EDIT_TITLE: string;
    BLOG_POST_EDIT_DESCRIPTION: string;
    BLOG_POST_ON_THIS_PAGE: string;
    BLOG_POST_KEEP_READING: string;
    BLOG_POST_VIEW_ALL: string;
    BLOG_CARD_DRAFT_BADGE: string;
    BLOG_LIST_TITLE: string;
    BLOG_LIST_DRAFTS_TITLE: string;
    BLOG_LIST_EMPTY: string;
    BLOG_LIST_LOAD_MORE: string;
    BLOG_LIST_LOADING_MORE: string;
    BLOG_LIST_SEARCH_PLACEHOLDER: string;
    BLOG_LIST_SEARCH_BUTTON: string;
    BLOG_LIST_SEARCH_EMPTY: string;
    BLOG_TAG_PAGE_TITLE: string;
    BLOG_TAG_PAGE_DESCRIPTION: string;
    BLOG_TAG_NOT_FOUND: string;
    BLOG_TAG_NOT_FOUND_DESCRIPTION: string;
    BLOG_GENERIC_ERROR_TITLE: string;
    BLOG_GENERIC_ERROR_MESSAGE: string;
    BLOG_PAGE_NOT_FOUND_TITLE: string;
    BLOG_PAGE_NOT_FOUND_DESCRIPTION: string;
};
type BlogLocalization = typeof BLOG_LOCALIZATION;

/**
 * Context passed to lifecycle hooks
 */
interface RouteContext {
    /** Current route path */
    path: string;
    /** Route parameters (e.g., { slug: "my-post" }) */
    params?: Record<string, string>;
    /** Whether rendering on server (true) or client (false) */
    isSSR: boolean;
    /** Additional context properties */
    [key: string]: any;
}
/**
 * Overridable components and functions for the Blog plugin
 *
 * External consumers can provide their own implementations of these
 * to customize the behavior for their framework (Next.js, React Router, etc.)
 */
interface BlogPluginOverrides {
    /**
     * Link component for navigation
     */
    Link?: ComponentType<React.ComponentProps<"a"> & Record<string, any>>;
    /**
     * Post card component for displaying a post
     */
    PostCard?: ComponentType<{
        post: SerializedPost;
    }>;
    /**
     * Navigation function for programmatic navigation
     */
    navigate: (path: string) => void | Promise<void>;
    /**
     * Refresh function to invalidate server-side cache (e.g., Next.js router.refresh())
     */
    refresh?: () => void | Promise<void>;
    /**
     * Image component for displaying images
     */
    Image?: ComponentType<React.ImgHTMLAttributes<HTMLImageElement> & Record<string, any>>;
    /**
     * Function used to upload an image and return its URL.
     */
    uploadImage: (file: File) => Promise<string>;
    /**
     * Localization object for the blog plugin
     */
    localization?: BlogLocalization;
    /**
     * API base URL
     */
    apiBaseURL: string;
    /**
     * API base path
     */
    apiBasePath: string;
    /**
     * Whether to show the attribution
     */
    showAttribution?: boolean;
    /**
     * Optional headers to pass with API requests (e.g., for SSR auth)
     */
    headers?: HeadersInit;
    /**
     * Called when a route is rendered
     * @param routeName - Name of the route (e.g., 'posts', 'post', 'newPost')
     * @param context - Route context with path, params, etc.
     */
    onRouteRender?: (routeName: string, context: RouteContext) => void | Promise<void>;
    /**
     * Called when a route encounters an error
     * @param routeName - Name of the route
     * @param error - The error that occurred
     * @param context - Route context
     */
    onRouteError?: (routeName: string, error: Error, context: RouteContext) => void | Promise<void>;
    /**
     * Called before the posts list page is rendered
     * Return false to prevent rendering (e.g., for authorization)
     * @param context - Route context
     */
    onBeforePostsPageRendered?: (context: RouteContext) => boolean;
    /**
     * Called before a single post page is rendered
     * Return false to prevent rendering (e.g., for authorization)
     * @param slug - The post slug
     * @param context - Route context
     */
    onBeforePostPageRendered?: (slug: string, context: RouteContext) => boolean;
    /**
     * Called before the new post page is rendered
     * Return false to prevent rendering (e.g., for authorization)
     * @param context - Route context
     */
    onBeforeNewPostPageRendered?: (context: RouteContext) => boolean;
    /**
     * Called before the edit post page is rendered
     * Return false to prevent rendering (e.g., for authorization)
     * @param slug - The post slug being edited
     * @param context - Route context
     */
    onBeforeEditPostPageRendered?: (slug: string, context: RouteContext) => boolean;
    /**
     * Called before the drafts page is rendered
     * Return false to prevent rendering (e.g., for authorization)
     * @param context - Route context
     */
    onBeforeDraftsPageRendered?: (context: RouteContext) => boolean;
}

export { blogClientPlugin };
export type { BlogClientConfig, BlogClientHooks, BlogPluginOverrides, LoaderContext, RouteContext$1 as RouteContext };
