@btst/stack 1.0.1 → 1.1.1

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 (282) hide show
  1. package/README.md +156 -709
  2. package/dist/api/index.cjs +2 -1
  3. package/dist/api/index.d.cts +4 -3
  4. package/dist/api/index.d.mts +4 -3
  5. package/dist/api/index.d.ts +4 -3
  6. package/dist/api/index.mjs +1 -1
  7. package/dist/client/components/compose.cjs +68 -0
  8. package/dist/client/components/compose.mjs +65 -0
  9. package/dist/client/components/error-boundary.cjs +24 -0
  10. package/dist/client/components/error-boundary.mjs +22 -0
  11. package/dist/client/components/index.cjs +10 -0
  12. package/dist/client/components/index.d.cts +52 -0
  13. package/dist/client/components/index.d.mts +52 -0
  14. package/dist/client/components/index.d.ts +52 -0
  15. package/dist/client/components/index.mjs +2 -0
  16. package/dist/client/index.cjs +24 -5
  17. package/dist/client/index.d.cts +125 -8
  18. package/dist/client/index.d.mts +125 -8
  19. package/dist/client/index.d.ts +125 -8
  20. package/dist/client/index.mjs +21 -4
  21. package/dist/client/meta-utils.cjs +162 -0
  22. package/dist/client/meta-utils.mjs +160 -0
  23. package/dist/client/path-utils.cjs +15 -0
  24. package/dist/client/path-utils.mjs +13 -0
  25. package/dist/client/sitemap-utils.cjs +14 -0
  26. package/dist/client/sitemap-utils.mjs +12 -0
  27. package/dist/context/index.cjs +6 -63
  28. package/dist/context/index.d.cts +21 -24
  29. package/dist/context/index.d.mts +21 -24
  30. package/dist/context/index.d.ts +21 -24
  31. package/dist/context/index.mjs +1 -61
  32. package/dist/context/provider.cjs +51 -0
  33. package/dist/context/provider.mjs +46 -0
  34. package/dist/index.cjs +2 -3
  35. package/dist/index.d.cts +3 -2
  36. package/dist/index.d.mts +3 -2
  37. package/dist/index.d.ts +3 -2
  38. package/dist/index.mjs +1 -2
  39. package/dist/plugins/api/index.cjs +13 -0
  40. package/dist/plugins/api/index.d.cts +40 -0
  41. package/dist/plugins/api/index.d.mts +40 -0
  42. package/dist/plugins/api/index.d.ts +40 -0
  43. package/dist/plugins/api/index.mjs +8 -0
  44. package/dist/plugins/blog/api/index.cjs +11 -0
  45. package/dist/plugins/blog/api/index.d.cts +7 -0
  46. package/dist/plugins/blog/api/index.d.mts +7 -0
  47. package/dist/plugins/blog/api/index.d.ts +7 -0
  48. package/dist/plugins/blog/api/index.mjs +2 -0
  49. package/dist/plugins/blog/api/plugin.cjs +569 -0
  50. package/dist/plugins/blog/api/plugin.mjs +565 -0
  51. package/dist/plugins/blog/client/components/forms/image-field.cjs +133 -0
  52. package/dist/plugins/blog/client/components/forms/image-field.mjs +131 -0
  53. package/dist/plugins/blog/client/components/forms/markdown-editor-styles.css +30 -0
  54. package/dist/plugins/blog/client/components/forms/markdown-editor.cjs +106 -0
  55. package/dist/plugins/blog/client/components/forms/markdown-editor.mjs +104 -0
  56. package/dist/plugins/blog/client/components/forms/post-forms.cjs +401 -0
  57. package/dist/plugins/blog/client/components/forms/post-forms.mjs +398 -0
  58. package/dist/plugins/blog/client/components/forms/tags-multiselect.cjs +71 -0
  59. package/dist/plugins/blog/client/components/forms/tags-multiselect.mjs +65 -0
  60. package/dist/plugins/blog/client/components/index.cjs +17 -0
  61. package/dist/plugins/blog/client/components/index.d.cts +22 -0
  62. package/dist/plugins/blog/client/components/index.d.mts +22 -0
  63. package/dist/plugins/blog/client/components/index.d.ts +22 -0
  64. package/dist/plugins/blog/client/components/index.mjs +12 -0
  65. package/dist/plugins/blog/client/components/loading/form-page-skeleton.cjs +62 -0
  66. package/dist/plugins/blog/client/components/loading/form-page-skeleton.mjs +60 -0
  67. package/dist/plugins/blog/client/components/loading/index.cjs +20 -0
  68. package/dist/plugins/blog/client/components/loading/index.mjs +16 -0
  69. package/dist/plugins/blog/client/components/loading/list-page-skeleton.cjs +26 -0
  70. package/dist/plugins/blog/client/components/loading/list-page-skeleton.mjs +24 -0
  71. package/dist/plugins/blog/client/components/loading/page-header-skeleton.cjs +13 -0
  72. package/dist/plugins/blog/client/components/loading/page-header-skeleton.mjs +11 -0
  73. package/dist/plugins/blog/client/components/loading/post-card-skeleton.cjs +22 -0
  74. package/dist/plugins/blog/client/components/loading/post-card-skeleton.mjs +20 -0
  75. package/dist/plugins/blog/client/components/loading/post-page-skeleton.cjs +56 -0
  76. package/dist/plugins/blog/client/components/loading/post-page-skeleton.mjs +54 -0
  77. package/dist/plugins/blog/client/components/pages/404-page.cjs +19 -0
  78. package/dist/plugins/blog/client/components/pages/404-page.mjs +17 -0
  79. package/dist/plugins/blog/client/components/pages/edit-post-page.cjs +41 -0
  80. package/dist/plugins/blog/client/components/pages/edit-post-page.internal.cjs +57 -0
  81. package/dist/plugins/blog/client/components/pages/edit-post-page.internal.mjs +55 -0
  82. package/dist/plugins/blog/client/components/pages/edit-post-page.mjs +39 -0
  83. package/dist/plugins/blog/client/components/pages/home-page.cjs +41 -0
  84. package/dist/plugins/blog/client/components/pages/home-page.internal.cjs +61 -0
  85. package/dist/plugins/blog/client/components/pages/home-page.internal.mjs +59 -0
  86. package/dist/plugins/blog/client/components/pages/home-page.mjs +39 -0
  87. package/dist/plugins/blog/client/components/pages/new-post-page.cjs +37 -0
  88. package/dist/plugins/blog/client/components/pages/new-post-page.internal.cjs +53 -0
  89. package/dist/plugins/blog/client/components/pages/new-post-page.internal.mjs +51 -0
  90. package/dist/plugins/blog/client/components/pages/new-post-page.mjs +35 -0
  91. package/dist/plugins/blog/client/components/pages/post-page.cjs +39 -0
  92. package/dist/plugins/blog/client/components/pages/post-page.internal.cjs +101 -0
  93. package/dist/plugins/blog/client/components/pages/post-page.internal.mjs +99 -0
  94. package/dist/plugins/blog/client/components/pages/post-page.mjs +37 -0
  95. package/dist/plugins/blog/client/components/pages/tag-page.cjs +39 -0
  96. package/dist/plugins/blog/client/components/pages/tag-page.internal.cjs +61 -0
  97. package/dist/plugins/blog/client/components/pages/tag-page.internal.mjs +59 -0
  98. package/dist/plugins/blog/client/components/pages/tag-page.mjs +37 -0
  99. package/dist/plugins/blog/client/components/shared/better-blog-attribution.cjs +24 -0
  100. package/dist/plugins/blog/client/components/shared/better-blog-attribution.mjs +22 -0
  101. package/dist/plugins/blog/client/components/shared/default-error.cjs +18 -0
  102. package/dist/plugins/blog/client/components/shared/default-error.mjs +16 -0
  103. package/dist/plugins/blog/client/components/shared/defaults.cjs +13 -0
  104. package/dist/plugins/blog/client/components/shared/defaults.mjs +10 -0
  105. package/dist/plugins/blog/client/components/shared/empty-list.cjs +21 -0
  106. package/dist/plugins/blog/client/components/shared/empty-list.mjs +19 -0
  107. package/dist/plugins/blog/client/components/shared/error-placeholder.cjs +24 -0
  108. package/dist/plugins/blog/client/components/shared/error-placeholder.mjs +22 -0
  109. package/dist/plugins/blog/client/components/shared/highlight-text.cjs +53 -0
  110. package/dist/plugins/blog/client/components/shared/highlight-text.mjs +51 -0
  111. package/dist/plugins/blog/client/components/shared/markdown-content-styles.css +328 -0
  112. package/dist/plugins/blog/client/components/shared/markdown-content.cjs +324 -0
  113. package/dist/plugins/blog/client/components/shared/markdown-content.mjs +315 -0
  114. package/dist/plugins/blog/client/components/shared/on-this-page.cjs +161 -0
  115. package/dist/plugins/blog/client/components/shared/on-this-page.mjs +158 -0
  116. package/dist/plugins/blog/client/components/shared/page-header.cjs +40 -0
  117. package/dist/plugins/blog/client/components/shared/page-header.mjs +38 -0
  118. package/dist/plugins/blog/client/components/shared/page-layout.cjs +24 -0
  119. package/dist/plugins/blog/client/components/shared/page-layout.mjs +22 -0
  120. package/dist/plugins/blog/client/components/shared/page-wrapper.cjs +23 -0
  121. package/dist/plugins/blog/client/components/shared/page-wrapper.mjs +21 -0
  122. package/dist/plugins/blog/client/components/shared/post-card.cjs +279 -0
  123. package/dist/plugins/blog/client/components/shared/post-card.mjs +277 -0
  124. package/dist/plugins/blog/client/components/shared/post-navigation.cjs +74 -0
  125. package/dist/plugins/blog/client/components/shared/post-navigation.mjs +72 -0
  126. package/dist/plugins/blog/client/components/shared/posts-list.cjs +48 -0
  127. package/dist/plugins/blog/client/components/shared/posts-list.mjs +46 -0
  128. package/dist/plugins/blog/client/components/shared/recent-posts-carousel.cjs +59 -0
  129. package/dist/plugins/blog/client/components/shared/recent-posts-carousel.mjs +57 -0
  130. package/dist/plugins/blog/client/components/shared/search-input.cjs +136 -0
  131. package/dist/plugins/blog/client/components/shared/search-input.mjs +117 -0
  132. package/dist/plugins/blog/client/components/shared/search-modal.cjs +135 -0
  133. package/dist/plugins/blog/client/components/shared/search-modal.mjs +116 -0
  134. package/dist/plugins/blog/client/components/shared/tags-list.cjs +22 -0
  135. package/dist/plugins/blog/client/components/shared/tags-list.mjs +20 -0
  136. package/dist/plugins/blog/client/components/shared/use-route-lifecycle.cjs +50 -0
  137. package/dist/plugins/blog/client/components/shared/use-route-lifecycle.mjs +48 -0
  138. package/dist/plugins/blog/client/hooks/blog-hooks.cjs +380 -0
  139. package/dist/plugins/blog/client/hooks/blog-hooks.mjs +368 -0
  140. package/dist/plugins/blog/client/hooks/index.cjs +17 -0
  141. package/dist/plugins/blog/client/hooks/index.d.cts +150 -0
  142. package/dist/plugins/blog/client/hooks/index.d.mts +150 -0
  143. package/dist/plugins/blog/client/hooks/index.d.ts +150 -0
  144. package/dist/plugins/blog/client/hooks/index.mjs +1 -0
  145. package/dist/plugins/blog/client/hooks/use-debounce.cjs +16 -0
  146. package/dist/plugins/blog/client/hooks/use-debounce.mjs +14 -0
  147. package/dist/plugins/blog/client/index.cjs +7 -0
  148. package/dist/plugins/blog/client/index.d.cts +414 -0
  149. package/dist/plugins/blog/client/index.d.mts +414 -0
  150. package/dist/plugins/blog/client/index.d.ts +414 -0
  151. package/dist/plugins/blog/client/index.mjs +1 -0
  152. package/dist/plugins/blog/client/localization/blog-card.cjs +7 -0
  153. package/dist/plugins/blog/client/localization/blog-card.mjs +5 -0
  154. package/dist/plugins/blog/client/localization/blog-common.cjs +10 -0
  155. package/dist/plugins/blog/client/localization/blog-common.mjs +8 -0
  156. package/dist/plugins/blog/client/localization/blog-forms.cjs +40 -0
  157. package/dist/plugins/blog/client/localization/blog-forms.mjs +38 -0
  158. package/dist/plugins/blog/client/localization/blog-list.cjs +18 -0
  159. package/dist/plugins/blog/client/localization/blog-list.mjs +16 -0
  160. package/dist/plugins/blog/client/localization/blog-post.cjs +13 -0
  161. package/dist/plugins/blog/client/localization/blog-post.mjs +11 -0
  162. package/dist/plugins/blog/client/localization/index.cjs +17 -0
  163. package/dist/plugins/blog/client/localization/index.mjs +15 -0
  164. package/dist/plugins/blog/client/plugin.cjs +462 -0
  165. package/dist/plugins/blog/client/plugin.mjs +460 -0
  166. package/dist/plugins/blog/client.css +3 -0
  167. package/dist/plugins/blog/db.cjs +90 -0
  168. package/dist/plugins/blog/db.mjs +88 -0
  169. package/dist/plugins/blog/query-keys.cjs +181 -0
  170. package/dist/plugins/blog/query-keys.d.cts +530 -0
  171. package/dist/plugins/blog/query-keys.d.mts +530 -0
  172. package/dist/plugins/blog/query-keys.d.ts +530 -0
  173. package/dist/plugins/blog/query-keys.mjs +179 -0
  174. package/dist/plugins/blog/schemas.cjs +39 -0
  175. package/dist/plugins/blog/schemas.mjs +35 -0
  176. package/dist/plugins/blog/style.css +22 -0
  177. package/dist/plugins/blog/utils.cjs +97 -0
  178. package/dist/plugins/blog/utils.mjs +87 -0
  179. package/dist/plugins/client/index.cjs +15 -0
  180. package/dist/plugins/client/index.d.cts +57 -0
  181. package/dist/plugins/client/index.d.mts +57 -0
  182. package/dist/plugins/client/index.d.ts +57 -0
  183. package/dist/plugins/client/index.mjs +9 -0
  184. package/dist/{shared/stack.3OUyGp_E.mjs → plugins/utils.mjs} +1 -1
  185. package/dist/shared/{stack.DORw_1ps.d.cts → stack.ByOugz9d.d.cts} +17 -1
  186. package/dist/shared/{stack.DORw_1ps.d.mts → stack.ByOugz9d.d.mts} +17 -1
  187. package/dist/shared/{stack.DORw_1ps.d.ts → stack.ByOugz9d.d.ts} +17 -1
  188. package/dist/shared/stack.CoPoHVfV.d.cts +76 -0
  189. package/dist/shared/stack.CoPoHVfV.d.mts +76 -0
  190. package/dist/shared/stack.CoPoHVfV.d.ts +76 -0
  191. package/package.json +102 -14
  192. package/src/__tests__/plugins.test.tsx +539 -0
  193. package/src/__tests__/sitemap.test.ts +60 -0
  194. package/src/api/index.ts +75 -0
  195. package/src/client/components/compose.tsx +116 -0
  196. package/src/client/components/error-boundary.tsx +30 -0
  197. package/src/client/components/index.tsx +2 -0
  198. package/src/client/index.ts +109 -0
  199. package/src/client/meta-utils.ts +228 -0
  200. package/src/client/path-utils.ts +38 -0
  201. package/src/client/sitemap-utils.ts +46 -0
  202. package/src/context/index.ts +1 -0
  203. package/src/context/provider.tsx +157 -0
  204. package/src/index.ts +1 -0
  205. package/src/plugins/api/index.ts +50 -0
  206. package/src/plugins/blog/api/index.ts +2 -0
  207. package/src/plugins/blog/api/plugin.ts +759 -0
  208. package/src/plugins/blog/client/components/forms/image-field.tsx +165 -0
  209. package/src/plugins/blog/client/components/forms/markdown-editor-styles.css +30 -0
  210. package/src/plugins/blog/client/components/forms/markdown-editor.tsx +136 -0
  211. package/src/plugins/blog/client/components/forms/post-forms.tsx +531 -0
  212. package/src/plugins/blog/client/components/forms/tags-multiselect.tsx +79 -0
  213. package/src/plugins/blog/client/components/index.tsx +11 -0
  214. package/src/plugins/blog/client/components/loading/form-page-skeleton.tsx +75 -0
  215. package/src/plugins/blog/client/components/loading/index.tsx +27 -0
  216. package/src/plugins/blog/client/components/loading/list-page-skeleton.tsx +38 -0
  217. package/src/plugins/blog/client/components/loading/page-header-skeleton.tsx +10 -0
  218. package/src/plugins/blog/client/components/loading/post-card-skeleton.tsx +30 -0
  219. package/src/plugins/blog/client/components/loading/post-page-skeleton.tsx +75 -0
  220. package/src/plugins/blog/client/components/pages/404-page.tsx +23 -0
  221. package/src/plugins/blog/client/components/pages/edit-post-page.internal.tsx +60 -0
  222. package/src/plugins/blog/client/components/pages/edit-post-page.tsx +40 -0
  223. package/src/plugins/blog/client/components/pages/home-page.internal.tsx +71 -0
  224. package/src/plugins/blog/client/components/pages/home-page.tsx +42 -0
  225. package/src/plugins/blog/client/components/pages/new-post-page.internal.tsx +59 -0
  226. package/src/plugins/blog/client/components/pages/new-post-page.tsx +36 -0
  227. package/src/plugins/blog/client/components/pages/post-page.internal.tsx +142 -0
  228. package/src/plugins/blog/client/components/pages/post-page.tsx +38 -0
  229. package/src/plugins/blog/client/components/pages/tag-page.internal.tsx +74 -0
  230. package/src/plugins/blog/client/components/pages/tag-page.tsx +38 -0
  231. package/src/plugins/blog/client/components/shared/better-blog-attribution.tsx +19 -0
  232. package/src/plugins/blog/client/components/shared/default-error.tsx +20 -0
  233. package/src/plugins/blog/client/components/shared/defaults.tsx +9 -0
  234. package/src/plugins/blog/client/components/shared/empty-list.tsx +25 -0
  235. package/src/plugins/blog/client/components/shared/error-placeholder.tsx +20 -0
  236. package/src/plugins/blog/client/components/shared/highlight-text.tsx +80 -0
  237. package/src/plugins/blog/client/components/shared/markdown-content-styles.css +328 -0
  238. package/src/plugins/blog/client/components/shared/markdown-content.tsx +448 -0
  239. package/src/plugins/blog/client/components/shared/on-this-page.tsx +234 -0
  240. package/src/plugins/blog/client/components/shared/page-header.tsx +35 -0
  241. package/src/plugins/blog/client/components/shared/page-layout.tsx +23 -0
  242. package/src/plugins/blog/client/components/shared/page-wrapper.tsx +32 -0
  243. package/src/plugins/blog/client/components/shared/post-card.tsx +308 -0
  244. package/src/plugins/blog/client/components/shared/post-navigation.tsx +98 -0
  245. package/src/plugins/blog/client/components/shared/posts-list.tsx +67 -0
  246. package/src/plugins/blog/client/components/shared/recent-posts-carousel.tsx +79 -0
  247. package/src/plugins/blog/client/components/shared/search-input.tsx +146 -0
  248. package/src/plugins/blog/client/components/shared/search-modal.tsx +162 -0
  249. package/src/plugins/blog/client/components/shared/tags-list.tsx +34 -0
  250. package/src/plugins/blog/client/components/shared/use-route-lifecycle.tsx +68 -0
  251. package/src/plugins/blog/client/hooks/blog-hooks.tsx +623 -0
  252. package/src/plugins/blog/client/hooks/index.tsx +1 -0
  253. package/src/plugins/blog/client/hooks/use-debounce.ts +43 -0
  254. package/src/plugins/blog/client/index.ts +9 -0
  255. package/src/plugins/blog/client/localization/blog-card.ts +3 -0
  256. package/src/plugins/blog/client/localization/blog-common.ts +7 -0
  257. package/src/plugins/blog/client/localization/blog-forms.ts +45 -0
  258. package/src/plugins/blog/client/localization/blog-list.ts +14 -0
  259. package/src/plugins/blog/client/localization/blog-post.ts +9 -0
  260. package/src/plugins/blog/client/localization/index.ts +15 -0
  261. package/src/plugins/blog/client/overrides.ts +123 -0
  262. package/src/plugins/blog/client/plugin.tsx +672 -0
  263. package/src/plugins/blog/client.css +3 -0
  264. package/src/plugins/blog/db.ts +90 -0
  265. package/src/plugins/blog/query-keys.ts +267 -0
  266. package/src/plugins/blog/schemas.ts +39 -0
  267. package/src/plugins/blog/style.css +22 -0
  268. package/src/plugins/blog/types.ts +37 -0
  269. package/src/plugins/blog/utils.ts +144 -0
  270. package/src/plugins/client/index.ts +53 -0
  271. package/src/plugins/index.ts +0 -0
  272. package/src/plugins/utils.ts +35 -0
  273. package/src/types.ts +209 -0
  274. package/dist/plugins/index.cjs +0 -15
  275. package/dist/plugins/index.d.cts +0 -64
  276. package/dist/plugins/index.d.mts +0 -64
  277. package/dist/plugins/index.d.ts +0 -64
  278. package/dist/plugins/index.mjs +0 -11
  279. package/dist/shared/stack.DrUAVfIH.d.cts +0 -17
  280. package/dist/shared/stack.DrUAVfIH.d.mts +0 -17
  281. package/dist/shared/stack.DrUAVfIH.d.ts +0 -17
  282. /package/dist/{shared/stack.CktCg4PJ.cjs → plugins/utils.cjs} +0 -0
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ const zod = require('zod');
4
+
5
+ const dateFields = {
6
+ publishedAt: zod.z.coerce.date().optional(),
7
+ createdAt: zod.z.coerce.date().optional(),
8
+ updatedAt: zod.z.coerce.date().optional()
9
+ };
10
+ const coreFields = {
11
+ title: zod.z.string().min(1, "Title is required"),
12
+ content: zod.z.string().min(1, "Content is required"),
13
+ excerpt: zod.z.string().min(1, "Excerpt is required"),
14
+ image: zod.z.string().optional(),
15
+ published: zod.z.boolean().optional().default(false),
16
+ slug: zod.z.string().min(1, "Slug is required"),
17
+ tags: zod.z.array(
18
+ zod.z.union([
19
+ zod.z.object({ name: zod.z.string() }),
20
+ zod.z.object({ id: zod.z.string(), name: zod.z.string(), slug: zod.z.string() })
21
+ ])
22
+ ).optional().default([])
23
+ };
24
+ const PostDomainSchema = zod.z.object({
25
+ id: zod.z.string().optional(),
26
+ ...coreFields,
27
+ ...dateFields
28
+ });
29
+ const createPostSchema = PostDomainSchema.extend({
30
+ slug: PostDomainSchema.shape.slug.optional()
31
+ }).omit({ id: true });
32
+ const updatePostSchema = PostDomainSchema.extend({
33
+ id: zod.z.string()
34
+ // required on update
35
+ });
36
+
37
+ exports.PostDomainSchema = PostDomainSchema;
38
+ exports.createPostSchema = createPostSchema;
39
+ exports.updatePostSchema = updatePostSchema;
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+
3
+ const dateFields = {
4
+ publishedAt: z.coerce.date().optional(),
5
+ createdAt: z.coerce.date().optional(),
6
+ updatedAt: z.coerce.date().optional()
7
+ };
8
+ const coreFields = {
9
+ title: z.string().min(1, "Title is required"),
10
+ content: z.string().min(1, "Content is required"),
11
+ excerpt: z.string().min(1, "Excerpt is required"),
12
+ image: z.string().optional(),
13
+ published: z.boolean().optional().default(false),
14
+ slug: z.string().min(1, "Slug is required"),
15
+ tags: z.array(
16
+ z.union([
17
+ z.object({ name: z.string() }),
18
+ z.object({ id: z.string(), name: z.string(), slug: z.string() })
19
+ ])
20
+ ).optional().default([])
21
+ };
22
+ const PostDomainSchema = z.object({
23
+ id: z.string().optional(),
24
+ ...coreFields,
25
+ ...dateFields
26
+ });
27
+ const createPostSchema = PostDomainSchema.extend({
28
+ slug: PostDomainSchema.shape.slug.optional()
29
+ }).omit({ id: true });
30
+ const updatePostSchema = PostDomainSchema.extend({
31
+ id: z.string()
32
+ // required on update
33
+ });
34
+
35
+ export { PostDomainSchema, createPostSchema, updatePostSchema };
@@ -0,0 +1,22 @@
1
+ @import "./client.css";
2
+
3
+ /*
4
+ * Blog Plugin CSS - Includes Tailwind class scanning
5
+ *
6
+ * When consumed from npm, Tailwind v4 will automatically scan this package's
7
+ * source files for Tailwind classes. Consumers only need:
8
+ * @import "@btst/stack/plugins/blog/css";
9
+ */
10
+
11
+ /* Scan this package's source files for Tailwind classes */
12
+ @source "../../../src/**/*.{ts,tsx}";
13
+
14
+ /* Scan UI package components (if in monorepo) */
15
+ @source "../../../../@workspace/ui/src/**/*.{ts,tsx}";
16
+
17
+ /* Scan UI package components (if installed as npm package) */
18
+ @source "../../../node_modules/@workspace/ui/src/**/*.{ts,tsx}";
19
+
20
+ /*
21
+ * alternatively consumer can use @source "../node_modules/@btst/stack/src/**\/*.{ts,tsx}";
22
+ */
@@ -0,0 +1,97 @@
1
+ 'use strict';
2
+
3
+ const clsx = require('clsx');
4
+ const tailwindMerge = require('tailwind-merge');
5
+ const slug = require('slug');
6
+
7
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
8
+
9
+ const slug__default = /*#__PURE__*/_interopDefaultCompat(slug);
10
+
11
+ function slugify(text, locale = "en") {
12
+ return slug__default(text, { lower: true, locale });
13
+ }
14
+ function cn(...inputs) {
15
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
16
+ }
17
+ function throttle(callback, waitMs) {
18
+ let timerId = null;
19
+ let lastInvokeTime = 0;
20
+ let trailingArgs = null;
21
+ const invoke = (args) => {
22
+ lastInvokeTime = Date.now();
23
+ callback(...args);
24
+ };
25
+ const throttled = (...args) => {
26
+ const now = Date.now();
27
+ const remaining = waitMs - (now - lastInvokeTime);
28
+ if (lastInvokeTime === 0) {
29
+ invoke(args);
30
+ return;
31
+ }
32
+ if (remaining <= 0 || remaining > waitMs) {
33
+ if (timerId) {
34
+ clearTimeout(timerId);
35
+ timerId = null;
36
+ }
37
+ invoke(args);
38
+ } else {
39
+ trailingArgs = args;
40
+ if (!timerId) {
41
+ timerId = setTimeout(() => {
42
+ timerId = null;
43
+ if (trailingArgs) {
44
+ invoke(trailingArgs);
45
+ trailingArgs = null;
46
+ }
47
+ }, remaining);
48
+ }
49
+ }
50
+ };
51
+ throttled.cancel = () => {
52
+ if (timerId) {
53
+ clearTimeout(timerId);
54
+ timerId = null;
55
+ }
56
+ trailingArgs = null;
57
+ lastInvokeTime = 0;
58
+ };
59
+ throttled.flush = () => {
60
+ if (timerId && trailingArgs) {
61
+ clearTimeout(timerId);
62
+ timerId = null;
63
+ invoke(trailingArgs);
64
+ trailingArgs = null;
65
+ }
66
+ };
67
+ return throttled;
68
+ }
69
+ function stripHtml(html) {
70
+ let text = html.replace(/<[^>]*>/g, "");
71
+ text = text.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#x27;/g, "'").replace(/&#x2F;/g, "/").replace(/&nbsp;/g, " ").replace(/&hellip;/g, "...");
72
+ return text.replace(/\s+/g, " ").trim();
73
+ }
74
+ function stripMarkdown(markdown) {
75
+ let text = markdown;
76
+ text = text.replace(/^#{1,6}\s+/gm, "");
77
+ text = text.replace(/\*\*([^*]+)\*\*/g, "$1");
78
+ text = text.replace(/\*([^*]+)\*/g, "$1");
79
+ text = text.replace(/__([^_]+)__/g, "$1");
80
+ text = text.replace(/_([^_]+)_/g, "$1");
81
+ text = text.replace(/~~([^~]+)~~/g, "$1");
82
+ text = text.replace(/`([^`]+)`/g, "$1");
83
+ text = text.replace(/```[\s\S]*?```/g, "");
84
+ text = text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
85
+ text = text.replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1");
86
+ text = text.replace(/^>\s+/gm, "");
87
+ text = text.replace(/^[-*]{3,}$/gm, "");
88
+ text = text.replace(/^[\s]*[-*+]\s+/gm, "");
89
+ text = text.replace(/^[\s]*\d+\.\s+/gm, "");
90
+ return text.replace(/\n\s*\n/g, "\n").replace(/\s+/g, " ").trim();
91
+ }
92
+
93
+ exports.cn = cn;
94
+ exports.slugify = slugify;
95
+ exports.stripHtml = stripHtml;
96
+ exports.stripMarkdown = stripMarkdown;
97
+ exports.throttle = throttle;
@@ -0,0 +1,87 @@
1
+ import { clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+ import slug from 'slug';
4
+
5
+ function slugify(text, locale = "en") {
6
+ return slug(text, { lower: true, locale });
7
+ }
8
+ function cn(...inputs) {
9
+ return twMerge(clsx(inputs));
10
+ }
11
+ function throttle(callback, waitMs) {
12
+ let timerId = null;
13
+ let lastInvokeTime = 0;
14
+ let trailingArgs = null;
15
+ const invoke = (args) => {
16
+ lastInvokeTime = Date.now();
17
+ callback(...args);
18
+ };
19
+ const throttled = (...args) => {
20
+ const now = Date.now();
21
+ const remaining = waitMs - (now - lastInvokeTime);
22
+ if (lastInvokeTime === 0) {
23
+ invoke(args);
24
+ return;
25
+ }
26
+ if (remaining <= 0 || remaining > waitMs) {
27
+ if (timerId) {
28
+ clearTimeout(timerId);
29
+ timerId = null;
30
+ }
31
+ invoke(args);
32
+ } else {
33
+ trailingArgs = args;
34
+ if (!timerId) {
35
+ timerId = setTimeout(() => {
36
+ timerId = null;
37
+ if (trailingArgs) {
38
+ invoke(trailingArgs);
39
+ trailingArgs = null;
40
+ }
41
+ }, remaining);
42
+ }
43
+ }
44
+ };
45
+ throttled.cancel = () => {
46
+ if (timerId) {
47
+ clearTimeout(timerId);
48
+ timerId = null;
49
+ }
50
+ trailingArgs = null;
51
+ lastInvokeTime = 0;
52
+ };
53
+ throttled.flush = () => {
54
+ if (timerId && trailingArgs) {
55
+ clearTimeout(timerId);
56
+ timerId = null;
57
+ invoke(trailingArgs);
58
+ trailingArgs = null;
59
+ }
60
+ };
61
+ return throttled;
62
+ }
63
+ function stripHtml(html) {
64
+ let text = html.replace(/<[^>]*>/g, "");
65
+ text = text.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#x27;/g, "'").replace(/&#x2F;/g, "/").replace(/&nbsp;/g, " ").replace(/&hellip;/g, "...");
66
+ return text.replace(/\s+/g, " ").trim();
67
+ }
68
+ function stripMarkdown(markdown) {
69
+ let text = markdown;
70
+ text = text.replace(/^#{1,6}\s+/gm, "");
71
+ text = text.replace(/\*\*([^*]+)\*\*/g, "$1");
72
+ text = text.replace(/\*([^*]+)\*/g, "$1");
73
+ text = text.replace(/__([^_]+)__/g, "$1");
74
+ text = text.replace(/_([^_]+)_/g, "$1");
75
+ text = text.replace(/~~([^~]+)~~/g, "$1");
76
+ text = text.replace(/`([^`]+)`/g, "$1");
77
+ text = text.replace(/```[\s\S]*?```/g, "");
78
+ text = text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
79
+ text = text.replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1");
80
+ text = text.replace(/^>\s+/gm, "");
81
+ text = text.replace(/^[-*]{3,}$/gm, "");
82
+ text = text.replace(/^[\s]*[-*+]\s+/gm, "");
83
+ text = text.replace(/^[\s]*\d+\.\s+/gm, "");
84
+ return text.replace(/\n\s*\n/g, "\n").replace(/\s+/g, " ").trim();
85
+ }
86
+
87
+ export { cn, slugify, stripHtml, stripMarkdown, throttle };
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ const utils = require('../utils.cjs');
4
+ const yar = require('@btst/yar');
5
+ const client = require('better-call/client');
6
+
7
+ function defineClientPlugin(plugin) {
8
+ return plugin;
9
+ }
10
+
11
+ exports.createApiClient = utils.createApiClient;
12
+ exports.createRoute = yar.createRoute;
13
+ exports.createRouter = yar.createRouter;
14
+ exports.createClient = client.createClient;
15
+ exports.defineClientPlugin = defineClientPlugin;
@@ -0,0 +1,57 @@
1
+ import { C as ClientPlugin } from '../../shared/stack.ByOugz9d.cjs';
2
+ export { P as PluginOverrides } from '../../shared/stack.ByOugz9d.cjs';
3
+ import { createClient } from 'better-call/client';
4
+ export { createClient } from 'better-call/client';
5
+ import { Router, Endpoint } from 'better-call';
6
+ export { Route, createRoute, createRouter } from '@btst/yar';
7
+ import '@btst/db';
8
+
9
+ interface CreateApiClientOptions {
10
+ baseURL?: string;
11
+ basePath?: string;
12
+ }
13
+ /**
14
+ * Creates a Better Call API client with proper URL handling for both server and client side
15
+ * @param options - Configuration options
16
+ * @param options.baseURL - The base URL (e.g., 'http://localhost:3000'). If not provided, uses relative URLs (same domain)
17
+ * @param options.basePath - The API base path (defaults to '/')
18
+ * @template TRouter - The router type (Router or Record<string, Endpoint>)
19
+ */
20
+ declare function createApiClient<TRouter extends Router | Record<string, Endpoint> = Record<string, Endpoint>>(options?: CreateApiClientOptions): ReturnType<typeof createClient<TRouter>>;
21
+
22
+ /**
23
+ * Plugin utilities and types for building standalone plugins
24
+ *
25
+ * This module exports everything needed to create custom plugins
26
+ * for Better Stack outside of this package.
27
+ *
28
+ * Note: Backend and Client plugins are separate to prevent SSR issues
29
+ * and enable better code splitting. Import them separately:
30
+ * - Backend: import type { BackendPlugin } from "@btst/stack/plugins/api"
31
+ * - Client: import type { ClientPlugin } from "@btst/stack/plugins/client"
32
+ */
33
+
34
+ /**
35
+ * Helper to define a client plugin with full type inference
36
+ *
37
+ * Automatically infers route keys, hook names, and their types without needing casts.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const messagesPlugin = defineClientPlugin({
42
+ * name: "messages",
43
+ * routes: () => ({
44
+ * messagesList: createRoute("/messages", () => ({ ... }))
45
+ * }),
46
+ * hooks: () => ({
47
+ * useMessages: () => { ... }
48
+ * })
49
+ * });
50
+ * // No casts needed - route keys, hook names, and types are all preserved!
51
+ * ```
52
+ *
53
+ * @template TPlugin - The exact plugin definition (auto-inferred)
54
+ */
55
+ declare function defineClientPlugin<TPlugin extends ClientPlugin<any, any>>(plugin: TPlugin): TPlugin;
56
+
57
+ export { ClientPlugin, createApiClient, defineClientPlugin };
@@ -0,0 +1,57 @@
1
+ import { C as ClientPlugin } from '../../shared/stack.ByOugz9d.mjs';
2
+ export { P as PluginOverrides } from '../../shared/stack.ByOugz9d.mjs';
3
+ import { createClient } from 'better-call/client';
4
+ export { createClient } from 'better-call/client';
5
+ import { Router, Endpoint } from 'better-call';
6
+ export { Route, createRoute, createRouter } from '@btst/yar';
7
+ import '@btst/db';
8
+
9
+ interface CreateApiClientOptions {
10
+ baseURL?: string;
11
+ basePath?: string;
12
+ }
13
+ /**
14
+ * Creates a Better Call API client with proper URL handling for both server and client side
15
+ * @param options - Configuration options
16
+ * @param options.baseURL - The base URL (e.g., 'http://localhost:3000'). If not provided, uses relative URLs (same domain)
17
+ * @param options.basePath - The API base path (defaults to '/')
18
+ * @template TRouter - The router type (Router or Record<string, Endpoint>)
19
+ */
20
+ declare function createApiClient<TRouter extends Router | Record<string, Endpoint> = Record<string, Endpoint>>(options?: CreateApiClientOptions): ReturnType<typeof createClient<TRouter>>;
21
+
22
+ /**
23
+ * Plugin utilities and types for building standalone plugins
24
+ *
25
+ * This module exports everything needed to create custom plugins
26
+ * for Better Stack outside of this package.
27
+ *
28
+ * Note: Backend and Client plugins are separate to prevent SSR issues
29
+ * and enable better code splitting. Import them separately:
30
+ * - Backend: import type { BackendPlugin } from "@btst/stack/plugins/api"
31
+ * - Client: import type { ClientPlugin } from "@btst/stack/plugins/client"
32
+ */
33
+
34
+ /**
35
+ * Helper to define a client plugin with full type inference
36
+ *
37
+ * Automatically infers route keys, hook names, and their types without needing casts.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const messagesPlugin = defineClientPlugin({
42
+ * name: "messages",
43
+ * routes: () => ({
44
+ * messagesList: createRoute("/messages", () => ({ ... }))
45
+ * }),
46
+ * hooks: () => ({
47
+ * useMessages: () => { ... }
48
+ * })
49
+ * });
50
+ * // No casts needed - route keys, hook names, and types are all preserved!
51
+ * ```
52
+ *
53
+ * @template TPlugin - The exact plugin definition (auto-inferred)
54
+ */
55
+ declare function defineClientPlugin<TPlugin extends ClientPlugin<any, any>>(plugin: TPlugin): TPlugin;
56
+
57
+ export { ClientPlugin, createApiClient, defineClientPlugin };
@@ -0,0 +1,57 @@
1
+ import { C as ClientPlugin } from '../../shared/stack.ByOugz9d.js';
2
+ export { P as PluginOverrides } from '../../shared/stack.ByOugz9d.js';
3
+ import { createClient } from 'better-call/client';
4
+ export { createClient } from 'better-call/client';
5
+ import { Router, Endpoint } from 'better-call';
6
+ export { Route, createRoute, createRouter } from '@btst/yar';
7
+ import '@btst/db';
8
+
9
+ interface CreateApiClientOptions {
10
+ baseURL?: string;
11
+ basePath?: string;
12
+ }
13
+ /**
14
+ * Creates a Better Call API client with proper URL handling for both server and client side
15
+ * @param options - Configuration options
16
+ * @param options.baseURL - The base URL (e.g., 'http://localhost:3000'). If not provided, uses relative URLs (same domain)
17
+ * @param options.basePath - The API base path (defaults to '/')
18
+ * @template TRouter - The router type (Router or Record<string, Endpoint>)
19
+ */
20
+ declare function createApiClient<TRouter extends Router | Record<string, Endpoint> = Record<string, Endpoint>>(options?: CreateApiClientOptions): ReturnType<typeof createClient<TRouter>>;
21
+
22
+ /**
23
+ * Plugin utilities and types for building standalone plugins
24
+ *
25
+ * This module exports everything needed to create custom plugins
26
+ * for Better Stack outside of this package.
27
+ *
28
+ * Note: Backend and Client plugins are separate to prevent SSR issues
29
+ * and enable better code splitting. Import them separately:
30
+ * - Backend: import type { BackendPlugin } from "@btst/stack/plugins/api"
31
+ * - Client: import type { ClientPlugin } from "@btst/stack/plugins/client"
32
+ */
33
+
34
+ /**
35
+ * Helper to define a client plugin with full type inference
36
+ *
37
+ * Automatically infers route keys, hook names, and their types without needing casts.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const messagesPlugin = defineClientPlugin({
42
+ * name: "messages",
43
+ * routes: () => ({
44
+ * messagesList: createRoute("/messages", () => ({ ... }))
45
+ * }),
46
+ * hooks: () => ({
47
+ * useMessages: () => { ... }
48
+ * })
49
+ * });
50
+ * // No casts needed - route keys, hook names, and types are all preserved!
51
+ * ```
52
+ *
53
+ * @template TPlugin - The exact plugin definition (auto-inferred)
54
+ */
55
+ declare function defineClientPlugin<TPlugin extends ClientPlugin<any, any>>(plugin: TPlugin): TPlugin;
56
+
57
+ export { ClientPlugin, createApiClient, defineClientPlugin };
@@ -0,0 +1,9 @@
1
+ export { createApiClient } from '../utils.mjs';
2
+ export { createRoute, createRouter } from '@btst/yar';
3
+ export { createClient } from 'better-call/client';
4
+
5
+ function defineClientPlugin(plugin) {
6
+ return plugin;
7
+ }
8
+
9
+ export { defineClientPlugin };
@@ -11,4 +11,4 @@ function createApiClient(options) {
11
11
  });
12
12
  }
13
13
 
14
- export { createApiClient as c };
14
+ export { createApiClient };
@@ -39,6 +39,11 @@ interface ClientPlugin<TOverrides = Record<string, never>, TRoutes extends Recor
39
39
  * Returns yar routes that will be composed into the router
40
40
  */
41
41
  routes: () => TRoutes;
42
+ /**
43
+ * Optional sitemap generator for this plugin. Should return absolute URLs.
44
+ * Implementations can call their own API endpoints to include dynamic routes.
45
+ */
46
+ sitemap?: () => Promise<Sitemap> | Sitemap;
42
47
  }
43
48
  /**
44
49
  * Configuration for creating the backend library
@@ -111,6 +116,17 @@ type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) exten
111
116
  */
112
117
  interface ClientLib<TRoutes extends Record<string, Route> = Record<string, Route>> {
113
118
  router: ReturnType<typeof createRouter<TRoutes, {}>>;
119
+ generateSitemap: () => Promise<Sitemap>;
114
120
  }
121
+ /**
122
+ * Minimal sitemap entry shape aligned with Next.js MetadataRoute.Sitemap
123
+ */
124
+ type SitemapEntry = {
125
+ url: string;
126
+ lastModified?: string | Date;
127
+ changeFrequency?: "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
128
+ priority?: number;
129
+ };
130
+ type Sitemap = Array<SitemapEntry>;
115
131
 
116
- export type { BackendPlugin as B, ClientPlugin as C, InferPluginOverrides as I, PluginRoutes as P, ClientLibConfig as a, ClientLib as b, PluginOverrides as c, PrefixedPluginRoutes as d, BackendLibConfig as e, BackendLib as f };
132
+ export type { BackendPlugin as B, ClientPlugin as C, PluginOverrides as P, Sitemap as S, PluginRoutes as a, ClientLibConfig as b, ClientLib as c, PrefixedPluginRoutes as d, BackendLibConfig as e, BackendLib as f };
@@ -39,6 +39,11 @@ interface ClientPlugin<TOverrides = Record<string, never>, TRoutes extends Recor
39
39
  * Returns yar routes that will be composed into the router
40
40
  */
41
41
  routes: () => TRoutes;
42
+ /**
43
+ * Optional sitemap generator for this plugin. Should return absolute URLs.
44
+ * Implementations can call their own API endpoints to include dynamic routes.
45
+ */
46
+ sitemap?: () => Promise<Sitemap> | Sitemap;
42
47
  }
43
48
  /**
44
49
  * Configuration for creating the backend library
@@ -111,6 +116,17 @@ type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) exten
111
116
  */
112
117
  interface ClientLib<TRoutes extends Record<string, Route> = Record<string, Route>> {
113
118
  router: ReturnType<typeof createRouter<TRoutes, {}>>;
119
+ generateSitemap: () => Promise<Sitemap>;
114
120
  }
121
+ /**
122
+ * Minimal sitemap entry shape aligned with Next.js MetadataRoute.Sitemap
123
+ */
124
+ type SitemapEntry = {
125
+ url: string;
126
+ lastModified?: string | Date;
127
+ changeFrequency?: "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
128
+ priority?: number;
129
+ };
130
+ type Sitemap = Array<SitemapEntry>;
115
131
 
116
- export type { BackendPlugin as B, ClientPlugin as C, InferPluginOverrides as I, PluginRoutes as P, ClientLibConfig as a, ClientLib as b, PluginOverrides as c, PrefixedPluginRoutes as d, BackendLibConfig as e, BackendLib as f };
132
+ export type { BackendPlugin as B, ClientPlugin as C, PluginOverrides as P, Sitemap as S, PluginRoutes as a, ClientLibConfig as b, ClientLib as c, PrefixedPluginRoutes as d, BackendLibConfig as e, BackendLib as f };
@@ -39,6 +39,11 @@ interface ClientPlugin<TOverrides = Record<string, never>, TRoutes extends Recor
39
39
  * Returns yar routes that will be composed into the router
40
40
  */
41
41
  routes: () => TRoutes;
42
+ /**
43
+ * Optional sitemap generator for this plugin. Should return absolute URLs.
44
+ * Implementations can call their own API endpoints to include dynamic routes.
45
+ */
46
+ sitemap?: () => Promise<Sitemap> | Sitemap;
42
47
  }
43
48
  /**
44
49
  * Configuration for creating the backend library
@@ -111,6 +116,17 @@ type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) exten
111
116
  */
112
117
  interface ClientLib<TRoutes extends Record<string, Route> = Record<string, Route>> {
113
118
  router: ReturnType<typeof createRouter<TRoutes, {}>>;
119
+ generateSitemap: () => Promise<Sitemap>;
114
120
  }
121
+ /**
122
+ * Minimal sitemap entry shape aligned with Next.js MetadataRoute.Sitemap
123
+ */
124
+ type SitemapEntry = {
125
+ url: string;
126
+ lastModified?: string | Date;
127
+ changeFrequency?: "always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never";
128
+ priority?: number;
129
+ };
130
+ type Sitemap = Array<SitemapEntry>;
115
131
 
116
- export type { BackendPlugin as B, ClientPlugin as C, InferPluginOverrides as I, PluginRoutes as P, ClientLibConfig as a, ClientLib as b, PluginOverrides as c, PrefixedPluginRoutes as d, BackendLibConfig as e, BackendLib as f };
132
+ export type { BackendPlugin as B, ClientPlugin as C, PluginOverrides as P, Sitemap as S, PluginRoutes as a, ClientLibConfig as b, ClientLib as c, PrefixedPluginRoutes as d, BackendLibConfig as e, BackendLib as f };
@@ -0,0 +1,76 @@
1
+ import { z } from 'zod';
2
+
3
+ type Post = {
4
+ id: string;
5
+ authorId?: string;
6
+ defaultLocale?: string;
7
+ slug: string;
8
+ title: string;
9
+ content: string;
10
+ excerpt: string;
11
+ image?: string;
12
+ published: boolean;
13
+ status?: "DRAFT" | "PUBLISHED";
14
+ tags: Tag[];
15
+ publishedAt?: Date;
16
+ createdAt: Date;
17
+ updatedAt: Date;
18
+ };
19
+ type Tag = {
20
+ id: string;
21
+ slug: string;
22
+ name: string;
23
+ createdAt: Date;
24
+ updatedAt: Date;
25
+ };
26
+ interface SerializedPost extends Omit<Post, "createdAt" | "updatedAt" | "publishedAt" | "tags"> {
27
+ tags: SerializedTag[];
28
+ publishedAt?: string;
29
+ createdAt: string;
30
+ updatedAt: string;
31
+ }
32
+ interface SerializedTag extends Omit<Tag, "createdAt" | "updatedAt"> {
33
+ createdAt: string;
34
+ updatedAt: string;
35
+ }
36
+
37
+ declare const createPostSchema: z.ZodObject<{
38
+ slug: z.ZodOptional<z.ZodString>;
39
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
40
+ createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
41
+ publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
42
+ updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
43
+ title: z.ZodString;
44
+ content: z.ZodString;
45
+ excerpt: z.ZodString;
46
+ image: z.ZodOptional<z.ZodString>;
47
+ tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
48
+ name: z.ZodString;
49
+ }, z.core.$strip>, z.ZodObject<{
50
+ id: z.ZodString;
51
+ name: z.ZodString;
52
+ slug: z.ZodString;
53
+ }, z.core.$strip>]>>>>;
54
+ }, z.core.$strip>;
55
+ declare const updatePostSchema: z.ZodObject<{
56
+ publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
57
+ createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
58
+ updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
59
+ title: z.ZodString;
60
+ content: z.ZodString;
61
+ excerpt: z.ZodString;
62
+ image: z.ZodOptional<z.ZodString>;
63
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
64
+ slug: z.ZodString;
65
+ tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
66
+ name: z.ZodString;
67
+ }, z.core.$strip>, z.ZodObject<{
68
+ id: z.ZodString;
69
+ name: z.ZodString;
70
+ slug: z.ZodString;
71
+ }, z.core.$strip>]>>>>;
72
+ id: z.ZodString;
73
+ }, z.core.$strip>;
74
+
75
+ export { createPostSchema as c, updatePostSchema as u };
76
+ export type { Post as P, SerializedPost as S, Tag as T, SerializedTag as a };