@corgelabs/corge 0.0.1 → 1.0.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 (341) hide show
  1. package/dist/ai/index.d.ts +3 -0
  2. package/dist/ai/index.d.ts.map +1 -0
  3. package/dist/ai/index.js +3 -0
  4. package/dist/ai/index.js.map +1 -0
  5. package/dist/ai/schema.d.ts +83 -0
  6. package/dist/ai/schema.d.ts.map +1 -0
  7. package/dist/ai/schema.js +19 -0
  8. package/dist/ai/schema.js.map +1 -0
  9. package/dist/ai/service.d.ts +14 -0
  10. package/dist/ai/service.d.ts.map +1 -0
  11. package/dist/ai/service.js +266 -0
  12. package/dist/ai/service.js.map +1 -0
  13. package/dist/ai/utils.d.ts +10 -0
  14. package/dist/ai/utils.d.ts.map +1 -0
  15. package/dist/ai/utils.js +27 -0
  16. package/dist/ai/utils.js.map +1 -0
  17. package/dist/attachments/index.d.ts +4 -0
  18. package/dist/attachments/index.d.ts.map +1 -0
  19. package/dist/attachments/index.js +4 -0
  20. package/dist/attachments/index.js.map +1 -0
  21. package/dist/attachments/routes.d.ts +75 -0
  22. package/dist/attachments/routes.d.ts.map +1 -0
  23. package/dist/attachments/routes.js +18 -0
  24. package/dist/attachments/routes.js.map +1 -0
  25. package/dist/attachments/schema.d.ts +61 -0
  26. package/dist/attachments/schema.d.ts.map +1 -0
  27. package/dist/attachments/schema.js +30 -0
  28. package/dist/attachments/schema.js.map +1 -0
  29. package/dist/attachments/service.d.ts +27 -0
  30. package/dist/attachments/service.d.ts.map +1 -0
  31. package/dist/attachments/service.js +224 -0
  32. package/dist/attachments/service.js.map +1 -0
  33. package/dist/attachments/utils.d.ts +9 -0
  34. package/dist/attachments/utils.d.ts.map +1 -0
  35. package/dist/attachments/utils.js +80 -0
  36. package/dist/attachments/utils.js.map +1 -0
  37. package/dist/auth/index.d.ts +4 -0
  38. package/dist/auth/index.d.ts.map +1 -0
  39. package/dist/auth/index.js +4 -0
  40. package/dist/auth/index.js.map +1 -0
  41. package/dist/auth/oidc.d.ts +25 -0
  42. package/dist/auth/oidc.d.ts.map +1 -0
  43. package/dist/auth/oidc.js +298 -0
  44. package/dist/auth/oidc.js.map +1 -0
  45. package/dist/auth/recovery.d.ts +41 -0
  46. package/dist/auth/recovery.d.ts.map +1 -0
  47. package/dist/auth/recovery.js +250 -0
  48. package/dist/auth/recovery.js.map +1 -0
  49. package/dist/auth/routes.d.ts +226 -0
  50. package/dist/auth/routes.d.ts.map +1 -0
  51. package/dist/auth/routes.js +96 -0
  52. package/dist/auth/routes.js.map +1 -0
  53. package/dist/auth/schema.d.ts +158 -0
  54. package/dist/auth/schema.d.ts.map +1 -0
  55. package/dist/auth/schema.js +82 -0
  56. package/dist/auth/schema.js.map +1 -0
  57. package/dist/auth/service.d.ts +96 -0
  58. package/dist/auth/service.d.ts.map +1 -0
  59. package/dist/auth/service.js +129 -0
  60. package/dist/auth/service.js.map +1 -0
  61. package/dist/auth/session.d.ts +51 -0
  62. package/dist/auth/session.d.ts.map +1 -0
  63. package/dist/auth/session.js +344 -0
  64. package/dist/auth/session.js.map +1 -0
  65. package/dist/auth/utils.d.ts +17 -0
  66. package/dist/auth/utils.d.ts.map +1 -0
  67. package/dist/auth/utils.js +96 -0
  68. package/dist/auth/utils.js.map +1 -0
  69. package/dist/bin/corge.js +547 -0
  70. package/dist/chat/context.d.ts +10 -0
  71. package/dist/chat/context.d.ts.map +1 -0
  72. package/dist/chat/context.js +221 -0
  73. package/dist/chat/context.js.map +1 -0
  74. package/dist/chat/index.d.ts +4 -0
  75. package/dist/chat/index.d.ts.map +1 -0
  76. package/dist/chat/index.js +4 -0
  77. package/dist/chat/index.js.map +1 -0
  78. package/dist/chat/routes.d.ts +160 -0
  79. package/dist/chat/routes.d.ts.map +1 -0
  80. package/dist/chat/routes.js +210 -0
  81. package/dist/chat/routes.js.map +1 -0
  82. package/dist/chat/schema.d.ts +285 -0
  83. package/dist/chat/schema.d.ts.map +1 -0
  84. package/dist/chat/schema.js +74 -0
  85. package/dist/chat/schema.js.map +1 -0
  86. package/dist/chat/service.d.ts +64 -0
  87. package/dist/chat/service.d.ts.map +1 -0
  88. package/dist/chat/service.js +279 -0
  89. package/dist/chat/service.js.map +1 -0
  90. package/dist/chat/stream.d.ts +53 -0
  91. package/dist/chat/stream.d.ts.map +1 -0
  92. package/dist/chat/stream.js +339 -0
  93. package/dist/chat/stream.js.map +1 -0
  94. package/dist/chat/utils.d.ts +61 -0
  95. package/dist/chat/utils.d.ts.map +1 -0
  96. package/dist/chat/utils.js +285 -0
  97. package/dist/chat/utils.js.map +1 -0
  98. package/dist/cli/builder.d.ts +6 -0
  99. package/dist/cli/builder.d.ts.map +1 -0
  100. package/dist/cli/builder.js +91 -0
  101. package/dist/cli/builder.js.map +1 -0
  102. package/dist/cli/deployer.d.ts +2 -0
  103. package/dist/cli/deployer.d.ts.map +1 -0
  104. package/dist/cli/deployer.js +152 -0
  105. package/dist/cli/deployer.js.map +1 -0
  106. package/dist/cli/dev-server.d.ts +2 -0
  107. package/dist/cli/dev-server.d.ts.map +1 -0
  108. package/dist/cli/dev-server.js +70 -0
  109. package/dist/cli/dev-server.js.map +1 -0
  110. package/dist/cli/env.d.ts +4 -0
  111. package/dist/cli/env.d.ts.map +1 -0
  112. package/dist/cli/env.js +68 -0
  113. package/dist/cli/env.js.map +1 -0
  114. package/dist/cli/init.d.ts +6 -0
  115. package/dist/cli/init.d.ts.map +1 -0
  116. package/dist/cli/init.js +103 -0
  117. package/dist/cli/init.js.map +1 -0
  118. package/dist/config.d.ts +262 -0
  119. package/dist/config.d.ts.map +1 -0
  120. package/dist/config.js +212 -0
  121. package/dist/config.js.map +1 -0
  122. package/dist/db/index.d.ts +3 -0
  123. package/dist/db/index.d.ts.map +1 -0
  124. package/dist/db/index.js +3 -0
  125. package/dist/db/index.js.map +1 -0
  126. package/dist/db/schema.d.ts +410 -0
  127. package/dist/db/schema.d.ts.map +1 -0
  128. package/dist/db/schema.js +294 -0
  129. package/dist/db/schema.js.map +1 -0
  130. package/dist/db/service.d.ts +42 -0
  131. package/dist/db/service.d.ts.map +1 -0
  132. package/dist/db/service.js +372 -0
  133. package/dist/db/service.js.map +1 -0
  134. package/dist/db/utils.d.ts +25 -0
  135. package/dist/db/utils.d.ts.map +1 -0
  136. package/dist/db/utils.js +188 -0
  137. package/dist/db/utils.js.map +1 -0
  138. package/dist/emails/index.d.ts +4 -0
  139. package/dist/emails/index.d.ts.map +1 -0
  140. package/dist/emails/index.js +4 -0
  141. package/dist/emails/index.js.map +1 -0
  142. package/dist/emails/routes.d.ts +191 -0
  143. package/dist/emails/routes.d.ts.map +1 -0
  144. package/dist/emails/routes.js +39 -0
  145. package/dist/emails/routes.js.map +1 -0
  146. package/dist/emails/schema.d.ts +237 -0
  147. package/dist/emails/schema.d.ts.map +1 -0
  148. package/dist/emails/schema.js +98 -0
  149. package/dist/emails/schema.js.map +1 -0
  150. package/dist/emails/service.d.ts +22 -0
  151. package/dist/emails/service.d.ts.map +1 -0
  152. package/dist/emails/service.js +337 -0
  153. package/dist/emails/service.js.map +1 -0
  154. package/dist/emails/utils.d.ts +49 -0
  155. package/dist/emails/utils.d.ts.map +1 -0
  156. package/dist/emails/utils.js +341 -0
  157. package/dist/emails/utils.js.map +1 -0
  158. package/dist/files/index.d.ts +4 -0
  159. package/dist/files/index.d.ts.map +1 -0
  160. package/dist/files/index.js +4 -0
  161. package/dist/files/index.js.map +1 -0
  162. package/dist/files/routes.d.ts +72 -0
  163. package/dist/files/routes.d.ts.map +1 -0
  164. package/dist/files/routes.js +38 -0
  165. package/dist/files/routes.js.map +1 -0
  166. package/dist/files/schema.d.ts +57 -0
  167. package/dist/files/schema.d.ts.map +1 -0
  168. package/dist/files/schema.js +39 -0
  169. package/dist/files/schema.js.map +1 -0
  170. package/dist/files/service.d.ts +27 -0
  171. package/dist/files/service.d.ts.map +1 -0
  172. package/dist/files/service.js +175 -0
  173. package/dist/files/service.js.map +1 -0
  174. package/dist/files/utils.d.ts +3 -0
  175. package/dist/files/utils.d.ts.map +1 -0
  176. package/dist/files/utils.js +63 -0
  177. package/dist/files/utils.js.map +1 -0
  178. package/dist/index.d.ts +875 -0
  179. package/dist/index.d.ts.map +1 -0
  180. package/dist/index.js +9919 -0
  181. package/dist/index.js.map +7 -0
  182. package/dist/payments/billing.d.ts +29 -0
  183. package/dist/payments/billing.d.ts.map +1 -0
  184. package/dist/payments/billing.js +378 -0
  185. package/dist/payments/billing.js.map +1 -0
  186. package/dist/payments/index.d.ts +4 -0
  187. package/dist/payments/index.d.ts.map +1 -0
  188. package/dist/payments/index.js +4 -0
  189. package/dist/payments/index.js.map +1 -0
  190. package/dist/payments/routes.d.ts +340 -0
  191. package/dist/payments/routes.d.ts.map +1 -0
  192. package/dist/payments/routes.js +56 -0
  193. package/dist/payments/routes.js.map +1 -0
  194. package/dist/payments/schema.d.ts +412 -0
  195. package/dist/payments/schema.d.ts.map +1 -0
  196. package/dist/payments/schema.js +260 -0
  197. package/dist/payments/schema.js.map +1 -0
  198. package/dist/payments/service.d.ts +31 -0
  199. package/dist/payments/service.d.ts.map +1 -0
  200. package/dist/payments/service.js +322 -0
  201. package/dist/payments/service.js.map +1 -0
  202. package/dist/payments/utils.d.ts +61 -0
  203. package/dist/payments/utils.d.ts.map +1 -0
  204. package/dist/payments/utils.js +369 -0
  205. package/dist/payments/utils.js.map +1 -0
  206. package/dist/router/guard.d.ts +19 -0
  207. package/dist/router/guard.d.ts.map +1 -0
  208. package/dist/router/guard.js +243 -0
  209. package/dist/router/guard.js.map +1 -0
  210. package/dist/router/index.d.ts +3 -0
  211. package/dist/router/index.d.ts.map +1 -0
  212. package/dist/router/index.js +3 -0
  213. package/dist/router/index.js.map +1 -0
  214. package/dist/router/schema.d.ts +103 -0
  215. package/dist/router/schema.d.ts.map +1 -0
  216. package/dist/router/schema.js +282 -0
  217. package/dist/router/schema.js.map +1 -0
  218. package/dist/router/service.d.ts +25 -0
  219. package/dist/router/service.d.ts.map +1 -0
  220. package/dist/router/service.js +339 -0
  221. package/dist/router/service.js.map +1 -0
  222. package/dist/tasks/index.d.ts +4 -0
  223. package/dist/tasks/index.d.ts.map +1 -0
  224. package/dist/tasks/index.js +4 -0
  225. package/dist/tasks/index.js.map +1 -0
  226. package/dist/tasks/routes.d.ts +54 -0
  227. package/dist/tasks/routes.d.ts.map +1 -0
  228. package/dist/tasks/routes.js +195 -0
  229. package/dist/tasks/routes.js.map +1 -0
  230. package/dist/tasks/schema.d.ts +261 -0
  231. package/dist/tasks/schema.d.ts.map +1 -0
  232. package/dist/tasks/schema.js +35 -0
  233. package/dist/tasks/schema.js.map +1 -0
  234. package/dist/tasks/service.d.ts +32 -0
  235. package/dist/tasks/service.d.ts.map +1 -0
  236. package/dist/tasks/service.js +201 -0
  237. package/dist/tasks/service.js.map +1 -0
  238. package/dist/tasks/steps.d.ts +18 -0
  239. package/dist/tasks/steps.d.ts.map +1 -0
  240. package/dist/tasks/steps.js +365 -0
  241. package/dist/tasks/steps.js.map +1 -0
  242. package/dist/tasks/utils.d.ts +75 -0
  243. package/dist/tasks/utils.d.ts.map +1 -0
  244. package/dist/tasks/utils.js +311 -0
  245. package/dist/tasks/utils.js.map +1 -0
  246. package/dist/tasks/watcher.d.ts +13 -0
  247. package/dist/tasks/watcher.d.ts.map +1 -0
  248. package/dist/tasks/watcher.js +255 -0
  249. package/dist/tasks/watcher.js.map +1 -0
  250. package/dist/tasks/worker.d.ts +28 -0
  251. package/dist/tasks/worker.d.ts.map +1 -0
  252. package/dist/tasks/worker.js +326 -0
  253. package/dist/tasks/worker.js.map +1 -0
  254. package/dist/utils/index.d.ts +3 -0
  255. package/dist/utils/index.d.ts.map +1 -0
  256. package/dist/utils/index.js +3 -0
  257. package/dist/utils/index.js.map +1 -0
  258. package/dist/utils/schema.d.ts +79 -0
  259. package/dist/utils/schema.d.ts.map +1 -0
  260. package/dist/utils/schema.js +41 -0
  261. package/dist/utils/schema.js.map +1 -0
  262. package/dist/utils/service.d.ts +32 -0
  263. package/dist/utils/service.d.ts.map +1 -0
  264. package/dist/utils/service.js +384 -0
  265. package/dist/utils/service.js.map +1 -0
  266. package/docs/SDK_SPEC.md +1645 -0
  267. package/infra/firestore.base.indexes.json +138 -0
  268. package/infra/firestore.base.rules +152 -0
  269. package/infra/storage.base.rules +8 -0
  270. package/package.json +59 -13
  271. package/src/ai/index.ts +2 -0
  272. package/src/ai/schema.ts +64 -0
  273. package/src/ai/service.ts +317 -0
  274. package/src/ai/utils.ts +38 -0
  275. package/src/attachments/index.ts +3 -0
  276. package/src/attachments/routes.ts +28 -0
  277. package/src/attachments/schema.ts +45 -0
  278. package/src/attachments/service.ts +315 -0
  279. package/src/attachments/utils.ts +115 -0
  280. package/src/auth/index.ts +3 -0
  281. package/src/auth/oidc.ts +419 -0
  282. package/src/auth/recovery.ts +365 -0
  283. package/src/auth/routes.ts +142 -0
  284. package/src/auth/schema.ts +181 -0
  285. package/src/auth/service.ts +183 -0
  286. package/src/auth/session.ts +414 -0
  287. package/src/auth/utils.ts +106 -0
  288. package/src/chat/context.ts +310 -0
  289. package/src/chat/index.ts +3 -0
  290. package/src/chat/routes.ts +264 -0
  291. package/src/chat/schema.ts +295 -0
  292. package/src/chat/service.ts +360 -0
  293. package/src/chat/stream.ts +481 -0
  294. package/src/chat/utils.ts +370 -0
  295. package/src/cli/builder.ts +93 -0
  296. package/src/cli/deployer.ts +184 -0
  297. package/src/cli/dev-server.ts +77 -0
  298. package/src/cli/env.ts +89 -0
  299. package/src/cli/init.ts +125 -0
  300. package/src/config.ts +447 -0
  301. package/src/db/index.ts +2 -0
  302. package/src/db/schema.ts +409 -0
  303. package/src/db/service.ts +477 -0
  304. package/src/db/utils.ts +250 -0
  305. package/src/emails/index.ts +3 -0
  306. package/src/emails/routes.ts +64 -0
  307. package/src/emails/schema.ts +239 -0
  308. package/src/emails/service.ts +488 -0
  309. package/src/emails/utils.ts +449 -0
  310. package/src/files/index.ts +3 -0
  311. package/src/files/routes.ts +44 -0
  312. package/src/files/schema.ts +76 -0
  313. package/src/files/service.ts +238 -0
  314. package/src/files/utils.ts +77 -0
  315. package/src/index.ts +425 -0
  316. package/src/payments/billing.ts +488 -0
  317. package/src/payments/index.ts +3 -0
  318. package/src/payments/routes.ts +92 -0
  319. package/src/payments/schema.ts +401 -0
  320. package/src/payments/service.ts +445 -0
  321. package/src/payments/utils.ts +472 -0
  322. package/src/router/guard.ts +319 -0
  323. package/src/router/index.ts +2 -0
  324. package/src/router/schema.ts +458 -0
  325. package/src/router/service.ts +453 -0
  326. package/src/tasks/index.ts +11 -0
  327. package/src/tasks/routes.ts +230 -0
  328. package/src/tasks/schema.ts +310 -0
  329. package/src/tasks/service.ts +254 -0
  330. package/src/tasks/steps.ts +472 -0
  331. package/src/tasks/utils.ts +445 -0
  332. package/src/tasks/watcher.ts +307 -0
  333. package/src/tasks/worker.ts +461 -0
  334. package/src/utils/index.ts +2 -0
  335. package/src/utils/schema.ts +69 -0
  336. package/src/utils/service.ts +461 -0
  337. package/tests/e2e.test.ts +2531 -0
  338. package/tsconfig.base.json +12 -0
  339. package/README.md +0 -2
  340. package/index.d.ts +0 -1
  341. package/index.js +0 -1
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/ai/schema.ts", "../src/ai/service.ts", "../src/ai/utils.ts", "../src/attachments/schema.ts", "../src/config.ts", "../src/files/schema.ts", "../src/db/schema.ts", "../src/db/service.ts", "../src/db/utils.ts", "../src/files/utils.ts", "../src/files/service.ts", "../src/files/routes.ts", "../src/attachments/utils.ts", "../src/attachments/service.ts", "../src/attachments/routes.ts", "../src/auth/schema.ts", "../src/auth/oidc.ts", "../src/auth/utils.ts", "../src/auth/recovery.ts", "../src/auth/session.ts", "../src/auth/service.ts", "../src/auth/routes.ts", "../src/chat/schema.ts", "../src/chat/service.ts", "../src/chat/context.ts", "../src/chat/utils.ts", "../src/chat/stream.ts", "../src/chat/routes.ts", "../src/emails/schema.ts", "../src/emails/utils.ts", "../src/emails/service.ts", "../src/emails/routes.ts", "../src/payments/schema.ts", "../src/payments/utils.ts", "../src/payments/billing.ts", "../src/payments/service.ts", "../src/payments/routes.ts", "../src/router/schema.ts", "../src/router/service.ts", "../src/tasks/schema.ts", "../src/utils/schema.ts", "../src/utils/service.ts", "../src/tasks/service.ts", "../src/tasks/utils.ts", "../src/tasks/steps.ts", "../src/tasks/watcher.ts", "../src/tasks/worker.ts", "../src/tasks/routes.ts", "../src/router/guard.ts", "../src/cli/env.ts"],
4
+ "sourcesContent": ["import { AsyncLocalStorage } from 'node:async_hooks'\nimport { AiService } from './ai'\nimport {\n AttachmentsService,\n defineAttachmentTypes,\n getRegisteredAttachmentTypes,\n processAttachmentsInput,\n processAttachmentsOutput,\n processedAttachment,\n registerAttachmentTypes,\n scanAttachmentInput,\n scanAttachmentOutput\n} from './attachments'\nimport { AuthService } from './auth'\nimport {\n ChatService,\n defineAgent,\n defineAgents,\n defineContext,\n openaiCompletionsBody,\n streamChatBody\n} from './chat'\nimport {\n CORE_CONFIG,\n defineConfig,\n type AppBindings,\n type DbRole\n} from './config'\nimport {\n DbService,\n defineCollection,\n defineCollections,\n entryId,\n fileRef,\n fileScan,\n fileScanError,\n registerCollections,\n unregisterCollections,\n type EntryId\n} from './db'\nimport {\n EmailsService,\n clearEmailTemplates,\n defineEmailTemplates,\n emailAttachmentInputSchema,\n emailLogStatusSchema,\n emailLogsQuerySchema,\n emailWebhookParamsSchema,\n getEmailTemplate,\n getRegisteredEmailTemplates,\n registerEmailTemplates,\n sendBatchEmailInputSchema,\n sendBatchEmailResultSchema,\n sendEmailInputSchema,\n sendEmailResultSchema\n} from './emails'\nimport { FilesService, fileBody, fileType, signedUploadInput } from './files'\nimport {\n PaymentsService, cancelSubscriptionInput, changeTierInput, chargeResultSchema, checkoutSessionResultSchema,\n clearPaymentDefinitions, createCheckoutInput, createInvoiceInput, createPaymentLinkInput,\n customerBillingSummarySchema, definePlans, defineProducts, directChargeInput, getPlanDefinition,\n getProductDefinition, getRegisteredPlans, getRegisteredProducts, invoiceResultSchema, paymentLinkResultSchema,\n paymentWebhookParamsSchema, quotaCheckResultSchema, recordUsageInput, registerPlans, registerProducts,\n subscribeInput, subscribeResultSchema, subscriptionRecordSchema, usageStatusResultSchema, usageSummarySchema\n} from './payments'\nimport {\n CORE_ROUTE_DEFAULTS, RouterService, defineRoute, defineRouteOverrides, defineRoutes, type CoreAppInit\n} from './router'\nimport { TasksService, type StepRunner } from './tasks'\nimport { ErrorsService, ResilienceService, errorBodySchema } from './utils'\n\nexport interface CoreRuntimeState {\n env: AppBindings\n userId: EntryId\n role: DbRole\n step?: StepRunner\n}\n\nconst coreStorage = new AsyncLocalStorage<CoreRuntimeState>()\n\nconst runWithCore = <T>(state: CoreRuntimeState, fn: () => Promise<T>): Promise<T> =>\n coreStorage.run(state, fn)\n\nconst getActiveCoreState = (): CoreRuntimeState | undefined => coreStorage.getStore()\n\nconst buildDefaultEnvBindings = (isDev = false): AppBindings => ({\n SDK_API_KEY: process.env.SDK_API_KEY ?? '',\n MISTRAL_API_KEY: process.env.MISTRAL_API_KEY ?? '',\n TYPESAFE_API_KEY: process.env.TYPESAFE_API_KEY ?? '',\n JINA_API_KEY: process.env.JINA_API_KEY ?? '',\n WEB_API_KEY: process.env.WEB_API_KEY ?? '',\n RESEND_API_KEY: process.env.RESEND_API_KEY ?? '',\n SENDGRID_API_KEY: process.env.SENDGRID_API_KEY ?? '',\n EMAIL_WEBHOOK_SECRET: process.env.EMAIL_WEBHOOK_SECRET ?? '',\n EMAIL_SANDBOX_WEBHOOK_SECRET: process.env.EMAIL_SANDBOX_WEBHOOK_SECRET ?? '',\n STRIPE_API_KEY: process.env.STRIPE_API_KEY ?? '',\n STRIPE_SANDBOX_API_KEY: process.env.STRIPE_SANDBOX_API_KEY ?? '',\n STRIPE_WEBHOOK_SECRET: process.env.STRIPE_WEBHOOK_SECRET ?? '',\n STRIPE_SANDBOX_WEBHOOK_SECRET: process.env.STRIPE_SANDBOX_WEBHOOK_SECRET ?? '',\n DODO_API_KEY: process.env.DODO_API_KEY ?? '',\n DODO_SANDBOX_API_KEY: process.env.DODO_SANDBOX_API_KEY ?? '',\n DODO_WEBHOOK_SECRET: process.env.DODO_WEBHOOK_SECRET ?? '',\n DODO_SANDBOX_WEBHOOK_SECRET: process.env.DODO_SANDBOX_WEBHOOK_SECRET ?? '',\n isDev\n})\n\nexport class Core {\n readonly #explicitState?: CoreRuntimeState\n readonly #resilience: ResilienceService\n readonly #router: RouterService\n readonly #db: DbService\n readonly #attachments: AttachmentsService\n readonly #auth: AuthService\n readonly #chat: ChatService\n readonly #tasks: TasksService\n readonly #emails: EmailsService\n readonly #payments: PaymentsService\n\n readonly errors: ErrorsService\n readonly db: Omit<DbService, 'internals'>\n readonly files: FilesService\n readonly ai: AiService\n readonly attachments: Omit<AttachmentsService, 'internals'>\n readonly auth: Omit<AuthService, 'internals'>\n readonly chat: Omit<ChatService, 'internals'>\n readonly tasks: Omit<TasksService, 'internals'>\n readonly emails: Omit<EmailsService, 'internals'>\n readonly payments: Omit<PaymentsService, 'internals'>\n\n constructor(state?: CoreRuntimeState) {\n this.#explicitState = state\n this.errors = new ErrorsService()\n this.#resilience = new ResilienceService(this)\n this.#db = new DbService(this)\n this.db = this.#db\n this.files = new FilesService(this)\n this.ai = new AiService(this)\n this.#attachments = new AttachmentsService(this)\n this.attachments = this.#attachments\n this.#auth = new AuthService(this)\n this.auth = this.#auth\n this.#chat = new ChatService(this)\n this.chat = this.#chat\n this.#tasks = new TasksService(this)\n this.tasks = this.#tasks\n this.#emails = new EmailsService(this)\n this.emails = this.#emails\n this.#payments = new PaymentsService(this)\n this.payments = this.#payments\n this.#router = new RouterService(this)\n }\n\n get #state(): CoreRuntimeState {\n if (this.#explicitState) return this.#explicitState\n const active = coreStorage.getStore()\n if (active) return active\n const wfStore = this.#tasks.internals.getActiveWorkflowStore()\n const isDevDefault =\n !process.env.K_SERVICE ||\n process.env.K_SERVICE.endsWith('-dev') ||\n process.env.NODE_ENV === 'development' ||\n process.env.NODE_ENV === 'test'\n return {\n env: wfStore?.env ?? buildDefaultEnvBindings(isDevDefault),\n userId: CORE_CONFIG.auth.adminUserId,\n role: 'admin',\n ...(wfStore?.step ? { step: wfStore.step } : {})\n }\n }\n\n get env(): AppBindings {\n return this.#state.env\n }\n get userId(): EntryId {\n return this.#state.userId\n }\n get role(): DbRole {\n return this.#state.role\n }\n get caller(): { userId: EntryId; role: DbRole } {\n return { userId: this.userId, role: this.role }\n }\n get step(): StepRunner {\n return this.#state.step ?? this.#tasks.internals.useStep()\n }\n\n readonly config = CORE_CONFIG\n readonly createApp = (opts?: CoreAppInit) => this.#router.createApp(opts)\n\n readonly define = {\n config: defineConfig,\n route: defineRoute,\n routes: defineRoutes,\n routeOverrides: defineRouteOverrides,\n collection: defineCollection,\n collections: defineCollections,\n agent: defineAgent,\n agents: defineAgents,\n context: defineContext,\n attachmentTypes: defineAttachmentTypes,\n emailTemplates: defineEmailTemplates,\n plans: definePlans,\n products: defineProducts\n }\n\n readonly schemas = {\n entryId,\n fileRef,\n fileScan,\n fileScanError,\n fileBody,\n fileType,\n signedUploadInput,\n processedAttachment,\n scanAttachmentInput,\n scanAttachmentOutput,\n processAttachmentsInput,\n processAttachmentsOutput,\n streamChatBody,\n openaiCompletionsBody,\n errorBodySchema,\n emailLogStatusSchema,\n emailAttachmentInputSchema,\n sendEmailInputSchema,\n sendBatchEmailInputSchema,\n emailLogsQuerySchema,\n emailWebhookParamsSchema,\n sendEmailResultSchema,\n sendBatchEmailResultSchema,\n createCheckoutInput,\n createPaymentLinkInput,\n createInvoiceInput,\n directChargeInput,\n subscribeInput,\n changeTierInput,\n cancelSubscriptionInput,\n recordUsageInput,\n paymentWebhookParamsSchema,\n checkoutSessionResultSchema,\n paymentLinkResultSchema,\n invoiceResultSchema,\n chargeResultSchema,\n subscribeResultSchema,\n subscriptionRecordSchema,\n customerBillingSummarySchema,\n usageStatusResultSchema,\n usageSummarySchema,\n quotaCheckResultSchema\n }\n\n get internals() {\n return {\n resilience: this.#resilience,\n context: {\n run: runWithCore,\n getState: getActiveCoreState,\n routeDefaults: CORE_ROUTE_DEFAULTS,\n getMcpTools: this.#chat.internals.getMcpTools,\n authenticateRequest: this.#router.authenticateRequest,\n applyRateLimit: this.#router.applyRateLimit,\n enforceAgentAccess: this.#chat.internals.enforceAgentAccess,\n stageAndScanAttachments: this.#chat.internals.stageAndScanAttachments,\n startChatStreamTurn: this.#chat.internals.startChatStreamTurn,\n saveChat: this.#chat.internals.saveChat,\n streamChatSse: this.#chat.internals.streamChatSse,\n scanShortCircuit: this.#attachments.internals.scanShortCircuit\n },\n registry: {\n registerCollections,\n unregisterCollections,\n ensureFirebaseApp: this.#db.internals.ensureFirebaseApp,\n getGcpAccessToken: this.#db.internals.getGcpAccessToken,\n cascadeEraseUserCollections: this.#db.internals.cascadeEraseUserCollections,\n getAttachmentTypes: getRegisteredAttachmentTypes,\n registerAttachmentTypes,\n registerEmailTemplates,\n clearEmailTemplates,\n getEmailTemplate,\n getRegisteredEmailTemplates,\n registerPlans,\n registerProducts,\n clearPaymentDefinitions,\n getPlanDefinition,\n getProductDefinition,\n getRegisteredPlans,\n getRegisteredProducts,\n registerAgents: this.#chat.internals.registerAgents,\n getRegisteredAgents: this.#chat.internals.getRegisteredAgents,\n getAgentRegistry: this.#chat.internals.getAgentRegistry,\n registerWorkflowTool: this.#chat.internals.registerWorkflowTool,\n clearWorkflowTools: this.#chat.internals.clearWorkflowTools,\n registerContextCatalog: this.#chat.internals.registerContextCatalog\n },\n workflows: this.#tasks.internals,\n auth: this.#auth.internals,\n emails: this.#emails.internals,\n payments: this.#payments.internals\n }\n }\n}\n\nexport type CoreInternals = Core['internals']\n\nexport const core = new Core()\n\nexport namespace core {\n export namespace types {\n export type AppBindings = import('./config').AppBindings\n export type DbAction = import('./config').DbAction\n export type DbRole = import('./config').DbRole\n export type CoreAppInit = import('./router').CoreAppInit\n export type CoreInternals = import('./index').CoreInternals\n export type CoreRuntimeState = import('./index').CoreRuntimeState\n export type CoreRouteOverrides = import('./router').CoreRouteOverrides\n export type RouteConfig<I = any, O = any, P = Record<string, string>, Q = Record<string, string>> =\n import('./router').RouteConfig<I, O, P, Q>\n export type RouteExecutionContext<I = unknown, P = Record<string, string>, Q = Record<string, string>> =\n import('./router').RouteExecutionContext<I, P, Q>\n export type RouteMode = import('./router').RouteMode\n export type RoutesIntrospectionResponse = import('./tasks').RoutesIntrospectionResponse\n export type CollectionDefinition<S extends import('zod').ZodObject<any> = import('zod').ZodObject<any>> =\n import('./db').CollectionDefinition<S>\n export type CollectionName = import('./db').CollectionName\n export type DbListOptions<T = Record<string, unknown>> = import('./db').DbListOptions<T>\n export type DbListPage<T> = import('./db').DbListPage<T>\n export type EntryId = import('./db').EntryId\n export type FileRef = import('./db').FileRef\n export type FileScan = import('./db').FileScan\n export type InsertData<N extends import('./db').CollectionName> = import('./db').InsertData<N>\n export type PaginatedList<T> = import('./db').PaginatedList<T>\n export type SelectModel<N extends import('./db').CollectionName> =\n import('./db').SelectModel<N>\n export type UpdateData<N extends import('./db').CollectionName> = import('./db').UpdateData<N>\n export type AttachmentTypesMap = import('./attachments').AttachmentTypesMap\n export type ProcessAttachmentsInput = import('./attachments').ProcessAttachmentsInput\n export type ProcessAttachmentsOutput = import('./attachments').ProcessAttachmentsOutput\n export type ProcessedAttachment = import('./attachments').ProcessedAttachment\n export type ScanAttachmentInput = import('./attachments').ScanAttachmentInput\n export type ScanAttachmentOutput = import('./attachments').ScanAttachmentOutput\n export type FileBody = import('./files').FileBody\n export type FileType = import('./files').FileType\n export type SignedDownloadUrlResult = import('./files').SignedDownloadUrlResult\n export type SignedUploadInput = import('./files').SignedUploadInput\n export type SignedUploadUrlResult = import('./files').SignedUploadUrlResult\n export type AuthUser = import('./auth').AuthUser\n export type AgentConfig = import('./chat').AgentConfig\n export type AskAgentOptions = import('./chat').AskAgentOptions\n export type RunAgentOptions = import('./chat').RunAgentOptions\n export type GetContextOptions = import('./chat').GetContextOptions\n export type HybridRetrievalOptions = import('./chat').HybridRetrievalOptions\n export type HybridRetrievalResult = import('./chat').HybridRetrievalResult\n export type ChatMessagePublic = import('./chat').ChatMessagePublic\n export type ContextEntry = import('./chat').ContextEntry\n export type ContextItemSpec = import('./chat').ContextItemSpec\n export type UserContext = import('./chat').UserContext\n export type UserContextResolver = import('./chat').UserContextResolver\n export type StepRunner = import('./tasks').StepRunner\n export type TaskStatus = import('./tasks').TaskStatus\n export type TaskStatusRecord<O = unknown> = import('./tasks').TaskStatusRecord<O>\n export type WorkflowContext = import('./tasks').WorkflowContext\n export type WorkflowRuntimeEntry = import('./tasks').WorkflowRuntimeEntry\n export type AiUsageSummary = import('./ai').AiUsageSummary\n export type DecideResult = import('./ai').DecideResult\n export type JevQuestion = import('./ai').JevQuestion\n export type AiGenerateOptions<O = string> = import('./ai').AiGenerateOptions<O>\n export type AiGenerateResult<O = string> = import('./ai').AiGenerateResult<O>\n export type VisionOptions = import('./ai').VisionOptions\n export type VisionResult = import('./ai').VisionResult\n export type ErrorBody = import('./utils').ErrorBody\n export type CircuitBreakerKey = import('./utils').CircuitBreakerKey\n export type CircuitBreakerRecord = import('./utils').CircuitBreakerRecord\n export type CircuitBreakerStateName = import('./utils').CircuitBreakerStateName\n export type SingleflightOptions = import('./utils').SingleflightOptions\n export type EmailProvider = import('./config').EmailProvider\n export type AuthEmailPurpose = import('./config').AuthEmailPurpose\n export type AuthEmailVariables = import('./config').AuthEmailVariables\n export type AuthFlowEmailHook = import('./config').AuthFlowEmailHook\n export type AuthFlowConfigSpec = import('./config').AuthFlowConfigSpec\n export type EmailsConfig = import('./config').EmailsConfig\n export type EmailTemplateDefinition<S extends import('zod').ZodObject<any> = import('zod').ZodObject<any>> =\n import('./emails').EmailTemplateDefinition<S>\n export type EmailTemplatesMap = import('./emails').EmailTemplatesMap\n export type EmailAttachmentInput = import('./emails').EmailAttachmentInput\n export type EmailCallOptions = import('./emails').EmailCallOptions\n export type SendEmailInput = import('./emails').SendEmailInput\n export type SendBatchEmailInput = import('./emails').SendBatchEmailInput\n export type SendEmailResult = import('./emails').SendEmailResult\n export type SendBatchEmailResult = import('./emails').SendBatchEmailResult\n export type EmailLogStatus = import('./emails').EmailLogStatus\n export type EmailLogsQuery = import('./emails').EmailLogsQuery\n export type PaymentProvider = import('./payments').PaymentProvider\n export type PaymentsConfig = import('./config').PaymentsConfig\n export type PlanDefinition = import('./payments').PlanDefinition\n export type PlansMap = import('./payments').PlansMap\n export type ProductDefinition = import('./payments').ProductDefinition\n export type ProductsMap = import('./payments').ProductsMap\n export type PaymentCallOptions = import('./payments').PaymentCallOptions\n export type CreateCheckoutInput = import('./payments').CreateCheckoutInput\n export type CheckoutSessionResult = import('./payments').CheckoutSessionResult\n export type CreatePaymentLinkInput = import('./payments').CreatePaymentLinkInput\n export type PaymentLinkResult = import('./payments').PaymentLinkResult\n export type CreateInvoiceInput = import('./payments').CreateInvoiceInput\n export type InvoiceResult = import('./payments').InvoiceResult\n export type DirectChargeInput = import('./payments').DirectChargeInput\n export type ChargeResult = import('./payments').ChargeResult\n export type SubscribeInput = import('./payments').SubscribeInput\n export type SubscribeResult = import('./payments').SubscribeResult\n export type ChangeTierInput = import('./payments').ChangeTierInput\n export type CancelSubscriptionInput = import('./payments').CancelSubscriptionInput\n export type SubscriptionRecord = import('./payments').SubscriptionRecord\n export type CustomerBillingSummary = import('./payments').CustomerBillingSummary\n export type UsageStatusResult = import('./payments').UsageStatusResult\n export type UsageSummary = import('./payments').UsageSummary\n export type QuotaCheckResult = import('./payments').QuotaCheckResult\n export type RecordUsageInput = import('./payments').RecordUsageInput\n }\n}\n\nexport const useCore = (): Core => {\n const active = coreStorage.getStore()\n return active ? new Core(active) : core\n}\n\nexport { CORE_CONFIG }\nexport { getSecrets, loadGcpSecrets } from './cli/env'\n", "import { z } from 'zod'\n\nexport type JevQuestion =\n | { type: 'noul'; instructions: string; criteria?: { true: string; false: string } }\n | { type: 'choice'; instructions: string; criteria: Record<string, string> }\n | { type: 'score'; instructions: string; criteria: string[] }\n\nexport const answerSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('noul'), noul: z.number().min(0).max(1) }),\n z.object({\n type: z.literal('choice'),\n choice: z.string(),\n probabilities: z.record(z.string(), z.number()),\n confidence: z.number()\n }),\n z.object({\n type: z.literal('score'),\n score: z.number(),\n probabilities: z.record(z.string(), z.number()),\n confidence: z.number()\n })\n])\n\nexport const envelopeSchema = z.object({ model: z.string(), answers: z.record(z.string(), answerSchema) })\n\nexport interface AiUsageSummary {\n model: string\n inputTokens: number\n outputTokens: number\n totalTokens: number\n pages?: number\n}\n\nexport type JevAnswer = z.infer<typeof answerSchema>\nexport type DecideResult = z.infer<typeof envelopeSchema> & { usage?: AiUsageSummary }\n\nexport interface VisionOptions {\n schema?: Record<string, unknown>\n prompt?: string\n fallbackVision?: boolean\n signal?: AbortSignal\n}\n\nexport interface VisionResult {\n markdown: string\n annotation: Record<string, unknown>\n usage?: AiUsageSummary\n}\n\nexport interface AiGenerateOptions<O = string> {\n model?: string\n system?: string\n schema?: z.ZodType<O>\n signal?: AbortSignal\n}\n\nexport interface AiGenerateResult<O = string> {\n text: string\n output: O\n usage: unknown\n}\n\nexport const DEFAULT_EXTRACTION_PROMPT =\n 'Extract the document fields as JSON matching the schema. Transcribe values exactly as printed, translate non-English into English, transliterate names, use Western digits. Empty string if not visible.'\n", "import { createGoogleVertex } from '@ai-sdk/google-vertex'\nimport { createVertexAnthropic } from '@ai-sdk/google-vertex/anthropic'\nimport { HTTPClient, Mistral } from '@mistralai/mistralai'\nimport { TypeSafeClient } from '@typesafe-ai/sdk'\nimport { embed, generateText, Output, type LanguageModel, type ModelMessage } from 'ai'\nimport type { Core } from '../index'\nimport {\n DEFAULT_EXTRACTION_PROMPT,\n envelopeSchema,\n type AiGenerateOptions,\n type AiGenerateResult,\n type AiUsageSummary,\n type DecideResult,\n type JevQuestion,\n type VisionOptions,\n type VisionResult\n} from './schema'\nimport { formatOcrPages, normalizeUsage } from './utils'\n\nlet cachedVertexKey = ''\nlet cachedVertexAnthropic: ReturnType<typeof createVertexAnthropic> | undefined\nlet cachedVertexEmbedding: ReturnType<typeof createGoogleVertex> | undefined\n\nlet cachedJevKey = ''\nlet cachedJev: TypeSafeClient | undefined\n\nlet cachedMistralKey = ''\nlet cachedMistral: Mistral | undefined\n\nexport class AiService {\n readonly #core: Core\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n }\n\n #vertexProviders = () => {\n const project = this.#core.config.gcpProject\n const location = this.#core.config.models.vertexLocation\n const key = `${project}:${location}`\n if (!cachedVertexAnthropic || !cachedVertexEmbedding || cachedVertexKey !== key) {\n cachedVertexKey = key\n cachedVertexAnthropic = createVertexAnthropic({ project, location })\n cachedVertexEmbedding = createGoogleVertex({\n project,\n location: location === 'global' ? 'us-central1' : location\n })\n }\n return { vertexAnthropic: cachedVertexAnthropic, vertexEmbeddingProvider: cachedVertexEmbedding }\n }\n\n languageModel = (modelId: string = this.#core.config.models.vertex): LanguageModel =>\n this.#vertexProviders().vertexAnthropic(modelId)\n\n #jevClient = (apiKey: string): TypeSafeClient =>\n cachedJev && cachedJevKey === apiKey\n ? cachedJev\n : ((cachedJevKey = apiKey),\n (cachedJev = new TypeSafeClient({ apiKey, defaultModel: this.#core.config.models.jev })))\n\n #mistralClient = (): Mistral => {\n const apiKey = this.#core.env.MISTRAL_API_KEY\n if (cachedMistral && cachedMistralKey === apiKey) return cachedMistral\n const httpClient = new HTTPClient()\n httpClient.addHook('response', async (res) => {\n const limit = Number(res.headers.get('x-ratelimit-limit-ocr-pages-minute') ?? '0')\n const remHeader = res.headers.get('x-ratelimit-remaining-ocr-pages-minute')\n const remaining = res.status === 429 ? 0 : remHeader !== null ? Number(remHeader) : undefined\n if (limit > 0 || remaining !== undefined) {\n await this.#core.internals.resilience.syncLimit('mistral', remaining, limit)\n }\n })\n cachedMistralKey = apiKey\n return (cachedMistral = new Mistral({\n apiKey,\n httpClient,\n retryConfig: {\n strategy: 'backoff',\n backoff: { initialInterval: 5000, maxInterval: 20000, exponent: 1.5, maxElapsedTime: 90000 },\n retryConnectionErrors: true\n }\n }))\n }\n\n describeImage = async (documentUrl: string, signal?: AbortSignal): Promise<string> =>\n this.#core.internals.resilience.circuitBreaker('vertex', async () => {\n await this.#core.internals.resilience.acquireLimit('ai')\n const match = /^data:([^;,]+);base64,(.+)$/.exec(documentUrl)\n const mediaType = match?.[1] ?? 'image/jpeg'\n const base64 = match?.[2] ?? documentUrl\n const modelId = this.#core.config.models.vertex\n const { text } = await generateText({\n model: this.languageModel(modelId),\n abortSignal: signal,\n messages: [\n {\n role: 'user',\n content: [\n { type: 'file', data: base64, mediaType },\n { type: 'text', text: 'Describe what is illustrated on this image concisely in markdown.' }\n ]\n }\n ]\n })\n const trimmed = text.trim()\n if (!trimmed) throw new Error('vision model returned empty description')\n return trimmed\n })\n\n #vertexVisionFallback = async (documentUrl: string, opts?: VisionOptions): Promise<VisionResult> => {\n const markdown = await this.describeImage(documentUrl, opts?.signal)\n let annotation: Record<string, unknown> = {}\n const modelId = this.#core.config.models.vertex\n let usage: AiUsageSummary | undefined\n if (opts?.schema) {\n await this.#core.internals.resilience.acquireLimit('ai')\n const match = /^data:([^;,]+);base64,(.+)$/.exec(documentUrl)\n const mediaType = match?.[1] ?? 'application/pdf'\n const base64 = match?.[2] ?? documentUrl\n const res = await this.#core.internals.resilience.circuitBreaker('vertex', () =>\n generateText({\n model: this.languageModel(modelId),\n abortSignal: opts.signal,\n messages: [\n {\n role: 'user',\n content: [\n { type: 'file', data: base64, mediaType },\n {\n type: 'text',\n text: `${opts.prompt ?? DEFAULT_EXTRACTION_PROMPT}\\n\\nJSON Schema:\\n${JSON.stringify(opts.schema)}\\n\\nRespond with ONLY a valid JSON object.`\n }\n ]\n }\n ]\n })\n )\n usage = normalizeUsage(modelId, res.usage)\n const jsonMatch = /\\{[\\s\\S]*\\}/.exec(res.text)\n if (jsonMatch?.[0]) {\n try {\n annotation = JSON.parse(jsonMatch[0]) as Record<string, unknown>\n } catch {}\n }\n }\n return { markdown, annotation, ...(usage ? { usage } : {}) }\n }\n\n vision = async (documentUrl: string, opts?: VisionOptions): Promise<VisionResult> => {\n const isImage = documentUrl.startsWith('data:image')\n const hasSchema = Boolean(opts?.schema)\n const allowFallback = opts?.fallbackVision !== false\n await this.#core.internals.payments.enforceAiQuota()\n\n return this.#core.internals.resilience.circuitBreaker(\n 'mistral',\n async () => {\n await this.#core.internals.resilience.acquireLimit('mistral')\n const modelId = this.#core.config.models.mistralOcr\n const result = await this.#mistralClient().ocr.process(\n {\n model: modelId,\n confidenceScoresGranularity: 'block',\n pages: !hasSchema && !isImage ? Array.from({ length: 10 }, (_, i) => i) : undefined,\n document: isImage\n ? { type: 'image_url' as const, imageUrl: documentUrl }\n : { type: 'document_url' as const, documentUrl },\n ...(opts?.schema && {\n documentAnnotationFormat: {\n type: 'json_schema' as const,\n jsonSchema: { name: 'fields', schemaDefinition: opts.schema, strict: true }\n },\n documentAnnotationPrompt: opts.prompt ?? DEFAULT_EXTRACTION_PROMPT\n })\n },\n opts?.signal ? { fetchOptions: { signal: opts.signal } } : undefined\n )\n const pagesProcessed = result.usageInfo?.pagesProcessed ?? result.pages.length\n if (pagesProcessed > 1) {\n await this.#core.internals.resilience.chargeLimit('mistral', pagesProcessed - 1)\n }\n let markdown = formatOcrPages(result.pages)\n const annotation = JSON.parse(result.documentAnnotation ?? '{}') as Record<string, unknown>\n\n if (!markdown && (opts?.fallbackVision ?? !hasSchema)) {\n markdown = await this.describeImage(documentUrl, opts?.signal)\n }\n\n const usage = normalizeUsage(modelId, null, pagesProcessed)\n await this.#core.internals.payments.trackAiUsage({\n model: usage.model,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens,\n source: 'vision'\n })\n return { markdown, annotation, usage }\n },\n allowFallback ? () => this.#vertexVisionFallback(documentUrl, opts) : undefined,\n { isDev: this.#core.env.isDev }\n )\n }\n\n decide = async (state: unknown, questions: Record<string, JevQuestion>): Promise<DecideResult> =>\n this.#core.internals.resilience.circuitBreaker(\n 'jev',\n async () => {\n await this.#core.internals.payments.enforceAiQuota()\n await this.#core.internals.resilience.acquireLimit('jev')\n const raw = await this.#jevClient(this.#core.env.TYPESAFE_API_KEY).systemOne({\n state: state as never,\n questions: questions as never\n })\n const parsed = envelopeSchema.safeParse(raw)\n if (parsed.success && Object.keys(questions).every((q) => parsed.data.answers[q]?.type === questions[q]?.type)) {\n const usage = normalizeUsage(parsed.data.model || this.#core.config.models.jev, null)\n await this.#core.internals.payments.trackAiUsage({\n model: usage.model,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens,\n source: 'decide'\n })\n return {\n ...parsed.data,\n usage\n }\n }\n throw new Error('Jev decision returned no valid answer envelope')\n },\n undefined,\n { isDev: this.#core.env.isDev }\n )\n\n generate = async <O = string>(\n promptOrMessages: string | ModelMessage[],\n opts?: AiGenerateOptions<O>\n ): Promise<AiGenerateResult<O>> =>\n this.#core.internals.resilience.circuitBreaker('vertex', async () => {\n await this.#core.internals.payments.enforceAiQuota()\n await this.#core.internals.resilience.acquireLimit('ai')\n const modelId = opts?.model ?? this.#core.config.models.vertex\n const model = this.languageModel(modelId)\n const messages: ModelMessage[] =\n typeof promptOrMessages === 'string'\n ? [{ role: 'user', content: [{ type: 'text', text: promptOrMessages }] }]\n : promptOrMessages\n\n if (opts?.schema) {\n const res = await generateText({\n model,\n system: opts.system,\n messages,\n output: Output.object({ schema: opts.schema }),\n abortSignal: opts.signal\n })\n const norm = normalizeUsage(modelId, res.usage)\n await this.#core.internals.payments.trackAiUsage({\n model: norm.model,\n inputTokens: norm.inputTokens,\n outputTokens: norm.outputTokens,\n totalTokens: norm.totalTokens,\n source: 'generate'\n })\n return {\n text: res.text,\n output: res.output as O,\n usage: res.usage\n }\n }\n\n const res = await generateText({\n model,\n system: opts?.system,\n messages,\n abortSignal: opts?.signal\n })\n const norm = normalizeUsage(modelId, res.usage)\n await this.#core.internals.payments.trackAiUsage({\n model: norm.model,\n inputTokens: norm.inputTokens,\n outputTokens: norm.outputTokens,\n totalTokens: norm.totalTokens,\n source: 'generate'\n })\n return {\n text: res.text,\n output: res.text as unknown as O,\n usage: res.usage\n }\n })\n\n embed = async (text: string): Promise<number[] | null> => {\n const normalized = text.trim()\n if (normalized.length < 15) return null\n try {\n return await this.#core.internals.resilience.circuitBreaker('vertex', async () => {\n await this.#core.internals.resilience.acquireLimit('ai')\n const embeddingModel = this.#vertexProviders().vertexEmbeddingProvider.textEmbeddingModel(\n this.#core.config.models.vertexEmbedding\n )\n const { embedding } = await embed({\n model: embeddingModel,\n value: normalized.slice(0, 8000),\n dimensions: 768,\n abortSignal: AbortSignal.timeout(15_000),\n providerOptions: {\n vertex: { outputDimensionality: 768 }\n }\n })\n return Array.isArray(embedding) && embedding.length === 768 ? embedding : null\n })\n } catch {\n return null\n }\n }\n}\n", "import type { OCRPageObject } from '@mistralai/mistralai/models/components'\nimport type { AiUsageSummary } from './schema'\n\nexport const formatOcrPages = (pages: OCRPageObject[]): string =>\n pages\n .map((p, i) => {\n const text = p.blocks\n ? p.blocks\n .filter(\n (b) =>\n b.type !== 'image' &&\n ('confidenceScores' in b ? (b.confidenceScores?.averageContentConfidenceScore ?? 1) : 1) >= 0.5\n )\n .map((b) => ('content' in b ? b.content.trim() : ''))\n .filter(Boolean)\n .join('\\n\\n')\n : p.markdown.replace(/!\\[[^\\]]*\\]\\([^)]*\\)/g, '').trim()\n return text ? `### Page ${i + 1}\\n${text}` : ''\n })\n .filter(Boolean)\n .join('\\n\\n')\n\nexport const normalizeUsage = (\n model: string,\n raw?: { inputTokens?: number; outputTokens?: number; totalTokens?: number; tokens?: number } | null,\n pages?: number\n): AiUsageSummary => {\n const inputTokens = raw?.inputTokens ?? raw?.tokens ?? 0\n const outputTokens = raw?.outputTokens ?? 0\n const totalTokens = raw?.totalTokens ?? (inputTokens + outputTokens || (pages ? pages * 1000 : 0))\n return {\n model,\n inputTokens,\n outputTokens,\n totalTokens,\n ...(pages !== undefined ? { pages } : {})\n }\n}\n", "import { z } from 'zod'\nimport { CORE_CONFIG } from '../config'\nimport { fileRef, fileScan } from '../files'\n\nexport const processedAttachment = z.union([\n z.object({ ref: fileRef, scan: fileScan }),\n z.object({ ref: fileRef, error: z.string() })\n])\nexport type ProcessedAttachment = z.infer<typeof processedAttachment>\n\nexport interface AttachmentTypeSpec<S extends z.ZodType = z.ZodType> {\n description: string\n schema: S\n}\nexport type AttachmentTypesMap = Record<string, AttachmentTypeSpec>\n\nexport const defineAttachmentTypes = <T extends AttachmentTypesMap>(types: T): T => types\n\nconst registeredAttachmentTypes: AttachmentTypesMap = {}\n\nexport const registerAttachmentTypes = (types?: AttachmentTypesMap, reset = false): void => {\n if (reset) {\n for (const k of Object.keys(registeredAttachmentTypes)) delete registeredAttachmentTypes[k]\n }\n if (!types) return\n Object.assign(registeredAttachmentTypes, types)\n}\n\nexport const getRegisteredAttachmentTypes = (): AttachmentTypesMap => registeredAttachmentTypes\n\nexport const scanAttachmentInput = z.object({ ref: fileRef, type: z.string().optional() })\nexport const scanAttachmentOutput = fileScan\nexport type ScanAttachmentInput = z.input<typeof scanAttachmentInput>\nexport type ScanAttachmentOutput = z.infer<typeof scanAttachmentOutput>\n\nexport const attachmentInput = z.union([fileRef, scanAttachmentInput])\nexport const processAttachmentsInput = z.object({\n refs: z\n .array(attachmentInput)\n .min(1)\n .refine((arr) => arr.length <= CORE_CONFIG.limits.maxAttachments, 'Too many attachments')\n})\nexport const processAttachmentsOutput = z.object({ attachments: z.array(processedAttachment) })\nexport type ProcessAttachmentsInput = z.input<typeof processAttachmentsInput>\nexport type ProcessAttachmentsOutput = z.infer<typeof processAttachmentsOutput>\n", "import type { Context } from 'hono'\nimport type { Core } from './index'\n\ntry {\n process.loadEnvFile()\n} catch {}\n\nexport type DbRole = 'admin' | 'user' | 'anon'\nexport type DbAction = 'read' | 'write' | 'create' | 'delete' | '*'\nexport type DbAccessScope = 'own' | 'any'\n\nexport type RbacRoleScopes = {\n [Scope in DbAccessScope]?: readonly DbAction[]\n}\n\nexport type RbacConfig = {\n [Role in DbRole]?: RbacRoleScopes\n}\n\nexport const SECRET_NAMES = [\n 'SDK_API_KEY',\n 'MISTRAL_API_KEY',\n 'TYPESAFE_API_KEY',\n 'JINA_API_KEY',\n 'WEB_API_KEY'\n] as const\n\nexport const EMAIL_SECRET_NAMES = [\n 'RESEND_API_KEY',\n 'SENDGRID_API_KEY',\n 'EMAIL_WEBHOOK_SECRET',\n 'EMAIL_SANDBOX_WEBHOOK_SECRET'\n] as const\n\nexport const PAYMENT_SECRET_NAMES = [\n 'STRIPE_API_KEY',\n 'STRIPE_SANDBOX_API_KEY',\n 'STRIPE_WEBHOOK_SECRET',\n 'STRIPE_SANDBOX_WEBHOOK_SECRET',\n 'DODO_API_KEY',\n 'DODO_SANDBOX_API_KEY',\n 'DODO_WEBHOOK_SECRET',\n 'DODO_SANDBOX_WEBHOOK_SECRET'\n] as const\n\nexport interface AppBindings {\n SDK_API_KEY: string\n MISTRAL_API_KEY: string\n TYPESAFE_API_KEY: string\n JINA_API_KEY: string\n WEB_API_KEY: string\n RESEND_API_KEY: string\n SENDGRID_API_KEY: string\n EMAIL_WEBHOOK_SECRET: string\n EMAIL_SANDBOX_WEBHOOK_SECRET: string\n STRIPE_API_KEY: string\n STRIPE_SANDBOX_API_KEY: string\n STRIPE_WEBHOOK_SECRET: string\n STRIPE_SANDBOX_WEBHOOK_SECRET: string\n DODO_API_KEY: string\n DODO_SANDBOX_API_KEY: string\n DODO_WEBHOOK_SECRET: string\n DODO_SANDBOX_WEBHOOK_SECRET: string\n isDev: boolean\n}\n\nexport interface AppEnv {\n Bindings: AppBindings\n Variables: { userId: string; userRole: DbRole }\n}\n\nexport interface RateLimitSpec {\n max: number\n windowMs: number\n keyBy?: 'user' | 'ip' | ((c: Context<AppEnv>) => string)\n}\n\nexport type RateLimitConfig = RateLimitSpec | false\n\nexport type EmailProvider = 'sendgrid' | 'resend' | 'firebase'\n\nexport type AuthTokenPurpose =\n | 'verify_email'\n | 'reset_password'\n | 'verify_recovery_email'\n | 'account_recovery'\n\nexport type AuthEmailPurpose =\n | AuthTokenPurpose\n | 'welcome'\n | 'security_alert'\n\nexport interface TransactionalEmailPayload {\n to: string\n purpose: AuthEmailPurpose\n code: string\n token: string\n expiresInMinutes: number\n userId: string\n}\n\nexport interface AuthEmailVariables {\n appName: string\n userId: string\n email: string\n purpose: AuthEmailPurpose\n code: string\n token: string\n actionUrl: string\n expiresInMinutes: number\n [key: string]: unknown\n}\n\nexport type AuthFlowEmailHook = (\n payload: AuthEmailVariables,\n context: { core: Core; env: AppBindings }\n) => Promise<boolean | Partial<AuthEmailVariables> | void>\n\nexport interface AuthFlowConfigSpec {\n templateId?: string\n subject?: string\n actionPath?: string\n onSend?: AuthFlowEmailHook\n}\n\nexport interface EmailsConfig {\n provider: EmailProvider\n fromEmail: string\n fromName: string\n replyTo?: string\n actionBaseUrl: string\n otpTtlMinutes: number\n recoveryOtpTtlMinutes: number\n maxVerifyAttempts: number\n enforceSuppressionList: boolean\n webhookToleranceSeconds: number\n onAuthEmail?: AuthFlowEmailHook\n authFlows: Record<AuthEmailPurpose, AuthFlowConfigSpec>\n sendgrid: {\n baseUrl: string\n }\n resend: {\n baseUrl: string\n }\n}\n\nexport type PaymentProvider = 'stripe' | 'dodo'\n\nexport type EnvScopedString = string | { prod: string; dev: string }\n\nexport interface PaymentsConfig {\n enabled: boolean\n provider: PaymentProvider\n defaultCurrency: Lowercase<string>\n defaultPlanId: string\n autoTrackAiTokens: boolean\n aiTokenMeterName: string\n webhookToleranceSeconds: number\n urls: {\n successUrl: EnvScopedString\n cancelUrl: EnvScopedString\n returnUrl: EnvScopedString\n }\n dodo: {\n liveBaseUrl: string\n testBaseUrl: string\n }\n stripe: {\n baseUrl: string\n apiVersion: string\n }\n}\n\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends object ? (T[K] extends (...args: any[]) => any ? T[K] : DeepPartial<T[K]>) : T[K]\n}\n\nexport interface CoreConfig {\n appName: string\n gcpProject: string\n region: string\n secrets: readonly string[]\n firestoreDbs: { prod: string; dev: string }\n storageBuckets: { prod: string; dev: string }\n db: {\n rbac: RbacConfig\n }\n context: {\n dir: string\n maxSources: number\n userContextTimeoutMs: number\n }\n serviceAccount: string\n computeAccount: string\n workerUris: { prod: string; dev: string }\n queueBaseNames: { prod: string; dev: string }\n cloudRun: {\n memory: '1GiB' | '2GiB' | '4GiB' | '8GiB'\n cpu: number\n http: { timeoutSeconds: number; concurrency: number; maxInstances: number; invoker: 'public' | 'private' }\n worker: { timeoutSeconds: number; concurrency: number; maxInstances: number }\n }\n tasks: {\n useCloudTasks: boolean\n defaultShardsCount: number\n batchCreateSize: number\n maxAttempts: number\n hedgeAfterMs: number\n heartbeatIntervalMs: number\n heartbeatStaleMs: number\n timeoutMs: number\n ttlMs: number\n scanDeadlineSeconds: number\n defaultDeadlineSeconds: number\n claimCheckThresholdBytes: number\n yieldBudgetRatio: number\n }\n models: {\n vertex: string\n vertexExpert: string\n vertexEmbedding: string\n vertexLocation: string\n mistralOcr: string\n jev: string\n defaultAgentMaxSteps: number\n }\n limits: {\n maxAttachments: number\n maxChatAttachments: number\n chatMessagesLimit: number\n defaultListLimit: number\n maxFileBytes: number\n maxBodyBytes: number\n maxWaitMs: number\n httpUser: RateLimitSpec\n httpIp: RateLimitSpec\n buckets: {\n mistral: { windowMs: number; max: number }\n jev: { windowMs: number; max: number }\n ai: { windowMs: number; max: number }\n workflows: { windowMs: number; max: number }\n firestore: { windowMs: number; max: number }\n storage: { windowMs: number; max: number }\n emails: { windowMs: number; max: number }\n payments: { windowMs: number; max: number }\n }\n }\n auth: {\n sessionCookie: string\n sessionExpiresInMs: number\n tokenCacheTtlMs: number\n tokenCacheMaxSize: number\n adminUserId: string\n allowedOrigins: (string | RegExp)[]\n oauth?: {\n googleClientIds?: string[]\n appleClientIds?: string[]\n }\n }\n emails: EmailsConfig\n payments: PaymentsConfig\n}\n\nconst gcpProject = process.env.GCP_PROJECT ?? ''\nconst region = 'me-central1'\nconst defaultWebBaseUrl = `https://${gcpProject || 'app'}.web.app`\n\nexport const CORE_CONFIG: CoreConfig = {\n appName: gcpProject,\n gcpProject,\n region,\n secrets: [],\n firestoreDbs: { prod: gcpProject, dev: `${gcpProject}-dev` },\n storageBuckets: { prod: `${gcpProject}.firebasestorage.app`, dev: `${gcpProject}-dev` },\n db: {\n rbac: {\n admin: { any: ['*'] },\n user: { own: ['*'] },\n anon: {}\n }\n },\n context: {\n dir: 'src/context',\n maxSources: 5,\n userContextTimeoutMs: 3_500\n },\n serviceAccount: `firebase-adminsdk-fbsvc@${gcpProject}.iam.gserviceaccount.com`,\n computeAccount: '68329189121-compute@developer.gserviceaccount.com',\n workerUris: {\n prod: `https://${region}-${gcpProject}.cloudfunctions.net/${gcpProject}-tasks`,\n dev: `https://${region}-${gcpProject}.cloudfunctions.net/${gcpProject}-tasks-dev`\n },\n queueBaseNames: {\n prod: `${gcpProject}-tasks`,\n dev: `${gcpProject}-tasks-dev`\n },\n cloudRun: {\n memory: '4GiB',\n cpu: 2,\n http: { timeoutSeconds: 180, concurrency: 80, maxInstances: 50, invoker: 'public' },\n worker: { timeoutSeconds: 540, concurrency: 20, maxInstances: 20 }\n },\n tasks: {\n useCloudTasks: Boolean(process.env.K_SERVICE),\n defaultShardsCount: 20,\n batchCreateSize: 100,\n maxAttempts: 3,\n hedgeAfterMs: 65_000,\n heartbeatIntervalMs: 20_000,\n heartbeatStaleMs: 30_000,\n timeoutMs: 510_000,\n ttlMs: 3_600_000,\n scanDeadlineSeconds: 120,\n defaultDeadlineSeconds: 540,\n claimCheckThresholdBytes: 204_800,\n yieldBudgetRatio: 0.75\n },\n models: {\n vertex: 'claude-haiku-5-5',\n vertexExpert: 'claude-sonnet-4-5',\n vertexEmbedding: 'text-embedding-005',\n vertexLocation: 'global',\n mistralOcr: 'mistral-ocr-latest',\n jev: 'jev-latest',\n defaultAgentMaxSteps: 8\n },\n limits: {\n maxAttachments: 500,\n maxChatAttachments: 20,\n chatMessagesLimit: 15,\n defaultListLimit: 100,\n maxFileBytes: 20 * 1024 * 1024,\n maxBodyBytes: 25 * 1024 * 1024,\n maxWaitMs: 60_000,\n httpUser: { max: 300, windowMs: 60_000, keyBy: 'user' },\n httpIp: { max: 60, windowMs: 60_000, keyBy: 'ip' },\n buckets: {\n mistral: { windowMs: 60_000, max: 1250 },\n jev: { windowMs: 60_000, max: 1200 },\n ai: { windowMs: 60_000, max: 2000 },\n workflows: { windowMs: 1_000, max: 500 },\n firestore: { windowMs: 1_000, max: 500 },\n storage: { windowMs: 1_000, max: 1000 },\n emails: { windowMs: 1_000, max: 50 },\n payments: { windowMs: 1_000, max: 100 }\n }\n },\n auth: {\n sessionCookie: 'session',\n sessionExpiresInMs: 14 * 24 * 60 * 60 * 1000,\n tokenCacheTtlMs: 5 * 60_000,\n tokenCacheMaxSize: 2000,\n adminUserId: 'admin',\n allowedOrigins: [\n /^https:\\/\\/[a-z0-9-]+\\.a\\.run\\.app$/i,\n /^https:\\/\\/([a-z0-9-]+\\.)?(web\\.app|firebaseapp\\.com)$/i,\n /^http:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/i\n ]\n },\n emails: {\n provider: 'resend',\n fromEmail: `no-reply@${gcpProject || 'app'}.firebaseapp.com`,\n fromName: gcpProject || 'App',\n actionBaseUrl: `https://${gcpProject || 'app'}.web.app`,\n otpTtlMinutes: 15,\n recoveryOtpTtlMinutes: 10,\n maxVerifyAttempts: 5,\n enforceSuppressionList: true,\n webhookToleranceSeconds: 300,\n authFlows: {\n verify_email: { actionPath: '/auth/verify-email', subject: 'Verify your email address' },\n reset_password: { actionPath: '/auth/reset-password', subject: 'Reset your password' },\n verify_recovery_email: { actionPath: '/auth/verify-recovery', subject: 'Verify your recovery email' },\n account_recovery: { actionPath: '/auth/account-recovery', subject: 'Recover your account' },\n welcome: { actionPath: '/dashboard', subject: 'Welcome!' },\n security_alert: { actionPath: '/settings/security', subject: 'Security alert on your account' }\n },\n sendgrid: {\n baseUrl: 'https://api.sendgrid.com/v3'\n },\n resend: {\n baseUrl: 'https://api.resend.com'\n }\n },\n payments: {\n enabled: false,\n provider: 'dodo',\n defaultCurrency: 'usd',\n defaultPlanId: 'free',\n autoTrackAiTokens: true,\n aiTokenMeterName: 'ai_tokens',\n webhookToleranceSeconds: 300,\n urls: {\n successUrl: `${defaultWebBaseUrl}/billing/success`,\n cancelUrl: `${defaultWebBaseUrl}/billing/cancel`,\n returnUrl: `${defaultWebBaseUrl}/billing`\n },\n dodo: {\n liveBaseUrl: 'https://live.dodopayments.com',\n testBaseUrl: 'https://test.dodopayments.com'\n },\n stripe: {\n baseUrl: 'https://api.stripe.com/v1',\n apiVersion: '2025-02-24.acacia'\n }\n }\n}\n\nconst mergeDeep = <T extends Record<string, any>>(target: T, source?: DeepPartial<T>): T => {\n if (!source) return target\n for (const [k, v] of Object.entries(source)) {\n if (v && typeof v === 'object' && !Array.isArray(v) && !(v instanceof RegExp) && typeof target[k] === 'object') {\n mergeDeep(target[k], v as any)\n } else if (v !== undefined) {\n ;(target as any)[k] = v\n }\n }\n return target\n}\n\nexport const defineConfig = (overrides?: DeepPartial<CoreConfig>): CoreConfig => {\n if (overrides?.gcpProject && overrides.gcpProject !== CORE_CONFIG.gcpProject) {\n const p = overrides.gcpProject\n const r = overrides.region ?? CORE_CONFIG.region\n CORE_CONFIG.appName = p\n CORE_CONFIG.firestoreDbs = { prod: p, dev: `${p}-dev` }\n CORE_CONFIG.storageBuckets = { prod: `${p}.firebasestorage.app`, dev: `${p}-dev` }\n CORE_CONFIG.serviceAccount = `firebase-adminsdk-fbsvc@${p}.iam.gserviceaccount.com`\n CORE_CONFIG.workerUris = {\n prod: `https://${r}-${p}.cloudfunctions.net/${p}-tasks`,\n dev: `https://${r}-${p}.cloudfunctions.net/${p}-tasks-dev`\n }\n CORE_CONFIG.queueBaseNames = {\n prod: `${p}-tasks`,\n dev: `${p}-tasks-dev`\n }\n CORE_CONFIG.emails.fromEmail = `no-reply@${p}.firebaseapp.com`\n CORE_CONFIG.emails.fromName = p\n CORE_CONFIG.emails.actionBaseUrl = `https://${p}.web.app`\n CORE_CONFIG.payments.urls = {\n successUrl: `https://${p}.web.app/billing/success`,\n cancelUrl: `https://${p}.web.app/billing/cancel`,\n returnUrl: `https://${p}.web.app/billing`\n }\n }\n return mergeDeep(CORE_CONFIG, overrides)\n}\n", "import { z } from 'zod'\nimport { CORE_CONFIG } from '../config'\nimport {\n fileRef,\n fileScan,\n fileScanError,\n unparseableReason,\n type FileRef,\n type FileScan,\n type FileScanError,\n type UnparseableReason\n} from '../db'\nimport { hasValidMagicBytes } from './utils'\n\nexport {\n fileRef,\n fileScan,\n fileScanError,\n unparseableReason,\n type FileRef,\n type FileScan,\n type FileScanError,\n type UnparseableReason\n}\n\nexport const fileType = z.enum([\n 'application/pdf',\n 'image/png',\n 'image/jpeg',\n 'image/webp',\n 'image/gif',\n 'image/bmp',\n 'image/tiff',\n 'image/avif'\n])\nexport type FileType = z.infer<typeof fileType>\n\nexport const fileBody = z\n .object({\n bytes: z\n .instanceof(Uint8Array)\n .refine((b) => b.byteLength > 0 && b.byteLength <= CORE_CONFIG.limits.maxFileBytes, 'File size must be 1B..20MiB'),\n name: z.string().min(1).max(256),\n type: fileType\n })\n .refine((f) => hasValidMagicBytes(f.type, f.bytes), {\n message: 'File binary header does not match declared MIME type',\n path: ['bytes']\n })\nexport type FileBody = z.infer<typeof fileBody>\n\nexport const signedUploadInput = z.object({\n sha256: z.string().regex(/^[a-fA-F0-9]{24,64}$/, 'Invalid SHA-256 hex digest'),\n name: z.string().min(1).max(256),\n type: fileType,\n size: z\n .number()\n .int()\n .positive()\n .refine((s) => s <= CORE_CONFIG.limits.maxFileBytes, 'File size exceeds maxFileBytes')\n .optional()\n})\nexport type SignedUploadInput = z.infer<typeof signedUploadInput>\n\nexport interface SignedUploadUrlResult {\n ref: FileRef\n url: string\n expiresAt: string\n deduplicated: boolean\n}\n\nexport interface SignedDownloadUrlResult {\n ref: FileRef\n url: string\n expiresAt: string\n}\n", "import { z } from 'zod'\nimport type { Core } from '../index'\nimport {\n CORE_CONFIG,\n type DbAccessScope,\n type DbAction,\n type DbRole,\n type RbacConfig,\n type RbacRoleScopes\n} from '../config'\n\nexport { type DbAccessScope, type DbAction, type DbRole, type RbacConfig, type RbacRoleScopes }\n\nexport interface DbCallContext {\n userId?: EntryId\n userRole?: DbRole\n bypassRbac?: boolean\n core?: Core\n}\n\nexport const entryId = z.string().regex(/^[A-Za-z0-9_-]{1,128}$/)\nexport type EntryId = z.infer<typeof entryId>\n\nexport const fileRef = z.string().regex(/^[A-Za-z0-9_-]{1,128}_[a-f0-9]{24}$/)\nexport type FileRef = z.infer<typeof fileRef>\n\nexport const fileScan = z.object({\n type: z.string(),\n confidence: z.number(),\n fields: z.record(z.string(), z.any()),\n markdown: z.string()\n})\nexport type FileScan = z.infer<typeof fileScan>\n\nexport const unparseableReason = z.enum([\n 'CORRUPTED_FILE',\n 'PASSWORD_PROTECTED',\n 'EMPTY_OR_UNREADABLE',\n 'UNSUPPORTED_FORMAT',\n 'CLASSIFICATION_REJECTED'\n])\nexport type UnparseableReason = z.infer<typeof unparseableReason>\n\nexport const fileScanError = z.object({\n status: z.literal('unparseable'),\n reason: unparseableReason,\n /** Clear instruction for the LLM agent explaining why the file failed and asking the user to upload a valid replacement */\n agentHint: z.string(),\n diagnosticMessage: z.string().optional(),\n failedAt: z.string()\n})\nexport type FileScanError = z.infer<typeof fileScanError>\n\nexport interface BaseEntryFields {\n id: EntryId\n deleted: boolean\n createdAt: Date\n updatedAt: Date\n}\n\nexport type WithBaseFields<T> = Omit<BaseEntryFields, keyof T> & T\n\nconst baseEntrySchemaShape = {\n id: entryId,\n deleted: z.boolean().default(false),\n createdAt: z.date(),\n updatedAt: z.date()\n}\n\nexport type AuthRelationType = '1:1' | '1:N' | 'N:1' | 'M:N' | 'global'\n\nexport interface UserRelationConfig {\n type?: AuthRelationType\n userField?: string\n userIdsField?: string\n junction?: {\n collection: string\n userField?: string\n targetField?: string\n }\n deleteWhenEmpty?: boolean\n}\n\nexport interface CollectionDefinition<S extends z.ZodObject<any> = z.ZodObject<any>> {\n name?: string\n schema: S\n userRelation?: UserRelationConfig\n rbac?: RbacConfig\n sortByUpdated?: boolean\n onHardDelete?: (doc: WithBaseFields<z.infer<S>>, core: Core) => Promise<void>\n}\n\nexport interface DbListOptions<M = Record<string, any>> {\n ids?: string[]\n userId?: EntryId\n where?: Partial<{ [K in keyof M]: M[K] | readonly M[K][] }>\n orderBy?: { field: keyof M & string; direction?: 'asc' | 'desc' }\n includeDeleted?: boolean\n limit?: number\n cursor?: string\n select?: (keyof M & string)[]\n bypassRbac?: boolean\n}\n\nexport type PaginatedList<T> = T[] & { nextCursor?: string | null }\n\nexport interface DbListPage<T> {\n items: T[]\n nextCursor: string | null\n}\n\nexport const defineCollection = <S extends z.ZodObject<any>>(def: CollectionDefinition<S>): CollectionDefinition<S> => {\n const mergedSchema = z.object({\n ...baseEntrySchemaShape,\n ...def.schema.shape\n }) as unknown as S\n const relType = def.userRelation?.type ?? '1:N'\n return {\n ...def,\n userRelation: {\n type: relType,\n userField: relType === '1:1' ? 'id' : 'userId',\n ...def.userRelation\n },\n schema: mergedSchema\n }\n}\n\nexport const defineCollections = <T extends Record<string, CollectionDefinition<any>>>(defs: T): T =>\n Object.fromEntries(\n Object.entries(defs).map(([name, def]) => [name, defineCollection({ ...def, name: def.name ?? name })])\n ) as T\n\nexport const coreCollections = defineCollections({\n chat: {\n schema: z.object({\n userId: entryId,\n agentId: z.string().default('chat'),\n title: z.string().default('New Chat'),\n model: z.string().default(CORE_CONFIG.models.vertex),\n messageCount: z.number().int().nonnegative().default(0),\n summary: z.string().nullable().optional(),\n activeGenerationId: z.string().nullable().optional()\n }),\n userRelation: { type: '1:N', userField: 'userId' },\n sortByUpdated: true\n },\n file: {\n schema: z.object({\n id: fileRef,\n shaSum: z.string(),\n fileName: z.string(),\n contentType: z.string(),\n size: z.number().int().nonnegative(),\n scan: fileScan.nullable().optional(),\n scanError: fileScanError.nullable().optional(),\n userId: entryId\n }),\n userRelation: { type: '1:N', userField: 'userId' }\n },\n user_auth_meta: {\n schema: z.object({\n email: z.string().nullable().optional(),\n emailVerified: z.boolean().default(false),\n name: z.string().nullable().optional(),\n avatarUrl: z.string().nullable().optional(),\n recoveryEmail: z.string().nullable().optional(),\n recoveryEmailVerified: z.boolean().default(false),\n linkedProviders: z\n .array(\n z.object({\n provider: z.enum(['google', 'apple']),\n providerUserId: z.string(),\n email: z.string().nullable().optional(),\n linkedAt: z.date()\n })\n )\n .default([]),\n providerKeys: z.array(z.string()).default([])\n }),\n userRelation: { type: '1:1', userField: 'id' },\n rbac: {\n admin: { any: ['*'] },\n user: { own: ['read'] },\n anon: {}\n }\n },\n auth_tokens: {\n schema: z.object({\n userId: entryId,\n purpose: z.enum(['verify_email', 'reset_password', 'verify_recovery_email', 'account_recovery']),\n targetEmail: z.string(),\n tokenHash: z.string(),\n urlTokenHash: z.string().optional(),\n attempts: z.number().int().nonnegative().default(0),\n expiresAt: z.date(),\n consumedAt: z.date().nullable().optional()\n }),\n userRelation: { type: '1:N', userField: 'userId' },\n rbac: {\n admin: { any: ['*'] },\n user: {},\n anon: {}\n }\n },\n email_log: {\n schema: z.object({\n userId: entryId.optional(),\n provider: z.enum(['sendgrid', 'resend', 'firebase', 'dev']),\n externalMessageId: z.string().optional(),\n to: z.string().email(),\n from: z.string(),\n subject: z.string().optional(),\n template: z.string().optional(),\n purpose: z.string().optional(),\n status: z\n .enum([\n 'queued',\n 'sent',\n 'delivered',\n 'opened',\n 'clicked',\n 'bounced',\n 'complained',\n 'failed',\n 'suppressed'\n ])\n .default('queued'),\n errorMessage: z.string().optional(),\n sentAt: z.string().datetime(),\n deliveredAt: z.string().datetime().optional(),\n bouncedAt: z.string().datetime().optional()\n }),\n userRelation: { type: '1:N', userField: 'userId' },\n sortByUpdated: true,\n rbac: {\n admin: { any: ['*'] },\n user: { own: ['read'] },\n anon: {}\n }\n },\n email_suppression: {\n schema: z.object({\n email: z.string().email(),\n reason: z.enum(['hard_bounce', 'spam_complaint', 'manual']),\n provider: z.enum(['sendgrid', 'resend', 'manual']),\n rawEvent: z.string().optional(),\n suppressedAt: z.string().datetime()\n }),\n userRelation: { type: 'global' },\n rbac: {\n admin: { any: ['*'] },\n user: {},\n anon: {}\n }\n },\n payment_customer: {\n schema: z.object({\n userId: entryId,\n email: z.string().email().optional(),\n name: z.string().optional(),\n stripeCustomerId: z.string().optional(),\n dodoCustomerId: z.string().optional(),\n activeProvider: z.enum(['stripe', 'dodo']).optional(),\n planId: z.string().default('free'),\n subscriptionId: z.string().optional(),\n subscriptionStatus: z\n .enum(['none', 'active', 'trialing', 'past_due', 'on_hold', 'cancelled', 'expired'])\n .default('none'),\n currentPeriodStart: z.string().datetime().optional(),\n currentPeriodEnd: z.string().datetime().optional(),\n cancelAtPeriodEnd: z.boolean().default(false),\n bonusAiTokens: z.number().int().nonnegative().default(0),\n credits: z.number().nonnegative().default(0),\n bonusMetrics: z.record(z.string(), z.number()).default({})\n }),\n userRelation: { type: '1:1', userField: 'id' },\n rbac: {\n admin: { any: ['*'] },\n user: { own: ['read'] },\n anon: {}\n }\n },\n payment_usage: {\n schema: z.object({\n userId: entryId,\n periodKey: z.string(),\n planId: z.string().default('free'),\n aiTokensUsed: z.number().int().nonnegative().default(0),\n aiInputTokens: z.number().int().nonnegative().default(0),\n aiOutputTokens: z.number().int().nonnegative().default(0),\n overageTokensReported: z.number().int().nonnegative().default(0),\n metricsUsed: z.record(z.string(), z.number()).default({}),\n lastUpdatedAt: z.string().datetime()\n }),\n userRelation: { type: '1:N', userField: 'userId' },\n rbac: {\n admin: { any: ['*'] },\n user: { own: ['read'] },\n anon: {}\n }\n },\n payment_transaction: {\n schema: z.object({\n userId: entryId,\n provider: z.enum(['stripe', 'dodo']),\n externalId: z.string(),\n type: z.enum([\n 'checkout.completed',\n 'payment.succeeded',\n 'payment.failed',\n 'invoice.created',\n 'invoice.paid',\n 'subscription.active',\n 'subscription.renewed',\n 'subscription.tier_changed',\n 'subscription.cancelled',\n 'subscription.past_due'\n ]),\n amount: z.number().int().optional(),\n currency: z.string().optional(),\n productOrPlanId: z.string().optional(),\n rawEventType: z.string(),\n processedAt: z.string().datetime()\n }),\n userRelation: { type: '1:N', userField: 'userId' },\n sortByUpdated: true,\n rbac: {\n admin: { any: ['*'] },\n user: { own: ['read'] },\n anon: {}\n }\n }\n})\n\nconst CORE_COLLECTION_NAMES = [\n 'chat',\n 'file',\n 'user_auth_meta',\n 'auth_tokens',\n 'email_log',\n 'email_suppression',\n 'payment_customer',\n 'payment_usage',\n 'payment_transaction'\n] as const\n\nexport const collectionRegistry = new Map<string, CollectionDefinition<any>>(\n CORE_COLLECTION_NAMES.map((name) => [name, coreCollections[name]])\n)\n\nexport const registerCollections = (defs: Record<string, CollectionDefinition<any>>, reset = false) => {\n if (reset) {\n collectionRegistry.clear()\n for (const name of CORE_COLLECTION_NAMES) {\n collectionRegistry.set(name, coreCollections[name])\n }\n }\n for (const [k, def] of Object.entries(defs)) {\n const normalized = defineCollection({ ...def, name: def.name ?? k })\n collectionRegistry.set(normalized.name!, normalized)\n }\n}\n\nexport const unregisterCollections = (names: string[]) => {\n for (const name of names) {\n if (!CORE_COLLECTION_NAMES.includes(name as (typeof CORE_COLLECTION_NAMES)[number])) {\n collectionRegistry.delete(name)\n }\n }\n}\n\nexport const getRegisteredCollectionNames = (): string[] => [...collectionRegistry.keys()]\n\nexport const getCollectionDef = (name: string): CollectionDefinition<any> => {\n const def = collectionRegistry.get(name)\n if (!def) throw new Error(`Unregistered collection: ${name}`)\n return def\n}\n\nexport const getEffectiveRbac = (collection: string): RbacConfig => {\n const def = getCollectionDef(collection)\n return {\n admin: { ...CORE_CONFIG.db.rbac.admin, ...def.rbac?.admin },\n user: { ...CORE_CONFIG.db.rbac.user, ...def.rbac?.user },\n anon: { ...CORE_CONFIG.db.rbac.anon, ...def.rbac?.anon }\n }\n}\n\nexport type CoreCollections = typeof coreCollections\n\nexport interface Register {}\n\nexport type RegisteredCollections = Register extends { collections: infer C extends Record<string, CollectionDefinition<any>> }\n ? CoreCollections & C\n : CoreCollections\n\nexport type CollectionName = keyof RegisteredCollections | (string & {})\n\nexport type SelectModel<T extends CollectionName> = T extends keyof RegisteredCollections\n ? WithBaseFields<z.infer<RegisteredCollections[T]['schema']>>\n : Record<string, any> & BaseEntryFields\n\nexport type InsertData<T extends CollectionName> = Omit<SelectModel<T>, 'id' | 'deleted' | 'createdAt' | 'updatedAt'> & {\n id?: string\n deleted?: boolean\n}\n\nexport type UpdateData<T extends CollectionName> = Partial<Omit<SelectModel<T>, 'id' | 'createdAt'>>\n", "import { Agent } from 'node:https'\nimport { getApp, getApps, initializeApp } from 'firebase-admin/app'\nimport { FieldValue, getFirestore, type Firestore } from 'firebase-admin/firestore'\nimport { getStorage } from 'firebase-admin/storage'\nimport { CORE_CONFIG, type DbAction, type DbRole } from '../config'\nimport { Core } from '../index'\nimport type { StepRunner } from '../tasks'\nimport {\n collectionRegistry,\n getCollectionDef,\n type CollectionName,\n type DbCallContext,\n type DbListOptions,\n type DbListPage,\n type EntryId,\n type InsertData,\n type PaginatedList,\n type SelectModel,\n type UpdateData\n} from './schema'\nimport {\n attachNextCursor,\n buildScopedCollectionQuery,\n drainQueryBatchDelete,\n executeFilteredListQuery,\n fromFirestoreDoc,\n isCreateOwnScopeAllowed,\n resolveAllowedScope,\n resolveJunction,\n runChunked,\n stripImmutableUpdateFields,\n wireCoreCollectionHooks\n} from './utils'\n\ntype StorageBucket = ReturnType<ReturnType<typeof getStorage>['bucket']>\n\nconst dbs: [Firestore | undefined, Firestore | undefined] = [undefined, undefined]\nconst buckets: [StorageBucket | undefined, StorageBucket | undefined] = [undefined, undefined]\n\nlet cachedToken = ''\nlet cachedTokenExp = 0\n\nexport class DbService {\n readonly #core: Core\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n wireCoreCollectionHooks()\n }\n\n #ensureFirebaseApp = (): void => {\n if (!getApps().length) {\n initializeApp({\n projectId: CORE_CONFIG.gcpProject,\n storageBucket: CORE_CONFIG.storageBuckets.prod,\n serviceAccountId: CORE_CONFIG.serviceAccount,\n httpAgent: new Agent({ keepAlive: true })\n })\n }\n }\n\n firestore = (isDev: boolean = this.#core.env.isDev): Firestore => {\n this.#ensureFirebaseApp()\n const idx = isDev ? 1 : 0\n if (!dbs[idx]) {\n const db = getFirestore(isDev ? CORE_CONFIG.firestoreDbs.dev : CORE_CONFIG.firestoreDbs.prod)\n try {\n db.settings({ ignoreUndefinedProperties: true })\n } catch {}\n dbs[idx] = db\n }\n return dbs[idx]!\n }\n\n bucket = (isDev: boolean = this.#core.env.isDev): StorageBucket => {\n this.#ensureFirebaseApp()\n const idx = isDev ? 1 : 0\n if (!buckets[idx]) {\n buckets[idx] = getStorage().bucket(isDev ? CORE_CONFIG.storageBuckets.dev : CORE_CONFIG.storageBuckets.prod)\n }\n return buckets[idx]!\n }\n\n #getGcpAccessToken = async (): Promise<string> => {\n this.#ensureFirebaseApp()\n if (cachedToken && cachedTokenExp > Date.now() + 60_000) return cachedToken\n return this.#core.internals.resilience.singleflight(\n 'gcp:token',\n async () => {\n const token = await getApp().options.credential?.getAccessToken()\n if (!token?.access_token) throw new Error('Unable to acquire GCP ADC access token')\n cachedToken = token.access_token\n cachedTokenExp = Date.now() + (token.expires_in ? token.expires_in * 1000 : 3_000_000)\n return cachedToken\n },\n { scope: 'global' }\n )\n }\n\n #effectiveCtx = (ctx?: DbCallContext): DbCallContext => ({\n userId: this.#core.userId,\n userRole: this.#core.role,\n ...ctx\n })\n\n #resolveRole = (ctx?: DbCallContext): DbRole =>\n this.#core.internals.auth.resolveUserRole(ctx?.userId, ctx?.userRole)\n\n #isEntryOwner = async (\n collection: CollectionName,\n doc: Record<string, any>,\n userId: EntryId\n ): Promise<boolean> => {\n if (!userId) return false\n if (userId === this.#core.config.auth.adminUserId) return true\n const def = getCollectionDef(collection)\n const rel = def.userRelation?.type ?? '1:N'\n if (rel === 'global') return false\n if (rel === '1:1') return doc[def.userRelation?.userField ?? 'id'] === userId\n if (rel === '1:N') return doc[def.userRelation?.userField ?? 'userId'] === userId\n if (rel === 'M:N' && def.userRelation?.junction) {\n const { collection: jCol, userField, targetField } = resolveJunction(collection, def.userRelation.junction)\n const jSnap = await this.firestore()\n .collection(jCol)\n .where(userField, '==', userId)\n .where(targetField, '==', doc.id)\n .limit(1)\n .get()\n return !jSnap.empty\n }\n const arr = doc[def.userRelation?.userIdsField ?? 'userIds']\n return Array.isArray(arr) && arr.includes(userId)\n }\n\n #fetchRawEntry = async <T extends CollectionName>(\n collection: T,\n id: string\n ): Promise<SelectModel<T> | undefined> => {\n if (!id) return undefined\n await this.#core.internals.resilience.acquireLimit('firestore')\n const snap = await this.firestore().collection(collection).doc(id).get()\n if (!snap.exists) return undefined\n const doc = fromFirestoreDoc(collection, snap.id, snap.data() ?? {})\n return doc.deleted ? undefined : doc\n }\n\n canAccess = async <N extends CollectionName>(\n collection: N,\n docOrId: string | Record<string, any> | undefined,\n userId: EntryId = this.#core.userId,\n action: DbAction = 'read',\n userRole?: DbRole\n ): Promise<boolean> => {\n const role = this.#resolveRole({\n userId,\n userRole: userRole ?? (userId === this.#core.userId ? this.#core.role : undefined)\n })\n const scope = resolveAllowedScope(collection, role, action)\n if (scope === 'none') return false\n if (scope === 'any') {\n if (!docOrId) return true\n return typeof docOrId === 'string' ? Boolean(await this.#fetchRawEntry(collection, docOrId)) : true\n }\n if (!userId) return false\n const doc =\n typeof docOrId === 'string'\n ? await this.#fetchRawEntry(collection, docOrId)\n : (docOrId as Record<string, any> | undefined)\n return doc ? this.#isEntryOwner(collection, doc, userId) : false\n }\n\n create = async <N extends CollectionName>(\n collection: N,\n data: InsertData<N>,\n ctx?: DbCallContext\n ): Promise<SelectModel<N>> => {\n const effective = this.#effectiveCtx(ctx)\n if (!effective.bypassRbac) {\n const role = this.#resolveRole(effective)\n const scope = resolveAllowedScope(collection, role, 'create')\n if (scope === 'none') this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n if (scope === 'own' && !isCreateOwnScopeAllowed(collection, effective.userId, data as Record<string, any>)) {\n this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n }\n await this.#core.internals.resilience.acquireLimit('firestore')\n const def = getCollectionDef(collection)\n const rel = def.userRelation?.type ?? '1:N'\n const userField = def.userRelation?.userField ?? (rel === '1:1' ? 'id' : 'userId')\n const col = this.firestore().collection(collection)\n const explicitId =\n data.id ?? (rel === '1:1' && userField === 'id' ? (data as Record<string, any>).userId : undefined)\n const docRef = explicitId ? col.doc(String(explicitId)) : col.doc()\n const now = new Date()\n const fullDoc = def.schema.parse({ deleted: false, ...data, id: docRef.id, createdAt: now, updatedAt: now })\n await docRef.set(fullDoc)\n return fullDoc as SelectModel<N>\n }\n\n read = async <N extends CollectionName>(\n collection: N,\n id: EntryId,\n includeDeleted = false,\n ctx?: DbCallContext\n ): Promise<SelectModel<N> | undefined> => {\n if (!id) return undefined\n await this.#core.internals.resilience.acquireLimit('firestore')\n const snap = await this.firestore().collection(collection).doc(id).get()\n if (!snap.exists) return undefined\n const doc = fromFirestoreDoc(collection, snap.id, snap.data() ?? {})\n if (!includeDeleted && doc.deleted) return undefined\n const effective = this.#effectiveCtx(ctx)\n if (!effective.bypassRbac) {\n const role = this.#resolveRole(effective)\n const scope = resolveAllowedScope(collection, role, 'read')\n if (scope === 'none') this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n if (scope === 'own') {\n if (!effective.userId || !(await this.#isEntryOwner(collection, doc, effective.userId))) {\n this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n }\n }\n return doc\n }\n\n #batchReadByIds = async <T extends CollectionName>(\n collection: T,\n ids: string[],\n includeDeleted = false,\n hasSelect = false\n ): Promise<SelectModel<T>[]> => {\n const uniqueIds = [...new Set(ids.filter(Boolean))]\n if (!uniqueIds.length) return []\n const byId = new Map<string, SelectModel<T>>()\n const db = this.firestore()\n for (let i = 0; i < uniqueIds.length; i += 100) {\n await this.#core.internals.resilience.acquireLimit('firestore')\n const snaps = await db.getAll(...uniqueIds.slice(i, i + 100).map((id) => db.collection(collection).doc(id)))\n for (const s of snaps) {\n if (!s.exists) continue\n const doc = fromFirestoreDoc(collection, s.id, s.data() ?? {}, hasSelect)\n if (includeDeleted || !doc.deleted) byId.set(s.id, doc)\n }\n }\n return ids.map((id) => byId.get(id)).filter((d): d is SelectModel<T> => Boolean(d))\n }\n\n list = async <N extends CollectionName>(\n collection: N,\n opts?: DbListOptions<SelectModel<N>>,\n ctx?: DbCallContext\n ): Promise<PaginatedList<SelectModel<N>>> => {\n const effective = this.#effectiveCtx(ctx)\n const bypass = Boolean(opts?.bypassRbac || effective.bypassRbac)\n let scopedUserId = opts?.userId\n if (!bypass) {\n const role = this.#resolveRole(effective)\n const scope = resolveAllowedScope(collection, role, 'read')\n if (scope === 'none') this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n if (scope === 'own') {\n if (!effective.userId) this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n if (scopedUserId && scopedUserId !== effective.userId) this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n scopedUserId = effective.userId\n }\n }\n\n const def = getCollectionDef(collection)\n const db = this.firestore()\n const rel = def.userRelation?.type ?? '1:N'\n const maxDocs = opts?.limit ?? this.#core.config.limits.defaultListLimit\n const hasSelect = Boolean(opts?.select?.length)\n\n if (opts?.ids) {\n const docs = await this.#batchReadByIds(collection, opts.ids, opts.includeDeleted, hasSelect)\n if (!scopedUserId || rel === 'global') return attachNextCursor(docs.slice(0, maxDocs), maxDocs)\n const ownership = await Promise.all(docs.map((doc) => this.#isEntryOwner(collection, doc, scopedUserId)))\n return attachNextCursor(docs.filter((_, i) => ownership[i]).slice(0, maxDocs), maxDocs)\n }\n\n await this.#core.internals.resilience.acquireLimit('firestore')\n\n if (scopedUserId) {\n if (rel === '1:1' && (def.userRelation?.userField ?? 'id') === 'id') {\n const single = await this.read(collection, scopedUserId, opts?.includeDeleted, { bypassRbac: true })\n return attachNextCursor(single ? [single] : [], maxDocs)\n }\n if (rel === 'M:N' && def.userRelation?.junction) {\n const { collection: jCol, userField, targetField } = resolveJunction(collection, def.userRelation.junction)\n const jSnap = await db.collection(jCol).where(userField, '==', scopedUserId).limit(maxDocs).get()\n const targetIds = jSnap.docs.map((d) => String(d.data()[targetField] ?? '')).filter(Boolean)\n const docs = await this.#batchReadByIds(collection, targetIds, opts?.includeDeleted, hasSelect)\n return attachNextCursor(docs, maxDocs)\n }\n }\n\n const baseQuery = buildScopedCollectionQuery(\n db.collection(collection),\n collection,\n scopedUserId,\n opts?.where as Record<string, unknown> | undefined,\n opts?.select\n )\n const docs = await executeFilteredListQuery(\n db,\n collection,\n baseQuery,\n opts,\n maxDocs,\n hasSelect,\n this.#core.config.limits.defaultListLimit\n )\n return attachNextCursor(docs.slice(0, maxDocs), maxDocs)\n }\n\n listPage = async <N extends CollectionName>(\n collection: N,\n opts?: DbListOptions<SelectModel<N>>,\n ctx?: DbCallContext\n ): Promise<DbListPage<SelectModel<N>>> => {\n const items = await this.list(collection, opts, ctx)\n return { items, nextCursor: items.nextCursor ?? null }\n }\n\n update = async <N extends CollectionName>(\n collection: N,\n id: EntryId,\n data: UpdateData<N>,\n ctx?: DbCallContext\n ): Promise<{ id: EntryId; updated: true }> => {\n const effective = this.#effectiveCtx(ctx)\n if (!effective.bypassRbac) {\n const allowed = await this.canAccess(collection, id, effective.userId ?? '', 'write', effective.userRole)\n if (!allowed) this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n const cleanPatch = stripImmutableUpdateFields(collection, data, Boolean(effective.bypassRbac))\n await this.#core.internals.resilience.acquireLimit('firestore')\n await this.firestore()\n .collection(collection)\n .doc(id)\n .update({ ...cleanPatch, updatedAt: new Date() })\n return { id, updated: true }\n }\n\n delete = async <N extends CollectionName>(\n collection: N,\n id: EntryId,\n ctx?: DbCallContext\n ): Promise<{ id: EntryId; deleted: true }> => {\n const existing = await this.read(collection, id, false, { bypassRbac: true })\n if (!existing) throw new Error(`Not found: ${collection}/${id}`)\n const effective = this.#effectiveCtx(ctx)\n if (!effective.bypassRbac) {\n const allowed = await this.canAccess(collection, existing, effective.userId ?? '', 'delete', effective.userRole)\n if (!allowed) this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n await this.update(collection, id, { deleted: true } as UpdateData<N>, { bypassRbac: true })\n return { id, deleted: true }\n }\n\n hardDelete = async <N extends CollectionName>(\n collection: N,\n id: EntryId,\n ctx?: DbCallContext\n ): Promise<{ id: EntryId; deleted: true; hard: true }> => {\n const def = getCollectionDef(collection)\n const effective = this.#effectiveCtx(ctx)\n const existing =\n def.onHardDelete || !effective.bypassRbac\n ? await this.read(collection, id, true, { bypassRbac: true })\n : undefined\n if (!effective.bypassRbac) {\n if (!existing) throw new Error(`Not found: ${collection}/${id}`)\n const allowed = await this.canAccess(collection, existing, effective.userId ?? '', 'delete', effective.userRole)\n if (!allowed) this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n await this.#core.internals.resilience.acquireLimit('firestore')\n await this.firestore().collection(collection).doc(id).delete()\n if (def.onHardDelete && (existing || collection === 'chat')) {\n const scopedCore =\n effective.core ??\n new Core({\n env: this.#core.env,\n userId: effective.userId ?? this.#core.config.auth.adminUserId,\n role: 'admin'\n })\n const targetDoc = existing ?? ({ id } as SelectModel<N>)\n await def.onHardDelete(targetDoc, scopedCore).catch(() => {})\n }\n return { id, deleted: true, hard: true }\n }\n\n #eraseOwnedEntries = async (name: string, userId: EntryId): Promise<number> => {\n let total = 0\n while (true) {\n const docs = await this.list(name, { userId, includeDeleted: true, limit: 500, bypassRbac: true })\n if (!docs.length) break\n await runChunked(docs, (d) => this.hardDelete(name, d.id, { bypassRbac: true }).catch(() => {}), 25)\n total += docs.length\n if (docs.length < 500) break\n }\n return total\n }\n\n #cascadeEraseUserCollections = async (\n userId: EntryId,\n step: StepRunner = this.#core.step\n ): Promise<{ erasedFiles: number; erasedChats: number; erasedCollections: Record<string, number> }> => {\n const erasedFiles = await step('erase-files', () => this.#eraseOwnedEntries('file', userId))\n const erasedChats = await step('erase-chats', async () => {\n const count = await this.#eraseOwnedEntries('chat', userId)\n const db = this.firestore()\n await drainQueryBatchDelete(db, db.collectionGroup('messages').where('userId', '==', userId)).catch(() => 0)\n return count\n })\n\n const erasedCollections: Record<string, number> = {}\n const db = this.firestore()\n\n for (const [name, def] of collectionRegistry) {\n if (name === 'file' || name === 'chat') continue\n const rel = def.userRelation?.type ?? '1:N'\n if (rel === 'global') continue\n\n erasedCollections[name] = await step(`erase-${name}`, async () => {\n if (rel === '1:1' || rel === '1:N') return this.#eraseOwnedEntries(name, userId)\n if (rel === 'M:N' && def.userRelation?.junction) {\n const { collection: jCol, userField } = resolveJunction(name, def.userRelation.junction)\n const jSnap = await db.collection(jCol).where(userField, '==', userId).get()\n await runChunked(jSnap.docs, (d) => d.ref.delete().catch(() => {}), 25)\n return jSnap.size\n }\n const userIdsField = def.userRelation?.userIdsField ?? 'userIds'\n const docs = await this.list(name, { userId, includeDeleted: true, limit: 500, bypassRbac: true })\n await runChunked(docs, async (d) => {\n const currentIds: string[] = Array.isArray(d[userIdsField]) ? d[userIdsField] : []\n if (def.userRelation?.deleteWhenEmpty && currentIds.filter((u) => u !== userId).length === 0) {\n await this.hardDelete(name, d.id, { bypassRbac: true }).catch(() => {})\n } else {\n await db.collection(name).doc(d.id).update({ [userIdsField]: FieldValue.arrayRemove(userId), updatedAt: new Date() }).catch(() => {})\n }\n })\n return docs.length\n })\n }\n\n await step('erase-tasks', async () => {\n const snap = await db.collection('_tasks').where('userId', '==', userId).get()\n const bucket = this.bucket()\n const docsToDelete = snap.docs.filter(\n (d) => d.data().workflowName !== 'erase-user' || d.data().status !== 'running'\n )\n await Promise.all([\n runChunked(\n docsToDelete,\n (d) =>\n Promise.all([\n d.ref.delete().catch(() => {}),\n bucket.deleteFiles({ prefix: `_tasks/${d.id}/` }).catch(() => {})\n ]),\n 25\n ),\n drainQueryBatchDelete(db, db.collection('_idempotency').where('userId', '==', userId)).catch(() => 0)\n ])\n return snap.size\n })\n\n return { erasedFiles, erasedChats, erasedCollections }\n }\n\n get internals() {\n return {\n ensureFirebaseApp: this.#ensureFirebaseApp,\n getGcpAccessToken: this.#getGcpAccessToken,\n cascadeEraseUserCollections: this.#cascadeEraseUserCollections\n }\n }\n}\n", "import { FieldPath, Timestamp } from 'firebase-admin/firestore'\nimport type { DbAction, DbRole } from '../config'\nimport type { Core } from '../index'\nimport {\n collectionRegistry,\n getCollectionDef,\n getEffectiveRbac,\n type CollectionName,\n type DbListOptions,\n type PaginatedList,\n type SelectModel,\n type UserRelationConfig\n} from './schema'\n\nexport const resolveJunction = (collection: string, j: NonNullable<UserRelationConfig['junction']>) => ({\n collection: j.collection,\n userField: j.userField ?? 'userId',\n targetField: j.targetField ?? `${collection}Id`\n})\n\nexport const hasAction = (actions: readonly DbAction[] | undefined, target: DbAction): boolean =>\n Boolean(actions && (actions.includes('*') || actions.includes(target)))\n\nexport const resolveAllowedScope = (collection: string, role: DbRole, action: DbAction): 'any' | 'own' | 'none' => {\n const rbac = getEffectiveRbac(collection)\n const roleScopes = rbac[role]\n if (!roleScopes) return 'none'\n if (hasAction(roleScopes.any, action)) return 'any'\n if (hasAction(roleScopes.own, action)) return 'own'\n return 'none'\n}\n\nexport const normalizeDates = (val: unknown): unknown => {\n if (val instanceof Timestamp) return val.toDate()\n if (Array.isArray(val)) return val.map(normalizeDates)\n if (val && typeof val === 'object' && !(val instanceof Date)) {\n return Object.fromEntries(Object.entries(val).map(([k, v]) => [k, normalizeDates(v)]))\n }\n return val\n}\n\nexport const fromFirestoreDoc = <T extends CollectionName>(\n c: T,\n id: string,\n raw: Record<string, unknown>,\n partial = false\n): SelectModel<T> => {\n const norm = normalizeDates({ ...raw, id }) as Record<string, unknown>\n const schema = getCollectionDef(c).schema\n return (partial ? schema.partial().parse(norm) : schema.parse(norm)) as SelectModel<T>\n}\n\nexport const attachNextCursor = <T extends { id: string }>(items: T[], limit: number): PaginatedList<T> => {\n const nextCursor = items.length >= limit ? (items.at(-1)?.id ?? null) : null\n Object.defineProperty(items, 'nextCursor', { value: nextCursor, enumerable: false, configurable: true })\n return items as PaginatedList<T>\n}\n\nexport const stripImmutableUpdateFields = (\n collection: string,\n data: unknown,\n allowSystemFields = false\n): Record<string, unknown> => {\n const def = getCollectionDef(collection)\n const ownerField = def.userRelation?.userField ?? 'userId'\n const raw = (data ?? {}) as Record<string, unknown>\n const {\n id: _id,\n createdAt: _createdAt,\n updatedAt: _updatedAt,\n deleted: _deleted,\n userId: _userId,\n [ownerField]: _ownerField,\n ...mutableData\n } = raw\n if (allowSystemFields && raw.deleted !== undefined) {\n mutableData.deleted = raw.deleted\n }\n const parsed = def.schema.partial().parse(mutableData) as Record<string, unknown>\n return Object.fromEntries(\n Object.keys(mutableData)\n .filter((k) => mutableData[k] !== undefined && k in parsed)\n .map((k) => [k, parsed[k]])\n )\n}\n\nexport const drainQueryBatchDelete = async (\n db: FirebaseFirestore.Firestore,\n query: FirebaseFirestore.Query,\n batchSize = 400\n): Promise<number> => {\n let deleted = 0\n while (true) {\n const snap = await query.limit(batchSize).get()\n if (snap.empty) break\n const batch = db.batch()\n for (const doc of snap.docs) batch.delete(doc.ref)\n await batch.commit()\n deleted += snap.size\n if (snap.size < batchSize) break\n }\n return deleted\n}\n\nexport const executeFilteredListQuery = async <N extends CollectionName>(\n db: FirebaseFirestore.Firestore,\n collection: N,\n baseQuery: FirebaseFirestore.Query,\n opts: DbListOptions<SelectModel<N>> | undefined,\n maxDocs: number,\n hasSelect: boolean,\n defaultListLimit: number\n): Promise<SelectModel<N>[]> => {\n const def = getCollectionDef(collection)\n const sortField = opts?.orderBy?.field ?? (def.sortByUpdated ? 'updatedAt' : undefined)\n const sortDir = opts?.orderBy?.direction ?? 'desc'\n const cursorSnap = opts?.cursor ? await db.collection(collection).doc(opts.cursor).get() : undefined\n const filteredQuery = !opts?.includeDeleted ? baseQuery.where('deleted', '==', false) : baseQuery\n\n let snap: FirebaseFirestore.QuerySnapshot\n let sortedInDb = false\n let appliedCursorInDb = false\n try {\n let q = sortField ? filteredQuery.orderBy(sortField, sortDir) : filteredQuery.orderBy(FieldPath.documentId(), 'asc')\n if (cursorSnap?.exists) q = q.startAfter(cursorSnap)\n snap = await q.limit(maxDocs).get()\n sortedInDb = true\n appliedCursorInDb = Boolean(cursorSnap?.exists)\n } catch (err) {\n console.warn(\n `[db] composite index missing for \"${collection}\" (falling back to filtered query):`,\n err instanceof Error ? err.message : err\n )\n const fallbackLimit = sortField || opts?.cursor ? Math.max(maxDocs * 5, defaultListLimit) : maxDocs\n try {\n snap = await filteredQuery.limit(fallbackLimit).get()\n } catch {\n snap = await baseQuery.limit(fallbackLimit).get()\n }\n }\n\n const docs = snap.docs\n .map((s) => fromFirestoreDoc(collection, s.id, s.data() ?? {}, hasSelect))\n .filter((d) => opts?.includeDeleted || !d.deleted)\n\n return sortAndSliceFallbackDocs(docs, sortField, sortDir, opts?.cursor, sortedInDb, appliedCursorInDb)\n}\n\nexport const sortAndSliceFallbackDocs = <T extends Record<string, any> & { id: string }>(\n docs: T[],\n sortField: string | undefined,\n sortDir: 'asc' | 'desc',\n cursor: string | undefined,\n sortedInDb: boolean,\n appliedCursorInDb: boolean\n): T[] => {\n let result = docs\n if (!sortedInDb) {\n result.sort((a, b) => {\n if (sortField) {\n const va = a[sortField] instanceof Date ? a[sortField].getTime() : a[sortField]\n const vb = b[sortField] instanceof Date ? b[sortField].getTime() : b[sortField]\n if (va !== vb) return sortDir === 'asc' ? (va > vb ? 1 : -1) : va < vb ? 1 : -1\n }\n return a.id.localeCompare(b.id)\n })\n }\n if (cursor && !appliedCursorInDb) {\n const idx = result.findIndex((d) => d.id === cursor)\n result = idx >= 0 ? result.slice(idx + 1) : []\n }\n return result\n}\n\nexport const runChunked = async <T>(\n items: readonly T[],\n fn: (item: T) => Promise<unknown>,\n concurrency = 25\n): Promise<void> => {\n for (let i = 0; i < items.length; i += concurrency) {\n await Promise.all(items.slice(i, i + concurrency).map(fn))\n }\n}\n\nexport const isCreateOwnScopeAllowed = (\n collection: string,\n userId: string | undefined,\n data: Record<string, any>\n): boolean => {\n if (!userId) return false\n const def = getCollectionDef(collection)\n const rel = def.userRelation?.type ?? '1:N'\n if (rel === 'global') return false\n if (rel === '1:1' || rel === '1:N') {\n const uf = def.userRelation?.userField ?? (rel === '1:1' ? 'id' : 'userId')\n const ownerVal = data[uf] ?? (uf === 'id' ? data.id : undefined)\n if (ownerVal && ownerVal !== userId) return false\n } else if (rel === 'M:N' && !def.userRelation?.junction) {\n const uif = def.userRelation?.userIdsField ?? 'userIds'\n const ownerIds = data[uif]\n if (Array.isArray(ownerIds) && !ownerIds.includes(userId)) return false\n }\n return true\n}\n\nexport const buildScopedCollectionQuery = (\n baseQuery: FirebaseFirestore.Query,\n collection: string,\n scopedUserId: string | undefined,\n where: Record<string, unknown> | undefined,\n select: readonly (string | symbol | number)[] | undefined\n): FirebaseFirestore.Query => {\n const def = getCollectionDef(collection)\n const rel = def.userRelation?.type ?? '1:N'\n let q = baseQuery\n if (scopedUserId && rel !== 'global') {\n q =\n rel === '1:1' || rel === '1:N'\n ? q.where(def.userRelation?.userField ?? 'userId', '==', scopedUserId)\n : q.where(def.userRelation?.userIdsField ?? 'userIds', 'array-contains', scopedUserId)\n }\n if (where) {\n for (const [field, value] of Object.entries(where)) {\n if (value === undefined) continue\n q = Array.isArray(value) ? q.where(field, 'in', value.slice(0, 30)) : q.where(field, '==', value)\n }\n }\n if (select?.length) q = q.select(...(select as string[]))\n return q\n}\n\nexport const wireCoreCollectionHooks = (): void => {\n const chatDef = collectionRegistry.get('chat')\n if (chatDef && !chatDef.onHardDelete) {\n chatDef.onHardDelete = async (doc: { id?: string }, core: Core) => {\n if (!doc.id) return\n const db = core.db.firestore()\n await core.internals.resilience.acquireLimit('firestore')\n await drainQueryBatchDelete(db, db.collection('chat').doc(doc.id).collection('messages'))\n }\n }\n const fileDef = collectionRegistry.get('file')\n if (fileDef && !fileDef.onHardDelete) {\n fileDef.onHardDelete = async (doc: { id?: string }, core: Core) => {\n if (!doc.id) return\n await core.internals.resilience.acquireLimit('storage')\n await core.files.bucket().file(doc.id).delete({ ignoreNotFound: true }).catch(() => {})\n }\n }\n}\n", "import { CORE_CONFIG } from '../config'\nimport { fileRef } from '../db'\n\nexport const canAccessFile = (userId: string, ref: string, role?: string): boolean =>\n role === 'admin' ||\n userId === CORE_CONFIG.auth.adminUserId ||\n (fileRef.safeParse(ref).success && ref.slice(0, -25) === userId)\n\nexport const hasValidMagicBytes = (type: string, bytes: Uint8Array): boolean => {\n switch (type) {\n case 'application/pdf':\n return (\n bytes.byteLength >= 5 &&\n bytes[0] === 0x25 &&\n bytes[1] === 0x50 &&\n bytes[2] === 0x44 &&\n bytes[3] === 0x46 &&\n bytes[4] === 0x2d\n )\n case 'image/png':\n return (\n bytes.byteLength >= 8 &&\n bytes[0] === 0x89 &&\n bytes[1] === 0x50 &&\n bytes[2] === 0x4e &&\n bytes[3] === 0x47 &&\n bytes[4] === 0x0d &&\n bytes[5] === 0x0a &&\n bytes[6] === 0x1a &&\n bytes[7] === 0x0a\n )\n case 'image/jpeg':\n return bytes.byteLength >= 3 && bytes[0] === 0xff && bytes[1] === 0xd8 && bytes[2] === 0xff\n case 'image/webp':\n return (\n bytes.byteLength >= 12 &&\n bytes[0] === 0x52 &&\n bytes[1] === 0x49 &&\n bytes[2] === 0x46 &&\n bytes[3] === 0x46 &&\n bytes[8] === 0x57 &&\n bytes[9] === 0x45 &&\n bytes[10] === 0x42 &&\n bytes[11] === 0x50\n )\n case 'image/gif':\n return (\n bytes.byteLength >= 6 &&\n bytes[0] === 0x47 &&\n bytes[1] === 0x49 &&\n bytes[2] === 0x46 &&\n bytes[3] === 0x38 &&\n (bytes[4] === 0x37 || bytes[4] === 0x39) &&\n bytes[5] === 0x61\n )\n case 'image/bmp':\n return bytes.byteLength >= 2 && bytes[0] === 0x42 && bytes[1] === 0x4d\n case 'image/tiff':\n return (\n bytes.byteLength >= 4 &&\n ((bytes[0] === 0x49 && bytes[1] === 0x49 && bytes[2] === 0x2a && bytes[3] === 0x00) ||\n (bytes[0] === 0x4d && bytes[1] === 0x4d && bytes[2] === 0x00 && bytes[3] === 0x2a))\n )\n case 'image/avif':\n return (\n bytes.byteLength >= 12 &&\n bytes[4] === 0x66 &&\n bytes[5] === 0x74 &&\n bytes[6] === 0x79 &&\n bytes[7] === 0x70 &&\n ((bytes[8] === 0x61 && bytes[9] === 0x76 && bytes[10] === 0x69 && (bytes[11] === 0x66 || bytes[11] === 0x73)) ||\n (bytes[8] === 0x6d && bytes[9] === 0x69 && bytes[10] === 0x66 && bytes[11] === 0x31))\n )\n default:\n return false\n }\n}\n", "import { createHash } from 'node:crypto'\nimport type { Bucket } from '@google-cloud/storage'\nimport type { DbRole } from '../config'\nimport {\n entryId,\n type DbListOptions,\n type EntryId,\n type PaginatedList,\n type SelectModel\n} from '../db'\nimport type { Core } from '../index'\nimport {\n fileBody,\n fileRef,\n signedUploadInput,\n type FileBody,\n type FileRef,\n type FileType,\n type SignedDownloadUrlResult,\n type SignedUploadInput,\n type SignedUploadUrlResult\n} from './schema'\nimport { canAccessFile } from './utils'\n\nexport class FilesService {\n readonly #core: Core\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n }\n\n bucket = (isDev: boolean = this.#core.env.isDev): Bucket => this.#core.db.bucket(isDev)\n\n canAccess = (\n ref: string,\n userId: EntryId = this.#core.userId,\n role: DbRole = this.#core.role\n ): boolean => canAccessFile(userId, ref, role)\n\n #assertAccess = (ref: FileRef): void => {\n if (!this.canAccess(ref)) this.#core.errors.httpError(403, 'Forbidden: file access denied', 'FORBIDDEN')\n }\n\n upload = async (\n file: FileBody,\n userId: EntryId = this.#core.userId || this.#core.config.auth.adminUserId\n ): Promise<{ ref: FileRef }> => {\n entryId.parse(userId)\n fileBody.parse(file)\n const shaSum = createHash('sha256').update(file.bytes).digest('hex').slice(0, 24)\n const ref = fileRef.parse(`${userId}_${shaSum}`)\n const existing = await this.#core.db.read('file', ref, true, { bypassRbac: true })\n const step = this.#core.step\n\n if (!existing) {\n await step(\n 'upload-storage',\n async () => {\n await this.#core.internals.resilience.acquireLimit('storage')\n await this.bucket().file(ref).save(Buffer.from(file.bytes), {\n resumable: false,\n contentType: file.type,\n metadata: {\n cacheControl: 'private, max-age=31536000, immutable',\n metadata: { fileName: file.name, userId, shaSum }\n }\n })\n },\n {\n rollback: async () => {\n await this.#core.internals.resilience.acquireLimit('storage')\n await this.bucket().file(ref).delete({ ignoreNotFound: true })\n }\n }\n )\n }\n\n await step(\n 'upload-meta',\n async () => {\n if (!existing) {\n await this.#core.db.create(\n 'file',\n {\n id: ref,\n shaSum,\n fileName: file.name,\n contentType: file.type,\n size: file.bytes.byteLength,\n userId,\n scan: null,\n scanError: null,\n deleted: false\n },\n { bypassRbac: true }\n )\n } else if (existing.deleted) {\n await this.#core.db.update('file', ref, { deleted: false, fileName: file.name }, { bypassRbac: true })\n }\n },\n {\n rollback: async () => {\n if (!existing) await this.#core.db.hardDelete('file', ref, { bypassRbac: true }).catch(() => {})\n else if (existing.deleted) {\n await this.#core.db.update('file', ref, { deleted: true }, { bypassRbac: true }).catch(() => {})\n }\n }\n }\n )\n\n return { ref }\n }\n\n #signGcsUrl = async (\n ref: FileRef,\n action: 'read' | 'write',\n expiresMs: number,\n contentType?: FileType\n ): Promise<string> => {\n await this.#core.internals.resilience.acquireLimit('storage')\n const bucket = this.bucket()\n try {\n const [signed] = await bucket.file(ref).getSignedUrl({\n version: 'v4',\n action,\n expires: expiresMs,\n ...(contentType ? { contentType } : {})\n })\n return signed\n } catch (err) {\n if (!this.#core.env.isDev && Boolean(process.env.K_SERVICE)) {\n return this.#core.errors.httpError(502, 'Failed to generate signed file URL', 'GCS_SIGN_FAILED')\n }\n const query = action === 'write' ? `uploadType=media&expires=${expiresMs}` : `alt=media&expires=${expiresMs}`\n return `https://storage.googleapis.com/${bucket.name}/${encodeURIComponent(ref)}?${query}`\n }\n }\n\n getSignedUploadUrl = async (\n rawInput: SignedUploadInput,\n userId: EntryId = this.#core.userId || this.#core.config.auth.adminUserId,\n expiresInMs = 15 * 60_000\n ): Promise<SignedUploadUrlResult> => {\n entryId.parse(userId)\n const input = signedUploadInput.parse(rawInput)\n const shaSum = input.sha256.toLowerCase().slice(0, 24)\n const ref = fileRef.parse(`${userId}_${shaSum}`)\n const existing = await this.#core.db.read('file', ref, true, { bypassRbac: true })\n const expiresMs = Date.now() + Math.max(60_000, expiresInMs)\n const expiresAt = new Date(expiresMs).toISOString()\n\n if (existing && !existing.deleted) {\n return { ref, url: '', expiresAt, deduplicated: true }\n }\n\n const url = await this.#signGcsUrl(ref, 'write', expiresMs, input.type)\n return { ref, url, expiresAt, deduplicated: false }\n }\n\n getSignedDownloadUrl = async (ref: FileRef, expiresInMs = 15 * 60_000): Promise<SignedDownloadUrlResult> => {\n fileRef.parse(ref)\n this.#assertAccess(ref)\n const doc = await this.#core.db.read('file', ref, false, { bypassRbac: true })\n if (!doc) this.#core.errors.httpError(404, `File not found: ${ref}`, 'NOT_FOUND')\n\n const expiresMs = Date.now() + Math.max(60_000, expiresInMs)\n const expiresAt = new Date(expiresMs).toISOString()\n const url = await this.#signGcsUrl(ref, 'read', expiresMs)\n return { ref, url, expiresAt }\n }\n\n download = async (ref: FileRef): Promise<Buffer> => {\n await this.#core.internals.resilience.acquireLimit('storage')\n try {\n return (await this.bucket().file(ref).download())[0]\n } catch {\n throw new Error(`File not found: ${ref}`)\n }\n }\n\n get = async (ref: FileRef): Promise<FileBody> => {\n fileRef.parse(ref)\n this.#assertAccess(ref)\n const [bytes, doc] = await Promise.all([\n this.download(ref),\n this.#core.db.read('file', ref, false, { bypassRbac: true })\n ])\n if (!doc) throw new Error(`File not found: ${ref}`)\n return fileBody.parse({\n bytes,\n name: doc.fileName || ref,\n type: (doc.contentType as FileType) || 'application/pdf'\n })\n }\n\n list = async (options?: DbListOptions<SelectModel<'file'>>): Promise<PaginatedList<SelectModel<'file'>>> =>\n this.#core.db.list('file', {\n ...(this.#core.userId && this.#core.role !== 'admin' ? { userId: this.#core.userId } : {}),\n ...options\n })\n\n delete = async (ref: FileRef): Promise<{ ref: FileRef; deleted: true }> => {\n fileRef.parse(ref)\n this.#assertAccess(ref)\n await this.#core.db.delete('file', ref, { bypassRbac: true })\n return { ref, deleted: true }\n }\n\n hardDelete = async (ref: FileRef): Promise<{ ref: FileRef }> => {\n fileRef.parse(ref)\n this.#assertAccess(ref)\n const step = this.#core.step\n await step(\n 'hard-delete-file',\n async () => {\n const prev = await this.#core.db.read('file', ref, true, { bypassRbac: true })\n await this.#core.db.hardDelete('file', ref, { bypassRbac: true })\n return prev ?? null\n },\n {\n rollback: async (prev) => {\n if (!prev) return\n await this.#core.db\n .firestore()\n .collection('file')\n .doc(ref)\n .set({\n ...prev,\n createdAt: prev.createdAt ? new Date(prev.createdAt) : new Date(),\n updatedAt: new Date()\n })\n .catch(() => {})\n }\n }\n )\n return { ref }\n }\n}\n", "import type { Context } from 'hono'\nimport type { AppEnv } from '../config'\nimport type { EntryId } from '../db'\nimport { core } from '../index'\nimport type { FileType } from './schema'\n\nexport const coreFilesRoutes = {\n 'files.list': {\n handler: async ({ userId }: { userId: EntryId }) => core.db.list('file', { userId }, { bypassRbac: true })\n },\n 'files.upload': {\n handler: async ({ c, userId }: { c: Context<AppEnv>; userId: EntryId }) => {\n const file = (await c!.req.formData()).get('file')\n if (!(file instanceof File)) return core.errors.httpError(400, 'Missing \"file\" field', 'INVALID_FILE')\n return core.files.upload(\n {\n bytes: new Uint8Array(await file.arrayBuffer()),\n name: file.name || 'upload',\n type: file.type as FileType\n },\n userId\n )\n }\n },\n 'files.get': {\n handler: async ({ c }: { c: Context<AppEnv> }) => {\n const ref = c!.req.param('ref') ?? ''\n if (c!.req.query('meta') === 'true') {\n const entry = await core.db.read('file', ref, false, { bypassRbac: true })\n return entry ?? core.errors.httpError(404, 'File not found', 'NOT_FOUND')\n }\n if (c!.req.query('signed') === 'true') {\n return core.files.getSignedDownloadUrl(ref)\n }\n const { bytes, type } = await core.files.get(ref)\n return new Response(Buffer.from(bytes), {\n headers: { 'content-type': type, 'cache-control': 'private, max-age=3600, immutable' }\n })\n }\n },\n 'files.delete': {\n handler: async ({ c }: { c: Context<AppEnv> }) => core.files.delete(c!.req.param('ref') ?? '')\n }\n}\n", "import { z } from 'zod'\nimport type { FileScanError, UnparseableReason } from '../files'\nimport {\n getRegisteredAttachmentTypes,\n processAttachmentsInput,\n type AttachmentTypesMap,\n type ProcessAttachmentsInput,\n type ScanAttachmentInput\n} from './schema'\n\nexport const schemaFor = (\n type: string,\n types: AttachmentTypesMap = getRegisteredAttachmentTypes()\n): Record<string, unknown> | undefined =>\n type in types ? (z.toJSONSchema(types[type]!.schema, { io: 'output' }) as Record<string, unknown>) : undefined\n\nexport const parseFields = (\n type: string,\n fields: Record<string, unknown>,\n types: AttachmentTypesMap = getRegisteredAttachmentTypes()\n): Record<string, unknown> => (type in types ? (types[type]!.schema.parse(fields) as Record<string, unknown>) : {})\n\nexport const extractAttachmentTasks = (input: ProcessAttachmentsInput): ScanAttachmentInput[] =>\n processAttachmentsInput.parse(input).refs.map((item) => (typeof item === 'string' ? { ref: item } : item))\n\nexport const buildScanError = (\n reason: UnparseableReason,\n agentHint: string,\n diagnosticMessage?: string\n): FileScanError => ({\n status: 'unparseable',\n reason,\n agentHint,\n ...(diagnosticMessage ? { diagnosticMessage: diagnosticMessage.slice(0, 500) } : {}),\n failedAt: new Date().toISOString()\n})\n\nexport const extractHttpStatus = (err: unknown): number | undefined => {\n if (!err || typeof err !== 'object') return undefined\n const rec = err as Record<string, unknown>\n if (typeof rec.statusCode === 'number') return rec.statusCode\n if (typeof rec.status === 'number') return rec.status\n const msg = err instanceof Error ? err.message : String(err)\n const match = /\\b(?:status(?:\\s+code)?|http)\\s*[:=]?\\s*(4\\d\\d|5\\d\\d)\\b/i.exec(msg)\n return match?.[1] ? Number(match[1]) : undefined\n}\n\nconst TRANSIENT_TOKENS = ['aborted', 'timed out', 'econnreset', 'etimedout', 'socket hang up', 'rate limit']\n\nconst DEFECT_RULES: ReadonlyArray<{\n reason: UnparseableReason\n hint: string\n match: (status: number | undefined, lower: string) => boolean\n}> = [\n {\n reason: 'PASSWORD_PROTECTED',\n hint: 'This document is password-protected or encrypted and cannot be read. Please upload an unlocked copy of the document.',\n match: (_, lower) => lower.includes('password') || lower.includes('encrypted')\n },\n {\n reason: 'UNSUPPORTED_FORMAT',\n hint: 'This file format is not supported by the document scanner. Please upload a valid PDF or standard image (JPEG, PNG, WebP).',\n match: (status, lower) =>\n status === 415 || lower.includes('unsupported media') || lower.includes('unsupported format')\n },\n {\n reason: 'EMPTY_OR_UNREADABLE',\n hint: 'The uploaded document appears blank or unreadable. Please upload a clear, legible scan or photo of the document.',\n match: (_, lower) =>\n lower.includes('empty description') ||\n lower.includes('empty_or_unreadable') ||\n lower.includes('no readable text')\n },\n {\n reason: 'CLASSIFICATION_REJECTED',\n hint: 'The document could not be classified into a valid document type. Please upload a clear, complete document.',\n match: (_, lower) => lower.includes('classification_rejected')\n },\n {\n reason: 'CORRUPTED_FILE',\n hint: 'This file appears corrupted or malformed and could not be parsed. Please export or re-upload a valid PDF or image file.',\n match: (status, lower) =>\n status === 400 ||\n status === 422 ||\n lower.includes('corrupt') ||\n lower.includes('malformed') ||\n lower.includes('invalid pdf') ||\n lower.includes('invalid image') ||\n lower.includes('failed to process document') ||\n lower.includes('could not parse')\n }\n]\n\nexport const classifyPermanentScanDefect = (err: unknown): FileScanError | null => {\n if (!err) return null\n const bodyStr =\n typeof err === 'object' && 'body' in err && typeof (err as { body?: unknown }).body === 'string'\n ? (err as { body: string }).body\n : ''\n const msg = `${err instanceof Error ? err.message : String(err)} ${bodyStr}`.trim()\n const lower = msg.toLowerCase()\n const status = extractHttpStatus(err)\n\n if (\n status === 408 ||\n status === 429 ||\n (status !== undefined && status >= 500) ||\n TRANSIENT_TOKENS.some((t) => lower.includes(t))\n ) {\n return null\n }\n\n const matched = DEFECT_RULES.find((rule) => rule.match(status, lower))\n return matched ? buildScanError(matched.reason, matched.hint, msg) : null\n}\n", "import type { JevQuestion } from '../ai'\nimport type { SelectModel } from '../db'\nimport { fileScan, fileScanError, type FileRef, type FileScan, type FileScanError } from '../files'\nimport type { Core } from '../index'\nimport type { StepRunner } from '../tasks'\nimport {\n getRegisteredAttachmentTypes,\n processAttachmentsOutput,\n scanAttachmentInput,\n scanAttachmentOutput,\n type AttachmentTypesMap,\n type ProcessedAttachment,\n type ProcessAttachmentsInput,\n type ProcessAttachmentsOutput,\n type ScanAttachmentInput,\n type ScanAttachmentOutput\n} from './schema'\nimport {\n buildScanError,\n classifyPermanentScanDefect,\n extractAttachmentTasks,\n parseFields,\n schemaFor\n} from './utils'\n\nexport class AttachmentsService {\n readonly #core: Core\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n }\n\n #wrapScanStep = async <T>(fn: () => Promise<T>, onDefect: (defect: FileScanError) => void): Promise<T> => {\n try {\n return await fn()\n } catch (err) {\n const defect = classifyPermanentScanDefect(err)\n if (defect) {\n onDefect(defect)\n return this.#core.errors.nonRetryableError(defect.agentHint, defect.reason)\n }\n throw err\n }\n }\n\n #findCrossUserByShaSum = async (\n ref: FileRef,\n shaSum: string,\n requestedType?: string\n ): Promise<{ scan?: FileScan; scanError?: FileScanError } | undefined> => {\n if (!shaSum || shaSum.length < 24) return undefined\n try {\n await this.#core.internals.resilience.acquireLimit('firestore')\n const snap = await this.#core.db.firestore().collection('file').where('shaSum', '==', shaSum).limit(5).get()\n for (const doc of snap.docs) {\n if (doc.id === ref) continue\n const data = doc.data()\n if (data.deleted === true) continue\n if (data.scan) {\n const parsedScan = fileScan.safeParse(data.scan)\n if (parsedScan.success && (!requestedType || parsedScan.data.type === requestedType)) {\n return { scan: parsedScan.data }\n }\n }\n if (data.scanError) {\n const parsedErr = fileScanError.safeParse(data.scanError)\n if (parsedErr.success) {\n return { scanError: parsedErr.data }\n }\n }\n }\n } catch {}\n return undefined\n }\n\n classify = async (\n attachmentContent: string,\n types: AttachmentTypesMap = getRegisteredAttachmentTypes()\n ): Promise<{ attachmentType: string; confidence: number }> => {\n const entries = Object.entries(types)\n if (!entries.length) return { attachmentType: 'other', confidence: 1 }\n const questions: Record<string, JevQuestion> = {\n documentType: {\n type: 'choice',\n instructions:\n 'Classify the attached document (its full text is the state) into exactly one type. Choose \"other\" when it matches none of the specific types.',\n criteria: {\n ...Object.fromEntries(entries.map(([k, v]) => [k, v.description])),\n other: 'Unrecognized document, plain image/diagram, or none of the specific attachment types'\n }\n }\n }\n const { answers } = await this.#core.ai.decide({ document: attachmentContent.slice(0, 80_000) }, questions)\n const ans = answers.documentType\n return ans?.type === 'choice'\n ? { attachmentType: ans.choice, confidence: ans.confidence }\n : { attachmentType: 'other', confidence: 0 }\n }\n\n #executeScanOcrAndClassify = async (opts: {\n ref: FileRef\n contentType: string\n initialType?: string\n types: AttachmentTypesMap\n step: StepRunner\n onDefect: (d: FileScanError) => void\n }): Promise<FileScan> => {\n const { ref, contentType, initialType, types, step, onDefect } = opts\n const isImage = contentType.startsWith('image/')\n let dataUrlP: Promise<string> | undefined\n const getDataUrl = () =>\n (dataUrlP ??= (async () =>\n `data:${contentType};base64,${(await this.#core.files.download(ref)).toString('base64')}`)())\n\n const hasTypes = Object.keys(types).length > 0\n let resolvedType: string | undefined = hasTypes ? initialType : 'other'\n let confidence = 1\n let markdown = ''\n\n if (!resolvedType || resolvedType === 'other') {\n const ocrRes = await step('ocr', ({ signal }) =>\n this.#wrapScanStep(async () => this.#core.ai.vision(await getDataUrl(), { signal }), onDefect)\n )\n markdown = ocrRes.markdown\n if (!markdown) {\n markdown = await step('vision', ({ signal }) =>\n this.#wrapScanStep(async () => this.#core.ai.describeImage(await getDataUrl(), signal), onDefect)\n )\n resolvedType = 'other'\n } else {\n if (!resolvedType) {\n const classified = await step('classify', () =>\n this.#wrapScanStep(() => this.classify(markdown, types), onDefect)\n )\n resolvedType = classified.attachmentType\n confidence = classified.confidence\n }\n if (hasTypes && resolvedType === 'other' && isImage) {\n const visionDesc = await step('vision', ({ signal }) =>\n this.#wrapScanStep(async () => this.#core.ai.describeImage(await getDataUrl(), signal), onDefect)\n )\n markdown = `${markdown}\\n\\n${visionDesc}`.trim()\n }\n }\n }\n\n let fields: Record<string, unknown> = {}\n const schema = resolvedType && resolvedType !== 'other' ? schemaFor(resolvedType, types) : undefined\n if (schema && resolvedType) {\n const extract = await step('extract', ({ signal }) =>\n this.#wrapScanStep(async () => this.#core.ai.vision(await getDataUrl(), { schema, signal }), onDefect)\n )\n fields = parseFields(resolvedType, extract.annotation, types)\n if (!markdown) markdown = extract.markdown\n }\n\n if (markdown.trim().length < 5 && Object.keys(fields).length === 0) {\n const defect = buildScanError(\n 'EMPTY_OR_UNREADABLE',\n 'The uploaded document appears blank or unreadable (fewer than 5 characters detected). Please upload a clear, legible scan or photo of the document.'\n )\n onDefect(defect)\n return this.#core.errors.nonRetryableError(defect.agentHint, defect.reason)\n }\n\n return { type: resolvedType ?? 'other', confidence, fields, markdown }\n }\n\n scan = async (\n raw: ScanAttachmentInput,\n opts?: { types?: AttachmentTypesMap; step?: StepRunner; preloadedFile?: SelectModel<'file'> }\n ): Promise<ScanAttachmentOutput> => {\n const step = opts?.step ?? this.#core.step\n const types = opts?.types ?? getRegisteredAttachmentTypes()\n const preloadedFile = opts?.preloadedFile\n const { ref, type } = scanAttachmentInput.parse(raw)\n if (type && type !== 'other' && Object.keys(types).length > 0 && !(type in types)) {\n throw new Error(`Invalid attachment type: ${type}`)\n }\n\n return this.#core.internals.resilience.singleflight(\n `scan:${this.#core.env.isDev ? 'dev' : 'prod'}:${ref}:${type ?? ''}`,\n async () => {\n const entry =\n preloadedFile ?? (await step('read-meta', () => this.#core.db.read('file', ref, false, { bypassRbac: true })))\n if (!entry) throw new Error(`File not found: ${ref}`)\n if (entry.scan) return scanAttachmentOutput.parse(entry.scan)\n if (entry.scanError) {\n return this.#core.errors.nonRetryableError(entry.scanError.agentHint, entry.scanError.reason)\n }\n\n const shaSum = entry.shaSum || ref.slice(-24)\n const crossUserMatch = await this.#findCrossUserByShaSum(ref, shaSum, type)\n if (crossUserMatch?.scan) {\n await step('persist', () =>\n this.#core.db.update('file', ref, { scan: crossUserMatch.scan!, scanError: null }, { bypassRbac: true })\n )\n return scanAttachmentOutput.parse(crossUserMatch.scan)\n }\n if (crossUserMatch?.scanError) {\n await this.#core.db\n .update('file', ref, { scanError: crossUserMatch.scanError, scan: null }, { bypassRbac: true })\n .catch(() => {})\n return this.#core.errors.nonRetryableError(\n crossUserMatch.scanError.agentHint,\n crossUserMatch.scanError.reason\n )\n }\n\n let capturedDefect: FileScanError | undefined\n try {\n const scan = await this.#executeScanOcrAndClassify({\n ref,\n contentType: entry.contentType || 'application/pdf',\n initialType: type,\n types,\n step,\n onDefect: (d) => {\n capturedDefect = d\n }\n })\n await step('persist', () =>\n this.#core.db.update('file', ref, { scan, scanError: null }, { bypassRbac: true })\n )\n return scanAttachmentOutput.parse(scan)\n } catch (err) {\n const defect = capturedDefect ?? classifyPermanentScanDefect(err)\n if (defect) {\n await this.#core.db\n .update('file', ref, { scanError: defect, scan: null }, { bypassRbac: true })\n .catch(() => {})\n if (err instanceof this.#core.errors.NonRetryableError) throw err\n return this.#core.errors.nonRetryableError(defect.agentHint, defect.reason)\n }\n throw err\n }\n }\n )\n }\n\n #scanShortCircuit = async ({ input }: { input: ScanAttachmentInput }): Promise<ScanAttachmentOutput | undefined> => {\n const entry = await this.#core.db.read('file', input.ref, false, { bypassRbac: true })\n if (entry?.scan) return scanAttachmentOutput.parse(entry.scan)\n if (entry?.scanError) {\n return this.#core.errors.nonRetryableError(entry.scanError.agentHint, entry.scanError.reason)\n }\n return undefined\n }\n\n #scanTask = async ({\n input,\n step,\n types,\n preloadedFile\n }: {\n input: ScanAttachmentInput\n step: StepRunner\n types?: AttachmentTypesMap\n preloadedFile?: SelectModel<'file'>\n }): Promise<ProcessedAttachment> => {\n try {\n return { ref: input.ref, scan: await this.scan(input, { step, types, preloadedFile }) }\n } catch (err) {\n if (this.#core.errors.isNonRetryableError(err)) {\n return { ref: input.ref, error: err instanceof Error ? err.message : String(err) }\n }\n return { ref: input.ref, error: 'Temporary scanning service unavailability. Please retry.' }\n }\n }\n\n process = async (\n raw: ProcessAttachmentsInput,\n opts?: { types?: AttachmentTypesMap; step?: StepRunner }\n ): Promise<ProcessAttachmentsOutput> => {\n const tasks = extractAttachmentTasks(raw)\n const step = opts?.step ?? this.#core.step\n\n const uniqueRefs = [...new Set(tasks.map((t) => t.ref))]\n const existingFiles = await this.#core.db.list('file', { ids: uniqueRefs }, { bypassRbac: true })\n const fileMap = new Map<FileRef, SelectModel<'file'>>(existingFiles.map((f) => [f.id, f]))\n\n const attachments = await step.map(\n 'process-attachments',\n tasks,\n (taskInput) =>\n this.#scanTask({\n input: taskInput,\n step: this.#core.internals.workflows.createStepRunner('workflow'),\n types: opts?.types,\n preloadedFile: fileMap.get(taskInput.ref)\n }),\n {\n timeout: `${this.#core.config.tasks.scanDeadlineSeconds}s`,\n shortCircuit: (taskInput) => {\n const fileDoc = fileMap.get(taskInput.ref)\n if (fileDoc?.scan) {\n return { ref: taskInput.ref, scan: scanAttachmentOutput.parse(fileDoc.scan) }\n }\n if (fileDoc?.scanError) {\n return { ref: taskInput.ref, error: fileDoc.scanError.agentHint }\n }\n return undefined\n }\n }\n )\n\n return processAttachmentsOutput.parse({ attachments })\n }\n\n get internals() {\n return {\n scanShortCircuit: this.#scanShortCircuit\n }\n }\n}\n", "import { core } from '../index'\nimport type { StepRunner } from '../tasks'\nimport {\n processAttachmentsInput,\n processAttachmentsOutput,\n scanAttachmentInput,\n scanAttachmentOutput,\n type ProcessAttachmentsInput,\n type ScanAttachmentInput\n} from './schema'\n\nexport const coreAttachmentsRoutes = {\n 'attachments.scan': {\n mode: 'workflow' as const,\n input: scanAttachmentInput,\n output: scanAttachmentOutput,\n shortCircuit: ({ input }: { input: ScanAttachmentInput }) => core.internals.context.scanShortCircuit({ input }),\n handler: ({ input, step }: { input: ScanAttachmentInput; step: StepRunner }) =>\n core.attachments.scan(input, { step })\n },\n 'attachments.process': {\n mode: 'workflow' as const,\n input: processAttachmentsInput,\n output: processAttachmentsOutput,\n handler: ({ input, step }: { input: ProcessAttachmentsInput; step: StepRunner }) =>\n core.attachments.process(input, { step })\n }\n}\n", "import { z } from 'zod'\nimport {\n CORE_CONFIG,\n type AuthEmailPurpose,\n type AuthTokenPurpose,\n type DbRole,\n type TransactionalEmailPayload\n} from '../config'\nimport { entryId, type BaseEntryFields, type EntryId } from '../db'\n\nexport { type AuthEmailPurpose, type AuthTokenPurpose, type TransactionalEmailPayload }\n\nexport const SESSION_COOKIE = CORE_CONFIG.auth.sessionCookie\nexport const SESSION_EXPIRES_IN = CORE_CONFIG.auth.sessionExpiresInMs\nexport const ADMIN_USER_ID: EntryId = CORE_CONFIG.auth.adminUserId\n\nexport type OAuthProvider = 'google' | 'apple'\n\nexport interface LinkedProvider {\n provider: OAuthProvider\n providerUserId: string\n email?: string | null\n linkedAt: Date\n}\n\nexport interface CachedTokenEntry {\n uid: EntryId\n role: DbRole\n exp: number\n cachedAt: number\n strictVerified: boolean\n emailVerified?: boolean\n}\n\nexport interface UserAuthMetaRecord {\n email?: string | null\n emailVerified?: boolean\n name?: string | null\n avatarUrl?: string | null\n recoveryEmail?: string | null\n recoveryEmailVerified?: boolean\n linkedProviders?: LinkedProvider[]\n providerKeys?: string[]\n createdAt?: Date\n updatedAt?: Date\n}\n\nexport interface VerifiedOidcClaims {\n sub: string\n email: string | null\n emailVerified: boolean\n name?: string\n picture?: string\n}\n\nexport interface AuthUser {\n id: EntryId\n email: string | null\n emailVerified: boolean\n name: string | null\n avatarUrl?: string | null\n /** Secondary recovery email (stored normalized/lowercase) */\n recoveryEmail?: string | null\n /** True only after the user verifies ownership of `recoveryEmail` via OTP */\n recoveryEmailVerified?: boolean\n linkedProviders?: LinkedProvider[]\n customClaims?: Record<string, unknown>\n deleted: boolean\n createdAt: Date\n updatedAt: Date\n}\n\nexport interface AuthTokenDoc extends BaseEntryFields {\n userId: EntryId\n purpose: AuthTokenPurpose\n /** Target email address (primary email or recovery email) */\n targetEmail: string\n /** SHA-256 hex digest of the 6-digit OTP code or 32-byte URL token */\n tokenHash: string\n urlTokenHash?: string\n /** Max 5 failed verification attempts before automatic invalidation */\n attempts: number\n expiresAt: Date\n consumedAt?: Date | null\n}\n\nexport const eraseUserInput = z.object({\n userId: entryId,\n backupBeforeErase: z.boolean().default(false)\n})\nexport const eraseUserOutput = z.object({\n userId: entryId,\n backupOperation: z.string().optional(),\n erasedFiles: z.number(),\n erasedChats: z.number(),\n erasedCollections: z.record(z.string(), z.number()).optional(),\n erasedUser: z.boolean()\n})\nexport type EraseUserInput = z.input<typeof eraseUserInput>\nexport type EraseUserOutput = z.infer<typeof eraseUserOutput>\n\nexport const customTokenBody = z\n .object({ uid: entryId.refine((id) => id !== CORE_CONFIG.auth.adminUserId, 'Reserved UID').optional() })\n .default({})\nexport const sessionBody = z.object({ idToken: z.string().min(1) })\nexport const emailSignUpBody = z.object({\n email: z.string().email(),\n password: z.string().min(8).max(128),\n name: z.string().min(1).max(120).optional()\n})\nexport const emailSignInBody = z.object({ email: z.string().email(), password: z.string().min(1).max(128) })\n\nexport const socialSignInInput = z.object({\n provider: z.enum(['google', 'apple']),\n /** OIDC ID token returned by Apple Sign-In (iOS/Capacitor/Web) or Google Sign-In */\n idToken: z.string().min(20),\n /** Optional raw nonce for Apple Sign-In replay protection */\n nonce: z.string().optional(),\n /** Optional access token (Google) */\n accessToken: z.string().optional(),\n /**\n * Apple iOS/Capacitor quirk: Apple ONLY sends the user's `name` on the VERY FIRST authorization.\n * Accept optional first-time profile data from the client and persist it immediately.\n */\n profile: z\n .object({\n name: z.string().min(1).max(128).optional(),\n avatarUrl: z.string().url().optional()\n })\n .optional()\n})\nexport type SocialSignInInput = z.infer<typeof socialSignInInput>\n\nexport const sendVerificationEmailBody = z.object({}).default({})\nexport const verifyEmailBody = z.object({\n email: z.string().email(),\n codeOrToken: z.string().min(4).max(512)\n})\nexport type VerifyEmailInput = z.infer<typeof verifyEmailBody>\n\nexport const forgotPasswordBody = z.object({\n email: z.string().email()\n})\nexport type ForgotPasswordInput = z.infer<typeof forgotPasswordBody>\n\nexport const resetPasswordBody = z.object({\n email: z.string().email(),\n codeOrToken: z.string().min(4).max(512),\n newPassword: z.string().min(8).max(128)\n})\nexport type ResetPasswordInput = z.infer<typeof resetPasswordBody>\n\nexport const setRecoveryEmailBody = z.object({\n recoveryEmail: z.string().email()\n})\nexport type SetRecoveryEmailInput = z.infer<typeof setRecoveryEmailBody>\n\nexport const verifyRecoveryEmailBody = z.object({\n codeOrToken: z.string().min(4).max(512)\n})\nexport type VerifyRecoveryEmailInput = z.infer<typeof verifyRecoveryEmailBody>\n\nexport const initiateAccountRecoveryBody = z.object({\n primaryEmail: z.string().email(),\n recoveryEmail: z.string().email()\n})\nexport type InitiateAccountRecoveryInput = z.infer<typeof initiateAccountRecoveryBody>\n\nexport const completeAccountRecoveryBody = z.object({\n primaryEmail: z.string().email(),\n recoveryEmail: z.string().email(),\n codeOrToken: z.string().min(4).max(512),\n newPrimaryEmail: z.string().email(),\n newPassword: z.string().min(8).max(128).optional()\n})\nexport type CompleteAccountRecoveryInput = z.infer<typeof completeAccountRecoveryBody>\n\nexport const blockUserBody = z\n .object({ userId: entryId.optional(), blocked: z.boolean().default(true) })\n .default({ blocked: true })\nexport const signOutBody = z.object({ deleteUser: z.boolean().optional() }).default({})\n", "import { createHash, createPublicKey, verify as cryptoVerify, type JsonWebKey } from 'node:crypto'\nimport type { UserRecord } from 'firebase-admin/auth'\nimport { HTTPException } from 'hono/http-exception'\nimport { CORE_CONFIG } from '../config'\nimport type { Core } from '../index'\nimport {\n socialSignInInput,\n type AuthUser,\n type LinkedProvider,\n type OAuthProvider,\n type SocialSignInInput,\n type VerifiedOidcClaims\n} from './schema'\nimport type { AuthSessionEngine } from './session'\nimport { fetchIdentityToolkit } from './utils'\n\ninterface JwksCacheEntry {\n keys: (JsonWebKey & { kid?: string })[]\n fetchedAt: number\n}\n\nconst jwksCache = new Map<OAuthProvider, JwksCacheEntry>()\nconst JWKS_TTL_MS = 60 * 60 * 1000\nconst JWKS_URLS: Record<OAuthProvider, string> = {\n google: 'https://www.googleapis.com/oauth2/v3/certs',\n apple: 'https://appleid.apple.com/auth/keys'\n}\n\nlet testOidcPublicKeyJwk: (JsonWebKey & { kid?: string }) | null = null\n\nexport class AuthOidcEngine {\n readonly #core: Core\n readonly #session: AuthSessionEngine\n\n constructor(coreClient: Core, session: AuthSessionEngine) {\n this.#core = coreClient\n this.#session = session\n }\n\n registerTestOidcPublicKey = (jwk: (JsonWebKey & { kid?: string }) | null): void => {\n testOidcPublicKeyJwk = jwk\n }\n\n #getProviderJwks = async (\n provider: OAuthProvider,\n force = false\n ): Promise<(JsonWebKey & { kid?: string })[]> => {\n const cached = jwksCache.get(provider)\n if (!force && cached && Date.now() - cached.fetchedAt < JWKS_TTL_MS) {\n return cached.keys\n }\n const res = await fetch(JWKS_URLS[provider], { signal: AbortSignal.timeout(10_000) })\n if (!res.ok) throw new Error(`Failed to fetch ${provider} JWKS (${res.status})`)\n const data = (await res.json()) as { keys?: (JsonWebKey & { kid?: string })[] }\n const keys = data.keys ?? []\n jwksCache.set(provider, { keys, fetchedAt: Date.now() })\n return keys\n }\n\n #verifyNonceClaim = (rawNonce: string | undefined, tokenNonce: unknown): void => {\n if (!rawNonce) return\n if (typeof tokenNonce !== 'string' || !tokenNonce) {\n this.#core.errors.httpError(401, 'Missing OIDC nonce claim in ID token', 'INVALID_NONCE')\n }\n const sha256Hex = createHash('sha256').update(rawNonce).digest('hex')\n const sha256B64 = createHash('sha256').update(rawNonce).digest('base64url')\n if (tokenNonce !== rawNonce && tokenNonce !== sha256Hex && tokenNonce !== sha256B64) {\n this.#core.errors.httpError(401, 'OIDC nonce mismatch', 'INVALID_NONCE')\n }\n }\n\n #verifyOidcSignature = async (\n provider: OAuthProvider,\n header: { kid?: string; alg?: string },\n headerB64: string,\n payloadB64: string,\n sigB64: string,\n isDev: boolean\n ): Promise<void> => {\n let jwk: (JsonWebKey & { kid?: string }) | undefined\n if (isDev && testOidcPublicKeyJwk && header.kid === (testOidcPublicKeyJwk.kid ?? 'test-oidc-key')) {\n jwk = testOidcPublicKeyJwk\n } else {\n const keys = await this.#getProviderJwks(provider)\n jwk = keys.find((k) => k.kid === header.kid)\n if (!jwk && header.kid) {\n const refreshed = await this.#getProviderJwks(provider, true)\n jwk = refreshed.find((k) => k.kid === header.kid)\n }\n }\n if (!jwk) {\n this.#core.errors.httpError(401, 'Unable to find matching OIDC JWK for token kid', 'INVALID_ID_TOKEN')\n }\n try {\n const pubKey = createPublicKey({ key: jwk!, format: 'jwk' })\n const signingInput = Buffer.from(`${headerB64}.${payloadB64}`, 'utf8')\n const signature = Buffer.from(sigB64, 'base64url')\n const valid = cryptoVerify('RSA-SHA256', signingInput, pubKey, signature)\n if (!valid) this.#core.errors.httpError(401, 'Invalid OIDC ID token signature', 'INVALID_ID_TOKEN')\n } catch (err) {\n if (err instanceof HTTPException) throw err\n this.#core.errors.httpError(401, 'OIDC signature verification failed', 'INVALID_ID_TOKEN')\n }\n }\n\n verifyOidcIdToken = async (\n provider: OAuthProvider,\n idToken: string,\n nonce?: string,\n isDev?: boolean\n ): Promise<VerifiedOidcClaims> => {\n const parts = idToken.split('.')\n if (parts.length !== 3) return this.#core.errors.httpError(401, 'Malformed OIDC ID token', 'INVALID_ID_TOKEN')\n const [headerB64, payloadB64, sigB64] = parts as [string, string, string]\n\n let header: { kid?: string; alg?: string }\n let payload: Record<string, unknown>\n try {\n header = JSON.parse(Buffer.from(headerB64, 'base64url').toString('utf8')) as { kid?: string; alg?: string }\n payload = JSON.parse(Buffer.from(payloadB64, 'base64url').toString('utf8')) as Record<string, unknown>\n } catch {\n return this.#core.errors.httpError(401, 'Malformed OIDC ID token JSON', 'INVALID_ID_TOKEN')\n }\n\n if (header.alg !== 'RS256') {\n return this.#core.errors.httpError(401, 'Unsupported OIDC signature algorithm', 'INVALID_ID_TOKEN')\n }\n\n const exp = typeof payload.exp === 'number' ? payload.exp : 0\n if (exp * 1000 <= Date.now()) {\n return this.#core.errors.httpError(401, 'OIDC ID token has expired', 'TOKEN_EXPIRED')\n }\n\n const iss = String(payload.iss ?? '')\n const validIss =\n provider === 'google'\n ? iss === 'https://accounts.google.com' || iss === 'accounts.google.com'\n : iss === 'https://appleid.apple.com'\n if (!validIss) {\n return this.#core.errors.httpError(401, `Invalid OIDC issuer for ${provider}: ${iss}`, 'INVALID_ISSUER')\n }\n\n const allowedClientIds =\n provider === 'google' ? CORE_CONFIG.auth.oauth?.googleClientIds : CORE_CONFIG.auth.oauth?.appleClientIds\n if (allowedClientIds && allowedClientIds.length > 0) {\n const aud = payload.aud\n const audList = Array.isArray(aud) ? aud.map(String) : [String(aud ?? '')]\n if (!audList.some((a) => allowedClientIds.includes(a))) {\n return this.#core.errors.httpError(401, `Invalid OIDC audience for ${provider}`, 'INVALID_AUDIENCE')\n }\n }\n\n this.#verifyNonceClaim(nonce, payload.nonce)\n await this.#verifyOidcSignature(\n provider,\n header,\n headerB64,\n payloadB64,\n sigB64,\n this.#session.resolveDefaultIsDev(isDev)\n )\n\n const sub = String(payload.sub ?? '').trim()\n if (!sub) return this.#core.errors.httpError(401, 'Missing OIDC subject (sub) claim', 'INVALID_ID_TOKEN')\n const email = typeof payload.email === 'string' && payload.email ? payload.email.trim().toLowerCase() : null\n const emailVerified = payload.email_verified === true || payload.email_verified === 'true'\n\n return {\n sub,\n email,\n emailVerified,\n ...(typeof payload.name === 'string' && payload.name ? { name: payload.name } : {}),\n ...(typeof payload.picture === 'string' && payload.picture ? { picture: payload.picture } : {})\n }\n }\n\n #tryIdentityToolkitIdp = async (\n key: string,\n provider: OAuthProvider,\n idToken: string,\n nonce?: string,\n accessToken?: string\n ): Promise<{\n firebaseIdToken: string\n localId: string\n federatedId?: string\n email?: string\n emailVerified?: boolean\n displayName?: string\n photoUrl?: string\n } | null> => {\n try {\n const providerId = provider === 'apple' ? 'apple.com' : 'google.com'\n const params = new URLSearchParams({ providerId })\n if (idToken) params.set('id_token', idToken)\n if (accessToken) params.set('access_token', accessToken)\n if (nonce) params.set('rawNonce', nonce)\n\n const { ok, data } = await fetchIdentityToolkit<{\n idToken?: string\n localId?: string\n federatedId?: string\n email?: string\n emailVerified?: boolean\n displayName?: string\n photoUrl?: string\n }>('accounts:signInWithIdp', key, {\n postBody: params.toString(),\n requestUri: 'http://localhost',\n returnIdpCredential: true,\n returnSecureToken: true\n })\n if (!ok || !data.idToken || !data.localId) return null\n return {\n firebaseIdToken: data.idToken,\n localId: data.localId,\n ...(data.federatedId ? { federatedId: data.federatedId } : {}),\n ...(data.email ? { email: data.email.trim().toLowerCase() } : {}),\n ...(typeof data.emailVerified === 'boolean' ? { emailVerified: data.emailVerified } : {}),\n ...(data.displayName ? { displayName: data.displayName } : {}),\n ...(data.photoUrl ? { photoUrl: data.photoUrl } : {})\n }\n } catch {\n return null\n }\n }\n\n #resolveOrCreateSocialUser = async (\n providerKey: string,\n oidcClaims: VerifiedOidcClaims & { _idpResult?: { localId: string } },\n resolvedName: string | undefined,\n resolvedAvatar: string | undefined,\n isDev: boolean\n ): Promise<{ userRecord: UserRecord; isNewUser: boolean }> => {\n const auth = this.#session.getAuth()\n const db = this.#core.db.firestore(isDev)\n let userRecord: UserRecord | undefined\n\n const existingProviderSnap = await db\n .collection('user_auth_meta')\n .where('providerKeys', 'array-contains', providerKey)\n .limit(1)\n .get()\n\n if (!existingProviderSnap.empty) {\n userRecord = await auth.getUser(existingProviderSnap.docs[0]!.id).catch(() => undefined)\n }\n\n if (!userRecord && oidcClaims.email && oidcClaims.emailVerified) {\n userRecord = await auth.getUserByEmail(oidcClaims.email).catch(() => undefined)\n if (userRecord && !userRecord.emailVerified) {\n userRecord = await auth.updateUser(userRecord.uid, { emailVerified: true }).catch(() => userRecord)\n }\n }\n\n if (!userRecord && oidcClaims._idpResult?.localId) {\n userRecord = await auth.getUser(oidcClaims._idpResult.localId).catch(() => undefined)\n }\n\n if (!userRecord) {\n const created = await auth.createUser({\n ...(oidcClaims.email ? { email: oidcClaims.email } : {}),\n emailVerified: oidcClaims.emailVerified,\n ...(resolvedName ? { displayName: resolvedName } : {}),\n ...(resolvedAvatar ? { photoURL: resolvedAvatar } : {})\n })\n return { userRecord: created, isNewUser: true }\n }\n\n const updates: { displayName?: string; photoURL?: string; emailVerified?: boolean } = {}\n if (resolvedName && !userRecord.displayName) updates.displayName = resolvedName\n if (resolvedAvatar && !userRecord.photoURL) updates.photoURL = resolvedAvatar\n if (oidcClaims.emailVerified && !userRecord.emailVerified && userRecord.email === oidcClaims.email) {\n updates.emailVerified = true\n }\n if (Object.keys(updates).length > 0) {\n userRecord = await auth.updateUser(userRecord.uid, updates).catch(() => userRecord!)\n }\n return { userRecord, isNewUser: false }\n }\n\n #maybeSendWelcomeEmail = async (userId: string, email?: string | null): Promise<void> => {\n const normalized = email?.trim().toLowerCase()\n if (!normalized) return\n const flowCfg = this.#core.config.emails.authFlows.welcome\n const hasWelcome =\n Boolean(this.#core.internals.registry.getEmailTemplate(flowCfg?.templateId ?? 'welcome')) ||\n Boolean(flowCfg?.onSend) ||\n Boolean(this.#core.config.emails.onAuthEmail)\n if (!hasWelcome) return\n await this.#core.internals.emails\n .dispatchAuthEmail({\n to: normalized,\n purpose: 'welcome',\n code: '',\n token: '',\n expiresInMinutes: 0,\n userId\n })\n .catch(() => {})\n }\n\n signInSocial = async (raw: SocialSignInInput): Promise<{ user: AuthUser; sessionCookie: string }> => {\n const { provider, idToken, nonce, accessToken, profile } = socialSignInInput.parse(raw)\n const targetIsDev = this.#core.env.isDev\n\n const oidcClaims = await this.verifyOidcIdToken(provider, idToken, nonce, targetIsDev).catch(async (err) => {\n if (err instanceof HTTPException) throw err\n const idp = await this.#tryIdentityToolkitIdp(this.#core.env.WEB_API_KEY, provider, idToken, nonce, accessToken)\n if (!idp) throw err\n return {\n sub: idp.federatedId ?? idp.localId,\n email: idp.email ?? null,\n emailVerified: Boolean(idp.emailVerified),\n ...(idp.displayName ? { name: idp.displayName } : {}),\n ...(idp.photoUrl ? { picture: idp.photoUrl } : {}),\n _idpResult: idp\n } as VerifiedOidcClaims & { _idpResult?: { localId: string } }\n })\n\n const providerKey = `${provider}:${oidcClaims.sub}`\n const resolvedName = profile?.name ?? oidcClaims.name\n const resolvedAvatar = profile?.avatarUrl ?? oidcClaims.picture\n const { userRecord, isNewUser } = await this.#resolveOrCreateSocialUser(\n providerKey,\n oidcClaims,\n resolvedName,\n resolvedAvatar,\n targetIsDev\n )\n\n const existingMeta = await this.#session.getUserAuthMeta(userRecord.uid, targetIsDev)\n const existingProviders = existingMeta?.linkedProviders ?? []\n const now = new Date()\n const updatedProviders: LinkedProvider[] = [\n ...existingProviders.filter((p) => !(p.provider === provider && p.providerUserId === oidcClaims.sub)),\n {\n provider,\n providerUserId: oidcClaims.sub,\n ...(oidcClaims.email ? { email: oidcClaims.email } : {}),\n linkedAt:\n existingProviders.find((p) => p.provider === provider && p.providerUserId === oidcClaims.sub)?.linkedAt ?? now\n }\n ]\n\n await this.#session.upsertUserAuthMeta(\n userRecord.uid,\n {\n email: userRecord.email ?? oidcClaims.email ?? existingMeta?.email ?? null,\n emailVerified: Boolean(userRecord.emailVerified || oidcClaims.emailVerified || existingMeta?.emailVerified),\n name: userRecord.displayName ?? resolvedName ?? existingMeta?.name ?? null,\n ...(resolvedAvatar || userRecord.photoURL || existingMeta?.avatarUrl\n ? { avatarUrl: userRecord.photoURL ?? resolvedAvatar ?? existingMeta?.avatarUrl ?? null }\n : {}),\n linkedProviders: updatedProviders,\n providerKeys: updatedProviders.map((p) => `${p.provider}:${p.providerUserId}`)\n },\n targetIsDev\n )\n\n if (isNewUser) {\n await this.#maybeSendWelcomeEmail(userRecord.uid, userRecord.email ?? oidcClaims.email)\n }\n\n return this.#session.mintSessionForUid(userRecord.uid, {\n ...(userRecord.email ?? oidcClaims.email ? { email: (userRecord.email ?? oidcClaims.email)! } : {}),\n ...(userRecord.displayName ?? resolvedName ? { name: (userRecord.displayName ?? resolvedName)! } : {}),\n ...(userRecord.photoURL ?? resolvedAvatar ? { avatarUrl: (userRecord.photoURL ?? resolvedAvatar)! } : {}),\n emailVerified: Boolean(userRecord.emailVerified || oidcClaims.emailVerified)\n })\n }\n\n #identityToolkit = async (\n key: string,\n endpoint: 'accounts:signUp' | 'accounts:signInWithPassword',\n email: string,\n password: string,\n displayName?: string\n ): Promise<{ idToken: string; localId: string; displayName?: string }> => {\n const { ok, data } = await fetchIdentityToolkit<{\n idToken?: string\n localId?: string\n displayName?: string\n error?: { message?: string }\n }>(endpoint, key, { email, password, ...(displayName ? { displayName } : {}), returnSecureToken: true })\n if (!ok || !data.idToken) {\n const msg = data.error?.message ?? 'AUTH_FAILED'\n return this.#core.errors.httpError(msg === 'EMAIL_EXISTS' ? 409 : 401, msg, msg)\n }\n return data as { idToken: string; localId: string; displayName?: string }\n }\n\n signUpEmail = async (\n email: string,\n password: string,\n name?: string\n ): Promise<{ user: AuthUser; sessionCookie: string }> => {\n const { idToken } = await this.#identityToolkit(\n this.#core.env.WEB_API_KEY,\n 'accounts:signUp',\n email,\n password,\n name\n )\n const session = await this.#session.createSession(idToken, { email, name })\n await this.#maybeSendWelcomeEmail(session.user.id, session.user.email ?? email)\n return session\n }\n\n signInEmail = async (email: string, password: string): Promise<{ user: AuthUser; sessionCookie: string }> => {\n const { idToken, displayName } = await this.#identityToolkit(\n this.#core.env.WEB_API_KEY,\n 'accounts:signInWithPassword',\n email,\n password\n )\n return this.#session.createSession(idToken, { email, ...(displayName ? { name: displayName } : {}) })\n }\n}\n", "import { createHash, timingSafeEqual } from 'node:crypto'\nimport type { UserRecord } from 'firebase-admin/auth'\nimport { CORE_CONFIG, type DbRole } from '../config'\nimport type { EntryId } from '../db'\nimport type { AuthUser, LinkedProvider, OAuthProvider, UserAuthMetaRecord } from './schema'\n\nexport const resolveUserRole = (userId?: EntryId, explicitRole?: DbRole): DbRole => {\n if (explicitRole === 'admin' || explicitRole === 'user' || explicitRole === 'anon') return explicitRole\n if (userId === CORE_CONFIG.auth.adminUserId) return 'admin'\n return userId ? 'user' : 'anon'\n}\n\nexport const resolveTokenRole = (decoded: Record<string, unknown>, uid: EntryId): DbRole =>\n uid === CORE_CONFIG.auth.adminUserId || decoded.role === 'admin' || decoded.admin === true ? 'admin' : 'user'\n\nexport const normalizeDate = (val: unknown, fallback = new Date()): Date => {\n if (val instanceof Date) return val\n if (\n val &&\n typeof val === 'object' &&\n 'toDate' in val &&\n typeof (val as { toDate: () => Date }).toDate === 'function'\n ) {\n return (val as { toDate: () => Date }).toDate()\n }\n if (typeof val === 'string' || typeof val === 'number') {\n const d = new Date(val)\n if (!Number.isNaN(d.getTime())) return d\n }\n return fallback\n}\n\nexport const safeEqualHex = (aHex: string, bHex: string): boolean => {\n if (!aHex || !bHex || aHex.length !== bHex.length) return false\n try {\n const a = Buffer.from(aHex, 'hex')\n const b = Buffer.from(bHex, 'hex')\n return a.length > 0 && a.length === b.length && timingSafeEqual(a, b)\n } catch {\n return false\n }\n}\n\nexport const hashToken = (raw: string): string => createHash('sha256').update(raw.trim()).digest('hex')\n\nexport const parseLinkedProviders = (rawProviders: unknown, fallbackDate = new Date()): LinkedProvider[] => {\n if (!Array.isArray(rawProviders)) return []\n return rawProviders\n .filter((p): p is Record<string, unknown> => Boolean(p && typeof p === 'object'))\n .map((p) => ({\n provider: (p.provider === 'apple' ? 'apple' : 'google') as OAuthProvider,\n providerUserId: String(p.providerUserId ?? ''),\n ...(p.email !== undefined ? { email: (p.email as string | null) ?? null } : {}),\n linkedAt: normalizeDate(p.linkedAt, fallbackDate)\n }))\n .filter((p) => Boolean(p.providerUserId))\n}\n\nexport const mapUserRecord = (u: UserRecord, meta?: UserAuthMetaRecord): AuthUser => {\n const createdAt = new Date(u.metadata.creationTime || Date.now())\n const updatedAt = new Date(u.metadata.lastRefreshTime || u.metadata.creationTime || Date.now())\n const fbProviders: LinkedProvider[] = (u.providerData ?? [])\n .filter((p) => p.providerId === 'google.com' || p.providerId === 'apple.com')\n .map((p) => ({\n provider: (p.providerId === 'apple.com' ? 'apple' : 'google') as OAuthProvider,\n providerUserId: p.uid,\n ...(p.email ? { email: p.email } : {}),\n linkedAt: createdAt\n }))\n const mergedProvidersMap = new Map<string, LinkedProvider>()\n for (const p of fbProviders) mergedProvidersMap.set(`${p.provider}:${p.providerUserId}`, p)\n for (const p of meta?.linkedProviders ?? []) mergedProvidersMap.set(`${p.provider}:${p.providerUserId}`, p)\n const linkedProviders = [...mergedProvidersMap.values()]\n const avatarUrl = u.photoURL ?? meta?.avatarUrl ?? undefined\n\n return {\n id: u.uid,\n email: u.email ?? meta?.email ?? null,\n emailVerified: Boolean(u.emailVerified || meta?.emailVerified),\n name: u.displayName ?? meta?.name ?? null,\n ...(avatarUrl !== undefined ? { avatarUrl } : {}),\n ...(meta?.recoveryEmail !== undefined ? { recoveryEmail: meta.recoveryEmail } : {}),\n ...(meta?.recoveryEmailVerified !== undefined ? { recoveryEmailVerified: meta.recoveryEmailVerified } : {}),\n ...(linkedProviders.length > 0 ? { linkedProviders } : {}),\n ...(u.customClaims ? { customClaims: u.customClaims } : {}),\n deleted: u.disabled,\n createdAt,\n updatedAt\n }\n}\n\nexport const fetchIdentityToolkit = async <T = Record<string, unknown>>(\n endpoint: string,\n apiKey: string,\n body: Record<string, unknown>,\n timeoutMs = 10_000\n): Promise<{ ok: boolean; status: number; data: T }> => {\n const res = await fetch(`https://identitytoolkit.googleapis.com/v1/${endpoint}?key=${apiKey}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs)\n })\n const data = (await res.json().catch(() => ({}))) as T\n return { ok: res.ok, status: res.status, data }\n}\n", "import { randomBytes, randomInt } from 'node:crypto'\nimport type { UserRecord } from 'firebase-admin/auth'\nimport type { EntryId } from '../db'\nimport type { Core } from '../index'\nimport {\n completeAccountRecoveryBody,\n forgotPasswordBody,\n initiateAccountRecoveryBody,\n resetPasswordBody,\n setRecoveryEmailBody,\n verifyEmailBody,\n verifyRecoveryEmailBody,\n type AuthEmailPurpose,\n type AuthTokenPurpose,\n type AuthUser,\n type CompleteAccountRecoveryInput,\n type ForgotPasswordInput,\n type InitiateAccountRecoveryInput,\n type ResetPasswordInput,\n type SetRecoveryEmailInput,\n type TransactionalEmailPayload,\n type VerifyEmailInput,\n type VerifyRecoveryEmailInput\n} from './schema'\nimport type { AuthSessionEngine } from './session'\nimport { hashToken, normalizeDate, safeEqualHex } from './utils'\n\nexport class AuthRecoveryEngine {\n readonly #core: Core\n readonly #session: AuthSessionEngine\n\n constructor(coreClient: Core, session: AuthSessionEngine) {\n this.#core = coreClient\n this.#session = session\n }\n\n getLastDevEmail = (to: string, purpose: AuthEmailPurpose): TransactionalEmailPayload | undefined =>\n this.#core.internals.emails.getLastDevEmail(to, purpose)\n\n #issueAuthToken = async (\n userId: EntryId,\n purpose: AuthTokenPurpose,\n targetEmail: string,\n expiresInMinutes = this.#core.config.emails.otpTtlMinutes\n ): Promise<TransactionalEmailPayload> => {\n const normalizedTarget = targetEmail.trim().toLowerCase()\n const code = String(randomInt(100_000, 1_000_000))\n const token = randomBytes(32).toString('base64url')\n const tokenHash = hashToken(code)\n const urlTokenHash = hashToken(token)\n const now = new Date()\n const expiresAt = new Date(now.getTime() + expiresInMinutes * 60_000)\n const docId = `${userId}_${purpose}`\n\n await this.#core.db\n .firestore()\n .collection('auth_tokens')\n .doc(docId)\n .set({\n id: docId,\n userId,\n purpose,\n targetEmail: normalizedTarget,\n tokenHash,\n urlTokenHash,\n attempts: 0,\n expiresAt,\n consumedAt: null,\n deleted: false,\n createdAt: now,\n updatedAt: now\n })\n\n const payload: TransactionalEmailPayload = {\n to: normalizedTarget,\n purpose,\n code,\n token,\n expiresInMinutes,\n userId\n }\n await this.#core.internals.emails.dispatchAuthEmail(payload)\n return payload\n }\n\n #consumeAuthToken = async (\n userId: EntryId,\n purpose: AuthTokenPurpose,\n expectedTargetEmail: string,\n codeOrToken: string\n ): Promise<void> => {\n const db = this.#core.db.firestore()\n const docRef = db.collection('auth_tokens').doc(`${userId}_${purpose}`)\n const maxAttempts = this.#core.config.emails.maxVerifyAttempts\n const normalizedExpected = expectedTargetEmail.trim().toLowerCase()\n const candidateHash = hashToken(codeOrToken)\n\n type ConsumeOutcome = 'valid' | 'missing_or_consumed' | 'expired' | 'max_attempts' | 'mismatch'\n\n const outcome = await db.runTransaction<ConsumeOutcome>(async (tx) => {\n const snap = await tx.get(docRef)\n if (!snap.exists) return 'missing_or_consumed'\n const data = snap.data() as Record<string, unknown> | undefined\n if (!data || data.deleted === true || data.consumedAt != null) return 'missing_or_consumed'\n\n const attempts = typeof data.attempts === 'number' ? data.attempts : 0\n if (attempts >= maxAttempts) return 'max_attempts'\n\n const now = new Date()\n if (normalizeDate(data.expiresAt, new Date(0)).getTime() <= now.getTime()) {\n tx.update(docRef, { deleted: true, updatedAt: now })\n return 'expired'\n }\n\n const targetEmail = String(data.targetEmail ?? '').trim().toLowerCase()\n const tokenHash = String(data.tokenHash ?? '')\n const urlTokenHash = typeof data.urlTokenHash === 'string' ? data.urlTokenHash : ''\n const matches =\n targetEmail === normalizedExpected &&\n (safeEqualHex(candidateHash, tokenHash) ||\n (Boolean(urlTokenHash) && safeEqualHex(candidateHash, urlTokenHash)))\n\n if (!matches) {\n const nextAttempts = attempts + 1\n const exhausted = nextAttempts >= maxAttempts\n tx.update(docRef, {\n attempts: nextAttempts,\n ...(exhausted ? { deleted: true, consumedAt: now } : {}),\n updatedAt: now\n })\n return exhausted ? 'max_attempts' : 'mismatch'\n }\n\n tx.update(docRef, { consumedAt: now, deleted: true, updatedAt: now })\n return 'valid'\n })\n\n if (outcome === 'valid') return\n if (outcome === 'expired') this.#core.errors.httpError(400, 'Verification token has expired', 'TOKEN_EXPIRED')\n if (outcome === 'max_attempts') {\n this.#core.errors.httpError(\n 400,\n 'Maximum verification attempts exceeded; token invalidated',\n 'TOKEN_MAX_ATTEMPTS_EXCEEDED'\n )\n }\n this.#core.errors.httpError(400, 'Invalid or expired verification code', 'INVALID_TOKEN')\n }\n\n #requireUserByEmail = async (\n email: string,\n errMessage: string,\n errCode: string,\n rejectDisabled = false\n ): Promise<{ user: UserRecord; normalizedEmail: string }> => {\n const normalizedEmail = email.trim().toLowerCase()\n const user = await this.#session\n .getAuth()\n .getUserByEmail(normalizedEmail)\n .catch(() => undefined)\n if (!user || !user.email || (rejectDisabled && user.disabled)) {\n return this.#core.errors.httpError(400, errMessage, errCode)\n }\n return { user, normalizedEmail }\n }\n\n #revokeAllUserSessions = async (uid: EntryId): Promise<void> => {\n this.#session.evictUserTokens(uid)\n await Promise.all([\n this.#session.recordRevocation(uid, this.#core.env.isDev),\n this.#session\n .getAuth()\n .revokeRefreshTokens(uid)\n .catch(() => {})\n ])\n }\n\n sendVerificationEmail = async (\n userId: EntryId = this.#core.userId\n ): Promise<{ sent: true; expiresInMinutes: number }> => {\n if (!userId) return this.#core.errors.httpError(401, 'Unauthorized', 'UNAUTHORIZED')\n const user = await this.#session\n .getAuth()\n .getUser(userId)\n .catch(() => undefined)\n if (!user || !user.email) {\n return this.#core.errors.httpError(400, 'User does not have a primary email address', 'MISSING_EMAIL')\n }\n const expiresInMinutes = this.#core.config.emails.otpTtlMinutes\n await this.#issueAuthToken(user.uid, 'verify_email', user.email, expiresInMinutes)\n return { sent: true, expiresInMinutes }\n }\n\n #consumeAndUpsertMeta = async (\n uid: EntryId,\n purpose: AuthTokenPurpose,\n targetEmail: string,\n codeOrToken: string,\n metaPatch: Parameters<AuthSessionEngine['upsertUserAuthMeta']>[1]\n ): Promise<void> => {\n await this.#consumeAuthToken(uid, purpose, targetEmail, codeOrToken)\n await this.#session.upsertUserAuthMeta(uid, metaPatch, this.#core.env.isDev)\n }\n\n verifyEmail = async (raw: VerifyEmailInput): Promise<{ verified: true; userId: string }> => {\n const { email, codeOrToken } = verifyEmailBody.parse(raw)\n const { user, normalizedEmail } = await this.#requireUserByEmail(\n email,\n 'Invalid email or verification token',\n 'INVALID_TOKEN'\n )\n await this.#consumeAndUpsertMeta(user.uid, 'verify_email', user.email!, codeOrToken, {\n email: normalizedEmail,\n emailVerified: true\n })\n await this.#session.getAuth().updateUser(user.uid, { emailVerified: true })\n this.#session.evictUserTokens(user.uid)\n return { verified: true, userId: user.uid }\n }\n\n forgotPassword = async (raw: ForgotPasswordInput): Promise<{ sent: true }> => {\n const { email } = forgotPasswordBody.parse(raw)\n const normalizedEmail = email.trim().toLowerCase()\n const user = await this.#session\n .getAuth()\n .getUserByEmail(normalizedEmail)\n .catch(() => undefined)\n if (user && user.email && !user.disabled) {\n await this.#issueAuthToken(user.uid, 'reset_password', user.email, this.#core.config.emails.otpTtlMinutes)\n }\n return { sent: true }\n }\n\n resetPassword = async (raw: ResetPasswordInput): Promise<{ reset: true }> => {\n const { email, codeOrToken, newPassword } = resetPasswordBody.parse(raw)\n const { user } = await this.#requireUserByEmail(email, 'Invalid email or reset token', 'INVALID_TOKEN')\n await this.#consumeAuthToken(user.uid, 'reset_password', user.email!, codeOrToken)\n await this.#session.getAuth().updateUser(user.uid, { password: newPassword })\n await this.#revokeAllUserSessions(user.uid)\n return { reset: true }\n }\n\n setRecoveryEmail = async (\n raw: SetRecoveryEmailInput,\n userId: EntryId = this.#core.userId\n ): Promise<{ recoveryEmail: string; recoveryEmailVerified: false; sent: true }> => {\n if (!userId) return this.#core.errors.httpError(401, 'Unauthorized', 'UNAUTHORIZED')\n const { recoveryEmail } = setRecoveryEmailBody.parse(raw)\n const normalizedRecovery = recoveryEmail.trim().toLowerCase()\n const user = await this.#session\n .getAuth()\n .getUser(userId)\n .catch(() => undefined)\n if (!user) return this.#core.errors.httpError(404, 'User not found', 'NOT_FOUND')\n\n const primaryEmail = (user.email ?? '').trim().toLowerCase()\n if (primaryEmail && normalizedRecovery === primaryEmail) {\n return this.#core.errors.httpError(\n 400,\n 'Recovery email must be different from primary email',\n 'INVALID_RECOVERY_EMAIL'\n )\n }\n\n await this.#session.upsertUserAuthMeta(\n user.uid,\n {\n ...(primaryEmail ? { email: primaryEmail } : {}),\n recoveryEmail: normalizedRecovery,\n recoveryEmailVerified: false\n },\n this.#core.env.isDev\n )\n await this.#issueAuthToken(\n user.uid,\n 'verify_recovery_email',\n normalizedRecovery,\n this.#core.config.emails.otpTtlMinutes\n )\n return { recoveryEmail: normalizedRecovery, recoveryEmailVerified: false, sent: true }\n }\n\n verifyRecoveryEmail = async (\n raw: VerifyRecoveryEmailInput,\n userId: EntryId = this.#core.userId\n ): Promise<{ recoveryEmail: string; recoveryEmailVerified: true; verified: true }> => {\n if (!userId) return this.#core.errors.httpError(401, 'Unauthorized', 'UNAUTHORIZED')\n const { codeOrToken } = verifyRecoveryEmailBody.parse(raw)\n const meta = await this.#session.getUserAuthMeta(userId, this.#core.env.isDev)\n if (!meta?.recoveryEmail) {\n return this.#core.errors.httpError(\n 400,\n 'No recovery email configured for this account',\n 'MISSING_RECOVERY_EMAIL'\n )\n }\n await this.#consumeAndUpsertMeta(userId, 'verify_recovery_email', meta.recoveryEmail, codeOrToken, {\n recoveryEmailVerified: true\n })\n return { recoveryEmail: meta.recoveryEmail, recoveryEmailVerified: true, verified: true }\n }\n\n initiateAccountRecovery = async (raw: InitiateAccountRecoveryInput): Promise<{ initiated: true }> => {\n const { primaryEmail, recoveryEmail } = initiateAccountRecoveryBody.parse(raw)\n const normPrimary = primaryEmail.trim().toLowerCase()\n const normRecovery = recoveryEmail.trim().toLowerCase()\n const user = await this.#session\n .getAuth()\n .getUserByEmail(normPrimary)\n .catch(() => undefined)\n if (user && !user.disabled && (user.email ?? '').trim().toLowerCase() === normPrimary) {\n const meta = await this.#session.getUserAuthMeta(user.uid, this.#core.env.isDev)\n if (meta?.recoveryEmail === normRecovery && meta.recoveryEmailVerified === true) {\n await this.#issueAuthToken(\n user.uid,\n 'account_recovery',\n normRecovery,\n this.#core.config.emails.recoveryOtpTtlMinutes\n )\n }\n }\n return { initiated: true }\n }\n\n completeAccountRecovery = async (\n raw: CompleteAccountRecoveryInput\n ): Promise<{ user: AuthUser; sessionCookie: string }> => {\n const { primaryEmail, recoveryEmail, codeOrToken, newPrimaryEmail, newPassword } =\n completeAccountRecoveryBody.parse(raw)\n const normPrimary = primaryEmail.trim().toLowerCase()\n const normRecovery = recoveryEmail.trim().toLowerCase()\n const normNewPrimary = newPrimaryEmail.trim().toLowerCase()\n\n const { user } = await this.#requireUserByEmail(\n normPrimary,\n 'Invalid account recovery request or token',\n 'INVALID_RECOVERY_REQUEST',\n true\n )\n if ((user.email ?? '').trim().toLowerCase() !== normPrimary) {\n return this.#core.errors.httpError(400, 'Invalid account recovery request or token', 'INVALID_RECOVERY_REQUEST')\n }\n\n const meta = await this.#session.getUserAuthMeta(user.uid, this.#core.env.isDev)\n if (!meta || meta.recoveryEmail !== normRecovery || meta.recoveryEmailVerified !== true) {\n return this.#core.errors.httpError(400, 'Invalid account recovery request or token', 'INVALID_RECOVERY_REQUEST')\n }\n\n await this.#consumeAndUpsertMeta(user.uid, 'account_recovery', normRecovery, codeOrToken, {\n email: normNewPrimary,\n emailVerified: true\n })\n await this.#session.getAuth().updateUser(user.uid, {\n email: normNewPrimary,\n emailVerified: true,\n ...(newPassword ? { password: newPassword } : {})\n })\n await this.#revokeAllUserSessions(user.uid)\n\n return this.#session.mintSessionForUid(user.uid, {\n email: normNewPrimary,\n emailVerified: true\n })\n }\n}\n", "import { getAuth, type Auth } from 'firebase-admin/auth'\nimport { setCookie } from 'hono/cookie'\nimport type { Context } from 'hono'\nimport { CORE_CONFIG, type AppEnv, type DbRole } from '../config'\nimport type { EntryId } from '../db'\nimport type { Core } from '../index'\nimport type { AuthUser, CachedTokenEntry, UserAuthMetaRecord } from './schema'\nimport { fetchIdentityToolkit, normalizeDate, parseLinkedProviders, resolveTokenRole } from './utils'\n\ntype InternalVerifier = { signatureVerifier?: { keyFetcher?: { fetchPublicKeys?: () => Promise<unknown> } } }\nlet authWarmPromise: Promise<unknown> | undefined\n\nconst REVOCATION_SYNC_TTL_MS = 3_000\nconst AUTH_REVOCATIONS_DOC_PATH = '_system/auth_revocations'\n\nexport const tokenCache = new Map<string, CachedTokenEntry>()\n\ninterface RevocationWatermarkState {\n lastSyncedAt: number\n revokedUsers: Record<string, number>\n}\n\nconst revocationWatermarks: [RevocationWatermarkState, RevocationWatermarkState] = [\n { lastSyncedAt: 0, revokedUsers: {} },\n { lastSyncedAt: 0, revokedUsers: {} }\n]\n\nlet bgSyncTimer: ReturnType<typeof setInterval> | null = null\n\nexport class AuthSessionEngine {\n readonly #core: Core\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n }\n\n getAuth = (): Auth => {\n this.#core.internals.registry.ensureFirebaseApp()\n return getAuth()\n }\n\n getAuthWarm = (): Promise<unknown> => {\n if (!authWarmPromise) {\n const auth = this.getAuth()\n const rawAuth = auth as unknown as {\n idTokenVerifier?: InternalVerifier\n sessionCookieVerifier?: InternalVerifier\n }\n authWarmPromise = Promise.all([\n rawAuth.idTokenVerifier?.signatureVerifier?.keyFetcher?.fetchPublicKeys?.(),\n rawAuth.sessionCookieVerifier?.signatureVerifier?.keyFetcher?.fetchPublicKeys?.(),\n auth.getUser(CORE_CONFIG.auth.adminUserId).catch(() => {})\n ]).catch(() => {})\n }\n return authWarmPromise\n }\n\n resolveDefaultIsDev = (isDev?: boolean): boolean => isDev ?? this.#core.env.isDev\n\n #ensureBackgroundRevocationSync = (): void => {\n if (bgSyncTimer) return\n bgSyncTimer = setInterval(() => {\n if (tokenCache.size === 0) {\n if (bgSyncTimer) {\n clearInterval(bgSyncTimer)\n bgSyncTimer = null\n }\n return\n }\n const defaultIsDev = this.#core.env.isDev\n for (const isDevSlot of [false, true] as const) {\n const idx = isDevSlot ? 1 : 0\n if (isDevSlot === defaultIsDev || revocationWatermarks[idx].lastSyncedAt > 0) {\n void this.syncRevocations(isDevSlot, true)\n }\n }\n }, 2_000)\n bgSyncTimer.unref?.()\n }\n\n setTokenCache = (\n token: string,\n uid: EntryId,\n role: DbRole = uid === CORE_CONFIG.auth.adminUserId ? 'admin' : 'user',\n exp = Date.now() + CORE_CONFIG.auth.tokenCacheTtlMs,\n strictVerified = false,\n emailVerified = false\n ): void => {\n const existing = tokenCache.get(token)\n if (!existing && tokenCache.size >= CORE_CONFIG.auth.tokenCacheMaxSize) {\n tokenCache.delete(tokenCache.keys().next().value!)\n }\n tokenCache.set(token, {\n uid,\n role,\n exp,\n cachedAt: Date.now(),\n strictVerified: Boolean(strictVerified || existing?.strictVerified),\n emailVerified: Boolean(emailVerified || existing?.emailVerified)\n })\n this.#ensureBackgroundRevocationSync()\n }\n\n evictUserTokens = (uid: EntryId, revokedAt?: number): void => {\n for (const [k, v] of tokenCache) {\n if (v.uid === uid && (revokedAt === undefined || v.cachedAt <= revokedAt)) {\n tokenCache.delete(k)\n }\n }\n }\n\n recordRevocation = async (uid: EntryId, isDev?: boolean): Promise<number> => {\n let revokedAt = Date.now()\n this.evictUserTokens(uid)\n const ttlMs = CORE_CONFIG.auth.tokenCacheTtlMs\n const targetIsDev = this.resolveDefaultIsDev(isDev)\n const localState = revocationWatermarks[targetIsDev ? 1 : 0]\n localState.revokedUsers[uid] = revokedAt\n localState.lastSyncedAt = revokedAt\n\n const db = this.#core.db.firestore(targetIsDev)\n const docRef = db.doc(AUTH_REVOCATIONS_DOC_PATH)\n try {\n await db.runTransaction(async (tx) => {\n const snap = await tx.get(docRef)\n const now = Date.now()\n revokedAt = now\n const data = snap.data() as { revokedUsers?: Record<string, number> } | undefined\n const existing = data?.revokedUsers ?? {}\n const pruned: Record<string, number> = {}\n const cutoff = now - ttlMs\n for (const [k, ts] of Object.entries(existing)) {\n if (typeof ts === 'number' && ts > cutoff) pruned[k] = ts\n }\n pruned[uid] = now\n tx.set(docRef, { revokedUsers: pruned, updatedAt: now })\n })\n localState.revokedUsers[uid] = revokedAt\n localState.lastSyncedAt = revokedAt\n } catch {}\n return revokedAt\n }\n\n clearUserRevocation = async (uid: EntryId, isDev?: boolean): Promise<void> => {\n const targetIsDev = this.resolveDefaultIsDev(isDev)\n const localState = revocationWatermarks[targetIsDev ? 1 : 0]\n delete localState.revokedUsers[uid]\n localState.lastSyncedAt = Date.now()\n\n const db = this.#core.db.firestore(targetIsDev)\n const docRef = db.doc(AUTH_REVOCATIONS_DOC_PATH)\n try {\n await db.runTransaction(async (tx) => {\n const snap = await tx.get(docRef)\n const data = snap.data() as { revokedUsers?: Record<string, number> } | undefined\n if (!data?.revokedUsers || !(uid in data.revokedUsers)) return\n const next = { ...data.revokedUsers }\n delete next[uid]\n tx.set(docRef, { revokedUsers: next, updatedAt: Date.now() })\n })\n } catch {}\n }\n\n syncRevocations = async (isDev?: boolean, force = false): Promise<Record<string, number>> => {\n const targetIsDev = this.resolveDefaultIsDev(isDev)\n const state = revocationWatermarks[targetIsDev ? 1 : 0]\n const now = Date.now()\n if (!force && state.lastSyncedAt > 0 && now - state.lastSyncedAt < REVOCATION_SYNC_TTL_MS) {\n return state.revokedUsers\n }\n return this.#core.internals.resilience.singleflight(\n `auth:revocations:${targetIsDev ? 'dev' : 'prod'}`,\n async () => {\n try {\n const snap = await this.#core.db.firestore(targetIsDev).doc(AUTH_REVOCATIONS_DOC_PATH).get()\n const remote = (snap.data()?.revokedUsers as Record<string, number> | undefined) ?? {}\n state.revokedUsers = remote\n state.lastSyncedAt = Date.now()\n for (const [uid, revokedAt] of Object.entries(remote)) {\n if (typeof revokedAt === 'number') this.evictUserTokens(uid, revokedAt)\n }\n } catch {\n state.lastSyncedAt = Date.now()\n }\n return state.revokedUsers\n },\n { scope: 'global' }\n )\n }\n\n verifyToken = async (\n token: string,\n isCookie: boolean,\n checkRevoked: boolean,\n isDev?: boolean\n ): Promise<{ uid: EntryId; role: DbRole; emailVerified: boolean }> => {\n const targetIsDev = this.resolveDefaultIsDev(isDev)\n const state = revocationWatermarks[targetIsDev ? 1 : 0]\n let hit = tokenCache.get(token)\n if (hit && hit.exp > Date.now()) {\n if (Date.now() - state.lastSyncedAt >= REVOCATION_SYNC_TTL_MS) {\n void this.syncRevocations(targetIsDev)\n }\n const revokedAt = state.revokedUsers[hit.uid]\n if (typeof revokedAt === 'number' && revokedAt >= hit.cachedAt) {\n this.evictUserTokens(hit.uid, revokedAt)\n hit = undefined\n }\n }\n if (hit && hit.exp > Date.now() && (!checkRevoked || hit.strictVerified)) {\n return { uid: hit.uid, role: hit.role, emailVerified: Boolean(hit.emailVerified) }\n }\n return this.#core.internals.resilience.singleflight(\n `auth:${isCookie ? 'c' : 'b'}:${checkRevoked ? '1' : '0'}:${token}`,\n async () => {\n const auth = this.getAuth()\n const d = isCookie\n ? await auth.verifySessionCookie(token, checkRevoked)\n : await auth.verifyIdToken(token, checkRevoked)\n const role = resolveTokenRole(d as unknown as Record<string, unknown>, d.uid)\n const emailVerified = Boolean(d.email_verified)\n this.setTokenCache(\n token,\n d.uid,\n role,\n Math.min(d.exp * 1000, Date.now() + CORE_CONFIG.auth.tokenCacheTtlMs),\n checkRevoked,\n emailVerified\n )\n return { uid: d.uid, role, emailVerified }\n }\n )\n }\n\n getUserAuthMeta = async (uid: EntryId, isDev?: boolean): Promise<UserAuthMetaRecord | undefined> => {\n if (!uid) return undefined\n try {\n const snap = await this.#core.db\n .firestore(this.resolveDefaultIsDev(isDev))\n .collection('user_auth_meta')\n .doc(uid)\n .get()\n if (!snap.exists) return undefined\n const raw = snap.data() as Record<string, unknown> | undefined\n if (!raw || raw.deleted === true) return undefined\n const linkedProviders = parseLinkedProviders(raw.linkedProviders)\n return {\n ...(typeof raw.email === 'string' || raw.email === null ? { email: raw.email } : {}),\n ...(typeof raw.emailVerified === 'boolean' ? { emailVerified: raw.emailVerified } : {}),\n ...(typeof raw.name === 'string' || raw.name === null ? { name: raw.name } : {}),\n ...(typeof raw.avatarUrl === 'string' || raw.avatarUrl === null ? { avatarUrl: raw.avatarUrl } : {}),\n ...(typeof raw.recoveryEmail === 'string' || raw.recoveryEmail === null\n ? { recoveryEmail: raw.recoveryEmail }\n : {}),\n ...(typeof raw.recoveryEmailVerified === 'boolean'\n ? { recoveryEmailVerified: raw.recoveryEmailVerified }\n : {}),\n ...(linkedProviders.length > 0 ? { linkedProviders } : {}),\n ...(Array.isArray(raw.providerKeys) ? { providerKeys: raw.providerKeys.map(String) } : {}),\n createdAt: normalizeDate(raw.createdAt),\n updatedAt: normalizeDate(raw.updatedAt)\n }\n } catch {\n return undefined\n }\n }\n\n upsertUserAuthMeta = async (\n uid: EntryId,\n patch: Partial<UserAuthMetaRecord>,\n isDev?: boolean\n ): Promise<UserAuthMetaRecord> => {\n const db = this.#core.db.firestore(this.resolveDefaultIsDev(isDev))\n const docRef = db.collection('user_auth_meta').doc(uid)\n const now = new Date()\n let merged: UserAuthMetaRecord = { ...patch, updatedAt: now }\n await db.runTransaction(async (tx) => {\n const snap = await tx.get(docRef)\n const existing = snap.exists ? (snap.data() as Record<string, unknown>) : undefined\n const createdAt = existing?.createdAt ? normalizeDate(existing.createdAt, now) : now\n const existingProviders = parseLinkedProviders(existing?.linkedProviders, now)\n const nextProviders = patch.linkedProviders ?? existingProviders\n const providerKeys = Array.from(\n new Set([\n ...(Array.isArray(existing?.providerKeys) ? existing.providerKeys.map(String) : []),\n ...(patch.providerKeys ?? []),\n ...nextProviders.map((p) => `${p.provider}:${p.providerUserId}`)\n ])\n )\n const nextDoc: Record<string, unknown> = {\n id: uid,\n deleted: false,\n email: patch.email !== undefined ? patch.email : (existing?.email ?? null),\n emailVerified: patch.emailVerified !== undefined ? patch.emailVerified : Boolean(existing?.emailVerified),\n name: patch.name !== undefined ? patch.name : (existing?.name ?? null),\n avatarUrl: patch.avatarUrl !== undefined ? patch.avatarUrl : (existing?.avatarUrl ?? null),\n recoveryEmail: patch.recoveryEmail !== undefined ? patch.recoveryEmail : (existing?.recoveryEmail ?? null),\n recoveryEmailVerified:\n patch.recoveryEmailVerified !== undefined\n ? patch.recoveryEmailVerified\n : Boolean(existing?.recoveryEmailVerified),\n linkedProviders: nextProviders,\n providerKeys,\n createdAt,\n updatedAt: now\n }\n tx.set(docRef, nextDoc, { merge: true })\n merged = {\n email: nextDoc.email as string | null,\n emailVerified: nextDoc.emailVerified as boolean,\n name: nextDoc.name as string | null,\n avatarUrl: nextDoc.avatarUrl as string | null,\n recoveryEmail: nextDoc.recoveryEmail as string | null,\n recoveryEmailVerified: nextDoc.recoveryEmailVerified as boolean,\n linkedProviders: nextProviders,\n providerKeys,\n createdAt,\n updatedAt: now\n }\n })\n return merged\n }\n\n setSessionCookie = (c: Context<AppEnv>, sessionCookie: string): void => {\n setCookie(c, CORE_CONFIG.auth.sessionCookie, sessionCookie, {\n httpOnly: true,\n secure: c.req.header('x-forwarded-proto') === 'https' || c.req.url.startsWith('https://'),\n path: '/',\n sameSite: 'Lax',\n maxAge: Math.floor(CORE_CONFIG.auth.sessionExpiresInMs / 1000)\n })\n }\n\n mintCustomToken = async (\n uid = `anon_${crypto.randomUUID().replace(/-/g, '').slice(0, 16)}`\n ): Promise<{ uid: string; customToken: string }> => ({\n uid,\n customToken: await this.getAuth().createCustomToken(uid)\n })\n\n createSession = async (\n idToken: string,\n profile?: { email?: string; name?: string; avatarUrl?: string; emailVerified?: boolean }\n ): Promise<{ user: AuthUser; sessionCookie: string }> => {\n const auth = this.getAuth()\n const cacheTtl = CORE_CONFIG.auth.tokenCacheTtlMs\n const sessionExpiresIn = CORE_CONFIG.auth.sessionExpiresInMs\n const now = new Date()\n const [ { decoded, meta }, sessionCookie ] = await Promise.all([\n auth.verifyIdToken(idToken, true).then(async (d) => {\n const role = resolveTokenRole(d as unknown as Record<string, unknown>, d.uid)\n const emailVerified = Boolean(d.email_verified || profile?.emailVerified)\n this.setTokenCache(idToken, d.uid, role, Math.min(d.exp * 1000, Date.now() + cacheTtl), true, emailVerified)\n const updates: { displayName?: string; photoURL?: string } = {}\n if (profile?.name && d.name !== profile.name) updates.displayName = profile.name\n if (profile?.avatarUrl && d.picture !== profile.avatarUrl) updates.photoURL = profile.avatarUrl\n const [m] = await Promise.all([\n this.getUserAuthMeta(d.uid, this.#core.env.isDev),\n Object.keys(updates).length > 0 ? auth.updateUser(d.uid, updates).catch(() => {}) : Promise.resolve()\n ])\n return { decoded: d, meta: m }\n }),\n auth.createSessionCookie(idToken, { expiresIn: sessionExpiresIn })\n ])\n const role = resolveTokenRole(decoded as unknown as Record<string, unknown>, decoded.uid)\n const emailVerified = Boolean(decoded.email_verified || profile?.emailVerified || meta?.emailVerified)\n const avatarUrl = profile?.avatarUrl ?? (decoded.picture as string | undefined) ?? meta?.avatarUrl\n const user: AuthUser = {\n id: decoded.uid,\n email: decoded.email ?? profile?.email ?? meta?.email ?? null,\n emailVerified,\n name: profile?.name ?? (decoded.name as string | undefined) ?? meta?.name ?? null,\n ...(avatarUrl !== undefined ? { avatarUrl } : {}),\n ...(meta?.recoveryEmail !== undefined ? { recoveryEmail: meta.recoveryEmail } : {}),\n ...(meta?.recoveryEmailVerified !== undefined ? { recoveryEmailVerified: meta.recoveryEmailVerified } : {}),\n ...(meta?.linkedProviders?.length ? { linkedProviders: meta.linkedProviders } : {}),\n ...(decoded.role || decoded.admin ? { customClaims: { role } } : {}),\n deleted: false,\n createdAt: meta?.createdAt ?? now,\n updatedAt: now\n }\n this.setTokenCache(sessionCookie, user.id, role, Date.now() + cacheTtl, true, emailVerified)\n return { user, sessionCookie }\n }\n\n mintSessionForUid = async (\n uid: EntryId,\n profile?: { email?: string; name?: string; avatarUrl?: string; emailVerified?: boolean }\n ): Promise<{ user: AuthUser; sessionCookie: string }> => {\n const customToken = await this.getAuth().createCustomToken(uid)\n const { ok, data } = await fetchIdentityToolkit<{ idToken?: string; error?: { message?: string } }>(\n 'accounts:signInWithCustomToken',\n this.#core.env.WEB_API_KEY,\n { token: customToken, returnSecureToken: true }\n )\n if (!ok || !data.idToken) {\n const msg = data.error?.message ?? 'CUSTOM_TOKEN_EXCHANGE_FAILED'\n return this.#core.errors.httpError(401, msg, msg)\n }\n return this.createSession(data.idToken, profile)\n }\n\n revokeSession = async (sessionCookie: string, deleteUser = false): Promise<void> => {\n const auth = this.getAuth()\n const uid = tokenCache.get(sessionCookie)?.uid ?? (await auth.verifySessionCookie(sessionCookie)).sub\n this.evictUserTokens(uid)\n tokenCache.delete(sessionCookie)\n await Promise.all([\n this.recordRevocation(uid, this.#core.env.isDev),\n auth.revokeRefreshTokens(uid).catch(() => {}),\n ...(deleteUser ? [auth.updateUser(uid, { disabled: true }).catch(() => {})] : [])\n ])\n }\n}\n", "import { CORE_CONFIG } from '../config'\nimport { getRegisteredCollectionNames, type EntryId } from '../db'\nimport type { Core } from '../index'\nimport type { StepRunner } from '../tasks'\nimport { AuthOidcEngine } from './oidc'\nimport { AuthRecoveryEngine } from './recovery'\nimport {\n eraseUserInput,\n eraseUserOutput,\n type AuthUser,\n type CompleteAccountRecoveryInput,\n type EraseUserInput,\n type EraseUserOutput,\n type ForgotPasswordInput,\n type InitiateAccountRecoveryInput,\n type ResetPasswordInput,\n type SetRecoveryEmailInput,\n type SocialSignInInput,\n type VerifyEmailInput,\n type VerifyRecoveryEmailInput\n} from './schema'\nimport { AuthSessionEngine, tokenCache } from './session'\nimport { hashToken, mapUserRecord, resolveUserRole } from './utils'\n\nexport class AuthService {\n readonly #core: Core\n readonly #session: AuthSessionEngine\n readonly #oidc: AuthOidcEngine\n readonly #recovery: AuthRecoveryEngine\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n this.#session = new AuthSessionEngine(coreClient)\n this.#oidc = new AuthOidcEngine(coreClient, this.#session)\n this.#recovery = new AuthRecoveryEngine(coreClient, this.#session)\n }\n\n signInSocial = (raw: SocialSignInInput): Promise<{ user: AuthUser; sessionCookie: string }> =>\n this.#oidc.signInSocial(raw)\n\n sendVerificationEmail = (userId?: EntryId): Promise<{ sent: true; expiresInMinutes: number }> =>\n this.#recovery.sendVerificationEmail(userId)\n\n verifyEmail = (raw: VerifyEmailInput): Promise<{ verified: true; userId: string }> =>\n this.#recovery.verifyEmail(raw)\n\n forgotPassword = (raw: ForgotPasswordInput): Promise<{ sent: true }> => this.#recovery.forgotPassword(raw)\n\n resetPassword = (raw: ResetPasswordInput): Promise<{ reset: true }> => this.#recovery.resetPassword(raw)\n\n setRecoveryEmail = (\n raw: SetRecoveryEmailInput,\n userId?: EntryId\n ): Promise<{ recoveryEmail: string; recoveryEmailVerified: false; sent: true }> =>\n this.#recovery.setRecoveryEmail(raw, userId)\n\n verifyRecoveryEmail = (\n raw: VerifyRecoveryEmailInput,\n userId?: EntryId\n ): Promise<{ recoveryEmail: string; recoveryEmailVerified: true; verified: true }> =>\n this.#recovery.verifyRecoveryEmail(raw, userId)\n\n initiateAccountRecovery = (raw: InitiateAccountRecoveryInput): Promise<{ initiated: true }> =>\n this.#recovery.initiateAccountRecovery(raw)\n\n completeAccountRecovery = (raw: CompleteAccountRecoveryInput): Promise<{ user: AuthUser; sessionCookie: string }> =>\n this.#recovery.completeAccountRecovery(raw)\n\n getUser = async (uid: EntryId): Promise<AuthUser | undefined> => {\n try {\n const [u, meta] = await Promise.all([\n this.#session.getAuth().getUser(uid),\n this.#session.getUserAuthMeta(uid, this.#core.env.isDev)\n ])\n return mapUserRecord(u, meta)\n } catch {\n return undefined\n }\n }\n\n setClaims = async (uid: EntryId, claims: Record<string, unknown> | null): Promise<void> => {\n await this.#session.getAuth().setCustomUserClaims(uid, claims)\n this.#session.evictUserTokens(uid)\n await this.#session.recordRevocation(uid, this.#core.env.isDev)\n }\n\n listUsers = async (includeDeleted = false): Promise<AuthUser[]> => {\n const { users } = await this.#session.getAuth().listUsers(1000)\n return users.map((u) => mapUserRecord(u)).filter((u) => includeDeleted || !u.deleted)\n }\n\n blockUser = async (\n userId: EntryId = this.#core.userId,\n blocked = true\n ): Promise<{ userId: EntryId; blocked: boolean; deleted: boolean }> => {\n const auth = this.#session.getAuth()\n this.#session.evictUserTokens(userId)\n await Promise.all([\n blocked\n ? this.#session.recordRevocation(userId, this.#core.env.isDev)\n : this.#session.clearUserRevocation(userId, this.#core.env.isDev),\n ...(blocked ? [auth.revokeRefreshTokens(userId).catch(() => {})] : []),\n auth.updateUser(userId, { disabled: blocked }).catch(() => {})\n ])\n return { userId, blocked, deleted: blocked }\n }\n\n #triggerFirestoreBackup = async (userId: string): Promise<string> => {\n const projectId = this.#core.config.gcpProject\n const dbId = this.#core.env.isDev ? this.#core.config.firestoreDbs.dev : this.#core.config.firestoreDbs.prod\n const bucketName = this.#core.env.isDev\n ? this.#core.config.storageBuckets.dev\n : this.#core.config.storageBuckets.prod\n const outputUriPrefix = `gs://${bucketName}/backups/${dbId}-${userId}-${Date.now()}`\n const accessToken = await this.#core.internals.registry.getGcpAccessToken()\n const res = await fetch(\n `https://firestore.googleapis.com/v1/projects/${projectId}/databases/${dbId}:exportDocuments`,\n {\n method: 'POST',\n headers: { Authorization: `Bearer ${accessToken}`, 'content-type': 'application/json' },\n body: JSON.stringify({ outputUriPrefix, collectionIds: getRegisteredCollectionNames() })\n }\n )\n if (!res.ok) throw new Error(`Firestore exportDocuments failed (${res.status}): ${await res.text()}`)\n const data = (await res.json()) as { name?: string }\n return data.name ?? outputUriPrefix\n }\n\n eraseUser = async (raw: EraseUserInput, step: StepRunner = this.#core.step): Promise<EraseUserOutput> => {\n const { userId, backupBeforeErase } = eraseUserInput.parse(raw)\n const backupOperation = backupBeforeErase\n ? await step('backup', () => this.#triggerFirestoreBackup(userId))\n : undefined\n\n const { erasedFiles, erasedChats, erasedCollections } =\n await this.#core.internals.registry.cascadeEraseUserCollections(userId, step)\n\n const erasedUser = await step('erase-user', async () => {\n this.#session.evictUserTokens(userId)\n await Promise.all([\n this.#session.recordRevocation(userId, this.#core.env.isDev),\n this.#session.getAuth().deleteUser(userId).catch(() => {})\n ])\n return true\n })\n\n return eraseUserOutput.parse({\n userId,\n ...(backupOperation ? { backupOperation } : {}),\n erasedFiles,\n erasedChats,\n ...(Object.keys(erasedCollections).length ? { erasedCollections } : {}),\n erasedUser\n })\n }\n\n get internals() {\n const getAuthWarm = this.#session.getAuthWarm\n return {\n verifyToken: this.#session.verifyToken,\n hashToken,\n resolveUserRole,\n tokenCache,\n setTokenCache: this.#session.setTokenCache,\n recordRevocation: this.#session.recordRevocation,\n syncRevocations: this.#session.syncRevocations,\n getLastDevEmail: this.#recovery.getLastDevEmail,\n registerTestOidcPublicKey: this.#oidc.registerTestOidcPublicKey,\n get sessionCookie() {\n return CORE_CONFIG.auth.sessionCookie\n },\n get authWarm() {\n return getAuthWarm()\n },\n mintCustomToken: this.#session.mintCustomToken,\n createSession: this.#session.createSession,\n signUpEmail: this.#oidc.signUpEmail,\n signInEmail: this.#oidc.signInEmail,\n revokeSession: this.#session.revokeSession,\n setSessionCookie: this.#session.setSessionCookie\n }\n }\n}\n", "import { deleteCookie, getCookie } from 'hono/cookie'\nimport type { Context } from 'hono'\nimport type { z } from 'zod'\nimport { CORE_CONFIG, type AppEnv, type DbRole } from '../config'\nimport type { EntryId } from '../db'\nimport { core } from '../index'\nimport type { StepRunner } from '../tasks'\nimport {\n blockUserBody,\n completeAccountRecoveryBody,\n customTokenBody,\n emailSignInBody,\n emailSignUpBody,\n eraseUserInput,\n eraseUserOutput,\n forgotPasswordBody,\n initiateAccountRecoveryBody,\n resetPasswordBody,\n sendVerificationEmailBody,\n sessionBody,\n setRecoveryEmailBody,\n signOutBody,\n socialSignInInput,\n verifyEmailBody,\n verifyRecoveryEmailBody,\n type AuthUser,\n type EraseUserInput\n} from './schema'\n\nconst respondWithSession = async (\n c: Context<AppEnv>,\n p: Promise<{ user: AuthUser; sessionCookie: string }>\n): Promise<AuthUser> => {\n const { user, sessionCookie } = await p\n core.internals.auth.setSessionCookie(c, sessionCookie)\n return user\n}\n\nexport const coreAuthRoutes = {\n 'auth.custom-token': {\n input: customTokenBody,\n handler: async ({\n input,\n userId,\n role\n }: {\n input: z.infer<typeof customTokenBody>\n userId: EntryId\n role: DbRole\n }) => {\n if (input.uid && role !== 'admin' && userId !== CORE_CONFIG.auth.adminUserId) {\n return core.errors.httpError(403, 'Admin privileges required to mint token for specific UID', 'FORBIDDEN')\n }\n return core.internals.auth.mintCustomToken(input.uid)\n }\n },\n 'auth.session.create': {\n input: sessionBody,\n handler: async ({ c, input }: { c: Context<AppEnv>; input: z.infer<typeof sessionBody> }) =>\n respondWithSession(c, core.internals.auth.createSession(input.idToken)).catch(() =>\n core.errors.httpError(401, 'Invalid ID token', 'INVALID_ID_TOKEN')\n )\n },\n 'auth.session.get': {\n handler: async ({ userId }: { userId: EntryId }) => ({ userId })\n },\n 'auth.sign-up.email': {\n input: emailSignUpBody,\n handler: async ({ c, input }: { c: Context<AppEnv>; input: z.infer<typeof emailSignUpBody> }) =>\n respondWithSession(c, core.internals.auth.signUpEmail(input.email, input.password, input.name))\n },\n 'auth.sign-in.email': {\n input: emailSignInBody,\n handler: async ({ c, input }: { c: Context<AppEnv>; input: z.infer<typeof emailSignInBody> }) =>\n respondWithSession(c, core.internals.auth.signInEmail(input.email, input.password))\n },\n 'auth.sign-in.social': {\n input: socialSignInInput,\n handler: async ({ c, input }: { c: Context<AppEnv>; input: z.infer<typeof socialSignInInput> }) =>\n respondWithSession(c, core.auth.signInSocial(input))\n },\n 'auth.email.send-verification': {\n input: sendVerificationEmailBody,\n handler: async ({ userId }: { userId: EntryId }) => core.auth.sendVerificationEmail(userId)\n },\n 'auth.email.verify': {\n input: verifyEmailBody,\n handler: async ({ input }: { input: z.infer<typeof verifyEmailBody> }) => core.auth.verifyEmail(input)\n },\n 'auth.password.forgot': {\n input: forgotPasswordBody,\n handler: async ({ input }: { input: z.infer<typeof forgotPasswordBody> }) => core.auth.forgotPassword(input)\n },\n 'auth.password.reset': {\n input: resetPasswordBody,\n handler: async ({ input }: { input: z.infer<typeof resetPasswordBody> }) => core.auth.resetPassword(input)\n },\n 'auth.recovery-email.set': {\n input: setRecoveryEmailBody,\n handler: async ({ userId, input }: { userId: EntryId; input: z.infer<typeof setRecoveryEmailBody> }) =>\n core.auth.setRecoveryEmail(input, userId)\n },\n 'auth.recovery-email.verify': {\n input: verifyRecoveryEmailBody,\n handler: async ({ userId, input }: { userId: EntryId; input: z.infer<typeof verifyRecoveryEmailBody> }) =>\n core.auth.verifyRecoveryEmail(input, userId)\n },\n 'auth.account-recovery.initiate': {\n input: initiateAccountRecoveryBody,\n handler: async ({ input }: { input: z.infer<typeof initiateAccountRecoveryBody> }) =>\n core.auth.initiateAccountRecovery(input)\n },\n 'auth.account-recovery.complete': {\n input: completeAccountRecoveryBody,\n handler: async ({ c, input }: { c: Context<AppEnv>; input: z.infer<typeof completeAccountRecoveryBody> }) =>\n respondWithSession(c, core.auth.completeAccountRecovery(input))\n },\n 'auth.users.list': {\n handler: async () => core.auth.listUsers()\n },\n 'auth.users.block': {\n input: blockUserBody,\n handler: async ({ userId, input }: { userId: EntryId; input: z.infer<typeof blockUserBody> }) =>\n core.auth.blockUser(input.userId ?? userId, input.blocked)\n },\n 'auth.users.delete': {\n mode: 'workflow' as const,\n workflowName: 'erase-user',\n input: eraseUserInput,\n output: eraseUserOutput,\n handler: async ({ input, step }: { input: EraseUserInput; step: StepRunner }) => core.auth.eraseUser(input, step)\n },\n 'auth.sign-out': {\n input: signOutBody,\n handler: async ({ c, input }: { c: Context<AppEnv>; input: z.infer<typeof signOutBody> }) => {\n const cookie = getCookie(c, CORE_CONFIG.auth.sessionCookie)\n if (cookie) await core.internals.auth.revokeSession(cookie, Boolean(input.deleteUser)).catch(() => {})\n deleteCookie(c, CORE_CONFIG.auth.sessionCookie, { path: '/' })\n return { ok: true }\n }\n }\n}\n", "import type { FieldValue, Timestamp } from 'firebase-admin/firestore'\nimport type { ModelMessage, streamText } from 'ai'\nimport { z } from 'zod'\nimport type { AttachmentTypesMap } from '../attachments'\nimport type { AppBindings, DbRole, RateLimitConfig } from '../config'\nimport { entryId, fileRef, type EntryId, type FileRef } from '../db'\nimport type { Core } from '../index'\nimport type { AuthLevel } from '../router'\n\nexport type VectorValue = ReturnType<typeof FieldValue.vector>\n\nexport type SystemPromptBuilder = (ctx: {\n today: string\n userId: EntryId\n env: AppBindings\n}) => string | Promise<string>\n\nexport interface AgentToolPresets {\n discovery?: string[]\n workflow?: string[]\n}\n\n/** Per-user data injected into a chat turn by `AgentConfig.resolveUserContext`. */\nexport interface UserContext {\n /** Compact flags (\u2264 ~1 KB). Sent to the InfoBase classifier and to the agent. */\n state: Record<string, unknown>\n /** Capped records (\u2264 ~8 KB). Sent to the agent only, never to the classifier. */\n details?: Record<string, unknown>\n}\n\nexport type UserContextResolver = (ctx: {\n userId: EntryId\n core: Core\n signal: AbortSignal\n}) => Promise<UserContext | undefined>\n\nexport interface AgentConfig {\n name?: string\n description?: string\n model?: string\n systemPrompt: string | SystemPromptBuilder\n tools?: string[]\n toolPresets?: AgentToolPresets\n maxSteps?: number\n useContext?: boolean\n /** Restricts InfoBase items to those tagged with any of these audiences. Omit for no filtering. */\n contextAudiences?: readonly string[]\n /** Loads the caller's own data for each turn. Must honour `signal`; failures degrade to no user context. */\n resolveUserContext?: UserContextResolver\n attachmentTypes?: AttachmentTypesMap\n auth?: AuthLevel\n rateLimit?: RateLimitConfig\n mcp?: boolean\n}\n\nexport const defineAgent = <C extends AgentConfig>(config: C): C => config\nexport const defineAgents = <T extends Record<string, AgentConfig>>(agents: T): T => agents\n\nexport interface ChatMetadataDoc {\n id: string\n userId: string\n agentId: string\n title: string\n model: string\n messageCount: number\n summary?: string | null\n activeGenerationId?: string | null\n deleted: boolean\n createdAt: Timestamp | Date\n updatedAt: Timestamp | Date\n}\n\nexport type ChatMessageRole = 'user' | 'assistant' | 'system' | 'tool'\n\nexport interface ChatMessageDoc {\n id: string\n chatId: string\n userId: string\n role: ChatMessageRole\n content: string\n parts: unknown[]\n toolInvocations?: unknown[]\n attachments?: string[]\n tokenCount?: number\n cancelled?: boolean\n createdAt: Timestamp | Date\n embedding?: VectorValue\n}\n\nexport type ChatMessagePublic = Omit<ChatMessageDoc, 'embedding' | 'createdAt'> & {\n createdAt: Date\n}\n\nexport interface RecalledMemorySnippet {\n id: string\n chatId: string\n role: ChatMessageRole\n content: string\n scope: 'in_chat' | 'cross_chat'\n}\n\nexport interface ContextItemSpec {\n path: string\n description: string\n /** Audiences allowed to receive this item (matched against `AgentConfig.contextAudiences`). Omit to expose to every agent. */\n audiences?: readonly string[]\n}\n\nexport const defineContext = <const T extends readonly ContextItemSpec[]>(items: T): T => items\n\nexport interface ContextEntry {\n path: string\n description: string\n markdown: string\n}\n\nexport interface GetContextOptions {\n maxSources?: number\n /** Only items tagged with any of these audiences (or untagged items) are considered. */\n audiences?: readonly string[]\n /** Compact caller state forwarded to the classifier to judge relevance. */\n userState?: Record<string, unknown>\n}\n\nexport interface DynamicContextBlockInput {\n currentTimeIso?: string\n recalledMemories?: readonly RecalledMemorySnippet[]\n infobaseContextEntries?: readonly ContextEntry[]\n stagedAttachmentSummaries?: readonly string[]\n userContext?: UserContext\n}\n\nexport interface HybridRetrievalOptions {\n userId?: EntryId\n chatId?: string\n messageCount?: number\n prompt: string\n useContext?: boolean\n slidingWindowSize?: number\n /** Agent whose `contextAudiences` and `resolveUserContext` scope this turn. */\n agent?: Pick<AgentConfig, 'contextAudiences' | 'resolveUserContext'>\n /** Verified caller role (defaults to `resolveUserRole(userId)`). */\n role?: DbRole\n abortSignal?: AbortSignal\n}\n\nexport interface HybridRetrievalResult {\n slidingWindowDocs: ChatMessagePublic[]\n slidingWindowMessages: ModelMessage[]\n recalledMemories: RecalledMemorySnippet[]\n infobaseContextEntries: ContextEntry[]\n userContext?: UserContext\n}\n\nexport interface ListChatMessagesOptions {\n limit?: number\n before?: EntryId\n}\n\nexport interface WorkflowToolSpec {\n description: string\n input: z.ZodType<any>\n mcp?: boolean\n tool?: boolean\n execute: (input: any, userId: EntryId) => Promise<unknown>\n}\n\nexport interface VerifiedAgentToolContext {\n core: Core\n chatId?: string\n abortSignal?: AbortSignal\n}\n\nexport interface RunAgentOptions {\n modelOverride?: string\n chatId?: string\n abortSignal?: AbortSignal\n dynamicContext?: DynamicContextBlockInput\n core?: Core\n onFinish?: Parameters<typeof streamText>[0]['onFinish']\n}\n\nexport interface AskAgentOptions {\n userId?: EntryId\n includeContext?: boolean\n abortSignal?: AbortSignal\n}\n\nexport const ReasoningExpertInputDto = z.object({\n problemStatement: z.string().describe('Self-contained specification of the complex reasoning task.'),\n constraintsAndContext: z.string().describe('Compact summary of relevant data, constraints, or document fields.')\n})\n\nexport const ReasoningExpertOutputDto = z.object({\n analysisSummary: z.string(),\n recommendedSolution: z.string(),\n edgeCasesToWatch: z.array(z.string())\n})\n\nexport interface RawAttachmentPart {\n dataUrl?: string\n ref?: FileRef\n filename: string\n}\n\nexport interface PersistTurnCompletionOpts {\n turn: ReturnType<typeof import('ai').streamText>\n getAccumulatedText: () => string\n signal: AbortSignal\n userVecPromise: Promise<number[] | null>\n chatDocRef: import('firebase-admin/firestore').DocumentReference\n chatId: string\n userId: EntryId\n resolvedAgentId: string\n title: string\n selectedModel: string\n userMsgId: string\n assistantMsgId: string\n userCreatedAtMs: number\n finalUserText: string\n userPartsForStorage: unknown[]\n stagedRefs: FileRef[]\n unsubCancelWatch: (() => void) | undefined\n key: string\n}\n\nexport const chatIdParam = z.object({ chatId: entryId })\n\nexport const listChatMessagesQuery = z.object({\n limit: z.coerce.number().int().min(1).max(200).optional(),\n before: entryId.optional()\n})\n\nexport const saveChatBody = z\n .object({\n id: entryId.optional(),\n chatId: entryId.optional(),\n title: z.string().min(1).max(256).optional(),\n agentId: z.string().min(1).max(128).optional(),\n model: z.string().min(1).max(128).optional(),\n summary: z.string().max(4000).nullable().optional()\n })\n .strict()\n\nexport const streamChatMessageInput = z.object({\n id: entryId.optional(),\n role: z.literal('user').default('user'),\n content: z.string().optional(),\n parts: z.array(z.record(z.string(), z.unknown())).optional(),\n attachments: z.array(fileRef).max(20).optional()\n})\n\nexport type StreamChatMessageInput = z.infer<typeof streamChatMessageInput>\n\nexport const streamChatBody = z\n .object({\n id: entryId.optional(),\n chatId: entryId.optional(),\n agentId: z.string().min(1).max(128).optional(),\n title: z.string().max(256).optional(),\n model: z.string().max(128).optional(),\n message: streamChatMessageInput\n })\n .strict()\n\nexport const openaiMessagePartSchema = z\n .object({\n type: z.string(),\n text: z.string().optional(),\n image_url: z.object({ url: z.string().optional() }).optional(),\n file: z.object({ file_data: z.string().optional(), filename: z.string().optional() }).optional()\n })\n .passthrough()\n\nexport const openaiMessageSchema = z\n .object({\n role: z.string(),\n content: z.union([z.string(), z.array(openaiMessagePartSchema), z.null()]).optional()\n })\n .passthrough()\n\nexport const openaiCompletionsBody = z\n .object({\n model: z.string(),\n messages: z.array(openaiMessageSchema).min(1).max(500),\n stream: z.boolean().optional(),\n stream_options: z.object({ include_usage: z.boolean().optional() }).optional()\n })\n .extend({ model: z.string().optional() })\n .passthrough()\n\nexport const webSearchInput = z.object({\n query: z.string().min(1).optional(),\n url: z.string().optional().describe('Full URL to open and read \u2014 wins over query')\n})\n", "import {\n stepCountIs,\n streamText,\n tool as aiTool,\n type ModelMessage,\n type SystemModelMessage,\n type ToolSet\n} from 'ai'\nimport { registerAttachmentTypes } from '../attachments'\nimport { CORE_CONFIG } from '../config'\nimport type { EntryId } from '../db'\nimport { Core } from '../index'\nimport { ChatContextEngine } from './context'\nimport {\n ReasoningExpertInputDto,\n ReasoningExpertOutputDto,\n webSearchInput,\n type AgentConfig,\n type AskAgentOptions,\n type ChatMessagePublic,\n type ContextEntry,\n type ContextItemSpec,\n type GetContextOptions,\n type HybridRetrievalOptions,\n type HybridRetrievalResult,\n type ListChatMessagesOptions,\n type RunAgentOptions,\n type VerifiedAgentToolContext,\n type WorkflowToolSpec\n} from './schema'\nimport { ChatStreamEngine } from './stream'\nimport {\n buildDynamicContextBlock,\n extractLatestUserPrompt,\n FORBIDDEN_TOOL_SCHEMA_KEYS,\n isSafePublicUrl,\n sanitizeToolInputSchema\n} from './utils'\n\nconst toolRegistry = new Map<string, WorkflowToolSpec>()\nconst agentRegistry = new Map<string, AgentConfig>()\n\nexport class ChatService {\n readonly #core: Core\n readonly #contextEngine: ChatContextEngine\n readonly #streamEngine: ChatStreamEngine\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n this.#contextEngine = new ChatContextEngine(coreClient)\n this.#streamEngine = new ChatStreamEngine(coreClient, agentRegistry)\n }\n\n #registerWorkflowTool = (name: string, spec: WorkflowToolSpec): void => {\n toolRegistry.set(name, {\n ...spec,\n mcp: spec.mcp === true,\n tool: spec.tool !== false,\n input: sanitizeToolInputSchema(spec.input)\n })\n }\n\n #clearWorkflowTools = (): void => {\n toolRegistry.clear()\n }\n\n #getMcpTools = (): Map<string, WorkflowToolSpec> =>\n new Map([...toolRegistry.entries()].filter(([, spec]) => spec.mcp === true))\n\n #registerAgents = (defs: Record<string, AgentConfig>, reset = false): void => {\n if (reset) {\n agentRegistry.clear()\n registerAttachmentTypes(undefined, true)\n }\n for (const [id, cfg] of Object.entries(defs)) {\n agentRegistry.set(id, { ...cfg, name: cfg.name ?? id })\n if (cfg.attachmentTypes) registerAttachmentTypes(cfg.attachmentTypes)\n }\n }\n\n #getRegisteredAgents = (): Record<string, AgentConfig> => Object.fromEntries(agentRegistry)\n\n #getAgentRegistry = (): Map<string, AgentConfig> => agentRegistry\n\n getContext = (\n prompt: string,\n catalog?: readonly ContextItemSpec[],\n options?: GetContextOptions\n ): Promise<ContextEntry[]> => this.#contextEngine.getContext(prompt, catalog, options)\n\n retrieveContext = (opts: HybridRetrievalOptions): Promise<HybridRetrievalResult> =>\n this.#contextEngine.retrieveContext(opts)\n\n messages = (chatId: EntryId, opts?: ListChatMessagesOptions): Promise<ChatMessagePublic[]> =>\n this.#streamEngine.messages(chatId, opts)\n\n cancel = (chatId: EntryId): Promise<{ chatId: string; cancelled: true }> =>\n this.#streamEngine.cancel(chatId)\n\n #webSearchTool = (abortSignal?: AbortSignal) =>\n aiTool({\n description: 'Search the web (DuckDuckGo) or open a URL and read it as markdown. Use for current information.',\n inputSchema: webSearchInput,\n execute: async ({ query, url }) => {\n const useUrl = isSafePublicUrl(url)\n const target = useUrl ? url! : `https://html.duckduckgo.com/html/?q=${encodeURIComponent(query ?? url ?? '')}`\n const maxChars = useUrl ? 6000 : 4000\n try {\n const timeoutSignal = AbortSignal.timeout(20_000)\n const signal = abortSignal ? AbortSignal.any([abortSignal, timeoutSignal]) : timeoutSignal\n const jinaKey = this.#core.env.JINA_API_KEY\n const res = await fetch(`https://r.jina.ai/${target}`, {\n headers: {\n Accept: 'text/plain, text/markdown;q=0.9, */*;q=0.8',\n ...(jinaKey ? { Authorization: `Bearer ${jinaKey}` } : {})\n },\n signal\n })\n if (!res.ok) return { text: `Web ${useUrl ? 'page' : 'search'} failed (HTTP ${res.status}).` }\n const reader = res.body?.getReader()\n if (!reader) return { text: '' }\n const decoder = new TextDecoder()\n let text = ''\n while (text.length < maxChars + 256) {\n const { done, value } = await reader.read()\n if (done) break\n text += decoder.decode(value, { stream: true })\n }\n await reader.cancel().catch(() => {})\n return { text: text.slice(0, maxChars).replace(/\\s+\\S*$/, '') }\n } catch {\n return { text: 'Web search failed.' }\n }\n }\n })\n\n #createReasoningExpertTool = (ctx: VerifiedAgentToolContext) =>\n aiTool({\n description:\n 'Delegate complex architectural, legal, financial, or multi-constraint reasoning problems to a frontier reasoning model. Use only when standard analysis is insufficient.',\n inputSchema: ReasoningExpertInputDto,\n execute: async ({ problemStatement, constraintsAndContext }) => {\n const result = await ctx.core.ai.generate(\n `Problem:\\n${problemStatement}\\n\\nConstraints & Context:\\n${constraintsAndContext}`,\n {\n schema: ReasoningExpertOutputDto,\n model: CORE_CONFIG.models.vertexExpert ?? 'claude-sonnet-4-5',\n signal: ctx.abortSignal\n }\n )\n return result.output\n }\n })\n\n #buildAgentToolsForTurn = (toolKeys: string[] = [], ctx: VerifiedAgentToolContext): ToolSet => {\n const tools: ToolSet = {}\n const { core: turnCore, abortSignal } = ctx\n const coreState = {\n env: turnCore.env,\n userId: turnCore.userId,\n role: turnCore.role,\n step: turnCore.step\n }\n\n for (const name of toolKeys) {\n if (name === 'web_search') {\n tools[name] = this.#webSearchTool(abortSignal)\n } else if (name === 'consult_reasoning_expert') {\n tools[name] = this.#createReasoningExpertTool(ctx)\n } else {\n const wf = toolRegistry.get(name)\n if (wf && wf.tool !== false) {\n tools[name] = aiTool({\n description: wf.description,\n inputSchema: sanitizeToolInputSchema(wf.input),\n execute: (rawInput) =>\n this.#core.internals.context.run(coreState, async () => {\n const safeInput =\n rawInput && typeof rawInput === 'object'\n ? Object.fromEntries(\n Object.entries(rawInput as Record<string, unknown>).filter(\n ([k]) => !FORBIDDEN_TOOL_SCHEMA_KEYS.has(k)\n )\n )\n : rawInput\n return wf.execute(safeInput, turnCore.userId)\n })\n })\n }\n }\n }\n return tools\n }\n\n #resolveStaticSystemPrompt = async (agent: AgentConfig): Promise<string> => {\n const raw =\n typeof agent.systemPrompt === 'function'\n ? await agent.systemPrompt({\n today: 'see dynamic context',\n userId: 'authenticated-user',\n env: this.#core.env\n })\n : agent.systemPrompt\n return raw\n .replace(/\\s*Today is \\{\\{today\\}\\}\\.?/gi, '')\n .replace(/\\s*Current userId is \\{\\{userId\\}\\}\\.?/gi, '')\n .replaceAll('{{today}}', 'see dynamic context')\n .replaceAll('{{userId}}', 'authenticated-user')\n .trim()\n }\n\n #resolveStepActiveTools = (agent: AgentConfig, allToolNames: string[], stepNumber: number): string[] => {\n if (allToolNames.length === 0) return []\n const presets = agent.toolPresets\n if (!presets) return allToolNames\n if (stepNumber === 0 && presets.discovery?.length && presets.workflow?.length) {\n return [...new Set([...presets.discovery, ...presets.workflow])].filter((k) => allToolNames.includes(k))\n }\n if (stepNumber > 0 && presets.workflow?.length) {\n return presets.workflow.filter((k) => allToolNames.includes(k))\n }\n return allToolNames\n }\n\n stream = async (\n agent: AgentConfig,\n messages: ModelMessage[],\n userId: EntryId = this.#core.userId,\n opts?: RunAgentOptions\n ): Promise<ReturnType<typeof streamText>> => {\n await this.#core.internals.payments.enforceAiQuota(userId)\n const [, staticCoreAgentInstructions] = await Promise.all([\n this.#core.internals.resilience.acquireLimit('ai'),\n this.#resolveStaticSystemPrompt(agent)\n ])\n\n const role = opts?.core?.role ?? this.#core.internals.auth.resolveUserRole(userId, this.#core.role)\n const verifiedCore = opts?.core ?? new Core({ env: this.#core.env, userId, role })\n const tools = this.#buildAgentToolsForTurn(agent.tools ?? [], {\n core: verifiedCore,\n chatId: opts?.chatId,\n abortSignal: opts?.abortSignal\n })\n const allToolNames = Object.keys(tools)\n\n const dynamicBlock = buildDynamicContextBlock({\n currentTimeIso: opts?.dynamicContext?.currentTimeIso ?? new Date().toISOString(),\n recalledMemories: opts?.dynamicContext?.recalledMemories,\n infobaseContextEntries: opts?.dynamicContext?.infobaseContextEntries,\n stagedAttachmentSummaries: opts?.dynamicContext?.stagedAttachmentSummaries,\n userContext: opts?.dynamicContext?.userContext\n })\n\n const systemInstructions: SystemModelMessage[] = [\n {\n role: 'system',\n content: staticCoreAgentInstructions,\n providerOptions: {\n anthropic: { cacheControl: { type: 'ephemeral' } },\n vertex: { cacheControl: { type: 'ephemeral' } }\n }\n },\n {\n role: 'system',\n content: dynamicBlock\n }\n ]\n\n const messagesForLlm: ModelMessage[] = messages.filter((m) => m.role !== 'system')\n const selectedModel = opts?.modelOverride || agent.model || CORE_CONFIG.models.vertex\n\n return streamText({\n model: this.#core.ai.languageModel(selectedModel),\n system: systemInstructions,\n messages: messagesForLlm,\n tools,\n ...(allToolNames.length > 0\n ? {\n activeTools: allToolNames,\n prepareStep: ({ stepNumber, messages: stepMessages }) => ({\n activeTools: this.#resolveStepActiveTools(agent, allToolNames, stepNumber),\n ...(stepNumber > 2 && stepMessages.length > CORE_CONFIG.limits.chatMessagesLimit\n ? { messages: stepMessages.slice(-CORE_CONFIG.limits.chatMessagesLimit) }\n : {})\n })\n }\n : {}),\n stopWhen: stepCountIs(agent.maxSteps ?? CORE_CONFIG.models.defaultAgentMaxSteps),\n ...(opts?.abortSignal ? { abortSignal: opts.abortSignal } : {}),\n onFinish: async (event) => {\n const usageObj = (event as { totalUsage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number }; usage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number } }).totalUsage ?? event.usage\n await this.#core.internals.payments.trackAiUsage({\n userId,\n model: selectedModel,\n inputTokens: usageObj?.inputTokens ?? 0,\n outputTokens: usageObj?.outputTokens ?? 0,\n ...(typeof usageObj?.totalTokens === 'number' ? { totalTokens: usageObj.totalTokens } : {}),\n source: 'chat'\n })\n await opts?.onFinish?.(event)\n }\n })\n }\n\n ask = async (\n agentOrId: string | AgentConfig,\n prompt: string | ModelMessage[],\n options?: AskAgentOptions\n ): Promise<{ text: string; messages: ModelMessage[] }> => {\n const agent = typeof agentOrId === 'string' ? agentRegistry.get(agentOrId) : agentOrId\n if (!agent) return this.#core.errors.httpError(404, `Unknown agent: ${String(agentOrId)}`, 'NOT_FOUND')\n\n const userId = options?.userId ?? this.#core.userId ?? CORE_CONFIG.auth.adminUserId\n const rawMessages: ModelMessage[] =\n typeof prompt === 'string' ? [{ role: 'user', content: [{ type: 'text', text: prompt }] }] : [...prompt]\n const latestPrompt = typeof prompt === 'string' ? prompt : extractLatestUserPrompt(rawMessages)\n\n const hybrid =\n options?.includeContext !== false\n ? await this.retrieveContext({\n userId,\n prompt: latestPrompt,\n useContext: agent.useContext !== false,\n agent,\n abortSignal: options?.abortSignal\n })\n : { recalledMemories: [], infobaseContextEntries: [], userContext: undefined }\n\n const turn = await this.stream(agent, rawMessages.slice(-15), userId, {\n abortSignal: options?.abortSignal,\n dynamicContext: {\n recalledMemories: hybrid.recalledMemories,\n infobaseContextEntries: hybrid.infobaseContextEntries,\n userContext: hybrid.userContext\n }\n })\n const [text, res] = await Promise.all([turn.text, turn.response])\n return {\n text,\n messages: [...rawMessages, ...(res.messages as unknown as ModelMessage[])]\n }\n }\n\n get internals() {\n return {\n registerWorkflowTool: this.#registerWorkflowTool,\n clearWorkflowTools: this.#clearWorkflowTools,\n getMcpTools: this.#getMcpTools,\n registerAgents: this.#registerAgents,\n getRegisteredAgents: this.#getRegisteredAgents,\n getAgentRegistry: this.#getAgentRegistry,\n registerContextCatalog: this.#contextEngine.registerContextCatalog,\n enforceAgentAccess: this.#streamEngine.enforceAgentAccess,\n stageAndScanAttachments: this.#streamEngine.stageAndScanAttachments,\n startChatStreamTurn: this.#streamEngine.startChatStreamTurn,\n saveChat: this.#streamEngine.saveChat,\n streamChatSse: this.#streamEngine.streamChatSse\n }\n }\n}\n", "import { readFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport type { ModelMessage } from 'ai'\nimport { FieldValue, type Query } from 'firebase-admin/firestore'\nimport type { JevQuestion } from '../ai'\nimport { CORE_CONFIG, type DbRole } from '../config'\nimport type { EntryId } from '../db'\nimport { Core } from '../index'\nimport type {\n AgentConfig,\n ChatMessagePublic,\n ChatMessageRole,\n ContextEntry,\n ContextItemSpec,\n GetContextOptions,\n HybridRetrievalOptions,\n HybridRetrievalResult,\n RecalledMemorySnippet,\n UserContext,\n VectorValue\n} from './schema'\nimport {\n isContextItemVisible,\n isUserContextShape,\n mapFirestoreMessageDoc,\n PUBLIC_MESSAGE_FIELDS,\n RECALL_MESSAGE_FIELDS,\n toModelMessageFromDoc\n} from './utils'\n\nlet contextCatalog: readonly ContextItemSpec[] = []\nconst markdownCache = new Map<string, string>()\n\nexport class ChatContextEngine {\n readonly #core: Core\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n }\n\n registerContextCatalog = (items: readonly ContextItemSpec[] = [], reset = false): void => {\n if (reset) {\n contextCatalog = []\n markdownCache.clear()\n }\n contextCatalog = [...items]\n }\n\n #readContextMarkdown = async (relPath: string): Promise<string | undefined> => {\n const cached = markdownCache.get(relPath)\n if (cached !== undefined) return cached\n\n const contextRoot = path.resolve(process.cwd(), CORE_CONFIG.context.dir)\n const resolved = path.resolve(contextRoot, relPath)\n if (!resolved.startsWith(contextRoot + path.sep) || !relPath.endsWith('.md')) {\n return undefined\n }\n\n try {\n const content = await readFile(resolved, 'utf8')\n markdownCache.set(relPath, content)\n return content\n } catch {\n return undefined\n }\n }\n\n getContext = async (\n prompt: string,\n catalog: readonly ContextItemSpec[] = contextCatalog,\n options?: GetContextOptions\n ): Promise<ContextEntry[]> => {\n const trimmed = prompt.trim()\n if (!trimmed || catalog.length === 0) return []\n\n const validItems = catalog.filter(\n (item) =>\n item.path?.endsWith('.md') &&\n !item.path.includes('..') &&\n !path.isAbsolute(item.path) &&\n isContextItemVisible(item, options?.audiences)\n )\n if (validItems.length === 0) return []\n\n const maxSources = options?.maxSources ?? CORE_CONFIG.context.maxSources\n const userState = options?.userState\n const stateHint = userState ? ' Use the provided userState when judging relevance.' : ''\n const questions: Record<string, JevQuestion> = {}\n validItems.forEach((item, idx) => {\n questions[`doc_${idx}`] = {\n type: 'noul',\n instructions: `Is documentation file \"${item.path}\" (${item.description}) directly relevant to answering the user prompt?${stateHint}`,\n criteria: {\n true: `The user prompt requires or benefits from documentation in ${item.path} (${item.description})`,\n false: 'The user prompt is unrelated to this documentation file'\n }\n }\n })\n\n try {\n const decision = await this.#core.ai.decide(\n { prompt: trimmed, ...(userState ? { userState } : {}) },\n questions\n )\n const scored = validItems\n .map((item, idx) => {\n const ans = decision.answers[`doc_${idx}`]\n return { item, score: ans?.type === 'noul' ? ans.noul : 0 }\n })\n .filter((x) => x.score >= 0.5)\n .sort((a, b) => b.score - a.score)\n .slice(0, maxSources)\n\n if (scored.length === 0) return []\n\n const loaded = await Promise.all(\n scored.map(async ({ item }): Promise<ContextEntry | undefined> => {\n const markdown = await this.#readContextMarkdown(item.path)\n return markdown ? { path: item.path, description: item.description, markdown } : undefined\n })\n )\n return loaded.filter((entry): entry is ContextEntry => Boolean(entry))\n } catch {\n return []\n }\n }\n\n #resolveTurnUserContext = async (opts: {\n userId: EntryId\n role?: DbRole\n agent?: Pick<AgentConfig, 'resolveUserContext'>\n abortSignal?: AbortSignal\n }): Promise<UserContext | undefined> => {\n const resolver = opts.agent?.resolveUserContext\n const role = opts.role ?? this.#core.internals.auth.resolveUserRole(opts.userId)\n if (!resolver || !opts.userId || role === 'anon') return undefined\n const timeout = AbortSignal.timeout(CORE_CONFIG.context.userContextTimeoutMs)\n const signal = opts.abortSignal ? AbortSignal.any([opts.abortSignal, timeout]) : timeout\n let onAbort: (() => void) | undefined\n try {\n const state = { env: this.#core.env, userId: opts.userId, role }\n const turnCore = new Core(state)\n const aborted = new Promise<undefined>((resolve) => {\n onAbort = () => resolve(undefined)\n if (signal.aborted) return resolve(undefined)\n signal.addEventListener('abort', onAbort, { once: true })\n })\n const result = await Promise.race([\n this.#core.internals.context.run(state, () =>\n Promise.resolve(resolver({ userId: opts.userId, core: turnCore, signal }))\n ),\n aborted\n ])\n return isUserContextShape(result) ? result : undefined\n } catch {\n return undefined\n } finally {\n if (onAbort) signal.removeEventListener('abort', onAbort)\n }\n }\n\n #queryNearestMessages = async (\n baseQuery: Query,\n vectorValue: VectorValue,\n limit: number,\n scope: 'in_chat' | 'cross_chat',\n fallbackChatId = ''\n ): Promise<RecalledMemorySnippet[]> => {\n try {\n await this.#core.internals.resilience.acquireLimit('firestore')\n const snap = await baseQuery\n .select(...RECALL_MESSAGE_FIELDS)\n .findNearest({\n vectorField: 'embedding',\n queryVector: vectorValue,\n limit,\n distanceMeasure: 'COSINE',\n distanceThreshold: 0.35\n })\n .get()\n return snap.docs\n .map((d) => {\n const data = d.data()\n const content = typeof data.content === 'string' ? data.content.trim() : ''\n if (!content) return undefined\n return {\n id: d.id,\n chatId: typeof data.chatId === 'string' ? data.chatId : fallbackChatId,\n role: (data.role === 'assistant' ? 'assistant' : 'user') as ChatMessageRole,\n content,\n scope\n }\n })\n .filter((x): x is RecalledMemorySnippet => Boolean(x))\n } catch {\n return []\n }\n }\n\n #vectorRecall = async (\n prompt: string,\n userId: EntryId,\n chatId: string | undefined,\n messageCount: number,\n slidingWindowSize: number\n ): Promise<RecalledMemorySnippet[]> => {\n const queryVector = await this.#core.ai.embed(prompt)\n if (!queryVector) return []\n const vectorValue = FieldValue.vector(queryVector)\n const db = this.#core.db.firestore()\n\n const inChatPromise =\n chatId && messageCount > slidingWindowSize\n ? this.#queryNearestMessages(\n db.collection('chat').doc(chatId).collection('messages'),\n vectorValue,\n 5,\n 'in_chat',\n chatId\n )\n : Promise.resolve([] as RecalledMemorySnippet[])\n\n const crossChatPromise = userId\n ? this.#queryNearestMessages(\n db.collectionGroup('messages').where('userId', '==', userId),\n vectorValue,\n 3,\n 'cross_chat'\n )\n : Promise.resolve([] as RecalledMemorySnippet[])\n\n const [inChat, crossChat] = await Promise.all([inChatPromise, crossChatPromise])\n return [...inChat, ...crossChat]\n }\n\n retrieveContext = async (opts: HybridRetrievalOptions): Promise<HybridRetrievalResult> => {\n const {\n userId = this.#core.userId,\n chatId,\n messageCount = 0,\n prompt,\n useContext = true,\n slidingWindowSize = CORE_CONFIG.limits.chatMessagesLimit,\n agent,\n role,\n abortSignal\n } = opts\n const db = this.#core.db.firestore()\n\n const userContextPromise = this.#resolveTurnUserContext({ userId, role, agent, abortSignal })\n\n const slidingWindowPromise = (async (): Promise<ChatMessagePublic[]> => {\n if (!chatId) return []\n try {\n await this.#core.internals.resilience.acquireLimit('firestore')\n const snap = await db\n .collection('chat')\n .doc(chatId)\n .collection('messages')\n .select(...PUBLIC_MESSAGE_FIELDS)\n .orderBy('createdAt', 'desc')\n .limit(slidingWindowSize)\n .get()\n return snap.docs.map((d) => mapFirestoreMessageDoc(d.id, d.data() ?? {})).reverse()\n } catch {\n return []\n }\n })()\n\n const vectorRecallPromise = this.#vectorRecall(prompt, userId, chatId, messageCount, slidingWindowSize)\n\n const infobasePromise =\n useContext !== false && prompt.trim()\n ? userContextPromise.then((userContext) =>\n this.getContext(prompt, undefined, {\n ...(agent?.contextAudiences ? { audiences: agent.contextAudiences } : {}),\n ...(userContext ? { userState: userContext.state } : {})\n })\n )\n : Promise.resolve([] as ContextEntry[])\n\n const [slidingWindowDocs, rawRecalled, infobaseContextEntries, userContext] = await Promise.all([\n slidingWindowPromise,\n vectorRecallPromise,\n infobasePromise,\n userContextPromise\n ])\n\n const windowIds = new Set(slidingWindowDocs.map((m) => m.id))\n const seenRecallIds = new Set<string>()\n const recalledMemories: RecalledMemorySnippet[] = []\n for (const mem of rawRecalled) {\n if (windowIds.has(mem.id) || seenRecallIds.has(mem.id)) continue\n seenRecallIds.add(mem.id)\n recalledMemories.push(mem)\n }\n\n const slidingWindowMessages = slidingWindowDocs\n .map(toModelMessageFromDoc)\n .filter((m): m is ModelMessage => Boolean(m))\n\n return {\n slidingWindowDocs,\n slidingWindowMessages,\n recalledMemories,\n infobaseContextEntries,\n ...(userContext ? { userContext } : {})\n }\n }\n}\n", "import { FieldValue, Timestamp, type DocumentReference, type Firestore } from 'firebase-admin/firestore'\nimport { createUIMessageStreamResponse, toUIMessageStream, type LanguageModelUsage, type ModelMessage, type streamText } from 'ai'\nimport { z } from 'zod'\nimport type { ProcessedAttachment } from '../attachments'\nimport type { EntryId } from '../db'\nimport type { FileRef } from '../files'\nimport type {\n ChatMessagePublic,\n ChatMessageRole,\n ContextEntry,\n ContextItemSpec,\n DynamicContextBlockInput,\n RawAttachmentPart,\n UserContext,\n streamChatBody\n} from './schema'\n\nexport const FORBIDDEN_TOOL_SCHEMA_KEYS = new Set([\n 'userId',\n 'chatId',\n 'role',\n 'userRole',\n 'token',\n 'idToken',\n 'apiKey',\n 'session'\n])\n\nexport const sanitizeToolInputSchema = (schema: z.ZodType<any>): z.ZodType<any> => {\n if (schema instanceof z.ZodObject) {\n const shape = schema.shape as Record<string, z.ZodType<any>>\n const keysToOmit: Record<string, true> = {}\n let hasForbidden = false\n for (const key of Object.keys(shape)) {\n if (FORBIDDEN_TOOL_SCHEMA_KEYS.has(key)) {\n keysToOmit[key] = true\n hasForbidden = true\n }\n }\n if (hasForbidden) {\n return schema.omit(keysToOmit)\n }\n }\n return schema\n}\n\nexport const isUserContextShape = (value: unknown): value is UserContext =>\n Boolean(value) &&\n typeof value === 'object' &&\n typeof (value as UserContext).state === 'object' &&\n (value as UserContext).state !== null\n\nexport const formatAttachmentLine = (filename: string, item: ProcessedAttachment): string =>\n 'error' in item\n ? `[attached ${filename} (ref: ${item.ref}) (error: ${item.error})]\\n`\n : `[attached ${filename} (ref: ${item.ref}) (type: ${item.scan.type}) (fields: ${JSON.stringify(item.scan.fields ?? {})}) (markdown: ${item.scan.markdown ?? ''})]\\n`\n\nexport const isSafePublicUrl = (raw?: string): boolean => {\n if (!raw) return false\n try {\n const u = new URL(raw)\n const host = u.hostname.toLowerCase()\n return (\n (u.protocol === 'https:' || u.protocol === 'http:') &&\n !/^(\\d+|0x[0-9a-f]+)$/i.test(host) &&\n !/^(localhost|127\\.|10\\.|100\\.(6[4-9]|[7-9]\\d|1[01]\\d|12[0-7])\\.|169\\.254\\.|192\\.168\\.|172\\.(1[6-9]|2\\d|3[01])\\.|0\\.|metadata\\.|\\[(::1?|fc|fd|fe80:|::ffff:))/i.test(\n host\n ) &&\n !/(\\.internal|\\.local|\\.nip\\.io|\\.sslip\\.io)\\.?$/i.test(host)\n )\n } catch {\n return false\n }\n}\n\nexport const extractPart = (p: Record<string, unknown>): RawAttachmentPart | undefined => {\n if (!p || typeof p !== 'object' || (p.type !== 'file' && !('url' in p))) return undefined\n const url = String(p.url ?? '')\n const dataUrl = url.startsWith('data:') ? url : undefined\n const ref = url.match(/^\\/api\\/files\\/([A-Za-z0-9_-]+_[a-f0-9]{24})$/)?.[1]\n return dataUrl || ref ? { dataUrl, ref, filename: typeof p.filename === 'string' ? p.filename : 'file' } : undefined\n}\n\nexport const extractTurnAttachmentParts = (msg: z.infer<typeof streamChatBody>['message']): RawAttachmentPart[] => {\n const fromParts = (msg.parts ?? [])\n .map((p) => extractPart(p))\n .filter((p): p is RawAttachmentPart => Boolean(p))\n const seenRefs = new Set(fromParts.map((p) => p.ref).filter(Boolean))\n const fromRefs: RawAttachmentPart[] = (msg.attachments ?? [])\n .filter((ref) => !seenRefs.has(ref))\n .map((ref) => ({ ref, filename: ref }))\n return [...fromParts, ...fromRefs]\n}\n\nexport const extractMessageText = (msg: { content?: unknown; parts?: readonly unknown[] }): string => {\n if (typeof msg.content === 'string' && msg.content.trim()) return msg.content.trim()\n const items = (Array.isArray(msg.content) ? msg.content : Array.isArray(msg.parts) ? msg.parts : []) as Record<\n string,\n unknown\n >[]\n return items\n .filter((p) => p && typeof p === 'object' && p.type === 'text' && typeof p.text === 'string')\n .map((p) => (p.text as string).trim())\n .filter(Boolean)\n .join('\\n')\n}\n\nexport const deriveTitle = (\n msgOrList: { content?: unknown; parts?: readonly unknown[]; role?: string } | readonly Record<string, unknown>[]\n): string => {\n const list = Array.isArray(msgOrList) ? msgOrList : [msgOrList]\n for (const m of list) {\n if (m.role && m.role !== 'user') continue\n const text = extractMessageText(m as { content?: unknown; parts?: readonly unknown[] })\n if (text) return text.slice(0, 80)\n }\n return 'New Chat'\n}\n\nexport const extractLatestUserPrompt = (messages: readonly (Record<string, unknown> | ModelMessage)[]): string => {\n for (let i = messages.length - 1; i >= 0; i--) {\n const m = messages[i] as Record<string, unknown>\n if (m?.role !== 'user') continue\n const text = extractMessageText(m as { content?: unknown; parts?: readonly unknown[] })\n if (text) return text\n }\n return ''\n}\n\nexport const formatUsage = (usage: LanguageModelUsage | null) => ({\n prompt_tokens: usage?.inputTokens ?? 0,\n completion_tokens: usage?.outputTokens ?? 0,\n total_tokens: usage?.totalTokens ?? (usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0)\n})\n\nexport const isContextItemVisible = (item: ContextItemSpec, audiences?: readonly string[]): boolean =>\n !audiences || !item.audiences || item.audiences.some((a) => audiences.includes(a))\n\nexport const formatContextBlock = (entries: readonly ContextEntry[]): string => {\n if (entries.length === 0) return ''\n const sources = entries\n .map(\n (entry) =>\n `<source path=${JSON.stringify(entry.path)} description=${JSON.stringify(entry.description)}>\\n${entry.markdown.trim()}\\n</source>`\n )\n .join('\\n')\n return `<infobase_context>\\n${sources}\\n</infobase_context>`\n}\n\nexport const buildDynamicContextBlock = (input: DynamicContextBlockInput): string => {\n const sections: string[] = [`Current UTC Date: ${input.currentTimeIso ?? new Date().toISOString()}`]\n\n if (input.userContext) {\n sections.push(`<user_state>\\n${JSON.stringify(input.userContext.state)}\\n</user_state>`)\n if (input.userContext.details && Object.keys(input.userContext.details).length > 0) {\n sections.push(`<user_records>\\n${JSON.stringify(input.userContext.details)}\\n</user_records>`)\n }\n }\n\n if (input.recalledMemories && input.recalledMemories.length > 0) {\n const items = input.recalledMemories\n .map(\n (m) =>\n `<memory scope=${JSON.stringify(m.scope)} chatId=${JSON.stringify(m.chatId)} role=${JSON.stringify(m.role)}>\\n${m.content.trim()}\\n</memory>`\n )\n .join('\\n')\n sections.push(`<recalled_memory>\\n${items}\\n</recalled_memory>`)\n }\n\n if (input.infobaseContextEntries && input.infobaseContextEntries.length > 0) {\n const block = formatContextBlock(input.infobaseContextEntries)\n if (block) sections.push(block)\n }\n\n if (input.stagedAttachmentSummaries && input.stagedAttachmentSummaries.length > 0) {\n sections.push(`<staged_attachments>\\n${input.stagedAttachmentSummaries.join('\\n').trim()}\\n</staged_attachments>`)\n }\n\n return sections.join('\\n\\n')\n}\n\nexport const PUBLIC_MESSAGE_FIELDS = [\n 'id',\n 'chatId',\n 'userId',\n 'role',\n 'content',\n 'parts',\n 'toolInvocations',\n 'attachments',\n 'tokenCount',\n 'cancelled',\n 'createdAt'\n] as const\n\nexport const RECALL_MESSAGE_FIELDS = ['id', 'chatId', 'role', 'content'] as const\n\nexport const mapFirestoreMessageDoc = (\n id: string,\n raw: Record<string, unknown>\n): ChatMessagePublic => {\n const createdRaw = raw.createdAt\n const createdAt =\n createdRaw instanceof Timestamp\n ? createdRaw.toDate()\n : createdRaw instanceof Date\n ? createdRaw\n : typeof createdRaw === 'string' || typeof createdRaw === 'number'\n ? new Date(createdRaw)\n : new Date()\n\n const role: ChatMessageRole =\n raw.role === 'assistant' || raw.role === 'system' || raw.role === 'tool' ? raw.role : 'user'\n const content = typeof raw.content === 'string' ? raw.content : ''\n const parts = Array.isArray(raw.parts) ? raw.parts : content ? [{ type: 'text', text: content }] : []\n\n return {\n id,\n chatId: typeof raw.chatId === 'string' ? raw.chatId : '',\n userId: typeof raw.userId === 'string' ? raw.userId : '',\n role,\n content,\n parts,\n ...(Array.isArray(raw.toolInvocations) ? { toolInvocations: raw.toolInvocations } : {}),\n ...(Array.isArray(raw.attachments) ? { attachments: raw.attachments as string[] } : {}),\n ...(typeof raw.tokenCount === 'number' ? { tokenCount: raw.tokenCount } : {}),\n ...(typeof raw.cancelled === 'boolean' ? { cancelled: raw.cancelled } : {}),\n createdAt\n }\n}\n\nexport const toModelMessageFromDoc = (doc: ChatMessagePublic): ModelMessage | undefined => {\n const text = doc.content.trim()\n if (!text) return undefined\n if (doc.role === 'assistant') {\n return { role: 'assistant', content: [{ type: 'text', text }] }\n }\n if (doc.role === 'user') {\n return { role: 'user', content: [{ type: 'text', text }] }\n }\n return undefined\n}\n\nexport const extractToolInvocations = (messages: readonly { content: unknown }[]): unknown[] => {\n const toolInvocations: unknown[] = []\n for (const m of messages) {\n if (!Array.isArray(m.content)) continue\n for (const part of m.content) {\n if (part && typeof part === 'object' && 'type' in part && (part.type === 'tool-call' || part.type === 'tool-result')) {\n toolInvocations.push(part)\n }\n }\n }\n return toolInvocations\n}\n\nexport const buildUIMessageResponse = (\n turn: ReturnType<typeof streamText>,\n chatId: string,\n generationId: string,\n completionPromise: Promise<void>,\n onDelta: (delta: string) => void\n): Response => {\n const baseRes = createUIMessageStreamResponse({ stream: toUIMessageStream({ stream: turn.stream }) })\n const headers = new Headers(baseRes.headers)\n headers.set('x-chat-id', chatId)\n headers.set('x-generation-id', generationId)\n\n const decoder = new TextDecoder()\n const [clientBranch, monitorBranch] = baseRes.body!.tee()\n\n void (async () => {\n const reader = monitorBranch.getReader()\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n for (const line of decoder.decode(value, { stream: true }).split('\\n')) {\n if (!line.startsWith('data: ')) continue\n try {\n const payload = JSON.parse(line.slice(6)) as { type?: string; delta?: string; textDelta?: string }\n if (payload.type === 'text-delta') onDelta(payload.delta ?? payload.textDelta ?? '')\n } catch {}\n }\n }\n } catch {\n } finally {\n reader.releaseLock()\n }\n })()\n\n const syncedClientStream = clientBranch.pipeThrough(\n new TransformStream<Uint8Array, Uint8Array>({\n async flush() {\n await completionPromise.catch(() => {})\n }\n })\n )\n\n return new Response(syncedClientStream, { status: baseRes.status, headers })\n}\n\nexport const buildCompletedTurnWriteBatch = (\n db: Firestore,\n opts: {\n chatDocRef: DocumentReference\n chatId: string\n userId: EntryId\n resolvedAgentId: string\n title: string\n selectedModel: string\n userMsgId: string\n assistantMsgId: string\n userCreatedAtMs: number\n finalUserText: string\n userPartsForStorage: unknown[]\n stagedRefs: FileRef[]\n finalAssistantText: string\n toolInvocations: unknown[]\n totalTokens?: number\n cancelled: boolean\n userVector: number[] | null\n assistantVector: number[] | null\n }\n) => {\n const messagesCol = opts.chatDocRef.collection('messages')\n const batch = db.batch()\n batch.set(messagesCol.doc(opts.userMsgId), {\n id: opts.userMsgId,\n chatId: opts.chatId,\n userId: opts.userId,\n role: 'user',\n content: opts.finalUserText,\n parts: opts.userPartsForStorage,\n ...(opts.stagedRefs.length > 0 ? { attachments: opts.stagedRefs } : {}),\n createdAt: Timestamp.fromMillis(opts.userCreatedAtMs),\n ...(opts.userVector ? { embedding: FieldValue.vector(opts.userVector) } : {})\n })\n\n batch.set(messagesCol.doc(opts.assistantMsgId), {\n id: opts.assistantMsgId,\n chatId: opts.chatId,\n userId: opts.userId,\n role: 'assistant',\n content: opts.finalAssistantText,\n parts: opts.finalAssistantText ? [{ type: 'text', text: opts.finalAssistantText }] : [],\n ...(opts.toolInvocations.length > 0 ? { toolInvocations: opts.toolInvocations } : {}),\n ...(opts.totalTokens !== undefined ? { tokenCount: opts.totalTokens } : {}),\n cancelled: opts.cancelled,\n createdAt: Timestamp.fromMillis(Math.max(opts.userCreatedAtMs + 1, Date.now())),\n ...(opts.assistantVector ? { embedding: FieldValue.vector(opts.assistantVector) } : {})\n })\n\n batch.set(\n opts.chatDocRef,\n {\n id: opts.chatId,\n userId: opts.userId,\n agentId: opts.resolvedAgentId,\n title: opts.title,\n model: opts.selectedModel,\n deleted: false,\n activeGenerationId: null,\n messageCount: FieldValue.increment(2),\n updatedAt: FieldValue.serverTimestamp()\n },\n { merge: true }\n )\n return batch\n}\n", "import { type ModelMessage, type streamText } from 'ai'\nimport { type DocumentReference } from 'firebase-admin/firestore'\nimport type { Context } from 'hono'\nimport type { z } from 'zod'\nimport type { AttachmentTypesMap, ProcessedAttachment } from '../attachments'\nimport { CORE_CONFIG, type AppEnv, type DbRole } from '../config'\nimport { entryId, type EntryId, type SelectModel } from '../db'\nimport type { FileRef, FileType } from '../files'\nimport { Core } from '../index'\nimport {\n saveChatBody,\n streamChatBody,\n type AgentConfig,\n type ChatMessagePublic,\n type ListChatMessagesOptions,\n type PersistTurnCompletionOpts,\n type RawAttachmentPart\n} from './schema'\nimport {\n buildCompletedTurnWriteBatch,\n buildUIMessageResponse,\n deriveTitle,\n extractMessageText,\n extractToolInvocations,\n extractTurnAttachmentParts,\n formatAttachmentLine,\n mapFirestoreMessageDoc,\n PUBLIC_MESSAGE_FIELDS\n} from './utils'\n\ninterface ActiveGenerationEntry {\n generationId: string\n controller: AbortController\n partialText: () => string\n completionPromise?: Promise<void>\n}\n\nconst activeGenerations = new Map<string, ActiveGenerationEntry>()\nconst genKey = (isDev: boolean, chatId: string): string => `${isDev ? 'dev' : 'prod'}:${chatId}`\n\nexport class ChatStreamEngine {\n readonly #core: Core\n readonly #agentRegistry: Map<string, AgentConfig>\n\n constructor(coreClient: Core, agentRegistry: Map<string, AgentConfig>) {\n this.#core = coreClient\n this.#agentRegistry = agentRegistry\n }\n\n #assertChatAccess = async (chatId: EntryId): Promise<void> => {\n const caller = this.#core.caller\n if (caller.role !== 'admin' && caller.userId !== CORE_CONFIG.auth.adminUserId) {\n const chatDoc = await this.#core.db.read('chat', chatId, false, {\n userId: caller.userId,\n userRole: caller.role\n })\n if (!chatDoc) this.#core.errors.httpError(404, `Chat not found: ${chatId}`, 'NOT_FOUND')\n }\n }\n\n enforceAgentAccess = async (c: Context<AppEnv>, agent: AgentConfig, scopeKey: string): Promise<void> => {\n if (agent.auth) {\n await this.#core.internals.context.authenticateRequest(c, agent.auth)\n }\n if (agent.rateLimit !== undefined) {\n this.#core.internals.context.applyRateLimit(c, agent.rateLimit, `${scopeKey}:${agent.name ?? 'agent'}`)\n }\n }\n\n stageAndScanAttachments = async (\n userId: EntryId,\n parts: RawAttachmentPart[],\n types?: AttachmentTypesMap\n ): Promise<{ staged: { ref: FileRef; filename: string }[]; attachments: ProcessedAttachment[] }> => {\n if (parts.length === 0) return { staged: [], attachments: [] }\n if (parts.length > CORE_CONFIG.limits.maxChatAttachments) {\n this.#core.errors.httpError(\n 400,\n `Too many attachments (max ${CORE_CONFIG.limits.maxChatAttachments})`,\n 'TOO_MANY_ATTACHMENTS'\n )\n }\n const staged = await Promise.all(\n parts.map(async (part) => {\n if (part.ref) {\n if (!this.#core.files.canAccess(part.ref, userId)) {\n this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n return { ref: part.ref, filename: part.filename }\n }\n if ((part.dataUrl?.length ?? 0) > 28 * 1024 * 1024) {\n this.#core.errors.httpError(413, 'Attachment exceeds 20MiB limit', 'PAYLOAD_TOO_LARGE')\n }\n const match = /^data:([^;,]+);base64,(.+)$/.exec(part.dataUrl ?? '')\n if (!match?.[1] || !match[2]) {\n return this.#core.errors.httpError(400, 'Invalid base64 data URL for attachment', 'INVALID_FILE')\n }\n const contentType = match[1] as FileType\n const bytes = new Uint8Array(Buffer.from(match[2], 'base64'))\n const { ref } = await this.#core.files.upload({ type: contentType, name: part.filename, bytes }, userId)\n return { ref, filename: part.filename }\n })\n )\n const { attachments } = await this.#core.attachments.process({ refs: staged.map((s) => s.ref) }, { types })\n return { staged, attachments }\n }\n\n saveChat = async ({\n userId = this.#core.userId,\n input\n }: {\n userId?: EntryId\n input: z.infer<typeof saveChatBody>\n }): Promise<SelectModel<'chat'>> => {\n const targetId = input.id ?? input.chatId\n const existing = targetId ? await this.#core.db.read('chat', targetId, true, { bypassRbac: true }) : undefined\n if (existing && userId !== CORE_CONFIG.auth.adminUserId && existing.userId !== userId) {\n return this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n const defaultAgentId = this.#agentRegistry.keys().next().value ?? 'chat'\n if (existing && input.agentId && input.agentId !== existing.agentId) {\n return this.#core.errors.httpError(400, 'Cannot switch agentId on an existing chat', 'AGENT_IMMUTABLE')\n }\n const title = input.title ?? existing?.title ?? 'New Chat'\n const agentId = existing ? existing.agentId : (input.agentId ?? defaultAgentId)\n if (!this.#agentRegistry.has(agentId)) {\n return this.#core.errors.httpError(404, `Unknown agent: ${agentId}`, 'NOT_FOUND')\n }\n const model = input.model ?? existing?.model ?? CORE_CONFIG.models.vertex\n\n if (existing && targetId) {\n const patch = { title, model, ...(input.summary !== undefined ? { summary: input.summary } : {}), deleted: false }\n await this.#core.db.update('chat', targetId, patch, { bypassRbac: true })\n return { ...existing, ...patch, updatedAt: new Date() }\n }\n\n return this.#core.db.create(\n 'chat',\n {\n ...(targetId ? { id: targetId } : {}),\n userId,\n agentId,\n title,\n model,\n messageCount: 0,\n summary: input.summary ?? null,\n activeGenerationId: null\n },\n { bypassRbac: true }\n )\n }\n\n messages = async (chatId: EntryId, opts?: ListChatMessagesOptions): Promise<ChatMessagePublic[]> => {\n await this.#assertChatAccess(chatId)\n const limit = Math.min(\n Math.max(opts?.limit ?? CORE_CONFIG.limits.chatMessagesLimit, 1),\n CORE_CONFIG.limits.defaultListLimit\n )\n const db = this.#core.db.firestore()\n const messagesCol = db.collection('chat').doc(chatId).collection('messages')\n\n await this.#core.internals.resilience.acquireLimit('firestore')\n let query = messagesCol.select(...PUBLIC_MESSAGE_FIELDS).orderBy('createdAt', 'desc').limit(limit)\n if (opts?.before) {\n const beforeSnap = await messagesCol.doc(opts.before).get()\n if (beforeSnap.exists) query = query.startAfter(beforeSnap)\n }\n const snap = await query.get()\n return snap.docs.map((d) => mapFirestoreMessageDoc(d.id, d.data() ?? {})).reverse()\n }\n\n cancel = async (chatId: EntryId): Promise<{ chatId: string; cancelled: true }> => {\n await this.#assertChatAccess(chatId)\n const key = genKey(Boolean(this.#core.env.isDev), chatId)\n const localGen = activeGenerations.get(key)\n\n await this.#core.db.update('chat', chatId, { activeGenerationId: null }, { bypassRbac: true }).catch(() => {})\n\n if (localGen) {\n localGen.controller.abort(new Error('Cancelled by user'))\n if (localGen.completionPromise) {\n await Promise.race([localGen.completionPromise, new Promise((r) => setTimeout(r, 2_500))])\n }\n }\n\n return { chatId, cancelled: true }\n }\n\n #resolveStreamTurnTarget = async (c: Context<AppEnv>, userId: EntryId, body: z.infer<typeof streamChatBody>) => {\n const paramValue = c.req.param('chatId')\n const paramIsAgent = Boolean(\n paramValue && this.#agentRegistry.has(paramValue) && !body.agentId && !body.chatId && !body.id\n )\n const defaultAgentId = this.#agentRegistry.keys().next().value ?? 'chat'\n const db = this.#core.db.firestore()\n const candidateChatId = !paramIsAgent ? (paramValue ?? body.chatId ?? body.id) : (body.chatId ?? body.id)\n const chatId =\n candidateChatId && entryId.safeParse(candidateChatId).success\n ? candidateChatId\n : db.collection('chat').doc().id\n\n const existing = await this.#core.db.read('chat', chatId, true, { bypassRbac: true })\n if (existing && userId !== CORE_CONFIG.auth.adminUserId && existing.userId !== userId) {\n this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n\n const requestedAgentId = body.agentId ?? (paramIsAgent ? paramValue : undefined)\n if (existing && requestedAgentId && requestedAgentId !== existing.agentId) {\n this.#core.errors.httpError(400, 'Cannot switch agentId on an existing chat', 'AGENT_IMMUTABLE')\n }\n const resolvedAgentId = existing ? existing.agentId : (requestedAgentId ?? defaultAgentId)\n const agent = this.#agentRegistry.get(resolvedAgentId)\n if (!agent) return this.#core.errors.httpError(404, `Unknown agent: ${resolvedAgentId}`, 'NOT_FOUND')\n await this.enforceAgentAccess(c, agent, 'chat.stream')\n\n const attachmentParts = extractTurnAttachmentParts(body.message)\n const rawUserText = extractMessageText(body.message)\n if (!rawUserText && attachmentParts.length === 0) {\n this.#core.errors.httpError(400, 'message must contain non-empty text or attachments', 'VALIDATION_ERROR')\n }\n\n const key = genKey(Boolean(this.#core.env.isDev), chatId)\n const activeTimeoutMs = CORE_CONFIG.cloudRun.http.timeoutSeconds * 1000\n const hasFreshRemoteLock =\n Boolean(existing?.activeGenerationId) &&\n Date.now() - (existing?.updatedAt instanceof Date ? existing.updatedAt.getTime() : 0) < activeTimeoutMs\n\n if (activeGenerations.has(key) || hasFreshRemoteLock) {\n this.#core.errors.httpError(409, 'A generation is already in progress for this chat', 'GENERATION_IN_PROGRESS')\n }\n\n return { chatId, existing, resolvedAgentId, agent, attachmentParts, rawUserText, key }\n }\n\n #persistTurnCompletion = async (opts: PersistTurnCompletionOpts): Promise<void> => {\n let assistantText = ''\n let totalTokens: number | undefined\n const toolInvocations: unknown[] = []\n try {\n try {\n const [text, response, usage] = await Promise.all([opts.turn.text, opts.turn.response, opts.turn.usage])\n assistantText = text || opts.getAccumulatedText()\n totalTokens = usage?.totalTokens ?? ((usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0) || undefined)\n toolInvocations.push(...extractToolInvocations(response.messages))\n } catch {\n assistantText = opts.getAccumulatedText()\n }\n\n const finalAssistantText = assistantText.trim()\n const [userVector, assistantVector] = await Promise.all([\n opts.userVecPromise,\n this.#core.ai.embed(finalAssistantText).catch(() => null)\n ])\n\n const batch = buildCompletedTurnWriteBatch(this.#core.db.firestore(), {\n ...opts,\n finalAssistantText,\n toolInvocations,\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n cancelled: opts.signal.aborted,\n userVector,\n assistantVector\n })\n\n await this.#core.internals.resilience.acquireLimit('firestore')\n await batch.commit().catch((err) => console.error('[chat] failed to commit turn batch:', err))\n } finally {\n try {\n opts.unsubCancelWatch?.()\n } catch {}\n activeGenerations.delete(opts.key)\n }\n }\n\n #upsertChatTurnLock = async (\n existing: SelectModel<'chat'> | undefined,\n chatDocRef: DocumentReference,\n chatId: string,\n userId: EntryId,\n resolvedAgentId: string,\n title: string,\n selectedModel: string,\n generationId: string,\n generationController: AbortController\n ): Promise<() => void> => {\n if (existing) {\n await this.#core.db.update(\n 'chat',\n chatId,\n { title, agentId: resolvedAgentId, model: selectedModel, activeGenerationId: generationId, deleted: false },\n { bypassRbac: true }\n )\n } else {\n await this.#core.db.create(\n 'chat',\n {\n id: chatId,\n userId,\n agentId: resolvedAgentId,\n title,\n model: selectedModel,\n messageCount: 0,\n summary: null,\n activeGenerationId: generationId\n },\n { bypassRbac: true }\n )\n }\n\n return chatDocRef.onSnapshot(\n (snap) => {\n if (snap.data()?.activeGenerationId !== generationId && !generationController.signal.aborted) {\n generationController.abort(new Error('Generation cancelled via Firestore state'))\n }\n },\n () => {}\n )\n }\n\n startChatStreamTurn = async (opts: {\n userId: EntryId\n role: DbRole\n agent: AgentConfig\n attachmentParts: RawAttachmentPart[]\n rawUserText: string\n signal: AbortSignal\n chatId?: string\n messageCount?: number\n selectedModel?: string\n priorMessages?: ModelMessage[]\n }) => {\n const { userId, role, agent, attachmentParts, rawUserText, signal, chatId, messageCount, selectedModel, priorMessages } =\n opts\n const [{ staged, attachments }, hybrid] = await Promise.all([\n this.stageAndScanAttachments(userId, attachmentParts, agent.attachmentTypes ?? {}),\n this.#core.chat.retrieveContext({\n userId,\n ...(chatId ? { chatId } : {}),\n ...(messageCount !== undefined ? { messageCount } : {}),\n prompt: rawUserText,\n useContext: agent.useContext !== false,\n agent,\n role,\n abortSignal: signal\n })\n ])\n\n const stagedAttachmentSummaries = attachments.map((item, idx) =>\n formatAttachmentLine(staged[idx]?.filename ?? 'file', item).trim()\n )\n const userCreatedAtMs = Date.now()\n const messagesForTurn = priorMessages\n ? [\n ...priorMessages,\n ...(stagedAttachmentSummaries.length > 0\n ? [{ role: 'user' as const, content: [{ type: 'text' as const, text: stagedAttachmentSummaries.join('\\n\\n') }] }]\n : [])\n ].slice(-CORE_CONFIG.limits.chatMessagesLimit)\n : [\n ...hybrid.slidingWindowMessages,\n {\n role: 'user' as const,\n content: [{ type: 'text' as const, text: [rawUserText, ...stagedAttachmentSummaries].filter(Boolean).join('\\n\\n') || 'Attached files.' }]\n }\n ]\n\n const turn = await this.#core.chat.stream(agent, messagesForTurn, userId, {\n ...(selectedModel ? { modelOverride: selectedModel } : {}),\n ...(chatId ? { chatId } : {}),\n abortSignal: signal,\n core: new Core({ env: this.#core.env, userId, role }),\n dynamicContext: {\n currentTimeIso: new Date(userCreatedAtMs).toISOString(),\n recalledMemories: hybrid.recalledMemories,\n infobaseContextEntries: hybrid.infobaseContextEntries,\n stagedAttachmentSummaries,\n userContext: hybrid.userContext\n }\n })\n return { turn, stagedRefs: staged.map((s) => s.ref), stagedAttachmentSummaries, userCreatedAtMs }\n }\n\n streamChatSse = async ({\n c,\n userId = this.#core.userId,\n input\n }: {\n c: Context<AppEnv>\n userId?: EntryId\n input?: z.infer<typeof streamChatBody>\n }): Promise<Response> => {\n const parsedBody = streamChatBody.safeParse(input ?? (await c.req.json().catch(() => ({}))))\n if (!parsedBody.success) {\n return this.#core.errors.httpError(\n 400,\n parsedBody.error.issues.map((i) => `${i.path.join('.') || 'input'}: ${i.message}`).join('; '),\n 'VALIDATION_ERROR'\n )\n }\n const body = parsedBody.data\n const { chatId, existing, resolvedAgentId, agent, attachmentParts, rawUserText, key } =\n await this.#resolveStreamTurnTarget(c, userId, body)\n\n const generationId = `gen_${crypto.randomUUID().replace(/-/g, '').slice(0, 20)}`\n const generationController = new AbortController()\n let accumulatedText = ''\n const activeEntry: ActiveGenerationEntry = {\n generationId,\n controller: generationController,\n partialText: () => accumulatedText\n }\n activeGenerations.set(key, activeEntry)\n\n const title = body.title ?? existing?.title ?? deriveTitle(body.message)\n const selectedModel = body.model ?? existing?.model ?? agent.model ?? CORE_CONFIG.models.vertex\n const chatDocRef = this.#core.db.firestore().collection('chat').doc(chatId)\n let unsubCancelWatch: (() => void) | undefined\n\n try {\n unsubCancelWatch = await this.#upsertChatTurnLock(\n existing,\n chatDocRef,\n chatId,\n userId,\n resolvedAgentId,\n title,\n selectedModel,\n generationId,\n generationController\n )\n const role = this.#core.internals.auth.resolveUserRole(userId, c.get('userRole'))\n const { turn, stagedRefs, stagedAttachmentSummaries, userCreatedAtMs } = await this.startChatStreamTurn({\n userId,\n role,\n chatId,\n messageCount: existing?.messageCount ?? 0,\n agent,\n selectedModel,\n attachmentParts,\n rawUserText,\n signal: generationController.signal\n })\n\n const finalUserText = rawUserText || stagedAttachmentSummaries.join('\\n')\n const msgCol = chatDocRef.collection('messages')\n const userMsgId = body.message.id && entryId.safeParse(body.message.id).success ? body.message.id : msgCol.doc().id\n const userPartsForStorage = body.message.parts?.length ? body.message.parts : [{ type: 'text', text: rawUserText }]\n const completionPromise = this.#persistTurnCompletion({\n turn,\n getAccumulatedText: () => accumulatedText,\n signal: generationController.signal,\n userVecPromise: this.#core.ai.embed(finalUserText).catch(() => null),\n chatDocRef,\n chatId,\n userId,\n resolvedAgentId,\n title,\n selectedModel,\n userMsgId,\n assistantMsgId: msgCol.doc().id,\n userCreatedAtMs,\n finalUserText,\n userPartsForStorage,\n stagedRefs,\n unsubCancelWatch,\n key\n })\n activeEntry.completionPromise = completionPromise\n return buildUIMessageResponse(turn, chatId, generationId, completionPromise, (d) => {\n accumulatedText += d\n })\n } catch (err) {\n try {\n unsubCancelWatch?.()\n } catch {}\n activeGenerations.delete(key)\n await this.#core.db.update('chat', chatId, { activeGenerationId: null }, { bypassRbac: true }).catch(() => {})\n throw err\n }\n }\n}\n", "import { createMcpHandler, McpServer } from '@modelcontextprotocol/server'\nimport type { ModelMessage, streamText } from 'ai'\nimport type { Context } from 'hono'\nimport type { z } from 'zod'\nimport { CORE_CONFIG, type AppEnv } from '../config'\nimport type { EntryId } from '../db'\nimport { core } from '../index'\nimport {\n listChatMessagesQuery,\n openaiCompletionsBody,\n saveChatBody,\n streamChatBody,\n type RawAttachmentPart,\n type WorkflowToolSpec\n} from './schema'\nimport { extractLatestUserPrompt, formatUsage, sanitizeToolInputSchema } from './utils'\n\nconst listOpenaiModelsService = async () => {\n const agents = core.internals.registry.getRegisteredAgents()\n return {\n object: 'list',\n data: Object.keys(agents).map((id) => ({\n id,\n object: 'model',\n created: Math.floor(Date.now() / 1000),\n owned_by: CORE_CONFIG.appName\n }))\n }\n}\n\nconst parseOpenaiMessages = (\n messages: z.infer<typeof openaiCompletionsBody>['messages']\n): { parts: RawAttachmentPart[]; modelMessages: ModelMessage[] } => {\n const parts: RawAttachmentPart[] = []\n const modelMessages: ModelMessage[] = []\n for (const message of messages) {\n if (message.role !== 'user' && message.role !== 'assistant') continue\n const text =\n typeof message.content === 'string'\n ? message.content\n : (message.content ?? [])\n .filter((p) => p.type === 'text')\n .map((p) => p.text ?? '')\n .join('\\n\\n')\n if (message.role === 'assistant' && text.trim()) {\n modelMessages.push({ role: 'assistant', content: [{ type: 'text', text }] })\n }\n if (message.role !== 'user') continue\n for (const p of Array.isArray(message.content) ? message.content : []) {\n const dataUrl = p.image_url?.url ?? p.file?.file_data\n if (dataUrl?.startsWith('data:')) parts.push({ dataUrl, filename: p.file?.filename ?? 'file' })\n }\n if (text.trim()) modelMessages.push({ role: 'user', content: [{ type: 'text', text }] })\n }\n return { parts, modelMessages }\n}\n\nconst createOpenaiSseResponse = (\n turn: ReturnType<typeof streamText>,\n id: string,\n created: number,\n model: string,\n includeUsage: boolean\n): Response => {\n const encoder = new TextEncoder()\n const stream = new ReadableStream({\n async start(controller) {\n const send = (payload: unknown) => controller.enqueue(encoder.encode(`data: ${JSON.stringify(payload)}\\n\\n`))\n const sendChunk = (choices: unknown[], extra?: Record<string, unknown>) =>\n send({ id, object: 'chat.completion.chunk', created, model, choices, ...extra })\n\n sendChunk([{ index: 0, delta: { role: 'assistant' }, finish_reason: null }])\n try {\n for await (const delta of turn.textStream) {\n if (delta) sendChunk([{ index: 0, delta: { content: delta }, finish_reason: null }])\n }\n sendChunk([{ index: 0, delta: {}, finish_reason: 'stop' }])\n if (includeUsage) sendChunk([], { usage: formatUsage(await turn.usage) })\n } catch (error) {\n console.error('[openai] stream failed:', error)\n send({ error: { message: 'The agent failed to produce a reply. Please retry.' } })\n }\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'))\n controller.close()\n }\n })\n return new Response(stream, {\n headers: { 'content-type': 'text/event-stream; charset=utf-8', 'cache-control': 'no-cache' }\n })\n}\n\nconst openaiCompletionsService = async ({\n c,\n userId,\n input\n}: {\n c: Context<AppEnv>\n userId: EntryId\n input?: z.infer<typeof openaiCompletionsBody>\n}) => {\n const body = input ?? openaiCompletionsBody.parse(await c.req.json().catch(() => ({})))\n const agents = core.internals.registry.getRegisteredAgents()\n const entries = Object.entries(agents)\n if (entries.length === 0) return core.errors.httpError(404, 'No registered agents', 'NOT_FOUND')\n const [defaultModel, defaultAgent] = entries[0]!\n const modelKey = body.model && body.model in agents ? body.model : defaultModel\n const agent = agents[modelKey] ?? defaultAgent\n const model = agent.name ?? modelKey\n\n await core.internals.context.enforceAgentAccess(c, agent, 'openai.completions')\n\n const { parts, modelMessages } = parseOpenaiMessages(body.messages)\n if (modelMessages.length === 0 && parts.length === 0) {\n return core.errors.httpError(400, 'No supported messages', 'VALIDATION_ERROR')\n }\n\n const latestPrompt = extractLatestUserPrompt(modelMessages)\n const role = core.internals.auth.resolveUserRole(userId, c.get('userRole'))\n const { turn, userCreatedAtMs } = await core.internals.context.startChatStreamTurn({\n userId,\n role,\n agent,\n attachmentParts: parts,\n rawUserText: latestPrompt,\n signal: c.req.raw.signal,\n priorMessages: modelMessages\n })\n const id = `chatcmpl-${crypto.randomUUID().replace(/-/g, '').slice(0, 24)}`\n const created = Math.floor(userCreatedAtMs / 1000)\n\n if (!body.stream) {\n const [text, usage] = await Promise.all([turn.text, turn.usage])\n return {\n id,\n object: 'chat.completion',\n created,\n model,\n choices: [{ index: 0, message: { role: 'assistant', content: text }, finish_reason: 'stop' }],\n usage: formatUsage(usage)\n }\n }\n\n return createOpenaiSseResponse(turn, id, created, model, Boolean(body.stream_options?.include_usage))\n}\n\nexport const mcpRoute = async (\n request: Request,\n userId: EntryId,\n mcpTools: Map<string, WorkflowToolSpec>\n): Promise<Response> => {\n const role = core.internals.auth.resolveUserRole(userId)\n const server = new McpServer({ name: CORE_CONFIG.appName, version: '1.0.0' })\n for (const [name, toolSpec] of mcpTools) {\n if (toolSpec.mcp !== true) continue\n server.registerTool(\n name,\n {\n description: (toolSpec.description || name).slice(0, 1024),\n inputSchema: sanitizeToolInputSchema(toolSpec.input)\n },\n async (input) => {\n try {\n const step = core.internals.workflows.createStepRunner('workflow')\n const result = await core.internals.context.run({ env: core.env, userId, role, step }, () =>\n toolSpec.execute(input, userId)\n )\n return { content: [{ type: 'text' as const, text: JSON.stringify(result) }] }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(core.errors.buildErrorBody(msg, 502, 'WORKFLOW_ERROR'))\n }\n ],\n isError: true\n }\n }\n }\n )\n }\n return createMcpHandler(() => server).fetch(request)\n}\n\nexport const coreChatRoutes = {\n 'chat.list': {\n handler: async ({ c, userId }: { c: Context<AppEnv>; userId: EntryId }) =>\n core.db.list(\n 'chat',\n {\n userId,\n ...(c?.req.query('full') === 'true'\n ? {}\n : {\n select: [\n 'id',\n 'userId',\n 'agentId',\n 'title',\n 'model',\n 'messageCount',\n 'summary',\n 'activeGenerationId',\n 'deleted',\n 'createdAt',\n 'updatedAt'\n ]\n })\n },\n { bypassRbac: true }\n )\n },\n 'chat.get': {\n handler: async ({ c }: { c: Context<AppEnv> }) => {\n const chat = await core.db.read('chat', c.req.param('chatId') ?? '', false)\n return chat ?? core.errors.httpError(404, 'Chat not found', 'NOT_FOUND')\n }\n },\n 'chat.messages': {\n handler: async ({ c }: { c: Context<AppEnv> }) => {\n const chatId = c.req.param('chatId') ?? ''\n const parsedQuery = listChatMessagesQuery.parse(c.req.query())\n return core.chat.messages(chatId, { limit: parsedQuery.limit, before: parsedQuery.before })\n }\n },\n 'chat.save': {\n input: saveChatBody,\n handler: ({ userId, input }: { userId: EntryId; input: z.infer<typeof saveChatBody> }) =>\n core.internals.context.saveChat({ userId, input })\n },\n 'chat.delete': {\n handler: async ({ c }: { c: Context<AppEnv> }) => {\n const chatId = c.req.param('chatId') ?? ''\n await core.db.delete('chat', chatId)\n return { id: chatId, deleted: true }\n }\n },\n 'chat.stream': {\n input: streamChatBody,\n handler: ({\n c,\n userId,\n input\n }: {\n c: Context<AppEnv>\n userId: EntryId\n input?: z.infer<typeof streamChatBody>\n }) => core.internals.context.streamChatSse({ c, userId, input })\n },\n 'chat.cancel': {\n handler: ({ c }: { c: Context<AppEnv> }) => {\n const chatId = c.req.param('chatId') ?? ''\n return core.chat.cancel(chatId)\n }\n },\n 'openai.models': {\n handler: listOpenaiModelsService\n },\n 'openai.completions': {\n input: openaiCompletionsBody,\n handler: openaiCompletionsService\n }\n}\n", "import { z } from 'zod'\nimport type {\n AuthEmailPurpose,\n AuthEmailVariables,\n AuthFlowConfigSpec,\n AuthFlowEmailHook,\n EmailProvider,\n EmailsConfig,\n TransactionalEmailPayload\n} from '../config'\nimport { entryId, fileRef, type EntryId } from '../db'\n\nexport type {\n AuthEmailPurpose,\n AuthEmailVariables,\n AuthFlowConfigSpec,\n AuthFlowEmailHook,\n EmailProvider,\n EmailsConfig,\n TransactionalEmailPayload\n}\n\nexport const emailLogStatusSchema = z.enum([\n 'queued',\n 'sent',\n 'delivered',\n 'opened',\n 'clicked',\n 'bounced',\n 'complained',\n 'failed',\n 'suppressed'\n])\nexport type EmailLogStatus = z.infer<typeof emailLogStatusSchema>\n\nexport interface EmailTemplateProviderSpec<V = Record<string, unknown>> {\n sendgrid?: {\n templateId: string\n }\n resend?: {\n templateId?: string\n subject?: string | ((vars: V) => string)\n html?: string | ((vars: V) => string)\n text?: string | ((vars: V) => string)\n }\n}\n\nexport interface EmailTemplateDefinition<S extends z.ZodTypeAny = z.ZodType<Record<string, unknown>>> {\n id?: string\n description?: string\n subject?: string | ((vars: z.infer<S>) => string)\n html?: string | ((vars: z.infer<S>) => string)\n text?: string | ((vars: z.infer<S>) => string)\n fromEmail?: string\n fromName?: string\n replyTo?: string\n category?: string\n variables?: S\n providers?: EmailTemplateProviderSpec<z.infer<S>>\n onBeforeSend?: (vars: z.infer<S>, recipient: string) => Promise<z.infer<S> | false>\n}\n\nexport type EmailTemplatesMap = Record<string, EmailTemplateDefinition<any>>\n\nconst registeredEmailTemplates: EmailTemplatesMap = {}\n\nexport const registerEmailTemplates = (templates?: EmailTemplatesMap, reset = false): void => {\n if (reset) {\n for (const k of Object.keys(registeredEmailTemplates)) delete registeredEmailTemplates[k]\n }\n if (!templates) return\n for (const [k, def] of Object.entries(templates)) {\n registeredEmailTemplates[k] = { ...def, id: def.id ?? k }\n }\n}\n\nexport const clearEmailTemplates = (): void => {\n for (const k of Object.keys(registeredEmailTemplates)) delete registeredEmailTemplates[k]\n}\n\nexport const defineEmailTemplates = <T extends EmailTemplatesMap>(templates: T): T => {\n const normalized = Object.fromEntries(\n Object.entries(templates).map(([k, def]) => [k, { ...def, id: def.id ?? k }])\n ) as T\n registerEmailTemplates(normalized, false)\n return normalized\n}\n\nexport const getEmailTemplate = (id: string): EmailTemplateDefinition<any> | undefined =>\n registeredEmailTemplates[id]\n\nexport const getRegisteredEmailTemplates = (): EmailTemplatesMap => registeredEmailTemplates\n\nexport const emailAttachmentInputSchema = z\n .object({\n filename: z.string().min(1),\n fileRef: fileRef.optional(),\n contentBase64: z.string().optional(),\n contentType: z.string().optional()\n })\n .refine((v) => Boolean(v.fileRef || v.contentBase64), {\n message: 'Attachment requires either fileRef or contentBase64'\n })\nexport type EmailAttachmentInput = z.infer<typeof emailAttachmentInputSchema>\n\nexport const sendEmailInputSchema = z\n .object({\n to: z.union([z.string().email(), z.array(z.string().email()).min(1).max(50)]),\n template: z.string().optional(),\n providerTemplateId: z.string().optional(),\n variables: z.record(z.string(), z.unknown()).default({}),\n subject: z.string().max(300).optional(),\n html: z.string().optional(),\n text: z.string().optional(),\n fromEmail: z.string().email().optional(),\n fromName: z.string().max(120).optional(),\n replyTo: z.string().email().optional(),\n cc: z.array(z.string().email()).optional(),\n bcc: z.array(z.string().email()).optional(),\n attachments: z.array(emailAttachmentInputSchema).max(10).optional(),\n tags: z.record(z.string(), z.string()).optional(),\n idempotencyKey: z.string().max(200).optional(),\n purpose: z.string().optional()\n })\n .refine((v) => Boolean(v.template || v.providerTemplateId || v.html || v.text), {\n message: 'Provide a template alias, providerTemplateId, or html/text body'\n })\n\nexport type SendEmailInput<T = Record<string, unknown>> = Omit<z.input<typeof sendEmailInputSchema>, 'variables'> & {\n variables?: T\n}\n\nexport const sendBatchEmailInputSchema = z.object({\n emails: z.array(sendEmailInputSchema).min(1).max(100)\n})\nexport type SendBatchEmailInput = z.input<typeof sendBatchEmailInputSchema>\n\nexport const emailLogsQuerySchema = z.object({\n to: z.string().optional(),\n template: z.string().optional(),\n purpose: z.string().optional(),\n status: emailLogStatusSchema.optional(),\n userId: entryId.optional(),\n limit: z.coerce.number().int().min(1).max(500).optional(),\n cursor: z.string().optional()\n})\nexport type EmailLogsQuery = z.infer<typeof emailLogsQuerySchema>\n\nexport const emailWebhookParamsSchema = z.object({\n provider: z.enum(['sendgrid', 'resend'])\n})\nexport type EmailWebhookParams = z.infer<typeof emailWebhookParamsSchema>\n\nexport const sendEmailResultSchema = z.object({\n emailId: entryId,\n externalMessageId: z.string().optional(),\n status: emailLogStatusSchema,\n provider: z.enum(['sendgrid', 'resend', 'firebase', 'dev']),\n deduplicated: z.boolean().optional()\n})\nexport type SendEmailResult = z.infer<typeof sendEmailResultSchema>\n\nexport const sendBatchEmailResultSchema = z.object({\n total: z.number().int().nonnegative(),\n sent: z.number().int().nonnegative(),\n suppressed: z.number().int().nonnegative(),\n failed: z.number().int().nonnegative(),\n results: z.array(sendEmailResultSchema)\n})\nexport type SendBatchEmailResult = z.infer<typeof sendBatchEmailResultSchema>\n\nexport interface EmailCallOptions {\n provider?: 'sendgrid' | 'resend'\n userId?: EntryId\n}\n\nexport interface ResolvedAttachment {\n filename: string\n contentBase64: string\n contentType: string\n}\n\nexport interface NormalizedEmailRequest {\n emailId: EntryId\n to: string[]\n fromEmail: string\n fromName: string\n replyTo?: string\n cc?: string[]\n bcc?: string[]\n subject?: string\n html?: string\n text?: string\n template?: string\n providerTemplateId?: string\n variables: Record<string, unknown>\n attachments: ResolvedAttachment[]\n tags?: Record<string, string>\n idempotencyKey?: string\n purpose?: string\n userId?: EntryId\n}\n\nexport interface ResendWebhookEvent {\n type:\n | 'email.sent'\n | 'email.delivered'\n | 'email.delivery_delayed'\n | 'email.complained'\n | 'email.bounced'\n | 'email.opened'\n | 'email.clicked'\n | (string & {})\n created_at?: string\n data: {\n email_id?: string\n to?: string[] | string\n from?: string\n subject?: string\n bounce?: { message?: string; type?: string }\n }\n}\n\nexport interface SendGridWebhookEvent {\n event:\n | 'processed'\n | 'delivered'\n | 'open'\n | 'click'\n | 'bounce'\n | 'dropped'\n | 'spamreport'\n | (string & {})\n email?: string\n sg_message_id?: string\n timestamp?: number\n reason?: string\n type?: string\n}\n", "import { createHash, createHmac, timingSafeEqual } from 'node:crypto'\nimport type { z } from 'zod'\nimport type {\n AuthEmailVariables,\n EmailLogStatus,\n EmailProvider,\n EmailsConfig,\n EmailTemplateDefinition,\n NormalizedEmailRequest,\n ResolvedAttachment,\n ResendWebhookEvent,\n SendBatchEmailResult,\n SendEmailResult,\n SendGridWebhookEvent,\n TransactionalEmailPayload,\n sendEmailInputSchema\n} from './schema'\n\nexport const normalizeEmail = (email: string): string => email.trim().toLowerCase()\n\nexport const suppressionDocId = (email: string): string =>\n createHash('sha256').update(normalizeEmail(email)).digest('hex')\n\nexport const idempotencyEmailDocId = (idempotencyKey: string): string =>\n `em_${createHash('sha256').update(idempotencyKey.trim()).digest('hex').slice(0, 40)}`\n\nexport const summarizeBatchEmailResults = (results: SendEmailResult[]): SendBatchEmailResult => ({\n total: results.length,\n sent: results.filter((r) => r.status === 'sent').length,\n suppressed: results.filter((r) => r.status === 'suppressed').length,\n failed: results.filter((r) => r.status === 'failed').length,\n results\n})\n\nexport const buildNormalizedEmailRequest = (\n emailId: string,\n toList: string[],\n parsed: z.infer<typeof sendEmailInputSchema>,\n tmpl: EmailTemplateDefinition<any> | undefined,\n provider: EmailProvider | 'dev',\n vars: Record<string, unknown>,\n emailsCfg: EmailsConfig,\n attachments: ResolvedAttachment[],\n userId?: string\n): NormalizedEmailRequest => {\n const f = resolveTemplateFields(parsed, tmpl, provider, vars, emailsCfg)\n return {\n emailId,\n to: toList,\n fromEmail: f.fromEmail,\n fromName: f.fromName,\n ...(f.replyTo ? { replyTo: f.replyTo } : {}),\n ...(parsed.cc?.length ? { cc: parsed.cc.map(normalizeEmail) } : {}),\n ...(parsed.bcc?.length ? { bcc: parsed.bcc.map(normalizeEmail) } : {}),\n ...(f.subject ? { subject: f.subject } : {}),\n ...(f.html ? { html: f.html } : {}),\n ...(f.text ? { text: f.text } : {}),\n ...(parsed.template ? { template: parsed.template } : {}),\n ...(f.providerTemplateId ? { providerTemplateId: f.providerTemplateId } : {}),\n variables: vars,\n attachments,\n ...(parsed.tags ? { tags: parsed.tags } : {}),\n ...(parsed.idempotencyKey ? { idempotencyKey: parsed.idempotencyKey } : {}),\n ...(parsed.purpose ? { purpose: parsed.purpose } : {}),\n ...(userId ? { userId } : {})\n }\n}\n\nconst constantTimeEqual = (a: string, b: string): boolean => {\n if (!a || !b) return false\n const bufA = createHash('sha256').update(a).digest()\n const bufB = createHash('sha256').update(b).digest()\n return timingSafeEqual(bufA, bufB)\n}\n\nconst getHeader = (headers: Record<string, string | undefined>, name: string): string | undefined => {\n const lower = name.toLowerCase()\n for (const [k, v] of Object.entries(headers)) {\n if (k.toLowerCase() === lower && v) return v.trim()\n }\n return undefined\n}\n\nexport const RESEND_STATUS_MAP: Record<string, EmailLogStatus> = {\n 'email.sent': 'sent',\n 'email.delivered': 'delivered',\n 'email.opened': 'opened',\n 'email.clicked': 'clicked',\n 'email.bounced': 'bounced',\n 'email.complained': 'complained'\n}\n\nexport const SENDGRID_STATUS_MAP: Record<string, EmailLogStatus> = {\n processed: 'sent',\n delivered: 'delivered',\n open: 'opened',\n click: 'clicked',\n bounce: 'bounced',\n dropped: 'bounced',\n spamreport: 'complained'\n}\n\nexport const resolveTemplateFields = (\n parsed: z.infer<typeof sendEmailInputSchema>,\n tmpl: EmailTemplateDefinition<any> | undefined,\n provider: EmailProvider | 'dev',\n vars: Record<string, unknown>,\n emailsCfg: EmailsConfig\n) => {\n const rSpec = tmpl?.providers?.resend\n const sgSpec = tmpl?.providers?.sendgrid\n const providerTemplateId =\n parsed.providerTemplateId ??\n (provider === 'sendgrid'\n ? sgSpec?.templateId\n : provider === 'resend'\n ? rSpec?.templateId\n : rSpec?.templateId ?? sgSpec?.templateId)\n\n const evalField = (val: string | ((v: Record<string, unknown>) => string) | undefined): string | undefined =>\n typeof val === 'function' ? val(vars) : val\n\n const subject = parsed.subject ?? evalField(rSpec?.subject) ?? evalField(tmpl?.subject)\n const html = parsed.html ?? evalField(rSpec?.html) ?? evalField(tmpl?.html)\n const text = parsed.text ?? evalField(rSpec?.text) ?? evalField(tmpl?.text)\n const fromEmail = parsed.fromEmail ?? tmpl?.fromEmail ?? emailsCfg.fromEmail\n const fromName = parsed.fromName ?? tmpl?.fromName ?? emailsCfg.fromName\n const replyTo = parsed.replyTo ?? tmpl?.replyTo ?? emailsCfg.replyTo\n\n return { providerTemplateId, subject, html, text, fromEmail, fromName, replyTo }\n}\n\nexport const buildAuthActionUrl = (\n baseUrl: string,\n actionPath: string,\n payload: TransactionalEmailPayload\n): string => {\n const cleanBase = baseUrl.replace(/\\/+$/, '')\n const cleanPath = actionPath.startsWith('/') ? actionPath : `/${actionPath}`\n const url = new URL(`${cleanBase}${cleanPath}`)\n if (payload.token) url.searchParams.set('token', payload.token)\n if (payload.code) url.searchParams.set('code', payload.code)\n url.searchParams.set('email', payload.to)\n return url.toString()\n}\n\nexport const renderDefaultAuthEmail = (\n vars: AuthEmailVariables,\n customSubject?: string\n): { subject: string; html: string; text: string } => {\n const subject = customSubject || `${vars.appName} \u2014 ${vars.purpose.replace(/_/g, ' ')}`\n if (vars.purpose === 'welcome') {\n return {\n subject,\n html: `<p>Welcome to <strong>${vars.appName}</strong>!</p><p><a href=\"${vars.actionUrl}\">Open ${vars.appName}</a></p>`,\n text: `Welcome to ${vars.appName}! Open: ${vars.actionUrl}`\n }\n }\n return {\n subject,\n html: [\n `<p>Your <strong>${vars.appName}</strong> verification code is:</p>`,\n `<p style=\"font-size:24px;font-weight:bold;letter-spacing:2px\">${vars.code}</p>`,\n `<p>Or click the link below (expires in ${vars.expiresInMinutes} minutes):</p>`,\n `<p><a href=\"${vars.actionUrl}\">${vars.actionUrl}</a></p>`\n ].join('\\n'),\n text: `Your ${vars.appName} code is ${vars.code} (expires in ${vars.expiresInMinutes} minutes).\\nLink: ${vars.actionUrl}`\n }\n}\n\nexport const buildSendGridPayload = (req: NormalizedEmailRequest): Record<string, unknown> => {\n const personalization: Record<string, unknown> = {\n to: req.to.map((email) => ({ email })),\n ...(req.cc?.length ? { cc: req.cc.map((email) => ({ email })) } : {}),\n ...(req.bcc?.length ? { bcc: req.bcc.map((email) => ({ email })) } : {}),\n ...(req.providerTemplateId\n ? { dynamic_template_data: req.variables }\n : req.subject\n ? { subject: req.subject }\n : {})\n }\n const content: { type: string; value: string }[] = []\n if (!req.providerTemplateId) {\n if (req.text) content.push({ type: 'text/plain', value: req.text })\n if (req.html) content.push({ type: 'text/html', value: req.html })\n if (!content.length) content.push({ type: 'text/plain', value: req.subject ?? '' })\n }\n return {\n personalizations: [personalization],\n from: { email: req.fromEmail, ...(req.fromName ? { name: req.fromName } : {}) },\n ...(req.replyTo ? { reply_to: { email: req.replyTo } } : {}),\n ...(req.subject ? { subject: req.subject } : {}),\n ...(req.providerTemplateId ? { template_id: req.providerTemplateId } : { content }),\n ...(req.attachments.length\n ? {\n attachments: req.attachments.map((a) => ({\n content: a.contentBase64,\n filename: a.filename,\n type: a.contentType,\n disposition: 'attachment'\n }))\n }\n : {}),\n ...(req.tags ? { custom_args: req.tags } : {})\n }\n}\n\nexport const buildResendPayload = (req: NormalizedEmailRequest): Record<string, unknown> => ({\n from: req.fromName ? `${req.fromName} <${req.fromEmail}>` : req.fromEmail,\n to: req.to,\n ...(req.cc?.length ? { cc: req.cc } : {}),\n ...(req.bcc?.length ? { bcc: req.bcc } : {}),\n ...(req.replyTo ? { reply_to: req.replyTo } : {}),\n subject: req.subject ?? req.template ?? 'Notification',\n ...(req.providerTemplateId\n ? { template_id: req.providerTemplateId, variables: req.variables }\n : {}),\n ...(req.html ? { html: req.html } : {}),\n ...(req.text ? { text: req.text } : {}),\n ...(!req.html && !req.text && !req.providerTemplateId\n ? { text: req.subject ?? 'Notification' }\n : {}),\n ...(req.attachments.length\n ? {\n attachments: req.attachments.map((a) => ({\n filename: a.filename,\n content: a.contentBase64,\n content_type: a.contentType\n }))\n }\n : {}),\n ...(req.tags\n ? { tags: Object.entries(req.tags).map(([name, value]) => ({ name, value })) }\n : {})\n})\n\nexport const postSendGridMail = async (\n baseUrl: string,\n apiKey: string,\n req: NormalizedEmailRequest\n): Promise<{ externalId: string }> => {\n const res = await fetch(`${baseUrl.replace(/\\/+$/, '')}/mail/send`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${apiKey}`, 'content-type': 'application/json' },\n body: JSON.stringify(buildSendGridPayload(req)),\n signal: AbortSignal.timeout(15_000)\n })\n if (!res.ok) {\n const err = new Error(`SendGrid HTTP ${res.status}: ${await res.text().catch(() => '')}`)\n ;(err as { status?: number }).status = res.status\n throw err\n }\n return { externalId: res.headers.get('x-message-id')?.trim() || `sg_${req.emailId}` }\n}\n\nexport const postResendEmail = async (\n baseUrl: string,\n apiKey: string,\n req: NormalizedEmailRequest\n): Promise<{ externalId: string }> => {\n const res = await fetch(`${baseUrl.replace(/\\/+$/, '')}/emails`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'content-type': 'application/json',\n ...(req.idempotencyKey ? { 'Idempotency-Key': req.idempotencyKey } : {})\n },\n body: JSON.stringify(buildResendPayload(req)),\n signal: AbortSignal.timeout(15_000)\n })\n if (!res.ok) {\n const err = new Error(`Resend HTTP ${res.status}: ${await res.text().catch(() => '')}`)\n ;(err as { status?: number }).status = res.status\n throw err\n }\n const data = (await res.json().catch(() => ({}))) as { id?: string }\n return { externalId: data.id || `re_${req.emailId}` }\n}\n\nexport const postResendBatch = async (\n baseUrl: string,\n apiKey: string,\n reqs: NormalizedEmailRequest[]\n): Promise<{ externalIds: string[] }> => {\n const res = await fetch(`${baseUrl.replace(/\\/+$/, '')}/emails/batch`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${apiKey}`, 'content-type': 'application/json' },\n body: JSON.stringify(reqs.map(buildResendPayload)),\n signal: AbortSignal.timeout(20_000)\n })\n if (!res.ok) {\n const err = new Error(`Resend Batch HTTP ${res.status}: ${await res.text().catch(() => '')}`)\n ;(err as { status?: number }).status = res.status\n throw err\n }\n const raw = (await res.json().catch(() => ({}))) as { data?: { id?: string }[] } | { id?: string }[]\n const items = Array.isArray(raw) ? raw : (raw.data ?? [])\n return { externalIds: reqs.map((r, idx) => items[idx]?.id || `re_${r.emailId}`) }\n}\n\nexport const postFirebaseOobCode = async (\n apiKey: string,\n customToken: string | undefined,\n payload: TransactionalEmailPayload,\n continueUrl: string\n): Promise<void> => {\n const postToolkit = async (endpoint: string, body: Record<string, unknown>) => {\n const res = await fetch(`https://identitytoolkit.googleapis.com/v1/${endpoint}?key=${apiKey}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(10_000)\n })\n return { ok: res.ok, data: (await res.json().catch(() => ({}))) as Record<string, unknown> }\n }\n let body: Record<string, unknown>\n if (payload.purpose === 'verify_email') {\n if (!customToken) return\n const { ok, data } = await postToolkit('accounts:signInWithCustomToken', {\n token: customToken,\n returnSecureToken: true\n })\n if (!ok || typeof data.idToken !== 'string') return\n body = { requestType: 'VERIFY_EMAIL', idToken: data.idToken }\n } else if (payload.purpose === 'reset_password') {\n body = { requestType: 'PASSWORD_RESET', email: payload.to }\n } else {\n body = { requestType: 'EMAIL_SIGNIN', email: payload.to, continueUrl, canHandleCodeInApp: true }\n }\n await postToolkit('accounts:sendOobCode', body)\n}\n\nexport const verifyResendWebhookHmac = (\n rawBody: string,\n headers: Record<string, string | undefined>,\n secret: string,\n toleranceSeconds: number\n): ResendWebhookEvent => {\n const msgId = getHeader(headers, 'svix-id') ?? getHeader(headers, 'webhook-id')\n const msgTimestamp = getHeader(headers, 'svix-timestamp') ?? getHeader(headers, 'webhook-timestamp')\n const msgSignature = getHeader(headers, 'svix-signature') ?? getHeader(headers, 'webhook-signature')\n if (!msgId || !msgTimestamp || !msgSignature || !secret) {\n throw new Error('Missing Resend/Svix webhook signature headers or secret')\n }\n\n const tsSeconds = Number(msgTimestamp)\n const nowSeconds = Math.floor(Date.now() / 1000)\n if (!Number.isFinite(tsSeconds) || Math.abs(nowSeconds - tsSeconds) > toleranceSeconds) {\n throw new Error('Resend webhook timestamp outside tolerance window')\n }\n\n const signedContent = `${msgId}.${msgTimestamp}.${rawBody}`\n const rawSecret = secret.startsWith('whsec_') ? secret.slice(6) : secret\n const expectedBase64FromDecoded = createHmac('sha256', Buffer.from(rawSecret, 'base64'))\n .update(signedContent, 'utf8')\n .digest('base64')\n const expectedBase64FromUtf8 = createHmac('sha256', Buffer.from(secret, 'utf8'))\n .update(signedContent, 'utf8')\n .digest('base64')\n\n const candidates = msgSignature\n .split(/\\s+/)\n .map((part) => (part.startsWith('v1,') ? part.slice(3) : part.trim()))\n .filter(Boolean)\n\n const verified = candidates.some(\n (sig) => constantTimeEqual(sig, expectedBase64FromDecoded) || constantTimeEqual(sig, expectedBase64FromUtf8)\n )\n if (!verified) {\n throw new Error('Invalid Resend webhook HMAC signature')\n }\n\n return JSON.parse(rawBody) as ResendWebhookEvent\n}\n\nexport const verifySendGridWebhookHmac = (\n rawBody: string,\n headers: Record<string, string | undefined>,\n secret: string,\n toleranceSeconds: number\n): SendGridWebhookEvent[] => {\n const timestamp =\n getHeader(headers, 'x-twilio-email-event-webhook-timestamp') ?? getHeader(headers, 'x-sendgrid-timestamp')\n const signature =\n getHeader(headers, 'x-twilio-email-event-webhook-signature') ?? getHeader(headers, 'x-sendgrid-signature')\n if (!timestamp || !signature || !secret) {\n throw new Error('Missing SendGrid webhook signature headers or secret')\n }\n\n const tsSeconds = Number(timestamp)\n const nowSeconds = Math.floor(Date.now() / 1000)\n if (!Number.isFinite(tsSeconds) || Math.abs(nowSeconds - tsSeconds) > toleranceSeconds) {\n throw new Error('SendGrid webhook timestamp outside tolerance window')\n }\n\n const signedPayload = `${timestamp}${rawBody}`\n const expectedBase64 = createHmac('sha256', secret).update(signedPayload, 'utf8').digest('base64')\n const expectedHex = createHmac('sha256', secret).update(signedPayload, 'utf8').digest('hex')\n const cleanSig = signature.startsWith('v1,') ? signature.slice(3) : signature\n\n if (!constantTimeEqual(cleanSig, expectedBase64) && !constantTimeEqual(cleanSig, expectedHex)) {\n throw new Error('Invalid SendGrid webhook HMAC signature')\n }\n\n const parsed = JSON.parse(rawBody) as unknown\n return Array.isArray(parsed) ? (parsed as SendGridWebhookEvent[]) : [parsed as SendGridWebhookEvent]\n}\n\nexport interface NormalizedWebhookUpdate {\n externalId?: string\n recipient?: string\n status: EmailLogStatus\n rawEvent: string\n}\n\nexport const parseAndVerifyEmailWebhook = (\n provider: 'sendgrid' | 'resend',\n rawBody: string,\n headers: Record<string, string | undefined>,\n secret: string,\n toleranceSeconds: number\n): { processed: number; updates: NormalizedWebhookUpdate[] } => {\n if (provider === 'resend') {\n const event = verifyResendWebhookHmac(rawBody, headers, secret, toleranceSeconds)\n const status = RESEND_STATUS_MAP[event.type]\n const recipient = Array.isArray(event.data?.to) ? event.data.to[0] : event.data?.to\n return {\n processed: 1,\n updates: status\n ? [{ ...(event.data?.email_id ? { externalId: event.data.email_id } : {}), ...(recipient ? { recipient } : {}), status, rawEvent: rawBody }]\n : []\n }\n }\n\n const events = verifySendGridWebhookHmac(rawBody, headers, secret, toleranceSeconds)\n const updates: NormalizedWebhookUpdate[] = []\n for (const ev of events) {\n const status = SENDGRID_STATUS_MAP[ev.event]\n if (!status) continue\n const cleanMsgId = ev.sg_message_id?.split('.')[0]\n updates.push({\n ...(cleanMsgId ? { externalId: cleanMsgId } : {}),\n ...(ev.email ? { recipient: ev.email } : {}),\n status,\n rawEvent: JSON.stringify(ev)\n })\n }\n return { processed: events.length, updates }\n}\n", "import type { DbListOptions, EntryId, PaginatedList, SelectModel } from '../db'\nimport type { Core } from '../index'\nimport {\n getEmailTemplate,\n sendEmailInputSchema,\n type AuthEmailPurpose,\n type AuthEmailVariables,\n type EmailAttachmentInput,\n type EmailCallOptions,\n type EmailLogStatus,\n type EmailProvider,\n type NormalizedEmailRequest,\n type ResolvedAttachment,\n type SendBatchEmailResult,\n type SendEmailInput,\n type SendEmailResult,\n type TransactionalEmailPayload\n} from './schema'\nimport {\n buildAuthActionUrl,\n buildNormalizedEmailRequest,\n idempotencyEmailDocId,\n normalizeEmail,\n parseAndVerifyEmailWebhook,\n postFirebaseOobCode,\n postResendBatch,\n postResendEmail,\n postSendGridMail,\n renderDefaultAuthEmail,\n summarizeBatchEmailResults,\n suppressionDocId\n} from './utils'\n\nexport class EmailsService {\n readonly #core: Core\n readonly #devEmailOutbox = new Map<string, TransactionalEmailPayload>()\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n }\n\n #resolveProvider = (override?: EmailProvider): EmailProvider | 'dev' => {\n const preferred = override ?? this.#core.config.emails.provider\n const hasResend = Boolean(this.#core.env.RESEND_API_KEY?.trim())\n const hasSendGrid = Boolean(this.#core.env.SENDGRID_API_KEY?.trim())\n if (preferred === 'sendgrid') {\n if (hasSendGrid) return 'sendgrid'\n if (!override && hasResend) return 'resend'\n } else if (preferred === 'resend') {\n if (hasResend) return 'resend'\n if (!override && hasSendGrid) return 'sendgrid'\n } else if (preferred === 'firebase') {\n return this.#core.env.isDev && !this.#core.env.WEB_API_KEY ? 'dev' : 'firebase'\n }\n return this.#core.env.isDev ? 'dev' : 'firebase'\n }\n\n #resolveAttachments = async (attachments?: EmailAttachmentInput[]): Promise<ResolvedAttachment[]> =>\n attachments?.length\n ? Promise.all(\n attachments.map(async (att) => {\n if (att.contentBase64) {\n return {\n filename: att.filename,\n contentBase64: att.contentBase64,\n contentType: att.contentType ?? 'application/octet-stream'\n }\n }\n const { bytes, type } = await this.#core.files.get(att.fileRef!)\n return {\n filename: att.filename,\n contentBase64: Buffer.from(bytes).toString('base64'),\n contentType: att.contentType ?? type\n }\n })\n )\n : []\n\n #withEmailBreaker = async <T>(cost: number, fn: () => Promise<T>): Promise<T> => {\n await this.#core.internals.resilience.acquireLimit('emails', cost)\n return this.#core.internals.resilience.circuitBreaker('emails', fn)\n }\n\n #sendViaSendGrid = (req: NormalizedEmailRequest): Promise<{ externalId: string }> =>\n this.#withEmailBreaker(1, () =>\n postSendGridMail(this.#core.config.emails.sendgrid.baseUrl, this.#core.env.SENDGRID_API_KEY, req)\n )\n\n #sendViaResend = (req: NormalizedEmailRequest): Promise<{ externalId: string }> =>\n this.#withEmailBreaker(1, () =>\n postResendEmail(this.#core.config.emails.resend.baseUrl, this.#core.env.RESEND_API_KEY, req)\n )\n\n #sendBatchViaResend = (reqs: NormalizedEmailRequest[]): Promise<{ externalIds: string[] }> =>\n this.#withEmailBreaker(reqs.length, () =>\n postResendBatch(this.#core.config.emails.resend.baseUrl, this.#core.env.RESEND_API_KEY, reqs)\n )\n\n #sendFirebaseOobEmail = async (payload: TransactionalEmailPayload): Promise<void> => {\n const apiKey = this.#core.env.WEB_API_KEY\n if (!apiKey) return\n try {\n const customToken =\n payload.purpose === 'verify_email'\n ? (await this.#core.internals.auth.mintCustomToken(payload.userId)).customToken\n : undefined\n await postFirebaseOobCode(\n apiKey,\n customToken,\n payload,\n this.#core.config.emails.actionBaseUrl || 'http://localhost'\n )\n } catch {}\n }\n\n #prepareEmailRequest = async (\n rawInput: SendEmailInput<any>,\n provider: EmailProvider | 'dev',\n opts?: EmailCallOptions\n ): Promise<{ req: NormalizedEmailRequest; cancelled: boolean }> => {\n const parsed = sendEmailInputSchema.parse(rawInput)\n const toList = (Array.isArray(parsed.to) ? parsed.to : [parsed.to]).map(normalizeEmail)\n const tmpl = parsed.template ? getEmailTemplate(parsed.template) : undefined\n if (parsed.template && !tmpl && !parsed.providerTemplateId && !parsed.html && !parsed.text) {\n return this.#core.errors.httpError(400, `Unregistered email template: ${parsed.template}`, 'INVALID_TEMPLATE')\n }\n\n let vars: Record<string, unknown> = { ...(parsed.variables ?? {}) }\n if (tmpl?.variables) vars = tmpl.variables.parse(vars) as Record<string, unknown>\n const emailId = parsed.idempotencyKey\n ? idempotencyEmailDocId(parsed.idempotencyKey)\n : `em_${crypto.randomUUID().replace(/-/g, '').slice(0, 24)}`\n const emailsCfg = this.#core.config.emails\n\n if (tmpl?.onBeforeSend) {\n const hookResult = await tmpl.onBeforeSend(vars, toList[0]!)\n if (hookResult === false) {\n return {\n cancelled: true,\n req: {\n emailId,\n to: toList,\n fromEmail: parsed.fromEmail ?? tmpl.fromEmail ?? emailsCfg.fromEmail,\n fromName: parsed.fromName ?? tmpl.fromName ?? emailsCfg.fromName,\n variables: vars,\n attachments: []\n }\n }\n }\n vars = hookResult as Record<string, unknown>\n }\n\n const attachments = await this.#resolveAttachments(parsed.attachments)\n const userId = opts?.userId ?? (this.#core.userId || undefined)\n return {\n cancelled: false,\n req: buildNormalizedEmailRequest(emailId, toList, parsed, tmpl, provider, vars, emailsCfg, attachments, userId)\n }\n }\n\n #recordEmailLog = async (\n req: NormalizedEmailRequest,\n provider: EmailProvider | 'dev',\n status: EmailLogStatus,\n externalMessageId?: string,\n errorMessage?: string\n ): Promise<SendEmailResult> => {\n const template = req.template ?? req.providerTemplateId\n await this.#core.db.create(\n 'email_log',\n {\n id: req.emailId,\n ...(req.userId ? { userId: req.userId } : {}),\n provider,\n ...(externalMessageId ? { externalMessageId } : {}),\n to: req.to[0]!,\n from: req.fromName ? `${req.fromName} <${req.fromEmail}>` : req.fromEmail,\n ...(req.subject ? { subject: req.subject } : {}),\n ...(template ? { template } : {}),\n ...(req.purpose ? { purpose: req.purpose } : {}),\n status,\n ...(errorMessage ? { errorMessage } : {}),\n sentAt: new Date().toISOString()\n },\n { bypassRbac: true }\n )\n return { emailId: req.emailId, ...(externalMessageId ? { externalMessageId } : {}), status, provider }\n }\n\n isSuppressed = async (email: string): Promise<boolean> =>\n Boolean(await this.#core.db.read('email_suppression', suppressionDocId(email), false, { bypassRbac: true }))\n\n #isRecipientListSuppressed = async (recipients: string[]): Promise<boolean> =>\n this.#core.config.emails.enforceSuppressionList\n ? (await Promise.all(recipients.map((addr) => this.isSuppressed(addr)))).some(Boolean)\n : false\n\n getLog = async (emailId: EntryId): Promise<SelectModel<'email_log'> | undefined> =>\n this.#core.db.read('email_log', emailId, false, { bypassRbac: true })\n\n listLogs = async (\n options?: DbListOptions<SelectModel<'email_log'>>\n ): Promise<PaginatedList<SelectModel<'email_log'>>> =>\n this.#core.db.list('email_log', options, { bypassRbac: true })\n\n #checkExistingIdempotentEmail = async (idempotencyKey?: string): Promise<SendEmailResult | undefined> => {\n if (!idempotencyKey) return undefined\n const existing = await this.#core.db.read('email_log', idempotencyEmailDocId(idempotencyKey), false, { bypassRbac: true })\n if (!existing || existing.status === 'failed') return undefined\n return {\n emailId: existing.id,\n ...(existing.externalMessageId ? { externalMessageId: existing.externalMessageId } : {}),\n status: existing.status,\n provider: existing.provider,\n deduplicated: true\n }\n }\n\n #sendOnce = async <T = Record<string, unknown>>(input: SendEmailInput<T>, opts?: EmailCallOptions): Promise<SendEmailResult> => {\n const existing = await this.#checkExistingIdempotentEmail(input.idempotencyKey)\n if (existing) return existing\n\n const provider = this.#resolveProvider(opts?.provider)\n const { req, cancelled } = await this.#prepareEmailRequest(input, provider, opts)\n if (cancelled || (await this.#isRecipientListSuppressed(req.to))) {\n return this.#recordEmailLog(req, provider, 'suppressed')\n }\n\n try {\n const externalId =\n provider === 'sendgrid'\n ? (await this.#sendViaSendGrid(req)).externalId\n : provider === 'resend'\n ? (await this.#sendViaResend(req)).externalId\n : `${provider}_${req.emailId}`\n return this.#recordEmailLog(req, provider, 'sent', externalId)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n await this.#recordEmailLog(req, provider, 'failed', undefined, msg).catch(() => {})\n throw err\n }\n }\n\n send = async <T = Record<string, unknown>>(input: SendEmailInput<T>, opts?: EmailCallOptions): Promise<SendEmailResult> =>\n input.idempotencyKey\n ? this.#core.internals.resilience.singleflight(\n `email_send:${idempotencyEmailDocId(input.idempotencyKey)}`,\n () => this.#sendOnce(input, opts),\n { scope: 'global' }\n )\n : this.#sendOnce(input, opts)\n\n sendBatch = async (inputs: SendEmailInput[], opts?: EmailCallOptions): Promise<SendBatchEmailResult> => {\n const provider = this.#resolveProvider(opts?.provider)\n if (provider !== 'resend' || !inputs.length) {\n return summarizeBatchEmailResults(await Promise.all(inputs.map((inp) => this.send(inp, opts))))\n }\n\n const prepared = await Promise.all(inputs.map((inp) => this.#prepareEmailRequest(inp, 'resend', opts)))\n const results: SendEmailResult[] = []\n const activeReqs: { idx: number; req: NormalizedEmailRequest }[] = []\n\n for (let i = 0; i < prepared.length; i++) {\n const dedup = await this.#checkExistingIdempotentEmail(inputs[i]?.idempotencyKey)\n if (dedup) {\n results[i] = dedup\n continue\n }\n const { req, cancelled } = prepared[i]!\n if (cancelled || (await this.#isRecipientListSuppressed(req.to))) {\n results[i] = await this.#recordEmailLog(req, 'resend', 'suppressed')\n } else {\n activeReqs.push({ idx: i, req })\n }\n }\n\n if (activeReqs.length > 0) {\n const { externalIds } = await this.#sendBatchViaResend(activeReqs.map((a) => a.req))\n await Promise.all(\n activeReqs.map(async ({ idx, req }, k) => {\n results[idx] = await this.#recordEmailLog(req, 'resend', 'sent', externalIds[k])\n })\n )\n }\n return summarizeBatchEmailResults(results)\n }\n\n sendAuthEmail = async (\n purpose: AuthEmailPurpose,\n to: string,\n vars?: Partial<AuthEmailVariables>,\n opts?: EmailCallOptions\n ): Promise<SendEmailResult> =>\n this.#dispatchAuthEmail(\n {\n to,\n purpose,\n code: vars?.code ?? '',\n token: vars?.token ?? '',\n expiresInMinutes: vars?.expiresInMinutes ?? this.#core.config.emails.otpTtlMinutes,\n userId: vars?.userId ?? this.#core.userId\n },\n vars,\n opts\n )\n\n #getLastDevEmail = (to: string, purpose: AuthEmailPurpose): TransactionalEmailPayload | undefined =>\n this.#devEmailOutbox.get(`${purpose}:${normalizeEmail(to)}`)\n\n #runAuthFlowHooks = async (\n initialVars: AuthEmailVariables,\n purpose: AuthEmailPurpose\n ): Promise<AuthEmailVariables | false> => {\n const emailsCfg = this.#core.config.emails\n const flowCfg = emailsCfg.authFlows[purpose]\n let authVars = initialVars\n for (const hook of [emailsCfg.onAuthEmail, flowCfg?.onSend]) {\n if (!hook) continue\n const hookOut = await hook(authVars, { core: this.#core, env: this.#core.env })\n if (hookOut === false) return false\n if (hookOut && typeof hookOut === 'object') authVars = { ...authVars, ...hookOut }\n }\n return authVars\n }\n\n #dispatchAuthEmail = async (\n payload: TransactionalEmailPayload,\n extraVars?: Partial<AuthEmailVariables>,\n opts?: EmailCallOptions\n ): Promise<SendEmailResult> => {\n const normalizedTo = normalizeEmail(payload.to)\n const normalizedPayload: TransactionalEmailPayload = { ...payload, to: normalizedTo }\n if (this.#core.env.isDev || !process.env.K_SERVICE) {\n const outboxKey = `${payload.purpose}:${normalizedTo}`\n if (!this.#devEmailOutbox.has(outboxKey) && this.#devEmailOutbox.size >= 500) {\n this.#devEmailOutbox.delete(this.#devEmailOutbox.keys().next().value!)\n }\n this.#devEmailOutbox.set(outboxKey, normalizedPayload)\n }\n\n const emailsCfg = this.#core.config.emails\n const flowCfg = emailsCfg.authFlows[payload.purpose]\n const actionUrl = buildAuthActionUrl(emailsCfg.actionBaseUrl, flowCfg?.actionPath ?? '/', normalizedPayload)\n const authVars = await this.#runAuthFlowHooks(\n {\n appName: this.#core.config.appName || emailsCfg.fromName || 'App',\n userId: payload.userId,\n email: normalizedTo,\n purpose: payload.purpose,\n code: payload.code,\n token: payload.token,\n actionUrl,\n expiresInMinutes: payload.expiresInMinutes,\n ...extraVars\n },\n payload.purpose\n )\n if (authVars === false) return { emailId: `em_hook_${Date.now()}`, status: 'sent', provider: 'dev' }\n const callOpts = { ...opts, userId: payload.userId || opts?.userId }\n\n const registeredTmpl = getEmailTemplate(payload.purpose)\n if (registeredTmpl || flowCfg?.templateId) {\n const hasTmplSubject = Boolean(registeredTmpl?.subject || registeredTmpl?.providers?.resend?.subject)\n return this.send(\n {\n to: normalizedTo,\n ...(registeredTmpl ? { template: payload.purpose } : {}),\n ...(flowCfg?.templateId ? { providerTemplateId: flowCfg.templateId } : {}),\n ...(!hasTmplSubject && flowCfg?.subject ? { subject: flowCfg.subject } : {}),\n variables: authVars,\n purpose: payload.purpose\n },\n callOpts\n )\n }\n\n const provider = this.#resolveProvider(opts?.provider)\n if (provider === 'sendgrid' || provider === 'resend' || this.#core.env.isDev) {\n return this.send(\n {\n to: normalizedTo,\n ...renderDefaultAuthEmail(authVars, flowCfg?.subject),\n variables: authVars,\n purpose: payload.purpose\n },\n callOpts\n )\n }\n\n await this.#sendFirebaseOobEmail(normalizedPayload)\n return this.#recordEmailLog(\n {\n emailId: `em_fb_${crypto.randomUUID().replace(/-/g, '').slice(0, 20)}`,\n to: [normalizedTo],\n fromEmail: emailsCfg.fromEmail,\n fromName: emailsCfg.fromName,\n subject: flowCfg?.subject ?? payload.purpose,\n variables: authVars,\n attachments: [],\n purpose: payload.purpose,\n userId: payload.userId\n },\n 'firebase',\n 'sent'\n )\n }\n\n #applyWebhookStatus = async (\n provider: 'sendgrid' | 'resend',\n externalId: string | undefined,\n recipient: string | undefined,\n status: EmailLogStatus,\n rawEvent: string\n ): Promise<void> => {\n const nowIso = new Date().toISOString()\n const normRecipient = recipient ? normalizeEmail(recipient) : undefined\n if ((status === 'bounced' || status === 'complained') && normRecipient) {\n const supId = suppressionDocId(normRecipient)\n const now = new Date()\n await this.#core.internals.resilience.acquireLimit('firestore')\n await this.#core.db.firestore().collection('email_suppression').doc(supId).set(\n {\n id: supId,\n email: normRecipient,\n reason: status === 'complained' ? 'spam_complaint' : 'hard_bounce',\n provider,\n rawEvent: rawEvent.slice(0, 1000),\n suppressedAt: nowIso,\n deleted: false,\n createdAt: now,\n updatedAt: now\n },\n { merge: true }\n )\n }\n\n const logs = externalId\n ? await this.listLogs({ where: { externalMessageId: externalId }, limit: 5 })\n : normRecipient\n ? await this.listLogs({ where: { to: normRecipient }, limit: 1 })\n : []\n\n const patch = {\n status,\n ...(status === 'delivered' ? { deliveredAt: nowIso } : {}),\n ...(status === 'bounced' || status === 'complained' ? { bouncedAt: nowIso } : {})\n }\n await Promise.all(logs.map((log) => this.#core.db.update('email_log', log.id, patch, { bypassRbac: true })))\n }\n\n #verifyAndProcessWebhook = async (\n provider: 'sendgrid' | 'resend',\n rawBody: string,\n headers: Record<string, string | undefined>\n ): Promise<{ received: true; processed: number }> => {\n const secret =\n this.#core.env.isDev && this.#core.env.EMAIL_SANDBOX_WEBHOOK_SECRET\n ? this.#core.env.EMAIL_SANDBOX_WEBHOOK_SECRET\n : this.#core.env.EMAIL_WEBHOOK_SECRET || this.#core.env.EMAIL_SANDBOX_WEBHOOK_SECRET\n try {\n const parsed = parseAndVerifyEmailWebhook(\n provider,\n rawBody,\n headers,\n secret,\n this.#core.config.emails.webhookToleranceSeconds\n )\n for (const u of parsed.updates) {\n await this.#applyWebhookStatus(provider, u.externalId, u.recipient, u.status, u.rawEvent)\n }\n return { received: true, processed: parsed.processed }\n } catch (err) {\n return this.#core.errors.httpError(\n 401,\n err instanceof Error ? err.message : `Invalid ${provider} webhook signature`,\n 'INVALID_WEBHOOK_SIGNATURE'\n )\n }\n }\n\n get internals() {\n return {\n dispatchAuthEmail: this.#dispatchAuthEmail,\n verifyAndProcessWebhook: this.#verifyAndProcessWebhook,\n getLastDevEmail: this.#getLastDevEmail\n }\n }\n}\n", "import type { Context } from 'hono'\nimport type { AppEnv } from '../config'\nimport type { Core } from '../index'\nimport {\n emailLogsQuerySchema,\n emailWebhookParamsSchema,\n sendBatchEmailInputSchema,\n sendBatchEmailResultSchema,\n sendEmailInputSchema,\n sendEmailResultSchema,\n type EmailLogsQuery,\n type EmailWebhookParams,\n type SendBatchEmailInput,\n type SendEmailInput\n} from './schema'\n\nexport const coreEmailRoutes = {\n 'emails.send': {\n input: sendEmailInputSchema,\n output: sendEmailResultSchema,\n handler: async ({ core, input }: { core: Core; input: SendEmailInput }) => core.emails.send(input)\n },\n 'emails.batch': {\n input: sendBatchEmailInputSchema,\n output: sendBatchEmailResultSchema,\n handler: async ({ core, input }: { core: Core; input: SendBatchEmailInput }) => core.emails.sendBatch(input.emails)\n },\n 'emails.logs': {\n query: emailLogsQuerySchema,\n handler: async ({ core, query }: { core: Core; query: EmailLogsQuery }) =>\n core.emails.listLogs({\n ...(query.userId ? { userId: query.userId } : {}),\n ...(query.limit ? { limit: query.limit } : {}),\n ...(query.cursor ? { cursor: query.cursor } : {}),\n where: {\n ...(query.to ? { to: query.to.trim().toLowerCase() } : {}),\n ...(query.template ? { template: query.template } : {}),\n ...(query.purpose ? { purpose: query.purpose } : {}),\n ...(query.status ? { status: query.status } : {})\n }\n })\n },\n 'emails.webhook': {\n params: emailWebhookParamsSchema,\n handler: async ({\n core,\n c,\n params,\n rawBody\n }: {\n core: Core\n c: Context<AppEnv>\n params: EmailWebhookParams\n rawBody?: string\n }) => {\n const headers: Record<string, string | undefined> = {}\n c?.req.raw.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value\n })\n const body = rawBody ?? (c ? await c.req.text() : '')\n return core.internals.emails.verifyAndProcessWebhook(params.provider, body, headers)\n }\n }\n}\n", "import { z } from 'zod'\nimport { CORE_CONFIG, type EnvScopedString, type PaymentProvider, type PaymentsConfig } from '../config'\nimport { entryId, type EntryId } from '../db'\n\nexport type { EnvScopedString, PaymentProvider, PaymentsConfig }\n\nexport interface ProviderPlanMapping {\n stripe?: {\n priceId: EnvScopedString\n meterEventName?: string\n }\n dodo?: {\n productId: EnvScopedString\n meterEventName?: string\n }\n}\n\nexport interface PlanQuotaSpec {\n aiTokens?: number | null\n metrics?: Record<string, number>\n overage?: {\n enabled: boolean\n maxOverageTokens?: number\n unitTokens?: number\n rateCents?: number\n }\n}\n\nexport interface PlanDefinition {\n id?: string\n name: string\n description?: string\n interval: 'month' | 'year' | 'free'\n amount: number\n currency?: Lowercase<string>\n providers?: ProviderPlanMapping\n quota?: PlanQuotaSpec\n quotas?: PlanQuotaSpec\n metadata?: Record<string, string>\n}\n\nexport type PlansMap = Record<string, PlanDefinition>\n\nexport interface ProductDefinition {\n id?: string\n name: string\n description?: string\n amount: number\n currency?: Lowercase<string>\n providers?: {\n stripe?: {\n priceId?: EnvScopedString\n productId?: EnvScopedString\n }\n dodo?: {\n productId: EnvScopedString\n }\n }\n grants?: {\n aiTokens?: number\n credits?: number\n metrics?: Record<string, number>\n }\n metadata?: Record<string, string>\n}\n\nexport type ProductsMap = Record<string, ProductDefinition>\n\nconst registeredPlans: Record<string, PlanDefinition & { id: string; quota: PlanQuotaSpec }> = {}\nconst registeredProducts: Record<string, ProductDefinition & { id: string }> = {}\n\nexport const registerPlans = (plans?: PlansMap, reset = false): void => {\n if (reset) {\n for (const k of Object.keys(registeredPlans)) delete registeredPlans[k]\n }\n if (!plans) return\n const entries = Object.entries(plans)\n for (const [k, def] of entries) {\n const quota = def.quota ?? def.quotas ?? {}\n registeredPlans[k] = { ...def, id: def.id ?? k, quota, quotas: quota }\n }\n if (entries.length > 0) CORE_CONFIG.payments.enabled = true\n}\n\nexport const registerProducts = (products?: ProductsMap, reset = false): void => {\n if (reset) {\n for (const k of Object.keys(registeredProducts)) delete registeredProducts[k]\n }\n if (!products) return\n const entries = Object.entries(products)\n for (const [k, def] of entries) {\n registeredProducts[k] = { ...def, id: def.id ?? k }\n }\n if (entries.length > 0) CORE_CONFIG.payments.enabled = true\n}\n\nexport const clearPaymentDefinitions = (): void => {\n for (const k of Object.keys(registeredPlans)) delete registeredPlans[k]\n for (const k of Object.keys(registeredProducts)) delete registeredProducts[k]\n CORE_CONFIG.payments.enabled = false\n}\n\nexport const definePlans = <T extends PlansMap>(plans: T): T => {\n const normalized = Object.fromEntries(\n Object.entries(plans).map(([k, def]) => [k, { ...def, id: def.id ?? k }])\n ) as T\n registerPlans(normalized, false)\n return normalized\n}\n\nexport const defineProducts = <T extends ProductsMap>(products: T): T => {\n const normalized = Object.fromEntries(\n Object.entries(products).map(([k, def]) => [k, { ...def, id: def.id ?? k }])\n ) as T\n registerProducts(normalized, false)\n return normalized\n}\n\nexport const getPlanDefinition = (id: string): (PlanDefinition & { id: string; quota: PlanQuotaSpec }) | undefined =>\n registeredPlans[id]\n\nexport const getProductDefinition = (id: string): (ProductDefinition & { id: string }) | undefined =>\n registeredProducts[id]\n\nexport const getRegisteredPlans = (): Record<string, PlanDefinition & { id: string; quota: PlanQuotaSpec }> => registeredPlans\n\nexport const getRegisteredProducts = (): Record<string, ProductDefinition & { id: string }> => registeredProducts\n\nexport const subscriptionStatusSchema = z.enum([\n 'none',\n 'active',\n 'trialing',\n 'past_due',\n 'on_hold',\n 'cancelled',\n 'expired'\n])\nexport type SubscriptionStatus = z.infer<typeof subscriptionStatusSchema>\n\nexport const paymentTransactionTypeSchema = z.enum([\n 'checkout.completed',\n 'payment.succeeded',\n 'payment.failed',\n 'invoice.created',\n 'invoice.paid',\n 'subscription.active',\n 'subscription.renewed',\n 'subscription.tier_changed',\n 'subscription.cancelled',\n 'subscription.past_due'\n])\nexport type PaymentTransactionType = z.infer<typeof paymentTransactionTypeSchema>\n\nexport const customLineItemSchema = z.object({\n name: z.string().min(1).max(200),\n description: z.string().max(1000).optional(),\n amount: z.number().int().positive(),\n currency: z.string().length(3).toLowerCase().optional(),\n quantity: z.number().int().positive().default(1)\n})\nexport type CustomLineItem = z.input<typeof customLineItemSchema>\n\nexport const createCheckoutInput = z\n .object({\n product: z.string().optional(),\n plan: z.string().optional(),\n custom: customLineItemSchema.optional(),\n quantity: z.number().int().positive().default(1),\n successUrl: z.string().url().optional(),\n cancelUrl: z.string().url().optional(),\n idempotencyKey: z.string().max(200).optional(),\n metadata: z.record(z.string(), z.string()).optional()\n })\n .refine((v) => Number(Boolean(v.product)) + Number(Boolean(v.plan)) + Number(Boolean(v.custom)) === 1, {\n message: 'Provide exactly one of: product, plan, or custom'\n })\nexport type CreateCheckoutInput = z.input<typeof createCheckoutInput>\n\nexport const checkoutSessionResultSchema = z.object({\n checkoutId: z.string(),\n url: z.string().url(),\n provider: z.enum(['stripe', 'dodo']),\n expiresAt: z.string().datetime().optional()\n})\nexport type CheckoutSessionResult = z.infer<typeof checkoutSessionResultSchema>\n\nexport const createPaymentLinkInput = z\n .object({\n product: z.string().optional(),\n plan: z.string().optional(),\n custom: customLineItemSchema.optional(),\n quantity: z.number().int().positive().default(1),\n returnUrl: z.string().url().optional(),\n idempotencyKey: z.string().max(200).optional(),\n metadata: z.record(z.string(), z.string()).optional()\n })\n .refine((v) => Number(Boolean(v.product)) + Number(Boolean(v.plan)) + Number(Boolean(v.custom)) === 1, {\n message: 'Provide exactly one of: product, plan, or custom'\n })\nexport type CreatePaymentLinkInput = z.input<typeof createPaymentLinkInput>\n\nexport const paymentLinkResultSchema = z.object({\n paymentLinkId: z.string(),\n url: z.string().url(),\n provider: z.enum(['stripe', 'dodo'])\n})\nexport type PaymentLinkResult = z.infer<typeof paymentLinkResultSchema>\n\nexport const createInvoiceInput = z\n .object({\n product: z.string().optional(),\n custom: customLineItemSchema.optional(),\n quantity: z.number().int().positive().default(1),\n daysUntilDue: z.number().int().positive().max(365).default(30),\n idempotencyKey: z.string().max(200).optional(),\n metadata: z.record(z.string(), z.string()).optional()\n })\n .refine((v) => Number(Boolean(v.product)) + Number(Boolean(v.custom)) === 1, {\n message: 'Provide exactly one of: product or custom'\n })\nexport type CreateInvoiceInput = z.input<typeof createInvoiceInput>\n\nexport const invoiceResultSchema = z.object({\n invoiceId: z.string(),\n status: z.enum(['open', 'paid', 'draft', 'void']),\n amount: z.number().int().nonnegative(),\n currency: z.string(),\n hostedInvoiceUrl: z.string().url(),\n pdfUrl: z.string().url().optional(),\n provider: z.enum(['stripe', 'dodo'])\n})\nexport type InvoiceResult = z.infer<typeof invoiceResultSchema>\n\nexport const directChargeInput = z\n .object({\n product: z.string().optional(),\n custom: customLineItemSchema.optional(),\n amount: z.number().int().positive().optional(),\n currency: z.string().length(3).toLowerCase().optional(),\n description: z.string().max(1000).optional(),\n paymentMethodId: z.string().optional(),\n idempotencyKey: z.string().max(200).optional(),\n metadata: z.record(z.string(), z.string()).optional()\n })\n .refine((v) => Boolean(v.product || v.custom || v.amount), {\n message: 'Provide product, custom, or amount'\n })\nexport type DirectChargeInput = z.input<typeof directChargeInput>\n\nexport const chargeResultSchema = z.object({\n chargeId: z.string(),\n status: z.enum(['succeeded', 'requires_action', 'failed']),\n amount: z.number().int().nonnegative(),\n currency: z.string(),\n provider: z.enum(['stripe', 'dodo']),\n checkoutUrl: z.string().url().optional(),\n clientSecret: z.string().optional()\n})\nexport type ChargeResult = z.infer<typeof chargeResultSchema>\n\nexport const subscribeInput = z.object({\n plan: z.string().min(1),\n returnUrl: z.string().url().optional(),\n idempotencyKey: z.string().max(200).optional(),\n metadata: z.record(z.string(), z.string()).optional()\n})\nexport type SubscribeInput = z.input<typeof subscribeInput>\n\nexport const subscribeResultSchema = z.object({\n subscriptionId: z.string(),\n planId: z.string(),\n status: z.enum(['active', 'trialing', 'requires_action']),\n provider: z.enum(['stripe', 'dodo']),\n checkoutUrl: z.string().url().optional()\n})\nexport type SubscribeResult = z.infer<typeof subscribeResultSchema>\n\nexport const changeTierInput = z.object({\n plan: z.string().min(1),\n proration: z.enum(['prorated_immediately', 'next_cycle', 'none']).default('prorated_immediately'),\n idempotencyKey: z.string().max(200).optional()\n})\nexport type ChangeTierInput = z.input<typeof changeTierInput>\n\nexport const cancelSubscriptionInput = z.object({\n immediately: z.boolean().default(false),\n reason: z.string().max(500).optional(),\n idempotencyKey: z.string().max(200).optional()\n})\nexport type CancelSubscriptionInput = z.input<typeof cancelSubscriptionInput>\n\nexport const subscriptionRecordSchema = z.object({\n subscriptionId: z.string(),\n planId: z.string(),\n status: subscriptionStatusSchema,\n provider: z.enum(['stripe', 'dodo']),\n cancelAtPeriodEnd: z.boolean(),\n currentPeriodStart: z.string().datetime().optional(),\n currentPeriodEnd: z.string().datetime().optional()\n})\nexport type SubscriptionRecord = z.infer<typeof subscriptionRecordSchema>\n\nexport const recordUsageInput = z.object({\n metric: z.string().default('ai_tokens'),\n amount: z.number().positive(),\n inputTokens: z.number().int().nonnegative().optional(),\n outputTokens: z.number().int().nonnegative().optional(),\n model: z.string().optional(),\n idempotencyKey: z.string().max(200).optional(),\n metadata: z.record(z.string(), z.string()).optional()\n})\nexport type RecordUsageInput = z.input<typeof recordUsageInput>\n\nexport const usageStatusResultSchema = z.object({\n userId: entryId,\n periodKey: z.string(),\n planId: z.string(),\n aiTokensUsed: z.number().int().nonnegative(),\n aiTokensLimit: z.number().int().nonnegative().nullable(),\n bonusAiTokens: z.number().int().nonnegative(),\n overageTokensReported: z.number().int().nonnegative(),\n overageEnabled: z.boolean(),\n maxOverageTokens: z.number().int().positive().optional(),\n metricsUsed: z.record(z.string(), z.number()),\n metricsLimits: z.record(z.string(), z.number()),\n bonusMetrics: z.record(z.string(), z.number())\n})\nexport type UsageStatusResult = z.infer<typeof usageStatusResultSchema>\nexport const usageSummarySchema = usageStatusResultSchema\nexport type UsageSummary = UsageStatusResult\n\nexport const quotaCheckResultSchema = z.object({\n allowed: z.boolean(),\n metric: z.string(),\n used: z.number().nonnegative(),\n limit: z.number().nonnegative().nullable(),\n bonusRemaining: z.number().nonnegative(),\n overageEnabled: z.boolean(),\n remaining: z.number().nullable()\n})\nexport type QuotaCheckResult = z.infer<typeof quotaCheckResultSchema>\n\nexport const customerBillingSummarySchema = z.object({\n userId: entryId,\n planId: z.string(),\n plan: z.object({\n id: z.string(),\n name: z.string(),\n interval: z.enum(['month', 'year', 'free']),\n amount: z.number(),\n currency: z.string()\n }),\n status: subscriptionStatusSchema,\n subscriptionId: z.string().optional(),\n activeProvider: z.enum(['stripe', 'dodo']).optional(),\n currentPeriodStart: z.string().datetime().optional(),\n currentPeriodEnd: z.string().datetime().optional(),\n cancelAtPeriodEnd: z.boolean(),\n bonusAiTokens: z.number().int().nonnegative(),\n credits: z.number().nonnegative(),\n bonusMetrics: z.record(z.string(), z.number())\n})\nexport type CustomerBillingSummary = z.infer<typeof customerBillingSummarySchema>\n\nexport const paymentWebhookParamsSchema = z.object({\n provider: z.enum(['stripe', 'dodo'])\n})\nexport type PaymentWebhookParams = z.infer<typeof paymentWebhookParamsSchema>\n\nexport const paymentWebhookResultSchema = z.object({\n received: z.literal(true),\n eventId: z.string(),\n handled: z.boolean(),\n deduplicated: z.boolean().optional()\n})\nexport type PaymentWebhookResult = z.infer<typeof paymentWebhookResultSchema>\n\nexport interface PaymentCallOptions {\n provider?: PaymentProvider\n userId?: EntryId\n idempotencyKey?: string\n}\n\nexport interface NormalizedPaymentWebhook {\n eventId: string\n paymentId?: string\n rawEventType: string\n txType: PaymentTransactionType | null\n userId?: string\n customerId?: string\n subscriptionId?: string\n subscriptionStatus?: SubscriptionStatus\n planId?: string\n productId?: string\n amount?: number\n currency?: string\n currentPeriodStart?: string\n currentPeriodEnd?: string\n cancelAtPeriodEnd?: boolean\n resetPeriodUsage?: boolean\n}\n", "import { createHash, createHmac, timingSafeEqual } from 'node:crypto'\nimport {\n getPlanDefinition, getProductDefinition, type CustomLineItem, type EnvScopedString, type NormalizedPaymentWebhook,\n type PaymentProvider, type PaymentTransactionType, type PlanDefinition, type PlanQuotaSpec, type SubscriptionStatus\n} from './schema'\n\nexport const resolveEnvScopedValue = (val: EnvScopedString | undefined, isDev: boolean): string | undefined =>\n typeof val === 'string' ? val : val ? (isDev ? val.dev : val.prod) : undefined\n\nexport const currentPeriodKey = (periodStartIso?: string): string =>\n periodStartIso && /^\\d{4}-\\d{2}/.test(periodStartIso) ? periodStartIso.slice(0, 7) : new Date().toISOString().slice(0, 7)\n\nexport const paymentUsageDocId = (userId: string, periodKey: string): string => `${userId}_${periodKey}`\n\nexport const paymentTxDocId = (provider: PaymentProvider, externalId: string): string =>\n `tx_${createHash('sha256').update(`${provider}:${externalId}`).digest('hex').slice(0, 40)}`\n\nexport const idempotencyPaymentKey = (prefix: string, rawKey?: string): string | undefined =>\n rawKey ? `${prefix}_${createHash('sha256').update(rawKey.trim()).digest('hex').slice(0, 32)}` : undefined\n\nexport const defaultFallbackPlan = (defaultPlanId: string, defaultCurrency: string): PlanDefinition & { id: string; quota: PlanQuotaSpec } => ({\n id: defaultPlanId,\n name: defaultPlanId === 'free' ? 'Free Plan' : defaultPlanId,\n interval: 'free',\n amount: 0,\n currency: defaultCurrency.toLowerCase() as Lowercase<string>,\n quota: { overage: { enabled: false } }\n})\n\nexport const encodeStripeForm = (data: Record<string, unknown>, prefix = '', out = new URLSearchParams()): URLSearchParams => {\n for (const [key, value] of Object.entries(data)) {\n if (value === undefined || value === null) continue\n const formKey = prefix ? `${prefix}[${key}]` : key\n if (Array.isArray(value)) {\n value.forEach((item, idx) => {\n if (item !== null && typeof item === 'object') encodeStripeForm(item as Record<string, unknown>, `${formKey}[${idx}]`, out)\n else if (item !== undefined) out.append(`${formKey}[${idx}]`, String(item))\n })\n } else if (typeof value === 'object') {\n encodeStripeForm(value as Record<string, unknown>, formKey, out)\n } else {\n out.append(formKey, String(value))\n }\n }\n return out\n}\n\nconst executePaymentFetch = async <T>(label: string, url: string, method: string, headers: Record<string, string>, body?: string): Promise<T> => {\n const res = await fetch(url, { method, headers, ...(body ? { body } : {}), signal: AbortSignal.timeout(15_000) })\n if (!res.ok) {\n const err = new Error(`${label} HTTP ${res.status}: ${await res.text().catch(() => '')}`)\n ;(err as { status?: number }).status = res.status\n throw err\n }\n return (await res.json().catch(() => ({}))) as T\n}\n\nexport const requestStripeApi = async <T = Record<string, any>>(\n baseUrl: string,\n apiKey: string,\n apiVersion: string,\n method: string,\n path: string,\n formParams?: Record<string, unknown>,\n idempotencyKey?: string\n): Promise<T> => {\n const url = `${baseUrl.replace(/\\/+$/, '')}${path.startsWith('/') ? path : `/${path}`}`\n const isGet = method.toUpperCase() === 'GET'\n const encoded = formParams ? encodeStripeForm(formParams).toString() : ''\n return executePaymentFetch<T>(\n 'Stripe',\n isGet && encoded ? `${url}?${encoded}` : url,\n method.toUpperCase(),\n {\n Authorization: `Bearer ${apiKey}`,\n 'Stripe-Version': apiVersion,\n ...(!isGet ? { 'content-type': 'application/x-www-form-urlencoded' } : {}),\n ...(idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : {})\n },\n !isGet && encoded ? encoded : undefined\n )\n}\n\nexport const requestDodoApi = async <T = Record<string, any>>(\n baseUrl: string,\n apiKey: string,\n method: string,\n path: string,\n body?: unknown,\n idempotencyKey?: string\n): Promise<T> => {\n const url = `${baseUrl.replace(/\\/+$/, '')}${path.startsWith('/') ? path : `/${path}`}`\n const isGet = method.toUpperCase() === 'GET'\n return executePaymentFetch<T>(\n 'Dodo',\n url,\n method.toUpperCase(),\n { Authorization: `Bearer ${apiKey}`, 'content-type': 'application/json', ...(idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : {}) },\n !isGet && body !== undefined ? JSON.stringify(body) : undefined\n )\n}\n\nconst constantTimeEqual = (a: string, b: string): boolean => {\n if (!a || !b) return false\n const bufA = createHash('sha256').update(a).digest()\n const bufB = createHash('sha256').update(b).digest()\n return timingSafeEqual(bufA, bufB)\n}\n\nconst getHeader = (headers: Record<string, string | undefined>, name: string): string | undefined => {\n const lower = name.toLowerCase()\n for (const [k, v] of Object.entries(headers)) {\n if (k.toLowerCase() === lower && v) return v.trim()\n }\n return undefined\n}\n\nexport const verifyStripeWebhookHmac = (\n rawBody: string,\n headers: Record<string, string | undefined>,\n secret: string,\n toleranceSeconds: number\n): Record<string, any> => {\n const sigHeader = getHeader(headers, 'stripe-signature')\n if (!sigHeader || !secret) {\n throw new Error('Missing Stripe-Signature header or webhook secret')\n }\n const parts = sigHeader.split(',').map((p) => p.trim())\n const tsPart = parts.find((p) => p.startsWith('t='))?.slice(2)\n const v1Sigs = parts.filter((p) => p.startsWith('v1=')).map((p) => p.slice(3))\n if (!tsPart || v1Sigs.length === 0) {\n throw new Error('Malformed Stripe-Signature header')\n }\n const tsSeconds = Number(tsPart)\n const nowSeconds = Math.floor(Date.now() / 1000)\n if (!Number.isFinite(tsSeconds) || Math.abs(nowSeconds - tsSeconds) > toleranceSeconds) {\n throw new Error('Stripe webhook timestamp outside tolerance window')\n }\n const expectedHex = createHmac('sha256', secret).update(`${tsPart}.${rawBody}`, 'utf8').digest('hex')\n if (!v1Sigs.some((sig) => constantTimeEqual(sig, expectedHex))) {\n throw new Error('Invalid Stripe webhook HMAC signature')\n }\n return JSON.parse(rawBody) as Record<string, any>\n}\n\nexport const verifyDodoWebhookHmac = (\n rawBody: string,\n headers: Record<string, string | undefined>,\n secret: string,\n toleranceSeconds: number\n): Record<string, any> => {\n const msgId = getHeader(headers, 'webhook-id') ?? getHeader(headers, 'svix-id')\n const msgTimestamp = getHeader(headers, 'webhook-timestamp') ?? getHeader(headers, 'svix-timestamp')\n const msgSignature = getHeader(headers, 'webhook-signature') ?? getHeader(headers, 'svix-signature')\n if (!msgId || !msgTimestamp || !msgSignature || !secret) {\n throw new Error('Missing Dodo Standard Webhooks signature headers or secret')\n }\n const tsSeconds = Number(msgTimestamp)\n const nowSeconds = Math.floor(Date.now() / 1000)\n if (!Number.isFinite(tsSeconds) || Math.abs(nowSeconds - tsSeconds) > toleranceSeconds) {\n throw new Error('Dodo webhook timestamp outside tolerance window')\n }\n const signedContent = `${msgId}.${msgTimestamp}.${rawBody}`\n const rawSecret = secret.startsWith('whsec_') ? secret.slice(6) : secret\n const expectedDecoded = createHmac('sha256', Buffer.from(rawSecret, 'base64'))\n .update(signedContent, 'utf8')\n .digest('base64')\n const expectedUtf8 = createHmac('sha256', Buffer.from(secret, 'utf8'))\n .update(signedContent, 'utf8')\n .digest('base64')\n const candidates = msgSignature\n .split(/\\s+/)\n .map((part) => (part.startsWith('v1,') ? part.slice(3) : part.trim()))\n .filter(Boolean)\n if (!candidates.some((sig) => constantTimeEqual(sig, expectedDecoded) || constantTimeEqual(sig, expectedUtf8))) {\n throw new Error('Invalid Dodo webhook HMAC signature')\n }\n const parsed = JSON.parse(rawBody) as Record<string, any>\n return { ...parsed, _webhookId: msgId }\n}\n\nconst STRIPE_EVENT_TX_MAP: Record<string, PaymentTransactionType> = {\n 'checkout.session.completed': 'checkout.completed',\n 'payment_intent.succeeded': 'payment.succeeded',\n 'payment_intent.payment_failed': 'payment.failed',\n 'invoice.created': 'invoice.created',\n 'invoice.paid': 'invoice.paid',\n 'invoice.payment_failed': 'subscription.past_due',\n 'customer.subscription.created': 'subscription.active',\n 'customer.subscription.updated': 'subscription.tier_changed',\n 'customer.subscription.deleted': 'subscription.cancelled'\n}\n\nconst DODO_EVENT_TX_MAP: Record<string, PaymentTransactionType> = {\n 'payment.succeeded': 'payment.succeeded',\n 'payment.failed': 'payment.failed',\n 'subscription.active': 'subscription.active',\n 'subscription.renewed': 'subscription.renewed',\n 'subscription.plan_changed': 'subscription.tier_changed',\n 'subscription.on_hold': 'subscription.past_due',\n 'subscription.cancelled': 'subscription.cancelled',\n 'subscription.expired': 'subscription.cancelled'\n}\n\nconst mapSubStatus = (rawStatus?: string): SubscriptionStatus | undefined => {\n if (!rawStatus) return undefined\n const s = rawStatus.toLowerCase()\n if (s === 'active') return 'active'\n if (s === 'trialing') return 'trialing'\n if (s === 'past_due' || s === 'unpaid') return 'past_due'\n if (s === 'on_hold' || s === 'paused') return 'on_hold'\n if (s === 'canceled' || s === 'cancelled') return 'cancelled'\n if (s === 'expired' || s === 'incomplete_expired') return 'expired'\n return undefined\n}\n\nconst toIsoIfEpochOrString = (val: unknown): string | undefined => {\n if (typeof val === 'number' && Number.isFinite(val)) {\n return new Date(val > 1e11 ? val : val * 1000).toISOString()\n }\n if (typeof val === 'string' && val.trim()) {\n const d = new Date(val)\n return Number.isNaN(d.getTime()) ? undefined : d.toISOString()\n }\n return undefined\n}\n\nexport const normalizePaymentWebhook = (\n provider: PaymentProvider,\n rawBody: string,\n headers: Record<string, string | undefined>,\n secret: string,\n toleranceSeconds: number\n): NormalizedPaymentWebhook => {\n const raw =\n provider === 'stripe'\n ? verifyStripeWebhookHmac(rawBody, headers, secret, toleranceSeconds)\n : verifyDodoWebhookHmac(rawBody, headers, secret, toleranceSeconds)\n\n const rawEventType = String(raw.type ?? raw.event_type ?? '')\n const obj = (raw.data?.object ?? raw.data ?? raw) as Record<string, any>\n const meta = (obj.metadata ?? raw.metadata ?? {}) as Record<string, string | undefined>\n const eventId = String(raw.id ?? raw.event_id ?? raw._webhookId ?? obj.id ?? `evt_${Date.now()}`)\n const txType =\n (provider === 'stripe' ? STRIPE_EVENT_TX_MAP[rawEventType] : DODO_EVENT_TX_MAP[rawEventType]) ?? null\n const paymentId =\n typeof obj.payment_intent === 'string'\n ? obj.payment_intent\n : typeof obj.payment_id === 'string'\n ? obj.payment_id\n : txType === 'payment.succeeded' && typeof obj.id === 'string'\n ? obj.id\n : undefined\n\n const customerId =\n typeof obj.customer === 'string'\n ? obj.customer\n : typeof obj.customer?.customer_id === 'string'\n ? obj.customer.customer_id\n : typeof obj.customer_id === 'string'\n ? obj.customer_id\n : undefined\n\n const subscriptionId =\n typeof obj.subscription === 'string'\n ? obj.subscription\n : typeof obj.subscription_id === 'string'\n ? obj.subscription_id\n : rawEventType.includes('subscription') && typeof obj.id === 'string'\n ? obj.id\n : undefined\n\n const subStatus =\n mapSubStatus(obj.status) ??\n (txType === 'subscription.active' || txType === 'subscription.renewed'\n ? 'active'\n : txType === 'subscription.cancelled'\n ? 'cancelled'\n : txType === 'subscription.past_due'\n ? 'past_due'\n : undefined)\n\n const amountRaw = obj.amount_total ?? obj.amount_paid ?? obj.amount ?? obj.total_amount\n const amount = typeof amountRaw === 'number' ? Math.round(amountRaw) : undefined\n const currency = typeof obj.currency === 'string' ? obj.currency.toLowerCase() : undefined\n const currentPeriodStart = toIsoIfEpochOrString(obj.current_period_start ?? obj.previous_billing_date)\n const currentPeriodEnd = toIsoIfEpochOrString(obj.current_period_end ?? obj.next_billing_date)\n const cancelAtPeriodEnd =\n typeof obj.cancel_at_period_end === 'boolean'\n ? obj.cancel_at_period_end\n : typeof obj.cancel_at_next_billing_date === 'boolean'\n ? obj.cancel_at_next_billing_date\n : undefined\n\n return {\n eventId,\n ...(paymentId ? { paymentId } : {}),\n rawEventType,\n txType,\n ...(meta.userId ? { userId: meta.userId } : {}),\n ...(customerId ? { customerId } : {}),\n ...(subscriptionId ? { subscriptionId } : {}),\n ...(subStatus ? { subscriptionStatus: subStatus } : {}),\n ...(meta.planId ? { planId: meta.planId } : {}),\n ...(meta.productId ? { productId: meta.productId } : {}),\n ...(amount !== undefined ? { amount } : {}),\n ...(currency ? { currency } : {}),\n ...(currentPeriodStart ? { currentPeriodStart } : {}),\n ...(currentPeriodEnd ? { currentPeriodEnd } : {}),\n ...(cancelAtPeriodEnd !== undefined ? { cancelAtPeriodEnd } : {}),\n resetPeriodUsage: txType === 'subscription.renewed' || rawEventType === 'invoice.paid'\n }\n}\n\nexport interface ResolvedPurchaseItem {\n kind: 'product' | 'plan' | 'custom'\n id?: string\n name: string\n description?: string\n amount: number\n currency: string\n quantity: number\n interval?: 'month' | 'year' | 'free'\n stripePriceId?: string\n dodoProductId?: string\n metadata: Record<string, string>\n}\n\nexport const resolvePurchaseItem = (\n input: {\n product?: string\n plan?: string\n custom?: CustomLineItem\n quantity?: number\n amount?: number\n currency?: string\n description?: string\n metadata?: Record<string, string>\n },\n userId: string,\n isDev: boolean,\n defaultCurrency: string\n): ResolvedPurchaseItem | { error: string } => {\n const quantity = input.quantity ?? input.custom?.quantity ?? 1\n if (input.product) {\n const prod = getProductDefinition(input.product)\n if (!prod) return { error: `Unknown product alias: ${input.product}` }\n const stripePriceId = resolveEnvScopedValue(prod.providers?.stripe?.priceId, isDev)\n const dodoProductId = resolveEnvScopedValue(prod.providers?.dodo?.productId, isDev)\n return {\n kind: 'product',\n id: prod.id,\n name: prod.name,\n ...(prod.description ? { description: prod.description } : {}),\n amount: prod.amount,\n currency: (prod.currency ?? defaultCurrency).toLowerCase(),\n quantity,\n ...(stripePriceId ? { stripePriceId } : {}),\n ...(dodoProductId ? { dodoProductId } : {}),\n metadata: { ...prod.metadata, ...input.metadata, userId, productId: prod.id }\n }\n }\n if (input.plan) {\n const plan = getPlanDefinition(input.plan)\n if (!plan) return { error: `Unknown plan alias: ${input.plan}` }\n const stripePriceId = resolveEnvScopedValue(plan.providers?.stripe?.priceId, isDev)\n const dodoProductId = resolveEnvScopedValue(plan.providers?.dodo?.productId, isDev)\n return {\n kind: 'plan',\n id: plan.id,\n name: plan.name,\n ...(plan.description ? { description: plan.description } : {}),\n amount: plan.amount,\n currency: (plan.currency ?? defaultCurrency).toLowerCase(),\n quantity,\n interval: plan.interval,\n ...(stripePriceId ? { stripePriceId } : {}),\n ...(dodoProductId ? { dodoProductId } : {}),\n metadata: { ...plan.metadata, ...input.metadata, userId, planId: plan.id }\n }\n }\n const c = input.custom\n const amount = c?.amount ?? input.amount ?? 0\n const name = c?.name ?? input.description ?? 'Custom Purchase'\n const description = c?.description ?? input.description\n return {\n kind: 'custom',\n name,\n ...(description ? { description } : {}),\n amount,\n currency: (c?.currency ?? input.currency ?? defaultCurrency).toLowerCase(),\n quantity,\n metadata: { ...input.metadata, userId }\n }\n}\n\nexport const buildStripeLineItem = (item: ResolvedPurchaseItem): Record<string, unknown> =>\n item.stripePriceId\n ? { price: item.stripePriceId, quantity: item.quantity }\n : {\n quantity: item.quantity,\n price_data: {\n currency: item.currency,\n unit_amount: item.amount,\n product_data: {\n name: item.name,\n ...(item.description ? { description: item.description } : {})\n },\n ...(item.kind === 'plan' && item.interval && item.interval !== 'free'\n ? { recurring: { interval: item.interval } }\n : {})\n }\n }\n\nexport const buildDodoCartOrCustom = (item: ResolvedPurchaseItem): Record<string, unknown> =>\n item.dodoProductId\n ? { product_cart: [{ product_id: item.dodoProductId, quantity: item.quantity }] }\n : {\n billing_currency: item.currency,\n custom_item: {\n name: item.name,\n ...(item.description ? { description: item.description } : {}),\n amount: item.amount * item.quantity,\n currency: item.currency,\n quantity: item.quantity\n }\n }\n\nexport const computeUsageDelta = (\n usageData: Record<string, unknown>,\n custData: Record<string, unknown>,\n plan: PlanDefinition & { quota: PlanQuotaSpec },\n parsed: { metric: string; amount: number; inputTokens?: number; outputTokens?: number },\n skipMutation = false\n) => {\n let aiTokensUsed = Number(usageData.aiTokensUsed ?? 0)\n let aiInputTokens = Number(usageData.aiInputTokens ?? 0)\n let aiOutputTokens = Number(usageData.aiOutputTokens ?? 0)\n let overageTokensReported = Number(usageData.overageTokensReported ?? 0)\n let bonusAiTokens = Number(custData.bonusAiTokens ?? 0)\n const metricsUsed: Record<string, number> = { ...(usageData.metricsUsed as Record<string, number> | undefined) }\n const bonusMetrics: Record<string, number> = { ...(custData.bonusMetrics as Record<string, number> | undefined) }\n let overageDelta = 0\n if (skipMutation) return { aiTokensUsed, aiInputTokens, aiOutputTokens, overageTokensReported, bonusAiTokens, metricsUsed, bonusMetrics, overageDelta }\n\n if (parsed.metric === 'ai_tokens') {\n const limit = plan.quota.aiTokens\n const prevUncovered = typeof limit === 'number' ? Math.max(0, aiTokensUsed - limit) : 0\n aiTokensUsed += Math.round(parsed.amount)\n aiInputTokens += parsed.inputTokens ?? 0\n aiOutputTokens += parsed.outputTokens ?? 0\n const nextUncovered = typeof limit === 'number' ? Math.max(0, aiTokensUsed - limit) : 0\n const uncoveredIncrease = Math.max(0, nextUncovered - prevUncovered)\n const bonusDeducted = Math.min(bonusAiTokens, uncoveredIncrease)\n bonusAiTokens -= bonusDeducted\n overageDelta = uncoveredIncrease - bonusDeducted\n if (overageDelta > 0 && plan.quota.overage?.enabled) overageTokensReported += overageDelta\n } else {\n const limit = plan.quota.metrics?.[parsed.metric]\n const prev = metricsUsed[parsed.metric] ?? 0\n const prevUncovered = typeof limit === 'number' ? Math.max(0, prev - limit) : 0\n const next = prev + parsed.amount\n metricsUsed[parsed.metric] = next\n const nextUncovered = typeof limit === 'number' ? Math.max(0, next - limit) : 0\n const uncoveredIncrease = Math.max(0, nextUncovered - prevUncovered)\n const availBonus = bonusMetrics[parsed.metric] ?? 0\n const bonusDeducted = Math.min(availBonus, uncoveredIncrease)\n if (bonusDeducted > 0) bonusMetrics[parsed.metric] = availBonus - bonusDeducted\n }\n return { aiTokensUsed, aiInputTokens, aiOutputTokens, overageTokensReported, bonusAiTokens, metricsUsed, bonusMetrics, overageDelta }\n}\n\n", "import type { EntryId, SelectModel } from '../db'\nimport type { Core } from '../index'\nimport {\n cancelSubscriptionInput, changeTierInput, createCheckoutInput, createInvoiceInput, createPaymentLinkInput, directChargeInput,\n getPlanDefinition, getProductDefinition, subscribeInput, type CancelSubscriptionInput, type ChangeTierInput, type ChargeResult,\n type CheckoutSessionResult, type CreateCheckoutInput, type CreateInvoiceInput, type CreatePaymentLinkInput, type DirectChargeInput,\n type InvoiceResult, type PaymentCallOptions, type PaymentLinkResult, type PaymentProvider, type SubscribeInput, type SubscribeResult, type SubscriptionRecord\n} from './schema'\nimport {\n buildDodoCartOrCustom, buildStripeLineItem, currentPeriodKey, idempotencyPaymentKey, paymentUsageDocId,\n requestDodoApi, requestStripeApi, resolveEnvScopedValue, resolvePurchaseItem, type ResolvedPurchaseItem\n} from './utils'\n\nexport class PaymentsBillingEngine {\n readonly #core: Core\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n }\n\n resolveProvider = (override?: PaymentProvider): PaymentProvider => {\n if (override) return override\n const preferred = this.#core.config.payments.provider\n const isDev = Boolean(this.#core.env.isDev)\n const env = this.#core.env\n const hasStripe = Boolean((isDev ? env.STRIPE_SANDBOX_API_KEY : env.STRIPE_API_KEY) || env.STRIPE_API_KEY || env.STRIPE_SANDBOX_API_KEY)\n const hasDodo = Boolean((isDev ? env.DODO_SANDBOX_API_KEY : env.DODO_API_KEY) || env.DODO_API_KEY || env.DODO_SANDBOX_API_KEY)\n if (preferred === 'dodo' && !hasDodo && hasStripe) return 'stripe'\n if (preferred === 'stripe' && !hasStripe && hasDodo) return 'dodo'\n return preferred\n }\n\n getCreds = (provider: PaymentProvider) => {\n const isDev = Boolean(this.#core.env.isDev)\n const cfg = this.#core.config.payments\n const env = this.#core.env\n if (provider === 'stripe') {\n const apiKey = (isDev && env.STRIPE_SANDBOX_API_KEY ? env.STRIPE_SANDBOX_API_KEY : env.STRIPE_API_KEY || env.STRIPE_SANDBOX_API_KEY).trim()\n const webhookSecret = (isDev && env.STRIPE_SANDBOX_WEBHOOK_SECRET ? env.STRIPE_SANDBOX_WEBHOOK_SECRET : env.STRIPE_WEBHOOK_SECRET || env.STRIPE_SANDBOX_WEBHOOK_SECRET).trim()\n return { apiKey, webhookSecret, baseUrl: cfg.stripe.baseUrl, isSyntheticDev: isDev && !apiKey }\n }\n const apiKey = (isDev && env.DODO_SANDBOX_API_KEY ? env.DODO_SANDBOX_API_KEY : env.DODO_API_KEY || env.DODO_SANDBOX_API_KEY).trim()\n const webhookSecret = (isDev && env.DODO_SANDBOX_WEBHOOK_SECRET ? env.DODO_SANDBOX_WEBHOOK_SECRET : env.DODO_WEBHOOK_SECRET || env.DODO_SANDBOX_WEBHOOK_SECRET).trim()\n return { apiKey, webhookSecret, baseUrl: isDev ? cfg.dodo.testBaseUrl : cfg.dodo.liveBaseUrl, isSyntheticDev: isDev && !apiKey }\n }\n\n #withBreaker = async <T>(cost: number, fn: () => Promise<T>): Promise<T> => {\n await this.#core.internals.resilience.acquireLimit('payments', cost)\n return this.#core.internals.resilience.circuitBreaker('payments', fn, undefined, { isDev: this.#core.env.isDev })\n }\n\n stripeCall = <T = Record<string, any>>(method: string, path: string, form?: Record<string, unknown>, idempotencyKey?: string): Promise<T> => {\n const { baseUrl, apiKey } = this.getCreds('stripe')\n return this.#withBreaker(1, () => requestStripeApi<T>(baseUrl, apiKey, this.#core.config.payments.stripe.apiVersion, method, path, form, idempotencyKey))\n }\n\n dodoCall = <T = Record<string, any>>(method: string, path: string, body?: unknown, idempotencyKey?: string): Promise<T> => {\n const { baseUrl, apiKey } = this.getCreds('dodo')\n return this.#withBreaker(1, () => requestDodoApi<T>(baseUrl, apiKey, method, path, body, idempotencyKey))\n }\n\n #resolveItem = (rawInput: Parameters<typeof resolvePurchaseItem>[0], userId: string): ResolvedPurchaseItem => {\n const res = resolvePurchaseItem(rawInput, userId, Boolean(this.#core.env.isDev), this.#core.config.payments.defaultCurrency)\n if ('error' in res) return this.#core.errors.httpError(400, res.error, 'INVALID_PAYMENT_ITEM')\n return res\n }\n\n ensureCustomer = async (userId: EntryId, provider: PaymentProvider): Promise<{ doc: SelectModel<'payment_customer'>; providerCustomerId: string }> =>\n this.#core.internals.resilience.singleflight(\n `pay_cust:${provider}:${userId}`,\n async () => {\n const defaultPlanId = this.#core.config.payments.defaultPlanId\n let doc = await this.#core.db.read('payment_customer', userId, false, { bypassRbac: true })\n if (!doc) {\n doc = await this.#core.db.create(\n 'payment_customer',\n { id: userId, userId, planId: defaultPlanId, subscriptionStatus: 'none', cancelAtPeriodEnd: false, bonusAiTokens: 0, credits: 0, bonusMetrics: {} },\n { bypassRbac: true }\n )\n }\n const existingCusId = provider === 'stripe' ? doc.stripeCustomerId : doc.dodoCustomerId\n if (existingCusId) return { doc, providerCustomerId: existingCusId }\n\n let providerCustomerId = `cus_dev_${provider}_${userId}`\n if (!this.getCreds(provider).isSyntheticDev) {\n const custIdemKey = `cust_${provider}_${userId}`\n const created =\n provider === 'stripe'\n ? await this.stripeCall('POST', '/customers', { ...(doc.email ? { email: doc.email } : {}), ...(doc.name ? { name: doc.name } : {}), metadata: { userId } }, custIdemKey)\n : await this.dodoCall('POST', '/customers', { email: doc.email ?? `${userId}@customer.local`, name: doc.name ?? userId, metadata: { userId } }, custIdemKey)\n providerCustomerId = String(created.id ?? created.customer_id ?? providerCustomerId)\n }\n const patch = provider === 'stripe' ? { stripeCustomerId: providerCustomerId, activeProvider: provider } : { dodoCustomerId: providerCustomerId, activeProvider: provider }\n await this.#core.db.update('payment_customer', userId, patch, { bypassRbac: true })\n return { doc: { ...doc, ...patch }, providerCustomerId }\n },\n { scope: 'global' }\n )\n\n applyProductGrants = async (userId: EntryId, productId?: string, grantKey?: string): Promise<void> => {\n const prod = productId ? getProductDefinition(productId) : undefined\n if (!prod?.grants) return\n const db = this.#core.db.firestore()\n const custRef = db.collection('payment_customer').doc(userId)\n const grantRef = grantKey ? db.collection('_idempotency').doc(`pay_grant_${userId}_${grantKey.replace(/[^A-Za-z0-9_-]/g, '_').slice(0, 96)}`) : undefined\n await this.#core.internals.resilience.acquireLimit('firestore')\n await db.runTransaction(async (tx) => {\n const [custSnap, grantSnap] = await Promise.all([tx.get(custRef), grantRef ? tx.get(grantRef) : Promise.resolve(undefined)])\n if (grantSnap?.exists) return\n const data = custSnap.data() ?? {}\n const bonusMetrics: Record<string, number> = { ...(data.bonusMetrics ?? {}) }\n for (const [m, delta] of Object.entries(prod.grants?.metrics ?? {})) bonusMetrics[m] = (bonusMetrics[m] ?? 0) + delta\n const now = new Date()\n if (grantRef) tx.set(grantRef, { key: grantRef.id, userId, productId, createdAt: now, expiresAt: new Date(now.getTime() + 86_400_000) })\n tx.set(\n custRef,\n {\n id: userId,\n userId,\n planId: data.planId ?? this.#core.config.payments.defaultPlanId,\n subscriptionStatus: data.subscriptionStatus ?? 'none',\n cancelAtPeriodEnd: Boolean(data.cancelAtPeriodEnd),\n bonusAiTokens: Number(data.bonusAiTokens ?? 0) + (prod.grants?.aiTokens ?? 0),\n credits: Number(data.credits ?? 0) + (prod.grants?.credits ?? 0),\n bonusMetrics,\n deleted: false,\n createdAt: data.createdAt ?? now,\n updatedAt: now\n },\n { merge: true }\n )\n })\n }\n\n createCheckout = async (rawInput: CreateCheckoutInput, opts?: PaymentCallOptions): Promise<CheckoutSessionResult> => {\n const parsed = createCheckoutInput.parse(rawInput)\n const userId = opts?.userId ?? this.#core.userId\n const provider = this.resolveProvider(opts?.provider)\n const isDev = Boolean(this.#core.env.isDev)\n const item = this.#resolveItem(parsed, userId)\n const { providerCustomerId } = await this.ensureCustomer(userId, provider)\n const cfgUrls = this.#core.config.payments.urls\n const successUrl = parsed.successUrl ?? resolveEnvScopedValue(cfgUrls.successUrl, isDev) ?? 'https://localhost/success'\n const cancelUrl = parsed.cancelUrl ?? resolveEnvScopedValue(cfgUrls.cancelUrl, isDev) ?? 'https://localhost/cancel'\n const idemKey = idempotencyPaymentKey('chk', parsed.idempotencyKey ?? opts?.idempotencyKey)\n\n if (this.getCreds(provider).isSyntheticDev) {\n const checkoutId = `chk_dev_${crypto.randomUUID().replace(/-/g, '').slice(0, 16)}`\n return { checkoutId, url: `${successUrl}?session_id=${checkoutId}`, provider }\n }\n if (provider === 'stripe') {\n const res = await this.stripeCall(\n 'POST',\n '/checkout/sessions',\n {\n mode: item.kind === 'plan' ? 'subscription' : 'payment',\n customer: providerCustomerId,\n success_url: successUrl,\n cancel_url: cancelUrl,\n line_items: [buildStripeLineItem(item)],\n metadata: item.metadata\n },\n idemKey\n )\n return {\n checkoutId: String(res.id ?? `cs_${Date.now()}`),\n url: String(res.url ?? `${successUrl}?session_id=${res.id}`),\n provider: 'stripe',\n ...(typeof res.expires_at === 'number' ? { expiresAt: new Date(res.expires_at * 1000).toISOString() } : {})\n }\n }\n const res = await this.dodoCall(\n 'POST',\n '/checkouts',\n { customer: { customer_id: providerCustomerId }, return_url: successUrl, ...buildDodoCartOrCustom(item), metadata: item.metadata },\n idemKey\n )\n const checkoutId = String(res.checkout_id ?? res.session_id ?? res.id ?? `chk_${Date.now()}`)\n return { checkoutId, url: String(res.checkout_url ?? res.payment_link ?? res.url ?? `${successUrl}?session_id=${checkoutId}`), provider: 'dodo' }\n }\n\n createPaymentLink = async (rawInput: CreatePaymentLinkInput, opts?: PaymentCallOptions): Promise<PaymentLinkResult> => {\n const parsed = createPaymentLinkInput.parse(rawInput)\n const userId = opts?.userId ?? this.#core.userId\n const provider = this.resolveProvider(opts?.provider)\n const isDev = Boolean(this.#core.env.isDev)\n const item = this.#resolveItem(parsed, userId)\n const { providerCustomerId } = await this.ensureCustomer(userId, provider)\n const returnUrl = parsed.returnUrl ?? resolveEnvScopedValue(this.#core.config.payments.urls.returnUrl, isDev) ?? 'https://localhost/billing'\n const idemKey = idempotencyPaymentKey('pl', parsed.idempotencyKey ?? opts?.idempotencyKey)\n\n if (this.getCreds(provider).isSyntheticDev) {\n const paymentLinkId = `pl_dev_${crypto.randomUUID().replace(/-/g, '').slice(0, 16)}`\n return { paymentLinkId, url: `${returnUrl}?payment_link=${paymentLinkId}`, provider }\n }\n if (provider === 'stripe') {\n const res = await this.stripeCall(\n 'POST',\n '/payment_links',\n { line_items: [buildStripeLineItem(item)], after_completion: { type: 'redirect', redirect: { url: returnUrl } }, metadata: item.metadata },\n idemKey\n )\n return { paymentLinkId: String(res.id ?? `plink_${Date.now()}`), url: String(res.url ?? `${returnUrl}?payment_link=${res.id}`), provider: 'stripe' }\n }\n const res = await this.dodoCall(\n 'POST',\n '/payments',\n { payment_link: true, customer: { customer_id: providerCustomerId }, return_url: returnUrl, ...buildDodoCartOrCustom(item), metadata: item.metadata },\n idemKey\n )\n const paymentLinkId = String(res.payment_id ?? res.id ?? `plink_${Date.now()}`)\n return { paymentLinkId, url: String(res.payment_link ?? res.url ?? `${returnUrl}?payment_link=${paymentLinkId}`), provider: 'dodo' }\n }\n\n createInvoice = async (rawInput: CreateInvoiceInput, opts?: PaymentCallOptions): Promise<InvoiceResult> => {\n const parsed = createInvoiceInput.parse(rawInput)\n const userId = opts?.userId ?? this.#core.userId\n const provider = this.resolveProvider(opts?.provider)\n const item = this.#resolveItem(parsed, userId)\n const totalAmount = item.amount * item.quantity\n const { providerCustomerId } = await this.ensureCustomer(userId, provider)\n const idemKey = idempotencyPaymentKey('inv', parsed.idempotencyKey ?? opts?.idempotencyKey)\n\n if (this.getCreds(provider).isSyntheticDev) {\n const invoiceId = `inv_dev_${crypto.randomUUID().replace(/-/g, '').slice(0, 16)}`\n return {\n invoiceId,\n status: 'open',\n amount: totalAmount,\n currency: item.currency,\n hostedInvoiceUrl: `https://localhost/invoices/${invoiceId}`,\n pdfUrl: `https://localhost/invoices/${invoiceId}.pdf`,\n provider\n }\n }\n if (provider === 'stripe') {\n await this.stripeCall('POST', '/invoiceitems', { customer: providerCustomerId, amount: totalAmount, currency: item.currency, description: item.name })\n const draft = await this.stripeCall(\n 'POST',\n '/invoices',\n { customer: providerCustomerId, collection_method: 'send_invoice', days_until_due: parsed.daysUntilDue, metadata: item.metadata },\n idemKey\n )\n const invId = String(draft.id ?? `in_${Date.now()}`)\n const finalized = await this.stripeCall('POST', `/invoices/${invId}/finalize`)\n return {\n invoiceId: invId,\n status: 'open',\n amount: totalAmount,\n currency: item.currency,\n hostedInvoiceUrl: String(finalized.hosted_invoice_url ?? `https://invoice.stripe.com/i/${invId}`),\n ...(finalized.invoice_pdf ? { pdfUrl: String(finalized.invoice_pdf) } : {}),\n provider: 'stripe'\n }\n }\n const { baseUrl } = this.getCreds('dodo')\n const res = await this.dodoCall(\n 'POST',\n '/payments',\n {\n payment_link: true,\n generate_invoice: true,\n customer: { customer_id: providerCustomerId },\n billing: { amount: totalAmount, currency: item.currency, name: item.name, ...(item.description ? { description: item.description } : {}) },\n metadata: item.metadata\n },\n idemKey\n )\n const invoiceId = String(res.payment_id ?? res.invoice_id ?? res.id ?? `inv_${Date.now()}`)\n return {\n invoiceId,\n status: 'open',\n amount: totalAmount,\n currency: item.currency,\n hostedInvoiceUrl: String(res.payment_link ?? res.hosted_invoice_url ?? `${baseUrl}/invoices/${invoiceId}`),\n pdfUrl: String(res.pdf_url ?? `${baseUrl.replace(/\\/+$/, '')}/invoices/payments/${invoiceId}`),\n provider: 'dodo'\n }\n }\n\n charge = async (rawInput: DirectChargeInput, opts?: PaymentCallOptions): Promise<ChargeResult> => {\n const parsed = directChargeInput.parse(rawInput)\n const userId = opts?.userId ?? this.#core.userId\n const provider = this.resolveProvider(opts?.provider)\n const item = this.#resolveItem(parsed, userId)\n const totalAmount = item.amount * item.quantity\n const { providerCustomerId } = await this.ensureCustomer(userId, provider)\n const idemKey = idempotencyPaymentKey('chg', parsed.idempotencyKey ?? opts?.idempotencyKey)\n\n if (this.getCreds(provider).isSyntheticDev) {\n const chargeId = idemKey ? `chg_dev_${idemKey.slice(4, 20)}` : `chg_dev_${crypto.randomUUID().replace(/-/g, '').slice(0, 16)}`\n if (item.kind === 'product') await this.applyProductGrants(userId, item.id, chargeId)\n return { chargeId, status: 'succeeded', amount: totalAmount, currency: item.currency, provider }\n }\n if (provider === 'stripe') {\n const res = await this.stripeCall(\n 'POST',\n '/payment_intents',\n {\n customer: providerCustomerId,\n amount: totalAmount,\n currency: item.currency,\n description: item.name,\n ...(parsed.paymentMethodId ? { payment_method: parsed.paymentMethodId, confirm: true, off_session: true } : {}),\n metadata: item.metadata\n },\n idemKey\n )\n const chargeId = String(res.id ?? `pi_${Date.now()}`)\n const status = res.status === 'succeeded' ? 'succeeded' : res.status === 'canceled' ? 'failed' : 'requires_action'\n if (status === 'succeeded' && item.kind === 'product') await this.applyProductGrants(userId, item.id, chargeId)\n return {\n chargeId,\n status,\n amount: totalAmount,\n currency: item.currency,\n provider: 'stripe',\n ...(res.next_action?.redirect_to_url?.url ? { checkoutUrl: String(res.next_action.redirect_to_url.url) } : {}),\n ...(res.client_secret ? { clientSecret: String(res.client_secret) } : {})\n }\n }\n const res = await this.dodoCall(\n 'POST',\n '/payments',\n {\n customer: { customer_id: providerCustomerId },\n payment_link: !parsed.paymentMethodId,\n ...(parsed.paymentMethodId ? { payment_method_id: parsed.paymentMethodId } : {}),\n ...buildDodoCartOrCustom(item),\n metadata: item.metadata\n },\n idemKey\n )\n const chargeId = String(res.payment_id ?? res.id ?? `pay_${Date.now()}`)\n const status = res.status === 'succeeded' ? 'succeeded' : res.status === 'failed' ? 'failed' : 'requires_action'\n if (status === 'succeeded' && item.kind === 'product') await this.applyProductGrants(userId, item.id, chargeId)\n return {\n chargeId,\n status,\n amount: totalAmount,\n currency: item.currency,\n provider: 'dodo',\n ...(res.payment_link ? { checkoutUrl: String(res.payment_link) } : {})\n }\n }\n\n subscribe = async (rawInput: SubscribeInput, opts?: PaymentCallOptions): Promise<SubscribeResult> => {\n const parsed = subscribeInput.parse(rawInput)\n const userId = opts?.userId ?? this.#core.userId\n const provider = this.resolveProvider(opts?.provider)\n const isDev = Boolean(this.#core.env.isDev)\n const plan = getPlanDefinition(parsed.plan)\n if (!plan) return this.#core.errors.httpError(400, `Unknown plan alias: ${parsed.plan}`, 'INVALID_PLAN')\n\n const { providerCustomerId } = await this.ensureCustomer(userId, provider)\n const returnUrl = parsed.returnUrl ?? resolveEnvScopedValue(this.#core.config.payments.urls.returnUrl, isDev) ?? 'https://localhost/billing'\n const idemKey = idempotencyPaymentKey('sub', parsed.idempotencyKey ?? opts?.idempotencyKey)\n\n if (plan.interval === 'free' || plan.amount === 0 || this.getCreds(provider).isSyntheticDev) {\n const subscriptionId = `sub_dev_${plan.id}_${userId}`\n await this.#core.db.update(\n 'payment_customer',\n userId,\n { planId: plan.id, subscriptionId, subscriptionStatus: 'active', activeProvider: provider, cancelAtPeriodEnd: false },\n { bypassRbac: true }\n )\n return { subscriptionId, planId: plan.id, status: 'active', provider }\n }\n const item = this.#resolveItem({ plan: plan.id, metadata: parsed.metadata }, userId)\n const res =\n provider === 'stripe'\n ? await this.stripeCall(\n 'POST',\n '/subscriptions',\n {\n customer: providerCustomerId,\n items: [{ ...(item.stripePriceId ? { price: item.stripePriceId } : buildStripeLineItem(item)) }],\n payment_behavior: 'default_incomplete',\n metadata: item.metadata\n },\n idemKey\n )\n : await this.dodoCall(\n 'POST',\n '/subscriptions',\n { customer: { customer_id: providerCustomerId }, product_id: item.dodoProductId ?? plan.id, quantity: 1, payment_link: true, return_url: returnUrl, metadata: item.metadata },\n idemKey\n )\n const subscriptionId = String(res.subscription_id ?? res.id ?? `sub_${Date.now()}`)\n const status = res.status === 'active' ? 'active' : res.status === 'trialing' ? 'trialing' : 'requires_action'\n const checkoutUrl = res.payment_link ?? res.checkout_url\n await this.#core.db.update(\n 'payment_customer',\n userId,\n { planId: plan.id, subscriptionId, subscriptionStatus: status === 'requires_action' ? 'none' : status, activeProvider: provider },\n { bypassRbac: true }\n )\n return { subscriptionId, planId: plan.id, status, provider, ...(checkoutUrl ? { checkoutUrl: String(checkoutUrl) } : {}) }\n }\n\n changeSubscriptionTier = async (rawInput: ChangeTierInput, opts?: PaymentCallOptions): Promise<SubscriptionRecord> => {\n const parsed = changeTierInput.parse(rawInput)\n const userId = opts?.userId ?? this.#core.userId\n const plan = getPlanDefinition(parsed.plan)\n if (!plan) return this.#core.errors.httpError(400, `Unknown plan alias: ${parsed.plan}`, 'INVALID_PLAN')\n\n const cust = await this.#core.db.read('payment_customer', userId, false, { bypassRbac: true })\n if (!cust?.subscriptionId) return this.#core.errors.httpError(400, 'No active subscription to change tier', 'NO_ACTIVE_SUBSCRIPTION')\n const provider = this.resolveProvider(opts?.provider ?? cust.activeProvider)\n const isDev = Boolean(this.#core.env.isDev)\n const idemKey = idempotencyPaymentKey('tier', parsed.idempotencyKey ?? opts?.idempotencyKey)\n\n if (!this.getCreds(provider).isSyntheticDev) {\n if (provider === 'stripe') {\n const sub = await this.stripeCall('GET', `/subscriptions/${cust.subscriptionId}`)\n const itemId = sub.items?.data?.[0]?.id\n const priceId = resolveEnvScopedValue(plan.providers?.stripe?.priceId, isDev) ?? plan.id\n const prorationBehavior = parsed.proration === 'prorated_immediately' ? 'always_invoice' : parsed.proration === 'next_cycle' ? 'create_prorations' : 'none'\n await this.stripeCall(\n 'POST',\n `/subscriptions/${cust.subscriptionId}`,\n { items: [{ ...(itemId ? { id: itemId } : {}), price: priceId }], proration_behavior: prorationBehavior, metadata: { userId, planId: plan.id } },\n idemKey\n )\n } else {\n const productId = resolveEnvScopedValue(plan.providers?.dodo?.productId, isDev) ?? plan.id\n await this.dodoCall(\n 'POST',\n `/subscriptions/${cust.subscriptionId}/change-plan`,\n { product_id: productId, proration_billing_mode: parsed.proration, quantity: 1 },\n idemKey\n )\n }\n }\n\n await this.#core.db.update('payment_customer', userId, { planId: plan.id, subscriptionStatus: 'active', cancelAtPeriodEnd: false }, { bypassRbac: true })\n const usageId = paymentUsageDocId(userId, currentPeriodKey(cust.currentPeriodStart))\n const usageDoc = await this.#core.db.read('payment_usage', usageId, false, { bypassRbac: true })\n if (usageDoc) await this.#core.db.update('payment_usage', usageId, { planId: plan.id }, { bypassRbac: true })\n\n return {\n subscriptionId: cust.subscriptionId,\n planId: plan.id,\n status: 'active',\n provider,\n cancelAtPeriodEnd: false,\n ...(cust.currentPeriodStart ? { currentPeriodStart: cust.currentPeriodStart } : {}),\n ...(cust.currentPeriodEnd ? { currentPeriodEnd: cust.currentPeriodEnd } : {})\n }\n }\n\n cancelSubscription = async (rawInput: CancelSubscriptionInput = {}, opts?: PaymentCallOptions): Promise<SubscriptionRecord> => {\n const parsed = cancelSubscriptionInput.parse(rawInput)\n const userId = opts?.userId ?? this.#core.userId\n const cust = await this.#core.db.read('payment_customer', userId, false, { bypassRbac: true })\n if (!cust?.subscriptionId) return this.#core.errors.httpError(400, 'No active subscription to cancel', 'NO_ACTIVE_SUBSCRIPTION')\n const provider = this.resolveProvider(opts?.provider ?? cust.activeProvider)\n const idemKey = idempotencyPaymentKey('can', parsed.idempotencyKey ?? opts?.idempotencyKey)\n\n if (!this.getCreds(provider).isSyntheticDev) {\n if (provider === 'stripe') {\n await (parsed.immediately\n ? this.stripeCall('DELETE', `/subscriptions/${cust.subscriptionId}`, undefined, idemKey)\n : this.stripeCall('POST', `/subscriptions/${cust.subscriptionId}`, { cancel_at_period_end: true }, idemKey))\n } else {\n await this.dodoCall(\n 'PATCH',\n `/subscriptions/${cust.subscriptionId}`,\n parsed.immediately ? { status: 'cancelled' } : { cancel_at_next_billing_date: true },\n idemKey\n )\n }\n }\n\n const newStatus = parsed.immediately ? 'cancelled' : cust.subscriptionStatus === 'none' ? 'active' : cust.subscriptionStatus\n const newPlanId = parsed.immediately ? this.#core.config.payments.defaultPlanId : cust.planId\n await this.#core.db.update('payment_customer', userId, { planId: newPlanId, subscriptionStatus: newStatus, cancelAtPeriodEnd: !parsed.immediately }, { bypassRbac: true })\n return {\n subscriptionId: cust.subscriptionId,\n planId: newPlanId,\n status: newStatus,\n provider,\n cancelAtPeriodEnd: !parsed.immediately,\n ...(cust.currentPeriodStart ? { currentPeriodStart: cust.currentPeriodStart } : {}),\n ...(cust.currentPeriodEnd ? { currentPeriodEnd: cust.currentPeriodEnd } : {})\n }\n }\n}\n", "import type { EntryId } from '../db'\nimport type { Core } from '../index'\nimport { PaymentsBillingEngine } from './billing'\nimport {\n getPlanDefinition,\n getProductDefinition,\n recordUsageInput,\n type CancelSubscriptionInput,\n type ChangeTierInput,\n type ChargeResult,\n type CheckoutSessionResult,\n type CreateCheckoutInput,\n type CreateInvoiceInput,\n type CreatePaymentLinkInput,\n type CustomerBillingSummary,\n type DirectChargeInput,\n type InvoiceResult,\n type NormalizedPaymentWebhook,\n type PaymentCallOptions,\n type PaymentLinkResult,\n type PaymentProvider,\n type PaymentWebhookResult,\n type QuotaCheckResult,\n type RecordUsageInput,\n type SubscribeInput,\n type SubscribeResult,\n type SubscriptionRecord,\n type UsageStatusResult\n} from './schema'\nimport {\n computeUsageDelta,\n currentPeriodKey,\n defaultFallbackPlan,\n normalizePaymentWebhook,\n paymentTxDocId,\n paymentUsageDocId\n} from './utils'\n\nexport class PaymentsService {\n readonly #core: Core\n readonly #billing: PaymentsBillingEngine\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n this.#billing = new PaymentsBillingEngine(coreClient)\n }\n\n createCheckout = (input: CreateCheckoutInput, opts?: PaymentCallOptions): Promise<CheckoutSessionResult> =>\n this.#billing.createCheckout(input, opts)\n\n createPaymentLink = (input: CreatePaymentLinkInput, opts?: PaymentCallOptions): Promise<PaymentLinkResult> =>\n this.#billing.createPaymentLink(input, opts)\n\n createInvoice = (input: CreateInvoiceInput, opts?: PaymentCallOptions): Promise<InvoiceResult> =>\n this.#billing.createInvoice(input, opts)\n\n charge = (input: DirectChargeInput, opts?: PaymentCallOptions): Promise<ChargeResult> =>\n this.#billing.charge(input, opts)\n\n subscribe = (input: SubscribeInput, opts?: PaymentCallOptions): Promise<SubscribeResult> =>\n this.#billing.subscribe(input, opts)\n\n changeSubscriptionTier = (input: ChangeTierInput, opts?: PaymentCallOptions): Promise<SubscriptionRecord> =>\n this.#billing.changeSubscriptionTier(input, opts)\n\n cancelSubscription = (input?: CancelSubscriptionInput, opts?: PaymentCallOptions): Promise<SubscriptionRecord> =>\n this.#billing.cancelSubscription(input, opts)\n\n getSubscription = async (userId: EntryId = this.#core.userId): Promise<CustomerBillingSummary> => {\n const cfg = this.#core.config.payments\n const cust = await this.#core.db.read('payment_customer', userId, false, { bypassRbac: true })\n const planId = cust?.planId ?? cfg.defaultPlanId\n const plan = getPlanDefinition(planId) ?? defaultFallbackPlan(planId, cfg.defaultCurrency)\n return {\n userId,\n planId,\n plan: {\n id: plan.id,\n name: plan.name,\n interval: plan.interval,\n amount: plan.amount,\n currency: (plan.currency ?? cfg.defaultCurrency).toLowerCase()\n },\n status: cust?.subscriptionStatus ?? 'none',\n ...(cust?.subscriptionId ? { subscriptionId: cust.subscriptionId } : {}),\n ...(cust?.activeProvider ? { activeProvider: cust.activeProvider } : {}),\n ...(cust?.currentPeriodStart ? { currentPeriodStart: cust.currentPeriodStart } : {}),\n ...(cust?.currentPeriodEnd ? { currentPeriodEnd: cust.currentPeriodEnd } : {}),\n cancelAtPeriodEnd: Boolean(cust?.cancelAtPeriodEnd),\n bonusAiTokens: cust?.bonusAiTokens ?? 0,\n credits: cust?.credits ?? 0,\n bonusMetrics: cust?.bonusMetrics ?? {}\n }\n }\n\n getUsage = async (userId: EntryId = this.#core.userId): Promise<UsageStatusResult> => {\n const cfg = this.#core.config.payments\n const cust = await this.#core.db.read('payment_customer', userId, false, { bypassRbac: true })\n const planId = cust?.planId ?? cfg.defaultPlanId\n const plan = getPlanDefinition(planId) ?? defaultFallbackPlan(planId, cfg.defaultCurrency)\n const periodKey = currentPeriodKey(cust?.currentPeriodStart)\n const usage = await this.#core.db.read('payment_usage', paymentUsageDocId(userId, periodKey), false, {\n bypassRbac: true\n })\n return {\n userId,\n periodKey,\n planId,\n aiTokensUsed: usage?.aiTokensUsed ?? 0,\n aiTokensLimit: plan.quota.aiTokens ?? null,\n bonusAiTokens: cust?.bonusAiTokens ?? 0,\n overageTokensReported: usage?.overageTokensReported ?? 0,\n overageEnabled: Boolean(plan.quota.overage?.enabled),\n ...(plan.quota.overage?.maxOverageTokens !== undefined ? { maxOverageTokens: plan.quota.overage.maxOverageTokens } : {}),\n metricsUsed: usage?.metricsUsed ?? {},\n metricsLimits: plan.quota.metrics ?? {},\n bonusMetrics: cust?.bonusMetrics ?? {}\n }\n }\n\n checkQuota = async (\n metric = 'ai_tokens',\n requiredAmount = 1,\n userId: EntryId = this.#core.userId,\n throwOnExceeded = true\n ): Promise<QuotaCheckResult> => {\n const usage = await this.getUsage(userId)\n const isAi = metric === 'ai_tokens'\n const used = isAi ? usage.aiTokensUsed : (usage.metricsUsed[metric] ?? 0)\n const limit = isAi ? usage.aiTokensLimit : (usage.metricsLimits[metric] ?? null)\n const bonusRemaining = isAi ? usage.bonusAiTokens : (usage.bonusMetrics[metric] ?? 0)\n const overageEnabled = isAi ? usage.overageEnabled : false\n const maxOverage = isAi ? usage.maxOverageTokens : undefined\n\n if (limit === null) {\n return { allowed: true, metric, used, limit: null, bonusRemaining, overageEnabled, remaining: null }\n }\n const baseAndBonusCap = limit + bonusRemaining\n const hardCap = overageEnabled\n ? maxOverage !== undefined\n ? baseAndBonusCap + maxOverage\n : Number.POSITIVE_INFINITY\n : baseAndBonusCap\n const allowed = used + requiredAmount <= hardCap\n const remaining = Number.isFinite(hardCap) ? Math.max(0, hardCap - used) : null\n\n if (!allowed && throwOnExceeded) {\n return this.#core.errors.httpError(\n 402,\n `Payment Required: ${metric} quota exceeded for plan \"${usage.planId}\"`,\n 'QUOTA_EXCEEDED'\n )\n }\n return { allowed, metric, used, limit, bonusRemaining, overageEnabled, remaining }\n }\n\n #ingestMeterEvent = async (\n provider: PaymentProvider,\n providerCustomerId: string,\n eventName: string,\n value: number,\n idempotencyKey: string,\n metadata?: Record<string, string>\n ): Promise<void> => {\n if (this.#billing.getCreds(provider).isSyntheticDev || value <= 0) return\n if (provider === 'stripe') {\n await this.#billing.stripeCall(\n 'POST',\n '/billing/meter_events',\n {\n event_name: eventName,\n identifier: idempotencyKey,\n payload: { stripe_customer_id: providerCustomerId, value: String(Math.round(value)) }\n },\n idempotencyKey\n )\n return\n }\n await this.#billing.dodoCall(\n 'POST',\n '/events/ingest',\n {\n events: [\n {\n event_id: idempotencyKey,\n customer_id: providerCustomerId,\n event_name: eventName,\n timestamp: new Date().toISOString(),\n metadata: { ...metadata, value: String(Math.round(value)) }\n }\n ]\n },\n idempotencyKey\n )\n }\n\n recordUsage = async (rawInput: RecordUsageInput, opts?: PaymentCallOptions): Promise<UsageStatusResult> => {\n const parsed = recordUsageInput.parse(rawInput)\n const userId = opts?.userId ?? this.#core.userId\n const cfg = this.#core.config.payments\n const db = this.#core.db.firestore()\n const custRef = db.collection('payment_customer').doc(userId)\n const rawIdemKey = parsed.idempotencyKey ?? opts?.idempotencyKey\n\n await this.#core.internals.resilience.acquireLimit('firestore')\n const txOut = await db.runTransaction(async (tx) => {\n const idemRef = rawIdemKey\n ? db.collection('_idempotency').doc(`pay_usage_${userId}_${rawIdemKey.replace(/[^A-Za-z0-9_-]/g, '_').slice(0, 96)}`)\n : undefined\n const custSnap = await tx.get(custRef)\n const custData = custSnap.data() ?? {}\n const planId = String(custData.planId ?? cfg.defaultPlanId)\n const plan = getPlanDefinition(planId) ?? defaultFallbackPlan(planId, cfg.defaultCurrency)\n const periodKey = currentPeriodKey(custData.currentPeriodStart as string | undefined)\n const usageId = paymentUsageDocId(userId, periodKey)\n const usageRef = db.collection('payment_usage').doc(usageId)\n const [usageSnap, idemSnap] = await Promise.all([tx.get(usageRef), idemRef ? tx.get(idemRef) : Promise.resolve(undefined)])\n const usageData = usageSnap.data() ?? {}\n const delta = computeUsageDelta(usageData, custData, plan, parsed, Boolean(idemSnap?.exists))\n\n if (!idemSnap?.exists) {\n const now = new Date()\n if (idemRef) tx.set(idemRef, { key: idemRef.id, userId, createdAt: now, expiresAt: new Date(now.getTime() + 86_400_000) })\n tx.set(\n usageRef,\n {\n id: usageId,\n userId,\n periodKey,\n planId,\n aiTokensUsed: delta.aiTokensUsed,\n aiInputTokens: delta.aiInputTokens,\n aiOutputTokens: delta.aiOutputTokens,\n overageTokensReported: delta.overageTokensReported,\n metricsUsed: delta.metricsUsed,\n lastUpdatedAt: now.toISOString(),\n deleted: false,\n createdAt: usageData.createdAt ?? now,\n updatedAt: now\n },\n { merge: true }\n )\n if (custSnap.exists || delta.bonusAiTokens !== Number(custData.bonusAiTokens ?? 0)) {\n tx.set(\n custRef,\n {\n id: userId,\n userId,\n planId,\n bonusAiTokens: delta.bonusAiTokens,\n bonusMetrics: delta.bonusMetrics,\n updatedAt: now,\n ...(custSnap.exists ? {} : { createdAt: now, deleted: false, subscriptionStatus: 'none', cancelAtPeriodEnd: false, credits: 0 })\n },\n { merge: true }\n )\n }\n }\n return {\n plan,\n custData,\n overageDelta: delta.overageDelta,\n result: {\n userId,\n periodKey,\n planId,\n aiTokensUsed: delta.aiTokensUsed,\n aiTokensLimit: plan.quota.aiTokens ?? null,\n bonusAiTokens: delta.bonusAiTokens,\n overageTokensReported: delta.overageTokensReported,\n overageEnabled: Boolean(plan.quota.overage?.enabled),\n ...(plan.quota.overage?.maxOverageTokens !== undefined ? { maxOverageTokens: plan.quota.overage.maxOverageTokens } : {}),\n metricsUsed: delta.metricsUsed,\n metricsLimits: plan.quota.metrics ?? {},\n bonusMetrics: delta.bonusMetrics\n } satisfies UsageStatusResult\n }\n })\n\n if (txOut.overageDelta > 0 && txOut.plan.quota.overage?.enabled) {\n const provider = this.#billing.resolveProvider(opts?.provider ?? (txOut.custData.activeProvider as PaymentProvider | undefined))\n const { providerCustomerId } = await this.#billing.ensureCustomer(userId, provider)\n const meterName =\n (provider === 'stripe' ? txOut.plan.providers?.stripe?.meterEventName : txOut.plan.providers?.dodo?.meterEventName) ??\n cfg.aiTokenMeterName\n const idemKey = parsed.idempotencyKey ?? `mtr_${userId}_${Date.now()}_${crypto.randomUUID().replace(/-/g, '').slice(0, 8)}`\n await this.#ingestMeterEvent(provider, providerCustomerId, meterName, txOut.overageDelta, idemKey, {\n ...parsed.metadata,\n ...(parsed.model ? { model: parsed.model } : {})\n })\n }\n return txOut.result\n }\n\n #applyWebhookStateUpdate = async (\n provider: PaymentProvider,\n ev: NormalizedPaymentWebhook\n ): Promise<{ handled: boolean; deduplicated?: boolean }> => {\n const db = this.#core.db.firestore()\n let userId = ev.userId\n if (!userId && ev.customerId) {\n const field = provider === 'stripe' ? 'stripeCustomerId' : 'dodoCustomerId'\n const snap = await db.collection('payment_customer').where(field, '==', ev.customerId).where('deleted', '==', false).limit(1).get()\n userId = snap.docs[0]?.id\n }\n if (!userId || !ev.txType) return { handled: false }\n\n const txId = paymentTxDocId(provider, ev.eventId)\n const txRef = db.collection('payment_transaction').doc(txId)\n const custRef = db.collection('payment_customer').doc(userId)\n const prod = ev.productId ? getProductDefinition(ev.productId) : undefined\n const grantKey = prod?.grants ? (ev.paymentId ?? ev.eventId).replace(/[^A-Za-z0-9_-]/g, '_').slice(0, 96) : undefined\n const grantRef = grantKey ? db.collection('_idempotency').doc(`pay_grant_${userId}_${grantKey}`) : undefined\n await this.#core.internals.resilience.acquireLimit('firestore')\n\n const { deduplicated } = await db.runTransaction(async (tx) => {\n const [txSnap, custSnap, grantSnap] = await Promise.all([tx.get(txRef), tx.get(custRef), grantRef ? tx.get(grantRef) : Promise.resolve(undefined)])\n if (txSnap.exists) return { deduplicated: true }\n const custData = custSnap.data() ?? {}\n const now = new Date()\n const applyGrants = Boolean(prod?.grants && !grantSnap?.exists)\n if (applyGrants && grantRef) {\n tx.set(grantRef, { key: grantRef.id, userId, productId: ev.productId, createdAt: now, expiresAt: new Date(now.getTime() + 86_400_000) })\n }\n const bonusMetrics: Record<string, number> = { ...(custData.bonusMetrics ?? {}) }\n if (applyGrants) {\n for (const [m, delta] of Object.entries(prod?.grants?.metrics ?? {})) bonusMetrics[m] = (bonusMetrics[m] ?? 0) + delta\n }\n const defaultPlanId = this.#core.config.payments.defaultPlanId\n const nextPlanId = ev.txType === 'subscription.cancelled' ? defaultPlanId : (ev.planId ?? custData.planId ?? defaultPlanId)\n\n tx.set(txRef, {\n id: txId,\n userId,\n provider,\n externalId: ev.eventId,\n type: ev.txType,\n ...(ev.amount !== undefined ? { amount: ev.amount } : {}),\n ...(ev.currency ? { currency: ev.currency } : {}),\n ...(ev.productId || ev.planId ? { productOrPlanId: ev.productId ?? ev.planId } : {}),\n rawEventType: ev.rawEventType,\n processedAt: now.toISOString(),\n deleted: false,\n createdAt: now,\n updatedAt: now\n })\n\n tx.set(\n custRef,\n {\n id: userId,\n userId,\n activeProvider: provider,\n ...(ev.customerId ? (provider === 'stripe' ? { stripeCustomerId: ev.customerId } : { dodoCustomerId: ev.customerId }) : {}),\n planId: nextPlanId,\n ...(ev.subscriptionId ? { subscriptionId: ev.subscriptionId } : {}),\n ...(ev.subscriptionStatus ? { subscriptionStatus: ev.subscriptionStatus } : {}),\n ...(ev.currentPeriodStart ? { currentPeriodStart: ev.currentPeriodStart } : {}),\n ...(ev.currentPeriodEnd ? { currentPeriodEnd: ev.currentPeriodEnd } : {}),\n ...(ev.cancelAtPeriodEnd !== undefined ? { cancelAtPeriodEnd: ev.cancelAtPeriodEnd } : {}),\n bonusAiTokens: Number(custData.bonusAiTokens ?? 0) + (applyGrants ? (prod?.grants?.aiTokens ?? 0) : 0),\n credits: Number(custData.credits ?? 0) + (applyGrants ? (prod?.grants?.credits ?? 0) : 0),\n bonusMetrics,\n deleted: false,\n createdAt: custData.createdAt ?? now,\n updatedAt: now\n },\n { merge: true }\n )\n return { deduplicated: false }\n })\n\n if (!deduplicated && ev.resetPeriodUsage) {\n const periodKey = currentPeriodKey(ev.currentPeriodStart)\n const usageId = paymentUsageDocId(userId, periodKey)\n const now = new Date()\n const planId = ev.planId ?? this.#core.config.payments.defaultPlanId\n await db.collection('payment_usage').doc(usageId).set(\n { id: usageId, userId, periodKey, planId, aiTokensUsed: 0, aiInputTokens: 0, aiOutputTokens: 0, overageTokensReported: 0, metricsUsed: {}, lastUpdatedAt: now.toISOString(), deleted: false, createdAt: now, updatedAt: now },\n { merge: true }\n )\n }\n return { handled: true, ...(deduplicated ? { deduplicated: true } : {}) }\n }\n\n #verifyAndProcessWebhook = async (\n provider: PaymentProvider,\n rawBody: string,\n headers: Record<string, string | undefined>\n ): Promise<PaymentWebhookResult> => {\n const { webhookSecret } = this.#billing.getCreds(provider)\n let normalized: NormalizedPaymentWebhook\n try {\n normalized = normalizePaymentWebhook(provider, rawBody, headers, webhookSecret, this.#core.config.payments.webhookToleranceSeconds)\n } catch (err) {\n return this.#core.errors.httpError(\n 401,\n err instanceof Error ? err.message : `Invalid ${provider} webhook signature`,\n 'INVALID_WEBHOOK_SIGNATURE'\n )\n }\n const { handled, deduplicated } = await this.#applyWebhookStateUpdate(provider, normalized)\n return { received: true, eventId: normalized.eventId, handled, ...(deduplicated ? { deduplicated: true } : {}) }\n }\n\n #enforceAiQuota = async (userId: EntryId = this.#core.userId, estimatedTokens = 1): Promise<void> => {\n const cfg = this.#core.config.payments\n if (!cfg.enabled || !cfg.autoTrackAiTokens || !userId || this.#core.role === 'admin' || userId === this.#core.config.auth.adminUserId) return\n await this.checkQuota('ai_tokens', estimatedTokens, userId, true)\n }\n\n #trackAiUsage = async (params: {\n userId?: EntryId\n model: string\n inputTokens: number\n outputTokens: number\n totalTokens?: number\n source: 'generate' | 'vision' | 'decide' | 'chat'\n }): Promise<void> => {\n const cfg = this.#core.config.payments\n const userId = params.userId ?? this.#core.userId\n if (!cfg.enabled || !cfg.autoTrackAiTokens || !userId || this.#core.role === 'admin' || userId === this.#core.config.auth.adminUserId) return\n const total = params.totalTokens ?? params.inputTokens + params.outputTokens\n if (total <= 0) return\n await this.recordUsage(\n {\n metric: 'ai_tokens',\n amount: total,\n inputTokens: params.inputTokens,\n outputTokens: params.outputTokens,\n model: params.model,\n metadata: { source: params.source }\n },\n { userId }\n )\n }\n\n get internals() {\n return {\n enforceAiQuota: this.#enforceAiQuota,\n trackAiUsage: this.#trackAiUsage,\n verifyAndProcessWebhook: this.#verifyAndProcessWebhook\n }\n }\n}\n", "import type { Context } from 'hono'\nimport type { AppEnv } from '../config'\nimport type { Core } from '../index'\nimport {\n cancelSubscriptionInput,\n changeTierInput,\n chargeResultSchema,\n checkoutSessionResultSchema,\n createCheckoutInput,\n createInvoiceInput,\n createPaymentLinkInput,\n directChargeInput,\n invoiceResultSchema,\n paymentLinkResultSchema,\n paymentWebhookParamsSchema,\n subscribeInput,\n subscribeResultSchema,\n subscriptionRecordSchema,\n type CancelSubscriptionInput,\n type ChangeTierInput,\n type CreateCheckoutInput,\n type CreateInvoiceInput,\n type CreatePaymentLinkInput,\n type DirectChargeInput,\n type PaymentWebhookParams,\n type SubscribeInput\n} from './schema'\n\nexport const corePaymentRoutes = {\n 'payments.checkout': {\n input: createCheckoutInput,\n output: checkoutSessionResultSchema,\n handler: async ({ core, input }: { core: Core; input: CreateCheckoutInput }) => core.payments.createCheckout(input)\n },\n 'payments.paymentLink': {\n input: createPaymentLinkInput,\n output: paymentLinkResultSchema,\n handler: async ({ core, input }: { core: Core; input: CreatePaymentLinkInput }) => core.payments.createPaymentLink(input)\n },\n 'payments.invoice': {\n input: createInvoiceInput,\n output: invoiceResultSchema,\n handler: async ({ core, input }: { core: Core; input: CreateInvoiceInput }) => core.payments.createInvoice(input)\n },\n 'payments.charge': {\n input: directChargeInput,\n output: chargeResultSchema,\n handler: async ({ core, input }: { core: Core; input: DirectChargeInput }) => core.payments.charge(input)\n },\n 'payments.subscribe': {\n input: subscribeInput,\n output: subscribeResultSchema,\n handler: async ({ core, input }: { core: Core; input: SubscribeInput }) => core.payments.subscribe(input)\n },\n 'payments.changeTier': {\n input: changeTierInput,\n output: subscriptionRecordSchema,\n handler: async ({ core, input }: { core: Core; input: ChangeTierInput }) => core.payments.changeSubscriptionTier(input)\n },\n 'payments.cancelSubscription': {\n input: cancelSubscriptionInput,\n output: subscriptionRecordSchema,\n handler: async ({ core, input }: { core: Core; input: CancelSubscriptionInput }) => core.payments.cancelSubscription(input)\n },\n 'payments.status': {\n handler: async ({ core }: { core: Core }) => ({\n subscription: await core.payments.getSubscription(),\n usage: await core.payments.getUsage()\n })\n },\n 'payments.webhook': {\n params: paymentWebhookParamsSchema,\n handler: async ({\n core,\n c,\n params,\n rawBody\n }: {\n core: Core\n c: Context<AppEnv>\n params: PaymentWebhookParams\n rawBody?: string\n }) => {\n const headers: Record<string, string | undefined> = {}\n c?.req.raw.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value\n })\n const body = rawBody ?? (c ? await c.req.text() : '')\n return core.internals.payments.verifyAndProcessWebhook(params.provider, body, headers)\n }\n }\n}\n", "import type { Context } from 'hono'\nimport type { z } from 'zod'\nimport { processAttachmentsInput, scanAttachmentInput, type AttachmentTypesMap } from '../attachments'\nimport {\n blockUserBody, completeAccountRecoveryBody, customTokenBody, emailSignInBody, emailSignUpBody,\n eraseUserInput, eraseUserOutput, forgotPasswordBody, initiateAccountRecoveryBody, resetPasswordBody,\n sendVerificationEmailBody, sessionBody, setRecoveryEmailBody, signOutBody, socialSignInInput,\n verifyEmailBody, verifyRecoveryEmailBody\n} from '../auth'\nimport { openaiCompletionsBody, saveChatBody, streamChatBody, type AgentConfig, type ContextItemSpec } from '../chat'\nimport type { AppBindings, AppEnv, DbRole, RateLimitConfig } from '../config'\nimport { fileScan, type CollectionDefinition, type CollectionName, type EntryId } from '../db'\nimport {\n emailLogsQuerySchema, emailWebhookParamsSchema, sendBatchEmailInputSchema, sendBatchEmailResultSchema,\n sendEmailInputSchema, sendEmailResultSchema, type EmailTemplatesMap, type SendEmailInput\n} from '../emails'\nimport type { Core } from '../index'\nimport {\n cancelSubscriptionInput, changeTierInput, chargeResultSchema, checkoutSessionResultSchema,\n createCheckoutInput, createInvoiceInput, createPaymentLinkInput, directChargeInput, invoiceResultSchema,\n paymentLinkResultSchema, paymentWebhookParamsSchema, subscribeInput, subscribeResultSchema,\n subscriptionRecordSchema, type CancelSubscriptionInput, type ChangeTierInput, type CreateCheckoutInput,\n type CreateInvoiceInput, type CreatePaymentLinkInput, type DirectChargeInput, type PlansMap,\n type ProductsMap, type SubscribeInput\n} from '../payments'\nimport type { RollbackLeg, StepRetryPolicy, StepRunner } from '../tasks'\nimport type { Duration } from '../utils'\n\nexport type AuthLevel = 'public' | 'user' | 'strict' | 'admin' | false | 'none' | 'authenticated' | 'api-key'\n\nexport type RouteMode = 'rest' | 'workflow'\n\nexport interface ResourceGuardConfig<I = any> {\n checkFileRef?: boolean | ((input: I, c?: Context<AppEnv>) => string | string[] | undefined)\n checkUserId?: boolean | ((input: I, c?: Context<AppEnv>) => string | undefined)\n checkCollectionField?: { collection: CollectionName; param: string }\n requireEmailVerified?: boolean\n custom?: (ctx: {\n userId: EntryId\n role: DbRole\n input: I\n env: AppBindings\n c?: Context<AppEnv>\n }) => boolean | Promise<boolean>\n}\n\nexport interface RouteExecutionContext<\n I = any,\n P = Record<string, string>,\n Q = Record<string, string>\n> {\n core: Core\n env: AppBindings\n userId: EntryId\n role: DbRole\n mode: RouteMode\n step: StepRunner\n allWithRollback: <T extends readonly unknown[]>(legs: { [K in keyof T]: RollbackLeg<T[K]> }) => Promise<T>\n input: I\n params: P\n query: Q\n rawBody?: string\n c: Context<AppEnv>\n}\n\nexport interface BaseRouteConfig<I = any, O = any, P = any, Q = any> {\n mode?: RouteMode\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'ALL'\n path?: string\n workflowName?: string\n description?: string\n auth?: AuthLevel\n rateLimit?: RateLimitConfig\n guard?: ResourceGuardConfig<I>\n params?: z.ZodType<P>\n query?: z.ZodType<Q>\n input?: z.ZodType<I>\n output?: z.ZodType<O>\n rawBody?: boolean\n mcp?: boolean\n tool?: boolean\n timeout?: Duration\n retry?: number | StepRetryPolicy\n idempotencyKey?: (input: I, ctx: { userId: EntryId }) => string | undefined\n}\n\nexport interface RouteConfig<I = any, O = any, P = any, Q = any> extends BaseRouteConfig<I, O, P, Q> {\n shortCircuit?: (ctx: RouteExecutionContext<I, P, Q>) => Promise<O | undefined | null> | O | undefined | null\n handler: (ctx: RouteExecutionContext<I, P, Q>) => Response | O | Promise<Response | O>\n}\n\nexport type CoreRouteId =\n | 'health'\n | 'auth.custom-token'\n | 'auth.session.create'\n | 'auth.session.get'\n | 'auth.sign-up.email'\n | 'auth.sign-in.email'\n | 'auth.sign-in.social'\n | 'auth.email.send-verification'\n | 'auth.email.verify'\n | 'auth.password.forgot'\n | 'auth.password.reset'\n | 'auth.recovery-email.set'\n | 'auth.recovery-email.verify'\n | 'auth.account-recovery.initiate'\n | 'auth.account-recovery.complete'\n | 'auth.users.list'\n | 'auth.users.block'\n | 'auth.users.delete'\n | 'auth.sign-out'\n | 'files.upload'\n | 'files.list'\n | 'files.get'\n | 'files.delete'\n | 'chat.list'\n | 'chat.get'\n | 'chat.messages'\n | 'chat.save'\n | 'chat.delete'\n | 'chat.stream'\n | 'chat.cancel'\n | 'openai.models'\n | 'openai.completions'\n | 'attachments.scan'\n | 'attachments.process'\n | 'routes.list'\n | 'tasks.status'\n | 'tasks.signal'\n | 'tasks.cancel'\n | 'emails.send'\n | 'emails.batch'\n | 'emails.logs'\n | 'emails.webhook'\n | 'payments.checkout'\n | 'payments.paymentLink'\n | 'payments.invoice'\n | 'payments.charge'\n | 'payments.subscribe'\n | 'payments.changeTier'\n | 'payments.cancelSubscription'\n | 'payments.status'\n | 'payments.webhook'\n\nexport type CoreRouteOverride = Partial<\n Pick<RouteConfig, 'auth' | 'rateLimit' | 'guard' | 'mcp' | 'tool' | 'timeout' | 'retry' | 'description'>\n>\n\nexport type CoreRouteOverrides = Partial<Record<CoreRouteId, CoreRouteOverride>>\n\nexport interface WorkflowRegistryEntry {\n name: string\n description: string\n input: z.ZodType<any>\n output?: z.ZodType<any>\n mode: RouteMode\n deadlineSeconds?: number\n guard?: BaseRouteConfig['guard']\n runTask: (params: any, step: StepRunner) => Promise<unknown>\n invoke: (\n params: any,\n userId: EntryId,\n c?: Context<AppEnv>,\n role?: DbRole,\n opts?: { wait?: boolean }\n ) => Promise<unknown>\n}\n\nexport interface CoreAppInit {\n coreRouteOverrides?: CoreRouteOverrides\n attachmentTypes?: AttachmentTypesMap\n emailTemplates?: EmailTemplatesMap\n plans?: PlansMap\n products?: ProductsMap\n agents?: Record<string, AgentConfig>\n routes?: Record<string, RouteConfig<any, any, any, any>>\n collections?: Record<string, CollectionDefinition<any>>\n context?: readonly ContextItemSpec[]\n}\n\nexport const defineRoute = <C extends RouteConfig<any, any, any, any>>(config: C): C => ({ mcp: false, ...config })\n\nexport const defineRoutes = <T extends Record<string, RouteConfig<any, any, any, any>>>(routes: T): T => routes\n\nexport const defineRouteOverrides = <T extends CoreRouteOverrides>(overrides: T): T => overrides\n\nexport const CORE_ROUTE_DEFAULTS: Record<CoreRouteId, BaseRouteConfig> = {\n health: { mode: 'rest', method: 'GET', path: '/health', auth: 'public', description: 'Public service health check endpoint.' },\n 'auth.custom-token': { mode: 'rest', method: 'POST', path: '/auth/custom-token', auth: 'admin', input: customTokenBody },\n 'auth.session.create': { mode: 'rest', method: 'POST', path: '/auth/session', auth: 'public', input: sessionBody },\n 'auth.session.get': { mode: 'rest', method: 'GET', path: '/auth/session', auth: 'strict' },\n 'auth.sign-up.email': { mode: 'rest', method: 'POST', path: '/auth/sign-up/email', auth: 'public', input: emailSignUpBody },\n 'auth.sign-in.email': { mode: 'rest', method: 'POST', path: '/auth/sign-in/email', auth: 'public', input: emailSignInBody },\n 'auth.sign-in.social': {\n mode: 'rest',\n method: 'POST',\n path: '/auth/sign-in/social',\n auth: 'public',\n description: 'Sign in or link user account using Google or Apple OIDC ID token (Web & iOS/Capacitor).',\n input: socialSignInInput\n },\n 'auth.email.send-verification': {\n mode: 'rest',\n method: 'POST',\n path: '/auth/email/send-verification',\n auth: 'user',\n description: 'Generate and send a 6-digit OTP and magic token to verify the caller primary email.',\n input: sendVerificationEmailBody\n },\n 'auth.email.verify': {\n mode: 'rest',\n method: 'POST',\n path: '/auth/email/verify',\n auth: 'public',\n description: 'Verify primary email ownership via OTP code or magic token and evict stale token cache entries.',\n input: verifyEmailBody\n },\n 'auth.password.forgot': {\n mode: 'rest',\n method: 'POST',\n path: '/auth/password/forgot',\n auth: 'public',\n description: 'Request a password reset OTP/token without revealing account existence.',\n input: forgotPasswordBody\n },\n 'auth.password.reset': {\n mode: 'rest',\n method: 'POST',\n path: '/auth/password/reset',\n auth: 'public',\n description: 'Reset user password using a valid OTP/token and revoke all active sessions.',\n input: resetPasswordBody\n },\n 'auth.recovery-email.set': {\n mode: 'rest',\n method: 'POST',\n path: '/auth/recovery-email/set',\n auth: 'strict',\n description: 'Bind a secondary recovery email address and send a verification OTP.',\n input: setRecoveryEmailBody\n },\n 'auth.recovery-email.verify': {\n mode: 'rest',\n method: 'POST',\n path: '/auth/recovery-email/verify',\n auth: 'strict',\n description: 'Verify ownership of the secondary recovery email via OTP code or token.',\n input: verifyRecoveryEmailBody\n },\n 'auth.account-recovery.initiate': {\n mode: 'rest',\n method: 'POST',\n path: '/auth/account-recovery/initiate',\n auth: 'public',\n description: 'Initiate full account recovery by sending a recovery OTP to a verified secondary recovery email.',\n input: initiateAccountRecoveryBody\n },\n 'auth.account-recovery.complete': {\n mode: 'rest',\n method: 'POST',\n path: '/auth/account-recovery/complete',\n auth: 'public',\n description: 'Complete account recovery, update primary email (and optional password), revoke old sessions, and mint a fresh session.',\n input: completeAccountRecoveryBody\n },\n 'auth.users.list': { mode: 'rest', method: 'GET', path: '/auth/users', auth: 'admin' },\n 'auth.users.block': { mode: 'rest', method: 'POST', path: '/auth/users/block', auth: 'strict', guard: { checkUserId: true }, input: blockUserBody },\n 'auth.users.delete': {\n mode: 'workflow',\n method: 'POST',\n path: '/erase-user',\n workflowName: 'erase-user',\n description: 'Cascade-erase a user across Storage, Firestore collections, and Firebase Auth.',\n auth: 'strict',\n guard: { checkUserId: true },\n mcp: false,\n input: eraseUserInput,\n output: eraseUserOutput\n },\n 'auth.sign-out': { mode: 'rest', method: 'POST', path: '/auth/sign-out', auth: 'public', input: signOutBody },\n 'files.upload': { mode: 'rest', method: 'POST', path: '/files', auth: 'user' },\n 'files.list': { mode: 'rest', method: 'GET', path: '/files', auth: 'user' },\n 'files.get': { mode: 'rest', method: 'GET', path: '/files/:ref', auth: 'user', guard: { checkFileRef: true } },\n 'files.delete': { mode: 'rest', method: 'DELETE', path: '/files/:ref', auth: 'user', guard: { checkFileRef: true } },\n 'chat.list': { mode: 'rest', method: 'GET', path: '/chats', auth: 'user' },\n 'chat.get': { mode: 'rest', method: 'GET', path: '/chats/:chatId', auth: 'user', guard: { checkCollectionField: { collection: 'chat', param: 'chatId' } } },\n 'chat.messages': { mode: 'rest', method: 'GET', path: '/chats/:chatId/messages', auth: 'user', guard: { checkCollectionField: { collection: 'chat', param: 'chatId' } } },\n 'chat.save': { mode: 'rest', method: 'POST', path: '/chats', auth: 'user', input: saveChatBody },\n 'chat.delete': { mode: 'rest', method: 'DELETE', path: '/chats/:chatId', auth: 'user', guard: { checkCollectionField: { collection: 'chat', param: 'chatId' } } },\n 'chat.stream': { mode: 'rest', method: 'POST', path: '/chats/:chatId', auth: 'user', input: streamChatBody },\n 'chat.cancel': { mode: 'rest', method: 'POST', path: '/chats/:chatId/cancel', auth: 'user', guard: { checkCollectionField: { collection: 'chat', param: 'chatId' } } },\n 'openai.models': { mode: 'rest', method: 'GET', path: '/v1/models', auth: 'user' },\n 'openai.completions': { mode: 'rest', method: 'POST', path: '/v1/chat/completions', auth: 'user', input: openaiCompletionsBody },\n 'attachments.scan': {\n mode: 'workflow',\n method: 'POST',\n path: '/scan-attachment',\n workflowName: 'scan-attachment',\n description: 'OCR + classify + extract structured fields for a single attachment ref.',\n auth: 'user',\n guard: { checkFileRef: true },\n mcp: true,\n tool: true,\n input: scanAttachmentInput,\n output: fileScan\n },\n 'attachments.process': {\n mode: 'workflow',\n method: 'POST',\n path: '/process-attachments',\n workflowName: 'process-attachments',\n description: 'Fan out scan-attachment across 1..N file refs with cache short-circuit and sharded parallelism.',\n auth: 'user',\n guard: { checkFileRef: true },\n mcp: true,\n tool: true,\n input: processAttachmentsInput\n },\n 'routes.list': { mode: 'rest', method: 'GET', path: '/routes', auth: 'admin' },\n 'tasks.status': { mode: 'rest', method: 'GET', path: '/tasks/:taskId', auth: 'user' },\n 'tasks.signal': { mode: 'rest', method: 'POST', path: '/tasks/:taskId/signal', auth: 'user' },\n 'tasks.cancel': { mode: 'rest', method: 'DELETE', path: '/tasks/:taskId', auth: 'user' },\n 'emails.send': {\n mode: 'rest',\n method: 'POST',\n path: '/emails/send',\n auth: 'admin',\n rateLimit: { max: 60, windowMs: 60_000, keyBy: 'user' },\n idempotencyKey: (inp: SendEmailInput | undefined) => inp?.idempotencyKey,\n description: 'Send a transactional email via SendGrid or Resend with template resolution and audit logging.',\n input: sendEmailInputSchema,\n output: sendEmailResultSchema\n },\n 'emails.batch': {\n mode: 'rest',\n method: 'POST',\n path: '/emails/batch',\n auth: 'admin',\n rateLimit: { max: 20, windowMs: 60_000, keyBy: 'user' },\n description: 'Send up to 100 transactional emails in a single batch.',\n input: sendBatchEmailInputSchema,\n output: sendBatchEmailResultSchema\n },\n 'emails.logs': {\n mode: 'rest',\n method: 'GET',\n path: '/emails/logs',\n auth: 'admin',\n rateLimit: { max: 120, windowMs: 60_000, keyBy: 'user' },\n description: 'List email delivery audit logs with filtering by recipient, template, purpose, and status.',\n query: emailLogsQuerySchema\n },\n 'emails.webhook': {\n mode: 'rest',\n method: 'POST',\n path: '/emails/webhooks/:provider',\n auth: 'none',\n rawBody: true,\n rateLimit: { max: 600, windowMs: 60_000, keyBy: 'ip' },\n description: 'Receive and verify HMAC-SHA256 delivery/bounce/complaint webhooks from SendGrid or Resend.',\n params: emailWebhookParamsSchema\n },\n 'payments.checkout': {\n mode: 'rest',\n method: 'POST',\n path: '/payments/checkout',\n auth: 'user',\n rateLimit: { max: 30, windowMs: 60_000, keyBy: 'user' },\n idempotencyKey: (inp: CreateCheckoutInput | undefined) => inp?.idempotencyKey,\n description: 'Create a hosted checkout session for a predefined plan, product, or custom ad-hoc amount.',\n input: createCheckoutInput,\n output: checkoutSessionResultSchema\n },\n 'payments.paymentLink': {\n mode: 'rest',\n method: 'POST',\n path: '/payments/payment-link',\n auth: 'user',\n rateLimit: { max: 30, windowMs: 60_000, keyBy: 'user' },\n idempotencyKey: (inp: CreatePaymentLinkInput | undefined) => inp?.idempotencyKey,\n description: 'Generate a shareable payment link for a predefined plan, product, or custom ad-hoc amount.',\n input: createPaymentLinkInput,\n output: paymentLinkResultSchema\n },\n 'payments.invoice': {\n mode: 'rest',\n method: 'POST',\n path: '/payments/invoice',\n auth: 'user',\n rateLimit: { max: 20, windowMs: 60_000, keyBy: 'user' },\n idempotencyKey: (inp: CreateInvoiceInput | undefined) => inp?.idempotencyKey,\n description: 'Generate a finalized invoice with hosted payment URL and PDF link.',\n input: createInvoiceInput,\n output: invoiceResultSchema\n },\n 'payments.charge': {\n mode: 'rest',\n method: 'POST',\n path: '/payments/charge',\n auth: 'user',\n rateLimit: { max: 20, windowMs: 60_000, keyBy: 'user' },\n idempotencyKey: (inp: DirectChargeInput | undefined) => inp?.idempotencyKey,\n description: 'Execute a direct one-time charge for a predefined product or custom amount.',\n input: directChargeInput,\n output: chargeResultSchema\n },\n 'payments.subscribe': {\n mode: 'rest',\n method: 'POST',\n path: '/payments/subscribe',\n auth: 'user',\n rateLimit: { max: 15, windowMs: 60_000, keyBy: 'user' },\n idempotencyKey: (inp: SubscribeInput | undefined) => inp?.idempotencyKey,\n description: 'Subscribe the caller to a defined recurring or free plan tier.',\n input: subscribeInput,\n output: subscribeResultSchema\n },\n 'payments.changeTier': {\n mode: 'rest',\n method: 'POST',\n path: '/payments/subscription/change-tier',\n auth: 'user',\n rateLimit: { max: 15, windowMs: 60_000, keyBy: 'user' },\n idempotencyKey: (inp: ChangeTierInput | undefined) => inp?.idempotencyKey,\n description: 'Upgrade or downgrade the caller active subscription tier with proration.',\n input: changeTierInput,\n output: subscriptionRecordSchema\n },\n 'payments.cancelSubscription': {\n mode: 'rest',\n method: 'POST',\n path: '/payments/subscription/cancel',\n auth: 'user',\n rateLimit: { max: 15, windowMs: 60_000, keyBy: 'user' },\n idempotencyKey: (inp: CancelSubscriptionInput | undefined) => inp?.idempotencyKey,\n description: 'Cancel the caller active subscription immediately or at period end.',\n input: cancelSubscriptionInput,\n output: subscriptionRecordSchema\n },\n 'payments.status': {\n mode: 'rest',\n method: 'GET',\n path: '/payments/status',\n auth: 'user',\n rateLimit: { max: 120, windowMs: 60_000, keyBy: 'user' },\n description: 'Get the caller current subscription tier, billing status, and AI token/metric usage summary.'\n },\n 'payments.webhook': {\n mode: 'rest',\n method: 'POST',\n path: '/payments/webhooks/:provider',\n auth: 'none',\n rawBody: true,\n rateLimit: { max: 600, windowMs: 60_000, keyBy: 'ip' },\n description: 'Receive and verify HMAC-SHA256 webhooks from Stripe or Dodo Payments with idempotent state reconciliation.',\n params: paymentWebhookParamsSchema\n }\n}\n", "import { getRequestListener } from '@hono/node-server'\nimport { defineSecret } from 'firebase-functions/params'\nimport { onRequest } from 'firebase-functions/v2/https'\nimport { onTaskDispatched } from 'firebase-functions/v2/tasks'\nimport { Hono, type Context } from 'hono'\nimport { bodyLimit } from 'hono/body-limit'\nimport { cors } from 'hono/cors'\nimport { z } from 'zod'\nimport { coreAttachmentsRoutes, getRegisteredAttachmentTypes, registerAttachmentTypes } from '../attachments'\nimport { coreAuthRoutes } from '../auth'\nimport { coreChatRoutes, mcpRoute } from '../chat'\nimport { CORE_CONFIG, SECRET_NAMES, type AppBindings, type AppEnv, type DbRole } from '../config'\nimport { registerCollections, type EntryId } from '../db'\nimport { coreEmailRoutes, registerEmailTemplates } from '../emails'\nimport { coreFilesRoutes } from '../files'\nimport { Core } from '../index'\nimport { corePaymentRoutes, registerPlans, registerProducts } from '../payments'\nimport {\n buildHealthRoute, buildRoutesListRoute, buildTaskCancelRoute, buildTaskSignalRoute, buildTaskStatusRoute,\n TaskWaitDetachedSignal, type RouteRegistryItem, type StepRunner, type WorkflowRuntimeEntry, type WorkflowTaskPayload\n} from '../tasks'\nimport { isRespondAsyncPreferred, mergeCoreAndDomainRoutes, RouterGuardEngine } from './guard'\nimport {\n type CoreAppInit, type CoreRouteId, type RouteConfig, type RouteExecutionContext, type RouteMode, type WorkflowRegistryEntry\n} from './schema'\n\nexport class RouterService {\n readonly #core: Core\n readonly #guard: RouterGuardEngine\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n this.#guard = new RouterGuardEngine(coreClient)\n }\n\n readonly applyRateLimit = (\n ...args: Parameters<RouterGuardEngine['applyRateLimit']>\n ): ReturnType<RouterGuardEngine['applyRateLimit']> => this.#guard.applyRateLimit(...args)\n\n readonly authenticateRequest = (\n ...args: Parameters<RouterGuardEngine['authenticateRequest']>\n ): ReturnType<RouterGuardEngine['authenticateRequest']> => this.#guard.authenticateRequest(...args)\n\n #createCloudFunctions = (\n app: Hono<AppEnv>,\n devApp: Hono<AppEnv>,\n workflowRegistry: Record<string, WorkflowRuntimeEntry>\n ) => {\n const emailProvider = CORE_CONFIG.emails.provider\n const paymentProvider = CORE_CONFIG.payments.provider\n const emailSecrets: string[] = [\n ...(emailProvider === 'resend' ? ['RESEND_API_KEY', 'EMAIL_WEBHOOK_SECRET'] : []),\n ...(emailProvider === 'sendgrid' ? ['SENDGRID_API_KEY', 'EMAIL_WEBHOOK_SECRET'] : [])\n ]\n const paymentSecrets: string[] = [\n ...(paymentProvider === 'stripe' ? ['STRIPE_API_KEY', 'STRIPE_WEBHOOK_SECRET', 'STRIPE_SANDBOX_API_KEY', 'STRIPE_SANDBOX_WEBHOOK_SECRET'] : []),\n ...(paymentProvider === 'dodo' ? ['DODO_API_KEY', 'DODO_WEBHOOK_SECRET', 'DODO_SANDBOX_API_KEY', 'DODO_SANDBOX_WEBHOOK_SECRET'] : [])\n ]\n const secretNames = [...new Set<string>([...SECRET_NAMES, ...emailSecrets, ...paymentSecrets, ...CORE_CONFIG.secrets])]\n const sharedOpts = {\n region: CORE_CONFIG.region,\n memory: CORE_CONFIG.cloudRun.memory,\n cpu: CORE_CONFIG.cloudRun.cpu,\n secrets: secretNames.map((name) => defineSecret(name))\n }\n const httpOpts = { ...sharedOpts, ...CORE_CONFIG.cloudRun.http }\n const workerOpts = { ...sharedOpts, ...CORE_CONFIG.cloudRun.worker }\n\n const httpHandler = onRequest(httpOpts, getRequestListener((req) => app.fetch(req)))\n const devHttpHandler = onRequest(httpOpts, getRequestListener((req) => devApp.fetch(req)))\n\n const workerConfig = {\n ...workerOpts,\n invoker: [CORE_CONFIG.serviceAccount, CORE_CONFIG.computeAccount],\n retryConfig: { maxAttempts: CORE_CONFIG.tasks.maxAttempts, minBackoffSeconds: 2, maxBackoffSeconds: 20 },\n rateLimits: { maxConcurrentDispatches: 1000, maxDispatchesPerSecond: 500 }\n }\n\n const tasksHandler = onTaskDispatched<WorkflowTaskPayload>(workerConfig, async (req) => {\n try {\n await this.#core.internals.workflows.execute({ ...req.data, isDev: false }, workflowRegistry)\n } catch (err) {\n if (!this.#core.errors.isStaleWorkerEpochError(err)) throw err\n }\n })\n const devTasksHandler = onTaskDispatched<WorkflowTaskPayload>(workerConfig, async (req) => {\n try {\n await this.#core.internals.workflows.execute({ ...req.data, isDev: true }, workflowRegistry)\n } catch (err) {\n if (!this.#core.errors.isStaleWorkerEpochError(err)) throw err\n }\n })\n\n const fnName = CORE_CONFIG.gcpProject\n const functions: Record<string, unknown> = {\n [fnName]: httpHandler,\n [`${fnName}-dev`]: devHttpHandler,\n [`${fnName}-tasks`]: tasksHandler,\n [`${fnName}-tasks-dev`]: devTasksHandler\n }\n\n return { httpHandler, devHttpHandler, tasksHandler, devTasksHandler, functions }\n }\n\n #makeCtx = <I, P = Record<string, string>, Q = Record<string, string>>(\n env: AppBindings,\n userId: EntryId,\n role: DbRole,\n mode: RouteMode,\n input: I,\n step: StepRunner = this.#core.internals.workflows.createStepRunner('rest'),\n c?: Context<AppEnv>,\n params?: P,\n query?: Q,\n rawBody?: string\n ): RouteExecutionContext<I, P, Q> => ({\n core: new Core({ env, userId, role, step }),\n c: c as Context<AppEnv>,\n env,\n userId,\n role,\n mode,\n step,\n allWithRollback: this.#core.internals.workflows.allWithRollback,\n input,\n params: (params ?? (c ? c.req.param() : {})) as P,\n query: (query ?? (c ? c.req.query() : {})) as Q,\n ...(rawBody !== undefined ? { rawBody } : {})\n })\n\n #respondAsync202 = (c: Context<AppEnv> | undefined, taskId: string) => {\n if (c) {\n c.header('Preference-Applied', 'respond-async')\n c.header('Location', `/api/tasks/${taskId}`)\n return c.json({ taskId, status: 'running', pollUrl: `/api/tasks/${taskId}` }, 202)\n }\n return { taskId, status: 'running', pollUrl: `/api/tasks/${taskId}` }\n }\n\n #executeRouteCore = async (opts: {\n key: string\n wfName: string\n cfg: RouteConfig\n mode: RouteMode\n runTask: (taskInput: unknown, step: StepRunner) => Promise<unknown>\n parseOut: (out: unknown) => unknown\n env: AppBindings\n userId: EntryId\n role: DbRole\n parsed: unknown\n parsedParams: Record<string, string>\n parsedQuery: Record<string, string>\n rawBody?: string\n c?: Context<AppEnv>\n wait: boolean\n }): Promise<unknown> => {\n const { key, wfName, cfg, mode, runTask, parseOut, env, userId, role, parsed, parsedParams, parsedQuery, rawBody, c, wait } =\n opts\n await this.#guard.enforceGuard(c, cfg, userId, parsed, role)\n const dedupeKey =\n (cfg.idempotencyKey ? cfg.idempotencyKey(parsed, { userId }) : undefined) ??\n (c?.req.header('idempotency-key')?.trim() || undefined)\n const runWithStep = <T>(m: RouteMode, fn: (ctx: RouteExecutionContext) => Promise<T> | T): Promise<T> => {\n const step = this.#core.internals.workflows.createStepRunner(m)\n return this.#core.internals.context.run({ env, userId, role, step }, async () =>\n fn(this.#makeCtx(env, userId, role, m, parsed, step, c, parsedParams, parsedQuery, rawBody))\n )\n }\n\n if (mode === 'rest') {\n const executeRest = () => runWithStep('rest', cfg.handler)\n const out = dedupeKey\n ? await this.#guard.withHttpIdempotency(key, dedupeKey, userId, Boolean(env.isDev), executeRest)\n : await executeRest()\n return parseOut(out)\n }\n\n const cached = cfg.shortCircuit ? await runWithStep('workflow', cfg.shortCircuit) : undefined\n if (cached !== undefined && cached !== null) return parseOut(cached)\n\n try {\n const dispatched = await this.#core.internals.workflows.dispatch(wfName, runTask, parsed, {\n mode: 'workflow',\n ...(cfg.timeout !== undefined ? { timeout: cfg.timeout } : {}),\n ...(dedupeKey ? { dedupeKey } : {}),\n wait,\n ...(wait && c ? { maxWaitMs: CORE_CONFIG.limits.maxWaitMs, signal: c.req.raw?.signal } : {}),\n userId,\n userRole: role\n })\n return !wait ? this.#respondAsync202(c, (dispatched as { taskId: string }).taskId) : parseOut(dispatched)\n } catch (err) {\n if (err instanceof TaskWaitDetachedSignal) return this.#respondAsync202(c, err.taskId)\n throw err\n }\n }\n\n #registerRouteSpecAndTools = (\n key: string,\n wfName: string,\n mode: RouteMode,\n cfg: RouteConfig,\n description: string,\n inputSchema: z.ZodType<any>,\n runTask: (taskInput: unknown, step: StepRunner) => Promise<unknown>,\n invoke: WorkflowRegistryEntry['invoke'],\n workflowRegistry: Record<string, WorkflowRegistryEntry>,\n routeRegistryItems: RouteRegistryItem[]\n ): void => {\n const method = (cfg.method ?? 'POST').toUpperCase()\n const path = cfg.path ?? `/${key}`\n const deadlineSeconds = cfg.timeout\n ? Math.max(15, Math.ceil(this.#core.errors.parseDuration(cfg.timeout, 540_000) / 1000))\n : undefined\n\n routeRegistryItems.push({\n id: key,\n mode,\n method,\n path,\n ...(mode === 'workflow' || cfg.workflowName ? { workflowName: wfName } : {}),\n auth: cfg.auth ?? 'user',\n description,\n mcp: cfg.mcp === true,\n tool: cfg.tool !== false,\n ...(cfg.input ? { input: cfg.input } : {}),\n ...(cfg.output ? { output: cfg.output } : {}),\n ...(cfg.guard ? { guard: cfg.guard } : {})\n })\n\n if (mode === 'workflow' || cfg.workflowName) {\n workflowRegistry[wfName] = {\n name: wfName,\n description,\n input: inputSchema,\n output: cfg.output,\n mode,\n ...(deadlineSeconds !== undefined ? { deadlineSeconds } : {}),\n guard: cfg.guard,\n runTask,\n invoke\n }\n }\n\n if (cfg.tool !== false || cfg.mcp === true || mode === 'workflow' || cfg.workflowName) {\n const registerToolUnder = (toolName: string, mcp: boolean, tool: boolean) =>\n this.#core.internals.registry.registerWorkflowTool(toolName, {\n description,\n input: inputSchema,\n mcp,\n tool,\n execute: (inp, u) => invoke(inp, u)\n })\n registerToolUnder(wfName, cfg.mcp === true, cfg.tool !== false)\n if (key !== wfName && cfg.tool !== false) registerToolUnder(key, false, true)\n }\n }\n\n #buildRouteInvoker = (\n key: string,\n cfg: RouteConfig,\n workflowRegistry: Record<string, WorkflowRegistryEntry>,\n routeRegistryItems: RouteRegistryItem[]\n ): WorkflowRegistryEntry['invoke'] => {\n const mode: RouteMode = cfg.mode ?? 'rest'\n const wfName = cfg.workflowName ?? key\n const inputSchema = (cfg.input ?? z.object({})) as z.ZodType<any>\n const description = cfg.description ?? wfName\n const parseOut = (out: unknown) => (out instanceof Response ? out : cfg.output ? cfg.output.parse(out) : out)\n\n const runTask = async (taskInput: unknown, step: StepRunner) => {\n const current = new Core()\n const uid = current.userId || CORE_CONFIG.auth.adminUserId\n return cfg.handler(this.#makeCtx(current.env, uid, current.role, mode, taskInput, step))\n }\n\n const invoke = async (\n rawInput: unknown,\n userId: EntryId,\n c?: Context<AppEnv>,\n explicitRole?: DbRole,\n opts?: { wait?: boolean; rawBody?: string }\n ) => {\n const env = c?.env ?? this.#core.env\n const authLevel = cfg.auth ?? 'user'\n const role = this.#core.internals.auth.resolveUserRole(userId, explicitRole ?? (c?.get('userRole') as DbRole | undefined))\n\n if (authLevel !== 'public' && authLevel !== 'none' && authLevel !== false && !userId) {\n return this.#core.errors.httpError(401, 'Unauthorized', 'UNAUTHORIZED')\n }\n if ((authLevel === 'admin' || authLevel === 'api-key') && role !== 'admin' && userId !== CORE_CONFIG.auth.adminUserId) {\n return this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n\n const parsedParams = cfg.params && c ? cfg.params.parse(c.req.param()) : c?.req.param() ?? {}\n const parsedQuery = cfg.query && c ? cfg.query.parse(c.req.query()) : c?.req.query() ?? {}\n const parsed = cfg.input ? cfg.input.parse(rawInput ?? {}) : rawInput\n\n return this.#core.internals.context.run({ env, userId, role }, () =>\n this.#executeRouteCore({ key, wfName, cfg, mode, runTask, parseOut, env, userId, role, parsed, parsedParams, parsedQuery, rawBody: opts?.rawBody, c, wait: opts?.wait !== false })\n )\n }\n\n this.#registerRouteSpecAndTools(key, wfName, mode, cfg, description, inputSchema, runTask, invoke, workflowRegistry, routeRegistryItems)\n return invoke\n }\n\n #mountRoute = (app: Hono<AppEnv>, cfg: RouteConfig, invoke: WorkflowRegistryEntry['invoke']): void => {\n const method = (cfg.method ?? 'POST').toLowerCase() as 'get' | 'post' | 'put' | 'patch' | 'delete' | 'all'\n const routePath = cfg.path ?? '/'\n\n app[method](routePath, async (c) => {\n const userId = await this.authenticateRequest(c, cfg)\n const role = this.#core.internals.auth.resolveUserRole(userId, c.get('userRole') as DbRole | undefined)\n let rawInput: unknown\n let rawText: string | undefined\n if (cfg.rawBody && method !== 'get') {\n rawText = await c.req.text().catch(() => '')\n if (cfg.input) {\n try {\n rawInput = rawText ? JSON.parse(rawText) : {}\n } catch {\n rawInput = {}\n }\n } else {\n rawInput = rawText\n }\n } else if (cfg.input && method !== 'get') {\n rawInput = await c.req.json().catch(() => ({}))\n }\n const wait = !(cfg.mode === 'workflow' && isRespondAsyncPreferred(c))\n const out = await invoke(rawInput, userId, c, role, {\n wait,\n ...(rawText !== undefined ? { rawBody: rawText } : {})\n })\n return out instanceof Response ? out : c.json(out)\n })\n }\n\n #createHonoApp = (\n isDev: boolean,\n allRoutes: Record<string, RouteConfig>,\n routeInvokers: Map<RouteConfig, WorkflowRegistryEntry['invoke']>\n ): Hono<AppEnv> => {\n const app = new Hono<AppEnv>().basePath('/api')\n app.use(\n '*',\n cors({\n origin: (origin, c) => {\n if (!origin) return undefined\n if (\n CORE_CONFIG.auth.allowedOrigins.some((p: string | RegExp) =>\n typeof p === 'string' ? p === origin : p.test(origin)\n )\n ) {\n return origin\n }\n try {\n if (origin === new URL(c.req.url).origin) return origin\n } catch {}\n return null\n },\n credentials: true\n })\n )\n app.use(\n '*',\n bodyLimit({\n maxSize: CORE_CONFIG.limits.maxBodyBytes,\n onError: () => this.#core.errors.httpError(413, 'Payload too large (max 25MiB)', 'PAYLOAD_TOO_LARGE')\n })\n )\n app.onError((err) => this.#core.errors.toHttpError(err).getResponse())\n app.use('*', async (c, next) => {\n const env: AppBindings = { ...this.#core.env, ...(c.env ?? {}), isDev }\n c.env = env\n await this.#core.internals.context.run(\n { env, userId: CORE_CONFIG.auth.adminUserId, role: 'admin' },\n () => next()\n )\n })\n\n for (const r of Object.values(allRoutes)) this.#mountRoute(app, r, routeInvokers.get(r)!)\n\n app.all('/mcp', async (c) => {\n const userId = await this.authenticateRequest(c, { path: '/mcp', auth: 'user' })\n return mcpRoute(c.req.raw, userId, this.#core.internals.context.getMcpTools())\n })\n\n return app\n }\n\n createApp = (init: CoreAppInit = {}) => {\n if (init.emailTemplates) registerEmailTemplates(init.emailTemplates, true)\n if (init.plans) registerPlans(init.plans, true)\n if (init.products) registerProducts(init.products, true)\n\n registerCollections(init.collections ?? {}, true)\n this.#core.internals.registry.registerAgents(init.agents ?? {}, true)\n if (init.attachmentTypes) registerAttachmentTypes(init.attachmentTypes)\n this.#core.internals.registry.registerContextCatalog(init.context ?? [], true)\n this.#core.internals.registry.clearWorkflowTools()\n\n const overrides = init.coreRouteOverrides ?? {}\n const workflowRegistry: Record<string, WorkflowRegistryEntry> = {}\n const routeRegistryItems: RouteRegistryItem[] = []\n\n const attachmentTypesDesc = Object.entries(getRegisteredAttachmentTypes())\n .map(([k, v]) => `${k} (${v.description})`)\n .join('; ')\n\n const rawCoreRoutes: Record<CoreRouteId, Partial<RouteConfig>> = {\n health: buildHealthRoute(),\n ...coreAuthRoutes,\n ...coreFilesRoutes,\n ...coreChatRoutes,\n ...coreAttachmentsRoutes,\n ...coreEmailRoutes,\n ...corePaymentRoutes,\n 'routes.list': buildRoutesListRoute(() => routeRegistryItems),\n 'tasks.status': buildTaskStatusRoute(),\n 'tasks.signal': buildTaskSignalRoute(),\n 'tasks.cancel': buildTaskCancelRoute()\n }\n\n const allRoutes = mergeCoreAndDomainRoutes(\n rawCoreRoutes,\n overrides,\n attachmentTypesDesc,\n init.routes ?? {}\n )\n const routeInvokers = new Map<RouteConfig, WorkflowRegistryEntry['invoke']>()\n for (const [id, r] of Object.entries(allRoutes)) {\n routeInvokers.set(r, this.#buildRouteInvoker(id, r, workflowRegistry, routeRegistryItems))\n }\n\n this.#core.internals.workflows.registerRuntime(workflowRegistry)\n\n const createApp = (isDev = false) => this.#createHonoApp(isDev, allRoutes, routeInvokers)\n const app = createApp(false)\n const devApp = createApp(true)\n const cloudFunctions = this.#createCloudFunctions(app, devApp, workflowRegistry)\n\n return {\n createApp,\n app,\n devApp,\n workflowRegistry,\n agents: this.#core.internals.registry.getRegisteredAgents(),\n ...cloudFunctions\n }\n }\n}\n", "import type { DocumentReference } from 'firebase-admin/firestore'\nimport { z } from 'zod'\nimport type { AppBindings, DbRole } from '../config'\nimport type { EntryId } from '../db'\nimport type { AuthLevel, BaseRouteConfig, RouteMode } from '../router'\nimport { StaleWorkerEpochError, type Duration } from '../utils'\n\nexport { StaleWorkerEpochError }\n\nexport type TaskStatus =\n | 'running'\n | 'sleeping'\n | 'waiting_signal'\n | 'compensating'\n | 'completed'\n | 'errored'\n | 'cancelled'\n\nexport interface TaskExecutionFence {\n /** Monotonically increasing integer incremented on every worker claim, yield, hedge, or cancel transition */\n epoch: number\n /** Unique UUID for the currently owning worker execution attempt */\n activeRunId: string | null\n /** Timestamp of the latest worker heartbeat */\n lastHeartbeatAt: number\n}\n\nexport interface TaskProgressUpdate {\n percent?: number\n stage?: string\n message?: string\n data?: Record<string, unknown>\n}\n\nexport interface TaskStatusRecord<O = unknown> {\n taskId: string\n workflowName: string\n status: TaskStatus\n userId?: EntryId\n epoch?: number\n activeRunId?: string | null\n lastHeartbeatAt?: number\n compensatedSteps?: Record<string, boolean>\n progress?: TaskProgressUpdate\n response?: O\n error?: string\n createdAt?: string\n updatedAt?: string\n}\n\nexport interface WorkflowContext {\n taskId: string\n workflowName: string\n attempt: number\n startedAt: number\n deadlineMs: number\n signal: AbortSignal\n}\n\nexport interface StepRetryPolicy {\n maxAttempts?: number\n initialInterval?: Duration\n backoffCoefficient?: number\n maxInterval?: Duration\n jitter?: boolean\n nonRetryableErrorTypes?: string[]\n}\n\nexport interface StepContext {\n signal: AbortSignal\n attempt: number\n stepId: string\n}\n\nexport interface StepOptions<T = unknown> {\n retry?: number | StepRetryPolicy\n timeout?: Duration\n rollback?: (result: T) => Promise<unknown>\n}\n\nexport interface StepMapOptions<T, R> extends StepOptions<R> {\n concurrency?: number\n shortCircuit?: (item: T, index: number) => Promise<R | undefined> | R | undefined\n}\n\nexport type StepSpec<T> =\n | ((ctx: StepContext) => Promise<T>)\n | {\n fn: (ctx: StepContext) => Promise<T>\n rollback?: (result: T) => Promise<unknown>\n retry?: number | StepRetryPolicy\n timeout?: Duration\n }\n\nexport type StepFn = <T>(name: string, fnOrSpec: StepSpec<T>, options?: StepOptions<T>) => Promise<T>\n\nexport interface WorkflowTargetRef<I = any, O = any> {\n workflowName?: string\n timeout?: Duration\n handler?: (ctx: any) => Promise<O>\n __input?: I\n}\n\nexport interface StepRunner extends StepFn {\n run: StepFn\n map: <T, R>(\n name: string,\n items: readonly T[],\n fn: (item: T, index: number, ctx: StepContext) => Promise<R>,\n options?: StepMapOptions<T, R>\n ) => Promise<R[]>\n invoke: <I = unknown, O = unknown>(\n name: string,\n target: string | WorkflowTargetRef<I, O>,\n input: I,\n options?: { timeout?: Duration; dedupeKey?: string }\n ) => Promise<O>\n spawn: <I = unknown>(\n name: string,\n target: string | WorkflowTargetRef<I, unknown>,\n input: I,\n options?: { dedupeKey?: string; timeout?: Duration }\n ) => Promise<{ taskId: string }>\n sleep: (name: string, duration: Duration) => Promise<void>\n waitForSignal: <T = unknown>(\n name: string,\n signalName: string,\n options?: { timeout?: Duration }\n ) => Promise<T>\n continueAsNew: <I = unknown>(newInput: I) => Promise<never>\n progress: (update: TaskProgressUpdate) => Promise<void>\n flush: () => Promise<PromiseSettledResult<unknown>[]>\n compensate: () => Promise<void>\n onError: () => Promise<void>\n}\n\nexport interface RollbackLeg<T> {\n fn: () => Promise<T>\n rollback?: (result: T) => Promise<unknown>\n}\n\nexport interface WorkflowTaskPayload {\n taskId: string\n workflowName: string\n params: Record<string, unknown>\n isDev: boolean\n expectedEpoch?: number\n}\n\nexport interface WorkflowRuntimeEntry {\n mode: RouteMode\n deadlineSeconds?: number\n runTask: (params: any, step: StepRunner) => Promise<unknown>\n}\n\nexport class TaskYieldSignal extends Error {\n readonly isTaskYield = true\n constructor(\n public readonly reason: 'sleeping' | 'waiting_signal' | 'continue_as_new' | 'yield',\n public readonly meta: {\n delaySeconds?: number\n signalName?: string\n timeoutMs?: number\n newInput?: unknown\n } = {}\n ) {\n super(`TaskYield:${reason}`)\n this.name = 'TaskYieldSignal'\n }\n}\n\nexport interface ClaimCheckPointer {\n __claimCheck: string\n}\n\nexport class ReplayCompleteSignal extends Error {\n readonly isReplayComplete = true as const\n constructor() {\n super('ReplayComplete')\n this.name = 'ReplayCompleteSignal'\n }\n}\n\nexport interface ActiveTaskExecution {\n taskId: string\n step: StepRunner\n controller: AbortController\n claimedEpoch?: number\n}\n\nexport interface ActiveWorkflowStore {\n workflow: WorkflowContext\n step: StepRunner\n env?: AppBindings\n}\n\nexport interface CreateStepRunnerOptions {\n isDev?: boolean\n signals?: Record<string, unknown>\n workflowContext?: WorkflowContext\n canYield?: boolean\n claimedEpoch?: number\n abortController?: AbortController\n compensatedSteps?: Record<string, boolean>\n replayOnly?: boolean\n}\n\nexport interface DispatchWorkflowOptions {\n mode?: RouteMode\n timeout?: Duration\n dedupeKey?: string\n wait?: boolean\n maxWaitMs?: number\n signal?: AbortSignal\n userId?: EntryId\n userRole?: DbRole\n}\n\nexport interface ExecuteWorkflowTaskOptions {\n canYield?: boolean\n}\n\nexport type TaskRecord<O = unknown> =\n | { status: 'completed'; response: O }\n | { status: 'errored'; error: string; errorCode?: string; nonRetryable?: boolean }\n | { status: 'cancelled'; error?: string }\n\nexport class TaskWaitDetachedSignal extends Error {\n readonly isTaskWaitDetached = true as const\n constructor(public readonly taskId: string) {\n super(`TaskWaitDetached:${taskId}`)\n this.name = 'TaskWaitDetachedSignal'\n }\n}\n\nexport interface PendingEntry {\n taskId: string\n workflowName: string\n docRef: DocumentReference\n createdAt: number\n hedged: boolean\n hedgeable?: boolean\n keepAlive?: boolean\n unsub?: () => void\n dispatch: () => Promise<void>\n finish: (res: TaskRecord<any>) => void\n}\n\nexport interface WatchTaskOptions {\n isDev?: boolean\n docRef?: DocumentReference\n workflowName?: string\n hedgeable?: boolean\n keepAlive?: boolean\n timeoutMs?: number\n maxWaitMs?: number\n hedgeAfterMs?: number\n pollIntervalMs?: number\n signal?: AbortSignal\n dispatch?: () => Promise<void>\n}\n\nexport interface RouteRegistryItem {\n id: string\n mode: RouteMode\n method: string\n path: string\n workflowName?: string\n auth?: AuthLevel\n description: string\n mcp?: boolean\n tool?: boolean\n input?: z.ZodType<any>\n output?: z.ZodType<any>\n guard?: BaseRouteConfig['guard']\n}\n\nexport interface RouteIntrospectionItem {\n id: string\n method: string\n path: string\n mode: 'rest' | 'workflow'\n workflowName?: string\n auth: string | false\n description: string\n mcp: boolean\n tool: boolean\n guards: string[]\n inputSchema: Record<string, unknown> | null\n outputSchema: Record<string, unknown> | null\n}\n\nexport interface RoutesIntrospectionResponse {\n appName: string\n generatedAt: string\n routes: RouteIntrospectionItem[]\n collections?: Record<\n string,\n {\n relationType: string\n rbac?: Record<string, unknown>\n schema: Record<string, unknown> | null\n }\n >\n}\n\nexport const signalTaskBody = z.object({\n signal: z.string().min(1),\n payload: z.unknown().optional()\n})\n", "import { z } from 'zod'\nimport { CORE_CONFIG } from '../config'\n\nexport type Duration = number | `${number}${'ms' | 's' | 'm' | 'h' | 'd'}`\n\nexport const errorBodySchema = z.object({\n error: z.string(),\n code: z.string().optional(),\n status: z.number().int().optional(),\n retryAfterMs: z.number().int().optional()\n})\n\nexport type ErrorBody = z.infer<typeof errorBodySchema>\n\nexport class NonRetryableError extends Error {\n readonly nonRetryable = true as const\n readonly code?: string\n constructor(message: string, code?: string) {\n super(message)\n this.name = 'NonRetryableError'\n this.code = code\n }\n}\n\nexport class StaleWorkerEpochError extends NonRetryableError {\n readonly isStaleWorkerEpoch = true as const\n readonly taskId?: string\n readonly claimedEpoch?: number\n readonly actualEpoch?: number\n constructor(\n message = 'Worker execution epoch superseded by a newer run or cancellation',\n meta?: { taskId?: string; claimedEpoch?: number; actualEpoch?: number }\n ) {\n super(message, 'STALE_WORKER_EPOCH')\n this.name = 'StaleWorkerEpochError'\n this.taskId = meta?.taskId\n this.claimedEpoch = meta?.claimedEpoch\n this.actualEpoch = meta?.actualEpoch\n }\n}\n\nexport class CircuitBreakerOpenError extends NonRetryableError {\n readonly isCircuitBreakerOpen = true as const\n readonly breakerKey: string\n constructor(breakerKey: string, message = `Circuit breaker \"${breakerKey}\" is OPEN`) {\n super(message, 'CIRCUIT_BREAKER_OPEN')\n this.name = 'CircuitBreakerOpenError'\n this.breakerKey = breakerKey\n }\n}\n\nexport interface SingleflightOptions {\n scope?: 'tenant' | 'global'\n}\n\nexport const LIMITS = CORE_CONFIG.limits.buckets\nexport type Bucket = keyof typeof LIMITS\n\n/** Built-in provider breakers plus any app-defined key (`[a-z0-9-]` recommended; used in a Firestore doc ID). */\nexport type CircuitBreakerKey = 'mistral' | 'jev' | 'vertex' | 'emails' | 'payments' | (string & {})\nexport type CircuitBreakerStateName = 'CLOSED' | 'OPEN' | 'HALF_OPEN'\n\nexport interface CircuitBreakerRecord {\n state: CircuitBreakerStateName\n failureCount: number\n firstFailureAt: number\n openedAt: number\n updatedAt?: number\n}\n", "import { HTTPException } from 'hono/http-exception'\nimport type { ContentfulStatusCode } from 'hono/utils/http-status'\nimport { ZodError } from 'zod'\nimport { CORE_CONFIG } from '../config'\nimport type { Core } from '../index'\nimport {\n CircuitBreakerOpenError,\n errorBodySchema,\n NonRetryableError,\n StaleWorkerEpochError,\n type Bucket,\n type CircuitBreakerKey,\n type CircuitBreakerRecord,\n type CircuitBreakerStateName,\n type Duration,\n type ErrorBody,\n type SingleflightOptions\n} from './schema'\n\nconst DURATION_UNITS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000\n}\n\nexport class ErrorsService {\n readonly NonRetryableError = NonRetryableError\n readonly StaleWorkerEpochError = StaleWorkerEpochError\n readonly CircuitBreakerOpenError = CircuitBreakerOpenError\n\n parseDuration = (d?: Duration, fallbackMs = 0): number => {\n if (d === undefined || d === null) return fallbackMs\n if (typeof d === 'number') return Math.max(0, d)\n const m = /^(\\d+(?:\\.\\d+)?)(ms|s|m|h|d)$/.exec(d.trim())\n if (!m) throw new Error(`Invalid duration: ${d}`)\n return Math.round(Number(m[1]) * (DURATION_UNITS[m[2]!] ?? 1))\n }\n\n buildErrorBody = (error: string, status?: number, code?: string, retryAfterMs?: number): ErrorBody =>\n errorBodySchema.parse({\n error,\n ...(code ? { code } : {}),\n ...(status ? { status } : {}),\n ...(retryAfterMs !== undefined ? { retryAfterMs: Math.ceil(retryAfterMs) } : {})\n })\n\n isStaleWorkerEpochError = (err: unknown): err is StaleWorkerEpochError =>\n err instanceof StaleWorkerEpochError ||\n Boolean(\n err &&\n typeof err === 'object' &&\n ((err as { isStaleWorkerEpoch?: unknown }).isStaleWorkerEpoch === true ||\n (err as { name?: unknown }).name === 'StaleWorkerEpochError')\n )\n\n nonRetryableError = (message: string, code?: string): never => {\n throw new NonRetryableError(message, code)\n }\n\n #jsonErr = (status: ContentfulStatusCode, error: string, code?: string, retryAfterMs?: number): HTTPException => {\n const headers: Record<string, string> = { 'content-type': 'application/json' }\n if (retryAfterMs !== undefined && retryAfterMs > 0) {\n headers['retry-after'] = String(Math.max(1, Math.ceil(retryAfterMs / 1000)))\n }\n return new HTTPException(status, {\n res: new Response(JSON.stringify(this.buildErrorBody(error, status, code, retryAfterMs)), { status, headers })\n })\n }\n\n httpError = (status: ContentfulStatusCode, message: string, code?: string, retryAfterMs?: number): never => {\n throw this.#jsonErr(status, message, code, retryAfterMs)\n }\n\n isNonRetryableError = (err: unknown): boolean => {\n if (err instanceof NonRetryableError || err instanceof ZodError) return true\n if (err instanceof HTTPException && err.status < 500) return true\n if (\n err &&\n typeof err === 'object' &&\n ('nonRetryable' in err || ('code' in err && (err.code === 'NOT_FOUND' || err.code === 5)))\n ) {\n return true\n }\n const msg = err instanceof Error ? err.message : String(err)\n return (\n msg.startsWith('File not found:') ||\n msg.startsWith('Not found:') ||\n msg.includes('NOT_FOUND') ||\n msg.includes('No document to update')\n )\n }\n\n toHttpError = (err: unknown): HTTPException => {\n if (err instanceof HTTPException) return err\n if (err instanceof ZodError) {\n return this.#jsonErr(\n 400,\n err.issues.map((i) => `${i.path.join('.') || 'input'}: ${i.message}`).join('; '),\n 'VALIDATION_ERROR'\n )\n }\n if (err instanceof NonRetryableError) {\n return this.#jsonErr(400, err.message, err.code ?? 'NON_RETRYABLE_ERROR')\n }\n const msg = err instanceof Error ? err.message : ''\n if (msg.startsWith('File not found:') || msg.startsWith('Not found:')) {\n return this.#jsonErr(404, msg, 'NOT_FOUND')\n }\n console.error('[http] unhandled error:', err)\n return this.#jsonErr(500, 'Internal server error', 'INTERNAL_SERVER_ERROR')\n }\n}\n\nclass RateLimiter {\n #slots: number[] = []\n #maxOverride?: number\n #remoteRemaining?: number\n #remoteResetAt = 0\n readonly #bucket: Bucket\n readonly #getMaxWaitMs: () => number\n\n constructor(bucket: Bucket, getMaxWaitMs: () => number) {\n this.#bucket = bucket\n this.#getMaxWaitMs = getMaxWaitMs\n }\n\n #cfg(now = Date.now()) {\n const base = CORE_CONFIG.limits.buckets[this.#bucket]\n const windowMs = this.#bucket === 'mistral' ? base.windowMs + 3000 : base.windowMs\n const max = this.#maxOverride ?? base.max\n const safeMax = this.#bucket === 'mistral' ? Math.max(1, max - 5) : max\n this.#slots = this.#slots.filter((at) => at > now - windowMs)\n if (now >= this.#remoteResetAt) this.#remoteRemaining = undefined\n return { now, windowMs, max, safeMax }\n }\n\n acquire(units = 1): number {\n const { now, windowMs, safeMax } = this.#cfg()\n const needed = Math.max(1, units)\n const next = [...this.#slots]\n let lastAt = now\n if (this.#remoteRemaining !== undefined && this.#remoteRemaining < needed) {\n lastAt = Math.max(lastAt, this.#remoteResetAt)\n }\n for (let i = 0; i < needed; i++) {\n const windowReady = next.length >= safeMax ? next[next.length - safeMax]! + windowMs : now\n lastAt = Math.max(lastAt, windowReady)\n next.push(lastAt)\n }\n const waitMs = Math.max(0, lastAt - now)\n if (waitMs <= this.#getMaxWaitMs()) {\n this.#slots = next\n if (this.#remoteRemaining !== undefined) {\n this.#remoteRemaining = Math.max(0, this.#remoteRemaining - needed)\n }\n }\n return waitMs\n }\n\n charge(units: number) {\n const now = Date.now()\n for (let i = 0; i < units; i++) this.#slots.push(now)\n if (this.#remoteRemaining !== undefined) {\n this.#remoteRemaining = Math.max(0, this.#remoteRemaining - units)\n }\n }\n\n sync(remaining?: number, limit?: number) {\n if (limit && limit > 0) this.#maxOverride = limit\n if (remaining === undefined || Number.isNaN(remaining)) return\n const now = Date.now()\n this.#remoteRemaining = Math.max(0, remaining)\n this.#remoteResetAt = now + (remaining === 0 ? 5_000 : 10_000)\n }\n}\n\nconst inflight = new Map<string, Promise<unknown>>()\nconst limiters = new Map<string, RateLimiter>()\nconst httpCounters = new Map<string, { count: number; resetAt: number }>()\nconst breakerCache = new Map<string, { record: CircuitBreakerRecord; cachedAt: number }>()\n\nconst BREAKER_CACHE_TTL_MS = 3_000\nconst BREAKER_FAILURE_WINDOW_MS = 30_000\nconst BREAKER_TRIP_THRESHOLD = 3\nconst BREAKER_OPEN_DURATION_MS = 45_000\n\nconst breakerCacheKey = (key: CircuitBreakerKey, isDev: boolean): string => `${isDev ? 'dev' : 'prod'}:${key}`\nconst breakerDocPath = (key: CircuitBreakerKey): string => `_system/breaker_${key}`\n\nexport class ResilienceService {\n readonly #core: Core\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n }\n\n #getLimiter = (b: Bucket): RateLimiter => {\n const key = `${this.#core.env.isDev ? 'dev' : 'prod'}:${b}`\n return (\n limiters.get(key) ??\n (limiters.set(key, new RateLimiter(b, () => this.#core.config.limits.maxWaitMs)), limiters.get(key)!)\n )\n }\n\n singleflight = <T>(key: string, fn: () => Promise<T>, opts?: SingleflightOptions): Promise<T> => {\n const scope = opts?.scope ?? 'tenant'\n const active = this.#core.internals.context.getState()\n const activeUserId = scope === 'tenant' ? active?.userId : undefined\n const scopedKey = activeUserId ? `tenant:${activeUserId}:${key}` : `global:${key}`\n\n const existing = inflight.get(scopedKey) as Promise<T> | undefined\n if (existing) return existing\n\n const exec =\n scope === 'global' && active\n ? () =>\n this.#core.internals.context.run(\n { env: active.env, userId: this.#core.config.auth.adminUserId, role: 'admin' },\n fn\n )\n : fn\n const promise = exec().finally(() => {\n inflight.delete(scopedKey)\n })\n inflight.set(scopedKey, promise)\n return promise\n }\n\n acquireLimit = async (bucket: Bucket, cost = 1): Promise<void> => {\n const waitMs = this.#getLimiter(bucket).acquire(cost)\n if (waitMs > this.#core.config.limits.maxWaitMs) {\n this.#core.errors.httpError(429, `Rate limit exceeded for ${bucket}`, 'RATE_LIMITED', waitMs)\n }\n if (waitMs > 0) await new Promise((r) => setTimeout(r, waitMs))\n }\n\n chargeLimit = async (bucket: Bucket, extra: number): Promise<void> => {\n this.#getLimiter(bucket).charge(extra)\n }\n\n syncLimit = async (bucket: Bucket, remaining?: number, max?: number): Promise<void> => {\n this.#getLimiter(bucket).sync(remaining, max)\n }\n\n acquireHttpLimit = (key: string, max = 300, windowMs = 60_000): void => {\n const now = Date.now()\n const existing = httpCounters.get(key)\n if (!existing || now >= existing.resetAt) {\n if (!existing && httpCounters.size >= 5000) {\n httpCounters.delete(httpCounters.keys().next().value!)\n }\n httpCounters.set(key, { count: 1, resetAt: now + windowMs })\n return\n }\n if (existing.count >= max) {\n const retryAfterMs = Math.max(1000, existing.resetAt - now)\n this.#core.errors.httpError(429, 'Rate limit exceeded', 'RATE_LIMITED', retryAfterMs)\n }\n existing.count += 1\n }\n\n #isUpstreamProviderError = (err: unknown): boolean => {\n if (!err) return false\n const rec = typeof err === 'object' ? (err as Record<string, unknown>) : {}\n const rawStatus =\n typeof rec.statusCode === 'number'\n ? rec.statusCode\n : typeof rec.status === 'number'\n ? rec.status\n : undefined\n const code = typeof rec.code === 'string' ? rec.code.toUpperCase() : ''\n const msg = err instanceof Error ? err.message : String(err)\n const lower = msg.toLowerCase()\n\n const parsedStatusMatch = /\\b(?:status(?:\\s+code)?|http)\\s*[:=]?\\s*(\\d{3})\\b/i.exec(msg)\n const status = rawStatus ?? (parsedStatusMatch?.[1] ? Number(parsedStatusMatch[1]) : undefined)\n\n if (status !== undefined) {\n if (status === 400 || status === 401 || status === 403 || status === 404 || status === 415 || status === 422) {\n return false\n }\n if (status === 502 || status === 503 || status === 504 || status === 408) {\n return true\n }\n }\n\n if (\n code === 'ETIMEDOUT' ||\n code === 'ECONNRESET' ||\n code === 'ECONNREFUSED' ||\n code === 'UND_ERR_CONNECT_TIMEOUT' ||\n lower.includes('etimedout') ||\n lower.includes('econnreset') ||\n lower.includes('econnrefused') ||\n lower.includes('socket hang up') ||\n lower.includes('bad gateway') ||\n lower.includes('service unavailable') ||\n lower.includes('gateway timeout') ||\n lower.includes('502') ||\n lower.includes('503') ||\n lower.includes('504')\n ) {\n return true\n }\n\n return false\n }\n\n getCircuitBreakerState = async (\n breakerKey: CircuitBreakerKey,\n isDev: boolean = this.#core.env.isDev,\n forceRefresh = false\n ): Promise<CircuitBreakerRecord> => {\n const cKey = breakerCacheKey(breakerKey, isDev)\n const now = Date.now()\n const hit = breakerCache.get(cKey)\n if (!forceRefresh && hit && now - hit.cachedAt < BREAKER_CACHE_TTL_MS) {\n return hit.record\n }\n\n return this.singleflight(\n `breaker:read:${cKey}`,\n async () => {\n try {\n const snap = await this.#core.db.firestore(isDev).doc(breakerDocPath(breakerKey)).get()\n const d = snap.data() as Partial<CircuitBreakerRecord> | undefined\n const record: CircuitBreakerRecord = {\n state: d?.state === 'OPEN' || d?.state === 'HALF_OPEN' ? d.state : 'CLOSED',\n failureCount: typeof d?.failureCount === 'number' ? d.failureCount : 0,\n firstFailureAt: typeof d?.firstFailureAt === 'number' ? d.firstFailureAt : 0,\n openedAt: typeof d?.openedAt === 'number' ? d.openedAt : 0\n }\n breakerCache.set(cKey, { record, cachedAt: Date.now() })\n return record\n } catch {\n const fallback: CircuitBreakerRecord = {\n state: 'CLOSED',\n failureCount: 0,\n firstFailureAt: 0,\n openedAt: 0\n }\n breakerCache.set(cKey, { record: fallback, cachedAt: Date.now() })\n return fallback\n }\n },\n { scope: 'global' }\n )\n }\n\n resetCircuitBreaker = async (breakerKey: CircuitBreakerKey, isDev: boolean = this.#core.env.isDev): Promise<void> => {\n const cKey = breakerCacheKey(breakerKey, isDev)\n const record: CircuitBreakerRecord = {\n state: 'CLOSED',\n failureCount: 0,\n firstFailureAt: 0,\n openedAt: 0,\n updatedAt: Date.now()\n }\n breakerCache.set(cKey, { record, cachedAt: Date.now() })\n await this.#core.db.firestore(isDev).doc(breakerDocPath(breakerKey)).set(record).catch(() => {})\n }\n\n #computeWindowFailureState = (prevFirst: number, prevCount: number, now: number): CircuitBreakerRecord => {\n const inWindow = prevFirst > 0 && now - prevFirst <= BREAKER_FAILURE_WINDOW_MS\n const failureCount = inWindow ? prevCount + 1 : 1\n const firstFailureAt = inWindow ? prevFirst : now\n const tripped = failureCount >= BREAKER_TRIP_THRESHOLD\n return {\n state: tripped ? 'OPEN' : 'CLOSED',\n failureCount,\n firstFailureAt,\n openedAt: tripped ? now : 0,\n updatedAt: now\n }\n }\n\n #recordBreakerFailure = async (breakerKey: CircuitBreakerKey, isDev: boolean): Promise<CircuitBreakerRecord> => {\n const cKey = breakerCacheKey(breakerKey, isDev)\n const db = this.#core.db.firestore(isDev)\n const docRef = db.doc(breakerDocPath(breakerKey))\n const now = Date.now()\n\n try {\n const updated = await db.runTransaction(async (tx) => {\n const snap = await tx.get(docRef)\n const d = snap.data() as Partial<CircuitBreakerRecord> | undefined\n const prevState: CircuitBreakerStateName =\n d?.state === 'OPEN' || d?.state === 'HALF_OPEN' ? d.state : 'CLOSED'\n const prevFirst = typeof d?.firstFailureAt === 'number' ? d.firstFailureAt : 0\n const prevCount = typeof d?.failureCount === 'number' ? d.failureCount : 0\n\n const next: CircuitBreakerRecord =\n prevState === 'HALF_OPEN'\n ? {\n state: 'OPEN',\n failureCount: Math.max(BREAKER_TRIP_THRESHOLD, prevCount + 1),\n firstFailureAt: prevFirst || now,\n openedAt: now,\n updatedAt: now\n }\n : this.#computeWindowFailureState(prevFirst, prevCount, now)\n tx.set(docRef, next)\n return next\n })\n breakerCache.set(cKey, { record: updated, cachedAt: now })\n return updated\n } catch {\n const localPrev = breakerCache.get(cKey)?.record\n const next = this.#computeWindowFailureState(localPrev?.firstFailureAt ?? 0, localPrev?.failureCount ?? 0, now)\n breakerCache.set(cKey, { record: next, cachedAt: now })\n return next\n }\n }\n\n circuitBreaker = async <T>(\n breakerKey: CircuitBreakerKey,\n fn: () => Promise<T>,\n fallbackFn?: () => Promise<T>,\n opts?: { isDev?: boolean }\n ): Promise<T> => {\n const targetIsDev = opts?.isDev ?? this.#core.env.isDev\n const cKey = breakerCacheKey(breakerKey, targetIsDev)\n let current = await this.getCircuitBreakerState(breakerKey, targetIsDev)\n const now = Date.now()\n\n if (current.state === 'OPEN') {\n if (now - current.openedAt >= BREAKER_OPEN_DURATION_MS) {\n current = { ...current, state: 'HALF_OPEN' }\n breakerCache.set(cKey, { record: current, cachedAt: now })\n void this.#core.db\n .firestore(targetIsDev)\n .doc(breakerDocPath(breakerKey))\n .set({ state: 'HALF_OPEN', updatedAt: now }, { merge: true })\n .catch(() => {})\n } else {\n if (fallbackFn) {\n return fallbackFn()\n }\n throw new CircuitBreakerOpenError(breakerKey)\n }\n }\n\n try {\n const result = await fn()\n if (current.state === 'HALF_OPEN' || current.failureCount > 0) {\n await this.resetCircuitBreaker(breakerKey, targetIsDev)\n }\n return result\n } catch (err) {\n if (this.#isUpstreamProviderError(err)) {\n const updated = await this.#recordBreakerFailure(breakerKey, targetIsDev)\n if (updated.state === 'OPEN' && fallbackFn) {\n return fallbackFn()\n }\n }\n throw err\n }\n }\n}\n", "import { Timestamp, type DocumentReference } from 'firebase-admin/firestore'\nimport { CORE_CONFIG } from '../config'\nimport type { Core } from '../index'\nimport {\n StaleWorkerEpochError,\n type StepRunner,\n type TaskStatusRecord,\n type WorkflowContext,\n type WorkflowRuntimeEntry\n} from './schema'\nimport { TaskStepsEngine } from './steps'\nimport { resolveTaskDeadline } from './utils'\nimport { TaskWatcherEngine } from './watcher'\nimport { TaskWorkerEngine } from './worker'\n\nexport class TasksService {\n readonly #core: Core\n readonly #worker: TaskWorkerEngine\n readonly #steps: TaskStepsEngine\n readonly #watcher: TaskWatcherEngine\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n this.#worker = new TaskWorkerEngine(coreClient)\n this.#steps = new TaskStepsEngine(coreClient, this.#worker.invokeChildWorkflow)\n this.#watcher = new TaskWatcherEngine(coreClient, this.#steps)\n this.#worker.bindEngines(this.#steps, this.#watcher)\n }\n\n #useStep = (): StepRunner => {\n const store = this.#worker.getActiveWorkflowStore()\n return store?.step ?? this.#steps.createStepRunner('workflow')\n }\n\n #assertTaskOwnership = (data: Record<string, unknown> | undefined): void => {\n if (!data) throw this.#core.errors.httpError(404, 'Task not found', 'NOT_FOUND')\n const caller = this.#core.caller\n if (!caller || caller.role === 'admin' || caller.userId === CORE_CONFIG.auth.adminUserId) return\n if (typeof data.userId === 'string' && data.userId !== caller.userId) {\n throw this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n }\n\n status = async <O = unknown>(taskId: string): Promise<TaskStatusRecord<O>> => {\n const isDev = Boolean(this.#core.env.isDev)\n const snap = await this.#core.db.firestore(isDev).collection('_tasks').doc(taskId).get()\n const data = snap.exists ? (snap.data() as Record<string, unknown>) : undefined\n this.#assertTaskOwnership(data)\n const response =\n 'response' in data! ? await this.#steps.maybeHydrateStepValue<O>(data!.response, isDev) : undefined\n return {\n taskId,\n workflowName: String(data!.workflowName ?? ''),\n status: (data!.status as TaskStatusRecord['status']) ?? 'running',\n ...(typeof data!.userId === 'string' ? { userId: data!.userId } : {}),\n ...(typeof data!.epoch === 'number' ? { epoch: data!.epoch } : {}),\n ...('activeRunId' in data! ? { activeRunId: (data!.activeRunId as string | null) ?? null } : {}),\n ...(typeof data!.lastHeartbeatAt === 'number' ? { lastHeartbeatAt: data!.lastHeartbeatAt } : {}),\n ...(data!.compensatedSteps\n ? { compensatedSteps: data!.compensatedSteps as Record<string, boolean> }\n : {}),\n ...(data!.progress ? { progress: data!.progress as TaskStatusRecord['progress'] } : {}),\n ...('response' in data! ? { response: response as O } : {}),\n ...(typeof data!.error === 'string' ? { error: data!.error } : {}),\n ...(typeof data!.createdAt === 'string' ? { createdAt: data!.createdAt } : {}),\n ...(typeof data!.updatedAt === 'string' ? { updatedAt: data!.updatedAt } : {})\n }\n }\n\n signal = async (\n taskId: string,\n signalName: string,\n payload?: unknown\n ): Promise<{ taskId: string; signaled: true }> => {\n const isDev = Boolean(this.#core.env.isDev)\n const db = this.#core.db.firestore(isDev)\n const docRef = db.collection('_tasks').doc(taskId)\n\n const outcome = await db.runTransaction(async (tx) => {\n const snap = await tx.get(docRef)\n const data = snap.exists ? (snap.data() as Record<string, unknown>) : undefined\n this.#assertTaskOwnership(data)\n\n const workflowName = String(data!.workflowName ?? '')\n const params = (data!.params as Record<string, unknown> | undefined) ?? {}\n const signals = {\n ...((data!.signals as Record<string, unknown> | undefined) ?? {}),\n [signalName]: payload ?? true\n }\n const wasWaiting = data!.status === 'waiting_signal'\n const currentEpoch = typeof data!.epoch === 'number' ? data!.epoch : 0\n const nextEpoch = wasWaiting ? currentEpoch + 1 : currentEpoch\n\n tx.set(\n docRef,\n {\n signals,\n ...(wasWaiting ? { status: 'running', waitingSignal: null, epoch: nextEpoch, activeRunId: null } : {}),\n updatedAt: new Date().toISOString()\n },\n { merge: true }\n )\n return { workflowName, params, wasWaiting, nextEpoch }\n })\n\n if (outcome.wasWaiting) {\n const wf = this.#worker.getRuntime().registry[outcome.workflowName]\n const deadline = resolveTaskDeadline(outcome.workflowName, wf?.deadlineSeconds)\n if (CORE_CONFIG.tasks.useCloudTasks) {\n await this.#watcher.enqueueBatched(\n {\n taskId,\n workflowName: outcome.workflowName,\n params: outcome.params,\n isDev,\n expectedEpoch: outcome.nextEpoch\n },\n deadline\n )\n } else if (wf) {\n void this.#worker\n .execute({\n taskId,\n workflowName: outcome.workflowName,\n params: outcome.params,\n isDev,\n expectedEpoch: outcome.nextEpoch\n })\n .catch(() => {})\n }\n }\n return { taskId, signaled: true }\n }\n\n #replayUncompensatedSteps = async (\n taskId: string,\n docRef: DocumentReference,\n freshData: Record<string, unknown>,\n isDev: boolean\n ): Promise<void> => {\n const stepsMap = { ...((freshData.steps as Record<string, unknown> | undefined) ?? {}) }\n const compMap = { ...((freshData.compensatedSteps as Record<string, boolean> | undefined) ?? {}) }\n const workflowName = String(freshData.workflowName ?? '')\n const wf: WorkflowRuntimeEntry | undefined = this.#worker.getRuntime().registry[workflowName]\n if (!wf || !Object.keys(stepsMap).some((k) => !compMap[k])) return\n\n const effectiveEnv = this.#core.env\n const expiresAt = Timestamp.fromMillis(Date.now() + CORE_CONFIG.tasks.ttlMs)\n const now = Date.now()\n const wfCtx: WorkflowContext = {\n taskId,\n workflowName,\n attempt: 1,\n startedAt: now,\n deadlineMs: now + 60_000,\n signal: new AbortController().signal\n }\n const replayStep = this.#steps.createStepRunner(wf.mode, docRef, stepsMap, expiresAt, {\n isDev,\n workflowContext: wfCtx,\n canYield: false,\n compensatedSteps: compMap,\n replayOnly: true\n })\n const params = (freshData.params as Record<string, unknown> | undefined) ?? {}\n try {\n await this.#worker.runWithWorkflowContext({ workflow: wfCtx, step: replayStep, env: effectiveEnv }, () =>\n this.#core.internals.context.run(\n { env: effectiveEnv, userId: this.#core.userId, role: this.#core.role, step: replayStep },\n () => wf.runTask(params, replayStep)\n )\n )\n } catch {}\n await replayStep.compensate()\n }\n\n cancel = async (taskId: string): Promise<{ taskId: string; status: 'cancelled' }> => {\n const isDev = Boolean(this.#core.env.isDev)\n const db = this.#core.db.firestore(isDev)\n const docRef = db.collection('_tasks').doc(taskId)\n const preActiveExec = this.#worker.getActiveTaskExecution(taskId)\n\n const txResult = await db.runTransaction(async (tx) => {\n const snap = await tx.get(docRef)\n const data = snap.exists ? (snap.data() as Record<string, unknown>) : undefined\n this.#assertTaskOwnership(data)\n\n const currentStatus = data!.status as string | undefined\n if (currentStatus === 'completed' || currentStatus === 'errored' || currentStatus === 'cancelled') {\n return { alreadyTerminal: true as const, data: data! }\n }\n\n const currentEpoch = typeof data!.epoch === 'number' ? data!.epoch : 0\n const nextEpoch = currentEpoch + 1\n tx.set(\n docRef,\n {\n status: 'compensating',\n epoch: nextEpoch,\n activeRunId: null,\n updatedAt: new Date().toISOString()\n },\n { merge: true }\n )\n return { alreadyTerminal: false as const, nextEpoch, data: data! }\n })\n\n if (!txResult.alreadyTerminal) {\n const activeExec = preActiveExec ?? this.#worker.getActiveTaskExecution(taskId)\n if (activeExec) {\n activeExec.controller.abort(\n new StaleWorkerEpochError(`Task ${taskId} cancelled by caller`, {\n taskId,\n claimedEpoch: activeExec.claimedEpoch,\n actualEpoch: txResult.nextEpoch\n })\n )\n await activeExec.step.compensate()\n }\n\n const freshSnap = await docRef.get().catch(() => null)\n const freshData = (freshSnap?.data() as Record<string, unknown> | undefined) ?? txResult.data\n await this.#replayUncompensatedSteps(taskId, docRef, freshData, isDev)\n\n await docRef.set(\n {\n status: 'cancelled',\n activeRunId: null,\n error: 'Cancelled by caller',\n updatedAt: new Date().toISOString()\n },\n { merge: true }\n )\n }\n\n return { taskId, status: 'cancelled' }\n }\n\n get internals() {\n return {\n createStepRunner: this.#steps.createStepRunner,\n allWithRollback: this.#steps.allWithRollback,\n getContext: this.#worker.getContext,\n useStep: this.#useStep,\n getActiveWorkflowStore: this.#worker.getActiveWorkflowStore,\n dispatch: this.#worker.dispatch,\n execute: this.#worker.execute,\n registerRuntime: this.#worker.registerRuntime,\n getRuntime: this.#worker.getRuntime,\n watchTask: this.#watcher.watchTask,\n getActiveWatcherCount: this.#watcher.getActiveWatcherCount\n }\n }\n}\n", "import { Timestamp, type DocumentReference, type Firestore } from 'firebase-admin/firestore'\nimport { z } from 'zod'\nimport { CORE_CONFIG, type DbRole } from '../config'\nimport type { EntryId } from '../db'\nimport type { RouteMode } from '../router'\nimport type { Duration } from '../utils'\nimport {\n StaleWorkerEpochError,\n TaskWaitDetachedSignal,\n TaskYieldSignal,\n type ClaimCheckPointer,\n type StepContext,\n type StepRetryPolicy,\n type TaskRecord,\n type WorkflowContext,\n type WorkflowTargetRef,\n type WorkflowTaskPayload\n} from './schema'\n\nexport interface StepRunnerState {\n mode: RouteMode\n docRef?: DocumentReference\n steps: Record<string, unknown>\n expiresAt?: Timestamp\n isDev: boolean\n signals: Record<string, unknown>\n wfCtx?: WorkflowContext\n canYield: boolean\n compensatedSteps: Record<string, boolean>\n replayOnly: boolean\n claimedEpoch?: number\n fencedError: Error | null\n activePersistPromise: Promise<void> | null\n pendingPersist: boolean\n writes: Promise<unknown>[]\n rollbacks: { name: string; run: () => Promise<unknown> }[]\n callCounts: Map<string, number>\n abortController?: AbortController\n}\n\nexport const isTaskYieldSignal = (err: unknown): err is TaskYieldSignal =>\n err instanceof TaskYieldSignal || Boolean(err && typeof err === 'object' && (err as any).isTaskYield === true)\n\nexport const isClaimCheckPointer = (val: unknown): val is ClaimCheckPointer =>\n Boolean(val && typeof val === 'object' && typeof (val as any).__claimCheck === 'string')\n\nexport const isTaskWaitDetachedSignal = (err: unknown): err is TaskWaitDetachedSignal =>\n err instanceof TaskWaitDetachedSignal ||\n Boolean(err && typeof err === 'object' && (err as { isTaskWaitDetached?: unknown }).isTaskWaitDetached === true)\n\nexport const zodToJsonSchemaSafe = (schema?: z.ZodType<any>): Record<string, unknown> | null => {\n if (!schema) return null\n try {\n const raw = z.toJSONSchema(schema, { unrepresentable: 'any' }) as Record<string, unknown>\n const { $schema: _$schema, ...rest } = raw\n return rest\n } catch {\n return null\n }\n}\n\nexport const resolveTaskDeadline = (workflowName: string, deadlineSeconds?: number): number =>\n deadlineSeconds ??\n (workflowName === 'scan-attachment'\n ? CORE_CONFIG.tasks.scanDeadlineSeconds\n : CORE_CONFIG.tasks.defaultDeadlineSeconds)\n\nexport const getQueueLoc = (): string => `projects/${CORE_CONFIG.gcpProject}/locations/${CORE_CONFIG.region}`\n\nexport const getQueueBase = (isDev = false): string =>\n `${getQueueLoc()}/queues/${isDev ? CORE_CONFIG.queueBaseNames.dev : CORE_CONFIG.queueBaseNames.prod}`\n\nexport const getQueueParent = (idx: number, isDev = false): string => {\n const base = getQueueBase(isDev)\n return idx === 0 ? base : `${base}-${String(idx).padStart(2, '0')}`\n}\n\nexport const getWorkerUri = (isDev = false): string =>\n isDev ? CORE_CONFIG.workerUris.dev : CORE_CONFIG.workerUris.prod\n\nexport const isTerminalRecord = (d: TaskRecord<unknown> | undefined): d is TaskRecord<unknown> =>\n Boolean(d && (d.status === 'completed' || d.status === 'errored' || d.status === 'cancelled'))\n\nexport const setTaskDoc = (docRef: DocumentReference, patch: Record<string, unknown>): Promise<void> =>\n docRef\n .set(patch, { mergeFields: Object.keys(patch).filter((k) => patch[k] !== undefined) })\n .then(() => {})\n .catch(() => {})\n\nexport const resolveTargetName = (target: string | WorkflowTargetRef<any, any>): string => {\n if (typeof target === 'string') return target\n if (target.workflowName) return target.workflowName\n throw new Error('Workflow target must specify a workflowName or route key')\n}\n\nexport const isFencedOut = (\n claimedEpoch: number | undefined,\n docEpoch: number | undefined,\n docStatus: string | undefined,\n requireRunning = false\n): boolean => {\n if (claimedEpoch !== undefined && docEpoch !== undefined && docEpoch !== claimedEpoch) return true\n if (requireRunning) return docStatus !== 'running'\n return (\n docStatus === 'compensating' ||\n docStatus === 'cancelled' ||\n docStatus === 'completed' ||\n docStatus === 'errored'\n )\n}\n\nexport const createStaleEpochError = (\n taskId: string | undefined,\n claimedEpoch: number | undefined,\n actualEpoch: number | undefined,\n status?: string\n): StaleWorkerEpochError =>\n new StaleWorkerEpochError(\n `Worker epoch ${claimedEpoch ?? 'unknown'} superseded by epoch ${actualEpoch ?? 'unknown'} (status=${status ?? 'unknown'})`,\n {\n ...(taskId ? { taskId } : {}),\n ...(claimedEpoch !== undefined ? { claimedEpoch } : {}),\n ...(actualEpoch !== undefined ? { actualEpoch } : {})\n }\n )\n\nconst compensationLocks = new Map<string, Promise<void>>()\n\nexport const runSerializedCompensation = async (taskId: string, fn: () => Promise<void>): Promise<void> => {\n const prev = compensationLocks.get(taskId) ?? Promise.resolve()\n const next = prev.catch(() => {}).then(fn)\n compensationLocks.set(taskId, next)\n try {\n await next\n } finally {\n if (compensationLocks.get(taskId) === next) compensationLocks.delete(taskId)\n }\n}\n\nexport const executeCompensateState = async (s: StepRunnerState): Promise<void> => {\n await Promise.allSettled(s.writes)\n if (!s.rollbacks.length) return\n if (s.docRef) {\n const snap = await s.docRef.get().catch(() => null)\n const remoteComp = snap?.data()?.compensatedSteps as Record<string, boolean> | undefined\n if (remoteComp && typeof remoteComp === 'object') Object.assign(s.compensatedSteps, remoteComp)\n }\n for (const item of [...s.rollbacks].reverse()) {\n if (s.compensatedSteps[item.name]) {\n delete s.steps[item.name]\n continue\n }\n await item.run()\n s.compensatedSteps[item.name] = true\n delete s.steps[item.name]\n if (s.docRef) {\n const patch: Record<string, unknown> = {\n compensatedSteps: { ...s.compensatedSteps },\n steps: { ...s.steps },\n updatedAt: new Date().toISOString(),\n ...(s.expiresAt ? { expiresAt: s.expiresAt } : {})\n }\n await s.docRef.set(patch, { mergeFields: Object.keys(patch) })\n }\n }\n}\n\nexport const runStepWithRetry = async <T>(\n fn: (ctx: StepContext) => Promise<T>,\n retryOrCount: number | StepRetryPolicy = 2,\n delayMs = 1000,\n stepId = 'step',\n timeout: Duration | undefined,\n parentSignal: AbortSignal | undefined,\n parseDuration: (d: Duration | undefined, fallbackMs: number) => number,\n isNonRetryableError: (err: unknown) => boolean\n): Promise<T> => {\n const policy: StepRetryPolicy =\n typeof retryOrCount === 'number'\n ? { maxAttempts: retryOrCount + 1, initialInterval: delayMs, backoffCoefficient: 1.5 }\n : retryOrCount\n const maxAttempts = Math.max(1, policy.maxAttempts ?? 3)\n const initialMs = parseDuration(policy.initialInterval, delayMs)\n const backoff = policy.backoffCoefficient ?? 1.5\n const maxIntervalMs = policy.maxInterval ? parseDuration(policy.maxInterval, 30_000) : 30_000\n const useJitter = policy.jitter !== false\n const timeoutMs = timeout ? parseDuration(timeout, 0) : 0\n\n let lastErr: unknown\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const controller = new AbortController()\n const onParentAbort = () => controller.abort(parentSignal?.reason)\n if (parentSignal) {\n if (parentSignal.aborted) controller.abort(parentSignal.reason)\n else parentSignal.addEventListener('abort', onParentAbort, { once: true })\n }\n const timer =\n timeoutMs > 0\n ? setTimeout(() => controller.abort(new Error(`Step \"${stepId}\" timed out after ${timeoutMs}ms`)), timeoutMs)\n : undefined\n try {\n const result = await fn({ signal: controller.signal, attempt, stepId })\n if (timer) clearTimeout(timer)\n if (parentSignal) parentSignal.removeEventListener('abort', onParentAbort)\n return result\n } catch (err) {\n if (timer) clearTimeout(timer)\n if (parentSignal) parentSignal.removeEventListener('abort', onParentAbort)\n if (isTaskYieldSignal(err)) throw err\n lastErr = err\n const errName = err instanceof Error ? err.name : ''\n if (isNonRetryableError(err) || (errName && policy.nonRetryableErrorTypes?.includes(errName))) throw err\n if (attempt < maxAttempts) {\n const rawWait = Math.min(maxIntervalMs, initialMs * Math.pow(backoff, attempt - 1))\n const waitMs = useJitter ? Math.round(rawWait * (0.75 + Math.random() * 0.5)) : Math.round(rawWait)\n await new Promise((r) => setTimeout(r, waitMs))\n }\n }\n }\n throw lastErr\n}\n\nexport const claimTaskEpochTx = (\n db: Firestore,\n docRef: DocumentReference,\n payload: WorkflowTaskPayload,\n attempt: number,\n resolveRole: (userId?: EntryId, explicitRole?: DbRole) => DbRole\n) =>\n db.runTransaction(async (tx) => {\n const data = (await tx.get(docRef)).data()\n const currentStatus = data?.status as string | undefined\n if (['completed', 'errored', 'cancelled', 'compensating'].includes(String(currentStatus))) {\n return { aborted: true as const }\n }\n const currentEpoch = typeof data?.epoch === 'number' ? data.epoch : 0\n if (attempt === 0 && payload.expectedEpoch !== undefined && currentEpoch !== payload.expectedEpoch) {\n return { aborted: true as const }\n }\n const claimedEpoch = currentEpoch + 1\n const activeRunId = crypto.randomUUID()\n const startedAt = Date.now()\n const expiresAt = Timestamp.fromMillis(startedAt + CORE_CONFIG.tasks.ttlMs)\n const effectiveParams = (data?.params as Record<string, unknown> | undefined) ?? payload.params\n const userId: EntryId = typeof data?.userId === 'string' ? data.userId : CORE_CONFIG.auth.adminUserId\n const userRole = resolveRole(userId, data?.userRole as DbRole | undefined)\n const steps: Record<string, unknown> = { ...((data?.steps as Record<string, unknown> | undefined) ?? {}) }\n const signals: Record<string, unknown> = { ...((data?.signals as Record<string, unknown> | undefined) ?? {}) }\n const compensatedSteps: Record<string, boolean> = {\n ...((data?.compensatedSteps as Record<string, boolean> | undefined) ?? {})\n }\n tx.set(\n docRef,\n {\n taskId: payload.taskId,\n workflowName: payload.workflowName,\n userId,\n userRole,\n status: 'running',\n epoch: claimedEpoch,\n activeRunId,\n lastHeartbeatAt: startedAt,\n params: effectiveParams,\n steps,\n compensatedSteps,\n updatedAt: new Date(startedAt).toISOString(),\n expiresAt\n },\n { merge: true }\n )\n return {\n aborted: false as const,\n claimedEpoch,\n startedAt,\n expiresAt,\n effectiveParams,\n userId,\n userRole,\n steps,\n signals,\n compensatedSteps\n }\n })\n\nexport const startTaskHeartbeatTimer = (\n db: Firestore,\n docRef: DocumentReference,\n taskId: string,\n claimedEpoch: number,\n expiresAt: Timestamp,\n controller: AbortController\n): ReturnType<typeof setInterval> => {\n const timer = setInterval(() => {\n void db\n .runTransaction(async (tx) => {\n const data = (await tx.get(docRef)).data()\n if (data?.epoch !== claimedEpoch || data?.status !== 'running') {\n controller.abort(\n new StaleWorkerEpochError(`Heartbeat detected stale epoch on ${taskId}`, {\n taskId,\n claimedEpoch,\n actualEpoch: typeof data?.epoch === 'number' ? data.epoch : undefined\n })\n )\n return\n }\n tx.set(docRef, { lastHeartbeatAt: Date.now(), updatedAt: new Date().toISOString(), expiresAt }, { merge: true })\n })\n .catch(() => {})\n }, CORE_CONFIG.tasks.heartbeatIntervalMs)\n timer.unref?.()\n return timer\n}\n\nexport const commitTaskCompletionTx = (\n db: Firestore,\n docRef: DocumentReference,\n baseMeta: Record<string, unknown>,\n taskId: string,\n claimedEpoch: number,\n storedResponse: unknown,\n steps: Record<string, unknown>,\n expiresAt: Timestamp\n): Promise<void> =>\n db.runTransaction(async (tx) => {\n const data = (await tx.get(docRef)).data()\n const docEpoch = typeof data?.epoch === 'number' ? data.epoch : undefined\n if (docEpoch !== claimedEpoch || data?.status !== 'running') {\n throw new StaleWorkerEpochError(`Completion fenced on ${taskId}`, {\n taskId,\n claimedEpoch,\n actualEpoch: docEpoch\n })\n }\n tx.set(\n docRef,\n {\n ...baseMeta,\n status: 'completed',\n epoch: claimedEpoch,\n activeRunId: null,\n response: storedResponse,\n steps,\n lastHeartbeatAt: Date.now(),\n updatedAt: new Date().toISOString(),\n expiresAt\n },\n { merge: true }\n )\n })\n\nexport const commitTaskYieldTx = async (\n db: Firestore,\n docRef: DocumentReference,\n baseMeta: Record<string, unknown>,\n taskId: string,\n claimedEpoch: number,\n err: TaskYieldSignal,\n nextEpoch: number,\n nextParams: Record<string, unknown>,\n nextSteps: Record<string, unknown>,\n nextStatus: string,\n expiresAt: Timestamp\n): Promise<void> => {\n const yieldCommitted = await db.runTransaction(async (tx) => {\n const data = (await tx.get(docRef)).data()\n const docEpoch = typeof data?.epoch === 'number' ? data.epoch : undefined\n if (docEpoch !== claimedEpoch || data?.status !== 'running') {\n return { fenced: true as const, docEpoch }\n }\n tx.set(\n docRef,\n {\n ...baseMeta,\n status: nextStatus,\n epoch: nextEpoch,\n activeRunId: null,\n params: nextParams,\n steps: nextSteps,\n ...(err.reason === 'waiting_signal' ? { waitingSignal: err.meta.signalName ?? null } : {}),\n updatedAt: new Date().toISOString(),\n expiresAt\n },\n {\n mergeFields: [\n 'taskId',\n 'workflowName',\n 'userId',\n 'userRole',\n 'status',\n 'epoch',\n 'activeRunId',\n 'params',\n 'steps',\n ...(err.reason === 'waiting_signal' ? ['waitingSignal'] : []),\n 'updatedAt',\n 'expiresAt'\n ]\n }\n )\n return { fenced: false as const }\n })\n if (yieldCommitted.fenced) {\n throw new StaleWorkerEpochError(`Yield fenced on ${taskId}`, {\n taskId,\n claimedEpoch,\n actualEpoch: yieldCommitted.docEpoch\n })\n }\n}\n\nexport const commitTaskCompensatingTx = async (\n db: Firestore,\n docRef: DocumentReference,\n taskId: string,\n claimedEpoch: number,\n expiresAt: Timestamp\n): Promise<void> => {\n const compTransition = await db.runTransaction(async (tx) => {\n const data = (await tx.get(docRef)).data()\n const docEpoch = typeof data?.epoch === 'number' ? data.epoch : undefined\n if (docEpoch !== claimedEpoch || data?.status !== 'running') {\n return { fenced: true as const, docEpoch }\n }\n tx.set(\n docRef,\n {\n status: 'compensating',\n epoch: claimedEpoch + 1,\n activeRunId: null,\n updatedAt: new Date().toISOString(),\n expiresAt\n },\n { merge: true }\n )\n return { fenced: false as const }\n })\n if (compTransition.fenced) {\n throw new StaleWorkerEpochError(`Error compensation fenced on ${taskId}`, {\n taskId,\n claimedEpoch,\n actualEpoch: compTransition.docEpoch\n })\n }\n}\n", "import type { DocumentReference, Timestamp } from 'firebase-admin/firestore'\nimport { CORE_CONFIG } from '../config'\nimport type { Core } from '../index'\nimport type { RouteMode } from '../router'\nimport type { Duration } from '../utils'\nimport {\n ReplayCompleteSignal,\n TaskYieldSignal,\n type ClaimCheckPointer,\n type CreateStepRunnerOptions,\n type RollbackLeg,\n type StepContext,\n type StepFn,\n type StepMapOptions,\n type StepOptions,\n type StepRetryPolicy,\n type StepRunner,\n type StepSpec,\n type TaskProgressUpdate,\n type WorkflowContext,\n type WorkflowTargetRef\n} from './schema'\nimport {\n createStaleEpochError,\n executeCompensateState,\n isClaimCheckPointer,\n isFencedOut,\n resolveTargetName,\n runSerializedCompensation,\n runStepWithRetry,\n type StepRunnerState\n} from './utils'\n\nconst CUMULATIVE_STEPS_THRESHOLD_BYTES = 150 * 1024\n\nexport class TaskStepsEngine {\n readonly #core: Core\n readonly #invokeChildWorkflow: (\n targetName: string,\n input: unknown,\n options?: { timeout?: Duration; dedupeKey?: string; wait?: boolean }\n ) => Promise<any>\n\n constructor(\n coreClient: Core,\n invokeChildWorkflow: (\n targetName: string,\n input: unknown,\n options?: { timeout?: Duration; dedupeKey?: string; wait?: boolean }\n ) => Promise<any>\n ) {\n this.#core = coreClient\n this.#invokeChildWorkflow = invokeChildWorkflow\n }\n\n maybeOffloadStepValue = async (\n docRef: DocumentReference | undefined,\n stepId: string,\n val: unknown,\n isDev = false,\n forceOffload = false\n ): Promise<unknown> => {\n if (!docRef || val === undefined || val === null || isClaimCheckPointer(val)) return val\n try {\n const json = JSON.stringify(val)\n if (!json) return val\n if (!forceOffload && Buffer.byteLength(json, 'utf8') <= CORE_CONFIG.tasks.claimCheckThresholdBytes) {\n return val\n }\n const gcsPath = `_tasks/${docRef.id}/steps/${encodeURIComponent(stepId)}.json`\n await this.#core.db\n .bucket(isDev)\n .file(gcsPath)\n .save(Buffer.from(json, 'utf8'), {\n resumable: false,\n validation: false,\n contentType: 'application/json'\n })\n return { __claimCheck: gcsPath } satisfies ClaimCheckPointer\n } catch {\n return val\n }\n }\n\n maybeHydrateStepValue = async <T>(raw: unknown, isDev = false): Promise<T> => {\n if (!isClaimCheckPointer(raw)) return raw as T\n const [buf] = await this.#core.db.bucket(isDev).file(raw.__claimCheck).download()\n return JSON.parse(buf.toString('utf8')) as T\n }\n\n allWithRollback = async <T extends readonly unknown[]>(\n legs: { [K in keyof T]: RollbackLeg<T[K]> }\n ): Promise<T> => {\n const settled = await Promise.allSettled(legs.map((l) => l.fn()))\n const failed = settled.find((s): s is PromiseRejectedResult => s.status === 'rejected')\n if (failed) {\n await Promise.allSettled(\n settled.map((s, i) => (s.status === 'fulfilled' && legs[i]?.rollback ? legs[i]!.rollback!(s.value) : undefined))\n )\n throw failed.reason\n }\n return settled.map((s) => (s as PromiseFulfilledResult<unknown>).value) as unknown as T\n }\n\n #assertNotFenced = (s: StepRunnerState): void => {\n if (s.fencedError) throw s.fencedError\n if (s.wfCtx?.signal?.aborted && this.#core.errors.isStaleWorkerEpochError(s.wfCtx.signal.reason)) {\n s.fencedError = s.wfCtx.signal.reason\n throw s.fencedError\n }\n }\n\n #triggerFenceAbort = (s: StepRunnerState, actualEpoch?: number, status?: string): never => {\n if (!s.fencedError) {\n s.fencedError = createStaleEpochError(s.docRef?.id, s.claimedEpoch, actualEpoch, status)\n }\n s.abortController?.abort(s.fencedError)\n throw s.fencedError\n }\n\n #runFencedPersistOnce = async (s: StepRunnerState): Promise<void> => {\n if (!s.docRef) return\n this.#assertNotFenced(s)\n try {\n if (Buffer.byteLength(JSON.stringify(s.steps), 'utf8') > CUMULATIVE_STEPS_THRESHOLD_BYTES) {\n for (const [k, v] of Object.entries(s.steps)) {\n if (v !== undefined && v !== null && typeof v === 'object' && !isClaimCheckPointer(v)) {\n s.steps[k] = await this.maybeOffloadStepValue(s.docRef, k, v, s.isDev, true)\n }\n }\n }\n } catch {}\n\n const docRef = s.docRef\n await docRef.firestore.runTransaction(async (tx) => {\n const snap = await tx.get(docRef)\n const data = snap.data()\n const docEpoch = typeof data?.epoch === 'number' ? data.epoch : undefined\n const docStatus = typeof data?.status === 'string' ? data.status : undefined\n if (s.claimedEpoch === undefined && docEpoch !== undefined) s.claimedEpoch = docEpoch\n if (isFencedOut(s.claimedEpoch, docEpoch, docStatus)) {\n this.#triggerFenceAbort(s, docEpoch, docStatus)\n }\n const patch: Record<string, unknown> = {\n steps: { ...s.steps },\n lastHeartbeatAt: Date.now(),\n ...(s.expiresAt ? { expiresAt: s.expiresAt } : {})\n }\n tx.set(docRef, patch, { mergeFields: Object.keys(patch) })\n })\n }\n\n #persistSteps = (s: StepRunnerState): Promise<void> => {\n if (!s.docRef) return Promise.resolve()\n this.#assertNotFenced(s)\n if (s.activePersistPromise) {\n s.pendingPersist = true\n return s.activePersistPromise\n }\n const loop = (async () => {\n try {\n do {\n s.pendingPersist = false\n await this.#runFencedPersistOnce(s)\n } while (s.pendingPersist && !s.fencedError)\n } finally {\n s.activePersistPromise = null\n }\n })()\n s.activePersistPromise = loop\n s.writes.push(loop.catch(() => {}))\n return loop\n }\n\n #executeSingleStep = async <T>(\n s: StepRunnerState,\n flushFn: () => Promise<unknown>,\n stepId: string,\n fnOrSpec: StepSpec<T>,\n options?: StepOptions<T>\n ): Promise<T> => {\n this.#assertNotFenced(s)\n const fn = typeof fnOrSpec === 'function' ? fnOrSpec : fnOrSpec.fn\n const rollback = options?.rollback ?? (typeof fnOrSpec === 'function' ? undefined : fnOrSpec.rollback)\n const retry = options?.retry ?? (typeof fnOrSpec === 'function' ? undefined : fnOrSpec.retry)\n const timeout = options?.timeout ?? (typeof fnOrSpec === 'function' ? undefined : fnOrSpec.timeout)\n\n const registerRollback = (val: T) => {\n if (!rollback) return\n const idx = s.rollbacks.findIndex((r) => r.name === stepId)\n if (idx !== -1) s.rollbacks.splice(idx, 1)\n s.rollbacks.push({ name: stepId, run: () => rollback(val) })\n }\n\n if (stepId in s.steps) {\n const cached = await this.maybeHydrateStepValue<T>(s.steps[stepId], s.isDev)\n registerRollback(cached)\n return cached\n }\n if (s.replayOnly) throw new ReplayCompleteSignal()\n\n if (s.canYield && s.wfCtx) {\n const budgetMs = (s.wfCtx.deadlineMs - s.wfCtx.startedAt) * CORE_CONFIG.tasks.yieldBudgetRatio\n if (budgetMs > 0 && Date.now() - s.wfCtx.startedAt > budgetMs) {\n await flushFn()\n throw new TaskYieldSignal('yield', { delaySeconds: 0 })\n }\n }\n this.#assertNotFenced(s)\n\n const val = await (s.mode !== 'rest' || retry !== undefined || timeout !== undefined\n ? runStepWithRetry(\n fn,\n retry ?? (s.mode !== 'rest' ? 2 : 0),\n 1000,\n stepId,\n timeout,\n s.wfCtx?.signal,\n this.#core.errors.parseDuration,\n this.#core.errors.isNonRetryableError\n )\n : fn({ signal: s.wfCtx?.signal ?? new AbortController().signal, attempt: 1, stepId }))\n\n this.#assertNotFenced(s)\n s.steps[stepId] = await this.maybeOffloadStepValue(s.docRef, stepId, val, s.isDev)\n if (s.docRef) {\n try {\n await this.#persistSteps(s)\n } catch (err) {\n if (this.#core.errors.isStaleWorkerEpochError(err)) {\n delete s.steps[stepId]\n throw err\n }\n }\n }\n registerRollback(val)\n return val\n }\n\n #mapStep = async <T, R>(\n s: StepRunnerState,\n flushFn: () => Promise<unknown>,\n stepId: string,\n items: readonly T[],\n fn: (item: T, index: number, ctx: StepContext) => Promise<R>,\n options?: StepMapOptions<T, R>\n ): Promise<R[]> => {\n if (items.length === 0) return []\n if (stepId in s.steps) return this.maybeHydrateStepValue<R[]>(s.steps[stepId], s.isDev)\n\n const results = new Array<R>(items.length)\n const pendingIndices: number[] = []\n\n if (options?.shortCircuit) {\n const checks = await Promise.all(items.map((item, idx) => options.shortCircuit!(item, idx)))\n for (let i = 0; i < items.length; i++) {\n if (checks[i] !== undefined) results[i] = checks[i]!\n else pendingIndices.push(i)\n }\n } else {\n for (let i = 0; i < items.length; i++) pendingIndices.push(i)\n }\n\n if (pendingIndices.length > 0) {\n const concurrency = Math.max(1, options?.concurrency ?? CORE_CONFIG.tasks.defaultShardsCount)\n let cursor = 0\n const workers = Array.from({ length: Math.min(concurrency, pendingIndices.length) }, async () => {\n while (cursor < pendingIndices.length) {\n const idx = pendingIndices[cursor++]!\n results[idx] = await this.#executeSingleStep(\n s,\n flushFn,\n `${stepId}:${idx}`,\n (ctx) => fn(items[idx]!, idx, ctx),\n options\n )\n }\n })\n await Promise.all(workers)\n }\n\n for (const idx of pendingIndices) delete s.steps[`${stepId}:${idx}`]\n s.steps[stepId] = await this.maybeOffloadStepValue(s.docRef, stepId, results, s.isDev, items.length > 25)\n if (s.docRef) await this.#persistSteps(s)\n return results\n }\n\n #waitForSignalStep = async <T = unknown>(\n s: StepRunnerState,\n flushFn: () => Promise<unknown>,\n stepId: string,\n signalName: string,\n options?: { timeout?: Duration }\n ): Promise<T> => {\n this.#assertNotFenced(s)\n if (stepId in s.steps) return this.maybeHydrateStepValue<T>(s.steps[stepId], s.isDev)\n if (s.replayOnly) throw new ReplayCompleteSignal()\n if (signalName in s.signals) {\n const payload = s.signals[signalName] as T\n s.steps[stepId] = await this.maybeOffloadStepValue(s.docRef, stepId, payload, s.isDev)\n if (s.docRef) await this.#persistSteps(s)\n return payload\n }\n if (s.docRef) {\n const freshSnap = await s.docRef.get().catch(() => null)\n const freshSignals = (freshSnap?.data()?.signals as Record<string, unknown> | undefined) ?? {}\n if (signalName in freshSignals) {\n const payload = freshSignals[signalName] as T\n s.steps[stepId] = await this.maybeOffloadStepValue(s.docRef, stepId, payload, s.isDev)\n await this.#persistSteps(s)\n return payload\n }\n const timeoutKey = `__signal_deadline:${stepId}`\n const timeoutMs = options?.timeout ? this.#core.errors.parseDuration(options.timeout, 0) : 0\n const now = Date.now()\n const existingDeadline = typeof s.steps[timeoutKey] === 'number' ? (s.steps[timeoutKey] as number) : undefined\n if (existingDeadline && now >= existingDeadline) {\n throw this.#core.errors.nonRetryableError(`Timed out waiting for signal \"${signalName}\"`, 'SIGNAL_TIMEOUT')\n }\n if (!existingDeadline && timeoutMs > 0) {\n s.steps[timeoutKey] = now + timeoutMs\n await this.#persistSteps(s)\n }\n if (s.canYield) {\n await flushFn()\n throw new TaskYieldSignal('waiting_signal', {\n signalName,\n ...(timeoutMs > 0 ? { timeoutMs: existingDeadline ? Math.max(1000, existingDeadline - now) : timeoutMs } : {})\n })\n }\n }\n throw this.#core.errors.nonRetryableError(`Signal \"${signalName}\" not received`, 'SIGNAL_TIMEOUT')\n }\n\n #invokeChildStep = <I, O>(\n s: StepRunnerState,\n flush: () => Promise<PromiseSettledResult<unknown>[]>,\n step: StepFn,\n stepId: string,\n target: string | WorkflowTargetRef<I, any>,\n input: I,\n options: { timeout?: Duration; dedupeKey?: string } | undefined,\n wait: boolean\n ): Promise<O> =>\n this.#executeSingleStep(s, flush, stepId, async () => {\n if (wait && typeof target === 'object' && target.handler && !target.workflowName) {\n return target.handler({ input, step })\n }\n const workflowName = resolveTargetName(target)\n const timeout = options?.timeout ?? (typeof target === 'object' ? target.timeout : undefined)\n return this.#invokeChildWorkflow(workflowName, input, {\n ...(timeout !== undefined ? { timeout } : {}),\n ...(options?.dedupeKey ? { dedupeKey: options.dedupeKey } : {}),\n wait\n }) as Promise<O>\n })\n\n #sleepStep = async (\n s: StepRunnerState,\n flush: () => Promise<PromiseSettledResult<unknown>[]>,\n stepId: string,\n duration: Duration\n ): Promise<void> => {\n this.#assertNotFenced(s)\n if (s.steps[stepId] === true) return\n if (s.replayOnly) throw new ReplayCompleteSignal()\n const ms = Math.max(0, this.#core.errors.parseDuration(duration, 0))\n if (!s.canYield || ms <= 2_000) {\n if (ms > 0) await new Promise((r) => setTimeout(r, ms))\n s.steps[stepId] = true\n if (s.docRef) await this.#persistSteps(s)\n return\n }\n s.steps[stepId] = true\n await this.#persistSteps(s)\n await flush()\n throw new TaskYieldSignal('sleeping', { delaySeconds: Math.ceil(ms / 1000) })\n }\n\n #progressStep = async (s: StepRunnerState, update: TaskProgressUpdate): Promise<void> => {\n this.#assertNotFenced(s)\n if (!s.docRef || !s.expiresAt) return\n const ref = s.docRef\n const p = ref.firestore\n .runTransaction(async (tx) => {\n const data = (await tx.get(ref)).data()\n const docEpoch = typeof data?.epoch === 'number' ? data.epoch : undefined\n const docStatus = typeof data?.status === 'string' ? data.status : undefined\n if (isFencedOut(s.claimedEpoch, docEpoch, docStatus)) this.#triggerFenceAbort(s, docEpoch, docStatus)\n tx.set(ref, { progress: update, updatedAt: new Date().toISOString(), expiresAt: s.expiresAt }, { merge: true })\n })\n .catch((err) => {\n if (this.#core.errors.isStaleWorkerEpochError(err)) throw err\n })\n s.writes.push(p)\n await p\n }\n\n #flushSteps = async (s: StepRunnerState): Promise<PromiseSettledResult<unknown>[]> => {\n this.#assertNotFenced(s)\n if (s.docRef && s.claimedEpoch !== undefined && s.writes.length === 0) await this.#persistSteps(s)\n const settled = await Promise.allSettled(s.writes)\n for (const item of settled) {\n if (item.status === 'rejected' && this.#core.errors.isStaleWorkerEpochError(item.reason)) throw item.reason\n }\n this.#assertNotFenced(s)\n return settled\n }\n\n createStepRunner = (\n mode: RouteMode = 'workflow',\n docRef?: DocumentReference,\n steps: Record<string, unknown> = {},\n expiresAt?: Timestamp,\n runnerOpts?: CreateStepRunnerOptions\n ): StepRunner => {\n const s: StepRunnerState = {\n mode,\n docRef,\n steps,\n expiresAt,\n isDev: Boolean(runnerOpts?.isDev ?? this.#core.env.isDev),\n signals: runnerOpts?.signals ?? {},\n wfCtx: runnerOpts?.workflowContext,\n canYield: Boolean(runnerOpts?.canYield && docRef && expiresAt && mode === 'workflow'),\n compensatedSteps: runnerOpts?.compensatedSteps ?? {},\n replayOnly: Boolean(runnerOpts?.replayOnly),\n claimedEpoch: runnerOpts?.claimedEpoch,\n fencedError: null,\n activePersistPromise: null,\n pendingPersist: false,\n writes: [],\n rollbacks: [],\n callCounts: new Map<string, number>(),\n abortController: runnerOpts?.abortController\n }\n\n const nextStepKey = (baseName: string): string => {\n const count = (s.callCounts.get(baseName) ?? 0) + 1\n s.callCounts.set(baseName, count)\n return count === 1 ? baseName : `${baseName}#${count}`\n }\n\n const flush = (): Promise<PromiseSettledResult<unknown>[]> => this.#flushSteps(s)\n const step: StepFn = <T>(name: string, fnOrSpec: StepSpec<T>, options?: StepOptions<T>): Promise<T> =>\n this.#executeSingleStep(s, flush, nextStepKey(name), fnOrSpec, options)\n const compensate = (): Promise<void> =>\n s.docRef ? runSerializedCompensation(s.docRef.id, () => executeCompensateState(s)) : executeCompensateState(s)\n\n return Object.assign(step, {\n run: step,\n map: <T, R>(name: string, items: readonly T[], fn: (item: T, index: number, ctx: StepContext) => Promise<R>, options?: StepMapOptions<T, R>): Promise<R[]> =>\n this.#mapStep(s, flush, nextStepKey(name), items, fn, options),\n invoke: <I = unknown, O = unknown>(name: string, target: string | WorkflowTargetRef<I, O>, input: I, options?: { timeout?: Duration; dedupeKey?: string }): Promise<O> =>\n this.#invokeChildStep(s, flush, step, nextStepKey(name), target, input, options, true),\n spawn: <I = unknown>(name: string, target: string | WorkflowTargetRef<I, unknown>, input: I, options?: { dedupeKey?: string; timeout?: Duration }): Promise<{ taskId: string }> =>\n this.#invokeChildStep<I, { taskId: string }>(s, flush, step, nextStepKey(name), target, input, options, false),\n sleep: (name: string, duration: Duration) => this.#sleepStep(s, flush, nextStepKey(name), duration),\n waitForSignal: <T = unknown>(name: string, signalName: string, options?: { timeout?: Duration }): Promise<T> =>\n this.#waitForSignalStep(s, flush, nextStepKey(name), signalName, options),\n continueAsNew: async <I = unknown>(newInput: I): Promise<never> => {\n this.#assertNotFenced(s)\n await flush()\n throw new TaskYieldSignal('continue_as_new', { newInput })\n },\n progress: (update: TaskProgressUpdate) => this.#progressStep(s, update),\n flush,\n compensate,\n onError: compensate\n })\n }\n}\n", "import type { DocumentReference, DocumentSnapshot } from 'firebase-admin/firestore'\nimport { CORE_CONFIG } from '../config'\nimport type { Core } from '../index'\nimport { TaskWaitDetachedSignal, type TaskRecord, type WatchTaskOptions, type WorkflowTaskPayload } from './schema'\nimport type { TaskStepsEngine } from './steps'\nimport { getQueueBase, getQueueLoc, getQueueParent, getWorkerUri, isTerminalRecord } from './utils'\n\ntype BatchItem = {\n payload: WorkflowTaskPayload\n deadline: number\n scheduleDelaySeconds?: number\n resolve: () => void\n reject: (e: Error) => void\n}\n\ntype WatchCleanup = {\n unsubscribeSnapshot?: () => void\n pollTimer?: ReturnType<typeof setInterval>\n hedgeTimer?: ReturnType<typeof setTimeout>\n deadlineTimer?: ReturnType<typeof setTimeout>\n detachTimer?: ReturnType<typeof setTimeout>\n onAbort?: () => void\n}\n\nconst batchQueue: BatchItem[] = []\nlet flushScheduled = false\nlet nextShard = 0\nlet activeWatcherCount = 0\n\nexport class TaskWatcherEngine {\n readonly #core: Core\n readonly #steps: TaskStepsEngine\n\n constructor(coreClient: Core, steps: TaskStepsEngine) {\n this.#core = coreClient\n this.#steps = steps\n }\n\n getActiveWatcherCount = (): number => activeWatcherCount\n\n #sendBatch = async (queueParent: string, chunk: BatchItem[]): Promise<void> => {\n await this.#core.internals.resilience.acquireLimit('workflows', chunk.length)\n const accessToken = await this.#core.internals.registry.getGcpAccessToken()\n const isDev = Boolean(chunk[0]?.payload.isDev)\n const queueBase = getQueueBase(isDev)\n const shardsCount = Math.max(1, CORE_CONFIG.tasks.defaultShardsCount)\n const headers = {\n authorization: `Bearer ${accessToken}`,\n 'content-type': 'application/json',\n 'x-goog-user-project': CORE_CONFIG.gcpProject\n }\n const buildRequests = (parent: string) =>\n chunk.map((i) => {\n const workerUri = getWorkerUri(i.payload.isDev)\n return {\n parent,\n task: {\n dispatchDeadline: `${i.deadline}s`,\n ...(i.scheduleDelaySeconds && i.scheduleDelaySeconds > 0\n ? { scheduleTime: new Date(Date.now() + Math.round(i.scheduleDelaySeconds * 1000)).toISOString() }\n : {}),\n httpRequest: {\n url: workerUri,\n httpMethod: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: Buffer.from(JSON.stringify({ data: i.payload })).toString('base64'),\n oidcToken: { serviceAccountEmail: CORE_CONFIG.serviceAccount, audience: workerUri }\n }\n }\n }\n })\n\n let targetParent = queueParent\n let lastErr: Error | null = null\n for (let a = 0; a < 3; a++) {\n try {\n const res = await fetch(`https://cloudtasks.googleapis.com/v2/${targetParent}/tasks:batchCreate`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ requests: buildRequests(targetParent) })\n })\n if (res.status === 404 && targetParent !== queueBase) {\n const createRes = await fetch(`https://cloudtasks.googleapis.com/v2/${getQueueLoc()}/queues`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n name: targetParent,\n rateLimits: { maxDispatchesPerSecond: 500, maxConcurrentDispatches: 1000 }\n })\n }).catch(() => null)\n if (!createRes?.ok) targetParent = getQueueParent(nextShard++ % shardsCount, isDev)\n continue\n }\n if (!res.ok) throw new Error(`Cloud Tasks batchCreate (${res.status}): ${await res.text()}`)\n return chunk.forEach((i) => i.resolve())\n } catch (e) {\n lastErr = e instanceof Error ? e : new Error(String(e))\n if (a < 2) await new Promise((r) => setTimeout(r, 300 * (a + 1)))\n }\n }\n chunk.forEach((i) => i.reject(lastErr!))\n }\n\n enqueueBatched = (\n payload: WorkflowTaskPayload,\n deadline: number,\n scheduleDelaySeconds?: number\n ): Promise<void> =>\n new Promise<void>((resolve, reject) => {\n batchQueue.push({\n payload,\n deadline,\n ...(scheduleDelaySeconds && scheduleDelaySeconds > 0 ? { scheduleDelaySeconds } : {}),\n resolve,\n reject\n })\n if (!flushScheduled) {\n flushScheduled = true\n queueMicrotask(() => {\n flushScheduled = false\n const shardsCount = Math.max(1, CORE_CONFIG.tasks.defaultShardsCount)\n const batchSize = Math.max(1, CORE_CONFIG.tasks.batchCreateSize)\n const byShard = new Map<string, BatchItem[]>()\n for (const item of batchQueue.splice(0)) {\n const parent = getQueueParent(nextShard++ % shardsCount, item.payload.isDev)\n let list = byShard.get(parent)\n if (!list) {\n list = []\n byShard.set(parent, list)\n }\n list.push(item)\n }\n for (const [parent, items] of byShard) {\n while (items.length) void this.#sendBatch(parent, items.splice(0, batchSize))\n }\n })\n }\n })\n\n #delRefs = (refs: DocumentReference[], isDev: boolean): void => {\n if (!refs.length) return\n const batch = this.#core.db.firestore(isDev).batch()\n const bucket = this.#core.db.bucket(isDev)\n refs.forEach((r) => {\n batch.delete(r)\n void bucket.deleteFiles({ prefix: `_tasks/${r.id}/` }).catch(() => {})\n })\n void batch.commit().catch(() => {})\n }\n\n hydrateTerminalSnap = async <O = unknown>(\n snap: DocumentSnapshot,\n isDev: boolean\n ): Promise<TaskRecord<O> | null> => {\n const d = snap.exists ? (snap.data() as TaskRecord<O> | undefined) : undefined\n if (!isTerminalRecord(d)) return null\n if (d.status === 'completed') {\n return { status: 'completed', response: await this.#steps.maybeHydrateStepValue<O>(d.response, isDev) }\n }\n return d\n }\n\n #startHedgeTimer = <O>(opts: {\n docRef: DocumentReference\n isDev: boolean\n createdAt: number\n hedgeAfterMs: number\n dispatch: () => Promise<void>\n isDone: () => boolean\n finishResolve: (rec: TaskRecord<O>, isTerminalFromDb: boolean) => void\n }): ReturnType<typeof setTimeout> => {\n let hedged = false\n const timer = setTimeout(async () => {\n if (opts.isDone() || hedged) return\n try {\n const snap = await opts.docRef.get()\n if (opts.isDone()) return\n const record = await this.hydrateTerminalSnap<O>(snap, opts.isDev)\n if (record) {\n opts.finishResolve(record, true)\n return\n }\n const rawData = snap.data() as { lastHeartbeatAt?: number } | undefined\n const lastHb = typeof rawData?.lastHeartbeatAt === 'number' ? rawData.lastHeartbeatAt : opts.createdAt\n if (Date.now() - lastHb > CORE_CONFIG.tasks.heartbeatStaleMs) {\n hedged = true\n opts.dispatch().catch(() => {})\n }\n } catch {}\n }, opts.hedgeAfterMs)\n timer.unref?.()\n return timer\n }\n\n #awaitTaskSettlement = <O>(\n taskId: string,\n docRef: DocumentReference,\n isDev: boolean,\n workflowName: string,\n hedgeable: boolean,\n timeoutMs: number,\n hedgeAfterMs: number,\n pollIntervalMs: number,\n createdAt: number,\n watchOpts: WatchTaskOptions | undefined,\n cleanup: WatchCleanup\n ): Promise<{ record: TaskRecord<O>; settledTerminal: boolean }> =>\n new Promise((resolve, reject) => {\n let done = false\n let polling = false\n const finishResolve = (record: TaskRecord<O>, settledTerminal = false) => {\n if (done) return\n done = true\n resolve({ record, settledTerminal })\n }\n const finishReject = (err: unknown) => {\n if (done) return\n done = true\n reject(err)\n }\n\n if (watchOpts?.signal) {\n if (watchOpts.signal.aborted) return finishReject(watchOpts.signal.reason ?? new Error(`Task watch aborted: ${taskId}`))\n cleanup.onAbort = () => finishReject(watchOpts.signal!.reason ?? new Error(`Task watch aborted: ${taskId}`))\n watchOpts.signal.addEventListener('abort', cleanup.onAbort, { once: true })\n }\n\n const checkSnapshot = async (snap: DocumentSnapshot) => {\n if (done) return\n try {\n const record = await this.hydrateTerminalSnap<O>(snap, isDev)\n if (record) finishResolve(record, true)\n } catch (err) {\n finishReject(err)\n }\n }\n\n cleanup.unsubscribeSnapshot = docRef.onSnapshot((snap) => void checkSnapshot(snap), () => {})\n cleanup.pollTimer = setInterval(async () => {\n if (done || polling) return\n polling = true\n try {\n await checkSnapshot(await docRef.get())\n } catch {\n } finally {\n polling = false\n }\n }, pollIntervalMs)\n cleanup.pollTimer.unref?.()\n\n if (hedgeable && watchOpts?.dispatch) {\n cleanup.hedgeTimer = this.#startHedgeTimer({ docRef, isDev, createdAt, hedgeAfterMs, dispatch: watchOpts.dispatch, isDone: () => done, finishResolve })\n }\n cleanup.deadlineTimer = setTimeout(() => finishResolve({ status: 'errored', error: `Workflow task timed out: ${workflowName}/${taskId}` }, false), timeoutMs)\n cleanup.deadlineTimer.unref?.()\n if (watchOpts?.maxWaitMs !== undefined && watchOpts.maxWaitMs > 0) {\n cleanup.detachTimer = setTimeout(() => finishReject(new TaskWaitDetachedSignal(taskId)), watchOpts.maxWaitMs)\n cleanup.detachTimer.unref?.()\n }\n if (watchOpts?.dispatch) {\n watchOpts.dispatch().catch((err) => finishResolve({ status: 'errored', error: err instanceof Error ? err.message : String(err) }, false))\n }\n })\n\n watchTask = async <O = unknown>(taskId: string, opts?: WatchTaskOptions): Promise<TaskRecord<O>> => {\n const isDev = Boolean(opts?.isDev ?? this.#core.env.isDev)\n const docRef = opts?.docRef ?? this.#core.db.firestore(isDev).collection('_tasks').doc(taskId)\n const workflowName = opts?.workflowName ?? 'workflow'\n const hedgeable = Boolean(opts?.hedgeable ?? workflowName === 'scan-attachment')\n const keepAlive = opts?.keepAlive ?? true\n const timeoutMs = opts?.timeoutMs ?? CORE_CONFIG.tasks.timeoutMs\n const hedgeAfterMs = opts?.hedgeAfterMs ?? CORE_CONFIG.tasks.hedgeAfterMs\n const pollIntervalMs = opts?.pollIntervalMs ?? 5_000\n const createdAt = Date.now()\n\n activeWatcherCount += 1\n const cleanup: WatchCleanup = {}\n\n try {\n const { record, settledTerminal } = await this.#awaitTaskSettlement<O>(\n taskId,\n docRef,\n isDev,\n workflowName,\n hedgeable,\n timeoutMs,\n hedgeAfterMs,\n pollIntervalMs,\n createdAt,\n opts,\n cleanup\n )\n if (settledTerminal && !keepAlive) this.#delRefs([docRef], isDev)\n return record\n } finally {\n try {\n cleanup.unsubscribeSnapshot?.()\n } catch {}\n if (cleanup.pollTimer !== undefined) clearInterval(cleanup.pollTimer)\n if (cleanup.hedgeTimer !== undefined) clearTimeout(cleanup.hedgeTimer)\n if (cleanup.deadlineTimer !== undefined) clearTimeout(cleanup.deadlineTimer)\n if (cleanup.detachTimer !== undefined) clearTimeout(cleanup.detachTimer)\n if (cleanup.onAbort && opts?.signal) opts.signal.removeEventListener('abort', cleanup.onAbort)\n activeWatcherCount = Math.max(0, activeWatcherCount - 1)\n }\n }\n}\n", "import { AsyncLocalStorage } from 'node:async_hooks'\nimport { createHash } from 'node:crypto'\nimport { Timestamp, type DocumentReference, type Firestore } from 'firebase-admin/firestore'\nimport { CORE_CONFIG, type DbRole } from '../config'\nimport type { EntryId } from '../db'\nimport type { Core } from '../index'\nimport type { RouteMode } from '../router'\nimport type { Duration } from '../utils'\nimport {\n StaleWorkerEpochError,\n type ActiveTaskExecution,\n type ActiveWorkflowStore,\n type DispatchWorkflowOptions,\n type ExecuteWorkflowTaskOptions,\n type StepRunner,\n type TaskRecord,\n type TaskYieldSignal,\n type WorkflowContext,\n type WorkflowRuntimeEntry,\n type WorkflowTaskPayload\n} from './schema'\nimport type { TaskStepsEngine } from './steps'\nimport {\n claimTaskEpochTx,\n commitTaskCompensatingTx,\n commitTaskCompletionTx,\n commitTaskYieldTx,\n isTaskYieldSignal,\n resolveTaskDeadline,\n setTaskDoc,\n startTaskHeartbeatTimer\n} from './utils'\nimport type { TaskWatcherEngine } from './watcher'\n\nconst activeTaskExecutions = new Map<string, ActiveTaskExecution>()\nconst workflowStorage = new AsyncLocalStorage<ActiveWorkflowStore>()\nlet activeRegistry: Record<string, WorkflowRuntimeEntry> = {}\n\nexport class TaskWorkerEngine {\n readonly #core: Core\n #steps!: TaskStepsEngine\n #watcher!: TaskWatcherEngine\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n }\n\n bindEngines = (steps: TaskStepsEngine, watcher: TaskWatcherEngine): void => {\n this.#steps = steps\n this.#watcher = watcher\n }\n\n getActiveWorkflowStore = (): ActiveWorkflowStore | undefined => workflowStorage.getStore()\n\n getContext = (): WorkflowContext => {\n const store = workflowStorage.getStore()\n if (store) return store.workflow\n const now = Date.now()\n return {\n taskId: 'inline',\n workflowName: 'inline',\n attempt: 1,\n startedAt: now,\n deadlineMs: now + CORE_CONFIG.tasks.defaultDeadlineSeconds * 1000,\n signal: new AbortController().signal\n }\n }\n\n runWithWorkflowContext = <T>(store: ActiveWorkflowStore, fn: () => Promise<T>): Promise<T> =>\n workflowStorage.run(store, fn)\n\n registerActiveTaskExecution = (exec: ActiveTaskExecution): void => {\n activeTaskExecutions.set(exec.taskId, exec)\n }\n\n unregisterActiveTaskExecution = (taskId: string, step?: StepRunner): void => {\n const existing = activeTaskExecutions.get(taskId)\n if (existing && (!step || existing.step === step)) activeTaskExecutions.delete(taskId)\n }\n\n getActiveTaskExecution = (taskId: string): ActiveTaskExecution | undefined => activeTaskExecutions.get(taskId)\n\n registerRuntime = (registry: Record<string, WorkflowRuntimeEntry>): void => {\n activeRegistry = registry\n }\n\n getRuntime = (): { registry: Record<string, WorkflowRuntimeEntry> } => ({ registry: activeRegistry })\n\n invokeChildWorkflow = async (\n targetName: string,\n input: unknown,\n options?: { timeout?: Duration; dedupeKey?: string; wait?: boolean }\n ): Promise<any> => {\n const wf = activeRegistry[targetName]\n if (!wf) throw new Error(`Unknown child workflow: ${targetName}`)\n const timeout: Duration | undefined =\n options?.timeout ?? (wf.deadlineSeconds !== undefined ? `${wf.deadlineSeconds}s` : undefined)\n return this.dispatch(targetName, wf.runTask as any, input, {\n mode: wf.mode,\n ...(timeout !== undefined ? { timeout } : {}),\n ...(options?.dedupeKey ? { dedupeKey: options.dedupeKey } : {}),\n wait: options?.wait !== false,\n userId: this.#core.userId,\n userRole: this.#core.role\n })\n }\n\n #unwrapTaskRecord = <O>(res: TaskRecord<O>): O => {\n if (res.status === 'completed') return res.response\n if (res.status === 'cancelled') {\n return this.#core.errors.httpError(409, res.error ?? 'Workflow task cancelled', 'TASK_CANCELLED')\n }\n if (res.nonRetryable) {\n return this.#core.errors.httpError(400, res.error, res.errorCode ?? 'NON_RETRYABLE_ERROR')\n }\n return this.#core.errors.httpError(502, res.error, 'WORKFLOW_ERROR')\n }\n\n #dispatchInline = async <I, O>(\n workflowName: string,\n mode: RouteMode,\n deadline: number,\n userId: EntryId,\n userRole: DbRole,\n fn: (input: I, step: StepRunner) => Promise<O>,\n params: I\n ): Promise<O> => {\n const env = this.#core.env\n const now = Date.now()\n const wfCtx: WorkflowContext = {\n taskId: 'inline',\n workflowName,\n attempt: 1,\n startedAt: now,\n deadlineMs: now + deadline * 1000,\n signal: new AbortController().signal\n }\n const step = this.#steps.createStepRunner(mode, undefined, {}, undefined, {\n isDev: env.isDev,\n workflowContext: wfCtx,\n canYield: false\n })\n try {\n return await this.runWithWorkflowContext({ workflow: wfCtx, step, env }, () =>\n this.#core.internals.context.run({ env, userId, role: userRole, step }, () => fn(params, step))\n )\n } catch (err) {\n await step.compensate()\n if (err instanceof this.#core.errors.NonRetryableError) {\n return this.#core.errors.httpError(400, err.message, err.code ?? 'NON_RETRYABLE_ERROR')\n }\n const msg = err instanceof Error ? err.message : String(err)\n return this.#core.errors.httpError(502, msg, 'WORKFLOW_ERROR')\n }\n }\n\n #initOrReuseTaskDoc = async <O>(\n db: Firestore,\n docRef: DocumentReference,\n deterministicId: string | undefined,\n workflowName: string,\n params: unknown,\n userId: EntryId,\n userRole: DbRole\n ): Promise<{ settled: true; response: O } | { settled: false; shouldDispatch: boolean }> => {\n const nowMs = Date.now()\n const nowIso = new Date(nowMs).toISOString()\n const initialTaskDoc = {\n taskId: docRef.id,\n workflowName,\n status: 'running',\n epoch: 0,\n activeRunId: null,\n compensatedSteps: {},\n params: (params ?? {}) as Record<string, unknown>,\n steps: {},\n userId,\n userRole,\n keepAlive: true,\n lastHeartbeatAt: nowMs,\n createdAt: nowIso,\n updatedAt: nowIso,\n expiresAt: Timestamp.fromMillis(nowMs + CORE_CONFIG.tasks.ttlMs)\n }\n\n if (!deterministicId) {\n await docRef.set(initialTaskDoc)\n return { settled: false, shouldDispatch: true }\n }\n\n let shouldDispatch = true\n const existingOutcome = await db.runTransaction(async (tx) => {\n const data = (await tx.get(docRef)).data()\n if (data?.status === 'completed') return { settled: true as const, response: data.response as O }\n if (['running', 'sleeping', 'waiting_signal', 'compensating'].includes(String(data?.status))) {\n shouldDispatch = false\n return { settled: false as const }\n }\n tx.set(docRef, initialTaskDoc)\n return { settled: false as const }\n })\n return existingOutcome.settled ? existingOutcome : { settled: false, shouldDispatch }\n }\n\n dispatch = async <I, O>(\n workflowName: string,\n fn: (input: I, step: StepRunner) => Promise<O>,\n params: I,\n opts?: DispatchWorkflowOptions\n ): Promise<O> => {\n const env = this.#core.env\n const mode = opts?.mode ?? 'workflow'\n const explicitDeadline = opts?.timeout\n ? Math.max(\n 15,\n Math.ceil(this.#core.errors.parseDuration(opts.timeout, CORE_CONFIG.tasks.defaultDeadlineSeconds * 1000) / 1000)\n )\n : undefined\n const deadline = resolveTaskDeadline(workflowName, explicitDeadline)\n const useQueue = mode !== 'rest' && CORE_CONFIG.tasks.useCloudTasks\n const userId = opts?.userId ?? this.#core.userId ?? CORE_CONFIG.auth.adminUserId\n const userRole = this.#core.internals.auth.resolveUserRole(userId, opts?.userRole ?? this.#core.role)\n\n const db = this.#core.db.firestore(env.isDev)\n const deterministicId = opts?.dedupeKey\n ? `dedupe_${createHash('sha256').update(`${workflowName}:${opts.dedupeKey}`).digest('hex').slice(0, 24)}`\n : undefined\n\n if (!useQueue && opts?.wait !== false && !deterministicId && opts?.maxWaitMs === undefined) {\n return this.#dispatchInline(workflowName, mode, deadline, userId, userRole, fn, params)\n }\n\n const docRef = deterministicId ? db.collection('_tasks').doc(deterministicId) : db.collection('_tasks').doc()\n const taskId = docRef.id\n const keepAlive = Boolean(deterministicId || opts?.wait === false || opts?.maxWaitMs !== undefined)\n const initRes = await this.#initOrReuseTaskDoc<O>(db, docRef, deterministicId, workflowName, params, userId, userRole)\n if (initRes.settled) {\n return opts?.wait === false\n ? ({ taskId } as unknown as O)\n : await this.#steps.maybeHydrateStepValue<O>(initRes.response, Boolean(env.isDev))\n }\n\n const payload: WorkflowTaskPayload = {\n taskId,\n workflowName,\n params: (params ?? {}) as Record<string, unknown>,\n isDev: Boolean(env.isDev),\n expectedEpoch: 0\n }\n const dispatchFn = () =>\n useQueue\n ? this.#watcher.enqueueBatched(payload, deadline)\n : this.execute(payload, {\n ...activeRegistry,\n [workflowName]: { mode, deadlineSeconds: deadline, runTask: fn as any }\n })\n\n if (opts?.wait === false) {\n if (initRes.shouldDispatch) void dispatchFn().catch(() => {})\n return { taskId } as unknown as O\n }\n\n const record = await this.#watcher.watchTask<O>(taskId, {\n isDev: Boolean(env.isDev),\n docRef,\n workflowName,\n hedgeable: workflowName === 'scan-attachment',\n keepAlive,\n timeoutMs: CORE_CONFIG.tasks.timeoutMs,\n ...(opts?.maxWaitMs !== undefined ? { maxWaitMs: opts.maxWaitMs } : {}),\n ...(opts?.signal ? { signal: opts.signal } : {}),\n ...(initRes.shouldDispatch ? { dispatch: dispatchFn } : {})\n })\n return this.#unwrapTaskRecord(record)\n }\n\n #commitCompletion = async (opts: {\n db: Firestore\n docRef: DocumentReference\n baseMeta: Record<string, unknown>\n taskId: string\n claimedEpoch: number\n response: unknown\n steps: Record<string, unknown>\n expiresAt: Timestamp\n isDev: boolean\n }): Promise<void> => {\n const stored = await this.#steps.maybeOffloadStepValue(opts.docRef, '__response', opts.response, opts.isDev)\n await commitTaskCompletionTx(opts.db, opts.docRef, opts.baseMeta, opts.taskId, opts.claimedEpoch, stored, opts.steps, opts.expiresAt)\n }\n\n #commitYieldAndEnqueue = async (opts: {\n db: Firestore\n docRef: DocumentReference\n baseMeta: Record<string, unknown>\n taskId: string\n workflowName: string\n claimedEpoch: number\n err: TaskYieldSignal\n effectiveParams: Record<string, unknown>\n steps: Record<string, unknown>\n expiresAt: Timestamp\n isDev: boolean\n useQueue: boolean\n deadlineSeconds: number\n }): Promise<void> => {\n const nextEpoch = opts.claimedEpoch + 1\n const nextParams =\n opts.err.reason === 'continue_as_new'\n ? ((opts.err.meta.newInput ?? {}) as Record<string, unknown>)\n : opts.effectiveParams\n const nextSteps = opts.err.reason === 'continue_as_new' ? {} : opts.steps\n const nextStatus =\n opts.err.reason === 'sleeping' ? 'sleeping' : opts.err.reason === 'waiting_signal' ? 'waiting_signal' : 'running'\n await commitTaskYieldTx(opts.db, opts.docRef, opts.baseMeta, opts.taskId, opts.claimedEpoch, opts.err, nextEpoch, nextParams, nextSteps, nextStatus, opts.expiresAt)\n if (!opts.useQueue) return\n const nextPayload: WorkflowTaskPayload = {\n taskId: opts.taskId,\n workflowName: opts.workflowName,\n params: nextParams,\n isDev: opts.isDev,\n expectedEpoch: nextEpoch\n }\n if (opts.err.reason === 'continue_as_new' || opts.err.reason === 'yield') {\n await this.#watcher.enqueueBatched(nextPayload, opts.deadlineSeconds)\n } else if (opts.err.reason === 'sleeping') {\n await this.#watcher.enqueueBatched(nextPayload, opts.deadlineSeconds, opts.err.meta.delaySeconds ?? 1)\n } else if (opts.err.reason === 'waiting_signal' && opts.err.meta.timeoutMs && opts.err.meta.timeoutMs > 0) {\n await this.#watcher.enqueueBatched(nextPayload, opts.deadlineSeconds, Math.ceil(opts.err.meta.timeoutMs / 1000))\n }\n }\n\n #commitErrorAndCompensate = async (opts: {\n db: Firestore\n docRef: DocumentReference\n baseMeta: Record<string, unknown>\n taskId: string\n claimedEpoch: number\n err: unknown\n step: StepRunner\n steps: Record<string, unknown>\n expiresAt: Timestamp\n }): Promise<void> => {\n const error = opts.err instanceof Error ? opts.err.message : String(opts.err)\n const nonRetryable = opts.err instanceof this.#core.errors.NonRetryableError\n const errorCode =\n opts.err instanceof this.#core.errors.NonRetryableError ? (opts.err.code ?? 'NON_RETRYABLE_ERROR') : undefined\n\n await commitTaskCompensatingTx(opts.db, opts.docRef, opts.taskId, opts.claimedEpoch, opts.expiresAt)\n await opts.step.compensate()\n await setTaskDoc(opts.docRef, {\n ...opts.baseMeta,\n status: 'errored',\n activeRunId: null,\n error,\n ...(nonRetryable ? { nonRetryable: true, errorCode } : {}),\n steps: opts.steps,\n updatedAt: new Date().toISOString(),\n expiresAt: opts.expiresAt\n })\n }\n\n #runSingleAttempt = async (\n db: Firestore,\n docRef: DocumentReference,\n payload: WorkflowTaskPayload,\n wf: WorkflowRuntimeEntry,\n attempt: number,\n deadlineSeconds: number,\n useQueue: boolean,\n canYield: boolean\n ): Promise<boolean> => {\n const { taskId, workflowName, isDev: rawIsDev } = payload\n const isDev = Boolean(rawIsDev)\n const claim = await claimTaskEpochTx(db, docRef, payload, attempt, this.#core.internals.auth.resolveUserRole)\n if (claim.aborted) return true\n\n const { claimedEpoch, startedAt, expiresAt, effectiveParams, userId, userRole, steps, signals, compensatedSteps } =\n claim\n const baseMeta = { taskId, workflowName, userId, userRole }\n const env = { ...this.#core.env, isDev }\n const controller = new AbortController()\n const wfCtx: WorkflowContext = {\n taskId,\n workflowName,\n attempt: attempt + 1,\n startedAt,\n deadlineMs: startedAt + deadlineSeconds * 1000,\n signal: controller.signal\n }\n const step = this.#steps.createStepRunner(wf.mode, docRef, steps, expiresAt, {\n isDev,\n signals,\n workflowContext: wfCtx,\n canYield,\n claimedEpoch,\n abortController: controller,\n compensatedSteps\n })\n\n this.registerActiveTaskExecution({ taskId, step, controller, claimedEpoch })\n const hbTimer = startTaskHeartbeatTimer(db, docRef, taskId, claimedEpoch, expiresAt, controller)\n\n try {\n const response = await this.runWithWorkflowContext({ workflow: wfCtx, step, env }, () =>\n this.#core.internals.context.run({ env, userId, role: userRole, step }, () => wf.runTask(effectiveParams, step))\n )\n await step.flush()\n await this.#commitCompletion({ db, docRef, baseMeta, taskId, claimedEpoch, response, steps, expiresAt, isDev })\n return true\n } catch (err) {\n if (this.#core.errors.isStaleWorkerEpochError(err)) throw err\n if (isTaskYieldSignal(err)) {\n await step.flush()\n await this.#commitYieldAndEnqueue({ db, docRef, baseMeta, taskId, workflowName, claimedEpoch, err, effectiveParams, steps, expiresAt, isDev, useQueue, deadlineSeconds })\n return true\n }\n if (this.#core.errors.isNonRetryableError(err) || attempt >= CORE_CONFIG.tasks.maxAttempts - 1) {\n await this.#commitErrorAndCompensate({ db, docRef, baseMeta, taskId, claimedEpoch, err, step, steps, expiresAt })\n return true\n }\n await step.flush()\n await new Promise((r) => setTimeout(r, 1500 * (attempt + 1)))\n return false\n } finally {\n clearInterval(hbTimer)\n this.unregisterActiveTaskExecution(taskId, step)\n }\n }\n\n execute = async (\n payload: WorkflowTaskPayload,\n workflowRegistry: Record<string, WorkflowRuntimeEntry> = activeRegistry,\n execOpts?: ExecuteWorkflowTaskOptions\n ): Promise<void> => {\n const { taskId, workflowName, isDev } = payload\n const db = this.#core.db.firestore(Boolean(isDev))\n const docRef = db.collection('_tasks').doc(taskId)\n const wf = workflowRegistry[workflowName]\n\n if (!wf) {\n await setTaskDoc(docRef, {\n taskId,\n workflowName,\n status: 'errored',\n error: `Unknown workflow: ${workflowName}`,\n expiresAt: Timestamp.fromMillis(Date.now() + CORE_CONFIG.tasks.ttlMs)\n })\n return\n }\n\n const deadlineSeconds = resolveTaskDeadline(workflowName, wf.deadlineSeconds)\n const useQueue = CORE_CONFIG.tasks.useCloudTasks\n const canYield = execOpts?.canYield ?? useQueue\n\n for (let attempt = 0; attempt < CORE_CONFIG.tasks.maxAttempts; attempt++) {\n const done = await this.#runSingleAttempt(db, docRef, payload, wf, attempt, deadlineSeconds, useQueue, canYield)\n if (done) return\n }\n }\n}\n", "import type { Context } from 'hono'\nimport type { z } from 'zod'\nimport { CORE_CONFIG, type AppEnv } from '../config'\nimport { collectionRegistry, getEffectiveRbac } from '../db'\nimport { core } from '../index'\nimport { CORE_ROUTE_DEFAULTS, type BaseRouteConfig } from '../router'\nimport {\n signalTaskBody,\n type RouteIntrospectionItem,\n type RouteRegistryItem,\n type RoutesIntrospectionResponse\n} from './schema'\nimport { zodToJsonSchemaSafe } from './utils'\n\nexport {\n signalTaskBody,\n zodToJsonSchemaSafe,\n type RouteIntrospectionItem,\n type RouteRegistryItem,\n type RoutesIntrospectionResponse\n}\n\nconst summarizeGuards = (g?: BaseRouteConfig['guard']): string[] => {\n if (!g) return []\n const guards: string[] = []\n if (g.checkFileRef) guards.push('checkFileRef')\n if (g.checkUserId) guards.push('checkUserId')\n if (g.checkCollectionField) {\n guards.push(`checkCollectionField:${g.checkCollectionField.collection}.${g.checkCollectionField.param}`)\n }\n if (g.requireEmailVerified) guards.push('requireEmailVerified')\n if (g.custom) guards.push('custom')\n return guards\n}\n\nexport const buildRoutesIntrospection = (\n routeItems: RouteRegistryItem[],\n scope: 'all' | 'custom' | 'core' = 'all'\n): RoutesIntrospectionResponse => {\n const filtered = routeItems.filter((r) => {\n const isCore = r.id in CORE_ROUTE_DEFAULTS\n if (scope === 'core') return isCore\n if (scope === 'custom') return !isCore\n return true\n })\n\n const routes: RouteIntrospectionItem[] = filtered.map((r) => ({\n id: r.id,\n method: r.method,\n path: `/api${r.path}`,\n mode: r.mode,\n ...(r.workflowName ? { workflowName: r.workflowName } : {}),\n auth: r.auth ?? 'user',\n description: r.description,\n mcp: Boolean(r.mcp),\n tool: r.tool !== false,\n guards: summarizeGuards(r.guard),\n inputSchema: zodToJsonSchemaSafe(r.input),\n outputSchema: zodToJsonSchemaSafe(r.output)\n }))\n\n const collections: NonNullable<RoutesIntrospectionResponse['collections']> = {}\n for (const [name, def] of collectionRegistry) {\n collections[name] = {\n relationType: def.userRelation?.type ?? '1:N',\n rbac: getEffectiveRbac(name) as Record<string, unknown>,\n schema: zodToJsonSchemaSafe(def.schema)\n }\n }\n\n return {\n appName: CORE_CONFIG.appName,\n generatedAt: new Date().toISOString(),\n routes,\n collections\n }\n}\n\nexport const renderApiContractMarkdown = (meta: RoutesIntrospectionResponse): string => {\n const coreRoutes = meta.routes.filter((r) => r.id in CORE_ROUTE_DEFAULTS)\n const domainRoutes = meta.routes.filter((r) => !(r.id in CORE_ROUTE_DEFAULTS))\n\n const renderRouteBlock = (r: RouteIntrospectionItem) => {\n const lines: string[] = [\n `### ${r.method} ${r.path}`,\n `- **ID:** \\`${r.id}\\`${r.workflowName ? ` (Workflow: \\`${r.workflowName}\\`)` : ''}`,\n `- **Mode:** \\`${r.mode}\\` | **Auth:** \\`${String(r.auth)}\\` | **Guards:** \\`${r.guards.join(', ') || 'none'}\\` | **MCP:** \\`${r.mcp}\\` | **Tool:** \\`${r.tool}\\``,\n `- **Description:** ${r.description}`\n ]\n if (r.inputSchema) {\n lines.push('', '**Input JSON Schema:**', '```json', JSON.stringify(r.inputSchema, null, 2), '```')\n }\n if (r.outputSchema) {\n lines.push('', '**Output JSON Schema:**', '```json', JSON.stringify(r.outputSchema, null, 2), '```')\n }\n return lines.join('\\n')\n }\n\n const collectionLines: string[] = []\n for (const [name, col] of Object.entries(meta.collections ?? {})) {\n collectionLines.push(\n `### Collection: \\`${name}\\``,\n `- **User Relation:** \\`${col.relationType}\\``,\n `- **RBAC Matrix:** \\`${JSON.stringify(col.rbac ?? {})}\\``,\n ...(col.schema ? ['', '```json', JSON.stringify(col.schema, null, 2), '```'] : [])\n )\n }\n\n return [\n `# API Contract & Schema Reference \u2014 ${meta.appName}`,\n '',\n `> **Generated At:** \\`${meta.generatedAt}\\``,\n '> **Agent Instruction:** This document is deterministically generated from runtime Zod schemas and route definitions. Treat it as the single source of truth for all HTTP endpoints, payloads, authentication levels, and Firestore collection models.',\n '',\n '## 1. Core Protocol & Architecture Conventions',\n '',\n '### 1.1. Authentication & Sessions (`auth`)',\n '- **`public` / `none` / `false`**: No authentication required.',\n '- **`user`**: Requires `Authorization: Bearer <idToken | SDK_API_KEY>` or HTTP-only `session` cookie.',\n '- **`strict`**: Requires revocation-checked session verification (`verifySessionCookie(..., true)` / `_system/auth_revocations`).',\n '- **`admin`**: Requires admin role (`SDK_API_KEY` or admin user claim).',\n '- **Social OAuth & Account Recovery**: Use `POST /api/auth/sign-in/social` (`google` | `apple`), `POST /api/auth/email/send-verification`, `POST /api/auth/email/verify`, `POST /api/auth/password/forgot`, `POST /api/auth/password/reset`, `POST /api/auth/recovery-email/set`, `POST /api/auth/recovery-email/verify`, `POST /api/auth/account-recovery/initiate`, and `POST /api/auth/account-recovery/complete`.',\n '',\n '### 1.2. Content-Addressed Files (`FileRef`)',\n '- All uploaded files use content-addressed IDs formatted as `<userId>_<sha256_24>` matching `/^[A-Za-z0-9_-]{1,128}_[a-f0-9]{24}$/`.',\n '- Upload files via `POST /api/files` (`multipart/form-data` field `file`) before passing `ref` or `refs` to downstream endpoints.',\n '',\n '### 1.3. Execution Modes (`mode: \"rest\"` vs `mode: \"workflow\"`)',\n '- **`mode: \"rest\"`**: Synchronous `200 OK` JSON response.',\n '- **`mode: \"workflow\"`**: Durable Cloud Tasks workflow. May return `200 OK` directly (if resolved via `shortCircuit` cache or within wait budget) **OR** `202 Accepted` (`{ taskId, status: \"running\", pollUrl: \"/api/tasks/<taskId>\" }`) when `Prefer: respond-async` / `?wait=false` is passed.',\n '- Poll task progress via `GET /api/tasks/:taskId`, send signals via `POST /api/tasks/:taskId/signal`, or cancel via `DELETE /api/tasks/:taskId`.',\n '',\n '### 1.4. Thin-Client AI Chat Streaming (`POST /api/chats/:chatId`)',\n '- Send `{ message: { id?, role: \"user\", content, parts?, attachments? }, agentId?, model? }` to stream SSE responses and cancel active streams via `POST /api/chats/:chatId/cancel`.',\n '',\n '## 2. Core Endpoints Catalog',\n '',\n ...coreRoutes.map(renderRouteBlock),\n '',\n '## 3. Domain Endpoints Catalog',\n '',\n ...(domainRoutes.length > 0 ? domainRoutes.map(renderRouteBlock) : ['_No custom domain routes registered._']),\n '',\n '## 4. Registered Firestore Collections Catalog',\n '',\n ...collectionLines\n ].join('\\n')\n}\n\nexport const buildHealthRoute = () => ({\n mode: 'rest' as const,\n handler: async () => ({\n ok: true,\n status: 'healthy' as const,\n service: CORE_CONFIG.appName,\n env: core.env.isDev ? ('dev' as const) : ('prod' as const),\n timestamp: new Date().toISOString()\n })\n})\n\nexport const buildRoutesListRoute = (routeItems: () => RouteRegistryItem[]) => ({\n mode: 'rest' as const,\n handler: async ({ c }: { c: Context<AppEnv> }) => {\n const rawScope = c?.req.query('scope')\n const scope: 'all' | 'custom' | 'core' =\n rawScope === 'custom' || rawScope === 'core' ? rawScope : 'all'\n const format = c?.req.query('format')\n const accept = c?.req.header('accept') ?? ''\n const meta = buildRoutesIntrospection(routeItems(), scope)\n\n if (format === 'md' || accept.includes('text/markdown')) {\n return new Response(renderApiContractMarkdown(meta), {\n status: 200,\n headers: { 'content-type': 'text/markdown; charset=utf-8' }\n })\n }\n return meta\n }\n})\n\nexport const buildTaskStatusRoute = () => ({\n mode: 'rest' as const,\n handler: async ({ c }: { c: Context<AppEnv> }) => {\n const taskId = c.req.param('taskId') ?? ''\n const status = await core.tasks.status(taskId)\n if (\n status.status === 'running' ||\n status.status === 'sleeping' ||\n status.status === 'waiting_signal' ||\n status.status === 'compensating'\n ) {\n return c.json(\n {\n taskId,\n status: status.status,\n ...(status.progress ? { progress: status.progress } : {}),\n pollUrl: `/api/tasks/${taskId}`\n },\n 202\n )\n }\n if (status.status === 'errored') {\n return core.errors.httpError(502, status.error ?? 'Workflow task failed', 'WORKFLOW_ERROR')\n }\n if (status.status === 'cancelled') {\n return core.errors.httpError(409, status.error ?? 'Workflow task cancelled', 'TASK_CANCELLED')\n }\n if (c.req.query('envelope') === 'true') {\n return status\n }\n return status.response\n }\n})\n\nexport const buildTaskSignalRoute = () => ({\n mode: 'rest' as const,\n input: signalTaskBody,\n handler: async ({ c, input }: { c: Context<AppEnv>; input: z.infer<typeof signalTaskBody> }) => {\n const taskId = c.req.param('taskId') ?? ''\n return core.tasks.signal(taskId, input.signal, input.payload)\n }\n})\n\nexport const buildTaskCancelRoute = () => ({\n mode: 'rest' as const,\n handler: async ({ c }: { c: Context<AppEnv> }) => {\n const taskId = c.req.param('taskId') ?? ''\n return core.tasks.cancel(taskId)\n }\n})\n", "import { createHash, timingSafeEqual } from 'node:crypto'\nimport { Timestamp } from 'firebase-admin/firestore'\nimport type { Context } from 'hono'\nimport { getCookie } from 'hono/cookie'\nimport { CORE_CONFIG, type AppEnv, type DbRole, type RateLimitConfig } from '../config'\nimport type { EntryId } from '../db'\nimport type { Core } from '../index'\nimport {\n CORE_ROUTE_DEFAULTS,\n type AuthLevel,\n type BaseRouteConfig,\n type CoreRouteId,\n type CoreRouteOverrides,\n type RouteConfig\n} from './schema'\n\nconst HTTP_IDEMPOTENCY_TTL_MS = 24 * 60 * 60 * 1000\n\nexport const getClientIp = (c: Context<AppEnv>): string => {\n const xff = c.req\n .header('x-forwarded-for')\n ?.split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n if (xff && xff.length > 0) {\n return (xff.length >= 2 ? xff.at(-2) : xff.at(-1))!\n }\n return c.req.header('cf-connecting-ip') || c.req.header('x-real-ip') || 'anon'\n}\n\nexport const isMasterKey = (bearer?: string, expected?: string): boolean => {\n if (!bearer || !expected) return false\n const a = createHash('sha256').update(bearer).digest()\n const b = createHash('sha256').update(expected).digest()\n return timingSafeEqual(a, b)\n}\n\nexport const isBaseRouteConfig = (v: unknown): v is BaseRouteConfig =>\n Boolean(v && typeof v === 'object' && ('path' in v || 'mode' in v || 'auth' in v || 'handler' in v))\n\nexport const isRespondAsyncPreferred = (c: Context<AppEnv>): boolean =>\n c.req.query('async') === 'true' ||\n c.req.query('wait') === 'false' ||\n /\\brespond-async\\b/i.test(c.req.header('prefer') ?? '')\n\nexport class RouterGuardEngine {\n readonly #core: Core\n\n constructor(coreClient: Core) {\n this.#core = coreClient\n }\n\n applyRateLimit = (\n c: Context<AppEnv>,\n cfgOrLimit: BaseRouteConfig | RateLimitConfig,\n userIdOrScope?: EntryId\n ): void => {\n const rl: RateLimitConfig = isBaseRouteConfig(cfgOrLimit)\n ? cfgOrLimit.rateLimit !== undefined\n ? cfgOrLimit.rateLimit\n : cfgOrLimit.auth === 'public' || cfgOrLimit.auth === 'none' || cfgOrLimit.auth === false\n ? CORE_CONFIG.limits.httpIp\n : CORE_CONFIG.limits.httpUser\n : cfgOrLimit\n if (!rl) return\n const userId = c.get('userId') || userIdOrScope\n const routePrefix = isBaseRouteConfig(cfgOrLimit) && cfgOrLimit.path ? `${cfgOrLimit.method ?? c.req.method}:${cfgOrLimit.path}:` : ''\n const key =\n typeof rl.keyBy === 'function'\n ? rl.keyBy(c)\n : rl.keyBy === 'ip' || !userId\n ? `${routePrefix}ip:${getClientIp(c)}`\n : `${routePrefix}user:${userId}`\n this.#core.internals.resilience.acquireHttpLimit(key, rl.max, rl.windowMs)\n }\n\n authenticateRequest = async (\n c: Context<AppEnv>,\n cfgOrAuth: BaseRouteConfig | AuthLevel = 'user'\n ): Promise<EntryId> => {\n const rawAuth: AuthLevel = isBaseRouteConfig(cfgOrAuth) ? (cfgOrAuth.auth ?? 'user') : cfgOrAuth\n const authLevel =\n rawAuth === 'none' || rawAuth === false\n ? 'public'\n : rawAuth === 'authenticated'\n ? 'user'\n : rawAuth === 'api-key'\n ? 'admin'\n : rawAuth\n\n if (authLevel === 'public') {\n c.set('userId', '')\n c.set('userRole', 'anon')\n if (isBaseRouteConfig(cfgOrAuth)) this.applyRateLimit(c, cfgOrAuth)\n return ''\n }\n\n const t0 = performance.now()\n const finishAuth = (uid: EntryId, role: DbRole): EntryId => {\n if (authLevel === 'admin' && role !== 'admin' && uid !== CORE_CONFIG.auth.adminUserId) {\n return this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n c.set('userId', uid)\n c.set('userRole', role)\n if (isBaseRouteConfig(cfgOrAuth)) this.applyRateLimit(c, cfgOrAuth, uid)\n const dur = (performance.now() - t0).toFixed(3)\n c.header('x-auth-time-ms', dur)\n c.header('Server-Timing', `auth;dur=${dur}`)\n return uid\n }\n\n const bearer = c.req.header('authorization')?.match(/^Bearer\\s+(.+)$/i)?.[1]?.trim()\n const cookie = !bearer ? getCookie(c, CORE_CONFIG.auth.sessionCookie) : undefined\n if (!bearer && !cookie) return this.#core.errors.httpError(401, 'Unauthorized', 'UNAUTHORIZED')\n const expectedKey = c.env?.SDK_API_KEY ?? this.#core.env.SDK_API_KEY\n if (isMasterKey(bearer, expectedKey)) {\n await this.#core.internals.auth.authWarm\n return finishAuth(CORE_CONFIG.auth.adminUserId, 'admin')\n }\n if (rawAuth === 'api-key') {\n return this.#core.errors.httpError(401, 'Valid API key required', 'UNAUTHORIZED')\n }\n\n let verified: { uid: EntryId; role: DbRole }\n try {\n verified = await this.#core.internals.auth.verifyToken(\n (bearer ?? cookie)!,\n !bearer,\n authLevel === 'strict',\n c.env?.isDev ?? this.#core.env.isDev\n )\n } catch {\n return this.#core.errors.httpError(401, 'Unauthorized', 'UNAUTHORIZED')\n }\n return finishAuth(verified.uid, verified.role)\n }\n\n #enforceFileRefCheck = (\n checkFileRef: NonNullable<BaseRouteConfig['guard']>['checkFileRef'],\n c: Context<AppEnv> | undefined,\n userId: EntryId,\n input: unknown,\n obj: Record<string, unknown>,\n role: DbRole\n ): void => {\n if (!checkFileRef) return\n let refs: string[] = []\n if (typeof checkFileRef === 'function') {\n const extracted = checkFileRef(input, c)\n if (typeof extracted === 'string') refs = [extracted]\n else if (Array.isArray(extracted)) refs = extracted\n } else {\n const paramRef = c?.req.param('ref')\n refs = [\n ...(paramRef ? [paramRef] : []),\n ...(typeof obj.ref === 'string' ? [obj.ref] : []),\n ...(Array.isArray(obj.refs)\n ? obj.refs.map((r) =>\n typeof r === 'string'\n ? r\n : r && typeof r === 'object' && 'ref' in r && typeof (r as { ref: unknown }).ref === 'string'\n ? (r as { ref: string }).ref\n : ''\n )\n : [])\n ]\n }\n if (refs.some((r) => !this.#core.files.canAccess(r, userId, role))) {\n this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n }\n\n enforceGuard = async (\n c: Context<AppEnv> | undefined,\n cfg: BaseRouteConfig,\n userId: EntryId,\n input: unknown,\n role: DbRole = this.#core.internals.auth.resolveUserRole(userId)\n ): Promise<void> => {\n const g = cfg.guard\n if (!g || !userId) return\n const obj = (input && typeof input === 'object' ? input : {}) as Record<string, unknown>\n\n this.#enforceFileRefCheck(g.checkFileRef, c, userId, input, obj, role)\n\n if (g.checkCollectionField) {\n const { collection, param } = g.checkCollectionField\n const docId = c?.req.param(param) ?? (typeof obj[param] === 'string' ? (obj[param] as string) : '')\n const doc = await this.#core.db.read(collection, docId, false, { bypassRbac: true })\n if (!doc) {\n return this.#core.errors.httpError(\n 404,\n `${collection === 'chat' ? 'Chat' : 'Document'} not found`,\n 'NOT_FOUND'\n )\n }\n if (!(await this.#core.db.canAccess(collection, doc, userId, 'read', role))) {\n return this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n }\n\n if (g.checkUserId) {\n const targetUserId =\n typeof g.checkUserId === 'function'\n ? g.checkUserId(input, c)\n : typeof obj.userId === 'string'\n ? obj.userId\n : undefined\n if (targetUserId && role !== 'admin' && userId !== CORE_CONFIG.auth.adminUserId && targetUserId !== userId) {\n this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n if (obj.backupBeforeErase && role !== 'admin' && userId !== CORE_CONFIG.auth.adminUserId) {\n this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n }\n\n if (g.requireEmailVerified && role !== 'admin' && userId !== CORE_CONFIG.auth.adminUserId) {\n const authUser = await this.#core.auth.getUser(userId)\n if (!authUser?.emailVerified) {\n this.#core.errors.httpError(403, 'Email verification required', 'EMAIL_NOT_VERIFIED')\n }\n }\n\n if (g.custom) {\n const ok = await g.custom({ userId, role, input, env: this.#core.env, ...(c ? { c } : {}) })\n if (ok === false) this.#core.errors.httpError(403, 'Forbidden', 'FORBIDDEN')\n }\n }\n\n withHttpIdempotency = async <T>(\n routeKey: string,\n dedupeKey: string,\n userId: EntryId,\n isDev: boolean,\n fn: () => Promise<T>\n ): Promise<T> => {\n const keyHash = createHash('sha256')\n .update(`${routeKey}:${userId}:${dedupeKey}`)\n .digest('hex')\n .slice(0, 40)\n return this.#core.internals.resilience.singleflight(\n `http_idem:${isDev ? 'dev' : 'prod'}:${keyHash}`,\n async () => {\n const docRef = this.#core.db.firestore(isDev).collection('_idempotency').doc(keyHash)\n const snap = await docRef.get().catch(() => null)\n const data = snap?.exists ? (snap.data() as Record<string, unknown> | undefined) : undefined\n const now = Date.now()\n if (\n data?.status === 'completed' &&\n typeof data.expiresAtMs === 'number' &&\n data.expiresAtMs > now &&\n 'response' in data\n ) {\n return data.response as T\n }\n const out = await fn()\n if (!(out instanceof Response)) {\n const expiresAtMs = Date.now() + HTTP_IDEMPOTENCY_TTL_MS\n await docRef\n .set({\n id: keyHash,\n routeKey,\n userId,\n status: 'completed',\n response: out ?? null,\n createdAt: new Date().toISOString(),\n expiresAtMs,\n expiresAt: Timestamp.fromMillis(expiresAtMs)\n })\n .catch(() => {})\n }\n return out\n },\n { scope: 'global' }\n )\n }\n}\n\nexport const mergeCoreAndDomainRoutes = (\n rawCoreRoutes: Record<CoreRouteId, Partial<RouteConfig>>,\n overrides: CoreRouteOverrides,\n attachmentTypesDesc: string,\n domainRouteDefs: Record<string, RouteConfig<any, any, any, any>>\n): Record<string, RouteConfig> => {\n const coreRoutes = Object.fromEntries(\n (Object.keys(CORE_ROUTE_DEFAULTS) as CoreRouteId[]).map((id) => {\n const merged = {\n mcp: false,\n ...CORE_ROUTE_DEFAULTS[id],\n ...rawCoreRoutes[id],\n ...(id === 'attachments.scan' && attachmentTypesDesc\n ? {\n description: `OCR + classify + extract structured fields for a single attachment ref. Recognised types: ${attachmentTypesDesc}; or other.`\n }\n : {}),\n ...(overrides[id] ?? {})\n } as RouteConfig\n merged.mcp = merged.mcp === true\n return [id, merged]\n })\n ) as Record<CoreRouteId, RouteConfig>\n\n const domainRoutes: Record<string, RouteConfig> = {}\n for (const [name, routeCfg] of Object.entries(domainRouteDefs)) {\n const normalizedPath = routeCfg.path\n ? routeCfg.path.startsWith('/')\n ? routeCfg.path\n : `/${routeCfg.path}`\n : `/${name}`\n domainRoutes[name] = {\n ...routeCfg,\n mcp: routeCfg.mcp === true,\n path: normalizedPath,\n workflowName: routeCfg.workflowName ?? (routeCfg.mode === 'workflow' ? name : undefined)\n } as RouteConfig\n }\n\n return { ...coreRoutes, ...domainRoutes }\n}\n", "import { spawn } from 'node:child_process'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { parseEnv } from 'node:util'\nimport { applicationDefault } from 'firebase-admin/app'\n\nconst hasValue = (value: string | undefined): value is string => value != null && value.length > 0\n\nconst readDotEnv = (cwd = process.cwd()): Record<string, string> => {\n const envPath = join(cwd, '.env')\n return existsSync(envPath) ? (parseEnv(readFileSync(envPath, 'utf8')) as Record<string, string>) : {}\n}\n\nconst getSecretText = async (projectId: string, accessToken: string, secretName: string): Promise<string> => {\n const url = `https://secretmanager.googleapis.com/v1/projects/${projectId}/secrets/${secretName}/versions/latest:access`\n const res = await fetch(url, { headers: { Authorization: `Bearer ${accessToken}` } })\n const data = (await res.json()) as { payload?: { data?: string }; error?: { message?: string } }\n if (!res.ok || !data.payload?.data) {\n throw new Error(`Secret is empty or not defined: ${secretName} (${data.error?.message ?? res.status})`)\n }\n return Buffer.from(data.payload.data, 'base64').toString('utf8')\n}\n\nexport const getSecrets = async (\n secretNames?: readonly string[],\n cwd = process.cwd()\n): Promise<Record<string, string>> => {\n const dotEnv = readDotEnv(cwd)\n const merged: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(dotEnv)) {\n if (hasValue(process.env[key])) {\n merged[key] = process.env[key]!\n } else if (hasValue(value)) {\n merged[key] = value\n }\n }\n\n const projectId = (merged.GCP_PROJECT || process.env.GCP_PROJECT)!\n const keysToResolve =\n secretNames && secretNames.length > 0\n ? secretNames.filter((name) => !hasValue(merged[name]) && !hasValue(process.env[name]))\n : Object.entries(dotEnv)\n .filter(([key, value]) => !hasValue(value) && !hasValue(process.env[key]))\n .map(([key]) => key)\n\n if (keysToResolve.length > 0 && projectId) {\n const { access_token } = await applicationDefault().getAccessToken()\n if (!access_token) throw new Error('Failed to obtain GCP Application Default Credentials access token')\n const resolved = await Promise.all(\n keysToResolve.map(\n async (secretName) => [secretName, await getSecretText(projectId, access_token, secretName)] as const\n )\n )\n for (const [key, value] of resolved) {\n merged[key] = value\n }\n }\n\n return merged\n}\n\nexport const loadGcpSecrets = async (\n secretNames?: readonly string[],\n cwd = process.cwd()\n): Promise<Record<string, string>> => {\n const env = await getSecrets(secretNames, cwd)\n for (const [k, v] of Object.entries(env)) {\n if (!hasValue(process.env[k])) process.env[k] = v\n }\n return env\n}\n\nexport const runWithGcpEnv = async (\n cmd: string[],\n secretNames?: readonly string[],\n cwd = process.cwd()\n): Promise<number> => {\n const env = await getSecrets(secretNames, cwd)\n return new Promise<number>((resolve, reject) => {\n const child = spawn(cmd[0]!, cmd.slice(1), {\n cwd,\n env: { ...process.env, ...env },\n stdio: 'inherit'\n })\n child.on('error', reject)\n child.on('close', (code) => resolve(code ?? 1))\n })\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["AsyncLocalStorage", "res", "norm", "z", "z", "z", "z", "core", "docs", "db", "z", "z", "z", "z", "z", "z", "createHash", "createHash", "createHash", "createHash", "role", "emailVerified", "z", "z", "FieldValue", "FieldValue", "Timestamp", "z", "FieldValue", "userContext", "agentRegistry", "z", "z", "createHash", "timingSafeEqual", "body", "core", "z", "z", "createHash", "createHmac", "timingSafeEqual", "createHash", "path", "constantTimeEqual", "timingSafeEqual", "getHeader", "createHmac", "apiKey", "webhookSecret", "path", "checkoutId", "res", "paymentLinkId", "invoiceId", "chargeId", "status", "subscriptionId", "core", "z", "z", "z", "z", "HTTPException", "HTTPException", "z", "Timestamp", "Timestamp", "z", "z", "Timestamp", "val", "createHash", "Timestamp", "Timestamp", "createHash", "Timestamp", "createHash", "timingSafeEqual", "Timestamp", "getCookie", "createHash", "timingSafeEqual", "getCookie", "Timestamp", "path", "z", "AsyncLocalStorage"]
7
+ }