@brokr/sdk 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/dist/account.js +34 -0
  2. package/dist/account.mjs +7 -0
  3. package/dist/auth.js +628 -114
  4. package/dist/auth.mjs +611 -111
  5. package/dist/chat.js +34 -0
  6. package/dist/chat.mjs +7 -0
  7. package/dist/events.js +64 -0
  8. package/dist/events.mjs +37 -0
  9. package/dist/feature.js +6304 -0
  10. package/dist/feature.mjs +6278 -0
  11. package/dist/files.js +428 -0
  12. package/dist/files.mjs +408 -0
  13. package/dist/index.d.ts +18 -2
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +4069 -454
  16. package/dist/index.mjs +4040 -448
  17. package/dist/logs.js +148 -0
  18. package/dist/logs.mjs +124 -0
  19. package/dist/management.js +14 -13
  20. package/dist/management.mjs +14 -13
  21. package/dist/next.js +2725 -0
  22. package/dist/next.mjs +2710 -0
  23. package/dist/notifications.js +140 -0
  24. package/dist/notifications.mjs +110 -0
  25. package/dist/payments.js +32 -0
  26. package/dist/payments.mjs +7 -0
  27. package/dist/react-notifications.js +299 -0
  28. package/dist/react-notifications.mjs +267 -0
  29. package/dist/react-styles.js +2756 -0
  30. package/dist/react-styles.mjs +2720 -0
  31. package/dist/react-theme.js +4196 -0
  32. package/dist/react-theme.mjs +4172 -0
  33. package/dist/react.js +8591 -209
  34. package/dist/react.mjs +8571 -183
  35. package/dist/runtime.js +2113 -385
  36. package/dist/runtime.mjs +2085 -397
  37. package/dist/src/account/config.d.ts +42 -0
  38. package/dist/src/account/config.d.ts.map +1 -0
  39. package/dist/src/account/index.d.ts +3 -0
  40. package/dist/src/account/index.d.ts.map +1 -0
  41. package/dist/src/ai/client.d.ts +58 -0
  42. package/dist/src/ai/client.d.ts.map +1 -0
  43. package/dist/src/ai/conversation-title.d.ts +13 -0
  44. package/dist/src/ai/conversation-title.d.ts.map +1 -0
  45. package/dist/src/ai/types.d.ts +81 -0
  46. package/dist/src/ai/types.d.ts.map +1 -0
  47. package/dist/src/auth.d.ts +133 -20
  48. package/dist/src/auth.d.ts.map +1 -1
  49. package/dist/src/chat/config.d.ts +61 -0
  50. package/dist/src/chat/config.d.ts.map +1 -0
  51. package/dist/src/chat/index.d.ts +3 -0
  52. package/dist/src/chat/index.d.ts.map +1 -0
  53. package/dist/src/chat/sse-parser.d.ts +44 -0
  54. package/dist/src/chat/sse-parser.d.ts.map +1 -0
  55. package/dist/src/dev-console.d.ts +18 -0
  56. package/dist/src/dev-console.d.ts.map +1 -0
  57. package/dist/src/email/client.d.ts +33 -0
  58. package/dist/src/email/client.d.ts.map +1 -0
  59. package/dist/src/email/templates.d.ts +15 -0
  60. package/dist/src/email/templates.d.ts.map +1 -0
  61. package/dist/src/email/types.d.ts +35 -0
  62. package/dist/src/email/types.d.ts.map +1 -0
  63. package/dist/src/env-detect.d.ts +25 -0
  64. package/dist/src/env-detect.d.ts.map +1 -0
  65. package/dist/src/errors.d.ts +53 -0
  66. package/dist/src/errors.d.ts.map +1 -0
  67. package/dist/src/events/client.d.ts +25 -0
  68. package/dist/src/events/client.d.ts.map +1 -0
  69. package/dist/src/events/index.d.ts +9 -0
  70. package/dist/src/events/index.d.ts.map +1 -0
  71. package/dist/src/events/types.d.ts +10 -0
  72. package/dist/src/events/types.d.ts.map +1 -0
  73. package/dist/src/feature/canonical.d.ts +33 -0
  74. package/dist/src/feature/canonical.d.ts.map +1 -0
  75. package/dist/src/feature/create-feature.d.ts +33 -0
  76. package/dist/src/feature/create-feature.d.ts.map +1 -0
  77. package/dist/src/feature/db.d.ts +16 -0
  78. package/dist/src/feature/db.d.ts.map +1 -0
  79. package/dist/src/feature/handlers.d.ts +28 -0
  80. package/dist/src/feature/handlers.d.ts.map +1 -0
  81. package/dist/src/feature/index.d.ts +21 -0
  82. package/dist/src/feature/index.d.ts.map +1 -0
  83. package/dist/src/feature/manifest.d.ts +173 -0
  84. package/dist/src/feature/manifest.d.ts.map +1 -0
  85. package/dist/src/feature/mapping.d.ts +18 -0
  86. package/dist/src/feature/mapping.d.ts.map +1 -0
  87. package/dist/src/feature/runtime.d.ts +45 -0
  88. package/dist/src/feature/runtime.d.ts.map +1 -0
  89. package/dist/src/feature/types.d.ts +65 -0
  90. package/dist/src/feature/types.d.ts.map +1 -0
  91. package/dist/src/files/client.d.ts +28 -0
  92. package/dist/src/files/client.d.ts.map +1 -0
  93. package/dist/src/files/types.d.ts +28 -0
  94. package/dist/src/files/types.d.ts.map +1 -0
  95. package/dist/src/fix-registry.d.ts +8 -0
  96. package/dist/src/fix-registry.d.ts.map +1 -0
  97. package/dist/src/gateway.d.ts +32 -0
  98. package/dist/src/gateway.d.ts.map +1 -0
  99. package/dist/src/logs/capture.d.ts +56 -0
  100. package/dist/src/logs/capture.d.ts.map +1 -0
  101. package/dist/src/logs/index.d.ts +2 -0
  102. package/dist/src/logs/index.d.ts.map +1 -0
  103. package/dist/src/management.d.ts +1 -1
  104. package/dist/src/management.d.ts.map +1 -1
  105. package/dist/src/models.d.ts +32 -0
  106. package/dist/src/models.d.ts.map +1 -0
  107. package/dist/src/next/auth.d.ts +54 -0
  108. package/dist/src/next/auth.d.ts.map +1 -0
  109. package/dist/src/next/chat.d.ts +31 -0
  110. package/dist/src/next/chat.d.ts.map +1 -0
  111. package/dist/src/next/index.d.ts +14 -0
  112. package/dist/src/next/index.d.ts.map +1 -0
  113. package/dist/src/next/notifications.d.ts +67 -0
  114. package/dist/src/next/notifications.d.ts.map +1 -0
  115. package/dist/src/notifications/built-ins.d.ts +9 -0
  116. package/dist/src/notifications/built-ins.d.ts.map +1 -0
  117. package/dist/src/notifications/client.d.ts +38 -0
  118. package/dist/src/notifications/client.d.ts.map +1 -0
  119. package/dist/src/notifications/config.d.ts +71 -0
  120. package/dist/src/notifications/config.d.ts.map +1 -0
  121. package/dist/src/notifications/index.d.ts +6 -0
  122. package/dist/src/notifications/index.d.ts.map +1 -0
  123. package/dist/src/notifications/registry.d.ts +67 -0
  124. package/dist/src/notifications/registry.d.ts.map +1 -0
  125. package/dist/src/notifications/types.d.ts +48 -0
  126. package/dist/src/notifications/types.d.ts.map +1 -0
  127. package/dist/src/payments/client.d.ts +64 -0
  128. package/dist/src/payments/client.d.ts.map +1 -0
  129. package/dist/src/payments/config.d.ts +46 -0
  130. package/dist/src/payments/config.d.ts.map +1 -0
  131. package/dist/src/payments/entitlements.d.ts +48 -0
  132. package/dist/src/payments/entitlements.d.ts.map +1 -0
  133. package/dist/src/payments/types.d.ts +135 -0
  134. package/dist/src/payments/types.d.ts.map +1 -0
  135. package/dist/src/react/BrokrErrorBoundary.d.ts +23 -0
  136. package/dist/src/react/BrokrErrorBoundary.d.ts.map +1 -0
  137. package/dist/src/react/account/AccountPanel.d.ts +12 -0
  138. package/dist/src/react/account/AccountPanel.d.ts.map +1 -0
  139. package/dist/src/react/account/Avatar.d.ts +11 -0
  140. package/dist/src/react/account/Avatar.d.ts.map +1 -0
  141. package/dist/src/react/account/ProfilePhotoButton.d.ts +7 -0
  142. package/dist/src/react/account/ProfilePhotoButton.d.ts.map +1 -0
  143. package/dist/src/react/account/UserButton.d.ts +7 -0
  144. package/dist/src/react/account/UserButton.d.ts.map +1 -0
  145. package/dist/src/react/auth-pages/AuthPageShell.d.ts +9 -0
  146. package/dist/src/react/auth-pages/AuthPageShell.d.ts.map +1 -0
  147. package/dist/src/react/auth-pages/SignInPage.d.ts +9 -0
  148. package/dist/src/react/auth-pages/SignInPage.d.ts.map +1 -0
  149. package/dist/src/react/auth-pages/SignUpPage.d.ts +8 -0
  150. package/dist/src/react/auth-pages/SignUpPage.d.ts.map +1 -0
  151. package/dist/src/react/auth.d.ts +1 -49
  152. package/dist/src/react/auth.d.ts.map +1 -1
  153. package/dist/src/react/chat/AIChat.d.ts +4 -0
  154. package/dist/src/react/chat/AIChat.d.ts.map +1 -0
  155. package/dist/src/react/chat/ChatContext.d.ts +76 -0
  156. package/dist/src/react/chat/ChatContext.d.ts.map +1 -0
  157. package/dist/src/react/chat/ChatInput.d.ts +3 -0
  158. package/dist/src/react/chat/ChatInput.d.ts.map +1 -0
  159. package/dist/src/react/chat/MarkdownRenderer.d.ts +5 -0
  160. package/dist/src/react/chat/MarkdownRenderer.d.ts.map +1 -0
  161. package/dist/src/react/chat/MessageBubble.d.ts +14 -0
  162. package/dist/src/react/chat/MessageBubble.d.ts.map +1 -0
  163. package/dist/src/react/chat/MessagePane.d.ts +10 -0
  164. package/dist/src/react/chat/MessagePane.d.ts.map +1 -0
  165. package/dist/src/react/chat/ModelSelector.d.ts +13 -0
  166. package/dist/src/react/chat/ModelSelector.d.ts.map +1 -0
  167. package/dist/src/react/chat/ThreadSidebar.d.ts +3 -0
  168. package/dist/src/react/chat/ThreadSidebar.d.ts.map +1 -0
  169. package/dist/src/react/chat/index.d.ts +5 -0
  170. package/dist/src/react/chat/index.d.ts.map +1 -0
  171. package/dist/src/react/chat/token-limit.d.ts +14 -0
  172. package/dist/src/react/chat/token-limit.d.ts.map +1 -0
  173. package/dist/src/react/chat/types.d.ts +65 -0
  174. package/dist/src/react/chat/types.d.ts.map +1 -0
  175. package/dist/src/react/chat/useChat.d.ts +57 -0
  176. package/dist/src/react/chat/useChat.d.ts.map +1 -0
  177. package/dist/src/react/composites/FabAI.d.ts +15 -0
  178. package/dist/src/react/composites/FabAI.d.ts.map +1 -0
  179. package/dist/src/react/composites/FeedbackWidget.d.ts +10 -0
  180. package/dist/src/react/composites/FeedbackWidget.d.ts.map +1 -0
  181. package/dist/src/react/composites/SmartUpload.d.ts +12 -0
  182. package/dist/src/react/composites/SmartUpload.d.ts.map +1 -0
  183. package/dist/src/react/config.d.ts +23 -0
  184. package/dist/src/react/config.d.ts.map +1 -0
  185. package/dist/src/react/context.d.ts +4 -0
  186. package/dist/src/react/context.d.ts.map +1 -0
  187. package/dist/src/react/css/account.d.ts +2 -0
  188. package/dist/src/react/css/account.d.ts.map +1 -0
  189. package/dist/src/react/css/animations.d.ts +2 -0
  190. package/dist/src/react/css/animations.d.ts.map +1 -0
  191. package/dist/src/react/css/auth.d.ts +2 -0
  192. package/dist/src/react/css/auth.d.ts.map +1 -0
  193. package/dist/src/react/css/chat-extras.d.ts +2 -0
  194. package/dist/src/react/css/chat-extras.d.ts.map +1 -0
  195. package/dist/src/react/css/chat.d.ts +2 -0
  196. package/dist/src/react/css/chat.d.ts.map +1 -0
  197. package/dist/src/react/css/composites.d.ts +2 -0
  198. package/dist/src/react/css/composites.d.ts.map +1 -0
  199. package/dist/src/react/css/gates.d.ts +2 -0
  200. package/dist/src/react/css/gates.d.ts.map +1 -0
  201. package/dist/src/react/css/index.d.ts +3 -0
  202. package/dist/src/react/css/index.d.ts.map +1 -0
  203. package/dist/src/react/css/markdown.d.ts +2 -0
  204. package/dist/src/react/css/markdown.d.ts.map +1 -0
  205. package/dist/src/react/css/notifications.d.ts +2 -0
  206. package/dist/src/react/css/notifications.d.ts.map +1 -0
  207. package/dist/src/react/css/primitives.d.ts +2 -0
  208. package/dist/src/react/css/primitives.d.ts.map +1 -0
  209. package/dist/src/react/css/reset.d.ts +2 -0
  210. package/dist/src/react/css/reset.d.ts.map +1 -0
  211. package/dist/src/react/css/responsive.d.ts +2 -0
  212. package/dist/src/react/css/responsive.d.ts.map +1 -0
  213. package/dist/src/react/css/skeleton.d.ts +2 -0
  214. package/dist/src/react/css/skeleton.d.ts.map +1 -0
  215. package/dist/src/react/css/tokens.d.ts +2 -0
  216. package/dist/src/react/css/tokens.d.ts.map +1 -0
  217. package/dist/src/react/gates/AuthWall.d.ts +7 -0
  218. package/dist/src/react/gates/AuthWall.d.ts.map +1 -0
  219. package/dist/src/react/gates/BillingBoundary.d.ts +4 -0
  220. package/dist/src/react/gates/BillingBoundary.d.ts.map +1 -0
  221. package/dist/src/react/gates/Gate.d.ts +9 -0
  222. package/dist/src/react/gates/Gate.d.ts.map +1 -0
  223. package/dist/src/react/gates/RequirePlan.d.ts +4 -0
  224. package/dist/src/react/gates/RequirePlan.d.ts.map +1 -0
  225. package/dist/src/react/gates/RequireUser.d.ts +4 -0
  226. package/dist/src/react/gates/RequireUser.d.ts.map +1 -0
  227. package/dist/src/react/gates/UsageGate.d.ts +4 -0
  228. package/dist/src/react/gates/UsageGate.d.ts.map +1 -0
  229. package/dist/src/react/helpers.d.ts +7 -0
  230. package/dist/src/react/helpers.d.ts.map +1 -0
  231. package/dist/src/react/hooks/use-theme.d.ts +15 -0
  232. package/dist/src/react/hooks/use-theme.d.ts.map +1 -0
  233. package/dist/src/react/hooks/use-user.d.ts +12 -0
  234. package/dist/src/react/hooks/use-user.d.ts.map +1 -0
  235. package/dist/src/react/icons.d.ts +26 -0
  236. package/dist/src/react/icons.d.ts.map +1 -0
  237. package/dist/src/react/index.d.ts +48 -0
  238. package/dist/src/react/index.d.ts.map +1 -0
  239. package/dist/src/react/notifications/NotificationBell.d.ts +7 -0
  240. package/dist/src/react/notifications/NotificationBell.d.ts.map +1 -0
  241. package/dist/src/react/notifications/NotificationList.d.ts +7 -0
  242. package/dist/src/react/notifications/NotificationList.d.ts.map +1 -0
  243. package/dist/src/react/notifications/Toast.d.ts +13 -0
  244. package/dist/src/react/notifications/Toast.d.ts.map +1 -0
  245. package/dist/src/react/notifications/index.d.ts +8 -0
  246. package/dist/src/react/notifications/index.d.ts.map +1 -0
  247. package/dist/src/react/notifications/provider.d.ts +14 -0
  248. package/dist/src/react/notifications/provider.d.ts.map +1 -0
  249. package/dist/src/react/notifications/use-notifications.d.ts +24 -0
  250. package/dist/src/react/notifications/use-notifications.d.ts.map +1 -0
  251. package/dist/src/react/payments/AutoReloadToggle.d.ts +6 -0
  252. package/dist/src/react/payments/AutoReloadToggle.d.ts.map +1 -0
  253. package/dist/src/react/payments/Balance.d.ts +8 -0
  254. package/dist/src/react/payments/Balance.d.ts.map +1 -0
  255. package/dist/src/react/payments/CancelSubscription.d.ts +6 -0
  256. package/dist/src/react/payments/CancelSubscription.d.ts.map +1 -0
  257. package/dist/src/react/payments/CheckoutButton.d.ts +7 -0
  258. package/dist/src/react/payments/CheckoutButton.d.ts.map +1 -0
  259. package/dist/src/react/payments/CustomerPortalButton.d.ts +6 -0
  260. package/dist/src/react/payments/CustomerPortalButton.d.ts.map +1 -0
  261. package/dist/src/react/payments/FeatureMeter.d.ts +6 -0
  262. package/dist/src/react/payments/FeatureMeter.d.ts.map +1 -0
  263. package/dist/src/react/payments/Plans.d.ts +8 -0
  264. package/dist/src/react/payments/Plans.d.ts.map +1 -0
  265. package/dist/src/react/payments/TopUpButton.d.ts +8 -0
  266. package/dist/src/react/payments/TopUpButton.d.ts.map +1 -0
  267. package/dist/src/react/payments/UpdateBilling.d.ts +3 -0
  268. package/dist/src/react/payments/UpdateBilling.d.ts.map +1 -0
  269. package/dist/src/react/payments/UpgradePrompt.d.ts +8 -0
  270. package/dist/src/react/payments/UpgradePrompt.d.ts.map +1 -0
  271. package/dist/src/react/primitives/Skeleton.d.ts +15 -0
  272. package/dist/src/react/primitives/Skeleton.d.ts.map +1 -0
  273. package/dist/src/react/provider.d.ts +21 -0
  274. package/dist/src/react/provider.d.ts.map +1 -0
  275. package/dist/src/react/request.d.ts +2 -0
  276. package/dist/src/react/request.d.ts.map +1 -0
  277. package/dist/src/react/styles-entry.d.ts +4 -0
  278. package/dist/src/react/styles-entry.d.ts.map +1 -0
  279. package/dist/src/react/styles.d.ts +2 -0
  280. package/dist/src/react/styles.d.ts.map +1 -0
  281. package/dist/src/react/theme-entry.d.ts +3 -0
  282. package/dist/src/react/theme-entry.d.ts.map +1 -0
  283. package/dist/src/react/theme.d.ts +6 -0
  284. package/dist/src/react/theme.d.ts.map +1 -0
  285. package/dist/src/react/types.d.ts +191 -0
  286. package/dist/src/react/types.d.ts.map +1 -0
  287. package/dist/src/react/use-brokr-theme.d.ts +6 -0
  288. package/dist/src/react/use-brokr-theme.d.ts.map +1 -0
  289. package/dist/src/runtime.d.ts +69 -180
  290. package/dist/src/runtime.d.ts.map +1 -1
  291. package/dist/src/storage/client.d.ts +113 -0
  292. package/dist/src/storage/client.d.ts.map +1 -0
  293. package/dist/src/storage/types.d.ts +60 -0
  294. package/dist/src/storage/types.d.ts.map +1 -0
  295. package/dist/tsconfig.tsbuildinfo +1 -1
  296. package/dist/types.d.ts +2 -2
  297. package/dist/types.d.ts.map +1 -1
  298. package/package.json +70 -9
package/dist/auth.mjs CHANGED
@@ -1,26 +1,616 @@
1
- var __getOwnPropNames = Object.getOwnPropertyNames;
2
- var __esm = (fn, res) => function __init() {
3
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
1
+ // src/fix-registry.ts
2
+ var FIX_REGISTRY = {
3
+ AUTH_TOKEN_INVALID: [
4
+ "\u2192 Run `brokr env pull --stack <name>` to refresh your token",
5
+ "\u2192 Or run `brokr link account` to re-authenticate"
6
+ ].join("\n"),
7
+ AUTH_SESSION_EXPIRED: [
8
+ "\u2192 Run `brokr link account` to re-authenticate"
9
+ ].join("\n"),
10
+ BROKR_TOKEN_MISSING: [
11
+ "\u2192 Run `brokr env pull --stack <name>` to sync your environment",
12
+ "\u2192 Or add BROKR_TOKEN to your .env.local manually"
13
+ ].join("\n"),
14
+ DATABASE_PROVISION_FAILED: [
15
+ "\u2192 Run `brokr status <stack>` to check current state",
16
+ "\u2192 Run `brokr retry <stack>` to re-trigger provisioning"
17
+ ].join("\n"),
18
+ DATABASE_QUOTA_REACHED: [
19
+ "\u2192 Upgrade your plan or delete unused databases",
20
+ "\u2192 Check usage at brokr.sh/billing"
21
+ ].join("\n"),
22
+ DATABASE_HEALTH_TIMEOUT: [
23
+ "\u2192 Run `brokr status <stack>` to check database state",
24
+ "\u2192 If persistent, check provider status page"
25
+ ].join("\n"),
26
+ DEPLOYMENT_FAILED: [
27
+ "\u2192 Run `brokr logs --stack <name>` to see build logs",
28
+ "\u2192 Fix the build error and run `brokr deploy`"
29
+ ].join("\n"),
30
+ DEPLOYMENT_RATE_LIMITED: [
31
+ "\u2192 Wait a minute and retry",
32
+ "\u2192 Vercel rate limits apply per project"
33
+ ].join("\n"),
34
+ REPO_ALREADY_EXISTS: [
35
+ "\u2192 Use a different stack name",
36
+ "\u2192 Or run `brokr status <stack>` to check the existing stack"
37
+ ].join("\n"),
38
+ REPO_CREATE_FAILED: [
39
+ "\u2192 Check your GitHub connection: `brokr link account`",
40
+ "\u2192 Ensure the Brokr GitHub App is installed"
41
+ ].join("\n"),
42
+ EMAIL_DOMAIN_FAILED: [
43
+ "\u2192 Check DNS records are propagated",
44
+ "\u2192 Run `brokr status <stack>` for details"
45
+ ].join("\n"),
46
+ DNS_RECORD_FAILED: [
47
+ "\u2192 Check Cloudflare dashboard for zone status",
48
+ "\u2192 Retry with `brokr retry <stack>`"
49
+ ].join("\n"),
50
+ INSUFFICIENT_CREDITS: [
51
+ "\u2192 Top up credits at brokr.sh/billing",
52
+ "\u2192 Or run `brokr billing topup`"
53
+ ].join("\n"),
54
+ AI_BUDGET_EXCEEDED: [
55
+ "\u2192 Top up credits at brokr.sh/billing",
56
+ "\u2192 Or run `brokr billing topup`"
57
+ ].join("\n"),
58
+ AI_PROVIDER_UNAVAILABLE: [
59
+ "\u2192 The AI provider is temporarily down",
60
+ "\u2192 Retry in a few seconds \u2014 this is usually transient"
61
+ ].join("\n"),
62
+ AI_MODEL_NOT_FOUND: [
63
+ "\u2192 Check the model name in your configuration",
64
+ "\u2192 See available models at brokr.sh/docs/ai-models"
65
+ ].join("\n"),
66
+ ENV_VAR_MISSING: [
67
+ "\u2192 Run `brokr env pull --stack <name>` to sync environment",
68
+ "\u2192 Check required vars in your template README"
69
+ ].join("\n"),
70
+ STACK_LIMIT_REACHED: [
71
+ "\u2192 Delete unused stacks with `brokr delete <stack>`",
72
+ "\u2192 Or upgrade your plan at brokr.sh/billing"
73
+ ].join("\n"),
74
+ STACK_NOT_FOUND: [
75
+ "\u2192 Check the stack name: `brokr list`",
76
+ "\u2192 Create a new stack: `brokr create --name <name>`"
77
+ ].join("\n"),
78
+ RATE_LIMITED: [
79
+ "\u2192 Wait a moment and retry",
80
+ "\u2192 If persistent, check brokr.sh/status"
81
+ ].join("\n"),
82
+ GATEWAY_AUTH_FAILED: [
83
+ "\u2192 Your BROKR_TOKEN may be expired",
84
+ "\u2192 Run `brokr env pull --stack <name>` to refresh"
85
+ ].join("\n"),
86
+ BROKR_TOKEN_INVALID: [
87
+ "\u2192 Your BROKR_TOKEN has expired or been revoked",
88
+ "\u2192 Run `brokr env pull --stack <name>` to get a fresh token"
89
+ ].join("\n"),
90
+ AI_STREAM_ERROR: [
91
+ "\u2192 The AI stream was interrupted",
92
+ "\u2192 Retry the request \u2014 this is usually transient"
93
+ ].join("\n"),
94
+ EMAIL_SEND_FAILED: [
95
+ "\u2192 Email delivery failed",
96
+ "\u2192 Check that your domain DNS is verified: `brokr status <stack>`"
97
+ ].join("\n"),
98
+ EMAIL_NOT_CONFIGURED: [
99
+ "\u2192 Email is not set up for this stack",
100
+ "\u2192 Add email capability: `brokr add email --stack <name>`"
101
+ ].join("\n"),
102
+ EMAIL_INVALID_FROM: [
103
+ "\u2192 The from address must match your verified domain",
104
+ "\u2192 Check your domain: `brokr status <stack>`"
105
+ ].join("\n"),
106
+ STORAGE_UPLOAD_FAILED: [
107
+ "\u2192 File upload failed",
108
+ "\u2192 Check file size limits and retry"
109
+ ].join("\n"),
110
+ STORAGE_NOT_FOUND: [
111
+ "\u2192 The requested file does not exist",
112
+ "\u2192 Check the key and try again"
113
+ ].join("\n"),
114
+ PAYMENTS_NOT_CONFIGURED: [
115
+ "\u2192 Payments are not set up for this stack",
116
+ "\u2192 Run `brokr payments sync` to configure Stripe"
117
+ ].join("\n"),
118
+ PAYMENTS_FAILED: [
119
+ "\u2192 Payment processing failed",
120
+ "\u2192 Check your Stripe dashboard for details"
121
+ ].join("\n"),
122
+ GATEWAY_INTERNAL: [
123
+ "\u2192 The Brokr gateway encountered an internal error",
124
+ "\u2192 Check brokr.sh/status for service health"
125
+ ].join("\n"),
126
+ UPSTREAM_ERROR: [
127
+ "\u2192 An upstream service is temporarily unavailable",
128
+ "\u2192 Retry in a few seconds \u2014 this is usually transient"
129
+ ].join("\n"),
130
+ NETWORK_ERROR: [
131
+ "\u2192 Could not reach the Brokr gateway",
132
+ "\u2192 Check your internet connection",
133
+ "\u2192 Check brokr.sh/status for service health"
134
+ ].join("\n"),
135
+ TIMEOUT: [
136
+ "\u2192 Request timed out",
137
+ "\u2192 Retry \u2014 if persistent, check brokr.sh/status"
138
+ ].join("\n")
4
139
  };
5
140
 
6
- // src/runtime.ts
7
- var BrokrError;
8
- var init_runtime = __esm({
9
- "src/runtime.ts"() {
10
- "use strict";
11
- BrokrError = class extends Error {
12
- constructor(message, code, capability, retryable = false) {
13
- super(message);
14
- this.code = code;
15
- this.capability = capability;
16
- this.retryable = retryable;
17
- this.name = "BrokrError";
18
- }
141
+ // src/errors.ts
142
+ var BrokrError = class extends Error {
143
+ constructor(message, code, capability, retryable = false, errorCode, requestId, hint) {
144
+ super(message);
145
+ this.code = code;
146
+ this.capability = capability;
147
+ this.retryable = retryable;
148
+ this.errorCode = errorCode;
149
+ this.requestId = requestId;
150
+ this.hint = hint;
151
+ this.name = "BrokrError";
152
+ }
153
+ /** Multi-line terminal fix block — looked up from error code. */
154
+ get fix() {
155
+ if (!this.errorCode) return void 0;
156
+ return FIX_REGISTRY[this.errorCode];
157
+ }
158
+ /** Documentation URL for this error code. */
159
+ get docsUrl() {
160
+ if (!this.errorCode) return void 0;
161
+ return `https://brokr.sh/errors/${this.errorCode.toLowerCase().replace(/_/g, "-")}`;
162
+ }
163
+ /** Safe message for end users — zero technical language. */
164
+ toUserMessage() {
165
+ switch (this.code) {
166
+ case "RATE_LIMITED":
167
+ return "Please wait a moment and try again.";
168
+ case "TIMEOUT":
169
+ return "The request took too long. Please try again.";
170
+ case "NETWORK_ERROR":
171
+ return "Connection issue. Check your internet and try again.";
172
+ case "BROKR_TOKEN_MISSING":
173
+ return "App is not connected to Brokr. Contact the developer.";
174
+ case "BROKR_TOKEN_INVALID":
175
+ return "Session expired. Please refresh.";
176
+ case "AI_BUDGET_EXCEEDED":
177
+ return "AI usage limit reached. The developer needs to add credits.";
178
+ case "AI_PROVIDER_UNAVAILABLE":
179
+ return "AI service is temporarily down. Please retry shortly.";
180
+ case "AI_PROVIDER_RATE_LIMITED":
181
+ return "Too many AI requests. Please wait a moment.";
182
+ case "INSUFFICIENT_CREDITS":
183
+ return "Not enough credits. Please top up your balance.";
184
+ case "STORAGE_UPLOAD_FAILED":
185
+ return "File upload failed. Please try again.";
186
+ case "STORAGE_NOT_FOUND":
187
+ return "File not found.";
188
+ case "EMAIL_SEND_FAILED":
189
+ return "Email could not be sent. Please try again.";
190
+ case "EMAIL_NOT_CONFIGURED":
191
+ return "Email is not set up for this app.";
192
+ case "PAYMENTS_NOT_CONFIGURED":
193
+ return "Payments are not configured. Contact the developer.";
194
+ case "PAYMENTS_FAILED":
195
+ return "Payment processing failed. Please try again.";
196
+ case "NOT_FOUND":
197
+ return "The requested resource was not found.";
198
+ case "VALIDATION_ERROR":
199
+ return "Invalid input. Please check your data and try again.";
200
+ default:
201
+ return "Something went wrong. We're looking into it.";
202
+ }
203
+ }
204
+ toString() {
205
+ return `${this.name} [${this.errorCode ?? this.code}]: ${this.message}`;
206
+ }
207
+ toJSON() {
208
+ return {
209
+ name: this.name,
210
+ code: this.code,
211
+ errorCode: this.errorCode,
212
+ message: this.message,
213
+ capability: this.capability,
214
+ retryable: this.retryable,
215
+ requestId: this.requestId,
216
+ hint: this.hint,
217
+ component: this.component
19
218
  };
20
219
  }
21
- });
220
+ };
22
221
 
23
222
  // src/auth.ts
223
+ function resolveAppUrl(appUrl) {
224
+ if (appUrl) return appUrl;
225
+ throw new BrokrError(
226
+ "[brokr] BROKR_AUTH_URL is not set. Auth may not be provisioned.",
227
+ "AUTH_NOT_CONFIGURED",
228
+ "auth"
229
+ );
230
+ }
231
+ function mapSessionUser(raw) {
232
+ return {
233
+ id: raw.id,
234
+ email: raw.email,
235
+ name: raw.name ?? null,
236
+ image: raw.image ?? null,
237
+ emailVerified: raw.emailVerified ? /* @__PURE__ */ new Date() : null
238
+ };
239
+ }
240
+ function pluralizeResource(resource) {
241
+ if (resource.endsWith("s")) return resource;
242
+ if (resource.endsWith("y") && !/[aeiou]y$/i.test(resource)) return resource.slice(0, -1) + "ies";
243
+ return resource + "s";
244
+ }
245
+ function validateSqlIdentifier(name, label) {
246
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
247
+ throw new BrokrError(
248
+ `[brokr] Invalid ${label}: "${name}". Must be alphanumeric with underscores only.`,
249
+ "INVALID_IDENTIFIER",
250
+ "auth"
251
+ );
252
+ }
253
+ }
254
+ var _ownershipPool = null;
255
+ async function getOwnershipPool(dbUrl) {
256
+ let Pool;
257
+ try {
258
+ const mod = await import("@neondatabase/serverless");
259
+ Pool = mod.Pool;
260
+ } catch {
261
+ throw new BrokrError(
262
+ "[brokr] @neondatabase/serverless is required for ownership checks. Run: npm install @neondatabase/serverless",
263
+ "MISSING_DEPENDENCY",
264
+ "auth"
265
+ );
266
+ }
267
+ if (_ownershipPool && _ownershipPool.dbUrl === dbUrl) {
268
+ return _ownershipPool.pool;
269
+ }
270
+ const pool = new Pool({ connectionString: dbUrl, max: 3 });
271
+ _ownershipPool = { pool, dbUrl };
272
+ return pool;
273
+ }
274
+ async function authApiFetch(appUrl, path, options) {
275
+ const headers = { "Content-Type": "application/json" };
276
+ if (options?.cookies) headers.cookie = options.cookies;
277
+ if (typeof window === "undefined") {
278
+ headers.Origin = process.env.BETTER_AUTH_URL ?? process.env.NEXT_PUBLIC_APP_URL ?? process.env.APP_URL ?? process.env.BROKR_AUTH_URL ?? (process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : void 0) ?? appUrl;
279
+ }
280
+ const res = await fetch(`${appUrl}${path}`, {
281
+ method: options?.method ?? "GET",
282
+ headers,
283
+ body: options?.body ? JSON.stringify(options.body) : void 0
284
+ });
285
+ if (!res.ok) {
286
+ const data = await res.json().catch(() => ({}));
287
+ throw new BrokrError(
288
+ data.message ?? `[brokr] Auth API call failed (HTTP ${res.status})`,
289
+ "AUTH_API_FAILED",
290
+ "auth"
291
+ );
292
+ }
293
+ return res.json();
294
+ }
295
+ var BrokrAuthClient = class {
296
+ constructor(_token, _gatewayUrl, appUrl) {
297
+ this._appUrl = appUrl ?? (typeof process !== "undefined" ? process.env.BROKR_AUTH_URL : void 0);
298
+ }
299
+ // -------------------------------------------------------------------------
300
+ // Identity — read user/session from incoming request
301
+ // -------------------------------------------------------------------------
302
+ /**
303
+ * Get user from request headers. Returns null if not authenticated.
304
+ * Calls the app's own Better Auth API.
305
+ */
306
+ async user(headers) {
307
+ const session = await this.session(headers);
308
+ return session?.user ?? null;
309
+ }
310
+ /**
311
+ * Get user from request headers. Throws 401 if not authenticated.
312
+ */
313
+ async requireUser(headers) {
314
+ const u = await this.user(headers);
315
+ if (!u) {
316
+ throw new BrokrError("[brokr] Authentication required. The request has no valid session. Check that cookies are being forwarded.", "UNAUTHORIZED", "auth");
317
+ }
318
+ return u;
319
+ }
320
+ /**
321
+ * Get full session from request headers. Returns null if not authenticated.
322
+ */
323
+ async session(headers) {
324
+ const appUrl = resolveAppUrl(this._appUrl);
325
+ const cookieHeader = headers.get("cookie") ?? "";
326
+ if (!cookieHeader) return null;
327
+ const res = await fetch(`${appUrl}/api/auth/get-session`, {
328
+ method: "GET",
329
+ headers: { cookie: cookieHeader }
330
+ });
331
+ if (!res.ok) return null;
332
+ const data = await res.json();
333
+ if (!data?.user || !data?.session) return null;
334
+ return {
335
+ user: mapSessionUser(data.user),
336
+ sessionId: data.session.id,
337
+ expiresAt: new Date(data.session.expiresAt)
338
+ };
339
+ }
340
+ /**
341
+ * Get full session. Throws 401 if not authenticated.
342
+ */
343
+ async requireSession(headers) {
344
+ const s = await this.session(headers);
345
+ if (!s) {
346
+ throw new BrokrError("[brokr] Authentication required. The request has no valid session. Check that cookies are being forwarded.", "UNAUTHORIZED", "auth");
347
+ }
348
+ return s;
349
+ }
350
+ // -------------------------------------------------------------------------
351
+ // Legacy aliases (backward compat)
352
+ // -------------------------------------------------------------------------
353
+ /** @deprecated Use user(request.headers) instead. */
354
+ async currentUser(request) {
355
+ return this.user(request.headers);
356
+ }
357
+ /** @deprecated Use session(request.headers) instead. */
358
+ async getSession(request) {
359
+ return this.session(request.headers);
360
+ }
361
+ // -------------------------------------------------------------------------
362
+ // Auth actions — call Better Auth endpoints on the stack's app
363
+ // -------------------------------------------------------------------------
364
+ /**
365
+ * Sign in with email and password.
366
+ */
367
+ async signIn(params) {
368
+ const appUrl = resolveAppUrl(this._appUrl);
369
+ const data = await authApiFetch(appUrl, "/api/auth/sign-in/email", {
370
+ method: "POST",
371
+ body: params
372
+ });
373
+ return {
374
+ user: mapSessionUser(data.user),
375
+ sessionId: data.session.id,
376
+ expiresAt: new Date(data.session.expiresAt)
377
+ };
378
+ }
379
+ /**
380
+ * Sign in with OAuth provider. Returns redirect URL.
381
+ */
382
+ async signInWithProvider(provider, options) {
383
+ const appUrl = resolveAppUrl(this._appUrl);
384
+ const redirectTo = options?.redirectTo ?? "/";
385
+ if (!redirectTo.startsWith("/") || redirectTo.startsWith("//")) {
386
+ throw new BrokrError("[brokr] redirectTo must be a relative path (start with /)", "INVALID_REDIRECT", "auth");
387
+ }
388
+ if (!/^[a-z][a-z0-9_-]*$/.test(provider)) {
389
+ throw new BrokrError(`[brokr] Invalid provider name: "${provider}". Must be lowercase alphanumeric.`, "INVALID_PROVIDER", "auth");
390
+ }
391
+ const params = new URLSearchParams({ provider, callbackURL: redirectTo });
392
+ return { redirectUrl: `${appUrl}/api/auth/sign-in/social?${params}` };
393
+ }
394
+ /**
395
+ * Sign up with email and password.
396
+ */
397
+ async signUp(params) {
398
+ const appUrl = resolveAppUrl(this._appUrl);
399
+ const data = await authApiFetch(appUrl, "/api/auth/sign-up/email", {
400
+ method: "POST",
401
+ body: params
402
+ });
403
+ return {
404
+ user: mapSessionUser(data.user),
405
+ sessionId: data.session.id,
406
+ expiresAt: new Date(data.session.expiresAt)
407
+ };
408
+ }
409
+ /**
410
+ * Sign out the current user.
411
+ */
412
+ async signOut(headers) {
413
+ const appUrl = resolveAppUrl(this._appUrl);
414
+ const cookies = headers?.get("cookie") ?? "";
415
+ await authApiFetch(appUrl, "/api/auth/sign-out", {
416
+ method: "POST",
417
+ cookies
418
+ });
419
+ }
420
+ /**
421
+ * Send a magic link email.
422
+ */
423
+ async sendMagicLink(email, options) {
424
+ const appUrl = resolveAppUrl(this._appUrl);
425
+ await authApiFetch(appUrl, "/api/auth/magic-link/send", {
426
+ method: "POST",
427
+ body: { email, callbackURL: options?.redirectTo ?? "/" }
428
+ });
429
+ }
430
+ /**
431
+ * Send a password reset email.
432
+ */
433
+ async sendPasswordReset(params) {
434
+ const appUrl = resolveAppUrl(this._appUrl);
435
+ await authApiFetch(appUrl, "/api/auth/forget-password", {
436
+ method: "POST",
437
+ body: params
438
+ });
439
+ }
440
+ /**
441
+ * Reset password with token from email.
442
+ */
443
+ async resetPassword(params) {
444
+ const appUrl = resolveAppUrl(this._appUrl);
445
+ await authApiFetch(appUrl, "/api/auth/reset-password", {
446
+ method: "POST",
447
+ body: { token: params.token, newPassword: params.password }
448
+ });
449
+ }
450
+ /**
451
+ * Verify email with token from email.
452
+ */
453
+ async verifyEmail(params) {
454
+ const appUrl = resolveAppUrl(this._appUrl);
455
+ await authApiFetch(appUrl, "/api/auth/verify-email", {
456
+ method: "POST",
457
+ body: params
458
+ });
459
+ }
460
+ /**
461
+ * Update the current user's profile.
462
+ */
463
+ async updateUser(params, headers) {
464
+ const appUrl = resolveAppUrl(this._appUrl);
465
+ const cookies = headers?.get("cookie") ?? "";
466
+ await authApiFetch(appUrl, "/api/auth/update-user", {
467
+ method: "POST",
468
+ body: params,
469
+ cookies
470
+ });
471
+ }
472
+ // -------------------------------------------------------------------------
473
+ // Session management
474
+ // -------------------------------------------------------------------------
475
+ /** Session management sub-client. */
476
+ get sessions() {
477
+ if (!this._sessions) {
478
+ this._sessions = new BrokrSessionsClient(this._appUrl);
479
+ }
480
+ return this._sessions;
481
+ }
482
+ // -------------------------------------------------------------------------
483
+ // Ownership — queries the stack's own DB via gateway → server
484
+ // -------------------------------------------------------------------------
485
+ /**
486
+ * Check if the current user owns a resource. Throws 403 if not.
487
+ *
488
+ * Queries the developer's own database directly via DATABASE_URL.
489
+ * Convention: pluralizes resource name → table, assumes `id` PK + `user_id` owner column.
490
+ * Override with `opts.table` and `opts.ownerColumn` for non-standard schemas.
491
+ *
492
+ * @example
493
+ * ```ts
494
+ * await brokr.auth.requireOwner('conversation', conversationId, request.headers);
495
+ * // Under the hood: SELECT 1 FROM conversations WHERE id = $1 AND user_id = $2
496
+ * ```
497
+ */
498
+ async requireOwner(resource, id, headers, opts) {
499
+ const isOwner = await this.isOwner(resource, id, headers, opts);
500
+ if (!isOwner) {
501
+ throw new BrokrError(
502
+ `[brokr] Access denied \u2014 current user does not own this ${resource}. Verify the resource ID and that the user is the owner.`,
503
+ "FORBIDDEN",
504
+ "auth"
505
+ );
506
+ }
507
+ }
508
+ /**
509
+ * Check if the current user owns a resource. Returns boolean.
510
+ *
511
+ * Runs a direct query against the developer's database (DATABASE_URL).
512
+ * No gateway round-trip — this is a local DB operation.
513
+ */
514
+ async isOwner(resource, id, headers, opts) {
515
+ const user = await this.requireUser(headers);
516
+ const dbUrl = typeof process !== "undefined" ? process.env.DATABASE_URL : void 0;
517
+ if (!dbUrl) {
518
+ throw new BrokrError(
519
+ "[brokr] DATABASE_URL is not set. Cannot check ownership without a database.",
520
+ "DB_NOT_CONFIGURED",
521
+ "auth"
522
+ );
523
+ }
524
+ const tableName = opts?.table ?? pluralizeResource(resource);
525
+ const ownerCol = opts?.ownerColumn ?? "user_id";
526
+ validateSqlIdentifier(tableName, "table name");
527
+ validateSqlIdentifier(ownerCol, "owner column");
528
+ const pool = await getOwnershipPool(dbUrl);
529
+ try {
530
+ const result = await pool.query(
531
+ `SELECT 1 FROM "${tableName}" WHERE id = $1 AND "${ownerCol}" = $2 LIMIT 1`,
532
+ [id, user.id]
533
+ );
534
+ return (result.rowCount ?? 0) > 0;
535
+ } catch (err) {
536
+ const msg = err instanceof Error ? err.message : String(err);
537
+ console.error("[brokr] Ownership check error:", msg);
538
+ if (msg.includes("does not exist")) {
539
+ throw new BrokrError(
540
+ `[brokr] Table "${tableName}" does not exist. Check your resource name or provide { table: '...' }.`,
541
+ "TABLE_NOT_FOUND",
542
+ "auth"
543
+ );
544
+ }
545
+ throw new BrokrError(
546
+ "[brokr] Ownership check failed. Check your DATABASE_URL and that the database is accessible.",
547
+ "DB_QUERY_FAILED",
548
+ "auth"
549
+ );
550
+ }
551
+ }
552
+ /**
553
+ * Check if the current user matches a specific userId. Throws 403 if not.
554
+ */
555
+ async requireCurrentUser(userId, headers) {
556
+ const user = await this.requireUser(headers);
557
+ if (user.id !== userId) {
558
+ throw new BrokrError("[brokr] Access denied.", "FORBIDDEN", "auth");
559
+ }
560
+ }
561
+ // -------------------------------------------------------------------------
562
+ // Legacy alias
563
+ // -------------------------------------------------------------------------
564
+ /** @deprecated Use signInWithProvider() instead. */
565
+ async getOAuthUrl(provider, options) {
566
+ return this.signInWithProvider(provider, options);
567
+ }
568
+ };
569
+ var BrokrSessionsClient = class {
570
+ constructor(appUrl) {
571
+ this._appUrl = appUrl;
572
+ }
573
+ /**
574
+ * List all active sessions for the current user.
575
+ */
576
+ async list(headers) {
577
+ const appUrl = resolveAppUrl(this._appUrl);
578
+ const cookies = headers.get("cookie") ?? "";
579
+ const data = await authApiFetch(appUrl, "/api/auth/list-sessions", { cookies });
580
+ const sessionToken = parseCookieValue(cookies, "better-auth.session_token") ?? parseCookieValue(cookies, "__Secure-better-auth.session_token");
581
+ return data.map((s) => ({
582
+ id: s.id,
583
+ createdAt: new Date(s.createdAt),
584
+ expiresAt: new Date(s.expiresAt),
585
+ userAgent: s.userAgent,
586
+ ipAddress: s.ipAddress,
587
+ isCurrent: s.token === sessionToken
588
+ }));
589
+ }
590
+ /**
591
+ * Revoke a specific session by ID.
592
+ */
593
+ async revoke(sessionId, headers) {
594
+ const appUrl = resolveAppUrl(this._appUrl);
595
+ const cookies = headers.get("cookie") ?? "";
596
+ await authApiFetch(appUrl, "/api/auth/revoke-session", {
597
+ method: "POST",
598
+ body: { id: sessionId },
599
+ cookies
600
+ });
601
+ }
602
+ /**
603
+ * Revoke all sessions except the current one.
604
+ */
605
+ async revokeOthers(headers) {
606
+ const appUrl = resolveAppUrl(this._appUrl);
607
+ const cookies = headers.get("cookie") ?? "";
608
+ await authApiFetch(appUrl, "/api/auth/revoke-other-sessions", {
609
+ method: "POST",
610
+ cookies
611
+ });
612
+ }
613
+ };
24
614
  function parseCookies(cookieHeader) {
25
615
  const cookies = /* @__PURE__ */ new Map();
26
616
  for (const pair of cookieHeader.split(";")) {
@@ -32,6 +622,9 @@ function parseCookies(cookieHeader) {
32
622
  }
33
623
  return cookies;
34
624
  }
625
+ function parseCookieValue(cookieHeader, name) {
626
+ return parseCookies(cookieHeader).get(name);
627
+ }
35
628
  function authMiddleware(options) {
36
629
  const { protectedRoutes = [], publicOnlyRoutes = [] } = options;
37
630
  return async function middleware(request) {
@@ -42,7 +635,7 @@ function authMiddleware(options) {
42
635
  if (!isProtected && !isPublicOnly) return void 0;
43
636
  const cookieHeader = request.headers.get("cookie") ?? "";
44
637
  const cookies = parseCookies(cookieHeader);
45
- const hasSession = cookies.has("better-auth.session_token");
638
+ const hasSession = cookies.has("better-auth.session_token") || cookies.has("__Secure-better-auth.session_token");
46
639
  if (isProtected && !hasSession) {
47
640
  return Response.redirect(new URL("/sign-in", request.url).toString(), 302);
48
641
  }
@@ -52,99 +645,6 @@ function authMiddleware(options) {
52
645
  return void 0;
53
646
  };
54
647
  }
55
- var BrokrAuthClient;
56
- var init_auth = __esm({
57
- "src/auth.ts"() {
58
- init_runtime();
59
- BrokrAuthClient = class {
60
- constructor(token, gatewayUrl, appUrl) {
61
- this._token = token;
62
- this._gatewayUrl = gatewayUrl;
63
- this._appUrl = appUrl ?? (typeof process !== "undefined" ? process.env.BETTER_AUTH_URL : void 0);
64
- }
65
- /**
66
- * Get current user from an incoming request's cookies.
67
- * Calls the local Better Auth API (runs inside your app).
68
- */
69
- async currentUser(request) {
70
- const session = await this.getSession(request);
71
- return session?.user ?? null;
72
- }
73
- /**
74
- * Get the full session (user + metadata) from an incoming request.
75
- * Calls the local Better Auth API.
76
- */
77
- async getSession(request) {
78
- const appUrl = this._appUrl;
79
- if (!appUrl) {
80
- throw new BrokrError(
81
- "[brokr] BETTER_AUTH_URL is not set. Auth may not be provisioned.",
82
- "AUTH_NOT_CONFIGURED",
83
- "auth"
84
- );
85
- }
86
- const cookieHeader = request.headers.get("cookie") ?? "";
87
- if (!cookieHeader) return null;
88
- const res = await fetch(`${appUrl}/api/auth/get-session`, {
89
- method: "GET",
90
- headers: { cookie: cookieHeader }
91
- });
92
- if (!res.ok) return null;
93
- const data = await res.json();
94
- if (!data?.user || !data?.session) return null;
95
- return {
96
- user: {
97
- id: data.user.id,
98
- email: data.user.email,
99
- name: data.user.name ?? null,
100
- avatarUrl: data.user.image ?? null,
101
- emailVerified: data.user.emailVerified ? /* @__PURE__ */ new Date() : null
102
- },
103
- sessionId: data.session.id,
104
- expiresAt: new Date(data.session.expiresAt)
105
- };
106
- }
107
- /**
108
- * Generate an OAuth authorization URL.
109
- */
110
- async getOAuthUrl(provider, options) {
111
- const appUrl = this._appUrl;
112
- if (!appUrl) {
113
- throw new BrokrError("[brokr] BETTER_AUTH_URL is not set.", "AUTH_NOT_CONFIGURED", "auth");
114
- }
115
- const redirectTo = options?.redirectTo ?? "/";
116
- if (!redirectTo.startsWith("/") || redirectTo.startsWith("//")) {
117
- throw new BrokrError("[brokr] redirectTo must be a relative path (start with /)", "INVALID_REDIRECT", "auth");
118
- }
119
- const params = new URLSearchParams({ callbackURL: redirectTo });
120
- return { redirectUrl: `${appUrl}/api/auth/sign-in/social?provider=${provider}&${params}` };
121
- }
122
- /**
123
- * Send a magic link email (requires email capability).
124
- */
125
- async sendMagicLink(email, options) {
126
- const appUrl = this._appUrl;
127
- if (!appUrl) {
128
- throw new BrokrError("[brokr] BETTER_AUTH_URL is not set.", "AUTH_NOT_CONFIGURED", "auth");
129
- }
130
- const res = await fetch(`${appUrl}/api/auth/magic-link/send`, {
131
- method: "POST",
132
- headers: { "Content-Type": "application/json" },
133
- body: JSON.stringify({ email, callbackURL: options?.redirectTo ?? "/" })
134
- });
135
- if (!res.ok) {
136
- const data = await res.json().catch(() => ({}));
137
- throw new BrokrError(
138
- data.message ?? `[brokr] Failed to send magic link (HTTP ${res.status})`,
139
- "AUTH_MAGIC_LINK_FAILED",
140
- "auth"
141
- );
142
- }
143
- }
144
- };
145
- }
146
- });
147
- init_auth();
148
648
  export {
149
649
  BrokrAuthClient,
150
650
  authMiddleware