tapimo 0.10.2 → 0.12.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 (386) hide show
  1. package/dist/App.d.ts +4896 -2166
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/App.js +2 -2
  4. package/dist/App.js.map +1 -1
  5. package/dist/Assets.d.ts +15 -0
  6. package/dist/Assets.d.ts.map +1 -1
  7. package/dist/Assets.js +7 -0
  8. package/dist/Assets.js.map +1 -1
  9. package/dist/Webhooks.d.ts +0 -75
  10. package/dist/Webhooks.d.ts.map +1 -1
  11. package/dist/Webhooks.js +1 -143
  12. package/dist/Webhooks.js.map +1 -1
  13. package/dist/admin/App.d.ts +127 -78
  14. package/dist/admin/App.d.ts.map +1 -1
  15. package/dist/admin/apps/earn-vaults.d.ts +115 -1
  16. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  17. package/dist/admin/apps/earn-vaults.js +59 -6
  18. package/dist/admin/apps/earn-vaults.js.map +1 -1
  19. package/dist/admin/apps/organizations.d.ts +3 -3
  20. package/dist/admin/apps/organizations.d.ts.map +1 -1
  21. package/dist/admin/apps/organizations.js +4 -2
  22. package/dist/admin/apps/organizations.js.map +1 -1
  23. package/dist/admin/apps/verified-tokens.d.ts +83 -83
  24. package/dist/admin/ui.generated.d.ts +1 -1
  25. package/dist/admin/ui.generated.d.ts.map +1 -1
  26. package/dist/admin/ui.generated.js +151 -151
  27. package/dist/admin/ui.generated.js.map +1 -1
  28. package/dist/apps/data/App.d.ts +5924 -4310
  29. package/dist/apps/data/App.d.ts.map +1 -1
  30. package/dist/apps/data/App.js +61 -9
  31. package/dist/apps/data/App.js.map +1 -1
  32. package/dist/apps/data/ZoneSelection.d.ts +62 -0
  33. package/dist/apps/data/ZoneSelection.d.ts.map +1 -0
  34. package/dist/apps/data/ZoneSelection.js +44 -0
  35. package/dist/apps/data/ZoneSelection.js.map +1 -0
  36. package/dist/apps/data/routes/activities.d.ts +2368 -5
  37. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  38. package/dist/apps/data/routes/activities.js +423 -114
  39. package/dist/apps/data/routes/activities.js.map +1 -1
  40. package/dist/apps/data/routes/addresses.d.ts +131 -0
  41. package/dist/apps/data/routes/addresses.d.ts.map +1 -1
  42. package/dist/apps/data/routes/balances.d.ts +25 -25
  43. package/dist/apps/data/routes/balances.js +1 -1
  44. package/dist/apps/data/routes/balances.js.map +1 -1
  45. package/dist/apps/data/routes/blocks.d.ts +1 -1
  46. package/dist/apps/data/routes/blocks.js +1 -1
  47. package/dist/apps/data/routes/blocks.js.map +1 -1
  48. package/dist/apps/data/routes/earn.d.ts +135 -10
  49. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  50. package/dist/apps/data/routes/earn.js +157 -25
  51. package/dist/apps/data/routes/earn.js.map +1 -1
  52. package/dist/apps/data/routes/exchanges.d.ts +829 -123
  53. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  54. package/dist/apps/data/routes/exchanges.js +16 -13
  55. package/dist/apps/data/routes/exchanges.js.map +1 -1
  56. package/dist/apps/data/routes/fee-amm.d.ts +26 -26
  57. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  58. package/dist/apps/data/routes/fee-amm.js +9 -11
  59. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  60. package/dist/apps/data/routes/receipts.d.ts +54 -54
  61. package/dist/apps/data/routes/receipts.js +1 -1
  62. package/dist/apps/data/routes/receipts.js.map +1 -1
  63. package/dist/apps/data/routes/rpc.js +24 -10
  64. package/dist/apps/data/routes/rpc.js.map +1 -1
  65. package/dist/apps/data/routes/tokenlist.d.ts +12 -12
  66. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
  67. package/dist/apps/data/routes/tokenlist.js +16 -15
  68. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  69. package/dist/apps/data/routes/tokens.d.ts +17 -3
  70. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  71. package/dist/apps/data/routes/tokens.js +34 -15
  72. package/dist/apps/data/routes/tokens.js.map +1 -1
  73. package/dist/apps/data/routes/transactions.d.ts +1 -1
  74. package/dist/apps/data/routes/transactions.js +1 -1
  75. package/dist/apps/data/routes/transactions.js.map +1 -1
  76. package/dist/apps/data/routes/transfers.d.ts +13 -13
  77. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  78. package/dist/apps/data/routes/transfers.js +7 -9
  79. package/dist/apps/data/routes/transfers.js.map +1 -1
  80. package/dist/apps/data/routes/valuation.d.ts +21 -21
  81. package/dist/apps/data/routes/verified-tokens.d.ts +5 -5
  82. package/dist/apps/data/routes/webhooks.d.ts +1011 -151
  83. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  84. package/dist/apps/data/routes/webhooks.js +126 -739
  85. package/dist/apps/data/routes/webhooks.js.map +1 -1
  86. package/dist/apps/data/routes/zones.d.ts +15 -15
  87. package/dist/apps/funding/App.d.ts +27 -27
  88. package/dist/apps/funding/routes/chains.d.ts.map +1 -1
  89. package/dist/apps/funding/routes/chains.js +5 -4
  90. package/dist/apps/funding/routes/chains.js.map +1 -1
  91. package/dist/apps/funding/routes/deposit-addresses.d.ts +18 -18
  92. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
  93. package/dist/apps/funding/routes/deposit-addresses.js +8 -8
  94. package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
  95. package/dist/apps/funding/routes/providers.d.ts.map +1 -1
  96. package/dist/apps/funding/routes/providers.js +3 -2
  97. package/dist/apps/funding/routes/providers.js.map +1 -1
  98. package/dist/apps/funding/routes/quotes.d.ts.map +1 -1
  99. package/dist/apps/funding/routes/quotes.js +2 -2
  100. package/dist/apps/funding/routes/quotes.js.map +1 -1
  101. package/dist/apps/funding/routes/transfers.d.ts +33 -33
  102. package/dist/apps/management/App.d.ts +1433 -322
  103. package/dist/apps/management/App.d.ts.map +1 -1
  104. package/dist/apps/management/Billing.d.ts.map +1 -1
  105. package/dist/apps/management/Billing.js +19 -6
  106. package/dist/apps/management/Billing.js.map +1 -1
  107. package/dist/apps/management/routes/api-keys.d.ts +154 -94
  108. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  109. package/dist/apps/management/routes/api-keys.js +76 -30
  110. package/dist/apps/management/routes/api-keys.js.map +1 -1
  111. package/dist/apps/management/routes/billing.d.ts +103 -30
  112. package/dist/apps/management/routes/billing.d.ts.map +1 -1
  113. package/dist/apps/management/routes/billing.js +91 -32
  114. package/dist/apps/management/routes/billing.js.map +1 -1
  115. package/dist/apps/management/routes/faucet.d.ts +12 -12
  116. package/dist/apps/management/routes/faucet.d.ts.map +1 -1
  117. package/dist/apps/management/routes/faucet.js +23 -12
  118. package/dist/apps/management/routes/faucet.js.map +1 -1
  119. package/dist/apps/management/routes/invitations.d.ts +46 -13
  120. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  121. package/dist/apps/management/routes/invitations.js +79 -29
  122. package/dist/apps/management/routes/invitations.js.map +1 -1
  123. package/dist/apps/management/routes/invite-links.d.ts +128 -83
  124. package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
  125. package/dist/apps/management/routes/invite-links.js +100 -41
  126. package/dist/apps/management/routes/invite-links.js.map +1 -1
  127. package/dist/apps/management/routes/me.d.ts +5 -5
  128. package/dist/apps/management/routes/me.d.ts.map +1 -1
  129. package/dist/apps/management/routes/me.js +14 -10
  130. package/dist/apps/management/routes/me.js.map +1 -1
  131. package/dist/apps/management/routes/members.d.ts +68 -47
  132. package/dist/apps/management/routes/members.d.ts.map +1 -1
  133. package/dist/apps/management/routes/members.js +37 -18
  134. package/dist/apps/management/routes/members.js.map +1 -1
  135. package/dist/apps/management/routes/orgs.d.ts +48 -8
  136. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  137. package/dist/apps/management/routes/orgs.js +48 -19
  138. package/dist/apps/management/routes/orgs.js.map +1 -1
  139. package/dist/apps/management/routes/projects.d.ts +130 -68
  140. package/dist/apps/management/routes/projects.d.ts.map +1 -1
  141. package/dist/apps/management/routes/projects.js +72 -21
  142. package/dist/apps/management/routes/projects.js.map +1 -1
  143. package/dist/apps/management/routes/scopes.d.ts.map +1 -1
  144. package/dist/apps/management/routes/scopes.js +8 -5
  145. package/dist/apps/management/routes/scopes.js.map +1 -1
  146. package/dist/apps/management/routes/usage.d.ts +38 -38
  147. package/dist/apps/management/routes/usage.d.ts.map +1 -1
  148. package/dist/apps/management/routes/usage.js +41 -31
  149. package/dist/apps/management/routes/usage.js.map +1 -1
  150. package/dist/apps/management/routes/verified-token-requests.d.ts +34 -6
  151. package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
  152. package/dist/apps/management/routes/verified-token-requests.js +36 -17
  153. package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
  154. package/dist/apps/management/routes/webhooks.d.ts +1186 -197
  155. package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
  156. package/dist/apps/management/routes/webhooks.js +106 -38
  157. package/dist/apps/management/routes/webhooks.js.map +1 -1
  158. package/dist/apps/mpp/internal/Adapter.d.ts +1 -1
  159. package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
  160. package/dist/apps/mpp/internal/Adapter.js +12 -0
  161. package/dist/apps/mpp/internal/Adapter.js.map +1 -1
  162. package/dist/db/Db.d.ts +2 -0
  163. package/dist/db/Db.d.ts.map +1 -1
  164. package/dist/db/Db.js +61 -0
  165. package/dist/db/Db.js.map +1 -1
  166. package/dist/db/Schema.d.ts +30 -2
  167. package/dist/db/Schema.d.ts.map +1 -1
  168. package/dist/db/Schema.js +28 -3
  169. package/dist/db/Schema.js.map +1 -1
  170. package/dist/db/tables/earnVaults.d.ts +5 -1
  171. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  172. package/dist/db/tables/earnVaults.js +5 -0
  173. package/dist/db/tables/earnVaults.js.map +1 -1
  174. package/dist/db/tables/webhookDeliveries.d.ts.map +1 -1
  175. package/dist/db/tables/webhookDeliveries.js +10 -0
  176. package/dist/db/tables/webhookDeliveries.js.map +1 -1
  177. package/dist/db/tables/webhookQueueCompletions.d.ts +15 -0
  178. package/dist/db/tables/webhookQueueCompletions.d.ts.map +1 -0
  179. package/dist/db/tables/webhookQueueCompletions.js +32 -0
  180. package/dist/db/tables/webhookQueueCompletions.js.map +1 -0
  181. package/dist/db/tables/webhookQueueEvents.d.ts +16 -20
  182. package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
  183. package/dist/db/tables/webhookQueueEvents.js +68 -43
  184. package/dist/db/tables/webhookQueueEvents.js.map +1 -1
  185. package/dist/db/tables/webhookSubscriptions.d.ts +47 -72
  186. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  187. package/dist/db/tables/webhookSubscriptions.js +92 -105
  188. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  189. package/dist/internal/Auth.d.ts +8 -1
  190. package/dist/internal/Auth.d.ts.map +1 -1
  191. package/dist/internal/Auth.js +13 -3
  192. package/dist/internal/Auth.js.map +1 -1
  193. package/dist/internal/Cache.d.ts.map +1 -1
  194. package/dist/internal/Cache.js +11 -7
  195. package/dist/internal/Cache.js.map +1 -1
  196. package/dist/internal/EarnVaults.d.ts +41 -2
  197. package/dist/internal/EarnVaults.d.ts.map +1 -1
  198. package/dist/internal/EarnVaults.js +167 -0
  199. package/dist/internal/EarnVaults.js.map +1 -1
  200. package/dist/internal/MetricSink.d.ts +35 -125
  201. package/dist/internal/MetricSink.d.ts.map +1 -1
  202. package/dist/internal/MetricSink.js +50 -121
  203. package/dist/internal/MetricSink.js.map +1 -1
  204. package/dist/internal/OpenApi.d.ts +26 -22
  205. package/dist/internal/OpenApi.d.ts.map +1 -1
  206. package/dist/internal/OpenApi.js +128 -39
  207. package/dist/internal/OpenApi.js.map +1 -1
  208. package/dist/internal/Response.d.ts +13 -8
  209. package/dist/internal/Response.d.ts.map +1 -1
  210. package/dist/internal/Response.js +16 -5
  211. package/dist/internal/Response.js.map +1 -1
  212. package/dist/internal/Schema.d.ts +8 -8
  213. package/dist/internal/Schema.d.ts.map +1 -1
  214. package/dist/internal/Schema.js +10 -9
  215. package/dist/internal/Schema.js.map +1 -1
  216. package/dist/internal/Store.d.ts +15 -6
  217. package/dist/internal/Store.d.ts.map +1 -1
  218. package/dist/internal/Store.js +45 -15
  219. package/dist/internal/Store.js.map +1 -1
  220. package/dist/internal/Tidx.d.ts +2 -0
  221. package/dist/internal/Tidx.d.ts.map +1 -1
  222. package/dist/internal/Tidx.js +16 -4
  223. package/dist/internal/Tidx.js.map +1 -1
  224. package/dist/internal/WebhookTransfer.d.ts +1 -55
  225. package/dist/internal/WebhookTransfer.d.ts.map +1 -1
  226. package/dist/internal/WebhookTransfer.js +1 -239
  227. package/dist/internal/WebhookTransfer.js.map +1 -1
  228. package/dist/internal/Webhooks.d.ts +112 -56
  229. package/dist/internal/Webhooks.d.ts.map +1 -1
  230. package/dist/internal/Webhooks.js +124 -93
  231. package/dist/internal/Webhooks.js.map +1 -1
  232. package/dist/internal/funding/Deposit.d.ts +2 -2
  233. package/dist/internal/funding/Deposit.d.ts.map +1 -1
  234. package/dist/internal/funding/Deposit.js +9 -8
  235. package/dist/internal/funding/Deposit.js.map +1 -1
  236. package/dist/internal/funding/DepositAddress.d.ts +4 -4
  237. package/dist/internal/funding/DepositAddress.d.ts.map +1 -1
  238. package/dist/internal/funding/DepositAddress.js +9 -8
  239. package/dist/internal/funding/DepositAddress.js.map +1 -1
  240. package/dist/internal/funding/DepositWebhook.d.ts +25 -0
  241. package/dist/internal/funding/DepositWebhook.d.ts.map +1 -0
  242. package/dist/internal/funding/DepositWebhook.js +74 -0
  243. package/dist/internal/funding/DepositWebhook.js.map +1 -0
  244. package/dist/internal/funding/Provider.d.ts.map +1 -1
  245. package/dist/internal/funding/Provider.js +13 -12
  246. package/dist/internal/funding/Provider.js.map +1 -1
  247. package/dist/internal/funding/Reconciliation.d.ts +6 -0
  248. package/dist/internal/funding/Reconciliation.d.ts.map +1 -1
  249. package/dist/internal/funding/Reconciliation.js +42 -10
  250. package/dist/internal/funding/Reconciliation.js.map +1 -1
  251. package/dist/internal/funding/index.d.ts +1 -0
  252. package/dist/internal/funding/index.d.ts.map +1 -1
  253. package/dist/internal/funding/index.js +1 -0
  254. package/dist/internal/funding/index.js.map +1 -1
  255. package/dist/internal/funding/providers/stargate.d.ts +19 -0
  256. package/dist/internal/funding/providers/stargate.d.ts.map +1 -0
  257. package/dist/internal/funding/providers/stargate.js +143 -0
  258. package/dist/internal/funding/providers/stargate.js.map +1 -0
  259. package/dist/internal/webhookDestinations/slack.d.ts.map +1 -1
  260. package/dist/internal/webhookDestinations/slack.js +16 -0
  261. package/dist/internal/webhookDestinations/slack.js.map +1 -1
  262. package/dist/providers/index.d.ts +7 -0
  263. package/dist/providers/index.d.ts.map +1 -1
  264. package/dist/providers/index.js +3 -0
  265. package/dist/providers/index.js.map +1 -1
  266. package/package.json +2 -2
  267. package/src/App.test.ts +48 -0
  268. package/src/App.ts +7 -2
  269. package/src/Assets.test.ts +18 -0
  270. package/src/Assets.ts +22 -0
  271. package/src/Client.test-d.ts +287 -17
  272. package/src/Webhooks.ts +1 -220
  273. package/src/admin/apps/earn-vaults.test.ts +143 -0
  274. package/src/admin/apps/earn-vaults.ts +83 -6
  275. package/src/admin/apps/organizations.ts +6 -2
  276. package/src/admin/ui/src/routes/api-keys.tsx +36 -0
  277. package/src/admin/ui.generated.ts +151 -189
  278. package/src/apps/data/App.test.ts +31 -0
  279. package/src/apps/data/App.ts +64 -10
  280. package/src/apps/data/ZoneSelection.test.ts +196 -0
  281. package/src/apps/data/ZoneSelection.ts +108 -0
  282. package/src/apps/data/routes/activities.test.ts +435 -12
  283. package/src/apps/data/routes/activities.ts +562 -125
  284. package/src/apps/data/routes/balances.ts +1 -1
  285. package/src/apps/data/routes/blocks.ts +1 -1
  286. package/src/apps/data/routes/earn.test.ts +183 -23
  287. package/src/apps/data/routes/earn.ts +225 -29
  288. package/src/apps/data/routes/earn.zone-access.test.ts +46 -0
  289. package/src/apps/data/routes/exchanges.test.ts +31 -1
  290. package/src/apps/data/routes/exchanges.ts +19 -15
  291. package/src/apps/data/routes/fee-amm.ts +18 -11
  292. package/src/apps/data/routes/receipts.ts +1 -1
  293. package/src/apps/data/routes/rpc.test.ts +75 -0
  294. package/src/apps/data/routes/rpc.ts +23 -9
  295. package/src/apps/data/routes/tokenlist.ts +21 -18
  296. package/src/apps/data/routes/tokens.test.ts +29 -0
  297. package/src/apps/data/routes/tokens.ts +38 -15
  298. package/src/apps/data/routes/transactions.ts +1 -1
  299. package/src/apps/data/routes/transfers.test.ts +3 -3
  300. package/src/apps/data/routes/transfers.ts +12 -9
  301. package/src/apps/data/routes/webhooks.test.ts +179 -1497
  302. package/src/apps/data/routes/webhooks.ts +156 -976
  303. package/src/apps/data/routes/zones.test.ts +19 -13
  304. package/src/apps/funding/routes/chains.test.ts +211 -7
  305. package/src/apps/funding/routes/chains.ts +19 -12
  306. package/src/apps/funding/routes/deposit-addresses.test.ts +394 -0
  307. package/src/apps/funding/routes/deposit-addresses.ts +84 -72
  308. package/src/apps/funding/routes/providers.ts +9 -5
  309. package/src/apps/funding/routes/quotes.test.ts +46 -0
  310. package/src/apps/funding/routes/quotes.ts +8 -5
  311. package/src/apps/funding/routes/transfers.test.ts +35 -32
  312. package/src/apps/management/Billing.test.ts +26 -0
  313. package/src/apps/management/Billing.ts +24 -7
  314. package/src/apps/management/routes/api-keys.test.ts +178 -0
  315. package/src/apps/management/routes/api-keys.ts +203 -144
  316. package/src/apps/management/routes/billing.test.ts +209 -0
  317. package/src/apps/management/routes/billing.ts +254 -177
  318. package/src/apps/management/routes/faucet.test.ts +39 -0
  319. package/src/apps/management/routes/faucet.ts +75 -41
  320. package/src/apps/management/routes/invitations.test.ts +216 -0
  321. package/src/apps/management/routes/invitations.ts +186 -109
  322. package/src/apps/management/routes/invite-links.test.ts +263 -1
  323. package/src/apps/management/routes/invite-links.ts +295 -214
  324. package/src/apps/management/routes/me.test.ts +49 -0
  325. package/src/apps/management/routes/me.ts +42 -32
  326. package/src/apps/management/routes/members.test.ts +124 -1
  327. package/src/apps/management/routes/members.ts +81 -51
  328. package/src/apps/management/routes/orgs.test.ts +176 -0
  329. package/src/apps/management/routes/orgs.ts +101 -59
  330. package/src/apps/management/routes/projects.test.ts +183 -0
  331. package/src/apps/management/routes/projects.ts +124 -60
  332. package/src/apps/management/routes/scopes.test.ts +44 -0
  333. package/src/apps/management/routes/scopes.ts +37 -28
  334. package/src/apps/management/routes/usage.test.ts +92 -0
  335. package/src/apps/management/routes/usage.ts +186 -151
  336. package/src/apps/management/routes/verified-token-requests.test.ts +114 -0
  337. package/src/apps/management/routes/verified-token-requests.ts +166 -133
  338. package/src/apps/management/routes/webhooks.test.ts +313 -1
  339. package/src/apps/management/routes/webhooks.ts +220 -71
  340. package/src/apps/mpp/internal/Adapter.ts +13 -1
  341. package/src/db/Db.test.ts +42 -5
  342. package/src/db/Db.ts +85 -0
  343. package/src/db/Schema.ts +41 -3
  344. package/src/db/tables/earnVaults.test.ts +22 -0
  345. package/src/db/tables/earnVaults.ts +11 -1
  346. package/src/db/tables/organizations.test.ts +5 -2
  347. package/src/db/tables/webhookDeliveries.ts +13 -0
  348. package/src/db/tables/webhookQueueCompletions.ts +55 -0
  349. package/src/db/tables/webhookQueueEvents.ts +97 -57
  350. package/src/db/tables/webhookSubscriptions.ts +134 -144
  351. package/src/internal/Auth.ts +23 -5
  352. package/src/internal/Cache.ts +14 -7
  353. package/src/internal/EarnVaults.capabilities.test.ts +33 -0
  354. package/src/internal/EarnVaults.test.ts +79 -0
  355. package/src/internal/EarnVaults.ts +277 -0
  356. package/src/internal/MetricSink.test.ts +41 -373
  357. package/src/internal/MetricSink.ts +92 -273
  358. package/src/internal/OpenApi.ts +165 -49
  359. package/src/internal/Response.test.ts +95 -0
  360. package/src/internal/Response.ts +40 -2
  361. package/src/internal/Schema.test.ts +34 -0
  362. package/src/internal/Schema.ts +20 -9
  363. package/src/internal/Store.test.ts +186 -0
  364. package/src/internal/Store.ts +57 -17
  365. package/src/internal/Tidx.test.ts +19 -0
  366. package/src/internal/Tidx.ts +16 -4
  367. package/src/internal/WebhookTransfer.ts +1 -351
  368. package/src/internal/Webhooks.test.ts +222 -145
  369. package/src/internal/Webhooks.ts +234 -135
  370. package/src/internal/funding/Deposit.ts +71 -64
  371. package/src/internal/funding/DepositAddress.ts +50 -43
  372. package/src/internal/funding/DepositWebhook.test.ts +131 -0
  373. package/src/internal/funding/DepositWebhook.ts +101 -0
  374. package/src/internal/funding/Provider.ts +164 -142
  375. package/src/internal/funding/Reconciliation.test.ts +14 -0
  376. package/src/internal/funding/Reconciliation.ts +161 -86
  377. package/src/internal/funding/index.test.ts +1 -0
  378. package/src/internal/funding/index.ts +1 -0
  379. package/src/internal/funding/providers/index.test.ts +185 -0
  380. package/src/internal/funding/providers/stargate.ts +184 -0
  381. package/src/internal/webhookDestinations/slack.ts +15 -0
  382. package/src/providers/index.test.ts +1 -0
  383. package/src/providers/index.ts +9 -0
  384. package/src/Webhooks.bench.ts +0 -714
  385. package/src/Webhooks.memory.bench.ts +0 -250
  386. package/src/Webhooks.test.ts +0 -146
@@ -21,6 +21,55 @@ function createApp() {
21
21
  })
22
22
  }
23
23
 
24
+ test('publishes a generator-ready OpenAPI contract', async () => {
25
+ const spec = await (await createApp().request('/openapi.json')).json()
26
+ const operation = spec.paths['/v1/me'].get
27
+
28
+ expect(spec.components.schemas.User.properties.email.examples).toEqual(['dev@example.com'])
29
+
30
+ expect({
31
+ component: spec.components.schemas.User ? 'User' : undefined,
32
+ errors: {
33
+ 400: operation.responses[400].content['application/json'].schema,
34
+ 403: operation.responses[403].content['application/json'].schema,
35
+ 404: operation.responses[404].content['application/json'].schema,
36
+ },
37
+ formats: {
38
+ address: spec.components.schemas.User.properties.address.pattern,
39
+ createdAt: spec.components.schemas.User.properties.createdAt.format,
40
+ email: spec.components.schemas.User.properties.email.format,
41
+ updatedAt: spec.components.schemas.User.properties.updatedAt.format,
42
+ },
43
+ operationId: operation.operationId,
44
+ response: operation.responses[200].content['application/json'].schema,
45
+ }).toMatchInlineSnapshot(`
46
+ {
47
+ "component": "User",
48
+ "errors": {
49
+ "400": {
50
+ "$ref": "#/components/schemas/ApiKeyMalformedError",
51
+ },
52
+ "403": {
53
+ "$ref": "#/components/schemas/ForbiddenError",
54
+ },
55
+ "404": {
56
+ "$ref": "#/components/schemas/UserNotFoundError",
57
+ },
58
+ },
59
+ "formats": {
60
+ "address": "^0x[0-9a-fA-F]{40}$",
61
+ "createdAt": "date-time",
62
+ "email": "email",
63
+ "updatedAt": "date-time",
64
+ },
65
+ "operationId": "getMe",
66
+ "response": {
67
+ "$ref": "#/components/schemas/User",
68
+ },
69
+ }
70
+ `)
71
+ })
72
+
24
73
  describe('SIWE verification', () => {
25
74
  test('surfaces configured RPC failures as dependency errors', async () => {
26
75
  const account = Account.fromHeadlessWebAuthn(P256.randomPrivateKey(), {
@@ -12,37 +12,43 @@ import * as Users from '../../../db/tables/users.js'
12
12
  /** Zod schemas owned by the current-user resource. */
13
13
  export namespace schema {
14
14
  /** The signed-in developer. */
15
- export const User = Schema.describe(
16
- z.object({
17
- address: z
18
- .optional(z.string())
19
- .check(
20
- z.describe('Wallet address bound to this user, when wallet sign-in established it.'),
21
- z.meta({ examples: ['0x0000000000000000000000000000000000000001'] }),
22
- ),
23
- createdAt: z
24
- .string()
25
- .check(
26
- z.describe('When the user was created (ISO 8601).'),
27
- z.meta({ examples: ['2026-01-01T00:00:00.000Z'] }),
28
- ),
29
- email: z
30
- .optional(z.string())
31
- .check(z.describe('Verified email from the wallet identity token, when present.')),
32
- id: z
33
- .string()
34
- .check(
35
- z.describe('Opaque user id (`usr_…`).'),
36
- z.meta({ examples: ['usr_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
37
- ),
38
- updatedAt: z
39
- .string()
40
- .check(
41
- z.describe('When the user was last updated (ISO 8601).'),
42
- z.meta({ examples: ['2026-01-01T00:00:00.000Z'] }),
43
- ),
44
- }),
45
- 'The signed-in developer.',
15
+ export const User = OpenApi.component(
16
+ Schema.describe(
17
+ z.object({
18
+ address: z
19
+ .optional(z.templateLiteral(['0x', z.string().check(z.regex(/^[0-9a-fA-F]{40}$/))]))
20
+ .check(
21
+ z.describe('Wallet address bound to this user, when wallet sign-in established it.'),
22
+ z.meta({ examples: ['0x0000000000000000000000000000000000000001'] }),
23
+ ),
24
+ createdAt: z.iso
25
+ .datetime()
26
+ .check(
27
+ z.describe('When the user was created (ISO 8601).'),
28
+ z.meta({ examples: ['2026-01-01T00:00:00.000Z'] }),
29
+ ),
30
+ email: z
31
+ .optional(z.email())
32
+ .check(
33
+ z.describe('Verified email from the wallet identity token, when present.'),
34
+ z.meta({ examples: ['dev@example.com'] }),
35
+ ),
36
+ id: z
37
+ .string()
38
+ .check(
39
+ z.describe('Opaque user id (`usr_…`).'),
40
+ z.meta({ examples: ['usr_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
41
+ ),
42
+ updatedAt: z.iso
43
+ .datetime()
44
+ .check(
45
+ z.describe('When the user was last updated (ISO 8601).'),
46
+ z.meta({ examples: ['2026-01-01T00:00:00.000Z'] }),
47
+ ),
48
+ }),
49
+ 'The signed-in developer.',
50
+ ),
51
+ 'User',
46
52
  )
47
53
  }
48
54
 
@@ -58,8 +64,12 @@ export function me() {
58
64
  operationId: 'getMe',
59
65
  responses: OpenApi.responses({
60
66
  errors: {
67
+ 400: { codes: [], description: 'Malformed API key.' },
61
68
  403: 'The caller is not a signed-in user.',
62
- 404: 'No user exists for this session.',
69
+ 404: {
70
+ codes: ['user_not_found'],
71
+ description: 'No user exists for this session.',
72
+ },
63
73
  },
64
74
  success: { description: 'The authenticated user.', schema: schema.User },
65
75
  }),
@@ -44,6 +44,129 @@ async function team(
44
44
  return { member, org, owner }
45
45
  }
46
46
 
47
+ test('publishes generator-ready OpenAPI contracts', async () => {
48
+ const spec = await (await createApp().request('/openapi.json')).json()
49
+ const collection = spec.paths['/v1/orgs/{orgId}/members']
50
+ const detail = spec.paths['/v1/orgs/{orgId}/members/{userId}']
51
+
52
+ expect(spec.components.schemas.MemberList.properties.data.examples).toEqual([[]])
53
+
54
+ expect({
55
+ components: ['Member', 'MemberList', 'RemoveMemberResponse', 'UpdateMemberRequest'].filter(
56
+ (name) => spec.components.schemas[name],
57
+ ),
58
+ list: {
59
+ errors: {
60
+ 400: collection.get.responses[400].content['application/json'].schema,
61
+ 403: collection.get.responses[403].content['application/json'].schema,
62
+ 404: collection.get.responses[404].content['application/json'].schema,
63
+ },
64
+ operationId: collection.get.operationId,
65
+ response: collection.get.responses[200].content['application/json'].schema,
66
+ },
67
+ memberFormats: {
68
+ address: spec.components.schemas.Member.properties.address.pattern,
69
+ createdAt: spec.components.schemas.Member.properties.createdAt.format,
70
+ email: spec.components.schemas.Member.properties.email.format,
71
+ },
72
+ remove: {
73
+ errors: {
74
+ 400: detail.delete.responses[400].content['application/json'].schema,
75
+ 403: detail.delete.responses[403].content['application/json'].schema,
76
+ 404: detail.delete.responses[404].content['application/json'].schema,
77
+ 409: detail.delete.responses[409].content['application/json'].schema,
78
+ },
79
+ operationId: detail.delete.operationId,
80
+ response: detail.delete.responses[200].content['application/json'].schema,
81
+ },
82
+ update: {
83
+ errors: {
84
+ 400: detail.patch.responses[400].content['application/json'].schema,
85
+ 403: detail.patch.responses[403].content['application/json'].schema,
86
+ 404: detail.patch.responses[404].content['application/json'].schema,
87
+ 409: detail.patch.responses[409].content['application/json'].schema,
88
+ },
89
+ operationId: detail.patch.operationId,
90
+ request: detail.patch.requestBody.content['application/json'].schema,
91
+ response: detail.patch.responses[200].content['application/json'].schema,
92
+ },
93
+ }).toMatchInlineSnapshot(`
94
+ {
95
+ "components": [
96
+ "Member",
97
+ "MemberList",
98
+ "RemoveMemberResponse",
99
+ "UpdateMemberRequest",
100
+ ],
101
+ "list": {
102
+ "errors": {
103
+ "400": {
104
+ "$ref": "#/components/schemas/ApiKeyMalformedOrParamInvalidError",
105
+ },
106
+ "403": {
107
+ "$ref": "#/components/schemas/ForbiddenError",
108
+ },
109
+ "404": {
110
+ "$ref": "#/components/schemas/OrganizationNotFoundError",
111
+ },
112
+ },
113
+ "operationId": "listMembers",
114
+ "response": {
115
+ "$ref": "#/components/schemas/MemberList",
116
+ },
117
+ },
118
+ "memberFormats": {
119
+ "address": "^0x[0-9a-fA-F]{40}$",
120
+ "createdAt": "date-time",
121
+ "email": "email",
122
+ },
123
+ "remove": {
124
+ "errors": {
125
+ "400": {
126
+ "$ref": "#/components/schemas/ApiKeyMalformedOrParamInvalidError",
127
+ },
128
+ "403": {
129
+ "$ref": "#/components/schemas/ForbiddenError",
130
+ },
131
+ "404": {
132
+ "$ref": "#/components/schemas/MemberNotFoundOrOrganizationNotFoundError",
133
+ },
134
+ "409": {
135
+ "$ref": "#/components/schemas/LastOwnerError",
136
+ },
137
+ },
138
+ "operationId": "removeMember",
139
+ "response": {
140
+ "$ref": "#/components/schemas/RemoveMemberResponse",
141
+ },
142
+ },
143
+ "update": {
144
+ "errors": {
145
+ "400": {
146
+ "$ref": "#/components/schemas/ApiKeyMalformedOrBodyInvalidOrParamInvalidError",
147
+ },
148
+ "403": {
149
+ "$ref": "#/components/schemas/ForbiddenError",
150
+ },
151
+ "404": {
152
+ "$ref": "#/components/schemas/MemberNotFoundOrOrganizationNotFoundError",
153
+ },
154
+ "409": {
155
+ "$ref": "#/components/schemas/LastOwnerError",
156
+ },
157
+ },
158
+ "operationId": "updateMember",
159
+ "request": {
160
+ "$ref": "#/components/schemas/UpdateMemberRequest",
161
+ },
162
+ "response": {
163
+ "$ref": "#/components/schemas/Member",
164
+ },
165
+ },
166
+ }
167
+ `)
168
+ })
169
+
47
170
  describe('members', () => {
48
171
  test('lists the team with roles and identity', async () => {
49
172
  const db = TestApp.database()
@@ -140,7 +263,7 @@ describe('members', () => {
140
263
  app.request(`/v1/orgs/${org.id}/members/${owner.userId}`, json('PATCH', second.cookie, { role: 'member' })), // prettier-ignore
141
264
  app.request(`/v1/orgs/${org.id}/members/${second.userId}`, json('PATCH', owner.cookie, { role: 'member' })), // prettier-ignore
142
265
  ])
143
- expect([a.status, b.status].sort()).toEqual([200, 409])
266
+ expect([a.status, b.status].sort((left, right) => left - right)).toEqual([200, 409])
144
267
  const owners = (await Memberships.listByOrg(db, org.id)).filter(({ role }) => role === 'owner')
145
268
  expect(owners).toHaveLength(1)
146
269
  })
@@ -18,35 +18,38 @@ export namespace schema {
18
18
  .check(z.describe('Membership role.'), z.meta({ examples: ['admin'] }))
19
19
 
20
20
  /** One organization member: the membership plus the member's identity. */
21
- export const Member = Schema.describe(
22
- z.object({
23
- address: z
24
- .optional(z.string())
25
- .check(
26
- z.describe("The member's wallet address, when wallet sign-in established it."),
27
- z.meta({ examples: ['0x20f414b3cbcf1fd8e8f5e1c1c2e3d4a5b6c7d8e9'] }),
28
- ),
29
- createdAt: z
30
- .string()
31
- .check(
32
- z.describe('When the member joined (ISO 8601).'),
33
- z.meta({ examples: ['2026-01-01T00:00:00.000Z'] }),
34
- ),
35
- email: z
36
- .optional(z.string())
37
- .check(
38
- z.describe("The member's verified email, when known."),
39
- z.meta({ examples: ['dev@example.com'] }),
40
- ),
41
- role: Role,
42
- userId: z
43
- .string()
44
- .check(
45
- z.describe('Member user id (`usr_…`).'),
46
- z.meta({ examples: ['usr_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
47
- ),
48
- }),
49
- "One organization member: the membership plus the member's identity.",
21
+ export const Member = OpenApi.component(
22
+ Schema.describe(
23
+ z.object({
24
+ address: z
25
+ .optional(z.templateLiteral(['0x', z.string().check(z.regex(/^[0-9a-fA-F]{40}$/))]))
26
+ .check(
27
+ z.describe("The member's wallet address, when wallet sign-in established it."),
28
+ z.meta({ examples: ['0x20f414b3cbcf1fd8e8f5e1c1c2e3d4a5b6c7d8e9'] }),
29
+ ),
30
+ createdAt: z.iso
31
+ .datetime()
32
+ .check(
33
+ z.describe('When the member joined (ISO 8601).'),
34
+ z.meta({ examples: ['2026-01-01T00:00:00.000Z'] }),
35
+ ),
36
+ email: z
37
+ .optional(z.email())
38
+ .check(
39
+ z.describe("The member's verified email, when known."),
40
+ z.meta({ examples: ['dev@example.com'] }),
41
+ ),
42
+ role: Role,
43
+ userId: z
44
+ .string()
45
+ .check(
46
+ z.describe('Member user id (`usr_…`).'),
47
+ z.meta({ examples: ['usr_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
48
+ ),
49
+ }),
50
+ "One organization member: the membership plus the member's identity.",
51
+ ),
52
+ 'Member',
50
53
  )
51
54
 
52
55
  /** Path parameters addressing an organization's member collection. */
@@ -80,34 +83,43 @@ export namespace schema {
80
83
  .check(z.describe('Path parameters for one member.'))
81
84
 
82
85
  /** Request body changing a member's role. */
83
- export const MemberBody = z
84
- .object({ role: Role })
85
- .check(z.describe("Fields for changing a member's role."))
86
+ export const UpdateMemberRequest = OpenApi.component(
87
+ z.object({ role: Role }).check(z.describe("Fields for changing a member's role.")),
88
+ 'UpdateMemberRequest',
89
+ )
86
90
 
87
91
  /** Schemas for the listMembers operation. */
88
92
  export namespace listMembers {
89
93
  /** Non-paginated list of an organization's members. */
90
- export const Response = Schema.describe(
91
- z.object({
92
- data: z.array(Member).check(z.describe('The members, oldest first.')),
93
- }),
94
- "A non-paginated list of an organization's members.",
94
+ export const Response = OpenApi.component(
95
+ Schema.describe(
96
+ z.object({
97
+ data: z
98
+ .array(Member)
99
+ .check(z.describe('The members, oldest first.'), z.meta({ examples: [[]] })),
100
+ }),
101
+ "A non-paginated list of an organization's members.",
102
+ ),
103
+ 'MemberList',
95
104
  )
96
105
  }
97
106
 
98
107
  /** Schemas for the removeMember operation. */
99
108
  export namespace removeMember {
100
109
  /** Confirmation that the member was removed. */
101
- export const Response = z
102
- .object({
103
- userId: z
104
- .string()
105
- .check(
106
- z.describe('User id (`usr_…`) of the removed member.'),
107
- z.meta({ examples: ['usr_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
108
- ),
109
- })
110
- .check(z.describe('Confirmation that the member was removed.'))
110
+ export const Response = OpenApi.component(
111
+ z
112
+ .object({
113
+ userId: z
114
+ .string()
115
+ .check(
116
+ z.describe('User id (`usr_…`) of the removed member.'),
117
+ z.meta({ examples: ['usr_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
118
+ ),
119
+ })
120
+ .check(z.describe('Confirmation that the member was removed.')),
121
+ 'RemoveMemberResponse',
122
+ )
111
123
  }
112
124
  }
113
125
 
@@ -129,7 +141,13 @@ export function members() {
129
141
  OpenApi.describeRoute({
130
142
  operationId: 'listMembers',
131
143
  responses: OpenApi.responses({
132
- errors: { 404: 'No accessible organization was found for this id.' },
144
+ errors: {
145
+ 400: { codes: ['param_invalid'], description: 'Malformed API key or invalid path.' },
146
+ 404: {
147
+ codes: ['organization_not_found'],
148
+ description: 'No accessible organization was found for this id.',
149
+ },
150
+ },
133
151
  success: {
134
152
  description: 'The members, oldest first.',
135
153
  schema: schema.listMembers.Response,
@@ -169,7 +187,7 @@ export function members() {
169
187
  code: 'param_invalid',
170
188
  message: 'Check the path parameters and try again.',
171
189
  }),
172
- OpenApi.validate('json', schema.MemberBody, {
190
+ OpenApi.validate('json', schema.UpdateMemberRequest, {
173
191
  code: 'body_invalid',
174
192
  message: 'Check the request body and try again.',
175
193
  }),
@@ -178,7 +196,14 @@ export function members() {
178
196
  operationId: 'updateMember',
179
197
  responses: OpenApi.responses({
180
198
  errors: {
181
- 404: 'No accessible member was found for this id.',
199
+ 400: {
200
+ codes: ['body_invalid', 'param_invalid'],
201
+ description: 'Malformed API key, invalid path, or invalid body.',
202
+ },
203
+ 404: {
204
+ codes: ['member_not_found', 'organization_not_found'],
205
+ description: 'No accessible organization or member was found for this id.',
206
+ },
182
207
  409: {
183
208
  codes: ['last_owner'],
184
209
  description: 'The organization would be left without an owner.',
@@ -192,6 +217,7 @@ export function members() {
192
217
  async (c) => {
193
218
  if (Auth.narrowAccess) return Auth.accessError(c)
194
219
  if (Auth.narrowScope) return Auth.ensureOrgError(c)
220
+ if (Auth.narrowOrgRole) return Auth.ensureOrgRoleError(c)
195
221
  if (OpenApi.narrowValidation)
196
222
  return OpenApi.validationError(c, {
197
223
  code: 'param_invalid',
@@ -237,7 +263,11 @@ export function members() {
237
263
  operationId: 'removeMember',
238
264
  responses: OpenApi.responses({
239
265
  errors: {
240
- 404: 'No accessible member was found for this id.',
266
+ 400: { codes: ['param_invalid'], description: 'Malformed API key or invalid path.' },
267
+ 404: {
268
+ codes: ['member_not_found', 'organization_not_found'],
269
+ description: 'No accessible organization or member was found for this id.',
270
+ },
241
271
  409: {
242
272
  codes: ['last_owner'],
243
273
  description: 'The organization would be left without an owner.',
@@ -79,7 +79,183 @@ async function session(app: TestApp.signIn.App) {
79
79
  return cookie!
80
80
  }
81
81
 
82
+ test('publishes generator-ready OpenAPI contracts', async () => {
83
+ const spec = await (await createApp().request('/openapi.json')).json()
84
+ const collection = spec.paths['/v1/orgs']
85
+ const detail = spec.paths['/v1/orgs/{orgId}']
86
+
87
+ expect({
88
+ components: [
89
+ 'CreateOrganizationRequest',
90
+ 'DeleteOrganizationResponse',
91
+ 'Organization',
92
+ 'OrganizationList',
93
+ 'UpdateOrganizationRequest',
94
+ ].filter((name) => spec.components.schemas[name]),
95
+ create: {
96
+ errors: {
97
+ 400: collection.post.responses[400].content['application/json'].schema,
98
+ 403: collection.post.responses[403].content['application/json'].schema,
99
+ },
100
+ operationId: collection.post.operationId,
101
+ request: collection.post.requestBody.content['application/json'].schema,
102
+ response: collection.post.responses[200].content['application/json'].schema,
103
+ },
104
+ delete: {
105
+ errors: {
106
+ 400: detail.delete.responses[400].content['application/json'].schema,
107
+ 403: detail.delete.responses[403].content['application/json'].schema,
108
+ 404: detail.delete.responses[404].content['application/json'].schema,
109
+ 409: detail.delete.responses[409].content['application/json'].schema,
110
+ },
111
+ operationId: detail.delete.operationId,
112
+ response: detail.delete.responses[200].content['application/json'].schema,
113
+ },
114
+ get: {
115
+ errors: {
116
+ 400: detail.get.responses[400].content['application/json'].schema,
117
+ 403: detail.get.responses[403].content['application/json'].schema,
118
+ 404: detail.get.responses[404].content['application/json'].schema,
119
+ },
120
+ operationId: detail.get.operationId,
121
+ response: detail.get.responses[200].content['application/json'].schema,
122
+ },
123
+ list: {
124
+ errors: {
125
+ 400: collection.get.responses[400].content['application/json'].schema,
126
+ 403: collection.get.responses[403].content['application/json'].schema,
127
+ },
128
+ operationId: collection.get.operationId,
129
+ response: collection.get.responses[200].content['application/json'].schema,
130
+ },
131
+ timestamps: {
132
+ createdAt: spec.components.schemas.Organization.properties.createdAt.format,
133
+ updatedAt: spec.components.schemas.Organization.properties.updatedAt.format,
134
+ },
135
+ update: {
136
+ errors: {
137
+ 400: detail.patch.responses[400].content['application/json'].schema,
138
+ 403: detail.patch.responses[403].content['application/json'].schema,
139
+ 404: detail.patch.responses[404].content['application/json'].schema,
140
+ },
141
+ operationId: detail.patch.operationId,
142
+ request: detail.patch.requestBody.content['application/json'].schema,
143
+ response: detail.patch.responses[200].content['application/json'].schema,
144
+ },
145
+ }).toMatchInlineSnapshot(`
146
+ {
147
+ "components": [
148
+ "CreateOrganizationRequest",
149
+ "DeleteOrganizationResponse",
150
+ "Organization",
151
+ "OrganizationList",
152
+ "UpdateOrganizationRequest",
153
+ ],
154
+ "create": {
155
+ "errors": {
156
+ "400": {
157
+ "$ref": "#/components/schemas/ApiKeyMalformedOrBodyInvalidError",
158
+ },
159
+ "403": {
160
+ "$ref": "#/components/schemas/ForbiddenError",
161
+ },
162
+ },
163
+ "operationId": "createOrganization",
164
+ "request": {
165
+ "$ref": "#/components/schemas/CreateOrganizationRequest",
166
+ },
167
+ "response": {
168
+ "$ref": "#/components/schemas/Organization",
169
+ },
170
+ },
171
+ "delete": {
172
+ "errors": {
173
+ "400": {
174
+ "$ref": "#/components/schemas/ApiKeyMalformedOrParamInvalidError",
175
+ },
176
+ "403": {
177
+ "$ref": "#/components/schemas/ForbiddenError",
178
+ },
179
+ "404": {
180
+ "$ref": "#/components/schemas/OrganizationNotFoundError",
181
+ },
182
+ "409": {
183
+ "$ref": "#/components/schemas/SponsorshipsUnreportedError",
184
+ },
185
+ },
186
+ "operationId": "deleteOrganization",
187
+ "response": {
188
+ "$ref": "#/components/schemas/DeleteOrganizationResponse",
189
+ },
190
+ },
191
+ "get": {
192
+ "errors": {
193
+ "400": {
194
+ "$ref": "#/components/schemas/ApiKeyMalformedOrParamInvalidError",
195
+ },
196
+ "403": {
197
+ "$ref": "#/components/schemas/ForbiddenError",
198
+ },
199
+ "404": {
200
+ "$ref": "#/components/schemas/OrganizationNotFoundError",
201
+ },
202
+ },
203
+ "operationId": "getOrganization",
204
+ "response": {
205
+ "$ref": "#/components/schemas/Organization",
206
+ },
207
+ },
208
+ "list": {
209
+ "errors": {
210
+ "400": {
211
+ "$ref": "#/components/schemas/ApiKeyMalformedError",
212
+ },
213
+ "403": {
214
+ "$ref": "#/components/schemas/ForbiddenError",
215
+ },
216
+ },
217
+ "operationId": "listOrganizations",
218
+ "response": {
219
+ "$ref": "#/components/schemas/OrganizationList",
220
+ },
221
+ },
222
+ "timestamps": {
223
+ "createdAt": "date-time",
224
+ "updatedAt": "date-time",
225
+ },
226
+ "update": {
227
+ "errors": {
228
+ "400": {
229
+ "$ref": "#/components/schemas/ApiKeyMalformedOrBodyInvalidOrParamInvalidError",
230
+ },
231
+ "403": {
232
+ "$ref": "#/components/schemas/ForbiddenError",
233
+ },
234
+ "404": {
235
+ "$ref": "#/components/schemas/OrganizationNotFoundError",
236
+ },
237
+ },
238
+ "operationId": "updateOrganization",
239
+ "request": {
240
+ "$ref": "#/components/schemas/UpdateOrganizationRequest",
241
+ },
242
+ "response": {
243
+ "$ref": "#/components/schemas/Organization",
244
+ },
245
+ },
246
+ }
247
+ `)
248
+ })
249
+
82
250
  describe('GET /orgs', () => {
251
+ test('rejects malformed API key credentials', async () => {
252
+ const response = await createApp().request('/v1/orgs', {
253
+ headers: { authorization: 'Basic wrong' },
254
+ })
255
+ expect(response.status).toBe(400)
256
+ expect(await response.json()).toMatchObject({ error: { code: 'api_key_malformed' } })
257
+ })
258
+
83
259
  test('lists all organizations for the super admin', async () => {
84
260
  const response = await (await seeded()).request('/v1/orgs', as(secret))
85
261
  expect(response.status).toBe(200)