@antasphere/chassis-server 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 (798) hide show
  1. package/LICENSE +82 -0
  2. package/dist/accounts/deletion.d.ts +163 -0
  3. package/dist/accounts/deletion.d.ts.map +1 -0
  4. package/dist/accounts/deletion.js +360 -0
  5. package/dist/accounts/deletion.js.map +1 -0
  6. package/dist/accounts/erasure-log.d.ts +66 -0
  7. package/dist/accounts/erasure-log.d.ts.map +1 -0
  8. package/dist/accounts/erasure-log.js +117 -0
  9. package/dist/accounts/erasure-log.js.map +1 -0
  10. package/dist/accounts/index.d.ts +6 -0
  11. package/dist/accounts/index.d.ts.map +1 -0
  12. package/dist/accounts/index.js +6 -0
  13. package/dist/accounts/index.js.map +1 -0
  14. package/dist/accounts/mint-refusal.d.ts +47 -0
  15. package/dist/accounts/mint-refusal.d.ts.map +1 -0
  16. package/dist/accounts/mint-refusal.js +59 -0
  17. package/dist/accounts/mint-refusal.js.map +1 -0
  18. package/dist/accounts/signup-duplicate.d.ts +14 -0
  19. package/dist/accounts/signup-duplicate.d.ts.map +1 -0
  20. package/dist/accounts/signup-duplicate.js +25 -0
  21. package/dist/accounts/signup-duplicate.js.map +1 -0
  22. package/dist/accounts/superadmin.d.ts +27 -0
  23. package/dist/accounts/superadmin.d.ts.map +1 -0
  24. package/dist/accounts/superadmin.js +46 -0
  25. package/dist/accounts/superadmin.js.map +1 -0
  26. package/dist/api/apikeys.d.ts +14 -0
  27. package/dist/api/apikeys.d.ts.map +1 -0
  28. package/dist/api/apikeys.js +124 -0
  29. package/dist/api/apikeys.js.map +1 -0
  30. package/dist/api/audit.d.ts +4 -0
  31. package/dist/api/audit.d.ts.map +1 -0
  32. package/dist/api/audit.js +75 -0
  33. package/dist/api/audit.js.map +1 -0
  34. package/dist/api/break-glass.d.ts +48 -0
  35. package/dist/api/break-glass.d.ts.map +1 -0
  36. package/dist/api/break-glass.js +217 -0
  37. package/dist/api/break-glass.js.map +1 -0
  38. package/dist/api/cli-auth.d.ts +84 -0
  39. package/dist/api/cli-auth.d.ts.map +1 -0
  40. package/dist/api/cli-auth.js +177 -0
  41. package/dist/api/cli-auth.js.map +1 -0
  42. package/dist/api/create-api.d.ts +123 -0
  43. package/dist/api/create-api.d.ts.map +1 -0
  44. package/dist/api/create-api.js +1165 -0
  45. package/dist/api/create-api.js.map +1 -0
  46. package/dist/api/demo-passes.d.ts +45 -0
  47. package/dist/api/demo-passes.d.ts.map +1 -0
  48. package/dist/api/demo-passes.js +143 -0
  49. package/dist/api/demo-passes.js.map +1 -0
  50. package/dist/api/errors.d.ts +5 -0
  51. package/dist/api/errors.d.ts.map +1 -0
  52. package/dist/api/errors.js +5 -0
  53. package/dist/api/errors.js.map +1 -0
  54. package/dist/api/export.d.ts +63 -0
  55. package/dist/api/export.d.ts.map +1 -0
  56. package/dist/api/export.js +393 -0
  57. package/dist/api/export.js.map +1 -0
  58. package/dist/api/files.d.ts +40 -0
  59. package/dist/api/files.d.ts.map +1 -0
  60. package/dist/api/files.js +150 -0
  61. package/dist/api/files.js.map +1 -0
  62. package/dist/api/index.d.ts +17 -0
  63. package/dist/api/index.d.ts.map +1 -0
  64. package/dist/api/index.js +17 -0
  65. package/dist/api/index.js.map +1 -0
  66. package/dist/api/invitations.d.ts +50 -0
  67. package/dist/api/invitations.d.ts.map +1 -0
  68. package/dist/api/invitations.js +313 -0
  69. package/dist/api/invitations.js.map +1 -0
  70. package/dist/api/members.d.ts +25 -0
  71. package/dist/api/members.d.ts.map +1 -0
  72. package/dist/api/members.js +522 -0
  73. package/dist/api/members.js.map +1 -0
  74. package/dist/api/onboarding.d.ts +26 -0
  75. package/dist/api/onboarding.d.ts.map +1 -0
  76. package/dist/api/onboarding.js +23 -0
  77. package/dist/api/onboarding.js.map +1 -0
  78. package/dist/api/openapi-doc.d.ts +21 -0
  79. package/dist/api/openapi-doc.d.ts.map +1 -0
  80. package/dist/api/openapi-doc.js +25 -0
  81. package/dist/api/openapi-doc.js.map +1 -0
  82. package/dist/api/projects.d.ts +24 -0
  83. package/dist/api/projects.d.ts.map +1 -0
  84. package/dist/api/projects.js +624 -0
  85. package/dist/api/projects.js.map +1 -0
  86. package/dist/api/scope-routes.d.ts +12 -0
  87. package/dist/api/scope-routes.d.ts.map +1 -0
  88. package/dist/api/scope-routes.js +2 -0
  89. package/dist/api/scope-routes.js.map +1 -0
  90. package/dist/api/sso-connect.d.ts +70 -0
  91. package/dist/api/sso-connect.d.ts.map +1 -0
  92. package/dist/api/sso-connect.js +164 -0
  93. package/dist/api/sso-connect.js.map +1 -0
  94. package/dist/api/sso-logout.d.ts +41 -0
  95. package/dist/api/sso-logout.d.ts.map +1 -0
  96. package/dist/api/sso-logout.js +34 -0
  97. package/dist/api/sso-logout.js.map +1 -0
  98. package/dist/api/teams.d.ts +43 -0
  99. package/dist/api/teams.d.ts.map +1 -0
  100. package/dist/api/teams.js +447 -0
  101. package/dist/api/teams.js.map +1 -0
  102. package/dist/api/workspaces.d.ts +114 -0
  103. package/dist/api/workspaces.d.ts.map +1 -0
  104. package/dist/api/workspaces.js +462 -0
  105. package/dist/api/workspaces.js.map +1 -0
  106. package/dist/apikeys/index.d.ts +3 -0
  107. package/dist/apikeys/index.d.ts.map +1 -0
  108. package/dist/apikeys/index.js +3 -0
  109. package/dist/apikeys/index.js.map +1 -0
  110. package/dist/apikeys/peppers.d.ts +53 -0
  111. package/dist/apikeys/peppers.d.ts.map +1 -0
  112. package/dist/apikeys/peppers.js +97 -0
  113. package/dist/apikeys/peppers.js.map +1 -0
  114. package/dist/apikeys/service.d.ts +56 -0
  115. package/dist/apikeys/service.d.ts.map +1 -0
  116. package/dist/apikeys/service.js +196 -0
  117. package/dist/apikeys/service.js.map +1 -0
  118. package/dist/app.d.ts +65 -0
  119. package/dist/app.d.ts.map +1 -0
  120. package/dist/app.js +142 -0
  121. package/dist/app.js.map +1 -0
  122. package/dist/audit/filters.d.ts +38 -0
  123. package/dist/audit/filters.d.ts.map +1 -0
  124. package/dist/audit/filters.js +97 -0
  125. package/dist/audit/filters.js.map +1 -0
  126. package/dist/audit/index.d.ts +3 -0
  127. package/dist/audit/index.d.ts.map +1 -0
  128. package/dist/audit/index.js +3 -0
  129. package/dist/audit/index.js.map +1 -0
  130. package/dist/audit/service.d.ts +65 -0
  131. package/dist/audit/service.d.ts.map +1 -0
  132. package/dist/audit/service.js +103 -0
  133. package/dist/audit/service.js.map +1 -0
  134. package/dist/boot.d.ts +8 -0
  135. package/dist/boot.d.ts.map +1 -0
  136. package/dist/boot.js +822 -0
  137. package/dist/boot.js.map +1 -0
  138. package/dist/constant-time.d.ts +3 -0
  139. package/dist/constant-time.d.ts.map +1 -0
  140. package/dist/constant-time.js +10 -0
  141. package/dist/constant-time.js.map +1 -0
  142. package/dist/email/driver.d.ts +16 -0
  143. package/dist/email/driver.d.ts.map +1 -0
  144. package/dist/email/driver.js +136 -0
  145. package/dist/email/driver.js.map +1 -0
  146. package/dist/email/index.d.ts +4 -0
  147. package/dist/email/index.d.ts.map +1 -0
  148. package/dist/email/index.js +4 -0
  149. package/dist/email/index.js.map +1 -0
  150. package/dist/email/shell.d.ts +72 -0
  151. package/dist/email/shell.d.ts.map +1 -0
  152. package/dist/email/shell.js +146 -0
  153. package/dist/email/shell.js.map +1 -0
  154. package/dist/email/templates.d.ts +83 -0
  155. package/dist/email/templates.d.ts.map +1 -0
  156. package/dist/email/templates.js +96 -0
  157. package/dist/email/templates.js.map +1 -0
  158. package/dist/entitlements/check.d.ts +140 -0
  159. package/dist/entitlements/check.d.ts.map +1 -0
  160. package/dist/entitlements/check.js +276 -0
  161. package/dist/entitlements/check.js.map +1 -0
  162. package/dist/entitlements/clock-skew.d.ts +27 -0
  163. package/dist/entitlements/clock-skew.d.ts.map +1 -0
  164. package/dist/entitlements/clock-skew.js +58 -0
  165. package/dist/entitlements/clock-skew.js.map +1 -0
  166. package/dist/entitlements/gate.d.ts +113 -0
  167. package/dist/entitlements/gate.d.ts.map +1 -0
  168. package/dist/entitlements/gate.js +430 -0
  169. package/dist/entitlements/gate.js.map +1 -0
  170. package/dist/entitlements/hub-machine-token.d.ts +83 -0
  171. package/dist/entitlements/hub-machine-token.d.ts.map +1 -0
  172. package/dist/entitlements/hub-machine-token.js +175 -0
  173. package/dist/entitlements/hub-machine-token.js.map +1 -0
  174. package/dist/entitlements/hub-subject.d.ts +32 -0
  175. package/dist/entitlements/hub-subject.d.ts.map +1 -0
  176. package/dist/entitlements/hub-subject.js +68 -0
  177. package/dist/entitlements/hub-subject.js.map +1 -0
  178. package/dist/entitlements/index.d.ts +9 -0
  179. package/dist/entitlements/index.d.ts.map +1 -0
  180. package/dist/entitlements/index.js +9 -0
  181. package/dist/entitlements/index.js.map +1 -0
  182. package/dist/entitlements/poster.d.ts +81 -0
  183. package/dist/entitlements/poster.d.ts.map +1 -0
  184. package/dist/entitlements/poster.js +169 -0
  185. package/dist/entitlements/poster.js.map +1 -0
  186. package/dist/entitlements/profiles.d.ts +121 -0
  187. package/dist/entitlements/profiles.d.ts.map +1 -0
  188. package/dist/entitlements/profiles.js +212 -0
  189. package/dist/entitlements/profiles.js.map +1 -0
  190. package/dist/entitlements/slot.d.ts +33 -0
  191. package/dist/entitlements/slot.d.ts.map +1 -0
  192. package/dist/entitlements/slot.js +75 -0
  193. package/dist/entitlements/slot.js.map +1 -0
  194. package/dist/env.d.ts +293 -0
  195. package/dist/env.d.ts.map +1 -0
  196. package/dist/env.js +383 -0
  197. package/dist/env.js.map +1 -0
  198. package/dist/files/http.d.ts +23 -0
  199. package/dist/files/http.d.ts.map +1 -0
  200. package/dist/files/http.js +66 -0
  201. package/dist/files/http.js.map +1 -0
  202. package/dist/files/index.d.ts +5 -0
  203. package/dist/files/index.d.ts.map +1 -0
  204. package/dist/files/index.js +5 -0
  205. package/dist/files/index.js.map +1 -0
  206. package/dist/files/serve.d.ts +43 -0
  207. package/dist/files/serve.d.ts.map +1 -0
  208. package/dist/files/serve.js +71 -0
  209. package/dist/files/serve.js.map +1 -0
  210. package/dist/files/service.d.ts +69 -0
  211. package/dist/files/service.d.ts.map +1 -0
  212. package/dist/files/service.js +188 -0
  213. package/dist/files/service.js.map +1 -0
  214. package/dist/files/spool.d.ts +21 -0
  215. package/dist/files/spool.d.ts.map +1 -0
  216. package/dist/files/spool.js +47 -0
  217. package/dist/files/spool.js.map +1 -0
  218. package/dist/identity/better-auth.d.ts +3927 -0
  219. package/dist/identity/better-auth.d.ts.map +1 -0
  220. package/dist/identity/better-auth.js +896 -0
  221. package/dist/identity/better-auth.js.map +1 -0
  222. package/dist/identity/demo-pass-plugin.d.ts +29 -0
  223. package/dist/identity/demo-pass-plugin.d.ts.map +1 -0
  224. package/dist/identity/demo-pass-plugin.js +88 -0
  225. package/dist/identity/demo-pass-plugin.js.map +1 -0
  226. package/dist/identity/demo-pass-rules.d.ts +84 -0
  227. package/dist/identity/demo-pass-rules.d.ts.map +1 -0
  228. package/dist/identity/demo-pass-rules.js +223 -0
  229. package/dist/identity/demo-pass-rules.js.map +1 -0
  230. package/dist/identity/demo-pass.d.ts +159 -0
  231. package/dist/identity/demo-pass.d.ts.map +1 -0
  232. package/dist/identity/demo-pass.js +319 -0
  233. package/dist/identity/demo-pass.js.map +1 -0
  234. package/dist/identity/hub-grant.d.ts +182 -0
  235. package/dist/identity/hub-grant.d.ts.map +1 -0
  236. package/dist/identity/hub-grant.js +594 -0
  237. package/dist/identity/hub-grant.js.map +1 -0
  238. package/dist/identity/hub-jwt.d.ts +22 -0
  239. package/dist/identity/hub-jwt.d.ts.map +1 -0
  240. package/dist/identity/hub-jwt.js +77 -0
  241. package/dist/identity/hub-jwt.js.map +1 -0
  242. package/dist/identity/hub-live-gate.d.ts +17 -0
  243. package/dist/identity/hub-live-gate.d.ts.map +1 -0
  244. package/dist/identity/hub-live-gate.js +146 -0
  245. package/dist/identity/hub-live-gate.js.map +1 -0
  246. package/dist/identity/hub-logout.d.ts +88 -0
  247. package/dist/identity/hub-logout.d.ts.map +1 -0
  248. package/dist/identity/hub-logout.js +158 -0
  249. package/dist/identity/hub-logout.js.map +1 -0
  250. package/dist/identity/hub-projection.d.ts +103 -0
  251. package/dist/identity/hub-projection.d.ts.map +1 -0
  252. package/dist/identity/hub-projection.js +130 -0
  253. package/dist/identity/hub-projection.js.map +1 -0
  254. package/dist/identity/hub-reconcile.d.ts +151 -0
  255. package/dist/identity/hub-reconcile.d.ts.map +1 -0
  256. package/dist/identity/hub-reconcile.js +400 -0
  257. package/dist/identity/hub-reconcile.js.map +1 -0
  258. package/dist/identity/hub-sso.d.ts +363 -0
  259. package/dist/identity/hub-sso.d.ts.map +1 -0
  260. package/dist/identity/hub-sso.js +536 -0
  261. package/dist/identity/hub-sso.js.map +1 -0
  262. package/dist/identity/hub-user-client.d.ts +222 -0
  263. package/dist/identity/hub-user-client.d.ts.map +1 -0
  264. package/dist/identity/hub-user-client.js +406 -0
  265. package/dist/identity/hub-user-client.js.map +1 -0
  266. package/dist/identity/index.d.ts +13 -0
  267. package/dist/identity/index.d.ts.map +1 -0
  268. package/dist/identity/index.js +13 -0
  269. package/dist/identity/index.js.map +1 -0
  270. package/dist/identity/oauth-jwt.d.ts +32 -0
  271. package/dist/identity/oauth-jwt.d.ts.map +1 -0
  272. package/dist/identity/oauth-jwt.js +122 -0
  273. package/dist/identity/oauth-jwt.js.map +1 -0
  274. package/dist/identity/resolve-membership.d.ts +28 -0
  275. package/dist/identity/resolve-membership.d.ts.map +1 -0
  276. package/dist/identity/resolve-membership.js +69 -0
  277. package/dist/identity/resolve-membership.js.map +1 -0
  278. package/dist/identity/signing-key.d.ts +49 -0
  279. package/dist/identity/signing-key.d.ts.map +1 -0
  280. package/dist/identity/signing-key.js +144 -0
  281. package/dist/identity/signing-key.js.map +1 -0
  282. package/dist/index.d.ts +21 -0
  283. package/dist/index.d.ts.map +1 -0
  284. package/dist/index.js +11 -0
  285. package/dist/index.js.map +1 -0
  286. package/dist/invitations/index.d.ts +2 -0
  287. package/dist/invitations/index.d.ts.map +1 -0
  288. package/dist/invitations/index.js +2 -0
  289. package/dist/invitations/index.js.map +1 -0
  290. package/dist/invitations/service.d.ts +36 -0
  291. package/dist/invitations/service.d.ts.map +1 -0
  292. package/dist/invitations/service.js +122 -0
  293. package/dist/invitations/service.js.map +1 -0
  294. package/dist/jobs/index.d.ts +3 -0
  295. package/dist/jobs/index.d.ts.map +1 -0
  296. package/dist/jobs/index.js +3 -0
  297. package/dist/jobs/index.js.map +1 -0
  298. package/dist/jobs/pgboss.d.ts +119 -0
  299. package/dist/jobs/pgboss.d.ts.map +1 -0
  300. package/dist/jobs/pgboss.js +521 -0
  301. package/dist/jobs/pgboss.js.map +1 -0
  302. package/dist/jobs/timers.d.ts +127 -0
  303. package/dist/jobs/timers.d.ts.map +1 -0
  304. package/dist/jobs/timers.js +228 -0
  305. package/dist/jobs/timers.js.map +1 -0
  306. package/dist/logger.d.ts +17 -0
  307. package/dist/logger.d.ts.map +1 -0
  308. package/dist/logger.js +64 -0
  309. package/dist/logger.js.map +1 -0
  310. package/dist/mcp/errors.d.ts +37 -0
  311. package/dist/mcp/errors.d.ts.map +1 -0
  312. package/dist/mcp/errors.js +77 -0
  313. package/dist/mcp/errors.js.map +1 -0
  314. package/dist/mcp/http.d.ts +35 -0
  315. package/dist/mcp/http.d.ts.map +1 -0
  316. package/dist/mcp/http.js +80 -0
  317. package/dist/mcp/http.js.map +1 -0
  318. package/dist/mcp/index.d.ts +8 -0
  319. package/dist/mcp/index.d.ts.map +1 -0
  320. package/dist/mcp/index.js +8 -0
  321. package/dist/mcp/index.js.map +1 -0
  322. package/dist/mcp/inputs.d.ts +19 -0
  323. package/dist/mcp/inputs.d.ts.map +1 -0
  324. package/dist/mcp/inputs.js +28 -0
  325. package/dist/mcp/inputs.js.map +1 -0
  326. package/dist/mcp/projects.d.ts +31 -0
  327. package/dist/mcp/projects.d.ts.map +1 -0
  328. package/dist/mcp/projects.js +315 -0
  329. package/dist/mcp/projects.js.map +1 -0
  330. package/dist/mcp/server.d.ts +52 -0
  331. package/dist/mcp/server.d.ts.map +1 -0
  332. package/dist/mcp/server.js +93 -0
  333. package/dist/mcp/server.js.map +1 -0
  334. package/dist/mcp/teams.d.ts +7 -0
  335. package/dist/mcp/teams.d.ts.map +1 -0
  336. package/dist/mcp/teams.js +62 -0
  337. package/dist/mcp/teams.js.map +1 -0
  338. package/dist/mcp/tool-kit.d.ts +67 -0
  339. package/dist/mcp/tool-kit.d.ts.map +1 -0
  340. package/dist/mcp/tool-kit.js +74 -0
  341. package/dist/mcp/tool-kit.js.map +1 -0
  342. package/dist/members/removal.d.ts +95 -0
  343. package/dist/members/removal.d.ts.map +1 -0
  344. package/dist/members/removal.js +143 -0
  345. package/dist/members/removal.js.map +1 -0
  346. package/dist/middleware/auth-body.d.ts +25 -0
  347. package/dist/middleware/auth-body.d.ts.map +1 -0
  348. package/dist/middleware/auth-body.js +55 -0
  349. package/dist/middleware/auth-body.js.map +1 -0
  350. package/dist/middleware/auth-context.d.ts +170 -0
  351. package/dist/middleware/auth-context.d.ts.map +1 -0
  352. package/dist/middleware/auth-context.js +251 -0
  353. package/dist/middleware/auth-context.js.map +1 -0
  354. package/dist/middleware/body-cap.d.ts +17 -0
  355. package/dist/middleware/body-cap.d.ts.map +1 -0
  356. package/dist/middleware/body-cap.js +31 -0
  357. package/dist/middleware/body-cap.js.map +1 -0
  358. package/dist/middleware/body-refusal.d.ts +20 -0
  359. package/dist/middleware/body-refusal.d.ts.map +1 -0
  360. package/dist/middleware/body-refusal.js +5 -0
  361. package/dist/middleware/body-refusal.js.map +1 -0
  362. package/dist/middleware/cross-site.d.ts +61 -0
  363. package/dist/middleware/cross-site.d.ts.map +1 -0
  364. package/dist/middleware/cross-site.js +59 -0
  365. package/dist/middleware/cross-site.js.map +1 -0
  366. package/dist/middleware/hub-managed.d.ts +45 -0
  367. package/dist/middleware/hub-managed.d.ts.map +1 -0
  368. package/dist/middleware/hub-managed.js +56 -0
  369. package/dist/middleware/hub-managed.js.map +1 -0
  370. package/dist/middleware/idempotency.d.ts +14 -0
  371. package/dist/middleware/idempotency.d.ts.map +1 -0
  372. package/dist/middleware/idempotency.js +222 -0
  373. package/dist/middleware/idempotency.js.map +1 -0
  374. package/dist/middleware/index.d.ts +12 -0
  375. package/dist/middleware/index.d.ts.map +1 -0
  376. package/dist/middleware/index.js +12 -0
  377. package/dist/middleware/index.js.map +1 -0
  378. package/dist/middleware/json-depth.d.ts +32 -0
  379. package/dist/middleware/json-depth.d.ts.map +1 -0
  380. package/dist/middleware/json-depth.js +80 -0
  381. package/dist/middleware/json-depth.js.map +1 -0
  382. package/dist/middleware/no-store.d.ts +21 -0
  383. package/dist/middleware/no-store.d.ts.map +1 -0
  384. package/dist/middleware/no-store.js +32 -0
  385. package/dist/middleware/no-store.js.map +1 -0
  386. package/dist/middleware/oauth-public.d.ts +16 -0
  387. package/dist/middleware/oauth-public.d.ts.map +1 -0
  388. package/dist/middleware/oauth-public.js +50 -0
  389. package/dist/middleware/oauth-public.js.map +1 -0
  390. package/dist/middleware/rate-limit.d.ts +182 -0
  391. package/dist/middleware/rate-limit.d.ts.map +1 -0
  392. package/dist/middleware/rate-limit.js +277 -0
  393. package/dist/middleware/rate-limit.js.map +1 -0
  394. package/dist/middleware/request-id.d.ts +10 -0
  395. package/dist/middleware/request-id.d.ts.map +1 -0
  396. package/dist/middleware/request-id.js +42 -0
  397. package/dist/middleware/request-id.js.map +1 -0
  398. package/dist/middleware/scopes.d.ts +33 -0
  399. package/dist/middleware/scopes.d.ts.map +1 -0
  400. package/dist/middleware/scopes.js +139 -0
  401. package/dist/middleware/scopes.js.map +1 -0
  402. package/dist/middleware/security-headers.d.ts +53 -0
  403. package/dist/middleware/security-headers.d.ts.map +1 -0
  404. package/dist/middleware/security-headers.js +96 -0
  405. package/dist/middleware/security-headers.js.map +1 -0
  406. package/dist/observability/index.d.ts +3 -0
  407. package/dist/observability/index.d.ts.map +1 -0
  408. package/dist/observability/index.js +3 -0
  409. package/dist/observability/index.js.map +1 -0
  410. package/dist/observability/metrics.d.ts +17 -0
  411. package/dist/observability/metrics.d.ts.map +1 -0
  412. package/dist/observability/metrics.js +82 -0
  413. package/dist/observability/metrics.js.map +1 -0
  414. package/dist/observability/otel.d.ts +20 -0
  415. package/dist/observability/otel.d.ts.map +1 -0
  416. package/dist/observability/otel.js +54 -0
  417. package/dist/observability/otel.js.map +1 -0
  418. package/dist/pagination.d.ts +57 -0
  419. package/dist/pagination.d.ts.map +1 -0
  420. package/dist/pagination.js +90 -0
  421. package/dist/pagination.js.map +1 -0
  422. package/dist/platform/edition.d.ts +57 -0
  423. package/dist/platform/edition.d.ts.map +1 -0
  424. package/dist/platform/edition.js +90 -0
  425. package/dist/platform/edition.js.map +1 -0
  426. package/dist/platform/entitlements.d.ts +26 -0
  427. package/dist/platform/entitlements.d.ts.map +1 -0
  428. package/dist/platform/entitlements.js +28 -0
  429. package/dist/platform/entitlements.js.map +1 -0
  430. package/dist/platform/events.d.ts +87 -0
  431. package/dist/platform/events.d.ts.map +1 -0
  432. package/dist/platform/events.js +32 -0
  433. package/dist/platform/events.js.map +1 -0
  434. package/dist/platform/index.d.ts +8 -0
  435. package/dist/platform/index.d.ts.map +1 -0
  436. package/dist/platform/index.js +8 -0
  437. package/dist/platform/index.js.map +1 -0
  438. package/dist/platform/local-identity.d.ts +39 -0
  439. package/dist/platform/local-identity.d.ts.map +1 -0
  440. package/dist/platform/local-identity.js +87 -0
  441. package/dist/platform/local-identity.js.map +1 -0
  442. package/dist/platform/registry.d.ts +23 -0
  443. package/dist/platform/registry.d.ts.map +1 -0
  444. package/dist/platform/registry.js +5 -0
  445. package/dist/platform/registry.js.map +1 -0
  446. package/dist/platform/usage.d.ts +11 -0
  447. package/dist/platform/usage.d.ts.map +1 -0
  448. package/dist/platform/usage.js +12 -0
  449. package/dist/platform/usage.js.map +1 -0
  450. package/dist/platform/workspaces.d.ts +25 -0
  451. package/dist/platform/workspaces.d.ts.map +1 -0
  452. package/dist/platform/workspaces.js +44 -0
  453. package/dist/platform/workspaces.js.map +1 -0
  454. package/dist/projects/access.d.ts +40 -0
  455. package/dist/projects/access.d.ts.map +1 -0
  456. package/dist/projects/access.js +133 -0
  457. package/dist/projects/access.js.map +1 -0
  458. package/dist/projects/index.d.ts +2 -0
  459. package/dist/projects/index.d.ts.map +1 -0
  460. package/dist/projects/index.js +2 -0
  461. package/dist/projects/index.js.map +1 -0
  462. package/dist/route-label.d.ts +23 -0
  463. package/dist/route-label.d.ts.map +1 -0
  464. package/dist/route-label.js +29 -0
  465. package/dist/route-label.js.map +1 -0
  466. package/dist/routes/health.d.ts +30 -0
  467. package/dist/routes/health.d.ts.map +1 -0
  468. package/dist/routes/health.js +54 -0
  469. package/dist/routes/health.js.map +1 -0
  470. package/dist/routes/index.d.ts +3 -0
  471. package/dist/routes/index.d.ts.map +1 -0
  472. package/dist/routes/index.js +3 -0
  473. package/dist/routes/index.js.map +1 -0
  474. package/dist/routes/wellknown.d.ts +11 -0
  475. package/dist/routes/wellknown.d.ts.map +1 -0
  476. package/dist/routes/wellknown.js +45 -0
  477. package/dist/routes/wellknown.js.map +1 -0
  478. package/dist/secret.d.ts +30 -0
  479. package/dist/secret.d.ts.map +1 -0
  480. package/dist/secret.js +97 -0
  481. package/dist/secret.js.map +1 -0
  482. package/dist/setup-transport.d.ts +23 -0
  483. package/dist/setup-transport.d.ts.map +1 -0
  484. package/dist/setup-transport.js +52 -0
  485. package/dist/setup-transport.js.map +1 -0
  486. package/dist/state.d.ts +21 -0
  487. package/dist/state.d.ts.map +1 -0
  488. package/dist/state.js +4 -0
  489. package/dist/state.js.map +1 -0
  490. package/dist/storage/driver.d.ts +38 -0
  491. package/dist/storage/driver.d.ts.map +1 -0
  492. package/dist/storage/driver.js +14 -0
  493. package/dist/storage/driver.js.map +1 -0
  494. package/dist/storage/factory.d.ts +4 -0
  495. package/dist/storage/factory.d.ts.map +1 -0
  496. package/dist/storage/factory.js +20 -0
  497. package/dist/storage/factory.js.map +1 -0
  498. package/dist/storage/index.d.ts +4 -0
  499. package/dist/storage/index.d.ts.map +1 -0
  500. package/dist/storage/index.js +4 -0
  501. package/dist/storage/index.js.map +1 -0
  502. package/dist/storage/local.d.ts +21 -0
  503. package/dist/storage/local.d.ts.map +1 -0
  504. package/dist/storage/local.js +88 -0
  505. package/dist/storage/local.js.map +1 -0
  506. package/dist/storage/s3.d.ts +29 -0
  507. package/dist/storage/s3.d.ts.map +1 -0
  508. package/dist/storage/s3.js +82 -0
  509. package/dist/storage/s3.js.map +1 -0
  510. package/dist/testing/fake-hub.d.ts +425 -0
  511. package/dist/testing/fake-hub.d.ts.map +1 -0
  512. package/dist/testing/fake-hub.js +1074 -0
  513. package/dist/testing/fake-hub.js.map +1 -0
  514. package/dist/testing/helpers.d.ts +124 -0
  515. package/dist/testing/helpers.d.ts.map +1 -0
  516. package/dist/testing/helpers.js +174 -0
  517. package/dist/testing/helpers.js.map +1 -0
  518. package/dist/testing/index.d.ts +12 -0
  519. package/dist/testing/index.d.ts.map +1 -0
  520. package/dist/testing/index.js +12 -0
  521. package/dist/testing/index.js.map +1 -0
  522. package/dist/testing/setup-origins.d.ts +21 -0
  523. package/dist/testing/setup-origins.d.ts.map +1 -0
  524. package/dist/testing/setup-origins.js +57 -0
  525. package/dist/testing/setup-origins.js.map +1 -0
  526. package/dist/testing/sso-helpers.d.ts +43 -0
  527. package/dist/testing/sso-helpers.d.ts.map +1 -0
  528. package/dist/testing/sso-helpers.js +159 -0
  529. package/dist/testing/sso-helpers.js.map +1 -0
  530. package/dist/tool-definition.d.ts +382 -0
  531. package/dist/tool-definition.d.ts.map +1 -0
  532. package/dist/tool-definition.js +46 -0
  533. package/dist/tool-definition.js.map +1 -0
  534. package/dist/util/index.d.ts +8 -0
  535. package/dist/util/index.d.ts.map +1 -0
  536. package/dist/util/index.js +8 -0
  537. package/dist/util/index.js.map +1 -0
  538. package/package.json +161 -0
  539. package/src/accounts/deletion.ts +389 -0
  540. package/src/accounts/erasure-log.ts +140 -0
  541. package/src/accounts/index.ts +5 -0
  542. package/src/accounts/mint-refusal.ts +67 -0
  543. package/src/accounts/signup-duplicate.ts +21 -0
  544. package/src/accounts/superadmin.ts +46 -0
  545. package/src/api/apikeys.ts +147 -0
  546. package/src/api/audit.ts +83 -0
  547. package/src/api/break-glass.ts +294 -0
  548. package/src/api/cli-auth.ts +308 -0
  549. package/src/api/create-api.ts +1403 -0
  550. package/src/api/demo-passes.ts +207 -0
  551. package/src/api/errors.ts +13 -0
  552. package/src/api/export.ts +482 -0
  553. package/src/api/files.ts +200 -0
  554. package/src/api/index.ts +29 -0
  555. package/src/api/invitations.ts +396 -0
  556. package/src/api/members.ts +617 -0
  557. package/src/api/onboarding.ts +50 -0
  558. package/src/api/openapi-doc.ts +34 -0
  559. package/src/api/projects.ts +788 -0
  560. package/src/api/scope-routes.ts +12 -0
  561. package/src/api/sso-connect.ts +246 -0
  562. package/src/api/sso-logout.ts +76 -0
  563. package/src/api/teams.ts +575 -0
  564. package/src/api/workspaces.ts +649 -0
  565. package/src/apikeys/index.ts +2 -0
  566. package/src/apikeys/peppers.ts +118 -0
  567. package/src/apikeys/service.ts +223 -0
  568. package/src/app.ts +228 -0
  569. package/src/audit/filters.ts +101 -0
  570. package/src/audit/index.ts +9 -0
  571. package/src/audit/service.ts +154 -0
  572. package/src/boot.ts +953 -0
  573. package/src/constant-time.ts +9 -0
  574. package/src/email/driver.ts +139 -0
  575. package/src/email/index.ts +26 -0
  576. package/src/email/shell.ts +201 -0
  577. package/src/email/templates.ts +184 -0
  578. package/src/entitlements/check.ts +435 -0
  579. package/src/entitlements/clock-skew.ts +58 -0
  580. package/src/entitlements/gate.ts +636 -0
  581. package/src/entitlements/hub-machine-token.ts +205 -0
  582. package/src/entitlements/hub-subject.ts +77 -0
  583. package/src/entitlements/index.ts +37 -0
  584. package/src/entitlements/poster.ts +265 -0
  585. package/src/entitlements/profiles.ts +303 -0
  586. package/src/entitlements/slot.ts +105 -0
  587. package/src/env.ts +456 -0
  588. package/src/files/http.ts +77 -0
  589. package/src/files/index.ts +4 -0
  590. package/src/files/serve.ts +115 -0
  591. package/src/files/service.ts +209 -0
  592. package/src/files/spool.ts +58 -0
  593. package/src/identity/better-auth.ts +1103 -0
  594. package/src/identity/demo-pass-plugin.ts +121 -0
  595. package/src/identity/demo-pass-rules.ts +229 -0
  596. package/src/identity/demo-pass.ts +390 -0
  597. package/src/identity/hub-grant.ts +704 -0
  598. package/src/identity/hub-jwt.ts +78 -0
  599. package/src/identity/hub-live-gate.ts +167 -0
  600. package/src/identity/hub-logout.ts +174 -0
  601. package/src/identity/hub-projection.ts +251 -0
  602. package/src/identity/hub-reconcile.ts +572 -0
  603. package/src/identity/hub-sso.ts +696 -0
  604. package/src/identity/hub-user-client.ts +554 -0
  605. package/src/identity/index.ts +56 -0
  606. package/src/identity/oauth-jwt.ts +128 -0
  607. package/src/identity/resolve-membership.ts +104 -0
  608. package/src/identity/signing-key.ts +164 -0
  609. package/src/index.ts +65 -0
  610. package/src/invitations/index.ts +1 -0
  611. package/src/invitations/service.ts +171 -0
  612. package/src/jobs/index.ts +25 -0
  613. package/src/jobs/pgboss.ts +594 -0
  614. package/src/jobs/timers.ts +287 -0
  615. package/src/logger.ts +67 -0
  616. package/src/mcp/errors.ts +111 -0
  617. package/src/mcp/http.ts +129 -0
  618. package/src/mcp/index.ts +28 -0
  619. package/src/mcp/inputs.ts +33 -0
  620. package/src/mcp/projects.ts +480 -0
  621. package/src/mcp/server.ts +174 -0
  622. package/src/mcp/teams.ts +97 -0
  623. package/src/mcp/tool-kit.ts +148 -0
  624. package/src/members/removal.ts +216 -0
  625. package/src/middleware/auth-body.ts +58 -0
  626. package/src/middleware/auth-context.ts +384 -0
  627. package/src/middleware/body-cap.ts +33 -0
  628. package/src/middleware/body-refusal.ts +23 -0
  629. package/src/middleware/cross-site.ts +122 -0
  630. package/src/middleware/hub-managed.ts +61 -0
  631. package/src/middleware/idempotency.ts +264 -0
  632. package/src/middleware/index.ts +33 -0
  633. package/src/middleware/json-depth.ts +74 -0
  634. package/src/middleware/no-store.ts +30 -0
  635. package/src/middleware/oauth-public.ts +54 -0
  636. package/src/middleware/rate-limit.ts +432 -0
  637. package/src/middleware/request-id.ts +54 -0
  638. package/src/middleware/scopes.ts +150 -0
  639. package/src/middleware/security-headers.ts +129 -0
  640. package/src/observability/index.ts +2 -0
  641. package/src/observability/metrics.ts +102 -0
  642. package/src/observability/otel.ts +79 -0
  643. package/src/pagination.ts +118 -0
  644. package/src/platform/edition.ts +140 -0
  645. package/src/platform/entitlements.ts +47 -0
  646. package/src/platform/events.ts +71 -0
  647. package/src/platform/index.ts +7 -0
  648. package/src/platform/local-identity.ts +90 -0
  649. package/src/platform/registry.ts +28 -0
  650. package/src/platform/usage.ts +13 -0
  651. package/src/platform/workspaces.ts +41 -0
  652. package/src/projects/access.ts +160 -0
  653. package/src/projects/index.ts +7 -0
  654. package/src/route-label.ts +29 -0
  655. package/src/routes/health.ts +79 -0
  656. package/src/routes/index.ts +2 -0
  657. package/src/routes/wellknown.ts +67 -0
  658. package/src/secret.ts +115 -0
  659. package/src/setup-transport.ts +46 -0
  660. package/src/state.ts +23 -0
  661. package/src/storage/driver.ts +48 -0
  662. package/src/storage/factory.ts +34 -0
  663. package/src/storage/index.ts +3 -0
  664. package/src/storage/local.ts +93 -0
  665. package/src/storage/s3.ts +109 -0
  666. package/src/testing/fake-hub.ts +1316 -0
  667. package/src/testing/helpers.ts +254 -0
  668. package/src/testing/index.ts +11 -0
  669. package/src/testing/setup-origins.ts +58 -0
  670. package/src/testing/sso-helpers.ts +178 -0
  671. package/src/tool-definition.ts +463 -0
  672. package/src/util/index.ts +17 -0
  673. package/test/fixtures/onboarding-backfill.sql +13 -0
  674. package/test/fixtures/operator-user-id-backfill.sql +18 -0
  675. package/test/host/dr-lib.sh +253 -0
  676. package/test/host/drizzle/0000_chassis_baseline.sql +438 -0
  677. package/test/host/drizzle/0001_last_owner_guard.sql +42 -0
  678. package/test/host/drizzle/meta/0000_snapshot.json +3566 -0
  679. package/test/host/drizzle/meta/_journal.json +20 -0
  680. package/test/host/drizzle.config.ts +17 -0
  681. package/test/host/identity.ts +41 -0
  682. package/test/host/minimal-host.ts +35 -0
  683. package/test/host/minimal-tool.ts +123 -0
  684. package/test/integration/account-oracle-uniformity.test.ts +284 -0
  685. package/test/integration/account-recovery.test.ts +236 -0
  686. package/test/integration/account.test.ts +120 -0
  687. package/test/integration/api-quota.test.ts +208 -0
  688. package/test/integration/apikey-expiry.test.ts +178 -0
  689. package/test/integration/apikey-pepper-rotation.test.ts +190 -0
  690. package/test/integration/boot-posture.test.ts +169 -0
  691. package/test/integration/break-glass.test.ts +484 -0
  692. package/test/integration/cloud-lifecycle.test.ts +233 -0
  693. package/test/integration/credential-boundaries.test.ts +195 -0
  694. package/test/integration/default-workspace.test.ts +414 -0
  695. package/test/integration/demo-pass-rules.test.ts +332 -0
  696. package/test/integration/demo-pass.test.ts +1222 -0
  697. package/test/integration/dr-verify-real-dump.test.ts +154 -0
  698. package/test/integration/edition.test.ts +868 -0
  699. package/test/integration/email-change.test.ts +394 -0
  700. package/test/integration/empty-tool.test.ts +267 -0
  701. package/test/integration/entitlements-null-hook.test.ts +187 -0
  702. package/test/integration/entitlements.test.ts +693 -0
  703. package/test/integration/export-entries.test.ts +321 -0
  704. package/test/integration/files.test.ts +320 -0
  705. package/test/integration/first-boot-claim.test.ts +131 -0
  706. package/test/integration/gdpr.test.ts +532 -0
  707. package/test/integration/helpers.ts +29 -0
  708. package/test/integration/hub-grant.test.ts +505 -0
  709. package/test/integration/hub-live-gate.test.ts +612 -0
  710. package/test/integration/hub-managed-membership.test.ts +559 -0
  711. package/test/integration/hub-org-selector.test.ts +281 -0
  712. package/test/integration/hub-reconcile.test.ts +646 -0
  713. package/test/integration/hub-sso.test.ts +704 -0
  714. package/test/integration/hub-teams.test.ts +771 -0
  715. package/test/integration/idempotency.test.ts +261 -0
  716. package/test/integration/invite-verification.test.ts +210 -0
  717. package/test/integration/last-owner-race.test.ts +263 -0
  718. package/test/integration/m9-fixes.test.ts +290 -0
  719. package/test/integration/mcp-projects.test.ts +463 -0
  720. package/test/integration/member-removal-race.test.ts +466 -0
  721. package/test/integration/member-removal.test.ts +794 -0
  722. package/test/integration/oauth-mcp.test.ts +477 -0
  723. package/test/integration/oauth-workspace.test.ts +371 -0
  724. package/test/integration/observability.test.ts +183 -0
  725. package/test/integration/onboarding.test.ts +268 -0
  726. package/test/integration/orphan-purge.test.ts +451 -0
  727. package/test/integration/pagination.test.ts +344 -0
  728. package/test/integration/platform-core.test.ts +305 -0
  729. package/test/integration/platform.test.ts +246 -0
  730. package/test/integration/pool-survives-restart.test.ts +80 -0
  731. package/test/integration/projects-cloud.test.ts +193 -0
  732. package/test/integration/projects.test.ts +1310 -0
  733. package/test/integration/security-fixes.test.ts +190 -0
  734. package/test/integration/setup-transport.test.ts +118 -0
  735. package/test/integration/signin-wall.test.ts +103 -0
  736. package/test/integration/signing-key-rotation.test.ts +349 -0
  737. package/test/integration/sso-helpers.ts +15 -0
  738. package/test/integration/sso-logout.test.ts +283 -0
  739. package/test/integration/teams-cloud.test.ts +194 -0
  740. package/test/integration/teams.test.ts +551 -0
  741. package/test/integration/timers.test.ts +377 -0
  742. package/test/integration/two-factor.test.ts +301 -0
  743. package/test/integration/usage-window.test.ts +161 -0
  744. package/test/integration/workspace-create-cloud.test.ts +523 -0
  745. package/test/integration/workspace-create.test.ts +510 -0
  746. package/test/integration/workspace-scoping.test.ts +530 -0
  747. package/test/integration/zz-adv-replay-owner.test.ts +205 -0
  748. package/test/unit/apikey-peppers.test.ts +110 -0
  749. package/test/unit/apikey-prefix.test.ts +34 -0
  750. package/test/unit/audit-filters.test.ts +135 -0
  751. package/test/unit/auth-origins.test.ts +92 -0
  752. package/test/unit/body-cap.test.ts +84 -0
  753. package/test/unit/clock-skew.test.ts +68 -0
  754. package/test/unit/cross-site.test.ts +166 -0
  755. package/test/unit/declared-credits.test.ts +13 -0
  756. package/test/unit/demo-pass-rules.test.ts +192 -0
  757. package/test/unit/email-driver.test.ts +127 -0
  758. package/test/unit/end-pool.test.ts +181 -0
  759. package/test/unit/entitlement-check.test.ts +492 -0
  760. package/test/unit/entitlement-gate.test.ts +1333 -0
  761. package/test/unit/entitlement-profiles.test.ts +289 -0
  762. package/test/unit/erasure-log.test.ts +72 -0
  763. package/test/unit/error-mapping.test.ts +89 -0
  764. package/test/unit/export-entries.test.ts +85 -0
  765. package/test/unit/export-sanitize.test.ts +27 -0
  766. package/test/unit/files-head-route.test.ts +155 -0
  767. package/test/unit/files-http.test.ts +97 -0
  768. package/test/unit/head-rewrite.test.ts +72 -0
  769. package/test/unit/hub-create-org.test.ts +181 -0
  770. package/test/unit/hub-jwt.test.ts +93 -0
  771. package/test/unit/hub-sso-params.test.ts +39 -0
  772. package/test/unit/hub-subject.test.ts +83 -0
  773. package/test/unit/idempotency-crypto.test.ts +45 -0
  774. package/test/unit/json-depth.test.ts +88 -0
  775. package/test/unit/logger-redaction.test.ts +66 -0
  776. package/test/unit/mcp-errors.test.ts +110 -0
  777. package/test/unit/mcp-inputs.test.ts +106 -0
  778. package/test/unit/mcp-project-hints.test.ts +26 -0
  779. package/test/unit/no-store.test.ts +49 -0
  780. package/test/unit/no-tool-migration-filename.test.ts +70 -0
  781. package/test/unit/observability.test.ts +64 -0
  782. package/test/unit/openapi-doc.test.ts +93 -0
  783. package/test/unit/rate-limit-consume-on.test.ts +76 -0
  784. package/test/unit/rate-limit.test.ts +39 -0
  785. package/test/unit/readyz-storage.test.ts +157 -0
  786. package/test/unit/request-quota.test.ts +146 -0
  787. package/test/unit/scopes.test.ts +66 -0
  788. package/test/unit/security-headers.test.ts +131 -0
  789. package/test/unit/serve-content-type.test.ts +74 -0
  790. package/test/unit/setup-transport.test.ts +29 -0
  791. package/test/unit/storage-local.test.ts +53 -0
  792. package/test/unit/superadmin.test.ts +32 -0
  793. package/test/unit/timers.test.ts +287 -0
  794. package/test/unit/tool-definition-guards.test.ts +166 -0
  795. package/test/unit/tool-entitlements-guard.test.ts +168 -0
  796. package/test/unit/usage-poster.test.ts +542 -0
  797. package/test/unit/usage-window.test.ts +48 -0
  798. package/test/unit/workspace-create-audit.test.ts +48 -0
@@ -0,0 +1,127 @@
1
+ import type PgBoss from 'pg-boss';
2
+ import type pg from 'pg';
3
+ import type { Logger } from '../logger.js';
4
+ /**
5
+ * One-off timers (PRDCT-3254): a tool runs a function ONCE at an instant or
6
+ * after a delay, with a JSON payload, on a queue its `jobs` slot declared.
7
+ * The runtime is pg-boss, the same durable queue the crons ride: a timer is a
8
+ * job row with `start_after` in the future, so it lives in the tool's own
9
+ * Postgres, survives a restart and a redeploy, and is taken by exactly one
10
+ * worker replica (pg-boss fetches with SKIP LOCKED). Edition-neutral, and an
11
+ * api-role replica schedules and cancels like any other: neither needs DDL.
12
+ *
13
+ * A KEY makes a timer replaceable: at most one PENDING timer per (queue, key).
14
+ * `schedule` with a key withdraws the pending timer of that key and inserts
15
+ * the new one in ONE transaction under a per-key advisory lock, so two
16
+ * replicas re-arming the same thing at once never leave two timers, and
17
+ * `cancel({ key })` withdraws whatever is pending under it. A timer that is
18
+ * already RUNNING is neither replaced nor cancelled (its handler is on it;
19
+ * the handler's own claim decides what it does), so a consumer keeps its
20
+ * at-most-once guard in the data it writes (meet's claim-before-send stamps),
21
+ * never in the timer alone. What a replace or a cancel DOES do to a running
22
+ * timer is take its retries away (`retry_limit = retry_count`): pg-boss's
23
+ * fail path re-inserts a failed run as a pending `retry` row with the same
24
+ * key, which would put the withdrawn payload back beside the new one
25
+ * (verifier round 1, F1). A withdrawn run that throws therefore ends
26
+ * `failed`, and "one pending per key" holds across the run's failure too.
27
+ * `cancel` itself runs without the per-key lock: a cancel concurrent with a
28
+ * replace may answer 0 and leave the replace's fresh timer pending (it ran
29
+ * first); a consumer that wants "nothing pending" cancels after its last
30
+ * schedule, as every path does.
31
+ *
32
+ * The payload is a plain JSON object (not an array, not a Date, nothing a
33
+ * `JSON.stringify` refuses): node-postgres serialises anything else into a
34
+ * value the `jsonb` column refuses with a raw database error, so the check is
35
+ * made here and answers `invalid_argument` before any statement runs.
36
+ *
37
+ * What a timer costs in pg-boss's terms: `keep_until` is `start_after` plus
38
+ * the queue's retention (fourteen days by default), so a timer months ahead is
39
+ * not archived before its time; the handler's run is bounded by the queue's
40
+ * `expireIn` (fifteen minutes by default); a handler that throws fails the
41
+ * job, retried per `retry` or the queue's own settings (pg-boss's queue
42
+ * default is two retries with no delay, so a handler that always throws runs
43
+ * three times back to back), then left `failed`.
44
+ *
45
+ * The pending-state SQL reads pg-boss's own `job` table (its schema is
46
+ * `PGBOSS_SCHEMA`, the column names pg-boss 10's), because pg-boss exposes no
47
+ * lookup by key; `timers.test.ts` pins the statements against the installed
48
+ * version. A pg-boss bump re-verifies them.
49
+ */
50
+ /** The pg-boss schema the chassis installs (`createJobs`). */
51
+ export declare const PGBOSS_SCHEMA = "pgboss";
52
+ /**
53
+ * Advisory-lock class serializing the replace of a keyed timer, beside the
54
+ * migration lock (7432001), the last-owner locks (7432002 xact / 7432003
55
+ * session) and the pg-boss install lock (7432004). Transaction-scoped, two-int
56
+ * form: the class and `hashtext(queue + US + key)`.
57
+ */
58
+ export declare const TIMER_KEY_LOCK_CLASS = 7432005;
59
+ /** What a handler learns about the run beside its payload. */
60
+ export interface TimerJob {
61
+ /** pg-boss's job id, the one `schedule` answered. */
62
+ id: string;
63
+ queue: string;
64
+ /** The dedupe key the timer was scheduled with; null without one, and on a cron's run. */
65
+ key: string | null;
66
+ }
67
+ /** When the timer fires: an instant, or a delay from now in seconds. Exactly one. */
68
+ export type TimerWhen = {
69
+ at: Date;
70
+ inSeconds?: never;
71
+ } | {
72
+ inSeconds: number;
73
+ at?: never;
74
+ };
75
+ /** How a failing handler is retried: `limit` more attempts, `delaySeconds` apart (doubled each time with `backoff`). */
76
+ export interface TimerRetry {
77
+ limit: number;
78
+ delaySeconds?: number;
79
+ backoff?: boolean;
80
+ }
81
+ export type TimerOptions = TimerWhen & {
82
+ /** The dedupe key: at most one pending timer per (queue, key); a new schedule under it replaces the pending one. */
83
+ key?: string;
84
+ /** Absent: the queue's own retry settings. */
85
+ retry?: TimerRetry;
86
+ };
87
+ export type TimerRef = {
88
+ id: string;
89
+ key?: never;
90
+ } | {
91
+ key: string;
92
+ id?: never;
93
+ };
94
+ export interface Timers {
95
+ /**
96
+ * Run the queue's handler once with `data`, at `at` or `inSeconds` from
97
+ * now. Answers the job id. Throws `TimerError` (`unknown_queue`) when the
98
+ * queue is not one the tool's `jobs` slot declared, `invalid_argument` on a
99
+ * malformed call.
100
+ */
101
+ schedule<TData extends object>(queue: string, data: TData, options: TimerOptions): Promise<string>;
102
+ /**
103
+ * Withdraw a timer that has not run yet, by its id or by its key. Answers
104
+ * how many pending timers were withdrawn (0 when none was pending: already
105
+ * run, already withdrawn, running right now, or never scheduled).
106
+ */
107
+ cancel(queue: string, ref: TimerRef): Promise<number>;
108
+ }
109
+ export declare class TimerError extends Error {
110
+ readonly code: 'unknown_queue' | 'invalid_argument';
111
+ constructor(code: 'unknown_queue' | 'invalid_argument', message: string);
112
+ }
113
+ /** The longest delay a timer takes, in seconds: a hundred years. Postgres refuses an interval written in exponent form. */
114
+ export declare const MAX_IN_SECONDS: number;
115
+ /** The pg-boss `startAfter` for `options`: the Date of `at`, or the delay in seconds. */
116
+ export declare function startAfterOf(options: TimerWhen): Date | number;
117
+ export declare class PgBossTimers implements Timers {
118
+ private readonly boss;
119
+ private readonly pool;
120
+ private readonly logger;
121
+ constructor(boss: PgBoss, pool: pg.Pool, logger: Logger);
122
+ schedule<TData extends object>(queue: string, data: TData, options: TimerOptions): Promise<string>;
123
+ cancel(queue: string, ref: TimerRef): Promise<number>;
124
+ /** pg-boss answers null for a queue that does not exist (its insert joins the queue row): that is an unknown queue, named. */
125
+ private insert;
126
+ }
127
+ //# sourceMappingURL=timers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timers.d.ts","sourceRoot":"","sources":["../../src/jobs/timers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,8DAA8D;AAC9D,eAAO,MAAM,aAAa,WAAW,CAAC;AAEtC;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,UAAY,CAAC;AAE9C,8DAA8D;AAC9D,MAAM,WAAW,QAAQ;IACvB,qDAAqD;IACrD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,qFAAqF;AACrF,MAAM,MAAM,SAAS,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE5F,wHAAwH;AACxH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG;IACrC,oHAAoH;IACpH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAEjF,MAAM,WAAW,MAAM;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnG;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACvD;AAED,qBAAa,UAAW,SAAQ,KAAK;IAEjC,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,kBAAkB;gBAA1C,IAAI,EAAE,eAAe,GAAG,kBAAkB,EACnD,OAAO,EAAE,MAAM;CAKlB;AASD,2HAA2H;AAC3H,eAAO,MAAM,cAAc,QAA2B,CAAC;AAQvD,yFAAyF;AACzF,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,CAa9D;AA+ED,qBAAa,YAAa,YAAW,MAAM;IAEvC,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAFN,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,MAAM,EAAE,MAAM;IAG3B,QAAQ,CAAC,KAAK,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAoClG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAO3D,8HAA8H;YAChH,MAAM;CAUrB"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * One-off timers (PRDCT-3254): a tool runs a function ONCE at an instant or
3
+ * after a delay, with a JSON payload, on a queue its `jobs` slot declared.
4
+ * The runtime is pg-boss, the same durable queue the crons ride: a timer is a
5
+ * job row with `start_after` in the future, so it lives in the tool's own
6
+ * Postgres, survives a restart and a redeploy, and is taken by exactly one
7
+ * worker replica (pg-boss fetches with SKIP LOCKED). Edition-neutral, and an
8
+ * api-role replica schedules and cancels like any other: neither needs DDL.
9
+ *
10
+ * A KEY makes a timer replaceable: at most one PENDING timer per (queue, key).
11
+ * `schedule` with a key withdraws the pending timer of that key and inserts
12
+ * the new one in ONE transaction under a per-key advisory lock, so two
13
+ * replicas re-arming the same thing at once never leave two timers, and
14
+ * `cancel({ key })` withdraws whatever is pending under it. A timer that is
15
+ * already RUNNING is neither replaced nor cancelled (its handler is on it;
16
+ * the handler's own claim decides what it does), so a consumer keeps its
17
+ * at-most-once guard in the data it writes (meet's claim-before-send stamps),
18
+ * never in the timer alone. What a replace or a cancel DOES do to a running
19
+ * timer is take its retries away (`retry_limit = retry_count`): pg-boss's
20
+ * fail path re-inserts a failed run as a pending `retry` row with the same
21
+ * key, which would put the withdrawn payload back beside the new one
22
+ * (verifier round 1, F1). A withdrawn run that throws therefore ends
23
+ * `failed`, and "one pending per key" holds across the run's failure too.
24
+ * `cancel` itself runs without the per-key lock: a cancel concurrent with a
25
+ * replace may answer 0 and leave the replace's fresh timer pending (it ran
26
+ * first); a consumer that wants "nothing pending" cancels after its last
27
+ * schedule, as every path does.
28
+ *
29
+ * The payload is a plain JSON object (not an array, not a Date, nothing a
30
+ * `JSON.stringify` refuses): node-postgres serialises anything else into a
31
+ * value the `jsonb` column refuses with a raw database error, so the check is
32
+ * made here and answers `invalid_argument` before any statement runs.
33
+ *
34
+ * What a timer costs in pg-boss's terms: `keep_until` is `start_after` plus
35
+ * the queue's retention (fourteen days by default), so a timer months ahead is
36
+ * not archived before its time; the handler's run is bounded by the queue's
37
+ * `expireIn` (fifteen minutes by default); a handler that throws fails the
38
+ * job, retried per `retry` or the queue's own settings (pg-boss's queue
39
+ * default is two retries with no delay, so a handler that always throws runs
40
+ * three times back to back), then left `failed`.
41
+ *
42
+ * The pending-state SQL reads pg-boss's own `job` table (its schema is
43
+ * `PGBOSS_SCHEMA`, the column names pg-boss 10's), because pg-boss exposes no
44
+ * lookup by key; `timers.test.ts` pins the statements against the installed
45
+ * version. A pg-boss bump re-verifies them.
46
+ */
47
+ /** The pg-boss schema the chassis installs (`createJobs`). */
48
+ export const PGBOSS_SCHEMA = 'pgboss';
49
+ /**
50
+ * Advisory-lock class serializing the replace of a keyed timer, beside the
51
+ * migration lock (7432001), the last-owner locks (7432002 xact / 7432003
52
+ * session) and the pg-boss install lock (7432004). Transaction-scoped, two-int
53
+ * form: the class and `hashtext(queue + US + key)`.
54
+ */
55
+ export const TIMER_KEY_LOCK_CLASS = 7_432_005;
56
+ export class TimerError extends Error {
57
+ code;
58
+ constructor(code, message) {
59
+ super(message);
60
+ this.code = code;
61
+ this.name = 'TimerError';
62
+ }
63
+ }
64
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
65
+ /** pg-boss's own rule for a queue name (`Attorney.assertQueueName`), applied before any statement runs. */
66
+ const QUEUE_NAME = /^[\w-]+$/;
67
+ /** Unit separator: joins the queue and the key under one lock hash, and can appear in neither. */
68
+ const US = '\u001f';
69
+ const invalid = (message) => new TimerError('invalid_argument', `timers: ${message}`);
70
+ /** The longest delay a timer takes, in seconds: a hundred years. Postgres refuses an interval written in exponent form. */
71
+ export const MAX_IN_SECONDS = 100 * 365.25 * 24 * 3600;
72
+ function assertQueue(queue) {
73
+ if (typeof queue !== 'string' || !QUEUE_NAME.test(queue)) {
74
+ throw invalid('the queue must be a name of letters, digits, underscores and hyphens');
75
+ }
76
+ }
77
+ /** The pg-boss `startAfter` for `options`: the Date of `at`, or the delay in seconds. */
78
+ export function startAfterOf(options) {
79
+ const hasAt = options.at !== undefined;
80
+ const hasIn = options.inSeconds !== undefined;
81
+ if (hasAt === hasIn)
82
+ throw invalid('exactly one of `at` and `inSeconds` is required');
83
+ if (hasAt) {
84
+ const at = options.at;
85
+ if (!(at instanceof Date) || !Number.isFinite(at.getTime()))
86
+ throw invalid('`at` must be a valid Date');
87
+ return at;
88
+ }
89
+ const seconds = options.inSeconds;
90
+ if (!Number.isFinite(seconds) || seconds < 0 || seconds > MAX_IN_SECONDS)
91
+ throw invalid('`inSeconds` must be a finite number, between 0 and a hundred years');
92
+ return seconds;
93
+ }
94
+ function retryOptionsOf(retry) {
95
+ if (retry === undefined)
96
+ return {};
97
+ if (!Number.isInteger(retry.limit) || retry.limit < 0)
98
+ throw invalid('`retry.limit` must be an integer, 0 or more');
99
+ const delay = retry.delaySeconds ?? 0;
100
+ if (!Number.isInteger(delay) || delay < 0)
101
+ throw invalid('`retry.delaySeconds` must be an integer, 0 or more');
102
+ return { retryLimit: retry.limit, retryDelay: delay, retryBackoff: retry.backoff ?? false };
103
+ }
104
+ function assertData(data) {
105
+ const proto = typeof data === 'object' && data !== null ? Object.getPrototypeOf(data) : undefined;
106
+ if (proto !== Object.prototype && proto !== null) {
107
+ throw invalid('the payload must be a plain object');
108
+ }
109
+ try {
110
+ JSON.stringify(data);
111
+ }
112
+ catch {
113
+ throw invalid('the payload must be JSON (no bigint, no circular reference)');
114
+ }
115
+ }
116
+ function assertKey(key) {
117
+ if (typeof key !== 'string' || key.length === 0 || key.includes(US)) {
118
+ throw invalid('the key must be a non-empty string');
119
+ }
120
+ }
121
+ /** The one statement that withdraws pending timers: created or waiting for a retry, never running. */
122
+ const CANCEL_PENDING = (where) => `
123
+ UPDATE ${PGBOSS_SCHEMA}.job
124
+ SET state = 'cancelled', completed_on = now()
125
+ WHERE name = $1 AND ${where} AND state IN ('created', 'retry')
126
+ `;
127
+ /**
128
+ * The statement that takes a RUNNING timer's retries away, so that if the
129
+ * run fails it ends `failed` and never comes back as a pending `retry` row
130
+ * under the withdrawn key or id (pg-boss retries while
131
+ * `retry_count < retry_limit`).
132
+ */
133
+ const DISARM_ACTIVE = (where) => `
134
+ UPDATE ${PGBOSS_SCHEMA}.job
135
+ SET retry_limit = retry_count
136
+ WHERE name = $1 AND ${where} AND state = 'active'
137
+ `;
138
+ /** Withdraw the pending timers `ref` names and disarm a running one; answers the pending count withdrawn. */
139
+ async function cancelPending(client, queue, ref) {
140
+ let where;
141
+ let value;
142
+ if (ref.id !== undefined) {
143
+ if (!UUID.test(ref.id))
144
+ throw invalid('the id must be a job id');
145
+ where = 'id = $2::uuid';
146
+ value = ref.id;
147
+ }
148
+ else {
149
+ assertKey(ref.key);
150
+ where = 'singleton_key = $2';
151
+ value = ref.key;
152
+ }
153
+ // The disarm FIRST, then the withdraw (verifier round 2, F7): pg-boss's fail
154
+ // path deletes the active row and re-inserts it as `retry` under the same
155
+ // key. Disarm first either takes the row lock before that fail (which then
156
+ // waits for the commit and computes `failed` on the disarmed row) or runs
157
+ // after it, and the withdraw, a new statement with a new snapshot, then
158
+ // sees the re-inserted `retry` row and cancels it. In the other order both
159
+ // statements could miss the row, one round trip wide. A replace whose
160
+ // insert then fails rolls the disarm back with it: the old run keeps its
161
+ // retries, a failed replace changes nothing.
162
+ await client.query(DISARM_ACTIVE(where), [queue, value]);
163
+ const res = await client.query(CANCEL_PENDING(where), [queue, value]);
164
+ return res.rowCount ?? 0;
165
+ }
166
+ export class PgBossTimers {
167
+ boss;
168
+ pool;
169
+ logger;
170
+ constructor(boss, pool, logger) {
171
+ this.boss = boss;
172
+ this.pool = pool;
173
+ this.logger = logger;
174
+ }
175
+ async schedule(queue, data, options) {
176
+ assertQueue(queue);
177
+ assertData(data);
178
+ const send = { startAfter: startAfterOf(options), ...retryOptionsOf(options.retry) };
179
+ if (options.key === undefined) {
180
+ return this.insert(queue, data, send);
181
+ }
182
+ assertKey(options.key);
183
+ const key = options.key;
184
+ // Replace = withdraw + insert in one transaction, serialized per key
185
+ // across replicas by a transaction-scoped advisory lock on a client of
186
+ // our own: pg-boss runs the insert through the `db` executor we hand it.
187
+ const client = await this.pool.connect();
188
+ try {
189
+ await client.query('BEGIN');
190
+ await client.query('SELECT pg_advisory_xact_lock($1, hashtext($2))', [
191
+ TIMER_KEY_LOCK_CLASS,
192
+ queue + US + key
193
+ ]);
194
+ const replaced = await cancelPending(client, queue, { key });
195
+ const id = await this.insert(queue, data, {
196
+ ...send,
197
+ singletonKey: key,
198
+ db: { executeSql: (text, values) => client.query(text, values) }
199
+ });
200
+ await client.query('COMMIT');
201
+ if (replaced > 0)
202
+ this.logger.debug({ queue, key, replaced }, 'timers: a pending timer was replaced');
203
+ return id;
204
+ }
205
+ catch (err) {
206
+ await client.query('ROLLBACK').catch(() => { });
207
+ throw err;
208
+ }
209
+ finally {
210
+ client.release();
211
+ }
212
+ }
213
+ async cancel(queue, ref) {
214
+ assertQueue(queue);
215
+ if ((ref.id === undefined) === (ref.key === undefined))
216
+ throw invalid('exactly one of `id` and `key` is required');
217
+ return cancelPending(this.pool, queue, ref);
218
+ }
219
+ /** pg-boss answers null for a queue that does not exist (its insert joins the queue row): that is an unknown queue, named. */
220
+ async insert(queue, data, send) {
221
+ const id = await this.boss.send(queue, data, send);
222
+ if (id === null) {
223
+ throw new TimerError('unknown_queue', `timers: the queue "${queue}" is not declared by the tool's jobs slot (a timer rides a declared queue)`);
224
+ }
225
+ return id;
226
+ }
227
+ }
228
+ //# sourceMappingURL=timers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timers.js","sourceRoot":"","sources":["../../src/jobs/timers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type Logger } from 'pino';
2
+ import type { Env } from './env.js';
3
+ export type { Logger };
4
+ /**
5
+ * The single redaction list — secrets never reach the log stream.
6
+ *
7
+ * Two rules when adding to it. (1) pino's `*.x` glob matches the key `x` at
8
+ * depth 1 ONLY, and it is an EXACT key match: `*.secret` does NOT cover
9
+ * `clientSecret`, `client_secret`, or `apiSecret`, so every camel/snake spelling
10
+ * a payload can carry needs its own entry. (2) Redaction keys off object
11
+ * PROPERTIES — it can do nothing about a secret interpolated into a message
12
+ * string. Never build a log message out of a config payload; log the shape
13
+ * (`{ length, path }`), never the bytes.
14
+ */
15
+ export declare const REDACT_PATHS: string[];
16
+ export declare function createLogger(env: Pick<Env, 'LOG_LEVEL' | 'NODE_ENV'>): Logger;
17
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,YAAY,EAAE,MAAM,EAAE,CAAC;AAEvB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,UAiCxB,CAAC;AAEF,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,MAAM,CAe7E"}
package/dist/logger.js ADDED
@@ -0,0 +1,64 @@
1
+ import { pino } from 'pino';
2
+ /**
3
+ * The single redaction list — secrets never reach the log stream.
4
+ *
5
+ * Two rules when adding to it. (1) pino's `*.x` glob matches the key `x` at
6
+ * depth 1 ONLY, and it is an EXACT key match: `*.secret` does NOT cover
7
+ * `clientSecret`, `client_secret`, or `apiSecret`, so every camel/snake spelling
8
+ * a payload can carry needs its own entry. (2) Redaction keys off object
9
+ * PROPERTIES — it can do nothing about a secret interpolated into a message
10
+ * string. Never build a log message out of a config payload; log the shape
11
+ * (`{ length, path }`), never the bytes.
12
+ */
13
+ export const REDACT_PATHS = [
14
+ 'req.headers.authorization',
15
+ 'req.headers.cookie',
16
+ '*.password',
17
+ '*.secret',
18
+ '*.token',
19
+ // Exact-key spellings the `*.secret` glob misses — OAuth/hub-federation
20
+ // payloads carry these verbatim.
21
+ '*.clientSecret',
22
+ '*.client_secret',
23
+ '*.accessToken',
24
+ '*.access_token',
25
+ '*.refreshToken',
26
+ '*.refresh_token',
27
+ '*.apiKey',
28
+ '*.api_key',
29
+ 'DATABASE_URL',
30
+ 'AUTH_SECRET',
31
+ 'API_KEY_PEPPERS',
32
+ 'SETUP_TOKEN',
33
+ 'METRICS_TOKEN',
34
+ 'SMTP_URL',
35
+ 'RESEND_API_KEY',
36
+ 'BREVO_API_KEY',
37
+ 'S3_SECRET_ACCESS_KEY',
38
+ 'S3_ACCESS_KEY_ID',
39
+ // Optional social credential — read in env.ts, so any "here is the parsed
40
+ // env" line would otherwise carry it.
41
+ 'GOOGLE_CLIENT_SECRET',
42
+ // Cloud edition: the hub-federation client credential (ADR 015 / user-scoped
43
+ // federation). It is THIS tool's identity at the Antasphere hub — leaking it
44
+ // lets anyone impersonate the tool at the authorization server.
45
+ 'HUB_CLIENT_SECRET'
46
+ ];
47
+ export function createLogger(env) {
48
+ const options = {
49
+ level: env.LOG_LEVEL,
50
+ redact: { paths: REDACT_PATHS, censor: '[redacted]' }
51
+ };
52
+ if (env.NODE_ENV === 'development') {
53
+ // pino-pretty is a devDependency; if it is absent (e.g. NODE_ENV flipped
54
+ // on a pruned production image) fall back to JSON instead of crashing.
55
+ try {
56
+ return pino({ ...options, transport: { target: 'pino-pretty', options: { colorize: true } } });
57
+ }
58
+ catch {
59
+ // fall through to JSON output
60
+ }
61
+ }
62
+ return pino(options);
63
+ }
64
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAe,MAAM,MAAM,CAAC;AAKzC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,2BAA2B;IAC3B,oBAAoB;IACpB,YAAY;IACZ,UAAU;IACV,SAAS;IACT,wEAAwE;IACxE,iCAAiC;IACjC,gBAAgB;IAChB,iBAAiB;IACjB,eAAe;IACf,gBAAgB;IAChB,gBAAgB;IAChB,iBAAiB;IACjB,UAAU;IACV,WAAW;IACX,cAAc;IACd,aAAa;IACb,iBAAiB;IACjB,aAAa;IACb,eAAe;IACf,UAAU;IACV,gBAAgB;IAChB,eAAe;IACf,sBAAsB;IACtB,kBAAkB;IAClB,0EAA0E;IAC1E,sCAAsC;IACtC,sBAAsB;IACtB,6EAA6E;IAC7E,6EAA6E;IAC7E,gEAAgE;IAChE,mBAAmB;CACpB,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,GAAwC;IACnE,MAAM,OAAO,GAAG;QACd,KAAK,EAAE,GAAG,CAAC,SAAS;QACpB,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE;KACtD,CAAC;IACF,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;QACnC,yEAAyE;QACzE,uEAAuE;QACvE,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QACjG,CAAC;QAAC,MAAM,CAAC;YACP,8BAA8B;QAChC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * API error → model-readable hint mapping (the predecessor MCP template's
3
+ * DOMAIN_HINTS pattern). The API returns `{ error: { code, message } }` on
4
+ * failure; each domain code can carry an actionable hint so the model
5
+ * self-corrects instead of retrying blindly. The table below holds the hints of
6
+ * the chassis' own codes; a tool adds its domain's through
7
+ * {@link mergeErrorHints} (the `errorHints` of its MCP definition).
8
+ */
9
+ export type ErrorHints = Readonly<Record<string, string>>;
10
+ /** The chassis hints plus a tool's own: ONE table, the one every lookup reads. */
11
+ export declare function mergeErrorHints(toolHints: ErrorHints): ErrorHints;
12
+ /** Thrown when the in-process API call returns a non-2xx wire-shape response. */
13
+ export declare class ApiToolError extends Error {
14
+ readonly status: number;
15
+ readonly code: string | null;
16
+ /** The wire's `error.details`, when the API sent any (a plan refusal's upgrade link rides here). */
17
+ readonly details: unknown;
18
+ constructor(status: number, code: string | null, message: string, details?: unknown);
19
+ toUserFacingText(hints?: ErrorHints): string;
20
+ }
21
+ export interface ToolTextResult {
22
+ [key: string]: unknown;
23
+ content: Array<{
24
+ type: 'text';
25
+ text: string;
26
+ }>;
27
+ isError?: true;
28
+ }
29
+ export declare const jsonText: (result: unknown) => ToolTextResult;
30
+ export declare const deny: (text: string) => ToolTextResult;
31
+ /**
32
+ * Wrap a tool body so any thrown ApiToolError surfaces as a structured MCP
33
+ * tool error (`isError: true` + text) rather than a protocol-level exception.
34
+ * Other errors propagate to the SDK.
35
+ */
36
+ export declare function wrapToolErrors(fn: () => Promise<ToolTextResult>, hints?: ErrorHints): Promise<ToolTextResult>;
37
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/mcp/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAmB1D,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,SAAS,EAAE,UAAU,GAAG,UAAU,CAEjE;AAED,iFAAiF;AACjF,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B,oGAAoG;IACpG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAEd,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;IAQnF,gBAAgB,CAAC,KAAK,GAAE,UAAyB,GAAG,MAAM;CA2B3D;AAED,MAAM,WAAW,cAAc;IAE7B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB;AAED,eAAO,MAAM,QAAQ,GAAI,QAAQ,OAAO,KAAG,cAEzC,CAAC;AAEH,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,KAAG,cAGlC,CAAC;AAEH;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,EACjC,KAAK,GAAE,UAAyB,GAC/B,OAAO,CAAC,cAAc,CAAC,CASzB"}
@@ -0,0 +1,77 @@
1
+ const DOMAIN_HINTS = {
2
+ insufficient_scope: 'Reconnect the MCP server and approve the permission on the consent screen ' +
3
+ '(or mint an API key that includes the scope).',
4
+ endpoint_not_allowed: 'This endpoint is not opened to machine credentials — a human must do this in the dashboard.',
5
+ invalid_token: 'The OAuth token expired or was revoked. Reconnect the MCP server.',
6
+ unauthenticated: 'No valid credential reached the API. Reconnect the MCP server.',
7
+ rate_limited: 'Rate limited — wait before retrying.',
8
+ plan_required: 'The workspace\u2019s plan does not allow this — the upgrade link in this message is where a human raises it.',
9
+ // The same code on both editions: the cloud's credit refusal (402, with the
10
+ // top-up link) and a self-hosted instance's cap (413, no details).
11
+ entitlement_denied: 'The instance refused this action: on the cloud the organization lacks the credits and the top-up link in this message is where a human adds them, or the quantity is beyond what can be priced and no top-up covers it (no link then); on a self-hosted instance the request exceeds the operator’s cap.'
12
+ };
13
+ /** The chassis hints plus a tool's own: ONE table, the one every lookup reads. */
14
+ export function mergeErrorHints(toolHints) {
15
+ return { ...DOMAIN_HINTS, ...toolHints };
16
+ }
17
+ /** Thrown when the in-process API call returns a non-2xx wire-shape response. */
18
+ export class ApiToolError extends Error {
19
+ status;
20
+ code;
21
+ /** The wire's `error.details`, when the API sent any (a plan refusal's upgrade link rides here). */
22
+ details;
23
+ constructor(status, code, message, details) {
24
+ super(message);
25
+ this.name = 'ApiToolError';
26
+ this.status = status;
27
+ this.code = code;
28
+ this.details = details;
29
+ }
30
+ toUserFacingText(hints = DOMAIN_HINTS) {
31
+ const hint = this.code ? hints[this.code] : undefined;
32
+ const codePart = this.code ? `, code: ${this.code}` : '';
33
+ // A plan refusal carries its upgrade link (the billing rail, §7): the
34
+ // agent relays it, a human follows it. Text, never a structured field.
35
+ const upgradeUrl = this.details?.upgradeUrl;
36
+ const upgrade = typeof upgradeUrl === 'string' && upgradeUrl ? ` Upgrade: ${upgradeUrl}` : '';
37
+ // A credit refusal (402 `entitlement_denied`, PRDCT-2664) carries its
38
+ // top-up link, the price and the balance: the same, as text. The
39
+ // self-hosted cap's 413 has no details, so no top-up sentence.
40
+ const { topUpUrl, credits, balance } = (this.details ?? {});
41
+ let topUp = '';
42
+ // The gate's message already carries the link, the price and the balance;
43
+ // the sentence is added only for a message that does not (verifier
44
+ // round 1: the URL was printed twice).
45
+ if (typeof topUpUrl === 'string' && topUpUrl && !this.message.includes(topUpUrl)) {
46
+ const needs = typeof credits === 'number' ? [`this needs ${credits} credits`] : [];
47
+ const holds = typeof balance === 'number' ? [`the organization holds ${balance}`] : [];
48
+ const numbers = [...needs, ...holds].join(', ');
49
+ topUp = ` Top up: ${topUpUrl}${numbers ? ` (${numbers}).` : ''}`;
50
+ }
51
+ return `API error (HTTP ${this.status}${codePart}): ${this.message}${hint ? ` — Next: ${hint}` : ''}${upgrade}${topUp}`;
52
+ }
53
+ }
54
+ export const jsonText = (result) => ({
55
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
56
+ });
57
+ export const deny = (text) => ({
58
+ content: [{ type: 'text', text }],
59
+ isError: true
60
+ });
61
+ /**
62
+ * Wrap a tool body so any thrown ApiToolError surfaces as a structured MCP
63
+ * tool error (`isError: true` + text) rather than a protocol-level exception.
64
+ * Other errors propagate to the SDK.
65
+ */
66
+ export async function wrapToolErrors(fn, hints = DOMAIN_HINTS) {
67
+ try {
68
+ return await fn();
69
+ }
70
+ catch (err) {
71
+ if (err instanceof ApiToolError) {
72
+ return { content: [{ type: 'text', text: err.toUserFacingText(hints) }], isError: true };
73
+ }
74
+ throw err;
75
+ }
76
+ }
77
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/mcp/errors.ts"],"names":[],"mappings":"AAUA,MAAM,YAAY,GAA2B;IAC3C,kBAAkB,EAChB,4EAA4E;QAC5E,+CAA+C;IACjD,oBAAoB,EAClB,6FAA6F;IAC/F,aAAa,EAAE,mEAAmE;IAClF,eAAe,EAAE,gEAAgE;IACjF,YAAY,EAAE,sCAAsC;IACpD,aAAa,EACX,8GAA8G;IAChH,4EAA4E;IAC5E,mEAAmE;IACnE,kBAAkB,EAChB,0SAA0S;CAC7S,CAAC;AAEF,kFAAkF;AAClF,MAAM,UAAU,eAAe,CAAC,SAAqB;IACnD,OAAO,EAAE,GAAG,YAAY,EAAE,GAAG,SAAS,EAAE,CAAC;AAC3C,CAAC;AAED,iFAAiF;AACjF,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,MAAM,CAAS;IACf,IAAI,CAAgB;IAE7B,oGAAoG;IAC3F,OAAO,CAAU;IAE1B,YAAY,MAAc,EAAE,IAAmB,EAAE,OAAe,EAAE,OAAiB;QACjF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,gBAAgB,CAAC,QAAoB,YAAY;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,sEAAsE;QACtE,uEAAuE;QACvE,MAAM,UAAU,GAAI,IAAI,CAAC,OAA2C,EAAE,UAAU,CAAC;QACjF,MAAM,OAAO,GAAG,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,CAAC,CAAC,aAAa,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,sEAAsE;QACtE,iEAAiE;QACjE,+DAA+D;QAC/D,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAIzD,CAAC;QACF,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,0EAA0E;QAC1E,mEAAmE;QACnE,uCAAuC;QACvC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjF,MAAM,KAAK,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,cAAc,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACnF,MAAM,KAAK,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,0BAA0B,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACvF,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChD,KAAK,GAAG,YAAY,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACnE,CAAC;QACD,OAAO,mBAAmB,IAAI,CAAC,MAAM,GAAG,QAAQ,MAAM,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,GAAG,KAAK,EAAE,CAAC;IAC1H,CAAC;CACF;AASD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,MAAe,EAAkB,EAAE,CAAC,CAAC;IAC5D,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;CAC5E,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAkB,EAAE,CAAC,CAAC;IACrD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;IAC1C,OAAO,EAAE,IAAa;CACvB,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,EAAiC,EACjC,QAAoB,YAAY;IAEhC,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3F,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { Hono } from 'hono';
2
+ import type { MiddlewareHandler } from 'hono';
3
+ import type { Principal } from '@antasphere/chassis-contract';
4
+ import { type McpIdentity, type McpToolDefinition } from './server.js';
5
+ /**
6
+ * The bundled /mcp endpoint (streamable HTTP, STATELESS — see ADR 002).
7
+ *
8
+ * Auth gate first: a valid OAuth bearer (token this instance minted) or an
9
+ * API key — both machine principals, resolved through the same machinery as
10
+ * /api/v1. Anything else gets the RFC 9728 401 challenge whose
11
+ * `resource_metadata` URL drives the whole client OAuth dance.
12
+ *
13
+ * Stateless transport: a fresh McpServer + transport per request, no session
14
+ * ids, no in-process stream state — the platform's statelessness invariant
15
+ * applies to MCP too (any replica can serve any request).
16
+ */
17
+ export interface McpHttpDeps {
18
+ publicBaseUrl: string;
19
+ version: string;
20
+ /** In-process fetch against the root app; tools forward the caller's bearer. */
21
+ fetchApi: (path: string, init?: RequestInit) => Promise<Response>;
22
+ resolveOauthJwt: (token: string) => Promise<Principal | null>;
23
+ resolveApiKey: (token: string) => Promise<Principal | null>;
24
+ isApiKeyToken: (token: string) => boolean;
25
+ /** Instance display name for the server instructions (cached by the caller). */
26
+ instanceName: () => Promise<string>;
27
+ /** Per-IP rate limit, applied before the auth gate (floods rejected cheaply). */
28
+ limiter: MiddlewareHandler;
29
+ /** The tool's MCP definition: its tools, instructions, error hints and scope names. */
30
+ tool: McpToolDefinition;
31
+ /** The server's name and the tool names' prefix (`identity.mcp`). */
32
+ identity: McpIdentity;
33
+ }
34
+ export declare function mcpRoutes(deps: McpHttpDeps): Hono;
35
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/mcp/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAI9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,EAAkB,KAAK,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEvF;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClE,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC9D,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5D,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,gFAAgF;IAChF,YAAY,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,iFAAiF;IACjF,OAAO,EAAE,iBAAiB,CAAC;IAC3B,uFAAuF;IACvF,IAAI,EAAE,iBAAiB,CAAC;IACxB,qEAAqE;IACrE,QAAQ,EAAE,WAAW,CAAC;CACvB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAyFjD"}