@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/next.js ADDED
@@ -0,0 +1,2725 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+
33
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/headers.js
34
+ var require_headers = __commonJS({
35
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/headers.js"(exports2, module2) {
36
+ "use strict";
37
+ var __defProp2 = Object.defineProperty;
38
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
39
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
40
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
41
+ var __export2 = (target, all) => {
42
+ for (var name in all)
43
+ __defProp2(target, name, { get: all[name], enumerable: true });
44
+ };
45
+ var __copyProps2 = (to, from, except, desc) => {
46
+ if (from && typeof from === "object" || typeof from === "function") {
47
+ for (let key of __getOwnPropNames2(from))
48
+ if (!__hasOwnProp2.call(to, key) && key !== except)
49
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
50
+ }
51
+ return to;
52
+ };
53
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
54
+ var headers_exports = {};
55
+ __export2(headers_exports, {
56
+ CITY_HEADER_NAME: () => CITY_HEADER_NAME,
57
+ COUNTRY_HEADER_NAME: () => COUNTRY_HEADER_NAME,
58
+ EMOJI_FLAG_UNICODE_STARTING_POSITION: () => EMOJI_FLAG_UNICODE_STARTING_POSITION,
59
+ IP_HEADER_NAME: () => IP_HEADER_NAME,
60
+ LATITUDE_HEADER_NAME: () => LATITUDE_HEADER_NAME,
61
+ LONGITUDE_HEADER_NAME: () => LONGITUDE_HEADER_NAME,
62
+ POSTAL_CODE_HEADER_NAME: () => POSTAL_CODE_HEADER_NAME,
63
+ REGION_HEADER_NAME: () => REGION_HEADER_NAME,
64
+ REQUEST_ID_HEADER_NAME: () => REQUEST_ID_HEADER_NAME,
65
+ geolocation: () => geolocation2,
66
+ ipAddress: () => ipAddress2
67
+ });
68
+ module2.exports = __toCommonJS2(headers_exports);
69
+ var CITY_HEADER_NAME = "x-vercel-ip-city";
70
+ var COUNTRY_HEADER_NAME = "x-vercel-ip-country";
71
+ var IP_HEADER_NAME = "x-real-ip";
72
+ var LATITUDE_HEADER_NAME = "x-vercel-ip-latitude";
73
+ var LONGITUDE_HEADER_NAME = "x-vercel-ip-longitude";
74
+ var REGION_HEADER_NAME = "x-vercel-ip-country-region";
75
+ var POSTAL_CODE_HEADER_NAME = "x-vercel-ip-postal-code";
76
+ var REQUEST_ID_HEADER_NAME = "x-vercel-id";
77
+ var EMOJI_FLAG_UNICODE_STARTING_POSITION = 127397;
78
+ function getHeader(headers, key) {
79
+ return headers.get(key) ?? void 0;
80
+ }
81
+ function getHeaderWithDecode(request, key) {
82
+ const header = getHeader(request.headers, key);
83
+ return header ? decodeURIComponent(header) : void 0;
84
+ }
85
+ function getFlag(countryCode) {
86
+ const regex = new RegExp("^[A-Z]{2}$").test(countryCode);
87
+ if (!countryCode || !regex)
88
+ return void 0;
89
+ return String.fromCodePoint(
90
+ ...countryCode.split("").map((char) => EMOJI_FLAG_UNICODE_STARTING_POSITION + char.charCodeAt(0))
91
+ );
92
+ }
93
+ function ipAddress2(input) {
94
+ const headers = "headers" in input ? input.headers : input;
95
+ return getHeader(headers, IP_HEADER_NAME);
96
+ }
97
+ function getRegionFromRequestId(requestId) {
98
+ if (!requestId) {
99
+ return "dev1";
100
+ }
101
+ return requestId.split(":")[0];
102
+ }
103
+ function geolocation2(request) {
104
+ return {
105
+ // city name may be encoded to support multi-byte characters
106
+ city: getHeaderWithDecode(request, CITY_HEADER_NAME),
107
+ country: getHeader(request.headers, COUNTRY_HEADER_NAME),
108
+ flag: getFlag(getHeader(request.headers, COUNTRY_HEADER_NAME)),
109
+ countryRegion: getHeader(request.headers, REGION_HEADER_NAME),
110
+ region: getRegionFromRequestId(
111
+ getHeader(request.headers, REQUEST_ID_HEADER_NAME)
112
+ ),
113
+ latitude: getHeader(request.headers, LATITUDE_HEADER_NAME),
114
+ longitude: getHeader(request.headers, LONGITUDE_HEADER_NAME),
115
+ postalCode: getHeader(request.headers, POSTAL_CODE_HEADER_NAME)
116
+ };
117
+ }
118
+ }
119
+ });
120
+
121
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/get-env.js
122
+ var require_get_env = __commonJS({
123
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/get-env.js"(exports2, module2) {
124
+ "use strict";
125
+ var __defProp2 = Object.defineProperty;
126
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
127
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
128
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
129
+ var __export2 = (target, all) => {
130
+ for (var name in all)
131
+ __defProp2(target, name, { get: all[name], enumerable: true });
132
+ };
133
+ var __copyProps2 = (to, from, except, desc) => {
134
+ if (from && typeof from === "object" || typeof from === "function") {
135
+ for (let key of __getOwnPropNames2(from))
136
+ if (!__hasOwnProp2.call(to, key) && key !== except)
137
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
138
+ }
139
+ return to;
140
+ };
141
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
142
+ var get_env_exports = {};
143
+ __export2(get_env_exports, {
144
+ getEnv: () => getEnv2
145
+ });
146
+ module2.exports = __toCommonJS2(get_env_exports);
147
+ var getEnv2 = (env = process.env) => ({
148
+ /**
149
+ * An indicator to show that System Environment Variables have been exposed to your project's Deployments.
150
+ * @example "1"
151
+ */
152
+ VERCEL: get(env, "VERCEL"),
153
+ /**
154
+ * An indicator that the code is running in a Continuous Integration environment.
155
+ * @example "1"
156
+ */
157
+ CI: get(env, "CI"),
158
+ /**
159
+ * The Environment that the app is deployed and running on.
160
+ * @example "production"
161
+ */
162
+ VERCEL_ENV: get(env, "VERCEL_ENV"),
163
+ /**
164
+ * The domain name of the generated deployment URL. The value does not include the protocol scheme https://.
165
+ * NOTE: This Variable cannot be used in conjunction with Standard Deployment Protection.
166
+ * @example "*.vercel.app"
167
+ */
168
+ VERCEL_URL: get(env, "VERCEL_URL"),
169
+ /**
170
+ * The domain name of the generated Git branch URL. The value does not include the protocol scheme https://.
171
+ * @example "*-git-*.vercel.app"
172
+ */
173
+ VERCEL_BRANCH_URL: get(env, "VERCEL_BRANCH_URL"),
174
+ /**
175
+ * A production domain name of the project. This is useful to reliably generate links that point to production such as OG-image URLs.
176
+ * The value does not include the protocol scheme https://.
177
+ * @example "myproject.vercel.app"
178
+ */
179
+ VERCEL_PROJECT_PRODUCTION_URL: get(env, "VERCEL_PROJECT_PRODUCTION_URL"),
180
+ /**
181
+ * The ID of the Region where the app is running.
182
+ *
183
+ * Possible values:
184
+ * - arn1 (Stockholm, Sweden)
185
+ * - bom1 (Mumbai, India)
186
+ * - cdg1 (Paris, France)
187
+ * - cle1 (Cleveland, USA)
188
+ * - cpt1 (Cape Town, South Africa)
189
+ * - dub1 (Dublin, Ireland)
190
+ * - fra1 (Frankfurt, Germany)
191
+ * - gru1 (São Paulo, Brazil)
192
+ * - hkg1 (Hong Kong)
193
+ * - hnd1 (Tokyo, Japan)
194
+ * - iad1 (Washington, D.C., USA)
195
+ * - icn1 (Seoul, South Korea)
196
+ * - kix1 (Osaka, Japan)
197
+ * - lhr1 (London, United Kingdom)
198
+ * - pdx1 (Portland, USA)
199
+ * - sfo1 (San Francisco, USA)
200
+ * - sin1 (Singapore)
201
+ * - syd1 (Sydney, Australia)
202
+ * - dev1 (Development Region)
203
+ *
204
+ * @example "iad1"
205
+ */
206
+ VERCEL_REGION: get(env, "VERCEL_REGION"),
207
+ /**
208
+ * The unique identifier for the deployment, which can be used to implement Skew Protection.
209
+ * @example "dpl_7Gw5ZMBpQA8h9GF832KGp7nwbuh3"
210
+ */
211
+ VERCEL_DEPLOYMENT_ID: get(env, "VERCEL_DEPLOYMENT_ID"),
212
+ /**
213
+ * When Skew Protection is enabled in Project Settings, this value is set to 1.
214
+ * @example "1"
215
+ */
216
+ VERCEL_SKEW_PROTECTION_ENABLED: get(env, "VERCEL_SKEW_PROTECTION_ENABLED"),
217
+ /**
218
+ * The Protection Bypass for Automation value, if the secret has been generated in the project's Deployment Protection settings.
219
+ */
220
+ VERCEL_AUTOMATION_BYPASS_SECRET: get(env, "VERCEL_AUTOMATION_BYPASS_SECRET"),
221
+ /**
222
+ * The Git Provider the deployment is triggered from.
223
+ * @example "github"
224
+ */
225
+ VERCEL_GIT_PROVIDER: get(env, "VERCEL_GIT_PROVIDER"),
226
+ /**
227
+ * The origin repository the deployment is triggered from.
228
+ * @example "my-site"
229
+ */
230
+ VERCEL_GIT_REPO_SLUG: get(env, "VERCEL_GIT_REPO_SLUG"),
231
+ /**
232
+ * The account that owns the repository the deployment is triggered from.
233
+ * @example "acme"
234
+ */
235
+ VERCEL_GIT_REPO_OWNER: get(env, "VERCEL_GIT_REPO_OWNER"),
236
+ /**
237
+ * The ID of the repository the deployment is triggered from.
238
+ * @example "117716146"
239
+ */
240
+ VERCEL_GIT_REPO_ID: get(env, "VERCEL_GIT_REPO_ID"),
241
+ /**
242
+ * The git branch of the commit the deployment was triggered by.
243
+ * @example "improve-about-page"
244
+ */
245
+ VERCEL_GIT_COMMIT_REF: get(env, "VERCEL_GIT_COMMIT_REF"),
246
+ /**
247
+ * The git SHA of the commit the deployment was triggered by.
248
+ * @example "fa1eade47b73733d6312d5abfad33ce9e4068081"
249
+ */
250
+ VERCEL_GIT_COMMIT_SHA: get(env, "VERCEL_GIT_COMMIT_SHA"),
251
+ /**
252
+ * The message attached to the commit the deployment was triggered by.
253
+ * @example "Update about page"
254
+ */
255
+ VERCEL_GIT_COMMIT_MESSAGE: get(env, "VERCEL_GIT_COMMIT_MESSAGE"),
256
+ /**
257
+ * The username attached to the author of the commit that the project was deployed by.
258
+ * @example "johndoe"
259
+ */
260
+ VERCEL_GIT_COMMIT_AUTHOR_LOGIN: get(env, "VERCEL_GIT_COMMIT_AUTHOR_LOGIN"),
261
+ /**
262
+ * The name attached to the author of the commit that the project was deployed by.
263
+ * @example "John Doe"
264
+ */
265
+ VERCEL_GIT_COMMIT_AUTHOR_NAME: get(env, "VERCEL_GIT_COMMIT_AUTHOR_NAME"),
266
+ /**
267
+ * The git SHA of the last successful deployment for the project and branch.
268
+ * NOTE: This Variable is only exposed when an Ignored Build Step is provided.
269
+ * @example "fa1eade47b73733d6312d5abfad33ce9e4068080"
270
+ */
271
+ VERCEL_GIT_PREVIOUS_SHA: get(env, "VERCEL_GIT_PREVIOUS_SHA"),
272
+ /**
273
+ * The pull request id the deployment was triggered by. If a deployment is created on a branch before a pull request is made, this value will be an empty string.
274
+ * @example "23"
275
+ */
276
+ VERCEL_GIT_PULL_REQUEST_ID: get(env, "VERCEL_GIT_PULL_REQUEST_ID")
277
+ });
278
+ var get = (env, key) => {
279
+ const value = env[key];
280
+ return value === "" ? void 0 : value;
281
+ };
282
+ }
283
+ });
284
+
285
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/get-context.js
286
+ var require_get_context = __commonJS({
287
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/get-context.js"(exports2, module2) {
288
+ "use strict";
289
+ var __defProp2 = Object.defineProperty;
290
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
291
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
292
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
293
+ var __export2 = (target, all) => {
294
+ for (var name in all)
295
+ __defProp2(target, name, { get: all[name], enumerable: true });
296
+ };
297
+ var __copyProps2 = (to, from, except, desc) => {
298
+ if (from && typeof from === "object" || typeof from === "function") {
299
+ for (let key of __getOwnPropNames2(from))
300
+ if (!__hasOwnProp2.call(to, key) && key !== except)
301
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
302
+ }
303
+ return to;
304
+ };
305
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
306
+ var get_context_exports = {};
307
+ __export2(get_context_exports, {
308
+ SYMBOL_FOR_REQ_CONTEXT: () => SYMBOL_FOR_REQ_CONTEXT,
309
+ getContext: () => getContext
310
+ });
311
+ module2.exports = __toCommonJS2(get_context_exports);
312
+ var SYMBOL_FOR_REQ_CONTEXT = Symbol.for("@vercel/request-context");
313
+ function getContext() {
314
+ const fromSymbol = globalThis;
315
+ return fromSymbol[SYMBOL_FOR_REQ_CONTEXT]?.get?.() ?? {};
316
+ }
317
+ }
318
+ });
319
+
320
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/wait-until.js
321
+ var require_wait_until = __commonJS({
322
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/wait-until.js"(exports2, module2) {
323
+ "use strict";
324
+ var __defProp2 = Object.defineProperty;
325
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
326
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
327
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
328
+ var __export2 = (target, all) => {
329
+ for (var name in all)
330
+ __defProp2(target, name, { get: all[name], enumerable: true });
331
+ };
332
+ var __copyProps2 = (to, from, except, desc) => {
333
+ if (from && typeof from === "object" || typeof from === "function") {
334
+ for (let key of __getOwnPropNames2(from))
335
+ if (!__hasOwnProp2.call(to, key) && key !== except)
336
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
337
+ }
338
+ return to;
339
+ };
340
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
341
+ var wait_until_exports = {};
342
+ __export2(wait_until_exports, {
343
+ waitUntil: () => waitUntil2
344
+ });
345
+ module2.exports = __toCommonJS2(wait_until_exports);
346
+ var import_get_context = require_get_context();
347
+ var waitUntil2 = (promise) => {
348
+ if (promise === null || typeof promise !== "object" || typeof promise.then !== "function") {
349
+ throw new TypeError(
350
+ `waitUntil can only be called with a Promise, got ${typeof promise}`
351
+ );
352
+ }
353
+ return (0, import_get_context.getContext)().waitUntil?.(promise);
354
+ };
355
+ }
356
+ });
357
+
358
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/middleware.js
359
+ var require_middleware = __commonJS({
360
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/middleware.js"(exports2, module2) {
361
+ "use strict";
362
+ var __defProp2 = Object.defineProperty;
363
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
364
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
365
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
366
+ var __export2 = (target, all) => {
367
+ for (var name in all)
368
+ __defProp2(target, name, { get: all[name], enumerable: true });
369
+ };
370
+ var __copyProps2 = (to, from, except, desc) => {
371
+ if (from && typeof from === "object" || typeof from === "function") {
372
+ for (let key of __getOwnPropNames2(from))
373
+ if (!__hasOwnProp2.call(to, key) && key !== except)
374
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
375
+ }
376
+ return to;
377
+ };
378
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
379
+ var middleware_exports = {};
380
+ __export2(middleware_exports, {
381
+ next: () => next2,
382
+ rewrite: () => rewrite2
383
+ });
384
+ module2.exports = __toCommonJS2(middleware_exports);
385
+ function handleMiddlewareField(init, headers) {
386
+ if (init?.request?.headers) {
387
+ if (!(init.request.headers instanceof Headers)) {
388
+ throw new Error("request.headers must be an instance of Headers");
389
+ }
390
+ const keys = [];
391
+ for (const [key, value] of init.request.headers) {
392
+ headers.set("x-middleware-request-" + key, value);
393
+ keys.push(key);
394
+ }
395
+ headers.set("x-middleware-override-headers", keys.join(","));
396
+ }
397
+ }
398
+ function rewrite2(destination, init) {
399
+ const headers = new Headers(init?.headers ?? {});
400
+ headers.set("x-middleware-rewrite", String(destination));
401
+ handleMiddlewareField(init, headers);
402
+ return new Response(null, {
403
+ ...init,
404
+ headers
405
+ });
406
+ }
407
+ function next2(init) {
408
+ const headers = new Headers(init?.headers ?? {});
409
+ headers.set("x-middleware-next", "1");
410
+ handleMiddlewareField(init, headers);
411
+ return new Response(null, {
412
+ ...init,
413
+ headers
414
+ });
415
+ }
416
+ }
417
+ });
418
+
419
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/cache/in-memory-cache.js
420
+ var require_in_memory_cache = __commonJS({
421
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/cache/in-memory-cache.js"(exports2, module2) {
422
+ "use strict";
423
+ var __defProp2 = Object.defineProperty;
424
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
425
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
426
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
427
+ var __export2 = (target, all) => {
428
+ for (var name in all)
429
+ __defProp2(target, name, { get: all[name], enumerable: true });
430
+ };
431
+ var __copyProps2 = (to, from, except, desc) => {
432
+ if (from && typeof from === "object" || typeof from === "function") {
433
+ for (let key of __getOwnPropNames2(from))
434
+ if (!__hasOwnProp2.call(to, key) && key !== except)
435
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
436
+ }
437
+ return to;
438
+ };
439
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
440
+ var in_memory_cache_exports = {};
441
+ __export2(in_memory_cache_exports, {
442
+ InMemoryCache: () => InMemoryCache
443
+ });
444
+ module2.exports = __toCommonJS2(in_memory_cache_exports);
445
+ var InMemoryCache = class {
446
+ constructor() {
447
+ this.cache = {};
448
+ }
449
+ async get(key) {
450
+ const entry = this.cache[key];
451
+ if (entry) {
452
+ if (entry.ttl && entry.lastModified + entry.ttl * 1e3 < Date.now()) {
453
+ await this.delete(key);
454
+ return null;
455
+ }
456
+ return JSON.parse(entry.value);
457
+ }
458
+ return null;
459
+ }
460
+ async set(key, value, options) {
461
+ const serialized = JSON.stringify(value ?? null);
462
+ this.cache[key] = {
463
+ value: serialized,
464
+ lastModified: Date.now(),
465
+ ttl: options?.ttl,
466
+ tags: new Set(options?.tags || [])
467
+ };
468
+ }
469
+ async delete(key) {
470
+ delete this.cache[key];
471
+ }
472
+ async expireTag(tag) {
473
+ const tags = Array.isArray(tag) ? tag : [tag];
474
+ for (const key in this.cache) {
475
+ if (Object.prototype.hasOwnProperty.call(this.cache, key)) {
476
+ const entry = this.cache[key];
477
+ if (tags.some((t) => entry.tags.has(t))) {
478
+ delete this.cache[key];
479
+ }
480
+ }
481
+ }
482
+ }
483
+ };
484
+ }
485
+ });
486
+
487
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/cache/build-client.js
488
+ var require_build_client = __commonJS({
489
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/cache/build-client.js"(exports2, module2) {
490
+ "use strict";
491
+ var __defProp2 = Object.defineProperty;
492
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
493
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
494
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
495
+ var __export2 = (target, all) => {
496
+ for (var name in all)
497
+ __defProp2(target, name, { get: all[name], enumerable: true });
498
+ };
499
+ var __copyProps2 = (to, from, except, desc) => {
500
+ if (from && typeof from === "object" || typeof from === "function") {
501
+ for (let key of __getOwnPropNames2(from))
502
+ if (!__hasOwnProp2.call(to, key) && key !== except)
503
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
504
+ }
505
+ return to;
506
+ };
507
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
508
+ var build_client_exports = {};
509
+ __export2(build_client_exports, {
510
+ BuildCache: () => BuildCache
511
+ });
512
+ module2.exports = __toCommonJS2(build_client_exports);
513
+ var import_index = require_cache();
514
+ var BuildCache = class {
515
+ constructor({
516
+ endpoint,
517
+ headers,
518
+ onError,
519
+ timeout = 500
520
+ }) {
521
+ this.get = async (key) => {
522
+ const controller = new AbortController();
523
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
524
+ try {
525
+ const res = await fetch(`${this.endpoint}${key}`, {
526
+ headers: this.headers,
527
+ method: "GET",
528
+ signal: controller.signal
529
+ });
530
+ if (res.status === 404) {
531
+ clearTimeout(timeoutId);
532
+ return null;
533
+ }
534
+ if (res.status === 200) {
535
+ const cacheState = res.headers.get(
536
+ import_index.HEADERS_VERCEL_CACHE_STATE
537
+ );
538
+ if (cacheState !== import_index.PkgCacheState.Fresh) {
539
+ res.body?.cancel?.();
540
+ clearTimeout(timeoutId);
541
+ return null;
542
+ }
543
+ const result = await res.json();
544
+ clearTimeout(timeoutId);
545
+ return result;
546
+ } else {
547
+ clearTimeout(timeoutId);
548
+ throw new Error(`Failed to get cache: ${res.statusText}`);
549
+ }
550
+ } catch (error) {
551
+ clearTimeout(timeoutId);
552
+ if (error.name === "AbortError") {
553
+ const timeoutError = new Error(
554
+ `Cache request timed out after ${this.timeout}ms`
555
+ );
556
+ timeoutError.stack = error.stack;
557
+ this.onError?.(timeoutError);
558
+ } else {
559
+ this.onError?.(error);
560
+ }
561
+ return null;
562
+ }
563
+ };
564
+ this.set = async (key, value, options) => {
565
+ const controller = new AbortController();
566
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
567
+ try {
568
+ const optionalHeaders = {};
569
+ if (options?.ttl) {
570
+ optionalHeaders[import_index.HEADERS_VERCEL_REVALIDATE] = options.ttl.toString();
571
+ }
572
+ if (options?.tags && options.tags.length > 0) {
573
+ optionalHeaders[import_index.HEADERS_VERCEL_CACHE_TAGS] = options.tags.join(",");
574
+ }
575
+ if (options?.name) {
576
+ optionalHeaders[import_index.HEADERS_VERCEL_CACHE_ITEM_NAME] = options.name;
577
+ }
578
+ const res = await fetch(`${this.endpoint}${key}`, {
579
+ method: "POST",
580
+ headers: {
581
+ ...this.headers,
582
+ ...optionalHeaders
583
+ },
584
+ body: JSON.stringify(value),
585
+ signal: controller.signal
586
+ });
587
+ clearTimeout(timeoutId);
588
+ if (res.status !== 200) {
589
+ throw new Error(`Failed to set cache: ${res.status} ${res.statusText}`);
590
+ }
591
+ } catch (error) {
592
+ clearTimeout(timeoutId);
593
+ if (error.name === "AbortError") {
594
+ const timeoutError = new Error(
595
+ `Cache request timed out after ${this.timeout}ms`
596
+ );
597
+ timeoutError.stack = error.stack;
598
+ this.onError?.(timeoutError);
599
+ } else {
600
+ this.onError?.(error);
601
+ }
602
+ }
603
+ };
604
+ this.delete = async (key) => {
605
+ const controller = new AbortController();
606
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
607
+ try {
608
+ const res = await fetch(`${this.endpoint}${key}`, {
609
+ method: "DELETE",
610
+ headers: this.headers,
611
+ signal: controller.signal
612
+ });
613
+ clearTimeout(timeoutId);
614
+ if (res.status !== 200) {
615
+ throw new Error(`Failed to delete cache: ${res.statusText}`);
616
+ }
617
+ } catch (error) {
618
+ clearTimeout(timeoutId);
619
+ if (error.name === "AbortError") {
620
+ const timeoutError = new Error(
621
+ `Cache request timed out after ${this.timeout}ms`
622
+ );
623
+ timeoutError.stack = error.stack;
624
+ this.onError?.(timeoutError);
625
+ } else {
626
+ this.onError?.(error);
627
+ }
628
+ }
629
+ };
630
+ this.expireTag = async (tag) => {
631
+ const controller = new AbortController();
632
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
633
+ try {
634
+ if (Array.isArray(tag)) {
635
+ tag = tag.join(",");
636
+ }
637
+ const res = await fetch(`${this.endpoint}revalidate?tags=${tag}`, {
638
+ method: "POST",
639
+ headers: this.headers,
640
+ signal: controller.signal
641
+ });
642
+ clearTimeout(timeoutId);
643
+ if (res.status !== 200) {
644
+ throw new Error(`Failed to revalidate tag: ${res.statusText}`);
645
+ }
646
+ } catch (error) {
647
+ clearTimeout(timeoutId);
648
+ if (error.name === "AbortError") {
649
+ const timeoutError = new Error(
650
+ `Cache request timed out after ${this.timeout}ms`
651
+ );
652
+ timeoutError.stack = error.stack;
653
+ this.onError?.(timeoutError);
654
+ } else {
655
+ this.onError?.(error);
656
+ }
657
+ }
658
+ };
659
+ this.endpoint = endpoint;
660
+ this.headers = headers;
661
+ this.onError = onError;
662
+ this.timeout = timeout;
663
+ }
664
+ };
665
+ }
666
+ });
667
+
668
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/cache/index.js
669
+ var require_cache = __commonJS({
670
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/cache/index.js"(exports2, module2) {
671
+ "use strict";
672
+ var __defProp2 = Object.defineProperty;
673
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
674
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
675
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
676
+ var __export2 = (target, all) => {
677
+ for (var name in all)
678
+ __defProp2(target, name, { get: all[name], enumerable: true });
679
+ };
680
+ var __copyProps2 = (to, from, except, desc) => {
681
+ if (from && typeof from === "object" || typeof from === "function") {
682
+ for (let key of __getOwnPropNames2(from))
683
+ if (!__hasOwnProp2.call(to, key) && key !== except)
684
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
685
+ }
686
+ return to;
687
+ };
688
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
689
+ var cache_exports = {};
690
+ __export2(cache_exports, {
691
+ HEADERS_VERCEL_CACHE_ITEM_NAME: () => HEADERS_VERCEL_CACHE_ITEM_NAME,
692
+ HEADERS_VERCEL_CACHE_STATE: () => HEADERS_VERCEL_CACHE_STATE,
693
+ HEADERS_VERCEL_CACHE_TAGS: () => HEADERS_VERCEL_CACHE_TAGS,
694
+ HEADERS_VERCEL_REVALIDATE: () => HEADERS_VERCEL_REVALIDATE,
695
+ PkgCacheState: () => PkgCacheState,
696
+ getCache: () => getCache2
697
+ });
698
+ module2.exports = __toCommonJS2(cache_exports);
699
+ var import_get_context = require_get_context();
700
+ var import_in_memory_cache = require_in_memory_cache();
701
+ var import_build_client = require_build_client();
702
+ var defaultKeyHashFunction = (key) => {
703
+ let hash = 5381;
704
+ for (let i = 0; i < key.length; i++) {
705
+ hash = hash * 33 ^ key.charCodeAt(i);
706
+ }
707
+ return (hash >>> 0).toString(16);
708
+ };
709
+ var defaultNamespaceSeparator = "$";
710
+ var inMemoryCacheInstance = null;
711
+ var buildCacheInstance = null;
712
+ var getCache2 = (cacheOptions) => {
713
+ const resolveCache = () => {
714
+ let cache2;
715
+ if ((0, import_get_context.getContext)().cache) {
716
+ cache2 = (0, import_get_context.getContext)().cache;
717
+ } else {
718
+ cache2 = getCacheImplementation(
719
+ process.env.SUSPENSE_CACHE_DEBUG === "true"
720
+ );
721
+ }
722
+ return cache2;
723
+ };
724
+ return wrapWithKeyTransformation(
725
+ resolveCache,
726
+ createKeyTransformer(cacheOptions)
727
+ );
728
+ };
729
+ function createKeyTransformer(cacheOptions) {
730
+ const hashFunction = cacheOptions?.keyHashFunction || defaultKeyHashFunction;
731
+ return (key) => {
732
+ if (!cacheOptions?.namespace)
733
+ return hashFunction(key);
734
+ const separator = cacheOptions.namespaceSeparator || defaultNamespaceSeparator;
735
+ return `${cacheOptions.namespace}${separator}${hashFunction(key)}`;
736
+ };
737
+ }
738
+ function wrapWithKeyTransformation(resolveCache, makeKey) {
739
+ return {
740
+ get: (key) => {
741
+ return resolveCache().get(makeKey(key));
742
+ },
743
+ set: (key, value, options) => {
744
+ return resolveCache().set(makeKey(key), value, options);
745
+ },
746
+ delete: (key) => {
747
+ return resolveCache().delete(makeKey(key));
748
+ },
749
+ expireTag: (tag) => {
750
+ return resolveCache().expireTag(tag);
751
+ }
752
+ };
753
+ }
754
+ var warnedCacheUnavailable = false;
755
+ function getCacheImplementation(debug) {
756
+ if (!inMemoryCacheInstance) {
757
+ inMemoryCacheInstance = new import_in_memory_cache.InMemoryCache();
758
+ }
759
+ if (process.env.RUNTIME_CACHE_DISABLE_BUILD_CACHE === "true") {
760
+ debug && console.log("Using InMemoryCache as build cache is disabled");
761
+ return inMemoryCacheInstance;
762
+ }
763
+ const { RUNTIME_CACHE_ENDPOINT, RUNTIME_CACHE_HEADERS } = process.env;
764
+ if (debug) {
765
+ console.log("Runtime cache environment variables:", {
766
+ RUNTIME_CACHE_ENDPOINT,
767
+ RUNTIME_CACHE_HEADERS
768
+ });
769
+ }
770
+ if (!RUNTIME_CACHE_ENDPOINT || !RUNTIME_CACHE_HEADERS) {
771
+ if (!warnedCacheUnavailable) {
772
+ console.warn(
773
+ "Runtime Cache unavailable in this environment. Falling back to in-memory cache."
774
+ );
775
+ warnedCacheUnavailable = true;
776
+ }
777
+ return inMemoryCacheInstance;
778
+ }
779
+ if (!buildCacheInstance) {
780
+ let parsedHeaders = {};
781
+ try {
782
+ parsedHeaders = JSON.parse(RUNTIME_CACHE_HEADERS);
783
+ } catch (e) {
784
+ console.error("Failed to parse RUNTIME_CACHE_HEADERS:", e);
785
+ return inMemoryCacheInstance;
786
+ }
787
+ let timeout = 500;
788
+ if (process.env.RUNTIME_CACHE_TIMEOUT) {
789
+ const parsed = parseInt(process.env.RUNTIME_CACHE_TIMEOUT, 10);
790
+ if (!isNaN(parsed) && parsed > 0) {
791
+ timeout = parsed;
792
+ } else {
793
+ console.warn(
794
+ `Invalid RUNTIME_CACHE_TIMEOUT value: "${process.env.RUNTIME_CACHE_TIMEOUT}". Using default: ${timeout}ms`
795
+ );
796
+ }
797
+ }
798
+ buildCacheInstance = new import_build_client.BuildCache({
799
+ endpoint: RUNTIME_CACHE_ENDPOINT,
800
+ headers: parsedHeaders,
801
+ onError: (error) => console.error(error),
802
+ timeout
803
+ });
804
+ }
805
+ return buildCacheInstance;
806
+ }
807
+ var PkgCacheState = /* @__PURE__ */ ((PkgCacheState2) => {
808
+ PkgCacheState2["Fresh"] = "fresh";
809
+ PkgCacheState2["Stale"] = "stale";
810
+ PkgCacheState2["Expired"] = "expired";
811
+ PkgCacheState2["NotFound"] = "notFound";
812
+ PkgCacheState2["Error"] = "error";
813
+ return PkgCacheState2;
814
+ })(PkgCacheState || {});
815
+ var HEADERS_VERCEL_CACHE_STATE = "x-vercel-cache-state";
816
+ var HEADERS_VERCEL_REVALIDATE = "x-vercel-revalidate";
817
+ var HEADERS_VERCEL_CACHE_TAGS = "x-vercel-cache-tags";
818
+ var HEADERS_VERCEL_CACHE_ITEM_NAME = "x-vercel-cache-item-name";
819
+ }
820
+ });
821
+
822
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/db-connections/index.js
823
+ var require_db_connections = __commonJS({
824
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/db-connections/index.js"(exports2, module2) {
825
+ "use strict";
826
+ var __defProp2 = Object.defineProperty;
827
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
828
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
829
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
830
+ var __export2 = (target, all) => {
831
+ for (var name in all)
832
+ __defProp2(target, name, { get: all[name], enumerable: true });
833
+ };
834
+ var __copyProps2 = (to, from, except, desc) => {
835
+ if (from && typeof from === "object" || typeof from === "function") {
836
+ for (let key of __getOwnPropNames2(from))
837
+ if (!__hasOwnProp2.call(to, key) && key !== except)
838
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
839
+ }
840
+ return to;
841
+ };
842
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
843
+ var db_connections_exports = {};
844
+ __export2(db_connections_exports, {
845
+ attachDatabasePool: () => attachDatabasePool2,
846
+ experimental_attachDatabasePool: () => experimental_attachDatabasePool2
847
+ });
848
+ module2.exports = __toCommonJS2(db_connections_exports);
849
+ var import_get_context = require_get_context();
850
+ var DEBUG = !!process.env.DEBUG;
851
+ function getIdleTimeout(dbPool) {
852
+ if ("options" in dbPool && dbPool.options) {
853
+ if ("idleTimeoutMillis" in dbPool.options) {
854
+ return typeof dbPool.options.idleTimeoutMillis === "number" ? dbPool.options.idleTimeoutMillis : 1e4;
855
+ }
856
+ if ("maxIdleTimeMS" in dbPool.options) {
857
+ return typeof dbPool.options.maxIdleTimeMS === "number" ? dbPool.options.maxIdleTimeMS : 0;
858
+ }
859
+ if ("status" in dbPool) {
860
+ return 5e3;
861
+ }
862
+ if ("connect" in dbPool && "execute" in dbPool) {
863
+ return 3e4;
864
+ }
865
+ }
866
+ if ("config" in dbPool && dbPool.config) {
867
+ if ("connectionConfig" in dbPool.config && dbPool.config.connectionConfig) {
868
+ return dbPool.config.connectionConfig.idleTimeout || 6e4;
869
+ }
870
+ if ("idleTimeout" in dbPool.config) {
871
+ return typeof dbPool.config.idleTimeout === "number" ? dbPool.config.idleTimeout : 6e4;
872
+ }
873
+ }
874
+ if ("poolTimeout" in dbPool) {
875
+ return typeof dbPool.poolTimeout === "number" ? dbPool.poolTimeout : 6e4;
876
+ }
877
+ if ("idleTimeout" in dbPool) {
878
+ return typeof dbPool.idleTimeout === "number" ? dbPool.idleTimeout : 0;
879
+ }
880
+ return 1e4;
881
+ }
882
+ var idleTimeout = null;
883
+ var idleTimeoutResolve = () => {
884
+ };
885
+ var bootTime = Date.now();
886
+ var maximumDuration = 15 * 60 * 1e3 - 1e3;
887
+ function waitUntilIdleTimeout(dbPool) {
888
+ if (!process.env.VERCEL_URL || // This is not set during builds where we don't need to wait for idle connections using the mechanism
889
+ !process.env.VERCEL_REGION) {
890
+ return;
891
+ }
892
+ if (idleTimeout) {
893
+ clearTimeout(idleTimeout);
894
+ idleTimeoutResolve();
895
+ }
896
+ const promise = new Promise((resolve) => {
897
+ idleTimeoutResolve = resolve;
898
+ });
899
+ const waitTime = Math.min(
900
+ getIdleTimeout(dbPool) + 100,
901
+ Math.max(100, maximumDuration - (Date.now() - bootTime))
902
+ );
903
+ idleTimeout = setTimeout(() => {
904
+ idleTimeoutResolve?.();
905
+ if (DEBUG) {
906
+ console.log("Database pool idle timeout reached. Releasing connections.");
907
+ }
908
+ }, waitTime);
909
+ const requestContext = (0, import_get_context.getContext)();
910
+ if (requestContext?.waitUntil) {
911
+ requestContext.waitUntil(promise);
912
+ } else {
913
+ console.warn("Pool release event triggered outside of request scope.");
914
+ }
915
+ }
916
+ function attachDatabasePool2(dbPool) {
917
+ if (idleTimeout) {
918
+ idleTimeoutResolve?.();
919
+ clearTimeout(idleTimeout);
920
+ }
921
+ if ("on" in dbPool && dbPool.on && "options" in dbPool && "idleTimeoutMillis" in dbPool.options) {
922
+ const pgPool = dbPool;
923
+ pgPool.on("release", () => {
924
+ if (DEBUG) {
925
+ console.log("Client released from pool");
926
+ }
927
+ waitUntilIdleTimeout(dbPool);
928
+ });
929
+ return;
930
+ } else if ("on" in dbPool && dbPool.on && "config" in dbPool && dbPool.config && "connectionConfig" in dbPool.config) {
931
+ const mysqlPool = dbPool;
932
+ mysqlPool.on("release", () => {
933
+ if (DEBUG) {
934
+ console.log("MySQL client released from pool");
935
+ }
936
+ waitUntilIdleTimeout(dbPool);
937
+ });
938
+ return;
939
+ } else if ("on" in dbPool && dbPool.on && "config" in dbPool && dbPool.config && "idleTimeout" in dbPool.config) {
940
+ const mysql2Pool = dbPool;
941
+ mysql2Pool.on("release", () => {
942
+ if (DEBUG) {
943
+ console.log("MySQL2/MariaDB client released from pool");
944
+ }
945
+ waitUntilIdleTimeout(dbPool);
946
+ });
947
+ return;
948
+ }
949
+ if ("on" in dbPool && dbPool.on && "options" in dbPool && dbPool.options && "maxIdleTimeMS" in dbPool.options) {
950
+ const mongoPool = dbPool;
951
+ mongoPool.on("connectionCheckedOut", () => {
952
+ if (DEBUG) {
953
+ console.log("MongoDB connection checked out");
954
+ }
955
+ waitUntilIdleTimeout(dbPool);
956
+ });
957
+ return;
958
+ }
959
+ if ("on" in dbPool && dbPool.on && "options" in dbPool && dbPool.options && "socket" in dbPool.options) {
960
+ const redisPool = dbPool;
961
+ redisPool.on("end", () => {
962
+ if (DEBUG) {
963
+ console.log("Redis connection ended");
964
+ }
965
+ waitUntilIdleTimeout(dbPool);
966
+ });
967
+ return;
968
+ }
969
+ throw new Error("Unsupported database pool type");
970
+ }
971
+ var experimental_attachDatabasePool2 = attachDatabasePool2;
972
+ }
973
+ });
974
+
975
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/purge/index.js
976
+ var require_purge = __commonJS({
977
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/purge/index.js"(exports2, module2) {
978
+ "use strict";
979
+ var __defProp2 = Object.defineProperty;
980
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
981
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
982
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
983
+ var __export2 = (target, all) => {
984
+ for (var name in all)
985
+ __defProp2(target, name, { get: all[name], enumerable: true });
986
+ };
987
+ var __copyProps2 = (to, from, except, desc) => {
988
+ if (from && typeof from === "object" || typeof from === "function") {
989
+ for (let key of __getOwnPropNames2(from))
990
+ if (!__hasOwnProp2.call(to, key) && key !== except)
991
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
992
+ }
993
+ return to;
994
+ };
995
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
996
+ var purge_exports = {};
997
+ __export2(purge_exports, {
998
+ dangerouslyDeleteBySrcImage: () => dangerouslyDeleteBySrcImage2,
999
+ dangerouslyDeleteByTag: () => dangerouslyDeleteByTag2,
1000
+ invalidateBySrcImage: () => invalidateBySrcImage2,
1001
+ invalidateByTag: () => invalidateByTag2
1002
+ });
1003
+ module2.exports = __toCommonJS2(purge_exports);
1004
+ var import_get_context = require_get_context();
1005
+ var invalidateByTag2 = (tag) => {
1006
+ const api = (0, import_get_context.getContext)().purge;
1007
+ if (api) {
1008
+ return api.invalidateByTag(tag);
1009
+ }
1010
+ return Promise.resolve();
1011
+ };
1012
+ var dangerouslyDeleteByTag2 = (tag, options) => {
1013
+ const api = (0, import_get_context.getContext)().purge;
1014
+ if (api) {
1015
+ return api.dangerouslyDeleteByTag(tag, options);
1016
+ }
1017
+ return Promise.resolve();
1018
+ };
1019
+ var invalidateBySrcImage2 = (src) => {
1020
+ const api = (0, import_get_context.getContext)().purge;
1021
+ return api ? api.invalidateBySrcImage(src) : Promise.resolve();
1022
+ };
1023
+ var dangerouslyDeleteBySrcImage2 = (src, options) => {
1024
+ const api = (0, import_get_context.getContext)().purge;
1025
+ return api ? api.dangerouslyDeleteBySrcImage(src, options) : Promise.resolve();
1026
+ };
1027
+ }
1028
+ });
1029
+
1030
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/addcachetag/index.js
1031
+ var require_addcachetag = __commonJS({
1032
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/addcachetag/index.js"(exports2, module2) {
1033
+ "use strict";
1034
+ var __defProp2 = Object.defineProperty;
1035
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
1036
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
1037
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
1038
+ var __export2 = (target, all) => {
1039
+ for (var name in all)
1040
+ __defProp2(target, name, { get: all[name], enumerable: true });
1041
+ };
1042
+ var __copyProps2 = (to, from, except, desc) => {
1043
+ if (from && typeof from === "object" || typeof from === "function") {
1044
+ for (let key of __getOwnPropNames2(from))
1045
+ if (!__hasOwnProp2.call(to, key) && key !== except)
1046
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
1047
+ }
1048
+ return to;
1049
+ };
1050
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
1051
+ var addcachetag_exports = {};
1052
+ __export2(addcachetag_exports, {
1053
+ addCacheTag: () => addCacheTag2
1054
+ });
1055
+ module2.exports = __toCommonJS2(addcachetag_exports);
1056
+ var import_get_context = require_get_context();
1057
+ var addCacheTag2 = (tag) => {
1058
+ const addCacheTag22 = (0, import_get_context.getContext)().addCacheTag;
1059
+ if (addCacheTag22) {
1060
+ return addCacheTag22(tag);
1061
+ }
1062
+ return Promise.resolve();
1063
+ };
1064
+ }
1065
+ });
1066
+
1067
+ // ../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/index.js
1068
+ var require_functions = __commonJS({
1069
+ "../../node_modules/.pnpm/@vercel+functions@3.4.3_@aws-sdk+credential-provider-web-identity@3.972.20/node_modules/@vercel/functions/index.js"(exports2, module2) {
1070
+ "use strict";
1071
+ var __defProp2 = Object.defineProperty;
1072
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
1073
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
1074
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
1075
+ var __export2 = (target, all) => {
1076
+ for (var name in all)
1077
+ __defProp2(target, name, { get: all[name], enumerable: true });
1078
+ };
1079
+ var __copyProps2 = (to, from, except, desc) => {
1080
+ if (from && typeof from === "object" || typeof from === "function") {
1081
+ for (let key of __getOwnPropNames2(from))
1082
+ if (!__hasOwnProp2.call(to, key) && key !== except)
1083
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
1084
+ }
1085
+ return to;
1086
+ };
1087
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
1088
+ var src_exports = {};
1089
+ __export2(src_exports, {
1090
+ addCacheTag: () => import_addcachetag.addCacheTag,
1091
+ attachDatabasePool: () => import_db_connections.attachDatabasePool,
1092
+ dangerouslyDeleteBySrcImage: () => import_purge.dangerouslyDeleteBySrcImage,
1093
+ dangerouslyDeleteByTag: () => import_purge.dangerouslyDeleteByTag,
1094
+ experimental_attachDatabasePool: () => import_db_connections.experimental_attachDatabasePool,
1095
+ geolocation: () => import_headers.geolocation,
1096
+ getCache: () => import_cache.getCache,
1097
+ getEnv: () => import_get_env.getEnv,
1098
+ invalidateBySrcImage: () => import_purge.invalidateBySrcImage,
1099
+ invalidateByTag: () => import_purge.invalidateByTag,
1100
+ ipAddress: () => import_headers.ipAddress,
1101
+ next: () => import_middleware.next,
1102
+ rewrite: () => import_middleware.rewrite,
1103
+ waitUntil: () => import_wait_until.waitUntil
1104
+ });
1105
+ module2.exports = __toCommonJS2(src_exports);
1106
+ var import_headers = require_headers();
1107
+ var import_get_env = require_get_env();
1108
+ var import_wait_until = require_wait_until();
1109
+ var import_middleware = require_middleware();
1110
+ var import_cache = require_cache();
1111
+ var import_db_connections = require_db_connections();
1112
+ var import_purge = require_purge();
1113
+ var import_addcachetag = require_addcachetag();
1114
+ }
1115
+ });
1116
+
1117
+ // src/next/index.ts
1118
+ var index_exports = {};
1119
+ __export(index_exports, {
1120
+ createBrokrHandlers: () => createBrokrHandlers,
1121
+ ensureNotificationTable: () => ensureNotificationTable,
1122
+ listPersistedNotifications: () => listPersistedNotifications,
1123
+ markNotificationRead: () => markNotificationRead,
1124
+ persistNotification: () => persistNotification,
1125
+ protectApi: () => protectApi,
1126
+ protectPage: () => protectPage,
1127
+ withUser: () => withUser
1128
+ });
1129
+ module.exports = __toCommonJS(index_exports);
1130
+
1131
+ // src/next/auth.ts
1132
+ var import_react = require("react");
1133
+
1134
+ // src/fix-registry.ts
1135
+ var FIX_REGISTRY = {
1136
+ AUTH_TOKEN_INVALID: [
1137
+ "\u2192 Run `brokr env pull --stack <name>` to refresh your token",
1138
+ "\u2192 Or run `brokr link account` to re-authenticate"
1139
+ ].join("\n"),
1140
+ AUTH_SESSION_EXPIRED: [
1141
+ "\u2192 Run `brokr link account` to re-authenticate"
1142
+ ].join("\n"),
1143
+ BROKR_TOKEN_MISSING: [
1144
+ "\u2192 Run `brokr env pull --stack <name>` to sync your environment",
1145
+ "\u2192 Or add BROKR_TOKEN to your .env.local manually"
1146
+ ].join("\n"),
1147
+ DATABASE_PROVISION_FAILED: [
1148
+ "\u2192 Run `brokr status <stack>` to check current state",
1149
+ "\u2192 Run `brokr retry <stack>` to re-trigger provisioning"
1150
+ ].join("\n"),
1151
+ DATABASE_QUOTA_REACHED: [
1152
+ "\u2192 Upgrade your plan or delete unused databases",
1153
+ "\u2192 Check usage at brokr.sh/billing"
1154
+ ].join("\n"),
1155
+ DATABASE_HEALTH_TIMEOUT: [
1156
+ "\u2192 Run `brokr status <stack>` to check database state",
1157
+ "\u2192 If persistent, check provider status page"
1158
+ ].join("\n"),
1159
+ DEPLOYMENT_FAILED: [
1160
+ "\u2192 Run `brokr logs --stack <name>` to see build logs",
1161
+ "\u2192 Fix the build error and run `brokr deploy`"
1162
+ ].join("\n"),
1163
+ DEPLOYMENT_RATE_LIMITED: [
1164
+ "\u2192 Wait a minute and retry",
1165
+ "\u2192 Vercel rate limits apply per project"
1166
+ ].join("\n"),
1167
+ REPO_ALREADY_EXISTS: [
1168
+ "\u2192 Use a different stack name",
1169
+ "\u2192 Or run `brokr status <stack>` to check the existing stack"
1170
+ ].join("\n"),
1171
+ REPO_CREATE_FAILED: [
1172
+ "\u2192 Check your GitHub connection: `brokr link account`",
1173
+ "\u2192 Ensure the Brokr GitHub App is installed"
1174
+ ].join("\n"),
1175
+ EMAIL_DOMAIN_FAILED: [
1176
+ "\u2192 Check DNS records are propagated",
1177
+ "\u2192 Run `brokr status <stack>` for details"
1178
+ ].join("\n"),
1179
+ DNS_RECORD_FAILED: [
1180
+ "\u2192 Check Cloudflare dashboard for zone status",
1181
+ "\u2192 Retry with `brokr retry <stack>`"
1182
+ ].join("\n"),
1183
+ INSUFFICIENT_CREDITS: [
1184
+ "\u2192 Top up credits at brokr.sh/billing",
1185
+ "\u2192 Or run `brokr billing topup`"
1186
+ ].join("\n"),
1187
+ AI_BUDGET_EXCEEDED: [
1188
+ "\u2192 Top up credits at brokr.sh/billing",
1189
+ "\u2192 Or run `brokr billing topup`"
1190
+ ].join("\n"),
1191
+ AI_PROVIDER_UNAVAILABLE: [
1192
+ "\u2192 The AI provider is temporarily down",
1193
+ "\u2192 Retry in a few seconds \u2014 this is usually transient"
1194
+ ].join("\n"),
1195
+ AI_MODEL_NOT_FOUND: [
1196
+ "\u2192 Check the model name in your configuration",
1197
+ "\u2192 See available models at brokr.sh/docs/ai-models"
1198
+ ].join("\n"),
1199
+ ENV_VAR_MISSING: [
1200
+ "\u2192 Run `brokr env pull --stack <name>` to sync environment",
1201
+ "\u2192 Check required vars in your template README"
1202
+ ].join("\n"),
1203
+ STACK_LIMIT_REACHED: [
1204
+ "\u2192 Delete unused stacks with `brokr delete <stack>`",
1205
+ "\u2192 Or upgrade your plan at brokr.sh/billing"
1206
+ ].join("\n"),
1207
+ STACK_NOT_FOUND: [
1208
+ "\u2192 Check the stack name: `brokr list`",
1209
+ "\u2192 Create a new stack: `brokr create --name <name>`"
1210
+ ].join("\n"),
1211
+ RATE_LIMITED: [
1212
+ "\u2192 Wait a moment and retry",
1213
+ "\u2192 If persistent, check brokr.sh/status"
1214
+ ].join("\n"),
1215
+ GATEWAY_AUTH_FAILED: [
1216
+ "\u2192 Your BROKR_TOKEN may be expired",
1217
+ "\u2192 Run `brokr env pull --stack <name>` to refresh"
1218
+ ].join("\n"),
1219
+ BROKR_TOKEN_INVALID: [
1220
+ "\u2192 Your BROKR_TOKEN has expired or been revoked",
1221
+ "\u2192 Run `brokr env pull --stack <name>` to get a fresh token"
1222
+ ].join("\n"),
1223
+ AI_STREAM_ERROR: [
1224
+ "\u2192 The AI stream was interrupted",
1225
+ "\u2192 Retry the request \u2014 this is usually transient"
1226
+ ].join("\n"),
1227
+ EMAIL_SEND_FAILED: [
1228
+ "\u2192 Email delivery failed",
1229
+ "\u2192 Check that your domain DNS is verified: `brokr status <stack>`"
1230
+ ].join("\n"),
1231
+ EMAIL_NOT_CONFIGURED: [
1232
+ "\u2192 Email is not set up for this stack",
1233
+ "\u2192 Add email capability: `brokr add email --stack <name>`"
1234
+ ].join("\n"),
1235
+ EMAIL_INVALID_FROM: [
1236
+ "\u2192 The from address must match your verified domain",
1237
+ "\u2192 Check your domain: `brokr status <stack>`"
1238
+ ].join("\n"),
1239
+ STORAGE_UPLOAD_FAILED: [
1240
+ "\u2192 File upload failed",
1241
+ "\u2192 Check file size limits and retry"
1242
+ ].join("\n"),
1243
+ STORAGE_NOT_FOUND: [
1244
+ "\u2192 The requested file does not exist",
1245
+ "\u2192 Check the key and try again"
1246
+ ].join("\n"),
1247
+ PAYMENTS_NOT_CONFIGURED: [
1248
+ "\u2192 Payments are not set up for this stack",
1249
+ "\u2192 Run `brokr payments sync` to configure Stripe"
1250
+ ].join("\n"),
1251
+ PAYMENTS_FAILED: [
1252
+ "\u2192 Payment processing failed",
1253
+ "\u2192 Check your Stripe dashboard for details"
1254
+ ].join("\n"),
1255
+ GATEWAY_INTERNAL: [
1256
+ "\u2192 The Brokr gateway encountered an internal error",
1257
+ "\u2192 Check brokr.sh/status for service health"
1258
+ ].join("\n"),
1259
+ UPSTREAM_ERROR: [
1260
+ "\u2192 An upstream service is temporarily unavailable",
1261
+ "\u2192 Retry in a few seconds \u2014 this is usually transient"
1262
+ ].join("\n"),
1263
+ NETWORK_ERROR: [
1264
+ "\u2192 Could not reach the Brokr gateway",
1265
+ "\u2192 Check your internet connection",
1266
+ "\u2192 Check brokr.sh/status for service health"
1267
+ ].join("\n"),
1268
+ TIMEOUT: [
1269
+ "\u2192 Request timed out",
1270
+ "\u2192 Retry \u2014 if persistent, check brokr.sh/status"
1271
+ ].join("\n")
1272
+ };
1273
+
1274
+ // src/errors.ts
1275
+ var BrokrError = class extends Error {
1276
+ constructor(message, code, capability, retryable = false, errorCode, requestId, hint) {
1277
+ super(message);
1278
+ this.code = code;
1279
+ this.capability = capability;
1280
+ this.retryable = retryable;
1281
+ this.errorCode = errorCode;
1282
+ this.requestId = requestId;
1283
+ this.hint = hint;
1284
+ this.name = "BrokrError";
1285
+ }
1286
+ /** Multi-line terminal fix block — looked up from error code. */
1287
+ get fix() {
1288
+ if (!this.errorCode) return void 0;
1289
+ return FIX_REGISTRY[this.errorCode];
1290
+ }
1291
+ /** Documentation URL for this error code. */
1292
+ get docsUrl() {
1293
+ if (!this.errorCode) return void 0;
1294
+ return `https://brokr.sh/errors/${this.errorCode.toLowerCase().replace(/_/g, "-")}`;
1295
+ }
1296
+ /** Safe message for end users — zero technical language. */
1297
+ toUserMessage() {
1298
+ switch (this.code) {
1299
+ case "RATE_LIMITED":
1300
+ return "Please wait a moment and try again.";
1301
+ case "TIMEOUT":
1302
+ return "The request took too long. Please try again.";
1303
+ case "NETWORK_ERROR":
1304
+ return "Connection issue. Check your internet and try again.";
1305
+ case "BROKR_TOKEN_MISSING":
1306
+ return "App is not connected to Brokr. Contact the developer.";
1307
+ case "BROKR_TOKEN_INVALID":
1308
+ return "Session expired. Please refresh.";
1309
+ case "AI_BUDGET_EXCEEDED":
1310
+ return "AI usage limit reached. The developer needs to add credits.";
1311
+ case "AI_PROVIDER_UNAVAILABLE":
1312
+ return "AI service is temporarily down. Please retry shortly.";
1313
+ case "AI_PROVIDER_RATE_LIMITED":
1314
+ return "Too many AI requests. Please wait a moment.";
1315
+ case "INSUFFICIENT_CREDITS":
1316
+ return "Not enough credits. Please top up your balance.";
1317
+ case "STORAGE_UPLOAD_FAILED":
1318
+ return "File upload failed. Please try again.";
1319
+ case "STORAGE_NOT_FOUND":
1320
+ return "File not found.";
1321
+ case "EMAIL_SEND_FAILED":
1322
+ return "Email could not be sent. Please try again.";
1323
+ case "EMAIL_NOT_CONFIGURED":
1324
+ return "Email is not set up for this app.";
1325
+ case "PAYMENTS_NOT_CONFIGURED":
1326
+ return "Payments are not configured. Contact the developer.";
1327
+ case "PAYMENTS_FAILED":
1328
+ return "Payment processing failed. Please try again.";
1329
+ case "NOT_FOUND":
1330
+ return "The requested resource was not found.";
1331
+ case "VALIDATION_ERROR":
1332
+ return "Invalid input. Please check your data and try again.";
1333
+ default:
1334
+ return "Something went wrong. We're looking into it.";
1335
+ }
1336
+ }
1337
+ toString() {
1338
+ return `${this.name} [${this.errorCode ?? this.code}]: ${this.message}`;
1339
+ }
1340
+ toJSON() {
1341
+ return {
1342
+ name: this.name,
1343
+ code: this.code,
1344
+ errorCode: this.errorCode,
1345
+ message: this.message,
1346
+ capability: this.capability,
1347
+ retryable: this.retryable,
1348
+ requestId: this.requestId,
1349
+ hint: this.hint,
1350
+ component: this.component
1351
+ };
1352
+ }
1353
+ };
1354
+ var BrokrAuthError = class extends BrokrError {
1355
+ constructor(message, code) {
1356
+ super(message, code, "auth", false);
1357
+ this.name = "BrokrAuthError";
1358
+ }
1359
+ };
1360
+ var BrokrRateLimitError = class extends BrokrError {
1361
+ constructor(message, retryAfter, capability) {
1362
+ super(message, "RATE_LIMITED", capability, true);
1363
+ this.retryAfter = retryAfter;
1364
+ this.name = "BrokrRateLimitError";
1365
+ }
1366
+ };
1367
+ var BrokrNetworkError = class extends BrokrError {
1368
+ constructor(message, capability) {
1369
+ super(message, "NETWORK_ERROR", capability, true);
1370
+ this.name = "BrokrNetworkError";
1371
+ }
1372
+ };
1373
+ var BrokrTimeoutError = class extends BrokrError {
1374
+ constructor(message, capability) {
1375
+ super(message, "TIMEOUT", capability, true);
1376
+ this.name = "BrokrTimeoutError";
1377
+ }
1378
+ };
1379
+
1380
+ // src/next/auth.ts
1381
+ function resolveAppUrl() {
1382
+ const localUrl = process.env.BETTER_AUTH_URL ?? process.env.NEXTAUTH_URL ?? process.env.NEXT_PUBLIC_APP_URL ?? (process.env.NODE_ENV !== "production" ? "http://localhost:3000" : void 0);
1383
+ const url = localUrl ?? process.env.APP_URL ?? process.env.BROKR_AUTH_URL;
1384
+ if (url) return url;
1385
+ const vercelUrl = process.env.VERCEL_URL;
1386
+ if (vercelUrl) return `https://${vercelUrl}`;
1387
+ if (process.env.NODE_ENV === "production") {
1388
+ throw new BrokrError(
1389
+ "[brokr] Cannot resolve auth URL in production. Set BETTER_AUTH_URL or APP_URL in your environment.",
1390
+ "AUTH_NOT_CONFIGURED",
1391
+ "auth"
1392
+ );
1393
+ }
1394
+ return "http://localhost:3000";
1395
+ }
1396
+ var getSessionFromCookies = (0, import_react.cache)(async function getSessionFromCookiesCached() {
1397
+ const { cookies } = await import("next/headers");
1398
+ const cookieStore = await cookies();
1399
+ const cookieHeader = cookieStore.getAll().map((c) => `${c.name}=${c.value}`).join("; ");
1400
+ if (!cookieHeader) return null;
1401
+ const appUrl = resolveAppUrl();
1402
+ const res = await fetch(`${appUrl}/api/auth/get-session`, {
1403
+ method: "GET",
1404
+ headers: { cookie: cookieHeader },
1405
+ cache: "no-store"
1406
+ // Don't cache across different users
1407
+ });
1408
+ if (!res.ok) return null;
1409
+ const data = await res.json();
1410
+ if (!data?.user || !data?.session) return null;
1411
+ return {
1412
+ user: {
1413
+ id: data.user.id,
1414
+ email: data.user.email,
1415
+ name: data.user.name ?? null,
1416
+ image: data.user.image ?? null,
1417
+ emailVerified: data.user.emailVerified ? /* @__PURE__ */ new Date() : null
1418
+ },
1419
+ sessionId: data.session.id,
1420
+ expiresAt: new Date(data.session.expiresAt)
1421
+ };
1422
+ });
1423
+ async function protectApi() {
1424
+ const session = await getSessionFromCookies();
1425
+ if (!session) {
1426
+ throw new BrokrError("[brokr] Authentication required.", "UNAUTHORIZED", "auth");
1427
+ }
1428
+ return session.user;
1429
+ }
1430
+ async function protectPage(redirectTo = "/sign-in") {
1431
+ const session = await getSessionFromCookies();
1432
+ if (!session) {
1433
+ const { redirect } = await import("next/navigation");
1434
+ redirect(redirectTo);
1435
+ throw new Error("unreachable");
1436
+ }
1437
+ return session.user;
1438
+ }
1439
+ function withUser(fn) {
1440
+ return async (request) => {
1441
+ const user = await protectApi();
1442
+ return fn(request, user);
1443
+ };
1444
+ }
1445
+
1446
+ // src/gateway.ts
1447
+ var GATEWAY_URL = "https://api.brokr.sh";
1448
+ var FETCH_TIMEOUT_MS = 3e4;
1449
+ function requireToken(token, capability) {
1450
+ if (!token) {
1451
+ let hint = "brokr env pull --stack <name>";
1452
+ try {
1453
+ if (typeof process !== "undefined") {
1454
+ const fs = require("fs");
1455
+ const path = require("path");
1456
+ const brokrFile = path.join(process.cwd(), ".brokr");
1457
+ if (fs.existsSync(brokrFile)) {
1458
+ const data = JSON.parse(fs.readFileSync(brokrFile, "utf8"));
1459
+ if (data?.stackName) hint = `brokr env pull --stack ${data.stackName}`;
1460
+ }
1461
+ }
1462
+ } catch {
1463
+ }
1464
+ throw new BrokrAuthError(
1465
+ `BROKR_TOKEN is not set. Run: ${hint}`,
1466
+ "BROKR_TOKEN_MISSING"
1467
+ );
1468
+ }
1469
+ }
1470
+ async function gatewayFetch(gatewayUrl, token, path, body, capability) {
1471
+ const controller = new AbortController();
1472
+ const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
1473
+ let res;
1474
+ try {
1475
+ res = await fetch(`${gatewayUrl}${path}`, {
1476
+ method: "POST",
1477
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
1478
+ body: JSON.stringify(body),
1479
+ signal: controller.signal
1480
+ });
1481
+ } catch (err) {
1482
+ if (err instanceof Error && err.name === "AbortError") {
1483
+ throw new BrokrTimeoutError(
1484
+ `Request timed out after ${FETCH_TIMEOUT_MS / 1e3}s`,
1485
+ capability
1486
+ );
1487
+ }
1488
+ throw new BrokrNetworkError(
1489
+ "Could not reach Brokr gateway. Check your network.",
1490
+ capability
1491
+ );
1492
+ } finally {
1493
+ clearTimeout(timeout);
1494
+ }
1495
+ if (res.status === 429) {
1496
+ const rawRetryAfter = parseInt(res.headers.get("Retry-After") ?? "60", 10);
1497
+ const retryAfter = Number.isFinite(rawRetryAfter) ? rawRetryAfter : 60;
1498
+ const data = await res.json().catch(() => ({}));
1499
+ const errorMsg = typeof data.error === "string" ? data.error : `Rate limited (retry after ${retryAfter}s)`;
1500
+ throw new BrokrRateLimitError(
1501
+ errorMsg,
1502
+ retryAfter,
1503
+ capability
1504
+ );
1505
+ }
1506
+ if (res.status === 401) {
1507
+ throw new BrokrAuthError("Invalid or expired BROKR_TOKEN.", "BROKR_TOKEN_INVALID");
1508
+ }
1509
+ if (!res.ok) {
1510
+ const body2 = await res.json().catch(() => ({}));
1511
+ const errObj = typeof body2.error === "object" && body2.error !== null ? body2.error : void 0;
1512
+ const errorData = body2.data ?? errObj?.data ?? body2;
1513
+ const errorCode = errorData.errorCode ?? body2.code;
1514
+ const hint = errorData.hint;
1515
+ const requestId = errorData.requestId ?? res.headers.get("x-request-id");
1516
+ const retryable = errorData.retryable;
1517
+ const errorStr = typeof body2.error === "string" ? body2.error : void 0;
1518
+ const message = body2.message ?? errObj?.message ?? errorStr ?? `${capability} request failed (HTTP ${res.status})`;
1519
+ throw new BrokrError(
1520
+ message,
1521
+ errorCode ?? `${capability.toUpperCase()}_FAILED`,
1522
+ capability,
1523
+ retryable ?? false,
1524
+ errorCode ?? void 0,
1525
+ requestId ?? void 0,
1526
+ hint ?? void 0
1527
+ );
1528
+ }
1529
+ try {
1530
+ return await res.json();
1531
+ } catch {
1532
+ throw new BrokrError(
1533
+ `${capability} returned invalid response (expected JSON).`,
1534
+ `${capability.toUpperCase()}_INVALID_RESPONSE`,
1535
+ capability,
1536
+ true
1537
+ );
1538
+ }
1539
+ }
1540
+ async function gatewayStream(gatewayUrl, token, path, body, capability) {
1541
+ const controller = new AbortController();
1542
+ const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
1543
+ let res;
1544
+ try {
1545
+ res = await fetch(`${gatewayUrl}${path}`, {
1546
+ method: "POST",
1547
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
1548
+ body: JSON.stringify(body),
1549
+ signal: controller.signal
1550
+ });
1551
+ } catch (err) {
1552
+ clearTimeout(timeout);
1553
+ if (err instanceof Error && err.name === "AbortError") {
1554
+ throw new BrokrTimeoutError(
1555
+ `Stream request timed out after ${FETCH_TIMEOUT_MS / 1e3}s`,
1556
+ capability
1557
+ );
1558
+ }
1559
+ throw new BrokrNetworkError(
1560
+ "Could not reach Brokr gateway. Check your network.",
1561
+ capability
1562
+ );
1563
+ }
1564
+ clearTimeout(timeout);
1565
+ if (res.status === 429) {
1566
+ const retryAfter = parseInt(res.headers.get("Retry-After") ?? "60", 10);
1567
+ throw new BrokrRateLimitError("Rate limited.", retryAfter, capability);
1568
+ }
1569
+ if (res.status === 401) {
1570
+ throw new BrokrAuthError("Invalid or expired BROKR_TOKEN.", "BROKR_TOKEN_INVALID");
1571
+ }
1572
+ if (!res.ok || !res.body) {
1573
+ throw new BrokrError(
1574
+ `${capability} stream failed (HTTP ${res.status})`,
1575
+ `${capability.toUpperCase()}_STREAM_FAILED`,
1576
+ capability
1577
+ );
1578
+ }
1579
+ return res;
1580
+ }
1581
+
1582
+ // src/logs/capture.ts
1583
+ var DEFAULT_BATCH_SIZE = 20;
1584
+ var DEFAULT_FLUSH_INTERVAL_MS = 5e3;
1585
+ var buffer = [];
1586
+ var flushTimer = null;
1587
+ var config = null;
1588
+ var intercepted = false;
1589
+ function initCapture(opts = {}) {
1590
+ if (config) return;
1591
+ const token = opts.token ?? (typeof process !== "undefined" ? process.env.BROKR_TOKEN : void 0);
1592
+ const stackId = opts.stackId ?? resolveStackId();
1593
+ if (!token || !stackId) {
1594
+ if (typeof process !== "undefined") {
1595
+ console.log(`[brokr] Log capture skipped: token=${token ? "present" : "MISSING"} stackId=${stackId ?? "MISSING"}`);
1596
+ }
1597
+ return;
1598
+ }
1599
+ const apiUrl = opts.apiUrl ?? opts.gatewayUrl ?? (typeof process !== "undefined" ? process.env.BROKR_GATEWAY_URL : void 0) ?? "https://api.brokr.sh";
1600
+ config = {
1601
+ token,
1602
+ stackId,
1603
+ apiUrl: apiUrl.replace(/\/+$/, ""),
1604
+ batchSize: opts.batchSize ?? DEFAULT_BATCH_SIZE,
1605
+ flushIntervalMs: opts.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS
1606
+ };
1607
+ if (typeof process !== "undefined") {
1608
+ console.log(`[brokr] Log capture initialized \u2192 ${apiUrl}/v1/logs/ingest (stack: ${stackId.slice(0, 8)}...)`);
1609
+ }
1610
+ if (flushTimer) clearInterval(flushTimer);
1611
+ flushTimer = setInterval(() => flush(), config.flushIntervalMs);
1612
+ if (typeof process !== "undefined" && process.on) {
1613
+ process.on("beforeExit", () => flush());
1614
+ }
1615
+ if (typeof process !== "undefined" && !intercepted) {
1616
+ intercepted = true;
1617
+ const origError = console.error;
1618
+ const origWarn = console.warn;
1619
+ console.error = (...args) => {
1620
+ origError.apply(console, args);
1621
+ try {
1622
+ const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
1623
+ if (!msg.startsWith("[brokr]")) capture("error", msg, "console.error");
1624
+ } catch {
1625
+ }
1626
+ };
1627
+ console.warn = (...args) => {
1628
+ origWarn.apply(console, args);
1629
+ try {
1630
+ const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
1631
+ if (!msg.startsWith("[brokr]")) capture("warn", msg, "console.warn");
1632
+ } catch {
1633
+ }
1634
+ };
1635
+ }
1636
+ }
1637
+ function capture(level, message, source, stackTrace) {
1638
+ if (!config) return;
1639
+ buffer.push({
1640
+ level,
1641
+ message: message.slice(0, 1e4),
1642
+ source: source ?? "app",
1643
+ stackTrace: stackTrace?.slice(0, 5e4),
1644
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1645
+ });
1646
+ if (buffer.length >= (config.batchSize ?? DEFAULT_BATCH_SIZE)) {
1647
+ flush();
1648
+ }
1649
+ }
1650
+ function captureRequest(method, path, statusCode, durationMs) {
1651
+ const level = statusCode >= 500 ? "error" : statusCode >= 400 ? "warn" : "info";
1652
+ const dur = durationMs != null ? ` ${durationMs}ms` : "";
1653
+ capture(level, `${method} ${path} ${statusCode}${dur}`, path);
1654
+ }
1655
+ function flush() {
1656
+ if (!config || buffer.length === 0) return;
1657
+ const entries = buffer.splice(0);
1658
+ const { token, stackId, apiUrl } = config;
1659
+ fetch(`${apiUrl}/v1/logs/ingest`, {
1660
+ method: "POST",
1661
+ headers: {
1662
+ "Content-Type": "application/json",
1663
+ Authorization: `Bearer ${token}`
1664
+ },
1665
+ body: JSON.stringify({ stackId, entries })
1666
+ }).catch((err) => {
1667
+ if (typeof console !== "undefined") {
1668
+ console.warn("[brokr] Log flush failed:", err instanceof Error ? err.message : err);
1669
+ }
1670
+ });
1671
+ }
1672
+ function resolveStackId() {
1673
+ if (typeof process === "undefined") return void 0;
1674
+ if (process.env.BROKR_STACK_ID) return process.env.BROKR_STACK_ID;
1675
+ try {
1676
+ const fs = require("fs");
1677
+ const path = require("path");
1678
+ const brokrFile = path.join(process.cwd(), ".brokr");
1679
+ if (fs.existsSync(brokrFile)) {
1680
+ const content = fs.readFileSync(brokrFile, "utf8");
1681
+ const match = content.match(/BROKR_STACK_ID=(.+)/);
1682
+ if (match) return match[1].trim();
1683
+ }
1684
+ } catch {
1685
+ }
1686
+ return void 0;
1687
+ }
1688
+
1689
+ // src/ai/client.ts
1690
+ function normalizeInput(input) {
1691
+ if (typeof input === "string") {
1692
+ return [{ role: "user", content: input }];
1693
+ }
1694
+ return input;
1695
+ }
1696
+ var BrokrAIClient = class {
1697
+ constructor(_token, _gatewayUrl) {
1698
+ this._token = _token;
1699
+ this._gatewayUrl = _gatewayUrl;
1700
+ }
1701
+ // ---------------------------------------------------------------------------
1702
+ // Core chat
1703
+ // ---------------------------------------------------------------------------
1704
+ /**
1705
+ * Send a chat completion request.
1706
+ * Accepts a string (auto-wrapped as user message) or a message array.
1707
+ */
1708
+ async chat(input, options) {
1709
+ requireToken(this._token, "ai");
1710
+ const messages = normalizeInput(input);
1711
+ try {
1712
+ const data = await gatewayFetch(this._gatewayUrl, this._token, "/v1/chat/completions", {
1713
+ messages,
1714
+ model: options?.model,
1715
+ max_tokens: options?.maxTokens,
1716
+ temperature: options?.temperature
1717
+ }, "ai");
1718
+ return {
1719
+ content: data.choices?.[0]?.message?.content ?? "",
1720
+ model: data.model ?? "",
1721
+ usage: {
1722
+ promptTokens: data.usage?.prompt_tokens ?? 0,
1723
+ completionTokens: data.usage?.completion_tokens ?? 0
1724
+ }
1725
+ };
1726
+ } catch (err) {
1727
+ if (err instanceof BrokrError) err.component = "AIChat";
1728
+ const msg = err instanceof Error ? err.message : String(err);
1729
+ capture("error", `AI chat failed: ${msg}`, "brokr.ai.chat", err instanceof Error ? err.stack : void 0);
1730
+ throw err;
1731
+ }
1732
+ }
1733
+ /**
1734
+ * Stream a chat completion. Yields text strings directly.
1735
+ * Accepts a string (auto-wrapped as user message) or a message array.
1736
+ */
1737
+ /**
1738
+ * Stream a chat completion. Yields text strings directly.
1739
+ * Tries streaming first — if the gateway or provider doesn't support it,
1740
+ * falls back to a non-streaming call and yields the full response at once.
1741
+ */
1742
+ async *stream(input, options) {
1743
+ requireToken(this._token, "ai");
1744
+ const messages = normalizeInput(input);
1745
+ let res;
1746
+ try {
1747
+ res = await gatewayStream(
1748
+ this._gatewayUrl,
1749
+ this._token,
1750
+ "/v1/chat/completions",
1751
+ {
1752
+ messages,
1753
+ stream: true,
1754
+ model: options?.model,
1755
+ max_tokens: options?.maxTokens,
1756
+ temperature: options?.temperature
1757
+ },
1758
+ "ai"
1759
+ );
1760
+ } catch (err) {
1761
+ if (err instanceof BrokrError) err.component = "AIStream";
1762
+ const msg = err instanceof Error ? err.message : String(err);
1763
+ capture("error", `AI stream failed: ${msg}`, "brokr.ai.stream", err instanceof Error ? err.stack : void 0);
1764
+ try {
1765
+ const fallback = await this.chat(input, options);
1766
+ yield fallback.content;
1767
+ } catch (fallbackErr) {
1768
+ throw err;
1769
+ }
1770
+ return;
1771
+ }
1772
+ const ct = res.headers.get("content-type") ?? "";
1773
+ if (!ct.includes("text/event-stream")) {
1774
+ try {
1775
+ const data = await res.json();
1776
+ const content = data.choices?.[0]?.message?.content ?? "";
1777
+ if (content) yield content;
1778
+ } catch {
1779
+ const fallback = await this.chat(input, options);
1780
+ yield fallback.content;
1781
+ }
1782
+ return;
1783
+ }
1784
+ const reader = res.body.getReader();
1785
+ const decoder = new TextDecoder();
1786
+ let buffer2 = "";
1787
+ while (true) {
1788
+ const { done, value } = await reader.read();
1789
+ if (done) break;
1790
+ buffer2 += decoder.decode(value, { stream: true });
1791
+ const lines = buffer2.split("\n");
1792
+ buffer2 = lines.pop() ?? "";
1793
+ for (const line of lines) {
1794
+ if (!line.startsWith("data: ")) continue;
1795
+ const payload = line.slice(6).trim();
1796
+ if (payload === "[DONE]") return;
1797
+ try {
1798
+ const parsed = JSON.parse(payload);
1799
+ const delta = parsed.choices?.[0]?.delta?.content ?? "";
1800
+ if (delta) yield delta;
1801
+ } catch {
1802
+ }
1803
+ }
1804
+ }
1805
+ }
1806
+ // ---------------------------------------------------------------------------
1807
+ // Higher-level primitives
1808
+ // ---------------------------------------------------------------------------
1809
+ /**
1810
+ * Extract structured data from a prompt using JSON mode.
1811
+ * Returns a parsed object matching the provided schema shape.
1812
+ */
1813
+ async structured(params) {
1814
+ requireToken(this._token, "ai");
1815
+ const schemaStr = JSON.stringify(params.schema, null, 2);
1816
+ const messages = [
1817
+ {
1818
+ role: "system",
1819
+ content: `You are a structured data extraction assistant. Return ONLY valid JSON matching this schema:
1820
+ ${schemaStr}
1821
+ Do not include any other text, markdown, or explanation.`
1822
+ },
1823
+ { role: "user", content: params.prompt }
1824
+ ];
1825
+ try {
1826
+ const data = await gatewayFetch(this._gatewayUrl, this._token, "/v1/chat/completions", {
1827
+ messages,
1828
+ model: params.model,
1829
+ temperature: params.temperature ?? 0,
1830
+ response_format: { type: "json_object" }
1831
+ }, "ai");
1832
+ const raw = data.choices?.[0]?.message?.content ?? "{}";
1833
+ try {
1834
+ return JSON.parse(raw);
1835
+ } catch {
1836
+ throw new BrokrError(
1837
+ "[brokr] AI returned invalid JSON for structured extraction.",
1838
+ "AI_STRUCTURED_PARSE_ERROR",
1839
+ "ai"
1840
+ );
1841
+ }
1842
+ } catch (err) {
1843
+ if (err instanceof BrokrError) err.component = "AIStructured";
1844
+ throw err;
1845
+ }
1846
+ }
1847
+ /**
1848
+ * Extract fields from unstructured text.
1849
+ * Semantic alias for structured() — same behavior, clearer intent.
1850
+ */
1851
+ async extract(prompt, schema) {
1852
+ return this.structured({ prompt, schema });
1853
+ }
1854
+ /**
1855
+ * Summarize text using AI.
1856
+ */
1857
+ async summarize(text, options) {
1858
+ try {
1859
+ const lengthHint = options?.maxLength ? ` Keep it under ${options.maxLength}.` : "";
1860
+ const response = await this.chat(
1861
+ [
1862
+ {
1863
+ role: "system",
1864
+ content: `You are a summarization assistant. Provide a concise, accurate summary of the following text.${lengthHint} Return only the summary, no preamble.`
1865
+ },
1866
+ { role: "user", content: text }
1867
+ ],
1868
+ { model: options?.model }
1869
+ );
1870
+ return { summary: response.content };
1871
+ } catch (err) {
1872
+ if (err instanceof BrokrError) err.component = "AISummarize";
1873
+ throw err;
1874
+ }
1875
+ }
1876
+ /**
1877
+ * Classify text into one of the provided labels.
1878
+ */
1879
+ async classify(text, labels, options) {
1880
+ try {
1881
+ const labelsStr = labels.map((l) => `"${l}"`).join(", ");
1882
+ const result = await this.structured({
1883
+ prompt: `Classify the following text into exactly one of these labels: [${labelsStr}]
1884
+
1885
+ Text: ${text}`,
1886
+ schema: {
1887
+ type: "object",
1888
+ properties: {
1889
+ label: { type: "string", enum: labels },
1890
+ confidence: { type: "number", minimum: 0, maximum: 1 }
1891
+ },
1892
+ required: ["label", "confidence"]
1893
+ },
1894
+ model: options?.model,
1895
+ temperature: 0
1896
+ });
1897
+ return result;
1898
+ } catch (err) {
1899
+ if (err instanceof BrokrError) err.component = "AIClassify";
1900
+ throw err;
1901
+ }
1902
+ }
1903
+ /**
1904
+ * Generate an embedding vector for the given text.
1905
+ */
1906
+ async embed(text) {
1907
+ requireToken(this._token, "ai");
1908
+ try {
1909
+ const data = await gatewayFetch(this._gatewayUrl, this._token, "/v1/embeddings", {
1910
+ input: text,
1911
+ model: "text-embedding-3-small"
1912
+ }, "ai");
1913
+ return {
1914
+ vector: data.data?.[0]?.embedding ?? []
1915
+ };
1916
+ } catch (err) {
1917
+ if (err instanceof BrokrError) err.component = "AIEmbed";
1918
+ throw err;
1919
+ }
1920
+ }
1921
+ /**
1922
+ * Generate an image from a text prompt.
1923
+ */
1924
+ async image(prompt, options) {
1925
+ requireToken(this._token, "ai");
1926
+ try {
1927
+ const data = await gatewayFetch(this._gatewayUrl, this._token, "/v1/images/generate", {
1928
+ prompt,
1929
+ size: options?.size ?? "1024x1024",
1930
+ n: options?.n ?? 1,
1931
+ model: options?.model
1932
+ }, "ai");
1933
+ const url = data.data?.[0]?.url;
1934
+ if (!url) {
1935
+ throw new BrokrError("[brokr] Image generation returned no URL.", "AI_IMAGE_FAILED", "ai");
1936
+ }
1937
+ return { url };
1938
+ } catch (err) {
1939
+ if (err instanceof BrokrError) err.component = "AIImage";
1940
+ throw err;
1941
+ }
1942
+ }
1943
+ // ---------------------------------------------------------------------------
1944
+ // OpenAI-SDK compatibility
1945
+ // ---------------------------------------------------------------------------
1946
+ /** OpenAI-SDK compatible base URL. */
1947
+ get baseURL() {
1948
+ return `${this._gatewayUrl}/v1`;
1949
+ }
1950
+ /** Use as `apiKey` with the official OpenAI SDK to route through Brokr's gateway. */
1951
+ get apiKey() {
1952
+ requireToken(this._token, "ai");
1953
+ return this._token;
1954
+ }
1955
+ };
1956
+
1957
+ // src/notifications/client.ts
1958
+ var BrokrNotificationsClient = class {
1959
+ constructor(token, gatewayUrl) {
1960
+ this.token = token;
1961
+ this.gatewayUrl = gatewayUrl;
1962
+ }
1963
+ /**
1964
+ * Send a notification to a user. Delivered via WebSocket in real-time
1965
+ * and persisted in the notification history.
1966
+ */
1967
+ async send(params) {
1968
+ requireToken(this.token, "notifications");
1969
+ try {
1970
+ return await gatewayFetch(
1971
+ this.gatewayUrl,
1972
+ this.token,
1973
+ "/v1/notifications/push",
1974
+ params,
1975
+ "notifications"
1976
+ );
1977
+ } catch (err) {
1978
+ if (err instanceof BrokrError) err.component = "Notifications";
1979
+ throw err;
1980
+ }
1981
+ }
1982
+ /**
1983
+ * Fetch notification history for a user. Reads from the DO's SQLite
1984
+ * storage via a gateway REST endpoint.
1985
+ */
1986
+ async list(params) {
1987
+ requireToken(this.token, "notifications");
1988
+ try {
1989
+ return await gatewayFetch(
1990
+ this.gatewayUrl,
1991
+ this.token,
1992
+ "/v1/notifications/list",
1993
+ params,
1994
+ "notifications"
1995
+ );
1996
+ } catch (err) {
1997
+ if (err instanceof BrokrError) err.component = "Notifications";
1998
+ throw err;
1999
+ }
2000
+ }
2001
+ };
2002
+
2003
+ // src/models.ts
2004
+ var providers = [
2005
+ { id: "deepseek", label: "Deepseek", model: "deepseek-chat", color: "#0EA5E9", free: true, logo: "https://assets.brokr.sh/sdk/deepseek_logo.png" },
2006
+ { id: "openai", label: "ChatGPT", model: "gpt-5.4-mini", color: "#10B981", free: false, logo: "https://assets.brokr.sh/sdk/gpt_logo.png" },
2007
+ { id: "anthropic", label: "Claude", model: "claude-sonnet-4-6", color: "#F59E0B", free: false, logo: "https://assets.brokr.sh/sdk/claude_logo.png" },
2008
+ { id: "kimi", label: "Kimi", model: "fireworks/kimi-k2p5", color: "#8B5CF6", free: false, logo: "https://assets.brokr.sh/sdk/kimi_logo.png" },
2009
+ { id: "minimax", label: "Minimax", model: "MiniMaxAI/MiniMax-M2.5", color: "#EC4899", free: false, logo: "https://assets.brokr.sh/sdk/minimax_logo.png" }
2010
+ ];
2011
+ function resolveProviderByModel(model) {
2012
+ return providers.find((p) => p.model === model) ?? providers.find((p) => model.toLowerCase().includes(p.id));
2013
+ }
2014
+
2015
+ // src/next/notifications.ts
2016
+ var DEFAULT_TABLE = "brokr_notifications";
2017
+ async function getNeonSql() {
2018
+ const url = process.env.DATABASE_URL;
2019
+ if (!url) {
2020
+ throw new Error(
2021
+ "[brokr] DATABASE_URL is not set. Notification persistence requires a Postgres database.\nRun: brokr add database"
2022
+ );
2023
+ }
2024
+ try {
2025
+ const { neon } = await import("@neondatabase/serverless");
2026
+ return neon(url);
2027
+ } catch {
2028
+ throw new Error(
2029
+ "[brokr] @neondatabase/serverless is not installed.\nRun: npm install @neondatabase/serverless"
2030
+ );
2031
+ }
2032
+ }
2033
+ var _sql = null;
2034
+ var _ensuredTables = /* @__PURE__ */ new Set();
2035
+ async function getDb() {
2036
+ if (!_sql) _sql = await getNeonSql();
2037
+ return _sql;
2038
+ }
2039
+ function validateTableName(name) {
2040
+ if (!/^[a-z_][a-z0-9_]{0,62}$/.test(name)) {
2041
+ throw new Error(`[brokr] Invalid table name: "${name}". Use lowercase letters, digits, and underscores only.`);
2042
+ }
2043
+ return name;
2044
+ }
2045
+ async function ensureNotificationTable(tableName = DEFAULT_TABLE) {
2046
+ const table = validateTableName(tableName);
2047
+ if (_ensuredTables.has(table)) return;
2048
+ const sql = await getDb();
2049
+ await sql`
2050
+ CREATE TABLE IF NOT EXISTS brokr_notifications (
2051
+ id TEXT PRIMARY KEY,
2052
+ user_id TEXT NOT NULL,
2053
+ type TEXT NOT NULL DEFAULT 'default',
2054
+ title TEXT NOT NULL,
2055
+ message TEXT NOT NULL,
2056
+ variant TEXT NOT NULL DEFAULT 'default',
2057
+ href TEXT,
2058
+ image_url TEXT,
2059
+ image_alt TEXT,
2060
+ read BOOLEAN NOT NULL DEFAULT false,
2061
+ read_at TIMESTAMPTZ,
2062
+ data JSONB,
2063
+ expires_at TIMESTAMPTZ,
2064
+ created_at TIMESTAMPTZ DEFAULT NOW()
2065
+ )
2066
+ `;
2067
+ await sql`ALTER TABLE brokr_notifications ADD COLUMN IF NOT EXISTS type TEXT NOT NULL DEFAULT 'default'`.catch(() => {
2068
+ });
2069
+ await sql`ALTER TABLE brokr_notifications ADD COLUMN IF NOT EXISTS href TEXT`.catch(() => {
2070
+ });
2071
+ await sql`ALTER TABLE brokr_notifications ADD COLUMN IF NOT EXISTS image_url TEXT`.catch(() => {
2072
+ });
2073
+ await sql`ALTER TABLE brokr_notifications ADD COLUMN IF NOT EXISTS image_alt TEXT`.catch(() => {
2074
+ });
2075
+ await sql`ALTER TABLE brokr_notifications ADD COLUMN IF NOT EXISTS read_at TIMESTAMPTZ`.catch(() => {
2076
+ });
2077
+ await sql`ALTER TABLE brokr_notifications ADD COLUMN IF NOT EXISTS expires_at TIMESTAMPTZ`.catch(() => {
2078
+ });
2079
+ await sql`
2080
+ CREATE INDEX IF NOT EXISTS idx_brokr_notifications_user
2081
+ ON brokr_notifications(user_id, created_at DESC)
2082
+ `;
2083
+ await sql`
2084
+ CREATE INDEX IF NOT EXISTS idx_brokr_notifications_type
2085
+ ON brokr_notifications(user_id, type, created_at DESC)
2086
+ `;
2087
+ if (table !== DEFAULT_TABLE) {
2088
+ const exists = await sql`
2089
+ SELECT 1 FROM information_schema.tables
2090
+ WHERE table_schema = 'public' AND table_name = ${table}
2091
+ `;
2092
+ if (exists.length === 0) {
2093
+ throw new Error(
2094
+ `[brokr] Custom notification table "${table}" does not exist.
2095
+ Create it with the same schema as brokr_notifications, or remove the tableName config.`
2096
+ );
2097
+ }
2098
+ }
2099
+ _ensuredTables.add(table);
2100
+ }
2101
+ async function persistNotification(params, opts) {
2102
+ await ensureNotificationTable(opts?.tableName);
2103
+ const sql = await getDb();
2104
+ await sql`
2105
+ INSERT INTO brokr_notifications (id, user_id, type, title, message, variant, href, image_url, image_alt, data, expires_at, created_at)
2106
+ VALUES (
2107
+ ${params.id},
2108
+ ${params.userId},
2109
+ ${params.type ?? "default"},
2110
+ ${params.title},
2111
+ ${params.message},
2112
+ ${params.variant},
2113
+ ${params.href ?? null},
2114
+ ${params.imageUrl ?? null},
2115
+ ${params.imageAlt ?? null},
2116
+ ${params.data ? JSON.stringify(params.data) : null}::jsonb,
2117
+ ${params.expiresAt?.toISOString() ?? null},
2118
+ NOW()
2119
+ )
2120
+ ON CONFLICT (id) DO NOTHING
2121
+ `;
2122
+ }
2123
+ async function listPersistedNotifications(userId, params, opts) {
2124
+ await ensureNotificationTable(opts?.tableName);
2125
+ const sql = await getDb();
2126
+ const limit = Math.min(params?.limit ?? 50, 100);
2127
+ const typeFilter = params?.type ?? null;
2128
+ const skipUnreadFilter = !(params?.unreadOnly ?? false);
2129
+ const rows = await sql`
2130
+ SELECT id, user_id, type, title, message, variant, href, image_url, image_alt, read, read_at, data, expires_at, created_at
2131
+ FROM brokr_notifications
2132
+ WHERE user_id = ${userId}
2133
+ AND (expires_at IS NULL OR expires_at > NOW())
2134
+ AND (${typeFilter}::text IS NULL OR type = ${typeFilter})
2135
+ AND (${skipUnreadFilter}::boolean OR read = false)
2136
+ ORDER BY created_at DESC
2137
+ LIMIT ${limit}
2138
+ `;
2139
+ return rows.map((r) => ({
2140
+ id: r.id,
2141
+ userId: r.user_id,
2142
+ type: r.type ?? "default",
2143
+ title: r.title,
2144
+ message: r.message,
2145
+ variant: r.variant,
2146
+ href: r.href ?? null,
2147
+ imageUrl: r.image_url ?? null,
2148
+ imageAlt: r.image_alt ?? null,
2149
+ read: r.read,
2150
+ readAt: r.read_at ? r.read_at.toISOString() : null,
2151
+ data: r.data,
2152
+ expiresAt: r.expires_at ? r.expires_at.toISOString() : null,
2153
+ createdAt: r.created_at.toISOString()
2154
+ }));
2155
+ }
2156
+ async function markNotificationRead(notificationId, userId, opts) {
2157
+ await ensureNotificationTable(opts?.tableName);
2158
+ const sql = await getDb();
2159
+ await sql`
2160
+ UPDATE brokr_notifications SET read = true, read_at = NOW()
2161
+ WHERE id = ${notificationId} AND user_id = ${userId}
2162
+ `;
2163
+ }
2164
+
2165
+ // src/ai/types.ts
2166
+ function contentToText(content) {
2167
+ if (typeof content === "string") return content;
2168
+ return content.filter((p) => p.type === "text").map((p) => p.text).join("");
2169
+ }
2170
+
2171
+ // src/next/chat.ts
2172
+ initCapture();
2173
+ var CHARS_PER_TOKEN = 4;
2174
+ var DEFAULT_TOKEN_BUDGET = 2e4;
2175
+ function estimateTokens(text) {
2176
+ return Math.ceil(text.length / CHARS_PER_TOKEN);
2177
+ }
2178
+ function trimToTokenBudget(msgs, budget = DEFAULT_TOKEN_BUDGET) {
2179
+ if (msgs.length === 0) return msgs;
2180
+ const system = msgs.filter((m) => m.role === "system");
2181
+ const rest = msgs.filter((m) => m.role !== "system");
2182
+ if (rest.length === 0) return system;
2183
+ const systemCost = system.reduce((s, m) => s + estimateTokens(contentToText(m.content)), 0);
2184
+ const latest = rest[rest.length - 1];
2185
+ const latestCost = estimateTokens(contentToText(latest.content));
2186
+ const remaining = budget - systemCost - latestCost;
2187
+ if (remaining <= 0) return [...system, latest];
2188
+ const kept = [];
2189
+ let used = 0;
2190
+ for (let i = rest.length - 2; i >= 0; i--) {
2191
+ const cost = estimateTokens(contentToText(rest[i].content));
2192
+ if (used + cost > remaining) break;
2193
+ used += cost;
2194
+ kept.unshift(rest[i]);
2195
+ }
2196
+ return [...system, ...kept, latest];
2197
+ }
2198
+ async function getNeonSql2() {
2199
+ const url = process.env.DATABASE_URL;
2200
+ if (!url) {
2201
+ throw new Error(
2202
+ "[brokr] DATABASE_URL is not set. Thread persistence requires a Postgres database.\nSet DATABASE_URL in your environment variables."
2203
+ );
2204
+ }
2205
+ try {
2206
+ const { neon } = await import("@neondatabase/serverless");
2207
+ return neon(url);
2208
+ } catch {
2209
+ throw new Error(
2210
+ "[brokr] @neondatabase/serverless is not installed.\nRun: npm install @neondatabase/serverless"
2211
+ );
2212
+ }
2213
+ }
2214
+ var _sql2 = null;
2215
+ var _tablesEnsured = false;
2216
+ async function getDb2() {
2217
+ if (!_sql2) _sql2 = await getNeonSql2();
2218
+ return _sql2;
2219
+ }
2220
+ async function ensureTables(sql) {
2221
+ if (_tablesEnsured) return;
2222
+ await sql`CREATE SCHEMA IF NOT EXISTS brokr_ai`;
2223
+ const oldTablesExist = await sql`
2224
+ SELECT EXISTS (
2225
+ SELECT 1 FROM information_schema.tables
2226
+ WHERE table_schema = 'public' AND table_name = 'brokr_ai_threads'
2227
+ ) AS exists
2228
+ `;
2229
+ if (oldTablesExist[0]?.exists) {
2230
+ await sql`ALTER TABLE public.brokr_ai_threads SET SCHEMA brokr_ai`.catch(() => {
2231
+ });
2232
+ await sql`ALTER TABLE public.brokr_ai_messages SET SCHEMA brokr_ai`.catch(() => {
2233
+ });
2234
+ await sql`ALTER TABLE brokr_ai.brokr_ai_threads RENAME TO threads`.catch(() => {
2235
+ });
2236
+ await sql`ALTER TABLE brokr_ai.brokr_ai_messages RENAME TO messages`.catch(() => {
2237
+ });
2238
+ }
2239
+ await sql`
2240
+ CREATE TABLE IF NOT EXISTS brokr_ai.threads (
2241
+ id TEXT PRIMARY KEY,
2242
+ surface TEXT NOT NULL DEFAULT 'default',
2243
+ subject TEXT,
2244
+ title TEXT NOT NULL DEFAULT 'New chat',
2245
+ created_at TIMESTAMPTZ DEFAULT NOW(),
2246
+ updated_at TIMESTAMPTZ DEFAULT NOW()
2247
+ )
2248
+ `;
2249
+ await sql`
2250
+ CREATE TABLE IF NOT EXISTS brokr_ai.messages (
2251
+ id TEXT PRIMARY KEY,
2252
+ thread_id TEXT NOT NULL REFERENCES brokr_ai.threads(id) ON DELETE CASCADE,
2253
+ role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
2254
+ content TEXT NOT NULL,
2255
+ model TEXT,
2256
+ created_at TIMESTAMPTZ DEFAULT NOW()
2257
+ )
2258
+ `;
2259
+ await sql`
2260
+ ALTER TABLE brokr_ai.messages ADD COLUMN IF NOT EXISTS model TEXT
2261
+ `.catch(() => {
2262
+ });
2263
+ await sql`
2264
+ ALTER TABLE brokr_ai.messages ADD COLUMN IF NOT EXISTS status TEXT NOT NULL DEFAULT 'complete'
2265
+ `.catch(() => {
2266
+ });
2267
+ await sql`
2268
+ ALTER TABLE brokr_ai.messages ADD COLUMN IF NOT EXISTS provider TEXT
2269
+ `.catch(() => {
2270
+ });
2271
+ await sql`
2272
+ CREATE INDEX IF NOT EXISTS brokr_ai_threads_surface_subject
2273
+ ON brokr_ai.threads(surface, subject, updated_at DESC)
2274
+ `;
2275
+ await sql`
2276
+ CREATE INDEX IF NOT EXISTS brokr_ai_messages_thread_id
2277
+ ON brokr_ai.messages(thread_id, created_at ASC)
2278
+ `;
2279
+ _tablesEnsured = true;
2280
+ }
2281
+ function parsePath(url) {
2282
+ const segments = new URL(url).pathname.split("/").filter(Boolean);
2283
+ const last = segments[segments.length - 1];
2284
+ const secondLast = segments[segments.length - 2];
2285
+ if (last === "chat") return { action: "chat" };
2286
+ if (last === "threads") return { action: "threads" };
2287
+ if (last === "ws-token") return { action: "ws-token" };
2288
+ if (last === "notifications") return { action: "notifications" };
2289
+ if (last === "read" && secondLast === "notifications") return { action: "notifications-read" };
2290
+ if (last === "messages" && secondLast) return { action: "messages", id: secondLast };
2291
+ if (last === "rename" && secondLast) return { action: "rename", id: secondLast };
2292
+ if (secondLast === "threads" && last) return { action: "thread", id: last };
2293
+ return { action: "unknown" };
2294
+ }
2295
+ function makeThreadTitle(content) {
2296
+ const cleaned = content.trim().replace(/\s+/g, " ");
2297
+ return cleaned.length > 48 ? `${cleaned.slice(0, 48).trimEnd()}\u2026` : cleaned || "New chat";
2298
+ }
2299
+ async function handleListThreads(request, opts) {
2300
+ if (!opts.persist) {
2301
+ return Response.json({ threads: [] });
2302
+ }
2303
+ const url = new URL(request.url);
2304
+ const surface = url.searchParams.get("surface") ?? "default";
2305
+ const subject = url.searchParams.get("subject");
2306
+ const sql = await getDb2();
2307
+ await ensureTables(sql);
2308
+ const rows = subject ? await sql`
2309
+ SELECT t.id, t.surface, t.subject, t.title, t.created_at, t.updated_at,
2310
+ (SELECT COUNT(*) FROM brokr_ai.messages WHERE thread_id = t.id) AS message_count
2311
+ FROM brokr_ai.threads t
2312
+ WHERE t.surface = ${surface} AND t.subject = ${subject}
2313
+ ORDER BY t.updated_at DESC
2314
+ LIMIT 50
2315
+ ` : await sql`
2316
+ SELECT t.id, t.surface, t.subject, t.title, t.created_at, t.updated_at,
2317
+ (SELECT COUNT(*) FROM brokr_ai.messages WHERE thread_id = t.id) AS message_count
2318
+ FROM brokr_ai.threads t
2319
+ WHERE t.surface = ${surface}
2320
+ ORDER BY t.updated_at DESC
2321
+ LIMIT 50
2322
+ `;
2323
+ return Response.json({
2324
+ threads: rows.map((r) => ({
2325
+ id: r.id,
2326
+ surface: r.surface,
2327
+ subject: r.subject,
2328
+ title: r.title,
2329
+ createdAt: r.created_at,
2330
+ updatedAt: r.updated_at,
2331
+ messageCount: Number(r.message_count)
2332
+ }))
2333
+ });
2334
+ }
2335
+ async function handleGetMessages(request, threadId, opts) {
2336
+ if (!opts.persist) {
2337
+ return Response.json({ messages: [], hasMore: false });
2338
+ }
2339
+ const url = new URL(request.url);
2340
+ const limit = Math.min(Number(url.searchParams.get("limit")) || 30, 100);
2341
+ const offset = Math.max(Number(url.searchParams.get("offset")) || 0, 0);
2342
+ const sql = await getDb2();
2343
+ const countResult = await sql`
2344
+ SELECT COUNT(*) AS total FROM brokr_ai.messages WHERE thread_id = ${threadId}
2345
+ `;
2346
+ const total = Number(countResult[0]?.total ?? 0);
2347
+ const rows = await sql`
2348
+ SELECT id, role, content, model, status, provider FROM (
2349
+ SELECT id, role, content, model, status, provider, created_at
2350
+ FROM brokr_ai.messages
2351
+ WHERE thread_id = ${threadId}
2352
+ ORDER BY created_at DESC, id DESC
2353
+ LIMIT ${limit} OFFSET ${offset}
2354
+ ) sub ORDER BY created_at ASC, id ASC
2355
+ `;
2356
+ return Response.json({
2357
+ messages: rows.map((r) => ({
2358
+ id: r.id,
2359
+ role: r.role,
2360
+ content: r.content,
2361
+ model: r.model ?? void 0,
2362
+ status: r.status ?? "complete",
2363
+ provider: r.provider ?? void 0
2364
+ })),
2365
+ hasMore: offset + limit < total
2366
+ });
2367
+ }
2368
+ async function handleRenameThread(request, threadId, opts) {
2369
+ if (!opts.persist) {
2370
+ return Response.json({ success: false }, { status: 400 });
2371
+ }
2372
+ const body = await request.json();
2373
+ const title = (body.title ?? "").trim();
2374
+ if (!title) {
2375
+ return Response.json({ error: "Title is required" }, { status: 400 });
2376
+ }
2377
+ const safeTitle = title.length > 100 ? `${title.slice(0, 100).trimEnd()}\u2026` : title;
2378
+ const sql = await getDb2();
2379
+ await ensureTables(sql);
2380
+ await sql`UPDATE brokr_ai.threads SET title = ${safeTitle}, updated_at = NOW() WHERE id = ${threadId}`;
2381
+ return Response.json({ success: true, title: safeTitle });
2382
+ }
2383
+ async function handleDeleteThread(_request, threadId, opts) {
2384
+ if (!opts.persist) {
2385
+ return Response.json({ success: true });
2386
+ }
2387
+ const sql = await getDb2();
2388
+ await sql`DELETE FROM brokr_ai.threads WHERE id = ${threadId}`;
2389
+ return Response.json({ success: true });
2390
+ }
2391
+ async function backgroundTask(promise) {
2392
+ try {
2393
+ const mod = await Promise.resolve().then(() => __toESM(require_functions()));
2394
+ if (typeof mod.waitUntil === "function") {
2395
+ mod.waitUntil(promise);
2396
+ return;
2397
+ }
2398
+ } catch {
2399
+ }
2400
+ promise.catch((err) => console.error("[brokr] Background task failed:", err));
2401
+ }
2402
+ async function handleChat(request, opts) {
2403
+ const body = await request.json();
2404
+ const gatewayUrl = process.env.BROKR_GATEWAY_URL ?? GATEWAY_URL;
2405
+ const token = process.env.BROKR_TOKEN;
2406
+ if (!token) {
2407
+ return Response.json(
2408
+ { error: "BROKR_TOKEN is not configured. Run: brokr env pull --stack <name>" },
2409
+ { status: 500 }
2410
+ );
2411
+ }
2412
+ const ai = new BrokrAIClient(token, gatewayUrl);
2413
+ const model = body.model;
2414
+ const systemPrompt = opts.systemPrompt ?? body.systemPrompt;
2415
+ const resolvedProvider = model ? resolveProviderByModel(model) : void 0;
2416
+ let messages;
2417
+ let threadId;
2418
+ let isNewThread = false;
2419
+ let userMsgId;
2420
+ let assistantMsgId;
2421
+ let threadTitle;
2422
+ if (opts.persist && body.content !== void 0) {
2423
+ threadId = body.thread_id ?? void 0;
2424
+ const sql = await getDb2();
2425
+ await ensureTables(sql);
2426
+ let history = [];
2427
+ if (threadId) {
2428
+ const [historyRows, titleRows] = await Promise.all([
2429
+ sql`
2430
+ SELECT role, content FROM brokr_ai.messages
2431
+ WHERE thread_id = ${threadId} AND status = 'complete'
2432
+ ORDER BY created_at ASC
2433
+ `,
2434
+ sql`SELECT title FROM brokr_ai.threads WHERE id = ${threadId} LIMIT 1`
2435
+ ]);
2436
+ history = historyRows;
2437
+ threadTitle = titleRows[0]?.title || void 0;
2438
+ } else {
2439
+ threadId = crypto.randomUUID();
2440
+ isNewThread = true;
2441
+ }
2442
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2443
+ const assistantNow = new Date(Date.parse(now) + 1).toISOString();
2444
+ if (!threadTitle) {
2445
+ threadTitle = makeThreadTitle(body.content ?? "");
2446
+ }
2447
+ userMsgId = crypto.randomUUID();
2448
+ assistantMsgId = crypto.randomUUID();
2449
+ if (isNewThread) {
2450
+ await sql`
2451
+ INSERT INTO brokr_ai.threads (id, surface, subject, title, created_at, updated_at)
2452
+ VALUES (
2453
+ ${threadId},
2454
+ ${body.surface ?? "default"},
2455
+ ${body.subject ?? null},
2456
+ ${threadTitle},
2457
+ ${now},
2458
+ ${now}
2459
+ )
2460
+ `;
2461
+ } else {
2462
+ await sql`
2463
+ UPDATE brokr_ai.threads SET updated_at = ${now} WHERE id = ${threadId}
2464
+ `;
2465
+ }
2466
+ await sql`
2467
+ INSERT INTO brokr_ai.messages (id, thread_id, role, content, status, created_at)
2468
+ VALUES (${userMsgId}, ${threadId}, 'user', ${body.content ?? ""}, 'complete', ${now})
2469
+ `;
2470
+ await sql`
2471
+ INSERT INTO brokr_ai.messages (id, thread_id, role, content, model, provider, status, created_at)
2472
+ VALUES (${assistantMsgId}, ${threadId}, 'assistant', '', ${model ?? null}, ${resolvedProvider?.id ?? null}, 'pending', ${assistantNow})
2473
+ `;
2474
+ messages = trimToTokenBudget([
2475
+ ...systemPrompt ? [{ role: "system", content: systemPrompt }] : [],
2476
+ ...history.map((h) => ({ role: h.role, content: h.content })),
2477
+ { role: "user", content: body.content }
2478
+ ]);
2479
+ } else {
2480
+ const clientMessages = body.messages ?? [];
2481
+ messages = systemPrompt ? [{ role: "system", content: systemPrompt }, ...clientMessages] : clientMessages;
2482
+ }
2483
+ const chunks = [];
2484
+ let chunkIndex = 0;
2485
+ let generationDone = false;
2486
+ let generationError = null;
2487
+ let fullResponse = "";
2488
+ let metadataSent = false;
2489
+ let resolveChunk = null;
2490
+ function notifyChunk() {
2491
+ if (resolveChunk) {
2492
+ const fn = resolveChunk;
2493
+ resolveChunk = null;
2494
+ fn();
2495
+ }
2496
+ }
2497
+ function waitForChunk() {
2498
+ if (generationDone || generationError || chunkIndex < chunks.length) {
2499
+ return Promise.resolve();
2500
+ }
2501
+ return new Promise((resolve) => {
2502
+ resolveChunk = resolve;
2503
+ });
2504
+ }
2505
+ const generationTask = (async () => {
2506
+ try {
2507
+ const aiStream = ai.stream(messages, { model });
2508
+ for await (const delta of aiStream) {
2509
+ fullResponse += delta;
2510
+ chunks.push(delta);
2511
+ notifyChunk();
2512
+ }
2513
+ if (opts.persist && threadId && assistantMsgId) {
2514
+ const sql = await getDb2();
2515
+ await sql`
2516
+ UPDATE brokr_ai.messages
2517
+ SET content = ${fullResponse}, status = 'complete'
2518
+ WHERE id = ${assistantMsgId}
2519
+ `;
2520
+ }
2521
+ if (opts.persist && body.userId && threadId && assistantMsgId) {
2522
+ const notifId = crypto.randomUUID();
2523
+ const preview = fullResponse.length > 120 ? `${fullResponse.slice(0, 120)}...` : fullResponse;
2524
+ const notifData = {
2525
+ type: "ai_response",
2526
+ threadId,
2527
+ assistantMessageId: assistantMsgId,
2528
+ model: model ?? null,
2529
+ provider: resolvedProvider?.id ?? null,
2530
+ providerLogo: resolvedProvider?.logo ?? null,
2531
+ surface: body.surface ?? "default",
2532
+ href: `/chat?thread=${threadId}`
2533
+ };
2534
+ await Promise.allSettled([
2535
+ persistNotification({
2536
+ id: notifId,
2537
+ userId: body.userId,
2538
+ type: "ai_response",
2539
+ title: threadTitle ?? "AI Response",
2540
+ message: preview,
2541
+ variant: "default",
2542
+ href: `/chat?thread=${threadId}`,
2543
+ imageUrl: resolvedProvider?.logo ?? void 0,
2544
+ imageAlt: resolvedProvider?.label ?? void 0,
2545
+ data: notifData
2546
+ }, { tableName: opts.notifications?.tableName }).catch((err) => {
2547
+ console.error("[brokr] Notification DB persist failed:", err);
2548
+ }),
2549
+ new BrokrNotificationsClient(token, gatewayUrl).send({
2550
+ userId: body.userId,
2551
+ title: threadTitle ?? "AI Response",
2552
+ message: preview,
2553
+ variant: "default",
2554
+ data: notifData,
2555
+ dedup: `ai_response:${assistantMsgId}`
2556
+ }).catch((err) => {
2557
+ console.error("[brokr] Notification push failed:", err);
2558
+ })
2559
+ ]);
2560
+ }
2561
+ } catch (err) {
2562
+ console.error("[brokr] AI generation error:", err);
2563
+ generationError = "Something went wrong generating a reply.";
2564
+ if (opts.persist && threadId && assistantMsgId) {
2565
+ try {
2566
+ const sql = await getDb2();
2567
+ await sql`
2568
+ UPDATE brokr_ai.messages
2569
+ SET status = 'error', content = ''
2570
+ WHERE id = ${assistantMsgId}
2571
+ `;
2572
+ } catch (dbErr) {
2573
+ console.error("[brokr] Failed to mark message as error:", dbErr);
2574
+ }
2575
+ }
2576
+ } finally {
2577
+ generationDone = true;
2578
+ notifyChunk();
2579
+ }
2580
+ })();
2581
+ void backgroundTask(generationTask);
2582
+ const encoder = new TextEncoder();
2583
+ const stream = new ReadableStream({
2584
+ async pull(controller) {
2585
+ const enqueue = (event) => {
2586
+ controller.enqueue(encoder.encode(`data: ${JSON.stringify(event)}
2587
+
2588
+ `));
2589
+ };
2590
+ await waitForChunk();
2591
+ if (!metadataSent && opts.persist && threadId) {
2592
+ metadataSent = true;
2593
+ enqueue({
2594
+ type: "conversation",
2595
+ id: threadId,
2596
+ assistantMessageId: assistantMsgId,
2597
+ isNewThread
2598
+ });
2599
+ }
2600
+ while (chunkIndex < chunks.length) {
2601
+ enqueue({ type: "delta", delta: chunks[chunkIndex] });
2602
+ chunkIndex++;
2603
+ }
2604
+ if (generationDone || generationError) {
2605
+ if (generationError) {
2606
+ enqueue({ type: "error", message: generationError });
2607
+ } else {
2608
+ enqueue({ type: "done" });
2609
+ }
2610
+ controller.close();
2611
+ }
2612
+ }
2613
+ });
2614
+ return new Response(stream, {
2615
+ headers: {
2616
+ "Content-Type": "text/event-stream",
2617
+ "Cache-Control": "no-cache",
2618
+ Connection: "keep-alive"
2619
+ }
2620
+ });
2621
+ }
2622
+ async function handleListNotifications(request, opts) {
2623
+ const url = new URL(request.url);
2624
+ const userId = url.searchParams.get("userId");
2625
+ if (!userId) {
2626
+ return Response.json({ error: "userId is required" }, { status: 400 });
2627
+ }
2628
+ const tableName = opts.notifications?.tableName;
2629
+ try {
2630
+ const notifications = await listPersistedNotifications(
2631
+ userId,
2632
+ {
2633
+ limit: Math.min(Number(url.searchParams.get("limit")) || 50, 100),
2634
+ unreadOnly: url.searchParams.get("unreadOnly") === "true",
2635
+ type: url.searchParams.get("type") ?? void 0
2636
+ },
2637
+ { tableName }
2638
+ );
2639
+ return Response.json({ notifications });
2640
+ } catch (err) {
2641
+ console.error("[brokr] List notifications failed:", err);
2642
+ return Response.json({ notifications: [] });
2643
+ }
2644
+ }
2645
+ async function handleMarkNotificationRead(request, opts) {
2646
+ const body = await request.json();
2647
+ if (!body.notificationId || !body.userId) {
2648
+ return Response.json({ error: "notificationId and userId are required" }, { status: 400 });
2649
+ }
2650
+ const tableName = opts.notifications?.tableName;
2651
+ try {
2652
+ await markNotificationRead(body.notificationId, body.userId, { tableName });
2653
+ return Response.json({ success: true });
2654
+ } catch (err) {
2655
+ console.error("[brokr] Mark notification read failed:", err);
2656
+ return Response.json({ error: "Failed to mark as read" }, { status: 500 });
2657
+ }
2658
+ }
2659
+ function handleWsToken() {
2660
+ const token = process.env.BROKR_TOKEN;
2661
+ if (!token) {
2662
+ return Response.json(
2663
+ { error: "BROKR_TOKEN not configured" },
2664
+ { status: 500 }
2665
+ );
2666
+ }
2667
+ return Response.json({ token });
2668
+ }
2669
+ function createBrokrHandlers(options) {
2670
+ const opts = { persist: false, ...options };
2671
+ function withLogging(method, handler) {
2672
+ return async (request) => {
2673
+ const start = Date.now();
2674
+ const urlPath = new URL(request.url).pathname;
2675
+ try {
2676
+ const response = await handler(request);
2677
+ const dur = Date.now() - start;
2678
+ captureRequest(method, urlPath, response.status, dur);
2679
+ return response;
2680
+ } catch (err) {
2681
+ const dur = Date.now() - start;
2682
+ capture("error", `${method} ${urlPath} FAILED ${dur}ms \u2014 ${err instanceof Error ? err.message : "unknown"}`, urlPath);
2683
+ throw err;
2684
+ }
2685
+ };
2686
+ }
2687
+ return {
2688
+ GET: withLogging("GET", async (request) => {
2689
+ const path = parsePath(request.url);
2690
+ if (path.action === "threads") return handleListThreads(request, opts);
2691
+ if (path.action === "messages" && path.id) return handleGetMessages(request, path.id, opts);
2692
+ if (path.action === "ws-token") return handleWsToken();
2693
+ if (path.action === "notifications") return handleListNotifications(request, opts);
2694
+ return new Response("Not found", { status: 404 });
2695
+ }),
2696
+ POST: withLogging("POST", async (request) => {
2697
+ const path = parsePath(request.url);
2698
+ if (path.action === "chat") return handleChat(request, opts);
2699
+ if (path.action === "notifications-read") return handleMarkNotificationRead(request, opts);
2700
+ return new Response("Not found", { status: 404 });
2701
+ }),
2702
+ PATCH: withLogging("PATCH", async (request) => {
2703
+ const path = parsePath(request.url);
2704
+ if (path.action === "rename" && path.id) return handleRenameThread(request, path.id, opts);
2705
+ if (path.action === "thread" && path.id) return handleRenameThread(request, path.id, opts);
2706
+ return new Response("Not found", { status: 404 });
2707
+ }),
2708
+ DELETE: withLogging("DELETE", async (request) => {
2709
+ const path = parsePath(request.url);
2710
+ if (path.action === "thread" && path.id) return handleDeleteThread(request, path.id, opts);
2711
+ return new Response("Not found", { status: 404 });
2712
+ })
2713
+ };
2714
+ }
2715
+ // Annotate the CommonJS export names for ESM import in node:
2716
+ 0 && (module.exports = {
2717
+ createBrokrHandlers,
2718
+ ensureNotificationTable,
2719
+ listPersistedNotifications,
2720
+ markNotificationRead,
2721
+ persistNotification,
2722
+ protectApi,
2723
+ protectPage,
2724
+ withUser
2725
+ });