@nxuss/lemma 1.42.0 → 1.44.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 (331) hide show
  1. package/README.md +1 -1
  2. package/bin/brain-ingest.js +18 -0
  3. package/bin/cloud.js +228 -0
  4. package/bin/init.js +1 -1
  5. package/dist/cjs/cli/hostHooks.d.ts +6 -0
  6. package/dist/cjs/cli/hostHooks.d.ts.map +1 -1
  7. package/dist/cjs/cli/hostHooks.js +13 -3
  8. package/dist/cjs/cli/hostHooks.js.map +1 -1
  9. package/dist/cjs/cloud/CloudBrainClient.d.ts +52 -0
  10. package/dist/cjs/cloud/CloudBrainClient.d.ts.map +1 -0
  11. package/dist/cjs/cloud/CloudBrainClient.js +161 -0
  12. package/dist/cjs/cloud/CloudBrainClient.js.map +1 -0
  13. package/dist/cjs/cloud/CloudConfig.d.ts +41 -0
  14. package/dist/cjs/cloud/CloudConfig.d.ts.map +1 -0
  15. package/dist/cjs/cloud/CloudConfig.js +133 -0
  16. package/dist/cjs/cloud/CloudConfig.js.map +1 -0
  17. package/dist/cjs/cloud/CloudEntitlement.d.ts +55 -0
  18. package/dist/cjs/cloud/CloudEntitlement.d.ts.map +1 -0
  19. package/dist/cjs/cloud/CloudEntitlement.js +174 -0
  20. package/dist/cjs/cloud/CloudEntitlement.js.map +1 -0
  21. package/dist/cjs/cloud/billing/stripeApi.d.ts +43 -0
  22. package/dist/cjs/cloud/billing/stripeApi.d.ts.map +1 -0
  23. package/dist/cjs/cloud/billing/stripeApi.js +111 -0
  24. package/dist/cjs/cloud/billing/stripeApi.js.map +1 -0
  25. package/dist/cjs/cloud/billing/stripeWebhook.d.ts +35 -0
  26. package/dist/cjs/cloud/billing/stripeWebhook.d.ts.map +1 -0
  27. package/dist/cjs/cloud/billing/stripeWebhook.js +185 -0
  28. package/dist/cjs/cloud/billing/stripeWebhook.js.map +1 -0
  29. package/dist/cjs/cloud/console/ConsoleStore.d.ts +111 -0
  30. package/dist/cjs/cloud/console/ConsoleStore.d.ts.map +1 -0
  31. package/dist/cjs/cloud/console/ConsoleStore.js +172 -0
  32. package/dist/cjs/cloud/console/ConsoleStore.js.map +1 -0
  33. package/dist/cjs/cloud/console/consoleRouter.d.ts +68 -0
  34. package/dist/cjs/cloud/console/consoleRouter.d.ts.map +1 -0
  35. package/dist/cjs/cloud/console/consoleRouter.js +263 -0
  36. package/dist/cjs/cloud/console/consoleRouter.js.map +1 -0
  37. package/dist/cjs/cloud/console/mailer.d.ts +22 -0
  38. package/dist/cjs/cloud/console/mailer.d.ts.map +1 -0
  39. package/dist/cjs/cloud/console/mailer.js +35 -0
  40. package/dist/cjs/cloud/console/mailer.js.map +1 -0
  41. package/dist/cjs/cloud/identity/PlanPolicy.d.ts +16 -1
  42. package/dist/cjs/cloud/identity/PlanPolicy.d.ts.map +1 -1
  43. package/dist/cjs/cloud/identity/PlanPolicy.js +47 -7
  44. package/dist/cjs/cloud/identity/PlanPolicy.js.map +1 -1
  45. package/dist/cjs/cloud/identity/RateLimiter.d.ts +21 -1
  46. package/dist/cjs/cloud/identity/RateLimiter.d.ts.map +1 -1
  47. package/dist/cjs/cloud/identity/RateLimiter.js +59 -2
  48. package/dist/cjs/cloud/identity/RateLimiter.js.map +1 -1
  49. package/dist/cjs/cloud/identity/TenantResolver.d.ts +4 -1
  50. package/dist/cjs/cloud/identity/TenantResolver.d.ts.map +1 -1
  51. package/dist/cjs/cloud/identity/TenantResolver.js +1 -1
  52. package/dist/cjs/cloud/identity/TenantResolver.js.map +1 -1
  53. package/dist/cjs/cloud/identity/authenticateV2.d.ts.map +1 -1
  54. package/dist/cjs/cloud/identity/authenticateV2.js +7 -4
  55. package/dist/cjs/cloud/identity/authenticateV2.js.map +1 -1
  56. package/dist/cjs/cloud/identity/identityStore.d.ts +85 -10
  57. package/dist/cjs/cloud/identity/identityStore.d.ts.map +1 -1
  58. package/dist/cjs/cloud/identity/identityStore.js +184 -2
  59. package/dist/cjs/cloud/identity/identityStore.js.map +1 -1
  60. package/dist/cjs/cloud/metering/PostgresLedgerStore.d.ts +16 -0
  61. package/dist/cjs/cloud/metering/PostgresLedgerStore.d.ts.map +1 -0
  62. package/dist/cjs/cloud/metering/PostgresLedgerStore.js +44 -0
  63. package/dist/cjs/cloud/metering/PostgresLedgerStore.js.map +1 -0
  64. package/dist/cjs/cloud/metering/UsageLedger.d.ts +37 -0
  65. package/dist/cjs/cloud/metering/UsageLedger.d.ts.map +1 -1
  66. package/dist/cjs/cloud/metering/UsageLedger.js +80 -17
  67. package/dist/cjs/cloud/metering/UsageLedger.js.map +1 -1
  68. package/dist/cjs/cloud/metering/index.d.ts +1 -0
  69. package/dist/cjs/cloud/metering/index.d.ts.map +1 -1
  70. package/dist/cjs/cloud/metering/index.js +1 -0
  71. package/dist/cjs/cloud/metering/index.js.map +1 -1
  72. package/dist/cjs/cloud/store/FileBrainStore.d.ts +1 -0
  73. package/dist/cjs/cloud/store/FileBrainStore.d.ts.map +1 -1
  74. package/dist/cjs/cloud/store/FileBrainStore.js +3 -0
  75. package/dist/cjs/cloud/store/FileBrainStore.js.map +1 -1
  76. package/dist/cjs/cloud/store/PostgresBrainStore.d.ts +1 -0
  77. package/dist/cjs/cloud/store/PostgresBrainStore.d.ts.map +1 -1
  78. package/dist/cjs/cloud/store/PostgresBrainStore.js +4 -0
  79. package/dist/cjs/cloud/store/PostgresBrainStore.js.map +1 -1
  80. package/dist/cjs/cloud/v2/app.d.ts.map +1 -1
  81. package/dist/cjs/cloud/v2/app.js +6 -0
  82. package/dist/cjs/cloud/v2/app.js.map +1 -1
  83. package/dist/cjs/cloud/v2/inputGuard.d.ts +23 -0
  84. package/dist/cjs/cloud/v2/inputGuard.d.ts.map +1 -0
  85. package/dist/cjs/cloud/v2/inputGuard.js +71 -0
  86. package/dist/cjs/cloud/v2/inputGuard.js.map +1 -0
  87. package/dist/cjs/cloud/v2/routes/admin.d.ts +24 -0
  88. package/dist/cjs/cloud/v2/routes/admin.d.ts.map +1 -0
  89. package/dist/cjs/cloud/v2/routes/admin.js +329 -0
  90. package/dist/cjs/cloud/v2/routes/admin.js.map +1 -0
  91. package/dist/cjs/cloud/v2/routes/entitlement.d.ts +13 -0
  92. package/dist/cjs/cloud/v2/routes/entitlement.d.ts.map +1 -0
  93. package/dist/cjs/cloud/v2/routes/entitlement.js +24 -0
  94. package/dist/cjs/cloud/v2/routes/entitlement.js.map +1 -0
  95. package/dist/cjs/cloud/v2/routes/index.d.ts +14 -1
  96. package/dist/cjs/cloud/v2/routes/index.d.ts.map +1 -1
  97. package/dist/cjs/cloud/v2/routes/index.js +36 -0
  98. package/dist/cjs/cloud/v2/routes/index.js.map +1 -1
  99. package/dist/cjs/cloud/v2/routes/memories.d.ts +21 -2
  100. package/dist/cjs/cloud/v2/routes/memories.d.ts.map +1 -1
  101. package/dist/cjs/cloud/v2/routes/memories.js +77 -0
  102. package/dist/cjs/cloud/v2/routes/memories.js.map +1 -1
  103. package/dist/cjs/cloud/v2/routes/recall.d.ts +1 -0
  104. package/dist/cjs/cloud/v2/routes/recall.d.ts.map +1 -1
  105. package/dist/cjs/cloud/v2/routes/recall.js +4 -0
  106. package/dist/cjs/cloud/v2/routes/recall.js.map +1 -1
  107. package/dist/cjs/cloud/v2/routes/tenant.d.ts +35 -0
  108. package/dist/cjs/cloud/v2/routes/tenant.d.ts.map +1 -0
  109. package/dist/cjs/cloud/v2/routes/tenant.js +62 -0
  110. package/dist/cjs/cloud/v2/routes/tenant.js.map +1 -0
  111. package/dist/cjs/cloud/v2/routes/usage.d.ts +1 -1
  112. package/dist/cjs/cloud/v2/routes/usage.d.ts.map +1 -1
  113. package/dist/cjs/cloud/v2/routes/verify.d.ts +1 -0
  114. package/dist/cjs/cloud/v2/routes/verify.d.ts.map +1 -1
  115. package/dist/cjs/cloud/v2/routes/verify.js +4 -0
  116. package/dist/cjs/cloud/v2/routes/verify.js.map +1 -1
  117. package/dist/cjs/cloud/v2/server.d.ts +9 -3
  118. package/dist/cjs/cloud/v2/server.d.ts.map +1 -1
  119. package/dist/cjs/cloud/v2/server.js +36 -2
  120. package/dist/cjs/cloud/v2/server.js.map +1 -1
  121. package/dist/cjs/cloud/v2/usageRecorder.d.ts +19 -0
  122. package/dist/cjs/cloud/v2/usageRecorder.d.ts.map +1 -0
  123. package/dist/cjs/cloud/v2/usageRecorder.js +42 -0
  124. package/dist/cjs/cloud/v2/usageRecorder.js.map +1 -0
  125. package/dist/cjs/contracts/api-v2.types.d.ts +90 -2
  126. package/dist/cjs/contracts/api-v2.types.d.ts.map +1 -1
  127. package/dist/cjs/contracts/store.d.ts +2 -0
  128. package/dist/cjs/contracts/store.d.ts.map +1 -1
  129. package/dist/cjs/mcp/index.js +3 -0
  130. package/dist/cjs/mcp/index.js.map +1 -1
  131. package/dist/cjs/mcp/tools/memory.d.ts.map +1 -1
  132. package/dist/cjs/mcp/tools/memory.js +104 -11
  133. package/dist/cjs/mcp/tools/memory.js.map +1 -1
  134. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  135. package/dist/cjs/mcp/tools.js.map +1 -1
  136. package/dist/cjs/proxy/KeyManager.d.ts.map +1 -1
  137. package/dist/cjs/proxy/KeyManager.js +5 -0
  138. package/dist/cjs/proxy/KeyManager.js.map +1 -1
  139. package/dist/cjs/subconscious/CloudBrain.d.ts +77 -0
  140. package/dist/cjs/subconscious/CloudBrain.d.ts.map +1 -0
  141. package/dist/cjs/subconscious/CloudBrain.js +347 -0
  142. package/dist/cjs/subconscious/CloudBrain.js.map +1 -0
  143. package/dist/cjs/subconscious/ProjectIdentity.d.ts +9 -0
  144. package/dist/cjs/subconscious/ProjectIdentity.d.ts.map +1 -0
  145. package/dist/cjs/subconscious/ProjectIdentity.js +63 -0
  146. package/dist/cjs/subconscious/ProjectIdentity.js.map +1 -0
  147. package/dist/cjs/subconscious/TeamBrain.d.ts +9 -3
  148. package/dist/cjs/subconscious/TeamBrain.d.ts.map +1 -1
  149. package/dist/cjs/subconscious/TeamBrain.js +39 -5
  150. package/dist/cjs/subconscious/TeamBrain.js.map +1 -1
  151. package/dist/cjs/subconscious/TheBrainV2.d.ts +7 -0
  152. package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -1
  153. package/dist/cjs/subconscious/TheBrainV2.js +25 -0
  154. package/dist/cjs/subconscious/TheBrainV2.js.map +1 -1
  155. package/dist/cjs/utils/ProLicense.d.ts.map +1 -1
  156. package/dist/cjs/utils/ProLicense.js +11 -3
  157. package/dist/cjs/utils/ProLicense.js.map +1 -1
  158. package/dist/cjs/utils/SessionCapture.d.ts +2 -0
  159. package/dist/cjs/utils/SessionCapture.d.ts.map +1 -1
  160. package/dist/cjs/utils/SessionCapture.js +5 -0
  161. package/dist/cjs/utils/SessionCapture.js.map +1 -1
  162. package/dist/cjs/utils/StopNudge.d.ts +8 -0
  163. package/dist/cjs/utils/StopNudge.d.ts.map +1 -0
  164. package/dist/cjs/utils/StopNudge.js +93 -0
  165. package/dist/cjs/utils/StopNudge.js.map +1 -0
  166. package/dist/esm/cli/hostHooks.d.ts +6 -0
  167. package/dist/esm/cli/hostHooks.d.ts.map +1 -1
  168. package/dist/esm/cli/hostHooks.js +12 -2
  169. package/dist/esm/cli/hostHooks.js.map +1 -1
  170. package/dist/esm/cloud/CloudBrainClient.d.ts +52 -0
  171. package/dist/esm/cloud/CloudBrainClient.d.ts.map +1 -0
  172. package/dist/esm/cloud/CloudBrainClient.js +153 -0
  173. package/dist/esm/cloud/CloudBrainClient.js.map +1 -0
  174. package/dist/esm/cloud/CloudConfig.d.ts +41 -0
  175. package/dist/esm/cloud/CloudConfig.d.ts.map +1 -0
  176. package/dist/esm/cloud/CloudConfig.js +118 -0
  177. package/dist/esm/cloud/CloudConfig.js.map +1 -0
  178. package/dist/esm/cloud/CloudEntitlement.d.ts +55 -0
  179. package/dist/esm/cloud/CloudEntitlement.d.ts.map +1 -0
  180. package/dist/esm/cloud/CloudEntitlement.js +159 -0
  181. package/dist/esm/cloud/CloudEntitlement.js.map +1 -0
  182. package/dist/esm/cloud/billing/stripeApi.d.ts +43 -0
  183. package/dist/esm/cloud/billing/stripeApi.d.ts.map +1 -0
  184. package/dist/esm/cloud/billing/stripeApi.js +103 -0
  185. package/dist/esm/cloud/billing/stripeApi.js.map +1 -0
  186. package/dist/esm/cloud/billing/stripeWebhook.d.ts +35 -0
  187. package/dist/esm/cloud/billing/stripeWebhook.d.ts.map +1 -0
  188. package/dist/esm/cloud/billing/stripeWebhook.js +176 -0
  189. package/dist/esm/cloud/billing/stripeWebhook.js.map +1 -0
  190. package/dist/esm/cloud/console/ConsoleStore.d.ts +111 -0
  191. package/dist/esm/cloud/console/ConsoleStore.d.ts.map +1 -0
  192. package/dist/esm/cloud/console/ConsoleStore.js +161 -0
  193. package/dist/esm/cloud/console/ConsoleStore.js.map +1 -0
  194. package/dist/esm/cloud/console/consoleRouter.d.ts +68 -0
  195. package/dist/esm/cloud/console/consoleRouter.d.ts.map +1 -0
  196. package/dist/esm/cloud/console/consoleRouter.js +252 -0
  197. package/dist/esm/cloud/console/consoleRouter.js.map +1 -0
  198. package/dist/esm/cloud/console/mailer.d.ts +22 -0
  199. package/dist/esm/cloud/console/mailer.d.ts.map +1 -0
  200. package/dist/esm/cloud/console/mailer.js +30 -0
  201. package/dist/esm/cloud/console/mailer.js.map +1 -0
  202. package/dist/esm/cloud/identity/PlanPolicy.d.ts +16 -1
  203. package/dist/esm/cloud/identity/PlanPolicy.d.ts.map +1 -1
  204. package/dist/esm/cloud/identity/PlanPolicy.js +46 -6
  205. package/dist/esm/cloud/identity/PlanPolicy.js.map +1 -1
  206. package/dist/esm/cloud/identity/RateLimiter.d.ts +21 -1
  207. package/dist/esm/cloud/identity/RateLimiter.d.ts.map +1 -1
  208. package/dist/esm/cloud/identity/RateLimiter.js +57 -2
  209. package/dist/esm/cloud/identity/RateLimiter.js.map +1 -1
  210. package/dist/esm/cloud/identity/TenantResolver.d.ts +4 -1
  211. package/dist/esm/cloud/identity/TenantResolver.d.ts.map +1 -1
  212. package/dist/esm/cloud/identity/TenantResolver.js +1 -1
  213. package/dist/esm/cloud/identity/TenantResolver.js.map +1 -1
  214. package/dist/esm/cloud/identity/authenticateV2.d.ts.map +1 -1
  215. package/dist/esm/cloud/identity/authenticateV2.js +7 -4
  216. package/dist/esm/cloud/identity/authenticateV2.js.map +1 -1
  217. package/dist/esm/cloud/identity/identityStore.d.ts +85 -10
  218. package/dist/esm/cloud/identity/identityStore.d.ts.map +1 -1
  219. package/dist/esm/cloud/identity/identityStore.js +180 -1
  220. package/dist/esm/cloud/identity/identityStore.js.map +1 -1
  221. package/dist/esm/cloud/metering/PostgresLedgerStore.d.ts +16 -0
  222. package/dist/esm/cloud/metering/PostgresLedgerStore.d.ts.map +1 -0
  223. package/dist/esm/cloud/metering/PostgresLedgerStore.js +40 -0
  224. package/dist/esm/cloud/metering/PostgresLedgerStore.js.map +1 -0
  225. package/dist/esm/cloud/metering/UsageLedger.d.ts +37 -0
  226. package/dist/esm/cloud/metering/UsageLedger.d.ts.map +1 -1
  227. package/dist/esm/cloud/metering/UsageLedger.js +78 -16
  228. package/dist/esm/cloud/metering/UsageLedger.js.map +1 -1
  229. package/dist/esm/cloud/metering/index.d.ts +1 -0
  230. package/dist/esm/cloud/metering/index.d.ts.map +1 -1
  231. package/dist/esm/cloud/metering/index.js +1 -0
  232. package/dist/esm/cloud/metering/index.js.map +1 -1
  233. package/dist/esm/cloud/store/FileBrainStore.d.ts +1 -0
  234. package/dist/esm/cloud/store/FileBrainStore.d.ts.map +1 -1
  235. package/dist/esm/cloud/store/FileBrainStore.js +3 -0
  236. package/dist/esm/cloud/store/FileBrainStore.js.map +1 -1
  237. package/dist/esm/cloud/store/PostgresBrainStore.d.ts +1 -0
  238. package/dist/esm/cloud/store/PostgresBrainStore.d.ts.map +1 -1
  239. package/dist/esm/cloud/store/PostgresBrainStore.js +4 -0
  240. package/dist/esm/cloud/store/PostgresBrainStore.js.map +1 -1
  241. package/dist/esm/cloud/v2/app.d.ts.map +1 -1
  242. package/dist/esm/cloud/v2/app.js +6 -0
  243. package/dist/esm/cloud/v2/app.js.map +1 -1
  244. package/dist/esm/cloud/v2/inputGuard.d.ts +23 -0
  245. package/dist/esm/cloud/v2/inputGuard.d.ts.map +1 -0
  246. package/dist/esm/cloud/v2/inputGuard.js +63 -0
  247. package/dist/esm/cloud/v2/inputGuard.js.map +1 -0
  248. package/dist/esm/cloud/v2/routes/admin.d.ts +24 -0
  249. package/dist/esm/cloud/v2/routes/admin.d.ts.map +1 -0
  250. package/dist/esm/cloud/v2/routes/admin.js +322 -0
  251. package/dist/esm/cloud/v2/routes/admin.js.map +1 -0
  252. package/dist/esm/cloud/v2/routes/entitlement.d.ts +13 -0
  253. package/dist/esm/cloud/v2/routes/entitlement.d.ts.map +1 -0
  254. package/dist/esm/cloud/v2/routes/entitlement.js +21 -0
  255. package/dist/esm/cloud/v2/routes/entitlement.js.map +1 -0
  256. package/dist/esm/cloud/v2/routes/index.d.ts +14 -1
  257. package/dist/esm/cloud/v2/routes/index.d.ts.map +1 -1
  258. package/dist/esm/cloud/v2/routes/index.js +37 -1
  259. package/dist/esm/cloud/v2/routes/index.js.map +1 -1
  260. package/dist/esm/cloud/v2/routes/memories.d.ts +21 -2
  261. package/dist/esm/cloud/v2/routes/memories.d.ts.map +1 -1
  262. package/dist/esm/cloud/v2/routes/memories.js +75 -0
  263. package/dist/esm/cloud/v2/routes/memories.js.map +1 -1
  264. package/dist/esm/cloud/v2/routes/recall.d.ts +1 -0
  265. package/dist/esm/cloud/v2/routes/recall.d.ts.map +1 -1
  266. package/dist/esm/cloud/v2/routes/recall.js +5 -1
  267. package/dist/esm/cloud/v2/routes/recall.js.map +1 -1
  268. package/dist/esm/cloud/v2/routes/tenant.d.ts +35 -0
  269. package/dist/esm/cloud/v2/routes/tenant.d.ts.map +1 -0
  270. package/dist/esm/cloud/v2/routes/tenant.js +58 -0
  271. package/dist/esm/cloud/v2/routes/tenant.js.map +1 -0
  272. package/dist/esm/cloud/v2/routes/usage.d.ts +1 -1
  273. package/dist/esm/cloud/v2/routes/usage.d.ts.map +1 -1
  274. package/dist/esm/cloud/v2/routes/verify.d.ts +1 -0
  275. package/dist/esm/cloud/v2/routes/verify.d.ts.map +1 -1
  276. package/dist/esm/cloud/v2/routes/verify.js +5 -1
  277. package/dist/esm/cloud/v2/routes/verify.js.map +1 -1
  278. package/dist/esm/cloud/v2/server.d.ts +9 -3
  279. package/dist/esm/cloud/v2/server.d.ts.map +1 -1
  280. package/dist/esm/cloud/v2/server.js +36 -3
  281. package/dist/esm/cloud/v2/server.js.map +1 -1
  282. package/dist/esm/cloud/v2/usageRecorder.d.ts +19 -0
  283. package/dist/esm/cloud/v2/usageRecorder.d.ts.map +1 -0
  284. package/dist/esm/cloud/v2/usageRecorder.js +37 -0
  285. package/dist/esm/cloud/v2/usageRecorder.js.map +1 -0
  286. package/dist/esm/contracts/api-v2.types.d.ts +90 -2
  287. package/dist/esm/contracts/api-v2.types.d.ts.map +1 -1
  288. package/dist/esm/contracts/store.d.ts +2 -0
  289. package/dist/esm/contracts/store.d.ts.map +1 -1
  290. package/dist/esm/mcp/index.js +3 -0
  291. package/dist/esm/mcp/index.js.map +1 -1
  292. package/dist/esm/mcp/tools/memory.d.ts.map +1 -1
  293. package/dist/esm/mcp/tools/memory.js +104 -11
  294. package/dist/esm/mcp/tools/memory.js.map +1 -1
  295. package/dist/esm/mcp/tools.d.ts.map +1 -1
  296. package/dist/esm/mcp/tools.js.map +1 -1
  297. package/dist/esm/proxy/KeyManager.d.ts.map +1 -1
  298. package/dist/esm/proxy/KeyManager.js +5 -0
  299. package/dist/esm/proxy/KeyManager.js.map +1 -1
  300. package/dist/esm/subconscious/CloudBrain.d.ts +77 -0
  301. package/dist/esm/subconscious/CloudBrain.d.ts.map +1 -0
  302. package/dist/esm/subconscious/CloudBrain.js +330 -0
  303. package/dist/esm/subconscious/CloudBrain.js.map +1 -0
  304. package/dist/esm/subconscious/ProjectIdentity.d.ts +9 -0
  305. package/dist/esm/subconscious/ProjectIdentity.d.ts.map +1 -0
  306. package/dist/esm/subconscious/ProjectIdentity.js +56 -0
  307. package/dist/esm/subconscious/ProjectIdentity.js.map +1 -0
  308. package/dist/esm/subconscious/TeamBrain.d.ts +9 -3
  309. package/dist/esm/subconscious/TeamBrain.d.ts.map +1 -1
  310. package/dist/esm/subconscious/TeamBrain.js +39 -7
  311. package/dist/esm/subconscious/TeamBrain.js.map +1 -1
  312. package/dist/esm/subconscious/TheBrainV2.d.ts +7 -0
  313. package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -1
  314. package/dist/esm/subconscious/TheBrainV2.js +25 -0
  315. package/dist/esm/subconscious/TheBrainV2.js.map +1 -1
  316. package/dist/esm/utils/ProLicense.d.ts.map +1 -1
  317. package/dist/esm/utils/ProLicense.js +11 -3
  318. package/dist/esm/utils/ProLicense.js.map +1 -1
  319. package/dist/esm/utils/SessionCapture.d.ts +2 -0
  320. package/dist/esm/utils/SessionCapture.d.ts.map +1 -1
  321. package/dist/esm/utils/SessionCapture.js +5 -0
  322. package/dist/esm/utils/SessionCapture.js.map +1 -1
  323. package/dist/esm/utils/StopNudge.d.ts +8 -0
  324. package/dist/esm/utils/StopNudge.d.ts.map +1 -0
  325. package/dist/esm/utils/StopNudge.js +86 -0
  326. package/dist/esm/utils/StopNudge.js.map +1 -0
  327. package/lemma-proxy.cjs +5 -0
  328. package/package.json +2 -1
  329. package/sdks/crewai/dist/ts/src/client.d.ts +5 -1
  330. package/sdks/crewai/dist/ts/src/client.js +8 -0
  331. package/sdks/crewai/dist/ts/src/types.d.ts +32 -1
@@ -1,10 +1,12 @@
1
- export function rateLimitErrorBody(decision, retryAfterSeconds, upgradeUrl) {
1
+ export function rateLimitErrorBody(decision, retryAfterSeconds, upgradeUrl, window = 'day') {
2
+ const scope = window === 'month' ? 'requests this month' : 'requests in the current window';
2
3
  return {
3
4
  error: {
4
5
  code: 'rate_limited',
5
6
  status: 429,
6
- message: `rate limit exceeded: ${decision.used}/${decision.limit} requests in the current window. ` +
7
+ message: `rate limit exceeded: ${decision.used}/${decision.limit} ${scope}. ` +
7
8
  `Back off and retry after ${retryAfterSeconds}s, or upgrade at ${upgradeUrl}.`,
9
+ window,
8
10
  limit: decision.limit,
9
11
  used: decision.used,
10
12
  remaining: decision.remaining,
@@ -14,10 +16,21 @@ export function rateLimitErrorBody(decision, retryAfterSeconds, upgradeUrl) {
14
16
  },
15
17
  };
16
18
  }
19
+ /** Bucket id of the calendar month (UTC) that contains `now`, e.g. `m:2026-10`. Text, so it shares the daily buckets' table without clashing. */
20
+ export function monthBucket(now) {
21
+ const d = new Date(now);
22
+ return `m:${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, '0')}`;
23
+ }
24
+ /** First instant (epoch ms) of the UTC month after the one containing `now`. */
25
+ export function nextMonthStart(now) {
26
+ const d = new Date(now);
27
+ return Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 1);
28
+ }
17
29
  /** In-process fixed-window limiter. Suitable for single-instance dev and tests. */
18
30
  export class InMemoryRateLimiter {
19
31
  constructor() {
20
32
  this.buckets = new Map();
33
+ this.months = new Map();
21
34
  }
22
35
  async consume(tenantId, limit, windowMs, now = Date.now()) {
23
36
  const bucket = Math.floor(now / windowMs);
@@ -42,6 +55,24 @@ export class InMemoryRateLimiter {
42
55
  resetAt,
43
56
  };
44
57
  }
58
+ async peek(tenantId, windowMs, now = Date.now()) {
59
+ return this.buckets.get(`${tenantId}:${Math.floor(now / windowMs)}`)?.count ?? 0;
60
+ }
61
+ async consumeMonthly(tenantId, limit, now = Date.now()) {
62
+ const bucket = monthBucket(now);
63
+ // Keep only the current month, as the daily map does: no background timers.
64
+ for (const k of this.months.keys()) {
65
+ if (!k.endsWith(`:${bucket}`))
66
+ this.months.delete(k);
67
+ }
68
+ const key = `${tenantId}:${bucket}`;
69
+ const used = (this.months.get(key) ?? 0) + 1;
70
+ this.months.set(key, used);
71
+ return { allowed: used <= limit, used, limit, remaining: Math.max(0, limit - used), resetAt: nextMonthStart(now) };
72
+ }
73
+ async peekMonthly(tenantId, now = Date.now()) {
74
+ return this.months.get(`${tenantId}:${monthBucket(now)}`) ?? 0;
75
+ }
45
76
  }
46
77
  /** Postgres-backed fixed-window limiter, atomic via a single upsert. */
47
78
  export class PostgresRateLimiter {
@@ -65,5 +96,29 @@ export class PostgresRateLimiter {
65
96
  resetAt: (bucket + 1) * windowMs,
66
97
  };
67
98
  }
99
+ async peek(tenantId, windowMs, now = Date.now()) {
100
+ const { rows } = await this.pool.query('SELECT request_count FROM tenant_rate_limits WHERE tenant_id = $1 AND bucket = $2', [
101
+ tenantId,
102
+ String(Math.floor(now / windowMs)),
103
+ ]);
104
+ return Number(rows[0]?.request_count ?? 0);
105
+ }
106
+ async consumeMonthly(tenantId, limit, now = Date.now()) {
107
+ const { rows } = await this.pool.query(`INSERT INTO tenant_rate_limits (tenant_id, bucket, request_count)
108
+ VALUES ($1, $2, 1)
109
+ ON CONFLICT (tenant_id, bucket) DO UPDATE
110
+ SET request_count = tenant_rate_limits.request_count + 1,
111
+ updated_at = CURRENT_TIMESTAMP
112
+ RETURNING request_count`, [tenantId, monthBucket(now)]);
113
+ const used = Number(rows[0]?.request_count ?? 1);
114
+ return { allowed: used <= limit, used, limit, remaining: Math.max(0, limit - used), resetAt: nextMonthStart(now) };
115
+ }
116
+ async peekMonthly(tenantId, now = Date.now()) {
117
+ const { rows } = await this.pool.query('SELECT request_count FROM tenant_rate_limits WHERE tenant_id = $1 AND bucket = $2', [
118
+ tenantId,
119
+ monthBucket(now),
120
+ ]);
121
+ return Number(rows[0]?.request_count ?? 0);
122
+ }
68
123
  }
69
124
  //# sourceMappingURL=RateLimiter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../../../src/cloud/identity/RateLimiter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../../../src/cloud/identity/RateLimiter.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,11 @@
1
1
  import type { IdentityStore } from './identityStore.js';
2
+ import type { PlanId } from './PlanPolicy.js';
2
3
  export interface Tenant {
3
4
  id: string;
4
- plan: 'free' | 'pro' | 'scale';
5
+ plan: PlanId;
5
6
  keyId: string;
7
+ /** Human label of the presented key (e.g. "dev-a"); recorded as the memory's author. */
8
+ keyName?: string;
6
9
  }
7
10
  export declare class TenantResolver {
8
11
  private readonly store;
@@ -1 +1 @@
1
- {"version":3,"file":"TenantResolver.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,cAAc;IAGb,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,QAAQ,CAAC,IAAI,OAAO;gBAES,KAAK,EAAE,aAAa;IAEjD;;;;OAIG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAY3D;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"TenantResolver.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAc;IAGb,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,QAAQ,CAAC,IAAI,OAAO;gBAES,KAAK,EAAE,aAAa;IAEjD;;;;OAIG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAY3D;AAED,eAAe,cAAc,CAAC"}
@@ -29,7 +29,7 @@ export class TenantResolver {
29
29
  return null;
30
30
  if (record.expiresAt !== null && Date.now() > record.expiresAt)
31
31
  return null;
32
- return { id: record.tenantId, plan: record.plan, keyId: record.id };
32
+ return { id: record.tenantId, plan: record.plan, keyId: record.id, keyName: record.name };
33
33
  }
34
34
  }
35
35
  export default TenantResolver;
@@ -1 +1 @@
1
- {"version":3,"file":"TenantResolver.js","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AASvD,MAAM,OAAO,cAAc;IAGzB,YAA6B,KAAoB;QAApB,UAAK,GAAL,KAAK,CAAe;QAFxC,SAAI,GAAG,GAAG,CAAC;IAEgC,CAAC;IAErD;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,WAAmB;QAC/B,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;QAE/C,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAChC,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5E,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;IACtE,CAAC;CACF;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"TenantResolver.js","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAYvD,MAAM,OAAO,cAAc;IAGzB,YAA6B,KAAoB;QAApB,UAAK,GAAL,KAAK,CAAe;QAFxC,SAAI,GAAG,GAAG,CAAC;IAEgC,CAAC;IAErD;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,WAAmB;QAC/B,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;QAE/C,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAChC,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5E,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAC5F,CAAC;CACF;AAED,eAAe,cAAc,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"authenticateV2.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,gEAAgE;YAChE,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB;KACF;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,oEAAoE;AACpE,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAgBhE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CA0CvE;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAChC,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"authenticateV2.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,gEAAgE;YAChE,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB;KACF;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,oEAAoE;AACpE,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAgBhE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CA6CvE;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAChC,eAAe,cAAc,CAAC"}
@@ -36,16 +36,19 @@ export function authenticateV2(deps) {
36
36
  return;
37
37
  }
38
38
  if (deps.rateLimiter) {
39
- const limit = policy.limitsFor(tenant.plan).dailyRequests;
40
- const decision = await deps.rateLimiter.consume(tenant.id, limit, windowMs, now());
39
+ const limits = policy.limitsFor(tenant.plan);
40
+ const daily = await deps.rateLimiter.consume(tenant.id, limits.dailyRequests, windowMs, now());
41
+ // A request the day already refused does not eat the month's allowance.
42
+ const decision = !daily.allowed || !deps.rateLimiter.consumeMonthly
43
+ ? daily
44
+ : await deps.rateLimiter.consumeMonthly(tenant.id, limits.monthlyRequests, now());
41
45
  if (!decision.allowed) {
42
46
  const retryAfter = Math.max(1, Math.ceil((decision.resetAt - now()) / 1000));
43
- const upgradeUrl = policy.limitsFor(tenant.plan).upgradeUrl;
44
47
  res
45
48
  .status(429)
46
49
  .set('Retry-After', String(retryAfter))
47
50
  .set('WWW-Authenticate', 'Bearer')
48
- .json(rateLimitErrorBody(decision, retryAfter, upgradeUrl));
51
+ .json(rateLimitErrorBody(decision, retryAfter, limits.upgradeUrl, decision === daily ? 'day' : 'month'));
49
52
  return;
50
53
  }
51
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"authenticateV2.js","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authenticateV2.js","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,3 @@
1
- /**
2
- * Lemma API v2 — identity store (Lane D)
3
- *
4
- * Persistence behind TenantResolver. Keys are stored as SHA-256 hashes only:
5
- * `key_hash` is the sole column that ever touches key material, and every write
6
- * is a parameterized insert that receives the hash, never the plaintext value.
7
- *
8
- * `InMemoryIdentityStore` powers unit tests and local/dev defaults.
9
- * `PostgresIdentityStore` is the production implementation over `pg`.
10
- */
11
1
  import type { Pool } from 'pg';
12
2
  import type { KeyPrefix } from './ApiKey.js';
13
3
  import type { PlanId } from './PlanPolicy.js';
@@ -30,6 +20,45 @@ export interface KeyRecord {
30
20
  expiresAt: number | null;
31
21
  revokedAt: number | null;
32
22
  }
23
+ /** What Stripe last told us about the tenant's subscription. Display and webhook bookkeeping only: quota code reads `plan`. */
24
+ export interface TenantBilling {
25
+ customerId: string | null;
26
+ subscriptionId: string | null;
27
+ /** Stripe's subscription status verbatim (active, past_due, canceled, ...). */
28
+ status: string | null;
29
+ /** Epoch ms of the end of the paid period: the next charge, or the last day of service when cancelling. */
30
+ currentPeriodEnd: number | null;
31
+ /** Epoch ms of the first failed payment of the current late streak; null while paid up. */
32
+ pastDueSince: number | null;
33
+ /** Epoch ms `created` of the last Stripe event applied; older events are dropped (delivery is unordered). */
34
+ eventAt: number | null;
35
+ }
36
+ export declare const NO_BILLING: Readonly<TenantBilling>;
37
+ export interface TenantRecord {
38
+ id: string;
39
+ name: string;
40
+ plan: PlanId;
41
+ createdAt: number;
42
+ billing: TenantBilling;
43
+ }
44
+ /** Outcome of applying a Stripe event to a tenant. */
45
+ export type BillingApplyResult = {
46
+ ok: true;
47
+ tenant: TenantRecord;
48
+ } | {
49
+ ok: false;
50
+ reason: 'no_tenant' | 'stale';
51
+ };
52
+ /** Outcome of an atomic "issue a key if the tenant still has a free seat". */
53
+ export type SeatedKeyResult = {
54
+ ok: true;
55
+ key: KeyRecord;
56
+ } | {
57
+ ok: false;
58
+ reason: 'no_tenant' | 'seats_full' | 'duplicate_name';
59
+ seats: number;
60
+ used: number;
61
+ };
33
62
  export interface IdentityStore {
34
63
  /** Look up a key by its hash. The ONLY read path — plaintext never enters a query. */
35
64
  findKeyByHash(hash: string): Promise<KeyRecord | null>;
@@ -37,12 +66,47 @@ export interface IdentityStore {
37
66
  createKey(input: NewKeyInput): Promise<KeyRecord>;
38
67
  /** Soft-revoke: the key dies on the NEXT lookup. No 24h cache can survive this. */
39
68
  revokeKey(keyId: string): Promise<boolean>;
69
+ /** Create a tenant; resolves null when the id is already taken. */
70
+ createTenant(input: {
71
+ id: string;
72
+ name: string;
73
+ plan: PlanId;
74
+ }): Promise<TenantRecord | null>;
75
+ getTenant(id: string): Promise<TenantRecord | null>;
76
+ setTenantPlan(id: string, plan: PlanId): Promise<TenantRecord | null>;
77
+ findTenantByStripeCustomer(customerId: string): Promise<TenantRecord | null>;
78
+ /**
79
+ * Write the plan and the full billing state in one statement, unless a NEWER Stripe event was
80
+ * already applied (`billing.eventAt` older than the stored one): then nothing changes and the
81
+ * result says `stale`. The caller passes the complete state, so a field is cleared by sending null.
82
+ */
83
+ applyBilling(id: string, plan: PlanId, billing: TenantBilling): Promise<BillingApplyResult>;
84
+ /** Every key the tenant ever had, newest first (hashes are never returned). */
85
+ listKeys(tenantId: string): Promise<KeyRecord[]>;
86
+ /**
87
+ * Issue a key only if the tenant has a free seat (active, unexpired keys < `seats`) and
88
+ * no active key already carries `input.name`. The check and the insert are atomic: two
89
+ * concurrent calls can never take the last seat twice.
90
+ */
91
+ createKeyWithinSeats(input: NewKeyInput, seats: number): Promise<SeatedKeyResult>;
40
92
  }
41
93
  /** In-memory store. Records carry the hash only — same invariant as Postgres. */
42
94
  export declare class InMemoryIdentityStore implements IdentityStore {
43
95
  readonly records: Map<string, KeyRecord>;
44
96
  findKeyByHash(hash: string): Promise<KeyRecord | null>;
45
97
  createKey(input: NewKeyInput): Promise<KeyRecord>;
98
+ readonly tenants: Map<string, TenantRecord>;
99
+ createTenant(input: {
100
+ id: string;
101
+ name: string;
102
+ plan: PlanId;
103
+ }): Promise<TenantRecord | null>;
104
+ getTenant(id: string): Promise<TenantRecord | null>;
105
+ setTenantPlan(id: string, plan: PlanId): Promise<TenantRecord | null>;
106
+ findTenantByStripeCustomer(customerId: string): Promise<TenantRecord | null>;
107
+ applyBilling(id: string, plan: PlanId, billing: TenantBilling): Promise<BillingApplyResult>;
108
+ listKeys(tenantId: string): Promise<KeyRecord[]>;
109
+ createKeyWithinSeats(input: NewKeyInput, seats: number): Promise<SeatedKeyResult>;
46
110
  revokeKey(keyId: string): Promise<boolean>;
47
111
  }
48
112
  /** Production store. All queries parameterized; key material appears only as hashed params. */
@@ -51,6 +115,17 @@ export declare class PostgresIdentityStore implements IdentityStore {
51
115
  constructor(pool: Pool);
52
116
  findKeyByHash(hash: string): Promise<KeyRecord | null>;
53
117
  createKey(input: NewKeyInput): Promise<KeyRecord>;
118
+ createTenant(input: {
119
+ id: string;
120
+ name: string;
121
+ plan: PlanId;
122
+ }): Promise<TenantRecord | null>;
123
+ getTenant(id: string): Promise<TenantRecord | null>;
124
+ setTenantPlan(id: string, plan: PlanId): Promise<TenantRecord | null>;
125
+ findTenantByStripeCustomer(customerId: string): Promise<TenantRecord | null>;
126
+ applyBilling(id: string, plan: PlanId, b: TenantBilling): Promise<BillingApplyResult>;
127
+ listKeys(tenantId: string): Promise<KeyRecord[]>;
128
+ createKeyWithinSeats(input: NewKeyInput, seats: number): Promise<SeatedKeyResult>;
54
129
  revokeKey(keyId: string): Promise<boolean>;
55
130
  }
56
131
  //# sourceMappingURL=identityStore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityStore.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/identityStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACvD,sFAAsF;IACtF,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,mFAAmF;IACnF,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5C;AAED,iFAAiF;AACjF,qBAAa,qBAAsB,YAAW,aAAa;IACzD,QAAQ,CAAC,OAAO,yBAAgC;IAE1C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAItD,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC;IAgBjD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAWjD;AAED,+FAA+F;AAC/F,qBAAa,qBAAsB,YAAW,aAAa;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;IAEjC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAwBtD,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC;IA6BjD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CASjD"}
1
+ {"version":3,"file":"identityStore.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/identityStore.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,37 @@
1
+ /**
2
+ * Lemma API v2 — identity store (Lane D)
3
+ *
4
+ * Persistence behind TenantResolver. Keys are stored as SHA-256 hashes only:
5
+ * `key_hash` is the sole column that ever touches key material, and every write
6
+ * is a parameterized insert that receives the hash, never the plaintext value.
7
+ *
8
+ * `InMemoryIdentityStore` powers unit tests and local/dev defaults.
9
+ * `PostgresIdentityStore` is the production implementation over `pg`.
10
+ */
11
+ import crypto from 'crypto';
12
+ export const NO_BILLING = Object.freeze({
13
+ customerId: null,
14
+ subscriptionId: null,
15
+ status: null,
16
+ currentPeriodEnd: null,
17
+ pastDueSince: null,
18
+ eventAt: null,
19
+ });
20
+ const isLive = (r, now) => r.active && (r.expiresAt === null || r.expiresAt > now);
1
21
  /** In-memory store. Records carry the hash only — same invariant as Postgres. */
2
22
  export class InMemoryIdentityStore {
3
23
  constructor() {
4
24
  this.records = new Map();
25
+ this.tenants = new Map();
5
26
  }
6
27
  async findKeyByHash(hash) {
7
28
  return this.records.get(hash) ?? null;
8
29
  }
9
30
  async createKey(input) {
10
31
  const record = {
11
- id: 'key_' + Math.random().toString(16).slice(2, 14),
32
+ // Always 12 hex chars, like the Postgres ids. Math.random().toString(16) drops trailing zeros,
33
+ // so slicing it yielded an 11-char id now and then: a key that /v2/admin could not address.
34
+ id: 'key_' + crypto.randomBytes(6).toString('hex'),
12
35
  tenantId: input.tenantId,
13
36
  name: input.name,
14
37
  plan: input.plan,
@@ -21,6 +44,56 @@ export class InMemoryIdentityStore {
21
44
  this.records.set(input.hash, record);
22
45
  return record;
23
46
  }
47
+ async createTenant(input) {
48
+ if (this.tenants.has(input.id))
49
+ return null;
50
+ const t = { id: input.id, name: input.name, plan: input.plan, createdAt: Date.now(), billing: { ...NO_BILLING } };
51
+ this.tenants.set(input.id, t);
52
+ return { ...t };
53
+ }
54
+ async getTenant(id) {
55
+ const t = this.tenants.get(id);
56
+ return t ? { ...t } : null;
57
+ }
58
+ async setTenantPlan(id, plan) {
59
+ const t = this.tenants.get(id);
60
+ if (!t)
61
+ return null;
62
+ t.plan = plan;
63
+ return { ...t };
64
+ }
65
+ async findTenantByStripeCustomer(customerId) {
66
+ for (const t of this.tenants.values())
67
+ if (t.billing.customerId === customerId)
68
+ return { ...t, billing: { ...t.billing } };
69
+ return null;
70
+ }
71
+ async applyBilling(id, plan, billing) {
72
+ const t = this.tenants.get(id);
73
+ if (!t)
74
+ return { ok: false, reason: 'no_tenant' };
75
+ if (t.billing.eventAt !== null && billing.eventAt !== null && billing.eventAt < t.billing.eventAt)
76
+ return { ok: false, reason: 'stale' };
77
+ t.plan = plan;
78
+ t.billing = { ...billing };
79
+ return { ok: true, tenant: { ...t, billing: { ...t.billing } } };
80
+ }
81
+ async listKeys(tenantId) {
82
+ return [...this.records.values()].filter((r) => r.tenantId === tenantId).sort((a, b) => b.createdAt - a.createdAt).map((r) => ({ ...r }));
83
+ }
84
+ async createKeyWithinSeats(input, seats) {
85
+ // Synchronous between the check and the insert, so it is atomic on a single event loop.
86
+ const tenant = this.tenants.get(input.tenantId);
87
+ if (!tenant)
88
+ return { ok: false, reason: 'no_tenant', seats, used: 0 };
89
+ const now = Date.now();
90
+ const live = [...this.records.values()].filter((r) => r.tenantId === input.tenantId && isLive(r, now));
91
+ if (live.some((r) => r.name === input.name))
92
+ return { ok: false, reason: 'duplicate_name', seats, used: live.length };
93
+ if (live.length >= seats)
94
+ return { ok: false, reason: 'seats_full', seats, used: live.length };
95
+ return { ok: true, key: await this.createKey({ ...input, plan: tenant.plan }) };
96
+ }
24
97
  async revokeKey(keyId) {
25
98
  let found = false;
26
99
  for (const record of this.records.values()) {
@@ -84,6 +157,82 @@ export class PostgresIdentityStore {
84
157
  revokedAt: null,
85
158
  };
86
159
  }
160
+ async createTenant(input) {
161
+ const { rows } = await this.pool.query(`INSERT INTO tenants (id, name, plan) VALUES ($1, $2, $3)
162
+ ON CONFLICT (id) DO NOTHING
163
+ RETURNING id, name, plan, created_at, stripe_customer_id, stripe_subscription_id, subscription_status, current_period_end, past_due_since, billing_event_at`, [input.id, input.name, input.plan]);
164
+ return rows.length ? toTenant(rows[0]) : null;
165
+ }
166
+ async getTenant(id) {
167
+ const { rows } = await this.pool.query(`SELECT id, name, plan, created_at, stripe_customer_id, stripe_subscription_id, subscription_status,
168
+ current_period_end, past_due_since, billing_event_at
169
+ FROM tenants WHERE id = $1`, [id]);
170
+ return rows.length ? toTenant(rows[0]) : null;
171
+ }
172
+ async setTenantPlan(id, plan) {
173
+ const { rows } = await this.pool.query(`UPDATE tenants SET plan = $2, updated_at = now() WHERE id = $1 RETURNING id, name, plan, created_at, stripe_customer_id, stripe_subscription_id, subscription_status, current_period_end, past_due_since, billing_event_at`, [id, plan]);
174
+ return rows.length ? toTenant(rows[0]) : null;
175
+ }
176
+ async findTenantByStripeCustomer(customerId) {
177
+ const { rows } = await this.pool.query(`SELECT id, name, plan, created_at, stripe_customer_id, stripe_subscription_id, subscription_status,
178
+ current_period_end, past_due_since, billing_event_at
179
+ FROM tenants WHERE stripe_customer_id = $1`, [customerId]);
180
+ return rows.length ? toTenant(rows[0]) : null;
181
+ }
182
+ async applyBilling(id, plan, b) {
183
+ const at = (ms) => (ms === null ? null : new Date(ms));
184
+ const { rows } = await this.pool.query(`UPDATE tenants
185
+ SET plan = $2, stripe_customer_id = $3, stripe_subscription_id = $4, subscription_status = $5,
186
+ current_period_end = $6, past_due_since = $7, billing_event_at = $8, updated_at = now()
187
+ WHERE id = $1 AND (billing_event_at IS NULL OR $8::timestamptz IS NULL OR billing_event_at <= $8::timestamptz)
188
+ RETURNING id, name, plan, created_at, stripe_customer_id, stripe_subscription_id, subscription_status, current_period_end, past_due_since, billing_event_at`, [id, plan, b.customerId, b.subscriptionId, b.status, at(b.currentPeriodEnd), at(b.pastDueSince), at(b.eventAt)]);
189
+ if (rows.length)
190
+ return { ok: true, tenant: toTenant(rows[0]) };
191
+ // No row updated: either the tenant does not exist or a newer event already won.
192
+ return { ok: false, reason: (await this.getTenant(id)) ? 'stale' : 'no_tenant' };
193
+ }
194
+ async listKeys(tenantId) {
195
+ const { rows } = await this.pool.query(`SELECT k.id, k.tenant_id, t.plan, k.name, k.prefix, k.active, k.created_at, k.expires_at, k.revoked_at
196
+ FROM api_keys k JOIN tenants t ON t.id = k.tenant_id
197
+ WHERE k.tenant_id = $1 ORDER BY k.created_at DESC, k.id`, [tenantId]);
198
+ return rows.map(toKey);
199
+ }
200
+ async createKeyWithinSeats(input, seats) {
201
+ const client = await this.pool.connect();
202
+ try {
203
+ await client.query('BEGIN');
204
+ // The tenant row is the lock: concurrent issuers for one tenant queue here, so the
205
+ // count below cannot go stale before the insert.
206
+ const t = await client.query('SELECT plan FROM tenants WHERE id = $1 FOR UPDATE', [input.tenantId]);
207
+ if (!t.rows.length) {
208
+ await client.query('ROLLBACK');
209
+ return { ok: false, reason: 'no_tenant', seats, used: 0 };
210
+ }
211
+ const live = await client.query(`SELECT name FROM api_keys
212
+ WHERE tenant_id = $1 AND active = TRUE AND (expires_at IS NULL OR expires_at > now())`, [input.tenantId]);
213
+ if (live.rows.some((r) => r.name === input.name)) {
214
+ await client.query('ROLLBACK');
215
+ return { ok: false, reason: 'duplicate_name', seats, used: live.rows.length };
216
+ }
217
+ if (live.rows.length >= seats) {
218
+ await client.query('ROLLBACK');
219
+ return { ok: false, reason: 'seats_full', seats, used: live.rows.length };
220
+ }
221
+ const plan = t.rows[0].plan;
222
+ const ins = await client.query(`INSERT INTO api_keys (id, tenant_id, name, key_hash, prefix, plan, active)
223
+ VALUES ($1, $2, $3, $4, $5, $6, TRUE)
224
+ RETURNING id, tenant_id, name, prefix, active, created_at, expires_at, revoked_at`, ['key_' + input.hash.slice(0, 12), input.tenantId, input.name, input.hash, input.prefix, plan]);
225
+ await client.query('COMMIT');
226
+ return { ok: true, key: toKey({ ...ins.rows[0], plan }) };
227
+ }
228
+ catch (err) {
229
+ await client.query('ROLLBACK').catch(() => undefined);
230
+ throw err;
231
+ }
232
+ finally {
233
+ client.release();
234
+ }
235
+ }
87
236
  async revokeKey(keyId) {
88
237
  const { rowCount } = await this.pool.query(`UPDATE api_keys
89
238
  SET active = FALSE, revoked_at = CURRENT_TIMESTAMP
@@ -91,4 +240,34 @@ export class PostgresIdentityStore {
91
240
  return (rowCount ?? 0) > 0;
92
241
  }
93
242
  }
243
+ function toTenant(r) {
244
+ const ms = (v) => (v ? new Date(v).getTime() : null);
245
+ return {
246
+ id: r.id,
247
+ name: r.name ?? '',
248
+ plan: r.plan,
249
+ createdAt: new Date(r.created_at).getTime(),
250
+ billing: {
251
+ customerId: r.stripe_customer_id ?? null,
252
+ subscriptionId: r.stripe_subscription_id ?? null,
253
+ status: r.subscription_status ?? null,
254
+ currentPeriodEnd: ms(r.current_period_end),
255
+ pastDueSince: ms(r.past_due_since),
256
+ eventAt: ms(r.billing_event_at),
257
+ },
258
+ };
259
+ }
260
+ function toKey(r) {
261
+ return {
262
+ id: r.id,
263
+ tenantId: r.tenant_id,
264
+ plan: r.plan,
265
+ name: r.name ?? '',
266
+ prefix: r.prefix,
267
+ active: r.active,
268
+ createdAt: new Date(r.created_at).getTime(),
269
+ expiresAt: r.expires_at ? new Date(r.expires_at).getTime() : null,
270
+ revokedAt: r.revoked_at ? new Date(r.revoked_at).getTime() : null,
271
+ };
272
+ }
94
273
  //# sourceMappingURL=identityStore.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityStore.js","sourceRoot":"","sources":["../../../../src/cloud/identity/identityStore.ts"],"names":[],"mappings":"AA4CA,iFAAiF;AACjF,MAAM,OAAO,qBAAqB;IAAlC;QACW,YAAO,GAAG,IAAI,GAAG,EAAqB,CAAC;IAiClD,CAAC;IA/BC,KAAK,CAAC,aAAa,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAkB;QAChC,MAAM,MAAM,GAAc;YACxB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YACpD,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;SAChB,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACrC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAa;QAC3B,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,IAAI,MAAM,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;gBACxB,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;gBACtB,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC9B,KAAK,GAAG,IAAI,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAED,+FAA+F;AAC/F,MAAM,OAAO,qBAAqB;IAChC,YAA6B,IAAU;QAAV,SAAI,GAAJ,IAAI,CAAM;IAAG,CAAC;IAE3C,KAAK,CAAC,aAAa,CAAC,IAAY;QAC9B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACpC;;;;8BAIwB,EACxB,CAAC,IAAI,CAAC,CACP,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,OAAO;YACL,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,QAAQ,EAAE,CAAC,CAAC,SAAS;YACrB,IAAI,EAAE,CAAC,CAAC,IAAc;YACtB,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;YAClB,MAAM,EAAE,CAAC,CAAC,MAAmB;YAC7B,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE;YAC3C,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI;YACjE,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI;SAClE,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAkB;QAChC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACpC;;8EAEwE,EACxE;YACE,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YAChC,KAAK,CAAC,QAAQ;YACd,KAAK,CAAC,IAAI;YACV,KAAK,CAAC,IAAI;YACV,KAAK,CAAC,MAAM;YACZ,KAAK,CAAC,IAAI;YACV,IAAI;SACL,CACF,CAAC;QACF,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,OAAO;YACL,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;YAClB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,CAAC,CAAC,MAAmB;YAC7B,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE;YAC3C,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI;YACjE,SAAS,EAAE,IAAI;SAChB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAa;QAC3B,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACxC;;wCAEkC,EAClC,CAAC,KAAK,CAAC,CACR,CAAC;QACF,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;CACF"}
1
+ {"version":3,"file":"identityStore.js","sourceRoot":"","sources":["../../../../src/cloud/identity/identityStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Lemma API v2 — durable usage ledger on Postgres (migration 003_usage.sql).
3
+ *
4
+ * Append-only by construction: the only write is INSERT. Reads are aggregated in SQL so
5
+ * /v2/usage costs one grouped query however many events a tenant has accumulated.
6
+ */
7
+ import type { Pool } from 'pg';
8
+ import type { AggregateRow, AppendOnlyStore, LedgerEvent, UsageQuery } from './UsageLedger.js';
9
+ export declare class PostgresLedgerStore implements AppendOnlyStore {
10
+ private readonly pool;
11
+ constructor(pool: Pool);
12
+ append(row: LedgerEvent): Promise<void>;
13
+ rows(): Promise<LedgerEvent[]>;
14
+ aggregate(query: UsageQuery): Promise<AggregateRow[]>;
15
+ }
16
+ //# sourceMappingURL=PostgresLedgerStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostgresLedgerStore.d.ts","sourceRoot":"","sources":["../../../../src/cloud/metering/PostgresLedgerStore.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE5F,qBAAa,mBAAoB,YAAW,eAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;IAEjC,MAAM,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvC,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAK9B,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAoB5D"}