tapimo 0.1.0 → 0.2.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.
- package/README.md +28 -15
- package/dist/ApiKey.d.ts +3 -1
- package/dist/ApiKey.d.ts.map +1 -1
- package/dist/ApiKey.js +1 -0
- package/dist/ApiKey.js.map +1 -1
- package/dist/ApiKeys.d.ts +71 -3
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +117 -1
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +7139 -4197
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +133 -329
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +11 -4
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +12 -4
- package/dist/Scope.js.map +1 -1
- package/dist/Webhooks.d.ts +2 -2
- package/dist/Webhooks.d.ts.map +1 -1
- package/dist/Webhooks.js +2 -2
- package/dist/Webhooks.js.map +1 -1
- package/dist/admin/App.d.ts +126 -53
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +104 -6
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +67 -0
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/scopes.d.ts +4 -1
- package/dist/admin/apps/scopes.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +115 -115
- package/dist/admin/apps/verified-tokens.js +1 -1
- package/dist/admin/apps/verified-tokens.js.map +1 -1
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.js +1 -1
- package/dist/apps/data/App.d.ts +19176 -0
- package/dist/apps/data/App.d.ts.map +1 -0
- package/dist/apps/data/App.js +236 -0
- package/dist/apps/data/App.js.map +1 -0
- package/dist/apps/data/index.d.ts +3 -0
- package/dist/apps/data/index.d.ts.map +1 -0
- package/dist/apps/data/index.js +3 -0
- package/dist/apps/data/index.js.map +1 -0
- package/dist/apps/{activities.d.ts → data/routes/activities.d.ts} +32 -32
- package/dist/apps/{activities.d.ts.map → data/routes/activities.d.ts.map} +1 -1
- package/dist/apps/{activities.js → data/routes/activities.js} +13 -13
- package/dist/apps/data/routes/activities.js.map +1 -0
- package/dist/apps/{addresses.d.ts → data/routes/addresses.d.ts} +22 -22
- package/dist/apps/{addresses.d.ts.map → data/routes/addresses.d.ts.map} +1 -1
- package/dist/apps/{addresses.js → data/routes/addresses.js} +5 -5
- package/dist/apps/data/routes/addresses.js.map +1 -0
- package/dist/apps/{balances.d.ts → data/routes/balances.d.ts} +49 -49
- package/dist/apps/data/routes/balances.d.ts.map +1 -0
- package/dist/apps/{balances.js → data/routes/balances.js} +42 -11
- package/dist/apps/data/routes/balances.js.map +1 -0
- package/dist/apps/{blocks.d.ts → data/routes/blocks.d.ts} +47 -47
- package/dist/apps/data/routes/blocks.d.ts.map +1 -0
- package/dist/apps/{blocks.js → data/routes/blocks.js} +13 -13
- package/dist/apps/data/routes/blocks.js.map +1 -0
- package/dist/apps/{coingecko.d.ts → data/routes/coingecko.d.ts} +183 -183
- package/dist/apps/data/routes/coingecko.d.ts.map +1 -0
- package/dist/apps/{coingecko.js → data/routes/coingecko.js} +13 -13
- package/dist/apps/data/routes/coingecko.js.map +1 -0
- package/dist/apps/{exchanges.d.ts → data/routes/exchanges.d.ts} +460 -460
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -0
- package/dist/apps/{exchanges.js → data/routes/exchanges.js} +19 -19
- package/dist/apps/data/routes/exchanges.js.map +1 -0
- package/dist/apps/{fee-amm.d.ts → data/routes/fee-amm.d.ts} +94 -94
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -0
- package/dist/apps/{fee-amm.js → data/routes/fee-amm.js} +17 -17
- package/dist/apps/data/routes/fee-amm.js.map +1 -0
- package/dist/apps/{indexer.d.ts → data/routes/indexer.d.ts} +4 -4
- package/dist/apps/data/routes/indexer.d.ts.map +1 -0
- package/dist/apps/{indexer.js → data/routes/indexer.js} +13 -9
- package/dist/apps/data/routes/indexer.js.map +1 -0
- package/dist/apps/{receipts.d.ts → data/routes/receipts.d.ts} +49 -49
- package/dist/apps/data/routes/receipts.d.ts.map +1 -0
- package/dist/apps/{receipts.js → data/routes/receipts.js} +12 -12
- package/dist/apps/data/routes/receipts.js.map +1 -0
- package/dist/apps/{rpc.d.ts → data/routes/rpc.d.ts} +4 -4
- package/dist/apps/data/routes/rpc.d.ts.map +1 -0
- package/dist/apps/{rpc.js → data/routes/rpc.js} +6 -6
- package/dist/apps/data/routes/rpc.js.map +1 -0
- package/dist/apps/{tokenlist.d.ts → data/routes/tokenlist.d.ts} +4 -4
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -0
- package/dist/apps/{tokenlist.js → data/routes/tokenlist.js} +8 -8
- package/dist/apps/data/routes/tokenlist.js.map +1 -0
- package/dist/apps/{tokens.d.ts → data/routes/tokens.d.ts} +468 -468
- package/dist/apps/data/routes/tokens.d.ts.map +1 -0
- package/dist/apps/{tokens.js → data/routes/tokens.js} +19 -19
- package/dist/apps/data/routes/tokens.js.map +1 -0
- package/dist/apps/{transactions.d.ts → data/routes/transactions.d.ts} +304 -304
- package/dist/apps/data/routes/transactions.d.ts.map +1 -0
- package/dist/apps/{transactions.js → data/routes/transactions.js} +13 -13
- package/dist/apps/data/routes/transactions.js.map +1 -0
- package/dist/apps/{transfers.d.ts → data/routes/transfers.d.ts} +6 -6
- package/dist/apps/data/routes/transfers.d.ts.map +1 -0
- package/dist/apps/{transfers.js → data/routes/transfers.js} +13 -13
- package/dist/apps/data/routes/transfers.js.map +1 -0
- package/dist/apps/{verified-tokens.d.ts → data/routes/verified-tokens.d.ts} +42 -42
- package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -0
- package/dist/apps/{verified-tokens.js → data/routes/verified-tokens.js} +9 -9
- package/dist/apps/data/routes/verified-tokens.js.map +1 -0
- package/dist/apps/{webhooks.d.ts → data/routes/webhooks.d.ts} +62 -62
- package/dist/apps/{webhooks.d.ts.map → data/routes/webhooks.d.ts.map} +1 -1
- package/dist/apps/{webhooks.js → data/routes/webhooks.js} +30 -26
- package/dist/apps/data/routes/webhooks.js.map +1 -0
- package/dist/apps/docs/App.d.ts +27 -0
- package/dist/apps/docs/App.d.ts.map +1 -0
- package/dist/apps/docs/App.js +122 -0
- package/dist/apps/docs/App.js.map +1 -0
- package/dist/{internal/OpenApi.fonts.d.ts → apps/docs/fonts.d.ts} +1 -1
- package/dist/apps/docs/fonts.d.ts.map +1 -0
- package/dist/{internal/OpenApi.fonts.js → apps/docs/fonts.js} +1 -1
- package/dist/apps/docs/fonts.js.map +1 -0
- package/dist/apps/docs/index.d.ts +2 -0
- package/dist/apps/docs/index.d.ts.map +1 -0
- package/dist/apps/docs/index.js +2 -0
- package/dist/apps/docs/index.js.map +1 -0
- package/dist/{internal/OpenApi.logo.d.ts → apps/docs/logo.d.ts} +1 -1
- package/dist/apps/docs/logo.d.ts.map +1 -0
- package/dist/{internal/OpenApi.logo.js → apps/docs/logo.js} +1 -1
- package/dist/apps/docs/logo.js.map +1 -0
- package/dist/apps/index.d.ts +4 -0
- package/dist/apps/index.d.ts.map +1 -0
- package/dist/apps/index.js +4 -0
- package/dist/apps/index.js.map +1 -0
- package/dist/apps/metadata.d.ts +7 -0
- package/dist/apps/metadata.d.ts.map +1 -0
- package/dist/apps/metadata.js +15 -0
- package/dist/apps/metadata.js.map +1 -0
- package/dist/apps/platform/App.d.ts +2985 -0
- package/dist/apps/platform/App.d.ts.map +1 -0
- package/dist/apps/platform/App.js +74 -0
- package/dist/apps/platform/App.js.map +1 -0
- package/dist/apps/platform/index.d.ts +2 -0
- package/dist/apps/platform/index.d.ts.map +1 -0
- package/dist/apps/platform/index.js +2 -0
- package/dist/apps/platform/index.js.map +1 -0
- package/dist/apps/platform/routes/api-keys.d.ts +681 -0
- package/dist/apps/platform/routes/api-keys.d.ts.map +1 -0
- package/dist/apps/platform/routes/api-keys.js +328 -0
- package/dist/apps/platform/routes/api-keys.js.map +1 -0
- package/dist/apps/platform/routes/invitations.d.ts +733 -0
- package/dist/apps/platform/routes/invitations.d.ts.map +1 -0
- package/dist/apps/platform/routes/invitations.js +413 -0
- package/dist/apps/platform/routes/invitations.js.map +1 -0
- package/dist/apps/platform/routes/me.d.ts +95 -0
- package/dist/apps/platform/routes/me.d.ts.map +1 -0
- package/dist/apps/platform/routes/me.js +81 -0
- package/dist/apps/platform/routes/me.js.map +1 -0
- package/dist/apps/platform/routes/members.d.ts +554 -0
- package/dist/apps/platform/routes/members.d.ts.map +1 -0
- package/dist/apps/platform/routes/members.js +251 -0
- package/dist/apps/platform/routes/members.js.map +1 -0
- package/dist/apps/platform/routes/orgs.d.ts +582 -0
- package/dist/apps/platform/routes/orgs.d.ts.map +1 -0
- package/dist/apps/platform/routes/orgs.js +265 -0
- package/dist/apps/platform/routes/orgs.js.map +1 -0
- package/dist/apps/platform/routes/projects.d.ts +740 -0
- package/dist/apps/platform/routes/projects.d.ts.map +1 -0
- package/dist/apps/platform/routes/projects.js +286 -0
- package/dist/apps/platform/routes/projects.js.map +1 -0
- package/dist/apps/relay/App.d.ts +41 -0
- package/dist/apps/relay/App.d.ts.map +1 -0
- package/dist/apps/relay/App.js +103 -0
- package/dist/apps/relay/App.js.map +1 -0
- package/dist/apps/relay/Sponsorships.d.ts +107 -0
- package/dist/apps/relay/Sponsorships.d.ts.map +1 -0
- package/dist/apps/relay/Sponsorships.js +193 -0
- package/dist/apps/relay/Sponsorships.js.map +1 -0
- package/dist/apps/relay/index.d.ts +3 -0
- package/dist/apps/relay/index.d.ts.map +1 -0
- package/dist/apps/relay/index.js +3 -0
- package/dist/apps/relay/index.js.map +1 -0
- package/dist/cli/Cli.d.ts +1 -1
- package/dist/cli/Cli.js +1 -1
- package/dist/cli/commands/admin.d.ts +1 -1
- package/dist/cli/commands/admin.js +2 -2
- package/dist/cli/commands/admin.js.map +1 -1
- package/dist/db/Db.d.ts +10 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +128 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +80 -0
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +99 -0
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/invitations.d.ts +84 -0
- package/dist/db/tables/invitations.d.ts.map +1 -0
- package/dist/db/tables/invitations.js +165 -0
- package/dist/db/tables/invitations.js.map +1 -0
- package/dist/db/tables/memberships.d.ts +108 -0
- package/dist/db/tables/memberships.d.ts.map +1 -0
- package/dist/db/tables/memberships.js +153 -0
- package/dist/db/tables/memberships.js.map +1 -0
- package/dist/db/tables/organizations.d.ts +44 -0
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +89 -0
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/projects.d.ts +65 -0
- package/dist/db/tables/projects.d.ts.map +1 -0
- package/dist/db/tables/projects.js +75 -0
- package/dist/db/tables/projects.js.map +1 -0
- package/dist/db/tables/sponsoredTransactions.d.ts +120 -0
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -0
- package/dist/db/tables/sponsoredTransactions.js +161 -0
- package/dist/db/tables/sponsoredTransactions.js.map +1 -0
- package/dist/db/tables/users.d.ts +48 -0
- package/dist/db/tables/users.d.ts.map +1 -0
- package/dist/db/tables/users.js +65 -0
- package/dist/db/tables/users.js.map +1 -0
- package/dist/handlers/internal/executionError.d.ts.map +1 -1
- package/dist/handlers/internal/executionError.js +2 -0
- package/dist/handlers/internal/executionError.js.map +1 -1
- package/dist/handlers/internal/multisig.d.ts +2 -6
- package/dist/handlers/internal/multisig.d.ts.map +1 -1
- package/dist/handlers/internal/multisig.js +11 -36
- package/dist/handlers/internal/multisig.js.map +1 -1
- package/dist/handlers/internal/sponsorship.d.ts +32 -2
- package/dist/handlers/internal/sponsorship.d.ts.map +1 -1
- package/dist/handlers/internal/sponsorship.js +34 -9
- package/dist/handlers/internal/sponsorship.js.map +1 -1
- package/dist/handlers/relay.d.ts +6 -2
- package/dist/handlers/relay.d.ts.map +1 -1
- package/dist/handlers/relay.js +16 -2
- package/dist/handlers/relay.js.map +1 -1
- package/dist/internal/Auth.d.ts +208 -6
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +500 -21
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Log.d.ts +7 -3
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +4 -0
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +0 -19
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +0 -57
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Store.d.ts +7 -1
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +16 -2
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Viem.d.ts +84 -0
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Webhooks.d.ts +1 -1
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/package.json +31 -5
- package/src/ApiKey.ts +1 -0
- package/src/ApiKeys.test.ts +104 -1
- package/src/ApiKeys.ts +154 -1
- package/src/App.test.ts +11187 -179
- package/src/App.ts +200 -420
- package/src/Client.test-d.ts +306 -15
- package/src/Scope.ts +13 -4
- package/src/Webhooks.ts +2 -2
- package/src/admin/apps/api-keys.test.ts +51 -0
- package/src/admin/apps/api-keys.ts +84 -0
- package/src/admin/apps/scopes.test.ts +5 -1
- package/src/admin/apps/verified-tokens.ts +1 -1
- package/src/admin/ui.generated.ts +1 -1
- package/src/apps/composition.test.ts +66 -0
- package/src/apps/data/App.ts +295 -0
- package/src/apps/data/index.ts +2 -0
- package/src/apps/{activities.test.ts → data/routes/activities.test.ts} +3 -3
- package/src/apps/{activities.ts → data/routes/activities.ts} +15 -15
- package/src/apps/{addresses.ts → data/routes/addresses.ts} +6 -6
- package/src/apps/{balances.test.ts → data/routes/balances.test.ts} +2 -2
- package/src/apps/{balances.ts → data/routes/balances.ts} +46 -12
- package/src/apps/{blocks.test.ts → data/routes/blocks.test.ts} +3 -3
- package/src/apps/{blocks.ts → data/routes/blocks.ts} +14 -14
- package/src/apps/{coingecko.test.ts → data/routes/coingecko.test.ts} +2 -2
- package/src/apps/{coingecko.ts → data/routes/coingecko.ts} +14 -14
- package/src/apps/{exchanges.test.ts → data/routes/exchanges.test.ts} +1 -1
- package/src/apps/{exchanges.ts → data/routes/exchanges.ts} +20 -20
- package/src/apps/{fee-amm.test.ts → data/routes/fee-amm.test.ts} +3 -3
- package/src/apps/{fee-amm.ts → data/routes/fee-amm.ts} +18 -18
- package/src/apps/{indexer.test.ts → data/routes/indexer.test.ts} +26 -5
- package/src/apps/{indexer.ts → data/routes/indexer.ts} +13 -10
- package/src/apps/{receipts.test.ts → data/routes/receipts.test.ts} +3 -3
- package/src/apps/{receipts.ts → data/routes/receipts.ts} +13 -13
- package/src/apps/{rpc.test.ts → data/routes/rpc.test.ts} +44 -5
- package/src/apps/{rpc.ts → data/routes/rpc.ts} +7 -7
- package/src/apps/{tokenlist.test.ts → data/routes/tokenlist.test.ts} +3 -3
- package/src/apps/{tokenlist.ts → data/routes/tokenlist.ts} +9 -9
- package/src/apps/{tokens.test.ts → data/routes/tokens.test.ts} +2 -2
- package/src/apps/{tokens.ts → data/routes/tokens.ts} +20 -20
- package/src/apps/{transactions.test.ts → data/routes/transactions.test.ts} +3 -3
- package/src/apps/{transactions.ts → data/routes/transactions.ts} +15 -15
- package/src/apps/{transfers.test.ts → data/routes/transfers.test.ts} +2 -2
- package/src/apps/{transfers.ts → data/routes/transfers.ts} +15 -15
- package/src/apps/{verified-tokens.test.ts → data/routes/verified-tokens.test.ts} +3 -3
- package/src/apps/{verified-tokens.ts → data/routes/verified-tokens.ts} +10 -10
- package/src/apps/{webhooks.test.ts → data/routes/webhooks.test.ts} +6 -6
- package/src/apps/{webhooks.ts → data/routes/webhooks.ts} +39 -35
- package/src/apps/docs/App.ts +136 -0
- package/src/apps/docs/index.ts +1 -0
- package/src/apps/index.ts +3 -0
- package/src/apps/metadata.ts +23 -0
- package/src/apps/platform/App.ts +130 -0
- package/src/apps/platform/index.ts +1 -0
- package/src/apps/platform/routes/api-keys.test.ts +330 -0
- package/src/apps/platform/routes/api-keys.ts +427 -0
- package/src/apps/platform/routes/invitations.test.ts +361 -0
- package/src/apps/platform/routes/invitations.ts +519 -0
- package/src/apps/platform/routes/me.test.ts +121 -0
- package/src/apps/platform/routes/me.ts +106 -0
- package/src/apps/platform/routes/members.test.ts +195 -0
- package/src/apps/platform/routes/members.ts +313 -0
- package/src/apps/platform/routes/orgs.test.ts +313 -0
- package/src/apps/platform/routes/orgs.ts +343 -0
- package/src/apps/platform/routes/projects.test.ts +181 -0
- package/src/apps/platform/routes/projects.ts +367 -0
- package/src/apps/relay/App.test.ts +484 -0
- package/src/apps/relay/App.ts +128 -0
- package/src/apps/relay/Sponsorships.test.ts +375 -0
- package/src/apps/relay/Sponsorships.ts +305 -0
- package/src/apps/relay/index.ts +2 -0
- package/src/cli/Cli.ts +1 -1
- package/src/cli/commands/admin.ts +2 -2
- package/src/db/Db.ts +159 -0
- package/src/db/Schema.ts +137 -0
- package/src/db/tables/invitations.ts +198 -0
- package/src/db/tables/memberships.ts +208 -0
- package/src/db/tables/organizations.test.ts +37 -1
- package/src/db/tables/organizations.ts +105 -0
- package/src/db/tables/projects.ts +107 -0
- package/src/db/tables/sponsoredTransactions.test.ts +218 -0
- package/src/db/tables/sponsoredTransactions.ts +236 -0
- package/src/db/tables/users.ts +85 -0
- package/src/handlers/internal/executionError.ts +2 -0
- package/src/handlers/internal/multisig.test.ts +84 -10
- package/src/handlers/internal/multisig.ts +15 -50
- package/src/handlers/internal/sponsorship.ts +74 -15
- package/src/handlers/{internal/relay.localnet.test.ts → relay.test.ts} +2 -2
- package/src/handlers/relay.ts +23 -5
- package/src/internal/Auth.test.ts +316 -0
- package/src/internal/Auth.ts +691 -25
- package/src/internal/Cursor.test.ts +3 -2
- package/src/internal/Log.test.ts +1 -1
- package/src/internal/Log.ts +11 -3
- package/src/internal/MetricSink.ts +1 -1
- package/src/internal/OpenApi.ts +0 -59
- package/src/internal/Store.test.ts +52 -0
- package/src/internal/Store.ts +24 -5
- package/src/internal/Tidx.local.test.ts +1 -1
- package/src/internal/VerifiedTokens.test.ts +1 -1
- package/src/internal/WebhookDestination.test.ts +1 -1
- package/src/internal/Webhooks.test.ts +4 -4
- package/src/internal/Webhooks.ts +1 -1
- package/dist/apps/activities.js.map +0 -1
- package/dist/apps/addresses.js.map +0 -1
- package/dist/apps/balances.d.ts.map +0 -1
- package/dist/apps/balances.js.map +0 -1
- package/dist/apps/blocks.d.ts.map +0 -1
- package/dist/apps/blocks.js.map +0 -1
- package/dist/apps/coingecko.d.ts.map +0 -1
- package/dist/apps/coingecko.js.map +0 -1
- package/dist/apps/exchanges.d.ts.map +0 -1
- package/dist/apps/exchanges.js.map +0 -1
- package/dist/apps/fee-amm.d.ts.map +0 -1
- package/dist/apps/fee-amm.js.map +0 -1
- package/dist/apps/indexer.d.ts.map +0 -1
- package/dist/apps/indexer.js.map +0 -1
- package/dist/apps/receipts.d.ts.map +0 -1
- package/dist/apps/receipts.js.map +0 -1
- package/dist/apps/rpc.d.ts.map +0 -1
- package/dist/apps/rpc.js.map +0 -1
- package/dist/apps/tokenlist.d.ts.map +0 -1
- package/dist/apps/tokenlist.js.map +0 -1
- package/dist/apps/tokens.d.ts.map +0 -1
- package/dist/apps/tokens.js.map +0 -1
- package/dist/apps/transactions.d.ts.map +0 -1
- package/dist/apps/transactions.js.map +0 -1
- package/dist/apps/transfers.d.ts.map +0 -1
- package/dist/apps/transfers.js.map +0 -1
- package/dist/apps/verified-tokens.d.ts.map +0 -1
- package/dist/apps/verified-tokens.js.map +0 -1
- package/dist/apps/webhooks.js.map +0 -1
- package/dist/internal/OpenApi.fonts.d.ts.map +0 -1
- package/dist/internal/OpenApi.fonts.js.map +0 -1
- package/dist/internal/OpenApi.logo.d.ts.map +0 -1
- package/dist/internal/OpenApi.logo.js.map +0 -1
- package/src/handlers/internal/multisig.localnet.test.ts +0 -146
- /package/src/{internal/OpenApi.fonts.ts → apps/docs/fonts.ts} +0 -0
- /package/src/{internal/OpenApi.logo.ts → apps/docs/logo.ts} +0 -0
package/src/App.ts
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import type { Context
|
|
1
|
+
import type { Context } from 'hono'
|
|
2
2
|
import { Hono } from 'hono'
|
|
3
3
|
import { compress as hono_compress } from 'hono/compress'
|
|
4
4
|
import { cors as hono_cors } from 'hono/cors'
|
|
5
5
|
import { HTTPException } from 'hono/http-exception'
|
|
6
6
|
import { requestId, type RequestIdVariables } from 'hono/request-id'
|
|
7
7
|
import { generateSpecs } from 'hono-openapi'
|
|
8
|
-
import { Handler as vocs_Handler } from 'vocs/server'
|
|
9
|
-
import * as z from 'zod/mini'
|
|
10
8
|
|
|
11
9
|
import * as ApiKey from './ApiKey.js'
|
|
12
10
|
import * as Assets from './Assets.js'
|
|
13
11
|
import * as Auth from './internal/Auth.js'
|
|
14
12
|
import * as Db from './db/Db.js'
|
|
15
13
|
import * as EdgeCache from './internal/EdgeCache.js'
|
|
16
|
-
import * as Handler from './Handler.js'
|
|
17
14
|
import * as Log from './internal/Log.js'
|
|
18
15
|
import * as MetricSink from './internal/MetricSink.js'
|
|
19
16
|
import type * as Metrics from './Metrics.js'
|
|
@@ -21,29 +18,23 @@ import * as OpenApi from './internal/OpenApi.js'
|
|
|
21
18
|
import * as Store from './internal/Store.js'
|
|
22
19
|
import * as Path from './internal/Path.js'
|
|
23
20
|
import * as Response from './internal/Response.js'
|
|
24
|
-
import * as
|
|
25
|
-
import * as Tidx from './internal/Tidx.js'
|
|
21
|
+
import type * as Tidx from './internal/Tidx.js'
|
|
26
22
|
import * as Timing from './internal/Timing.js'
|
|
27
|
-
import * as VerifiedTokens from './internal/VerifiedTokens.js'
|
|
28
23
|
import * as Viem from './internal/Viem.js'
|
|
29
24
|
|
|
30
25
|
import openrpcSpec from './openrpc.json' with { type: 'json' }
|
|
31
26
|
|
|
32
|
-
import
|
|
33
|
-
import
|
|
34
|
-
import
|
|
35
|
-
|
|
36
|
-
import
|
|
37
|
-
import
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
import { transfers } from './apps/transfers.js'
|
|
44
|
-
import { verifiedTokens } from './apps/verified-tokens.js'
|
|
45
|
-
import { tokenlist } from './apps/tokenlist.js'
|
|
46
|
-
import { schema as webhookSchema, webhooks } from './apps/webhooks.js'
|
|
27
|
+
import * as Metadata from './apps/metadata.js'
|
|
28
|
+
import * as Data from './apps/data/App.js'
|
|
29
|
+
import * as Platform from './apps/platform/App.js'
|
|
30
|
+
|
|
31
|
+
export import data = Data.data
|
|
32
|
+
export import platform = Platform.platform
|
|
33
|
+
|
|
34
|
+
/** The chain-data route group; see {@link data}. */
|
|
35
|
+
export type DataApp = ReturnType<typeof data>
|
|
36
|
+
/** The tenant-platform route group; see {@link platform}. */
|
|
37
|
+
export type PlatformApp = ReturnType<typeof platform>
|
|
47
38
|
|
|
48
39
|
/** Hono environment variables set by the Tempo API app. */
|
|
49
40
|
export type Environment = {
|
|
@@ -83,15 +74,18 @@ export type Environment = {
|
|
|
83
74
|
}
|
|
84
75
|
|
|
85
76
|
/**
|
|
86
|
-
* Tempo API
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* `ReturnType<typeof create>` would resolve `path` to its constraint
|
|
90
|
-
* (`string`), and Hono's `MergePath<string, '/foo'>` would surface every
|
|
91
|
-
* endpoint key as `` `… ${string}/foo` `` — which can be satisfied but never
|
|
92
|
-
* autocompleted.
|
|
77
|
+
* The canonical fully-composed Tempo API app ({@link create} with both route
|
|
78
|
+
* groups). {@link Client} and the reference worker target this type; a subset
|
|
79
|
+
* consumer infers its own narrower type from its own composition chain.
|
|
93
80
|
*/
|
|
94
|
-
export type App = ReturnType<typeof
|
|
81
|
+
export type App = ReturnType<typeof compose>
|
|
82
|
+
|
|
83
|
+
// Type anchor only — never invoked. Expresses the canonical composition so
|
|
84
|
+
// `App` (and thus `Client`) reflect the full route surface; real consumers
|
|
85
|
+
// compose explicitly.
|
|
86
|
+
function compose(options: create.Options) {
|
|
87
|
+
return create(options).route('/', data()).route('/', platform())
|
|
88
|
+
}
|
|
95
89
|
|
|
96
90
|
/** Node.js request listener for `node:http` and compatible interfaces. */
|
|
97
91
|
export type Listener = (incoming: unknown, outgoing: unknown) => Promise<void>
|
|
@@ -99,6 +93,9 @@ export type Listener = (incoming: unknown, outgoing: unknown) => Promise<void>
|
|
|
99
93
|
/** HTTP endpoints owned by Tempo API handlers, used for typed auth overrides. */
|
|
100
94
|
export type Endpoint = Auth.Endpoint<App>
|
|
101
95
|
|
|
96
|
+
/** Transactional email sender for platform emails; owned by {@link platform}. */
|
|
97
|
+
export type Email = Platform.Email
|
|
98
|
+
|
|
102
99
|
/** One static API asset resolved from packaged data. */
|
|
103
100
|
export type Asset = {
|
|
104
101
|
/** Loaded asset response. */
|
|
@@ -118,7 +115,7 @@ const infoDescription = 'REST API for reading and interacting with Tempo'
|
|
|
118
115
|
|
|
119
116
|
/** Creates the Tempo API Hono app. */
|
|
120
117
|
export function create<const path extends string = '/'>(options: create.Options<path>) {
|
|
121
|
-
const {
|
|
118
|
+
const { path = '/' as path } = options
|
|
122
119
|
|
|
123
120
|
// Capture as the literal generic so `Hono.basePath(...)` preserves the
|
|
124
121
|
// typed prefix. testClient's `Client<T, ...>` inference collapses to a
|
|
@@ -136,31 +133,6 @@ export function create<const path extends string = '/'>(options: create.Options<
|
|
|
136
133
|
// `options.db`, API-key records in `options.kv`.
|
|
137
134
|
const store = options.cache?.store ?? Store.memory()
|
|
138
135
|
|
|
139
|
-
// Memoize one viem client per resolved upstream. Clients are stateless HTTP
|
|
140
|
-
// transports, so reusing them avoids per-request construction cost. The cache
|
|
141
|
-
// key is the resolved output (`url` + `basicAuth` + `chainId`), not the
|
|
142
|
-
// principal, so a resolver `rpc` may branch on any principal field while
|
|
143
|
-
// client cardinality stays bounded by the number of distinct upstreams —
|
|
144
|
-
// callers that resolve to the same upstream share a client.
|
|
145
|
-
const clients = new Map<string, ReturnType<typeof Viem.getClient>>()
|
|
146
|
-
const getClient = (chainId = defaultChainId, principal: Auth.Principal | null = null) => {
|
|
147
|
-
// Resolve to derive the cache key; `Viem.getClient` re-resolves to build the
|
|
148
|
-
// client on a miss. `resolve` is pure and cheap, so the extra call is free.
|
|
149
|
-
const { url, basicAuth } = Viem.resolve(rpc, { chainId, principal })
|
|
150
|
-
const cacheKey = `${url}|${basicAuth ?? ''}|${chainId}`
|
|
151
|
-
const existing = clients.get(cacheKey)
|
|
152
|
-
if (existing) return existing
|
|
153
|
-
const client = Viem.getClient({ chainId, principal, rpc })
|
|
154
|
-
clients.set(cacheKey, client)
|
|
155
|
-
return client
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Memoize TIDX clients per `chainId` so the base URL resolver runs once per
|
|
159
|
-
// chain instead of on every request. The same factory backs the scheduled
|
|
160
|
-
// webhook poller (`Webhooks.createPoller`), keeping client construction in
|
|
161
|
-
// one place.
|
|
162
|
-
const getTidx = Tidx.createGetClient({ defaultChainId, tidx: options.tidx })
|
|
163
|
-
|
|
164
136
|
// Build the app in two phases: register middleware imperatively, then chain
|
|
165
137
|
// route mounts so the merged Hono schema flows through the return type. The
|
|
166
138
|
// chained type is what makes `testClient(create())` produce typed path
|
|
@@ -217,69 +189,25 @@ export function create<const path extends string = '/'>(options: create.Options<
|
|
|
217
189
|
},
|
|
218
190
|
}),
|
|
219
191
|
)
|
|
220
|
-
// The chain ids this deployment serves: the built-in public chains plus the
|
|
221
|
-
// configured `defaultChainId` and any explicit `supportedChainIds`. Exposed on
|
|
222
|
-
// context so mounted apps with a path `chainId` (e.g. GeckoTerminal) can guard
|
|
223
|
-
// it too.
|
|
224
|
-
const supportedChainIds = new Set<number>([
|
|
225
|
-
...Object.keys(Viem.url).map(Number),
|
|
226
|
-
...Object.keys(Tidx.url).map(Number),
|
|
227
|
-
defaultChainId,
|
|
228
|
-
...(options.supportedChainIds ?? []),
|
|
229
|
-
])
|
|
230
192
|
|
|
231
193
|
// Normalize the `db` option: the plain form is `{ source }` with no cached
|
|
232
194
|
// side; `cached` falls back to `source` so consumers never branch.
|
|
233
195
|
const db = 'source' in options.db ? options.db : { source: options.db }
|
|
234
196
|
|
|
197
|
+
// Built-in auth: the session surface (mounted last) plus the enforcement
|
|
198
|
+
// middleware (installed below), wired together in `Auth.install`.
|
|
199
|
+
const auth = Auth.install({ auth: options.auth, db: db.source, kv: options.kv })
|
|
200
|
+
|
|
235
201
|
base.use('*', Timing.middleware())
|
|
236
202
|
base.use('*', async (c, next) => {
|
|
237
|
-
// Put app-level dependencies on Hono context so mounted handlers only
|
|
238
|
-
// receive request-local state from `c`.
|
|
239
203
|
c.set('basePath', basePath)
|
|
240
|
-
c.set('chainId', defaultChainId)
|
|
241
204
|
c.set('db', db.source)
|
|
242
205
|
c.set('dbCached', db.cached ?? db.source)
|
|
243
|
-
c.set('getAsset', createGetAsset({ assets, basePath, origin: new URL(c.req.url).origin }))
|
|
244
|
-
c.set('getClient', (chainId) => getClient(chainId, Auth.getPrincipal(c)))
|
|
245
|
-
c.set('getTidx', (chainId) => getTidx(chainId, Auth.getPrincipal(c)))
|
|
246
206
|
c.set('kv', options.kv)
|
|
247
|
-
c.set('rpc', rpc)
|
|
248
207
|
c.set('store', store)
|
|
249
|
-
c.set('supportedChainIds', supportedChainIds)
|
|
250
|
-
c.set('tidx', options.tidx)
|
|
251
|
-
// Feature configs default to enabled empty configs; `false` disables.
|
|
252
|
-
c.set('verifiedTokens', options.verifiedTokens === false ? undefined : (options.verifiedTokens ?? {})) // prettier-ignore
|
|
253
|
-
c.set('webhook', options.webhook === false ? undefined : (options.webhook ?? {}))
|
|
254
208
|
await next()
|
|
255
209
|
})
|
|
256
210
|
|
|
257
|
-
// Reject a syntactically valid `chainId` this deployment does not serve before
|
|
258
|
-
// it reaches an upstream — an unknown chain otherwise hits the configured
|
|
259
|
-
// RPC/indexer (a static `tidx.baseUrl` answers for any chain id) and comes
|
|
260
|
-
// back as an opaque `upstream_error`.
|
|
261
|
-
base.use('*', async (c, next) => {
|
|
262
|
-
const raw = c.req.query('chainId') ?? c.req.query('chain_id')
|
|
263
|
-
if (raw === undefined) return next()
|
|
264
|
-
// Only reject a well-formed-but-unsupported chain here; malformed values
|
|
265
|
-
// (e.g. `abc`, `0`) fall through to the route's own query validation.
|
|
266
|
-
const parsed = Schema.ChainId.safeParse(raw)
|
|
267
|
-
if (!parsed.success || supportedChainIds.has(parsed.data)) return next()
|
|
268
|
-
return Response.unsupportedChainId(c, parsed.data, supportedChainIds)
|
|
269
|
-
})
|
|
270
|
-
// Skip the static asset route entirely when no store is configured; token
|
|
271
|
-
// logo URIs simply go unresolved.
|
|
272
|
-
if (assets)
|
|
273
|
-
base.use('/assets/*', async (c, next) => {
|
|
274
|
-
const key = stripAssetPath(c.req.path, basePath).replace(/^\/+/, '')
|
|
275
|
-
const asset = key ? await assets.get(key) : undefined
|
|
276
|
-
if (!asset) return next()
|
|
277
|
-
return c.body(asset.body, 200, {
|
|
278
|
-
'Cache-Control': 'public, max-age=86400',
|
|
279
|
-
'Content-Type': asset.contentType,
|
|
280
|
-
})
|
|
281
|
-
})
|
|
282
|
-
|
|
283
211
|
// Safety net: any non-2xx response (auth/validation errors, MPP `402`
|
|
284
212
|
// challenges, rate-limit `429`s, upstream `502`s, etc.) must never be
|
|
285
213
|
// cached. This wraps endpoint middleware and handlers registered below.
|
|
@@ -295,106 +223,79 @@ export function create<const path extends string = '/'>(options: create.Options<
|
|
|
295
223
|
// latency.
|
|
296
224
|
if (options.cache?.edge !== false) base.use('*', EdgeCache.middleware<Environment>({ store }))
|
|
297
225
|
|
|
298
|
-
const
|
|
226
|
+
const app = base.get('/health', OpenApi.describeRoute({ hide: true }), (c) =>
|
|
299
227
|
c.json({ status: 'ok' }, 200),
|
|
300
228
|
)
|
|
301
229
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
.
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
.route(
|
|
330
|
-
'/rpc/relay',
|
|
331
|
-
Handler.relay({
|
|
332
|
-
cache: store,
|
|
333
|
-
getClient: (chainId) => getClient(chainId as Viem.ChainId | undefined),
|
|
334
|
-
...(options.verifiedTokens === false
|
|
335
|
-
? {}
|
|
336
|
-
: {
|
|
337
|
-
resolveTokens: async (chainId: number) => {
|
|
338
|
-
const snapshot = await VerifiedTokens.read(Db.get(db.cached ?? db.source), chainId)
|
|
339
|
-
return snapshot?.list.map((token) => token.address) ?? []
|
|
340
|
-
},
|
|
341
|
-
}),
|
|
342
|
-
}),
|
|
230
|
+
// Built-in enforcement: default-closed policies over OpenAPI-registered
|
|
231
|
+
// routes. `auth: false` leaves policies unenforced (tests only).
|
|
232
|
+
if (auth.middleware) app.use('*', auth.middleware)
|
|
233
|
+
|
|
234
|
+
// Collect each mounted group's OpenAPI metadata: Hono's `.route()` drops
|
|
235
|
+
// sub-app metadata, so a group attaches it to its instance (a WeakMap) and we
|
|
236
|
+
// read it back here. Patching the runtime method, not the type, keeps `hc`.
|
|
237
|
+
const metadata: create.Metadata[] = []
|
|
238
|
+
const route = app.route.bind(app)
|
|
239
|
+
;(app as unknown as { route: typeof route }).route = ((path, sub) => {
|
|
240
|
+
const entry = Metadata.read(sub)
|
|
241
|
+
if (entry) metadata.push(entry)
|
|
242
|
+
return route(path, sub)
|
|
243
|
+
}) as typeof route
|
|
244
|
+
|
|
245
|
+
// Register the JSON error envelopes eagerly (they don't depend on mounted
|
|
246
|
+
// routes) so error handling is live before the first request and a consumer's
|
|
247
|
+
// `withSentry(app)` sees them already in place.
|
|
248
|
+
app.notFound((c) =>
|
|
249
|
+
Response.error(c, { code: 'not_found', message: 'Route not found', status: 404 }),
|
|
250
|
+
)
|
|
251
|
+
app.onError((cause, c) => {
|
|
252
|
+
if (cause instanceof HTTPException) return errorFromException(c, cause)
|
|
253
|
+
|
|
254
|
+
// Redact any leaked API-key token from the logged error/stack.
|
|
255
|
+
console.error(
|
|
256
|
+
ApiKey.redact(cause instanceof Error ? (cause.stack ?? cause.message) : String(cause)),
|
|
343
257
|
)
|
|
344
|
-
.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
header('tempo-event-type', 'What happened: `token:transfer`, `transaction:included`, `log:emitted`, `block:created`, or `ping`.'), // prettier-ignore
|
|
386
|
-
],
|
|
387
|
-
requestBody: {
|
|
388
|
-
content: { 'application/json': { schema: envelope } },
|
|
389
|
-
required: true,
|
|
390
|
-
},
|
|
391
|
-
responses: { '2xx': { description: 'Delivery acknowledged.' } },
|
|
392
|
-
summary: 'Webhook event delivery',
|
|
393
|
-
tags: ['Webhooks'],
|
|
394
|
-
},
|
|
395
|
-
},
|
|
396
|
-
},
|
|
397
|
-
}
|
|
258
|
+
return Response.error(c, {
|
|
259
|
+
code: 'internal_error',
|
|
260
|
+
message: 'Internal server error',
|
|
261
|
+
status: 500,
|
|
262
|
+
})
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
// Mount the OpenAPI/OpenRPC documents and docs reference lazily on the first
|
|
266
|
+
// request, so the document sees the full route surface without a `seal()`
|
|
267
|
+
// step. The patched `fetch` runs this before Hono builds its matcher.
|
|
268
|
+
//
|
|
269
|
+
// Spec generation stays lazy: ordinary API traffic only installs the routes,
|
|
270
|
+
// while `/openapi.json` and the Vocs handler start the memoized build.
|
|
271
|
+
let spec: ReturnType<typeof buildSpec> | undefined
|
|
272
|
+
const getSpec = () => (spec ??= buildSpec())
|
|
273
|
+
const buildSpec = async () => {
|
|
274
|
+
// Merge each mounted group's contributed OpenAPI metadata (tags, security
|
|
275
|
+
// schemes, webhooks block). Unused tags/schemes don't render, so a subset
|
|
276
|
+
// app's document carries only what its groups contributed.
|
|
277
|
+
// The built-in session surface's metadata appends after every mounted
|
|
278
|
+
// group's, so consumer-mounted groups lead the document order.
|
|
279
|
+
const metadata_all = (() => {
|
|
280
|
+
const entry = auth.app ? Metadata.read(auth.app) : undefined
|
|
281
|
+
return entry ? [...metadata, entry] : metadata
|
|
282
|
+
})()
|
|
283
|
+
const contributedSchemes = Object.assign({}, ...metadata_all.map((m) => m.securitySchemes ?? {})) // prettier-ignore
|
|
284
|
+
const tags = metadata_all.flatMap((m) => m.tags ?? [])
|
|
285
|
+
// Tag groups contributed under the same name merge into one sidebar group,
|
|
286
|
+
// deduped and filtered to defined tags (a group may list a tag another
|
|
287
|
+
// surface defines, e.g. `Auth` from the built-in session surface).
|
|
288
|
+
const tagGroups = (() => {
|
|
289
|
+
const defined = new Set(tags.map((tag) => tag.name))
|
|
290
|
+
const groups = new Map<string, { name: string; tags: string[] }>()
|
|
291
|
+
for (const { name, tags: members } of metadata_all.flatMap((m) => m['x-tagGroups'] ?? []))
|
|
292
|
+
groups.set(name, { name, tags: [...(groups.get(name)?.tags ?? []), ...members] })
|
|
293
|
+
return [...groups.values()]
|
|
294
|
+
.map((group) => ({
|
|
295
|
+
...group,
|
|
296
|
+
tags: [...new Set(group.tags)].filter((tag) => defined.has(tag)),
|
|
297
|
+
})) // prettier-ignore
|
|
298
|
+
.filter((group) => group.tags.length > 0)
|
|
398
299
|
})()
|
|
399
300
|
const generated = await generateSpecs(app, {
|
|
400
301
|
documentation: {
|
|
@@ -414,6 +315,7 @@ export function create<const path extends string = '/'>(options: create.Options<
|
|
|
414
315
|
scheme: 'bearer',
|
|
415
316
|
type: 'http',
|
|
416
317
|
},
|
|
318
|
+
...contributedSchemes,
|
|
417
319
|
},
|
|
418
320
|
},
|
|
419
321
|
info: {
|
|
@@ -427,71 +329,24 @@ export function create<const path extends string = '/'>(options: create.Options<
|
|
|
427
329
|
{ url: basePath || '/', description: 'Relative to the host serving this document.' },
|
|
428
330
|
]),
|
|
429
331
|
],
|
|
430
|
-
tags
|
|
431
|
-
|
|
432
|
-
name: 'Activities',
|
|
433
|
-
description: 'A readable feed of what an account did onchain.',
|
|
434
|
-
},
|
|
435
|
-
{
|
|
436
|
-
name: 'Balances',
|
|
437
|
-
description: 'How much of each token an account holds.',
|
|
438
|
-
},
|
|
439
|
-
{
|
|
440
|
-
name: 'Blocks',
|
|
441
|
-
description: 'The ordered batches of transactions making up the chain.',
|
|
442
|
-
},
|
|
443
|
-
{
|
|
444
|
-
name: 'Exchange',
|
|
445
|
-
description: "Tempo's built-in stablecoin exchange: pairs, swaps, orders, prices.",
|
|
446
|
-
},
|
|
447
|
-
{
|
|
448
|
-
name: 'Fee AMM',
|
|
449
|
-
description: 'Pools that convert stablecoins to pay fees.',
|
|
450
|
-
},
|
|
451
|
-
{
|
|
452
|
-
name: 'Tokens',
|
|
453
|
-
description: 'TIP-20 token details, supply, and holders.',
|
|
454
|
-
},
|
|
455
|
-
{
|
|
456
|
-
name: 'Transactions',
|
|
457
|
-
description: 'Transactions submitted to Tempo, and their receipts.',
|
|
458
|
-
},
|
|
459
|
-
{
|
|
460
|
-
name: 'Transfers',
|
|
461
|
-
description: 'Token movements from executing transactions.',
|
|
462
|
-
},
|
|
463
|
-
{
|
|
464
|
-
name: 'Verified Tokens',
|
|
465
|
-
description: 'A curated, trusted list of TIP-20 tokens.',
|
|
466
|
-
},
|
|
467
|
-
...(options.webhook !== false
|
|
468
|
-
? [
|
|
469
|
-
{
|
|
470
|
-
name: 'Webhooks',
|
|
471
|
-
description: 'Get signed callbacks when onchain events happen.',
|
|
472
|
-
},
|
|
473
|
-
]
|
|
474
|
-
: []),
|
|
475
|
-
{
|
|
476
|
-
name: 'Indexer',
|
|
477
|
-
description: "Run read-only SQL queries against Tempo's indexed data.",
|
|
478
|
-
},
|
|
479
|
-
{
|
|
480
|
-
name: 'RPC',
|
|
481
|
-
description:
|
|
482
|
-
'Direct access to the chain over Ethereum JSON-RPC. Not part of the stable API contract; best-effort support only. No compatibility, latency, availability, or data-freshness guarantees. Breaking changes may happen with limited notice.',
|
|
483
|
-
},
|
|
484
|
-
{
|
|
485
|
-
name: 'CoinGecko',
|
|
486
|
-
description: "Exchange data in CoinGecko's GeckoTerminal format.",
|
|
487
|
-
},
|
|
488
|
-
],
|
|
332
|
+
tags,
|
|
333
|
+
...(tagGroups.length ? { 'x-tagGroups': tagGroups } : {}),
|
|
489
334
|
},
|
|
490
335
|
})
|
|
491
|
-
//
|
|
492
|
-
//
|
|
493
|
-
//
|
|
494
|
-
|
|
336
|
+
// Document the outbound `webhooks` block only when the webhook routes are
|
|
337
|
+
// actually mounted; a disabled feature hides its routes, so it must not
|
|
338
|
+
// advertise deliveries.
|
|
339
|
+
const hasWebhookRoutes = Object.keys(generated.paths).some((path) =>
|
|
340
|
+
/\/webhooks(\/|$)/.test(path),
|
|
341
|
+
)
|
|
342
|
+
const webhookBlocks = hasWebhookRoutes ? metadata_all.flatMap((m) => (m.webhooks ? [m.webhooks()] : [])) : [] // prettier-ignore
|
|
343
|
+
const webhooksDoc = webhookBlocks.length
|
|
344
|
+
? { webhooks: Object.assign({}, ...webhookBlocks) }
|
|
345
|
+
: {}
|
|
346
|
+
// Set per-operation `security` and the `402` payment-challenge response
|
|
347
|
+
// from each route's resolved auth policy (the single source of truth), so
|
|
348
|
+
// the anonymous option and `402` appear only where the public/MPP lanes
|
|
349
|
+
// are enabled, not on every operation via the document default.
|
|
495
350
|
applyAccess(generated.paths, Auth.describeAccess(app))
|
|
496
351
|
// Point the `/rpc` operation at the OpenRPC document via `x-openrpc`.
|
|
497
352
|
applyOpenrpcLink(generated.paths, basePath)
|
|
@@ -501,53 +356,34 @@ export function create<const path extends string = '/'>(options: create.Options<
|
|
|
501
356
|
// tag and preserves document path order within a tag, so reordering here
|
|
502
357
|
// drives the sidebar sub-item order.
|
|
503
358
|
return { ...generated, ...webhooksDoc, paths: sortPaths(generated.paths) }
|
|
504
|
-
}
|
|
359
|
+
}
|
|
360
|
+
let finalized = false
|
|
361
|
+
const finalize = () => {
|
|
362
|
+
if (finalized) return
|
|
363
|
+
finalized = true
|
|
505
364
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
// The OpenRPC document is a committed build artifact (no runtime generator);
|
|
509
|
-
// see scripts/openrpc/build.ts and `pnpm openrpc:build`.
|
|
510
|
-
app.get('/openrpc.json', (c) => c.json(openrpcSpec))
|
|
511
|
-
|
|
512
|
-
if (options.docs !== false)
|
|
513
|
-
app.route(
|
|
514
|
-
'/',
|
|
515
|
-
vocs_Handler.openApi(
|
|
516
|
-
{
|
|
517
|
-
// Inline the OpenRPC doc so vocs expands it without a self-subrequest
|
|
518
|
-
// (see `inlineOpenrpc`); the public `/openapi.json` keeps the URL ref.
|
|
519
|
-
spec: spec.then(inlineOpenrpc),
|
|
520
|
-
sidebar: { collapsed: true },
|
|
521
|
-
vocs: { logoUrl: OpenApi.logoUrl, title: 'Tempo API Reference', ...options.docs },
|
|
522
|
-
},
|
|
523
|
-
{ fallback: 'next', css: OpenApi.css },
|
|
524
|
-
),
|
|
525
|
-
)
|
|
365
|
+
app.get('/openapi.json', async (c) => c.json(await getSpec()))
|
|
526
366
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
367
|
+
// The OpenRPC document is a committed build artifact (no runtime generator);
|
|
368
|
+
// see scripts/openrpc/build.ts and `pnpm openrpc:build`.
|
|
369
|
+
app.get('/openrpc.json', (c) => c.json(openrpcSpec))
|
|
530
370
|
|
|
531
|
-
|
|
532
|
-
|
|
371
|
+
// Mount each docs group's reference factory (see `docs()` in `tapimo/docs`)
|
|
372
|
+
// last, so its catch-all sits behind every API route and the documents
|
|
373
|
+
// above — regardless of where the group sat in the composition chain.
|
|
374
|
+
for (const entry of metadata) if (entry.docs) app.route('/', entry.docs({ spec: getSpec }))
|
|
375
|
+
}
|
|
533
376
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
})
|
|
543
|
-
})
|
|
377
|
+
// Patch `fetch` to finalize once before dispatch. `request()` reads
|
|
378
|
+
// `this.fetch` dynamically so it picks up the patch, and the captured
|
|
379
|
+
// `originalFetch` still dispatches as a bare value (used by `App.listener`).
|
|
380
|
+
const originalFetch = app.fetch
|
|
381
|
+
;(app as unknown as { fetch: typeof originalFetch }).fetch = ((request, ...rest) => {
|
|
382
|
+
finalize()
|
|
383
|
+
return originalFetch(request, ...rest)
|
|
384
|
+
}) as typeof originalFetch
|
|
544
385
|
|
|
545
|
-
|
|
546
|
-
// the app would intersect the inferred Hono type and breaks `testClient`'s
|
|
547
|
-
// schema inference for downstream consumers. The cache `store` is owned by
|
|
548
|
-
// the caller (pass `options.cache.store`), and a Node listener is produced on
|
|
549
|
-
// demand via `App.listener(app)`.
|
|
550
|
-
return app
|
|
386
|
+
return route('/', auth.app ?? new Hono<Environment>())
|
|
551
387
|
}
|
|
552
388
|
|
|
553
389
|
/**
|
|
@@ -561,10 +397,14 @@ export function listener(app: { fetch: NodeFetch }): Listener {
|
|
|
561
397
|
}
|
|
562
398
|
|
|
563
399
|
export declare namespace create {
|
|
564
|
-
/**
|
|
400
|
+
/**
|
|
401
|
+
* Options for creating the Tempo API Hono app — the shared core:
|
|
402
|
+
* db/cache/kv/auth capabilities and cross-cutting middleware. Chain-data
|
|
403
|
+
* configuration belongs to {@link data}; email to {@link platform}.
|
|
404
|
+
*/
|
|
565
405
|
type Options<path extends string = '/'> = {
|
|
566
|
-
/**
|
|
567
|
-
|
|
406
|
+
/** Authentication: lane defaults, quotas, and credentials for the built-in enforcement middleware, plus the `session` sign-in surface. Omit for default-closed policies with in-memory rate limiting; pass false to leave policies unenforced (tests only). */
|
|
407
|
+
auth?: Auth.install.Options['auth'] | false | undefined
|
|
568
408
|
/** Caching configuration: the cache store plus the edge response cache toggle. */
|
|
569
409
|
cache?: Cache | undefined
|
|
570
410
|
/** Response compression for API handlers. Disabled by default; pass true for defaults or a config object to customize. Leave disabled when fronted by a proxy/CDN that already compresses. */
|
|
@@ -573,32 +413,16 @@ export declare namespace create {
|
|
|
573
413
|
cors?: boolean | Cors | undefined
|
|
574
414
|
/** Authoritative Postgres store backing stateful features (webhooks, verified tokens). Pass a long-lived `Db.postgres(...)` singleton on Node, or a factory (`() => Db.postgres(...)`) on Workers so each request builds a fresh Hyperdrive-pooled connection. Pass `{ source, cached }` to route staleness-tolerant reads (verified tokens) through a second, query-caching Hyperdrive config; `source` stays uncached for read-after-write correctness. Apply migrations out of band via `tapimo admin migrate`. */
|
|
575
415
|
db: Db.Source | { cached?: Db.Source | undefined; source: Db.Source }
|
|
576
|
-
/** Default Tempo chain id for requests that omit `chainId`. */
|
|
577
|
-
defaultChainId?: Viem.ChainId | undefined
|
|
578
416
|
/** KV state store backing API-key records (e.g. `Store.cloudflareKv(...)`). Omit to leave API-key auth closed — every token resolves to `null`. */
|
|
579
417
|
kv?: Kv | undefined
|
|
580
|
-
/** Vocs API reference options. Set to false to disable the `/` docs page. */
|
|
581
|
-
docs?: Docs | false | undefined
|
|
582
418
|
/** Request logging. Disabled by default. Pass `true` to emit one canonical structured log entry per request through the level-matched console method (indexed by Workers Logs); a level (e.g. `'warn'`) to emit only that level and above (dropping successful-request info lines); or an emit function for a custom sink. */
|
|
583
419
|
logger?: boolean | Log.Level | Logger | undefined
|
|
584
420
|
/** Metrics backend. Disabled by default; pass a backend (e.g. `Metrics.cloudflare()`) to emit request (HTTP) metrics per response. Pass the same backend to the webhook poller/queue handlers so they emit over it too. */
|
|
585
421
|
metrics?: Metrics.Metrics | undefined
|
|
586
|
-
/** Hono middleware to run before API handlers mount. */
|
|
587
|
-
middleware?: readonly MiddlewareHandler[] | undefined
|
|
588
422
|
/** Base path to mount API handlers under. Provided as a literal via the `path` generic so the resulting Hono schema keeps typed route paths for `testClient`. */
|
|
589
423
|
path?: path | undefined
|
|
590
424
|
/** OpenAPI `servers` for the generated document. Defaults to a single relative server (the host serving the doc), so the reference targets the deployment it is served from. Set the canonical public URL(s) here, e.g. `[{ url: 'https://api.tempo.xyz' }]`. */
|
|
591
425
|
servers?: readonly Server[] | undefined
|
|
592
|
-
/** Extra Tempo chain ids this deployment serves, in addition to the built-in public chains and the configured `defaultChainId`. A request for a `chainId` outside this set is rejected with a clear 400 instead of reaching an upstream. */
|
|
593
|
-
supportedChainIds?: readonly number[] | undefined
|
|
594
|
-
/** Tempo RPC options. */
|
|
595
|
-
rpc?: Rpc | undefined
|
|
596
|
-
/** TIDX query client options. */
|
|
597
|
-
tidx?: Tidx.getClient.Tidx | undefined
|
|
598
|
-
/** Verified-token feature configuration. Enabled by default (token rows live in `db`; empty until published); pass `false` to always serve an empty verified list. */
|
|
599
|
-
verifiedTokens?: VerifiedTokens | false | undefined
|
|
600
|
-
/** Webhook feature configuration. Enabled by default (subscription/delivery rows live in `db`). Pass `false` to disable: the `/webhooks` routes stay mounted (for a stable schema and typed test client) but return `404` and are hidden from the OpenAPI document. */
|
|
601
|
-
webhook?: Webhook | false | undefined
|
|
602
426
|
}
|
|
603
427
|
|
|
604
428
|
/** KV state-store configuration. */
|
|
@@ -620,27 +444,6 @@ export declare namespace create {
|
|
|
620
444
|
store?: Store.Store | undefined
|
|
621
445
|
}
|
|
622
446
|
|
|
623
|
-
/** Verified-token feature configuration. */
|
|
624
|
-
type VerifiedTokens = {
|
|
625
|
-
/**
|
|
626
|
-
* Per-isolate soft-refresh window in milliseconds. Within this window
|
|
627
|
-
* verified-token lookups are served from the in-memory snapshot with no
|
|
628
|
-
* database I/O; after it, the next lookup re-checks the head version
|
|
629
|
-
* (single-flight) and recompiles only when it changed. Defaults to 10_000.
|
|
630
|
-
*/
|
|
631
|
-
refreshMs?: number | undefined
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
/** Webhook feature configuration. */
|
|
635
|
-
type Webhook = {
|
|
636
|
-
/**
|
|
637
|
-
* Maximum active subscriptions a single owner may hold. Creation is rejected
|
|
638
|
-
* with `403 limit_exceeded` once reached. Defaults to 100; bounds the
|
|
639
|
-
* spam/SSRF surface and unbounded downstream delivery cost per owner.
|
|
640
|
-
*/
|
|
641
|
-
maxPerOwner?: number | undefined
|
|
642
|
-
}
|
|
643
|
-
|
|
644
447
|
/** Binary asset store for static API assets (e.g. `Assets.cloudflareR2(...)`). */
|
|
645
448
|
type Assets = Assets.Assets
|
|
646
449
|
|
|
@@ -650,8 +453,14 @@ export declare namespace create {
|
|
|
650
453
|
/** CORS middleware options. */
|
|
651
454
|
type Cors = NonNullable<Parameters<typeof hono_cors>[0]>
|
|
652
455
|
|
|
653
|
-
/**
|
|
654
|
-
type Docs =
|
|
456
|
+
/** Reference-UI factory a docs group carries via {@link Metadata} (see `docs()` in `tapimo/docs`): given the app's OpenAPI document builder, returns an app that {@link create} mounts at the root on finalize. */
|
|
457
|
+
type Docs = (context: DocsContext) => Hono<any, any, any>
|
|
458
|
+
|
|
459
|
+
/** Context the app provides to a docs group's reference factory. */
|
|
460
|
+
type DocsContext = {
|
|
461
|
+
/** Memoized OpenAPI document builder — the same document served at `/openapi.json`. */
|
|
462
|
+
spec: () => Promise<{ paths: Record<string, unknown> }>
|
|
463
|
+
}
|
|
655
464
|
|
|
656
465
|
/** Custom request-log sink, receiving one canonical entry per request. */
|
|
657
466
|
type Logger = Log.Emit
|
|
@@ -665,10 +474,39 @@ export declare namespace create {
|
|
|
665
474
|
}
|
|
666
475
|
|
|
667
476
|
/**
|
|
668
|
-
*
|
|
669
|
-
*
|
|
477
|
+
* What a route group contributes to the composed app beyond its routes:
|
|
478
|
+
* OpenAPI document metadata (tags, security schemes, outbound webhooks block)
|
|
479
|
+
* and an optional docs-UI factory. `create` collects these off each mounted
|
|
480
|
+
* group (via {@link Metadata}); unused entries don't render.
|
|
670
481
|
*/
|
|
671
|
-
type
|
|
482
|
+
type Metadata = {
|
|
483
|
+
/** Reference-UI factory mounted at the root on finalize (see `docs()` in `tapimo/docs`). */
|
|
484
|
+
docs?: Docs | undefined
|
|
485
|
+
/** Security scheme definitions this group's routes reference (e.g. the session cookie). */
|
|
486
|
+
securitySchemes?: Record<string, unknown> | undefined
|
|
487
|
+
/** Root-level OpenAPI tag definitions for this group's operations. */
|
|
488
|
+
tags?: readonly Tag[] | undefined
|
|
489
|
+
/** Builds the OAS 3.1 `webhooks` block documenting outbound deliveries, emitted only when the group's webhook routes are mounted. Called during spec generation only, keeping schema conversion off isolate startup. */
|
|
490
|
+
webhooks?: (() => Record<string, unknown>) | undefined
|
|
491
|
+
/** Vocs tag-group metadata for grouping root tags in the reference. */
|
|
492
|
+
'x-tagGroups'?: readonly TagGroup[] | undefined
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/** One root-level OpenAPI tag definition. */
|
|
496
|
+
type Tag = {
|
|
497
|
+
/** Human-readable summary shown in the reference sidebar. */
|
|
498
|
+
description: string
|
|
499
|
+
/** Tag name referenced by operations. */
|
|
500
|
+
name: string
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/** One Vocs OpenAPI tag group. */
|
|
504
|
+
type TagGroup = {
|
|
505
|
+
/** Section name shown by tag-group-aware references. */
|
|
506
|
+
name: string
|
|
507
|
+
/** Root tag names in this group. */
|
|
508
|
+
tags: readonly string[]
|
|
509
|
+
}
|
|
672
510
|
}
|
|
673
511
|
|
|
674
512
|
function getRequestId(c: Context<Environment>) {
|
|
@@ -746,10 +584,11 @@ function sortPaths(paths: PathsObject): PathsObject {
|
|
|
746
584
|
|
|
747
585
|
/**
|
|
748
586
|
* Sets per-operation `security` and the `402` payment-challenge response from
|
|
749
|
-
* each route's resolved access lanes (see {@link Auth.describeAccess}).
|
|
750
|
-
*
|
|
751
|
-
*
|
|
752
|
-
*
|
|
587
|
+
* each route's resolved access lanes (see {@link Auth.describeAccess}).
|
|
588
|
+
* Security options compose from the enabled lanes — API keys (header +
|
|
589
|
+
* bearer), sessions (cookie + bearer token), anonymous (`{}`) — and the `402`
|
|
590
|
+
* response is emitted only where the MPP lane is enabled; required API-key
|
|
591
|
+
* scopes are surfaced as the `x-required-scopes` extension.
|
|
753
592
|
*/
|
|
754
593
|
function applyAccess(paths: PathsObject, access: Record<string, Auth.OperationAccess>) {
|
|
755
594
|
for (const item of Object.values(paths)) {
|
|
@@ -757,7 +596,12 @@ function applyAccess(paths: PathsObject, access: Record<string, Auth.OperationAc
|
|
|
757
596
|
if (!isMutableOperation(op)) continue
|
|
758
597
|
const lanes = access[op.operationId]
|
|
759
598
|
if (!lanes) continue
|
|
760
|
-
|
|
599
|
+
const security = [
|
|
600
|
+
...(lanes.apiKey ? [{ apiKey: [] }, { bearerAuth: [] }] : []),
|
|
601
|
+
...(lanes.session ? [{ session: [] }, ...(lanes.apiKey ? [] : [{ bearerAuth: [] }])] : []),
|
|
602
|
+
...(lanes.public ? [{}] : []),
|
|
603
|
+
]
|
|
604
|
+
if (security.length > 0) op.security = security
|
|
761
605
|
if (lanes.scopes.length > 0) op['x-required-scopes'] = [...lanes.scopes]
|
|
762
606
|
if (lanes.mpp) op.responses = { ...op.responses, 402: OpenApi.paymentChallengeRef }
|
|
763
607
|
else if (op.responses) delete op.responses['402']
|
|
@@ -772,7 +616,7 @@ function applyAccess(paths: PathsObject, access: Record<string, Auth.OperationAc
|
|
|
772
616
|
* method/param/return schemas it accepts.
|
|
773
617
|
*
|
|
774
618
|
* The public `/openapi.json` keeps a URL reference (small, conventional). The
|
|
775
|
-
* docs handler instead
|
|
619
|
+
* docs handler instead inlines the document — see `inlineOpenrpc` in `tapimo/docs`.
|
|
776
620
|
*/
|
|
777
621
|
function applyOpenrpcLink(paths: PathsObject, basePath: string) {
|
|
778
622
|
// `basePath` is `/` at the root mount and `/api` etc. otherwise; strip any
|
|
@@ -783,31 +627,6 @@ function applyOpenrpcLink(paths: PathsObject, basePath: string) {
|
|
|
783
627
|
if (isMutableOperation(op) && isRpcOperation(op)) op['x-openrpc'] = url
|
|
784
628
|
}
|
|
785
629
|
|
|
786
|
-
/**
|
|
787
|
-
* Returns a shallow copy of `spec` with the JSON-RPC passthrough operation's
|
|
788
|
-
* `x-openrpc` replaced by the inline OpenRPC document, for the docs handler.
|
|
789
|
-
*
|
|
790
|
-
* Vocs expands `x-openrpc` at request time. A URL reference (as kept in the
|
|
791
|
-
* public `/openapi.json`) would make the docs worker fetch its own
|
|
792
|
-
* `/openrpc.json` — a self-subrequest that is unreliable on Cloudflare Workers
|
|
793
|
-
* and silently falls back to a single, unexpanded operation. Inlining the
|
|
794
|
-
* committed artifact keeps expansion deterministic across local and deployed
|
|
795
|
-
* environments, without bloating the public spec. Only the affected path/op are
|
|
796
|
-
* cloned; the rest of the (large) document is shared by reference.
|
|
797
|
-
*/
|
|
798
|
-
function inlineOpenrpc<spec extends { paths: Record<string, unknown> }>(spec: spec): spec {
|
|
799
|
-
const paths: Record<string, unknown> = {}
|
|
800
|
-
for (const [pathname, item] of Object.entries(spec.paths)) {
|
|
801
|
-
let next = item
|
|
802
|
-
if (isRecord(item))
|
|
803
|
-
for (const [method, op] of Object.entries(item))
|
|
804
|
-
if (isMutableOperation(op) && isRpcOperation(op))
|
|
805
|
-
next = { ...item, [method]: { ...op, 'x-openrpc': openrpcSpec } }
|
|
806
|
-
paths[pathname] = next
|
|
807
|
-
}
|
|
808
|
-
return { ...spec, paths }
|
|
809
|
-
}
|
|
810
|
-
|
|
811
630
|
type PathsObject = Awaited<ReturnType<typeof generateSpecs>>['paths']
|
|
812
631
|
type PathItem = PathsObject[string]
|
|
813
632
|
type Operation = { summary?: string | undefined }
|
|
@@ -839,45 +658,6 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
839
658
|
return !!value && typeof value === 'object' && !Array.isArray(value)
|
|
840
659
|
}
|
|
841
660
|
|
|
842
|
-
function createGetAsset(options: createGetAsset.Options): GetAsset {
|
|
843
|
-
const { assets, basePath, origin } = options
|
|
844
|
-
// Without an asset store, every lookup misses so callers fall back to their
|
|
845
|
-
// "no static data" behavior (undefined logo URIs).
|
|
846
|
-
if (!assets) return () => undefined
|
|
847
|
-
return async (chainId, path) => {
|
|
848
|
-
// Public URLs include `/assets/:chainId`, but the store is keyed by
|
|
849
|
-
// `:chainId/:path` (e.g. an R2 object key), decoupled from the URL shape.
|
|
850
|
-
// `path` may be absolute (`Path.join` returns a leading slash); strip it so
|
|
851
|
-
// the key is `:chainId/:path`, not `:chainId//:path`.
|
|
852
|
-
const pathname = Path.join(basePath, 'assets', String(chainId), path)
|
|
853
|
-
const key = `${chainId}/${path.replace(/^\/+/, '')}`
|
|
854
|
-
const asset = await assets.get(key)
|
|
855
|
-
if (!asset) return undefined
|
|
856
|
-
// Return an absolute public URL (scheme + host) against the request origin
|
|
857
|
-
// so logo URLs work for any consumer regardless of the API's domain.
|
|
858
|
-
return {
|
|
859
|
-
response: new globalThis.Response(asset.body, {
|
|
860
|
-
headers: { 'Content-Type': asset.contentType },
|
|
861
|
-
}),
|
|
862
|
-
uri: new URL(pathname, origin).toString(),
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
declare namespace createGetAsset {
|
|
868
|
-
type Options = {
|
|
869
|
-
assets?: create.Assets | undefined
|
|
870
|
-
basePath: string
|
|
871
|
-
origin: string
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
function stripAssetPath(path: string, basePath: string) {
|
|
876
|
-
for (const prefix of [`${Path.join(basePath, 'assets')}/`, '/assets/'])
|
|
877
|
-
if (path.startsWith(prefix)) return `/${path.slice(prefix.length)}`
|
|
878
|
-
return path
|
|
879
|
-
}
|
|
880
|
-
|
|
881
661
|
type GetNodeRequestListener = (typeof import('@hono/node-server'))['getRequestListener']
|
|
882
662
|
type NodeFetch = Parameters<GetNodeRequestListener>[0]
|
|
883
663
|
type NodeRequestListener = ReturnType<GetNodeRequestListener>
|