@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,96 @@
1
+ import { createHash } from 'node:crypto';
2
+ /**
3
+ * Baseline headers on every response (brief §2.6). The CSP applies to HTML
4
+ * we serve (the dashboard SPA) and locks it to self — with hashes for the
5
+ * inline bootstrap script SvelteKit bakes into index.html, computed once at
6
+ * boot. User-uploaded content never renders on this origin (the files
7
+ * module forces attachment for active types), so this CSP is the only HTML
8
+ * policy the origin needs. frame-ancestors 'none' replaces X-Frame-Options.
9
+ */
10
+ export function inlineScriptHashes(html) {
11
+ const hashes = [];
12
+ const re = /<script(?![^>]*\bsrc=)[^>]*>([\s\S]*?)<\/script>/gi;
13
+ let match;
14
+ while ((match = re.exec(html)) !== null) {
15
+ const body = match[1] ?? '';
16
+ if (body.trim().length === 0)
17
+ continue;
18
+ hashes.push(`'sha256-${createHash('sha256').update(body).digest('base64')}'`);
19
+ }
20
+ return hashes;
21
+ }
22
+ export function buildCsp(scriptHashes, { frameSrc = [], imgSrc = [] } = {}) {
23
+ const script = ["'self'", ...scriptHashes].join(' ');
24
+ const frame = ["'self'", ...frameSrc].join(' ');
25
+ const img = ["'self'", 'data:', ...imgSrc].join(' ');
26
+ return [
27
+ "default-src 'self'",
28
+ `script-src ${script}`,
29
+ // Svelte injects component styles at runtime; hashes are impractical there.
30
+ // The two font CDNs the dashboard's app.html links (PRDCT-2308): the
31
+ // Observatory pairing rides Fontshare (Sentient, Synonym) and Google
32
+ // Fonts (Onest) because this repo is slated for the OSS cut and the
33
+ // faces may not be committed. Stylesheets from the two API hosts, the
34
+ // font files from their two file hosts, and nothing else — the
35
+ // dashboard's own origin stays the only script and connect source.
36
+ "style-src 'self' 'unsafe-inline' https://api.fontshare.com https://fonts.googleapis.com",
37
+ `img-src ${img}`,
38
+ "connect-src 'self'",
39
+ "font-src 'self' https://cdn.fontshare.com https://fonts.gstatic.com",
40
+ `frame-src ${frame}`,
41
+ "object-src 'none'",
42
+ "frame-ancestors 'none'",
43
+ "base-uri 'self'",
44
+ "form-action 'self'"
45
+ ].join('; ');
46
+ }
47
+ /**
48
+ * The HSTS header for this instance, or null when it must not be sent.
49
+ * Only an https PUBLIC_BASE_URL arms it: a browser MUST ignore HSTS received
50
+ * over plain http (RFC 6797 §7.2), and pinning an http-only self-host into
51
+ * https for 180 days would brick it. `HSTS_MAX_AGE=0` is the operator opt-out
52
+ * (e.g. a subdomain that cannot yet serve TLS).
53
+ */
54
+ export function hstsValue(env) {
55
+ if (env.HSTS_MAX_AGE <= 0)
56
+ return null;
57
+ let isHttps = false;
58
+ try {
59
+ isHttps = new URL(env.PUBLIC_BASE_URL).protocol === 'https:';
60
+ }
61
+ catch {
62
+ isHttps = false;
63
+ }
64
+ if (!isHttps)
65
+ return null;
66
+ return `max-age=${env.HSTS_MAX_AGE}; includeSubDomains`;
67
+ }
68
+ export function securityHeaders({ csp, state, hsts }) {
69
+ return async (c, next) => {
70
+ await next();
71
+ c.header('x-content-type-options', 'nosniff');
72
+ // HSTS on EVERY response, not just HTML: the cookie this origin issues is
73
+ // sent with XHR too, so an http downgrade on /api/v1 is the same theft.
74
+ if (hsts && !c.res.headers.has('strict-transport-security')) {
75
+ c.header('strict-transport-security', hsts);
76
+ }
77
+ // Baseline defaults, but NEVER clobber a value a route set for itself:
78
+ // the public viewer (ADR 012) serves user-authored HTML under its own
79
+ // `Content-Security-Policy: sandbox …` + `Referrer-Policy: no-referrer`,
80
+ // and an unconditional overwrite here would silently replace the sandbox
81
+ // CSP with the dashboard CSP — re-opening the session-theft surface the
82
+ // sandbox exists to close (found by the ADR 012 spike; fail-dangerous
83
+ // class, see the ADR's residual-risk #1 and the viewer regression tests).
84
+ if (!c.res.headers.has('referrer-policy')) {
85
+ c.header('referrer-policy', 'strict-origin-when-cross-origin');
86
+ }
87
+ // Draining: ask keep-alive clients to reconnect elsewhere (rolling deploy).
88
+ if (state.draining)
89
+ c.header('connection', 'close');
90
+ const contentType = c.res.headers.get('content-type') ?? '';
91
+ if (contentType.includes('text/html') && !c.res.headers.has('content-security-policy')) {
92
+ c.header('content-security-policy', csp);
93
+ }
94
+ };
95
+ }
96
+ //# sourceMappingURL=security-headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-headers.js","sourceRoot":"","sources":["../../src/middleware/security-headers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { type Otel, createOtel } from './otel.js';
2
+ export { createMetrics } from './metrics.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createOtel } from './otel.js';
2
+ export { createMetrics } from './metrics.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { Registry } from 'prom-client';
2
+ import type { MiddlewareHandler } from 'hono';
3
+ import { Hono } from 'hono';
4
+ import { type Db } from '@antasphere/chassis-db';
5
+ import type PgBoss from 'pg-boss';
6
+ /**
7
+ * Prometheus surface. Route labels use the MATCHED pattern (not the raw
8
+ * path) so label cardinality stays bounded. Queue depth and storage bytes
9
+ * are collected lazily at scrape time.
10
+ */
11
+ export interface Metrics {
12
+ registry: Registry;
13
+ middleware: MiddlewareHandler;
14
+ routes: (token: string | undefined) => Hono;
15
+ }
16
+ export declare function createMetrics(db: Db, boss: PgBoss): Metrics;
17
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/observability/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,QAAQ,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAS,KAAK,EAAE,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAKlC;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;CAC7C;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAgF3D"}
@@ -0,0 +1,82 @@
1
+ import { collectDefaultMetrics, Gauge, Histogram, Registry } from 'prom-client';
2
+ import { Hono } from 'hono';
3
+ import { sql } from 'drizzle-orm';
4
+ import { files } from '@antasphere/chassis-db';
5
+ import { constantTimeEquals } from '../constant-time.js';
6
+ import { USAGE_QUEUE } from '../jobs/pgboss.js';
7
+ import { routeLabel } from '../route-label.js';
8
+ export function createMetrics(db, boss) {
9
+ const registry = new Registry();
10
+ collectDefaultMetrics({ register: registry });
11
+ const httpDuration = new Histogram({
12
+ name: 'http_request_duration_seconds',
13
+ help: 'HTTP request latency by route',
14
+ labelNames: ['method', 'route', 'status'],
15
+ buckets: [0.005, 0.02, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5],
16
+ registers: [registry]
17
+ });
18
+ new Gauge({
19
+ name: 'job_queue_depth',
20
+ help: 'Pending jobs in the usage queue',
21
+ registers: [registry],
22
+ async collect() {
23
+ try {
24
+ this.set((await boss.getQueueSize(USAGE_QUEUE)) ?? 0);
25
+ }
26
+ catch {
27
+ // queue may not exist yet (api-only role before first worker boot)
28
+ }
29
+ }
30
+ });
31
+ new Gauge({
32
+ name: 'storage_bytes_total',
33
+ help: 'Bytes referenced by live file rows',
34
+ registers: [registry],
35
+ async collect() {
36
+ const [row] = await db
37
+ .select({ total: sql `coalesce(sum(${files.sizeBytes}), 0)::text` })
38
+ .from(files)
39
+ .where(sql `${files.deletedAt} IS NULL`);
40
+ this.set(Number(row?.total ?? '0'));
41
+ }
42
+ });
43
+ const middleware = async (c, next) => {
44
+ const start = performance.now();
45
+ try {
46
+ await next();
47
+ }
48
+ finally {
49
+ const seconds = (performance.now() - start) / 1000;
50
+ httpDuration.observe({
51
+ method: c.req.method,
52
+ // routeLabel, same as the log line and the span: on the pinned
53
+ // Hono the previous `?? c.req.path` fallback was unreachable
54
+ // (routePath always answers a string here), but a raw-path
55
+ // expression in a label position is exactly what must not come
56
+ // back to life on a version bump — one shared, secret-free
57
+ // label instead (PRIV-1).
58
+ route: routeLabel(c),
59
+ status: String(c.error ? 500 : c.res.status)
60
+ }, seconds);
61
+ }
62
+ };
63
+ const routes = (token) => {
64
+ const app = new Hono();
65
+ app.get('/metrics', async (c) => {
66
+ // Default-closed: route names, queue depth, and storage totals are not
67
+ // for the open internet. setup.sh generates a METRICS_TOKEN.
68
+ if (!token) {
69
+ return c.text('metrics disabled: set METRICS_TOKEN', 401);
70
+ }
71
+ const auth = c.req.header('authorization') ?? '';
72
+ if (!constantTimeEquals(auth, `Bearer ${token}`)) {
73
+ return c.text('unauthorized', 401);
74
+ }
75
+ c.header('content-type', registry.contentType);
76
+ return c.body(await registry.metrics());
77
+ });
78
+ return app;
79
+ };
80
+ return { registry, middleware, routes };
81
+ }
82
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/observability/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEhF,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,KAAK,EAAW,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAa/C,MAAM,UAAU,aAAa,CAAC,EAAM,EAAE,IAAY;IAChD,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAChC,qBAAqB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE9C,MAAM,YAAY,GAAG,IAAI,SAAS,CAAC;QACjC,IAAI,EAAE,+BAA+B;QACrC,IAAI,EAAE,+BAA+B;QACrC,UAAU,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAU;QAClD,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACvD,SAAS,EAAE,CAAC,QAAQ,CAAC;KACtB,CAAC,CAAC;IAEH,IAAI,KAAK,CAAC;QACR,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,iCAAiC;QACvC,SAAS,EAAE,CAAC,QAAQ,CAAC;QACrB,KAAK,CAAC,OAAO;YACX,IAAI,CAAC;gBACH,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,mEAAmE;YACrE,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,KAAK,CAAC;QACR,IAAI,EAAE,qBAAqB;QAC3B,IAAI,EAAE,oCAAoC;QAC1C,SAAS,EAAE,CAAC,QAAQ,CAAC;QACrB,KAAK,CAAC,OAAO;YACX,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE;iBACnB,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAQ,gBAAgB,KAAK,CAAC,SAAS,aAAa,EAAE,CAAC;iBAC1E,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CAAC,GAAG,CAAA,GAAG,KAAK,CAAC,SAAS,UAAU,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC;QACtC,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,UAAU,GAAsB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACtD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC;YACnD,YAAY,CAAC,OAAO,CAClB;gBACE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM;gBACpB,+DAA+D;gBAC/D,6DAA6D;gBAC7D,2DAA2D;gBAC3D,+DAA+D;gBAC/D,2DAA2D;gBAC3D,0BAA0B;gBAC1B,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;gBACpB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;aAC7C,EACD,OAAO,CACR,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,KAAyB,EAAQ,EAAE;QACjD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YAC9B,uEAAuE;YACvE,6DAA6D;YAC7D,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,CAAC,IAAI,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAC;YAC5D,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;YACjD,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,UAAU,KAAK,EAAE,CAAC,EAAE,CAAC;gBACjD,OAAO,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;YACrC,CAAC;YACD,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;YAC/C,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IAEF,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type Tracer } from '@opentelemetry/api';
2
+ import type { MiddlewareHandler } from 'hono';
3
+ import type { Env } from '../env.js';
4
+ import type { Logger } from '../logger.js';
5
+ /**
6
+ * Tracing with the zero-phone-home default: spans are recorded ONLY when an
7
+ * operator configures OTEL_EXPORTER_OTLP_ENDPOINT — without it no exporter
8
+ * is registered and nothing leaves the instance. The request id rides every
9
+ * span as `request.id`, which is the correlation key across log line, span,
10
+ * and audit row.
11
+ */
12
+ export interface Otel {
13
+ tracer: Tracer;
14
+ middleware: MiddlewareHandler;
15
+ shutdown: () => Promise<void>;
16
+ }
17
+ export declare function createOtel(env: Pick<Env, 'OTEL_EXPORTER_OTLP_ENDPOINT' | 'APP_VERSION' | 'EDITION'>, logger: Logger, options: {
18
+ serviceName: string;
19
+ }): Promise<Otel>;
20
+ //# sourceMappingURL=otel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.d.ts","sourceRoot":"","sources":["../../src/observability/otel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAIxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C;;;;;;GAMG;AACH,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,iBAAiB,CAAC;IAC9B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,wBAAsB,UAAU,CAC9B,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,6BAA6B,GAAG,aAAa,GAAG,SAAS,CAAC,EACzE,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAC/B,OAAO,CAAC,IAAI,CAAC,CAoDf"}
@@ -0,0 +1,54 @@
1
+ import { trace } from '@opentelemetry/api';
2
+ import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
3
+ import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
4
+ import { resourceFromAttributes } from '@opentelemetry/resources';
5
+ import { routeLabel } from '../route-label.js';
6
+ export async function createOtel(env, logger, options) {
7
+ const resource = resourceFromAttributes({
8
+ 'service.name': options.serviceName,
9
+ 'service.version': env.APP_VERSION,
10
+ 'deployment.environment.name': env.EDITION
11
+ });
12
+ const spanProcessors = [];
13
+ if (env.OTEL_EXPORTER_OTLP_ENDPOINT) {
14
+ const { OTLPTraceExporter } = await import('@opentelemetry/exporter-trace-otlp-http');
15
+ spanProcessors.push(new BatchSpanProcessor(new OTLPTraceExporter({ url: `${env.OTEL_EXPORTER_OTLP_ENDPOINT}/v1/traces` })));
16
+ logger.info({ endpoint: env.OTEL_EXPORTER_OTLP_ENDPOINT }, 'otel export enabled');
17
+ }
18
+ const provider = new NodeTracerProvider({ resource, spanProcessors });
19
+ provider.register();
20
+ const tracer = trace.getTracer(options.serviceName);
21
+ const middleware = async (c, next) => {
22
+ // Start with a low-cardinality name (the matched route pattern isn't known
23
+ // until after routing); rename to the pattern in `finally` so span names
24
+ // stay bounded — a raw path with ids would explode span cardinality.
25
+ await tracer.startActiveSpan(`HTTP ${c.req.method}`, async (span) => {
26
+ span.setAttributes({
27
+ 'http.request.method': c.req.method,
28
+ 'request.id': c.get('requestId')
29
+ });
30
+ try {
31
+ await next();
32
+ }
33
+ finally {
34
+ // The MATCHED ROUTE PATTERN, never the raw path (route-label.ts): a
35
+ // span attribute is exported OFF-INSTANCE, so a `/v/<share secret>`
36
+ // there hands a working capability to the trace backend.
37
+ const route = routeLabel(c);
38
+ span.updateName(`${c.req.method} ${route}`);
39
+ span.setAttributes({
40
+ 'http.route': route,
41
+ 'url.path': route,
42
+ 'http.response.status_code': c.error ? 500 : c.res.status
43
+ });
44
+ span.end();
45
+ }
46
+ });
47
+ };
48
+ return {
49
+ tracer,
50
+ middleware,
51
+ shutdown: () => provider.shutdown()
52
+ };
53
+ }
54
+ //# sourceMappingURL=otel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.js","sourceRoot":"","sources":["../../src/observability/otel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAe,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAIlE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAe/C,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAyE,EACzE,MAAc,EACd,OAAgC;IAEhC,MAAM,QAAQ,GAAG,sBAAsB,CAAC;QACtC,cAAc,EAAE,OAAO,CAAC,WAAW;QACnC,iBAAiB,EAAE,GAAG,CAAC,WAAW;QAClC,6BAA6B,EAAE,GAAG,CAAC,OAAO;KAC3C,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,EAAE,CAAC;IAC1B,IAAI,GAAG,CAAC,2BAA2B,EAAE,CAAC;QACpC,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,yCAAyC,CAAC,CAAC;QACtF,cAAc,CAAC,IAAI,CACjB,IAAI,kBAAkB,CAAC,IAAI,iBAAiB,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,2BAA2B,YAAY,EAAE,CAAC,CAAC,CACvG,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,2BAA2B,EAAE,EAAE,qBAAqB,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,kBAAkB,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;IACtE,QAAQ,CAAC,QAAQ,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAEpD,MAAM,UAAU,GAAsB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACtD,2EAA2E;QAC3E,yEAAyE;QACzE,qEAAqE;QACrE,MAAM,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YAClE,IAAI,CAAC,aAAa,CAAC;gBACjB,qBAAqB,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM;gBACnC,YAAY,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;aACjC,CAAC,CAAC;YACH,IAAI,CAAC;gBACH,MAAM,IAAI,EAAE,CAAC;YACf,CAAC;oBAAS,CAAC;gBACT,oEAAoE;gBACpE,oEAAoE;gBACpE,yDAAyD;gBACzD,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;gBAC5C,IAAI,CAAC,aAAa,CAAC;oBACjB,YAAY,EAAE,KAAK;oBACnB,UAAU,EAAE,KAAK;oBACjB,2BAA2B,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM;iBAC1D,CAAC,CAAC;gBACH,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO;QACL,MAAM;QACN,UAAU;QACV,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE;KACpC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { type SQL } from 'drizzle-orm';
2
+ import type { PgColumn, PgTable } from 'drizzle-orm/pg-core';
3
+ /**
4
+ * Shared UUID shape check — cursors here, and the id params of the
5
+ * plain-Hono routes that have no contract schema (files content/HEAD): a
6
+ * non-UUID string must be rejected before it reaches Postgres' uuid cast.
7
+ */
8
+ export declare function isUuid(value: string): boolean;
9
+ /**
10
+ * The cursor row id, or null when absent/malformed. A malformed cursor is
11
+ * silently ignored — the caller serves page 1 (the audit route's
12
+ * `Number('banana')` tolerance).
13
+ */
14
+ export declare function cursorRowId(cursor: string | undefined): string | null;
15
+ /**
16
+ * Row-value keyset predicate: everything strictly older than the cursor row,
17
+ * with the cursor row's (created_at, id) resolved by a SQL-side subquery.
18
+ * The subquery is workspace-scoped so a foreign workspace's cursor can never
19
+ * position inside this workspace's ordering. A well-formed-but-unknown id
20
+ * makes the subquery empty → NULL predicate → empty page + nextCursor null;
21
+ * harmless, since cursors are server-issued and these tables never
22
+ * hard-delete rows.
23
+ */
24
+ export declare function keysetBefore(opts: {
25
+ table: PgTable;
26
+ id: PgColumn;
27
+ createdAt: PgColumn;
28
+ workspaceId: PgColumn;
29
+ cursorId: string;
30
+ workspace: string;
31
+ }): SQL;
32
+ /** Slice a limit+1 fetch into the page + the audit-style nextCursor (last id of the page). */
33
+ export declare function pageOf<T extends {
34
+ id: string;
35
+ }>(rows: T[], limit: number): {
36
+ page: T[];
37
+ nextCursor: string | null;
38
+ };
39
+ export interface KeysetValueCursor {
40
+ /** `created_at::text`, exactly as Postgres rendered it. */
41
+ createdAt: string;
42
+ id: string;
43
+ }
44
+ export declare function encodeKeysetCursor(row: {
45
+ id: string;
46
+ createdAtText: string;
47
+ }): string;
48
+ export declare function decodeKeysetCursor(cursor: string | undefined): KeysetValueCursor | null;
49
+ /** The `created_at::text` column to select beside a row that will mint a value cursor. */
50
+ export declare function createdAtText(createdAt: PgColumn): SQL<string>;
51
+ /** `(created_at, id) < (cursor)` with the cursor's own values; `keysetBefore`'s twin for hard-deleting tables. */
52
+ export declare function keysetBeforeValue(opts: {
53
+ id: PgColumn;
54
+ createdAt: PgColumn;
55
+ cursor: KeysetValueCursor;
56
+ }): SQL;
57
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,GAAG,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAsB7D;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAGrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,EAAE,EAAE,QAAQ,CAAC;IACb,SAAS,EAAE,QAAQ,CAAC;IACpB,WAAW,EAAE,QAAQ,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,GAAG,CAEN;AAED,8FAA8F;AAC9F,wBAAgB,MAAM,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAC7C,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,EAAE,MAAM,GACZ;IAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAI1C;AAUD,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAErF;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,iBAAiB,GAAG,IAAI,CAavF;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,SAAS,EAAE,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,CAE9D;AAED,kHAAkH;AAClH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,EAAE,EAAE,QAAQ,CAAC;IACb,SAAS,EAAE,QAAQ,CAAC;IACpB,MAAM,EAAE,iBAAiB,CAAC;CAC3B,GAAG,GAAG,CAEN"}
@@ -0,0 +1,90 @@
1
+ import { sql } from 'drizzle-orm';
2
+ /**
3
+ * Keyset (cursor) pagination over (created_at, id), newest first — the audit
4
+ * route's convention extended to the uuid-keyed tables. Two cursor dialects,
5
+ * one rule: the timestamp's precision never leaves Postgres, because a JS
6
+ * Date round-trip truncates its microseconds and a millisecond-equal
7
+ * boundary row would then be skipped or repeated.
8
+ *
9
+ * - `keysetBefore`: the cursor is the last returned row's plain id, and the
10
+ * timestamp is resolved from that row by subquery at page time. For the
11
+ * tables that never hard-delete a row (members are deactivated, keys and
12
+ * invitations revoked, projects archived): the cursor row is always there.
13
+ * - `keysetBeforeValue`: the cursor CARRIES the timestamp, as the text
14
+ * Postgres itself rendered (`created_at::text`, selected beside the row,
15
+ * never a JS Date), with the id. For a table that hard-deletes rows
16
+ * (project_members): a cursor naming a removed row would compare against
17
+ * NULL under the subquery dialect and end the listing early.
18
+ */
19
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
20
+ /**
21
+ * Shared UUID shape check — cursors here, and the id params of the
22
+ * plain-Hono routes that have no contract schema (files content/HEAD): a
23
+ * non-UUID string must be rejected before it reaches Postgres' uuid cast.
24
+ */
25
+ export function isUuid(value) {
26
+ return UUID_RE.test(value);
27
+ }
28
+ /**
29
+ * The cursor row id, or null when absent/malformed. A malformed cursor is
30
+ * silently ignored — the caller serves page 1 (the audit route's
31
+ * `Number('banana')` tolerance).
32
+ */
33
+ export function cursorRowId(cursor) {
34
+ if (!cursor || !isUuid(cursor))
35
+ return null;
36
+ return cursor;
37
+ }
38
+ /**
39
+ * Row-value keyset predicate: everything strictly older than the cursor row,
40
+ * with the cursor row's (created_at, id) resolved by a SQL-side subquery.
41
+ * The subquery is workspace-scoped so a foreign workspace's cursor can never
42
+ * position inside this workspace's ordering. A well-formed-but-unknown id
43
+ * makes the subquery empty → NULL predicate → empty page + nextCursor null;
44
+ * harmless, since cursors are server-issued and these tables never
45
+ * hard-delete rows.
46
+ */
47
+ export function keysetBefore(opts) {
48
+ return sql `(${opts.createdAt}, ${opts.id}) < (SELECT ${opts.createdAt}, ${opts.id} FROM ${opts.table} WHERE ${opts.id} = ${opts.cursorId} AND ${opts.workspaceId} = ${opts.workspace})`;
49
+ }
50
+ /** Slice a limit+1 fetch into the page + the audit-style nextCursor (last id of the page). */
51
+ export function pageOf(rows, limit) {
52
+ const page = rows.slice(0, limit);
53
+ const nextCursor = rows.length > limit ? (page[page.length - 1]?.id ?? null) : null;
54
+ return { page, nextCursor };
55
+ }
56
+ /**
57
+ * The value-carrying cursor (`keysetBeforeValue`): the row's `created_at` as
58
+ * Postgres rendered it and its id, base64url of `<text>|<id>`. Opaque on the
59
+ * wire like the other dialect; a malformed one is ignored (page 1).
60
+ */
61
+ const TIMESTAMPTZ_TEXT_RE = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d{1,6})?[+-]\d{2}(?::\d{2}(?::\d{2})?)?$/;
62
+ export function encodeKeysetCursor(row) {
63
+ return Buffer.from(`${row.createdAtText}|${row.id}`, 'utf8').toString('base64url');
64
+ }
65
+ export function decodeKeysetCursor(cursor) {
66
+ if (!cursor || cursor.length > 200)
67
+ return null;
68
+ // Node's base64url decoder never throws (it drops what it cannot read):
69
+ // the guard is the two shape checks below, not the decode.
70
+ const decoded = Buffer.from(cursor, 'base64url').toString('utf8');
71
+ const at = decoded.lastIndexOf('|');
72
+ if (at < 0)
73
+ return null;
74
+ const createdAt = decoded.slice(0, at);
75
+ const id = decoded.slice(at + 1);
76
+ // Both halves are validated before they reach a Postgres cast: a shape the
77
+ // casts would refuse must answer page 1, never a 500.
78
+ if (!TIMESTAMPTZ_TEXT_RE.test(createdAt) || !isUuid(id))
79
+ return null;
80
+ return { createdAt, id };
81
+ }
82
+ /** The `created_at::text` column to select beside a row that will mint a value cursor. */
83
+ export function createdAtText(createdAt) {
84
+ return sql `${createdAt}::text`;
85
+ }
86
+ /** `(created_at, id) < (cursor)` with the cursor's own values; `keysetBefore`'s twin for hard-deleting tables. */
87
+ export function keysetBeforeValue(opts) {
88
+ return sql `(${opts.createdAt}, ${opts.id}) < (${opts.cursor.createdAt}::timestamptz, ${opts.cursor.id}::uuid)`;
89
+ }
90
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import type { Db } from '@antasphere/chassis-db';
2
+ import type { EntitlementService, IdentityProvider, UsageSink } from '@antasphere/chassis-contract';
3
+ import type { HubOrgReconciler } from '../identity/hub-reconcile.js';
4
+ import type { PrincipalGate } from '../middleware/auth-context.js';
5
+ import type { HubConfig } from '../env.js';
6
+ import type { Logger } from '../logger.js';
7
+ /**
8
+ * The edition split (internal/federation.md): one codebase, one Docker image,
9
+ * two seam bindings selected purely by instance config. This module is the
10
+ * ONLY place edition decides which implementations the boot-time registry
11
+ * gets — `oss` binds the local defaults byte-identically; `cloud` rebinds
12
+ * the hub-federating variants here.
13
+ */
14
+ /**
15
+ * The hub SSO method name the cloud edition advertises in discovery — the
16
+ * better-auth `genericOAuth` providerId registered by identity/hub-sso.ts
17
+ * (its callback lands on /api/v1/auth/oauth2/callback/antasphere, the
18
+ * redirect URI in the hub's TOOL_REGISTRY entry).
19
+ */
20
+ export declare const HUB_SSO_METHOD = "antasphere";
21
+ /** The three registry seams the edition owns (events/workspaces are edition-independent). */
22
+ export interface EditionSeams {
23
+ identity: IdentityProvider;
24
+ entitlements: EntitlementService;
25
+ usage: UsageSink;
26
+ }
27
+ /** What the cloud bindings need beyond the seams themselves. */
28
+ export interface EditionBindingDeps {
29
+ db: Db;
30
+ /**
31
+ * The live org reconciler (identity/hub-reconcile.ts), constructed by
32
+ * boot on cloud — the ONE hub data path, shared by the login pass, the
33
+ * live gate, and the unknown-workspace miss hook.
34
+ */
35
+ reconciler?: HubOrgReconciler | undefined;
36
+ }
37
+ /**
38
+ * The bound seams plus the cloud-only extra boot wires alongside them: the
39
+ * post-resolution principal gate (authContext). Absent on oss by
40
+ * construction.
41
+ */
42
+ export interface BoundEditionSeams extends EditionSeams {
43
+ principalGate?: PrincipalGate;
44
+ }
45
+ /**
46
+ * Bind the registry seams for this instance's edition. `hub` is the single
47
+ * switch: null (EDITION=oss) returns the local defaults UNTOUCHED — the
48
+ * self-host edition carries zero hub surface at runtime; a HubConfig
49
+ * (EDITION=cloud, validated at env parse) selects the cloud bindings.
50
+ *
51
+ * Entitlements bind LOCAL on BOTH editions: the live gate refuses a
52
+ * suspended/revoked/unavailable principal at the door, before any handler
53
+ * or entitlement check runs — a hub-wrapping entitlement layer would be a
54
+ * second, redundant enforcement path.
55
+ */
56
+ export declare function bindEditionSeams(hub: HubConfig | null, local: EditionSeams, logger: Logger, deps: EditionBindingDeps): BoundEditionSeams;
57
+ //# sourceMappingURL=edition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edition.d.ts","sourceRoot":"","sources":["../../src/platform/edition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAIhB,SAAS,EACV,MAAM,8BAA8B,CAAC;AAGtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C;;;;;;GAMG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,cAAc,eAAsB,CAAC;AA2ClD,6FAA6F;AAC7F,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,YAAY,EAAE,kBAAkB,CAAC;IACjC,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,gEAAgE;AAChE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,EAAE,CAAC;IACP;;;;OAIG;IACH,UAAU,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CAC3C;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,SAAS,GAAG,IAAI,EACrB,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,kBAAkB,GACvB,iBAAiB,CAuBnB"}
@@ -0,0 +1,90 @@
1
+ import { HUB_SSO_PROVIDER_ID } from '../identity/hub-sso.js';
2
+ import { HubLiveGate } from '../identity/hub-live-gate.js';
3
+ /**
4
+ * The edition split (internal/federation.md): one codebase, one Docker image,
5
+ * two seam bindings selected purely by instance config. This module is the
6
+ * ONLY place edition decides which implementations the boot-time registry
7
+ * gets — `oss` binds the local defaults byte-identically; `cloud` rebinds
8
+ * the hub-federating variants here.
9
+ */
10
+ /**
11
+ * The hub SSO method name the cloud edition advertises in discovery — the
12
+ * better-auth `genericOAuth` providerId registered by identity/hub-sso.ts
13
+ * (its callback lands on /api/v1/auth/oauth2/callback/antasphere, the
14
+ * redirect URI in the hub's TOOL_REGISTRY entry).
15
+ */
16
+ export const HUB_SSO_METHOD = HUB_SSO_PROVIDER_ID;
17
+ /**
18
+ * The cloud identity binding. Request RESOLUTION stays exactly the local
19
+ * provider's — after the SSO callback mints an ordinary session, every
20
+ * request is sessions + live membership re-check (the live hub gate runs
21
+ * post-resolution in authContext, not here). What changes is the ADVERTISED
22
+ * entrance (D1, hub-only human login):
23
+ *
24
+ * - `antasphere` replaces password/email-otp/google — the login page
25
+ * renders ONLY "Sign in with Antasphere". The local password machinery
26
+ * stays WIRED (hidden, not blocked): the break-glass CLI remains the
27
+ * operator door, and blocking /sign-in/email would dead-end it.
28
+ * - `passwordReset`/`emailChange` are off: credentials and email are the
29
+ * HUB's to manage (D10 re-syncs email at every login); a local reset
30
+ * surface would fight the sync. Since the P8 close (ADR 017) the reset
31
+ * routes don't just report false — they REFUSE on cloud (403; the
32
+ * before-hook in identity/better-auth.ts + the members reset-link mint),
33
+ * so a hub-JIT user can never SET a local password and sidestep SSO.
34
+ * - `twoFactor` is off: the second factor guards local password/OTP
35
+ * sign-ins, which the cloud page no longer offers — MFA is the hub's
36
+ * concern at its own login.
37
+ */
38
+ class HubSsoIdentityProvider {
39
+ local;
40
+ constructor(local) {
41
+ this.local = local;
42
+ }
43
+ resolve(ctx) {
44
+ return this.local.resolve(ctx);
45
+ }
46
+ describe() {
47
+ return {
48
+ // Machine entrances are edition-independent; the human entrance is
49
+ // hub-only. 'oauth' stays: every instance is its own OAuth 2.1 AS for
50
+ // /mcp — the hub never appears in the MCP dance.
51
+ methods: [HUB_SSO_METHOD, 'api-key', 'oauth'],
52
+ passwordReset: false,
53
+ emailChange: false,
54
+ twoFactor: false
55
+ };
56
+ }
57
+ }
58
+ /**
59
+ * Bind the registry seams for this instance's edition. `hub` is the single
60
+ * switch: null (EDITION=oss) returns the local defaults UNTOUCHED — the
61
+ * self-host edition carries zero hub surface at runtime; a HubConfig
62
+ * (EDITION=cloud, validated at env parse) selects the cloud bindings.
63
+ *
64
+ * Entitlements bind LOCAL on BOTH editions: the live gate refuses a
65
+ * suspended/revoked/unavailable principal at the door, before any handler
66
+ * or entitlement check runs — a hub-wrapping entitlement layer would be a
67
+ * second, redundant enforcement path.
68
+ */
69
+ export function bindEditionSeams(hub, local, logger, deps) {
70
+ if (!hub)
71
+ return local;
72
+ logger.info({ hubIssuer: hub.issuerUrl }, 'EDITION=cloud: hub SSO is the human entrance (identity resolution stays local sessions); ' +
73
+ 'org/membership truth is reconciled live AS THE USER via each user’s own hub grant ' +
74
+ '(internal/federation.md).');
75
+ const gate = deps.reconciler
76
+ ? new HubLiveGate({ db: deps.db, reconciler: deps.reconciler, logger })
77
+ : undefined;
78
+ return {
79
+ // Hub-only entrance advertised; the SSO machinery itself (relying
80
+ // party, JIT, login reconcile) lives in identity/hub-sso.ts and is
81
+ // wired through createAuth — resolution stays local by design.
82
+ identity: new HubSsoIdentityProvider(local.identity),
83
+ entitlements: local.entitlements,
84
+ // D6: usage stays the local sink with a no-op downstream for v1; hub
85
+ // ingest is a one-class downstream swap when it ships (plan §4.3).
86
+ usage: local.usage,
87
+ ...(gate ? { principalGate: gate.assert } : {})
88
+ };
89
+ }
90
+ //# sourceMappingURL=edition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edition.js","sourceRoot":"","sources":["../../src/platform/edition.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAM3D;;;;;;GAMG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,sBAAsB;IACG;IAA7B,YAA6B,KAAuB;QAAvB,UAAK,GAAL,KAAK,CAAkB;IAAG,CAAC;IAExD,OAAO,CAAC,GAAmB;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,QAAQ;QACN,OAAO;YACL,mEAAmE;YACnE,sEAAsE;YACtE,iDAAiD;YACjD,OAAO,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,OAAO,CAAC;YAC7C,aAAa,EAAE,KAAK;YACpB,WAAW,EAAE,KAAK;YAClB,SAAS,EAAE,KAAK;SACjB,CAAC;IACJ,CAAC;CACF;AA6BD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAqB,EACrB,KAAmB,EACnB,MAAc,EACd,IAAwB;IAExB,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IAEvB,MAAM,CAAC,IAAI,CACT,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,EAC5B,2FAA2F;QACzF,oFAAoF;QACpF,2BAA2B,CAC9B,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU;QAC1B,CAAC,CAAC,IAAI,WAAW,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;QACvE,CAAC,CAAC,SAAS,CAAC;IACd,OAAO;QACL,kEAAkE;QAClE,mEAAmE;QACnE,+DAA+D;QAC/D,QAAQ,EAAE,IAAI,sBAAsB,CAAC,KAAK,CAAC,QAAQ,CAAC;QACpD,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,qEAAqE;QACrE,mEAAmE;QACnE,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC;AACJ,CAAC"}