@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
package/src/config.ts ADDED
@@ -0,0 +1,447 @@
1
+ import type { Context } from 'hono'
2
+ import type { Core } from './index'
3
+
4
+ try {
5
+ process.loadEnvFile()
6
+ } catch {}
7
+
8
+ export type DbRole = 'admin' | 'user' | 'anon'
9
+ export type DbAction = 'read' | 'write' | 'create' | 'delete' | '*'
10
+ export type DbAccessScope = 'own' | 'any'
11
+
12
+ export type RbacRoleScopes = {
13
+ [Scope in DbAccessScope]?: readonly DbAction[]
14
+ }
15
+
16
+ export type RbacConfig = {
17
+ [Role in DbRole]?: RbacRoleScopes
18
+ }
19
+
20
+ export const SECRET_NAMES = [
21
+ 'SDK_API_KEY',
22
+ 'MISTRAL_API_KEY',
23
+ 'TYPESAFE_API_KEY',
24
+ 'JINA_API_KEY',
25
+ 'WEB_API_KEY'
26
+ ] as const
27
+
28
+ export const EMAIL_SECRET_NAMES = [
29
+ 'RESEND_API_KEY',
30
+ 'SENDGRID_API_KEY',
31
+ 'EMAIL_WEBHOOK_SECRET',
32
+ 'EMAIL_SANDBOX_WEBHOOK_SECRET'
33
+ ] as const
34
+
35
+ export const PAYMENT_SECRET_NAMES = [
36
+ 'STRIPE_API_KEY',
37
+ 'STRIPE_SANDBOX_API_KEY',
38
+ 'STRIPE_WEBHOOK_SECRET',
39
+ 'STRIPE_SANDBOX_WEBHOOK_SECRET',
40
+ 'DODO_API_KEY',
41
+ 'DODO_SANDBOX_API_KEY',
42
+ 'DODO_WEBHOOK_SECRET',
43
+ 'DODO_SANDBOX_WEBHOOK_SECRET'
44
+ ] as const
45
+
46
+ export interface AppBindings {
47
+ SDK_API_KEY: string
48
+ MISTRAL_API_KEY: string
49
+ TYPESAFE_API_KEY: string
50
+ JINA_API_KEY: string
51
+ WEB_API_KEY: string
52
+ RESEND_API_KEY: string
53
+ SENDGRID_API_KEY: string
54
+ EMAIL_WEBHOOK_SECRET: string
55
+ EMAIL_SANDBOX_WEBHOOK_SECRET: string
56
+ STRIPE_API_KEY: string
57
+ STRIPE_SANDBOX_API_KEY: string
58
+ STRIPE_WEBHOOK_SECRET: string
59
+ STRIPE_SANDBOX_WEBHOOK_SECRET: string
60
+ DODO_API_KEY: string
61
+ DODO_SANDBOX_API_KEY: string
62
+ DODO_WEBHOOK_SECRET: string
63
+ DODO_SANDBOX_WEBHOOK_SECRET: string
64
+ isDev: boolean
65
+ }
66
+
67
+ export interface AppEnv {
68
+ Bindings: AppBindings
69
+ Variables: { userId: string; userRole: DbRole }
70
+ }
71
+
72
+ export interface RateLimitSpec {
73
+ max: number
74
+ windowMs: number
75
+ keyBy?: 'user' | 'ip' | ((c: Context<AppEnv>) => string)
76
+ }
77
+
78
+ export type RateLimitConfig = RateLimitSpec | false
79
+
80
+ export type EmailProvider = 'sendgrid' | 'resend' | 'firebase'
81
+
82
+ export type AuthTokenPurpose =
83
+ | 'verify_email'
84
+ | 'reset_password'
85
+ | 'verify_recovery_email'
86
+ | 'account_recovery'
87
+
88
+ export type AuthEmailPurpose =
89
+ | AuthTokenPurpose
90
+ | 'welcome'
91
+ | 'security_alert'
92
+
93
+ export interface TransactionalEmailPayload {
94
+ to: string
95
+ purpose: AuthEmailPurpose
96
+ code: string
97
+ token: string
98
+ expiresInMinutes: number
99
+ userId: string
100
+ }
101
+
102
+ export interface AuthEmailVariables {
103
+ appName: string
104
+ userId: string
105
+ email: string
106
+ purpose: AuthEmailPurpose
107
+ code: string
108
+ token: string
109
+ actionUrl: string
110
+ expiresInMinutes: number
111
+ [key: string]: unknown
112
+ }
113
+
114
+ export type AuthFlowEmailHook = (
115
+ payload: AuthEmailVariables,
116
+ context: { core: Core; env: AppBindings }
117
+ ) => Promise<boolean | Partial<AuthEmailVariables> | void>
118
+
119
+ export interface AuthFlowConfigSpec {
120
+ templateId?: string
121
+ subject?: string
122
+ actionPath?: string
123
+ onSend?: AuthFlowEmailHook
124
+ }
125
+
126
+ export interface EmailsConfig {
127
+ provider: EmailProvider
128
+ fromEmail: string
129
+ fromName: string
130
+ replyTo?: string
131
+ actionBaseUrl: string
132
+ otpTtlMinutes: number
133
+ recoveryOtpTtlMinutes: number
134
+ maxVerifyAttempts: number
135
+ enforceSuppressionList: boolean
136
+ webhookToleranceSeconds: number
137
+ onAuthEmail?: AuthFlowEmailHook
138
+ authFlows: Record<AuthEmailPurpose, AuthFlowConfigSpec>
139
+ sendgrid: {
140
+ baseUrl: string
141
+ }
142
+ resend: {
143
+ baseUrl: string
144
+ }
145
+ }
146
+
147
+ export type PaymentProvider = 'stripe' | 'dodo'
148
+
149
+ export type EnvScopedString = string | { prod: string; dev: string }
150
+
151
+ export interface PaymentsConfig {
152
+ enabled: boolean
153
+ provider: PaymentProvider
154
+ defaultCurrency: Lowercase<string>
155
+ defaultPlanId: string
156
+ autoTrackAiTokens: boolean
157
+ aiTokenMeterName: string
158
+ webhookToleranceSeconds: number
159
+ urls: {
160
+ successUrl: EnvScopedString
161
+ cancelUrl: EnvScopedString
162
+ returnUrl: EnvScopedString
163
+ }
164
+ dodo: {
165
+ liveBaseUrl: string
166
+ testBaseUrl: string
167
+ }
168
+ stripe: {
169
+ baseUrl: string
170
+ apiVersion: string
171
+ }
172
+ }
173
+
174
+ export type DeepPartial<T> = {
175
+ [K in keyof T]?: T[K] extends object ? (T[K] extends (...args: any[]) => any ? T[K] : DeepPartial<T[K]>) : T[K]
176
+ }
177
+
178
+ export interface CoreConfig {
179
+ appName: string
180
+ gcpProject: string
181
+ region: string
182
+ secrets: readonly string[]
183
+ firestoreDbs: { prod: string; dev: string }
184
+ storageBuckets: { prod: string; dev: string }
185
+ db: {
186
+ rbac: RbacConfig
187
+ }
188
+ context: {
189
+ dir: string
190
+ maxSources: number
191
+ userContextTimeoutMs: number
192
+ }
193
+ serviceAccount: string
194
+ computeAccount: string
195
+ workerUris: { prod: string; dev: string }
196
+ queueBaseNames: { prod: string; dev: string }
197
+ cloudRun: {
198
+ memory: '1GiB' | '2GiB' | '4GiB' | '8GiB'
199
+ cpu: number
200
+ http: { timeoutSeconds: number; concurrency: number; maxInstances: number; invoker: 'public' | 'private' }
201
+ worker: { timeoutSeconds: number; concurrency: number; maxInstances: number }
202
+ }
203
+ tasks: {
204
+ useCloudTasks: boolean
205
+ defaultShardsCount: number
206
+ batchCreateSize: number
207
+ maxAttempts: number
208
+ hedgeAfterMs: number
209
+ heartbeatIntervalMs: number
210
+ heartbeatStaleMs: number
211
+ timeoutMs: number
212
+ ttlMs: number
213
+ scanDeadlineSeconds: number
214
+ defaultDeadlineSeconds: number
215
+ claimCheckThresholdBytes: number
216
+ yieldBudgetRatio: number
217
+ }
218
+ models: {
219
+ vertex: string
220
+ vertexExpert: string
221
+ vertexEmbedding: string
222
+ vertexLocation: string
223
+ mistralOcr: string
224
+ jev: string
225
+ defaultAgentMaxSteps: number
226
+ }
227
+ limits: {
228
+ maxAttachments: number
229
+ maxChatAttachments: number
230
+ chatMessagesLimit: number
231
+ defaultListLimit: number
232
+ maxFileBytes: number
233
+ maxBodyBytes: number
234
+ maxWaitMs: number
235
+ httpUser: RateLimitSpec
236
+ httpIp: RateLimitSpec
237
+ buckets: {
238
+ mistral: { windowMs: number; max: number }
239
+ jev: { windowMs: number; max: number }
240
+ ai: { windowMs: number; max: number }
241
+ workflows: { windowMs: number; max: number }
242
+ firestore: { windowMs: number; max: number }
243
+ storage: { windowMs: number; max: number }
244
+ emails: { windowMs: number; max: number }
245
+ payments: { windowMs: number; max: number }
246
+ }
247
+ }
248
+ auth: {
249
+ sessionCookie: string
250
+ sessionExpiresInMs: number
251
+ tokenCacheTtlMs: number
252
+ tokenCacheMaxSize: number
253
+ adminUserId: string
254
+ allowedOrigins: (string | RegExp)[]
255
+ oauth?: {
256
+ googleClientIds?: string[]
257
+ appleClientIds?: string[]
258
+ }
259
+ }
260
+ emails: EmailsConfig
261
+ payments: PaymentsConfig
262
+ }
263
+
264
+ const gcpProject = process.env.GCP_PROJECT ?? ''
265
+ const region = 'me-central1'
266
+ const defaultWebBaseUrl = `https://${gcpProject || 'app'}.web.app`
267
+
268
+ export const CORE_CONFIG: CoreConfig = {
269
+ appName: gcpProject,
270
+ gcpProject,
271
+ region,
272
+ secrets: [],
273
+ firestoreDbs: { prod: gcpProject, dev: `${gcpProject}-dev` },
274
+ storageBuckets: { prod: `${gcpProject}.firebasestorage.app`, dev: `${gcpProject}-dev` },
275
+ db: {
276
+ rbac: {
277
+ admin: { any: ['*'] },
278
+ user: { own: ['*'] },
279
+ anon: {}
280
+ }
281
+ },
282
+ context: {
283
+ dir: 'src/context',
284
+ maxSources: 5,
285
+ userContextTimeoutMs: 3_500
286
+ },
287
+ serviceAccount: `firebase-adminsdk-fbsvc@${gcpProject}.iam.gserviceaccount.com`,
288
+ computeAccount: '68329189121-compute@developer.gserviceaccount.com',
289
+ workerUris: {
290
+ prod: `https://${region}-${gcpProject}.cloudfunctions.net/${gcpProject}-tasks`,
291
+ dev: `https://${region}-${gcpProject}.cloudfunctions.net/${gcpProject}-tasks-dev`
292
+ },
293
+ queueBaseNames: {
294
+ prod: `${gcpProject}-tasks`,
295
+ dev: `${gcpProject}-tasks-dev`
296
+ },
297
+ cloudRun: {
298
+ memory: '4GiB',
299
+ cpu: 2,
300
+ http: { timeoutSeconds: 180, concurrency: 80, maxInstances: 50, invoker: 'public' },
301
+ worker: { timeoutSeconds: 540, concurrency: 20, maxInstances: 20 }
302
+ },
303
+ tasks: {
304
+ useCloudTasks: Boolean(process.env.K_SERVICE),
305
+ defaultShardsCount: 20,
306
+ batchCreateSize: 100,
307
+ maxAttempts: 3,
308
+ hedgeAfterMs: 65_000,
309
+ heartbeatIntervalMs: 20_000,
310
+ heartbeatStaleMs: 30_000,
311
+ timeoutMs: 510_000,
312
+ ttlMs: 3_600_000,
313
+ scanDeadlineSeconds: 120,
314
+ defaultDeadlineSeconds: 540,
315
+ claimCheckThresholdBytes: 204_800,
316
+ yieldBudgetRatio: 0.75
317
+ },
318
+ models: {
319
+ vertex: 'claude-haiku-5-5',
320
+ vertexExpert: 'claude-sonnet-4-5',
321
+ vertexEmbedding: 'text-embedding-005',
322
+ vertexLocation: 'global',
323
+ mistralOcr: 'mistral-ocr-latest',
324
+ jev: 'jev-latest',
325
+ defaultAgentMaxSteps: 8
326
+ },
327
+ limits: {
328
+ maxAttachments: 500,
329
+ maxChatAttachments: 20,
330
+ chatMessagesLimit: 15,
331
+ defaultListLimit: 100,
332
+ maxFileBytes: 20 * 1024 * 1024,
333
+ maxBodyBytes: 25 * 1024 * 1024,
334
+ maxWaitMs: 60_000,
335
+ httpUser: { max: 300, windowMs: 60_000, keyBy: 'user' },
336
+ httpIp: { max: 60, windowMs: 60_000, keyBy: 'ip' },
337
+ buckets: {
338
+ mistral: { windowMs: 60_000, max: 1250 },
339
+ jev: { windowMs: 60_000, max: 1200 },
340
+ ai: { windowMs: 60_000, max: 2000 },
341
+ workflows: { windowMs: 1_000, max: 500 },
342
+ firestore: { windowMs: 1_000, max: 500 },
343
+ storage: { windowMs: 1_000, max: 1000 },
344
+ emails: { windowMs: 1_000, max: 50 },
345
+ payments: { windowMs: 1_000, max: 100 }
346
+ }
347
+ },
348
+ auth: {
349
+ sessionCookie: 'session',
350
+ sessionExpiresInMs: 14 * 24 * 60 * 60 * 1000,
351
+ tokenCacheTtlMs: 5 * 60_000,
352
+ tokenCacheMaxSize: 2000,
353
+ adminUserId: 'admin',
354
+ allowedOrigins: [
355
+ /^https:\/\/[a-z0-9-]+\.a\.run\.app$/i,
356
+ /^https:\/\/([a-z0-9-]+\.)?(web\.app|firebaseapp\.com)$/i,
357
+ /^http:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i
358
+ ]
359
+ },
360
+ emails: {
361
+ provider: 'resend',
362
+ fromEmail: `no-reply@${gcpProject || 'app'}.firebaseapp.com`,
363
+ fromName: gcpProject || 'App',
364
+ actionBaseUrl: `https://${gcpProject || 'app'}.web.app`,
365
+ otpTtlMinutes: 15,
366
+ recoveryOtpTtlMinutes: 10,
367
+ maxVerifyAttempts: 5,
368
+ enforceSuppressionList: true,
369
+ webhookToleranceSeconds: 300,
370
+ authFlows: {
371
+ verify_email: { actionPath: '/auth/verify-email', subject: 'Verify your email address' },
372
+ reset_password: { actionPath: '/auth/reset-password', subject: 'Reset your password' },
373
+ verify_recovery_email: { actionPath: '/auth/verify-recovery', subject: 'Verify your recovery email' },
374
+ account_recovery: { actionPath: '/auth/account-recovery', subject: 'Recover your account' },
375
+ welcome: { actionPath: '/dashboard', subject: 'Welcome!' },
376
+ security_alert: { actionPath: '/settings/security', subject: 'Security alert on your account' }
377
+ },
378
+ sendgrid: {
379
+ baseUrl: 'https://api.sendgrid.com/v3'
380
+ },
381
+ resend: {
382
+ baseUrl: 'https://api.resend.com'
383
+ }
384
+ },
385
+ payments: {
386
+ enabled: false,
387
+ provider: 'dodo',
388
+ defaultCurrency: 'usd',
389
+ defaultPlanId: 'free',
390
+ autoTrackAiTokens: true,
391
+ aiTokenMeterName: 'ai_tokens',
392
+ webhookToleranceSeconds: 300,
393
+ urls: {
394
+ successUrl: `${defaultWebBaseUrl}/billing/success`,
395
+ cancelUrl: `${defaultWebBaseUrl}/billing/cancel`,
396
+ returnUrl: `${defaultWebBaseUrl}/billing`
397
+ },
398
+ dodo: {
399
+ liveBaseUrl: 'https://live.dodopayments.com',
400
+ testBaseUrl: 'https://test.dodopayments.com'
401
+ },
402
+ stripe: {
403
+ baseUrl: 'https://api.stripe.com/v1',
404
+ apiVersion: '2025-02-24.acacia'
405
+ }
406
+ }
407
+ }
408
+
409
+ const mergeDeep = <T extends Record<string, any>>(target: T, source?: DeepPartial<T>): T => {
410
+ if (!source) return target
411
+ for (const [k, v] of Object.entries(source)) {
412
+ if (v && typeof v === 'object' && !Array.isArray(v) && !(v instanceof RegExp) && typeof target[k] === 'object') {
413
+ mergeDeep(target[k], v as any)
414
+ } else if (v !== undefined) {
415
+ ;(target as any)[k] = v
416
+ }
417
+ }
418
+ return target
419
+ }
420
+
421
+ export const defineConfig = (overrides?: DeepPartial<CoreConfig>): CoreConfig => {
422
+ if (overrides?.gcpProject && overrides.gcpProject !== CORE_CONFIG.gcpProject) {
423
+ const p = overrides.gcpProject
424
+ const r = overrides.region ?? CORE_CONFIG.region
425
+ CORE_CONFIG.appName = p
426
+ CORE_CONFIG.firestoreDbs = { prod: p, dev: `${p}-dev` }
427
+ CORE_CONFIG.storageBuckets = { prod: `${p}.firebasestorage.app`, dev: `${p}-dev` }
428
+ CORE_CONFIG.serviceAccount = `firebase-adminsdk-fbsvc@${p}.iam.gserviceaccount.com`
429
+ CORE_CONFIG.workerUris = {
430
+ prod: `https://${r}-${p}.cloudfunctions.net/${p}-tasks`,
431
+ dev: `https://${r}-${p}.cloudfunctions.net/${p}-tasks-dev`
432
+ }
433
+ CORE_CONFIG.queueBaseNames = {
434
+ prod: `${p}-tasks`,
435
+ dev: `${p}-tasks-dev`
436
+ }
437
+ CORE_CONFIG.emails.fromEmail = `no-reply@${p}.firebaseapp.com`
438
+ CORE_CONFIG.emails.fromName = p
439
+ CORE_CONFIG.emails.actionBaseUrl = `https://${p}.web.app`
440
+ CORE_CONFIG.payments.urls = {
441
+ successUrl: `https://${p}.web.app/billing/success`,
442
+ cancelUrl: `https://${p}.web.app/billing/cancel`,
443
+ returnUrl: `https://${p}.web.app/billing`
444
+ }
445
+ }
446
+ return mergeDeep(CORE_CONFIG, overrides)
447
+ }
@@ -0,0 +1,2 @@
1
+ export * from './schema'
2
+ export { DbService } from './service'