diff --git a/package.json b/package.json index 80ec52bc..ec5f3d23 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "sql-formatter": "^15.7.3", "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.2", + "tapimo": "0.0.1", "unified": "^11.0.5", "unplugin-auto-import": "^21.0.0", "unplugin-icons": "^23.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eacd4cbf..f9111441 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -120,6 +120,9 @@ importers: tailwindcss: specifier: ^4.2.2 version: 4.2.2 + tapimo: + specifier: 0.0.1 + version: 0.0.1(04687d79abcc92c1f3b5219c6c82df03) unified: specifier: ^11.0.5 version: 11.0.5 @@ -645,6 +648,12 @@ packages: peerDependencies: hono: ^4 + '@hono/standard-validator@0.2.3': + resolution: {integrity: sha512-bp9vHu6Va6SfMHC3D4ZLBbT/woi+AZ9CRdTXQu3kLJuLh2W/Gb9UO4hijS+BQAGFXi4EGpXdetxpzwTAawSVeg==} + peerDependencies: + '@standard-schema/spec': ^1.0.0 + hono: '>=3.9.0' + '@iconify-json/lucide@1.2.102': resolution: {integrity: sha512-Dm3EEqu5NrmzyDMB2U1+8yroEj2/dB9V4KlH0m/szwwF/ofSf0cPaGTZqkd1aExXjCor+vU53ttRMCGuXf+/cg==} @@ -1208,6 +1217,10 @@ packages: resolution: {integrity: sha512-E6beEdTsJxUStxOmY1knQvSNJq6LTiXOsRX2WTrfmU6d/kiATn6IKkAU0kXtAZkaYCGU4UCEmBFHCMmNKn0JLA==} engines: {node: '>=22'} + '@scalar/openapi-types@0.8.0': + resolution: {integrity: sha512-WmaxVSfvY5K/TwcG2B2TU1WOe1As1uc2s7myswtP6dBlcjU3hM08SApxv/jmyGaCE8t4gO5BBhmHY4pDUfmr2g==} + engines: {node: '>=22'} + '@scalar/openapi-types@0.9.1': resolution: {integrity: sha512-gkGhSkxSzADaBiNg+ZAbJuwj+ZUmzP2Pg9CWZ7ZP+0fck2WjPeDDM7aAbouAm0aQQMF9xBjSPXSA9a/qTHYaTw==} engines: {node: '>=22'} @@ -1307,6 +1320,67 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} + '@standard-community/standard-json@0.3.5': + resolution: {integrity: sha512-4+ZPorwDRt47i+O7RjyuaxHRK/37QY/LmgxlGrRrSTLYoFatEOzvqIc85GTlM18SFZ5E91C+v0o/M37wZPpUHA==} + peerDependencies: + '@standard-schema/spec': ^1.0.0 + '@types/json-schema': ^7.0.15 + '@valibot/to-json-schema': ^1.3.0 + arktype: ^2.1.20 + effect: ^3.16.8 + quansync: ^0.2.11 + sury: ^10.0.0 + typebox: ^1.0.17 + valibot: ^1.1.0 + zod: ^3.25.0 || ^4.0.0 + zod-to-json-schema: ^3.24.5 + peerDependenciesMeta: + '@valibot/to-json-schema': + optional: true + arktype: + optional: true + effect: + optional: true + sury: + optional: true + typebox: + optional: true + valibot: + optional: true + zod: + optional: true + zod-to-json-schema: + optional: true + + '@standard-community/standard-openapi@0.2.9': + resolution: {integrity: sha512-htj+yldvN1XncyZi4rehbf9kLbu8os2Ke/rfqoZHCMHuw34kiF3LP/yQPdA0tQ940y8nDq3Iou8R3wG+AGGyvg==} + peerDependencies: + '@standard-community/standard-json': ^0.3.5 + '@standard-schema/spec': ^1.0.0 + arktype: ^2.1.20 + effect: ^3.17.14 + openapi-types: ^12.1.3 + sury: ^10.0.0 + typebox: ^1.0.0 + valibot: ^1.1.0 + zod: ^3.25.0 || ^4.0.0 + zod-openapi: ^4 + peerDependenciesMeta: + arktype: + optional: true + effect: + optional: true + sury: + optional: true + typebox: + optional: true + valibot: + optional: true + zod: + optional: true + zod-openapi: + optional: true + '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} @@ -3018,6 +3092,21 @@ packages: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} + hono-openapi@1.3.0: + resolution: {integrity: sha512-xDvCWpWEIv0weEmnl3EjRQzqbHIO8LnfzMuYOCmbuyE5aes6aXxLg4vM3ybnoZD5TiTUkA6PuRQPJs3R7WRBig==} + peerDependencies: + '@hono/standard-validator': ^0.2.0 + '@standard-community/standard-json': ^0.3.5 + '@standard-community/standard-openapi': ^0.2.9 + '@types/json-schema': ^7.0.15 + hono: ^4.8.3 + openapi-types: ^12.1.3 + peerDependenciesMeta: + '@hono/standard-validator': + optional: true + hono: + optional: true + hono@4.12.26: resolution: {integrity: sha512-uyZtpnYxM9CmQ7QsQknM4zN8EftNqhON1qYeIKM0Se67CCEe2c44xyGURwB0axX2fBDu1dqHrHAc1hmNT8ITkw==} engines: {node: '>=16.9.0'} @@ -3070,6 +3159,11 @@ packages: import-meta-resolve@4.2.0: resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + incur@0.4.10: + resolution: {integrity: sha512-u35+Ba0oJOPQnAYxYPo5j91P/rI9kTtpDf/iJe6kOs335iguz8mYnVguex4NP6GmIP6uc7iqUWY5cmdc/0MwTw==} + engines: {node: '>=22'} + hasBin: true + incur@0.4.5: resolution: {integrity: sha512-4WFlqm5e+IKNoX+lDIjjpebO8ResPx3vPUBChxNfnNo3oGp0ooo6piiiTspOMub2dq2mcG/AmlUq0ejuGfKobg==} engines: {node: '>=22'} @@ -3211,6 +3305,10 @@ packages: khroma@2.1.0: resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + kysely@0.28.17: + resolution: {integrity: sha512-nbD8lB9EB3wNdMhOCdx5Li8DxnLbvKByylRLcJ1h+4SkrowVeECAyZlyiKMThF7xFdRz0jSQ2MoJr+wXux2y0Q==} + engines: {node: '>=20.0.0'} + langium@4.2.2: resolution: {integrity: sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ==} engines: {node: '>=20.10.0', npm: '>=10.2.3'} @@ -3578,6 +3676,9 @@ packages: typescript: optional: true + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mlly@1.8.2: resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} @@ -3606,6 +3707,25 @@ packages: hono: optional: true + mppx@0.6.31: + resolution: {integrity: sha512-euHHDLjNa9DQdPSzpayRBhUb3YVGSNZhVAzoOPmjzqxcEb77ry59uaeSBsWr3IjSxqmpR45cB6aR0uiNSgO6kA==} + hasBin: true + peerDependencies: + '@modelcontextprotocol/sdk': '>=1.25.0' + elysia: '>=1' + express: '>=5' + hono: '>=4.12.18' + viem: '>=2.51.0' + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + elysia: + optional: true + express: + optional: true + hono: + optional: true + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3782,6 +3902,9 @@ packages: oniguruma-to-es@4.3.6: resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + outvariant@1.4.0: resolution: {integrity: sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw==} @@ -3793,6 +3916,22 @@ packages: typescript: optional: true + ox@0.14.25: + resolution: {integrity: sha512-8DoibKtxE8yw63Y2jjMhlbjaURev6WCx4QR4MWLusl2/qIaeTzMJMBIYIDl1KOF45+8H1Ur6eLTdPlUoO8PlRw==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.14.27: + resolution: {integrity: sha512-+xhLHo/f+f4BH121/1Pomm/1vgBBda1wYiFpTvjSo8o5OcEj76Pf1hGPJiepoYMTQoTm2SKdSBvWkFWk5l07PA==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + ox@0.14.29: resolution: {integrity: sha512-M5j87Ec4V99MQdRct/g09eWXW60g6zhHTUs1lr4deUtrPDnezBdCJTgKd7pxqTpSZBFveV0ALi9jMMuT1qKyNg==} peerDependencies: @@ -4319,6 +4458,9 @@ packages: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} + tapimo@0.0.1: + resolution: {integrity: sha512-JjBmtWEGjEnVyrObc9bsG0qnTeswSPLMaYexRKL7EpWwxP3QWkqHxDo16RLnBHeSdSv4xosSNIfbl24ik26EZw==} + tar@7.5.13: resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} engines: {node: '>=18'} @@ -4378,6 +4520,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tidx.ts@0.1.1: + resolution: {integrity: sha512-XFoDuwCQwkERGRYB+QGQvzH//Y6kDknttWSts3durreALgkrKOCM9mUDfgRVg3zVisuQgx5RfvoJmO8x8oXm+g==} + time-span@5.1.0: resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} engines: {node: '>=12'} @@ -4606,6 +4751,14 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + viem@2.51.3: + resolution: {integrity: sha512-DA4EbrsvatzzLo6MwcWWiv6kI6dIr3I9HH9B6qsJaClN/s0AjIDUz5RIxl+VmGrovIUCcIvG8744yuGH7d37zw==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + viem@2.53.1: resolution: {integrity: sha512-FhfJ/SW73CVosiyVLmIMVgKDRKYV1AGCLzZoHYvmNayyVff63Qi1ocPCk59LqC/cNw244RbBJjHnmxqXkE7NpA==} peerDependencies: @@ -4720,6 +4873,26 @@ packages: jsdom: optional: true + vocs@2.2.5: + resolution: {integrity: sha512-BSRSu4EIeHsUTo3BFP6OW/a26F87mlFW6HQASqQAW3+wB52pQMo/6l8Ui3SmuMiIiUIbkzTEYRi765lXZ0aC6Q==} + hasBin: true + peerDependencies: + '@vocs/twoslash-rust': ^0.1.0 + mermaid: ^11 + react: ^19 + react-dom: ^19 + vite: ^8 + waku: ^1.0.0-beta.3 + peerDependenciesMeta: + '@vocs/twoslash-rust': + optional: true + mermaid: + optional: true + vite: + optional: true + waku: + optional: true + vocs@2.3.0: resolution: {integrity: sha512-pWfoG3J2iUrllEKZi83TkR+53tXl9HAvZ47lPuwH/8r866Hp7B/zBbcaDF2hDK2BCpIsTcZb+EN+yh0ViHph7w==} hasBin: true @@ -5408,6 +5581,11 @@ snapshots: dependencies: hono: 4.12.26 + '@hono/standard-validator@0.2.3(@standard-schema/spec@1.1.0)(hono@4.12.26)': + dependencies: + '@standard-schema/spec': 1.1.0 + hono: 4.12.26 + '@iconify-json/lucide@1.2.102': dependencies: '@iconify/types': 2.0.0 @@ -6049,6 +6227,8 @@ snapshots: leven: 4.1.0 yaml: 2.9.0 + '@scalar/openapi-types@0.8.0': {} + '@scalar/openapi-types@0.9.1': {} '@scalar/openapi-upgrader@0.2.9': @@ -6225,6 +6405,23 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} + '@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6)': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/json-schema': 7.0.15 + quansync: 0.2.11 + optionalDependencies: + zod: 4.3.6 + zod-to-json-schema: 3.25.2(zod@4.3.6) + + '@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6)': + dependencies: + '@standard-community/standard-json': 0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6) + '@standard-schema/spec': 1.1.0 + openapi-types: 12.1.3 + optionalDependencies: + zod: 4.3.6 + '@standard-schema/spec@1.0.0': {} '@standard-schema/spec@1.1.0': {} @@ -8018,6 +8215,16 @@ snapshots: highlight.js@11.11.1: {} + hono-openapi@1.3.0(@hono/standard-validator@0.2.3(@standard-schema/spec@1.1.0)(hono@4.12.26))(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6))(@types/json-schema@7.0.15)(hono@4.12.26)(openapi-types@12.1.3): + dependencies: + '@standard-community/standard-json': 0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6) + '@standard-community/standard-openapi': 0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6) + '@types/json-schema': 7.0.15 + openapi-types: 12.1.3 + optionalDependencies: + '@hono/standard-validator': 0.2.3(@standard-schema/spec@1.1.0)(hono@4.12.26) + hono: 4.12.26 + hono@4.12.26: {} html-void-elements@3.0.0: {} @@ -8067,6 +8274,16 @@ snapshots: import-meta-resolve@4.2.0: {} + incur@0.4.10: + dependencies: + '@cfworker/json-schema': 4.1.1 + '@modelcontextprotocol/server': 2.0.0-alpha.2(@cfworker/json-schema@4.1.1) + '@scalar/openapi-types': 0.8.0 + '@toon-format/toon': 2.1.0 + tokenx: 1.3.0 + yaml: 2.9.0 + zod: 4.4.3 + incur@0.4.5: dependencies: '@cfworker/json-schema': 4.1.1 @@ -8168,6 +8385,8 @@ snapshots: khroma@2.1.0: {} + kysely@0.28.17: {} + langium@4.2.2: dependencies: '@chevrotain/regexp-to-ast': 12.0.0 @@ -8813,6 +9032,8 @@ snapshots: optionalDependencies: typescript: 5.9.3 + mitt@3.0.1: {} + mlly@1.8.2: dependencies: acorn: 8.17.0 @@ -8840,6 +9061,19 @@ snapshots: transitivePeerDependencies: - typescript + mppx@0.6.31(@modelcontextprotocol/sdk@1.29.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(express@5.2.1)(hono@4.12.26)(typescript@5.9.3)(viem@2.51.3(typescript@5.9.3)(zod@4.4.3)): + dependencies: + incur: 0.4.10 + ox: 0.14.27(typescript@5.9.3)(zod@4.4.3) + viem: 2.51.3(typescript@5.9.3)(zod@4.4.3) + zod: 4.4.3 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.29.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + express: 5.2.1 + hono: 4.12.26 + transitivePeerDependencies: + - typescript + ms@2.1.3: {} mz@2.7.0: @@ -8906,6 +9140,8 @@ snapshots: regex: 6.1.0 regex-recursion: 6.0.2 + openapi-types@12.1.3: {} + outvariant@1.4.0: {} ox@0.14.20(typescript@5.9.3)(zod@4.3.6): @@ -8938,6 +9174,36 @@ snapshots: transitivePeerDependencies: - zod + ox@0.14.25(typescript@5.9.3)(zod@4.4.3): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3)(zod@4.4.3) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.14.27(typescript@5.9.3)(zod@4.4.3): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3)(zod@4.4.3) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + ox@0.14.29(typescript@5.9.3)(zod@4.3.6): dependencies: '@adraffy/ens-normalize': 1.11.1 @@ -9645,6 +9911,70 @@ snapshots: tapable@2.3.3: {} + tapimo@0.0.1(04687d79abcc92c1f3b5219c6c82df03): + dependencies: + '@hono/node-server': 2.0.5(hono@4.12.26) + '@hono/standard-validator': 0.2.3(@standard-schema/spec@1.1.0)(hono@4.12.26) + hono: 4.12.26 + hono-openapi: 1.3.0(@hono/standard-validator@0.2.3(@standard-schema/spec@1.1.0)(hono@4.12.26))(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6))(@types/json-schema@7.0.15)(hono@4.12.26)(openapi-types@12.1.3) + incur: 0.4.10 + jose: 6.2.3 + mppx: 0.6.31(@modelcontextprotocol/sdk@1.29.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(express@5.2.1)(hono@4.12.26)(typescript@5.9.3)(viem@2.51.3(typescript@5.9.3)(zod@4.4.3)) + nanoid: 5.1.15 + ox: 0.14.27(typescript@5.9.3)(zod@4.4.3) + tidx.ts: 0.1.1(typescript@5.9.3) + viem: 2.51.3(typescript@5.9.3)(zod@4.4.3) + vocs: 2.2.5(@cfworker/json-schema@4.1.1)(@types/react@19.2.14)(@vue/compiler-sfc@3.5.38)(change-case@5.4.4)(idb-keyval@6.2.2)(mermaid@11.14.0)(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)))(react@19.2.6)(rollup@4.60.1)(typescript@5.9.3)(vite@8.0.16(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(waku@1.0.0-beta.0(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)))(react@19.2.6)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + zod: 4.4.3 + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@date-fns/tz' + - '@modelcontextprotocol/sdk' + - '@remix-run/react' + - '@rolldown/plugin-babel' + - '@standard-community/standard-json' + - '@standard-community/standard-openapi' + - '@standard-schema/spec' + - '@svgx/core' + - '@tanstack/react-router' + - '@types/json-schema' + - '@types/react' + - '@vocs/twoslash-rust' + - '@vue/compiler-sfc' + - '@vue/composition-api' + - async-validator + - axios + - babel-plugin-react-compiler + - bufferutil + - change-case + - date-fns + - drauu + - elysia + - express + - idb-keyval + - jwt-decode + - mermaid + - next + - nprogress + - openapi-types + - qrcode + - react + - react-dom + - react-router + - react-router-dom + - react-server-dom-webpack + - rollup + - sortablejs + - supports-color + - svelte + - typescript + - universal-cookie + - utf-8-validate + - vite + - vue-template-compiler + - vue-template-es2015-compiler + - waku + tar@7.5.13: dependencies: '@isaacs/fs-minipass': 4.0.1 @@ -9678,6 +10008,16 @@ snapshots: dependencies: any-promise: 1.3.0 + tidx.ts@0.1.1(typescript@5.9.3): + dependencies: + abitype: 1.2.3(typescript@5.9.3)(zod@4.4.3) + kysely: 0.28.17 + mitt: 3.0.1 + ox: 0.14.20(typescript@5.9.3)(zod@4.4.3) + zod: 4.4.3 + transitivePeerDependencies: + - typescript + time-span@5.1.0: dependencies: convert-hrtime: 5.0.0 @@ -9907,6 +10247,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 + viem@2.51.3(typescript@5.9.3)(zod@4.4.3): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3)(zod@4.4.3) + isows: 1.0.7(ws@8.20.1) + ox: 0.14.25(typescript@5.9.3)(zod@4.4.3) + ws: 8.20.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + viem@2.53.1(typescript@5.9.3)(zod@4.3.6): dependencies: '@noble/curves': 1.9.1 @@ -9986,6 +10343,123 @@ snapshots: transitivePeerDependencies: - msw + vocs@2.2.5(@cfworker/json-schema@4.1.1)(@types/react@19.2.14)(@vue/compiler-sfc@3.5.38)(change-case@5.4.4)(idb-keyval@6.2.2)(mermaid@11.14.0)(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)))(react@19.2.6)(rollup@4.60.1)(typescript@5.9.3)(vite@8.0.16(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(waku@1.0.0-beta.0(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)))(react@19.2.6)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)): + dependencies: + '@base-ui/react': 1.6.0(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@codesandbox/sandpack-react': 2.20.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@hono/node-server': 2.0.5(hono@4.12.26) + '@iconify-json/lucide': 1.2.102 + '@iconify-json/simple-icons': 1.2.77 + '@iconify-json/vscode-icons': 1.2.58 + '@iconify/types': 2.0.0 + '@iconify/utils': 3.1.3 + '@mdx-js/mdx': 3.1.1 + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.6) + '@mdx-js/rollup': 3.1.1(rollup@4.60.1) + '@modelcontextprotocol/sdk': 1.29.0(@cfworker/json-schema@4.1.1)(zod@4.4.3) + '@remix-run/node-fetch-server': 0.13.3 + '@scalar/api-client': 3.10.4(change-case@5.4.4)(idb-keyval@6.2.2)(tailwindcss@4.3.1)(typescript@5.9.3) + '@scalar/openapi-parser': 0.28.7 + '@scalar/snippetz': 0.9.17 + '@scalar/workspace-store': 0.54.4(typescript@5.9.3) + '@shikijs/rehype': 3.23.0 + '@shikijs/transformers': 3.23.0 + '@shikijs/twoslash': 3.23.0(typescript@5.9.3) + '@shikijs/types': 3.23.0 + '@svgr/core': 8.1.0(typescript@5.9.3) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) + '@tailwindcss/vite': 4.3.0(vite@8.0.16(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + '@takumi-rs/image-response': 0.62.8 + '@takumi-rs/wasm': 0.62.8 + '@vitejs/plugin-react': 6.0.2(vite@8.0.16(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + '@vitejs/plugin-rsc': 0.5.27(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)))(react@19.2.6)(vite@8.0.16(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + cac: 6.7.14 + cva: class-variance-authority@0.7.1 + debug: 4.4.3 + esast-util-from-js: 2.0.1 + estree-util-value-to-estree: 3.5.0 + estree-util-visit: 2.0.0 + extend: 3.0.2 + github-slugger: 2.0.0 + hono: 4.12.26 + image-size: 2.0.2 + lz-string: 1.5.0 + magic-string: 0.30.21 + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm: 3.1.0 + mdast-util-mdx: 3.0.0 + mdast-util-to-hast: 13.2.1 + mdast-util-to-markdown: 2.1.2 + mdast-util-to-string: 4.0.0 + micromark-extension-gfm: 3.0.0 + minisearch: 7.2.0 + nuqs: 2.8.9(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-error-boundary: 6.1.2(react@19.2.6) + rehype-autolink-headings: 7.1.0 + rehype-slug: 6.0.0 + rehype-stringify: 10.0.1 + remark-directive: 4.0.0 + remark-frontmatter: 5.0.0 + remark-gfm: 4.0.1 + remark-mdx: 3.1.1 + remark-mdx-frontmatter: 5.2.0 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remark-stringify: 11.0.0 + shiki: 3.23.0 + sucrase: 3.35.1 + tailwindcss: 4.3.1 + tailwindcss-logical: 4.2.0(tailwindcss@4.3.1) + tsx: 4.21.0 + twoslash: 0.3.8(typescript@5.9.3) + unified: 11.0.5 + unist-util-visit: 5.1.0 + unplugin-icons: 22.5.0(@svgr/core@8.1.0(typescript@5.9.3))(@vue/compiler-sfc@3.5.38) + urlpattern-polyfill: 10.1.0 + vfile: 6.0.3 + vite-plugin-arraybuffer: 0.1.4 + vite-plugin-wasm: 3.6.0(vite@8.0.16(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + yaml: 2.9.0 + zod: 4.4.3 + optionalDependencies: + mermaid: 11.14.0 + vite: 8.0.16(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0) + waku: 1.0.0-beta.0(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)))(react@19.2.6)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0) + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@date-fns/tz' + - '@remix-run/react' + - '@rolldown/plugin-babel' + - '@svgx/core' + - '@tanstack/react-router' + - '@types/react' + - '@vue/compiler-sfc' + - '@vue/composition-api' + - async-validator + - axios + - babel-plugin-react-compiler + - change-case + - date-fns + - drauu + - idb-keyval + - jwt-decode + - next + - nprogress + - qrcode + - react-router + - react-router-dom + - react-server-dom-webpack + - rollup + - sortablejs + - supports-color + - svelte + - typescript + - universal-cookie + - vue-template-compiler + - vue-template-es2015-compiler + vocs@2.3.0(@cfworker/json-schema@4.1.1)(@types/react@19.2.14)(@vue/compiler-sfc@3.5.38)(change-case@5.4.4)(idb-keyval@6.2.2)(mermaid@11.14.0)(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)))(react@19.2.6)(rollup@4.60.1)(typescript@5.9.3)(vite@8.0.16(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(waku@1.0.0-beta.0(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.7)))(react@19.2.6)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)): dependencies: '@base-ui/react': 1.6.0(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 46a2117c..daf19a66 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -13,6 +13,7 @@ minimumReleaseAgeExclude: - viem - vocs - vite + - tapimo - es-module-lexer - '@vocs/twoslash-rust' - '@vocs/twoslash-rust-darwin-arm64' diff --git a/src/pages/docs/api/json-rpc.mdx b/src/pages/docs/api/json-rpc.mdx index 9cb0f52e..b32509e2 100644 --- a/src/pages/docs/api/json-rpc.mdx +++ b/src/pages/docs/api/json-rpc.mdx @@ -47,6 +47,25 @@ Use the Tempo JSON-RPC API with command-line tools, TypeScript clients, React ho ``` + + The [Tempo API Typed Client](/docs/api/typed-client) is Tempo's typed API client for TypeScript. Use it when you want one client for Tempo REST endpoints and the JSON-RPC passthrough, with typed route parameters, status narrowing, and Tempo API error envelopes. + +
+ + ```ts [example.ts] + import { Client } from 'tapimo' + + const client = Client.create({ apiKey: process.env.TEMPO_API_KEY }) + + const response = await client.rpc[':chain{mainnet|testnet|[0-9]+}?'].$post({ + param: { chain: 'testnet' }, // [!code focus] + json: { jsonrpc: '2.0', id: 1, method: 'eth_blockNumber', params: [] }, // [!code focus] + }) + + const body = await response.json() // [!code focus] + ``` + + [Wagmi](https://wagmi.sh/react/api/createConfig) provides React hooks and configuration helpers on top of Viem clients. diff --git a/src/pages/docs/api/typed-client.mdx b/src/pages/docs/api/typed-client.mdx new file mode 100644 index 00000000..79ea1fb0 --- /dev/null +++ b/src/pages/docs/api/typed-client.mdx @@ -0,0 +1,172 @@ +--- +title: Tempo API Typed Client +description: Use the Tempo API Typed Client to call REST and JSON-RPC endpoints with autocomplete, API key headers, status narrowing, and error handling in TypeScript. +--- + +# Tempo API Typed Client + +Use the Tempo API Typed Client for endpoint autocomplete and full end-to-end type-safety across API parameters, response bodies, statuses, and errors. + +## Install Tempo API package + +Install the [`tapimo`](https://www.npmjs.com/package/tapimo) package with your package manager. + +:::code-group +```bash [npm] +npm install tapimo +``` +```bash [pnpm] +pnpm add tapimo +``` +```bash [bun] +bun add tapimo +``` +::: + +## Create typed Tempo API client + +Create a Tempo API client with `Client.create`. + +```ts twoslash [client.ts] +import { Client } from 'tapimo' + +const client = Client.create({ + // API key sugar for the canonical `tempo-api-key` header. + apiKey: 'tempo_api_key', + // Override the API URL. Defaults to `Client.defaultUrl`. + url: 'https://api.tempo.xyz', + // Or pass custom headers directly. + headers: { authorization: 'Bearer tempo_api_key' }, +}) +``` + +`Client.create()` also accepts Hono client options such as a custom `fetch` implementation. If you pass `apiKey`, the client merges it into the request headers as `tempo-api-key`. + +## Make type-safe Tempo API requests + +Requests are end-to-end type-safe across parameters, response bodies, statuses, and errors. For example, `GET /v1/tokens/:token` narrows the response body from the HTTP status: + +```ts twoslash [tokens.ts] +import { Client } from 'tapimo' + +const client = Client.create() + +const response = await client.v1.tokens[':token'].$get({ + param: { token: '0x20c0000000000000000000000000000000000000' }, +}) + +// Narrow responses by status. +if (response.status !== 200) { + response.status // status is now typed to non-200 series + // ^? + if (response.status === 404) { + // Handle 404 status specifically + const json = await response.json() + // ^? + json.error.code // which narrows to "token_not_found" + // ^? + } else if (response.status === 402) { + // Handle the payment challenge from `WWW-Authenticate` + const challenge = await response.text() + // ^? + } else { + // Handle validation, auth, rate-limit, or upstream errors + const json = await response.json() + // ^? + } + + throw new Error('Request failed') +} + +// Request is successfull +response.status // Response is narrowed to 200 +// ^? +// Get typed response body +const token = await response.json() +// ^? +token.symbol +// ^? +``` + +## Tempo API endpoint autocomplete + +Routes autocomplete directly on the client, so you can discover endpoints without leaving your editor: + +```ts twoslash [endpoints.ts] +// @noErrors +import { Client } from 'tapimo' + +const client = Client.create() + +const response1 = await client.v1. +// ^| +const response2 = await client.v1.transactions. +// ^| +``` + +## Call Tempo JSON-RPC through Typed Client + +The Typed Client exposes the raw JSON-RPC passthrough as a typed route under `client.rpc`. The route key includes Hono's path pattern because the chain selector is optional: + +```ts twoslash [rpc.ts] +// @noErrors +import { Client } from 'tapimo' + +const client = Client.create() + +const response = await client.rpc[':chain{mainnet|testnet|[0-9]+}?'].$post({ + // Use `undefined` for `/rpc`, or pass `mainnet`, `testnet`, or a numeric chain id. + param: { chain: 'testnet' }, + json: { + jsonrpc: '2.0', + id: 1, + method: 'eth_blockNumber', + params: [], + }, +}) + +if (response.status !== 200) { + const error = await response.json() + throw new Error(error.error.message) +} + +const body = await response.json() +if (!Array.isArray(body) && body.error) + throw new Error(body.error.message) + +const blockNumber = Array.isArray(body) ? body[0]?.result : body.result +``` + +Chain selectors map to these hosted endpoints: + +| `chain` value | Hosted RPC path | +| --- | --- | +| `undefined` | `https://api.tempo.xyz/rpc` | +| `'mainnet'` | `https://api.tempo.xyz/rpc/mainnet` | +| `'testnet'` | `https://api.tempo.xyz/rpc/testnet` | +| `'4217'` | `https://api.tempo.xyz/rpc/4217` | + +### Send batch JSON-RPC requests + +The JSON-RPC body type accepts one request or an array of requests. The client narrows the success body to the same single-or-batch response union: + +```ts twoslash [batch-rpc.ts] +// @noErrors +import { Client } from 'tapimo' + +const client = Client.create() + +const response = await client.rpc[':chain{mainnet|testnet|[0-9]+}?'].$post({ + param: { chain: undefined }, + json: [ + { jsonrpc: '2.0', id: 1, method: 'eth_chainId', params: [] }, + { jsonrpc: '2.0', id: 2, method: 'eth_blockNumber', params: [] }, + ], +}) + +if (response.status === 200) { + const results = await response.json() + // results is typed as one JSON-RPC response or an array of JSON-RPC responses. +} +``` + diff --git a/vocs.config.ts b/vocs.config.ts index a06cc516..28e61813 100644 --- a/vocs.config.ts +++ b/vocs.config.ts @@ -223,6 +223,10 @@ export default defineConfig({ text: 'Versioning Policy', link: '/docs/api/versioning-policy', }, + { + text: 'Typed Client', + link: '/docs/api/typed-client', + }, ], }, },