@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
@@ -1,9 +1,99 @@
1
- import { C as ClientPlugin, P as PluginRoutes, a as ClientLibConfig, b as ClientLib } from '../shared/stack.DORw_1ps.mjs';
2
- export { createRoute } from '@btst/yar';
3
- export { c as createApiClient } from '../shared/stack.DrUAVfIH.mjs';
1
+ import { S as Sitemap, C as ClientPlugin, a as PluginRoutes, b as ClientLibConfig, c as ClientLib } from '../shared/stack.ByOugz9d.mjs';
2
+ import '@btst/yar';
4
3
  import '@btst/db';
5
4
  import 'better-call';
6
- import 'better-call/client';
5
+
6
+ /**
7
+ * Converts an array of sitemap entries into an XML string following the sitemap.org protocol.
8
+ *
9
+ * @param entries - Array of sitemap entries from `lib.generateSitemap()`
10
+ * @returns Complete XML string for the sitemap
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const entries = await lib.generateSitemap();
15
+ * const xml = sitemapEntryToXmlString(entries);
16
+ * return new Response(xml, {
17
+ * headers: { "Content-Type": "application/xml; charset=utf-8" }
18
+ * });
19
+ * ```
20
+ */
21
+ declare function sitemapEntryToXmlString(entries: Sitemap): string;
22
+
23
+ interface Metadata {
24
+ title: string;
25
+ description?: string;
26
+ keywords?: string[];
27
+ applicationName?: string;
28
+ generator?: string;
29
+ referrer?: "no-referrer" | "origin" | "no-referrer-when-downgrade" | "origin-when-cross-origin" | "same-origin" | "strict-origin" | "strict-origin-when-cross-origin";
30
+ themeColor?: string;
31
+ viewport?: string;
32
+ creator?: string;
33
+ publisher?: string;
34
+ authors?: {
35
+ name: string;
36
+ }[];
37
+ abstract?: string;
38
+ robots?: string;
39
+ alternates?: Partial<{
40
+ canonical: string;
41
+ }>;
42
+ twitter?: Partial<{
43
+ title: string;
44
+ description: string;
45
+ site: string;
46
+ creator: string;
47
+ images?: string[];
48
+ }>;
49
+ openGraph?: Partial<{
50
+ title: string;
51
+ description: string;
52
+ url: string;
53
+ siteName: string;
54
+ locale: string;
55
+ images?: string[];
56
+ videos?: string[];
57
+ audio?: string[];
58
+ }>;
59
+ }
60
+ /**
61
+ * Converts an array of meta elements to a metadata object
62
+ * @param metaElements - An array of meta elements
63
+ * @example
64
+ * ```ts
65
+ * const metaElements = [
66
+ * { name: "title", content: "My Page" },
67
+ * { name: "description", content: "This is my page" },
68
+ * ];
69
+ * const metadata = metaElementsToObject(metaElements);
70
+ * console.log(metadata);
71
+ * ```
72
+ */
73
+ declare function metaElementsToObject(metaElements: Array<React.JSX.IntrinsicElements["meta"] | undefined>): Metadata;
74
+
75
+ /**
76
+ * Normalizes path segments from framework route params into a consistent path string.
77
+ *
78
+ * Handles different framework param formats:
79
+ * - Next.js: `pathParams.all` (string[])
80
+ * - React Router: `params["*"]` (string)
81
+ * - TanStack Router: `params._splat` (string)
82
+ *
83
+ * @param path - Path segments as string, string array, or undefined
84
+ * @returns Normalized path string starting with "/" (or "/" for empty/undefined)
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * // Next.js
89
+ * normalizePath(pathParams?.all) // ["blog", "post"] => "/blog/post"
90
+ *
91
+ * // React Router / TanStack Router
92
+ * normalizePath(params["*"]) // "blog/post" => "/blog/post"
93
+ * normalizePath(undefined) // => "/"
94
+ * ```
95
+ */
96
+ declare function normalizePath(path?: string | Array<string> | undefined): string;
7
97
 
8
98
  /**
9
99
  * Creates the client library with plugin support
@@ -13,12 +103,39 @@ import 'better-call/client';
13
103
  * // For Next.js with SSR:
14
104
  * const lib = createStackClient({
15
105
  * plugins: {
16
- * messages: messagesPlugin.client
106
+ * blog: blogPlugin.client
17
107
  * }
18
108
  * });
19
109
  *
20
- * // Access router for page routing
21
- * const route = lib.router.getRoute('/messages');
110
+ * // SPA usage - just render the route
111
+ * function Page() {
112
+ * return lib.resolveRoute('/blog');
113
+ * }
114
+ *
115
+ * // SSR usage - prefetch data with loader, then render
116
+ * async function Page({ params }) {
117
+ * const path = '/blog';
118
+ *
119
+ * // Load data server-side if loader exists
120
+ * const loader = lib.getLoader(path);
121
+ * if (loader) await loader(queryClient, baseURL, basePath);
122
+ *
123
+ * // Render with built-in Suspense + Error Boundary
124
+ * return lib.resolveRoute(path);
125
+ * }
126
+ *
127
+ * // Next.js with notFound() function
128
+ * import { notFound } from 'next/navigation';
129
+ *
130
+ * async function Page({ params }) {
131
+ * const path = '/blog';
132
+ * const loader = lib.getLoader(path);
133
+ * if (loader) await loader(queryClient, baseURL);
134
+ *
135
+ * return lib.resolveRoute(path, {
136
+ * onNotFound: notFound // Calls Next.js notFound() instead of rendering
137
+ * });
138
+ * }
22
139
  *
23
140
  * ```
24
141
  *
@@ -27,4 +144,4 @@ import 'better-call/client';
27
144
  */
28
145
  declare function createStackClient<TPlugins extends Record<string, ClientPlugin<any, any>>, TRoutes extends PluginRoutes<TPlugins> = PluginRoutes<TPlugins>>(config: ClientLibConfig<TPlugins>): ClientLib<TRoutes>;
29
146
 
30
- export { ClientLib, ClientLibConfig, ClientPlugin, createStackClient };
147
+ export { ClientLib, ClientLibConfig, ClientPlugin, createStackClient, metaElementsToObject, normalizePath, sitemapEntryToXmlString };
@@ -1,9 +1,99 @@
1
- import { C as ClientPlugin, P as PluginRoutes, a as ClientLibConfig, b as ClientLib } from '../shared/stack.DORw_1ps.js';
2
- export { createRoute } from '@btst/yar';
3
- export { c as createApiClient } from '../shared/stack.DrUAVfIH.js';
1
+ import { S as Sitemap, C as ClientPlugin, a as PluginRoutes, b as ClientLibConfig, c as ClientLib } from '../shared/stack.ByOugz9d.js';
2
+ import '@btst/yar';
4
3
  import '@btst/db';
5
4
  import 'better-call';
6
- import 'better-call/client';
5
+
6
+ /**
7
+ * Converts an array of sitemap entries into an XML string following the sitemap.org protocol.
8
+ *
9
+ * @param entries - Array of sitemap entries from `lib.generateSitemap()`
10
+ * @returns Complete XML string for the sitemap
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const entries = await lib.generateSitemap();
15
+ * const xml = sitemapEntryToXmlString(entries);
16
+ * return new Response(xml, {
17
+ * headers: { "Content-Type": "application/xml; charset=utf-8" }
18
+ * });
19
+ * ```
20
+ */
21
+ declare function sitemapEntryToXmlString(entries: Sitemap): string;
22
+
23
+ interface Metadata {
24
+ title: string;
25
+ description?: string;
26
+ keywords?: string[];
27
+ applicationName?: string;
28
+ generator?: string;
29
+ referrer?: "no-referrer" | "origin" | "no-referrer-when-downgrade" | "origin-when-cross-origin" | "same-origin" | "strict-origin" | "strict-origin-when-cross-origin";
30
+ themeColor?: string;
31
+ viewport?: string;
32
+ creator?: string;
33
+ publisher?: string;
34
+ authors?: {
35
+ name: string;
36
+ }[];
37
+ abstract?: string;
38
+ robots?: string;
39
+ alternates?: Partial<{
40
+ canonical: string;
41
+ }>;
42
+ twitter?: Partial<{
43
+ title: string;
44
+ description: string;
45
+ site: string;
46
+ creator: string;
47
+ images?: string[];
48
+ }>;
49
+ openGraph?: Partial<{
50
+ title: string;
51
+ description: string;
52
+ url: string;
53
+ siteName: string;
54
+ locale: string;
55
+ images?: string[];
56
+ videos?: string[];
57
+ audio?: string[];
58
+ }>;
59
+ }
60
+ /**
61
+ * Converts an array of meta elements to a metadata object
62
+ * @param metaElements - An array of meta elements
63
+ * @example
64
+ * ```ts
65
+ * const metaElements = [
66
+ * { name: "title", content: "My Page" },
67
+ * { name: "description", content: "This is my page" },
68
+ * ];
69
+ * const metadata = metaElementsToObject(metaElements);
70
+ * console.log(metadata);
71
+ * ```
72
+ */
73
+ declare function metaElementsToObject(metaElements: Array<React.JSX.IntrinsicElements["meta"] | undefined>): Metadata;
74
+
75
+ /**
76
+ * Normalizes path segments from framework route params into a consistent path string.
77
+ *
78
+ * Handles different framework param formats:
79
+ * - Next.js: `pathParams.all` (string[])
80
+ * - React Router: `params["*"]` (string)
81
+ * - TanStack Router: `params._splat` (string)
82
+ *
83
+ * @param path - Path segments as string, string array, or undefined
84
+ * @returns Normalized path string starting with "/" (or "/" for empty/undefined)
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * // Next.js
89
+ * normalizePath(pathParams?.all) // ["blog", "post"] => "/blog/post"
90
+ *
91
+ * // React Router / TanStack Router
92
+ * normalizePath(params["*"]) // "blog/post" => "/blog/post"
93
+ * normalizePath(undefined) // => "/"
94
+ * ```
95
+ */
96
+ declare function normalizePath(path?: string | Array<string> | undefined): string;
7
97
 
8
98
  /**
9
99
  * Creates the client library with plugin support
@@ -13,12 +103,39 @@ import 'better-call/client';
13
103
  * // For Next.js with SSR:
14
104
  * const lib = createStackClient({
15
105
  * plugins: {
16
- * messages: messagesPlugin.client
106
+ * blog: blogPlugin.client
17
107
  * }
18
108
  * });
19
109
  *
20
- * // Access router for page routing
21
- * const route = lib.router.getRoute('/messages');
110
+ * // SPA usage - just render the route
111
+ * function Page() {
112
+ * return lib.resolveRoute('/blog');
113
+ * }
114
+ *
115
+ * // SSR usage - prefetch data with loader, then render
116
+ * async function Page({ params }) {
117
+ * const path = '/blog';
118
+ *
119
+ * // Load data server-side if loader exists
120
+ * const loader = lib.getLoader(path);
121
+ * if (loader) await loader(queryClient, baseURL, basePath);
122
+ *
123
+ * // Render with built-in Suspense + Error Boundary
124
+ * return lib.resolveRoute(path);
125
+ * }
126
+ *
127
+ * // Next.js with notFound() function
128
+ * import { notFound } from 'next/navigation';
129
+ *
130
+ * async function Page({ params }) {
131
+ * const path = '/blog';
132
+ * const loader = lib.getLoader(path);
133
+ * if (loader) await loader(queryClient, baseURL);
134
+ *
135
+ * return lib.resolveRoute(path, {
136
+ * onNotFound: notFound // Calls Next.js notFound() instead of rendering
137
+ * });
138
+ * }
22
139
  *
23
140
  * ```
24
141
  *
@@ -27,4 +144,4 @@ import 'better-call/client';
27
144
  */
28
145
  declare function createStackClient<TPlugins extends Record<string, ClientPlugin<any, any>>, TRoutes extends PluginRoutes<TPlugins> = PluginRoutes<TPlugins>>(config: ClientLibConfig<TPlugins>): ClientLib<TRoutes>;
29
146
 
30
- export { ClientLib, ClientLibConfig, ClientPlugin, createStackClient };
147
+ export { ClientLib, ClientLibConfig, ClientPlugin, createStackClient, metaElementsToObject, normalizePath, sitemapEntryToXmlString };
@@ -1,7 +1,7 @@
1
1
  import { createRouter } from '@btst/yar';
2
- export { createRoute } from '@btst/yar';
3
- export { c as createApiClient } from '../shared/stack.3OUyGp_E.mjs';
4
- import 'better-call/client';
2
+ export { sitemapEntryToXmlString } from './sitemap-utils.mjs';
3
+ export { metaElementsToObject } from './meta-utils.mjs';
4
+ export { normalizePath } from './path-utils.mjs';
5
5
 
6
6
  function createStackClient(config) {
7
7
  const { plugins } = config;
@@ -12,7 +12,24 @@ function createStackClient(config) {
12
12
  }
13
13
  const router = createRouter(allRoutes);
14
14
  return {
15
- router
15
+ router,
16
+ async generateSitemap() {
17
+ const sitemapEntries = [];
18
+ for (const plugin of Object.values(plugins)) {
19
+ if (typeof plugin.sitemap === "function") {
20
+ const entries = await plugin.sitemap();
21
+ if (Array.isArray(entries)) sitemapEntries.push(...entries);
22
+ }
23
+ }
24
+ const seen = /* @__PURE__ */ new Set();
25
+ const deduped = [];
26
+ for (const entry of sitemapEntries) {
27
+ if (!entry?.url || seen.has(entry.url)) continue;
28
+ seen.add(entry.url);
29
+ deduped.push(entry);
30
+ }
31
+ return deduped;
32
+ }
16
33
  };
17
34
  }
18
35
 
@@ -0,0 +1,162 @@
1
+ 'use strict';
2
+
3
+ function metaElementsToObject(metaElements) {
4
+ const metadata = { title: "" };
5
+ const nameHandlers = {
6
+ title: (c) => {
7
+ metadata.title = c;
8
+ },
9
+ description: (c) => {
10
+ metadata.description = c;
11
+ },
12
+ keywords: (c) => {
13
+ const parts = c.split(",").map((k) => k.trim()).filter(Boolean);
14
+ metadata.keywords = parts.length > 0 ? parts : void 0;
15
+ },
16
+ "application-name": (c) => {
17
+ metadata.applicationName = c;
18
+ },
19
+ generator: (c) => {
20
+ metadata.generator = c;
21
+ },
22
+ referrer: (c) => {
23
+ const allowedReferrers = /* @__PURE__ */ new Set([
24
+ "no-referrer",
25
+ "origin",
26
+ "no-referrer-when-downgrade",
27
+ "origin-when-cross-origin",
28
+ "same-origin",
29
+ "strict-origin",
30
+ "strict-origin-when-cross-origin",
31
+ "unsafe-url"
32
+ ]);
33
+ if (allowedReferrers.has(c)) {
34
+ metadata.referrer = c;
35
+ }
36
+ },
37
+ "theme-color": (c) => {
38
+ metadata.themeColor = c;
39
+ },
40
+ viewport: (c) => {
41
+ metadata.viewport = c;
42
+ },
43
+ creator: (c) => {
44
+ metadata.creator = c;
45
+ },
46
+ publisher: (c) => {
47
+ metadata.publisher = c;
48
+ },
49
+ author: (c) => {
50
+ metadata.authors = [{ name: c }];
51
+ },
52
+ abstract: (c) => {
53
+ metadata.abstract = c;
54
+ },
55
+ robots: (c) => {
56
+ metadata.robots = c;
57
+ },
58
+ // Twitter
59
+ "twitter:title": (c) => {
60
+ if (!metadata.twitter) metadata.twitter = {};
61
+ metadata.twitter.title = c;
62
+ },
63
+ "twitter:description": (c) => {
64
+ if (!metadata.twitter) metadata.twitter = {};
65
+ metadata.twitter.description = c;
66
+ },
67
+ "twitter:site": (c) => {
68
+ if (!metadata.twitter) metadata.twitter = {};
69
+ metadata.twitter.site = c;
70
+ },
71
+ "twitter:creator": (c) => {
72
+ if (!metadata.twitter) metadata.twitter = {};
73
+ metadata.twitter.creator = c;
74
+ },
75
+ "twitter:image": (c) => {
76
+ if (!metadata.twitter) metadata.twitter = {};
77
+ const currentImages = metadata.twitter.images;
78
+ if (!currentImages) {
79
+ metadata.twitter.images = [c];
80
+ } else if (Array.isArray(currentImages)) {
81
+ metadata.twitter.images = [...currentImages, c];
82
+ } else {
83
+ metadata.twitter.images = [currentImages, c];
84
+ }
85
+ }
86
+ };
87
+ const propertyHandlers = {
88
+ "og:title": (c) => {
89
+ if (!metadata.openGraph) metadata.openGraph = {};
90
+ metadata.openGraph.title = c;
91
+ },
92
+ "og:description": (c) => {
93
+ if (!metadata.openGraph) metadata.openGraph = {};
94
+ metadata.openGraph.description = c;
95
+ },
96
+ "og:url": (c) => {
97
+ if (!metadata.openGraph) metadata.openGraph = {};
98
+ metadata.openGraph.url = c;
99
+ metadata.alternates = {
100
+ ...metadata.alternates ?? {},
101
+ canonical: c
102
+ };
103
+ },
104
+ "og:site_name": (c) => {
105
+ if (!metadata.openGraph) metadata.openGraph = {};
106
+ metadata.openGraph.siteName = c;
107
+ },
108
+ "og:locale": (c) => {
109
+ if (!metadata.openGraph) metadata.openGraph = {};
110
+ metadata.openGraph.locale = c;
111
+ },
112
+ "og:image": (c) => {
113
+ if (!metadata.openGraph) metadata.openGraph = {};
114
+ const currentImages = metadata.openGraph.images;
115
+ if (!currentImages) {
116
+ metadata.openGraph.images = [c];
117
+ } else if (Array.isArray(currentImages)) {
118
+ metadata.openGraph.images = [...currentImages, c];
119
+ } else {
120
+ metadata.openGraph.images = [currentImages, c];
121
+ }
122
+ },
123
+ "og:video": (c) => {
124
+ if (!metadata.openGraph) metadata.openGraph = {};
125
+ const currentVideos = metadata.openGraph.videos;
126
+ if (!currentVideos) {
127
+ metadata.openGraph.videos = [c];
128
+ } else if (Array.isArray(currentVideos)) {
129
+ metadata.openGraph.videos = [...currentVideos, c];
130
+ } else {
131
+ metadata.openGraph.videos = [currentVideos, c];
132
+ }
133
+ },
134
+ "og:audio": (c) => {
135
+ if (!metadata.openGraph) metadata.openGraph = {};
136
+ const currentAudio = metadata.openGraph.audio;
137
+ if (!currentAudio) {
138
+ metadata.openGraph.audio = [c];
139
+ } else if (Array.isArray(currentAudio)) {
140
+ metadata.openGraph.audio = [...currentAudio, c];
141
+ } else {
142
+ metadata.openGraph.audio = [currentAudio, c];
143
+ }
144
+ }
145
+ };
146
+ for (const meta of metaElements) {
147
+ if (!meta) continue;
148
+ if ("name" in meta && "content" in meta) {
149
+ const handler = nameHandlers[String(meta.name)];
150
+ if (handler) handler(String(meta.content));
151
+ continue;
152
+ }
153
+ if ("property" in meta && "content" in meta) {
154
+ const handler = propertyHandlers[String(meta.property)];
155
+ if (handler) handler(String(meta.content));
156
+ continue;
157
+ }
158
+ }
159
+ return metadata;
160
+ }
161
+
162
+ exports.metaElementsToObject = metaElementsToObject;
@@ -0,0 +1,160 @@
1
+ function metaElementsToObject(metaElements) {
2
+ const metadata = { title: "" };
3
+ const nameHandlers = {
4
+ title: (c) => {
5
+ metadata.title = c;
6
+ },
7
+ description: (c) => {
8
+ metadata.description = c;
9
+ },
10
+ keywords: (c) => {
11
+ const parts = c.split(",").map((k) => k.trim()).filter(Boolean);
12
+ metadata.keywords = parts.length > 0 ? parts : void 0;
13
+ },
14
+ "application-name": (c) => {
15
+ metadata.applicationName = c;
16
+ },
17
+ generator: (c) => {
18
+ metadata.generator = c;
19
+ },
20
+ referrer: (c) => {
21
+ const allowedReferrers = /* @__PURE__ */ new Set([
22
+ "no-referrer",
23
+ "origin",
24
+ "no-referrer-when-downgrade",
25
+ "origin-when-cross-origin",
26
+ "same-origin",
27
+ "strict-origin",
28
+ "strict-origin-when-cross-origin",
29
+ "unsafe-url"
30
+ ]);
31
+ if (allowedReferrers.has(c)) {
32
+ metadata.referrer = c;
33
+ }
34
+ },
35
+ "theme-color": (c) => {
36
+ metadata.themeColor = c;
37
+ },
38
+ viewport: (c) => {
39
+ metadata.viewport = c;
40
+ },
41
+ creator: (c) => {
42
+ metadata.creator = c;
43
+ },
44
+ publisher: (c) => {
45
+ metadata.publisher = c;
46
+ },
47
+ author: (c) => {
48
+ metadata.authors = [{ name: c }];
49
+ },
50
+ abstract: (c) => {
51
+ metadata.abstract = c;
52
+ },
53
+ robots: (c) => {
54
+ metadata.robots = c;
55
+ },
56
+ // Twitter
57
+ "twitter:title": (c) => {
58
+ if (!metadata.twitter) metadata.twitter = {};
59
+ metadata.twitter.title = c;
60
+ },
61
+ "twitter:description": (c) => {
62
+ if (!metadata.twitter) metadata.twitter = {};
63
+ metadata.twitter.description = c;
64
+ },
65
+ "twitter:site": (c) => {
66
+ if (!metadata.twitter) metadata.twitter = {};
67
+ metadata.twitter.site = c;
68
+ },
69
+ "twitter:creator": (c) => {
70
+ if (!metadata.twitter) metadata.twitter = {};
71
+ metadata.twitter.creator = c;
72
+ },
73
+ "twitter:image": (c) => {
74
+ if (!metadata.twitter) metadata.twitter = {};
75
+ const currentImages = metadata.twitter.images;
76
+ if (!currentImages) {
77
+ metadata.twitter.images = [c];
78
+ } else if (Array.isArray(currentImages)) {
79
+ metadata.twitter.images = [...currentImages, c];
80
+ } else {
81
+ metadata.twitter.images = [currentImages, c];
82
+ }
83
+ }
84
+ };
85
+ const propertyHandlers = {
86
+ "og:title": (c) => {
87
+ if (!metadata.openGraph) metadata.openGraph = {};
88
+ metadata.openGraph.title = c;
89
+ },
90
+ "og:description": (c) => {
91
+ if (!metadata.openGraph) metadata.openGraph = {};
92
+ metadata.openGraph.description = c;
93
+ },
94
+ "og:url": (c) => {
95
+ if (!metadata.openGraph) metadata.openGraph = {};
96
+ metadata.openGraph.url = c;
97
+ metadata.alternates = {
98
+ ...metadata.alternates ?? {},
99
+ canonical: c
100
+ };
101
+ },
102
+ "og:site_name": (c) => {
103
+ if (!metadata.openGraph) metadata.openGraph = {};
104
+ metadata.openGraph.siteName = c;
105
+ },
106
+ "og:locale": (c) => {
107
+ if (!metadata.openGraph) metadata.openGraph = {};
108
+ metadata.openGraph.locale = c;
109
+ },
110
+ "og:image": (c) => {
111
+ if (!metadata.openGraph) metadata.openGraph = {};
112
+ const currentImages = metadata.openGraph.images;
113
+ if (!currentImages) {
114
+ metadata.openGraph.images = [c];
115
+ } else if (Array.isArray(currentImages)) {
116
+ metadata.openGraph.images = [...currentImages, c];
117
+ } else {
118
+ metadata.openGraph.images = [currentImages, c];
119
+ }
120
+ },
121
+ "og:video": (c) => {
122
+ if (!metadata.openGraph) metadata.openGraph = {};
123
+ const currentVideos = metadata.openGraph.videos;
124
+ if (!currentVideos) {
125
+ metadata.openGraph.videos = [c];
126
+ } else if (Array.isArray(currentVideos)) {
127
+ metadata.openGraph.videos = [...currentVideos, c];
128
+ } else {
129
+ metadata.openGraph.videos = [currentVideos, c];
130
+ }
131
+ },
132
+ "og:audio": (c) => {
133
+ if (!metadata.openGraph) metadata.openGraph = {};
134
+ const currentAudio = metadata.openGraph.audio;
135
+ if (!currentAudio) {
136
+ metadata.openGraph.audio = [c];
137
+ } else if (Array.isArray(currentAudio)) {
138
+ metadata.openGraph.audio = [...currentAudio, c];
139
+ } else {
140
+ metadata.openGraph.audio = [currentAudio, c];
141
+ }
142
+ }
143
+ };
144
+ for (const meta of metaElements) {
145
+ if (!meta) continue;
146
+ if ("name" in meta && "content" in meta) {
147
+ const handler = nameHandlers[String(meta.name)];
148
+ if (handler) handler(String(meta.content));
149
+ continue;
150
+ }
151
+ if ("property" in meta && "content" in meta) {
152
+ const handler = propertyHandlers[String(meta.property)];
153
+ if (handler) handler(String(meta.content));
154
+ continue;
155
+ }
156
+ }
157
+ return metadata;
158
+ }
159
+
160
+ export { metaElementsToObject };
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ function normalizePath(path) {
4
+ if (!path) {
5
+ return "/";
6
+ }
7
+ if (Array.isArray(path)) {
8
+ const segments2 = path.filter(Boolean);
9
+ return segments2.length > 0 ? `/${segments2.join("/")}` : "/";
10
+ }
11
+ const segments = path.split("/").filter(Boolean);
12
+ return segments.length > 0 ? `/${segments.join("/")}` : "/";
13
+ }
14
+
15
+ exports.normalizePath = normalizePath;
@@ -0,0 +1,13 @@
1
+ function normalizePath(path) {
2
+ if (!path) {
3
+ return "/";
4
+ }
5
+ if (Array.isArray(path)) {
6
+ const segments2 = path.filter(Boolean);
7
+ return segments2.length > 0 ? `/${segments2.join("/")}` : "/";
8
+ }
9
+ const segments = path.split("/").filter(Boolean);
10
+ return segments.length > 0 ? `/${segments.join("/")}` : "/";
11
+ }
12
+
13
+ export { normalizePath };