@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,14 @@
1
+ 'use strict';
2
+
3
+ function sitemapEntryToXmlString(entries) {
4
+ const xml = `<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">` + entries.map((entry) => {
5
+ const url = `<loc>${entry.url}</loc>`;
6
+ const lastModified = entry.lastModified ? `<lastmod>${entry.lastModified instanceof Date ? entry.lastModified.toISOString() : entry.lastModified}</lastmod>` : "";
7
+ const changeFrequency = entry.changeFrequency ? `<changefreq>${entry.changeFrequency}</changefreq>` : "";
8
+ const priority = entry.priority !== void 0 ? `<priority>${entry.priority}</priority>` : "";
9
+ return `<url>${url}${lastModified}${changeFrequency}${priority}</url>`;
10
+ }).join("") + `</urlset>`;
11
+ return xml;
12
+ }
13
+
14
+ exports.sitemapEntryToXmlString = sitemapEntryToXmlString;
@@ -0,0 +1,12 @@
1
+ function sitemapEntryToXmlString(entries) {
2
+ const xml = `<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">` + entries.map((entry) => {
3
+ const url = `<loc>${entry.url}</loc>`;
4
+ const lastModified = entry.lastModified ? `<lastmod>${entry.lastModified instanceof Date ? entry.lastModified.toISOString() : entry.lastModified}</lastmod>` : "";
5
+ const changeFrequency = entry.changeFrequency ? `<changefreq>${entry.changeFrequency}</changefreq>` : "";
6
+ const priority = entry.priority !== void 0 ? `<priority>${entry.priority}</priority>` : "";
7
+ return `<url>${url}${lastModified}${changeFrequency}${priority}</url>`;
8
+ }).join("") + `</urlset>`;
9
+ return xml;
10
+ }
11
+
12
+ export { sitemapEntryToXmlString };
@@ -1,67 +1,10 @@
1
- "use client";
2
1
  'use strict';
3
2
 
4
- const jsxRuntime = require('react/jsx-runtime');
5
- const react = require('react');
3
+ const provider = require('./provider.cjs');
6
4
 
7
- const BetterStackContext = react.createContext(
8
- null
9
- );
10
- function BetterStackProvider({
11
- children,
12
- overrides,
13
- basePath
14
- }) {
15
- const value = {
16
- overrides,
17
- basePath
18
- };
19
- return /* @__PURE__ */ jsxRuntime.jsx(BetterStackContext.Provider, { value, children });
20
- }
21
- function useBetterStack() {
22
- const context = react.useContext(
23
- BetterStackContext
24
- );
25
- if (!context) {
26
- throw new Error(
27
- "useBetterStack must be used within BetterStackProvider. Wrap your app with <BetterStackProvider> in your layout file."
28
- );
29
- }
30
- return context;
31
- }
32
- function usePluginOverrides(pluginName) {
33
- const context = useBetterStack();
34
- const overrides = context.overrides[pluginName];
35
- if (!overrides) {
36
- throw new Error(
37
- `Plugin "${pluginName}" not found in BetterStackProvider. Available plugins: ${Object.keys(context.overrides).join(", ")}`
38
- );
39
- }
40
- return overrides;
41
- }
42
- function usePluginOverride(pluginName, overrideKey) {
43
- const overrides = usePluginOverrides(pluginName);
44
- const override = overrides[overrideKey];
45
- if (override === void 0) {
46
- const availableKeys = overrides && typeof overrides === "object" ? Object.keys(overrides).join(", ") : "none";
47
- throw new Error(
48
- `Override "${overrideKey}" not found for plugin "${pluginName}". Available overrides: ${availableKeys}`
49
- );
50
- }
51
- return override;
52
- }
53
- function useBasePath() {
54
- const context = useBetterStack();
55
- if (!context) {
56
- throw new Error(
57
- "useBasePath must be used within BetterStackProvider. Wrap your app with <BetterStackProvider> in your layout file."
58
- );
59
- }
60
- return context.basePath;
61
- }
62
5
 
63
- exports.BetterStackProvider = BetterStackProvider;
64
- exports.useBasePath = useBasePath;
65
- exports.useBetterStack = useBetterStack;
66
- exports.usePluginOverride = usePluginOverride;
67
- exports.usePluginOverrides = usePluginOverrides;
6
+
7
+ exports.BetterStackProvider = provider.BetterStackProvider;
8
+ exports.useBasePath = provider.useBasePath;
9
+ exports.useBetterStack = provider.useBetterStack;
10
+ exports.usePluginOverrides = provider.usePluginOverrides;
@@ -1,4 +1,3 @@
1
- "use client";
2
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
2
  import { ReactNode } from 'react';
4
3
 
@@ -7,7 +6,13 @@ import { ReactNode } from 'react';
7
6
  * Generic over the shape of all plugin overrides
8
7
  */
9
8
  interface BetterStackContextValue<TPluginOverrides extends Record<string, any>> {
9
+ /**
10
+ * The overrides for the plugin.
11
+ */
10
12
  overrides: TPluginOverrides;
13
+ /**
14
+ * The base path where the client router is mounted.
15
+ */
11
16
  basePath: string;
12
17
  }
13
18
  /**
@@ -49,41 +54,33 @@ declare function BetterStackProvider<TPluginOverrides extends Record<string, any
49
54
  * Useful if you need access to multiple plugins or the full context
50
55
  */
51
56
  declare function useBetterStack<TPluginOverrides extends Record<string, any> = Record<string, any>>(): BetterStackContextValue<TPluginOverrides>;
57
+ type OverridesResult<TOverrides, TDefaults> = undefined extends TDefaults ? TOverrides : TOverrides & Required<Pick<TDefaults & {}, keyof TDefaults>>;
52
58
  /**
53
59
  * Hook to access overrides for a specific plugin
54
60
  * This is type-safe and will only expose the overrides defined by that plugin
55
61
  *
62
+ * When default values are provided, properties with defaults are guaranteed to be non-null.
63
+ *
56
64
  * @example
57
65
  * ```tsx
58
- * // In a todos plugin component
66
+ * // Without defaults - trusts plugin is configured
59
67
  * function TodosList() {
60
- * const { Link, navigate } = usePluginOverrides<TodosPluginOverrides>("todos");
61
- *
62
- * return (
63
- * <Link href="/todos/add">
64
- * <button onClick={() => navigate("/todos")}>
65
- * Add Todo
66
- * </button>
67
- * </Link>
68
- * );
68
+ * const { navigate } = usePluginOverrides<TodosPluginOverrides>("todos");
69
+ * // navigate is (path: string) => void (required fields are non-nullable)
70
+ * navigate("/todos/add");
69
71
  * }
70
- * ```
71
- */
72
- declare function usePluginOverrides<TOverrides = any>(pluginName: string): TOverrides;
73
- /**
74
- * Hook to access a specific override from a plugin
75
- * Provides fine-grained access with full type safety
76
72
  *
77
- * @example
78
- * ```tsx
73
+ * // With defaults - optional fields with defaults become required
79
74
  * function TodosList() {
80
- * const Link = usePluginOverride<typeof NextLink>("todos", "Link");
81
- *
82
- * return <Link href="/todos/add">Add Todo</Link>;
75
+ * const { localization } = usePluginOverrides<TodosPluginOverrides, Partial<TodosPluginOverrides>>("todos", {
76
+ * localization: DEFAULT_LOCALIZATION
77
+ * });
78
+ * // localization is Localization (guaranteed to exist because we provided a default)
79
+ * console.log(localization.SOME_KEY);
83
80
  * }
84
81
  * ```
85
82
  */
86
- declare function usePluginOverride<TOverride = any>(pluginName: string, overrideKey: string): TOverride;
83
+ declare function usePluginOverrides<TOverrides = any, TDefaults extends Partial<TOverrides> | undefined = undefined>(pluginName: string, defaultValues?: TDefaults): OverridesResult<TOverrides, TDefaults>;
87
84
  declare function useBasePath(): string;
88
85
 
89
- export { BetterStackProvider, useBasePath, useBetterStack, usePluginOverride, usePluginOverrides };
86
+ export { BetterStackProvider, useBasePath, useBetterStack, usePluginOverrides };
@@ -1,4 +1,3 @@
1
- "use client";
2
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
2
  import { ReactNode } from 'react';
4
3
 
@@ -7,7 +6,13 @@ import { ReactNode } from 'react';
7
6
  * Generic over the shape of all plugin overrides
8
7
  */
9
8
  interface BetterStackContextValue<TPluginOverrides extends Record<string, any>> {
9
+ /**
10
+ * The overrides for the plugin.
11
+ */
10
12
  overrides: TPluginOverrides;
13
+ /**
14
+ * The base path where the client router is mounted.
15
+ */
11
16
  basePath: string;
12
17
  }
13
18
  /**
@@ -49,41 +54,33 @@ declare function BetterStackProvider<TPluginOverrides extends Record<string, any
49
54
  * Useful if you need access to multiple plugins or the full context
50
55
  */
51
56
  declare function useBetterStack<TPluginOverrides extends Record<string, any> = Record<string, any>>(): BetterStackContextValue<TPluginOverrides>;
57
+ type OverridesResult<TOverrides, TDefaults> = undefined extends TDefaults ? TOverrides : TOverrides & Required<Pick<TDefaults & {}, keyof TDefaults>>;
52
58
  /**
53
59
  * Hook to access overrides for a specific plugin
54
60
  * This is type-safe and will only expose the overrides defined by that plugin
55
61
  *
62
+ * When default values are provided, properties with defaults are guaranteed to be non-null.
63
+ *
56
64
  * @example
57
65
  * ```tsx
58
- * // In a todos plugin component
66
+ * // Without defaults - trusts plugin is configured
59
67
  * function TodosList() {
60
- * const { Link, navigate } = usePluginOverrides<TodosPluginOverrides>("todos");
61
- *
62
- * return (
63
- * <Link href="/todos/add">
64
- * <button onClick={() => navigate("/todos")}>
65
- * Add Todo
66
- * </button>
67
- * </Link>
68
- * );
68
+ * const { navigate } = usePluginOverrides<TodosPluginOverrides>("todos");
69
+ * // navigate is (path: string) => void (required fields are non-nullable)
70
+ * navigate("/todos/add");
69
71
  * }
70
- * ```
71
- */
72
- declare function usePluginOverrides<TOverrides = any>(pluginName: string): TOverrides;
73
- /**
74
- * Hook to access a specific override from a plugin
75
- * Provides fine-grained access with full type safety
76
72
  *
77
- * @example
78
- * ```tsx
73
+ * // With defaults - optional fields with defaults become required
79
74
  * function TodosList() {
80
- * const Link = usePluginOverride<typeof NextLink>("todos", "Link");
81
- *
82
- * return <Link href="/todos/add">Add Todo</Link>;
75
+ * const { localization } = usePluginOverrides<TodosPluginOverrides, Partial<TodosPluginOverrides>>("todos", {
76
+ * localization: DEFAULT_LOCALIZATION
77
+ * });
78
+ * // localization is Localization (guaranteed to exist because we provided a default)
79
+ * console.log(localization.SOME_KEY);
83
80
  * }
84
81
  * ```
85
82
  */
86
- declare function usePluginOverride<TOverride = any>(pluginName: string, overrideKey: string): TOverride;
83
+ declare function usePluginOverrides<TOverrides = any, TDefaults extends Partial<TOverrides> | undefined = undefined>(pluginName: string, defaultValues?: TDefaults): OverridesResult<TOverrides, TDefaults>;
87
84
  declare function useBasePath(): string;
88
85
 
89
- export { BetterStackProvider, useBasePath, useBetterStack, usePluginOverride, usePluginOverrides };
86
+ export { BetterStackProvider, useBasePath, useBetterStack, usePluginOverrides };
@@ -1,4 +1,3 @@
1
- "use client";
2
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
2
  import { ReactNode } from 'react';
4
3
 
@@ -7,7 +6,13 @@ import { ReactNode } from 'react';
7
6
  * Generic over the shape of all plugin overrides
8
7
  */
9
8
  interface BetterStackContextValue<TPluginOverrides extends Record<string, any>> {
9
+ /**
10
+ * The overrides for the plugin.
11
+ */
10
12
  overrides: TPluginOverrides;
13
+ /**
14
+ * The base path where the client router is mounted.
15
+ */
11
16
  basePath: string;
12
17
  }
13
18
  /**
@@ -49,41 +54,33 @@ declare function BetterStackProvider<TPluginOverrides extends Record<string, any
49
54
  * Useful if you need access to multiple plugins or the full context
50
55
  */
51
56
  declare function useBetterStack<TPluginOverrides extends Record<string, any> = Record<string, any>>(): BetterStackContextValue<TPluginOverrides>;
57
+ type OverridesResult<TOverrides, TDefaults> = undefined extends TDefaults ? TOverrides : TOverrides & Required<Pick<TDefaults & {}, keyof TDefaults>>;
52
58
  /**
53
59
  * Hook to access overrides for a specific plugin
54
60
  * This is type-safe and will only expose the overrides defined by that plugin
55
61
  *
62
+ * When default values are provided, properties with defaults are guaranteed to be non-null.
63
+ *
56
64
  * @example
57
65
  * ```tsx
58
- * // In a todos plugin component
66
+ * // Without defaults - trusts plugin is configured
59
67
  * function TodosList() {
60
- * const { Link, navigate } = usePluginOverrides<TodosPluginOverrides>("todos");
61
- *
62
- * return (
63
- * <Link href="/todos/add">
64
- * <button onClick={() => navigate("/todos")}>
65
- * Add Todo
66
- * </button>
67
- * </Link>
68
- * );
68
+ * const { navigate } = usePluginOverrides<TodosPluginOverrides>("todos");
69
+ * // navigate is (path: string) => void (required fields are non-nullable)
70
+ * navigate("/todos/add");
69
71
  * }
70
- * ```
71
- */
72
- declare function usePluginOverrides<TOverrides = any>(pluginName: string): TOverrides;
73
- /**
74
- * Hook to access a specific override from a plugin
75
- * Provides fine-grained access with full type safety
76
72
  *
77
- * @example
78
- * ```tsx
73
+ * // With defaults - optional fields with defaults become required
79
74
  * function TodosList() {
80
- * const Link = usePluginOverride<typeof NextLink>("todos", "Link");
81
- *
82
- * return <Link href="/todos/add">Add Todo</Link>;
75
+ * const { localization } = usePluginOverrides<TodosPluginOverrides, Partial<TodosPluginOverrides>>("todos", {
76
+ * localization: DEFAULT_LOCALIZATION
77
+ * });
78
+ * // localization is Localization (guaranteed to exist because we provided a default)
79
+ * console.log(localization.SOME_KEY);
83
80
  * }
84
81
  * ```
85
82
  */
86
- declare function usePluginOverride<TOverride = any>(pluginName: string, overrideKey: string): TOverride;
83
+ declare function usePluginOverrides<TOverrides = any, TDefaults extends Partial<TOverrides> | undefined = undefined>(pluginName: string, defaultValues?: TDefaults): OverridesResult<TOverrides, TDefaults>;
87
84
  declare function useBasePath(): string;
88
85
 
89
- export { BetterStackProvider, useBasePath, useBetterStack, usePluginOverride, usePluginOverrides };
86
+ export { BetterStackProvider, useBasePath, useBetterStack, usePluginOverrides };
@@ -1,61 +1 @@
1
- "use client";
2
- import { jsx } from 'react/jsx-runtime';
3
- import { createContext, useContext } from 'react';
4
-
5
- const BetterStackContext = createContext(
6
- null
7
- );
8
- function BetterStackProvider({
9
- children,
10
- overrides,
11
- basePath
12
- }) {
13
- const value = {
14
- overrides,
15
- basePath
16
- };
17
- return /* @__PURE__ */ jsx(BetterStackContext.Provider, { value, children });
18
- }
19
- function useBetterStack() {
20
- const context = useContext(
21
- BetterStackContext
22
- );
23
- if (!context) {
24
- throw new Error(
25
- "useBetterStack must be used within BetterStackProvider. Wrap your app with <BetterStackProvider> in your layout file."
26
- );
27
- }
28
- return context;
29
- }
30
- function usePluginOverrides(pluginName) {
31
- const context = useBetterStack();
32
- const overrides = context.overrides[pluginName];
33
- if (!overrides) {
34
- throw new Error(
35
- `Plugin "${pluginName}" not found in BetterStackProvider. Available plugins: ${Object.keys(context.overrides).join(", ")}`
36
- );
37
- }
38
- return overrides;
39
- }
40
- function usePluginOverride(pluginName, overrideKey) {
41
- const overrides = usePluginOverrides(pluginName);
42
- const override = overrides[overrideKey];
43
- if (override === void 0) {
44
- const availableKeys = overrides && typeof overrides === "object" ? Object.keys(overrides).join(", ") : "none";
45
- throw new Error(
46
- `Override "${overrideKey}" not found for plugin "${pluginName}". Available overrides: ${availableKeys}`
47
- );
48
- }
49
- return override;
50
- }
51
- function useBasePath() {
52
- const context = useBetterStack();
53
- if (!context) {
54
- throw new Error(
55
- "useBasePath must be used within BetterStackProvider. Wrap your app with <BetterStackProvider> in your layout file."
56
- );
57
- }
58
- return context.basePath;
59
- }
60
-
61
- export { BetterStackProvider, useBasePath, useBetterStack, usePluginOverride, usePluginOverrides };
1
+ export { BetterStackProvider, useBasePath, useBetterStack, usePluginOverrides } from './provider.mjs';
@@ -0,0 +1,51 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const React = require('react');
6
+
7
+ const BetterStackContext = React.createContext(
8
+ null
9
+ );
10
+ function BetterStackProvider({
11
+ children,
12
+ overrides,
13
+ basePath
14
+ }) {
15
+ const value = {
16
+ overrides,
17
+ basePath
18
+ };
19
+ return /* @__PURE__ */ jsxRuntime.jsx(BetterStackContext.Provider, { value, children });
20
+ }
21
+ function useBetterStack() {
22
+ const context = React.useContext(
23
+ BetterStackContext
24
+ );
25
+ if (!context) {
26
+ throw new Error(
27
+ "useBetterStack must be used within BetterStackProvider. Wrap your app with <BetterStackProvider> in your layout file."
28
+ );
29
+ }
30
+ return context;
31
+ }
32
+ function usePluginOverrides(pluginName, defaultValues) {
33
+ const context = useBetterStack();
34
+ const pluginOverrides = context.overrides[pluginName];
35
+ const overrides = defaultValues ? { ...defaultValues, ...pluginOverrides } : pluginOverrides;
36
+ return overrides;
37
+ }
38
+ function useBasePath() {
39
+ const context = useBetterStack();
40
+ if (!context) {
41
+ throw new Error(
42
+ "useBasePath must be used within BetterStackProvider. Wrap your app with <BetterStackProvider> in your layout file."
43
+ );
44
+ }
45
+ return context.basePath;
46
+ }
47
+
48
+ exports.BetterStackProvider = BetterStackProvider;
49
+ exports.useBasePath = useBasePath;
50
+ exports.useBetterStack = useBetterStack;
51
+ exports.usePluginOverrides = usePluginOverrides;
@@ -0,0 +1,46 @@
1
+ "use client";
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { createContext, useContext } from 'react';
4
+
5
+ const BetterStackContext = createContext(
6
+ null
7
+ );
8
+ function BetterStackProvider({
9
+ children,
10
+ overrides,
11
+ basePath
12
+ }) {
13
+ const value = {
14
+ overrides,
15
+ basePath
16
+ };
17
+ return /* @__PURE__ */ jsx(BetterStackContext.Provider, { value, children });
18
+ }
19
+ function useBetterStack() {
20
+ const context = useContext(
21
+ BetterStackContext
22
+ );
23
+ if (!context) {
24
+ throw new Error(
25
+ "useBetterStack must be used within BetterStackProvider. Wrap your app with <BetterStackProvider> in your layout file."
26
+ );
27
+ }
28
+ return context;
29
+ }
30
+ function usePluginOverrides(pluginName, defaultValues) {
31
+ const context = useBetterStack();
32
+ const pluginOverrides = context.overrides[pluginName];
33
+ const overrides = defaultValues ? { ...defaultValues, ...pluginOverrides } : pluginOverrides;
34
+ return overrides;
35
+ }
36
+ function useBasePath() {
37
+ const context = useBetterStack();
38
+ if (!context) {
39
+ throw new Error(
40
+ "useBasePath must be used within BetterStackProvider. Wrap your app with <BetterStackProvider> in your layout file."
41
+ );
42
+ }
43
+ return context.basePath;
44
+ }
45
+
46
+ export { BetterStackProvider, useBasePath, useBetterStack, usePluginOverrides };
package/dist/index.cjs CHANGED
@@ -1,10 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  const api_index = require('./api/index.cjs');
4
- const betterCall = require('better-call');
5
- require('@btst/db');
4
+ const node = require('better-call/node');
6
5
 
7
6
 
8
7
 
9
8
  exports.betterStack = api_index.betterStack;
10
- exports.createEndpoint = betterCall.createEndpoint;
9
+ exports.toNodeHandler = node.toNodeHandler;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { betterStack } from './api/index.cjs';
2
- export { f as BackendLib, e as BackendLibConfig, B as BackendPlugin } from './shared/stack.DORw_1ps.cjs';
3
- export { createEndpoint } from 'better-call';
2
+ export { toNodeHandler } from 'better-call/node';
3
+ export { f as BackendLib, e as BackendLibConfig, B as BackendPlugin } from './shared/stack.ByOugz9d.cjs';
4
4
  import '@btst/yar';
5
5
  import '@btst/db';
6
+ import 'better-call';
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { betterStack } from './api/index.mjs';
2
- export { f as BackendLib, e as BackendLibConfig, B as BackendPlugin } from './shared/stack.DORw_1ps.mjs';
3
- export { createEndpoint } from 'better-call';
2
+ export { toNodeHandler } from 'better-call/node';
3
+ export { f as BackendLib, e as BackendLibConfig, B as BackendPlugin } from './shared/stack.ByOugz9d.mjs';
4
4
  import '@btst/yar';
5
5
  import '@btst/db';
6
+ import 'better-call';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { betterStack } from './api/index.js';
2
- export { f as BackendLib, e as BackendLibConfig, B as BackendPlugin } from './shared/stack.DORw_1ps.js';
3
- export { createEndpoint } from 'better-call';
2
+ export { toNodeHandler } from 'better-call/node';
3
+ export { f as BackendLib, e as BackendLibConfig, B as BackendPlugin } from './shared/stack.ByOugz9d.js';
4
4
  import '@btst/yar';
5
5
  import '@btst/db';
6
+ import 'better-call';
package/dist/index.mjs CHANGED
@@ -1,3 +1,2 @@
1
1
  export { betterStack } from './api/index.mjs';
2
- export { createEndpoint } from 'better-call';
3
- import '@btst/db';
2
+ export { toNodeHandler } from 'better-call/node';
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const betterCall = require('better-call');
4
+ const db = require('@btst/db');
5
+
6
+ function defineBackendPlugin(plugin) {
7
+ return plugin;
8
+ }
9
+
10
+ exports.createEndpoint = betterCall.createEndpoint;
11
+ exports.createRouter = betterCall.createRouter;
12
+ exports.createDbPlugin = db.createDbPlugin;
13
+ exports.defineBackendPlugin = defineBackendPlugin;
@@ -0,0 +1,40 @@
1
+ import { B as BackendPlugin } from '../../shared/stack.ByOugz9d.cjs';
2
+ export { C as ClientPlugin } from '../../shared/stack.ByOugz9d.cjs';
3
+ import { Endpoint } from 'better-call';
4
+ export { Endpoint, Router, createEndpoint, createRouter } from 'better-call';
5
+ export { Adapter, DatabaseDefinition, DbPlugin, createDbPlugin } from '@btst/db';
6
+ import '@btst/yar';
7
+
8
+ /**
9
+ * Plugin utilities and types for building standalone plugins
10
+ *
11
+ * This module exports everything needed to create custom plugins
12
+ * for Better Stack outside of this package.
13
+ *
14
+ * Note: Backend and Client plugins are separate to prevent SSR issues
15
+ * and enable better code splitting. Import them separately:
16
+ * - Backend: import type { BackendPlugin } from "@btst/stack/plugins/api"
17
+ * - Client: import type { ClientPlugin } from "@btst/stack/plugins/client"
18
+ */
19
+
20
+ /**
21
+ * Helper to define a backend plugin with full type inference
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const messagesPlugin = defineBackendPlugin({
26
+ * name: "messages",
27
+ * dbPlugin: createDbPlugin("messages", messagesSchema),
28
+ * routes: (adapter) => ({
29
+ * list: endpoint("/messages", { method: "GET" }, async () => { ... }),
30
+ * create: endpoint("/messages", { method: "POST" }, async () => { ... })
31
+ * })
32
+ * });
33
+ * // Route keys "list" and "create" are preserved in types
34
+ * ```
35
+ *
36
+ * @template TRoutes - The exact shape of routes (auto-inferred from routes function)
37
+ */
38
+ declare function defineBackendPlugin<TRoutes extends Record<string, Endpoint> = Record<string, Endpoint>>(plugin: BackendPlugin<TRoutes>): BackendPlugin<TRoutes>;
39
+
40
+ export { BackendPlugin, defineBackendPlugin };
@@ -0,0 +1,40 @@
1
+ import { B as BackendPlugin } from '../../shared/stack.ByOugz9d.mjs';
2
+ export { C as ClientPlugin } from '../../shared/stack.ByOugz9d.mjs';
3
+ import { Endpoint } from 'better-call';
4
+ export { Endpoint, Router, createEndpoint, createRouter } from 'better-call';
5
+ export { Adapter, DatabaseDefinition, DbPlugin, createDbPlugin } from '@btst/db';
6
+ import '@btst/yar';
7
+
8
+ /**
9
+ * Plugin utilities and types for building standalone plugins
10
+ *
11
+ * This module exports everything needed to create custom plugins
12
+ * for Better Stack outside of this package.
13
+ *
14
+ * Note: Backend and Client plugins are separate to prevent SSR issues
15
+ * and enable better code splitting. Import them separately:
16
+ * - Backend: import type { BackendPlugin } from "@btst/stack/plugins/api"
17
+ * - Client: import type { ClientPlugin } from "@btst/stack/plugins/client"
18
+ */
19
+
20
+ /**
21
+ * Helper to define a backend plugin with full type inference
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const messagesPlugin = defineBackendPlugin({
26
+ * name: "messages",
27
+ * dbPlugin: createDbPlugin("messages", messagesSchema),
28
+ * routes: (adapter) => ({
29
+ * list: endpoint("/messages", { method: "GET" }, async () => { ... }),
30
+ * create: endpoint("/messages", { method: "POST" }, async () => { ... })
31
+ * })
32
+ * });
33
+ * // Route keys "list" and "create" are preserved in types
34
+ * ```
35
+ *
36
+ * @template TRoutes - The exact shape of routes (auto-inferred from routes function)
37
+ */
38
+ declare function defineBackendPlugin<TRoutes extends Record<string, Endpoint> = Record<string, Endpoint>>(plugin: BackendPlugin<TRoutes>): BackendPlugin<TRoutes>;
39
+
40
+ export { BackendPlugin, defineBackendPlugin };