@btst/stack 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/dist/api/index.cjs +9 -1
  2. package/dist/api/index.d.cts +4 -4
  3. package/dist/api/index.d.mts +4 -4
  4. package/dist/api/index.d.ts +4 -4
  5. package/dist/api/index.mjs +9 -1
  6. package/dist/client/index.d.cts +2 -2
  7. package/dist/client/index.d.mts +2 -2
  8. package/dist/client/index.d.ts +2 -2
  9. package/dist/index.d.cts +1 -1
  10. package/dist/index.d.mts +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/packages/stack/src/plugins/ai-chat/api/getters.cjs +42 -0
  13. package/dist/packages/stack/src/plugins/ai-chat/api/getters.mjs +39 -0
  14. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +5 -0
  15. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +5 -0
  16. package/dist/packages/stack/src/plugins/blog/api/getters.cjs +131 -0
  17. package/dist/packages/stack/src/plugins/blog/api/getters.mjs +127 -0
  18. package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +60 -107
  19. package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +60 -107
  20. package/dist/packages/stack/src/plugins/blog/api/query-key-defs.cjs +18 -0
  21. package/dist/packages/stack/src/plugins/blog/api/query-key-defs.mjs +15 -0
  22. package/dist/packages/stack/src/plugins/blog/api/serializers.cjs +21 -0
  23. package/dist/packages/stack/src/plugins/blog/api/serializers.mjs +18 -0
  24. package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +16 -1
  25. package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +17 -2
  26. package/dist/packages/stack/src/plugins/cms/api/getters.cjs +156 -0
  27. package/dist/packages/stack/src/plugins/cms/api/getters.mjs +147 -0
  28. package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +624 -617
  29. package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +623 -616
  30. package/dist/packages/stack/src/plugins/cms/api/query-key-defs.cjs +29 -0
  31. package/dist/packages/stack/src/plugins/cms/api/query-key-defs.mjs +26 -0
  32. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.internal.cjs +1 -1
  33. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.internal.mjs +1 -1
  34. package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.cjs +6 -3
  35. package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.mjs +6 -3
  36. package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +15 -0
  37. package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +16 -1
  38. package/dist/packages/stack/src/plugins/form-builder/api/getters.cjs +120 -0
  39. package/dist/packages/stack/src/plugins/form-builder/api/getters.mjs +112 -0
  40. package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +75 -86
  41. package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +71 -82
  42. package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.cjs +37 -0
  43. package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.mjs +33 -0
  44. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.cjs +1 -1
  45. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.mjs +1 -1
  46. package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +15 -0
  47. package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +16 -1
  48. package/dist/packages/stack/src/plugins/kanban/api/getters.cjs +84 -0
  49. package/dist/packages/stack/src/plugins/kanban/api/getters.mjs +81 -0
  50. package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +37 -123
  51. package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +37 -123
  52. package/dist/packages/stack/src/plugins/kanban/api/query-key-defs.cjs +26 -0
  53. package/dist/packages/stack/src/plugins/kanban/api/query-key-defs.mjs +23 -0
  54. package/dist/packages/stack/src/plugins/kanban/api/serializers.cjs +30 -0
  55. package/dist/packages/stack/src/plugins/kanban/api/serializers.mjs +26 -0
  56. package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +11 -1
  57. package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +12 -2
  58. package/dist/packages/stack/src/plugins/utils.cjs +6 -0
  59. package/dist/packages/stack/src/plugins/utils.mjs +6 -1
  60. package/dist/plugins/ai-chat/api/index.cjs +3 -0
  61. package/dist/plugins/ai-chat/api/index.d.cts +27 -4
  62. package/dist/plugins/ai-chat/api/index.d.mts +27 -4
  63. package/dist/plugins/ai-chat/api/index.d.ts +27 -4
  64. package/dist/plugins/ai-chat/api/index.mjs +1 -0
  65. package/dist/plugins/ai-chat/client/hooks/index.d.cts +2 -2
  66. package/dist/plugins/ai-chat/client/hooks/index.d.mts +2 -2
  67. package/dist/plugins/ai-chat/client/hooks/index.d.ts +2 -2
  68. package/dist/plugins/ai-chat/query-keys.d.cts +9 -284
  69. package/dist/plugins/ai-chat/query-keys.d.mts +9 -284
  70. package/dist/plugins/ai-chat/query-keys.d.ts +9 -284
  71. package/dist/plugins/api/index.d.cts +4 -3
  72. package/dist/plugins/api/index.d.mts +4 -3
  73. package/dist/plugins/api/index.d.ts +4 -3
  74. package/dist/plugins/blog/api/index.cjs +9 -0
  75. package/dist/plugins/blog/api/index.d.cts +20 -4
  76. package/dist/plugins/blog/api/index.d.mts +20 -4
  77. package/dist/plugins/blog/api/index.d.ts +20 -4
  78. package/dist/plugins/blog/api/index.mjs +3 -0
  79. package/dist/plugins/blog/client/hooks/index.d.cts +5 -5
  80. package/dist/plugins/blog/client/hooks/index.d.mts +5 -5
  81. package/dist/plugins/blog/client/hooks/index.d.ts +5 -5
  82. package/dist/plugins/blog/client/index.d.cts +1 -1
  83. package/dist/plugins/blog/client/index.d.mts +1 -1
  84. package/dist/plugins/blog/client/index.d.ts +1 -1
  85. package/dist/plugins/blog/query-keys.cjs +13 -9
  86. package/dist/plugins/blog/query-keys.d.cts +8 -333
  87. package/dist/plugins/blog/query-keys.d.mts +8 -333
  88. package/dist/plugins/blog/query-keys.d.ts +8 -333
  89. package/dist/plugins/blog/query-keys.mjs +13 -9
  90. package/dist/plugins/client/index.cjs +1 -0
  91. package/dist/plugins/client/index.d.cts +10 -3
  92. package/dist/plugins/client/index.d.mts +10 -3
  93. package/dist/plugins/client/index.d.ts +10 -3
  94. package/dist/plugins/client/index.mjs +1 -1
  95. package/dist/plugins/cms/api/index.cjs +10 -0
  96. package/dist/plugins/cms/api/index.d.cts +7 -163
  97. package/dist/plugins/cms/api/index.d.mts +7 -163
  98. package/dist/plugins/cms/api/index.d.ts +7 -163
  99. package/dist/plugins/cms/api/index.mjs +2 -0
  100. package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
  101. package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
  102. package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
  103. package/dist/plugins/cms/query-keys.cjs +2 -1
  104. package/dist/plugins/cms/query-keys.d.cts +6 -9
  105. package/dist/plugins/cms/query-keys.d.mts +6 -9
  106. package/dist/plugins/cms/query-keys.d.ts +6 -9
  107. package/dist/plugins/cms/query-keys.mjs +2 -1
  108. package/dist/plugins/form-builder/api/index.cjs +10 -0
  109. package/dist/plugins/form-builder/api/index.d.cts +7 -141
  110. package/dist/plugins/form-builder/api/index.d.mts +7 -141
  111. package/dist/plugins/form-builder/api/index.d.ts +7 -141
  112. package/dist/plugins/form-builder/api/index.mjs +2 -0
  113. package/dist/plugins/form-builder/client/components/index.d.cts +1 -1
  114. package/dist/plugins/form-builder/client/components/index.d.mts +1 -1
  115. package/dist/plugins/form-builder/client/components/index.d.ts +1 -1
  116. package/dist/plugins/form-builder/client/hooks/index.d.cts +1 -1
  117. package/dist/plugins/form-builder/client/hooks/index.d.mts +1 -1
  118. package/dist/plugins/form-builder/client/hooks/index.d.ts +1 -1
  119. package/dist/plugins/form-builder/query-keys.cjs +3 -2
  120. package/dist/plugins/form-builder/query-keys.d.cts +7 -6
  121. package/dist/plugins/form-builder/query-keys.d.mts +7 -6
  122. package/dist/plugins/form-builder/query-keys.d.ts +7 -6
  123. package/dist/plugins/form-builder/query-keys.mjs +3 -2
  124. package/dist/plugins/kanban/api/index.cjs +9 -0
  125. package/dist/plugins/kanban/api/index.d.cts +17 -395
  126. package/dist/plugins/kanban/api/index.d.mts +17 -395
  127. package/dist/plugins/kanban/api/index.d.ts +17 -395
  128. package/dist/plugins/kanban/api/index.mjs +3 -0
  129. package/dist/plugins/kanban/client/components/index.d.cts +1 -1
  130. package/dist/plugins/kanban/client/components/index.d.mts +1 -1
  131. package/dist/plugins/kanban/client/components/index.d.ts +1 -1
  132. package/dist/plugins/kanban/client/hooks/index.d.cts +1 -1
  133. package/dist/plugins/kanban/client/hooks/index.d.mts +1 -1
  134. package/dist/plugins/kanban/client/hooks/index.d.ts +1 -1
  135. package/dist/plugins/kanban/client/index.d.cts +1 -1
  136. package/dist/plugins/kanban/client/index.d.mts +1 -1
  137. package/dist/plugins/kanban/client/index.d.ts +1 -1
  138. package/dist/plugins/kanban/query-keys.cjs +6 -12
  139. package/dist/plugins/kanban/query-keys.d.cts +5 -16
  140. package/dist/plugins/kanban/query-keys.d.mts +5 -16
  141. package/dist/plugins/kanban/query-keys.d.ts +5 -16
  142. package/dist/plugins/kanban/query-keys.mjs +6 -12
  143. package/dist/plugins/open-api/api/index.d.cts +2 -2
  144. package/dist/plugins/open-api/api/index.d.mts +2 -2
  145. package/dist/plugins/open-api/api/index.d.ts +2 -2
  146. package/dist/plugins/route-docs/client/index.d.cts +1 -1
  147. package/dist/plugins/route-docs/client/index.d.mts +1 -1
  148. package/dist/plugins/route-docs/client/index.d.ts +1 -1
  149. package/dist/plugins/ui-builder/index.d.cts +1 -1
  150. package/dist/plugins/ui-builder/index.d.mts +1 -1
  151. package/dist/plugins/ui-builder/index.d.ts +1 -1
  152. package/dist/shared/{stack.BoA0xkJv.d.cts → stack.7n9Y_u7N.d.cts} +33 -7
  153. package/dist/shared/{stack.BoA0xkJv.d.mts → stack.7n9Y_u7N.d.mts} +33 -7
  154. package/dist/shared/{stack.BoA0xkJv.d.ts → stack.7n9Y_u7N.d.ts} +33 -7
  155. package/dist/shared/stack.B1EeBt1b.d.ts +297 -0
  156. package/dist/shared/stack.BIXEI6v_.d.mts +419 -0
  157. package/dist/shared/stack.BKfolAyK.d.ts +419 -0
  158. package/dist/shared/stack.BeSm90va.d.ts +289 -0
  159. package/dist/shared/stack.BpolpQpf.d.cts +445 -0
  160. package/dist/shared/stack.C5dtIncc.d.mts +293 -0
  161. package/dist/shared/stack.CIP6QS9l.d.ts +293 -0
  162. package/dist/shared/stack.CMh_EdxW.d.cts +289 -0
  163. package/dist/shared/stack.CP68pFEH.d.mts +297 -0
  164. package/dist/shared/{stack.BsXokfNh.d.mts → stack.CVDTkMoO.d.cts} +8 -2
  165. package/dist/shared/{stack.BsXokfNh.d.ts → stack.CVDTkMoO.d.mts} +8 -2
  166. package/dist/shared/{stack.BsXokfNh.d.cts → stack.CVDTkMoO.d.ts} +8 -2
  167. package/dist/shared/{stack.DKDMI-QO.d.mts → stack.DJaKVY7v.d.cts} +7 -1
  168. package/dist/shared/{stack.DKDMI-QO.d.ts → stack.DJaKVY7v.d.mts} +7 -1
  169. package/dist/shared/{stack.DKDMI-QO.d.cts → stack.DJaKVY7v.d.ts} +7 -1
  170. package/dist/shared/{stack.DzH_wcvr.d.mts → stack.DdI5W6MB.d.cts} +9 -3
  171. package/dist/shared/{stack.DzH_wcvr.d.ts → stack.DdI5W6MB.d.mts} +9 -3
  172. package/dist/shared/{stack.DzH_wcvr.d.cts → stack.DdI5W6MB.d.ts} +9 -3
  173. package/dist/shared/stack.Dg09R0oB.d.mts +289 -0
  174. package/dist/shared/stack.Dw0Ly2TM.d.cts +293 -0
  175. package/dist/shared/stack.IdtKDRka.d.cts +297 -0
  176. package/dist/shared/stack.TIBF2AOx.d.ts +445 -0
  177. package/dist/shared/stack.rTy7-wQU.d.mts +445 -0
  178. package/dist/shared/stack.snB1EDP7.d.cts +419 -0
  179. package/package.json +3 -3
  180. package/src/__tests__/stack-api.test.ts +118 -0
  181. package/src/api/index.ts +15 -1
  182. package/src/plugins/ai-chat/__tests__/getters.test.ts +109 -0
  183. package/src/plugins/ai-chat/api/getters.ts +71 -0
  184. package/src/plugins/ai-chat/api/index.ts +1 -0
  185. package/src/plugins/ai-chat/api/plugin.ts +8 -0
  186. package/src/plugins/api/index.ts +3 -1
  187. package/src/plugins/blog/__tests__/getters.test.ts +540 -0
  188. package/src/plugins/blog/api/getters.ts +243 -0
  189. package/src/plugins/blog/api/index.ts +9 -0
  190. package/src/plugins/blog/api/plugin.ts +98 -141
  191. package/src/plugins/blog/api/query-key-defs.ts +46 -0
  192. package/src/plugins/blog/api/serializers.ts +27 -0
  193. package/src/plugins/blog/client/plugin.tsx +21 -1
  194. package/src/plugins/blog/query-keys.ts +21 -20
  195. package/src/plugins/client/index.ts +1 -1
  196. package/src/plugins/cms/__tests__/getters.test.ts +206 -0
  197. package/src/plugins/cms/api/getters.ts +268 -0
  198. package/src/plugins/cms/api/index.ts +15 -1
  199. package/src/plugins/cms/api/plugin.ts +151 -150
  200. package/src/plugins/cms/api/query-key-defs.ts +53 -0
  201. package/src/plugins/cms/api/serializers.ts +12 -0
  202. package/src/plugins/cms/client/components/pages/content-editor-page.internal.tsx +1 -1
  203. package/src/plugins/cms/client/hooks/cms-hooks.tsx +3 -0
  204. package/src/plugins/cms/client/plugin.tsx +19 -0
  205. package/src/plugins/cms/query-keys.ts +2 -1
  206. package/src/plugins/cms/types.ts +1 -1
  207. package/src/plugins/form-builder/__tests__/getters.test.ts +159 -0
  208. package/src/plugins/form-builder/api/getters.ts +226 -0
  209. package/src/plugins/form-builder/api/index.ts +15 -1
  210. package/src/plugins/form-builder/api/plugin.ts +107 -109
  211. package/src/plugins/form-builder/api/query-key-defs.ts +79 -0
  212. package/src/plugins/form-builder/api/serializers.ts +12 -0
  213. package/src/plugins/form-builder/client/components/pages/submissions-page.internal.tsx +1 -1
  214. package/src/plugins/form-builder/client/plugin.tsx +19 -0
  215. package/src/plugins/form-builder/query-keys.ts +6 -2
  216. package/src/plugins/form-builder/types.ts +2 -2
  217. package/src/plugins/kanban/__tests__/getters.test.ts +172 -0
  218. package/src/plugins/kanban/api/getters.ts +149 -0
  219. package/src/plugins/kanban/api/index.ts +4 -0
  220. package/src/plugins/kanban/api/plugin.ts +65 -146
  221. package/src/plugins/kanban/api/query-key-defs.ts +54 -0
  222. package/src/plugins/kanban/api/serializers.ts +49 -0
  223. package/src/plugins/kanban/client/plugin.tsx +15 -1
  224. package/src/plugins/kanban/query-keys.ts +10 -14
  225. package/src/plugins/utils.ts +19 -0
  226. package/src/types.ts +44 -5
  227. package/dist/shared/{stack.CbuN2zVV.d.cts → stack.CBON0dWL.d.cts} +7 -7
  228. package/dist/shared/{stack.CbuN2zVV.d.mts → stack.CBON0dWL.d.mts} +7 -7
  229. package/dist/shared/{stack.CbuN2zVV.d.ts → stack.CBON0dWL.d.ts} +7 -7
@@ -0,0 +1,419 @@
1
+ import * as _tanstack_react_query from '@tanstack/react-query';
2
+ import { QueryClient } from '@tanstack/react-query';
3
+ import { createApiClient } from '@btst/stack/plugins/client';
4
+ import { P as Post, T as Tag, c as createPostSchema, u as updatePostSchema, S as SerializedPost, a as SerializedTag } from './stack.CBON0dWL.js';
5
+ import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
6
+ import * as better_call from 'better-call';
7
+ import { Adapter } from '@btst/db';
8
+ import { z } from 'zod';
9
+
10
+ /**
11
+ * Parameters for filtering/paginating posts.
12
+ * Mirrors the shape of the list API query schema.
13
+ */
14
+ interface PostListParams {
15
+ slug?: string;
16
+ tagSlug?: string;
17
+ offset?: number;
18
+ limit?: number;
19
+ query?: string;
20
+ published?: boolean;
21
+ }
22
+ /**
23
+ * Paginated result returned by {@link getAllPosts}.
24
+ */
25
+ interface PostListResult {
26
+ items: Array<Post & {
27
+ tags: Tag[];
28
+ }>;
29
+ total: number;
30
+ limit?: number;
31
+ offset?: number;
32
+ }
33
+ /**
34
+ * Retrieve all posts matching optional filter criteria.
35
+ * Pure DB function — no hooks, no HTTP context. Safe for SSG and server-side use.
36
+ *
37
+ * @remarks **Security:** Authorization hooks (e.g. `onBeforeListPosts`) are NOT
38
+ * called. The caller is responsible for any access-control checks before
39
+ * invoking this function.
40
+ *
41
+ * @param adapter - The database adapter
42
+ * @param params - Optional filter/pagination parameters (same shape as the list API query)
43
+ */
44
+ declare function getAllPosts(adapter: Adapter, params?: PostListParams): Promise<PostListResult>;
45
+ /**
46
+ * Retrieve a single post by its slug, including associated tags.
47
+ * Returns null if no post is found.
48
+ * Pure DB function — no hooks, no HTTP context. Safe for SSG and server-side use.
49
+ *
50
+ * @remarks **Security:** Authorization hooks are NOT called. The caller is
51
+ * responsible for any access-control checks before invoking this function.
52
+ *
53
+ * @param adapter - The database adapter
54
+ * @param slug - The post slug
55
+ */
56
+ declare function getPostBySlug(adapter: Adapter, slug: string): Promise<(Post & {
57
+ tags: Tag[];
58
+ }) | null>;
59
+ /**
60
+ * Retrieve all tags, sorted alphabetically by name.
61
+ * Pure DB function — no hooks, no HTTP context. Safe for SSG and server-side use.
62
+ *
63
+ * @remarks **Security:** Authorization hooks are NOT called. The caller is
64
+ * responsible for any access-control checks before invoking this function.
65
+ *
66
+ * @param adapter - The database adapter
67
+ */
68
+ declare function getAllTags(adapter: Adapter): Promise<Tag[]>;
69
+
70
+ /**
71
+ * Route keys for the blog plugin — matches the keys returned by
72
+ * `stackClient.router.getRoute(path).routeKey`.
73
+ */
74
+ type BlogRouteKey = "posts" | "drafts" | "post" | "tag" | "newPost" | "editPost";
75
+ /**
76
+ * Overloaded signature for `prefetchForRoute`.
77
+ * TypeScript enforces the correct params for each routeKey at call sites.
78
+ */
79
+ interface BlogPrefetchForRoute {
80
+ (key: "posts" | "drafts" | "newPost", qc: QueryClient): Promise<void>;
81
+ (key: "post" | "editPost", qc: QueryClient, params: {
82
+ slug: string;
83
+ }): Promise<void>;
84
+ (key: "tag", qc: QueryClient, params: {
85
+ tagSlug: string;
86
+ }): Promise<void>;
87
+ }
88
+ declare const PostListQuerySchema: z.ZodObject<{
89
+ slug: z.ZodOptional<z.ZodString>;
90
+ tagSlug: z.ZodOptional<z.ZodString>;
91
+ offset: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
92
+ limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
93
+ query: z.ZodOptional<z.ZodString>;
94
+ published: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<boolean | undefined, string | undefined>>;
95
+ }, z.core.$strip>;
96
+ declare const NextPreviousPostsQuerySchema: z.ZodObject<{
97
+ date: z.ZodCoercedDate<unknown>;
98
+ }, z.core.$strip>;
99
+ /**
100
+ * Context passed to blog API hooks
101
+ */
102
+ interface BlogApiContext<TBody = any, TParams = any, TQuery = any> {
103
+ body?: TBody;
104
+ params?: TParams;
105
+ query?: TQuery;
106
+ request?: Request;
107
+ headers?: Headers;
108
+ [key: string]: any;
109
+ }
110
+ /**
111
+ * Configuration hooks for blog backend plugin
112
+ * All hooks are optional and allow consumers to customize behavior
113
+ */
114
+ interface BlogBackendHooks {
115
+ /**
116
+ * Called before listing posts. Return false to deny access.
117
+ * @param filter - Query parameters for filtering posts
118
+ * @param context - Request context with headers, etc.
119
+ */
120
+ onBeforeListPosts?: (filter: z.infer<typeof PostListQuerySchema>, context: BlogApiContext) => Promise<boolean> | boolean;
121
+ /**
122
+ * Called before creating a post. Return false to deny access.
123
+ * @param data - Post data being created
124
+ * @param context - Request context with headers, etc.
125
+ */
126
+ onBeforeCreatePost?: (data: z.infer<typeof createPostSchema>, context: BlogApiContext) => Promise<boolean> | boolean;
127
+ /**
128
+ * Called before updating a post. Return false to deny access.
129
+ * @param postId - ID of the post being updated
130
+ * @param data - Updated post data
131
+ * @param context - Request context with headers, etc.
132
+ */
133
+ onBeforeUpdatePost?: (postId: string, data: z.infer<typeof updatePostSchema>, context: BlogApiContext) => Promise<boolean> | boolean;
134
+ /**
135
+ * Called before deleting a post. Return false to deny access.
136
+ * @param postId - ID of the post being deleted
137
+ * @param context - Request context with headers, etc.
138
+ */
139
+ onBeforeDeletePost?: (postId: string, context: BlogApiContext) => Promise<boolean> | boolean;
140
+ /**
141
+ * Called after posts are read successfully
142
+ * @param posts - The list of posts returned by the query
143
+ * @param filter - Query parameters used for filtering
144
+ * @param context - Request context
145
+ */
146
+ onPostsRead?: (posts: Array<Post & {
147
+ tags: Tag[];
148
+ }>, filter: z.infer<typeof PostListQuerySchema>, context: BlogApiContext) => Promise<void> | void;
149
+ /**
150
+ * Called after a post is created successfully
151
+ * @param post - The created post
152
+ * @param context - Request context
153
+ */
154
+ onPostCreated?: (post: Post, context: BlogApiContext) => Promise<void> | void;
155
+ /**
156
+ * Called after a post is updated successfully
157
+ * @param post - The updated post
158
+ * @param context - Request context
159
+ */
160
+ onPostUpdated?: (post: Post, context: BlogApiContext) => Promise<void> | void;
161
+ /**
162
+ * Called after a post is deleted successfully
163
+ * @param postId - ID of the deleted post
164
+ * @param context - Request context
165
+ */
166
+ onPostDeleted?: (postId: string, context: BlogApiContext) => Promise<void> | void;
167
+ /**
168
+ * Called when listing posts fails
169
+ * @param error - The error that occurred
170
+ * @param context - Request context
171
+ */
172
+ onListPostsError?: (error: Error, context: BlogApiContext) => Promise<void> | void;
173
+ /**
174
+ * Called when creating a post fails
175
+ * @param error - The error that occurred
176
+ * @param context - Request context
177
+ */
178
+ onCreatePostError?: (error: Error, context: BlogApiContext) => Promise<void> | void;
179
+ /**
180
+ * Called when updating a post fails
181
+ * @param error - The error that occurred
182
+ * @param context - Request context
183
+ */
184
+ onUpdatePostError?: (error: Error, context: BlogApiContext) => Promise<void> | void;
185
+ /**
186
+ * Called when deleting a post fails
187
+ * @param error - The error that occurred
188
+ * @param context - Request context
189
+ */
190
+ onDeletePostError?: (error: Error, context: BlogApiContext) => Promise<void> | void;
191
+ }
192
+ /**
193
+ * Blog backend plugin
194
+ * Provides API endpoints for managing blog posts
195
+ * Uses better-db adapter for database operations
196
+ *
197
+ * @param hooks - Optional configuration hooks for customizing plugin behavior
198
+ */
199
+ declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugins_api.BackendPlugin<{
200
+ readonly listPosts: better_call.StrictEndpoint<"/posts", {
201
+ method: "GET";
202
+ query: z.ZodObject<{
203
+ slug: z.ZodOptional<z.ZodString>;
204
+ tagSlug: z.ZodOptional<z.ZodString>;
205
+ offset: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
206
+ limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
207
+ query: z.ZodOptional<z.ZodString>;
208
+ published: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<boolean | undefined, string | undefined>>;
209
+ }, z.core.$strip>;
210
+ }, PostListResult>;
211
+ readonly createPost: better_call.StrictEndpoint<"/posts", {
212
+ method: "POST";
213
+ body: z.ZodObject<{
214
+ tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
215
+ name: z.ZodString;
216
+ }, z.core.$strip>, z.ZodObject<{
217
+ id: z.ZodString;
218
+ name: z.ZodString;
219
+ slug: z.ZodString;
220
+ }, z.core.$strip>]>>>>;
221
+ slug: z.ZodOptional<z.ZodString>;
222
+ publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
223
+ createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
224
+ updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
225
+ title: z.ZodString;
226
+ content: z.ZodString;
227
+ excerpt: z.ZodString;
228
+ image: z.ZodOptional<z.ZodString>;
229
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
230
+ }, z.core.$strip>;
231
+ }, Post>;
232
+ readonly updatePost: better_call.StrictEndpoint<"/posts/:id", {
233
+ method: "PUT";
234
+ body: z.ZodObject<{
235
+ publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
236
+ createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
237
+ updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
238
+ title: z.ZodString;
239
+ content: z.ZodString;
240
+ excerpt: z.ZodString;
241
+ image: z.ZodOptional<z.ZodString>;
242
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
243
+ slug: z.ZodString;
244
+ tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
245
+ name: z.ZodString;
246
+ }, z.core.$strip>, z.ZodObject<{
247
+ id: z.ZodString;
248
+ name: z.ZodString;
249
+ slug: z.ZodString;
250
+ }, z.core.$strip>]>>>>;
251
+ id: z.ZodString;
252
+ }, z.core.$strip>;
253
+ }, Post>;
254
+ readonly deletePost: better_call.StrictEndpoint<"/posts/:id", {
255
+ method: "DELETE";
256
+ }, {
257
+ success: boolean;
258
+ }>;
259
+ readonly getNextPreviousPosts: better_call.StrictEndpoint<"/posts/next-previous", {
260
+ method: "GET";
261
+ query: z.ZodObject<{
262
+ date: z.ZodCoercedDate<unknown>;
263
+ }, z.core.$strip>;
264
+ }, {
265
+ previous: {
266
+ tags: Tag[];
267
+ id: string;
268
+ authorId?: string;
269
+ defaultLocale?: string;
270
+ slug: string;
271
+ title: string;
272
+ content: string;
273
+ excerpt: string;
274
+ image?: string;
275
+ published: boolean;
276
+ status?: "DRAFT" | "PUBLISHED";
277
+ publishedAt?: Date;
278
+ createdAt: Date;
279
+ updatedAt: Date;
280
+ } | null;
281
+ next: {
282
+ tags: Tag[];
283
+ id: string;
284
+ authorId?: string;
285
+ defaultLocale?: string;
286
+ slug: string;
287
+ title: string;
288
+ content: string;
289
+ excerpt: string;
290
+ image?: string;
291
+ published: boolean;
292
+ status?: "DRAFT" | "PUBLISHED";
293
+ publishedAt?: Date;
294
+ createdAt: Date;
295
+ updatedAt: Date;
296
+ } | null;
297
+ }>;
298
+ readonly listTags: better_call.StrictEndpoint<"/tags", {
299
+ method: "GET";
300
+ }, Tag[]>;
301
+ }, {
302
+ getAllPosts: (params?: Parameters<typeof getAllPosts>[1]) => Promise<PostListResult>;
303
+ getPostBySlug: (slug: string) => Promise<(Post & {
304
+ tags: Tag[];
305
+ }) | null>;
306
+ getAllTags: () => Promise<Tag[]>;
307
+ prefetchForRoute: BlogPrefetchForRoute;
308
+ }>;
309
+ type BlogApiRouter = ReturnType<ReturnType<typeof blogBackendPlugin>["routes"]>;
310
+
311
+ /**
312
+ * Internal query key constants for the blog plugin.
313
+ * Shared between query-keys.ts (HTTP path) and prefetchForRoute (DB path)
314
+ * to prevent key drift between SSR loaders and SSG prefetching.
315
+ */
316
+ interface PostsListDiscriminator {
317
+ query: string | undefined;
318
+ limit: number;
319
+ published: boolean;
320
+ tagSlug: string | undefined;
321
+ }
322
+ /** Full query key builders — use these with queryClient.setQueryData() */
323
+ declare const BLOG_QUERY_KEYS: {
324
+ postsList: (params: {
325
+ published: boolean;
326
+ limit?: number;
327
+ tagSlug?: string;
328
+ }) => readonly ["posts", "list", PostsListDiscriminator];
329
+ postDetail: (slug: string) => readonly ["posts", "detail", string];
330
+ tagsList: () => readonly ["tags", "list", "tags"];
331
+ };
332
+
333
+ interface PostsListParams {
334
+ query?: string;
335
+ limit?: number;
336
+ published?: boolean;
337
+ tagSlug?: string;
338
+ }
339
+ declare function createBlogQueryKeys(client: ReturnType<typeof createApiClient<BlogApiRouter>>, headers?: HeadersInit): {
340
+ posts: {
341
+ _def: readonly ["posts"];
342
+ } & {
343
+ list: ((params?: PostsListParams | undefined) => Omit<Omit<{
344
+ queryKey: readonly ["posts", "list", PostsListDiscriminator];
345
+ queryFn: _tanstack_react_query.QueryFunction<unknown, readonly ["posts", "list", PostsListDiscriminator]>;
346
+ }, "queryFn"> & {
347
+ _def: readonly ["posts", "list"];
348
+ }, "_def">) & {
349
+ _def: readonly ["posts", "list"];
350
+ };
351
+ detail: ((slug: string) => Omit<{
352
+ queryKey: readonly ["posts", "detail", string];
353
+ queryFn: _tanstack_react_query.QueryFunction<SerializedPost | null, readonly ["posts", "detail", string]>;
354
+ } & {
355
+ _def: readonly ["posts", "detail"];
356
+ }, "_def">) & {
357
+ _def: readonly ["posts", "detail"];
358
+ };
359
+ nextPrevious: ((date: string | Date) => Omit<{
360
+ queryKey: readonly ["posts", "nextPrevious", string, string | Date];
361
+ queryFn: _tanstack_react_query.QueryFunction<{
362
+ previous: SerializedPost | null;
363
+ next: SerializedPost | null;
364
+ }, readonly ["posts", "nextPrevious", string, string | Date]>;
365
+ } & {
366
+ _def: readonly ["posts", "nextPrevious"];
367
+ }, "_def">) & {
368
+ _def: readonly ["posts", "nextPrevious"];
369
+ };
370
+ recent: ((params?: {
371
+ limit?: number;
372
+ excludeSlug?: string;
373
+ } | undefined) => Omit<{
374
+ queryKey: readonly ["posts", "recent", string, {
375
+ limit?: number;
376
+ excludeSlug?: string;
377
+ } | undefined];
378
+ queryFn: _tanstack_react_query.QueryFunction<SerializedPost[], readonly ["posts", "recent", string, {
379
+ limit?: number;
380
+ excludeSlug?: string;
381
+ } | undefined]>;
382
+ } & {
383
+ _def: readonly ["posts", "recent"];
384
+ }, "_def">) & {
385
+ _def: readonly ["posts", "recent"];
386
+ };
387
+ };
388
+ drafts: {
389
+ _def: readonly ["drafts"];
390
+ } & {
391
+ list: ((params?: PostsListParams | undefined) => Omit<Omit<{
392
+ queryKey: readonly ["drafts", "list", {
393
+ limit?: number | undefined;
394
+ }];
395
+ queryFn: _tanstack_react_query.QueryFunction<unknown, readonly ["drafts", "list", {
396
+ limit?: number | undefined;
397
+ }]>;
398
+ }, "queryFn"> & {
399
+ _def: readonly ["drafts", "list"];
400
+ }, "_def">) & {
401
+ _def: readonly ["drafts", "list"];
402
+ };
403
+ };
404
+ tags: {
405
+ _def: readonly ["tags"];
406
+ } & {
407
+ list: (() => Omit<{
408
+ queryKey: readonly ["tags", "list", string];
409
+ queryFn: _tanstack_react_query.QueryFunction<SerializedTag[], readonly ["tags", "list", string]>;
410
+ } & {
411
+ _def: readonly ["tags", "list"];
412
+ }, "_def">) & {
413
+ _def: readonly ["tags", "list"];
414
+ };
415
+ };
416
+ };
417
+
418
+ export { BLOG_QUERY_KEYS as B, NextPreviousPostsQuerySchema as N, getPostBySlug as a, getAllTags as b, createBlogQueryKeys as d, PostListQuerySchema as f, getAllPosts as g, blogBackendPlugin as j };
419
+ export type { PostListParams as P, PostListResult as c, BlogRouteKey as e, BlogApiContext as h, BlogBackendHooks as i, BlogApiRouter as k };