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
@@ -1,6 +1,13 @@
1
1
  import type { Context, Env, MiddlewareHandler, ValidationTargets } from 'hono'
2
2
  import type { HasRequiredKeys } from 'hono/utils/types'
3
- import { resolver, type ResponsesWithResolver, validator } from 'hono-openapi'
3
+ import {
4
+ describeRoute as core_describeRoute,
5
+ type DescribeRouteOptions,
6
+ resolver,
7
+ type ResponsesWithResolver,
8
+ uniqueSymbol,
9
+ validator,
10
+ } from 'hono-openapi'
4
11
  import * as z from 'zod/mini'
5
12
  import * as Response from './Response.js'
6
13
  import * as Schema from './Schema.js'
@@ -41,7 +48,6 @@ const schemaOptions = { options: { override: recoverExamples, unrepresentable: '
41
48
  // re-exports because `uniqueSymbol` is a `unique symbol` whose identity is
42
49
  // lost when copied through a `const` declaration.
43
50
  export {
44
- describeRoute,
45
51
  type HandlerUniqueProperty,
46
52
  resolver,
47
53
  type ResponsesWithResolver,
@@ -49,12 +55,53 @@ export {
49
55
  validator,
50
56
  } from 'hono-openapi'
51
57
 
58
+ function cloneResponseContainers(spec: DescribeRouteOptions): DescribeRouteOptions {
59
+ if (!spec.responses) return spec
60
+ return {
61
+ ...spec,
62
+ responses: Object.fromEntries(
63
+ Object.entries(spec.responses).map(([status, response]) => [
64
+ status,
65
+ !response || !('content' in response)
66
+ ? response
67
+ : {
68
+ ...response,
69
+ content: Object.fromEntries(
70
+ Object.entries(response.content ?? {}).map(([mediaType, media]) => [
71
+ mediaType,
72
+ { ...media },
73
+ ]),
74
+ ),
75
+ },
76
+ ]),
77
+ ),
78
+ }
79
+ }
80
+
81
+ /** Describes a route without allowing spec generation to mutate reusable response definitions. */
82
+ export function describeRoute(spec: DescribeRouteOptions): MiddlewareHandler {
83
+ const handler = core_describeRoute(spec)
84
+ Object.defineProperty(handler, uniqueSymbol, {
85
+ get: () => ({ spec: cloneResponseContainers(spec) }),
86
+ })
87
+ return handler
88
+ }
89
+
90
+ /** Emits a named OpenAPI component and uses its `$ref` wherever the schema appears. */
91
+ export function component<const schema extends z.ZodMiniType>(
92
+ schema: schema,
93
+ name: string,
94
+ ): schema {
95
+ const cloned = schema.clone()
96
+ z.globalRegistry.add(cloned, { ...z.globalRegistry.get(schema), ref: name })
97
+ return cloned as schema
98
+ }
99
+
52
100
  /**
53
101
  * Standard machine-readable `error.code` values per status, shared API-wide.
54
102
  * The reference enumerates `error.code` to these so generated clients narrow it
55
- * to a literal union instead of an open `string`. 400 and 404 vary per
56
- * operation; the values here are the API-wide supersets, narrowable per route
57
- * via the `codes` override in {@link responses.Options}.
103
+ * to a literal union instead of an open `string`. The values here are shared
104
+ * defaults; operation-specific codes are supplied through {@link responses.Options}.
58
105
  */
59
106
  export const errorCodes = {
60
107
  400: [
@@ -80,7 +127,7 @@ export const errorCodes = {
80
127
  'api_key_malformed',
81
128
  ],
82
129
  401: ['api_key_missing', 'api_key_invalid', 'unauthorized'],
83
- 403: ['api_key_forbidden', 'api_key_ip_forbidden', 'limit_exceeded'],
130
+ 403: ['api_key_forbidden', 'api_key_ip_forbidden', 'forbidden'],
84
131
  404: [
85
132
  'not_found',
86
133
  'token_not_found',
@@ -164,11 +211,78 @@ export const rateLimitHeaders = {
164
211
  /** Representative `requestId` used in error-body examples. */
165
212
  const exampleRequestId = '0a1b2c3d-4e5f-6071-8293-a4b5c6d7e8f9'
166
213
 
167
- /** Builds the `application/json` content for a standard error response: the enumerated-code envelope plus an example body. */
168
- function errorContent(codes: readonly [string, ...string[]] | undefined, message: string) {
214
+ const standardErrorNames = {
215
+ 400: 'InvalidRequestError',
216
+ 401: 'AuthenticationError',
217
+ 403: 'ForbiddenError',
218
+ 404: 'ResourceNotFoundError',
219
+ 429: 'RateLimitError',
220
+ 500: 'InternalError',
221
+ 501: 'NotImplementedError',
222
+ 502: 'UpstreamError',
223
+ } as const satisfies Record<keyof typeof errorCodes, string>
224
+
225
+ const reservedErrorNames = new Set<string>(Object.values(standardErrorNames))
226
+ const errorSchemas = new Map<string, z.ZodMiniType>()
227
+
228
+ function errorName(status: number, codes: readonly string[]) {
229
+ const standard = errorCodes[status as keyof typeof errorCodes]
230
+ if (
231
+ standard &&
232
+ standard.length === codes.length &&
233
+ [...standard].sort().every((code, index) => code === codes[index])
234
+ )
235
+ return standardErrorNames[status as keyof typeof standardErrorNames]
236
+ const name = `${codes
237
+ .map((code) =>
238
+ code
239
+ .split('_')
240
+ .map((part) => `${part[0]?.toUpperCase()}${part.slice(1)}`)
241
+ .join(''),
242
+ )
243
+ .join('Or')}Error`
244
+ if (reservedErrorNames.has(name)) return `${name.slice(0, -'Error'.length)}${status}Error`
245
+ return name
246
+ }
247
+
248
+ function errorSchema(status: number, codes: readonly [string, ...string[]] | undefined) {
249
+ const defaults = errorCodes[status as keyof typeof errorCodes]
250
+ if (!codes && !defaults) {
251
+ const cached = errorSchemas.get('*')
252
+ if (cached) return cached
253
+ const schema = component(Schema.errorResponse(), 'ErrorResponse')
254
+ errorSchemas.set('*', schema)
255
+ return schema
256
+ }
257
+ const normalized = [...(codes ?? defaults ?? [])].sort() as [string, ...string[]]
258
+ const key = normalized.join('\0')
259
+ const cached = errorSchemas.get(key)
260
+ if (cached) return cached
261
+ const schema = component(Schema.errorResponse(normalized), errorName(status, normalized))
262
+ errorSchemas.set(key, schema)
263
+ return schema
264
+ }
265
+
266
+ function mergeErrorCodes(
267
+ status: number,
268
+ codes: readonly string[] | undefined,
269
+ ): readonly [string, ...string[]] | undefined {
270
+ if (!codes) return errorCodes[status as keyof typeof errorCodes]
271
+ if (status !== 400 && status !== 403)
272
+ return codes.length ? (codes as [string, ...string[]]) : undefined
273
+ const baseline = status === 400 ? (['api_key_malformed'] as const) : errorCodes[403]
274
+ return [...new Set([...baseline, ...codes])] as [string, ...string[]]
275
+ }
276
+
277
+ /** Builds the `application/json` content for a standard error response: the named enumerated-code envelope plus an example body. */
278
+ function errorContent(
279
+ status: number,
280
+ codes: readonly [string, ...string[]] | undefined,
281
+ message: string,
282
+ ) {
169
283
  return {
170
284
  'application/json': {
171
- schema: resolver(Schema.errorResponse(codes), schemaOptions),
285
+ schema: resolver(errorSchema(status, codes), schemaOptions),
172
286
  example: { error: { code: codes?.[0] ?? 'error', message }, requestId: exampleRequestId },
173
287
  },
174
288
  }
@@ -186,32 +300,30 @@ export const paymentChallenge = {
186
300
  headers: { 'WWW-Authenticate': headerRef('WwwAuthenticate') },
187
301
  } as const
188
302
 
189
- /** Shared `429` rate-limit response, registered as `components.responses.RateLimited`. */
190
- const rateLimitedResponse = {
191
- content: errorContent(errorCodes[429], 'Rate limit exceeded.'),
192
- description:
193
- 'Rate limit exceeded. On endpoints that accept MPP, over-quota unpaid requests return `402 Payment Required` instead.',
194
- headers: { ...rateLimitHeaders },
195
- }
196
-
197
- /** Shared `500` internal-error response, registered as `components.responses.InternalError`. */
198
- const serverErrorResponse = {
199
- content: errorContent(errorCodes[500], 'Internal server error.'),
200
- description: 'Internal server error.',
201
- }
303
+ type ResponseComponentName = 'InternalError' | 'PaymentRequired' | 'RateLimited'
202
304
 
203
305
  /**
204
306
  * Reusable responses registered under `components.responses` (see `App.create`)
205
307
  * and `$ref`-erenced from operations, so the uniform `402`/`429`/`500` responses
206
308
  * are defined once instead of inlined on every operation.
207
309
  */
208
- export const responseComponents: ResponsesWithResolver = {
209
- InternalError: serverErrorResponse,
210
- PaymentRequired: paymentChallenge,
211
- RateLimited: rateLimitedResponse,
310
+ export function responseComponents(): ResponsesWithResolver {
311
+ return {
312
+ InternalError: {
313
+ content: errorContent(500, errorCodes[500], 'Internal server error.'),
314
+ description: 'Internal server error.',
315
+ },
316
+ PaymentRequired: paymentChallenge,
317
+ RateLimited: {
318
+ content: errorContent(429, errorCodes[429], 'Rate limit exceeded.'),
319
+ description:
320
+ 'Rate limit exceeded. On endpoints that accept MPP, over-quota unpaid requests return `402 Payment Required` instead.',
321
+ headers: { ...rateLimitHeaders },
322
+ },
323
+ }
212
324
  }
213
325
 
214
- const responseRef = (name: keyof typeof responseComponents) => ({
326
+ const responseRef = (name: ResponseComponentName) => ({
215
327
  $ref: `#/components/responses/${name}`,
216
328
  })
217
329
 
@@ -232,22 +344,22 @@ export function standardError(
232
344
  ): ResponsesWithResolver[string] {
233
345
  if (status === 429) return responseRef('RateLimited')
234
346
  if (status === 500) return responseRef('InternalError')
235
- return { content: errorContent(codes ?? errorCodes[status], description), description }
347
+ return { content: errorContent(status, mergeErrorCodes(status, codes), description), description }
236
348
  }
237
349
 
238
350
  /**
239
351
  * Builds an OpenAPI `responses` map with the API's standard error responses
240
352
  * pre-filled, plus the success response (with rate-limit headers):
241
353
  *
242
- * - `400` invalid request, `401` missing/invalid key, `429` rate limited,
243
- * `500` internal error, and `502` upstream failure on every operation;
244
- * - `403`/`404`/`409`/`412`/`413`/`415` only when an `errors` entry is set.
354
+ * - `400` invalid request, `401` missing/invalid key, `403` forbidden, `429`
355
+ * rate limited, `500` internal error, and `502` upstream failure on every operation;
356
+ * - `404`/`409`/`412`/`413`/`415` only when an `errors` entry is set.
245
357
  *
246
- * `error.code` is enumerated per status from {@link errorCodes}; narrow 400/404
247
- * to a route's exact codes by passing `{ description, codes }` for that status.
248
- * `429`/`500` `$ref` the shared {@link responseComponents}. `402` is not emitted
249
- * here it is injected per operation from the route's MPP policy during spec
250
- * generation (see `App.ts`).
358
+ * `error.code` is enumerated per status from {@link errorCodes}. Operation-level
359
+ * 400/403 codes merge with shared auth codes; other overrides replace defaults.
360
+ * The default `429` and `500` `$ref` shared {@link responseComponents}; an exact
361
+ * operation-level `429` override is emitted inline with the standard headers.
362
+ * `402` is injected per operation from the route's MPP policy in `App.ts`.
251
363
  */
252
364
  export function responses<schema extends z.ZodMiniType>(
253
365
  options: responses.Options<schema>,
@@ -257,10 +369,11 @@ export function responses<schema extends z.ZodMiniType>(
257
369
  const override = errors?.[status as 400]
258
370
  const description =
259
371
  typeof override === 'string' ? override : (override?.description ?? fallback)
260
- const codes =
261
- (typeof override === 'object' ? override.codes : undefined) ??
262
- errorCodes[status as keyof typeof errorCodes]
263
- return { content: errorContent(codes, description), description }
372
+ const codes = mergeErrorCodes(status, typeof override === 'object' ? override.codes : undefined)
373
+ return {
374
+ content: errorContent(status, codes, description),
375
+ description,
376
+ }
264
377
  }
265
378
  return {
266
379
  200: {
@@ -279,13 +392,15 @@ export function responses<schema extends z.ZodMiniType>(
279
392
  },
280
393
  400: error(400, 'Invalid request.'),
281
394
  401: error(401, 'Missing or invalid API key.'),
282
- ...(errors?.[403] && { 403: error(403, 'Forbidden.') }),
395
+ 403: error(403, 'Forbidden.'),
283
396
  ...(errors?.[404] && { 404: error(404, 'Not found.') }),
284
397
  ...(errors?.[409] && { 409: error(409, 'Conflict.') }),
285
398
  ...(errors?.[412] && { 412: error(412, 'Precondition failed.') }),
286
399
  ...(errors?.[413] && { 413: error(413, 'Payload too large.') }),
287
400
  ...(errors?.[415] && { 415: error(415, 'Unsupported media type.') }),
288
- 429: responseRef('RateLimited'),
401
+ 429: errors?.[429]
402
+ ? { ...error(429, 'Rate limit exceeded.'), headers: { ...rateLimitHeaders } }
403
+ : responseRef('RateLimited'),
289
404
  500: responseRef('InternalError'),
290
405
  ...(errors?.[501] && { 501: error(501, 'Not implemented.') }),
291
406
  502: error(502, 'Upstream data failure.'),
@@ -295,23 +410,22 @@ export function responses<schema extends z.ZodMiniType>(
295
410
  export declare namespace responses {
296
411
  /**
297
412
  * Override for a standard error response: a description string, or an object
298
- * adding the exact `codes` that status can return (narrowing the enum).
413
+ * adding operation codes. Codes replace defaults except shared 400/403 auth codes.
299
414
  */
300
415
  type ErrorOverride =
301
416
  | string
302
417
  | {
303
418
  /** Human-readable description of the error response. */
304
419
  description?: string | undefined
305
- /** Exact `error.code` values this status returns for the operation. */
306
- codes?: readonly [string, ...string[]] | undefined
420
+ /** Operation-specific `error.code` values for this status. */
421
+ codes?: readonly string[] | undefined
307
422
  }
308
423
 
309
424
  /** Options for building a standard OpenAPI responses map. */
310
425
  type Options<schema> = {
311
426
  /**
312
- * Optional overrides for standard error responses (description and/or exact
313
- * `error.code` enum). Setting `403`/`404`/`409`/`412`/`413`/`415` also
314
- * includes that status in the map.
427
+ * Optional overrides for standard error responses. Setting
428
+ * `404`/`409`/`412`/`413`/`415` includes that status in the map.
315
429
  */
316
430
  errors?:
317
431
  | {
@@ -319,7 +433,7 @@ export declare namespace responses {
319
433
  400?: ErrorOverride | undefined
320
434
  /** Override for the 401 response. */
321
435
  401?: ErrorOverride | undefined
322
- /** Override for the 403 response. Setting this includes 403 in the map. */
436
+ /** Add operation-specific 403 codes or override its description. */
323
437
  403?: ErrorOverride | undefined
324
438
  /** Override for the 404 response. Setting this includes 404 in the map. */
325
439
  404?: ErrorOverride | undefined
@@ -331,6 +445,8 @@ export declare namespace responses {
331
445
  413?: ErrorOverride | undefined
332
446
  /** Override for the 415 response. Setting this includes 415 in the map. */
333
447
  415?: ErrorOverride | undefined
448
+ /** Override the shared 429 response with operation-specific rate-limit codes. */
449
+ 429?: ErrorOverride | undefined
334
450
  /** Override for the 501 response. Setting this includes 501 in the map. */
335
451
  501?: ErrorOverride | undefined
336
452
  /** Override for the 502 response. */
@@ -1,4 +1,5 @@
1
1
  import { Hono } from 'hono'
2
+ import { Tidx } from 'tidx.ts'
2
3
 
3
4
  import * as Response from './Response.js'
4
5
 
@@ -25,4 +26,98 @@ describe('upstream', () => {
25
26
  `)
26
27
  expect(captured).toBe(cause)
27
28
  })
29
+
30
+ test('returns a query error when a positional page times out', async () => {
31
+ const app = new Hono()
32
+ const cause = new Tidx.FetchRequestError(
33
+ 'Request timeout',
34
+ new globalThis.Response(null, { status: 408 }),
35
+ )
36
+ let captured: Error | undefined
37
+
38
+ app.use(async (c, next) => {
39
+ await next()
40
+ captured = c.error
41
+ })
42
+ app.get('/', (c) => Response.upstream(c, cause, { page: 2 }))
43
+
44
+ const response = await app.request('/')
45
+ expect(response.status).toMatchInlineSnapshot(`400`)
46
+ expect(await response.json()).toMatchInlineSnapshot(`
47
+ {
48
+ "error": {
49
+ "code": "query_invalid",
50
+ "message": "The requested page timed out. Use cursor pagination for deep traversal.",
51
+ },
52
+ }
53
+ `)
54
+ expect(captured).toBe(cause)
55
+ })
56
+
57
+ test('returns a query error when a positional page is rejected', async () => {
58
+ const app = new Hono()
59
+ const cause = new Tidx.FetchRequestError(
60
+ 'Query rejected',
61
+ new globalThis.Response(null, { status: 422 }),
62
+ )
63
+ let captured: Error | undefined
64
+
65
+ app.use(async (c, next) => {
66
+ await next()
67
+ captured = c.error
68
+ })
69
+ app.get('/', (c) => Response.upstream(c, cause, { page: 584 }))
70
+
71
+ const response = await app.request('/')
72
+ expect(response.status).toMatchInlineSnapshot(`400`)
73
+ expect(await response.json()).toMatchInlineSnapshot(`
74
+ {
75
+ "error": {
76
+ "code": "query_invalid",
77
+ "message": "The requested page was rejected. Use cursor pagination for deep traversal.",
78
+ },
79
+ }
80
+ `)
81
+ expect(captured).toBe(cause)
82
+ })
83
+
84
+ test('keeps timeouts without a deep positional page as upstream errors', async () => {
85
+ const app = new Hono()
86
+ const cause = new Tidx.FetchRequestError(
87
+ 'Request timeout',
88
+ new globalThis.Response(null, { status: 408 }),
89
+ )
90
+ app.get('/', (c) => Response.upstream(c, cause, { page: undefined }))
91
+
92
+ const response = await app.request('/')
93
+ expect(response.status).toMatchInlineSnapshot(`502`)
94
+ expect(await response.json()).toMatchInlineSnapshot(`
95
+ {
96
+ "error": {
97
+ "code": "upstream_error",
98
+ "message": "Upstream service could not complete the request",
99
+ },
100
+ }
101
+ `)
102
+ })
103
+
104
+ test('keeps query rejections without a deep positional page as upstream errors', async () => {
105
+ const app = new Hono()
106
+ const cause = new Tidx.FetchRequestError(
107
+ 'Query rejected',
108
+ new globalThis.Response(null, { status: 422 }),
109
+ )
110
+ app.get('/', (c) => Response.upstream(c, cause, { page: undefined }))
111
+
112
+ const response = await app.request('/')
113
+ expect(response.status).toMatchInlineSnapshot(`502`)
114
+ expect(await response.json()).toMatchInlineSnapshot(`
115
+ {
116
+ "error": {
117
+ "code": "upstream_error",
118
+ "message": "Upstream service could not complete the request",
119
+ },
120
+ }
121
+ `)
122
+ })
28
123
  })
@@ -1,6 +1,8 @@
1
1
  import type { Context } from 'hono'
2
2
  import type * as z from 'zod/mini'
3
3
 
4
+ import * as Tidx from './Tidx.js'
5
+
4
6
  /** Creates a JSON error response. */
5
7
  export function error<const status extends error.Status, const code extends string>(
6
8
  c: Context,
@@ -39,14 +41,34 @@ export function unsupportedChainId(c: Context, chainId: number, supported: Itera
39
41
  }
40
42
 
41
43
  /**
42
- * Maps an unexpected upstream failure to a stable 502 JSON error envelope.
44
+ * Maps upstream failures to 502, except TIDX query failures after the first positional page return 400.
43
45
  * Preserves `Error` causes for reporting and rethrows non-`Error` causes.
44
46
  */
45
- export function upstream(c: Context, cause: unknown) {
47
+ export function upstream(c: Context, cause: unknown): upstream.Response
48
+ export function upstream(
49
+ c: Context,
50
+ cause: unknown,
51
+ options: upstream.Options,
52
+ ): upstream.PageResponse
53
+ export function upstream(c: Context, cause: unknown, options?: upstream.Options) {
46
54
  if (cause instanceof Error) {
47
55
  // Preserve the original error for error-reporting middleware without
48
56
  // exposing provider URLs, payloads, or credentials in the response.
49
57
  c.error = cause
58
+ if (options?.page !== undefined && options.page > 1) {
59
+ if (Tidx.isQueryTimeout(cause))
60
+ return error(c, {
61
+ code: 'query_invalid',
62
+ message: 'The requested page timed out. Use cursor pagination for deep traversal.',
63
+ status: 400,
64
+ })
65
+ if (Tidx.isQueryRejection(cause))
66
+ return error(c, {
67
+ code: 'query_invalid',
68
+ message: 'The requested page was rejected. Use cursor pagination for deep traversal.',
69
+ status: 400,
70
+ })
71
+ }
50
72
  return error(c, {
51
73
  code: 'upstream_error',
52
74
  message: 'Upstream service could not complete the request',
@@ -56,6 +78,22 @@ export function upstream(c: Context, cause: unknown) {
56
78
  throw cause
57
79
  }
58
80
 
81
+ export declare namespace upstream {
82
+ /** Pagination context for classifying a deep-page query failure. */
83
+ type Options = {
84
+ /** Validated positional page number, when requested. */
85
+ page: number | undefined
86
+ }
87
+
88
+ /** Upstream response for routes that support positional pagination. */
89
+ type PageResponse =
90
+ | ReturnType<typeof error<400, 'query_invalid'>>
91
+ | ReturnType<typeof error<502, 'upstream_error'>>
92
+
93
+ /** Default upstream error response. */
94
+ type Response = ReturnType<typeof error<502, 'upstream_error'>>
95
+ }
96
+
59
97
  /**
60
98
  * Validates `value` against `schema`. Returns the parsed value on success or
61
99
  * throws a generic upstream error so the public response body never leaks Zod
@@ -1,3 +1,5 @@
1
+ import * as z from 'zod/mini'
2
+
1
3
  import * as Schema from './Schema.js'
2
4
 
3
5
  describe('ChainId', () => {
@@ -33,6 +35,38 @@ describe('ChainIdQuery', () => {
33
35
  })
34
36
  })
35
37
 
38
+ describe('Limit', () => {
39
+ test('defaults to 10 and accepts page sizes through 50', () => {
40
+ expect(Schema.Limit.parse(undefined)).toMatchInlineSnapshot(`10`)
41
+ expect(Schema.Limit.parse('5')).toMatchInlineSnapshot(`5`)
42
+ expect(Schema.Limit.parse('50')).toMatchInlineSnapshot(`50`)
43
+ })
44
+
45
+ test('caps larger page sizes at 50', () => {
46
+ expect(Schema.Limit.parse('51')).toMatchInlineSnapshot(`50`)
47
+ expect(Schema.Limit.parse('200')).toMatchInlineSnapshot(`50`)
48
+ expect(Schema.Limit.parse('10000')).toMatchInlineSnapshot(`50`)
49
+ })
50
+
51
+ test('rejects page sizes below the minimum', () => {
52
+ expect(Schema.Limit.safeParse('4').success).toMatchInlineSnapshot(`false`)
53
+ })
54
+ })
55
+
56
+ describe('pageChecks', () => {
57
+ const Query = z
58
+ .object({ cursor: Schema.Cursor, limit: Schema.Limit, page: Schema.Page })
59
+ .check(...Schema.pageChecks())
60
+
61
+ test('accepts positional pages through the 500-row window', () => {
62
+ expect(Query.safeParse({ limit: '10', page: '50' }).success).toMatchInlineSnapshot(`true`)
63
+ })
64
+
65
+ test('rejects deeper positional pages', () => {
66
+ expect(Query.safeParse({ limit: '10', page: '51' }).success).toMatchInlineSnapshot(`false`)
67
+ })
68
+ })
69
+
36
70
  describe('timestampBound', () => {
37
71
  test('normalizes RFC 3339 offsets to UTC', () => {
38
72
  const bound = Schema.timestampBound('swaps', 'from')
@@ -191,6 +191,8 @@ export const ErrorDetail = z
191
191
  })
192
192
  .check(z.describe('A single problem with the request.'))
193
193
 
194
+ z.globalRegistry.add(ErrorDetail, { ...z.globalRegistry.get(ErrorDetail), ref: 'ErrorDetail' })
195
+
194
196
  /**
195
197
  * Builds the global error envelope, optionally enumerating `error.code` to a
196
198
  * fixed set of machine-readable codes. Pass the codes a given status can return
@@ -337,11 +339,22 @@ export const TokenAmount = describe(
337
339
  */
338
340
  export const minLimit = 5
339
341
 
342
+ /** Maximum number of rows returned per page. Larger requests are clamped to this value. */
343
+ export const maxLimit = 50
344
+
340
345
  /** Page-size query parameter shared across list endpoints. */
341
346
  export const Limit = z
342
- ._default(z.coerce.number().check(z.int(), z.gte(minLimit), z.lte(200)), 10)
347
+ ._default(
348
+ z.pipe(
349
+ z.coerce.number().check(z.int(), z.gte(minLimit)),
350
+ z.transform((value) => Math.min(value, maxLimit)),
351
+ ),
352
+ 10,
353
+ )
343
354
  .check(
344
- z.describe('How many items to return per page (5\u2013200, default 10).'),
355
+ z.describe(
356
+ 'How many items to return per page (5\u201350, default 10). Use `nextCursor` to fetch more.',
357
+ ),
345
358
  z.meta({ examples: [10] }),
346
359
  )
347
360
 
@@ -373,12 +386,10 @@ export const Cursor = z
373
386
 
374
387
  /**
375
388
  * Maximum page window (`page × limit` rows) accepted by positional pagination.
376
- * Mirrors the indexer's own 10k row ceiling, and the bounded-window convention
377
- * of comparable APIs (Elasticsearch `max_result_window`, Zendesk's 100-page
378
- * cap): shallow page-numbered access is served positionally, deep traversal
379
- * must use cursors.
389
+ * Stays below the indexer's own 10k row ceiling so large offsets do not reach
390
+ * the indexer. Deeper traversal must use cursors.
380
391
  */
381
- export const maxPageWindow = 10_000
392
+ export const maxPageWindow = 500
382
393
 
383
394
  /**
384
395
  * Page-number query parameter (1-indexed) shared by list endpoints that
@@ -432,8 +443,8 @@ export const NextCursor = z
432
443
  * count is computed by a capped subquery (`… LIMIT countCap`) so it can't blow
433
444
  * the indexer's execution budget on the 10⁹-plus row tables; when the bound is
434
445
  * hit the count is a lower bound, signalled by `Meta.totalCountCapped`. Mirrors the
435
- * indexer's own 10k row ceiling (see {@link maxPageWindow}) and the capped-count
436
- * conventions of comparable APIs (Stripe Search's 10k `total_count`,
446
+ * indexer's own 10k row ceiling and the capped-count conventions of comparable
447
+ * APIs (Stripe Search's 10k `total_count`,
437
448
  * Elasticsearch `track_total_hits`, Shopify's `Count.precision`).
438
449
  */
439
450
  export const countCap = 10_000