@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,462 @@
1
+ 'use strict';
2
+
3
+ const jsxRuntime = require('react/jsx-runtime');
4
+ const client = require('@btst/stack/plugins/client');
5
+ const yar = require('@btst/yar');
6
+ const plugins_blog_queryKeys = require('../query-keys.cjs');
7
+ const homePage = require('./components/pages/home-page.cjs');
8
+ const newPostPage = require('./components/pages/new-post-page.cjs');
9
+ const editPostPage = require('./components/pages/edit-post-page.cjs');
10
+ const tagPage = require('./components/pages/tag-page.cjs');
11
+ const postPage = require('./components/pages/post-page.cjs');
12
+
13
+ function createPostsLoader(published, config) {
14
+ return async () => {
15
+ if (typeof window === "undefined") {
16
+ const { queryClient, apiBasePath, apiBaseURL, hooks } = config;
17
+ const context = {
18
+ path: published ? "/blog" : "/blog/drafts",
19
+ isSSR: true,
20
+ apiBaseURL,
21
+ apiBasePath
22
+ };
23
+ try {
24
+ if (hooks?.beforeLoadPosts) {
25
+ const canLoad = await hooks.beforeLoadPosts({ published }, context);
26
+ if (!canLoad) {
27
+ throw new Error("Load prevented by beforeLoadPosts hook");
28
+ }
29
+ }
30
+ const limit = 10;
31
+ const client$1 = client.createApiClient({
32
+ baseURL: apiBaseURL,
33
+ basePath: apiBasePath
34
+ });
35
+ const queries = plugins_blog_queryKeys.createBlogQueryKeys(client$1);
36
+ const listQuery = queries.posts.list({
37
+ query: void 0,
38
+ limit,
39
+ published
40
+ });
41
+ await queryClient.prefetchInfiniteQuery({
42
+ ...listQuery,
43
+ initialPageParam: 0
44
+ });
45
+ const tagsQuery = queries.tags.list();
46
+ await queryClient.prefetchQuery(tagsQuery);
47
+ if (hooks?.afterLoadPosts) {
48
+ const posts = queryClient.getQueryData(listQuery.queryKey) || null;
49
+ await hooks.afterLoadPosts(posts, { published }, context);
50
+ }
51
+ const queryState = queryClient.getQueryState(listQuery.queryKey);
52
+ if (queryState?.error) {
53
+ if (hooks?.onLoadError) {
54
+ const error = queryState.error instanceof Error ? queryState.error : new Error(String(queryState.error));
55
+ await hooks.onLoadError(error, context);
56
+ }
57
+ }
58
+ } catch (error) {
59
+ if (hooks?.onLoadError) {
60
+ await hooks.onLoadError(error, context);
61
+ }
62
+ }
63
+ }
64
+ };
65
+ }
66
+ function createPostLoader(slug, config) {
67
+ return async () => {
68
+ if (typeof window === "undefined") {
69
+ const { queryClient, apiBasePath, apiBaseURL, hooks } = config;
70
+ const context = {
71
+ path: `/blog/${slug}`,
72
+ params: { slug },
73
+ isSSR: true,
74
+ apiBaseURL,
75
+ apiBasePath
76
+ };
77
+ try {
78
+ if (hooks?.beforeLoadPost) {
79
+ const canLoad = await hooks.beforeLoadPost(slug, context);
80
+ if (!canLoad) {
81
+ throw new Error("Load prevented by beforeLoadPost hook");
82
+ }
83
+ }
84
+ const client$1 = client.createApiClient({
85
+ baseURL: apiBaseURL,
86
+ basePath: apiBasePath
87
+ });
88
+ const queries = plugins_blog_queryKeys.createBlogQueryKeys(client$1);
89
+ const postQuery = queries.posts.detail(slug);
90
+ await queryClient.prefetchQuery(postQuery);
91
+ if (hooks?.afterLoadPost) {
92
+ const post = queryClient.getQueryData(postQuery.queryKey) || null;
93
+ await hooks.afterLoadPost(post, slug, context);
94
+ }
95
+ const queryState = queryClient.getQueryState(postQuery.queryKey);
96
+ if (queryState?.error) {
97
+ if (hooks?.onLoadError) {
98
+ const error = queryState.error instanceof Error ? queryState.error : new Error(String(queryState.error));
99
+ await hooks.onLoadError(error, context);
100
+ }
101
+ }
102
+ } catch (error) {
103
+ if (hooks?.onLoadError) {
104
+ await hooks.onLoadError(error, context);
105
+ }
106
+ }
107
+ }
108
+ };
109
+ }
110
+ function createTagLoader(tagSlug, config) {
111
+ return async () => {
112
+ if (typeof window === "undefined") {
113
+ const { queryClient, apiBasePath, apiBaseURL, hooks } = config;
114
+ const context = {
115
+ path: `/blog/tag/${tagSlug}`,
116
+ params: { tagSlug },
117
+ isSSR: true,
118
+ apiBaseURL,
119
+ apiBasePath
120
+ };
121
+ try {
122
+ const limit = 10;
123
+ const client$1 = client.createApiClient({
124
+ baseURL: apiBaseURL,
125
+ basePath: apiBasePath
126
+ });
127
+ const queries = plugins_blog_queryKeys.createBlogQueryKeys(client$1);
128
+ const listQuery = queries.posts.list({
129
+ query: void 0,
130
+ limit,
131
+ published: true,
132
+ tagSlug
133
+ });
134
+ await queryClient.prefetchInfiniteQuery({
135
+ ...listQuery,
136
+ initialPageParam: 0
137
+ });
138
+ const tagsQuery = queries.tags.list();
139
+ await queryClient.prefetchQuery(tagsQuery);
140
+ if (hooks?.onLoadError) {
141
+ const queryState = queryClient.getQueryState(listQuery.queryKey);
142
+ if (queryState?.error) {
143
+ const error = queryState.error instanceof Error ? queryState.error : new Error(String(queryState.error));
144
+ await hooks.onLoadError(error, context);
145
+ }
146
+ }
147
+ } catch (error) {
148
+ if (hooks?.onLoadError) {
149
+ await hooks.onLoadError(error, context);
150
+ }
151
+ }
152
+ }
153
+ };
154
+ }
155
+ function createPostsListMeta(published, config) {
156
+ return () => {
157
+ const { siteBaseURL, siteBasePath, seo } = config;
158
+ const path = published ? "/blog" : "/blog/drafts";
159
+ const fullUrl = `${siteBaseURL}${siteBasePath}${path}`;
160
+ const title = published ? "Blog" : "Draft Posts";
161
+ const description = published ? "Read our latest articles, insights, and updates on web development, technology, and more." : "View and manage your draft blog posts.";
162
+ return [
163
+ // Primary meta tags
164
+ { title },
165
+ { name: "title", content: title },
166
+ { name: "description", content: description },
167
+ {
168
+ name: "keywords",
169
+ content: "blog, articles, technology, web development, insights"
170
+ },
171
+ ...seo?.author ? [{ name: "author", content: seo.author }] : [],
172
+ {
173
+ name: "robots",
174
+ content: published ? "index, follow" : "noindex, nofollow"
175
+ },
176
+ // Open Graph / Facebook
177
+ { property: "og:type", content: "website" },
178
+ { property: "og:title", content: title },
179
+ { property: "og:description", content: description },
180
+ { property: "og:url", content: fullUrl },
181
+ ...seo?.siteName ? [{ property: "og:site_name", content: seo.siteName }] : [],
182
+ ...seo?.locale ? [{ property: "og:locale", content: seo.locale }] : [],
183
+ ...seo?.defaultImage ? [{ property: "og:image", content: seo.defaultImage }] : [],
184
+ // Twitter Card
185
+ { name: "twitter:card", content: "summary_large_image" },
186
+ { name: "twitter:title", content: title },
187
+ { name: "twitter:description", content: description },
188
+ ...seo?.twitterHandle ? [{ name: "twitter:site", content: seo.twitterHandle }] : []
189
+ ];
190
+ };
191
+ }
192
+ function createPostMeta(slug, config) {
193
+ return () => {
194
+ const { queryClient } = config;
195
+ const { apiBaseURL, apiBasePath, siteBaseURL, siteBasePath, seo } = config;
196
+ const queries = plugins_blog_queryKeys.createBlogQueryKeys(
197
+ client.createApiClient({
198
+ baseURL: apiBaseURL,
199
+ basePath: apiBasePath
200
+ })
201
+ );
202
+ const post = queryClient.getQueryData(
203
+ queries.posts.detail(slug).queryKey
204
+ );
205
+ if (!post) {
206
+ return [
207
+ { title: "Unknown route" },
208
+ { name: "title", content: "Unknown route" },
209
+ { name: "robots", content: "noindex" }
210
+ ];
211
+ }
212
+ const fullUrl = `${siteBaseURL}${siteBasePath}/blog/${post.slug}`;
213
+ const title = post.title;
214
+ const description = post.excerpt || post.content.substring(0, 160);
215
+ const publishedTime = post.publishedAt ? new Date(post.publishedAt).toISOString() : new Date(post.createdAt).toISOString();
216
+ const modifiedTime = new Date(post.updatedAt).toISOString();
217
+ const image = post.image || seo?.defaultImage;
218
+ return [
219
+ // Primary meta tags
220
+ { title },
221
+ { name: "title", content: title },
222
+ { name: "description", content: description },
223
+ ...post.authorId || seo?.author ? [{ name: "author", content: post.authorId || seo?.author }] : [],
224
+ {
225
+ name: "robots",
226
+ content: post.published ? "index, follow" : "noindex, nofollow"
227
+ },
228
+ {
229
+ name: "keywords",
230
+ content: `blog, article, ${post.slug.replace(/-/g, ", ")}`
231
+ },
232
+ // Open Graph / Facebook
233
+ { property: "og:type", content: "article" },
234
+ { property: "og:title", content: title },
235
+ { property: "og:description", content: description },
236
+ { property: "og:url", content: fullUrl },
237
+ ...seo?.siteName ? [{ property: "og:site_name", content: seo.siteName }] : [],
238
+ ...seo?.locale ? [{ property: "og:locale", content: seo.locale }] : [],
239
+ ...image ? [{ property: "og:image", content: image }] : [],
240
+ ...image ? [
241
+ { property: "og:image:width", content: "1200" },
242
+ { property: "og:image:height", content: "630" },
243
+ { property: "og:image:alt", content: title }
244
+ ] : [],
245
+ // Article-specific Open Graph tags
246
+ { property: "article:published_time", content: publishedTime },
247
+ { property: "article:modified_time", content: modifiedTime },
248
+ ...post.authorId ? [{ property: "article:author", content: post.authorId }] : [],
249
+ // Twitter Card
250
+ {
251
+ name: "twitter:card",
252
+ content: image ? "summary_large_image" : "summary"
253
+ },
254
+ { name: "twitter:title", content: title },
255
+ { name: "twitter:description", content: description },
256
+ ...seo?.twitterHandle ? [{ name: "twitter:site", content: seo.twitterHandle }] : [],
257
+ ...post.authorId || seo?.twitterHandle ? [
258
+ {
259
+ name: "twitter:creator",
260
+ content: post.authorId || seo?.twitterHandle
261
+ }
262
+ ] : [],
263
+ ...image ? [{ name: "twitter:image", content: image }] : [],
264
+ ...image ? [{ name: "twitter:image:alt", content: title }] : [],
265
+ // Additional SEO tags
266
+ { name: "publish_date", content: publishedTime }
267
+ ];
268
+ };
269
+ }
270
+ function createTagMeta(tagSlug, config) {
271
+ return () => {
272
+ const { queryClient } = config;
273
+ const { apiBaseURL, apiBasePath, siteBaseURL, siteBasePath, seo } = config;
274
+ const queries = plugins_blog_queryKeys.createBlogQueryKeys(
275
+ client.createApiClient({
276
+ baseURL: apiBaseURL,
277
+ basePath: apiBasePath
278
+ })
279
+ );
280
+ const tags = queryClient.getQueryData(
281
+ queries.tags.list().queryKey
282
+ );
283
+ const tag = tags?.find((t) => t.slug === tagSlug);
284
+ if (!tag) {
285
+ return [
286
+ { title: "Unknown route" },
287
+ { name: "title", content: "Unknown route" },
288
+ { name: "robots", content: "noindex" }
289
+ ];
290
+ }
291
+ const fullUrl = `${siteBaseURL}${siteBasePath}/blog/tag/${tag.slug}`;
292
+ const title = `${tag.name} Posts`;
293
+ const description = `Browse all ${tag.name} posts`;
294
+ return [
295
+ { title },
296
+ { name: "title", content: title },
297
+ { name: "description", content: description },
298
+ { name: "robots", content: "index, follow" },
299
+ { name: "keywords", content: `blog, ${tag.name}, articles` },
300
+ { property: "og:type", content: "website" },
301
+ { property: "og:title", content: title },
302
+ { property: "og:description", content: description },
303
+ { property: "og:url", content: fullUrl },
304
+ ...seo?.siteName ? [{ property: "og:site_name", content: seo.siteName }] : [],
305
+ ...seo?.defaultImage ? [{ property: "og:image", content: seo.defaultImage }] : [],
306
+ { name: "twitter:card", content: "summary" },
307
+ { name: "twitter:title", content: title }
308
+ ];
309
+ };
310
+ }
311
+ function createNewPostMeta(config) {
312
+ return () => {
313
+ const { siteBaseURL, siteBasePath } = config;
314
+ const fullUrl = `${siteBaseURL}${siteBasePath}/blog/new`;
315
+ const title = "Create New Post";
316
+ return [
317
+ { title },
318
+ { name: "title", content: title },
319
+ { name: "description", content: "Write and publish a new blog post." },
320
+ { name: "robots", content: "noindex, nofollow" },
321
+ // Open Graph
322
+ { property: "og:type", content: "website" },
323
+ { property: "og:title", content: title },
324
+ {
325
+ property: "og:description",
326
+ content: "Write and publish a new blog post."
327
+ },
328
+ { property: "og:url", content: fullUrl },
329
+ // Twitter
330
+ { name: "twitter:card", content: "summary" },
331
+ { name: "twitter:title", content: title }
332
+ ];
333
+ };
334
+ }
335
+ function createEditPostMeta(slug, config) {
336
+ return () => {
337
+ const { queryClient } = config;
338
+ const { apiBaseURL, apiBasePath, siteBaseURL, siteBasePath } = config;
339
+ const queries = plugins_blog_queryKeys.createBlogQueryKeys(
340
+ client.createApiClient({
341
+ baseURL: apiBaseURL,
342
+ basePath: apiBasePath
343
+ })
344
+ );
345
+ const post = queryClient.getQueryData(
346
+ queries.posts.detail(slug).queryKey
347
+ );
348
+ const fullUrl = `${siteBaseURL}${siteBasePath}/blog/${slug}/edit`;
349
+ const title = post ? `Edit: ${post.title}` : "Unknown route";
350
+ return [
351
+ { title },
352
+ { name: "title", content: title },
353
+ { name: "description", content: "Edit your blog post." },
354
+ { name: "robots", content: "noindex, nofollow" },
355
+ // Open Graph
356
+ { property: "og:type", content: "website" },
357
+ { property: "og:title", content: title },
358
+ { property: "og:url", content: fullUrl },
359
+ // Twitter
360
+ { name: "twitter:card", content: "summary" },
361
+ { name: "twitter:title", content: title }
362
+ ];
363
+ };
364
+ }
365
+ const blogClientPlugin = (config) => client.defineClientPlugin({
366
+ name: "blog",
367
+ routes: () => ({
368
+ posts: yar.createRoute("/blog", () => {
369
+ return {
370
+ PageComponent: () => /* @__PURE__ */ jsxRuntime.jsx(homePage.HomePageComponent, { published: true }),
371
+ loader: createPostsLoader(true, config),
372
+ meta: createPostsListMeta(true, config)
373
+ };
374
+ }),
375
+ drafts: yar.createRoute("/blog/drafts", () => {
376
+ return {
377
+ PageComponent: () => /* @__PURE__ */ jsxRuntime.jsx(homePage.HomePageComponent, { published: false }),
378
+ loader: createPostsLoader(false, config),
379
+ meta: createPostsListMeta(false, config)
380
+ };
381
+ }),
382
+ newPost: yar.createRoute("/blog/new", () => {
383
+ return {
384
+ PageComponent: newPostPage.NewPostPageComponent,
385
+ meta: createNewPostMeta(config)
386
+ };
387
+ }),
388
+ editPost: yar.createRoute("/blog/:slug/edit", ({ params: { slug } }) => {
389
+ return {
390
+ PageComponent: () => /* @__PURE__ */ jsxRuntime.jsx(editPostPage.EditPostPageComponent, { slug }),
391
+ loader: createPostLoader(slug, config),
392
+ meta: createEditPostMeta(slug, config)
393
+ };
394
+ }),
395
+ tag: yar.createRoute("/blog/tag/:tagSlug", ({ params: { tagSlug } }) => {
396
+ return {
397
+ PageComponent: () => /* @__PURE__ */ jsxRuntime.jsx(tagPage.TagPageComponent, { tagSlug }),
398
+ loader: createTagLoader(tagSlug, config),
399
+ meta: createTagMeta(tagSlug, config)
400
+ };
401
+ }),
402
+ post: yar.createRoute("/blog/:slug", ({ params: { slug } }) => {
403
+ return {
404
+ PageComponent: () => /* @__PURE__ */ jsxRuntime.jsx(postPage.PostPageComponent, { slug }),
405
+ loader: createPostLoader(slug, config),
406
+ meta: createPostMeta(slug, config)
407
+ };
408
+ })
409
+ }),
410
+ sitemap: async () => {
411
+ const origin = `${config.siteBaseURL}${config.siteBasePath}`;
412
+ const indexUrl = `${origin}/blog`;
413
+ const client$1 = client.createApiClient({
414
+ baseURL: config.apiBaseURL,
415
+ basePath: config.apiBasePath
416
+ });
417
+ const limit = 100;
418
+ let offset = 0;
419
+ const posts = [];
420
+ while (true) {
421
+ const res = await client$1("/posts", {
422
+ method: "GET",
423
+ query: {
424
+ offset,
425
+ limit,
426
+ published: "true"
427
+ }
428
+ });
429
+ const page = res.data ?? [];
430
+ posts.push(...page);
431
+ if (page.length < limit) break;
432
+ offset += limit;
433
+ }
434
+ const getLastModified = (p) => {
435
+ const dates = [p.updatedAt, p.publishedAt, p.createdAt].filter(
436
+ Boolean
437
+ );
438
+ if (dates.length === 0) return void 0;
439
+ const times = dates.map((d) => new Date(d).getTime()).filter((t) => !Number.isNaN(t));
440
+ if (times.length === 0) return void 0;
441
+ return new Date(Math.max(...times));
442
+ };
443
+ const latestTime = posts.map((p) => getLastModified(p)?.getTime() ?? 0).reduce((a, b) => Math.max(a, b), 0);
444
+ const entries = [
445
+ {
446
+ url: indexUrl,
447
+ lastModified: latestTime ? new Date(latestTime) : void 0,
448
+ changeFrequency: "daily",
449
+ priority: 0.7
450
+ },
451
+ ...posts.map((p) => ({
452
+ url: `${origin}/blog/${p.slug}`,
453
+ lastModified: getLastModified(p),
454
+ changeFrequency: "monthly",
455
+ priority: 0.6
456
+ }))
457
+ ];
458
+ return entries;
459
+ }
460
+ });
461
+
462
+ exports.blogClientPlugin = blogClientPlugin;