@corgelabs/corge 0.0.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +542 -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 +97 -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 +58 -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 +121 -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,458 @@
1
+ import type { Context } from 'hono'
2
+ import type { z } from 'zod'
3
+ import { processAttachmentsInput, scanAttachmentInput, type AttachmentTypesMap } from '../attachments'
4
+ import {
5
+ blockUserBody, completeAccountRecoveryBody, customTokenBody, emailSignInBody, emailSignUpBody,
6
+ eraseUserInput, eraseUserOutput, forgotPasswordBody, initiateAccountRecoveryBody, resetPasswordBody,
7
+ sendVerificationEmailBody, sessionBody, setRecoveryEmailBody, signOutBody, socialSignInInput,
8
+ verifyEmailBody, verifyRecoveryEmailBody
9
+ } from '../auth'
10
+ import { openaiCompletionsBody, saveChatBody, streamChatBody, type AgentConfig, type ContextItemSpec } from '../chat'
11
+ import type { AppBindings, AppEnv, DbRole, RateLimitConfig } from '../config'
12
+ import { fileScan, type CollectionDefinition, type CollectionName, type EntryId } from '../db'
13
+ import {
14
+ emailLogsQuerySchema, emailWebhookParamsSchema, sendBatchEmailInputSchema, sendBatchEmailResultSchema,
15
+ sendEmailInputSchema, sendEmailResultSchema, type EmailTemplatesMap, type SendEmailInput
16
+ } from '../emails'
17
+ import type { Core } from '../index'
18
+ import {
19
+ cancelSubscriptionInput, changeTierInput, chargeResultSchema, checkoutSessionResultSchema,
20
+ createCheckoutInput, createInvoiceInput, createPaymentLinkInput, directChargeInput, invoiceResultSchema,
21
+ paymentLinkResultSchema, paymentWebhookParamsSchema, subscribeInput, subscribeResultSchema,
22
+ subscriptionRecordSchema, type CancelSubscriptionInput, type ChangeTierInput, type CreateCheckoutInput,
23
+ type CreateInvoiceInput, type CreatePaymentLinkInput, type DirectChargeInput, type PlansMap,
24
+ type ProductsMap, type SubscribeInput
25
+ } from '../payments'
26
+ import type { RollbackLeg, StepRetryPolicy, StepRunner } from '../tasks'
27
+ import type { Duration } from '../utils'
28
+
29
+ export type AuthLevel = 'public' | 'user' | 'strict' | 'admin' | false | 'none' | 'authenticated' | 'api-key'
30
+
31
+ export type RouteMode = 'rest' | 'workflow'
32
+
33
+ export interface ResourceGuardConfig<I = any> {
34
+ checkFileRef?: boolean | ((input: I, c?: Context<AppEnv>) => string | string[] | undefined)
35
+ checkUserId?: boolean | ((input: I, c?: Context<AppEnv>) => string | undefined)
36
+ checkCollectionField?: { collection: CollectionName; param: string }
37
+ requireEmailVerified?: boolean
38
+ custom?: (ctx: {
39
+ userId: EntryId
40
+ role: DbRole
41
+ input: I
42
+ env: AppBindings
43
+ c?: Context<AppEnv>
44
+ }) => boolean | Promise<boolean>
45
+ }
46
+
47
+ export interface RouteExecutionContext<
48
+ I = any,
49
+ P = Record<string, string>,
50
+ Q = Record<string, string>
51
+ > {
52
+ core: Core
53
+ env: AppBindings
54
+ userId: EntryId
55
+ role: DbRole
56
+ mode: RouteMode
57
+ step: StepRunner
58
+ allWithRollback: <T extends readonly unknown[]>(legs: { [K in keyof T]: RollbackLeg<T[K]> }) => Promise<T>
59
+ input: I
60
+ params: P
61
+ query: Q
62
+ rawBody?: string
63
+ c: Context<AppEnv>
64
+ }
65
+
66
+ export interface BaseRouteConfig<I = any, O = any, P = any, Q = any> {
67
+ mode?: RouteMode
68
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'ALL'
69
+ path?: string
70
+ workflowName?: string
71
+ description?: string
72
+ auth?: AuthLevel
73
+ rateLimit?: RateLimitConfig
74
+ guard?: ResourceGuardConfig<I>
75
+ params?: z.ZodType<P>
76
+ query?: z.ZodType<Q>
77
+ input?: z.ZodType<I>
78
+ output?: z.ZodType<O>
79
+ rawBody?: boolean
80
+ mcp?: boolean
81
+ tool?: boolean
82
+ timeout?: Duration
83
+ retry?: number | StepRetryPolicy
84
+ idempotencyKey?: (input: I, ctx: { userId: EntryId }) => string | undefined
85
+ }
86
+
87
+ export interface RouteConfig<I = any, O = any, P = any, Q = any> extends BaseRouteConfig<I, O, P, Q> {
88
+ shortCircuit?: (ctx: RouteExecutionContext<I, P, Q>) => Promise<O | undefined | null> | O | undefined | null
89
+ handler: (ctx: RouteExecutionContext<I, P, Q>) => Response | O | Promise<Response | O>
90
+ }
91
+
92
+ export type CoreRouteId =
93
+ | 'health'
94
+ | 'auth.custom-token'
95
+ | 'auth.session.create'
96
+ | 'auth.session.get'
97
+ | 'auth.sign-up.email'
98
+ | 'auth.sign-in.email'
99
+ | 'auth.sign-in.social'
100
+ | 'auth.email.send-verification'
101
+ | 'auth.email.verify'
102
+ | 'auth.password.forgot'
103
+ | 'auth.password.reset'
104
+ | 'auth.recovery-email.set'
105
+ | 'auth.recovery-email.verify'
106
+ | 'auth.account-recovery.initiate'
107
+ | 'auth.account-recovery.complete'
108
+ | 'auth.users.list'
109
+ | 'auth.users.block'
110
+ | 'auth.users.delete'
111
+ | 'auth.sign-out'
112
+ | 'files.upload'
113
+ | 'files.list'
114
+ | 'files.get'
115
+ | 'files.delete'
116
+ | 'chat.list'
117
+ | 'chat.get'
118
+ | 'chat.messages'
119
+ | 'chat.save'
120
+ | 'chat.delete'
121
+ | 'chat.stream'
122
+ | 'chat.cancel'
123
+ | 'openai.models'
124
+ | 'openai.completions'
125
+ | 'attachments.scan'
126
+ | 'attachments.process'
127
+ | 'routes.list'
128
+ | 'tasks.status'
129
+ | 'tasks.signal'
130
+ | 'tasks.cancel'
131
+ | 'emails.send'
132
+ | 'emails.batch'
133
+ | 'emails.logs'
134
+ | 'emails.webhook'
135
+ | 'payments.checkout'
136
+ | 'payments.paymentLink'
137
+ | 'payments.invoice'
138
+ | 'payments.charge'
139
+ | 'payments.subscribe'
140
+ | 'payments.changeTier'
141
+ | 'payments.cancelSubscription'
142
+ | 'payments.status'
143
+ | 'payments.webhook'
144
+
145
+ export type CoreRouteOverride = Partial<
146
+ Pick<RouteConfig, 'auth' | 'rateLimit' | 'guard' | 'mcp' | 'tool' | 'timeout' | 'retry' | 'description'>
147
+ >
148
+
149
+ export type CoreRouteOverrides = Partial<Record<CoreRouteId, CoreRouteOverride>>
150
+
151
+ export interface WorkflowRegistryEntry {
152
+ name: string
153
+ description: string
154
+ input: z.ZodType<any>
155
+ output?: z.ZodType<any>
156
+ mode: RouteMode
157
+ deadlineSeconds?: number
158
+ guard?: BaseRouteConfig['guard']
159
+ runTask: (params: any, step: StepRunner) => Promise<unknown>
160
+ invoke: (
161
+ params: any,
162
+ userId: EntryId,
163
+ c?: Context<AppEnv>,
164
+ role?: DbRole,
165
+ opts?: { wait?: boolean }
166
+ ) => Promise<unknown>
167
+ }
168
+
169
+ export interface CoreAppInit {
170
+ coreRouteOverrides?: CoreRouteOverrides
171
+ attachmentTypes?: AttachmentTypesMap
172
+ emailTemplates?: EmailTemplatesMap
173
+ plans?: PlansMap
174
+ products?: ProductsMap
175
+ agents?: Record<string, AgentConfig>
176
+ routes?: Record<string, RouteConfig<any, any, any, any>>
177
+ collections?: Record<string, CollectionDefinition<any>>
178
+ context?: readonly ContextItemSpec[]
179
+ }
180
+
181
+ export const defineRoute = <C extends RouteConfig<any, any, any, any>>(config: C): C => ({ mcp: false, ...config })
182
+
183
+ export const defineRoutes = <T extends Record<string, RouteConfig<any, any, any, any>>>(routes: T): T => routes
184
+
185
+ export const defineRouteOverrides = <T extends CoreRouteOverrides>(overrides: T): T => overrides
186
+
187
+ export const CORE_ROUTE_DEFAULTS: Record<CoreRouteId, BaseRouteConfig> = {
188
+ health: { mode: 'rest', method: 'GET', path: '/health', auth: 'public', description: 'Public service health check endpoint.' },
189
+ 'auth.custom-token': { mode: 'rest', method: 'POST', path: '/auth/custom-token', auth: 'admin', input: customTokenBody },
190
+ 'auth.session.create': { mode: 'rest', method: 'POST', path: '/auth/session', auth: 'public', input: sessionBody },
191
+ 'auth.session.get': { mode: 'rest', method: 'GET', path: '/auth/session', auth: 'strict' },
192
+ 'auth.sign-up.email': { mode: 'rest', method: 'POST', path: '/auth/sign-up/email', auth: 'public', input: emailSignUpBody },
193
+ 'auth.sign-in.email': { mode: 'rest', method: 'POST', path: '/auth/sign-in/email', auth: 'public', input: emailSignInBody },
194
+ 'auth.sign-in.social': {
195
+ mode: 'rest',
196
+ method: 'POST',
197
+ path: '/auth/sign-in/social',
198
+ auth: 'public',
199
+ description: 'Sign in or link user account using Google or Apple OIDC ID token (Web & iOS/Capacitor).',
200
+ input: socialSignInInput
201
+ },
202
+ 'auth.email.send-verification': {
203
+ mode: 'rest',
204
+ method: 'POST',
205
+ path: '/auth/email/send-verification',
206
+ auth: 'user',
207
+ description: 'Generate and send a 6-digit OTP and magic token to verify the caller primary email.',
208
+ input: sendVerificationEmailBody
209
+ },
210
+ 'auth.email.verify': {
211
+ mode: 'rest',
212
+ method: 'POST',
213
+ path: '/auth/email/verify',
214
+ auth: 'public',
215
+ description: 'Verify primary email ownership via OTP code or magic token and evict stale token cache entries.',
216
+ input: verifyEmailBody
217
+ },
218
+ 'auth.password.forgot': {
219
+ mode: 'rest',
220
+ method: 'POST',
221
+ path: '/auth/password/forgot',
222
+ auth: 'public',
223
+ description: 'Request a password reset OTP/token without revealing account existence.',
224
+ input: forgotPasswordBody
225
+ },
226
+ 'auth.password.reset': {
227
+ mode: 'rest',
228
+ method: 'POST',
229
+ path: '/auth/password/reset',
230
+ auth: 'public',
231
+ description: 'Reset user password using a valid OTP/token and revoke all active sessions.',
232
+ input: resetPasswordBody
233
+ },
234
+ 'auth.recovery-email.set': {
235
+ mode: 'rest',
236
+ method: 'POST',
237
+ path: '/auth/recovery-email/set',
238
+ auth: 'strict',
239
+ description: 'Bind a secondary recovery email address and send a verification OTP.',
240
+ input: setRecoveryEmailBody
241
+ },
242
+ 'auth.recovery-email.verify': {
243
+ mode: 'rest',
244
+ method: 'POST',
245
+ path: '/auth/recovery-email/verify',
246
+ auth: 'strict',
247
+ description: 'Verify ownership of the secondary recovery email via OTP code or token.',
248
+ input: verifyRecoveryEmailBody
249
+ },
250
+ 'auth.account-recovery.initiate': {
251
+ mode: 'rest',
252
+ method: 'POST',
253
+ path: '/auth/account-recovery/initiate',
254
+ auth: 'public',
255
+ description: 'Initiate full account recovery by sending a recovery OTP to a verified secondary recovery email.',
256
+ input: initiateAccountRecoveryBody
257
+ },
258
+ 'auth.account-recovery.complete': {
259
+ mode: 'rest',
260
+ method: 'POST',
261
+ path: '/auth/account-recovery/complete',
262
+ auth: 'public',
263
+ description: 'Complete account recovery, update primary email (and optional password), revoke old sessions, and mint a fresh session.',
264
+ input: completeAccountRecoveryBody
265
+ },
266
+ 'auth.users.list': { mode: 'rest', method: 'GET', path: '/auth/users', auth: 'admin' },
267
+ 'auth.users.block': { mode: 'rest', method: 'POST', path: '/auth/users/block', auth: 'strict', guard: { checkUserId: true }, input: blockUserBody },
268
+ 'auth.users.delete': {
269
+ mode: 'workflow',
270
+ method: 'POST',
271
+ path: '/erase-user',
272
+ workflowName: 'erase-user',
273
+ description: 'Cascade-erase a user across Storage, Firestore collections, and Firebase Auth.',
274
+ auth: 'strict',
275
+ guard: { checkUserId: true },
276
+ mcp: false,
277
+ input: eraseUserInput,
278
+ output: eraseUserOutput
279
+ },
280
+ 'auth.sign-out': { mode: 'rest', method: 'POST', path: '/auth/sign-out', auth: 'public', input: signOutBody },
281
+ 'files.upload': { mode: 'rest', method: 'POST', path: '/files', auth: 'user' },
282
+ 'files.list': { mode: 'rest', method: 'GET', path: '/files', auth: 'user' },
283
+ 'files.get': { mode: 'rest', method: 'GET', path: '/files/:ref', auth: 'user', guard: { checkFileRef: true } },
284
+ 'files.delete': { mode: 'rest', method: 'DELETE', path: '/files/:ref', auth: 'user', guard: { checkFileRef: true } },
285
+ 'chat.list': { mode: 'rest', method: 'GET', path: '/chats', auth: 'user' },
286
+ 'chat.get': { mode: 'rest', method: 'GET', path: '/chats/:chatId', auth: 'user', guard: { checkCollectionField: { collection: 'chat', param: 'chatId' } } },
287
+ 'chat.messages': { mode: 'rest', method: 'GET', path: '/chats/:chatId/messages', auth: 'user', guard: { checkCollectionField: { collection: 'chat', param: 'chatId' } } },
288
+ 'chat.save': { mode: 'rest', method: 'POST', path: '/chats', auth: 'user', input: saveChatBody },
289
+ 'chat.delete': { mode: 'rest', method: 'DELETE', path: '/chats/:chatId', auth: 'user', guard: { checkCollectionField: { collection: 'chat', param: 'chatId' } } },
290
+ 'chat.stream': { mode: 'rest', method: 'POST', path: '/chats/:chatId', auth: 'user', input: streamChatBody },
291
+ 'chat.cancel': { mode: 'rest', method: 'POST', path: '/chats/:chatId/cancel', auth: 'user', guard: { checkCollectionField: { collection: 'chat', param: 'chatId' } } },
292
+ 'openai.models': { mode: 'rest', method: 'GET', path: '/v1/models', auth: 'user' },
293
+ 'openai.completions': { mode: 'rest', method: 'POST', path: '/v1/chat/completions', auth: 'user', input: openaiCompletionsBody },
294
+ 'attachments.scan': {
295
+ mode: 'workflow',
296
+ method: 'POST',
297
+ path: '/scan-attachment',
298
+ workflowName: 'scan-attachment',
299
+ description: 'OCR + classify + extract structured fields for a single attachment ref.',
300
+ auth: 'user',
301
+ guard: { checkFileRef: true },
302
+ mcp: true,
303
+ tool: true,
304
+ input: scanAttachmentInput,
305
+ output: fileScan
306
+ },
307
+ 'attachments.process': {
308
+ mode: 'workflow',
309
+ method: 'POST',
310
+ path: '/process-attachments',
311
+ workflowName: 'process-attachments',
312
+ description: 'Fan out scan-attachment across 1..N file refs with cache short-circuit and sharded parallelism.',
313
+ auth: 'user',
314
+ guard: { checkFileRef: true },
315
+ mcp: true,
316
+ tool: true,
317
+ input: processAttachmentsInput
318
+ },
319
+ 'routes.list': { mode: 'rest', method: 'GET', path: '/routes', auth: 'admin' },
320
+ 'tasks.status': { mode: 'rest', method: 'GET', path: '/tasks/:taskId', auth: 'user' },
321
+ 'tasks.signal': { mode: 'rest', method: 'POST', path: '/tasks/:taskId/signal', auth: 'user' },
322
+ 'tasks.cancel': { mode: 'rest', method: 'DELETE', path: '/tasks/:taskId', auth: 'user' },
323
+ 'emails.send': {
324
+ mode: 'rest',
325
+ method: 'POST',
326
+ path: '/emails/send',
327
+ auth: 'admin',
328
+ rateLimit: { max: 60, windowMs: 60_000, keyBy: 'user' },
329
+ idempotencyKey: (inp: SendEmailInput | undefined) => inp?.idempotencyKey,
330
+ description: 'Send a transactional email via SendGrid or Resend with template resolution and audit logging.',
331
+ input: sendEmailInputSchema,
332
+ output: sendEmailResultSchema
333
+ },
334
+ 'emails.batch': {
335
+ mode: 'rest',
336
+ method: 'POST',
337
+ path: '/emails/batch',
338
+ auth: 'admin',
339
+ rateLimit: { max: 20, windowMs: 60_000, keyBy: 'user' },
340
+ description: 'Send up to 100 transactional emails in a single batch.',
341
+ input: sendBatchEmailInputSchema,
342
+ output: sendBatchEmailResultSchema
343
+ },
344
+ 'emails.logs': {
345
+ mode: 'rest',
346
+ method: 'GET',
347
+ path: '/emails/logs',
348
+ auth: 'admin',
349
+ rateLimit: { max: 120, windowMs: 60_000, keyBy: 'user' },
350
+ description: 'List email delivery audit logs with filtering by recipient, template, purpose, and status.',
351
+ query: emailLogsQuerySchema
352
+ },
353
+ 'emails.webhook': {
354
+ mode: 'rest',
355
+ method: 'POST',
356
+ path: '/emails/webhooks/:provider',
357
+ auth: 'none',
358
+ rawBody: true,
359
+ rateLimit: { max: 600, windowMs: 60_000, keyBy: 'ip' },
360
+ description: 'Receive and verify HMAC-SHA256 delivery/bounce/complaint webhooks from SendGrid or Resend.',
361
+ params: emailWebhookParamsSchema
362
+ },
363
+ 'payments.checkout': {
364
+ mode: 'rest',
365
+ method: 'POST',
366
+ path: '/payments/checkout',
367
+ auth: 'user',
368
+ rateLimit: { max: 30, windowMs: 60_000, keyBy: 'user' },
369
+ idempotencyKey: (inp: CreateCheckoutInput | undefined) => inp?.idempotencyKey,
370
+ description: 'Create a hosted checkout session for a predefined plan, product, or custom ad-hoc amount.',
371
+ input: createCheckoutInput,
372
+ output: checkoutSessionResultSchema
373
+ },
374
+ 'payments.paymentLink': {
375
+ mode: 'rest',
376
+ method: 'POST',
377
+ path: '/payments/payment-link',
378
+ auth: 'user',
379
+ rateLimit: { max: 30, windowMs: 60_000, keyBy: 'user' },
380
+ idempotencyKey: (inp: CreatePaymentLinkInput | undefined) => inp?.idempotencyKey,
381
+ description: 'Generate a shareable payment link for a predefined plan, product, or custom ad-hoc amount.',
382
+ input: createPaymentLinkInput,
383
+ output: paymentLinkResultSchema
384
+ },
385
+ 'payments.invoice': {
386
+ mode: 'rest',
387
+ method: 'POST',
388
+ path: '/payments/invoice',
389
+ auth: 'user',
390
+ rateLimit: { max: 20, windowMs: 60_000, keyBy: 'user' },
391
+ idempotencyKey: (inp: CreateInvoiceInput | undefined) => inp?.idempotencyKey,
392
+ description: 'Generate a finalized invoice with hosted payment URL and PDF link.',
393
+ input: createInvoiceInput,
394
+ output: invoiceResultSchema
395
+ },
396
+ 'payments.charge': {
397
+ mode: 'rest',
398
+ method: 'POST',
399
+ path: '/payments/charge',
400
+ auth: 'user',
401
+ rateLimit: { max: 20, windowMs: 60_000, keyBy: 'user' },
402
+ idempotencyKey: (inp: DirectChargeInput | undefined) => inp?.idempotencyKey,
403
+ description: 'Execute a direct one-time charge for a predefined product or custom amount.',
404
+ input: directChargeInput,
405
+ output: chargeResultSchema
406
+ },
407
+ 'payments.subscribe': {
408
+ mode: 'rest',
409
+ method: 'POST',
410
+ path: '/payments/subscribe',
411
+ auth: 'user',
412
+ rateLimit: { max: 15, windowMs: 60_000, keyBy: 'user' },
413
+ idempotencyKey: (inp: SubscribeInput | undefined) => inp?.idempotencyKey,
414
+ description: 'Subscribe the caller to a defined recurring or free plan tier.',
415
+ input: subscribeInput,
416
+ output: subscribeResultSchema
417
+ },
418
+ 'payments.changeTier': {
419
+ mode: 'rest',
420
+ method: 'POST',
421
+ path: '/payments/subscription/change-tier',
422
+ auth: 'user',
423
+ rateLimit: { max: 15, windowMs: 60_000, keyBy: 'user' },
424
+ idempotencyKey: (inp: ChangeTierInput | undefined) => inp?.idempotencyKey,
425
+ description: 'Upgrade or downgrade the caller active subscription tier with proration.',
426
+ input: changeTierInput,
427
+ output: subscriptionRecordSchema
428
+ },
429
+ 'payments.cancelSubscription': {
430
+ mode: 'rest',
431
+ method: 'POST',
432
+ path: '/payments/subscription/cancel',
433
+ auth: 'user',
434
+ rateLimit: { max: 15, windowMs: 60_000, keyBy: 'user' },
435
+ idempotencyKey: (inp: CancelSubscriptionInput | undefined) => inp?.idempotencyKey,
436
+ description: 'Cancel the caller active subscription immediately or at period end.',
437
+ input: cancelSubscriptionInput,
438
+ output: subscriptionRecordSchema
439
+ },
440
+ 'payments.status': {
441
+ mode: 'rest',
442
+ method: 'GET',
443
+ path: '/payments/status',
444
+ auth: 'user',
445
+ rateLimit: { max: 120, windowMs: 60_000, keyBy: 'user' },
446
+ description: 'Get the caller current subscription tier, billing status, and AI token/metric usage summary.'
447
+ },
448
+ 'payments.webhook': {
449
+ mode: 'rest',
450
+ method: 'POST',
451
+ path: '/payments/webhooks/:provider',
452
+ auth: 'none',
453
+ rawBody: true,
454
+ rateLimit: { max: 600, windowMs: 60_000, keyBy: 'ip' },
455
+ description: 'Receive and verify HMAC-SHA256 webhooks from Stripe or Dodo Payments with idempotent state reconciliation.',
456
+ params: paymentWebhookParamsSchema
457
+ }
458
+ }