import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
import * as better_call from 'better-call';
import { z } from 'zod';
import { c as createPostSchema, u as updatePostSchema, P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../shared/stack.CcI4sYJP.js';
import * as _tanstack_react_query from '@tanstack/react-query';
import { createApiClient } from '@btst/stack/plugins/client';

declare const PostListQuerySchema: z.ZodObject<{
    slug: z.ZodOptional<z.ZodString>;
    tagSlug: z.ZodOptional<z.ZodString>;
    offset: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
    limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
    query: z.ZodOptional<z.ZodString>;
    published: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<boolean | undefined, string | undefined>>;
}, z.core.$strip>;
declare const NextPreviousPostsQuerySchema: z.ZodObject<{
    date: z.ZodCoercedDate<unknown>;
}, z.core.$strip>;
/**
 * Context passed to blog API hooks
 */
interface BlogApiContext<TBody = any, TParams = any, TQuery = any> {
    body?: TBody;
    params?: TParams;
    query?: TQuery;
    request?: Request;
    headers?: Headers;
    [key: string]: any;
}
/**
 * Configuration hooks for blog backend plugin
 * All hooks are optional and allow consumers to customize behavior
 */
interface BlogBackendHooks {
    /**
     * Called before listing posts. Return false to deny access.
     * @param filter - Query parameters for filtering posts
     * @param context - Request context with headers, etc.
     */
    onBeforeListPosts?: (filter: z.infer<typeof PostListQuerySchema>, context: BlogApiContext) => Promise<boolean> | boolean;
    /**
     * Called before creating a post. Return false to deny access.
     * @param data - Post data being created
     * @param context - Request context with headers, etc.
     */
    onBeforeCreatePost?: (data: z.infer<typeof createPostSchema>, context: BlogApiContext) => Promise<boolean> | boolean;
    /**
     * Called before updating a post. Return false to deny access.
     * @param postId - ID of the post being updated
     * @param data - Updated post data
     * @param context - Request context with headers, etc.
     */
    onBeforeUpdatePost?: (postId: string, data: z.infer<typeof updatePostSchema>, context: BlogApiContext) => Promise<boolean> | boolean;
    /**
     * Called before deleting a post. Return false to deny access.
     * @param postId - ID of the post being deleted
     * @param context - Request context with headers, etc.
     */
    onBeforeDeletePost?: (postId: string, context: BlogApiContext) => Promise<boolean> | boolean;
    /**
     * Called after posts are read successfully
     * @param posts - Array of posts that were read
     * @param filter - Query parameters used for filtering
     * @param context - Request context
     */
    onPostsRead?: (posts: Post[], filter: z.infer<typeof PostListQuerySchema>, context: BlogApiContext) => Promise<void> | void;
    /**
     * Called after a post is created successfully
     * @param post - The created post
     * @param context - Request context
     */
    onPostCreated?: (post: Post, context: BlogApiContext) => Promise<void> | void;
    /**
     * Called after a post is updated successfully
     * @param post - The updated post
     * @param context - Request context
     */
    onPostUpdated?: (post: Post, context: BlogApiContext) => Promise<void> | void;
    /**
     * Called after a post is deleted successfully
     * @param postId - ID of the deleted post
     * @param context - Request context
     */
    onPostDeleted?: (postId: string, context: BlogApiContext) => Promise<void> | void;
    /**
     * Called when listing posts fails
     * @param error - The error that occurred
     * @param context - Request context
     */
    onListPostsError?: (error: Error, context: BlogApiContext) => Promise<void> | void;
    /**
     * Called when creating a post fails
     * @param error - The error that occurred
     * @param context - Request context
     */
    onCreatePostError?: (error: Error, context: BlogApiContext) => Promise<void> | void;
    /**
     * Called when updating a post fails
     * @param error - The error that occurred
     * @param context - Request context
     */
    onUpdatePostError?: (error: Error, context: BlogApiContext) => Promise<void> | void;
    /**
     * Called when deleting a post fails
     * @param error - The error that occurred
     * @param context - Request context
     */
    onDeletePostError?: (error: Error, context: BlogApiContext) => Promise<void> | void;
}
/**
 * Blog backend plugin
 * Provides API endpoints for managing blog posts
 * Uses better-db adapter for database operations
 *
 * @param hooks - Optional configuration hooks for customizing plugin behavior
 */
declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugins_api.BackendPlugin<{
    readonly listPosts: better_call.StrictEndpoint<"/posts", {
        method: "GET";
        query: z.ZodObject<{
            slug: z.ZodOptional<z.ZodString>;
            tagSlug: z.ZodOptional<z.ZodString>;
            offset: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
            limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
            query: z.ZodOptional<z.ZodString>;
            published: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<boolean | undefined, string | undefined>>;
        }, z.core.$strip>;
    }, {
        tags: Tag[];
        id: string;
        authorId?: string;
        defaultLocale?: string;
        slug: string;
        title: string;
        content: string;
        excerpt: string;
        image?: string;
        published: boolean;
        status?: "DRAFT" | "PUBLISHED";
        publishedAt?: Date;
        createdAt: Date;
        updatedAt: Date;
    }[]>;
    readonly createPost: better_call.StrictEndpoint<"/posts", {
        method: "POST";
        body: z.ZodObject<{
            slug: z.ZodOptional<z.ZodString>;
            published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
            createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
            title: z.ZodString;
            content: z.ZodString;
            excerpt: z.ZodString;
            image: z.ZodOptional<z.ZodString>;
            tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
                name: z.ZodString;
            }, z.core.$strip>, z.ZodObject<{
                id: z.ZodString;
                name: z.ZodString;
                slug: z.ZodString;
            }, z.core.$strip>]>>>>;
            publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
            updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
        }, z.core.$strip>;
    }, Post>;
    readonly updatePost: better_call.StrictEndpoint<"/posts/:id", {
        method: "PUT";
        body: z.ZodObject<{
            publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
            createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
            updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
            title: z.ZodString;
            content: z.ZodString;
            excerpt: z.ZodString;
            image: z.ZodOptional<z.ZodString>;
            published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
            slug: z.ZodString;
            tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
                name: z.ZodString;
            }, z.core.$strip>, z.ZodObject<{
                id: z.ZodString;
                name: z.ZodString;
                slug: z.ZodString;
            }, z.core.$strip>]>>>>;
            id: z.ZodString;
        }, z.core.$strip>;
    }, Post>;
    readonly deletePost: better_call.StrictEndpoint<"/posts/:id", {
        method: "DELETE";
    }, {
        success: boolean;
    }>;
    readonly getNextPreviousPosts: better_call.StrictEndpoint<"/posts/next-previous", {
        method: "GET";
        query: z.ZodObject<{
            date: z.ZodCoercedDate<unknown>;
        }, z.core.$strip>;
    }, {
        previous: {
            tags: Tag[];
            id: string;
            authorId?: string;
            defaultLocale?: string;
            slug: string;
            title: string;
            content: string;
            excerpt: string;
            image?: string;
            published: boolean;
            status?: "DRAFT" | "PUBLISHED";
            publishedAt?: Date;
            createdAt: Date;
            updatedAt: Date;
        } | null;
        next: {
            tags: Tag[];
            id: string;
            authorId?: string;
            defaultLocale?: string;
            slug: string;
            title: string;
            content: string;
            excerpt: string;
            image?: string;
            published: boolean;
            status?: "DRAFT" | "PUBLISHED";
            publishedAt?: Date;
            createdAt: Date;
            updatedAt: Date;
        } | null;
    }>;
    readonly listTags: better_call.StrictEndpoint<"/tags", {
        method: "GET";
    }, Tag[]>;
}>;
type BlogApiRouter = ReturnType<ReturnType<typeof blogBackendPlugin>["routes"]>;

interface PostsListParams {
    query?: string;
    limit?: number;
    published?: boolean;
    tagSlug?: string;
}
declare function createBlogQueryKeys(client: ReturnType<typeof createApiClient<BlogApiRouter>>, headers?: HeadersInit): {
    posts: {
        _def: readonly ["posts"];
    } & {
        list: ((params?: PostsListParams | undefined) => Omit<Omit<{
            queryKey: readonly ["posts", "list", {
                query: string | undefined;
                limit: number;
                published: boolean;
                tagSlug: string | undefined;
            }];
            queryFn: _tanstack_react_query.QueryFunction<unknown, readonly ["posts", "list", {
                query: string | undefined;
                limit: number;
                published: boolean;
                tagSlug: string | undefined;
            }]>;
        }, "queryFn"> & {
            _def: readonly ["posts", "list"];
        }, "_def">) & {
            _def: readonly ["posts", "list"];
        };
        detail: ((slug: string) => Omit<{
            queryKey: readonly ["posts", "detail", string];
            queryFn: _tanstack_react_query.QueryFunction<SerializedPost | null, readonly ["posts", "detail", string]>;
        } & {
            _def: readonly ["posts", "detail"];
        }, "_def">) & {
            _def: readonly ["posts", "detail"];
        };
        nextPrevious: ((date: string | Date) => Omit<{
            queryKey: readonly ["posts", "nextPrevious", string, string | Date];
            queryFn: _tanstack_react_query.QueryFunction<{
                previous: SerializedPost | null;
                next: SerializedPost | null;
            }, readonly ["posts", "nextPrevious", string, string | Date]>;
        } & {
            _def: readonly ["posts", "nextPrevious"];
        }, "_def">) & {
            _def: readonly ["posts", "nextPrevious"];
        };
        recent: ((params?: {
            limit?: number;
            excludeSlug?: string;
        } | undefined) => Omit<{
            queryKey: readonly ["posts", "recent", string, {
                limit?: number;
                excludeSlug?: string;
            } | undefined];
            queryFn: _tanstack_react_query.QueryFunction<SerializedPost[], readonly ["posts", "recent", string, {
                limit?: number;
                excludeSlug?: string;
            } | undefined]>;
        } & {
            _def: readonly ["posts", "recent"];
        }, "_def">) & {
            _def: readonly ["posts", "recent"];
        };
    };
    drafts: {
        _def: readonly ["drafts"];
    } & {
        list: ((params?: PostsListParams | undefined) => Omit<Omit<{
            queryKey: readonly ["drafts", "list", {
                limit?: number | undefined;
            }];
            queryFn: _tanstack_react_query.QueryFunction<unknown, readonly ["drafts", "list", {
                limit?: number | undefined;
            }]>;
        }, "queryFn"> & {
            _def: readonly ["drafts", "list"];
        }, "_def">) & {
            _def: readonly ["drafts", "list"];
        };
    };
    tags: {
        _def: readonly ["tags"];
    } & {
        list: (() => Omit<{
            queryKey: readonly ["tags", "list", string];
            queryFn: _tanstack_react_query.QueryFunction<SerializedTag[], readonly ["tags", "list", string]>;
        } & {
            _def: readonly ["tags", "list"];
        }, "_def">) & {
            _def: readonly ["tags", "list"];
        };
    };
};

export { NextPreviousPostsQuerySchema as N, PostListQuerySchema as P, blogBackendPlugin as b, createBlogQueryKeys };
export type { BlogApiContext as B, BlogBackendHooks as a, BlogApiRouter as c };
