mppx 0.0.1 → 0.1.1

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 (446) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/dist/BodyDigest.d.ts +42 -0
  4. package/dist/BodyDigest.d.ts.map +1 -0
  5. package/dist/BodyDigest.js +40 -0
  6. package/dist/BodyDigest.js.map +1 -0
  7. package/dist/Challenge.d.ts +271 -0
  8. package/dist/Challenge.d.ts.map +1 -0
  9. package/dist/Challenge.js +291 -0
  10. package/dist/Challenge.js.map +1 -0
  11. package/dist/Credential.d.ts +91 -0
  12. package/dist/Credential.d.ts.map +1 -0
  13. package/dist/Credential.js +122 -0
  14. package/dist/Credential.js.map +1 -0
  15. package/dist/Errors.d.ts +243 -0
  16. package/dist/Errors.d.ts.map +1 -0
  17. package/dist/Errors.js +201 -0
  18. package/dist/Errors.js.map +1 -0
  19. package/dist/Expires.d.ts +15 -0
  20. package/dist/Expires.d.ts.map +1 -0
  21. package/dist/Expires.js +29 -0
  22. package/dist/Expires.js.map +1 -0
  23. package/dist/Intent.d.ts +101 -0
  24. package/dist/Intent.d.ts.map +1 -0
  25. package/dist/Intent.js +83 -0
  26. package/dist/Intent.js.map +1 -0
  27. package/dist/Mcp.d.ts +74 -0
  28. package/dist/Mcp.d.ts.map +1 -0
  29. package/dist/Mcp.js +9 -0
  30. package/dist/Mcp.js.map +1 -0
  31. package/dist/MethodIntent.d.ts +225 -0
  32. package/dist/MethodIntent.d.ts.map +1 -0
  33. package/dist/MethodIntent.js +156 -0
  34. package/dist/MethodIntent.js.map +1 -0
  35. package/dist/PaymentRequest.d.ts +88 -0
  36. package/dist/PaymentRequest.d.ts.map +1 -0
  37. package/dist/PaymentRequest.js +81 -0
  38. package/dist/PaymentRequest.js.map +1 -0
  39. package/dist/Receipt.d.ts +110 -0
  40. package/dist/Receipt.d.ts.map +1 -0
  41. package/dist/Receipt.js +105 -0
  42. package/dist/Receipt.js.map +1 -0
  43. package/dist/Store.d.ts +28 -0
  44. package/dist/Store.d.ts.map +1 -0
  45. package/dist/Store.js +61 -0
  46. package/dist/Store.js.map +1 -0
  47. package/dist/cli.d.ts +3 -0
  48. package/dist/cli.d.ts.map +1 -0
  49. package/dist/cli.js +1219 -0
  50. package/dist/cli.js.map +1 -0
  51. package/dist/client/Methods.d.ts +4 -0
  52. package/dist/client/Methods.d.ts.map +1 -0
  53. package/dist/client/Methods.js +4 -0
  54. package/dist/client/Methods.js.map +1 -0
  55. package/dist/client/Mppx.d.ts +89 -0
  56. package/dist/client/Mppx.d.ts.map +1 -0
  57. package/dist/client/Mppx.js +69 -0
  58. package/dist/client/Mppx.js.map +1 -0
  59. package/dist/client/Transport.d.ts +56 -0
  60. package/dist/client/Transport.d.ts.map +1 -0
  61. package/dist/client/Transport.js +81 -0
  62. package/dist/client/Transport.js.map +1 -0
  63. package/dist/client/index.d.ts +5 -0
  64. package/dist/client/index.d.ts.map +1 -0
  65. package/dist/client/index.js +5 -0
  66. package/dist/client/index.js.map +1 -0
  67. package/dist/client/internal/Fetch.d.ts +87 -0
  68. package/dist/client/internal/Fetch.d.ts.map +1 -0
  69. package/dist/client/internal/Fetch.js +99 -0
  70. package/dist/client/internal/Fetch.js.map +1 -0
  71. package/dist/index.d.ts +13 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +13 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/internal/types.d.ts +302 -0
  76. package/dist/internal/types.d.ts.map +1 -0
  77. package/dist/internal/types.js +2 -0
  78. package/dist/internal/types.js.map +1 -0
  79. package/dist/mcp-sdk/client/McpClient.d.ts +78 -0
  80. package/dist/mcp-sdk/client/McpClient.d.ts.map +1 -0
  81. package/dist/mcp-sdk/client/McpClient.js +98 -0
  82. package/dist/mcp-sdk/client/McpClient.js.map +1 -0
  83. package/dist/mcp-sdk/client/index.d.ts +3 -0
  84. package/dist/mcp-sdk/client/index.d.ts.map +1 -0
  85. package/dist/mcp-sdk/client/index.js +3 -0
  86. package/dist/mcp-sdk/client/index.js.map +1 -0
  87. package/dist/mcp-sdk/server/Transport.d.ts +43 -0
  88. package/dist/mcp-sdk/server/Transport.d.ts.map +1 -0
  89. package/dist/mcp-sdk/server/Transport.js +71 -0
  90. package/dist/mcp-sdk/server/Transport.js.map +1 -0
  91. package/dist/mcp-sdk/server/index.d.ts +2 -0
  92. package/dist/mcp-sdk/server/index.d.ts.map +1 -0
  93. package/dist/mcp-sdk/server/index.js +2 -0
  94. package/dist/mcp-sdk/server/index.js.map +1 -0
  95. package/dist/middlewares/elysia.d.ts +51 -0
  96. package/dist/middlewares/elysia.d.ts.map +1 -0
  97. package/dist/middlewares/elysia.js +59 -0
  98. package/dist/middlewares/elysia.js.map +1 -0
  99. package/dist/middlewares/express.d.ts +46 -0
  100. package/dist/middlewares/express.d.ts.map +1 -0
  101. package/dist/middlewares/express.js +69 -0
  102. package/dist/middlewares/express.js.map +1 -0
  103. package/dist/middlewares/hono.d.ts +46 -0
  104. package/dist/middlewares/hono.d.ts.map +1 -0
  105. package/dist/middlewares/hono.js +57 -0
  106. package/dist/middlewares/hono.js.map +1 -0
  107. package/dist/middlewares/internal/mppx.d.ts +16 -0
  108. package/dist/middlewares/internal/mppx.d.ts.map +1 -0
  109. package/dist/middlewares/internal/mppx.js +16 -0
  110. package/dist/middlewares/internal/mppx.js.map +1 -0
  111. package/dist/middlewares/nextjs.d.ts +45 -0
  112. package/dist/middlewares/nextjs.d.ts.map +1 -0
  113. package/dist/middlewares/nextjs.js +57 -0
  114. package/dist/middlewares/nextjs.js.map +1 -0
  115. package/dist/proxy/Proxy.d.ts +47 -0
  116. package/dist/proxy/Proxy.d.ts.map +1 -0
  117. package/dist/proxy/Proxy.js +126 -0
  118. package/dist/proxy/Proxy.js.map +1 -0
  119. package/dist/proxy/Service.d.ts +100 -0
  120. package/dist/proxy/Service.d.ts.map +1 -0
  121. package/dist/proxy/Service.js +147 -0
  122. package/dist/proxy/Service.js.map +1 -0
  123. package/dist/proxy/index.d.ts +7 -0
  124. package/dist/proxy/index.d.ts.map +1 -0
  125. package/dist/proxy/index.js +7 -0
  126. package/dist/proxy/index.js.map +1 -0
  127. package/dist/proxy/internal/Headers.d.ts +3 -0
  128. package/dist/proxy/internal/Headers.d.ts.map +1 -0
  129. package/dist/proxy/internal/Headers.js +41 -0
  130. package/dist/proxy/internal/Headers.js.map +1 -0
  131. package/dist/proxy/internal/Route.d.ts +14 -0
  132. package/dist/proxy/internal/Route.d.ts.map +1 -0
  133. package/dist/proxy/internal/Route.js +47 -0
  134. package/dist/proxy/internal/Route.js.map +1 -0
  135. package/dist/proxy/services/anthropic.d.ts +29 -0
  136. package/dist/proxy/services/anthropic.d.ts.map +1 -0
  137. package/dist/proxy/services/anthropic.js +30 -0
  138. package/dist/proxy/services/anthropic.js.map +1 -0
  139. package/dist/proxy/services/openai.d.ts +29 -0
  140. package/dist/proxy/services/openai.d.ts.map +1 -0
  141. package/dist/proxy/services/openai.js +30 -0
  142. package/dist/proxy/services/openai.js.map +1 -0
  143. package/dist/proxy/services/stripe.d.ts +29 -0
  144. package/dist/proxy/services/stripe.d.ts.map +1 -0
  145. package/dist/proxy/services/stripe.js +30 -0
  146. package/dist/proxy/services/stripe.js.map +1 -0
  147. package/dist/server/Methods.d.ts +3 -0
  148. package/dist/server/Methods.d.ts.map +1 -0
  149. package/dist/server/Methods.js +3 -0
  150. package/dist/server/Methods.js.map +1 -0
  151. package/dist/server/Mppx.d.ts +116 -0
  152. package/dist/server/Mppx.d.ts.map +1 -0
  153. package/dist/server/Mppx.js +207 -0
  154. package/dist/server/Mppx.js.map +1 -0
  155. package/dist/server/NodeListener.d.ts +3 -0
  156. package/dist/server/NodeListener.d.ts.map +1 -0
  157. package/dist/server/NodeListener.js +3 -0
  158. package/dist/server/NodeListener.js.map +1 -0
  159. package/dist/server/Request.d.ts +24 -0
  160. package/dist/server/Request.d.ts.map +1 -0
  161. package/dist/server/Request.js +26 -0
  162. package/dist/server/Request.js.map +1 -0
  163. package/dist/server/Response.d.ts +10 -0
  164. package/dist/server/Response.d.ts.map +1 -0
  165. package/dist/server/Response.js +15 -0
  166. package/dist/server/Response.js.map +1 -0
  167. package/dist/server/Transport.d.ts +93 -0
  168. package/dist/server/Transport.d.ts.map +1 -0
  169. package/dist/server/Transport.js +132 -0
  170. package/dist/server/Transport.js.map +1 -0
  171. package/dist/server/index.d.ts +9 -0
  172. package/dist/server/index.d.ts.map +1 -0
  173. package/dist/server/index.js +9 -0
  174. package/dist/server/index.js.map +1 -0
  175. package/dist/stripe/Intents.d.ts +54 -0
  176. package/dist/stripe/Intents.d.ts.map +1 -0
  177. package/dist/stripe/Intents.js +27 -0
  178. package/dist/stripe/Intents.js.map +1 -0
  179. package/dist/stripe/client/Charge.d.ts +105 -0
  180. package/dist/stripe/client/Charge.d.ts.map +1 -0
  181. package/dist/stripe/client/Charge.js +74 -0
  182. package/dist/stripe/client/Charge.js.map +1 -0
  183. package/dist/stripe/client/MethodIntents.d.ts +80 -0
  184. package/dist/stripe/client/MethodIntents.d.ts.map +1 -0
  185. package/dist/stripe/client/MethodIntents.js +34 -0
  186. package/dist/stripe/client/MethodIntents.js.map +1 -0
  187. package/dist/stripe/client/index.d.ts +3 -0
  188. package/dist/stripe/client/index.d.ts.map +1 -0
  189. package/dist/stripe/client/index.js +3 -0
  190. package/dist/stripe/client/index.js.map +1 -0
  191. package/dist/stripe/index.d.ts +2 -0
  192. package/dist/stripe/index.d.ts.map +1 -0
  193. package/dist/stripe/index.js +2 -0
  194. package/dist/stripe/index.js.map +1 -0
  195. package/dist/stripe/server/Charge.d.ts +74 -0
  196. package/dist/stripe/server/Charge.d.ts.map +1 -0
  197. package/dist/stripe/server/Charge.js +79 -0
  198. package/dist/stripe/server/Charge.js.map +1 -0
  199. package/dist/stripe/server/MethodIntents.d.ts +65 -0
  200. package/dist/stripe/server/MethodIntents.d.ts.map +1 -0
  201. package/dist/stripe/server/MethodIntents.js +21 -0
  202. package/dist/stripe/server/MethodIntents.js.map +1 -0
  203. package/dist/stripe/server/index.d.ts +3 -0
  204. package/dist/stripe/server/index.d.ts.map +1 -0
  205. package/dist/stripe/server/index.js +3 -0
  206. package/dist/stripe/server/index.js.map +1 -0
  207. package/dist/tempo/Attribution.d.ts +101 -0
  208. package/dist/tempo/Attribution.d.ts.map +1 -0
  209. package/dist/tempo/Attribution.js +124 -0
  210. package/dist/tempo/Attribution.js.map +1 -0
  211. package/dist/tempo/Intents.d.ts +132 -0
  212. package/dist/tempo/Intents.d.ts.map +1 -0
  213. package/dist/tempo/Intents.js +81 -0
  214. package/dist/tempo/Intents.js.map +1 -0
  215. package/dist/tempo/client/ChannelOps.d.ts +54 -0
  216. package/dist/tempo/client/ChannelOps.d.ts.map +1 -0
  217. package/dist/tempo/client/ChannelOps.js +138 -0
  218. package/dist/tempo/client/ChannelOps.js.map +1 -0
  219. package/dist/tempo/client/Charge.d.ts +76 -0
  220. package/dist/tempo/client/Charge.d.ts.map +1 -0
  221. package/dist/tempo/client/Charge.js +69 -0
  222. package/dist/tempo/client/Charge.js.map +1 -0
  223. package/dist/tempo/client/MethodIntents.d.ts +157 -0
  224. package/dist/tempo/client/MethodIntents.d.ts.map +1 -0
  225. package/dist/tempo/client/MethodIntents.js +25 -0
  226. package/dist/tempo/client/MethodIntents.js.map +1 -0
  227. package/dist/tempo/client/Session.d.ts +159 -0
  228. package/dist/tempo/client/Session.d.ts.map +1 -0
  229. package/dist/tempo/client/Session.js +263 -0
  230. package/dist/tempo/client/Session.js.map +1 -0
  231. package/dist/tempo/client/SessionManager.d.ts +62 -0
  232. package/dist/tempo/client/SessionManager.d.ts.map +1 -0
  233. package/dist/tempo/client/SessionManager.js +201 -0
  234. package/dist/tempo/client/SessionManager.js.map +1 -0
  235. package/dist/tempo/client/index.d.ts +6 -0
  236. package/dist/tempo/client/index.d.ts.map +1 -0
  237. package/dist/tempo/client/index.js +5 -0
  238. package/dist/tempo/client/index.js.map +1 -0
  239. package/dist/tempo/index.d.ts +3 -0
  240. package/dist/tempo/index.d.ts.map +1 -0
  241. package/dist/tempo/index.js +3 -0
  242. package/dist/tempo/index.js.map +1 -0
  243. package/dist/tempo/internal/account.d.ts +32 -0
  244. package/dist/tempo/internal/account.d.ts.map +1 -0
  245. package/dist/tempo/internal/account.js +33 -0
  246. package/dist/tempo/internal/account.js.map +1 -0
  247. package/dist/tempo/internal/defaults.d.ts +18 -0
  248. package/dist/tempo/internal/defaults.d.ts.map +1 -0
  249. package/dist/tempo/internal/defaults.js +18 -0
  250. package/dist/tempo/internal/defaults.js.map +1 -0
  251. package/dist/tempo/internal/types.d.ts +11 -0
  252. package/dist/tempo/internal/types.d.ts.map +1 -0
  253. package/dist/tempo/internal/types.js +2 -0
  254. package/dist/tempo/internal/types.js.map +1 -0
  255. package/dist/tempo/server/Charge.d.ts +77 -0
  256. package/dist/tempo/server/Charge.d.ts.map +1 -0
  257. package/dist/tempo/server/Charge.js +228 -0
  258. package/dist/tempo/server/Charge.js.map +1 -0
  259. package/dist/tempo/server/MethodIntents.d.ts +140 -0
  260. package/dist/tempo/server/MethodIntents.d.ts.map +1 -0
  261. package/dist/tempo/server/MethodIntents.js +26 -0
  262. package/dist/tempo/server/MethodIntents.js.map +1 -0
  263. package/dist/tempo/server/Session.d.ts +148 -0
  264. package/dist/tempo/server/Session.d.ts.map +1 -0
  265. package/dist/tempo/server/Session.js +529 -0
  266. package/dist/tempo/server/Session.js.map +1 -0
  267. package/dist/tempo/server/internal/transport.d.ts +47 -0
  268. package/dist/tempo/server/internal/transport.d.ts.map +1 -0
  269. package/dist/tempo/server/internal/transport.js +119 -0
  270. package/dist/tempo/server/internal/transport.js.map +1 -0
  271. package/dist/tempo/stream/Chain.d.ts +52 -0
  272. package/dist/tempo/stream/Chain.d.ts.map +1 -0
  273. package/dist/tempo/stream/Chain.js +215 -0
  274. package/dist/tempo/stream/Chain.js.map +1 -0
  275. package/dist/tempo/stream/Channel.d.ts +26 -0
  276. package/dist/tempo/stream/Channel.d.ts.map +1 -0
  277. package/dist/tempo/stream/Channel.js +27 -0
  278. package/dist/tempo/stream/Channel.js.map +1 -0
  279. package/dist/tempo/stream/ChannelStore.d.ts +103 -0
  280. package/dist/tempo/stream/ChannelStore.d.ts.map +1 -0
  281. package/dist/tempo/stream/ChannelStore.js +100 -0
  282. package/dist/tempo/stream/ChannelStore.js.map +1 -0
  283. package/dist/tempo/stream/Receipt.d.ts +22 -0
  284. package/dist/tempo/stream/Receipt.d.ts.map +1 -0
  285. package/dist/tempo/stream/Receipt.js +34 -0
  286. package/dist/tempo/stream/Receipt.js.map +1 -0
  287. package/dist/tempo/stream/Sse.d.ts +134 -0
  288. package/dist/tempo/stream/Sse.d.ts.map +1 -0
  289. package/dist/tempo/stream/Sse.js +288 -0
  290. package/dist/tempo/stream/Sse.js.map +1 -0
  291. package/dist/tempo/stream/Types.d.ts +78 -0
  292. package/dist/tempo/stream/Types.d.ts.map +1 -0
  293. package/dist/tempo/stream/Types.js +2 -0
  294. package/dist/tempo/stream/Types.js.map +1 -0
  295. package/dist/tempo/stream/Voucher.d.ts +20 -0
  296. package/dist/tempo/stream/Voucher.d.ts.map +1 -0
  297. package/dist/tempo/stream/Voucher.js +98 -0
  298. package/dist/tempo/stream/Voucher.js.map +1 -0
  299. package/dist/tempo/stream/escrow.abi.d.ts +598 -0
  300. package/dist/tempo/stream/escrow.abi.d.ts.map +1 -0
  301. package/dist/tempo/stream/escrow.abi.js +760 -0
  302. package/dist/tempo/stream/escrow.abi.js.map +1 -0
  303. package/dist/tempo/stream/index.d.ts +8 -0
  304. package/dist/tempo/stream/index.d.ts.map +1 -0
  305. package/dist/tempo/stream/index.js +8 -0
  306. package/dist/tempo/stream/index.js.map +1 -0
  307. package/dist/viem/Account.d.ts +12 -0
  308. package/dist/viem/Account.d.ts.map +1 -0
  309. package/dist/viem/Account.js +14 -0
  310. package/dist/viem/Account.js.map +1 -0
  311. package/dist/viem/Client.d.ts +21 -0
  312. package/dist/viem/Client.d.ts.map +1 -0
  313. package/dist/viem/Client.js +19 -0
  314. package/dist/viem/Client.js.map +1 -0
  315. package/dist/zod.d.ts +17 -0
  316. package/dist/zod.d.ts.map +1 -0
  317. package/dist/zod.js +35 -0
  318. package/dist/zod.js.map +1 -0
  319. package/package.json +117 -4
  320. package/src/BodyDigest.test.ts +43 -0
  321. package/src/BodyDigest.ts +53 -0
  322. package/src/Challenge.test-d.ts +81 -0
  323. package/src/Challenge.test.ts +414 -0
  324. package/src/Challenge.ts +429 -0
  325. package/src/Credential.test.ts +227 -0
  326. package/src/Credential.ts +154 -0
  327. package/src/Errors.test.ts +402 -0
  328. package/src/Errors.ts +348 -0
  329. package/src/Expires.ts +34 -0
  330. package/src/Intent.test.ts +180 -0
  331. package/src/Intent.ts +109 -0
  332. package/src/Mcp.ts +81 -0
  333. package/src/MethodIntent.test.ts +303 -0
  334. package/src/MethodIntent.ts +388 -0
  335. package/src/PaymentRequest.test.ts +152 -0
  336. package/src/PaymentRequest.ts +107 -0
  337. package/src/Receipt.test.ts +98 -0
  338. package/src/Receipt.ts +129 -0
  339. package/src/Store.ts +84 -0
  340. package/src/cli.test.ts +542 -0
  341. package/src/cli.ts +1319 -0
  342. package/src/client/Methods.ts +3 -0
  343. package/src/client/Mppx.test-d.ts +90 -0
  344. package/src/client/Mppx.test.ts +468 -0
  345. package/src/client/Mppx.ts +165 -0
  346. package/src/client/Transport.test.ts +283 -0
  347. package/src/client/Transport.ts +115 -0
  348. package/src/client/index.ts +4 -0
  349. package/src/client/internal/Fetch.test-d.ts +57 -0
  350. package/src/client/internal/Fetch.test.ts +315 -0
  351. package/src/client/internal/Fetch.ts +169 -0
  352. package/src/env.d.ts +11 -0
  353. package/src/index.ts +12 -0
  354. package/src/internal/types.ts +403 -0
  355. package/src/mcp-sdk/client/McpClient.test-d.ts +109 -0
  356. package/src/mcp-sdk/client/McpClient.test.ts +219 -0
  357. package/src/mcp-sdk/client/McpClient.ts +187 -0
  358. package/src/mcp-sdk/client/index.ts +2 -0
  359. package/src/mcp-sdk/server/Transport.ts +94 -0
  360. package/src/mcp-sdk/server/index.ts +1 -0
  361. package/src/middlewares/elysia.ts +66 -0
  362. package/src/middlewares/express.test.ts +155 -0
  363. package/src/middlewares/express.ts +82 -0
  364. package/src/middlewares/hono.test.ts +148 -0
  365. package/src/middlewares/hono.ts +62 -0
  366. package/src/middlewares/internal/mppx.ts +30 -0
  367. package/src/middlewares/nextjs.test.ts +164 -0
  368. package/src/middlewares/nextjs.ts +66 -0
  369. package/src/proxy/Proxy.test.ts +472 -0
  370. package/src/proxy/Proxy.ts +175 -0
  371. package/src/proxy/Service.test.ts +125 -0
  372. package/src/proxy/Service.ts +227 -0
  373. package/src/proxy/index.ts +6 -0
  374. package/src/proxy/internal/Headers.test.ts +100 -0
  375. package/src/proxy/internal/Headers.ts +40 -0
  376. package/src/proxy/internal/Route.test.ts +143 -0
  377. package/src/proxy/internal/Route.ts +54 -0
  378. package/src/proxy/services/anthropic.ts +45 -0
  379. package/src/proxy/services/openai.test.ts +97 -0
  380. package/src/proxy/services/openai.ts +48 -0
  381. package/src/proxy/services/stripe.ts +49 -0
  382. package/src/server/Methods.ts +2 -0
  383. package/src/server/Mppx.test-d.ts +343 -0
  384. package/src/server/Mppx.test.ts +342 -0
  385. package/src/server/Mppx.ts +378 -0
  386. package/src/server/NodeListener.test.ts +188 -0
  387. package/src/server/NodeListener.ts +3 -0
  388. package/src/server/Request.test.ts +102 -0
  389. package/src/server/Request.ts +33 -0
  390. package/src/server/Response.test.ts +31 -0
  391. package/src/server/Response.ts +27 -0
  392. package/src/server/Transport.test.ts +294 -0
  393. package/src/server/Transport.ts +222 -0
  394. package/src/server/index.ts +8 -0
  395. package/src/stripe/Charge.integration.test.ts +329 -0
  396. package/src/stripe/Intents.test.ts +52 -0
  397. package/src/stripe/Intents.ts +27 -0
  398. package/src/stripe/client/Charge.ts +115 -0
  399. package/src/stripe/client/MethodIntents.ts +37 -0
  400. package/src/stripe/client/index.ts +2 -0
  401. package/src/stripe/index.ts +1 -0
  402. package/src/stripe/server/Charge.ts +121 -0
  403. package/src/stripe/server/MethodIntents.ts +24 -0
  404. package/src/stripe/server/index.ts +2 -0
  405. package/src/tempo/Attribution.test.ts +187 -0
  406. package/src/tempo/Attribution.ts +156 -0
  407. package/src/tempo/Intents.test.ts +84 -0
  408. package/src/tempo/Intents.ts +93 -0
  409. package/src/tempo/client/ChannelOps.ts +233 -0
  410. package/src/tempo/client/Charge.ts +84 -0
  411. package/src/tempo/client/MethodIntents.ts +28 -0
  412. package/src/tempo/client/Session.ts +369 -0
  413. package/src/tempo/client/SessionManager.test.ts +223 -0
  414. package/src/tempo/client/SessionManager.ts +276 -0
  415. package/src/tempo/client/index.ts +5 -0
  416. package/src/tempo/index.ts +2 -0
  417. package/src/tempo/internal/account.ts +47 -0
  418. package/src/tempo/internal/defaults.ts +20 -0
  419. package/src/tempo/internal/types.ts +8 -0
  420. package/src/tempo/server/Charge.test.ts +847 -0
  421. package/src/tempo/server/Charge.ts +309 -0
  422. package/src/tempo/server/MethodIntents.ts +29 -0
  423. package/src/tempo/server/Session.test.ts +1349 -0
  424. package/src/tempo/server/Session.ts +773 -0
  425. package/src/tempo/server/Sse.test.ts +289 -0
  426. package/src/tempo/server/index.ts +5 -0
  427. package/src/tempo/server/internal/transport.ts +154 -0
  428. package/src/tempo/stream/Chain.ts +333 -0
  429. package/src/tempo/stream/Channel.ts +50 -0
  430. package/src/tempo/stream/ChannelStore.test.ts +473 -0
  431. package/src/tempo/stream/ChannelStore.ts +202 -0
  432. package/src/tempo/stream/Receipt.test.ts +84 -0
  433. package/src/tempo/stream/Receipt.ts +45 -0
  434. package/src/tempo/stream/Sse.test.ts +401 -0
  435. package/src/tempo/stream/Sse.ts +375 -0
  436. package/src/tempo/stream/Types.ts +86 -0
  437. package/src/tempo/stream/Voucher.test.ts +134 -0
  438. package/src/tempo/stream/Voucher.ts +123 -0
  439. package/src/tempo/stream/escrow.abi.ts +759 -0
  440. package/src/tempo/stream/index.ts +7 -0
  441. package/src/tsconfig.json +10 -0
  442. package/src/viem/Account.test.ts +71 -0
  443. package/src/viem/Account.ts +30 -0
  444. package/src/viem/Client.test.ts +58 -0
  445. package/src/viem/Client.ts +33 -0
  446. package/src/zod.ts +47 -0
@@ -0,0 +1,165 @@
1
+ import type * as Challenge from '../Challenge.js'
2
+ import type * as MethodIntent from '../MethodIntent.js'
3
+ import type * as z from '../zod.js'
4
+ import * as Fetch from './internal/Fetch.js'
5
+ import * as Transport from './Transport.js'
6
+
7
+ export type Methods = readonly (MethodIntent.AnyClient | readonly MethodIntent.AnyClient[])[]
8
+
9
+ /**
10
+ * Client-side payment handler.
11
+ */
12
+ export type Mppx<
13
+ methods extends Methods = Methods,
14
+ transport extends Transport.Transport = Transport.Transport,
15
+ > = {
16
+ /** Payment-aware fetch function that automatically handles 402 responses. */
17
+ fetch: Fetch.from.Fetch<FlattenMethods<methods>>
18
+ /** Methods to configure. */
19
+ methods: FlattenMethods<methods>
20
+ /** The transport used. */
21
+ transport: transport
22
+ /** Creates a credential from a payment-required response by routing to the correct method. */
23
+ createCredential: (
24
+ response: Transport.ResponseOf<transport>,
25
+ context?: AnyContextFor<FlattenMethods<methods>> | undefined,
26
+ ) => Promise<string>
27
+ }
28
+
29
+ /**
30
+ * Creates a client-side payment handler from an array of method intents.
31
+ *
32
+ * Returns a payment handler with a `fetch` function that automatically handles
33
+ * 402 Payment Required responses. By default, also polyfills `globalThis.fetch`.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * import { Mppx, tempo } from 'mppx/client'
38
+ *
39
+ * const mppx = Mppx.create({
40
+ * methods: [tempo({ account })],
41
+ * })
42
+ *
43
+ * // Use the returned fetch — handles 402 automatically
44
+ * const res = await mppx.fetch('/resource')
45
+ *
46
+ * // Or use globalThis.fetch (polyfilled by default)
47
+ * const res2 = await fetch('/resource')
48
+ * ```
49
+ */
50
+ export function create<
51
+ const methods extends Methods,
52
+ const transport extends Transport.Transport<any, any> = Transport.Transport<
53
+ RequestInit,
54
+ Response
55
+ >,
56
+ >(config: create.Config<methods, transport>): Mppx<methods, transport> {
57
+ const { onChallenge, polyfill = true, transport = Transport.http() as transport } = config
58
+
59
+ const methods = config.methods.flat() as unknown as FlattenMethods<methods>
60
+
61
+ const resolvedOnChallenge = onChallenge as Fetch.from.Config<
62
+ FlattenMethods<methods>
63
+ >['onChallenge']
64
+ const config_fetch = {
65
+ ...(config.fetch && { fetch: config.fetch }),
66
+ ...(resolvedOnChallenge && { onChallenge: resolvedOnChallenge }),
67
+ methods,
68
+ } satisfies Fetch.from.Config<FlattenMethods<methods>>
69
+ const fetch = Fetch.from<FlattenMethods<methods>>(config_fetch)
70
+
71
+ if (polyfill) Fetch.polyfill(config_fetch)
72
+ return {
73
+ fetch,
74
+ methods,
75
+ transport,
76
+ async createCredential(response: Transport.ResponseOf<transport>, context?: unknown) {
77
+ const challenge = transport.getChallenge(response as never) as Challenge.Challenge
78
+
79
+ const mi = methods.find((m) => m.method === challenge.method && m.name === challenge.intent)
80
+ if (!mi)
81
+ throw new Error(
82
+ `No method intent found for "${challenge.method}.${challenge.intent}". Available: ${methods.map((m) => `${m.method}.${m.name}`).join(', ')}`,
83
+ )
84
+
85
+ const parsedContext =
86
+ mi.context && context !== undefined ? mi.context.parse(context) : undefined
87
+
88
+ return mi.createCredential(
89
+ parsedContext !== undefined
90
+ ? { challenge, context: parsedContext }
91
+ : ({ challenge } as never),
92
+ )
93
+ },
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Restores the original `fetch` after `create()` polyfilled it.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * import { Mppx, tempo } from 'mppx/client'
103
+ *
104
+ * Mppx.create({ methods: [tempo({ account })] })
105
+ *
106
+ * // ... use payment-aware fetch ...
107
+ *
108
+ * Mppx.restore()
109
+ * ```
110
+ */
111
+ export function restore(): void {
112
+ Fetch.restore()
113
+ }
114
+
115
+ export declare namespace create {
116
+ type Config<
117
+ methods extends Methods = Methods,
118
+ transport extends Transport.Transport = Transport.Transport,
119
+ > = {
120
+ /** Custom fetch function to wrap. Defaults to `globalThis.fetch`. */
121
+ fetch?: typeof globalThis.fetch
122
+ /** Called when a 402 challenge is received, before credential creation. */
123
+ onChallenge?:
124
+ | ((
125
+ challenge: Challenge.Challenge,
126
+ helpers: {
127
+ createCredential: (context?: AnyContextFor<FlattenMethods<methods>>) => Promise<string>
128
+ },
129
+ ) => Promise<string | undefined>)
130
+ | undefined
131
+ /** Array of method intents to use. Accepts individual clients or tuples (e.g. from `tempo()`). */
132
+ methods: methods
133
+ /** Whether to polyfill `globalThis.fetch` with the payment-aware wrapper. @default true */
134
+ polyfill?: boolean | undefined
135
+ /** Transport to use (defaults to HTTP). */
136
+ transport?: transport | undefined
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Union of all context types from all methods that have context schemas.
142
+ * @internal
143
+ */
144
+ type AnyContextFor<methods extends readonly MethodIntent.AnyClient[]> = {
145
+ [method in keyof methods]: methods[method] extends MethodIntent.Client<any, infer context>
146
+ ? context extends z.ZodMiniType
147
+ ? z.input<context>
148
+ : undefined
149
+ : undefined
150
+ }[number]
151
+
152
+ /**
153
+ * Flattens a methods config tuple, preserving positional types.
154
+ * @internal
155
+ */
156
+ type FlattenMethods<methods extends Methods> = methods extends readonly [
157
+ infer head,
158
+ ...infer tail extends Methods,
159
+ ]
160
+ ? head extends readonly MethodIntent.AnyClient[]
161
+ ? readonly [...head, ...FlattenMethods<tail>]
162
+ : head extends MethodIntent.AnyClient
163
+ ? readonly [head, ...FlattenMethods<tail>]
164
+ : never
165
+ : readonly []
@@ -0,0 +1,283 @@
1
+ import { Challenge, Credential, Mcp } from 'mppx'
2
+ import { Transport } from 'mppx/client'
3
+ import { MethodIntents as Intents } from 'mppx/tempo'
4
+ import { describe, expect, test } from 'vitest'
5
+
6
+ const realm = 'api.example.com'
7
+ const secretKey = 'test-secret-key'
8
+
9
+ const challenge = Challenge.fromIntent(Intents.charge, {
10
+ realm,
11
+ secretKey,
12
+ request: {
13
+ amount: '0.001',
14
+ currency: '0x20c0000000000000000000000000000000000001',
15
+ decimals: 6,
16
+ recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00',
17
+ expires: '2025-01-01T00:00:00.000Z',
18
+ },
19
+ })
20
+
21
+ const credential = Credential.from({
22
+ challenge,
23
+ payload: { signature: '0xabc123', type: 'transaction' },
24
+ })
25
+
26
+ describe('http', () => {
27
+ describe('isPaymentRequired', () => {
28
+ test('returns true for 402 response', () => {
29
+ const transport = Transport.http()
30
+ const response = new Response(null, { status: 402 })
31
+
32
+ expect(transport.isPaymentRequired(response)).toBe(true)
33
+ })
34
+
35
+ test('returns false for 200 response', () => {
36
+ const transport = Transport.http()
37
+ const response = new Response(null, { status: 200 })
38
+
39
+ expect(transport.isPaymentRequired(response)).toBe(false)
40
+ })
41
+
42
+ test('returns false for other error responses', () => {
43
+ const transport = Transport.http()
44
+ const response = new Response(null, { status: 401 })
45
+
46
+ expect(transport.isPaymentRequired(response)).toBe(false)
47
+ })
48
+ })
49
+
50
+ describe('getChallenge', () => {
51
+ test('default', () => {
52
+ const transport = Transport.http()
53
+ const response = new Response(null, {
54
+ status: 402,
55
+ headers: {
56
+ 'WWW-Authenticate': Challenge.serialize(challenge),
57
+ },
58
+ })
59
+
60
+ expect(transport.getChallenge(response)).toMatchInlineSnapshot(`
61
+ {
62
+ "expires": "2025-01-01T00:00:00.000Z",
63
+ "id": "EUAHxZRCSFB29SAs5TEcB4cQDS0uVDzl8uSYuA58aVs",
64
+ "intent": "charge",
65
+ "method": "tempo",
66
+ "realm": "api.example.com",
67
+ "request": {
68
+ "amount": "1000",
69
+ "currency": "0x20c0000000000000000000000000000000000001",
70
+ "expires": "2025-01-01T00:00:00.000Z",
71
+ "recipient": "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00",
72
+ },
73
+ }
74
+ `)
75
+ })
76
+
77
+ test('throws for non-402 response', () => {
78
+ const transport = Transport.http()
79
+ const response = new Response(null, { status: 200 })
80
+
81
+ expect(() => transport.getChallenge(response)).toThrow()
82
+ })
83
+ })
84
+
85
+ describe('setCredential', () => {
86
+ test('default', () => {
87
+ const transport = Transport.http()
88
+ const serialized = Credential.serialize(credential)
89
+
90
+ const result = transport.setCredential({}, serialized)
91
+ const headers = result.headers as Headers
92
+
93
+ expect(headers.get('Authorization')).toMatchInlineSnapshot(
94
+ `"Payment eyJjaGFsbGVuZ2UiOnsiZXhwaXJlcyI6IjIwMjUtMDEtMDFUMDA6MDA6MDAuMDAwWiIsImlkIjoiRVVBSHhaUkNTRkIyOVNBczVURWNCNGNRRFMwdVZEemw4dVNZdUE1OGFWcyIsImludGVudCI6ImNoYXJnZSIsIm1ldGhvZCI6InRlbXBvIiwicmVhbG0iOiJhcGkuZXhhbXBsZS5jb20iLCJyZXF1ZXN0IjoiZXlKamRYSnlaVzVqZVNJNklqQjRNakJqTURBd01EQXdNREF3TURBd01EQXdNREF3TURBd01EQXdNREF3TURBd01EQXdNREF3TVNJc0ltVjRjR2x5WlhNaU9pSXlNREkxTFRBeExUQXhWREF3T2pBd09qQXdMakF3TUZvaUxDSnlaV05wY0dsbGJuUWlPaUl3ZURjME1tUXpOVU5qTmpZek5FTXdOVE15T1RJMVlUTmlPRFEwUW1NNVpUYzFPVFZtT0daRk1EQWlMQ0poYlc5MWJuUWlPaUl4TURBd0luMCJ9LCJwYXlsb2FkIjp7InNpZ25hdHVyZSI6IjB4YWJjMTIzIiwidHlwZSI6InRyYW5zYWN0aW9uIn19"`,
95
+ )
96
+ })
97
+
98
+ test('preserves existing headers', () => {
99
+ const transport = Transport.http()
100
+ const serialized = Credential.serialize(credential)
101
+
102
+ const result = transport.setCredential(
103
+ { headers: { 'Content-Type': 'application/json' } },
104
+ serialized,
105
+ )
106
+ const headers = result.headers as Headers
107
+
108
+ expect(headers.get('Content-Type')).toBe('application/json')
109
+ })
110
+ })
111
+ })
112
+
113
+ describe('mcp', () => {
114
+ const mcpRequest: Mcp.Request = {
115
+ method: 'tools/call',
116
+ params: {
117
+ name: 'test-tool',
118
+ },
119
+ }
120
+
121
+ describe('isPaymentRequired', () => {
122
+ test('returns true for payment required error', () => {
123
+ const transport = Transport.mcp()
124
+ const response: Mcp.Response = {
125
+ jsonrpc: '2.0',
126
+ id: 1,
127
+ error: {
128
+ code: Mcp.paymentRequiredCode,
129
+ message: 'Payment Required',
130
+ data: {
131
+ httpStatus: 402,
132
+ challenges: [challenge],
133
+ },
134
+ },
135
+ }
136
+
137
+ expect(transport.isPaymentRequired(response)).toBe(true)
138
+ })
139
+
140
+ test('returns false for success response', () => {
141
+ const transport = Transport.mcp()
142
+ const response: Mcp.Response = {
143
+ jsonrpc: '2.0',
144
+ id: 1,
145
+ result: { content: [] },
146
+ }
147
+
148
+ expect(transport.isPaymentRequired(response)).toBe(false)
149
+ })
150
+
151
+ test('returns false for other error codes', () => {
152
+ const transport = Transport.mcp()
153
+ const response: Mcp.Response = {
154
+ jsonrpc: '2.0',
155
+ id: 1,
156
+ error: {
157
+ code: -32600,
158
+ message: 'Invalid Request',
159
+ },
160
+ }
161
+
162
+ expect(transport.isPaymentRequired(response)).toBe(false)
163
+ })
164
+ })
165
+
166
+ describe('getChallenge', () => {
167
+ test('default', () => {
168
+ const transport = Transport.mcp()
169
+ const response: Mcp.Response = {
170
+ jsonrpc: '2.0',
171
+ id: 1,
172
+ error: {
173
+ code: Mcp.paymentRequiredCode,
174
+ message: 'Payment Required',
175
+ data: {
176
+ httpStatus: 402,
177
+ challenges: [challenge],
178
+ },
179
+ },
180
+ }
181
+
182
+ expect(transport.getChallenge(response)).toMatchInlineSnapshot(`
183
+ {
184
+ "expires": "2025-01-01T00:00:00.000Z",
185
+ "id": "EUAHxZRCSFB29SAs5TEcB4cQDS0uVDzl8uSYuA58aVs",
186
+ "intent": "charge",
187
+ "method": "tempo",
188
+ "realm": "api.example.com",
189
+ "request": {
190
+ "amount": "1000",
191
+ "currency": "0x20c0000000000000000000000000000000000001",
192
+ "expires": "2025-01-01T00:00:00.000Z",
193
+ "recipient": "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00",
194
+ },
195
+ }
196
+ `)
197
+ })
198
+
199
+ test('throws for success response', () => {
200
+ const transport = Transport.mcp()
201
+ const response: Mcp.Response = {
202
+ jsonrpc: '2.0',
203
+ id: 1,
204
+ result: { content: [] },
205
+ }
206
+
207
+ expect(() => transport.getChallenge(response)).toThrow('Response is not an error')
208
+ })
209
+
210
+ test('throws when no challenges in error', () => {
211
+ const transport = Transport.mcp()
212
+ const response: Mcp.Response = {
213
+ jsonrpc: '2.0',
214
+ id: 1,
215
+ error: {
216
+ code: Mcp.paymentRequiredCode,
217
+ message: 'Payment Required',
218
+ data: {
219
+ httpStatus: 402,
220
+ challenges: [],
221
+ },
222
+ },
223
+ }
224
+
225
+ expect(() => transport.getChallenge(response)).toThrow('No challenge in error response')
226
+ })
227
+ })
228
+
229
+ describe('setCredential', () => {
230
+ test('default', () => {
231
+ const transport = Transport.mcp()
232
+ const serialized = Credential.serialize(credential)
233
+
234
+ expect(transport.setCredential(mcpRequest, serialized)).toMatchInlineSnapshot(`
235
+ {
236
+ "method": "tools/call",
237
+ "params": {
238
+ "_meta": {
239
+ "org.paymentauth/credential": {
240
+ "challenge": {
241
+ "expires": "2025-01-01T00:00:00.000Z",
242
+ "id": "EUAHxZRCSFB29SAs5TEcB4cQDS0uVDzl8uSYuA58aVs",
243
+ "intent": "charge",
244
+ "method": "tempo",
245
+ "realm": "api.example.com",
246
+ "request": {
247
+ "amount": "1000",
248
+ "currency": "0x20c0000000000000000000000000000000000001",
249
+ "expires": "2025-01-01T00:00:00.000Z",
250
+ "recipient": "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE00",
251
+ },
252
+ },
253
+ "payload": {
254
+ "signature": "0xabc123",
255
+ "type": "transaction",
256
+ },
257
+ },
258
+ },
259
+ "name": "test-tool",
260
+ },
261
+ }
262
+ `)
263
+ })
264
+
265
+ test('preserves existing _meta', () => {
266
+ const transport = Transport.mcp()
267
+ const serialized = Credential.serialize(credential)
268
+ const requestWithMeta: Mcp.Request = {
269
+ ...mcpRequest,
270
+ params: {
271
+ ...mcpRequest.params,
272
+ _meta: {
273
+ existingKey: 'existingValue',
274
+ },
275
+ },
276
+ }
277
+
278
+ const result = transport.setCredential(requestWithMeta, serialized)
279
+
280
+ expect(result.params?._meta?.existingKey).toBe('existingValue')
281
+ })
282
+ })
283
+ })
@@ -0,0 +1,115 @@
1
+ import * as Challenge from '../Challenge.js'
2
+ import * as Credential from '../Credential.js'
3
+ import * as Mcp from '../Mcp.js'
4
+
5
+ /**
6
+ * Client-side transport adapter.
7
+ *
8
+ * Abstracts how challenges are received and credentials are sent
9
+ * across different transport protocols (HTTP, MCP, etc.).
10
+ */
11
+ export type Transport<in out request = unknown, in out response = unknown> = {
12
+ /** Transport name for identification. */
13
+ name: string
14
+ /** Checks if a response indicates payment is required. */
15
+ isPaymentRequired: (response: response) => boolean
16
+ /** Extracts the challenge from a payment-required response. */
17
+ getChallenge: (response: response) => Challenge.Challenge
18
+ /** Attaches a credential to a request. */
19
+ setCredential: (request: request, credential: string) => request
20
+ }
21
+ export type AnyTransport = Transport<any, any>
22
+
23
+ /** Extracts the response type from a transport. */
24
+ export type ResponseOf<transport extends Transport> =
25
+ transport extends Transport<any, infer response> ? response : never
26
+
27
+ /** Extracts the request type from a transport. */
28
+ export type RequestOf<transport extends Transport> =
29
+ transport extends Transport<infer request, any> ? request : never
30
+
31
+ /**
32
+ * Creates a custom client-side transport.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * import { Transport } from 'mppx/client'
37
+ *
38
+ * const custom = Transport.from({
39
+ * name: 'custom',
40
+ * isPaymentRequired(response) { ... },
41
+ * getChallenge(response) { ... },
42
+ * setCredential(request, credential) { ... },
43
+ * })
44
+ * ```
45
+ */
46
+ export function from<request, response>(
47
+ transport: Transport<request, response>,
48
+ ): Transport<request, response> {
49
+ return transport
50
+ }
51
+
52
+ /**
53
+ * HTTP transport for client-side payment handling.
54
+ *
55
+ * - Detects payment required via 402 status
56
+ * - Extracts challenges from `WWW-Authenticate` header
57
+ * - Sends credentials via `Authorization` header
58
+ */
59
+ export function http() {
60
+ return from<RequestInit, Response>({
61
+ name: 'http',
62
+
63
+ isPaymentRequired(response) {
64
+ return response.status === 402
65
+ },
66
+
67
+ getChallenge(response) {
68
+ return Challenge.fromResponse(response)
69
+ },
70
+
71
+ setCredential(request, credential) {
72
+ const headers = new Headers(request.headers)
73
+ headers.set('Authorization', credential)
74
+ return { ...request, headers }
75
+ },
76
+ })
77
+ }
78
+
79
+ /**
80
+ * MCP transport for client-side payment handling.
81
+ *
82
+ * - Detects payment required via error code -32042
83
+ * - Extracts challenges from `error.data.challenges[0]`
84
+ * - Sends credentials via `_meta["org.paymentauth/credential"]`
85
+ */
86
+ export function mcp() {
87
+ return from<Mcp.Request, Mcp.Response>({
88
+ name: 'mcp',
89
+
90
+ isPaymentRequired(response) {
91
+ return 'error' in response && response.error?.code === Mcp.paymentRequiredCode
92
+ },
93
+
94
+ getChallenge(response) {
95
+ if (!('error' in response) || !response.error) throw new Error('Response is not an error.')
96
+ const challenge = response.error.data?.challenges[0]
97
+ if (!challenge) throw new Error('No challenge in error response.')
98
+ return challenge
99
+ },
100
+
101
+ setCredential(request, credential) {
102
+ const parsed = Credential.deserialize(credential)
103
+ return {
104
+ ...request,
105
+ params: {
106
+ ...request.params,
107
+ _meta: {
108
+ ...request.params?._meta,
109
+ [Mcp.credentialMetaKey]: parsed,
110
+ },
111
+ },
112
+ }
113
+ },
114
+ })
115
+ }
@@ -0,0 +1,4 @@
1
+ export * as Expires from '../Expires.js'
2
+ export { session, stripe, tempo } from './Methods.js'
3
+ export * as Mppx from './Mppx.js'
4
+ export * as Transport from './Transport.js'
@@ -0,0 +1,57 @@
1
+ import type { Account } from 'viem'
2
+ import { describe, expectTypeOf, test } from 'vitest'
3
+ import { charge } from '../../tempo/client/Charge.js'
4
+ import * as Fetch from './Fetch.js'
5
+
6
+ describe('Fetch.from', () => {
7
+ test('default', () => {
8
+ const fetch = Fetch.from({
9
+ methods: [charge()],
10
+ })
11
+
12
+ expectTypeOf(fetch).toBeFunction()
13
+ expectTypeOf(fetch).returns.toMatchTypeOf<Promise<Response>>()
14
+ })
15
+
16
+ test('behavior: accepts context in RequestInit when method has context', () => {
17
+ const fetch = Fetch.from({
18
+ methods: [charge()],
19
+ })
20
+
21
+ expectTypeOf(fetch).toBeCallableWith('https://example.com', {
22
+ context: { account: {} as Account },
23
+ })
24
+ })
25
+
26
+ test('behavior: context is optional in RequestInit', () => {
27
+ const fetch = Fetch.from({
28
+ methods: [charge()],
29
+ })
30
+
31
+ expectTypeOf(fetch).toBeCallableWith('https://example.com')
32
+ expectTypeOf(fetch).toBeCallableWith('https://example.com', {})
33
+ })
34
+
35
+ test('behavior: RequestInit extends standard RequestInit', () => {
36
+ const fetch = Fetch.from({
37
+ methods: [charge()],
38
+ })
39
+
40
+ expectTypeOf(fetch).toBeCallableWith('https://example.com', {
41
+ method: 'POST',
42
+ headers: { 'Content-Type': 'application/json' },
43
+ body: JSON.stringify({ foo: 'bar' }),
44
+ })
45
+ })
46
+ })
47
+
48
+ describe('Fetch.from.RequestInit', () => {
49
+ test('behavior: has context property typed to method context', () => {
50
+ const method = charge()
51
+
52
+ type Methods = [typeof method]
53
+ type Init = Fetch.from.RequestInit<Methods>
54
+
55
+ expectTypeOf<Init>().toHaveProperty('context')
56
+ })
57
+ })